Ejemplo n.º 1
0
        private void RefreshThread()
        {
            using (TimedUdpClient client = new TimedUdpClient())
            {
                IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Any, 0);

                try
                {
                    DateTime connectTime = DateTime.Now;
                    Players.Clear();

                    //add default 27015 port if not present
                    if(address.IndexOf(':') == -1)
                        address += ":27015";

                    // attempt to connect
                    Int32 colonIndex = address.IndexOf(':');
                    // what's the timeout???
                    client.Connect(address.Remove(colonIndex), Convert.ToInt32(address.Substring(colonIndex + 1)));

                    if (abortRefresh)
                    {
                        Common.AbortThread(Thread);
                    }

                    // send A2S_INFO
                    // -1 (int), A2S_INFO, "Source Engine Query" (string)
                    DateTime sendTime = DateTime.Now;
                    client.Send(new Byte[] { 0xFF, 0xFF, 0xFF, 0xFF, A2S_INFO, 0x53, 0x6F, 0x75, 0x72, 0x63, 0x65, 0x20, 0x45, 0x6E, 0x67, 0x69, 0x6E, 0x65, 0x20, 0x51, 0x75, 0x65, 0x72, 0x79, 0x00 });

                    // receive A2S_INFO reply
                    Byte[] infoReply = client.Receive(ref ipEndPoint);
                    if (infoReply == null)
                    {
                        title = "Server not responding";
                    }

                    // calculate ping
                    TimeSpan ping = DateTime.Now - connectTime;

                    // parse A2S_INFO reply
                    ParseInfoQueryReply(infoReply);

                    if (client.Available > 0)
                    {
                        client.Receive(ref ipEndPoint);
                    }

                    //Int32 challengeNumber = ParseServerQueryGetChallengeReply(serverQueryGetChallengeReply);
                    Int32 challengeNumber = -1;

                    while (true)
                    {
                        if (abortRefresh)
                        {
                            Common.AbortThread(Thread);
                        }

                        // send A2S_PLAYER
                        BitWriter bitWriter = new BitWriter();
                        bitWriter.WriteInt32(-1);
                        bitWriter.WriteByte(A2S_PLAYER);
                        bitWriter.WriteInt32(challengeNumber);
                        client.Send(bitWriter.Data);

                        // receive and parse A2S_PLAYER reply
                        Byte[] playerReply = client.Receive(ref ipEndPoint);
                        if (playerReply == null)
                        {
                            if (challengeNumber != -1)
                            {
                                // oh, it's a sourcetv server
                                break;
                            }

                            title = "Player query failed";
                        }

                        // check for a challenge number (source servers)
                        BitBuffer bitBuffer = new BitBuffer(playerReply);

                        if (bitBuffer.ReadInt32() != -1)
                        {
                            title = "Bad A2S_PLAYER reply";
                        }

                        Byte type = bitBuffer.ReadByte();

                        if (type == S2C_CHALLENGE)
                        {
                            challengeNumber = bitBuffer.ReadInt32();
                            continue;
                        }
                        else if (type == S2C_PLAYER)
                        {
                            ParsePlayerQueryReply(bitBuffer);
                        }
                        else if (type == S2C_INFO_SOURCE)
                        {
                            ParsePlayerQueryReply(bitBuffer);
                        }
                        else
                        {
                            title = (String.Format("Bad A2S_PLAYER type: {0}", type));
                        }

                        break;
                    }

                }
                catch (ThreadAbortException)
                {
                    throw;
                }
                finally
                {
                    client.Close();
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Parses S2C_PLAYER.
        /// </summary>
        /// <param name="data"></param>
        /// <param name="si"></param>
        private void ParsePlayerQueryReply(BitBuffer bitBuffer)
        {
            Int32 nPlayers = bitBuffer.ReadByte();
            for (Int32 i = 0; i < nPlayers; i++)
            {
                bitBuffer.SeekBytes(1); // skip index

                Player player = new Player();
                player.Name = bitBuffer.ReadString();
                player.Score = bitBuffer.ReadInt32();
                Single time = bitBuffer.ReadSingle();
                player.Time = (time == -1 ? "BOT" : Common.DurationString(time));
                players.Add(player);
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Parses S2C_CHALLENGE and returns the challenge number.
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        private Int32 ParseServerQueryGetChallengeReply(Byte[] data)
        {
            BitBuffer bitBuffer = new BitBuffer(data);

            if (bitBuffer.ReadInt32() != -1)
            {
                throw new ApplicationException("Bad A2S_SERVERQUERY_GETCHALLENGE reply");
            }

            Byte type = bitBuffer.ReadByte();

            if (type != S2C_CHALLENGE)
            {
                throw new ApplicationException(String.Format("Bad A2S_SERVERQUERY_GETCHALLENGE type: {0}", type));
            }

            return bitBuffer.ReadInt32();
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Parses S2C_INFO.
        /// </summary>
        /// <param name="data"></param>
        /// <param name="si"></param>
        private void ParseInfoQueryReply(Byte[] data)
        {
            BitBuffer bitBuffer = new BitBuffer(data);

            if (bitBuffer.ReadInt32() != -1)
            {
                throw new ApplicationException("Bad A2S_INFO reply");
            }

            // read reply type
            Byte type = bitBuffer.ReadByte();
            Boolean sourceEngine;

            if (type == S2C_INFO_SOURCE)
            {
                sourceEngine = true;
            }
            else if (type == S2C_INFO_GOLDSRC)
            {
                sourceEngine = false;
            }
            else
            {
                throw new ApplicationException(String.Format("Bad A2S_INFO type: {0}", type));
            }

            // read the rest
            if (!sourceEngine)
            {
                bitBuffer.ReadString();
                //si.Address = bitBuffer.ReadString(); // resolved hostname
            }
            else
            {
                bitBuffer.SeekBytes(1); // network version
            }

            title = bitBuffer.ReadString();
            map = bitBuffer.ReadString(); // map

            if (sourceEngine)
            {
                bitBuffer.SeekBytes(2); // app id
            }
            bitBuffer.SeekBytes(1); // goldsrc: network version, source: num bots
            bitBuffer.SeekBytes(1); // dedicated
            bitBuffer.SeekBytes(1); // os
        }