Esempio n. 1
0
        private void OnReceive(IAsyncResult asyncResult)
        {
            try
            {
                Socket s = (Socket)asyncResult.AsyncState;

                int byteCount = s.EndReceive(asyncResult);

                if (byteCount > 0)
                {
                    m_NextCheckActivity = Core.TickCount + 90000;

                    byte[] buffer;

                    lock (m_AsyncLock)
                        buffer = m_RecvBuffer;

                    if (PacketEncryptor != null)
                    {
                        PacketEncryptor.DecryptIncomingPacket(this, ref buffer, ref byteCount);
                    }

                    if (PacketEncoder != null)
                    {
                        PacketEncoder.DecodeIncomingPacket(this, ref buffer, ref byteCount);
                    }

                    lock (m_Buffer)
                        m_Buffer.Enqueue(buffer, 0, byteCount);

                    m_MessagePump.OnReceive(this);

                    lock (m_AsyncLock)
                    {
                        m_AsyncState &= ~AsyncState.Pending;

                        if ((m_AsyncState & AsyncState.Paused) == 0)
                        {
                            try
                            {
                                InternalBeginReceive();
                            }
                            catch (Exception ex)
                            {
                                TraceException(ex);
                                Dispose(false);
                            }
                        }
                    }
                }
                else
                {
                    Dispose(false);
                }
            }
            catch
            {
                Dispose(false);
            }
        }
Esempio n. 2
0
        public void Send(byte[] buffer, int length)
        {
            if (Socket == null)
            {
                return;
            }

            if (PacketEncoder != null)
            {
                PacketEncoder.EncodeOutgoingPacket(this, ref buffer, ref length);
            }

            var shouldBegin = false;

            lock (m_SendQueue)
                shouldBegin = (m_SendQueue.Enqueue(buffer, length));

            if (shouldBegin)
            {
                var sendLength = 0;
                var sendBuffer = m_SendQueue.Peek(ref sendLength);

                try
                {
                    Socket.BeginSend(sendBuffer, 0, sendLength, SocketFlags.None, OnSend, null);
                    m_Sending = true;
                }
                catch (Exception ex)
                {
                    TraceException(ex);
                    Dispose(false);
                }
            }
        }
Esempio n. 3
0
        private void InternalSend(Packet packet)
        {
            if (Running == false)
            {
                // 表示已处理发送
                packet.Release();
                return;
            }

            // 连接的通知事件
            EventHandler <NetStateSendPacketEventArgs> tempEvent = m_EventSendPacket;

            if (tempEvent != null)
            {
                NetStateSendPacketEventArgs sendEventArgs = new NetStateSendPacketEventArgs(this, packet);
                tempEvent(this, sendEventArgs);

                if (sendEventArgs.IsCancelSend == true)
                {
                    // 表示已处理发送
                    packet.Release();
                    return;
                }
            }

            long iLength = 0;

            PacketProfile packetProfile = PacketProfile.GetOutgoingProfile((byte)packet.PacketID);
            DateTime      dateTimeStart = (packetProfile == null ? DateTime.MinValue : OneServer.NowTime);

            {
                PacketBuffer packetBuffer = packet.AcquireBuffer();
                if (packetBuffer.IsNULL == true)
                {
                    throw new Exception("NetState.InternalSend(...) - packetBuffer.IsNULL == true error!");
                }

                byte[] byteBuffer = packetBuffer.Buffer;
                long   lLength    = packetBuffer.Length;

                // 加密数据
                if (PacketEncoder != null)
                {
                    PacketEncoder.EncodeOutgoingPacket(this, ref byteBuffer, ref lLength);
                }

                m_SendQueue.Enqueue(byteBuffer, 0, lLength);

                // 表示已处理发送
                packet.Release();

                // 实际压缩后的数据长度
                iLength = lLength;
            }
            if (packetProfile != null)
            {
                packetProfile.Record(iLength, OneServer.NowTime - dateTimeStart);
            }
        }
Esempio n. 4
0
        public ushort wingsID = 0x0000; // ride wings model ID

        public override byte[] use(Hero p)
        {
            var pktsAfterUse = new byte[0];

            isActive = !isActive;

            PacketEncoder.concatPacket(
                PacketEncoder.activeBagItem(this.itemUID, isActive)
                , ref pktsAfterUse, false);
            // TODO: should split to two pkts? one for self, one for broadcast?

            return(pktsAfterUse);
        }
Esempio n. 5
0
 public static void spawnNearbys(Client client, IEntity baseEntity, int distance = 16, bool includeSelf = true)
 {
     Lib.searchForNearby(baseEntity, distance, includeSelf)?.ForEach(nearby =>
     {
         if (nearby is Hero)
         {
             client.send(
                 PacketEncoder.spawnHero(nearby as Hero, false)
                 );
         }
         else if (nearby is NPC)
         {
             client.send(
                 PacketEncoder.spawnNPC(nearby as NPC)
                 );
         }
     });
 }
