Clean up empty entries for playersByHiddenBlock in removeAllPos #3

Merged
SKBotNL merged 6 commits from main into main 2025-09-28 14:41:38 -04:00
4 changed files with 63 additions and 38 deletions

No files matched your search

@@ -5,8 +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.Collections
import java.util.IdentityHashMap
import java.util.*
import org.bukkit.Bukkit
import org.bukkit.Material
import org.bukkit.plugin.java.JavaPlugin
@@ -96,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() {
@@ -108,6 +111,7 @@ class AntiPieRay : JavaPlugin() {
}
override fun onDisable() {
Bukkit.getScheduler().cancelTasks(this)
PacketEvents.getAPI().terminate()
}
}
@@ -395,46 +395,52 @@ class BlockEntityHider {
fun Location.toBlockPosition() = BlockPosition(blockX, blockY, blockZ)
}
val hiddenBlocksForPlayer: MutableMap<UUID, MutableSet<BlockPosition>> = ConcurrentHashMap()
val blockHiddenForPlayers: MutableMap<BlockPosition, MutableSet<UUID>> = ConcurrentHashMap()
val hiddenBlocksByPlayer: MutableMap<UUID, MutableSet<BlockPosition>> = ConcurrentHashMap()
val playersByHiddenBlock: MutableMap<BlockPosition, MutableSet<UUID>> = ConcurrentHashMap()
/**
* Outer map key: A hidden block
*
* Inner map key: A block that is preventing the hidden block to be seen
*/
val blockBlockedByForPlayer: MutableMap<BlockPosition, MutableMap<BlockPosition, MutableSet<UUID>>> =
val blockingBlockForPlayersByHiddenBlock: MutableMap<BlockPosition, MutableMap<BlockPosition, MutableSet<UUID>>> =
ConcurrentHashMap()
fun addPos(uuid: UUID, pos: BlockPosition, blockingPositions: Set<BlockPosition>) {
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 +453,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 +468,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 +483,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 ->
@@ -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()
.runTaskAsynchronously(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()
.runTaskAsynchronously(AntiPieRay.plugin, Runnable { AntiPieRay.blockEntityHider.removeAllPos(event.player.uniqueId) })
}
}
@@ -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<Player>()
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,
)
}
}