コード例 #1
0
        internal void Pong(int time, PongPacket pkt)
        {
            try
            {
                if (Random.Next(1, 100000) == 1)
                {
                    Client.GiftCodeReceived("Pong");
                }

                updateLastSeen++;

                if (updateLastSeen >= 60)
                {
                    Manager.Database.DoActionAsync(db =>
                    {
                        db.UpdateLastSeen(Client.Account.AccountId, Client.Character.CharacterId, WorldInstance.Name);
                        updateLastSeen = 0;
                    });
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        }
コード例 #2
0
        void DestroyWorstNeighbor(double?mutualValueLowLimit, DateTime timeNowUtc)
        {
            if (ConnectedNeighbors.Any(x => x.IsInTeardownState))
            {
                return;
            }

            double?worstValue = mutualValueLowLimit;
            ConnectionToNeighbor worstNeighbor = null;

            foreach (var neighbor in ConnectedNeighborsCanBeUsedForNewRequests)
            {
                var p2pConnectionValue_withNeighbor =
                    P2pConnectionValueCalculator.GetMutualP2pConnectionValue(CryptoLibrary,
                                                                             this.Configuration.LocalPeerRegistrationId, this.ConnectedNeighborsBusySectorIds,
                                                                             neighbor.RemoteRegistrationId, neighbor.RemoteNeighborsBusySectorIds ?? 0,
                                                                             Engine.NumberOfDimensions,
                                                                             true,
                                                                             this.AnotherNeighborToSameSectorExists(neighbor),
                                                                             neighbor.Remote_AnotherNeighborToSameSectorExists ?? false
                                                                             );
                Engine.WriteToLog_p2p_higherLevelDetail(neighbor, $"@DestroyWorstNeighbor() p2pConnectionValue_withNeighbor={p2pConnectionValue_withNeighbor} from {this} to {neighbor}", null);
                if (worstValue == null || p2pConnectionValue_withNeighbor < worstValue)
                {
                    worstValue    = p2pConnectionValue_withNeighbor;
                    worstNeighbor = neighbor;
                }
            }

            if (worstNeighbor != null)
            {
                _lastTimeDetroyedWorstNeighborUtc = timeNowUtc;

                Engine.WriteToLog_p2p_higherLevelDetail(worstNeighbor, $"destroying worst P2P connection with neighbor. neighbors count = {ConnectedNeighbors.Count}", null);
                var ping = worstNeighbor.CreatePing(false, true, 0, false);

                var pendingPingRequest = new PendingLowLevelUdpRequest("pendingPingRequest 351", worstNeighbor.RemoteEndpoint,
                                                                       PongPacket.GetScanner(worstNeighbor.LocalNeighborToken32, ping.PingRequestId32), Engine.DateTimeNowUtc,
                                                                       Engine.Configuration.UdpLowLevelRequests_ExpirationTimeoutS,
                                                                       ping.Encode(),
                                                                       Engine.Configuration.UdpLowLevelRequests_InitialRetransmissionTimeoutS,
                                                                       Engine.Configuration.UdpLowLevelRequests_RetransmissionTimeoutIncrement
                                                                       );

                _ = Engine.SendUdpRequestAsync_Retransmit(pendingPingRequest); // retransmit until PONG
                worstNeighbor.IsInTeardownState = true;
                Engine.EngineThreadQueue.EnqueueDelayed(TimeSpan.FromSeconds(PingPacket.ConnectionTeardownStateDurationS), () =>
                {
                    if (!worstNeighbor.IsDisposed)
                    {
                        Engine.WriteToLog_p2p_higherLevelDetail(worstNeighbor, $"destroying worst P2P connection after teardown state timeout", null);
                        worstNeighbor.Dispose();
                    }
                }, "estroying worst P2P connection 2146");
            }
        }
コード例 #3
0
ファイル: KappaClient.cs プロジェクト: barthinator/KappaGame
        private void ListenForMessages()
        {
            NetIncomingMessage message;

            Console.WriteLine("CLIENT: Listening for messages");
            while (isListening)
            {
                while ((message = client.ReadMessage()) != null)
                {
                    switch (message.MessageType)
                    {
                    case NetIncomingMessageType.Data:
                        // handle custom messages
                        //read
                        PacketTypes type      = (PacketTypes)message.ReadByte();
                        PongPacket  payPacket = PacketHelper.Get <PongPacket>(type);
                        payPacket.Deserialize(message);
                        Console.WriteLine($"We got a packet of: {type} with PingMs {payPacket.PingMs}");

                        //send
                        NetOutgoingMessage msg      = client.CreateMessage();
                        PingPacket         outbound = PacketHelper.Get <PingPacket>(PacketTypes.Ping);
                        outbound.PingMs = DateTime.Now.Millisecond;
                        outbound.Serialize(msg);
                        client.SendMessage(msg, message.SenderConnection, NetDeliveryMethod.ReliableOrdered);
                        Console.WriteLine($"We sent a packet of: {PacketTypes.Ping} with PingMs {outbound.PingMs}");
                        break;

                    case NetIncomingMessageType.StatusChanged:
                        // handle connection status messages
                        //switch (message.SenderConnection.Status) {
                        /* .. */
                        //}
                        Console.WriteLine($"CLIENT: Status Changed = {message.SenderConnection.Status}");
                        break;

                    case NetIncomingMessageType.DebugMessage:
                        // handle debug messages
                        // (only received when compiled in DEBUG mode)
                        Console.WriteLine($"CLIENT: {message.ReadString()}");
                        break;

                    /* .. */
                    case NetIncomingMessageType.WarningMessage:
                        Console.WriteLine($"CLIENT: WARNING: {message}");
                        break;

                    default:
                        Console.WriteLine("CLIENT: unhandled message with type: "
                                          + message.MessageType);
                        break;
                    }
                }
            }
            Console.WriteLine("CLIENT: Done listening for messages");
        }
コード例 #4
0
 internal void Pong(int time, PongPacket pkt)
 {
     try
     {
         updateLastSeen++;
     }
     catch (Exception e)
     {
         log.Error(e);
     }
 }
コード例 #5
0
        public async Task PongAsync()
        {
            await _policy.ExecuteAsync(async (content) =>
            {
                await ConnectAsync();

                var Packet = new PongPacket();

                await _embed_channel.WriteAndFlushAsync(Packet);
            }, new Dictionary <string, object>() { { "hld", "PongAsync" } });
        }
コード例 #6
0
ファイル: Player.KeepAlive.cs プロジェクト: trapped/rotmg_svr
 public void Pong(PongPacket pkt)
 {
     if (lastTime != null && (pkt.Time - lastTime.Value > 3000 || pkt.Time - lastTime.Value < 0))
     {
         ;//psr.Disconnect();
     }
     else
     {
         lastTime = pkt.Time;
     }
     tickMapping = ts.Dequeue() - pkt.Time;
     lastPong    = pkt.Time + tickMapping;
 }
コード例 #7
0
        internal void Pong(int time, PongPacket pkt)
        {
            updateLastSeen++;

            if (Owner.Timers.Contains(PongDCTimer))
            {
                Owner.Timers.Remove(PongDCTimer);
            }

            Owner.Timers.Add(PongDCTimer = new WorldTimer(DC_THRESOLD, (w, t) =>
            {
                SendError("Lost connection to server.");
                Client.Disconnect();
            }));
        }
コード例 #8
0
 internal void Pong(int time, PongPacket pkt)
 {
     if (lastTime != null && (time - lastTime.Value > 17500 || time - lastTime.Value < 0))
     {
         SendError("Lost connection to server.");
         client.Disconnect();
     }
     else
     {
         lastTime = time;
     }
     tickMapping = ts.Dequeue() - time;
     lastPong    = time + tickMapping;
     sentPing    = false;
 }
コード例 #9
0
ファイル: Player.KeepAlive.cs プロジェクト: ethus3h/LR-v1
        public void Pong(PongPacket pkt)
        {
            if (lastTime != null && (pkt.Time - lastTime.Value > 15000 || pkt.Time - lastTime.Value < 0))
#pragma warning disable 642
            {
                ; //psr.Disconnect();
            }
#pragma warning restore 642
            else
            {
                lastTime = pkt.Time;
            }
            tickMapping = ts.Dequeue() - pkt.Time;
            lastPong    = pkt.Time + tickMapping;
            sentPing    = false;
        }
コード例 #10
0
        protected override void ChannelRead0(IChannelHandlerContext ctx, PingPacket msg)
        {
            _logger.LogDebug("Receive Ping-[{0}]", msg.PingCode);
            try
            {
                var pongPacket = new PongPacket()
                {
                    Sequence = 0
                };

                ctx.WriteAndFlushAsync(pongPacket);
            }
            finally
            {
                ReferenceCountUtil.SafeRelease(msg);
            }
        }
コード例 #11
0
        static void EncodePongMessage(IByteBufferAllocator bufferAllocator, PongPacket packet, List <object> output)
        {
            IByteBuffer buf = null;

            try
            {
                buf = bufferAllocator.Buffer(PONG_BYTES.Length + CRLF_BYTES.Length);
                buf.WriteBytes(PONG_BYTES);
                buf.WriteBytes(CRLF_BYTES);

                output.Add(buf);
                buf = null;
            }
            finally
            {
                buf?.SafeRelease();
            }
        }
コード例 #12
0
        internal void Pong(int time, PongPacket pkt)
        {
            try
            {
                _updateLastSeen++;

                if (_updateLastSeen >= 60)
                {
                    Manager.Database.DoActionAsync(db =>
                    {
                        db.UpdateLastSeen(Client.Account.AccountId, Client.Character.CharacterId, WorldInstance.Name);
                        _updateLastSeen = 0;
                    });
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        }
コード例 #13
0
ファイル: Player.KeepAlive.cs プロジェクト: ethus3h/LR-v2
        internal void Pong(int time, PongPacket pkt)
        {
            try
            {
                /*if (Random.Next(-999999999, 999999999) == 1)
                 *  Client.GiftCodeReceived("Pong");*/

                /*updateLastSeen++;
                 * if (updateLastSeen >= 300)
                 * {
                 *  Manager.Database.DoActionAsync(db =>
                 *  {
                 *      db.UpdateLastSeen(Client.Account.AccountId, Client.Character.CharacterId, WorldInstance.Name);
                 *      updateLastSeen = 0;
                 *  });
                 * }*/
            }
            catch// (Exception e)
            {
                //log.Error(e);
            }
        }
コード例 #14
0
        internal void Pong(int time, PongPacket pkt)
        {
            try
            {
                if (Random.Next(1, 100000) == 1)
                {
                    updateLastSeen++;
                }

                if (updateLastSeen >= 60)
                {
                    Manager.Database.DoActionAsync(db =>
                    {
                        db.UpdateLastSeen(Client.Account.AccountId, Client.Character.CharacterId, WorldInstance.Name);
                        updateLastSeen = 0;
                    });
                }
            }
            catch (Exception e)
            {
                log.Error(e);
            }
        }
コード例 #15
0
        internal void DoDecode(IChannelHandlerContext context, IByteBuffer buffer, List <object> output)
        {
            ////1 byte type, 4 byte sequence, 4 byte length
            //if (buffer.ReadableBytes < 9)
            //{
            //    return;
            //}
            ////var lengthBuffer = buffer.Slice(5, 4);
            ////// is that right?
            ////var length = lengthBuffer.ReadInt();

            //var length = buffer.GetInt(5);

            //// buffer is smaller than packet length
            //if (buffer.ReadableBytes < 9 + length)
            //{
            //    return;
            //}

            var packetType = (PacketType)buffer.ReadByte();
            var sequence   = buffer.ReadInt();

            switch (packetType)
            {
            case PacketType.PINGREQ:
                var pingCode   = buffer.ReadByte();
                var pingPacket = new PingPacket()
                {
                    Sequence = sequence,
                    PingCode = pingCode
                };
                output.Add(pingPacket);
                break;

            case PacketType.PINGRESP:
                var pongCode   = buffer.ReadByte();
                var pongPacket = new PongPacket()
                {
                    Sequence = sequence,
                    PongCode = pongCode
                };
                output.Add(pongPacket);
                break;

            case PacketType.MESSAGEREQ:
                var req_code         = buffer.ReadShort();
                var req_length       = buffer.ReadInt();
                var messageReqPacket = new MessageReqPacket()
                {
                    Sequence = sequence,
                    Code     = req_code,
                    Body     = new byte[req_length]
                };
                buffer.ReadBytes(messageReqPacket.Body);
                output.Add(messageReqPacket);
                break;

            case PacketType.MESSAGERESP:
                var resp_code         = buffer.ReadShort();
                var resp_length       = buffer.ReadInt();
                var messageRespPacket = new MessageRespPacket()
                {
                    Sequence = sequence,
                    Code     = resp_code,
                    Body     = new byte[resp_length]
                };
                buffer.ReadBytes(messageRespPacket.Body);
                output.Add(messageRespPacket);
                break;

            case PacketType.PUSHREQ:
                var reqPush_type   = buffer.ReadByte();
                var reqPush_code   = buffer.ReadShort();
                var reqPush_length = buffer.ReadInt();
                var reqPushPacket  = new PushReqPacket()
                {
                    Sequence = sequence,
                    Code     = reqPush_code,
                    PushType = (PushType)reqPush_type,
                    Body     = new byte[reqPush_length]
                };
                buffer.ReadBytes(reqPushPacket.Body);
                output.Add(reqPushPacket);
                break;

            case PacketType.PUSHRESP:
                var respPush_type   = buffer.ReadByte();
                var respPush_Code   = buffer.ReadShort();
                var respPush_length = buffer.ReadInt();
                var respPushPacket  = new PushRespPacket()
                {
                    Sequence = sequence,
                    Code     = respPush_Code,
                    PushType = (PushType)respPush_type,
                    Body     = new byte[respPush_length]
                };
                buffer.ReadBytes(respPushPacket.Body);
                output.Add(respPushPacket);
                break;

            default:
                throw new ArgumentException("Invalid packet type!");
            }
        }
コード例 #16
0
        /// <summary>
        /// main register responder proc for both A-EP and P2P modes
        /// in P2P mode Timestamp32S, NeighborToken32 and NeighborHMAC are verified at this time
        /// </summary>
        /// <param name="receivedFromInP2pMode">
        /// is null in A-EP mode
        /// </param>
        internal async Task AcceptRegisterRequestAsync(LocalDrpPeer acceptAt, RoutedRequest routedRequest) // engine thread
        {
            var logger = routedRequest.Logger;

            logger.ModuleName = VisionChannelModuleName_reg_responderSide;
            var req = routedRequest.RegisterReq;

            if (req.RequesterRegistrationId.Equals(acceptAt.Configuration.LocalPeerRegistrationId))
            {
                throw new InvalidOperationException();
            }

            // check  signature of requester (A)
            if (!req.RequesterSignature.Verify(_cryptoLibrary,
                                               w => req.GetSharedSignedFields(w, false),
                                               req.RequesterRegistrationId
                                               )
                )
            {
                throw new BadSignatureException("invalid REGISTER REQ RequesterSignature 2396");
            }

            if (routedRequest.ReceivedFromNeighborNullable == null)
            { // A-EP mode
                if (req.EpEndpoint.Address.Equals(acceptAt.PublicIpApiProviderResponse) == false)
                {
                    throw new PossibleAttackException();
                }
            }

            if (PendingRegisterRequestExists(req.RequesterRegistrationId))
            {
                // received duplicate REGISTER REQ packet
                logger.WriteToLog_needsAttention($"ignoring duplicate registration request {req.RequesterRegistrationId} from {routedRequest.ReceivedFromEndpoint}");
                return;
            }

            if (!RecentUniqueAcceptedRegistrationRequests.Filter(req.GetUniqueRequestIdFields))
            {
                logger.WriteToLog_needsAttention($"ignoring registration request {req.RequesterRegistrationId} ts={req.ReqTimestamp64} from {routedRequest.ReceivedFromEndpoint} with non-unique request ID fields");
                return;
            }

            logger.WriteToLog_higherLevelDetail($"accepting registration from {routedRequest.ReceivedFromEndpoint}: ReqP2pSeq16={req.ReqP2pSeq16}, NumberOfHopsRemaining={req.NumberOfHopsRemaining}, epEndpoint={req.EpEndpoint}, sourcePeer={routedRequest.ReceivedFromNeighborNullable}, ts={req.ReqTimestamp64}");

            if (!RecentUniquePublicEcdhKeys.Filter(req.RequesterEcdhePublicKey.Ecdh25519PublicKey))
            {
                logger.WriteToLog_needsAttention($"ignoring registration request {req.RequesterRegistrationId} from {routedRequest.ReceivedFromEndpoint} with non-unique RequesterEcdhePublicKey");
                return;
            }

            _pendingRegisterRequests.Add(req.RequesterRegistrationId);
            try
            {
                if (logger.WriteToLog_detail_enabled)
                {
                    logger.WriteToLog_detail($"sending NPACK to REQ to {routedRequest.ReceivedFromEndpoint} (delay={routedRequest.ReqReceivedSw_ms}ms)");
                }
                routedRequest.SendNeighborPeerAck_accepted_IfNotAlreadyReplied();

                var newConnectionToNeighbor = new ConnectionToNeighbor(this, acceptAt, ConnectedDrpPeerInitiatedBy.remotePeer, req.RequesterRegistrationId)
                {
                    LocalEndpoint = routedRequest.ReceivedFromNeighborNullable?.LocalEndpoint ?? req.EpEndpoint,
                };
                byte[] ack1UdpData;
                try
                {
                    var ack1 = new RegisterAck1Packet
                    {
                        RequesterRegistrationId = req.RequesterRegistrationId,
                        ReqTimestamp64          = req.ReqTimestamp64,
                        ResponderEcdhePublicKey = new EcdhPublicKey(newConnectionToNeighbor.LocalEcdhe25519PublicKey),
                        ResponderRegistrationId = acceptAt.Configuration.LocalPeerRegistrationId,
                        ReqP2pSeq16             = GetNewNpaSeq16_AtoEP(),
                    };
                    RecentUniquePublicEcdhKeys.AssertIsUnique(ack1.ResponderEcdhePublicKey.Ecdh25519PublicKey, $"ack1.ResponderEcdhePublicKey");
                    ack1.ToResponderTxParametersEncrypted = newConnectionToNeighbor.Encrypt_ack1_ToResponderTxParametersEncrypted_AtResponder_DeriveSharedDhSecret(logger, req, ack1, routedRequest.ReceivedFromNeighborNullable);
                    ack1.ResponderSignature = RegistrationSignature.Sign(_cryptoLibrary,
                                                                         (w2) =>
                    {
                        req.GetSharedSignedFields(w2, true);
                        ack1.GetSharedSignedFields(w2, false, true);
                    },
                                                                         acceptAt.Configuration.LocalPeerRegistrationPrivateKey);
                    if (routedRequest.ReceivedFromNeighborNullable == null)
                    {
                        ack1.RequesterEndpoint = routedRequest.ReceivedFromEndpoint;
                    }
                    ack1UdpData = ack1.Encode_OpionallySignNeighborHMAC(routedRequest.ReceivedFromNeighborNullable);

                    var    ack2Scanner = RegisterAck2Packet.GetScanner(logger, routedRequest.ReceivedFromNeighborNullable, req);
                    var    requesterVisibleDescription = routedRequest.ReceivedFromNeighborNullable?.ToString() ?? routedRequest.ReceivedFromEndpoint.ToString();
                    byte[] ack2UdpData;
                    if (routedRequest.ReceivedFromNeighborNullable == null)
                    {   // wait for ACK2, retransmitting ACK1
                        if (logger.WriteToLog_detail_enabled)
                        {
                            logger.WriteToLog_detail($"sending ACK1, waiting for ACK2");
                        }
                        ack2UdpData = await OptionallySendUdpRequestAsync_Retransmit_WaitForResponse("ack2 33469", requesterVisibleDescription, ack1UdpData, routedRequest.ReceivedFromEndpoint, ack2Scanner);
                    }
                    else
                    {   // retransmit ACK1 until NPACK (via P2P); at same time wait for ACK
                        if (logger.WriteToLog_detail_enabled)
                        {
                            logger.WriteToLog_detail($"sending ACK1, awaiting for NPACK");
                        }
                        _ = OptionallySendUdpRequestAsync_Retransmit_WaitForNeighborPeerAck("ack1 423087", ack1UdpData, routedRequest.ReceivedFromEndpoint,
                                                                                            ack1.ReqP2pSeq16, routedRequest.ReceivedFromNeighborNullable, ack1.GetSignedFieldsForNeighborHMAC);
                        // not waiting for NPACK, wait for ACK
                        if (logger.WriteToLog_detail_enabled)
                        {
                            logger.WriteToLog_detail($"waiting for ACK2");
                        }
                        ack2UdpData = await OptionallySendUdpRequestAsync_Retransmit_WaitForResponse("ack2 46051", requesterVisibleDescription, null, routedRequest.ReceivedFromEndpoint, ack2Scanner);
                    }

                    if (logger.WriteToLog_detail_enabled)
                    {
                        logger.WriteToLog_detail($"received ACK2");
                    }
                    var ack2 = RegisterAck2Packet.Decode_OptionallyVerify_InitializeP2pStreamAtResponder(logger, ack2UdpData, req, ack1, newConnectionToNeighbor);
                    if (logger.WriteToLog_detail_enabled)
                    {
                        logger.WriteToLog_detail($"verified ACK2");
                    }

                    acceptAt.AddToConnectedNeighbors(newConnectionToNeighbor, req);                                                                  // added to list here in order to respond to ping requests from A

                    SendNeighborPeerAckResponseToRegisterAck2(ack2, routedRequest.ReceivedFromEndpoint, routedRequest.ReceivedFromNeighborNullable); // send NPACK to ACK

                    _ = WaitForRegistrationConfirmationRequestAsync(requesterVisibleDescription, logger, routedRequest.ReceivedFromEndpoint, req, newConnectionToNeighbor, routedRequest.ReceivedFromNeighborNullable);

                    #region send ping, verify pong
                    var ping = newConnectionToNeighbor.CreatePing(true, false, acceptAt.ConnectedNeighborsBusySectorIds, acceptAt.AnotherNeighborToSameSectorExists(newConnectionToNeighbor));

                    var pendingPingRequest = new PendingLowLevelUdpRequest("pendingPingRequest 693", newConnectionToNeighbor.RemoteEndpoint,
                                                                           PongPacket.GetScanner(newConnectionToNeighbor.LocalNeighborToken32, ping.PingRequestId32), DateTimeNowUtc,
                                                                           Configuration.InitialPingRequests_ExpirationTimeoutS,
                                                                           ping.Encode(),
                                                                           Configuration.InitialPingRequests_InitialRetransmissionTimeoutS,
                                                                           Configuration.InitialPingRequests_RetransmissionTimeoutIncrement
                                                                           );

                    if (logger.WriteToLog_detail_enabled)
                    {
                        logger.WriteToLog_detail($"sent PING");
                    }
                    var pongPacketData = await SendUdpRequestAsync_Retransmit(pendingPingRequest); // wait for pong from A

                    if (pongPacketData == null)
                    {
                        throw new DrpTimeoutException($"reg. responder initial PING request to {newConnectionToNeighbor} (timeout={Configuration.InitialPingRequests_ExpirationTimeoutS}s)");
                    }
                    var pong = PongPacket.DecodeAndVerify(_cryptoLibrary,
                                                          pongPacketData, ping, newConnectionToNeighbor,
                                                          true);
                    if (logger.WriteToLog_detail_enabled)
                    {
                        logger.WriteToLog_detail($"verified PONG");
                    }
                    newConnectionToNeighbor.OnReceivedVerifiedPong(pong, pendingPingRequest.ResponseReceivedAtUtc.Value,
                                                                   pendingPingRequest.ResponseReceivedAtUtc.Value - pendingPingRequest.InitialTxTimeUTC.Value);
                    #endregion
                }
                catch (Exception exc)
                {
                    newConnectionToNeighbor.Dispose();
                    throw exc;
                }
            }
            catch (DrpTimeoutException exc)
            {
                logger.WriteToLog_needsAttention($"could not accept REGISTER request: {exc}");
            }
            catch (Exception exc)
            {
                logger.WriteToLog_mediumPain($"could not accept REGISTER request: {exc}");
            }
            finally
            {
                _pendingRegisterRequests.Remove(req.RequesterRegistrationId);
            }
        }
コード例 #17
0
        public void OnPing(PingPacket packet)
        {
            var response = new PongPacket(packet.message);

            SendPacket(response);
        }
コード例 #18
0
ファイル: Client.cs プロジェクト: MEDVEDx64/SoundAndVision
        protected override bool HandlePacket(string packet)
        {
            var pongPkt = new PongPacket();

            if (pongPkt.ParsePacket(packet))
            {
                IsAnyPongsAccepted = true;
                return(true);
            }

            var loginPkt = new LoginPacket();

            if (loginPkt.ParsePacket(packet))
            {
                if (loginPkt.Version != PacketBase.ProtocolVersion)
                {
                    SendPacket(new ErrorPacket()
                    {
                        Text = "Unsupported protocol"
                    });
                    return(false);
                }

                if (loginPkt.Id == null && Id == null)
                {
                    SendPacket(new ErrorPacket()
                    {
                        Text = "Please provide me with ID"
                    });
                    return(true);
                }

                if (loginPkt.Id != null)
                {
                    foreach (var cl in server.Clients)
                    {
                        if (cl == this || cl.Id == null)
                        {
                            continue;
                        }

                        /* ID check disabled
                         * if (cl.Id == loginPkt.Id)
                         * {
                         *  SendPacket(new ErrorPacket()
                         *  {
                         *      Text = "ID is already registered"
                         *  });
                         *  return true;
                         * }
                         */
                    }

                    id = (Guid)loginPkt.Id;
                    IdChanged?.Invoke(this, new ValueCarrierEventArgs <Guid?>(id));
                }

                name = loginPkt.Name;
                mode = loginPkt.Mode;
                SendPacket(new AckPacket());

                var ln = (name == null ? "" : name + " ") + "(" + (id == null ? "?" : id.ToString().Substring(0, 8)) + ")";
                server.PrintLog(logName + " has registered as " + ln);
                logName = ln;

                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Name)));
                NameChanged?.Invoke(this, new ValueCarrierEventArgs <string>(name));
                return(true);
            }

            if (mode == LoginMode.Unspecified)
            {
                SendPacket(new ErrorPacket()
                {
                    Text = "Not logged in"
                });
                return(true);
            }

            var displayPkt = new DisplayInfoPacket();

            if (displayPkt.ParsePacket(packet))
            {
                PurgeDisplays();
                var port  = startingPort - 1;
                var ports = new List <ushort>();
                for (int d = 0; d < displayPkt.Displays.Count; d++)
                {
                    port++;
                    if (port > portMax)
                    {
                        throw new Exception("No more network ports available in range");
                    }

                    if (!IsTcpPortAvailable((ushort)port))
                    {
                        d--;
                        continue;
                    }

                    var ds = displayPkt.Displays[d];
                    Displays.Add(new Display((ushort)port, this, ds.Width, ds.Height));
                    ports.Add((ushort)port);
                }

                SendPacket(new DisplayPortsPacket(ports)).Flush();
                return(true);
            }

            var pingPkt = new PingPacket();

            if (pingPkt.ParsePacket(packet))
            {
                SendPacket(new PongPacket()
                {
                    Text = pingPkt.Text
                });
                return(true);
            }

            return(true);
        }
コード例 #19
0
        /// <returns>null if registration failed with timeout or some error code</returns>
        public async Task <ConnectionToNeighbor> RegisterAsync(LocalDrpPeer localDrpPeer, IPEndPoint epEndpoint, uint minimalDistanceToNeighbor,
                                                               byte numberofHops, double[] directionVectorNullable, bool allowConnectionsToRequesterRegistrationId) // engine thread
        {
            var regSW = Stopwatch.StartNew();

            WriteToLog_reg_requesterSide_higherLevelDetail($"connecting via EntryPeer {epEndpoint}", null, null);
            localDrpPeer.CurrentRegistrationOperationsCount++;
            try
            {
                #region PoW1
                RegisterPow1ResponsePacket pow1ResponsePacket = null;
                if (!Configuration.SandboxModeOnly_DisablePoW)
                {
                    WriteToLog_reg_requesterSide_detail($"generating PoW1 request", null, null);
                    var pow1SW = Stopwatch.StartNew();

                    await PowThreadQueue.EnqueueAsync("pow1 6318");

                    WriteToLog_reg_requesterSide_detail($"generating PoW1 request @pow thread", null, null);
                    var registerPow1RequestPacket = GenerateRegisterPow1RequestPacket(localDrpPeer.PublicIpApiProviderResponse.GetAddressBytes(), Timestamp32S);
                    await EngineThreadQueue.EnqueueAsync("pow1 234709");

                    WriteToLog_reg_requesterSide_detail($"generated PoW1 request @engine thread", null, null);

                    // send register pow1 request
                    if (pow1SW.Elapsed.TotalMilliseconds > 3000)
                    {
                        WriteToLog_reg_requesterSide_lightPain($"PoW1 took {(int)pow1SW.Elapsed.TotalMilliseconds}ms", null, null);
                    }
                    WriteToLog_reg_requesterSide_detail($"PoW1 took {(int)pow1SW.Elapsed.TotalMilliseconds}ms. sending PoW1 request", null, null);
                    var rpPow1ResponsePacketData = await SendUdpRequestAsync_Retransmit(
                        new PendingLowLevelUdpRequest("rpPow1 469", epEndpoint,
                                                      RegisterPow1ResponsePacket.GetScanner(registerPow1RequestPacket.Pow1RequestId),
                                                      DateTimeNowUtc,
                                                      Configuration.UdpLowLevelRequests_ExpirationTimeoutS,
                                                      registerPow1RequestPacket.Encode(),
                                                      Configuration.UdpLowLevelRequests_InitialRetransmissionTimeoutS,
                                                      Configuration.UdpLowLevelRequests_RetransmissionTimeoutIncrement
                                                      ));

                    //  wait for response, retransmit
                    if (rpPow1ResponsePacketData == null)
                    {
                        throw new DrpTimeoutException($"pow1 request to EP '{epEndpoint}' (timeout={Configuration.UdpLowLevelRequests_ExpirationTimeoutS}s)");
                    }
                    ;
                    pow1ResponsePacket = new RegisterPow1ResponsePacket(rpPow1ResponsePacketData);
                    WriteToLog_reg_requesterSide_detail($"got PoW1 response with status={pow1ResponsePacket.StatusCode}", null, null);
                    if (pow1ResponsePacket.StatusCode != RegisterPow1ResponseStatusCode.succeeded_Pow2Challenge)
                    {
                        throw new Pow1RejectedException(pow1ResponsePacket.StatusCode);
                    }
                }
                #endregion

                var newConnectionToNeighbor = new ConnectionToNeighbor(this, localDrpPeer, ConnectedDrpPeerInitiatedBy.localPeer, null);

                PongPacket pong;
                var        req = new RegisterRequestPacket
                {
                    RequesterRegistrationId   = localDrpPeer.Configuration.LocalPeerRegistrationId,
                    ReqTimestamp64            = Timestamp64,
                    MinimalDistanceToNeighbor = minimalDistanceToNeighbor,
                    RequesterNatBehaviour     = LocalNatBehaviour,
                    AllowConnectionsToRequesterRegistrationId = allowConnectionsToRequesterRegistrationId,
                    NumberOfHopsRemaining   = numberofHops,
                    RequesterEcdhePublicKey = new EcdhPublicKey(newConnectionToNeighbor.LocalEcdhe25519PublicKey),
                    ReqP2pSeq16             = GetNewNpaSeq16_AtoEP(),
                    EpEndpoint = epEndpoint,
                    DirectionVectorNullableD = directionVectorNullable
                };
                var logger = new Logger(this, localDrpPeer, req, VisionChannelModuleName_reg_requesterSide);
                try
                {
                    #region register REQ  PoW2
                    RecentUniquePublicEcdhKeys.AssertIsUnique(req.RequesterEcdhePublicKey.Ecdh25519PublicKey, $"req.RequesterEcdhePublicKey {req}"); // this is used in non-standard way when routing registration requests to same (local) reg. ID,  too

                    var pow2SW = Stopwatch.StartNew();
                    if (!Configuration.SandboxModeOnly_DisablePoW)
                    {
                        await PowThreadQueue.EnqueueAsync("pow2 23465");

                        if (logger.WriteToLog_detail_enabled)
                        {
                            logger.WriteToLog_detail($"calculating PoW2 @pow thread");
                        }
                        GenerateRegisterReqPow2(req, pow1ResponsePacket.ProofOfWork2Request);
                        await EngineThreadQueue.EnqueueAsync("pow2 2496");

                        if (logger.WriteToLog_detail_enabled)
                        {
                            logger.WriteToLog_detail($"calculated PoW2 @engine thread");
                        }
                    }
                    else
                    {
                        req.ProofOfWork2 = new byte[64];
                    }
                    pow2SW.Stop();
                    if (pow2SW.Elapsed.TotalMilliseconds > 3000)
                    {
                        logger.WriteToLog_lightPain($"PoW2 took {(int)pow2SW.Elapsed.TotalMilliseconds}ms");
                    }

                    req.RequesterSignature = RegistrationSignature.Sign(_cryptoLibrary,
                                                                        w => req.GetSharedSignedFields(w, false),
                                                                        localDrpPeer.Configuration.LocalPeerRegistrationPrivateKey
                                                                        );
                    var reqToAck1Stopwatch = Stopwatch.StartNew();

                    if (logger.WriteToLog_detail_enabled)
                    {
                        logger.WriteToLog_detail($"PoW2 took {(int)pow2SW.Elapsed.TotalMilliseconds}ms. sending REQ, waiting for NPACK. ReqP2pSeq16={req.ReqP2pSeq16}");
                    }
                    #endregion

                    //  var reqSW = Stopwatch.StartNew();
                    #region wait for ACK1
                    var sentRequest = new SentRequest(this, logger, epEndpoint, null, req.Encode_OptionallySignNeighborHMAC(null), req.ReqP2pSeq16, RegisterAck1Packet.GetScanner(logger, req));
                    var ack1UdpData = await sentRequest.SendRequestAsync("reg req ack1 367097");

                    var ack1 = RegisterAck1Packet.DecodeAndOptionallyVerify(logger, ack1UdpData, req, newConnectionToNeighbor);
                    if (logger.WriteToLog_detail_enabled)
                    {
                        logger.WriteToLog_detail($"verified ACK1. RequesterEndpoint={ack1.RequesterEndpoint}");
                    }
                    #endregion



                    // check if it matches to previously known local public IP
                    if (ack1.RequesterEndpoint.Address.Equals(localDrpPeer.PublicIpApiProviderResponse) == false)
                    {
                        // MITM attack / EP sent local (requester) endpoint IP some bad IP address
                        throw new PossibleAttackException();
                    }
                    RecentUniquePublicEcdhKeys.AssertIsUnique(ack1.ResponderEcdhePublicKey.Ecdh25519PublicKey, $"ack1.ResponderEcdhePublicKey from {epEndpoint}");

                    newConnectionToNeighbor.LocalEndpoint        = ack1.RequesterEndpoint;
                    newConnectionToNeighbor.RemoteRegistrationId = ack1.ResponderRegistrationId;
                    reqToAck1Stopwatch.Stop();
                    var reqToAck1TimeMs = reqToAck1Stopwatch.Elapsed.TotalMilliseconds;
                    if (logger.WriteToLog_detail_enabled)
                    {
                        logger.WriteToLog_detail($"measured  REQ-ACK1_RTT={(int)reqToAck1TimeMs}ms");
                    }

                    #region send ACK2, encode local IP
                    var ack2 = new RegisterAck2Packet
                    {
                        ReqTimestamp64          = req.ReqTimestamp64,
                        RequesterRegistrationId = localDrpPeer.Configuration.LocalPeerRegistrationId,
                        ReqP2pSeq16             = GetNewNpaSeq16_AtoEP()
                    };
                    ack2.ToRequesterTxParametersEncrypted = newConnectionToNeighbor.Encrypt_ack2_ToRequesterTxParametersEncrypted_AtRequester(logger, req, ack1, ack2);
                    newConnectionToNeighbor.InitializeP2pStream(req, ack1, ack2);
                    ack2.RequesterSignature = RegistrationSignature.Sign(_cryptoLibrary, w =>
                    {
                        req.GetSharedSignedFields(w, true);
                        ack1.GetSharedSignedFields(w, true, true);
                        ack2.GetSharedSignedFields(w, false, true);
                    },
                                                                         localDrpPeer.Configuration.LocalPeerRegistrationPrivateKey
                                                                         );

                    if (logger.WriteToLog_detail_enabled)
                    {
                        logger.WriteToLog_detail($"sending ACK2 (in response to ACK1), waiting for NPACK");
                    }
                    RespondToRequestAndRetransmissions(ack1UdpData, ack2.Encode_OptionallySignNeighborHMAC(null), epEndpoint);
                    await OptionallySendUdpRequestAsync_Retransmit_WaitForNeighborPeerAck("ack2 46873", null, epEndpoint, ack2.ReqP2pSeq16);

                    #endregion

                    var neighborWaitTimeMs = reqToAck1TimeMs * 0.5 - 250; if (neighborWaitTimeMs < 0)
                    {
                        neighborWaitTimeMs = 0;
                    }
                    if (neighborWaitTimeMs > 20)
                    {
                        if (logger.WriteToLog_detail_enabled)
                        {
                            logger.WriteToLog_detail($"awaiting {(int)neighborWaitTimeMs}ms before PING...");
                        }
                        await EngineThreadQueue.WaitAsync(TimeSpan.FromMilliseconds(neighborWaitTimeMs), "before PING 34589"); // wait until the ACK2 reaches neighbor N via peers

                        if (logger.WriteToLog_detail_enabled)
                        {
                            logger.WriteToLog_detail($"... awaiting is complete");
                        }
                    }

                    localDrpPeer.AddToConnectedNeighbors(newConnectionToNeighbor, req);

                    #region send ping request directly to neighbor N, retransmit
                    var pingRequest = newConnectionToNeighbor.CreatePing(true, false, localDrpPeer.ConnectedNeighborsBusySectorIds, localDrpPeer.AnotherNeighborToSameSectorExists(newConnectionToNeighbor));
                    newConnectionToNeighbor.InitialPendingPingRequest = new PendingLowLevelUdpRequest("pingRequest 3850", newConnectionToNeighbor.RemoteEndpoint,
                                                                                                      PongPacket.GetScanner(newConnectionToNeighbor.LocalNeighborToken32, pingRequest.PingRequestId32),
                                                                                                      DateTimeNowUtc,
                                                                                                      Configuration.InitialPingRequests_ExpirationTimeoutS,
                                                                                                      pingRequest.Encode(),
                                                                                                      Configuration.InitialPingRequests_InitialRetransmissionTimeoutS,
                                                                                                      Configuration.InitialPingRequests_RetransmissionTimeoutIncrement
                                                                                                      );

                    if (logger.WriteToLog_detail_enabled)
                    {
                        logger.WriteToLog_detail($"sending PING neighborToken32={pingRequest.NeighborToken32}, waiting for PONG");
                    }
                    var pongPacketData = await SendUdpRequestAsync_Retransmit(newConnectionToNeighbor.InitialPendingPingRequest);

                    if (pongPacketData == null)
                    {
                        throw new DrpTimeoutException($"initial reg. requester PING to {newConnectionToNeighbor} (timeout={Configuration.InitialPingRequests_ExpirationTimeoutS}s)");
                    }
                    if (newConnectionToNeighbor.IsDisposed)
                    {
                        throw new ObjectDisposedException($"initial reg. requester PING to {newConnectionToNeighbor} (special case: connection is disposed)", (Exception)null);                                     // ping timeout already destroyed the connection, so PONG response here is too late
                    }
                    pong = PongPacket.DecodeAndVerify(_cryptoLibrary,
                                                      pongPacketData, pingRequest, newConnectionToNeighbor,
                                                      true);
                    if (logger.WriteToLog_detail_enabled)
                    {
                        logger.WriteToLog_detail($"verified PONG");
                    }
                    newConnectionToNeighbor.OnReceivedVerifiedPong(pong, newConnectionToNeighbor.InitialPendingPingRequest.ResponseReceivedAtUtc.Value,
                                                                   newConnectionToNeighbor.InitialPendingPingRequest.ResponseReceivedAtUtc.Value - newConnectionToNeighbor.InitialPendingPingRequest.InitialTxTimeUTC.Value);
                    #endregion
                }
                catch
                {
                    // todo update QoS
                    newConnectionToNeighbor.Dispose(); // remove from token32 table
                    throw;
                }

                #region send registration confirmation packet to EP->X->N
                try
                {
                    var cfm = new RegisterConfirmationPacket
                    {
                        ReqTimestamp64          = req.ReqTimestamp64,
                        RequesterRegistrationId = localDrpPeer.Configuration.LocalPeerRegistrationId,
                        ResponderRegistrationConfirmationSignature = pong.ResponderRegistrationConfirmationSignature,
                        ReqP2pSeq16 = GetNewNpaSeq16_AtoEP()
                    };
                    cfm.RequesterRegistrationConfirmationSignature = RegistrationSignature.Sign(_cryptoLibrary,
                                                                                                w => newConnectionToNeighbor.GetRequesterRegistrationConfirmationSignatureFields(w, cfm.ResponderRegistrationConfirmationSignature),
                                                                                                localDrpPeer.Configuration.LocalPeerRegistrationPrivateKey);
                    if (logger.WriteToLog_detail_enabled)
                    {
                        logger.WriteToLog_detail($"sending CFM, waiting for NPACK");
                    }
                    await OptionallySendUdpRequestAsync_Retransmit_WaitForNeighborPeerAck("cfm 32107", cfm.Encode_OptionallySignNeighborHMAC(null), epEndpoint, cfm.ReqP2pSeq16);

                    if (logger.WriteToLog_detail_enabled)
                    {
                        logger.WriteToLog_detail($"received NPACK to CFM");
                    }
                }
                catch (DrpTimeoutException exc)
                {  // we ingnore exceptions here, just wite warning to log.  the connection is alive already, as direct ping channel to neighbor is set up
                    logger.WriteToLog_needsAttention($"... registration confirmation request failed: {exc}");
                }
                catch (Exception exc)
                {  // we ingnore exceptions here, just wite warning to log.  the connection is alive already, as direct ping channel to neighbor is set up
                    logger.WriteToLog_mediumPain($"... registration confirmation request failed: {exc}");
                }
                #endregion

                regSW.Stop();
                if (regSW.Elapsed.TotalMilliseconds > 5000)
                {
                    logger.WriteToLog_lightPain($"registration is completed in {(int)regSW.Elapsed.TotalMilliseconds}ms");
                }
                else
                {
                    logger.WriteToLog_higherLevelDetail($"registration is completed in {(int)regSW.Elapsed.TotalMilliseconds}ms");
                };

                return(newConnectionToNeighbor);
            }
            finally
            {
                localDrpPeer.CurrentRegistrationOperationsCount--;
            }
        }
コード例 #20
0
        /// <summary>
        /// is used to expand neighborhood
        /// </summary>
        internal async Task RegisterAsync(uint minimalDistanceToNeighbor, ushort busySectorIds, byte numberOfHopsRemaining, byte numberOfRandomHopsRemaining, double[] directionVectorNullable, bool allowConnectionsToRequesterRegistrationId)
        {
            _engine.WriteToLog_reg_requesterSide_detail($">> ConnectionToNeighbor.RegisterAsync(minimalDistanceToNeighbor={minimalDistanceToNeighbor}", null, null);
            _localDrpPeer.CurrentRegistrationOperationsCount++;

            try
            {
                var        newConnectionToNeighbor = new ConnectionToNeighbor(_engine, _localDrpPeer, ConnectedDrpPeerInitiatedBy.localPeer, null);
                PongPacket pong;
                //  PendingLowLevelUdpRequest pendingPingRequest;
                var req = new RegisterRequestPacket
                {
                    RequesterRegistrationId   = _localDrpPeer.Configuration.LocalPeerRegistrationId,
                    ReqTimestamp64            = _engine.Timestamp64,
                    MinimalDistanceToNeighbor = minimalDistanceToNeighbor,
                    RequesterNatBehaviour     = _engine.LocalNatBehaviour,
                    AllowConnectionsToRequesterRegistrationId = allowConnectionsToRequesterRegistrationId,
                    RequesterNeighborsBusySectorIds           = busySectorIds,
                    NumberOfHopsRemaining       = numberOfHopsRemaining,
                    NumberOfRandomHopsRemaining = numberOfRandomHopsRemaining,
                    RequesterEcdhePublicKey     = new EcdhPublicKey(newConnectionToNeighbor.LocalEcdhe25519PublicKey),
                    ReqP2pSeq16 = GetNewRequestP2pSeq16_P2P(),
                    EpEndpoint  = this.RemoteEndpoint,
                    DirectionVectorNullableD = directionVectorNullable
                };
                var logger = new Logger(Engine, LocalDrpPeer, req, DrpPeerEngine.VisionChannelModuleName_reg_requesterSide);
                try
                {
                    _engine.RecentUniquePublicEcdhKeys.AssertIsUnique(req.RequesterEcdhePublicKey.Ecdh25519PublicKey, $"req.RequesterEcdhePublicKey {req}");

                    req.RequesterSignature = RegistrationSignature.Sign(_engine.CryptoLibrary,
                                                                        w => req.GetSharedSignedFields(w, false),
                                                                        _localDrpPeer.Configuration.LocalPeerRegistrationPrivateKey
                                                                        );

                    var reqToAck1Stopwatch = Stopwatch.StartNew();

                    #region wait for ACK1, respond with NPACK
                    if (logger.WriteToLog_detail_enabled)
                    {
                        logger.WriteToLog_detail($"sending {req}, waiting for NPACK. ReqP2pSeq16={req.ReqP2pSeq16}");
                    }

                    var sentRequest = new SentRequest(Engine, logger, this.RemoteEndpoint, this, req.Encode_OptionallySignNeighborHMAC(this),
                                                      req.ReqP2pSeq16, RegisterAck1Packet.GetScanner(logger, req, this));
                    var ack1UdpData = await sentRequest.SendRequestAsync("reg req ack1 42084");

                    var ack1 = RegisterAck1Packet.DecodeAndOptionallyVerify(logger, ack1UdpData, req, newConnectionToNeighbor);
                    if (logger.WriteToLog_detail_enabled)
                    {
                        logger.WriteToLog_detail($"verified ACK1, sending NPACK to ACK1");
                    }

                    _engine.SendNeighborPeerAckResponseToRegisterAck1(ack1, this);
                    #endregion

                    if (newConnectionToNeighbor.IsDisposed)
                    {
                        logger.WriteToLog_needsAttention($"connection {newConnectionToNeighbor} is disposed during reg. request 5345322345");
                        return;
                    }
                    if (IsDisposed)
                    {
                        logger.WriteToLog_needsAttention($"connection {this} is disposed during reg. request 5345322345");
                        return;
                    }
                    _engine.RecentUniquePublicEcdhKeys.AssertIsUnique(ack1.ResponderEcdhePublicKey.Ecdh25519PublicKey, $"ack1.ResponderEcdhePublicKey from {newConnectionToNeighbor}");

                    newConnectionToNeighbor.LocalEndpoint        = this.LocalEndpoint;
                    newConnectionToNeighbor.RemoteRegistrationId = ack1.ResponderRegistrationId;
                    reqToAck1Stopwatch.Stop();
                    var reqToAck1TimeMs = reqToAck1Stopwatch.Elapsed.TotalMilliseconds;
                    if (logger.WriteToLog_detail_enabled)
                    {
                        logger.WriteToLog_detail($"measured REQ-ACK1 RTT = {(int)reqToAck1TimeMs}ms");
                    }

                    #region send ACK2, encode local IP
                    var ack2 = new RegisterAck2Packet
                    {
                        ReqTimestamp64          = req.ReqTimestamp64,
                        RequesterRegistrationId = _localDrpPeer.Configuration.LocalPeerRegistrationId,
                        ReqP2pSeq16             = GetNewRequestP2pSeq16_P2P(),
                    };
                    ack2.ToRequesterTxParametersEncrypted = newConnectionToNeighbor.Encrypt_ack2_ToRequesterTxParametersEncrypted_AtRequester(logger, req, ack1, ack2);
                    newConnectionToNeighbor.InitializeP2pStream(req, ack1, ack2);
                    ack2.RequesterSignature = RegistrationSignature.Sign(_engine.CryptoLibrary, w =>
                    {
                        req.GetSharedSignedFields(w, true);
                        ack1.GetSharedSignedFields(w, true, true);
                        ack2.GetSharedSignedFields(w, false, true);
                    },
                                                                         _localDrpPeer.Configuration.LocalPeerRegistrationPrivateKey
                                                                         );

                    if (logger.WriteToLog_detail_enabled)
                    {
                        logger.WriteToLog_detail($"sending ACK2 (in response to ACK1), waiting for NPACK");
                    }
                    await _engine.OptionallySendUdpRequestAsync_Retransmit_WaitForNeighborPeerAck("ack2 1235739", ack2.Encode_OptionallySignNeighborHMAC(this), this.RemoteEndpoint, ack2.ReqP2pSeq16);

                    #endregion

                    var neighborWaitTimeMs = reqToAck1TimeMs * 0.5 - 100; if (neighborWaitTimeMs < 0)
                    {
                        neighborWaitTimeMs = 0;
                    }
                    if (neighborWaitTimeMs > 20)
                    {
                        await _engine.EngineThreadQueue.WaitAsync(TimeSpan.FromMilliseconds(neighborWaitTimeMs), "neighborWaitTimeMs45236"); // wait until the ACK2 reaches neighbor N via peers
                    }


                    if (newConnectionToNeighbor.IsDisposed)
                    {
                        logger.WriteToLog_needsAttention($"connection {newConnectionToNeighbor} is disposed during reg. request 234574568");
                        return;
                    }
                    if (IsDisposed)
                    {
                        logger.WriteToLog_needsAttention($"connection {this} is disposed during reg. request 234574568");
                        return;
                    }

                    _localDrpPeer.AddToConnectedNeighbors(newConnectionToNeighbor, req);

                    #region send ping request directly to neighbor N, retransmit
                    var pingRequest = newConnectionToNeighbor.CreatePing(true, false, _localDrpPeer.ConnectedNeighborsBusySectorIds, _localDrpPeer.AnotherNeighborToSameSectorExists(newConnectionToNeighbor));
                    newConnectionToNeighbor.InitialPendingPingRequest = new PendingLowLevelUdpRequest("pendingPingRequest 12247", newConnectionToNeighbor.RemoteEndpoint,
                                                                                                      PongPacket.GetScanner(newConnectionToNeighbor.LocalNeighborToken32, pingRequest.PingRequestId32),
                                                                                                      _engine.DateTimeNowUtc,
                                                                                                      _engine.Configuration.InitialPingRequests_ExpirationTimeoutS,
                                                                                                      pingRequest.Encode(),
                                                                                                      _engine.Configuration.InitialPingRequests_InitialRetransmissionTimeoutS,
                                                                                                      _engine.Configuration.InitialPingRequests_RetransmissionTimeoutIncrement
                                                                                                      );

                    if (logger.WriteToLog_detail_enabled)
                    {
                        logger.WriteToLog_detail($"sending PING, waiting for PONG");
                    }
                    var pongPacketData = await _engine.SendUdpRequestAsync_Retransmit(newConnectionToNeighbor.InitialPendingPingRequest);

                    if (pongPacketData == null)
                    {
                        throw new DrpTimeoutException($"reg. requester initial PING to {newConnectionToNeighbor} (timeout={_engine.Configuration.InitialPingRequests_ExpirationTimeoutS}s)");
                    }
                    if (newConnectionToNeighbor.IsDisposed)
                    {
                        logger.WriteToLog_needsAttention($"connection {newConnectionToNeighbor} is disposed during reg. request 548798");
                        return;
                    }
                    if (IsDisposed)
                    {
                        logger.WriteToLog_needsAttention($"connection {this} is disposed during reg. request 548798");
                        return;
                    }

                    pong = PongPacket.DecodeAndVerify(_engine.CryptoLibrary,
                                                      pongPacketData, pingRequest, newConnectionToNeighbor,
                                                      true);
                    if (logger.WriteToLog_detail_enabled)
                    {
                        logger.WriteToLog_detail($"verified PONG");
                    }
                    newConnectionToNeighbor.OnReceivedVerifiedPong(pong, newConnectionToNeighbor.InitialPendingPingRequest.ResponseReceivedAtUtc.Value,
                                                                   newConnectionToNeighbor.InitialPendingPingRequest.ResponseReceivedAtUtc.Value - newConnectionToNeighbor.InitialPendingPingRequest.InitialTxTimeUTC.Value);
                    #endregion
                }
                catch
                {
                    // todo update QoS
                    newConnectionToNeighbor.Dispose(); // remove from token32 table
                    throw;
                }

                #region send registration confirmation packet to X->N
                try
                {
                    if (newConnectionToNeighbor.IsDisposed)
                    {
                        logger.WriteToLog_needsAttention($"connection {newConnectionToNeighbor} is disposed during reg. request 541687987");
                        return;
                    }
                    if (IsDisposed)
                    {
                        logger.WriteToLog_needsAttention($"connection {this} is disposed during reg. request 541687987");
                        return;
                    }
                    var cfm = new RegisterConfirmationPacket
                    {
                        ReqTimestamp64          = req.ReqTimestamp64,
                        RequesterRegistrationId = _localDrpPeer.Configuration.LocalPeerRegistrationId,
                        ResponderRegistrationConfirmationSignature = pong.ResponderRegistrationConfirmationSignature,
                        ReqP2pSeq16 = GetNewRequestP2pSeq16_P2P()
                    };
                    cfm.RequesterRegistrationConfirmationSignature = RegistrationSignature.Sign(_engine.CryptoLibrary,
                                                                                                w => newConnectionToNeighbor.GetRequesterRegistrationConfirmationSignatureFields(w, cfm.ResponderRegistrationConfirmationSignature),
                                                                                                _localDrpPeer.Configuration.LocalPeerRegistrationPrivateKey);
                    if (logger.WriteToLog_detail_enabled)
                    {
                        logger.WriteToLog_detail($"sending CFM, waiting for NPACK");
                    }
                    await _engine.OptionallySendUdpRequestAsync_Retransmit_WaitForNeighborPeerAck("cfm 14478", cfm.Encode_OptionallySignNeighborHMAC(this), this.RemoteEndpoint, cfm.ReqP2pSeq16);

                    if (logger.WriteToLog_detail_enabled)
                    {
                        logger.WriteToLog_detail($"received NPACK to CFM");
                    }
                }
                catch (DrpTimeoutException exc)
                {  // we ingnore exceptions here, just wite warning to log.  the connection is alive already, as direct ping channel to neighbor is set up
                    logger.WriteToLog_needsAttention($"... registration confirmation request failed: {exc}");
                }
                catch (Exception exc)
                {  // we ingnore exceptions here, just wite warning to log.  the connection is alive already, as direct ping channel to neighbor is set up
                    logger.WriteToLog_mediumPain($"... registration confirmation request failed: {exc}");
                }
                #endregion

                return;// newConnectionToNeighbor;
            }
            finally
            {
                _localDrpPeer.CurrentRegistrationOperationsCount--;
            }
        }
コード例 #21
0
        public void ProcessPacket(ZoneConnection client, SubPacket subpacket)
        {
            Session session = mServer.GetSession(subpacket.header.sourceId);

            if (session == null && subpacket.gameMessage.opcode != 0x1000)
            {
                return;
            }

            //Normal Game Opcode
            switch (subpacket.gameMessage.opcode)
            {
            //World Server - Error
            case 0x100A:
                ErrorPacket worldError = new ErrorPacket(subpacket.data);
                switch (worldError.errorCode)
                {
                case 0x01:
                    session.GetActor().SendGameMessage(Server.GetWorldManager().GetActor(), 60005, 0x20);
                    break;
                }
                break;

            //World Server - Session Begin
            case 0x1000:
                subpacket.DebugPrintSubPacket();

                SessionBeginPacket beginSessionPacket = new SessionBeginPacket(subpacket.data);

                session = mServer.AddSession(subpacket.header.sourceId);

                if (!beginSessionPacket.isLogin)
                {
                    Server.GetWorldManager().DoZoneIn(session.GetActor(), false, session.GetActor().destinationSpawnType);
                }

                Program.Log.Info("{0} has been added to the session list.", session.GetActor().customDisplayName);

                client.FlushQueuedSendPackets();
                break;

            //World Server - Session End
            case 0x1001:
                SessionEndPacket endSessionPacket = new SessionEndPacket(subpacket.data);

                if (endSessionPacket.destinationZoneId == 0)
                {
                    session.GetActor().CleanupAndSave();
                }
                else
                {
                    session.GetActor().CleanupAndSave(endSessionPacket.destinationZoneId, endSessionPacket.destinationSpawnType, endSessionPacket.destinationX, endSessionPacket.destinationY, endSessionPacket.destinationZ, endSessionPacket.destinationRot);
                }

                Server.GetServer().RemoveSession(session.id);
                Program.Log.Info("{0} has been removed from the session list.", session.GetActor().customDisplayName);

                session.QueuePacket(SessionEndConfirmPacket.BuildPacket(session, endSessionPacket.destinationZoneId));
                client.FlushQueuedSendPackets();
                break;

            //World Server - Party Synch
            case 0x1020:
                PartySyncPacket partySyncPacket = new PartySyncPacket(subpacket.data);
                Server.GetWorldManager().PartyMemberListRecieved(partySyncPacket);
                break;

            //Ping
            case 0x0001:
                //subpacket.DebugPrintSubPacket();
                PingPacket pingPacket = new PingPacket(subpacket.data);
                session.QueuePacket(PongPacket.BuildPacket(session.id, pingPacket.time));
                session.Ping();
                break;

            //Unknown
            case 0x0002:

                subpacket.DebugPrintSubPacket();
                session.QueuePacket(_0x2Packet.BuildPacket(session.id));
                client.FlushQueuedSendPackets();

                break;

            //Chat Received
            case 0x0003:
                ChatMessagePacket chatMessage = new ChatMessagePacket(subpacket.data);
                //Program.Log.Info("Got type-{5} message: {0} @ {1}, {2}, {3}, Rot: {4}", chatMessage.message, chatMessage.posX, chatMessage.posY, chatMessage.posZ, chatMessage.posRot, chatMessage.logType);

                if (chatMessage.message.StartsWith("!"))
                {
                    if (Server.GetCommandProcessor().DoCommand(chatMessage.message, session))
                    {
                        return;
                    }
                    ;
                }

                if (chatMessage.logType == SendMessagePacket.MESSAGE_TYPE_SAY || chatMessage.logType == SendMessagePacket.MESSAGE_TYPE_SHOUT)
                {
                    session.GetActor().BroadcastPacket(SendMessagePacket.BuildPacket(session.id, chatMessage.logType, session.GetActor().customDisplayName, chatMessage.message), false);
                }

                break;

            //Langauge Code (Client safe to send packets to now)
            case 0x0006:
                LangaugeCodePacket langCode = new LangaugeCodePacket(subpacket.data);
                LuaEngine.GetInstance().CallLuaFunction(session.GetActor(), session.GetActor(), "onBeginLogin", true);
                Server.GetWorldManager().DoZoneIn(session.GetActor(), true, 0x1);
                LuaEngine.GetInstance().CallLuaFunction(session.GetActor(), session.GetActor(), "onLogin", true);
                session.languageCode = langCode.languageCode;
                break;

            //Unknown - Happens a lot at login, then once every time player zones
            case 0x0007:
                //subpacket.DebugPrintSubPacket();
                ZoneInCompletePacket zoneInCompletePacket = new ZoneInCompletePacket(subpacket.data);
                break;

            //Update Position
            case 0x00CA:
                //Update Position
                UpdatePlayerPositionPacket posUpdate = new UpdatePlayerPositionPacket(subpacket.data);
                session.UpdatePlayerActorPosition(posUpdate.x, posUpdate.y, posUpdate.z, posUpdate.rot, posUpdate.moveState);
                session.GetActor().SendInstanceUpdate();

                if (session.GetActor().IsInZoneChange())
                {
                    session.GetActor().SetZoneChanging(false);
                }

                break;

            //Set Target
            case 0x00CD:
                //subpacket.DebugPrintSubPacket();

                SetTargetPacket setTarget        = new SetTargetPacket(subpacket.data);
                session.GetActor().currentTarget = setTarget.actorID;
                session.GetActor().BroadcastPacket(SetActorTargetAnimatedPacket.BuildPacket(session.id, setTarget.actorID), true);
                break;

            //Lock Target
            case 0x00CC:
                LockTargetPacket lockTarget            = new LockTargetPacket(subpacket.data);
                session.GetActor().currentLockedTarget = lockTarget.actorID;
                break;

            //Start Event
            case 0x012D:
                subpacket.DebugPrintSubPacket();
                EventStartPacket eventStart = new EventStartPacket(subpacket.data);

                /*
                 * if (eventStart.error != null)
                 * {
                 *  player.errorMessage += eventStart.error;
                 *
                 *  if (eventStart.errorIndex == eventStart.errorNum - 1)
                 *      Program.Log.Error("\n"+player.errorMessage);
                 *
                 *
                 *  break;
                 * }
                 */

                Actor ownerActor = Server.GetStaticActors(eventStart.scriptOwnerActorID);


                session.GetActor().currentEventOwner = eventStart.scriptOwnerActorID;
                session.GetActor().currentEventName  = eventStart.triggerName;


                if (ownerActor == null)
                {
                    //Is it a instance actor?
                    ownerActor = session.GetActor().zone.FindActorInArea(session.GetActor().currentEventOwner);
                    if (ownerActor == null)
                    {
                        //Is it a Director?
                        Director director = session.GetActor().GetDirector(eventStart.scriptOwnerActorID);
                        if (director != null)
                        {
                            ownerActor = director;
                        }
                        else
                        {
                            Program.Log.Debug("\n===Event START===\nCould not find actor 0x{0:X} for event started by caller: 0x{1:X}\nEvent Starter: {2}\nParams: {3}", eventStart.actorID, eventStart.scriptOwnerActorID, eventStart.triggerName, LuaUtils.DumpParams(eventStart.luaParams));
                            break;
                        }
                    }
                }

                session.GetActor().StartEvent(ownerActor, eventStart);

                Program.Log.Debug("\n===Event START===\nSource Actor: 0x{0:X}\nCaller Actor: 0x{1:X}\nVal1: 0x{2:X}\nVal2: 0x{3:X}\nEvent Starter: {4}\nParams: {5}", eventStart.actorID, eventStart.scriptOwnerActorID, eventStart.val1, eventStart.val2, eventStart.triggerName, LuaUtils.DumpParams(eventStart.luaParams));
                break;

            //Unknown, happens at npc spawn and cutscene play????
            case 0x00CE:
                subpacket.DebugPrintSubPacket();
                break;

            //Event Result
            case 0x012E:
                subpacket.DebugPrintSubPacket();
                EventUpdatePacket eventUpdate = new EventUpdatePacket(subpacket.data);
                Program.Log.Debug("\n===Event UPDATE===\nSource Actor: 0x{0:X}\nCaller Actor: 0x{1:X}\nVal1: 0x{2:X}\nVal2: 0x{3:X}\nStep: 0x{4:X}\nParams: {5}", eventUpdate.actorID, eventUpdate.scriptOwnerActorID, eventUpdate.val1, eventUpdate.val2, eventUpdate.step, LuaUtils.DumpParams(eventUpdate.luaParams));

                /*
                 * //Is it a static actor? If not look in the player's instance
                 * Actor updateOwnerActor = Server.GetStaticActors(session.GetActor().currentEventOwner);
                 * if (updateOwnerActor == null)
                 * {
                 *  updateOwnerActor = Server.GetWorldManager().GetActorInWorld(session.GetActor().currentEventOwner);
                 *
                 *  if (session.GetActor().currentDirector != null && session.GetActor().currentEventOwner == session.GetActor().currentDirector.actorId)
                 *      updateOwnerActor = session.GetActor().currentDirector;
                 *
                 *  if (updateOwnerActor == null)
                 *      break;
                 * }
                 */
                session.GetActor().UpdateEvent(eventUpdate);

                //LuaEngine.DoActorOnEventUpdated(session.GetActor(), updateOwnerActor, eventUpdate);

                break;

            case 0x012F:
                subpacket.DebugPrintSubPacket();
                ParameterDataRequestPacket paramRequest = new ParameterDataRequestPacket(subpacket.data);
                if (paramRequest.paramName.Equals("charaWork/exp"))
                {
                    session.GetActor().SendCharaExpInfo();
                }
                break;

            //Group Created Confirm
            case 0x0133:
                GroupCreatedPacket groupCreated = new GroupCreatedPacket(subpacket.data);
                Server.GetWorldManager().SendGroupInit(session, groupCreated.groupId);
                break;

            /* RECRUITMENT */
            //Start Recruiting
            case 0x01C3:
                StartRecruitingRequestPacket recruitRequestPacket = new StartRecruitingRequestPacket(subpacket.data);
                session.QueuePacket(StartRecruitingResponse.BuildPacket(session.id, true));
                break;

            //End Recruiting
            case 0x01C4:
                session.QueuePacket(EndRecruitmentPacket.BuildPacket(session.id));
                break;

            //Party Window Opened, Request State
            case 0x01C5:
                session.QueuePacket(RecruiterStatePacket.BuildPacket(session.id, false, false, 0));
                break;

            //Search Recruiting
            case 0x01C7:
                RecruitmentSearchRequestPacket recruitSearchPacket = new RecruitmentSearchRequestPacket(subpacket.data);
                break;

            //Get Recruitment Details
            case 0x01C8:
                RecruitmentDetailsRequestPacket currentRecruitDetailsPacket = new RecruitmentDetailsRequestPacket(subpacket.data);
                RecruitmentDetails details = new RecruitmentDetails();
                details.recruiterName = "Localhost Character";
                details.purposeId     = 2;
                details.locationId    = 1;
                details.subTaskId     = 1;
                details.comment       = "This is a test details packet sent by the server. No implementation has been Created yet...";
                details.num[0]        = 1;
                session.QueuePacket(CurrentRecruitmentDetailsPacket.BuildPacket(session.id, details));
                break;

            //Accepted Recruiting
            case 0x01C6:
                subpacket.DebugPrintSubPacket();
                break;

            /* SOCIAL STUFF */
            case 0x01C9:
                AddRemoveSocialPacket addBlackList = new AddRemoveSocialPacket(subpacket.data);
                session.QueuePacket(BlacklistAddedPacket.BuildPacket(session.id, true, addBlackList.name));
                break;

            case 0x01CA:
                AddRemoveSocialPacket RemoveBlackList = new AddRemoveSocialPacket(subpacket.data);
                session.QueuePacket(BlacklistRemovedPacket.BuildPacket(session.id, true, RemoveBlackList.name));
                break;

            case 0x01CB:
                int offset1 = 0;
                session.QueuePacket(SendBlacklistPacket.BuildPacket(session.id, new String[] { "Test" }, ref offset1));
                break;

            case 0x01CC:
                AddRemoveSocialPacket addFriendList = new AddRemoveSocialPacket(subpacket.data);
                session.QueuePacket(FriendlistAddedPacket.BuildPacket(session.id, true, (uint)addFriendList.name.GetHashCode(), true, addFriendList.name));
                break;

            case 0x01CD:
                AddRemoveSocialPacket RemoveFriendList = new AddRemoveSocialPacket(subpacket.data);
                session.QueuePacket(FriendlistRemovedPacket.BuildPacket(session.id, true, RemoveFriendList.name));
                break;

            case 0x01CE:
                int offset2 = 0;
                session.QueuePacket(SendFriendlistPacket.BuildPacket(session.id, new Tuple <long, string>[] { new Tuple <long, string>(01, "Test2") }, ref offset2));
                break;

            case 0x01CF:
                session.QueuePacket(FriendStatusPacket.BuildPacket(session.id, null));
                break;

            /* SUPPORT DESK STUFF */
            //Request for FAQ/Info List
            case 0x01D0:
                FaqListRequestPacket faqRequest = new FaqListRequestPacket(subpacket.data);
                session.QueuePacket(FaqListResponsePacket.BuildPacket(session.id, new string[] { "Testing FAQ1", "Coded style!" }));
                break;

            //Request for body of a faq/info selection
            case 0x01D1:
                FaqBodyRequestPacket faqBodyRequest = new FaqBodyRequestPacket(subpacket.data);
                session.QueuePacket(FaqBodyResponsePacket.BuildPacket(session.id, "HERE IS A GIANT BODY. Nothing else to say!"));
                break;

            //Request issue list
            case 0x01D2:
                GMTicketIssuesRequestPacket issuesRequest = new GMTicketIssuesRequestPacket(subpacket.data);
                session.QueuePacket(IssueListResponsePacket.BuildPacket(session.id, new string[] { "Test1", "Test2", "Test3", "Test4", "Test5" }));
                break;

            //Request if GM ticket exists
            case 0x01D3:
                session.QueuePacket(StartGMTicketPacket.BuildPacket(session.id, false));
                break;

            //Request for GM response message
            case 0x01D4:
                session.QueuePacket(GMTicketPacket.BuildPacket(session.id, "This is a GM Ticket Title", "This is a GM Ticket Body."));
                break;

            //GM Ticket Sent
            case 0x01D5:
                GMSupportTicketPacket gmTicket = new GMSupportTicketPacket(subpacket.data);
                Program.Log.Info("Got GM Ticket: \n" + gmTicket.ticketTitle + "\n" + gmTicket.ticketBody);
                session.QueuePacket(GMTicketSentResponsePacket.BuildPacket(session.id, true));
                break;

            //Request to end ticket
            case 0x01D6:
                session.QueuePacket(EndGMTicketPacket.BuildPacket(session.id));
                break;

            default:
                Program.Log.Debug("Unknown command 0x{0:X} received.", subpacket.gameMessage.opcode);
                subpacket.DebugPrintSubPacket();
                break;
            }
        }
コード例 #22
0
 private Object readPong(short packetType, NetworkStream buffer)
 {
     return(PongPacket.ReadBuffer(packetType, buffer));
 }
コード例 #23
0
        public void processPacket(ClientConnection client, BasePacket packet)
        {
            if (packet.header.isCompressed == 0x01)
            {
                BasePacket.decryptPacket(client.blowfish, ref packet);
            }

            List <SubPacket> subPackets = packet.getSubpackets();

            foreach (SubPacket subpacket in subPackets)
            {
                if (subpacket.header.type == 0x01)
                {
                    packet.debugPrintPacket();
                    byte[] reply1Data =
                    {
                        0x01, 0x00, 0x00, 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                        0x18, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFD, 0xFF, 0xFF,
                        0xE5, 0x6E, 0x01, 0xE0, 0x00, 0x00, 0x00, 0x0
                    };

                    byte[] reply2Data =
                    {
                        0x01, 0x00, 0x00, 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                        0x38, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x2B, 0x5F, 0x26,
                        0x66, 0x00, 0x00, 0x00, 0xC8, 0xD6, 0xAF, 0x2B, 0x38, 0x2B, 0x5F, 0x26, 0xB8, 0x8D, 0xF0, 0x2B,
                        0xC8, 0xFD, 0x85, 0xFE, 0xA8, 0x7C, 0x5B, 0x09, 0x38, 0x2B, 0x5F, 0x26, 0xC8, 0xD6, 0xAF, 0x2B,
                        0xB8, 0x8D, 0xF0, 0x2B, 0x88, 0xAF, 0x5E, 0x26
                    };

                    BasePacket reply1 = new BasePacket(reply1Data);
                    BasePacket reply2 = new BasePacket(reply2Data);

                    //Write Timestamp into Reply1
                    using (MemoryStream mem = new MemoryStream(reply1.data))
                    {
                        using (BinaryWriter binReader = new BinaryWriter(mem))
                        {
                            binReader.BaseStream.Seek(0x14, SeekOrigin.Begin);
                            binReader.Write((UInt32)Utils.UnixTimeStampUTC());
                        }
                    }

                    //Read in Actor Id that owns this connection
                    uint actorID = 0;
                    using (MemoryStream mem = new MemoryStream(packet.data))
                    {
                        using (BinaryReader binReader = new BinaryReader(mem))
                        {
                            try
                            {
                                byte[] readIn = new byte[12];
                                binReader.BaseStream.Seek(0x14, SeekOrigin.Begin);
                                binReader.Read(readIn, 0, 12);
                                actorID = UInt32.Parse(Encoding.ASCII.GetString(readIn));
                            }
                            catch (Exception)
                            { }
                        }
                    }

                    //Should never happen.... unless actor id IS 0!
                    if (actorID == 0)
                    {
                        break;
                    }

                    client.owner = actorID;

                    //Write Actor ID into reply2
                    using (MemoryStream mem = new MemoryStream(reply2.data))
                    {
                        using (BinaryWriter binReader = new BinaryWriter(mem))
                        {
                            binReader.BaseStream.Seek(0x10, SeekOrigin.Begin);
                            binReader.Write(actorID);
                        }
                    }

                    ConnectedPlayer player = null;

                    if (packet.header.connectionType == BasePacket.TYPE_ZONE)
                    {
                        while (!mPlayers.ContainsKey(client.owner))
                        {
                        }
                        player = mPlayers[client.owner];
                    }

                    //Create connected player if not created
                    if (player == null)
                    {
                        player            = new ConnectedPlayer(actorID);
                        mPlayers[actorID] = player;
                    }

                    player.setConnection(packet.header.connectionType, client);

                    if (packet.header.connectionType == BasePacket.TYPE_ZONE)
                    {
                        Log.debug(String.Format("Got {0} connection for ActorID {1} @ {2}.", "zone", actorID, client.getAddress()));
                    }
                    else if (packet.header.connectionType == BasePacket.TYPE_CHAT)
                    {
                        Log.debug(String.Format("Got {0} connection for ActorID {1} @ {2}.", "chat", actorID, client.getAddress()));
                    }

                    //Create player actor
                    reply1.debugPrintPacket();
                    client.queuePacket(reply1);
                    client.queuePacket(reply2);
                    break;
                }
                else if (subpacket.header.type == 0x07)
                {
                    BasePacket init = Login0x7ResponsePacket.buildPacket(BitConverter.ToUInt32(packet.data, 0x10), Utils.UnixTimeStampUTC());
                    //client.queuePacket(init);
                }
                else if (subpacket.header.type == 0x08)
                {
                    //Response, client's current [actorID][time]
                    packet.debugPrintPacket();
                }
                else if (subpacket.header.type == 0x03)
                {
                    ConnectedPlayer player = null;

                    if (mPlayers.ContainsKey(client.owner))
                    {
                        player = mPlayers[client.owner];
                    }

                    if (player == null)
                    {
                        return;
                    }

                    //Normal Game Opcode
                    switch (subpacket.gameMessage.opcode)
                    {
                    //Ping
                    case 0x0001:
                        //subpacket.debugPrintSubPacket();
                        PingPacket pingPacket = new PingPacket(subpacket.data);
                        client.queuePacket(BasePacket.createPacket(PongPacket.buildPacket(player.actorID, pingPacket.time), true, false));
                        player.ping();
                        break;

                    //Unknown
                    case 0x0002:

                        subpacket.debugPrintSubPacket();
                        client.queuePacket(_0x2Packet.buildPacket(player.actorID), true, false);

                        Server.GetWorldManager().DoLogin(player.getActor());


                        break;

                    //Chat Received
                    case 0x0003:
                        ChatMessagePacket chatMessage = new ChatMessagePacket(subpacket.data);
                        Log.info(String.Format("Got type-{5} message: {0} @ {1}, {2}, {3}, Rot: {4}", chatMessage.message, chatMessage.posX, chatMessage.posY, chatMessage.posZ, chatMessage.posRot, chatMessage.logType));
                        subpacket.debugPrintSubPacket();

                        if (chatMessage.message.StartsWith("!"))
                        {
                            if (cp.doCommand(chatMessage.message, player))
                            {
                                continue;
                            }
                        }

                        player.getActor().broadcastPacket(SendMessagePacket.buildPacket(player.actorID, player.actorID, chatMessage.logType, player.getActor().customDisplayName, chatMessage.message), false);

                        break;

                    //Langauge Code
                    case 0x0006:
                        LangaugeCodePacket langCode = new LangaugeCodePacket(subpacket.data);
                        player.languageCode = langCode.languageCode;
                        break;

                    //Unknown - Happens a lot at login, then once every time player zones
                    case 0x0007:
                        //subpacket.debugPrintSubPacket();
                        _0x07Packet unknown07 = new _0x07Packet(subpacket.data);
                        break;

                    //Update Position
                    case 0x00CA:
                        //Update Position
                        //subpacket.debugPrintSubPacket();
                        UpdatePlayerPositionPacket posUpdate = new UpdatePlayerPositionPacket(subpacket.data);
                        player.updatePlayerActorPosition(posUpdate.x, posUpdate.y, posUpdate.z, posUpdate.rot, posUpdate.moveState);
                        player.getActor().sendInstanceUpdate();

                        if (player.getActor().isInZoneChange())
                        {
                            player.getActor().setZoneChanging(false);
                        }

                        break;

                    //Set Target
                    case 0x00CD:
                        //subpacket.debugPrintSubPacket();

                        SetTargetPacket setTarget       = new SetTargetPacket(subpacket.data);
                        player.getActor().currentTarget = setTarget.actorID;
                        player.getActor().broadcastPacket(SetActorTargetAnimatedPacket.buildPacket(player.actorID, player.actorID, setTarget.actorID), true);
                        break;

                    //Lock Target
                    case 0x00CC:
                        LockTargetPacket lockTarget           = new LockTargetPacket(subpacket.data);
                        player.getActor().currentLockedTarget = lockTarget.actorID;
                        break;

                    //Start Event
                    case 0x012D:
                        subpacket.debugPrintSubPacket();
                        EventStartPacket eventStart = new EventStartPacket(subpacket.data);

                        /*
                         * if (eventStart.error != null)
                         * {
                         *  player.errorMessage += eventStart.error;
                         *
                         *  if (eventStart.errorIndex == eventStart.errorNum - 1)
                         *      Log.error("\n"+player.errorMessage);
                         *
                         *
                         *  break;
                         * }
                         */

                        Actor ownerActor = Server.getStaticActors(eventStart.scriptOwnerActorID);
                        if (ownerActor != null && ownerActor is Command)
                        {
                            player.getActor().currentCommand     = eventStart.scriptOwnerActorID;
                            player.getActor().currentCommandName = eventStart.triggerName;
                        }
                        else
                        {
                            player.getActor().currentEventOwner = eventStart.scriptOwnerActorID;
                            player.getActor().currentEventName  = eventStart.triggerName;
                        }

                        if (ownerActor == null)
                        {
                            //Is it a instance actor?
                            ownerActor = Server.GetWorldManager().GetActorInWorld(player.getActor().currentEventOwner);
                            if (ownerActor == null)
                            {
                                //Is it a Director?
                                if (player.getActor().currentDirector != null && player.getActor().currentEventOwner == player.getActor().currentDirector.actorId)
                                {
                                    ownerActor = player.getActor().currentDirector;
                                }
                                else
                                {
                                    Log.debug(String.Format("\n===Event START===\nCould not find actor 0x{0:X} for event started by caller: 0x{1:X}\nEvent Starter: {2}\nParams: {3}", eventStart.actorID, eventStart.scriptOwnerActorID, eventStart.triggerName, LuaUtils.dumpParams(eventStart.luaParams)));
                                    break;
                                }
                            }
                        }

                        LuaEngine.doActorOnEventStarted(player.getActor(), ownerActor, eventStart);

                        Log.debug(String.Format("\n===Event START===\nSource Actor: 0x{0:X}\nCaller Actor: 0x{1:X}\nVal1: 0x{2:X}\nVal2: 0x{3:X}\nEvent Starter: {4}\nParams: {5}", eventStart.actorID, eventStart.scriptOwnerActorID, eventStart.val1, eventStart.val2, eventStart.triggerName, LuaUtils.dumpParams(eventStart.luaParams)));
                        break;

                    //Unknown, happens at npc spawn and cutscene play????
                    case 0x00CE:
                        break;

                    //Event Result
                    case 0x012E:
                        subpacket.debugPrintSubPacket();
                        EventUpdatePacket eventUpdate = new EventUpdatePacket(subpacket.data);
                        Log.debug(String.Format("\n===Event UPDATE===\nSource Actor: 0x{0:X}\nCaller Actor: 0x{1:X}\nVal1: 0x{2:X}\nVal2: 0x{3:X}\nStep: 0x{4:X}\nParams: {5}", eventUpdate.actorID, eventUpdate.scriptOwnerActorID, eventUpdate.val1, eventUpdate.val2, eventUpdate.step, LuaUtils.dumpParams(eventUpdate.luaParams)));

                        //Is it a static actor? If not look in the player's instance
                        Actor updateOwnerActor = Server.getStaticActors(player.getActor().currentEventOwner);
                        if (updateOwnerActor == null)
                        {
                            updateOwnerActor = Server.GetWorldManager().GetActorInWorld(player.getActor().currentEventOwner);

                            if (player.getActor().currentDirector != null && player.getActor().currentEventOwner == player.getActor().currentDirector.actorId)
                            {
                                updateOwnerActor = player.getActor().currentDirector;
                            }

                            if (updateOwnerActor == null)
                            {
                                break;
                            }
                        }

                        LuaEngine.doActorOnEventUpdated(player.getActor(), updateOwnerActor, eventUpdate);

                        break;

                    case 0x012F:
                        subpacket.debugPrintSubPacket();
                        ParameterDataRequestPacket paramRequest = new ParameterDataRequestPacket(subpacket.data);
                        if (paramRequest.paramName.Equals("charaWork/exp"))
                        {
                            player.getActor().sendCharaExpInfo();
                        }
                        break;

                    /* RECRUITMENT */
                    //Start Recruiting
                    case 0x01C3:
                        StartRecruitingRequestPacket recruitRequestPacket = new StartRecruitingRequestPacket(subpacket.data);
                        client.queuePacket(BasePacket.createPacket(StartRecruitingResponse.buildPacket(player.actorID, true), true, false));
                        break;

                    //End Recruiting
                    case 0x01C4:
                        client.queuePacket(BasePacket.createPacket(EndRecruitmentPacket.buildPacket(player.actorID), true, false));
                        break;

                    //Party Window Opened, Request State
                    case 0x01C5:
                        client.queuePacket(BasePacket.createPacket(RecruiterStatePacket.buildPacket(player.actorID, true, true, 1), true, false));
                        break;

                    //Search Recruiting
                    case 0x01C7:
                        RecruitmentSearchRequestPacket recruitSearchPacket = new RecruitmentSearchRequestPacket(subpacket.data);
                        break;

                    //Get Recruitment Details
                    case 0x01C8:
                        RecruitmentDetailsRequestPacket currentRecruitDetailsPacket = new RecruitmentDetailsRequestPacket(subpacket.data);
                        RecruitmentDetails details = new RecruitmentDetails();
                        details.recruiterName = "Localhost Character";
                        details.purposeId     = 2;
                        details.locationId    = 1;
                        details.subTaskId     = 1;
                        details.comment       = "This is a test details packet sent by the server. No implementation has been created yet...";
                        details.num[0]        = 1;
                        client.queuePacket(BasePacket.createPacket(CurrentRecruitmentDetailsPacket.buildPacket(player.actorID, details), true, false));
                        break;

                    //Accepted Recruiting
                    case 0x01C6:
                        subpacket.debugPrintSubPacket();
                        break;

                    /* SOCIAL STUFF */
                    case 0x01C9:
                        AddRemoveSocialPacket addBlackList = new AddRemoveSocialPacket(subpacket.data);
                        client.queuePacket(BasePacket.createPacket(BlacklistAddedPacket.buildPacket(player.actorID, true, addBlackList.name), true, false));
                        break;

                    case 0x01CA:
                        AddRemoveSocialPacket removeBlackList = new AddRemoveSocialPacket(subpacket.data);
                        client.queuePacket(BasePacket.createPacket(BlacklistRemovedPacket.buildPacket(player.actorID, true, removeBlackList.name), true, false));
                        break;

                    case 0x01CB:
                        int offset1 = 0;
                        client.queuePacket(BasePacket.createPacket(SendBlacklistPacket.buildPacket(player.actorID, new String[] { "Test" }, ref offset1), true, false));
                        break;

                    case 0x01CC:
                        AddRemoveSocialPacket addFriendList = new AddRemoveSocialPacket(subpacket.data);
                        client.queuePacket(BasePacket.createPacket(FriendlistAddedPacket.buildPacket(player.actorID, true, (uint)addFriendList.name.GetHashCode(), true, addFriendList.name), true, false));
                        break;

                    case 0x01CD:
                        AddRemoveSocialPacket removeFriendList = new AddRemoveSocialPacket(subpacket.data);
                        client.queuePacket(BasePacket.createPacket(FriendlistRemovedPacket.buildPacket(player.actorID, true, removeFriendList.name), true, false));
                        break;

                    case 0x01CE:
                        int offset2 = 0;
                        client.queuePacket(BasePacket.createPacket(SendFriendlistPacket.buildPacket(player.actorID, new Tuple <long, string>[] { new Tuple <long, string>(01, "Test2") }, ref offset2), true, false));
                        break;

                    case 0x01CF:
                        client.queuePacket(BasePacket.createPacket(FriendStatusPacket.buildPacket(player.actorID, null), true, false));
                        break;

                    /* SUPPORT DESK STUFF */
                    //Request for FAQ/Info List
                    case 0x01D0:
                        FaqListRequestPacket faqRequest = new FaqListRequestPacket(subpacket.data);
                        client.queuePacket(BasePacket.createPacket(FaqListResponsePacket.buildPacket(player.actorID, new string[] { "Testing FAQ1", "Coded style!" }), true, false));
                        break;

                    //Request for body of a faq/info selection
                    case 0x01D1:
                        FaqBodyRequestPacket faqBodyRequest = new FaqBodyRequestPacket(subpacket.data);
                        client.queuePacket(BasePacket.createPacket(FaqBodyResponsePacket.buildPacket(player.actorID, "HERE IS A GIANT BODY. Nothing else to say!"), true, false));
                        break;

                    //Request issue list
                    case 0x01D2:
                        GMTicketIssuesRequestPacket issuesRequest = new GMTicketIssuesRequestPacket(subpacket.data);
                        client.queuePacket(BasePacket.createPacket(IssueListResponsePacket.buildPacket(player.actorID, new string[] { "Test1", "Test2", "Test3", "Test4", "Test5" }), true, false));
                        break;

                    //Request if GM ticket exists
                    case 0x01D3:
                        client.queuePacket(BasePacket.createPacket(StartGMTicketPacket.buildPacket(player.actorID, false), true, false));
                        break;

                    //Request for GM response message
                    case 0x01D4:
                        client.queuePacket(BasePacket.createPacket(GMTicketPacket.buildPacket(player.actorID, "This is a GM Ticket Title", "This is a GM Ticket Body."), true, false));
                        break;

                    //GM Ticket Sent
                    case 0x01D5:
                        GMSupportTicketPacket gmTicket = new GMSupportTicketPacket(subpacket.data);
                        Log.info("Got GM Ticket: \n" + gmTicket.ticketTitle + "\n" + gmTicket.ticketBody);
                        client.queuePacket(BasePacket.createPacket(GMTicketSentResponsePacket.buildPacket(player.actorID, true), true, false));
                        break;

                    //Request to end ticket
                    case 0x01D6:
                        client.queuePacket(BasePacket.createPacket(EndGMTicketPacket.buildPacket(player.actorID), true, false));
                        break;

                    default:
                        Log.debug(String.Format("Unknown command 0x{0:X} received.", subpacket.gameMessage.opcode));
                        subpacket.debugPrintSubPacket();
                        break;
                    }
                }
                else
                {
                    packet.debugPrintPacket();
                }
            }
        }
コード例 #24
0
ファイル: Connection.cs プロジェクト: HampsterEater/Dynammo
        /// <summary>
        ///     Processes a packet if its an internal packet.
        /// </summary>
        /// <param name="packet">Packet to process.</param>
        /// <returns>True if the packet was processes, otherwise false.</returns>
        private bool ProcessInternalPacket(Packet packet)
        {
            // Responds to a ping request from a client.
            if (packet is PingPacket)
            {
                PongPacket pong = new PongPacket();
                SendPacket(pong, packet);

                return true;
            }

            // Registers the response from a ping packet we have sent.
            else if (packet is PongPacket)
            {
                m_ping              = Environment.TickCount - m_timeSinceLastPing;
                m_timeSinceLastPong = Environment.TickCount;
                m_waitingForPong    = false;

                return true;
            }

            // Provides connections details regarding their connection.
            else if (packet is ConnectPacket)
            {
                if (m_listenConnection == null)
                {
                    throw new InvalidOperationException("Remote host sent a connect packet to a non-listening connection.");
                }

                ConnectPacket p = (ConnectPacket)packet;

                m_hardwareFingerprint = p.HardwareFingerprint;
                m_guid                = p.ConnectionGUID;
                m_computerUserName    = p.ComputerUserName;
                m_computerName        = p.ComputerName;

                Logger.Info("Connection from {0} established connection.", LoggerVerboseLevel.High, m_endPoint.Serialize().ToString());
                Logger.Info("\tHardware Fingerprint: {0}", LoggerVerboseLevel.High, StringHelper.ByteArrayToHexString(m_hardwareFingerprint));
                Logger.Info("\tGUID: {0}", LoggerVerboseLevel.High, StringHelper.ByteArrayToHexString(m_guid));
                Logger.Info("\tComputer Name: {0}", LoggerVerboseLevel.High, m_computerName);
                Logger.Info("\tComputer User Name: {0}", LoggerVerboseLevel.High, m_computerUserName);

                // Send an AOK message :3.
                ConnectReplyPacket reply = new ConnectReplyPacket();
                SendPacket(reply, packet);

                lock (m_socket_lock)
                {
                    m_connectionEstablished = true;
                    lock (m_listenConnection.m_peers_lock)
                    {
                        m_listenConnection.m_connected_peers.Add(this);
                    }
                    m_encryptor = new StreamEncryptor(GenerateEncryptionKey());
                }

                return true;
            }

            // Finishes establishing a connection.
            else if (packet is ConnectReplyPacket)
            {
                // Generate new encryption keys.
                lock (m_socket_lock)
                {
                    m_encryptor = new StreamEncryptor(GenerateEncryptionKey());
                }

                m_connectionEstablished = true;
            }

            // Disconnects the user from the server gracefully.
            else if (packet is DisconnectPacket)
            {
                DisconnectAsync(true).Wait();
                return true;
            }

            return false;
        }
コード例 #25
0
ファイル: Connection.cs プロジェクト: legend-plus/LegendPlus
    public void getPackets()
    {
        //GD.Print("Get Packets");
        //GD.Print(wrapped_client.GetAvailablePacketCount());
        if (connected && client.GetAvailableBytes() > 0)
        {
            //byte[] packet_data = wrapped_client.GetPacket();
            //UInt32 packetLength = BitConverter.ToUInt32(packet_data, 0);
            //short packetId = BitConverter.ToInt16(packet_data, 4);
            UInt32 packetLength = (UInt32)client.GetU32();
            short  packetId     = (short)client.Get16();
            var    packetData   = client.GetData((int)packetLength - 2);
            //var data = new List<byte>(packet_data).GetRange(6, packet_data.Length -6).ToArray();
            //GD.Print(BitConverter.ToString( (byte[]) packetData[1]));
            var data   = (byte[])packetData[1];
            var packet = Packets.Packets.decode(packetId, data);

            if (GetParent().GetNodeOrNull("GUI") != null)
            {
                var gui = (Control)GetParent().GetNodeOrNull("GUI");
                gui.Call("recordPacket", packetLength + 4);
            }

            GD.Print(String.Format("Received packet {0}, ID: {1} Length: {2}", packet.name, packetId, packetLength));

            if (packet is ReadyPacket)
            {
                ReadyPacket parsed_packet = (ReadyPacket)packet;
                if (parsed_packet.code == 0)
                {
                    string token       = (string)GetParent().GetNode("Discord Integration").Call("getToken");
                    var    loginPacket = new LoginPacket(token);
                    GD.Print("Sending login");
                    sendPacket(loginPacket);
                }
                else if (parsed_packet.code == 1)
                {
                    var requestWorldPacket = new RequestWorldPacket();
                    sendPacket(requestWorldPacket);
                    if (!joined)
                    {
                        var loadingRes = GD.Load <PackedScene>("res://scenes/world.tscn");
                        var node       = loadingRes.Instance();
                        node.SetName("WorldScene");
                        var loadingGuiRes = GD.Load <PackedScene>("res://scenes/gui.tscn");
                        var gui           = (Control)loadingGuiRes.Instance();
                        gui.SetName("GUI");
                        GetParent().Call("setState", 2);
                        GetParent().AddChild(node);
                        //GetParent().AddChild(gui);
                        GetParent().AddChild(gui);
                        //node.AddChild(gui);
                        GetParent().GetNode("GameLoader").Free();
                        //var playerSpriteScene = (PackedScene) node.Call("getSprite", "rowan");
                        //var playerSprite = (AnimatedSprite) playerSpriteScene.Instance();
                        //playerSprite.SetName("PlayerSprite");
                        //node.GetNode("World/Player").AddChild(playerSprite);
                        //playerSprite.Position = ((KinematicBody2D) node.GetNode("Player")).Position;
                        //playerSprite.Visible = true;
                        //GD.Print(playerSprite);
                        joined = true;
                    }
                }
            }
            else if (packet is PongPacket)
            {
                PongPacket parsed_packet = (PongPacket)packet;
                GD.Print("Got pong of " + parsed_packet.message);
            }
            else if (packet is LoginResultPacket)
            {
                LoginResultPacket parsed_packet = (LoginResultPacket)packet;
                GD.Print("Login Result: " + parsed_packet.responseCode.ToString() + " Name: " + parsed_packet.userId);
                var joinGamePacket = new JoinGamePacket();
                sendPacket(joinGamePacket);
            }
            else if (packet is WorldPacket)
            {
                WorldPacket parsed_packet = (WorldPacket)packet;
                //GD.Print(parsed_packet.debug);
                GetParent().GetNode("WorldScene").Call("loadWorld", new object[] { parsed_packet.worldData, parsed_packet.bumpData, parsed_packet.height, parsed_packet.width });
            }
            else if (packet is PlayerPositionPacket)
            {
                PlayerPositionPacket parsed_packet = (PlayerPositionPacket)packet;
                GetParent().GetNode("WorldScene/World/Player").Call("move", new object[] { parsed_packet.x, parsed_packet.y });
            }
            else if (packet is ChatPacket)
            {
                ChatPacket parsed_packet = (ChatPacket)packet;
                GetNode("../GUI/Chat").Call("AddMessage", parsed_packet.author + ": " + parsed_packet.msg);
            }
            else if (packet is EntityPacket)
            {
                EntityPacket parsed_packet = (EntityPacket)packet;
                GD.Print("Got entity '", parsed_packet.sprite, "' at ", parsed_packet.x, ",", parsed_packet.y, " ID: ", parsed_packet.uuid);
                GetNode("../WorldScene").Call("addEntity", parsed_packet.x, parsed_packet.y, parsed_packet.type, parsed_packet.facing, parsed_packet.interactable, parsed_packet.sprite, parsed_packet.uuid, parsed_packet.type != 2);
            }
            else if (packet is EntityMovePacket)
            {
                EntityMovePacket parsed_packet = (EntityMovePacket)packet;
                GD.Print("Got entity moving to ", parsed_packet.x, ",", parsed_packet.y, " ID: ", parsed_packet.uuid);
                GetNode("../WorldScene").Call("moveEntity", parsed_packet.uuid, parsed_packet.x, parsed_packet.y, parsed_packet.facing);
            }
            else if (packet is InvalidateCachePacket)
            {
                InvalidateCachePacket parsed_packet = (InvalidateCachePacket)packet;
                GD.Print(parsed_packet.uuid, " Invalidated.");
                GetNode("../WorldScene").Call("hideEntity", parsed_packet.uuid);
            }
            else if (packet is DialoguePacket)
            {
                DialoguePacket parsed_packet = (DialoguePacket)packet;
                GD.Print("Got dialogue \"", parsed_packet.text, "\"");
                Window window = (Window)GetNode("../GUI/Window");
                window.OpenDialoguePanel();
                DialoguePanel dialoguePanel = window.OpenDialoguePanel(); //(DialoguePanel) GetNode("../GUI/Window/DialoguePanel");
                dialoguePanel.SetDialogue(parsed_packet.text, parsed_packet.author, parsed_packet.sprite, parsed_packet.substitutions, parsed_packet.optionViews);
            }
            else if (packet is CloseDialoguePacket)
            {
                CloseDialoguePacket parsed_packet = (CloseDialoguePacket)packet;
                DialoguePanel       dialoguePanel = (DialoguePanel)GetNode("../GUI/Window/DialoguePanel");
                dialoguePanel.CloseDialogue(parsed_packet.guid);
                //dialoguePanel.SetDialogue(parsed_packet.text, parsed_packet.author, parsed_packet.sprite, parsed_packet.substitutions, parsed_packet.optionViews);
            }
            else if (packet is PlayerDataPacket)
            {
                PlayerDataPacket parsed_packet = (PlayerDataPacket)packet;
                var player = (Player)GetNode("../WorldScene/World/Player");
                player.SetUuid(parsed_packet.guid);
                if (player.GetNodeOrNull("PlayerSprite") != null)
                {
                    player.GetNodeOrNull("PlayerSprite").Free();
                }
                var playerSpriteScene = (PackedScene)GetNode("../WorldScene").Call("getSprite", parsed_packet.sprite);
                var playerSprite      = (AnimatedSprite)playerSpriteScene.Instance();
                playerSprite.SetName("PlayerSprite");
                player.AddChild(playerSprite);
            }
            else if (packet is InventoryPacket)
            {
                InventoryPacket parsed_packet = (InventoryPacket)packet;
                var             player        = (Player)GetNode("../WorldScene/World/Player");
                if (player.guid == parsed_packet.inventory.guid)
                {
                    player.inventory = parsed_packet.inventory;
                    foreach (Item item in player.inventory.items)
                    {
                        GD.Print("Item: ", item.GetName(), " \"", item.GetDescription(), "\"");
                    }
                }
            }
            else if (packet is AddItemPacket)
            {
                AddItemPacket parsed_packet = (AddItemPacket)packet;
                var           player        = (Player)GetNode("../WorldScene/World/Player");
                if (player.guid == parsed_packet.guid)
                {
                    //TODO: Make use of indices.
                    player.inventory.AddItem(parsed_packet.item, true);
                }
            }
            else if (packet is ModifyItemPacket)
            {
                ModifyItemPacket parsed_packet = (ModifyItemPacket)packet;
                var player = (Player)GetNode("../WorldScene/World/Player");
                if (player.guid == parsed_packet.guid)
                {
                    //TODO: Make use of indices.
                    player.inventory.UpdateItem(parsed_packet.item, parsed_packet.index);
                }
            }
        }
        else
        {
            var testPacket = new Packets.PingPacket("Hello There!");
            //sendPacket(testPacket);
        }
    }