Sueta
AN

AntiESP

1.0.0

A working AntiPlayerESP, AntiBlockESP, AntiXray and AntiFreecam Plugin.

·Plugin

AntiESP

A Paper plugin that makes ESP / wallhack / xray cheats far less useful by never
sending the client information it should not be able to see in the first place.

Three independent protections in one plugin:

#ProtectionWhat it does
1Player hidingPlayers behind walls are removed client-side for the viewer (optionally keeping a floating nametag and their tab-list entry).
2Block disguiseChests, shulkers, spawners, barrels … look like plain stone from a distance.
3Ore obfuscatorSelf-written anti-xray: real ores are hidden, fake ore veins are scattered in, and caves can be filled with solid rock (freecam-proof).

Everything is configurable in config.yml, and every feature can be turned off
individually.


Requirements

  • Paper 1.21.8 (or a compatible build) — the plugin uses the Paper API
  • Java 21
  • Optional: PacketEvents
    — required for packet mode (cave filling / freecam protection) and for keeping
    hidden players in the tab list. Without it the plugin still runs, just with the
    block-mode feature set.

Installation

  1. Drop AntiESP-1.0.0.jar into your server's plugins/ folder.
  2. (Recommended) Drop PacketEvents into plugins/ as well.
  3. Start the server — plugins/AntiESP/config.yml is generated on first run.
  4. Before going live with packet mode, run the identity-test once (see
    Ore obfuscator).

Building from source

mvn clean package

The jar ends up in target/AntiESP-1.0.0.jar. Both dependencies are provided,
so nothing is shaded in — the jar stays tiny.


1) Player hiding

For every viewer/target pair the plugin ray-traces the line of sight
(Amanatides & Woo voxel traversal, RayTracer) and picks one of three states:

  • VISIBLE — close by or in clear sight: nothing changes.
  • NAMETAG — occluded at medium range: the player model and hitbox are hidden,
    but a floating name (a proxy TextDisplay) stays visible.
  • GONE — occluded and far away: completely invisible.

Hiding starts at min-distance (default 12 blocks) and only when more than
walls-to-hide opaque blocks are in the way. Several target points on the body
are checked — a player is only hidden when all of them are occluded, so nobody
pops out of existence while half-visible around a corner.

Key options:

OptionDefaultMeaning
check-interval-ticks10How often visibility is recalculated
min-distance12.0Below this distance players are always visible
max-distance96.0Upper bound for the check (0 = no limit)
walls-to-hide2Hide when the wall count is greater than this
require-occlusiontrueOnly hide genuinely occluded players
keep-nametagstrueKeep the floating name for hidden players
nametag-max-distance48.0Beyond this the nametag disappears too
keep-tablisttrueKeep hidden players in the tab list (needs PacketEvents)

Sneaking hides the nametag immediately instead of waiting for the next tick.

Note: a visible nametag still roughly gives away a position. Set
keep-nametags: false for the strongest protection.

2) Block disguise

Valuable block-entities are replaced with stone (disguise-as) via
sendBlockChange for viewers that are far away or looking through walls. Walk
closer than reveal-distance and the real block comes back, so containers open
normally. Uses only the Bukkit API — no ProtocolLib, no PacketEvents.

By default chests, trapped chests, ender chests, barrels, hoppers, droppers,
dispensers, all shulker boxes, spawners, trial spawners, vaults, brewing stands,
beacons, furnaces, blast furnaces, smokers and decorated pots are disguised. Edit
the block-disguise.blocks list, or set all-block-entities: true to cover every
block-entity (signs and banners included — this is noticeable).

3) Ore obfuscator (anti-xray)

A fully self-contained anti-xray implementation — no Paper anti-xray, no
Orebfuscator. Real ores are sent as stone/deepslate and fake ore veins are grown
in natural Y ranges and vein sizes.

Two modes:

Block modePacket mode (recommended)
Needs PacketEventsnoyes
Hide enclosed real ores✅✅
Scatter fake ore veins✅✅
Fill small enclosed pockets✅✅
Fill large open caves (freecam-proof)❌✅
HowsendBlockChange after chunk loadrewrites the CHUNK_DATA packet itself

Ores that border air are left real — you would see them anyway — so the world
"normalizes" itself exactly where a player could legitimately look. In packet
mode a proximity reveal flood-fills through the connected cave air you are
standing in and uncovers the whole cave system, direction-independently, spread
across a few ticks. Revealed blocks stay revealed until relog. Nether and End are
not obfuscated at all.

The fake pattern is seeded from a secretSalt generated with SecureRandom at
every server start (RAM only) XOR'd with the chunk coordinates: stable per chunk
(no flickering), but not reproducible without the salt.

Test packet mode first. Rewriting the chunk binary format is version
sensitive. Set ore-obfuscation.identity-test: true, restart, and check that
the world looks normal — that decodes and re-encodes every chunk packet without
changing anything. If it looks fine, set it back to false.

Full details, tuning advice and the honest limitations (notably: anyone who
knows the world seed can regenerate ore positions server-side, no client-side
obfuscation can prevent that
) are in docs/ANTI-XRAY.md.


Commands & permissions

CommandDescription
/antiesp reloadReload config.yml and clear the chunk cache
/antiesp statusShow the active settings, mode and cache sizes
PermissionDefaultDescription
antiesp.adminopAccess to /antiesp
antiesp.bypassfalseThis player is never hidden from others and sees the real, unobfuscated world

packet-mode and identity-test are only applied on a server restart, not
via /antiesp reload.


Project layout

src/main/java/dev/antiesp/
  AntiESPPlugin.java          entry point, events, commands
  PlayerVisibilityService.java player hiding + proxy nametags
  TabListKeeper.java          keeps hidden players in the tab list (PacketEvents)
  BlockDisguiseService.java   container/block-entity disguise
  OreObfuscationService.java  anti-xray, block mode
  ChunkPacketObfuscator.java  anti-xray, packet mode (CHUNK_DATA rewriting)
  ProximityRevealer.java      persistent flood-fill cave reveal
  RayTracer.java              voxel ray tracing for occlusion counting
src/main/resources/
  config.yml, plugin.yml
docs/ANTI-XRAY.md             in-depth anti-xray documentation (German)

Performance notes

  • Packet mode computes per chunk on the Netty threads; results are cached
    (max-cache-chunks, default 6000) and invalidated when blocks are mined.
  • Only player block-breaking invalidates the cache — TNT, pistons and water do
    not, currently.
  • The proximity reveal only re-floods when you move to a new block, mine, or
    join; standing still and turning around costs nothing.

Similar projects

Plugin →