SmoOnlineServer/Server/Client.cs

75 lines
2.7 KiB
C#
Raw Normal View History

using System.Buffers;
using System.Collections.Concurrent;
2022-04-27 06:43:11 +00:00
using System.Diagnostics;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using Shared;
2022-02-10 08:42:35 +00:00
using Shared.Packet;
2022-02-08 22:46:12 +00:00
using Shared.Packet.Packets;
2021-11-29 04:04:34 +00:00
2022-02-10 01:44:50 +00:00
namespace Server;
2021-11-29 04:04:34 +00:00
public class Client : IDisposable {
2022-03-15 07:23:37 +00:00
public readonly ConcurrentDictionary<string, object?> Metadata = new ConcurrentDictionary<string, object?>(); // can be used to store any information about a player
2022-02-09 21:56:57 +00:00
public bool Connected = false;
public CostumePacket? CurrentCostume = null; // required for proper client sync
public string Name {
get => Logger.Name;
set => Logger.Name = value;
}
2022-02-10 01:44:50 +00:00
public Guid Id;
public Socket? Socket;
2022-02-10 08:42:35 +00:00
public Server Server { get; init; }
public Logger Logger { get; }
2022-02-10 01:44:50 +00:00
public Client(Socket socket) {
Socket = socket;
Logger = new Logger("Unknown User");
}
2022-02-10 01:44:50 +00:00
public void Dispose() {
if (Socket?.Connected is true)
Socket.Disconnect(false);
2022-02-10 01:44:50 +00:00
}
2021-11-29 04:04:34 +00:00
2022-02-16 00:35:38 +00:00
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);
2022-04-27 05:48:13 +00:00
PacketAttribute packetAttribute = Constants.PacketMap[typeof(T)];
if (packetAttribute.Type is not PacketType.Cap and not PacketType.Player)
2022-04-27 06:31:48 +00:00
Logger.Info($"About to receive {packetAttribute.Type} ({(short)packetAttribute.Type}) - {typeof(T)}");
PacketHeader header = new PacketHeader {
2022-03-15 07:31:24 +00:00
Id = sender?.Id ?? Id,
2022-04-27 05:48:13 +00:00
Type = packetAttribute.Type,
PacketSize = packet.Size
};
Server.FillPacket(header, packet, memory.Memory);
2022-04-27 06:31:48 +00:00
await Send(memory.Memory, sender, packetAttribute.Type);
memory.Dispose();
}
2022-04-27 06:31:48 +00:00
public async Task Send(Memory<byte> data, Client? sender, PacketType? partTime = null) {
PacketHeader header = new PacketHeader();
header.Deserialize(data.Span);
2022-04-27 05:58:43 +00:00
if (!Connected && header.Type is not PacketType.Connect) {
Server.Logger.Error($"Didn't send {header.Type} to {Id} because they weren't connected yet");
2022-02-10 08:42:35 +00:00
return;
}
2022-04-27 06:43:11 +00:00
if (header.Type is not PacketType.Cap and not PacketType.Player) {
Logger.Info($"About to receive {header.Type} + ({(short)header.Type}), {partTime} ({(short?) partTime}) {new StackTrace().ToString()}");
}
2022-04-27 05:38:25 +00:00
2022-04-27 05:58:43 +00:00
await Socket!.SendAsync(data[..(Constants.HeaderSize + header.PacketSize)], SocketFlags.None);
2021-11-29 04:04:34 +00:00
}
2022-02-10 01:44:50 +00:00
public static bool operator ==(Client? left, Client? right) {
return left is { } leftClient && right is { } rightClient && leftClient.Id == rightClient.Id;
2021-11-29 04:04:34 +00:00
}
2022-02-10 01:44:50 +00:00
public static bool operator !=(Client? left, Client? right) {
return !(left == right);
}
2021-11-29 04:04:34 +00:00
}