Server: tools can be locked for single players, and for a throwdown's players

The server can take noclip (with teleporting), No Bail, the boosts and the
player's own physics tuning from one player while everyone else keeps what
the server allows: for fair throwdowns on a server that allows them for free
skating. Server only: a locked player gets a roster of their own with the
tool off (players with the same locks share one) and permissions without
"movement", so their role cannot give it back. Players without locks get
exactly the roster they got before.

- lock <player|SteamID64> <tool[,tool...]|all>, unlock <player|SteamID64>
  [<tools>|all], locks: from the console, or an admin in chat. In memory
  only; locks end when the player leaves. Logged as
  "[lock] <name> (<SteamID64>): nobail, boosts locked by <who>".
- players.throwdown_locks (default []): tools locked for the players of a
  throwdown from its start until they quit, it ends or they leave
  (console: throwdown-locks <tools>|off).
- Tests: Server/Test/server_lock_tests.cpp, and the key in the config tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PreNfxwh21xyPp8EA72cUN
This commit is contained in:
Robin MoellerandClaude Opus 5.5 committed 2026-10-13 13:33:55 +02:00
1 parent 0f8af62710
commit 3bfabed705
13 files changed
+720 -18

No files matched your search

+1 -1
View File
@@ -150,7 +150,7 @@ void Host::chat_command(Guest &guest, std::string_view line) {
if (config_.parties) text += "/party: your party (invite, accept, leave...; /party help); /p <message>: party chat\n";
if (const auto *role = role_of(guest.member.id); staff(role))
text += role->all_commands
? "Admins: any server command as /<command>, e.g. /kick, /map, /tpall, /votes, /announce, /announce-to, /msg, /msg-party, /msg-admins\n"
? "Admins: any server command as /<command>, e.g. /kick, /map, /tpall, /votes, /announce, /announce-to, /msg, /msg-party, /msg-admins, /lock, /unlock, /locks\n"
: "Your role (" + role->name + "): these server commands as /<command>: " + joined(role->commands, ", ") + "\n";
const std::string whisper = "/w <player> <message>: send a private message";
return reply(guest, (text.empty() ? "This server has no player votes. Type /tp <player> to teleport.\n" : text) + whisper);