Hush
Hush: allows hosts and clients to filter and censor chat. Use /hushhelp
| Date uploaded | 4 months ago |
| Version | 0.1.0 |
| Download link | AndrewLin-Hush-0.1.0.zip |
| Downloads | 27 |
| Dependency string | AndrewLin-Hush-0.1.0 |
This mod requires the following mods to function
BepInEx-BepInExPack
BepInEx pack for Mono Unity games. Preconfigured and ready to use.
Preferred version: 5.4.2305AndrewLin-Alpha
Alpha: A mod for On-Together to provide common utilities and features.
Preferred version: 0.1.1README
Hush
A BepInEx mod for On Together that lets hosts and clients filter chat messages. Matched words can be censored with asterisks or blocked entirely. The filter list persists between sessions and can be managed from in-game chat commands.
Hosts can also mute individual players permanently or for a fixed duration, suppressing their messages before they are relayed to any client.
When installed on the host, the filter and mute system are enforced server-side before the message is relayed, so every connected client receives the already-filtered version regardless of whether they have the mod. Clients with the mod installed also apply the word filter locally as a second layer.
In-Game Commands
Type any command into the in-game chat. Commands start with / and are not sent to other players.
Player muting (host only)
| Command | Short | Description |
|---|---|---|
/hushmute <player> |
/hmu |
Permanently mute a player |
/hushtmute <player> <duration> |
/htm |
Temporarily mute a player (e.g. 10m, 1h30m, 30s) |
/hushunmute <player> |
/humu |
Unmute a player (accepts Steam ID for offline players) |
/hushgetmutes |
/hgmu |
List all currently muted players with expiry |
Player query formats — name (partial match), Steam ID suffix (digits only), or _host.
Word management
| Command | Short | Description |
|---|---|---|
/hushaddword <word> |
/haw |
Add a literal word to the filter |
/hushremoveword <word> |
/hrw |
Remove a literal word from the filter |
/hushgetwords |
/hgw |
List all filtered words |
Pattern management
Patterns are raw regular expressions. Use inline flags to control matching behavior.
| Command | Short | Description |
|---|---|---|
/hushaddpattern <regex> |
/hap |
Add a regex pattern to the filter |
/hushremovepattern <regex> |
/hrp |
Remove a regex pattern from the filter |
/hushgetpatterns |
/hgp |
List all filtered patterns |
Pattern examples
| Pattern | Behavior |
|---|---|
(?i)f+u+c+k |
Case-insensitive, matches repeated letters, no word boundary |
\bslur\b |
Exact whole-word match, case-sensitive |
(?i)\bslur\b |
Exact whole-word match, case-insensitive |
Utility
| Command | Short | Description |
|---|---|---|
/hushtoggle |
/ht |
Toggle the filter on or off |
/hushfilteraction <action> |
/hfa |
Set the filter action: Censor or Block |
/hushcensorchar <char> |
/hcc |
Set the character used to replace matched words in Censor mode |
/hushloadfilter |
/hlf |
Reload the filter word list from disk |
Configuration
Located in BepInEx/config/com.andrewlin.ontogether.hush.cfg
| Key | Default | Description |
|---|---|---|
General > EnableFeature |
true |
Master switch for the mod |
General > ShowCommand |
false |
Show typed commands in chat |
Filter > Action |
Censor |
Censor replaces matches with asterisks. Block suppresses the entire message. |
Filter > CensorChar |
* |
Character used to replace matched words when in Censor mode |
Filter > ConfigPath |
(see below) | Path to the filter word list JSON file |
The filter word and pattern list is stored separately in BepInEx/config/com.andrewlin.ontogether.hush.filter.json and is updated automatically whenever you add or remove an entry via a chat command.
The player mute list (permanent and timed) is stored in BepInEx/config/com.andrewlin.ontogether.hush.mutes.json and is updated automatically on every mute/unmute. Timed mute expiry times survive game restarts.
Installation
Use r2modman or the Thunderstore app for the simplest install.
Manual:
| Step | Action |
|---|---|
| 1 | Install BepInEx into your On Together game folder |
| 2 | Copy AndrewLin.Hush.dll into BepInEx/plugins/ |
| 3 | Launch the game -- config files will be generated automatically |
Dependencies: BepInExPack, Alpha
Host-only vs. all-clients
Installing on the host is sufficient to enforce filtering for everyone in the session. Clients who also have the mod installed get an additional local filter pass that covers their own messages before they are sent.
CHANGELOG
Changelog
All notable changes to this project will be documented in this file.
[0.1.14] - 2026-06-15
Fixed
- Adapt to game update 1.1.3 - PurrNet RPC API removed BitPacker stream parameter from HandleRPCGenerated_0; updated Harmony prefix signature and packet read/write logic to use BitData instead of ByteData
[0.1.13] - 2026-04-15
Fixed
- Relay command targeting could silently fail or crash for certain player names.
PlayerUtils.QueryMatchesPlayerpassed the user-supplied query string directly as a regex pattern; names or queries containing regex metacharacters (e.g.[,(,+,.) would throwArgumentExceptionand abort the relay path entirely. TheContainscheck is now evaluated first (unchanged behaviour), andRegex.IsMatchis called only as a fallback wrapped in a try-catch so an invalid pattern skips the regex step instead of throwing.
Changed
- Relay prefix detection in
TextChannelManagerPatchnow usestext.Trim().StartsWith("hush:")so leading whitespace in a relay message does not cause the sentinel to be missed. - Admin override for relay commands (
PlayerLists.IsAdmin) re-enabled; admins can now issue relay commands in addition to whitelisted delegates. ExecuteRelaycalls are now wrapped in a try-catch so any unhandled exception logs a full error instead of silently escaping the Harmony prefix.
[0.1.12] - 2026-04-12
Changed
- Dependency update to Alpha 0.0.11
[0.1.11] - 2026-04-12
Changed
- Temporarily not using the PlayerList blacklist/admin feature from Alpha pending further review.
[0.1.10] - 2026-04-12
Changed
- Depends on Alpha 0.0.10
[0.1.9] - 2026-04-11
Changed
- Depends on Alpha 0.0.8
[0.1.8] - 2026-04-11
Added
- Relay commands (e.g.
hush:tmute:) now accept a player name query in place of a raw Steam ID64. If the target field is not a valid Steam ID64 (SteamUtils.IsSteamID), it is resolved viaPlayerUtils.FindPlayerByQuerybefore execution. Unresolvable queries are rejected with a warning. RelayExecutor- relay business logic extracted fromTextChannelManagerPatchinto a standalone injectable class. All game-API dependencies (mute manager, ban, name resolution, notifications) are injected via constructor, making the relay logic fully unit-testable./hushunmuteis no longer host-only: whitelisted delegates and mod admins can now relay unmute requests to the host viahush:unmute:<target>sentinel, matching the existing tmute/ban relay pattern.- Relay sentinels now accept a player name query in place of a raw Steam ID64 for all relay commands. If the target is not a valid Steam ID64, it is resolved via
PlayerUtils.FindPlayerByQuerybefore execution; unresolvable queries are rejected with a warning.
Changed
- Depends on Alpha 0.0.8
[0.1.7] - 2026-04-11
Added
- Improve relay and server side logging
[0.1.6] - 2026-04-10
Added
/hushlogverbose(/hlv) - toggle verbose BepInEx logging for Hush at runtime. Off by default; when enabled, debug-level traces (mute checks, relay paths, save/load messages) are emitted to the log.Hush.Testsproject with 81 unit tests coveringChatFilterManager,PlayerMuteManager,RelayParser, andDurationFormatter.
Changed
- Removed client-side suppression of
hush:sentinel messages. If a sentinel leaks to a client it will now display in chat as a visible indicator that the server-side intercept failed. - Relay parsing and duration formatting extracted into standalone
RelayParser/DurationFormatterclasses (no behaviour change).
[0.1.5] - 2026-04-05
Added
BanManagerclass: centralises all ban operations (add, add offline, remove, list) on top of the game'sDataManager.BanData./hushban <player>(/hb) - ban an online player. Host executes directly; whitelisted delegates relay the request to the host and also add the player to their own local ban list./hushbanoffline <steamid> <nickname>(/hbo) - ban a player by Steam ID without them being online (host only)./hushunban <player|steamid>(/hub) - remove a ban; accepts player query or raw Steam ID for offline removal (host only)./hushgetbans(/hgb) - list all banned players (host only).- Ban commands share the existing delegate whitelist: delegates may relay
/hushbanto the host in the same way as timed mutes.
[0.1.4] - 2026-04-02
Added
- Fixed Hush nullrefs
[0.1.3] - 2026-03-31
Added
/hushversion(/hv) command
Changed
- Attempt 1 at fixing the host-side of the
hush:tmute:relay
[0.1.2] - 2026-03-30
Added
- Mute-delegate relay system: the host can whitelist trusted non-host players to use
/hushtmute. Delegates send a hidden sentinel message; the host validates and executes the mute server-side - the sentinel is never visible to other clients. /hushdelegateadd <player>(/hdda) - add a player to the mute-delegate whitelist (host only)./hushdelegateremove <player>(/hddr) - remove a player from the whitelist; accepts a raw Steam ID for offline players (host only)./hushdelegatelist(/hddl) - list all current delegates (host only).- Delegate list persisted to the mutes JSON file and restored on load.
Changed
/hushtmuteis no longer host-only: whitelisted delegates may use it and their request is relayed to the host for execution.
[0.1.1] - 2026-03-29
Changed
- Add notification on timed mute expiry
- Add notification on blocked players
[0.1.0] - 2026-03-29
Added
- Player mute system (host only): suppress all messages from specific players server-side.
/hushmute <player>- permanently mute a player by name or Steam ID suffix./hushtmute <player> <duration>- timed mute with ISO 8601 /hh:mm:ssduration (e.g.10m,1h30m,30s)./hushunmute <player>- remove a permanent or timed mute. Accepts Steam ID for offline players./hushgetmutes- list all currently muted players with their expiry time.- Mute list persisted to
BepInEx/config/com.andrewlin.ontogether.hush.mutes.json; timed mute expiry times are preserved across game restarts.
[0.0.1] - 2026-03-20
Added
- Server-side relay intercept: when installed on the host, the filter is enforced before the message is broadcast to all clients.
- Client-side display filter: censors or blocks messages at the UI layer as a second pass.
ChatFilterManagerwith two modes:Censor(replace matched text with asterisks) andBlock(suppress the entire message).- Literal word filtering with automatic case-insensitive whole-word boundary matching.
- Raw regex pattern filtering with full inline flag support (
(?i),\b, etc.). - In-game commands for managing the filter list without restarting the game.
- Filter list persisted to
BepInEx/config/AndrewLin.Hush.filter.json; updated automatically on every mutation. - BepInEx config entry for
Filter > Action(CensororBlock), live-reload supported via ConfigurationManager.
| Command | Description |
|---|---|
/hushaddword <word> |
Add a literal word |
/hushremoveword <word> |
Remove a literal word |
/hushgetwords |
List all words |
/hushaddpattern <regex> |
Add a regex pattern |
/hushremovepattern <regex> |
Remove a regex pattern |
/hushgetpatterns |
List all patterns |
/hushtoggle |
Toggle the filter on or off |
/hushfilteraction <action> |
Set the filter action (Censor or Block) |