From b68113733e65b72acd94de09ff4d550f4d04d368 Mon Sep 17 00:00:00 2001 From: Astra Date: Sun, 27 Sep 2026 18:10:22 +0100 Subject: [PATCH] WebPanelBridge 0.2.0: leave out admins hidden with CS2-SimpleAdmin's css_hide --- README.md | 9 ++++++--- WebPanelBridge.cs | 21 +++++++++++++++++++-- WebPanelBridge.csproj | 5 +++++ lib/CS2-SimpleAdminApi.dll | Bin 0 -> 12800 bytes 4 files changed, 30 insertions(+), 5 deletions(-) create mode 100644 lib/CS2-SimpleAdminApi.dll diff --git a/README.md b/README.md index 2e956ac..070ffcd 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,13 @@ Reports live match state to [simpleadmin-web](../../go/simpleadmin-web) over RCON: the hostname, map, team scores, warmup state, and each connected player's userid, name, SteamID64, team, -kills, deaths and ping. It changes nothing in the game. +kills, deaths and ping. Admins hidden with CS2-SimpleAdmin's `css_hide` are left out entirely, as if +they weren't connected, so the panel never lists or counts them. It changes nothing in the game. -Built for CounterStrikeSharp **1.0.375** (`net10.0`) on Metamod:Source 2.0.0.1469. No other -dependencies. +Built for CounterStrikeSharp **1.0.375** (`net10.0`) on Metamod:Source 2.0.0.1469. It uses +CS2-SimpleAdmin's shared API (`CS2-SimpleAdminApi`) to spot hidden admins. `lib/CS2-SimpleAdminApi.dll` +is a compile-time copy of the server's `shared/` one and isn't shipped. Without SimpleAdmin loaded, +everyone is listed. ## The command diff --git a/WebPanelBridge.cs b/WebPanelBridge.cs index b9e8086..ad5263b 100644 --- a/WebPanelBridge.cs +++ b/WebPanelBridge.cs @@ -3,19 +3,22 @@ using System.Text.Json.Serialization; using CounterStrikeSharp.API; using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core.Attributes.Registration; +using CounterStrikeSharp.API.Core.Capabilities; using CounterStrikeSharp.API.Modules.Commands; using CounterStrikeSharp.API.Modules.Cvars; using CounterStrikeSharp.API.Modules.Utils; +using CS2_SimpleAdminApi; namespace WebPanelBridge; // Reports live match state to simpleadmin-web over RCON. The server console command prints one // JSON object per line, each prefixed with "wpb ", so the web panel can pick them out of whatever -// else lands in the RCON response. Nothing here changes game state. +// else lands in the RCON response. Admins hidden with CS2-SimpleAdmin's css_hide are left out, as if +// they weren't connected. Nothing here changes game state. public class WebPanelBridge : BasePlugin { public override string ModuleName => "WebPanelBridge"; - public override string ModuleVersion => "0.1.0"; + public override string ModuleVersion => "0.2.0"; public override string ModuleAuthor => "astra"; public override string ModuleDescription => "Live server status for simpleadmin-web, over RCON"; @@ -27,6 +30,8 @@ public class WebPanelBridge : BasePlugin DefaultIgnoreCondition = JsonIgnoreCondition.Never, }; + private static readonly PluginCapability SimpleAdminCapability = new("simpleadmin:api"); + private record ServerLine(int V, string Hostname, string Map, int MaxPlayers, int ScoreT, int ScoreCt, bool Warmup); private record PlayerLine(int Userid, string Name, string Steamid, int Team, int Kills, int Deaths, uint Ping, bool Bot); @@ -56,10 +61,22 @@ public class WebPanelBridge : BasePlugin scoreT, scoreCt, warmup); command.ReplyToCommand(Prefix + JsonSerializer.Serialize(server, JsonOptions)); + // Fetched on every call, so reloading SimpleAdmin doesn't leave a stale instance here. + ICS2_SimpleAdminApi? simpleAdmin = null; + try + { + simpleAdmin = SimpleAdminCapability.Get(); + } + catch (KeyNotFoundException) + { + } + foreach (var player in Utilities.GetPlayers()) { if (player is not { IsValid: true, IsHLTV: false } || player.Connected != PlayerConnectedState.Connected) continue; + if (!player.IsBot && simpleAdmin?.IsAdminSilent(player) == true) + continue; var stats = player.ActionTrackingServices?.MatchStats; var line = new PlayerLine( diff --git a/WebPanelBridge.csproj b/WebPanelBridge.csproj index d68d986..8da7d84 100644 --- a/WebPanelBridge.csproj +++ b/WebPanelBridge.csproj @@ -13,5 +13,10 @@ runtime compile; build; native; contentfiles; analyzers; buildtransitive + + + lib/CS2-SimpleAdminApi.dll + false + diff --git a/lib/CS2-SimpleAdminApi.dll b/lib/CS2-SimpleAdminApi.dll new file mode 100644 index 0000000000000000000000000000000000000000..3b594c763973e54689c774e53a8af74e65c4b7f1 GIT binary patch literal 12800 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 literal 0 HcmV?d00001