예제 #1
0
        internal static byte[] getInfo(IPEndPoint ipe, Packet packet)
        {
            //Create the socket
            Socket srvSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

            //Save the max packet size
            int packetSize = 12288;

            //Send/Receive timeouts
            srvSocket.SendTimeout = 3000;
            srvSocket.ReceiveTimeout = 3000;

            try
            {
                //Send the request to the server
                srvSocket.SendTo(packet.outputAsBytes(), ipe);
            }
            catch (SocketException se)
            {
                throw new SSQLServerException("Could not send packet to server {" + se.Message + "}");
            }

            //Create a new receive buffer
            byte[] rcvPacketInfo = new byte[packetSize];
            EndPoint Remote = (EndPoint)ipe;

            int recvdBytes = -1;
            try
            {
                //Receive the data from the server
                recvdBytes = srvSocket.ReceiveFrom(rcvPacketInfo, ref Remote);
            }
            catch (SocketException se)
            {
                throw new SSQLServerException("Could not receive packet from server {" + se.Message + "}");
            }

            if (recvdBytes < sizeof(uint))
                return null;

            uint headerInt = BitConverter.ToUInt32(rcvPacketInfo, 0);
            if (headerInt != 0xFFFFFFFF) //we only support simple non-split packets for this query
                return null;

            int realDataSize = recvdBytes - sizeof(uint);

            //Send the packet data back
            byte[] retnData = new byte[realDataSize];
            Array.Copy(rcvPacketInfo, sizeof(uint), retnData,  0, realDataSize);
            return retnData;
        }
예제 #2
0
        internal static byte[] getInfo(IPEndPoint ipe, Packet packet)
        {
            //Create the socket
            Socket srvSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

            //Save the max packet size
            int packetSize = 12288;

            //Send/Receive timeouts
            srvSocket.SendTimeout = 3000;
            srvSocket.ReceiveTimeout = 3000;

            try
            {
                //Send the request to the server
                srvSocket.SendTo(packet.outputAsBytes(), ipe);
            }
            catch (SocketException se)
            {
                throw new SSQLServerException("Could not send packet to server {" + se.Message + "}");
            }

            //Create a new receive buffer
            byte[] rcvPacketInfo = new byte[packetSize];
            EndPoint Remote = (EndPoint)ipe;

            try
            {
                //Receive the data from the server
                srvSocket.ReceiveFrom(rcvPacketInfo, ref Remote);
            }
            catch (SocketException se)
            {
                throw new SSQLServerException("Could not receive packet from server {" + se.Message + "}");
            }

            //Send the information back
            return rcvPacketInfo;
        }
예제 #3
0
파일: SSQL.cs 프로젝트: Khaon/ssqlib
        /// <summary>
        /// Pings the specified Source server to retreive information about it such as the server name, max players, current number of players, etc.
        /// </summary>
        /// <param name="ip_end">The IPEndPoint object containing the IP address and port of the server</param>
        /// <returns>Information about the server or throws an SSQLServerException if it could not be retreived</returns>
        public ServerInfo Server(IPEndPoint ip_end)
        {
            //Create a new empty server info object
            ServerInfo info = new ServerInfo();

            //Create an empty buffer
            byte[] buf = null;

            //Create a new packet and request
            Packet requestPacket = new Packet();
            requestPacket.Data = "TSource Engine Query";

            try
            {
                //Attempt to get the server info
                buf = SocketUtils.getInfo(ip_end, requestPacket);
            }
            catch(SSQLServerException e)
            {
                throw e;
            }

            //Start past the first four bytes which are all 0xff
            int i = 4;

            //Make sure the first character is an I
            if (buf[i++] != 'I') return null;

            //Make sure the returned version is above 0x07
            if (buf[i++] < 0x07) return null;

            StringBuilder srvName = new StringBuilder();

            //Retrieve the server name
            while (buf[i] != 0x00)
            {
                srvName.Append((char)buf[i]);
                i++;
            }

            //Move to the next byte
            i++;

            //Set the name of the server
            info.Name = srvName.ToString();

            StringBuilder mapName = new StringBuilder();

            //Retrieve the map name
            while (buf[i] != 0x00)
            {
                mapName.Append((char)buf[i]);
                i++;
            }

            //Move to the next byte
            i++;

            info.Map = mapName.ToString();

            StringBuilder gameName = new StringBuilder();

            //Get the short name for the game
            while (buf[i] != 0x00)
            {
                gameName.Append((char)buf[i]);
                i++;
            }

            //Move to the next byte
            i++;

            StringBuilder gameFriendly = new StringBuilder();

            //Get the friendly game description
            while (buf[i] != 0x00)
            {
                gameFriendly.Append((char)buf[i]);
                i++;
            }

            //Move to the next byte
            i++;

            info.Game = gameFriendly.ToString() + " (" + gameName.ToString() + ")";

            short appID = (short)System.BitConverter.ToInt16(buf, i);

            //Skip the next 2 bytes
            i += 2;

            //Store the app id
            info.AppID = appID.ToString();

            //Get the number of players
            info.PlayerCount = buf[i++].ToString();

            //Get the number of max players
            info.MaxPlayers = buf[i++].ToString();

            //Get the number of bots
            info.BotCount = buf[i++].ToString();

            //Get the dedicated server type
            if ((char)buf[i] == 'l')
                info.Dedicated = ServerInfo.DedicatedType.LISTEN;
            else if ((char)buf[i] == 'd')
                info.Dedicated = ServerInfo.DedicatedType.DEDICATED;
            else if ((char)buf[i] == 'p')
                info.Dedicated = ServerInfo.DedicatedType.SOURCETV;

            //Move to the next byte
            i++;

            //Get the OS type
            if ((char)buf[i] == 'l')
                info.OS = ServerInfo.OSType.LINUX;
            else if ((char)buf[i] == 'w')
                info.OS = ServerInfo.OSType.WINDOWS;

            //Move to the next byte
            i++;

            //Check for password protection
            if (buf[i++] == 0x01) info.Password = true;

            //Check for VAC
            if (buf[i++] == 0x01) info.VAC = true;

            StringBuilder versionInfo = new StringBuilder();

            //Get the game version
            while (buf[i] != 0x00)
            {
                versionInfo.Append((char)buf[i]);
                i++;
            }

            //Move to the next byte
            i++;

            //Set the version
            info.Version = versionInfo.ToString();

            return info;
        }
