/// <summary> /// Ensures that the client is receiving all reliable packets sent /// </summary> /// <remarks>Also is the only function that sends reliable packets.</remarks> private void ensureReliable(Client.StreamState stream) { //Compare times int currentTick = Environment.TickCount; //Do we need to send an out of sync notification? if (stream.lastOOSPacket > stream.C2S_Reliable && currentTick - stream.tickOOSPacket > 100) { OutOfSync oos = new OutOfSync(stream.streamID); oos.streamID = stream.streamID; oos.rNumber = stream.lastOOSPacket; send(oos); stream.tickOOSPacket = currentTick + 200; } //Do we have any bandwidth available? int bytesLeft = _rateThreshold - _bytesWritten; if (bytesLeft < 0) { return; } //We want to start with the first sent packet for (ushort n = stream.S2C_ReliableConfirmed; n < stream.S2C_Reliable; ++n) { //Does it exist? ReliableInfo ri; if (!stream.reliablePackets.TryGetValue(n, out ri)) { continue; } //Has it been delayed too long? if (currentTick - ri.timeSent < 1000) { continue; } //Resend it _packetQueue.Enqueue(ri.packet); //Was it a reattempt? if (ri.timeSent != 0) { ri.attempts++; //Log.write(TLog.Warning, "Reliable packet #" + ri.rid + " lost. (" + ri.attempts + ")"); } ri.timeSent = Environment.TickCount; //Don't go over the bandwidth limit or we'll just complicate things bytesLeft -= ri.packet._size; if (bytesLeft < 0) { break; } } }
{ /// <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); }