Documentation·Paper and Folia 1.21+

DupeWatch
Wiki

Everything you need to install, activate and run the most advanced anti-dupe plugin for Minecraft. From your very first watch rule to tracing exactly how a dupe spread across your server, it is all here. Clean setup, powerful detection, no guesswork.

Get started
0%+
CPU reduction
vs. naive scanning
<0.00ms
Event handling
off thread, off your TPS
0
GUI screens
no commands required
0.00.5+
Paper / Folia
single artifact
Introduction

What is DupeWatch?

DupeWatch spots duplicated items on your server using advanced fingerprinting, opens investigation cases, and gives your staff a full point and click workflow to review, resolve and act. Optional Discord alerts keep your team in the loop.

Smart scanning

It scans inventories, ender chests and nested containers using semantic item fingerprints.

Growth detection

It spots items multiplying over time (5, 10, 20, 40) across scan cycles, not just raw counts.

Case management

Create, annotate, export, confiscate and resolve. A full investigation lifecycle in one place.

15-screen GUI

Run everything with clicks. Commands are there too, for power users and automation.

Discord alerts

High signal webhooks for new cases and confiscations, without the spam.

Built for scale

Caching, bloom filters and async work keep big servers smooth.

The detection pipeline
Scan
Fingerprint
Detect growth
Open case
Gather forensics
Act
About 5 minutes

Quick Start

The quickest path from download to catching your first dupe. Each step links to a deeper section below.

1

Install the loader

Drop the DupeWatch loader jar into plugins/ and start the server once. It writes a loader.yml file.
2

Add your license

Paste your key into loader.yml, then restart so the loader can verify it. See License.
3

Make your first rule

Hold the item you want to watch, open /dw, go to Watchlist and click Add From Hand. See Rules.
4

Try it out

Run /dw scan on a player, then open the Cases screen to see what turned up.
/dw scan <player>
Pro tip
Start with high thresholds (100 or more) and short time windows while you are testing, then tighten them once you get a feel for how your economy behaves. Every rule is editable live from the GUI.
Setup

Installation

DupeWatch ships as a single drop-in jar. Here is what it needs and where its files live.

Requirements

Server software

Paper or Folia, Minecraft 1.21.5+. Folia is fully supported.

Java runtime

Java 21+ at runtime. The jar loads all the way up to the Java 25 ceiling.

Storage

SQLite out of the box. MySQL is there if you run a network.

Soft deps

PacketEvents unlocks forensic replay and Vault unlocks Money Watch. Both optional.

Steps

  1. 1Download the latest DupeWatch loader jar from your purchase.
  2. 2Drop it into your server's plugins/ folder.
  3. 3Start once, add your license to loader.yml (see License below), then restart.
  4. 4Once it is verified, tune config.yml to taste and run /dw reload.

Where things live

plugins/DupeWatch/
loader.ymlYour license key (the Lukittu loader reads this)
config.ymlPlugin settings: scanning, Discord, Money Watch
messages.ymlEvery GUI title, button and message
watchlist.jsonYour watch rules
data.dbThe SQLite database (default storage)
cases/Exported investigation cases
Activation

License & Activation

DupeWatch is protected by the Lukittu loader. After you buy, you collect your license key from our Discord, drop it into loader.yml, and restart. Updates take care of themselves after that.

Getting your license key

Keys are handed out in our Discord, not at checkout.

  1. 1. Buy DupeWatch
    Buy direct on our site for the lowest price, or grab it on BuiltByBit / VoxelShop.
  2. 2. Open a Discord ticket
    Join our Discord, open a ticket, and post your proof of purchase.
  3. 3. Receive your key
    A staff member sends your license key right there in the ticket.
Open a ticket in Discord

Once you have your key, open plugins/DupeWatch/loader.yml and paste it in:

plugins/DupeWatch/loader.yml
# Lukittu Loader Configuration
license-key: "XXXX-XXXX-XXXX-XXXX"

Then restart your server. The loader checks the key on startup and pulls the plugin down once it is valid. A plain /dw reload will not re-run the loader, so use a full restart for this step.

