0
0
Fork 0
mirror of https://github.com/Sanae6/SmoOnlineServer.git synced 2024-11-21 18:55:17 +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 {
IMemoryOwner<byte> memory = MemoryPool<byte>.Shared.RentZero(Constants.HeaderSize + packet.Size);
packet = (T) (PacketTransformer?.Invoke(sender, packet) ?? packet);
PacketHeader header = new PacketHeader {
Id = sender?.Id ?? Id,
Type = Constants.PacketMap[typeof(T)].Type,
@ -49,13 +48,20 @@ public class Client : IDisposable {
memory.Dispose();
}
public async Task Send(ReadOnlyMemory<byte> data, Client? sender) {
public async Task Send(Memory<byte> data, Client? sender) {
if (!Connected) {
// Server.Logger.Info($"Didn't send {MemoryMarshal.Read<PacketType>(data.Span[16..])} to {Id} because they weren't connected yet");
return;
}
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);
}

View file

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

View file

@ -180,7 +180,10 @@ public class Server {
case ConnectPacket.ConnectionTypes.FirstConnection: {
firstConn = true;
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;
client = newClient;
}
@ -190,7 +193,10 @@ public class Server {
case ConnectPacket.ConnectionTypes.Reconnecting: {
client.Id = header.Id;
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;
client = newClient;
} else {

View file

@ -18,7 +18,7 @@ public struct PacketHeader : IPacket {
MemoryMarshal.Write(data[18..], ref PacketSize);
}
public void Deserialize(Span<byte> data) {
public void Deserialize(ReadOnlySpan<byte> data) {
Id = MemoryMarshal.Read<Guid>(data);
Type = MemoryMarshal.Read<PacketType>(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)]);
}
public void Deserialize(Span<byte> data) {
public void Deserialize(ReadOnlySpan<byte> data) {
Position = MemoryMarshal.Read<Vector3>(data);
Rotation = MemoryMarshal.Read<Quaternion>(data[12..]);
CapOut = MemoryMarshal.Read<bool>(data[28..]);

View file

@ -12,7 +12,7 @@ public struct CapturePacket : IPacket {
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();
}

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 + 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.");
}
}

View file

@ -17,7 +17,7 @@ public struct ConnectPacket : IPacket {
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);
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..]);
}
public void Deserialize(Span<byte> data) {
public void Deserialize(ReadOnlySpan<byte> data) {
BodyName = 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 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)]);
}
public void Deserialize(Span<byte> data) {
public void Deserialize(ReadOnlySpan<byte> data) {
Is2d = MemoryMarshal.Read<bool>(data);
ScenarioNum = MemoryMarshal.Read<byte>(data[1..]);
Stage = Encoding.UTF8.GetString(data[2..(2 + StageSize)]).TrimEnd('\0');

View file

@ -4,5 +4,5 @@
public interface IPacket {
short Size { get; }
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);
}
public void Deserialize(Span<byte> data) {
public void Deserialize(ReadOnlySpan<byte> data) {
int offset = 0;
Position = MemoryMarshal.Read<Vector3>(data[..(offset += Marshal.SizeOf<Vector3>())]);
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);
}
public void Deserialize(Span<byte> data) {
public void Deserialize(ReadOnlySpan<byte> data) {
ShineId = MemoryMarshal.Read<int>(data);
}
}

View file

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

View file

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