From e3a0ed619798af198575439fdf29f4bd89de7a31 Mon Sep 17 00:00:00 2001 From: Fusezion Date: Sun, 23 Mar 2025 09:50:54 -0400 Subject: [PATCH 1/7] ExprLore.java - Rewrite File --- .../ch/njol/skript/expressions/ExprLore.java | 315 ++++++++---------- 1 file changed, 133 insertions(+), 182 deletions(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprLore.java b/src/main/java/ch/njol/skript/expressions/ExprLore.java index 7b4c26361cf..c92152f0b61 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprLore.java +++ b/src/main/java/ch/njol/skript/expressions/ExprLore.java @@ -1,236 +1,183 @@ package ch.njol.skript.expressions; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.event.Event; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; -import org.jetbrains.annotations.Nullable; - import ch.njol.skript.Skript; -import ch.njol.skript.SkriptConfig; import ch.njol.skript.aliases.ItemType; +import ch.njol.skript.bukkitutil.ItemUtils; 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.Since; +import ch.njol.skript.doc.*; import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.ExpressionType; import ch.njol.skript.lang.SkriptParser.ParseResult; +import ch.njol.skript.lang.SyntaxStringBuilder; import ch.njol.skript.lang.util.SimpleExpression; import ch.njol.util.Kleenean; -import ch.njol.util.Math2; -import ch.njol.util.StringUtils; import ch.njol.util.coll.CollectionUtils; +import org.bukkit.event.Event; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.jaxen.expr.Expr; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; /** * TODO make a 'line %number% of %text%' expression and figure out how to deal with signs (4 lines, delete = empty, etc...) - * - * @author joeuguce99 */ @Name("Lore") @Description("An item's lore.") +@Example(""" + set {_item} to diamond named "Bling Diamond" with lore "&bThe blingiest of diamonds" + add "With extra steps" to lore of {_item} + remove line 1 of lore of {_item} from lore of {_item} + set line 3 of lore of {_item} to "-----" + """) @Examples("set the 1st line of the item's lore to \"<orange>Excalibur 2.0\"") @Since("2.1") public class ExprLore extends SimpleExpression { + private static final boolean IS_RUNNING_1_21_5 = Skript.isRunningMinecraft(1,21,5); + static { - Skript.registerExpression(ExprLore.class, String.class, ExpressionType.PROPERTY, - "[the] lore of %itemstack/itemtype%", "%itemstack/itemtype%'[s] lore", - "[the] line %number% of [the] lore of %itemstack/itemtype%", - "[the] line %number% of %itemstack/itemtype%'[s] lore", - "[the] %number%(st|nd|rd|th) line of [the] lore of %itemstack/itemtype%", - "[the] %number%(st|nd|rd|th) line of %itemstack/itemtype%'[s] lore"); + Skript.registerExpression(ExprLore.class, String.class, ExpressionType.PROPERTY, + "[the] lore of %itemstack/itemtype%", + "%itemstack/itemtype%'[s] lore", + "[the] line %number% of [the] lore of %itemstack/itemtype%", + "[the] line %number% of %itemstack/itemtype%'[s] lore", + "[the] %number%(st|nd|rd|th) line of [the] lore of %itemstack/itemtype%", + "[the] %number%(st|nd|rd|th) line of %itemstack/itemtype%'[s] lore"); } - @Nullable - private Expression lineNumber; - - @SuppressWarnings("null") + private @Nullable Expression lineNumber; private Expression item; - @SuppressWarnings({"unchecked", "null"}) @Override - public boolean init(final Expression[] exprs, final int matchedPattern, final Kleenean isDelayed, final ParseResult parseResult) { + public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { + //noinspection unchecked lineNumber = exprs.length > 1 ? (Expression) exprs[0] : null; item = exprs[exprs.length - 1]; return true; } @Override - @Nullable - protected String[] get(final Event e) { - final Object i = item.getSingle(e); - final Number n = lineNumber != null ? lineNumber.getSingle(e) : null; - if (n == null && lineNumber != null) + protected String @Nullable [] get(Event event) { + if (!validateItem(item.getSingle(event))) + return null; + ItemStack itemStack = ItemUtils.asItemStack(item.getSingle(event)); + assert itemStack != null; // Validated in validateItem + ItemMeta itemMeta = itemStack.getItemMeta(); + //noinspection deprecation + List itemLore = itemMeta.getLore(); + if (itemLore == null || itemLore.isEmpty()) return null; - if (i == null || i instanceof ItemStack && ((ItemStack) i).getType() == Material.AIR) - return new String[0]; - final ItemMeta meta = i instanceof ItemStack ? ((ItemStack) i).getItemMeta() : (ItemMeta) ((ItemType) i).getItemMeta(); - if (meta == null || !meta.hasLore()) - return new String[0]; - final List lore = meta.getLore(); - assert lore != null; // hasLore() called before - if (n == null) - return lore.toArray(new String[0]); - final int l = n.intValue() - 1; - if (l < 0 || l >= lore.size()) - return new String[0]; - return new String[]{lore.get(l)}; - } - @Override - @Nullable - public Class[] acceptChange(final ChangeMode mode) { - boolean acceptsMany = lineNumber == null; - switch (mode) { - case REMOVE: - case REMOVE_ALL: - case DELETE: - acceptsMany = false; - case SET: - case ADD: - if (ChangerUtils.acceptsChange(item, ChangeMode.SET, ItemStack.class, ItemType.class)) { - return CollectionUtils.array(acceptsMany ? String[].class : String.class); - } - return null; - case RESET: - default: - return null; + if (lineNumber == null) { + return itemLore.toArray(String[]::new); + } + + int loreIndex = this.lineNumber.getOptionalSingle(event).orElse(0).intValue() -1; + if (loreIndex < 0 || loreIndex >= itemLore.size()) { + return null; } + return new String[]{itemLore.get(loreIndex)}; } @Override - public void change(final Event e, final @Nullable Object[] delta, final ChangeMode mode) throws UnsupportedOperationException { - Object i = item.getSingle(e); - - String[] stringDelta = delta == null ? null : Arrays.copyOf(delta, delta.length, String[].class); - - // air is just nothing, it can't have a lore - if (i == null || i instanceof ItemStack && ((ItemStack) i).getType() == Material.AIR) - return; - - ItemMeta meta = i instanceof ItemStack ? ((ItemStack) i).getItemMeta() : (ItemMeta) ((ItemType) i).getItemMeta(); - if (meta == null) - meta = Bukkit.getItemFactory().getItemMeta(Material.STONE); - - Number lineNumber = this.lineNumber != null ? this.lineNumber.getSingle(e) : null; - List lore = meta.hasLore() ? new ArrayList<>(meta.getLore()) : new ArrayList<>(); - - if (lineNumber == null) { - // if the condition below is true, the pattern with the line %number% expression was used, - // but the line number turned out to be null at runtime, meaning we should ignore it - if (this.lineNumber != null) { - return; + public Class @Nullable [] acceptChange(ChangeMode mode) { + boolean acceptsMany = this.lineNumber == null; + return switch (mode) { + case SET -> CollectionUtils.array(acceptsMany ? String[].class : String.class); + case DELETE -> CollectionUtils.array(); + case ADD, REMOVE, REMOVE_ALL -> { + // this should not accept remove "hello" from line 1 of lore of player's tool + // users should instead use replace "hello" in line 1 of lore of player's tool + if (!acceptsMany) { + Skript.error("You cannot remove/add lore to a single line, you can however replace/concat lore within a line."); + yield null; + } + yield CollectionUtils.array(String[].class); } + default -> null; + }; +// TODO: see if this method is required, should only limit ability to use event-item which isn't necessary and just falsely limits Skript +// if (ChangerUtils.acceptsChange(item, ChangeMode.SET, ItemStack.class, ItemType.class)) { +// return CollectionUtils.array(acceptsMany ? String[].class : String.class); +// } + } + @Override + public void change(Event event, Object @Nullable [] delta, ChangeMode mode) { + Object item = this.item.getSingle(event); + if (!validateItem(item)) + return; // Validates to ensure it is a valid item, has item meta, + ItemStack modifiedItem = ItemUtils.asItemStack(item); + assert modifiedItem != null; // validateItem has already run a check against this + ItemMeta itemMeta = modifiedItem.getItemMeta(); +// noinspection deprecation + List modifiedLore = itemMeta.hasLore() ? itemMeta.getLore() : new ArrayList<>(); + assert modifiedLore != null; // lore can never be null here, if it's unset we create an empty list + + if (this.lineNumber == null) { switch (mode) { - case SET: - assert stringDelta != null; - List newLore = new ArrayList<>(); - for (String line : stringDelta) { - if (line.contains("\n")) { - Collections.addAll(newLore, line.split("\n")); - continue; - } - newLore.add(line); - } - lore = newLore; - break; - case ADD: - assert stringDelta != null; - List addLore = new ArrayList<>(); - for (String line : stringDelta) { - if (line.contains("\n")) { - Collections.addAll(addLore, line.split("\n")); - continue; - } - addLore.add(line); + case SET, DELETE -> modifiedLore = (delta != null) ? List.of((String[]) delta) : null; + case ADD -> { + assert delta != null; + modifiedLore.addAll(List.of((String[]) delta)); + } + case REMOVE, REMOVE_ALL -> { + boolean isAll = mode == ChangeMode.REMOVE_ALL; + if (isAll) { + //noinspection DataFlowIssue + modifiedLore.removeAll(List.of((String[]) delta)); + } else { + //noinspection DataFlowIssue + for (String string : (String[]) delta) + modifiedLore.remove(string); } - lore.addAll(addLore); - break; - case DELETE: - lore = null; - break; - case REMOVE: - case REMOVE_ALL: - assert stringDelta != null; - lore = Arrays.asList(handleRemove( - StringUtils.join(lore, "\n"), stringDelta[0], mode == ChangeMode.REMOVE_ALL).split("\n")); - break; - case RESET: - assert false; - return; + } } } else { - // Note: line number is changed from one-indexed to zero-indexed here - int lineNum = Math2.fit(0, lineNumber.intValue() - 1, 99); // TODO figure out the actual maximum - - // Fill in the empty lines above the line being set with empty strings (avoids index out of bounds) - while (lore.size() <= lineNum) - lore.add(""); + int loreIndex = this.lineNumber.getOptionalSingle(event).orElse(0).intValue() -1; + if (loreIndex < 0) + return; // Cannot change anything in lore if it's negative, therefor we return switch (mode) { - case SET: - assert stringDelta != null; - lore.set(lineNum, stringDelta[0]); - break; - case ADD: - assert stringDelta != null; - lore.set(lineNum, lore.get(lineNum) + stringDelta[0]); - break; - case DELETE: - lore.remove(lineNum); - break; - case REMOVE: - case REMOVE_ALL: - assert stringDelta != null; - lore.set(lineNum, handleRemove(lore.get(lineNum), stringDelta[0], mode == ChangeMode.REMOVE_ALL)); - break; - case RESET: - assert false; - return; + case SET -> { + for (int line = modifiedLore.size()-1; line < loreIndex; line++) { + modifiedLore.add(""); + } + //noinspection DataFlowIssue + modifiedLore.set(loreIndex, (String) delta[0]); + } + case DELETE -> { + if (loreIndex > modifiedLore.size() || !itemMeta.hasLore()) + return; // Cannot change anything in lore, therefor we return + modifiedLore.remove(loreIndex); + } } } - meta.setLore(lore == null || lore.size() == 0 ? null : lore); - if (i instanceof ItemStack) { - ((ItemStack) i).setItemMeta(meta); - } else { - ((ItemType) i).setItemMeta(meta); + if (modifiedLore != null && !modifiedLore.isEmpty()) { + if (IS_RUNNING_1_21_5) { + // The maximum amount of lore an item can have is 256 + // this change was made in 1.21.5, was unable to find the source for older versions + // source: https://minecraft.wiki/w/Data_component_format#lore + modifiedLore = modifiedLore.stream().limit(256).toList(); + } else { + modifiedLore = modifiedLore.stream().limit(99).toList(); + } } - - if (ChangerUtils.acceptsChange(item, ChangeMode.SET, i.getClass())) { - Object[] itemDelta = i instanceof ItemStack ? new ItemStack[]{(ItemStack) i} : new ItemType[]{(ItemType) i}; - item.change(e, itemDelta, ChangeMode.SET); - } else { - Object[] itemDelta = i instanceof ItemStack ? new ItemType[]{new ItemType((ItemStack) i)} : - new ItemStack[]{((ItemType) i).getRandom()}; - item.change(e, itemDelta, ChangeMode.SET); + //noinspection deprecation + itemMeta.setLore(modifiedLore); + if (item instanceof ItemType itemType) { + itemType.setItemMeta(itemMeta); + } else if (item instanceof ItemStack itemStack) { + itemStack.setItemMeta(itemMeta); } } - 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(""); - } + private boolean validateItem(Object item) { + ItemStack itemStack = ItemUtils.asItemStack(item); + return itemStack != null && itemStack.hasItemMeta(); } @Override @@ -244,7 +191,11 @@ public Class getReturnType() { } @Override - public String toString(final @Nullable Event e, final boolean debug) { - return (lineNumber != null ? "the line " + lineNumber.toString(e, debug) + " of " : "") + "the lore of " + item.toString(e, debug); + public String toString(@Nullable Event event, boolean debug) { + SyntaxStringBuilder syntaxBuilder = new SyntaxStringBuilder(event, debug); + if (lineNumber != null) + return syntaxBuilder.append("line", lineNumber, "of the lore of", item).toString(); + return syntaxBuilder.append("the lore of", item).toString(); } + } From 5a02b5a8170bf21503916d55296a68724af9d31b Mon Sep 17 00:00:00 2001 From: Fusezion Date: Sun, 23 Mar 2025 11:42:53 -0400 Subject: [PATCH 2/7] ExprLore.java - Fix hasItemMeta issue --- .../java/ch/njol/skript/expressions/ExprLore.java | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprLore.java b/src/main/java/ch/njol/skript/expressions/ExprLore.java index c92152f0b61..35df54e10d5 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprLore.java +++ b/src/main/java/ch/njol/skript/expressions/ExprLore.java @@ -15,7 +15,6 @@ import org.bukkit.event.Event; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; -import org.jaxen.expr.Expr; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; @@ -89,10 +88,8 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye case SET -> CollectionUtils.array(acceptsMany ? String[].class : String.class); case DELETE -> CollectionUtils.array(); case ADD, REMOVE, REMOVE_ALL -> { - // this should not accept remove "hello" from line 1 of lore of player's tool - // users should instead use replace "hello" in line 1 of lore of player's tool if (!acceptsMany) { - Skript.error("You cannot remove/add lore to a single line, you can however replace/concat lore within a line."); + Skript.error("You cannot add/remove the lore from a single line, you can however replace/concat lore."); yield null; } yield CollectionUtils.array(String[].class); @@ -109,7 +106,7 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye public void change(Event event, Object @Nullable [] delta, ChangeMode mode) { Object item = this.item.getSingle(event); if (!validateItem(item)) - return; // Validates to ensure it is a valid item, has item meta, + return; // Validates to ensure it is a valid item and has item meta. ItemStack modifiedItem = ItemUtils.asItemStack(item); assert modifiedItem != null; // validateItem has already run a check against this ItemMeta itemMeta = modifiedItem.getItemMeta(); @@ -159,7 +156,7 @@ public void change(Event event, Object @Nullable [] delta, ChangeMode mode) { if (modifiedLore != null && !modifiedLore.isEmpty()) { if (IS_RUNNING_1_21_5) { // The maximum amount of lore an item can have is 256 - // this change was made in 1.21.5, was unable to find the source for older versions + // this change was made in 1.21.5 // source: https://minecraft.wiki/w/Data_component_format#lore modifiedLore = modifiedLore.stream().limit(256).toList(); } else { @@ -177,7 +174,7 @@ public void change(Event event, Object @Nullable [] delta, ChangeMode mode) { private boolean validateItem(Object item) { ItemStack itemStack = ItemUtils.asItemStack(item); - return itemStack != null && itemStack.hasItemMeta(); + return itemStack != null && itemStack.getItemMeta() != null; } @Override From d3f80d1d0ead66cc51633e22721e82096c67ca78 Mon Sep 17 00:00:00 2001 From: Fusezion Date: Sun, 23 Mar 2025 12:05:20 -0400 Subject: [PATCH 3/7] ExprLore.sk - Basic Test Implementation --- .../tests/syntaxes/expressions/ExprLore.sk | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 src/test/skript/tests/syntaxes/expressions/ExprLore.sk diff --git a/src/test/skript/tests/syntaxes/expressions/ExprLore.sk b/src/test/skript/tests/syntaxes/expressions/ExprLore.sk new file mode 100644 index 00000000000..c0273046dec --- /dev/null +++ b/src/test/skript/tests/syntaxes/expressions/ExprLore.sk @@ -0,0 +1,35 @@ +test "ExprLore - Lore of Item": + set {_item} to a diamond + set lore of {_item} to "Line1", "Line2", "Line3" and "Line4" + assert lore of {_item} is "Line1", "Line2", "Line3" and "Line4" + + copy {_item} into {_item2} + set lore of {_item2} to {_null} + assert lore of {_item2} is not set + + remove "Line2" from lore of {_item} + remove {_null} from lore of {_item} + assert lore of {_item} is "Line1", "Line3" and "Line4" + + add "Line5" and "Line5" to lore of {_item} + add {_null} to lore of {_item} + assert lore of {_item} is "Line1", "Line3", "Line4", "Line5" and "Line5" + + remove all "Line5" from lore of {_item} + assert lore of {_item} is "Line1", "Line3" and "Line4" + + clear lore of {_item} + assert lore of {_item} is not set with "The lore of an item after being cleared did not become null" + +test "ExprLore - Line X of Lore of Item": + set {_item} to a diamond + set lore of {_item} to "Line1", "Line2", "Line3" + + delete line 3 of lore of {_item} + assert line 3 of lore of {_item} is not set with "Line 3 of item was not removed" + + set line 6 of lore of {_item} to "3 Blanks = 1 Word" + assert line 6 of lore of {_item} is "3 Blanks = 1 Word" + + set line 4 of lore of {_item} to {_null} + assert size of lore of {_item} is 5 with "Setting a line to a null value, did not default to delete" From 06b514faf2ee22033a320c1a2860e3e5d8a75424 Mon Sep 17 00:00:00 2001 From: Fusezion Date: Sun, 23 Mar 2025 14:28:13 -0400 Subject: [PATCH 4/7] Update some time state change mode support --- .../java/ch/njol/skript/expressions/ExprLore.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprLore.java b/src/main/java/ch/njol/skript/expressions/ExprLore.java index 35df54e10d5..d3ff9c5d25d 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprLore.java +++ b/src/main/java/ch/njol/skript/expressions/ExprLore.java @@ -4,12 +4,14 @@ import ch.njol.skript.aliases.ItemType; import ch.njol.skript.bukkitutil.ItemUtils; import ch.njol.skript.classes.Changer.ChangeMode; +import ch.njol.skript.classes.Changer.ChangerUtils; import ch.njol.skript.doc.*; import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.ExpressionType; import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.skript.lang.SyntaxStringBuilder; import ch.njol.skript.lang.util.SimpleExpression; +import ch.njol.skript.registrations.EventValues; import ch.njol.util.Kleenean; import ch.njol.util.coll.CollectionUtils; import org.bukkit.event.Event; @@ -31,7 +33,6 @@ remove line 1 of lore of {_item} from lore of {_item} set line 3 of lore of {_item} to "-----" """) -@Examples("set the 1st line of the item's lore to \"<orange>Excalibur 2.0\"") @Since("2.1") public class ExprLore extends SimpleExpression { @@ -83,6 +84,10 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye @Override public Class @Nullable [] acceptChange(ChangeMode mode) { + if (this.item.getTime() != EventValues.TIME_NOW && !ChangerUtils.acceptsChange(item, ChangeMode.SET, ItemStack.class, ItemType.class)) { + // Allows past/future expressions only if they accept the set change mode + return null; + } boolean acceptsMany = this.lineNumber == null; return switch (mode) { case SET -> CollectionUtils.array(acceptsMany ? String[].class : String.class); @@ -96,10 +101,6 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye } default -> null; }; -// TODO: see if this method is required, should only limit ability to use event-item which isn't necessary and just falsely limits Skript -// if (ChangerUtils.acceptsChange(item, ChangeMode.SET, ItemStack.class, ItemType.class)) { -// return CollectionUtils.array(acceptsMany ? String[].class : String.class); -// } } @Override @@ -110,7 +111,7 @@ public void change(Event event, Object @Nullable [] delta, ChangeMode mode) { ItemStack modifiedItem = ItemUtils.asItemStack(item); assert modifiedItem != null; // validateItem has already run a check against this ItemMeta itemMeta = modifiedItem.getItemMeta(); -// noinspection deprecation + //noinspection deprecation List modifiedLore = itemMeta.hasLore() ? itemMeta.getLore() : new ArrayList<>(); assert modifiedLore != null; // lore can never be null here, if it's unset we create an empty list From e195f06c69f30232c2ec00ee639c8f96dde92984 Mon Sep 17 00:00:00 2001 From: Fusezion Date: Sun, 23 Mar 2025 20:24:45 -0400 Subject: [PATCH 5/7] Fix pattern indention? --- src/main/java/ch/njol/skript/expressions/ExprLore.java | 10 +++++----- 1 file changed, 5 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 d3ff9c5d25d..72e4a466559 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprLore.java +++ b/src/main/java/ch/njol/skript/expressions/ExprLore.java @@ -41,11 +41,11 @@ public class ExprLore extends SimpleExpression { static { Skript.registerExpression(ExprLore.class, String.class, ExpressionType.PROPERTY, "[the] lore of %itemstack/itemtype%", - "%itemstack/itemtype%'[s] lore", - "[the] line %number% of [the] lore of %itemstack/itemtype%", - "[the] line %number% of %itemstack/itemtype%'[s] lore", - "[the] %number%(st|nd|rd|th) line of [the] lore of %itemstack/itemtype%", - "[the] %number%(st|nd|rd|th) line of %itemstack/itemtype%'[s] lore"); + "%itemstack/itemtype%'[s] lore", + "[the] line %number% of [the] lore of %itemstack/itemtype%", + "[the] line %number% of %itemstack/itemtype%'[s] lore", + "[the] %number%(st|nd|rd|th) line of [the] lore of %itemstack/itemtype%", + "[the] %number%(st|nd|rd|th) line of %itemstack/itemtype%'[s] lore"); } private @Nullable Expression lineNumber; From 2f978e0b9ab490012b46aefa93647618689189d5 Mon Sep 17 00:00:00 2001 From: Fusezion Date: Mon, 31 Mar 2025 18:46:22 -0400 Subject: [PATCH 6/7] Apply suggestions from code review Co-authored-by: Patrick Miller --- .../java/ch/njol/skript/expressions/ExprLore.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprLore.java b/src/main/java/ch/njol/skript/expressions/ExprLore.java index 72e4a466559..93ce4cda857 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprLore.java +++ b/src/main/java/ch/njol/skript/expressions/ExprLore.java @@ -42,8 +42,8 @@ public class ExprLore extends SimpleExpression { Skript.registerExpression(ExprLore.class, String.class, ExpressionType.PROPERTY, "[the] lore of %itemstack/itemtype%", "%itemstack/itemtype%'[s] lore", - "[the] line %number% of [the] lore of %itemstack/itemtype%", - "[the] line %number% of %itemstack/itemtype%'[s] lore", + "line %number% of [the] lore of %itemstack/itemtype%", + "line %number% of %itemstack/itemtype%'[s] lore", "[the] %number%(st|nd|rd|th) line of [the] lore of %itemstack/itemtype%", "[the] %number%(st|nd|rd|th) line of %itemstack/itemtype%'[s] lore"); } @@ -62,14 +62,14 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye @Override protected String @Nullable [] get(Event event) { if (!validateItem(item.getSingle(event))) - return null; + return String[0]; ItemStack itemStack = ItemUtils.asItemStack(item.getSingle(event)); assert itemStack != null; // Validated in validateItem ItemMeta itemMeta = itemStack.getItemMeta(); //noinspection deprecation List itemLore = itemMeta.getLore(); if (itemLore == null || itemLore.isEmpty()) - return null; + return new String[0]; if (lineNumber == null) { return itemLore.toArray(String[]::new); @@ -77,7 +77,7 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye int loreIndex = this.lineNumber.getOptionalSingle(event).orElse(0).intValue() -1; if (loreIndex < 0 || loreIndex >= itemLore.size()) { - return null; + return new String[0]; } return new String[]{itemLore.get(loreIndex)}; } @@ -94,7 +94,7 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye case DELETE -> CollectionUtils.array(); case ADD, REMOVE, REMOVE_ALL -> { if (!acceptsMany) { - Skript.error("You cannot add/remove the lore from a single line, you can however replace/concat lore."); + Skript.error("You cannot add to or remove from the lore from a single line."); yield null; } yield CollectionUtils.array(String[].class); From a2fd3e92a8a1aeea4c2021c6fc813e7f4ad164fb Mon Sep 17 00:00:00 2001 From: Fusezion Date: Mon, 31 Mar 2025 18:51:48 -0400 Subject: [PATCH 7/7] Update src/main/java/ch/njol/skript/expressions/ExprLore.java --- src/main/java/ch/njol/skript/expressions/ExprLore.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprLore.java b/src/main/java/ch/njol/skript/expressions/ExprLore.java index 93ce4cda857..ad30682acb4 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprLore.java +++ b/src/main/java/ch/njol/skript/expressions/ExprLore.java @@ -62,7 +62,7 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye @Override protected String @Nullable [] get(Event event) { if (!validateItem(item.getSingle(event))) - return String[0]; + return new String[0]; ItemStack itemStack = ItemUtils.asItemStack(item.getSingle(event)); assert itemStack != null; // Validated in validateItem ItemMeta itemMeta = itemStack.getItemMeta();