Skip to content

Add runtime toggles for global and group chat - #236

Open
Zaldaryon wants to merge 1 commit into
indevfrom
feat/chat-runtime-toggle
Open

Add runtime toggles for global and group chat#236
Zaldaryon wants to merge 1 commit into
indevfrom
feat/chat-runtime-toggle

Conversation

@Zaldaryon

Copy link
Copy Markdown
Contributor

Fixes #218.

What

Two independent runtime toggles, Chat.Global.Enabled and Chat.Groups.Enabled. Each channel also gets AllowStaffBypass (default on) and a DisabledMessage shown to a blocked sender. Config-backed, so it survives a restart, unlike /lockchat which is session state.

/chattoggle                    status for both channels
/chattoggle global on|off|toggle
/chattoggle group  on|off|toggle
/chattoggle all    on|off|toggle
/togglechat ...                alias

No new command needed either, /stratum set Chat.Global.Enabled false works today through the existing reflection path.

/announce, /staffbroadcast, and slash commands are untouched. They never go through OnPlayerChat.

Where it hooks and why

CmdStratumStaffCommands.OnPlayerChat already runs the mute check, then an unconditional staff bypass, then the chat lock and slowmode checks. I put the new check between the mute check and the bypass, not after it. The bypass at that point returns unconditionally, so if the per-channel check came after it, AllowStaffBypass = false would be dead code, staff would always get through regardless of the setting.

StratumChatConfig.ChannelFor(channelId) maps 0 to Global, any positive group id to Groups, and returns null for the negative server channels (ServerInfo, DamageLog, InfoLog, AllChatGroups). Those are server-to-client only, never reachable from a player chat packet, left alone.

Kept it independent of the existing Chat.Enabled flag. That one only gates role-prefix formatting. If the new toggles read it too, disabling formatting would silently re-enable a channel someone had turned off on purpose.

A tradeoff worth flagging

The staff exemption reuses the existing Commands.ChatControl privilege (stratum.chatcontrol) instead of adding a new one. Simpler, no new config block, no new catalog entry, matches what /lockchat's bypass already uses. The cost: if an operator disables the ChatControl command block entirely, the staff exemption goes with it, since PlayerHasAccess checks that block's own Enabled flag. Recoverable from console (console callers always pass the check) or by hand-editing stratum.json. Same behavior /lockchat already has, not a new failure mode, but worth knowing before merge.

Testing

No test project in this repo, so this follows the usual live-boot convention.

  • dotnet build VintageStory.slnx -c Release, zero warnings on the touched files.
  • Fresh dataPath boot, reaches RunGame, no fatal errors.
  • Fresh-config boot: stratum.json writes Chat.Global and Chat.Groups with correct defaults, ConfigVersion unchanged.
  • Upgrade path: hand-edited stratum.json, set Chat.Global.Enabled = false with a custom message, deleted the Chat.Groups block outright, restarted. The custom Global value survived, the deleted Groups block came back with the right defaults through EnsurePopulated.
  • Live two-account test against a real client, not just the smoke boot:
    • baseline chat delivered normally
    • /chattoggle global off with AllowStaffBypass at its default (true): staff message still delivered
    • /stratum set Chat.Global.AllowStaffBypass false, same account, same channel: message blocked, disabled message shown client-side
    • /announce delivered with global chat off, confirms it doesn't route through the hook
    • /chattoggle status and the on/off/toggle modes all exercised through the actual command, not just read from source

That last live pass caught a real bug before it shipped: the arg parser accepts status as a value for the mode argument too (/chattoggle global status), but the original handler only checked for on/off and fell through to the toggle branch for anything else, status included. Typing /chattoggle global status expecting a read would have flipped the channel instead. Fixed by handling mode == "status" as its own branch before the mutation path, verified against the same build.

@trevorftp @tehtelev

Fixes #218. CmdStratumStaffCommands.OnPlayerChat already carried
channelId and had a staff bypass; this adds a per-channel check ahead
of that bypass so the exemption can actually be turned off.

Chat.Global and Chat.Groups each get Enabled, AllowStaffBypass, and
DisabledMessage. Defaults preserve current behavior. /chattoggle
mirrors /lockchat and /slowmode, shares the ChatControl privilege, no
new privilege or catalog entry. /stratum set works too with zero new
command code.
@Zaldaryon
Zaldaryon requested review from tehtelev and trevorftp August 7, 2026 00:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant