using ReboundEmulator.Core.Rooms; using System.Net.Sockets; namespace ReboundEmulator.Core { public sealed class Player { static int _nextId; public int Id { get; } = Interlocked.Increment(ref _nextId); public Account? Account { get; set; } public string ScreenName { get; set; } = "Guest"; public string ProfileId { get; set; } = "100000000000"; public string LoginKey { get; set; } = ""; public Room? Room { get; set; } public DateTime? LastSeen { get; set; } public ILogger? Log { get; set; } readonly NetworkStream _stream; readonly SemaphoreSlim _writeLock = new(1, 1); public Player(NetworkStream stream) => _stream = stream; public async Task SendAsync(params (string key, string value)[] fields) { var msg = new Dictionary(); foreach (var (k, v) in fields) msg[k] = v; await SendAsync(msg); msg.TryGetValue("msg.op", out var op); Log?.LogInformation("[plid {Id}] -> {Op} {Msg}", Id, op, string.Join(" ", msg.Where(kv => kv.Key != "msg.op").Select(kv => $"{kv.Key}='{kv.Value}'"))); } public async Task SendAsync(Dictionary msg) { await _writeLock.WaitAsync(); try { await TCPProtocol.WriteMessageAsync(_stream, msg); } catch (IOException) { } catch (ObjectDisposedException) { } finally { _writeLock.Release(); } } } }