Пример #1
0
        public GameConnection(Session session)
        {
            _session    = session;
            Subscribers = new List <IDisposable>();

            Characters = new Dictionary <uint, Character>();
            Houses     = new Dictionary <uint, House>();
            Payment    = new AccountPayment(this);

            //шифрация пакетов
            CryptRsa       = new CryptRSA();
            DecryptCs      = new DecryptCs();
            EncryptSc      = new EncryptSc();
            EncryptSc.MNum = 0;
        }
        // получаем пакеты от клиента
        public void OnReceive(GameConnection connection, byte[] buf, int bytes)
        {
            int offset;

            try
            {
                var stream = new PacketStream();
                if (connection.LastPacket != null)
                {
                    stream.Insert(0, connection.LastPacket);
                    connection.LastPacket = null;
                }
                offset = stream.Count; // запомним начало пакета
                stream.Insert(stream.Count, buf);
                while (stream != null && stream.Count > 0)
                {
                    ushort len;
                    try
                    {
                        len = stream.ReadUInt16();
                    }
                    catch (MarshalException)
                    {
                        //_log.Warn("Error on reading type {0}", type);
                        stream.Rollback();
                        connection.LastPacket = stream;
                        stream = null;
                        continue;
                    }
                    var packetLen = len + stream.Pos;
                    if (packetLen <= stream.Count)
                    {
                        stream.Rollback();
                        var stream2 = new PacketStream();
                        stream2.Replace(stream, 0, packetLen);
                        if (stream.Count > packetLen)
                        {
                            var stream3 = new PacketStream();
                            stream3.Replace(stream, packetLen, stream.Count - packetLen);
                            stream = stream3;
                        }
                        else
                        {
                            stream = null;
                        }

                        stream2.ReadUInt16(); //len
                        stream2.ReadByte();   //unk
                        var  level   = stream2.ReadByte();
                        uint type    = 0;
                        byte crc     = 0;
                        byte counter = 0;
                        if (level == 1)
                        {
                            crc     = stream2.ReadByte(); // TODO 1.2 crc
                            counter = stream2.ReadByte(); // TODO 1.2 counter
                        }
                        if (level == 5)
                        {
                            //пакет от клиента, дешифруем
                            //------------------------------
                            var input = new byte[stream2.Count - 2];
                            Buffer.BlockCopy(stream2, 2, input, 0, stream2.Count - 2);
                            var output = DecryptCs.Decode(input, GameConnection.CryptRsa.XorKey, GameConnection.CryptRsa.AesKey, GameConnection.CryptRsa.Iv, m_numPck);
                            m_numPck++;                                                  //увеличим номер пакета от клиента
                            var OutBytes = new byte[output.Length + 5];
                            Buffer.BlockCopy(stream2, offset, OutBytes, 0, 5);           // скопируем (ushort)len, 0005
                            Buffer.BlockCopy(output, 1, OutBytes, 5, output.Length - 1); // сформируем полный расшифрованные пакет
                            // заменим шифрованные данные на дешифрованные
                            var strm = new PacketStream();
                            strm.Write(OutBytes);
                            stream2.Replace(strm, 0, OutBytes.Length);
                            stream2.ReadUInt16();
                            //------------------------------
                        }
                        type = stream2.ReadUInt16();

                        _packets[level].TryGetValue(type, out var classType);
                        if (classType == null)
                        {
                            HandleUnknownPacket(connection, type, level, stream2);
                        }
                        else
                        {
                            var packet = (GamePacket)Activator.CreateInstance(classType);
                            packet.Level      = level;
                            packet.Connection = connection;
                            packet.Decode(stream2);
                        }
                    }
                    else
                    {
                        stream.Rollback();
                        connection.LastPacket = stream;
                        stream = null;
                    }
                }
            }
            catch (Exception e)
            {
                connection?.Shutdown();
                _log.Error(e);
            }
        }