Channel System
Overview
Channels route chat messages to specific groups of players. Each channel has a format, optional range limit, party integration, proxy support, and Discord linking. Players join channels in READ (receive-only) or WRITE (send+receive) mode. Only one WRITE channel at a time.
Architecture
Key Classes
- •
Channel(model/Channel.java) — extendsYamlConfig, loaded fromsettings.ymlChannels.List - •
Channel.State— encapsulates message state (sender, message, component, variables) - •
ChannelMode(core: model/ChannelMode.java) — enum:WRITE(gold),READ(green) - •
ChannelCommands(command/channel/) —/channelsubcommands - •
ChatHandler(listener/chat/) — routes chat to channels
Message Send Pipeline
code
Player types message
→ ChatHandler routes to write channel
→ Channel.sendMessage(State)
1. Compile receivers (range, party, vanish, ignore checks)
2. Fire ChannelPreChatEvent (API — cancellable)
3. Check mute status (player, channel, server, proxy)
4. Remove unauthorized colors
5. Run rules/filters via Checker.filterChannel()
6. Process @mentions and sound notifications
7. Format.build() — compile format parts into component
8. Send to each receiver (with per-receiver view conditions)
9. Log to console and database
10. Forward to Discord (if Discord_Channel_Id set)
11. Forward over proxy (if Proxy: true)
12. Fire ChannelPostChatEvent
Common Issues & Solutions
"Messages not showing in channel"
- •Check
Channels.Enabled: truein settings.yml - •Verify player has
chatcontrol.channel.join.{channel}.write - •Run
/channel listto check membership - •Check
Ignore_Worldsdoesn't include current world - •Enable
Rules.Verbose: trueto see if rules deny the message
"Ranged channel not working"
- •Check
Rangevalue is a number (blocks) or*(world-wide) - •
Min_Players_For_Rangemay prevent range from activating - •
Range_Worldsonly applies whenRange: "*" - •
chatcontrol.bypass.rangereaches everyone — check staff perms - •Party option may override range behavior
"Player can't leave/switch channels"
- •Players can only be in ONE write channel. Joining a new write channel leaves the old one.
- •
Join_Read_Old: trueauto-converts old write channel to READ mode - •Manually left channels (
/channel leave) are remembered — won't auto-rejoin
"Console format shows wrong output"
- •
"none"cancels the event (bad for DynMap, other plugins) - •
"default"uses the channel's formatted output as-is
"Discord messages showing wrong format"
- •Old
Format_Discordwas split: useFormat_To_Discord(MC→Discord) andFormat_From_Discord(Discord→MC)
Key File Paths
- •Channel class:
chatcontrol-bukkit/src/main/java/org/mineacademy/chatcontrol/model/Channel.java - •Channel mode:
chatcontrol-core/src/main/java/org/mineacademy/chatcontrol/model/ChannelMode.java - •Channel commands:
chatcontrol-bukkit/src/main/java/org/mineacademy/chatcontrol/command/channel/ - •Chat handler:
chatcontrol-bukkit/src/main/java/org/mineacademy/chatcontrol/listener/chat/ChatHandler.java - •Settings:
chatcontrol-bukkit/src/main/resources/settings.yml(Channels section)
Reference
For configuration keys, default values, commands, permissions, and variables not covered above, read the source files directly using read_codebase_file. The key file paths above point to the most relevant files.