From ca636d20afd4355119b55389a65942b0d00ae3d2 Mon Sep 17 00:00:00 2001 From: stonar96 Date: Mon, 10 Apr 2023 03:25:44 +0200 Subject: [PATCH] Fix NPE when non-player entities create new nether portals (#1995) * Fix NPE when non-player entities create new nether portals * Fix flag checking for portal create event * Use failed load region set * Clean up --- .../listener/WorldGuardEntityListener.java | 55 ++++++++++++------- 1 file changed, 35 insertions(+), 20 deletions(-) diff --git a/worldguard-bukkit/src/main/java/com/sk89q/worldguard/bukkit/listener/WorldGuardEntityListener.java b/worldguard-bukkit/src/main/java/com/sk89q/worldguard/bukkit/listener/WorldGuardEntityListener.java index ea59fb5d..67e2c8b8 100644 --- a/worldguard-bukkit/src/main/java/com/sk89q/worldguard/bukkit/listener/WorldGuardEntityListener.java +++ b/worldguard-bukkit/src/main/java/com/sk89q/worldguard/bukkit/listener/WorldGuardEntityListener.java @@ -25,13 +25,17 @@ import com.sk89q.worldguard.LocalPlayer; import com.sk89q.worldguard.WorldGuard; import com.sk89q.worldguard.bukkit.BukkitWorldConfiguration; import com.sk89q.worldguard.bukkit.WorldGuardPlugin; +import com.sk89q.worldguard.bukkit.cause.Cause; import com.sk89q.worldguard.bukkit.util.Entities; +import com.sk89q.worldguard.bukkit.util.InteropUtils; import com.sk89q.worldguard.config.ConfigurationManager; import com.sk89q.worldguard.config.WorldConfiguration; import com.sk89q.worldguard.protection.ApplicableRegionSet; +import com.sk89q.worldguard.protection.FailedLoadRegionSet; import com.sk89q.worldguard.protection.association.RegionAssociable; import com.sk89q.worldguard.protection.flags.Flags; import com.sk89q.worldguard.protection.flags.StateFlag; +import com.sk89q.worldguard.protection.flags.StateFlag.State; import com.sk89q.worldguard.protection.managers.RegionManager; import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion; import com.sk89q.worldguard.protection.regions.RegionQuery; @@ -653,35 +657,46 @@ public class WorldGuardEntityListener extends AbstractListener { public void onCreatePortal(PortalCreateEvent event) { WorldConfiguration wcfg = getWorldConfig(event.getWorld()); - if (wcfg.regionNetherPortalProtection + if (wcfg.useRegions && wcfg.regionNetherPortalProtection && event.getReason() == PortalCreateEvent.CreateReason.NETHER_PAIR && !event.getBlocks().isEmpty()) { final com.sk89q.worldedit.world.World world = BukkitAdapter.adapt(event.getWorld()); - final RegionManager regionManager = WorldGuard.getInstance().getPlatform().getRegionContainer() - .get(world); - if (regionManager == null) return; - LocalPlayer associable = null; - if (event.getEntity() instanceof Player player) { - associable = getPlugin().wrapPlayer(player); - if (WorldGuard.getInstance().getPlatform().getSessionManager().hasBypass(associable, world)) { + final Cause cause = Cause.create(event.getEntity()); + LocalPlayer localPlayer = null; + if (cause.getRootCause() instanceof Player player) { + if (wcfg.fakePlayerBuildOverride && InteropUtils.isFakePlayer(player)) { + return; + } + localPlayer = getPlugin().wrapPlayer(player); + if (WorldGuard.getInstance().getPlatform().getSessionManager().hasBypass(localPlayer, world)) { return; } } - BlockVector3 min = null; - BlockVector3 max = null; - for (BlockState block : event.getBlocks()) { - BlockVector3 loc = BlockVector3.at(block.getX(), block.getY(), block.getZ()); - min = min == null ? loc : loc.getMinimum(min); - max = max == null ? loc : loc.getMaximum(max); + final RegionManager regionManager = WorldGuard.getInstance().getPlatform().getRegionContainer() + .get(world); + ApplicableRegionSet regions; + if (regionManager == null) { + regions = FailedLoadRegionSet.getInstance(); + } else { + BlockVector3 min = null; + BlockVector3 max = null; + for (BlockState block : event.getBlocks()) { + BlockVector3 loc = BlockVector3.at(block.getX(), block.getY(), block.getZ()); + min = min == null ? loc : loc.getMinimum(min); + max = max == null ? loc : loc.getMaximum(max); + } + ProtectedCuboidRegion target = new ProtectedCuboidRegion("__portal_check", true, min, max); + regions = regionManager.getApplicableRegions(target); } - ProtectedCuboidRegion target = new ProtectedCuboidRegion("__portal_check", true, min, max); - final ApplicableRegionSet regions = regionManager.getApplicableRegions(target); - if (!regions.testState(associable, Flags.BUILD, Flags.BLOCK_PLACE)) { - if (associable != null) { + final RegionAssociable associable = createRegionAssociable(cause); + final State buildState = StateFlag.denyToNone(regions.queryState(associable, Flags.BUILD)); + if (!StateFlag.test(buildState, regions.queryState(associable, Flags.BLOCK_BREAK)) + || !StateFlag.test(buildState, regions.queryState(associable, Flags.BLOCK_PLACE))) { + if (localPlayer != null && !cause.isIndirect()) { // NB there is no way to cancel the teleport without PTA (since PlayerPortal doesn't have block info) // removing PTA was a mistake - String message = regions.queryValue(associable, Flags.DENY_MESSAGE); - RegionProtectionListener.formatAndSendDenyMessage("create portals", associable, message); + String message = regions.queryValue(localPlayer, Flags.DENY_MESSAGE); + RegionProtectionListener.formatAndSendDenyMessage("create portals", localPlayer, message); } event.setCancelled(true); }