using HermesSocketLibrary.Requests.Messages; using HermesSocketLibrary.Socket.Data; using HermesSocketServer.Services; using ILogger = Serilog.ILogger; namespace HermesSocketServer.Socket.Handlers { public class EmoteDetailsHandler : ISocketHandler { private const int EMOTE_BUFFER_SIZE = 5000; public int OperationCode { get; } = 7; private readonly ChannelManager _manager; private readonly HashSet _emotes; private readonly string[] _array; private readonly ILogger _logger; private readonly Mutex _mutex; private int _index; public EmoteDetailsHandler(ChannelManager manager, ILogger logger) { _manager = manager; _emotes = new HashSet(EMOTE_BUFFER_SIZE); _array = new string[EMOTE_BUFFER_SIZE]; _logger = logger; _mutex = new Mutex(); _index = -1; } public async Task Execute(WebSocketUser sender, T message, HermesSocketManager sockets) { if (message is not EmoteDetailsMessage data || sender.Id == null) return; if (data.Emotes == null || !data.Emotes.Any()) return; if (sender.Slave && !sender.WebLogin) { _logger.Warning($"Received message from a slave client [message type: emote details][sender id: {sender.Id}][sender session: {sender.SessionId}]"); return; } try { _mutex.WaitOne(); foreach (var entry in data.Emotes) { if (_emotes.Contains(entry.Key)) { data.Emotes.Remove(entry.Key); continue; } _emotes.Add(entry.Key); if (_index == _array.Length - 1) _index = -1; var previous = _array[++_index]; if (previous != null) { _emotes.Remove(previous); } _array[_index] = entry.Key; } } finally { _mutex.ReleaseMutex(); } if (!data.Emotes.Any()) return; var channel = _manager.Get(sender.Id); if (channel == null) return; foreach (var entry in data.Emotes) channel.Emotes.Set(entry.Key, new EmoteInfo() { Id = entry.Key, Name = entry.Value, UserId = channel.Id }); } } }