GameServer + packet types, we aren't parsing yet

This commit is contained in:
rfi
2023-10-08 21:12:01 +07:00
parent f753a0ffc4
commit 0eacd1bfe2
10 changed files with 306 additions and 5 deletions

View File

@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MessagePack" Version="2.5.129" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AscNet.Common\AscNet.Common.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,76 @@
using MessagePack;
namespace AscNet.GameServer
{
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
[MessagePackObject(false)]
public class Packet
{
[Key(0)]
public int No;
[Key(1)]
public ContentType Type;
[Key(2)]
public byte[] Content;
public enum ContentType
{
Request,
Response,
Push,
Exception
}
[MessagePackObject(false)]
public class Request
{
[Key(0)]
public int Id;
[Key(1)]
public string Name;
[Key(2)]
public byte[] Content;
}
[MessagePackObject(false)]
public class Response
{
[Key(0)]
public int Id;
[Key(1)]
public string Name;
[Key(2)]
public byte[] Content;
}
[MessagePackObject(false)]
public class Push
{
[Key(0)]
public string Name;
[Key(1)]
public byte[] Content;
}
[MessagePackObject(false)]
public class Exception
{
[Key(0)]
public int Id;
[Key(1)]
public int Code;
[Key(2)]
public string Message;
}
}
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
}

View File

@@ -0,0 +1,54 @@
using System.Net.Sockets;
using System.Net;
using AscNet.Common.Util;
namespace AscNet.GameServer
{
public class Server
{
public static readonly Logger c = new(nameof(GameServer), ConsoleColor.Cyan);
public readonly Dictionary<string, Session> Sessions = new();
private static Server? _instance;
private readonly TcpListener listener;
public static Server Instance
{
get
{
return _instance ??= new Server();
}
}
public Server()
{
listener = new(IPAddress.Parse("0.0.0.0"), Common.Common.config.GameServer.Port);
}
public void Start()
{
for (; ; )
{
try
{
listener.Start();
c.Log($"{nameof(GameServer)} started and listening on port {Common.Common.config.GameServer.Port}");
for (; ; )
{
TcpClient tcpClient = listener.AcceptTcpClient();
string id = tcpClient.Client.RemoteEndPoint!.ToString()!;
c.Warn($"{id} connected");
Sessions.Add(id, new Session(id, tcpClient));
}
}
catch (Exception ex)
{
c.Error("TCP listener error: " + ex.Message);
c.Log("Waiting 3 seconds before restarting...");
Thread.Sleep(3000);
}
}
}
}
}

View File

@@ -0,0 +1,65 @@
using System.Net.Sockets;
using AscNet.Common.Util;
namespace AscNet.GameServer
{
public class Session
{
public readonly string id;
public readonly TcpClient client;
public readonly Logger c;
private long lastPacketTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
// private ushort packetNo = 0;
public Session(string id, TcpClient tcpClient)
{
this.id = id;
client = tcpClient;
c = new(id, ConsoleColor.DarkGray);
Task.Run(ClientLoop);
}
public async void ClientLoop()
{
NetworkStream stream = client.GetStream();
byte[] msg = new byte[1 << 16];
while (client.Connected)
{
try
{
Array.Clear(msg, 0, msg.Length);
int len = stream.Read(msg, 0, msg.Length);
if (len > 0)
{
lastPacketTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
}
}
catch (Exception)
{
break;
}
await Task.Delay(10);
// 10 sec timeout
if (DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() - lastPacketTime > 10000)
break;
}
DisconnectProtocol();
}
public void DisconnectProtocol()
{
if (Server.Instance.Sessions.GetValueOrDefault(id) is null)
return;
c.Warn($"{id} disconnected");
client.Close();
Server.Instance.Sessions.Remove(id);
}
}
}