// Copyright (c) 2023 Timothy Schenk. Subject to the GNU AGPL Version 3 License. using System.Net.Sockets; using System.Reflection; using Continuity.AuthServer.Packets; using MassTransit.Mediator; using Microsoft.Extensions.Logging; using NetCoreServer; using Wonderking.Packets; namespace Continuity.AuthServer; public class AuthSession : TcpSession { private readonly ILogger _logger; private readonly IMediator _mediator; public AuthSession(TcpServer server, IMediator mediator, ILogger logger) : base(server) { _mediator = mediator; _logger = logger; } public Guid AccountId { get; set; } public override long Send(byte[] buffer) { _logger.LogInformation("Data being sent is: {Data}", BitConverter.ToString(buffer)); return base.Send(buffer); } public Task SendAsync(IPacket packet) { var type = packet.GetType(); _logger.LogInformation("Packet of type {Type} is being serialized", type.Name); var packetIdAttribute = type.GetCustomAttribute(); if (packetIdAttribute == null) { return Task.CompletedTask; } var opcode = packetIdAttribute.Code; Span packetData = packet.Serialize(); var length = (ushort)(packetData.Length + 8); Span buffer = stackalloc byte[length]; buffer.Clear(); packetData.CopyTo(buffer[8..length]); var bytesOfLength = BitConverter.GetBytes(length); var bytesOfOpcode = BitConverter.GetBytes((ushort)opcode); for (var i = 0; i < bytesOfLength.Length || i < 2; i++) { buffer[i] = bytesOfLength[i]; } for (var i = 0; i < bytesOfOpcode.Length || i < 2; i++) { buffer[2 + i] = bytesOfOpcode[i]; } _logger.LogInformation("Packet data being parsed is: {Data}", BitConverter.ToString(packetData.ToArray())); _logger.LogInformation("Packet being parsed is: {Data}", BitConverter.ToString(buffer.ToArray())); SendAsync(buffer); return Task.CompletedTask; } protected override void OnReceived(byte[] buffer, long offset, long size) { _logger.LogDebug("Length: {Size} & offset: {Offset}", size, offset); Span decryptedBuffer = stackalloc byte[(int)size]; // xor every value after the first 8 bytes var dataBuffer = Decrypt(buffer.AsSpan(8, (int)size - 8)); _logger.LogDebug("Length {Length}", BitConverter.ToUInt16(buffer, 0)); var opCode = BitConverter.ToUInt16(buffer.ToArray(), 2); _logger.LogDebug("Packet Op Code: {OpCode}", opCode); _logger.LogDebug("Some Value: {RandomValue}", buffer[4]); var clientAliveTime = BitConverter.ToUInt16(buffer.ToArray(), 5); _logger.LogDebug("Client Alive time: {ClientAliveTime}", clientAliveTime); _logger.LogDebug("Might be a flag: {Flag}", buffer[7]); _logger.LogDebug("Full buffer: {Buffer}", BitConverter.ToString(dataBuffer.ToArray())); var rawPacket = new RawPacket((OperationCode)opCode, dataBuffer, clientAliveTime, buffer[7], buffer[4], Id, this); _ = _mediator.Send(rawPacket); _logger.LogInformation("Connection from: {@RemoteEndpoint}", Socket.RemoteEndPoint?.ToString()); base.OnReceived(decryptedBuffer.ToArray(), offset, decryptedBuffer.Length); } private static Span Decrypt(Span buffer) { for (var i = 0; i < buffer.Length; ++i) { buffer[i] = (byte)(buffer[i] ^ i ^ (3 * (0xFE - i))); } return buffer; } protected override void OnError(SocketError error) { _logger.LogWarning("An error has occured: {Error}", error); } }