diff --git a/BauSystem_Main/src/de/steamwar/bausystem/BauSystem.java b/BauSystem_Main/src/de/steamwar/bausystem/BauSystem.java index c388e29..dd1817f 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/BauSystem.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/BauSystem.java @@ -108,6 +108,7 @@ public class BauSystem extends JavaPlugin implements Listener { Bukkit.getPluginManager().registerEvents(new ClipboardListener(), this); Bukkit.getPluginManager().registerEvents(new TNTSimulatorListener(), this); Bukkit.getPluginManager().registerEvents(new CommandGUI(), this); + Bukkit.getPluginManager().registerEvents(new DetonatorListener(), this); new AFKStopper(); autoShutdown = Bukkit.getScheduler().runTaskLater(this, Bukkit::shutdown, 1200); diff --git a/BauSystem_Main/src/de/steamwar/bausystem/commands/CommandDetonator.java b/BauSystem_Main/src/de/steamwar/bausystem/commands/CommandDetonator.java index ab6ff39..e45e53b 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/commands/CommandDetonator.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/commands/CommandDetonator.java @@ -65,21 +65,19 @@ public class CommandDetonator implements CommandExecutor { case "item": PlayerUtils.giveItemToPlayer(player, Detonator.WAND); player.updateInventory(); - Detonator.getDetonator(player); break; case "remove": - Detonator.deleteDetonator(player); player.getInventory().removeItem(Detonator.WAND); break; case "detonate": case "click": case "use": - Detonator.getDetonator(player).execute(); + Detonator.execute(player); break; case "clear": case "delete": case "reset": - Detonator.getDetonator(player).clearLocs(); + player.getInventory().setItemInMainHand(Detonator.clearDetonator(player.getInventory().getItemInMainHand())); break; default: help(player); diff --git a/BauSystem_Main/src/de/steamwar/bausystem/world/Detonator.java b/BauSystem_Main/src/de/steamwar/bausystem/world/Detonator.java index eea3380..a82be18 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/world/Detonator.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/world/Detonator.java @@ -25,27 +25,24 @@ import de.steamwar.core.VersionedRunnable; import net.md_5.bungee.api.ChatMessageType; import net.md_5.bungee.api.chat.TextComponent; import org.bukkit.Bukkit; +import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.NamespacedKey; import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.HandlerList; import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; import java.util.*; -import java.util.stream.Collectors; public class Detonator implements Listener { public static final ItemStack WAND; - private static final Map players = new HashMap<>(); - - private final Set locs = new HashSet<>(); - private final Player player; + private static final String DETO_PREFIX = "deto-loc-"; + public static final Map> PLAYER_LOCS = new HashMap<>(); static { WAND = new ItemStack(Material.BLAZE_ROD, 1); @@ -53,6 +50,8 @@ public class Detonator implements Listener { im.setDisplayName("§eFernzünder"); + VersionedRunnable.call(new VersionedRunnable(() -> im.getPersistentDataContainer().set(new NamespacedKey(BauSystem.getPlugin(), "deto"), PersistentDataType.BYTE, (byte) 1), 15)); + List lorelist = Arrays.asList("§eLinks Klick §8- §7Setzte einen Punkt zum Aktivieren", "§eLinks Klick + Shift §8- §7Füge einen Punkt hinzu", "§eRechts Klick §8- §7Löse alle Punkte aus"); im.setLore(lorelist); @@ -60,25 +59,64 @@ public class Detonator implements Listener { WAND.setItemMeta(im); } - public static Detonator getDetonator(Player player) { - if (!players.containsKey(player)) - return new Detonator(player); - return players.get(player); + public static Detonator getDetonator(Player player, ItemStack item) { + return VersionedCallable.call(new VersionedCallable<>(() -> { + return new Detonator(player, PLAYER_LOCS.get(player)); + }, 12), new VersionedCallable<>(() -> { + ItemMeta meta = item.getItemMeta(); + PersistentDataContainer container = meta.getPersistentDataContainer(); + List locs = new ArrayList<>(); + for (int i = 0; i < 128; i++) { + NamespacedKey key = new NamespacedKey(BauSystem.getPlugin(), DETO_PREFIX + i); + if(container.has(key, PersistentDataType.INTEGER_ARRAY)) + locs.add(container.get(key, PersistentDataType.INTEGER_ARRAY)); + } + return new Detonator(player, locs.toArray(new int[0][0])); + }, 15)); } - public Detonator(Player player) { - this.player = player; - Bukkit.getPluginManager().registerEvents(this, BauSystem.getPlugin()); - players.put(player, this); + public static ItemStack setLocation(Player player, ItemStack item, Detoloader.DetonatorActivation detoloader) { + return VersionedCallable.call(new VersionedCallable<>(() -> { + PLAYER_LOCS.computeIfAbsent(player, player1 -> new HashSet<>()).clear(); + PLAYER_LOCS.get(player).add(detoloader); + return item; + }, 12), new VersionedCallable<>(() -> pushLocToDetonator(clearDetonator(item), detoloader), 15)); } - public static void deleteDetonator(Player player) { - if (players.containsKey(player)) - HandlerList.unregisterAll(players.remove(player)); + public static ItemStack toggleLocation(ItemStack item, Player player, Detoloader detoloader, Location location) { + if(VersionedCallable.call(new VersionedCallable<>(() -> PLAYER_LOCS.computeIfAbsent(player, player1 -> new HashSet<>()).stream().anyMatch(activation -> activation.location.equals(location)), 12), + new VersionedCallable<>(() -> hasLocation(item, location), 15))) { + DetonatorListener.print(player, detoloader.addBack ? "§e" + detoloader.getBlock() + " entfernt" : + detoloader.getBlock(), Detonator.getDetonator(player, player.getInventory().getItemInMainHand()).getLocs().size() - 1); + return VersionedCallable.call(new VersionedCallable<>(() -> { + PLAYER_LOCS.computeIfAbsent(player, player1 -> new HashSet<>()).removeIf(activation -> activation.location.equals(location)); + return item; + }, 12), new VersionedCallable<>(() -> removeLocation(item, location), 15)); + }else { + DetonatorListener.print(player, detoloader.addBack ? "§e" + detoloader.getBlock() + " hinzugefügt" : + detoloader.getBlock(), Math.min(Detonator.getDetonator(player, player.getInventory().getItemInMainHand()).getLocs().size() + 1, 128)); + if(detoloader.getActivation() == 0) + return VersionedCallable.call(new VersionedCallable<>(() -> { + PLAYER_LOCS.computeIfAbsent(player, player1 -> new HashSet<>()).add(new Detoloader.DetonatorActivation(location)); + return item; + }, 12), new VersionedCallable<>(() -> pushLocToDetonator(item, new Detoloader.DetonatorActivation(location)), 15)); + else + return VersionedCallable.call(new VersionedCallable<>(() -> { + PLAYER_LOCS.computeIfAbsent(player, player1 -> new HashSet<>()).add(new Detoloader.DetonatorActivation(detoloader.getActivation(), location)); + return item; + }, 12), new VersionedCallable<>(() -> pushLocToDetonator(item, new Detoloader.DetonatorActivation(detoloader.getActivation(), location)), 15)); + } } - public void execute() { - for (Detoloader.DetonatorActivation activation : getLocations()) { + public static void execute(Player player) { + VersionedRunnable.call(new VersionedRunnable(() -> execute(player, PLAYER_LOCS.get(player)), 12), new VersionedRunnable(() -> { + Detonator detonator = getDetonator(player, player.getInventory().getItemInMainHand()); + execute(player, detonator.getLocs()); + }, 15)); + } + + private static void execute(Player player, Set locs) { + for (Detoloader.DetonatorActivation activation : locs) { if (activation.activation == -1) { VersionedRunnable.call(new VersionedRunnable(() -> { @@ -98,87 +136,88 @@ public class Detonator implements Listener { }, 15)); } } - player.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText("§a" + locs.size() + " Punkt" + (locs.size() > 1 ? "e" : "") + " ausgelöst!")); + player.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText("§e" + locs.size() + " §7Punkt" + (locs.size() > 1 ? "e" : "") + " ausgelöst!")); } - @EventHandler - public void onPlayerInteract(PlayerInteractEvent event) { - if (!event.getPlayer().equals(player)) - return; + private static int getFreeSlot(ItemStack item) { + ItemMeta meta = item.getItemMeta(); + PersistentDataContainer container = meta.getPersistentDataContainer(); + for (int i = 0; i < 128; i++) { + if (!container.has(new NamespacedKey(BauSystem.getPlugin(), DETO_PREFIX + i), PersistentDataType.INTEGER_ARRAY)) + return i; + } + return -1; + } - if (event.getItem() == null) return; - if (event.getItem().isSimilar(WAND)) { - event.setCancelled(true); - switch (event.getAction()) { - case LEFT_CLICK_BLOCK: - Detoloader detoloader = VersionedCallable.call( - new VersionedCallable<>(() -> AutoLoader_12.onPlayerInteractLoader(event), 12), - new VersionedCallable<>(() -> AutoLoader_15.onPlayerInteractLoader(event), 15)); + public static ItemStack pushLocToDetonator(ItemStack item, Detoloader.DetonatorActivation detoloader) { + int slot = getFreeSlot(item); + if(slot == -1) + throw new SecurityException("Der Detonator ist auf 128 Positionen Limitiert"); + ItemMeta meta = item.getItemMeta(); + Location block = detoloader.location; + meta.getPersistentDataContainer().set(new NamespacedKey(BauSystem.getPlugin(), DETO_PREFIX + slot), PersistentDataType.INTEGER_ARRAY, new int[] + {block.getBlockX(), block.getBlockY(), block.getBlockZ(), detoloader.activation}); + item.setItemMeta(meta); + return item; + } - if (detoloader == null) { - return; - } else if (detoloader.activation == -1) { - print(detoloader.getBlock(), detoloader.addBack); - return; - } + public static ItemStack clearDetonator(ItemStack item) { + ItemMeta meta = item.getItemMeta(); + PersistentDataContainer container = meta.getPersistentDataContainer(); + for (int i = 0; i < 128; i++) { + NamespacedKey key = new NamespacedKey(BauSystem.getPlugin(), DETO_PREFIX + i); + container.remove(key); + } + item.setItemMeta(meta); + return item; + } + public static boolean hasLocation(ItemStack item, Location location) { + return getSlotOfLocation(item, location) != -1; + } - if (event.getPlayer().isSneaking()) { - if (locs.stream().filter(detonatorActivation -> detonatorActivation.location.equals(event.getClickedBlock().getLocation())).collect(Collectors.toList()).size() == 1) { - locs.removeIf(detonatorActivation -> detonatorActivation.location.equals(event.getClickedBlock().getLocation())); - print(detoloader.addBack ? "§e" + detoloader.getBlock() + " entfernt" : - detoloader.getBlock(), detoloader.addBack); - } else { - if (detoloader.getActivation() == 0) { - locs.add(new Detoloader.DetonatorActivation(event.getClickedBlock().getLocation())); - } else { - locs.add(new Detoloader.DetonatorActivation(detoloader.getActivation(), event.getClickedBlock().getLocation())); - } - print(detoloader.addBack ? "§e" + detoloader.getBlock() + " hinzugefügt" : - detoloader.getBlock(), detoloader.addBack); - } - } else { - locs.clear(); - if (detoloader.getActivation() == 0) { - locs.add(new Detoloader.DetonatorActivation(event.getClickedBlock().getLocation())); - } else { - locs.add(new Detoloader.DetonatorActivation(detoloader.getActivation(), event.getClickedBlock().getLocation())); - } - print(detoloader.addBack ? "§e" + detoloader.getBlock() + " gesetzt" : - detoloader.getBlock(), detoloader.addBack); - } - break; - case RIGHT_CLICK_AIR: - case RIGHT_CLICK_BLOCK: - execute(); - break; + private static int getSlotOfLocation(ItemStack item, Location location) { + ItemMeta meta = item.getItemMeta(); + PersistentDataContainer container = meta.getPersistentDataContainer(); + for (int i = 0; i < 128; i++) { + NamespacedKey key = new NamespacedKey(BauSystem.getPlugin(), DETO_PREFIX + i); + if(container.has(key, PersistentDataType.INTEGER_ARRAY)) { + int[] locs = container.get(key, PersistentDataType.INTEGER_ARRAY); + if(locs[0] == location.getBlockX() && locs[1] == location.getBlockY() && locs[2] == location.getBlockZ()) + return i; } } + return -1; + } + + public static ItemStack removeLocation(ItemStack item, Location location) { + ItemMeta meta = item.getItemMeta(); + PersistentDataContainer container = meta.getPersistentDataContainer(); + container.remove(new NamespacedKey(BauSystem.getPlugin(), DETO_PREFIX + getSlotOfLocation(item, location))); + item.setItemMeta(meta); + return item; + } + + private Set locs = new HashSet<>(); + private final Player player; + + private Detonator(Player player, int[][] activations) { + this.player = player; + for (int[] activation : activations) { + locs.add(new Detoloader.DetonatorActivation(activation[3], new Location(player.getWorld(), activation[0], activation[1], activation[2]))); + } } - @EventHandler - public void onPlayerQuit(PlayerQuitEvent event) { - if (event.getPlayer().equals(player)) - deleteDetonator(player); + private Detonator(Player player, Set locs) { + this.player = player; + this.locs = locs; } - Set getLocations() { + public Set getLocs() { return locs; } - Player getPlayer() { + public Player getPlayer() { return player; } - - public void clearLocs() { - locs.clear(); - } - - void print(String message, boolean withSize) { - if (withSize) { - getPlayer().spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(message + " §8" + getLocations().size())); - }else { - getPlayer().spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(message)); - } - } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/world/DetonatorListener.java b/BauSystem_Main/src/de/steamwar/bausystem/world/DetonatorListener.java new file mode 100644 index 0000000..abc569a --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/world/DetonatorListener.java @@ -0,0 +1,75 @@ +package de.steamwar.bausystem.world; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.Permission; +import de.steamwar.core.VersionedCallable; +import net.md_5.bungee.api.ChatMessageType; +import net.md_5.bungee.api.chat.TextComponent; +import org.bukkit.NamespacedKey; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.persistence.PersistentDataType; + +public class DetonatorListener implements Listener { + + @EventHandler + public void onPlayerInteract(PlayerInteractEvent event) { + if (event.getItem() == null) return; + if (VersionedCallable.call(new VersionedCallable<>(() -> event.getItem().isSimilar(Detonator.WAND), 12), + new VersionedCallable<>(() -> event.getItem().getItemMeta().getPersistentDataContainer().has(new NamespacedKey(BauSystem.getPlugin(), "deto"), PersistentDataType.BYTE), 15))) { + Player player = event.getPlayer(); + if(Welt.noPermission(player, Permission.world)){ + player.sendMessage(BauSystem.PREFIX + "§cDu darfst hier nicht den Detonator nutzen"); + return; + } + ItemStack item = event.getItem(); + event.setCancelled(true); + try { + switch (event.getAction()) { + case LEFT_CLICK_BLOCK: + Detoloader detoloader = VersionedCallable.call( + new VersionedCallable<>(() -> AutoLoader_12.onPlayerInteractLoader(event), 12), + new VersionedCallable<>(() -> AutoLoader_15.onPlayerInteractLoader(event), 15)); + + if (detoloader == null) { + return; + } else if (detoloader.activation == -1) { + print(player, detoloader.getBlock(), detoloader.addBack?Detonator.getDetonator(player, player.getInventory().getItemInMainHand()).getLocs().size():0); + return; + } + + if (event.getPlayer().isSneaking()) { + player.getInventory().setItemInMainHand(Detonator.toggleLocation(item, player, detoloader, event.getClickedBlock().getLocation())); + } else { + if (detoloader.getActivation() == 0) { + player.getInventory().setItemInMainHand(Detonator.setLocation(player, item, new Detoloader.DetonatorActivation(event.getClickedBlock().getLocation()))); + } else { + player.getInventory().setItemInMainHand(Detonator.setLocation(player, item, new Detoloader.DetonatorActivation(detoloader.activation, event.getClickedBlock().getLocation()))); + } + print(player, detoloader.addBack ? "§e" + detoloader.getBlock() + " gesetzt" : + detoloader.getBlock(), detoloader.addBack?Detonator.getDetonator(player, player.getInventory().getItemInMainHand()).getLocs().size():0); + } + break; + case RIGHT_CLICK_AIR: + case RIGHT_CLICK_BLOCK: + Detonator.execute(player); + break; + } + }catch (RuntimeException e) { + player.sendMessage(BauSystem.PREFIX + "§c" + e.getMessage()); + player.getInventory().setItemInMainHand(item); + } + } + } + + public static void print(Player player, String message, int size) { + if (size == 0) { + player.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(message)); + }else { + player.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(message + " §8" + size)); + } + } +}