/// <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()); } } }
/// <summary> /// Allows handling of packets before they're dispatched /// </summary> public virtual bool predispatchCheck(PacketBase packet) { return(true); }