package nl.sbdeveloper.themeparkplus.util; import nl.sbdeveloper.themeparkplus.ThemeParkPlus; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.block.BlockState; import org.bukkit.util.Vector; import org.jetbrains.annotations.Nullable; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import java.util.Objects; public class LGUtil { private static List offsets = new ArrayList<>(); private static List nearbyBlocks = new ArrayList<>(); private static boolean nieuweVersie = false; private static Method getBlockDataMethod; private static Method setBlockDataMethod; private static Method getAsStringMethod; private static Object lampAanData; private static Object lampUitData; public LGUtil() { offsets.add(new Vector(1, 0, 0)); offsets.add(new Vector(-1, 0, 0)); offsets.add(new Vector(0, 1, 0)); offsets.add(new Vector(0, -1, 0)); offsets.add(new Vector(0, 0, 1)); offsets.add(new Vector(0, 0, -1)); try { Class blockDataClass = Class.forName("org.bukkit.block.data.BlockData"); Method methodCreateBlockData = Bukkit.class.getMethod("createBlockData", String.class); getBlockDataMethod = Block.class.getMethod("getBlockData"); setBlockDataMethod = Block.class.getMethod("setBlockData", blockDataClass, Boolean.TYPE); getAsStringMethod = blockDataClass.getMethod("getAsString"); lampAanData = methodCreateBlockData.invoke(null, "minecraft:redstone_lamp[lit=true]"); lampUitData = methodCreateBlockData.invoke(null, "minecraft:redstone_lamp[lit=false]"); nieuweVersie = true; } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) {} } public static boolean zetLampAan(Block lampBlock) { if (nieuweVersie) { if ((isLamp(lampBlock)) && (!isAan(lampBlock))) { setBlockData(lampBlock, lampAanData); return true; } return false; } if (!isAan(lampBlock)) { final Block neighbor = getNeighbor(lampBlock); if (neighbor != null) { BlockState neighborState = neighbor.getState(); try { for (org.bukkit.util.Vector offset: offsets) { Block neighborOfNeighbor = neighbor.getLocation().add(offset).getBlock(); if ((neighborOfNeighbor.getX() != lampBlock.getX()) || (neighborOfNeighbor.getY() != lampBlock.getY()) || (neighborOfNeighbor.getZ() != lampBlock.getZ())) { nearbyBlocks.add(neighborOfNeighbor); } } neighbor.setType(Material.REDSTONE_BLOCK); } catch (Exception e) { e.printStackTrace(); } finally { neighborState.update(true, false); Bukkit.getScheduler().runTaskLater(ThemeParkPlus.getInstance(), () -> { for (Vector offset: offsets) { Block neighborOfNeighbor = neighbor.getLocation().add(offset).getBlock(); nearbyBlocks.remove(neighborOfNeighbor); } }, 1L); } return true; } } return false; } public static boolean zetLampUit(Block lampBlock) { if (nieuweVersie) { if ((isLamp(lampBlock)) && (isAan(lampBlock))) { setBlockData(lampBlock, lampUitData); return true; } return false; } if (isAan(lampBlock)) { lampBlock.setType(Objects.requireNonNull(Material.matchMaterial(XMaterial.REDSTONE_LAMP.getLegacy()[0]))); return true; } return false; } public static boolean openGate(Block b) { return openGate(b, getDirection(b)); } public static boolean openGate(Block b, BlockFace openFace) { if (nieuweVersie) { org.bukkit.block.data.BlockData blockData = b.getBlockData(); if (isOpenable(b)) { org.bukkit.block.data.Openable op = (org.bukkit.block.data.Openable) blockData; if (op.isOpen()) return false; op.setOpen(true); b.setBlockData(blockData); org.bukkit.block.data.Directional dir = (org.bukkit.block.data.Directional) blockData; dir.setFacing(openFace); b.setBlockData(blockData); return true; } } else { BlockState state = b.getState(); if (isOpenable(b)) { org.bukkit.material.Openable openable = (org.bukkit.material.Openable) state.getData(); if (openable.isOpen()) return false; openable.setOpen(true); state.setData((org.bukkit.material.MaterialData) openable); state.update(); org.bukkit.material.Directional dir = (org.bukkit.material.Directional) state.getData(); dir.setFacingDirection(openFace); state.setData((org.bukkit.material.MaterialData) dir); state.update(); return true; } } return false; } public static boolean closeGate(Block b) { if (nieuweVersie) { org.bukkit.block.data.BlockData blockData = b.getBlockData(); if (isOpenable(b)) { org.bukkit.block.data.Openable op = (org.bukkit.block.data.Openable) blockData; if (!op.isOpen()) { return false; } op.setOpen(false); b.setBlockData(blockData); return true; } } else { BlockState state = b.getState(); if (isOpenable(b)) { org.bukkit.material.Openable openable = (org.bukkit.material.Openable) state.getData(); if (!openable.isOpen()) { return false; } openable.setOpen(false); state.setData((org.bukkit.material.MaterialData) openable); state.update(); return true; } } return false; } @Nullable public static BlockFace getDirection(Block b) { if (nieuweVersie) { org.bukkit.block.data.BlockData blockData = b.getBlockData(); if (isOpenable(b)) { org.bukkit.block.data.Directional dir = (org.bukkit.block.data.Directional) blockData; return dir.getFacing(); } } else { BlockState state = b.getState(); if (isOpenable(b)) { org.bukkit.material.Directional dir = (org.bukkit.material.Directional) state.getData(); return dir.getFacing(); } } return null; } public static boolean isOpen(Block b) { if (nieuweVersie) { org.bukkit.block.data.BlockData blockData = b.getBlockData(); if (isOpenable(b)) { org.bukkit.block.data.Openable op = (org.bukkit.block.data.Openable) blockData; return op.isOpen(); } } else { BlockState state = b.getState(); if (isOpenable(b)) { org.bukkit.material.Openable openable = (org.bukkit.material.Openable) state.getData(); return openable.isOpen(); } } return false; } /* Gate codes sponsored by MrWouter <3 */ public static boolean isOpenable(Block b) { if (b == null) { return false; } if (nieuweVersie) { return b.getBlockData() instanceof org.bukkit.block.data.Openable; } else { return b.getState().getData() instanceof org.bukkit.material.Openable; } } private static Block getNeighbor(Block lampBlock) { List possibleNeighbors = new ArrayList<>(); if (lampBlock.getLocation().getY() > 0.0D) { possibleNeighbors.add(lampBlock.getLocation().add(0.0D, -1.0D, 0.0D).getBlock()); } if (lampBlock.getLocation().getY() < 255.0D) { possibleNeighbors.add(lampBlock.getLocation().add(0.0D, 1.0D, 0.0D).getBlock()); } possibleNeighbors.add(lampBlock.getLocation().add(0.0D, 0.0D, 1.0D).getBlock()); possibleNeighbors.add(lampBlock.getLocation().add(0.0D, 0.0D, -1.0D).getBlock()); possibleNeighbors.add(lampBlock.getLocation().add(1.0D, 0.0D, 0.0D).getBlock()); possibleNeighbors.add(lampBlock.getLocation().add(-1.0D, 0.0D, 0.0D).getBlock()); for (Block neighbor: possibleNeighbors) { if (neighbor.getType() == Material.AIR) { return neighbor; } } for (Block neighbor: possibleNeighbors) { if ((neighbor.getState().getClass().getSimpleName().equals("CraftBlockState")) && (neighbor.getType() != Material.valueOf(XMaterial.PISTON_HEAD.getLegacy()[0]) && neighbor.getType() != Material.valueOf(XMaterial.MOVING_PISTON.getLegacy()[1])) && (neighbor.getType() != Material.valueOf("REDSTONE_LAMP_ON"))) { return neighbor; } } for (Block neighbor: possibleNeighbors) { if ((neighbor.getState().getClass().getSimpleName().equals("CraftBlockState")) && (neighbor.getType() != Material.valueOf(XMaterial.PISTON_HEAD.getLegacy()[0]) && neighbor.getType() != Material.valueOf(XMaterial.MOVING_PISTON.getLegacy()[1]))) { return neighbor; } } return null; } private static boolean isAan(Block lamp) { return ((nieuweVersie) && (Objects.requireNonNull(getAsString(getBlockData(lamp))).contains("lit=true"))) || ((!nieuweVersie) && (lamp.getType() == Material.matchMaterial(XMaterial.REDSTONE_LAMP.getLegacy()[1]))); } private static boolean isLamp(Block lamp) { if (nieuweVersie) { return lamp.getType() == XMaterial.REDSTONE_LAMP.parseMaterial(); } else { return lamp.getType() == Material.matchMaterial(XMaterial.REDSTONE_LAMP.getLegacy()[1]) || lamp.getType() == Material.matchMaterial(XMaterial.REDSTONE_LAMP.getLegacy()[0]); } } private static void setBlockData(Block lamp, Object blockData) { try { setBlockDataMethod.invoke(lamp, blockData, Boolean.FALSE); } catch (Exception e) { e.printStackTrace(); } } private static Object getBlockData(Block lamp) { try { return getBlockDataMethod.invoke(lamp); } catch (Exception e) { e.printStackTrace(); } return null; } private static String getAsString(Object blockData) { try { return (String) getAsStringMethod.invoke(blockData, new Object[0]); } catch (Exception e) { e.printStackTrace(); } return null; } }