예제 #4
0
        /// <summary>
        /// Pings the specified Source server to retreive information about it such as the server name, max players, current number of players, etc.
        /// </summary>
        /// <returns>Information about the server or throws an SSQLServerException if it could not be retreived</returns>
        public ServerInfo Server()
        {
            //Create a new empty server info object
            ServerInfo info = new ServerInfo();

            //Create an empty buffer
            byte[] buf = null;

            //Create a new packet and request
            Packet requestPacket = new Packet();
            requestPacket.Data = "TSource Engine Query";

            try
            {
                //Attempt to get the server info
                buf = SocketUtils.getInfo(_ipEnd, requestPacket);
            }
            catch(SSQLServerException e)
            {
                throw e;
            }

            //Record the IP the packet came from
            info.IP = _ipEnd.Address.ToString();

            uint i = 0;

            //Make sure the first character is an I
            if (buf[i++] != 'I') return null;

            //Make sure the returned version is above 0x07
            if (buf[i++] < 0x07) return null;

            //Set the name of the server
            info.Name = ReadString(buf,ref i);

            //Set the name of the map
            info.Map = ReadString(buf, ref i);

            //Get the short name for the game
            info.Folder = ReadString(buf, ref i);

            //Get the friendly game description
            info.Game = ReadString(buf, ref i);

            //read the appId of the game
            var appID = ReadUint16(buf, ref i);

            //Store the app id
            info.AppID = appID.ToString();

            //Get the number of players
            info.PlayerCount = buf[i++].ToString();

            //Get the number of max players
            info.MaxPlayers = buf[i++].ToString();

            //Get the number of bots
            info.BotCount = buf[i++].ToString();

            //Get the dedicated server type
            if (buf[i] == 'l')
                info.Dedicated = ServerInfo.DedicatedType.LISTEN;
            else if (buf[i] == 'd')
                info.Dedicated = ServerInfo.DedicatedType.DEDICATED;
            else if (buf[i] == 'p')
                info.Dedicated = ServerInfo.DedicatedType.SOURCETV;

            //Move to the next byte
            i++;

            //Get the OS type
            if (buf[i] == 'l')
                info.OS = ServerInfo.OSType.LINUX;
            else if (buf[i] == 'w')
                info.OS = ServerInfo.OSType.WINDOWS;

            //Move to the next byte
            i++;

            //Check for password protection
            if (buf[i++] == 0x01) info.Password = true;

            //Check for VAC
            if (buf[i++] == 0x01) info.VAC = true;

            //Get the game version
            info.Version = ReadString(buf, ref i);

            //get EDF
            uint edf = buf[i++];

            if ((edf & 0x80) != 0) //has port number
            {
                ushort portNumber = ReadUint16(buf, ref i);
                info.Port = portNumber.ToString();
            }

            if ((edf & 0x10) != 0) //has server SteamId
            {
                ulong serverSteamId = ReadUint64(buf, ref i);
                info.SteamID = serverSteamId.ToString();
            }

            if ((edf & 0x40) != 0) //has spectator port number and name
            {
                //we currently arent storing these anywhere as they aren't needed

                ushort sourceTvPort = ReadUint16(buf, ref i);
                string sourceTvName = ReadString(buf, ref i);
            }

            if ((edf & 0x20) != 0) //has keywords
            {
                info.Keywords = ReadString(buf, ref i);
            }

            if ((edf & 0x01) != 0) //has higher precision GameID
            {
                ulong gameId = ReadUint64(buf, ref i);
                ulong preciseAppId = gameId & 0xFFFFFF; //lower 24-bits contain the appId
                info.AppID = preciseAppId.ToString();
            }

            //should be at the end of the packet now

            return info;
        }