SERVER ANTICHEAT

ModGuard

A Fabric client mod + Paper server plugin duo that verifies player modlists on join, fingerprints hacked clients by multiple methods, and gives server admins full control over what runs on their server.

Minecraft 1.21.11
Fabric Loader 0.18.2
Fabric API 0.140.2+1.21.11
Paper 1.21.11
🔍
How it Works

ModGuard uses four independent detection methods client-side. Even if one is bypassed, the others remain active.

METHOD 01
Plugin Channels
Every mod that communicates over the network registers its channel namespace. These are declared in code, not metadata — renaming the mod doesn't change them.
Bypassed by: removing networking code
METHOD 02
Mixin Targets
ModGuard reads every *.mixins.json inside each mod JAR and collects the Minecraft classes being injected into. A movement hack always targets LocalPlayer.
Bypassed by: restructuring all mixins
METHOD 03
Classpath Probes
Class.forName() checks for known hacked client classes at runtime. The class names are compiled into bytecode — they survive metadata and JAR repacking.
Bypassed by: renaming every class (breaks the mod)
METHOD 04
Entrypoint Class Hashes
SHA-256 of specific compiled .class files inside the JAR — not the whole JAR. The compiled bytecode hash is stable across cosmetic repacks that only change metadata.
Bypassed by: recompiling from source
The payload: On every server join, the client mod collects results from all four methods and sends them as a single JSON packet to the server. The server checks each layer in order and kicks or flags on the first match.
📦
Installation
CLIENT
Fabric Mod
Drop modguard-1.0.0.jar into .minecraft/mods/. Requires Fabric Loader 0.18.2 and Fabric API 0.140.2. Runs silently — no UI.
SERVER
Paper Plugin
Drop modguard-paper-1.0.0.jar into plugins/. Config files are created automatically on first start. No dependencies.
Note: Players without the client mod installed will be kicked after the configured timeout (default 10s) unless /modguard toggle required is disabled.
⌨️
Commands

All commands require the modguard.admin permission (default: op). Use /modguard with no arguments to see a usage summary in-game.

/modguard check <player> [-t]
info
View a player's verified modlist. Without -t shows full detail including version and SHA-256 hash prefix. With -t shows a tidy list of name, mod ID, and author.
ParameterDescription
<player>Online player name (tab-completable)
-tTidy mode: name | mod id | author
# Full detail
/modguard check Steve
# Tidy view
/modguard check Steve -t
/modguard ban <player> <modname|modid|*>
writes
Ban a specific mod from a player's verified modlist by name or ID, and save it to banned-mods.yml. Use * to ban every mod in the player's list at once (excluding system mods).
ParameterDescription
<player>Online player whose modlist to search
<modname|modid>Mod display name (partial match) or exact mod ID
*Ban all mods in the player's list
/modguard ban Steve meteor-client
/modguard ban Steve Meteor # partial name match
/modguard ban Steve * # ban everything
/modguard pardon <modid|*>
writes
Remove a mod from banned-mods.yml. Supports partial matching. Use * to clear the entire ban list.
/modguard pardon meteor-client
/modguard pardon * # clear all bans
/modguard banlist
info
Show all currently banned mods from banned-mods.yml with their ID, hash prefix, and reason.
/modguard capture <player> [flags] [modname]
writes
The primary anticheat command. Reads a player's full fingerprint payload and writes all selected ban types at once. A bare word at the end is treated as a mod filter — only that mod is targeted.
FlagDescription
--allDo all four types (default if no flags given)
--hashBan exact JAR SHA-256 hash
--idBan mod ID (all versions)
--channelsAdd channel fingerprint to fingerprints.yml
--classpathReport detected classpath flags (already auto-blocked)
--mod <name>Filter to a specific mod only
--reason <text>Custom ban reason
--name <text>Custom fingerprint name
--action kick|flag|logAction for channel fingerprint (default: kick)
# Full capture of everything
/modguard capture Steve
# Capture only one specific mod
/modguard capture Steve --all meteor-client
/modguard capture Steve --id totemequip
# Custom reason and fingerprint name
/modguard capture Steve --all --reason "Hacked" --name "Meteor fork"
Tip: Any word without -- at the end is automatically treated as --mod. So capture Steve --all hackedclient only captures the hackedclient mod.
/modguard flags | /modguard approve <player>
info
flags lists all players currently flagged by channel fingerprinting (action: flag). approve clears the flag and whitelists the player for the rest of the session — they won't be re-flagged until they relog.
/modguard flags
/modguard approve Steve
/modguard fplist
info
Show all loaded channel fingerprints from fingerprints.yml, including their action and channel patterns.
/modguard fpadd "<name>" <kick|flag|log> <channel1> [channel2...] [--reason <text>]
writes
Add a new channel fingerprint manually. Names with spaces must be wrapped in double quotes. Channels support wildcard suffix :*.
/modguard fpadd Wurst kick wurst:* --reason "Wurst hacked client"
/modguard fpadd "My Custom Client" flag myclient:* --reason "Unknown client"
/modguard fpremove "<name>"
writes
Remove a fingerprint by name. Case-insensitive. Saves to fingerprints.yml immediately.
/modguard fpremove "Meteor Client"
/modguard fpedit "<name>" <field> <value>
writes
Edit a specific field of an existing fingerprint in-game without manually editing the YAML file.
FieldDescription
actionChange to kick, flag, or log
reasonUpdate the kick/flag message
nameRename the fingerprint
addchannelAdd a channel pattern (e.g. meteor:*)
removechannelRemove a channel pattern
addmixinAdd a mixin target class to match on
removemixinRemove a mixin target class
addephashAdd an entrypoint class file SHA-256 hash
removeephashRemove an entrypoint hash
/modguard fpedit "Meteor Client" action flag
/modguard fpedit "Meteor Client" addchannel meteor-client:extra
/modguard fpedit "Meteor Client" addmixin net.minecraft.client.player.LocalPlayer
/modguard fpedit "Meteor Client" addephash a1b2c3d4e5f6...
/modguard toggle [required|nametags]
admin
Toggle runtime settings without restarting. Without arguments shows the current state of all toggles.
ToggleDescription
requiredWhether players must have the ModGuard mod installed to join. When disabled, players without the mod are allowed in silently.
nametagsWhether verified players get a ✔ prefix on their display name. Toggling off immediately removes the prefix from all online verified players.
# Show current state
/modguard toggle
# Allow unverified players temporarily
/modguard toggle required
# Disable name tag prefixes
/modguard toggle nametags
/modguard reload
admin
Reload config.yml, banned-mods.yml, and fingerprints.yml without restarting the server. Shows a summary of how many entries were loaded.
🔒
Permissions
Node Default Description
modguard.admin op Access to all /modguard commands
modguard.bypass false Skip all modlist checks entirely (for trusted staff)
⚙️
config.yml
# Seconds to wait for a player's modlist before kicking. verify-timeout-seconds: 10 # Show a ✔ prefix on verified players' names. verified-prefix: enabled: false symbol: "✔" color: "green" # aqua, gold, red, white, etc. show-in-tab: true
Chat plugin detection: ModGuard auto-detects LuckPerms, EssentialsX, and CMI on startup and routes the verified prefix through the appropriate API. Check the server log on startup to see which was detected.
🚫
banned-mods.yml