Esempio n. 6
0
        public void Test1()
        {
            var data = new byte[] {
                0x30,                                                                                                             // Packet type
                0x23,                                                                                                             // Packet length = 35
                0x00, 0x0e,                                                                                                       // Topic length =14
                0x24, 0x53, 0x59, 0x53, 0x2f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x65,                               // Topic
                0x32, 0x30, 0x32, 0x30, 0x2f, 0x30, 0x36, 0x2f, 0x31, 0x31, 0x20, 0x31, 0x33, 0x3a, 0x31, 0x38, 0x3a, 0x32, 0x34, //Payload
                0x6e,                                                                                                             // 'n'
                0x04,                                                                                                             // 4 bytes => uint
                0x00, 0x00, 0x00, 0x00                                                                                            // uint
            };

            var packet = PacketEncoder.DecodePublish(data);

            Assert.AreEqual("$SYS/localtime", packet.Topic, "Topic");
            Assert.AreEqual(19, packet.Payload.Length, "Payload.Length");
            Assert.AreEqual("2020/06/11 13:18:24", packet.ReadString(), "ReadString");
        }
Esempio n. 7
0
        private void OnReceive(IAsyncResult asyncResult)
        {
            lock (this)
            {
                if (Socket == null)
                {
                    return;
                }

                try
                {
                    var byteCount = Socket.EndReceive(asyncResult);

                    if (byteCount > 0)
                    {
                        m_NextCheckActivity = DateTime.UtcNow + TimeSpan.FromMinutes(1.2);

                        var buffer = m_RecvBuffer;

                        if (PacketEncoder != null)
                        {
                            PacketEncoder.DecodeIncomingPacket(this, ref buffer, ref byteCount);
                        }

                        Buffer.Enqueue(buffer, 0, byteCount);

                        Incoming += byteCount;

                        m_NetServer.OnReceive(this, byteCount);
                    }
                    else
                    {
                        Dispose(false);
                    }
                }
                catch (Exception ex)
                {
                    TraceException(ex);
                    Dispose(false);
                }
            }
        }
Esempio n. 8
0
        public IFuture Send(object obj)
        {
            IPacket packet;

            try
            {
                packet = PacketEncoder.Encode(this, obj);
            }
            catch (Exception ex)
            {
                SessionCaughtException(ex);

                AsyncFuture future = new AsyncFuture(this);
                future.AssociatedObject = obj;

                return(future);
            }

            return(Send(obj, packet));
        }
Esempio n. 9
0
        public override byte[] use(Hero p)
        {
            p.rideList ??= new List <Ride>();

            //foreach (var ride in p.rideList)
            //{
            //    if (ride.descItemID == this.itemID)
            //    {
            //        // duplicated ride item
            //        var pkt = new byte[0];
            //        PacketEncoder.concatPacket(Lib.hexToBytes(
            //            ""
            //        ), ref pkt);
            //        return pkt;
            //    }
            //}

            p.rideList.Add(new Ride(this.baseID, this.itemID));

            return(PacketEncoder.rideItem(p, (byte)(p.rideList.Count)));
        }
Esempio n. 10
0
        protected virtual void Dispose(bool disposing)
        {
            if (disposed)
            {
                return;
            }

            if (disposing)
            {
                tcp.Close();
                tcp = null;

                if (isJoined)
                {
                    // send despawn to nearbys
                    Lib.sendToNearby(this.hero, PacketEncoder.despawnEntity(this.hero));

                    lock (Lib.entityListByMap)
                    {
                        Lib.entityListByMap.GetValueOrDefault(((IEntity)this.hero).map, null)?.Remove(this.hero);
                    }
                    lock (Lib.clientList)
                    {
                        Lib.clientList.Remove(this.hero.heroID);
                    }
                }

                aes = null;

                if (listenerThread != null)
                {
                    listenerThread = null;
                }
            }

            disposed = true;
        }
