0
0
Fork 0
mirror of https://github.com/Sanae6/SmoOnlineServer.git synced 2024-11-21 18:55:17 +00:00

Catch up with crafty's current protocol

This commit is contained in:
Sanae 2022-02-08 10:15:31 -06:00
parent de16e4a787
commit aa119c0b2f
12 changed files with 100 additions and 51 deletions

View file

@ -151,16 +151,15 @@ public class Server {
Logger.Info($"Client {socket.RemoteEndPoint} disconnected from the server");
} else {
Logger.Error($"Exception on socket {socket.RemoteEndPoint}, disconnecting for: {e}");
await socket.DisconnectAsync(false);
Task.Run(() => socket.DisconnectAsync(false));
}
memory?.Dispose();
}
Clients.Remove(client);
Broadcast(new DisconnectPacket(), client).ContinueWith(_ => {
client.Dispose();
});
client.Dispose();
Task.Run(() => Broadcast(new DisconnectPacket(), client));
}
private static PacketHeader GetHeader(Span<byte> data) {

View file

@ -9,6 +9,7 @@ public static class Constants {
public const int MaxPacketSize = 256;
public const int MaxClients = 4;
public static int HeaderSize { get; } = Marshal.SizeOf<PacketHeader>();
public const int CostumeNameSize = 0x20;
// dictionary of packet types to packet
public static readonly Dictionary<Type, PacketAttribute> Packets = Assembly

View file

@ -8,4 +8,12 @@ public static class Extensions {
}
public static string Hex(this IEnumerable<byte> array) => string.Join(' ', array.ToArray().Select(x => x.ToString("X2")));
public static unsafe byte* Ptr(this Span<byte> span) {
fixed (byte* data = span) return data;
}
public static string TrimNullTerm(this string text) {
return text.Split('\0').FirstOrDefault() ?? "";
}
}

View file

@ -0,0 +1,23 @@
using System.Numerics;
using System.Runtime.InteropServices;
using System.Text;
namespace Shared.Packet.Packets;
public class CapPacket : IPacket {
public const int NameSize = 0x30;
public Vector3 Position;
public Quaternion Rotation;
public string CapAnim;
public void Serialize(Span<byte> data) {
MemoryMarshal.Write(data, ref Position);
MemoryMarshal.Write(data[12..], ref Position);
Encoding.UTF8.GetBytes(CapAnim).CopyTo(data[28..]);
}
public void Deserialize(Span<byte> data) {
Position = MemoryMarshal.Read<Vector3>(data);
Rotation = MemoryMarshal.Read<Quaternion>(data[12..]);
CapAnim = Encoding.UTF8.GetString(data[28..]).TrimEnd('\0');
}
}

View file

@ -0,0 +1,19 @@
using System.Runtime.InteropServices;
using System.Text;
namespace Shared.Packet.Packets;
public class CapturePacket : IPacket {
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = Constants.CostumeNameSize)]
public string ModelName;
public bool IsCaptured;
public void Serialize(Span<byte> data) {
Encoding.UTF8.GetBytes(ModelName).CopyTo(data[..Constants.CostumeNameSize]);
MemoryMarshal.Write(data[Constants.CostumeNameSize..], ref IsCaptured);
}
public void Deserialize(Span<byte> data) {
ModelName = Encoding.UTF8.GetString(data[..Constants.CostumeNameSize]).TrimNullTerm();
IsCaptured = MemoryMarshal.Read<bool>(data[Constants.CostumeNameSize..]);
}
}

View file

@ -1,24 +1,21 @@
using System.Runtime.InteropServices;
using System.Text;
namespace Shared.Packet.Packets;
[Packet(PacketType.Costume)]
public struct CostumePacket : IPacket {
public const int CostumeNameSize = 0x20;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = CostumeNameSize)]
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = Constants.CostumeNameSize)]
public string BodyName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = CostumeNameSize)]
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = Constants.CostumeNameSize)]
public string CapName;
public void Serialize(Span<byte> data) {
Span<char> strData = MemoryMarshal.Cast<byte, char>(data);
BodyName.CopyTo(strData[..CostumeNameSize]);
CapName.CopyTo(strData[CostumeNameSize..]);
Encoding.UTF8.GetBytes(BodyName).CopyTo(data[..Constants.CostumeNameSize]);
Encoding.UTF8.GetBytes(CapName).CopyTo(data[Constants.CostumeNameSize..]);
}
public void Deserialize(Span<byte> data) {
Span<char> strData = MemoryMarshal.Cast<byte, char>(data);
BodyName = new string(strData[..CostumeNameSize].TrimEnd('\0'));
CapName = new string(strData[CostumeNameSize..].TrimEnd('\0'));
BodyName = Encoding.UTF8.GetString(data[..Constants.CostumeNameSize]).TrimNullTerm();
CapName = Encoding.UTF8.GetString(data[Constants.CostumeNameSize..]).TrimNullTerm();
}
}

View file

