Пример #1
0
        private void RConnPacketHandler(Packet args)
        {
            if (args.IsRequest)
            {
                var formattedPacket = RecognizedPacket.FormatRequestPacket(args);

                if (MessageEvents.ContainsKey(args.FirstWord) && MessageEvents[args.FirstWord] != null)
                {
                    MessageEvents[args.FirstWord](this, formattedPacket);
                }
            }
            else if(args.IsResponse && RequestCallbacks.ContainsKey(args.SequenceNumber))
            {
                Packet request = RequestPackets[args.SequenceNumber];
                RequestCallbacks[args.SequenceNumber](this, RecognizedPacket.FormatResponsePacket(request, args));
            }

            //Version .1 we only want player.onChat, admin.say, and admin.yell
            if (OnChat.IsOnChat(args))
            {
                var chat = new OnChat(args);
                var message = new ChatMessage
                    {
                        MessageTimeStamp = DateTime.UtcNow,
                        Text = chat.Text,
                        Speaker = chat.SoldierName,
                        MessageType = chat.TargetPlayers.ToString()
                    };

                var chatArgs = new ChatEventArgs(message);
                CommHandler(this, chatArgs);
            }
        }
Пример #2
0
        public static Packet BytesToPacket(this byte[] bytes)
        {
            if (bytes.Length < Packet.HeaderSize)
            {
                return null;
            }

            UInt32 sequenceNumber = bytes.BytesToUInt();
            UInt32 size = bytes.BytesToUInt(4);
            UInt32 numWords = bytes.BytesToUInt(8);

            if (bytes.Length < size)
            {
                return null;
            }

            var result = new Packet
                {
                    OrigininatesFromClient = (sequenceNumber & 0x80000000) > 0,
                    IsResponse = (sequenceNumber & 0x40000000) > 0
                };

            int offset = 12;
            for (int i = 0; i < numWords; i++)
            {
                Word word = bytes.BytesToWord(offset);
                offset += (int) word.Size + 5; //Include the null terminator and the size int
                result.Words.Add(word);
            }

            return result;
        }
Пример #3
0
        /// <summary>
        /// Names the parameters from the specified request packet.
        /// </summary>
        /// <param name="packet">The request to be formatted.</param>
        /// <returns>Name value pairs of the request's parameters.</returns>
        public static Dictionary<string, string> FormatRequestPacket(Packet packet)
        {
            string name = packet.FirstWord;
            if (packet.IsResponse)
            {
                throw new ArgumentException("The specified packet is not a request packet.");
            }

            if (ValidRequestFormats.ContainsKey(name))
            {
                PacketFormat format;
                Dictionary<string, string> parameters = new Dictionary<string, string>();
                try
                {
                    format = ValidRequestFormats[name];
                }
                catch (KeyNotFoundException)
                {
                    throw new ArgumentException("Somehow, the key wasn't in the ValidRequestFormats dictionary...");
                }

                if (packet.WordCount - 1 > format.Parameters.Count && format.Parameters.Count == 0)
                {
                    throw new ArgumentException("Unknown variable packet format.");
                }

                Stack<string> keys = new Stack<string>(format.Parameters.Select(p => p.Name).Reverse());
                Stack<string> words = new Stack<string>(packet.Words.Skip(1).Select(w => new String(w.Content)).Reverse());

                while (keys.Count > 0 && words.Count > 0)
                {
                    string key = keys.Pop();
                    string word = words.Pop();

                    if (parameters.ContainsKey(key))
                    {
                        parameters[key] += word;
                    }
                    else
                    {
                        parameters[key] = word;
                    }

                    //Multi word final parameter
                    if (keys.Count == 0 && words.Count > 0)
                    {
                        keys.Push(key);
                    }
                }

                parameters["packet.Name"] = packet.FirstWord;

                return parameters;
            }

            throw new ArgumentException("Unknown request packet.");
        }
