From 241dd39e72780df2a22674aa1d564dee4829642a Mon Sep 17 00:00:00 2001 From: Sven Date: Sun, 28 Sep 2025 19:42:06 +0200 Subject: [PATCH 1/5] Clean up empty entries for playersByHiddenBlock in removeAllPos --- .../trueog/antipierayog/BlockEntityHider.kt | 45 ++++++++++--------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/src/main/kotlin/net/trueog/antipierayog/BlockEntityHider.kt b/src/main/kotlin/net/trueog/antipierayog/BlockEntityHider.kt index 8a3645f..dd40aa7 100644 --- a/src/main/kotlin/net/trueog/antipierayog/BlockEntityHider.kt +++ b/src/main/kotlin/net/trueog/antipierayog/BlockEntityHider.kt @@ -395,46 +395,51 @@ class BlockEntityHider { fun Location.toBlockPosition() = BlockPosition(blockX, blockY, blockZ) } - val hiddenBlocksForPlayer: MutableMap> = ConcurrentHashMap() - val blockHiddenForPlayers: MutableMap> = ConcurrentHashMap() + val hiddenBlocksByPlayer: MutableMap> = ConcurrentHashMap() + val playersByHiddenBlock: MutableMap> = ConcurrentHashMap() /** * Outer map key: A hidden block * * Inner map key: A block that is preventing the hidden block to be seen */ - val blockBlockedByForPlayer: MutableMap>> = + val blockingBlockForPlayersByHiddenBlock: MutableMap>> = ConcurrentHashMap() fun addPos(uuid: UUID, pos: BlockPosition, blockingPositions: Set) { - hiddenBlocksForPlayer.computeIfAbsent(uuid) { ConcurrentHashMap.newKeySet() }.add(pos) - blockHiddenForPlayers.computeIfAbsent(pos) { ConcurrentHashMap.newKeySet() }.add(uuid) - val entry = blockBlockedByForPlayer.computeIfAbsent(pos) { ConcurrentHashMap() } + hiddenBlocksByPlayer.computeIfAbsent(uuid) { ConcurrentHashMap.newKeySet() }.add(pos) + playersByHiddenBlock.computeIfAbsent(pos) { ConcurrentHashMap.newKeySet() }.add(uuid) + val entry = blockingBlockForPlayersByHiddenBlock.computeIfAbsent(pos) { ConcurrentHashMap() } blockingPositions.forEach { entry.computeIfAbsent(it) { ConcurrentHashMap.newKeySet() }.add(uuid) } } fun removePos(uuid: UUID, pos: BlockPosition, skipBlockBlockedByForPlayer: Boolean = false) { - hiddenBlocksForPlayer[uuid]?.remove(pos) - blockHiddenForPlayers[pos]?.remove(uuid) + hiddenBlocksByPlayer[uuid]?.remove(pos) + playersByHiddenBlock[pos]?.remove(uuid) if (!skipBlockBlockedByForPlayer) { - blockBlockedByForPlayer[pos]?.entries?.removeAll { (_, uuids) -> + blockingBlockForPlayersByHiddenBlock[pos]?.entries?.removeAll { (_, uuids) -> uuids.remove(uuid) uuids.isEmpty() } } - if (hiddenBlocksForPlayer[uuid]?.isEmpty() == true) hiddenBlocksForPlayer.remove(uuid) - if (blockHiddenForPlayers[pos]?.isEmpty() == true) blockHiddenForPlayers.remove(pos) + if (hiddenBlocksByPlayer[uuid]?.isEmpty() == true) hiddenBlocksByPlayer.remove(uuid) + if (playersByHiddenBlock[pos]?.isEmpty() == true) playersByHiddenBlock.remove(pos) if (!skipBlockBlockedByForPlayer) { - if (blockBlockedByForPlayer[pos]?.isEmpty() == true) blockBlockedByForPlayer.remove(pos) + if (blockingBlockForPlayersByHiddenBlock[pos]?.isEmpty() == true) blockingBlockForPlayersByHiddenBlock.remove(pos) } } fun removeAllPos(uuid: UUID) { - val hiddenBlocks = hiddenBlocksForPlayer[uuid] ?: return - hiddenBlocks.forEach { blockHiddenForPlayers[it]?.remove(uuid) } - hiddenBlocksForPlayer.remove(uuid) - blockBlockedByForPlayer.entries.removeAll { + val hiddenBlocks = hiddenBlocksByPlayer[uuid] ?: return + hiddenBlocks.forEach { + playersByHiddenBlock.computeIfPresent(it) { _, uuids -> + uuids.remove(uuid) + if (uuids.isEmpty()) null else uuids + } + } + hiddenBlocksByPlayer.remove(uuid) + blockingBlockForPlayersByHiddenBlock.entries.removeAll { it.value.values.removeAll { uuids -> uuids.remove(uuid) uuids.isEmpty() @@ -447,14 +452,14 @@ class BlockEntityHider { val threshold = min(player.viewDistance, Bukkit.getViewDistance()) + 1 val chunkX = player.location.x.toInt() shr 4 val chunkZ = player.location.z.toInt() shr 4 - blockHiddenForPlayers + playersByHiddenBlock .filterKeys { abs(chunkX - (it.x shr 4)) > threshold || abs(chunkZ - (it.z shr 4)) > threshold } .forEach { (pos, uuids) -> uuids.forEach { uuid -> removePos(uuid, pos) } } } fun removeIfNeeded(pos: BlockPosition, world: World) { if (world.getBlockAt(pos.toLocation(world)).type !in AntiPieRay.hideMaterials) { - blockHiddenForPlayers + playersByHiddenBlock .filterKeys { pos == it } .values .forEach { uuids -> uuids.forEach { uuid -> removePos(uuid, pos) } } @@ -462,7 +467,7 @@ class BlockEntityHider { } fun updateBlockVisibility(player: Player) { - val blockList = hiddenBlocksForPlayer[player.uniqueId] ?: return + val blockList = hiddenBlocksByPlayer[player.uniqueId] ?: return blockList.forEach { val loc = it.toLocation(player.world) val blockingBlock = canSee(player.eyeLocation, loc) @@ -477,7 +482,7 @@ class BlockEntityHider { fun updateBlockVisibility(pos: BlockPosition, world: World) { removeIfNeeded(pos, world) - blockBlockedByForPlayer.entries.removeAll { (blockPos, entry) -> + blockingBlockForPlayersByHiddenBlock.entries.removeAll { (blockPos, entry) -> val blockLoc = blockPos.toLocation(world) val posEntry = entry[pos] posEntry?.removeAll { uuid -> -- 2.47.3 From 9ef083718bd06ebe6b725c88586a4e0a8ce51a9e Mon Sep 17 00:00:00 2001 From: Sven Date: Sun, 28 Sep 2025 19:46:05 +0200 Subject: [PATCH 2/5] Formatting --- src/main/kotlin/net/trueog/antipierayog/BlockEntityHider.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/net/trueog/antipierayog/BlockEntityHider.kt b/src/main/kotlin/net/trueog/antipierayog/BlockEntityHider.kt index dd40aa7..b6c2dcd 100644 --- a/src/main/kotlin/net/trueog/antipierayog/BlockEntityHider.kt +++ b/src/main/kotlin/net/trueog/antipierayog/BlockEntityHider.kt @@ -426,7 +426,8 @@ class BlockEntityHider { if (hiddenBlocksByPlayer[uuid]?.isEmpty() == true) hiddenBlocksByPlayer.remove(uuid) if (playersByHiddenBlock[pos]?.isEmpty() == true) playersByHiddenBlock.remove(pos) if (!skipBlockBlockedByForPlayer) { - if (blockingBlockForPlayersByHiddenBlock[pos]?.isEmpty() == true) blockingBlockForPlayersByHiddenBlock.remove(pos) + if (blockingBlockForPlayersByHiddenBlock[pos]?.isEmpty() == true) + blockingBlockForPlayersByHiddenBlock.remove(pos) } } -- 2.47.3 From f406d5385cb1094312ec848a98c60f282f676fa7 Mon Sep 17 00:00:00 2001 From: Sven Date: Sun, 28 Sep 2025 19:48:48 +0200 Subject: [PATCH 3/5] Cancel tasks on disable --- src/main/kotlin/net/trueog/antipierayog/AntiPieRay.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/kotlin/net/trueog/antipierayog/AntiPieRay.kt b/src/main/kotlin/net/trueog/antipierayog/AntiPieRay.kt index 9fe4ab8..129a432 100644 --- a/src/main/kotlin/net/trueog/antipierayog/AntiPieRay.kt +++ b/src/main/kotlin/net/trueog/antipierayog/AntiPieRay.kt @@ -5,6 +5,7 @@ import com.github.retrooper.packetevents.event.PacketListenerPriority import com.github.retrooper.packetevents.protocol.world.states.type.StateType import com.github.retrooper.packetevents.protocol.world.states.type.StateTypes import io.github.retrooper.packetevents.factory.spigot.SpigotPacketEventsBuilder +import org.bukkit.Bukkit import java.util.Collections import java.util.IdentityHashMap import org.bukkit.Material @@ -108,6 +109,7 @@ class AntiPieRay : JavaPlugin() { } override fun onDisable() { + Bukkit.getScheduler().cancelTasks(this) PacketEvents.getAPI().terminate() } } -- 2.47.3 From 067e6cb1d324e5f625f7012517d96545121c5873 Mon Sep 17 00:00:00 2001 From: Sven Date: Sun, 28 Sep 2025 20:39:27 +0200 Subject: [PATCH 4/5] Just make it not lag bro --- .../net/trueog/antipierayog/AntiPieRay.kt | 6 +++-- .../kotlin/net/trueog/antipierayog/Events.kt | 20 +++----------- .../PlayerPositionRotationPacketListener.kt | 27 +++++++++++++++++++ 3 files changed, 35 insertions(+), 18 deletions(-) create mode 100644 src/main/kotlin/net/trueog/antipierayog/PlayerPositionRotationPacketListener.kt diff --git a/src/main/kotlin/net/trueog/antipierayog/AntiPieRay.kt b/src/main/kotlin/net/trueog/antipierayog/AntiPieRay.kt index 129a432..aaf84f0 100644 --- a/src/main/kotlin/net/trueog/antipierayog/AntiPieRay.kt +++ b/src/main/kotlin/net/trueog/antipierayog/AntiPieRay.kt @@ -5,9 +5,8 @@ import com.github.retrooper.packetevents.event.PacketListenerPriority import com.github.retrooper.packetevents.protocol.world.states.type.StateType import com.github.retrooper.packetevents.protocol.world.states.type.StateTypes import io.github.retrooper.packetevents.factory.spigot.SpigotPacketEventsBuilder +import java.util.* import org.bukkit.Bukkit -import java.util.Collections -import java.util.IdentityHashMap import org.bukkit.Material import org.bukkit.plugin.java.JavaPlugin @@ -97,6 +96,9 @@ class AntiPieRay : JavaPlugin() { ) PacketEvents.getAPI().eventManager.registerListener(ChunkDataPacketListener(), PacketListenerPriority.NORMAL) PacketEvents.getAPI().eventManager.registerListener(BlockChangePacketListener(), PacketListenerPriority.NORMAL) + PacketEvents.getAPI() + .eventManager + .registerListener(PlayerPositionRotationPacketListener(), PacketListenerPriority.NORMAL) } override fun onEnable() { diff --git a/src/main/kotlin/net/trueog/antipierayog/Events.kt b/src/main/kotlin/net/trueog/antipierayog/Events.kt index f7bbfc9..9af3f16 100644 --- a/src/main/kotlin/net/trueog/antipierayog/Events.kt +++ b/src/main/kotlin/net/trueog/antipierayog/Events.kt @@ -11,23 +11,9 @@ import org.bukkit.event.block.BlockBurnEvent import org.bukkit.event.block.BlockExplodeEvent import org.bukkit.event.entity.EntityExplodeEvent import org.bukkit.event.player.PlayerChangedWorldEvent -import org.bukkit.event.player.PlayerMoveEvent import org.bukkit.event.player.PlayerQuitEvent class Events : Listener { - @EventHandler(priority = EventPriority.MONITOR) - fun onPlayerMove(event: PlayerMoveEvent) { - val worldName = event.player.world.name - if (worldName != "world" && worldName != "world_nether" && worldName != "world_the_end") return - - Bukkit.getScheduler() - .runTaskLaterAsynchronously( - AntiPieRay.plugin, - Runnable { AntiPieRay.blockEntityHider.updateBlockVisibility(event.player) }, - 1L, - ) - } - fun genericBlockBreakHandler(block: Block) { Bukkit.getScheduler() .runTaskLaterAsynchronously( @@ -76,11 +62,13 @@ class Events : Listener { val worldName = event.player.world.name if (worldName != "world" && worldName != "world_nether" && worldName != "world_the_end") return - AntiPieRay.blockEntityHider.removeAllPos(event.player.uniqueId) + Bukkit.getScheduler() + .runTask(AntiPieRay.plugin, Runnable { AntiPieRay.blockEntityHider.removeAllPos(event.player.uniqueId) }) } @EventHandler(priority = EventPriority.MONITOR) fun onPlayerQuit(event: PlayerQuitEvent) { - AntiPieRay.blockEntityHider.removeAllPos(event.player.uniqueId) + Bukkit.getScheduler() + .runTask(AntiPieRay.plugin, Runnable { AntiPieRay.blockEntityHider.removeAllPos(event.player.uniqueId) }) } } diff --git a/src/main/kotlin/net/trueog/antipierayog/PlayerPositionRotationPacketListener.kt b/src/main/kotlin/net/trueog/antipierayog/PlayerPositionRotationPacketListener.kt new file mode 100644 index 0000000..e9e36bf --- /dev/null +++ b/src/main/kotlin/net/trueog/antipierayog/PlayerPositionRotationPacketListener.kt @@ -0,0 +1,27 @@ +package net.trueog.antipierayog + +import com.github.retrooper.packetevents.event.PacketListener +import com.github.retrooper.packetevents.event.PacketReceiveEvent +import com.github.retrooper.packetevents.protocol.packettype.PacketType +import org.bukkit.Bukkit +import org.bukkit.entity.Player + +class PlayerPositionRotationPacketListener : PacketListener { + override fun onPacketReceive(event: PacketReceiveEvent) { + if (event.packetType != PacketType.Play.Client.PLAYER_POSITION_AND_ROTATION) { + return + } + + val player = event.getPlayer() + + val worldName = player.world.name + if (worldName != "world" && worldName != "world_nether" && worldName != "world_the_end") return + + Bukkit.getScheduler() + .runTaskLaterAsynchronously( + AntiPieRay.plugin, + Runnable { AntiPieRay.blockEntityHider.updateBlockVisibility(player) }, + 1, + ) + } +} -- 2.47.3 From 34843bc01391073596e68768e649034cfafb3641 Mon Sep 17 00:00:00 2001 From: Sven Date: Sun, 28 Sep 2025 20:40:47 +0200 Subject: [PATCH 5/5] removeAllPos can run asynchronously --- src/main/kotlin/net/trueog/antipierayog/Events.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/net/trueog/antipierayog/Events.kt b/src/main/kotlin/net/trueog/antipierayog/Events.kt index 9af3f16..8385eb3 100644 --- a/src/main/kotlin/net/trueog/antipierayog/Events.kt +++ b/src/main/kotlin/net/trueog/antipierayog/Events.kt @@ -63,12 +63,12 @@ class Events : Listener { if (worldName != "world" && worldName != "world_nether" && worldName != "world_the_end") return Bukkit.getScheduler() - .runTask(AntiPieRay.plugin, Runnable { AntiPieRay.blockEntityHider.removeAllPos(event.player.uniqueId) }) + .runTaskAsynchronously(AntiPieRay.plugin, Runnable { AntiPieRay.blockEntityHider.removeAllPos(event.player.uniqueId) }) } @EventHandler(priority = EventPriority.MONITOR) fun onPlayerQuit(event: PlayerQuitEvent) { Bukkit.getScheduler() - .runTask(AntiPieRay.plugin, Runnable { AntiPieRay.blockEntityHider.removeAllPos(event.player.uniqueId) }) + .runTaskAsynchronously(AntiPieRay.plugin, Runnable { AntiPieRay.blockEntityHider.removeAllPos(event.player.uniqueId) }) } } -- 2.47.3