Targets: prefer an exact name, partial names for ungag/unmute/unsilence

Part of 1.8.2b-zio15.
This commit is contained in:
Astra 2026-10-03 00:18:04 +01:00
parent dc5ad30952
commit bbda9af75c
4 changed files with 36 additions and 2 deletions

View file

@ -242,7 +242,13 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig<CS2_SimpleAdmin
if (matches.Count() == 1)
return matches;
command.ReplyToCommand($"Multiple targets found for \"{command.GetArg(argument)}\".");
// zio: a name that is exactly the pattern wins over names that only contain it, so "duck"
// still finds "Duck" when "Ducky" is also on.
var exact = matches.Players.Where(p => 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;
}

View file

@ -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);

View file

@ -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<CCSPlayerController> 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)

View file

@ -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>` (ModuleVersion is `1.8.2b-zioN`).
It rebuilds from the committed source and uploads `SimpleAdmin-<tag>.tar.gz` to git.zio.sh