コード例 #1
0
        bool SendRawPacketInternal(RawPacket packet, byte[] buffer,
                                   Socket socket, TeraEncryptionSession encryption, bool server)
        {
            if (packet == null)
            {
                throw new ArgumentNullException(nameof(packet));
            }

            if (packet.Payload.Length > PacketHeader.MaxPayloadSize)
            {
                throw new ArgumentException("Packet is too big.", nameof(packet));
            }

            var header = new PacketHeader((ushort)packet.Payload.Length,
                                          Proxy.Processor.Serializer.Messages.Game.NameToOpCode[packet.OpCode]);

            lock (socket)
            {
                PacketProcessor.WriteHeader(header, buffer);
                Buffer.BlockCopy(packet.Payload, 0, buffer,
                                 PacketHeader.HeaderSize, header.Length);

                try
                {
                    return(SendInternal(buffer, header.FullLength, false,
                                        socket, encryption, server));
                }
                catch (SocketDisconnectedException)
                {
                    // Normal disconnection.
                    return(false);
                }
            }
        }
コード例 #2
0
 public GameClient(TeraEncryptionKeys keys, MessageTables tables)
 {
     if (keys == null)
     {
         throw new ArgumentNullException(nameof(keys));
     }
     _tesClient = new TeraEncryptionSession(PacketDirection.ServerToClient, keys);
     _tesServer = new TeraEncryptionSession(PacketDirection.ClientToServer, keys);
     Processor  = new PacketProcessor(new PacketSerializer(tables));
 }
コード例 #3
0
        void ReceiveInternal(byte[] data, int length, Socket socket,
                             TeraEncryptionSession encryption, bool server)
        {
            RunGuarded(true, server, () =>
            {
                socket.ReceiveFull(data, 0, length);

                if (encryption != null)
                {
                    lock (encryption)
                        encryption.Decrypt(data, 0, length);
                }
            });
        }
コード例 #4
0
        bool SendInternal(byte[] data, int length, bool rethrow,
                          Socket socket, TeraEncryptionSession encryption, bool server)
        {
            return(RunGuarded(rethrow, server, () =>
            {
                if (encryption != null)
                {
                    lock (encryption)
                        encryption.Encrypt(data, 0, length);
                }

                lock (socket)
                    socket.SendFull(data, 0, length);
            }));
        }
コード例 #5
0
ファイル: GameClient.cs プロジェクト: neowutran/alkahest
        bool SendRawPacketInternal(RawPacket packet, byte[] buffer,
                                   Socket socket, TeraEncryptionSession encryption, bool server)
        {
            lock (socket)
            {
                var header = new PacketHeader((ushort)packet.Payload.Length,
                                              Proxy.Processor.Serializer.GameMessages.NameToOpCode[packet.OpCode]);

                PacketProcessor.WriteHeader(header, buffer);
                Buffer.BlockCopy(packet.Payload, 0, buffer,
                                 PacketHeader.HeaderSize, header.Length);

                return(SendInternal(buffer, header.FullLength, false,
                                    socket, encryption, server));
            }
        }
コード例 #6
0
        void OnConnect(object sender, SocketAsyncEventArgs args)
        {
            var error = args.SocketError;

            args.Completed -= OnConnect;
            Proxy.ArgsPool.TryPut(args);

            if (error != SocketError.Success && error != SocketError.OperationAborted)
            {
                DisconnectInternal();
                _log.Error("Could not connect to {0} ({1}) for client {2}: {3}",
                           Proxy.Info.Name, Proxy.Info.RealEndPoint, EndPoint, error);
                return;
            }

            _log.Info("Connected to {0} ({1}) for client {2}",
                      Proxy.Info.Name, Proxy.Info.RealEndPoint, EndPoint);

            byte[] ckey1;
            byte[] ckey2;
            byte[] skey1;
            byte[] skey2;

            try
            {
                var magic = ReceiveFromServerInternal(_magic.Length);
                SendToClientInternal(magic, true);

                if (!magic.SequenceEqual(_magic))
                {
                    DisconnectInternal();
                    _log.Error("Disconnected client {0} from {1} due to incorrect magic bytes: {2}",
                               EndPoint, Proxy.Info.Name,
                               magic.Aggregate("0x", (acc, x) => acc + x.ToString("X2")));
                    return;
                }

                ckey1 = ReceiveFromClientInternal(TeraEncryptionSession.KeySize);
                SendToServerInternal(ckey1, true);

                skey1 = ReceiveFromServerInternal(TeraEncryptionSession.KeySize);
                SendToClientInternal(skey1, true);

                ckey2 = ReceiveFromClientInternal(TeraEncryptionSession.KeySize);
                SendToServerInternal(ckey2, true);

                skey2 = ReceiveFromServerInternal(TeraEncryptionSession.KeySize);
                SendToClientInternal(skey2, true);
            }
            catch (SocketDisconnectedException)
            {
                // Normal disconnection.
                Disconnect();
                return;
            }
            catch (Exception e) when(IsSocketException(e))
            {
                // The client is already disconnected.
                return;
            }

            _clientEncryption = new TeraEncryptionSession(
                Direction.ClientToServer, ckey1, ckey2, skey1, skey2);
            _serverEncryption = new TeraEncryptionSession(
                Direction.ServerToClient, ckey1, ckey2, skey1, skey2);

            _log.Info("Established encrypted session for client {0}", EndPoint);

            Receive(Direction.ClientToServer, null, null);
            Receive(Direction.ServerToClient, null, null);
        }