5 releases, newest first.
ConcurrentModificationException traces from Paper's async command builder after /snchat reload when blockcommands.yml had been edited. 2.1.1 only covered a reload that changed nothing. The command whitelist now rebuilds its placeholder commands before the command tree is sent, so no player is left with stale tab completion.command.aliases no longer gets a placeholder command.{prefix} and {suffix} now accept hex written without the &. A LuckPerms prefix like
#E70000&lO#F30000&lW#FF0000&lN#E60000&lE#CD0000&lR #CD0000 - the shape every hex-prefix
generator produces - used to reach chat as literal text, because the render pipeline only knew
&#RRGGBB and <#RRGGBB>. It now renders as colour.&#RRGGBB is left alone, so is the
#RRGGBB inside a MiniMessage tag such as <gradient:#FF0000:#00FF00>, and so is a # that
is not followed by six hex digits.config.yml, and hex
a player types into their own message, still needs the & - applying this to the message body
would let anyone colour chat without holding snchat.color.ConcurrentModificationException on /snchat reloadOn Paper, /snchat reload could print ConcurrentModificationException stack traces from the
Async Command Builder Thread Pool. Nothing crashed and no data was affected, but each trace was
one online player whose command tree never arrived - so that player silently kept their OLD tab
completion until they relogged.
The cause: SnLib re-registers the plugin's three root commands and pushes the command tree to every player immediately BEFORE the reload hook runs, and the hook then released and re-claimed every command-blocker placeholder inline, mutating the command registry while Paper's async pool was still walking it.
What changed:
blockcommands.yml
no longer touches the server's command map at all.A command added to a group's commands: list still tab-completes immediately after
/snchat reload, with no restart - that behaviour is unchanged.
The underlying race is Paper's own and reproduces with no plugins installed; this release stops SnChat from feeding it.
Violation alerts are now opt-in. After this update your existing staff stop
receiving them until each one runs /snchat alerts once. That choice is then
saved and never has to be repeated.
snchat.notify now decides who is eligible for chat-control violation alerts, not who
receives them. Alerts start off for everyone./snchat alerts turns your own alerts on or off, and the choice survives relog and
restart. Previously it only lasted the session and alerts came back on at the next login.snchat.notify still silences a player immediately, even if their opt-in is on file.data.yml in the plugin folder, written by the plugin, holding who opted in. It is never
seeded or merged, and is not meant to be edited by hand.Group-based chat formatting for Paper, with inline showcase tokens, chat moderation, automatic announcements and a per-group command whitelist.
Chat formatting - one format per LuckPerms primary group, falling back to a global chat-format. Every line can carry a hover tooltip and a click action, and every string supports & codes, &#RRGGBB hex and PlaceholderAPI. Placeholders are {prefix}, {suffix}, {displayname}, {name} and {message}.
Showcase tokens - [item] puts the item a player is holding into their message, tooltip and all. [inv] and [ec] post a clickable tag that opens a frozen replica of the sender's inventory or ender chest, viewable by anyone who clicks it. Each family has its own material blacklist.
Chat moderation - caps, character repetition, message cooldown, a plugin:command syntax block and a global chat mute. Each module either corrects the message or denies it, has its own snchat.bypass.* node and its own staff-alert switch.
Announcements - a rotating or random list on its own interval, each entry with its own hover and click.
Command whitelist - a per-LuckPerms-group allowlist of the commands a player may run, with unlisted groups falling back to default.
Put SnChat.jar, SnLib.jar and LuckPerms into plugins/ and start the server. SnChat generates its own config.yml, lang/messages_en.yml and both guis/ files on first boot, and announcements.yml and blockcommands.yml once it enables.
The command blocker is on out of the box. blockcommands.yml ships with a populated default group and every unlisted group falls back to it, so players are restricted from the first boot. Add your groups to that file or set command-blocker.enabled: false. This is the one default that surprises people.
Licensing, permissions and the full config reference are in the README.
The four line tags - [center], [rgb], [small], [noprefix] - are gated by their own snchat.prefixtags node, separate from snchat.color. They affect the whole line rather than a span of it, so selling coloured chat to a donor rank does not also sell line centring.