示例#1
0
        public void SendPacket(byte[] packet)
        {
            Precondition.Check <InvalidOperationException>(Connected, "Socket is not connected");
            Precondition.Check <InvalidOperationException>(Encrypted, "Handshake has not been received yet");
            Precondition.Check <ArgumentException>(packet.Length >= 2, @"Packet length must be greater than 2");

            lock (sendLock) {
                byte[] final = new byte[packet.Length + PACKET_HEADER_SIZE];

                switch (SessionType)
                {
                case SessionType.CLIENT:
                    clientCipher.GetHeaderToServer(packet.Length, final);
                    break;

                case SessionType.SERVER:
                    clientCipher.GetHeaderToClient(packet.Length, final);
                    break;
                }

                clientCipher.Transform(packet);
                Buffer.BlockCopy(packet, 0, final, PACKET_HEADER_SIZE, packet.Length);
                SendRawPacket(final);
            }
        }
示例#2
0
        private void SendInternal(byte[] packet)
        {
            short  opcode = BitConverter.ToInt16(packet, 0);
            SendOp sendOp = (SendOp)opcode;

            switch (sendOp)
            {
            case SendOp.USER_SYNC:
            case SendOp.KEY_TABLE:
            case SendOp.STAT:
            case SendOp.EMOTION:
            case SendOp.CHARACTER_LIST:
            case SendOp.ITEM_INVENTORY:
            case SendOp.FIELD_ADD_NPC:
            case SendOp.FIELD_PORTAL:
            case SendOp.NPC_CONTROL:
            case SendOp.PROXY_GAME_OBJ:
            case SendOp.FIELD_ADD_USER:
            case SendOp.FIELD_ENTRANCE:
            case SendOp.SERVER_ENTER:
                break;

            default:
                string packetString = packet.ToHexString(' ');
                logger.Debug($"SEND ({sendOp.ToString()}): {packetString.Substring(Math.Min(packetString.Length, 6))}".Pastel("#E05561"));
                break;
            }
            Packet encryptedPacket = sendCipher.Transform(packet);

            SendRaw(encryptedPacket);
        }