Esempio n. 11
0
        public void PacketEncodingSingleFrame()
        {
            JoinRequestMessage originalMessage = new JoinRequestMessage();

            originalMessage.BubbleId              = Guid.NewGuid();
            originalMessage.LocationName          = "TestLocation";
            originalMessage.IdentityProviderUrl   = "IdentityProviderUrl";
            originalMessage.ParticipantIdentifier = "TestParticipantName";
            originalMessage.ParticipantSecret     = "TestParticipantPassphrase";
            originalMessage.ParticipantRealTime   = 10;

            originalMessage.ProgramName          = "TestProgramName";
            originalMessage.ProgramMajorVersion  = 1;
            originalMessage.ProgramMinorVersion  = 2;
            originalMessage.ProtocolMajorVersion = 3;
            originalMessage.ProtocolMinorVersion = 4;

            Packet originalPacket = new Packet();

            originalPacket.SessionId     = 1;
            originalPacket.PacketId      = 2;
            originalPacket.FirstSendTime = 3;
            originalPacket.ResendCount   = 4;
            originalPacket.Quaranteed    = true;

            Session senderSession = new Session();

            senderSession.Send(originalMessage);

            PacketEncoder.EncodePacketHeader(originalPacket);
            bool packetQuaranteed = false;

            PacketEncoder.EncodePacketData(senderSession, originalPacket, ref packetQuaranteed);
            Assert.IsTrue(packetQuaranteed);

            Session receiverSession = new Session();

            Packet receivedPacket = new Packet();

            receivedPacket.PacketLength = originalPacket.PacketLength;
            receivedPacket.PacketBytes  = originalPacket.PacketBytes;

            PacketEncoder.DecodePacketHeader(receivedPacket);

            packetQuaranteed = false;
            PacketEncoder.DecodePacketData(receiverSession, receivedPacket, ref packetQuaranteed);
            Assert.IsTrue(packetQuaranteed);

            Message decodedMessage = receiverSession.Receive();

            Assert.IsNotNull(decodedMessage);

            Assert.AreEqual(0, senderSession.GetOutboundMessageCount());
            Assert.AreEqual(0, senderSession.GetPartiallySentMessageCount());
            Assert.AreEqual(0, senderSession.AvailableMessages);
            Assert.AreEqual(0, senderSession.GetPartiallyReceivedMessageCount());
            Assert.AreEqual(0, receiverSession.GetOutboundMessageCount());
            Assert.AreEqual(0, receiverSession.GetPartiallySentMessageCount());
            Assert.AreEqual(0, receiverSession.AvailableMessages);
            Assert.AreEqual(0, receiverSession.GetPartiallyReceivedMessageCount());



            decodedMessage.MessageId = originalMessage.MessageId;

            decodedMessage.IsAutoRelease = false;

            String originalMessageString = originalMessage.ToString();
            String decodedMessageString  = decodedMessage.ToString();

            Assert.AreEqual(originalMessageString, decodedMessageString);

            String originalPacketString = originalPacket.ToString();
            String receivedPacketString = receivedPacket.ToString();

            Assert.AreEqual(originalPacketString, receivedPacketString);
        }
Esempio n. 12
0
        public void PacketEncodingPerceptionMessageMultiFrame()
        {
            PerceptionEventMessage originalMessage = new PerceptionEventMessage();

            originalMessage.ObjectFragment.ObjectId              = Guid.NewGuid();
            originalMessage.ObjectFragment.ObjectIndex           = 1;
            originalMessage.ObjectFragment.TypeId                = Guid.NewGuid();
            originalMessage.ObjectFragment.ObjectName            = "TestObjectName";
            originalMessage.ObjectFragment.TypeName              = "TestTypeName";
            originalMessage.ObjectFragment.OwnerId               = Guid.NewGuid();
            originalMessage.ObjectFragment.Location.X            = 1; originalMessage.ObjectFragment.Location.Y = 2; originalMessage.ObjectFragment.Location.Z = 3;
            originalMessage.ObjectFragment.Velocity.X            = 4; originalMessage.ObjectFragment.Velocity.Y = 5; originalMessage.ObjectFragment.Velocity.Z = 6;
            originalMessage.ObjectFragment.Acceleration.X        = 7; originalMessage.ObjectFragment.Acceleration.Y = 8; originalMessage.ObjectFragment.Acceleration.Z = 9;
            originalMessage.ObjectFragment.Orientation.X         = 10; originalMessage.ObjectFragment.Orientation.Y = 11; originalMessage.ObjectFragment.Orientation.Z = 12; originalMessage.ObjectFragment.Orientation.W = 13;
            originalMessage.ObjectFragment.AngularVelocity.X     = 14; originalMessage.ObjectFragment.AngularVelocity.Y = 15; originalMessage.ObjectFragment.AngularVelocity.Z = 16; originalMessage.ObjectFragment.AngularVelocity.W = 17;
            originalMessage.ObjectFragment.AngularAcceleration.X = 18; originalMessage.ObjectFragment.AngularAcceleration.Y = 19; originalMessage.ObjectFragment.AngularAcceleration.Z = 20; originalMessage.ObjectFragment.AngularAcceleration.W = 21;
            originalMessage.ObjectFragment.BoundingSphereRadius  = 22;
            originalMessage.ObjectFragment.Mass             = 23;
            originalMessage.ObjectFragment.ExtensionDialect = "TEST";
            originalMessage.ObjectFragment.SetExtensionData(UTF8Encoding.UTF8.GetBytes(
                                                                "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" +
                                                                "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" +
                                                                "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"));

            Packet originalPacket = new Packet();

            originalPacket.SessionId     = 1;
            originalPacket.PacketId      = 2;
            originalPacket.FirstSendTime = 3;
            originalPacket.ResendCount   = 4;
            originalPacket.Quaranteed    = true;

            Session senderSession = new Session();

            senderSession.Send(originalMessage);

            PacketEncoder.EncodePacketHeader(originalPacket);
            bool packetQuaranteed = false;

            PacketEncoder.EncodePacketData(senderSession, originalPacket, ref packetQuaranteed);
            Assert.IsTrue(packetQuaranteed);

            Session receiverSession = new Session();

            Packet receivedPacket = new Packet();

            receivedPacket.PacketLength = originalPacket.PacketLength;
            receivedPacket.PacketBytes  = originalPacket.PacketBytes;

            List <int> highlightedIndexes = new List <int>();

            highlightedIndexes.Add(18 + 5);
            highlightedIndexes.Add(18 + 265 + 5);

            PacketEncoder.DecodePacketHeader(receivedPacket);

            Assert.AreEqual(2, receivedPacket.PacketBytes[18 + 5]);
            Assert.AreEqual(2, receivedPacket.PacketBytes[18 + 265 + 5]);

            packetQuaranteed = false;
            PacketEncoder.DecodePacketData(receiverSession, receivedPacket, ref packetQuaranteed);
            Assert.IsTrue(packetQuaranteed);

            Message decodedMessage = receiverSession.Receive();

            Assert.IsNotNull(decodedMessage);

            Assert.AreEqual(0, senderSession.GetOutboundMessageCount());
            Assert.AreEqual(0, senderSession.GetPartiallySentMessageCount());
            Assert.AreEqual(0, senderSession.AvailableMessages);
            Assert.AreEqual(0, senderSession.GetPartiallyReceivedMessageCount());
            Assert.AreEqual(0, receiverSession.GetOutboundMessageCount());
            Assert.AreEqual(0, receiverSession.GetPartiallySentMessageCount());
            Assert.AreEqual(0, receiverSession.AvailableMessages);
            Assert.AreEqual(0, receiverSession.GetPartiallyReceivedMessageCount());



            decodedMessage.MessageId     = originalMessage.MessageId;
            decodedMessage.IsAutoRelease = false;

            String originalMessageString = originalMessage.ToString();
            String decodedMessageString  = decodedMessage.ToString();

            Assert.AreEqual(originalMessageString, decodedMessageString);

            String originalPacketString = originalPacket.ToString();
            String receivedPacketString = receivedPacket.ToString();

            Assert.AreEqual(originalPacketString, receivedPacketString);
        }
