From 6b8f791497eed3b4d05666669ea2640f5b78b7a0 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Thu, 6 Nov 2025 21:38:24 +0100 Subject: [PATCH 01/11] Add SWPlayer for per player storage and without Memory Leaks --- .../features/countingwand/Countingwand.java | 99 ++++------ .../countingwand/CountingwandListener.java | 6 - .../src/de/steamwar/core/SWPlayer.java | 183 ++++++++++++++++++ 3 files changed, 222 insertions(+), 66 deletions(-) create mode 100644 SpigotCore/SpigotCore_Main/src/de/steamwar/core/SWPlayer.java diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/countingwand/Countingwand.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/countingwand/Countingwand.java index bcd13a7f..0e222021 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/countingwand/Countingwand.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/countingwand/Countingwand.java @@ -21,9 +21,10 @@ package de.steamwar.bausystem.features.countingwand; import de.steamwar.bausystem.BauSystem; import de.steamwar.bausystem.region.Point; -import de.steamwar.bausystem.shared.Pair; import de.steamwar.bausystem.utils.ItemUtils; +import de.steamwar.core.SWPlayer; import de.steamwar.inventory.SWItem; +import lombok.Data; import lombok.experimental.UtilityClass; import org.bukkit.Material; import org.bukkit.entity.Player; @@ -31,13 +32,32 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; - @UtilityClass public class Countingwand { + @Data + public class CountingWandComponent implements SWPlayer.Component { + private Point pos1; + private Point pos2; + + public boolean set(boolean pos1, Point point) { + if (this.pos1 == null || this.pos2 == null) { + this.pos1 = point; + this.pos2 = point; + return true; + } + Point current = pos1 ? this.pos1 : this.pos2; + if (current.equals(point)) return false; + if (pos1) { + this.pos1 = point; + } else { + this.pos2 = point; + } + return true; + } + } + public static ItemStack getWandItem(Player player) { ItemStack itemStack = new SWItem(Material.STICK, BauSystem.MESSAGE.parse("COUNTINGWAND_ITEM_NAME", player), Arrays.asList(BauSystem.MESSAGE.parse("COUNTINGWAND_ITEM_LORE1", player), BauSystem.MESSAGE.parse("COUNTINGWAND_ITEM_LORE2", player)), false, null).getItemStack(); ItemUtils.setItem(itemStack, "countingwand"); @@ -47,61 +67,20 @@ public class Countingwand { return itemStack; } - private final Map> selections = new HashMap<>(); + public boolean isCountingwand(ItemStack itemStack) { + return ItemUtils.isItem(itemStack, "countingwand"); + } - public boolean isCountingwand(ItemStack itemStack) { - return ItemUtils.isItem(itemStack, "countingwand"); - } - - public void checkSelection(final Point point, final boolean pos1, final Player p) { - Pair selection = selections.get(p.getUniqueId().toString()); - final boolean newPos; - if (selection != null) { - if (pos1) { - newPos = !point.equals(selection.setKey(point)); - } else { - newPos = !point.equals(selection.setValue(point)); - } - } else { - if (pos1) { - selection = new Pair<>(point, null); - } else { - selection = new Pair<>(null, point); - } - selections.put(p.getUniqueId().toString(), selection); - newPos = true; - } - - if (newPos) { - String dimension = getDimensions(p, selection.getKey(), selection.getValue()); - String volume = getVolume(p, selection.getKey(), selection.getValue()); - if (pos1) { - BauSystem.MESSAGE.send("COUNTINGWAND_MESSAGE_RCLICK", p, point.getX(), point.getY(), point.getZ(), dimension, volume); - } else { - BauSystem.MESSAGE.send("COUNTINGWAND_MESSAGE_LCLICK", p, point.getX(), point.getY(), point.getZ(), dimension, volume); - } - } - } - - public void removePlayer(Player p) { - selections.remove(p.getUniqueId().toString()); - } - - public String getVolume(Player player, final Point point1, final Point point2) { - if (point1 == null || point2 == null) { - return BauSystem.MESSAGE.parse("COUNTINGWAND_MESSAGE_VOLUME", player, 0); - } - return BauSystem.MESSAGE.parse("COUNTINGWAND_MESSAGE_VOLUME", player, getAmount(point1, point2)); - } - - public String getDimensions(Player player, final Point point1, final Point point2) { - if (point1 == null || point2 == null) { - return BauSystem.MESSAGE.parse("COUNTINGWAND_MESSAGE_DIMENSION", player, 0, 0, 0); - } - return BauSystem.MESSAGE.parse("COUNTINGWAND_MESSAGE_DIMENSION", player, Math.abs(point1.getX() - point2.getX()) + 1, Math.abs(point1.getY() - point2.getY()) + 1, Math.abs(point1.getZ() - point2.getZ()) + 1); - } - - public int getAmount(final Point point1, final Point point2) { - return (Math.abs(point1.getX() - point2.getX()) + 1) * (Math.abs(point1.getY() - point2.getY()) + 1) * (Math.abs(point1.getZ() - point2.getZ()) + 1); - } + public void checkSelection(final Point point, final boolean pos1, final Player p) { + SWPlayer player = SWPlayer.of(p); + CountingWandComponent countingWandComponent = player.getComponentOrDefault(CountingWandComponent.class, CountingWandComponent::new); + if (countingWandComponent.set(pos1, point)) { + Point point1 = countingWandComponent.pos1; + Point point2 = countingWandComponent.pos2; + int amount = (Math.abs(point1.getX() - point2.getX()) + 1) * (Math.abs(point1.getY() - point2.getY()) + 1) * (Math.abs(point1.getZ() - point2.getZ()) + 1); + String dimension = player.using(BauSystem.MESSAGE).parse("COUNTINGWAND_MESSAGE_VOLUME", amount); + String volume = player.parse("COUNTINGWAND_MESSAGE_DIMENSION", Math.abs(point1.getX() - point2.getX()) + 1, Math.abs(point1.getY() - point2.getY()) + 1, Math.abs(point1.getZ() - point2.getZ()) + 1); + player.sendMessage(pos1 ? "COUNTINGWAND_MESSAGE_RCLICK" : "COUNTINGWAND_MESSAGE_LCLICK", point.getX(), point.getY(), point.getZ(), dimension, volume); + } + } } \ No newline at end of file diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/countingwand/CountingwandListener.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/countingwand/CountingwandListener.java index 127bb964..9daab3f0 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/countingwand/CountingwandListener.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/countingwand/CountingwandListener.java @@ -27,7 +27,6 @@ import org.bukkit.event.Listener; import org.bukkit.event.block.Action; import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.util.RayTraceResult; import java.util.Objects; @@ -67,9 +66,4 @@ public class CountingwandListener implements Listener { event.setCancelled(true); Countingwand.checkSelection(Point.fromLocation(Objects.requireNonNull(event.getClickedBlock()).getLocation()), false, event.getPlayer()); } - - @EventHandler - public void onLeave(PlayerQuitEvent event) { - Countingwand.removePlayer(event.getPlayer()); - } } \ No newline at end of file diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/core/SWPlayer.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/core/SWPlayer.java new file mode 100644 index 00000000..12a2aa0c --- /dev/null +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/core/SWPlayer.java @@ -0,0 +1,183 @@ +/* + * 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.core; + +import de.steamwar.message.Message; +import lombok.Getter; +import lombok.NonNull; +import lombok.experimental.Delegate; +import net.md_5.bungee.api.ChatMessageType; +import net.md_5.bungee.api.chat.ClickEvent; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.function.Supplier; +import java.util.stream.Stream; + +public class SWPlayer { + + private static final Map players = new HashMap<>(); + + private static class SWPlayerListener implements Listener { + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onPlayerJoin(PlayerJoinEvent event) { + SWPlayer.of(event.getPlayer()); + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onPlayerQuit(PlayerQuitEvent event) { + SWPlayer swPlayer = players.remove(event.getPlayer()); + swPlayer.components.forEach((aClass, component) -> { + component.onUnmount(swPlayer); + }); + } + + @EventHandler + public void onCRIUSleep(CRIUSleepEvent event) { + for (SWPlayer value : players.values()) { + value.components.forEach((aClass, component) -> { + component.onUnmount(value); + }); + } + players.clear(); + } + } + + public interface Component { + + default void onMount(SWPlayer player) { + } + + default void onUnmount(SWPlayer player) { + } + } + + static { + Bukkit.getPluginManager().registerEvents(new SWPlayerListener(), Core.getInstance()); + } + + public static @NonNull SWPlayer of(@NonNull Player player) { + return players.computeIfAbsent(player, SWPlayer::new); + } + + public static @NonNull Stream all() { + return players.values().stream(); + } + + @SafeVarargs + public static @NonNull Stream allWithComponent(Class component, Class... components) { + Stream stream = players.values().stream() + .filter(player -> player.components.containsKey(component)); + if (components != null) { + for (Class comp : components) { + stream = stream.filter(player -> player.components.containsKey(comp)); + } + } + return stream; + } + + @Delegate + @Getter + private final Player player; + private final Map, Component> components = new HashMap<>(); + + private SWPlayer(@NonNull Player player) { + this.player = player; + } + + public boolean hasComponent(@NonNull Class component) { + return components.containsKey(component); + } + + public @NonNull Optional getComponent(@NonNull Class clazz) { + return Optional.ofNullable((T) components.get(clazz)); + } + + public @NonNull T getComponentOrDefault(@NonNull Class clazz, @NonNull Supplier defaultValue) { + T value = (T) components.get(clazz); + if (value != null) return value; + value = defaultValue.get(); + setComponent(value); + return value; + } + + public SWPlayer setComponent(@NonNull T value) { + Component component = components.put(value.getClass(), value); + if (component != null) component.onUnmount(this); + value.onMount(this); + return this; + } + + public SWPlayer removeComponent(@NonNull Class clazz) { + Component component = components.remove(clazz); + if (component != null) component.onUnmount(this); + return this; + } + + private ThreadLocal messageThreadLocal = ThreadLocal.withInitial(() -> null); + + public SWPlayer using(Message message) { + this.messageThreadLocal.set(message); + return this; + } + + private Message getMessage() { + Message message = this.messageThreadLocal.get(); + if (message == null) throw new IllegalStateException("Use #using(Message) before sending or parsing a message!"); + return message; + } + + public void sendMessage(String message, Object... params) { + getMessage().send(message, player, ChatMessageType.SYSTEM, params); + } + + public void sendMessagePrefixless(String message, Object... params) { + getMessage().sendPrefixless(message, player, ChatMessageType.SYSTEM, params); + } + + public void sendActionBar(String message, Object... params) { + getMessage().sendPrefixless(message, player, ChatMessageType.ACTION_BAR, params); + } + + public void sendMessage(String message, String onHover, ClickEvent onClick, Object... params) { + getMessage().send(message, true, player, ChatMessageType.SYSTEM, onHover, onClick, params); + } + + public void sendMessagePrefixless(String message, String onHover, ClickEvent onClick, Object... params) { + getMessage().send(message, false, player, ChatMessageType.SYSTEM, onHover, onClick, params); + } + + public String parsePrefixed(String message, Object... params) { + return getMessage().parsePrefixed(message, player, params); + } + + public String parse(String message, Object... params) { + return getMessage().parse(message, player, params); + } +} From 941a1916b71c5f80fb782cbbf56b7838c15f67bd Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Fri, 7 Nov 2025 09:12:17 +0100 Subject: [PATCH 02/11] Improve Detonator --- .../features/detonator/Detonator.java | 43 +++++++++----- .../features/detonator/DetonatorListener.java | 56 ++++++++----------- .../src/de/steamwar/core/SWPlayer.java | 7 ++- 3 files changed, 58 insertions(+), 48 deletions(-) diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/detonator/Detonator.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/detonator/Detonator.java index 5ba2bca8..51d5e4e5 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/detonator/Detonator.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/detonator/Detonator.java @@ -25,8 +25,11 @@ import de.steamwar.bausystem.configplayer.Config; import de.steamwar.bausystem.features.autostart.AutostartListener; import de.steamwar.bausystem.features.detonator.storage.DetonatorStorage; import de.steamwar.bausystem.features.detonator.storage.ItemStorage; +import de.steamwar.core.SWPlayer; import de.steamwar.entity.REntityServer; import de.steamwar.entity.RFallingBlockEntity; +import lombok.Getter; +import lombok.Setter; import lombok.experimental.UtilityClass; import org.bukkit.Bukkit; import org.bukkit.Location; @@ -45,7 +48,28 @@ import java.util.*; @UtilityClass public class Detonator { - private static final Map ENTITIES_MAP = new HashMap<>(); + public class DetonatorComponent implements SWPlayer.Component { + private final REntityServer entities = new REntityServer(); + + @Getter + @Setter + private boolean hasUpdated = false; + + @Override + public void onMount(SWPlayer player) { + entities.addPlayer(player.getPlayer()); + entities.setCallback((player1, entity, action) -> { + Vector vector = new Vector(entity.getX(), entity.getY(), entity.getZ()); + DetonatorListener.addLocationToDetonator(vector.toLocation(player.getWorld()).getBlock().getLocation(), player1); + }); + } + + @Override + public void onUnmount(SWPlayer player) { + entities.close(); + } + } + private static final Vector HALF = new Vector(0.5, 0, 0.5); public static boolean isDetonator(ItemStack itemStack) { @@ -53,28 +77,19 @@ public class Detonator { } public static void showDetonator(Player p, List locs) { - if (ENTITIES_MAP.containsKey(p)) return; - REntityServer entities = new REntityServer(); - entities.setCallback((player, rEntity, entityAction) -> { - Vector vector = new Vector(rEntity.getX(), rEntity.getY(), rEntity.getZ()); - DetonatorListener.addLocationToDetonator(vector.toLocation(player.getWorld()).getBlock().getLocation(), player); - DetonatorListener.HAS_UPDATED.add(player); - }); - entities.addPlayer(p); - ENTITIES_MAP.put(p, entities); - + DetonatorComponent detonatorComponent = SWPlayer.of(p).getComponentOrDefault(DetonatorComponent.class, DetonatorComponent::new); locs.forEach(location -> { - RFallingBlockEntity entity = new RFallingBlockEntity(entities, location.clone().add(HALF), Material.RED_STAINED_GLASS); + RFallingBlockEntity entity = new RFallingBlockEntity(detonatorComponent.entities, location.clone().add(HALF), Material.RED_STAINED_GLASS); entity.setNoGravity(true); }); } public static void hideDetonator(Player p) { - ENTITIES_MAP.remove(p).close(); + SWPlayer.of(p).removeComponent(DetonatorComponent.class); } public static boolean hasActiveDetonatorShow(Player p) { - return ENTITIES_MAP.containsKey(p); + return SWPlayer.of(p).hasComponent(DetonatorComponent.class); } public static void activateDetonator(DetonatorStorage detonator) { diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/detonator/DetonatorListener.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/detonator/DetonatorListener.java index 9d70d11a..d8cd57e3 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/detonator/DetonatorListener.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/detonator/DetonatorListener.java @@ -24,6 +24,7 @@ import de.steamwar.bausystem.Permission; import de.steamwar.bausystem.SWUtils; import de.steamwar.bausystem.features.detonator.storage.DetonatorStorage; import de.steamwar.bausystem.features.detonator.storage.ItemStorage; +import de.steamwar.core.SWPlayer; import de.steamwar.linkage.Linked; import org.bukkit.Location; import org.bukkit.entity.Player; @@ -36,15 +37,11 @@ import org.bukkit.event.player.PlayerItemHeldEvent; import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.event.player.PlayerSwapHandItemsEvent; -import java.util.HashSet; -import java.util.Set; - @Linked public class DetonatorListener implements Listener { - static final Set HAS_UPDATED = new HashSet<>(); - static void addLocationToDetonator(Location location, Player p) { + SWPlayer.of(p).getComponent(Detonator.DetonatorComponent.class).ifPresent(detonatorComponent -> detonatorComponent.setHasUpdated(true)); Detoblock detoblock = Detonator.getBlock(location.getBlock()); if (detoblock == Detoblock.INVALID) { SWUtils.sendToActionbar(p, BauSystem.MESSAGE.parse("DETONATOR_INVALID_BLOCK", p)); @@ -66,64 +63,59 @@ public class DetonatorListener implements Listener { @EventHandler public void onBlockBreak(BlockBreakEvent event) { - if(!Permission.BUILD.hasPermission(event.getPlayer())) return; + if (!Permission.BUILD.hasPermission(event.getPlayer())) return; Player p = event.getPlayer(); if (Detonator.isDetonator(p.getInventory().getItemInMainHand())) { event.setCancelled(true); addLocationToDetonator(event.getBlock().getLocation(), p); - HAS_UPDATED.add(event.getPlayer()); } } @EventHandler public void onPlayerInteract(PlayerInteractEvent event) { - if(!Permission.BUILD.hasPermission(event.getPlayer())) return; - if (!Detonator.isDetonator(event.getItem())) { - return; - } + if (!Permission.BUILD.hasPermission(event.getPlayer())) return; + if (!Detonator.isDetonator(event.getItem())) return; if (event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK) { event.setCancelled(true); DetonatorStorage detonator = new ItemStorage(event.getPlayer()); Detonator.activateDetonator(detonator); - HAS_UPDATED.add(event.getPlayer()); + SWPlayer.of(event.getPlayer()).getComponent(Detonator.DetonatorComponent.class).ifPresent(detonatorComponent -> detonatorComponent.setHasUpdated(true)); } } @EventHandler(ignoreCancelled = true) public void onPlayerMove(PlayerMoveEvent event) { - if (!Permission.BUILD.hasPermission(event.getPlayer()) ||!Detonator.isDetonator(event.getPlayer().getInventory().getItemInMainHand())) { + if (!Permission.BUILD.hasPermission(event.getPlayer()) || !Detonator.isDetonator(event.getPlayer().getInventory().getItemInMainHand())) { if (Detonator.hasActiveDetonatorShow(event.getPlayer())) { Detonator.hideDetonator(event.getPlayer()); } - } else { - if (!Detonator.hasActiveDetonatorShow(event.getPlayer())) { - Detonator.showDetonator(event.getPlayer(), new ItemStorage(event.getPlayer()).getLocations()); - } + return; } - - if (HAS_UPDATED.contains(event.getPlayer())) { - HAS_UPDATED.remove(event.getPlayer()); - if (Detonator.hasActiveDetonatorShow(event.getPlayer())) { - Detonator.hideDetonator(event.getPlayer()); - Detonator.showDetonator(event.getPlayer(), new ItemStorage(event.getPlayer()).getLocations()); - } + if (!Detonator.hasActiveDetonatorShow(event.getPlayer())) { + Detonator.showDetonator(event.getPlayer(), new ItemStorage(event.getPlayer()).getLocations()); + return; } + Detonator.DetonatorComponent component = SWPlayer.of(event.getPlayer()) + .getComponentAndFilter(Detonator.DetonatorComponent.class, Detonator.DetonatorComponent::isHasUpdated) + .orElse(null); + if (component == null) return; + component.setHasUpdated(false); + Detonator.hideDetonator(event.getPlayer()); + Detonator.showDetonator(event.getPlayer(), new ItemStorage(event.getPlayer()).getLocations()); } @EventHandler public void onPlayerItemHeld(PlayerItemHeldEvent event) { - if(!Permission.BUILD.hasPermission(event.getPlayer())) return; - if (Detonator.isDetonator(event.getPlayer().getInventory().getItemInMainHand())) { - HAS_UPDATED.add(event.getPlayer()); - } + if (!Permission.BUILD.hasPermission(event.getPlayer())) return; + if (!Detonator.isDetonator(event.getPlayer().getInventory().getItemInMainHand())) return; + SWPlayer.of(event.getPlayer()).getComponent(Detonator.DetonatorComponent.class).ifPresent(detonatorComponent -> detonatorComponent.setHasUpdated(true)); } @EventHandler public void onPlayerSwapHandItems(PlayerSwapHandItemsEvent event) { - if(!Permission.BUILD.hasPermission(event.getPlayer())) return; - if (Detonator.isDetonator(event.getMainHandItem()) || Detonator.isDetonator(event.getOffHandItem())) { - HAS_UPDATED.add(event.getPlayer()); - } + if (!Permission.BUILD.hasPermission(event.getPlayer())) return; + if (!(Detonator.isDetonator(event.getMainHandItem()) || Detonator.isDetonator(event.getOffHandItem()))) return; + SWPlayer.of(event.getPlayer()).getComponent(Detonator.DetonatorComponent.class).ifPresent(detonatorComponent -> detonatorComponent.setHasUpdated(true)); } } diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/core/SWPlayer.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/core/SWPlayer.java index 12a2aa0c..a911fbfd 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/core/SWPlayer.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/core/SWPlayer.java @@ -20,7 +20,6 @@ package de.steamwar.core; import de.steamwar.message.Message; -import lombok.Getter; import lombok.NonNull; import lombok.experimental.Delegate; import net.md_5.bungee.api.ChatMessageType; @@ -36,6 +35,7 @@ import org.bukkit.event.player.PlayerQuitEvent; import java.util.HashMap; import java.util.Map; import java.util.Optional; +import java.util.function.Predicate; import java.util.function.Supplier; import java.util.stream.Stream; @@ -103,7 +103,6 @@ public class SWPlayer { } @Delegate - @Getter private final Player player; private final Map, Component> components = new HashMap<>(); @@ -119,6 +118,10 @@ public class SWPlayer { return Optional.ofNullable((T) components.get(clazz)); } + public @NonNull Optional getComponentAndFilter(@NonNull Class clazz, Predicate filter) { + return Optional.ofNullable((T) components.get(clazz)).filter(filter); + } + public @NonNull T getComponentOrDefault(@NonNull Class clazz, @NonNull Supplier defaultValue) { T value = (T) components.get(clazz); if (value != null) return value; From 1ccc2c4b5546609d05c080fd1c743d39ddd10ef3 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Fri, 7 Nov 2025 09:25:40 +0100 Subject: [PATCH 03/11] Improve Loader Improve ObserverTracer --- .../bausystem/features/loader/Loader.java | 13 +++----- .../features/observer/ObserverTracer.java | 3 +- .../observer/ObserverTracerCommand.java | 9 +++--- .../observer/ObserverTracerListener.java | 32 +++++++------------ .../src/de/steamwar/core/SWPlayer.java | 15 +++------ 5 files changed, 29 insertions(+), 43 deletions(-) diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/loader/Loader.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/loader/Loader.java index 491f45aa..4f990052 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/loader/Loader.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/loader/Loader.java @@ -26,6 +26,7 @@ import de.steamwar.bausystem.features.loader.elements.LoaderInteractionElement; import de.steamwar.bausystem.features.loader.elements.impl.LoaderTNT; import de.steamwar.bausystem.features.loader.elements.impl.LoaderWait; import de.steamwar.bausystem.shared.EnumDisplay; +import de.steamwar.core.SWPlayer; import de.steamwar.inventory.SWAnvilInv; import de.steamwar.inventory.SWItem; import de.steamwar.inventory.SWListInv; @@ -40,21 +41,17 @@ import org.bukkit.event.inventory.ClickType; import org.bukkit.event.player.PlayerQuitEvent; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; -public class Loader implements Listener { - - private static final Map LOADER_MAP = new HashMap<>(); +public class Loader implements Listener, SWPlayer.Component { public static Loader getLoader(Player player) { - return LOADER_MAP.get(player); + return SWPlayer.of(player).getComponent(Loader.class).orElse(null); } public static void newLoader(Player player) { - LOADER_MAP.put(player, new Loader(player)); + SWPlayer.of(player).setComponent(new Loader(player)); } private final Player p; @@ -145,7 +142,7 @@ public class Loader implements Listener { recorder = null; } elements.clear(); - LOADER_MAP.remove(p); + SWPlayer.of(p).removeComponent(Loader.class); } public boolean setTicksBetweenShots(int delay) { diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/observer/ObserverTracer.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/observer/ObserverTracer.java index ad0bca1b..6dad9e00 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/observer/ObserverTracer.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/observer/ObserverTracer.java @@ -21,6 +21,7 @@ package de.steamwar.bausystem.features.observer; import de.steamwar.Reflection; import de.steamwar.bausystem.region.Point; +import de.steamwar.core.SWPlayer; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.Particle; @@ -34,7 +35,7 @@ import org.bukkit.entity.Player; import java.util.*; -public class ObserverTracer { +public class ObserverTracer implements SWPlayer.Component { private static final Set ALLOWED = EnumSet.of(BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, BlockFace.WEST, BlockFace.UP, BlockFace.DOWN); diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/observer/ObserverTracerCommand.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/observer/ObserverTracerCommand.java index 7cfadf2c..e88e4ca0 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/observer/ObserverTracerCommand.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/observer/ObserverTracerCommand.java @@ -21,6 +21,7 @@ package de.steamwar.bausystem.features.observer; import de.steamwar.bausystem.BauSystem; import de.steamwar.command.SWCommand; +import de.steamwar.core.SWPlayer; import de.steamwar.linkage.Linked; import org.bukkit.entity.Player; @@ -41,23 +42,23 @@ public class ObserverTracerCommand extends SWCommand { @Register(value = "disable", description = "OBSERVER_HELP_DISABLE") public void disable(Player p) { ObserverTracerListener.enabled.remove(p); - ObserverTracerListener.observerTracerMap.remove(p); + SWPlayer.of(p).removeComponent(ObserverTracer.class); BauSystem.MESSAGE.send("OBSERVER_DISABLE", p); } @Register(value = "delete", description = "OBSERVER_HELP_DELETE") public void delete(@Validator Player p) { - ObserverTracerListener.observerTracerMap.remove(p); + SWPlayer.of(p).removeComponent(ObserverTracer.class); BauSystem.MESSAGE.send("OBSERVER_DELETE", p); } @Register(value = "retrace", description = "OBSERVER_HELP_RETRACE") public void retrace(@Validator Player p) { - if (ObserverTracerListener.observerTracerMap.containsKey(p)) { + if (SWPlayer.of(p).hasComponent(ObserverTracer.class)) { BauSystem.MESSAGE.send("OBSERVER_RETRACE_NO_TRACE", p); return; } - ObserverTracerListener.observerTracerMap.get(p).trace(); + SWPlayer.of(p).getComponent(ObserverTracer.class).ifPresent(ObserverTracer::trace); BauSystem.MESSAGE.send("OBSERVER_RETRACE_DONE", p); } } diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/observer/ObserverTracerListener.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/observer/ObserverTracerListener.java index 9ef56909..0528527e 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/observer/ObserverTracerListener.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/observer/ObserverTracerListener.java @@ -22,6 +22,7 @@ package de.steamwar.bausystem.features.observer; import de.steamwar.bausystem.BauSystem; import de.steamwar.bausystem.Permission; import de.steamwar.bausystem.utils.BauMemberUpdateEvent; +import de.steamwar.core.SWPlayer; import de.steamwar.linkage.Linked; import org.bukkit.Bukkit; import org.bukkit.GameMode; @@ -34,23 +35,19 @@ import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerQuitEvent; -import java.util.HashMap; import java.util.HashSet; -import java.util.Map; import java.util.Set; @Linked public class ObserverTracerListener implements Listener { static Set enabled = new HashSet<>(); - static Map observerTracerMap = new HashMap<>(); public ObserverTracerListener() { Bukkit.getScheduler().runTaskTimer(BauSystem.getInstance(), () -> { - observerTracerMap.forEach((player, observerTracer) -> { - if (player.getGameMode() == GameMode.SPECTATOR) { - observerTracer.show(); - } + SWPlayer.allWithSingleComponent(ObserverTracer.class).forEach(pair -> { + if (pair.getKey().getGameMode() != GameMode.SPECTATOR) return; + pair.getValue().show(); }); }, 15L, 15L); } @@ -58,20 +55,16 @@ public class ObserverTracerListener implements Listener { @EventHandler public void onPlayerInteract(PlayerInteractEvent event) { if(!Permission.BUILD.hasPermission(event.getPlayer())) return; - if (!enabled.contains(event.getPlayer())) { - return; - } - if (event.getClickedBlock() == null) { - return; - } - if (observerTracerMap.containsKey(event.getPlayer())) { - ObserverTracer observerTracer = observerTracerMap.get(event.getPlayer()); + if (!enabled.contains(event.getPlayer())) return; + if (event.getClickedBlock() == null) return; + ObserverTracer observerTracer = SWPlayer.of(event.getPlayer()).getComponent(ObserverTracer.class).orElse(null); + if (observerTracer != null) { Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> { if (!observerTracer.trace()) { createNew(event); } - observerTracerMap.forEach((player, o) -> { - o.trace(); + SWPlayer.allWithSingleComponent(ObserverTracer.class).forEach(pair -> { + pair.getValue().trace(); }); }, 1L); } else { @@ -86,13 +79,13 @@ public class ObserverTracerListener implements Listener { if (event.getClickedBlock().getType() == Material.OBSERVER) { ObserverTracer observerTracer = new ObserverTracer(event.getPlayer(), event.getClickedBlock()); observerTracer.trace(); - observerTracerMap.put(event.getPlayer(), observerTracer); + SWPlayer.of(event.getPlayer()).setComponent(observerTracer); } } @EventHandler public void onBauMemberUpdate(BauMemberUpdateEvent event) { - event.getNewSpectator().forEach(observerTracerMap::remove); + event.getNewBuilder().forEach(player -> SWPlayer.of(player).removeComponent(ObserverTracer.class)); } @EventHandler @@ -103,6 +96,5 @@ public class ObserverTracerListener implements Listener { @EventHandler public void onPlayerQuit(PlayerQuitEvent event) { enabled.remove(event.getPlayer()); - observerTracerMap.remove(event.getPlayer()); } } diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/core/SWPlayer.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/core/SWPlayer.java index a911fbfd..ffe98933 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/core/SWPlayer.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/core/SWPlayer.java @@ -24,6 +24,7 @@ import lombok.NonNull; import lombok.experimental.Delegate; import net.md_5.bungee.api.ChatMessageType; import net.md_5.bungee.api.chat.ClickEvent; +import org.apache.commons.lang3.tuple.Pair; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -90,16 +91,10 @@ public class SWPlayer { return players.values().stream(); } - @SafeVarargs - public static @NonNull Stream allWithComponent(Class component, Class... components) { - Stream stream = players.values().stream() - .filter(player -> player.components.containsKey(component)); - if (components != null) { - for (Class comp : components) { - stream = stream.filter(player -> player.components.containsKey(comp)); - } - } - return stream; + public static @NonNull Stream> allWithSingleComponent(Class component) { + return players.values().stream() + .filter(player -> player.components.containsKey(component)) + .map(player -> Pair.of(player, (T) player.components.get(component))); } @Delegate From 51411ceabed3c99085850792f0f99a0921785789 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Fri, 7 Nov 2025 09:34:28 +0100 Subject: [PATCH 04/11] Improve ScriptRunner --- .../features/script/ScriptRunner.java | 39 ++++++++++++------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/ScriptRunner.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/ScriptRunner.java index 2a506e12..3bcb1f71 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/ScriptRunner.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/ScriptRunner.java @@ -23,6 +23,7 @@ import de.steamwar.bausystem.BauSystem; import de.steamwar.bausystem.features.script.lua.CommandRegister; import de.steamwar.bausystem.features.script.lua.SteamWarGlobalLuaPlugin; import de.steamwar.bausystem.features.script.lua.SteamWarPlatform; +import de.steamwar.core.SWPlayer; import de.steamwar.sql.Script; import de.steamwar.sql.SteamwarUser; import lombok.experimental.UtilityClass; @@ -44,12 +45,14 @@ public class ScriptRunner { // Key -> bau-script- // Value -> - private static final Map>> EVENT_MAP = new HashMap<>(); - private static final Map>> HOTKEY_MAP = new HashMap<>(); - private static final Map> COMMAND_MAP = new HashMap<>(); + public class ScriptData implements SWPlayer.Component { + private Map> events = new EnumMap<>(SteamWarGlobalLuaPlugin.EventType.class); + private Map> hotkeys = new HashMap<>(); + private Map commands = new HashMap<>(); + } public Set getCommandsOfPlayer(Player player) { - return COMMAND_MAP.getOrDefault(player, new HashMap<>()).keySet(); + return SWPlayer.of(player).getComponentOrDefault(ScriptData.class, ScriptData::new).commands.keySet(); } public static void runScript(String script, Player player) { @@ -64,10 +67,12 @@ public class ScriptRunner { public static void createGlobalScript(List scripts, Player player) { remove(player); + SWPlayer swPlayer = SWPlayer.of(player); + ScriptData scriptData = swPlayer.getComponentOrDefault(ScriptData.class, ScriptData::new); Globals globals = SteamWarPlatform.createGlobalGlobals(player, - (s, luaFunction) -> EVENT_MAP.computeIfAbsent(player, player1 -> new EnumMap<>(SteamWarGlobalLuaPlugin.EventType.class)).computeIfAbsent(s, s1 -> new ArrayList<>()).add(luaFunction), - (s, luaFunction) -> HOTKEY_MAP.computeIfAbsent(player, player1 -> new HashMap<>()).computeIfAbsent(Hotkey.fromString(s), s1 -> new ArrayList<>()).add(luaFunction), - commandRegister -> COMMAND_MAP.computeIfAbsent(player, player1 -> new HashMap<>()).put(commandRegister.getName(), commandRegister)); + (s, luaFunction) -> scriptData.events.computeIfAbsent(s, s1 -> new ArrayList<>()).add(luaFunction), + (s, luaFunction) -> scriptData.hotkeys.computeIfAbsent(Hotkey.fromString(s), s1 -> new ArrayList<>()).add(luaFunction), + commandRegister -> scriptData.commands.put(commandRegister.getName(), commandRegister)); for (String script : scripts) { catchScript("SCRIPT_ERROR_GLOBAL", player, () -> globals.load(script).call()); @@ -75,13 +80,14 @@ public class ScriptRunner { } public static void remove(Player player) { - EVENT_MAP.remove(player); - COMMAND_MAP.remove(player); - HOTKEY_MAP.remove(player); + SWPlayer.of(player).removeComponent(ScriptData.class); } public static void callEvent(Player player, SteamWarGlobalLuaPlugin.EventType event, LuaValue eventValue, Event wrappedEvent) { - List luaFunctions = EVENT_MAP.getOrDefault(player, Collections.emptyMap()).getOrDefault(event, Collections.emptyList()); + List luaFunctions = SWPlayer.of(player).getComponent(ScriptData.class) + .map(scriptData -> scriptData.events) + .orElse(Collections.emptyMap()) + .getOrDefault(event, Collections.emptyList()); if (luaFunctions.isEmpty()) { if(event == SteamWarGlobalLuaPlugin.EventType.DoubleSwap) { player.performCommand("gui"); @@ -124,7 +130,10 @@ public class ScriptRunner { } public static boolean callCommand(Player player, String command, String[] argsArray) { - CommandRegister commandRegister = COMMAND_MAP.getOrDefault(player, Collections.emptyMap()).get(command); + CommandRegister commandRegister = SWPlayer.of(player).getComponent(ScriptData.class) + .map(scriptData -> scriptData.commands) + .orElse(Collections.emptyMap()) + .get(command); if (commandRegister == null) { return false; } @@ -188,7 +197,11 @@ public class ScriptRunner { public static void callHotkey(int mods, int key, Player player, boolean pressed) { Hotkey hotkey = Hotkey.fromChar(key, mods); - catchScript("SCRIPT_ERROR_GLOBAL", player, () -> HOTKEY_MAP.getOrDefault(player, Collections.emptyMap()).getOrDefault(hotkey, Collections.emptyList()).forEach(luaFunction -> luaFunction.call(LuaValue.valueOf(pressed)))); + List hotkeys = SWPlayer.of(player).getComponent(ScriptData.class) + .map(scriptData -> scriptData.hotkeys) + .orElse(Collections.emptyMap()) + .getOrDefault(hotkey, Collections.emptyList()); + catchScript("SCRIPT_ERROR_GLOBAL", player, () -> hotkeys.forEach(luaFunction -> luaFunction.call(LuaValue.valueOf(pressed)))); } public static void catchScript(String errorMsg, Player player, Runnable run) { From 26b4d8578a00b762c9cb52aaf5f8b998f238c7fa Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Fri, 7 Nov 2025 09:43:11 +0100 Subject: [PATCH 05/11] Improve ScriptRunner --- .../features/script/ScriptListener.java | 2 +- .../features/script/ScriptRunner.java | 13 +++++ .../script/event/CommandListener.java | 30 ++---------- .../features/script/event/EventListener.java | 48 +++++++++---------- 4 files changed, 42 insertions(+), 51 deletions(-) diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/ScriptListener.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/ScriptListener.java index 0eadc3ed..2f444561 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/ScriptListener.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/ScriptListener.java @@ -67,7 +67,7 @@ public class ScriptListener implements Listener { @EventHandler public void onPlayerQuit(PlayerQuitEvent event) { - ScriptRunner.remove(event.getPlayer()); + playerSet.remove(event.getPlayer()); } @EventHandler diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/ScriptRunner.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/ScriptRunner.java index 3bcb1f71..ee10536e 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/ScriptRunner.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/ScriptRunner.java @@ -26,6 +26,8 @@ import de.steamwar.bausystem.features.script.lua.SteamWarPlatform; import de.steamwar.core.SWPlayer; import de.steamwar.sql.Script; import de.steamwar.sql.SteamwarUser; +import lombok.Getter; +import lombok.Setter; import lombok.experimental.UtilityClass; import org.bukkit.entity.Player; import org.bukkit.event.Cancellable; @@ -49,6 +51,17 @@ public class ScriptRunner { private Map> events = new EnumMap<>(SteamWarGlobalLuaPlugin.EventType.class); private Map> hotkeys = new HashMap<>(); private Map commands = new HashMap<>(); + + @Getter + private Set calledCommands = new HashSet<>(); + + @Getter + @Setter + private Long lastF = Long.MAX_VALUE; + + @Getter + @Setter + private boolean ignore; } public Set getCommandsOfPlayer(Player player) { diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/event/CommandListener.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/event/CommandListener.java index d52e4d9b..f79d4ac3 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/event/CommandListener.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/event/CommandListener.java @@ -21,44 +21,24 @@ package de.steamwar.bausystem.features.script.event; import de.steamwar.bausystem.Permission; import de.steamwar.bausystem.features.script.ScriptRunner; +import de.steamwar.core.SWPlayer; import de.steamwar.linkage.Linked; -import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerCommandPreprocessEvent; -import org.bukkit.event.player.PlayerJoinEvent; -import org.bukkit.event.player.PlayerQuitEvent; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; @Linked public class CommandListener implements Listener { - private Map> calledCommands = new HashMap<>(); - @EventHandler public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) { if(!Permission.BUILD.hasPermission(event.getPlayer())) return; String[] split = event.getMessage().split(" "); - if (calledCommands.getOrDefault(event.getPlayer(), new HashSet<>()).contains(split[0])) { - return; - } + ScriptRunner.ScriptData scriptData = SWPlayer.of(event.getPlayer()).getComponentOrDefault(ScriptRunner.ScriptData.class, ScriptRunner.ScriptData::new); + if (scriptData.getCalledCommands().contains(split[0])) return; - calledCommands.getOrDefault(event.getPlayer(), new HashSet<>()).add(split[0]); + scriptData.getCalledCommands().add(split[0]); event.setCancelled(ScriptRunner.callCommand(event.getPlayer(), split[0].substring(1), split)); - calledCommands.getOrDefault(event.getPlayer(), new HashSet<>()).remove(split[0]); - } - - @EventHandler - public void onPlayerJoin(PlayerJoinEvent event) { - calledCommands.put(event.getPlayer(), new HashSet<>()); - } - - @EventHandler - public void onPlayerQuit(PlayerQuitEvent event) { - calledCommands.remove(event.getPlayer()); + scriptData.getCalledCommands().remove(split[0]); } } diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/event/EventListener.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/event/EventListener.java index 8aade642..3490ea2e 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/event/EventListener.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/event/EventListener.java @@ -25,6 +25,7 @@ import de.steamwar.bausystem.features.script.ScriptRunner; import de.steamwar.bausystem.features.script.lua.SteamWarGlobalLuaPlugin; import de.steamwar.bausystem.features.script.lua.libs.StorageLib; import de.steamwar.bausystem.region.Region; +import de.steamwar.core.SWPlayer; import de.steamwar.core.TrickyTrialsWrapper; import de.steamwar.linkage.Linked; import org.bukkit.Bukkit; @@ -43,32 +44,27 @@ import org.bukkit.event.player.*; import org.luaj.vm2.LuaTable; import org.luaj.vm2.LuaValue; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - @Linked public class EventListener implements Listener { - private static final Map LAST_FS = new HashMap<>(); - static { Bukkit.getScheduler().runTaskTimer(BauSystem.getInstance(), () -> { long millis = System.currentTimeMillis(); - LAST_FS.entrySet().removeIf(entry -> millis - entry.getValue() > 200); + SWPlayer.allWithSingleComponent(ScriptRunner.ScriptData.class) + .filter(pair -> millis - pair.getValue().getLastF() > 200) + .forEach(pair -> pair.getValue().setLastF(Long.MAX_VALUE)); }, 1, 1); } @EventHandler(priority = EventPriority.MONITOR) public void onPlayerJoin(PlayerJoinEvent event) { - if(!Permission.BUILD.hasPermission(event.getPlayer())) return; + if (!Permission.BUILD.hasPermission(event.getPlayer())) return; ScriptRunner.callEvent(event.getPlayer(), SteamWarGlobalLuaPlugin.EventType.SelfJoin, LuaValue.NIL, event); } @EventHandler(priority = EventPriority.HIGH) public void onPlayerQuit(PlayerQuitEvent event) { - if(Permission.BUILD.hasPermission(event.getPlayer())) { + if (Permission.BUILD.hasPermission(event.getPlayer())) { ScriptRunner.callEvent(event.getPlayer(), SteamWarGlobalLuaPlugin.EventType.SelfLeave, LuaValue.NIL, event); } StorageLib.removePlayer(event.getPlayer()); @@ -76,19 +72,20 @@ public class EventListener implements Listener { @EventHandler(priority = EventPriority.HIGH) public void onPlayerSwapHandItems(PlayerSwapHandItemsEvent event) { - if(!Permission.BUILD.hasPermission(event.getPlayer())) return; - if (LAST_FS.containsKey(event.getPlayer())) { + if (!Permission.BUILD.hasPermission(event.getPlayer())) return; + ScriptRunner.ScriptData scriptData = SWPlayer.of(event.getPlayer()).getComponentOrDefault(ScriptRunner.ScriptData.class, ScriptRunner.ScriptData::new); + if (scriptData.getLastF() != Long.MAX_VALUE) { Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> { ScriptRunner.callEvent(event.getPlayer(), SteamWarGlobalLuaPlugin.EventType.DoubleSwap, LuaValue.NIL, event); }, 1); } else { - LAST_FS.put(event.getPlayer(), System.currentTimeMillis()); + scriptData.setLastF(System.currentTimeMillis()); } } @EventHandler(priority = EventPriority.HIGH) public void onBlockPlace(BlockPlaceEvent event) { - if(!Permission.BUILD.hasPermission(event.getPlayer())) return; + if (!Permission.BUILD.hasPermission(event.getPlayer())) return; LuaTable table = new LuaTable(); table.set("x", event.getBlock().getX()); table.set("y", event.getBlock().getY()); @@ -99,7 +96,7 @@ public class EventListener implements Listener { @EventHandler(priority = EventPriority.HIGH) public void onBlockBreak(BlockBreakEvent event) { - if(!Permission.BUILD.hasPermission(event.getPlayer())) return; + if (!Permission.BUILD.hasPermission(event.getPlayer())) return; LuaTable table = new LuaTable(); table.set("x", event.getBlock().getX()); table.set("y", event.getBlock().getY()); @@ -108,12 +105,12 @@ public class EventListener implements Listener { ScriptRunner.callEvent(event.getPlayer(), SteamWarGlobalLuaPlugin.EventType.BreakBlock, table, event); } - private final Set ignore = new HashSet<>(); - @EventHandler(priority = EventPriority.LOW) public void onPlayerInteract(PlayerInteractEvent event) { - if(!Permission.BUILD.hasPermission(event.getPlayer())) return; - if (ignore.remove(event.getPlayer())) { + if (!Permission.BUILD.hasPermission(event.getPlayer())) return; + ScriptRunner.ScriptData scriptData = SWPlayer.of(event.getPlayer()).getComponentOrDefault(ScriptRunner.ScriptData.class, ScriptRunner.ScriptData::new); + if (scriptData.isIgnore()) { + scriptData.setIgnore(false); return; } LuaTable table = new LuaTable(); @@ -124,7 +121,7 @@ public class EventListener implements Listener { table.set("hand", event.getHand().name()); } table.set("block", event.getItem() == null ? Material.AIR.name() : event.getItem().getType().name()); - if(event.getAction() == Action.RIGHT_CLICK_BLOCK || event.getAction() == Action.LEFT_CLICK_BLOCK) { + if (event.getAction() == Action.RIGHT_CLICK_BLOCK || event.getAction() == Action.LEFT_CLICK_BLOCK) { table.set("hasBlock", LuaValue.valueOf(true)); table.set("blockX", event.getClickedBlock().getX()); table.set("blockY", event.getClickedBlock().getY()); @@ -150,7 +147,7 @@ public class EventListener implements Listener { Region tntRegion = Region.getRegion(event.getLocation()); for (Player player : Bukkit.getOnlinePlayers()) { - if(!Permission.BUILD.hasPermission(player)) continue; + if (!Permission.BUILD.hasPermission(player)) continue; if (tntRegion.getArea().inRegion(player.getLocation(), false)) { ScriptRunner.callEvent(player, SteamWarGlobalLuaPlugin.EventType.TNTSpawn, LuaValue.NIL, event); } @@ -172,7 +169,7 @@ public class EventListener implements Listener { boolean inBuild = event.blockList().stream().anyMatch(block -> tntRegion.getBuildArea().inRegion(block.getLocation(), true)); for (Player player : Bukkit.getOnlinePlayers()) { - if(!Permission.BUILD.hasPermission(player)) continue; + if (!Permission.BUILD.hasPermission(player)) continue; if (tntRegion.getArea().inRegion(player.getLocation(), false)) { ScriptRunner.callEvent(player, SteamWarGlobalLuaPlugin.EventType.TNTExplode, table, event); if (inBuild) { @@ -184,8 +181,9 @@ public class EventListener implements Listener { @EventHandler(priority = EventPriority.HIGH) public void onPlayerDropItem(PlayerDropItemEvent event) { - if(!Permission.BUILD.hasPermission(event.getPlayer())) return; - ignore.add(event.getPlayer()); + if (!Permission.BUILD.hasPermission(event.getPlayer())) return; + ScriptRunner.ScriptData scriptData = SWPlayer.of(event.getPlayer()).getComponentOrDefault(ScriptRunner.ScriptData.class, ScriptRunner.ScriptData::new); + scriptData.setIgnore(true); LuaTable table = new LuaTable(); table.set("type", event.getItemDrop().getItemStack().getType().name()); ScriptRunner.callEvent(event.getPlayer(), SteamWarGlobalLuaPlugin.EventType.DropItem, table, event); @@ -194,7 +192,7 @@ public class EventListener implements Listener { @EventHandler(priority = EventPriority.HIGH) public void onEntityDeath(EntityDeathEvent event) { for (Player player : Bukkit.getOnlinePlayers()) { - if(!Permission.BUILD.hasPermission(player)) continue; + if (!Permission.BUILD.hasPermission(player)) continue; LuaTable table = new LuaTable(); table.set("type", event.getEntityType().name()); ScriptRunner.callEvent(player, SteamWarGlobalLuaPlugin.EventType.EntityDeath, table, event); From ceb8d2c6d4e64dcd0cd14c442d1fc3f090118736 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Fri, 7 Nov 2025 14:21:05 +0100 Subject: [PATCH 06/11] Improve LaufbauUtils --- .../features/slaves/laufbau/LaufbauUtils.java | 71 ++++++++----------- 1 file changed, 31 insertions(+), 40 deletions(-) diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/LaufbauUtils.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/LaufbauUtils.java index 4eb6c382..926618d0 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/LaufbauUtils.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/LaufbauUtils.java @@ -20,6 +20,7 @@ package de.steamwar.bausystem.features.slaves.laufbau; import de.steamwar.bausystem.BauSystem; +import de.steamwar.core.SWPlayer; import de.steamwar.inventory.SWItem; import de.steamwar.linkage.Linked; import de.steamwar.sql.UserConfig; @@ -27,10 +28,7 @@ import lombok.Cleanup; import lombok.SneakyThrows; import org.bukkit.Material; import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerJoinEvent; -import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.inventory.meta.ItemMeta; import yapion.hierarchy.output.StreamOutput; import yapion.hierarchy.types.YAPIONObject; @@ -39,7 +37,10 @@ import yapion.parser.options.StreamOptions; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Base64; +import java.util.List; import java.util.stream.Collectors; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; @@ -47,36 +48,34 @@ import java.util.zip.GZIPOutputStream; @Linked public class LaufbauUtils implements Listener { - private static Map yapionObjectMap = new HashMap<>(); + public static class LaufbauComponent implements SWPlayer.Component { - @EventHandler - @SneakyThrows - public void onPlayerJoin(PlayerJoinEvent event) { - String config = UserConfig.getConfig(event.getPlayer().getUniqueId(), "bausystem-laufbau"); - if (config == null) { - return; - } - byte[] bytes = Base64.getDecoder().decode(config); - @Cleanup GZIPInputStream gzipInputStream = new GZIPInputStream(new ByteArrayInputStream(bytes)); - YAPIONObject yapionObject = new YAPIONParser(gzipInputStream, new StreamOptions().stopOnStreamEnd(true)).parse().result(); - yapionObjectMap.put(event.getPlayer(), yapionObject); - } + private YAPIONObject yapionObject = new YAPIONObject(); - @EventHandler - @SneakyThrows - public void onPlayerQuit(PlayerQuitEvent event) { - YAPIONObject yapionObject = yapionObjectMap.get(event.getPlayer()); - if (yapionObject == null) { - return; + @Override + @SneakyThrows + public void onMount(SWPlayer player) { + String config = UserConfig.getConfig(player.getPlayer().getUniqueId(), "bausystem-laufbau"); + if (config == null) { + return; + } + byte[] bytes = Base64.getDecoder().decode(config); + @Cleanup GZIPInputStream gzipInputStream = new GZIPInputStream(new ByteArrayInputStream(bytes)); + yapionObject = new YAPIONParser(gzipInputStream, new StreamOptions().stopOnStreamEnd(true)).parse().result(); } - if (yapionObject.isEmpty()) { - UserConfig.removePlayerConfig(event.getPlayer().getUniqueId(), "bausystem-laufbau"); - return; + + @Override + @SneakyThrows + public void onUnmount(SWPlayer player) { + if (yapionObject.isEmpty()) { + UserConfig.removePlayerConfig(player.getPlayer().getUniqueId(), "bausystem-laufbau"); + return; + } + @Cleanup ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + @Cleanup GZIPOutputStream gzipOutputStream = new GZIPOutputStream(byteArrayOutputStream); + yapionObject.toYAPION(new StreamOutput(gzipOutputStream)).close(); + UserConfig.updatePlayerConfig(player.getPlayer().getUniqueId(), "bausystem-laufbau", Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray())); } - @Cleanup ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); - @Cleanup GZIPOutputStream gzipOutputStream = new GZIPOutputStream(byteArrayOutputStream); - yapionObject.toYAPION(new StreamOutput(gzipOutputStream)).close(); - UserConfig.updatePlayerConfig(event.getPlayer().getUniqueId(), "bausystem-laufbau", Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray())); } public static Cuboid pixelCuboid(double pixelX, double pixelY, double pixelZ, double pixelDX, double pixelDY, double pixelDZ) { @@ -125,11 +124,7 @@ public class LaufbauUtils implements Listener { return false; } String identifier = identifier(bb); - YAPIONObject yapionObject = yapionObjectMap.get(p); - if (yapionObject == null) { - return false; - } - return yapionObject.containsKey(identifier); + return SWPlayer.of(p).getComponentOrDefault(LaufbauComponent.class, LaufbauComponent::new).yapionObject.containsKey(identifier); } @SneakyThrows @@ -138,11 +133,7 @@ public class LaufbauUtils implements Listener { return; } String identifier = identifier(bb); - YAPIONObject yapionObject = yapionObjectMap.get(p); - if (yapionObject == null) { - yapionObject = new YAPIONObject(); - yapionObjectMap.put(p, yapionObject); - } + YAPIONObject yapionObject = SWPlayer.of(p).getComponentOrDefault(LaufbauComponent.class, LaufbauComponent::new).yapionObject; if (yapionObject.containsKey(identifier)) { yapionObject.remove(identifier); } else { From b69adcd36282d6464c12e6f782a718d5651adcde Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Fri, 7 Nov 2025 14:34:30 +0100 Subject: [PATCH 07/11] Improve MaterialCommand --- .../features/slaves/laufbau/LaufbauUtils.java | 7 +- .../features/util/MaterialCommand.java | 85 ++++++++----------- .../features/util/MaterialLazyInit.java | 2 +- 3 files changed, 41 insertions(+), 53 deletions(-) diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/LaufbauUtils.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/LaufbauUtils.java index 926618d0..a642c22d 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/LaufbauUtils.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/LaufbauUtils.java @@ -22,13 +22,12 @@ package de.steamwar.bausystem.features.slaves.laufbau; import de.steamwar.bausystem.BauSystem; import de.steamwar.core.SWPlayer; import de.steamwar.inventory.SWItem; -import de.steamwar.linkage.Linked; import de.steamwar.sql.UserConfig; import lombok.Cleanup; import lombok.SneakyThrows; +import lombok.experimental.UtilityClass; import org.bukkit.Material; import org.bukkit.entity.Player; -import org.bukkit.event.Listener; import org.bukkit.inventory.meta.ItemMeta; import yapion.hierarchy.output.StreamOutput; import yapion.hierarchy.types.YAPIONObject; @@ -45,8 +44,8 @@ import java.util.stream.Collectors; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; -@Linked -public class LaufbauUtils implements Listener { +@UtilityClass +public class LaufbauUtils { public static class LaufbauComponent implements SWPlayer.Component { diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/util/MaterialCommand.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/util/MaterialCommand.java index 69b53897..52a588f9 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/util/MaterialCommand.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/util/MaterialCommand.java @@ -26,6 +26,7 @@ import de.steamwar.bausystem.shared.EnumDisplay; import de.steamwar.command.PreviousArguments; import de.steamwar.command.SWCommand; import de.steamwar.command.TypeMapper; +import de.steamwar.core.SWPlayer; import de.steamwar.data.CMDs; import de.steamwar.inventory.SWAnvilInv; import de.steamwar.inventory.SWInventory; @@ -56,11 +57,9 @@ public class MaterialCommand extends SWCommand implements Listener { WorldEditListener.addCommandExclusion("material"); } - private Map searchMap = new HashMap<>(); - @Getter @Setter - static class Search { + public class SearchParameter implements SWPlayer.Component { SearchType transparent = SearchType.IGNORE; SearchType solid = SearchType.IGNORE; SearchType gravity = SearchType.IGNORE; @@ -104,10 +103,10 @@ public class MaterialCommand extends SWCommand implements Listener { @Register public void materialGUI(Player p) { - materialGUI(p, searchMap.get(p)); + materialGUI(p, SWPlayer.of(p).getComponentOrDefault(SearchParameter.class, SearchParameter::new)); } - private static final Map> elements = new HashMap<>(); + private static final Map> elements = new HashMap<>(); static { elements.put("-transparent", (search, searchType) -> search.transparent = searchType); elements.put("-solid", (search, searchType) -> search.solid = searchType); @@ -122,15 +121,15 @@ public class MaterialCommand extends SWCommand implements Listener { @Register public void search(Player p, @Mapper("search") String... searches) { - Search search = new Search(); + SearchParameter searchParameter = SWPlayer.of(p).getComponentOrDefault(SearchParameter.class, SearchParameter::new); for (String s : searches) { boolean has = false; - for (Map.Entry> element: elements.entrySet()) { + for (Map.Entry> element: elements.entrySet()) { if (s.startsWith(element.getKey() + ":")) { - element.getValue().accept(search, SearchType.valueOf(s.substring(element.getKey().length() + 1).toUpperCase())); + element.getValue().accept(searchParameter, SearchType.valueOf(s.substring(element.getKey().length() + 1).toUpperCase())); has = true; } else if (s.startsWith(element.getKey().substring(0, 2) + ":")) { - element.getValue().accept(search, SearchType.valueOf(s.substring(element.getKey().substring(0, 2).length() + 1).toUpperCase())); + element.getValue().accept(searchParameter, SearchType.valueOf(s.substring(element.getKey().substring(0, 2).length() + 1).toUpperCase())); has = true; } if (has) break; @@ -141,15 +140,15 @@ public class MaterialCommand extends SWCommand implements Listener { case "-blastresistance:": s = s.substring(s.indexOf(':') + 1).replace('_', ' '); if (s.isEmpty() || s.matches("((([><]=?)|!|=)\\d+(\\.|,\\d+)?)( ((([><]=?)|!|=)\\d+(\\.|,\\d+)?))*")) { - search.blastResistance = s; + searchParameter.blastResistance = s; } break; default: - search.name = s; + searchParameter.name = s; break; } } - materialGUI(p, search); + materialGUI(p, searchParameter); } @Mapper(value = "search", local = true) @@ -182,7 +181,7 @@ public class MaterialCommand extends SWCommand implements Listener { }; } - public void materialGUI(Player p, Search search) { + public void materialGUI(Player p, SearchParameter search) { List> swListEntries = new ArrayList<>(); MaterialLazyInit.materialData.forEach(data -> { if (data.is(search)) { @@ -202,59 +201,59 @@ public class MaterialCommand extends SWCommand implements Listener { private void searchGUI(Player p) { SWInventory swInventory = new SWInventory(p, 54, BauSystem.MESSAGE.parse("MATERIAL_SEARCH", p)); - Search search = searchMap.get(p); + SearchParameter searchParameter = SWPlayer.of(p).getComponentOrDefault(SearchParameter.class, SearchParameter::new); swInventory.setItem(0, new SWItem(Material.ARROW, BauSystem.MESSAGE.parse("MATERIAL_BACK", p), clickType -> { materialGUI(p); }).setCustomModelData(CMDs.BACK)); - swInventory.setItem(10, new SWItem(Material.NAME_TAG, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_NAME", p) + BauSystem.MESSAGE.parse("MATERIAL_SEARCH_VALUE", p, search.name), clickType -> { - SWAnvilInv swAnvilInv = new SWAnvilInv(p, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_NAME", p), search.name); + swInventory.setItem(10, new SWItem(Material.NAME_TAG, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_NAME", p) + BauSystem.MESSAGE.parse("MATERIAL_SEARCH_VALUE", p, searchParameter.name), clickType -> { + SWAnvilInv swAnvilInv = new SWAnvilInv(p, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_NAME", p), searchParameter.name); swAnvilInv.setCallback(s -> { - search.name = s; + searchParameter.name = s; searchGUI(p); }); swAnvilInv.open(); })); - swInventory.setItem(19, new SWItem(Material.GLASS, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_TRANSPARENT", p) + BauSystem.MESSAGE.parse("MATERIAL_SEARCH_VALUE", p, BauSystem.MESSAGE.parse(search.transparent.getChatValue(), p)), clickType -> { - search.transparent = search.transparent.next(); + swInventory.setItem(19, new SWItem(Material.GLASS, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_TRANSPARENT", p) + BauSystem.MESSAGE.parse("MATERIAL_SEARCH_VALUE", p, BauSystem.MESSAGE.parse(searchParameter.transparent.getChatValue(), p)), clickType -> { + searchParameter.transparent = searchParameter.transparent.next(); searchGUI(p); })); - swInventory.setItem(20, new SWItem(Material.BRICK, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_SOLID", p) + BauSystem.MESSAGE.parse("MATERIAL_SEARCH_VALUE", p, BauSystem.MESSAGE.parse(search.solid.getChatValue(), p)), clickType -> { - search.solid = search.solid.next(); + swInventory.setItem(20, new SWItem(Material.BRICK, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_SOLID", p) + BauSystem.MESSAGE.parse("MATERIAL_SEARCH_VALUE", p, BauSystem.MESSAGE.parse(searchParameter.solid.getChatValue(), p)), clickType -> { + searchParameter.solid = searchParameter.solid.next(); searchGUI(p); })); - swInventory.setItem(21, new SWItem(Material.BLACK_CONCRETE_POWDER, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_GRAVITY", p) + BauSystem.MESSAGE.parse("MATERIAL_SEARCH_VALUE", p, BauSystem.MESSAGE.parse(search.gravity.getChatValue(), p)), clickType -> { - search.gravity = search.gravity.next(); + swInventory.setItem(21, new SWItem(Material.BLACK_CONCRETE_POWDER, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_GRAVITY", p) + BauSystem.MESSAGE.parse("MATERIAL_SEARCH_VALUE", p, BauSystem.MESSAGE.parse(searchParameter.gravity.getChatValue(), p)), clickType -> { + searchParameter.gravity = searchParameter.gravity.next(); searchGUI(p); })); - swInventory.setItem(22, new SWItem(Material.BIRCH_LOG, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_OCCLUDING", p) + BauSystem.MESSAGE.parse("MATERIAL_SEARCH_VALUE", p, BauSystem.MESSAGE.parse(search.occluding.getChatValue(), p)), clickType -> { - search.occluding = search.occluding.next(); + swInventory.setItem(22, new SWItem(Material.BIRCH_LOG, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_OCCLUDING", p) + BauSystem.MESSAGE.parse("MATERIAL_SEARCH_VALUE", p, BauSystem.MESSAGE.parse(searchParameter.occluding.getChatValue(), p)), clickType -> { + searchParameter.occluding = searchParameter.occluding.next(); searchGUI(p); })); - swInventory.setItem(23, new SWItem(Material.OAK_BUTTON, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_INTERACTEABLE", p) + BauSystem.MESSAGE.parse("MATERIAL_SEARCH_VALUE", p, BauSystem.MESSAGE.parse(search.interacteable.getChatValue(), p)), clickType -> { - search.interacteable = search.interacteable.next(); + swInventory.setItem(23, new SWItem(Material.OAK_BUTTON, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_INTERACTEABLE", p) + BauSystem.MESSAGE.parse("MATERIAL_SEARCH_VALUE", p, BauSystem.MESSAGE.parse(searchParameter.interacteable.getChatValue(), p)), clickType -> { + searchParameter.interacteable = searchParameter.interacteable.next(); searchGUI(p); })); - swInventory.setItem(24, new SWItem(Material.FLINT_AND_STEEL, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_FLAMMABLE", p) + BauSystem.MESSAGE.parse("MATERIAL_SEARCH_VALUE", p, BauSystem.MESSAGE.parse(search.flammable.getChatValue(), p)), clickType -> { - search.flammable = search.flammable.next(); + swInventory.setItem(24, new SWItem(Material.FLINT_AND_STEEL, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_FLAMMABLE", p) + BauSystem.MESSAGE.parse("MATERIAL_SEARCH_VALUE", p, BauSystem.MESSAGE.parse(searchParameter.flammable.getChatValue(), p)), clickType -> { + searchParameter.flammable = searchParameter.flammable.next(); searchGUI(p); })); - swInventory.setItem(25, new SWItem(Material.LAVA_BUCKET, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_BURNABLE", p) + BauSystem.MESSAGE.parse("MATERIAL_SEARCH_VALUE", p, BauSystem.MESSAGE.parse(search.burnable.getChatValue(), p)), clickType -> { - search.burnable = search.burnable.next(); + swInventory.setItem(25, new SWItem(Material.LAVA_BUCKET, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_BURNABLE", p) + BauSystem.MESSAGE.parse("MATERIAL_SEARCH_VALUE", p, BauSystem.MESSAGE.parse(searchParameter.burnable.getChatValue(), p)), clickType -> { + searchParameter.burnable = searchParameter.burnable.next(); searchGUI(p); })); - swInventory.setItem(28, new SWItem(Material.WATER_BUCKET, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_WATERLOGGABLE", p) + BauSystem.MESSAGE.parse("MATERIAL_SEARCH_VALUE", p, BauSystem.MESSAGE.parse(search.waterloggable.getChatValue(), p)), clickType -> { - search.waterloggable = search.waterloggable.next(); + swInventory.setItem(28, new SWItem(Material.WATER_BUCKET, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_WATERLOGGABLE", p) + BauSystem.MESSAGE.parse("MATERIAL_SEARCH_VALUE", p, BauSystem.MESSAGE.parse(searchParameter.waterloggable.getChatValue(), p)), clickType -> { + searchParameter.waterloggable = searchParameter.waterloggable.next(); searchGUI(p); })); - swInventory.setItem(29, new SWItem(Material.PISTON, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_UNMOVEABLE", p) + BauSystem.MESSAGE.parse("MATERIAL_SEARCH_VALUE", p, BauSystem.MESSAGE.parse(search.unmoveable.getChatValue(), p)), clickType -> { - search.unmoveable = search.unmoveable.next(); + swInventory.setItem(29, new SWItem(Material.PISTON, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_UNMOVEABLE", p) + BauSystem.MESSAGE.parse("MATERIAL_SEARCH_VALUE", p, BauSystem.MESSAGE.parse(searchParameter.unmoveable.getChatValue(), p)), clickType -> { + searchParameter.unmoveable = searchParameter.unmoveable.next(); searchGUI(p); })); - swInventory.setItem(34, new SWItem(Material.NETHER_BRICK, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_BLASTRESISTANCE", p) + BauSystem.MESSAGE.parse("MATERIAL_SEARCH_VALUE", p, search.blastResistance), clickType -> { - SWAnvilInv swAnvilInv = new SWAnvilInv(p, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_BLASTRESISTANCE", p), search.blastResistance); + swInventory.setItem(34, new SWItem(Material.NETHER_BRICK, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_BLASTRESISTANCE", p) + BauSystem.MESSAGE.parse("MATERIAL_SEARCH_VALUE", p, searchParameter.blastResistance), clickType -> { + SWAnvilInv swAnvilInv = new SWAnvilInv(p, BauSystem.MESSAGE.parse("MATERIAL_SEARCH_BLASTRESISTANCE", p), searchParameter.blastResistance); swAnvilInv.setCallback(s -> { if (s.isEmpty() || s.matches("((([><]=?)|!|=)\\d+(\\.|,\\d+)?)( ((([><]=?)|!|=)\\d+(\\.|,\\d+)?))*")) { - search.blastResistance = s; + searchParameter.blastResistance = s; } searchGUI(p); }); @@ -262,14 +261,4 @@ public class MaterialCommand extends SWCommand implements Listener { })); swInventory.open(); } - - @EventHandler - public void onPlayerJoin(PlayerJoinEvent event) { - searchMap.put(event.getPlayer(), new Search()); - } - - @EventHandler - public void onPlayerQuit(PlayerQuitEvent event) { - searchMap.remove(event.getPlayer()); - } } diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/util/MaterialLazyInit.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/util/MaterialLazyInit.java index f05e0de9..acfc3336 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/util/MaterialLazyInit.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/util/MaterialLazyInit.java @@ -132,7 +132,7 @@ public class MaterialLazyInit { }), originalMaterial); } - public boolean is(MaterialCommand.Search search) { + public boolean is(MaterialCommand.SearchParameter search) { boolean result = true; result &= search.transparent.test(transparent); result &= search.solid.test(solid); From 40ac7b21392bc1220ae610616fd42bf1f7d26136 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Fri, 7 Nov 2025 14:43:52 +0100 Subject: [PATCH 08/11] Improve NoClipCommand Improve SelectBauGuiItem --- .../features/util/GamemodeCommand.java | 14 ++--- .../features/util/NoClipCommand.java | 62 +++++++++---------- .../features/util/items/SelectBauGuiItem.java | 13 ++-- 3 files changed, 42 insertions(+), 47 deletions(-) diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/util/GamemodeCommand.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/util/GamemodeCommand.java index 9e3da950..86ecf6ca 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/util/GamemodeCommand.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/util/GamemodeCommand.java @@ -20,6 +20,7 @@ package de.steamwar.bausystem.features.util; import de.steamwar.bausystem.BauSystem; import de.steamwar.command.SWCommand; +import de.steamwar.core.SWPlayer; import de.steamwar.linkage.Linked; import org.bukkit.GameMode; import org.bukkit.entity.Player; @@ -39,10 +40,11 @@ public class GamemodeCommand extends SWCommand { @Register public void genericCommand(final Player p) { - if (NoClipCommand.getNOCLIPS().contains(p)) { - p.performCommand("noclip"); - return; - } + SWPlayer swPlayer = SWPlayer.of(p); + if (swPlayer.hasComponent(NoClipCommand.NoClipData.class)) { + swPlayer.removeComponent(NoClipCommand.NoClipData.class); + return; + } if (p.getGameMode() == GameMode.CREATIVE) { p.setGameMode(GameMode.SPECTATOR); } else { @@ -52,9 +54,7 @@ public class GamemodeCommand extends SWCommand { @Register public void gamemodeCommand(final Player p, final GameMode gameMode) { - if (NoClipCommand.getNOCLIPS().contains(p)) { - p.performCommand("noclip"); - } + SWPlayer.of(p).removeComponent(NoClipCommand.NoClipData.class); p.setGameMode(gameMode); } } \ No newline at end of file diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/util/NoClipCommand.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/util/NoClipCommand.java index ad97dac0..61fdecdc 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/util/NoClipCommand.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/util/NoClipCommand.java @@ -19,17 +19,17 @@ package de.steamwar.bausystem.features.util; -import de.steamwar.Reflection; import com.comphenix.tinyprotocol.TinyProtocol; import com.mojang.authlib.GameProfile; +import de.steamwar.Reflection; import de.steamwar.bausystem.BauSystem; import de.steamwar.bausystem.features.tpslimit.TPSUtils; import de.steamwar.bausystem.utils.BauMemberUpdateEvent; import de.steamwar.bausystem.utils.NMSWrapper; import de.steamwar.command.SWCommand; import de.steamwar.core.ProtocolWrapper; +import de.steamwar.core.SWPlayer; import de.steamwar.linkage.Linked; -import lombok.Getter; import org.bukkit.Bukkit; import org.bukkit.GameMode; import org.bukkit.entity.Player; @@ -40,10 +40,6 @@ import org.bukkit.event.player.PlayerGameModeChangeEvent; import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.event.player.PlayerToggleFlightEvent; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; import java.util.function.BiFunction; @Linked @@ -59,29 +55,34 @@ public class NoClipCommand extends SWCommand implements Listener { private static final Class windowClick = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundContainerClickPacket"); private static final Class setSlotStack = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundSetCreativeModeSlotPacket"); - @Getter - private static final List NOCLIPS = new ArrayList<>(); - private static final Map LAST_TICKS = new HashMap<>(); + public static class NoClipData implements SWPlayer.Component { + private long lastTick = -1; + + @Override + public void onUnmount(SWPlayer player) { + player.setGameMode(GameMode.CREATIVE); + } + } public NoClipCommand() { super("noclip", "nc"); BiFunction first = (player, o) -> { - if (NOCLIPS.contains(player)) { - if (LAST_TICKS.getOrDefault(player, -1L).equals(TPSUtils.currentTick.get())) return o; - NMSWrapper.impl.setInternalGameMode(player, GameMode.SPECTATOR); - LAST_TICKS.put(player, TPSUtils.currentTick.get()); - } + NoClipData noClipData = SWPlayer.of(player).getComponent(NoClipData.class).orElse(null); + if (noClipData == null) return o; + if (noClipData.lastTick == TPSUtils.currentTick.get()) return o; + NMSWrapper.impl.setInternalGameMode(player, GameMode.SPECTATOR); + noClipData.lastTick = TPSUtils.currentTick.get(); return o; }; TinyProtocol.instance.addFilter(position, first); TinyProtocol.instance.addFilter(positionLook, first); BiFunction second = (player, o) -> { - if (NOCLIPS.contains(player)) { - NMSWrapper.impl.setInternalGameMode(player, GameMode.CREATIVE); - LAST_TICKS.put(player, TPSUtils.currentTick.get()); - } + NoClipData noClipData = SWPlayer.of(player).getComponent(NoClipData.class).orElse(null); + if (noClipData == null) return o; + NMSWrapper.impl.setInternalGameMode(player, GameMode.CREATIVE); + noClipData.lastTick = TPSUtils.currentTick.get(); return o; }; TinyProtocol.instance.addFilter(useItem, second); @@ -89,7 +90,7 @@ public class NoClipCommand extends SWCommand implements Listener { TinyProtocol.instance.addFilter(windowClick, second); BiFunction third = (player, o) -> { - if (NOCLIPS.contains(player)) { + if (SWPlayer.of(player).hasComponent(NoClipData.class)) { NMSWrapper.impl.setSlotToItemStack(player, o); } return o; @@ -99,9 +100,9 @@ public class NoClipCommand extends SWCommand implements Listener { @Register(help = true) public void genericCommand(@Validator Player player) { - if (NOCLIPS.contains(player)) { - NOCLIPS.remove(player); - player.setGameMode(GameMode.CREATIVE); + SWPlayer swPlayer = SWPlayer.of(player); + if (swPlayer.hasComponent(NoClipData.class)) { + swPlayer.removeComponent(NoClipData.class); } else { player.setGameMode(GameMode.SPECTATOR); NMSWrapper.impl.setPlayerBuildAbilities(player); @@ -109,8 +110,8 @@ public class NoClipCommand extends SWCommand implements Listener { Object gameStateChangeObject = Reflection.newInstance(gameStateChange); NMSWrapper.impl.setGameStateChangeReason(gameStateChangeObject); floatFieldAccessor.set(gameStateChangeObject, 1F); - - NOCLIPS.add(player); + + swPlayer.setComponent(new NoClipData()); BauSystem.MESSAGE.send("OTHER_NOCLIP_SLOT_INFO", player); TinyProtocol.instance.sendPacket(player, gameStateChangeObject); pseudoGameMode(player, GameMode.SPECTATOR); @@ -120,30 +121,27 @@ public class NoClipCommand extends SWCommand implements Listener { @EventHandler public void onBauMemberUpdate(BauMemberUpdateEvent event) { event.getNewSpectator().forEach(player -> { - if (NOCLIPS.contains(player)) { - NOCLIPS.remove(player); - player.setGameMode(GameMode.CREATIVE); - } + SWPlayer.of(player).removeComponent(NoClipData.class); }); } @EventHandler(ignoreCancelled = true) public void onPlayerGameModeChange(PlayerGameModeChangeEvent event) { - if (NOCLIPS.contains(event.getPlayer())) { + if (SWPlayer.of(event.getPlayer()).hasComponent(NoClipData.class)) { event.setCancelled(true); } } @EventHandler(ignoreCancelled = true) public void onBlock(BlockCanBuildEvent event) { - if (NOCLIPS.contains(event.getPlayer())) { + if (SWPlayer.of(event.getPlayer()).hasComponent(NoClipData.class)) { event.setBuildable(true); } } @EventHandler(ignoreCancelled = true) public void onPlayerToggleFlight(PlayerToggleFlightEvent event) { - if (NOCLIPS.contains(event.getPlayer())) { + if (SWPlayer.of(event.getPlayer()).hasComponent(NoClipData.class)) { event.setCancelled(true); event.getPlayer().setFlying(true); } @@ -154,7 +152,7 @@ public class NoClipCommand extends SWCommand implements Listener { if (event.getCause() != PlayerTeleportEvent.TeleportCause.SPECTATE) { return; } - if (NOCLIPS.contains(event.getPlayer())) { + if (SWPlayer.of(event.getPlayer()).hasComponent(NoClipData.class)) { event.setCancelled(true); Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> { event.getPlayer().setSpectatorTarget(null); diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/util/items/SelectBauGuiItem.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/util/items/SelectBauGuiItem.java index 78669a8d..43b9cb85 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/util/items/SelectBauGuiItem.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/util/items/SelectBauGuiItem.java @@ -24,6 +24,7 @@ import de.steamwar.bausystem.Permission; import de.steamwar.bausystem.linkage.BauGuiItem; import de.steamwar.bausystem.region.utils.RegionExtensionType; import de.steamwar.bausystem.region.utils.RegionType; +import de.steamwar.core.SWPlayer; import de.steamwar.inventory.SWInventory; import de.steamwar.inventory.SWItem; import de.steamwar.linkage.Linked; @@ -35,15 +36,11 @@ import org.bukkit.event.inventory.ClickType; import org.bukkit.inventory.ItemStack; import java.util.Arrays; -import java.util.HashMap; import java.util.Locale; -import java.util.Map; @Linked public class SelectBauGuiItem extends BauGuiItem { - private static final Map LAST_SELECT_MAP = new HashMap<>(); - public SelectBauGuiItem() { super(13); } @@ -58,13 +55,13 @@ public class SelectBauGuiItem extends BauGuiItem { private static void selectFinish(Player p, RegionType type, RegionExtensionType extensionType) { p.closeInventory(); - LAST_SELECT_MAP.put(p, new LastSelect(type, extensionType)); + SWPlayer.of(p).setComponent(new LastSelect(type, extensionType)); p.performCommand("select " + type.name() + " " + extensionType.toString()); } @Override public ItemStack getItem(Player player) { - LastSelect last = LAST_SELECT_MAP.getOrDefault(player, new LastSelect(RegionType.BUILD, RegionExtensionType.NORMAL)); + LastSelect last = SWPlayer.of(player).getComponentOrDefault(LastSelect.class, () -> new LastSelect(RegionType.BUILD, RegionExtensionType.NORMAL)); return new SWItem(Material.SCAFFOLDING, BauSystem.MESSAGE.parse("SELECT_ITEM_SELECT", player), Arrays.asList(BauSystem.MESSAGE.parse("SELECT_ITEM_AUSWAHL", player, BauSystem.MESSAGE.parse(last.type.getChatValue(), player), last.extensionType.name()), BauSystem.MESSAGE.parse("SELECT_ITEM_RIGHT_CLICK", player)), false, clickType -> { }).getItemStack(); } @@ -80,7 +77,7 @@ public class SelectBauGuiItem extends BauGuiItem { inv.open(); } else { p.closeInventory(); - LastSelect last = LAST_SELECT_MAP.getOrDefault(p, new LastSelect(RegionType.BUILD, RegionExtensionType.NORMAL)); + LastSelect last = SWPlayer.of(p).getComponentOrDefault(LastSelect.class, () -> new LastSelect(RegionType.BUILD, RegionExtensionType.NORMAL)); p.performCommand("select " + last.getType().name() + " " + last.getExtensionType().toString()); } return false; @@ -92,7 +89,7 @@ public class SelectBauGuiItem extends BauGuiItem { } @AllArgsConstructor - private static class LastSelect { + private static class LastSelect implements SWPlayer.Component { @Getter private final RegionType type; @Getter From 58460416c3fcc09ec66dbcfabb0613252e406c61 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Fri, 7 Nov 2025 14:49:10 +0100 Subject: [PATCH 09/11] Improve WarpListener --- .../bausystem/features/warp/WarpListener.java | 74 ++++++++----------- 1 file changed, 32 insertions(+), 42 deletions(-) diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/warp/WarpListener.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/warp/WarpListener.java index 60121c90..f57ff726 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/warp/WarpListener.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/warp/WarpListener.java @@ -21,6 +21,7 @@ package de.steamwar.bausystem.features.warp; import de.steamwar.bausystem.region.Region; import de.steamwar.core.Core; +import de.steamwar.core.SWPlayer; import de.steamwar.entity.RArmorStand; import de.steamwar.entity.REntityServer; import de.steamwar.linkage.Linked; @@ -30,7 +31,10 @@ 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.player.*; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerItemHeldEvent; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.event.player.PlayerToggleSneakEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.util.Vector; @@ -42,8 +46,21 @@ import java.util.Map; @Linked public class WarpListener implements Listener { - private Map warpEntityServer = new HashMap<>(); - private Map> selected = new HashMap<>(); + public static class WarpComponent implements SWPlayer.Component { + private REntityServer server; + private List selected = new ArrayList<>(); + + @Override + public void onMount(SWPlayer player) { + server = new REntityServer(); + server.addPlayer(player.getPlayer()); + } + + @Override + public void onUnmount(SWPlayer player) { + server.close(); + } + } @EventHandler public void onPlayerItemHeld(PlayerItemHeldEvent e) { @@ -65,20 +82,11 @@ public class WarpListener implements Listener { } private void reshow(Player p, Material material, boolean sneaking) { - REntityServer entityServer = warpEntityServer.get(p); - if (entityServer != null) { - entityServer.close(); - } - if (material != Material.COMPASS) { - warpEntityServer.remove(p); - return; - } - - selected.remove(p); - entityServer = new REntityServer(); - entityServer.addPlayer(p); - warpEntityServer.put(p, entityServer); + SWPlayer swPlayer = SWPlayer.of(p); + swPlayer.removeComponent(WarpComponent.class); + if (material != Material.COMPASS) return; + WarpComponent warpComponent = swPlayer.getComponentOrDefault(WarpComponent.class, WarpComponent::new); Vector current = p.getLocation().clone().add(p.getLocation().getDirection().multiply(5)).toVector(); Map locations = new HashMap<>(); @@ -99,12 +107,9 @@ public class WarpListener implements Listener { } } - REntityServer finalEntityServer = entityServer; locations.forEach((name, location) -> { Vector vector = location.toVector().subtract(p.getLocation().toVector()); - if (vector.getX() * vector.getX() + vector.getZ() * vector.getZ() < 25) { - return; - } + if (vector.getX() * vector.getX() + vector.getZ() * vector.getZ() < 25) return; vector.setY(0); Vector position = p.getLocation().toVector().clone().add(vector.normalize().multiply(5)); @@ -112,9 +117,9 @@ public class WarpListener implements Listener { if ((position.getX() - current.getX()) * (position.getX() - current.getX()) + (position.getZ() - current.getZ()) * (position.getZ() - current.getZ()) < 0.1) { name = "§a§l" + name; - selected.computeIfAbsent(p, player -> new ArrayList<>()).add(location); + warpComponent.selected.add(location); } - RArmorStand armorStand = new RArmorStand(finalEntityServer, position.toLocation(p.getWorld()), RArmorStand.Size.MARKER); + RArmorStand armorStand = new RArmorStand(warpComponent.server, position.toLocation(p.getWorld()), RArmorStand.Size.MARKER); armorStand.setDisplayName(name); armorStand.setNoGravity(true); armorStand.setInvisible(true); @@ -123,28 +128,13 @@ public class WarpListener implements Listener { @EventHandler(priority = EventPriority.LOWEST) public void onPlayerInteract(PlayerInteractEvent event) { - if (event.getPlayer().getInventory().getItemInMainHand().getType() != Material.COMPASS) { - return; - } - if (event.getAction() != Action.RIGHT_CLICK_AIR) { - return; - } - List locations = selected.getOrDefault(event.getPlayer(), new ArrayList<>()); - if (locations.size() != 1) { - return; - } - Location location = locations.get(0); + if (event.getPlayer().getInventory().getItemInMainHand().getType() != Material.COMPASS) return; + if (event.getAction() != Action.RIGHT_CLICK_AIR) return; + WarpComponent warpComponent = SWPlayer.of(event.getPlayer()).getComponent(WarpComponent.class).orElse(null); + if (warpComponent == null || warpComponent.selected.size() != 1) return; + Location location = warpComponent.selected.get(0); event.getPlayer().teleport(location); event.getPlayer().playSound(location, Sound.ENTITY_ENDERMAN_TELEPORT, SoundCategory.PLAYERS, 1, 1); event.setCancelled(true); } - - @EventHandler - public void onPlayerQuit(PlayerQuitEvent event) { - warpEntityServer.computeIfPresent(event.getPlayer(), (player, rEntityServer) -> { - rEntityServer.close(); - return null; - }); - selected.remove(event.getPlayer()); - } } From cc3b93a8f6d251ddc00b323ac997ecb3e0f50faf Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Fri, 7 Nov 2025 14:54:57 +0100 Subject: [PATCH 10/11] Improve SelectAdjacent --- .../features/worldedit/SelectAdjacent.java | 25 ++++++++----------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/worldedit/SelectAdjacent.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/worldedit/SelectAdjacent.java index 518ca00c..3f6ca8f2 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/worldedit/SelectAdjacent.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/worldedit/SelectAdjacent.java @@ -23,6 +23,7 @@ import de.steamwar.bausystem.BauSystem; import de.steamwar.bausystem.region.Point; import de.steamwar.bausystem.region.Region; import de.steamwar.bausystem.utils.FlatteningWrapper; +import de.steamwar.core.SWPlayer; import de.steamwar.core.WorldEditRenderer; import de.steamwar.linkage.Linked; import de.steamwar.linkage.MinVersion; @@ -35,13 +36,10 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.block.Action; import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.scheduler.BukkitTask; import org.bukkit.util.Vector; -import java.util.HashMap; import java.util.HashSet; -import java.util.Map; import java.util.Set; import java.util.function.Predicate; @@ -71,32 +69,23 @@ public class SelectAdjacent implements Listener { new Vector(0, -1, -1), }; - private Map selectors = new HashMap<>(); - @EventHandler public void onPlayerInteract(PlayerInteractEvent event) { if (!event.hasItem()) return; if (event.getItem().getType() != Material.WOODEN_AXE) return; - Selector selector = selectors.get(event.getPlayer()); - if (selector != null) selector.cancel(); if (!event.getPlayer().isSneaking()) return; if (event.getAction() != Action.LEFT_CLICK_BLOCK) return; Material material = event.getPlayer().getInventory().getItemInOffHand().getType(); + Selector selector; if (material.isAir()) { selector = new Selector(event.getClickedBlock(), event.getPlayer(), __ -> true); } else { selector = new Selector(event.getClickedBlock(), event.getPlayer(), type -> type == material); } - selectors.put(event.getPlayer(), selector); + SWPlayer.of(event.getPlayer()).setComponent(selector); } - @EventHandler - public void onPlayerQuit(PlayerQuitEvent event) { - Selector selector = selectors.remove(event.getPlayer()); - if (selector != null) selector.cancel(); - } - - private class Selector { + private class Selector implements SWPlayer.Component { private static final int MAX_BLOCKS = 500_000; @@ -154,6 +143,7 @@ public class SelectAdjacent implements Listener { if (toCalc.isEmpty() || seen.size() > MAX_BLOCKS) { bukkitTask.cancel(); player.sendTitle("§aDone", "§e" + volume + " §7Blocks", 0, 20, 5); + SWPlayer.of(player).removeComponent(Selector.class); } }, 1, 1); } @@ -190,5 +180,10 @@ public class SelectAdjacent implements Listener { } } } + + @Override + public void onUnmount(SWPlayer player) { + cancel(); + } } } From 14045a3366887ebc17ff4454040cc304b8d2c36d Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Fri, 7 Nov 2025 15:30:18 +0100 Subject: [PATCH 11/11] Update method name in Countingwand --- .../bausystem/features/countingwand/Countingwand.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/countingwand/Countingwand.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/countingwand/Countingwand.java index 0e222021..0fbaf1b7 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/countingwand/Countingwand.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/countingwand/Countingwand.java @@ -41,7 +41,7 @@ public class Countingwand { private Point pos1; private Point pos2; - public boolean set(boolean pos1, Point point) { + public boolean setPosition(boolean pos1, Point point) { if (this.pos1 == null || this.pos2 == null) { this.pos1 = point; this.pos2 = point; @@ -74,7 +74,7 @@ public class Countingwand { public void checkSelection(final Point point, final boolean pos1, final Player p) { SWPlayer player = SWPlayer.of(p); CountingWandComponent countingWandComponent = player.getComponentOrDefault(CountingWandComponent.class, CountingWandComponent::new); - if (countingWandComponent.set(pos1, point)) { + if (countingWandComponent.setPosition(pos1, point)) { Point point1 = countingWandComponent.pos1; Point point2 = countingWandComponent.pos2; int amount = (Math.abs(point1.getX() - point2.getX()) + 1) * (Math.abs(point1.getY() - point2.getY()) + 1) * (Math.abs(point1.getZ() - point2.getZ()) + 1);