diff --git a/src/main/java/ch/njol/skript/config/Node.java b/src/main/java/ch/njol/skript/config/Node.java
index f59c7210f5c..cff13bda618 100644
--- a/src/main/java/ch/njol/skript/config/Node.java
+++ b/src/main/java/ch/njol/skript/config/Node.java
@@ -23,6 +23,7 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import ch.njol.skript.SkriptConfig;
import org.eclipse.jdt.annotation.Nullable;
import ch.njol.skript.Skript;
@@ -114,17 +115,27 @@ public void move(final SectionNode newParent) {
p.remove(this);
newParent.add(this);
}
-
- @SuppressWarnings("null")
- private final static Pattern linePattern = Pattern.compile("^((?:[^#]|##)*)(\\s*#(?!#).*)$");
-
+
/**
* Splits a line into value and comment.
*
* Whitespace is preserved (whitespace in front of the comment is added to the value), and any ## in the value are replaced by a single #. The comment is returned with a
* leading #, except if there is no comment in which case it will be the empty string.
+ *
+ * @param line the line to split
+ * @return A pair (value, comment).
+ */
+ public static NonNullPair splitLine(String line) {
+ return splitLine(line, new AtomicBoolean(false));
+ }
+
+ /**
+ * Splits a line into value and comment.
+ *
+ * Whitespace is preserved (whitespace in front of the comment is added to the value), and any ## not in quoted strings in the value are replaced by a single #. The comment is returned with a
+ * leading #, except if there is no comment in which case it will be the empty string.
*
- * @param line
+ * @param line the line to split
* @param inBlockComment Whether we are currently inside a block comment
* @return A pair (value, comment).
*/
@@ -138,34 +149,99 @@ public static NonNullPair splitLine(String line, AtomicBoolean i
} else if (inBlockComment.get()) { // we're inside a comment, all text is a comment
return new NonNullPair<>("", line);
}
- final Matcher m = linePattern.matcher(line);
- boolean matches = false;
- try {
- matches = line.contains("#") && m.matches();
- } catch (StackOverflowError e) { // Probably a very long line
- handleNodeStackOverflow(e, line);
+
+ // idea: find first # that is not within a string or variable name. Use state machine to determine whether a # is a comment or not.
+ int length = line.length();
+ StringBuilder finalLine = new StringBuilder(line);
+ int numRemoved = 0;
+ SplitLineState state = SplitLineState.CODE;
+ SplitLineState previousState = SplitLineState.CODE; // stores the state prior to entering %, so it can be re-set when leaving
+ // find next " or %
+ for (int i = 0; i < length; i++) {
+ char c = line.charAt(i);
+ // check for things that can be escaped by doubling
+ if (c == '%' || c == '"' || c == '#') {
+ // skip if doubled (only skip ## outside of strings)
+ if ((c != '#' || state != SplitLineState.STRING) && i + 1 < length && line.charAt(i + 1) == c) {
+ if (c == '#') { // remove duplicate #
+ finalLine.deleteCharAt(i - numRemoved);
+ numRemoved++;
+ }
+ i++;
+ continue;
+ }
+ SplitLineState tmp = state;
+ state = SplitLineState.update(c, state, previousState);
+ if (state == SplitLineState.HALT)
+ return new NonNullPair<>(finalLine.substring(0, i - numRemoved), line.substring(i));
+ // only update previous state when we go from !CODE -> CODE due to %
+ if (c == '%' && state == SplitLineState.CODE)
+ previousState = tmp;
+ }
}
- if (matches)
- return new NonNullPair<>("" + m.group(1).replace("##", "#"), "" + m.group(2));
- return new NonNullPair<>("" + line.replace("##", "#"), "");
+ return new NonNullPair<>(finalLine.toString(), "");
}
/**
- * Splits a line into value and comment.
- *
- * Whitespace is preserved (whitespace in front of the comment is added to the value), and any ## in the value are replaced by a single #. The comment is returned with a
- * leading #, except if there is no comment in which case it will be the empty string.
- *
- * @param line
- * @return A pair (value, comment).
+ * state machine:
+ * ": CODE -> STRING, STRING -> CODE, VARIABLE -> VARIABLE
+ * %: CODE -> PREVIOUS_STATE, STRING -> CODE, VARIABLE -> CODE
+ * {: CODE -> VARIABLE, STRING -> STRING, VARIABLE -> VARIABLE
+ * }: CODE -> CODE, STRING -> STRING, VARIABLE -> CODE
+ * #: CODE -> HALT, STRING -> STRING, VARIABLE -> HALT
+ * invalid characters simply return given state.
*/
- public static NonNullPair splitLine(String line) {
- return splitLine(line, new AtomicBoolean(false));
+ private enum SplitLineState {
+ HALT,
+ CODE,
+ STRING,
+ VARIABLE;
+
+ /**
+ * Updates the state given a character input.
+ * @param c character input. '"', '%', '{', '}', and '#' are valid.
+ * @param state the current state of the machine
+ * @param previousState the state of the machine when it last entered a % CODE % section
+ * @return the new state of the machine
+ */
+ private static SplitLineState update(char c, SplitLineState state, SplitLineState previousState) {
+ if (state == HALT)
+ return HALT;
+
+ switch (c) {
+ case '%':
+ if (state == CODE)
+ return previousState;
+ return CODE;
+ case '"':
+ switch (state) {
+ case CODE:
+ return STRING;
+ case STRING:
+ return CODE;
+ default:
+ return state;
+ }
+ case '{':
+ if (state == STRING)
+ return STRING;
+ return VARIABLE;
+ case '}':
+ if (state == STRING)
+ return STRING;
+ return CODE;
+ case '#':
+ if (state == STRING)
+ return STRING;
+ return HALT;
+ }
+ return state;
+ }
}
static void handleNodeStackOverflow(StackOverflowError e, String line) {
Node n = SkriptLogger.getNode();
- SkriptLogger.setNode(null); // Avoid duplicating the which node error occurred in paranthesis on every error message
+ SkriptLogger.setNode(null); // Avoid duplicating the which node error occurred in parentheses on every error message
Skript.error("There was a StackOverFlowError occurred when loading a node. This maybe from your scripts, aliases or Skript configuration.");
Skript.error("Please make your script lines shorter! Do NOT report this to SkriptLang unless it occurs with a short script line or built-in aliases!");
@@ -214,12 +290,43 @@ protected String getIndentation() {
abstract String save_i();
public final String save() {
- return getIndentation() + save_i().replace("#", "##") + comment;
+ return getIndentation() + escapeUnquotedHashtags(save_i()) + comment;
}
public void save(final PrintWriter w) {
w.println(save());
}
+
+ private static String escapeUnquotedHashtags(String input) {
+ int length = input.length();
+ StringBuilder output = new StringBuilder(input);
+ int numAdded = 0;
+ SplitLineState state = SplitLineState.CODE;
+ SplitLineState previousState = SplitLineState.CODE;
+ // find next " or %
+ for (int i = 0; i < length; i++) {
+ char c = input.charAt(i);
+ // check for things that can be escaped by doubling
+ if (c == '%' || c == '"' || c == '#') {
+ // escaped #s outside of strings
+ if (c == '#' && state != SplitLineState.STRING) {
+ output.insert(i + numAdded, "#");
+ numAdded++;
+ continue;
+ }
+ // skip if doubled (not #s)
+ if (i + 1 < length && input.charAt(i + 1) == c) {
+ i++;
+ continue;
+ }
+ SplitLineState tmp = state;
+ state = SplitLineState.update(c, state, previousState);
+ previousState = tmp;
+ }
+ }
+ return output.toString();
+ }
+
@Nullable
public SectionNode getParent() {
diff --git a/src/main/java/ch/njol/skript/expressions/ExprChestInventory.java b/src/main/java/ch/njol/skript/expressions/ExprChestInventory.java
index 0ba4548c184..a01ac6b9dcc 100644
--- a/src/main/java/ch/njol/skript/expressions/ExprChestInventory.java
+++ b/src/main/java/ch/njol/skript/expressions/ExprChestInventory.java
@@ -52,7 +52,7 @@
"set slot 4 of {_inventory} to a diamond named \"example\"",
"open {_inventory} to player",
"",
- "open chest inventory named \"<##00ff00>hex coloured title!\" with 6 rows to player",
+ "open chest inventory named \"<#00ff00>hex coloured title!\" with 6 rows to player",
})
@RequiredPlugins("Paper 1.16+ (chat format)")
@Since("2.2-dev34, 2.8.0 (chat format)")
diff --git a/src/main/java/ch/njol/skript/expressions/ExprLoopIteration.java b/src/main/java/ch/njol/skript/expressions/ExprLoopIteration.java
index 37640b26db7..12fb9b0a782 100644
--- a/src/main/java/ch/njol/skript/expressions/ExprLoopIteration.java
+++ b/src/main/java/ch/njol/skript/expressions/ExprLoopIteration.java
@@ -45,7 +45,7 @@
"",
"loop {top-balances::*}:",
"\tif loop-iteration <= 10:",
- "\t\tbroadcast \"##%loop-iteration% %loop-index% has $%loop-value%\"",
+ "\t\tbroadcast \"#%loop-iteration% %loop-index% has $%loop-value%\"",
})
@Since("2.8.0")
public class ExprLoopIteration extends SimpleExpression {
diff --git a/src/main/java/ch/njol/skript/expressions/ExprLoopValue.java b/src/main/java/ch/njol/skript/expressions/ExprLoopValue.java
index 343cc9461c3..10142cb0268 100644
--- a/src/main/java/ch/njol/skript/expressions/ExprLoopValue.java
+++ b/src/main/java/ch/njol/skript/expressions/ExprLoopValue.java
@@ -62,7 +62,7 @@
"",
"loop {top-balances::*}:",
"\tloop-iteration <= 10",
- "\tsend \"##%loop-iteration% %loop-index% has $%loop-value%\"",
+ "\tsend \"#%loop-iteration% %loop-index% has $%loop-value%\"",
})
@Since("1.0, 2.8.0 (loop-counter)")
public class ExprLoopValue extends SimpleExpression {
diff --git a/src/main/java/ch/njol/skript/util/Utils.java b/src/main/java/ch/njol/skript/util/Utils.java
index 862e440ceb8..879e1aabe74 100644
--- a/src/main/java/ch/njol/skript/util/Utils.java
+++ b/src/main/java/ch/njol/skript/util/Utils.java
@@ -641,7 +641,7 @@ public String run(final Matcher m) {
return "" + m;
}
- private static final Pattern HEX_PATTERN = Pattern.compile("(?i)#?[0-9a-f]{6}");
+ private static final Pattern HEX_PATTERN = Pattern.compile("(?i)#{0,2}[0-9a-f]{6}");
/**
* Tries to get a {@link ChatColor} from the given string.
diff --git a/src/main/resources/config.sk b/src/main/resources/config.sk
index 85784c06a92..4ba081e7c33 100644
--- a/src/main/resources/config.sk
+++ b/src/main/resources/config.sk
@@ -22,7 +22,7 @@
# This file, all scripts and other files ending in .sk are NOT .yml/YAML files, but very similar!
# Please remember the following when editing files:
# - To indent sections you can use spaces like in YAML, but tabs are also allowed. Just remember to stick to the one or the other for a section/trigger.
-# - '#' starts a comment like in YAML. If you don't want it to start a comment simply double it: '##' (You also have to double these in "quoted text")
+# - '#' starts a comment like in YAML. If you don't want it to start a comment simply double it: '##' (You do NOT have to double these in "quoted text")
# - If you use special characters (§, äöü, éèàôç, ñ, etc.) you have to encode the file in UTF-8.
#
diff --git a/src/main/resources/scripts/-examples/text formatting.sk b/src/main/resources/scripts/-examples/text formatting.sk
index 8a5a1ab277a..5163ca116c3 100644
--- a/src/main/resources/scripts/-examples/text formatting.sk
+++ b/src/main/resources/scripts/-examples/text formatting.sk
@@ -4,7 +4,7 @@
# You can also use <> for colours and formats, like `` for red and `` for bold
#
# In Minecraft 1.16, support was added for 6-digit hexadecimal colors to specify custom colors other than the 16 default color codes.
-# The tag for these colors looks like this: <##hex code> e.g. `<##123456>`
+# The tag for these colors looks like this: <#hex code> e.g. `<#123456>`
#
command /color:
@@ -12,7 +12,7 @@ command /color:
trigger:
send "&6This message is golden."
send "This message is light red and bold."
- send "<##FF0000>This message is red."
+ send "<#FF0000>This message is red."
#
# Other formatting options are also available.
diff --git a/src/test/java/org/skriptlang/skript/test/tests/config/NodeTest.java b/src/test/java/org/skriptlang/skript/test/tests/config/NodeTest.java
index c7e0eb3b29f..b0a7ff2b606 100644
--- a/src/test/java/org/skriptlang/skript/test/tests/config/NodeTest.java
+++ b/src/test/java/org/skriptlang/skript/test/tests/config/NodeTest.java
@@ -47,6 +47,7 @@ public void splitLineTest() {
{"#########", "", "#########"},
{"a##b#c##d#e", "a#b", "#c##d#e"},
{" a ## b # c ## d # e ", " a # b ", "# c ## d # e "},
+ {"a b \"#a ##\" # b \"", "a b \"#a ##\" ", "# b \""},
};
for (String[] d : data) {
NonNullPair p = Node.splitLine(d[0]);
diff --git a/src/test/skript/tests/misc/comments.sk b/src/test/skript/tests/misc/comments.sk
new file mode 100644
index 00000000000..348f7560d6d
--- /dev/null
+++ b/src/test/skript/tests/misc/comments.sk
@@ -0,0 +1,46 @@
+test "comments":
+ parse:
+ set {_a} to {_b} # test
+ assert last parse logs is not set with "skript should be able to handle inline comments but did not"
+
+
+ parse:
+ assert "a" is "a" with "wrong number of hashtags"
+ assert "#a" is join "#", and "a" with "wrong number of hashtags"
+ assert "##a" is join "#", "#", and "a" with "wrong number of hashtags"
+ assert "###a" is join "#", "#", "#", and "a" with "wrong number of hashtags"
+ assert last parse logs is not set with "skript should be able to handle strings any number of hashtags but did not"
+
+
+ parse:
+ assert "a%"#"%" is join "a", and "#" with "wrong number of hashtags"
+ assert "#a%"#}"%" is join "#", "a", and "#}" with "wrong number of hashtags"
+ assert "##a%"#"%" is join "#", "#", "a", and "#" with "wrong number of hashtags"
+ assert "#{##a%"#"%" is join "#{", "#", "#", "a", and "#" with "wrong number of hashtags"
+ assert last parse logs is not set with "skript should be able to handle complex strings any number of hashtags but did not"
+
+
+ parse:
+ set {_a} to "<#abcdef>test"
+ set {_b} to "<##abcdef>test"
+ assert uncoloured {_a} is "test" with "failed to parse single hashtag colour code"
+ assert uncoloured {_b} is "test" with "failed to parse double hashtag colour code"
+ assert last parse logs is not set with "skript should be able to handle hex colour codes but did not"
+
+ parse:
+ set {_a} to "###SH#JABJ#BJ#JB#K#BH#G#J##J#HJ%%KJB#JKK%%""%%""%%""%%#""##%%""#""%%##""#%""%##%"#"""%#"#!!""#""#L@$L@:@#L@K:L%@^$:"#^#:^J$%:K^J%&LK:#::&&^^^%%test
+ assert last parse logs is not set with "skript should be able to handle very messy string but did not"
+
+
+ parse:
+ set {_a##} to "test"
+ set {##_b} to "test"
+ set {##_b::%"{}"%} to "test"
+ set {##_b::%"{}#"%} to "#test"
+ assert {##_b::%"{}#"%} is join "#" and "test" with "failed state machine check"
+ assert last parse logs is not set with "skript should be able to handle hashtags in variable names but did not"
+
+
+ parse:
+ set {##_b::%"{}"#%} to "#test"
+ assert last parse logs is set with "skript should not be able to handle hashtags in an expression in a variable name but did"
diff --git a/src/test/skript/tests/regressions/4235-floating point errors rounding functions.sk b/src/test/skript/tests/regressions/4235-floating point errors rounding functions.sk
index ad8ecff83d5..4afe12bc824 100644
--- a/src/test/skript/tests/regressions/4235-floating point errors rounding functions.sk
+++ b/src/test/skript/tests/regressions/4235-floating point errors rounding functions.sk
@@ -1,12 +1,12 @@
test "floating point errors in rounding functions":
- #assert ceil(100*0.07) is 7 with "ceil function doesn't adjust for floating point errors ##1"
- #assert ceil(100*0.033 - 0.3) is 3 with "ceil function doesn't adjust for floating point errors ##2"
+ #assert ceil(100*0.07) is 7 with "ceil function doesn't adjust for floating point errors"
+ #assert ceil(100*0.033 - 0.3) is 3 with "ceil function doesn't adjust for floating point errors"
- #assert rounded up 100*0.07 is 7 with "ceil expression doesn't adjust for floating point errors ##1"
- #assert rounded up 100*0.033 - 0.3 is 3 with "ceil expression doesn't adjust for floating point errors ##2"
+ #assert rounded up 100*0.07 is 7 with "ceil expression doesn't adjust for floating point errors"
+ #assert rounded up 100*0.033 - 0.3 is 3 with "ceil expression doesn't adjust for floating point errors"
set {_sum} to 0
loop 100 times:
add 0.1 to {_sum}
- assert floor({_sum}) is 10 with "floor function doesn't adjust for floating point errors ##1"
- assert rounded down {_sum} is 10 with "floor expression doesn't adjust for floating point errors ##1"
+ assert floor({_sum}) is 10 with "floor function doesn't adjust for floating point errors"
+ assert rounded down {_sum} is 10 with "floor expression doesn't adjust for floating point errors"
diff --git a/src/test/skript/tests/regressions/4664-formatted time.sk b/src/test/skript/tests/regressions/4664-formatted time.sk
index 329c06bb9fa..a43029af91b 100644
--- a/src/test/skript/tests/regressions/4664-formatted time.sk
+++ b/src/test/skript/tests/regressions/4664-formatted time.sk
@@ -3,18 +3,18 @@ test "formatted time":
set {_now} to now
set {_date1} to {_now} formatted
- assert {_date1} = {_now} formatted as {_default} with "default date format failed ##1"
+ assert {_date1} = {_now} formatted as {_default} with "default date format failed"
set {_date2} to {_now} formatted human-readable
- assert {_date2} = {_now} formatted as {_default} with "default date format failed ##2"
+ assert {_date2} = {_now} formatted as {_default} with "default date format failed"
set {_date3} to {_now} formatted as "HH:mm"
- assert length of {_date3} = 5 with "custom date format failed ##1"
+ assert length of {_date3} = 5 with "custom date format failed"
set {_cFormat} to "hh:mm"
set {_date4} to {_now} formatted as {_cFormat}
- assert length of {_date4} = 5 with "custom date format failed ##2"
+ assert length of {_date4} = 5 with "custom date format failed"
set {_cFormat2} to "i"
set {_date5} to {_now} formatted as {_cFormat2}
- assert {_date5} is not set with "custom date format failed ##3"
+ assert {_date5} is not set with "custom date format failed"
diff --git a/src/test/skript/tests/regressions/4769-fire-visualeffect.sk b/src/test/skript/tests/regressions/4769-fire-visualeffect.sk
index 3965e6c877f..c490fa9e9cb 100644
--- a/src/test/skript/tests/regressions/4769-fire-visualeffect.sk
+++ b/src/test/skript/tests/regressions/4769-fire-visualeffect.sk
@@ -8,8 +8,8 @@ test "fire visual effect comparison":
set block at spawn of world "world" to {_block}
play 5 fire at spawn of world "world"
assert "fire" parsed as visual effect is fire with "failed to compare visual effects"
- assert "fire" parsed as visual effect is "fire" parsed as itemtype to fail with "failed to compare visual effects ##2"
+ assert "fire" parsed as visual effect is "fire" parsed as itemtype to fail with "failed to compare visual effects"
spawn a chicken at spawn of world "world":
assert event-entity is a chicken with "failed to compare a chicken"
- assert event-entity is a "chicken" parsed as itemtype to fail with "failed to compare a chicken ##2"
+ assert event-entity is a "chicken" parsed as itemtype to fail with "failed to compare a chicken"
clear event-entity
diff --git a/src/test/skript/tests/regressions/535-math is done in the wrong order.sk b/src/test/skript/tests/regressions/535-math is done in the wrong order.sk
index 665ce0346f8..b404c89846d 100644
--- a/src/test/skript/tests/regressions/535-math is done in the wrong order.sk
+++ b/src/test/skript/tests/regressions/535-math is done in the wrong order.sk
@@ -1,10 +1,10 @@
test "math order":
- assert 1 + 1 = 2 with "basic math ##1 failed"
- assert 5 - 3 = 2 with "basic math ##2 failed"
+ assert 1 + 1 = 2 with "basic math failed"
+ assert 5 - 3 = 2 with "basic math failed"
- assert 5 - 3 - 1 = 1 with "basic chained math ##1 failed"
- assert 5-3-2 = 0 with "basic chained math ##2 failed"
- assert 10 - 1 - 5 = 4 with "basic chained math ##3 failed"
+ assert 5 - 3 - 1 = 1 with "basic chained math failed"
+ assert 5-3-2 = 0 with "basic chained math failed"
+ assert 10 - 1 - 5 = 4 with "basic chained math failed"
- assert (9 - 1) - 3 = 5 with "basic chained math with parentheses ##1 failed"
- assert 9 - (1 - 3) = 11 with "basic chained math with parentheses ##2 failed"
+ assert (9 - 1) - 3 = 5 with "basic chained math with parentheses failed"
+ assert 9 - (1 - 3) = 11 with "basic chained math with parentheses failed"
diff --git a/src/test/skript/tests/regressions/590-escaping quotes is required in some places it shouldn't be.sk b/src/test/skript/tests/regressions/590-escaping quotes is required in some places it shouldn't be.sk
index cfa2aaa63e9..f0b63a43f23 100644
--- a/src/test/skript/tests/regressions/590-escaping quotes is required in some places it shouldn't be.sk
+++ b/src/test/skript/tests/regressions/590-escaping quotes is required in some places it shouldn't be.sk
@@ -8,8 +8,8 @@ test "double quote parsing":
assert "Testing """ is set with "simple string with escaped quote failed"
- assert "Testing %length of "abc"%" is set with "string with expression with string ##1 failed"
- assert "%myFunction_five_nine_zero("Hello")% world" is "Hello world" with "string with expression with string ##2 failed"
+ assert "Testing %length of "abc"%" is set with "string with expression with string failed"
+ assert "%myFunction_five_nine_zero("Hello")% world" is "Hello world" with "string with expression with string failed"
assert {_abc} is not set with "simple variable failed"
diff --git a/src/test/skript/tests/regressions/837-getting a uuid of a var inside code.sk b/src/test/skript/tests/regressions/837-getting a uuid of a var inside code.sk
index 1da43a1f75d..e05e22b9639 100644
--- a/src/test/skript/tests/regressions/837-getting a uuid of a var inside code.sk
+++ b/src/test/skript/tests/regressions/837-getting a uuid of a var inside code.sk
@@ -2,8 +2,8 @@ test "variable parsing":
assert {_test::%{_x}%} is not set with "simple list index using local variable failed"
assert {_test::{_x}} is not set to fail with "list index with local variable without percentage signs failed"
- assert {_test::%uuid of {_x}%} is not set with "list index with expression and local variable ##1 failed"
- assert {_test::%{_x}'s uuid%} is not set with "list index with expression and local variable ##2 failed"
+ assert {_test::%uuid of {_x}%} is not set with "list index with expression and local variable failed"
+ assert {_test::%{_x}'s uuid%} is not set with "list index with expression and local variable failed"
assert {_test::%{_a} split at {_b}%} is not set with "list index with expression with local variables on both ends failed"
diff --git a/src/test/skript/tests/syntaxes/conditions/CondContains.sk b/src/test/skript/tests/syntaxes/conditions/CondContains.sk
index e076c90f83f..fcc247bb7c0 100644
--- a/src/test/skript/tests/syntaxes/conditions/CondContains.sk
+++ b/src/test/skript/tests/syntaxes/conditions/CondContains.sk
@@ -1,34 +1,34 @@
test "contains condition":
# Strings
- assert "abc" contains "b" with "simple string contains failed ##1"
- assert "abc" contains "abc" with "simple string contains failed ##2"
- assert "abc" and "cde" contain "c" with "simple string contains failed ##3"
- assert "abc" does not contain "d" with "simple string contains failed ##4"
- assert "abc" and "def" do not contain "ghi" with "simple string contains failed ##5"
- assert "abc" and "def" does not contain "ab" with "string object failed ##6"
+ assert "abc" contains "b" with "simple string contains failed"
+ assert "abc" contains "abc" with "simple string contains failed"
+ assert "abc" and "cde" contain "c" with "simple string contains failed"
+ assert "abc" does not contain "d" with "simple string contains failed"
+ assert "abc" and "def" do not contain "ghi" with "simple string contains failed"
+ assert "abc" and "def" does not contain "ab" with "string object failed"
# Objects
- assert "abc" and "def" contains "abc" with "object contains failed ##1"
- assert 123 and 456 contains 456 with "object contains failed ##2"
- assert 123 and 456 does not contain 789 with "object contains failed ##3"
- assert 123 contains 123 with "object contains failed ##4"
+ assert "abc" and "def" contains "abc" with "object contains failed"
+ assert 123 and 456 contains 456 with "object contains failed"
+ assert 123 and 456 does not contain 789 with "object contains failed"
+ assert 123 contains 123 with "object contains failed"
set {_l::*} to 5 times
- assert {_l::*} contains 5 with "object contains failed ##5"
- assert {_l::*} does not contain 6 with "object contains failed ##6"
+ assert {_l::*} contains 5 with "object contains failed"
+ assert {_l::*} does not contain 6 with "object contains failed"
# Inventory
set {_inv} to chest inventory with 3 rows
set slot 0 of {_inv} to stone named "pp"
set slot 1 of {_inv} to dirt
- assert {_inv} contains stone with "inventory contains failed ##1"
- assert {_inv} contains stone named "pp" with "inventory contains failed ##2"
- assert {_inv} does not contain stone named "abc" with "inventory contains failed ##3"
- assert {_inv} does not contain sand with "inventory contains failed ##4"
- assert {_inv} contains dirt with "inventory contains failed ##5"
- assert {_inv} does not contain 2 dirt with "inventory contains failed ##6"
+ assert {_inv} contains stone with "inventory contains failed"
+ assert {_inv} contains stone named "pp" with "inventory contains failed"
+ assert {_inv} does not contain stone named "abc" with "inventory contains failed"
+ assert {_inv} does not contain sand with "inventory contains failed"
+ assert {_inv} contains dirt with "inventory contains failed"
+ assert {_inv} does not contain 2 dirt with "inventory contains failed"
set slot 2 of {_inv} to dirt
- assert {_inv} contains 2 dirt with "inventory contains failed ##7"
- assert {_inv} does not contain 3 dirt with "inventory contains failed ##8"
+ assert {_inv} contains 2 dirt with "inventory contains failed"
+ assert {_inv} does not contain 3 dirt with "inventory contains failed"
set {_inv1} to chest inventory with 3 rows
set {_inv2} to chest inventory with 3 rows
diff --git a/src/test/skript/tests/syntaxes/conditions/CondIsWithin.sk b/src/test/skript/tests/syntaxes/conditions/CondIsWithin.sk
index a0c4339f556..b432c72f0ff 100644
--- a/src/test/skript/tests/syntaxes/conditions/CondIsWithin.sk
+++ b/src/test/skript/tests/syntaxes/conditions/CondIsWithin.sk
@@ -2,32 +2,32 @@ test "within condition" when running minecraft "1.17":
# two locations
set {_loc1} to location(0, 0, 0, "world")
set {_loc2} to location(20, 20, 20, "world")
- assert location(10, 10, 10, "world") is within {_loc1} and {_loc2} with "failed within two locs ##1"
- assert location(10, -10, 10, "world") is not within {_loc1} and {_loc2} with "failed within two locs ##2"
+ assert location(10, 10, 10, "world") is within {_loc1} and {_loc2} with "failed within two locs"
+ assert location(10, -10, 10, "world") is not within {_loc1} and {_loc2} with "failed within two locs"
# chunks
set {_chunk1} to chunk at {_loc1}
- assert location(10, 10, 10, "world") is within {_chunk1} with "failed within chunk ##1"
- assert location(-10, 10, -10, "world") is not within {_chunk1} with "failed within chunk ##2"
+ assert location(10, 10, 10, "world") is within {_chunk1} with "failed within chunk"
+ assert location(-10, 10, -10, "world") is not within {_chunk1} with "failed within chunk"
# worlds
- assert location(10, 10, 10, "world") is within world("world") with "failed within world ##1"
+ assert location(10, 10, 10, "world") is within world("world") with "failed within world"
# blocks
set block at {_loc1} to stone
- assert {_loc1} is within block at {_loc1} with "failed within block ##1"
- assert {_loc2} is not within block at {_loc1} with "failed within block ##2"
+ assert {_loc1} is within block at {_loc1} with "failed within block"
+ assert {_loc2} is not within block at {_loc1} with "failed within block"
# special case, non-full blocks
set block at {_loc1} to lime carpet
- assert {_loc1} is within block at {_loc1} with "failed within block ##3"
- assert ({_loc1} ~ vector(0,0.3,0)) is not within block at {_loc1} with "failed within block ##4"
+ assert {_loc1} is within block at {_loc1} with "failed within block"
+ assert ({_loc1} ~ vector(0,0.3,0)) is not within block at {_loc1} with "failed within block"
# entities
set {_loc} to spawn of world "world"
spawn a pig at {_loc}
set {_pig} to last spawned entity
- assert {_loc} is within {_pig} with "failed within entity ##1"
- assert {_loc1} is not within {_pig} with "failed within entity ##2"
+ assert {_loc} is within {_pig} with "failed within entity"
+ assert {_loc1} is not within {_pig} with "failed within entity"
delete random entity of {_pig}
@@ -35,22 +35,22 @@ test "within condition" when running below minecraft "1.17":
# two locations
set {_loc1} to location(0, 0, 0, "world")
set {_loc2} to location(20, 20, 20, "world")
- assert location(10, 10, 10, "world") is within {_loc1} and {_loc2} with "failed within two locs ##1"
- assert location(10, -10, 10, "world") is not within {_loc1} and {_loc2} with "failed within two locs ##2"
+ assert location(10, 10, 10, "world") is within {_loc1} and {_loc2} with "failed within two locs"
+ assert location(10, -10, 10, "world") is not within {_loc1} and {_loc2} with "failed within two locs"
# chunks
set {_chunk1} to chunk at {_loc1}
- assert location(10, 10, 10, "world") is within {_chunk1} with "failed within chunk ##1"
- assert location(-10, 10, -10, "world") is not within {_chunk1} with "failed within chunk ##2"
+ assert location(10, 10, 10, "world") is within {_chunk1} with "failed within chunk"
+ assert location(-10, 10, -10, "world") is not within {_chunk1} with "failed within chunk"
# worlds
- assert location(10, 10, 10, "world") is within world("world") with "failed within world ##1"
+ assert location(10, 10, 10, "world") is within world("world") with "failed within world"
# entities
set {_loc} to spawn of world "world"
spawn a pig at {_loc}
set {_pig} to last spawned entity
- assert {_loc} is within {_pig} with "failed within entity ##1"
- assert {_loc1} is not within {_pig} with "failed within entity ##2"
+ assert {_loc} is within {_pig} with "failed within entity"
+ assert {_loc1} is not within {_pig} with "failed within entity"
delete random entity of {_pig}
diff --git a/src/test/skript/tests/syntaxes/conditions/CondMethodExists.sk b/src/test/skript/tests/syntaxes/conditions/CondMethodExists.sk
index e34bac7daac..538f8f5be04 100644
--- a/src/test/skript/tests/syntaxes/conditions/CondMethodExists.sk
+++ b/src/test/skript/tests/syntaxes/conditions/CondMethodExists.sk
@@ -1,10 +1,10 @@
test "method exists":
- assert method "java.lang.String##length()" exists with "Existing method was not found"
- assert method "java.lang.String##notReal()" doesn't exist with "Fake method was found"
- assert method "java.lang.SuperFakeClass##notReal()" doesn't exist with "Fake class was found"
- assert method "java.lang.String##indexOf(java.lang.String)" exists with "Existing method with parameter was not found"
- assert method "java.lang.String##replace(java.lang.CharSequence,java.lang.CharSequence)" exists with "Existing method with multiple parameters not found"
- assert method "java.lang.String##charAt(int)" exists with "Existing method with primitive parameter not found"
- assert method "java.lang.String##substring(int,int)" exists with "Existing method with multiple primitive parameters not found"
- assert method "java.lang.String##valueOf(char[])" exists with "Existing method with primitive array parameter not found"
- assert method "java.lang.Runtime##exec(java.lang.String[],java.lang.String[])" exists with "Existing method with array parameter not found"
+ assert method "java.lang.String#length()" exists with "Existing method was not found"
+ assert method "java.lang.String#notReal()" doesn't exist with "Fake method was found"
+ assert method "java.lang.SuperFakeClass#notReal()" doesn't exist with "Fake class was found"
+ assert method "java.lang.String#indexOf(java.lang.String)" exists with "Existing method with parameter was not found"
+ assert method "java.lang.String#replace(java.lang.CharSequence,java.lang.CharSequence)" exists with "Existing method with multiple parameters not found"
+ assert method "java.lang.String#charAt(int)" exists with "Existing method with primitive parameter not found"
+ assert method "java.lang.String#substring(int,int)" exists with "Existing method with multiple primitive parameters not found"
+ assert method "java.lang.String#valueOf(char[])" exists with "Existing method with primitive array parameter not found"
+ assert method "java.lang.Runtime#exec(java.lang.String[],java.lang.String[])" exists with "Existing method with array parameter not found"
diff --git a/src/test/skript/tests/syntaxes/effects/EffContinue.sk b/src/test/skript/tests/syntaxes/effects/EffContinue.sk
index 83804bc908f..2400e7441e0 100644
--- a/src/test/skript/tests/syntaxes/effects/EffContinue.sk
+++ b/src/test/skript/tests/syntaxes/effects/EffContinue.sk
@@ -11,9 +11,9 @@ test "continue effect":
assert {_i} is not 5 with "continue in while failed"
loop integers from 1 to 10:
continue this loop if loop-value is 5
- assert loop-value is not 5 with "leveled continue failed ##1"
+ assert loop-value is not 5 with "leveled continue failed"
loop integers from 11 to 20:
continue 2nd loop if loop-value-2 is 15
- assert loop-value-2 is not 15 with "leveled continue failed ##2"
+ assert loop-value-2 is not 15 with "leveled continue failed"
continue 1st loop if loop-value-1 is 10
- assert loop-value is not 10 with "leveled continue failed ##3"
+ assert loop-value is not 10 with "leveled continue failed"
diff --git a/src/test/skript/tests/syntaxes/effects/EffHealth.sk b/src/test/skript/tests/syntaxes/effects/EffHealth.sk
index 41ecf33904b..b77c566076b 100644
--- a/src/test/skript/tests/syntaxes/effects/EffHealth.sk
+++ b/src/test/skript/tests/syntaxes/effects/EffHealth.sk
@@ -11,13 +11,13 @@ test "health effect":
set {_m} to last spawned cow
assert health of {_m} is 5 with "default cow health failed"
damage {_m} by 0.5
- assert health of {_m} is 4.5 with "damage cow ##1 failed"
+ assert health of {_m} is 4.5 with "damage cow failed"
damage {_m} by 99
- assert health of {_m} is 0 with "damage cow ##2 failed"
+ assert health of {_m} is 0 with "damage cow failed"
heal {_m} by 1
- assert health of {_m} is 1 with "heal cow ##1 failed"
+ assert health of {_m} is 1 with "heal cow failed"
heal {_m} by 0.5
- assert health of {_m} is 1.5 with "heal cow ##2 failed"
+ assert health of {_m} is 1.5 with "heal cow failed"
heal {_m} by 99
- assert health of {_m} is 5 with "heal cow ##3 failed"
+ assert health of {_m} is 5 with "heal cow failed"
clear all entities
diff --git a/src/test/skript/tests/syntaxes/expressions/ExprArrowsStuck.sk b/src/test/skript/tests/syntaxes/expressions/ExprArrowsStuck.sk
index 9b41359b7af..aa577e45d4c 100644
--- a/src/test/skript/tests/syntaxes/expressions/ExprArrowsStuck.sk
+++ b/src/test/skript/tests/syntaxes/expressions/ExprArrowsStuck.sk
@@ -4,15 +4,15 @@ test "arrows stuck":
set arrows stuck in event-entity to 31
assert arrows stuck in event-entity is 31 with "arrows stuck set failed"
add 5 to arrows stuck in event-entity
- assert arrows stuck in event-entity is 36 with "arrows stuck add ##1 failed"
+ assert arrows stuck in event-entity is 36 with "arrows stuck add failed"
remove 10 from arrows stuck in event-entity
- assert arrows stuck in event-entity is 26 with "arrows stuck remove ##1 failed"
+ assert arrows stuck in event-entity is 26 with "arrows stuck remove failed"
remove 999 from arrows stuck in event-entity
- assert arrows stuck in event-entity is 0 with "arrows stuck remove ##2 failed"
+ assert arrows stuck in event-entity is 0 with "arrows stuck remove failed"
remove -2 from arrows stuck in event-entity
- assert arrows stuck in event-entity is 2 with "arrows stuck remove ##3 failed"
+ assert arrows stuck in event-entity is 2 with "arrows stuck remove failed"
add -1 to arrows stuck in event-entity
- assert arrows stuck in event-entity is 1 with "arrows stuck add ##2 failed"
+ assert arrows stuck in event-entity is 1 with "arrows stuck add failed"
delete arrows stuck in event-entity
assert arrows stuck in event-entity is 0 with "arrows stuck delete failed"
delete event-entity
diff --git a/src/test/skript/tests/syntaxes/expressions/ExprEntityAttribute.sk b/src/test/skript/tests/syntaxes/expressions/ExprEntityAttribute.sk
index 730afc9d164..ed04483dbe0 100644
--- a/src/test/skript/tests/syntaxes/expressions/ExprEntityAttribute.sk
+++ b/src/test/skript/tests/syntaxes/expressions/ExprEntityAttribute.sk
@@ -6,9 +6,9 @@ test "attributes 1":
add 5 to movement speed attribute of event-entity
assert movement speed attribute of event-entity is 8.14 with "attribute add failed"
remove 4 from movement speed attribute of event-entity
- assert movement speed attribute of event-entity is 4.14 with "attribute remove ##1 failed"
+ assert movement speed attribute of event-entity is 4.14 with "attribute remove failed"
remove 10 from movement speed attribute of event-entity
- assert movement speed attribute of event-entity is -5.86 with "attribute remove ##2 failed" # Negative attribute values should be safe
+ assert movement speed attribute of event-entity is -5.86 with "attribute remove failed" # Negative attribute values should be safe
delete movement speed attribute of event-entity
assert movement speed attribute of event-entity is 0 with "attribute delete failed"
delete event-entity
diff --git a/src/test/skript/tests/syntaxes/expressions/ExprFreezeTicks.sk b/src/test/skript/tests/syntaxes/expressions/ExprFreezeTicks.sk
index c6e47ec617e..7caec6fcb3f 100644
--- a/src/test/skript/tests/syntaxes/expressions/ExprFreezeTicks.sk
+++ b/src/test/skript/tests/syntaxes/expressions/ExprFreezeTicks.sk
@@ -4,14 +4,14 @@ test "freeze time" when running minecraft "1.18":
set freeze time of entity to 3 seconds
assert freeze time of entity is 3 seconds with "freeze time set failed"
add 2 seconds to freeze time of entity
- assert freeze time of entity is 5 seconds with "freeze time add ##1 failed"
+ assert freeze time of entity is 5 seconds with "freeze time add failed"
add 10 seconds to freeze time of entity
- assert freeze time of entity is 15 seconds with "freeze time add ##2 failed" # freeze time should not be capped at entity's max freeze time (7 seconds for a cow)
+ assert freeze time of entity is 15 seconds with "freeze time add failed" # freeze time should not be capped at entity's max freeze time (7 seconds for a cow)
remove 6 seconds from freeze time of entity
- assert freeze time of entity is 9 seconds with "freeze time remove ##1 failed"
+ assert freeze time of entity is 9 seconds with "freeze time remove failed"
remove 10 seconds from freeze time of entity
- assert freeze time of entity is 0 seconds with "freeze time remove ##2 failed" # freeze time should not be negative
+ assert freeze time of entity is 0 seconds with "freeze time remove failed" # freeze time should not be negative
delete freeze time of entity
assert freeze time of entity is 0 seconds with "freeze time delete failed"
diff --git a/src/test/skript/tests/syntaxes/expressions/ExprItemsIn.sk b/src/test/skript/tests/syntaxes/expressions/ExprItemsIn.sk
index 9b2c90fb25f..b5ef324b555 100644
--- a/src/test/skript/tests/syntaxes/expressions/ExprItemsIn.sk
+++ b/src/test/skript/tests/syntaxes/expressions/ExprItemsIn.sk
@@ -5,8 +5,8 @@ test "filtering ExprItemsIn":
set slot 1 of {_inv} to dirt
set slot 2 of {_inv} to stone
set slot 3 of {_inv} to bucket
- assert all blocks in inventory {_inv} are dirt or stone with "found correct items with ExprItemsIn##get"
- assert (all blocks in inventory {_inv} where [true is true]) are dirt or stone with "found correct items with ExprItemsIn##iterator"
+ assert all blocks in inventory {_inv} are dirt or stone with "found correct items with ExprItemsIn#get"
+ assert (all blocks in inventory {_inv} where [true is true]) are dirt or stone with "found correct items with ExprItemsIn#iterator"
set {_dirt} to dirt
assert all {_dirt} in inventory {_inv} is dirt with "found incorrect items with variable itemtypes"
@@ -17,5 +17,5 @@ test "unfiltered ExprItemsIn":
set slot 1 of {_inv} to dirt
set slot 2 of {_inv} to stone
set slot 3 of {_inv} to bucket
- assert all items in inventory {_inv} are dirt, stone or bucket with "found correct items with ExprItemsIn##get"
- assert (all items in inventory {_inv} where [true is true]) are dirt, stone or bucket with "found correct items with ExprItemsIn##iterator"
+ assert all items in inventory {_inv} are dirt, stone or bucket with "found correct items with ExprItemsIn#get"
+ assert (all items in inventory {_inv} where [true is true]) are dirt, stone or bucket with "found correct items with ExprItemsIn#iterator"
diff --git a/src/test/skript/tests/syntaxes/expressions/ExprNoDamageTicks.sk b/src/test/skript/tests/syntaxes/expressions/ExprNoDamageTicks.sk
index 794dffa6e87..2d314c9e6d2 100644
--- a/src/test/skript/tests/syntaxes/expressions/ExprNoDamageTicks.sk
+++ b/src/test/skript/tests/syntaxes/expressions/ExprNoDamageTicks.sk
@@ -5,14 +5,14 @@ test "no damage ticks":
set {_m}'s invulnerability ticks to 25
assert {_m}'s invulnerability ticks is 25 with "no damage ticks set failed"
add 5 to {_m}'s invulnerability ticks
- assert {_m}'s invulnerability ticks is 30 with "no damage ticks add ##1 failed"
+ assert {_m}'s invulnerability ticks is 30 with "no damage ticks add failed"
remove 12 from {_m}'s invulnerability ticks
- assert {_m}'s invulnerability ticks is 18 with "no damage ticks remove ##1 failed"
+ assert {_m}'s invulnerability ticks is 18 with "no damage ticks remove failed"
remove 999 from {_m}'s invulnerability ticks
- assert {_m}'s invulnerability ticks is 0 with "no damage ticks remove ##2 failed"
+ assert {_m}'s invulnerability ticks is 0 with "no damage ticks remove failed"
remove -2 from {_m}'s invulnerability ticks
- assert {_m}'s invulnerability ticks is 2 with "no damage ticks remove ##3 failed"
+ assert {_m}'s invulnerability ticks is 2 with "no damage ticks remove failed"
add -1 to {_m}'s invulnerability ticks
- assert {_m}'s invulnerability ticks is 1 with "no damage ticks add ##2 failed"
+ assert {_m}'s invulnerability ticks is 1 with "no damage ticks add failed"
delete {_m}'s invulnerability ticks
assert {_m}'s invulnerability ticks is 0 with "no damage ticks delete failed"
diff --git a/src/test/skript/tests/syntaxes/expressions/ExprPortalCooldown.sk b/src/test/skript/tests/syntaxes/expressions/ExprPortalCooldown.sk
index 7d919d788da..36b95564dc7 100644
--- a/src/test/skript/tests/syntaxes/expressions/ExprPortalCooldown.sk
+++ b/src/test/skript/tests/syntaxes/expressions/ExprPortalCooldown.sk
@@ -4,11 +4,11 @@ test "portal cooldown":
set event-entity's portal cooldown to 25 ticks
assert event-entity's portal cooldown is 25 ticks with "portal cooldown set failed"
add 5 seconds to event-entity's portal cooldown
- assert event-entity's portal cooldown is 125 ticks with "portal cooldown add ##1 failed"
+ assert event-entity's portal cooldown is 125 ticks with "portal cooldown add failed"
remove 12 ticks from event-entity's portal cooldown
- assert event-entity's portal cooldown is 113 ticks with "portal cooldown remove ##1 failed"
+ assert event-entity's portal cooldown is 113 ticks with "portal cooldown remove failed"
remove 999 ticks from event-entity's portal cooldown
- assert event-entity's portal cooldown is 0 ticks with "portal cooldown remove ##2 failed"
+ assert event-entity's portal cooldown is 0 ticks with "portal cooldown remove failed"
delete event-entity's portal cooldown
assert event-entity's portal cooldown is 0 ticks with "portal cooldown delete failed"
reset event-entity's portal cooldown
diff --git a/src/test/skript/tests/syntaxes/functions/caseEquals.sk b/src/test/skript/tests/syntaxes/functions/caseEquals.sk
index f777e6ff7df..ace8276da6e 100644
--- a/src/test/skript/tests/syntaxes/functions/caseEquals.sk
+++ b/src/test/skript/tests/syntaxes/functions/caseEquals.sk
@@ -1,6 +1,6 @@
test "case equals function":
- assert caseEquals("") is true with "case equals function failed ##1"
- assert caseEquals("dummy") is true with "case equals function failed ##2"
- assert caseEquals("hi", "Hi") is false with "case equals function failed ##3"
- assert caseEquals("text", "text", "tExt") is false with "case equals function failed ##4"
- assert caseEquals("🐢<-turtle", "🐢<-turtle", "🐢<-turtle", "🐢<-turtle") is true with "case equals function failed ##5"
+ assert caseEquals("") is true with "case equals function failed"
+ assert caseEquals("dummy") is true with "case equals function failed"
+ assert caseEquals("hi", "Hi") is false with "case equals function failed"
+ assert caseEquals("text", "text", "tExt") is false with "case equals function failed"
+ assert caseEquals("🐢<-turtle", "🐢<-turtle", "🐢<-turtle", "🐢<-turtle") is true with "case equals function failed"
diff --git a/src/test/skript/tests/syntaxes/sections/SecConditional.sk b/src/test/skript/tests/syntaxes/sections/SecConditional.sk
index f9991e9f621..4957319f369 100644
--- a/src/test/skript/tests/syntaxes/sections/SecConditional.sk
+++ b/src/test/skript/tests/syntaxes/sections/SecConditional.sk
@@ -18,18 +18,18 @@ test "SecConditional":
delete {_b}
1 = 2
else if 1 = 1:
- assert 1 = 2 with "conditional failed ##1"
+ assert 1 = 2 with "conditional failed"
else:
- assert 1 = 2 with "conditional failed ##2"
+ assert 1 = 2 with "conditional failed"
if {_b} is set:
- assert 1 = 2 with "conditional failed ##3"
+ assert 1 = 2 with "conditional failed"
if 1 = 2:
- assert 1 = 2 with "conditional failed ##4"
+ assert 1 = 2 with "conditional failed"
else if 1 = 1:
exit 1 section
else:
- assert 1 = 2 with "conditional failed ##5"
+ assert 1 = 2 with "conditional failed"
test "SecConditional - if all true":
if: