You've already forked Arcturus-Morningstar-Extended
mirror of
https://github.com/duckietm/Arcturus-Morningstar-Extended.git
synced 2026-06-19 15:06:19 +00:00
Merge pull request #235 from simoleo89/fix/wired-inputs
fix(wired): bound save payloads
This commit is contained in:
+6
-26
@@ -2,6 +2,7 @@ package com.eu.habbo.habbohotel.items.interactions;
|
|||||||
|
|
||||||
import com.eu.habbo.Emulator;
|
import com.eu.habbo.Emulator;
|
||||||
import com.eu.habbo.habbohotel.items.Item;
|
import com.eu.habbo.habbohotel.items.Item;
|
||||||
|
import com.eu.habbo.habbohotel.items.interactions.wired.WiredInputGuard;
|
||||||
import com.eu.habbo.habbohotel.items.interactions.wired.WiredSettings;
|
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;
|
||||||
@@ -230,39 +231,18 @@ public abstract class InteractionWired extends InteractionDefault {
|
|||||||
|
|
||||||
public static WiredSettings readSettings(ClientMessage packet, boolean isEffect)
|
public static WiredSettings readSettings(ClientMessage packet, boolean isEffect)
|
||||||
{
|
{
|
||||||
int intParamCount = packet.readInt();
|
int[] intParams = WiredInputGuard.readIntParams(packet);
|
||||||
if (intParamCount < 0 || intParamCount > 100) {
|
String stringParam = WiredInputGuard.readStringParam(packet);
|
||||||
throw new IllegalArgumentException("Invalid intParamCount: " + intParamCount);
|
int[] itemIds = WiredInputGuard.readFurniIds(packet);
|
||||||
}
|
|
||||||
int[] intParams = new int[intParamCount];
|
|
||||||
|
|
||||||
for(int i = 0; i < intParamCount; i++)
|
|
||||||
{
|
|
||||||
intParams[i] = packet.readInt();
|
|
||||||
}
|
|
||||||
|
|
||||||
String stringParam = packet.readString();
|
|
||||||
|
|
||||||
int itemCount = packet.readInt();
|
|
||||||
int selectionLimit = Emulator.getConfig() != null ? Emulator.getConfig().getInt("hotel.wired.furni.selection.count", 5) : 5;
|
|
||||||
if (itemCount < 0 || itemCount > selectionLimit * 20) {
|
|
||||||
throw new IllegalArgumentException("Invalid itemCount: " + itemCount + " exceeds maximum allowed limit");
|
|
||||||
}
|
|
||||||
int[] itemIds = new int[itemCount];
|
|
||||||
|
|
||||||
for(int i = 0; i < itemCount; i++)
|
|
||||||
{
|
|
||||||
itemIds[i] = packet.readInt();
|
|
||||||
}
|
|
||||||
|
|
||||||
WiredSettings settings = new WiredSettings(intParams, stringParam, itemIds, -1);
|
WiredSettings settings = new WiredSettings(intParams, stringParam, itemIds, -1);
|
||||||
|
|
||||||
if(isEffect)
|
if(isEffect)
|
||||||
{
|
{
|
||||||
settings.setDelay(packet.readInt());
|
settings.setDelay(WiredInputGuard.normalizeDelay(packet.readInt()));
|
||||||
}
|
}
|
||||||
|
|
||||||
settings.setStuffTypeSelectionCode(packet.readInt());
|
settings.setStuffTypeSelectionCode(WiredInputGuard.normalizeStuffSelectionCode(packet.readInt()));
|
||||||
return settings;
|
return settings;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+90
@@ -0,0 +1,90 @@
|
|||||||
|
package com.eu.habbo.habbohotel.items.interactions.wired;
|
||||||
|
|
||||||
|
import com.eu.habbo.Emulator;
|
||||||
|
import com.eu.habbo.messages.ClientMessage;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
public final class WiredInputGuard {
|
||||||
|
public static final int MAX_INT_PARAMS = 100;
|
||||||
|
public static final int MAX_STRING_PARAM_LENGTH = 1024;
|
||||||
|
public static final int MAX_ABSOLUTE_FURNI_IDS = 100;
|
||||||
|
public static final int DEFAULT_MAX_DELAY = 20;
|
||||||
|
public static final int MAX_ABSOLUTE_DELAY = 3600;
|
||||||
|
public static final int MIN_STUFF_SELECTION_CODE = -1;
|
||||||
|
public static final int MAX_STUFF_SELECTION_CODE = 2;
|
||||||
|
|
||||||
|
private WiredInputGuard() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int[] readIntParams(ClientMessage packet) {
|
||||||
|
int count = packet.readInt();
|
||||||
|
if (count < 0 || count > MAX_INT_PARAMS) {
|
||||||
|
throw new IllegalArgumentException("Invalid wired int param count");
|
||||||
|
}
|
||||||
|
|
||||||
|
int[] values = new int[count];
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
values[i] = packet.readInt();
|
||||||
|
}
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String readStringParam(ClientMessage packet) {
|
||||||
|
String value = packet.readString();
|
||||||
|
if (value == null || value.isEmpty()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
return value.length() > MAX_STRING_PARAM_LENGTH
|
||||||
|
? value.substring(0, MAX_STRING_PARAM_LENGTH)
|
||||||
|
: value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int[] readFurniIds(ClientMessage packet) {
|
||||||
|
int count = packet.readInt();
|
||||||
|
int maxCount = maxFurniSelectionCount();
|
||||||
|
if (count < 0 || count > maxCount) {
|
||||||
|
throw new IllegalArgumentException("Invalid wired furni selection count");
|
||||||
|
}
|
||||||
|
|
||||||
|
int[] values = new int[count];
|
||||||
|
int accepted = 0;
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
int itemId = packet.readInt();
|
||||||
|
if (itemId > 0) {
|
||||||
|
values[accepted++] = itemId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return accepted == values.length ? values : Arrays.copyOf(values, accepted);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int normalizeDelay(int delay) {
|
||||||
|
return Math.max(0, Math.min(delay, maxDelay()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int normalizeStuffSelectionCode(int code) {
|
||||||
|
if (code < MIN_STUFF_SELECTION_CODE || code > MAX_STUFF_SELECTION_CODE) {
|
||||||
|
return MIN_STUFF_SELECTION_CODE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int maxFurniSelectionCount() {
|
||||||
|
int selectionLimit = Emulator.getConfig() != null
|
||||||
|
? Emulator.getConfig().getInt("hotel.wired.furni.selection.count", 5)
|
||||||
|
: 5;
|
||||||
|
selectionLimit = Math.max(1, selectionLimit);
|
||||||
|
return Math.min(MAX_ABSOLUTE_FURNI_IDS, selectionLimit * 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int maxDelay() {
|
||||||
|
int configured = Emulator.getConfig() != null
|
||||||
|
? Emulator.getConfig().getInt("hotel.wired.max_delay", DEFAULT_MAX_DELAY)
|
||||||
|
: DEFAULT_MAX_DELAY;
|
||||||
|
configured = Math.max(0, configured);
|
||||||
|
return Math.min(MAX_ABSOLUTE_DELAY, configured);
|
||||||
|
}
|
||||||
|
}
|
||||||
+7
-1
@@ -31,7 +31,13 @@ public class WiredConditionSaveDataEvent extends MessageHandler {
|
|||||||
|
|
||||||
if(saveMethod.isPresent()) {
|
if(saveMethod.isPresent()) {
|
||||||
if (saveMethod.get().getParameterTypes()[0] == WiredSettings.class) {
|
if (saveMethod.get().getParameterTypes()[0] == WiredSettings.class) {
|
||||||
WiredSettings settings = InteractionWired.readSettings(this.packet, false);
|
WiredSettings settings;
|
||||||
|
try {
|
||||||
|
settings = InteractionWired.readSettings(this.packet, false);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
this.client.sendResponse(new UpdateFailedComposer("Invalid wired condition settings"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (condition.saveData(settings)) {
|
if (condition.saveData(settings)) {
|
||||||
this.client.sendResponse(new WiredSavedComposer());
|
this.client.sendResponse(new WiredSavedComposer());
|
||||||
|
|||||||
+7
-1
@@ -28,7 +28,13 @@ public class WiredEffectSaveDataEvent extends MessageHandler {
|
|||||||
if (effect == null && extra == null)
|
if (effect == null && extra == null)
|
||||||
throw new WiredSaveException(String.format("Wired effect/extra with item id %s not found in room", itemId));
|
throw new WiredSaveException(String.format("Wired effect/extra with item id %s not found in room", itemId));
|
||||||
|
|
||||||
WiredSettings settings = InteractionWired.readSettings(this.packet, true);
|
WiredSettings settings;
|
||||||
|
try {
|
||||||
|
settings = InteractionWired.readSettings(this.packet, true);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
this.client.sendResponse(new UpdateFailedComposer("Invalid wired effect settings"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
boolean saved;
|
boolean saved;
|
||||||
|
|
||||||
if (effect != null) {
|
if (effect != null) {
|
||||||
|
|||||||
+7
-1
@@ -22,7 +22,13 @@ public class WiredTriggerSaveDataEvent extends MessageHandler {
|
|||||||
InteractionWiredTrigger trigger = room.getRoomSpecialTypes().getTrigger(itemId);
|
InteractionWiredTrigger trigger = room.getRoomSpecialTypes().getTrigger(itemId);
|
||||||
|
|
||||||
if (trigger != null) {
|
if (trigger != null) {
|
||||||
WiredSettings settings = InteractionWired.readSettings(this.packet, false);
|
WiredSettings settings;
|
||||||
|
try {
|
||||||
|
settings = InteractionWired.readSettings(this.packet, false);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
this.client.sendResponse(new UpdateFailedComposer("Invalid wired trigger settings"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
boolean saved = trigger.saveData(settings, this.client);
|
boolean saved = trigger.saveData(settings, this.client);
|
||||||
|
|||||||
+51
@@ -0,0 +1,51 @@
|
|||||||
|
package com.eu.habbo.habbohotel.items.interactions.wired;
|
||||||
|
|
||||||
|
import com.eu.habbo.messages.ClientMessage;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
class WiredInputGuardTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void trimsOversizedStringParams() {
|
||||||
|
String input = "x".repeat(WiredInputGuard.MAX_STRING_PARAM_LENGTH + 1);
|
||||||
|
ClientMessage message = new ClientMessage(1, stringBuffer(input));
|
||||||
|
|
||||||
|
assertEquals(WiredInputGuard.MAX_STRING_PARAM_LENGTH,
|
||||||
|
WiredInputGuard.readStringParam(message).length());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void filtersNonPositiveFurniIds() {
|
||||||
|
ByteBuf buffer = Unpooled.buffer();
|
||||||
|
buffer.writeInt(4);
|
||||||
|
buffer.writeInt(1);
|
||||||
|
buffer.writeInt(0);
|
||||||
|
buffer.writeInt(-1);
|
||||||
|
buffer.writeInt(2);
|
||||||
|
|
||||||
|
assertArrayEquals(new int[]{1, 2}, WiredInputGuard.readFurniIds(new ClientMessage(1, buffer)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void clampsDelayAndSelectionCode() {
|
||||||
|
assertEquals(0, WiredInputGuard.normalizeDelay(-10));
|
||||||
|
assertEquals(WiredInputGuard.DEFAULT_MAX_DELAY, WiredInputGuard.normalizeDelay(WiredInputGuard.DEFAULT_MAX_DELAY + 1));
|
||||||
|
assertEquals(-1, WiredInputGuard.normalizeStuffSelectionCode(99));
|
||||||
|
assertEquals(2, WiredInputGuard.normalizeStuffSelectionCode(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ByteBuf stringBuffer(String value) {
|
||||||
|
byte[] bytes = value.getBytes(StandardCharsets.UTF_8);
|
||||||
|
ByteBuf buffer = Unpooled.buffer();
|
||||||
|
buffer.writeShort(bytes.length);
|
||||||
|
buffer.writeBytes(bytes);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user