# Whisper Private messages between players, for CounterStrikeSharp 1.0.376 (net10.0), alongside CS2-SimpleAdmin and CS2-Tags. ## Commands | Chat | Console | What | |---|---|---| | `/pm `, `/w` | `css_pm`, `css_w` | Send a private message | | `/r ` | `css_r` | Reply to whoever last messaged you | | `/block <#userid\|steamid64>` | `css_block` | Stop a player messaging you. A SteamID64 works while they're offline | | `/blocklist` | `css_blocklist` | Your blocks, numbered from 1 | | `/unblock ` | `css_unblock` | Remove that block | | | `css_whisper_history ` | `@css/root` and the server console: see [History](#history) | `!` works the same as `/`. The plugin takes these commands out of chat itself, so `!pm` never shows the message to everyone the way a `!` command normally would. **Targets** are one player: - part of a name (an exact match wins when several names contain it), or `"a name with spaces"`; - `#userid`, as `css_players` and `status` show it, a SteamID64 (with or without `#`) or a `STEAM_` ID; - `@me`, `@aim` (who you're looking at), `@randomt`, `@randomct`, or `@random` (anyone on any team, alive, dead or spectating). Group targets (`@all`, `@t`, `@ct`, `@spec`, `@alive`, `@dead`, `@bots`, `@human`, `@!me`) are refused. Bots and SourceTV can't be messaged. Admins hidden with SimpleAdmin's `css_hide` can't be found, so a message doesn't give them away; staff (`StaffPermission`) still can. Random picks never land on you or a hidden admin. ## Messages ``` >[[M] Kalus → me] rotate b what Bravo sees >[[M] Kalus → Bravo] rotate b what Kalus sees ``` The sender's rank prefix, name colour (`nick_color`, the team colour when empty) and message colour (`message_color`) come from CS2-Tags' `tags.json`, picked the way CS2-Tags picks them: SteamID64, then the first `#group`/`@permission` key in file order, then `everyone`. A player with no prefix shows as `>[Kalus → me]`. The recipient's name is in their own `nick_color`. The file is reread when it changes. No dead or team labels. - Dead players can message anyone. - Gagged or silenced players (CS2-SimpleAdmin) can't send. - A player who has blocked the sender isn't messaged, and the sender is told so. Staff get through. - One message per `CooldownSeconds`, at most `MaxMessageLength` characters. ## Configuration `configs/plugins/Whisper/Whisper.json`, written on first load: | Setting | Default | Meaning | |---|---|---| | `History` | `true` | Keep each message in `wh_messages`, see below | | `Open`, `Arrow`, `Me`, `Close` | `{Default}>[`, `{Default}→`, `{Default}me`, `{Default}]` | The parts of the line around the names. Colour tags as in `tags.json` | | `TagsFile` | `configs/plugins/CS2-Tags/tags.json` | Relative to `addons/counterstrikesharp/` | | `CooldownSeconds` | `1` | | | `MaxMessageLength` | `200` | | | `MaxBlocks` | `100` | Per player | | `StaffPermission` | `@css/generic` | Gets through blocks and can find hidden admins | | `SpoolMaxEntries` | `20000` | Writes kept on disk while the database is down | ## Storage Everything is in CS2-SimpleAdmin's MySQL database, over its connection string (from its API), in tables created on first load and tracked in `wh_migrations`. All times are UTC. ### History With `History` on, each `/pm` and `/r`, sent or not, is a row in `wh_messages`: when (`sent_at`), `server_id` (SimpleAdmin's), `map`, the sender's and recipient's SteamID64, name, team (0 none, 1 spectator, 2 T, 3 CT) and whether alive, the `target` as typed, the `message`, and the `result`: `sent`, `blocked`, `gagged`, `cooldown`, `too_long`, `no_target`, `ambiguous` or `group_target`. The recipient columns are `NULL` when no single player was found. `css_whisper_history off` stops it at once and saves the setting to `Whisper.json`; rows already kept stay. Writes go in order on a background task and spool to `plugins/Whisper/spool.jsonl` while the database is down. ```sql SELECT sent_at, map, sender_name, sender_steamid64, sender_team, sender_alive, recipient_name, recipient_steamid64, recipient_team, recipient_alive, message, result FROM wh_messages ORDER BY sent_at DESC LIMIT 50; ``` ### Blocks `wh_blocks`: blocker, blocked, the blocked player's name when blocked (empty for an offline SteamID64), and when. Kept whatever `History` says. A player's list is read when they join. ## Building and releasing `../../build.sh` from this folder builds into `compiled/Whisper/`. `lib/CS2-SimpleAdminApi.dll` is a compile-only copy of the one SimpleAdmin installs in `shared/`. `./release.sh v` (Forgejo token from `FORGEJO_TOKEN` or `../../.forgejo-token`) builds from the committed source, tags it, and publishes `Whisper-.tar.gz` (laid out like `game/csgo/`) on git.zio.sh. The server installs it from there (`WHISPER_VERSION` in the server repo's `update_plugins.sh`).