How the loader works
Your download is a secure Lukittu loader. On startup it verifies your license, then loads and runs the real DupeWatch inside a protected environment. That is what keeps the plugin safe from leaks and lets new versions ship to you automatically.
Keep your key private
Treat your license key like a password. Share it only inside your own Discord ticket, never in public channels, logs or screenshots.
No commands needed

The GUI System

A clean point and click interface across 15 screens. Your staff can run the whole workflow without typing a single command.

Main Menu
Central hub. Jump to every feature.
Watchlist
Browse, add and manage watch rules.
Add Rule
Add the item in your hand as a new rule.
Edit Rule
Tune thresholds, scope, severity and actions.
Scan Player
Pick a player and run a manual scan.
Cases
All active investigation cases, searchable.
Resolved Cases
Browse closed cases, searchable.
Case View
Evidence, notes, confiscate and export.
Player Cases
Every case for a specific player.
Settings
Adjust plugin behaviour on the fly.
Inventory Snapshot
A frozen snapshot of an inventory.
Live Inventory
Watch a player's inventory in real time.
Forensic Replay
Watch the crime scene back in-game.
Confirmation
A safety gate for destructive actions.
Search anything
Use the compass at the bottom of the Cases and Resolved Cases screens to search by player name (left click) or by Case ID (right click).
The heart of DupeWatch

Watchlist & Rules

A rule says what to watch for and what happens when it triggers. You build one straight from the item in your hand, all through the GUI.

add a watch rule
1 / 5
NTH
Hold the item

Put the item you want to watch in your main hand.

Rule settings

Threshold
How many matching items before it triggers (say 30).
Time window
The rolling window, in seconds, that counts toward the threshold.
Scope
inventory, inventory+ender, or everywhere.
Severity
low, med or high. Drives alert urgency and the Discord colour.
Added from the GUI
There is no instant command to add a rule. You hold the item, open /dw, and click Add From Hand in the Watchlist. That captures the item's exact fingerprint.
threshold tuning
Trigger threshold30 items / 60s
Items seen this window18
Under threshold, so nothing happens.
scan scope
Inventory
Main + hotbar
scanned
Ender chest
Per-player vault
scanned
Nested containers
Shulkers & bundles

Actions when a rule fires

ALERT_STAFF
Send an in-game alert to all online staff.
LOG_CASE
Open a full investigation case.
DISCORD_WEBHOOK
Fire a Discord alert via webhook.
RUN_COMMANDS
Run configured commands (ban, jail, notify…).
CONFISCATE_OPTIONAL
Enable the confiscate option on the case.
The engine

Scanning & Detection

DupeWatch identifies duplicated items with semantic fingerprinting and watches how stacks grow over time, so it keeps catching dupes even after a Minecraft update.

live scan · Netherite Ingot
count / scan cycle
·
·
·
·
·
·
scan #1threshold: 30 / 60sscan #6
Fingerprinting items and tracking growth across scan cycles…
material:netherite_ingotname:§6Tycoon Barlore[2]enchants{}custom_model:14502pdc(filtered)
················

The same logical item hashes identically across Minecraft versions, so dupes are still caught after an update.

manual scan
CBL
DIA
NTH
EMR
STN
GLD
NTH
DIA
AME
NTH
IRN
RED
detection pipeline
item
Material filter
Bloom filter
Fingerprint
Match

Most items are rejected in microseconds before any heavy work happens.

Fingerprint matching

It compares type, name, lore, enchants, custom model data and filtered PDC, not raw bytes.

Growth patterns

It flags items multiplying across scan cycles, not just a high count on its own.

Bloom filters

Sub-microsecond material pre-filtering skips items it does not care about instantly.

Dirty-flag scanning

It only scans inventories that actually changed since the last cycle.

Rate limiting

Global alert caps and per-rule cooldowns stop alert spam before it starts.

Smart de-duplication

It avoids opening noisy duplicate cases for the same underlying issue.

Investigations

Case Management

Every triggered rule opens a case with a full lifecycle. Work them in-game or wherever your staff are most comfortable.