Esempio n. 13
0
        public void PacketEncodingMultiFrame()
        {
            ListBubblesResponse originalMessage = new ListBubblesResponse();

            {
                BubbleFragment bubbleEntry = new BubbleFragment();
                bubbleEntry.BubbleId              = Guid.NewGuid();
                bubbleEntry.BubbleName            = "TestBubble1";
                bubbleEntry.BubbleAssetCacheUrl   = "TestCloudUrl";
                bubbleEntry.BubbleAddress         = "TestBubbleAddress";
                bubbleEntry.BubblePort            = 1;
                bubbleEntry.BubbleCenter.X        = 2;
                bubbleEntry.BubbleCenter.Y        = 3;
                bubbleEntry.BubbleCenter.Z        = 4;
                bubbleEntry.BubbleRange           = 5;
                bubbleEntry.BubblePerceptionRange = 6;
                bubbleEntry.BubbleRealTime        = 7;
                originalMessage.AddBubbleFragment(bubbleEntry);
            }
            {
                BubbleFragment bubbleEntry = new BubbleFragment();
                bubbleEntry.BubbleId              = Guid.NewGuid();
                bubbleEntry.BubbleName            = "TestBubble2";
                bubbleEntry.BubbleAssetCacheUrl   = "TestCloudUrl";
                bubbleEntry.BubbleAddress         = "TestBubbleAddress";
                bubbleEntry.BubblePort            = 1;
                bubbleEntry.BubbleCenter.X        = 2;
                bubbleEntry.BubbleCenter.Y        = 3;
                bubbleEntry.BubbleCenter.Z        = 4;
                bubbleEntry.BubbleRange           = 5;
                bubbleEntry.BubblePerceptionRange = 6;
                bubbleEntry.BubbleRealTime        = 7;
                originalMessage.AddBubbleFragment(bubbleEntry);
            }
            {
                BubbleFragment bubbleEntry = new BubbleFragment();
                bubbleEntry.BubbleId              = Guid.NewGuid();
                bubbleEntry.BubbleName            = "TestBubble3";
                bubbleEntry.BubbleAssetCacheUrl   = "TestCloudUrl";
                bubbleEntry.BubbleAddress         = "TestBubbleAddress";
                bubbleEntry.BubblePort            = 1;
                bubbleEntry.BubbleCenter.X        = 2;
                bubbleEntry.BubbleCenter.Y        = 3;
                bubbleEntry.BubbleCenter.Z        = 4;
                bubbleEntry.BubbleRange           = 5;
                bubbleEntry.BubblePerceptionRange = 6;
                bubbleEntry.BubbleRealTime        = 7;
                originalMessage.AddBubbleFragment(bubbleEntry);
            }
            {
                BubbleFragment bubbleEntry = new BubbleFragment();
                bubbleEntry.BubbleId              = Guid.NewGuid();
                bubbleEntry.BubbleName            = "TestBubble4";
                bubbleEntry.BubbleAssetCacheUrl   = "TestCloudUrl";
                bubbleEntry.BubbleAddress         = "TestBubbleAddress";
                bubbleEntry.BubblePort            = 1;
                bubbleEntry.BubbleCenter.X        = 2;
                bubbleEntry.BubbleCenter.Y        = 3;
                bubbleEntry.BubbleCenter.Z        = 4;
                bubbleEntry.BubbleRange           = 5;
                bubbleEntry.BubblePerceptionRange = 6;
                bubbleEntry.BubbleRealTime        = 7;
                originalMessage.AddBubbleFragment(bubbleEntry);
            }
            {
                BubbleFragment bubbleEntry = new BubbleFragment();
                bubbleEntry.BubbleId              = Guid.NewGuid();
                bubbleEntry.BubbleName            = "TestBubble5";
                bubbleEntry.BubbleAssetCacheUrl   = "TestCloudUrl";
                bubbleEntry.BubbleAddress         = "TestBubbleAddress";
                bubbleEntry.BubblePort            = 1;
                bubbleEntry.BubbleCenter.X        = 2;
                bubbleEntry.BubbleCenter.Y        = 3;
                bubbleEntry.BubbleCenter.Z        = 4;
                bubbleEntry.BubbleRange           = 5;
                bubbleEntry.BubblePerceptionRange = 6;
                bubbleEntry.BubbleRealTime        = 7;
                originalMessage.AddBubbleFragment(bubbleEntry);
            }

            Packet originalPacket = new Packet();

            originalPacket.SessionId     = 1;
            originalPacket.PacketId      = 2;
            originalPacket.FirstSendTime = 3;
            originalPacket.ResendCount   = 4;
            originalPacket.Quaranteed    = true;

            Session senderSession = new Session();

            senderSession.Send(originalMessage);

            PacketEncoder.EncodePacketHeader(originalPacket);
            bool packetQuaranteed = false;

            PacketEncoder.EncodePacketData(senderSession, originalPacket, ref packetQuaranteed);
            Assert.IsTrue(packetQuaranteed);

            Session receiverSession = new Session();

            Packet receivedPacket = new Packet();

            receivedPacket.PacketLength = originalPacket.PacketLength;
            receivedPacket.PacketBytes  = originalPacket.PacketBytes;

            PacketEncoder.DecodePacketHeader(receivedPacket);

            packetQuaranteed = false;
            PacketEncoder.DecodePacketData(receiverSession, receivedPacket, ref packetQuaranteed);
            Assert.IsTrue(packetQuaranteed);

            Message decodedMessage = receiverSession.Receive();

            Assert.IsNotNull(decodedMessage);

            Assert.AreEqual(0, senderSession.GetOutboundMessageCount());
            Assert.AreEqual(0, senderSession.GetPartiallySentMessageCount());
            Assert.AreEqual(0, senderSession.AvailableMessages);
            Assert.AreEqual(0, senderSession.GetPartiallyReceivedMessageCount());
            Assert.AreEqual(0, receiverSession.GetOutboundMessageCount());
            Assert.AreEqual(0, receiverSession.GetPartiallySentMessageCount());
            Assert.AreEqual(0, receiverSession.AvailableMessages);
            Assert.AreEqual(0, receiverSession.GetPartiallyReceivedMessageCount());



            decodedMessage.MessageId = originalMessage.MessageId;


            String originalMessageString = originalMessage.ToString();
            String decodedMessageString  = decodedMessage.ToString();

            Assert.AreEqual(originalMessageString, decodedMessageString);

            String originalPacketString = originalPacket.ToString();
            String receivedPacketString = receivedPacket.ToString();

            Assert.AreEqual(originalPacketString, receivedPacketString);
        }
Esempio n. 14
0
        public virtual void Send(Packet p)
        {
            if (Socket == null || BlockAllPackets)
            {
                p.OnSend();
                return;
            }

            int length;

            var buffer = p.Compile(CompressionEnabled, out length);

            if (buffer != null)
            {
                if (buffer.Length <= 0 || length <= 0)
                {
                    p.OnSend();
                    return;
                }

                PacketSendProfile prof = null;

                if (Core.Profiling)
                {
                    prof = PacketSendProfile.Acquire(p.GetType());
                }

                if (prof != null)
                {
                    prof.Start();
                }

                var buffered = false;

                if (PacketEncoder != null || PacketEncryptor != null)
                {
                    var packetBuffer = buffer;
                    var packetLength = length;

                    if (BufferStaticPackets && p.State.HasFlag(PacketState.Acquired))
                    {
                        if (packetLength <= SendBufferSize)
                        {
                            packetBuffer = m_SendBufferPool.AcquireBuffer();
                        }
                        else
                        {
                            packetBuffer = new byte[packetLength];
                        }

                        System.Buffer.BlockCopy(buffer, 0, packetBuffer, 0, packetLength);
                    }

                    if (PacketEncoder != null)
                    {
                        PacketEncoder.EncodeOutgoingPacket(this, ref packetBuffer, ref packetLength);
                    }

                    if (PacketEncryptor != null)
                    {
                        PacketEncryptor.EncryptOutgoingPacket(this, ref packetBuffer, ref packetLength);
                    }

                    buffered = buffer != packetBuffer && packetBuffer.Length == SendBufferSize;

                    buffer = packetBuffer;
                    length = packetLength;
                }

                try
                {
                    SendQueue.Gram gram;

                    lock (_SendLock)
                    {
                        lock (m_SendQueue)
                        {
                            gram = m_SendQueue.Enqueue(buffer, length);
                        }

                        if (buffered && m_SendBufferPool.Count < SendBufferCapacity)
                        {
                            m_SendBufferPool.ReleaseBuffer(buffer);
                        }

                        if (gram != null && !_Sending)
                        {
                            _Sending = true;

                            try
                            {
                                Socket.BeginSend(gram.Buffer, 0, gram.Length, SocketFlags.None, m_OnSend, Socket);
                            }
                            catch (Exception ex)
                            {
                                TraceException(ex);
                                Dispose(false);
                            }
                        }
                    }
                }
                catch (CapacityExceededException)
                {
                    Utility.PushColor(ConsoleColor.Red);
                    Console.WriteLine("Client: {0}: Too much data pending, disconnecting...", this);
                    Utility.PopColor();

                    Dispose(false);
                }

                p.OnSend();

                if (prof != null)
                {
                    prof.Finish(length);
                }
            }
            else
            {
                Utility.PushColor(ConsoleColor.Red);
                Console.WriteLine("Client: {0}: null buffer send, disconnecting...", this);
                Utility.PopColor();

                using (var op = new StreamWriter("null_send.log", true))
                {
                    op.WriteLine("{0} Client: {1}: null buffer send, disconnecting...", DateTime.UtcNow, this);
                    op.WriteLine(new StackTrace());
                }

                Dispose();
            }
        }
        public static void handle(string cmd)
        {
            var    inp = cmd.Split(" ");
            int    heroID;
            Client cli;

            switch (inp[0].ToLower())
            {
            case "e":
            case "end":
            case "exit":
                Lib.endSrv = true;
                Console.WriteLine("[!] Killing Server ...");
                break;

            case "snpc":
                //Lib.broadcast(PacketEncoder.spawnNPC(int.Parse(inp[1]), new Location(45, 45, Map.TYC)));
                break;

            case "give_test_item":
            case "gti":
                Console.WriteLine("[.] Input Give Test Item Mode:");
                Console.WriteLine("    -- Type \"exit\" to exit this mode --");
                Console.Write("\t[+] Please type the HeroID to send to.\n\tHeroID: ");

                if (!int.TryParse(Console.ReadLine(), out heroID))
                {
                    Console.WriteLine($"\t[!] Failed to parse heroID to integer.");
                    Console.WriteLine("\t[!] Exited Give Test Item Mode.");
                    return;
                }

                if (!Lib.clientList.ContainsKey(heroID))
                {
                    Console.WriteLine($"\t[!] HeroID[{heroID}] is not connected.");
                    Console.WriteLine("\t[!] Exited Give Test Item Mode.");
                    return;
                }
                cli = Lib.clientList[heroID];

                Console.WriteLine("\t[.] Please enter the item with format: <itemID> [baseID]. (baseID is optional)");
                do
                {
                    Console.Write("\n\t[+] Give Item: ");
                    inp = Console.ReadLine().Split(" ");

                    uint gti_itemID = 0,
                         gti_baseID = 0;

                    if (inp.Length >= 1)
                    {
                        if (inp[0] == "exit")
                        {
                            break;     // exit
                        }
                        // itemID is given

                        if (inp.Length > 2)
                        {
                            continue;     // incorrect format
                        }
                        else
                        {
                            // itemID & baseID are given
                            if (!uint.TryParse(inp[1], out gti_baseID))
                            {
                                Console.WriteLine($"\t[!] Failed to parse baseID unsigned-integer.");
                                Console.WriteLine("\t[!] Exited Give Test Item Mode.");
                                return;
                            }
                        }

                        if (!uint.TryParse(inp[0], out gti_itemID))
                        {
                            Console.WriteLine($"\t[!] Failed to parse itemID unsigned-integer.");
                            Console.WriteLine("\t[!] Exited Give Test Item Mode.");
                            return;
                        }

                        Item item = null;
                        if (gti_itemID >= 124000 && gti_itemID <= 124019)
                        {
                            item = new RideWing();
                            ((RideWing)item).wingsID = 0x0841;
                            ((RideWing)item).wingsLv = 0x000b;
                        }
                        else if (gti_baseID >= 101035 && gti_baseID <= 101039 || gti_baseID == 101057)
                        {
                            item = new RideContract();
                        }

                        item ??= new Item();
                        item.itemUID = Lib.lastItemUID++;
                        item.baseID  = gti_baseID == 0 ? gti_itemID : gti_baseID;
                        item.itemID  = gti_itemID;
                        item.stack   = 1;

                        item.headAttributes.Add(EHeadAttribute.forever_binded);

                        if (cli.hero.bag.addItem(cli.hero, item))
                        {
                            cli.send(PacketEncoder.addBagItem(item));
                        }
                        else
                        {
                            Console.WriteLine($"[-] Failed to give item to Hero[{cli.hero.heroName} (ID: {heroID})]. [More: Bag is full]");
                        }
                    }
                    else
                    {
                        continue;     // incorrect format
                    }
                }while (true);

                Console.WriteLine("\t[!] Exited Give Test Item Mode.");
                break;

            case "send_raw_pkt":
            case "srp":
                Console.WriteLine("[.] Input Raw Packet Mode:");
                Console.WriteLine("    -- Type \"erp\" to exit this mode --");
                Console.WriteLine("    -- Type \"x\" to clear the current send buffer --");
                Console.WriteLine("    -- Type \"show\" to show the current send buffer --");
                Console.WriteLine("    -- Press ENTER or \"s\" after packet to send the packets --");
                Console.Write("\t[+] Please type the HeroID to send to. (-1 is broadcast)\n\tHeroID: ");

                if (!int.TryParse(Console.ReadLine(), out heroID))
                {
                    Console.WriteLine($"\t[!] Failed to parse heroID to integer. Fallback to broadcast mode.");
                    heroID = -1;
                }

                if (!Lib.clientList.ContainsKey(heroID))
                {
                    Console.WriteLine($"\t[!] HeroID[{heroID}] is not connected. Fallback to broadcast mode.");
                    heroID = -1;
                }

                Console.WriteLine("\t[.] Enter the pkt.\n");
                byte          numByte  = 0;
                ushort        numShort = 0;
                int           numInt   = 0;
                string        pkt;
                List <byte[]> fullPkt = new List <byte[]>();
                do
                {
                    Console.Write("\t +-> ");
                    pkt = Console.ReadLine();
                    if (pkt == "" || pkt == "s")
                    {
                        if (heroID == -1)
                        {
                            Lib.broadcast(fullPkt.SelectMany(x => x).ToArray());
                        }
                        else
                        {
                            Client c;
                            if (Lib.clientList.TryGetValue(heroID, out c))
                            {
                                c.send(fullPkt.SelectMany(x => x).ToArray());
                            }
                            else
                            {
                                Console.WriteLine($"\t[-] HeroID[{heroID}] not found. No packet sent.");
                            }
                        }
                    }
                    else if (pkt.StartsWith("rm"))
                    {
                        if (pkt.Length < 3)
                        {
                            continue;
                        }

                        byte idx = byte.Parse(pkt.Split(" ")[1]);
                        fullPkt.RemoveAt(idx);
                    }
                    else if (pkt == "ins")
                    {
                        // (insertion)
                        // ins <idx>
                        // > new pkt <
                        if (pkt.Length < 5)
                        {
                            continue;
                        }

                        byte idx = byte.Parse(pkt.Split(" ")[1]);
                        Console.WriteLine("\t[.] Enter the pkt.\n");
                        pkt = Console.ReadLine();

                        byte[] tmpPkt = new byte[0];
                        try
                        {
                            PacketEncoder.concatPacket(Lib.hexToBytes(
                                                           pkt.Replace("{hid}", Lib.toHex(heroID == -1 ? 0x78563412 : heroID)).Replace("_", "")
                                                           ), ref tmpPkt);
                            fullPkt.Insert(idx, tmpPkt);
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine($"\t[!] Failed to parse pkt. Error[{e.Message}]");
                        }
                    }
                    else if (pkt == "rp")
                    {
                        // (replace)
                        // rp <idx>
                        // > new pkt <
                        if (pkt.Length < 4)
                        {
                            continue;
                        }

                        byte idx = byte.Parse(pkt.Split(" ")[1]);
                        Console.WriteLine("\t[.] Enter the pkt.\n");
                        pkt = Console.ReadLine();

                        byte[] tmpPkt = new byte[0];
                        try
                        {
                            PacketEncoder.concatPacket(Lib.hexToBytes(
                                                           pkt
                                                           .Replace("{hid}", Lib.toHex(heroID == -1 ? 0x78563412 : heroID))
                                                           .Replace("{ai:1}", Lib.toHex(numByte++))  // auto increment: 1 byte
                                                           .Replace("{ai:2}", Lib.toHex(numShort++)) // auto increment: 2 byte
                                                           .Replace("{ai:4}", Lib.toHex(numInt++))   // auto increment: 4 byte
                                                           .Replace("_", "")
                                                           ), ref tmpPkt);
                            fullPkt[idx] = tmpPkt;
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine($"\t[!] Failed to parse pkt. Error[{e.Message}]");
                        }
                    }
                    else if (pkt == "x")
                    {
                        fullPkt  = new List <byte[]>();
                        numByte  = 0;
                        numShort = 0;
                        numInt   = 0;
                        Console.WriteLine($"\t[!] Cleared.\n");
                    }
                    else if (pkt.StartsWith("ai "))
                    {
                        var str  = pkt.Split(" ")[1];
                        var flag = System.Globalization.NumberStyles.Integer;

                        if (str.StartsWith("0x"))
                        {
                            flag = System.Globalization.NumberStyles.HexNumber;
                        }

                        if (int.TryParse(str, flag, null, out numInt))
                        {
                            if (!ushort.TryParse(str, flag, null, out numShort))
                            {
                                Console.WriteLine("[!] Value applied to numInt only.");
                                continue;
                            }
                            else if (!byte.TryParse(str, flag, null, out numByte))
                            {
                                Console.WriteLine("[!] Value applied to numInt & numShort only.");
                                continue;
                            }

                            Console.WriteLine("[+] Value applied to numInt & numShort & numByte.");
                            continue;
                        }

                        Console.WriteLine("[X] Are you fking srsly? This fking value cant parse to either int, ushort, or byte!");
                        continue;
                    }
                    else if (pkt == "show" || pkt == "sh" || pkt == "q")
                    {
                        Console.WriteLine(Lib.pktParser(
                                              Lib.toHex(fullPkt.SelectMany(x => x).ToArray())
                                              ));
                    }
                    else if (pkt == "erp")
                    {
                        break;
                    }
                    else if (pkt.Contains("x"))
                    {
                        Console.WriteLine("\t[!] Failed to add pkt. Since it contains \"x\"\n");
                        continue;
                    }
                    else if (pkt != "")
                    {
                        byte[] tmpPkt = new byte[0];
                        try
                        {
                            PacketEncoder.concatPacket(Lib.hexToBytes(
                                                           pkt.Replace("{hid}", Lib.toHex(heroID == -1 ? 0x78563412 : heroID)).Replace("_", "")
                                                           ), ref tmpPkt);
                            fullPkt.Add(tmpPkt);
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine($"\t[!] Failed to parse pkt. Error[{e.Message}]");
                        }
                    }
                } while (true);

                Console.WriteLine("[.] Exited Raw Packet Mode.");
                break;

            case "give":
                if (inp[1] == "item")
                {
                    int  targetID = int.Parse(inp[2]);
                    uint itemID   = uint.Parse(inp[3]);
                    uint baseID   = 0;

                    if (inp.Length == 5)
                    {
                        baseID = uint.Parse(inp[4]);
                    }

                    cli = Lib.clientList.GetValueOrDefault(targetID, null);

                    if (cli == null)
                    {
                        Console.WriteLine($"[X] Failed to find target[{targetID}]");
                        return;
                    }

                    // TODO: ItemFactory pattern
                    Item item = null;
                    if (itemID >= 124000 && itemID <= 124019)
                    {
                        item = new RideWing();
                        ((RideWing)item).wingsID = 0x0841;
                        ((RideWing)item).wingsLv = 0x000b;
                    }
                    else if (baseID >= 101035 && baseID <= 101039 || baseID == 101057)
                    {
                        item = new RideContract();
                    }

                    item ??= new Item();
                    item.itemUID = Lib.lastItemUID++;
                    item.baseID  = baseID == 0 ? itemID : baseID;
                    item.itemID  = itemID;
                    item.stack   = 1;
                    item.quality = 4;

                    item.headAttributes.Add(EHeadAttribute.forever_binded);

                    item.itemAttributes.Add(new ItemAttribute(
                                                EItemAttribute.durability,
                                                Lib.hexToBytes(
                                                    "64 78000000 64 ff000000 00"
                                                    ),
                                                new object[] { 0x78, 0xFF }
                                                ));
                    item.itemAttributes.Add(new ItemAttribute(
                                                EItemAttribute.hole_skill_desc,
                                                Lib.hexToBytes(
                                                    "64 91E10800 64 03000000 00"
                                                    ),
                                                new object[] { /*skillID*/ 582033, 3 }
                                                ));
                    item.itemAttributes.Add(new ItemAttribute(
                                                EItemAttribute.hole_skill_amount,
                                                Lib.hexToBytes(
                                                    "64 0B000000 64 03000000 00"
                                                    ),
                                                new object[] { 11, 3 }
                                                ));

                    if (cli.hero.bag.addItem(cli.hero, item))
                    {
                        cli.send(PacketEncoder.addBagItem(item));
                    }
                    else
                    {
                        Console.WriteLine($"[-] Failed to give item to Hero[{cli.hero.heroName} (ID: {targetID})]. [More: Bag is full]");
                    }
                }
                break;

            case "help":
                Console.WriteLine("----- Help -----");
                Console.WriteLine("  exit\t Kill the server.");
                Console.WriteLine("  srp\t Enter \"send raw packet\" mode.");
                Console.WriteLine("  give\t Give item to player.");
                Console.WriteLine("--- End Help ---");
                break;

            default:
                Console.WriteLine("[-] Unknown Command. Type \"help\" to print command list.");
                break;
            }
        }