From 4292d1e5cb2e762fe0e78cec17881984f4fd4ae4 Mon Sep 17 00:00:00 2001 From: Eren KARA Date: Thu, 19 Jun 2025 23:12:50 +0300 Subject: [PATCH 01/10] allow literals in ExprAmount --- src/main/java/ch/njol/skript/expressions/ExprAmount.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprAmount.java b/src/main/java/ch/njol/skript/expressions/ExprAmount.java index 375f01cdb36..57555705964 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprAmount.java +++ b/src/main/java/ch/njol/skript/expressions/ExprAmount.java @@ -9,7 +9,6 @@ import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.ExpressionList; import ch.njol.skript.lang.ExpressionType; -import ch.njol.skript.lang.Literal; import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.skript.lang.Variable; import ch.njol.skript.lang.util.SimpleExpression; @@ -66,9 +65,6 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye this.exprs = exprs[0] instanceof ExpressionList ? (ExpressionList) exprs[0] : new ExpressionList<>(new Expression[]{exprs[0]}, Object.class, false); this.recursive = matchedPattern == 2; for (Expression expr : this.exprs.getExpressions()) { - if (expr instanceof Literal) { - return false; - } if (expr.isSingle()) { Skript.error("'" + expr.toString(null, false) + "' can only ever have one value at most, thus the 'amount of ...' expression is useless. Use '... exists' instead to find out whether the expression has a value."); return false; @@ -111,7 +107,7 @@ protected Number[] get(Event e) { } @Override - public void change(Event event, Object @Nullable [] delta, ChangeMode mode) { + public void change(Event event, Object @Nullable [] delta, ChangeMode mode) { if (any == null) { super.change(event, delta, mode); return; From a9be31df586d6d1f667d4362e8a690c929d64a8a Mon Sep 17 00:00:00 2001 From: Eren KARA Date: Sat, 21 Jun 2025 01:13:16 +0300 Subject: [PATCH 02/10] update ExprAmount --- .../njol/skript/expressions/ExprAmount.java | 83 +++++++++++-------- .../tests/syntaxes/expressions/ExprAmount.sk | 14 +++- 2 files changed, 61 insertions(+), 36 deletions(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprAmount.java b/src/main/java/ch/njol/skript/expressions/ExprAmount.java index 57555705964..3e79af611f9 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprAmount.java +++ b/src/main/java/ch/njol/skript/expressions/ExprAmount.java @@ -6,13 +6,11 @@ import ch.njol.skript.doc.Examples; import ch.njol.skript.doc.Name; import ch.njol.skript.doc.Since; -import ch.njol.skript.lang.Expression; -import ch.njol.skript.lang.ExpressionList; -import ch.njol.skript.lang.ExpressionType; +import ch.njol.skript.lang.*; import ch.njol.skript.lang.SkriptParser.ParseResult; -import ch.njol.skript.lang.Variable; import ch.njol.skript.lang.util.SimpleExpression; import ch.njol.skript.lang.util.common.AnyAmount; +import ch.njol.skript.util.LiteralUtils; import ch.njol.util.Kleenean; import ch.njol.util.coll.CollectionUtils; import org.bukkit.event.Event; @@ -22,31 +20,31 @@ @Name("Amount") @Description({"The amount or size of something.", - "Please note that amount of %items% will not return the number of items, but the number of stacks, e.g. 1 for a stack of 64 torches. To get the amount of items in a stack, see the item amount expression.", - "", - "Also, you can get the recursive size of a list, which will return the recursive size of the list with sublists included, e.g.", - "", - "
",
-		"{list::*} Structure
", - " ├──── {list::1}: 1
", - " ├──── {list::2}: 2
", - " │ ├──── {list::2::1}: 3
", - " │ │ └──── {list::2::1::1}: 4
", - " │ └──── {list::2::2}: 5
", - " └──── {list::3}: 6", - "
", - "", - "Where using %size of {list::*}% will only return 3 (the first layer of indices only), while %recursive size of {list::*}% will return 6 (the entire list)", - "Please note that getting a list's recursive size can cause lag if the list is large, so only use this expression if you need to!"}) + "Please note that amount of %items% will not return the number of items, but the number of stacks, e.g. 1 for a stack of 64 torches. To get the amount of items in a stack, see the item amount expression.", + "", + "Also, you can get the recursive size of a list, which will return the recursive size of the list with sublists included, e.g.", + "", + "
",
+	"{list::*} Structure
", + " ├──── {list::1}: 1
", + " ├──── {list::2}: 2
", + " │ ├──── {list::2::1}: 3
", + " │ │ └──── {list::2::1::1}: 4
", + " │ └──── {list::2::2}: 5
", + " └──── {list::3}: 6", + "
", + "", + "Where using %size of {list::*}% will only return 3 (the first layer of indices only), while %recursive size of {list::*}% will return 6 (the entire list)", + "Please note that getting a list's recursive size can cause lag if the list is large, so only use this expression if you need to!"}) @Examples({"message \"There are %number of all players% players online!\""}) @Since("1.0") public class ExprAmount extends SimpleExpression { static { Skript.registerExpression(ExprAmount.class, Number.class, ExpressionType.PROPERTY, - "[the] (amount|number|size) of %numbered%", - "[the] (amount|number|size) of %objects%", - "[the] recursive (amount|number|size) of %objects%"); + "[the] (amount|number|size) of %numbered%", + "[the] (amount|number|size) of %objects%", + "[the] recursive (amount|number|size) of %objects%"); } @SuppressWarnings("null") @@ -62,13 +60,23 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye this.any = (Expression) exprs[0]; return true; } - this.exprs = exprs[0] instanceof ExpressionList ? (ExpressionList) exprs[0] : new ExpressionList<>(new Expression[]{exprs[0]}, Object.class, false); + + this.exprs = exprs[0] instanceof ExpressionList exprList + ? exprList + : new ExpressionList<>(new Expression[]{ exprs[0] }, Object.class, false); + + if (this.exprs.isSingle()) { + Skript.error("'" + this.exprs.toString(null, false) + "' can only ever have one value at most, thus the 'amount of ...' expression is useless. Use '... exists' instead to find out whether the expression has a value."); + return false; + } + + this.exprs = (ExpressionList) LiteralUtils.defendExpression(this.exprs); + if (!LiteralUtils.canInitSafely(this.exprs)) { + return false; + } + this.recursive = matchedPattern == 2; for (Expression expr : this.exprs.getExpressions()) { - if (expr.isSingle()) { - Skript.error("'" + expr.toString(null, false) + "' can only ever have one value at most, thus the 'amount of ...' expression is useless. Use '... exists' instead to find out whether the expression has a value."); - return false; - } if (recursive && !(expr instanceof Variable)) { Skript.error("Getting the recursive size of a list only applies to variables, thus the '" + expr.toString(null, false) + "' expression is useless."); return false; @@ -79,20 +87,20 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye @Override @SuppressWarnings("unchecked") - protected Number[] get(Event e) { + protected Number[] get(Event event) { if (any != null) - return new Number[] {any.getOptionalSingle(e).orElse(() -> 0).amount()}; + return new Number[] {any.getOptionalSingle(event).orElse(() -> 0).amount()}; if (recursive) { int currentSize = 0; for (Expression expr : exprs.getExpressions()) { - Object var = ((Variable) expr).getRaw(e); + Object var = ((Variable) expr).getRaw(event); if (var != null) { // Should already be a map currentSize += getRecursiveSize((Map) var); } } return new Long[]{(long) currentSize}; } - return new Long[]{(long) exprs.getArray(e).length}; + return new Long[]{(long) exprs.getArray(event).length}; } @Override @@ -134,13 +142,20 @@ public void change(Event event, Object @Nullable [] delta, ChangeMode mode) { } } - @SuppressWarnings("unchecked") private static int getRecursiveSize(Map map) { + return getRecursiveSize(map, true); + } + + @SuppressWarnings("unchecked") + private static int getRecursiveSize(Map map, boolean skipNull) { int count = 0; for (Map.Entry entry : map.entrySet()) { + if (skipNull && entry.getKey() == null) + continue; // when getting the recursive size of {a::*}, ignore {a} + Object value = entry.getValue(); if (value instanceof Map) - count += getRecursiveSize((Map) value); + count += getRecursiveSize((Map) value, false); else count++; } diff --git a/src/test/skript/tests/syntaxes/expressions/ExprAmount.sk b/src/test/skript/tests/syntaxes/expressions/ExprAmount.sk index d4cc336b031..c497a48d89b 100644 --- a/src/test/skript/tests/syntaxes/expressions/ExprAmount.sk +++ b/src/test/skript/tests/syntaxes/expressions/ExprAmount.sk @@ -1,12 +1,22 @@ test "amount of objects": set {_objects::*} to (1 and 2) set {_amount} to amount of {_objects::*} - assert {_amount} is 2 with "was wrong" + assert {_amount} is 2 with "size of list was wrong - 1" + set {_objects::*} to ("hello", "there" and 1) set {_amount} to amount of {_objects::*} - assert {_amount} is 3 with "was wrong" + assert {_amount} is 3 with "size of list was wrong - 2" + + assert size of (1, 2 and 3) is 3 with "size of literal list was wrong" test "amount of items": assert amount of (3 of stone) is 3 with "was wrong" set {_item} to 3 of stone assert amount of {_item} is 3 with "was wrong" + +test "recursive size": + set {_a} to 1 + set {_a::*} to 1, 2 and 3 + set {_a::1::*} to 1 and 2 + set {_a::1::1::1::1::1} to 5 + assert recursive size of {_a::*} is 6 with "recursive size was wrong" From 53ef340688beafa54da8bbbbabc4b96ec8593eb2 Mon Sep 17 00:00:00 2001 From: Eren KARA Date: Sat, 21 Jun 2025 01:15:46 +0300 Subject: [PATCH 03/10] fix indentation --- .../njol/skript/expressions/ExprAmount.java | 39 +++++++++---------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprAmount.java b/src/main/java/ch/njol/skript/expressions/ExprAmount.java index 3e79af611f9..f7968c54db3 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprAmount.java +++ b/src/main/java/ch/njol/skript/expressions/ExprAmount.java @@ -2,10 +2,7 @@ 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.Since; +import ch.njol.skript.doc.*; import ch.njol.skript.lang.*; import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.skript.lang.util.SimpleExpression; @@ -20,23 +17,23 @@ @Name("Amount") @Description({"The amount or size of something.", - "Please note that amount of %items% will not return the number of items, but the number of stacks, e.g. 1 for a stack of 64 torches. To get the amount of items in a stack, see the item amount expression.", - "", - "Also, you can get the recursive size of a list, which will return the recursive size of the list with sublists included, e.g.", - "", - "
",
-	"{list::*} Structure
", - " ├──── {list::1}: 1
", - " ├──── {list::2}: 2
", - " │ ├──── {list::2::1}: 3
", - " │ │ └──── {list::2::1::1}: 4
", - " │ └──── {list::2::2}: 5
", - " └──── {list::3}: 6", - "
", - "", - "Where using %size of {list::*}% will only return 3 (the first layer of indices only), while %recursive size of {list::*}% will return 6 (the entire list)", - "Please note that getting a list's recursive size can cause lag if the list is large, so only use this expression if you need to!"}) -@Examples({"message \"There are %number of all players% players online!\""}) + "Please note that amount of %items% will not return the number of items, but the number of stacks, e.g. 1 for a stack of 64 torches. To get the amount of items in a stack, see the item amount expression.", + "", + "Also, you can get the recursive size of a list, which will return the recursive size of the list with sublists included, e.g.", + "", + "
",
+		"{list::*} Structure
", + " ├──── {list::1}: 1
", + " ├──── {list::2}: 2
", + " │ ├──── {list::2::1}: 3
", + " │ │ └──── {list::2::1::1}: 4
", + " │ └──── {list::2::2}: 5
", + " └──── {list::3}: 6", + "
", + "", + "Where using %size of {list::*}% will only return 3 (the first layer of indices only), while %recursive size of {list::*}% will return 6 (the entire list)", + "Please note that getting a list's recursive size can cause lag if the list is large, so only use this expression if you need to!"}) +@Example("message \"There are %number of all players% players online!\"") @Since("1.0") public class ExprAmount extends SimpleExpression { From a8b9f0ddf51e7c5c5836b3616c531883a4939cb5 Mon Sep 17 00:00:00 2001 From: Eren KARA Date: Sat, 21 Jun 2025 01:16:55 +0300 Subject: [PATCH 04/10] fix indentation --- src/main/java/ch/njol/skript/expressions/ExprAmount.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprAmount.java b/src/main/java/ch/njol/skript/expressions/ExprAmount.java index f7968c54db3..69edb409a25 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprAmount.java +++ b/src/main/java/ch/njol/skript/expressions/ExprAmount.java @@ -39,9 +39,9 @@ public class ExprAmount extends SimpleExpression { static { Skript.registerExpression(ExprAmount.class, Number.class, ExpressionType.PROPERTY, - "[the] (amount|number|size) of %numbered%", - "[the] (amount|number|size) of %objects%", - "[the] recursive (amount|number|size) of %objects%"); + "[the] (amount|number|size) of %numbered%", + "[the] (amount|number|size) of %objects%", + "[the] recursive (amount|number|size) of %objects%"); } @SuppressWarnings("null") From bb285b01e523955de60d65b81da966b033b34486 Mon Sep 17 00:00:00 2001 From: Eren KARA Date: Mon, 23 Jun 2025 09:23:01 +0300 Subject: [PATCH 05/10] requested changes --- .../njol/skript/expressions/ExprAmount.java | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprAmount.java b/src/main/java/ch/njol/skript/expressions/ExprAmount.java index 69edb409a25..2bac5bdd22e 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprAmount.java +++ b/src/main/java/ch/njol/skript/expressions/ExprAmount.java @@ -58,7 +58,12 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye return true; } - this.exprs = exprs[0] instanceof ExpressionList exprList + this.exprs = (ExpressionList) LiteralUtils.defendExpression(this.exprs); + if (!LiteralUtils.canInitSafely(this.exprs)) { + return false; + } + + this.exprs = exprs[0] instanceof ExpressionList exprList ? exprList : new ExpressionList<>(new Expression[]{ exprs[0] }, Object.class, false); @@ -67,11 +72,6 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye return false; } - this.exprs = (ExpressionList) LiteralUtils.defendExpression(this.exprs); - if (!LiteralUtils.canInitSafely(this.exprs)) { - return false; - } - this.recursive = matchedPattern == 2; for (Expression expr : this.exprs.getExpressions()) { if (recursive && !(expr instanceof Variable)) { @@ -83,7 +83,6 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye } @Override - @SuppressWarnings("unchecked") protected Number[] get(Event event) { if (any != null) return new Number[] {any.getOptionalSingle(event).orElse(() -> 0).amount()}; @@ -92,6 +91,7 @@ protected Number[] get(Event event) { for (Expression expr : exprs.getExpressions()) { Object var = ((Variable) expr).getRaw(event); if (var != null) { // Should already be a map + // noinspection unchecked currentSize += getRecursiveSize((Map) var); } } @@ -139,20 +139,19 @@ public void change(Event event, Object @Nullable [] delta, ChangeMode mode) { } } - private static int getRecursiveSize(Map map) { + private static int getRecursiveSize(Map map) { return getRecursiveSize(map, true); } - @SuppressWarnings("unchecked") - private static int getRecursiveSize(Map map, boolean skipNull) { + private static int getRecursiveSize(Map map, boolean skipNull) { int count = 0; - for (Map.Entry entry : map.entrySet()) { + for (Map.Entry entry : map.entrySet()) { if (skipNull && entry.getKey() == null) continue; // when getting the recursive size of {a::*}, ignore {a} Object value = entry.getValue(); - if (value instanceof Map) - count += getRecursiveSize((Map) value, false); + if (value instanceof Map nestedMap) + count += getRecursiveSize(nestedMap, false); else count++; } From 4490146cecb0a7ee7abee1ed55925969fa388dc7 Mon Sep 17 00:00:00 2001 From: Eren KARA Date: Mon, 23 Jun 2025 09:34:01 +0300 Subject: [PATCH 06/10] whoops --- src/main/java/ch/njol/skript/expressions/ExprAmount.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprAmount.java b/src/main/java/ch/njol/skript/expressions/ExprAmount.java index 2bac5bdd22e..d1cefdfd80e 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprAmount.java +++ b/src/main/java/ch/njol/skript/expressions/ExprAmount.java @@ -58,15 +58,15 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye return true; } + this.exprs = exprs[0] instanceof ExpressionList exprList + ? exprList + : new ExpressionList<>(new Expression[]{ exprs[0] }, Object.class, false); + this.exprs = (ExpressionList) LiteralUtils.defendExpression(this.exprs); if (!LiteralUtils.canInitSafely(this.exprs)) { return false; } - this.exprs = exprs[0] instanceof ExpressionList exprList - ? exprList - : new ExpressionList<>(new Expression[]{ exprs[0] }, Object.class, false); - if (this.exprs.isSingle()) { Skript.error("'" + this.exprs.toString(null, false) + "' can only ever have one value at most, thus the 'amount of ...' expression is useless. Use '... exists' instead to find out whether the expression has a value."); return false; From cb39b4f2a93258be9a3be2b85371fce3c9230c75 Mon Sep 17 00:00:00 2001 From: Eren <67760502+erenkarakal@users.noreply.github.com> Date: Thu, 26 Jun 2025 18:55:52 +0300 Subject: [PATCH 07/10] add debug Co-authored-by: Patrick Miller --- src/main/java/ch/njol/skript/expressions/ExprAmount.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprAmount.java b/src/main/java/ch/njol/skript/expressions/ExprAmount.java index d1cefdfd80e..313fff7af27 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprAmount.java +++ b/src/main/java/ch/njol/skript/expressions/ExprAmount.java @@ -75,7 +75,7 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye this.recursive = matchedPattern == 2; for (Expression expr : this.exprs.getExpressions()) { if (recursive && !(expr instanceof Variable)) { - Skript.error("Getting the recursive size of a list only applies to variables, thus the '" + expr.toString(null, false) + "' expression is useless."); + Skript.error("Getting the recursive size of a list only applies to variables, thus the '" + expr.toString(null, Skript.debug()) + "' expression is useless."); return false; } } From bf2b933590a556d40c761da3b3c5585a7711b100 Mon Sep 17 00:00:00 2001 From: Eren <67760502+erenkarakal@users.noreply.github.com> Date: Thu, 26 Jun 2025 18:56:05 +0300 Subject: [PATCH 08/10] add debug Co-authored-by: Patrick Miller --- src/main/java/ch/njol/skript/expressions/ExprAmount.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprAmount.java b/src/main/java/ch/njol/skript/expressions/ExprAmount.java index 313fff7af27..64ba70920e9 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprAmount.java +++ b/src/main/java/ch/njol/skript/expressions/ExprAmount.java @@ -68,7 +68,7 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye } if (this.exprs.isSingle()) { - Skript.error("'" + this.exprs.toString(null, false) + "' can only ever have one value at most, thus the 'amount of ...' expression is useless. Use '... exists' instead to find out whether the expression has a value."); + Skript.error("'" + this.exprs.toString(null, Skript.debug()) + "' can only ever have one value at most, thus the 'amount of ...' expression is useless. Use '... exists' instead to find out whether the expression has a value."); return false; } From 33c1275b0de87a5202036cbdb456844579e16a93 Mon Sep 17 00:00:00 2001 From: Eren <67760502+erenkarakal@users.noreply.github.com> Date: Thu, 26 Jun 2025 18:56:16 +0300 Subject: [PATCH 09/10] indentation Co-authored-by: Patrick Miller --- src/main/java/ch/njol/skript/expressions/ExprAmount.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprAmount.java b/src/main/java/ch/njol/skript/expressions/ExprAmount.java index 64ba70920e9..93f2edb5c7b 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprAmount.java +++ b/src/main/java/ch/njol/skript/expressions/ExprAmount.java @@ -59,8 +59,8 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye } this.exprs = exprs[0] instanceof ExpressionList exprList - ? exprList - : new ExpressionList<>(new Expression[]{ exprs[0] }, Object.class, false); + ? exprList + : new ExpressionList<>(new Expression[]{ exprs[0] }, Object.class, false); this.exprs = (ExpressionList) LiteralUtils.defendExpression(this.exprs); if (!LiteralUtils.canInitSafely(this.exprs)) { From 07b361c04248753393eed899491c1f1d04d66676 Mon Sep 17 00:00:00 2001 From: Eren KARA Date: Thu, 26 Jun 2025 20:12:24 +0300 Subject: [PATCH 10/10] update test --- src/test/skript/tests/syntaxes/expressions/ExprAmount.sk | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/skript/tests/syntaxes/expressions/ExprAmount.sk b/src/test/skript/tests/syntaxes/expressions/ExprAmount.sk index c497a48d89b..a0a21793517 100644 --- a/src/test/skript/tests/syntaxes/expressions/ExprAmount.sk +++ b/src/test/skript/tests/syntaxes/expressions/ExprAmount.sk @@ -8,6 +8,7 @@ test "amount of objects": assert {_amount} is 3 with "size of list was wrong - 2" assert size of (1, 2 and 3) is 3 with "size of literal list was wrong" + assert size of (1, {_objects::*} and 3) is 5 with "size of mixed list was wrong" test "amount of items": assert amount of (3 of stone) is 3 with "was wrong"