diff --git a/Common/Utils/Logger.cs b/Common/Utils/Logger.cs index 0249da2..4394f52 100644 --- a/Common/Utils/Logger.cs +++ b/Common/Utils/Logger.cs @@ -49,10 +49,28 @@ Console.Write(_name); Console.ResetColor(); Console.Write("> "); - Console.BackgroundColor = ConsoleColor.Cyan; + Console.ForegroundColor = ConsoleColor.White; Console.BackgroundColor = ConsoleColor.DarkRed; Console.WriteLine(string.Join("\t", message)); Console.ResetColor(); } + + public void Debug(params string[] message) + { +#if DEBUG + Console.ForegroundColor = ConsoleColor.White; + Console.Write(DateTime.Now.ToString("HH:mm:ss ")); + Console.ResetColor(); + Console.Write("<"); + Console.ForegroundColor = ConsoleColor.Cyan; + Console.Write(_name); + Console.ResetColor(); + Console.Write("> "); + Console.ForegroundColor = ConsoleColor.White; + Console.BackgroundColor = ConsoleColor.DarkMagenta; + Console.WriteLine(string.Join("\t", message)); + Console.ResetColor(); +#endif + } } } diff --git a/Gameserver/Server.cs b/Gameserver/Server.cs index c96771e..e07bafc 100644 --- a/Gameserver/Server.cs +++ b/Gameserver/Server.cs @@ -8,27 +8,50 @@ namespace PemukulPaku.Gameserver public class Server { public static readonly Logger c = new("TCP", ConsoleColor.Blue); + public readonly Dictionary Sessions = new(); + private static Server? Instance; - public static void Start() + public static Server GetInstance() { + return Instance ??= new Server(); + } + + public Server() + { + Task.Run(Start); + } + + public void Start() { TcpListener Listener = new(IPAddress.Parse("0.0.0.0"), (int)Global.config.Gameserver.Port); - try + while(true) { - Listener.Start(); - c.Log($"TCP server started on port {Global.config.Gameserver.Port}"); - - while (true) + try { - TcpClient Client = Listener.AcceptTcpClient(); - c.Warn($"{Client.Client.RemoteEndPoint} connected!"); - NetworkStream stream = Client.GetStream(); + Listener.Start(); + c.Log($"TCP server started on port {Global.config.Gameserver.Port}"); + + while (true) + { + TcpClient Client = Listener.AcceptTcpClient(); + string Id = Client.Client.RemoteEndPoint!.ToString()!; + + c.Warn($"{Id} connected"); + Sessions.Add(Id, new Session(Id, Client)); + LogClients(); + } + } + catch (Exception ex) + { + c.Error("TCP server error: " + ex.Message); + Thread.Sleep(3000); } } - catch (Exception ex) - { - c.Error("TCP server error: " + ex.Message); - } + } + + public void LogClients() + { + c.Log($"Connected clients: {Sessions.Count}"); } } } diff --git a/Gameserver/Session.cs b/Gameserver/Session.cs new file mode 100644 index 0000000..3634db9 --- /dev/null +++ b/Gameserver/Session.cs @@ -0,0 +1,101 @@ +using System.Net.Sockets; +using Common.Utils; + +namespace PemukulPaku.Gameserver +{ + public class Session + { + public readonly string Id; + public readonly TcpClient Client; + public readonly Logger c; + + public Session(string id, TcpClient client) + { + Id = id; + Client = client; + c = new Logger(Id); + Task.Run(() => ClientLoop(client)); + } + + private void ClientLoop(TcpClient client) + { + NetworkStream stream = client.GetStream(); + + byte[] packetMagic = { 0x01, 0x23, 0x45, 0x67 }; // Magic start pattern + byte[] packetEnd = { 0x89, 0xAB, 0xCD, 0xEF }; // Magic end pattern + + byte[] buffer = new byte[4096]; + int bytesRead; + + try + { + while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0) + { + // Process the received bytes + for (int i = 0; i < bytesRead; i++) + { + if (buffer[i] == packetMagic[0]) + { + bool found = true; + for (int j = 1; j < packetMagic.Length; j++) + { + if (buffer[i + j] != packetMagic[j]) + { + found = false; + break; + } + } + + if (found) + { + // Magic start pattern found + int endIndex = Array.IndexOf(buffer, packetEnd[0], i + packetMagic.Length); + if (endIndex != -1) + { + // Magic end pattern found + int packetLength = endIndex - i + packetEnd.Length; + byte[] packet = new byte[packetLength]; + Array.Copy(buffer, i, packet, 0, packetLength); + + // Process the packet + ProcessPacket(packet); + + // Update the buffer + int remainingBytes = bytesRead - (i + packetLength); + Array.Copy(buffer, i + packetLength, buffer, 0, remainingBytes); + + // Adjust the bytesRead value accordingly + bytesRead = remainingBytes; + i = -1; // Start processing from the beginning of the buffer again + } + else + { + // End pattern not found, break the loop and wait for more data + break; + } + } + } + } + } + } + catch (Exception ex) + { + if (Client != null) + { + c.Warn($"{Id} disconnected"); + Server.GetInstance().Sessions.Remove(Id); + } + else + { + c.Error("TCP client error: " + ex.Message); + } + } + finally { Server.GetInstance().LogClients(); }; + } + + public void ProcessPacket(byte[] packet) + { + c.Debug("Received packet: " + BitConverter.ToString(packet).Replace("-", "")); + } + } +} diff --git a/HttpServer/Program.cs b/HttpServer/Program.cs index c5c3e1e..36e6ae3 100644 --- a/HttpServer/Program.cs +++ b/HttpServer/Program.cs @@ -49,7 +49,7 @@ namespace HttpServer if ((int)Global.config.VerboseLevel > (int)VerboseLevel.Normal) { c.Log($"{context.Response.StatusCode} {context.Request.Method.ToUpper()} {context.Request.Path}"); - }else if(((int)Global.config.VerboseLevel > (int)VerboseLevel.Silent) && (Array.IndexOf(SurpressedRoutes, context.Request.Path.ToString()) == -1)) + }else if(((int)Global.config.VerboseLevel > (int)VerboseLevel.Silent) && !SurpressedRoutes.Contains(context.Request.Path.ToString())) { c.Log($"{context.Response.StatusCode} {context.Request.Method.ToUpper()} {context.Request.Path}"); } diff --git a/Program.cs b/Program.cs index 85b17fc..4f8e185 100644 --- a/Program.cs +++ b/Program.cs @@ -19,9 +19,9 @@ namespace PemukulPaku }; new Thread(HttpServer.Program.Main).Start(); - new Thread(Server.Start).Start(); + _ = Server.GetInstance(); - Console.ReadKey(true); + Console.Read(); } } } \ No newline at end of file diff --git a/Properties/launchSettings.json b/Properties/launchSettings.json new file mode 100644 index 0000000..833dd4c --- /dev/null +++ b/Properties/launchSettings.json @@ -0,0 +1,11 @@ +{ + "profiles": { + "PemukulPaku": { + "commandName": "Project" + }, + "WSL": { + "commandName": "WSL2", + "distributionName": "" + } + } +} \ No newline at end of file