@ -1,19 +0,0 @@
using System.Runtime.InteropServices;
namespace Shared.Packet.Packets;
public class GamePacket : IPacket {
public int ScenarioNum;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = PlayerPacket.NameSize)]
public string Stage;
public void Serialize(Span<byte> data) {
MemoryMarshal.Write(data, ref ScenarioNum);
Stage.CopyTo(MemoryMarshal.Cast<byte, char>(data[4..]));
}
public void Deserialize(Span<byte> data) {
ScenarioNum = MemoryMarshal.Read<int>(data);
Stage = new string(MemoryMarshal.Cast<byte, char>(data[4..]));
}
}

View file

@ -1,4 +1,5 @@
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
@ -38,7 +39,6 @@ public struct PlayerPacket : IPacket {
MemoryMarshal.Write(data[offset++..], ref IsIt);
MemoryMarshal.Write(data[offset..], ref ScenarioNum);
offset += 5;
// Span<char> strData = MemoryMarshal.Cast<byte, char>(data[offset..]);
Encoding.UTF8.GetBytes(Stage).CopyTo(data[offset..(offset + NameSize)]);
offset += NameSize;
Encoding.UTF8.GetBytes(Act).CopyTo(data[offset..(offset + NameSize)]);
@ -60,10 +60,10 @@ public struct PlayerPacket : IPacket {
// offset++; // padding
ScenarioNum = MemoryMarshal.Read<int>(data[offset..]);
offset += 5;
Stage = new string(Encoding.UTF8.GetString(data[offset..(offset + NameSize)]).TrimEnd('\0'));
Stage = Encoding.UTF8.GetString(data[offset..(offset + NameSize)]).TrimEnd('\0');
offset += NameSize;
Act = new string(Encoding.UTF8.GetString(data[offset..(offset + NameSize)]).TrimEnd('\0'));
Act = Encoding.UTF8.GetString(data[offset..(offset + NameSize)]).TrimEnd('\0');
offset += NameSize;
SubAct = new string(Encoding.UTF8.GetString(data[offset..(offset + NameSize)]).TrimEnd('\0'));
SubAct = Encoding.UTF8.GetString(data[offset..(offset + NameSize)]).TrimEnd('\0');
}
}

View file

@ -5,11 +5,14 @@ namespace Shared.Packet.Packets;
[Packet(PacketType.Shine)]
public struct ShinePacket : IPacket {
public int ShineId;
public bool IsGrand;
public void Serialize(Span<byte> data) {
MemoryMarshal.Write(data, ref ShineId);
MemoryMarshal.Write(data, ref IsGrand);
}
public void Deserialize(Span<byte> data) {
ShineId = MemoryMarshal.Read<int>(data);
IsGrand = MemoryMarshal.Read<bool>(data);
}
}

View file

@ -0,0 +1,14 @@
using System.Runtime.InteropServices;
namespace Shared.Packet.Packets;
public class TagPacket : IPacket {
public bool IsIt = false;
public void Serialize(Span<byte> data) {
MemoryMarshal.Write(data, ref IsIt);
}
public void Deserialize(Span<byte> data) {
IsIt = MemoryMarshal.Read<bool>(data);
}
}

View file

@ -4,6 +4,7 @@
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>

View file

@ -32,7 +32,7 @@ async void Funny() {
while (true) {
d += Math.PI / 32;
if (playerPacket == null) {
// logger.Warn($"Waiting...");
// wait until valid player packet has arrived
await Task.Delay(300);
continue;
}
@ -55,27 +55,30 @@ async Task S() {
IMemoryOwner<byte> owner = MemoryPool<byte>.Shared.Rent(256);
while (true) {
await stream.ReadAsync(owner.Memory);
PacketHeader header = MemoryMarshal.Read<PacketHeader>(owner.Memory.Span);
if (header.Type == PacketType.Player) {
if (otherId == Guid.Empty) otherId = header.Id;
if (otherId != header.Id) continue;
if (e++ != 0) {
e %= 3;
continue;
}
unsafe {
PacketHeader header = MemoryMarshal.Read<PacketHeader>(owner.Memory.Span);
if (header.Type == PacketType.Player) {
if (otherId == Guid.Empty) otherId = header.Id;
if (otherId != header.Id) continue;
if (e++ != 0) {
e %= 3;
continue;
}
header.Id = ownId;
MemoryMarshal.Write(owner.Memory.Span, ref header);
unsafe {
header.Id = ownId;
MemoryMarshal.Write(owner.Memory.Span, ref header);
fixed (byte* data = owner.Memory.Span[Constants.HeaderSize..]) {
logger.Error($"{Marshal.OffsetOf<PlayerPacket>(nameof(PlayerPacket.AnimationBlendWeights))} {Marshal.OffsetOf<PlayerPacket>(nameof(PlayerPacket.AnimationRate))}");
PlayerPacket packet = Marshal.PtrToStructure<PlayerPacket>((IntPtr) data);
playerPacket = packet;
basePoint = packet.Position;
}
}
// packet.SubAct = "";
// packet.SubAct = "";
} else if (header.Type == PacketType.Cap) {
}
}
}
}