示例#3
0
        private async void StartRead()
        {
            CancellationToken readToken = Source.Token;

            while (!readToken.IsCancellationRequested)
            {
                try
                {
                    int length = await NetworkStream.ReadAsync(RecvBuffer.AsMemory(0, RecvBuffer.Length), readToken);

                    if (length <= 0)
                    {
                        if (!Connected())
                        {
                            return;
                        }

                        continue;
                    }

                    MapleStream.Write(RecvBuffer, 0, length);
                }
                catch (IOException)
                {
                    Disconnect();
                    return;
                }
                catch (Exception ex)
                {
                    Logger.Error(ex, "Exception reading from socket:");
                    return;
                }

                while (MapleStream.TryRead(out byte[] packetBuffer))
                {
                    Packet packet = RecvCipher.Transform(packetBuffer);
                    short  opcode = packet.Reader().ReadShort();

                    RecvOp recvOp = (RecvOp)opcode;

                    switch (recvOp)
                    {
                    case RecvOp.USER_SYNC:
                    case RecvOp.KEY_TABLE:
                    case RecvOp.RIDE_SYNC:
                    case RecvOp.GUIDE_OBJECT_SYNC:
                    case RecvOp.REQUEST_TIME_SYNC:
                    case RecvOp.STATE:
                    case RecvOp.STATE_FALL_DAMAGE:
                    case RecvOp.VIBRATE:
                        break;

                    default:
                        string packetString = packet.ToString();
                        Logger.Debug($"RECV ({recvOp}): {packetString[Math.Min(packetString.Length, 6)..]}".ColorGreen());
                        break;
                    }
                    OnPacket?.Invoke(this, packet); // handle packet
                }
示例#4
0
        private void SendInternal(byte[] packet)
        {
            short opcode = BitConverter.ToInt16(packet, 0);

            if (opcode != 0x1C)   // Filtering sync from logs
            {
                logger.Debug($"SEND ({packet.Length}): {packet.ToHexString(' ')}");
            }
            Packet encryptedPacket = sendCipher.Transform(packet);

            SendRaw(encryptedPacket);
        }
示例#5
0
        private async void StartRead()
        {
            CancellationToken readToken = source.Token;

            while (!readToken.IsCancellationRequested)
            {
                try
                {
                    int length = await networkStream.ReadAsync(recvBuffer, 0, recvBuffer.Length, readToken);

                    if (length <= 0)
                    {
                        if (!Connected())
                        {
                            return;
                        }
                        continue;
                    }

                    mapleStream.Write(recvBuffer, 0, length);
                }
                catch (IOException ex)
                {
                    logger.Error("Exception reading from socket: ", ex);
                    return;
                }

                while (mapleStream.TryRead(out byte[] packetBuffer))
                {
                    Packet packet = recvCipher.Transform(packetBuffer);
                    short  opcode = packet.Reader().ReadShort();

                    RecvOp recvOp = (RecvOp)opcode;

                    switch (recvOp)
                    {
                    case RecvOp.USER_SYNC:
                    case RecvOp.KEY_TABLE:
                        break;

                    default:
                        string packetString = packet.ToString();
                        logger.Debug($"RECV ({recvOp.ToString()}): {packetString.Substring(Math.Min(packetString.Length, 6))}".Pastel("#8CC265"));
                        break;
                    }
                    OnPacket?.Invoke(this, packet); // handle packet
                }
            }
        }
示例#6
0
        private void SendInternal(byte[] packet)
        {
            short  opcode = BitConverter.ToInt16(packet, 0);
            SendOp sendOp = (SendOp)opcode;

            switch (sendOp)
            {
            case SendOp.USER_SYNC:
                break;

            default:
                string packetString = packet.ToHexString(' ');
                logger.Debug($"SEND ({sendOp.ToString()}): {packetString.Substring(Math.Min(packetString.Length, 6))}".Pastel("#E05561"));
                break;
            }
            Packet encryptedPacket = sendCipher.Transform(packet);

            SendRaw(encryptedPacket);
        }
示例#7
0
        public void SendPacket(PacketWriter packet)
        {
            if (!m_connected)
            {
                throw new InvalidOperationException("Socket is not connected");
            }

            if (!m_encrypted)
            {
                throw new InvalidOperationException("Handshake has not been received yet");
            }

            byte[] data = packet.ToArray();

            if (data.Length < 2)
            {
                throw new ArgumentOutOfRangeException("Packet length must be greater than 2", "packet");
            }

            const int HeaderSize = 4;

            lock (m_sendLock)
            {
                byte[] final = new byte[data.Length + HeaderSize];

                switch (m_sessionType)
                {
                case SessionType.Client:
                    m_clientCipher.GetHeaderToServer(data.Length, final);
                    break;

                case SessionType.Server:
                    m_clientCipher.GetHeaderToClient(data.Length, final);
                    break;
                }

                m_clientCipher.Transform(data);

                Buffer.BlockCopy(data, 0, final, HeaderSize, data.Length);

                SendRawPacket(final);
            }
        }
示例#8
0
        private void ProcessPacket()
        {
            while (cursor > PACKET_HEADER_SIZE && Connected)
            {
                int packetSize = MapleCipher.GetPacketLength(packetBuffer);
                if (cursor < packetSize + PACKET_HEADER_SIZE || OnPacket == null)
                {
                    return;
                }

                byte[] buffer = new byte[packetSize];
                Buffer.BlockCopy(packetBuffer, PACKET_HEADER_SIZE, buffer, 0, packetSize);
                serverCipher.Transform(buffer);

                cursor -= packetSize + PACKET_HEADER_SIZE;
                if (cursor > 0)
                {
                    Buffer.BlockCopy(packetBuffer, packetSize + PACKET_HEADER_SIZE, packetBuffer, 0, cursor);
                }
                OnPacket(this, buffer);
            }
        }
示例#9
0
        private async void StartRead()
        {
            CancellationToken readToken = source.Token;

            while (!readToken.IsCancellationRequested)
            {
                try {
                    int length = await networkStream.ReadAsync(recvBuffer, 0, recvBuffer.Length, readToken);

                    if (length <= 0)
                    {
                        if (!Connected())
                        {
                            return;
                        }
                        continue;
                    }

                    mapleStream.Write(recvBuffer, 0, length);
                } catch (IOException ex) {
                    logger.Error("Exception reading from socket: ", ex);
                    return;
                }

                while (mapleStream.TryRead(out byte[] packetBuffer))
                {
                    Packet packet = recvCipher.Transform(packetBuffer);
                    short  opcode = packet.Reader().ReadShort();
                    if (opcode != 0x12)   // Filtering sync from logs
                    {
                        logger.Debug($"RECV ({packet.Length}): {packet}");
                    }
                    OnPacket?.Invoke(this, packet); // handle packet
                }
            }
        }
示例#10
0
        private void ManipulateBuffer()
        {
            if (m_encrypted)
            {
                const int HeaderSize = 4;

                while (m_cursor > HeaderSize && m_connected) //header room + still connected
                {
                    int packetSize = MapleCipher.GetPacketLength(m_packetBuffer);

                    if (m_cursor < packetSize + HeaderSize) //header + packet room
                    {
                        break;
                    }

                    byte[] buffer = new byte[packetSize];
                    Buffer.BlockCopy(m_packetBuffer, HeaderSize, buffer, 0, packetSize); //copy packet
                    m_serverCipher.Transform(buffer);                                    //decrypt

                    m_cursor -= packetSize + HeaderSize;                                 //fix len

                    if (m_cursor > 0)                                                    //move reamining bytes
                    {
                        Buffer.BlockCopy(m_packetBuffer, packetSize + HeaderSize, m_packetBuffer, 0, m_cursor);
                    }

                    if (OnPacket != null)
                    {
                        OnPacket(this, buffer);
                    }

                    buffer = null; //get rid of buffer
                }
            }
            else if (m_cursor >= 2)
            {
                const int HeaderSize = 2;

                short packetSize = BitConverter.ToInt16(m_packetBuffer, 0);

                if (m_cursor >= packetSize + HeaderSize)
                {
                    byte[] buffer = new byte[packetSize];
                    Buffer.BlockCopy(m_packetBuffer, HeaderSize, buffer, 0, packetSize);

                    PacketReader packet = new PacketReader(buffer);

                    short  major = packet.ReadShort();
                    string minor = packet.ReadMapleString();

                    m_clientCipher = new MapleCipher(major, packet.ReadBytes(4), m_aesCipher, CipherType.Encrypt);
                    m_serverCipher = new MapleCipher(major, packet.ReadBytes(4), m_aesCipher, CipherType.Decrypt);

                    byte locale = packet.ReadByte();

                    m_encrypted = true; //start waiting for encrypted packets

                    if (OnHandshake != null)
                    {
                        var info = new ServerInfo()
                        {
                            Version    = major,
                            Subversion = minor,
                            Locale     = locale
                        };

                        OnHandshake(this, info);
                    }

                    buffer   = null; //get rid of buffer
                    m_cursor = 0;    //reset stream
                }
            }
        }