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); } } }
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)); }
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); } }); }
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); })); }
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)); } }
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); }