Each entry bans by mod ID, exact SHA-256 hash, or both. A match on either field kicks the player. Managed via /modguard ban, pardon, and capture.

banned-mods: # Ban by ID (any version) - id: "meteor-client" sha256: "" reason: "Hacked client." # Ban by exact JAR hash (specific build) - id: "" sha256: "a1b2c3d4e5f6..." reason: "Tampered JAR detected." # Ban by both (most thorough) - id: "wurst" sha256: "a1b2c3d4e5f6..." reason: "Wurst hacked client."
🧬
fingerprints.yml

Channel fingerprints detect mods by what they do rather than what they claim to be. Works even when a mod has been repacked with a different ID, name, or JAR hash.

fingerprints: - name: "Meteor Client" channels: # Method 1 — plugin channel namespaces - "meteor-client:*" mixin_targets: # Method 2 — Minecraft classes this mod injects into - "net.minecraft.client.player.LocalPlayer" entrypoint_hashes: # Method 4 — SHA-256 of compiled .class files - "a1b2c3d4e5f6..." action: kick # kick | flag | log reason: "Meteor Client detected."
Finding hashes for Method 4: Have a test player with the target mod join — their full payload including entrypoint_hashes is written to plugins/ModGuard/modlists.log. Copy the hash from there and add it with /modguard fpedit "<name>" addephash <hash>.
📋
Log Files

All files are written to plugins/ModGuard/.

FILE
modlists.log
Full JSON payload for every player that joins — allowed or kicked. Contains all four fingerprint method results. Use this to find hashes for new fingerprints.
FILE
flagged.log
Written when a player matches a fingerprint with action flag or log. Records which fingerprint matched and the specific channels/targets that triggered it.
📝
Changelog
Current
  • Method 2 — Mixin targets: client now reads all *.mixins.json files inside mod JARs and sends the full list of injected Minecraft classes
  • Method 4 — Entrypoint hashes: SHA-256 of specific compiled .class files inside mod JARs, stable across cosmetic repacks
  • fpedit: new fields addmixin, removemixin, addephash, removeephash
  • capture: bare word at end auto-treated as --mod filter; fpName auto-uses mod filter name
  • fpadd / fpremove / fpedit: quoted name support for fingerprints with spaces
  • Channel filtering: significantly expanded safe channel prefix list; channels filtered by mod namespace when --mod is set
  • Chat plugin detection: auto-detects LuckPerms, EssentialsX, CMI on startup
  • toggle: runtime toggle for mod requirement and name tags
  • verified prefix: ✔ symbol on verified players' display names and tab list
  • ban *: wildcard to ban all mods from a player's list
  • pardon *: wildcard to clear the entire ban list
Earlier
  • capture: single command to write hash, id, channel fingerprint, and classpath report at once
  • fpadd / fpremove / fpedit: full in-game fingerprint list management
  • Method 3 — Classpath probes: Class.forName() checks for known hacked client classes
  • Method 1 — Channel fingerprints: fingerprints.yml with wildcard channel matching
  • flags / approve: staff flagging workflow for suspicious but unconfirmed players
  • ban / pardon / banlist: ID and hash ban management
  • check -t: tidy modlist view with name, id, and author
  • Initial release: modlist collection and verification on join