Пример #1
0
        /// <summary>
        /// Delegate for asynchronously receiving UDP packets
        /// </summary>
        private void onDataRecieved(IAsyncResult asyn)
        {               //Use the logger
            using (LogAssume.Assume(_logger))
            {
                PacketBase packet = null;
                int        read   = 0;

                try
                {                       //Sanity checks
                    if (!asyn.IsCompleted)
                    {                   //Abort
                        Log.write(TLog.Warning, "Asynchronous socket operation not completed.");
                        return;
                    }

                    //Receive the data
                    read = _sock.EndReceiveFrom(asyn, ref _remEP);

                    //Read in the typeID
                    ushort typeID = NetworkClient.getTypeID(_buffer, 0);

                    //Handle the initial packet specially
                    bool bNewClient = false;

                    //Initial && system packet?
                    if (_buffer[0] == 0 && typeID == Protocol.CS_Initial.TypeID)
                    {                           //If we're receiving the initial packet, then the client will
                                                //want to begin a new connection state. Destroy the old one!
                                                //Protocol.CS_Initial init = packet as Protocol.CS_Initial;
                        bNewClient = true;
                    }

                    //Attempt to find the related NetworkClient
                    _networkLock.AcquireWriterLock(Timeout.Infinite);
                    NetworkClient client = null;

                    try
                    {                           //Form the uid for the client
                        IPEndPoint ipe = (IPEndPoint)_remEP;
                        Int64      id  = ipe.Address.Address | (((Int64)ipe.Port) << 32);

                        //Do we have a client?
                        if (bNewClient)
                        {                               //This client doesn't exist yet, let's create a new class
                            client = _clientTemplate.newInstance();
                            client._lastPacketRecv = Environment.TickCount;
                            client._ipe            = ipe;
                            client._handler        = this;

                            //Add it to our client list
                            _clients[id] = client;
                        }
                        else
                        {
                            _clients.TryGetValue(id, out client);
                        }

                        //Out of sync packet?
                        if (client == null)
                        {
                            Log.write(TLog.Inane, "Out of state packet received from {0}", _remEP);
                        }
                        //If the client is inactive, ignore
                        else if (client._bDestroyed)
                        {
                            client = null;
                        }
                    }
                    finally
                    {                           //Release our lock
                        _networkLock.ReleaseWriterLock();
                    }

                    if (client != null)
                    {                           //Make sure the packet is intact
                        int offset = 0;
                        if (!client.checkPacket(_buffer, ref offset, ref read))
                        {
                            //Bad packet!
                            Log.write(TLog.Warning, "Bad packet received from {0}", client);
                        }
                        else
                        {                               //Transplant the data into a packet class
                            packet          = _factory.createPacket(client, typeID, _buffer, offset, read);
                            packet._client  = client;
                            packet._handler = this;

                            packet.Deserialize();

                            //Queue it up
                            handlePacket(packet, client);
                            client._lastPacketRecv = Environment.TickCount;
                        }
                    }
                }
                catch (ObjectDisposedException)
                {                       //Socket was closed
                    Log.write(TLog.Inane, "Socket closed.");
                    _bOperating = false;
                    return;
                }
                catch (SocketException se)
                {                       //Store the exception and exit
                    Log.write(TLog.Exception, "Socket exception[{0}]:\r\n{1}", se.ErrorCode, se.ToString());
                }
                catch (Exception ex)
                {                       //Store the exception and exit
                    Log.write(TLog.Exception, "Exception on recieving data:\r\n{0}", ex.ToString());
                    if (packet != null)
                    {
                        Log.write(TLog.Inane, "Packet data:\r\n{0}", packet.DataDump);
                    }
                    else
                    {
                        Log.write(TLog.Inane, "Packet data:\r\n{0}", PacketBase.createDataDump(_buffer, 0, read));
                    }
                }

                try
                {                       //Wait for more data
                    _sock.BeginReceiveFrom(_buffer, 0, _buffer.Length, SocketFlags.None, ref _remEP, onDataRecieved, null);
                }
                catch (SocketException se)
                {                       //Store the exception and exit
                    Log.write(TLog.Exception, "Socket exception[{0}]:\r\n{1}", se.ErrorCode, se.ToString());
                }
            }
        }
Пример #2
0
 /// <summary>
 /// Allows handling of packets before they're dispatched
 /// </summary>
 public virtual bool predispatchCheck(PacketBase packet)
 {
     return(true);
 }