diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorCursor.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorCursor.java deleted file mode 100644 index 1c44e35d..00000000 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorCursor.java +++ /dev/null @@ -1,362 +0,0 @@ -/* - * This file is a part of the SteamWar software. - * - * Copyright (C) 2025 SteamWar.de-Serverteam - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package de.steamwar.bausystem.features.simulator; - -import de.steamwar.bausystem.BauSystem; -import de.steamwar.bausystem.Permission; -import de.steamwar.bausystem.SWUtils; -import de.steamwar.bausystem.features.simulator.data.Simulator; -import de.steamwar.bausystem.features.simulator.data.SimulatorElement; -import de.steamwar.bausystem.features.simulator.data.SimulatorGroup; -import de.steamwar.bausystem.features.simulator.data.observer.ObserverElement; -import de.steamwar.bausystem.features.simulator.data.observer.ObserverPhase; -import de.steamwar.bausystem.features.simulator.data.redstone.RedstoneElement; -import de.steamwar.bausystem.features.simulator.data.redstone.RedstonePhase; -import de.steamwar.bausystem.features.simulator.data.tnt.TNTElement; -import de.steamwar.bausystem.features.simulator.data.tnt.TNTPhase; -import de.steamwar.bausystem.features.simulator.execute.SimulatorExecutor; -import de.steamwar.bausystem.features.simulator.gui.SimulatorGroupGui; -import de.steamwar.bausystem.features.simulator.gui.SimulatorGui; -import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui; -import de.steamwar.bausystem.utils.BauMemberUpdateEvent; -import de.steamwar.bausystem.utils.ItemUtils; -import de.steamwar.core.SWPlayer; -import de.steamwar.cursor.Cursor; -import de.steamwar.entity.REntity; -import de.steamwar.entity.REntityServer; -import de.steamwar.inventory.SWAnvilInv; -import de.steamwar.linkage.Linked; -import lombok.AllArgsConstructor; -import lombok.Getter; -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.Material; -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.inventory.InventoryClickEvent; -import org.bukkit.event.inventory.InventoryDragEvent; -import org.bukkit.event.player.PlayerDropItemEvent; -import org.bukkit.event.player.PlayerItemHeldEvent; -import org.bukkit.event.player.PlayerJoinEvent; -import org.bukkit.event.player.PlayerQuitEvent; -import org.bukkit.event.player.PlayerToggleSneakEvent; -import org.bukkit.inventory.ItemStack; -import org.bukkit.util.Vector; - -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.function.Function; -import java.util.stream.Collectors; - -@Linked -public class SimulatorCursor implements Listener { - - private static final Map cursorType = Collections.synchronizedMap(new HashMap<>()); - private static final Map emptyTargetServers = Collections.synchronizedMap(new HashMap<>()); - - public static boolean isSimulatorItem(ItemStack itemStack) { - return ItemUtils.isItem(itemStack, "simulator"); - } - - private static boolean hasSimulatorItem(Player player) { - return isSimulatorItem(player.getInventory().getItemInMainHand()) || isSimulatorItem(player.getInventory().getItemInOffHand()); - } - - private static void scheduleCursorUpdate(Player player) { - BauSystem.runTaskLater(BauSystem.getInstance(), () -> calcCursor(player), 1); - } - - @EventHandler - public void onPlayerJoin(PlayerJoinEvent event) { - if (!Permission.BUILD.hasPermission(event.getPlayer())) return; - scheduleCursorUpdate(event.getPlayer()); - } - - @EventHandler - public void onPlayerDropItem(PlayerDropItemEvent event) { - if (!Permission.BUILD.hasPermission(event.getPlayer())) return; - scheduleCursorUpdate(event.getPlayer()); - } - - @EventHandler - public void onPlayerItemHeld(PlayerItemHeldEvent event) { - if (!Permission.BUILD.hasPermission(event.getPlayer())) return; - scheduleCursorUpdate(event.getPlayer()); - } - - @EventHandler - public void onInventoryClick(InventoryClickEvent event) { - if (!(event.getWhoClicked() instanceof Player player)) return; - if (!Permission.BUILD.hasPermission(player)) return; - scheduleCursorUpdate(player); - } - - @EventHandler - public void onInventoryDrag(InventoryDragEvent event) { - if (!(event.getWhoClicked() instanceof Player player)) return; - if (!Permission.BUILD.hasPermission(player)) return; - scheduleCursorUpdate(player); - } - - @EventHandler - public void onBauMemberUpdate(BauMemberUpdateEvent event) { - event.getChanged().forEach(SimulatorCursor::calcCursor); - } - - @EventHandler - public void onPlayerQuit(PlayerQuitEvent event) { - cursorType.remove(event.getPlayer()); - removeCursor(event.getPlayer()); - } - - private static final Map LAST_SNEAKS = new HashMap<>(); - - static { - Bukkit.getScheduler().runTaskTimer(BauSystem.getInstance(), () -> { - long millis = System.currentTimeMillis(); - LAST_SNEAKS.entrySet().removeIf(entry -> millis - entry.getValue() > 200); - }, 1, 1); - } - - @EventHandler(priority = EventPriority.HIGH) - public void onPlayerToggleSneak(PlayerToggleSneakEvent event) { - if (!event.isSneaking()) return; - Player player = event.getPlayer(); - if (!hasSimulatorItem(player)) { - return; - } - if (LAST_SNEAKS.containsKey(player)) { - CursorType currentType = cursorType.getOrDefault(player, CursorType.TNT); - if (currentType == CursorType.TNT) { - cursorType.put(player, CursorType.REDSTONE_BLOCK); - } else { - cursorType.put(player, CursorType.TNT); - } - calcCursor(player); - } else { - LAST_SNEAKS.put(player, System.currentTimeMillis()); - } - } - - public static CursorType getCursorType(Player player) { - return cursorType.getOrDefault(player, CursorType.TNT); - } - - public static void setCursorType(Player player, CursorType cursorType) { - SimulatorCursor.cursorType.put(player, cursorType); - calcCursor(player); - } - - public static void calcCursor(Player player) { - if (!Permission.BUILD.hasPermission(player) || !hasSimulatorItem(player)) { - if (removeCursor(player) || SimulatorWatcher.show(null, player)) { - SWUtils.sendToActionbar(player, ""); - } - return; - } - - Simulator simulator = SimulatorStorage.getSimulator(player); - if (simulator != null && simulator.getStabGenerator() != null) { - removeCursor(player); - SimulatorWatcher.show(null, player); - SWUtils.sendToActionbar(player, "§cGenerating Stab"); - return; - } - - SimulatorWatcher.show(simulator, player); - Cursor cursor = getOrCreateCursor(player, simulator, cursorType.getOrDefault(player, CursorType.TNT)); - cursor.renderDeduplicated(); - } - - private static Cursor getOrCreateCursor(Player player, Simulator simulator, CursorType type) { - REntityServer targetServer = simulator == null ? emptyTargetServers.computeIfAbsent(player, __ -> new REntityServer()) : SimulatorWatcher.getEntityServerOfSimulator(simulator); - SWPlayer swPlayer = SWPlayer.of(player); - Optional activeCursor = swPlayer.getComponent(Cursor.class); - - Cursor cursor = activeCursor.orElse(null); - if (cursor == null || cursor.getTargetServer() != targetServer) { - swPlayer.removeComponent(Cursor.class); - cursor = new Cursor( - targetServer, - player, - Material.GLASS, - type.material, - type.cursorModes, - (location, hitEntity, action) -> handlePlayerClick(player, location, hitEntity, action), - (location, hitEntity) -> sendCursorActionbar(player, SimulatorStorage.getSimulator(player), location != null, hitEntity.isPresent()) - ); - } else { - cursor.setCursorMaterial(type.material); - cursor.setAllowedCursorModes(type.cursorModes); - } - - return cursor; - } - - private static synchronized boolean removeCursor(Player player) { - Optional cursor = SWPlayer.of(player).getComponent(Cursor.class); - cursor.ifPresent(__ -> SWPlayer.of(player).removeComponent(Cursor.class)); - REntityServer emptyTargetServer = emptyTargetServers.remove(player); - if (emptyTargetServer != null) { - emptyTargetServer.close(); - } - return cursor.isPresent(); - } - - private static void sendCursorActionbar(Player player, Simulator simulator, boolean hasCursorLocation, boolean hasHitEntity) { - if (!hasCursorLocation) { - SWUtils.sendToActionbar(player, simulator == null ? "§eSelect Simulator" : "§eOpen Simulator"); - } else if (simulator == null) { - SWUtils.sendToActionbar(player, "§eCreate new Simulator"); - } else if (hasHitEntity) { - SWUtils.sendToActionbar(player, "§eEdit Position"); - } else { - SWUtils.sendToActionbar(player, "§eAdd new " + cursorType.getOrDefault(player, CursorType.TNT).name); - } - } - - @Getter - @AllArgsConstructor - public enum CursorType { - TNT(Material.TNT, Material.GUNPOWDER, List.of(Cursor.CursorMode.FREE, Cursor.CursorMode.SURFACE_ALIGNED), "TNT", vector -> new TNTElement(vector).add(new TNTPhase())), - REDSTONE_BLOCK(Material.REDSTONE_BLOCK, Material.REDSTONE, List.of(Cursor.CursorMode.BLOCK_ALIGNED), "Redstone Block", vector -> new RedstoneElement(vector).add(new RedstonePhase())), - OBSERVER(Material.OBSERVER, Material.QUARTZ, List.of(Cursor.CursorMode.BLOCK_ALIGNED), "Observer", vector -> new ObserverElement(vector).add(new ObserverPhase())), - ; - - public final Material material; - public final Material nonSelectedMaterial; - public final List cursorModes; - public final String name; - public final Function> elementFunction; - } - - private static void handlePlayerClick(Player player, Location cursorLocation, Optional hitEntity, Action action) { - if (!Permission.BUILD.hasPermission(player)) return; - if (!hasSimulatorItem(player)) { - return; - } - - Simulator simulator = SimulatorStorage.getSimulator(player); - - if (action == Action.LEFT_CLICK_BLOCK || action == Action.LEFT_CLICK_AIR) { - if (simulator == null) { - return; - } - SimulatorExecutor.run(player, simulator, null); - return; - } - - if (action != Action.RIGHT_CLICK_BLOCK && action != Action.RIGHT_CLICK_AIR) { - return; - } - - if (simulator == null) { - if (cursorLocation == null) { - SimulatorStorage.openSimulatorSelector(player); - } else { - SWAnvilInv anvilInv = new SWAnvilInv(player, "Name"); - anvilInv.setCallback(s -> { - Simulator sim = SimulatorStorage.getSimulator(s); - if (sim != null) { - BauSystem.MESSAGE.send("SIMULATOR_NAME_ALREADY_EXISTS", player); - return; - } - if (!s.matches("[a-zA-Z_0-9-]+")) { - BauSystem.MESSAGE.send("SIMULATOR_NAME_INVALID", player); - return; - } - sim = new Simulator(s); - SimulatorStorage.addSimulator(s, sim); - createElement(player, cursorLocation, sim); - SimulatorStorage.setSimulator(player, sim); - }); - anvilInv.open(); - } - return; - } - - if (cursorLocation == null) { - new SimulatorGui(player, simulator).open(); - return; - } - - if (hitEntity.isPresent()) { - openElement(player, simulator, hitEntity.get()); - return; - } - - createElement(player, cursorLocation, simulator); - } - - private static void openElement(Player player, Simulator simulator, REntity hitEntity) { - Vector vector = new Vector(hitEntity.getX(), hitEntity.getY(), hitEntity.getZ()); - List> elements = simulator.getGroups().stream().map(SimulatorGroup::getElements).flatMap(List::stream).filter(element -> { - return element.getWorldPos().distanceSquared(vector) < (1 / 16.0) * (1 / 16.0); - }).collect(Collectors.toList()); - - switch (elements.size()) { - case 0: - return; - case 1: - SimulatorElement element = elements.get(0); - SimulatorGroup group1 = element.getGroup(simulator); - SimulatorBaseGui back = new SimulatorGui(player, simulator); - if (group1.getElements().size() > 1) { - back = new SimulatorGroupGui(player, simulator, group1, back); - } - element.open(player, simulator, group1, back); - break; - default: - List parents = elements.stream().map(e -> e.getGroup(simulator)).distinct().collect(Collectors.toList()); - if (parents.size() == 1) { - SimulatorGui simulatorGui = new SimulatorGui(player, simulator); - new SimulatorGroupGui(player, simulator, parents.get(0), simulatorGui).open(); - } else { - SimulatorGroup group2 = new SimulatorGroup(); - group2.setMaterial(null); - group2.getElements().addAll(elements); - SimulatorGui simulatorGui = new SimulatorGui(player, simulator); - new SimulatorGroupGui(player, simulator, group2, simulatorGui).open(); - } - break; - } - } - - private static void createElement(Player player, Location cursorLocation, Simulator simulator) { - CursorType type = cursorType.getOrDefault(player, CursorType.TNT); - Vector vector = cursorLocation.toVector(); - if (type == CursorType.REDSTONE_BLOCK) { - vector.subtract(new Vector(0.5, 0, 0.5)); - } - SimulatorElement element = type.elementFunction.apply(vector); - SimulatorGroup group = new SimulatorGroup().add(element); - simulator.getGroups().add(group); - SimulatorGui simulatorGui = new SimulatorGui(player, simulator); - element.open(player, simulator, group, simulatorGui); - SimulatorWatcher.update(simulator); - calcCursor(player); - } -}