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;
 }
Exemplo n.º 11
0
        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);
        }
Exemplo n.º 12
0
        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");
            }
        }