Merge pull request #248 from simoleo89/fix/wired-count-time-payloads

fix(wired): bound count time payloads
This commit is contained in:
DuckieTM
2026-06-18 12:40:15 +02:00
committed by GitHub
5 changed files with 83 additions and 3 deletions
@@ -16,6 +16,7 @@ import java.sql.SQLException;
public class WiredConditionHabboCount extends InteractionWiredCondition { public class WiredConditionHabboCount extends InteractionWiredCondition {
public static final WiredConditionType type = WiredConditionType.USER_COUNT; public static final WiredConditionType type = WiredConditionType.USER_COUNT;
static final int MAX_USER_COUNT_LIMIT = 1000;
private int lowerLimit = 0; private int lowerLimit = 0;
private int upperLimit = 50; private int upperLimit = 50;
@@ -31,6 +32,10 @@ public class WiredConditionHabboCount extends InteractionWiredCondition {
@Override @Override
public boolean evaluate(WiredContext ctx) { public boolean evaluate(WiredContext ctx) {
if (ctx == null || ctx.room() == null) {
return false;
}
int count = (this.userSource == WiredSourceUtil.SOURCE_TRIGGER) int count = (this.userSource == WiredSourceUtil.SOURCE_TRIGGER)
? ctx.room().getUserCount() ? ctx.room().getUserCount()
: WiredSourceUtil.resolveUsers(ctx, this.userSource).size(); : WiredSourceUtil.resolveUsers(ctx, this.userSource).size();
@@ -55,7 +60,12 @@ public class WiredConditionHabboCount extends InteractionWiredCondition {
@Override @Override
public void loadWiredData(ResultSet set, Room room) throws SQLException { public void loadWiredData(ResultSet set, Room room) throws SQLException {
this.onPickUp();
String wiredData = set.getString("wired_data"); String wiredData = set.getString("wired_data");
if (wiredData == null || wiredData.isEmpty()) {
return;
}
if (wiredData.startsWith("{")) { if (wiredData.startsWith("{")) {
JsonData data = WiredManager.getGson().fromJson(wiredData, JsonData.class); JsonData data = WiredManager.getGson().fromJson(wiredData, JsonData.class);
@@ -71,8 +81,8 @@ public class WiredConditionHabboCount extends InteractionWiredCondition {
// malformed legacy data — keep the constructed defaults // malformed legacy data — keep the constructed defaults
} }
} }
this.userSource = WiredSourceUtil.SOURCE_TRIGGER;
} }
this.userSource = WiredSourceUtil.SOURCE_TRIGGER;
} }
@Override @Override
@@ -58,6 +58,7 @@ public class WiredConditionLessTimeElapsed extends InteractionWiredCondition {
this.cycles = WiredConditionInputGuard.normalizeTimerCycles(Integer.parseInt(wiredData)); this.cycles = WiredConditionInputGuard.normalizeTimerCycles(Integer.parseInt(wiredData));
} }
} catch (Exception e) { } catch (Exception e) {
this.cycles = 0;
} }
} }
@@ -94,6 +95,10 @@ public class WiredConditionLessTimeElapsed extends InteractionWiredCondition {
return true; return true;
} }
int normalizeCycles(int value) {
return Math.max(0, Math.min(WiredConditionMoreTimeElapsed.MAX_CYCLES, value));
}
static class JsonData { static class JsonData {
int cycles; int cycles;
@@ -16,6 +16,7 @@ import java.sql.SQLException;
public class WiredConditionMoreTimeElapsed extends InteractionWiredCondition { public class WiredConditionMoreTimeElapsed extends InteractionWiredCondition {
private static final WiredConditionType type = WiredConditionType.TIME_MORE_THAN; private static final WiredConditionType type = WiredConditionType.TIME_MORE_THAN;
static final int MAX_CYCLES = 1_000_000;
private int cycles; private int cycles;
@@ -58,6 +59,7 @@ public class WiredConditionMoreTimeElapsed extends InteractionWiredCondition {
this.cycles = WiredConditionInputGuard.normalizeTimerCycles(Integer.parseInt(wiredData)); this.cycles = WiredConditionInputGuard.normalizeTimerCycles(Integer.parseInt(wiredData));
} }
} catch (Exception e) { } catch (Exception e) {
this.cycles = 0;
} }
} }
@@ -94,6 +96,10 @@ public class WiredConditionMoreTimeElapsed extends InteractionWiredCondition {
return true; return true;
} }
int normalizeCycles(int value) {
return Math.max(0, Math.min(MAX_CYCLES, value));
}
static class JsonData { static class JsonData {
int cycles; int cycles;
@@ -6,8 +6,8 @@ import com.eu.habbo.habbohotel.items.interactions.wired.WiredSettings;
import com.eu.habbo.habbohotel.rooms.Room; import com.eu.habbo.habbohotel.rooms.Room;
import com.eu.habbo.habbohotel.rooms.RoomUnit; import com.eu.habbo.habbohotel.rooms.RoomUnit;
import com.eu.habbo.habbohotel.wired.WiredConditionType; import com.eu.habbo.habbohotel.wired.WiredConditionType;
import com.eu.habbo.habbohotel.wired.core.WiredManager;
import com.eu.habbo.habbohotel.wired.core.WiredContext; import com.eu.habbo.habbohotel.wired.core.WiredContext;
import com.eu.habbo.habbohotel.wired.core.WiredManager;
import com.eu.habbo.habbohotel.wired.core.WiredSourceUtil; import com.eu.habbo.habbohotel.wired.core.WiredSourceUtil;
import com.eu.habbo.messages.ServerMessage; import com.eu.habbo.messages.ServerMessage;
@@ -31,6 +31,10 @@ public class WiredConditionNotHabboCount extends InteractionWiredCondition {
@Override @Override
public boolean evaluate(WiredContext ctx) { public boolean evaluate(WiredContext ctx) {
if (ctx == null || ctx.room() == null) {
return false;
}
int count = (this.userSource == WiredSourceUtil.SOURCE_TRIGGER) int count = (this.userSource == WiredSourceUtil.SOURCE_TRIGGER)
? ctx.room().getUserCount() ? ctx.room().getUserCount()
: WiredSourceUtil.resolveUsers(ctx, this.userSource).size(); : WiredSourceUtil.resolveUsers(ctx, this.userSource).size();
@@ -55,7 +59,12 @@ public class WiredConditionNotHabboCount extends InteractionWiredCondition {
@Override @Override
public void loadWiredData(ResultSet set, Room room) throws SQLException { public void loadWiredData(ResultSet set, Room room) throws SQLException {
this.onPickUp();
String wiredData = set.getString("wired_data"); String wiredData = set.getString("wired_data");
if (wiredData == null || wiredData.isEmpty()) {
return;
}
if (wiredData.startsWith("{")) { if (wiredData.startsWith("{")) {
WiredConditionHabboCount.JsonData data = WiredManager.getGson().fromJson(wiredData, WiredConditionHabboCount.JsonData.class); WiredConditionHabboCount.JsonData data = WiredManager.getGson().fromJson(wiredData, WiredConditionHabboCount.JsonData.class);
@@ -70,8 +79,8 @@ public class WiredConditionNotHabboCount extends InteractionWiredCondition {
// malformed legacy data — keep the constructed defaults // malformed legacy data — keep the constructed defaults
} }
} }
this.userSource = WiredSourceUtil.SOURCE_TRIGGER;
} }
this.userSource = WiredSourceUtil.SOURCE_TRIGGER;
} }
@Override @Override
@@ -0,0 +1,50 @@
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 WiredConditionCountTimePayloadGuardTest {
@Test
void userCountLimitsAndSourcesAreBounded() {
WiredConditionHabboCount condition = new WiredConditionHabboCount(1, 1, null, "", 0, 0);
assertEquals(0, condition.normalizeLimit(-20));
assertEquals(25, condition.normalizeLimit(25));
assertEquals(WiredConditionHabboCount.MAX_USER_COUNT_LIMIT, condition.normalizeLimit(50_000));
assertEquals(WiredSourceUtil.SOURCE_SIGNAL, condition.normalizeUserSource(WiredSourceUtil.SOURCE_SIGNAL));
assertEquals(WiredSourceUtil.SOURCE_TRIGGER, condition.normalizeUserSource(-55));
}
@Test
void invertedUserCountRangesAreSorted() {
WiredConditionHabboCount condition = new WiredConditionHabboCount(1, 1, null, "", 0, 0);
condition.setLimits(80, 10);
assertEquals("{\"lowerLimit\":10,\"upperLimit\":80,\"userSource\":0}", condition.getWiredData());
}
@Test
void notUserCountUsesSameBounds() {
WiredConditionNotHabboCount condition = new WiredConditionNotHabboCount(1, 1, null, "", 0, 0);
assertEquals(0, condition.normalizeLimit(-1));
assertEquals(WiredConditionHabboCount.MAX_USER_COUNT_LIMIT, condition.normalizeLimit(9_999));
assertEquals(WiredSourceUtil.SOURCE_CLICKED_USER, condition.normalizeUserSource(WiredSourceUtil.SOURCE_CLICKED_USER));
assertEquals(WiredSourceUtil.SOURCE_TRIGGER, condition.normalizeUserSource(777));
}
@Test
void elapsedTimeCyclesAreBounded() {
WiredConditionMoreTimeElapsed more = new WiredConditionMoreTimeElapsed(1, 1, null, "", 0, 0);
WiredConditionLessTimeElapsed less = new WiredConditionLessTimeElapsed(1, 1, null, "", 0, 0);
assertEquals(0, more.normalizeCycles(-1));
assertEquals(42, more.normalizeCycles(42));
assertEquals(WiredConditionMoreTimeElapsed.MAX_CYCLES, more.normalizeCycles(Integer.MAX_VALUE));
assertEquals(0, less.normalizeCycles(-1));
assertEquals(WiredConditionMoreTimeElapsed.MAX_CYCLES, less.normalizeCycles(Integer.MAX_VALUE));
}
}