mirror of
https://git.lewd.wtf/PGR/ascnet
synced 2026-02-04 12:35:05 +01:00
GameServer + packet types, we aren't parsing yet
This commit is contained in:
17
AscNet.GameServer/AscNet.GameServer.csproj
Normal file
17
AscNet.GameServer/AscNet.GameServer.csproj
Normal 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>
|
||||
76
AscNet.GameServer/Packet.cs
Normal file
76
AscNet.GameServer/Packet.cs
Normal 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.
|
||||
}
|
||||
54
AscNet.GameServer/Server.cs
Normal file
54
AscNet.GameServer/Server.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
65
AscNet.GameServer/Session.cs
Normal file
65
AscNet.GameServer/Session.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user