diff --git a/BLHX.Server.Common/BLHX.Server.Common.csproj b/BLHX.Server.Common/BLHX.Server.Common.csproj new file mode 100644 index 0000000..fa71b7a --- /dev/null +++ b/BLHX.Server.Common/BLHX.Server.Common.csproj @@ -0,0 +1,9 @@ + + + + net8.0 + enable + enable + + + diff --git a/BLHX.Server.Common/Utils/Logger.cs b/BLHX.Server.Common/Utils/Logger.cs new file mode 100644 index 0000000..b659e8c --- /dev/null +++ b/BLHX.Server.Common/Utils/Logger.cs @@ -0,0 +1,99 @@ +using System.Diagnostics; + +namespace BLHX.Server.Common.Utils +{ + public class Logger + { + public static readonly Logger c = new("BLHX.Server", ConsoleColor.Blue); + private readonly string _name; + private readonly bool TraceOnError; + private readonly ConsoleColor _color; + + public Logger(string name, ConsoleColor color = ConsoleColor.Cyan, bool traceOnError = true) + { + _name = name; + _color = color; + TraceOnError = traceOnError; + } + + public void Log(params string[] message) + { + Console.ForegroundColor = ConsoleColor.White; + Console.Write(DateTime.Now.ToString("HH:mm:ss ")); + Console.ResetColor(); + Console.Write("<"); + Console.ForegroundColor = _color; + Console.Write(_name); + Console.ResetColor(); + Console.Write("> "); + Console.WriteLine(string.Join("\t", message)); + Console.ResetColor(); + } + + public void Warn(params string[] message) + { + Console.ForegroundColor = ConsoleColor.White; + Console.Write(DateTime.Now.ToString("HH:mm:ss ")); + Console.ResetColor(); + Console.Write("<"); + Console.ForegroundColor = ConsoleColor.Yellow; + Console.Write(_name); + Console.ResetColor(); + Console.Write("> "); + Console.WriteLine(string.Join("\t", message)); + Console.ResetColor(); + } + + public void Trail(params string[] msg) + { + Console.ForegroundColor = ConsoleColor.DarkGray; + Console.WriteLine($"\t└── {string.Join(' ', msg)}"); + Console.ResetColor(); + } + + public void Error(params string[] message) + { + Console.ForegroundColor = ConsoleColor.White; + Console.Write(DateTime.Now.ToString("HH:mm:ss ")); + Console.ResetColor(); + Console.Write("<"); + Console.ForegroundColor = ConsoleColor.Red; + Console.Write(_name); + Console.ResetColor(); + Console.Write("> "); + Console.ForegroundColor = ConsoleColor.White; + if (TraceOnError) + Console.BackgroundColor = ConsoleColor.DarkRed; + Console.WriteLine(string.Join("\t", message)); + Console.ResetColor(); +#if DEBUG + StackTrace trace = new(true); + if (TraceOnError) + Trail(trace.ToString()); +#endif + } + + 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(); + Console.BackgroundColor = ConsoleColor.Black; + + StackTrace trace = new(true); + if (TraceOnError) + Trail(trace.ToString()); +#endif + } + } +} diff --git a/BLHX.Server.Game/BLHX.Server.Game.csproj b/BLHX.Server.Game/BLHX.Server.Game.csproj new file mode 100644 index 0000000..0342417 --- /dev/null +++ b/BLHX.Server.Game/BLHX.Server.Game.csproj @@ -0,0 +1,13 @@ + + + + net8.0 + enable + enable + + + + + + + diff --git a/BLHX.Server.Game/Connection.cs b/BLHX.Server.Game/Connection.cs new file mode 100644 index 0000000..1402a78 --- /dev/null +++ b/BLHX.Server.Game/Connection.cs @@ -0,0 +1,49 @@ +using BLHX.Server.Common.Utils; +using System.Net; +using System.Net.Sockets; + +namespace BLHX.Server.Game +{ + public class Connection + { + readonly TcpClient tcpClient; + readonly Logger c; + readonly CancellationTokenSource cts = new(); + readonly Task loopTask; + public IPEndPoint EndPoint => (IPEndPoint)tcpClient.Client.RemoteEndPoint!; + + public Connection(TcpClient tcpClient) + { + this.tcpClient = tcpClient; + c = new(EndPoint.ToString()); + loopTask = Task.Run(ClientLoop, cts.Token); + } + + private async Task ClientLoop() + { + var ns = tcpClient.GetStream(); + var buf = GC.AllocateUninitializedArray(8 << 13); + var pos = 0; + + while (!cts.Token.IsCancellationRequested) + { + await Task.Delay(1); + int len = ns.Read(buf, pos, buf.Length - pos); + len += pos; + if (len == 0) + continue; + + c.Debug(BitConverter.ToString(buf[..len]).Replace("-", "")); + } + } + + public void EndProtocol() + { + cts.Cancel(); + loopTask.Wait(); + loopTask.Dispose(); + + tcpClient.Dispose(); + } + } +} diff --git a/BLHX.Server.Game/GameServer.cs b/BLHX.Server.Game/GameServer.cs new file mode 100644 index 0000000..1d4927c --- /dev/null +++ b/BLHX.Server.Game/GameServer.cs @@ -0,0 +1,47 @@ +using System.Net; +using System.Net.Sockets; +using BLHX.Server.Common.Utils; + +namespace BLHX.Server.Game +{ + public static class GameServer + { + static readonly TcpListener listener; + public static readonly Dictionary connections = new(); + public static readonly Logger c = new(nameof(GameServer), ConsoleColor.Magenta); + public static IPEndPoint EndPoint { get; } + + static GameServer() + { + EndPoint = new(IPAddress.Any, 20000); + listener = new TcpListener(EndPoint); + } + + public static async Task Start() + { + listener.Start(); + c.Log($"{nameof(GameServer)} started on {EndPoint}"); + + while (true) + { + try + { + TcpClient client = await listener.AcceptTcpClientAsync(); + if (client.Client.RemoteEndPoint is not null and IPEndPoint) + { + if (connections.ContainsKey((IPEndPoint)client.Client.RemoteEndPoint)) + connections[(IPEndPoint)client.Client.RemoteEndPoint].EndProtocol(); + + connections[(IPEndPoint)client.Client.RemoteEndPoint] = new Connection(client); + continue; + } + client.Dispose(); + } + catch (Exception ex) + { + c.Error($"{nameof(GameServer)} listener error {ex}"); + } + } + } + } +} diff --git a/BLHX.Server.sln b/BLHX.Server.sln new file mode 100644 index 0000000..bd867ba --- /dev/null +++ b/BLHX.Server.sln @@ -0,0 +1,37 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.8.34309.116 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLHX.Server", "BLHX.Server\BLHX.Server.csproj", "{C67D2B44-EFF0-4325-9C90-9D8BA4799E02}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLHX.Server.Game", "BLHX.Server.Game\BLHX.Server.Game.csproj", "{33059688-36C1-43D1-BEE6-3A5C5C7DA4E6}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLHX.Server.Common", "BLHX.Server.Common\BLHX.Server.Common.csproj", "{BA896C61-5025-4CBB-B56C-18A59D3D0D7D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {C67D2B44-EFF0-4325-9C90-9D8BA4799E02}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C67D2B44-EFF0-4325-9C90-9D8BA4799E02}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C67D2B44-EFF0-4325-9C90-9D8BA4799E02}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C67D2B44-EFF0-4325-9C90-9D8BA4799E02}.Release|Any CPU.Build.0 = Release|Any CPU + {33059688-36C1-43D1-BEE6-3A5C5C7DA4E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {33059688-36C1-43D1-BEE6-3A5C5C7DA4E6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {33059688-36C1-43D1-BEE6-3A5C5C7DA4E6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {33059688-36C1-43D1-BEE6-3A5C5C7DA4E6}.Release|Any CPU.Build.0 = Release|Any CPU + {BA896C61-5025-4CBB-B56C-18A59D3D0D7D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BA896C61-5025-4CBB-B56C-18A59D3D0D7D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BA896C61-5025-4CBB-B56C-18A59D3D0D7D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BA896C61-5025-4CBB-B56C-18A59D3D0D7D}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {23C7FC14-F3E9-4AA5-8FE0-0E08FF97E4BA} + EndGlobalSection +EndGlobal diff --git a/BLHX.Server/BLHX.Server.csproj b/BLHX.Server/BLHX.Server.csproj new file mode 100644 index 0000000..623e668 --- /dev/null +++ b/BLHX.Server/BLHX.Server.csproj @@ -0,0 +1,16 @@ + + + + Exe + net8.0 + enable + enable + true + true + + + + + + + diff --git a/BLHX.Server/Program.cs b/BLHX.Server/Program.cs new file mode 100644 index 0000000..eda4102 --- /dev/null +++ b/BLHX.Server/Program.cs @@ -0,0 +1,14 @@ +using BLHX.Server.Common.Utils; +using BLHX.Server.Game; + +namespace BLHX.Server +{ + internal class Program + { + static void Main() + { + Logger.c.Log("Starting..."); + Task.Run(GameServer.Start).Wait(); + } + } +}