using System.Net; using System.Net.Sockets; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using Tiger.Networking.Game.Sessions; using System.Text; using HabboEncoding; using Tiger.Communication.Messages; using Tiger.Communication.Messages.Outgoing.Handshake; using Tiger.Communication.Messages.Types; using Tiger.Utils; namespace Tiger.Networking.Game; public sealed class GameTcpServer : TcpServer { private readonly IGameSessionManager _gameSessionManager; private readonly ILogger _logger; private readonly IMessageHandler _messageHandler; public GameTcpServer(IGameSessionManager gameSessionManager, IConfiguration configuration, ILogger logger, IMessageHandler messageHandler) : base(configuration["Network:Game:Ip"] ?? "0.0.0.0", int.TryParse(configuration["Network:Game:Port"], out var port) ? port : 30000) { _gameSessionManager = gameSessionManager; _logger = logger; _messageHandler = messageHandler; } protected override async Task ConnectionCallbackAsync(TcpClient client) { var gameSession = _gameSessionManager.AddSession(client); var buffer = new byte[1024]; _logger.LogInformation("Client {Id} connected ({EndPoint}", gameSession.SessionId, gameSession.Client.Client.RemoteEndPoint); await gameSession.SendComposerAsync(new HelloComposer()); while (true) { var bytesRead = await gameSession.Stream.ReadAsync(buffer); if (bytesRead == 0) break; var actualBytes = ByteUtils.CopyArray(buffer, 0, bytesRead); if (gameSession.Rc4 != null) { actualBytes = gameSession.Rc4.Decipher(actualBytes); } var readerIndex = 0; while (actualBytes.Length - readerIndex >= 5) { var length = Base64Encoding.DecodeInt32(ByteUtils.CopyArray(actualBytes, readerIndex, 3)); var packet = ByteUtils.CopyArray(actualBytes, readerIndex + 3, length); await _messageHandler.TryHandleAsync(gameSession, new ClientMessage(packet)); readerIndex += 3 + length; } } await _gameSessionManager.CloseAsync(gameSession); _logger.LogInformation("Client {Id} disconnected ({EndPoint}", gameSession.SessionId, gameSession.Client.Client.RemoteEndPoint); } public override void Start() { base.Start(); _logger.LogInformation("Started Game Tcp Server on {EndPoint}", Server.LocalEndpoint); } }