mirror of
https://github.com/Sanae6/SmoOnlineServer.git
synced 2024-11-24 04:05:17 +00:00
Reformat solution
This commit is contained in:
parent
351304f99f
commit
7dbe2ecd55
25 changed files with 89 additions and 73 deletions
|
@ -1,28 +1,34 @@
|
||||||
using System.Buffers;
|
using System.Net.Sockets;
|
||||||
using System.Net.Sockets;
|
|
||||||
using Shared.Packet.Packets;
|
using Shared.Packet.Packets;
|
||||||
|
|
||||||
namespace Server;
|
namespace Server;
|
||||||
|
|
||||||
public class Client : IDisposable {
|
public class Client : IDisposable {
|
||||||
public Socket? Socket;
|
public readonly Dictionary<string, object> Metadata = new Dictionary<string, object>(); // can be used to store any information about a player
|
||||||
public bool Connected = false;
|
public bool Connected = false;
|
||||||
public Guid Id;
|
|
||||||
public CostumePacket CurrentCostume = new CostumePacket {
|
public CostumePacket CurrentCostume = new CostumePacket {
|
||||||
BodyName = "",
|
BodyName = "",
|
||||||
CapName = ""
|
CapName = ""
|
||||||
};
|
};
|
||||||
public readonly Dictionary<string, object> Metadata = new Dictionary<string, object>(); // can be used to store any information about a player
|
|
||||||
|
public Guid Id;
|
||||||
|
public Socket? Socket;
|
||||||
|
|
||||||
|
public void Dispose() {
|
||||||
|
Socket?.Disconnect(false);
|
||||||
|
}
|
||||||
|
|
||||||
public async Task Send(Memory<byte> data) {
|
public async Task Send(Memory<byte> data) {
|
||||||
if (!Connected) return;
|
if (!Connected) return;
|
||||||
await Socket!.SendAsync(data, SocketFlags.None);
|
await Socket!.SendAsync(data, SocketFlags.None);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose() {
|
public static bool operator ==(Client? left, Client? right) {
|
||||||
Socket?.Disconnect(false);
|
return left is { } leftClient && right is { } rightClient && leftClient.Id == rightClient.Id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool operator ==(Client? left, Client? right) => left is { } leftClient && right is { } rightClient && leftClient.Id == rightClient.Id;
|
public static bool operator !=(Client? left, Client? right) {
|
||||||
public static bool operator !=(Client? left, Client? right) => !(left == right);
|
return !(left == right);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,3 @@
|
||||||
using System.Buffers;
|
Server.Server server = new Server.Server();
|
||||||
using System.Net.Sockets;
|
|
||||||
|
|
||||||
Server.Server server = new Server.Server();
|
|
||||||
|
|
||||||
await server.Listen(1027);
|
await server.Listen(1027);
|
|
@ -9,19 +9,20 @@ using Shared.Packet.Packets;
|
||||||
namespace Server;
|
namespace Server;
|
||||||
|
|
||||||
public class Server {
|
public class Server {
|
||||||
private readonly MemoryPool<byte> memoryPool = MemoryPool<byte>.Shared;
|
|
||||||
public readonly List<Client> Clients = new List<Client>();
|
public readonly List<Client> Clients = new List<Client>();
|
||||||
public readonly Logger Logger = new Logger("Server");
|
public readonly Logger Logger = new Logger("Server");
|
||||||
|
private readonly MemoryPool<byte> memoryPool = MemoryPool<byte>.Shared;
|
||||||
|
|
||||||
public async Task Listen(ushort port) {
|
public async Task Listen(ushort port) {
|
||||||
Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||||
serverSocket.Bind(new IPEndPoint(IPAddress.Any, port));
|
serverSocket.Bind(new IPEndPoint(IPAddress.Any, port));
|
||||||
serverSocket.Listen();
|
serverSocket.Listen();
|
||||||
|
|
||||||
Logger.Info($"Listening on port {port}");
|
Logger.Info($"Listening on port {port}");
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
Socket socket = await serverSocket.AcceptAsync();
|
Socket socket = await serverSocket.AcceptAsync();
|
||||||
|
|
||||||
Logger.Warn("ok");
|
Logger.Warn("ok");
|
||||||
|
|
||||||
if (Clients.Count > Constants.MaxClients) {
|
if (Clients.Count > Constants.MaxClients) {
|
||||||
|
@ -47,14 +48,14 @@ public class Server {
|
||||||
|
|
||||||
PacketHeader header = new PacketHeader {
|
PacketHeader header = new PacketHeader {
|
||||||
Id = sender?.Id ?? Guid.Empty,
|
Id = sender?.Id ?? Guid.Empty,
|
||||||
Type = Constants.Packets[typeof(T)].Type,
|
Type = Constants.Packets[typeof(T)].Type
|
||||||
};
|
};
|
||||||
FillPacket(header, packet, memory.Memory);
|
FillPacket(header, packet, memory.Memory);
|
||||||
await Broadcast(memory, sender);
|
await Broadcast(memory, sender);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Takes ownership of data and disposes once done.
|
/// Takes ownership of data and disposes once done.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="data">Memory owner to dispose once done</param>
|
/// <param name="data">Memory owner to dispose once done</param>
|
||||||
/// <param name="sender">Optional sender to not broadcast data to</param>
|
/// <param name="sender">Optional sender to not broadcast data to</param>
|
||||||
|
@ -67,7 +68,7 @@ public class Server {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Broadcasts memory whose memory shouldn't be disposed, should only be fired by server code.
|
/// Broadcasts memory whose memory shouldn't be disposed, should only be fired by server code.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="data">Memory to send to the clients</param>
|
/// <param name="data">Memory to send to the clients</param>
|
||||||
/// <param name="sender">Optional sender to not broadcast data to</param>
|
/// <param name="sender">Optional sender to not broadcast data to</param>
|
||||||
|
@ -81,14 +82,15 @@ public class Server {
|
||||||
|
|
||||||
|
|
||||||
private async void HandleSocket(Socket socket) {
|
private async void HandleSocket(Socket socket) {
|
||||||
Client client = new Client {Socket = socket};
|
Client client = new Client { Socket = socket };
|
||||||
IMemoryOwner<byte> memory = null!;
|
IMemoryOwner<byte> memory = null!;
|
||||||
bool first = true;
|
bool first = true;
|
||||||
try {
|
try {
|
||||||
while (true) {
|
while (true) {
|
||||||
memory = memoryPool.Rent(Constants.MaxPacketSize);
|
memory = memoryPool.Rent(Constants.MaxPacketSize);
|
||||||
int size = await socket.ReceiveAsync(memory.Memory, SocketFlags.None);
|
int size = await socket.ReceiveAsync(memory.Memory, SocketFlags.None);
|
||||||
if (size == 0) { // treat it as a disconnect and exit
|
if (size == 0) {
|
||||||
|
// treat it as a disconnect and exit
|
||||||
Logger.Info($"Socket {socket.RemoteEndPoint} disconnected.");
|
Logger.Info($"Socket {socket.RemoteEndPoint} disconnected.");
|
||||||
await socket.DisconnectAsync(false);
|
await socket.DisconnectAsync(false);
|
||||||
break;
|
break;
|
||||||
|
@ -99,9 +101,7 @@ public class Server {
|
||||||
// connection initialization
|
// connection initialization
|
||||||
if (first) {
|
if (first) {
|
||||||
first = false;
|
first = false;
|
||||||
if (header.Type != PacketType.Connect) {
|
if (header.Type != PacketType.Connect) throw new Exception($"First packet was not init, instead it was {header.Type}");
|
||||||
throw new Exception($"First packet was not init, instead it was {header.Type}");
|
|
||||||
}
|
|
||||||
|
|
||||||
ConnectPacket connect = MemoryMarshal.Read<ConnectPacket>(memory.Memory.Span[Constants.HeaderSize..size]);
|
ConnectPacket connect = MemoryMarshal.Read<ConnectPacket>(memory.Memory.Span[Constants.HeaderSize..size]);
|
||||||
lock (Clients) {
|
lock (Clients) {
|
||||||
|
@ -119,6 +119,7 @@ public class Server {
|
||||||
} else {
|
} else {
|
||||||
firstConn = true;
|
firstConn = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -130,7 +131,7 @@ public class Server {
|
||||||
// do any cleanup required when it comes to new clients
|
// do any cleanup required when it comes to new clients
|
||||||
List<Client> toDisconnect = Clients.FindAll(c => c.Id == header.Id && c.Connected && c.Socket != null);
|
List<Client> toDisconnect = Clients.FindAll(c => c.Id == header.Id && c.Connected && c.Socket != null);
|
||||||
Clients.RemoveAll(c => c.Id == header.Id);
|
Clients.RemoveAll(c => c.Id == header.Id);
|
||||||
|
|
||||||
client.Id = header.Id;
|
client.Id = header.Id;
|
||||||
Clients.Add(client);
|
Clients.Add(client);
|
||||||
|
|
||||||
|
@ -138,33 +139,32 @@ public class Server {
|
||||||
// done disconnecting and removing stale clients with the same id
|
// done disconnecting and removing stale clients with the same id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Client> otherConnectedPlayers = Clients.FindAll(c => c.Id != header.Id && c.Connected && c.Socket != null);
|
List<Client> otherConnectedPlayers = Clients.FindAll(c => c.Id != header.Id && c.Connected && c.Socket != null);
|
||||||
await Parallel.ForEachAsync(otherConnectedPlayers, async (other, _) => {
|
await Parallel.ForEachAsync(otherConnectedPlayers, async (other, _) => {
|
||||||
IMemoryOwner<byte> connectBuffer = MemoryPool<byte>.Shared.Rent(256);
|
IMemoryOwner<byte> connectBuffer = MemoryPool<byte>.Shared.Rent(256);
|
||||||
PacketHeader connectHeader = new PacketHeader() {
|
PacketHeader connectHeader = new PacketHeader {
|
||||||
Id = other.Id,
|
Id = other.Id,
|
||||||
Type = PacketType.Connect
|
Type = PacketType.Connect
|
||||||
};
|
};
|
||||||
MemoryMarshal.Write(connectBuffer.Memory.Span, ref connectHeader);
|
MemoryMarshal.Write(connectBuffer.Memory.Span, ref connectHeader);
|
||||||
ConnectPacket connectPacket = new ConnectPacket() {
|
ConnectPacket connectPacket = new ConnectPacket {
|
||||||
ConnectionType = ConnectionTypes.FirstConnection // doesn't matter what it is :)
|
ConnectionType = ConnectionTypes.FirstConnection // doesn't matter what it is :)
|
||||||
};
|
};
|
||||||
MemoryMarshal.Write(connectBuffer.Memory.Span, ref connectPacket);
|
MemoryMarshal.Write(connectBuffer.Memory.Span, ref connectPacket);
|
||||||
await client.Send(connectBuffer.Memory);
|
await client.Send(connectBuffer.Memory);
|
||||||
connectBuffer.Dispose();
|
connectBuffer.Dispose();
|
||||||
});
|
});
|
||||||
|
|
||||||
Logger.Info($"Client {socket.RemoteEndPoint} ({client.Id}) connected.");
|
Logger.Info($"Client {socket.RemoteEndPoint} ({client.Id}) connected.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// todo support variable length packets if they show up
|
// todo support variable length packets if they show up
|
||||||
Logger.Warn($"broadcasting {header.Type} from {client.Id}");
|
Logger.Warn($"broadcasting {header.Type} from {client.Id}");
|
||||||
await Broadcast(memory, client);
|
await Broadcast(memory, client);
|
||||||
}
|
}
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e) {
|
if (e is SocketException { SocketErrorCode: SocketError.ConnectionReset }) {
|
||||||
if (e is SocketException {SocketErrorCode: SocketError.ConnectionReset}) {
|
|
||||||
Logger.Info($"Client {socket.RemoteEndPoint} ({client.Id}) disconnected from the server");
|
Logger.Info($"Client {socket.RemoteEndPoint} ({client.Id}) disconnected from the server");
|
||||||
} else {
|
} else {
|
||||||
Logger.Error($"Exception on socket {socket.RemoteEndPoint} ({client.Id}) and disconnecting for: {e}");
|
Logger.Error($"Exception on socket {socket.RemoteEndPoint} ({client.Id}) and disconnecting for: {e}");
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Shared\Shared.csproj" />
|
<ProjectReference Include="..\Shared\Shared.csproj"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -3,13 +3,11 @@ using System.Runtime.InteropServices;
|
||||||
using Shared.Packet;
|
using Shared.Packet;
|
||||||
using Shared.Packet.Packets;
|
using Shared.Packet.Packets;
|
||||||
|
|
||||||
namespace Shared;
|
namespace Shared;
|
||||||
|
|
||||||
public static class Constants {
|
public static class Constants {
|
||||||
public const int MaxPacketSize = 256;
|
public const int MaxPacketSize = 256;
|
||||||
public const int MaxClients = 4;
|
public const int MaxClients = 4;
|
||||||
public static int HeaderSize { get; } = Marshal.SizeOf<PacketHeader>();
|
|
||||||
public static int PacketDataSize { get; } = MaxPacketSize - HeaderSize;
|
|
||||||
public const int CostumeNameSize = 0x20;
|
public const int CostumeNameSize = 0x20;
|
||||||
|
|
||||||
// dictionary of packet types to packet
|
// dictionary of packet types to packet
|
||||||
|
@ -18,4 +16,7 @@ public static class Constants {
|
||||||
.GetTypes()
|
.GetTypes()
|
||||||
.Where(type => type.IsAssignableTo(typeof(IPacket)))
|
.Where(type => type.IsAssignableTo(typeof(IPacket)))
|
||||||
.ToDictionary(type => type, type => type.GetCustomAttribute<PacketAttribute>()!);
|
.ToDictionary(type => type, type => type.GetCustomAttribute<PacketAttribute>()!);
|
||||||
|
|
||||||
|
public static int HeaderSize { get; } = Marshal.SizeOf<PacketHeader>();
|
||||||
|
public static int PacketDataSize { get; } = MaxPacketSize - HeaderSize;
|
||||||
}
|
}
|
|
@ -1,16 +1,18 @@
|
||||||
using System.Text;
|
namespace Shared;
|
||||||
|
|
||||||
namespace Shared;
|
|
||||||
|
|
||||||
public static class Extensions {
|
public static class Extensions {
|
||||||
public static string Hex(this Span<byte> span) {
|
public static string Hex(this Span<byte> span) {
|
||||||
return span.ToArray().Hex();
|
return span.ToArray().Hex();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string Hex(this IEnumerable<byte> array) => string.Join(' ', array.ToArray().Select(x => x.ToString("X2")));
|
public static string Hex(this IEnumerable<byte> array) {
|
||||||
|
return string.Join(' ', array.ToArray().Select(x => x.ToString("X2")));
|
||||||
|
}
|
||||||
|
|
||||||
public static unsafe byte* Ptr(this Span<byte> span) {
|
public static unsafe byte* Ptr(this Span<byte> span) {
|
||||||
fixed (byte* data = span) return data;
|
fixed (byte* data = span) {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string TrimNullTerm(this string text) {
|
public static string TrimNullTerm(this string text) {
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
namespace Shared;
|
namespace Shared;
|
||||||
|
|
||||||
public class Logger {
|
public class Logger {
|
||||||
public string Name { get; }
|
|
||||||
public Logger(string name) {
|
public Logger(string name) {
|
||||||
Name = name;
|
Name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string Name { get; }
|
||||||
|
|
||||||
public void Info(string text) {
|
public void Info(string text) {
|
||||||
Console.ResetColor();
|
Console.ResetColor();
|
||||||
Console.WriteLine($"Info [{Name}] {text}");
|
Console.WriteLine($"Info [{Name}] {text}");
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
namespace Shared.Packet;
|
namespace Shared.Packet;
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Struct, AllowMultiple = true)]
|
[AttributeUsage(AttributeTargets.Struct, AllowMultiple = true)]
|
||||||
public class PacketAttribute : Attribute {
|
public class PacketAttribute : Attribute {
|
||||||
public PacketType Type { get; }
|
|
||||||
public PacketAttribute(PacketType type) {
|
public PacketAttribute(PacketType type) {
|
||||||
Type = type;
|
Type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PacketType Type { get; }
|
||||||
}
|
}
|
|
@ -1,13 +1,14 @@
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using Shared.Packet.Packets;
|
using Shared.Packet.Packets;
|
||||||
|
|
||||||
namespace Shared.Packet;
|
namespace Shared.Packet;
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
public struct PacketHeader : IPacket {
|
public struct PacketHeader : IPacket {
|
||||||
// public int Length;
|
// public int Length;
|
||||||
public Guid Id;
|
public Guid Id;
|
||||||
public PacketType Type;
|
public PacketType Type;
|
||||||
|
|
||||||
public void Serialize(Span<byte> data) {
|
public void Serialize(Span<byte> data) {
|
||||||
// MemoryMarshal.Write(data, ref Length);
|
// MemoryMarshal.Write(data, ref Length);
|
||||||
MemoryMarshal.Write(data, ref Id);
|
MemoryMarshal.Write(data, ref Id);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
namespace Shared.Packet;
|
namespace Shared.Packet;
|
||||||
|
|
||||||
public enum PacketType {
|
public enum PacketType {
|
||||||
Unknown,
|
Unknown,
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using Shared.Packet.Packets;
|
using Shared.Packet.Packets;
|
||||||
|
|
||||||
namespace Shared.Packet;
|
namespace Shared.Packet;
|
||||||
|
|
||||||
public static class PacketUtils {
|
public static class PacketUtils {
|
||||||
public static void SerializeHeaded<T>(Span<byte> data, PacketHeader header, T t) where T : struct, IPacket {
|
public static void SerializeHeaded<T>(Span<byte> data, PacketHeader header, T t) where T : struct, IPacket {
|
||||||
header.Serialize(data);
|
header.Serialize(data);
|
||||||
t.Serialize(data[Constants.HeaderSize..]);
|
t.Serialize(data[Constants.HeaderSize..]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static T Deserialize<T>(Span<byte> data) where T : IPacket, new() {
|
public static T Deserialize<T>(Span<byte> data) where T : IPacket, new() {
|
||||||
T packet = new T();
|
T packet = new T();
|
||||||
packet.Deserialize(data);
|
packet.Deserialize(data);
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace Shared.Packet.Packets;
|
namespace Shared.Packet.Packets;
|
||||||
|
|
||||||
[Packet(PacketType.Cap)]
|
[Packet(PacketType.Cap)]
|
||||||
public struct CapPacket : IPacket {
|
public struct CapPacket : IPacket {
|
||||||
|
@ -10,6 +10,7 @@ public struct CapPacket : IPacket {
|
||||||
public Vector3 Position;
|
public Vector3 Position;
|
||||||
public Quaternion Rotation;
|
public Quaternion Rotation;
|
||||||
public string CapAnim;
|
public string CapAnim;
|
||||||
|
|
||||||
public void Serialize(Span<byte> data) {
|
public void Serialize(Span<byte> data) {
|
||||||
MemoryMarshal.Write(data, ref Position);
|
MemoryMarshal.Write(data, ref Position);
|
||||||
MemoryMarshal.Write(data[12..], ref Position);
|
MemoryMarshal.Write(data[12..], ref Position);
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace Shared.Packet.Packets;
|
namespace Shared.Packet.Packets;
|
||||||
|
|
||||||
[Packet(PacketType.Capture)]
|
[Packet(PacketType.Capture)]
|
||||||
public struct CapturePacket : IPacket {
|
public struct CapturePacket : IPacket {
|
||||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = Constants.CostumeNameSize)]
|
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = Constants.CostumeNameSize)]
|
||||||
public string ModelName;
|
public string ModelName;
|
||||||
|
|
||||||
public bool IsCaptured;
|
public bool IsCaptured;
|
||||||
|
|
||||||
public void Serialize(Span<byte> data) {
|
public void Serialize(Span<byte> data) {
|
||||||
Encoding.UTF8.GetBytes(ModelName).CopyTo(data[..Constants.CostumeNameSize]);
|
Encoding.UTF8.GetBytes(ModelName).CopyTo(data[..Constants.CostumeNameSize]);
|
||||||
MemoryMarshal.Write(data[Constants.CostumeNameSize..], ref IsCaptured);
|
MemoryMarshal.Write(data[Constants.CostumeNameSize..], ref IsCaptured);
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Shared.Packet.Packets;
|
namespace Shared.Packet.Packets;
|
||||||
|
|
||||||
[Packet(PacketType.Connect)]
|
[Packet(PacketType.Connect)]
|
||||||
public struct ConnectPacket : IPacket {
|
public struct ConnectPacket : IPacket {
|
||||||
public ConnectionTypes ConnectionType;
|
public ConnectionTypes ConnectionType;
|
||||||
|
|
||||||
public void Serialize(Span<byte> data) {
|
public void Serialize(Span<byte> data) {
|
||||||
MemoryMarshal.Write(data, ref ConnectionType);
|
MemoryMarshal.Write(data, ref ConnectionType);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
namespace Shared.Packet.Packets;
|
namespace Shared.Packet.Packets;
|
||||||
|
|
||||||
public enum ConnectionTypes {
|
public enum ConnectionTypes {
|
||||||
FirstConnection,
|
FirstConnection,
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace Shared.Packet.Packets;
|
namespace Shared.Packet.Packets;
|
||||||
|
|
||||||
[Packet(PacketType.Costume)]
|
[Packet(PacketType.Costume)]
|
||||||
public struct CostumePacket : IPacket {
|
public struct CostumePacket : IPacket {
|
||||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = Constants.CostumeNameSize)]
|
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = Constants.CostumeNameSize)]
|
||||||
public string BodyName;
|
public string BodyName;
|
||||||
|
|
||||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = Constants.CostumeNameSize)]
|
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = Constants.CostumeNameSize)]
|
||||||
public string CapName;
|
public string CapName;
|
||||||
|
|
||||||
public void Serialize(Span<byte> data) {
|
public void Serialize(Span<byte> data) {
|
||||||
Encoding.UTF8.GetBytes(BodyName).CopyTo(data[..Constants.CostumeNameSize]);
|
Encoding.UTF8.GetBytes(BodyName).CopyTo(data[..Constants.CostumeNameSize]);
|
||||||
Encoding.UTF8.GetBytes(CapName).CopyTo(data[Constants.CostumeNameSize..]);
|
Encoding.UTF8.GetBytes(CapName).CopyTo(data[Constants.CostumeNameSize..]);
|
||||||
|
|
|
@ -1,13 +1,9 @@
|
||||||
namespace Shared.Packet.Packets;
|
namespace Shared.Packet.Packets;
|
||||||
|
|
||||||
[Packet(PacketType.Disconnect)]
|
[Packet(PacketType.Disconnect)]
|
||||||
public struct DisconnectPacket : IPacket {
|
public struct DisconnectPacket : IPacket {
|
||||||
//empty packet
|
//empty packet
|
||||||
public void Serialize(Span<byte> data) {
|
public void Serialize(Span<byte> data) { }
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Deserialize(Span<byte> data) {
|
public void Deserialize(Span<byte> data) { }
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -1,6 +1,4 @@
|
||||||
using System.Runtime.InteropServices;
|
namespace Shared.Packet.Packets;
|
||||||
|
|
||||||
namespace Shared.Packet.Packets;
|
|
||||||
|
|
||||||
// Packet interface for type safety
|
// Packet interface for type safety
|
||||||
public interface IPacket {
|
public interface IPacket {
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
|
@ -11,17 +10,22 @@ public struct PlayerPacket : IPacket {
|
||||||
|
|
||||||
public Vector3 Position;
|
public Vector3 Position;
|
||||||
public Quaternion Rotation;
|
public Quaternion Rotation;
|
||||||
|
|
||||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
|
||||||
public float[] AnimationBlendWeights;
|
public float[] AnimationBlendWeights;
|
||||||
|
|
||||||
public float AnimationRate;
|
public float AnimationRate;
|
||||||
public bool Is2d;
|
public bool Is2d;
|
||||||
public bool ThrowingCap;
|
public bool ThrowingCap;
|
||||||
public bool IsIt;
|
public bool IsIt;
|
||||||
public int ScenarioNum;
|
public int ScenarioNum;
|
||||||
|
|
||||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = NameSize)]
|
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = NameSize)]
|
||||||
public string Stage;
|
public string Stage;
|
||||||
|
|
||||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = NameSize)]
|
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = NameSize)]
|
||||||
public string Act;
|
public string Act;
|
||||||
|
|
||||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = NameSize)]
|
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = NameSize)]
|
||||||
public string SubAct;
|
public string SubAct;
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Shared.Packet.Packets;
|
namespace Shared.Packet.Packets;
|
||||||
|
|
||||||
[Packet(PacketType.Shine)]
|
[Packet(PacketType.Shine)]
|
||||||
public struct ShinePacket : IPacket {
|
public struct ShinePacket : IPacket {
|
||||||
public int ShineId;
|
public int ShineId;
|
||||||
public bool IsGrand;
|
public bool IsGrand;
|
||||||
|
|
||||||
public void Serialize(Span<byte> data) {
|
public void Serialize(Span<byte> data) {
|
||||||
MemoryMarshal.Write(data, ref ShineId);
|
MemoryMarshal.Write(data, ref ShineId);
|
||||||
MemoryMarshal.Write(data, ref IsGrand);
|
MemoryMarshal.Write(data, ref IsGrand);
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Shared.Packet.Packets;
|
namespace Shared.Packet.Packets;
|
||||||
|
|
||||||
[Packet(PacketType.Tag)]
|
[Packet(PacketType.Tag)]
|
||||||
public struct TagPacket : IPacket {
|
public struct TagPacket : IPacket {
|
||||||
public bool IsIt = false;
|
public bool IsIt;
|
||||||
|
|
||||||
public void Serialize(Span<byte> data) {
|
public void Serialize(Span<byte> data) {
|
||||||
MemoryMarshal.Write(data, ref IsIt);
|
MemoryMarshal.Write(data, ref IsIt);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
namespace Shared.Packet.Packets;
|
namespace Shared.Packet.Packets;
|
||||||
|
|
||||||
[Packet(PacketType.Unknown)] // empty like boss
|
[Packet(PacketType.Unknown)] // empty like boss
|
||||||
// [Packet(PacketType.Command)]
|
// [Packet(PacketType.Command)]
|
||||||
public struct UnhandledPacket : IPacket {
|
public struct UnhandledPacket : IPacket {
|
||||||
public byte[] Data = new byte[Constants.PacketDataSize];
|
public byte[] Data = new byte[Constants.PacketDataSize];
|
||||||
|
|
||||||
public void Serialize(Span<byte> data) {
|
public void Serialize(Span<byte> data) {
|
||||||
Data.CopyTo(data);
|
Data.CopyTo(data);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />
|
<PackageReference Include="System.Numerics.Vectors" Version="4.5.0"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
using System.Buffers;
|
using System.Buffers;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using Shared;
|
using Shared;
|
||||||
using Shared.Packet;
|
using Shared.Packet;
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Shared\Shared.csproj" />
|
<ProjectReference Include="..\Shared\Shared.csproj"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
Loading…
Reference in a new issue