After switching from 4.19 to 4.21 clients could not connect to dedicated server anymore.
I build UE4 from the source, rebuild dedicated server from the source, Package project with UE 4.21 Source Build but clients could not connect anymore.
Tried more than once, but no effect. When client try to connect server shows :
Prelogin failure: incompatible_unique_net_id
Iāve been having this same issue, but only with Android connecting to a dedicated server. Windows can still connect.
It seems to be caused by attempting to use OnlineSubsystemUNSET. But Iāve selected to use OnlineSubsystemOculus, and Iām in the process of figuring out why it appears to be UNSET instead.
Here are some of my logs around this:
UE4 : [2018.12.07-22.53.35:481][522]LogGameMode: Display: Match State Changed from InProgress to LeavingMap
UE4 : [2018.12.07-22.53.35:481][522]LogGameState: Match State Changed from InProgress to LeavingMap
UE4 : [2018.12.07-22.53.35:481][522]LogNet: Browse: 35.197.7.152//Game/SculptureMode
UE4 : [2018.12.07-22.53.35:482][522]LogInit: BSD_Android: Socket queue 65536 / 65536
UE4 : [2018.12.07-22.53.35:483][522]LogInit: BSD_Android: I am localhost (127.0.0.1:0)
UE4 : [2018.12.07-22.53.35:483][522]LogSockets: (BSD_Android) Wifi Adapter IP 127.0.0.1
UE4 : [2018.12.07-22.53.35:484][522]PacketHandlerLog: Loaded PacketHandler component: Engine.EngineHandlerComponentFactory (StatelessConnectHandlerComponent)
UE4 : [2018.12.07-22.53.35:484][522]LogNet: Game client on port 7777, rate 500000000
UE4 : [2018.12.07-22.53.35:676][536]LogNetVersion: SculptrVR 1.0.0.0, NetCL: 0, EngineNetVer: 5, GameNetVer: 0 (Checksum: 1388534187)
UE4 : [2018.12.07-22.53.35:677][536]LogNet: UPendingNetGame::SendInitialJoin: Sending hello. [UNetConnection] RemoteAddr: 35.197.7.152:7777, Name: IpConnection_0, Driver: PendingNetDriver IpNetDriver_0, IsServer: NO, PC: NULL, Owner: NULL, UniqueId: INVALID
UE4 : [2018.12.07-22.53.35:718][539]LogModuleManager: Warning: ModuleManager: Module āOnlineSubsystemUNSETā not found - its StaticallyLinkedModuleInitializers function is null.
UE4 : [2018.12.07-22.53.35:788][544]LogNet: NetConnection::Close() [PendingNetDriver] [NoPC] [No Owner] from NMT_Failure incompatible_unique_net_id
Either in 4.20 or 4.21 Epic changed the PreLogin function in GameModeBase.cpp.
Now it verifies that both the server and the client are using the same OnlineSubsystem type.
I have tried overriding that function in my GameMode to allow any connection. It connects to the server successfully! But now it crashes Iāll have to report back later if I can get it to work.
Btw, the super suspicious line is:
UE4 : [2018.12.07-22.53.35:718][539]LogModuleManager: Warning: ModuleManager: Module āOnlineSubsystemUNSETā not found - its StaticallyLinkedModuleInitializers function is null.
I donāt know why it would ever try to load OnlineSubsystemUNSET instead of OnlineSubsystemNULLā¦
This is my isolated reply/solution from that post:
Found the fix for the hash issue. Instead of adding a hash, given the "fix" implemented by Epic in 4.20.3, we now need to override the following function in FUniqueNetIdUWorks, inherited from FUniqueNetId:
virtual FName GetType() const override
{
return TEXT("UWorks");
}
Sorry for the troubles everyone, I wrote that to avoid our QA causing late night, last minute fires when we are trying to ship games. As you probably know, any commandline addition of the form
-no<ossname> will disable an online subsystem. We use at least 7 at any given time, so its possible for mistakes to be made.
Many use this for different reasons, but what happened all to often (and on a Friday night no less) would be the server would be fine but some client would have one of these set. Our servers would assert that the FUniqueNetId wasnāt serializing the right type to play our game. QA would freak out and bug it but it was always user error.
I added this explicit check because I figured externally most teams expect compatible unique ids. As it would seem it has been discovered, you are free to remove the check in AGameMode::Prelogin().
That being said, Iām curious, how do you get around the automatic calls to RegisterPlayer that would probably complain. Do you overload these functions? Do you not use the session interface to manage multiplayer sessions? Just want to understand the paths you are treading.
Most client/server relationships should be talking compatible OnlineSubsystems. For example, it makes little sense for a Steam client to join a non Steam server and not authenticate. A lot of that pipeline was written in the base engine implementation. APlayerState has one FUniqueNetId, which should be the one defined by DefaultPlatformSubsystem in your DefaultEngine.ini file.
My solution was to remove the check in PreLogin and then yeah it created problems converting between FUniqueNetId types. So I Made a routine that could convert everything into a NULL online subsystem unique ID (which is basically just a string) and the server just keeps those around.
Thanks for the reply. In my case, Iām using Steam for clients and player hosted listen servers but then using official dedicated servers without steamās online subsystem for simplicities sake. I made a simple server browsing system for those dedicated servers. The complexity for most people to host a dedicated server increases quite a lot when you add SteamCMD into the mix. Itās going to be a free community āblueprintsā project, so Iād like to avoid modifying the engine. And because itās free, the project doesnāt require any of the auth checks and such. Staying with a blueprint only multiplayer project has proven to be quite the challenge.
Iāve seen a few people having problems with UE20+ using Android clients mixing with null subsystems as well, if I remember right. Iām guessing they might be running into a similar problem.
Iām spanning quite a lot of different skill sets here and maybe I just donāt fully understand what the best route should be. I understand we should probably just be querying the steam SDK with OnlineSubsystemNull instead of using OnlineSubsystemSteam, but we are just trying to keep everything simple.
I realize Epicās cross platform online service was announced recently. My tentative plan was to wait until that matures. (Unless it will be a long time.) Maybe I should just scrap that idea and use Steam for dedicated servers.
That sounds like a good solution. Maybe Epic can implement a method like that in the future releases? Were you only experiencing crashes with the conversion between FUniqueNetId types?
Thanks, Iām strongly considering using UWorks in the future. Youāve done some fine work there.
Thank you for giving us more information on why exactly these changes were made. What Iām trying to figure out is how we are expected to implement ācross-platformā client/server. You mention that you would expect if you are using a steam client, to also be using a steam server online subsystem. The type check changes make sense if that is the assumption, but if you want to use a steam client with your own online subsystem how exactly are we suppose to approach this?
From my understanding, you expect the developer to create their own online subsystem (letās call it TestOnlineSubSystem) and create their own UniqueID (FUniqueNetIdTest, which derives from unique net id etc). When the user boots up the game on steam / xbox / ps4 / epic launcher letās say, they will be using that specific subsystem (xbox, ps4 etc). Where are we suppose to handle the conversion from FUniqueNetIdSteam (this is replicated from client to server by the means of FUniqueNetIdRepl) to FUniqueNetIdTest (on the server) in order to be used for TestOnlineSubSystem so that the type checking will pass?
Currently in order to get around this, I implemented my own uniqueID and inside the PreLogin / InitNewPlayer functions I will create my own subsystems type and pass that through and it will work, but I dont really understand what official approach to your new implementation should be. It appears that many developers are having the same problems / questions regarding this.
I used to be able to use the command āopen ExampleMap?listenā on PC
and then connect using āopen [PCās IP Address]ā on my iOS/Android device to quickly test out multiplayer, but now this crashes the game.
If you can, please fix this and let us know, thanks!
The check in Prelogin was meant to keep compatible āDefaultā OnlineSubsystems together and alert if they are incompatible for reasons alluded to here, including registration and just basic FUniqueNetId incompatibility. The engine tries to do various things for you AGameSession::RegisterPlayer for example and things will just break if you pass incompatible FUniqueNetIds around.
That being said PC obviously doesnāt have any console interface because there is simply no API from them to do so. Some people have been using the OnlineSubsystemNULL as the default subsystem for both clients/servers but it wasnāt really meant to be a production system as it doesnāt support many features you need.
Depending on what you are doing, you could try to start with this (DefaultPlatformService=NULL) so both servers/clients have a common OSS. Depending on the feature set you may need to extend NULL. We pass the PlatformUniqueNetId to the AGameMode::Login call by extending ULocalPlayer::GetGameLoginOptions (?PlatformId=someConsoleId/etc) and then the dedicated server holds on to that via CreateForeignUniqueNetId so it can be replicated/compared/etc even though it canāt be directly useful off the native platform. Replicating to other players is super important for parties and other reasons.
Beacons donāt care about most of this, other than say passing around an FUniqueNetId as part of the handshaking. Console session management has to occur on the clients since a Linux/PC server doesnāt understand console APIs.
You can access any OnlineSubsystems directly from the code via IOnlineSubsystem::Get(World, NAMEOFSUBSYSTEM). For Fortnite we wrap this call into GetPlatformOnlineSubsystem() which returns Xbox/PS4/Switch/etc based on compiled platform. The common interface makes it so it doesnāt really matter what platform we are talking to for registration/voice/cloud save/etc.
The overall point isnāt about converting from UniqueId to another, but maintaining parallel OnlineSubsystems to get the data between clients through agnostic replication on the server. There is no universal OnlineSubsystem yet that can talk across platforms. The one we have in Fortnite is what weāre trying to expose via the Epic Online Services SDK which is underway right now.
You can see its beginnings at dev.epicgames.com or the various blogs that talk about our services roadmap. To be clear this SDK does not require our store, but our current implementations arenāt ready for public consumption yet.
Iām on 4.22 an i have an issue with players on steam connection to a non steam dedicated server.
I figured out that subsystems now need to be the same and removed that check like described here.
I now have a problem that the server crashes as a player joins. Itās probably about the problems converting between FUniqueNetId types, but Iām not sure.
Can anyone help me with that?
I attached the end of my Server log file with the crash.
Note, I am not using steam on my dedicated server, connecting via raw IP, and so client side I removed all steam net definitions in the DefaultEngine.ini
[OnlineSubsystemSteam]
bUseSteamNetworking=false
ā¦ other stuff
[OnlineSubsystem]
DefaultPlatformService=Steam
ā¦ other stuff
DO NOT HAVE
[PacketHandlerComponents]
/Script/OnlineSubsystemSteam.SteamNetDriver
I then had to hack the engine in PendingNetGame.cpp by commenting out the following line
//Connection->PlayerId = LocalPlayer->GetPreferredUniqueNetId();
WARNING: I have zero clue what other ramifications there are having a default PlayerId, but I know thatās whats happening if you run the game via editor or run the game without the steam client running.
Thanks man! It saved at least a day for me I mean the last line.
I had the same issue with Oculus Online Subsystem, because its UniqueNetID format is not compatible with NULL OSS, and if I removed the format check in GameModeBase::PreLogin() it crashed my Linux server, but if no ID is sent, it works fine with Gamelift btw ID is passed as UNKNOWN similarly when testing from Editor. And Gamelift uses its own PlayerSessionID, so apparently no more problems so farā¦
//Connection->PlayerId = LocalPlayer->GetPreferredUniqueNetId();
This change no longer works in UE 4.27
Has anyone been able to solve the problem in the latest available Unreal Engine 4 version (4.27)?