From ee5918b825bdebab32184df2f04e02ae067f1422 Mon Sep 17 00:00:00 2001 From: Sekwah Date: Sun, 24 Dec 2023 05:09:04 +0000 Subject: [PATCH] feat: add portal protections --- .../advancedportals/core/CoreListeners.java | 65 +++++---- .../portal/ShowPortalSubCommand.java | 1 - .../connector/containers/EntityContainer.java | 18 +++ .../connector/containers/PlayerContainer.java | 14 +- .../core/portal/AdvancedPortal.java | 22 ++- .../core/repository/ConfigRepository.java | 8 ++ .../repository/impl/ConfigRepositoryImpl.java | 25 ++++ .../core/serializeddata/BlockLocation.java | 20 +++ .../core/serializeddata/PlayerTempData.java | 4 +- .../core/services/PortalServices.java | 55 +++++++- .../core/services/PortalTempDataServices.java | 7 + lang/src/main/resources/lang/en_GB.lang | 4 + .../spigot/AdvancedPortalsPlugin.java | 2 + .../advancedportals/spigot/Listeners.java | 133 +++++++++++++++++- .../container/SpigotEntityContainer.java | 61 ++++++++ .../container/SpigotPlayerContainer.java | 28 ++-- .../spigot/utils/ContainerHelpers.java | 18 +++ 17 files changed, 407 insertions(+), 78 deletions(-) create mode 100644 core/src/main/java/com/sekwah/advancedportals/core/connector/containers/EntityContainer.java create mode 100644 spigot/src/main/java/com/sekwah/advancedportals/spigot/connector/container/SpigotEntityContainer.java create mode 100644 spigot/src/main/java/com/sekwah/advancedportals/spigot/utils/ContainerHelpers.java diff --git a/core/src/main/java/com/sekwah/advancedportals/core/CoreListeners.java b/core/src/main/java/com/sekwah/advancedportals/core/CoreListeners.java index 114ece9..a45fbb7 100644 --- a/core/src/main/java/com/sekwah/advancedportals/core/CoreListeners.java +++ b/core/src/main/java/com/sekwah/advancedportals/core/CoreListeners.java @@ -1,6 +1,7 @@ package com.sekwah.advancedportals.core; import com.google.inject.Inject; +import com.sekwah.advancedportals.core.connector.containers.EntityContainer; import com.sekwah.advancedportals.core.connector.containers.PlayerContainer; import com.sekwah.advancedportals.core.connector.containers.WorldContainer; import com.sekwah.advancedportals.core.data.BlockAxis; @@ -12,6 +13,7 @@ import com.sekwah.advancedportals.core.repository.ConfigRepository; import com.sekwah.advancedportals.core.services.PortalServices; import com.sekwah.advancedportals.core.services.PortalTempDataServices; import com.sekwah.advancedportals.core.util.GameScheduler; +import com.sekwah.advancedportals.core.util.Lang; import java.util.Objects; @@ -45,41 +47,30 @@ public class CoreListeners { this.gameScheduler.tick(); } - /** - * @param loc where the entity spawns - * @return if the entity is allowed to spawn - */ - public boolean mobSpawn(PlayerLocation loc) { - return !this.portalServices.inPortalRegion(loc); - } - /** * @param player - * @param fromLoc * @param toLoc - * @return if the player is allowed to move */ - public boolean playerMove(PlayerContainer player, PlayerLocation fromLoc, PlayerLocation toLoc) { - return this.portalServices.playerMove(player, fromLoc, toLoc); + public void playerMove(PlayerContainer player, PlayerLocation toLoc) { + this.portalServices.playerMove(player, toLoc); } /** + * If the block is indirectly broken it will also take null for the player e.g. with tnt * - * @param fromPos - * @param toPos - * @return if movement is allowed - */ - public boolean liquidFlow(BlockLocation fromPos, BlockLocation toPos) { - return true; - } - - /** * @player player causing the event (or null if not a player) * @param blockPos * @param blockMaterial * @return if the block is allowed to break */ public boolean blockBreak(PlayerContainer player, BlockLocation blockPos, String blockMaterial, String itemInHandMaterial, String itemInHandName) { + if(player == null) { + return !portalServices.inPortalRegionProtected(blockPos); + } + if(!(PortalPermissions.BUILD.hasPermission(player) || !portalServices.inPortalRegionProtected(blockPos))) { + player.sendMessage(Lang.translate("messageprefix.negative") + Lang.translate("portal.nobuild")); + return false; + } return true; } @@ -90,7 +81,7 @@ public class CoreListeners { * @return if the block is allowed to be placed */ public boolean blockPlace(PlayerContainer player, BlockLocation blockPos, String blockMaterial, String itemInHandMaterial, String itemInHandName) { - if(itemInHandName != null && player != null && PortalPermissions.BUILD.hasPermission(player)) { + if(player != null && PortalPermissions.BUILD.hasPermission(player)) { WorldContainer world = player.getWorld(); if(itemInHandName.equals("\u00A75Portal Block Placer")) { world.setBlock(blockPos, "NETHER_PORTAL"); @@ -101,16 +92,23 @@ public class CoreListeners { break; } } - return false; + return true; } else if(itemInHandName.equals("\u00A78End Portal Block Placer")) { world.setBlock(blockPos, "END_PORTAL"); - return false; + return true; } else if(itemInHandName.equals("\u00A78Gateway Block Placer")) { world.setBlock(blockPos, "END_GATEWAY"); - return false; + return true; } + return true; + } + if(portalServices.inPortalRegionProtected(blockPos)) { + if(player != null) { + player.sendMessage(Lang.translate("messageprefix.negative") + Lang.translate("portal.nobuild")); + } + return false; } return true; } @@ -158,4 +156,21 @@ public class CoreListeners { return true; } + public void worldChange(PlayerContainer player) { + this.portalTempDataServices.activateCooldown(player); + } + + public boolean preventEntityCombust(EntityContainer entity) { + return portalServices.inPortalRegion(entity.getBlockLoc(), 2); + } + + public boolean portalEvent(PlayerContainer player) { + return !portalServices.inPortalRegion(player.getBlockLoc(), 1) + && (!(player.getHeight() > 1) || !portalServices.inPortalRegion(player.getBlockLoc().addY((int) player.getHeight()), 1)); + } + + public boolean entityPortalEvent(EntityContainer entity) { + return !portalServices.inPortalRegion(entity.getBlockLoc(), 1) + && (!(entity.getHeight() > 1) || !portalServices.inPortalRegion(entity.getBlockLoc().addY((int) entity.getHeight()), 1)); + } } diff --git a/core/src/main/java/com/sekwah/advancedportals/core/commands/subcommands/portal/ShowPortalSubCommand.java b/core/src/main/java/com/sekwah/advancedportals/core/commands/subcommands/portal/ShowPortalSubCommand.java index 4f2a27e..4038d0e 100644 --- a/core/src/main/java/com/sekwah/advancedportals/core/commands/subcommands/portal/ShowPortalSubCommand.java +++ b/core/src/main/java/com/sekwah/advancedportals/core/commands/subcommands/portal/ShowPortalSubCommand.java @@ -174,7 +174,6 @@ public class ShowPortalSubCommand implements SubCommand, SubCommand.SubCommandOn for (int z = minZ; z <= maxZ; z++) { var pos = new BlockLocation(pos1.worldName, x, y, z); boolean isTrigger = portal != null && portal.isTriggerBlock(world.getBlock(pos)); - System.out.println(world.getBlock(pos)); boolean isOutline = (y == minY || y == maxY) && (x == minX || x == maxX || z == minZ || z == maxZ) || (z == minZ || z == maxZ) && (x == minX || x == maxX); if (isTrigger && isOutline && alternate_show_trigger) { Debug.addMarker(player, pos, "", TRIGGER_OUTLINE_COLOR, time); diff --git a/core/src/main/java/com/sekwah/advancedportals/core/connector/containers/EntityContainer.java b/core/src/main/java/com/sekwah/advancedportals/core/connector/containers/EntityContainer.java new file mode 100644 index 0000000..ddc106a --- /dev/null +++ b/core/src/main/java/com/sekwah/advancedportals/core/connector/containers/EntityContainer.java @@ -0,0 +1,18 @@ +package com.sekwah.advancedportals.core.connector.containers; + +import com.sekwah.advancedportals.core.serializeddata.BlockLocation; +import com.sekwah.advancedportals.core.serializeddata.PlayerLocation; + +public interface EntityContainer { + + PlayerLocation getLoc(); + + double getHeight(); + + BlockLocation getBlockLoc(); + + void teleport(PlayerLocation location); + + WorldContainer getWorld(); + +} diff --git a/core/src/main/java/com/sekwah/advancedportals/core/connector/containers/PlayerContainer.java b/core/src/main/java/com/sekwah/advancedportals/core/connector/containers/PlayerContainer.java index 27bff69..eb2b045 100644 --- a/core/src/main/java/com/sekwah/advancedportals/core/connector/containers/PlayerContainer.java +++ b/core/src/main/java/com/sekwah/advancedportals/core/connector/containers/PlayerContainer.java @@ -8,26 +8,16 @@ import java.util.UUID; /** * Just a temporary container for whenever advanced portals needs to get data from a player */ -public interface PlayerContainer { +public interface PlayerContainer extends EntityContainer { UUID getUUID(); - public void sendMessage(String message); + void sendMessage(String message); boolean isOp(); - PlayerLocation getLoc(); - - BlockLocation getBlockLoc(); - - double getEyeHeight(); - - void teleport(PlayerLocation location); - boolean hasPermission(String permission); - WorldContainer getWorld(); - /** * @param blockPos * @param material diff --git a/core/src/main/java/com/sekwah/advancedportals/core/portal/AdvancedPortal.java b/core/src/main/java/com/sekwah/advancedportals/core/portal/AdvancedPortal.java index de78a67..db6c56e 100644 --- a/core/src/main/java/com/sekwah/advancedportals/core/portal/AdvancedPortal.java +++ b/core/src/main/java/com/sekwah/advancedportals/core/portal/AdvancedPortal.java @@ -122,14 +122,24 @@ public class AdvancedPortal implements TagTarget { return true; } - public boolean isLocationInPortal(PlayerLocation playerLocation) { - return this.isLocationInPortal(playerLocation, 0); + + public boolean isLocationInPortal(BlockLocation loc) { + return this.isLocationInPortal(loc, 0); } - public boolean isLocationInPortal(PlayerLocation playerLocation, int additionalArea) { - double playerX = playerLocation.getPosX(); - double playerY = playerLocation.getPosY(); - double playerZ = playerLocation.getPosZ(); + public boolean isLocationInPortal(PlayerLocation loc) { + return this.isLocationInPortal(loc.toBlockPos(), 0); + } + + + public boolean isLocationInPortal(PlayerLocation loc, int additionalArea) { + return this.isLocationInPortal(loc.toBlockPos(), additionalArea); + } + + public boolean isLocationInPortal(BlockLocation loc, int additionalArea) { + double playerX = loc.posX; + double playerY = loc.posY; + double playerZ = loc.posZ; return playerX >= this.minLoc.posX - additionalArea && playerX < this.maxLoc.posX + 1 + additionalArea && diff --git a/core/src/main/java/com/sekwah/advancedportals/core/repository/ConfigRepository.java b/core/src/main/java/com/sekwah/advancedportals/core/repository/ConfigRepository.java index ad9a7f1..5e5b7c7 100644 --- a/core/src/main/java/com/sekwah/advancedportals/core/repository/ConfigRepository.java +++ b/core/src/main/java/com/sekwah/advancedportals/core/repository/ConfigRepository.java @@ -18,5 +18,13 @@ public interface ConfigRepository { String getDefaultTriggerBlock(); + boolean isProtectionActive(); + int getProtectionRadius(); + + boolean getStopWaterFlow(); + + boolean getPortalProtection(); + + long getPortalCooldown(); } diff --git a/core/src/main/java/com/sekwah/advancedportals/core/repository/impl/ConfigRepositoryImpl.java b/core/src/main/java/com/sekwah/advancedportals/core/repository/impl/ConfigRepositoryImpl.java index ed5dcf8..a850e71 100644 --- a/core/src/main/java/com/sekwah/advancedportals/core/repository/impl/ConfigRepositoryImpl.java +++ b/core/src/main/java/com/sekwah/advancedportals/core/repository/impl/ConfigRepositoryImpl.java @@ -57,6 +57,31 @@ public class ConfigRepositoryImpl implements ConfigRepository { return this.config.defaultTriggerBlock; } + @Override + public boolean isProtectionActive() { + return this.config.portalProtection; + } + + @Override + public int getProtectionRadius() { + return this.config.portalProtectionRaduis; + } + + @Override + public boolean getStopWaterFlow() { + return this.config.stopWaterFlow; + } + + @Override + public boolean getPortalProtection() { + return this.config.portalProtection; + } + + @Override + public long getPortalCooldown() { + return this.config.portalCooldown; + } + @Override public void loadConfig(DataStorage dataStorage) { this.config = dataStorage.loadJson(Config.class, "config.json"); diff --git a/core/src/main/java/com/sekwah/advancedportals/core/serializeddata/BlockLocation.java b/core/src/main/java/com/sekwah/advancedportals/core/serializeddata/BlockLocation.java index e40ff35..1424eb1 100644 --- a/core/src/main/java/com/sekwah/advancedportals/core/serializeddata/BlockLocation.java +++ b/core/src/main/java/com/sekwah/advancedportals/core/serializeddata/BlockLocation.java @@ -32,6 +32,18 @@ public class BlockLocation { } + public int getPosX() { + return posX; + } + + public int getPosY() { + return posY; + } + + public int getPosZ() { + return posZ; + } + public boolean equals(BlockLocation location) { return location.posX == this.posX && location.posY == this.posY && location.posZ == this.posZ && location.worldName.equals(this.worldName); } @@ -46,4 +58,12 @@ public class BlockLocation { double dz = this.posZ - pos.posZ; return dx * dx + dy * dy + dz * dz; } + + public BlockLocation addY(double offsetY) { + return this.addY((int) Math.floor(offsetY)); + } + + public BlockLocation addY(int offsetY) { + return new BlockLocation(this.worldName, this.posX, (this.posY + offsetY), this.posZ); + } } diff --git a/core/src/main/java/com/sekwah/advancedportals/core/serializeddata/PlayerTempData.java b/core/src/main/java/com/sekwah/advancedportals/core/serializeddata/PlayerTempData.java index c96efbf..02cea8f 100644 --- a/core/src/main/java/com/sekwah/advancedportals/core/serializeddata/PlayerTempData.java +++ b/core/src/main/java/com/sekwah/advancedportals/core/serializeddata/PlayerTempData.java @@ -30,9 +30,7 @@ public class PlayerTempData { private boolean destiVisible; /** - * Used for things like join cooldowns - * TODO either store a hashmap of cool-downs on a portal, or a hashmap of cool-downs for portals on a player - * Can be switched at a later date + * The next time System.currentTimeMillis() a player can use a portal. */ private long globalCooldown; diff --git a/core/src/main/java/com/sekwah/advancedportals/core/services/PortalServices.java b/core/src/main/java/com/sekwah/advancedportals/core/services/PortalServices.java index c82dd9f..1678814 100644 --- a/core/src/main/java/com/sekwah/advancedportals/core/services/PortalServices.java +++ b/core/src/main/java/com/sekwah/advancedportals/core/services/PortalServices.java @@ -1,10 +1,11 @@ package com.sekwah.advancedportals.core.services; -import com.google.common.collect.ImmutableList; import com.google.inject.Inject; import com.sekwah.advancedportals.core.connector.containers.PlayerContainer; import com.sekwah.advancedportals.core.registry.TagRegistry; +import com.sekwah.advancedportals.core.repository.ConfigRepository; import com.sekwah.advancedportals.core.repository.IPortalRepository; +import com.sekwah.advancedportals.core.serializeddata.BlockLocation; import com.sekwah.advancedportals.core.serializeddata.DataTag; import com.sekwah.advancedportals.core.serializeddata.PlayerLocation; import com.sekwah.advancedportals.core.portal.AdvancedPortal; @@ -20,15 +21,15 @@ import java.util.*; @Singleton public class PortalServices { - @Inject - InfoLogger infoLogger; - @Inject private IPortalRepository portalRepository; @Inject private PortalTempDataServices portalTempDataServices; + @Inject + private ConfigRepository configRepository; + private final Map portalCache = new HashMap<>(); @Inject @@ -45,14 +46,56 @@ public class PortalServices { } - public boolean inPortalRegion(PlayerLocation loc) { + public boolean inPortalRegionProtected(BlockLocation loc) { + for (AdvancedPortal portal : portalCache.values()) { + if(portal.isLocationInPortal(loc, configRepository.getProtectionRadius())) { + return true; + } + } return false; } - public boolean playerMove(PlayerContainer player, PlayerLocation fromLoc, PlayerLocation toLoc) { + public boolean inPortalRegionProtected(PlayerLocation loc) { + for (AdvancedPortal portal : portalCache.values()) { + if(portal.isLocationInPortal(loc, configRepository.getProtectionRadius())) { + return true; + } + } return false; } + public boolean inPortalRegion(BlockLocation loc, int extraBlocks) { + for (AdvancedPortal portal : portalCache.values()) { + if(portal.isLocationInPortal(loc, extraBlocks)) { + return true; + } + } + return false; + } + + public void playerMove(PlayerContainer player, PlayerLocation toLoc) { + PlayerTempData tempData = portalTempDataServices.getPlayerTempData(player); + + if(tempData.getGlobalCooldown() > System.currentTimeMillis()) { + return; + } + + var blockLoc = toLoc.toBlockPos(); + var blockEntityTopLoc = blockLoc.addY(player.getHeight()); + var world = player.getWorld(); + var blockMaterial = world.getBlock(blockLoc); + var blockEntityTopMaterial = world.getBlock(blockEntityTopLoc); + + for (AdvancedPortal portal : portalCache.values()) { + if (portal.isLocationInPortal(toLoc) + || portal.isLocationInPortal(blockEntityTopLoc) + || portal.isTriggerBlock(blockMaterial) + || portal.isTriggerBlock(blockEntityTopMaterial)) { + portal.activate(player); + } + } + } + public List getPortalNames() { return portalRepository.getAllNames(); } diff --git a/core/src/main/java/com/sekwah/advancedportals/core/services/PortalTempDataServices.java b/core/src/main/java/com/sekwah/advancedportals/core/services/PortalTempDataServices.java index b2e99d3..713ec07 100644 --- a/core/src/main/java/com/sekwah/advancedportals/core/services/PortalTempDataServices.java +++ b/core/src/main/java/com/sekwah/advancedportals/core/services/PortalTempDataServices.java @@ -1,6 +1,8 @@ package com.sekwah.advancedportals.core.services; +import com.google.inject.Inject; import com.sekwah.advancedportals.core.connector.containers.PlayerContainer; +import com.sekwah.advancedportals.core.repository.ConfigRepository; import com.sekwah.advancedportals.core.serializeddata.BlockLocation; import com.sekwah.advancedportals.core.serializeddata.PlayerTempData; import com.sekwah.advancedportals.core.util.Lang; @@ -18,11 +20,16 @@ public final class PortalTempDataServices { */ private Map tempDataMap = new HashMap<>(); + @Inject + private ConfigRepository configRepository; + public PlayerTempData getPlayerTempData(PlayerContainer player) { return tempDataMap.computeIfAbsent(player.getUUID(), uuid -> new PlayerTempData()); } public void activateCooldown(PlayerContainer player) { + var tempData = getPlayerTempData(player); + tempData.setGlobalCooldown(System.currentTimeMillis() + configRepository.getPortalCooldown()); } public void playerLeave(PlayerContainer player) { diff --git a/lang/src/main/resources/lang/en_GB.lang b/lang/src/main/resources/lang/en_GB.lang index 8f666f9..82421cc 100644 --- a/lang/src/main/resources/lang/en_GB.lang +++ b/lang/src/main/resources/lang/en_GB.lang @@ -120,6 +120,8 @@ portal.error.selection.differentworlds= Both the selected points need to be in t portal.error.selection.missing= You need to select both points for the portal. portal.error.save= There was a problem saving the portal. +portal.nobuild= You don't have permission to build here! + desti.info.noargs=&cNo tags were given command.error.noname= You must specify a name &ename:someNameHere @@ -147,3 +149,5 @@ items.interact.right=Right Click tag.desti.description=Sets the destination of the portal tag.name.error.nospaces= The name cannot contain spaces. tag.triggerblock.description=Sets the trigger block/s of the portal. Comma seperated or multi tag. + + diff --git a/spigot/src/main/java/com/sekwah/advancedportals/spigot/AdvancedPortalsPlugin.java b/spigot/src/main/java/com/sekwah/advancedportals/spigot/AdvancedPortalsPlugin.java index 93064c8..a70187d 100644 --- a/spigot/src/main/java/com/sekwah/advancedportals/spigot/AdvancedPortalsPlugin.java +++ b/spigot/src/main/java/com/sekwah/advancedportals/spigot/AdvancedPortalsPlugin.java @@ -32,6 +32,8 @@ public class AdvancedPortalsPlugin extends JavaPlugin { @Override public void onEnable() { + new Metrics(this); + String mcVersion = this.getServer().getVersion(); Pattern pattern = Pattern.compile("\\(MC: ([\\d.]+)\\)"); Matcher matcher = pattern.matcher(mcVersion); diff --git a/spigot/src/main/java/com/sekwah/advancedportals/spigot/Listeners.java b/spigot/src/main/java/com/sekwah/advancedportals/spigot/Listeners.java index 5f9ec99..b380eeb 100644 --- a/spigot/src/main/java/com/sekwah/advancedportals/spigot/Listeners.java +++ b/spigot/src/main/java/com/sekwah/advancedportals/spigot/Listeners.java @@ -2,23 +2,42 @@ package com.sekwah.advancedportals.spigot; import com.google.inject.Inject; import com.sekwah.advancedportals.core.CoreListeners; +import com.sekwah.advancedportals.core.repository.ConfigRepository; import com.sekwah.advancedportals.core.serializeddata.BlockLocation; +import com.sekwah.advancedportals.core.services.PortalServices; +import com.sekwah.advancedportals.spigot.connector.container.SpigotEntityContainer; import com.sekwah.advancedportals.spigot.connector.container.SpigotPlayerContainer; +import com.sekwah.advancedportals.spigot.utils.ContainerHelpers; import org.bukkit.Location; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.block.Action; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockFromToEvent; import org.bukkit.event.block.BlockPlaceEvent; -import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.event.player.PlayerJoinEvent; -import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.entity.*; +import org.bukkit.event.player.*; +import java.util.List; + +/** + * Some of these will be passed to the core listener to handle the events, others it's easier to just check directly. + */ public class Listeners implements Listener { @Inject private CoreListeners coreListeners; + @Inject + private PortalServices portalServices; + + @Inject + private ConfigRepository configRepository; + + // Entity and portal events @EventHandler public void onJoinEvent(PlayerJoinEvent event) { coreListeners.playerJoin(new SpigotPlayerContainer(event.getPlayer())); @@ -26,19 +45,68 @@ public class Listeners implements Listener { @EventHandler public void onPlayerQuitEvent(PlayerQuitEvent event) { - // coreListeners.playerLeave(new SpigotPlayerContainer(event.getPlayer())); + coreListeners.playerLeave(new SpigotPlayerContainer(event.getPlayer())); + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onMoveEvent(PlayerMoveEvent event) { + var to = event.getTo(); + coreListeners.playerMove(new SpigotPlayerContainer(event.getPlayer()), ContainerHelpers.toPlayerLocation(to)); + } + + + @EventHandler(ignoreCancelled = true) + public void onEntityPortalEvent(EntityPortalEvent event) { + if(!this.coreListeners.entityPortalEvent(new SpigotEntityContainer(event.getEntity()))) { + event.setCancelled(true); + } + } + + + @EventHandler(ignoreCancelled = true) + public void onPortalEvent(PlayerPortalEvent event) { + if(!this.coreListeners.portalEvent(new SpigotPlayerContainer(event.getPlayer()))) { + event.setCancelled(true); + } + } + + + @EventHandler(ignoreCancelled = true) + public void onDamEvent(EntityDamageEvent event) { + if (event.getEntity() instanceof Player && (event.getCause() == EntityDamageEvent.DamageCause.LAVA + || event.getCause() == EntityDamageEvent.DamageCause.FIRE + || event.getCause() == EntityDamageEvent.DamageCause.FIRE_TICK)) { + if(this.coreListeners.preventEntityCombust(new SpigotEntityContainer(event.getEntity()))) { + event.setCancelled(true); + } + } + } + + + @EventHandler(ignoreCancelled = true) + public void onCombustEntityEvent(EntityCombustEvent event) { + if(this.coreListeners.preventEntityCombust(new SpigotEntityContainer(event.getEntity()))) { + event.setCancelled(true); + } } @EventHandler(priority = EventPriority.HIGH) public void onBlockPlace(BlockPlaceEvent event) { if (!event.isCancelled()) { Location blockloc = event.getBlock().getLocation(); - this.coreListeners.blockPlace(new SpigotPlayerContainer(event.getPlayer()), + if(!this.coreListeners.blockPlace(new SpigotPlayerContainer(event.getPlayer()), new BlockLocation(blockloc.getWorld().getName(), blockloc.getBlockX(), blockloc.getBlockY(), blockloc.getBlockZ()), event.getBlockPlaced().getType().toString(), - event.getItemInHand().getType().toString(), event.getItemInHand().getItemMeta().getDisplayName()); + event.getItemInHand().getType().toString(), event.getItemInHand().getItemMeta().getDisplayName())) { + event.setCancelled(true); + } } } + @EventHandler + public void onWorldChangeEvent(PlayerChangedWorldEvent event) { + coreListeners.worldChange(new SpigotPlayerContainer(event.getPlayer())); + } + @EventHandler public void onItemInteract(PlayerInteractEvent event) { if (!event.isCancelled() && (event.getAction() == Action.LEFT_CLICK_BLOCK || event.getAction() == Action.RIGHT_CLICK_BLOCK) && event.getItem() != null) { @@ -53,4 +121,57 @@ public class Listeners implements Listener { } } + @EventHandler(ignoreCancelled = true) + public void spawnMobEvent(CreatureSpawnEvent event) { + if(event.getSpawnReason() == CreatureSpawnEvent.SpawnReason.NETHER_PORTAL && portalServices.inPortalRegionProtected(ContainerHelpers.toPlayerLocation(event.getLocation()))) { + event.setCancelled(true); + } + } + + // Block events + + @EventHandler(priority = EventPriority.HIGH) + public void onBlockFromTo(BlockFromToEvent event) { + if(!configRepository.getStopWaterFlow()) { + return; + } + if(!coreListeners.blockPlace(null, + ContainerHelpers.toBlockLocation(event.getBlock().getLocation()), + event.getBlock().getType().toString(), + null, + null) || !coreListeners.blockPlace(null, + ContainerHelpers.toBlockLocation(event.getToBlock().getLocation()), + event.getBlock().getType().toString(), + null, + null)) { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGH) + public void onBlockBreak(BlockBreakEvent event) { + var itemInHand = event.getPlayer().getItemInHand(); + if(!coreListeners.blockBreak(new SpigotPlayerContainer(event.getPlayer()), + ContainerHelpers.toBlockLocation(event.getBlock().getLocation()), + event.getBlock().getType().toString(), + itemInHand == null ? null : itemInHand.getType().toString(), + itemInHand == null || itemInHand.getItemMeta() == null ? null : itemInHand.getItemMeta().getDisplayName())) { + event.setCancelled(true); + } + } + + + @EventHandler(priority = EventPriority.HIGH) + public void onExplosion(EntityExplodeEvent event) { + if(!configRepository.getPortalProtection()) return; + + List blockList = event.blockList(); + for (int i = 0; i < blockList.size(); i++) { + Block block = blockList.get(i); + if (portalServices.inPortalRegionProtected(ContainerHelpers.toBlockLocation(block.getLocation()))) { + blockList.remove(i); + i--; + } + } + } } diff --git a/spigot/src/main/java/com/sekwah/advancedportals/spigot/connector/container/SpigotEntityContainer.java b/spigot/src/main/java/com/sekwah/advancedportals/spigot/connector/container/SpigotEntityContainer.java new file mode 100644 index 0000000..191af64 --- /dev/null +++ b/spigot/src/main/java/com/sekwah/advancedportals/spigot/connector/container/SpigotEntityContainer.java @@ -0,0 +1,61 @@ +package com.sekwah.advancedportals.spigot.connector.container; + +import com.google.inject.Inject; +import com.sekwah.advancedportals.core.AdvancedPortalsCore; +import com.sekwah.advancedportals.core.connector.containers.EntityContainer; +import com.sekwah.advancedportals.core.connector.containers.WorldContainer; +import com.sekwah.advancedportals.core.serializeddata.BlockLocation; +import com.sekwah.advancedportals.core.serializeddata.PlayerLocation; +import com.sekwah.advancedportals.spigot.AdvancedPortalsPlugin; +import com.sekwah.advancedportals.spigot.reflection.MinecraftCustomPayload; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Entity; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.Arrays; + +/** + * Just a temporary container for whenever advanced portals needs to get data from a player + */ +public class SpigotEntityContainer implements EntityContainer { + + @Inject + private AdvancedPortalsCore portalsCore; + + private final Entity entity; + + public SpigotEntityContainer(Entity entity) { + this.entity = entity; + } + + @Override + public PlayerLocation getLoc() { + Location loc = this.entity.getLocation(); + return new PlayerLocation(loc.getWorld().getName(), loc.getX(), loc.getY(), loc.getZ(), loc.getYaw(), loc.getPitch()); + } + + @Override + public BlockLocation getBlockLoc() { + Location loc = this.entity.getLocation(); + return new BlockLocation(loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); + } + + @Override + public double getHeight() { + return this.entity.getHeight(); + } + + @Override + public void teleport(PlayerLocation location) { + this.entity.teleport(new Location(Bukkit.getWorld(location.getWorldName()), location.getPosX(), location.getPosY(), location.getPosZ())); + } + + + @Override + public WorldContainer getWorld() { + return new SpigotWorldContainer(this.entity.getWorld()); + } +} diff --git a/spigot/src/main/java/com/sekwah/advancedportals/spigot/connector/container/SpigotPlayerContainer.java b/spigot/src/main/java/com/sekwah/advancedportals/spigot/connector/container/SpigotPlayerContainer.java index c00f9e6..dd8c364 100644 --- a/spigot/src/main/java/com/sekwah/advancedportals/spigot/connector/container/SpigotPlayerContainer.java +++ b/spigot/src/main/java/com/sekwah/advancedportals/spigot/connector/container/SpigotPlayerContainer.java @@ -21,7 +21,7 @@ import java.util.UUID; /** * Just a temporary container for whenever advanced portals needs to get data from a player */ -public class SpigotPlayerContainer implements PlayerContainer { +public class SpigotPlayerContainer extends SpigotEntityContainer implements PlayerContainer { @Inject private AdvancedPortalsCore portalsCore; @@ -29,52 +29,40 @@ public class SpigotPlayerContainer implements PlayerContainer { private final Player player; public SpigotPlayerContainer(Player player) { + super(player); this.player = player; } + @Override public UUID getUUID() { return player.getUniqueId(); } + @Override public void sendMessage(String message) { player.sendMessage(message); } + @Override public boolean isOp() { return this.player.isOp(); } - public PlayerLocation getLoc() { - Location loc = this.player.getLocation(); - return new PlayerLocation(loc.getWorld().getName(), loc.getX(), loc.getY(), loc.getZ(), loc.getYaw(), loc.getPitch()); - } - @Override - public BlockLocation getBlockLoc() { - Location loc = this.player.getLocation(); - return new BlockLocation(loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); - } - - public double getEyeHeight() { - return 0; - } - public void teleport(PlayerLocation location) { this.player.teleport(new Location(Bukkit.getWorld(location.getWorldName()), location.getPosX(), location.getPosY(), location.getPosZ())); } + @Override public boolean hasPermission(String permission) { return this.player.hasPermission(permission); } - public WorldContainer getWorld() { - return new SpigotWorldContainer(this.player.getWorld()); - } - /** * @param blockPos * @param material */ + @Override public void sendFakeBlock(BlockLocation blockPos, String material) { } @@ -85,10 +73,12 @@ public class SpigotPlayerContainer implements PlayerContainer { * @param material * @param data */ + @Override public void sendFakeBlockWithData(BlockLocation blockPos, String material, byte data) { } + @Override public void giveItem(String material, String itemName, String... itemDescription) { ItemStack regionselector = new ItemStack(Material.getMaterial(material)); ItemMeta selectorname = regionselector.getItemMeta(); diff --git a/spigot/src/main/java/com/sekwah/advancedportals/spigot/utils/ContainerHelpers.java b/spigot/src/main/java/com/sekwah/advancedportals/spigot/utils/ContainerHelpers.java new file mode 100644 index 0000000..a18a492 --- /dev/null +++ b/spigot/src/main/java/com/sekwah/advancedportals/spigot/utils/ContainerHelpers.java @@ -0,0 +1,18 @@ +package com.sekwah.advancedportals.spigot.utils; + +import com.sekwah.advancedportals.core.serializeddata.BlockLocation; +import com.sekwah.advancedportals.core.serializeddata.PlayerLocation; +import org.bukkit.Location; + +public class ContainerHelpers { + + public static PlayerLocation toPlayerLocation(Location loc) { + return new PlayerLocation(loc.getWorld().getName(), loc.getX(), loc.getY(), loc.getZ(), loc.getYaw(), loc.getPitch()); + } + + public static BlockLocation toBlockLocation(Location loc) { + return new BlockLocation(loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); + } + + +}