diff --git a/CS2-Tags.cs b/CS2-Tags.cs index af56b24..d6fc30d 100644 --- a/CS2-Tags.cs +++ b/CS2-Tags.cs @@ -44,7 +44,7 @@ public class CS2_Tags : BasePlugin public override string ModuleName => "CS2-Tags"; public override string ModuleDescription => "Add player tags easily in cs2 game"; public override string ModuleAuthor => "daffyy"; - public override string ModuleVersion => "1.0.4c-zio7"; + public override string ModuleVersion => "1.0.4c-zio4"; private static string TagsPath => Path.Combine(Server.GameDirectory, "csgo", "addons", "counterstrikesharp", "configs", "plugins", "CS2-Tags", "tags.json"); @@ -53,12 +53,6 @@ public class CS2_Tags : BasePlugin private List> _tags = new(); private ChatLabels _labels = new(); - // zio: GroupVerify, when it's installed (see ScoreboardTag). - private VerifyLink? _verify; - // zio: players whose own clan tag was replaced because they have no rank tag: slot -> their - // SteamID64, their own tag (to put back) and the tag set in its place. - private readonly Dictionary _replaced = new(); - public override void Load(bool hotReload) { LoadTags(); @@ -67,7 +61,6 @@ public class CS2_Tags : BasePlugin RegisterEventHandler(OnPlayerConnectFull); RegisterEventHandler(OnPlayerSpawn); RegisterEventHandler(OnPlayerDeath); - RegisterListener(slot => _replaced.Remove(slot)); AddCommandListener("say", OnPlayerChat); AddCommandListener("say_team", OnPlayerChatTeam); @@ -75,32 +68,6 @@ public class CS2_Tags : BasePlugin ApplyAllClanTags(); } - // zio: GroupVerify's API is only there after every plugin has loaded. - public override void OnAllPluginsLoaded(bool hotReload) - { - try - { - _verify = VerifyLink.TryCreate(player => SetPlayerClanTag(player), ApplyAllClanTags); - } - catch (Exception ex) when (ex is FileNotFoundException or FileLoadException or TypeLoadException) - { - // GroupVerifyApi isn't in shared/: tags work as they always have. - } - Logger.LogInformation(_verify == null - ? "GroupVerify isn't loaded: players without a rank tag keep their own" - : "Using GroupVerify's clan tag for verified players without a rank tag"); - // Only after a hot reload: at server start nobody is connected, and the engine's globals - // (which GetPlayers needs) don't exist yet. - if (_verify != null && hotReload) - ApplyAllClanTags(); - } - - public override void Unload(bool hotReload) - { - _verify?.Dispose(); - _verify = null; - } - private void LoadTags() { try @@ -262,44 +229,15 @@ public class CS2_Tags : BasePlugin private void SetPlayerClanTag(CCSPlayerController? player) { - if (player == null || !player.IsValid || player.IsBot || player.IsHLTV || player.AuthorizedSteamID == null) return; - - var steamId = player.AuthorizedSteamID.SteamId64; - if (_replaced.TryGetValue(player.Slot, out var r) && r.SteamId != steamId) - { - _replaced.Remove(player.Slot); // left over from whoever had the slot before - r = default; - } + if (player == null || !player.IsValid) return; var tag = FindTag(player); - string? want = tag is { Scoreboard: not "" } ? tag.Scoreboard : ClanTagFor(player); - if (want == null) - { - // Nothing to show for them any more: put their own tag back if it was replaced. - if (!_replaced.Remove(player.Slot)) return; - want = r.Own ?? ""; - } - else if (tag is not { Scoreboard: not "" }) - { - // Replacing their own tag. Keep it, unless what's there is what was set last time. - var own = _replaced.ContainsKey(player.Slot) && player.Clan == r.Set ? r.Own ?? "" : player.Clan ?? ""; - _replaced[player.Slot] = (steamId, own, want); - } + if (tag == null || tag.Scoreboard == "" || player.Clan == tag.Scoreboard) return; - if (player.Clan == want) return; - player.Clan = want; + player.Clan = tag.Scoreboard; Utilities.SetStateChanged(player, "CCSPlayerController", "m_szClan"); } - // zio: for a player with no rank tag, while GroupVerify has a clan tag set: that tag if they're - // verified, none at all if not. null when no clan tag is set, leaving their own tag alone. - private string? ClanTagFor(CCSPlayerController player) - { - var clan = _verify?.ClanTag ?? ""; - if (clan == "") return null; - return _verify!.IsVerified(player) ? clan : ""; - } - private string TeamLabel(int teamNum) { return teamNum switch @@ -342,8 +280,8 @@ public class CS2_Tags : BasePlugin // Written to configs/plugins/CS2-Tags/tags.json on first load. Our CS2-SimpleAdmin rank groups, // highest first; guardian (VIP) comes after staff so a staff member's rank tag wins. The - // chat prefixes match CS2-SimpleAdmin's rank tags in staff chat ("[Mod] name: message"). No - // brackets on the scoreboard: CS2 adds its own around the clan tag. + // abbreviations match CS2-SimpleAdmin's staff chat ("[M] name: message"); the scoreboard spells + // the rank out. No brackets there: CS2 adds its own around the clan tag. private const string DefaultTagsJson = """ { "chat": { @@ -354,15 +292,15 @@ public class CS2_Tags : BasePlugin "team_none": "(NONE)" }, "tags": { - "#rank/owner": { "prefix": "{Default}[{Lime}O{Default}]", "nick_color": "", "message_color": "", "scoreboard": "OWNER" }, - "#rank/senioradmin": { "prefix": "{Default}[{Lime}S.Admin{Default}]", "nick_color": "", "message_color": "", "scoreboard": "S.ADMIN" }, - "#rank/admin": { "prefix": "{Default}[{Lime}Admin{Default}]", "nick_color": "", "message_color": "", "scoreboard": "ADMIN" }, - "#rank/trialadmin": { "prefix": "{Default}[{Lime}T.Admin{Default}]", "nick_color": "", "message_color": "", "scoreboard": "T.ADMIN" }, - "#rank/mod": { "prefix": "{Default}[{Lime}Mod{Default}]", "nick_color": "", "message_color": "", "scoreboard": "MOD" }, - "#rank/trialmod": { "prefix": "{Default}[{Lime}T.Mod{Default}]", "nick_color": "", "message_color": "", "scoreboard": "T.MOD" }, - "#rank/helper": { "prefix": "{Default}[{Lime}Helper{Default}]", "nick_color": "", "message_color": "", "scoreboard": "HELPER" }, - "#rank/guardian": { "prefix": "{Default}[{Lime}Guardian{Default}]", "nick_color": "", "message_color": "", "scoreboard": "GUARDIAN" }, - "everyone": { "prefix": "", "nick_color": "", "message_color": "", "scoreboard": "" } + "#rank/owner": { "prefix": "{Default}[{Lime}O{Default}]", "nick_color": "", "message_color": "", "scoreboard": "Owner" }, + "#rank/senioradmin": { "prefix": "{Default}[{Lime}SA{Default}]", "nick_color": "", "message_color": "", "scoreboard": "Sen.Admin" }, + "#rank/admin": { "prefix": "{Default}[{Lime}A{Default}]", "nick_color": "", "message_color": "", "scoreboard": "Admin" }, + "#rank/trialadmin": { "prefix": "{Default}[{Lime}TA{Default}]", "nick_color": "", "message_color": "", "scoreboard": "T.Admin" }, + "#rank/mod": { "prefix": "{Default}[{Lime}M{Default}]", "nick_color": "", "message_color": "", "scoreboard": "Mod" }, + "#rank/trialmod": { "prefix": "{Default}[{Lime}TM{Default}]", "nick_color": "", "message_color": "", "scoreboard": "T.Mod" }, + "#rank/helper": { "prefix": "{Default}[{Lime}H{Default}]", "nick_color": "", "message_color": "", "scoreboard": "Helper" }, + "#rank/guardian": { "prefix": "{Default}[{Lime}G{Default}]", "nick_color": "", "message_color": "", "scoreboard": "Guardian" }, + "everyone": { "prefix": "", "nick_color": "", "message_color": "", "scoreboard": "" } } } """; diff --git a/CS2-Tags.csproj b/CS2-Tags.csproj index f162b53..2dca71c 100644 --- a/CS2-Tags.csproj +++ b/CS2-Tags.csproj @@ -15,12 +15,6 @@ runtime compile; build; native; contentfiles; analyzers; buildtransitive - - - lib/GroupVerifyApi.dll - false - diff --git a/README.md b/README.md index 79e6cad..e7c658e 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,6 @@ CounterStrikeSharp 1.0.375 (net10.0) and meant to run alongside CS2-SimpleAdmin. (the game prints it), in both all and team chat. The old `team_chat` key is gone. - `css_tags_reload` works from the server console and for `@css/root` admins, and reapplies scoreboard tags straight away. Hot reload applies tags to players already connected. -- Verification tags from GroupVerify (see below). - Removed `css_tag_mute`/`css_tag_unmute` and the `@` team-chat admin chat. CS2-SimpleAdmin already does both, and its catch-all command listener runs first. CSS always runs those before per-command listeners, so gagged players' messages never reach this plugin. @@ -27,18 +26,17 @@ CounterStrikeSharp 1.0.375 (net10.0) and meant to run alongside CS2-SimpleAdmin. ## Configuration `addons/counterstrikesharp/configs/plugins/CS2-Tags/tags.json`, written on first load with a tag -for each of our SimpleAdmin rank groups. The chat prefixes are the same rank tags SimpleAdmin uses in -staff chat (O, S.Admin, Admin, T.Admin, Mod, T.Mod, Helper, Guardian): `[Mod] name: message`, -with a white `[ ]`, lime rank and team-coloured name. The scoreboard shows OWNER, S.ADMIN, ADMIN, -T.ADMIN, MOD, T.MOD, HELPER and GUARDIAN (CS2 adds the brackets itself). An example with other -kinds of key: +for each of our SimpleAdmin rank groups. They use the same abbreviations as SimpleAdmin's staff chat +(O, SA, A, TA, M, TM, H, G): `[M] name: message` in chat, with a white `[ ]`, lime rank and +team-coloured name. The scoreboard spells the rank out: Owner, Sen.Admin, Admin, T.Admin, Mod, +T.Mod, Helper and Guardian (CS2 adds the brackets itself). An example with other kinds of key: ```jsonc { "tags": { "76561198000000000": { "prefix": "{Magenta}[Dev]", "nick_color": "", "message_color": "", "scoreboard": "Dev" }, - "#rank/owner": { "prefix": "{Default}[{Lime}O{Default}]", "nick_color": "", "message_color": "", "scoreboard": "OWNER" }, - "#rank/mod": { "prefix": "{Default}[{Lime}Mod{Default}]", "nick_color": "", "message_color": "", "scoreboard": "MOD" }, + "#rank/owner": { "prefix": "{Default}[{Lime}O{Default}]", "nick_color": "", "message_color": "", "scoreboard": "Owner" }, + "#rank/mod": { "prefix": "{Default}[{Lime}M{Default}]", "nick_color": "", "message_color": "", "scoreboard": "Mod" }, "@css/vip": { "prefix": "{Gold}[VIP]", "nick_color": "", "message_color": "", "scoreboard": "VIP" }, "everyone": { "prefix": "", "nick_color": "", "message_color": "", "scoreboard": "" } } @@ -80,25 +78,6 @@ Group membership comes from CS2-SimpleAdmin (`css_addadmin ... -g`, `css_addgrou `css_reloadadmins`). After changing ranks or `tags.json`, run `css_tags_reload` to reapply scoreboard tags without waiting for a respawn. -## Verified players' clan tag (GroupVerify) - -When GroupVerify (`plugins/GroupVerify`) is installed and has a clan tag set (`css_gv_clantag`, -or the web panel's Verification page), players **without a rank tag** get it in place of their own -Steam group tag: - -| | verified | not verified | -|-----------------------------------|----------------|----------------| -| a scoreboard tag from `tags.json` | their rank tag | their rank tag | -| everyone else | the clan tag | no tag at all | - -Staff keep their rank tag either way. With no clan tag set, GroupVerify turned off or not -installed, everyone else keeps their own tag, as before; turning the clan tag off puts back the -tag each player had. Tags update as soon as someone's verification or the clan tag changes. - -GroupVerify's API is a compile-only reference (`lib/GroupVerifyApi.dll`, a copy of -`plugins/GroupVerify`'s build; GroupVerify installs the real one in `shared/GroupVerifyApi`). -CS2-Tags loads without it. - ## Commands - `css_tags_reload` (`@css/root` or server console) - reload `tags.json` and reapply scoreboard tags. @@ -112,4 +91,4 @@ FORGEJO_TOKEN=... ./release.sh v `release.sh` rebuilds from the committed source and publishes `CS2-Tags-.tar.gz`, laid out like `game/csgo/`, to https://git.zio.sh/cs2/CS2-Tags. The tag must equal `v` -(`v1.0.4c-zio7` now). +(`v1.0.4c-zio4` now). diff --git a/VerifyLink.cs b/VerifyLink.cs deleted file mode 100644 index 5935ba1..0000000 --- a/VerifyLink.cs +++ /dev/null @@ -1,51 +0,0 @@ -using CounterStrikeSharp.API.Core; -using GroupVerifyApi; - -namespace CS2_Tags; - -// zio: GroupVerify's API (shared/GroupVerifyApi). Kept in its own class, and only created inside a -// try in OnAllPluginsLoaded, so CS2-Tags still loads, and tags as before, when GroupVerify isn't -// installed and its assembly can't be found. -internal sealed class VerifyLink : IDisposable -{ - private readonly IGroupVerifyApi _api; - private readonly Action _playerChanged; - private readonly Action _tagChanged; - - private VerifyLink(IGroupVerifyApi api, Action playerChanged, Action tagChanged) - { - _api = api; - _playerChanged = playerChanged; - _tagChanged = tagChanged; - _api.OnVerifiedChanged += OnVerifiedChanged; - _api.OnClanTagChanged += _tagChanged; - } - - // The API, or null when GroupVerify isn't loaded. - public static VerifyLink? TryCreate(Action playerChanged, Action tagChanged) - { - IGroupVerifyApi? api; - try - { - api = IGroupVerifyApi.Capability.Get(); - } - catch (KeyNotFoundException) - { - return null; - } - return api == null ? null : new VerifyLink(api, playerChanged, tagChanged); - } - - // The tag verified players without a rank get, "" while none is set or GroupVerify is off. - public string ClanTag => _api.ClanTag; - - public bool IsVerified(CCSPlayerController player) => _api.IsVerified(player); - - private void OnVerifiedChanged(CCSPlayerController player, VerifyStatus status) => _playerChanged(player); - - public void Dispose() - { - _api.OnVerifiedChanged -= OnVerifiedChanged; - _api.OnClanTagChanged -= _tagChanged; - } -} diff --git a/lib/GroupVerifyApi.dll b/lib/GroupVerifyApi.dll deleted file mode 100644 index 6f187f9..0000000 Binary files a/lib/GroupVerifyApi.dll and /dev/null differ diff --git a/release.sh b/release.sh index c3f479f..06e9b35 100755 --- a/release.sh +++ b/release.sh @@ -19,13 +19,8 @@ set -euo pipefail FORGEJO_URL="https://git.zio.sh" OWNER="cs2" REPO="CS2-Tags" -# Needs write:repository. Only uploading needs it; downloading from the public repo doesn't. From the -# environment, or else from .forgejo-token in the cs2/ folder above every plugin (outside their -# repos, mode 600). Don't commit a real token. -TOKEN_FILE="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")/../../.forgejo-token" -if [[ -z "${FORGEJO_TOKEN:-}" && -r "$TOKEN_FILE" ]]; then - FORGEJO_TOKEN="$(tr -d '[:space:]' < "$TOKEN_FILE")" -fi +# Placeholder - replace, or set FORGEJO_TOKEN in the environment instead. Needs write:repository. +# Only uploading needs it; downloading from the public repo doesn't. Don't commit a real token. FORGEJO_TOKEN="${FORGEJO_TOKEN:-CHANGE_ME_FORGEJO_TOKEN}" # Only these ship from the publish output. CounterStrikeSharp.API.dll is excluded by the csproj @@ -42,7 +37,7 @@ if [[ -z "$TAG" ]]; then exit 1 fi if [[ "$FORGEJO_TOKEN" == "CHANGE_ME_FORGEJO_TOKEN" ]]; then - echo "Set FORGEJO_TOKEN (export it, or put it in $TOKEN_FILE) first." >&2 + echo "Set FORGEJO_TOKEN (edit release.sh or export it) first." >&2 exit 1 fi for tool in podman jq curl git; do