No description
Find a file
Astra c414e8a770 Whisper 0.1.0: private messages between players
/pm (/w) with names, #userid, SteamIDs, @me, @aim, @random, @randomt and
@randomct, /r to reply, and /block, /blocklist, /unblock. Lines use
CS2-Tags' rank prefixes and colours: >[[M] Kalus -> me] message. Gagged
players can't send; blocks stop everyone but staff. Messages are kept in
CS2-SimpleAdmin's database while History is on (css_whisper_history).
2026-10-05 13:13:58 +01:00
lib Whisper 0.1.0: private messages between players 2026-10-05 13:13:58 +01:00
Migrations Whisper 0.1.0: private messages between players 2026-10-05 13:13:58 +01:00
.gitignore Whisper 0.1.0: private messages between players 2026-10-05 13:13:58 +01:00
Config.cs Whisper 0.1.0: private messages between players 2026-10-05 13:13:58 +01:00
Database.cs Whisper 0.1.0: private messages between players 2026-10-05 13:13:58 +01:00
Ops.cs Whisper 0.1.0: private messages between players 2026-10-05 13:13:58 +01:00
README.md Whisper 0.1.0: private messages between players 2026-10-05 13:13:58 +01:00
release.sh Whisper 0.1.0: private messages between players 2026-10-05 13:13:58 +01:00
Tags.cs Whisper 0.1.0: private messages between players 2026-10-05 13:13:58 +01:00
Whisper.cs Whisper 0.1.0: private messages between players 2026-10-05 13:13:58 +01:00
Whisper.csproj Whisper 0.1.0: private messages between players 2026-10-05 13:13:58 +01:00
Writer.cs Whisper 0.1.0: private messages between players 2026-10-05 13:13:58 +01:00

Whisper

Private messages between players, for CounterStrikeSharp 1.0.376 (net10.0), alongside CS2-SimpleAdmin and CS2-Tags.

Commands

Chat Console What
/pm <target> <message>, /w css_pm, css_w Send a private message
/r <message> 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 <number> css_unblock Remove that block
css_whisper_history <on|off> @css/root and the server console: see 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.

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<ModuleVersion> (Forgejo token from FORGEJO_TOKEN or ../../.forgejo-token) builds from the committed source, tags it, and publishes Whisper-<tag>.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).