more temporary handlers

This commit is contained in:
rfi
2024-02-19 06:18:44 +07:00
parent 11382f9d20
commit d2552b74b7
6 changed files with 165 additions and 16 deletions

View File

@@ -26,7 +26,7 @@ namespace BLHX.Server.Common.Utils
Console.Write(_name);
Console.ResetColor();
Console.Write("> ");
Console.WriteLine(string.Join("\t", message));
Console.Write(string.Join("\t", message.Append(Environment.NewLine)));
Console.ResetColor();
}
@@ -40,14 +40,14 @@ namespace BLHX.Server.Common.Utils
Console.Write(_name);
Console.ResetColor();
Console.Write("> ");
Console.WriteLine(string.Join("\t", message));
Console.Write(string.Join("\t", message.Append(Environment.NewLine)));
Console.ResetColor();
}
public void Trail(params string[] msg)
{
Console.ForegroundColor = ConsoleColor.DarkGray;
Console.WriteLine($"\t└── {string.Join(' ', msg)}");
Console.Write($"\t└── {string.Join(' ', msg)}\n");
Console.ResetColor();
}
@@ -64,7 +64,7 @@ namespace BLHX.Server.Common.Utils
Console.ForegroundColor = ConsoleColor.White;
if (TraceOnError)
Console.BackgroundColor = ConsoleColor.DarkRed;
Console.WriteLine(string.Join("\t", message));
Console.Write(string.Join("\t", message.Append(Environment.NewLine)));
Console.ResetColor();
#if DEBUG
StackTrace trace = new(true);
@@ -86,7 +86,7 @@ namespace BLHX.Server.Common.Utils
Console.Write("> ");
Console.ForegroundColor = ConsoleColor.White;
Console.BackgroundColor = ConsoleColor.DarkMagenta;
Console.WriteLine(string.Join("\t", message));
Console.Write(string.Join("\t", message.Append(Environment.NewLine)));
Console.ResetColor();
Console.BackgroundColor = ConsoleColor.Black;

View File

