diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionDateRangeActive.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionDateRangeActive.java index 0b92d4e6..4ae14f56 100644 --- a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionDateRangeActive.java +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionDateRangeActive.java @@ -53,8 +53,7 @@ public class WiredConditionDateRangeActive extends InteractionWiredCondition { @Override public boolean saveData(WiredSettings settings) { if(settings.getIntParams().length < 2) return false; - this.startDate = settings.getIntParams()[0]; - this.endDate = settings.getIntParams()[1]; + this.setRange(settings.getIntParams()[0], settings.getIntParams()[1]); return true; } @@ -80,20 +79,34 @@ public class WiredConditionDateRangeActive extends InteractionWiredCondition { @Override public void loadWiredData(ResultSet set, Room room) throws SQLException { + this.onPickUp(); String wiredData = set.getString("wired_data"); + if (wiredData == null || wiredData.isEmpty()) { + return; + } if (wiredData.startsWith("{")) { - JsonData data = WiredManager.getGson().fromJson(wiredData, JsonData.class); - this.startDate = data.startDate; - this.endDate = data.endDate; + JsonData data; + try { + data = WiredManager.getGson().fromJson(wiredData, JsonData.class); + } catch (RuntimeException exception) { + this.onPickUp(); + return; + } + + if (data == null) { + return; + } + + this.setRange(data.startDate, data.endDate); } else { String[] data = wiredData.split("\t"); if (data.length == 2) { try { - this.startDate = Integer.parseInt(data[0]); - this.endDate = Integer.parseInt(data[1]); + this.setRange(Integer.parseInt(data[0]), Integer.parseInt(data[1])); } catch (Exception e) { + this.onPickUp(); } } } @@ -105,6 +118,24 @@ public class WiredConditionDateRangeActive extends InteractionWiredCondition { this.endDate = 0; } + void setRange(int startDate, int endDate) { + int normalizedStart = this.normalizeTimestamp(startDate); + int normalizedEnd = this.normalizeTimestamp(endDate); + + if (normalizedStart > normalizedEnd) { + this.startDate = normalizedEnd; + this.endDate = normalizedStart; + return; + } + + this.startDate = normalizedStart; + this.endDate = normalizedEnd; + } + + int normalizeTimestamp(int value) { + return Math.max(0, value); + } + static class JsonData { int startDate; int endDate; diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionMatchDate.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionMatchDate.java index 3574480b..c214f266 100644 --- a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionMatchDate.java +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionMatchDate.java @@ -125,7 +125,14 @@ public class WiredConditionMatchDate extends InteractionWiredCondition { } if (wiredData.startsWith("{")) { - JsonData data = WiredManager.getGson().fromJson(wiredData, JsonData.class); + JsonData data; + try { + data = WiredManager.getGson().fromJson(wiredData, JsonData.class); + } catch (RuntimeException exception) { + this.reset(); + return; + } + if (data == null) { return; } @@ -193,7 +200,7 @@ public class WiredConditionMatchDate extends InteractionWiredCondition { } } - private int normalizeMode(int value) { + int normalizeMode(int value) { if (value < MODE_SKIP || value > MODE_RANGE) { return MODE_SKIP; } @@ -201,20 +208,20 @@ public class WiredConditionMatchDate extends InteractionWiredCondition { return value; } - private int normalizeDay(int value) { + int normalizeDay(int value) { return Math.max(1, Math.min(31, value)); } - private int normalizeYear(int value) { + int normalizeYear(int value) { return Math.max(1, Math.min(9999, value)); } - private int normalizeWeekdayMask(int value) { + int normalizeWeekdayMask(int value) { int normalized = value & ALL_WEEKDAYS_MASK; return (normalized == 0) ? ALL_WEEKDAYS_MASK : normalized; } - private int normalizeMonthMask(int value) { + int normalizeMonthMask(int value) { int normalized = value & ALL_MONTHS_MASK; return (normalized == 0) ? ALL_MONTHS_MASK : normalized; } diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionMatchTime.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionMatchTime.java index 982b56ec..69211d1a 100644 --- a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionMatchTime.java +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionMatchTime.java @@ -126,7 +126,14 @@ public class WiredConditionMatchTime extends InteractionWiredCondition { } if (wiredData.startsWith("{")) { - JsonData data = WiredManager.getGson().fromJson(wiredData, JsonData.class); + JsonData data; + try { + data = WiredManager.getGson().fromJson(wiredData, JsonData.class); + } catch (RuntimeException exception) { + this.reset(); + return; + } + if (data == null) { return; } @@ -195,7 +202,7 @@ public class WiredConditionMatchTime extends InteractionWiredCondition { } } - private int normalizeMode(int value) { + int normalizeMode(int value) { if (value < MODE_SKIP || value > MODE_RANGE) { return MODE_SKIP; } @@ -203,11 +210,11 @@ public class WiredConditionMatchTime extends InteractionWiredCondition { return value; } - private int normalizeHour(int value) { + int normalizeHour(int value) { return Math.max(0, Math.min(23, value)); } - private int normalizeMinuteOrSecond(int value) { + int normalizeMinuteOrSecond(int value) { return Math.max(0, Math.min(59, value)); } diff --git a/Emulator/src/main/java/com/eu/habbo/util/HotelDateTimeUtil.java b/Emulator/src/main/java/com/eu/habbo/util/HotelDateTimeUtil.java index 0abb37f3..3b5fbce0 100644 --- a/Emulator/src/main/java/com/eu/habbo/util/HotelDateTimeUtil.java +++ b/Emulator/src/main/java/com/eu/habbo/util/HotelDateTimeUtil.java @@ -23,7 +23,9 @@ public final class HotelDateTimeUtil { } public static ZoneId getZoneId() { - String configuredZoneId = Emulator.getConfig().getValue(CONFIG_KEY, ZoneId.systemDefault().getId()); + String configuredZoneId = Emulator.getConfig() != null + ? Emulator.getConfig().getValue(CONFIG_KEY, ZoneId.systemDefault().getId()) + : ZoneId.systemDefault().getId(); try { lastInvalidTimezoneId = null; diff --git a/Emulator/src/test/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionDatePayloadGuardTest.java b/Emulator/src/test/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionDatePayloadGuardTest.java new file mode 100644 index 00000000..41e3317a --- /dev/null +++ b/Emulator/src/test/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionDatePayloadGuardTest.java @@ -0,0 +1,45 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.conditions; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class WiredConditionDatePayloadGuardTest { + @Test + void matchDateBoundsMasksAndParts() { + WiredConditionMatchDate condition = new WiredConditionMatchDate(1, 1, null, "", 0, 0); + + assertEquals(0, condition.normalizeMode(99)); + assertEquals(2, condition.normalizeMode(2)); + assertEquals(1, condition.normalizeDay(-1)); + assertEquals(31, condition.normalizeDay(99)); + assertEquals(1, condition.normalizeYear(-1)); + assertEquals(9999, condition.normalizeYear(50_000)); + assertEquals(254, condition.normalizeWeekdayMask(0)); + assertEquals(8190, condition.normalizeMonthMask(0)); + } + + @Test + void matchTimeBoundsParts() { + WiredConditionMatchTime condition = new WiredConditionMatchTime(1, 1, null, "", 0, 0); + + assertEquals(0, condition.normalizeMode(99)); + assertEquals(2, condition.normalizeMode(2)); + assertEquals(0, condition.normalizeHour(-1)); + assertEquals(23, condition.normalizeHour(99)); + assertEquals(0, condition.normalizeMinuteOrSecond(-1)); + assertEquals(59, condition.normalizeMinuteOrSecond(99)); + } + + @Test + void dateRangeBoundsAndSortsUnixTimestamps() { + WiredConditionDateRangeActive condition = new WiredConditionDateRangeActive(1, 1, null, "", 0, 0); + + assertEquals(0, condition.normalizeTimestamp(-1)); + assertEquals(123, condition.normalizeTimestamp(123)); + + condition.setRange(200, 100); + + assertEquals("{\"startDate\":100,\"endDate\":200}", condition.getWiredData()); + } +}