forked from PGR/ascnet
working tcp (kinda), send still brokey
This commit is contained in:
parent
0eacd1bfe2
commit
8c53541d7f
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Config.Net" Version="5.1.5" />
|
<PackageReference Include="Config.Net" Version="5.1.5" />
|
||||||
|
<PackageReference Include="MessagePack" Version="2.5.129" />
|
||||||
<PackageReference Include="MongoDB.Driver" Version="2.21.0" />
|
<PackageReference Include="MongoDB.Driver" Version="2.21.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,22 @@
|
||||||
|
using AscNet.Common.MsgPack;
|
||||||
|
using MessagePack;
|
||||||
|
|
||||||
|
namespace AscNet.GameServer.Handlers
|
||||||
|
{
|
||||||
|
internal class AccountModule
|
||||||
|
{
|
||||||
|
[PacketHandler("HandshakeRequest")]
|
||||||
|
public static void HandshakeRequestHandler(Session session, byte[] packet)
|
||||||
|
{
|
||||||
|
HandshakeRequest request = MessagePackSerializer.Deserialize<HandshakeRequest>(packet);
|
||||||
|
HandshakeResponse response = new()
|
||||||
|
{
|
||||||
|
Code = 0,
|
||||||
|
UtcOpenTime = 0,
|
||||||
|
Sha1Table = null
|
||||||
|
};
|
||||||
|
|
||||||
|
session.SendResponse(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,6 @@
|
||||||
using MessagePack;
|
using System.Reflection;
|
||||||
|
using AscNet.Common.Util;
|
||||||
|
using MessagePack;
|
||||||
|
|
||||||
namespace AscNet.GameServer
|
namespace AscNet.GameServer
|
||||||
{
|
{
|
||||||
|
@ -73,4 +75,49 @@ namespace AscNet.GameServer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
|
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
|
||||||
|
|
||||||
|
[AttributeUsage(AttributeTargets.Method)]
|
||||||
|
public class PacketHandler : Attribute
|
||||||
|
{
|
||||||
|
public string Name { get; }
|
||||||
|
|
||||||
|
public PacketHandler(string name)
|
||||||
|
{
|
||||||
|
Name = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public delegate void PacketHandlerDelegate(Session session, byte[] packet);
|
||||||
|
|
||||||
|
public static class PacketFactory
|
||||||
|
{
|
||||||
|
public static readonly Dictionary<string, PacketHandlerDelegate> Handlers = new();
|
||||||
|
static readonly Logger c = new("Factory", ConsoleColor.Yellow);
|
||||||
|
|
||||||
|
public static void LoadPacketHandlers()
|
||||||
|
{
|
||||||
|
c.Log("Loading Packet Handlers...");
|
||||||
|
|
||||||
|
IEnumerable<Type> classes = from t in Assembly.GetExecutingAssembly().GetTypes()
|
||||||
|
select t;
|
||||||
|
|
||||||
|
foreach (var method in classes.SelectMany(t => t.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)))
|
||||||
|
{
|
||||||
|
var attr = method.GetCustomAttribute<PacketHandler>(false);
|
||||||
|
if (attr == null || Handlers.ContainsKey(attr.Name)) continue;
|
||||||
|
Handlers.Add(attr.Name, (PacketHandlerDelegate)Delegate.CreateDelegate(typeof(PacketHandlerDelegate), method));
|
||||||
|
#if DEBUG
|
||||||
|
c.Log($"Loaded {method.Name}");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Log("Finished Loading Packet Handlers");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PacketHandlerDelegate? GetPacketHandler(string name)
|
||||||
|
{
|
||||||
|
Handlers.TryGetValue(name, out PacketHandlerDelegate? handler);
|
||||||
|
return handler;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
using System.Net.Sockets;
|
using System.Buffers.Binary;
|
||||||
|
using System.Net.Mail;
|
||||||
|
using System.Net.Sockets;
|
||||||
using AscNet.Common.Util;
|
using AscNet.Common.Util;
|
||||||
|
using MessagePack;
|
||||||
|
|
||||||
namespace AscNet.GameServer
|
namespace AscNet.GameServer
|
||||||
{
|
{
|
||||||
|
@ -9,7 +12,8 @@ namespace AscNet.GameServer
|
||||||
public readonly TcpClient client;
|
public readonly TcpClient client;
|
||||||
public readonly Logger c;
|
public readonly Logger c;
|
||||||
private long lastPacketTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
private long lastPacketTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||||||
// private ushort packetNo = 0;
|
private ushort packetNo = 0;
|
||||||
|
private readonly MessagePackSerializerOptions lz4Options = MessagePackSerializerOptions.Standard.WithCompression(MessagePackCompression.Lz4Block);
|
||||||
|
|
||||||
public Session(string id, TcpClient tcpClient)
|
public Session(string id, TcpClient tcpClient)
|
||||||
{
|
{
|
||||||
|
@ -35,7 +39,55 @@ namespace AscNet.GameServer
|
||||||
if (len > 0)
|
if (len > 0)
|
||||||
{
|
{
|
||||||
lastPacketTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
lastPacketTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||||||
|
List<Packet> packets = new();
|
||||||
|
|
||||||
|
int readbytes = 0;
|
||||||
|
while (readbytes < len)
|
||||||
|
{
|
||||||
|
int packetLen = BinaryPrimitives.ReadInt32LittleEndian(msg.AsSpan()[readbytes..]);
|
||||||
|
readbytes += 4;
|
||||||
|
if (packetLen < 4)
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
byte[] packet = GC.AllocateUninitializedArray<byte>(packetLen);
|
||||||
|
Array.Copy(msg, readbytes, packet, 0, packetLen);
|
||||||
|
readbytes += packetLen;
|
||||||
|
Crypto.HaruCrypt.Decrypt(packet);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
packets.Add(MessagePackSerializer.Deserialize<Packet>(packet, lz4Options));
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
c.Error("Failed to deserialize packet: " + BitConverter.ToString(packet).Replace("-", ""));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var packet in packets)
|
||||||
|
{
|
||||||
|
switch (packet.Type)
|
||||||
|
{
|
||||||
|
case Packet.ContentType.Request:
|
||||||
|
Packet.Request request = MessagePackSerializer.Deserialize<Packet.Request>(packet.Content);
|
||||||
|
c.Log(request.Name);
|
||||||
|
PacketFactory.GetPacketHandler(request.Name)?.Invoke(this, request.Content);
|
||||||
|
break;
|
||||||
|
case Packet.ContentType.Push:
|
||||||
|
Packet.Push push = MessagePackSerializer.Deserialize<Packet.Push>(packet.Content);
|
||||||
|
c.Log(push.Name);
|
||||||
|
PacketFactory.GetPacketHandler(push.Name)?.Invoke(this, push.Content);
|
||||||
|
break;
|
||||||
|
case Packet.ContentType.Exception:
|
||||||
|
Packet.Exception exception = MessagePackSerializer.Deserialize<Packet.Exception>(packet.Content);
|
||||||
|
c.Error($"Exception packet received: {exception.Code}, {exception.Message}");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -52,6 +104,55 @@ namespace AscNet.GameServer
|
||||||
DisconnectProtocol();
|
DisconnectProtocol();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SendPush<T>(T push)
|
||||||
|
{
|
||||||
|
Packet.Push packet = new()
|
||||||
|
{
|
||||||
|
Name = typeof(T).Name,
|
||||||
|
Content = MessagePackSerializer.Serialize(push)
|
||||||
|
};
|
||||||
|
|
||||||
|
Send(new Packet()
|
||||||
|
{
|
||||||
|
No = packetNo,
|
||||||
|
Type = Packet.ContentType.Push,
|
||||||
|
Content = MessagePackSerializer.Serialize(packet)
|
||||||
|
});
|
||||||
|
c.Log(packet.Name);
|
||||||
|
packetNo++;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SendResponse<T>(T response)
|
||||||
|
{
|
||||||
|
Packet.Response packet = new()
|
||||||
|
{
|
||||||
|
Id = 0,
|
||||||
|
Name = typeof(T).Name,
|
||||||
|
Content = MessagePackSerializer.Serialize(response)
|
||||||
|
};
|
||||||
|
|
||||||
|
Send(new Packet()
|
||||||
|
{
|
||||||
|
No = packetNo,
|
||||||
|
Type = Packet.ContentType.Response,
|
||||||
|
Content = MessagePackSerializer.Serialize(packet)
|
||||||
|
});
|
||||||
|
c.Log(packet.Name);
|
||||||
|
packetNo++;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Send(Packet packet)
|
||||||
|
{
|
||||||
|
byte[] serializedPacket = MessagePackSerializer.Serialize(packet, lz4Options);
|
||||||
|
byte[] sendBytes = GC.AllocateUninitializedArray<byte>(serializedPacket.Length + 4);
|
||||||
|
|
||||||
|
BinaryPrimitives.WriteInt32LittleEndian(sendBytes, serializedPacket.Length);
|
||||||
|
Array.Copy(serializedPacket, 0, sendBytes, 4, serializedPacket.Length);
|
||||||
|
|
||||||
|
Crypto.HaruCrypt.Encrypt(sendBytes);
|
||||||
|
client.GetStream().Write(sendBytes);
|
||||||
|
}
|
||||||
|
|
||||||
public void DisconnectProtocol()
|
public void DisconnectProtocol()
|
||||||
{
|
{
|
||||||
if (Server.Instance.Sessions.GetValueOrDefault(id) is null)
|
if (Server.Instance.Sessions.GetValueOrDefault(id) is null)
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\AscNet.Common\AscNet.Common.csproj" />
|
||||||
<ProjectReference Include="..\AscNet.GameServer\AscNet.GameServer.csproj" />
|
<ProjectReference Include="..\AscNet.GameServer\AscNet.GameServer.csproj" />
|
||||||
<ProjectReference Include="..\AscNet.SDKServer\AscNet.SDKServer.csproj" />
|
<ProjectReference Include="..\AscNet.SDKServer\AscNet.SDKServer.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue