/// <summary> /// Sends queued packets, grouping them where necessary /// </summary> public void sendQueuedPackets() { //Are we over threshold? if (_bytesWritten > _rateThreshold) { return; } //If it's just one packet, there's no need int queueCount = _packetQueue.Count; if (queueCount == 0) { return; } else if (queueCount == 1) { PacketBase packet = _packetQueue.Dequeue(); internalSend(packet); _bytesWritten += packet._size; return; } //Go through the list, creating boxed packets as we go List <PacketBase> boxes = new List <PacketBase>(); BoxPacket box = new BoxPacket(); int currentSize = 2 + _CRCLength; //Header+footer size of a box packet //Send as many packets as we can! while (queueCount > 0 && _bytesWritten < _rateThreshold) { //Get our next packet PacketBase packet = _packetQueue.Dequeue(); _bytesWritten += packet._size; queueCount--; //Do not group data packets if (packet is DataPacket) { boxes.Add(packet); continue; } //Make sure the packet is serialized before we go comparing size packet.MakeSerialized(this, _handler); //If the packet exceeds the max limit, send it on it's own if (2 + 1 + packet.Length > byte.MaxValue) { //WARNING: This may disrupt the reliable flow? boxes.Add(packet); continue; } //Do we have space to add this packet? if (currentSize + packet.Length + 1 > udpMaxSize) { //There's not enough room. Check if our previous packet is on it's //own and actually warrants a box packet. if (box.packets.Count == 1) { boxes.Add(box.packets[0]); } else { boxes.Add(box); } //Create our new box box = new BoxPacket(); currentSize = 2 + _CRCLength; } //Add the packet to the box list box.packets.Add(packet); currentSize += packet.Length + 1; } //If the last box has more than one packet, keep it if (box.packets.Count > 1) { boxes.Add(box); } else if (box.packets.Count == 1) { //If it's only one packet, we don't need the box boxes.Add(box.packets[0]); } //Send all our packets foreach (PacketBase packet in boxes) { internalSend(packet); } }
{ /// <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); }