case #4F2A
Status
New
Case opened automatically from a rule trigger.

Review

See the evidence, the player, the flagged items and the forensic context.

Annotate

Drop staff notes on any case so the next person has the full story.

Export

Save a case to JSON for your records or an external review.

Resolve

Close it out. Resolved cases stay searchable and can be reopened.

Nothing is ever lost
Resolved cases move to their own searchable tab and can be reopened if new evidence shows up. The history sticks around for audits.
Clean up

Quarantine & Confiscation

Pull duped items out of circulation safely, and hand back any false positives as fully legitimate items with no leftover flags.

confiscation
Quarantine: 0
NTH×64
NTH×64
NTH×64
DIA
DIA
DIA
DIA
DIA
DIA
DIA
DIA
DIA

Confiscate

Remove flagged items from a player's inventory and ender chest, behind a confirmation gate.

Quarantine

Hold seized items for review instead of deleting them. Hand them back later if the player is cleared.

Identity regeneration

Returned items get fresh IDs and cleared flags, so they behave just like newly spawned legit items.

No re-flag loop
Because returned items are re-minted, a cleared player can use them normally without instantly tripping detection again, while the case history is kept for audits.
Integration

Discord Alerts

Real time alerts in your staff channels, kept deliberately to high signal events so your channels stay clean and actually useful.

DW
DupeWatchApptoday at 14:32
New Investigation Case
Player
Steve_92
Severity
High
Item
Netherite Ingot ×68
Rule
netherite_watch
DupeWatch · Case #4F2A · today at 14:32

Click a severity to see how the embed recolours.

config.yml
discord:
enabled: true
webhookUrl: "YOUR_WEBHOOK_URL"
override: false # true routes ALL rules through this webhook
webhook:
username: "DupeWatch"
colors:
low: 0x00FF00 # green
med: 0xFFA500 # orange
high: 0xFF0000 # red

Per-rule webhooks

Route important items to their own channel, or send everything through one global webhook.

Role pings

Optionally ping a staff role on high severity cases so nothing slips by.

/dw testwebhook <fingerprint>
Economy

Money Watch

Vault integration that watches for suspicious economy activity, like the tell tale balance spikes that tend to follow a dupe.

balance / time

Steady earning curve. Nothing to see here.

Anomaly detection

It flags sudden balance spikes, doubling and abnormal growth rates.

Balance tracking

It keeps a rolling history of balance snapshots for trend analysis.

Your thresholds

Set the minimum amount, the doubling threshold and the growth rate limit.

config.yml
moneywatch:
enabled: true
pollIntervalSeconds: 5
anomaly:
minAmountThreshold: 100.0
balanceDoublingThreshold: 2.0
growthRateThreshold: 5.0
Forensics

Forensic Replay

When a case opens, DupeWatch has already recorded the crime scene. Watch exactly how the dupe happened, tick by tick, from a clean in-game viewer. No third-party logger required.

forensic replay
-0:42Broke a spawner
-0:31Opened a double chest
-0:18Placed 3 shulker boxes
-0:05Said "dupe stack" in chat
0:00DupeWatch flagged the inventory

The scene, recorded

Three streams are captured around every suspect: the world's block truth, the suspect's own movement and inventory, and every nearby player, item drop and container open, attributed by name.

Watch it back in-game

The suspect and everyone near them replay as ghosts with tick-accurate position sync. Dropped items arc with real physics, containers keep their contents, and a live readout shows ML confidence, the rule, ping and coordinates.

Rolling buffer, per case

An adaptive buffer holds the last seconds of everyone in view. The moment a case opens it is written to disk and kept for your configured retention.

Built in, needs PacketEvents
Replay records the world itself, so there is no CoreProtect dependency. Install PacketEvents to enable the entity streams, then set your retention in config.yml. Nothing else to wire up.
Item tracking

Item Identity Engine

It tracks how individual item stacks move across your server, so you can see exactly how a dupe spread.

item spread
StSteve
AlAlex
BoBob
MiMia
KaKai

The identity engine traces every hand a duped item passes through.

Stack IDs

Unique IDs are minted into item stacks using Persistent Data Containers.

