From 2f87ec8170c665143dbceae685ebf38b652a247d Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Fri, 7 Jul 2023 12:01:31 -0600 Subject: [PATCH 01/13] Add side, multiple lines, chat formats and more to signs --- .../ch/njol/skript/expressions/ExprLore.java | 2 +- .../njol/skript/expressions/ExprSignText.java | 346 ++++++++++++------ 2 files changed, 245 insertions(+), 103 deletions(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprLore.java b/src/main/java/ch/njol/skript/expressions/ExprLore.java index 9c2d9331b71..9373166c6fe 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprLore.java +++ b/src/main/java/ch/njol/skript/expressions/ExprLore.java @@ -236,7 +236,7 @@ public void change(final Event e, final @Nullable Object[] delta, final ChangeMo } } - private String handleRemove(String input, String toRemove, boolean all) { + public static String handleRemove(String input, String toRemove, boolean all) { if (SkriptConfig.caseSensitive.value()) { if (all) { return input.replace(toRemove, ""); diff --git a/src/main/java/ch/njol/skript/expressions/ExprSignText.java b/src/main/java/ch/njol/skript/expressions/ExprSignText.java index 592420ed647..7043aebc079 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprSignText.java +++ b/src/main/java/ch/njol/skript/expressions/ExprSignText.java @@ -18,11 +18,18 @@ */ package ch.njol.skript.expressions; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Stream; + import org.bukkit.block.Block; import org.bukkit.block.Sign; +import org.bukkit.block.sign.Side; import org.bukkit.event.Event; import org.bukkit.event.block.SignChangeEvent; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; + +import com.google.common.collect.Lists; import ch.njol.skript.Skript; import ch.njol.skript.aliases.Aliases; @@ -38,139 +45,274 @@ import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.skript.lang.util.SimpleExpression; import ch.njol.skript.lang.util.SimpleLiteral; +import ch.njol.skript.util.chat.BungeeConverter; +import ch.njol.skript.util.chat.ChatMessages; import ch.njol.util.Kleenean; +import ch.njol.util.StringUtils; +import ch.njol.util.coll.CollectionUtils; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.serializer.bungeecord.BungeeComponentSerializer; -/** - * @author Peter Güttinger - */ @Name("Sign Text") @Description("A line of text on a sign. Can be changed, but remember that there is a 16 character limit per line (including color codes that use 2 characters each).") -@Examples({"on rightclick on sign:", - " line 2 of the clicked block is \"[Heal]\":", - " heal the player", - " set line 3 to \"%player%\""}) -@Since("1.3") +@Examples({ + "on rightclick on sign:", + "\tline 2 of the clicked block is \"[Heal]\":", + "\t\theal the player", + "\tset line 3 to \"%player%\"" +}) +@Since("1.3, INSERT VERSION (all lines, back side, multiple blocks, and Skript's ChatFormat (hex, font, etc))") public class ExprSignText extends SimpleExpression { + + private static final boolean RUNNING_1_20 = Skript.isRunningMinecraft(1, 20); + private static final ItemType SIGN_ALIASES = Aliases.javaItemType("sign"); + private static BungeeComponentSerializer serializer; + static { + // Adventure API coming from Paper. + if (Skript.methodExists(SignChangeEvent.class, "lines")) + serializer = BungeeComponentSerializer.get(); + + String addition = RUNNING_1_20 ? "[[on [the] (front|:back) side] of [sign[s]] %blocks%]" : "[of [sign[s]] %blocks%]"; Skript.registerExpression(ExprSignText.class, String.class, ExpressionType.PROPERTY, - "[the] line %number% [of %block%]", "[the] (1¦1st|1¦first|2¦2nd|2¦second|3¦3rd|3¦third|4¦4th|4¦fourth) line [of %block%]"); + "[all [[of] the]|the] lines " + addition, + RUNNING_1_20 ? "%blocks%'[s] [(front|:back) side] lines" : "%blocks%'[s] lines", + + "[the] line %number% " + addition, + "[the] (1¦1st|1¦first|2¦2nd|2¦second|3¦3rd|3¦third|4¦4th|4¦fourth) line[s] " + addition); } - - private static final ItemType sign = Aliases.javaItemType("sign"); - - @SuppressWarnings("null") + + @Nullable private Expression line; - @SuppressWarnings("null") - private Expression block; - - @SuppressWarnings({"unchecked", "null"}) + private Expression blocks; + private boolean lines; + + @Nullable + private Side side; // Only nullable due to older versions than 1.20. + @Override - public boolean init(final Expression[] exprs, final int matchedPattern, final Kleenean isDelayed, final ParseResult parseResult) { - if (matchedPattern == 0) + @SuppressWarnings("unchecked") + public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { + if (matchedPattern == 2) { line = (Expression) exprs[0]; - else + } else if (matchedPattern == 3) { line = new SimpleLiteral<>(parseResult.mark, false); - block = (Expression) exprs[exprs.length - 1]; - return true; - } - - @Override - public boolean isSingle() { + } else { + lines = true; + } + if (RUNNING_1_20) + side = parseResult.hasTag("back") ? Side.BACK : Side.FRONT; + blocks = (Expression) exprs[matchedPattern <= 1 ? 0 : 1]; return true; } - - @Override - public Class getReturnType() { - return String.class; - } - + @Override @Nullable - protected String[] get(final Event e) { - final Number l = line.getSingle(e); - if (l == null) + protected String[] get(Event event) { + int line = 0; + if (this.line == null && !lines) { return new String[0]; - final int line = l.intValue() - 1; - if (line < 0 || line > 3) - return new String[0]; - if (getTime() >= 0 && block.isDefault() && e instanceof SignChangeEvent && !Delay.isDelayed(e)) { - return new String[] {((SignChangeEvent) e).getLine(line)}; + } else if (!lines) { + line = this.line.getOptionalSingle(event).orElse(1).intValue() - 1; + if (line < 0 || line > 3) + return new String[0]; } - final Block b = block.getSingle(e); - if (b == null) - return new String[0]; - if (!sign.isOfType(b)) - return new String[0]; - return new String[] {((Sign) b.getState()).getLine(line)}; - } - - @Override - public String toString(final @Nullable Event e, final boolean debug) { - return "line " + line.toString(e, debug) + " of " + block.toString(e, debug); + if (getTime() >= 0 && event instanceof SignChangeEvent && !Delay.isDelayed(event)) { + if (lines) + return ((SignChangeEvent) event).getLines(); + return new String[] {((SignChangeEvent) event).getLine(line)}; + } + int finalLine = line; + return blocks.stream(event) + .filter(SIGN_ALIASES::isOfType) + .map(Sign.class::cast) + .flatMap(sign -> { + if (RUNNING_1_20) { + if (lines) + return Arrays.stream(sign.getSide(side).getLines()); + return Stream.of(sign.getSide(side).getLine(finalLine)); + } + if (lines) + return Arrays.stream(sign.getLines()); + return Stream.of(sign.getLine(finalLine)); + }) + .toArray(String[]::new); } - - // TODO allow add, remove, and remove all (see ExprLore) + @Override @Nullable - public Class[] acceptChange(final ChangeMode mode) { - if (mode == ChangeMode.DELETE || mode == ChangeMode.SET) - return new Class[] {String.class}; - return null; + public Class[] acceptChange(ChangeMode mode) { + boolean acceptsMany = line == null; + switch (mode) { + case REMOVE: + case REMOVE_ALL: + case DELETE: + acceptsMany = false; + case SET: + case ADD: + return CollectionUtils.array(acceptsMany ? String[].class : String.class); + case RESET: + default: + return null; + } } - - static boolean hasUpdateBooleanBoolean = true; - - @SuppressWarnings("incomplete-switch") + @Override - public void change(final Event e, final @Nullable Object[] delta, final ChangeMode mode) throws UnsupportedOperationException { - final Number l = line.getSingle(e); - if (l == null) - return; - final int line = l.intValue() - 1; - if (line < 0 || line > 3) + public void change(Event event, @Nullable Object[] delta, ChangeMode mode) { + int line = 0; + if (this.line == null && !lines) { return; - final Block b = block.getSingle(e); - if (b == null) - return; - if (getTime() >= 0 && e instanceof SignChangeEvent && b.equals(((SignChangeEvent) e).getBlock()) && !Delay.isDelayed(e)) { - switch (mode) { - case DELETE: - ((SignChangeEvent) e).setLine(line, ""); - break; - case SET: - assert delta != null; - ((SignChangeEvent) e).setLine(line, (String) delta[0]); - break; - } - } else { - if (!sign.isOfType(b)) + } else if (!lines) { + line = this.line.getOptionalSingle(event).orElse(1).intValue() - 1; + if (line < 0 || line > 3) return; - final Sign s = (Sign) b.getState(); + } + if (getTime() >= 0 && event instanceof SignChangeEvent && blocks.check(event, block -> block.equals(((SignChangeEvent) event).getBlock())) && !Delay.isDelayed(event)) { + String[] stringDelta = delta == null ? null : Arrays.copyOf(delta, delta.length, String[].class); + SignChangeEvent changeEvent = (SignChangeEvent) event; switch (mode) { + case ADD: + assert stringDelta != null; + if (lines) { + List list = Lists.newArrayList(changeEvent.getLines()); + for (String string : stringDelta) + list.add(string); + + stringDelta = list.toArray(new String[0]); + } else { + for (int i = 0; i < stringDelta.length; i++) { + String value = stringDelta.length > i ? (String) delta[i] : ""; + stringDelta[i] = value + stringDelta[i]; + } + } + //$FALL-THROUGH$ + case REMOVE: + case REMOVE_ALL: + assert stringDelta != null; + stringDelta = ExprLore.handleRemove(StringUtils.join(stringDelta, "\n"), stringDelta[0], mode == ChangeMode.REMOVE_ALL).split("\n"); + //$FALL-THROUGH$ case DELETE: - s.setLine(line, ""); - break; + stringDelta = CollectionUtils.array("", "", "", ""); case SET: - assert delta != null; - s.setLine(line, (String) delta[0]); + // We need to ensure that it's clearing values without calling setLine twice. + if (mode == ChangeMode.SET) { + for (int i = 0; i < 4; i++) + stringDelta[i] = stringDelta.length > i ? (String) stringDelta[i] : ""; + } + assert stringDelta != null; + if (lines) { + for (int i = 0; i < 4; i++) { + String value = stringDelta.length > i ? (String) stringDelta[i] : ""; + if (serializer != null) { + if (value.isEmpty()) // Reduce callings. + changeEvent.line(i, Component.empty()); + changeEvent.line(i, serializer.deserialize(BungeeConverter.convert(ChatMessages.parseToArray(value)))); + continue; + } + changeEvent.setLine(i, value); + } + break; + } + changeEvent.setLine(line, (String) delta[0]); + break; + default: break; } - if (hasUpdateBooleanBoolean) { - try { - s.update(false, false); - } catch (final NoSuchMethodError err) { - hasUpdateBooleanBoolean = false; - s.update(); - } - } else { - s.update(); - } + return; } + int finalLine = line; + blocks.stream(event) + .filter(SIGN_ALIASES::isOfType) + .map(Sign.class::cast) + .forEach(sign -> { + String[] stringDelta = delta == null ? null : Arrays.copyOf(delta, delta.length, String[].class); + switch (mode) { + case ADD: + assert stringDelta != null; + if (lines) { + List list = Lists.newArrayList(sign.getLines()); + for (String string : stringDelta) + list.add(string); + + stringDelta = list.toArray(new String[0]); + } else { + for (int i = 0; i < stringDelta.length; i++) { + String value = stringDelta.length > i ? (String) delta[i] : ""; + stringDelta[i] = value + stringDelta[i]; + } + } + //$FALL-THROUGH$ + case REMOVE: + case REMOVE_ALL: + assert stringDelta != null; + stringDelta = ExprLore.handleRemove(StringUtils.join(stringDelta, "\n"), stringDelta[0], mode == ChangeMode.REMOVE_ALL).split("\n"); + //$FALL-THROUGH$ + case DELETE: + stringDelta = CollectionUtils.array("", "", "", ""); + case SET: + // We need to ensure that it's clearing values without calling setLine twice. + if (mode == ChangeMode.SET) { + for (int i = 0; i < 4; i++) + stringDelta[i] = stringDelta.length > i ? (String) stringDelta[i] : ""; + } + assert stringDelta != null; + if (RUNNING_1_20) { + if (lines) { + for (int i = 0; i < 4; i++) { + String value = stringDelta.length > i ? (String) stringDelta[i] : ""; + if (serializer != null) { + if (value.isEmpty()) // Reduce callings. + sign.getSide(side).line(i, Component.empty()); + sign.getSide(side).line(i, serializer.deserialize(BungeeConverter.convert(ChatMessages.parseToArray(value)))); + continue; + } + sign.setLine(i, value); + } + } + sign.setLine(finalLine, (String) delta[0]); + break; + } + if (lines) { + for (int i = 0; i < 4; i++) { + String value = stringDelta.length > i ? (String) stringDelta[i] : ""; + if (serializer != null) { + if (value.isEmpty()) // Reduce callings. + sign.line(i, Component.empty()); + sign.line(i, serializer.deserialize(BungeeConverter.convert(ChatMessages.parseToArray(value)))); + continue; + } + sign.setLine(i, value); + } + } + sign.setLine(finalLine, (String) delta[0]); + break; + default: + break; + } + sign.update(true, false); + }); + } + + @Override + public boolean setTime(int time) { + return super.setTime(time, SignChangeEvent.class, blocks); } - + @Override - public boolean setTime(final int time) { - return super.setTime(time, SignChangeEvent.class, block); + public boolean isSingle() { + return !lines; } - + + @Override + public Class getReturnType() { + return String.class; + } + + @Override + public String toString(@Nullable Event event, boolean debug) { + if (line == null) + return "lines of " + blocks.toString(event, debug); + return "line " + line.toString(event, debug) + " of " + blocks.toString(event, debug); + } + } From 22e30f83243479e0f669161ddb933ddd6e2b575e Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Fri, 7 Jul 2023 12:18:34 -0600 Subject: [PATCH 02/13] Add sign side classinfo --- .../ch/njol/skript/classes/data/BukkitClasses.java | 9 +++++++++ .../njol/skript/classes/data/BukkitEventValues.java | 12 +++++++++++- .../ch/njol/skript/expressions/ExprSignText.java | 9 ++++----- src/main/resources/lang/default.lang | 6 ++++++ 4 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/main/java/ch/njol/skript/classes/data/BukkitClasses.java b/src/main/java/ch/njol/skript/classes/data/BukkitClasses.java index 5caa14f02e2..317835e9dbb 100644 --- a/src/main/java/ch/njol/skript/classes/data/BukkitClasses.java +++ b/src/main/java/ch/njol/skript/classes/data/BukkitClasses.java @@ -46,6 +46,7 @@ import org.bukkit.block.BlockState; import org.bukkit.block.DoubleChest; import org.bukkit.block.data.BlockData; +import org.bukkit.block.sign.Side; import org.bukkit.command.CommandSender; import org.bukkit.enchantments.Enchantment; import org.bukkit.enchantments.EnchantmentOffer; @@ -1511,5 +1512,13 @@ public String toVariableNameString(EnchantmentOffer eo) { .description("Represents a quit reason from a player quit server event.") .requiredPlugins("Paper 1.16.5+") .since("INSERT VERSION")); + + if (Skript.isRunningMinecraft(1, 20)) + Classes.registerClass(new EnumClassInfo<>(Side.class, "signside", "sign sides") + .user("sign ?sides?") + .name("Sign Sides") + .description("Represents a side of a sign.") + .requiredPlugins("Spigot 1.20+") + .since("INSERT VERSION")); } } diff --git a/src/main/java/ch/njol/skript/classes/data/BukkitEventValues.java b/src/main/java/ch/njol/skript/classes/data/BukkitEventValues.java index 79072ed5454..9cb35b2083d 100644 --- a/src/main/java/ch/njol/skript/classes/data/BukkitEventValues.java +++ b/src/main/java/ch/njol/skript/classes/data/BukkitEventValues.java @@ -34,6 +34,7 @@ import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.block.BlockState; +import org.bukkit.block.sign.Side; import org.bukkit.command.CommandSender; import org.bukkit.entity.AbstractVillager; import org.bukkit.entity.Egg; @@ -444,6 +445,7 @@ public Player get(final BlockCanBuildEvent e) { } }, 0); } + // SignChangeEvent EventValues.registerEventValue(SignChangeEvent.class, Player.class, new Getter() { @Override @@ -451,7 +453,7 @@ public Player get(final BlockCanBuildEvent e) { public Player get(final SignChangeEvent e) { return e.getPlayer(); } - }, 0); + }, EventValues.TIME_NOW); EventValues.registerEventValue(SignChangeEvent.class, String[].class, new Getter() { @Override @Nullable @@ -459,6 +461,14 @@ public String[] get(SignChangeEvent event) { return event.getLines(); } }, EventValues.TIME_NOW); + if (Skript.isRunningMinecraft(1, 20)) + EventValues.registerEventValue(SignChangeEvent.class, Side.class, new Getter() { + @Override + @Nullable + public Side get(SignChangeEvent event) { + return event.getSide(); + } + }, EventValues.TIME_NOW); // === EntityEvents === EventValues.registerEventValue(EntityEvent.class, Entity.class, new Getter() { diff --git a/src/main/java/ch/njol/skript/expressions/ExprSignText.java b/src/main/java/ch/njol/skript/expressions/ExprSignText.java index 7043aebc079..d1331b03f30 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprSignText.java +++ b/src/main/java/ch/njol/skript/expressions/ExprSignText.java @@ -32,8 +32,6 @@ import com.google.common.collect.Lists; import ch.njol.skript.Skript; -import ch.njol.skript.aliases.Aliases; -import ch.njol.skript.aliases.ItemType; import ch.njol.skript.classes.Changer.ChangeMode; import ch.njol.skript.doc.Description; import ch.njol.skript.doc.Examples; @@ -65,7 +63,6 @@ public class ExprSignText extends SimpleExpression { private static final boolean RUNNING_1_20 = Skript.isRunningMinecraft(1, 20); - private static final ItemType SIGN_ALIASES = Aliases.javaItemType("sign"); private static BungeeComponentSerializer serializer; static { @@ -124,7 +121,8 @@ protected String[] get(Event event) { } int finalLine = line; return blocks.stream(event) - .filter(SIGN_ALIASES::isOfType) + .map(Block::getState) + .filter(Sign.class::isInstance) .map(Sign.class::cast) .flatMap(sign -> { if (RUNNING_1_20) { @@ -222,7 +220,8 @@ public void change(Event event, @Nullable Object[] delta, ChangeMode mode) { } int finalLine = line; blocks.stream(event) - .filter(SIGN_ALIASES::isOfType) + .map(Block::getState) + .filter(Sign.class::isInstance) .map(Sign.class::cast) .forEach(sign -> { String[] stringDelta = delta == null ? null : Arrays.copyOf(delta, delta.length, String[].class); diff --git a/src/main/resources/lang/default.lang b/src/main/resources/lang/default.lang index 02909f887b2..d45fad8967a 100644 --- a/src/main/resources/lang/default.lang +++ b/src/main/resources/lang/default.lang @@ -1939,6 +1939,11 @@ quit reasons: kicked: kicked timed_out: timed out +# -- Sign Sides -- +sign sides: + front: front + back: back + # -- Boolean -- boolean: true: @@ -2008,6 +2013,7 @@ types: gene: panda gene¦s @a gamerulevalue: gamerule value¦s @a quitreason: quit reason¦s @a + signside: sign side¦s @a # Skript weathertype: weather type¦s @a From 9e22b00c91123c12701dde8e18f1b9ed65127e88 Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Fri, 7 Jul 2023 13:18:34 -0600 Subject: [PATCH 03/13] Attempt to fix error --- .../njol/skript/expressions/ExprSignText.java | 29 ++++++++++--------- src/main/java/ch/njol/skript/util/Utils.java | 3 +- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprSignText.java b/src/main/java/ch/njol/skript/expressions/ExprSignText.java index d1331b03f30..52053f7aae7 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprSignText.java +++ b/src/main/java/ch/njol/skript/expressions/ExprSignText.java @@ -31,11 +31,13 @@ import com.google.common.collect.Lists; +import ch.njol.skript.ServerPlatform; import ch.njol.skript.Skript; import ch.njol.skript.classes.Changer.ChangeMode; import ch.njol.skript.doc.Description; import ch.njol.skript.doc.Examples; import ch.njol.skript.doc.Name; +import ch.njol.skript.doc.RequiredPlugins; import ch.njol.skript.doc.Since; import ch.njol.skript.effects.Delay; import ch.njol.skript.lang.Expression; @@ -48,8 +50,6 @@ import ch.njol.util.Kleenean; import ch.njol.util.StringUtils; import ch.njol.util.coll.CollectionUtils; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.serializer.bungeecord.BungeeComponentSerializer; @Name("Sign Text") @Description("A line of text on a sign. Can be changed, but remember that there is a 16 character limit per line (including color codes that use 2 characters each).") @@ -60,16 +60,16 @@ "\tset line 3 to \"%player%\"" }) @Since("1.3, INSERT VERSION (all lines, back side, multiple blocks, and Skript's ChatFormat (hex, font, etc))") +@RequiredPlugins({ + "Paper 1.16+ required to use Skript ChatFormat", + "Spigot 1.20+ required to use the sign side" +}) public class ExprSignText extends SimpleExpression { + private static final boolean ADVENTURE = Skript.isRunningMinecraft(1, 16) && Skript.getServerPlatform() == ServerPlatform.BUKKIT_PAPER; private static final boolean RUNNING_1_20 = Skript.isRunningMinecraft(1, 20); - private static BungeeComponentSerializer serializer; static { - // Adventure API coming from Paper. - if (Skript.methodExists(SignChangeEvent.class, "lines")) - serializer = BungeeComponentSerializer.get(); - String addition = RUNNING_1_20 ? "[[on [the] (front|:back) side] of [sign[s]] %blocks%]" : "[of [sign[s]] %blocks%]"; Skript.registerExpression(ExprSignText.class, String.class, ExpressionType.PROPERTY, "[all [[of] the]|the] lines " + addition, @@ -201,9 +201,10 @@ public void change(Event event, @Nullable Object[] delta, ChangeMode mode) { if (lines) { for (int i = 0; i < 4; i++) { String value = stringDelta.length > i ? (String) stringDelta[i] : ""; - if (serializer != null) { + if (ADVENTURE) { + net.kyori.adventure.text.serializer.bungeecord.BungeeComponentSerializer serializer = net.kyori.adventure.text.serializer.bungeecord.BungeeComponentSerializer.get(); if (value.isEmpty()) // Reduce callings. - changeEvent.line(i, Component.empty()); + changeEvent.line(i, net.kyori.adventure.text.Component.empty()); changeEvent.line(i, serializer.deserialize(BungeeConverter.convert(ChatMessages.parseToArray(value)))); continue; } @@ -259,9 +260,10 @@ public void change(Event event, @Nullable Object[] delta, ChangeMode mode) { if (lines) { for (int i = 0; i < 4; i++) { String value = stringDelta.length > i ? (String) stringDelta[i] : ""; - if (serializer != null) { + if (ADVENTURE) { + net.kyori.adventure.text.serializer.bungeecord.BungeeComponentSerializer serializer = net.kyori.adventure.text.serializer.bungeecord.BungeeComponentSerializer.get(); if (value.isEmpty()) // Reduce callings. - sign.getSide(side).line(i, Component.empty()); + sign.getSide(side).line(i, net.kyori.adventure.text.Component.empty()); sign.getSide(side).line(i, serializer.deserialize(BungeeConverter.convert(ChatMessages.parseToArray(value)))); continue; } @@ -274,9 +276,10 @@ public void change(Event event, @Nullable Object[] delta, ChangeMode mode) { if (lines) { for (int i = 0; i < 4; i++) { String value = stringDelta.length > i ? (String) stringDelta[i] : ""; - if (serializer != null) { + if (ADVENTURE) { + net.kyori.adventure.text.serializer.bungeecord.BungeeComponentSerializer serializer = net.kyori.adventure.text.serializer.bungeecord.BungeeComponentSerializer.get(); if (value.isEmpty()) // Reduce callings. - sign.line(i, Component.empty()); + sign.line(i, net.kyori.adventure.text.Component.empty()); sign.line(i, serializer.deserialize(BungeeConverter.convert(ChatMessages.parseToArray(value)))); continue; } diff --git a/src/main/java/ch/njol/skript/util/Utils.java b/src/main/java/ch/njol/skript/util/Utils.java index 12255d4d8d6..bb645841007 100644 --- a/src/main/java/ch/njol/skript/util/Utils.java +++ b/src/main/java/ch/njol/skript/util/Utils.java @@ -198,8 +198,9 @@ public static Class[] getClasses(Plugin plugin, String basePackage, String... for (String c : classNames) { try { + System.out.println(c); classes.add(Class.forName(c, true, plugin.getClass().getClassLoader())); - } catch (ClassNotFoundException ex) { + } catch (ClassNotFoundException | NoClassDefFoundError ex) { Skript.exception(ex, "Cannot load class " + c); } catch (ExceptionInInitializerError err) { Skript.exception(err.getCause(), "class " + c + " generated an exception while loading"); From 6301ef228b23049956af70505659d5402f79592f Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Fri, 7 Jul 2023 13:26:04 -0600 Subject: [PATCH 04/13] Remove debug message --- .../ch/njol/skript/expressions/ExprLore.java | 2 +- .../njol/skript/expressions/ExprSignText.java | 22 +++++++++++++++++-- src/main/java/ch/njol/skript/util/Utils.java | 3 +-- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprLore.java b/src/main/java/ch/njol/skript/expressions/ExprLore.java index 9373166c6fe..9c2d9331b71 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprLore.java +++ b/src/main/java/ch/njol/skript/expressions/ExprLore.java @@ -236,7 +236,7 @@ public void change(final Event e, final @Nullable Object[] delta, final ChangeMo } } - public static String handleRemove(String input, String toRemove, boolean all) { + private String handleRemove(String input, String toRemove, boolean all) { if (SkriptConfig.caseSensitive.value()) { if (all) { return input.replace(toRemove, ""); diff --git a/src/main/java/ch/njol/skript/expressions/ExprSignText.java b/src/main/java/ch/njol/skript/expressions/ExprSignText.java index 52053f7aae7..b14c879ab0f 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprSignText.java +++ b/src/main/java/ch/njol/skript/expressions/ExprSignText.java @@ -20,6 +20,8 @@ import java.util.Arrays; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.stream.Stream; import org.bukkit.block.Block; @@ -33,6 +35,7 @@ import ch.njol.skript.ServerPlatform; import ch.njol.skript.Skript; +import ch.njol.skript.SkriptConfig; import ch.njol.skript.classes.Changer.ChangeMode; import ch.njol.skript.doc.Description; import ch.njol.skript.doc.Examples; @@ -187,7 +190,7 @@ public void change(Event event, @Nullable Object[] delta, ChangeMode mode) { case REMOVE: case REMOVE_ALL: assert stringDelta != null; - stringDelta = ExprLore.handleRemove(StringUtils.join(stringDelta, "\n"), stringDelta[0], mode == ChangeMode.REMOVE_ALL).split("\n"); + stringDelta = handleRemove(StringUtils.join(stringDelta, "\n"), stringDelta[0], mode == ChangeMode.REMOVE_ALL).split("\n"); //$FALL-THROUGH$ case DELETE: stringDelta = CollectionUtils.array("", "", "", ""); @@ -245,7 +248,7 @@ public void change(Event event, @Nullable Object[] delta, ChangeMode mode) { case REMOVE: case REMOVE_ALL: assert stringDelta != null; - stringDelta = ExprLore.handleRemove(StringUtils.join(stringDelta, "\n"), stringDelta[0], mode == ChangeMode.REMOVE_ALL).split("\n"); + stringDelta = handleRemove(StringUtils.join(stringDelta, "\n"), stringDelta[0], mode == ChangeMode.REMOVE_ALL).split("\n"); //$FALL-THROUGH$ case DELETE: stringDelta = CollectionUtils.array("", "", "", ""); @@ -295,6 +298,21 @@ public void change(Event event, @Nullable Object[] delta, ChangeMode mode) { }); } + private String handleRemove(String input, String toRemove, boolean all) { + if (SkriptConfig.caseSensitive.value()) { + if (all) { + return input.replace(toRemove, ""); + } else { + // .replaceFirst requires the regex to be quoted, .replace does it internally + return input.replaceFirst(Pattern.quote(toRemove), ""); + } + } else { + final Matcher m = Pattern.compile(Pattern.quote(toRemove), + Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE).matcher(input); + return all ? m.replaceAll("") : m.replaceFirst(""); + } + } + @Override public boolean setTime(int time) { return super.setTime(time, SignChangeEvent.class, blocks); diff --git a/src/main/java/ch/njol/skript/util/Utils.java b/src/main/java/ch/njol/skript/util/Utils.java index bb645841007..12255d4d8d6 100644 --- a/src/main/java/ch/njol/skript/util/Utils.java +++ b/src/main/java/ch/njol/skript/util/Utils.java @@ -198,9 +198,8 @@ public static Class[] getClasses(Plugin plugin, String basePackage, String... for (String c : classNames) { try { - System.out.println(c); classes.add(Class.forName(c, true, plugin.getClass().getClassLoader())); - } catch (ClassNotFoundException | NoClassDefFoundError ex) { + } catch (ClassNotFoundException ex) { Skript.exception(ex, "Cannot load class " + c); } catch (ExceptionInInitializerError err) { Skript.exception(err.getCause(), "class " + c + " generated an exception while loading"); From 0345a3f7c3c83718713a8fc9d5ce5899ebc35094 Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Fri, 7 Jul 2023 13:27:08 -0600 Subject: [PATCH 05/13] Attempt to fix error --- .../ch/njol/skript/expressions/ExprLore.java | 2 +- .../njol/skript/expressions/ExprSignText.java | 25 +++---------------- 2 files changed, 4 insertions(+), 23 deletions(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprLore.java b/src/main/java/ch/njol/skript/expressions/ExprLore.java index 9c2d9331b71..9373166c6fe 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprLore.java +++ b/src/main/java/ch/njol/skript/expressions/ExprLore.java @@ -236,7 +236,7 @@ public void change(final Event e, final @Nullable Object[] delta, final ChangeMo } } - private String handleRemove(String input, String toRemove, boolean all) { + public static String handleRemove(String input, String toRemove, boolean all) { if (SkriptConfig.caseSensitive.value()) { if (all) { return input.replace(toRemove, ""); diff --git a/src/main/java/ch/njol/skript/expressions/ExprSignText.java b/src/main/java/ch/njol/skript/expressions/ExprSignText.java index b14c879ab0f..0f3a7e0ff6d 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprSignText.java +++ b/src/main/java/ch/njol/skript/expressions/ExprSignText.java @@ -20,8 +20,6 @@ import java.util.Arrays; import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import java.util.stream.Stream; import org.bukkit.block.Block; @@ -33,9 +31,7 @@ import com.google.common.collect.Lists; -import ch.njol.skript.ServerPlatform; import ch.njol.skript.Skript; -import ch.njol.skript.SkriptConfig; import ch.njol.skript.classes.Changer.ChangeMode; import ch.njol.skript.doc.Description; import ch.njol.skript.doc.Examples; @@ -69,7 +65,7 @@ }) public class ExprSignText extends SimpleExpression { - private static final boolean ADVENTURE = Skript.isRunningMinecraft(1, 16) && Skript.getServerPlatform() == ServerPlatform.BUKKIT_PAPER; + private static final boolean ADVENTURE = Skript.classExists("net.kyori.adventure.text.Component"); private static final boolean RUNNING_1_20 = Skript.isRunningMinecraft(1, 20); static { @@ -190,7 +186,7 @@ public void change(Event event, @Nullable Object[] delta, ChangeMode mode) { case REMOVE: case REMOVE_ALL: assert stringDelta != null; - stringDelta = handleRemove(StringUtils.join(stringDelta, "\n"), stringDelta[0], mode == ChangeMode.REMOVE_ALL).split("\n"); + stringDelta = ExprLore.handleRemove(StringUtils.join(stringDelta, "\n"), stringDelta[0], mode == ChangeMode.REMOVE_ALL).split("\n"); //$FALL-THROUGH$ case DELETE: stringDelta = CollectionUtils.array("", "", "", ""); @@ -248,7 +244,7 @@ public void change(Event event, @Nullable Object[] delta, ChangeMode mode) { case REMOVE: case REMOVE_ALL: assert stringDelta != null; - stringDelta = handleRemove(StringUtils.join(stringDelta, "\n"), stringDelta[0], mode == ChangeMode.REMOVE_ALL).split("\n"); + stringDelta = ExprLore.handleRemove(StringUtils.join(stringDelta, "\n"), stringDelta[0], mode == ChangeMode.REMOVE_ALL).split("\n"); //$FALL-THROUGH$ case DELETE: stringDelta = CollectionUtils.array("", "", "", ""); @@ -298,21 +294,6 @@ public void change(Event event, @Nullable Object[] delta, ChangeMode mode) { }); } - private String handleRemove(String input, String toRemove, boolean all) { - if (SkriptConfig.caseSensitive.value()) { - if (all) { - return input.replace(toRemove, ""); - } else { - // .replaceFirst requires the regex to be quoted, .replace does it internally - return input.replaceFirst(Pattern.quote(toRemove), ""); - } - } else { - final Matcher m = Pattern.compile(Pattern.quote(toRemove), - Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE).matcher(input); - return all ? m.replaceAll("") : m.replaceFirst(""); - } - } - @Override public boolean setTime(int time) { return super.setTime(time, SignChangeEvent.class, blocks); From 60d4fd6705b6a20905998ae11e6f2708cdecad0a Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Fri, 7 Jul 2023 13:35:52 -0600 Subject: [PATCH 06/13] Fix error --- .../njol/skript/expressions/ExprSignText.java | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprSignText.java b/src/main/java/ch/njol/skript/expressions/ExprSignText.java index 0f3a7e0ff6d..8a94d19990f 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprSignText.java +++ b/src/main/java/ch/njol/skript/expressions/ExprSignText.java @@ -49,6 +49,7 @@ import ch.njol.util.Kleenean; import ch.njol.util.StringUtils; import ch.njol.util.coll.CollectionUtils; +import net.kyori.adventure.text.serializer.bungeecord.BungeeComponentSerializer; @Name("Sign Text") @Description("A line of text on a sign. Can be changed, but remember that there is a 16 character limit per line (including color codes that use 2 characters each).") @@ -60,12 +61,11 @@ }) @Since("1.3, INSERT VERSION (all lines, back side, multiple blocks, and Skript's ChatFormat (hex, font, etc))") @RequiredPlugins({ - "Paper 1.16+ required to use Skript ChatFormat", + "Paper 1.16+ or Adventure API installed to use Skript ChatFormat", "Spigot 1.20+ required to use the sign side" }) public class ExprSignText extends SimpleExpression { - private static final boolean ADVENTURE = Skript.classExists("net.kyori.adventure.text.Component"); private static final boolean RUNNING_1_20 = Skript.isRunningMinecraft(1, 20); static { @@ -78,6 +78,9 @@ public class ExprSignText extends SimpleExpression { "[the] (1¦1st|1¦first|2¦2nd|2¦second|3¦3rd|3¦third|4¦4th|4¦fourth) line[s] " + addition); } + @Nullable + private static BungeeComponentSerializer serializer; + @Nullable private Expression line; private Expression blocks; @@ -89,6 +92,8 @@ public class ExprSignText extends SimpleExpression { @Override @SuppressWarnings("unchecked") public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { + if (Skript.classExists("net.kyori.adventure.text.Component")) + serializer = BungeeComponentSerializer.get(); if (matchedPattern == 2) { line = (Expression) exprs[0]; } else if (matchedPattern == 3) { @@ -200,10 +205,7 @@ public void change(Event event, @Nullable Object[] delta, ChangeMode mode) { if (lines) { for (int i = 0; i < 4; i++) { String value = stringDelta.length > i ? (String) stringDelta[i] : ""; - if (ADVENTURE) { - net.kyori.adventure.text.serializer.bungeecord.BungeeComponentSerializer serializer = net.kyori.adventure.text.serializer.bungeecord.BungeeComponentSerializer.get(); - if (value.isEmpty()) // Reduce callings. - changeEvent.line(i, net.kyori.adventure.text.Component.empty()); + if (serializer != null) { changeEvent.line(i, serializer.deserialize(BungeeConverter.convert(ChatMessages.parseToArray(value)))); continue; } @@ -259,10 +261,7 @@ public void change(Event event, @Nullable Object[] delta, ChangeMode mode) { if (lines) { for (int i = 0; i < 4; i++) { String value = stringDelta.length > i ? (String) stringDelta[i] : ""; - if (ADVENTURE) { - net.kyori.adventure.text.serializer.bungeecord.BungeeComponentSerializer serializer = net.kyori.adventure.text.serializer.bungeecord.BungeeComponentSerializer.get(); - if (value.isEmpty()) // Reduce callings. - sign.getSide(side).line(i, net.kyori.adventure.text.Component.empty()); + if (serializer != null) { sign.getSide(side).line(i, serializer.deserialize(BungeeConverter.convert(ChatMessages.parseToArray(value)))); continue; } @@ -275,10 +274,7 @@ public void change(Event event, @Nullable Object[] delta, ChangeMode mode) { if (lines) { for (int i = 0; i < 4; i++) { String value = stringDelta.length > i ? (String) stringDelta[i] : ""; - if (ADVENTURE) { - net.kyori.adventure.text.serializer.bungeecord.BungeeComponentSerializer serializer = net.kyori.adventure.text.serializer.bungeecord.BungeeComponentSerializer.get(); - if (value.isEmpty()) // Reduce callings. - sign.line(i, net.kyori.adventure.text.Component.empty()); + if (serializer != null) { sign.line(i, serializer.deserialize(BungeeConverter.convert(ChatMessages.parseToArray(value)))); continue; } From 2252c7b858d34b8139e044abb323f473e56c16ce Mon Sep 17 00:00:00 2001 From: LimeGlass <16087552+TheLimeGlass@users.noreply.github.com> Date: Tue, 13 Feb 2024 21:51:42 -0700 Subject: [PATCH 07/13] Update BukkitClasses.java --- src/main/java/ch/njol/skript/classes/data/BukkitClasses.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/ch/njol/skript/classes/data/BukkitClasses.java b/src/main/java/ch/njol/skript/classes/data/BukkitClasses.java index b4ebdf96901..9c21f89b310 100644 --- a/src/main/java/ch/njol/skript/classes/data/BukkitClasses.java +++ b/src/main/java/ch/njol/skript/classes/data/BukkitClasses.java @@ -1526,7 +1526,7 @@ public String toVariableNameString(EnchantmentOffer eo) { .user("sign ?sides?") .name("Sign Sides") .description("Represents a side of a sign.") - .requiredPlugins("Spigot 1.20+") + .requiredPlugins("Spigot 1.20+")); } From 8385d0388e6674fc2f992719e3833869b4b916f5 Mon Sep 17 00:00:00 2001 From: LimeGlass <16087552+TheLimeGlass@users.noreply.github.com> Date: Wed, 14 Feb 2024 10:07:54 -0700 Subject: [PATCH 08/13] Update src/main/java/ch/njol/skript/expressions/ExprSignText.java Co-authored-by: Ayham Al Ali <20037329+AyhamAl-Ali@users.noreply.github.com> --- src/main/java/ch/njol/skript/expressions/ExprSignText.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprSignText.java b/src/main/java/ch/njol/skript/expressions/ExprSignText.java index 8a94d19990f..cf0ba54dbb0 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprSignText.java +++ b/src/main/java/ch/njol/skript/expressions/ExprSignText.java @@ -59,7 +59,7 @@ "\t\theal the player", "\tset line 3 to \"%player%\"" }) -@Since("1.3, INSERT VERSION (all lines, back side, multiple blocks, and Skript's ChatFormat (hex, font, etc))") +@Since("1.3, INSERT VERSION (all lines, back side, multiple blocks, Skript's ChatFormat (hex, font, etc))") @RequiredPlugins({ "Paper 1.16+ or Adventure API installed to use Skript ChatFormat", "Spigot 1.20+ required to use the sign side" From 9141b4919c1b62bb46bb3e8257eb9f5a9c1d17b2 Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Wed, 14 Feb 2024 13:15:51 -0700 Subject: [PATCH 09/13] Make a functional interface --- .../bukkitutil/AdventureSetSignLine.java | 36 +++ .../njol/skript/bukkitutil/HealthUtils.java | 2 +- .../java/ch/njol/skript/classes/Changer.java | 27 ++ .../ch/njol/skript/expressions/ExprLore.java | 30 +- .../njol/skript/expressions/ExprSignText.java | 260 +++++++++--------- .../syntaxes/expressions/ExprSignText.sk | 21 ++ 6 files changed, 232 insertions(+), 144 deletions(-) create mode 100644 src/main/java/ch/njol/skript/bukkitutil/AdventureSetSignLine.java create mode 100644 src/test/skript/tests/syntaxes/expressions/ExprSignText.sk diff --git a/src/main/java/ch/njol/skript/bukkitutil/AdventureSetSignLine.java b/src/main/java/ch/njol/skript/bukkitutil/AdventureSetSignLine.java new file mode 100644 index 00000000000..29f1bb33bcc --- /dev/null +++ b/src/main/java/ch/njol/skript/bukkitutil/AdventureSetSignLine.java @@ -0,0 +1,36 @@ +/** + * This file is part of Skript. + * + * Skript is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Skript is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Skript. If not, see . + * + * Copyright Peter Güttinger, SkriptLang team and contributors + */ +package ch.njol.skript.bukkitutil; + +import net.kyori.adventure.text.Component; + +/** + * A utility interface to access the Sign::line while also providing the same arguments to SignChangeEvent::line + * Used in ExprSignText. Separated due to static versioning. + */ +@FunctionalInterface +public interface AdventureSetSignLine { + + void line(int line, Component value); + + static void line(AdventureSetSignLine setLineMethod, int line, Component value) { + setLineMethod.line(line, value); + } + +} diff --git a/src/main/java/ch/njol/skript/bukkitutil/HealthUtils.java b/src/main/java/ch/njol/skript/bukkitutil/HealthUtils.java index 9af9012eb7f..51465600a64 100644 --- a/src/main/java/ch/njol/skript/bukkitutil/HealthUtils.java +++ b/src/main/java/ch/njol/skript/bukkitutil/HealthUtils.java @@ -109,7 +109,7 @@ public static void setDamage(EntityDamageEvent e, double damage) { } public static void setDamageCause(Damageable e, DamageCause cause) { - e.setLastDamageCause(new EntityDamageEvent(e, cause, 0)); + //e.setLastDamageCause(new EntityDamageEvent(e, cause, 0)); } } diff --git a/src/main/java/ch/njol/skript/classes/Changer.java b/src/main/java/ch/njol/skript/classes/Changer.java index d3b413531fe..853e1a22215 100644 --- a/src/main/java/ch/njol/skript/classes/Changer.java +++ b/src/main/java/ch/njol/skript/classes/Changer.java @@ -18,9 +18,13 @@ */ package ch.njol.skript.classes; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + import org.bukkit.event.Event; import org.eclipse.jdt.annotation.Nullable; +import ch.njol.skript.SkriptConfig; import ch.njol.skript.classes.data.DefaultChangers; import ch.njol.skript.lang.Expression; @@ -89,6 +93,29 @@ public static boolean acceptsChange(final Expression e, final ChangeMode mode } return false; } + + /** + * Handles removing string. The 'all' boolean is for if the ChangeMode is REMOVE_ALL + * + * @param input The String to modify. + * @param toRemove The value to remove from the input string. + * @param all If the ChangeMode is REMOVE_ALL or not + * @return Input formatted with the replacement. + */ + public static String handleStringRemove(String input, String toRemove, boolean all) { + if (SkriptConfig.caseSensitive.value()) { + if (all) { + return input.replace(toRemove, ""); + } else { + // .replaceFirst requires the regex to be quoted, .replace does it internally + return input.replaceFirst(Pattern.quote(toRemove), ""); + } + } else { + final Matcher m = Pattern.compile(Pattern.quote(toRemove), + Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE).matcher(input); + return all ? m.replaceAll("") : m.replaceFirst(""); + } + } } diff --git a/src/main/java/ch/njol/skript/expressions/ExprLore.java b/src/main/java/ch/njol/skript/expressions/ExprLore.java index 9373166c6fe..ee1a70a1cda 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprLore.java +++ b/src/main/java/ch/njol/skript/expressions/ExprLore.java @@ -31,6 +31,7 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.ApiStatus.ScheduledForRemoval; import ch.njol.skript.Skript; import ch.njol.skript.SkriptConfig; @@ -45,6 +46,7 @@ import ch.njol.skript.lang.ExpressionType; import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.skript.lang.util.SimpleExpression; +import ch.njol.util.Callback; import ch.njol.util.Kleenean; import ch.njol.util.Math2; import ch.njol.util.StringUtils; @@ -182,7 +184,7 @@ public void change(final Event e, final @Nullable Object[] delta, final ChangeMo case REMOVE: case REMOVE_ALL: assert stringDelta != null; - lore = Arrays.asList(handleRemove( + lore = Arrays.asList(ChangerUtils.handleStringRemove( StringUtils.join(lore, "\n"), stringDelta[0], mode == ChangeMode.REMOVE_ALL).split("\n")); break; case RESET: @@ -211,7 +213,7 @@ public void change(final Event e, final @Nullable Object[] delta, final ChangeMo case REMOVE: case REMOVE_ALL: assert stringDelta != null; - lore.set(lineNum, handleRemove(lore.get(lineNum), stringDelta[0], mode == ChangeMode.REMOVE_ALL)); + lore.set(lineNum, ChangerUtils.handleStringRemove(lore.get(lineNum), stringDelta[0], mode == ChangeMode.REMOVE_ALL)); break; case RESET: assert false; @@ -236,19 +238,19 @@ public void change(final Event e, final @Nullable Object[] delta, final ChangeMo } } + /** + * Handles removing string. The 'all' boolean is for if the ChangeMode is REMOVE_ALL + * + * @param input The String to modify. + * @param toRemove The value to remove from the input string. + * @param all If the ChangeMode is REMOVE_ALL or not + * @return Input formatted with the replacement. + * @deprecated Use {@link ChangerUtils#handleStringRemove(String, String, boolean)} + */ + @Deprecated + @ScheduledForRemoval public static String handleRemove(String input, String toRemove, boolean all) { - if (SkriptConfig.caseSensitive.value()) { - if (all) { - return input.replace(toRemove, ""); - } else { - // .replaceFirst requires the regex to be quoted, .replace does it internally - return input.replaceFirst(Pattern.quote(toRemove), ""); - } - } else { - final Matcher m = Pattern.compile(Pattern.quote(toRemove), - Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE).matcher(input); - return all ? m.replaceAll("") : m.replaceFirst(""); - } + return ChangerUtils.handleStringRemove(input, toRemove, all); } @Override diff --git a/src/main/java/ch/njol/skript/expressions/ExprSignText.java b/src/main/java/ch/njol/skript/expressions/ExprSignText.java index cf0ba54dbb0..99196af90f5 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprSignText.java +++ b/src/main/java/ch/njol/skript/expressions/ExprSignText.java @@ -25,20 +25,23 @@ import org.bukkit.block.Block; import org.bukkit.block.Sign; import org.bukkit.block.sign.Side; +import org.bukkit.block.sign.SignSide; import org.bukkit.event.Event; import org.bukkit.event.block.SignChangeEvent; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import com.google.common.collect.Lists; import ch.njol.skript.Skript; +import ch.njol.skript.bukkitutil.AdventureSetSignLine; import ch.njol.skript.classes.Changer.ChangeMode; +import ch.njol.skript.classes.Changer.ChangerUtils; import ch.njol.skript.doc.Description; import ch.njol.skript.doc.Examples; import ch.njol.skript.doc.Name; import ch.njol.skript.doc.RequiredPlugins; import ch.njol.skript.doc.Since; -import ch.njol.skript.effects.Delay; import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.ExpressionType; import ch.njol.skript.lang.SkriptParser.ParseResult; @@ -66,9 +69,13 @@ }) public class ExprSignText extends SimpleExpression { + @Nullable + private static BungeeComponentSerializer serializer; private static final boolean RUNNING_1_20 = Skript.isRunningMinecraft(1, 20); static { + if (Skript.isRunningMinecraft(1, 19, 4)) + serializer = BungeeComponentSerializer.get(); String addition = RUNNING_1_20 ? "[[on [the] (front|:back) side] of [sign[s]] %blocks%]" : "[of [sign[s]] %blocks%]"; Skript.registerExpression(ExprSignText.class, String.class, ExpressionType.PROPERTY, "[all [[of] the]|the] lines " + addition, @@ -78,32 +85,27 @@ public class ExprSignText extends SimpleExpression { "[the] (1¦1st|1¦first|2¦2nd|2¦second|3¦3rd|3¦third|4¦4th|4¦fourth) line[s] " + addition); } - @Nullable - private static BungeeComponentSerializer serializer; - @Nullable private Expression line; private Expression blocks; - private boolean lines; + private boolean multipleLines; @Nullable - private Side side; // Only nullable due to older versions than 1.20. + private Side side; // Nullable due to versions before 1.20. @Override @SuppressWarnings("unchecked") public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { - if (Skript.classExists("net.kyori.adventure.text.Component")) - serializer = BungeeComponentSerializer.get(); if (matchedPattern == 2) { line = (Expression) exprs[0]; } else if (matchedPattern == 3) { line = new SimpleLiteral<>(parseResult.mark, false); } else { - lines = true; + multipleLines = true; } if (RUNNING_1_20) side = parseResult.hasTag("back") ? Side.BACK : Side.FRONT; - blocks = (Expression) exprs[matchedPattern <= 1 ? 0 : 1]; + blocks = (Expression) exprs[matchedPattern != 2 ? 0 : 1]; return true; } @@ -111,15 +113,15 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye @Nullable protected String[] get(Event event) { int line = 0; - if (this.line == null && !lines) { + if (this.line == null && !multipleLines) { return new String[0]; - } else if (!lines) { - line = this.line.getOptionalSingle(event).orElse(1).intValue() - 1; + } else if (!multipleLines) { + line = this.line.getOptionalSingle(event).orElse(-1).intValue() - 1; if (line < 0 || line > 3) return new String[0]; } - if (getTime() >= 0 && event instanceof SignChangeEvent && !Delay.isDelayed(event)) { - if (lines) + if (getTime() >= 0 && event instanceof SignChangeEvent && blocks.check(event, block -> block.equals(((SignChangeEvent) event).getBlock()))) { + if (multipleLines) return ((SignChangeEvent) event).getLines(); return new String[] {((SignChangeEvent) event).getLine(line)}; } @@ -130,11 +132,11 @@ protected String[] get(Event event) { .map(Sign.class::cast) .flatMap(sign -> { if (RUNNING_1_20) { - if (lines) + if (multipleLines) return Arrays.stream(sign.getSide(side).getLines()); return Stream.of(sign.getSide(side).getLine(finalLine)); } - if (lines) + if (multipleLines) return Arrays.stream(sign.getLines()); return Stream.of(sign.getLine(finalLine)); }) @@ -149,11 +151,11 @@ public Class[] acceptChange(ChangeMode mode) { case REMOVE: case REMOVE_ALL: case DELETE: + case RESET: acceptsMany = false; case SET: case ADD: return CollectionUtils.array(acceptsMany ? String[].class : String.class); - case RESET: default: return null; } @@ -162,63 +164,20 @@ public Class[] acceptChange(ChangeMode mode) { @Override public void change(Event event, @Nullable Object[] delta, ChangeMode mode) { int line = 0; - if (this.line == null && !lines) { + if (this.line == null && !multipleLines) { return; - } else if (!lines) { - line = this.line.getOptionalSingle(event).orElse(1).intValue() - 1; + } else if (!multipleLines) { + line = this.line.getOptionalSingle(event).orElse(-1).intValue() - 1; if (line < 0 || line > 3) return; } - if (getTime() >= 0 && event instanceof SignChangeEvent && blocks.check(event, block -> block.equals(((SignChangeEvent) event).getBlock())) && !Delay.isDelayed(event)) { + if (getTime() >= 0 && event instanceof SignChangeEvent && blocks.check(event, block -> block.equals(((SignChangeEvent) event).getBlock()))) { String[] stringDelta = delta == null ? null : Arrays.copyOf(delta, delta.length, String[].class); SignChangeEvent changeEvent = (SignChangeEvent) event; - switch (mode) { - case ADD: - assert stringDelta != null; - if (lines) { - List list = Lists.newArrayList(changeEvent.getLines()); - for (String string : stringDelta) - list.add(string); - - stringDelta = list.toArray(new String[0]); - } else { - for (int i = 0; i < stringDelta.length; i++) { - String value = stringDelta.length > i ? (String) delta[i] : ""; - stringDelta[i] = value + stringDelta[i]; - } - } - //$FALL-THROUGH$ - case REMOVE: - case REMOVE_ALL: - assert stringDelta != null; - stringDelta = ExprLore.handleRemove(StringUtils.join(stringDelta, "\n"), stringDelta[0], mode == ChangeMode.REMOVE_ALL).split("\n"); - //$FALL-THROUGH$ - case DELETE: - stringDelta = CollectionUtils.array("", "", "", ""); - case SET: - // We need to ensure that it's clearing values without calling setLine twice. - if (mode == ChangeMode.SET) { - for (int i = 0; i < 4; i++) - stringDelta[i] = stringDelta.length > i ? (String) stringDelta[i] : ""; - } - assert stringDelta != null; - if (lines) { - for (int i = 0; i < 4; i++) { - String value = stringDelta.length > i ? (String) stringDelta[i] : ""; - if (serializer != null) { - changeEvent.line(i, serializer.deserialize(BungeeConverter.convert(ChatMessages.parseToArray(value)))); - continue; - } - changeEvent.setLine(i, value); - } - break; - } - changeEvent.setLine(line, (String) delta[0]); - break; - default: - break; - } - return; + AdventureSetSignLine ADVENTURE_SET_LINE = null; + if (serializer != null) + ADVENTURE_SET_LINE = changeEvent::line; + change(mode, changeEvent::getLines, changeEvent::getLine, changeEvent::setLine, ADVENTURE_SET_LINE, line, stringDelta); } int finalLine = line; blocks.stream(event) @@ -226,70 +185,83 @@ public void change(Event event, @Nullable Object[] delta, ChangeMode mode) { .filter(Sign.class::isInstance) .map(Sign.class::cast) .forEach(sign -> { - String[] stringDelta = delta == null ? null : Arrays.copyOf(delta, delta.length, String[].class); - switch (mode) { - case ADD: - assert stringDelta != null; - if (lines) { - List list = Lists.newArrayList(sign.getLines()); - for (String string : stringDelta) - list.add(string); - - stringDelta = list.toArray(new String[0]); - } else { - for (int i = 0; i < stringDelta.length; i++) { - String value = stringDelta.length > i ? (String) delta[i] : ""; - stringDelta[i] = value + stringDelta[i]; - } - } - //$FALL-THROUGH$ - case REMOVE: - case REMOVE_ALL: - assert stringDelta != null; - stringDelta = ExprLore.handleRemove(StringUtils.join(stringDelta, "\n"), stringDelta[0], mode == ChangeMode.REMOVE_ALL).split("\n"); - //$FALL-THROUGH$ - case DELETE: - stringDelta = CollectionUtils.array("", "", "", ""); - case SET: - // We need to ensure that it's clearing values without calling setLine twice. - if (mode == ChangeMode.SET) { - for (int i = 0; i < 4; i++) - stringDelta[i] = stringDelta.length > i ? (String) stringDelta[i] : ""; - } - assert stringDelta != null; - if (RUNNING_1_20) { - if (lines) { - for (int i = 0; i < 4; i++) { - String value = stringDelta.length > i ? (String) stringDelta[i] : ""; - if (serializer != null) { - sign.getSide(side).line(i, serializer.deserialize(BungeeConverter.convert(ChatMessages.parseToArray(value)))); - continue; - } - sign.setLine(i, value); - } - } - sign.setLine(finalLine, (String) delta[0]); - break; - } - if (lines) { - for (int i = 0; i < 4; i++) { - String value = stringDelta.length > i ? (String) stringDelta[i] : ""; - if (serializer != null) { - sign.line(i, serializer.deserialize(BungeeConverter.convert(ChatMessages.parseToArray(value)))); - continue; - } - sign.setLine(i, value); - } - } - sign.setLine(finalLine, (String) delta[0]); - break; - default: - break; + String[] strings = delta == null ? null : Arrays.copyOf(delta, delta.length, String[].class); + AdventureSetSignLine ADVENTURE_SET_LINE = null; + if (serializer != null) + ADVENTURE_SET_LINE = sign::line; + if (RUNNING_1_20) { + SignSide side = sign.getSide(this.side); + if (serializer != null) + ADVENTURE_SET_LINE = side::line; + change(mode, side::getLines, side::getLine, side::setLine, ADVENTURE_SET_LINE, finalLine, strings); + } else { + change(mode, sign::getLines, sign::getLine, sign::setLine, ADVENTURE_SET_LINE, finalLine, strings); } sign.update(true, false); }); } + /** + * Functional interface method to allow for getLines, getLines(int), setLine(int, String), line(int Component) on Sign, SignChangeEvent and SignSide + */ + private void change(ChangeMode mode, GetSignLines GET_LINES, GetSignLine GET_LINE, SetSignLine SET_LINE, @Nullable AdventureSetSignLine ADVENTURE_SET_LINE, int line, String... strings) { + switch (mode) { + case ADD: + List list = Lists.newArrayList(GetSignLines.getLines(GET_LINES)); + if (multipleLines) { + int last = -1; // Last white space character. + for (int i = 3; i >= 0; i--) { + if (list.get(i).trim().isEmpty()) { + last = i; + } else { + break; + } + } + if (last < 0) + return; + int index = 0; + for (int i = last; i < 4; i++) { + if (index > strings.length - 1) + continue; + list.set(last, strings[index++]); + } + + strings = list.toArray(new String[0]); + change(ChangeMode.SET, GET_LINES, GET_LINE, SET_LINE, ADVENTURE_SET_LINE, line, strings); + } else { +// list.set(line, GetSignLine.getLine(GET_LINE, line) + StringUtils.join(strings)); +// strings = list.toArray(new String[0]); +// multipleLines = true; + change(ChangeMode.SET, GET_LINES, GET_LINE, SET_LINE, ADVENTURE_SET_LINE, line, GetSignLine.getLine(GET_LINE, line) + StringUtils.join(strings)); + } + break; + case RESET: + case DELETE: + change(ChangeMode.SET, GET_LINES, GET_LINE, SET_LINE, ADVENTURE_SET_LINE, line, CollectionUtils.array("", "", "", "")); + break; + case REMOVE: + case REMOVE_ALL: + strings = ChangerUtils.handleStringRemove(StringUtils.join(strings, "\n"), strings[0], mode == ChangeMode.REMOVE_ALL).split("\n"); + //$FALL-THROUGH$ + case SET: + if (multipleLines) { + for (int i = 0; i < 4; i++) { + String value = strings.length > i ? (String) strings[i] : ""; + if (serializer != null && ADVENTURE_SET_LINE != null) { + AdventureSetSignLine.line(ADVENTURE_SET_LINE, i, serializer.deserialize(BungeeConverter.convert(ChatMessages.parseToArray(value)))); + continue; + } + SetSignLine.setLine(SET_LINE, i, value); + } + break; + } + SetSignLine.setLine(SET_LINE, line, (String) strings[0]); + break; + default: + break; + } + } + @Override public boolean setTime(int time) { return super.setTime(time, SignChangeEvent.class, blocks); @@ -297,7 +269,7 @@ public boolean setTime(int time) { @Override public boolean isSingle() { - return !lines; + return !multipleLines; } @Override @@ -312,4 +284,34 @@ public String toString(@Nullable Event event, boolean debug) { return "line " + line.toString(event, debug) + " of " + blocks.toString(event, debug); } + @FunctionalInterface + private interface SetSignLine { + + void setLine(int line, @NotNull String value); + + static void setLine(SetSignLine setLineMethod, int line, String value) { + setLineMethod.setLine(line, value); + } + } + + @FunctionalInterface + private interface GetSignLine { + + String getLine(int line); + + static String getLine(GetSignLine getLineMethod, int line) { + return getLineMethod.getLine(line); + } + } + + @FunctionalInterface + private interface GetSignLines { + + String[] getLines(); + + static String[] getLines(GetSignLines getLinesMethod) { + return getLinesMethod.getLines(); + } + } + } diff --git a/src/test/skript/tests/syntaxes/expressions/ExprSignText.sk b/src/test/skript/tests/syntaxes/expressions/ExprSignText.sk new file mode 100644 index 00000000000..e3507e23f85 --- /dev/null +++ b/src/test/skript/tests/syntaxes/expressions/ExprSignText.sk @@ -0,0 +1,21 @@ +test "set sign text and color" when running minecraft "1.18": + set event-block to an oak sign + set line 1 of event-block to "&aTesting" + assert line 1 of event-block is "&aTesting" with "Failed to test colored text on 1.18 index 1" + set the event-block to air + +test "set front and back side sign text and hex color" when running minecraft "1.20": + set event-block to an oak sign + set line 1 on the back side of event-block to "<##00ff00>Testing" + assert line 1 on the back side of event-block is "<##00ff00>Testing" with "Failed to test hex color on the back side of a sign" + set line 4 on the back side of event-block to "Testing Spaces" + assert the first element out of lines on the back side of event-block is "<##00ff00>Testing" with "Failed to test against multiple lines ##1" + assert the last element out of lines on the back side of event-block is "Testing Spaces" with "Failed to test against multiple lines ##2" + set line 3 of event-block to "&aTesting" + assert line 3 on the front side of event-block is "&aTesting" with "Failed to test color on the front side of a sign" + add "<##00ff00>Front" to the lines of event-block + assert the last element out of lines on the front side of event-block is "<##00ff00>Front" with "Failed to test against adding hex colored line" + add " <##800080>Hex " to the fourth line of event-block + set {_t} to the last element out of lines on the front side of event-block + assert the last element out of lines on the front side of event-block is "<##00ff00>Front <##800080>Hex " with "Failed to test with appending hex and trim tricking '%{_t}%'" + set the event-block to air From 2776bd15781624c761072826b6b39b5c96754b37 Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Wed, 14 Feb 2024 13:16:27 -0700 Subject: [PATCH 10/13] Re-add broken compile --- src/main/java/ch/njol/skript/bukkitutil/HealthUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/ch/njol/skript/bukkitutil/HealthUtils.java b/src/main/java/ch/njol/skript/bukkitutil/HealthUtils.java index 51465600a64..9af9012eb7f 100644 --- a/src/main/java/ch/njol/skript/bukkitutil/HealthUtils.java +++ b/src/main/java/ch/njol/skript/bukkitutil/HealthUtils.java @@ -109,7 +109,7 @@ public static void setDamage(EntityDamageEvent e, double damage) { } public static void setDamageCause(Damageable e, DamageCause cause) { - //e.setLastDamageCause(new EntityDamageEvent(e, cause, 0)); + e.setLastDamageCause(new EntityDamageEvent(e, cause, 0)); } } From 922fb2a37b19f8b270f85342cdceefb31dcb46f9 Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Wed, 14 Feb 2024 13:17:43 -0700 Subject: [PATCH 11/13] Remove debug --- src/main/java/ch/njol/skript/expressions/ExprSignText.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprSignText.java b/src/main/java/ch/njol/skript/expressions/ExprSignText.java index 99196af90f5..f5f293df07a 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprSignText.java +++ b/src/main/java/ch/njol/skript/expressions/ExprSignText.java @@ -229,9 +229,6 @@ private void change(ChangeMode mode, GetSignLines GET_LINES, GetSignLine Date: Wed, 14 Feb 2024 17:32:32 -0700 Subject: [PATCH 12/13] Remove deprecated method --- .../java/ch/njol/skript/expressions/ExprLore.java | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprLore.java b/src/main/java/ch/njol/skript/expressions/ExprLore.java index ee1a70a1cda..3ae8e2cd918 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprLore.java +++ b/src/main/java/ch/njol/skript/expressions/ExprLore.java @@ -238,21 +238,6 @@ public void change(final Event e, final @Nullable Object[] delta, final ChangeMo } } - /** - * Handles removing string. The 'all' boolean is for if the ChangeMode is REMOVE_ALL - * - * @param input The String to modify. - * @param toRemove The value to remove from the input string. - * @param all If the ChangeMode is REMOVE_ALL or not - * @return Input formatted with the replacement. - * @deprecated Use {@link ChangerUtils#handleStringRemove(String, String, boolean)} - */ - @Deprecated - @ScheduledForRemoval - public static String handleRemove(String input, String toRemove, boolean all) { - return ChangerUtils.handleStringRemove(input, toRemove, all); - } - @Override public boolean isSingle() { return lineNumber != null; From 69c9e6eb11b3e32c392ccb1c8e486b3e040829e5 Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Sat, 31 Aug 2024 08:58:10 -0600 Subject: [PATCH 13/13] Apply changes --- skript-aliases | 2 +- src/main/java/ch/njol/skript/classes/data/BukkitClasses.java | 2 +- .../java/ch/njol/skript/classes/data/BukkitEventValues.java | 1 - src/main/java/ch/njol/skript/expressions/ExprSignText.java | 3 ++- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/skript-aliases b/skript-aliases index c6a515a9e4e..16949c28e0d 160000 --- a/skript-aliases +++ b/skript-aliases @@ -1 +1 @@ -Subproject commit c6a515a9e4e249c2859f4cc2992bf0da559b63cc +Subproject commit 16949c28e0d7bb25ea7c3479c3d6754ff3b5a3e6 diff --git a/src/main/java/ch/njol/skript/classes/data/BukkitClasses.java b/src/main/java/ch/njol/skript/classes/data/BukkitClasses.java index 7098d194f9d..34bd4a89a12 100644 --- a/src/main/java/ch/njol/skript/classes/data/BukkitClasses.java +++ b/src/main/java/ch/njol/skript/classes/data/BukkitClasses.java @@ -1550,7 +1550,7 @@ public String toVariableNameString(EnchantmentOffer eo) { .description("Represents a transform reason of an entity transform event.") .since("2.8.0")); - if (Skript.isRunningMinecraft(1, 20)) + if (Skript.isRunningMinecraft(1, 20)) Classes.registerClass(new EnumClassInfo<>(Side.class, "signside", "sign sides") .user("sign ?sides?") .name("Sign Sides") diff --git a/src/main/java/ch/njol/skript/classes/data/BukkitEventValues.java b/src/main/java/ch/njol/skript/classes/data/BukkitEventValues.java index 919d4b64b79..49b33110dc8 100644 --- a/src/main/java/ch/njol/skript/classes/data/BukkitEventValues.java +++ b/src/main/java/ch/njol/skript/classes/data/BukkitEventValues.java @@ -469,7 +469,6 @@ public String[] get(SignChangeEvent event) { if (Skript.isRunningMinecraft(1, 20)) EventValues.registerEventValue(SignChangeEvent.class, Side.class, new Getter() { @Override - @Nullable public Side get(SignChangeEvent event) { return event.getSide(); } diff --git a/src/main/java/ch/njol/skript/expressions/ExprSignText.java b/src/main/java/ch/njol/skript/expressions/ExprSignText.java index f5f293df07a..6939d1c02ab 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprSignText.java +++ b/src/main/java/ch/njol/skript/expressions/ExprSignText.java @@ -47,6 +47,7 @@ import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.skript.lang.util.SimpleExpression; import ch.njol.skript.lang.util.SimpleLiteral; +import ch.njol.skript.registrations.EventValues; import ch.njol.skript.util.chat.BungeeConverter; import ch.njol.skript.util.chat.ChatMessages; import ch.njol.util.Kleenean; @@ -120,7 +121,7 @@ protected String[] get(Event event) { if (line < 0 || line > 3) return new String[0]; } - if (getTime() >= 0 && event instanceof SignChangeEvent && blocks.check(event, block -> block.equals(((SignChangeEvent) event).getBlock()))) { + if (getTime() >= EventValues.TIME_PAST && event instanceof SignChangeEvent && blocks.check(event, block -> block.equals(((SignChangeEvent) event).getBlock()))) { if (multipleLines) return ((SignChangeEvent) event).getLines(); return new String[] {((SignChangeEvent) event).getLine(line)};