0
0
Fork 0
mirror of https://github.com/Sanae6/SmoOnlineServer.git synced 2024-11-25 04:35:18 +00:00
This commit is contained in:
CraftyBoss 2022-04-05 19:35:15 +00:00
commit a89471de54
16 changed files with 33 additions and 19 deletions

View file

@ -38,7 +38,6 @@ public class Client : IDisposable {
public async Task Send<T>(T packet, Client? sender = null) where T : struct, IPacket { public async Task Send<T>(T packet, Client? sender = null) where T : struct, IPacket {
IMemoryOwner<byte> memory = MemoryPool<byte>.Shared.RentZero(Constants.HeaderSize + packet.Size); IMemoryOwner<byte> memory = MemoryPool<byte>.Shared.RentZero(Constants.HeaderSize + packet.Size);
packet = (T) (PacketTransformer?.Invoke(sender, packet) ?? packet);
PacketHeader header = new PacketHeader { PacketHeader header = new PacketHeader {
Id = sender?.Id ?? Id, Id = sender?.Id ?? Id,
Type = Constants.PacketMap[typeof(T)].Type, Type = Constants.PacketMap[typeof(T)].Type,
@ -49,13 +48,20 @@ public class Client : IDisposable {
memory.Dispose(); memory.Dispose();
} }
public async Task Send(ReadOnlyMemory<byte> data, Client? sender) { public async Task Send(Memory<byte> data, Client? sender) {
if (!Connected) { if (!Connected) {
// Server.Logger.Info($"Didn't send {MemoryMarshal.Read<PacketType>(data.Span[16..])} to {Id} because they weren't connected yet"); // Server.Logger.Info($"Didn't send {MemoryMarshal.Read<PacketType>(data.Span[16..])} to {Id} because they weren't connected yet");
return; return;
} }
int packetSize = MemoryMarshal.Read<short>(data.Span[18..]); int packetSize = MemoryMarshal.Read<short>(data.Span[18..]);
if (PacketTransformer != null) {
PacketType type = MemoryMarshal.Read<PacketType>(data.Span[16..]);
IPacket packet = (IPacket) Activator.CreateInstance(Constants.PacketIdMap[type])!;
packet.Deserialize(data.Span);
packet = PacketTransformer?.Invoke(sender, packet) ?? packet;
packet.Serialize(data.Span);
}
await Socket!.SendAsync(data[..(Constants.HeaderSize + packetSize)], SocketFlags.None); await Socket!.SendAsync(data[..(Constants.HeaderSize + packetSize)], SocketFlags.None);
} }

View file

@ -20,7 +20,7 @@ server.ClientJoined += (c, _) => {
c.Metadata["speedrun"] = false; c.Metadata["speedrun"] = false;
foreach (Client client in server.Clients.Where(client => client.Metadata.ContainsKey("lastGamePacket")).ToArray()) { foreach (Client client in server.Clients.Where(client => client.Metadata.ContainsKey("lastGamePacket")).ToArray()) {
try { try {
Task.WaitAll(c.Send((GamePacket) client.Metadata["lastGamePacket"]!, client)); c.Send((GamePacket) client.Metadata["lastGamePacket"]!, client).Wait();
} }
catch { catch {
// lol who gives a fuck // lol who gives a fuck
@ -84,12 +84,14 @@ server.PacketHandler = (c, p) => {
c.Metadata["speedrun"] = true; c.Metadata["speedrun"] = true;
((ConcurrentBag<int>) (c.Metadata["shineSync"] ??= new ConcurrentBag<int>())).Clear(); ((ConcurrentBag<int>) (c.Metadata["shineSync"] ??= new ConcurrentBag<int>())).Clear();
shineBag.Clear(); shineBag.Clear();
c.Logger.Info("Entered Cap on scenario 0, enabling speedrun flag");
break; break;
case "WaterfallWorldHomeStage": case "WaterfallWorldHomeStage":
bool wasSpeedrun = (bool) c.Metadata["speedrun"]!; bool wasSpeedrun = (bool) c.Metadata["speedrun"]!;
c.Metadata["speedrun"] = false; c.Metadata["speedrun"] = false;
if (wasSpeedrun) if (wasSpeedrun)
Task.Run(async () => { Task.Run(async () => {
c.Logger.Info("Entered Cascade with speedrun mode on");
await Task.Delay(15000); await Task.Delay(15000);
await ClientSyncShineBag(c); await ClientSyncShineBag(c);
}); });
@ -215,7 +217,7 @@ CommandHandler.RegisterCommand("scenario", args => {
return optionUsage; return optionUsage;
} }
case "merge" when args.Length == 1: { case "merge" when args.Length == 1: {
return $"Scenario merging is {(Settings.Instance.Scenario.MergeEnabled)}"; return $"Scenario merging is {Settings.Instance.Scenario.MergeEnabled}";
} }
default: default:
return optionUsage; return optionUsage;

View file

@ -180,7 +180,10 @@ public class Server {
case ConnectPacket.ConnectionTypes.FirstConnection: { case ConnectPacket.ConnectionTypes.FirstConnection: {
firstConn = true; firstConn = true;
if (FindExistingClient(header.Id) is { } newClient) { if (FindExistingClient(header.Id) is { } newClient) {
if (newClient.Connected) throw new Exception($"Tried to join as already connected user {header.Id}"); if (newClient.Connected) {
newClient.Logger.Info($"Disconnecting already connected client {newClient.Socket?.RemoteEndPoint} for {client.Socket?.RemoteEndPoint}");
newClient.Dispose();
}
newClient.Socket = client.Socket; newClient.Socket = client.Socket;
client = newClient; client = newClient;
} }
@ -190,7 +193,10 @@ public class Server {
case ConnectPacket.ConnectionTypes.Reconnecting: { case ConnectPacket.ConnectionTypes.Reconnecting: {
client.Id = header.Id; client.Id = header.Id;
if (FindExistingClient(header.Id) is { } newClient) { if (FindExistingClient(header.Id) is { } newClient) {
if (newClient.Connected) throw new Exception($"Tried to join as already connected user {header.Id}"); if (newClient.Connected) {
newClient.Logger.Info($"Disconnecting already connected client {newClient.Socket?.RemoteEndPoint} for {client.Socket?.RemoteEndPoint}");
newClient.Dispose();
}
newClient.Socket = client.Socket; newClient.Socket = client.Socket;
client = newClient; client = newClient;
} else { } else {

View file

@ -18,7 +18,7 @@ public struct PacketHeader : IPacket {
MemoryMarshal.Write(data[18..], ref PacketSize); MemoryMarshal.Write(data[18..], ref PacketSize);
} }
public void Deserialize(Span<byte> data) { public void Deserialize(ReadOnlySpan<byte> data) {
Id = MemoryMarshal.Read<Guid>(data); Id = MemoryMarshal.Read<Guid>(data);
Type = MemoryMarshal.Read<PacketType>(data[16..]); Type = MemoryMarshal.Read<PacketType>(data[16..]);
PacketSize = MemoryMarshal.Read<short>(data[16..]); PacketSize = MemoryMarshal.Read<short>(data[16..]);

View file

@ -21,7 +21,7 @@ public struct CapPacket : IPacket {
Encoding.UTF8.GetBytes(CapAnim).CopyTo(data[32..(32 + NameSize)]); Encoding.UTF8.GetBytes(CapAnim).CopyTo(data[32..(32 + NameSize)]);
} }
public void Deserialize(Span<byte> data) { public void Deserialize(ReadOnlySpan<byte> data) {
Position = MemoryMarshal.Read<Vector3>(data); Position = MemoryMarshal.Read<Vector3>(data);
Rotation = MemoryMarshal.Read<Quaternion>(data[12..]); Rotation = MemoryMarshal.Read<Quaternion>(data[12..]);
CapOut = MemoryMarshal.Read<bool>(data[28..]); CapOut = MemoryMarshal.Read<bool>(data[28..]);

View file

@ -12,7 +12,7 @@ public struct CapturePacket : IPacket {
Encoding.UTF8.GetBytes(ModelName).CopyTo(data[..Constants.CostumeNameSize]); Encoding.UTF8.GetBytes(ModelName).CopyTo(data[..Constants.CostumeNameSize]);
} }
public void Deserialize(Span<byte> data) { public void Deserialize(ReadOnlySpan<byte> data) {
ModelName = Encoding.UTF8.GetString(data[..Constants.CostumeNameSize]).TrimNullTerm(); ModelName = Encoding.UTF8.GetString(data[..Constants.CostumeNameSize]).TrimNullTerm();
} }

View file

@ -19,7 +19,7 @@ public struct ChangeStagePacket : IPacket {
MemoryMarshal.Write(data[(IdSize + StageSize)..(IdSize + StageSize + 1)], ref Scenario); MemoryMarshal.Write(data[(IdSize + StageSize)..(IdSize + StageSize + 1)], ref Scenario);
MemoryMarshal.Write(data[(IdSize + StageSize + 1)..(IdSize + StageSize + 2)], ref SubScenarioType); MemoryMarshal.Write(data[(IdSize + StageSize + 1)..(IdSize + StageSize + 2)], ref SubScenarioType);
} }
public void Deserialize(Span<byte> data) { public void Deserialize(ReadOnlySpan<byte> data) {
throw new NotImplementedException("This packet should not be sent by the client."); throw new NotImplementedException("This packet should not be sent by the client.");
} }
} }

View file

@ -17,7 +17,7 @@ public struct ConnectPacket : IPacket {
Encoding.UTF8.GetBytes(ClientName).CopyTo(data[4..(4 + Constants.CostumeNameSize)]); Encoding.UTF8.GetBytes(ClientName).CopyTo(data[4..(4 + Constants.CostumeNameSize)]);
} }
public void Deserialize(Span<byte> data) { public void Deserialize(ReadOnlySpan<byte> data) {
ConnectionType = MemoryMarshal.Read<ConnectionTypes>(data); ConnectionType = MemoryMarshal.Read<ConnectionTypes>(data);
ClientName = Encoding.UTF8.GetString(data[4..(4 + Constants.CostumeNameSize)]).TrimNullTerm(); ClientName = Encoding.UTF8.GetString(data[4..(4 + Constants.CostumeNameSize)]).TrimNullTerm();
} }

View file

@ -15,7 +15,7 @@ public struct CostumePacket : IPacket {
Encoding.UTF8.GetBytes(CapName).CopyTo(data[Constants.CostumeNameSize..]); Encoding.UTF8.GetBytes(CapName).CopyTo(data[Constants.CostumeNameSize..]);
} }
public void Deserialize(Span<byte> data) { public void Deserialize(ReadOnlySpan<byte> data) {
BodyName = Encoding.UTF8.GetString(data[..Constants.CostumeNameSize]).TrimNullTerm(); BodyName = Encoding.UTF8.GetString(data[..Constants.CostumeNameSize]).TrimNullTerm();
CapName = Encoding.UTF8.GetString(data[Constants.CostumeNameSize..]).TrimNullTerm(); CapName = Encoding.UTF8.GetString(data[Constants.CostumeNameSize..]).TrimNullTerm();
} }

View file

@ -6,5 +6,5 @@ public struct DisconnectPacket : IPacket {
public short Size => 0; public short Size => 0;
public void Serialize(Span<byte> data) { } public void Serialize(Span<byte> data) { }
public void Deserialize(Span<byte> data) { } public void Deserialize(ReadOnlySpan<byte> data) { }
} }

View file

@ -22,7 +22,7 @@ public struct GamePacket : IPacket {
Encoding.UTF8.GetBytes(Stage).CopyTo(data[2..(2 + StageSize)]); Encoding.UTF8.GetBytes(Stage).CopyTo(data[2..(2 + StageSize)]);
} }
public void Deserialize(Span<byte> data) { public void Deserialize(ReadOnlySpan<byte> data) {
Is2d = MemoryMarshal.Read<bool>(data); Is2d = MemoryMarshal.Read<bool>(data);
ScenarioNum = MemoryMarshal.Read<byte>(data[1..]); ScenarioNum = MemoryMarshal.Read<byte>(data[1..]);
Stage = Encoding.UTF8.GetString(data[2..(2 + StageSize)]).TrimEnd('\0'); Stage = Encoding.UTF8.GetString(data[2..(2 + StageSize)]).TrimEnd('\0');

View file

@ -4,5 +4,5 @@
public interface IPacket { public interface IPacket {
short Size { get; } short Size { get; }
void Serialize(Span<byte> data); void Serialize(Span<byte> data);
void Deserialize(Span<byte> data); void Deserialize(ReadOnlySpan<byte> data);
} }

View file

@ -35,7 +35,7 @@ public struct PlayerPacket : IPacket {
MemoryMarshal.Write(data[offset++..++offset], ref SubAct); MemoryMarshal.Write(data[offset++..++offset], ref SubAct);
} }
public void Deserialize(Span<byte> data) { public void Deserialize(ReadOnlySpan<byte> data) {
int offset = 0; int offset = 0;
Position = MemoryMarshal.Read<Vector3>(data[..(offset += Marshal.SizeOf<Vector3>())]); Position = MemoryMarshal.Read<Vector3>(data[..(offset += Marshal.SizeOf<Vector3>())]);
Rotation = MemoryMarshal.Read<Quaternion>(data[offset..(offset += Marshal.SizeOf<Quaternion>())]); Rotation = MemoryMarshal.Read<Quaternion>(data[offset..(offset += Marshal.SizeOf<Quaternion>())]);

View file

@ -12,7 +12,7 @@ public struct ShinePacket : IPacket {
MemoryMarshal.Write(data, ref ShineId); MemoryMarshal.Write(data, ref ShineId);
} }
public void Deserialize(Span<byte> data) { public void Deserialize(ReadOnlySpan<byte> data) {
ShineId = MemoryMarshal.Read<int>(data); ShineId = MemoryMarshal.Read<int>(data);
} }
} }

View file

@ -18,7 +18,7 @@ public struct TagPacket : IPacket {
MemoryMarshal.Write(data[4..], ref Minutes); MemoryMarshal.Write(data[4..], ref Minutes);
} }
public void Deserialize(Span<byte> data) { public void Deserialize(ReadOnlySpan<byte> data) {
UpdateType = MemoryMarshal.Read<TagUpdate>(data); UpdateType = MemoryMarshal.Read<TagUpdate>(data);
IsIt = MemoryMarshal.Read<bool>(data[1..]); IsIt = MemoryMarshal.Read<bool>(data[1..]);
Seconds = MemoryMarshal.Read<byte>(data[2..]); Seconds = MemoryMarshal.Read<byte>(data[2..]);

View file

@ -14,7 +14,7 @@ public struct UnhandledPacket : IPacket {
Data.CopyTo(data); Data.CopyTo(data);
} }
public void Deserialize(Span<byte> data) { public void Deserialize(ReadOnlySpan<byte> data) {
Data = data.ToArray(); Data = data.ToArray();
} }