Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion realscoreboard-api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -102,5 +102,11 @@
<version>1.18.46</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,21 @@
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;

import java.util.regex.Pattern;

@Getter
@Setter
public class Condition {
private static final Pattern NUMBER_PATTERN = Pattern.compile(
"[+-]?(?:" +
"NaN|Infinity|" +
"(?:" +
"(?:[0-9]+(?:\\.[0-9]*)?|\\.[0-9]+)(?:[eE][+-]?[0-9]+)?|" +
"0[xX](?:[0-9a-fA-F]+(?:\\.[0-9a-fA-F]*)?|\\.[0-9a-fA-F]+)[pP][+-]?[0-9]+" +
")[fFdD]?" +
")"
);

private String condition, met, notMet;
private RealScoreboardAPI rsa;

Expand Down Expand Up @@ -54,20 +66,15 @@ public boolean parseExpression(String expression) {
return evaluate(left, operator, right);
}

// Helper method to parse operands as integers, doubles, booleans, or strings
// Helper method to parse operands as numbers, booleans, or strings
private Object parseValue(String value) {
// Try to parse as an integer
try {
return Integer.parseInt(value);
} catch (NumberFormatException e) {
// Not an integer, continue
Integer integer = parseInteger(value);
if (integer != null) {
return integer;
}

// Try to parse as a double
try {
if (NUMBER_PATTERN.matcher(value).matches()) {
return Double.parseDouble(value);
} catch (NumberFormatException e) {
// Not a double, continue
}

// Try to parse as a boolean
Expand All @@ -79,6 +86,43 @@ private Object parseValue(String value) {
return value;
}

private Integer parseInteger(String value) {
if (value == null || value.isEmpty()) {
return null;
}

int index = 0;
boolean negative = false;
char first = value.charAt(0);
if (first == '-' || first == '+') {
negative = first == '-';
index++;
}

if (index == value.length()) {
return null;
}

int limit = negative ? Integer.MIN_VALUE : -Integer.MAX_VALUE;
int multiplicationLimit = limit / 10;
int result = 0;

while (index < value.length()) {
int digit = Character.digit(value.charAt(index++), 10);
if (digit < 0 || result < multiplicationLimit) {
return null;
}

result *= 10;
if (result < limit + digit) {
return null;
}
result -= digit;
}

return negative ? result : -result;
}

// Helper method to evaluate the expression based on the operator
private boolean evaluate(Object left, String operator, Object right) {
// Handle numeric comparisons (Integer and Double)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package joserodpt.realscoreboard.api.conditions;

import org.junit.Test;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

public class ConditionTest {
private final Condition condition = new Condition(null, "", "", "");

@Test
public void evaluatesTextWithoutChangingStringOperators() {
assertTrue(condition.parseExpression("compact == compact"));
assertTrue(condition.parseExpression("full != compact"));
assertTrue(condition.parseExpression("compact startsWith comp"));
assertTrue(condition.parseExpression("full contains ull"));
assertTrue(condition.parseExpression("1.2.3 == 1.2.3"));
assertFalse(condition.parseExpression("compact == full"));
}

@Test
public void preservesIntegerAndFloatingPointComparisons() {
assertTrue(condition.parseExpression("2147483647 == 2147483647"));
assertTrue(condition.parseExpression("-2147483648 == -2147483648"));
assertTrue(condition.parseExpression("\u0661 == 1"));
assertTrue(condition.parseExpression("2147483648 > 2147483647"));
assertTrue(condition.parseExpression("1.25 < 1.5"));
assertTrue(condition.parseExpression("1e3 == 1000"));
assertTrue(condition.parseExpression("1f == 1"));
assertTrue(condition.parseExpression("0x1.0p2 == 4"));
assertTrue(condition.parseExpression("Infinity > 1"));
assertFalse(condition.parseExpression("NaN == NaN"));
}

@Test
public void preservesBooleanComparisons() {
assertTrue(condition.parseExpression("true == true"));
assertTrue(condition.parseExpression("true != false"));
assertFalse(condition.parseExpression("false != false"));
}
}