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
feat(housekeeping): rooms domain — find/search + open/close/mute/kick-all/transfer/delete
Eight new incoming handlers + two new outgoing composers cover the full rooms-domain HK panel. * Outgoing 9202 HousekeepingRoomDetailComposer — single room with a leading `found` boolean. Writes the IHousekeepingRoom shape via a static `appendRoomFields` that HousekeepingRoomListComposer shares. * Outgoing 9203 HousekeepingRoomListComposer — `count` then N rooms. Used for both find-by-name (exact match, up to 50) and the prefix autocomplete dropdown (up to 8). * Incoming 9110 HousekeepingFindRoomByIdEvent — loadRoom(id, false) covers both the in-memory cache and the offline `SELECT * FROM rooms` path. No `loadData` so HK doesn't pull furni/bots/pets just to render a summary. * Incoming 9111 HousekeepingSearchRoomsEvent — (query, exactMatch, limit). Branches between `name = ?` and `name LIKE ?` so the same wire packet serves both the autocomplete and the exact-find flows. Hard-capped to 50. * Incoming 9112 HousekeepingRoomStateEvent — (roomId, open). Toggles Room.setState(OPEN | LOCKED) and persists via Room.save(). One packet covers both the open and close API endpoints. * Incoming 9113 HousekeepingMuteRoomEvent — (roomId, minutes). Room. setMuted is a boolean, so minutes==0 unmutes and minutes>0 mutes. A scheduled auto-unmute is left for a future slice; the wire field is reserved. * Incoming 9114 HousekeepingKickAllFromRoomEvent — Room.ejectAll(). * Incoming 9115 HousekeepingTransferRoomOwnershipEvent — UPDATEs both rooms.owner_id and rooms.owner_name so the navigator cached name doesn't go stale. Validates the new owner exists via HabboManager.getHabboInfo before touching the row. * Incoming 9116 HousekeepingDeleteRoomEvent — ejectAll + dispose + uncacheRoom + DELETE FROM rooms, mirroring the minimum-viable subset of RequestDeleteRoomEvent. Pets/guild/custom-layout cleanup is skipped on this slice (orphans don't crash the emulator). `mvn compile` clean.
This commit is contained in:
@@ -728,5 +728,12 @@ public class PacketManager {
|
||||
this.registerHandler(Incoming.HousekeepingSetUserRankEvent, com.eu.habbo.messages.incoming.housekeeping.HousekeepingSetUserRankEvent.class);
|
||||
this.registerHandler(Incoming.HousekeepingTradeLockUserEvent, com.eu.habbo.messages.incoming.housekeeping.HousekeepingTradeLockUserEvent.class);
|
||||
this.registerHandler(Incoming.HousekeepingResetUserPasswordEvent, com.eu.habbo.messages.incoming.housekeeping.HousekeepingResetUserPasswordEvent.class);
|
||||
this.registerHandler(Incoming.HousekeepingFindRoomByIdEvent, com.eu.habbo.messages.incoming.housekeeping.HousekeepingFindRoomByIdEvent.class);
|
||||
this.registerHandler(Incoming.HousekeepingSearchRoomsEvent, com.eu.habbo.messages.incoming.housekeeping.HousekeepingSearchRoomsEvent.class);
|
||||
this.registerHandler(Incoming.HousekeepingRoomStateEvent, com.eu.habbo.messages.incoming.housekeeping.HousekeepingRoomStateEvent.class);
|
||||
this.registerHandler(Incoming.HousekeepingMuteRoomEvent, com.eu.habbo.messages.incoming.housekeeping.HousekeepingMuteRoomEvent.class);
|
||||
this.registerHandler(Incoming.HousekeepingKickAllFromRoomEvent, com.eu.habbo.messages.incoming.housekeeping.HousekeepingKickAllFromRoomEvent.class);
|
||||
this.registerHandler(Incoming.HousekeepingTransferRoomOwnershipEvent, com.eu.habbo.messages.incoming.housekeeping.HousekeepingTransferRoomOwnershipEvent.class);
|
||||
this.registerHandler(Incoming.HousekeepingDeleteRoomEvent, com.eu.habbo.messages.incoming.housekeeping.HousekeepingDeleteRoomEvent.class);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -472,4 +472,11 @@ public class Incoming {
|
||||
public static final int HousekeepingSetUserRankEvent = 9107;
|
||||
public static final int HousekeepingTradeLockUserEvent = 9108;
|
||||
public static final int HousekeepingResetUserPasswordEvent = 9109;
|
||||
public static final int HousekeepingFindRoomByIdEvent = 9110;
|
||||
public static final int HousekeepingSearchRoomsEvent = 9111;
|
||||
public static final int HousekeepingRoomStateEvent = 9112;
|
||||
public static final int HousekeepingMuteRoomEvent = 9113;
|
||||
public static final int HousekeepingKickAllFromRoomEvent = 9114;
|
||||
public static final int HousekeepingTransferRoomOwnershipEvent = 9115;
|
||||
public static final int HousekeepingDeleteRoomEvent = 9116;
|
||||
}
|
||||
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
package com.eu.habbo.messages.incoming.housekeeping;
|
||||
|
||||
import com.eu.habbo.Emulator;
|
||||
import com.eu.habbo.habbohotel.permissions.Permission;
|
||||
import com.eu.habbo.habbohotel.rooms.Room;
|
||||
import com.eu.habbo.messages.incoming.MessageHandler;
|
||||
import com.eu.habbo.messages.outgoing.housekeeping.HousekeepingActionResultComposer;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* Permanently delete a room. Mirrors the minimum-viable subset of
|
||||
* RequestDeleteRoomEvent: eject all users from the live room, dispose
|
||||
* + uncache, then DELETE FROM rooms. Pets/guild/custom-layout cleanup
|
||||
* is intentionally skipped on this slice — leftover rows in those
|
||||
* tables become orphans but don't crash the emulator; a follow-up
|
||||
* pass can cascade once we have a HK audit-log row to attach the
|
||||
* orphan-cleanup to.
|
||||
*/
|
||||
public class HousekeepingDeleteRoomEvent extends MessageHandler {
|
||||
private static final String ACTION_KEY = "room.delete";
|
||||
|
||||
@Override
|
||||
public int getRatelimit() {
|
||||
return 2000;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle() throws Exception {
|
||||
if (!this.client.getHabbo().hasPermission(Permission.ACC_HOUSEKEEPING)) {
|
||||
return;
|
||||
}
|
||||
|
||||
int roomId = this.packet.readInt();
|
||||
|
||||
if (roomId <= 0) {
|
||||
this.client.sendResponse(new HousekeepingActionResultComposer(ACTION_KEY, false, 0, "housekeeping.error.invalid_input"));
|
||||
return;
|
||||
}
|
||||
|
||||
Room room = Emulator.getGameEnvironment().getRoomManager().loadRoom(roomId, false);
|
||||
|
||||
if (room != null) {
|
||||
room.ejectAll();
|
||||
room.preventUnloading = false;
|
||||
room.dispose();
|
||||
Emulator.getGameEnvironment().getRoomManager().uncacheRoom(room);
|
||||
}
|
||||
|
||||
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection();
|
||||
PreparedStatement statement = connection.prepareStatement("DELETE FROM rooms WHERE id = ? LIMIT 1")) {
|
||||
statement.setInt(1, roomId);
|
||||
int rows = statement.executeUpdate();
|
||||
|
||||
if (rows == 0) {
|
||||
this.client.sendResponse(new HousekeepingActionResultComposer(ACTION_KEY, false, 0, "housekeeping.error.room_not_found"));
|
||||
return;
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
this.client.sendResponse(new HousekeepingActionResultComposer(ACTION_KEY, false, 0, "housekeeping.error.db_failed"));
|
||||
return;
|
||||
}
|
||||
|
||||
this.client.sendResponse(new HousekeepingActionResultComposer(ACTION_KEY, true, roomId, ""));
|
||||
}
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
package com.eu.habbo.messages.incoming.housekeeping;
|
||||
|
||||
import com.eu.habbo.Emulator;
|
||||
import com.eu.habbo.habbohotel.permissions.Permission;
|
||||
import com.eu.habbo.habbohotel.rooms.Room;
|
||||
import com.eu.habbo.messages.incoming.MessageHandler;
|
||||
import com.eu.habbo.messages.outgoing.housekeeping.HousekeepingRoomDetailComposer;
|
||||
|
||||
public class HousekeepingFindRoomByIdEvent extends MessageHandler {
|
||||
@Override
|
||||
public int getRatelimit() {
|
||||
return 500;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle() throws Exception {
|
||||
if (!this.client.getHabbo().hasPermission(Permission.ACC_HOUSEKEEPING)) {
|
||||
return;
|
||||
}
|
||||
|
||||
int roomId = this.packet.readInt();
|
||||
|
||||
if (roomId <= 0) {
|
||||
this.client.sendResponse(new HousekeepingRoomDetailComposer(null));
|
||||
return;
|
||||
}
|
||||
|
||||
// loadRoom covers both the in-memory cache (already-loaded rooms)
|
||||
// and the offline path (SELECT * FROM rooms WHERE id=?). Pass
|
||||
// false for loadData so we don't pull furni/bots/pets just to
|
||||
// render an HK panel summary — getOwnerName / getUserCount work
|
||||
// on the pre-loaded skeleton.
|
||||
Room room = Emulator.getGameEnvironment().getRoomManager().loadRoom(roomId, false);
|
||||
|
||||
this.client.sendResponse(new HousekeepingRoomDetailComposer(room));
|
||||
}
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
package com.eu.habbo.messages.incoming.housekeeping;
|
||||
|
||||
import com.eu.habbo.Emulator;
|
||||
import com.eu.habbo.habbohotel.permissions.Permission;
|
||||
import com.eu.habbo.habbohotel.rooms.Room;
|
||||
import com.eu.habbo.messages.incoming.MessageHandler;
|
||||
import com.eu.habbo.messages.outgoing.housekeeping.HousekeepingActionResultComposer;
|
||||
|
||||
public class HousekeepingKickAllFromRoomEvent extends MessageHandler {
|
||||
private static final String ACTION_KEY = "room.kick_all";
|
||||
|
||||
@Override
|
||||
public int getRatelimit() {
|
||||
return 1000;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle() throws Exception {
|
||||
if (!this.client.getHabbo().hasPermission(Permission.ACC_HOUSEKEEPING)) {
|
||||
return;
|
||||
}
|
||||
|
||||
int roomId = this.packet.readInt();
|
||||
|
||||
if (roomId <= 0) {
|
||||
this.client.sendResponse(new HousekeepingActionResultComposer(ACTION_KEY, false, 0, "housekeeping.error.invalid_input"));
|
||||
return;
|
||||
}
|
||||
|
||||
Room room = Emulator.getGameEnvironment().getRoomManager().loadRoom(roomId, false);
|
||||
|
||||
if (room == null) {
|
||||
this.client.sendResponse(new HousekeepingActionResultComposer(ACTION_KEY, false, 0, "housekeeping.error.room_not_found"));
|
||||
return;
|
||||
}
|
||||
|
||||
room.ejectAll();
|
||||
|
||||
this.client.sendResponse(new HousekeepingActionResultComposer(ACTION_KEY, true, roomId, ""));
|
||||
}
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
package com.eu.habbo.messages.incoming.housekeeping;
|
||||
|
||||
import com.eu.habbo.Emulator;
|
||||
import com.eu.habbo.habbohotel.permissions.Permission;
|
||||
import com.eu.habbo.habbohotel.rooms.Room;
|
||||
import com.eu.habbo.messages.incoming.MessageHandler;
|
||||
import com.eu.habbo.messages.outgoing.housekeeping.HousekeepingActionResultComposer;
|
||||
|
||||
/**
|
||||
* Toggle room-wide mute. Habbo's Room.setMuted is boolean, not duration-
|
||||
* scoped, so the wire `minutes` arg picks the semantic: minutes==0 =>
|
||||
* unmute, minutes>0 => mute. An emulator-side scheduled unmute could
|
||||
* use the value as a timer, but for now the mute stays until the
|
||||
* operator unmutes manually — the minutes is reserved as a forward-
|
||||
* compat field on the wire.
|
||||
*/
|
||||
public class HousekeepingMuteRoomEvent extends MessageHandler {
|
||||
private static final String ACTION_KEY = "room.mute";
|
||||
|
||||
@Override
|
||||
public int getRatelimit() {
|
||||
return 1000;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle() throws Exception {
|
||||
if (!this.client.getHabbo().hasPermission(Permission.ACC_HOUSEKEEPING)) {
|
||||
return;
|
||||
}
|
||||
|
||||
int roomId = this.packet.readInt();
|
||||
int minutes = this.packet.readInt();
|
||||
|
||||
if (roomId <= 0) {
|
||||
this.client.sendResponse(new HousekeepingActionResultComposer(ACTION_KEY, false, 0, "housekeeping.error.invalid_input"));
|
||||
return;
|
||||
}
|
||||
|
||||
Room room = Emulator.getGameEnvironment().getRoomManager().loadRoom(roomId, false);
|
||||
|
||||
if (room == null) {
|
||||
this.client.sendResponse(new HousekeepingActionResultComposer(ACTION_KEY, false, 0, "housekeeping.error.room_not_found"));
|
||||
return;
|
||||
}
|
||||
|
||||
room.setMuted(minutes > 0);
|
||||
|
||||
this.client.sendResponse(new HousekeepingActionResultComposer(ACTION_KEY, true, roomId, ""));
|
||||
}
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
package com.eu.habbo.messages.incoming.housekeeping;
|
||||
|
||||
import com.eu.habbo.Emulator;
|
||||
import com.eu.habbo.habbohotel.permissions.Permission;
|
||||
import com.eu.habbo.habbohotel.rooms.Room;
|
||||
import com.eu.habbo.habbohotel.rooms.RoomState;
|
||||
import com.eu.habbo.messages.incoming.MessageHandler;
|
||||
import com.eu.habbo.messages.outgoing.housekeeping.HousekeepingActionResultComposer;
|
||||
|
||||
/**
|
||||
* Toggle the room state between OPEN (open) and LOCKED (closed). The
|
||||
* client picks which transition it wants via the boolean — true => OPEN,
|
||||
* false => LOCKED. Persists state through `Room.save()` so the change
|
||||
* outlives an unload.
|
||||
*/
|
||||
public class HousekeepingRoomStateEvent extends MessageHandler {
|
||||
@Override
|
||||
public int getRatelimit() {
|
||||
return 1000;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle() throws Exception {
|
||||
if (!this.client.getHabbo().hasPermission(Permission.ACC_HOUSEKEEPING)) {
|
||||
return;
|
||||
}
|
||||
|
||||
int roomId = this.packet.readInt();
|
||||
boolean open = this.packet.readBoolean();
|
||||
String actionKey = open ? "room.open" : "room.close";
|
||||
|
||||
if (roomId <= 0) {
|
||||
this.client.sendResponse(new HousekeepingActionResultComposer(actionKey, false, 0, "housekeeping.error.invalid_input"));
|
||||
return;
|
||||
}
|
||||
|
||||
Room room = Emulator.getGameEnvironment().getRoomManager().loadRoom(roomId, false);
|
||||
|
||||
if (room == null) {
|
||||
this.client.sendResponse(new HousekeepingActionResultComposer(actionKey, false, 0, "housekeeping.error.room_not_found"));
|
||||
return;
|
||||
}
|
||||
|
||||
room.setState(open ? RoomState.OPEN : RoomState.LOCKED);
|
||||
room.save();
|
||||
|
||||
this.client.sendResponse(new HousekeepingActionResultComposer(actionKey, true, roomId, ""));
|
||||
}
|
||||
}
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
package com.eu.habbo.messages.incoming.housekeeping;
|
||||
|
||||
import com.eu.habbo.Emulator;
|
||||
import com.eu.habbo.habbohotel.permissions.Permission;
|
||||
import com.eu.habbo.habbohotel.rooms.Room;
|
||||
import com.eu.habbo.messages.incoming.MessageHandler;
|
||||
import com.eu.habbo.messages.outgoing.housekeeping.HousekeepingRoomListComposer;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Search rooms by name. `exactMatch=true` => `name = ?` (used by the
|
||||
* findByName autocomplete that wants a unique hit). `exactMatch=false`
|
||||
* => `name LIKE concat(?, '%')` (used by the prefix dropdown).
|
||||
*
|
||||
* Both branches go through the same packet because the wire shape is
|
||||
* identical — the client picks which mode it wants by toggling the
|
||||
* boolean.
|
||||
*/
|
||||
public class HousekeepingSearchRoomsEvent extends MessageHandler {
|
||||
private static final int HARD_LIMIT = 50;
|
||||
|
||||
@Override
|
||||
public int getRatelimit() {
|
||||
return 500;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle() throws Exception {
|
||||
if (!this.client.getHabbo().hasPermission(Permission.ACC_HOUSEKEEPING)) {
|
||||
return;
|
||||
}
|
||||
|
||||
String query = this.packet.readString();
|
||||
boolean exactMatch = this.packet.readBoolean();
|
||||
int limit = Math.min(Math.max(this.packet.readInt(), 1), HARD_LIMIT);
|
||||
|
||||
if (query == null) query = "";
|
||||
query = query.trim();
|
||||
|
||||
if (query.isEmpty()) {
|
||||
this.client.sendResponse(new HousekeepingRoomListComposer(new ArrayList<>()));
|
||||
return;
|
||||
}
|
||||
|
||||
String sql = exactMatch
|
||||
? "SELECT id FROM rooms WHERE name = ? LIMIT ?"
|
||||
: "SELECT id FROM rooms WHERE name LIKE ? LIMIT ?";
|
||||
|
||||
List<Room> rooms = new ArrayList<>();
|
||||
|
||||
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection();
|
||||
PreparedStatement statement = connection.prepareStatement(sql)) {
|
||||
statement.setString(1, exactMatch ? query : query + "%");
|
||||
statement.setInt(2, limit);
|
||||
|
||||
try (ResultSet set = statement.executeQuery()) {
|
||||
while (set.next()) {
|
||||
Room room = Emulator.getGameEnvironment().getRoomManager().loadRoom(set.getInt("id"), false);
|
||||
|
||||
if (room != null) rooms.add(room);
|
||||
}
|
||||
}
|
||||
} catch (SQLException ignored) {
|
||||
// fall through with whatever we collected before the failure
|
||||
}
|
||||
|
||||
this.client.sendResponse(new HousekeepingRoomListComposer(rooms));
|
||||
}
|
||||
}
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
package com.eu.habbo.messages.incoming.housekeeping;
|
||||
|
||||
import com.eu.habbo.Emulator;
|
||||
import com.eu.habbo.habbohotel.permissions.Permission;
|
||||
import com.eu.habbo.habbohotel.users.HabboInfo;
|
||||
import com.eu.habbo.messages.incoming.MessageHandler;
|
||||
import com.eu.habbo.messages.outgoing.housekeeping.HousekeepingActionResultComposer;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* Transfer ownership of a room to a different user. Updates both
|
||||
* `rooms.owner_id` and `rooms.owner_name` so the cached owner name on
|
||||
* the navigator stays in sync without forcing a relog. The room is
|
||||
* touched via direct SQL rather than via Room.setOwnerId() because
|
||||
* the room may not be loaded.
|
||||
*/
|
||||
public class HousekeepingTransferRoomOwnershipEvent extends MessageHandler {
|
||||
private static final String ACTION_KEY = "room.transfer";
|
||||
|
||||
@Override
|
||||
public int getRatelimit() {
|
||||
return 2000;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle() throws Exception {
|
||||
if (!this.client.getHabbo().hasPermission(Permission.ACC_HOUSEKEEPING)) {
|
||||
return;
|
||||
}
|
||||
|
||||
int roomId = this.packet.readInt();
|
||||
int newOwnerId = this.packet.readInt();
|
||||
|
||||
if (roomId <= 0 || newOwnerId <= 0) {
|
||||
this.client.sendResponse(new HousekeepingActionResultComposer(ACTION_KEY, false, 0, "housekeeping.error.invalid_input"));
|
||||
return;
|
||||
}
|
||||
|
||||
HabboInfo newOwner = Emulator.getGameEnvironment().getHabboManager().getHabboInfo(newOwnerId);
|
||||
|
||||
if (newOwner == null) {
|
||||
this.client.sendResponse(new HousekeepingActionResultComposer(ACTION_KEY, false, 0, "housekeeping.error.new_owner_not_found"));
|
||||
return;
|
||||
}
|
||||
|
||||
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection();
|
||||
PreparedStatement statement = connection.prepareStatement("UPDATE rooms SET owner_id = ?, owner_name = ? WHERE id = ? LIMIT 1")) {
|
||||
statement.setInt(1, newOwnerId);
|
||||
statement.setString(2, newOwner.getUsername());
|
||||
statement.setInt(3, roomId);
|
||||
int rows = statement.executeUpdate();
|
||||
|
||||
if (rows == 0) {
|
||||
this.client.sendResponse(new HousekeepingActionResultComposer(ACTION_KEY, false, 0, "housekeeping.error.room_not_found"));
|
||||
return;
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
this.client.sendResponse(new HousekeepingActionResultComposer(ACTION_KEY, false, 0, "housekeeping.error.db_failed"));
|
||||
return;
|
||||
}
|
||||
|
||||
this.client.sendResponse(new HousekeepingActionResultComposer(ACTION_KEY, true, roomId, ""));
|
||||
}
|
||||
}
|
||||
@@ -589,5 +589,7 @@ public class Outgoing {
|
||||
// Housekeeping (in-client admin panel) — IDs 9200..9299 reserved
|
||||
public static final int HousekeepingUserDetailComposer = 9200;
|
||||
public static final int HousekeepingActionResultComposer = 9201;
|
||||
public static final int HousekeepingRoomDetailComposer = 9202;
|
||||
public static final int HousekeepingRoomListComposer = 9203;
|
||||
|
||||
}
|
||||
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
package com.eu.habbo.messages.outgoing.housekeeping;
|
||||
|
||||
import com.eu.habbo.habbohotel.rooms.Room;
|
||||
import com.eu.habbo.habbohotel.rooms.RoomState;
|
||||
import com.eu.habbo.messages.ServerMessage;
|
||||
import com.eu.habbo.messages.outgoing.MessageComposer;
|
||||
import com.eu.habbo.messages.outgoing.Outgoing;
|
||||
|
||||
public class HousekeepingRoomDetailComposer extends MessageComposer {
|
||||
private final Room room;
|
||||
|
||||
public HousekeepingRoomDetailComposer(Room room) {
|
||||
this.room = room;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ServerMessage composeInternal() {
|
||||
this.response.init(Outgoing.HousekeepingRoomDetailComposer);
|
||||
|
||||
if (this.room == null) {
|
||||
this.response.appendBoolean(false);
|
||||
return this.response;
|
||||
}
|
||||
|
||||
this.response.appendBoolean(true);
|
||||
appendRoomFields(this.response, this.room);
|
||||
|
||||
return this.response;
|
||||
}
|
||||
|
||||
/** Shared by HousekeepingRoomListComposer too. */
|
||||
public static void appendRoomFields(ServerMessage response, Room room) {
|
||||
response.appendInt(room.getId());
|
||||
response.appendString(safe(room.getName()));
|
||||
response.appendString(safe(room.getDescription()));
|
||||
response.appendInt(room.getOwnerId());
|
||||
response.appendString(safe(room.getOwnerName()));
|
||||
response.appendInt(room.getUserCount());
|
||||
response.appendInt(room.getUsersMax());
|
||||
response.appendBoolean(room.getState() != null && room.getState() != RoomState.OPEN);
|
||||
response.appendBoolean(room.isMuted());
|
||||
response.appendBoolean(room.isPublicRoom());
|
||||
response.appendInt(0); // createdAt — Room doesn't expose; left as 0 until a schema-side timestamp surfaces.
|
||||
}
|
||||
|
||||
private static String safe(String value) {
|
||||
return value != null ? value : "";
|
||||
}
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
package com.eu.habbo.messages.outgoing.housekeeping;
|
||||
|
||||
import com.eu.habbo.habbohotel.rooms.Room;
|
||||
import com.eu.habbo.messages.ServerMessage;
|
||||
import com.eu.habbo.messages.outgoing.MessageComposer;
|
||||
import com.eu.habbo.messages.outgoing.Outgoing;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class HousekeepingRoomListComposer extends MessageComposer {
|
||||
private final List<Room> rooms;
|
||||
|
||||
public HousekeepingRoomListComposer(List<Room> rooms) {
|
||||
this.rooms = rooms;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ServerMessage composeInternal() {
|
||||
this.response.init(Outgoing.HousekeepingRoomListComposer);
|
||||
this.response.appendInt(this.rooms != null ? this.rooms.size() : 0);
|
||||
|
||||
if (this.rooms != null) {
|
||||
for (Room room : this.rooms) {
|
||||
HousekeepingRoomDetailComposer.appendRoomFields(this.response, room);
|
||||
}
|
||||
}
|
||||
|
||||
return this.response;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user