using HintServiceMeow.Core.Enum; using HintServiceMeow.Core.Models.Hints; using HintServiceMeow.Core.Utilities; using LabApi.Events.Arguments.PlayerEvents; using LabApi.Features; using LabApi.Features.Console; using LabApi.Features.Wrappers; using MEC; using PlayerRoles; namespace VisibleSpectators; /// /// Handles spectator hint management and updates for players. /// public class SpectatorManager { private readonly SpectatorConfig _config; private readonly Dictionary _spectatorHints = new(); public int YCoordinate { get; set; } = 100; public SpectatorManager(SpectatorConfig config) { _config = config; } public IEnumerator KeepUpdatingSpectators() { while (true) { UpdateSpectators(); yield return Timing.WaitForSeconds(1); } // ReSharper disable once IteratorNeverReturns } public void OnSpectate(PlayerChangedSpectatorEventArgs ev) { UpdateSpectators(ev.OldTarget); UpdateSpectators(ev.NewTarget); UpdateSpectators(ev.Player); } public void OnJoin(PlayerJoinedEventArgs ev) { AddPlayerHint(ev.Player); } private void UpdateSpectators() { foreach (var player in GetPlayers()) UpdateSpectators(player); } private void AddPlayerHint(Player player) { var hint = new Hint { Text = $"{_config.HeaderMessage}\n{_config.NoSpectatorsMessage}", Alignment = HintAlignment.Right, YCoordinate = YCoordinate, Hide = true }; var playerDisplay = PlayerDisplay.Get(player); playerDisplay.AddHint(hint); _spectatorHints[player] = hint; } private void UpdateSpectators(Player player) { if (player == null) return; if (!_spectatorHints.ContainsKey(player)) AddPlayerHint(player); var spectators = _config.NoSpectatorsMessage; try { spectators = string.Join("\n", player.CurrentSpectators.Where(PlayerDisplayUtil.IsNotOverwatch).Select(PlayerDisplayUtil.PlayerToDisplay)); if (player.Role == RoleTypeId.Spectator) spectators = player.CurrentlySpectating == null ? _config.NoSpectatorsMessage : string.Join("\n", player.CurrentlySpectating?.CurrentSpectators.Where(PlayerDisplayUtil.IsNotOverwatch) .Select(PlayerDisplayUtil.PlayerToDisplay) ?? Array.Empty()); } catch (Exception e) { Logger.Error(e); } if (spectators.Length < 2) spectators = _config.NoSpectatorsMessage; _spectatorHints[player].Text = $"{_config.HeaderMessage}\n{spectators}"; _spectatorHints[player].Hide = player.Role is RoleTypeId.Destroyed or RoleTypeId.None; _spectatorHints[player].YCoordinate = YCoordinate + player.CurrentSpectators.Count * 10; } private static Player[] GetPlayers() { return Player.ReadyList.Where(PlayerDisplayUtil.IsNotOverwatch).Where(x => x != null).ToArray(); } }