Hello there,
I am using Steam for multiplayer, so I can easily browse and connect to my dedicated servers using the Steam server browser or my in-game implementation. It is all working good, but recently I started integrating Amazon GameLift, a matchmaking tool by Amazon which hosts my dedicated servers on their EC2 instances. When matchmaking was successful, I get a raw IP and port back, and I now try to connect to it, but “open ip:port” won’t work, neither ClientTravel does. It tries to connect, then the log’s silent for a minute, and then the connection times out. I found out that Unreal connects to Steam servers by using “open steam.<steam id of the server>”, but I don’t have that ID, only the IP and port.
Is this normal that we can’t connect to a IP when using Steam, or am I just too dumb?
I am using playfab instead of Gamelift which worked fine, I use to get Port and IP from Playfab component and I just Open level with those details, but when I am using steam in client side, it does not connect anymore it throws “PreLogin failure: incompatible_unique_net_id”
Hey! As mentioned, you can only connect to servers if you have the Steam ID. That being said the way to connect to servers via the command line is “open steam.12345” where 12345 would be the Steam ID of the server.
To get the servers Steam ID from raw IP, there is a function in the Steam SDK here: ISteamMatchmakingServers Interface (Steamworks Documentation).
You’ll have to give him the IP and Port (the query port, often 27015! Not the game port), and after the async call called back (you’ll need to make your class inheriting ISteamMatchmakingPingResponse), you’ll get the server data, including the Steam ID. Then use the command line above to connect!
I personally expose an IP field on my steam session, then have the client look through the sessions list until it finds the IP it wants to connect to.
That’s probably super dirty, and you need to add some anti-spoofing verifications, but it does work within the bounds if existing UE4 Steam SDK libraries.
iUltimateLP’s answer is very interesting though, I’m defintitely going to take a look at it
Is there a way in which I can use steam for authentication and platform and not for creating game sessions coz I’m already using playfab for matchmaking, just want use the usual way of getting the ip and the port and join the game session.
Unfortunately not. Once you use the Steam net driver, connections via raw IP/Port aren’t possible anymore. It’s a security measure, and something Steam delivers: it protects servers behind IDs so it won’t expose their raw connection info. So either you disable Steam completely, or use my approach to ask the server about it’s IP. It’s not that hard implementing it, so I’d suggest it
Well I tried everything, my server is registered with steam its showing in steam server list on LAN as well as Internet Tab but, somehow my client cant find that server via Find advance session also I implemented Steam Ping server, which server failed to respond. anyone any idea, what could have gone wrong.
The Steam PingServer function you mentioned seems to take in the ip and port in host order. Been struggling to try to convert FString to host order (which can apparently be held in a uint32 for the ip, and uint16 for the port). Would really appreciate knowing how you did this.
It takes the URL, splits it by the “:” so we have the IP and port string, then it converts the port string to an uint16 and the IP to a uint32 decimal address. Because inet_addr is returning it in the wrong order, I took the code from stackoverflow to reverse it. Then you have perfect data for PingServer()!
Ah was wondering why inet_addr wasn’t working right out of the box. As we say in Dublin, Ireland, you are a straight legend iUltimateLP!
I’m now getting the ServerResponded callback. Need to figure out how to get the WorldContext inside this steam callback class now so I can GetFirstLocalPlayerController to do a ClientTravel.
I tried creating an intermediary uobject class and overwriting its GetWorld function but just getting nullptr so far. Did you happen to have to deal with this aswell?
Ah! Multiple inheritance I didn’t consider it as Unreal doesn’t support it with their internal macros, but since the steam class is not using the internal macros it’s possible.
I got it working though, thank you very much friend.
A warning for others, I got some horrible *.gen.cpp errors when I included the steam/isteammatchmaking.h. Had to add this after the steam includes
Sorry to necro this thread but, even after following the instructions i can not get the “PingServer()” function to return the proper response it always fails, I am using the following function instead of the one in the thread to get the IP in host order so that might be something wrong with that but from what i’ve read i belive it should be working properly.
I am trying to connect to a PLAYFAB server, i can get the IP and port just fine but steam never returns the proper ID for me to connect, do i need to open a specific port for the query to work?
EDIT: tried opening the 27015 ports both tcp and udp in the playfab dashboard and the result is the same.
In order to connect via raw IP I had to first make sure both my client and server were compiled with the steam networking disabled in the DefaultEngine.ini
[OnlineSubsystemSteam]
bUseSteamNetworking=false
… other stuff
[OnlineSubsystem]
DefaultPlatformService=Steam
… other stuff
DO NOT HAVE THESE SECTIONS
[PacketHandlerComponents]
[/Script/OnlineSubsystemSteam.SteamNetDriver]
After doing that I was getting disconnected due to incompatible_unique_net_id
So 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. However since the id was simply Steam : DisplayName the value is not actually unique anyway.