Merge pull request #246 from simoleo89/fix/wired-furni-condition-payloads

fix(wired): bound furni condition payloads
This commit is contained in:
DuckieTM
2026-06-18 12:37:51 +02:00
committed by GitHub
3 changed files with 99 additions and 20 deletions
@@ -111,19 +111,21 @@ public class WiredConditionCounterTimeMatches extends InteractionWiredCondition
@Override @Override
public void loadWiredData(ResultSet set, Room room) throws SQLException { public void loadWiredData(ResultSet set, Room room) throws SQLException {
this.items.clear(); this.resetSettings();
this.comparison = COMPARISON_EQUAL;
this.minutes = 0;
this.halfSecondSteps = 0;
this.furniSource = WiredSourceUtil.SOURCE_TRIGGER;
this.quantifier = QUANTIFIER_ALL;
String wiredData = set.getString("wired_data"); String wiredData = set.getString("wired_data");
if (wiredData == null || wiredData.isEmpty() || !wiredData.startsWith("{")) { if (wiredData == null || wiredData.isEmpty() || !wiredData.startsWith("{")) {
return; return;
} }
JsonData data = WiredManager.getGson().fromJson(wiredData, JsonData.class); JsonData data;
try {
data = WiredManager.getGson().fromJson(wiredData, JsonData.class);
} catch (RuntimeException exception) {
this.resetSettings();
return;
}
if (data == null) { if (data == null) {
return; return;
} }
@@ -131,7 +133,7 @@ public class WiredConditionCounterTimeMatches extends InteractionWiredCondition
this.comparison = this.normalizeComparison(data.comparison); this.comparison = this.normalizeComparison(data.comparison);
this.minutes = this.normalizeMinutes(data.minutes); this.minutes = this.normalizeMinutes(data.minutes);
this.halfSecondSteps = this.normalizeHalfSecondSteps(data.halfSecondSteps); this.halfSecondSteps = this.normalizeHalfSecondSteps(data.halfSecondSteps);
this.furniSource = data.furniSource; this.furniSource = this.normalizeFurniSource(data.furniSource);
this.quantifier = this.normalizeQuantifier(data.quantifier); this.quantifier = this.normalizeQuantifier(data.quantifier);
if (data.itemIds == null) { if (data.itemIds == null) {
@@ -139,6 +141,10 @@ public class WiredConditionCounterTimeMatches extends InteractionWiredCondition
} }
for (Integer id : data.itemIds) { for (Integer id : data.itemIds) {
if (id == null) {
continue;
}
HabboItem item = room.getHabboItem(id); HabboItem item = room.getHabboItem(id);
if (item instanceof InteractionGameUpCounter) { if (item instanceof InteractionGameUpCounter) {
this.items.add(item); this.items.add(item);
@@ -195,7 +201,7 @@ public class WiredConditionCounterTimeMatches extends InteractionWiredCondition
this.comparison = (params.length > 0) ? this.normalizeComparison(params[0]) : COMPARISON_EQUAL; this.comparison = (params.length > 0) ? this.normalizeComparison(params[0]) : COMPARISON_EQUAL;
this.minutes = (params.length > 1) ? this.normalizeMinutes(params[1]) : 0; this.minutes = (params.length > 1) ? this.normalizeMinutes(params[1]) : 0;
this.halfSecondSteps = (params.length > 2) ? this.normalizeHalfSecondSteps(params[2]) : 0; this.halfSecondSteps = (params.length > 2) ? this.normalizeHalfSecondSteps(params[2]) : 0;
this.furniSource = (params.length > 3) ? params[3] : WiredSourceUtil.SOURCE_TRIGGER; this.furniSource = (params.length > 3) ? this.normalizeFurniSource(params[3]) : WiredSourceUtil.SOURCE_TRIGGER;
this.quantifier = (params.length > 4) ? this.normalizeQuantifier(params[4]) : QUANTIFIER_ALL; this.quantifier = (params.length > 4) ? this.normalizeQuantifier(params[4]) : QUANTIFIER_ALL;
this.items.clear(); this.items.clear();
@@ -224,6 +230,15 @@ public class WiredConditionCounterTimeMatches extends InteractionWiredCondition
return true; return true;
} }
private void resetSettings() {
this.items.clear();
this.comparison = COMPARISON_EQUAL;
this.minutes = 0;
this.halfSecondSteps = 0;
this.furniSource = WiredSourceUtil.SOURCE_TRIGGER;
this.quantifier = QUANTIFIER_ALL;
}
private void refresh(Room room) { private void refresh(Room room) {
THashSet<HabboItem> remove = new THashSet<>(); THashSet<HabboItem> remove = new THashSet<>();
@@ -256,7 +271,7 @@ public class WiredConditionCounterTimeMatches extends InteractionWiredCondition
} }
} }
private int normalizeComparison(int value) { int normalizeComparison(int value) {
if (value < COMPARISON_LESS || value > COMPARISON_GREATER) { if (value < COMPARISON_LESS || value > COMPARISON_GREATER) {
return COMPARISON_EQUAL; return COMPARISON_EQUAL;
} }
@@ -264,18 +279,30 @@ public class WiredConditionCounterTimeMatches extends InteractionWiredCondition
return value; return value;
} }
private int normalizeMinutes(int value) { int normalizeMinutes(int value) {
return Math.max(0, Math.min(MAX_MINUTES, value)); return Math.max(0, Math.min(MAX_MINUTES, value));
} }
private int normalizeHalfSecondSteps(int value) { int normalizeHalfSecondSteps(int value) {
return Math.max(0, Math.min(MAX_HALF_SECOND_STEPS, value)); return Math.max(0, Math.min(MAX_HALF_SECOND_STEPS, value));
} }
private int normalizeQuantifier(int value) { int normalizeQuantifier(int value) {
return (value == QUANTIFIER_ANY) ? QUANTIFIER_ANY : QUANTIFIER_ALL; return (value == QUANTIFIER_ANY) ? QUANTIFIER_ANY : QUANTIFIER_ALL;
} }
int normalizeFurniSource(int value) {
switch (value) {
case WiredSourceUtil.SOURCE_SELECTED:
case WiredSourceUtil.SOURCE_SELECTOR:
case WiredSourceUtil.SOURCE_SIGNAL:
case WiredSourceUtil.SOURCE_TRIGGER:
return value;
default:
return WiredSourceUtil.SOURCE_TRIGGER;
}
}
static class JsonData { static class JsonData {
int comparison; int comparison;
int minutes; int minutes;
@@ -97,7 +97,14 @@ public class WiredConditionHasAltitude extends InteractionWiredCondition {
return; 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) { if (data == null) {
return; return;
} }
@@ -112,6 +119,10 @@ public class WiredConditionHasAltitude extends InteractionWiredCondition {
} }
for (Integer id : data.itemIds) { for (Integer id : data.itemIds) {
if (id == null) {
continue;
}
HabboItem item = room.getHabboItem(id); HabboItem item = room.getHabboItem(id);
if (item != null) { if (item != null) {
this.items.add(item); this.items.add(item);
@@ -225,7 +236,7 @@ public class WiredConditionHasAltitude extends InteractionWiredCondition {
} }
} }
private int normalizeComparison(int value) { int normalizeComparison(int value) {
if (value < COMPARISON_LESS || value > COMPARISON_GREATER) { if (value < COMPARISON_LESS || value > COMPARISON_GREATER) {
return COMPARISON_EQUAL; return COMPARISON_EQUAL;
} }
@@ -233,11 +244,11 @@ public class WiredConditionHasAltitude extends InteractionWiredCondition {
return value; return value;
} }
private int normalizeQuantifier(int value) { int normalizeQuantifier(int value) {
return (value == QUANTIFIER_ANY) ? QUANTIFIER_ANY : QUANTIFIER_ALL; return (value == QUANTIFIER_ANY) ? QUANTIFIER_ANY : QUANTIFIER_ALL;
} }
private int normalizeFurniSource(int value) { int normalizeFurniSource(int value) {
switch (value) { switch (value) {
case WiredSourceUtil.SOURCE_SELECTED: case WiredSourceUtil.SOURCE_SELECTED:
case WiredSourceUtil.SOURCE_SELECTOR: case WiredSourceUtil.SOURCE_SELECTOR:
@@ -249,12 +260,12 @@ public class WiredConditionHasAltitude extends InteractionWiredCondition {
} }
} }
private double normalizeAltitude(double value) { double normalizeAltitude(double value) {
double clampedValue = Math.max(0.0D, Math.min(Room.MAXIMUM_FURNI_HEIGHT, value)); double clampedValue = Math.max(0.0D, Math.min(Room.MAXIMUM_FURNI_HEIGHT, value));
return BigDecimal.valueOf(clampedValue).setScale(2, RoundingMode.HALF_UP).doubleValue(); return BigDecimal.valueOf(clampedValue).setScale(2, RoundingMode.HALF_UP).doubleValue();
} }
private double parseAltitudeOrDefault(String value) { double parseAltitudeOrDefault(String value) {
if (value == null || value.trim().isEmpty()) { if (value == null || value.trim().isEmpty()) {
return 0.0D; return 0.0D;
} }
@@ -266,7 +277,7 @@ public class WiredConditionHasAltitude extends InteractionWiredCondition {
} }
} }
private String formatAltitude(double value) { String formatAltitude(double value) {
BigDecimal decimal = BigDecimal.valueOf(this.normalizeAltitude(value)).stripTrailingZeros(); BigDecimal decimal = BigDecimal.valueOf(this.normalizeAltitude(value)).stripTrailingZeros();
return (decimal.scale() < 0 ? decimal.setScale(0, RoundingMode.DOWN) : decimal).toPlainString(); return (decimal.scale() < 0 ? decimal.setScale(0, RoundingMode.DOWN) : decimal).toPlainString();
} }
@@ -0,0 +1,41 @@
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 WiredConditionFurniPayloadGuardTest {
@Test
void counterTimeNormalizesTimeComparisonQuantifierAndSources() {
WiredConditionCounterTimeMatches condition = new WiredConditionCounterTimeMatches(1, 1, null, "", 0, 0);
assertEquals(1, condition.normalizeComparison(1));
assertEquals(1, condition.normalizeComparison(-1));
assertEquals(1, condition.normalizeComparison(99));
assertEquals(0, condition.normalizeMinutes(-10));
assertEquals(99, condition.normalizeMinutes(250));
assertEquals(0, condition.normalizeHalfSecondSteps(-1));
assertEquals(119, condition.normalizeHalfSecondSteps(500));
assertEquals(1, condition.normalizeQuantifier(1));
assertEquals(0, condition.normalizeQuantifier(7));
assertEquals(WiredSourceUtil.SOURCE_SELECTED, condition.normalizeFurniSource(WiredSourceUtil.SOURCE_SELECTED));
assertEquals(WiredSourceUtil.SOURCE_TRIGGER, condition.normalizeFurniSource(42_424));
}
@Test
void altitudeNormalizesPayloadInputs() {
WiredConditionHasAltitude condition = new WiredConditionHasAltitude(1, 1, null, "", 0, 0);
assertEquals(1, condition.normalizeComparison(1));
assertEquals(1, condition.normalizeComparison(-5));
assertEquals(1, condition.normalizeComparison(9));
assertEquals(1, condition.normalizeQuantifier(1));
assertEquals(0, condition.normalizeQuantifier(8));
assertEquals(WiredSourceUtil.SOURCE_SIGNAL, condition.normalizeFurniSource(WiredSourceUtil.SOURCE_SIGNAL));
assertEquals(WiredSourceUtil.SOURCE_TRIGGER, condition.normalizeFurniSource(-900));
assertEquals(0.0D, condition.parseAltitudeOrDefault("nope"));
assertEquals(12.35D, condition.parseAltitudeOrDefault("12.345"));
assertEquals("12.35", condition.formatAltitude(12.345D));
}
}