From 44d38b8661351b43d4b0bfb6f6def1be32cc1a8d Mon Sep 17 00:00:00 2001 From: DuckieTM Date: Tue, 26 May 2026 22:18:02 +0200 Subject: [PATCH 1/2] =?UTF-8?q?=F0=9F=86=99=20SQL=20update?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Database Updates/006_Allow_Housekeeping_in_Client.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Database Updates/006_Allow_Housekeeping_in_Client.sql b/Database Updates/006_Allow_Housekeeping_in_Client.sql index 8d401928..42359fe0 100644 --- a/Database Updates/006_Allow_Housekeeping_in_Client.sql +++ b/Database Updates/006_Allow_Housekeeping_in_Client.sql @@ -1 +1 @@ -INSERT INTO `camwijsnew`.`permission_definitions` (`permission_key`, `max_value`, `comment`, `rank_1`, `rank_2`, `rank_3`, `rank_4`, `rank_5`, `rank_6`, `rank_7`) VALUES ('acc_housekeeping', '1', 'Allow housekeeping in the client', '0', '0', '0', '0', '0', '0', '1'); +INSERT INTO `permission_definitions` (`permission_key`, `max_value`, `comment`, `rank_1`, `rank_2`, `rank_3`, `rank_4`, `rank_5`, `rank_6`, `rank_7`) VALUES ('acc_housekeeping', '1', 'Allow housekeeping in the client', '0', '0', '0', '0', '0', '0', '1'); From e213609609e69201efbd408cb990be4bf3d0e421 Mon Sep 17 00:00:00 2001 From: duckietm Date: Wed, 27 May 2026 09:37:49 +0200 Subject: [PATCH 2/2] =?UTF-8?q?=F0=9F=86=95=20Added=20Pickup=20furni=20to?= =?UTF-8?q?=20the=20floorplan?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FloorPlanEditorSaveEvent.java | 66 +++++++++++++++++-- 1 file changed, 60 insertions(+), 6 deletions(-) diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/floorplaneditor/FloorPlanEditorSaveEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/floorplaneditor/FloorPlanEditorSaveEvent.java index 17a5c9d7..bd2bd76a 100644 --- a/Emulator/src/main/java/com/eu/habbo/messages/incoming/floorplaneditor/FloorPlanEditorSaveEvent.java +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/floorplaneditor/FloorPlanEditorSaveEvent.java @@ -4,19 +4,20 @@ import com.eu.habbo.Emulator; import com.eu.habbo.habbohotel.permissions.Permission; import com.eu.habbo.habbohotel.rooms.*; import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; import com.eu.habbo.messages.ServerMessage; import com.eu.habbo.messages.incoming.MessageHandler; import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertComposer; import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertKeys; import com.eu.habbo.messages.outgoing.generic.alerts.GenericAlertComposer; +import com.eu.habbo.messages.outgoing.inventory.AddHabboItemComposer; +import com.eu.habbo.messages.outgoing.inventory.InventoryRefreshComposer; import com.eu.habbo.messages.outgoing.rooms.ForwardToRoomComposer; import gnu.trove.set.hash.THashSet; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.ArrayList; -import java.util.Collection; -import java.util.StringJoiner; +import java.util.*; import java.util.regex.Pattern; public class FloorPlanEditorSaveEvent extends MessageHandler { @@ -26,6 +27,7 @@ public class FloorPlanEditorSaveEvent extends MessageHandler { public static int MAXIMUM_FLOORPLAN_SIZE = 64 * 64; private static final int SAVE_COOLDOWN_SECONDS = 3; + private static final int MAX_AUTO_PICKUP_ITEMS = 500; private static final Pattern ALLOWED_MAP_CHARS = Pattern.compile("[a-zA-Z0-9\r]+"); @Override @@ -127,6 +129,11 @@ public class FloorPlanEditorSaveEvent extends MessageHandler { errors.add("${notification.floorplan_editor.error.message.invalid_walls_fixed_height}"); } + boolean autoPickup = false; + if (this.packet.bytesAvailable() >= 1) { + autoPickup = this.packet.readBoolean(); + } + if (errors.length() > 0) { this.client.sendResponse(new BubbleAlertComposer(BubbleAlertKeys.FLOORPLAN_EDITOR_ERROR.key, errors.toString())); return; @@ -134,6 +141,7 @@ public class FloorPlanEditorSaveEvent extends MessageHandler { THashSet locked_tileList = room.getLockedTiles(); THashSet new_tileList = new THashSet<>(); + THashSet itemsToPickup = new THashSet<>(); int blockedX = -1; int blockedY = -1; blockingRoomItemScan: @@ -146,6 +154,11 @@ public class FloorPlanEditorSaveEvent extends MessageHandler { short height; if (square.equalsIgnoreCase("x") && room.getTopItemAt(x, y) != null) { + if (autoPickup) { + THashSet here = room.getItemsAt(x, y); + if (here != null) itemsToPickup.addAll(here); + continue; + } blockedX = x; blockedY = y; break blockingRoomItemScan; @@ -168,6 +181,11 @@ public class FloorPlanEditorSaveEvent extends MessageHandler { } if (tile != null && tile.state != RoomTileState.INVALID && height != tile.z && room.getTopItemAt(x, y) != null) { + if (autoPickup) { + THashSet here = room.getItemsAt(x, y); + if (here != null) itemsToPickup.addAll(here); + continue; + } blockedX = x; blockedY = y; break blockingRoomItemScan; @@ -178,9 +196,16 @@ public class FloorPlanEditorSaveEvent extends MessageHandler { if (blockedX < 0) { locked_tileList.removeAll(new_tileList); if (!locked_tileList.isEmpty()) { - RoomTile first = locked_tileList.iterator().next(); - blockedX = first.x; - blockedY = first.y; + if (autoPickup) { + for (RoomTile lt : locked_tileList) { + THashSet here = room.getItemsAt(lt.x, lt.y); + if (here != null) itemsToPickup.addAll(here); + } + } else { + RoomTile first = locked_tileList.iterator().next(); + blockedX = first.x; + blockedY = first.y; + } } } @@ -190,6 +215,35 @@ public class FloorPlanEditorSaveEvent extends MessageHandler { return; } + if (autoPickup && !itemsToPickup.isEmpty()) { + if (itemsToPickup.size() > MAX_AUTO_PICKUP_ITEMS) { + LOGGER.warn("Floorplan auto-pickup rejected (over cap): user={} room={} itemCount={} cap={}", + this.client.getHabbo().getHabboInfo().getId(), room.getId(), itemsToPickup.size(), MAX_AUTO_PICKUP_ITEMS); + this.client.sendResponse(new BubbleAlertComposer(BubbleAlertKeys.FLOORPLAN_EDITOR_ERROR.key, + "Too many items would be picked up (" + itemsToPickup.size() + " > " + MAX_AUTO_PICKUP_ITEMS + "). Remove some furniture manually and save again.")); + return; + } + + Map> byOwner = new HashMap<>(); + for (HabboItem itm : itemsToPickup) { + if (itm == null) continue; + byOwner.computeIfAbsent(itm.getUserId(), k -> new ArrayList<>()).add(itm); + room.pickUpItem(itm, null); + } + + for (Map.Entry> entry : byOwner.entrySet()) { + Habbo owner = Emulator.getGameEnvironment().getHabboManager().getHabbo(entry.getKey()); + if (owner == null) continue; + for (HabboItem itm : entry.getValue()) { + owner.getClient().sendResponse(new AddHabboItemComposer(itm)); + } + owner.getClient().sendResponse(new InventoryRefreshComposer()); + } + + LOGGER.info("Floorplan auto-pickup: user={} room={} itemCount={} owners={}", + this.client.getHabbo().getHabboInfo().getId(), room.getId(), itemsToPickup.size(), byOwner.size()); + } + RoomLayout layout = room.getLayout(); if (layout instanceof CustomRoomLayout) {