Voxel Shop beta is live. Expect occasional bugs. Learn more
⚡ DupeWatch: Most Advanced next-gen Anti-dupe plugin for Paper/Spigot🚫✨
Every case now comes with a recording of the dupe itself.
DupeWatch keeps a rolling 120 seconds of activity for every player online, so the evidence is already saved before anyone knew to look for it. When a case opens, the area around the incident is frozen with it: 11 by 11 chunks, chunk aligned so a base never gets cut in half.
Open the case and you walk into a private copy of that scene. The suspect moves, drops land and get picked up, blocks go up and come down in the exact order they happened, and every player who was within 64 blocks is there with their real name and skin.
Play, pause, step, scrub, 0.25x to 4x, follow camera or free flight. Chest opens, commands and inventory jumps are marked on a timeline, and clicking one jumps playback to it. Their inventory opens as a live GUI that updates as you scrub.
Replay playback needs Packetevents, which is free. Everything else in the plugin works without it.
One button for the moment a dupe is happening right now and you do not know who or what yet. You can ban and roll back in an hour. You cannot get the evidence back.
Press it and DupeWatch writes every online player's replay buffer, inventory and ender chest to disk in under a second. Then it stops value moving: no paying, no trading, no dropping items. Players can still log in, mine, build and talk, and they are told nothing.
Then it sweeps every inventory and open chest for the same item serial in two places at once and hands you a report naming what was duped, who held it first, and who has it now.
Panic never bans, kicks or confiscates on its own. Every action on that report is a button you press.
Nothing it changes is written into your config, so lifting it puts everything back instantly, even after a crash. It also never expires by itself, because switching off in the middle of an outbreak is the worst thing it could do. It nags your staff in chat until somebody lifts it.
Command: /dw panic
Permission: dupewatch.panic
DupeWatch now watches for twelve known duplication methods as they happen, instead of only catching the duped item afterwards.
Six of them are things a normal Minecraft client physically cannot send, like creative-only packets from a survival player or a click on a chest the server does not have open. Those get blocked outright, so the dupe never happens.
The other six can happen to somebody with bad internet, so those open a case for you to read instead of getting cancelled. Cancelling a click that a lagging player really sent desyncs their inventory, and a desync is itself a dupe.
Two more are read straight out of your server log, including the encoder rollback dupe, which means DupeWatch now catches things your console was already quietly telling you about.
You can move any of them onto the block list in the config if you want to.
A full audit of every container on the server, including chunks nobody has loaded in months.
It reads which chunks exist without loading them, so it never generates terrain and your world folder does not grow.
It spends 2 ms per tick, keeps four chunk loads in flight at most, and stops completely the moment your TPS dips. It saves its place as it goes, so a restart mid sweep picks up where it stopped.
Nobody sees it except the person who started it, and findings collect into a report instead of spamming your alerts for hours.
There is a background mode that crawls forever on its own, so a stash buried in a base nobody visits turns up by itself.
It takes nothing by default. Turn confiscation on and every item gets written down before it moves, so /dw sweep undo puts it back in the same chest and the same slot.
Command: /dw sweep
Permission: dupewatch.sweep
When you give an item back from quarantine it now comes back with a brand new identity, so it does not get flagged again five minutes later.
The case file keeps every detail for your records.
If your rewards are built by copying a template item, every reward shares one identity, which looks exactly like a dupe.
DupeWatchAPI.get().items().resetFingerprint(item) strips the tracking tags so the item is treated as brand new.
It does not whitelist anything, it just stops template copies colliding.
DupeWatch is built against the latest Paper API and runs from 1.21.5 up through 26.x, on Paper, Spigot and Folia.
If you are still on 1.20 or 1.21.4, stay on 1.3.9 until you update your server.
Evidence capture is built in now.
The replay records the world itself, so there is no second plugin to keep in sync.
CoreProtect still works alongside DupeWatch, it is just not part of how cases are built anymore.
They used to be tied to Minecraft's own save format, which changes between versions, so the same sword came out different on 1.21.5 and 26.x.
They are now built from what the item actually is.
Your existing rules are re baselined automatically on first start, and your cases and history are left alone.
/dw heatmap and /dw cleanup no longer exist.
The replay does the same job properly: instead of a map of where things happened, you watch it happen.
One colour and spacing system across all of them, readable item names instead of raw fingerprints, and about 120 settings that used to need config editing now live in the settings menu.
Your existing config, rules, flags and cases all carry over.
The new sections are added on first start with sensible defaults, and Panic and Sweep both need a permission you have to grant before anyone can use them.
To update, drop in the new jar and restart.
The developer API jar has moved to dupewatch-api-1.4.0.jar.
Everything from 1.3.9 still works the same way, with items() added on top.
The plugin was still showing 1.3.5 in the console now it properly shows 1.3.7
This release supports the latest Minecraft 26 builds while remaining fully compatible with Minecraft 1.21.5 and newer. To update, simply replace your existing jar with the new one.
The developer API (dupewatch-api-1.3.5.jar) has not changed and remains fully compatible.
NOTE:
To update to v1.3.5, you must completely remove the old dupewatch.jar before starting your server. (files are okay you can keep the whole dupewatch folder only delete the jar)
When the server starts, DupeWatch will automatically generate a new loader.yml file. Your license key must now be placed in loader.yml instead of config.yml.
This change is required for the new update system. DupeWatch will use your license key to securely check for and download future updates automatically.
If you do not move your license key to loader.yml, the plugin will not start. Once your license key has been added, restart the server and DupeWatch will load normally.
What’s fixed?
Duplicate detection is now significantly faster.
Fixed an issue where identical items in a player’s inventory were not always detected correctly. This happened because the player wasn’t being flagged before new IDs were assigned, allowing duplicates to slip through.
What’s new?
Auto-Fingerprinting
Non-stackable items are now automatically assigned unique IDs.
This means custom armor, weapons, and other valuable non-stackables no longer need to be manually added one by one.
Stackable items are not included in this system and must still be added to the watchlist manually. (spawners, ores, etc)
🚀 Folia support is here
Took long enough. The plugin works with Folia now, concurrent region scheduling without everything catching fire.
🔴 Critical fixes
Services were initializing twice in onEnable(). That's fixed. Listeners don't duplicate on reload anymore either.
Race conditions in ChatInputManager and GuiManager are gone. ActiveFlagManager uses dirty tracking now, blocking calls got pulled out of hot paths, and flag clearing went from O(N) to O(K). There was also a sneaky ItemStack mutation bug that was corrupting data silently, that's dead.
License startup runs async safe, which it should have been doing from the start.
🟡 Detection tweaks
Thresholds are configurable now instead of hardcoded. Growth detection moved to config driven logic. ESCALATED states actually trigger deep scans instead of doing nothing useful.
Odd increment detection does something now. Added grace windows for world switches and new rules. Player join tracking got more consistent, which matters more than it sounds like it does.
🚀 Performance stuff
Watchlist updates batch process. Debug logging rate limits per player so you don't get 10,000 lines in three seconds. Heatmap writes buffer in batches. Regex patterns precompile, about time. All the existing async systems are still there.
🏗️ Code cleanup
CommandSanitizer has a strict allowlist. Ripped out dead code. CaseManager API is cleaner. Registry getters don't mutate anymore. TrollService was hitting the wrong players sometimes, that's fixed.
🎨 UI improvements
Alert tooltips are better. Quick action buttons added to alerts. Console output format changed. CaseView GUI has a summary panel now. Discord embeds are more customizable.
ConfigValidator shows warnings on startup if something's misconfigured. Added /dw status to see the full system state at a glance.
✨ New features
Per rule growth sensitivity, bumps the schema to v12. /dw export csv if you want to pull data out. /dw player <name> summary command. Case archiving works as soft delete now.
Heatmap overlays by detection type. ML rarity overrides if you need them. Automated false positive reporting, off by default. Startup grace period so the plugin doesn't freak out while the server warms up.
New Stuff
Bug Fixes
New Stuff
Bug Fixes
Under the Hood
You can now attach commands directly to detection rules.
Example:
If a player is caught with 500 duplicated items, DupeWatch can automatically run something like:
ban {player} Duping detected
Commands trigger automatically when the rule fires.
You can configure them in the GUI or inside ruleCommands.yml.
Supported placeholders:
{player}
{item}
{count}
This allows automatic punishments like bans, kicks, inventory clears, or anything else your server command system supports.
Full setup guide is available in the Discord.
The scan system did detect violations correctly, but the final message sometimes told admins:
"No issues found"
Even when something was actually detected.
The message now properly reflects the real scan results.
Servers with items created by older DupeWatch versions could crash when:
a player joined
an item was dropped
a scan ran
Older versions stored identity data differently.
Old items used a 32-bit number, while the new system uses a 64-bit number.
DupeWatch now detects both formats so old items no longer crash the plugin.
Some servers configured rule commands but nothing happened when rules triggered.
Two issues caused this:
Commands were executed from a background thread, which Bukkit does not allow.
Rule IDs reset after every server restart, which sometimes broke rule lookups.
Commands now run on the main server thread, and rule IDs now persist across restarts.
Several internal systems were improved:
Inventory change tracking
Money Watch service
Surge tracker
These changes reduce rare crashes and improve detection reliability.
Previously, placeholders like {player} or {item} were inserted directly into console commands.
In rare situations this could allow malformed values to alter the command being executed.
Placeholders are now validated and sanitized before commands run.
Some internal lists kept storing data but never removed old entries.
On active servers this could slowly increase memory usage.
Old data now cleans itself up automatically, keeping memory usage stable.
DupeWatch tracks suspicious activity per player.
Previously, if players left the server, their threat data could remain stored forever.
Inactive player data is now automatically removed after a period of time, preventing memory buildup.
When the plugin reloaded, some background database threads were not shutting down properly.
Over time this could create unused threads running in the background.
All database threads now shut down correctly during reload or shutdown.
One diagnostic database check ran directly on the main Minecraft thread.
On slower databases this could briefly freeze the server.
That check now runs asynchronously, preventing lag.
In rare cases the watchlist system could try to access data that did not exist yet.
Additional safety checks were added to prevent this crash.
Identity data used to save every 30 seconds.
If the server crashed before the next save, some recent identity data could be lost.
The plugin now forces a final save during shutdown, reducing the chance of data loss.
On first startup the plugin generates a secret key file.
In rare edge cases two processes could attempt to create the file at the same time.
The file creation process is now locked and atomic, preventing this issue.
Only a very small part of a SHA-256 hash was used to verify identity salts.
The system now uses a larger portion of the hash, making verification more reliable.
Several internal systems were improved for stability and performance:
Old command tracking data now cleans itself up
Plugin reload behavior improved
Temporary caches behave more predictably
Static counters made thread-safe
Configuration values now validated
Confiscation request data automatically cleans up
Recursive inventory scans now have safe depth limits
Statistics tracking made thread-safe
Error logging improved for easier debugging
Configuration loading simplified
Shared HTTP client implemented
Feature flag system cleaned up
Reduced unnecessary object cloning
Configuration upgrade process improved
Extra safeguards added for ID generation
id engine was giving new id's to all items regardless if it was in the watchlist or not, this has now been fixed!
i accidently removed webhook support from the config.yml now its fixed sorry about that!
This new version introduces an experimental Identity Engine. It is insanely complex and would take years to explain fully, but the short version is that every item on the watchlist now gets a unique, trackable ID. This allows the plugin to detect duplicates across inventories, chests, shulkers, and even nested containers, linking them back to their original owner. It is designed to catch dupes that traditional fingerprinting would miss while intelligently handling stack splits and item transfers to prevent false positives. False positives are still possible, so review everything carefully before banning any user. I also recommend using the threshold or max items option to set a maximum amount per player; even if someone somehow bypasses the plugin, the max amount detection will still catch them.
IT IS RECOMMEND IT TO DELETE AND RE-ADD ALL WATCHLISTED ITEMS AGAIN!
Major Features & Improvements
DELETE YOUR MESSAGES.YML BEFORE STARTING YOUR SERVER THERE IS A NEW UPDATE THERE TOO!
New Features & Enhancements:
Detection Profiles:
Introducing a fully configurable Threat-Adaptive Detection System. You can now choose between LOW, NORMAL, and AGGRESSIVE detection modes directly from the main menu.
LOW: Conservative scanning; only triggers heavy scans for highly suspicious behavior. Minimal server impact.
NORMAL: Balanced detection; standard scanning thresholds and math checks. Default mode.
AGGRESSIVE: Maximum vigilance; lowers thresholds, increases suspicion gain, slows decay, expands pattern analysis, and monitors relational container activity for smarter detection. Perfect for high-security servers.
Profiles dynamically adjust how DupeWatch evaluates player activity, suspicion scores, and tiered detection (Tier 1 lightweight events vs Tier 2 deep analysis). Switching profiles applies immediately without interrupting ongoing scans.
Player SuspicionScore & Lifecycle:
Players now move through a structured lifecycle: CLEAN → MONITORED → ESCALATED → COOLDOWN → FLAGGED.
Tier 1 detection (pickup events, inventory interactions) feeds the SuspicionScore, which controls escalation to heavier Tier 2 modules (ScanBasedDetectionService, ContainerWatchService).
Score decay, threshold modifiers, and dwell-time rules prevent thrashing and ensure accurate, CPU-friendly detection even under heavy activity or macro bursts.
Smart Tiered Scanning:
Tier 1: Always-on, lightweight event tracking (SurgeTracker, inventory/container listeners). Fire-and-forget signals.
Tier 2: Heavy-duty scans triggered only for monitored/escalated players. Includes deep math pattern checks, container content logging, and relational awareness (e.g., if Player A triggers ESCALATED in a container, Player B interacting with the same container is monitored).
ScanDispatcher ensures safe snapshot scheduling, rate-limited per tick, and async processing to prevent server freezes.
Fixes:
Copper Chest Support: All copper chest variants are now fully detected by DupeWatch. This includes:
copper_chest, exposed_copper_chest, weathered_copper_chest, oxidized_copper_chest
waxed_copper_chest, waxed_exposed_copper_chest, waxed_weathered_copper_chest, waxed_oxidized_copper_chest
Items inside any of these chests are now properly scanned, flagged, and included in duplication detection. Double chests using these variants are fully supported.
Safety Invariants & Performance:
Max snapshots per tick, bounded async queues, ephemeral fingerprint caching, and per-player cooldowns ensure even AGGRESSIVE mode cannot crash the server.
Redundant scans are eliminated; coalescing scan requests and tick-level burst clamping keep CPU usage minimal.
Other Improvements:
Dynamic hot-swapping of detection profiles from the main menu without restarting the server.
All profile changes immediately affect gain, decay, threshold, and Tier 2 analysis depth.
Logs and alerts now respect profile settings, giving admins clear, actionable information.
Since update 1.2.1, custom items from EcoItems, MMOItems, and other plugins were not being detected correctly. This update fully resolves that issue. All existing custom item plugins are now supported, and any new custom item plugins will be detected automatically through a dynamic system.
There was a small error that happend when you type /dupewatch, its fixed now :)