Chat is the messaging system for Eternal Empires — formatting, chat modes, spam prevention, and an AI-assisted content filter, all pluggable through their own provider interfaces so new filters or modes can be added without touching the core.
Players send messages through one of several chat modes: default (everyone sees it), world (only players in the same world), or dynamic — a custom Eternal Empires mode that relays messages through a chain of nearby players rather than broadcasting globally. Every message passes through a stack of chat filters before it's delivered:
- speed — rate-limits how fast a player can send messages, with an initial delay plus a per-character delay so long messages naturally take a bit longer to be allowed again
- personal-spam — blocks a player from repeating a similar message too soon (similarity threshold + cooldown)
- global-spam — blocks a message if too many similar messages have been sent server-wide within a short window
- ai — an n-gram-based classifier (
AIClassifier) checking messages against allowed/blocked word-list models, catching things pattern-matching alone would miss
Every filter implements the same ChatFilter interface (isBlocked(sender, message)), so adding a new filter is a matter of implementing that interface and registering it — nothing about chat modes or delivery needs to change. Every message, filtered or not, is written to a ChatLog for moderation and history purposes.
Config values for filter thresholds and cooldowns support simple math expressions ("60 * 3" for 180 seconds) so numbers can be written in whatever unit is easiest to reason about rather than pre-calculated.
Chat mode is set through per-player preference rather than a documented slash command in this repository — see ChatModeProvider if you're building a UI or command to let players switch modes.
ChatFilterProvider and ChatModeProvider are where filters and modes are registered and looked up. ChatLogProvider gives access to logged ChatMessages. PlayerChatEvent fires for other plugins that want to observe or react to chat without implementing their own filter.
api— public interfaces (ChatFilter,ChatMode,ChatLog,ChatMessage,PlayerChatEvent,ChatSystemAPI). No implementation, published for other plugins to depend on.common— the implementation: the built-in filters, the AI classifier, chat logging, and MongoDB-backed models via Morphia.paper— the Paper plugin: chat formatting, the three built-in chat modes, and startup wiring.
Java 21, Paper 1.20 or newer, and a MongoDB instance. Chat depends on multilanguage and permissions being installed.
./gradlew buildTo get a plugin jar, build the paper module's shadow jar:
./gradlew paper:shadowJarThe resulting jar is written to paper/build/libs/.
On first run, several files are generated under plugins/chat/:
config.yml controls formatting, chat mode, and filter thresholds:
chat-format: '{prefix}{prefix-spacer}{player}: {message}'
message-grey-factor: 0.66
chat-mode: 'default' # 'default', 'dynamic', or 'world'
chat-filters:
personal-spam:
enabled: true
similarity-threshold: 0.8
cooldown: "60 * 3"
speed:
enabled: true
initial-time: 0.5
time-per-character: 0.095
global-spam:
enabled: true
similarity-threshold: 0.8
alert-when:
time: 30
messages: 5
ai:
enabled: true
max-char-n-gram: 7Numeric values throughout support simple math expressions (+ - * / ^ %), which is why cooldown above is written as "60 * 3" rather than 180.
database.yml configures the MongoDB connection used for chat logs.
If your plugin needs to send filtered chat messages, add a custom filter, or read chat history, depend on chat-api:
repositories {
maven {
url 'https://packages.eternalempires.net'
}
}
dependencies {
compileOnly 'net.eternalempires:chat-api:VERSION'
}Replace VERSION with the release you want to target — see the Releases page for available versions.
See LICENSE.
See CONTRIBUTING.md.