Ownership registry

It tracks who has held an item and when, building a chain of custody.

Spread graph

It maps how duplicated items propagate from player to player over time.

Version independent
Fingerprints are built from semantic item fields, so the same item hashes identically on 1.21.5 and 26.x. Dupes are still caught after a Minecraft update.
Integrations

PlaceholderAPI

DupeWatch publishes 131 read-only placeholders to any PlaceholderAPI-aware plugin: scoreboards, tab lists, holograms, chat. Install PlaceholderAPI and they register automatically. There is nothing to fetch from the eCloud and nothing to configure.

Setup: it registers itself
Install PlaceholderAPI and that is the whole setup. On the next start you will see[DupeWatch] PlaceholderAPI found - registered 131 %dupewatch_...% placeholders. Without PlaceholderAPI, DupeWatch behaves exactly as before: no errors, no warnings, no cost. Confirm it is live with/papi parse me %dupewatch_cases_active%.
Booleans
Render as PlaceholderAPI’s own yes/no wording, so DupeWatch matches every other expansion.
Empty vs N/A
Empty = valid but nothing to show right now. N/A = that subsystem is disabled or not installed.
Timestamps
Raw epoch millis; the matching _age / _ago token gives it as 3d 4h.
Never blocks
DB-backed values are cached (30s server-wide, 60s per-player) and never fetched on the render thread.
131 / 131
Server-wide
Ignore the player they are parsed for.

Plugin

4
Installed DupeWatch version, e.g. 1.4.9.
Whether DupeWatch has finished starting and its API is usable.
Whether debug logging is switched on in config.yml.
Whether the cached server-wide counters have been read at least once.

Cases & flags

4

These counters come from the database and refresh every 30 seconds.

Unresolved investigation cases, server-wide.
Resolved cases, server-wide.
Active + resolved.
Active flag states currently held in memory (one per player + watched item).

Watchlist rules

9

Get a fingerprint from /dw → Watchlist. A fingerprint with no rule renders empty.

Number of watchlist rules loaded.
Whether a rule exists for that item fingerprint.
The rule's display label.
How many of the item trigger the rule.
The rule's detection window, in minutes.
The rule's maximum allowed amount.
Where the rule looks (inventory, ender chest, …).
The rule's severity.
The rule's actions, comma-separated (capped at 16).

Scanning

5
Whether periodic inventory scanning is on.
Configured interval between scans of an online player.
Configured per-player scan cooldown.
Maximum concurrent scans allowed.
Players with scan history currently held in memory.

Quarantine

4
Whether quarantine is enabled in config.yml.
Whether quarantine is usable right now (enabled and confiscation in QUARANTINE mode).
The configured confiscation mode.
Items currently held in quarantine, server-wide. Refreshed every 30s.

Detection, ML & Exploit Guard

9
The detection profile in force right now (reflects a Panic Mode override when active).
The profile config.yml asks for, ignoring any Panic override.
Whether Exploit Guard is running.
Whether the ML system is enabled.
Whether a trained model is currently loaded.
Whether ML is running degraded (falling back to heuristics).
Epoch millis of the last training run, or never.
How long ago that was, or never.
Configured ML confidence threshold.

Panic Mode

20

All panic_* except panic_enabled / panic_active render empty when there is no lockdown or report yet.

Whether Panic Mode is available at all.
Whether a lockdown is engaged right now.
Current lockdown ID.
Reason given when it was engaged.
Who engaged it (empty for console).
Epoch millis it was engaged.
How long the lockdown has been running.
Whether an outbreak report exists.
How long ago that report was generated.
Whether the report found an actual outbreak.
Distinct item identities found in two places at once. The core outbreak number.
Items the diagnosis examined.
Players holding at least one colliding identity.
Containers holding colliding identities.
Material with the most colliding identities.
Total quantity of that material across colliding stacks.
How many colliding identities that material accounts for.
Name of whoever held a colliding identity first.
Replay buffers written to disk when the lockdown was called.
Inventory snapshots preserved at the same moment.

Clean Sweep

19

sweep_running and sweep_queued_worlds always answer; the rest describe the current session and render empty when idle.

Whether a sweep is in progress.
Worlds still waiting in a sweep all.
Current sweep's ID.
World being swept.
MANUAL or BACKGROUND.
RUNNING, PAUSED, FINISHED, STOPPED or FAILED.
Who started it.
Epoch millis it started.
How long it has been running.
Progress as 0.00 to 1.00.
Progress as a whole-number percentage.
Chunks finished.
Chunks to do.
Chunks skipped (unreadable or empty).
Containers scanned so far.
Items scanned so far.
Findings recorded so far.
Why it is not doing anything right now, if idle.
Whether Panic Mode paused it rather than an operator.

Replay

11
Whether replay is enabled in config.yml.
Whether replay actually came up (needs PacketEvents).
Why it did not, in plain words. Empty when replay is fine.
How long recordings are kept.
Length of the rolling capture buffer.
Whether anyone is being recorded at all.
Live capture buffers.
Players whose entity stream is being recorded.
Frames sampled since startup.
Inventory diffs actually run.
0.00 to 1.00 share of samples that skipped the expensive inventory diff.

Economy: Money Watch & Pay-All

8
Whether Money Watch is enabled in config.yml.
Whether it is actually running (needs Vault).
Players currently carrying a money dirty flag.
Whether a working Vault economy provider is available.
The economy provider's name.
The currency name.
Whether Pay-All detection is enabled.
Whether it is running.

Container Watch

2
Whether container logging is on.
How long container logs are kept.
Per-player
Describe whoever the placeholder is parsed for: the scoreboard owner, tab entry, chat sender.

Player · Cases

11

Counts the cases DupeWatch keeps in its recent-case cache; very old cases are still in the DB and in /dw.

Whether they have at least one unresolved case.
Cases on record for them.
Of those, how many are unresolved.
Of those, how many are resolved.
Their newest case's ID.
The rule that opened it.
Its severity.
Epoch millis it was opened.
How long ago that was.
Items recorded on it.
ML confidence for that case, or empty if ML did not score it.

Player · Risk

5
Their numeric risk score, two decimals.
Enum name: MINIMAL, LOW, MODERATE, HIGH, EXTREME.
The same, human-readable: Minimal … Extreme.
The legacy colour code for that level (§7, §a, §e, §c, §c§l).
Score and label, pre-coloured, e.g. §e2.30 §7(Moderate).

Player · Flags, scanning & state

10
Flag states held for them (any state).
Of those, how many are currently ACTIVE.
Their items currently in quarantine.
Threat lifecycle state: CLEAN, MONITORED, ESCALATED, FLAGGED.
Whether a scan of them is running right now.
Scans of them held in history.
Epoch millis of their last scan.
How long ago that was.
Whether they hold dupewatch.bypass. Always no while offline.
Whether Container Watch treats them as flagged.

Player · Replay

2
Whether they currently have a live replay buffer.
Whether they are inside a replay session as a viewer.

Player · Money

8
Whether they carry a money dirty flag.
Why it was raised.
The flagged amount.
How many hops from the original flagged player the money reached them. 0 is the source.
Whether they are the primary (source) flag rather than a downstream recipient.
The last balance DupeWatch recorded for them. Empty when it has none.
Whether Pay-All detection has them blocked.
Seconds left on that block.
Staff scoreboard
scoreboard.yml
lines:
- '&cActive cases: &f%dupewatch_cases_active%'
- '&cQuarantined: &f%dupewatch_quarantine_total%'
- '&cProfile: &f%dupewatch_profile%'
- '&cPanic: &f%dupewatch_panic_active%'
Risk tag in the tab list
tab.yml
%player_name% %dupewatch_player_risk_color%[%dupewatch_player_risk_label%]
Clean Sweep hologram
hologram
Clean Sweep · %dupewatch_sweep_world%
%dupewatch_sweep_percent%% (%dupewatch_sweep_chunks_done%/%dupewatch_sweep_chunks_total%)
Findings: %dupewatch_sweep_findings%
Built for scale

Performance

DupeWatch is built for busy servers. The optimizations are on by default and manage themselves.

main-thread CPU
~85%80% lighter

Caching, bloom filters and dirty-flag scanning keep the main thread quiet.

0%+
CPU reduction
<0.00ms
Event handling
0k
Fingerprint cache
5 min TTL
0%+
Cache hit rate
typical
Server sizeCache hit rateMemoryCPU reduction
Small (1 to 50)85 to 90%under 30 MB75 to 80%
Medium (50 to 200)90 to 95%30 to 40 MB80 to 85%
Large (200+)90 to 95%40 to 50 MB80 to 85%
Watch it live
Run /dw stats or turn on debug.enabled to see cache hit rates and any slow operation warnings.
Reference

Commands

Most of the work lives in the GUI, but every action has a command for power users and automation. The base command is /dupewatch, with /dw as a shortcut.

CommandWhat it doesPermission
/dwOpen the main DupeWatch GUI, the hub for everything.review
/dw scan <player>Run a manual scan of a player's inventory and ender chest.scan
/dw case <caseId>Open a specific investigation case in the GUI.review
/dw note <caseId> <text>Attach a staff note to a case.review
/dw resolve <caseId>Mark a case as resolved.admin
/dw exportcase <caseId>Export a case to JSON for external review.review
/dw webhook <fingerprint> <url>Set a per-rule Discord webhook URL.admin
/dw testwebhook <fingerprint>Send a test Discord webhook for a rule.admin
/dw statsShow live performance and cache statistics.review
/dw reloadReload config, messages and the watchlist.admin
Rename the command
You can rename /dw to anything you like (say /antidupe) from the command section of config.yml. That one needs a full restart, not just a reload.
Reference

Permissions

Granular nodes let you hand staff exactly what they need. Here are some sensible preset groups.

Permission nodeGrantsDefault
dupewatch.reviewView the GUI, cases and evidenceop
dupewatch.adminManage rules and destructive actionsop
dupewatch.scanRun manual scansop
dupewatch.alertsReceive in-game staff alertsop
dupewatch.confiscateConfiscate suspicious items from casesop
dupewatch.containerwatch.viewView container watch logsop
dupewatch.containerwatch.clearClear container watch logsop
dupewatch.moneywatch.viewView Money Watch status and graphsop
dupewatch.bypassExempt a player from all detectionfalse
dupewatch.payall.bypassBypass pay-all mass payment detectionfalse
Administrators
adminreviewscanalertsconfiscate
Staff and moderators
reviewscanalertsconfiscate
Trusted players
bypass
Reference

Configuration

Almost everything is configurable through config.yml (750+ lines) and messages.yml (460+ lines). The essentials are below, and every option ships with inline comments.

Database

config.yml
database:
sqlite: # the default, no setup needed
filename: "data.db"
mysql:
enabled: false # flip to true for MySQL + HikariCP pooling
host: "localhost"
port: 3306
database: "dupewatch"
user: "dupewatch"
password: "password"
migration:
autoMigrateOnStartup: true # moves file data into the DB, originals kept
backup:
enableAutoBackup: true # auto backup before upgrades

Scanning

config.yml
scan:
maxItemsPerScan: 1000 # cap items scanned per player
onlyDirty: true # only scan inventories that changed
sampleFraction: 0.1 # also re-check 10% of "clean" players
maxConcurrentScans: 5 # parallel scan cap
minimumScansForDetection: 5
growthDetection:
doublingThreshold: 0.15
triplingThreshold: 0.20

Money Watch

config.yml
moneywatch:
enabled: true
pollIntervalSeconds: 5
anomaly:
minAmountThreshold: 100.0
balanceDoublingThreshold: 2.0
growthRateThreshold: 5.0
Apply changes instantly
Most settings hot reload with /dw reload. The config-version field is managed for you, so do not edit it by hand.
Help

Troubleshooting

Quick fixes for the things people hit most often. Still stuck? Our support team is one click away.

Questions

Frequently Asked

Ready to lock down your economy?

Set DupeWatch up in minutes and run the whole thing from the in-game GUI.

Get support