/// <summary> /// Groups packets together into box packets as necessary /// </summary> public ICollection <ReliableInfo> boxReliablePackets(Queue <ReliableInfo> packetQueue, StreamState stream, int streamID) { //Empty? if (packetQueue.Count == 0) { return(null); } //If it's just one packet, there's no need else if (packetQueue.Count == 1) { //We need to put it in a reliable case Reliable reli = new Reliable(); ReliableInfo rinfo = packetQueue.Dequeue(); reli.streamID = streamID; reli.packet = rinfo.packet; rinfo.rid = reli.rNumber = stream.S2C_Reliable++; rinfo.packet = reli; List <ReliableInfo> list = new List <ReliableInfo>(); list.Add(rinfo); return(list); } //Go through the list, creating boxed packets as we go List <ReliableInfo> reliables = new List <ReliableInfo>(); ReliableInfo info; ReliableBox box = new ReliableBox(streamID); int packetStartSize = 4 /*reliable*/ + 2 /*reliable box*/ + _CRCLength; int currentSize = packetStartSize; //Header+footer size of a boxed reliable packet //Group our normal packets while (packetQueue.Count > 0 && packetQueue.Peek().dataStream == null) { ReliableInfo pInfo = packetQueue.Dequeue(); //If the packet exceeds the max limit, send it on it's own if (2 + 1 + pInfo.packet.Length > byte.MaxValue) { //We need to send the previous boxing packets first, as they //should be in order of reliable id if (box.reliables.Count > 0) { info = new ReliableInfo(); info.rid = stream.S2C_Reliable++; //Don't add a lonely box if (box.reliables.Count == 1) { info.packet = new Reliable(box.reliables[0].packet, info.rid, streamID); } else { //Make sure the box is serialized box.MakeSerialized(this, _handler); info.packet = new Reliable(box, info.rid, streamID); } info.consolidateEvents(box.reliables); reliables.Add(info); } box = new ReliableBox(streamID); currentSize = packetStartSize; //Add the packet on it's own Reliable reli = new Reliable(); reli.streamID = streamID; reli.packet = pInfo.packet; pInfo.rid = reli.rNumber = stream.S2C_Reliable++; pInfo.packet = reli; reliables.Add(pInfo); continue; } //Do we have space to add this packet? if (currentSize + pInfo.packet.Length + 1 > udpMaxSize) { //There's not enough room, box up our current packet info = new ReliableInfo(); info.rid = stream.S2C_Reliable++; //Don't add a lonely box if (box.reliables.Count == 1) { info.packet = new Reliable(box.reliables[0].packet, info.rid, streamID); } else { //Make sure the box is serialized box.MakeSerialized(this, _handler); info.packet = new Reliable(box, info.rid, streamID); } info.consolidateEvents(box.reliables); reliables.Add(info); box = new ReliableBox(streamID); currentSize = packetStartSize; } //Add the packet to the box list box.reliables.Add(pInfo); currentSize += pInfo.packet.Length + 1; } //If the last box has more than one packet, keep it if (box.reliables.Count > 1) { info = new ReliableInfo(); info.rid = stream.S2C_Reliable++; //Make sure the box is serialized box.MakeSerialized(this, _handler); info.packet = new Reliable(box, info.rid, streamID); info.consolidateEvents(box.reliables); reliables.Add(info); } else if (box.reliables.Count == 1) { //If it's only one packet, we don't need the box info = new ReliableInfo(); info.rid = stream.S2C_Reliable++; info.packet = new Reliable(box.reliables[0].packet, info.rid, streamID); info.consolidateEvents(box.reliables[0]); reliables.Add(info); } //Boxed them all return(reliables); }
{ /// <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); }