2022-02-14 19:45:58 +00:00
using System.Buffers ;
using System.Collections.Concurrent ;
using System.Net.Sockets ;
2022-03-11 05:59:02 +00:00
using System.Runtime.InteropServices ;
2022-02-10 04:29:10 +00:00
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-02-14 19:45:58 +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 ;
2022-02-14 19:45:58 +00:00
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 ; }
2022-02-15 20:26:50 +00:00
public Logger Logger { get ; }
2022-02-10 01:44:50 +00:00
2022-02-15 20:26:50 +00:00
public Client ( Socket socket ) {
Socket = socket ;
2022-03-06 23:19:49 +00:00
Logger = new Logger ( "Unknown User" ) ;
2022-02-15 20:26:50 +00:00
}
2022-03-01 21:08:53 +00:00
2022-02-10 01:44:50 +00:00
public void Dispose ( ) {
2022-02-15 20:26:50 +00:00
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-03-01 21:08:53 +00:00
public delegate IPacket PacketTransformerDel ( Client ? sender , IPacket packet ) ;
public event PacketTransformerDel ? PacketTransformer ;
2022-02-16 00:35:38 +00:00
public async Task Send < T > ( T packet , Client ? sender = null ) where T : struct , IPacket {
2022-03-11 05:59:02 +00:00
IMemoryOwner < byte > memory = MemoryPool < byte > . Shared . RentZero ( Constants . HeaderSize + packet . Size ) ;
2022-03-01 21:08:53 +00:00
packet = ( T ) ( PacketTransformer ? . Invoke ( sender , packet ) ? ? packet ) ;
2022-02-14 19:45:58 +00:00
PacketHeader header = new PacketHeader {
Id = sender ? . Id ? ? Guid . Empty ,
2022-03-11 05:59:02 +00:00
Type = Constants . PacketMap [ typeof ( T ) ] . Type ,
PacketSize = packet . Size
2022-02-14 19:45:58 +00:00
} ;
Server . FillPacket ( header , packet , memory . Memory ) ;
2022-03-11 05:59:02 +00:00
await Send ( memory . Memory [ . . ] , sender ) ;
2022-02-16 20:33:21 +00:00
memory . Dispose ( ) ;
2022-02-14 19:45:58 +00:00
}
public async Task Send ( ReadOnlyMemory < byte > data , Client ? sender ) {
2022-02-10 08:42:35 +00:00
if ( ! Connected ) {
2022-03-11 05:59:02 +00:00
Server . Logger . Info ( $"Didn't send {MemoryMarshal.Read<PacketType>(data.Span[16..])} to {Id} because they weren't connected yet" ) ;
2022-02-10 08:42:35 +00:00
return ;
}
2022-02-14 19:45:58 +00:00
2022-03-11 05:59:02 +00:00
int packetSize = MemoryMarshal . Read < short > ( data . Span [ 18. . ] ) ;
await Socket ! . SendAsync ( data [ . . ( Constants . HeaderSize + 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
}