Пример #4
0
        public void RConnPacketHandler(Packet args)
        {
            //Detect a socket exception and initiate a reconnect.
            if (args.FirstWord == "SocketException")
            {
                Disconnect();
                //Continue to attempt to reconnect unless credentials fail.
                while (true)
                {
                    try
                    {
                        Connect(Address, Port, Password);
                        break;
                    }
                    catch (ArgumentException e)
                    {
                        //Bad Password -- we should stop trying to reconnect and let the user handle it.
                        LogUtility.Log(GetType().Name, MethodBase.GetCurrentMethod().Name, e.Message);
                        throw;
                    }
                    catch (Exception e)
                    {
                        //Random connection exceptions; sleep for 2 seconds and try again.
                        LogUtility.Log(GetType().Name, MethodBase.GetCurrentMethod().Name, e.Message);
                        Thread.Sleep(2000);
                    }
                }

                return;
            }

            if (args.IsRequest)
            {
                try
                {
                    var formattedPacket = RecognizedPacket.FormatRequestPacket(args);

                    if (MessageEvents.ContainsKey(args.FirstWord) && MessageEvents[args.FirstWord] != null)
                    {
                        MessageEvents[args.FirstWord](this, formattedPacket);
                    }
                }
                catch (ArgumentException e)
                {
                    LogUtility.Log(GetType().Name, MethodBase.GetCurrentMethod().Name, e.Message);
                    //TODO: Investigate why FormatRequestPacket is throwing an exception upon server reconnects
                }
            }
            else if (args.IsResponse && RequestCallbacks.ContainsKey(args.SequenceNumber))
            {
                Packet request = RequestPackets[args.SequenceNumber];
                if (RequestCallbacks[args.SequenceNumber] != null)
                {
                    RequestCallbacks[args.SequenceNumber](this, RecognizedPacket.FormatResponsePacket(request, args));
                }
            }
        }
Пример #5
0
        /// <summary>
        /// Names the parameters from the specified request packet.
        /// </summary>
        /// <param name="packet">The request to be formatted.</param>
        /// <returns>Name value pairs of the request's parameters.</returns>
        public static Dictionary<string, string> FormatRequestPacket(Packet packet)
        {
            string name = packet.FirstWord;
            if (packet.IsResponse)
            {
                throw new ArgumentException("The specified packet is not a request packet.");
            }

            if (ValidRequestFormats.ContainsKey(name))
            {
                Dictionary<string, string> parameters = new Dictionary<string, string>();
                PacketFormat format = ValidRequestFormats[name];

                // Is this a special packet, using variable length parameters?
                if (packet.WordCount - 1 > format.Parameters.Count && format.Parameters.Count > 0)
                {
                    parameters[format.Parameters[0].Name] = "";
                    foreach (Word word in packet.Words)
                    {
                        parameters[format.Parameters[0].Name] += new string(word.Content);
                    }

                    return parameters;
                }
                else if (packet.WordCount - 1 > format.Parameters.Count && format.Parameters.Count == 0)
                {
                    throw new ArgumentException("Unknown variable packet format.");
                }

                for (int i = 1; i < packet.WordCount; i++)
                {
                    parameters[format.Parameters[i - 1].Name] = new string(packet.Words[i].Content);
                }

                parameters["packet.Name"] = packet.FirstWord;

                return parameters;
            }

            throw new ArgumentException("Unknown request packet.");
        }
Пример #6
0
        public static Packet CreatePacketFromFormattedData(string packetName, Dictionary<string, string> parameters)
        {
            if (!ValidRequestFormats.ContainsKey(packetName) || ValidRequestFormats[packetName].MinimumParameterCount > parameters.Count)
            {
                throw new ArgumentException("Invalid packet data.");
            }

            PacketFormat format = ValidRequestFormats[packetName];

            Packet request = new Packet();
            request.OrigininatesFromClient = true;
            request.SequenceNumber = 0; //This will be filled out before being sent.
            List<Word> words = new List<Word>();
            words.Add(new Word(packetName));

            for (int i = 0; i < parameters.Count; i++)
            {
                words.Add(new Word(parameters[format.Parameters[i].Name]));
            }

            request.Words = words;

            return request;
        }
Пример #7
0
 private void SendOkResponse(Packet packet)
 {
     Sock.Send(new ResponseOk(packet).Emit());
 }
Пример #8
0
        private void ReceivePackets()
        {
            try
            {
                while (Sock.Connected)
                {
                    Packet packet = ReceivePacket();

                    if (packet != null)
                    {
                        if (packet.IsRequest)
                        {
                            HandleRequest(packet);
                        }
                        else if (packet.IsResponse)
                        {
                            HandleResponse(packet);
                        }
                    }
                }
            }
            catch (SocketException ex)
            {
                LogUtility.Log(GetType().Name, MethodBase.GetCurrentMethod().Name, ex.Message);

                Packet serverDied = new Packet();
                List<Word> words = new List<Word>();
                words.Add(new Word("SocketException"));
                words.Add(new Word(ex.Message));
                serverDied.Words = words;

                if (PacketEvent != null)
                {
                    //We're going to return from this function anyway which will end the thread; allow a new MessagePump to be started.
                    MessagePump = null;
                    PacketEvent(serverDied);
                }
            }
        }
Пример #9
0
 private void HandleResponse(Packet packet)
 {
     if (PacketEvent != null)
     {
         PacketEvent(packet);
     }
 }
Пример #10
0
 private void HandleRequest(Packet packet)
 {
     //All requests we'll be getting for version .1 will be events.
     SendOkResponse(packet);
     if (PacketEvent != null)
     {
         PacketEvent(packet);
     }
 }
Пример #11
0
        public Packet SendRequest(Packet packet)
        {
            packet.OrigininatesFromClient = true;
            packet.IsRequest = true;
            packet.SequenceNumber = ++SequenceCounter;
            Sock.Send(packet.Emit());

            return packet;
        }
Пример #12
0
 private void HandleResponse(Packet packet)
 {
     PacketEvent(packet);
 }
Пример #13
0
 private void SendRequest(Packet packet)
 {
     packet.OrigininatesFromClient = true;
     packet.IsRequest = true;
     packet.SequenceNumber = SequenceCounter++;
     Sock.Send(packet.Emit());
 }
Пример #14
0
 private void SendOkResponse(Packet packet)
 {
     packet.OrigininatesFromClient = packet.OrigininatesFromClient;
     packet.IsRequest = false;
     packet.SequenceNumber = packet.SequenceNumber;
     Sock.Send(packet.Emit());
 }
Пример #15
0
        /// <summary>
        /// Names the parameters from the specified response packet.  The associated request packet
        /// is required to differentiate between response formats -- the response name is not unique across
        /// requests.
        /// </summary>
        /// <param name="request">The request which instigated the response.</param>
        /// <param name="response">The response to be formatted.</param>
        /// <returns>Name value pairs of the response's parameters</returns>
        public static Dictionary<string, string> FormatResponsePacket(Packet request, Packet response)
        {
            string requestName = request.FirstWord;
            if (response.IsRequest)
            {
                throw new ArgumentException("The specified packet is not a response packet.");
            }

            if (!request.IsRequest || request.SequenceNumber != response.SequenceNumber)
            {
                throw new ArgumentException("This request response pair is invalid.");
            }

            if (ValidResponseFormats.ContainsKey(requestName))
            {
                List<PacketFormat> formats = ValidResponseFormats[requestName];

                foreach (PacketFormat format in formats)
                {
                    if (response.FirstWord == format.Name && response.WordCount - 1 >= format.MinimumParameterCount)
                    {
                        Dictionary<string, string> parameters = new Dictionary<string, string>();

                        for (int i = 1; i < response.WordCount; i++)
                        {
                            parameters[format.Parameters[i - 1].Name] = new string(response.Words[i].Content);
                        }

                        parameters["packet.Namae"] = response.FirstWord;
                        return parameters;
                    }
                }
            }

            throw new ArgumentException("Unknown request packet.");
        }