diff --git a/CS2-SimpleAdmin.example.json b/CS2-SimpleAdmin.example.json index 5c2ea01..ca2decc 100644 --- a/CS2-SimpleAdmin.example.json +++ b/CS2-SimpleAdmin.example.json @@ -1,6 +1,5 @@ -// This configuration was automatically generated by CounterStrikeSharp for plugin 'CS2-SimpleAdmin', at 2024/10/09 05:40:44 { - "ConfigVersion": 24, + "ConfigVersion": 25, "DatabaseHost": "", "DatabasePort": 3306, "DatabaseUser": "", @@ -14,6 +13,7 @@ "TimeMode": 1, "DisableDangerousCommands": true, "MaxBanDuration": 10080, + "MaxMuteDuration": 10080, "ExpireOldIpBans": 0, "ReloadAdminsEveryMapChange": false, "DisconnectedPlayersHistoryCount": 10, @@ -21,7 +21,8 @@ "ShowBanMenuIfNoTime": true, "UserMessageGagChatType": false, "CheckMultiAccountsByIp": true, - "AdditionalCommandsToLog": [] + "AdditionalCommandsToLog": [], + "HideStealthPlayersFromSpecList": false }, "EnableMetrics": true, "EnableUpdateCheck": true, diff --git a/CS2-SimpleAdmin/Config.cs b/CS2-SimpleAdmin/Config.cs index 91ee7dc..0f96b58 100644 --- a/CS2-SimpleAdmin/Config.cs +++ b/CS2-SimpleAdmin/Config.cs @@ -245,11 +245,14 @@ public class OtherSettings [JsonPropertyName("AdditionalCommandsToLog")] public List AdditionalCommandsToLog { get; set; } = new(); + + [JsonPropertyName("HideStealthPlayersFromSpecList")] + public bool HideStealthPlayersFromSpecList {get; set; } = false; } public class CS2_SimpleAdminConfig : BasePluginConfig { - [JsonPropertyName("ConfigVersion")] public override int Version { get; set; } = 24; + [JsonPropertyName("ConfigVersion")] public override int Version { get; set; } = 25; [JsonPropertyName("DatabaseHost")] public string DatabaseHost { get; set; } = ""; diff --git a/CS2-SimpleAdmin/Events.cs b/CS2-SimpleAdmin/Events.cs index edfb77c..5c2c18e 100644 --- a/CS2-SimpleAdmin/Events.cs +++ b/CS2-SimpleAdmin/Events.cs @@ -18,12 +18,16 @@ namespace CS2_SimpleAdmin; public partial class CS2_SimpleAdmin { private bool _serverLoading; + + public List CachedPlayers = new(); private void RegisterEvents() { RegisterListener(OnMapStart); RegisterListener(OnClientConnect); RegisterListener(OnGameServerSteamAPIActivated); + if (Config.OtherSettings.HideStealthPlayersFromSpecList) + RegisterListener(CheckTransmitListener); if (Config.OtherSettings.UserMessageGagChatType) HookUserMessage(118, HookUmChat); @@ -59,6 +63,44 @@ public partial class CS2_SimpleAdmin new ServerManager().LoadServerData(); } + + private void CheckTransmitListener(CCheckTransmitInfoList infoList) + { + // Code taken from admin esp by aqua + foreach ((CCheckTransmitInfo info, CCSPlayerController? player) in infoList) + { + if (player is null || player.IsValid is not true) continue; + + //itereate cached players + for (int i = 0; i < CachedPlayers.Count(); i++) { + //leave self's observerPawn so it can spectate and check if feature is enabled + //we are clearing the whole spectator list as it doesn't work relaibly per person basis + if (CachedPlayers[i] is null || CachedPlayers[i].IsValid is not true) continue; + + //check if it 'us' in the current context and do the magic only if it's not + if (CachedPlayers[i].Slot != player.Slot) { + + //get the target's pawn + var targetPawn = CachedPlayers[i].PlayerPawn.Value; + if (targetPawn is null || targetPawn.IsValid is not true) continue; + + //get the target's observerpawn + var targetObserverPawn = CachedPlayers[i].ObserverPawn; + if (targetObserverPawn is null + || targetObserverPawn.IsValid is not true + || targetObserverPawn.Value is null + || targetObserverPawn.Value.OriginalController.Value is null + || !SilentPlayers.Contains(targetObserverPawn.Value.OriginalController.Value.Slot)) continue; + + //we clear the spec list via clearing all of the observerTarget' pawns indexes + //from the Observer_services class that any cheat uses as a method to campare + //against current players in the server + info.TransmitEntities.Remove((int)targetObserverPawn.Index); + } + } + } + } + [GameEventHandler(HookMode.Pre)] public HookResult OnClientDisconnect(EventPlayerDisconnect @event, GameEventInfo info) { @@ -97,6 +139,7 @@ public partial class CS2_SimpleAdmin PlayerPenaltyManager.RemoveAllPenalties(player.Slot); + CachedPlayers.Remove(player); SilentPlayers.Remove(player.Slot); GodPlayers.Remove(player.Slot); SpeedPlayers.Remove(player.Slot); @@ -155,6 +198,8 @@ public partial class CS2_SimpleAdmin if (player == null || !player.IsValid || player.IsBot) return HookResult.Continue; + + CachedPlayers.Add(player); if (player.UserId.HasValue && PlayersInfo.TryGetValue(player.UserId.Value, out PlayerInfo? value) && value.WaitingForKick) diff --git a/CS2-SimpleAdmin/Managers/ServerManager.cs b/CS2-SimpleAdmin/Managers/ServerManager.cs index 7779d13..28d522d 100644 --- a/CS2-SimpleAdmin/Managers/ServerManager.cs +++ b/CS2-SimpleAdmin/Managers/ServerManager.cs @@ -24,7 +24,7 @@ public class ServerManager CS2_SimpleAdmin.Instance.AddTimer(1.2f, () => { if (CS2_SimpleAdmin.ServerLoaded || CS2_SimpleAdmin.ServerId != null || CS2_SimpleAdmin.Database == null) return; - + if (_getIpTryCount > 32 && Helper.GetServerIp().StartsWith("0.0.0.0") || string.IsNullOrEmpty(Helper.GetServerIp())) { CS2_SimpleAdmin._logger?.LogError("Unable to load server data - can't fetch ip address!"); @@ -40,13 +40,22 @@ public class ServerManager if (_getIpTryCount <= 32 && (string.IsNullOrEmpty(ipAddress) || ipAddress.StartsWith("0.0.0"))) { _getIpTryCount++; - + LoadServerData(); return; } } - string? address = !string.IsNullOrWhiteSpace(CS2_SimpleAdmin.Instance.Config.DefaultServerIP) ? CS2_SimpleAdmin.Instance.Config.DefaultServerIP : $"{ipAddress}:{ConVar.Find("hostport")?.GetPrimitiveValue()}"; + string address = CS2_SimpleAdmin.Instance.Config.DefaultServerIP; + + if(string.IsNullOrWhiteSpace(CS2_SimpleAdmin.Instance.Config.DefaultServerIP) || !CS2_SimpleAdmin.Instance.Config.DefaultServerIP.Contains(":")) + { + if(!string.IsNullOrWhiteSpace(CS2_SimpleAdmin.Instance.Config.DefaultServerIP) && !CS2_SimpleAdmin.Instance.Config.DefaultServerIP.Contains(":")) + CS2_SimpleAdmin._logger?.LogError("DefaultServerIP was set but no port was provided!"); + + address = $"{ipAddress}:{ConVar.Find("hostport")?.GetPrimitiveValue()}"; + } + var hostname = ConVar.Find("hostname")!.StringValue; var rcon = ConVar.Find("rcon_password")!.StringValue; CS2_SimpleAdmin.IpAddress = address;