mirror of
https://github.com/Sanae6/SmoOnlineServer.git
synced 2024-11-25 04:35:18 +00:00
Merge branch 'master' of https://github.com/Sanae6/SmoOnlineServer
This commit is contained in:
commit
a89471de54
16 changed files with 33 additions and 19 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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..]);
|
||||||
|
|
|
@ -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..]);
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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.");
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) { }
|
||||||
}
|
}
|
|
@ -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');
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
|
@ -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>())]);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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..]);
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue