From a2c958684c2de6e4310cf0ea4998516319cc14ce Mon Sep 17 00:00:00 2001 From: simoleo89 Date: Wed, 17 Jun 2026 19:09:52 +0200 Subject: [PATCH] fix(wired): bound furni condition payloads --- .../WiredConditionCounterTimeMatches.java | 53 ++++++++++++++----- .../conditions/WiredConditionHasAltitude.java | 25 ++++++--- .../WiredConditionFurniPayloadGuardTest.java | 41 ++++++++++++++ 3 files changed, 99 insertions(+), 20 deletions(-) create mode 100644 Emulator/src/test/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionFurniPayloadGuardTest.java diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionCounterTimeMatches.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionCounterTimeMatches.java index a28ea00b..769fbae7 100644 --- a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionCounterTimeMatches.java +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionCounterTimeMatches.java @@ -111,19 +111,21 @@ public class WiredConditionCounterTimeMatches extends InteractionWiredCondition @Override public void loadWiredData(ResultSet set, Room room) throws SQLException { - this.items.clear(); - this.comparison = COMPARISON_EQUAL; - this.minutes = 0; - this.halfSecondSteps = 0; - this.furniSource = WiredSourceUtil.SOURCE_TRIGGER; - this.quantifier = QUANTIFIER_ALL; + this.resetSettings(); 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.resetSettings(); + return; + } + if (data == null) { return; } @@ -131,7 +133,7 @@ public class WiredConditionCounterTimeMatches extends InteractionWiredCondition this.comparison = this.normalizeComparison(data.comparison); this.minutes = this.normalizeMinutes(data.minutes); this.halfSecondSteps = this.normalizeHalfSecondSteps(data.halfSecondSteps); - this.furniSource = data.furniSource; + this.furniSource = this.normalizeFurniSource(data.furniSource); this.quantifier = this.normalizeQuantifier(data.quantifier); if (data.itemIds == null) { @@ -139,6 +141,10 @@ public class WiredConditionCounterTimeMatches extends InteractionWiredCondition } for (Integer id : data.itemIds) { + if (id == null) { + continue; + } + HabboItem item = room.getHabboItem(id); if (item instanceof InteractionGameUpCounter) { 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.minutes = (params.length > 1) ? this.normalizeMinutes(params[1]) : 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.items.clear(); @@ -224,6 +230,15 @@ public class WiredConditionCounterTimeMatches extends InteractionWiredCondition 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) { THashSet 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) { return COMPARISON_EQUAL; } @@ -264,18 +279,30 @@ public class WiredConditionCounterTimeMatches extends InteractionWiredCondition return value; } - private int normalizeMinutes(int value) { + int normalizeMinutes(int 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)); } - private int normalizeQuantifier(int value) { + int normalizeQuantifier(int value) { 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 { int comparison; int minutes; diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionHasAltitude.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionHasAltitude.java index 43a71b8f..0a5f4a64 100644 --- a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionHasAltitude.java +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionHasAltitude.java @@ -97,7 +97,14 @@ public class WiredConditionHasAltitude extends InteractionWiredCondition { 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; } @@ -112,6 +119,10 @@ public class WiredConditionHasAltitude extends InteractionWiredCondition { } for (Integer id : data.itemIds) { + if (id == null) { + continue; + } + HabboItem item = room.getHabboItem(id); if (item != null) { 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) { return COMPARISON_EQUAL; } @@ -233,11 +244,11 @@ public class WiredConditionHasAltitude extends InteractionWiredCondition { return value; } - private int normalizeQuantifier(int value) { + int normalizeQuantifier(int value) { return (value == QUANTIFIER_ANY) ? QUANTIFIER_ANY : QUANTIFIER_ALL; } - private int normalizeFurniSource(int value) { + int normalizeFurniSource(int value) { switch (value) { case WiredSourceUtil.SOURCE_SELECTED: 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)); 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()) { 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(); return (decimal.scale() < 0 ? decimal.setScale(0, RoundingMode.DOWN) : decimal).toPlainString(); } diff --git a/Emulator/src/test/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionFurniPayloadGuardTest.java b/Emulator/src/test/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionFurniPayloadGuardTest.java new file mode 100644 index 00000000..52bd2714 --- /dev/null +++ b/Emulator/src/test/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionFurniPayloadGuardTest.java @@ -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)); + } +}