void HandleInboundPacket(NetInboundPacket packet) { if (IsPingPacket(packet.Type)) { HandlePingPacket(packet); } else if (packet.Type == NetPacketType.AckResponse) { // Handle ack ushort ackid = packet.ReadUInt16(); if (NetLogger.LogAcks) { NetLogger.LogVerbose("[ACK] Received {0} from {1}", ackid, packet.Sender); } packet.Sender.HandleAck(ackid); } else if (packet.Type == NetPacketType.Custom) { receivedPackets.Enqueue(packet); } else if (packet.Type == NetPacketType.Disconnected) { string reason = packet.ReadString(); bool lostConnection = packet.ReadBool(); packet.Sender.Disconnect(reason, lostConnection); } else if (IsRemotePacket(packet.Type)) { HandleRemotePacket(packet); } else { NetLogger.LogWarning("Invalid packet sent from {0}. Type: {1}", packet.Sender, packet.Type); } }
internal NetInboundPacket(NetInboundPacket original, byte[] data) : base(data) { Sender = original.Sender; Id = original.Id; Type = original.Type; isReliable = original.isReliable; isEncrypted = original.isEncrypted; isCompressed = original.isCompressed; }
void HandlePingPacket(NetInboundPacket packet) { if (packet.Type == NetPacketType.PingRequest) { packet.Sender.SendPingResponse(); } else if (packet.Type == NetPacketType.PingResponse) { packet.Sender.ReceivedPingResponse(); } }
public NetInboundPacket Construct(NetInboundPacket original) { NetBuffer buffer = new NetBuffer(size); for (int i = 0; i < packets.Length; i++) { buffer.WriteBytes(packets[i]); } buffer.RemovePadding(); return(new NetInboundPacket(original, buffer.data)); }
void HandleRemotePacket(NetInboundPacket packet) { // Read the remote header RemoteChannelType type = (RemoteChannelType)packet.ReadByte(); ushort channelId = packet.ReadUInt16(); // Attempt to locate the channel RemoteChannelBase channel = GetRemoteChannelFromPacket(type, channelId); if (channel != null) { inboundRemotes.Enqueue(new InboundRemote(packet, channel)); } }
void ReplyAck(NetInboundPacket packet, IPEndPoint sender) { // Create the ack packet NetOutboundPacket ack = new NetOutboundPacket(NetDeliveryMethod.Unreliable, 3); ack.Type = NetPacketType.AckResponse; ack.Write(packet.Id); // Write the id if (NetLogger.LogAcks) { NetLogger.LogVerbose("[ACK] Replying {0} to {1}", packet.Id, packet.Sender); } // And send packet.Sender.SendPacket(ack); }
void HandleRemoteEvent(NetInboundPacket packet, RemoteChannelBase channel) { // Attempt to locate the event string eventName = packet.ReadString(); RemoteEvent evt; if (channel.Events.TryGetValue(eventName, out evt)) { // Call the event ushort numArgs = packet.ReadUInt16(); evt(packet.Sender, packet, numArgs); } else { NetLogger.LogError("Remote Event \"{0}\" was fired on a {1} channel with the id {2}, but it doesn't exist!", eventName, channel.Type, channel.Id); } }
void HandleRemoteFunctionResponse(NetInboundPacket packet, RemoteChannelBase channel) { // Attempt to locate the function callback string funcName = packet.ReadString(); ushort callbackId = packet.ReadUInt16(); RemoteFunctionCallback callback; if (channel.WaitingFunctions.TryGetValue(callbackId, out callback)) { // Call the callback (hehe) callback(packet.Sender, packet); // Remove the callback from the waiting list channel.WaitingFunctions.TryRemove(callbackId, out callback); } else { NetLogger.LogError( "Received a Remote Function Response for function {0} on channel {1}, but we do not have a callback!", funcName, channel.Id); } }
void HandleRemoteFunction(NetInboundPacket packet, RemoteChannelBase channel) { // Attempt to locate the function string funcName = packet.ReadString(); RemoteFunction func; if (channel.Functions.TryGetValue(funcName, out func)) { // Get the callback id ushort callbackId = packet.ReadUInt16(); // Call the event ushort numArgs = packet.ReadUInt16(); NetBuffer returnValue = func(packet.Sender, packet, numArgs); // Send the response NetOutboundPacket funcResponse = new NetOutboundPacket(NetDeliveryMethod.Reliable); funcResponse.Type = NetPacketType.RemoteFunctionResponse; funcResponse.Encrypt = packet.isEncrypted; // Write the normal remote header funcResponse.Write((byte)channel.Type); funcResponse.Write(channel.Id); funcResponse.Write(funcName); funcResponse.Write(callbackId); // Write the return value funcResponse.WriteBytes(returnValue.data, 0, returnValue.Length); // Send the response packet.Sender.SendPacket(funcResponse); } else { NetLogger.LogError("Remote Function \"{0}\" was invoked on a {1} channel with the id {2}, but it doesn't exist!", funcName, channel.Type, channel.Id); } }
public InboundRemote(NetInboundPacket packet, RemoteChannelBase channel) { Packet = packet; Channel = channel; }
bool HandlePartial(ref NetInboundPacket packet) { // Read the partials header (6 bytes) ushort partialId = packet.ReadUInt16(); byte index = packet.ReadByte(); byte numPartials = packet.ReadByte(); ushort partialSize = packet.ReadUInt16(); PartialPacket partial; // See if the partial already exists if (!packet.Sender.Partials.TryGetValue(partialId, out partial)) { // Since the partial doesn't exist, create one. if (!packet.Sender.Partials.TryAdd(partialId, partial = new PartialPacket(packet.Sender, partialId, numPartials, partialSize))) { //NetLogger.LogError("[Partial:{0}:{1}] Failed to add new partial!", packet.Sender.EndPoint, partialId); //return false; // TODO: See if theres a better way to handle this partial packet concurrency issue // If for some reason, two partials are processed simultaneously, // and it tried adding two packets at once, // we'll just grab the packet created by the other and move on. partial = packet.Sender.Partials[partialId]; } else { if (NetLogger.LogPartials) { NetLogger.LogVerbose("[Partial:{0}:{1}] Starting new; NumPackets: {2}; PacketSize: {3}b", packet.Sender, partialId, numPartials, partialSize); } } } // Add the current partial if (partial.AddPacket(index, packet.ReadBytes(partialSize))) { if (NetLogger.LogPartials) { NetLogger.LogVerbose("[Partial:{0}:{1}] Adding index: {2}; PacketsLeft: {3}", packet.Sender, partialId, index, partial.numPartials - partial.numPartialsReceived); } // Check if the partial is complete if (partial.numPartialsReceived >= partial.numPartials) { // Remove the partial from the connections queue if (packet.Sender.Partials.TryRemove(partial.id, out partial)) { // Save the old sender NetConnection sender = packet.Sender; // Construct the final packet packet = partial.Construct(packet); // Reset the packets parameters packet.ReadOnly = true; if (NetLogger.LogPartials) { NetLogger.LogVerbose("[Partial:{0}:{1}] Constructed final partial; FullSize: {2}b", sender, partialId, packet.Length); } // Process the partial like a physical packet packet.position = 0; if (packet.ReadHeader()) { if (packet.isEncrypted) { NetEncryption.DecryptPacket(packet); } if (packet.isCompressed) { NetCompressor.Decompress(packet); } // Update the stats packet.Sender.PartialPacketReceived(numPartials); // Tell the caller this partial is ready! return(true); } else { // Bad stuff happened NetLogger.LogWarning("[Partial:{0}:{1}] Constructed partial packet had invalid header!", sender, partialId); return(false); } } else { NetLogger.LogError("[Partial:{0}:{1}] Failed to remove completed partial!", packet.Sender, partialId); } } } // Tell the caller this partial is not complete return(false); }
void PacketReceived(byte[] data, IPEndPoint sender, bool parentWasChunk = false) { NetInboundPacketBase packet; NetInboundPacket connectionyPacket = null; bool connectionless; NetConnection senderConn; if (Connections.TryGetValue(sender, out senderConn)) { connectionless = false; packet = connectionyPacket = new NetInboundPacket(senderConn, data); if (!parentWasChunk) { senderConn.PhysicalPacketReceived(); } else { senderConn.PacketReceived(); } } else { connectionless = true; packet = new NetConnectionlessInboundPacket(sender, data); } if (packet.ReadHeader()) { if (packet.isChunked) { byte[][] chunks = packet.GetChunked(); for (int i = 0; i < chunks.Length; i++) { PacketReceived(chunks[i], sender, true); } } else { if (packet.Type == NetPacketType.MTUTest) { return; } if (ignoredConnections.Count > 0 && ignoredConnections.ContainsKey(sender)) { return; } bool packetAlreadyReceived = connectionless ? false : !connectionyPacket.Sender.TryHandlePacket(packet.Id); if (NetLogger.LogPacketReceives && !IsPingPacket(packet.Type) && !packetAlreadyReceived) { NetLogger.LogVerbose("[Inbound:{0}] {1}", sender, packet.ToInternalString()); } if (packet.isReliable && !connectionless) { ReplyAck(connectionyPacket, sender); } else if (packet.isReliable && connectionless) { AddWatchedConnection(sender, "Sent reliable connectionless packet"); } if (packetAlreadyReceived) { if (NetLogger.LogAlreadyHandledPackets) { NetLogger.LogWarning("[DUPLICATE PACKET:{0}] Ignoring packet {1}", sender, packet.Id); } return; } if (packet.isEncrypted) { NetEncryption.DecryptPacket(packet); } if (packet.isCompressed) { NetCompressor.Decompress(packet); } if (packet.isPartial) { if (connectionyPacket == null) { AddWatchedConnection(sender, "Sent connectionless partial packet"); return; } if (!HandlePartial(ref connectionyPacket)) { // Partial is not complete yet, so just return return; } else { // Partial is complete, so overrite the current // packet with the completed packet. packet = connectionyPacket; } } if (connectionless) { HandleConnectionlessInboundPacket((NetConnectionlessInboundPacket)packet); } else { HandleInboundPacket((NetInboundPacket)packet); } } } else { AddWatchedConnection(sender, "Sent packet with invalid signature"); } }