From 1f0fbc0bce3fbec24fce9ec5b6d859bdaf632636 Mon Sep 17 00:00:00 2001 From: Lorenzune Date: Tue, 17 Mar 2026 03:27:55 +0100 Subject: [PATCH] feat(wired): add freeze and furni movement effects - register interaction types wf_act_freeze, wf_act_unfreeze, wf_act_furni_to_user, wf_act_user_to_furni and wf_act_furni_to_furni - add effect types FREEZE, UNFREEZE, FURNI_TO_USER, USER_TO_FURNI and FURNI_TO_FURNI - add freeze handling with cancel-on-teleport and cleanup on teleport or room leave - support furni-to-furni secondary target selection and immediate furni position persistence - prevent frozen users from walking until they are unfrozen or moved out of the frozen state --- .../habbo/habbohotel/items/ItemManager.java | 5 + .../wired/effects/WiredEffectFreeze.java | 175 +++++++++ .../effects/WiredEffectFurniToFurni.java | 354 ++++++++++++++++++ .../wired/effects/WiredEffectFurniToUser.java | 57 +++ .../wired/effects/WiredEffectUnfreeze.java | 149 ++++++++ .../effects/WiredEffectUserFurniBase.java | 260 +++++++++++++ .../wired/effects/WiredEffectUserToFurni.java | 48 +++ .../habbohotel/rooms/RoomUnitManager.java | 7 + .../habbohotel/wired/WiredEffectType.java | 7 +- .../wired/core/WiredFreezeUtil.java | 74 ++++ .../rooms/users/RoomUserWalkEvent.java | 3 +- .../threading/runnables/RoomUnitTeleport.java | 4 + .../teleport/TeleportActionFive.java | 4 + .../teleport/TeleportActionFour.java | 3 +- .../runnables/teleport/TeleportActionOne.java | 3 +- .../teleport/TeleportActionThree.java | 3 +- .../runnables/teleport/TeleportActionTwo.java | 3 +- 17 files changed, 1153 insertions(+), 6 deletions(-) create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectFreeze.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectFurniToFurni.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectFurniToUser.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectUnfreeze.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectUserFurniBase.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectUserToFurni.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/wired/core/WiredFreezeUtil.java 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 78bdda77..2f317f1f 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 @@ -264,6 +264,11 @@ public class ItemManager { this.interactionsList.add(new ItemInteraction("wf_act_alert", WiredEffectAlert.class)); this.interactionsList.add(new ItemInteraction("wf_act_give_handitem", WiredEffectGiveHandItem.class)); this.interactionsList.add(new ItemInteraction("wf_act_give_effect", WiredEffectGiveEffect.class)); + this.interactionsList.add(new ItemInteraction("wf_act_freeze", WiredEffectFreeze.class)); + this.interactionsList.add(new ItemInteraction("wf_act_unfreeze", WiredEffectUnfreeze.class)); + this.interactionsList.add(new ItemInteraction("wf_act_furni_to_user", WiredEffectFurniToUser.class)); + this.interactionsList.add(new ItemInteraction("wf_act_user_to_furni", WiredEffectUserToFurni.class)); + this.interactionsList.add(new ItemInteraction("wf_act_furni_to_furni", WiredEffectFurniToFurni.class)); this.interactionsList.add(new ItemInteraction("wf_slc_furni_area", WiredEffectFurniArea.class)); this.interactionsList.add(new ItemInteraction("wf_slc_furni_neighborhood", WiredEffectFurniNeighborhood.class)); this.interactionsList.add(new ItemInteraction("wf_slc_furni_bytype", WiredEffectFurniByType.class)); diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectFreeze.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectFreeze.java new file mode 100644 index 00000000..66f11eae --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectFreeze.java @@ -0,0 +1,175 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.effects; + +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.InteractionWiredEffect; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger; +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.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.core.WiredContext; +import com.eu.habbo.habbohotel.wired.core.WiredFreezeUtil; +import com.eu.habbo.habbohotel.wired.core.WiredManager; +import com.eu.habbo.habbohotel.wired.core.WiredSourceUtil; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.wired.WiredSaveException; +import gnu.trove.procedure.TObjectProcedure; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +public class WiredEffectFreeze extends InteractionWiredEffect { + private static final Set ALLOWED_EFFECT_IDS = Set.of(218, 12, 11, 53, 163); + public static final WiredEffectType type = WiredEffectType.FREEZE; + + private int effectId = 218; + private boolean cancelOnTeleport = false; + private int userSource = WiredSourceUtil.SOURCE_TRIGGER; + + public WiredEffectFreeze(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredEffectFreeze(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public void execute(WiredContext ctx) { + Room room = ctx.room(); + + for (RoomUnit roomUnit : WiredSourceUtil.resolveUsers(ctx, this.userSource)) { + if (room.getHabbo(roomUnit) == null) { + continue; + } + + WiredFreezeUtil.freeze(room, roomUnit, this.effectId, this.cancelOnTeleport); + } + } + + @Deprecated + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + return false; + } + + @Override + public String getWiredData() { + return WiredManager.getGson().toJson(new JsonData(this.effectId, this.cancelOnTeleport, this.getDelay(), this.userSource)); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + String wiredData = set.getString("wired_data"); + + if (wiredData.startsWith("{")) { + JsonData data = WiredManager.getGson().fromJson(wiredData, JsonData.class); + this.effectId = ALLOWED_EFFECT_IDS.contains(data.effectId) ? data.effectId : 218; + this.cancelOnTeleport = data.cancelOnTeleport; + this.setDelay(data.delay); + this.userSource = data.userSource; + } else { + this.effectId = 218; + this.cancelOnTeleport = false; + this.setDelay(0); + this.userSource = WiredSourceUtil.SOURCE_TRIGGER; + } + } + + @Override + public void onPickUp() { + this.effectId = 218; + this.cancelOnTeleport = false; + this.setDelay(0); + this.userSource = WiredSourceUtil.SOURCE_TRIGGER; + } + + @Override + public WiredEffectType getType() { + return type; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + message.appendBoolean(false); + message.appendInt(5); + message.appendInt(0); + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(""); + message.appendInt(3); + message.appendInt(this.effectId); + message.appendInt(this.cancelOnTeleport ? 1 : 0); + message.appendInt(this.userSource); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(this.getDelay()); + + if (this.requiresTriggeringUser()) { + List invalidTriggers = new ArrayList<>(); + room.getRoomSpecialTypes().getTriggers(this.getX(), this.getY()).forEach(new TObjectProcedure() { + @Override + public boolean execute(InteractionWiredTrigger object) { + if (!object.isTriggeredByRoomUnit()) { + invalidTriggers.add(object.getBaseItem().getSpriteId()); + } + return true; + } + }); + message.appendInt(invalidTriggers.size()); + for (Integer i : invalidTriggers) { + message.appendInt(i); + } + } else { + message.appendInt(0); + } + } + + @Override + public boolean saveData(WiredSettings settings, GameClient gameClient) throws WiredSaveException { + if (settings.getIntParams().length < 3) { + throw new WiredSaveException("Invalid data"); + } + + int nextEffectId = settings.getIntParams()[0]; + if (!ALLOWED_EFFECT_IDS.contains(nextEffectId)) { + throw new WiredSaveException("Invalid freeze effect"); + } + + int delay = settings.getDelay(); + if (delay > Emulator.getConfig().getInt("hotel.wired.max_delay", 20)) { + throw new WiredSaveException("Delay too long"); + } + + this.effectId = nextEffectId; + this.cancelOnTeleport = settings.getIntParams()[1] == 1; + this.userSource = settings.getIntParams()[2]; + this.setDelay(delay); + + return true; + } + + @Override + public boolean requiresTriggeringUser() { + return this.userSource == WiredSourceUtil.SOURCE_TRIGGER; + } + + static class JsonData { + int effectId; + boolean cancelOnTeleport; + int delay; + int userSource; + + public JsonData(int effectId, boolean cancelOnTeleport, int delay, int userSource) { + this.effectId = effectId; + this.cancelOnTeleport = cancelOnTeleport; + this.delay = delay; + this.userSource = userSource; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectFurniToFurni.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectFurniToFurni.java new file mode 100644 index 00000000..bdaa461b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectFurniToFurni.java @@ -0,0 +1,354 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.effects; + +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.InteractionWiredEffect; +import com.eu.habbo.habbohotel.items.interactions.wired.WiredSettings; +import com.eu.habbo.habbohotel.rooms.FurnitureMovementError; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.core.WiredContext; +import com.eu.habbo.habbohotel.wired.core.WiredManager; +import com.eu.habbo.habbohotel.wired.core.WiredSourceUtil; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.wired.WiredSaveException; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +public class WiredEffectFurniToFurni extends InteractionWiredEffect { + private static final int SOURCE_SECONDARY_SELECTED = 101; + private static final String FURNI_SPLIT_REGEX = "[;,\\t]"; + private static final String FURNI_DELIMITER = ";"; + + public static final WiredEffectType type = WiredEffectType.FURNI_TO_FURNI; + + private final List moveItems = new ArrayList<>(); + private final List targetItems = new ArrayList<>(); + private int moveSource = WiredSourceUtil.SOURCE_TRIGGER; + private int targetSource = WiredSourceUtil.SOURCE_TRIGGER; + + public WiredEffectFurniToFurni(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredEffectFurniToFurni(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public void execute(WiredContext ctx) { + Room room = ctx.room(); + + if (room == null) { + return; + } + + HabboItem moveItem = this.resolveLastMoveItem(ctx); + HabboItem targetItem = this.resolveLastTargetItem(ctx); + + if (moveItem == null || targetItem == null || moveItem.getId() == targetItem.getId()) { + return; + } + + RoomTile targetTile = room.getLayout().getTile(targetItem.getX(), targetItem.getY()); + if (targetTile == null) { + return; + } + + FurnitureMovementError error = room.moveFurniTo(moveItem, targetTile, moveItem.getRotation(), null, true, false); + if (error != FurnitureMovementError.NONE) { + room.moveFurniTo(moveItem, targetTile, moveItem.getRotation(), targetItem.getZ(), null, true, false); + } + } + + @Deprecated + @Override + public boolean execute(com.eu.habbo.habbohotel.rooms.RoomUnit roomUnit, Room room, Object[] stuff) { + return false; + } + + @Override + public String getWiredData() { + return WiredManager.getGson().toJson(new JsonData( + this.getDelay(), + this.moveItems.stream().map(HabboItem::getId).collect(Collectors.toList()), + this.targetItems.stream().map(HabboItem::getId).collect(Collectors.toList()), + this.moveSource, + this.targetSource + )); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + this.moveItems.clear(); + this.targetItems.clear(); + + String wiredData = set.getString("wired_data"); + + if (wiredData != null && wiredData.startsWith("{")) { + JsonData data = WiredManager.getGson().fromJson(wiredData, JsonData.class); + + this.setDelay(data.delay); + this.moveSource = data.moveSource; + this.targetSource = this.normalizeTargetSource(data.targetSource); + + this.loadItems(room, data.itemIds, this.moveItems); + this.loadItems(room, data.targetItemIds, this.targetItems); + + if (this.moveSource == WiredSourceUtil.SOURCE_TRIGGER && !this.moveItems.isEmpty()) { + this.moveSource = WiredSourceUtil.SOURCE_SELECTED; + } + + if (this.targetSource == WiredSourceUtil.SOURCE_TRIGGER && !this.targetItems.isEmpty()) { + this.targetSource = SOURCE_SECONDARY_SELECTED; + } + + return; + } + + if (wiredData != null && !wiredData.isEmpty()) { + String[] wiredDataOld = wiredData.split("\t"); + + if (wiredDataOld.length >= 1) { + this.setDelay(Integer.parseInt(wiredDataOld[0])); + } + + if (wiredDataOld.length >= 2 && !wiredDataOld[1].trim().isEmpty()) { + this.loadItems(room, this.parseIds(wiredDataOld[1], room), this.moveItems); + } + } + + this.moveSource = this.moveItems.isEmpty() ? WiredSourceUtil.SOURCE_TRIGGER : WiredSourceUtil.SOURCE_SELECTED; + this.targetSource = this.targetItems.isEmpty() ? WiredSourceUtil.SOURCE_TRIGGER : SOURCE_SECONDARY_SELECTED; + } + + @Override + public void onPickUp() { + this.moveItems.clear(); + this.targetItems.clear(); + this.moveSource = WiredSourceUtil.SOURCE_TRIGGER; + this.targetSource = WiredSourceUtil.SOURCE_TRIGGER; + this.setDelay(0); + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + this.validateItems(this.moveItems); + this.validateItems(this.targetItems); + + message.appendBoolean(false); + message.appendInt(WiredManager.MAXIMUM_FURNI_SELECTION); + message.appendInt(this.moveItems.size()); + + for (HabboItem item : this.moveItems) { + message.appendInt(item.getId()); + } + + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(this.serializeIds(this.targetItems)); + message.appendInt(2); + message.appendInt(this.moveSource); + message.appendInt(this.targetSource); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(this.getDelay()); + message.appendInt(0); + } + + @Override + public boolean saveData(WiredSettings settings, GameClient gameClient) throws WiredSaveException { + this.moveSource = (settings.getIntParams().length > 0) ? settings.getIntParams()[0] : WiredSourceUtil.SOURCE_TRIGGER; + this.targetSource = this.normalizeTargetSource((settings.getIntParams().length > 1) ? settings.getIntParams()[1] : WiredSourceUtil.SOURCE_TRIGGER); + + Room room = this.getRoom(); + if (room == null) { + throw new WiredSaveException("Room not found"); + } + + List newMoveItems = new ArrayList<>(); + if (this.moveSource == WiredSourceUtil.SOURCE_SELECTED) { + for (int itemId : settings.getFurniIds()) { + HabboItem item = room.getHabboItem(itemId); + + if (item == null) { + throw new WiredSaveException(String.format("Item %s not found", itemId)); + } + + newMoveItems.add(item); + } + } + + if (newMoveItems.size() > Emulator.getConfig().getInt("hotel.wired.furni.selection.count")) { + throw new WiredSaveException("Too many furni selected"); + } + + List newTargetItems = new ArrayList<>(); + if (this.targetSource == SOURCE_SECONDARY_SELECTED) { + newTargetItems.addAll(this.parseItems(settings.getStringParam(), room)); + } + + if (newTargetItems.size() > Emulator.getConfig().getInt("hotel.wired.furni.selection.count")) { + throw new WiredSaveException("Too many furni selected"); + } + + int delay = settings.getDelay(); + if (delay > Emulator.getConfig().getInt("hotel.wired.max_delay", 20)) { + throw new WiredSaveException("Delay too long"); + } + + this.moveItems.clear(); + this.moveItems.addAll(newMoveItems); + + this.targetItems.clear(); + this.targetItems.addAll(newTargetItems); + + this.setDelay(delay); + + return true; + } + + @Override + public WiredEffectType getType() { + return type; + } + + @Override + protected long requiredCooldown() { + return COOLDOWN_MOVEMENT; + } + + private HabboItem resolveLastMoveItem(WiredContext ctx) { + return this.resolveLastItem(ctx, this.moveSource, this.moveItems); + } + + private HabboItem resolveLastTargetItem(WiredContext ctx) { + int source = (this.targetSource == SOURCE_SECONDARY_SELECTED) ? WiredSourceUtil.SOURCE_SELECTED : this.targetSource; + return this.resolveLastItem(ctx, source, this.targetItems); + } + + private HabboItem resolveLastItem(WiredContext ctx, int source, List items) { + if (source == WiredSourceUtil.SOURCE_SELECTED) { + this.validateItems(items); + } + + List resolvedItems = WiredSourceUtil.resolveItems(ctx, source, items); + + if (resolvedItems.isEmpty()) { + return null; + } + + for (int index = resolvedItems.size() - 1; index >= 0; index--) { + HabboItem item = resolvedItems.get(index); + + if (item != null) { + return item; + } + } + + return null; + } + + private List parseItems(String data, Room room) throws WiredSaveException { + List items = new ArrayList<>(); + if (data == null || data.trim().isEmpty() || room == null) { + return items; + } + + Set seen = new HashSet<>(); + + for (String part : data.split(FURNI_SPLIT_REGEX)) { + if (part == null) { + continue; + } + + String trimmed = part.trim(); + if (trimmed.isEmpty()) { + continue; + } + + int itemId; + try { + itemId = Integer.parseInt(trimmed); + } catch (NumberFormatException e) { + continue; + } + + if (itemId <= 0 || !seen.add(itemId)) { + continue; + } + + HabboItem item = room.getHabboItem(itemId); + if (item == null) { + throw new WiredSaveException(String.format("Item %s not found", itemId)); + } + + items.add(item); + } + + return items; + } + + private List parseIds(String data, Room room) { + try { + return this.parseItems(data, room).stream().map(HabboItem::getId).collect(Collectors.toList()); + } catch (WiredSaveException e) { + return new ArrayList<>(); + } + } + + private void loadItems(Room room, List itemIds, List target) { + if (room == null || itemIds == null || itemIds.isEmpty()) { + return; + } + + for (Integer itemId : itemIds) { + HabboItem item = room.getHabboItem(itemId); + + if (item != null) { + target.add(item); + } + } + } + + private int normalizeTargetSource(int source) { + return (source == WiredSourceUtil.SOURCE_SELECTED) ? SOURCE_SECONDARY_SELECTED : source; + } + + private String serializeIds(List items) { + if (items == null || items.isEmpty()) { + return ""; + } + + return items.stream() + .map(HabboItem::getId) + .distinct() + .map(String::valueOf) + .collect(Collectors.joining(FURNI_DELIMITER)); + } + + static class JsonData { + int delay; + List itemIds; + List targetItemIds; + int moveSource; + int targetSource; + + public JsonData(int delay, List itemIds, List targetItemIds, int moveSource, int targetSource) { + this.delay = delay; + this.itemIds = itemIds; + this.targetItemIds = targetItemIds; + this.moveSource = moveSource; + this.targetSource = targetSource; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectFurniToUser.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectFurniToUser.java new file mode 100644 index 00000000..62df4762 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectFurniToUser.java @@ -0,0 +1,57 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.effects; + +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.rooms.FurnitureMovementError; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.core.WiredContext; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class WiredEffectFurniToUser extends WiredEffectUserFurniBase { + public static final WiredEffectType type = WiredEffectType.FURNI_TO_USER; + + public WiredEffectFurniToUser(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredEffectFurniToUser(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public void execute(WiredContext ctx) { + Room room = ctx.room(); + HabboItem item = this.resolveLastItem(ctx); + Habbo habbo = this.resolveLastHabbo(room, ctx); + + if (room == null || item == null || habbo == null || habbo.getRoomUnit() == null) { + return; + } + + RoomTile targetTile = habbo.getRoomUnit().getCurrentLocation(); + if (targetTile == null) { + return; + } + + FurnitureMovementError error = room.moveFurniTo(item, targetTile, item.getRotation(), null, true, false); + if (error != FurnitureMovementError.NONE && item.getBaseItem().getStateCount() > 0) { + room.moveFurniTo(item, targetTile, item.getRotation(), item.getZ(), null, true, false); + } + } + + @Deprecated + @Override + public boolean execute(com.eu.habbo.habbohotel.rooms.RoomUnit roomUnit, Room room, Object[] stuff) { + return false; + } + + @Override + public WiredEffectType getType() { + return type; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectUnfreeze.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectUnfreeze.java new file mode 100644 index 00000000..40978a4b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectUnfreeze.java @@ -0,0 +1,149 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.effects; + +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.InteractionWiredEffect; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger; +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.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.core.WiredContext; +import com.eu.habbo.habbohotel.wired.core.WiredFreezeUtil; +import com.eu.habbo.habbohotel.wired.core.WiredManager; +import com.eu.habbo.habbohotel.wired.core.WiredSourceUtil; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.wired.WiredSaveException; +import gnu.trove.procedure.TObjectProcedure; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +public class WiredEffectUnfreeze extends InteractionWiredEffect { + public static final WiredEffectType type = WiredEffectType.UNFREEZE; + + private int userSource = WiredSourceUtil.SOURCE_TRIGGER; + + public WiredEffectUnfreeze(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredEffectUnfreeze(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public void execute(WiredContext ctx) { + Room room = ctx.room(); + + for (RoomUnit roomUnit : WiredSourceUtil.resolveUsers(ctx, this.userSource)) { + if (room.getHabbo(roomUnit) == null || !WiredFreezeUtil.isFrozen(roomUnit)) { + continue; + } + + WiredFreezeUtil.unfreeze(room, roomUnit); + } + } + + @Deprecated + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + return false; + } + + @Override + public String getWiredData() { + return WiredManager.getGson().toJson(new JsonData(this.getDelay(), this.userSource)); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + String wiredData = set.getString("wired_data"); + + if (wiredData.startsWith("{")) { + JsonData data = WiredManager.getGson().fromJson(wiredData, JsonData.class); + this.setDelay(data.delay); + this.userSource = data.userSource; + } else { + this.setDelay(0); + this.userSource = WiredSourceUtil.SOURCE_TRIGGER; + } + } + + @Override + public void onPickUp() { + this.setDelay(0); + this.userSource = WiredSourceUtil.SOURCE_TRIGGER; + } + + @Override + public WiredEffectType getType() { + return type; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + message.appendBoolean(false); + message.appendInt(5); + message.appendInt(0); + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(""); + message.appendInt(1); + message.appendInt(this.userSource); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(this.getDelay()); + + if (this.requiresTriggeringUser()) { + List invalidTriggers = new ArrayList<>(); + room.getRoomSpecialTypes().getTriggers(this.getX(), this.getY()).forEach(new TObjectProcedure() { + @Override + public boolean execute(InteractionWiredTrigger object) { + if (!object.isTriggeredByRoomUnit()) { + invalidTriggers.add(object.getBaseItem().getSpriteId()); + } + return true; + } + }); + message.appendInt(invalidTriggers.size()); + for (Integer i : invalidTriggers) { + message.appendInt(i); + } + } else { + message.appendInt(0); + } + } + + @Override + public boolean saveData(WiredSettings settings, GameClient gameClient) throws WiredSaveException { + int[] params = settings.getIntParams(); + this.userSource = (params.length > 0) ? params[0] : WiredSourceUtil.SOURCE_TRIGGER; + + int delay = settings.getDelay(); + if (delay > Emulator.getConfig().getInt("hotel.wired.max_delay", 20)) { + throw new WiredSaveException("Delay too long"); + } + + this.setDelay(delay); + return true; + } + + @Override + public boolean requiresTriggeringUser() { + return this.userSource == WiredSourceUtil.SOURCE_TRIGGER; + } + + static class JsonData { + int delay; + int userSource; + + public JsonData(int delay, int userSource) { + this.delay = delay; + this.userSource = userSource; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectUserFurniBase.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectUserFurniBase.java new file mode 100644 index 00000000..bc86f16d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectUserFurniBase.java @@ -0,0 +1,260 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.effects; + +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.InteractionWiredEffect; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger; +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.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.core.WiredContext; +import com.eu.habbo.habbohotel.wired.core.WiredManager; +import com.eu.habbo.habbohotel.wired.core.WiredSourceUtil; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.wired.WiredSaveException; +import gnu.trove.procedure.TObjectProcedure; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +public abstract class WiredEffectUserFurniBase extends InteractionWiredEffect { + protected final List items = new ArrayList<>(); + protected int furniSource = WiredSourceUtil.SOURCE_TRIGGER; + protected int userSource = WiredSourceUtil.SOURCE_TRIGGER; + + public WiredEffectUserFurniBase(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredEffectUserFurniBase(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + protected HabboItem resolveLastItem(WiredContext ctx) { + Room room = ctx.room(); + List effectiveItems = WiredSourceUtil.resolveItems(ctx, this.furniSource, this.items); + + if (this.furniSource == WiredSourceUtil.SOURCE_SELECTED && room != null) { + this.items.removeIf(item -> item == null + || item.getRoomId() != this.getRoomId() + || room.getHabboItem(item.getId()) == null); + } + + if (effectiveItems.isEmpty()) { + return null; + } + + for (int index = effectiveItems.size() - 1; index >= 0; index--) { + HabboItem item = effectiveItems.get(index); + + if (item != null) { + return item; + } + } + + return null; + } + + protected Habbo resolveLastHabbo(Room room, WiredContext ctx) { + Habbo targetHabbo = null; + + for (RoomUnit unit : WiredSourceUtil.resolveUsers(ctx, this.userSource)) { + Habbo habbo = room.getHabbo(unit); + + if (habbo != null) { + targetHabbo = habbo; + } + } + + return targetHabbo; + } + + protected List resolveHabbos(Room room, WiredContext ctx) { + List habbos = new ArrayList<>(); + + for (RoomUnit unit : WiredSourceUtil.resolveUsers(ctx, this.userSource)) { + Habbo habbo = room.getHabbo(unit); + + if (habbo != null) { + habbos.add(habbo); + } + } + + return habbos; + } + + @Override + public String getWiredData() { + return WiredManager.getGson().toJson(new JsonData( + this.getDelay(), + this.items.stream().map(HabboItem::getId).collect(Collectors.toList()), + this.furniSource, + this.userSource + )); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + this.items.clear(); + String wiredData = set.getString("wired_data"); + + if (wiredData.startsWith("{")) { + JsonData data = WiredManager.getGson().fromJson(wiredData, JsonData.class); + this.setDelay(data.delay); + this.furniSource = data.furniSource; + this.userSource = data.userSource; + + if (data.itemIds != null) { + for (Integer id : data.itemIds) { + HabboItem item = room.getHabboItem(id); + + if (item != null) { + this.items.add(item); + } + } + } + + if (this.furniSource == WiredSourceUtil.SOURCE_TRIGGER && !this.items.isEmpty()) { + this.furniSource = WiredSourceUtil.SOURCE_SELECTED; + } + } else { + String[] wiredDataOld = wiredData.split("\t"); + + if (wiredDataOld.length >= 1) { + this.setDelay(Integer.parseInt(wiredDataOld[0])); + } + + if (wiredDataOld.length == 2 && wiredDataOld[1].contains(";")) { + for (String s : wiredDataOld[1].split(";")) { + HabboItem item = room.getHabboItem(Integer.parseInt(s)); + + if (item != null) { + this.items.add(item); + } + } + } + + this.furniSource = this.items.isEmpty() ? WiredSourceUtil.SOURCE_TRIGGER : WiredSourceUtil.SOURCE_SELECTED; + this.userSource = WiredSourceUtil.SOURCE_TRIGGER; + } + } + + @Override + public void onPickUp() { + this.items.clear(); + this.furniSource = WiredSourceUtil.SOURCE_TRIGGER; + this.userSource = WiredSourceUtil.SOURCE_TRIGGER; + this.setDelay(0); + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + List itemsSnapshot = new ArrayList<>(this.items); + itemsSnapshot.removeIf(item -> item == null + || item.getRoomId() != this.getRoomId() + || room.getHabboItem(item.getId()) == null); + this.items.clear(); + this.items.addAll(itemsSnapshot); + + message.appendBoolean(false); + message.appendInt(WiredManager.MAXIMUM_FURNI_SELECTION); + message.appendInt(itemsSnapshot.size()); + for (HabboItem item : itemsSnapshot) { + message.appendInt(item.getId()); + } + + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(""); + message.appendInt(2); + message.appendInt(this.furniSource); + message.appendInt(this.userSource); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(this.getDelay()); + + if (this.requiresTriggeringUser()) { + List invalidTriggers = new ArrayList<>(); + room.getRoomSpecialTypes().getTriggers(this.getX(), this.getY()).forEach(new TObjectProcedure() { + @Override + public boolean execute(InteractionWiredTrigger object) { + if (!object.isTriggeredByRoomUnit()) { + invalidTriggers.add(object.getId()); + } + return true; + } + }); + message.appendInt(invalidTriggers.size()); + for (Integer i : invalidTriggers) { + message.appendInt(i); + } + } else { + message.appendInt(0); + } + } + + @Override + public boolean saveData(WiredSettings settings, GameClient gameClient) throws WiredSaveException { + this.furniSource = (settings.getIntParams().length > 0) ? settings.getIntParams()[0] : WiredSourceUtil.SOURCE_TRIGGER; + this.userSource = (settings.getIntParams().length > 1) ? settings.getIntParams()[1] : WiredSourceUtil.SOURCE_TRIGGER; + + if (settings.getFurniIds().length > Emulator.getConfig().getInt("hotel.wired.furni.selection.count")) { + throw new WiredSaveException("Too many furni selected"); + } + + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()); + if (room == null) { + throw new WiredSaveException("Room not found"); + } + + List newItems = new ArrayList<>(); + if (this.furniSource == WiredSourceUtil.SOURCE_SELECTED) { + for (int itemId : settings.getFurniIds()) { + HabboItem item = room.getHabboItem(itemId); + + if (item == null) { + throw new WiredSaveException(String.format("Item %s not found", itemId)); + } + + newItems.add(item); + } + } + + int delay = settings.getDelay(); + if (delay > Emulator.getConfig().getInt("hotel.wired.max_delay", 20)) { + throw new WiredSaveException("Delay too long"); + } + + this.items.clear(); + this.items.addAll(newItems); + this.setDelay(delay); + + return true; + } + + @Override + public boolean requiresTriggeringUser() { + return this.userSource == WiredSourceUtil.SOURCE_TRIGGER; + } + + static class JsonData { + int delay; + List itemIds; + int furniSource; + int userSource; + + public JsonData(int delay, List itemIds, int furniSource, int userSource) { + this.delay = delay; + this.itemIds = itemIds; + this.furniSource = furniSource; + this.userSource = userSource; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectUserToFurni.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectUserToFurni.java new file mode 100644 index 00000000..b5d50cc3 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectUserToFurni.java @@ -0,0 +1,48 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.effects; + +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.core.WiredContext; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class WiredEffectUserToFurni extends WiredEffectUserFurniBase { + public static final WiredEffectType type = WiredEffectType.USER_TO_FURNI; + + public WiredEffectUserToFurni(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredEffectUserToFurni(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public void execute(WiredContext ctx) { + Room room = ctx.room(); + HabboItem item = this.resolveLastItem(ctx); + + if (room == null || item == null) { + return; + } + + for (Habbo habbo : this.resolveHabbos(room, ctx)) { + room.teleportHabboToItem(habbo, item); + } + } + + @Deprecated + @Override + public boolean execute(com.eu.habbo.habbohotel.rooms.RoomUnit roomUnit, Room room, Object[] stuff) { + return false; + } + + @Override + public WiredEffectType getType() { + return type; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomUnitManager.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomUnitManager.java index 7a33df06..8f4f0772 100644 --- a/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomUnitManager.java +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomUnitManager.java @@ -12,6 +12,7 @@ import com.eu.habbo.habbohotel.users.DanceType; import com.eu.habbo.habbohotel.users.Habbo; import com.eu.habbo.habbohotel.users.HabboGender; import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.wired.core.WiredFreezeUtil; import com.eu.habbo.habbohotel.wired.core.WiredManager; import com.eu.habbo.habbohotel.wired.WiredUserActionType; import com.eu.habbo.messages.outgoing.generic.alerts.GenericErrorMessagesComposer; @@ -220,6 +221,9 @@ public class RoomUnitManager { if (habbo.getRoomUnit() != null) { WiredManager.triggerUserLeavesRoom(this.room, habbo.getRoomUnit()); + if (WiredFreezeUtil.isFrozen(habbo.getRoomUnit())) { + WiredFreezeUtil.unfreeze(this.room, habbo.getRoomUnit()); + } } if (habbo.getRoomUnit() != null && habbo.getRoomUnit().getCurrentLocation() != null) { @@ -1309,6 +1313,8 @@ public class RoomUnitManager { */ public void teleportRoomUnitToLocation(RoomUnit roomUnit, short x, short y, double z) { if (this.room.isLoaded()) { + WiredFreezeUtil.onTeleport(this.room, roomUnit); + RoomTile tile = this.room.getLayout().getTile(x, y); if (z < tile.z) { @@ -1320,6 +1326,7 @@ public class RoomUnitManager { roomUnit.setZ(z); roomUnit.setPreviousLocationZ(z); this.room.updateRoomUnit(roomUnit); + WiredFreezeUtil.restoreWalkState(roomUnit); } } diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/WiredEffectType.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/WiredEffectType.java index 0d5e74d2..d1f01bcc 100644 --- a/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/WiredEffectType.java +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/WiredEffectType.java @@ -32,7 +32,12 @@ public enum WiredEffectType { FURNI_BYTYPE_SELECTOR(30), USERS_AREA_SELECTOR(31), USERS_NEIGHBORHOOD_SELECTOR(32), - SEND_SIGNAL(33); + SEND_SIGNAL(33), + FREEZE(34), + UNFREEZE(35), + FURNI_TO_USER(36), + USER_TO_FURNI(37), + FURNI_TO_FURNI(38); public final int code; diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/core/WiredFreezeUtil.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/core/WiredFreezeUtil.java new file mode 100644 index 00000000..70b73254 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/core/WiredFreezeUtil.java @@ -0,0 +1,74 @@ +package com.eu.habbo.habbohotel.wired.core; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserStatusComposer; + +public final class WiredFreezeUtil { + private static final String CACHE_ACTIVE = "wired.freeze.active"; + private static final String CACHE_EFFECT_ID = "wired.freeze.effect_id"; + private static final String CACHE_CANCEL_ON_TELEPORT = "wired.freeze.cancel_on_teleport"; + + private WiredFreezeUtil() { + } + + public static boolean isFrozen(RoomUnit roomUnit) { + return roomUnit != null && Boolean.TRUE.equals(roomUnit.getCacheable().get(CACHE_ACTIVE)); + } + + public static void freeze(Room room, RoomUnit roomUnit, int effectId, boolean cancelOnTeleport) { + if (room == null || roomUnit == null || effectId <= 0) { + return; + } + + roomUnit.getCacheable().put(CACHE_ACTIVE, true); + roomUnit.getCacheable().put(CACHE_EFFECT_ID, effectId); + roomUnit.getCacheable().put(CACHE_CANCEL_ON_TELEPORT, cancelOnTeleport); + + roomUnit.stopWalking(); + roomUnit.setCanWalk(false); + roomUnit.statusUpdate(true); + + room.giveEffect(roomUnit, effectId, Integer.MAX_VALUE); + room.sendComposer(new RoomUserStatusComposer(roomUnit).compose()); + } + + public static void unfreeze(Room room, RoomUnit roomUnit) { + if (roomUnit == null) { + return; + } + + roomUnit.getCacheable().remove(CACHE_ACTIVE); + roomUnit.getCacheable().remove(CACHE_EFFECT_ID); + roomUnit.getCacheable().remove(CACHE_CANCEL_ON_TELEPORT); + + roomUnit.stopWalking(); + roomUnit.setCanWalk(true); + roomUnit.statusUpdate(true); + + if (room != null) { + room.giveEffect(roomUnit, 0, -1); + room.sendComposer(new RoomUserStatusComposer(roomUnit).compose()); + } else { + roomUnit.setEffectId(0, 0); + } + } + + public static void onTeleport(Room room, RoomUnit roomUnit) { + if (!isFrozen(roomUnit)) { + return; + } + + if (Boolean.TRUE.equals(roomUnit.getCacheable().get(CACHE_CANCEL_ON_TELEPORT))) { + unfreeze(room, roomUnit); + } + } + + public static void restoreWalkState(RoomUnit roomUnit) { + if (roomUnit == null) { + return; + } + + roomUnit.setCanWalk(!isFrozen(roomUnit)); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserWalkEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserWalkEvent.java index 2b5d5a5e..0e174672 100644 --- a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserWalkEvent.java +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserWalkEvent.java @@ -10,6 +10,7 @@ import com.eu.habbo.habbohotel.rooms.BedProfile; import com.eu.habbo.habbohotel.users.Habbo; import com.eu.habbo.habbohotel.users.HabboInfo; import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.wired.core.WiredFreezeUtil; import com.eu.habbo.messages.incoming.MessageHandler; import com.eu.habbo.messages.outgoing.rooms.users.RoomUnitOnRollerComposer; import com.eu.habbo.plugin.events.users.UserIdleEvent; @@ -46,7 +47,7 @@ public class RoomUserWalkEvent extends MessageHandler { Room room = habboInfo.getCurrentRoom(); try { - if (roomUnit != null && roomUnit.isInRoom() && roomUnit.canWalk()) { + if (roomUnit != null && roomUnit.isInRoom() && roomUnit.canWalk() && !WiredFreezeUtil.isFrozen(roomUnit)) { if (roomUnit.cmdTeleport) { handleTeleport(room, (short) x, (short) y, roomUnit, habboInfo); return; diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/RoomUnitTeleport.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/RoomUnitTeleport.java index 9747026e..43ddeb97 100644 --- a/Emulator/src/main/java/com/eu/habbo/threading/runnables/RoomUnitTeleport.java +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/RoomUnitTeleport.java @@ -5,6 +5,7 @@ import com.eu.habbo.habbohotel.rooms.RoomTile; import com.eu.habbo.habbohotel.rooms.RoomUnit; import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.wired.core.WiredFreezeUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -38,6 +39,8 @@ public class RoomUnitTeleport implements Runnable { return; } + WiredFreezeUtil.onTeleport(this.room, this.roomUnit); + RoomTile lastLocation = this.roomUnit.getCurrentLocation(); RoomTile newLocation = this.room.getLayout().getTile((short) this.x, (short) this.y); @@ -60,6 +63,7 @@ public class RoomUnitTeleport implements Runnable { //this.room.sendComposer(teleportMessage); this.roomUnit.statusUpdate(true); roomUnit.isWiredTeleporting = false; + WiredFreezeUtil.restoreWalkState(this.roomUnit); this.room.updateHabbosAt(newLocation.x, newLocation.y); this.room.updateBotsAt(newLocation.x, newLocation.y); diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionFive.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionFive.java index 9fab330b..ea5d1ee8 100644 --- a/Emulator/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionFive.java +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionFive.java @@ -5,6 +5,7 @@ import com.eu.habbo.habbohotel.gameclients.GameClient; import com.eu.habbo.habbohotel.items.interactions.InteractionTeleportTile; import com.eu.habbo.habbohotel.rooms.*; import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.wired.core.WiredFreezeUtil; import com.eu.habbo.threading.runnables.HabboItemNewState; import com.eu.habbo.threading.runnables.RoomUnitWalkToLocation; @@ -46,6 +47,7 @@ class TeleportActionFive implements Runnable { List onSuccess = new ArrayList(); onSuccess.add(() -> { unit.setCanLeaveRoomByDoor(true); + WiredFreezeUtil.restoreWalkState(unit); Emulator.getThreading().run(() -> { unit.isLeavingTeleporter = false; @@ -57,6 +59,8 @@ class TeleportActionFive implements Runnable { unit.statusUpdate(true); unit.isLeavingTeleporter = true; Emulator.getThreading().run(new RoomUnitWalkToLocation(unit, tile, room, onSuccess, onSuccess)); + } else { + WiredFreezeUtil.restoreWalkState(unit); } this.currentTeleport.setExtradata("1"); diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionFour.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionFour.java index 5fea22ef..7b13dec4 100644 --- a/Emulator/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionFour.java +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionFour.java @@ -4,6 +4,7 @@ import com.eu.habbo.Emulator; import com.eu.habbo.habbohotel.gameclients.GameClient; import com.eu.habbo.habbohotel.rooms.Room; import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.wired.core.WiredFreezeUtil; class TeleportActionFour implements Runnable { private final HabboItem currentTeleport; @@ -21,7 +22,7 @@ class TeleportActionFour implements Runnable { if (this.client.getHabbo().getHabboInfo().getCurrentRoom() != this.room) { this.client.getHabbo().getHabboInfo().setLoadingRoom(0); this.client.getHabbo().getRoomUnit().isTeleporting = false; - this.client.getHabbo().getRoomUnit().setCanWalk(true); + WiredFreezeUtil.restoreWalkState(this.client.getHabbo().getRoomUnit()); this.currentTeleport.setExtradata("0"); this.room.updateItem(this.currentTeleport); return; diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionOne.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionOne.java index 757db39c..8ba24c37 100644 --- a/Emulator/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionOne.java +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionOne.java @@ -7,6 +7,7 @@ import com.eu.habbo.habbohotel.rooms.Room; import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; import com.eu.habbo.habbohotel.rooms.RoomUserRotation; import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.wired.core.WiredFreezeUtil; import com.eu.habbo.messages.outgoing.rooms.users.RoomUserStatusComposer; public class TeleportActionOne implements Runnable { @@ -25,7 +26,7 @@ public class TeleportActionOne implements Runnable { if (this.client.getHabbo().getHabboInfo().getCurrentRoom() != this.room) { this.client.getHabbo().getHabboInfo().setLoadingRoom(0); this.client.getHabbo().getRoomUnit().isTeleporting = false; - this.client.getHabbo().getRoomUnit().setCanWalk(true); + WiredFreezeUtil.restoreWalkState(this.client.getHabbo().getRoomUnit()); return; } diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionThree.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionThree.java index ed3a5d84..efcd9ca7 100644 --- a/Emulator/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionThree.java +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionThree.java @@ -9,6 +9,7 @@ import com.eu.habbo.habbohotel.rooms.RoomTile; import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; import com.eu.habbo.habbohotel.rooms.RoomUserRotation; import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.wired.core.WiredFreezeUtil; class TeleportActionThree implements Runnable { private final HabboItem currentTeleport; @@ -26,7 +27,7 @@ class TeleportActionThree implements Runnable { if (this.client.getHabbo().getHabboInfo().getCurrentRoom() != this.room) { this.client.getHabbo().getHabboInfo().setLoadingRoom(0); this.client.getHabbo().getRoomUnit().isTeleporting = false; - this.client.getHabbo().getRoomUnit().setCanWalk(true); + WiredFreezeUtil.restoreWalkState(this.client.getHabbo().getRoomUnit()); return; } 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 eb5c4bb0..53cdc9c7 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 @@ -7,6 +7,7 @@ import com.eu.habbo.habbohotel.items.interactions.InteractionTeleportTile; import com.eu.habbo.habbohotel.rooms.Room; import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; 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; @@ -41,7 +42,7 @@ class TeleportActionTwo implements Runnable { if (this.client.getHabbo().getHabboInfo().getCurrentRoom() != this.room) { this.client.getHabbo().getHabboInfo().setLoadingRoom(0); this.client.getHabbo().getRoomUnit().isTeleporting = false; - this.client.getHabbo().getRoomUnit().setCanWalk(true); + WiredFreezeUtil.restoreWalkState(this.client.getHabbo().getRoomUnit()); return; }