feat: initial commit - server and client
This commit is contained in:
commit
1ef186c46c
23 changed files with 677 additions and 0 deletions
43
.gitignore
vendored
Normal file
43
.gitignore
vendored
Normal file
|
@ -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
|
14
GServer.Client/GServer.Client.csproj
Normal file
14
GServer.Client/GServer.Client.csproj
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\GServer.Common\GServer.Common.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
25
GServer.Client/GServer.Client.sln
Normal file
25
GServer.Client/GServer.Client.sln
Normal file
|
@ -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
|
78
GServer.Client/Program.cs
Normal file
78
GServer.Client/Program.cs
Normal file
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
16
GServer.Common/.editorconfig
Normal file
16
GServer.Common/.editorconfig
Normal file
|
@ -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
|
11
GServer.Common/Extensions/StringExtensions.cs
Normal file
11
GServer.Common/Extensions/StringExtensions.cs
Normal file
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
13
GServer.Common/GServer.Common.csproj
Normal file
13
GServer.Common/GServer.Common.csproj
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Enums/" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
25
GServer.Common/GServer.Common.sln
Normal file
25
GServer.Common/GServer.Common.sln
Normal file
|
@ -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
|
11
GServer.Common/Game/Entities/ServerListing.cs
Normal file
11
GServer.Common/Game/Entities/ServerListing.cs
Normal file
|
@ -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; }
|
||||||
|
}
|
7
GServer.Common/Game/Enums/ServerTier.cs
Normal file
7
GServer.Common/Game/Enums/ServerTier.cs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
namespace GServer.Common;
|
||||||
|
|
||||||
|
public enum ServerTier : byte
|
||||||
|
{
|
||||||
|
Default = 0,
|
||||||
|
Listed = 1
|
||||||
|
}
|
57
GServer.Common/Networking/Core/MessageMemoryStream.cs
Normal file
57
GServer.Common/Networking/Core/MessageMemoryStream.cs
Normal file
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
13
GServer.Common/Networking/Enums/ClientPacketIn.cs
Normal file
13
GServer.Common/Networking/Enums/ClientPacketIn.cs
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
namespace GServer.Common.Networking.Enums
|
||||||
|
{
|
||||||
|
public enum ClientPacketIn : byte
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents an auth result from the server.
|
||||||
|
/// Format: {1(success) | 2(error)}{error msg length}{error msg}
|
||||||
|
/// </summary>
|
||||||
|
AUTH_RESPONSE = 1,
|
||||||
|
|
||||||
|
UNKNOWN = 255
|
||||||
|
}
|
||||||
|
}
|
7
GServer.Common/Networking/Enums/ServerPacketIn.cs
Normal file
7
GServer.Common/Networking/Enums/ServerPacketIn.cs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
namespace GServer.Common.Networking.Enums
|
||||||
|
{
|
||||||
|
public enum ServerPacketIn : byte
|
||||||
|
{
|
||||||
|
AUTH = 1
|
||||||
|
}
|
||||||
|
}
|
11
GServer.Common/Networking/Messages/BaseMessage.cs
Normal file
11
GServer.Common/Networking/Messages/BaseMessage.cs
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
namespace GServer.Common.Networking.Messages;
|
||||||
|
|
||||||
|
public abstract class BaseMessage
|
||||||
|
{
|
||||||
|
protected readonly byte PacketId;
|
||||||
|
|
||||||
|
public BaseMessage(byte packetId)
|
||||||
|
{
|
||||||
|
PacketId = packetId;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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<AuthResponseMessage>
|
||||||
|
{
|
||||||
|
public bool IsSuccessful { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Used to authenticate the user. Only set if IsSuccessful is true.
|
||||||
|
/// </summary>
|
||||||
|
public string? SessionToken { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reason for auth failure. Only set is IsSuccessful is false.
|
||||||
|
/// </summary>
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
6
GServer.Common/Networking/Messages/IMessage.cs
Normal file
6
GServer.Common/Networking/Messages/IMessage.cs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
namespace GServer.Common.Networking.Messages;
|
||||||
|
|
||||||
|
public interface IMessage<T>
|
||||||
|
{
|
||||||
|
byte[] Serialize();
|
||||||
|
}
|
55
GServer.Common/Networking/Messages/Server/AuthMessage.cs
Normal file
55
GServer.Common/Networking/Messages/Server/AuthMessage.cs
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
using System.Text;
|
||||||
|
using GServer.Common.Networking.Enums;
|
||||||
|
|
||||||
|
namespace GServer.Common.Networking.Messages.Server;
|
||||||
|
|
||||||
|
public class AuthMessage : BaseMessage, IMessage<AuthMessage>
|
||||||
|
{
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
14
GServer.Server/GServer.Server.csproj
Normal file
14
GServer.Server/GServer.Server.csproj
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\GServer.Common\GServer.Common.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
25
GServer.Server/GServer.Server.sln
Normal file
25
GServer.Server/GServer.Server.sln
Normal file
|
@ -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
|
39
GServer.Server/GServer.cs
Normal file
39
GServer.Server/GServer.cs
Normal file
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
79
GServer.Server/Program.cs
Normal file
79
GServer.Server/Program.cs
Normal file
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
25
GServer.Server/Services/ServerListService.cs
Normal file
25
GServer.Server/Services/ServerListService.cs
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
using GServer.Common.Game.Entities;
|
||||||
|
|
||||||
|
namespace GServer.Server.Services
|
||||||
|
{
|
||||||
|
public class ServerListService
|
||||||
|
{
|
||||||
|
public ServerListService()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<ServerListing> List()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
new ServerListing
|
||||||
|
{
|
||||||
|
Name = "Smallville",
|
||||||
|
Description = "A tiny development server!",
|
||||||
|
IPAddress = "localhost",
|
||||||
|
Port = 11001,
|
||||||
|
Playercount = 1,
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
34
GServer.sln
Normal file
34
GServer.sln
Normal file
|
@ -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
|
Loading…
Add table
Reference in a new issue