Chat plugin for a school Minecraft server (PaperMC 1.20.x / 1.21.x)
ChatModifier overhauls chat and player communication — it scopes messages to a configurable radius, handles private messages, staff broadcasts, an admin spy mode, a word filter with auto-mute, and optional chat unlock requirements. It optionally integrates with LuckPerms to display rank prefixes.
- Messages are only visible to players within a configured radius
- Setting
0= infinite range (entire world) - Configurable cooldown between messages
- Ignores spectator-mode and vanished players
- Anti-repeat — blocks sending the same message again (configurable history of 1–5 messages)
- Link blocker — blocks URLs and domain names
- Email blocker — blocks email addresses
- Broadcasts a message to every player on the server
- Long cooldown configurable in config.yml
- Can require a block-mining threshold before it's unlocked
- Staff broadcast visible to everyone
- Requires the
chatmodifier.command.globalpermission - Can be disabled in config.yml
- Send a private message to a specific player
/reply(or/r) replies to the last conversation partner- Handles vanished / spectator players correctly
- Tab-complete filters hidden players based on permission
- Separate toggles for chat spy and private-message spy
- Intercepted messages are prefixed with
[SPY] - Requires the
chatmodifier.spypermission
- Language packs loaded from
bannedWords/pl.jsonandbannedWords/en.json - Three severity levels: HIGH, MEDIUM, LOW
- Hard-block mode (default): message is rejected and the sender is notified
- Soft-block mode (
hard-block: false): banned words are censored in-place (k***a,f***k) - Extra words can be added directly in config.yml
- Automatically mutes players who repeatedly trigger the word filter:
- LOW — 3 violations in 25 min → muted 30 min
- MEDIUM — 3 violations in 45 min → muted 1 h
- HIGH — 1 violation → muted 1 h
- All thresholds and durations are configurable
- Mute with optional duration (
30s,5m,1h,2d,7w) or permanently - Accessible as
/cm muteand/chatmodifier mutein case another plugin shadows/mute
- Shows up to 20 recent log entries for a player, filtered by type:
all— every logged messagedisallowed— only blocked messagesmutes— only mute events
- Require players to mine a configurable amount of a block before they can:
- Use chat (e.g. mine 10 Dirt)
- Use
/shout(e.g. mine 10 Stone)
- Progress is saved between server restarts
- Players are notified when they unlock a feature
- All messages (and blocked messages, mutes) are written to
logs/word-YYYY-MM-DD.log - Includes timestamp, message type, sender → recipient, viewer list, block reason
- Log format:
[HH:mm:ss] TYPE sender: message [BLOCKED:HIGH] - Viewers: Player1, Player2
- Download the
.jarfrom GitHub - Place it in your server's
plugins/folder - Start the server — config files are generated automatically
- Edit
plugins/ChatModifier/config.ymlandlang.yml - Reload with
/reload confirmor restart the server
Requirements:
- PaperMC 1.20.x or 1.21.x
- Java 21+
- LuckPerms (optional — for rank prefix display)
| Command | Aliases | Description | Permission |
|---|---|---|---|
/shout <message> |
/s, /krzyk |
Broadcast to the whole server | (everyone) |
/global <message> |
/g |
Staff broadcast | chatmodifier.command.global |
/msg <player> <message> |
/tell, /w, /message |
Private message | (everyone) |
/reply <message> |
/r |
Reply to last private message | (everyone) |
/spy [chat|msg] |
— | Toggle chat / PM spy | chatmodifier.spy |
/mute <player> [duration] [reason] |
/cm mute |
Mute a player | chatmodifier.command.mute |
/unmute <player> |
/cm unmute |
Unmute a player | chatmodifier.command.mute |
/cm history <player> <all|disallowed|mutes> |
/chatmodifier history |
View chat log | chatmodifier.command.history |
| Format | Duration |
|---|---|
30s |
30 seconds |
5m |
5 minutes |
1h |
1 hour |
2d |
2 days |
1w |
1 week |
| (no duration) | Permanent |
| Permission | Default | Description |
|---|---|---|
chatmodifier.command.global |
false | Access to /global |
chatmodifier.cooldown.bypass |
false | Skip chat cooldown |
chatmodifier.spy |
op | Access to /spy |
chatmodifier.seehidden |
false | See hidden/vanished players in /msg tab-complete |
chatmodifier.command.mute |
op | Access to /mute and /unmute |
chatmodifier.command.history |
op | Access to /cm history |
/lp group admin permission set chatmodifier.command.global true
/lp group admin permission set chatmodifier.spy true
/lp group admin permission set chatmodifier.command.mute true
/lp group admin permission set chatmodifier.command.history true
/lp group vip permission set chatmodifier.cooldown.bypass true
# ------- [ CHAT ] ------- #
chat:
distance: 32 # Message radius in blocks (0 = infinite)
cooldown: 1500 # Time between messages in ms
anti-repeat:
enabled: true
history: 3 # How many past messages to check (1–5)
block-links: true
block-emails: true
# ------- [ WORD FILTER ] ------- #
word-filter:
languages: [ pl ] # Language files to load (pl.json, en.json, ...)
extra: [] # Additional words to always block (severity: MEDIUM)
# true = block the message entirely
# false = censor banned words (k***a) and still deliver the message
hard-block: true
# ------- [ AUTO-MUTE ] ------- #
auto-mute:
enabled: true
low:
window: 1500000 # 25 min — tracking window
count: 3 # violations before mute
duration: 1800000 # 30 min mute
medium:
window: 2700000 # 45 min
count: 3
duration: 3600000 # 1 h
high:
window: 300000 # irrelevant — count is 1
count: 1
duration: 3600000 # 1 h
# ------- [ GLOBAL ] ------- #
global:
enabled: true
# ------- [ SHOUT ] ------- #
shout:
enabled: true
cooldown: 60000 # ms between /shout uses
# ------- [ LOGGING ] ------- #
logging:
enabled: true
log-clean: true # also log clean (non-blocked) messages
# ------- [ REQUIREMENTS ] ------- #
requirements:
chat:
enabled: false
block: DIRT # any Bukkit Material name
amount: 10
shout:
enabled: false
block: STONE
amount: 10
# ------- [ COMMANDS ] ------- #
# Extra aliases registered at startup. Restart required after changes.
commands:
shout:
extra-aliases: [ sh ]
global:
extra-aliases: [ gl ]
msg:
extra-aliases: []
reply:
extra-aliases: [ re ]
spy:
extra-aliases: []distance |
Effect |
|---|---|
0 |
Infinite (entire world) |
32 |
Visible within 32 blocks |
64 |
Visible within 64 blocks |
shout.cooldown |
Duration |
|---|---|
60000 |
1 minute |
300000 |
5 minutes |
900000 |
15 minutes |
All player-facing messages live in plugins/ChatModifier/lang.yml. Any key missing from your file automatically falls back to the plugin's default, so you only need to override what you want to change.
Color codes use & (&c = red, &a = green, &7 = gray). Placeholders are documented inside the file.
chat:
no-recipients: "&c[CM] Nobody heard you - No players within {distance} blocks!"
repeat: "&c[CM] Don't repeat the same message!"
link-blocked: "&c[CM] Links are not allowed in chat!"
email-blocked: "&c[CM] Email addresses are not allowed in chat!"
mute:
blocked: "&c[CM] You are currently muted. Time remaining: &e{time}&c."
auto-muted: "&4[CM] You have been automatically muted for &c{time}&4."
shout:
cooldown: "&c[CM] You must wait {minutes}min. {seconds}s. before using this command again."
requirements:
chat-locked: "&c[CM] You haven't unlocked chat yet! Mine &e{progress}&c to start chatting."
shout-locked: "&c[CM] You haven't unlocked /shout yet! Mine &e{progress}&c to use it."To add a custom alias (e.g. /bc for /shout), edit config.yml and restart the server:
commands:
shout:
extra-aliases: [ bc, broadcast ]Place JSON files in plugins/ChatModifier/bannedWords/. Each file is a JSON array:
[
{ "word": "example", "severity": "MEDIUM" },
{ "word": "badword", "severity": "HIGH" }
]Severity values: HIGH, MEDIUM, LOW. Add the language code to word-filter.languages in config.yml.
When LuckPerms is installed, the plugin automatically fetches each player's prefix and prepends it to chat messages:
[Admin] Dominik: Hello!
Without LuckPerms only the player name is shown:
Dominik: Hello!
- Check the server version — Paper 1.20.x or 1.21.x is required (
/version) - Check that you are running Java 21+ (
java -version) - Look for
[ChatModifier]errors in the server console
Make sure the player / group has chatmodifier.command.global.
Set chat.distance: 0 — the value 0 means infinite range.
Make sure you restarted the server (not just /reload). Extra aliases are registered via CommandMap at startup.
Ensure LuckPerms is installed and loaded before ChatModifier.
Use /cm mute <player> [duration] [reason] or /chatmodifier mute instead.
Delete plugins/ChatModifier/lang.yml and restart the server to regenerate it. New keys always fall back to the plugin's bundled default, so you can also just leave the file as-is.
0.2.0
- Word filter:
bannedWords/pl.json+bannedWords/en.json, severity levels (HIGH/MEDIUM/LOW) - Auto-mute system — configurable per-severity thresholds
- Manual
/mute//unmutewith duration format /cmmeta-command (mute, unmute, history) — bypass plugin conflicts/cm history— per-player log viewer (all / disallowed / mutes)- Anti-repeat, link blocker, email blocker
- Block-mining requirements for chat and
/shout - Daily log rotation:
logs/word-YYYY-MM-DD.log - Hard-block vs. soft-block (censored) word filter mode
lang.yml— all player-facing messages with auto-fallback for missing keys- Configurable extra command aliases in config.yml
0.1.0
- Initial release
- Local chat with radius and cooldown
- Commands:
/shout,/global,/msg,/reply,/spy - LuckPerms integration
- Support for Minecraft 1.20.x and 1.21.x
- GitHub: https://github.com/Dominos111G/ChatModifier
- Issues: https://github.com/Dominos111G/ChatModifier/issues
MIT License — Free to modify and distribute
Version: 0.2.0 | Minecraft: 1.20.x / 1.21.x | Java: 21+