333 lines
13 KiB
Java
333 lines
13 KiB
Java
/*
|
|
* Copyright (C) 2012-2022 Frank Baumann
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
package de.erethon.dungeonsxl.global;
|
|
|
|
import de.erethon.caliburn.category.Category;
|
|
import de.erethon.caliburn.item.VanillaItem;
|
|
import de.erethon.dungeonsxl.DungeonsXL;
|
|
import de.erethon.dungeonsxl.config.DMessage;
|
|
import de.erethon.dungeonsxl.player.DGlobalPlayer;
|
|
import de.erethon.dungeonsxl.player.DPermission;
|
|
import de.erethon.dungeonsxl.player.DPlayerListener;
|
|
import java.util.Collection;
|
|
import java.util.HashSet;
|
|
import java.util.List;
|
|
import java.util.Map.Entry;
|
|
import java.util.Set;
|
|
import org.bukkit.World;
|
|
import org.bukkit.block.Block;
|
|
import org.bukkit.block.BlockFace;
|
|
import org.bukkit.block.BlockState;
|
|
import org.bukkit.block.Sign;
|
|
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.BlockBreakEvent;
|
|
import org.bukkit.event.block.BlockPhysicsEvent;
|
|
import org.bukkit.event.block.BlockPlaceEvent;
|
|
import org.bukkit.event.block.BlockSpreadEvent;
|
|
import org.bukkit.event.block.SignChangeEvent;
|
|
import org.bukkit.event.entity.EntityExplodeEvent;
|
|
import org.bukkit.event.player.PlayerBucketFillEvent;
|
|
import org.bukkit.event.player.PlayerInteractEvent;
|
|
import org.bukkit.event.player.PlayerMoveEvent;
|
|
import org.bukkit.event.player.PlayerPortalEvent;
|
|
import org.bukkit.event.world.WorldLoadEvent;
|
|
import org.bukkit.event.world.WorldUnloadEvent;
|
|
import org.bukkit.inventory.ItemStack;
|
|
|
|
/**
|
|
* @author Daniel Saukel, Wooyoung Son, Frank Baumann, Milan Albrecht
|
|
*/
|
|
public class GlobalProtectionListener implements Listener {
|
|
|
|
private DungeonsXL plugin;
|
|
|
|
public GlobalProtectionListener(DungeonsXL plugin) {
|
|
this.plugin = plugin;
|
|
}
|
|
|
|
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
|
|
public void onBlockBreakWithSignOnIt(BlockBreakEvent event) {
|
|
Block block = event.getBlock();
|
|
Player player = event.getPlayer();
|
|
|
|
Block blockAbove = block.getRelative(BlockFace.UP);
|
|
//get the above block and return if there is nothing
|
|
if (blockAbove == null) {
|
|
return;
|
|
}
|
|
|
|
//return if above block is not a sign
|
|
if (!Category.SIGNS.containsBlock(blockAbove)) {
|
|
return;
|
|
}
|
|
|
|
//let onBreak() method to handle the sign
|
|
BlockBreakEvent bbe = new BlockBreakEvent(blockAbove, player);
|
|
onBlockBreak(bbe);
|
|
|
|
//follow the onBreak()
|
|
event.setCancelled(bbe.isCancelled());
|
|
}
|
|
|
|
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
|
|
public void onBlockBreak(BlockBreakEvent event) {
|
|
Block block = event.getBlock();
|
|
Player player = event.getPlayer();
|
|
DGlobalPlayer dGlobalPlayer = (DGlobalPlayer) plugin.getPlayerCache().get(player);
|
|
|
|
GlobalProtection protection = plugin.getGlobalProtectionCache().getByBlock(block);
|
|
if (protection != null) {
|
|
if (protection.onBreak(dGlobalPlayer)) {
|
|
event.setCancelled(true);
|
|
}
|
|
}
|
|
}
|
|
|
|
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
|
|
public void onBlockPlace(BlockPlaceEvent event) {
|
|
if (DPortal.getByBlock(plugin, event.getBlock()) != null) {
|
|
event.setCancelled(true);
|
|
}
|
|
}
|
|
|
|
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
|
|
public void onPlayerBucketFill(PlayerBucketFillEvent event) {
|
|
Player player = event.getPlayer();
|
|
if (DPlayerListener.isCitizensNPC(player)) {
|
|
return;
|
|
}
|
|
Block block = event.getBlockClicked();
|
|
if (DPortal.getByBlock(plugin, block) != null) {
|
|
event.setCancelled(true);
|
|
// Workaround for a bug of Bukkit
|
|
event.getPlayer().sendBlockChange(block.getLocation(), block.getType(), (byte) 0);
|
|
}
|
|
}
|
|
|
|
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
|
|
public void onBlockSpread(BlockSpreadEvent event) {
|
|
if (DPortal.getByBlock(plugin, event.getBlock()) != null) {
|
|
event.setCancelled(true);
|
|
}
|
|
}
|
|
|
|
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
|
|
public void onBlockPhysics(BlockPhysicsEvent event) {
|
|
if (DPortal.getByBlock(plugin, event.getBlock()) != null) {
|
|
event.setCancelled(true);
|
|
}
|
|
}
|
|
|
|
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
|
|
public void onEntityExplode(EntityExplodeEvent event) {
|
|
List<Block> blocklist = event.blockList();
|
|
for (Block block : blocklist) {
|
|
if (plugin.getGlobalProtectionCache().isProtectedBlock(block)) {
|
|
event.setCancelled(true);
|
|
}
|
|
}
|
|
}
|
|
|
|
@EventHandler
|
|
public void onPlayerMove(PlayerMoveEvent event) {
|
|
Player player = event.getPlayer();
|
|
if (DPlayerListener.isCitizensNPC(player) || plugin.isInstance(event.getTo().getWorld())) {
|
|
return;
|
|
}
|
|
|
|
if (!plugin.getMainConfig().isStrictMovementCheckEnabled()) {
|
|
Block blockFrom = event.getFrom().getBlock();
|
|
Block blockTo = event.getTo().getBlock();
|
|
if (blockFrom.equals(blockTo)) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
DPortal dPortal = DPortal.getByLocation(plugin, player.getEyeLocation());
|
|
if (dPortal == null) {
|
|
return;
|
|
}
|
|
|
|
dPortal.teleport(player);
|
|
}
|
|
|
|
@EventHandler
|
|
public void onPlayerPortal(PlayerPortalEvent event) {
|
|
Block block1 = event.getFrom().getBlock();
|
|
Block block2 = block1.getRelative(BlockFace.UP);
|
|
Block block3 = block2.getRelative(BlockFace.UP);
|
|
Block block4 = block1.getRelative(BlockFace.DOWN);
|
|
if (isPortalInNearBy(block1) || isPortalInNearBy(block2) || isPortalInNearBy(block3) || isPortalInNearBy(block4)) {
|
|
event.setCancelled(true);
|
|
}
|
|
}
|
|
|
|
private boolean isPortalInNearBy(Block block1) {
|
|
Block block2 = block1.getRelative(BlockFace.WEST);
|
|
Block block3 = block1.getRelative(BlockFace.NORTH);
|
|
Block block4 = block1.getRelative(BlockFace.EAST);
|
|
Block block5 = block1.getRelative(BlockFace.SOUTH);
|
|
Block block6 = block2.getRelative(BlockFace.NORTH);
|
|
Block block7 = block2.getRelative(BlockFace.SOUTH);
|
|
Block block8 = block4.getRelative(BlockFace.NORTH);
|
|
Block block9 = block4.getRelative(BlockFace.SOUTH);
|
|
return (DPortal.getByBlock(plugin, block1) != null || DPortal.getByBlock(plugin, block2) != null || DPortal.getByBlock(plugin, block3) != null
|
|
|| DPortal.getByBlock(plugin, block4) != null || DPortal.getByBlock(plugin, block5) != null || DPortal.getByBlock(plugin, block6) != null
|
|
|| DPortal.getByBlock(plugin, block7) != null || DPortal.getByBlock(plugin, block8) != null || DPortal.getByBlock(plugin, block9) != null);
|
|
}
|
|
|
|
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
|
|
public void onPortalCreation(PlayerInteractEvent event) {
|
|
Player player = event.getPlayer();
|
|
if (DPlayerListener.isCitizensNPC(player)) {
|
|
return;
|
|
}
|
|
DGlobalPlayer dPlayer = (DGlobalPlayer) plugin.getPlayerCache().get(player);
|
|
if (!dPlayer.isCreatingPortal()) {
|
|
return;
|
|
}
|
|
ItemStack item = event.getItem();
|
|
Block block = event.getClickedBlock();
|
|
if (item == null || !VanillaItem.WOODEN_SWORD.is(item) || block == null) {
|
|
return;
|
|
}
|
|
|
|
for (GlobalProtection protection : plugin.getGlobalProtectionCache().getProtections(DPortal.class)) {
|
|
DPortal dPortal = (DPortal) protection;
|
|
if (dPortal.isActive() || dPortal != dPlayer.getPortal()) {
|
|
continue;
|
|
}
|
|
|
|
if (dPortal.getBlock1() == null) {
|
|
dPortal.setBlock1(event.getClickedBlock());
|
|
dPlayer.sendMessage(DMessage.PLAYER_PORTAL_PROGRESS.getMessage());
|
|
|
|
} else if (dPortal.getBlock2() == null) {
|
|
dPortal.setBlock2(event.getClickedBlock());
|
|
dPortal.setActive(true);
|
|
dPortal.create(dPlayer);
|
|
}
|
|
event.setCancelled(true);
|
|
}
|
|
}
|
|
|
|
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
|
|
public void onInteract(PlayerInteractEvent event) {
|
|
Player player = event.getPlayer();
|
|
if (DPlayerListener.isCitizensNPC(player) || plugin.getPlayerCache().get(player).isInBreakMode()) {
|
|
return;
|
|
}
|
|
Block clickedBlock = event.getClickedBlock();
|
|
if (clickedBlock == null) {
|
|
return;
|
|
}
|
|
|
|
if (Category.SIGNS.containsBlock(clickedBlock)) {
|
|
GroupSign groupSign = GroupSign.getByBlock(plugin, clickedBlock);
|
|
if (groupSign != null) {
|
|
groupSign.onPlayerInteract(clickedBlock, player);
|
|
event.setCancelled(true);
|
|
}
|
|
|
|
GameSign gameSign = GameSign.getByBlock(plugin, clickedBlock);
|
|
if (gameSign != null) {
|
|
gameSign.onPlayerInteract(clickedBlock, player);
|
|
event.setCancelled(true);
|
|
}
|
|
|
|
LeaveSign leaveSign = LeaveSign.getByBlock(plugin, clickedBlock);
|
|
if (leaveSign != null) {
|
|
leaveSign.onPlayerInteract(player);
|
|
event.setCancelled(true);
|
|
}
|
|
}
|
|
}
|
|
|
|
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
|
|
public void onSignChange(SignChangeEvent event) {
|
|
Player player = event.getPlayer();
|
|
Block block = event.getBlock();
|
|
BlockState state = block.getState();
|
|
if (!(state instanceof Sign)) {
|
|
return;
|
|
}
|
|
|
|
String[] lines = event.getLines();
|
|
|
|
// Group Signs
|
|
if (plugin.getEditWorld(player.getWorld()) == null) {
|
|
if (!DPermission.hasPermission(player, DPermission.SIGN)) {
|
|
return;
|
|
}
|
|
|
|
if (!lines[0].equalsIgnoreCase(GlobalProtection.SIGN_TAG)) {
|
|
return;
|
|
}
|
|
|
|
if (lines[1].equalsIgnoreCase(GroupSign.GROUP_SIGN_TAG)) {
|
|
if (GroupSign.tryToCreate(plugin, event) != null) {
|
|
event.setCancelled(true);
|
|
}
|
|
|
|
} else if (lines[1].equalsIgnoreCase(GameSign.GAME_SIGN_TAG)) {
|
|
if (GameSign.tryToCreate(plugin, event) != null) {
|
|
event.setCancelled(true);
|
|
}
|
|
|
|
} else if (lines[1].equalsIgnoreCase(LeaveSign.LEAVE_SIGN_TAG)) {
|
|
Sign sign = (Sign) state;
|
|
plugin.getGlobalProtectionCache().addProtection(new LeaveSign(plugin, plugin.getGlobalProtectionCache().generateId(LeaveSign.class, sign.getWorld()), sign));
|
|
event.setCancelled(true);
|
|
}
|
|
}
|
|
}
|
|
|
|
@EventHandler
|
|
public void onWorldLoad(WorldLoadEvent event) {
|
|
World world = event.getWorld();
|
|
plugin.log("New world detected.");
|
|
Set<Entry<UnloadedProtection, String>> protections = plugin.getGlobalProtectionCache().getUnloadedProtections().entrySet();
|
|
for (Entry<UnloadedProtection, String> entry : protections.toArray(new Entry[protections.size()])) {
|
|
plugin.log("Checking unloaded protection " + entry);
|
|
if (world.getName().equals(entry.getValue())) {
|
|
plugin.log("New world has global DXL data: " + entry);
|
|
plugin.getGlobalProtectionCache().addProtection(entry.getKey().load(world));
|
|
}
|
|
}
|
|
}
|
|
|
|
@EventHandler
|
|
public void onWorldUnload(WorldUnloadEvent event) {
|
|
World world = event.getWorld();
|
|
if (world.getName().startsWith("DXL_")) {
|
|
return;
|
|
}
|
|
plugin.log("Unloaded world detected.");
|
|
Collection<GlobalProtection> protections = plugin.getGlobalProtectionCache().getProtections();
|
|
for (GlobalProtection protection : protections.toArray(new GlobalProtection[protections.size()])) {
|
|
if (protection.getWorld().getName().equals(world.getName())) {
|
|
protection.delete();
|
|
plugin.getGlobalProtectionCache().getUnloadedProtections().put(protection.unload(), world.getName());
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|