From 1ef186c46c64c3075fec96ce5a61cd5529feba23 Mon Sep 17 00:00:00 2001 From: Aaron Yarborough Date: Sun, 19 May 2024 22:13:48 +0100 Subject: [PATCH] feat: initial commit - server and client --- .gitignore | 43 ++++++++++ GServer.Client/GServer.Client.csproj | 14 ++++ GServer.Client/GServer.Client.sln | 25 ++++++ GServer.Client/Program.cs | 78 ++++++++++++++++++ GServer.Common/.editorconfig | 16 ++++ GServer.Common/Extensions/StringExtensions.cs | 11 +++ GServer.Common/GServer.Common.csproj | 13 +++ GServer.Common/GServer.Common.sln | 25 ++++++ GServer.Common/Game/Entities/ServerListing.cs | 11 +++ GServer.Common/Game/Enums/ServerTier.cs | 7 ++ .../Networking/Core/MessageMemoryStream.cs | 57 +++++++++++++ .../Networking/Enums/ClientPacketIn.cs | 13 +++ .../Networking/Enums/ServerPacketIn.cs | 7 ++ .../Networking/Messages/BaseMessage.cs | 11 +++ .../Messages/Client/AuthResponseMessage.cs | 69 ++++++++++++++++ .../Networking/Messages/IMessage.cs | 6 ++ .../Networking/Messages/Server/AuthMessage.cs | 55 +++++++++++++ GServer.Server/GServer.Server.csproj | 14 ++++ GServer.Server/GServer.Server.sln | 25 ++++++ GServer.Server/GServer.cs | 39 +++++++++ GServer.Server/Program.cs | 79 +++++++++++++++++++ GServer.Server/Services/ServerListService.cs | 25 ++++++ GServer.sln | 34 ++++++++ 23 files changed, 677 insertions(+) create mode 100644 .gitignore create mode 100644 GServer.Client/GServer.Client.csproj create mode 100644 GServer.Client/GServer.Client.sln create mode 100644 GServer.Client/Program.cs create mode 100644 GServer.Common/.editorconfig create mode 100644 GServer.Common/Extensions/StringExtensions.cs create mode 100644 GServer.Common/GServer.Common.csproj create mode 100644 GServer.Common/GServer.Common.sln create mode 100644 GServer.Common/Game/Entities/ServerListing.cs create mode 100644 GServer.Common/Game/Enums/ServerTier.cs create mode 100644 GServer.Common/Networking/Core/MessageMemoryStream.cs create mode 100644 GServer.Common/Networking/Enums/ClientPacketIn.cs create mode 100644 GServer.Common/Networking/Enums/ServerPacketIn.cs create mode 100644 GServer.Common/Networking/Messages/BaseMessage.cs create mode 100644 GServer.Common/Networking/Messages/Client/AuthResponseMessage.cs create mode 100644 GServer.Common/Networking/Messages/IMessage.cs create mode 100644 GServer.Common/Networking/Messages/Server/AuthMessage.cs create mode 100644 GServer.Server/GServer.Server.csproj create mode 100644 GServer.Server/GServer.Server.sln create mode 100644 GServer.Server/GServer.cs create mode 100644 GServer.Server/Program.cs create mode 100644 GServer.Server/Services/ServerListService.cs create mode 100644 GServer.sln diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bfca666 --- /dev/null +++ b/.gitignore @@ -0,0 +1,43 @@ +*.swp +*.*~ +project.lock.json +.DS_Store +*.pyc +nupkg/ + +# Visual Studio Code +.vscode/ + +# Rider +.idea/ + +# Visual Studio +.vs/ + +# Fleet +.fleet/ + +# Code Rush +.cr/ + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +build/ +bld/ +[Bb]in/ +[Oo]bj/ +[Oo]ut/ +msbuild.log +msbuild.err +msbuild.wrn diff --git a/GServer.Client/GServer.Client.csproj b/GServer.Client/GServer.Client.csproj new file mode 100644 index 0000000..8de6103 --- /dev/null +++ b/GServer.Client/GServer.Client.csproj @@ -0,0 +1,14 @@ + + + + + + + + Exe + net8.0 + enable + enable + + + diff --git a/GServer.Client/GServer.Client.sln b/GServer.Client/GServer.Client.sln new file mode 100644 index 0000000..bb1cbec --- /dev/null +++ b/GServer.Client/GServer.Client.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.5.002.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GServer.Client", "GServer.Client.csproj", "{ED3BEE9D-85F6-44FB-95EC-750D42901E38}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {ED3BEE9D-85F6-44FB-95EC-750D42901E38}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {ED3BEE9D-85F6-44FB-95EC-750D42901E38}.Debug|Any CPU.Build.0 = Debug|Any CPU + {ED3BEE9D-85F6-44FB-95EC-750D42901E38}.Release|Any CPU.ActiveCfg = Release|Any CPU + {ED3BEE9D-85F6-44FB-95EC-750D42901E38}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {038F1EC1-6953-46F4-AD0E-D7AD5B0D93FB} + EndGlobalSection +EndGlobal diff --git a/GServer.Client/Program.cs b/GServer.Client/Program.cs new file mode 100644 index 0000000..29b9f2c --- /dev/null +++ b/GServer.Client/Program.cs @@ -0,0 +1,78 @@ +using System.Net; +using System.Net.Sockets; +using GServer.Common; +using GServer.Common.Networking.Enums; +using GServer.Common.Networking.Messages.Server; + +internal class Program +{ + private const int SERVER_PORT = 11000; + + private static void Main(string[] args) + { + // var sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); + + var serverEP = new IPEndPoint(IPAddress.Any, SERVER_PORT); + + UdpClient udpClient = new(); + udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); + udpClient.Connect(serverEP); + + + // byte[] username = "helloworld123".ToUTF8String(); + // byte[] password = "password&(*$())".ToUTF8String(); + + // byte[] sendBuffer = [(byte)ServerPacketIn.AUTH, (byte)username.Length, .. username, (byte)password.Length, .. password]; + + Console.WriteLine("Username..."); + string username = Console.ReadLine()!; + + Console.WriteLine("Password..."); + string password = Console.ReadLine()!; + + AuthMessage authMessage = new(username, password); + udpClient.Send(authMessage.Serialize()); + + try + { + while (true) + { + byte[] bytes = udpClient.Receive(ref serverEP); + + MessageMemoryStream stream = new(bytes); + + ClientPacketIn packetIn = (ClientPacketIn)stream.ReadByte(); + switch (packetIn) + { + case ClientPacketIn.AUTH_RESPONSE: + var authResultMessage = new AuthResponseMessage(stream); + + Console.WriteLine("Success = " + authResultMessage.IsSuccessful); + + Console.WriteLine("SessionToken = " + authResultMessage.SessionToken ?? "null"); + + + Console.WriteLine("FailureReason = " + authResultMessage.FailureReason ?? "null"); + + break; + + default: + Console.WriteLine($"Received unsupported packet."); + // byte[] response = [(byte)ClientPacketIn.UNKNOWN]; + // listener.Send(response); + break; + } + } + } + catch (Exception ex) + { + Console.WriteLine(ex); + } + finally + { + udpClient.Close(); + } + + + } +} \ No newline at end of file diff --git a/GServer.Common/.editorconfig b/GServer.Common/.editorconfig new file mode 100644 index 0000000..35ee465 --- /dev/null +++ b/GServer.Common/.editorconfig @@ -0,0 +1,16 @@ +[*.cs] + +# Default severity for all analyzer diagnostics +dotnet_analyzer_diagnostic.severity = warning + +# IDE0290: Use primary constructor +csharp_style_prefer_primary_constructors = false + +# Default severity for analyzer diagnostics with category 'Naming' +dotnet_analyzer_diagnostic.category-Naming.severity = none + +# IDE0160: Convert to block scoped namespace +csharp_style_namespace_declarations = file_scoped + +# CA1051: Do not declare visible instance fields +dotnet_diagnostic.CA1051.severity = none diff --git a/GServer.Common/Extensions/StringExtensions.cs b/GServer.Common/Extensions/StringExtensions.cs new file mode 100644 index 0000000..60f35fe --- /dev/null +++ b/GServer.Common/Extensions/StringExtensions.cs @@ -0,0 +1,11 @@ +using System.Text; + +namespace GServer.Common; + +public static class StringExtensions +{ + public static byte[] GetASCIIBytes(this string value) + { + return Encoding.ASCII.GetBytes(value); + } +} diff --git a/GServer.Common/GServer.Common.csproj b/GServer.Common/GServer.Common.csproj new file mode 100644 index 0000000..dbf1cfd --- /dev/null +++ b/GServer.Common/GServer.Common.csproj @@ -0,0 +1,13 @@ + + + + net8.0 + enable + enable + + + + + + + diff --git a/GServer.Common/GServer.Common.sln b/GServer.Common/GServer.Common.sln new file mode 100644 index 0000000..38cce46 --- /dev/null +++ b/GServer.Common/GServer.Common.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.5.002.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GServer.Common", "GServer.Common.csproj", "{3FD4F40B-AF21-432D-BE62-FBC84909615A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3FD4F40B-AF21-432D-BE62-FBC84909615A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3FD4F40B-AF21-432D-BE62-FBC84909615A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3FD4F40B-AF21-432D-BE62-FBC84909615A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3FD4F40B-AF21-432D-BE62-FBC84909615A}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {9244EF2A-AE82-44F6-B8A2-93FF81FBA16A} + EndGlobalSection +EndGlobal diff --git a/GServer.Common/Game/Entities/ServerListing.cs b/GServer.Common/Game/Entities/ServerListing.cs new file mode 100644 index 0000000..cbd982e --- /dev/null +++ b/GServer.Common/Game/Entities/ServerListing.cs @@ -0,0 +1,11 @@ +namespace GServer.Common.Game.Entities; + +public record ServerListing +{ + public required string Name { get; set; } + public required string Description { get; set; } + public ushort Playercount { get; set; } + public required string IPAddress { get; set; } + public ushort Port { get; set; } + public ServerTier ServerTier { get; set; } +} diff --git a/GServer.Common/Game/Enums/ServerTier.cs b/GServer.Common/Game/Enums/ServerTier.cs new file mode 100644 index 0000000..1f1d809 --- /dev/null +++ b/GServer.Common/Game/Enums/ServerTier.cs @@ -0,0 +1,7 @@ +namespace GServer.Common; + +public enum ServerTier : byte +{ + Default = 0, + Listed = 1 +} diff --git a/GServer.Common/Networking/Core/MessageMemoryStream.cs b/GServer.Common/Networking/Core/MessageMemoryStream.cs new file mode 100644 index 0000000..b2ea9b8 --- /dev/null +++ b/GServer.Common/Networking/Core/MessageMemoryStream.cs @@ -0,0 +1,57 @@ +using System.Text; + +namespace GServer.Common; + +public class MessageMemoryStream : MemoryStream +{ + public MessageMemoryStream() + { + } + + public MessageMemoryStream(byte[] buffer) : base(buffer) + { + } + + public bool ReadBoolean() + { + return ReadByte() == 1; + } + + public ushort ReadUInt16() + { + byte[] buffer = new byte[2]; + _ = Read(buffer, 0, 2); + return BitConverter.ToUInt16(buffer); + } + + public short ReadInt16() + { + byte[] buffer = new byte[2]; + _ = Read(buffer, 0, 2); + return BitConverter.ToInt16(buffer); + } + + public string ReadUTF8String(int length) + { + byte[] bytes = new byte[length]; + _ = Read(bytes, 0, length); + return Encoding.UTF8.GetString(bytes); + } + + public void WriteBoolean(bool value) + { + WriteByte((byte)(value ? 1 : 0)); + } + + public void WriteUInt16(short value) + { + byte[] bytes = BitConverter.GetBytes(value); + Write(bytes, 0, 2); + } + + public void WriteUTF8String(string value) + { + byte[] bytes = Encoding.UTF8.GetBytes(value); + Write(bytes, 0, bytes.Length); + } +} diff --git a/GServer.Common/Networking/Enums/ClientPacketIn.cs b/GServer.Common/Networking/Enums/ClientPacketIn.cs new file mode 100644 index 0000000..c665ccf --- /dev/null +++ b/GServer.Common/Networking/Enums/ClientPacketIn.cs @@ -0,0 +1,13 @@ +namespace GServer.Common.Networking.Enums +{ + public enum ClientPacketIn : byte + { + /// + /// Represents an auth result from the server. + /// Format: {1(success) | 2(error)}{error msg length}{error msg} + /// + AUTH_RESPONSE = 1, + + UNKNOWN = 255 + } +} \ No newline at end of file diff --git a/GServer.Common/Networking/Enums/ServerPacketIn.cs b/GServer.Common/Networking/Enums/ServerPacketIn.cs new file mode 100644 index 0000000..29fa6ab --- /dev/null +++ b/GServer.Common/Networking/Enums/ServerPacketIn.cs @@ -0,0 +1,7 @@ +namespace GServer.Common.Networking.Enums +{ + public enum ServerPacketIn : byte + { + AUTH = 1 + } +} \ No newline at end of file diff --git a/GServer.Common/Networking/Messages/BaseMessage.cs b/GServer.Common/Networking/Messages/BaseMessage.cs new file mode 100644 index 0000000..7289d45 --- /dev/null +++ b/GServer.Common/Networking/Messages/BaseMessage.cs @@ -0,0 +1,11 @@ +namespace GServer.Common.Networking.Messages; + +public abstract class BaseMessage +{ + protected readonly byte PacketId; + + public BaseMessage(byte packetId) + { + PacketId = packetId; + } +} \ No newline at end of file diff --git a/GServer.Common/Networking/Messages/Client/AuthResponseMessage.cs b/GServer.Common/Networking/Messages/Client/AuthResponseMessage.cs new file mode 100644 index 0000000..e39f44a --- /dev/null +++ b/GServer.Common/Networking/Messages/Client/AuthResponseMessage.cs @@ -0,0 +1,69 @@ +using System.Text; +using GServer.Common.Networking.Enums; +using GServer.Common.Networking.Messages; + +namespace GServer.Common; + +public enum AuthResponseFailure : byte +{ + IncorrectLoginOrPassword, + Unknown +} + +public class AuthResponseMessage : BaseMessage, IMessage +{ + public bool IsSuccessful { get; private set; } + + /// + /// Used to authenticate the user. Only set if IsSuccessful is true. + /// + public string? SessionToken { get; private set; } + + /// + /// Reason for auth failure. Only set is IsSuccessful is false. + /// + public AuthResponseFailure? FailureReason { get; private set; } + + public AuthResponseMessage(bool isSuccessful, string? sessionToken = null, AuthResponseFailure? failureReason = null) : base((byte)ClientPacketIn.AUTH_RESPONSE) + { + IsSuccessful = isSuccessful; + SessionToken = sessionToken; + FailureReason = failureReason; + } + + public AuthResponseMessage(MessageMemoryStream stream) : base((byte)ClientPacketIn.AUTH_RESPONSE) + { + IsSuccessful = stream.ReadBoolean(); + + if (IsSuccessful) + { + ushort sessionTokenLen = stream.ReadUInt16(); + SessionToken = stream.ReadUTF8String(sessionTokenLen); + } + else + { + FailureReason = (AuthResponseFailure)stream.ReadByte(); + } + } + + public byte[] Serialize() + { + using MessageMemoryStream stream = new(); + + stream.WriteByte(PacketId); + stream.WriteBoolean(IsSuccessful); + + if (IsSuccessful) + { + short sessionTokenByteLen = (short)Encoding.UTF8.GetByteCount(SessionToken!); + stream.WriteUInt16(sessionTokenByteLen); + stream.WriteUTF8String(SessionToken!); + } + else + { + stream.WriteByte((byte)FailureReason!); + } + + return stream.ToArray(); + } +} diff --git a/GServer.Common/Networking/Messages/IMessage.cs b/GServer.Common/Networking/Messages/IMessage.cs new file mode 100644 index 0000000..746ccbd --- /dev/null +++ b/GServer.Common/Networking/Messages/IMessage.cs @@ -0,0 +1,6 @@ +namespace GServer.Common.Networking.Messages; + +public interface IMessage +{ + byte[] Serialize(); +} \ No newline at end of file diff --git a/GServer.Common/Networking/Messages/Server/AuthMessage.cs b/GServer.Common/Networking/Messages/Server/AuthMessage.cs new file mode 100644 index 0000000..76f9fa7 --- /dev/null +++ b/GServer.Common/Networking/Messages/Server/AuthMessage.cs @@ -0,0 +1,55 @@ +using System.Text; +using GServer.Common.Networking.Enums; + +namespace GServer.Common.Networking.Messages.Server; + +public class AuthMessage : BaseMessage, IMessage +{ + public string Username { get; private set; } + public string Password { get; private set; } + + public AuthMessage(string username, string password) : base((byte)ServerPacketIn.AUTH) + { + Username = username; + Password = password; + } + + public AuthMessage(MessageMemoryStream stream) : base((byte)ServerPacketIn.AUTH) + { + // byte usernameLength = (byte)stream.ReadByte(); + // byte[] usernameBytes = new byte[usernameLength]; + // _ = stream.Read(usernameBytes, 0, usernameLength); + // string username = Encoding.UTF8.GetString(usernameBytes); + + // byte passwordLength = (byte)stream.ReadByte(); + // byte[] passwordBytes = new byte[passwordLength]; + // _ = stream.Read(passwordBytes, 0, passwordLength); + // string password = Encoding.UTF8.GetString(passwordBytes); + + byte usernameLen = (byte)stream.ReadByte(); + string username = stream.ReadUTF8String(usernameLen); + + byte passwordLen = (byte)stream.ReadByte(); + string password = stream.ReadUTF8String(passwordLen); + + Username = username; + Password = password; + } + + public byte[] Serialize() + { + using MemoryStream stream = new(); + + stream.WriteByte(PacketId); + + byte[] usernameBytes = Encoding.UTF8.GetBytes(Username); + stream.WriteByte((byte)usernameBytes.Length); + stream.Write(usernameBytes, 0, usernameBytes.Length); + + byte[] passwordBytes = Encoding.UTF8.GetBytes(Password); + stream.WriteByte((byte)passwordBytes.Length); + stream.Write(passwordBytes, 0, passwordBytes.Length); + + return stream.ToArray(); + } +} \ No newline at end of file diff --git a/GServer.Server/GServer.Server.csproj b/GServer.Server/GServer.Server.csproj new file mode 100644 index 0000000..8de6103 --- /dev/null +++ b/GServer.Server/GServer.Server.csproj @@ -0,0 +1,14 @@ + + + + + + + + Exe + net8.0 + enable + enable + + + diff --git a/GServer.Server/GServer.Server.sln b/GServer.Server/GServer.Server.sln new file mode 100644 index 0000000..141bde9 --- /dev/null +++ b/GServer.Server/GServer.Server.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.5.002.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GServer.Server", "GServer.Server.csproj", "{F1459667-32BD-4657-9898-C6F5124E9135}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F1459667-32BD-4657-9898-C6F5124E9135}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F1459667-32BD-4657-9898-C6F5124E9135}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F1459667-32BD-4657-9898-C6F5124E9135}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F1459667-32BD-4657-9898-C6F5124E9135}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {E3CECC00-FAA1-4FD8-A35C-FCFFEDB6E8F0} + EndGlobalSection +EndGlobal diff --git a/GServer.Server/GServer.cs b/GServer.Server/GServer.cs new file mode 100644 index 0000000..b3ce03a --- /dev/null +++ b/GServer.Server/GServer.cs @@ -0,0 +1,39 @@ +using System.Net; +using System.Net.Sockets; +using GServer.Server.Services; + +namespace GServer.Server +{ + public class GServer : IDisposable + { + public readonly UdpClient UdpClient; + private IPEndPoint _ipEndpoint; + + private readonly ServerListService _serverListService; + + public GServer(UdpClient udpClient, IPEndPoint ipEndPoint) + { + UdpClient = udpClient; + _ipEndpoint = ipEndPoint; + + UdpClient.Client.SetSocketOption( + SocketOptionLevel.Socket, + SocketOptionName.ReuseAddress, + true); + + _serverListService = new ServerListService(); + } + + public void Bind() + { + UdpClient.Client.Bind(_ipEndpoint); + Console.WriteLine("Now listening on " + UdpClient.Client.LocalEndPoint); + } + + public void Dispose() + { + UdpClient.Close(); + UdpClient.Dispose(); + } + } +} \ No newline at end of file diff --git a/GServer.Server/Program.cs b/GServer.Server/Program.cs new file mode 100644 index 0000000..b1d440d --- /dev/null +++ b/GServer.Server/Program.cs @@ -0,0 +1,79 @@ +using System.Net; +using System.Net.Sockets; +using System.Text; +using GServer.Common; +using GServer.Common.Networking.Enums; +using GServer.Common.Networking.Messages.Server; + +internal class Program +{ + private const int LISTEN_PORT = 11000; + + private static void Main(string[] args) + { + + GServer.Server.GServer server = new( + new UdpClient(), + new IPEndPoint(IPAddress.Any, LISTEN_PORT)); + + server.Bind(); + + try + { + IPEndPoint remoteEP = new(IPAddress.Any, 0); + + while (true) + { + Console.WriteLine("Waiting for message..."); + + byte[] bytes = server.UdpClient.Receive(ref remoteEP); + string ASCIIContent = Encoding.ASCII.GetString(bytes, 0, bytes.Length); + + Console.WriteLine("Received from: " + remoteEP); + Console.WriteLine($"Length = {bytes.Length}, Content = {ASCIIContent}"); + + var stream = new MessageMemoryStream(bytes); + + ServerPacketIn serverPacketIn = (ServerPacketIn)stream.ReadByte(); + + switch (serverPacketIn) + { + case ServerPacketIn.AUTH: + var msg = new AuthMessage(stream); + + Console.WriteLine($"Username = {msg.Username}, Length = {msg.Username.Length}"); + + Console.WriteLine($"Password = {msg.Password}, Length = {msg.Password.Length}"); + + AuthResponseMessage resp; + + if (msg.Username == "aaronyarbz" && msg.Password == "password123") + { + resp = new(true, Guid.NewGuid().ToString(), null); + } + else + { + resp = new(false, null, AuthResponseFailure.IncorrectLoginOrPassword); + } + + server.UdpClient.Send(resp.Serialize(), remoteEP); + + break; + + default: + Console.WriteLine($"Received unsupported packet."); + break; + } + } + } + catch (Exception ex) + { + Console.WriteLine(ex); + } + finally + { + Console.WriteLine("Disposing of server..."); + server.Dispose(); + } + } +} \ No newline at end of file diff --git a/GServer.Server/Services/ServerListService.cs b/GServer.Server/Services/ServerListService.cs new file mode 100644 index 0000000..4c7fbc0 --- /dev/null +++ b/GServer.Server/Services/ServerListService.cs @@ -0,0 +1,25 @@ +using GServer.Common.Game.Entities; + +namespace GServer.Server.Services +{ + public class ServerListService + { + public ServerListService() + { + } + + public IEnumerable List() + { + return [ + new ServerListing + { + Name = "Smallville", + Description = "A tiny development server!", + IPAddress = "localhost", + Port = 11001, + Playercount = 1, + } + ]; + } + } +} \ No newline at end of file diff --git a/GServer.sln b/GServer.sln new file mode 100644 index 0000000..e6bac6a --- /dev/null +++ b/GServer.sln @@ -0,0 +1,34 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31903.59 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GServer.Common", "GServer.Common\GServer.Common.csproj", "{14D7D62B-C48B-4F6B-83F4-0CAFA8A7D6D4}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GServer.Server", "GServer.Server\GServer.Server.csproj", "{E54AFEDB-9561-4E54-B702-9A2E1C5EFBBF}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GServer.Client", "GServer.Client\GServer.Client.csproj", "{C105363D-E719-4296-94A2-01170E603889}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {14D7D62B-C48B-4F6B-83F4-0CAFA8A7D6D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {14D7D62B-C48B-4F6B-83F4-0CAFA8A7D6D4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {14D7D62B-C48B-4F6B-83F4-0CAFA8A7D6D4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {14D7D62B-C48B-4F6B-83F4-0CAFA8A7D6D4}.Release|Any CPU.Build.0 = Release|Any CPU + {E54AFEDB-9561-4E54-B702-9A2E1C5EFBBF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E54AFEDB-9561-4E54-B702-9A2E1C5EFBBF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E54AFEDB-9561-4E54-B702-9A2E1C5EFBBF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E54AFEDB-9561-4E54-B702-9A2E1C5EFBBF}.Release|Any CPU.Build.0 = Release|Any CPU + {C105363D-E719-4296-94A2-01170E603889}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C105363D-E719-4296-94A2-01170E603889}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C105363D-E719-4296-94A2-01170E603889}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C105363D-E719-4296-94A2-01170E603889}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal