Sell a Minecraft plugin, a FiveM script, a Discord bot or a desktop app, and someone will use it without paying. Usually it isn't a skilled cracker. It's one buyer sharing their copy with five friends, or a jar reposted on a leak forum the week you launch.

You can't make piracy impossible, and trying to usually hurts paying customers more than pirates. What you can do is make sharing inconvenient, make leaks traceable, and make paying the easy option. This is the plan I'd follow, in order. Each step is worth doing on its own, so stop wherever the effort stops paying off.

Step 0: Decide what you're actually fighting

Threat How common What stops it
A buyer shares their copy or key Very common Per-buyer keys and machine limits (steps 1-2)
A jar gets reposted on a leak site Common Per-buyer keys, watermarks, takedowns (steps 1, 6, 8)
Someone deletes your license check Less common, easier with AI editors Core unlock and obfuscation (steps 4-5)
A determined cracker rewrites your code Rare Nothing fully. Make it slow and not worth it

Most losses sit in the first two rows, and those are the cheapest to fix.

Step 1: Give every buyer their own key, automatically

A single shared password or license file can't tell anyone apart. Give each purchase its own key, so you can see who's using what and switch off exactly one person.

Don't do it by hand. Connect your store so keys are created at checkout. On BuiltByBit, an External license key placeholder writes the buyer's key into the jar they download. Voxel Shop and SpigotMC have their own placeholders, and Tebex, Stripe, Gumroad, Lemon Squeezy and others can create a key through a webhook. Wire refunds in too, so a refunded purchase loses its key.

Step 2: Limit where a key can run

A key that works everywhere is a key that gets shared. Set a limit that fits the product:

  • Plugins: servers per key (1-3 is typical).
  • Desktop apps: machines per key (2-3 covers a laptop and a desktop).
  • Bots or web tools: an IP address limit.

When the limit is reached, a new machine is refused with a clear message, and the buyer can free a slot themselves. Be generous: a support ticket costs you more than one extra machine.

A policy with Max machines and Max IPs per key

Step 3: Check at startup, and never take a customer down

Check the license when the app starts, then again every few hours. No need to phone home every minute. Above all, only stop on a clear "no" (revoked, suspended, expired, too many machines). If your license server can't be reached, keep running. BuiltByBit's DRM guidance says the same, and plugins that disable themselves when a server is down risk being removed. For a Minecraft plugin, I walk through this check line by line in How to add license keys to a Minecraft plugin in 10 minutes.

For customers without internet, ship a signed offline license: a file signed with a private key (Ed25519, for example) that your app verifies with the public key, and that expires on a date you set.

Step 4: Make the check hard to delete

A license check is one if statement. Anyone with a decompiler, or an AI editor, can delete it. Two things make that pointless:

  • Core unlock. Encrypt a small, essential piece of your code (a core class, default rules, a lookup table) and only decrypt it after a valid license check. Delete the check, and that piece is simply missing.
  • Tamper reports. Hash your own classes and report a modified copy with the next license check, so you know which license runs a patched build.

Step 5: Obfuscate your release builds

Rename classes and methods, encrypt strings and scramble control flow, so your check and your core are hard to find and patch. ProGuard gives a safe rename; ProGuard followed by Skidfuscator adds control flow and string encryption. Only obfuscate the build you sell, test it before upload, and keep the mapping file so you can read customers' stack traces. I wrote a step-by-step guide: How to obfuscate a Minecraft plugin.

Step 6: Watermark every download

Put something in each buyer's copy that names them: their license key in the jar, an ID in the manifest, a mark in the archive. When the jar shows up on a leak site, you know whose it was without guessing. It also deters sharing: people think twice when their copy carries their name.

Step 7: Watch for sharing

You won't spot a shared key by reading logs. Get alerts for the patterns that matter: one key on many machines at once, a key checking in from two countries an hour apart, a machine trying random keys, a revoked key still in use, a key pasted in your Discord. Then act on the real ones (a customer who travels isn't a pirate).

Sentinel watches license checks and flags shared and leaked keys

Step 8: Respond fast when something leaks

  1. Find the buyer from the watermark or the key in the leaked file.
  2. Revoke that key. Copies stop at their next check; everyone else is untouched.
  3. Send a takedown notice (DMCA) to the site hosting it. Most marketplaces also have a DMCA form.
  4. Revoke refunded and charged-back purchases too, or they keep a free copy.

Step 9: Make paying easier than pirating

The best anti-piracy feature is a product that's easy to buy. A fair price, a trial, fast updates, real support and a Discord. A pirate gets an old jar and no help. A customer gets the update that fixes their bug today.

The whole plan on one page

The plan, layer by layer: keys, limits, a safe check, core unlock, obfuscation, watermarks, alerts, response

How to put it together

You can build each layer yourself: a small key server, a signing key, an obfuscation step in your build, and a dashboard to revoke from. Or use a service. I build SunLicense, which covers the list:

Step In SunLicense Plan
1. Per-buyer keys from your store BuiltByBit, Voxel Shop, SpigotMC, Tebex, Stripe, Gumroad and more Free
2. Machine and IP limits Per policy Free
3. Safe startup check, offline files SDKs for Java, JavaScript, Python, .NET, PHP and Lua; signed Ed25519 files Free
4. Core unlock and tamper reports Seal up to 512 KB, 7 days offline grace Free
5. Obfuscation Maximum, ProGuard, yGuard, Skidfuscator; JavaScript, Python, Lua (FiveM) Free (3 runs a month)
6. Watermarked downloads The buyer's mark in each file Standard
7. Sharing alerts Sentinel detectors, Discord alerts Free
8. Revoke in one click Dashboard, CLI, Discord Free

It's free for 3 products and 100 licenses, with no credit card and no cut of your sales. See what SunLicense covers, then work through the list, starting with step 1.