From ed29a0a4cc2ad06cfa009da161b0c362375a3990 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Thu, 1 Aug 2024 19:12:15 +0200 Subject: [PATCH 001/122] begin new sign API --- .../java/net/countercraft/movecraft/listener/SignListener.java | 2 ++ .../java/net/countercraft/movecraft/sign/AbstractCraftSign.java | 2 ++ .../net/countercraft/movecraft/sign/AbstractMovecraftSign.java | 2 ++ 3 files changed, 6 insertions(+) create mode 100644 Movecraft/src/main/java/net/countercraft/movecraft/listener/SignListener.java create mode 100644 api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftSign.java create mode 100644 api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/listener/SignListener.java b/Movecraft/src/main/java/net/countercraft/movecraft/listener/SignListener.java new file mode 100644 index 000000000..2e74575c2 --- /dev/null +++ b/Movecraft/src/main/java/net/countercraft/movecraft/listener/SignListener.java @@ -0,0 +1,2 @@ +package net.countercraft.movecraft.listener;public class SignListener { +} diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftSign.java new file mode 100644 index 000000000..3f358c8e1 --- /dev/null +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftSign.java @@ -0,0 +1,2 @@ +package net.countercraft.movecraft.sign;public class AbstractCraftSign { +} diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java new file mode 100644 index 000000000..b7779f5b4 --- /dev/null +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java @@ -0,0 +1,2 @@ +package net.countercraft.movecraft.sign;public class AbstractMovecraftSign { +} From 0825279e4be75ef1b3cf4e46c08bf012f0034869 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Thu, 1 Aug 2024 19:12:36 +0200 Subject: [PATCH 002/122] add base class for signs and registration --- .../movecraft/sign/AbstractMovecraftSign.java | 83 ++++++++++++++++++- 1 file changed, 82 insertions(+), 1 deletion(-) diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java index b7779f5b4..63239d9d5 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java @@ -1,2 +1,83 @@ -package net.countercraft.movecraft.sign;public class AbstractMovecraftSign { +package net.countercraft.movecraft.sign; + +import net.countercraft.movecraft.craft.Craft; +import net.countercraft.movecraft.util.MathUtils; +import org.bukkit.block.Sign; +import org.bukkit.entity.Player; +import org.bukkit.event.block.Action; +import org.bukkit.event.block.SignChangeEvent; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +public abstract class AbstractMovecraftSign { + + private static final Map SIGNS = Collections.synchronizedMap(new HashMap<>()); + + public static boolean hasBeenRegistered(final String ident) { + return SIGNS.containsKey(ident); + } + + public static Optional tryGet(final String ident) { + String identToUse = ident.toUpperCase(); + if (identToUse.indexOf(":") >= 0) { + identToUse = identToUse.split(":")[0]; + } + return Optional.ofNullable(SIGNS.getOrDefault(identToUse, null)); + } + + public static void forceRegister(final String ident, final @Nonnull AbstractMovecraftSign instance) { + register(ident, instance, true); + } + + public static void register(final String ident, final @Nonnull AbstractMovecraftSign instance, boolean allowOverride) { + if (allowOverride) { + SIGNS.put(ident.toUpperCase(), instance); + } else { + SIGNS.putIfAbsent(ident.toUpperCase(), instance); + } + } + + protected final Optional optPermission; + + public AbstractMovecraftSign() { + this(null); + } + + public AbstractMovecraftSign(String permissionNode) { + this.optPermission = Optional.ofNullable(permissionNode); + } + + // Return true to cancel the event + public boolean processSignClick(Action clickType, Sign sign, Player player) { + if (!this.isSignValid(clickType, sign, player)) { + return false; + } + if (!this.canPlayerUseSign(clickType, sign, player)) { + return false; + } + + return internalProcessSign(clickType, sign, player, getCraft(sign)); + } + + protected boolean canPlayerUseSign(Action clickType, Sign sign, Player player) { + if (this.optPermission.isPresent()) { + return player.hasPermission(this.optPermission.get()); + } + return true; + } + + protected Optional getCraft(Sign sign) { + return Optional.ofNullable(MathUtils.getCraftByPersistentBlockData(sign.getLocation())); + } + + public abstract boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action type, boolean sneaking); + protected abstract boolean isSignValid(Action clickType, Sign sign, Player player); + protected abstract boolean internalProcessSign(Action clickType, Sign sign, Player player, Optional craft); + public abstract boolean processSignChange(SignChangeEvent event); + } From b66b5e0f61e5a69b87a31fe3b136aba2022969b0 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Thu, 1 Aug 2024 19:12:54 +0200 Subject: [PATCH 003/122] add craft sign => For stuff like cruise signs or remote signs --- .../movecraft/sign/AbstractCraftSign.java | 96 ++++++++++++++++++- 1 file changed, 95 insertions(+), 1 deletion(-) diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftSign.java index 3f358c8e1..cf07f3705 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftSign.java @@ -1,2 +1,96 @@ -package net.countercraft.movecraft.sign;public class AbstractCraftSign { +package net.countercraft.movecraft.sign; + +import net.countercraft.movecraft.craft.Craft; +import net.countercraft.movecraft.craft.PilotedCraft; +import net.countercraft.movecraft.craft.PlayerCraft; +import net.countercraft.movecraft.events.CraftDetectEvent; +import net.countercraft.movecraft.events.SignTranslateEvent; +import net.countercraft.movecraft.util.MathUtils; +import org.bukkit.block.Sign; +import org.bukkit.entity.Player; +import org.bukkit.event.block.Action; +import org.bukkit.event.inventory.ClickType; + +import java.util.Optional; + +public abstract class AbstractCraftSign extends AbstractMovecraftSign { + + public static Optional tryGetCraftSign(final String ident) { + Optional tmp = AbstractCraftSign.tryGet(ident); + if (tmp.isPresent() && tmp.get() instanceof AbstractCraftSign acs) { + return Optional.of(acs); + } + return Optional.empty(); + } + + private final boolean ignoreCraftIsBusy; + + public AbstractCraftSign(boolean ignoreCraftIsBusy) { + this(null, ignoreCraftIsBusy); + } + + public AbstractCraftSign(final String permission, boolean ignoreCraftIsBusy) { + super(permission); + this.ignoreCraftIsBusy = ignoreCraftIsBusy; + } + + // Return true to cancel the event + @Override + public boolean processSignClick(Action clickType, Sign sign, Player player) { + if (!this.isSignValid(clickType, sign, player)) { + return false; + } + if (!this.canPlayerUseSign(clickType, sign, player)) { + return false; + } + Optional craft = this.getCraft(sign); + if (craft.isEmpty()) { + this.onCraftNotFound(player, sign); + return false; + } + + if (craft.get() instanceof PlayerCraft pc) { + if (!pc.isNotProcessing() && !this.ignoreCraftIsBusy) { + this.onParentCraftBusy(player, craft.get()); + return false; + } + } + + return internalProcessSign(clickType, sign, player, craft); + } + + protected abstract void onParentCraftBusy(Player player, Craft craft); + + protected boolean canPlayerUseSignOn(Player player, Craft craft) { + if (craft instanceof PilotedCraft pc) { + return pc.getPilot() == player; + } + return true; + } + + protected abstract void onCraftNotFound(Player player, Sign sign); + + protected boolean canPlayerUseSign(ClickType clickType, Sign sign, Player player) { + if (this.optPermission.isPresent()) { + return player.hasPermission(this.optPermission.get()); + } + return true; + } + + protected abstract boolean internalProcessSign(ClickType clickType, Sign sign, Player player, Optional craft); + + protected Optional getCraft(Sign sign) { + return Optional.ofNullable(MathUtils.getCraftByPersistentBlockData(sign.getLocation())); + } + + public void onCraftDetect(CraftDetectEvent event) { + // Do nothing by default + } + + public void onSignMovedByCraft(SignTranslateEvent event) { + // Do nothing by default + } + + protected abstract boolean isSignValid(ClickType clickType, Sign sign, Player player); + } From 6a3ad90502ee1a6e99f57cb508299f36c92f6605 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Thu, 1 Aug 2024 19:13:12 +0200 Subject: [PATCH 004/122] implement listener that calls the individual registered signs --- .../net/countercraft/movecraft/Movecraft.java | 1 + .../movecraft/listener/SignListener.java | 82 ++++++++++++++++++- 2 files changed, 82 insertions(+), 1 deletion(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java b/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java index 3614892dd..b18a2ba53 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java @@ -222,6 +222,7 @@ public void onEnable() { getServer().getPluginManager().registerEvents(new ScuttleSign(), this); getServer().getPluginManager().registerEvents(new CraftPilotListener(), this); getServer().getPluginManager().registerEvents(new CraftReleaseListener(), this); + getServer().getPluginManager().registerEvents(new SignListener(), this); var contactsManager = new ContactsManager(); contactsManager.runTaskTimerAsynchronously(this, 0, 20); diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/listener/SignListener.java b/Movecraft/src/main/java/net/countercraft/movecraft/listener/SignListener.java index 2e74575c2..9bd7d7ec1 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/listener/SignListener.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/listener/SignListener.java @@ -1,2 +1,82 @@ -package net.countercraft.movecraft.listener;public class SignListener { +package net.countercraft.movecraft.listener; + +import net.countercraft.movecraft.events.CraftDetectEvent; +import net.countercraft.movecraft.events.SignTranslateEvent; +import net.countercraft.movecraft.sign.AbstractCraftSign; +import net.countercraft.movecraft.sign.AbstractMovecraftSign; +import org.bukkit.ChatColor; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.block.Sign; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.SignChangeEvent; +import org.bukkit.event.player.PlayerInteractEvent; + +public class SignListener implements Listener { + + @EventHandler(ignoreCancelled = true, priority = EventPriority.LOW) + public void onCraftDetect(CraftDetectEvent event) { + final World world = event.getCraft().getWorld();; + event.getCraft().getHitBox().forEach( + (mloc) -> { + Block block = mloc.toBukkit(world).getBlock(); + BlockState state = block.getState(); + if (state instanceof Sign sign) { + String ident = sign.getLines()[0]; + AbstractCraftSign.tryGetCraftSign(ident).ifPresent(acs -> { + acs.onCraftDetect(event); + }); + } + } + ); + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.LOW) + public void onSignTranslate(SignTranslateEvent event) { + String ident = event.getLine(0); + AbstractCraftSign.tryGetCraftSign(ident).ifPresent(acs -> { + acs.onSignMovedByCraft(event); + }); + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.LOW) + public void onSignChange(SignChangeEvent event) { + Block block = event.getBlock(); + if (block == null) { + return; + } + BlockState state = block.getState(); + if (state instanceof Sign sign) { + final String signHeader = ChatColor.stripColor(event.getLines()[0]); + AbstractMovecraftSign.tryGet(signHeader).ifPresent(ams -> { + + boolean success = ams.processSignChange(event); + if (ams.shouldCancelEvent(success, null, event.getPlayer().isSneaking())) { + event.setCancelled(true); + } + }); + } + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.LOW) + public void onSignClick(PlayerInteractEvent event) { + Block block = event.getClickedBlock(); + if (block == null) { + return; + } + BlockState state = block.getState(); + if (state instanceof Sign sign) { + final String signHeader = ChatColor.stripColor(sign.getLines()[0]); + AbstractMovecraftSign.tryGet(signHeader).ifPresent(ams -> { + boolean success = ams.processSignClick(event.getAction(), sign, event.getPlayer()); + if (ams.shouldCancelEvent(success, event.getAction(), event.getPlayer().isSneaking())) { + event.setCancelled(true); + } + }); + } + } + } From 9ca48166598b920281f85882a9549becd9070fc9 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Fri, 2 Aug 2024 16:24:43 +0200 Subject: [PATCH 005/122] add base for cruise-like signs --- .../movecraft/sign/AbstractCruiseSign.java | 114 ++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 api/src/main/java/net/countercraft/movecraft/sign/AbstractCruiseSign.java diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractCruiseSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractCruiseSign.java new file mode 100644 index 000000000..de458674b --- /dev/null +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractCruiseSign.java @@ -0,0 +1,114 @@ +package net.countercraft.movecraft.sign; + +import net.countercraft.movecraft.CruiseDirection; +import net.countercraft.movecraft.craft.Craft; +import net.countercraft.movecraft.craft.PilotedCraft; +import net.countercraft.movecraft.events.CraftDetectEvent; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.Style; +import net.kyori.adventure.text.format.TextColor; +import org.bukkit.ChatColor; +import org.bukkit.block.Sign; +import org.bukkit.entity.Player; +import org.bukkit.event.block.Action; +import org.bukkit.event.block.SignChangeEvent; +import org.jetbrains.annotations.Nullable; + +public abstract class AbstractCruiseSign extends AbstractCraftSign { + + private final String suffixOn; + private final String suffixOff; + private final String ident = AbstractMovecraftSign.findIdent(this); + + public AbstractCruiseSign(boolean ignoreCraftIsBusy, final String suffixOn, final String suffixOff) { + this(null, ignoreCraftIsBusy, suffixOn, suffixOff); + } + + public AbstractCruiseSign(final String permission, boolean ignoreCraftIsBusy, final String suffixOn, final String suffixOff) { + super(permission, ignoreCraftIsBusy); + this.suffixOn = suffixOn; + this.suffixOff = suffixOff; + } + + @Override + protected boolean isSignValid(Action clickType, Sign sign, Player player) { + if (sign.getLines() == null || sign.getLines()[0] == null) { + return false; + } + String[] headerSplit = ChatColor.stripColor(sign.getLine(0)).split(":"); + if (headerSplit.length != 2) { + return false; + } + String suffix = headerSplit[1]; + return suffix.equalsIgnoreCase(this.suffixOff) || suffix.equalsIgnoreCase(this.suffixOn); + } + + protected boolean isOnOrOff(Sign sign) { + String[] headerSplit = ChatColor.stripColor(sign.getLine(0)).split(":"); + if (headerSplit.length != 2) { + return false; + } + String suffix = headerSplit[1]; + return suffix.equalsIgnoreCase(this.suffixOn); + } + + @Override + public boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action type, boolean sneaking) { + return false; + } + + @Override + protected boolean internalProcessSign(Action clickType, Sign sign, Player player, Craft craft) { + boolean isOn = this.isOnOrOff(sign); + boolean willBeOn = !isOn; + if (willBeOn) { + CruiseDirection direction = this.getCruiseDirection(sign); + this.setCraftCruising(player, direction); + } else { + craft.setCruising(false); + } + + // Update sign + sign.line(0, buildHeader(willBeOn)); + sign.update(true); + craft.resetSigns(sign); + + return true; + } + + @Override + public boolean processSignChange(SignChangeEvent event) { + return true; + } + + @Override + public void onCraftDetect(CraftDetectEvent event, Sign sign) { + Player p = null; + if (event.getCraft() instanceof PilotedCraft pc) { + p = pc.getPilot(); + } + + if (this.isSignValid(Action.PHYSICAL, sign, p)) { + sign.line(0, buildHeader(false)); + } else { + // TODO: Error? React in any way? + sign.line(0, buildHeader(false)); + } + } + + protected Component buildHeader(boolean on) { + return on ? buildHeaderOn() : buildHeaderOff(); + } + + protected Component buildHeaderOn() { + return Component.text(this.ident).append(Component.text(": ")).append(Component.text(this.suffixOn, Style.style(TextColor.color(0, 255, 0)))); + } + + protected Component buildHeaderOff() { + return Component.text(this.ident).append(Component.text(": ")).append(Component.text(this.suffixOff, Style.style(TextColor.color(255, 0, 0)))); + } + + protected abstract void setCraftCruising(Player player, CruiseDirection direction); + // TODO: Rework cruise direction to vectors => Vector defines the skip distance and the direction + protected abstract CruiseDirection getCruiseDirection(Sign sign); +} From c80df993cb5d3337c5a752bc50cdb47555ff752f Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Fri, 2 Aug 2024 16:24:59 +0200 Subject: [PATCH 006/122] add overloaded internalProcessing method for craftsigns --- .../movecraft/sign/AbstractCraftSign.java | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftSign.java index cf07f3705..7df76eef7 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftSign.java @@ -9,7 +9,6 @@ import org.bukkit.block.Sign; import org.bukkit.entity.Player; import org.bukkit.event.block.Action; -import org.bukkit.event.inventory.ClickType; import java.util.Optional; @@ -59,6 +58,14 @@ public boolean processSignClick(Action clickType, Sign sign, Player player) { return internalProcessSign(clickType, sign, player, craft); } + @Override + protected boolean internalProcessSign(Action clickType, Sign sign, Player player, Optional craft) { + if (this.canPlayerUseSignOn(player, craft.get())) { + return this.internalProcessSign(clickType, sign, player, craft.get()); + } + return false; + } + protected abstract void onParentCraftBusy(Player player, Craft craft); protected boolean canPlayerUseSignOn(Player player, Craft craft) { @@ -70,20 +77,18 @@ protected boolean canPlayerUseSignOn(Player player, Craft craft) { protected abstract void onCraftNotFound(Player player, Sign sign); - protected boolean canPlayerUseSign(ClickType clickType, Sign sign, Player player) { + protected boolean canPlayerUseSign(Action clickType, Sign sign, Player player) { if (this.optPermission.isPresent()) { return player.hasPermission(this.optPermission.get()); } return true; } - protected abstract boolean internalProcessSign(ClickType clickType, Sign sign, Player player, Optional craft); - protected Optional getCraft(Sign sign) { return Optional.ofNullable(MathUtils.getCraftByPersistentBlockData(sign.getLocation())); } - public void onCraftDetect(CraftDetectEvent event) { + public void onCraftDetect(CraftDetectEvent event, Sign sign) { // Do nothing by default } @@ -91,6 +96,8 @@ public void onSignMovedByCraft(SignTranslateEvent event) { // Do nothing by default } - protected abstract boolean isSignValid(ClickType clickType, Sign sign, Player player); + protected abstract boolean isSignValid(Action clickType, Sign sign, Player player); + + protected abstract boolean internalProcessSign(Action clickType, Sign sign, Player player, Craft craft); } From 07e829ef22114474df3635525dedc573212e2ea4 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Fri, 2 Aug 2024 16:25:14 +0200 Subject: [PATCH 007/122] add method to get ident of sign instance --- .../movecraft/sign/AbstractMovecraftSign.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java index 63239d9d5..baab33654 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java @@ -52,6 +52,18 @@ public AbstractMovecraftSign(String permissionNode) { this.optPermission = Optional.ofNullable(permissionNode); } + public static String findIdent(AbstractMovecraftSign instance) { + if (!SIGNS.containsValue(instance)) { + throw new IllegalArgumentException("MovecraftSign instanceo must be registered!"); + } + for (Map.Entry entry : SIGNS.entrySet()) { + if (entry.getValue() == instance) { + return entry.getKey(); + } + } + throw new IllegalStateException("Somehow didn't find a key for a value that is in the map!"); + } + // Return true to cancel the event public boolean processSignClick(Action clickType, Sign sign, Player player) { if (!this.isSignValid(clickType, sign, player)) { @@ -79,5 +91,4 @@ protected Optional getCraft(Sign sign) { protected abstract boolean isSignValid(Action clickType, Sign sign, Player player); protected abstract boolean internalProcessSign(Action clickType, Sign sign, Player player, Optional craft); public abstract boolean processSignChange(SignChangeEvent event); - } From edbd6ef180121a63fa8ec2eb1523d41d4fd682aa Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Fri, 2 Aug 2024 16:25:25 +0200 Subject: [PATCH 008/122] call detect event with the sign --- .../java/net/countercraft/movecraft/listener/SignListener.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/listener/SignListener.java b/Movecraft/src/main/java/net/countercraft/movecraft/listener/SignListener.java index 9bd7d7ec1..36bdcbf6b 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/listener/SignListener.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/listener/SignListener.java @@ -27,7 +27,7 @@ public void onCraftDetect(CraftDetectEvent event) { if (state instanceof Sign sign) { String ident = sign.getLines()[0]; AbstractCraftSign.tryGetCraftSign(ident).ifPresent(acs -> { - acs.onCraftDetect(event); + acs.onCraftDetect(event, sign); }); } } From 0b3f467f6edefd6de83764a4666113e3f08a0baf Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Fri, 2 Aug 2024 16:40:42 +0200 Subject: [PATCH 009/122] migrate name sign to new sign API --- .../net/countercraft/movecraft/Movecraft.java | 3 +- .../countercraft/movecraft/sign/NameSign.java | 100 ++++++++++-------- 2 files changed, 58 insertions(+), 45 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java b/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java index b18a2ba53..082e97eb7 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java @@ -211,7 +211,8 @@ public void onEnable() { getServer().getPluginManager().registerEvents(new DescendSign(), this); getServer().getPluginManager().registerEvents(new HelmSign(), this); getServer().getPluginManager().registerEvents(new MoveSign(), this); - getServer().getPluginManager().registerEvents(new NameSign(), this); + //getServer().getPluginManager().registerEvents(new NameSign(), this); + AbstractMovecraftSign.register("Name", new NameSign(), true); getServer().getPluginManager().registerEvents(new PilotSign(), this); getServer().getPluginManager().registerEvents(new RelativeMoveSign(), this); getServer().getPluginManager().registerEvents(new ReleaseSign(), this); diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/NameSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/NameSign.java index 787f3711c..01366a239 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/NameSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/NameSign.java @@ -12,6 +12,7 @@ import org.bukkit.block.Block; import org.bukkit.block.BlockState; import org.bukkit.block.Sign; +import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; @@ -19,66 +20,77 @@ import org.bukkit.event.block.SignChangeEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Arrays; +import java.util.Optional; import java.util.stream.Collectors; -public final class NameSign implements Listener { - private static final String HEADER = "Name:"; - @EventHandler - public void onCraftDetect(@NotNull CraftDetectEvent event) { - Craft c = event.getCraft(); +public class NameSign extends AbstractCraftSign { - if (c instanceof PilotedCraft) { - PilotedCraft pilotedCraft = (PilotedCraft) c; - if (Settings.RequireNamePerm && !pilotedCraft.getPilot().hasPermission("movecraft.name.place")) - return; - } + public static final String NAME_SIGN_PERMISSION = "movecraft.name.place"; - World w = c.getWorld(); + public NameSign() { + super(NAME_SIGN_PERMISSION, true); + } - for (MovecraftLocation location : c.getHitBox()) { - var block = location.toBukkit(w).getBlock(); - if(!Tag.SIGNS.isTagged(block.getType())){ - continue; - } - BlockState state = block.getState(); - if (!(state instanceof Sign)) { - return; - } - Sign sign = (Sign) state; - if (sign.getLine(0).equalsIgnoreCase(HEADER)) { - String name = Arrays.stream(sign.getLines()).skip(1).filter(f -> f != null - && !f.trim().isEmpty()).collect(Collectors.joining(" ")); - c.setName(name); - return; - } + @Override + public boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action type, boolean sneaking) { + if (type == null) { + return !processingSuccessful; } + return !sneaking; + } + + @Override + protected boolean canPlayerUseSign(Action clickType, Sign sign, Player player) { + return !Settings.RequireNamePerm || super.canPlayerUseSign(clickType, sign, player); + } + + @Override + protected boolean isSignValid(Action clickType, Sign sign, Player player) { + return true; + } + + @Override + protected boolean internalProcessSign(Action clickType, Sign sign, Player player, Craft craft) { + return true; + } + + @Override + protected boolean internalProcessSign(Action clickType, Sign sign, Player player, Optional craft) { + return true; + } + + @Override + protected void onParentCraftBusy(Player player, Craft craft) { } - @EventHandler - public void onSignChange(@NotNull SignChangeEvent event) { - if (HEADER.equalsIgnoreCase(event.getLine(0)) - && Settings.RequireNamePerm && !event.getPlayer().hasPermission("movecraft.name.place")) { + @Override + protected void onCraftNotFound(Player player, Sign sign) { + } + + @Override + public boolean processSignChange(SignChangeEvent event) { + if (this.canPlayerUseSign(Action.RIGHT_CLICK_BLOCK, null, event.getPlayer())) { + // Nothing to do + return true; + } else { event.getPlayer().sendMessage(ChatUtils.MOVECRAFT_COMMAND_PREFIX + "Insufficient permissions"); event.setCancelled(true); + return false; } } - @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) - public void onSignClickEvent(@NotNull PlayerInteractEvent event) { - if (event.getAction() != Action.RIGHT_CLICK_BLOCK) { - return; - } - Block block = event.getClickedBlock(); - if (!(block.getState() instanceof Sign)) { - return; + @Override + public void onCraftDetect(CraftDetectEvent event, Sign sign) { + Craft craft = event.getCraft(); + if (craft != null && craft instanceof PilotedCraft pc) { + if (Settings.RequireNamePerm && !pc.getPilot().hasPermission(NAME_SIGN_PERMISSION)) + return; } - Sign sign = (Sign) block.getState(); - if (!ChatColor.stripColor(sign.getLine(0)).equalsIgnoreCase(HEADER)) { - return; - } - event.setCancelled(true); + craft.setName(Arrays.stream(sign.getLines()).skip(1).filter(f -> f != null + && !f.trim().isEmpty()).collect(Collectors.joining(" "))); } } From 95cbe5b760b3d6e88a4a6d13314c5c4b5aefb0c2 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Fri, 2 Aug 2024 17:02:38 +0200 Subject: [PATCH 010/122] organize imports --- .../net/countercraft/movecraft/sign/NameSign.java | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/NameSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/NameSign.java index 01366a239..2a3400f76 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/NameSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/NameSign.java @@ -1,25 +1,14 @@ package net.countercraft.movecraft.sign; -import net.countercraft.movecraft.MovecraftLocation; import net.countercraft.movecraft.config.Settings; import net.countercraft.movecraft.craft.Craft; import net.countercraft.movecraft.craft.PilotedCraft; import net.countercraft.movecraft.events.CraftDetectEvent; import net.countercraft.movecraft.util.ChatUtils; -import org.bukkit.ChatColor; -import org.bukkit.Tag; -import org.bukkit.World; -import org.bukkit.block.Block; -import org.bukkit.block.BlockState; import org.bukkit.block.Sign; import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; import org.bukkit.event.block.Action; import org.bukkit.event.block.SignChangeEvent; -import org.bukkit.event.player.PlayerInteractEvent; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Arrays; From f82bb7bd73a22c5c9baacc4fa72b63aa352da5cf Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Fri, 2 Aug 2024 17:02:48 +0200 Subject: [PATCH 011/122] reimplement release sign with new sign api --- .../movecraft/sign/ReleaseSign.java | 64 +++++++++++-------- 1 file changed, 38 insertions(+), 26 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/ReleaseSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/ReleaseSign.java index 91e9aa544..289db41d5 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/ReleaseSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/ReleaseSign.java @@ -3,37 +3,49 @@ import net.countercraft.movecraft.craft.Craft; import net.countercraft.movecraft.craft.CraftManager; import net.countercraft.movecraft.events.CraftReleaseEvent; -import org.bukkit.ChatColor; -import org.bukkit.block.BlockState; import org.bukkit.block.Sign; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; +import org.bukkit.entity.Player; import org.bukkit.event.block.Action; -import org.bukkit.event.player.PlayerInteractEvent; -import org.jetbrains.annotations.NotNull; +import org.bukkit.event.block.SignChangeEvent; +import org.jetbrains.annotations.Nullable; -public final class ReleaseSign implements Listener{ - private static final String HEADER = "Release"; +public class ReleaseSign extends AbstractCraftSign { - @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) - public void onSignClick(@NotNull PlayerInteractEvent event) { - if (event.getAction() != Action.RIGHT_CLICK_BLOCK) { - return; - } - BlockState state = event.getClickedBlock().getState(); - if (!(state instanceof Sign)) { - return; - } - Sign sign = (Sign) state; - if (!ChatColor.stripColor(sign.getLine(0)).equalsIgnoreCase(HEADER)) { - return; - } - event.setCancelled(true); - Craft craft = CraftManager.getInstance().getCraftByPlayer(event.getPlayer()); - if (craft == null) { - return; + public ReleaseSign() { + super(true); + } + + @Override + protected void onParentCraftBusy(Player player, Craft craft) { + + } + + @Override + protected void onCraftNotFound(Player player, Sign sign) { + + } + + @Override + public boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action type, boolean sneaking) { + if (processingSuccessful) { + return true; } + return !sneaking; + } + + @Override + protected boolean isSignValid(Action clickType, Sign sign, Player player) { + return true; + } + + @Override + public boolean processSignChange(SignChangeEvent event) { + return false; + } + + @Override + protected boolean internalProcessSign(Action clickType, Sign sign, Player player, Craft craft) { CraftManager.getInstance().release(craft, CraftReleaseEvent.Reason.PLAYER, false); + return true; } } From 4692881f48a6d96535d532e5eae99c7224a68e4c Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Fri, 2 Aug 2024 17:02:58 +0200 Subject: [PATCH 012/122] reimplement scuttle sign with new sign API --- .../movecraft/sign/ScuttleSign.java | 106 ++++++++++-------- 1 file changed, 59 insertions(+), 47 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/ScuttleSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/ScuttleSign.java index 39f9fd215..a579196a0 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/ScuttleSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/ScuttleSign.java @@ -2,82 +2,94 @@ import net.countercraft.movecraft.craft.Craft; import net.countercraft.movecraft.craft.CraftManager; +import net.countercraft.movecraft.craft.PilotedCraft; import net.countercraft.movecraft.craft.SinkingCraft; import net.countercraft.movecraft.craft.type.CraftType; import net.countercraft.movecraft.events.CraftScuttleEvent; import net.countercraft.movecraft.localisation.I18nSupport; -import net.countercraft.movecraft.util.MathUtils; import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.block.BlockState; import org.bukkit.block.Sign; -import org.bukkit.command.CommandSender; 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.player.PlayerInteractEvent; -import org.jetbrains.annotations.NotNull; +import org.bukkit.event.block.SignChangeEvent; +import org.jetbrains.annotations.Nullable; import static net.countercraft.movecraft.util.ChatUtils.MOVECRAFT_COMMAND_PREFIX; -public class ScuttleSign implements Listener { +public class ScuttleSign extends AbstractCraftSign { - private static final String HEADER = "Scuttle"; + public ScuttleSign() { + super("movecraft.commands.scuttle.others", true); + } - @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) - public void onSignClick(@NotNull PlayerInteractEvent event) { - if (event.getAction() != Action.RIGHT_CLICK_BLOCK) - return; - if(event.getClickedBlock() == null) - return; + @Override + protected void onParentCraftBusy(Player player, Craft craft) { - BlockState state = event.getClickedBlock().getState(); - if (!(state instanceof Sign)) { - return; - } - Sign sign = (Sign) state; - if (!ChatColor.stripColor(sign.getLine(0)).equalsIgnoreCase(HEADER)) { - return; - } - event.setCancelled(true); - Craft craft = CraftManager.getInstance().getCraftByPlayer(event.getPlayer()); - if (craft == null) { - if (!event.getPlayer().hasPermission("movecraft.commands.scuttle.others")) { - event.getPlayer().sendMessage(MOVECRAFT_COMMAND_PREFIX - + I18nSupport.getInternationalisedString("You must be piloting a craft")); - return; - } - craft = MathUtils.fastNearestCraftToLoc(CraftManager.getInstance().getCrafts(), - event.getClickedBlock().getLocation()); - if (craft == null) - return; + } + + @Override + protected void onCraftNotFound(Player player, Sign sign) { + player.sendMessage(MOVECRAFT_COMMAND_PREFIX + + I18nSupport.getInternationalisedString("You must be piloting a craft")); + } + + @Override + public boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action type, boolean sneaking) { + if (processingSuccessful) { + return true; } - scuttle(craft, event.getPlayer()); + return !sneaking; } - private void scuttle(Craft craft, CommandSender commandSender){ + @Override + protected boolean isSignValid(Action clickType, Sign sign, Player player) { + return true; + } + + @Override + public boolean processSignChange(SignChangeEvent event) { + return false; + } + + @Override + protected boolean canPlayerUseSignOn(Player player, Craft craft) { if(craft instanceof SinkingCraft) { - commandSender.sendMessage(MOVECRAFT_COMMAND_PREFIX + player.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("Scuttle - Craft Already Sinking")); - return; + return false; } - if(!commandSender.hasPermission("movecraft." + craft.getType().getStringProperty(CraftType.NAME) + if(!player.hasPermission("movecraft." + craft.getType().getStringProperty(CraftType.NAME) + ".scuttle")) { - commandSender.sendMessage(MOVECRAFT_COMMAND_PREFIX + player.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("Insufficient Permissions")); - return; + return false; + } + if (craft instanceof PilotedCraft pc) { + if (player == pc.getPilot()) { + return true; + } } + // Check for "can scuttle others" permission + if (this.optPermission.isPresent()) { + if (!player.hasPermission(this.optPermission.get())) { + player.sendMessage(MOVECRAFT_COMMAND_PREFIX + + I18nSupport.getInternationalisedString("You must be piloting a craft")); + } + } + return true; + } - CraftScuttleEvent e = new CraftScuttleEvent(craft, (Player) commandSender); + @Override + protected boolean internalProcessSign(Action clickType, Sign sign, Player player, Craft craft) { + CraftScuttleEvent e = new CraftScuttleEvent(craft, player); Bukkit.getServer().getPluginManager().callEvent(e); if(e.isCancelled()) - return; + return false; craft.setCruising(false); CraftManager.getInstance().sink(craft); - commandSender.sendMessage(MOVECRAFT_COMMAND_PREFIX + player.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("Scuttle - Scuttle Activated")); + return true; } } From 08611a92b7661a54b918d4c9f7563b496bf59509 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Fri, 2 Aug 2024 17:03:08 +0200 Subject: [PATCH 013/122] register release and scuttle signs --- .../src/main/java/net/countercraft/movecraft/Movecraft.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java b/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java index 082e97eb7..6226846ff 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java @@ -215,12 +215,14 @@ public void onEnable() { AbstractMovecraftSign.register("Name", new NameSign(), true); getServer().getPluginManager().registerEvents(new PilotSign(), this); getServer().getPluginManager().registerEvents(new RelativeMoveSign(), this); - getServer().getPluginManager().registerEvents(new ReleaseSign(), this); + //getServer().getPluginManager().registerEvents(new ReleaseSign(), this); + AbstractMovecraftSign.register("Release", new ReleaseSign(), true); getServer().getPluginManager().registerEvents(new RemoteSign(), this); getServer().getPluginManager().registerEvents(new SpeedSign(), this); getServer().getPluginManager().registerEvents(new SubcraftRotateSign(), this); getServer().getPluginManager().registerEvents(new TeleportSign(), this); - getServer().getPluginManager().registerEvents(new ScuttleSign(), this); + //getServer().getPluginManager().registerEvents(new ScuttleSign(), this); + AbstractMovecraftSign.register("Scuttle", new ScuttleSign(), true); getServer().getPluginManager().registerEvents(new CraftPilotListener(), this); getServer().getPluginManager().registerEvents(new CraftReleaseListener(), this); getServer().getPluginManager().registerEvents(new SignListener(), this); From d4f9cbb996e6bdb951dc80e1375f69623f35f547 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Fri, 2 Aug 2024 17:52:31 +0200 Subject: [PATCH 014/122] migrate Move and RMove signs --- .../net/countercraft/movecraft/Movecraft.java | 6 +- .../countercraft/movecraft/sign/MoveSign.java | 141 ++++++++++-------- .../movecraft/sign/RelativeMoveSign.java | 126 +++++----------- 3 files changed, 122 insertions(+), 151 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java b/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java index 6226846ff..dea2babcd 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java @@ -210,11 +210,13 @@ public void onEnable() { getServer().getPluginManager().registerEvents(new CruiseSign(), this); getServer().getPluginManager().registerEvents(new DescendSign(), this); getServer().getPluginManager().registerEvents(new HelmSign(), this); - getServer().getPluginManager().registerEvents(new MoveSign(), this); + //getServer().getPluginManager().registerEvents(new MoveSign(), this); + AbstractMovecraftSign.register("Move", new MoveSign(), true); //getServer().getPluginManager().registerEvents(new NameSign(), this); AbstractMovecraftSign.register("Name", new NameSign(), true); getServer().getPluginManager().registerEvents(new PilotSign(), this); - getServer().getPluginManager().registerEvents(new RelativeMoveSign(), this); + //getServer().getPluginManager().registerEvents(new RelativeMoveSign(), this); + AbstractMovecraftSign.register("RMove", new RelativeMoveSign(), true); //getServer().getPluginManager().registerEvents(new ReleaseSign(), this); AbstractMovecraftSign.register("Release", new ReleaseSign(), true); getServer().getPluginManager().registerEvents(new RemoteSign(), this); diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/MoveSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/MoveSign.java index 37c0f00d4..372c6e580 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/MoveSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/MoveSign.java @@ -1,80 +1,99 @@ package net.countercraft.movecraft.sign; -import net.countercraft.movecraft.craft.CraftManager; +import net.countercraft.movecraft.craft.Craft; import net.countercraft.movecraft.craft.type.CraftType; import net.countercraft.movecraft.localisation.I18nSupport; import org.bukkit.ChatColor; -import org.bukkit.block.BlockState; import org.bukkit.block.Sign; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; +import org.bukkit.entity.Player; import org.bukkit.event.block.Action; -import org.bukkit.event.player.PlayerInteractEvent; -import org.jetbrains.annotations.NotNull; +import org.bukkit.event.block.SignChangeEvent; +import org.jetbrains.annotations.Nullable; -public final class MoveSign implements Listener{ - private static final String HEADER = "Move:"; +public class MoveSign extends AbstractCraftSign { - @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) - public void onSignClick(@NotNull PlayerInteractEvent event) { - if (event.getAction() != Action.RIGHT_CLICK_BLOCK) { - return; + public MoveSign() { + super(null, false); + } + + @Override + protected void onParentCraftBusy(Player player, Craft craft) { + player.sendMessage(I18nSupport.getInternationalisedString("Detection - Parent Craft is busy")); + } + + @Override + protected void onCraftNotFound(Player player, Sign sign) { + + } + + @Override + public boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action type, boolean sneaking) { + if (processingSuccessful) { + return true; } - BlockState state = event.getClickedBlock().getState(); - if (!(state instanceof Sign)) { - return; + return !sneaking; + } + + @Override + protected boolean isSignValid(Action clickType, Sign sign, Player player) { + String[] numbers = ChatColor.stripColor(sign.getLine(1)).split(","); + if (numbers.length != 3) { + return false; } - Sign sign = (Sign) state; - if (!ChatColor.stripColor(sign.getLine(0)).equalsIgnoreCase(HEADER)) { - return; + for (String s : numbers) { + try { + Integer.parseInt(s); + } catch(NumberFormatException nfe) { + return false; + } } - event.setCancelled(true); - if (CraftManager.getInstance().getCraftByPlayer(event.getPlayer()) == null) { - return; + return true; + } + + @Override + public boolean processSignChange(SignChangeEvent event) { + return false; + } + + @Override + protected boolean internalProcessSign(Action clickType, Sign sign, Player player, Craft craft) { + if (!craft.getType().getBoolProperty(CraftType.CAN_STATIC_MOVE)) { + return false; } - /*Long time = timeMap.get(event.getPlayer()); - if (time != null) { - long ticksElapsed = (System.currentTimeMillis() - time) / 50; - Craft craft = CraftManager.getInstance().getCraftByPlayer(event.getPlayer()); - // if the craft should go slower underwater, make time pass - // more slowly there - if (craft.getType().getHalfSpeedUnderwater() && craft.getMinY() < craft.getW().getSeaLevel()) { - ticksElapsed = ticksElapsed >> 1; - } - if (Math.abs(ticksElapsed) < CraftManager.getInstance().getCraftByPlayer(event.getPlayer()).getType().getTickCooldown()) { - event.setCancelled(true); - return; - } - }*/ + if (!player.hasPermission("movecraft." + craft.getType().getStringProperty(CraftType.NAME) + ".move")) { + player.sendMessage( + I18nSupport.getInternationalisedString("Insufficient Permissions")); + return false; + } + String[] numbers = ChatColor.stripColor(sign.getLine(1)).split(","); int dx = Integer.parseInt(numbers[0]); int dy = Integer.parseInt(numbers[1]); int dz = Integer.parseInt(numbers[2]); - int maxMove = CraftManager.getInstance().getCraftByPlayer(event.getPlayer()).getType().getIntProperty(CraftType.MAX_STATIC_MOVE); - - if (dx > maxMove) - dx = maxMove; - if (dx < 0 - maxMove) - dx = 0 - maxMove; - if (dy > maxMove) - dy = maxMove; - if (dy < 0 - maxMove) - dy = 0 - maxMove; - if (dz > maxMove) - dz = maxMove; - if (dz < 0 - maxMove) - dz = 0 - maxMove; - - if (!event.getPlayer().hasPermission("movecraft." + CraftManager.getInstance().getCraftByPlayer(event.getPlayer()).getType().getStringProperty(CraftType.NAME) + ".move")) { - event.getPlayer().sendMessage( - I18nSupport.getInternationalisedString("Insufficient Permissions")); - return; - } - if (CraftManager.getInstance().getCraftByPlayer(event.getPlayer()).getType().getBoolProperty(CraftType.CAN_STATIC_MOVE)) { - CraftManager.getInstance().getCraftByPlayer(event.getPlayer()).translate(dx, dy, dz); - //timeMap.put(event.getPlayer(), System.currentTimeMillis()); - CraftManager.getInstance().getCraftByPlayer(event.getPlayer()).setLastCruiseUpdate(System.currentTimeMillis()); - } + + return translateCraft(sign.getRawData(), dy, dy, dz, craft); + } + + protected boolean translateCraft(final byte signDataRaw, int dxRaw, int dyRaw, int dzRaw, Craft craft) { + int maxMove = craft.getType().getIntProperty(CraftType.MAX_STATIC_MOVE); + + if (dxRaw > maxMove) + dxRaw = maxMove; + if (dxRaw < 0 - maxMove) + dxRaw = 0 - maxMove; + if (dyRaw > maxMove) + dyRaw = maxMove; + if (dyRaw < 0 - maxMove) + dyRaw = 0 - maxMove; + if (dzRaw > maxMove) + dzRaw = maxMove; + if (dzRaw < 0 - maxMove) + dzRaw = 0 - maxMove; + + craft.translate(dxRaw, dyRaw, dzRaw); + //timeMap.put(event.getPlayer(), System.currentTimeMillis()); + craft.setLastCruiseUpdate(System.currentTimeMillis()); + + return true; } } diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/RelativeMoveSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/RelativeMoveSign.java index 2e187d3fb..fe5f22253 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/RelativeMoveSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/RelativeMoveSign.java @@ -1,113 +1,63 @@ package net.countercraft.movecraft.sign; -import net.countercraft.movecraft.craft.CraftManager; +import net.countercraft.movecraft.craft.Craft; import net.countercraft.movecraft.craft.type.CraftType; -import net.countercraft.movecraft.localisation.I18nSupport; -import org.bukkit.ChatColor; -import org.bukkit.block.Block; -import org.bukkit.block.Sign; -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.PlayerInteractEvent; -import org.jetbrains.annotations.NotNull; -public final class RelativeMoveSign implements Listener{ - private static final String HEADER = "RMove:"; +public class RelativeMoveSign extends MoveSign { - @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) - public void onSignClick(@NotNull PlayerInteractEvent event) { - if (event.getAction() != Action.RIGHT_CLICK_BLOCK) { - return; - } - Block block = event.getClickedBlock(); - if (!(block.getState() instanceof Sign)) { - return; - } - Sign sign = (Sign) event.getClickedBlock().getState(); - if (!ChatColor.stripColor(sign.getLine(0)).equalsIgnoreCase(HEADER)) { - return; - } - event.setCancelled(true); - if (CraftManager.getInstance().getCraftByPlayer(event.getPlayer()) == null) { - return; - } - /*Long time = timeMap.get(event.getPlayer()); - if (time != null) { - long ticksElapsed = (System.currentTimeMillis() - time) / 50; - Craft craft = CraftManager.getInstance().getCraftByPlayer(event.getPlayer()); - // if the craft should go slower underwater, make time pass - // more slowly there - if (craft.getType().getHalfSpeedUnderwater() && craft.getMinY() < craft.getW().getSeaLevel()) { - ticksElapsed = ticksElapsed >> 1; - } + public RelativeMoveSign() { + super(); + } - if (Math.abs(ticksElapsed) < CraftManager.getInstance().getCraftByPlayer(event.getPlayer()).getType().getTickCooldown()) { - event.setCancelled(true); - return; - } - }*/ - String[] numbers = ChatColor.stripColor(sign.getLine(1)).split(","); - int dLeftRight = Integer.parseInt(numbers[0]); // negative = - // left, - // positive = - // right - int dy = Integer.parseInt(numbers[1]); - int dBackwardForward = Integer.parseInt(numbers[2]); // negative - // = - // backwards, - // positive - // = - // forwards - int maxMove = CraftManager.getInstance().getCraftByPlayer(event.getPlayer()).getType().getIntProperty(CraftType.MAX_STATIC_MOVE); + @Override + protected boolean translateCraft(byte signDataRaw, int dxRaw, int dyRaw, int dzRaw, Craft craft) { + final int maxMove = craft.getType().getIntProperty(CraftType.MAX_STATIC_MOVE); - if (dLeftRight > maxMove) - dLeftRight = maxMove; - if (dLeftRight < -maxMove) - dLeftRight = -maxMove; - if (dy > maxMove) - dy = maxMove; - if (dy < -maxMove) - dy = -maxMove; - if (dBackwardForward > maxMove) - dBackwardForward = maxMove; - if (dBackwardForward < -maxMove) - dBackwardForward = -maxMove; + // X: Left/Right + // Y: Up/Down + // Z: Forward/Backward + + if (dxRaw > maxMove) + dxRaw = maxMove; + if (dxRaw < -maxMove) + dxRaw = -maxMove; + if (dyRaw > maxMove) + dyRaw = maxMove; + if (dyRaw < -maxMove) + dyRaw = -maxMove; + if (dzRaw > maxMove) + dzRaw = maxMove; + if (dzRaw < -maxMove) + dzRaw = -maxMove; int dx = 0; int dz = 0; - switch (sign.getRawData()) { + switch (signDataRaw) { case 0x3: // North - dx = dLeftRight; - dz = -dBackwardForward; + dx = dxRaw; + dz = -dzRaw; break; case 0x2: // South - dx = -dLeftRight; - dz = dBackwardForward; + dx = -dxRaw; + dz = dzRaw; break; case 0x4: // East - dx = dBackwardForward; - dz = dLeftRight; + dx = dzRaw; + dz = dxRaw; break; case 0x5: // West - dx = -dBackwardForward; - dz = -dLeftRight; + dx = -dzRaw; + dz = -dxRaw; break; } - if (!event.getPlayer().hasPermission("movecraft." + CraftManager.getInstance().getCraftByPlayer(event.getPlayer()).getType().getStringProperty(CraftType.NAME) + ".move")) { - event.getPlayer().sendMessage( - I18nSupport.getInternationalisedString("Insufficient Permissions")); - return; - } - if (CraftManager.getInstance().getCraftByPlayer(event.getPlayer()).getType().getBoolProperty(CraftType.CAN_STATIC_MOVE)) { - CraftManager.getInstance().getCraftByPlayer(event.getPlayer()).translate(dx, dy, dz); - //timeMap.put(event.getPlayer(), System.currentTimeMillis()); - CraftManager.getInstance().getCraftByPlayer(event.getPlayer()).setLastCruiseUpdate(System.currentTimeMillis()); - } + craft.translate(dx, dyRaw, dz); + //timeMap.put(event.getPlayer(), System.currentTimeMillis()); + craft.setLastCruiseUpdate(System.currentTimeMillis()); + + return true; } } From 8f927992a9a6d631c365f7d21a48d1e7c5c91a3b Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Sun, 4 Aug 2024 21:53:50 +0200 Subject: [PATCH 015/122] move perm check to canPlayerUseOn --- .../net/countercraft/movecraft/sign/MoveSign.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/MoveSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/MoveSign.java index 372c6e580..bba302f44 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/MoveSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/MoveSign.java @@ -56,8 +56,8 @@ public boolean processSignChange(SignChangeEvent event) { } @Override - protected boolean internalProcessSign(Action clickType, Sign sign, Player player, Craft craft) { - if (!craft.getType().getBoolProperty(CraftType.CAN_STATIC_MOVE)) { + protected boolean canPlayerUseSignOn(Player player, Craft craft) { + if (!super.canPlayerUseSignOn(player, craft)) { return false; } if (!player.hasPermission("movecraft." + craft.getType().getStringProperty(CraftType.NAME) + ".move")) { @@ -65,6 +65,14 @@ protected boolean internalProcessSign(Action clickType, Sign sign, Player player I18nSupport.getInternationalisedString("Insufficient Permissions")); return false; } + return true; + } + + @Override + protected boolean internalProcessSign(Action clickType, Sign sign, Player player, Craft craft) { + if (!craft.getType().getBoolProperty(CraftType.CAN_STATIC_MOVE)) { + return false; + } String[] numbers = ChatColor.stripColor(sign.getLine(1)).split(","); int dx = Integer.parseInt(numbers[0]); From 81cf5a9e0f196ac3571a176ef31aa20d5e87efca Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Sun, 4 Aug 2024 21:54:33 +0200 Subject: [PATCH 016/122] migrate helm sign it is a bit ugly to register it twice but i think that's just alright. Alternatively we could just create a empty sign change listener for the [Helm] stuff and roll with that --- .../net/countercraft/movecraft/Movecraft.java | 4 +- .../countercraft/movecraft/sign/HelmSign.java | 105 +++++++++++++----- 2 files changed, 79 insertions(+), 30 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java b/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java index dea2babcd..a0ab0c6de 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java @@ -209,7 +209,9 @@ public void onEnable() { getServer().getPluginManager().registerEvents(new CraftSign(), this); getServer().getPluginManager().registerEvents(new CruiseSign(), this); getServer().getPluginManager().registerEvents(new DescendSign(), this); - getServer().getPluginManager().registerEvents(new HelmSign(), this); + //getServer().getPluginManager().registerEvents(new HelmSign(), this); + AbstractMovecraftSign.register("[Helm]", new HelmSign(), true); + AbstractMovecraftSign.register(HelmSign.PRETTY_HEADER, new HelmSign(), true); //getServer().getPluginManager().registerEvents(new MoveSign(), this); AbstractMovecraftSign.register("Move", new MoveSign(), true); //getServer().getPluginManager().registerEvents(new NameSign(), this); diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/HelmSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/HelmSign.java index 74eef63fa..0f04900cb 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/HelmSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/HelmSign.java @@ -9,6 +9,7 @@ import org.bukkit.ChatColor; import org.bukkit.block.BlockState; import org.bukkit.block.Sign; +import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; @@ -16,48 +17,80 @@ import org.bukkit.event.block.SignChangeEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; -public final class HelmSign implements Listener { +public class HelmSign extends AbstractCraftSign { + + public static final String[] PRETTY_LINES = new String[] { + "\\ || /", + "\\ || /", + "/ || \\" + }; + public static final String PRETTY_HEADER = PRETTY_LINES[0]; + + public HelmSign() { + super(false); + } @EventHandler public void onSignChange(SignChangeEvent event){ if (!ChatColor.stripColor(event.getLine(0)).equalsIgnoreCase("[helm]")) { return; } + for (int i = 0; i < PRETTY_LINES.length && i < event.getLines().length; i++) { + event.setLine(i, PRETTY_LINES[i]); + } + } + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void onSignClick(@NotNull PlayerInteractEvent event) { + + + } + + @Override + protected void onParentCraftBusy(Player player, Craft craft) { + + } + + @Override + protected void onCraftNotFound(Player player, Sign sign) { + + } + + @Override + public boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action type, boolean sneaking) { + return !sneaking; + } + + @Override + protected boolean isSignValid(Action clickType, Sign sign, Player player) { + // Nothing to check here honestly... + return true; + } + + @Override + public boolean processSignChange(SignChangeEvent event) { + if (!ChatColor.stripColor(event.getLine(0)).equalsIgnoreCase("[helm]")) { + return true; + } event.setLine(0, "\\ || /"); event.setLine(1, "== =="); event.setLine(2, "/ || \\"); + return true; } - @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) - public void onSignClick(@NotNull PlayerInteractEvent event) { + @Override + protected boolean internalProcessSign(Action clickType, Sign sign, Player player, Craft craft) { MovecraftRotation rotation; - if (event.getAction() == Action.RIGHT_CLICK_BLOCK) { + if (clickType == Action.RIGHT_CLICK_BLOCK) { rotation = MovecraftRotation.CLOCKWISE; - }else if(event.getAction() == Action.LEFT_CLICK_BLOCK){ + }else if(clickType == Action.LEFT_CLICK_BLOCK){ rotation = MovecraftRotation.ANTICLOCKWISE; }else{ - return; - } - BlockState state = event.getClickedBlock().getState(); - if (!(state instanceof Sign)) { - return; - } - Sign sign = (Sign) state; - if (!(ChatColor.stripColor(sign.getLine(0)).equals("\\ || /") && - ChatColor.stripColor(sign.getLine(1)).equals("== ==") && - ChatColor.stripColor(sign.getLine(2)).equals("/ || \\"))) { - return; - } - event.setCancelled(true); - Craft craft = CraftManager.getInstance().getCraftByPlayer(event.getPlayer()); - if (craft == null) { - return; - } - if (!event.getPlayer().hasPermission("movecraft." + craft.getType().getStringProperty(CraftType.NAME) + ".rotate")) { - event.getPlayer().sendMessage(I18nSupport.getInternationalisedString("Insufficient Permissions")); - return; + return false; } + /*Long time = timeMap.get(event.getPlayer()); if (time != null) { long ticksElapsed = (System.currentTimeMillis() - time) / 50; @@ -74,13 +107,14 @@ public void onSignClick(@NotNull PlayerInteractEvent event) { } }*/ - if(!MathUtils.locIsNearCraftFast(craft, MathUtils.bukkit2MovecraftLoc(event.getPlayer().getLocation()))) - return; + if(!MathUtils.locIsNearCraftFast(craft, MathUtils.bukkit2MovecraftLoc(player.getLocation()))) + return false; + // TODO: Why was this used before? CraftManager.getInstance().getCraftByPlayer(event.getPlayer())... The craft variable did exist, so why don't use it? if (craft.getType().getBoolProperty(CraftType.ROTATE_AT_MIDPOINT)) { - CraftManager.getInstance().getCraftByPlayer(event.getPlayer()).rotate(rotation, craft.getHitBox().getMidPoint()); + craft.rotate(rotation, craft.getHitBox().getMidPoint()); } else { - CraftManager.getInstance().getCraftByPlayer(event.getPlayer()).rotate(rotation, MathUtils.bukkit2MovecraftLoc(sign.getLocation())); + craft.rotate(rotation, MathUtils.bukkit2MovecraftLoc(sign.getLocation())); } //timeMap.put(event.getPlayer(), System.currentTimeMillis()); @@ -93,5 +127,18 @@ public void onSignClick(@NotNull PlayerInteractEvent event) { curTickCooldown = curTickCooldown * 2;*/ //CraftManager.getInstance().getCraftByPlayer(event.getPlayer()).setCurTickCooldown(curTickCooldown); // lose half your speed when turning + return false; + } + + @Override + protected boolean canPlayerUseSignOn(Player player, Craft craft) { + if (super.canPlayerUseSignOn(player, craft)) { + if (!player.hasPermission("movecraft." + craft.getType().getStringProperty(CraftType.NAME) + ".rotate")) { + player.sendMessage(I18nSupport.getInternationalisedString("Insufficient Permissions")); + return false; + } + return true; + } + return false; } } From 99aa14684c43011bdc38cc3a0ea3ed1dfa1f18d1 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Sun, 4 Aug 2024 21:57:51 +0200 Subject: [PATCH 017/122] rename method to "onCraftisBusy" is it isn't always a parent craft but the craft that the sign is on --- .../main/java/net/countercraft/movecraft/sign/HelmSign.java | 2 +- .../main/java/net/countercraft/movecraft/sign/MoveSign.java | 2 +- .../main/java/net/countercraft/movecraft/sign/NameSign.java | 2 +- .../java/net/countercraft/movecraft/sign/ReleaseSign.java | 2 +- .../java/net/countercraft/movecraft/sign/ScuttleSign.java | 2 +- .../net/countercraft/movecraft/sign/AbstractCraftSign.java | 4 ++-- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/HelmSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/HelmSign.java index 0f04900cb..f0efdbbbb 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/HelmSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/HelmSign.java @@ -49,7 +49,7 @@ public void onSignClick(@NotNull PlayerInteractEvent event) { } @Override - protected void onParentCraftBusy(Player player, Craft craft) { + protected void onCraftIsBusy(Player player, Craft craft) { } diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/MoveSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/MoveSign.java index bba302f44..a51a38036 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/MoveSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/MoveSign.java @@ -17,7 +17,7 @@ public MoveSign() { } @Override - protected void onParentCraftBusy(Player player, Craft craft) { + protected void onCraftIsBusy(Player player, Craft craft) { player.sendMessage(I18nSupport.getInternationalisedString("Detection - Parent Craft is busy")); } diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/NameSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/NameSign.java index 2a3400f76..e80bb50f7 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/NameSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/NameSign.java @@ -52,7 +52,7 @@ protected boolean internalProcessSign(Action clickType, Sign sign, Player player } @Override - protected void onParentCraftBusy(Player player, Craft craft) { + protected void onCraftIsBusy(Player player, Craft craft) { } @Override diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/ReleaseSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/ReleaseSign.java index 289db41d5..dacd3b1f1 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/ReleaseSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/ReleaseSign.java @@ -16,7 +16,7 @@ public ReleaseSign() { } @Override - protected void onParentCraftBusy(Player player, Craft craft) { + protected void onCraftIsBusy(Player player, Craft craft) { } diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/ScuttleSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/ScuttleSign.java index a579196a0..f50ac2cf3 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/ScuttleSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/ScuttleSign.java @@ -23,7 +23,7 @@ public ScuttleSign() { } @Override - protected void onParentCraftBusy(Player player, Craft craft) { + protected void onCraftIsBusy(Player player, Craft craft) { } diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftSign.java index 7df76eef7..6d86c382a 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftSign.java @@ -50,7 +50,7 @@ public boolean processSignClick(Action clickType, Sign sign, Player player) { if (craft.get() instanceof PlayerCraft pc) { if (!pc.isNotProcessing() && !this.ignoreCraftIsBusy) { - this.onParentCraftBusy(player, craft.get()); + this.onCraftIsBusy(player, craft.get()); return false; } } @@ -66,7 +66,7 @@ protected boolean internalProcessSign(Action clickType, Sign sign, Player player return false; } - protected abstract void onParentCraftBusy(Player player, Craft craft); + protected abstract void onCraftIsBusy(Player player, Craft craft); protected boolean canPlayerUseSignOn(Player player, Craft craft) { if (craft instanceof PilotedCraft pc) { From a66a0af155e95fbdfc2acbba0ba9a831640ec8cf Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Sun, 4 Aug 2024 22:02:43 +0200 Subject: [PATCH 018/122] allow double colons in idents --- .../src/main/java/net/countercraft/movecraft/Movecraft.java | 6 +++--- .../countercraft/movecraft/sign/AbstractMovecraftSign.java | 3 +++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java b/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java index a0ab0c6de..6b574cc8d 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java @@ -213,12 +213,12 @@ public void onEnable() { AbstractMovecraftSign.register("[Helm]", new HelmSign(), true); AbstractMovecraftSign.register(HelmSign.PRETTY_HEADER, new HelmSign(), true); //getServer().getPluginManager().registerEvents(new MoveSign(), this); - AbstractMovecraftSign.register("Move", new MoveSign(), true); + AbstractMovecraftSign.register("Move:", new MoveSign(), true); //getServer().getPluginManager().registerEvents(new NameSign(), this); - AbstractMovecraftSign.register("Name", new NameSign(), true); + AbstractMovecraftSign.register("Name:", new NameSign(), true); getServer().getPluginManager().registerEvents(new PilotSign(), this); //getServer().getPluginManager().registerEvents(new RelativeMoveSign(), this); - AbstractMovecraftSign.register("RMove", new RelativeMoveSign(), true); + AbstractMovecraftSign.register("RMove:", new RelativeMoveSign(), true); //getServer().getPluginManager().registerEvents(new ReleaseSign(), this); AbstractMovecraftSign.register("Release", new ReleaseSign(), true); getServer().getPluginManager().registerEvents(new RemoteSign(), this); diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java index baab33654..c48a95e5c 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java @@ -26,6 +26,9 @@ public static Optional tryGet(final String ident) { String identToUse = ident.toUpperCase(); if (identToUse.indexOf(":") >= 0) { identToUse = identToUse.split(":")[0]; + if (ident.contains(":")) { + identToUse = identToUse + ":"; + } } return Optional.ofNullable(SIGNS.getOrDefault(identToUse, null)); } From c4623f539ef50af7a73ad5de0e2be281ef96cc5f Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Sun, 4 Aug 2024 22:06:26 +0200 Subject: [PATCH 019/122] add comment for later --- .../src/main/java/net/countercraft/movecraft/Movecraft.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java b/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java index 6b574cc8d..ff4b79a84 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java @@ -202,6 +202,8 @@ public void onEnable() { getCommand("crafttype").setExecutor(new CraftTypeCommand()); getCommand("craftinfo").setExecutor(new CraftInfoCommand()); + // Naming scheme: If it has parameters, append a double colon except if it is a subcraft + // Parameters follow on the following lines getServer().getPluginManager().registerEvents(new BlockListener(), this); getServer().getPluginManager().registerEvents(new PlayerListener(), this); getServer().getPluginManager().registerEvents(new ChunkManager(), this); From 9575095f39d53983d05e2889b76b591f7fce682b Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Sat, 10 Aug 2024 12:06:51 +0200 Subject: [PATCH 020/122] make sign listener abstract and add abstraction layer to signs --- .../movecraft/sign/AbstractSignListener.java | 70 +++++++++++++------ 1 file changed, 50 insertions(+), 20 deletions(-) rename Movecraft/src/main/java/net/countercraft/movecraft/listener/SignListener.java => api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java (51%) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/listener/SignListener.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java similarity index 51% rename from Movecraft/src/main/java/net/countercraft/movecraft/listener/SignListener.java rename to api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java index 36bdcbf6b..b20f46447 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/listener/SignListener.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java @@ -1,12 +1,12 @@ -package net.countercraft.movecraft.listener; +package net.countercraft.movecraft.sign; import net.countercraft.movecraft.events.CraftDetectEvent; import net.countercraft.movecraft.events.SignTranslateEvent; -import net.countercraft.movecraft.sign.AbstractCraftSign; -import net.countercraft.movecraft.sign.AbstractMovecraftSign; -import org.bukkit.ChatColor; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; import org.bukkit.World; import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; import org.bukkit.block.BlockState; import org.bukkit.block.Sign; import org.bukkit.event.EventHandler; @@ -15,20 +15,53 @@ import org.bukkit.event.block.SignChangeEvent; import org.bukkit.event.player.PlayerInteractEvent; -public class SignListener implements Listener { +import java.util.List; +import java.util.function.BiConsumer; +import java.util.function.Function; + +public abstract class AbstractSignListener implements Listener { + + public static AbstractSignListener INSTANCE; + + public AbstractSignListener() { + INSTANCE = this; + } + + public static record SignWrapper( + Sign block, + Function getLine, + List lines, + BiConsumer setLine, + BlockFace facing + ) { + public Component line(int index) { + if (index >= lines.size() || index < 0) { + throw new IndexOutOfBoundsException(); + } + return getLine().apply(index); + } + + public void line(int index, Component component) { + setLine.accept(index, component); + } + } + + public abstract SignWrapper[] getSignWrappers(Sign sign); + protected abstract SignWrapper getSignWrapper(Sign sign, SignChangeEvent signChangeEvent); + protected abstract SignWrapper getSignWrapper(Sign sign, PlayerInteractEvent interactEvent); @EventHandler(ignoreCancelled = true, priority = EventPriority.LOW) public void onCraftDetect(CraftDetectEvent event) { - final World world = event.getCraft().getWorld();; + final World world = event.getCraft().getWorld(); event.getCraft().getHitBox().forEach( (mloc) -> { Block block = mloc.toBukkit(world).getBlock(); BlockState state = block.getState(); if (state instanceof Sign sign) { - String ident = sign.getLines()[0]; - AbstractCraftSign.tryGetCraftSign(ident).ifPresent(acs -> { - acs.onCraftDetect(event, sign); - }); + for (SignWrapper wrapper : this.getSignWrappers(sign)) { + String ident = PlainTextComponentSerializer.plainText().serialize(wrapper.line(0)); + AbstractCraftSign.tryGetCraftSign(ident).ifPresent(acs -> acs.onCraftDetect(event, wrapper)); + } } } ); @@ -37,23 +70,19 @@ public void onCraftDetect(CraftDetectEvent event) { @EventHandler(ignoreCancelled = true, priority = EventPriority.LOW) public void onSignTranslate(SignTranslateEvent event) { String ident = event.getLine(0); - AbstractCraftSign.tryGetCraftSign(ident).ifPresent(acs -> { - acs.onSignMovedByCraft(event); - }); + AbstractCraftSign.tryGetCraftSign(ident).ifPresent(acs -> acs.onSignMovedByCraft(event)); } @EventHandler(ignoreCancelled = true, priority = EventPriority.LOW) public void onSignChange(SignChangeEvent event) { Block block = event.getBlock(); - if (block == null) { - return; - } BlockState state = block.getState(); if (state instanceof Sign sign) { - final String signHeader = ChatColor.stripColor(event.getLines()[0]); + SignWrapper wrapper = this.getSignWrapper(sign, event); + final String signHeader = PlainTextComponentSerializer.plainText().serialize(wrapper.line(0)); AbstractMovecraftSign.tryGet(signHeader).ifPresent(ams -> { - boolean success = ams.processSignChange(event); + boolean success = ams.processSignChange(event, wrapper); if (ams.shouldCancelEvent(success, null, event.getPlayer().isSneaking())) { event.setCancelled(true); } @@ -69,9 +98,10 @@ public void onSignClick(PlayerInteractEvent event) { } BlockState state = block.getState(); if (state instanceof Sign sign) { - final String signHeader = ChatColor.stripColor(sign.getLines()[0]); + SignWrapper wrapper = this.getSignWrapper(sign, event); + final String signHeader = PlainTextComponentSerializer.plainText().serialize(wrapper.line(0)); AbstractMovecraftSign.tryGet(signHeader).ifPresent(ams -> { - boolean success = ams.processSignClick(event.getAction(), sign, event.getPlayer()); + boolean success = ams.processSignClick(event.getAction(), wrapper, event.getPlayer()); if (ams.shouldCancelEvent(success, event.getAction(), event.getPlayer().isSneaking())) { event.setCancelled(true); } From 2997b1e05e37bd28f79ab4cf8ba19a2f9c0f4cd9 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Sat, 10 Aug 2024 12:07:09 +0200 Subject: [PATCH 021/122] initialize sign listener like the version specific stuff --- .../java/net/countercraft/movecraft/Movecraft.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java b/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java index ff4b79a84..7ee001732 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java @@ -28,7 +28,7 @@ import net.countercraft.movecraft.features.contacts.ContactsSign; import net.countercraft.movecraft.features.status.StatusManager; import net.countercraft.movecraft.features.status.StatusSign; -import net.countercraft.movecraft.listener.*; +import net.countercraft.movecraft.compat.v1_21.listener.*; import net.countercraft.movecraft.localisation.I18nSupport; import net.countercraft.movecraft.mapUpdater.MapUpdateManager; import net.countercraft.movecraft.processing.WorldManager; @@ -127,6 +127,12 @@ public void onEnable() { getLogger().warning("Falling back to bukkit teleportation provider."); } } + + final Class signListenerClass = Class.forName("net.countercraft.movecraft.compat." + WorldHandler.getPackageName(minecraftVersion) + ".SignListener"); + if (AbstractSignListener.class.isAssignableFrom(signListenerClass)) { + AbstractSignListener abstractSignListener = (AbstractSignListener) signListenerClass.getConstructor().newInstance(); + getServer().getPluginManager().registerEvents(abstractSignListener, this); + } } catch (final Exception e) { e.printStackTrace(); @@ -231,7 +237,8 @@ public void onEnable() { AbstractMovecraftSign.register("Scuttle", new ScuttleSign(), true); getServer().getPluginManager().registerEvents(new CraftPilotListener(), this); getServer().getPluginManager().registerEvents(new CraftReleaseListener(), this); - getServer().getPluginManager().registerEvents(new SignListener(), this); + // Moved to compat section! + //getServer().getPluginManager().registerEvents(new SignListener(), this); var contactsManager = new ContactsManager(); contactsManager.runTaskTimerAsynchronously(this, 0, 20); From 604abebd4a5e97d39741e1e62128eb4fc0e087f4 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Sat, 10 Aug 2024 12:07:30 +0200 Subject: [PATCH 022/122] refactor sign base classes to use the abstraction class --- .../movecraft/sign/AbstractCraftSign.java | 31 ++++++----------- .../movecraft/sign/AbstractCruiseSign.java | 34 ++++++++++++------- .../movecraft/sign/AbstractMovecraftSign.java | 23 ++++++------- 3 files changed, 42 insertions(+), 46 deletions(-) diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftSign.java index 6d86c382a..ca2c2cfbb 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftSign.java @@ -5,11 +5,10 @@ import net.countercraft.movecraft.craft.PlayerCraft; import net.countercraft.movecraft.events.CraftDetectEvent; import net.countercraft.movecraft.events.SignTranslateEvent; -import net.countercraft.movecraft.util.MathUtils; -import org.bukkit.block.Sign; import org.bukkit.entity.Player; import org.bukkit.event.block.Action; +import javax.annotation.Nullable; import java.util.Optional; public abstract class AbstractCraftSign extends AbstractMovecraftSign { @@ -35,7 +34,7 @@ public AbstractCraftSign(final String permission, boolean ignoreCraftIsBusy) { // Return true to cancel the event @Override - public boolean processSignClick(Action clickType, Sign sign, Player player) { + public boolean processSignClick(Action clickType, AbstractSignListener.SignWrapper sign, Player player) { if (!this.isSignValid(clickType, sign, player)) { return false; } @@ -59,7 +58,10 @@ public boolean processSignClick(Action clickType, Sign sign, Player player) { } @Override - protected boolean internalProcessSign(Action clickType, Sign sign, Player player, Optional craft) { + protected boolean internalProcessSign(Action clickType, AbstractSignListener.SignWrapper sign, Player player, Optional craft) { + if (craft.isEmpty()) { + throw new IllegalStateException("Somehow craft is not set here. It should always be present here!"); + } if (this.canPlayerUseSignOn(player, craft.get())) { return this.internalProcessSign(clickType, sign, player, craft.get()); } @@ -68,27 +70,16 @@ protected boolean internalProcessSign(Action clickType, Sign sign, Player player protected abstract void onCraftIsBusy(Player player, Craft craft); - protected boolean canPlayerUseSignOn(Player player, Craft craft) { + protected boolean canPlayerUseSignOn(Player player, @Nullable Craft craft) { if (craft instanceof PilotedCraft pc) { return pc.getPilot() == player; } return true; } - protected abstract void onCraftNotFound(Player player, Sign sign); - - protected boolean canPlayerUseSign(Action clickType, Sign sign, Player player) { - if (this.optPermission.isPresent()) { - return player.hasPermission(this.optPermission.get()); - } - return true; - } - - protected Optional getCraft(Sign sign) { - return Optional.ofNullable(MathUtils.getCraftByPersistentBlockData(sign.getLocation())); - } + protected abstract void onCraftNotFound(Player player, AbstractSignListener.SignWrapper sign); - public void onCraftDetect(CraftDetectEvent event, Sign sign) { + public void onCraftDetect(CraftDetectEvent event, AbstractSignListener.SignWrapper sign) { // Do nothing by default } @@ -96,8 +87,8 @@ public void onSignMovedByCraft(SignTranslateEvent event) { // Do nothing by default } - protected abstract boolean isSignValid(Action clickType, Sign sign, Player player); + protected abstract boolean isSignValid(Action clickType, AbstractSignListener.SignWrapper sign, Player player); - protected abstract boolean internalProcessSign(Action clickType, Sign sign, Player player, Craft craft); + protected abstract boolean internalProcessSign(Action clickType, AbstractSignListener.SignWrapper sign, Player player, Craft craft); } diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractCruiseSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractCruiseSign.java index de458674b..4916d8b7f 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractCruiseSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractCruiseSign.java @@ -7,8 +7,7 @@ import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.Style; import net.kyori.adventure.text.format.TextColor; -import org.bukkit.ChatColor; -import org.bukkit.block.Sign; +import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; import org.bukkit.entity.Player; import org.bukkit.event.block.Action; import org.bukkit.event.block.SignChangeEvent; @@ -31,11 +30,11 @@ public AbstractCruiseSign(final String permission, boolean ignoreCraftIsBusy, fi } @Override - protected boolean isSignValid(Action clickType, Sign sign, Player player) { - if (sign.getLines() == null || sign.getLines()[0] == null) { + protected boolean isSignValid(Action clickType, AbstractSignListener.SignWrapper sign, Player player) { + if (PlainTextComponentSerializer.plainText().serialize(sign.line(0)).isBlank()) { return false; } - String[] headerSplit = ChatColor.stripColor(sign.getLine(0)).split(":"); + String[] headerSplit = this.getSplitHeader(sign); if (headerSplit.length != 2) { return false; } @@ -43,8 +42,16 @@ protected boolean isSignValid(Action clickType, Sign sign, Player player) { return suffix.equalsIgnoreCase(this.suffixOff) || suffix.equalsIgnoreCase(this.suffixOn); } - protected boolean isOnOrOff(Sign sign) { - String[] headerSplit = ChatColor.stripColor(sign.getLine(0)).split(":"); + protected String[] getSplitHeader(final AbstractSignListener.SignWrapper sign) { + String header = PlainTextComponentSerializer.plainText().serialize(sign.line(0)); + if (header.isBlank()) { + return null; + } + return header.split(":"); + } + + protected boolean isOnOrOff(AbstractSignListener.SignWrapper sign) { + String[] headerSplit = this.getSplitHeader(sign); if (headerSplit.length != 2) { return false; } @@ -58,7 +65,7 @@ public boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action } @Override - protected boolean internalProcessSign(Action clickType, Sign sign, Player player, Craft craft) { + protected boolean internalProcessSign(Action clickType, AbstractSignListener.SignWrapper sign, Player player, Craft craft) { boolean isOn = this.isOnOrOff(sign); boolean willBeOn = !isOn; if (willBeOn) { @@ -70,19 +77,20 @@ protected boolean internalProcessSign(Action clickType, Sign sign, Player player // Update sign sign.line(0, buildHeader(willBeOn)); - sign.update(true); - craft.resetSigns(sign); + sign.block().update(true); + // TODO: What to replace this with? + craft.resetSigns(sign.block()); return true; } @Override - public boolean processSignChange(SignChangeEvent event) { + public boolean processSignChange(SignChangeEvent event, AbstractSignListener.SignWrapper sign) { return true; } @Override - public void onCraftDetect(CraftDetectEvent event, Sign sign) { + public void onCraftDetect(CraftDetectEvent event, AbstractSignListener.SignWrapper sign) { Player p = null; if (event.getCraft() instanceof PilotedCraft pc) { p = pc.getPilot(); @@ -110,5 +118,5 @@ protected Component buildHeaderOff() { protected abstract void setCraftCruising(Player player, CruiseDirection direction); // TODO: Rework cruise direction to vectors => Vector defines the skip distance and the direction - protected abstract CruiseDirection getCruiseDirection(Sign sign); + protected abstract CruiseDirection getCruiseDirection(AbstractSignListener.SignWrapper sign); } diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java index c48a95e5c..7d2a83f16 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java @@ -2,7 +2,6 @@ import net.countercraft.movecraft.craft.Craft; import net.countercraft.movecraft.util.MathUtils; -import org.bukkit.block.Sign; import org.bukkit.entity.Player; import org.bukkit.event.block.Action; import org.bukkit.event.block.SignChangeEvent; @@ -14,6 +13,7 @@ import java.util.Map; import java.util.Optional; +// TODO: In 1.21 signs can have multiple sides! This requires us to pass the clicked side through or well the relevant lines and the set method for the clicked side public abstract class AbstractMovecraftSign { private static final Map SIGNS = Collections.synchronizedMap(new HashMap<>()); @@ -24,7 +24,7 @@ public static boolean hasBeenRegistered(final String ident) { public static Optional tryGet(final String ident) { String identToUse = ident.toUpperCase(); - if (identToUse.indexOf(":") >= 0) { + if (identToUse.contains(":")) { identToUse = identToUse.split(":")[0]; if (ident.contains(":")) { identToUse = identToUse + ":"; @@ -68,7 +68,7 @@ public static String findIdent(AbstractMovecraftSign instance) { } // Return true to cancel the event - public boolean processSignClick(Action clickType, Sign sign, Player player) { + public boolean processSignClick(Action clickType, AbstractSignListener.SignWrapper sign, Player player) { if (!this.isSignValid(clickType, sign, player)) { return false; } @@ -79,19 +79,16 @@ public boolean processSignClick(Action clickType, Sign sign, Player player) { return internalProcessSign(clickType, sign, player, getCraft(sign)); } - protected boolean canPlayerUseSign(Action clickType, Sign sign, Player player) { - if (this.optPermission.isPresent()) { - return player.hasPermission(this.optPermission.get()); - } - return true; + protected boolean canPlayerUseSign(Action clickType, AbstractSignListener.SignWrapper sign, Player player) { + return this.optPermission.map(player::hasPermission).orElse(true); } - protected Optional getCraft(Sign sign) { - return Optional.ofNullable(MathUtils.getCraftByPersistentBlockData(sign.getLocation())); + protected Optional getCraft(AbstractSignListener.SignWrapper sign) { + return Optional.ofNullable(MathUtils.getCraftByPersistentBlockData(sign.block().getLocation())); } public abstract boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action type, boolean sneaking); - protected abstract boolean isSignValid(Action clickType, Sign sign, Player player); - protected abstract boolean internalProcessSign(Action clickType, Sign sign, Player player, Optional craft); - public abstract boolean processSignChange(SignChangeEvent event); + protected abstract boolean isSignValid(Action clickType, AbstractSignListener.SignWrapper sign, Player player); + protected abstract boolean internalProcessSign(Action clickType, AbstractSignListener.SignWrapper sign, Player player, Optional craft); + public abstract boolean processSignChange(SignChangeEvent event, AbstractSignListener.SignWrapper sign); } From c1bf27dc0c63110680166ac8128f324744b2994a Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Sat, 10 Aug 2024 12:08:03 +0200 Subject: [PATCH 023/122] add base for info signs --- .../sign/AbstractInformationSign.java | 112 ++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 api/src/main/java/net/countercraft/movecraft/sign/AbstractInformationSign.java diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractInformationSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractInformationSign.java new file mode 100644 index 000000000..4b452faa1 --- /dev/null +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractInformationSign.java @@ -0,0 +1,112 @@ +package net.countercraft.movecraft.sign; + +import net.countercraft.movecraft.MovecraftLocation; +import net.countercraft.movecraft.craft.Craft; +import net.countercraft.movecraft.events.CraftDetectEvent; +import net.countercraft.movecraft.events.SignTranslateEvent; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; +import org.bukkit.block.Block; +import org.bukkit.block.Sign; +import org.bukkit.entity.Player; +import org.bukkit.event.block.Action; +import org.jetbrains.annotations.Nullable; + +public abstract class AbstractInformationSign extends AbstractCraftSign { + + public AbstractInformationSign() { + // Info signs only display things, that should not require permissions, also it doesn't matter if the craft is busy or not + super(null, true); + } + + @Override + protected boolean canPlayerUseSignOn(Player player, Craft craft) { + // Permcheck related, no perms required, return true + return true; + } + + @Override + public void onCraftDetect(CraftDetectEvent event, AbstractSignListener.SignWrapper sign) { + // TODO: Check if the craft supports this sign? If no, cancel + super.onCraftDetect(event, sign); + this.refreshSign(event.getCraft(), sign); + } + + @Override + public void onSignMovedByCraft(SignTranslateEvent event) { + super.onSignMovedByCraft(event); + final Craft craft = event.getCraft(); + for (MovecraftLocation movecraftLocation : event.getLocations()) { + Block block = movecraftLocation.toBukkit(craft.getWorld()).getBlock(); + if (block instanceof Sign sign) { + for (AbstractSignListener.SignWrapper wrapper : AbstractSignListener.INSTANCE.getSignWrappers(sign)) { + this.refreshSign(event.getCraft(), wrapper); + } + } + } + } + + @Override + protected void onCraftNotFound(Player player, AbstractSignListener.SignWrapper sign) { + // Nothing to do + } + + @Override + protected boolean isSignValid(Action clickType, AbstractSignListener.SignWrapper sign, Player player) { + return true; + } + + @Override + public boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action type, boolean sneaking) { + if (processingSuccessful) { + return true; + } + return !sneaking; + } + + @Override + protected boolean internalProcessSign(Action clickType, AbstractSignListener.SignWrapper sign, Player player, Craft craft) { + this.refreshSign(craft, sign); + return true; + } + + protected void refreshSign(Craft craft, AbstractSignListener.SignWrapper sign) { + boolean changedSome = false; + Component[] updatePayload = new Component[sign.lines().size()]; + for(int i = 1; i < sign.lines().size(); i++) { + Component oldComponent = sign.line(i); + Component potentiallyNew = this.getUpdateString(i, oldComponent, craft); + if (potentiallyNew != null && !potentiallyNew.equals(oldComponent)) { + String oldValue = PlainTextComponentSerializer.plainText().serialize(oldComponent); + String newValue = PlainTextComponentSerializer.plainText().serialize(potentiallyNew); + if (!oldValue.equals(newValue)) { + changedSome = true; + updatePayload[i] = potentiallyNew; + } + } + } + if (changedSome) { + this.performUpdate(updatePayload, sign); + this.sendUpdatePacket(craft, sign); + } + } + + /* + Data to set on the sign. Return null if no update should happen! + Attention: A update will only be performed, if the new and old component are different! + */ + @Nullable + protected abstract Component getUpdateString(int lineIndex, Component oldData, Craft craft); + + /* + * @param newComponents: Array of nullable values. The index represents the index on the sign. Only contains the updated components + * + * Only gets called if at least one line has changed + */ + protected abstract void performUpdate(Component[] newComponents, AbstractSignListener.SignWrapper sign); + + /* + Gets called after performUpdate has been called + */ + protected abstract void sendUpdatePacket(Craft craft, AbstractSignListener.SignWrapper sign); +} From 0edd8cba2e1f8abedaa6127d322b93f7e10dcc34 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Sat, 10 Aug 2024 12:08:17 +0200 Subject: [PATCH 024/122] refactors --- .../net/countercraft/movecraft/sign/HelmSign.java | 12 ++++-------- .../net/countercraft/movecraft/sign/MoveSign.java | 11 +++++------ .../net/countercraft/movecraft/sign/NameSign.java | 15 +++++++-------- .../countercraft/movecraft/sign/ReleaseSign.java | 9 ++++----- .../countercraft/movecraft/sign/ScuttleSign.java | 9 ++++----- 5 files changed, 24 insertions(+), 32 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/HelmSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/HelmSign.java index f0efdbbbb..1a38acf77 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/HelmSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/HelmSign.java @@ -2,17 +2,13 @@ import net.countercraft.movecraft.MovecraftRotation; import net.countercraft.movecraft.craft.Craft; -import net.countercraft.movecraft.craft.CraftManager; import net.countercraft.movecraft.craft.type.CraftType; import net.countercraft.movecraft.localisation.I18nSupport; import net.countercraft.movecraft.util.MathUtils; import org.bukkit.ChatColor; -import org.bukkit.block.BlockState; -import org.bukkit.block.Sign; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; import org.bukkit.event.block.Action; import org.bukkit.event.block.SignChangeEvent; import org.bukkit.event.player.PlayerInteractEvent; @@ -54,7 +50,7 @@ protected void onCraftIsBusy(Player player, Craft craft) { } @Override - protected void onCraftNotFound(Player player, Sign sign) { + protected void onCraftNotFound(Player player, AbstractSignListener.SignWrapper sign) { } @@ -64,13 +60,13 @@ public boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action } @Override - protected boolean isSignValid(Action clickType, Sign sign, Player player) { + protected boolean isSignValid(Action clickType, AbstractSignListener.SignWrapper sign, Player player) { // Nothing to check here honestly... return true; } @Override - public boolean processSignChange(SignChangeEvent event) { + public boolean processSignChange(SignChangeEvent event, AbstractSignListener.SignWrapper sign) { if (!ChatColor.stripColor(event.getLine(0)).equalsIgnoreCase("[helm]")) { return true; } @@ -81,7 +77,7 @@ public boolean processSignChange(SignChangeEvent event) { } @Override - protected boolean internalProcessSign(Action clickType, Sign sign, Player player, Craft craft) { + protected boolean internalProcessSign(Action clickType, AbstractSignListener.SignWrapper sign, Player player, Craft craft) { MovecraftRotation rotation; if (clickType == Action.RIGHT_CLICK_BLOCK) { rotation = MovecraftRotation.CLOCKWISE; diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/MoveSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/MoveSign.java index a51a38036..6375e85a1 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/MoveSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/MoveSign.java @@ -4,7 +4,6 @@ import net.countercraft.movecraft.craft.type.CraftType; import net.countercraft.movecraft.localisation.I18nSupport; import org.bukkit.ChatColor; -import org.bukkit.block.Sign; import org.bukkit.entity.Player; import org.bukkit.event.block.Action; import org.bukkit.event.block.SignChangeEvent; @@ -22,7 +21,7 @@ protected void onCraftIsBusy(Player player, Craft craft) { } @Override - protected void onCraftNotFound(Player player, Sign sign) { + protected void onCraftNotFound(Player player, AbstractSignListener.SignWrapper sign) { } @@ -35,7 +34,7 @@ public boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action } @Override - protected boolean isSignValid(Action clickType, Sign sign, Player player) { + protected boolean isSignValid(Action clickType, AbstractSignListener.SignWrapper sign, Player player) { String[] numbers = ChatColor.stripColor(sign.getLine(1)).split(","); if (numbers.length != 3) { return false; @@ -51,7 +50,7 @@ protected boolean isSignValid(Action clickType, Sign sign, Player player) { } @Override - public boolean processSignChange(SignChangeEvent event) { + public boolean processSignChange(SignChangeEvent event, AbstractSignListener.SignWrapper sign) { return false; } @@ -69,7 +68,7 @@ protected boolean canPlayerUseSignOn(Player player, Craft craft) { } @Override - protected boolean internalProcessSign(Action clickType, Sign sign, Player player, Craft craft) { + protected boolean internalProcessSign(Action clickType, AbstractSignListener.SignWrapper sign, Player player, Craft craft) { if (!craft.getType().getBoolProperty(CraftType.CAN_STATIC_MOVE)) { return false; } @@ -79,7 +78,7 @@ protected boolean internalProcessSign(Action clickType, Sign sign, Player player int dy = Integer.parseInt(numbers[1]); int dz = Integer.parseInt(numbers[2]); - return translateCraft(sign.getRawData(), dy, dy, dz, craft); + return translateCraft(sign.getRawData(), dx, dy, dz, craft); } protected boolean translateCraft(final byte signDataRaw, int dxRaw, int dyRaw, int dzRaw, Craft craft) { diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/NameSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/NameSign.java index e80bb50f7..246d960e9 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/NameSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/NameSign.java @@ -5,7 +5,6 @@ import net.countercraft.movecraft.craft.PilotedCraft; import net.countercraft.movecraft.events.CraftDetectEvent; import net.countercraft.movecraft.util.ChatUtils; -import org.bukkit.block.Sign; import org.bukkit.entity.Player; import org.bukkit.event.block.Action; import org.bukkit.event.block.SignChangeEvent; @@ -32,22 +31,22 @@ public boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action } @Override - protected boolean canPlayerUseSign(Action clickType, Sign sign, Player player) { + protected boolean canPlayerUseSign(Action clickType, AbstractSignListener.SignWrapper sign, Player player) { return !Settings.RequireNamePerm || super.canPlayerUseSign(clickType, sign, player); } @Override - protected boolean isSignValid(Action clickType, Sign sign, Player player) { + protected boolean isSignValid(Action clickType, AbstractSignListener.SignWrapper sign, Player player) { return true; } @Override - protected boolean internalProcessSign(Action clickType, Sign sign, Player player, Craft craft) { + protected boolean internalProcessSign(Action clickType, AbstractSignListener.SignWrapper sign, Player player, Craft craft) { return true; } @Override - protected boolean internalProcessSign(Action clickType, Sign sign, Player player, Optional craft) { + protected boolean internalProcessSign(Action clickType, AbstractSignListener.SignWrapper sign, Player player, Optional craft) { return true; } @@ -56,11 +55,11 @@ protected void onCraftIsBusy(Player player, Craft craft) { } @Override - protected void onCraftNotFound(Player player, Sign sign) { + protected void onCraftNotFound(Player player, AbstractSignListener.SignWrapper sign) { } @Override - public boolean processSignChange(SignChangeEvent event) { + public boolean processSignChange(SignChangeEvent event, AbstractSignListener.SignWrapper sign) { if (this.canPlayerUseSign(Action.RIGHT_CLICK_BLOCK, null, event.getPlayer())) { // Nothing to do return true; @@ -72,7 +71,7 @@ public boolean processSignChange(SignChangeEvent event) { } @Override - public void onCraftDetect(CraftDetectEvent event, Sign sign) { + public void onCraftDetect(CraftDetectEvent event, AbstractSignListener.SignWrapper sign) { Craft craft = event.getCraft(); if (craft != null && craft instanceof PilotedCraft pc) { if (Settings.RequireNamePerm && !pc.getPilot().hasPermission(NAME_SIGN_PERMISSION)) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/ReleaseSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/ReleaseSign.java index dacd3b1f1..82ddaa9f1 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/ReleaseSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/ReleaseSign.java @@ -3,7 +3,6 @@ import net.countercraft.movecraft.craft.Craft; import net.countercraft.movecraft.craft.CraftManager; import net.countercraft.movecraft.events.CraftReleaseEvent; -import org.bukkit.block.Sign; import org.bukkit.entity.Player; import org.bukkit.event.block.Action; import org.bukkit.event.block.SignChangeEvent; @@ -21,7 +20,7 @@ protected void onCraftIsBusy(Player player, Craft craft) { } @Override - protected void onCraftNotFound(Player player, Sign sign) { + protected void onCraftNotFound(Player player, AbstractSignListener.SignWrapper sign) { } @@ -34,17 +33,17 @@ public boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action } @Override - protected boolean isSignValid(Action clickType, Sign sign, Player player) { + protected boolean isSignValid(Action clickType, AbstractSignListener.SignWrapper sign, Player player) { return true; } @Override - public boolean processSignChange(SignChangeEvent event) { + public boolean processSignChange(SignChangeEvent event, AbstractSignListener.SignWrapper sign) { return false; } @Override - protected boolean internalProcessSign(Action clickType, Sign sign, Player player, Craft craft) { + protected boolean internalProcessSign(Action clickType, AbstractSignListener.SignWrapper sign, Player player, Craft craft) { CraftManager.getInstance().release(craft, CraftReleaseEvent.Reason.PLAYER, false); return true; } diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/ScuttleSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/ScuttleSign.java index f50ac2cf3..d58dfa171 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/ScuttleSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/ScuttleSign.java @@ -8,7 +8,6 @@ import net.countercraft.movecraft.events.CraftScuttleEvent; import net.countercraft.movecraft.localisation.I18nSupport; import org.bukkit.Bukkit; -import org.bukkit.block.Sign; import org.bukkit.entity.Player; import org.bukkit.event.block.Action; import org.bukkit.event.block.SignChangeEvent; @@ -28,7 +27,7 @@ protected void onCraftIsBusy(Player player, Craft craft) { } @Override - protected void onCraftNotFound(Player player, Sign sign) { + protected void onCraftNotFound(Player player, AbstractSignListener.SignWrapper sign) { player.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("You must be piloting a craft")); } @@ -42,12 +41,12 @@ public boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action } @Override - protected boolean isSignValid(Action clickType, Sign sign, Player player) { + protected boolean isSignValid(Action clickType, AbstractSignListener.SignWrapper sign, Player player) { return true; } @Override - public boolean processSignChange(SignChangeEvent event) { + public boolean processSignChange(SignChangeEvent event, AbstractSignListener.SignWrapper sign) { return false; } @@ -80,7 +79,7 @@ protected boolean canPlayerUseSignOn(Player player, Craft craft) { } @Override - protected boolean internalProcessSign(Action clickType, Sign sign, Player player, Craft craft) { + protected boolean internalProcessSign(Action clickType, AbstractSignListener.SignWrapper sign, Player player, Craft craft) { CraftScuttleEvent e = new CraftScuttleEvent(craft, player); Bukkit.getServer().getPluginManager().callEvent(e); if(e.isCancelled()) From d6796895208913185fa85c3faaa0475e046478a0 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Sat, 10 Aug 2024 12:08:34 +0200 Subject: [PATCH 025/122] add 1.21 implementation of signlistener --- .../movecraft/compat/v1_21/SignListener.java | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/SignListener.java diff --git a/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/SignListener.java b/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/SignListener.java new file mode 100644 index 000000000..ca957fba8 --- /dev/null +++ b/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/SignListener.java @@ -0,0 +1,59 @@ +package net.countercraft.movecraft.compat.v1_21; + +import net.countercraft.movecraft.sign.AbstractSignListener; +import org.bukkit.block.BlockFace; +import org.bukkit.block.Sign; +import org.bukkit.block.data.Directional; +import org.bukkit.block.sign.Side; +import org.bukkit.block.sign.SignSide; +import org.bukkit.event.block.SignChangeEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.jetbrains.annotations.NotNull; + +public class SignListener extends AbstractSignListener { + + protected final SignWrapper createFromSide(final Sign sign, final Side side) { + SignSide signSide = sign.getSide(side); + return createFromSide(sign, signSide, side); + } + + protected final SignWrapper createFromSide(final Sign sign, final SignSide signSide, Side side) { + BlockFace face = ((Directional) sign.getBlockData()).getFacing(); + if (side == Side.BACK) { + face = face.getOppositeFace(); + } + SignWrapper wrapper = new SignWrapper( + sign, + signSide::line, + signSide.lines(), + signSide::line, + face + ); + return wrapper; + } + + @Override + public SignWrapper[] getSignWrappers(Sign sign) { + Side[] sides = new Side[Side.values().length]; + SignWrapper[] wrappers = new SignWrapper[sides.length]; + for (int i = 0; i < sides.length; i++) { + Side side = sides[i]; + SignSide signSide = sign.getSide(side); + SignWrapper wrapper = this.createFromSide(sign, signSide, side); + wrappers[i] = wrapper; + } + return wrappers; + } + + @Override + protected SignWrapper getSignWrapper(Sign sign, SignChangeEvent signChangeEvent) { + @NotNull Side side = signChangeEvent.getSide(); + return this.createFromSide(sign, side); + } + + @Override + protected SignWrapper getSignWrapper(Sign sign, PlayerInteractEvent interactEvent) { + @NotNull SignSide side = sign.getTargetSide(interactEvent.getPlayer()); + return this.createFromSide(sign, side, sign.getInteractableSideFor(interactEvent.getPlayer())); + } +} From 02fe15e05ce36b374be779700a225fe5e684231a Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Sat, 10 Aug 2024 12:09:38 +0200 Subject: [PATCH 026/122] fix imports --- .../src/main/java/net/countercraft/movecraft/Movecraft.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java b/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java index 7ee001732..0a286d873 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java @@ -28,7 +28,7 @@ import net.countercraft.movecraft.features.contacts.ContactsSign; import net.countercraft.movecraft.features.status.StatusManager; import net.countercraft.movecraft.features.status.StatusSign; -import net.countercraft.movecraft.compat.v1_21.listener.*; +import net.countercraft.movecraft.listener.*; import net.countercraft.movecraft.localisation.I18nSupport; import net.countercraft.movecraft.mapUpdater.MapUpdateManager; import net.countercraft.movecraft.processing.WorldManager; From ef9ca4b18dedfffd6c2f9677d7982c65baec201b Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Sat, 10 Aug 2024 12:10:15 +0200 Subject: [PATCH 027/122] add 1.20 implementation of listener --- .../movecraft/compat/v1_20/SignListener.java | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 v1_20/src/main/java/net/countercraft/movecraft/compat/v1_20/SignListener.java diff --git a/v1_20/src/main/java/net/countercraft/movecraft/compat/v1_20/SignListener.java b/v1_20/src/main/java/net/countercraft/movecraft/compat/v1_20/SignListener.java new file mode 100644 index 000000000..791e3d71b --- /dev/null +++ b/v1_20/src/main/java/net/countercraft/movecraft/compat/v1_20/SignListener.java @@ -0,0 +1,59 @@ +package net.countercraft.movecraft.compat.v1_20; + +import net.countercraft.movecraft.sign.AbstractSignListener; +import org.bukkit.block.BlockFace; +import org.bukkit.block.Sign; +import org.bukkit.block.data.Directional; +import org.bukkit.block.sign.Side; +import org.bukkit.block.sign.SignSide; +import org.bukkit.event.block.SignChangeEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.jetbrains.annotations.NotNull; + +public class SignListener extends AbstractSignListener { + + protected final SignWrapper createFromSide(final Sign sign, final Side side) { + SignSide signSide = sign.getSide(side); + return createFromSide(sign, signSide, side); + } + + protected final SignWrapper createFromSide(final Sign sign, final SignSide signSide, Side side) { + BlockFace face = ((Directional) sign.getBlockData()).getFacing(); + if (side == Side.BACK) { + face = face.getOppositeFace(); + } + SignWrapper wrapper = new SignWrapper( + sign, + signSide::line, + signSide.lines(), + signSide::line, + face + ); + return wrapper; + } + + @Override + public SignWrapper[] getSignWrappers(Sign sign) { + Side[] sides = new Side[Side.values().length]; + SignWrapper[] wrappers = new SignWrapper[sides.length]; + for (int i = 0; i < sides.length; i++) { + Side side = sides[i]; + SignSide signSide = sign.getSide(side); + SignWrapper wrapper = this.createFromSide(sign, signSide, side); + wrappers[i] = wrapper; + } + return wrappers; + } + + @Override + protected SignWrapper getSignWrapper(Sign sign, SignChangeEvent signChangeEvent) { + @NotNull Side side = signChangeEvent.getSide(); + return this.createFromSide(sign, side); + } + + @Override + protected SignWrapper getSignWrapper(Sign sign, PlayerInteractEvent interactEvent) { + @NotNull SignSide side = sign.getTargetSide(interactEvent.getPlayer()); + return this.createFromSide(sign, side, sign.getInteractableSideFor(interactEvent.getPlayer())); + } +} From 383683eb7b1d5f39eb6c257f47f43480ea809d78 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Sat, 10 Aug 2024 12:12:50 +0200 Subject: [PATCH 028/122] add 1.18 signListener implementation --- .../movecraft/compat/v1_18/SignListener.java | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 v1_18/src/main/java/net/countercraft/movecraft/compat/v1_18/SignListener.java diff --git a/v1_18/src/main/java/net/countercraft/movecraft/compat/v1_18/SignListener.java b/v1_18/src/main/java/net/countercraft/movecraft/compat/v1_18/SignListener.java new file mode 100644 index 000000000..d57a53000 --- /dev/null +++ b/v1_18/src/main/java/net/countercraft/movecraft/compat/v1_18/SignListener.java @@ -0,0 +1,39 @@ +package net.countercraft.movecraft.compat.v1_18; + +import net.countercraft.movecraft.sign.AbstractSignListener; +import org.bukkit.block.BlockFace; +import org.bukkit.block.Sign; +import org.bukkit.block.data.Directional; +import org.bukkit.event.block.SignChangeEvent; +import org.bukkit.event.player.PlayerInteractEvent; + +public class SignListener extends AbstractSignListener { + + protected final SignWrapper createFromSign(final Sign sign) { + BlockFace face = ((Directional) sign.getBlockData()).getFacing(); + SignWrapper wrapper = new SignWrapper( + sign, + sign::line, + sign.lines(), + sign::line, + face + ); + return wrapper; + } + + @Override + public SignWrapper[] getSignWrappers(Sign sign) { + SignWrapper wrapper = this.createFromSign(sign); + return new SignWrapper[] {wrapper}; + } + + @Override + protected SignWrapper getSignWrapper(Sign sign, SignChangeEvent signChangeEvent) { + return this.createFromSign(sign); + } + + @Override + protected SignWrapper getSignWrapper(Sign sign, PlayerInteractEvent interactEvent) { + return this.createFromSign(sign); + } +} From f8e6c028cdc3e8297ca9350fae52846b23528430 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Sat, 10 Aug 2024 12:29:10 +0200 Subject: [PATCH 029/122] migrate teleport sign and fix move sign --- .../net/countercraft/movecraft/Movecraft.java | 3 +- .../countercraft/movecraft/sign/MoveSign.java | 9 +- .../movecraft/sign/RelativeMoveSign.java | 4 +- .../movecraft/sign/TeleportSign.java | 110 ++++++++---------- .../movecraft/sign/AbstractSignListener.java | 5 + 5 files changed, 61 insertions(+), 70 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java b/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java index 0a286d873..161c79057 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java @@ -232,7 +232,8 @@ public void onEnable() { getServer().getPluginManager().registerEvents(new RemoteSign(), this); getServer().getPluginManager().registerEvents(new SpeedSign(), this); getServer().getPluginManager().registerEvents(new SubcraftRotateSign(), this); - getServer().getPluginManager().registerEvents(new TeleportSign(), this); + //getServer().getPluginManager().registerEvents(new TeleportSign(), this); + AbstractMovecraftSign.register("Teleport:", new TeleportSign(), true); //getServer().getPluginManager().registerEvents(new ScuttleSign(), this); AbstractMovecraftSign.register("Scuttle", new ScuttleSign(), true); getServer().getPluginManager().registerEvents(new CraftPilotListener(), this); diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/MoveSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/MoveSign.java index 6375e85a1..a363d8494 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/MoveSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/MoveSign.java @@ -3,7 +3,6 @@ import net.countercraft.movecraft.craft.Craft; import net.countercraft.movecraft.craft.type.CraftType; import net.countercraft.movecraft.localisation.I18nSupport; -import org.bukkit.ChatColor; import org.bukkit.entity.Player; import org.bukkit.event.block.Action; import org.bukkit.event.block.SignChangeEvent; @@ -35,7 +34,7 @@ public boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action @Override protected boolean isSignValid(Action clickType, AbstractSignListener.SignWrapper sign, Player player) { - String[] numbers = ChatColor.stripColor(sign.getLine(1)).split(","); + String[] numbers = sign.getRaw(1).split(","); if (numbers.length != 3) { return false; } @@ -73,15 +72,15 @@ protected boolean internalProcessSign(Action clickType, AbstractSignListener.Sig return false; } - String[] numbers = ChatColor.stripColor(sign.getLine(1)).split(","); + String[] numbers = sign.getRaw(1).split(","); int dx = Integer.parseInt(numbers[0]); int dy = Integer.parseInt(numbers[1]); int dz = Integer.parseInt(numbers[2]); - return translateCraft(sign.getRawData(), dx, dy, dz, craft); + return translateCraft(sign.block().getRawData(), dx, dy, dz, craft, sign); } - protected boolean translateCraft(final byte signDataRaw, int dxRaw, int dyRaw, int dzRaw, Craft craft) { + protected boolean translateCraft(final byte signDataRaw, int dxRaw, int dyRaw, int dzRaw, Craft craft, AbstractSignListener.SignWrapper signWrapper) { int maxMove = craft.getType().getIntProperty(CraftType.MAX_STATIC_MOVE); if (dxRaw > maxMove) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/RelativeMoveSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/RelativeMoveSign.java index fe5f22253..6c63c604e 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/RelativeMoveSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/RelativeMoveSign.java @@ -3,6 +3,8 @@ import net.countercraft.movecraft.craft.Craft; import net.countercraft.movecraft.craft.type.CraftType; +import javax.annotation.Nullable; + public class RelativeMoveSign extends MoveSign { public RelativeMoveSign() { @@ -10,7 +12,7 @@ public RelativeMoveSign() { } @Override - protected boolean translateCraft(byte signDataRaw, int dxRaw, int dyRaw, int dzRaw, Craft craft) { + protected boolean translateCraft(byte signDataRaw, int dxRaw, int dyRaw, int dzRaw, Craft craft, AbstractSignListener.SignWrapper signWrapper) { final int maxMove = craft.getType().getIntProperty(CraftType.MAX_STATIC_MOVE); // X: Left/Right diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/TeleportSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/TeleportSign.java index 4f41f6db5..f7e35f125 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/TeleportSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/TeleportSign.java @@ -1,78 +1,62 @@ package net.countercraft.movecraft.sign; import net.countercraft.movecraft.craft.Craft; -import net.countercraft.movecraft.craft.CraftManager; import net.countercraft.movecraft.craft.type.CraftType; import net.countercraft.movecraft.localisation.I18nSupport; import org.bukkit.Bukkit; -import org.bukkit.ChatColor; import org.bukkit.World; -import org.bukkit.block.BlockState; -import org.bukkit.block.Sign; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; +import org.bukkit.entity.Player; import org.bukkit.event.block.Action; -import org.bukkit.event.player.PlayerInteractEvent; -import org.jetbrains.annotations.NotNull; -public final class TeleportSign implements Listener { - private static final String HEADER = "Teleport:"; +public class TeleportSign extends MoveSign { - @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) - public void onSignClick(@NotNull PlayerInteractEvent event) { - if (event.getAction() != Action.RIGHT_CLICK_BLOCK) { - return; - } - BlockState state = event.getClickedBlock().getState(); - if (!(state instanceof Sign)) { - return; - } - Sign sign = (Sign) state; - if (!ChatColor.stripColor(sign.getLine(0)).equalsIgnoreCase(HEADER)) { - return; - } - event.setCancelled(true); - if (CraftManager.getInstance().getCraftByPlayer(event.getPlayer()) == null) { - return; - } - - int tX = sign.getX(); int tY = sign.getY(); int tZ = sign.getZ(); - String[] numbers = ChatColor.stripColor(sign.getLine(1)).replaceAll(" ", "").split(","); - if (numbers.length >= 3) { - try { - - tX = Integer.parseInt(numbers[0]); - tY = Integer.parseInt(numbers[1]); - tZ = Integer.parseInt(numbers[2]); - - } catch (NumberFormatException e) { - event.getPlayer().sendMessage(I18nSupport.getInternationalisedString("Invalid Coordinates")); - return; - } - } - - String w = ChatColor.stripColor(sign.getLine(2)); - World world = Bukkit.getWorld(w); - if (world == null) world = sign.getWorld(); + public TeleportSign() { + super(); + } - if (!event.getPlayer().hasPermission("movecraft." + CraftManager.getInstance().getCraftByPlayer(event.getPlayer()).getType().getStringProperty(CraftType.NAME) + ".move")) { - event.getPlayer().sendMessage(I18nSupport.getInternationalisedString("Insufficient Permissions")); - return; - } - final Craft c = CraftManager.getInstance().getCraftByPlayer(event.getPlayer()); - if (c == null || !c.getType().getBoolProperty(CraftType.CAN_TELEPORT)) { - return; + @Override + protected boolean isSignValid(Action clickType, AbstractSignListener.SignWrapper sign, Player player) { + if (!super.isSignValid(clickType, sign, player)) { + return false; + } + // Check world => If specified it has to exist! + String w = sign.getRaw(2); + if (!w.isBlank()) { + World world = Bukkit.getWorld(w); + return world != null; + } + return true; + } + + @Override + protected boolean translateCraft(byte signDataRaw, int dxRaw, int dyRaw, int dzRaw, Craft craft, AbstractSignListener.SignWrapper signWrapper) { + World world = craft.getWorld(); + String w = signWrapper.getRaw(2); + if (!w.isBlank()) { + world = Bukkit.getWorld(w); } - long timeSinceLastTeleport = System.currentTimeMillis() - c.getLastTeleportTime(); - if (c.getType().getIntProperty(CraftType.TELEPORTATION_COOLDOWN) > 0 && timeSinceLastTeleport < c.getType().getIntProperty(CraftType.TELEPORTATION_COOLDOWN)) { - event.getPlayer().sendMessage(String.format(I18nSupport.getInternationalisedString("Teleportation - Cooldown active"), timeSinceLastTeleport)); - return; + + int dx = dxRaw - signWrapper.block().getX(); + int dy = dyRaw - signWrapper.block().getY(); + int dz = dzRaw - signWrapper.block().getZ(); + craft.translate(world, dx, dy, dz); + craft.setLastTeleportTime(System.currentTimeMillis()); + + return true; + } + + @Override + protected boolean canPlayerUseSignOn(Player player, Craft craft) { + if (super.canPlayerUseSignOn(player, craft)) { + if (craft.getType().getBoolProperty(CraftType.CAN_TELEPORT)) { + long timeSinceLastTeleport = System.currentTimeMillis() - craft.getLastTeleportTime(); + if (craft.getType().getIntProperty(CraftType.TELEPORTATION_COOLDOWN) > 0 && timeSinceLastTeleport < craft.getType().getIntProperty(CraftType.TELEPORTATION_COOLDOWN)) { + player.sendMessage(String.format(I18nSupport.getInternationalisedString("Teleportation - Cooldown active"), timeSinceLastTeleport)); + return false; + } + return true; + } } - int dx = tX - sign.getX(); - int dy = tY - sign.getY(); - int dz = tZ - sign.getZ(); - c.translate(world, dx, dy, dz); - c.setLastTeleportTime(System.currentTimeMillis()); + return false; } } diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java index b20f46447..3e5cab79b 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java @@ -44,6 +44,11 @@ public Component line(int index) { public void line(int index, Component component) { setLine.accept(index, component); } + + public String getRaw(int index) { + return PlainTextComponentSerializer.plainText().serialize(line(index)); + } + } public abstract SignWrapper[] getSignWrappers(Sign sign); From 7260f9df7869bb143e6da8e0914559a986c348a9 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Sat, 10 Aug 2024 14:56:25 +0200 Subject: [PATCH 030/122] fix helm sign --- .../src/main/java/net/countercraft/movecraft/sign/HelmSign.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/HelmSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/HelmSign.java index 1a38acf77..f66135159 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/HelmSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/HelmSign.java @@ -110,7 +110,7 @@ protected boolean internalProcessSign(Action clickType, AbstractSignListener.Sig if (craft.getType().getBoolProperty(CraftType.ROTATE_AT_MIDPOINT)) { craft.rotate(rotation, craft.getHitBox().getMidPoint()); } else { - craft.rotate(rotation, MathUtils.bukkit2MovecraftLoc(sign.getLocation())); + craft.rotate(rotation, MathUtils.bukkit2MovecraftLoc(sign.block().getLocation())); } //timeMap.put(event.getPlayer(), System.currentTimeMillis()); From 7b77377a3a2bf61f69feb7ee1462e17a0cdd5eed Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Sat, 10 Aug 2024 14:56:35 +0200 Subject: [PATCH 031/122] add comment in TeleportSign --- .../main/java/net/countercraft/movecraft/sign/TeleportSign.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/TeleportSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/TeleportSign.java index f7e35f125..d923e837f 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/TeleportSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/TeleportSign.java @@ -36,6 +36,7 @@ protected boolean translateCraft(byte signDataRaw, int dxRaw, int dyRaw, int dzR world = Bukkit.getWorld(w); } + // Substract the signs location so we get a vector int dx = dxRaw - signWrapper.block().getX(); int dy = dyRaw - signWrapper.block().getY(); int dz = dzRaw - signWrapper.block().getZ(); From ddec33c286eecc0e37a0ff4176761194b097dcd0 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Sat, 10 Aug 2024 14:57:02 +0200 Subject: [PATCH 032/122] migrate PilotSign TODO: Should we replace the validator in the detection task? --- .../net/countercraft/movecraft/Movecraft.java | 3 +- .../validators/PilotSignValidator.java | 1 + .../movecraft/sign/PilotSign.java | 70 +++++++++++++------ 3 files changed, 50 insertions(+), 24 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java b/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java index 161c79057..7e2e49be1 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java @@ -224,7 +224,8 @@ public void onEnable() { AbstractMovecraftSign.register("Move:", new MoveSign(), true); //getServer().getPluginManager().registerEvents(new NameSign(), this); AbstractMovecraftSign.register("Name:", new NameSign(), true); - getServer().getPluginManager().registerEvents(new PilotSign(), this); + //getServer().getPluginManager().registerEvents(new PilotSign(), this); + AbstractMovecraftSign.register("Pilot:", new PilotSign(), true); //getServer().getPluginManager().registerEvents(new RelativeMoveSign(), this); AbstractMovecraftSign.register("RMove:", new RelativeMoveSign(), true); //getServer().getPluginManager().registerEvents(new ReleaseSign(), this); diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/validators/PilotSignValidator.java b/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/validators/PilotSignValidator.java index 045b9d47d..c429a3e5a 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/validators/PilotSignValidator.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/validators/PilotSignValidator.java @@ -14,6 +14,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +// TODO: Remove, replaced by the sign implementation! public class PilotSignValidator implements DetectionPredicate { @Override @Contract(pure = true) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/PilotSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/PilotSign.java index 9ed6cd230..9a3a9970b 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/PilotSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/PilotSign.java @@ -1,8 +1,11 @@ package net.countercraft.movecraft.sign; +import net.countercraft.movecraft.craft.Craft; +import net.kyori.adventure.text.Component; import org.bukkit.ChatColor; import org.bukkit.block.Block; import org.bukkit.block.Sign; +import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; @@ -10,33 +13,54 @@ import org.bukkit.event.block.SignChangeEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; -public final class PilotSign implements Listener { - private static final String HEADER = "Pilot:"; - @EventHandler - public final void onSignChange(SignChangeEvent event){ - if (event.getLine(0).equalsIgnoreCase(HEADER)) { - String pilotName = ChatColor.stripColor(event.getLine(1)); - if (pilotName.isEmpty()) { - event.setLine(1, event.getPlayer().getName()); - } - } +import java.util.Optional; + +// TODO: Replace PilotSignValidator with this? +public class PilotSign extends AbstractMovecraftSign { + + public PilotSign() { + super(null); } - @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) - public void onSignClickEvent(@NotNull PlayerInteractEvent event) { - if (event.getAction() != Action.RIGHT_CLICK_BLOCK) { - return; - } - Block block = event.getClickedBlock(); - if (!(block.getState() instanceof Sign)) { - return; - } + @Override + public boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action type, boolean sneaking) { + return processingSuccessful || !sneaking; + } - Sign sign = (Sign) block.getState(); - if (!ChatColor.stripColor(sign.getLine(0)).equalsIgnoreCase(HEADER)) { - return; + // Pilot signs are pretty much always valid + @Override + protected boolean isSignValid(Action clickType, AbstractSignListener.SignWrapper sign, Player player) { + return true; + } + + @Override + protected boolean internalProcessSign(Action clickType, AbstractSignListener.SignWrapper sign, Player player, Optional craft) { + // Nothing to do here + return true; + } + + @Override + public boolean processSignChange(SignChangeEvent event, AbstractSignListener.SignWrapper sign) { + boolean foundSome = false; + for (int i = 1; i < sign.lines().size(); i++) { + String data = null; + try { + data = sign.getRaw(i); + } catch (IndexOutOfBoundsException ioob) { + // Ignore + } + if (data != null) { + foundSome = !data.isBlank(); + if (foundSome) { + break; + } + } + } + if (!foundSome) { + sign.line(1, event.getPlayer().name()); } - event.setCancelled(true); + return true; } } From a3b2c522f37709ec61e652ba54d7efa6ec927a2e Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Sat, 10 Aug 2024 15:16:37 +0200 Subject: [PATCH 033/122] migrate cruise sign --- .../net/countercraft/movecraft/Movecraft.java | 3 +- .../movecraft/sign/CruiseSign.java | 113 ++++++++---------- .../movecraft/sign/AbstractCruiseSign.java | 19 +++ 3 files changed, 70 insertions(+), 65 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java b/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java index 7e2e49be1..69b47f76f 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java @@ -215,7 +215,8 @@ public void onEnable() { getServer().getPluginManager().registerEvents(new ChunkManager(), this); getServer().getPluginManager().registerEvents(new AscendSign(), this); getServer().getPluginManager().registerEvents(new CraftSign(), this); - getServer().getPluginManager().registerEvents(new CruiseSign(), this); + //getServer().getPluginManager().registerEvents(new CruiseSign(), this); + AbstractMovecraftSign.register("Cruise:", new CruiseSign(), true); getServer().getPluginManager().registerEvents(new DescendSign(), this); //getServer().getPluginManager().registerEvents(new HelmSign(), this); AbstractMovecraftSign.register("[Helm]", new HelmSign(), true); diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/CruiseSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/CruiseSign.java index fd4efec28..91a3af6c2 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/CruiseSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/CruiseSign.java @@ -11,9 +11,12 @@ import org.bukkit.ChatColor; import org.bukkit.Tag; import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; import org.bukkit.block.BlockState; import org.bukkit.block.Sign; import org.bukkit.block.data.Directional; +import org.bukkit.block.data.type.WallSign; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -22,83 +25,65 @@ import org.bukkit.event.block.SignChangeEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; -public final class CruiseSign implements Listener { +public class CruiseSign extends AbstractCruiseSign { - @EventHandler - public void onCraftDetect(@NotNull CraftDetectEvent event) { - World world = event.getCraft().getWorld(); - for (MovecraftLocation location : event.getCraft().getHitBox()) { - var block = location.toBukkit(world).getBlock(); - if (!Tag.SIGNS.isTagged(block.getType())) - continue; - - BlockState state = block.getState(); - if (!(state instanceof Sign)) - continue; - Sign sign = (Sign) state; - if (ChatColor.stripColor(sign.getLine(0)).equalsIgnoreCase("Cruise: ON")) { - sign.setLine(0, "Cruise: OFF"); - sign.update(); - } - } + public CruiseSign() { + super("movecraft.cruisesign", true, "ON", "OFF"); } - @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) - public void onSignClick(@NotNull PlayerInteractEvent event) { - if (event.getAction() != Action.RIGHT_CLICK_BLOCK) - return; + @Override + protected void setCraftCruising(Player player, CruiseDirection direction) { - BlockState state = event.getClickedBlock().getState(); - if (!(state instanceof Sign)) - return; - - Sign sign = (Sign) state; - String line = ChatColor.stripColor(sign.getLine(0)); - if (line.equalsIgnoreCase("Cruise: OFF")) { - event.setCancelled(true); - Craft c = CraftManager.getInstance().getCraftByPlayer(event.getPlayer()); - if (c == null || !c.getType().getBoolProperty(CraftType.CAN_CRUISE)) - return; - if (!(sign.getBlockData() instanceof Directional)) - return; + } - sign.setLine(0, "Cruise: ON"); - sign.update(true); + @Override + protected CruiseDirection getCruiseDirection(AbstractSignListener.SignWrapper sign) { + BlockFace face = sign.facing(); + face = face.getOppositeFace(); + return CruiseDirection.fromBlockFace(face); + } - c.setCruiseDirection(CruiseDirection.fromBlockFace(((Directional) sign.getBlockData()).getFacing())); - c.setLastCruiseUpdate(System.currentTimeMillis()); - c.setCruising(true); - c.resetSigns(sign); - if (!c.getType().getBoolProperty(CraftType.MOVE_ENTITIES)) { - CraftManager.getInstance().addReleaseTask(c); + @Override + protected boolean isSignValid(Action clickType, AbstractSignListener.SignWrapper sign, Player player) { + if (super.isSignValid(clickType, sign, player)) { + switch(sign.facing()) { + case NORTH: + case EAST: + case SOUTH: + case WEST: + return true; + default: + return false; } } - else if (line.equalsIgnoreCase("Cruise: ON")) { - event.setCancelled(true); - Craft c = CraftManager.getInstance().getCraftByPlayer(event.getPlayer()); - if (c == null || !c.getType().getBoolProperty(CraftType.CAN_CRUISE)) - return; + return false; + } - sign.setLine(0, "Cruise: OFF"); - sign.update(true); - c.setCruising(false); - c.resetSigns(sign); + @Override + protected void onAfterStoppingCruise(Craft craft, AbstractSignListener.SignWrapper signWrapper, Player player) { + super.onAfterStoppingCruise(craft, signWrapper, player); + if (!craft.getType().getBoolProperty(CraftType.MOVE_ENTITIES)) { + CraftManager.getInstance().addReleaseTask(craft); } } - @EventHandler(priority = EventPriority.NORMAL) - public void onSignChange(@NotNull SignChangeEvent event) { - Player player = event.getPlayer(); - String line = ChatColor.stripColor(event.getLine(0)); - if (line == null) - return; - if (!line.equalsIgnoreCase("Cruise: OFF") && !line.equalsIgnoreCase("Cruise: ON")) - return; - if (player.hasPermission("movecraft.cruisesign") || !Settings.RequireCreatePerm) - return; + @Override + protected void onCraftIsBusy(Player player, Craft craft) { + // Ignore + } + + @Override + protected void onCraftNotFound(Player player, AbstractSignListener.SignWrapper sign) { - player.sendMessage(I18nSupport.getInternationalisedString("Insufficient Permissions")); - event.setCancelled(true); + } + + @Override + protected boolean canPlayerUseSignOn(Player player, @Nullable Craft craft) { + if (super.canPlayerUseSignOn(player, craft)) { + return craft.getType().getBoolProperty(CraftType.CAN_CRUISE) + } + return false; } } diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractCruiseSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractCruiseSign.java index 4916d8b7f..7b25766bd 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractCruiseSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractCruiseSign.java @@ -3,6 +3,7 @@ import net.countercraft.movecraft.CruiseDirection; import net.countercraft.movecraft.craft.Craft; import net.countercraft.movecraft.craft.PilotedCraft; +import net.countercraft.movecraft.craft.type.CraftType; import net.countercraft.movecraft.events.CraftDetectEvent; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.Style; @@ -64,6 +65,14 @@ public boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action return false; } + protected void onAfterStoppingCruise(Craft craft, AbstractSignListener.SignWrapper signWrapper, Player player) { + + } + + protected void onAfterStartingCruise(Craft craft, AbstractSignListener.SignWrapper signWrapper, Player player) { + + } + @Override protected boolean internalProcessSign(Action clickType, AbstractSignListener.SignWrapper sign, Player player, Craft craft) { boolean isOn = this.isOnOrOff(sign); @@ -81,11 +90,21 @@ protected boolean internalProcessSign(Action clickType, AbstractSignListener.Sig // TODO: What to replace this with? craft.resetSigns(sign.block()); + if (willBeOn) { + this.onAfterStartingCruise(craft, sign, player); + } else { + this.onAfterStoppingCruise(craft, sign, player); + } + return true; } @Override public boolean processSignChange(SignChangeEvent event, AbstractSignListener.SignWrapper sign) { + String header = sign.getRaw(0).trim(); + if (header.equalsIgnoreCase(this.ident)) { + sign.line(0, buildHeaderOff()); + } return true; } From 6913afeb63640a14cf103da4b826e0b755a8c9ad Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Sat, 10 Aug 2024 15:17:01 +0200 Subject: [PATCH 034/122] forgot that --- .../movecraft/sign/CruiseSign.java | 20 +------------------ 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/CruiseSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/CruiseSign.java index 91a3af6c2..d425effad 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/CruiseSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/CruiseSign.java @@ -1,30 +1,12 @@ package net.countercraft.movecraft.sign; import net.countercraft.movecraft.CruiseDirection; -import net.countercraft.movecraft.MovecraftLocation; -import net.countercraft.movecraft.config.Settings; import net.countercraft.movecraft.craft.Craft; import net.countercraft.movecraft.craft.CraftManager; import net.countercraft.movecraft.craft.type.CraftType; -import net.countercraft.movecraft.events.CraftDetectEvent; -import net.countercraft.movecraft.localisation.I18nSupport; -import org.bukkit.ChatColor; -import org.bukkit.Tag; -import org.bukkit.World; -import org.bukkit.block.Block; import org.bukkit.block.BlockFace; -import org.bukkit.block.BlockState; -import org.bukkit.block.Sign; -import org.bukkit.block.data.Directional; -import org.bukkit.block.data.type.WallSign; 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.block.SignChangeEvent; -import org.bukkit.event.player.PlayerInteractEvent; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class CruiseSign extends AbstractCruiseSign { @@ -82,7 +64,7 @@ protected void onCraftNotFound(Player player, AbstractSignListener.SignWrapper s @Override protected boolean canPlayerUseSignOn(Player player, @Nullable Craft craft) { if (super.canPlayerUseSignOn(player, craft)) { - return craft.getType().getBoolProperty(CraftType.CAN_CRUISE) + return craft.getType().getBoolProperty(CraftType.CAN_CRUISE); } return false; } From 57c9d9895c09ea532a0db72acf420eb4e554c860 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Sat, 10 Aug 2024 15:28:04 +0200 Subject: [PATCH 035/122] migrate cruise signs --- .../net/countercraft/movecraft/Movecraft.java | 6 +- .../movecraft/sign/AscendSign.java | 109 ++++++------------ .../movecraft/sign/CruiseSign.java | 6 +- .../movecraft/sign/DescendSign.java | 107 ++++++----------- .../movecraft/sign/AbstractCruiseSign.java | 5 +- 5 files changed, 81 insertions(+), 152 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java b/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java index 69b47f76f..4db6337c8 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java @@ -213,11 +213,13 @@ public void onEnable() { getServer().getPluginManager().registerEvents(new BlockListener(), this); getServer().getPluginManager().registerEvents(new PlayerListener(), this); getServer().getPluginManager().registerEvents(new ChunkManager(), this); - getServer().getPluginManager().registerEvents(new AscendSign(), this); + //getServer().getPluginManager().registerEvents(new AscendSign(), this); + AbstractMovecraftSign.register("Ascend:", new AscendSign(), true); getServer().getPluginManager().registerEvents(new CraftSign(), this); //getServer().getPluginManager().registerEvents(new CruiseSign(), this); AbstractMovecraftSign.register("Cruise:", new CruiseSign(), true); - getServer().getPluginManager().registerEvents(new DescendSign(), this); + //getServer().getPluginManager().registerEvents(new DescendSign(), this); + AbstractMovecraftSign.register("Descend:", new DescendSign(), true); //getServer().getPluginManager().registerEvents(new HelmSign(), this); AbstractMovecraftSign.register("[Helm]", new HelmSign(), true); AbstractMovecraftSign.register(HelmSign.PRETTY_HEADER, new HelmSign(), true); diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/AscendSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/AscendSign.java index e59193e3b..60dc0b1e3 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/AscendSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/AscendSign.java @@ -1,93 +1,52 @@ package net.countercraft.movecraft.sign; import net.countercraft.movecraft.CruiseDirection; -import net.countercraft.movecraft.MovecraftLocation; import net.countercraft.movecraft.craft.Craft; import net.countercraft.movecraft.craft.CraftManager; import net.countercraft.movecraft.craft.type.CraftType; -import net.countercraft.movecraft.events.CraftDetectEvent; -import org.bukkit.ChatColor; -import org.bukkit.Tag; -import org.bukkit.World; -import org.bukkit.block.Block; -import org.bukkit.block.BlockState; -import org.bukkit.block.Sign; -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.PlayerInteractEvent; -import org.jetbrains.annotations.NotNull; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.Nullable; -public class AscendSign implements Listener { +public class AscendSign extends AbstractCruiseSign { - @EventHandler - public void onCraftDetect(CraftDetectEvent event){ - World world = event.getCraft().getWorld(); - for(MovecraftLocation location: event.getCraft().getHitBox()){ - var block = location.toBukkit(world).getBlock(); - if(!Tag.SIGNS.isTagged(block.getType())){ - continue; - } - BlockState state = block.getState(); - if(block.getState() instanceof Sign){ - Sign sign = (Sign) block.getState(); - if (ChatColor.stripColor(sign.getLine(0)).equalsIgnoreCase("Ascend: ON")) { - sign.setLine(0, "Ascend: OFF"); - sign.update(); - } - } - } + public AscendSign() { + super(true, "ON", "OFF"); } + @Override + protected void setCraftCruising(Player player, CruiseDirection direction, Craft craft) { + craft.setCruiseDirection(direction); + craft.setLastCruiseUpdate(System.currentTimeMillis()); + craft.setCruising(true); + } - @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) - public void onSignClickEvent(@NotNull PlayerInteractEvent event){ - if (event.getAction() != Action.RIGHT_CLICK_BLOCK) { - return; - } - Block block = event.getClickedBlock(); - if (!(block.getState() instanceof Sign)){ - return; - } + @Override + protected CruiseDirection getCruiseDirection(AbstractSignListener.SignWrapper sign) { + return CruiseDirection.UP; + } - Sign sign = (Sign) block.getState(); - if (ChatColor.stripColor(sign.getLine(0)).equalsIgnoreCase("Ascend: OFF")) { - event.setCancelled(true); - if (CraftManager.getInstance().getCraftByPlayer(event.getPlayer()) == null) { - return; - } - Craft c = CraftManager.getInstance().getCraftByPlayer(event.getPlayer()); - if (!c.getType().getBoolProperty(CraftType.CAN_CRUISE)) { - return; - } - //c.resetSigns(true, false, true); - sign.setLine(0, "Ascend: ON"); - sign.update(true); + @Override + protected void onCraftIsBusy(Player player, Craft craft) { + // Ignore + } - c.setCruiseDirection(CruiseDirection.UP); - c.setLastCruiseUpdate(System.currentTimeMillis()); - c.setCruising(true); - c.resetSigns(sign); + @Override + protected void onCraftNotFound(Player player, AbstractSignListener.SignWrapper sign) { - if (!c.getType().getBoolProperty(CraftType.MOVE_ENTITIES)) { - CraftManager.getInstance().addReleaseTask(c); - } - return; - } - if (!ChatColor.stripColor(sign.getLine(0)).equalsIgnoreCase("Ascend: ON")) { - return; - } - event.setCancelled(true); - Craft c = CraftManager.getInstance().getCraftByPlayer(event.getPlayer()); - if (c == null || !c.getType().getBoolProperty(CraftType.CAN_CRUISE)) { - return; - } - sign.setLine(0, "Ascend: OFF"); - sign.update(true); + } - c.setCruising(false); - c.resetSigns(sign); + @Override + protected void onAfterStoppingCruise(Craft craft, AbstractSignListener.SignWrapper signWrapper, Player player) { + if (!craft.getType().getBoolProperty(CraftType.MOVE_ENTITIES)) { + CraftManager.getInstance().addReleaseTask(craft); + } + } + @Override + protected boolean canPlayerUseSignOn(Player player, @Nullable Craft craft) { + if (super.canPlayerUseSignOn(player, craft)) { + return craft.getType().getBoolProperty(CraftType.CAN_CRUISE); + } + return false; } } diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/CruiseSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/CruiseSign.java index d425effad..5c28d2cb1 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/CruiseSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/CruiseSign.java @@ -16,8 +16,10 @@ public CruiseSign() { } @Override - protected void setCraftCruising(Player player, CruiseDirection direction) { - + protected void setCraftCruising(Player player, CruiseDirection direction, Craft craft) { + craft.setCruiseDirection(direction); + craft.setLastCruiseUpdate(System.currentTimeMillis()); + craft.setCruising(true); } @Override diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/DescendSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/DescendSign.java index 2d638689b..2ccecd465 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/DescendSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/DescendSign.java @@ -1,86 +1,53 @@ package net.countercraft.movecraft.sign; import net.countercraft.movecraft.CruiseDirection; -import net.countercraft.movecraft.MovecraftLocation; import net.countercraft.movecraft.craft.Craft; import net.countercraft.movecraft.craft.CraftManager; import net.countercraft.movecraft.craft.type.CraftType; -import net.countercraft.movecraft.events.CraftDetectEvent; -import org.bukkit.ChatColor; -import org.bukkit.Tag; -import org.bukkit.World; -import org.bukkit.block.BlockState; -import org.bukkit.block.Sign; -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.PlayerInteractEvent; -import org.jetbrains.annotations.NotNull; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.Nullable; -public final class DescendSign implements Listener{ +// TODO: Unify with AscendSign to use a common "VerticalCruiseSign" class +public class DescendSign extends AbstractCruiseSign { - @EventHandler - public void onCraftDetect(CraftDetectEvent event){ - World world = event.getCraft().getWorld(); - for(MovecraftLocation location: event.getCraft().getHitBox()){ - var block = location.toBukkit(world).getBlock(); - if(!Tag.SIGNS.isTagged(block.getType())){ - continue; - } - BlockState state = block.getState(); - if(state instanceof Sign){ - Sign sign = (Sign) state; - if (ChatColor.stripColor(sign.getLine(0)).equalsIgnoreCase("Descend: ON")) { - sign.setLine(0, "Descend: OFF"); - sign.update(); - } - } - } + public DescendSign() { + super(true, "ON", "OFF"); } - @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) - public void onSignClick(@NotNull PlayerInteractEvent event) { - if (event.getAction() != Action.RIGHT_CLICK_BLOCK) { - return; - } - BlockState state = event.getClickedBlock().getState(); - if (!(state instanceof Sign)) { - return; - } - Sign sign = (Sign) state; - if (ChatColor.stripColor(sign.getLine(0)).equalsIgnoreCase("Descend: OFF")) { - event.setCancelled(true); - if (CraftManager.getInstance().getCraftByPlayer(event.getPlayer()) == null) { - return; - } - Craft c = CraftManager.getInstance().getCraftByPlayer(event.getPlayer()); - if (!c.getType().getBoolProperty(CraftType.CAN_CRUISE)) { - return; - } - //c.resetSigns(true, true, false); - sign.setLine(0, "Descend: ON"); - sign.update(true); + @Override + protected void setCraftCruising(Player player, CruiseDirection direction, Craft craft) { + craft.setCruiseDirection(direction); + craft.setLastCruiseUpdate(System.currentTimeMillis()); + craft.setCruising(true); + } + + @Override + protected CruiseDirection getCruiseDirection(AbstractSignListener.SignWrapper sign) { + return CruiseDirection.DOWN; + } - c.setCruiseDirection(CruiseDirection.DOWN); - c.setLastCruiseUpdate(System.currentTimeMillis()); - c.setCruising(true); - c.resetSigns(sign); + @Override + protected void onCraftIsBusy(Player player, Craft craft) { + // Ignore + } + + @Override + protected void onCraftNotFound(Player player, AbstractSignListener.SignWrapper sign) { + + } - if (!c.getType().getBoolProperty(CraftType.MOVE_ENTITIES)) { - CraftManager.getInstance().addReleaseTask(c); - } - return; + @Override + protected void onAfterStoppingCruise(Craft craft, AbstractSignListener.SignWrapper signWrapper, Player player) { + if (!craft.getType().getBoolProperty(CraftType.MOVE_ENTITIES)) { + CraftManager.getInstance().addReleaseTask(craft); } - if (ChatColor.stripColor(sign.getLine(0)).equalsIgnoreCase("Descend: ON")) { - event.setCancelled(true); - Craft c = CraftManager.getInstance().getCraftByPlayer(event.getPlayer()); - if (c != null && c.getType().getBoolProperty(CraftType.CAN_CRUISE)) { - sign.setLine(0, "Descend: OFF"); - sign.update(true); - c.setCruising(false); - c.resetSigns(sign); - } + } + + @Override + protected boolean canPlayerUseSignOn(Player player, @Nullable Craft craft) { + if (super.canPlayerUseSignOn(player, craft)) { + return craft.getType().getBoolProperty(CraftType.CAN_CRUISE); } + return false; } } diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractCruiseSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractCruiseSign.java index 7b25766bd..e4f622643 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractCruiseSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractCruiseSign.java @@ -3,7 +3,6 @@ import net.countercraft.movecraft.CruiseDirection; import net.countercraft.movecraft.craft.Craft; import net.countercraft.movecraft.craft.PilotedCraft; -import net.countercraft.movecraft.craft.type.CraftType; import net.countercraft.movecraft.events.CraftDetectEvent; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.Style; @@ -79,7 +78,7 @@ protected boolean internalProcessSign(Action clickType, AbstractSignListener.Sig boolean willBeOn = !isOn; if (willBeOn) { CruiseDirection direction = this.getCruiseDirection(sign); - this.setCraftCruising(player, direction); + this.setCraftCruising(player, direction, craft); } else { craft.setCruising(false); } @@ -135,7 +134,7 @@ protected Component buildHeaderOff() { return Component.text(this.ident).append(Component.text(": ")).append(Component.text(this.suffixOff, Style.style(TextColor.color(255, 0, 0)))); } - protected abstract void setCraftCruising(Player player, CruiseDirection direction); + protected abstract void setCraftCruising(Player player, CruiseDirection direction, Craft craft); // TODO: Rework cruise direction to vectors => Vector defines the skip distance and the direction protected abstract CruiseDirection getCruiseDirection(AbstractSignListener.SignWrapper sign); } From 38c644a90616525749e8ceba2c33dcdab1e8dbc4 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Sat, 10 Aug 2024 16:29:41 +0200 Subject: [PATCH 036/122] fix namesign --- .../java/net/countercraft/movecraft/sign/NameSign.java | 2 +- .../countercraft/movecraft/sign/AbstractSignListener.java | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/NameSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/NameSign.java index 246d960e9..5b75294db 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/NameSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/NameSign.java @@ -78,7 +78,7 @@ public void onCraftDetect(CraftDetectEvent event, AbstractSignListener.SignWrapp return; } - craft.setName(Arrays.stream(sign.getLines()).skip(1).filter(f -> f != null + craft.setName(Arrays.stream(sign.rawLines()).skip(1).filter(f -> f != null && !f.trim().isEmpty()).collect(Collectors.joining(" "))); } } diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java index 3e5cab79b..9019033dd 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java @@ -49,6 +49,13 @@ public String getRaw(int index) { return PlainTextComponentSerializer.plainText().serialize(line(index)); } + public String[] rawLines() { + String[] result = new String[this.lines.size()]; + for (int i = 0; i < result.length; i++) { + result[i] = this.getRaw(i); + } + } + } public abstract SignWrapper[] getSignWrappers(Sign sign); From 0d61dd5c3102b7f0b7c29e10e19b8422a2f6be7f Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Sat, 10 Aug 2024 16:43:18 +0200 Subject: [PATCH 037/122] migrate speed sign --- .../sign/AbstractInformationSign.java | 30 ++++++++++++++----- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractInformationSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractInformationSign.java index 4b452faa1..bd8e14265 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractInformationSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractInformationSign.java @@ -10,6 +10,7 @@ import org.bukkit.block.Sign; import org.bukkit.entity.Player; import org.bukkit.event.block.Action; +import org.bukkit.event.block.SignChangeEvent; import org.jetbrains.annotations.Nullable; public abstract class AbstractInformationSign extends AbstractCraftSign { @@ -29,7 +30,7 @@ protected boolean canPlayerUseSignOn(Player player, Craft craft) { public void onCraftDetect(CraftDetectEvent event, AbstractSignListener.SignWrapper sign) { // TODO: Check if the craft supports this sign? If no, cancel super.onCraftDetect(event, sign); - this.refreshSign(event.getCraft(), sign); + this.refreshSign(event.getCraft(), sign, true); } @Override @@ -40,7 +41,7 @@ public void onSignMovedByCraft(SignTranslateEvent event) { Block block = movecraftLocation.toBukkit(craft.getWorld()).getBlock(); if (block instanceof Sign sign) { for (AbstractSignListener.SignWrapper wrapper : AbstractSignListener.INSTANCE.getSignWrappers(sign)) { - this.refreshSign(event.getCraft(), wrapper); + this.refreshSign(event.getCraft(), wrapper, false); } } } @@ -66,16 +67,21 @@ public boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action @Override protected boolean internalProcessSign(Action clickType, AbstractSignListener.SignWrapper sign, Player player, Craft craft) { - this.refreshSign(craft, sign); + this.refreshSign(craft, sign, false); return true; } - protected void refreshSign(Craft craft, AbstractSignListener.SignWrapper sign) { + protected void refreshSign(@Nullable Craft craft, AbstractSignListener.SignWrapper sign, boolean fillDefault) { boolean changedSome = false; Component[] updatePayload = new Component[sign.lines().size()]; for(int i = 1; i < sign.lines().size(); i++) { Component oldComponent = sign.line(i); - Component potentiallyNew = this.getUpdateString(i, oldComponent, craft); + Component potentiallyNew; + if (craft == null || fillDefault) { + potentiallyNew = this.getDefaultString(i, oldComponent); + } else { + potentiallyNew = this.getUpdateString(i, oldComponent, craft); + } if (potentiallyNew != null && !potentiallyNew.equals(oldComponent)) { String oldValue = PlainTextComponentSerializer.plainText().serialize(oldComponent); String newValue = PlainTextComponentSerializer.plainText().serialize(potentiallyNew); @@ -91,12 +97,20 @@ protected void refreshSign(Craft craft, AbstractSignListener.SignWrapper sign) { } } + @Override + public boolean processSignChange(SignChangeEvent event, AbstractSignListener.SignWrapper sign) { + this.refreshSign(null, sign, true); + return true; + } + /* - Data to set on the sign. Return null if no update should happen! - Attention: A update will only be performed, if the new and old component are different! - */ + Data to set on the sign. Return null if no update should happen! + Attention: A update will only be performed, if the new and old component are different! + */ @Nullable protected abstract Component getUpdateString(int lineIndex, Component oldData, Craft craft); + @Nullable + protected abstract Component getDefaultString(int lineIndex, Component oldComponent); /* * @param newComponents: Array of nullable values. The index represents the index on the sign. Only contains the updated components From f9681d4eb891fb542d3765e97ed226f9ed66b8e9 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Sat, 10 Aug 2024 17:03:58 +0200 Subject: [PATCH 038/122] own wrapper for SignTranslateEvent TODO: Separate PR to migrate that to use Adventure! On 1.20+: Also call per side! --- .../movecraft/compat/v1_18/SignListener.java | 42 ++++++++++++++- .../movecraft/compat/v1_20/SignListener.java | 51 ++++++++++++++++++- .../movecraft/compat/v1_21/SignListener.java | 51 ++++++++++++++++++- 3 files changed, 141 insertions(+), 3 deletions(-) diff --git a/v1_18/src/main/java/net/countercraft/movecraft/compat/v1_18/SignListener.java b/v1_18/src/main/java/net/countercraft/movecraft/compat/v1_18/SignListener.java index d57a53000..7028b7bd2 100644 --- a/v1_18/src/main/java/net/countercraft/movecraft/compat/v1_18/SignListener.java +++ b/v1_18/src/main/java/net/countercraft/movecraft/compat/v1_18/SignListener.java @@ -1,12 +1,18 @@ package net.countercraft.movecraft.compat.v1_18; +import net.countercraft.movecraft.events.SignTranslateEvent; import net.countercraft.movecraft.sign.AbstractSignListener; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; import org.bukkit.block.BlockFace; import org.bukkit.block.Sign; import org.bukkit.block.data.Directional; import org.bukkit.event.block.SignChangeEvent; import org.bukkit.event.player.PlayerInteractEvent; +import java.util.ArrayList; +import java.util.List; + public class SignListener extends AbstractSignListener { protected final SignWrapper createFromSign(final Sign sign) { @@ -27,9 +33,43 @@ public SignWrapper[] getSignWrappers(Sign sign) { return new SignWrapper[] {wrapper}; } + @Override + public SignWrapper[] getSignWrappers(Sign sign, SignTranslateEvent event) { + SignWrapper[] wrappers = new SignWrapper[1]; + for (int i = 0; i < wrappers.length; i++) { + BlockFace face = ((Directional) sign.getBlockData()).getFacing(); + List lines = new ArrayList<>(); + for (int j = 0; j < event.getLines().length; j++) { + lines.add(Component.text(event.getLine(j))); + } + SignWrapper wrapper = new SignWrapper( + sign, + (k) -> { + String valTmp = event.getLine(k); + return Component.text(valTmp); + }, + lines, + (k, component) -> { + event.setLine(k, PlainTextComponentSerializer.plainText().serialize(component)); + }, + face + ); + wrappers[i] = wrapper; + } + return wrappers; + } + @Override protected SignWrapper getSignWrapper(Sign sign, SignChangeEvent signChangeEvent) { - return this.createFromSign(sign); + BlockFace face = ((Directional) sign.getBlockData()).getFacing(); + SignWrapper wrapper = new SignWrapper( + sign, + signChangeEvent::line, + signChangeEvent.lines(), + signChangeEvent::line, + face + ); + return wrapper; } @Override diff --git a/v1_20/src/main/java/net/countercraft/movecraft/compat/v1_20/SignListener.java b/v1_20/src/main/java/net/countercraft/movecraft/compat/v1_20/SignListener.java index 791e3d71b..a6641bf0d 100644 --- a/v1_20/src/main/java/net/countercraft/movecraft/compat/v1_20/SignListener.java +++ b/v1_20/src/main/java/net/countercraft/movecraft/compat/v1_20/SignListener.java @@ -1,6 +1,9 @@ package net.countercraft.movecraft.compat.v1_20; +import net.countercraft.movecraft.events.SignTranslateEvent; import net.countercraft.movecraft.sign.AbstractSignListener; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; import org.bukkit.block.BlockFace; import org.bukkit.block.Sign; import org.bukkit.block.data.Directional; @@ -10,6 +13,9 @@ import org.bukkit.event.player.PlayerInteractEvent; import org.jetbrains.annotations.NotNull; +import java.util.ArrayList; +import java.util.List; + public class SignListener extends AbstractSignListener { protected final SignWrapper createFromSide(final Sign sign, final Side side) { @@ -45,10 +51,53 @@ public SignWrapper[] getSignWrappers(Sign sign) { return wrappers; } + @Override + public SignWrapper[] getSignWrappers(Sign sign, SignTranslateEvent event) { + Side[] sides = new Side[Side.values().length]; + SignWrapper[] wrappers = new SignWrapper[sides.length]; + for (int i = 0; i < sides.length; i++) { + Side side = sides[i]; + SignSide signSide = sign.getSide(side); + BlockFace face = ((Directional) sign.getBlockData()).getFacing(); + if (side == Side.BACK) { + face = face.getOppositeFace(); + } + List lines = new ArrayList<>(); + for (int j = 0; j < event.getLines().length; j++) { + lines.add(Component.text(event.getLine(j))); + } + SignWrapper wrapper = new SignWrapper( + sign, + (k) -> { + String valTmp = event.getLine(k); + return Component.text(valTmp); + }, + lines, + (k, component) -> { + event.setLine(k, PlainTextComponentSerializer.plainText().serialize(component)); + }, + face + ); + wrappers[i] = wrapper; + } + return wrappers; + } + @Override protected SignWrapper getSignWrapper(Sign sign, SignChangeEvent signChangeEvent) { @NotNull Side side = signChangeEvent.getSide(); - return this.createFromSide(sign, side); + BlockFace face = ((Directional) sign.getBlockData()).getFacing(); + if (side == Side.BACK) { + face = face.getOppositeFace(); + } + SignWrapper wrapper = new SignWrapper( + sign, + signChangeEvent::line, + signChangeEvent.lines(), + signChangeEvent::line, + face + ); + return wrapper; } @Override diff --git a/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/SignListener.java b/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/SignListener.java index ca957fba8..2c1eb9e8d 100644 --- a/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/SignListener.java +++ b/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/SignListener.java @@ -1,6 +1,9 @@ package net.countercraft.movecraft.compat.v1_21; +import net.countercraft.movecraft.events.SignTranslateEvent; import net.countercraft.movecraft.sign.AbstractSignListener; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; import org.bukkit.block.BlockFace; import org.bukkit.block.Sign; import org.bukkit.block.data.Directional; @@ -10,6 +13,9 @@ import org.bukkit.event.player.PlayerInteractEvent; import org.jetbrains.annotations.NotNull; +import java.util.ArrayList; +import java.util.List; + public class SignListener extends AbstractSignListener { protected final SignWrapper createFromSide(final Sign sign, final Side side) { @@ -45,10 +51,53 @@ public SignWrapper[] getSignWrappers(Sign sign) { return wrappers; } + @Override + public SignWrapper[] getSignWrappers(Sign sign, SignTranslateEvent event) { + Side[] sides = new Side[Side.values().length]; + SignWrapper[] wrappers = new SignWrapper[sides.length]; + for (int i = 0; i < sides.length; i++) { + Side side = sides[i]; + SignSide signSide = sign.getSide(side); + BlockFace face = ((Directional) sign.getBlockData()).getFacing(); + if (side == Side.BACK) { + face = face.getOppositeFace(); + } + List lines = new ArrayList<>(); + for (int j = 0; j < event.getLines().length; j++) { + lines.add(Component.text(event.getLine(j))); + } + SignWrapper wrapper = new SignWrapper( + sign, + (k) -> { + String valTmp = event.getLine(k); + return Component.text(valTmp); + }, + lines, + (k, component) -> { + event.setLine(k, PlainTextComponentSerializer.plainText().serialize(component)); + }, + face + ); + wrappers[i] = wrapper; + } + return wrappers; + } + @Override protected SignWrapper getSignWrapper(Sign sign, SignChangeEvent signChangeEvent) { @NotNull Side side = signChangeEvent.getSide(); - return this.createFromSide(sign, side); + BlockFace face = ((Directional) sign.getBlockData()).getFacing(); + if (side == Side.BACK) { + face = face.getOppositeFace(); + } + SignWrapper wrapper = new SignWrapper( + sign, + signChangeEvent::line, + signChangeEvent.lines(), + signChangeEvent::line, + face + ); + return wrapper; } @Override From 50b83dcc0c1f2bfb9545d2ab21abd33471108581 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Sat, 10 Aug 2024 17:05:11 +0200 Subject: [PATCH 039/122] actually return something --- .../net/countercraft/movecraft/sign/AbstractSignListener.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java index 9019033dd..44ba02b2d 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java @@ -54,11 +54,13 @@ public String[] rawLines() { for (int i = 0; i < result.length; i++) { result[i] = this.getRaw(i); } + return result; } } public abstract SignWrapper[] getSignWrappers(Sign sign); + public abstract SignWrapper[] getSignWrappers(Sign sign, SignTranslateEvent event); protected abstract SignWrapper getSignWrapper(Sign sign, SignChangeEvent signChangeEvent); protected abstract SignWrapper getSignWrapper(Sign sign, PlayerInteractEvent interactEvent); From d95c1d0278d519801b8a9b19be04e6f9e450376c Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Sat, 10 Aug 2024 17:05:24 +0200 Subject: [PATCH 040/122] migrate speed sign --- .../movecraft/sign/SpeedSign.java | 116 ++++++++++-------- 1 file changed, 62 insertions(+), 54 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/SpeedSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/SpeedSign.java index 1d77fee88..9ab81a9fe 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/SpeedSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/SpeedSign.java @@ -7,6 +7,7 @@ import net.countercraft.movecraft.events.CraftDetectEvent; import net.countercraft.movecraft.events.SignTranslateEvent; import net.countercraft.movecraft.localisation.I18nSupport; +import net.kyori.adventure.text.Component; import net.md_5.bungee.api.ChatMessageType; import net.md_5.bungee.api.chat.TextComponent; import org.bukkit.ChatColor; @@ -19,71 +20,27 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.block.Action; +import org.bukkit.event.block.SignChangeEvent; import org.bukkit.event.player.PlayerInteractEvent; +import org.jetbrains.annotations.Nullable; -public final class SpeedSign implements Listener{ - @EventHandler - public void onCraftDetect(CraftDetectEvent event){ - World world = event.getCraft().getWorld(); - for(MovecraftLocation location: event.getCraft().getHitBox()){ - var block = location.toBukkit(world).getBlock(); - if(!Tag.SIGNS.isTagged(block.getType())) - continue; +public class SpeedSign extends AbstractInformationSign { - BlockState state = block.getState(); - if (!(state instanceof Sign)) - continue; - - Sign sign = (Sign) state; - if (ChatColor.stripColor(sign.getLine(0)).equalsIgnoreCase("Speed:")) { - sign.setLine(1, "0 m/s"); - sign.setLine(2, "0ms"); - sign.setLine(3, "0T"); - sign.update(); - } - } + public SpeedSign() { + super(); } - @EventHandler - public void onSignTranslate(SignTranslateEvent event) { - Craft craft = event.getCraft(); - if (!ChatColor.stripColor(event.getLine(0)).equalsIgnoreCase("Speed:")) { - return; - } - event.setLine(1,String.format("%.2f",craft.getSpeed()) + "m/s"); - event.setLine(2,String.format("%.2f",craft.getMeanCruiseTime() * 1000) + "ms"); - event.setLine(3,craft.getTickCooldown() + "T"); - } - - @EventHandler - public void onSignClick(PlayerInteractEvent event) { - if (event.getAction() != Action.RIGHT_CLICK_BLOCK) - return; - - Block block = event.getClickedBlock(); - if (block == null) - return; - - BlockState state = block.getState(); - if (!(state instanceof Sign)) - return; - - Sign sign = (Sign) state; - if (!ChatColor.stripColor(sign.getLine(0)).equalsIgnoreCase("Speed:")) - return; - - event.setCancelled(true); - Player player = event.getPlayer(); - Craft craft = CraftManager.getInstance().getCraftByPlayer(player); - if (craft == null) - return; + @Override + protected boolean internalProcessSign(Action clickType, AbstractSignListener.SignWrapper sign, Player player, Craft craft) { + if (clickType != Action.RIGHT_CLICK_BLOCK) + return false; final int gearShifts = craft.getType().getIntProperty(CraftType.GEAR_SHIFTS); int currentGear = craft.getCurrentGear(); if (gearShifts == 1) { player.spigot().sendMessage(ChatMessageType.ACTION_BAR, new TextComponent(I18nSupport.getInternationalisedString("Gearshift - Disabled for craft type"))); - return; + return false; } currentGear++; if (currentGear > gearShifts) @@ -92,5 +49,56 @@ public void onSignClick(PlayerInteractEvent event) { new TextComponent(I18nSupport.getInternationalisedString("Gearshift - Gear changed") + " " + currentGear + " / " + gearShifts)); craft.setCurrentGear(currentGear); + + return true; + } + + @Override + protected @Nullable Component getUpdateString(int lineIndex, Component oldData, Craft craft) { + // TODO: Display the gear somewhere? + switch(lineIndex) { + case 1: + return Component.text(String.format("%.2f",craft.getSpeed()) + "m/s"); + case 2: + return Component.text(String.format("%.2f",craft.getMeanCruiseTime() * 1000) + "ms"); + case 3: + return Component.text(craft.getTickCooldown() + "T"); + default: + return null; + } } + + static final Component[] DEFAULT_VALUES = new Component[] { + null, + Component.text("0 m/s"), + Component.text("0 ms"), + Component.text("0 T") + }; + + @Override + protected @Nullable Component getDefaultString(int lineIndex, Component oldComponent) { + // TODO: Display the gear somewhere? + return DEFAULT_VALUES[lineIndex]; + } + + @Override + protected void performUpdate(Component[] newComponents, AbstractSignListener.SignWrapper sign) { + for (int i = 0; i < newComponents.length; i++) { + Component newComp = newComponents[i]; + if (newComp != null) { + sign.line(i, newComp); + } + } + } + + @Override + protected void sendUpdatePacket(Craft craft, AbstractSignListener.SignWrapper sign) { + + } + + @Override + protected void onCraftIsBusy(Player player, Craft craft) { + return; + } + } From 2a53a7c8c5a13c90d20feb1349deb4c9555e1adb Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Sat, 10 Aug 2024 17:05:54 +0200 Subject: [PATCH 041/122] forgot those --- .../src/main/java/net/countercraft/movecraft/Movecraft.java | 3 ++- .../countercraft/movecraft/sign/AbstractInformationSign.java | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java b/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java index 4db6337c8..08955bb50 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java @@ -234,7 +234,8 @@ public void onEnable() { //getServer().getPluginManager().registerEvents(new ReleaseSign(), this); AbstractMovecraftSign.register("Release", new ReleaseSign(), true); getServer().getPluginManager().registerEvents(new RemoteSign(), this); - getServer().getPluginManager().registerEvents(new SpeedSign(), this); + //getServer().getPluginManager().registerEvents(new SpeedSign(), this); + AbstractMovecraftSign.register("Speed:", new SpeedSign(), true); getServer().getPluginManager().registerEvents(new SubcraftRotateSign(), this); //getServer().getPluginManager().registerEvents(new TeleportSign(), this); AbstractMovecraftSign.register("Teleport:", new TeleportSign(), true); diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractInformationSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractInformationSign.java index bd8e14265..c4793f9bc 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractInformationSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractInformationSign.java @@ -40,7 +40,7 @@ public void onSignMovedByCraft(SignTranslateEvent event) { for (MovecraftLocation movecraftLocation : event.getLocations()) { Block block = movecraftLocation.toBukkit(craft.getWorld()).getBlock(); if (block instanceof Sign sign) { - for (AbstractSignListener.SignWrapper wrapper : AbstractSignListener.INSTANCE.getSignWrappers(sign)) { + for (AbstractSignListener.SignWrapper wrapper : AbstractSignListener.INSTANCE.getSignWrappers(sign, event)) { this.refreshSign(event.getCraft(), wrapper, false); } } @@ -94,6 +94,7 @@ protected void refreshSign(@Nullable Craft craft, AbstractSignListener.SignWrapp if (changedSome) { this.performUpdate(updatePayload, sign); this.sendUpdatePacket(craft, sign); + sign.block().update(true); } } From 35ea96697e56ee3cb07631296be5fcea21f63bb8 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Sun, 11 Aug 2024 15:34:29 +0200 Subject: [PATCH 042/122] move status sign class --- .../movecraft/features/status/StatusSign.java | 179 ------------------ .../movecraft/sign/StatusSign.java | 2 + 2 files changed, 2 insertions(+), 179 deletions(-) delete mode 100644 Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java create mode 100644 Movecraft/src/main/java/net/countercraft/movecraft/sign/StatusSign.java diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java deleted file mode 100644 index 1246c1381..000000000 --- a/Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java +++ /dev/null @@ -1,179 +0,0 @@ -package net.countercraft.movecraft.features.status; - -import it.unimi.dsi.fastutil.objects.Object2IntMap; -import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; -import net.countercraft.movecraft.Movecraft; -import net.countercraft.movecraft.MovecraftLocation; -import net.countercraft.movecraft.craft.BaseCraft; -import net.countercraft.movecraft.craft.Craft; -import net.countercraft.movecraft.craft.type.CraftType; -import net.countercraft.movecraft.craft.type.RequiredBlockEntry; -import net.countercraft.movecraft.events.CraftDetectEvent; -import net.countercraft.movecraft.events.SignTranslateEvent; -import net.countercraft.movecraft.features.status.StatusManager; -import net.countercraft.movecraft.util.Counter; -import net.countercraft.movecraft.util.Tags; -import org.bukkit.ChatColor; -import org.bukkit.Material; -import org.bukkit.Tag; -import org.bukkit.World; -import org.bukkit.block.Block; -import org.bukkit.block.BlockState; -import org.bukkit.block.Sign; -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.PlayerInteractEvent; -import org.bukkit.inventory.InventoryHolder; -import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.NotNull; - -import java.util.EnumSet; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.logging.Level; - -public final class StatusSign implements Listener { - - @EventHandler - public void onCraftDetect(CraftDetectEvent event) { - World world = event.getCraft().getWorld(); - for (MovecraftLocation location : event.getCraft().getHitBox()) { - var block = location.toBukkit(world).getBlock(); - if (!Tag.SIGNS.isTagged(block.getType())) { - continue; - } - BlockState state = block.getState(); - if (state instanceof Sign) { - Sign sign = (Sign) state; - if (ChatColor.stripColor(sign.getLine(0)).equalsIgnoreCase("Status:")) { - sign.setLine(1, ""); - sign.setLine(2, ""); - sign.setLine(3, ""); - sign.update(); - } - } - } - } - - @EventHandler - public final void onSignTranslate(SignTranslateEvent event) { - Craft craft = event.getCraft(); - if (!ChatColor.stripColor(event.getLine(0)).equalsIgnoreCase("Status:")) { - return; - } - double fuel = craft.getDataTag(Craft.FUEL); - - int totalNonNegligibleBlocks = 0; - int totalNonNegligibleWaterBlocks = 0; - Counter materials = craft.getDataTag(Craft.MATERIALS); - if (materials.isEmpty()) { - return; - } - for (Material material : materials.getKeySet()) { - if (material.equals(Material.FIRE) || material.isAir()) - continue; - - int add = materials.get(material); - totalNonNegligibleBlocks += add; - if (!Tags.WATER.contains(material)) { - totalNonNegligibleWaterBlocks += add; - } - } - Object2IntMap displayBlocks = new Object2IntOpenHashMap<>(); - for (RequiredBlockEntry entry : craft.getType().getRequiredBlockProperty(CraftType.FLY_BLOCKS)) { - int total = 0; - for (Material material : entry.getMaterials()) { - if (materials.getKeySet().contains(material)) { - total += materials.get(material); - } - } - displayBlocks.putIfAbsent(entry, total); - } - for (RequiredBlockEntry entry : craft.getType().getRequiredBlockProperty(CraftType.MOVE_BLOCKS)) { - int total = 0; - for (Material material : entry.getMaterials()) { - if (materials.getKeySet().contains(material)) { - total += materials.get(material); - } - } - displayBlocks.putIfAbsent(entry, total); - } - int signLine = 1; - int signColumn = 0; - for (RequiredBlockEntry entry : displayBlocks.keySet()) { - if (entry.getMin() == 0.0) { - continue; - } - double percentPresent = (displayBlocks.get(entry) * 100D); - if (craft.getType().getBoolProperty(CraftType.BLOCKED_BY_WATER)) { - percentPresent /= totalNonNegligibleBlocks; - } else { - percentPresent /= totalNonNegligibleWaterBlocks; - } - String signText = ""; - if (percentPresent > entry.getMin() * 1.04) { - signText += ChatColor.GREEN; - } else if (percentPresent > entry.getMin() * 1.02) { - signText += ChatColor.YELLOW; - } else { - signText += ChatColor.RED; - } - if (entry.getName() == null) { - signText += entry.materialsToString().toUpperCase().charAt(0); - } else { - signText += entry.getName().toUpperCase().charAt(0); - } - signText += " "; - signText += (int) percentPresent; - signText += "/"; - signText += (int) entry.getMin(); - signText += " "; - if (signColumn == 0) { - event.setLine(signLine, signText); - signColumn++; - } else if (signLine < 3) { - String existingLine = event.getLine(signLine); - existingLine += signText; - event.setLine(signLine, existingLine); - signLine++; - signColumn = 0; - } - } - - String fuelText = ""; - int cruiseSkipBlocks = (int) craft.getType().getPerWorldProperty(CraftType.PER_WORLD_CRUISE_SKIP_BLOCKS, craft.getWorld()); - cruiseSkipBlocks++; - double fuelBurnRate = (double) craft.getType().getPerWorldProperty(CraftType.PER_WORLD_FUEL_BURN_RATE, craft.getWorld()); - int fuelRange = (int) Math.round((fuel * (1 + cruiseSkipBlocks)) / fuelBurnRate); - if (fuelRange > 1000) { - fuelText += ChatColor.GREEN; - } else if (fuelRange > 100) { - fuelText += ChatColor.YELLOW; - } else { - fuelText += ChatColor.RED; - } - fuelText += "Fuel range:"; - fuelText += fuelRange; - event.setLine(signLine, fuelText); - } - - @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) - public void onSignClickEvent(@NotNull PlayerInteractEvent event) { - if (event.getAction() != Action.RIGHT_CLICK_BLOCK) { - return; - } - Block block = event.getClickedBlock(); - if (!(block.getState() instanceof Sign)) { - return; - } - - Sign sign = (Sign) block.getState(); - if (!ChatColor.stripColor(sign.getLine(0)).equalsIgnoreCase("Status:")) { - return; - } - event.setCancelled(true); - } -} \ No newline at end of file diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/StatusSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/StatusSign.java new file mode 100644 index 000000000..4952f313e --- /dev/null +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/StatusSign.java @@ -0,0 +1,2 @@ +package net.countercraft.movecraft.sign;public class StatusSign { +} From d8826033eb87ef7b1222a5ed1dc4517b58f79d76 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Sun, 11 Aug 2024 15:34:44 +0200 Subject: [PATCH 043/122] add constants for colors and add enum for update reason --- .../sign/AbstractInformationSign.java | 32 +++++++++++++------ 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractInformationSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractInformationSign.java index c4793f9bc..789c856d4 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractInformationSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractInformationSign.java @@ -5,6 +5,8 @@ import net.countercraft.movecraft.events.CraftDetectEvent; import net.countercraft.movecraft.events.SignTranslateEvent; import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.Style; +import net.kyori.adventure.text.format.TextColor; import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; import org.bukkit.block.Block; import org.bukkit.block.Sign; @@ -15,6 +17,17 @@ public abstract class AbstractInformationSign extends AbstractCraftSign { + protected static final Style STYLE_COLOR_GREEN = Style.style(TextColor.color(0, 255, 0)); + protected static final Style STYLE_COLOR_YELLOW = Style.style(TextColor.color(255, 255, 0)); + protected static final Style STYLE_COLOR_RED = Style.style(TextColor.color(255, 0, 0)); + + public enum REFRESH_CAUSE { + SIGN_CREATION, + CRAFT_DETECT, + SIGN_MOVED_BY_CRAFT, + SIGN_CLICK + } + public AbstractInformationSign() { // Info signs only display things, that should not require permissions, also it doesn't matter if the craft is busy or not super(null, true); @@ -30,7 +43,7 @@ protected boolean canPlayerUseSignOn(Player player, Craft craft) { public void onCraftDetect(CraftDetectEvent event, AbstractSignListener.SignWrapper sign) { // TODO: Check if the craft supports this sign? If no, cancel super.onCraftDetect(event, sign); - this.refreshSign(event.getCraft(), sign, true); + this.refreshSign(event.getCraft(), sign, true, REFRESH_CAUSE.CRAFT_DETECT); } @Override @@ -41,7 +54,7 @@ public void onSignMovedByCraft(SignTranslateEvent event) { Block block = movecraftLocation.toBukkit(craft.getWorld()).getBlock(); if (block instanceof Sign sign) { for (AbstractSignListener.SignWrapper wrapper : AbstractSignListener.INSTANCE.getSignWrappers(sign, event)) { - this.refreshSign(event.getCraft(), wrapper, false); + this.refreshSign(event.getCraft(), wrapper, false, REFRESH_CAUSE.SIGN_MOVED_BY_CRAFT); } } } @@ -67,11 +80,11 @@ public boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action @Override protected boolean internalProcessSign(Action clickType, AbstractSignListener.SignWrapper sign, Player player, Craft craft) { - this.refreshSign(craft, sign, false); + this.refreshSign(craft, sign, false, REFRESH_CAUSE.SIGN_CLICK); return true; } - protected void refreshSign(@Nullable Craft craft, AbstractSignListener.SignWrapper sign, boolean fillDefault) { + protected void refreshSign(@Nullable Craft craft, AbstractSignListener.SignWrapper sign, boolean fillDefault, REFRESH_CAUSE refreshCause) { boolean changedSome = false; Component[] updatePayload = new Component[sign.lines().size()]; for(int i = 1; i < sign.lines().size(); i++) { @@ -92,15 +105,14 @@ protected void refreshSign(@Nullable Craft craft, AbstractSignListener.SignWrapp } } if (changedSome) { - this.performUpdate(updatePayload, sign); - this.sendUpdatePacket(craft, sign); - sign.block().update(true); + this.performUpdate(updatePayload, sign, refreshCause); + this.sendUpdatePacket(craft, sign, refreshCause); } } @Override public boolean processSignChange(SignChangeEvent event, AbstractSignListener.SignWrapper sign) { - this.refreshSign(null, sign, true); + this.refreshSign(null, sign, true, REFRESH_CAUSE.SIGN_CREATION); return true; } @@ -118,10 +130,10 @@ public boolean processSignChange(SignChangeEvent event, AbstractSignListener.Sig * * Only gets called if at least one line has changed */ - protected abstract void performUpdate(Component[] newComponents, AbstractSignListener.SignWrapper sign); + protected abstract void performUpdate(Component[] newComponents, AbstractSignListener.SignWrapper sign, REFRESH_CAUSE refreshCause); /* Gets called after performUpdate has been called */ - protected abstract void sendUpdatePacket(Craft craft, AbstractSignListener.SignWrapper sign); + protected abstract void sendUpdatePacket(Craft craft, AbstractSignListener.SignWrapper sign, REFRESH_CAUSE refreshCause); } From 1ede8b7dddce8dc8767dc317cce94d99536dacd6 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Sun, 11 Aug 2024 15:34:55 +0200 Subject: [PATCH 044/122] migrate status sign --- .../net/countercraft/movecraft/Movecraft.java | 4 +- .../movecraft/sign/StatusSign.java | 179 +++++++++++++++++- 2 files changed, 180 insertions(+), 3 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java b/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java index 08955bb50..26297766d 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java @@ -27,7 +27,6 @@ import net.countercraft.movecraft.features.contacts.ContactsManager; import net.countercraft.movecraft.features.contacts.ContactsSign; import net.countercraft.movecraft.features.status.StatusManager; -import net.countercraft.movecraft.features.status.StatusSign; import net.countercraft.movecraft.listener.*; import net.countercraft.movecraft.localisation.I18nSupport; import net.countercraft.movecraft.mapUpdater.MapUpdateManager; @@ -236,6 +235,7 @@ public void onEnable() { getServer().getPluginManager().registerEvents(new RemoteSign(), this); //getServer().getPluginManager().registerEvents(new SpeedSign(), this); AbstractMovecraftSign.register("Speed:", new SpeedSign(), true); + AbstractMovecraftSign.register("Status:", new StatusSign(), true); getServer().getPluginManager().registerEvents(new SubcraftRotateSign(), this); //getServer().getPluginManager().registerEvents(new TeleportSign(), this); AbstractMovecraftSign.register("Teleport:", new TeleportSign(), true); @@ -255,7 +255,7 @@ public void onEnable() { var statusManager = new StatusManager(); statusManager.runTaskTimerAsynchronously(this, 0, 1); getServer().getPluginManager().registerEvents(statusManager, this); - getServer().getPluginManager().registerEvents(new StatusSign(), this); + //getServer().getPluginManager().registerEvents(new StatusSign(), this); logger.info("[V " + getDescription().getVersion() + "] has been enabled."); } diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/StatusSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/StatusSign.java index 4952f313e..d750f50a5 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/StatusSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/StatusSign.java @@ -1,2 +1,179 @@ -package net.countercraft.movecraft.sign;public class StatusSign { +package net.countercraft.movecraft.sign; + +import it.unimi.dsi.fastutil.objects.Object2IntMap; +import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import net.countercraft.movecraft.craft.Craft; +import net.countercraft.movecraft.craft.type.CraftType; +import net.countercraft.movecraft.craft.type.RequiredBlockEntry; +import net.countercraft.movecraft.util.Counter; +import net.countercraft.movecraft.util.Tags; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.Style; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +// TODO: Split this into multiple signs? Separate sign for fuel would make sense +public class StatusSign extends AbstractInformationSign { + + Object2IntMap displayBlocks = new Object2IntOpenHashMap<>(); + List displayComponents = new ObjectArrayList<>(); + int totalNonNegligibleBlocks = 0; + int totalNonNegligibleWaterBlocks = 0; + + public static final Component EMPTY = Component.text(""); + + protected static final int FUEL_LINE_INDEX = 3; + protected static final int BLOCK_LINE_INDEX_TOP = 1; + protected static final int BLOCK_LINE_INDEX_BOTTOM = 2; + + @Override + protected @Nullable Component getUpdateString(int lineIndex, Component oldData, Craft craft) { + switch(lineIndex) { + case FUEL_LINE_INDEX: + return calcFuel(craft); + case BLOCK_LINE_INDEX_TOP: + return displayComponents.get(0); + case BLOCK_LINE_INDEX_BOTTOM: + return displayComponents.get(1); + } + return oldData; + } + + protected Component calcFuel(Craft craft) { + double fuel = craft.getDataTag(Craft.FUEL); + int cruiseSkipBlocks = (int) craft.getType().getPerWorldProperty(CraftType.PER_WORLD_CRUISE_SKIP_BLOCKS, craft.getWorld()); + cruiseSkipBlocks++; + double fuelBurnRate = (double) craft.getType().getPerWorldProperty(CraftType.PER_WORLD_FUEL_BURN_RATE, craft.getWorld()); + int fuelRange = (int) Math.round((fuel * (1 + cruiseSkipBlocks)) / fuelBurnRate); + // DONE: Create constants in base class for style colors! + Style style; + if (fuelRange > 1000) { + style = STYLE_COLOR_GREEN; + } else if (fuelRange > 100) { + style = STYLE_COLOR_YELLOW; + } else { + style = STYLE_COLOR_RED; + } + + return Component.text("Fuel range: " + fuelRange).style(style); + } + + @Override + protected @Nullable Component getDefaultString(int lineIndex, Component oldComponent) { + return EMPTY; + } + + @Override + protected void refreshSign(@Nullable Craft craft, AbstractSignListener.SignWrapper sign, boolean fillDefault, REFRESH_CAUSE refreshCause) { + // Calculate blocks and store them temporary, not pretty but works! + calcDisplayBlocks(craft); + calcdisplayComponents(craft); + super.refreshSign(craft, sign, fillDefault, refreshCause); + } + + protected void calcDisplayBlocks(Craft craft) { + displayBlocks.clear(); + displayComponents.clear(); + + totalNonNegligibleBlocks = 0; + totalNonNegligibleWaterBlocks = 0; + Counter materials = craft.getDataTag(Craft.MATERIALS); + if (materials.isEmpty()) { + return; + } + for (Material material : materials.getKeySet()) { + if (material.equals(Material.FIRE) || material.isAir()) + continue; + + int add = materials.get(material); + totalNonNegligibleBlocks += add; + if (!Tags.WATER.contains(material)) { + totalNonNegligibleWaterBlocks += add; + } + } + Object2IntMap displayBlocks = new Object2IntOpenHashMap<>(); + for (RequiredBlockEntry entry : craft.getType().getRequiredBlockProperty(CraftType.FLY_BLOCKS)) { + int total = 0; + for (Material material : entry.getMaterials()) { + if (materials.getKeySet().contains(material)) { + total += materials.get(material); + } + } + displayBlocks.putIfAbsent(entry, total); + } + for (RequiredBlockEntry entry : craft.getType().getRequiredBlockProperty(CraftType.MOVE_BLOCKS)) { + int total = 0; + for (Material material : entry.getMaterials()) { + if (materials.getKeySet().contains(material)) { + total += materials.get(material); + } + } + displayBlocks.putIfAbsent(entry, total); + } + } + + protected void calcdisplayComponents(Craft craft) { + displayComponents.set(0, EMPTY); + displayComponents.set(1, EMPTY); + int signLine = 0; + int signColumn = 0; + for (RequiredBlockEntry entry : displayBlocks.keySet()) { + if (entry.getMin() == 0.0) { + continue; + } + double percentPresent = (displayBlocks.get(entry) * 100D); + if (craft.getType().getBoolProperty(CraftType.BLOCKED_BY_WATER)) { + percentPresent /= totalNonNegligibleBlocks; + } else { + percentPresent /= totalNonNegligibleWaterBlocks; + } + Component signText = EMPTY; + Style style; + if (percentPresent > entry.getMin() * 1.04) { + style = STYLE_COLOR_GREEN; + } else if (percentPresent > entry.getMin() * 1.02) { + style = STYLE_COLOR_YELLOW; + } else { + style = STYLE_COLOR_RED; + } + if (entry.getName() == null) { + signText = Component.text(entry.materialsToString().toUpperCase().charAt(0)); + } else { + signText = Component.text(entry.getName().toUpperCase().charAt(0)); + } + signText = signText.append(Component.text(" " + (int)percentPresent + "/" + (int)entry.getMin() + " ")); + signText = signText.style(style); + if (signColumn == 0) { + displayComponents.set(signLine, signText); + signColumn++; + } else if (signLine < 2) { + Component existingLine = displayComponents.get(signLine); + existingLine = existingLine.append(signText); + displayComponents.set(signLine, existingLine); + signLine++; + signColumn = 0; + } + } + } + + @Override + protected void performUpdate(Component[] newComponents, AbstractSignListener.SignWrapper sign, REFRESH_CAUSE refreshCause) { + if (refreshCause != REFRESH_CAUSE.SIGN_MOVED_BY_CRAFT) { + sign.block().update(true); + } + } + + @Override + protected void sendUpdatePacket(Craft craft, AbstractSignListener.SignWrapper sign, REFRESH_CAUSE refreshCause) { + + } + + @Override + protected void onCraftIsBusy(Player player, Craft craft) { + + } } From b546e7a38f5c02abd98a368043b258b9dd24b00d Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Sun, 11 Aug 2024 15:35:02 +0200 Subject: [PATCH 045/122] fix speed sign --- .../movecraft/sign/SpeedSign.java | 21 +++++-------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/SpeedSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/SpeedSign.java index 9ab81a9fe..1fcb5d8d4 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/SpeedSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/SpeedSign.java @@ -1,27 +1,13 @@ package net.countercraft.movecraft.sign; -import net.countercraft.movecraft.MovecraftLocation; import net.countercraft.movecraft.craft.Craft; -import net.countercraft.movecraft.craft.CraftManager; import net.countercraft.movecraft.craft.type.CraftType; -import net.countercraft.movecraft.events.CraftDetectEvent; -import net.countercraft.movecraft.events.SignTranslateEvent; import net.countercraft.movecraft.localisation.I18nSupport; import net.kyori.adventure.text.Component; import net.md_5.bungee.api.ChatMessageType; import net.md_5.bungee.api.chat.TextComponent; -import org.bukkit.ChatColor; -import org.bukkit.Tag; -import org.bukkit.World; -import org.bukkit.block.Block; -import org.bukkit.block.BlockState; -import org.bukkit.block.Sign; import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; import org.bukkit.event.block.Action; -import org.bukkit.event.block.SignChangeEvent; -import org.bukkit.event.player.PlayerInteractEvent; import org.jetbrains.annotations.Nullable; public class SpeedSign extends AbstractInformationSign { @@ -82,17 +68,20 @@ protected boolean internalProcessSign(Action clickType, AbstractSignListener.Sig } @Override - protected void performUpdate(Component[] newComponents, AbstractSignListener.SignWrapper sign) { + protected void performUpdate(Component[] newComponents, AbstractSignListener.SignWrapper sign, REFRESH_CAUSE refreshCause) { for (int i = 0; i < newComponents.length; i++) { Component newComp = newComponents[i]; if (newComp != null) { sign.line(i, newComp); } } + if (refreshCause != REFRESH_CAUSE.SIGN_MOVED_BY_CRAFT) { + sign.block().update(true); + } } @Override - protected void sendUpdatePacket(Craft craft, AbstractSignListener.SignWrapper sign) { + protected void sendUpdatePacket(Craft craft, AbstractSignListener.SignWrapper sign, REFRESH_CAUSE refreshCause) { } From 1bcae237b309d7a481b921ebec3a374b0a813c83 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Wed, 14 Aug 2024 17:52:22 +0200 Subject: [PATCH 046/122] migrate craft pilot sign --- .../movecraft/sign/CraftPilotSign.java | 176 ++++++++++++++++++ .../sign/AbstractCraftPilotSign.java | 14 ++ .../movecraft/sign/AbstractMovecraftSign.java | 19 +- 3 files changed, 205 insertions(+), 4 deletions(-) create mode 100644 Movecraft/src/main/java/net/countercraft/movecraft/sign/CraftPilotSign.java create mode 100644 api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftPilotSign.java diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/CraftPilotSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/CraftPilotSign.java new file mode 100644 index 000000000..cf1a16c01 --- /dev/null +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/CraftPilotSign.java @@ -0,0 +1,176 @@ +package net.countercraft.movecraft.sign; + +import net.countercraft.movecraft.CruiseDirection; +import net.countercraft.movecraft.Movecraft; +import net.countercraft.movecraft.MovecraftLocation; +import net.countercraft.movecraft.config.Settings; +import net.countercraft.movecraft.craft.*; +import net.countercraft.movecraft.craft.type.CraftType; +import net.countercraft.movecraft.events.CraftPilotEvent; +import net.countercraft.movecraft.events.CraftReleaseEvent; +import net.countercraft.movecraft.localisation.I18nSupport; +import net.countercraft.movecraft.processing.functions.Result; +import net.countercraft.movecraft.util.Pair; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Player; +import org.bukkit.event.block.Action; +import org.bukkit.event.block.SignChangeEvent; +import org.bukkit.scheduler.BukkitRunnable; +import org.jetbrains.annotations.Nullable; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Optional; +import java.util.Set; + +public class CraftPilotSign extends AbstractCraftPilotSign { + + static final Set PILOTING = Collections.synchronizedSet(new HashSet<>()); + + public CraftPilotSign(CraftType craftType) { + super(craftType); + } + + @Override + public boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action type, boolean sneaking) { + return processingSuccessful || !sneaking; + } + + @Override + protected boolean isSignValid(Action clickType, AbstractSignListener.SignWrapper sign, Player player) { + String header = sign.getRaw(0).trim(); + CraftType craftType = CraftManager.getInstance().getCraftTypeFromString(header); + if (craftType != this.craftType) { + return false; + } + if (!player.hasPermission("movecraft." + header + ".pilot")) { + player.sendMessage(I18nSupport.getInternationalisedString("Insufficient Permissions")); + return false; + } else { + return true; + } + } + + @Override + protected boolean internalProcessSign(Action clickType, AbstractSignListener.SignWrapper sign, Player player, Optional craft) { + if (this.craftType.getBoolProperty(CraftType.MUST_BE_SUBCRAFT) && craft.isEmpty()) { + return false; + } + World world = sign.block().getWorld(); + if (craft.isPresent()) { + world = craft.get().getWorld(); + } + Location loc = sign.block().getLocation(); + MovecraftLocation startPoint = new MovecraftLocation(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); + + if (PILOTING.contains(startPoint)) { + // Always return true + return true; + } + + runDetectTask(startPoint, player, sign, craft, world); + + return true; + } + + protected void runDetectTask(MovecraftLocation startPoint, Player player, AbstractSignListener.SignWrapper signWrapper, Optional parentCraft, World world) { + PILOTING.add(startPoint); + CraftManager.getInstance().detect( + startPoint, + craftType, (type, w, p, parents) -> { + // Assert instructions are not available normally, also this is checked in beforehand sort of + assert p != null; // Note: This only passes in a non-null player. + if (type.getBoolProperty(CraftType.CRUISE_ON_PILOT)) { + if (parents.size() > 1) + return new Pair<>(Result.failWithMessage(I18nSupport.getInternationalisedString( + "Detection - Failed - Already commanding a craft")), null); + if (parents.size() == 1) { + Craft parent = parents.iterator().next(); + return new Pair<>(Result.succeed(), + new CruiseOnPilotSubCraft(type, world, p, parent)); + } + + return new Pair<>(Result.succeed(), + new CruiseOnPilotCraft(type, world, p)); + } + else { + if (parents.size() > 0) + return new Pair<>(Result.failWithMessage(I18nSupport.getInternationalisedString( + "Detection - Failed - Already commanding a craft")), null); + + return new Pair<>(Result.succeed(), + new PlayerCraftImpl(type, w, p)); + } + }, + world, player, player, + craft -> () -> { + Bukkit.getServer().getPluginManager().callEvent(new CraftPilotEvent(craft, CraftPilotEvent.Reason.PLAYER)); + if (craft instanceof SubCraft) { // Subtract craft from the parent + Craft parent = ((SubCraft) craft).getParent(); + var newHitbox = parent.getHitBox().difference(craft.getHitBox());; + parent.setHitBox(newHitbox); + parent.setOrigBlockCount(parent.getOrigBlockCount() - craft.getHitBox().size()); + } + + if (craft.getType().getBoolProperty(CraftType.CRUISE_ON_PILOT)) { + // Setup cruise direction + BlockFace facing = signWrapper.facing(); + craft.setCruiseDirection(CruiseDirection.fromBlockFace(facing)); + /*if (signWrapper.block().getBlockData() instanceof Directional) + craft.setCruiseDirection(CruiseDirection.fromBlockFace(((Directional) sign.getBlockData()).getFacing())); + else + craft.setCruiseDirection(CruiseDirection.NONE);*/ + + // Start craft cruising + craft.setLastCruiseUpdate(System.currentTimeMillis()); + craft.setCruising(true); + + // Stop craft cruising and sink it in 15 seconds + new BukkitRunnable() { + @Override + public void run() { + craft.setCruising(false); + CraftManager.getInstance().sink(craft); + } + }.runTaskLater(Movecraft.getInstance(), (craftType.getIntProperty(CraftType.CRUISE_ON_PILOT_LIFETIME))); + } + else { + // Release old craft if it exists + Craft oldCraft = CraftManager.getInstance().getCraftByPlayer(player); + if (oldCraft != null) + CraftManager.getInstance().release(oldCraft, CraftReleaseEvent.Reason.PLAYER, false); + } + } + ); + new BukkitRunnable() { + @Override + public void run() { + PILOTING.remove(startPoint); + } + }.runTaskLater(Movecraft.getInstance(), 4); + + } + + @Override + public boolean processSignChange(SignChangeEvent event, AbstractSignListener.SignWrapper sign) { + String header = sign.getRaw(0).trim(); + CraftType craftType = CraftManager.getInstance().getCraftTypeFromString(header); + if (craftType != this.craftType) { + return false; + } + if (Settings.RequireCreatePerm) { + Player player = event.getPlayer(); + if (!player.hasPermission("movecraft." + header + ".create")) { + player.sendMessage(I18nSupport.getInternationalisedString("Insufficient Permissions")); + return false; + } else { + return true; + } + } else { + return true; + } + } +} diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftPilotSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftPilotSign.java new file mode 100644 index 000000000..0ffe0a115 --- /dev/null +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftPilotSign.java @@ -0,0 +1,14 @@ +package net.countercraft.movecraft.sign; + +import net.countercraft.movecraft.craft.type.CraftType; + +public abstract class AbstractCraftPilotSign extends AbstractMovecraftSign { + + protected final CraftType craftType; + + public AbstractCraftPilotSign(final CraftType craftType) { + super(); + this.craftType = craftType; + } + +} diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java index 7d2a83f16..2cff041e6 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java @@ -1,6 +1,8 @@ package net.countercraft.movecraft.sign; import net.countercraft.movecraft.craft.Craft; +import net.countercraft.movecraft.craft.type.CraftType; +import net.countercraft.movecraft.events.CraftPilotEvent; import net.countercraft.movecraft.util.MathUtils; import org.bukkit.entity.Player; import org.bukkit.event.block.Action; @@ -8,10 +10,8 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; +import java.util.*; +import java.util.function.Function; // TODO: In 1.21 signs can have multiple sides! This requires us to pass the clicked side through or well the relevant lines and the set method for the clicked side public abstract class AbstractMovecraftSign { @@ -22,6 +22,17 @@ public static boolean hasBeenRegistered(final String ident) { return SIGNS.containsKey(ident); } + public static void registerCraftPilotSigns(Set loadedTypes, Function signFactory) { + SIGNS.entrySet().removeIf(entry -> { + return entry.getValue() instanceof AbstractCraftPilotSign; + }); + // Now, add all types... + for (CraftType type : loadedTypes) { + AbstractCraftPilotSign sign = signFactory.apply(type); + register(type.getStringProperty(CraftType.NAME), sign, true); + } + } + public static Optional tryGet(final String ident) { String identToUse = ident.toUpperCase(); if (identToUse.contains(":")) { From e89dbf59c2fce52a9b593ab7fc0ede6333722589 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Wed, 14 Aug 2024 17:52:31 +0200 Subject: [PATCH 047/122] register calls --- .../src/main/java/net/countercraft/movecraft/Movecraft.java | 3 ++- .../net/countercraft/movecraft/commands/MovecraftCommand.java | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java b/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java index 26297766d..75ea9b125 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java @@ -214,7 +214,6 @@ public void onEnable() { getServer().getPluginManager().registerEvents(new ChunkManager(), this); //getServer().getPluginManager().registerEvents(new AscendSign(), this); AbstractMovecraftSign.register("Ascend:", new AscendSign(), true); - getServer().getPluginManager().registerEvents(new CraftSign(), this); //getServer().getPluginManager().registerEvents(new CruiseSign(), this); AbstractMovecraftSign.register("Cruise:", new CruiseSign(), true); //getServer().getPluginManager().registerEvents(new DescendSign(), this); @@ -246,6 +245,8 @@ public void onEnable() { // Moved to compat section! //getServer().getPluginManager().registerEvents(new SignListener(), this); + AbstractMovecraftSign.registerCraftPilotSigns(CraftManager.getInstance().getCraftTypes(), CraftPilotSign::new); + var contactsManager = new ContactsManager(); contactsManager.runTaskTimerAsynchronously(this, 0, 20); getServer().getPluginManager().registerEvents(contactsManager, this); diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/commands/MovecraftCommand.java b/Movecraft/src/main/java/net/countercraft/movecraft/commands/MovecraftCommand.java index 6bb739cbd..6ac1ef2bf 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/commands/MovecraftCommand.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/commands/MovecraftCommand.java @@ -3,6 +3,8 @@ import net.countercraft.movecraft.Movecraft; import net.countercraft.movecraft.craft.CraftManager; import net.countercraft.movecraft.localisation.I18nSupport; +import net.countercraft.movecraft.sign.AbstractMovecraftSign; +import net.countercraft.movecraft.sign.CraftPilotSign; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.command.TabExecutor; @@ -33,6 +35,7 @@ public boolean onCommand(CommandSender commandSender, Command command, String s, if(args.length==1 && args[0].equalsIgnoreCase("reloadtypes") && commandSender.hasPermission("movecraft.commands.movecraft.reloadtypes")){ CraftManager.getInstance().reloadCraftTypes(); + AbstractMovecraftSign.registerCraftPilotSigns(CraftManager.getInstance().getCraftTypes(), CraftPilotSign::new); commandSender.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("Movecraft - Reloaded Types")); return true; } From 01cf53c2123fe0bc8bd7c910df127df98848ac6d Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Wed, 14 Aug 2024 17:52:39 +0200 Subject: [PATCH 048/122] remove old sign --- .../movecraft/sign/CraftSign.java | 158 ------------------ 1 file changed, 158 deletions(-) delete mode 100644 Movecraft/src/main/java/net/countercraft/movecraft/sign/CraftSign.java diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/CraftSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/CraftSign.java deleted file mode 100644 index ec5a977c5..000000000 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/CraftSign.java +++ /dev/null @@ -1,158 +0,0 @@ -package net.countercraft.movecraft.sign; - -import net.countercraft.movecraft.CruiseDirection; -import net.countercraft.movecraft.Movecraft; -import net.countercraft.movecraft.MovecraftLocation; -import net.countercraft.movecraft.config.Settings; -import net.countercraft.movecraft.craft.Craft; -import net.countercraft.movecraft.craft.CraftManager; -import net.countercraft.movecraft.craft.CruiseOnPilotCraft; -import net.countercraft.movecraft.craft.CruiseOnPilotSubCraft; -import net.countercraft.movecraft.craft.PlayerCraftImpl; -import net.countercraft.movecraft.craft.SubCraft; -import net.countercraft.movecraft.craft.type.CraftType; -import net.countercraft.movecraft.events.CraftPilotEvent; -import net.countercraft.movecraft.events.CraftReleaseEvent; -import net.countercraft.movecraft.localisation.I18nSupport; -import net.countercraft.movecraft.processing.functions.Result; -import net.countercraft.movecraft.util.Pair; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.Location; -import org.bukkit.World; -import org.bukkit.block.BlockState; -import org.bukkit.block.Sign; -import org.bukkit.block.data.Directional; -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.block.SignChangeEvent; -import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.scheduler.BukkitRunnable; -import org.jetbrains.annotations.NotNull; - -import java.util.HashSet; -import java.util.Set; - -public final class CraftSign implements Listener { - private final Set piloting = new HashSet<>(); - - @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) - public void onSignChange(@NotNull SignChangeEvent event) { - if (CraftManager.getInstance().getCraftTypeFromString(event.getLine(0)) == null) - return; - - if (!Settings.RequireCreatePerm) - return; - - if (!event.getPlayer().hasPermission("movecraft." + ChatColor.stripColor(event.getLine(0)) + ".create")) { - event.getPlayer().sendMessage(I18nSupport.getInternationalisedString("Insufficient Permissions")); - event.setCancelled(true); - } - } - - @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) - public void onSignClick(@NotNull PlayerInteractEvent event) { - if (event.getAction() != Action.RIGHT_CLICK_BLOCK || event.getClickedBlock() == null) - return; - - BlockState state = event.getClickedBlock().getState(); - if (!(state instanceof Sign)) - return; - - Sign sign = (Sign) state; - CraftType craftType = CraftManager.getInstance().getCraftTypeFromString(ChatColor.stripColor(sign.getLine(0))); - if (craftType == null) - return; - - // Valid sign prompt for ship command. - event.setCancelled(true); - Player player = event.getPlayer(); - if (!player.hasPermission("movecraft." + ChatColor.stripColor(sign.getLine(0)) + ".pilot")) { - player.sendMessage(I18nSupport.getInternationalisedString("Insufficient Permissions")); - return; - } - - Location loc = event.getClickedBlock().getLocation(); - MovecraftLocation startPoint = new MovecraftLocation(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); - if (piloting.contains(startPoint)) { - return; - } - - // Attempt to run detection - World world = event.getClickedBlock().getWorld(); - - CraftManager.getInstance().detect( - startPoint, - craftType, (type, w, p, parents) -> { - assert p != null; // Note: This only passes in a non-null player. - if (type.getBoolProperty(CraftType.CRUISE_ON_PILOT)) { - if (parents.size() > 1) - return new Pair<>(Result.failWithMessage(I18nSupport.getInternationalisedString( - "Detection - Failed - Already commanding a craft")), null); - if (parents.size() == 1) { - Craft parent = parents.iterator().next(); - return new Pair<>(Result.succeed(), - new CruiseOnPilotSubCraft(type, world, p, parent)); - } - - return new Pair<>(Result.succeed(), - new CruiseOnPilotCraft(type, world, p)); - } - else { - if (parents.size() > 0) - return new Pair<>(Result.failWithMessage(I18nSupport.getInternationalisedString( - "Detection - Failed - Already commanding a craft")), null); - - return new Pair<>(Result.succeed(), - new PlayerCraftImpl(type, w, p)); - } - }, - world, player, player, - craft -> () -> { - Bukkit.getServer().getPluginManager().callEvent(new CraftPilotEvent(craft, CraftPilotEvent.Reason.PLAYER)); - if (craft instanceof SubCraft) { // Subtract craft from the parent - Craft parent = ((SubCraft) craft).getParent(); - var newHitbox = parent.getHitBox().difference(craft.getHitBox());; - parent.setHitBox(newHitbox); - parent.setOrigBlockCount(parent.getOrigBlockCount() - craft.getHitBox().size()); - } - - if (craft.getType().getBoolProperty(CraftType.CRUISE_ON_PILOT)) { - // Setup cruise direction - if (sign.getBlockData() instanceof Directional) - craft.setCruiseDirection(CruiseDirection.fromBlockFace(((Directional) sign.getBlockData()).getFacing())); - else - craft.setCruiseDirection(CruiseDirection.NONE); - - // Start craft cruising - craft.setLastCruiseUpdate(System.currentTimeMillis()); - craft.setCruising(true); - - // Stop craft cruising and sink it in 15 seconds - new BukkitRunnable() { - @Override - public void run() { - craft.setCruising(false); - CraftManager.getInstance().sink(craft); - } - }.runTaskLater(Movecraft.getInstance(), (craftType.getIntProperty(CraftType.CRUISE_ON_PILOT_LIFETIME))); - } - else { - // Release old craft if it exists - Craft oldCraft = CraftManager.getInstance().getCraftByPlayer(player); - if (oldCraft != null) - CraftManager.getInstance().release(oldCraft, CraftReleaseEvent.Reason.PLAYER, false); - } - } - ); - new BukkitRunnable() { - @Override - public void run() { - piloting.remove(startPoint); - } - }.runTaskLater(Movecraft.getInstance(), 4); - } -} From 540d89fc798350d586dd3867545083d3e8d96b34 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Wed, 14 Aug 2024 18:00:33 +0200 Subject: [PATCH 049/122] add helper methods --- .../movecraft/sign/AbstractSignListener.java | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java index 44ba02b2d..b79fd15d8 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java @@ -57,6 +57,49 @@ public String[] rawLines() { return result; } + public boolean areSignsEqual(SignWrapper other) { + if (other == null) { + return false; + } + + String[] myLines = this.rawLines(); + String[] theirLines = other.rawLines(); + + if (myLines.length != theirLines.length) { + return false; + } + + for (int i = 0; i < myLines.length; i++) { + String mine = myLines[i].trim(); + String theirs = theirLines[i].trim(); + + if (!mine.equalsIgnoreCase(theirs)) { + return false; + } + } + + return true; + } + + public static boolean areSignsEqual(SignWrapper[] a, SignWrapper[] b) { + if (a == null || b == null) { + return false; + } + if (a.length != b.length) { + return false; + } + + for (int i = 0; i < a.length; i++) { + SignWrapper aWrap = a[i]; + SignWrapper bWrap = b[i]; + + if (!aWrap.areSignsEqual(bWrap)) { + return false; + } + } + return true; + } + } public abstract SignWrapper[] getSignWrappers(Sign sign); From 47638bd319a8911271c3e5786197868cfe5eceaa Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Thu, 15 Aug 2024 17:32:03 +0200 Subject: [PATCH 050/122] add todo notes --- .../java/net/countercraft/movecraft/sign/CraftPilotSign.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/CraftPilotSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/CraftPilotSign.java index cf1a16c01..3657680c2 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/CraftPilotSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/CraftPilotSign.java @@ -26,6 +26,7 @@ import java.util.Optional; import java.util.Set; +//TODO: This is not very pretty... public class CraftPilotSign extends AbstractCraftPilotSign { static final Set PILOTING = Collections.synchronizedSet(new HashSet<>()); @@ -145,6 +146,8 @@ public void run() { } } ); + // TODO: Move this to be directly called by the craftmanager post detection... + // Or use the event handler or something new BukkitRunnable() { @Override public void run() { From bea521b5d09286cc2f9acc6e9582d1b5143e4046 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Mon, 19 Aug 2024 16:07:03 +0200 Subject: [PATCH 051/122] move status sign back to where it was --- .../src/main/java/net/countercraft/movecraft/Movecraft.java | 1 + .../movecraft/{sign => features/status}/StatusSign.java | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) rename Movecraft/src/main/java/net/countercraft/movecraft/{sign => features/status}/StatusSign.java (97%) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java b/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java index 75ea9b125..2ac82f217 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java @@ -27,6 +27,7 @@ import net.countercraft.movecraft.features.contacts.ContactsManager; import net.countercraft.movecraft.features.contacts.ContactsSign; import net.countercraft.movecraft.features.status.StatusManager; +import net.countercraft.movecraft.features.status.StatusSign; import net.countercraft.movecraft.listener.*; import net.countercraft.movecraft.localisation.I18nSupport; import net.countercraft.movecraft.mapUpdater.MapUpdateManager; diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/StatusSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java similarity index 97% rename from Movecraft/src/main/java/net/countercraft/movecraft/sign/StatusSign.java rename to Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java index d750f50a5..fe9c388a1 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/StatusSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java @@ -1,4 +1,4 @@ -package net.countercraft.movecraft.sign; +package net.countercraft.movecraft.features.status; import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; @@ -6,6 +6,8 @@ import net.countercraft.movecraft.craft.Craft; import net.countercraft.movecraft.craft.type.CraftType; import net.countercraft.movecraft.craft.type.RequiredBlockEntry; +import net.countercraft.movecraft.sign.AbstractInformationSign; +import net.countercraft.movecraft.sign.AbstractSignListener; import net.countercraft.movecraft.util.Counter; import net.countercraft.movecraft.util.Tags; import net.kyori.adventure.text.Component; From e9b7c62de1cb20b97a544cbad5f0e06437e39712 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Mon, 19 Aug 2024 16:11:22 +0200 Subject: [PATCH 052/122] subscribe to event to re-register the craft sigsn --- .../net/countercraft/movecraft/Movecraft.java | 1 + .../movecraft/commands/MovecraftCommand.java | 1 - .../movecraft/listener/CraftTypeListener.java | 17 +++++++++++++++++ .../movecraft/sign/AbstractMovecraftSign.java | 4 +--- 4 files changed, 19 insertions(+), 4 deletions(-) create mode 100644 Movecraft/src/main/java/net/countercraft/movecraft/listener/CraftTypeListener.java diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java b/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java index 2ac82f217..6f333a889 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java @@ -252,6 +252,7 @@ public void onEnable() { contactsManager.runTaskTimerAsynchronously(this, 0, 20); getServer().getPluginManager().registerEvents(contactsManager, this); getServer().getPluginManager().registerEvents(new ContactsSign(), this); + getServer().getPluginManager().registerEvents(new CraftTypeListener(), this); getCommand("contacts").setExecutor(new ContactsCommand()); var statusManager = new StatusManager(); diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/commands/MovecraftCommand.java b/Movecraft/src/main/java/net/countercraft/movecraft/commands/MovecraftCommand.java index 6ac1ef2bf..1ceea602f 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/commands/MovecraftCommand.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/commands/MovecraftCommand.java @@ -35,7 +35,6 @@ public boolean onCommand(CommandSender commandSender, Command command, String s, if(args.length==1 && args[0].equalsIgnoreCase("reloadtypes") && commandSender.hasPermission("movecraft.commands.movecraft.reloadtypes")){ CraftManager.getInstance().reloadCraftTypes(); - AbstractMovecraftSign.registerCraftPilotSigns(CraftManager.getInstance().getCraftTypes(), CraftPilotSign::new); commandSender.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("Movecraft - Reloaded Types")); return true; } diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/listener/CraftTypeListener.java b/Movecraft/src/main/java/net/countercraft/movecraft/listener/CraftTypeListener.java new file mode 100644 index 000000000..6b3748b89 --- /dev/null +++ b/Movecraft/src/main/java/net/countercraft/movecraft/listener/CraftTypeListener.java @@ -0,0 +1,17 @@ +package net.countercraft.movecraft.listener; + +import net.countercraft.movecraft.craft.CraftManager; +import net.countercraft.movecraft.events.TypesReloadedEvent; +import net.countercraft.movecraft.sign.AbstractMovecraftSign; +import net.countercraft.movecraft.sign.CraftPilotSign; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +public class CraftTypeListener implements Listener { + + @EventHandler + public void onReload(TypesReloadedEvent event) { + AbstractMovecraftSign.registerCraftPilotSigns(CraftManager.getInstance().getCraftTypes(), CraftPilotSign::new); + } + +} diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java index 2cff041e6..4a8def8d8 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java @@ -23,9 +23,7 @@ public static boolean hasBeenRegistered(final String ident) { } public static void registerCraftPilotSigns(Set loadedTypes, Function signFactory) { - SIGNS.entrySet().removeIf(entry -> { - return entry.getValue() instanceof AbstractCraftPilotSign; - }); + SIGNS.entrySet().removeIf(entry -> entry.getValue() instanceof AbstractCraftPilotSign); // Now, add all types... for (CraftType type : loadedTypes) { AbstractCraftPilotSign sign = signFactory.apply(type); From 5efcc73ae89b68b674f9a9467c724e4f06a09a12 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Mon, 19 Aug 2024 16:14:31 +0200 Subject: [PATCH 053/122] remove unnecessary if --- .../countercraft/movecraft/sign/AbstractMovecraftSign.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java index 4a8def8d8..fdae6070c 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java @@ -35,9 +35,8 @@ public static Optional tryGet(final String ident) { String identToUse = ident.toUpperCase(); if (identToUse.contains(":")) { identToUse = identToUse.split(":")[0]; - if (ident.contains(":")) { - identToUse = identToUse + ":"; - } + // Re-add the : cause things should be registered with : at the end + identToUse = identToUse + ":"; } return Optional.ofNullable(SIGNS.getOrDefault(identToUse, null)); } From 4537421c0e36a20e47b1f96da41a0802e8cf5214 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Mon, 19 Aug 2024 16:17:17 +0200 Subject: [PATCH 054/122] Optional => Nullable string --- .../net/countercraft/movecraft/sign/ScuttleSign.java | 4 ++-- .../movecraft/sign/AbstractMovecraftSign.java | 11 +++++++---- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/ScuttleSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/ScuttleSign.java index d58dfa171..36a260302 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/ScuttleSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/ScuttleSign.java @@ -69,8 +69,8 @@ protected boolean canPlayerUseSignOn(Player player, Craft craft) { } } // Check for "can scuttle others" permission - if (this.optPermission.isPresent()) { - if (!player.hasPermission(this.optPermission.get())) { + if (this.permissionString != null || !this.permissionString.isBlank()) { + if (!player.hasPermission(this.permissionString)) { player.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("You must be piloting a craft")); } diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java index fdae6070c..4bd3d28b1 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java @@ -2,7 +2,6 @@ import net.countercraft.movecraft.craft.Craft; import net.countercraft.movecraft.craft.type.CraftType; -import net.countercraft.movecraft.events.CraftPilotEvent; import net.countercraft.movecraft.util.MathUtils; import org.bukkit.entity.Player; import org.bukkit.event.block.Action; @@ -53,14 +52,15 @@ public static void register(final String ident, final @Nonnull AbstractMovecraft } } - protected final Optional optPermission; + @Nullable + protected final String permissionString; public AbstractMovecraftSign() { this(null); } public AbstractMovecraftSign(String permissionNode) { - this.optPermission = Optional.ofNullable(permissionNode); + this.permissionString = permissionNode; } public static String findIdent(AbstractMovecraftSign instance) { @@ -88,7 +88,10 @@ public boolean processSignClick(Action clickType, AbstractSignListener.SignWrapp } protected boolean canPlayerUseSign(Action clickType, AbstractSignListener.SignWrapper sign, Player player) { - return this.optPermission.map(player::hasPermission).orElse(true); + if (this.permissionString == null || this.permissionString.isBlank()) { + return true; + } + return player.hasPermission(this.permissionString); } protected Optional getCraft(AbstractSignListener.SignWrapper sign) { From 69d701dd85772f0b1744c03697bda5a7c86b2954 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Mon, 19 Aug 2024 16:20:26 +0200 Subject: [PATCH 055/122] typo fix --- .../net/countercraft/movecraft/sign/AbstractMovecraftSign.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java index 4bd3d28b1..17fbcdbd1 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java @@ -65,7 +65,7 @@ public AbstractMovecraftSign(String permissionNode) { public static String findIdent(AbstractMovecraftSign instance) { if (!SIGNS.containsValue(instance)) { - throw new IllegalArgumentException("MovecraftSign instanceo must be registered!"); + throw new IllegalArgumentException("MovecraftSign instance must be registered!"); } for (Map.Entry entry : SIGNS.entrySet()) { if (entry.getValue() == instance) { From b307c87dc17f1997c8deea028792aa558b0a13b4 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Mon, 19 Aug 2024 16:23:06 +0200 Subject: [PATCH 056/122] add overloaded register method --- .../net/countercraft/movecraft/Movecraft.java | 28 +++++++++---------- .../movecraft/sign/AbstractMovecraftSign.java | 6 ++-- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java b/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java index 6f333a889..8c8f361e2 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java @@ -214,33 +214,33 @@ public void onEnable() { getServer().getPluginManager().registerEvents(new PlayerListener(), this); getServer().getPluginManager().registerEvents(new ChunkManager(), this); //getServer().getPluginManager().registerEvents(new AscendSign(), this); - AbstractMovecraftSign.register("Ascend:", new AscendSign(), true); + AbstractMovecraftSign.register("Ascend:", new AscendSign()); //getServer().getPluginManager().registerEvents(new CruiseSign(), this); - AbstractMovecraftSign.register("Cruise:", new CruiseSign(), true); + AbstractMovecraftSign.register("Cruise:", new CruiseSign()); //getServer().getPluginManager().registerEvents(new DescendSign(), this); - AbstractMovecraftSign.register("Descend:", new DescendSign(), true); + AbstractMovecraftSign.register("Descend:", new DescendSign()); //getServer().getPluginManager().registerEvents(new HelmSign(), this); - AbstractMovecraftSign.register("[Helm]", new HelmSign(), true); - AbstractMovecraftSign.register(HelmSign.PRETTY_HEADER, new HelmSign(), true); + AbstractMovecraftSign.register("[Helm]", new HelmSign()); + AbstractMovecraftSign.register(HelmSign.PRETTY_HEADER, new HelmSign()); //getServer().getPluginManager().registerEvents(new MoveSign(), this); - AbstractMovecraftSign.register("Move:", new MoveSign(), true); + AbstractMovecraftSign.register("Move:", new MoveSign()); //getServer().getPluginManager().registerEvents(new NameSign(), this); - AbstractMovecraftSign.register("Name:", new NameSign(), true); + AbstractMovecraftSign.register("Name:", new NameSign()); //getServer().getPluginManager().registerEvents(new PilotSign(), this); - AbstractMovecraftSign.register("Pilot:", new PilotSign(), true); + AbstractMovecraftSign.register("Pilot:", new PilotSign()); //getServer().getPluginManager().registerEvents(new RelativeMoveSign(), this); - AbstractMovecraftSign.register("RMove:", new RelativeMoveSign(), true); + AbstractMovecraftSign.register("RMove:", new RelativeMoveSign()); //getServer().getPluginManager().registerEvents(new ReleaseSign(), this); - AbstractMovecraftSign.register("Release", new ReleaseSign(), true); + AbstractMovecraftSign.register("Release", new ReleaseSign()); getServer().getPluginManager().registerEvents(new RemoteSign(), this); //getServer().getPluginManager().registerEvents(new SpeedSign(), this); - AbstractMovecraftSign.register("Speed:", new SpeedSign(), true); - AbstractMovecraftSign.register("Status:", new StatusSign(), true); + AbstractMovecraftSign.register("Speed:", new SpeedSign()); + AbstractMovecraftSign.register("Status:", new StatusSign()); getServer().getPluginManager().registerEvents(new SubcraftRotateSign(), this); //getServer().getPluginManager().registerEvents(new TeleportSign(), this); - AbstractMovecraftSign.register("Teleport:", new TeleportSign(), true); + AbstractMovecraftSign.register("Teleport:", new TeleportSign()); //getServer().getPluginManager().registerEvents(new ScuttleSign(), this); - AbstractMovecraftSign.register("Scuttle", new ScuttleSign(), true); + AbstractMovecraftSign.register("Scuttle", new ScuttleSign()); getServer().getPluginManager().registerEvents(new CraftPilotListener(), this); getServer().getPluginManager().registerEvents(new CraftReleaseListener(), this); // Moved to compat section! diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java index 17fbcdbd1..9e2db8e92 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java @@ -40,12 +40,12 @@ public static Optional tryGet(final String ident) { return Optional.ofNullable(SIGNS.getOrDefault(identToUse, null)); } - public static void forceRegister(final String ident, final @Nonnull AbstractMovecraftSign instance) { + public static void register(final String ident, final @Nonnull AbstractMovecraftSign instance) { register(ident, instance, true); } - public static void register(final String ident, final @Nonnull AbstractMovecraftSign instance, boolean allowOverride) { - if (allowOverride) { + public static void register(final String ident, final @Nonnull AbstractMovecraftSign instance, boolean overrideIfAlreadyRegistered) { + if (overrideIfAlreadyRegistered) { SIGNS.put(ident.toUpperCase(), instance); } else { SIGNS.putIfAbsent(ident.toUpperCase(), instance); From 8219dc35ec6df3da883a94a4d43296c2fb38d956 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Mon, 19 Aug 2024 16:30:45 +0200 Subject: [PATCH 057/122] Optional => Nullable Craft --- .../movecraft/sign/CraftPilotSign.java | 2 +- .../countercraft/movecraft/sign/HelmSign.java | 2 +- .../countercraft/movecraft/sign/MoveSign.java | 2 +- .../countercraft/movecraft/sign/NameSign.java | 7 +++---- .../movecraft/sign/PilotSign.java | 13 +------------ .../movecraft/sign/ReleaseSign.java | 2 +- .../movecraft/sign/ScuttleSign.java | 2 +- .../movecraft/sign/AbstractCraftSign.java | 19 ++++++++++--------- .../movecraft/sign/AbstractMovecraftSign.java | 7 ++++--- 9 files changed, 23 insertions(+), 33 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/CraftPilotSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/CraftPilotSign.java index 3657680c2..7b8aa680b 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/CraftPilotSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/CraftPilotSign.java @@ -56,7 +56,7 @@ protected boolean isSignValid(Action clickType, AbstractSignListener.SignWrapper } @Override - protected boolean internalProcessSign(Action clickType, AbstractSignListener.SignWrapper sign, Player player, Optional craft) { + protected boolean internalProcessSign(Action clickType, AbstractSignListener.SignWrapper sign, Player player, @javax.annotation.Nullable Craft craft) { if (this.craftType.getBoolProperty(CraftType.MUST_BE_SUBCRAFT) && craft.isEmpty()) { return false; } diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/HelmSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/HelmSign.java index f66135159..1c5afc392 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/HelmSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/HelmSign.java @@ -77,7 +77,7 @@ public boolean processSignChange(SignChangeEvent event, AbstractSignListener.Sig } @Override - protected boolean internalProcessSign(Action clickType, AbstractSignListener.SignWrapper sign, Player player, Craft craft) { + protected boolean internalProcessSignWithCraft(Action clickType, AbstractSignListener.SignWrapper sign, Craft craft, Player player) { MovecraftRotation rotation; if (clickType == Action.RIGHT_CLICK_BLOCK) { rotation = MovecraftRotation.CLOCKWISE; diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/MoveSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/MoveSign.java index a363d8494..9a65437b2 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/MoveSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/MoveSign.java @@ -67,7 +67,7 @@ protected boolean canPlayerUseSignOn(Player player, Craft craft) { } @Override - protected boolean internalProcessSign(Action clickType, AbstractSignListener.SignWrapper sign, Player player, Craft craft) { + protected boolean internalProcessSignWithCraft(Action clickType, AbstractSignListener.SignWrapper sign, Craft craft, Player player) { if (!craft.getType().getBoolProperty(CraftType.CAN_STATIC_MOVE)) { return false; } diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/NameSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/NameSign.java index 5b75294db..159fdf45d 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/NameSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/NameSign.java @@ -8,10 +8,9 @@ import org.bukkit.entity.Player; import org.bukkit.event.block.Action; import org.bukkit.event.block.SignChangeEvent; -import org.jetbrains.annotations.Nullable; +import javax.annotation.Nullable; import java.util.Arrays; -import java.util.Optional; import java.util.stream.Collectors; public class NameSign extends AbstractCraftSign { @@ -41,12 +40,12 @@ protected boolean isSignValid(Action clickType, AbstractSignListener.SignWrapper } @Override - protected boolean internalProcessSign(Action clickType, AbstractSignListener.SignWrapper sign, Player player, Craft craft) { + protected boolean internalProcessSignWithCraft(Action clickType, AbstractSignListener.SignWrapper sign, Craft craft, Player player) { return true; } @Override - protected boolean internalProcessSign(Action clickType, AbstractSignListener.SignWrapper sign, Player player, Optional craft) { + protected boolean internalProcessSign(Action clickType, AbstractSignListener.SignWrapper sign, Player player, @Nullable Craft craft) { return true; } diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/PilotSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/PilotSign.java index 9a3a9970b..5853fce65 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/PilotSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/PilotSign.java @@ -1,22 +1,11 @@ package net.countercraft.movecraft.sign; import net.countercraft.movecraft.craft.Craft; -import net.kyori.adventure.text.Component; -import org.bukkit.ChatColor; -import org.bukkit.block.Block; -import org.bukkit.block.Sign; import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; import org.bukkit.event.block.Action; import org.bukkit.event.block.SignChangeEvent; -import org.bukkit.event.player.PlayerInteractEvent; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Optional; - // TODO: Replace PilotSignValidator with this? public class PilotSign extends AbstractMovecraftSign { @@ -36,7 +25,7 @@ protected boolean isSignValid(Action clickType, AbstractSignListener.SignWrapper } @Override - protected boolean internalProcessSign(Action clickType, AbstractSignListener.SignWrapper sign, Player player, Optional craft) { + protected boolean internalProcessSign(Action clickType, AbstractSignListener.SignWrapper sign, Player player, @javax.annotation.Nullable Craft craft) { // Nothing to do here return true; } diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/ReleaseSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/ReleaseSign.java index 82ddaa9f1..e18a0f59b 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/ReleaseSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/ReleaseSign.java @@ -43,7 +43,7 @@ public boolean processSignChange(SignChangeEvent event, AbstractSignListener.Sig } @Override - protected boolean internalProcessSign(Action clickType, AbstractSignListener.SignWrapper sign, Player player, Craft craft) { + protected boolean internalProcessSignWithCraft(Action clickType, AbstractSignListener.SignWrapper sign, Craft craft, Player player) { CraftManager.getInstance().release(craft, CraftReleaseEvent.Reason.PLAYER, false); return true; } diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/ScuttleSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/ScuttleSign.java index 36a260302..07efe8f10 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/ScuttleSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/ScuttleSign.java @@ -79,7 +79,7 @@ protected boolean canPlayerUseSignOn(Player player, Craft craft) { } @Override - protected boolean internalProcessSign(Action clickType, AbstractSignListener.SignWrapper sign, Player player, Craft craft) { + protected boolean internalProcessSignWithCraft(Action clickType, AbstractSignListener.SignWrapper sign, Craft craft, Player player) { CraftScuttleEvent e = new CraftScuttleEvent(craft, player); Bukkit.getServer().getPluginManager().callEvent(e); if(e.isCancelled()) diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftSign.java index ca2c2cfbb..5baa43582 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftSign.java @@ -41,15 +41,15 @@ public boolean processSignClick(Action clickType, AbstractSignListener.SignWrapp if (!this.canPlayerUseSign(clickType, sign, player)) { return false; } - Optional craft = this.getCraft(sign); - if (craft.isEmpty()) { + Craft craft = this.getCraft(sign); + if (craft == null) { this.onCraftNotFound(player, sign); return false; } - if (craft.get() instanceof PlayerCraft pc) { + if (craft instanceof PlayerCraft pc) { if (!pc.isNotProcessing() && !this.ignoreCraftIsBusy) { - this.onCraftIsBusy(player, craft.get()); + this.onCraftIsBusy(player, craft); return false; } } @@ -58,12 +58,12 @@ public boolean processSignClick(Action clickType, AbstractSignListener.SignWrapp } @Override - protected boolean internalProcessSign(Action clickType, AbstractSignListener.SignWrapper sign, Player player, Optional craft) { - if (craft.isEmpty()) { + protected boolean internalProcessSign(Action clickType, AbstractSignListener.SignWrapper sign, Player player, @Nullable Craft craft) { + if (craft == null) { throw new IllegalStateException("Somehow craft is not set here. It should always be present here!"); } - if (this.canPlayerUseSignOn(player, craft.get())) { - return this.internalProcessSign(clickType, sign, player, craft.get()); + if (this.canPlayerUseSignOn(player, craft)) { + return this.internalProcessSignWithCraft(clickType, sign, craft, player); } return false; } @@ -89,6 +89,7 @@ public void onSignMovedByCraft(SignTranslateEvent event) { protected abstract boolean isSignValid(Action clickType, AbstractSignListener.SignWrapper sign, Player player); - protected abstract boolean internalProcessSign(Action clickType, AbstractSignListener.SignWrapper sign, Player player, Craft craft); + // Gets called by internalProcessSign if a craft is found + protected abstract boolean internalProcessSignWithCraft(Action clickType, AbstractSignListener.SignWrapper sign, Craft craft, Player player); } diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java index 9e2db8e92..a15e1add8 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java @@ -94,12 +94,13 @@ protected boolean canPlayerUseSign(Action clickType, AbstractSignListener.SignWr return player.hasPermission(this.permissionString); } - protected Optional getCraft(AbstractSignListener.SignWrapper sign) { - return Optional.ofNullable(MathUtils.getCraftByPersistentBlockData(sign.block().getLocation())); + @Nullable + protected Craft getCraft(AbstractSignListener.SignWrapper sign) { + return MathUtils.getCraftByPersistentBlockData(sign.block().getLocation()); } public abstract boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action type, boolean sneaking); protected abstract boolean isSignValid(Action clickType, AbstractSignListener.SignWrapper sign, Player player); - protected abstract boolean internalProcessSign(Action clickType, AbstractSignListener.SignWrapper sign, Player player, Optional craft); + protected abstract boolean internalProcessSign(Action clickType, AbstractSignListener.SignWrapper sign, Player player, @Nullable Craft craft); public abstract boolean processSignChange(SignChangeEvent event, AbstractSignListener.SignWrapper sign); } From 0b3d5d1937810479307797187f812d806e28eac3 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Mon, 19 Aug 2024 16:31:21 +0200 Subject: [PATCH 058/122] remove static modifier --- .../net/countercraft/movecraft/sign/AbstractSignListener.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java index b79fd15d8..5c6398453 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java @@ -27,7 +27,7 @@ public AbstractSignListener() { INSTANCE = this; } - public static record SignWrapper( + public record SignWrapper( Sign block, Function getLine, List lines, From 344afceba4759b9d54c4b0b929d0d35eb56f3b90 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Mon, 19 Aug 2024 16:34:51 +0200 Subject: [PATCH 059/122] refactor equals function --- .../movecraft/sign/AbstractSignListener.java | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java index 5c6398453..37799c472 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java @@ -58,26 +58,25 @@ public String[] rawLines() { } public boolean areSignsEqual(SignWrapper other) { - if (other == null) { - return false; - } + return areSignsEqual(this, other); + } - String[] myLines = this.rawLines(); - String[] theirLines = other.rawLines(); + public static boolean areSignsEqual(SignWrapper a, SignWrapper b) { + String[] aLines = a.rawLines(); + String[] bLines = b.rawLines(); - if (myLines.length != theirLines.length) { + if (aLines.length != bLines.length) { return false; } - for (int i = 0; i < myLines.length; i++) { - String mine = myLines[i].trim(); - String theirs = theirLines[i].trim(); + for (int i = 0; i < aLines.length; i++) { + String aLine = aLines[i].trim(); + String bLine = bLines[i].trim(); - if (!mine.equalsIgnoreCase(theirs)) { + if (!aLine.equalsIgnoreCase(bLine)) { return false; } } - return true; } @@ -92,8 +91,7 @@ public static boolean areSignsEqual(SignWrapper[] a, SignWrapper[] b) { for (int i = 0; i < a.length; i++) { SignWrapper aWrap = a[i]; SignWrapper bWrap = b[i]; - - if (!aWrap.areSignsEqual(bWrap)) { + if (!areSignsEqual(aWrap, bWrap)) { return false; } } From a133c7b50548fd2564a25cd845ca9bac882b2cbc Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Tue, 20 Aug 2024 15:04:26 +0200 Subject: [PATCH 060/122] documentation --- .../movecraft/events/SignTranslateEvent.java | 1 + .../sign/AbstractCraftPilotSign.java | 3 ++ .../movecraft/sign/AbstractCraftSign.java | 22 ++++++++- .../movecraft/sign/AbstractCruiseSign.java | 41 +++++++++++++--- .../sign/AbstractInformationSign.java | 14 ++++-- .../movecraft/sign/AbstractMovecraftSign.java | 48 ++++++++++++++++++- 6 files changed, 116 insertions(+), 13 deletions(-) diff --git a/api/src/main/java/net/countercraft/movecraft/events/SignTranslateEvent.java b/api/src/main/java/net/countercraft/movecraft/events/SignTranslateEvent.java index 5439cfdad..1ff71765f 100644 --- a/api/src/main/java/net/countercraft/movecraft/events/SignTranslateEvent.java +++ b/api/src/main/java/net/countercraft/movecraft/events/SignTranslateEvent.java @@ -8,6 +8,7 @@ import java.util.Collections; import java.util.List; +// TODO: Rewrite to use the adventure API public class SignTranslateEvent extends CraftEvent{ private static final HandlerList HANDLERS = new HandlerList(); @NotNull private final List locations; diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftPilotSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftPilotSign.java index 0ffe0a115..c2d80313a 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftPilotSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftPilotSign.java @@ -2,6 +2,9 @@ import net.countercraft.movecraft.craft.type.CraftType; +/* + * Base implementation for all craft pilot signs, does nothing but has the relevant CraftType instance backed + */ public abstract class AbstractCraftPilotSign extends AbstractMovecraftSign { protected final CraftType craftType; diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftSign.java index 5baa43582..56192087e 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftSign.java @@ -11,8 +11,15 @@ import javax.annotation.Nullable; import java.util.Optional; +/* + * Extension of @AbstractMovecraftSign + * The difference is, that for this sign to work, it must exist on a craft instance + * + * Also this will react to the SignTranslate event + */ public abstract class AbstractCraftSign extends AbstractMovecraftSign { + // Helper method for the listener public static Optional tryGetCraftSign(final String ident) { Optional tmp = AbstractCraftSign.tryGet(ident); if (tmp.isPresent() && tmp.get() instanceof AbstractCraftSign acs) { @@ -32,6 +39,10 @@ public AbstractCraftSign(final String permission, boolean ignoreCraftIsBusy) { this.ignoreCraftIsBusy = ignoreCraftIsBusy; } + // Similar to the super class variant + // In addition a check for a existing craft is being made + // If the craft is a player craft that is currently processing and ignoreCraftIsBusy is set to false, this will quit early and call onCraftIsBusy() + // If no craft is found, onCraftNotFound() is called // Return true to cancel the event @Override public boolean processSignClick(Action clickType, AbstractSignListener.SignWrapper sign, Player player) { @@ -57,6 +68,9 @@ public boolean processSignClick(Action clickType, AbstractSignListener.SignWrapp return internalProcessSign(clickType, sign, player, craft); } + // Implementation of the standard method. + // The craft instance is required here and it's existance is being confirmed in processSignClick() in beforehand + // After that, canPlayerUseSignOn() is being called. If that is successful, the result of internalProcessSignWithCraft() is returned @Override protected boolean internalProcessSign(Action clickType, AbstractSignListener.SignWrapper sign, Player player, @Nullable Craft craft) { if (craft == null) { @@ -68,8 +82,11 @@ protected boolean internalProcessSign(Action clickType, AbstractSignListener.Sig return false; } + // Called when the craft is a player craft and is processing and ignoreCraftIsBusy is set to false protected abstract void onCraftIsBusy(Player player, Craft craft); + // Validation method, intended to indicate if a player is allowed to execute a sign action on a mounted craft + // By default, this returns wether or not the player is the pilot of the craft protected boolean canPlayerUseSignOn(Player player, @Nullable Craft craft) { if (craft instanceof PilotedCraft pc) { return pc.getPilot() == player; @@ -77,8 +94,10 @@ protected boolean canPlayerUseSignOn(Player player, @Nullable Craft craft) { return true; } + // Called when there is no craft instance for this sign protected abstract void onCraftNotFound(Player player, AbstractSignListener.SignWrapper sign); + // By default we don't react to CraftDetectEvent here public void onCraftDetect(CraftDetectEvent event, AbstractSignListener.SignWrapper sign) { // Do nothing by default } @@ -87,9 +106,8 @@ public void onSignMovedByCraft(SignTranslateEvent event) { // Do nothing by default } - protected abstract boolean isSignValid(Action clickType, AbstractSignListener.SignWrapper sign, Player player); - // Gets called by internalProcessSign if a craft is found + // Always override this as the validation has been made already when this is being called protected abstract boolean internalProcessSignWithCraft(Action clickType, AbstractSignListener.SignWrapper sign, Craft craft, Player player); } diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractCruiseSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractCruiseSign.java index e4f622643..48b25588a 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractCruiseSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractCruiseSign.java @@ -13,6 +13,12 @@ import org.bukkit.event.block.SignChangeEvent; import org.jetbrains.annotations.Nullable; +/* + * Base class for all cruise signs + * + * Has the relevant logic for the "state" suffix (on / off) as well as calling the relevant methods and setting the craft to cruising + * + */ public abstract class AbstractCruiseSign extends AbstractCraftSign { private final String suffixOn; @@ -29,12 +35,15 @@ public AbstractCruiseSign(final String permission, boolean ignoreCraftIsBusy, fi this.suffixOff = suffixOff; } + // Checks if the header is empty, if yes, it quits early (unnecessary actually as if it was empty this would never be called) + // Afterwards the header is validated, if it's splitted variant doesn't have exactly 2 entries it is invalid + // Finally, the "state" (second part of the header) isn't matching suffixOn or suffixOff, it is invalid @Override protected boolean isSignValid(Action clickType, AbstractSignListener.SignWrapper sign, Player player) { if (PlainTextComponentSerializer.plainText().serialize(sign.line(0)).isBlank()) { return false; } - String[] headerSplit = this.getSplitHeader(sign); + String[] headerSplit = getSplitHeader(sign); if (headerSplit.length != 2) { return false; } @@ -42,7 +51,10 @@ protected boolean isSignValid(Action clickType, AbstractSignListener.SignWrapper return suffix.equalsIgnoreCase(this.suffixOff) || suffix.equalsIgnoreCase(this.suffixOn); } - protected String[] getSplitHeader(final AbstractSignListener.SignWrapper sign) { + // Returns the raw header, which should consist of the ident and either the suffixOn or suffixOff value + // Returns null if the header is blank + @Nullable + protected static String[] getSplitHeader(final AbstractSignListener.SignWrapper sign) { String header = PlainTextComponentSerializer.plainText().serialize(sign.line(0)); if (header.isBlank()) { return null; @@ -50,30 +62,41 @@ protected String[] getSplitHeader(final AbstractSignListener.SignWrapper sign) { return header.split(":"); } + // If the suffix matches the suffixOn field it will returnt true + // calls getSplitHeader() to retrieve the raw header string protected boolean isOnOrOff(AbstractSignListener.SignWrapper sign) { - String[] headerSplit = this.getSplitHeader(sign); - if (headerSplit.length != 2) { + String[] headerSplit = getSplitHeader(sign); + if (headerSplit == null || headerSplit.length != 2) { return false; } String suffix = headerSplit[1]; return suffix.equalsIgnoreCase(this.suffixOn); } + // By default, cancel the event if the processing was successful, or the invoker was not sneaking => Allows breaking signs while sneaking @Override public boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action type, boolean sneaking) { - return false; + return processingSuccessful || !sneaking; } + // Hook to do stuff that run after stopping to cruise protected void onAfterStoppingCruise(Craft craft, AbstractSignListener.SignWrapper signWrapper, Player player) { } + // Hook to do stuff that run after starting to cruise protected void onAfterStartingCruise(Craft craft, AbstractSignListener.SignWrapper signWrapper, Player player) { } + // Actual processing, determines wether the sign will switch to on or off + // If it will be on, the CruiseDirection is retrieved and then setCraftCruising() is called + // Otherwise, the craft will stop cruising + // Then the sign is updated and the block resetted + // Finally, the relevant hooks are called + // This always returns true @Override - protected boolean internalProcessSign(Action clickType, AbstractSignListener.SignWrapper sign, Player player, Craft craft) { + protected boolean internalProcessSignWithCraft(Action clickType, AbstractSignListener.SignWrapper sign, Craft craft, Player player) { boolean isOn = this.isOnOrOff(sign); boolean willBeOn = !isOn; if (willBeOn) { @@ -98,6 +121,7 @@ protected boolean internalProcessSign(Action clickType, AbstractSignListener.Sig return true; } + // On sign placement, if the entered header is the same as our ident, it will append the off-suffix automatically @Override public boolean processSignChange(SignChangeEvent event, AbstractSignListener.SignWrapper sign) { String header = sign.getRaw(0).trim(); @@ -107,6 +131,7 @@ public boolean processSignChange(SignChangeEvent event, AbstractSignListener.Sig return true; } + // On craft detection, we set all the headers to the "off" header @Override public void onCraftDetect(CraftDetectEvent event, AbstractSignListener.SignWrapper sign) { Player p = null; @@ -122,6 +147,7 @@ public void onCraftDetect(CraftDetectEvent event, AbstractSignListener.SignWrapp } } + // Helper method to build the headline for on or off state protected Component buildHeader(boolean on) { return on ? buildHeaderOn() : buildHeaderOff(); } @@ -134,7 +160,10 @@ protected Component buildHeaderOff() { return Component.text(this.ident).append(Component.text(": ")).append(Component.text(this.suffixOff, Style.style(TextColor.color(255, 0, 0)))); } + // Should call the craft's relevant methods to start cruising protected abstract void setCraftCruising(Player player, CruiseDirection direction, Craft craft); + // TODO: Rework cruise direction to vectors => Vector defines the skip distance and the direction + // Returns the direction in which the craft should cruise protected abstract CruiseDirection getCruiseDirection(AbstractSignListener.SignWrapper sign); } diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractInformationSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractInformationSign.java index 789c856d4..837c6ae59 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractInformationSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractInformationSign.java @@ -84,6 +84,11 @@ protected boolean internalProcessSign(Action clickType, AbstractSignListener.Sig return true; } + // Called whenever the info needs to be refreshed + // That happens on CraftDetect, sign right click (new), Sign Translate + // The new and old values are gathered here and compared + // If nothing has changed, no update happens + // If something has changed, performUpdate() and sendUpdatePacket() are called protected void refreshSign(@Nullable Craft craft, AbstractSignListener.SignWrapper sign, boolean fillDefault, REFRESH_CAUSE refreshCause) { boolean changedSome = false; Component[] updatePayload = new Component[sign.lines().size()]; @@ -117,11 +122,14 @@ public boolean processSignChange(SignChangeEvent event, AbstractSignListener.Sig } /* - Data to set on the sign. Return null if no update should happen! - Attention: A update will only be performed, if the new and old component are different! - */ + Data to set on the sign. Return null if no update should happen! + Attention: A update will only be performed, if the new and old component are different! + */ @Nullable protected abstract Component getUpdateString(int lineIndex, Component oldData, Craft craft); + + // Returns the default value for this info sign per line + // Used on CraftDetect and on sign change @Nullable protected abstract Component getDefaultString(int lineIndex, Component oldComponent); diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java index a15e1add8..56ce941c4 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java @@ -12,7 +12,21 @@ import java.util.*; import java.util.function.Function; -// TODO: In 1.21 signs can have multiple sides! This requires us to pass the clicked side through or well the relevant lines and the set method for the clicked side +// DONE: In 1.21 signs can have multiple sides! This requires us to pass the clicked side through or well the relevant lines and the set method for the clicked side => Resolved using the SignWrapper +/* + * Base class for all signs + * + * A instance of a sign needs to be registered using the register function. + * Signs react to the following events: + * - SignChangeEvent + * - PlayerInteractEvent, if the clicked block is a sign + * - CraftDetectEvent + * - SignTranslateEvent (if the sign is a subclass of AbstractCraftSign) + * + * Whenenver one of those events are cought by the AbstractSignListener instance, it is attempted to retrieve the relevant AbstractMovecraftSign instance. + * For that, the first line of the sign's clicked side is extracted and formatting removed. If it matches the format "foo: bar", only "foo:" will be used. + * With that ident, the sign is attempted to be retrieved vy tryGet(). If that returns something, the object's relevant method is called. + */ public abstract class AbstractMovecraftSign { private static final Map SIGNS = Collections.synchronizedMap(new HashMap<>()); @@ -21,6 +35,7 @@ public static boolean hasBeenRegistered(final String ident) { return SIGNS.containsKey(ident); } + // Special case for pilot signs, they are registered via the crafttypes name public static void registerCraftPilotSigns(Set loadedTypes, Function signFactory) { SIGNS.entrySet().removeIf(entry -> entry.getValue() instanceof AbstractCraftPilotSign); // Now, add all types... @@ -30,6 +45,8 @@ public static void registerCraftPilotSigns(Set loadedTypes, Function< } } + // Attempts to find a AbstractMovecraftSign instance, if something has been registered + // If the ident follows the format "foo: bar", only "foo:" is used as ident to search for public static Optional tryGet(final String ident) { String identToUse = ident.toUpperCase(); if (identToUse.contains(":")) { @@ -40,10 +57,13 @@ public static Optional tryGet(final String ident) { return Optional.ofNullable(SIGNS.getOrDefault(identToUse, null)); } + // Registers a sign in all cases public static void register(final String ident, final @Nonnull AbstractMovecraftSign instance) { register(ident, instance, true); } + // Registers a sign + // If @param overrideIfAlreadyRegistered is set to false, it won't be registered if something has elready been registered using that name public static void register(final String ident, final @Nonnull AbstractMovecraftSign instance, boolean overrideIfAlreadyRegistered) { if (overrideIfAlreadyRegistered) { SIGNS.put(ident.toUpperCase(), instance); @@ -52,6 +72,9 @@ public static void register(final String ident, final @Nonnull AbstractMovecraft } } + // Optional permission for this sign + // Note that this is only checked against in normal processSignClick by default + // When using the default constructor, the permission will not be set @Nullable protected final String permissionString; @@ -63,6 +86,9 @@ public AbstractMovecraftSign(String permissionNode) { this.permissionString = permissionNode; } + // Utility function to retrieve the ident of a a given sign instance + // DO NOT call this for unregistered instances! + // It is a good idea to cache the return value of this function cause otherwise a loop over all registered sign instances will be necessary public static String findIdent(AbstractMovecraftSign instance) { if (!SIGNS.containsValue(instance)) { throw new IllegalArgumentException("MovecraftSign instance must be registered!"); @@ -75,7 +101,9 @@ public static String findIdent(AbstractMovecraftSign instance) { throw new IllegalStateException("Somehow didn't find a key for a value that is in the map!"); } - // Return true to cancel the event + // Called whenever a player clicks the sign + // SignWrapper wraps the relevant clicked side of the sign and the sign block itself + // If true is returned, the event will be cancelled public boolean processSignClick(Action clickType, AbstractSignListener.SignWrapper sign, Player player) { if (!this.isSignValid(clickType, sign, player)) { return false; @@ -87,6 +115,8 @@ public boolean processSignClick(Action clickType, AbstractSignListener.SignWrapp return internalProcessSign(clickType, sign, player, getCraft(sign)); } + // Validation method + // By default this checks if the player has the set permission protected boolean canPlayerUseSign(Action clickType, AbstractSignListener.SignWrapper sign, Player player) { if (this.permissionString == null || this.permissionString.isBlank()) { return true; @@ -94,13 +124,27 @@ protected boolean canPlayerUseSign(Action clickType, AbstractSignListener.SignWr return player.hasPermission(this.permissionString); } + // Helper method, simply calls the existing methods @Nullable protected Craft getCraft(AbstractSignListener.SignWrapper sign) { return MathUtils.getCraftByPersistentBlockData(sign.block().getLocation()); } + // Used by the event handler to determine if the event should be cancelled + // processingSuccessful is the output of processSignClick() or processSignChange() + // This is only called for the PlayerInteractEvent and the SignChangeEvent public abstract boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action type, boolean sneaking); + + // Validation method, called by default in processSignClick + // If false is returned, nothing will be processed protected abstract boolean isSignValid(Action clickType, AbstractSignListener.SignWrapper sign, Player player); + + // Called by processSignClick after validation. At this point, isSignValid() and canPlayerUseSign() have been called already + // If the sign belongs to a craft, that craft is given in the @param craft argument + // Return true, if everything was ok protected abstract boolean internalProcessSign(Action clickType, AbstractSignListener.SignWrapper sign, Player player, @Nullable Craft craft); + + // Called by the event handler when SignChangeEvent is being cought + // Return true, if everything was ok public abstract boolean processSignChange(SignChangeEvent event, AbstractSignListener.SignWrapper sign); } From 3a261a6aa3755ea9fa5891ad3ff9a5b93b6a92d9 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Tue, 20 Aug 2024 16:10:20 +0200 Subject: [PATCH 061/122] small corrections --- .../net/countercraft/movecraft/sign/CraftPilotSign.java | 8 ++++---- .../countercraft/movecraft/sign/AbstractCraftSign.java | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/CraftPilotSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/CraftPilotSign.java index 7b8aa680b..a3827e8b0 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/CraftPilotSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/CraftPilotSign.java @@ -57,12 +57,12 @@ protected boolean isSignValid(Action clickType, AbstractSignListener.SignWrapper @Override protected boolean internalProcessSign(Action clickType, AbstractSignListener.SignWrapper sign, Player player, @javax.annotation.Nullable Craft craft) { - if (this.craftType.getBoolProperty(CraftType.MUST_BE_SUBCRAFT) && craft.isEmpty()) { + if (this.craftType.getBoolProperty(CraftType.MUST_BE_SUBCRAFT) && craft == null) { return false; } World world = sign.block().getWorld(); - if (craft.isPresent()) { - world = craft.get().getWorld(); + if (craft != null) { + world = craft.getWorld(); } Location loc = sign.block().getLocation(); MovecraftLocation startPoint = new MovecraftLocation(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); @@ -77,7 +77,7 @@ protected boolean internalProcessSign(Action clickType, AbstractSignListener.Sig return true; } - protected void runDetectTask(MovecraftLocation startPoint, Player player, AbstractSignListener.SignWrapper signWrapper, Optional parentCraft, World world) { + protected void runDetectTask(MovecraftLocation startPoint, Player player, AbstractSignListener.SignWrapper signWrapper, Craft parentCraft, World world) { PILOTING.add(startPoint); CraftManager.getInstance().detect( startPoint, diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftSign.java index 56192087e..3a7a00d4d 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftSign.java @@ -28,7 +28,7 @@ public static Optional tryGetCraftSign(final String ident) { return Optional.empty(); } - private final boolean ignoreCraftIsBusy; + protected final boolean ignoreCraftIsBusy; public AbstractCraftSign(boolean ignoreCraftIsBusy) { this(null, ignoreCraftIsBusy); From a755453a6cd47c608b679a1d1f9bbdb64e21db69 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Tue, 20 Aug 2024 16:10:33 +0200 Subject: [PATCH 062/122] add base for subcraft signs --- .../movecraft/sign/AbstractSubcraftSign.java | 179 ++++++++++++++++++ 1 file changed, 179 insertions(+) create mode 100644 api/src/main/java/net/countercraft/movecraft/sign/AbstractSubcraftSign.java diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractSubcraftSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractSubcraftSign.java new file mode 100644 index 000000000..1d8b4a023 --- /dev/null +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractSubcraftSign.java @@ -0,0 +1,179 @@ +package net.countercraft.movecraft.sign; + +import net.countercraft.movecraft.MovecraftLocation; +import net.countercraft.movecraft.craft.Craft; +import net.countercraft.movecraft.craft.PlayerCraft; +import net.countercraft.movecraft.craft.type.CraftType; +import net.kyori.adventure.text.Component; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.Player; +import org.bukkit.event.block.Action; +import org.bukkit.event.block.SignChangeEvent; +import org.bukkit.plugin.Plugin; +import org.bukkit.scheduler.BukkitRunnable; +import org.jetbrains.annotations.Nullable; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import java.util.function.Function; +import java.util.function.Supplier; + +public abstract class AbstractSubcraftSign extends AbstractCraftSign { + + // TODO: Replace by writing to the signs nbt data + protected static final Set IN_USE = Collections.synchronizedSet(new HashSet<>()); + + protected final Function craftTypeRetrievalFunction; + + protected final Supplier pluginInstance; + + public AbstractSubcraftSign(Function craftTypeRetrievalFunction, final Supplier plugin) { + this(null, craftTypeRetrievalFunction, plugin); + } + + public AbstractSubcraftSign(final String permission, Function craftTypeRetrievalFunction, final Supplier plugin) { + super(permission, false); + this.craftTypeRetrievalFunction = craftTypeRetrievalFunction; + this.pluginInstance = plugin; + } + + @Override + public boolean processSignClick(Action clickType, AbstractSignListener.SignWrapper sign, Player player) { + if (!this.isSignValid(clickType, sign, player)) { + return false; + } + if (!this.canPlayerUseSign(clickType, sign, player)) { + return false; + } + Craft craft = this.getCraft(sign); + + if (craft instanceof PlayerCraft pc) { + if (!pc.isNotProcessing() && !this.ignoreCraftIsBusy) { + this.onCraftIsBusy(player, craft); + return false; + } + } + + return internalProcessSign(clickType, sign, player, craft); + } + + @Override + protected boolean internalProcessSign(Action clickType, AbstractSignListener.SignWrapper sign, Player player, Craft craft) { + if (craft != null) { + // TODO: Add property to crafts that they can use subcrafts? + if (!this.canPlayerUseSignOn(player, craft)) { + return false; + } + } + return this.internalProcessSignWithCraft(clickType, sign, craft, player); + } + + @Override + public boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action type, boolean sneaking) { + return processingSuccessful || !sneaking; + } + + @Override + public boolean processSignChange(SignChangeEvent event, AbstractSignListener.SignWrapper sign) { + // TODO: Implement + return false; + } + + @Override + protected boolean isSignValid(Action clickType, AbstractSignListener.SignWrapper sign, Player player) { + String[] headerSplit = sign.getRaw(0).split(" "); + if (headerSplit.length != 2) { + return false; + } + // TODO: Change to enums? + String action = headerSplit[headerSplit.length - 1].toUpperCase(); + if (!this.isActionAllowed(action)) { + return false; + } + return this.getCraftType(sign) != null; + } + + @Override + protected boolean canPlayerUseSign(Action clickType, AbstractSignListener.SignWrapper sign, Player player) { + if (!super.canPlayerUseSign(clickType, sign, player)) { + return false; + } + CraftType craftType = this.getCraftType(sign); + if (craftType != null) { + return player.hasPermission("movecraft." + craftType.getStringProperty(CraftType.NAME) + ".pilot") && this.canPlayerUseSignForCraftType(clickType, sign, player, craftType); + } + return false; + } + + @Override + protected boolean internalProcessSignWithCraft(Action clickType, AbstractSignListener.SignWrapper sign, @Nullable Craft craft, Player player) { + CraftType subcraftType = this.getCraftType(sign); + + final Location signLoc = sign.block().getLocation(); + final MovecraftLocation startPoint = new MovecraftLocation(signLoc.getBlockX(), signLoc.getBlockY(), signLoc.getBlockZ()); + + if (craft != null) { + craft.setProcessing(true); + // TODO: SOlve this more elegantly... + new BukkitRunnable() { + @Override + public void run() { + craft.setProcessing(false); + } + }.runTaskLater(this.pluginInstance.get(), (10)); + } + + if (!IN_USE.add(startPoint)) { + this.onActionAlreadyInProgress(player); + return true; + } + + this.applyDefaultText(sign); + + final World world = sign.block().getWorld(); + + this.runDetectTask(subcraftType, craft, world, player, startPoint); + + // TODO: Change this, it is ugly, should be done by the detect task itself + new BukkitRunnable() { + @Override + public void run() { + IN_USE.remove(startPoint); + } + }.runTaskLater(this.pluginInstance.get(), 4); + + return false; + } + + protected abstract void runDetectTask(CraftType subcraftType, Craft craft, World world, Player player, MovecraftLocation startPoint); + + protected void applyDefaultText(AbstractSignListener.SignWrapper sign) { + if (sign.getRaw(2).isBlank() && sign.getRaw(3).isBlank()) { + Component l3 = this.getDefaultTextFor(2); + Component l4 = this.getDefaultTextFor(3); + if (l3 != null) { + sign.line(2, l3); + } + if (l4 != null) { + sign.line(2, l4); + } + } + } + + @Nullable + protected CraftType getCraftType(AbstractSignListener.SignWrapper wrapper) { + String ident = wrapper.getRaw(2); + if (ident.trim().isBlank()) { + return null; + } + return this.craftTypeRetrievalFunction.apply(ident); + } + + protected abstract boolean isActionAllowed(final String action); + protected abstract void onActionAlreadyInProgress(Player player); + protected abstract Component getDefaultTextFor(int line); + protected abstract boolean canPlayerUseSignForCraftType(Action clickType, AbstractSignListener.SignWrapper sign, Player player, CraftType craftType); + +} From e78f2fd1e29459928d961ad9ec761cf225f9fc54 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Tue, 27 Aug 2024 12:53:06 +0200 Subject: [PATCH 063/122] migrate Remote Sign Needs review! --- .../net/countercraft/movecraft/Movecraft.java | 8 +- .../movecraft/sign/RemoteSign.java | 212 +++++++++--------- 2 files changed, 118 insertions(+), 102 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java b/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java index 8c8f361e2..10f85faef 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java @@ -55,6 +55,7 @@ public class Movecraft extends JavaPlugin { private WorldHandler worldHandler; private SmoothTeleport smoothTeleport; private AsyncManager asyncManager; + private AbstractSignListener abstractSignListener; public static synchronized Movecraft getInstance() { return instance; @@ -130,7 +131,7 @@ public void onEnable() { final Class signListenerClass = Class.forName("net.countercraft.movecraft.compat." + WorldHandler.getPackageName(minecraftVersion) + ".SignListener"); if (AbstractSignListener.class.isAssignableFrom(signListenerClass)) { - AbstractSignListener abstractSignListener = (AbstractSignListener) signListenerClass.getConstructor().newInstance(); + abstractSignListener = (AbstractSignListener) signListenerClass.getConstructor().newInstance(); getServer().getPluginManager().registerEvents(abstractSignListener, this); } } @@ -232,7 +233,8 @@ public void onEnable() { AbstractMovecraftSign.register("RMove:", new RelativeMoveSign()); //getServer().getPluginManager().registerEvents(new ReleaseSign(), this); AbstractMovecraftSign.register("Release", new ReleaseSign()); - getServer().getPluginManager().registerEvents(new RemoteSign(), this); + //getServer().getPluginManager().registerEvents(new RemoteSign(), this); + AbstractMovecraftSign.register("Remote Sign", new RemoteSign()); //getServer().getPluginManager().registerEvents(new SpeedSign(), this); AbstractMovecraftSign.register("Speed:", new SpeedSign()); AbstractMovecraftSign.register("Status:", new StatusSign()); @@ -355,4 +357,6 @@ public SmoothTeleport getSmoothTeleport() { public AsyncManager getAsyncManager() { return asyncManager; } + + public AbstractSignListener getAbstractSignListener() {return abstractSignListener;} } diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/RemoteSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/RemoteSign.java index f9bad8835..f847cc530 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/RemoteSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/RemoteSign.java @@ -1,152 +1,164 @@ package net.countercraft.movecraft.sign; +import net.countercraft.movecraft.Movecraft; import net.countercraft.movecraft.MovecraftLocation; import net.countercraft.movecraft.config.Settings; import net.countercraft.movecraft.craft.Craft; -import net.countercraft.movecraft.craft.CraftManager; -import net.countercraft.movecraft.craft.PlayerCraft; import net.countercraft.movecraft.craft.type.CraftType; import net.countercraft.movecraft.localisation.I18nSupport; -import net.countercraft.movecraft.util.MathUtils; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.block.Block; +import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; import org.bukkit.block.BlockState; import org.bukkit.block.Sign; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; +import org.bukkit.entity.Player; import org.bukkit.event.block.Action; import org.bukkit.event.block.SignChangeEvent; -import org.bukkit.event.player.PlayerInteractEvent; -import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import java.util.Hashtable; import java.util.LinkedList; +import java.util.Map; +import java.util.Optional; import static net.countercraft.movecraft.util.ChatUtils.ERROR_PREFIX; -public final class RemoteSign implements Listener{ +public class RemoteSign extends AbstractCraftSign { private static final String HEADER = "Remote Sign"; - @EventHandler - public final void onSignChange(SignChangeEvent event) { - if (!event.getLine(0).equalsIgnoreCase(HEADER)) { - return; - } - else if(event.getLine(1).equals("")) { - event.getPlayer().sendMessage(ERROR_PREFIX + I18nSupport.getInternationalisedString("Remote Sign - Cannot be blank")); - event.setLine(0,""); - event.setLine(2,""); - event.setLine(3,""); - return; - } + public RemoteSign() { + super(null, false); } - @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) - public void onSignClick(@NotNull PlayerInteractEvent event) { - if (event.getAction() != Action.RIGHT_CLICK_BLOCK && event.getAction() != Action.LEFT_CLICK_BLOCK) { - return; - } - BlockState state = event.getClickedBlock().getState(); - if (!(state instanceof Sign)) { - return; - } - Sign sign = (Sign) state; - if (!ChatColor.stripColor(sign.getLine(0)).equalsIgnoreCase(HEADER)) { - return; - } - event.setCancelled(true); - Craft foundCraft = null; - for (PlayerCraft tcraft : CraftManager.getInstance().getPlayerCraftsInWorld(event.getClickedBlock().getWorld())) { - if (MathUtils.locationInHitBox(tcraft.getHitBox(), event.getClickedBlock().getLocation())) { - // don't use a craft with a null player. This is - // mostly to avoid trying to use subcrafts - foundCraft = tcraft; - break; - } - } - - if (foundCraft == null) { - event.getPlayer().sendMessage(ERROR_PREFIX+I18nSupport.getInternationalisedString("Remote Sign - Must be a part of a piloted craft")); - return; - } - - if (!foundCraft.getType().getBoolProperty(CraftType.ALLOW_REMOTE_SIGN)) { - event.getPlayer().sendMessage(ERROR_PREFIX + I18nSupport.getInternationalisedString("Remote Sign - Not allowed on this craft")); - return; - } - - String targetText = ChatColor.stripColor(sign.getLine(1)); - if(targetText.equalsIgnoreCase(HEADER)) { - event.getPlayer().sendMessage(ERROR_PREFIX+I18nSupport.getInternationalisedString("Remote Sign - Cannot remote another Remote Sign")); - return; - } + @Override + protected void onCraftIsBusy(Player player, Craft craft) { + // TODO: How to react? + } - if(targetText.equalsIgnoreCase("")) { - event.getPlayer().sendMessage("Remote Sign - Cannot be blank"); - return; - } + @Override + protected void onCraftNotFound(Player player, AbstractSignListener.SignWrapper sign) { + player.sendMessage(ERROR_PREFIX+I18nSupport.getInternationalisedString("Remote Sign - Must be a part of a piloted craft")); + } + @Override + protected boolean internalProcessSignWithCraft(Action clickType, AbstractSignListener.SignWrapper sign, Craft craft, Player player) { LinkedList foundLocations = new LinkedList(); + Map> foundTargetSigns = new Hashtable<>(); boolean firstError = true; - for (MovecraftLocation tloc : foundCraft.getHitBox()) { - BlockState tstate = event.getClickedBlock().getWorld().getBlockAt(tloc.getX(), tloc.getY(), tloc.getZ()).getState(); + final String targetIdent = sign.getRaw(1).toUpperCase(); + for (MovecraftLocation tloc : craft.getHitBox()) { + BlockState tstate = craft.getWorld().getBlockAt(tloc.getX(), tloc.getY(), tloc.getZ()).getState(); if (!(tstate instanceof Sign)) { continue; } Sign ts = (Sign) tstate; - if (isEqualSign(ts, targetText)) { - if (isForbidden(ts)) { - if (firstError) { - event.getPlayer().sendMessage(I18nSupport.getInternationalisedString("Remote Sign - Forbidden string found")); - firstError = false; + AbstractSignListener.SignWrapper[] targetSignWrappers = Movecraft.getInstance().getAbstractSignListener().getSignWrappers(ts); + + if (targetSignWrappers != null) { + for (AbstractSignListener.SignWrapper wrapper : targetSignWrappers) { + // Matches source? + final String signHeader = PlainTextComponentSerializer.plainText().serialize(wrapper.line(0)); + Optional signHandler = AbstractMovecraftSign.tryGet(signHeader); + // Ignore other remove signs + if (!signHandler.isPresent() || signHandler.get() instanceof RemoteSign) { + continue; + } + // Forbidden strings + if (hasForbiddenString(wrapper)) { + if (firstError) { + player.sendMessage(I18nSupport.getInternationalisedString("Remote Sign - Forbidden string found")); + firstError = false; + } + player.sendMessage(" - ".concat(tloc.toString()).concat(" : ").concat(ts.getLine(0))); + } + // But does it match the source man? + if (matchesDescriptor(targetIdent, wrapper)) { + LinkedList value = foundTargetSigns.getOrDefault(signHandler.get(), new LinkedList<>()); + value.add(wrapper); + foundLocations.add(tloc); } - event.getPlayer().sendMessage(" - ".concat(tloc.toString()).concat(" : ").concat(ts.getLine(0))); - } else { - foundLocations.add(tloc); } } } if (!firstError) { - return; + return false; } - else if (foundLocations.isEmpty()) { - event.getPlayer().sendMessage(I18nSupport.getInternationalisedString("Remote Sign - Could not find target sign")); - return; + else if (foundTargetSigns.isEmpty()) { + player.sendMessage(I18nSupport.getInternationalisedString("Remote Sign - Could not find target sign")); + return false; } if (Settings.MaxRemoteSigns > -1) { - int foundLocCount = foundLocations.size(); + int foundLocCount = foundTargetSigns.size(); if(foundLocCount > Settings.MaxRemoteSigns) { - event.getPlayer().sendMessage(String.format(I18nSupport.getInternationalisedString("Remote Sign - Exceeding maximum allowed"), foundLocCount, Settings.MaxRemoteSigns)); - return; + player.sendMessage(String.format(I18nSupport.getInternationalisedString("Remote Sign - Exceeding maximum allowed"), foundLocCount, Settings.MaxRemoteSigns)); + return false; } } - for (MovecraftLocation foundLoc : foundLocations) { - Block newBlock = event.getClickedBlock().getWorld().getBlockAt(foundLoc.getX(), foundLoc.getY(), foundLoc.getZ()); + // call the handlers! + foundTargetSigns.entrySet().forEach(entry -> { + AbstractMovecraftSign signHandler = entry.getKey(); + for (AbstractSignListener.SignWrapper wrapper : entry.getValue()) { + signHandler.processSignClick(clickType, wrapper, player); + } + }); + + return true; + } + + @Override + public boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action type, boolean sneaking) { + return processingSuccessful || !sneaking; + } - PlayerInteractEvent newEvent = new PlayerInteractEvent(event.getPlayer(), event.getAction(), event.getItem(), newBlock, event.getBlockFace()); + @Override + protected boolean isSignValid(Action clickType, AbstractSignListener.SignWrapper sign, Player player) { + String target = sign.getRaw(1); + if (target.isBlank()) { + player.sendMessage(ERROR_PREFIX + I18nSupport.getInternationalisedString("Remote Sign - Cannot be blank")); + return false; + } - //TODO: DON'T DO THIS - Bukkit.getServer().getPluginManager().callEvent(newEvent); + if (hasForbiddenString(sign)) { + player.sendMessage(I18nSupport.getInternationalisedString("Remote Sign - Forbidden string found")); + return false; } - - event.setCancelled(true); + + return true; } - private boolean isEqualSign(Sign test, String target) { - return !ChatColor.stripColor(test.getLine(0)).equalsIgnoreCase(HEADER) && ( ChatColor.stripColor(test.getLine(0)).equalsIgnoreCase(target) - || ChatColor.stripColor(test.getLine(1)).equalsIgnoreCase(target) - || ChatColor.stripColor(test.getLine(2)).equalsIgnoreCase(target) - || ChatColor.stripColor(test.getLine(3)).equalsIgnoreCase(target) ); + + protected static boolean hasForbiddenString(AbstractSignListener.SignWrapper wrapper) { + for (int i = 0; i < wrapper.lines().size(); i++) { + String s = wrapper.getRaw(i).toLowerCase(); + if(Settings.ForbiddenRemoteSigns.contains(s)) + return true; + } + return false; } - private boolean isForbidden(Sign test) { - for (int i = 0; i < 4; i++) { - String t = test.getLine(i).toLowerCase(); - if(Settings.ForbiddenRemoteSigns.contains(t)) + + // Walks through all strings on the wrapper and if any of the non-header strings match it returns true + protected static boolean matchesDescriptor(final String descriptor, final AbstractSignListener.SignWrapper potentialTarget) { + for (int i = 1; i < potentialTarget.lines().size(); i++) { + String targetStr = potentialTarget.getRaw(i).toUpperCase(); + if (descriptor.equalsIgnoreCase(targetStr)) { return true; + } } return false; } + + @Override + public boolean processSignChange(SignChangeEvent event, AbstractSignListener.SignWrapper sign) { + return isSignValid(Action.PHYSICAL, sign, event.getPlayer()); + } + + @Override + protected boolean canPlayerUseSignOn(Player player, @Nullable Craft craft) { + if (!craft.getType().getBoolProperty(CraftType.ALLOW_REMOTE_SIGN)) { + player.sendMessage(ERROR_PREFIX + I18nSupport.getInternationalisedString("Remote Sign - Not allowed on this craft")); + return false; + } + + return super.canPlayerUseSignOn(player, craft); + } } From ebc5a3b8d181b2c3084ce53bbc64579e19711222 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Tue, 27 Aug 2024 14:15:00 +0200 Subject: [PATCH 064/122] Migrate subcraft rotate sign --- .../net/countercraft/movecraft/Movecraft.java | 3 +- .../movecraft/sign/SubcraftRotateSign.java | 159 ++++++++---------- .../movecraft/MovecraftRotation.java | 15 ++ .../movecraft/sign/AbstractSubcraftSign.java | 7 +- 4 files changed, 89 insertions(+), 95 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java b/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java index 10f85faef..4776f0dad 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java @@ -238,7 +238,8 @@ public void onEnable() { //getServer().getPluginManager().registerEvents(new SpeedSign(), this); AbstractMovecraftSign.register("Speed:", new SpeedSign()); AbstractMovecraftSign.register("Status:", new StatusSign()); - getServer().getPluginManager().registerEvents(new SubcraftRotateSign(), this); + //getServer().getPluginManager().registerEvents(new SubcraftRotateSign(), this); + AbstractMovecraftSign.register("Subcraft Rotate", new SubcraftRotateSign(CraftManager.getInstance()::getCraftTypeFromString, Movecraft::getInstance)); //getServer().getPluginManager().registerEvents(new TeleportSign(), this); AbstractMovecraftSign.register("Teleport:", new TeleportSign()); //getServer().getPluginManager().registerEvents(new ScuttleSign(), this); diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/SubcraftRotateSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/SubcraftRotateSign.java index c8469fa38..628f4bb23 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/SubcraftRotateSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/SubcraftRotateSign.java @@ -10,93 +10,34 @@ import net.countercraft.movecraft.localisation.I18nSupport; import net.countercraft.movecraft.processing.functions.Result; import net.countercraft.movecraft.util.Pair; +import net.kyori.adventure.text.Component; import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.Location; import org.bukkit.World; -import org.bukkit.block.BlockState; -import org.bukkit.block.Sign; import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; import org.bukkit.event.block.Action; -import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.plugin.Plugin; import org.bukkit.scheduler.BukkitRunnable; -import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; -import java.util.HashSet; -import java.util.Set; +import java.util.function.Function; +import java.util.function.Supplier; -public final class SubcraftRotateSign implements Listener { - private static final String HEADER = "Subcraft Rotate"; - private final Set rotating = new HashSet<>(); +public class SubcraftRotateSign extends AbstractSubcraftSign { - @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) - public void onSignClick(@NotNull PlayerInteractEvent event) { - MovecraftRotation rotation; - if (event.getAction() == Action.RIGHT_CLICK_BLOCK) - rotation = MovecraftRotation.CLOCKWISE; - else if (event.getAction() == Action.LEFT_CLICK_BLOCK) - rotation = MovecraftRotation.ANTICLOCKWISE; - else - return; - - BlockState state = event.getClickedBlock().getState(); - if (!(state instanceof Sign)) - return; - Sign sign = (Sign) state; - if (!ChatColor.stripColor(sign.getLine(0)).equalsIgnoreCase(HEADER)) - return; - - event.setCancelled(true); - Location loc = event.getClickedBlock().getLocation(); - MovecraftLocation startPoint = new MovecraftLocation(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); - if (rotating.contains(startPoint)) { - event.getPlayer().sendMessage(I18nSupport.getInternationalisedString("Rotation - Already Rotating")); - event.setCancelled(true); - return; - } - - // rotate subcraft - String craftTypeStr = ChatColor.stripColor(sign.getLine(1)); - CraftType craftType = CraftManager.getInstance().getCraftTypeFromString(craftTypeStr); - if (craftType == null) - return; - if (ChatColor.stripColor(sign.getLine(2)).equals("") - && ChatColor.stripColor(sign.getLine(3)).equals("")) { - sign.setLine(2, "_\\ /_"); - sign.setLine(3, "/ \\"); - sign.update(false, false); - } + public SubcraftRotateSign(Function craftTypeRetrievalFunction, Supplier plugin) { + super(craftTypeRetrievalFunction, plugin); + } - if (!event.getPlayer().hasPermission("movecraft." + craftTypeStr + ".pilot") || !event.getPlayer().hasPermission("movecraft." + craftTypeStr + ".rotate")) { - event.getPlayer().sendMessage(I18nSupport.getInternationalisedString("Insufficient Permissions")); + @Override + protected void runDetectTask(Action clickType, CraftType subcraftType, Craft parentcraft, World world, Player player, MovecraftLocation startPoint) { + final MovecraftRotation rotation = MovecraftRotation.fromAction(clickType); + if (rotation == MovecraftRotation.NONE) { return; } - Craft playerCraft = CraftManager.getInstance().getCraftByPlayer(event.getPlayer()); - if (playerCraft != null) { - if (!playerCraft.isNotProcessing()) { - event.getPlayer().sendMessage(I18nSupport.getInternationalisedString("Detection - Parent Craft is busy")); - return; - } - playerCraft.setProcessing(true); // prevent the parent craft from moving or updating until the subcraft is done - new BukkitRunnable() { - @Override - public void run() { - playerCraft.setProcessing(false); - } - }.runTaskLater(Movecraft.getInstance(), (10)); - } - - rotating.add(startPoint); - - Player player = event.getPlayer(); - World world = event.getClickedBlock().getWorld(); CraftManager.getInstance().detect( startPoint, - craftType, (type, w, p, parents) -> { + subcraftType, (type, w, p, parents) -> { if (parents.size() > 1) return new Pair<>(Result.failWithMessage(I18nSupport.getInternationalisedString( "Detection - Failed - Already commanding a craft")), null); @@ -107,34 +48,72 @@ public void run() { return new Pair<>(Result.succeed(), new SubCraftImpl(type, w, parent)); }, world, player, player, - craft -> () -> { - Bukkit.getServer().getPluginManager().callEvent(new CraftPilotEvent(craft, CraftPilotEvent.Reason.SUB_CRAFT)); - if (craft instanceof SubCraft) { // Subtract craft from the parent - Craft parent = ((SubCraft) craft).getParent(); - var newHitbox = parent.getHitBox().difference(craft.getHitBox());; + subcraft -> () -> { + Bukkit.getServer().getPluginManager().callEvent(new CraftPilotEvent(subcraft, CraftPilotEvent.Reason.SUB_CRAFT)); + if (subcraft instanceof SubCraft) { // Subtract craft from the parent + Craft parent = ((SubCraft) subcraft).getParent(); + var newHitbox = parent.getHitBox().difference(subcraft.getHitBox());; parent.setHitBox(newHitbox); } new BukkitRunnable() { @Override public void run() { - craft.rotate(rotation, startPoint, true); - if (craft instanceof SubCraft) { - Craft parent = ((SubCraft) craft).getParent(); - var newHitbox = parent.getHitBox().union(craft.getHitBox()); + subcraft.rotate(rotation, startPoint, true); + if (subcraft instanceof SubCraft) { + Craft parent = ((SubCraft) subcraft).getParent(); + var newHitbox = parent.getHitBox().union(subcraft.getHitBox()); parent.setHitBox(newHitbox); } - CraftManager.getInstance().release(craft, CraftReleaseEvent.Reason.SUB_CRAFT, false); + CraftManager.getInstance().release(subcraft, CraftReleaseEvent.Reason.SUB_CRAFT, false); } }.runTaskLater(Movecraft.getInstance(), 3); } ); - event.setCancelled(true); - new BukkitRunnable() { - @Override - public void run() { - rotating.remove(startPoint); - } - }.runTaskLater(Movecraft.getInstance(), 4); + } + + @Override + protected boolean isActionAllowed(String action) { + return action.toUpperCase().equalsIgnoreCase("ROTATE"); + } + + @Override + protected void onActionAlreadyInProgress(Player player) { + player.sendMessage(I18nSupport.getInternationalisedString("Rotation - Already Rotating")); + } + + static final Component DEFAULT_LINE_3 = Component.text("_\\ / _"); + static final Component DEFAULT_LINE_4 = Component.text("/ \\"); + + @Override + protected Component getDefaultTextFor(int line) { + switch (line) { + case 2: + return DEFAULT_LINE_3; + case 3: + return DEFAULT_LINE_4; + default: + return null; + } + } + + @Override + protected boolean canPlayerUseSignForCraftType(Action clickType, AbstractSignListener.SignWrapper sign, Player player, CraftType subcraftType) { + final String craftTypeStr = subcraftType.getStringProperty(CraftType.NAME).toLowerCase(); + if (!player.hasPermission("movecraft." + craftTypeStr + ".rotate")) { + player.sendMessage(I18nSupport.getInternationalisedString("Insufficient Permissions")); + return false; + } + return true; + } + + @Override + protected void onCraftIsBusy(Player player, Craft craft) { + player.sendMessage(I18nSupport.getInternationalisedString("Detection - Parent Craft is busy")); + } + + @Override + protected void onCraftNotFound(Player player, AbstractSignListener.SignWrapper sign) { + // Ignored } } diff --git a/api/src/main/java/net/countercraft/movecraft/MovecraftRotation.java b/api/src/main/java/net/countercraft/movecraft/MovecraftRotation.java index f9b580ee7..ca1144495 100644 --- a/api/src/main/java/net/countercraft/movecraft/MovecraftRotation.java +++ b/api/src/main/java/net/countercraft/movecraft/MovecraftRotation.java @@ -17,6 +17,21 @@ package net.countercraft.movecraft; +import org.bukkit.event.block.Action; + public enum MovecraftRotation { CLOCKWISE, NONE, ANTICLOCKWISE + + public static MovecraftRotation fromAction(Action clickType) { + switch (clickType) { + case LEFT_CLICK_AIR: + case LEFT_CLICK_BLOCK: + return ANTICLOCKWISE; + case RIGHT_CLICK_AIR: + case RIGHT_CLICK_BLOCK: + return CLOCKWISE; + default: + return NONE; + } + } } diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractSubcraftSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractSubcraftSign.java index 1d8b4a023..cf9d40cb7 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractSubcraftSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractSubcraftSign.java @@ -134,7 +134,7 @@ public void run() { final World world = sign.block().getWorld(); - this.runDetectTask(subcraftType, craft, world, player, startPoint); + this.runDetectTask(clickType, subcraftType, craft, world, player, startPoint); // TODO: Change this, it is ugly, should be done by the detect task itself new BukkitRunnable() { @@ -147,8 +147,6 @@ public void run() { return false; } - protected abstract void runDetectTask(CraftType subcraftType, Craft craft, World world, Player player, MovecraftLocation startPoint); - protected void applyDefaultText(AbstractSignListener.SignWrapper sign) { if (sign.getRaw(2).isBlank() && sign.getRaw(3).isBlank()) { Component l3 = this.getDefaultTextFor(2); @@ -171,9 +169,10 @@ protected CraftType getCraftType(AbstractSignListener.SignWrapper wrapper) { return this.craftTypeRetrievalFunction.apply(ident); } + protected abstract void runDetectTask(Action clickType, CraftType subcraftType, Craft parentCraft, World world, Player player, MovecraftLocation startPoint); protected abstract boolean isActionAllowed(final String action); protected abstract void onActionAlreadyInProgress(Player player); protected abstract Component getDefaultTextFor(int line); - protected abstract boolean canPlayerUseSignForCraftType(Action clickType, AbstractSignListener.SignWrapper sign, Player player, CraftType craftType); + protected abstract boolean canPlayerUseSignForCraftType(Action clickType, AbstractSignListener.SignWrapper sign, Player player, CraftType subCraftType); } From e493b78d097662bc41df65705808660bdd028404 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Tue, 27 Aug 2024 14:25:03 +0200 Subject: [PATCH 065/122] fix refactor artifact --- .../countercraft/movecraft/sign/AbstractInformationSign.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractInformationSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractInformationSign.java index 837c6ae59..4b796c1d5 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractInformationSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractInformationSign.java @@ -79,7 +79,7 @@ public boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action } @Override - protected boolean internalProcessSign(Action clickType, AbstractSignListener.SignWrapper sign, Player player, Craft craft) { + protected boolean internalProcessSignWithCraft(Action clickType, AbstractSignListener.SignWrapper sign, Craft craft, Player player) { this.refreshSign(craft, sign, false, REFRESH_CAUSE.SIGN_CLICK); return true; } From dc0075cabbc5a66e2deaae8adf1e7a6cf8e7b348 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Tue, 27 Aug 2024 14:25:19 +0200 Subject: [PATCH 066/122] remove unneeded variable => use the field! --- .../net/countercraft/movecraft/features/status/StatusSign.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java index fe9c388a1..398a86f05 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java @@ -14,6 +14,7 @@ import net.kyori.adventure.text.format.Style; import org.bukkit.Material; import org.bukkit.entity.Player; +import org.bukkit.event.block.Action; import org.jetbrains.annotations.Nullable; import java.util.List; @@ -97,7 +98,6 @@ protected void calcDisplayBlocks(Craft craft) { totalNonNegligibleWaterBlocks += add; } } - Object2IntMap displayBlocks = new Object2IntOpenHashMap<>(); for (RequiredBlockEntry entry : craft.getType().getRequiredBlockProperty(CraftType.FLY_BLOCKS)) { int total = 0; for (Material material : entry.getMaterials()) { @@ -178,4 +178,5 @@ protected void sendUpdatePacket(Craft craft, AbstractSignListener.SignWrapper si protected void onCraftIsBusy(Player player, Craft craft) { } + } From f8414ed48072648c51cb6eba2d0e17f22e405d62 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Wed, 28 Aug 2024 11:10:16 +0200 Subject: [PATCH 067/122] migrate contacts sign --- .../net/countercraft/movecraft/Movecraft.java | 3 +- .../features/contacts/ContactsSign.java | 139 +++++++++--------- .../movecraft/features/status/StatusSign.java | 2 - .../sign/AbstractInformationSign.java | 3 + 4 files changed, 71 insertions(+), 76 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java b/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java index 4776f0dad..12fdfa419 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java @@ -238,6 +238,7 @@ public void onEnable() { //getServer().getPluginManager().registerEvents(new SpeedSign(), this); AbstractMovecraftSign.register("Speed:", new SpeedSign()); AbstractMovecraftSign.register("Status:", new StatusSign()); + AbstractMovecraftSign.register("Contacts:", new ContactsSign()); //getServer().getPluginManager().registerEvents(new SubcraftRotateSign(), this); AbstractMovecraftSign.register("Subcraft Rotate", new SubcraftRotateSign(CraftManager.getInstance()::getCraftTypeFromString, Movecraft::getInstance)); //getServer().getPluginManager().registerEvents(new TeleportSign(), this); @@ -254,7 +255,7 @@ public void onEnable() { var contactsManager = new ContactsManager(); contactsManager.runTaskTimerAsynchronously(this, 0, 20); getServer().getPluginManager().registerEvents(contactsManager, this); - getServer().getPluginManager().registerEvents(new ContactsSign(), this); + //getServer().getPluginManager().registerEvents(new ContactsSign(), this); getServer().getPluginManager().registerEvents(new CraftTypeListener(), this); getCommand("contacts").setExecutor(new ContactsCommand()); diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/features/contacts/ContactsSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/features/contacts/ContactsSign.java index 83f52d845..9510ce03d 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/features/contacts/ContactsSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/features/contacts/ContactsSign.java @@ -3,107 +3,100 @@ import net.countercraft.movecraft.MovecraftLocation; import net.countercraft.movecraft.craft.Craft; import net.countercraft.movecraft.craft.type.CraftType; -import net.countercraft.movecraft.events.CraftDetectEvent; -import net.countercraft.movecraft.events.SignTranslateEvent; -import org.bukkit.ChatColor; -import org.bukkit.Tag; -import org.bukkit.World; -import org.bukkit.block.Block; -import org.bukkit.block.BlockState; -import org.bukkit.block.Sign; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; +import net.countercraft.movecraft.sign.AbstractInformationSign; +import net.countercraft.movecraft.sign.AbstractSignListener; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.Style; +import org.bukkit.entity.Player; import org.bukkit.event.block.Action; -import org.bukkit.event.player.PlayerInteractEvent; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; -public class ContactsSign implements Listener { +import java.util.List; + +public class ContactsSign extends AbstractInformationSign { private static final String HEADER = "Contacts:"; - @EventHandler - public void onCraftDetect(@NotNull CraftDetectEvent event) { - World world = event.getCraft().getWorld(); - for (MovecraftLocation location : event.getCraft().getHitBox()) { - var block = location.toBukkit(world).getBlock(); - if (!Tag.SIGNS.isTagged(block.getType())) - continue; - - BlockState state = block.getState(); - if (!(state instanceof Sign sign)) - continue; - - if (!ChatColor.stripColor(sign.getLine(0)).equalsIgnoreCase(HEADER)) - continue; - - sign.setLine(1, ""); - sign.setLine(2, ""); - sign.setLine(3, ""); - sign.update(); - } - } + protected final int MAX_DISTANCE_COLOR_RED = 64 * 64; + protected final int MAX_DISTANCE_COLOR_YELLOW = 128 * 128; - @EventHandler - public final void onSignTranslateEvent(@NotNull SignTranslateEvent event) { - if (!ChatColor.stripColor(event.getLine(0)).equalsIgnoreCase(HEADER)) - return; + protected @NotNull Component contactsLine(@NotNull Craft base, @NotNull Craft target) { + MovecraftLocation baseCenter = base.getHitBox().getMidPoint(); + MovecraftLocation targetCenter = target.getHitBox().getMidPoint(); + int distanceSquared = baseCenter.distanceSquared(targetCenter); - Craft base = event.getCraft(); - int line = 1; - for (Craft target : base.getDataTag(Craft.CONTACTS)) { - if (line > 3) - break; + String craftTypeName = target.getType().getStringProperty(CraftType.NAME); + if (craftTypeName.length() > 9) + craftTypeName = craftTypeName.substring(0, 7); - event.setLine(line++, contactsLine(base, target)); + Style style = STYLE_COLOR_GREEN; + if (distanceSquared <= MAX_DISTANCE_COLOR_RED) { + style = STYLE_COLOR_RED; } - while (line <= 3) { - event.setLine(line++, ""); + else if (distanceSquared <= MAX_DISTANCE_COLOR_YELLOW) { + style = STYLE_COLOR_YELLOW; } - } - - private static @NotNull String contactsLine(@NotNull Craft base, @NotNull Craft target) { - MovecraftLocation baseCenter = base.getHitBox().getMidPoint(); - MovecraftLocation targetCenter = target.getHitBox().getMidPoint(); - int distanceSquared = baseCenter.distanceSquared(targetCenter); - String result = ChatColor.BLUE + target.getType().getStringProperty(CraftType.NAME); - if (result.length() > 9) - result = result.substring(0, 7); + Component result = Component.text(craftTypeName + " ").style(style); - result += " " + (int) Math.sqrt(distanceSquared); int diffX = baseCenter.getX() - targetCenter.getX(); int diffZ = baseCenter.getZ() - targetCenter.getZ(); + String directionStr = "" + (int) Math.sqrt(distanceSquared)); if (Math.abs(diffX) > Math.abs(diffZ)) { if (diffX<0) { - result +=" E"; + directionStr +=" E"; } else { - result +=" W"; + directionStr +=" W"; } } else { if (diffZ<0) { - result +=" S"; + directionStr +=" S"; } else { - result +=" N"; + directionStr +=" N"; } } + result = result.append(Component.text(directionStr).style(STYLE_COLOR_WHITE)); return result; } - @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) - public void onSignClickEvent(@NotNull PlayerInteractEvent event) { - if (event.getAction() != Action.RIGHT_CLICK_BLOCK) - return; + @Override + protected boolean internalProcessSignWithCraft(Action clickType, AbstractSignListener.SignWrapper sign, Craft craft, Player player) { + player.performCommand("contacts"); + + return true; + } + + @Override + protected @Nullable Component getUpdateString(int lineIndex, Component oldData, Craft craft) { + Craft contact = null; + List contacts = craft.getDataTag(Craft.CONTACTS); + if (contacts.isEmpty() || contacts.size() < lineIndex) { + return EMPTY; + } + contact = contacts.get(lineIndex); + + return contactsLine(craft, contact); + } + + @Override + protected @Nullable Component getDefaultString(int lineIndex, Component oldComponent) { + return EMPTY; + } + + @Override + protected void performUpdate(Component[] newComponents, AbstractSignListener.SignWrapper sign, REFRESH_CAUSE refreshCause) { + if (refreshCause != REFRESH_CAUSE.SIGN_MOVED_BY_CRAFT) { + sign.block().update(); + } + } + + @Override + protected void sendUpdatePacket(Craft craft, AbstractSignListener.SignWrapper sign, REFRESH_CAUSE refreshCause) { - Block block = event.getClickedBlock(); - if (block == null) - return; - if (!(block.getState() instanceof Sign sign)) - return; + } - if (!ChatColor.stripColor(sign.getLine(0)).equalsIgnoreCase(HEADER)) - return; + @Override + protected void onCraftIsBusy(Player player, Craft craft) { - event.setCancelled(true); - event.getPlayer().performCommand("contacts"); } } diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java index 398a86f05..360450817 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java @@ -27,8 +27,6 @@ public class StatusSign extends AbstractInformationSign { int totalNonNegligibleBlocks = 0; int totalNonNegligibleWaterBlocks = 0; - public static final Component EMPTY = Component.text(""); - protected static final int FUEL_LINE_INDEX = 3; protected static final int BLOCK_LINE_INDEX_TOP = 1; protected static final int BLOCK_LINE_INDEX_BOTTOM = 2; diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractInformationSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractInformationSign.java index 4b796c1d5..add4afd98 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractInformationSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractInformationSign.java @@ -17,9 +17,12 @@ public abstract class AbstractInformationSign extends AbstractCraftSign { + public static final Component EMPTY = Component.text(""); + protected static final Style STYLE_COLOR_GREEN = Style.style(TextColor.color(0, 255, 0)); protected static final Style STYLE_COLOR_YELLOW = Style.style(TextColor.color(255, 255, 0)); protected static final Style STYLE_COLOR_RED = Style.style(TextColor.color(255, 0, 0)); + protected static final Style STYLE_COLOR_WHITE = Style.style(TextColor.color(255, 255, 255)); public enum REFRESH_CAUSE { SIGN_CREATION, From 36fbe17c3a97a019bd7fd84612a6b9e541175d83 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Wed, 28 Aug 2024 11:11:00 +0200 Subject: [PATCH 068/122] fix error --- .../countercraft/movecraft/features/contacts/ContactsSign.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/features/contacts/ContactsSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/features/contacts/ContactsSign.java index 9510ce03d..378eb691d 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/features/contacts/ContactsSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/features/contacts/ContactsSign.java @@ -15,7 +15,6 @@ import java.util.List; public class ContactsSign extends AbstractInformationSign { - private static final String HEADER = "Contacts:"; protected final int MAX_DISTANCE_COLOR_RED = 64 * 64; protected final int MAX_DISTANCE_COLOR_YELLOW = 128 * 128; @@ -41,7 +40,7 @@ else if (distanceSquared <= MAX_DISTANCE_COLOR_YELLOW) { int diffX = baseCenter.getX() - targetCenter.getX(); int diffZ = baseCenter.getZ() - targetCenter.getZ(); - String directionStr = "" + (int) Math.sqrt(distanceSquared)); + String directionStr = "" + (int) Math.sqrt(distanceSquared); if (Math.abs(diffX) > Math.abs(diffZ)) { if (diffX<0) { directionStr +=" E"; From 1b512f23528072e701abd52cf1286e8fc37181a7 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Wed, 28 Aug 2024 15:43:10 +0200 Subject: [PATCH 069/122] add isEmpty() method and add implementation for equals --- .../movecraft/sign/AbstractSignListener.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java index 37799c472..f26596add 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java @@ -57,6 +57,29 @@ public String[] rawLines() { return result; } + public boolean isEmpty() { + for(String s : this.rawLines()) { + if (s.trim().isEmpty() || s.trim().isBlank()) { + continue; + } + else { + return false; + } + } + return true; + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (obj instanceof SignWrapper other) { + return areSignsEqual(other); + } + return false; + } + public boolean areSignsEqual(SignWrapper other) { return areSignsEqual(this, other); } From c84a81a1a194f3b14191998ebc8ec257cb3e6f23 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Wed, 28 Aug 2024 15:49:33 +0200 Subject: [PATCH 070/122] if the other is null it will be false. Always --- .../net/countercraft/movecraft/sign/AbstractSignListener.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java index f26596add..92e35d347 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java @@ -71,6 +71,9 @@ public boolean isEmpty() { @Override public boolean equals(Object obj) { + if (obj == null) { + return false; + } if (obj == this) { return true; } From 48add81d22fc6bd18baacbcbf63fca6bd3fd7861 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Wed, 28 Aug 2024 15:56:43 +0200 Subject: [PATCH 071/122] begin migrating SignTranslateEvent to use the signwrapper (issue #688) --- .../movecraft/events/SignTranslateEvent.java | 54 ++++++++++++++++--- 1 file changed, 46 insertions(+), 8 deletions(-) diff --git a/api/src/main/java/net/countercraft/movecraft/events/SignTranslateEvent.java b/api/src/main/java/net/countercraft/movecraft/events/SignTranslateEvent.java index 1ff71765f..40e2ad7f1 100644 --- a/api/src/main/java/net/countercraft/movecraft/events/SignTranslateEvent.java +++ b/api/src/main/java/net/countercraft/movecraft/events/SignTranslateEvent.java @@ -2,9 +2,13 @@ import net.countercraft.movecraft.MovecraftLocation; import net.countercraft.movecraft.craft.Craft; +import net.countercraft.movecraft.sign.AbstractSignListener; +import net.kyori.adventure.text.Component; +import org.bukkit.block.BlockFace; import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; +import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -12,37 +16,71 @@ public class SignTranslateEvent extends CraftEvent{ private static final HandlerList HANDLERS = new HandlerList(); @NotNull private final List locations; - @NotNull private final String[] lines; + @NotNull private final AbstractSignListener.SignWrapper backing; private boolean updated = false; + @Deprecated(forRemoval = true) public SignTranslateEvent(@NotNull Craft craft, @NotNull String[] lines, @NotNull List locations) throws IndexOutOfBoundsException{ super(craft); this.locations = locations; - if(lines.length!=4) - throw new IndexOutOfBoundsException(); - this.lines=lines; + List components = new ArrayList<>(); + for (String s : lines) { + components.add(Component.text(s)); + } + this.backing = new AbstractSignListener.SignWrapper(null, components::get, components, components::set, BlockFace.SELF); + } + + public SignTranslateEvent(@NotNull Craft craft, @NotNull AbstractSignListener.SignWrapper backing, @NotNull List locations) throws IndexOutOfBoundsException{ + super(craft); + this.locations = locations; + this.backing = backing; } @NotNull - @Deprecated + @Deprecated(forRemoval = true) public String[] getLines() { + // TODO: Why does this set it to updated? This is just reading... this.updated = true; - return lines; + return backing.rawLines(); } + @Deprecated(forRemoval = true) public String getLine(int index) throws IndexOutOfBoundsException{ if(index > 3 || index < 0) throw new IndexOutOfBoundsException(); - return lines[index]; + return backing.getRaw(index); } + @Deprecated(forRemoval = true) public void setLine(int index, String line){ if(index > 3 || index < 0) throw new IndexOutOfBoundsException(); this.updated = true; - lines[index]=line; + backing.line(index, Component.text(line)); + } + + public Component line(int index) { + return backing.line(index); + } + + public void line(int index, Component component) { + this.updated = true; + backing.line(index, component); + } + + public String getRaw(int index) { + return backing.getRaw(index); + } + + public String[] rawLines() { + return backing.rawLines(); + } + + public List lines() { + return backing.lines(); } + // Bukkit crap @Override public HandlerList getHandlers() { return HANDLERS; From 104be4650f7ac33bcdba3009fe366ca6fe60a493 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Wed, 28 Aug 2024 16:07:07 +0200 Subject: [PATCH 072/122] add methods to directly allow Component as header dient --- .../countercraft/movecraft/sign/AbstractCraftSign.java | 10 ++++++++++ .../movecraft/sign/AbstractMovecraftSign.java | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftSign.java index 3a7a00d4d..232601e82 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftSign.java @@ -5,6 +5,8 @@ import net.countercraft.movecraft.craft.PlayerCraft; import net.countercraft.movecraft.events.CraftDetectEvent; import net.countercraft.movecraft.events.SignTranslateEvent; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; import org.bukkit.entity.Player; import org.bukkit.event.block.Action; @@ -20,6 +22,14 @@ public abstract class AbstractCraftSign extends AbstractMovecraftSign { // Helper method for the listener + public static Optional tryGetCraftSign(final Component ident) { + if (ident == null) { + return Optional.empty(); + } + final String identStr = PlainTextComponentSerializer.plainText().serialize(ident); + return tryGetCraftSign(identStr); + } + public static Optional tryGetCraftSign(final String ident) { Optional tmp = AbstractCraftSign.tryGet(ident); if (tmp.isPresent() && tmp.get() instanceof AbstractCraftSign acs) { diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java index 56ce941c4..516ee6afa 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java @@ -3,6 +3,8 @@ import net.countercraft.movecraft.craft.Craft; import net.countercraft.movecraft.craft.type.CraftType; import net.countercraft.movecraft.util.MathUtils; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; import org.bukkit.entity.Player; import org.bukkit.event.block.Action; import org.bukkit.event.block.SignChangeEvent; @@ -45,6 +47,14 @@ public static void registerCraftPilotSigns(Set loadedTypes, Function< } } + public static Optional tryGet(final Component ident) { + if (ident == null) { + return Optional.empty(); + } + final String identStr = PlainTextComponentSerializer.plainText().serialize(ident); + return tryGet(identStr); + } + // Attempts to find a AbstractMovecraftSign instance, if something has been registered // If the ident follows the format "foo: bar", only "foo:" is used as ident to search for public static Optional tryGet(final String ident) { From 22f1520beaaea64ea21b88a34bece6f3c9bc5efc Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Wed, 28 Aug 2024 16:07:15 +0200 Subject: [PATCH 073/122] use new methods --- .../movecraft/sign/AbstractSignListener.java | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java index 92e35d347..e78380454 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java @@ -140,8 +140,7 @@ public void onCraftDetect(CraftDetectEvent event) { BlockState state = block.getState(); if (state instanceof Sign sign) { for (SignWrapper wrapper : this.getSignWrappers(sign)) { - String ident = PlainTextComponentSerializer.plainText().serialize(wrapper.line(0)); - AbstractCraftSign.tryGetCraftSign(ident).ifPresent(acs -> acs.onCraftDetect(event, wrapper)); + AbstractCraftSign.tryGetCraftSign(wrapper.line(0)).ifPresent(acs -> acs.onCraftDetect(event, wrapper)); } } } @@ -150,8 +149,7 @@ public void onCraftDetect(CraftDetectEvent event) { @EventHandler(ignoreCancelled = true, priority = EventPriority.LOW) public void onSignTranslate(SignTranslateEvent event) { - String ident = event.getLine(0); - AbstractCraftSign.tryGetCraftSign(ident).ifPresent(acs -> acs.onSignMovedByCraft(event)); + AbstractCraftSign.tryGetCraftSign(event.line(0)).ifPresent(acs -> acs.onSignMovedByCraft(event)); } @EventHandler(ignoreCancelled = true, priority = EventPriority.LOW) @@ -160,8 +158,7 @@ public void onSignChange(SignChangeEvent event) { BlockState state = block.getState(); if (state instanceof Sign sign) { SignWrapper wrapper = this.getSignWrapper(sign, event); - final String signHeader = PlainTextComponentSerializer.plainText().serialize(wrapper.line(0)); - AbstractMovecraftSign.tryGet(signHeader).ifPresent(ams -> { + AbstractMovecraftSign.tryGet(wrapper.line(0)).ifPresent(ams -> { boolean success = ams.processSignChange(event, wrapper); if (ams.shouldCancelEvent(success, null, event.getPlayer().isSneaking())) { @@ -180,8 +177,7 @@ public void onSignClick(PlayerInteractEvent event) { BlockState state = block.getState(); if (state instanceof Sign sign) { SignWrapper wrapper = this.getSignWrapper(sign, event); - final String signHeader = PlainTextComponentSerializer.plainText().serialize(wrapper.line(0)); - AbstractMovecraftSign.tryGet(signHeader).ifPresent(ams -> { + AbstractMovecraftSign.tryGet(wrapper.line(0)).ifPresent(ams -> { boolean success = ams.processSignClick(event.getAction(), wrapper, event.getPlayer()); if (ams.shouldCancelEvent(success, event.getAction(), event.getPlayer().isSneaking())) { event.setCancelled(true); From c583ab4329ca2af2185ba1913dfaffc96e388ac2 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Wed, 28 Aug 2024 16:07:22 +0200 Subject: [PATCH 074/122] todo notes --- .../movecraft/mapUpdater/update/CraftRotateCommand.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/mapUpdater/update/CraftRotateCommand.java b/Movecraft/src/main/java/net/countercraft/movecraft/mapUpdater/update/CraftRotateCommand.java index 5998f6de3..f843c57f2 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/mapUpdater/update/CraftRotateCommand.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/mapUpdater/update/CraftRotateCommand.java @@ -200,6 +200,7 @@ public void doUpdate() { } private void sendSignEvents() { + // TODO: Use the signwrappers here Object2ObjectMap> signs = new Object2ObjectOpenCustomHashMap<>(new Hash.Strategy() { @Override public int hashCode(String[] strings) { @@ -216,6 +217,7 @@ public boolean equals(String[] a, String[] b) { for (MovecraftLocation location : craft.getHitBox()) { Block block = location.toBukkit(craft.getWorld()).getBlock(); BlockState state = block.getState(); + // TODO: Change to return the signwrappers for this sign (if not empty!) if (state instanceof Sign) { Sign sign = (Sign) block.getState(); if (!signs.containsKey(sign.getLines())) From dce6e0fafcbc3d3b880e7f3dbb1f371c1dfefdaa Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Wed, 28 Aug 2024 16:07:32 +0200 Subject: [PATCH 075/122] use new methods in SignTranslateEvent --- .../movecraft/compat/v1_18/SignListener.java | 16 ++++------------ .../movecraft/compat/v1_20/SignListener.java | 16 ++++------------ .../movecraft/compat/v1_21/SignListener.java | 16 ++++------------ 3 files changed, 12 insertions(+), 36 deletions(-) diff --git a/v1_18/src/main/java/net/countercraft/movecraft/compat/v1_18/SignListener.java b/v1_18/src/main/java/net/countercraft/movecraft/compat/v1_18/SignListener.java index 7028b7bd2..49a6c2e91 100644 --- a/v1_18/src/main/java/net/countercraft/movecraft/compat/v1_18/SignListener.java +++ b/v1_18/src/main/java/net/countercraft/movecraft/compat/v1_18/SignListener.java @@ -3,7 +3,6 @@ import net.countercraft.movecraft.events.SignTranslateEvent; import net.countercraft.movecraft.sign.AbstractSignListener; import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; import org.bukkit.block.BlockFace; import org.bukkit.block.Sign; import org.bukkit.block.data.Directional; @@ -35,23 +34,16 @@ public SignWrapper[] getSignWrappers(Sign sign) { @Override public SignWrapper[] getSignWrappers(Sign sign, SignTranslateEvent event) { + // TODO: WTF? This is nonsensical SignWrapper[] wrappers = new SignWrapper[1]; for (int i = 0; i < wrappers.length; i++) { BlockFace face = ((Directional) sign.getBlockData()).getFacing(); - List lines = new ArrayList<>(); - for (int j = 0; j < event.getLines().length; j++) { - lines.add(Component.text(event.getLine(j))); - } + List lines = new ArrayList<>(event.lines()); SignWrapper wrapper = new SignWrapper( sign, - (k) -> { - String valTmp = event.getLine(k); - return Component.text(valTmp); - }, + event::line, lines, - (k, component) -> { - event.setLine(k, PlainTextComponentSerializer.plainText().serialize(component)); - }, + event::line, face ); wrappers[i] = wrapper; diff --git a/v1_20/src/main/java/net/countercraft/movecraft/compat/v1_20/SignListener.java b/v1_20/src/main/java/net/countercraft/movecraft/compat/v1_20/SignListener.java index a6641bf0d..f04757e5c 100644 --- a/v1_20/src/main/java/net/countercraft/movecraft/compat/v1_20/SignListener.java +++ b/v1_20/src/main/java/net/countercraft/movecraft/compat/v1_20/SignListener.java @@ -3,7 +3,6 @@ import net.countercraft.movecraft.events.SignTranslateEvent; import net.countercraft.movecraft.sign.AbstractSignListener; import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; import org.bukkit.block.BlockFace; import org.bukkit.block.Sign; import org.bukkit.block.data.Directional; @@ -53,6 +52,7 @@ public SignWrapper[] getSignWrappers(Sign sign) { @Override public SignWrapper[] getSignWrappers(Sign sign, SignTranslateEvent event) { + // TODO: WTF? This is nonsensical Side[] sides = new Side[Side.values().length]; SignWrapper[] wrappers = new SignWrapper[sides.length]; for (int i = 0; i < sides.length; i++) { @@ -62,20 +62,12 @@ public SignWrapper[] getSignWrappers(Sign sign, SignTranslateEvent event) { if (side == Side.BACK) { face = face.getOppositeFace(); } - List lines = new ArrayList<>(); - for (int j = 0; j < event.getLines().length; j++) { - lines.add(Component.text(event.getLine(j))); - } + List lines = new ArrayList<>(event.lines()); SignWrapper wrapper = new SignWrapper( sign, - (k) -> { - String valTmp = event.getLine(k); - return Component.text(valTmp); - }, + event::line, lines, - (k, component) -> { - event.setLine(k, PlainTextComponentSerializer.plainText().serialize(component)); - }, + event::line, face ); wrappers[i] = wrapper; diff --git a/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/SignListener.java b/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/SignListener.java index 2c1eb9e8d..13dee5b97 100644 --- a/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/SignListener.java +++ b/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/SignListener.java @@ -3,7 +3,6 @@ import net.countercraft.movecraft.events.SignTranslateEvent; import net.countercraft.movecraft.sign.AbstractSignListener; import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; import org.bukkit.block.BlockFace; import org.bukkit.block.Sign; import org.bukkit.block.data.Directional; @@ -53,6 +52,7 @@ public SignWrapper[] getSignWrappers(Sign sign) { @Override public SignWrapper[] getSignWrappers(Sign sign, SignTranslateEvent event) { + // TODO: WTF? This is nonsensical Side[] sides = new Side[Side.values().length]; SignWrapper[] wrappers = new SignWrapper[sides.length]; for (int i = 0; i < sides.length; i++) { @@ -62,20 +62,12 @@ public SignWrapper[] getSignWrappers(Sign sign, SignTranslateEvent event) { if (side == Side.BACK) { face = face.getOppositeFace(); } - List lines = new ArrayList<>(); - for (int j = 0; j < event.getLines().length; j++) { - lines.add(Component.text(event.getLine(j))); - } + List lines = new ArrayList<>(event.lines()); SignWrapper wrapper = new SignWrapper( sign, - (k) -> { - String valTmp = event.getLine(k); - return Component.text(valTmp); - }, + event::line, lines, - (k, component) -> { - event.setLine(k, PlainTextComponentSerializer.plainText().serialize(component)); - }, + event::line, face ); wrappers[i] = wrapper; From 514a447dceda4bf95fc72271f1afe7d2a51e602c Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Thu, 29 Aug 2024 12:51:56 +0200 Subject: [PATCH 076/122] add facing value to event --- .../net/countercraft/movecraft/events/SignTranslateEvent.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/api/src/main/java/net/countercraft/movecraft/events/SignTranslateEvent.java b/api/src/main/java/net/countercraft/movecraft/events/SignTranslateEvent.java index 40e2ad7f1..e615f8c5f 100644 --- a/api/src/main/java/net/countercraft/movecraft/events/SignTranslateEvent.java +++ b/api/src/main/java/net/countercraft/movecraft/events/SignTranslateEvent.java @@ -76,6 +76,10 @@ public String[] rawLines() { return backing.rawLines(); } + public BlockFace facing() { + return backing.facing(); + } + public List lines() { return backing.lines(); } From fb0446eb4e835adde2a725dcf90c52ca1cc7b44b Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Thu, 29 Aug 2024 12:53:01 +0200 Subject: [PATCH 077/122] add more utility and itnerface methods --- .../movecraft/sign/AbstractSignListener.java | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java index e78380454..ea05b0ee1 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java @@ -1,5 +1,6 @@ package net.countercraft.movecraft.sign; +import net.countercraft.movecraft.craft.Craft; import net.countercraft.movecraft.events.CraftDetectEvent; import net.countercraft.movecraft.events.SignTranslateEvent; import net.kyori.adventure.text.Component; @@ -14,6 +15,7 @@ import org.bukkit.event.Listener; import org.bukkit.event.block.SignChangeEvent; import org.bukkit.event.player.PlayerInteractEvent; +import org.jetbrains.annotations.Nullable; import java.util.List; import java.util.function.BiConsumer; @@ -28,7 +30,7 @@ public AbstractSignListener() { } public record SignWrapper( - Sign block, + @Nullable Sign block, Function getLine, List lines, BiConsumer setLine, @@ -103,7 +105,9 @@ public static boolean areSignsEqual(SignWrapper a, SignWrapper b) { return false; } } - return true; + + // Now check the facing too! + return a.facing().equals(b.facing()); } public static boolean areSignsEqual(SignWrapper[] a, SignWrapper[] b) { @@ -124,13 +128,23 @@ public static boolean areSignsEqual(SignWrapper[] a, SignWrapper[] b) { return true; } + public void copyContent(SignWrapper other) { + for (int i = 0; i < this.lines().size() && i < other.lines().size(); i++) { + this.line(i, other.line(i)); + } + } + } - public abstract SignWrapper[] getSignWrappers(Sign sign); - public abstract SignWrapper[] getSignWrappers(Sign sign, SignTranslateEvent event); + public SignWrapper[] getSignWrappers(Sign sign) { + return getSignWrappers(sign, false); + }; + public abstract SignWrapper[] getSignWrappers(Sign sign, boolean ignoreEmpty); protected abstract SignWrapper getSignWrapper(Sign sign, SignChangeEvent signChangeEvent); protected abstract SignWrapper getSignWrapper(Sign sign, PlayerInteractEvent interactEvent); + public abstract void processSignTranslation(final Craft craft, boolean checkEventIsUpdated); + @EventHandler(ignoreCancelled = true, priority = EventPriority.LOW) public void onCraftDetect(CraftDetectEvent event) { final World world = event.getCraft().getWorld(); From 376986c43c4dc629164d376543713c8d188cc416 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Thu, 29 Aug 2024 12:53:13 +0200 Subject: [PATCH 078/122] call the adatper --- .../mapUpdater/update/CraftRotateCommand.java | 28 +++-------------- .../update/CraftTranslateCommand.java | 30 ++++--------------- 2 files changed, 9 insertions(+), 49 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/mapUpdater/update/CraftRotateCommand.java b/Movecraft/src/main/java/net/countercraft/movecraft/mapUpdater/update/CraftRotateCommand.java index f843c57f2..adad83847 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/mapUpdater/update/CraftRotateCommand.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/mapUpdater/update/CraftRotateCommand.java @@ -1,8 +1,5 @@ package net.countercraft.movecraft.mapUpdater.update; -import it.unimi.dsi.fastutil.Hash; -import it.unimi.dsi.fastutil.objects.Object2ObjectMap; -import it.unimi.dsi.fastutil.objects.Object2ObjectOpenCustomHashMap; import net.countercraft.movecraft.Movecraft; import net.countercraft.movecraft.MovecraftLocation; import net.countercraft.movecraft.MovecraftRotation; @@ -13,35 +10,18 @@ import net.countercraft.movecraft.craft.SinkingCraft; import net.countercraft.movecraft.craft.type.CraftType; import net.countercraft.movecraft.events.CraftReleaseEvent; -import net.countercraft.movecraft.events.SignTranslateEvent; import net.countercraft.movecraft.util.CollectionUtils; import net.countercraft.movecraft.util.MathUtils; import net.countercraft.movecraft.util.Tags; import net.countercraft.movecraft.util.hitboxes.HitBox; import net.countercraft.movecraft.util.hitboxes.SetHitBox; import net.countercraft.movecraft.util.hitboxes.SolidHitBox; -import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.Tag; -import org.bukkit.block.Block; -import org.bukkit.block.BlockState; -import org.bukkit.block.Sign; -import org.bukkit.block.data.BlockData; import org.jetbrains.annotations.NotNull; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Queue; -import java.util.Set; +import java.util.*; import java.util.logging.Logger; import java.util.stream.Collectors; @@ -200,8 +180,8 @@ public void doUpdate() { } private void sendSignEvents() { - // TODO: Use the signwrappers here - Object2ObjectMap> signs = new Object2ObjectOpenCustomHashMap<>(new Hash.Strategy() { + Movecraft.getInstance().getAbstractSignListener().processSignTranslation(craft, true); + /* Object2ObjectMap> signs = new Object2ObjectOpenCustomHashMap<>(new Hash.Strategy() { @Override public int hashCode(String[] strings) { return Arrays.hashCode(strings); @@ -250,7 +230,7 @@ public boolean equals(String[] a, String[] b) { sign.update(false, false); block.setBlockData(data); } - } + }*/ } @NotNull diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/mapUpdater/update/CraftTranslateCommand.java b/Movecraft/src/main/java/net/countercraft/movecraft/mapUpdater/update/CraftTranslateCommand.java index 7fa64e43a..7a4d8b057 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/mapUpdater/update/CraftTranslateCommand.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/mapUpdater/update/CraftTranslateCommand.java @@ -2,9 +2,6 @@ import com.google.common.collect.Lists; import com.google.common.collect.Sets; -import it.unimi.dsi.fastutil.Hash; -import it.unimi.dsi.fastutil.objects.Object2ObjectMap; -import it.unimi.dsi.fastutil.objects.Object2ObjectOpenCustomHashMap; import net.countercraft.movecraft.Movecraft; import net.countercraft.movecraft.MovecraftLocation; import net.countercraft.movecraft.WorldHandler; @@ -14,37 +11,19 @@ import net.countercraft.movecraft.craft.SinkingCraft; import net.countercraft.movecraft.craft.type.CraftType; import net.countercraft.movecraft.events.CraftReleaseEvent; -import net.countercraft.movecraft.events.SignTranslateEvent; import net.countercraft.movecraft.util.MathUtils; import net.countercraft.movecraft.util.Tags; import net.countercraft.movecraft.util.hitboxes.HitBox; import net.countercraft.movecraft.util.hitboxes.SetHitBox; import net.countercraft.movecraft.util.hitboxes.SolidHitBox; -import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.Tag; import org.bukkit.World; -import org.bukkit.block.Block; -import org.bukkit.block.BlockState; -import org.bukkit.block.Sign; import org.bukkit.block.data.Waterlogged; import org.jetbrains.annotations.NotNull; -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Queue; -import java.util.Set; +import java.util.*; import java.util.logging.Logger; public class CraftTranslateCommand extends UpdateCommand { @@ -303,7 +282,8 @@ private LinkedList hullSearch(SetHitBox validExterior) { } private void sendSignEvents(){ - Object2ObjectMap> signs = new Object2ObjectOpenCustomHashMap<>(new Hash.Strategy() { + Movecraft.getInstance().getAbstractSignListener().processSignTranslation(craft, false); + /*Object2ObjectMap> signs = new Object2ObjectOpenCustomHashMap<>(new Hash.Strategy() { @Override public int hashCode(String[] strings) { return Arrays.hashCode(strings); @@ -345,12 +325,12 @@ public boolean equals(String[] a, String[] b) { continue; } Sign sign = signStates.get(location); - for(int i = 0; i<4; i++){ + for(int i = 0; i<4; i++) { sign.setLine(i, entry.getKey()[i]); } sign.update(false, false); } - } + }*/ } @NotNull From 4e407a3a41161412108f70d31fcbac4f21e03286 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Thu, 29 Aug 2024 12:53:24 +0200 Subject: [PATCH 079/122] implement methods in adatpers --- .../movecraft/compat/v1_18/SignListener.java | 105 ++++++++++++---- .../movecraft/compat/v1_20/SignListener.java | 118 +++++++++++++----- .../movecraft/compat/v1_21/SignListener.java | 118 +++++++++++++----- 3 files changed, 257 insertions(+), 84 deletions(-) diff --git a/v1_18/src/main/java/net/countercraft/movecraft/compat/v1_18/SignListener.java b/v1_18/src/main/java/net/countercraft/movecraft/compat/v1_18/SignListener.java index 49a6c2e91..40ad6b48a 100644 --- a/v1_18/src/main/java/net/countercraft/movecraft/compat/v1_18/SignListener.java +++ b/v1_18/src/main/java/net/countercraft/movecraft/compat/v1_18/SignListener.java @@ -1,16 +1,24 @@ package net.countercraft.movecraft.compat.v1_18; +import it.unimi.dsi.fastutil.Hash; +import it.unimi.dsi.fastutil.objects.Object2ObjectMap; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenCustomHashMap; +import net.countercraft.movecraft.MovecraftLocation; +import net.countercraft.movecraft.craft.Craft; import net.countercraft.movecraft.events.SignTranslateEvent; import net.countercraft.movecraft.sign.AbstractSignListener; import net.kyori.adventure.text.Component; +import org.bukkit.Bukkit; +import org.bukkit.Tag; +import org.bukkit.block.Block; import org.bukkit.block.BlockFace; +import org.bukkit.block.BlockState; import org.bukkit.block.Sign; import org.bukkit.block.data.Directional; import org.bukkit.event.block.SignChangeEvent; import org.bukkit.event.player.PlayerInteractEvent; -import java.util.ArrayList; -import java.util.List; +import java.util.*; public class SignListener extends AbstractSignListener { @@ -27,28 +35,12 @@ protected final SignWrapper createFromSign(final Sign sign) { } @Override - public SignWrapper[] getSignWrappers(Sign sign) { + public SignWrapper[] getSignWrappers(Sign sign, boolean ignoreEmpty) { SignWrapper wrapper = this.createFromSign(sign); - return new SignWrapper[] {wrapper}; - } - - @Override - public SignWrapper[] getSignWrappers(Sign sign, SignTranslateEvent event) { - // TODO: WTF? This is nonsensical - SignWrapper[] wrappers = new SignWrapper[1]; - for (int i = 0; i < wrappers.length; i++) { - BlockFace face = ((Directional) sign.getBlockData()).getFacing(); - List lines = new ArrayList<>(event.lines()); - SignWrapper wrapper = new SignWrapper( - sign, - event::line, - lines, - event::line, - face - ); - wrappers[i] = wrapper; + if (ignoreEmpty && wrapper.isEmpty()) { + return new SignWrapper[] {}; } - return wrappers; + return new SignWrapper[] {wrapper}; } @Override @@ -68,4 +60,73 @@ protected SignWrapper getSignWrapper(Sign sign, SignChangeEvent signChangeEvent) protected SignWrapper getSignWrapper(Sign sign, PlayerInteractEvent interactEvent) { return this.createFromSign(sign); } + + @Override + public void processSignTranslation(Craft craft, boolean checkEventIsUpdated) { + Object2ObjectMap> signs = new Object2ObjectOpenCustomHashMap<>(new Hash.Strategy() { + @Override + public int hashCode(SignWrapper strings) { + return Arrays.hashCode(strings.rawLines()); + } + + @Override + public boolean equals(SignWrapper a, SignWrapper b) { + return SignWrapper.areSignsEqual(a, b); + } + }); + Map signStates = new HashMap<>(); + + for (MovecraftLocation location : craft.getHitBox()) { + Block block = location.toBukkit(craft.getWorld()).getBlock(); + if(!Tag.SIGNS.isTagged(block.getType())){ + continue; + } + BlockState state = block.getState(); + if (state instanceof Sign) { + Sign sign = (Sign) state; + SignWrapper[] wrappersAtLoc = this.getSignWrappers(sign, true); + if (wrappersAtLoc == null || wrappersAtLoc.length == 0) { + continue; + } + for (SignWrapper wrapper : wrappersAtLoc) { + List values = signs.computeIfAbsent(wrapper, (w) -> new ArrayList<>()); + values.add(location); + } + signStates.put(location, wrappersAtLoc); + } + } + // TODO: This is not good yet, this doesn't really care about a signs sides... + for(Map.Entry> entry : signs.entrySet()){ + final List components = new ArrayList<>(entry.getKey().lines()); + SignWrapper backingForEvent = new SignWrapper(null, components::get, components, components::set, entry.getKey().facing()); + SignTranslateEvent event = new SignTranslateEvent(craft, backingForEvent, entry.getValue()); + Bukkit.getServer().getPluginManager().callEvent(event); + // if(!event.isUpdated()){ + // continue; + // } + // TODO: This is implemented only to fix client caching + // ideally we wouldn't do the update and would instead fake it out to the player + for(MovecraftLocation location : entry.getValue()){ + Block block = location.toBukkit(craft.getWorld()).getBlock(); + BlockState state = block.getState(); + if (!(state instanceof Sign)) { + continue; + } + SignWrapper[] signsAtLoc = signStates.get(location); + if (signsAtLoc != null && signsAtLoc.length > 0) { + for (SignWrapper sw : signsAtLoc) { + if (!checkEventIsUpdated || event.isUpdated()) { + sw.copyContent(entry.getKey()); + } + } + try { + ((Sign)location.toBukkit(craft.getWorld()).getBlock()).update(false, false); + } catch(ClassCastException ex) { + // Ignore + } + } + } + } + } + } diff --git a/v1_20/src/main/java/net/countercraft/movecraft/compat/v1_20/SignListener.java b/v1_20/src/main/java/net/countercraft/movecraft/compat/v1_20/SignListener.java index f04757e5c..3b52fc57a 100644 --- a/v1_20/src/main/java/net/countercraft/movecraft/compat/v1_20/SignListener.java +++ b/v1_20/src/main/java/net/countercraft/movecraft/compat/v1_20/SignListener.java @@ -1,9 +1,18 @@ package net.countercraft.movecraft.compat.v1_20; +import it.unimi.dsi.fastutil.Hash; +import it.unimi.dsi.fastutil.objects.Object2ObjectMap; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenCustomHashMap; +import net.countercraft.movecraft.MovecraftLocation; +import net.countercraft.movecraft.craft.Craft; import net.countercraft.movecraft.events.SignTranslateEvent; import net.countercraft.movecraft.sign.AbstractSignListener; import net.kyori.adventure.text.Component; +import org.bukkit.Bukkit; +import org.bukkit.Tag; +import org.bukkit.block.Block; import org.bukkit.block.BlockFace; +import org.bukkit.block.BlockState; import org.bukkit.block.Sign; import org.bukkit.block.data.Directional; import org.bukkit.block.sign.Side; @@ -12,8 +21,7 @@ import org.bukkit.event.player.PlayerInteractEvent; import org.jetbrains.annotations.NotNull; -import java.util.ArrayList; -import java.util.List; +import java.util.*; public class SignListener extends AbstractSignListener { @@ -38,41 +46,18 @@ protected final SignWrapper createFromSide(final Sign sign, final SignSide signS } @Override - public SignWrapper[] getSignWrappers(Sign sign) { + public SignWrapper[] getSignWrappers(Sign sign, boolean ignoreEmpty) { Side[] sides = new Side[Side.values().length]; - SignWrapper[] wrappers = new SignWrapper[sides.length]; + List wrappers = new ArrayList<>(); for (int i = 0; i < sides.length; i++) { Side side = sides[i]; SignSide signSide = sign.getSide(side); SignWrapper wrapper = this.createFromSide(sign, signSide, side); - wrappers[i] = wrapper; + wrappers.add(wrapper); } - return wrappers; - } - - @Override - public SignWrapper[] getSignWrappers(Sign sign, SignTranslateEvent event) { - // TODO: WTF? This is nonsensical - Side[] sides = new Side[Side.values().length]; - SignWrapper[] wrappers = new SignWrapper[sides.length]; - for (int i = 0; i < sides.length; i++) { - Side side = sides[i]; - SignSide signSide = sign.getSide(side); - BlockFace face = ((Directional) sign.getBlockData()).getFacing(); - if (side == Side.BACK) { - face = face.getOppositeFace(); - } - List lines = new ArrayList<>(event.lines()); - SignWrapper wrapper = new SignWrapper( - sign, - event::line, - lines, - event::line, - face - ); - wrappers[i] = wrapper; - } - return wrappers; + if (ignoreEmpty) + wrappers.removeIf(SignWrapper::isEmpty); + return wrappers.toArray(new SignWrapper[wrappers.size()]); } @Override @@ -97,4 +82,75 @@ protected SignWrapper getSignWrapper(Sign sign, PlayerInteractEvent interactEven @NotNull SignSide side = sign.getTargetSide(interactEvent.getPlayer()); return this.createFromSide(sign, side, sign.getInteractableSideFor(interactEvent.getPlayer())); } + + @Override + public void processSignTranslation(Craft craft, boolean checkEventIsUpdated) { + Object2ObjectMap> signs = new Object2ObjectOpenCustomHashMap<>(new Hash.Strategy() { + @Override + public int hashCode(SignWrapper strings) { + return Arrays.hashCode(strings.rawLines()) * strings.facing().hashCode(); + } + + @Override + public boolean equals(SignWrapper a, SignWrapper b) { + return SignWrapper.areSignsEqual(a, b); + } + }); + Map signStates = new HashMap<>(); + + for (MovecraftLocation location : craft.getHitBox()) { + Block block = location.toBukkit(craft.getWorld()).getBlock(); + if(!Tag.SIGNS.isTagged(block.getType())){ + continue; + } + BlockState state = block.getState(); + if (state instanceof Sign) { + Sign sign = (Sign) state; + SignWrapper[] wrappersAtLoc = this.getSignWrappers(sign, true); + if (wrappersAtLoc == null || wrappersAtLoc.length == 0) { + continue; + } + for (SignWrapper wrapper : wrappersAtLoc) { + List values = signs.computeIfAbsent(wrapper, (w) -> new ArrayList<>()); + values.add(location); + } + signStates.put(location, wrappersAtLoc); + } + } + for(Map.Entry> entry : signs.entrySet()){ + final List components = new ArrayList<>(entry.getKey().lines()); + SignWrapper backingForEvent = new SignWrapper(null, components::get, components, components::set, entry.getKey().facing()); + SignTranslateEvent event = new SignTranslateEvent(craft, backingForEvent, entry.getValue()); + Bukkit.getServer().getPluginManager().callEvent(event); + // if(!event.isUpdated()){ + // continue; + // } + // TODO: This is implemented only to fix client caching + // ideally we wouldn't do the update and would instead fake it out to the player + for(MovecraftLocation location : entry.getValue()){ + Block block = location.toBukkit(craft.getWorld()).getBlock(); + BlockState state = block.getState(); + if (!(state instanceof Sign)) { + continue; + } + SignWrapper[] signsAtLoc = signStates.get(location); + if (signsAtLoc != null && signsAtLoc.length > 0) { + for (SignWrapper sw : signsAtLoc) { + // Important: Check if the wrapper faces the right way! + if (!sw.facing().equals(entry.getKey().facing())) { + continue; + } + if (!checkEventIsUpdated || event.isUpdated()) { + sw.copyContent(entry.getKey()); + } + } + try { + ((Sign)location.toBukkit(craft.getWorld()).getBlock()).update(false, false); + } catch(ClassCastException ex) { + // Ignore + } + } + } + } + } } diff --git a/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/SignListener.java b/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/SignListener.java index 13dee5b97..829a7196f 100644 --- a/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/SignListener.java +++ b/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/SignListener.java @@ -1,9 +1,18 @@ package net.countercraft.movecraft.compat.v1_21; +import it.unimi.dsi.fastutil.Hash; +import it.unimi.dsi.fastutil.objects.Object2ObjectMap; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenCustomHashMap; +import net.countercraft.movecraft.MovecraftLocation; +import net.countercraft.movecraft.craft.Craft; import net.countercraft.movecraft.events.SignTranslateEvent; import net.countercraft.movecraft.sign.AbstractSignListener; import net.kyori.adventure.text.Component; +import org.bukkit.Bukkit; +import org.bukkit.Tag; +import org.bukkit.block.Block; import org.bukkit.block.BlockFace; +import org.bukkit.block.BlockState; import org.bukkit.block.Sign; import org.bukkit.block.data.Directional; import org.bukkit.block.sign.Side; @@ -12,8 +21,7 @@ import org.bukkit.event.player.PlayerInteractEvent; import org.jetbrains.annotations.NotNull; -import java.util.ArrayList; -import java.util.List; +import java.util.*; public class SignListener extends AbstractSignListener { @@ -38,41 +46,18 @@ protected final SignWrapper createFromSide(final Sign sign, final SignSide signS } @Override - public SignWrapper[] getSignWrappers(Sign sign) { + public SignWrapper[] getSignWrappers(Sign sign, boolean ignoreEmpty) { Side[] sides = new Side[Side.values().length]; - SignWrapper[] wrappers = new SignWrapper[sides.length]; + List wrappers = new ArrayList<>(); for (int i = 0; i < sides.length; i++) { Side side = sides[i]; SignSide signSide = sign.getSide(side); SignWrapper wrapper = this.createFromSide(sign, signSide, side); - wrappers[i] = wrapper; + wrappers.add(wrapper); } - return wrappers; - } - - @Override - public SignWrapper[] getSignWrappers(Sign sign, SignTranslateEvent event) { - // TODO: WTF? This is nonsensical - Side[] sides = new Side[Side.values().length]; - SignWrapper[] wrappers = new SignWrapper[sides.length]; - for (int i = 0; i < sides.length; i++) { - Side side = sides[i]; - SignSide signSide = sign.getSide(side); - BlockFace face = ((Directional) sign.getBlockData()).getFacing(); - if (side == Side.BACK) { - face = face.getOppositeFace(); - } - List lines = new ArrayList<>(event.lines()); - SignWrapper wrapper = new SignWrapper( - sign, - event::line, - lines, - event::line, - face - ); - wrappers[i] = wrapper; - } - return wrappers; + if (ignoreEmpty) + wrappers.removeIf(SignWrapper::isEmpty); + return wrappers.toArray(new SignWrapper[wrappers.size()]); } @Override @@ -97,4 +82,75 @@ protected SignWrapper getSignWrapper(Sign sign, PlayerInteractEvent interactEven @NotNull SignSide side = sign.getTargetSide(interactEvent.getPlayer()); return this.createFromSide(sign, side, sign.getInteractableSideFor(interactEvent.getPlayer())); } + + @Override + public void processSignTranslation(Craft craft, boolean checkEventIsUpdated) { + Object2ObjectMap> signs = new Object2ObjectOpenCustomHashMap<>(new Hash.Strategy() { + @Override + public int hashCode(SignWrapper strings) { + return Arrays.hashCode(strings.rawLines()) * strings.facing().hashCode(); + } + + @Override + public boolean equals(SignWrapper a, SignWrapper b) { + return SignWrapper.areSignsEqual(a, b); + } + }); + Map signStates = new HashMap<>(); + + for (MovecraftLocation location : craft.getHitBox()) { + Block block = location.toBukkit(craft.getWorld()).getBlock(); + if(!Tag.SIGNS.isTagged(block.getType())){ + continue; + } + BlockState state = block.getState(); + if (state instanceof Sign) { + Sign sign = (Sign) state; + SignWrapper[] wrappersAtLoc = this.getSignWrappers(sign, true); + if (wrappersAtLoc == null || wrappersAtLoc.length == 0) { + continue; + } + for (SignWrapper wrapper : wrappersAtLoc) { + List values = signs.computeIfAbsent(wrapper, (w) -> new ArrayList<>()); + values.add(location); + } + signStates.put(location, wrappersAtLoc); + } + } + for(Map.Entry> entry : signs.entrySet()){ + final List components = new ArrayList<>(entry.getKey().lines()); + SignWrapper backingForEvent = new SignWrapper(null, components::get, components, components::set, entry.getKey().facing()); + SignTranslateEvent event = new SignTranslateEvent(craft, backingForEvent, entry.getValue()); + Bukkit.getServer().getPluginManager().callEvent(event); + // if(!event.isUpdated()){ + // continue; + // } + // TODO: This is implemented only to fix client caching + // ideally we wouldn't do the update and would instead fake it out to the player + for(MovecraftLocation location : entry.getValue()){ + Block block = location.toBukkit(craft.getWorld()).getBlock(); + BlockState state = block.getState(); + if (!(state instanceof Sign)) { + continue; + } + SignWrapper[] signsAtLoc = signStates.get(location); + if (signsAtLoc != null && signsAtLoc.length > 0) { + for (SignWrapper sw : signsAtLoc) { + // Important: Check if the wrapper faces the right way! + if (!sw.facing().equals(entry.getKey().facing())) { + continue; + } + if (!checkEventIsUpdated || event.isUpdated()) { + sw.copyContent(entry.getKey()); + } + } + try { + ((Sign)location.toBukkit(craft.getWorld()).getBlock()).update(false, false); + } catch(ClassCastException ex) { + // Ignore + } + } + } + } + } } From 9531e366ec776c9e7b037fec08f4587cfb7feed4 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Thu, 29 Aug 2024 12:53:34 +0200 Subject: [PATCH 080/122] adjust information signs --- .../features/contacts/ContactsSign.java | 7 +--- .../movecraft/features/status/StatusSign.java | 11 ++---- .../movecraft/sign/SpeedSign.java | 7 +--- .../sign/AbstractInformationSign.java | 35 +++++++++++++------ 4 files changed, 30 insertions(+), 30 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/features/contacts/ContactsSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/features/contacts/ContactsSign.java index 378eb691d..a88978759 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/features/contacts/ContactsSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/features/contacts/ContactsSign.java @@ -84,16 +84,11 @@ protected boolean internalProcessSignWithCraft(Action clickType, AbstractSignLis @Override protected void performUpdate(Component[] newComponents, AbstractSignListener.SignWrapper sign, REFRESH_CAUSE refreshCause) { - if (refreshCause != REFRESH_CAUSE.SIGN_MOVED_BY_CRAFT) { + if (refreshCause != REFRESH_CAUSE.SIGN_MOVED_BY_CRAFT && sign.block() != null) { sign.block().update(); } } - @Override - protected void sendUpdatePacket(Craft craft, AbstractSignListener.SignWrapper sign, REFRESH_CAUSE refreshCause) { - - } - @Override protected void onCraftIsBusy(Player player, Craft craft) { diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java index 360450817..826d52c27 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java @@ -69,11 +69,11 @@ protected Component calcFuel(Craft craft) { } @Override - protected void refreshSign(@Nullable Craft craft, AbstractSignListener.SignWrapper sign, boolean fillDefault, REFRESH_CAUSE refreshCause) { + protected boolean refreshSign(@Nullable Craft craft, AbstractSignListener.SignWrapper sign, boolean fillDefault, REFRESH_CAUSE refreshCause) { // Calculate blocks and store them temporary, not pretty but works! calcDisplayBlocks(craft); calcdisplayComponents(craft); - super.refreshSign(craft, sign, fillDefault, refreshCause); + return super.refreshSign(craft, sign, fillDefault, refreshCause); } protected void calcDisplayBlocks(Craft craft) { @@ -162,16 +162,11 @@ protected void calcdisplayComponents(Craft craft) { @Override protected void performUpdate(Component[] newComponents, AbstractSignListener.SignWrapper sign, REFRESH_CAUSE refreshCause) { - if (refreshCause != REFRESH_CAUSE.SIGN_MOVED_BY_CRAFT) { + if (refreshCause != REFRESH_CAUSE.SIGN_MOVED_BY_CRAFT && sign.block() != null) { sign.block().update(true); } } - @Override - protected void sendUpdatePacket(Craft craft, AbstractSignListener.SignWrapper sign, REFRESH_CAUSE refreshCause) { - - } - @Override protected void onCraftIsBusy(Player player, Craft craft) { diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/SpeedSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/SpeedSign.java index 1fcb5d8d4..a26f80495 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/SpeedSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/SpeedSign.java @@ -75,16 +75,11 @@ protected void performUpdate(Component[] newComponents, AbstractSignListener.Sig sign.line(i, newComp); } } - if (refreshCause != REFRESH_CAUSE.SIGN_MOVED_BY_CRAFT) { + if (refreshCause != REFRESH_CAUSE.SIGN_MOVED_BY_CRAFT && sign.block() != null) { sign.block().update(true); } } - @Override - protected void sendUpdatePacket(Craft craft, AbstractSignListener.SignWrapper sign, REFRESH_CAUSE refreshCause) { - - } - @Override protected void onCraftIsBusy(Player player, Craft craft) { return; diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractInformationSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractInformationSign.java index add4afd98..fed132cb3 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractInformationSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractInformationSign.java @@ -9,6 +9,7 @@ import net.kyori.adventure.text.format.TextColor; import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; import org.bukkit.block.Sign; import org.bukkit.entity.Player; import org.bukkit.event.block.Action; @@ -53,11 +54,13 @@ public void onCraftDetect(CraftDetectEvent event, AbstractSignListener.SignWrapp public void onSignMovedByCraft(SignTranslateEvent event) { super.onSignMovedByCraft(event); final Craft craft = event.getCraft(); - for (MovecraftLocation movecraftLocation : event.getLocations()) { - Block block = movecraftLocation.toBukkit(craft.getWorld()).getBlock(); - if (block instanceof Sign sign) { - for (AbstractSignListener.SignWrapper wrapper : AbstractSignListener.INSTANCE.getSignWrappers(sign, event)) { - this.refreshSign(event.getCraft(), wrapper, false, REFRESH_CAUSE.SIGN_MOVED_BY_CRAFT); + AbstractSignListener.SignWrapper wrapperTmp = new AbstractSignListener.SignWrapper(null, event::line, event.lines(), event::line, BlockFace.SELF); + if (this.refreshSign(craft, wrapperTmp, false, REFRESH_CAUSE.SIGN_MOVED_BY_CRAFT)) { + for (MovecraftLocation movecraftLocation : event.getLocations()) { + Block block = movecraftLocation.toBukkit(craft.getWorld()).getBlock(); + if (block instanceof Sign sign) { + AbstractSignListener.SignWrapper wrapperTmpTmp = new AbstractSignListener.SignWrapper(sign, event::line, event.lines(), event::line, event.facing()); + this.sendUpdatePacket(craft, wrapperTmpTmp, REFRESH_CAUSE.SIGN_MOVED_BY_CRAFT); } } } @@ -83,7 +86,9 @@ public boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action @Override protected boolean internalProcessSignWithCraft(Action clickType, AbstractSignListener.SignWrapper sign, Craft craft, Player player) { - this.refreshSign(craft, sign, false, REFRESH_CAUSE.SIGN_CLICK); + if (this.refreshSign(craft, sign, false, REFRESH_CAUSE.SIGN_CLICK)) { + this.sendUpdatePacket(craft, sign, REFRESH_CAUSE.SIGN_CLICK); + } return true; } @@ -92,7 +97,8 @@ protected boolean internalProcessSignWithCraft(Action clickType, AbstractSignLis // The new and old values are gathered here and compared // If nothing has changed, no update happens // If something has changed, performUpdate() and sendUpdatePacket() are called - protected void refreshSign(@Nullable Craft craft, AbstractSignListener.SignWrapper sign, boolean fillDefault, REFRESH_CAUSE refreshCause) { + // Returns wether or not something has changed + protected boolean refreshSign(@Nullable Craft craft, AbstractSignListener.SignWrapper sign, boolean fillDefault, REFRESH_CAUSE refreshCause) { boolean changedSome = false; Component[] updatePayload = new Component[sign.lines().size()]; for(int i = 1; i < sign.lines().size(); i++) { @@ -114,13 +120,15 @@ protected void refreshSign(@Nullable Craft craft, AbstractSignListener.SignWrapp } if (changedSome) { this.performUpdate(updatePayload, sign, refreshCause); - this.sendUpdatePacket(craft, sign, refreshCause); } + return changedSome; } @Override public boolean processSignChange(SignChangeEvent event, AbstractSignListener.SignWrapper sign) { - this.refreshSign(null, sign, true, REFRESH_CAUSE.SIGN_CREATION); + if (this.refreshSign(null, sign, true, REFRESH_CAUSE.SIGN_CREATION)) { + this.sendUpdatePacket(null, sign, REFRESH_CAUSE.SIGN_CREATION); + } return true; } @@ -146,5 +154,12 @@ public boolean processSignChange(SignChangeEvent event, AbstractSignListener.Sig /* Gets called after performUpdate has been called */ - protected abstract void sendUpdatePacket(Craft craft, AbstractSignListener.SignWrapper sign, REFRESH_CAUSE refreshCause); + protected void sendUpdatePacket(Craft craft, AbstractSignListener.SignWrapper sign, REFRESH_CAUSE refreshCause) { + if (sign.block() == null) { + return; + } + for (Player player : sign.block().getLocation().getNearbyPlayers(16)) { + player.sendSignChange(sign.block().getLocation(), sign.lines()); + } + } } From 630dd476723f9a606ae5afe64637cb7e950bd6fa Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Thu, 29 Aug 2024 12:56:25 +0200 Subject: [PATCH 081/122] deprecation note --- .../countercraft/movecraft/sign/AbstractSignListener.java | 8 ++++++++ .../countercraft/movecraft/compat/v1_18/SignListener.java | 4 ++++ .../countercraft/movecraft/compat/v1_20/SignListener.java | 4 ++++ .../countercraft/movecraft/compat/v1_21/SignListener.java | 4 ++++ 4 files changed, 20 insertions(+) diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java index ea05b0ee1..db3008138 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java @@ -21,6 +21,10 @@ import java.util.function.BiConsumer; import java.util.function.Function; +/* + * As soon as 1.18 support is dropped, the adapter system will be dropped too + */ +@Deprecated(forRemoval = true) public abstract class AbstractSignListener implements Listener { public static AbstractSignListener INSTANCE; @@ -29,6 +33,10 @@ public AbstractSignListener() { INSTANCE = this; } + /* + * As soon as 1.18 support is dropped, the adapter system will be dropped too + */ + @Deprecated(forRemoval = true) public record SignWrapper( @Nullable Sign block, Function getLine, diff --git a/v1_18/src/main/java/net/countercraft/movecraft/compat/v1_18/SignListener.java b/v1_18/src/main/java/net/countercraft/movecraft/compat/v1_18/SignListener.java index 40ad6b48a..7f1e122a6 100644 --- a/v1_18/src/main/java/net/countercraft/movecraft/compat/v1_18/SignListener.java +++ b/v1_18/src/main/java/net/countercraft/movecraft/compat/v1_18/SignListener.java @@ -20,6 +20,10 @@ import java.util.*; +/* + * As soon as 1.18 support is dropped, the adapter system will be dropped too + */ +@Deprecated(forRemoval = true) public class SignListener extends AbstractSignListener { protected final SignWrapper createFromSign(final Sign sign) { diff --git a/v1_20/src/main/java/net/countercraft/movecraft/compat/v1_20/SignListener.java b/v1_20/src/main/java/net/countercraft/movecraft/compat/v1_20/SignListener.java index 3b52fc57a..6a5d9add0 100644 --- a/v1_20/src/main/java/net/countercraft/movecraft/compat/v1_20/SignListener.java +++ b/v1_20/src/main/java/net/countercraft/movecraft/compat/v1_20/SignListener.java @@ -23,6 +23,10 @@ import java.util.*; +/* + * As soon as 1.18 support is dropped, the adapter system will be dropped too + */ +@Deprecated(forRemoval = true) public class SignListener extends AbstractSignListener { protected final SignWrapper createFromSide(final Sign sign, final Side side) { diff --git a/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/SignListener.java b/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/SignListener.java index 829a7196f..f49ed798c 100644 --- a/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/SignListener.java +++ b/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/SignListener.java @@ -23,6 +23,10 @@ import java.util.*; +/* + * As soon as 1.18 support is dropped, the adapter system will be dropped too + */ +@Deprecated(forRemoval = true) public class SignListener extends AbstractSignListener { protected final SignWrapper createFromSide(final Sign sign, final Side side) { From 9b20ae06513f514798b5a8ef4bc369324987831e Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Thu, 29 Aug 2024 13:11:36 +0200 Subject: [PATCH 082/122] fix method name --- .../net/countercraft/movecraft/features/status/StatusSign.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java index 9e487c318..5f9314424 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java @@ -128,7 +128,7 @@ protected void calcdisplayComponents(Craft craft) { displayComponents.set(1, EMPTY); int signLine = 0; int signColumn = 0; - for (RequiredBlockEntry entry : displayBlocks.getKeySet()) { + for (RequiredBlockEntry entry : displayBlocks.keySet()) { if (entry.getMin() == 0.0) { continue; } From 68c62a1dd4eabed71880bd614a0b1a30c825eeba Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Thu, 29 Aug 2024 13:16:53 +0200 Subject: [PATCH 083/122] fix compile errors --- .../countercraft/movecraft/features/status/StatusSign.java | 4 ++-- .../java/net/countercraft/movecraft/MovecraftRotation.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java index 5f9314424..aeebd3f3e 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java @@ -104,8 +104,8 @@ protected void calcDisplayBlocks(Craft craft) { } Counter displayBlocksTmp = new Counter<>(); - displayBlocksTmp.add(craft.getDataTag(Craft.FLYBLOCKS); - displayBlocksTmp.add(craft.getDataTag(Craft.MOVEBLOCKS); + displayBlocksTmp.add(craft.getDataTag(Craft.FLYBLOCKS)); + displayBlocksTmp.add(craft.getDataTag(Craft.MOVEBLOCKS)); for (RequiredBlockEntry entry : displayBlocksTmp.getKeySet()) { // TODO: Sure? diff --git a/api/src/main/java/net/countercraft/movecraft/MovecraftRotation.java b/api/src/main/java/net/countercraft/movecraft/MovecraftRotation.java index ca1144495..49f98781b 100644 --- a/api/src/main/java/net/countercraft/movecraft/MovecraftRotation.java +++ b/api/src/main/java/net/countercraft/movecraft/MovecraftRotation.java @@ -20,7 +20,7 @@ import org.bukkit.event.block.Action; public enum MovecraftRotation { - CLOCKWISE, NONE, ANTICLOCKWISE + CLOCKWISE, NONE, ANTICLOCKWISE; public static MovecraftRotation fromAction(Action clickType) { switch (clickType) { From 92141d49124c38a2f2827ea129c397b2fdba99bf Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Thu, 29 Aug 2024 15:02:34 +0200 Subject: [PATCH 084/122] fix release sign => it is not dependant on a craft existing! --- .../movecraft/sign/ReleaseSign.java | 30 ++++++++----------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/ReleaseSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/ReleaseSign.java index e18a0f59b..44c43e754 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/ReleaseSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/ReleaseSign.java @@ -8,20 +8,10 @@ import org.bukkit.event.block.SignChangeEvent; import org.jetbrains.annotations.Nullable; -public class ReleaseSign extends AbstractCraftSign { +public class ReleaseSign extends AbstractMovecraftSign { public ReleaseSign() { - super(true); - } - - @Override - protected void onCraftIsBusy(Player player, Craft craft) { - - } - - @Override - protected void onCraftNotFound(Player player, AbstractSignListener.SignWrapper sign) { - + super(null); } @Override @@ -38,13 +28,19 @@ protected boolean isSignValid(Action clickType, AbstractSignListener.SignWrapper } @Override - public boolean processSignChange(SignChangeEvent event, AbstractSignListener.SignWrapper sign) { - return false; + protected boolean internalProcessSign(Action clickType, AbstractSignListener.SignWrapper sign, Player player, @Nullable Craft craft) { + if (craft == null) { + craft = CraftManager.getInstance().getCraftByPlayer(player); + } + if (craft != null) { + CraftManager.getInstance().release(craft, CraftReleaseEvent.Reason.PLAYER, false); + } + return true; } @Override - protected boolean internalProcessSignWithCraft(Action clickType, AbstractSignListener.SignWrapper sign, Craft craft, Player player) { - CraftManager.getInstance().release(craft, CraftReleaseEvent.Reason.PLAYER, false); - return true; + public boolean processSignChange(SignChangeEvent event, AbstractSignListener.SignWrapper sign) { + return false; } + } From 2df78c524d42811149767ea20922b87756121262 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Thu, 5 Sep 2024 13:57:15 +0200 Subject: [PATCH 085/122] fix startup error => can't retrieve ident while registering --- .../main/java/net/countercraft/movecraft/Movecraft.java | 6 +++--- .../java/net/countercraft/movecraft/sign/AscendSign.java | 4 ++-- .../java/net/countercraft/movecraft/sign/CruiseSign.java | 4 ++-- .../net/countercraft/movecraft/sign/DescendSign.java | 4 ++-- .../countercraft/movecraft/sign/AbstractCruiseSign.java | 9 +++++---- 5 files changed, 14 insertions(+), 13 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java b/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java index 923a33260..312989a81 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java @@ -222,11 +222,11 @@ public void onEnable() { getServer().getPluginManager().registerEvents(new PlayerListener(), this); getServer().getPluginManager().registerEvents(new ChunkManager(), this); //getServer().getPluginManager().registerEvents(new AscendSign(), this); - AbstractMovecraftSign.register("Ascend:", new AscendSign()); + AbstractMovecraftSign.register("Ascend:", new AscendSign("Ascend:")); //getServer().getPluginManager().registerEvents(new CruiseSign(), this); - AbstractMovecraftSign.register("Cruise:", new CruiseSign()); + AbstractMovecraftSign.register("Cruise:", new CruiseSign("Cruise:")); //getServer().getPluginManager().registerEvents(new DescendSign(), this); - AbstractMovecraftSign.register("Descend:", new DescendSign()); + AbstractMovecraftSign.register("Descend:", new DescendSign("Descend:")); //getServer().getPluginManager().registerEvents(new HelmSign(), this); AbstractMovecraftSign.register("[Helm]", new HelmSign()); AbstractMovecraftSign.register(HelmSign.PRETTY_HEADER, new HelmSign()); diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/AscendSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/AscendSign.java index 60dc0b1e3..b0170ea3b 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/AscendSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/AscendSign.java @@ -9,8 +9,8 @@ public class AscendSign extends AbstractCruiseSign { - public AscendSign() { - super(true, "ON", "OFF"); + public AscendSign(final String ident) { + super(true, ident, "ON", "OFF"); } @Override diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/CruiseSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/CruiseSign.java index 5c28d2cb1..2ce7fbfec 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/CruiseSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/CruiseSign.java @@ -11,8 +11,8 @@ public class CruiseSign extends AbstractCruiseSign { - public CruiseSign() { - super("movecraft.cruisesign", true, "ON", "OFF"); + public CruiseSign(final String ident) { + super("movecraft.cruisesign", true, ident,"ON", "OFF"); } @Override diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/DescendSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/DescendSign.java index 2ccecd465..0ea2d10e4 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/DescendSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/DescendSign.java @@ -10,8 +10,8 @@ // TODO: Unify with AscendSign to use a common "VerticalCruiseSign" class public class DescendSign extends AbstractCruiseSign { - public DescendSign() { - super(true, "ON", "OFF"); + public DescendSign(final String ident) { + super(true, ident, "ON", "OFF"); } @Override diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractCruiseSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractCruiseSign.java index 48b25588a..7cdc4be16 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractCruiseSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractCruiseSign.java @@ -23,16 +23,17 @@ public abstract class AbstractCruiseSign extends AbstractCraftSign { private final String suffixOn; private final String suffixOff; - private final String ident = AbstractMovecraftSign.findIdent(this); + private final String ident; - public AbstractCruiseSign(boolean ignoreCraftIsBusy, final String suffixOn, final String suffixOff) { - this(null, ignoreCraftIsBusy, suffixOn, suffixOff); + public AbstractCruiseSign(boolean ignoreCraftIsBusy, final String ident, final String suffixOn, final String suffixOff) { + this(null, ignoreCraftIsBusy, ident, suffixOn, suffixOff); } - public AbstractCruiseSign(final String permission, boolean ignoreCraftIsBusy, final String suffixOn, final String suffixOff) { + public AbstractCruiseSign(final String permission, boolean ignoreCraftIsBusy, final String ident, final String suffixOn, final String suffixOff) { super(permission, ignoreCraftIsBusy); this.suffixOn = suffixOn; this.suffixOff = suffixOff; + this.ident = ident; } // Checks if the header is empty, if yes, it quits early (unnecessary actually as if it was empty this would never be called) From 960b30a7ed8c4ecc6d9a4f89dbb7af48ca4b5b4c Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Thu, 5 Sep 2024 14:05:01 +0200 Subject: [PATCH 086/122] fix getSignWrappers() method for sign => NPE (cherry picked from commit 5248bc244accc651f97e4a8a17f9e5cbf01bdf7a) --- .../net/countercraft/movecraft/compat/v1_20/SignListener.java | 4 +--- .../net/countercraft/movecraft/compat/v1_21/SignListener.java | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/v1_20/src/main/java/net/countercraft/movecraft/compat/v1_20/SignListener.java b/v1_20/src/main/java/net/countercraft/movecraft/compat/v1_20/SignListener.java index 6a5d9add0..c0dc6685c 100644 --- a/v1_20/src/main/java/net/countercraft/movecraft/compat/v1_20/SignListener.java +++ b/v1_20/src/main/java/net/countercraft/movecraft/compat/v1_20/SignListener.java @@ -51,10 +51,8 @@ protected final SignWrapper createFromSide(final Sign sign, final SignSide signS @Override public SignWrapper[] getSignWrappers(Sign sign, boolean ignoreEmpty) { - Side[] sides = new Side[Side.values().length]; List wrappers = new ArrayList<>(); - for (int i = 0; i < sides.length; i++) { - Side side = sides[i]; + for (Side side : Side.values()) { SignSide signSide = sign.getSide(side); SignWrapper wrapper = this.createFromSide(sign, signSide, side); wrappers.add(wrapper); diff --git a/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/SignListener.java b/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/SignListener.java index f49ed798c..922caaf95 100644 --- a/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/SignListener.java +++ b/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/SignListener.java @@ -51,10 +51,8 @@ protected final SignWrapper createFromSide(final Sign sign, final SignSide signS @Override public SignWrapper[] getSignWrappers(Sign sign, boolean ignoreEmpty) { - Side[] sides = new Side[Side.values().length]; List wrappers = new ArrayList<>(); - for (int i = 0; i < sides.length; i++) { - Side side = sides[i]; + for (Side side : Side.values()) { SignSide signSide = sign.getSide(side); SignWrapper wrapper = this.createFromSide(sign, signSide, side); wrappers.add(wrapper); From 060d8b4ef96baf36f0c41d0f66867ae9baa5915a Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Thu, 5 Sep 2024 14:06:58 +0200 Subject: [PATCH 087/122] fix status sign (cherry picked from commit 189782c3bb2b7bb99d9e136dd9a8ff164b708b76) --- .../countercraft/movecraft/features/status/StatusSign.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java index aeebd3f3e..adce001a3 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java @@ -124,8 +124,8 @@ protected void calcDisplayBlocks(Craft craft) { } protected void calcdisplayComponents(Craft craft) { - displayComponents.set(0, EMPTY); - displayComponents.set(1, EMPTY); + displayComponents.add(EMPTY); + displayComponents.add(EMPTY); int signLine = 0; int signColumn = 0; for (RequiredBlockEntry entry : displayBlocks.keySet()) { From debb19170656a5aa6c0a313560a19b29931f05ac Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Thu, 5 Sep 2024 14:09:28 +0200 Subject: [PATCH 088/122] craft is nullable (cherry picked from commit a2350b26330432c9a5a033ca3f3243ea27e4ac28) --- .../movecraft/features/status/StatusSign.java | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java index adce001a3..074cb998a 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java @@ -8,19 +8,12 @@ import net.countercraft.movecraft.craft.type.RequiredBlockEntry; import net.countercraft.movecraft.sign.AbstractInformationSign; import net.countercraft.movecraft.sign.AbstractSignListener; -import net.countercraft.movecraft.MovecraftLocation; -import net.countercraft.movecraft.craft.Craft; -import net.countercraft.movecraft.craft.type.CraftType; -import net.countercraft.movecraft.craft.type.RequiredBlockEntry; -import net.countercraft.movecraft.events.CraftDetectEvent; -import net.countercraft.movecraft.events.SignTranslateEvent; import net.countercraft.movecraft.util.Counter; import net.countercraft.movecraft.util.Tags; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.Style; import org.bukkit.Material; import org.bukkit.entity.Player; -import org.bukkit.event.block.Action; import org.jetbrains.annotations.Nullable; import java.util.List; @@ -82,10 +75,14 @@ protected boolean refreshSign(@Nullable Craft craft, AbstractSignListener.SignWr return super.refreshSign(craft, sign, fillDefault, refreshCause); } - protected void calcDisplayBlocks(Craft craft) { + protected void calcDisplayBlocks(@Nullable Craft craft) { displayBlocks.clear(); displayComponents.clear(); + if (craft == null) { + return; + } + totalNonNegligibleBlocks = 0; totalNonNegligibleWaterBlocks = 0; Counter materials = craft.getDataTag(Craft.MATERIALS); @@ -123,9 +120,14 @@ protected void calcDisplayBlocks(Craft craft) { } } - protected void calcdisplayComponents(Craft craft) { + protected void calcdisplayComponents(@Nullable Craft craft) { displayComponents.add(EMPTY); displayComponents.add(EMPTY); + + if (craft == null) { + return; + } + int signLine = 0; int signColumn = 0; for (RequiredBlockEntry entry : displayBlocks.keySet()) { From 39e08a5c26b00deecbcbf4337667ba5a86d7d588 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Thu, 5 Sep 2024 14:28:11 +0200 Subject: [PATCH 089/122] corrections to BlockFace access (cherry picked from commit 7f468956f5bf4a0207f08d23b514927caec8a1a6) --- .../countercraft/movecraft/compat/v1_20/SignListener.java | 4 ++-- .../countercraft/movecraft/compat/v1_21/SignListener.java | 7 +++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/v1_20/src/main/java/net/countercraft/movecraft/compat/v1_20/SignListener.java b/v1_20/src/main/java/net/countercraft/movecraft/compat/v1_20/SignListener.java index c0dc6685c..59ea73196 100644 --- a/v1_20/src/main/java/net/countercraft/movecraft/compat/v1_20/SignListener.java +++ b/v1_20/src/main/java/net/countercraft/movecraft/compat/v1_20/SignListener.java @@ -35,7 +35,7 @@ protected final SignWrapper createFromSide(final Sign sign, final Side side) { } protected final SignWrapper createFromSide(final Sign sign, final SignSide signSide, Side side) { - BlockFace face = ((Directional) sign.getBlockData()).getFacing(); + BlockFace face = ((Directional) sign.getBlock().getBlockData()).getFacing(); if (side == Side.BACK) { face = face.getOppositeFace(); } @@ -65,7 +65,7 @@ public SignWrapper[] getSignWrappers(Sign sign, boolean ignoreEmpty) { @Override protected SignWrapper getSignWrapper(Sign sign, SignChangeEvent signChangeEvent) { @NotNull Side side = signChangeEvent.getSide(); - BlockFace face = ((Directional) sign.getBlockData()).getFacing(); + BlockFace face = ((Directional) sign.getBlock().getBlockData()).getFacing(); if (side == Side.BACK) { face = face.getOppositeFace(); } diff --git a/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/SignListener.java b/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/SignListener.java index 922caaf95..23707abc7 100644 --- a/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/SignListener.java +++ b/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/SignListener.java @@ -6,6 +6,8 @@ import net.countercraft.movecraft.MovecraftLocation; import net.countercraft.movecraft.craft.Craft; import net.countercraft.movecraft.events.SignTranslateEvent; +import net.countercraft.movecraft.processing.CachedMovecraftWorld; +import net.countercraft.movecraft.processing.MovecraftWorld; import net.countercraft.movecraft.sign.AbstractSignListener; import net.kyori.adventure.text.Component; import org.bukkit.Bukkit; @@ -14,6 +16,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.BlockState; import org.bukkit.block.Sign; +import org.bukkit.block.data.BlockData; import org.bukkit.block.data.Directional; import org.bukkit.block.sign.Side; import org.bukkit.block.sign.SignSide; @@ -35,7 +38,7 @@ protected final SignWrapper createFromSide(final Sign sign, final Side side) { } protected final SignWrapper createFromSide(final Sign sign, final SignSide signSide, Side side) { - BlockFace face = ((Directional) sign.getBlockData()).getFacing(); + BlockFace face = ((Directional) sign.getBlock().getBlockData()).getFacing(); if (side == Side.BACK) { face = face.getOppositeFace(); } @@ -65,7 +68,7 @@ public SignWrapper[] getSignWrappers(Sign sign, boolean ignoreEmpty) { @Override protected SignWrapper getSignWrapper(Sign sign, SignChangeEvent signChangeEvent) { @NotNull Side side = signChangeEvent.getSide(); - BlockFace face = ((Directional) sign.getBlockData()).getFacing(); + BlockFace face = ((Directional) sign.getBlock().getBlockData()).getFacing(); if (side == Side.BACK) { face = face.getOppositeFace(); } From 9b7ea60e82c573f749156f5ad910bfcc38380f24 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Thu, 5 Sep 2024 14:39:33 +0200 Subject: [PATCH 090/122] more fixes regarding getting the blockface of a sign... (cherry picked from commit d5ded2eddf9406148ff7452eb422c705cf06c96c) --- .../movecraft/compat/v1_18/SignListener.java | 24 ++++++++++++++-- .../movecraft/compat/v1_20/SignListener.java | 27 ++++++++++++++++-- .../movecraft/compat/v1_21/SignListener.java | 28 ++++++++++++++++--- 3 files changed, 71 insertions(+), 8 deletions(-) diff --git a/v1_18/src/main/java/net/countercraft/movecraft/compat/v1_18/SignListener.java b/v1_18/src/main/java/net/countercraft/movecraft/compat/v1_18/SignListener.java index 7f1e122a6..f6a4244ab 100644 --- a/v1_18/src/main/java/net/countercraft/movecraft/compat/v1_18/SignListener.java +++ b/v1_18/src/main/java/net/countercraft/movecraft/compat/v1_18/SignListener.java @@ -14,7 +14,9 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.BlockState; import org.bukkit.block.Sign; +import org.bukkit.block.data.BlockData; import org.bukkit.block.data.Directional; +import org.bukkit.block.data.Rotatable; import org.bukkit.event.block.SignChangeEvent; import org.bukkit.event.player.PlayerInteractEvent; @@ -27,7 +29,16 @@ public class SignListener extends AbstractSignListener { protected final SignWrapper createFromSign(final Sign sign) { - BlockFace face = ((Directional) sign.getBlockData()).getFacing(); + BlockData blockData = sign.getBlock().getBlockData(); + BlockFace face; + if (blockData instanceof Directional directional) { + face = directional.getFacing(); + } else if (blockData instanceof Rotatable rotatable) { + face = rotatable.getRotation(); + } + else { + face = BlockFace.SELF; + } SignWrapper wrapper = new SignWrapper( sign, sign::line, @@ -49,7 +60,16 @@ public SignWrapper[] getSignWrappers(Sign sign, boolean ignoreEmpty) { @Override protected SignWrapper getSignWrapper(Sign sign, SignChangeEvent signChangeEvent) { - BlockFace face = ((Directional) sign.getBlockData()).getFacing(); + BlockData blockData = sign.getBlock().getBlockData(); + BlockFace face; + if (blockData instanceof Directional directional) { + face = directional.getFacing(); + } else if (blockData instanceof Rotatable rotatable) { + face = rotatable.getRotation(); + } + else { + face = BlockFace.SELF; + } SignWrapper wrapper = new SignWrapper( sign, signChangeEvent::line, diff --git a/v1_20/src/main/java/net/countercraft/movecraft/compat/v1_20/SignListener.java b/v1_20/src/main/java/net/countercraft/movecraft/compat/v1_20/SignListener.java index 59ea73196..497a6ffa8 100644 --- a/v1_20/src/main/java/net/countercraft/movecraft/compat/v1_20/SignListener.java +++ b/v1_20/src/main/java/net/countercraft/movecraft/compat/v1_20/SignListener.java @@ -14,7 +14,9 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.BlockState; import org.bukkit.block.Sign; +import org.bukkit.block.data.BlockData; import org.bukkit.block.data.Directional; +import org.bukkit.block.data.Rotatable; import org.bukkit.block.sign.Side; import org.bukkit.block.sign.SignSide; import org.bukkit.event.block.SignChangeEvent; @@ -35,7 +37,17 @@ protected final SignWrapper createFromSide(final Sign sign, final Side side) { } protected final SignWrapper createFromSide(final Sign sign, final SignSide signSide, Side side) { - BlockFace face = ((Directional) sign.getBlock().getBlockData()).getFacing(); + BlockData blockData = sign.getBlock().getBlockData(); + BlockFace face; + if (blockData instanceof Directional directional) { + face = directional.getFacing(); + } else if (blockData instanceof Rotatable rotatable) { + face = rotatable.getRotation(); + } + else { + face = BlockFace.SELF; + } + if (side == Side.BACK) { face = face.getOppositeFace(); } @@ -65,7 +77,18 @@ public SignWrapper[] getSignWrappers(Sign sign, boolean ignoreEmpty) { @Override protected SignWrapper getSignWrapper(Sign sign, SignChangeEvent signChangeEvent) { @NotNull Side side = signChangeEvent.getSide(); - BlockFace face = ((Directional) sign.getBlock().getBlockData()).getFacing(); + + BlockData blockData = sign.getBlock().getBlockData(); + BlockFace face; + if (blockData instanceof Directional directional) { + face = directional.getFacing(); + } else if (blockData instanceof Rotatable rotatable) { + face = rotatable.getRotation(); + } + else { + face = BlockFace.SELF; + } + if (side == Side.BACK) { face = face.getOppositeFace(); } diff --git a/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/SignListener.java b/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/SignListener.java index 23707abc7..1c8621fe9 100644 --- a/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/SignListener.java +++ b/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/SignListener.java @@ -6,8 +6,6 @@ import net.countercraft.movecraft.MovecraftLocation; import net.countercraft.movecraft.craft.Craft; import net.countercraft.movecraft.events.SignTranslateEvent; -import net.countercraft.movecraft.processing.CachedMovecraftWorld; -import net.countercraft.movecraft.processing.MovecraftWorld; import net.countercraft.movecraft.sign.AbstractSignListener; import net.kyori.adventure.text.Component; import org.bukkit.Bukkit; @@ -18,6 +16,7 @@ import org.bukkit.block.Sign; import org.bukkit.block.data.BlockData; import org.bukkit.block.data.Directional; +import org.bukkit.block.data.Rotatable; import org.bukkit.block.sign.Side; import org.bukkit.block.sign.SignSide; import org.bukkit.event.block.SignChangeEvent; @@ -38,7 +37,17 @@ protected final SignWrapper createFromSide(final Sign sign, final Side side) { } protected final SignWrapper createFromSide(final Sign sign, final SignSide signSide, Side side) { - BlockFace face = ((Directional) sign.getBlock().getBlockData()).getFacing(); + BlockData blockData = sign.getBlock().getBlockData(); + BlockFace face; + if (blockData instanceof Directional directional) { + face = directional.getFacing(); + } else if (blockData instanceof Rotatable rotatable) { + face = rotatable.getRotation(); + } + else { + face = BlockFace.SELF; + } + if (side == Side.BACK) { face = face.getOppositeFace(); } @@ -68,7 +77,18 @@ public SignWrapper[] getSignWrappers(Sign sign, boolean ignoreEmpty) { @Override protected SignWrapper getSignWrapper(Sign sign, SignChangeEvent signChangeEvent) { @NotNull Side side = signChangeEvent.getSide(); - BlockFace face = ((Directional) sign.getBlock().getBlockData()).getFacing(); + + BlockData blockData = sign.getBlock().getBlockData(); + BlockFace face; + if (blockData instanceof Directional directional) { + face = directional.getFacing(); + } else if (blockData instanceof Rotatable rotatable) { + face = rotatable.getRotation(); + } + else { + face = BlockFace.SELF; + } + if (side == Side.BACK) { face = face.getOppositeFace(); } From 48a9bc14bd475fba803ce97d0ff123819e121ac1 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Thu, 5 Sep 2024 14:43:13 +0200 Subject: [PATCH 091/122] NPE prevention (cherry picked from commit aff2a1da968dde6f5d9d1a6c168405aa4688faf6) --- .../countercraft/movecraft/sign/AbstractSignListener.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java index db3008138..519e0148b 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java @@ -98,6 +98,12 @@ public boolean areSignsEqual(SignWrapper other) { } public static boolean areSignsEqual(SignWrapper a, SignWrapper b) { + if (a == b) { + return true; + } + if (a == null || b == null) { + return false; + } String[] aLines = a.rawLines(); String[] bLines = b.rawLines(); From ca35cd37e0eee5657da3652a9a35dffa7d270db7 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Thu, 5 Sep 2024 14:53:01 +0200 Subject: [PATCH 092/122] add TODO note (cherry picked from commit dc85f9df038c0b72a959c085fda6dbbff854b2d3) --- .../net/countercraft/movecraft/sign/AbstractInformationSign.java | 1 + 1 file changed, 1 insertion(+) diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractInformationSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractInformationSign.java index fed132cb3..4eef24d1e 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractInformationSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractInformationSign.java @@ -76,6 +76,7 @@ protected boolean isSignValid(Action clickType, AbstractSignListener.SignWrapper return true; } + // TODO: Add "reason" what to cancel, we might not want to cancel all edit events @Override public boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action type, boolean sneaking) { if (processingSuccessful) { From 464fcd672919c715de5492c26f195a7e31a1c857 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Thu, 5 Sep 2024 16:28:49 +0200 Subject: [PATCH 093/122] remove spaces from suffix --- .../net/countercraft/movecraft/sign/AbstractCruiseSign.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractCruiseSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractCruiseSign.java index 7cdc4be16..f249d0585 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractCruiseSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractCruiseSign.java @@ -48,7 +48,7 @@ protected boolean isSignValid(Action clickType, AbstractSignListener.SignWrapper if (headerSplit.length != 2) { return false; } - String suffix = headerSplit[1]; + String suffix = headerSplit[1].trim(); return suffix.equalsIgnoreCase(this.suffixOff) || suffix.equalsIgnoreCase(this.suffixOn); } @@ -70,7 +70,7 @@ protected boolean isOnOrOff(AbstractSignListener.SignWrapper sign) { if (headerSplit == null || headerSplit.length != 2) { return false; } - String suffix = headerSplit[1]; + String suffix = headerSplit[1].trim(); return suffix.equalsIgnoreCase(this.suffixOn); } From b65562e1f1a8e002c82588d02aa42284f7e09e7c Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Thu, 5 Sep 2024 16:35:56 +0200 Subject: [PATCH 094/122] correction => if the ident has trailing : => don't add them yourself again (cherry picked from commit a30780380579e77cf4b2cff5caf583cd24541477) --- .../countercraft/movecraft/sign/AbstractCruiseSign.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractCruiseSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractCruiseSign.java index f249d0585..fe4b38dcc 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractCruiseSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractCruiseSign.java @@ -24,6 +24,8 @@ public abstract class AbstractCruiseSign extends AbstractCraftSign { private final String suffixOn; private final String suffixOff; private final String ident; + private final Component headerOn = this.buildHeaderOn(); + private final Component headerOff = this.buildHeaderOff(); public AbstractCruiseSign(boolean ignoreCraftIsBusy, final String ident, final String suffixOn, final String suffixOff) { this(null, ignoreCraftIsBusy, ident, suffixOn, suffixOff); @@ -150,15 +152,15 @@ public void onCraftDetect(CraftDetectEvent event, AbstractSignListener.SignWrapp // Helper method to build the headline for on or off state protected Component buildHeader(boolean on) { - return on ? buildHeaderOn() : buildHeaderOff(); + return on ? this.headerOn : this.headerOff; } protected Component buildHeaderOn() { - return Component.text(this.ident).append(Component.text(": ")).append(Component.text(this.suffixOn, Style.style(TextColor.color(0, 255, 0)))); + return Component.text(this.ident).append(this.ident.endsWith(":") ? Component.empty() : Component.text(": ")).append(Component.text(this.suffixOn, Style.style(TextColor.color(0, 255, 0)))); } protected Component buildHeaderOff() { - return Component.text(this.ident).append(Component.text(": ")).append(Component.text(this.suffixOff, Style.style(TextColor.color(255, 0, 0)))); + return Component.text(this.ident).append(this.ident.endsWith(":") ? Component.empty() : Component.text(": ")).append(Component.text(this.suffixOff, Style.style(TextColor.color(255, 0, 0)))); } // Should call the craft's relevant methods to start cruising From 132f1796e7c4c23ae3622a8ca2ed3879d7a4958b Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Thu, 5 Sep 2024 16:46:27 +0200 Subject: [PATCH 095/122] startup correction --- .../countercraft/movecraft/sign/AbstractCruiseSign.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractCruiseSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractCruiseSign.java index fe4b38dcc..cfa89f122 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractCruiseSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractCruiseSign.java @@ -24,8 +24,8 @@ public abstract class AbstractCruiseSign extends AbstractCraftSign { private final String suffixOn; private final String suffixOff; private final String ident; - private final Component headerOn = this.buildHeaderOn(); - private final Component headerOff = this.buildHeaderOff(); + private final Component headerOn; + private final Component headerOff; public AbstractCruiseSign(boolean ignoreCraftIsBusy, final String ident, final String suffixOn, final String suffixOff) { this(null, ignoreCraftIsBusy, ident, suffixOn, suffixOff); @@ -36,6 +36,9 @@ public AbstractCruiseSign(final String permission, boolean ignoreCraftIsBusy, fi this.suffixOn = suffixOn; this.suffixOff = suffixOff; this.ident = ident; + + this.headerOn = this.buildHeaderOn(); + this.headerOff = this.buildHeaderOff(); } // Checks if the header is empty, if yes, it quits early (unnecessary actually as if it was empty this would never be called) From 5ff7af8109e4a5bb5a83ba328eaee781ec2b24c0 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Thu, 5 Sep 2024 16:52:37 +0200 Subject: [PATCH 096/122] forgot the space (cherry picked from commit ce7f379980b79ae21d7ae0220150d6cbc8f0cc63) (cherry picked from commit 719a1ec2842eddd3050301e7919aecd5523bba2b) --- .../net/countercraft/movecraft/sign/AbstractCruiseSign.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractCruiseSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractCruiseSign.java index cfa89f122..04a74669a 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractCruiseSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractCruiseSign.java @@ -159,11 +159,11 @@ protected Component buildHeader(boolean on) { } protected Component buildHeaderOn() { - return Component.text(this.ident).append(this.ident.endsWith(":") ? Component.empty() : Component.text(": ")).append(Component.text(this.suffixOn, Style.style(TextColor.color(0, 255, 0)))); + return Component.text(this.ident).append(this.ident.endsWith(":") ? Component.text(" ") : Component.text(": ")).append(Component.text(this.suffixOn, Style.style(TextColor.color(0, 255, 0)))); } protected Component buildHeaderOff() { - return Component.text(this.ident).append(this.ident.endsWith(":") ? Component.empty() : Component.text(": ")).append(Component.text(this.suffixOff, Style.style(TextColor.color(255, 0, 0)))); + return Component.text(this.ident).append(this.ident.endsWith(":") ? Component.text(" ") : Component.text(": ")).append(Component.text(this.suffixOff, Style.style(TextColor.color(255, 0, 0)))); } // Should call the craft's relevant methods to start cruising From 9fb19175278dfeaae045f7ddffa5683bd76d8f37 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Thu, 5 Sep 2024 17:03:17 +0200 Subject: [PATCH 097/122] avoid double inversion (cherry picked from commit 7075208e9884522a47669a74f1c07a7dcf2df6bb) --- .../main/java/net/countercraft/movecraft/sign/CruiseSign.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/CruiseSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/CruiseSign.java index 2ce7fbfec..142433e6a 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/CruiseSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/CruiseSign.java @@ -25,7 +25,8 @@ protected void setCraftCruising(Player player, CruiseDirection direction, Craft @Override protected CruiseDirection getCruiseDirection(AbstractSignListener.SignWrapper sign) { BlockFace face = sign.facing(); - face = face.getOppositeFace(); + // NOt necessary, CruiseDirection#fromBlockFace already handles this! + //face = face.getOppositeFace(); return CruiseDirection.fromBlockFace(face); } From e09c26d62c8920f629876b586c3a9b3767bfdcdb Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Thu, 5 Sep 2024 17:13:54 +0200 Subject: [PATCH 098/122] crafttype is specified in second, not the third line (cherry picked from commit 1aaf852c2eb6f25b3ffad1be8194a98651bedf96) (cherry picked from commit 956c8c5cad11007a2f93ed2ef8147179b82073b6) --- .../net/countercraft/movecraft/sign/AbstractSubcraftSign.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractSubcraftSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractSubcraftSign.java index cf9d40cb7..300bfc358 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractSubcraftSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractSubcraftSign.java @@ -41,7 +41,7 @@ public AbstractSubcraftSign(final String permission, Function Date: Thu, 5 Sep 2024 17:15:18 +0200 Subject: [PATCH 099/122] typo (cherry picked from commit d70b65b760b0aeb66f227e64c21628d034a043e3) (cherry picked from commit 8e1e7c7a9e5dfcfe3b0ff5ea364b6eba927d590d) --- .../net/countercraft/movecraft/sign/AbstractSubcraftSign.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractSubcraftSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractSubcraftSign.java index 300bfc358..81bdee52a 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractSubcraftSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractSubcraftSign.java @@ -41,7 +41,7 @@ public AbstractSubcraftSign(final String permission, Function Date: Thu, 5 Sep 2024 17:23:59 +0200 Subject: [PATCH 100/122] remote sign correction => don't use old list, use HashMap and use computeIfAbsent (cherry picked from commit e8896a240756651287140310e478120990fc00b8) --- .../movecraft/sign/RemoteSign.java | 30 ++++++++----------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/RemoteSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/RemoteSign.java index f847cc530..aa980bfba 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/RemoteSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/RemoteSign.java @@ -14,10 +14,7 @@ import org.bukkit.event.block.SignChangeEvent; import org.jetbrains.annotations.Nullable; -import java.util.Hashtable; -import java.util.LinkedList; -import java.util.Map; -import java.util.Optional; +import java.util.*; import static net.countercraft.movecraft.util.ChatUtils.ERROR_PREFIX; @@ -40,8 +37,7 @@ protected void onCraftNotFound(Player player, AbstractSignListener.SignWrapper s @Override protected boolean internalProcessSignWithCraft(Action clickType, AbstractSignListener.SignWrapper sign, Craft craft, Player player) { - LinkedList foundLocations = new LinkedList(); - Map> foundTargetSigns = new Hashtable<>(); + Map> foundTargetSigns = new HashMap<>(); boolean firstError = true; final String targetIdent = sign.getRaw(1).toUpperCase(); for (MovecraftLocation tloc : craft.getHitBox()) { @@ -62,19 +58,19 @@ protected boolean internalProcessSignWithCraft(Action clickType, AbstractSignLis if (!signHandler.isPresent() || signHandler.get() instanceof RemoteSign) { continue; } - // Forbidden strings - if (hasForbiddenString(wrapper)) { - if (firstError) { - player.sendMessage(I18nSupport.getInternationalisedString("Remote Sign - Forbidden string found")); - firstError = false; - } - player.sendMessage(" - ".concat(tloc.toString()).concat(" : ").concat(ts.getLine(0))); - } // But does it match the source man? if (matchesDescriptor(targetIdent, wrapper)) { - LinkedList value = foundTargetSigns.getOrDefault(signHandler.get(), new LinkedList<>()); - value.add(wrapper); - foundLocations.add(tloc); + // Forbidden strings + if (hasForbiddenString(wrapper)) { + if (firstError) { + player.sendMessage(I18nSupport.getInternationalisedString("Remote Sign - Forbidden string found")); + firstError = false; + } + player.sendMessage(" - ".concat(tloc.toString()).concat(" : ").concat(ts.getLine(0))); + } else { + LinkedList value = foundTargetSigns.computeIfAbsent(signHandler.get(), (a) -> new LinkedList<>()); + value.add(wrapper); + } } } } From 8e767627d25876273539aad9b667607c2940e0d2 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Fri, 6 Sep 2024 13:40:37 +0200 Subject: [PATCH 101/122] fix information signs not updating (cherry picked from commit e2bae7d68b6218fbfa317c9225eeb5dcb151b5f6) (cherry picked from commit 4eda66ffc66aad7f109347ee34d60a9d9ba125eb) --- .../movecraft/sign/AbstractSignListener.java | 18 ++++- .../movecraft/compat/v1_20/SignListener.java | 62 +++++++++-------- .../movecraft/compat/v1_21/SignListener.java | 66 ++++++++++++++----- 3 files changed, 98 insertions(+), 48 deletions(-) diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java index 519e0148b..3810dd048 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java @@ -97,7 +97,15 @@ public boolean areSignsEqual(SignWrapper other) { return areSignsEqual(this, other); } + public static boolean areSignsEqualIgnoreFace(SignWrapper a, SignWrapper b) { + return areSignsEqual(a, b, true); + } + public static boolean areSignsEqual(SignWrapper a, SignWrapper b) { + return areSignsEqual(a, b, false); + } + + public static boolean areSignsEqual(SignWrapper a, SignWrapper b, boolean ignoreFace) { if (a == b) { return true; } @@ -121,7 +129,7 @@ public static boolean areSignsEqual(SignWrapper a, SignWrapper b) { } // Now check the facing too! - return a.facing().equals(b.facing()); + return ignoreFace || a.facing().equals(b.facing()); } public static boolean areSignsEqual(SignWrapper[] a, SignWrapper[] b) { @@ -143,8 +151,12 @@ public static boolean areSignsEqual(SignWrapper[] a, SignWrapper[] b) { } public void copyContent(SignWrapper other) { - for (int i = 0; i < this.lines().size() && i < other.lines().size(); i++) { - this.line(i, other.line(i)); + this.copyContent(other::line, (i) -> i < other.lines().size()); + } + + public void copyContent(Function retrievalFunction, Function indexValidator) { + for (int i = 0; i < this.lines().size() && indexValidator.apply(i); i++) { + this.line(i, retrievalFunction.apply(i)); } } diff --git a/v1_20/src/main/java/net/countercraft/movecraft/compat/v1_20/SignListener.java b/v1_20/src/main/java/net/countercraft/movecraft/compat/v1_20/SignListener.java index 497a6ffa8..c2042cb4b 100644 --- a/v1_20/src/main/java/net/countercraft/movecraft/compat/v1_20/SignListener.java +++ b/v1_20/src/main/java/net/countercraft/movecraft/compat/v1_20/SignListener.java @@ -110,18 +110,20 @@ protected SignWrapper getSignWrapper(Sign sign, PlayerInteractEvent interactEven @Override public void processSignTranslation(Craft craft, boolean checkEventIsUpdated) { - Object2ObjectMap> signs = new Object2ObjectOpenCustomHashMap<>(new Hash.Strategy() { + // Ignore facing value here and directly store the associated wrappers in the list + Object2ObjectMap> signs = new Object2ObjectOpenCustomHashMap<>(new Hash.Strategy() { @Override public int hashCode(SignWrapper strings) { - return Arrays.hashCode(strings.rawLines()) * strings.facing().hashCode(); + return Arrays.hashCode(strings.rawLines()); } @Override public boolean equals(SignWrapper a, SignWrapper b) { - return SignWrapper.areSignsEqual(a, b); + return SignWrapper.areSignsEqualIgnoreFace(a, b); } }); - Map signStates = new HashMap<>(); + // Remember the locations for the event! + Map> wrapperToLocs = new HashMap<>(); for (MovecraftLocation location : craft.getHitBox()) { Block block = location.toBukkit(craft.getWorld()).getBlock(); @@ -136,45 +138,49 @@ public boolean equals(SignWrapper a, SignWrapper b) { continue; } for (SignWrapper wrapper : wrappersAtLoc) { - List values = signs.computeIfAbsent(wrapper, (w) -> new ArrayList<>()); - values.add(location); + List values = signs.computeIfAbsent(wrapper, (w) -> new ArrayList<>()); + values.add(wrapper); + wrapperToLocs.computeIfAbsent(wrapper, (w) -> new ArrayList<>()).add(location); } - signStates.put(location, wrappersAtLoc); } } - for(Map.Entry> entry : signs.entrySet()){ + Set keySet = new HashSet<>(); + for(Map.Entry> entry : signs.entrySet()){ final List components = new ArrayList<>(entry.getKey().lines()); SignWrapper backingForEvent = new SignWrapper(null, components::get, components, components::set, entry.getKey().facing()); - SignTranslateEvent event = new SignTranslateEvent(craft, backingForEvent, entry.getValue()); + SignTranslateEvent event = new SignTranslateEvent(craft, backingForEvent, wrapperToLocs.getOrDefault(entry.getKey(), new ArrayList<>())); Bukkit.getServer().getPluginManager().callEvent(event); // if(!event.isUpdated()){ // continue; // } // TODO: This is implemented only to fix client caching // ideally we wouldn't do the update and would instead fake it out to the player - for(MovecraftLocation location : entry.getValue()){ - Block block = location.toBukkit(craft.getWorld()).getBlock(); + + System.out.println("New lines: "); + for (String s : event.rawLines()) { + System.out.println(" - " + s); + } + System.out.println("Old lines: "); + for (String s : entry.getKey().rawLines()) { + System.out.println(" - " + s); + } + // Values get changed definitely, but perhaps it does not get applied to the sign after all? + for(SignWrapper wrapperTmp : entry.getValue()){ + if (!checkEventIsUpdated || event.isUpdated()) { + wrapperTmp.copyContent(event::line, (i) -> i < event.lines().size()); + keySet.add(entry.getKey()); + } + } + } + + for (SignWrapper wrapperTmp : keySet) { + for (MovecraftLocation mLoc : wrapperToLocs.getOrDefault(wrapperTmp, new ArrayList<>())) { + Block block = mLoc.toBukkit(craft.getWorld()).getBlock(); BlockState state = block.getState(); if (!(state instanceof Sign)) { continue; } - SignWrapper[] signsAtLoc = signStates.get(location); - if (signsAtLoc != null && signsAtLoc.length > 0) { - for (SignWrapper sw : signsAtLoc) { - // Important: Check if the wrapper faces the right way! - if (!sw.facing().equals(entry.getKey().facing())) { - continue; - } - if (!checkEventIsUpdated || event.isUpdated()) { - sw.copyContent(entry.getKey()); - } - } - try { - ((Sign)location.toBukkit(craft.getWorld()).getBlock()).update(false, false); - } catch(ClassCastException ex) { - // Ignore - } - } + ((Sign)block).update(false, false); } } } diff --git a/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/SignListener.java b/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/SignListener.java index 1c8621fe9..356d77eda 100644 --- a/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/SignListener.java +++ b/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/SignListener.java @@ -110,18 +110,20 @@ protected SignWrapper getSignWrapper(Sign sign, PlayerInteractEvent interactEven @Override public void processSignTranslation(Craft craft, boolean checkEventIsUpdated) { - Object2ObjectMap> signs = new Object2ObjectOpenCustomHashMap<>(new Hash.Strategy() { + // Ignore facing value here and directly store the associated wrappers in the list + Object2ObjectMap> signs = new Object2ObjectOpenCustomHashMap<>(new Hash.Strategy() { @Override public int hashCode(SignWrapper strings) { - return Arrays.hashCode(strings.rawLines()) * strings.facing().hashCode(); + return Arrays.hashCode(strings.rawLines()); } @Override public boolean equals(SignWrapper a, SignWrapper b) { - return SignWrapper.areSignsEqual(a, b); + return SignWrapper.areSignsEqualIgnoreFace(a, b); } }); - Map signStates = new HashMap<>(); + // Remember the locations for the event! + Map> wrapperToLocs = new HashMap<>(); for (MovecraftLocation location : craft.getHitBox()) { Block block = location.toBukkit(craft.getWorld()).getBlock(); @@ -136,45 +138,75 @@ public boolean equals(SignWrapper a, SignWrapper b) { continue; } for (SignWrapper wrapper : wrappersAtLoc) { - List values = signs.computeIfAbsent(wrapper, (w) -> new ArrayList<>()); - values.add(location); + List values = signs.computeIfAbsent(wrapper, (w) -> new ArrayList<>()); + values.add(wrapper); + wrapperToLocs.computeIfAbsent(wrapper, (w) -> new ArrayList<>()).add(location); } - signStates.put(location, wrappersAtLoc); } } - for(Map.Entry> entry : signs.entrySet()){ + Set keySet = new HashSet<>(); + for(Map.Entry> entry : signs.entrySet()){ final List components = new ArrayList<>(entry.getKey().lines()); SignWrapper backingForEvent = new SignWrapper(null, components::get, components, components::set, entry.getKey().facing()); - SignTranslateEvent event = new SignTranslateEvent(craft, backingForEvent, entry.getValue()); + SignTranslateEvent event = new SignTranslateEvent(craft, backingForEvent, wrapperToLocs.getOrDefault(entry.getKey(), new ArrayList<>())); Bukkit.getServer().getPluginManager().callEvent(event); // if(!event.isUpdated()){ // continue; // } // TODO: This is implemented only to fix client caching // ideally we wouldn't do the update and would instead fake it out to the player - for(MovecraftLocation location : entry.getValue()){ - Block block = location.toBukkit(craft.getWorld()).getBlock(); + + System.out.println("New lines: "); + for (String s : event.rawLines()) { + System.out.println(" - " + s); + } + System.out.println("Old lines: "); + for (String s : entry.getKey().rawLines()) { + System.out.println(" - " + s); + } + // Values get changed definitely, but perhaps it does not get applied to the sign after all? + for(SignWrapper wrapperTmp : entry.getValue()){ + /*Block block = location.toBukkit(craft.getWorld()).getBlock(); BlockState state = block.getState(); if (!(state instanceof Sign)) { continue; } SignWrapper[] signsAtLoc = signStates.get(location); if (signsAtLoc != null && signsAtLoc.length > 0) { + boolean hadCorrectSide = false; for (SignWrapper sw : signsAtLoc) { // Important: Check if the wrapper faces the right way! - if (!sw.facing().equals(entry.getKey().facing())) { + if (!sw.facing().equals(event.facing())) { continue; } + hadCorrectSide = true; if (!checkEventIsUpdated || event.isUpdated()) { - sw.copyContent(entry.getKey()); + sw.copyContent(event::line, (i) -> i < event.lines().size()); } } - try { - ((Sign)location.toBukkit(craft.getWorld()).getBlock()).update(false, false); - } catch(ClassCastException ex) { - // Ignore + if (hadCorrectSide) { + try { + ((Sign)location.toBukkit(craft.getWorld()).getBlock()).update(false, false); + } catch(ClassCastException ex) { + // Ignore + } } + }*/ + if (!checkEventIsUpdated || event.isUpdated()) { + wrapperTmp.copyContent(event::line, (i) -> i < event.lines().size()); + keySet.add(entry.getKey()); + } + } + } + + for (SignWrapper wrapperTmp : keySet) { + for (MovecraftLocation mLoc : wrapperToLocs.getOrDefault(wrapperTmp, new ArrayList<>())) { + Block block = mLoc.toBukkit(craft.getWorld()).getBlock(); + BlockState state = block.getState(); + if (!(state instanceof Sign)) { + continue; } + ((Sign)block).update(false, false); } } } From d86b510a94f444107b3945a4e6233e5d86c9f976 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Fri, 6 Sep 2024 13:42:49 +0200 Subject: [PATCH 102/122] comment out debug logs --- .../countercraft/movecraft/compat/v1_20/SignListener.java | 8 -------- .../countercraft/movecraft/compat/v1_21/SignListener.java | 4 ++-- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/v1_20/src/main/java/net/countercraft/movecraft/compat/v1_20/SignListener.java b/v1_20/src/main/java/net/countercraft/movecraft/compat/v1_20/SignListener.java index c2042cb4b..afe255d25 100644 --- a/v1_20/src/main/java/net/countercraft/movecraft/compat/v1_20/SignListener.java +++ b/v1_20/src/main/java/net/countercraft/movecraft/compat/v1_20/SignListener.java @@ -156,14 +156,6 @@ public boolean equals(SignWrapper a, SignWrapper b) { // TODO: This is implemented only to fix client caching // ideally we wouldn't do the update and would instead fake it out to the player - System.out.println("New lines: "); - for (String s : event.rawLines()) { - System.out.println(" - " + s); - } - System.out.println("Old lines: "); - for (String s : entry.getKey().rawLines()) { - System.out.println(" - " + s); - } // Values get changed definitely, but perhaps it does not get applied to the sign after all? for(SignWrapper wrapperTmp : entry.getValue()){ if (!checkEventIsUpdated || event.isUpdated()) { diff --git a/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/SignListener.java b/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/SignListener.java index 356d77eda..219ac408d 100644 --- a/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/SignListener.java +++ b/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/SignListener.java @@ -156,14 +156,14 @@ public boolean equals(SignWrapper a, SignWrapper b) { // TODO: This is implemented only to fix client caching // ideally we wouldn't do the update and would instead fake it out to the player - System.out.println("New lines: "); + /*System.out.println("New lines: "); for (String s : event.rawLines()) { System.out.println(" - " + s); } System.out.println("Old lines: "); for (String s : entry.getKey().rawLines()) { System.out.println(" - " + s); - } + }*/ // Values get changed definitely, but perhaps it does not get applied to the sign after all? for(SignWrapper wrapperTmp : entry.getValue()){ /*Block block = location.toBukkit(craft.getWorld()).getBlock(); From 5ac3fc67b0e4967a2f94566b2418fa8195902f03 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Fri, 6 Sep 2024 13:58:23 +0200 Subject: [PATCH 103/122] call update on the state, not on the block... (cherry picked from commit 3194ed75a540aa79f7b7c531dcd4e6abfe099202) (cherry picked from commit 19e2171c313e9904b301781bf07e45c876841136) --- .../countercraft/movecraft/compat/v1_18/SignListener.java | 2 +- .../countercraft/movecraft/compat/v1_20/SignListener.java | 2 +- .../countercraft/movecraft/compat/v1_21/SignListener.java | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/v1_18/src/main/java/net/countercraft/movecraft/compat/v1_18/SignListener.java b/v1_18/src/main/java/net/countercraft/movecraft/compat/v1_18/SignListener.java index f6a4244ab..c20f5bd4d 100644 --- a/v1_18/src/main/java/net/countercraft/movecraft/compat/v1_18/SignListener.java +++ b/v1_18/src/main/java/net/countercraft/movecraft/compat/v1_18/SignListener.java @@ -144,7 +144,7 @@ public boolean equals(SignWrapper a, SignWrapper b) { } } try { - ((Sign)location.toBukkit(craft.getWorld()).getBlock()).update(false, false); + ((Sign)location.toBukkit(craft.getWorld()).getBlock().getState()).update(false, false); } catch(ClassCastException ex) { // Ignore } diff --git a/v1_20/src/main/java/net/countercraft/movecraft/compat/v1_20/SignListener.java b/v1_20/src/main/java/net/countercraft/movecraft/compat/v1_20/SignListener.java index afe255d25..b8d945fac 100644 --- a/v1_20/src/main/java/net/countercraft/movecraft/compat/v1_20/SignListener.java +++ b/v1_20/src/main/java/net/countercraft/movecraft/compat/v1_20/SignListener.java @@ -172,7 +172,7 @@ public boolean equals(SignWrapper a, SignWrapper b) { if (!(state instanceof Sign)) { continue; } - ((Sign)block).update(false, false); + ((Sign)state).update(false, false); } } } diff --git a/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/SignListener.java b/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/SignListener.java index 219ac408d..3bc1b77c7 100644 --- a/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/SignListener.java +++ b/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/SignListener.java @@ -156,14 +156,14 @@ public boolean equals(SignWrapper a, SignWrapper b) { // TODO: This is implemented only to fix client caching // ideally we wouldn't do the update and would instead fake it out to the player - /*System.out.println("New lines: "); + System.out.println("New lines: "); for (String s : event.rawLines()) { System.out.println(" - " + s); } System.out.println("Old lines: "); for (String s : entry.getKey().rawLines()) { System.out.println(" - " + s); - }*/ + } // Values get changed definitely, but perhaps it does not get applied to the sign after all? for(SignWrapper wrapperTmp : entry.getValue()){ /*Block block = location.toBukkit(craft.getWorld()).getBlock(); @@ -206,7 +206,7 @@ public boolean equals(SignWrapper a, SignWrapper b) { if (!(state instanceof Sign)) { continue; } - ((Sign)block).update(false, false); + ((Sign)state).update(false, false); } } } From 7bf7297fe9a42fea3a33dad91d7d69f88fe72f7a Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Fri, 6 Sep 2024 14:16:41 +0200 Subject: [PATCH 104/122] more elegant solution (cherry picked from commit 2df03851c8d4b4e4f07651064306ff511d1b9513) (cherry picked from commit 6d8b47a235c5df04a2c7461e571f6c09ae7005e4) --- .../movecraft/compat/v1_18/SignListener.java | 5 +- .../movecraft/compat/v1_20/SignListener.java | 51 +++++++++++++++---- .../movecraft/compat/v1_21/SignListener.java | 21 +++----- 3 files changed, 51 insertions(+), 26 deletions(-) diff --git a/v1_18/src/main/java/net/countercraft/movecraft/compat/v1_18/SignListener.java b/v1_18/src/main/java/net/countercraft/movecraft/compat/v1_18/SignListener.java index c20f5bd4d..170619320 100644 --- a/v1_18/src/main/java/net/countercraft/movecraft/compat/v1_18/SignListener.java +++ b/v1_18/src/main/java/net/countercraft/movecraft/compat/v1_18/SignListener.java @@ -141,13 +141,14 @@ public boolean equals(SignWrapper a, SignWrapper b) { for (SignWrapper sw : signsAtLoc) { if (!checkEventIsUpdated || event.isUpdated()) { sw.copyContent(entry.getKey()); + sw.block().update(false, false); } } - try { + /*try { ((Sign)location.toBukkit(craft.getWorld()).getBlock().getState()).update(false, false); } catch(ClassCastException ex) { // Ignore - } + }*/ } } } diff --git a/v1_20/src/main/java/net/countercraft/movecraft/compat/v1_20/SignListener.java b/v1_20/src/main/java/net/countercraft/movecraft/compat/v1_20/SignListener.java index b8d945fac..483b44baf 100644 --- a/v1_20/src/main/java/net/countercraft/movecraft/compat/v1_20/SignListener.java +++ b/v1_20/src/main/java/net/countercraft/movecraft/compat/v1_20/SignListener.java @@ -144,7 +144,7 @@ public boolean equals(SignWrapper a, SignWrapper b) { } } } - Set keySet = new HashSet<>(); + Set signsToUpdate = new HashSet<>(); for(Map.Entry> entry : signs.entrySet()){ final List components = new ArrayList<>(entry.getKey().lines()); SignWrapper backingForEvent = new SignWrapper(null, components::get, components, components::set, entry.getKey().facing()); @@ -156,24 +156,53 @@ public boolean equals(SignWrapper a, SignWrapper b) { // TODO: This is implemented only to fix client caching // ideally we wouldn't do the update and would instead fake it out to the player + /*System.out.println("New lines: "); + for (String s : event.rawLines()) { + System.out.println(" - " + s); + } + System.out.println("Old lines: "); + for (String s : entry.getKey().rawLines()) { + System.out.println(" - " + s); + }*/ // Values get changed definitely, but perhaps it does not get applied to the sign after all? for(SignWrapper wrapperTmp : entry.getValue()){ + /*Block block = location.toBukkit(craft.getWorld()).getBlock(); + BlockState state = block.getState(); + if (!(state instanceof Sign)) { + continue; + } + SignWrapper[] signsAtLoc = signStates.get(location); + if (signsAtLoc != null && signsAtLoc.length > 0) { + boolean hadCorrectSide = false; + for (SignWrapper sw : signsAtLoc) { + // Important: Check if the wrapper faces the right way! + if (!sw.facing().equals(event.facing())) { + continue; + } + hadCorrectSide = true; + if (!checkEventIsUpdated || event.isUpdated()) { + sw.copyContent(event::line, (i) -> i < event.lines().size()); + } + } + if (hadCorrectSide) { + try { + ((Sign)location.toBukkit(craft.getWorld()).getBlock()).update(false, false); + } catch(ClassCastException ex) { + // Ignore + } + } + }*/ if (!checkEventIsUpdated || event.isUpdated()) { wrapperTmp.copyContent(event::line, (i) -> i < event.lines().size()); - keySet.add(entry.getKey()); + if (wrapperTmp.block() != null) { + signsToUpdate.add(wrapperTmp.block()); + } } } } - for (SignWrapper wrapperTmp : keySet) { - for (MovecraftLocation mLoc : wrapperToLocs.getOrDefault(wrapperTmp, new ArrayList<>())) { - Block block = mLoc.toBukkit(craft.getWorld()).getBlock(); - BlockState state = block.getState(); - if (!(state instanceof Sign)) { - continue; - } - ((Sign)state).update(false, false); - } + for (Sign sign : signsToUpdate) { + sign.update(false, false); } } } diff --git a/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/SignListener.java b/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/SignListener.java index 3bc1b77c7..0b6eb9d0d 100644 --- a/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/SignListener.java +++ b/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/SignListener.java @@ -144,7 +144,7 @@ public boolean equals(SignWrapper a, SignWrapper b) { } } } - Set keySet = new HashSet<>(); + Set signsToUpdate = new HashSet<>(); for(Map.Entry> entry : signs.entrySet()){ final List components = new ArrayList<>(entry.getKey().lines()); SignWrapper backingForEvent = new SignWrapper(null, components::get, components, components::set, entry.getKey().facing()); @@ -156,14 +156,14 @@ public boolean equals(SignWrapper a, SignWrapper b) { // TODO: This is implemented only to fix client caching // ideally we wouldn't do the update and would instead fake it out to the player - System.out.println("New lines: "); + /*System.out.println("New lines: "); for (String s : event.rawLines()) { System.out.println(" - " + s); } System.out.println("Old lines: "); for (String s : entry.getKey().rawLines()) { System.out.println(" - " + s); - } + }*/ // Values get changed definitely, but perhaps it does not get applied to the sign after all? for(SignWrapper wrapperTmp : entry.getValue()){ /*Block block = location.toBukkit(craft.getWorld()).getBlock(); @@ -194,20 +194,15 @@ public boolean equals(SignWrapper a, SignWrapper b) { }*/ if (!checkEventIsUpdated || event.isUpdated()) { wrapperTmp.copyContent(event::line, (i) -> i < event.lines().size()); - keySet.add(entry.getKey()); + if (wrapperTmp.block() != null) { + signsToUpdate.add(wrapperTmp.block()); + } } } } - for (SignWrapper wrapperTmp : keySet) { - for (MovecraftLocation mLoc : wrapperToLocs.getOrDefault(wrapperTmp, new ArrayList<>())) { - Block block = mLoc.toBukkit(craft.getWorld()).getBlock(); - BlockState state = block.getState(); - if (!(state instanceof Sign)) { - continue; - } - ((Sign)state).update(false, false); - } + for (Sign sign : signsToUpdate) { + sign.update(false, false); } } } From 01788657cb58b0f423e52c03ec3834d8cdff79ee Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Fri, 6 Sep 2024 14:28:07 +0200 Subject: [PATCH 105/122] actually perform the update, event uses the signwrapper under the hood too (cherry picked from commit 039756d0e87a744988e41118581e50fd04da5416) --- .../movecraft/features/contacts/ContactsSign.java | 6 ++++++ .../countercraft/movecraft/features/status/StatusSign.java | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/features/contacts/ContactsSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/features/contacts/ContactsSign.java index a88978759..ce86818c4 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/features/contacts/ContactsSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/features/contacts/ContactsSign.java @@ -84,6 +84,12 @@ protected boolean internalProcessSignWithCraft(Action clickType, AbstractSignLis @Override protected void performUpdate(Component[] newComponents, AbstractSignListener.SignWrapper sign, REFRESH_CAUSE refreshCause) { + for (int i = 0; i < newComponents.length; i++) { + Component newComp = newComponents[i]; + if (newComp != null) { + sign.line(i, newComp); + } + } if (refreshCause != REFRESH_CAUSE.SIGN_MOVED_BY_CRAFT && sign.block() != null) { sign.block().update(); } diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java index 074cb998a..78329594e 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java @@ -171,6 +171,12 @@ protected void calcdisplayComponents(@Nullable Craft craft) { @Override protected void performUpdate(Component[] newComponents, AbstractSignListener.SignWrapper sign, REFRESH_CAUSE refreshCause) { + for (int i = 0; i < newComponents.length; i++) { + Component newComp = newComponents[i]; + if (newComp != null) { + sign.line(i, newComp); + } + } if (refreshCause != REFRESH_CAUSE.SIGN_MOVED_BY_CRAFT && sign.block() != null) { sign.block().update(true); } From 9da541bd94ed9d215935e89881160d39a3c72f3d Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Fri, 6 Sep 2024 18:19:38 +0200 Subject: [PATCH 106/122] fix status sign (reimplement based on @Vaan1310 changes) (cherry picked from commit 956053d43a647cf7c0e4b4ee75a96307d7606720) --- .../movecraft/features/status/StatusSign.java | 92 +++++++------------ 1 file changed, 34 insertions(+), 58 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java index 78329594e..7a7bb5850 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java @@ -1,7 +1,5 @@ package net.countercraft.movecraft.features.status; -import it.unimi.dsi.fastutil.objects.Object2IntMap; -import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import it.unimi.dsi.fastutil.objects.ObjectArrayList; import net.countercraft.movecraft.craft.Craft; import net.countercraft.movecraft.craft.type.CraftType; @@ -21,10 +19,7 @@ // TODO: Split this into multiple signs? Separate sign for fuel would make sense public class StatusSign extends AbstractInformationSign { - Object2IntMap displayBlocks = new Object2IntOpenHashMap<>(); List displayComponents = new ObjectArrayList<>(); - int totalNonNegligibleBlocks = 0; - int totalNonNegligibleWaterBlocks = 0; protected static final int FUEL_LINE_INDEX = 3; protected static final int BLOCK_LINE_INDEX_TOP = 1; @@ -59,6 +54,7 @@ protected Component calcFuel(Craft craft) { style = STYLE_COLOR_RED; } + // TODO: Shorten for large numbers, or trim the number (e.g. 10k instead of 10.000) return Component.text("Fuel range: " + fuelRange).style(style); } @@ -70,21 +66,18 @@ protected Component calcFuel(Craft craft) { @Override protected boolean refreshSign(@Nullable Craft craft, AbstractSignListener.SignWrapper sign, boolean fillDefault, REFRESH_CAUSE refreshCause) { // Calculate blocks and store them temporary, not pretty but works! - calcDisplayBlocks(craft); calcdisplayComponents(craft); + // Access violation prevention + while(displayComponents.size() < 2) { + displayComponents.add(EMPTY); + } return super.refreshSign(craft, sign, fillDefault, refreshCause); } - protected void calcDisplayBlocks(@Nullable Craft craft) { - displayBlocks.clear(); + protected void calcdisplayComponents(@Nullable Craft craft) { displayComponents.clear(); - - if (craft == null) { - return; - } - - totalNonNegligibleBlocks = 0; - totalNonNegligibleWaterBlocks = 0; + int totalNonNegligibleBlocks = 0; + int totalNonNegligibleWaterBlocks = 0; Counter materials = craft.getDataTag(Craft.MATERIALS); if (materials.isEmpty()) { return; @@ -100,37 +93,15 @@ protected void calcDisplayBlocks(@Nullable Craft craft) { } } - Counter displayBlocksTmp = new Counter<>(); - displayBlocksTmp.add(craft.getDataTag(Craft.FLYBLOCKS)); - displayBlocksTmp.add(craft.getDataTag(Craft.MOVEBLOCKS)); - - for (RequiredBlockEntry entry : displayBlocksTmp.getKeySet()) { - // TODO: Sure? - if (entry.getMin() == 0.0) { - continue; - } - double pctPresent = (displayBlocksTmp.get(entry) * 100D); - // TODO: WTF? Why? - if (craft.getType().getBoolProperty(CraftType.BLOCKED_BY_WATER)) { - pctPresent /= totalNonNegligibleBlocks; - } else { - pctPresent /= totalNonNegligibleWaterBlocks; - } - displayBlocks.putIfAbsent(entry, (int) pctPresent); - } - } - - protected void calcdisplayComponents(@Nullable Craft craft) { - displayComponents.add(EMPTY); - displayComponents.add(EMPTY); + Counter displayBlocks = new Counter<>(); + // TODO: Extend to allow definition of tags in craft file + displayBlocks.add(craft.getDataTag(Craft.FLYBLOCKS)); + displayBlocks.add(craft.getDataTag(Craft.MOVEBLOCKS)); - if (craft == null) { - return; - } - - int signLine = 0; + // TODO: Refactor loop into own method + int signLine = 1; int signColumn = 0; - for (RequiredBlockEntry entry : displayBlocks.keySet()) { + for (RequiredBlockEntry entry : displayBlocks.getKeySet()) { if (entry.getMin() == 0.0) { continue; } @@ -140,29 +111,34 @@ protected void calcdisplayComponents(@Nullable Craft craft) { } else { percentPresent /= totalNonNegligibleWaterBlocks; } - Component signText = EMPTY; + + String text = ""; + if (entry.getName() == null) { + text += entry.materialsToString().toUpperCase().charAt(0); + } else { + text += entry.getName().toUpperCase().charAt(0); + } + text += " "; + text += (int) percentPresent; + text += "/"; + text += (int) entry.getMin(); + Style style; if (percentPresent > entry.getMin() * 1.04) { style = STYLE_COLOR_GREEN; } else if (percentPresent > entry.getMin() * 1.02) { style = STYLE_COLOR_YELLOW; } else { - style = STYLE_COLOR_RED; - } - if (entry.getName() == null) { - signText = Component.text(entry.materialsToString().toUpperCase().charAt(0)); - } else { - signText = Component.text(entry.getName().toUpperCase().charAt(0)); + style = STYLE_COLOR_YELLOW; } - signText = signText.append(Component.text(" " + (int)percentPresent + "/" + (int)entry.getMin() + " ")); - signText = signText.style(style); + Component signText = Component.text(text).style(style); if (signColumn == 0) { - displayComponents.set(signLine, signText); + displayComponents.add(signText); signColumn++; - } else if (signLine < 2) { - Component existingLine = displayComponents.get(signLine); - existingLine = existingLine.append(signText); - displayComponents.set(signLine, existingLine); + } else if (signLine < 3) { + Component existingLine = displayComponents.get(signLine - 1); + existingLine = existingLine.append(Component.text(" ")).append(signText); + displayComponents.set((signLine - 1), existingLine); signLine++; signColumn = 0; } From 26d149723a7798ab07bc3856ad3936dc7006dc29 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Sat, 7 Sep 2024 00:07:08 +0200 Subject: [PATCH 107/122] NPE prevention (cherry picked from commit 9a40431e37966b32f0d7aabece45b716176d92d0) --- .../countercraft/movecraft/features/status/StatusSign.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java index 7a7bb5850..dd1d9d32b 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java @@ -76,6 +76,11 @@ protected boolean refreshSign(@Nullable Craft craft, AbstractSignListener.SignWr protected void calcdisplayComponents(@Nullable Craft craft) { displayComponents.clear(); + + if (craft == null) { + return; + } + int totalNonNegligibleBlocks = 0; int totalNonNegligibleWaterBlocks = 0; Counter materials = craft.getDataTag(Craft.MATERIALS); From 115349841f2ae1372129157181297b926bf253f6 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Sat, 7 Sep 2024 00:53:09 +0200 Subject: [PATCH 108/122] remove unnecessary toUpperCase() (cherry picked from commit 232ab10bc991e87346ac06262e70825aa8848026) --- .../net/countercraft/movecraft/sign/SubcraftRotateSign.java | 2 +- .../net/countercraft/movecraft/sign/AbstractSubcraftSign.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/SubcraftRotateSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/SubcraftRotateSign.java index 628f4bb23..8bc79776d 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/SubcraftRotateSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/SubcraftRotateSign.java @@ -74,7 +74,7 @@ public void run() { @Override protected boolean isActionAllowed(String action) { - return action.toUpperCase().equalsIgnoreCase("ROTATE"); + return action.equalsIgnoreCase("ROTATE"); } @Override diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractSubcraftSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractSubcraftSign.java index 81bdee52a..155694262 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractSubcraftSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractSubcraftSign.java @@ -88,7 +88,7 @@ protected boolean isSignValid(Action clickType, AbstractSignListener.SignWrapper return false; } // TODO: Change to enums? - String action = headerSplit[headerSplit.length - 1].toUpperCase(); + String action = headerSplit[headerSplit.length - 1]; if (!this.isActionAllowed(action)) { return false; } From 731aae745e50e3e6cd6030f89486edaa57fb9b26 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Sat, 7 Sep 2024 00:55:16 +0200 Subject: [PATCH 109/122] add eventtype enum (to api classes) (cherry picked from commit 91ff87275ef33faaba3d00f7c3ac04ef493d1331) --- .../movecraft/sign/AbstractCruiseSign.java | 2 +- .../sign/AbstractInformationSign.java | 2 +- .../movecraft/sign/AbstractMovecraftSign.java | 20 ++++++++++++++++++- .../movecraft/sign/AbstractSubcraftSign.java | 2 +- 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractCruiseSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractCruiseSign.java index 04a74669a..e474e419c 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractCruiseSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractCruiseSign.java @@ -81,7 +81,7 @@ protected boolean isOnOrOff(AbstractSignListener.SignWrapper sign) { // By default, cancel the event if the processing was successful, or the invoker was not sneaking => Allows breaking signs while sneaking @Override - public boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action type, boolean sneaking) { + public boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action type, boolean sneaking, EventType eventType) { return processingSuccessful || !sneaking; } diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractInformationSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractInformationSign.java index 4eef24d1e..2136377e1 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractInformationSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractInformationSign.java @@ -78,7 +78,7 @@ protected boolean isSignValid(Action clickType, AbstractSignListener.SignWrapper // TODO: Add "reason" what to cancel, we might not want to cancel all edit events @Override - public boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action type, boolean sneaking) { + public boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action type, boolean sneaking, EventType eventType) { if (processingSuccessful) { return true; } diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java index 516ee6afa..c30697c6e 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java @@ -140,10 +140,28 @@ protected Craft getCraft(AbstractSignListener.SignWrapper sign) { return MathUtils.getCraftByPersistentBlockData(sign.block().getLocation()); } + public enum EventType { + SIGN_CREATION, + SIGN_EDIT, + SIGN_EDIT_ON_CRAFT(true), + SIGN_CLICK, + SIGN_CLICK_ON_CRAFT(true); + + private boolean onCraft; + + EventType() { + this(false); + } + + EventType(boolean onCraft) { + this.onCraft = onCraft; + } + } + // Used by the event handler to determine if the event should be cancelled // processingSuccessful is the output of processSignClick() or processSignChange() // This is only called for the PlayerInteractEvent and the SignChangeEvent - public abstract boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action type, boolean sneaking); + public abstract boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action type, boolean sneaking, EventType eventType); // Validation method, called by default in processSignClick // If false is returned, nothing will be processed diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractSubcraftSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractSubcraftSign.java index 155694262..0202941bb 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractSubcraftSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractSubcraftSign.java @@ -71,7 +71,7 @@ protected boolean internalProcessSign(Action clickType, AbstractSignListener.Sig } @Override - public boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action type, boolean sneaking) { + public boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action type, boolean sneaking, EventType eventType) { return processingSuccessful || !sneaking; } From baad4f821d316745fc49de07d67083b36bc1c7ed Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Sat, 7 Sep 2024 00:55:54 +0200 Subject: [PATCH 110/122] refactor for eventtype enum (implementations) (cherry picked from commit 3f8dfdb4710618473a56cac1052ef4041dc249a5) --- .../src/main/java/net/countercraft/movecraft/sign/HelmSign.java | 2 +- .../src/main/java/net/countercraft/movecraft/sign/MoveSign.java | 2 +- .../src/main/java/net/countercraft/movecraft/sign/NameSign.java | 2 +- .../main/java/net/countercraft/movecraft/sign/PilotSign.java | 2 +- .../main/java/net/countercraft/movecraft/sign/RemoteSign.java | 2 +- .../main/java/net/countercraft/movecraft/sign/ScuttleSign.java | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/HelmSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/HelmSign.java index 1c5afc392..9dd720055 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/HelmSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/HelmSign.java @@ -55,7 +55,7 @@ protected void onCraftNotFound(Player player, AbstractSignListener.SignWrapper s } @Override - public boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action type, boolean sneaking) { + public boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action type, boolean sneaking, EventType eventType) { return !sneaking; } diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/MoveSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/MoveSign.java index 9a65437b2..f18150c11 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/MoveSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/MoveSign.java @@ -25,7 +25,7 @@ protected void onCraftNotFound(Player player, AbstractSignListener.SignWrapper s } @Override - public boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action type, boolean sneaking) { + public boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action type, boolean sneaking, EventType eventType) { if (processingSuccessful) { return true; } diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/NameSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/NameSign.java index 159fdf45d..b4956dc4d 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/NameSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/NameSign.java @@ -22,7 +22,7 @@ public NameSign() { } @Override - public boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action type, boolean sneaking) { + public boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action type, boolean sneaking, EventType eventType) { if (type == null) { return !processingSuccessful; } diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/PilotSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/PilotSign.java index 5853fce65..b3031b644 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/PilotSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/PilotSign.java @@ -14,7 +14,7 @@ public PilotSign() { } @Override - public boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action type, boolean sneaking) { + public boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action type, boolean sneaking, EventType eventType) { return processingSuccessful || !sneaking; } diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/RemoteSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/RemoteSign.java index aa980bfba..a5b8f05e8 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/RemoteSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/RemoteSign.java @@ -103,7 +103,7 @@ else if (foundTargetSigns.isEmpty()) { } @Override - public boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action type, boolean sneaking) { + public boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action type, boolean sneaking, EventType eventType) { return processingSuccessful || !sneaking; } diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/ScuttleSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/ScuttleSign.java index 07efe8f10..e5ef4ce64 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/ScuttleSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/ScuttleSign.java @@ -33,7 +33,7 @@ protected void onCraftNotFound(Player player, AbstractSignListener.SignWrapper s } @Override - public boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action type, boolean sneaking) { + public boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action type, boolean sneaking, EventType eventType) { if (processingSuccessful) { return true; } From cdd55d112eb9c994f3f1775fe6859aead2e81b8f Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Sat, 7 Sep 2024 00:56:05 +0200 Subject: [PATCH 111/122] refactor for eventtype enum (implementations (simple)) (cherry picked from commit 633f33c8c46bf89e70bc90229c2840e2b632e209) --- .../java/net/countercraft/movecraft/sign/CraftPilotSign.java | 3 +-- .../main/java/net/countercraft/movecraft/sign/ReleaseSign.java | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/CraftPilotSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/CraftPilotSign.java index a3827e8b0..db9fcbe25 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/CraftPilotSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/CraftPilotSign.java @@ -23,7 +23,6 @@ import java.util.Collections; import java.util.HashSet; -import java.util.Optional; import java.util.Set; //TODO: This is not very pretty... @@ -36,7 +35,7 @@ public CraftPilotSign(CraftType craftType) { } @Override - public boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action type, boolean sneaking) { + public boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action type, boolean sneaking, EventType eventType) { return processingSuccessful || !sneaking; } diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/ReleaseSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/ReleaseSign.java index 44c43e754..1488e9c26 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/ReleaseSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/ReleaseSign.java @@ -15,7 +15,7 @@ public ReleaseSign() { } @Override - public boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action type, boolean sneaking) { + public boolean shouldCancelEvent(boolean processingSuccessful, @Nullable Action type, boolean sneaking, EventType eventType) { if (processingSuccessful) { return true; } From f4eef4a1a8bbac16f7dfdc95aa669b7bfe5192b7 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Sat, 7 Sep 2024 00:58:44 +0200 Subject: [PATCH 112/122] Status Sign: round to 2 decimals (cherry picked from commit 3aa0dc97cdaf1280b60b122a8ca2fc60cddd2469) --- .../countercraft/movecraft/features/status/StatusSign.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java index dd1d9d32b..e495427b2 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/features/status/StatusSign.java @@ -14,6 +14,7 @@ import org.bukkit.entity.Player; import org.jetbrains.annotations.Nullable; +import java.text.DecimalFormat; import java.util.List; // TODO: Split this into multiple signs? Separate sign for fuel would make sense @@ -124,7 +125,8 @@ protected void calcdisplayComponents(@Nullable Craft craft) { text += entry.getName().toUpperCase().charAt(0); } text += " "; - text += (int) percentPresent; + // Round to 2 digits to better reflect the actual situation + text += String.format("%.2f", percentPresent); text += "/"; text += (int) entry.getMin(); From 4bc2ad4a2a60ead315046dbb8d6fe2012eb755b5 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Tue, 10 Sep 2024 19:44:29 +0200 Subject: [PATCH 113/122] supply eventType and use nullable for sign get access (cherry picked from commit 5e0ed2e6d3d6beeab327a9ce61c24fe01f553b16) --- .../movecraft/sign/RemoteSign.java | 4 +- .../movecraft/sign/AbstractCraftSign.java | 16 +++---- .../movecraft/sign/AbstractMovecraftSign.java | 10 ++-- .../movecraft/sign/AbstractSignListener.java | 46 ++++++++++++++++--- 4 files changed, 54 insertions(+), 22 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/RemoteSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/RemoteSign.java index a5b8f05e8..b47c7ccd7 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/RemoteSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/RemoteSign.java @@ -53,9 +53,9 @@ protected boolean internalProcessSignWithCraft(Action clickType, AbstractSignLis for (AbstractSignListener.SignWrapper wrapper : targetSignWrappers) { // Matches source? final String signHeader = PlainTextComponentSerializer.plainText().serialize(wrapper.line(0)); - Optional signHandler = AbstractMovecraftSign.tryGet(signHeader); + AbstractMovecraftSign signHandler = AbstractMovecraftSign.get(signHeader); // Ignore other remove signs - if (!signHandler.isPresent() || signHandler.get() instanceof RemoteSign) { + if (signHandler == null || signHandler instanceof RemoteSign) { continue; } // But does it match the source man? diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftSign.java index 232601e82..775d73cb9 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftSign.java @@ -22,20 +22,20 @@ public abstract class AbstractCraftSign extends AbstractMovecraftSign { // Helper method for the listener - public static Optional tryGetCraftSign(final Component ident) { + public static @Nullable AbstractCraftSign getCraftSign(final Component ident) { if (ident == null) { - return Optional.empty(); + return null; } final String identStr = PlainTextComponentSerializer.plainText().serialize(ident); - return tryGetCraftSign(identStr); + return getCraftSign(identStr); } - public static Optional tryGetCraftSign(final String ident) { - Optional tmp = AbstractCraftSign.tryGet(ident); - if (tmp.isPresent() && tmp.get() instanceof AbstractCraftSign acs) { - return Optional.of(acs); + public static @Nullable AbstractCraftSign getCraftSign(final String ident) { + AbstractMovecraftSign tmp = AbstractCraftSign.get(ident); + if (tmp != null && tmp instanceof AbstractCraftSign acs) { + return acs; } - return Optional.empty(); + return null; } protected final boolean ignoreCraftIsBusy; diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java index c30697c6e..49201c2c6 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java @@ -47,24 +47,24 @@ public static void registerCraftPilotSigns(Set loadedTypes, Function< } } - public static Optional tryGet(final Component ident) { + public static @Nullable AbstractMovecraftSign get(final Component ident) { if (ident == null) { - return Optional.empty(); + return null; } final String identStr = PlainTextComponentSerializer.plainText().serialize(ident); - return tryGet(identStr); + return get(identStr); } // Attempts to find a AbstractMovecraftSign instance, if something has been registered // If the ident follows the format "foo: bar", only "foo:" is used as ident to search for - public static Optional tryGet(final String ident) { + public static @Nullable AbstractMovecraftSign get(final String ident) { String identToUse = ident.toUpperCase(); if (identToUse.contains(":")) { identToUse = identToUse.split(":")[0]; // Re-add the : cause things should be registered with : at the end identToUse = identToUse + ":"; } - return Optional.ofNullable(SIGNS.getOrDefault(identToUse, null)); + return SIGNS.getOrDefault(identToUse, null); } // Registers a sign in all cases diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java index 3810dd048..d08d87a71 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractSignListener.java @@ -3,6 +3,7 @@ import net.countercraft.movecraft.craft.Craft; import net.countercraft.movecraft.events.CraftDetectEvent; import net.countercraft.movecraft.events.SignTranslateEvent; +import net.countercraft.movecraft.util.MathUtils; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; import org.bukkit.World; @@ -10,11 +11,13 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.BlockState; import org.bukkit.block.Sign; +import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.block.SignChangeEvent; import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.Nullable; import java.util.List; @@ -167,7 +170,10 @@ public SignWrapper[] getSignWrappers(Sign sign) { }; public abstract SignWrapper[] getSignWrappers(Sign sign, boolean ignoreEmpty); protected abstract SignWrapper getSignWrapper(Sign sign, SignChangeEvent signChangeEvent); - protected abstract SignWrapper getSignWrapper(Sign sign, PlayerInteractEvent interactEvent); + protected SignWrapper getSignWrapper(Sign sign, PlayerInteractEvent interactEvent) { + return this.getSignWrapper(sign, interactEvent.getPlayer()); + } + protected abstract SignWrapper getSignWrapper(Sign sign, Player player); public abstract void processSignTranslation(final Craft craft, boolean checkEventIsUpdated); @@ -180,7 +186,11 @@ public void onCraftDetect(CraftDetectEvent event) { BlockState state = block.getState(); if (state instanceof Sign sign) { for (SignWrapper wrapper : this.getSignWrappers(sign)) { - AbstractCraftSign.tryGetCraftSign(wrapper.line(0)).ifPresent(acs -> acs.onCraftDetect(event, wrapper)); + // Would be one more readable line if using Optionals but Nullables were wanted + AbstractCraftSign acs = AbstractCraftSign.getCraftSign(wrapper.line(0)); + if (acs != null) { + acs.onCraftDetect(event, wrapper); + } } } } @@ -189,7 +199,11 @@ public void onCraftDetect(CraftDetectEvent event) { @EventHandler(ignoreCancelled = true, priority = EventPriority.LOW) public void onSignTranslate(SignTranslateEvent event) { - AbstractCraftSign.tryGetCraftSign(event.line(0)).ifPresent(acs -> acs.onSignMovedByCraft(event)); + // Would be one more readable line if using Optionals but Nullables were wanted + AbstractCraftSign acs = AbstractCraftSign.getCraftSign(event.line(0)); + if (acs != null) { + acs.onSignMovedByCraft(event); + } } @EventHandler(ignoreCancelled = true, priority = EventPriority.LOW) @@ -197,11 +211,19 @@ public void onSignChange(SignChangeEvent event) { Block block = event.getBlock(); BlockState state = block.getState(); if (state instanceof Sign sign) { + SignWrapper signWrapper = this.getSignWrapper(sign, event.getPlayer()); SignWrapper wrapper = this.getSignWrapper(sign, event); - AbstractMovecraftSign.tryGet(wrapper.line(0)).ifPresent(ams -> { + AbstractMovecraftSign.EventType eventType = signWrapper.isEmpty() ? AbstractMovecraftSign.EventType.SIGN_CREATION : AbstractMovecraftSign.EventType.SIGN_EDIT; + if (eventType == AbstractMovecraftSign.EventType.SIGN_EDIT && MathUtils.getCraftByPersistentBlockData(sign.getLocation()) != null) { + eventType = AbstractMovecraftSign.EventType.SIGN_EDIT_ON_CRAFT; + } + final AbstractMovecraftSign.EventType eventTypeTmp = eventType; + AbstractMovecraftSign ams = AbstractMovecraftSign.get(wrapper.line(0)); + // Would be one more readable line if using Optionals but Nullables were wanted + if (ams != null) { boolean success = ams.processSignChange(event, wrapper); - if (ams.shouldCancelEvent(success, null, event.getPlayer().isSneaking())) { + if (ams.shouldCancelEvent(success, null, event.getPlayer().isSneaking(), eventTypeTmp)) { event.setCancelled(true); } }); @@ -217,9 +239,19 @@ public void onSignClick(PlayerInteractEvent event) { BlockState state = block.getState(); if (state instanceof Sign sign) { SignWrapper wrapper = this.getSignWrapper(sign, event); - AbstractMovecraftSign.tryGet(wrapper.line(0)).ifPresent(ams -> { + boolean shift = event.getPlayer().isSneaking(); + ItemStack heldItem = event.getItem(); + + // TODO: If the item is a feather (right click) or a axe (left click) and shift is pressed, then we don't do movecraft stuff + + // Would be one more readable line if using Optionals but Nullables were wanted + AbstractMovecraftSign ams = AbstractMovecraftSign.get(wrapper.line(0)); + if (ams != null) { boolean success = ams.processSignClick(event.getAction(), wrapper, event.getPlayer()); - if (ams.shouldCancelEvent(success, event.getAction(), event.getPlayer().isSneaking())) { + if (ams.shouldCancelEvent(success, event.getAction(), event.getPlayer().isSneaking(), AbstractMovecraftSign.EventType.SIGN_CLICK)) { + event.setCancelled(true); + } else if (MathUtils.getCraftByPersistentBlockData(sign.getLocation()) != null) { + // Cancel interact in all cases when on a craft event.setCancelled(true); } }); From 21c61c0f8f3018542672b73257e872d98403a10e Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Tue, 10 Sep 2024 19:46:30 +0200 Subject: [PATCH 114/122] just call it override (cherry picked from commit 88baa63888a310fb190ab7945eef888e348da2d9) --- .../countercraft/movecraft/sign/AbstractMovecraftSign.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java index 49201c2c6..303cb4f2c 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java @@ -74,8 +74,8 @@ public static void register(final String ident, final @Nonnull AbstractMovecraft // Registers a sign // If @param overrideIfAlreadyRegistered is set to false, it won't be registered if something has elready been registered using that name - public static void register(final String ident, final @Nonnull AbstractMovecraftSign instance, boolean overrideIfAlreadyRegistered) { - if (overrideIfAlreadyRegistered) { + public static void register(final String ident, final @Nonnull AbstractMovecraftSign instance, boolean override) { + if (override) { SIGNS.put(ident.toUpperCase(), instance); } else { SIGNS.putIfAbsent(ident.toUpperCase(), instance); From 9acc31a49d4321e2411977711d7ff3d0b27d4361 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Tue, 10 Sep 2024 20:05:19 +0200 Subject: [PATCH 115/122] add registry base class, implement it, and use it (cherry picked from commit 1853ba716b49f568d695fb570a87b2f337bb3724) --- .../craft/datatag/CraftDataTagRegistry.java | 3 + .../movecraft/sign/AbstractCraftSign.java | 16 ++-- .../movecraft/sign/AbstractMovecraftSign.java | 39 ++++----- .../movecraft/sign/MovecraftSignRegistry.java | 80 +++++++++++++++++++ .../movecraft/util/SimpleRegistry.java | 46 +++++++++++ 5 files changed, 150 insertions(+), 34 deletions(-) create mode 100644 api/src/main/java/net/countercraft/movecraft/sign/MovecraftSignRegistry.java create mode 100644 api/src/main/java/net/countercraft/movecraft/util/SimpleRegistry.java diff --git a/api/src/main/java/net/countercraft/movecraft/craft/datatag/CraftDataTagRegistry.java b/api/src/main/java/net/countercraft/movecraft/craft/datatag/CraftDataTagRegistry.java index d542f8405..96207624e 100644 --- a/api/src/main/java/net/countercraft/movecraft/craft/datatag/CraftDataTagRegistry.java +++ b/api/src/main/java/net/countercraft/movecraft/craft/datatag/CraftDataTagRegistry.java @@ -10,6 +10,9 @@ import java.util.concurrent.ConcurrentMap; import java.util.function.Function; +/** + * TODO: Change to extend @link SimpleRegistry in the future + */ public class CraftDataTagRegistry { public static final @NotNull CraftDataTagRegistry INSTANCE = new CraftDataTagRegistry(); diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftSign.java index 775d73cb9..2c73c8962 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftSign.java @@ -22,20 +22,16 @@ public abstract class AbstractCraftSign extends AbstractMovecraftSign { // Helper method for the listener + // Use the methods in MovecraftSignRegistry instead + @Deprecated(forRemoval = true) public static @Nullable AbstractCraftSign getCraftSign(final Component ident) { - if (ident == null) { - return null; - } - final String identStr = PlainTextComponentSerializer.plainText().serialize(ident); - return getCraftSign(identStr); + return MovecraftSignRegistry.INSTANCE.getCraftSign(ident); } + // Use the methods in MovecraftSignRegistry instead + @Deprecated(forRemoval = true) public static @Nullable AbstractCraftSign getCraftSign(final String ident) { - AbstractMovecraftSign tmp = AbstractCraftSign.get(ident); - if (tmp != null && tmp instanceof AbstractCraftSign acs) { - return acs; - } - return null; + return MovecraftSignRegistry.INSTANCE.getCraftSign(ident); } protected final boolean ignoreCraftIsBusy; diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java index 303cb4f2c..f5608e0a7 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractMovecraftSign.java @@ -38,48 +38,39 @@ public static boolean hasBeenRegistered(final String ident) { } // Special case for pilot signs, they are registered via the crafttypes name + // Use the methods in MovecraftSignRegistry instead + @Deprecated(forRemoval = true) public static void registerCraftPilotSigns(Set loadedTypes, Function signFactory) { - SIGNS.entrySet().removeIf(entry -> entry.getValue() instanceof AbstractCraftPilotSign); - // Now, add all types... - for (CraftType type : loadedTypes) { - AbstractCraftPilotSign sign = signFactory.apply(type); - register(type.getStringProperty(CraftType.NAME), sign, true); - } + MovecraftSignRegistry.INSTANCE.registerCraftPilotSigns(loadedTypes, signFactory); } + // Use the methods in MovecraftSignRegistry instead + @Deprecated(forRemoval = true) public static @Nullable AbstractMovecraftSign get(final Component ident) { - if (ident == null) { - return null; - } - final String identStr = PlainTextComponentSerializer.plainText().serialize(ident); - return get(identStr); + return MovecraftSignRegistry.INSTANCE.get(ident); } // Attempts to find a AbstractMovecraftSign instance, if something has been registered // If the ident follows the format "foo: bar", only "foo:" is used as ident to search for + // Use the methods in MovecraftSignRegistry instead + @Deprecated(forRemoval = true) public static @Nullable AbstractMovecraftSign get(final String ident) { - String identToUse = ident.toUpperCase(); - if (identToUse.contains(":")) { - identToUse = identToUse.split(":")[0]; - // Re-add the : cause things should be registered with : at the end - identToUse = identToUse + ":"; - } - return SIGNS.getOrDefault(identToUse, null); + return MovecraftSignRegistry.INSTANCE.get(ident); } // Registers a sign in all cases + // Use the methods in MovecraftSignRegistry instead + @Deprecated(forRemoval = true) public static void register(final String ident, final @Nonnull AbstractMovecraftSign instance) { - register(ident, instance, true); + MovecraftSignRegistry.INSTANCE.register(ident, instance); } // Registers a sign // If @param overrideIfAlreadyRegistered is set to false, it won't be registered if something has elready been registered using that name + // Use the methods in MovecraftSignRegistry instead + @Deprecated(forRemoval = true) public static void register(final String ident, final @Nonnull AbstractMovecraftSign instance, boolean override) { - if (override) { - SIGNS.put(ident.toUpperCase(), instance); - } else { - SIGNS.putIfAbsent(ident.toUpperCase(), instance); - } + MovecraftSignRegistry.INSTANCE.register(ident, instance, override); } // Optional permission for this sign diff --git a/api/src/main/java/net/countercraft/movecraft/sign/MovecraftSignRegistry.java b/api/src/main/java/net/countercraft/movecraft/sign/MovecraftSignRegistry.java new file mode 100644 index 000000000..a068f94ba --- /dev/null +++ b/api/src/main/java/net/countercraft/movecraft/sign/MovecraftSignRegistry.java @@ -0,0 +1,80 @@ +package net.countercraft.movecraft.sign; + +import net.countercraft.movecraft.craft.datatag.CraftDataTagRegistry; +import net.countercraft.movecraft.craft.type.CraftType; +import net.countercraft.movecraft.util.SimpleRegistry; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Set; +import java.util.function.Function; + +public class MovecraftSignRegistry extends SimpleRegistry { + + public static final @NotNull MovecraftSignRegistry INSTANCE = new MovecraftSignRegistry(); + + public void registerCraftPilotSigns(Set loadedTypes, Function signFactory) { + _register.entrySet().removeIf(entry -> entry.getValue() instanceof AbstractCraftPilotSign); + // Now, add all types... + for (CraftType type : loadedTypes) { + AbstractCraftPilotSign sign = signFactory.apply(type); + register(type.getStringProperty(CraftType.NAME), sign, true); + } + } + + public @NotNull AbstractMovecraftSign register(@NotNull String key, @NotNull AbstractMovecraftSign value, String... aliases) throws IllegalArgumentException { + return register(key, value, false, aliases); + } + + public @NotNull AbstractMovecraftSign register(@NotNull String key, @NotNull AbstractMovecraftSign value, boolean override, String... aliases) throws IllegalArgumentException { + AbstractMovecraftSign result = this.register(key, value, override); + for (String alias : aliases) { + this.register(alias, result, override); + } + return result; + } + + public @Nullable AbstractMovecraftSign get(Component key) { + if (key == null) { + return null; + } + final String identStr = PlainTextComponentSerializer.plainText().serialize(key); + return get(identStr); + } + + @Override + public @Nullable AbstractMovecraftSign get(@NotNull String key) { + String identToUse = key.toUpperCase(); + if (identToUse.contains(":")) { + identToUse = identToUse.split(":")[0]; + // Re-add the : cause things should be registered with : at the end + identToUse = identToUse + ":"; + } + return super.get(identToUse); + } + + // Helper method for the listener + public @Nullable AbstractCraftSign getCraftSign(final Component ident) { + if (ident == null) { + return null; + } + final String identStr = PlainTextComponentSerializer.plainText().serialize(ident); + return this.getCraftSign(identStr); + } + + public @Nullable AbstractCraftSign getCraftSign(final String ident) { + AbstractMovecraftSign tmp = this.get(ident); + if (tmp != null && tmp instanceof AbstractCraftSign acs) { + return acs; + } + return null; + } + + + @Override + public @NotNull AbstractMovecraftSign register(@NotNull String key, @NotNull AbstractMovecraftSign value, boolean override) throws IllegalArgumentException { + return super.register(key.toUpperCase(), value, override); + } +} diff --git a/api/src/main/java/net/countercraft/movecraft/util/SimpleRegistry.java b/api/src/main/java/net/countercraft/movecraft/util/SimpleRegistry.java new file mode 100644 index 000000000..bddee0e9d --- /dev/null +++ b/api/src/main/java/net/countercraft/movecraft/util/SimpleRegistry.java @@ -0,0 +1,46 @@ +package net.countercraft.movecraft.util; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +public class SimpleRegistry { + + protected final @NotNull ConcurrentMap<@NotNull K, @NotNull T> _register; + + public SimpleRegistry(){ + _register = new ConcurrentHashMap<>(); + } + + public @NotNull T register(final @NotNull K key, final @NotNull T value) throws IllegalArgumentException { + return this.register(key, value, false); + } + + public @NotNull T register(final @NotNull K key, final @NotNull T value, boolean override) throws IllegalArgumentException { + T previous = _register.putIfAbsent(key, value); + if(previous != null && !override){ + throw new IllegalArgumentException(String.format("Key %s is already registered.", key)); + } + + return value; + } + + public @Nullable T get(final @NotNull K key) { + return _register.getOrDefault(key, null); + } + + public boolean isRegistered(final @NotNull K key){ + return _register.containsKey(key); + } + + /** + * Get an iterable over all keys currently registered. + * @return An immutable iterable over the registry keys + */ + public @NotNull Iterable<@NotNull K> getAllKeys(){ + return _register.keySet().stream().toList(); + } + +} From aef31b49583eee28f8c92ecca03479446329067c Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Tue, 10 Sep 2024 20:06:47 +0200 Subject: [PATCH 116/122] adjust comment (cherry picked from commit 23168768bef04534665e5e09acb8d8a1f86087de) --- .../net/countercraft/movecraft/events/SignTranslateEvent.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/api/src/main/java/net/countercraft/movecraft/events/SignTranslateEvent.java b/api/src/main/java/net/countercraft/movecraft/events/SignTranslateEvent.java index e615f8c5f..34fa72835 100644 --- a/api/src/main/java/net/countercraft/movecraft/events/SignTranslateEvent.java +++ b/api/src/main/java/net/countercraft/movecraft/events/SignTranslateEvent.java @@ -39,7 +39,8 @@ public SignTranslateEvent(@NotNull Craft craft, @NotNull AbstractSignListener.Si @NotNull @Deprecated(forRemoval = true) public String[] getLines() { - // TODO: Why does this set it to updated? This is just reading... + // Why does this set it to updated? This is just reading... + // => Lines can be updated externally. We need to mark all signs as updated so it displays properly on clients this.updated = true; return backing.rawLines(); } From 970d49d7b39f0f61f978572bbf3b1e8564ac052f Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Tue, 10 Sep 2024 20:07:08 +0200 Subject: [PATCH 117/122] adjust comment (cherry picked from commit 238e989fa852a21e2d99ca4fb4efc3eff3b2101d) --- .../net/countercraft/movecraft/events/SignTranslateEvent.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/main/java/net/countercraft/movecraft/events/SignTranslateEvent.java b/api/src/main/java/net/countercraft/movecraft/events/SignTranslateEvent.java index 34fa72835..38ab5c040 100644 --- a/api/src/main/java/net/countercraft/movecraft/events/SignTranslateEvent.java +++ b/api/src/main/java/net/countercraft/movecraft/events/SignTranslateEvent.java @@ -85,7 +85,7 @@ public List lines() { return backing.lines(); } - // Bukkit crap + // Bukkit @Override public HandlerList getHandlers() { return HANDLERS; From 0da888dabf26e7f17d7a398c41400d0721fde76d Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Tue, 10 Sep 2024 20:13:57 +0200 Subject: [PATCH 118/122] remove old code (cherry picked from commit fd70b5053987a9a7ede55a938a38b0926b38920c) (cherry picked from commit 17b458e5b9b87799a070df8c238a353ccb9c2d7c) --- .../java/net/countercraft/movecraft/sign/CraftPilotSign.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/CraftPilotSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/CraftPilotSign.java index db9fcbe25..13d69239b 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/CraftPilotSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/CraftPilotSign.java @@ -119,10 +119,6 @@ protected void runDetectTask(MovecraftLocation startPoint, Player player, Abstra // Setup cruise direction BlockFace facing = signWrapper.facing(); craft.setCruiseDirection(CruiseDirection.fromBlockFace(facing)); - /*if (signWrapper.block().getBlockData() instanceof Directional) - craft.setCruiseDirection(CruiseDirection.fromBlockFace(((Directional) sign.getBlockData()).getFacing())); - else - craft.setCruiseDirection(CruiseDirection.NONE);*/ // Start craft cruising craft.setLastCruiseUpdate(System.currentTimeMillis()); From bf290401efb3f8c7df6a06ea40de2d5a34ccf7d0 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Sat, 21 Sep 2024 22:09:12 +0200 Subject: [PATCH 119/122] index out of bounds exception patch (cherry picked from commit 21c4554621c47dc975fde4291558251399af7067) (cherry picked from commit c2978b07adaa24ffb2c6dba4c58fb0787a38e280) --- .../countercraft/movecraft/features/contacts/ContactsSign.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/features/contacts/ContactsSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/features/contacts/ContactsSign.java index ce86818c4..65d2fd19c 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/features/contacts/ContactsSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/features/contacts/ContactsSign.java @@ -69,7 +69,7 @@ protected boolean internalProcessSignWithCraft(Action clickType, AbstractSignLis protected @Nullable Component getUpdateString(int lineIndex, Component oldData, Craft craft) { Craft contact = null; List contacts = craft.getDataTag(Craft.CONTACTS); - if (contacts.isEmpty() || contacts.size() < lineIndex) { + if (contacts.isEmpty() || contacts.size() <= lineIndex) { return EMPTY; } contact = contacts.get(lineIndex); From d44c29dc409a49ba60ef68d8838ff8c2e63a64f0 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Sun, 29 Sep 2024 13:27:26 +0200 Subject: [PATCH 120/122] add getter for crafttype (cherry picked from commit c83b41ee0652e9f2b6751083150b000c7f954ab2) (cherry picked from commit 9d850cefbecd6d1fd5783c038ce9d4f50dcb2d47) --- .../countercraft/movecraft/sign/AbstractCraftPilotSign.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftPilotSign.java b/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftPilotSign.java index c2d80313a..501cf4743 100644 --- a/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftPilotSign.java +++ b/api/src/main/java/net/countercraft/movecraft/sign/AbstractCraftPilotSign.java @@ -14,4 +14,8 @@ public AbstractCraftPilotSign(final CraftType craftType) { this.craftType = craftType; } + public CraftType getCraftType() { + return this.craftType; + } + } From ca320fc2284618b15f493bd3f8ca1228a24d5e64 Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Sat, 5 Oct 2024 15:46:17 +0200 Subject: [PATCH 121/122] cherry pick commit --- .../java/net/countercraft/movecraft/sign/RemoteSign.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/RemoteSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/RemoteSign.java index b47c7ccd7..1dbbafff9 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/RemoteSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/RemoteSign.java @@ -39,7 +39,7 @@ protected void onCraftNotFound(Player player, AbstractSignListener.SignWrapper s protected boolean internalProcessSignWithCraft(Action clickType, AbstractSignListener.SignWrapper sign, Craft craft, Player player) { Map> foundTargetSigns = new HashMap<>(); boolean firstError = true; - final String targetIdent = sign.getRaw(1).toUpperCase(); + final String targetIdent = sign.getRaw(1); for (MovecraftLocation tloc : craft.getHitBox()) { BlockState tstate = craft.getWorld().getBlockAt(tloc.getX(), tloc.getY(), tloc.getZ()).getState(); if (!(tstate instanceof Sign)) { @@ -134,8 +134,8 @@ protected static boolean hasForbiddenString(AbstractSignListener.SignWrapper wra // Walks through all strings on the wrapper and if any of the non-header strings match it returns true protected static boolean matchesDescriptor(final String descriptor, final AbstractSignListener.SignWrapper potentialTarget) { - for (int i = 1; i < potentialTarget.lines().size(); i++) { - String targetStr = potentialTarget.getRaw(i).toUpperCase(); + for (int i = 2; i < potentialTarget.lines().size(); i++) { + String targetStr = potentialTarget.getRaw(i); if (descriptor.equalsIgnoreCase(targetStr)) { return true; } From dcddc05cde65dbf04fea67e06ba13a88229e35db Mon Sep 17 00:00:00 2001 From: DerToaster98 <38782719+DerToaster98@users.noreply.github.com> Date: Sat, 5 Oct 2024 15:49:17 +0200 Subject: [PATCH 122/122] cherry pick commit --- .../main/java/net/countercraft/movecraft/sign/RemoteSign.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/sign/RemoteSign.java b/Movecraft/src/main/java/net/countercraft/movecraft/sign/RemoteSign.java index 1dbbafff9..25e9f9c93 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/sign/RemoteSign.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/sign/RemoteSign.java @@ -134,7 +134,7 @@ protected static boolean hasForbiddenString(AbstractSignListener.SignWrapper wra // Walks through all strings on the wrapper and if any of the non-header strings match it returns true protected static boolean matchesDescriptor(final String descriptor, final AbstractSignListener.SignWrapper potentialTarget) { - for (int i = 2; i < potentialTarget.lines().size(); i++) { + for (int i = 1; i < potentialTarget.lines().size(); i++) { String targetStr = potentialTarget.getRaw(i); if (descriptor.equalsIgnoreCase(targetStr)) { return true;