Skip to content

Server Query Protocol

Filigrani edited this page Apr 2, 2023 · 2 revisions

Server Query Protocol

This page documents the Sky Co-op server query protocol to get infromation about server.

Query information about server.

Server will respond by same address that used for game.

Default port of Sky Co-op Server is 26950 (if not listed otherwise).

If server don't have listed port, it will respond via default 26950 port, but if server has specified port, this port will be used for query of information aswell.

Examples for easier understanding

Server Address Game port Query port
87.254.159.105 26950 26950
87.254.159.105:26950 26950 26950
87.254.159.105:35735 35735 35735

Query format

Send the following UDP query to a Sky Co-op server to get server status information.

Type Field Value
Signed Int Message Type -2

If everything done right, you will get reply.

Reply format

Type Data
Signed Int Header, always 147
Signed Int Server name length
Unicode String Unicode server name, use lenght you have read earlier to read this string
Signed Int Mod version string length
UTF8 string UTF8 formated string of mod version, use lenght you have read earlier to read this string
Signed Int Current amout of players on server
Signed Int Max slots for players
Signed Int Server config json string length
Unicode String Unicode formated json string with server config data, use lenght you have read earlier to read this string

Server config json contains experience mode selected on server (difficulty), names of players that currently on server, and status of enabled PVP.

C# Example

        public static void Ping()
        {
            // Request of server status should be done via UDP.
            // Use same port as game server use.
            // Default port of Sky Co-op Server is 26950 (if not listed otherwise).
            // Example: Game server with address 87.254.159.105:26950
            // Will respond with status data by same 26950 port,
            // aswell as servers that listed as 87.254.159.105
            // will respond by port 26950, but I think is obvious.

            // Send to server (signed int) -2 message to request servers status.

            UdpClient Pinger = new UdpClient();
            IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse(ip), port);
            Pinger.Connect(endPoint);
            byte[] Buffer = BitConverter.GetBytes(-2);
            Pinger.Send(Buffer.ToArray(), Buffer.Length);

            byte[] ReturnData = Pinger.Receive(ref endPoint);
            // First 4 bytes is header, always should be 147
            // Next 4 bytes is server name length.
            // Next Unicode formated string of server name.
            // Next 4 bytes is Mod's version string length
            // Next UTF8 formated string of version.
            // Next 4 bytes after version string is current amout of players on server.
            // Next 4 bytes is max players slots on server.
            // Next 4 bytes is server information json string length.
            // Next Unicode formated string of server's information.


            int i = 0;
            int IntHeader = BitConverter.ToInt32(ReturnData, i);
            if (IntHeader == 147)
            {
                Console.WriteLine("Correct header!");
            } else
            {
                Console.WriteLine("Wrong header!");
                return;
            }
            i += 4;
            int ServerNameLength = BitConverter.ToInt32(ReturnData, i);
            i += 4;
            string ServerName = Encoding.Unicode.GetString(ReturnData, i, ServerNameLength);
            i += ServerNameLength;
            int ServerVersionStringLength = BitConverter.ToInt32(ReturnData, i);
            i += 4;
            string ServerVersion = Encoding.UTF8.GetString(ReturnData, i, ServerVersionStringLength);
            i += ServerVersionStringLength;
            int Players = BitConverter.ToInt32(ReturnData, i);
            i += 4;
            int PlayersMax = BitConverter.ToInt32(ReturnData, i);
            i += 4;
            int ServerConfigStringLength = BitConverter.ToInt32(ReturnData, i);
            i += 4;
            string ConfigString = Encoding.Unicode.GetString(ReturnData, i, ServerConfigStringLength);

            Console.WriteLine(ServerName+" version " + ServerVersion +" Players: " + Players + "/" + PlayersMax +" Server json:");
            Console.WriteLine(ConfigString);
            Pinger.Close();
        }