From 8bec658db4313d39f9a4bbaa1dd1431841241fce Mon Sep 17 00:00:00 2001 From: Astra Date: Sat, 3 Oct 2026 00:18:04 +0100 Subject: [PATCH] Targets: prefer an exact name, partial names for ungag/unmute/unsilence Part of 1.8.2b-zio15. --- CS2-SimpleAdmin/CS2-SimpleAdmin.cs | 8 +++++++- CS2-SimpleAdmin/Commands/basecomms.cs | 21 +++++++++++++++++++++ CS2-SimpleAdmin/Helper.cs | 5 ++++- README.md | 4 ++++ 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/CS2-SimpleAdmin/CS2-SimpleAdmin.cs b/CS2-SimpleAdmin/CS2-SimpleAdmin.cs index 23a403c..c4ea959 100644 --- a/CS2-SimpleAdmin/CS2-SimpleAdmin.cs +++ b/CS2-SimpleAdmin/CS2-SimpleAdmin.cs @@ -242,7 +242,13 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig p.PlayerName.Equals(command.GetArg(argument), StringComparison.OrdinalIgnoreCase)).ToList(); + if (exact.Count == 1) + return new TargetResult { Players = exact }; + + command.ReplyToCommand($"Multiple targets found for \"{command.GetArg(argument)}\": {string.Join(", ", matches.Players.Select(p => p.PlayerName))}."); return null; } diff --git a/CS2-SimpleAdmin/Commands/basecomms.cs b/CS2-SimpleAdmin/Commands/basecomms.cs index 6305f40..e3b5656 100644 --- a/CS2-SimpleAdmin/Commands/basecomms.cs +++ b/CS2-SimpleAdmin/Commands/basecomms.cs @@ -292,6 +292,13 @@ public partial class CS2_SimpleAdmin var nameMatches = Helper.GetPlayerFromName(pattern); var namePlayer = nameMatches.Count == 1 ? nameMatches.FirstOrDefault() : null; + // zio: several online players match part of the name; don't fall through to the offline search. + if (nameMatches.Count > 1) + { + command.ReplyToCommand($"Multiple targets found for \"{pattern}\": {string.Join(", ", nameMatches.Select(p => p.PlayerName))}."); + return; + } + if (namePlayer != null && namePlayer.IsValid) { PlayerPenaltyManager.RemovePenaltiesByType(namePlayer.Slot, PenaltyType.Gag); @@ -604,6 +611,13 @@ public partial class CS2_SimpleAdmin var nameMatches = Helper.GetPlayerFromName(pattern); var namePlayer = nameMatches.Count == 1 ? nameMatches.FirstOrDefault() : null; + // zio: several online players match part of the name; don't fall through to the offline search. + if (nameMatches.Count > 1) + { + command.ReplyToCommand($"Multiple targets found for \"{pattern}\": {string.Join(", ", nameMatches.Select(p => p.PlayerName))}."); + return; + } + if (namePlayer != null && namePlayer.IsValid) { PlayerPenaltyManager.RemovePenaltiesByType(namePlayer.Slot, PenaltyType.Mute); @@ -919,6 +933,13 @@ public partial class CS2_SimpleAdmin var nameMatches = Helper.GetPlayerFromName(pattern); var namePlayer = nameMatches.Count == 1 ? nameMatches.FirstOrDefault() : null; + // zio: several online players match part of the name; don't fall through to the offline search. + if (nameMatches.Count > 1) + { + command.ReplyToCommand($"Multiple targets found for \"{pattern}\": {string.Join(", ", nameMatches.Select(p => p.PlayerName))}."); + return; + } + if (namePlayer != null && namePlayer.IsValid) { PlayerPenaltyManager.RemovePenaltiesByType(namePlayer.Slot, PenaltyType.Silence); diff --git a/CS2-SimpleAdmin/Helper.cs b/CS2-SimpleAdmin/Helper.cs index 105be3b..1a04a9c 100644 --- a/CS2-SimpleAdmin/Helper.cs +++ b/CS2-SimpleAdmin/Helper.cs @@ -49,9 +49,12 @@ internal static class Helper } } + // zio: an exact (case-insensitive) name match, or else every player whose name contains it. public static List GetPlayerFromName(string name) { - return GetValidPlayers().FindAll(x => x.PlayerName.Equals(name, StringComparison.OrdinalIgnoreCase)); + var players = GetValidPlayers(); + var exact = players.FindAll(x => x.PlayerName.Equals(name, StringComparison.OrdinalIgnoreCase)); + return exact.Count > 0 ? exact : players.FindAll(x => x.PlayerName.Contains(name, StringComparison.OrdinalIgnoreCase)); } public static CCSPlayerController? GetPlayerFromSteamid64(ulong steamid) diff --git a/README.md b/README.md index ee39a72..b0669d1 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,10 @@ from the `build-1.8.2b` tag). Changes, all marked `zio:` in the code: database row expires. Upstream matched the two by exact end time, which never matched for one given in game (the database stores the time to the second), so it lasted until the player reconnected. A penalty marked passed also stops applying at once, not on the next 61-second tick. +- Targeting by part of a name: when several names contain it, one that is exactly it (any case) + is picked, and otherwise the reply lists the matches. `css_ungag`, `css_unmute` and + `css_unsilence` match online players by part of the name too (upstream needed the full name), + falling back to the offline search only when no one online matches. Publish with `FORGEJO_TOKEN=... ./release.sh v` (ModuleVersion is `1.8.2b-zioN`). It rebuilds from the committed source and uploads `SimpleAdmin-.tar.gz` to git.zio.sh