diff --git a/Emulator/src/main/java/com/eu/habbo/core/RoomUserPetComposer.java b/Emulator/src/main/java/com/eu/habbo/core/RoomUserPetComposer.java index fa3a5190..73d7992a 100644 --- a/Emulator/src/main/java/com/eu/habbo/core/RoomUserPetComposer.java +++ b/Emulator/src/main/java/com/eu/habbo/core/RoomUserPetComposer.java @@ -47,6 +47,8 @@ public class RoomUserPetComposer extends MessageComposer { this.response.appendBoolean(true); //Can breed this.response.appendInt(0); this.response.appendString(""); + this.response.appendString("unknown"); + this.response.appendInt(0); return this.response; } diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/ItemManager.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/ItemManager.java index d724ce14..796f3f0c 100644 --- a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/ItemManager.java +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/ItemManager.java @@ -60,6 +60,7 @@ import com.eu.habbo.habbohotel.items.interactions.wired.extra.WiredExtraMovePhys import com.eu.habbo.habbohotel.items.interactions.wired.extra.WiredExtraMoveNoAnimation; import com.eu.habbo.habbohotel.items.interactions.wired.extra.WiredExtraOrEval; import com.eu.habbo.habbohotel.items.interactions.wired.extra.WiredExtraRandom; +import com.eu.habbo.habbohotel.items.interactions.wired.extra.WiredExtraTextOutputFurniName; import com.eu.habbo.habbohotel.items.interactions.wired.extra.WiredExtraTextOutputUsername; import com.eu.habbo.habbohotel.items.interactions.wired.extra.WiredExtraUnseen; import com.eu.habbo.habbohotel.items.interactions.wired.selector.*; @@ -355,6 +356,7 @@ public class ItemManager { this.interactionsList.add(new ItemInteraction("wf_xtra_exec_in_order", WiredExtraExecuteInOrder.class)); this.interactionsList.add(new ItemInteraction("wf_xtra_execution_limit", WiredExtraExecutionLimit.class)); this.interactionsList.add(new ItemInteraction("wf_xtra_text_output_username", WiredExtraTextOutputUsername.class)); + this.interactionsList.add(new ItemInteraction("wf_xtra_text_output_furni_name", WiredExtraTextOutputFurniName.class)); this.interactionsList.add(new ItemInteraction("wf_highscore", InteractionWiredHighscore.class)); @@ -697,7 +699,7 @@ public class ItemManager { } public void insertTeleportPair(int itemOneId, int itemTwoId) { - try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO items_teleports VALUES (?, ?)")) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO items_teleports (teleport_one_id, teleport_two_id) VALUES (?, ?)")) { statement.setInt(1, itemOneId); statement.setInt(2, itemTwoId); statement.execute(); @@ -717,20 +719,28 @@ public class ItemManager { } public int[] getTargetTeleportRoomId(HabboItem item) { - int[] a = new int[]{}; + int[] target = new int[]{}; - try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT items.id, items.room_id FROM items_teleports INNER JOIN items ON items_teleports.teleport_one_id = items.id OR items_teleports.teleport_two_id = items.id WHERE items.id != ? AND items.room_id > 0 LIMIT 1")) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT items_teleports.*, A.room_id as a_room_id, A.id as a_id, B.room_id as b_room_id, B.id as b_id FROM items_teleports INNER JOIN items AS A ON items_teleports.teleport_one_id = A.id INNER JOIN items AS B ON items_teleports.teleport_two_id = B.id WHERE (teleport_one_id = ? OR teleport_two_id = ?) LIMIT 1")) { statement.setInt(1, item.getId()); + statement.setInt(2, item.getId()); + try (ResultSet set = statement.executeQuery()) { if (set.next()) { - a = new int[]{set.getInt("room_id"), set.getInt("id")}; + final boolean useA = (set.getInt("a_id") != item.getId()); + final int targetRoomId = useA ? set.getInt("a_room_id") : set.getInt("b_room_id"); + final int targetItemId = useA ? set.getInt("a_id") : set.getInt("b_id"); + + if (targetRoomId > 0 && targetItemId > 0) { + target = new int[]{targetRoomId, targetItemId}; + } } } } catch (SQLException e) { LOGGER.error("Caught SQL exception", e); } - return a; + return target; } public HabboItem loadHabboItem(int itemId) { diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWiredEffect.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWiredEffect.java index 84c7453a..9bf8a905 100644 --- a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWiredEffect.java +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWiredEffect.java @@ -224,13 +224,19 @@ public abstract class InteractionWiredEffect extends InteractionWired implements } protected LinkedHashSet getSelectableFloorItems(Room room) { + return this.getSelectableFloorItems(room, null); + } + + protected LinkedHashSet getSelectableFloorItems(Room room, WiredContext ctx) { LinkedHashSet result = new LinkedHashSet<>(); if (room == null) { return result; } + boolean includeWiredItems = this.includeWiredTargets(ctx); + room.getFloorItems().forEach(item -> { - if (item != null && !(item instanceof InteractionWired)) { + if (item != null && (includeWiredItems || !(item instanceof InteractionWired))) { result.add(item); } }); @@ -238,6 +244,10 @@ public abstract class InteractionWiredEffect extends InteractionWired implements return result; } + protected boolean includeWiredTargets(WiredContext ctx) { + return ctx != null && ctx.includeWiredSelectorItems(); + } + protected LinkedHashSet toLinkedHashSet(Iterable values) { LinkedHashSet result = new LinkedHashSet<>(); if (values == null) { diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/extra/WiredExtraTextOutputFurniName.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/extra/WiredExtraTextOutputFurniName.java new file mode 100644 index 00000000..a6c21d93 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/extra/WiredExtraTextOutputFurniName.java @@ -0,0 +1,294 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.extra; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredExtra; +import com.eu.habbo.habbohotel.items.interactions.wired.WiredSettings; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.wired.core.WiredManager; +import com.eu.habbo.habbohotel.wired.core.WiredSourceUtil; +import com.eu.habbo.messages.ServerMessage; +import gnu.trove.set.hash.THashSet; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +public class WiredExtraTextOutputFurniName extends InteractionWiredExtra { + public static final int CODE = 68; + public static final int TYPE_SINGLE = 1; + public static final int TYPE_MULTIPLE = 2; + public static final String DEFAULT_PLACEHOLDER_NAME = ""; + public static final String DEFAULT_DELIMITER = ", "; + public static final int MAX_PLACEHOLDER_NAME_LENGTH = 32; + public static final int MAX_DELIMITER_LENGTH = 16; + + private static final Pattern WRAPPED_PLACEHOLDER_PATTERN = Pattern.compile("^\\$\\((.*)\\)$"); + + private final THashSet items; + private String placeholderName = DEFAULT_PLACEHOLDER_NAME; + private int placeholderType = TYPE_SINGLE; + private String delimiter = DEFAULT_DELIMITER; + private int furniSource = WiredSourceUtil.SOURCE_TRIGGER; + + public WiredExtraTextOutputFurniName(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + this.items = new THashSet<>(); + } + + public WiredExtraTextOutputFurniName(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + this.items = new THashSet<>(); + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + return false; + } + + @Override + public boolean saveData(WiredSettings settings, GameClient gameClient) { + int[] intParams = settings.getIntParams(); + String[] stringData = splitStringData(settings.getStringParam()); + + this.placeholderType = normalizePlaceholderType((intParams.length > 0) ? intParams[0] : TYPE_SINGLE); + this.furniSource = normalizeFurniSource((intParams.length > 1) ? intParams[1] : WiredSourceUtil.SOURCE_TRIGGER); + this.placeholderName = normalizePlaceholderName(stringData[0]); + this.delimiter = normalizeDelimiter(stringData[1]); + this.items.clear(); + + if (this.furniSource != WiredSourceUtil.SOURCE_SELECTED) { + return true; + } + + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()); + if (room == null) { + return false; + } + + if (settings.getFurniIds().length > Emulator.getConfig().getInt("hotel.wired.furni.selection.count")) { + return false; + } + + for (int itemId : settings.getFurniIds()) { + HabboItem item = room.getHabboItem(itemId); + + if (item != null) { + this.items.add(item); + } + } + + return true; + } + + @Override + public String getWiredData() { + return WiredManager.getGson().toJson(new JsonData( + this.placeholderName, + this.placeholderType, + this.delimiter, + this.furniSource, + this.items.stream().map(HabboItem::getId).collect(Collectors.toList()) + )); + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + this.refresh(room); + + message.appendBoolean(false); + message.appendInt(WiredManager.MAXIMUM_FURNI_SELECTION); + message.appendInt(this.items.size()); + + for (HabboItem item : this.items) { + message.appendInt(item.getId()); + } + + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(this.placeholderName + "\t" + this.delimiter); + message.appendInt(2); + message.appendInt(this.placeholderType); + message.appendInt(this.furniSource); + message.appendInt(0); + message.appendInt(CODE); + message.appendInt(0); + message.appendInt(0); + } + + @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); + + if (data != null) { + this.placeholderName = normalizePlaceholderName(data.placeholderName); + this.placeholderType = normalizePlaceholderType(data.placeholderType); + this.delimiter = normalizeDelimiter(data.delimiter); + this.furniSource = normalizeFurniSource(data.furniSource); + + if (data.itemIds != null) { + for (Integer itemId : data.itemIds) { + HabboItem item = room.getHabboItem(itemId); + + if (item != null) { + this.items.add(item); + } + } + } + } + + return; + } + + String[] legacyData = splitStringData(wiredData); + this.placeholderName = normalizePlaceholderName(legacyData[0]); + this.delimiter = normalizeDelimiter(legacyData[1]); + } + + @Override + public void onPickUp() { + this.items.clear(); + this.placeholderName = DEFAULT_PLACEHOLDER_NAME; + this.placeholderType = TYPE_SINGLE; + this.delimiter = DEFAULT_DELIMITER; + this.furniSource = WiredSourceUtil.SOURCE_TRIGGER; + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } + + @Override + public boolean hasConfiguration() { + return true; + } + + public String getPlaceholderName() { + return this.placeholderName; + } + + public String getPlaceholderToken() { + return this.placeholderName.isEmpty() ? "" : "$(" + this.placeholderName + ")"; + } + + public int getPlaceholderType() { + return this.placeholderType; + } + + public String getDelimiter() { + return this.delimiter; + } + + public int getFurniSource() { + return this.furniSource; + } + + public THashSet getItems() { + return this.items; + } + + private void refresh(Room room) { + THashSet remove = new THashSet<>(); + + for (HabboItem item : this.items) { + if (room.getHabboItem(item.getId()) == null) { + remove.add(item); + } + } + + for (HabboItem item : remove) { + this.items.remove(item); + } + } + + private static String[] splitStringData(String value) { + if (value == null) { + return new String[] { DEFAULT_PLACEHOLDER_NAME, DEFAULT_DELIMITER }; + } + + String[] parts = value.split("\t", -1); + + if (parts.length <= 1) { + return new String[] { value, DEFAULT_DELIMITER }; + } + + return new String[] { parts[0], parts[1] }; + } + + private static int normalizePlaceholderType(int value) { + return (value == TYPE_MULTIPLE) ? TYPE_MULTIPLE : TYPE_SINGLE; + } + + private static String normalizePlaceholderName(String value) { + if (value == null) { + return DEFAULT_PLACEHOLDER_NAME; + } + + String normalized = value.trim().replace("\t", "").replace("\r", "").replace("\n", ""); + if (WRAPPED_PLACEHOLDER_PATTERN.matcher(normalized).matches()) { + normalized = normalized.substring(2, normalized.length() - 1).trim(); + } + + if (normalized.length() > MAX_PLACEHOLDER_NAME_LENGTH) { + normalized = normalized.substring(0, MAX_PLACEHOLDER_NAME_LENGTH); + } + + return normalized; + } + + private static String normalizeDelimiter(String value) { + if (value == null) { + return DEFAULT_DELIMITER; + } + + String normalized = value.replace("\t", "").replace("\r", "").replace("\n", ""); + + if (normalized.length() > MAX_DELIMITER_LENGTH) { + normalized = normalized.substring(0, MAX_DELIMITER_LENGTH); + } + + return normalized; + } + + private static int normalizeFurniSource(int value) { + switch (value) { + case WiredSourceUtil.SOURCE_SELECTED: + case WiredSourceUtil.SOURCE_SELECTOR: + case WiredSourceUtil.SOURCE_SIGNAL: + case WiredSourceUtil.SOURCE_TRIGGER: + return value; + default: + return WiredSourceUtil.SOURCE_TRIGGER; + } + } + + static class JsonData { + String placeholderName; + int placeholderType; + String delimiter; + int furniSource; + List itemIds; + + JsonData(String placeholderName, int placeholderType, String delimiter, int furniSource, List itemIds) { + this.placeholderName = placeholderName; + this.placeholderType = placeholderType; + this.delimiter = delimiter; + this.furniSource = furniSource; + this.itemIds = itemIds; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/selector/WiredEffectFurniAltitude.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/selector/WiredEffectFurniAltitude.java index a2b6473a..b77a2c1c 100644 --- a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/selector/WiredEffectFurniAltitude.java +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/selector/WiredEffectFurniAltitude.java @@ -48,10 +48,12 @@ public class WiredEffectFurniAltitude extends InteractionWiredEffect { return; } + boolean includeWiredItems = this.includeWiredTargets(ctx); + Set matchingItems = new LinkedHashSet<>(); room.getFloorItems().forEach(item -> { - if (item == null || item instanceof InteractionWired) { + if (item == null || (!includeWiredItems && item instanceof InteractionWired)) { return; } @@ -62,7 +64,7 @@ public class WiredEffectFurniAltitude extends InteractionWiredEffect { Set result = new LinkedHashSet<>(matchingItems); - result = this.applySelectorModifiers(result, this.getSelectableFloorItems(room), ctx.targets().items(), this.filterExisting, this.invert); + result = this.applySelectorModifiers(result, this.getSelectableFloorItems(room, ctx), ctx.targets().items(), this.filterExisting, this.invert); ctx.targets().setItems(result); } diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/selector/WiredEffectFurniArea.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/selector/WiredEffectFurniArea.java index 8b223fe5..7abbc94a 100644 --- a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/selector/WiredEffectFurniArea.java +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/selector/WiredEffectFurniArea.java @@ -44,16 +44,16 @@ public class WiredEffectFurniArea extends InteractionWiredEffect { Room room = ctx.room(); if (room == null || areaWidth <= 0 || areaHeight <= 0) return; - List furniInArea = getFurniInArea(room); + List furniInArea = getFurniInArea(room, this.includeWiredTargets(ctx)); ctx.targets().setItems(this.applySelectorModifiers( furniInArea, - this.getSelectableFloorItems(room), + this.getSelectableFloorItems(room, ctx), ctx.targets().items(), this.filterExisting, this.invert)); } - private List getFurniInArea(Room room) { + private List getFurniInArea(Room room, boolean includeWiredItems) { List result = new ArrayList<>(); int maxX = rootX + areaWidth - 1; @@ -62,7 +62,7 @@ public class WiredEffectFurniArea extends InteractionWiredEffect { for (int x = rootX; x <= maxX; x++) { for (int y = rootY; y <= maxY; y++) { for (HabboItem item : room.getItemsAt(x, y)) { - if (item != null && !(item instanceof InteractionWired) && !result.contains(item)) { + if (item != null && (includeWiredItems || !(item instanceof InteractionWired)) && !result.contains(item)) { result.add(item); } } @@ -161,6 +161,22 @@ public class WiredEffectFurniArea extends InteractionWiredEffect { return false; } + public int getRootX() { + return this.rootX; + } + + public int getRootY() { + return this.rootY; + } + + public int getAreaWidth() { + return this.areaWidth; + } + + public int getAreaHeight() { + return this.areaHeight; + } + static class JsonData { int rootX; int rootY; diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/selector/WiredEffectFurniByType.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/selector/WiredEffectFurniByType.java index e936fabe..c036239a 100644 --- a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/selector/WiredEffectFurniByType.java +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/selector/WiredEffectFurniByType.java @@ -48,6 +48,8 @@ public class WiredEffectFurniByType extends InteractionWiredEffect { Room room = ctx.room(); if (room == null) return; + boolean includeWiredItems = this.includeWiredTargets(ctx); + List sourceFurni = resolveSourceFurni(ctx, room); if (sourceFurni.isEmpty()) return; @@ -61,7 +63,7 @@ public class WiredEffectFurniByType extends InteractionWiredEffect { Set matched = new LinkedHashSet<>(); room.getFloorItems().forEach(item -> { - if (item instanceof InteractionWired) return; + if (!includeWiredItems && item instanceof InteractionWired) return; String key = matchState ? item.getBaseItem().getId() + ":" + item.getExtradata() : String.valueOf(item.getBaseItem().getId()); @@ -70,7 +72,7 @@ public class WiredEffectFurniByType extends InteractionWiredEffect { } }); - Set result = this.applySelectorModifiers(matched, this.getSelectableFloorItems(room), ctx.targets().items(), filterExisting, invert); + Set result = this.applySelectorModifiers(matched, this.getSelectableFloorItems(room, ctx), ctx.targets().items(), filterExisting, invert); ctx.targets().setItems(result); } diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/selector/WiredEffectFurniNeighborhood.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/selector/WiredEffectFurniNeighborhood.java index 2dd2c5b5..e1974f6a 100644 --- a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/selector/WiredEffectFurniNeighborhood.java +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/selector/WiredEffectFurniNeighborhood.java @@ -61,6 +61,8 @@ public class WiredEffectFurniNeighborhood extends InteractionWiredEffect { Room room = ctx.room(); if (room == null || tileOffsets.isEmpty()) return; + boolean includeWiredItems = this.includeWiredTargets(ctx); + List sourcePositions = resolveSourcePositions(ctx, room); if (sourcePositions.isEmpty()) return; @@ -75,7 +77,7 @@ public class WiredEffectFurniNeighborhood extends InteractionWiredEffect { for (HabboItem item : room.getItemsAt(tx, ty)) { if (item == null) continue; totalRaw++; - if (item instanceof InteractionWired) { + if (!includeWiredItems && item instanceof InteractionWired) { wiredSkipped++; LOGGER.info("[FurniNeighborhood] SKIP wired item {} ({}) at ({},{})", item.getId(), item.getClass().getSimpleName(), tx, ty); @@ -89,7 +91,7 @@ public class WiredEffectFurniNeighborhood extends InteractionWiredEffect { } LOGGER.info("[FurniNeighborhood] Raw={}, wiredSkipped={}, kept={}", totalRaw, wiredSkipped, result.size()); - result = this.applySelectorModifiers(result, this.getSelectableFloorItems(room), ctx.targets().items(), filterExisting, invert); + result = this.applySelectorModifiers(result, this.getSelectableFloorItems(room, ctx), ctx.targets().items(), filterExisting, invert); // Always set the selector result — even if empty. // An empty result means no items matched the neighborhood, so downstream diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/selector/WiredEffectFurniOnFurni.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/selector/WiredEffectFurniOnFurni.java index 0ec8730c..0e3c9e01 100644 --- a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/selector/WiredEffectFurniOnFurni.java +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/selector/WiredEffectFurniOnFurni.java @@ -67,12 +67,13 @@ public class WiredEffectFurniOnFurni extends InteractionWiredEffect { } Set result = new LinkedHashSet<>(); + boolean includeWiredItems = this.includeWiredTargets(ctx); for (HabboItem sourceItem : sourceItems) { - result.addAll(this.resolveRelatedItems(room, sourceItem)); + result.addAll(this.resolveRelatedItems(room, sourceItem, includeWiredItems)); } - result = this.applySelectorModifiers(result, this.getSelectableFloorItems(room), ctx.targets().items(), this.filterExisting, this.invert); + result = this.applySelectorModifiers(result, this.getSelectableFloorItems(room, ctx), ctx.targets().items(), this.filterExisting, this.invert); ctx.targets().setItems(result); } @@ -211,7 +212,7 @@ public class WiredEffectFurniOnFurni extends InteractionWiredEffect { return false; } - private Set resolveRelatedItems(Room room, HabboItem sourceItem) { + private Set resolveRelatedItems(Room room, HabboItem sourceItem, boolean includeWiredItems) { Set result = new LinkedHashSet<>(); if (sourceItem == null) { @@ -237,7 +238,7 @@ public class WiredEffectFurniOnFurni extends InteractionWiredEffect { } for (HabboItem matchedItem : room.getItemsAt(tile)) { - if (matchedItem == null || matchedItem instanceof InteractionWired) { + if (matchedItem == null || (!includeWiredItems && matchedItem instanceof InteractionWired)) { continue; } diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/selector/WiredEffectFurniPicks.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/selector/WiredEffectFurniPicks.java index 53a3c92c..26c16426 100644 --- a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/selector/WiredEffectFurniPicks.java +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/selector/WiredEffectFurniPicks.java @@ -45,12 +45,14 @@ public class WiredEffectFurniPicks extends InteractionWiredEffect { return; } + boolean includeWiredItems = this.includeWiredTargets(ctx); + Set result = this.pickedFurniIds.stream() .map(room::getHabboItem) - .filter(item -> item != null && !(item instanceof InteractionWired)) + .filter(item -> item != null && (includeWiredItems || !(item instanceof InteractionWired))) .collect(Collectors.toCollection(LinkedHashSet::new)); - result = this.applySelectorModifiers(result, this.getSelectableFloorItems(room), ctx.targets().items(), this.filterExisting, this.invert); + result = this.applySelectorModifiers(result, this.getSelectableFloorItems(room, ctx), ctx.targets().items(), this.filterExisting, this.invert); ctx.targets().setItems(result); } diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/selector/WiredEffectFurniSignal.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/selector/WiredEffectFurniSignal.java index 2dc15691..1ba14216 100644 --- a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/selector/WiredEffectFurniSignal.java +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/selector/WiredEffectFurniSignal.java @@ -42,15 +42,17 @@ public class WiredEffectFurniSignal extends InteractionWiredEffect { return; } + boolean includeWiredItems = this.includeWiredTargets(ctx); + Set result = new LinkedHashSet<>(); if (ctx.eventType() == WiredEvent.Type.SIGNAL_RECEIVED) { List signalItems = WiredSourceUtil.resolveItems(ctx, WiredSourceUtil.SOURCE_SIGNAL, null); Set matched = signalItems.stream() - .filter(item -> item != null && !(item instanceof InteractionWired)) + .filter(item -> item != null && (includeWiredItems || !(item instanceof InteractionWired))) .collect(java.util.stream.Collectors.toCollection(LinkedHashSet::new)); - result = this.applySelectorModifiers(matched, this.getSelectableFloorItems(room), ctx.targets().items(), this.filterExisting, this.invert); + result = this.applySelectorModifiers(matched, this.getSelectableFloorItems(room, ctx), ctx.targets().items(), this.filterExisting, this.invert); } ctx.targets().setItems(result); diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/selector/WiredEffectUsersArea.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/selector/WiredEffectUsersArea.java index b03f4bb7..0763cf9e 100644 --- a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/selector/WiredEffectUsersArea.java +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/selector/WiredEffectUsersArea.java @@ -147,6 +147,22 @@ public class WiredEffectUsersArea extends InteractionWiredEffect { return false; } + public int getRootX() { + return this.rootX; + } + + public int getRootY() { + return this.rootY; + } + + public int getAreaWidth() { + return this.areaWidth; + } + + public int getAreaHeight() { + return this.areaHeight; + } + static class JsonData { int rootX; int rootY; diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/Room.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/Room.java index 64dbb8bf..c4d9e653 100644 --- a/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/Room.java +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/Room.java @@ -28,6 +28,7 @@ import com.eu.habbo.messages.outgoing.inventory.InventoryRefreshComposer; import com.eu.habbo.messages.outgoing.rooms.HideDoorbellComposer; import com.eu.habbo.messages.outgoing.rooms.UpdateStackHeightComposer; import com.eu.habbo.messages.outgoing.rooms.items.*; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserIgnoredComposer; import com.eu.habbo.messages.outgoing.rooms.users.RoomUserStatusComposer; import com.eu.habbo.plugin.Event; import com.eu.habbo.plugin.events.furniture.FurniturePickedUpEvent; @@ -1890,10 +1891,12 @@ public class Room implements Comparable, ISerialize, Runnable { public void muteHabbo(Habbo habbo, int minutes) { this.chatManager.muteHabbo(habbo, minutes); + this.sendComposer(new RoomUserIgnoredComposer(habbo, RoomUserIgnoredComposer.MUTED).compose()); } public void unmuteHabbo(Habbo habbo) { this.chatManager.unmuteHabbo(habbo); + this.sendComposer(new RoomUserIgnoredComposer(habbo, RoomUserIgnoredComposer.UNIGNORED).compose()); } public boolean isMuted(Habbo habbo) { diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomManager.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomManager.java index d02a95a1..fff73a0b 100644 --- a/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomManager.java +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomManager.java @@ -654,6 +654,8 @@ public class RoomManager { } habbo.setRoomUnit(new RoomUnit()); + habbo.getHabboInfo().setRoomEntryMethod("door"); + habbo.getHabboInfo().setRoomEntryTeleportId(0); habbo.getRoomUnit().clearStatus(); if (habbo.getRoomUnit().getCurrentLocation() == null) { @@ -672,8 +674,10 @@ public class RoomManager { // Furniture teleport spawn habbo.getRoomUnit().setCanLeaveRoomByDoor(false); habbo.getRoomUnit().isTeleporting = true; + habbo.getHabboInfo().setRoomEntryMethod("teleport"); HabboItem topItem = room.getTopItemAt(doorLocation.x, doorLocation.y); if (topItem != null) { + habbo.getHabboInfo().setRoomEntryTeleportId(topItem.getId()); habbo.getRoomUnit().setRotation(RoomUserRotation.values()[topItem.getRotation()]); } } diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/users/HabboInfo.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/HabboInfo.java index c0524b9e..5c21f4ca 100644 --- a/Emulator/src/main/java/com/eu/habbo/habbohotel/users/HabboInfo.java +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/HabboInfo.java @@ -47,6 +47,8 @@ public class HabboInfo implements Runnable { private int InfostandOverlay; private int loadingRoom; private Room currentRoom; + private String roomEntryMethod = "door"; + private int roomEntryTeleportId = 0; private int roomQueueId; private RideablePet riding; private Class currentGame; @@ -435,6 +437,22 @@ public class HabboInfo implements Runnable { this.currentRoom = room; } + public String getRoomEntryMethod() { + return this.roomEntryMethod; + } + + public void setRoomEntryMethod(String roomEntryMethod) { + this.roomEntryMethod = roomEntryMethod; + } + + public int getRoomEntryTeleportId() { + return this.roomEntryTeleportId; + } + + public void setRoomEntryTeleportId(int roomEntryTeleportId) { + this.roomEntryTeleportId = roomEntryTeleportId; + } + public int getRoomQueueId() { return this.roomQueueId; } diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/users/HabboItem.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/HabboItem.java index 7f37a1ae..9a8849fd 100644 --- a/Emulator/src/main/java/com/eu/habbo/habbohotel/users/HabboItem.java +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/HabboItem.java @@ -133,6 +133,24 @@ public abstract class HabboItem implements Runnable, IEventTriggers { serverMessage.appendInt(-1); serverMessage.appendInt(this.isUsable()); serverMessage.appendInt(this.getUserId()); + serverMessage.appendInt(this.getBaseItem().allowStack() ? 1 : 0); + serverMessage.appendInt(this.getBaseItem().allowSit() ? 1 : 0); + serverMessage.appendInt(this.getBaseItem().allowLay() ? 1 : 0); + serverMessage.appendInt(this.getBaseItem().allowWalk() ? 1 : 0); + serverMessage.appendInt(this.getBaseItem().getWidth()); + serverMessage.appendInt(this.getBaseItem().getLength()); + serverMessage.appendInt(this.getTeleportTargetId()); + } + + public int getTeleportTargetId() { + if (!(InteractionTeleport.class.isAssignableFrom(this.getBaseItem().getInteractionType().getType()) + || InteractionTeleportTile.class.isAssignableFrom(this.getBaseItem().getInteractionType().getType()))) { + return 0; + } + + int[] target = Emulator.getGameEnvironment().getItemManager().getTargetTeleportRoomId(this); + + return (target.length >= 2) ? target[1] : 0; } public int getId() { diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/core/WiredContext.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/core/WiredContext.java index 142528e7..f52ca70c 100644 --- a/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/core/WiredContext.java +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/core/WiredContext.java @@ -59,6 +59,9 @@ public final class WiredContext { /** Extra settings from the trigger item (for legacy compatibility) */ private final Object[] legacySettings; + /** Whether selector item resolution should include wired furniture too. */ + private boolean includeWiredSelectorItems = false; + /** * Create a new wired context. * @@ -256,6 +259,14 @@ public final class WiredContext { return legacySettings != null ? legacySettings : new Object[0]; } + public boolean includeWiredSelectorItems() { + return this.includeWiredSelectorItems; + } + + public void setIncludeWiredSelectorItems(boolean includeWiredSelectorItems) { + this.includeWiredSelectorItems = includeWiredSelectorItems; + } + // ========== Utility Methods ========== /** diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/core/WiredSourceUtil.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/core/WiredSourceUtil.java index c2094c6b..8e4dbd75 100644 --- a/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/core/WiredSourceUtil.java +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/core/WiredSourceUtil.java @@ -93,6 +93,24 @@ public final class WiredSourceUtil { return value == SOURCE_SELECTED || isDefaultUserSource(value); } + public static List resolveSelectorItems(WiredContext ctx, boolean includeWiredItems) { + if (ctx == null) { + return Collections.emptyList(); + } + + if (!includeWiredItems) { + return resolveItems(ctx, SOURCE_SELECTOR, null); + } + + WiredContext selectorContext = executeSelectors(cloneSelectorContext(ctx, true)); + + if (selectorContext == null || !selectorContext.targets().isItemsModifiedBySelector()) { + return Collections.emptyList(); + } + + return new ArrayList<>(selectorContext.targets().items()); + } + private static WiredTargets getSelectorTargets(WiredContext ctx) { if (ctx == null) { return new WiredTargets(); @@ -139,6 +157,7 @@ public final class WiredSourceUtil { new WiredState(100), originalCtx.legacySettings() ); + selectorCtx.setIncludeWiredSelectorItems(originalCtx.includeWiredSelectorItems()); List selectorEffects = getOrderedSelectorEffects(originalCtx, room, triggerItem); @@ -159,6 +178,23 @@ public final class WiredSourceUtil { return selectorCtx; } + private static WiredContext cloneSelectorContext(WiredContext originalCtx, boolean includeWiredItems) { + if (originalCtx == null) { + return null; + } + + WiredContext selectorCtx = new WiredContext( + originalCtx.event(), + originalCtx.triggerItem(), + originalCtx.stack(), + originalCtx.services(), + new WiredState(100), + originalCtx.legacySettings() + ); + selectorCtx.setIncludeWiredSelectorItems(includeWiredItems); + return selectorCtx; + } + private static List getOrderedSelectorEffects(WiredContext originalCtx, Room room, HabboItem triggerItem) { List selectorEffects = new ArrayList<>(); diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/core/WiredTextPlaceholderUtil.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/core/WiredTextPlaceholderUtil.java index 6fb80e11..d9b86538 100644 --- a/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/core/WiredTextPlaceholderUtil.java +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/core/WiredTextPlaceholderUtil.java @@ -1,9 +1,13 @@ package com.eu.habbo.habbohotel.wired.core; +import com.eu.habbo.habbohotel.bots.Bot; import com.eu.habbo.habbohotel.items.interactions.InteractionWiredExtra; +import com.eu.habbo.habbohotel.items.interactions.wired.extra.WiredExtraTextOutputFurniName; import com.eu.habbo.habbohotel.items.interactions.wired.extra.WiredExtraTextOutputUsername; +import com.eu.habbo.habbohotel.pets.Pet; import com.eu.habbo.habbohotel.rooms.Room; import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.rooms.RoomUnitType; import com.eu.habbo.habbohotel.users.Habbo; import com.eu.habbo.habbohotel.users.HabboItem; import gnu.trove.set.hash.THashSet; @@ -36,18 +40,25 @@ public final class WiredTextPlaceholderUtil { String resolvedText = text; for (InteractionWiredExtra extra : WiredExecutionOrderUtil.sort(extras)) { - if (!(extra instanceof WiredExtraTextOutputUsername)) { + if (extra instanceof WiredExtraTextOutputUsername) { + WiredExtraTextOutputUsername usernameExtra = (WiredExtraTextOutputUsername) extra; + String placeholderToken = usernameExtra.getPlaceholderToken(); + + if (!placeholderToken.isEmpty() && resolvedText.contains(placeholderToken)) { + resolvedText = resolvedText.replace(placeholderToken, buildUsernameReplacement(ctx, usernameExtra)); + } + continue; } - WiredExtraTextOutputUsername usernameExtra = (WiredExtraTextOutputUsername) extra; - String placeholderToken = usernameExtra.getPlaceholderToken(); + if (extra instanceof WiredExtraTextOutputFurniName) { + WiredExtraTextOutputFurniName furniExtra = (WiredExtraTextOutputFurniName) extra; + String placeholderToken = furniExtra.getPlaceholderToken(); - if (placeholderToken.isEmpty() || !resolvedText.contains(placeholderToken)) { - continue; + if (!placeholderToken.isEmpty() && resolvedText.contains(placeholderToken)) { + resolvedText = resolvedText.replace(placeholderToken, buildFurniNameReplacement(ctx, furniExtra)); + } } - - resolvedText = resolvedText.replace(placeholderToken, buildUsernameReplacement(ctx, usernameExtra)); } return resolvedText; @@ -83,7 +94,6 @@ public final class WiredTextPlaceholderUtil { return ""; } - Room room = ctx.room(); LinkedHashSet seenUserIds = new LinkedHashSet<>(); List usernames = new ArrayList<>(); @@ -92,12 +102,12 @@ public final class WiredTextPlaceholderUtil { continue; } - Habbo habbo = room.getHabbo(unit); - if ((habbo == null) || (habbo.getHabboInfo() == null)) { + String roomUnitName = getRoomUnitName(ctx.room(), unit); + if (roomUnitName == null || roomUnitName.trim().isEmpty()) { continue; } - usernames.add(habbo.getHabboInfo().getUsername()); + usernames.add(roomUnitName); } if (usernames.isEmpty()) { @@ -110,4 +120,70 @@ public final class WiredTextPlaceholderUtil { return usernames.get(0); } + + private static String buildFurniNameReplacement(WiredContext ctx, WiredExtraTextOutputFurniName extra) { + List items; + if (extra.getFurniSource() == WiredSourceUtil.SOURCE_SELECTOR) { + items = WiredSourceUtil.resolveSelectorItems(ctx, true); + } else { + items = WiredSourceUtil.resolveItems(ctx, extra.getFurniSource(), extra.getItems()); + } + + if (items.isEmpty()) { + return ""; + } + + LinkedHashSet seenItemIds = new LinkedHashSet<>(); + List furniNames = new ArrayList<>(); + + for (HabboItem item : items) { + if ((item == null) || (item.getBaseItem() == null) || !seenItemIds.add(item.getId())) { + continue; + } + + String furniName = item.getBaseItem().getFullName(); + if (furniName == null || furniName.trim().isEmpty()) { + furniName = item.getBaseItem().getName(); + } + + if (furniName == null || furniName.trim().isEmpty()) { + continue; + } + + furniNames.add(furniName); + } + + if (furniNames.isEmpty()) { + return ""; + } + + if (extra.getPlaceholderType() == WiredExtraTextOutputFurniName.TYPE_MULTIPLE) { + return String.join(extra.getDelimiter(), furniNames); + } + + return furniNames.get(0); + } + + private static String getRoomUnitName(Room room, RoomUnit roomUnit) { + if (room == null || roomUnit == null) { + return ""; + } + + if (roomUnit.getRoomUnitType() == RoomUnitType.USER) { + Habbo habbo = room.getHabbo(roomUnit); + return (habbo != null && habbo.getHabboInfo() != null) ? habbo.getHabboInfo().getUsername() : ""; + } + + if (roomUnit.getRoomUnitType() == RoomUnitType.BOT) { + Bot bot = room.getBot(roomUnit); + return (bot != null) ? bot.getName() : ""; + } + + if (roomUnit.getRoomUnitType() == RoomUnitType.PET) { + Pet pet = room.getPet(roomUnit); + return (pet != null) ? pet.getName() : ""; + } + + return ""; + } } diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/UpdateFurniturePositionEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/UpdateFurniturePositionEvent.java index ee0b9ae0..f5bce826 100644 --- a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/UpdateFurniturePositionEvent.java +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/UpdateFurniturePositionEvent.java @@ -7,8 +7,12 @@ import com.eu.habbo.habbohotel.users.HabboItem; 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.rooms.WiredMovementsComposer; import com.eu.habbo.messages.outgoing.rooms.items.FloorItemUpdateComposer; +import java.util.ArrayList; +import java.util.List; + public class UpdateFurniturePositionEvent extends MessageHandler { @Override public void handle() throws Exception { @@ -34,10 +38,30 @@ public class UpdateFurniturePositionEvent extends MessageHandler { return; } - error = room.moveFurniTo(item, tile, rotation, z, this.client.getHabbo(), true, true); + RoomTile oldTile = room.getLayout().getTile(item.getX(), item.getY()); + double oldZ = item.getZ(); + + error = room.moveFurniTo(item, tile, rotation, z, this.client.getHabbo(), false, true); if (error != FurnitureMovementError.NONE) { this.client.sendResponse(new BubbleAlertComposer(BubbleAlertKeys.FURNITURE_PLACEMENT_ERROR.key, error.errorCode)); this.client.sendResponse(new FloorItemUpdateComposer(item)); + return; + } + + if (oldTile != null) { + List movements = new ArrayList<>(1); + movements.add(WiredMovementsComposer.furniMovement( + item.getId(), + oldTile.x, + oldTile.y, + tile.x, + tile.y, + oldZ, + item.getZ(), + item.getRotation(), + WiredMovementsComposer.DEFAULT_DURATION)); + + room.sendComposer(new WiredMovementsComposer(movements).compose()); } } } diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomDataComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomDataComposer.java index 01326eac..4f6163bc 100644 --- a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomDataComposer.java +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomDataComposer.java @@ -7,6 +7,7 @@ import com.eu.habbo.habbohotel.users.Habbo; import com.eu.habbo.messages.ServerMessage; import com.eu.habbo.messages.outgoing.MessageComposer; import com.eu.habbo.messages.outgoing.Outgoing; +import com.eu.habbo.util.HotelDateTimeUtil; public class RoomDataComposer extends MessageComposer { private final Room room; @@ -108,6 +109,9 @@ public class RoomDataComposer extends MessageComposer { this.response.appendInt(this.room.getChatSpeed()); this.response.appendInt(this.room.getChatDistance()); this.response.appendInt(this.room.getChatProtection()); + this.response.appendString(HotelDateTimeUtil.getTimezoneId()); + this.response.appendString(String.valueOf(HotelDateTimeUtil.now().toInstant().toEpochMilli())); + this.response.appendInt(Room.MAXIMUM_FURNI); return this.response; @@ -128,4 +132,4 @@ public class RoomDataComposer extends MessageComposer { public boolean isEnterRoom() { return enterRoom; } -} \ No newline at end of file +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/AddFloorItemComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/AddFloorItemComposer.java index 809fede9..dde6076a 100644 --- a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/AddFloorItemComposer.java +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/AddFloorItemComposer.java @@ -24,6 +24,13 @@ public class AddFloorItemComposer extends MessageComposer { this.response.appendInt(-1); this.response.appendInt(this.item instanceof InteractionTeleport || this.item instanceof InteractionSwitch || this.item instanceof InteractionSwitchRemoteControl || this.item instanceof InteractionVendingMachine || this.item instanceof InteractionInformationTerminal || this.item instanceof InteractionPostIt|| this.item instanceof InteractionPuzzleBox ? 2 : this.item.isUsable() ? 1 : 0); this.response.appendInt(this.item.getUserId()); + this.response.appendInt(this.item.getBaseItem().allowStack() ? 1 : 0); + this.response.appendInt(this.item.getBaseItem().allowSit() ? 1 : 0); + this.response.appendInt(this.item.getBaseItem().allowLay() ? 1 : 0); + this.response.appendInt(this.item.getBaseItem().allowWalk() ? 1 : 0); + this.response.appendInt(this.item.getBaseItem().getWidth()); + this.response.appendInt(this.item.getBaseItem().getLength()); + this.response.appendInt(this.item.getTeleportTargetId()); this.response.appendString(this.itemOwnerName); return this.response; } diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/FloorItemUpdateComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/FloorItemUpdateComposer.java index 5ce45b95..77b292ea 100644 --- a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/FloorItemUpdateComposer.java +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/FloorItemUpdateComposer.java @@ -23,6 +23,13 @@ public class FloorItemUpdateComposer extends MessageComposer { this.response.appendInt(-1); this.response.appendInt(0); this.response.appendInt(this.item.getUserId()); + this.response.appendInt(this.item.getBaseItem().allowStack() ? 1 : 0); + this.response.appendInt(this.item.getBaseItem().allowSit() ? 1 : 0); + this.response.appendInt(this.item.getBaseItem().allowLay() ? 1 : 0); + this.response.appendInt(this.item.getBaseItem().allowWalk() ? 1 : 0); + this.response.appendInt(this.item.getBaseItem().getWidth()); + this.response.appendInt(this.item.getBaseItem().getLength()); + this.response.appendInt(this.item.getTeleportTargetId()); return this.response; } diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/RoomFloorItemsComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/RoomFloorItemsComposer.java index 908d81a3..162935ab 100644 --- a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/RoomFloorItemsComposer.java +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/RoomFloorItemsComposer.java @@ -46,6 +46,13 @@ public class RoomFloorItemsComposer extends MessageComposer { this.response.appendInt(-1); this.response.appendInt(item instanceof InteractionTeleport || item instanceof InteractionSwitch || item instanceof InteractionSwitchRemoteControl || item instanceof InteractionVendingMachine || item instanceof InteractionInformationTerminal || item instanceof InteractionPostIt || item instanceof InteractionPuzzleBox ? 2 : item.isUsable() ? 1 : 0); this.response.appendInt(item.getUserId()); + this.response.appendInt(item.getBaseItem().allowStack() ? 1 : 0); + this.response.appendInt(item.getBaseItem().allowSit() ? 1 : 0); + this.response.appendInt(item.getBaseItem().allowLay() ? 1 : 0); + this.response.appendInt(item.getBaseItem().allowWalk() ? 1 : 0); + this.response.appendInt(item.getBaseItem().getWidth()); + this.response.appendInt(item.getBaseItem().getLength()); + this.response.appendInt(item.getTeleportTargetId()); } return this.response; } diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/RoomPetComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/RoomPetComposer.java index 00b03985..2820706a 100644 --- a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/RoomPetComposer.java +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/RoomPetComposer.java @@ -59,6 +59,8 @@ public class RoomPetComposer extends MessageComposer implements TIntObjectProced this.response.appendBoolean(pet instanceof MonsterplantPet && ((MonsterplantPet) pet).isPubliclyBreedable()); //Breedable checkbox //Toggle breeding permission this.response.appendInt(pet instanceof MonsterplantPet ? ((MonsterplantPet) pet).getGrowthStage() : pet.getLevel()); this.response.appendString(""); + this.response.appendString("unknown"); + this.response.appendInt(0); return true; } diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUsersComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUsersComposer.java index 9efb6bf9..9d634f44 100644 --- a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUsersComposer.java +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUsersComposer.java @@ -66,6 +66,8 @@ public class RoomUsersComposer extends MessageComposer { this.response.appendString(""); this.response.appendInt(this.habbo.getHabboStats().getAchievementScore()); this.response.appendBoolean(true); + this.response.appendString(this.habbo.getHabboInfo().getRoomEntryMethod()); + this.response.appendInt(this.habbo.getHabboInfo().getRoomEntryTeleportId()); } else if (this.habbos != null) { this.response.appendInt(this.habbos.size()); for (Habbo habbo : this.habbos) { @@ -97,6 +99,8 @@ public class RoomUsersComposer extends MessageComposer { this.response.appendString(""); this.response.appendInt(habbo.getHabboStats().getAchievementScore()); this.response.appendBoolean(true); + this.response.appendString(habbo.getHabboInfo().getRoomEntryMethod()); + this.response.appendInt(habbo.getHabboInfo().getRoomEntryTeleportId()); } } } else if (this.bot != null) { @@ -128,6 +132,8 @@ public class RoomUsersComposer extends MessageComposer { this.response.appendShort(7); this.response.appendShort(8); this.response.appendShort(9); + this.response.appendString("unknown"); + this.response.appendInt(0); } else if (this.bots != null) { this.response.appendInt(this.bots.size()); for (Bot bot : this.bots) { @@ -158,6 +164,8 @@ public class RoomUsersComposer extends MessageComposer { this.response.appendShort(7); this.response.appendShort(8); this.response.appendShort(9); + this.response.appendString("unknown"); + this.response.appendInt(0); } } return this.response; diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionTwo.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionTwo.java index 53cdc9c7..ceab30ff 100644 --- a/Emulator/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionTwo.java +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionTwo.java @@ -10,17 +10,8 @@ import com.eu.habbo.habbohotel.users.HabboItem; import com.eu.habbo.habbohotel.wired.core.WiredFreezeUtil; import com.eu.habbo.messages.outgoing.rooms.users.RoomUserStatusComposer; import com.eu.habbo.threading.runnables.HabboItemNewState; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; class TeleportActionTwo implements Runnable { - private static final Logger LOGGER = LoggerFactory.getLogger(TeleportActionTwo.class); - private final HabboItem currentTeleport; private final Room room; private final GameClient client; @@ -65,23 +56,11 @@ class TeleportActionTwo implements Runnable { ((InteractionTeleport) this.currentTeleport).setTargetId(0); } if (((InteractionTeleport) this.currentTeleport).getTargetId() == 0) { - try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT items_teleports.*, A.room_id as a_room_id, A.id as a_id, B.room_id as b_room_id, B.id as b_id FROM items_teleports INNER JOIN items AS A ON items_teleports.teleport_one_id = A.id INNER JOIN items AS B ON items_teleports.teleport_two_id = B.id WHERE (teleport_one_id = ? OR teleport_two_id = ?)")) { - statement.setInt(1, this.currentTeleport.getId()); - statement.setInt(2, this.currentTeleport.getId()); + int[] targetTeleport = Emulator.getGameEnvironment().getItemManager().getTargetTeleportRoomId(this.currentTeleport); - try (ResultSet set = statement.executeQuery()) { - if (set.next()) { - if (set.getInt("a_id") != this.currentTeleport.getId()) { - ((InteractionTeleport) this.currentTeleport).setTargetId(set.getInt("a_id")); - ((InteractionTeleport) this.currentTeleport).setTargetRoomId(set.getInt("a_room_id")); - } else { - ((InteractionTeleport) this.currentTeleport).setTargetId(set.getInt("b_id")); - ((InteractionTeleport) this.currentTeleport).setTargetRoomId(set.getInt("b_room_id")); - } - } - } - } catch (SQLException e) { - LOGGER.error("Caught SQL exception", e); + if (targetTeleport.length == 2) { + ((InteractionTeleport) this.currentTeleport).setTargetRoomId(targetTeleport[0]); + ((InteractionTeleport) this.currentTeleport).setTargetId(targetTeleport[1]); } }