{ /// <summary> /// Creates a new system protocol packet. /// </summary> public PacketBase createSystemPacket(ushort typeID, byte[] buffer, int offset, int size) { //Ready our packet base PacketBase packet = null; offset++; size--; //What are we dealing with? switch (typeID) { case CS_Initial.TypeID: packet = new CS_Initial(typeID, buffer, offset, size); break; case BoxPacket.TypeID: packet = new BoxPacket(typeID, buffer, offset, size); break; case Disconnect.TypeID: packet = new Disconnect(typeID, buffer, offset, size); break; case PingPacket.TypeID: packet = new PingPacket(typeID, buffer, offset, size); break; case CS_State.TypeID: packet = new CS_State(typeID, buffer, offset, size); break; case Reliable.TypeID: packet = new Reliable(typeID, buffer, offset, size, 0); break; case Reliable.TypeID + 1: packet = new Reliable(typeID, buffer, offset, size, 1); break; case Reliable.TypeID + 2: packet = new Reliable(typeID, buffer, offset, size, 2); break; case Reliable.TypeID + 3: packet = new Reliable(typeID, buffer, offset, size, 3); break; case OutOfSync.TypeID: packet = new OutOfSync(typeID, buffer, offset, size, 0); break; case OutOfSync.TypeID + 1: packet = new OutOfSync(typeID, buffer, offset, size, 1); break; case OutOfSync.TypeID + 2: packet = new OutOfSync(typeID, buffer, offset, size, 2); break; case OutOfSync.TypeID + 3: packet = new OutOfSync(typeID, buffer, offset, size, 3); break; case ReliableEcho.TypeID: packet = new ReliableEcho(typeID, buffer, offset, size, 0); break; case ReliableEcho.TypeID + 1: packet = new ReliableEcho(typeID, buffer, offset, size, 1); break; case ReliableEcho.TypeID + 2: packet = new ReliableEcho(typeID, buffer, offset, size, 2); break; case ReliableEcho.TypeID + 3: packet = new ReliableEcho(typeID, buffer, offset, size, 3); break; case ReliableBox.TypeID: packet = new ReliableBox(typeID, buffer, offset, size, 0); break; case ReliableBox.TypeID + 1: packet = new ReliableBox(typeID, buffer, offset, size, 1); break; case ReliableBox.TypeID + 2: packet = new ReliableBox(typeID, buffer, offset, size, 2); break; case ReliableBox.TypeID + 3: packet = new ReliableBox(typeID, buffer, offset, size, 3); break; case DataPacketRcv.TypeID: packet = new DataPacketRcv(typeID, buffer, offset, size, 0); break; case DataPacketRcv.TypeID + 1: packet = new DataPacketRcv(typeID, buffer, offset, size, 1); break; case DataPacketRcv.TypeID + 2: packet = new DataPacketRcv(typeID, buffer, offset, size, 2); break; case DataPacketRcv.TypeID + 3: packet = new DataPacketRcv(typeID, buffer, offset, size, 3); break; default: //An undefined packet. packet = new PacketDummy(typeID, buffer, offset, size); break; } return(packet); }
{ /// <summary> /// Handles all reliable packets received from clients /// </summary> static public void Handle_DataPacketRcv(DataPacketRcv pkt, Client client) { //Get the relevant stream Client.StreamState stream = client._streams[pkt.streamID]; //Is the reliable number what we expected? if (pkt.rNumber > stream.C2S_Reliable) { //Report it! Log.write(TLog.Inane, "OOS Data Packet Stream[{0}]. {1} vs {2}", pkt.streamID, pkt.rNumber, stream.C2S_Reliable); client.reportOutOfSync(pkt, pkt.rNumber, pkt.streamID); return; } //A previously received reliable? else if (pkt.rNumber < stream.C2S_Reliable) { //Re-send the echo ReliableEcho resent = new ReliableEcho(pkt.streamID); resent.rNumber = (ushort)(stream.C2S_Reliable - 1); client.send(resent); return; } //Expect the next! stream.C2S_Reliable++; //Is there a pre-existing stream? if (stream.dataStreamBuffer == null) { //Let's be sensible //This commented part causes issues for some players on certain aliases, removing for now /* * if (pkt.dataSize < client._C2S_UDPSize - client._CRCLength) * { * Log.write(TLog.Error, "Received data stream packet with invalid size {0}", pkt.dataSize); * return; * } */ if (pkt.dataSize > 20 * 1024 * 1024) { Log.write(TLog.Error, "Received data stream packet with invalid size {0}", pkt.dataSize); return; } //Create one of the appropriate size stream.dataStreamBuffer = new byte[pkt.dataSize]; Array.Copy(pkt.data, 4, stream.dataStreamBuffer, 0, pkt.data.Length - 4); stream.dataStreamIndex = pkt.data.Length - 4; } else { //Copy in the data Array.Copy(pkt.data, 0, stream.dataStreamBuffer, stream.dataStreamIndex, pkt.data.Length); stream.dataStreamIndex += pkt.data.Length; //Do we have enough? if (stream.dataStreamIndex >= stream.dataStreamBuffer.Length) { //Create the packet! ushort typeID = NetworkClient.getTypeID(stream.dataStreamBuffer, 0); PacketBase packet = null; try { packet = client._handler.getFactory().createPacket(client, typeID, stream.dataStreamBuffer, 0, stream.dataStreamBuffer.Length); packet._client = client; packet._handler = client._handler; packet.Deserialize(); } catch (Exception ex) { //There was an error while deserializing the packet, create a dummy packet packet = null; Log.write(TLog.Exception, "Exception while deserializing datastream packet:\r\n{0}", ex); } if (packet != null) { client._handler.handlePacket(packet, client); } //Destroy the original stream stream.dataStreamBuffer = null; stream.dataStreamIndex = 0; } } //If we have other packets in seqence waiting in store, use them too PacketBase unhandled; ushort reliableNext = stream.C2S_Reliable; while (stream.oosReliable.TryGetValue(reliableNext, out unhandled)) { //Handle it and go to next packet client._handler.handlePacket(unhandled, client); stream.oosReliable.Remove(reliableNext++); } //Prepare an echo for all received packets ReliableEcho echo = new ReliableEcho(pkt.streamID); echo.streamID = pkt.streamID; echo.rNumber = (ushort)(stream.C2S_Reliable - 1); client.send(echo); }