@@ -5,14 +5,16 @@ using ProtoBuf;
using System.Buffers.Binary;
using System.Net;
using System.Net.Sockets;
using System.Security.AccessControl;
using System.Text;
using System.Text.Json;
namespace BLHX.Server.Game
{
public class Connection
{
public readonly Logger c;
readonly TcpClient tcpClient;
readonly Logger c;
readonly CancellationTokenSource cts = new();
readonly Task loopTask;
ushort packetIdx = 0;
@@ -32,6 +34,7 @@ namespace BLHX.Server.Game
{
var ns = tcpClient.GetStream();
var buf = GC.AllocateUninitializedArray<byte>(ushort.MaxValue);
// TODO: pos isn't actually doing anything
var pos = 0;
while (!cts.Token.IsCancellationRequested)
@@ -47,32 +50,51 @@ namespace BLHX.Server.Game
int readLen = 0;
while (readLen < len)
{
if (buf.AsSpan(0, 22).SequenceEqual(Encoding.UTF8.GetBytes("GET /?cmd=load_server?")))
{
string svrList = @"[{""id"":1,""name"":""BLHX.Server"",""state"":0,""flag"":0,""sort"":0}]";
SendHttpResponse(svrList, "application/json");
readLen = len;
cts.Cancel();
break;
}
if (len - readLen < Packet.HEADER_SIZE + Packet.LENGTH_SIZE)
break;
var packet = new Packet(buf[readLen..]);
if (packet.command == Command.Cs10800)
{
var dec = packet.Decode<Cs10800>();
c.Debug(JsonSerializer.Serialize(dec, jsonSerializerOptions));
}
c.Log(packet.command.ToString());
var handler = PacketFactory.GetPacketHandler(packet.command);
if (handler is not null)
handler(this, packet);
else
c.Warn($"{packet.command} unhandled!"
#if DEBUG
, Enum.IsDefined(packet.command) ? BitConverter.ToString(packet.bytes).Replace("-", "") : BitConverter.ToString(buf[readLen..]).Replace("-", "")
#endif
);
readLen += packet.length + Packet.LENGTH_SIZE;
}
pos += len - readLen;
if (pos > 0)
Array.Copy(buf, readLen, buf, 0, pos);
if (len == readLen)
pos = 0;
}
catch (Exception ex)
{
c.Error($"An error occured while reading packets {ex}");
break;
}
}
EndProtocol();
}
public void Send<T>(T packet) where T : IExtensible
{
Command command = Enum.Parse<Command>(packet.GetType().Name);
c.Log(command.ToString());
var ns = tcpClient.GetStream();
using var ms = new MemoryStream();
@@ -85,10 +107,21 @@ namespace BLHX.Server.Game
BinaryPrimitives.WriteUInt16BigEndian(sendBuf.AsSpan(Packet.HEADER_SIZE), NextPacketIdx);
ms.ToArray().CopyTo(sendBuf.AsSpan(Packet.LENGTH_SIZE + Packet.HEADER_SIZE));
c.Debug(BitConverter.ToString(sendBuf).Replace("-", ""));
// c.Debug(BitConverter.ToString(sendBuf).Replace("-", ""));
ns.Write(sendBuf);
}
public void SendHttpResponse(string rsp, string type = "text/plain")
{
tcpClient.GetStream().Write(Encoding.UTF8.GetBytes(
"HTTP/1.1 200 OK" + Environment.NewLine
+ "Content-Length: " + rsp.Length + Environment.NewLine
+ "Content-Type: " + type + Environment.NewLine
+ Environment.NewLine
+ rsp
+ Environment.NewLine + Environment.NewLine));
}
public void EndProtocol()
{
cts.Cancel();

View File

@@ -13,6 +13,9 @@ namespace BLHX.Server.Game
static GameServer()
{
// Preload
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(typeof(PacketFactory).TypeHandle);
EndPoint = new(IPAddress.Any, 20000);
listener = new TcpListener(EndPoint);
}

View File

@@ -0,0 +1,72 @@
using BHXY.Server.Common.Proto.p10;
using BLHX.Server.Common.Proto;
namespace BLHX.Server.Game.Handlers
{
internal static class P10
{
[PacketHandler(Command.Cs10800)]
static void Cs10800Handler(Connection connection, Packet packet)
{
var req = packet.Decode<Cs10800>();
connection.Send(new Sc10801()
{
GatewayIp = "192.168.1.4",
GatewayPort = 20000,
Url = "http://192.168.1.4",
ProxyIp = "192.168.1.4",
ProxyPort = 20000,
Versions = [
"$azhash$7$1$459$470aa097fec844d6",
"$cvhash$467$98edcdd4e7dac668",
"$l2dhash$514$b59cdb747b1c64c9",
"$pichash$15$0d6f59289972cc8a",
"$bgmhash$13$76fdc897426a138d",
"$paintinghash$82$6daa07fa50583c60",
"$mangahash$24$3cefad85368b3296",
"$cipherhash$24$3cefad85368b3296",
"dTag-1"
],
Timestamp = (uint)DateTimeOffset.Now.ToUnixTimeSeconds(),
Monday0oclockTimestamp = 1606114800
});
}
[PacketHandler(Command.Cs10020)]
static void Cs10020Handler(Connection connection, Packet packet)
{
// Arg2 uid
// Arg3 accessToken
// CheckKey md5(Arg1 + salt)
var req = packet.Decode<Cs10020>();
connection.Send(new Sc10021()
{
Result = 0,
AccountId = 1,
Serverlists = [
new Serverinfo()
{
Ids = [0],
Name = "BLHX.Server",
Ip = "192.168.1.4",
Port = 20000,
ProxyIp = "192.168.1.4",
ProxyPort = 20000
}
],
ServerTicket = req.Arg3
});
}
[PacketHandler(Command.Cs10022)]
static void Cs10022Handler(Connection connection, Packet packet)
{
var req = packet.Decode<Cs10022>();
connection.Send(new Sc10023()
{
Result = 0,
UserId = 1
});
}
}
}

View File

@@ -1,6 +1,8 @@
using BLHX.Server.Common.Proto;
using BLHX.Server.Common.Utils;
using ProtoBuf;
using System.Buffers.Binary;
using System.Reflection;
namespace BLHX.Server.Game
{
@@ -26,4 +28,43 @@ namespace BLHX.Server.Game
public T Decode<T>() where T : IExtensible => Serializer.Deserialize<T>(bytes.AsSpan());
}
static class PacketFactory
{
static readonly Logger c = new(nameof(PacketFactory), ConsoleColor.DarkGreen);
static readonly Dictionary<Command, PacketHandlerDelegate> handlers = [];
static PacketFactory()
{
LoadPacketHandlers();
}
private static void LoadPacketHandlers()
{
foreach (var method in Assembly.GetExecutingAssembly().GetTypes().SelectMany(x => x.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).Where(x => x.GetCustomAttribute<PacketHandlerAttribute>() is not null)))
{
var attr = method.GetCustomAttribute<PacketHandlerAttribute>()!;
if (handlers.ContainsKey(attr.command))
continue;
handlers.Add(attr.command, (PacketHandlerDelegate)Delegate.CreateDelegate(typeof(PacketHandlerDelegate), method));
c.Log($"Loaded {method.Name} for {attr.command}");
}
c.Log($"{handlers.Count} packet handlers loaded!");
}
public static PacketHandlerDelegate? GetPacketHandler(Command command)
{
handlers.TryGetValue(command, out var handler);
return handler;
}
}
delegate void PacketHandlerDelegate(Connection connection, Packet packet);
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
class PacketHandlerAttribute(Command command) : Attribute
{
public Command command = command;
}
}