fix(wired): bound variable payloads

This commit is contained in:
simoleo89
2026-06-17 19:55:04 +02:00
parent 416d0bb088
commit c83cd22fff
3 changed files with 86 additions and 16 deletions
@@ -35,6 +35,7 @@ public class WiredConditionVariableAgeMatch extends WiredConditionHasVariable {
private static final int DURATION_UNIT_WEEKS = 5;
private static final int DURATION_UNIT_MONTHS = 6;
private static final int DURATION_UNIT_YEARS = 7;
static final int MAX_DURATION_AMOUNT = 1_000_000;
protected int compareValue = COMPARE_VALUE_CREATED;
protected int comparison = COMPARISON_LOWER_THAN;
@@ -97,7 +98,7 @@ public class WiredConditionVariableAgeMatch extends WiredConditionHasVariable {
this.targetType = (params.length > 0) ? normalizeTargetTypeExtended(params[0]) : TARGET_USER;
this.compareValue = (params.length > 1) ? normalizeCompareValue(params[1]) : COMPARE_VALUE_CREATED;
this.comparison = (params.length > 2) ? normalizeComparison(params[2]) : COMPARISON_LOWER_THAN;
this.durationAmount = Math.max(0, (params.length > 3) ? params[3] : 0);
this.durationAmount = normalizeDurationAmount((params.length > 3) ? params[3] : 0);
this.durationUnit = (params.length > 4) ? normalizeDurationUnit(params[4]) : DURATION_UNIT_SECONDS;
this.userSource = (params.length > 5) ? normalizeUserSource(params[5]) : WiredSourceUtil.SOURCE_TRIGGER;
this.furniSource = (params.length > 6) ? normalizeFurniSource(params[6]) : WiredSourceUtil.SOURCE_TRIGGER;
@@ -130,6 +131,10 @@ public class WiredConditionVariableAgeMatch extends WiredConditionHasVariable {
@Override
public boolean evaluate(WiredContext ctx) {
if (ctx == null) {
return false;
}
Room room = ctx.room();
if (room == null || this.variableToken == null || this.variableToken.isEmpty() || !isCustomVariableToken(this.variableToken)) {
@@ -192,7 +197,7 @@ public class WiredConditionVariableAgeMatch extends WiredConditionHasVariable {
this.targetType = normalizeTargetTypeExtended(data.targetType);
this.compareValue = normalizeCompareValue(data.compareValue);
this.comparison = normalizeComparison(data.comparison);
this.durationAmount = Math.max(0, data.durationAmount);
this.durationAmount = normalizeDurationAmount(data.durationAmount);
this.durationUnit = normalizeDurationUnit(data.durationUnit);
this.userSource = normalizeUserSource(data.userSource);
this.furniSource = normalizeFurniSource(data.furniSource);
@@ -345,8 +350,8 @@ public class WiredConditionVariableAgeMatch extends WiredConditionHasVariable {
return Math.max(0L, System.currentTimeMillis() - timestampMs);
}
private static long durationToMillis(int amount, int unit) {
long normalizedAmount = Math.max(0L, amount);
static long durationToMillis(int amount, int unit) {
long normalizedAmount = normalizeDurationAmount(amount);
return switch (unit) {
case DURATION_UNIT_MILLISECONDS -> normalizedAmount;
@@ -367,22 +372,26 @@ public class WiredConditionVariableAgeMatch extends WiredConditionHasVariable {
return left * right;
}
private static int normalizeTargetTypeExtended(int value) {
static int normalizeDurationAmount(int value) {
return Math.max(0, Math.min(MAX_DURATION_AMOUNT, value));
}
static int normalizeTargetTypeExtended(int value) {
return switch (value) {
case TARGET_FURNI, TARGET_CONTEXT, TARGET_ROOM -> value;
default -> TARGET_USER;
};
}
private static int normalizeCompareValue(int value) {
static int normalizeCompareValue(int value) {
return (value == COMPARE_VALUE_UPDATED) ? COMPARE_VALUE_UPDATED : COMPARE_VALUE_CREATED;
}
private static int normalizeComparison(int value) {
static int normalizeComparison(int value) {
return (value == COMPARISON_HIGHER_THAN) ? COMPARISON_HIGHER_THAN : COMPARISON_LOWER_THAN;
}
private static int normalizeDurationUnit(int value) {
static int normalizeDurationUnit(int value) {
return switch (value) {
case DURATION_UNIT_MILLISECONDS, DURATION_UNIT_SECONDS, DURATION_UNIT_MINUTES, DURATION_UNIT_HOURS,
DURATION_UNIT_DAYS, DURATION_UNIT_WEEKS, DURATION_UNIT_MONTHS, DURATION_UNIT_YEARS -> value;
@@ -51,6 +51,7 @@ public class WiredConditionVariableValueMatch extends WiredConditionHasVariable
private static final int COMPARISON_NOT_EQUAL = 5;
private static final String DELIM = "\t";
private static final String FURNI_DELIM = ";";
static final int MAX_ABS_REFERENCE_CONSTANT = 1_000_000_000;
protected int comparison = COMPARISON_EQUAL;
protected int referenceMode = REFERENCE_CONSTANT;
@@ -123,7 +124,7 @@ public class WiredConditionVariableValueMatch extends WiredConditionHasVariable
int nextTargetType = normalizeTargetTypeExtended(param(params, 0, TARGET_USER));
int nextComparison = normalizeComparison(param(params, 1, COMPARISON_EQUAL));
int nextReferenceMode = normalizeReferenceMode(param(params, 2, REFERENCE_CONSTANT));
int nextReferenceConstantValue = param(params, 3, 0);
int nextReferenceConstantValue = normalizeReferenceConstantValue(param(params, 3, 0));
int nextReferenceTargetType = normalizeTargetTypeExtended(param(params, 4, TARGET_USER));
int nextUserSource = normalizeUserSource(param(params, 5, WiredSourceUtil.SOURCE_TRIGGER));
int nextFurniSource = normalizeFurniSource(param(params, 6, WiredSourceUtil.SOURCE_TRIGGER));
@@ -168,6 +169,10 @@ public class WiredConditionVariableValueMatch extends WiredConditionHasVariable
@Override
public boolean evaluate(WiredContext ctx) {
if (ctx == null) {
return false;
}
Room room = ctx.room();
if (room == null || this.variableToken == null || this.variableToken.isEmpty()) {
@@ -220,14 +225,21 @@ public class WiredConditionVariableValueMatch extends WiredConditionHasVariable
String wiredData = set.getString("wired_data");
if (wiredData == null || wiredData.isEmpty() || !wiredData.startsWith("{")) return;
JsonData data = WiredManager.getGson().fromJson(wiredData, JsonData.class);
JsonData data;
try {
data = WiredManager.getGson().fromJson(wiredData, JsonData.class);
} catch (RuntimeException exception) {
this.onPickUp();
return;
}
if (data == null) return;
this.targetType = normalizeTargetTypeExtended(data.targetType);
this.setVariableToken(normalizeVariableToken((data.variableToken != null) ? data.variableToken : ((data.variableItemId > 0) ? String.valueOf(data.variableItemId) : "")));
this.comparison = normalizeComparison(data.comparison);
this.referenceMode = normalizeReferenceMode(data.referenceMode);
this.referenceConstantValue = data.referenceConstantValue;
this.referenceConstantValue = normalizeReferenceConstantValue(data.referenceConstantValue);
this.referenceTargetType = normalizeTargetTypeExtended(data.referenceTargetType);
this.setReferenceVariableToken(normalizeVariableToken((data.referenceVariableToken != null) ? data.referenceVariableToken : ((data.referenceVariableItemId > 0) ? String.valueOf(data.referenceVariableItemId) : "")));
this.userSource = normalizeUserSource(data.userSource);
@@ -737,32 +749,36 @@ public class WiredConditionVariableValueMatch extends WiredConditionHasVariable
return (params.length > index) ? params[index] : fallback;
}
private static int normalizeTargetTypeExtended(int value) {
static int normalizeTargetTypeExtended(int value) {
return switch (value) {
case TARGET_FURNI, TARGET_CONTEXT, TARGET_ROOM -> value;
default -> TARGET_USER;
};
}
private static int normalizeReferenceMode(int value) {
static int normalizeReferenceMode(int value) {
return (value == REFERENCE_VARIABLE) ? REFERENCE_VARIABLE : REFERENCE_CONSTANT;
}
private static int normalizeReferenceFurniSource(int value) {
static int normalizeReferenceFurniSource(int value) {
return switch (value) {
case SOURCE_SECONDARY_SELECTED, WiredSourceUtil.SOURCE_SELECTOR, WiredSourceUtil.SOURCE_SIGNAL -> value;
default -> WiredSourceUtil.SOURCE_TRIGGER;
};
}
private static int normalizeComparison(int value) {
static int normalizeComparison(int value) {
return switch (value) {
case COMPARISON_GREATER_THAN, COMPARISON_GREATER_THAN_OR_EQUAL, COMPARISON_LESS_THAN_OR_EQUAL, COMPARISON_LESS_THAN, COMPARISON_NOT_EQUAL -> value;
default -> COMPARISON_EQUAL;
};
}
private static int parseInteger(String value) {
static int normalizeReferenceConstantValue(int value) {
return Math.max(-MAX_ABS_REFERENCE_CONSTANT, Math.min(MAX_ABS_REFERENCE_CONSTANT, value));
}
static int parseInteger(String value) {
try {
return (value == null || value.trim().isEmpty()) ? 0 : Integer.parseInt(value.trim());
} catch (NumberFormatException e) {
@@ -0,0 +1,45 @@
package com.eu.habbo.habbohotel.items.interactions.wired.conditions;
import com.eu.habbo.habbohotel.wired.core.WiredSourceUtil;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
class WiredConditionVariablePayloadGuardTest {
@Test
void variableAgeDurationsAreBounded() {
assertEquals(0, WiredConditionVariableAgeMatch.normalizeDurationAmount(-1));
assertEquals(42, WiredConditionVariableAgeMatch.normalizeDurationAmount(42));
assertEquals(WiredConditionVariableAgeMatch.MAX_DURATION_AMOUNT, WiredConditionVariableAgeMatch.normalizeDurationAmount(Integer.MAX_VALUE));
assertEquals(0L, WiredConditionVariableAgeMatch.durationToMillis(-1, 1));
assertEquals(1_000L, WiredConditionVariableAgeMatch.durationToMillis(1, 1));
}
@Test
void variableAgeModesFallBackToSafeDefaults() {
assertEquals(0, WiredConditionVariableAgeMatch.normalizeTargetTypeExtended(999));
assertEquals(1, WiredConditionVariableAgeMatch.normalizeTargetTypeExtended(1));
assertEquals(0, WiredConditionVariableAgeMatch.normalizeCompareValue(99));
assertEquals(1, WiredConditionVariableAgeMatch.normalizeCompareValue(1));
assertEquals(0, WiredConditionVariableAgeMatch.normalizeComparison(99));
assertEquals(2, WiredConditionVariableAgeMatch.normalizeComparison(2));
assertEquals(1, WiredConditionVariableAgeMatch.normalizeDurationUnit(99));
assertEquals(7, WiredConditionVariableAgeMatch.normalizeDurationUnit(7));
}
@Test
void variableValueModesAndConstantsAreBounded() {
assertEquals(0, WiredConditionVariableValueMatch.normalizeTargetTypeExtended(900));
assertEquals(3, WiredConditionVariableValueMatch.normalizeTargetTypeExtended(3));
assertEquals(0, WiredConditionVariableValueMatch.normalizeReferenceMode(5));
assertEquals(1, WiredConditionVariableValueMatch.normalizeReferenceMode(1));
assertEquals(WiredSourceUtil.SOURCE_TRIGGER, WiredConditionVariableValueMatch.normalizeReferenceFurniSource(-1));
assertEquals(101, WiredConditionVariableValueMatch.normalizeReferenceFurniSource(101));
assertEquals(2, WiredConditionVariableValueMatch.normalizeComparison(99));
assertEquals(5, WiredConditionVariableValueMatch.normalizeComparison(5));
assertEquals(WiredConditionVariableValueMatch.MAX_ABS_REFERENCE_CONSTANT, WiredConditionVariableValueMatch.normalizeReferenceConstantValue(Integer.MAX_VALUE));
assertEquals(-WiredConditionVariableValueMatch.MAX_ABS_REFERENCE_CONSTANT, WiredConditionVariableValueMatch.normalizeReferenceConstantValue(Integer.MIN_VALUE));
assertEquals(0, WiredConditionVariableValueMatch.parseInteger("nope"));
assertEquals(123, WiredConditionVariableValueMatch.parseInteger(" 123 "));
}
}