Esempio n. 1
0
        /// <summary>
        /// Data received event handler
        /// </summary>
        /// <param name="iar">IAsyncResult of the data received event</param>
        private void OnDataReceived(IAsyncResult iar)
        {
            var socketInfo = (SocketInfo)iar.AsyncState;

            try
            {
                var received = socketInfo.Socket.EndReceive(iar);
                if (received == 0)
                {
                    OnClientDisconnected?.Invoke(this);
                    return;
                }

                socketInfo.Index += received;

                if (socketInfo.Index == socketInfo.DataBuffer.Length)
                {
                    switch (socketInfo.State)
                    {
                    case SocketInfo.StateEnum.Header:
                        if (socketInfo.IsNoEncryption)
                        {
                            var headerReader = new PacketReader(socketInfo.DataBuffer);
                            var packetHeader = headerReader.ReadShort();
                            socketInfo.State      = SocketInfo.StateEnum.Content;
                            socketInfo.DataBuffer = new byte[packetHeader];
                            socketInfo.Index      = 0;
                            WaitForData(socketInfo);
                        }
                        else
                        {
                            var headerReader  = new PacketReader(socketInfo.DataBuffer);
                            var packetHeaderB = headerReader.ToArray();
                            var packetHeader  = headerReader.ReadInt();
                            var packetLength  = (short)MapleCrypto.GetPacketLength(packetHeader);
                            if (Type == SessionType.SERVER_TO_CLIENT &&
                                !RIV.CheckPacketToServer(BitConverter.GetBytes(packetHeader)))
                            {
                                Log.LogError("Packet check failed. Disconnecting client");
                                Socket.Close();
                            }

                            socketInfo.State      = SocketInfo.StateEnum.Content;
                            socketInfo.DataBuffer = new byte[packetLength];
                            socketInfo.Index      = 0;
                            WaitForData(socketInfo);
                        }

                        break;

                    case SocketInfo.StateEnum.Content:
                        var data = socketInfo.DataBuffer;

                        if (socketInfo.IsNoEncryption)
                        {
                            socketInfo.IsNoEncryption = false;
                            var reader  = new PacketReader(data);
                            var version = reader.ReadShort();
                            var unknown = reader.ReadMapleString();
                            SIV = new MapleCrypto(reader.ReadBytes(4), version);
                            RIV = new MapleCrypto(reader.ReadBytes(4), version);
                            var serverType = reader.ReadByte();

                            if (Type == SessionType.CLIENT_TO_SERVER)
                            {
                                OnInitPacketReceived(version, serverType);
                            }

                            OnPacketReceived(new PacketReader(data), true);
                            WaitForData();
                        }
                        else
                        {
                            RIV.Crypt(data);
                            MapleCustomEncryption.Decrypt(data);

                            if (data.Length != 0)
                            {
                                OnPacketReceived?.Invoke(new PacketReader(data), false);
                            }

                            WaitForData();
                        }

                        break;
                    }
                }
                else
                {
                    Log.LogWarning("Not enough data");
                    WaitForData(socketInfo);
                }
            }
            catch (ObjectDisposedException e)
            {
                Log.LogError("Socket has been closed", e);
            }
            catch (SocketException se)
            {
                if (se.ErrorCode != 10054)
                {
                    Log.LogError("Session.OnDataReceived", se);
                }
            }
            catch (Exception e)
            {
                Log.LogError("Session.OnDataReceived", e);
            }
        }