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 01/84] 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 02/84] 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 03/84] 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 04/84] 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 05/84] 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 06/84] 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 07/84] 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 08/84] 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 09/84] 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 10/84] 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 11/84] 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 12/84] 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 13/84] 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 14/84] 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 15/84] 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 16/84] 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 17/84] 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 18/84] 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 19/84] 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 20/84] 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 21/84] 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 22/84] 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 23/84] 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 24/84] 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 25/84] 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 26/84] 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 27/84] 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 28/84] 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 29/84] 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 30/84] 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 31/84] 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 32/84] 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 33/84] 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 34/84] 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 35/84] 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 36/84] 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 37/84] 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 38/84] 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 39/84] 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 40/84] 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 41/84] 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 42/84] 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 43/84] 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 44/84] 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 45/84] 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 46/84] 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 47/84] 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 48/84] 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 49/84] 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 50/84] 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 51/84] 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 52/84] 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 53/84] 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 54/84] 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 55/84] 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 56/84] 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 57/84] 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 58/84] 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 59/84] 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 60/84] 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 61/84] 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 62/84] 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 63/84] 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 64/84] 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 65/84] 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 66/84] 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 67/84] 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 68/84] 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 69/84] 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 70/84] 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 71/84] 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 72/84] 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 73/84] 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 74/84] 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 75/84] 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 76/84] 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 77/84] 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 78/84] 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 79/84] 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 80/84] 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 81/84] 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 82/84] 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 83/84] 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 84/84] 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; } + }