AdvancedSensitiveWords
AdvancedSensitiveWords is a Paper moderation plugin built around DFA word matching, event-based content inspection, modular violation levels, and optional LLM-assisted chat review.
2.x is a breaking release. It targets Paper only, uses Gradle with Kotlin DSL, and generates a new kebab-case configuration model. Do not reuse pre-2.0 configuration files without reviewing every setting.
Requirements
| Component | Requirement |
|---|---|
| Server | Paper 1.21.11 or higher |
| Java | Java 21 |
| Proxy (optional) | Velocity with the matching Velocity jar |
| Optional integrations | TrChat, PacketEvents, PlaceholderAPI, floodgate, AuthMe |
Spigot, CraftBukkit, and BungeeCord are not supported since version 2.x.
Installation
- Download the Paper artifact from the release, or build
paper:shadowJarlocally. - Put the Paper jar in the server
plugins/directory and start Paper once. - Configure
plugins/AdvancedSensitiveWords/config.ymland the generatedmessages_en.ymlormessages_zhcn.yml. - Run
/asw reload allafter changing dictionaries or/asw reload configafter changing only configuration.
For Velocity notifications and proxy commands, install the Velocity artifact on the proxy, set plugin.hook-velocity: true on Paper, then restart both sides. The proxy module does not filter chat by itself.
What 2.x Filters
- Chat and commands: Paper
AsyncChatEvent, command preprocessing, cross-message chat context, configurable replacement or cancellation, fake messages on cancellation, and TrChat fake-message/shadowban compatibility. - Books: event-based writable-book checking, optional cross-page checking in cancel mode, and a bounded cache for processed book content.
- Signs: per-line, multi-line, and recent-sign context checking. In cancel mode, optional PacketEvents fake view can show the author their attempted text while other players retain the real, clean sign view.
- Anvils and items: rename-result filtering plus item display-name and lore filtering using Adventure components.
- Player names and broadcasts: login rejection for blocked names and optional broadcast filtering.
- Optional LLM chat review: asynchronous, cost-gated review for messages that did not match DFA or chat context. It is disabled by default and never retracts chat; it can notify, record, increment the separate AI VL, and run configured actions after a validated response.
Quick Configuration
Configuration is generated in lower kebab-case. The generated file is the authoritative list of defaults and inline comments.
plugin:
language: en
enable-chat-check: true
enable-sign-edit-check: true
chat:
method: CANCEL # REPLACE or CANCEL
fake-message-on-cancel: false
context-check: true
REPLACE changes matched text with the configured replacement. CANCEL rejects the affected interaction. Fake chat messages and sign fake view are cancellation-only features.
Command Argument Rules
chat.command-white-list also defines which command arguments are inspected. With the default invert-command-white-list: true, listed command paths are inspected and commands outside the list are skipped.
chat:
invert-command-white-list: true
command-white-list:
- "[default:include] /msg [ignore:1]"
- "[default:include] /bc [ignore:1,-1]"
- "[default:ignore] /mail send [include:2..]"
Arguments are numbered after the command path, starting at 1. -1 is the final argument; 2.. means the second argument through the end. include and ignore directives are processed in order. Ignored arguments split detection segments, so a blocked word cannot match across a skipped player name, server name, count, or other parameter.
Punishments and Violation Levels
Each filter module has its own punishment list and its own VL: CHAT, AI, BOOK, SIGN, ANVIL, and ITEM. Commands share the CHAT VL. The manual default list at plugin.manual-punishment is the exception: its VL conditions use the total across modules.
chat:
punishment:
- "COMMAND|kick %player% Blocked content|VL>2"
- "SHADOW|60|VL>5"
Supported action types are COMMAND, COMMAND_PROXY, DAMAGE, HOSTILE, EFFECT, and SHADOW. Use %player% or %PLAYER% in command actions. Empty lists keep detection, logging, notification, and VL counting active while disabling automatic actions.
Optional LLM Moderation
Enable LLM review only after configuring a compatible provider and API key. Paper loads LangChain4j libraries through plugin.yml, so the server needs network access or an existing Paper library cache during the first startup.
ai:
enabled: true
base-url: https://api.deepseek.com
api-mode: CHAT_COMPLETIONS # CHAT_COMPLETIONS, RESPONSES, or ANTHROPIC_MESSAGES
api-key-environment: DEEPSEEK_API_KEY
model-name: deepseek-v4-flash
Before a request, ASW requires that direct DFA and chat-context checks miss, then applies message-length, entropy, per-player cooldown, in-flight, concurrency, and queue limits. LLM output is strictly parsed locally before any follow-up action.
Each category has independent notification and punishment confidence thresholds and actions under ai.category-policy. LLM requests and responses are audited in plugins/AdvancedSensitiveWords/llm-history/. Treat this directory as sensitive operational data.
ai.server-context-can-override is a server-owner policy switch. When enabled, ai.server-context is inserted into the trusted system policy and is intentionally omitted from the user JSON payload. Keep policy text administrator-controlled; never place player input, credentials, or private data there.
Commands
| Command | Purpose |
|---|---|
/asw help [query] |
Show command help. |
/asw status |
Show general plugin status. |
/asw ai status |
Show LLM runtime counters, queue state, model, API mode, and category policies. |
/asw reload [all\|config] |
Reload configuration, or configuration plus dictionaries. |
/asw test <text...> |
Test text against the DFA filter. |
/asw word add/remove <word> [word...] |
Mutate the blocked-word list for the current runtime only. |
/asw allow add/remove <word> [word...] |
Mutate the allowed-word list for the current runtime only. |
/asw player info <online-player> |
Show per-module and total VL. |
/asw player reset <online-player> [module] |
Reset all or one module VL. |
/asw player punish <online-player> [method...] |
Execute configured manual punishment or one supplied action. |
/asw teleport <world-id> <x> <y> <z> |
Teleport a staff member to a reported location. |
/asw and /advancedsensitivewords are equivalent. Runtime word-list mutations are discarded on a full dictionary reload or server restart.
Permissions
| Permission | Default | Purpose |
|---|---|---|
advancedsensitivewords.bypass |
false | Bypass filtering. |
advancedsensitivewords.notice |
op | Receive staff notifications. |
advancedsensitivewords.update |
op | Receive update notices. |
advancedsensitivewords.command.* |
false | Parent node for all management commands. |
advancedsensitivewords.command.help |
op | Use help. |
advancedsensitivewords.command.status |
op | Use general status. |
advancedsensitivewords.command.ai.status |
op | Use AI status. |
advancedsensitivewords.command.reload.all |
op | Reload configuration and dictionaries. |
advancedsensitivewords.command.reload.config |
op | Reload configuration only. |
advancedsensitivewords.command.test |
op | Use DFA test. |
advancedsensitivewords.command.word.add |
op | Add blocked words at runtime. |
advancedsensitivewords.command.word.remove |
op | Remove blocked words at runtime. |
advancedsensitivewords.command.allow.add |
op | Add allowed words at runtime. |
advancedsensitivewords.command.allow.remove |
op | Remove allowed words at runtime. |
advancedsensitivewords.command.player.info |
op | Inspect player VL. |
advancedsensitivewords.command.player.reset |
op | Reset player VL. |
advancedsensitivewords.command.player.punish |
op | Apply manual punishment. |
Integrations and API
- TrChat: compatibility for fake chat messages and shadowban display. TrChat remains responsible for its own formatting pipeline.
- PacketEvents: optional and soft-required only for sign fake view. Without it, sign cancel behavior remains active without a fake view.
- PlaceholderAPI: enable
plugin.enable-placeholderto expose%asw_version%,%asw_total_filtered%,%asw_is_shadow%, and%asw_violation_count%. - Floodgate / AuthMe: optional Bedrock-name and authentication-state handling.
Other Paper plugins can access the shadowban API without depending on implementation classes:
import io.wdsj.asw.bukkit.api.AdvancedSensitiveWordsApi;
import java.time.Duration;
AdvancedSensitiveWordsApi.shadowBan().shadow(player, Duration.ofMinutes(5));
AsyncModerationResponseEvent is fired asynchronously after an LLM response. Event handlers may observe, cancel ASW follow-up, or replace the validated result, but must schedule Bukkit entity/world work themselves.
Building From Source
.\gradlew.bat --no-daemon build
License
AdvancedSensitiveWords is licensed under the GNU AGPL-3.0.
Links
All Versions
+ Add Version| Name | Game version | Platforms | Published | Downloads | Actions |
|---|---|---|---|---|---|
| 15h ago | 1 | ||||
| 15h ago | 1 | ||||
| 15h ago | 1 | ||||
| 15h ago | 1 | ||||
| 15h ago | 1 | ||||
| 15h ago | 1 | ||||
| 15h ago | 1 | ||||
| 15h ago | 1 | ||||
| 15h ago | 1 | ||||
|
R
Pro-1.2
|
15h ago | 1 | |||
| 15h ago | 1 | ||||
| 15h ago | 1 | ||||
| 15h ago | 1 | ||||
|
R
Pro-1.1
|
15h ago | 1 | |||
| 15h ago | 1 | ||||
| 15h ago | 1 | ||||
|
R
Pro-1.0
|
15h ago | 1 | |||
| 15h ago | 1 | ||||
| 15h ago | 1 | ||||
| 15h ago | 1 | ||||
| 15h ago | 1 | ||||
| 15h ago | 1 | ||||
| 15h ago | 1 | ||||
| 15h ago | 1 | ||||
| 15h ago | 1 | ||||
| 15h ago | 1 | ||||
| 15h ago | 1 | ||||
| 15h ago | 1 | ||||
| 15h ago | 1 |
- Full Changelog**: https://github.com/HaHaWTH/AdvancedSensitiveWords/compare/2.1.0...2.3.0
- Full Changelog**: https://github.com/HaHaWTH/AdvancedSensitiveWords/compare/2.1.0...2.3.0
- Full Changelog**: https://github.com/HaHaWTH/AdvancedSensitiveWords/compare/2.0.1...2.1.0
- Full Changelog**: https://github.com/HaHaWTH/AdvancedSensitiveWords/compare/2.0.1...2.1.0
- Neo-Aspect by @HaHaWTH in https://github.com/HaHaWTH/AdvancedSensitiveWords/pull/122
- Full Changelog**: https://github.com/HaHaWTH/AdvancedSensitiveWords/compare/1.2...2.0.0
- Neo-Aspect Rebuild the whole project from ground-up by @HaHaWTH in https://github.com/HaHaWTH/AdvancedSensitiveWords/pull/122
- Full Changelog**: https://github.com/HaHaWTH/AdvancedSensitiveWords/compare/1.2...2.0.0
1. Added config & update checker
1. Move permission package
2. Use PermissionsEnum instead of PermissionsConstant
3. Kotlin migration
4. Added dev version check
5. Added bypass permission check for item spawn
6. Use parallel stream to load external files & reduce memory consume
7. Cache for loading words from internet
8. Early return if no files to load
1. Added config & update checker
1. Fix message being sent twice
2. Improve forwarding performance
1. Use LimitedByteArrayDataOutput
1. Added
reloadconfig & add & remove command2. Fix FakeMessageExecutor
3. Fix /asw status output
4. Use player uuid to store data instead of player object
5. VL-based punishment system
6. Make fake message work under packet mode
7. Remove DatabaseManager & Messages fixes & Added /asw reset command
8. Make hooks reloadable
9. Use Gson to parse response
10. Cache permission check
11. Offload logging operation to single thread
12. Use Caffeine
13. Improve logic in listeners
14. Monitor item spawn
15. Add addallow/removeallow command & More full match condition
16. Further improve library download speed in China
17. Update dependencies
### Changelog:
1. Fix bug when running on latest packetevents
2. Notify operators on update available
3. Integrate OpenAI & Ollama AI moderation processors
4. Optimize zh dict
5. Expand en default dict
6. Invert command whitelist by default
7. Added check for SimpleVoiceChat
8. Fix potential CME by using ConcurrentHashmap
9. Added punish command
10. Added
is_shadow placeholder11. Simplify message file
12. Update dependency
13. Runtime library loading
14. Fix ip retrieve
15. Add proxy command execution
16. Recode fakemessage
17. Add config for chat check
18. Process message even it is cancelled
19. Code cleanup
20. Throw exception on player ip is null
1. **Removed built-in packetevents, now you need to download manually**
2. 1.21 support (Only event mode)
3. Removed ProtocolLibListener for better maintainbility
4. Add IPv4 address check
5. Show wordlist in notify messages
6. Fix bug when using replace mode for book check
7. Optimize dict (Thanks to @CuteLittleSky )
8. Added AltListener for fakeMessages
9. Code cleanup
10. Migrate all listeners to Kotlin
11. Support for latest Leaves
#### Download:
#### Update notes:
1. Update all AdvancedSensitiveWords on your backend server and proxy
2. Regenerate message files
Fix Velocity receiver
- If you are running standalone servers without proxy, don't download this!**
- If you are running standalone servers without proxy, don't download this!**
## This is Spigot version!!!!!
- Changelog:**
2. Add alternative event-based check
3. Add PlaceholderAPI expansion
4. Add SHADOW punishment method
5. Add /asw info command
6. Optimize dict
7. Fix potential ConcurrentModification
8. Reduced memory consume
9. Add database to record player violations
10. Rewrite BookCache
11. Optimize ChatContext
12. Able to flush player data on quit
13. Bump dependecies
14. Code cleanup
15. Support for BungeeCord and Velocity
16. Switch to multi-module project
- Regenerate your message file before updating!**
- Changelog:**
2. Fix tab complete on console
- Changelog:**
2. Add drop item check to Item checks
3. Add per-check punish option
4. NPC compatibiliy
5. Dependencies update
- Whats changed:**
2. Fix proxySelector
3. Add external sensitive file loader (./external/deny(allow))
4. Add operator notification (permission advancedsensitivewords.notice)
5. Add custom punishment (Options: EFFECT, COMMAND, HOSTILE, DAMAGE)(Visit wiki for more details)
6. Bug fixes
7. Add update checker
- Please regenerate your language file before update!**