diff --git a/src/main/java/com/eu/habbo/Emulator.java b/src/main/java/com/eu/habbo/Emulator.java index c825f8d9..0d132f78 100644 --- a/src/main/java/com/eu/habbo/Emulator.java +++ b/src/main/java/com/eu/habbo/Emulator.java @@ -38,8 +38,7 @@ public final class Emulator { public final static int MAJOR = 2; public final static int MINOR = 5; public final static int BUILD = 0; - - public final static String PREVIEW = "RC-1"; + public final static String PREVIEW = "Beta 1"; public static final String version = "Arcturus Morningstar" + " " + MAJOR + "." + MINOR + "." + BUILD + " " + PREVIEW; private static final String logo = @@ -49,8 +48,8 @@ public final class Emulator { "██╔████╔██║██║ ██║██████╔╝██╔██╗ ██║██║██╔██╗ ██║██║ ███╗███████╗ ██║ ███████║██████╔╝\n" + "██║╚██╔╝██║██║ ██║██╔══██╗██║╚██╗██║██║██║╚██╗██║██║ ██║╚════██║ ██║ ██╔══██║██╔══██╗\n" + "██║ ╚═╝ ██║╚██████╔╝██║ ██║██║ ╚████║██║██║ ╚████║╚██████╔╝███████║ ██║ ██║ ██║██║ ██║\n" + - "╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═══╝╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝\n" + - "Emulator goes zoom."; + "╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═══╝╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝\n" ; + public static String build = ""; public static boolean isReady = false; @@ -83,6 +82,13 @@ public final class Emulator { Runtime.getRuntime().addShutdownHook(hook); } + public static void promptEnterKey(){ + System.out.println("\n"); + System.out.println("Press \"ENTER\" if you agree to the terms stated above..."); + Scanner scanner = new Scanner(System.in); + scanner.nextLine(); + } + public static void main(String[] args) throws Exception { try { // Check if running on Windows and not in IntelliJ. @@ -104,6 +110,12 @@ public final class Emulator { System.out.println(logo); + // Checks if this is a BETA build before allowing them to continue. + if (PREVIEW.toLowerCase().contains("beta")) { + System.out.println("Warning, this is a beta build, this means that there may be unintended consequences so make sure you take regular backups while using this build. If you notice any issues you should make an issue on the Krews Git."); + promptEnterKey(); + } + LOGGER.info("This project is for educational purposes only. This Emulator is an open-source fork of Arcturus created by TheGeneral."); LOGGER.info("Version: {}", version); LOGGER.info("Build: {}", build); diff --git a/src/main/java/com/eu/habbo/habbohotel/bots/Bot.java b/src/main/java/com/eu/habbo/habbohotel/bots/Bot.java index 674f5019..8f0b0360 100644 --- a/src/main/java/com/eu/habbo/habbohotel/bots/Bot.java +++ b/src/main/java/com/eu/habbo/habbohotel/bots/Bot.java @@ -178,11 +178,11 @@ public class Bot implements Runnable { int timeOut = Emulator.getRandom().nextInt(20) * 2; this.roomUnit.setWalkTimeOut((timeOut < 10 ? 5 : timeOut) + Emulator.getIntUnixTimestamp()); } - } else { + }/* else { for (RoomTile t : this.room.getLayout().getTilesAround(this.room.getLayout().getTile(this.getRoomUnit().getX(), this.getRoomUnit().getY()))) { WiredHandler.handle(WiredTriggerType.BOT_REACHED_STF, this.roomUnit, this.room, this.room.getItemsAt(t).toArray()); } - } + }*/ } if (!this.chatLines.isEmpty() && this.chatTimeOut <= Emulator.getIntUnixTimestamp() && this.chatAuto) { @@ -193,12 +193,16 @@ public class Bot implements Runnable { this.lastChatIndex = 0; } - this.talk(this.chatLines.get(this.lastChatIndex) + String message = this.chatLines.get(this.lastChatIndex) .replace("%owner%", this.room.getOwnerName()) .replace("%item_count%", this.room.itemCount() + "") .replace("%name%", this.name) .replace("%roomname%", this.room.getName()) - .replace("%user_count%", this.room.getUserCount() + "")); + .replace("%user_count%", this.room.getUserCount() + ""); + + if(!WiredHandler.handle(WiredTriggerType.SAY_SOMETHING, this.getRoomUnit(), room, new Object[]{ message })) { + this.talk(message); + } this.chatTimeOut = Emulator.getIntUnixTimestamp() + this.chatDelay; } @@ -252,7 +256,12 @@ public class Bot implements Runnable { room.giveEffect(this.roomUnit, this.effect, -1); } - this.talk(PLACEMENT_MESSAGES[Emulator.getRandom().nextInt(PLACEMENT_MESSAGES.length)]); + if(PLACEMENT_MESSAGES.length > 0) { + String message = PLACEMENT_MESSAGES[Emulator.getRandom().nextInt(PLACEMENT_MESSAGES.length)]; + if (!WiredHandler.handle(WiredTriggerType.SAY_SOMETHING, this.getRoomUnit(), room, new Object[]{message})) { + this.talk(message); + } + } } public void onPickUp(Habbo habbo, Room room) { diff --git a/src/main/java/com/eu/habbo/habbohotel/bots/ButlerBot.java b/src/main/java/com/eu/habbo/habbohotel/bots/ButlerBot.java index d776bee9..89a66272 100644 --- a/src/main/java/com/eu/habbo/habbohotel/bots/ButlerBot.java +++ b/src/main/java/com/eu/habbo/habbohotel/bots/ButlerBot.java @@ -3,6 +3,8 @@ package com.eu.habbo.habbohotel.bots; import com.eu.habbo.Emulator; import com.eu.habbo.habbohotel.rooms.RoomChatMessage; import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.habbohotel.wired.WiredTriggerType; import com.eu.habbo.plugin.events.bots.BotServerItemEvent; import com.eu.habbo.threading.runnables.RoomUnitGiveHanditem; import com.eu.habbo.threading.runnables.RoomUnitWalkToRoomUnit; @@ -78,7 +80,14 @@ public class ButlerBot extends Bot { tasks.add(new RoomUnitGiveHanditem(serveEvent.habbo.getRoomUnit(), serveEvent.habbo.getHabboInfo().getCurrentRoom(), serveEvent.itemId)); tasks.add(new RoomUnitGiveHanditem(this.getRoomUnit(), serveEvent.habbo.getHabboInfo().getCurrentRoom(), 0)); - tasks.add(() -> b.talk(Emulator.getTexts().getValue("bots.butler.given").replace("%key%", key).replace("%username%", serveEvent.habbo.getHabboInfo().getUsername()))); + tasks.add(() -> { + if(this.getRoom() != null) { + String msg = Emulator.getTexts().getValue("bots.butler.given").replace("%key%", key).replace("%username%", serveEvent.habbo.getHabboInfo().getUsername()); + if (!WiredHandler.handle(WiredTriggerType.SAY_SOMETHING, this.getRoomUnit(), this.getRoom(), new Object[]{msg})) { + b.talk(msg); + } + } + }); List failedReached = new ArrayList(); failedReached.add(() -> { @@ -98,7 +107,13 @@ public class ButlerBot extends Bot { } } else { this.getRoom().giveHandItem(serveEvent.habbo, serveEvent.itemId); - this.talk(Emulator.getTexts().getValue("bots.butler.given").replace("%key%", s).replace("%username%", serveEvent.habbo.getHabboInfo().getUsername())); + + if(this.getRoom() != null) { + String msg = Emulator.getTexts().getValue("bots.butler.given").replace("%key%", s).replace("%username%", serveEvent.habbo.getHabboInfo().getUsername()); + if (!WiredHandler.handle(WiredTriggerType.SAY_SOMETHING, this.getRoomUnit(), this.getRoom(), new Object[]{msg})) { + this.talk(msg); + } + } } return; } diff --git a/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogManager.java b/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogManager.java index 34a24e3d..cac81c5b 100644 --- a/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogManager.java +++ b/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogManager.java @@ -1070,9 +1070,6 @@ public class CatalogManager { } } - UserCatalogItemPurchasedEvent purchasedEvent = new UserCatalogItemPurchasedEvent(habbo, item, itemsList, totalCredits, totalPoints, badges); - Emulator.getPluginManager().fireEvent(purchasedEvent); - if (badgeFound) { habbo.getClient().sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.ALREADY_HAVE_BADGE)); @@ -1081,6 +1078,9 @@ public class CatalogManager { } } + UserCatalogItemPurchasedEvent purchasedEvent = new UserCatalogItemPurchasedEvent(habbo, item, itemsList, totalCredits, totalPoints, badges); + Emulator.getPluginManager().fireEvent(purchasedEvent); + if (!free && !habbo.getClient().getHabbo().hasPermission(Permission.ACC_INFINITE_CREDITS)) { if (purchasedEvent.totalCredits > 0) { habbo.getClient().getHabbo().getHabboInfo().addCredits(-purchasedEvent.totalCredits); diff --git a/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/RoomBundleLayout.java b/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/RoomBundleLayout.java index 680d3e9b..d283ada6 100644 --- a/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/RoomBundleLayout.java +++ b/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/RoomBundleLayout.java @@ -5,6 +5,7 @@ import com.eu.habbo.habbohotel.bots.Bot; import com.eu.habbo.habbohotel.catalog.CatalogItem; import com.eu.habbo.habbohotel.items.Item; import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomManager; import com.eu.habbo.habbohotel.users.Habbo; import com.eu.habbo.habbohotel.users.HabboItem; import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertComposer; @@ -133,7 +134,7 @@ public class RoomBundleLayout extends SingleBundle { if (habbo != null) { int count = Emulator.getGameEnvironment().getRoomManager().getRoomsForHabbo(habbo).size(); - int max = habbo.getHabboStats().hasActiveClub() ? Emulator.getConfig().getInt("hotel.max.rooms.vip") : Emulator.getConfig().getInt("hotel.max.rooms.user"); + int max = habbo.getHabboStats().hasActiveClub() ? RoomManager.MAXIMUM_ROOMS_HC : RoomManager.MAXIMUM_ROOMS_USER; if (count >= max) { habbo.getClient().sendResponse(new CanCreateRoomComposer(count, max)); diff --git a/src/main/java/com/eu/habbo/habbohotel/games/Game.java b/src/main/java/com/eu/habbo/habbohotel/games/Game.java index 16783eb7..24a8051d 100644 --- a/src/main/java/com/eu/habbo/habbohotel/games/Game.java +++ b/src/main/java/com/eu/habbo/habbohotel/games/Game.java @@ -95,7 +95,9 @@ public abstract class Game implements Runnable { if (team != null && team.isMember(habbo)) { if (habbo.getHabboInfo().getGamePlayer() != null) { team.removeMember(habbo.getHabboInfo().getGamePlayer()); - habbo.getHabboInfo().getGamePlayer().reset(); + if (habbo.getHabboInfo().getGamePlayer() != null) { + habbo.getHabboInfo().getGamePlayer().reset(); + } } habbo.getHabboInfo().setCurrentGame(null); @@ -238,7 +240,10 @@ public abstract class Game implements Runnable { if (this.room == null) return; - for (Map.Entry teamEntry : this.teams.entrySet()) { + THashMap teamsCopy = new THashMap<>(); + teamsCopy.putAll(this.teams); + + for (Map.Entry teamEntry : teamsCopy.entrySet()) { Emulator.getThreading().run(new SaveScoreForTeam(teamEntry.getValue(), this)); } } diff --git a/src/main/java/com/eu/habbo/habbohotel/games/GamePlayer.java b/src/main/java/com/eu/habbo/habbohotel/games/GamePlayer.java index 1950c917..bfd82a59 100644 --- a/src/main/java/com/eu/habbo/habbohotel/games/GamePlayer.java +++ b/src/main/java/com/eu/habbo/habbohotel/games/GamePlayer.java @@ -13,6 +13,7 @@ public class GamePlayer { private int score; + private int wiredScore; public GamePlayer(Habbo habbo, GameTeamColors teamColor) { @@ -23,15 +24,23 @@ public class GamePlayer { public void reset() { this.score = 0; + this.wiredScore = 0; } - public synchronized void addScore(int amount) { + addScore(amount, false); + } + + public synchronized void addScore(int amount, boolean isWired) { if (habbo.getHabboInfo().getGamePlayer() != null && this.habbo.getHabboInfo().getCurrentGame() != null && this.habbo.getHabboInfo().getCurrentRoom().getGame(this.habbo.getHabboInfo().getCurrentGame()).getTeamForHabbo(this.habbo) != null) { this.score += amount; if (this.score < 0) this.score = 0; + if(isWired && this.score > 0) { + this.wiredScore += amount; + } + WiredHandler.handle(WiredTriggerType.SCORE_ACHIEVED, this.habbo.getRoomUnit(), this.habbo.getHabboInfo().getCurrentRoom(), new Object[]{this.habbo.getHabboInfo().getCurrentRoom().getGame(this.habbo.getHabboInfo().getCurrentGame()).getTeamForHabbo(this.habbo).getTotalScore(), amount}); } } @@ -49,4 +58,8 @@ public class GamePlayer { public int getScore() { return this.score; } + + public int getScoreAchievementValue() { + return this.score - this.wiredScore; + } } diff --git a/src/main/java/com/eu/habbo/habbohotel/games/battlebanzai/BattleBanzaiGame.java b/src/main/java/com/eu/habbo/habbohotel/games/battlebanzai/BattleBanzaiGame.java index 07b83048..b2ee6dcf 100644 --- a/src/main/java/com/eu/habbo/habbohotel/games/battlebanzai/BattleBanzaiGame.java +++ b/src/main/java/com/eu/habbo/habbohotel/games/battlebanzai/BattleBanzaiGame.java @@ -178,7 +178,7 @@ public class BattleBanzaiGame extends Game { for (GameTeam team : this.teams.values()) { if (!singleTeamGame) { for (GamePlayer player : team.getMembers()) { - if (player.getScore() > 0) { + if (player.getScoreAchievementValue() > 0) { AchievementManager.progressAchievement(player.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("BattleBallPlayer")); } } @@ -192,7 +192,7 @@ public class BattleBanzaiGame extends Game { if (winningTeam != null) { if (!singleTeamGame) { for (GamePlayer player : winningTeam.getMembers()) { - if (player.getScore() > 0) { + if (player.getScoreAchievementValue() > 0) { this.room.sendComposer(new RoomUserActionComposer(player.getHabbo().getRoomUnit(), RoomUserAction.WAVE).compose()); AchievementManager.progressAchievement(player.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("BattleBallWinner")); } diff --git a/src/main/java/com/eu/habbo/habbohotel/games/freeze/FreezeGame.java b/src/main/java/com/eu/habbo/habbohotel/games/freeze/FreezeGame.java index eb625350..642564d1 100644 --- a/src/main/java/com/eu/habbo/habbohotel/games/freeze/FreezeGame.java +++ b/src/main/java/com/eu/habbo/habbohotel/games/freeze/FreezeGame.java @@ -287,9 +287,9 @@ public class FreezeGame extends Game { players.addAll(team.getMembers()); for (GamePlayer p : players) { - if (p.getScore() > 0) { + if (p.getScoreAchievementValue() > 0) { if (team.equals(winningTeam)) { - AchievementManager.progressAchievement(p.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("FreezeWinner"), p.getScore()); + AchievementManager.progressAchievement(p.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("FreezeWinner"), p.getScoreAchievementValue()); this.room.sendComposer(new RoomUserActionComposer(p.getHabbo().getRoomUnit(), RoomUserAction.WAVE).compose()); } diff --git a/src/main/java/com/eu/habbo/habbohotel/items/Item.java b/src/main/java/com/eu/habbo/habbohotel/items/Item.java index 97e1a435..11d19294 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/Item.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/Item.java @@ -38,6 +38,7 @@ public class Item implements ISerialize { private String clothingOnWalk; private ItemInteraction interactionType; + private int rotations; public Item(ResultSet set) throws SQLException { this.load(set); @@ -119,6 +120,13 @@ public class Item implements ISerialize { this.multiHeights = new double[0]; } } + + this.rotations = 4; + + try { + this.rotations = set.getInt("rotations"); + } + catch (SQLException ignored) { } } public int getId() { @@ -223,6 +231,10 @@ public class Item implements ISerialize { public String getClothingOnWalk() { return clothingOnWalk; } + public int getRotations() { + return rotations; + } + @Override public void serialize(ServerMessage message) { message.appendString(this.type.code.toLowerCase()); diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionDefault.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionDefault.java index 1db3a1d2..4860d0ff 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionDefault.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionDefault.java @@ -48,15 +48,17 @@ public class InteractionDefault extends HabboItem { public void onMove(Room room, RoomTile oldLocation, RoomTile newLocation) { super.onMove(room, oldLocation, newLocation); - for (RoomUnit unit : room.getRoomUnits()) { - if (!oldLocation.unitIsOnFurniOnTile(unit, this.getBaseItem())) - continue; // If the unit was previously on the furni... - if (newLocation.unitIsOnFurniOnTile(unit, this.getBaseItem())) continue; // but is not anymore... + if(room.getItemsAt(oldLocation).stream().noneMatch(item -> item.getClass().isAssignableFrom(InteractionRoller.class))) { + for (RoomUnit unit : room.getRoomUnits()) { + if (!oldLocation.unitIsOnFurniOnTile(unit, this.getBaseItem())) + continue; // If the unit was previously on the furni... + if (newLocation.unitIsOnFurniOnTile(unit, this.getBaseItem())) continue; // but is not anymore... - try { - this.onWalkOff(unit, room, new Object[]{}); // the unit walked off! - } catch (Exception ignored) { + try { + this.onWalkOff(unit, room, new Object[]{oldLocation, newLocation}); // the unit walked off! + } catch (Exception ignored) { + } } } } @@ -137,14 +139,22 @@ public class InteractionDefault extends HabboItem { if (roomUnit != null) { if (this.getBaseItem().getEffectF() > 0 || this.getBaseItem().getEffectM() > 0) { + int nextEffectM = 0; + int nextEffectF = 0; + if (objects != null && objects.length == 2) { if (objects[0] instanceof RoomTile && objects[1] instanceof RoomTile) { - RoomTile goalTile = (RoomTile) objects[1]; - HabboItem topItem = room.getTopItemAt(goalTile.x, goalTile.y); + RoomTile goalTile = (RoomTile) objects[0]; + HabboItem topItem = room.getTopItemAt(goalTile.x, goalTile.y, (objects[0] != objects[1]) ? this : null); if (topItem != null && (topItem.getBaseItem().getEffectM() == this.getBaseItem().getEffectM() || topItem.getBaseItem().getEffectF() == this.getBaseItem().getEffectF())) { return; } + + if(topItem != null) { + nextEffectM = topItem.getBaseItem().getEffectM(); + nextEffectF = topItem.getBaseItem().getEffectF(); + } } } @@ -154,12 +164,12 @@ public class InteractionDefault extends HabboItem { if (habbo != null) { if (habbo.getHabboInfo().getGender().equals(HabboGender.M) && this.getBaseItem().getEffectM() > 0) { - room.giveEffect(habbo, 0, -1); + room.giveEffect(habbo, nextEffectM, -1); return; } if (habbo.getHabboInfo().getGender().equals(HabboGender.F) && this.getBaseItem().getEffectF() > 0) { - room.giveEffect(habbo, 0, -1); + room.giveEffect(habbo, nextEffectF, -1); } } } else if (roomUnit.getRoomUnitType().equals(RoomUnitType.BOT)) { @@ -167,12 +177,12 @@ public class InteractionDefault extends HabboItem { if (bot != null) { if (bot.getGender().equals(HabboGender.M) && this.getBaseItem().getEffectM() > 0) { - room.giveEffect(roomUnit, 0, -1); + room.giveEffect(roomUnit, nextEffectM, -1); return; } if (bot.getGender().equals(HabboGender.F) && this.getBaseItem().getEffectF() > 0) { - room.giveEffect(roomUnit, 0, -1); + room.giveEffect(roomUnit, nextEffectF, -1); } } } diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionGuildFurni.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionGuildFurni.java index 667c5f44..b4374f86 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionGuildFurni.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionGuildFurni.java @@ -6,12 +6,18 @@ import com.eu.habbo.habbohotel.items.Item; import com.eu.habbo.habbohotel.rooms.Room; import com.eu.habbo.habbohotel.rooms.RoomUnit; import com.eu.habbo.messages.ServerMessage; +import gnu.trove.set.hash.THashSet; import java.sql.ResultSet; import java.sql.SQLException; public class InteractionGuildFurni extends InteractionDefault { private int guildId; + private static final THashSet ROTATION_8_ITEMS = new THashSet() { + { + this.add("gld_wall_tall"); + } + }; public InteractionGuildFurni(ResultSet set, Item baseItem) throws SQLException { super(set, baseItem); @@ -23,6 +29,14 @@ public class InteractionGuildFurni extends InteractionDefault { this.guildId = 0; } + @Override + public int getMaximumRotations() { + if(ROTATION_8_ITEMS.stream().anyMatch(x -> x.equalsIgnoreCase(this.getBaseItem().getName()))) { + return 8; + } + return this.getBaseItem().getRotations(); + } + @Override public void serializeExtradata(ServerMessage serverMessage) { Guild guild = Emulator.getGameEnvironment().getGuildManager().getGuild(this.guildId); diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionMannequin.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionMannequin.java index 9036b625..f9c304a4 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionMannequin.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionMannequin.java @@ -23,6 +23,11 @@ public class InteractionMannequin extends HabboItem { super(id, userId, item, extradata, limitedStack, limitedSells); } + @Override + public int getMaximumRotations() { + return 8; + } + @Override public void serializeExtradata(ServerMessage serverMessage) { serverMessage.appendInt(1 + (this.isLimited() ? 256 : 0)); diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionMultiHeight.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionMultiHeight.java index 765b6e3b..47cba012 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionMultiHeight.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionMultiHeight.java @@ -15,6 +15,7 @@ import gnu.trove.set.hash.THashSet; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; @@ -68,39 +69,39 @@ public class InteractionMultiHeight extends HabboItem { this.setExtradata("0"); if (this.getBaseItem().getMultiHeights().length > 0) { - this.setExtradata("" + (Integer.valueOf(this.getExtradata()) + 1) % (this.getBaseItem().getMultiHeights().length)); + this.setExtradata("" + (Integer.parseInt(this.getExtradata()) + 1) % (this.getBaseItem().getMultiHeights().length)); this.needsUpdate(true); room.updateTiles(room.getLayout().getTilesAt(room.getLayout().getTile(this.getX(), this.getY()), this.getBaseItem().getWidth(), this.getBaseItem().getLength(), this.getRotation())); room.updateItemState(this); //room.sendComposer(new UpdateStackHeightComposer(this.getX(), this.getY(), this.getBaseItem().getMultiHeights()[Integer.valueOf(this.getExtradata())] * 256.0D).compose()); } + } + } + } - if (this.isWalkable()) { - List unitsOnItem = new ArrayList<>(); - unitsOnItem.addAll(room.getHabbosOnItem(this).stream().map(Habbo::getRoomUnit).filter(Objects::nonNull).collect(Collectors.toList())); - unitsOnItem.addAll(room.getBotsOnItem(this).stream().map(Bot::getRoomUnit).filter(Objects::nonNull).collect(Collectors.toList())); + public void updateUnitsOnItem(Room room) { + THashSet occupiedTiles = room.getLayout().getTilesAt(room.getLayout().getTile(this.getX(), this.getY()), this.getBaseItem().getWidth(), this.getBaseItem().getLength(), this.getRotation()); - THashSet updatedUnits = new THashSet<>(); - for (RoomUnit unit : unitsOnItem) { - if (unit.hasStatus(RoomUnitStatus.MOVE)) - continue; + for(RoomTile tile : occupiedTiles) { + Collection unitsOnItem = room.getRoomUnitsAt(room.getLayout().getTile(tile.x, tile.y)); - if (this.getBaseItem().getMultiHeights().length >= 0) { - if (this.getBaseItem().allowSit()) { - unit.setStatus(RoomUnitStatus.SIT, this.getBaseItem().getMultiHeights()[(this.getExtradata().isEmpty() ? 0 : Integer.valueOf(this.getExtradata()) % (this.getBaseItem().getMultiHeights().length))] * 1.0D + ""); - } else { - unit.setZ(unit.getCurrentLocation().getStackHeight()); - unit.setPreviousLocationZ(unit.getZ()); - } - } + THashSet updatedUnits = new THashSet<>(); + for (RoomUnit unit : unitsOnItem) { + if (unit.hasStatus(RoomUnitStatus.MOVE) && unit.getGoal() != tile) + continue; - updatedUnits.add(unit); - } - - room.sendComposer(new RoomUserStatusComposer(updatedUnits, true).compose()); + if (this.getBaseItem().allowSit() || unit.hasStatus(RoomUnitStatus.SIT)) { + unit.sitUpdate = true; + unit.statusUpdate(true); + } else { + unit.setZ(unit.getCurrentLocation().getStackHeight()); + unit.setPreviousLocationZ(unit.getZ()); + unit.statusUpdate(true); } } } + + //room.sendComposer(new RoomUserStatusComposer(updatedUnits, true).compose()); } @Override diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionObstacle.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionObstacle.java index 5b3cdb75..a63dcad8 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionObstacle.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionObstacle.java @@ -1,33 +1,34 @@ package com.eu.habbo.habbohotel.items.interactions; -import com.eu.habbo.Emulator; -import com.eu.habbo.habbohotel.achievements.AchievementManager; import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.items.ICycleable; import com.eu.habbo.habbohotel.items.Item; import com.eu.habbo.habbohotel.pets.HorsePet; import com.eu.habbo.habbohotel.pets.Pet; -import com.eu.habbo.habbohotel.pets.PetTasks; -import com.eu.habbo.habbohotel.rooms.Room; -import com.eu.habbo.habbohotel.rooms.RoomUnit; -import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; -import com.eu.habbo.habbohotel.rooms.RoomUserRotation; +import com.eu.habbo.habbohotel.rooms.*; import com.eu.habbo.habbohotel.users.Habbo; import com.eu.habbo.habbohotel.users.HabboItem; import com.eu.habbo.messages.ServerMessage; -import com.eu.habbo.threading.runnables.HabboItemNewState; +import gnu.trove.set.hash.THashSet; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.Objects; + +public class InteractionObstacle extends HabboItem implements ICycleable { + + private THashSet middleTiles; -public class InteractionObstacle extends HabboItem { public InteractionObstacle(ResultSet set, Item baseItem) throws SQLException { super(set, baseItem); this.setExtradata("0"); + this.middleTiles = new THashSet<>(); } public InteractionObstacle(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { super(id, userId, item, extradata, limitedStack, limitedSells); this.setExtradata("0"); + this.middleTiles = new THashSet<>(); } @Override @@ -40,20 +41,12 @@ public class InteractionObstacle extends HabboItem { @Override public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { - Pet pet = room.getPet(roomUnit); - - if (pet instanceof HorsePet) { - HorsePet horsePet = (HorsePet) pet; - - return horsePet.getRider() != null; - } - - return false; + return true; } @Override public boolean isWalkable() { - return false; + return true; } @Override @@ -63,36 +56,32 @@ public class InteractionObstacle extends HabboItem { @Override public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { - Habbo habbo = room.getHabbo(roomUnit); + /*Pet pet = room.getPet(roomUnit); - if (habbo != null) { - Pet pet = room.getPet(roomUnit); + if (pet instanceof HorsePet && ((HorsePet) pet).getRider() != null) { + if (pet.getTask() != null && pet.getTask().equals(PetTasks.RIDE)) { + if (pet.getRoomUnit().hasStatus(RoomUnitStatus.JUMP)) { + pet.getRoomUnit().removeStatus(RoomUnitStatus.JUMP); + Emulator.getThreading().run(new HabboItemNewState(this, room, "0"), 2000); + } else { + int state = 0; + for (int i = 0; i < 2; i++) { + state = Emulator.getRandom().nextInt(4) + 1; - if (pet instanceof HorsePet && ((HorsePet) pet).getRider() != null) { - if (pet.getTask() != null && pet.getTask().equals(PetTasks.RIDE)) { - if (pet.getRoomUnit().hasStatus(RoomUnitStatus.JUMP)) { - pet.getRoomUnit().removeStatus(RoomUnitStatus.JUMP); - Emulator.getThreading().run(new HabboItemNewState(this, room, "0"), 2000); - } else { - int state = 0; - for (int i = 0; i < 2; i++) { - state = Emulator.getRandom().nextInt(4) + 1; - - if (state == 4) - break; - } - - this.setExtradata(state + ""); - pet.getRoomUnit().setStatus(RoomUnitStatus.JUMP, "0"); - - AchievementManager.progressAchievement(habbo, Emulator.getGameEnvironment().getAchievementManager().getAchievement("HorseConsecutiveJumpsCount")); - AchievementManager.progressAchievement(habbo, Emulator.getGameEnvironment().getAchievementManager().getAchievement("HorseJumping")); + if (state == 4) + break; } - room.updateItemState(this); + this.setExtradata(state + ""); + pet.getRoomUnit().setStatus(RoomUnitStatus.JUMP, "0"); + + AchievementManager.progressAchievement(habbo, Emulator.getGameEnvironment().getAchievementManager().getAchievement("HorseConsecutiveJumpsCount")); + AchievementManager.progressAchievement(habbo, Emulator.getGameEnvironment().getAchievementManager().getAchievement("HorseJumping")); } + + room.updateItemState(this); } - } + }*/ } @Override @@ -138,4 +127,70 @@ public class InteractionObstacle extends HabboItem { } } } + + @Override + public void onPlace(Room room) { + super.onPlace(room); + this.calculateMiddleTiles(room); + } + + @Override + public void onPickUp(Room room) { + super.onPickUp(room); + middleTiles.clear(); + } + + @Override + public void onMove(Room room, RoomTile oldLocation, RoomTile newLocation) { + super.onMove(room, oldLocation, newLocation); + this.calculateMiddleTiles(room); + } + + private void calculateMiddleTiles(Room room) { + middleTiles.clear(); + + if(this.getRotation() == 2) { + middleTiles.add(room.getLayout().getTile((short)(this.getX() + 1), this.getY())); + middleTiles.add(room.getLayout().getTile((short)(this.getX() + 1), (short)(this.getY() + 1))); + } + else if(this.getRotation() == 4) { + middleTiles.add(room.getLayout().getTile(this.getX(), (short)(this.getY() + 1))); + middleTiles.add(room.getLayout().getTile((short)(this.getX() + 1), (short)(this.getY() + 1))); + } + } + + @Override + public RoomTileState getOverrideTileState(RoomTile tile, Room room) { + if(this.middleTiles.contains(tile)) + return RoomTileState.BLOCKED; + + return null; + } + + @Override + public void cycle(Room room) { + if(this.middleTiles.size() == 0) { + this.calculateMiddleTiles(room); + } + + for(RoomTile tile : this.middleTiles) { + for(RoomUnit unit : tile.getUnits()) { + if(unit.getPath().size() == 0 && !unit.hasStatus(RoomUnitStatus.MOVE)) { + if(unit.getBodyRotation().getValue() != this.getRotation() && Objects.requireNonNull(unit.getBodyRotation().getOpposite()).getValue() != this.getRotation()) + continue; + + RoomTile tileInfront = room.getLayout().getTileInFront(unit.getCurrentLocation(), unit.getBodyRotation().getValue()); + if(tileInfront.state != RoomTileState.INVALID && tileInfront.state != RoomTileState.BLOCKED && room.getRoomUnitsAt(tileInfront).size() == 0) { + unit.setGoalLocation(tileInfront); + } + else { + RoomTile tileBehind = room.getLayout().getTileInFront(unit.getCurrentLocation(), Objects.requireNonNull(unit.getBodyRotation().getOpposite()).getValue()); + if(tileBehind.state != RoomTileState.INVALID && tileBehind.state != RoomTileState.BLOCKED && room.getRoomUnitsAt(tileBehind).size() == 0) { + unit.setGoalLocation(tileBehind); + } + } + } + } + } + } } diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionPressurePlate.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionPressurePlate.java index 0eee202b..06d19289 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionPressurePlate.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionPressurePlate.java @@ -8,12 +8,13 @@ import com.eu.habbo.habbohotel.rooms.RoomTile; import com.eu.habbo.habbohotel.rooms.RoomUnit; import com.eu.habbo.habbohotel.users.HabboItem; import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.rooms.items.ItemStateComposer; import gnu.trove.set.hash.THashSet; import java.sql.ResultSet; import java.sql.SQLException; -public class InteractionPressurePlate extends HabboItem { +public class InteractionPressurePlate extends InteractionDefault { public InteractionPressurePlate(ResultSet set, Item baseItem) throws SQLException { super(set, baseItem); this.setExtradata("0"); @@ -39,14 +40,6 @@ public class InteractionPressurePlate extends HabboItem { super.onClick(client, room, objects); } - @Override - public void serializeExtradata(ServerMessage serverMessage) { - serverMessage.appendInt((this.isLimited() ? 256 : 0)); - serverMessage.appendString(this.getExtradata()); - - super.serializeExtradata(serverMessage); - } - @Override public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { @@ -99,7 +92,7 @@ public class InteractionPressurePlate extends HabboItem { } this.setExtradata(occupied ? "1" : "0"); - room.updateItem(this); + room.updateItemState(this); } @Override diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionTeleport.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionTeleport.java index 69d7fe3a..42813714 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionTeleport.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionTeleport.java @@ -93,7 +93,7 @@ public class InteractionTeleport extends HabboItem { // set state 1 and walk on item this.roomUnitID = unit.getId(); this.setExtradata("1"); - room.updateItem(this); + room.updateItemState(this); unit.setGoalLocation(infrontTile); List onSuccess = new ArrayList(); @@ -111,7 +111,7 @@ public class InteractionTeleport extends HabboItem { walkable = this.getBaseItem().allowWalk(); room.updateTile(currentLocation); this.setExtradata("0"); - room.updateItem(this); + room.updateItemState(this); this.roomUnitID = -1; unit.removeOverrideTile(currentLocation); unit.setCanLeaveRoomByDoor(true); diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionTrophy.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionTrophy.java index 791109a4..80f2c39c 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionTrophy.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionTrophy.java @@ -13,4 +13,9 @@ public class InteractionTrophy extends InteractionDefault { public InteractionTrophy(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { super(id, userId, item, extradata, limitedStack, limitedSells); } + + @Override + public boolean allowWiredResetState() { + return false; + } } diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionVendingMachine.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionVendingMachine.java index ca0175a2..63a32a1a 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionVendingMachine.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionVendingMachine.java @@ -7,6 +7,8 @@ import com.eu.habbo.habbohotel.rooms.*; 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.WiredHandler; +import com.eu.habbo.habbohotel.wired.WiredTriggerType; import com.eu.habbo.messages.ServerMessage; import com.eu.habbo.messages.outgoing.rooms.items.FloorItemUpdateComposer; import com.eu.habbo.messages.outgoing.rooms.users.RoomUserStatusComposer; @@ -75,6 +77,12 @@ public class InteractionVendingMachine extends HabboItem { this.setExtradata("1"); room.updateItem(this); + try { + super.onClick(client, room, new Object[]{"TOGGLE_OVERRIDE"}); + } catch (Exception e) { + e.printStackTrace(); + } + if(!unit.isWalking() && !unit.hasStatus(RoomUnitStatus.SIT) && !unit.hasStatus(RoomUnitStatus.LAY)) { this.rotateToMachine(room, unit); } @@ -98,8 +106,6 @@ public class InteractionVendingMachine extends HabboItem { @Override public void onClick(GameClient client, Room room, Object[] objects) throws Exception { - super.onClick(client, room, objects); - if (client == null) { return; } @@ -122,7 +128,7 @@ public class InteractionVendingMachine extends HabboItem { if(!inActivatorSpace) { RoomTile tileToWalkTo = null; for(RoomTile tile : activatorTiles) { - if(room.getLayout().tileWalkable(tile.x, tile.y) && (tileToWalkTo == null || tileToWalkTo.distance(unit.getCurrentLocation()) > tile.distance(unit.getCurrentLocation()))) { + if((tile.state == RoomTileState.OPEN || tile.state == RoomTileState.SIT) && (tileToWalkTo == null || tileToWalkTo.distance(unit.getCurrentLocation()) > tile.distance(unit.getCurrentLocation()))) { tileToWalkTo = tile; } } diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWaterItem.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWaterItem.java index 0332c717..4b283da1 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWaterItem.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWaterItem.java @@ -1,6 +1,7 @@ package com.eu.habbo.habbohotel.items.interactions; import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; import com.eu.habbo.habbohotel.items.Item; import com.eu.habbo.habbohotel.rooms.Room; import com.eu.habbo.habbohotel.rooms.RoomLayout; @@ -13,7 +14,7 @@ import java.awt.*; import java.sql.ResultSet; import java.sql.SQLException; -public class InteractionWaterItem extends InteractionDefault { +public class InteractionWaterItem extends InteractionMultiHeight { public InteractionWaterItem(ResultSet set, Item baseItem) throws SQLException { super(set, baseItem); } @@ -30,15 +31,22 @@ public class InteractionWaterItem extends InteractionDefault { @Override public void onPickUp(Room room) { + super.onPickUp(room); this.setExtradata("0"); this.needsUpdate(true); } @Override public void onMove(Room room, RoomTile oldLocation, RoomTile newLocation) { + super.onMove(room, oldLocation, newLocation); this.update(); } + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + super.onClick(client, room, new Object[] { }); + } + public void update() { Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()); @@ -75,7 +83,7 @@ public class InteractionWaterItem extends InteractionDefault { if (!this.getExtradata().equals(updatedData)) { this.setExtradata(updatedData); this.needsUpdate(true); - room.updateItem(this); + room.updateItemState(this); } } @@ -83,9 +91,4 @@ public class InteractionWaterItem extends InteractionDefault { public boolean allowWiredResetState() { return false; } - - @Override - public boolean canToggle(Habbo habbo, Room room) { - return false; - } } diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWired.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWired.java index a465367c..c19b1ec9 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWired.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWired.java @@ -15,7 +15,7 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; -public abstract class InteractionWired extends HabboItem { +public abstract class InteractionWired extends InteractionDefault { private static final Logger LOGGER = LoggerFactory.getLogger(InteractionWired.class); private long cooldown; @@ -37,25 +37,6 @@ public abstract class InteractionWired extends HabboItem { public abstract void loadWiredData(ResultSet set, Room room) throws SQLException; - @Override - public void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { - super.onWalkOn(roomUnit, room, objects); - } - - @Override - public void onWalkOff(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { - super.onWalkOff(roomUnit, room, objects); - } - - - @Override - public void serializeExtradata(ServerMessage serverMessage) { - serverMessage.appendInt((this.isLimited() ? 256 : 0)); - serverMessage.appendString(this.getExtradata()); - - super.serializeExtradata(serverMessage); - } - @Override public void run() { if (this.needsUpdate()) { diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWiredCondition.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWiredCondition.java index d8c7ed41..7bf21fe1 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWiredCondition.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWiredCondition.java @@ -41,21 +41,6 @@ public abstract class InteractionWiredCondition extends InteractionWired { } } - @Override - public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { - - } - - @Override - public void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { - - } - - @Override - public void onWalkOff(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { - - } - public abstract WiredConditionType getType(); public abstract boolean saveData(ClientMessage packet); diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWiredEffect.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWiredEffect.java index a6ae8ab4..59da2b6f 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWiredEffect.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWiredEffect.java @@ -6,6 +6,7 @@ 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.messages.ClientMessage; +import com.eu.habbo.messages.incoming.wired.WiredSaveException; import com.eu.habbo.messages.outgoing.wired.WiredEffectDataComposer; import java.sql.ResultSet; @@ -42,22 +43,7 @@ public abstract class InteractionWiredEffect extends InteractionWired { } } - @Override - public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { - - } - - @Override - public void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { - - } - - @Override - public void onWalkOff(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { - - } - - public abstract boolean saveData(ClientMessage packet, GameClient gameClient); + public abstract boolean saveData(ClientMessage packet, GameClient gameClient) throws WiredSaveException; public int getDelay() { return this.delay; diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWiredHighscore.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWiredHighscore.java index 9708c565..8fb95dd4 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWiredHighscore.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWiredHighscore.java @@ -6,6 +6,9 @@ import com.eu.habbo.habbohotel.items.Item; 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.WiredEffectType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.habbohotel.wired.WiredTriggerType; import com.eu.habbo.habbohotel.wired.highscores.WiredHighscoreClearType; import com.eu.habbo.habbohotel.wired.highscores.WiredHighscoreRow; import com.eu.habbo.habbohotel.wired.highscores.WiredHighscoreScoreType; @@ -78,6 +81,9 @@ public class InteractionWiredHighscore extends HabboItem { @Override public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + if (!((client != null && room != null && room.hasRights(client.getHabbo())) || (objects.length >= 2 && objects[1] instanceof WiredEffectType))) + return; + if (this.getExtradata() == null || this.getExtradata().isEmpty() || this.getExtradata().length() == 0) { this.setExtradata("0"); } @@ -89,6 +95,10 @@ public class InteractionWiredHighscore extends HabboItem { } catch (Exception e) { LOGGER.error("Caught exception", e); } + + if(client != null && !(objects.length >= 2 && objects[1] instanceof WiredEffectType)) { + WiredHandler.handle(WiredTriggerType.STATE_CHANGED, client.getHabbo().getRoomUnit(), room, new Object[]{this}); + } } diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWiredTrigger.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWiredTrigger.java index 30ed0565..c0bbaabb 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWiredTrigger.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWiredTrigger.java @@ -42,21 +42,6 @@ public abstract class InteractionWiredTrigger extends InteractionWired { } } - @Override - public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { - - } - - @Override - public void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { - - } - - @Override - public void onWalkOff(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { - - } - public abstract WiredTriggerType getType(); public abstract boolean saveData(ClientMessage packet); diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/InteractionGameTimer.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/InteractionGameTimer.java index 6197b017..1f7396e9 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/InteractionGameTimer.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/InteractionGameTimer.java @@ -4,6 +4,7 @@ import com.eu.habbo.Emulator; import com.eu.habbo.habbohotel.gameclients.GameClient; import com.eu.habbo.habbohotel.games.Game; import com.eu.habbo.habbohotel.games.GameState; +import com.eu.habbo.habbohotel.games.wired.WiredGame; import com.eu.habbo.habbohotel.items.Item; import com.eu.habbo.habbohotel.permissions.Permission; import com.eu.habbo.habbohotel.rooms.Room; @@ -98,11 +99,15 @@ public class InteractionGameTimer extends HabboItem implements Runnable { } public void endGame(Room room) { + endGame(room, false); + } + + public void endGame(Room room, boolean isStart) { this.isRunning = false; this.isPaused = false; for (Game game : room.getGames()) { - if (!game.getState().equals(GameState.IDLE)) { + if (!game.getState().equals(GameState.IDLE) && !(isStart && game instanceof WiredGame)) { game.onEnd(); game.stop(); } @@ -226,7 +231,7 @@ public class InteractionGameTimer extends HabboItem implements Runnable { return; boolean wasPaused = this.isPaused; - this.endGame(room); + this.endGame(room, true); if(wasPaused) { WiredHandler.handle(WiredTriggerType.GAME_ENDS, null, room, new Object[]{}); diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/InteractionBattleBanzaiTeleporter.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/InteractionBattleBanzaiTeleporter.java index 067f1056..98a627fe 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/InteractionBattleBanzaiTeleporter.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/InteractionBattleBanzaiTeleporter.java @@ -55,18 +55,18 @@ public class InteractionBattleBanzaiTeleporter extends HabboItem { @Override public void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { super.onWalkOn(roomUnit, room, objects); - HabboItem target = room.getRoomSpecialTypes().getRandomTeleporter(this.getBaseItem(), this); - if (target == null) return; + if(objects.length < 3) { + HabboItem target = room.getRoomSpecialTypes().getRandomTeleporter(null, this); + if (target == null) return; - this.setExtradata("1"); - roomUnit.removeStatus(RoomUnitStatus.MOVE); - target.setExtradata("1"); - room.updateItem(this); - room.updateItem(target); - roomUnit.setGoalLocation(room.getLayout().getTile(roomUnit.getX(), roomUnit.getY())); - roomUnit.setCanWalk(false); - Emulator.getThreading().run(new BanzaiRandomTeleport(this, target, roomUnit, room), 1000); + this.setExtradata("1"); + room.updateItemState(this); + roomUnit.removeStatus(RoomUnitStatus.MOVE); + roomUnit.setGoalLocation(roomUnit.getCurrentLocation()); + roomUnit.setCanWalk(false); + Emulator.getThreading().run(new BanzaiRandomTeleport(this, target, roomUnit, room), 500); + } } @Override diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/InteractionFootball.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/InteractionFootball.java index 9c81282d..f64b0ade 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/InteractionFootball.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/InteractionFootball.java @@ -7,10 +7,7 @@ import com.eu.habbo.habbohotel.items.Item; import com.eu.habbo.habbohotel.items.interactions.InteractionPushable; import com.eu.habbo.habbohotel.items.interactions.games.InteractionGameTeamItem; import com.eu.habbo.habbohotel.items.interactions.games.football.goals.InteractionFootballGoal; -import com.eu.habbo.habbohotel.rooms.Room; -import com.eu.habbo.habbohotel.rooms.RoomTile; -import com.eu.habbo.habbohotel.rooms.RoomUnit; -import com.eu.habbo.habbohotel.rooms.RoomUserRotation; +import com.eu.habbo.habbohotel.rooms.*; import com.eu.habbo.habbohotel.users.HabboItem; import com.eu.habbo.messages.outgoing.rooms.items.ItemStateComposer; import com.eu.habbo.util.pathfinding.Rotation; @@ -32,7 +29,7 @@ public class InteractionFootball extends InteractionPushable { @Override public int getWalkOnVelocity(RoomUnit roomUnit, Room room) { - if (roomUnit.getPath().isEmpty() && roomUnit.tilesWalked() == 2) + if (roomUnit.getPath().isEmpty() && roomUnit.tilesWalked() == 2 && this.getExtradata().equals("1")) return 0; if (roomUnit.getPath().size() == 0 && roomUnit.tilesWalked() == 1) @@ -43,7 +40,7 @@ public class InteractionFootball extends InteractionPushable { @Override public int getWalkOffVelocity(RoomUnit roomUnit, Room room) { - if (roomUnit.getPath().size() == 0) + if (roomUnit.getPath().size() == 0 && roomUnit.tilesWalked() == 0) return 6; return 1; @@ -152,9 +149,9 @@ public class InteractionFootball extends InteractionPushable { @Override public boolean validMove(Room room, RoomTile from, RoomTile to) { - if (to == null) return false; + if (to == null || to.state == RoomTileState.INVALID) return false; HabboItem topItem = room.getTopItemAt(to.x, to.y, this); - return !(!room.getLayout().tileWalkable(to.x, to.y) || (topItem != null && (!topItem.getBaseItem().allowStack() || topItem.getBaseItem().allowSit() || topItem.getBaseItem().allowLay()))); + return (topItem == null || topItem.getBaseItem().allowStack()); } //Events diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/goals/InteractionFootballGoal.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/goals/InteractionFootballGoal.java index 7386b365..a3ef5202 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/goals/InteractionFootballGoal.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/goals/InteractionFootballGoal.java @@ -26,7 +26,7 @@ public class InteractionFootballGoal extends InteractionGameTeamItem { @Override public boolean isWalkable() { - return true; + return this.getBaseItem().allowWalk(); } @Override diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionFurniHaveFurni.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionFurniHaveFurni.java index 4aa50beb..d83921c4 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionFurniHaveFurni.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionFurniHaveFurni.java @@ -4,6 +4,7 @@ import com.eu.habbo.Emulator; import com.eu.habbo.habbohotel.items.Item; import com.eu.habbo.habbohotel.items.interactions.InteractionWiredCondition; import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; import com.eu.habbo.habbohotel.rooms.RoomUnit; import com.eu.habbo.habbohotel.users.HabboItem; import com.eu.habbo.habbohotel.wired.WiredConditionType; @@ -35,39 +36,23 @@ public class WiredConditionFurniHaveFurni extends InteractionWiredCondition { public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { this.refresh(); - boolean foundSomething = false; - for (HabboItem item : this.items) { - boolean found = false; + if(this.items.isEmpty()) + return true; - THashSet stackedItems = room.getItemsAt(room.getLayout().getTile(item.getX(), item.getY())); - - if (stackedItems == null) - continue; - - if (stackedItems.isEmpty() && this.all) - return false; - - for (HabboItem i : stackedItems) { - if (i == item) - continue; - - if (i.getZ() >= item.getZ()) { - found = true; - foundSomething = true; - } - } - - if (this.all) { - if (!found) - return false; - } else { - if (found) - return true; - } + if(this.all) { + return this.items.stream().allMatch(item -> { + double minZ = item.getZ() + Item.getCurrentHeight(item); + THashSet occupiedTiles = room.getLayout().getTilesAt(room.getLayout().getTile(item.getX(), item.getY()), item.getBaseItem().getWidth(), item.getBaseItem().getLength(), item.getRotation()); + return occupiedTiles.stream().anyMatch(tile -> room.getItemsAt(tile).stream().anyMatch(matchedItem -> matchedItem != item && matchedItem.getZ() >= minZ)); + }); + } + else { + return this.items.stream().anyMatch(item -> { + double minZ = item.getZ() + Item.getCurrentHeight(item); + THashSet occupiedTiles = room.getLayout().getTilesAt(room.getLayout().getTile(item.getX(), item.getY()), item.getBaseItem().getWidth(), item.getBaseItem().getLength(), item.getRotation()); + return occupiedTiles.stream().anyMatch(tile -> room.getItemsAt(tile).stream().anyMatch(matchedItem -> matchedItem != item && matchedItem.getZ() >= minZ)); + }); } - - return this.items.isEmpty() || foundSomething; - } @Override diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionFurniHaveHabbo.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionFurniHaveHabbo.java index 4895462e..3f9033f3 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionFurniHaveHabbo.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionFurniHaveHabbo.java @@ -51,43 +51,16 @@ public class WiredConditionFurniHaveHabbo extends InteractionWiredCondition { if (this.items.isEmpty()) return true; - THashMap> tiles = new THashMap<>(); - for (HabboItem item : this.items) { - tiles.put(item, room.getLayout().getTilesAt(room.getLayout().getTile(item.getX(), item.getY()), item.getBaseItem().getWidth(), item.getBaseItem().getLength(), item.getRotation())); - } - Collection habbos = room.getHabbos(); Collection bots = room.getCurrentBots().valueCollection(); Collection pets = room.getCurrentPets().valueCollection(); - for (Map.Entry> set : tiles.entrySet()) { - boolean found = false; - for (Habbo habbo : habbos) { - if (set.getValue().contains(habbo.getRoomUnit().getCurrentLocation())) { - found = true; - } - } - - if (!found) { - for (Bot bot : bots) { - if (set.getValue().contains(bot.getRoomUnit().getCurrentLocation())) { - found = true; - } - } - } - - if (!found) { - for (Pet pet : pets) { - if (set.getValue().contains(pet.getRoomUnit().getCurrentLocation())) { - found = true; - } - } - } - - if (!found) return false; - } - - return true; + return this.items.stream().allMatch(item -> { + THashSet occupiedTiles = room.getLayout().getTilesAt(room.getLayout().getTile(item.getX(), item.getY()), item.getBaseItem().getWidth(), item.getBaseItem().getLength(), item.getRotation()); + return habbos.stream().anyMatch(character -> occupiedTiles.contains(character.getRoomUnit().getCurrentLocation())) || + bots.stream().anyMatch(character -> occupiedTiles.contains(character.getRoomUnit().getCurrentLocation())) || + pets.stream().anyMatch(character -> occupiedTiles.contains(character.getRoomUnit().getCurrentLocation())); + }); } @Override diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionFurniTypeMatch.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionFurniTypeMatch.java index d2a2f573..798054d0 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionFurniTypeMatch.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionFurniTypeMatch.java @@ -37,21 +37,19 @@ public class WiredConditionFurniTypeMatch extends InteractionWiredCondition { public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { this.refresh(); + if(items.isEmpty()) + return false; + if (stuff != null) { if (stuff.length >= 1) { if (stuff[0] instanceof HabboItem) { - HabboItem item = (HabboItem) stuff[0]; - - for (HabboItem i : this.items) { - if (i.getBaseItem().getId() == item.getBaseItem().getId()) - return true; - } - - return false; + HabboItem triggeringItem = (HabboItem)stuff[0]; + return this.items.stream().anyMatch(item -> item == triggeringItem); } } } - return true; + + return false; } @Override diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionMatchStatePosition.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionMatchStatePosition.java index 27f1ed0e..27c82d91 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionMatchStatePosition.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionMatchStatePosition.java @@ -49,7 +49,7 @@ public class WiredConditionMatchStatePosition extends InteractionWiredCondition message.appendInt(this.settings.size()); for (WiredMatchFurniSetting item : this.settings) - message.appendInt(item.itemId); + message.appendInt(item.item_id); message.appendInt(this.getBaseItem().getSpriteId()); message.appendInt(this.getId()); @@ -105,7 +105,7 @@ public class WiredConditionMatchStatePosition extends InteractionWiredCondition THashSet s = new THashSet<>(); for (WiredMatchFurniSetting setting : this.settings) { - HabboItem item = room.getHabboItem(setting.itemId); + HabboItem item = room.getHabboItem(setting.item_id); if (item != null) { if (this.state) { @@ -187,7 +187,7 @@ public class WiredConditionMatchStatePosition extends InteractionWiredCondition THashSet remove = new THashSet<>(); for (WiredMatchFurniSetting setting : this.settings) { - HabboItem item = room.getHabboItem(setting.itemId); + HabboItem item = room.getHabboItem(setting.item_id); if (item == null) { remove.add(setting); } diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotFurniHaveFurni.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotFurniHaveFurni.java index 7e666b33..71fbc0b6 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotFurniHaveFurni.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotFurniHaveFurni.java @@ -4,6 +4,7 @@ import com.eu.habbo.Emulator; import com.eu.habbo.habbohotel.items.Item; import com.eu.habbo.habbohotel.items.interactions.InteractionWiredCondition; import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; import com.eu.habbo.habbohotel.rooms.RoomUnit; import com.eu.habbo.habbohotel.users.HabboItem; import com.eu.habbo.habbohotel.wired.WiredConditionOperator; @@ -39,19 +40,20 @@ public class WiredConditionNotFurniHaveFurni extends InteractionWiredCondition { if (this.items.isEmpty()) return true; - for (HabboItem item : this.items) { - THashSet things = room.getItemsAt(item.getX(), item.getY(), item.getZ() + Item.getCurrentHeight(item)); - things.removeAll(this.items); - if (!things.isEmpty()) { - if (this.all) - return false; - else - continue; - } - return true; + if(this.all) { + return this.items.stream().allMatch(item -> { + double minZ = item.getZ() + Item.getCurrentHeight(item); + THashSet occupiedTiles = room.getLayout().getTilesAt(room.getLayout().getTile(item.getX(), item.getY()), item.getBaseItem().getWidth(), item.getBaseItem().getLength(), item.getRotation()); + return occupiedTiles.stream().noneMatch(tile -> room.getItemsAt(tile).stream().anyMatch(matchedItem -> matchedItem != item && matchedItem.getZ() >= minZ)); + }); + } + else { + return this.items.stream().anyMatch(item -> { + double minZ = item.getZ() + Item.getCurrentHeight(item); + THashSet occupiedTiles = room.getLayout().getTilesAt(room.getLayout().getTile(item.getX(), item.getY()), item.getBaseItem().getWidth(), item.getBaseItem().getLength(), item.getRotation()); + return occupiedTiles.stream().noneMatch(tile -> room.getItemsAt(tile).stream().anyMatch(matchedItem -> matchedItem != item && matchedItem.getZ() >= minZ)); + }); } - - return false; } @Override @@ -79,7 +81,7 @@ public class WiredConditionNotFurniHaveFurni extends InteractionWiredCondition { String[] items = data[1].split(";"); for (String s : items) { - HabboItem item = room.getHabboItem(Integer.valueOf(s)); + HabboItem item = room.getHabboItem(Integer.parseInt(s)); if (item != null) this.items.add(item); @@ -169,6 +171,8 @@ public class WiredConditionNotFurniHaveFurni extends InteractionWiredCondition { @Override public WiredConditionOperator operator() { - return this.all ? WiredConditionOperator.AND : WiredConditionOperator.OR; + // NICE TRY BUT THAT'S NOT HOW IT WORKS. NOTHING IN HABBO IS AN "OR" CONDITION - EVERY CONDITION MUST BE SUCCESS FOR THE STACK TO EXECUTE, BUT LET'S LEAVE IT IMPLEMENTED FOR PLUGINS TO USE. + //return this.all ? WiredConditionOperator.AND : WiredConditionOperator.OR; + return WiredConditionOperator.AND; } } diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotFurniHaveHabbo.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotFurniHaveHabbo.java index abc5c559..b85217aa 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotFurniHaveHabbo.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotFurniHaveHabbo.java @@ -51,43 +51,16 @@ public class WiredConditionNotFurniHaveHabbo extends InteractionWiredCondition { if (this.items.isEmpty()) return true; - THashMap> tiles = new THashMap<>(); - for (HabboItem item : this.items) { - tiles.put(item, room.getLayout().getTilesAt(room.getLayout().getTile(item.getX(), item.getY()), item.getBaseItem().getWidth(), item.getBaseItem().getLength(), item.getRotation())); - } - Collection habbos = room.getHabbos(); Collection bots = room.getCurrentBots().valueCollection(); Collection pets = room.getCurrentPets().valueCollection(); - for (Map.Entry> set : tiles.entrySet()) { - if (!habbos.isEmpty()) { - for (Habbo habbo : habbos) { - if (set.getValue().contains(habbo.getRoomUnit().getCurrentLocation())) { - return false; - } - } - } - - if (!bots.isEmpty()) { - for (Bot bot : bots) { - if (set.getValue().contains(bot.getRoomUnit().getCurrentLocation())) { - return false; - } - } - } - - if (!pets.isEmpty()) { - for (Pet pet : pets) { - if (set.getValue().contains(pet.getRoomUnit().getCurrentLocation())) { - return false; - } - } - } - - } - - return true; + return this.items.stream().noneMatch(item -> { + THashSet occupiedTiles = room.getLayout().getTilesAt(room.getLayout().getTile(item.getX(), item.getY()), item.getBaseItem().getWidth(), item.getBaseItem().getLength(), item.getRotation()); + return habbos.stream().anyMatch(character -> occupiedTiles.contains(character.getRoomUnit().getCurrentLocation())) || + bots.stream().anyMatch(character -> occupiedTiles.contains(character.getRoomUnit().getCurrentLocation())) || + pets.stream().anyMatch(character -> occupiedTiles.contains(character.getRoomUnit().getCurrentLocation())); + }); } @Override diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotFurniTypeMatch.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotFurniTypeMatch.java index 754aed77..d9b6d466 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotFurniTypeMatch.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotFurniTypeMatch.java @@ -32,15 +32,14 @@ public class WiredConditionNotFurniTypeMatch extends InteractionWiredCondition { public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { this.refresh(); + if(items.isEmpty()) + return true; + if (stuff != null) { if (stuff.length >= 1) { if (stuff[0] instanceof HabboItem) { - HabboItem item = (HabboItem) stuff[0]; - - for (HabboItem i : this.items) { - if (i.getBaseItem().getId() == item.getBaseItem().getId()) - return false; - } + HabboItem triggeringItem = (HabboItem)stuff[0]; + return this.items.stream().noneMatch(item -> item == triggeringItem); } } } diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotInTeam.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotInTeam.java index fba63af0..704921fc 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotInTeam.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotInTeam.java @@ -31,13 +31,10 @@ public class WiredConditionNotInTeam extends InteractionWiredCondition { Habbo habbo = room.getHabbo(roomUnit); if (habbo != null) { - if (habbo.getHabboInfo().getGamePlayer() != null) { - return !habbo.getHabboInfo().getGamePlayer().getTeamColor().equals(this.teamColor); - } - return true; // user is not part of any team + return habbo.getHabboInfo().getGamePlayer() == null || !habbo.getHabboInfo().getGamePlayer().getTeamColor().equals(this.teamColor); // user is not part of any team } - return false; + return true; } @Override diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotMatchStatePosition.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotMatchStatePosition.java index 698cd2c3..48983cef 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotMatchStatePosition.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotMatchStatePosition.java @@ -43,15 +43,15 @@ public class WiredConditionNotMatchStatePosition extends InteractionWiredConditi THashSet s = new THashSet<>(); for (WiredMatchFurniSetting setting : this.settings) { - HabboItem item = room.getHabboItem(setting.itemId); + HabboItem item = room.getHabboItem(setting.item_id); if (item != null) { boolean stateMatches = !this.state || item.getExtradata().equals(setting.state); boolean positionMatches = !this.position || (setting.x == item.getX() && setting.y == item.getY()); boolean directionMatches = !this.rotation || setting.rotation == item.getRotation(); - if (stateMatches && positionMatches && directionMatches) - return false; + if (!stateMatches || !positionMatches || !directionMatches) + return true; } else { s.add(setting); } @@ -63,7 +63,7 @@ public class WiredConditionNotMatchStatePosition extends InteractionWiredConditi } } - return true; + return false; } @Override @@ -124,7 +124,7 @@ public class WiredConditionNotMatchStatePosition extends InteractionWiredConditi message.appendInt(this.settings.size()); for (WiredMatchFurniSetting item : this.settings) - message.appendInt(item.itemId); + message.appendInt(item.item_id); message.appendInt(this.getBaseItem().getSpriteId()); message.appendInt(this.getId()); @@ -178,7 +178,7 @@ public class WiredConditionNotMatchStatePosition extends InteractionWiredConditi THashSet remove = new THashSet<>(); for (WiredMatchFurniSetting setting : this.settings) { - HabboItem item = room.getHabboItem(setting.itemId); + HabboItem item = room.getHabboItem(setting.item_id); if (item == null) { remove.add(setting); } diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotTriggerOnFurni.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotTriggerOnFurni.java index 65dc97f1..cf31f254 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotTriggerOnFurni.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotTriggerOnFurni.java @@ -37,12 +37,8 @@ public class WiredConditionNotTriggerOnFurni extends InteractionWiredCondition { if (this.items.isEmpty()) return true; - for (HabboItem item : this.items) { - if (RoomLayout.getRectangle(item.getX(), item.getY(), item.getBaseItem().getWidth(), item.getBaseItem().getLength(), item.getRotation()).contains(roomUnit.getX(), roomUnit.getY())) - return false; - } - - return true; + THashSet itemsAtUser = room.getItemsAt(roomUnit.getCurrentLocation()); + return this.items.stream().noneMatch(itemsAtUser::contains); } @Override diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionTriggerOnFurni.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionTriggerOnFurni.java index 9d373e56..56d54325 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionTriggerOnFurni.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionTriggerOnFurni.java @@ -5,6 +5,7 @@ import com.eu.habbo.habbohotel.items.Item; import com.eu.habbo.habbohotel.items.interactions.InteractionWiredCondition; import com.eu.habbo.habbohotel.rooms.Room; import com.eu.habbo.habbohotel.rooms.RoomLayout; +import com.eu.habbo.habbohotel.rooms.RoomTile; import com.eu.habbo.habbohotel.rooms.RoomUnit; import com.eu.habbo.habbohotel.users.HabboItem; import com.eu.habbo.habbohotel.wired.WiredConditionOperator; @@ -37,14 +38,10 @@ public class WiredConditionTriggerOnFurni extends InteractionWiredCondition { this.refresh(); if (this.items.isEmpty()) - return true; + return false; - for (HabboItem item : this.items) { - if (RoomLayout.getRectangle(item.getX(), item.getY(), item.getBaseItem().getWidth(), item.getBaseItem().getLength(), item.getRotation()).contains(roomUnit.getX(), roomUnit.getY())) - return true; - } - - return false; + THashSet itemsAtUser = room.getItemsAt(roomUnit.getCurrentLocation()); + return this.items.stream().anyMatch(itemsAtUser::contains); } @Override @@ -149,6 +146,6 @@ public class WiredConditionTriggerOnFurni extends InteractionWiredCondition { @Override public WiredConditionOperator operator() { - return WiredConditionOperator.OR; + return WiredConditionOperator.AND; } } diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotClothes.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotClothes.java index ec22bf63..f0a5b3f8 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotClothes.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotClothes.java @@ -1,5 +1,6 @@ package com.eu.habbo.habbohotel.items.interactions.wired.effects; +import com.eu.habbo.Emulator; import com.eu.habbo.habbohotel.bots.Bot; import com.eu.habbo.habbohotel.gameclients.GameClient; import com.eu.habbo.habbohotel.items.Item; @@ -7,12 +8,16 @@ import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect; 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.WiredHandler; import com.eu.habbo.messages.ClientMessage; import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.wired.WiredSaveException; +import com.google.gson.Gson; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; +import java.util.regex.Pattern; public class WiredEffectBotClothes extends InteractionWiredEffect { public static final WiredEffectType type = WiredEffectType.BOT_CLOTHES; @@ -44,18 +49,27 @@ public class WiredEffectBotClothes extends InteractionWiredEffect { } @Override - public boolean saveData(ClientMessage packet, GameClient gameClient) { + public boolean saveData(ClientMessage packet, GameClient gameClient) throws WiredSaveException { packet.readInt(); - - String[] data = packet.readString().split(((char) 9) + ""); - - if (data.length == 2) { - this.botName = data[0]; - this.botLook = data[1]; - } - + String dataString = packet.readString(); packet.readInt(); - this.setDelay(packet.readInt()); + int delay = packet.readInt(); + + if(delay > Emulator.getConfig().getInt("hotel.wired.max_delay", 20)) + throw new WiredSaveException("Delay too long"); + + String splitBy = "\t"; + if(!dataString.contains(splitBy)) + throw new WiredSaveException("Malformed data string"); + + String[] data = dataString.split(Pattern.quote(splitBy)); + + if (data.length != 2) + throw new WiredSaveException("Malformed data string. Invalid data length"); + + this.botName = data[0].substring(0, Math.min(data[0].length(), Emulator.getConfig().getInt("hotel.wired.message.max_length", 100))); + this.botLook = data[1]; + this.setDelay(delay); return true; } @@ -69,31 +83,39 @@ public class WiredEffectBotClothes extends InteractionWiredEffect { public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { List bots = room.getBots(this.botName); - if (bots.size() != 1) { - return false; + if (bots.size() == 1) { + Bot bot = bots.get(0); + bot.setFigure(this.botLook); } - Bot bot = bots.get(0); - bot.setFigure(this.botLook); - return true; } @Override public String getWiredData() { - return this.getDelay() + "" + ((char) 9) + "" + - this.botName + ((char) 9) + - this.botLook; + return WiredHandler.getGsonBuilder().create().toJson(new JsonData(this.botName, this.botLook, this.getDelay())); } @Override public void loadWiredData(ResultSet set, Room room) throws SQLException { - String[] data = set.getString("wired_data").split(((char) 9) + ""); + String wiredData = set.getString("wired_data"); - if (data.length >= 3) { - this.setDelay(Integer.valueOf(data[0])); - this.botName = data[1]; - this.botLook = data[2]; + if(wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.setDelay(data.delay); + this.botName = data.bot_name; + this.botLook = data.look; + } + else { + String[] data = wiredData.split(((char) 9) + ""); + + if (data.length >= 3) { + this.setDelay(Integer.valueOf(data[0])); + this.botName = data[1]; + this.botLook = data[2]; + } + + this.needsUpdate(true); } } @@ -119,4 +141,16 @@ public class WiredEffectBotClothes extends InteractionWiredEffect { public void setBotLook(String botLook) { this.botLook = botLook; } + + static class JsonData { + String bot_name; + String look; + int delay; + + public JsonData(String bot_name, String look, int delay) { + this.bot_name = bot_name; + this.look = look; + this.delay = delay; + } + } } diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotFollowHabbo.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotFollowHabbo.java index 928068af..ee1b28b1 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotFollowHabbo.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotFollowHabbo.java @@ -1,5 +1,6 @@ package com.eu.habbo.habbohotel.items.interactions.wired.effects; +import com.eu.habbo.Emulator; import com.eu.habbo.habbohotel.bots.Bot; import com.eu.habbo.habbohotel.gameclients.GameClient; import com.eu.habbo.habbohotel.items.Item; @@ -9,8 +10,10 @@ 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.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.WiredHandler; import com.eu.habbo.messages.ClientMessage; import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.wired.WiredSaveException; import gnu.trove.procedure.TObjectProcedure; import java.sql.ResultSet; @@ -67,13 +70,25 @@ public class WiredEffectBotFollowHabbo extends InteractionWiredEffect { } @Override - public boolean saveData(ClientMessage packet, GameClient gameClient) { + public boolean saveData(ClientMessage packet, GameClient gameClient) throws WiredSaveException { packet.readInt(); + int mode = packet.readInt(); - this.mode = packet.readInt(); - this.botName = packet.readString().replace("\t", ""); + if(mode != 0 && mode != 1) + throw new WiredSaveException("Mode is invalid"); + + String botName = packet.readString().replace("\t", ""); + botName = botName.substring(0, Math.min(botName.length(), Emulator.getConfig().getInt("hotel.wired.message.max_length", 100))); packet.readInt(); - this.setDelay(packet.readInt()); + int delay = packet.readInt(); + + if(delay > Emulator.getConfig().getInt("hotel.wired.max_delay", 20)) + throw new WiredSaveException("Delay too long"); + + this.botName = botName; + this.mode = mode; + this.setDelay(delay); + return true; } @@ -105,17 +120,29 @@ public class WiredEffectBotFollowHabbo extends InteractionWiredEffect { @Override public String getWiredData() { - return this.getDelay() + "" + ((char) 9) + "" + this.mode + "" + ((char) 9) + this.botName; + return WiredHandler.getGsonBuilder().create().toJson(new JsonData(this.botName, this.mode, this.getDelay())); } @Override public void loadWiredData(ResultSet set, Room room) throws SQLException { - String[] data = set.getString("wired_data").split(((char) 9) + ""); + String wiredData = set.getString("wired_data"); - if (data.length == 3) { - this.setDelay(Integer.valueOf(data[0])); - this.mode = (data[1].equalsIgnoreCase("1") ? 1 : 0); - this.botName = data[2]; + if(wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.setDelay(data.delay); + this.mode = data.mode; + this.botName = data.bot_name; + } + else { + String[] data = wiredData.split(((char) 9) + ""); + + if (data.length == 3) { + this.setDelay(Integer.valueOf(data[0])); + this.mode = (data[1].equalsIgnoreCase("1") ? 1 : 0); + this.botName = data[2]; + } + + this.needsUpdate(true); } } @@ -130,4 +157,16 @@ public class WiredEffectBotFollowHabbo extends InteractionWiredEffect { public boolean requiresTriggeringUser() { return true; } + + static class JsonData { + String bot_name; + int mode; + int delay; + + public JsonData(String bot_name, int mode, int delay) { + this.bot_name = bot_name; + this.mode = mode; + this.delay = delay; + } + } } diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotGiveHandItem.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotGiveHandItem.java index 94173cdd..27fc7888 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotGiveHandItem.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotGiveHandItem.java @@ -7,13 +7,17 @@ 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.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; import com.eu.habbo.habbohotel.rooms.RoomUnit; import com.eu.habbo.habbohotel.users.Habbo; import com.eu.habbo.habbohotel.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.habbohotel.wired.WiredTriggerType; import com.eu.habbo.messages.ClientMessage; import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.wired.WiredSaveException; import com.eu.habbo.threading.runnables.RoomUnitGiveHanditem; -import com.eu.habbo.threading.runnables.RoomUnitWalkToRoomUnit; +import com.eu.habbo.threading.runnables.RoomUnitWalkToLocation; import gnu.trove.procedure.TObjectProcedure; import java.sql.ResultSet; @@ -70,13 +74,25 @@ public class WiredEffectBotGiveHandItem extends InteractionWiredEffect { } @Override - public boolean saveData(ClientMessage packet, GameClient gameClient) { + public boolean saveData(ClientMessage packet, GameClient gameClient) throws WiredSaveException { packet.readInt(); - this.itemId = packet.readInt(); - this.botName = packet.readString(); + int itemId = packet.readInt(); + + if(itemId < 0) + itemId = 0; + + String botName = packet.readString(); packet.readInt(); - this.setDelay(packet.readInt()); + int delay = packet.readInt(); + + if(delay > Emulator.getConfig().getInt("hotel.wired.max_delay", 20)) + throw new WiredSaveException("Delay too long"); + + this.itemId = itemId; + this.botName = botName.substring(0, Math.min(botName.length(), Emulator.getConfig().getInt("hotel.wired.message.max_length", 100))); + this.setDelay(delay); + return true; } @@ -94,15 +110,22 @@ public class WiredEffectBotGiveHandItem extends InteractionWiredEffect { Bot bot = bots.get(0); List tasks = new ArrayList<>(); - tasks.add(new RoomUnitGiveHanditem(habbo.getRoomUnit(), room, this.itemId)); + tasks.add(new RoomUnitGiveHanditem(roomUnit, room, this.itemId)); tasks.add(new RoomUnitGiveHanditem(bot.getRoomUnit(), room, 0)); + tasks.add(() -> { + if(roomUnit.getRoom() != null && roomUnit.getRoom().getId() == room.getId() && roomUnit.getCurrentLocation().distance(bot.getRoomUnit().getCurrentLocation()) < 2) { + WiredHandler.handle(WiredTriggerType.BOT_REACHED_AVTR, bot.getRoomUnit(), room, new Object[]{}); + } + }); + + RoomTile tile = bot.getRoomUnit().getClosestAdjacentTile(roomUnit.getX(), roomUnit.getY(), true); + + if(tile != null) { + bot.getRoomUnit().setGoalLocation(tile); + } Emulator.getThreading().run(new RoomUnitGiveHanditem(bot.getRoomUnit(), room, this.itemId)); - - List failedReach = new ArrayList<>(); - failedReach.add(() -> tasks.forEach(Runnable::run)); - - Emulator.getThreading().run(new RoomUnitWalkToRoomUnit(bot.getRoomUnit(), habbo.getRoomUnit(), room, tasks, failedReach)); + Emulator.getThreading().run(new RoomUnitWalkToLocation(bot.getRoomUnit(), tile, room, tasks, tasks)); return true; } @@ -112,17 +135,29 @@ public class WiredEffectBotGiveHandItem extends InteractionWiredEffect { @Override public String getWiredData() { - return this.getDelay() + "" + ((char) 9) + "" + this.itemId + "" + ((char) 9) + "" + this.botName; + return WiredHandler.getGsonBuilder().create().toJson(new JsonData(this.botName, this.itemId, this.getDelay())); } @Override public void loadWiredData(ResultSet set, Room room) throws SQLException { - String[] data = set.getString("wired_data").split(((char) 9) + ""); + String wiredData = set.getString("wired_data"); - if (data.length == 3) { - this.setDelay(Integer.valueOf(data[0])); - this.itemId = Integer.valueOf(data[1]); - this.botName = data[2]; + if(wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.setDelay(data.delay); + this.itemId = data.item_id; + this.botName = data.bot_name; + } + else { + String[] data = wiredData.split(((char) 9) + ""); + + if (data.length == 3) { + this.setDelay(Integer.valueOf(data[0])); + this.itemId = Integer.valueOf(data[1]); + this.botName = data[2]; + } + + this.needsUpdate(true); } } @@ -137,4 +172,16 @@ public class WiredEffectBotGiveHandItem extends InteractionWiredEffect { public boolean requiresTriggeringUser() { return true; } + + static class JsonData { + String bot_name; + int item_id; + int delay; + + public JsonData(String bot_name, int item_id, int delay) { + this.bot_name = bot_name; + this.item_id = item_id; + this.delay = delay; + } + } } diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotTalk.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotTalk.java index 8297cde1..0b7b0d3a 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotTalk.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotTalk.java @@ -9,12 +9,16 @@ 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.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.habbohotel.wired.WiredTriggerType; import com.eu.habbo.messages.ClientMessage; 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.List; +import java.util.regex.Pattern; public class WiredEffectBotTalk extends InteractionWiredEffect { public static final WiredEffectType type = WiredEffectType.BOT_TALK; @@ -48,22 +52,35 @@ public class WiredEffectBotTalk extends InteractionWiredEffect { } @Override - public boolean saveData(ClientMessage packet, GameClient gameClient) { + public boolean saveData(ClientMessage packet, GameClient gameClient) throws WiredSaveException { packet.readInt(); - this.mode = packet.readInt(); + int mode = packet.readInt(); - String[] data = packet.readString().split(((char) 9) + ""); + if(mode != 0 && mode != 1) + throw new WiredSaveException("Mode is invalid"); - if (data.length == 2) { - this.botName = data[0]; + String dataString = packet.readString(); - if (data[1].length() > 64) return false; - this.message = data[1]; - } + String splitBy = "\t"; + if(!dataString.contains(splitBy)) + throw new WiredSaveException("Malformed data string"); + + String[] data = dataString.split(Pattern.quote(splitBy)); + + if (data.length != 2) + throw new WiredSaveException("Malformed data string. Invalid data length"); packet.readInt(); - this.setDelay(packet.readInt()); + int delay = packet.readInt(); + + if(delay > Emulator.getConfig().getInt("hotel.wired.max_delay", 20)) + throw new WiredSaveException("Delay too long"); + + this.setDelay(delay); + this.botName = data[0].substring(0, Math.min(data[0].length(), Emulator.getConfig().getInt("hotel.wired.message.max_length", 100))); + this.message = data[1].substring(0, Math.min(data[1].length(), Emulator.getConfig().getInt("hotel.wired.message.max_length", 100))); + this.mode = mode; return true; } @@ -88,16 +105,16 @@ public class WiredEffectBotTalk extends InteractionWiredEffect { List bots = room.getBots(this.botName); - if (bots.size() != 1) { - return false; - } + if (bots.size() == 1) { + Bot bot = bots.get(0); - Bot bot = bots.get(0); - - if (this.mode == 1) { - bot.shout(message); - } else { - bot.talk(message); + if(!WiredHandler.handle(WiredTriggerType.SAY_SOMETHING, bot.getRoomUnit(), room, new Object[]{ message })) { + if (this.mode == 1) { + bot.shout(message); + } else { + bot.talk(message); + } + } } return true; @@ -105,19 +122,31 @@ public class WiredEffectBotTalk extends InteractionWiredEffect { @Override public String getWiredData() { - return this.getDelay() + "" + ((char) 9) + "" + this.mode + "" + ((char) 9) + "" + this.botName + "" + ((char) 9) + "" + this.message; + return WiredHandler.getGsonBuilder().create().toJson(new JsonData(this.botName, this.mode, this.message, this.getDelay())); } @Override public void loadWiredData(ResultSet set, Room room) throws SQLException { - String d = set.getString("wired_data"); - String[] data = d.split(((char) 9) + ""); + String wiredData = set.getString("wired_data"); - if (data.length == 4) { - this.setDelay(Integer.valueOf(data[0])); - this.mode = data[1].equalsIgnoreCase("1") ? 1 : 0; - this.botName = data[2]; - this.message = data[3]; + if(wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.setDelay(data.delay); + this.mode = data.mode; + this.botName = data.bot_name; + this.message = data.message; + } + else { + String[] data = wiredData.split(((char) 9) + ""); + + if (data.length == 4) { + this.setDelay(Integer.valueOf(data[0])); + this.mode = data[1].equalsIgnoreCase("1") ? 1 : 0; + this.botName = data[2]; + this.message = data[3]; + } + + this.needsUpdate(true); } } @@ -157,4 +186,18 @@ public class WiredEffectBotTalk extends InteractionWiredEffect { protected long requiredCooldown() { return 500; } + + static class JsonData { + String bot_name; + int mode; + String message; + int delay; + + public JsonData(String bot_name, int mode, String message, int delay) { + this.bot_name = bot_name; + this.mode = mode; + this.message = message; + this.delay = delay; + } + } } diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotTalkToHabbo.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotTalkToHabbo.java index 97badb10..85d93546 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotTalkToHabbo.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotTalkToHabbo.java @@ -10,14 +10,18 @@ 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.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.habbohotel.wired.WiredTriggerType; import com.eu.habbo.messages.ClientMessage; 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.regex.Pattern; public class WiredEffectBotTalkToHabbo extends InteractionWiredEffect { public static final WiredEffectType type = WiredEffectType.BOT_TALK_TO_AVATAR; @@ -69,21 +73,34 @@ public class WiredEffectBotTalkToHabbo extends InteractionWiredEffect { } @Override - public boolean saveData(ClientMessage packet, GameClient gameClient) { + public boolean saveData(ClientMessage packet, GameClient gameClient) throws WiredSaveException { packet.readInt(); - this.mode = packet.readInt(); - String[] data = packet.readString().split("" + ((char) 9)); + int mode = packet.readInt(); - if (data.length == 2) { - this.botName = data[0]; + if(mode != 0 && mode != 1) + throw new WiredSaveException("Mode is invalid"); - if (data[1].length() > 64) return false; - this.message = data[1]; - } + String dataString = packet.readString(); + String splitBy = "\t"; + if(!dataString.contains(splitBy)) + throw new WiredSaveException("Malformed data string"); + + String[] data = dataString.split(Pattern.quote(splitBy)); + + if (data.length != 2) + throw new WiredSaveException("Malformed data string. Invalid data length"); packet.readInt(); - this.setDelay(packet.readInt()); + int delay = packet.readInt(); + + if(delay > Emulator.getConfig().getInt("hotel.wired.max_delay", 20)) + throw new WiredSaveException("Delay too long"); + + this.botName = data[0].substring(0, Math.min(data[0].length(), Emulator.getConfig().getInt("hotel.wired.message.max_length", 100))); + this.message = data[1].substring(0, Math.min(data[1].length(), Emulator.getConfig().getInt("hotel.wired.message.max_length", 100))); + this.mode = mode; + this.setDelay(delay); return true; } @@ -112,10 +129,12 @@ public class WiredEffectBotTalkToHabbo extends InteractionWiredEffect { Bot bot = bots.get(0); - if (this.mode == 1) { - bot.whisper(m, habbo); - } else { - bot.talk(habbo.getHabboInfo().getUsername() + ": " + m); + if(!WiredHandler.handle(WiredTriggerType.SAY_SOMETHING, bot.getRoomUnit(), room, new Object[]{ m })) { + if (this.mode == 1) { + bot.whisper(m, habbo); + } else { + bot.talk(habbo.getHabboInfo().getUsername() + ": " + m); + } } return true; @@ -126,18 +145,31 @@ public class WiredEffectBotTalkToHabbo extends InteractionWiredEffect { @Override public String getWiredData() { - return this.getDelay() + "" + ((char) 9) + "" + this.mode + "" + ((char) 9) + "" + this.botName + "" + ((char) 9) + "" + this.message; + return WiredHandler.getGsonBuilder().create().toJson(new JsonData(this.botName, this.mode, this.message, this.getDelay())); } @Override public void loadWiredData(ResultSet set, Room room) throws SQLException { - String[] data = set.getString("wired_data").split(((char) 9) + ""); + String wiredData = set.getString("wired_data"); - if (data.length == 4) { - this.setDelay(Integer.valueOf(data[0])); - this.mode = data[1].equalsIgnoreCase("1") ? 1 : 0; - this.botName = data[2]; - this.message = data[3]; + if(wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.setDelay(data.delay); + this.mode = data.mode; + this.botName = data.bot_name; + this.message = data.message; + } + else { + String[] data = wiredData.split(((char) 9) + ""); + + if (data.length == 4) { + this.setDelay(Integer.valueOf(data[0])); + this.mode = data[1].equalsIgnoreCase("1") ? 1 : 0; + this.botName = data[2]; + this.message = data[3]; + } + + this.needsUpdate(true); } } @@ -153,4 +185,18 @@ public class WiredEffectBotTalkToHabbo extends InteractionWiredEffect { public boolean requiresTriggeringUser() { return true; } + + static class JsonData { + String bot_name; + int mode; + String message; + int delay; + + public JsonData(String bot_name, int mode, String message, int delay) { + this.bot_name = bot_name; + this.mode = mode; + this.message = message; + this.delay = delay; + } + } } diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotTeleport.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotTeleport.java index 9fe3e8ef..07bbac6f 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotTeleport.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotTeleport.java @@ -14,6 +14,7 @@ import com.eu.habbo.habbohotel.wired.WiredEffectType; import com.eu.habbo.habbohotel.wired.WiredHandler; import com.eu.habbo.messages.ClientMessage; import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.wired.WiredSaveException; import com.eu.habbo.messages.outgoing.rooms.users.RoomUserEffectComposer; import com.eu.habbo.threading.runnables.RoomUnitTeleport; import com.eu.habbo.threading.runnables.SendRoomUnitEffectComposer; @@ -21,8 +22,10 @@ import gnu.trove.set.hash.THashSet; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.stream.Collectors; public class WiredEffectBotTeleport extends InteractionWiredEffect { public static final WiredEffectType type = WiredEffectType.BOT_TELEPORT; @@ -77,6 +80,7 @@ public class WiredEffectBotTeleport extends InteractionWiredEffect { } } + Emulator.getThreading().run(() -> { roomUnit.isWiredTeleporting = true; }, Math.max(0, WiredHandler.TELEPORT_DELAY - 500)); Emulator.getThreading().run(new RoomUnitTeleport(roomUnit, room, tile.x, tile.y, tile.getStackHeight() + (tile.state == RoomTileState.SIT ? -0.5 : 0), roomUnit.getEffectId()), WiredHandler.TELEPORT_DELAY); } @@ -110,20 +114,36 @@ public class WiredEffectBotTeleport extends InteractionWiredEffect { } @Override - public boolean saveData(ClientMessage packet, GameClient gameClient) { + public boolean saveData(ClientMessage packet, GameClient gameClient) throws WiredSaveException { packet.readInt(); - this.botName = packet.readString(); + String botName = packet.readString(); + int itemsCount = packet.readInt(); - int count = packet.readInt(); - if (count > Emulator.getConfig().getInt("hotel.wired.furni.selection.count")) return false; - - this.items.clear(); - - for (int i = 0; i < count; i++) { - this.items.add(Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(packet.readInt())); + if(itemsCount > Emulator.getConfig().getInt("hotel.wired.furni.selection.count")) { + throw new WiredSaveException("Too many furni selected"); } - this.setDelay(packet.readInt()); + List newItems = new ArrayList<>(); + + for (int i = 0; i < itemsCount; i++) { + int itemId = packet.readInt(); + HabboItem it = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(itemId); + + if(it == null) + throw new WiredSaveException(String.format("Item %s not found", itemId)); + + newItems.add(it); + } + + int delay = packet.readInt(); + + if(delay > Emulator.getConfig().getInt("hotel.wired.max_delay", 20)) + throw new WiredSaveException("Delay too long"); + + this.items.clear(); + this.items.addAll(newItems); + this.botName = botName.substring(0, Math.min(botName.length(), Emulator.getConfig().getInt("hotel.wired.message.max_length", 100))); + this.setDelay(delay); return true; } @@ -165,38 +185,57 @@ public class WiredEffectBotTeleport extends InteractionWiredEffect { @Override public String getWiredData() { - StringBuilder wiredData = new StringBuilder(this.getDelay() + "\t" + this.botName + ";"); + ArrayList itemIds = new ArrayList<>(); - if (this.items != null && !this.items.isEmpty()) { + if (this.items != null) { for (HabboItem item : this.items) { if (item.getRoomId() != 0) { - wiredData.append(item.getId()).append(";"); + itemIds.add(item.getId()); } } } - return wiredData.toString(); + return WiredHandler.getGsonBuilder().create().toJson(new JsonData(this.botName, itemIds, this.getDelay())); } @Override public void loadWiredData(ResultSet set, Room room) throws SQLException { this.items = new THashSet<>(); - String[] wiredData = set.getString("wired_data").split("\t"); - if (wiredData.length >= 2) { - this.setDelay(Integer.valueOf(wiredData[0])); - String[] data = wiredData[1].split(";"); + String wiredData = set.getString("wired_data"); - if (data.length > 1) { - this.botName = data[0]; + if(wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.setDelay(data.delay); + this.botName = data.bot_name; - for (int i = 1; i < data.length; i++) { - HabboItem item = room.getHabboItem(Integer.valueOf(data[i])); + for(int itemId : data.items) { + HabboItem item = room.getHabboItem(itemId); - if (item != null) - this.items.add(item); + if (item != null) + this.items.add(item); + } + } + else { + String[] wiredDataSplit = set.getString("wired_data").split("\t"); + + if (wiredDataSplit.length >= 2) { + this.setDelay(Integer.valueOf(wiredDataSplit[0])); + String[] data = wiredDataSplit[1].split(";"); + + if (data.length > 1) { + this.botName = data[0]; + + for (int i = 1; i < data.length; i++) { + HabboItem item = room.getHabboItem(Integer.valueOf(data[i])); + + if (item != null) + this.items.add(item); + } } } + + this.needsUpdate(true); } } @@ -206,4 +245,16 @@ public class WiredEffectBotTeleport extends InteractionWiredEffect { this.items.clear(); this.setDelay(0); } + + static class JsonData { + String bot_name; + List items; + int delay; + + public JsonData(String bot_name, List items, int delay) { + this.bot_name = bot_name; + this.items = items; + this.delay = delay; + } + } } diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotWalkToFurni.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotWalkToFurni.java index 3b5543b7..be2cccd6 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotWalkToFurni.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotWalkToFurni.java @@ -12,26 +12,28 @@ import com.eu.habbo.habbohotel.wired.WiredEffectType; import com.eu.habbo.habbohotel.wired.WiredHandler; import com.eu.habbo.messages.ClientMessage; import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.wired.WiredSaveException; import gnu.trove.set.hash.THashSet; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.ArrayList; import java.util.List; public class WiredEffectBotWalkToFurni extends InteractionWiredEffect { public static final WiredEffectType type = WiredEffectType.BOT_MOVE; - private THashSet items; + private List items; private String botName = ""; public WiredEffectBotWalkToFurni(ResultSet set, Item baseItem) throws SQLException { super(set, baseItem); - this.items = new THashSet<>(); + this.items = new ArrayList<>(); } public WiredEffectBotWalkToFurni(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { super(id, userId, item, extradata, limitedStack, limitedSells); - this.items = new THashSet<>(); + this.items = new ArrayList<>(); } @Override @@ -64,20 +66,36 @@ public class WiredEffectBotWalkToFurni extends InteractionWiredEffect { } @Override - public boolean saveData(ClientMessage packet, GameClient gameClient) { + public boolean saveData(ClientMessage packet, GameClient gameClient) throws WiredSaveException { packet.readInt(); - this.botName = packet.readString(); + String botName = packet.readString(); + int itemsCount = packet.readInt(); - int count = packet.readInt(); - if (count > Emulator.getConfig().getInt("hotel.wired.furni.selection.count")) return false; - - this.items.clear(); - - for (int i = 0; i < count; i++) { - this.items.add(Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(packet.readInt())); + if(itemsCount > Emulator.getConfig().getInt("hotel.wired.furni.selection.count")) { + throw new WiredSaveException("Too many furni selected"); } - this.setDelay(packet.readInt()); + List newItems = new ArrayList<>(); + + for (int i = 0; i < itemsCount; i++) { + int itemId = packet.readInt(); + HabboItem it = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(itemId); + + if(it == null) + throw new WiredSaveException(String.format("Item %s not found", itemId)); + + newItems.add(it); + } + + int delay = packet.readInt(); + + if(delay > Emulator.getConfig().getInt("hotel.wired.max_delay", 20)) + throw new WiredSaveException("Delay too long"); + + this.items.clear(); + this.items.addAll(newItems); + this.botName = botName.substring(0, Math.min(botName.length(), Emulator.getConfig().getInt("hotel.wired.message.max_length", 100))); + this.setDelay(delay); return true; } @@ -92,33 +110,18 @@ public class WiredEffectBotWalkToFurni extends InteractionWiredEffect { List bots = room.getBots(this.botName); if (this.items.isEmpty() || bots.size() != 1) { - return false; + return true; } Bot bot = bots.get(0); - THashSet items = new THashSet<>(); - - for (HabboItem item : this.items) { - if (Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null) - items.add(item); - } - - for (HabboItem item : items) { - this.items.remove(item); - } + this.items.removeIf(item -> item == null || item.getRoomId() != this.getRoomId() || Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null); + // wtf was that if (this.items.size() > 0) { - int i = Emulator.getRandom().nextInt(this.items.size()) + 1; - int j = 1; - for (HabboItem item : this.items) { - if (item.getRoomId() != 0 && item.getRoomId() == bot.getRoom().getId()) { - if (i == j) { - bot.getRoomUnit().setGoalLocation(room.getLayout().getTile(item.getX(), item.getY())); - break; - } else { - j++; - } - } + HabboItem item = this.items.get(Emulator.getRandom().nextInt(this.items.size())); + + if (item.getRoomId() != 0 && item.getRoomId() == bot.getRoom().getId()) { + bot.getRoomUnit().setGoalLocation(room.getLayout().getTile(item.getX(), item.getY())); } } @@ -127,38 +130,57 @@ public class WiredEffectBotWalkToFurni extends InteractionWiredEffect { @Override public String getWiredData() { - StringBuilder wiredData = new StringBuilder(this.getDelay() + "\t" + this.botName + ";"); + ArrayList itemIds = new ArrayList<>(); - if (this.items != null && !this.items.isEmpty()) { + if (this.items != null) { for (HabboItem item : this.items) { if (item.getRoomId() != 0) { - wiredData.append(item.getId()).append(";"); + itemIds.add(item.getId()); } } } - return wiredData.toString(); + return WiredHandler.getGsonBuilder().create().toJson(new JsonData(this.botName, itemIds, this.getDelay())); } @Override public void loadWiredData(ResultSet set, Room room) throws SQLException { - this.items = new THashSet<>(); - String[] wiredData = set.getString("wired_data").split("\t"); + this.items = new ArrayList<>(); - if (wiredData.length > 1) { - this.setDelay(Integer.valueOf(wiredData[0])); - String[] data = wiredData[1].split(";"); + String wiredData = set.getString("wired_data"); - if (data.length >= 1) { - this.botName = data[0]; + if(wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.setDelay(data.delay); + this.botName = data.bot_name; - for (int i = 1; i < data.length; i++) { - HabboItem item = room.getHabboItem(Integer.valueOf(data[i])); + for(int itemId : data.items) { + HabboItem item = room.getHabboItem(itemId); - if (item != null) - this.items.add(item); + if (item != null) + this.items.add(item); + } + } + else { + String[] wiredDataSplit = set.getString("wired_data").split("\t"); + + if (wiredDataSplit.length >= 2) { + this.setDelay(Integer.valueOf(wiredDataSplit[0])); + String[] data = wiredDataSplit[1].split(";"); + + if (data.length > 1) { + this.botName = data[0]; + + for (int i = 1; i < data.length; i++) { + HabboItem item = room.getHabboItem(Integer.valueOf(data[i])); + + if (item != null) + this.items.add(item); + } } } + + this.needsUpdate(true); } } @@ -168,4 +190,16 @@ public class WiredEffectBotWalkToFurni extends InteractionWiredEffect { this.botName = ""; this.setDelay(0); } + + static class JsonData { + String bot_name; + List items; + int delay; + + public JsonData(String bot_name, List items, int delay) { + this.bot_name = bot_name; + this.items = items; + this.delay = delay; + } + } } diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectChangeFurniDirection.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectChangeFurniDirection.java index 308c1bbf..0ce892d7 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectChangeFurniDirection.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectChangeFurniDirection.java @@ -5,19 +5,19 @@ 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.rooms.*; -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.WiredHandler; -import com.eu.habbo.habbohotel.wired.WiredTriggerType; +import com.eu.habbo.habbohotel.wired.*; import com.eu.habbo.messages.ClientMessage; import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.wired.WiredSaveException; import com.eu.habbo.messages.outgoing.rooms.items.FloorItemOnRollerComposer; import gnu.trove.map.hash.THashMap; import gnu.trove.set.hash.THashSet; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; import java.util.Map; public class WiredEffectChangeFurniDirection extends InteractionWiredEffect { @@ -31,9 +31,9 @@ public class WiredEffectChangeFurniDirection extends InteractionWiredEffect { public static final WiredEffectType type = WiredEffectType.MOVE_DIRECTION; - private final THashMap items = new THashMap<>(0); + private final THashMap items = new THashMap<>(0); private RoomUserRotation startRotation = RoomUserRotation.NORTH; - private int rotateAction = 0; + private int blockedAction = 0; public WiredEffectChangeFurniDirection(ResultSet set, Item baseItem) throws SQLException { super(set, baseItem); @@ -57,29 +57,56 @@ public class WiredEffectChangeFurniDirection extends InteractionWiredEffect { } if (this.items.isEmpty()) return false; - for (Map.Entry entry : this.items.entrySet()) { - RoomUserRotation currentRotation = entry.getValue(); - RoomTile targetTile = room.getLayout().getTileInFront(room.getLayout().getTile(entry.getKey().getX(), entry.getKey().getY()), entry.getValue().getValue()); + + for (Map.Entry entry : this.items.entrySet()) { + HabboItem item = entry.getKey(); + RoomTile targetTile = room.getLayout().getTileInFront(room.getLayout().getTile(item.getX(), item.getY()), entry.getValue().direction.getValue()); int count = 1; - while ((targetTile == null || !targetTile.getAllowStack() || targetTile.state == RoomTileState.INVALID || targetTile.state == RoomTileState.BLOCKED) && count < 8) { - entry.setValue(this.nextRotation(entry.getValue())); - targetTile = room.getLayout().getTileInFront(room.getLayout().getTile(entry.getKey().getX(), entry.getKey().getY()), entry.getValue().getValue()); - count++; - } + while ((targetTile == null || targetTile.state == RoomTileState.INVALID || room.furnitureFitsAt(targetTile, item, item.getRotation(), false) != FurnitureMovementError.NONE) && count < 8) { + entry.getValue().direction = this.nextRotation(entry.getValue().direction); - if (targetTile != null && targetTile.state != RoomTileState.INVALID) { - boolean hasRoomUnits = false; - for (RoomUnit _roomUnit : room.getHabbosAndBotsAt(targetTile)) { - hasRoomUnits = true; - Emulator.getThreading().run(() -> WiredHandler.handle(WiredTriggerType.COLLISION, _roomUnit, room, new Object[]{entry.getKey()})); + RoomTile tile = room.getLayout().getTileInFront(room.getLayout().getTile(item.getX(), item.getY()), entry.getValue().direction.getValue()); + if (tile != null && tile.state != RoomTileState.INVALID) { + targetTile = tile; } + count++; + } + } + + for (Map.Entry entry : this.items.entrySet()) { + HabboItem item = entry.getKey(); + int newDirection = entry.getValue().direction.getValue(); + + RoomTile targetTile = room.getLayout().getTileInFront(room.getLayout().getTile(item.getX(), item.getY()), newDirection); + + if(item.getRotation() != entry.getValue().rotation) { + if(room.furnitureFitsAt(targetTile, item, entry.getValue().rotation, false) != FurnitureMovementError.NONE) + continue; + + room.moveFurniTo(entry.getKey(), targetTile, entry.getValue().rotation, null, true); + } + + boolean hasRoomUnits = false; + THashSet newOccupiedTiles = room.getLayout().getTilesAt(targetTile, item.getBaseItem().getWidth(), item.getBaseItem().getLength(), item.getRotation()); + for(RoomTile tile : newOccupiedTiles) { + for (RoomUnit _roomUnit : room.getRoomUnits(tile)) { + hasRoomUnits = true; + if(_roomUnit.getCurrentLocation() == targetTile) { + Emulator.getThreading().run(() -> WiredHandler.handle(WiredTriggerType.COLLISION, _roomUnit, room, new Object[]{entry.getKey()})); + break; + } + } + } + + if (targetTile != null && targetTile.state != RoomTileState.INVALID && room.furnitureFitsAt(targetTile, item, item.getRotation(), false) == FurnitureMovementError.NONE) { if (!hasRoomUnits) { - THashSet refreshTiles = room.getLayout().getTilesAt(room.getLayout().getTile(entry.getKey().getX(), entry.getKey().getY()), entry.getKey().getBaseItem().getWidth(), entry.getKey().getBaseItem().getLength(), entry.getKey().getRotation()); - room.sendComposer(new FloorItemOnRollerComposer(entry.getKey(), null, targetTile, targetTile.getStackHeight() - entry.getKey().getZ(), room).compose()); - room.getLayout().getTilesAt(room.getLayout().getTile(entry.getKey().getX(), entry.getKey().getY()), entry.getKey().getBaseItem().getWidth(), entry.getKey().getBaseItem().getLength(), entry.getKey().getRotation()); - room.updateTiles(refreshTiles); + RoomTile oldLocation = room.getLayout().getTile(entry.getKey().getX(), entry.getKey().getY()); + double oldZ = entry.getKey().getZ(); + if(room.moveFurniTo(entry.getKey(), targetTile, item.getRotation(), null, false) == FurnitureMovementError.NONE) { + room.sendComposer(new FloorItemOnRollerComposer(entry.getKey(), null, oldLocation, oldZ, targetTile, entry.getKey().getZ(), 0, room).compose()); + } } } } @@ -89,41 +116,63 @@ public class WiredEffectChangeFurniDirection extends InteractionWiredEffect { @Override public String getWiredData() { - StringBuilder data = new StringBuilder(this.getDelay() + this.startRotation.getValue() + "\t" + this.rotateAction + "\t" + this.items.size()); - - for (Map.Entry entry : this.items.entrySet()) { - data.append("\t").append(entry.getKey().getId()).append(":").append(entry.getValue().getValue()); - } - - return data.toString(); + ArrayList settings = new ArrayList<>(this.items.values()); + return WiredHandler.getGsonBuilder().create().toJson(new JsonData(this.startRotation, this.blockedAction, settings, this.getDelay())); } @Override public void loadWiredData(ResultSet set, Room room) throws SQLException { - String[] data = set.getString("wired_data").split("\t"); - if (data.length >= 1) { - this.setDelay(Integer.parseInt(data[0])); + this.items.clear(); + + String wiredData = set.getString("wired_data"); + + if(wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.setDelay(data.delay); + this.startRotation = data.start_direction; + this.blockedAction = data.blocked_action; + + for(WiredChangeDirectionSetting setting : data.items) { + HabboItem item = room.getHabboItem(setting.item_id); + + if (item != null) { + this.items.put(item, setting); + } + } } - if (data.length >= 3) { - this.startRotation = RoomUserRotation.fromValue(Integer.parseInt(data[0])); - this.rotateAction = Integer.parseInt(data[1]); + else { + String[] data = wiredData.split("\t"); - int itemCount = Integer.parseInt(data[2]); + if (data.length >= 4) { + this.setDelay(Integer.parseInt(data[0])); + this.startRotation = RoomUserRotation.fromValue(Integer.parseInt(data[1])); + this.blockedAction = Integer.parseInt(data[2]); - if (itemCount > 0) { - for (int i = 3; i < data.length; i++) { - String[] subData = data[i].split(":"); + int itemCount = Integer.parseInt(data[3]); - if (subData.length == 2) { - HabboItem item = room.getHabboItem(Integer.parseInt(subData[0])); + if (itemCount > 0) { + for (int i = 4; i < data.length; i++) { + String[] subData = data[i].split(":"); - if (item != null) { - this.items.put(item, RoomUserRotation.fromValue(Integer.parseInt(subData[1]))); + if (subData.length >= 2) { + HabboItem item = room.getHabboItem(Integer.parseInt(subData[0])); + + if (item != null) { + int rotation = item.getRotation(); + + if (subData.length > 2) { + rotation = Integer.parseInt(subData[2]); + } + + this.items.put(item, new WiredChangeDirectionSetting(item.getId(), rotation, RoomUserRotation.fromValue(Integer.parseInt(subData[1])))); + } } } } } + + this.needsUpdate(true); } } @@ -131,7 +180,7 @@ public class WiredEffectChangeFurniDirection extends InteractionWiredEffect { public void onPickUp() { this.setDelay(0); this.items.clear(); - this.rotateAction = 0; + this.blockedAction = 0; this.startRotation = RoomUserRotation.NORTH; } @@ -145,15 +194,15 @@ public class WiredEffectChangeFurniDirection extends InteractionWiredEffect { message.appendBoolean(false); message.appendInt(WiredHandler.MAXIMUM_FURNI_SELECTION); message.appendInt(this.items.size()); - for (Map.Entry item : this.items.entrySet()) { + for (Map.Entry item : this.items.entrySet()) { message.appendInt(item.getKey().getId()); } message.appendInt(this.getBaseItem().getSpriteId()); message.appendInt(this.getId()); message.appendString(""); message.appendInt(2); - message.appendInt(this.startRotation.getValue()); - message.appendInt(this.rotateAction); + message.appendInt(this.startRotation != null ? this.startRotation.getValue() : 0); + message.appendInt(this.blockedAction); message.appendInt(0); message.appendInt(this.getType().code); message.appendInt(this.getDelay()); @@ -161,33 +210,60 @@ public class WiredEffectChangeFurniDirection extends InteractionWiredEffect { } @Override - public boolean saveData(ClientMessage packet, GameClient gameClient) { + public boolean saveData(ClientMessage packet, GameClient gameClient) throws WiredSaveException { packet.readInt(); - this.startRotation = RoomUserRotation.fromValue(packet.readInt()); - this.rotateAction = packet.readInt(); + int startDirectionInt = packet.readInt(); + + if(startDirectionInt < 0 || startDirectionInt > 7 || (startDirectionInt % 2) != 0) { + throw new WiredSaveException("Start direction is invalid"); + } + + RoomUserRotation startDirection = RoomUserRotation.fromValue(startDirectionInt); + + int blockedActionInt = packet.readInt(); + + if(blockedActionInt < 0 || blockedActionInt > 6) { + throw new WiredSaveException("Blocked action is invalid"); + } + packet.readString(); - int count = packet.readInt(); - if (count > Emulator.getConfig().getInt("hotel.wired.furni.selection.count")) return false; + int itemsCount = packet.readInt(); + + if(itemsCount > Emulator.getConfig().getInt("hotel.wired.furni.selection.count")) { + throw new WiredSaveException("Too many furni selected"); + } + + THashMap newItems = new THashMap<>(); + + for (int i = 0; i < itemsCount; i++) { + int itemId = packet.readInt(); + HabboItem it = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(itemId); + + if(it == null) + throw new WiredSaveException(String.format("Item %s not found", itemId)); + + newItems.put(it, new WiredChangeDirectionSetting(it.getId(), it.getRotation(), startDirection)); + } + + int delay = packet.readInt(); + + if(delay > Emulator.getConfig().getInt("hotel.wired.max_delay", 20)) + throw new WiredSaveException("Delay too long"); this.items.clear(); + this.items.putAll(newItems); + this.startRotation = startDirection; + this.blockedAction = blockedActionInt; + this.setDelay(delay); - for (int i = 0; i < count; i++) { - HabboItem item = gameClient.getHabbo().getHabboInfo().getCurrentRoom().getHabboItem(packet.readInt()); - - if (item != null) { - this.items.put(item, this.startRotation); - } - } - this.setDelay(packet.readInt()); return true; } private RoomUserRotation nextRotation(RoomUserRotation currentRotation) { - switch (this.rotateAction) { + switch (this.blockedAction) { case ACTION_TURN_BACK: - return RoomUserRotation.fromValue(currentRotation.getValue() + 4); - + return RoomUserRotation.fromValue(currentRotation.getValue()).getOpposite(); case ACTION_TURN_LEFT_45: return RoomUserRotation.counterClockwise(currentRotation); case ACTION_TURN_LEFT_90: @@ -201,8 +277,6 @@ public class WiredEffectChangeFurniDirection extends InteractionWiredEffect { case ACTION_WAIT: default: return currentRotation; - - } } @@ -210,4 +284,18 @@ public class WiredEffectChangeFurniDirection extends InteractionWiredEffect { protected long requiredCooldown() { return 495; } + + static class JsonData { + RoomUserRotation start_direction; + int blocked_action; + List items; + int delay; + + public JsonData(RoomUserRotation start_direction, int blocked_action, List items, int delay) { + this.start_direction = start_direction; + this.blocked_action = blocked_action; + this.items = items; + this.delay = delay; + } + } } diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveHotelviewHofPoints.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveHotelviewHofPoints.java index 5bca3009..0bd62164 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveHotelviewHofPoints.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveHotelviewHofPoints.java @@ -9,6 +9,7 @@ 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.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.WiredHandler; import com.eu.habbo.messages.ClientMessage; import com.eu.habbo.messages.ServerMessage; import gnu.trove.procedure.TObjectProcedure; @@ -101,21 +102,31 @@ public class WiredEffectGiveHotelviewHofPoints extends InteractionWiredEffect { @Override public String getWiredData() { - return this.getDelay() + "\t" + this.amount; + return WiredHandler.getGsonBuilder().create().toJson(new JsonData(this.amount, this.getDelay())); } @Override public void loadWiredData(ResultSet set, Room room) throws SQLException { - String wireData = set.getString("wired_data"); - this.amount = 0; + String wiredData = set.getString("wired_data"); - if (wireData.split("\t").length >= 2) { - super.setDelay(Integer.valueOf(wireData.split("\t")[0])); + if(wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.amount = data.amount; + this.setDelay(data.delay); + } + else { + this.amount = 0; - try { - this.amount = Integer.valueOf(this.getWiredData().split("\t")[1]); - } catch (Exception e) { + if (wiredData.split("\t").length >= 2) { + super.setDelay(Integer.valueOf(wiredData.split("\t")[0])); + + try { + this.amount = Integer.valueOf(this.getWiredData().split("\t")[1]); + } catch (Exception e) { + } } + + this.needsUpdate(true); } } @@ -129,4 +140,14 @@ public class WiredEffectGiveHotelviewHofPoints extends InteractionWiredEffect { public boolean requiresTriggeringUser() { return true; } + + static class JsonData { + int amount; + int delay; + + public JsonData(int amount, int delay) { + this.amount = amount; + this.delay = delay; + } + } } diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveRespect.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveRespect.java index 233a97e9..4a3b966f 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveRespect.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveRespect.java @@ -10,6 +10,7 @@ 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.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.WiredHandler; import com.eu.habbo.messages.ClientMessage; import com.eu.habbo.messages.ServerMessage; import gnu.trove.procedure.TObjectProcedure; @@ -101,22 +102,32 @@ public class WiredEffectGiveRespect extends InteractionWiredEffect { @Override public String getWiredData() { - return this.getDelay() + "\t" + this.respects; + return WiredHandler.getGsonBuilder().create().toJson(new JsonData(this.respects, this.getDelay())); } @Override public void loadWiredData(ResultSet set, Room room) throws SQLException { - String wireData = set.getString("wired_data"); - String[] data = wireData.split("\t"); - this.respects = 0; + String wiredData = set.getString("wired_data"); - if (data.length >= 2) { - super.setDelay(Integer.valueOf(data[0])); + if(wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.respects = data.amount; + this.setDelay(data.delay); + } + else { + String[] data = wiredData.split("\t"); + this.respects = 0; - try { - this.respects = Integer.valueOf(data[1]); - } catch (Exception e) { + if (data.length >= 2) { + super.setDelay(Integer.valueOf(data[0])); + + try { + this.respects = Integer.valueOf(data[1]); + } catch (Exception e) { + } } + + this.needsUpdate(true); } } @@ -130,4 +141,14 @@ public class WiredEffectGiveRespect extends InteractionWiredEffect { public boolean requiresTriggeringUser() { return true; } + + static class JsonData { + int amount; + int delay; + + public JsonData(int amount, int delay) { + this.amount = amount; + this.delay = delay; + } + } } \ No newline at end of file diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveReward.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveReward.java index e61973e9..f4c3a2ba 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveReward.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveReward.java @@ -56,43 +56,52 @@ public class WiredEffectGiveReward extends InteractionWiredEffect { @Override public String getWiredData() { - StringBuilder data = new StringBuilder(this.limit + ":" + this.given + ":" + this.rewardTime + ":" + (this.uniqueRewards ? 1 : 0) + ":" + this.limitationInterval + ":" + this.getDelay() + ":"); - if (this.rewardItems.isEmpty()) { - data.append("\t"); - } else { - for (WiredGiveRewardItem item : this.rewardItems) { - data.append(item.toString()).append(";"); - } - } - - return data.toString(); + ArrayList rewards = new ArrayList<>(this.rewardItems); + return WiredHandler.getGsonBuilder().create().toJson(new JsonData(this.limit, this.given, this.rewardTime, this.uniqueRewards, this.limitationInterval, rewards, this.getDelay())); } @Override public void loadWiredData(ResultSet set, Room room) throws SQLException { - String[] data = set.getString("wired_data").split(":"); - if (data.length > 0) { - this.limit = Integer.valueOf(data[0]); - this.given = Integer.valueOf(data[1]); - this.rewardTime = Integer.valueOf(data[2]); - this.uniqueRewards = data[3].equals("1"); - this.limitationInterval = Integer.valueOf(data[4]); - this.setDelay(Integer.valueOf(data[5])); + String wiredData = set.getString("wired_data"); - if (data.length > 6) { - if (!data[6].equalsIgnoreCase("\t")) { - String[] items = data[6].split(";"); + if(wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.setDelay(data.delay); + this.limit = data.limit; + this.given = data.given; + this.rewardTime = data.reward_time; + this.uniqueRewards = data.unique_rewards; + this.limitationInterval = data.limit_interval; + this.rewardItems.clear(); + this.rewardItems.addAll(data.rewards); + } + else { + String[] data = wiredData.split(":"); + if (data.length > 0) { + this.limit = Integer.valueOf(data[0]); + this.given = Integer.valueOf(data[1]); + this.rewardTime = Integer.valueOf(data[2]); + this.uniqueRewards = data[3].equals("1"); + this.limitationInterval = Integer.valueOf(data[4]); + this.setDelay(Integer.valueOf(data[5])); - this.rewardItems.clear(); + if (data.length > 6) { + if (!data[6].equalsIgnoreCase("\t")) { + String[] items = data[6].split(";"); - for (String s : items) { - try { - this.rewardItems.add(new WiredGiveRewardItem(s)); - } catch (Exception e) { + this.rewardItems.clear(); + + for (String s : items) { + try { + this.rewardItems.add(new WiredGiveRewardItem(s)); + } catch (Exception e) { + } } } } + + this.needsUpdate(true); } } } @@ -167,8 +176,7 @@ public class WiredEffectGiveReward extends InteractionWiredEffect { @Override public boolean saveData(ClientMessage packet, GameClient gameClient) { if (gameClient.getHabbo().hasPermission(Permission.ACC_SUPERWIRED)) { - packet.readInt(); - + int argsLength = packet.readInt(); this.rewardTime = packet.readInt(); this.uniqueRewards = packet.readInt() == 1; this.limit = packet.readInt(); @@ -196,11 +204,10 @@ public class WiredEffectGiveReward extends InteractionWiredEffect { return false; } - WiredHandler.dropRewards(this.getId()); - - packet.readString(); packet.readInt(); this.setDelay(packet.readInt()); + + WiredHandler.dropRewards(this.getId()); return true; } @@ -217,4 +224,24 @@ public class WiredEffectGiveReward extends InteractionWiredEffect { protected long requiredCooldown() { return 0; } + + static class JsonData { + int limit; + int given; + int reward_time; + boolean unique_rewards; + int limit_interval; + List rewards; + int delay; + + public JsonData(int limit, int given, int reward_time, boolean unique_rewards, int limit_interval, List rewards, int delay) { + this.limit = limit; + this.given = given; + this.reward_time = reward_time; + this.unique_rewards = unique_rewards; + this.limit_interval = limit_interval; + this.rewards = rewards; + this.delay = delay; + } + } } diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveScore.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveScore.java index 91475710..5a326356 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveScore.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveScore.java @@ -1,5 +1,6 @@ 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.games.Game; import com.eu.habbo.habbohotel.items.Item; @@ -9,8 +10,10 @@ 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.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.WiredHandler; import com.eu.habbo.messages.ClientMessage; import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.wired.WiredSaveException; import gnu.trove.iterator.TObjectIntIterator; import gnu.trove.map.TObjectIntMap; import gnu.trove.map.hash.TObjectIntHashMap; @@ -61,7 +64,7 @@ public class WiredEffectGiveScore extends InteractionWiredEffect { if (iterator.value() < this.count) { iterator.setValue(iterator.value() + 1); - habbo.getHabboInfo().getGamePlayer().addScore(this.score); + habbo.getHabboInfo().getGamePlayer().addScore(this.score, true); return true; } @@ -74,7 +77,7 @@ public class WiredEffectGiveScore extends InteractionWiredEffect { this.data.put(new AbstractMap.SimpleEntry<>(game.getStartTime(), habbo.getHabboInfo().getId()), 1); if (habbo.getHabboInfo().getGamePlayer() != null) { - habbo.getHabboInfo().getGamePlayer().addScore(this.score); + habbo.getHabboInfo().getGamePlayer().addScore(this.score, true); } return true; @@ -85,17 +88,29 @@ public class WiredEffectGiveScore extends InteractionWiredEffect { @Override public String getWiredData() { - return this.score + ";" + this.count + ";" + this.getDelay(); + return WiredHandler.getGsonBuilder().create().toJson(new JsonData(this.score, this.count, this.getDelay())); } @Override public void loadWiredData(ResultSet set, Room room) throws SQLException { - String[] data = set.getString("wired_data").split(";"); + String wiredData = set.getString("wired_data"); - if (data.length == 3) { - this.score = Integer.valueOf(data[0]); - this.count = Integer.valueOf(data[1]); - this.setDelay(Integer.valueOf(data[2])); + if(wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.score = data.score; + this.count = data.count; + this.setDelay(data.delay); + } + else { + String[] data = wiredData.split(";"); + + if (data.length == 3) { + this.score = Integer.valueOf(data[0]); + this.count = Integer.valueOf(data[1]); + this.setDelay(Integer.valueOf(data[2])); + } + + this.needsUpdate(true); } } @@ -147,14 +162,30 @@ public class WiredEffectGiveScore extends InteractionWiredEffect { } @Override - public boolean saveData(ClientMessage packet, GameClient gameClient) { + public boolean saveData(ClientMessage packet, GameClient gameClient) throws WiredSaveException { packet.readInt(); - this.score = packet.readInt(); - this.count = packet.readInt(); + int score = packet.readInt(); + + if(score < 1 || score > 100) + throw new WiredSaveException("Score is invalid"); + + int timesPerGame = packet.readInt(); + + if(timesPerGame < 1 || timesPerGame > 10) + throw new WiredSaveException("Times per game is invalid"); + packet.readString(); packet.readInt(); - this.setDelay(packet.readInt()); + + int delay = packet.readInt(); + + if(delay > Emulator.getConfig().getInt("hotel.wired.max_delay", 20)) + throw new WiredSaveException("Delay too long"); + + this.score = score; + this.count = timesPerGame; + this.setDelay(delay); return true; } @@ -163,4 +194,16 @@ public class WiredEffectGiveScore extends InteractionWiredEffect { public boolean requiresTriggeringUser() { return true; } + + static class JsonData { + int score; + int count; + int delay; + + public JsonData(int score, int count, int delay) { + this.score = score; + this.count = count; + this.delay = delay; + } + } } diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveScoreToTeam.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveScoreToTeam.java index 738fc508..dcbc1481 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveScoreToTeam.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveScoreToTeam.java @@ -1,17 +1,20 @@ 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.games.Game; +import com.eu.habbo.habbohotel.games.GameState; import com.eu.habbo.habbohotel.games.GameTeam; import com.eu.habbo.habbohotel.games.GameTeamColors; import com.eu.habbo.habbohotel.items.Item; import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect; 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.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.WiredHandler; import com.eu.habbo.messages.ClientMessage; import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.wired.WiredSaveException; import gnu.trove.map.hash.TIntIntHashMap; import java.sql.ResultSet; @@ -36,49 +39,52 @@ public class WiredEffectGiveScoreToTeam extends InteractionWiredEffect { @Override public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { - Habbo habbo = room.getHabbo(roomUnit); + for (Game game : room.getGames()) { + if (game != null && game.state.equals(GameState.RUNNING)) { + int c = this.startTimes.get(game.getStartTime()); - if (habbo != null) { - Class game = habbo.getHabboInfo().getCurrentGame(); + if (c < this.count) { + GameTeam team = game.getTeam(this.teamColor); - if (game != null) { - Game g = room.getGame(game); + if (team != null) { + team.addTeamScore(this.points); - if (g != null) { - int c = this.startTimes.get(g.getStartTime()); - - if (c < this.count) { - GameTeam team = g.getTeam(this.teamColor); - - if (team != null) { - team.addTeamScore(this.points); - - this.startTimes.put(g.getStartTime(), c++); - - return true; - } + this.startTimes.put(game.getStartTime(), c + 1); } } } } - return false; + return true; } @Override public String getWiredData() { - return this.points + ";" + this.count + ";" + this.teamColor.type + ";" + this.getDelay(); + return WiredHandler.getGsonBuilder().create().toJson(new JsonData(this.points, this.count, this.teamColor, this.getDelay())); } @Override public void loadWiredData(ResultSet set, Room room) throws SQLException { - String[] data = set.getString("wired_data").split(";"); + String wiredData = set.getString("wired_data"); - if (data.length == 4) { - this.points = Integer.valueOf(data[0]); - this.count = Integer.valueOf(data[1]); - this.teamColor = GameTeamColors.values()[Integer.valueOf(data[2])]; - this.setDelay(Integer.valueOf(data[3])); + if(wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.points = data.score; + this.count = data.count; + this.teamColor = data.team; + this.setDelay(data.delay); + } + else { + String[] data = set.getString("wired_data").split(";"); + + if (data.length == 4) { + this.points = Integer.valueOf(data[0]); + this.count = Integer.valueOf(data[1]); + this.teamColor = GameTeamColors.values()[Integer.valueOf(data[2])]; + this.setDelay(Integer.valueOf(data[3])); + } + + this.needsUpdate(true); } } @@ -115,15 +121,51 @@ public class WiredEffectGiveScoreToTeam extends InteractionWiredEffect { } @Override - public boolean saveData(ClientMessage packet, GameClient gameClient) { + public boolean saveData(ClientMessage packet, GameClient gameClient) throws WiredSaveException { packet.readInt(); - this.points = packet.readInt(); - this.count = packet.readInt(); - this.teamColor = GameTeamColors.values()[packet.readInt()]; + int points = packet.readInt(); + + if(points < 1 || points > 100) + throw new WiredSaveException("Points is invalid"); + + int timesPerGame = packet.readInt(); + + if(timesPerGame < 1 || timesPerGame > 10) + throw new WiredSaveException("Times per game is invalid"); + + int team = packet.readInt(); + + if(team < 1 || team > 4) + throw new WiredSaveException("Team is invalid"); + packet.readString(); packet.readInt(); - this.setDelay(packet.readInt()); + + int delay = packet.readInt(); + + if(delay > Emulator.getConfig().getInt("hotel.wired.max_delay", 20)) + throw new WiredSaveException("Delay too long"); + + this.points = points; + this.count = timesPerGame; + this.teamColor = GameTeamColors.values()[team]; + this.setDelay(delay); + return true; } + + static class JsonData { + int score; + int count; + GameTeamColors team; + int delay; + + public JsonData(int score, int count, GameTeamColors team, int delay) { + this.score = score; + this.count = count; + this.team = team; + this.delay = delay; + } + } } diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectJoinTeam.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectJoinTeam.java index 3285865a..8d367009 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectJoinTeam.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectJoinTeam.java @@ -1,6 +1,8 @@ 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.games.Game; import com.eu.habbo.habbohotel.games.GameTeamColors; import com.eu.habbo.habbohotel.games.wired.WiredGame; import com.eu.habbo.habbohotel.items.Item; @@ -10,8 +12,10 @@ 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.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.WiredHandler; import com.eu.habbo.messages.ClientMessage; import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.wired.WiredSaveException; import gnu.trove.procedure.TObjectProcedure; import java.sql.ResultSet; @@ -37,16 +41,19 @@ public class WiredEffectJoinTeam extends InteractionWiredEffect { Habbo habbo = room.getHabbo(roomUnit); if (habbo != null) { - if (habbo.getHabboInfo().getGamePlayer() == null) { - WiredGame game = (WiredGame) room.getGame(WiredGame.class); + WiredGame game = (WiredGame) room.getGameOrCreate(WiredGame.class); - if (game == null) { - game = new WiredGame(room); - room.addGame(game); - } - - return game.addHabbo(habbo, this.teamColor); + if (habbo.getHabboInfo().getGamePlayer() != null && habbo.getHabboInfo().getCurrentGame() != null && (habbo.getHabboInfo().getCurrentGame() != WiredGame.class || (habbo.getHabboInfo().getCurrentGame() == WiredGame.class && habbo.getHabboInfo().getGamePlayer().getTeamColor() != this.teamColor))) { + // remove from current game + Game currentGame = room.getGame(habbo.getHabboInfo().getCurrentGame()); + currentGame.removeHabbo(habbo); } + + if(habbo.getHabboInfo().getGamePlayer() == null) { + game.addHabbo(habbo, this.teamColor); + } + + return true; } return false; @@ -54,19 +61,30 @@ public class WiredEffectJoinTeam extends InteractionWiredEffect { @Override public String getWiredData() { - return this.getDelay() + "\t" + this.teamColor.type + ""; + return WiredHandler.getGsonBuilder().create().toJson(new JsonData(this.teamColor, this.getDelay())); } @Override public void loadWiredData(ResultSet set, Room room) throws SQLException { - String[] data = set.getString("wired_data").split("\t"); + String wiredData = set.getString("wired_data"); - if (data.length >= 1) { - this.setDelay(Integer.valueOf(data[0])); + if(wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.setDelay(data.delay); + this.teamColor = data.team; + } + else { + String[] data = set.getString("wired_data").split("\t"); - if (data.length >= 2) { - this.teamColor = GameTeamColors.values()[Integer.valueOf(data[1])]; + if (data.length >= 1) { + this.setDelay(Integer.valueOf(data[0])); + + if (data.length >= 2) { + this.teamColor = GameTeamColors.values()[Integer.valueOf(data[1])]; + } } + + this.needsUpdate(true); } } @@ -116,12 +134,22 @@ public class WiredEffectJoinTeam extends InteractionWiredEffect { } @Override - public boolean saveData(ClientMessage packet, GameClient gameClient) { + public boolean saveData(ClientMessage packet, GameClient gameClient) throws WiredSaveException { + packet.readInt(); + int team = packet.readInt(); + + if(team < 1 || team > 4) + throw new WiredSaveException("Team is invalid"); + packet.readInt(); - this.teamColor = GameTeamColors.values()[packet.readInt()]; - int unknownInt = packet.readInt(); packet.readString(); - this.setDelay(packet.readInt()); + int delay = packet.readInt(); + + if(delay > Emulator.getConfig().getInt("hotel.wired.max_delay", 20)) + throw new WiredSaveException("Delay too long"); + + this.teamColor = GameTeamColors.values()[team]; + this.setDelay(delay); return true; } @@ -130,4 +158,14 @@ public class WiredEffectJoinTeam extends InteractionWiredEffect { public boolean requiresTriggeringUser() { return true; } + + static class JsonData { + GameTeamColors team; + int delay; + + public JsonData(GameTeamColors team, int delay) { + this.team = team; + this.delay = delay; + } + } } diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectKickHabbo.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectKickHabbo.java index 72897ebf..e0f2ecd2 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectKickHabbo.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectKickHabbo.java @@ -12,8 +12,10 @@ import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; import com.eu.habbo.habbohotel.rooms.RoomUnit; import com.eu.habbo.habbohotel.users.Habbo; import com.eu.habbo.habbohotel.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.WiredHandler; import com.eu.habbo.messages.ClientMessage; import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.wired.WiredSaveException; import com.eu.habbo.messages.outgoing.rooms.users.RoomUserWhisperComposer; import com.eu.habbo.threading.runnables.RoomUnitKick; import gnu.trove.procedure.TObjectProcedure; @@ -69,24 +71,35 @@ public class WiredEffectKickHabbo extends InteractionWiredEffect { @Override public String getWiredData() { - return this.getDelay() + "\t" + this.message; + return WiredHandler.getGsonBuilder().create().toJson(new JsonData(this.message, this.getDelay())); } @Override public void loadWiredData(ResultSet set, Room room) throws SQLException { - try { - String[] data = set.getString("wired_data").split("\t"); + String wiredData = set.getString("wired_data"); - if (data.length >= 1) { - this.setDelay(Integer.valueOf(data[0])); + if(wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.setDelay(data.delay); + this.message = data.message; + } + else { + try { + String[] data = set.getString("wired_data").split("\t"); - if (data.length >= 2) { - this.message = data[1]; + if (data.length >= 1) { + this.setDelay(Integer.valueOf(data[0])); + + if (data.length >= 2) { + this.message = data[1]; + } } + } catch (Exception e) { + this.message = ""; + this.setDelay(0); } - } catch (Exception e) { - this.message = ""; - this.setDelay(0); + + this.needsUpdate(true); } } @@ -135,11 +148,17 @@ public class WiredEffectKickHabbo extends InteractionWiredEffect { } @Override - public boolean saveData(ClientMessage packet, GameClient gameClient) { + public boolean saveData(ClientMessage packet, GameClient gameClient) throws WiredSaveException { packet.readInt(); - this.message = packet.readString(); + String message = packet.readString(); packet.readInt(); - this.setDelay(packet.readInt()); + int delay = packet.readInt(); + + if(delay > Emulator.getConfig().getInt("hotel.wired.max_delay", 20)) + throw new WiredSaveException("Delay too long"); + + this.message = message.substring(0, Math.min(message.length(), Emulator.getConfig().getInt("hotel.wired.message.max_length", 100))); + this.setDelay(delay); return true; } @@ -148,4 +167,14 @@ public class WiredEffectKickHabbo extends InteractionWiredEffect { public boolean requiresTriggeringUser() { return true; } + + static class JsonData { + String message; + int delay; + + public JsonData(String message, int delay) { + this.message = message; + this.delay = delay; + } + } } diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectLeaveTeam.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectLeaveTeam.java index 248adcda..deff061e 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectLeaveTeam.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectLeaveTeam.java @@ -1,5 +1,6 @@ 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.games.Game; import com.eu.habbo.habbohotel.games.wired.WiredGame; @@ -10,8 +11,10 @@ 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.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.WiredHandler; import com.eu.habbo.messages.ClientMessage; import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.wired.WiredSaveException; import gnu.trove.procedure.TObjectProcedure; import java.sql.ResultSet; @@ -39,7 +42,7 @@ public class WiredEffectLeaveTeam extends InteractionWiredEffect { Game game = room.getGame(habbo.getHabboInfo().getCurrentGame()); if (game == null) { - game = room.getGame(WiredGame.class); + game = room.getGameOrCreate(WiredGame.class); } if (game != null) { @@ -53,12 +56,20 @@ public class WiredEffectLeaveTeam extends InteractionWiredEffect { @Override public String getWiredData() { - return this.getDelay() + ""; + return WiredHandler.getGsonBuilder().create().toJson(new JsonData(this.getDelay())); } @Override public void loadWiredData(ResultSet set, Room room) throws SQLException { - this.setDelay(Integer.valueOf(set.getString("wired_data"))); + String wiredData = set.getString("wired_data"); + + if(wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.setDelay(data.delay); + } + else { + this.setDelay(Integer.valueOf(wiredData)); + } } @Override @@ -105,11 +116,24 @@ public class WiredEffectLeaveTeam extends InteractionWiredEffect { } @Override - public boolean saveData(ClientMessage packet, GameClient gameClient) { + public boolean saveData(ClientMessage packet, GameClient gameClient) throws WiredSaveException { packet.readInt(); packet.readString(); packet.readInt(); - this.setDelay(packet.readInt()); + int delay = packet.readInt(); + + if(delay > Emulator.getConfig().getInt("hotel.wired.max_delay", 20)) + throw new WiredSaveException("Delay too long"); + + this.setDelay(delay); return true; } + + static class JsonData { + int delay; + + public JsonData(int delay) { + this.delay = delay; + } + } } diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectMatchFurni.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectMatchFurni.java index 251bc2a5..fbd374d4 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectMatchFurni.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectMatchFurni.java @@ -2,19 +2,17 @@ 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.games.GameTeamColors; import com.eu.habbo.habbohotel.items.Item; -import com.eu.habbo.habbohotel.items.interactions.InteractionRoller; import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect; -import com.eu.habbo.habbohotel.rooms.Room; -import com.eu.habbo.habbohotel.rooms.RoomTile; -import com.eu.habbo.habbohotel.rooms.RoomTileState; -import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.rooms.*; import com.eu.habbo.habbohotel.users.HabboItem; import com.eu.habbo.habbohotel.wired.WiredEffectType; import com.eu.habbo.habbohotel.wired.WiredHandler; import com.eu.habbo.habbohotel.wired.WiredMatchFurniSetting; import com.eu.habbo.messages.ClientMessage; import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.wired.WiredSaveException; import com.eu.habbo.messages.outgoing.rooms.items.FloorItemOnRollerComposer; import gnu.trove.set.hash.THashSet; import org.slf4j.Logger; @@ -22,6 +20,9 @@ import org.slf4j.LoggerFactory; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Pattern; public class WiredEffectMatchFurni extends InteractionWiredEffect { private static final Logger LOGGER = LoggerFactory.getLogger(WiredEffectMatchFurni.class); @@ -45,163 +46,94 @@ public class WiredEffectMatchFurni extends InteractionWiredEffect { @Override public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { - THashSet tilesToUpdate = new THashSet<>(this.settings.size()); - //this.refresh(); if(this.settings.isEmpty()) - return false; + return true; for (WiredMatchFurniSetting setting : this.settings) { - HabboItem item = room.getHabboItem(setting.itemId); + HabboItem item = room.getHabboItem(setting.item_id); if (item != null) { if (this.state && (this.checkForWiredResetPermission && item.allowWiredResetState())) { - if (!setting.state.equals(" ")) { + if (!setting.state.equals(" ") && !item.getExtradata().equals(setting.state)) { item.setExtradata(setting.state); - tilesToUpdate.addAll(room.getLayout().getTilesAt(room.getLayout().getTile(item.getX(), item.getY()), item.getBaseItem().getWidth(), item.getBaseItem().getLength(), item.getRotation())); + room.updateItemState(item); } } - int oldRotation = item.getRotation(); - boolean slideAnimation = true; - double offsetZ = 0; + RoomTile oldLocation = room.getLayout().getTile(item.getX(), item.getY()); + double oldZ = item.getZ(); - if (this.direction && item.getRotation() != setting.rotation) { - item.setRotation(setting.rotation); - slideAnimation = false; - - room.scheduledTasks.add(() -> { - room.getLayout().getTilesAt(room.getLayout().getTile(item.getX(), item.getY()), item.getBaseItem().getWidth(), item.getBaseItem().getLength(), oldRotation).forEach(t -> { - room.updateBotsAt(t.x, t.y); - room.updateHabbosAt(t.x, t.y); - }); - room.getLayout().getTilesAt(room.getLayout().getTile(item.getX(), item.getY()), item.getBaseItem().getWidth(), item.getBaseItem().getLength(), setting.rotation).forEach(t -> { - room.updateBotsAt(t.x, t.y); - room.updateHabbosAt(t.x, t.y); - }); - }); + if(this.direction && !this.position) { + if(item.getRotation() != setting.rotation && room.furnitureFitsAt(oldLocation, item, setting.rotation, false) == FurnitureMovementError.NONE) { + room.moveFurniTo(item, oldLocation, setting.rotation, null, true); + } } + else if(this.position) { + boolean slideAnimation = !this.direction || item.getRotation() == setting.rotation; + RoomTile newLocation = room.getLayout().getTile((short) setting.x, (short) setting.y); + int newRotation = this.direction ? setting.rotation : item.getRotation(); - RoomTile t = null; - - if (this.position) { - t = room.getLayout().getTile((short) setting.x, (short) setting.y); - - if (t != null && t.state != RoomTileState.INVALID) { - boolean canMove = true; - - if (t.x == item.getX() && t.y == item.getY() || room.hasHabbosAt(t.x, t.y)) { - canMove = !(room.getTopItemAt(t.x, t.y) == item); - slideAnimation = false; - } - - - if (canMove && !room.hasHabbosAt(t.x, t.y)) { - THashSet tiles = room.getLayout().getTilesAt(t, item.getBaseItem().getWidth(), item.getBaseItem().getLength(), setting.rotation); - double highestZ = -1d; - for (RoomTile tile : tiles) { - if (tile.state == RoomTileState.INVALID) { - highestZ = -1d; - break; - } - - if (item instanceof InteractionRoller && room.hasItemsAt(tile.x, tile.y)) { - highestZ = -1d; - break; - } - - double stackHeight = room.getStackHeight(tile.x, tile.y, false, item); - if (stackHeight > highestZ) { - highestZ = stackHeight; - } - } - - if (highestZ != -1d) { - tilesToUpdate.addAll(tiles); - - offsetZ = highestZ - item.getZ(); - double totalHeight = item.getZ() + offsetZ; - if (totalHeight > 40) break; - tilesToUpdate.addAll(room.getLayout().getTilesAt(room.getLayout().getTile(item.getX(), item.getY()), item.getBaseItem().getWidth(), item.getBaseItem().getLength(), oldRotation)); - - if (!slideAnimation) { - item.setX(t.x); - item.setY(t.y); - } + if(newLocation != null && newLocation.state != RoomTileState.INVALID && (newLocation != oldLocation || newRotation != item.getRotation()) && room.furnitureFitsAt(newLocation, item, newRotation, true) == FurnitureMovementError.NONE) { + if(room.moveFurniTo(item, newLocation, newRotation, null, !slideAnimation) == FurnitureMovementError.NONE) { + if(slideAnimation) { + room.sendComposer(new FloorItemOnRollerComposer(item, null, oldLocation, oldZ, newLocation, item.getZ(), 0, room).compose()); } } } } - if (slideAnimation && t != null) { - room.sendComposer(new FloorItemOnRollerComposer(item, null, t, offsetZ, room).compose()); - } else { - room.updateItem(item); - } - - item.needsUpdate(true); } } - room.updateTiles(tilesToUpdate); - return true; } @Override public String getWiredData() { this.refresh(); - - StringBuilder data = new StringBuilder(this.settings.size() + ":"); - - if (this.settings.isEmpty()) { - data.append(";"); - } else { - Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()); - - for (WiredMatchFurniSetting item : this.settings) { - HabboItem i; - - if (room != null) { - i = room.getHabboItem(item.itemId); - - if (i != null) { - data.append(item.toString(this.checkForWiredResetPermission && i.allowWiredResetState())).append(";"); - } - } - } - } - - data.append(":").append(this.state ? 1 : 0).append(":").append(this.direction ? 1 : 0).append(":").append(this.position ? 1 : 0).append(":").append(this.getDelay()); - - return data.toString(); + return WiredHandler.getGsonBuilder().create().toJson(new JsonData(this.state, this.direction, this.position, new ArrayList(this.settings), this.getDelay())); } @Override public void loadWiredData(ResultSet set, Room room) throws SQLException { - String[] data = set.getString("wired_data").split(":"); + String wiredData = set.getString("wired_data"); - int itemCount = Integer.valueOf(data[0]); - - String[] items = data[1].split(";"); - - for (int i = 0; i < items.length; i++) { - try { - - String[] stuff = items[i].split("-"); - - if (stuff.length >= 5) { - this.settings.add(new WiredMatchFurniSetting(Integer.valueOf(stuff[0]), stuff[1], Integer.valueOf(stuff[2]), Integer.valueOf(stuff[3]), Integer.valueOf(stuff[4]))); - } - - } catch (Exception e) { - LOGGER.error("Caught exception", e); - } + if(wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.setDelay(data.delay); + this.state = data.state; + this.direction = data.direction; + this.position = data.position; + this.settings.clear(); + this.settings.addAll(data.items); } + else { + String[] data = set.getString("wired_data").split(":"); - this.state = data[2].equals("1"); - this.direction = data[3].equals("1"); - this.position = data[4].equals("1"); - this.setDelay(Integer.valueOf(data[5])); + int itemCount = Integer.parseInt(data[0]); + + String[] items = data[1].split(Pattern.quote(";")); + + for (int i = 0; i < items.length; i++) { + try { + + String[] stuff = items[i].split(Pattern.quote("-")); + + if (stuff.length >= 5) { + this.settings.add(new WiredMatchFurniSetting(Integer.parseInt(stuff[0]), stuff[1], Integer.parseInt(stuff[2]), Integer.parseInt(stuff[3]), Integer.parseInt(stuff[4]))); + } + + } catch (Exception e) { + LOGGER.error("Caught exception", e); + } + } + + this.state = data[2].equals("1"); + this.direction = data[3].equals("1"); + this.position = data[4].equals("1"); + this.setDelay(Integer.parseInt(data[5])); + this.needsUpdate(true); + } } @Override @@ -227,7 +159,7 @@ public class WiredEffectMatchFurni extends InteractionWiredEffect { message.appendInt(this.settings.size()); for (WiredMatchFurniSetting item : this.settings) - message.appendInt(item.itemId); + message.appendInt(item.item_id); message.appendInt(this.getBaseItem().getSpriteId()); message.appendInt(this.getId()); @@ -243,34 +175,49 @@ public class WiredEffectMatchFurni extends InteractionWiredEffect { } @Override - public boolean saveData(ClientMessage packet, GameClient gameClient) { + public boolean saveData(ClientMessage packet, GameClient gameClient) throws WiredSaveException { packet.readInt(); - this.state = packet.readInt() == 1; - this.direction = packet.readInt() == 1; - this.position = packet.readInt() == 1; + boolean setState = packet.readInt() == 1; + boolean setDirection = packet.readInt() == 1; + boolean setPosition = packet.readInt() == 1; packet.readString(); Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()); if (room == null) - return true; + throw new WiredSaveException("Trying to save wired in unloaded room"); - int count = packet.readInt(); - if (count > Emulator.getConfig().getInt("hotel.wired.furni.selection.count")) return false; + int itemsCount = packet.readInt(); - this.settings.clear(); - - for (int i = 0; i < count; i++) { - int itemId = packet.readInt(); - HabboItem item = room.getHabboItem(itemId); - - if (item != null) - this.settings.add(new WiredMatchFurniSetting(item.getId(), this.checkForWiredResetPermission && item.allowWiredResetState() ? item.getExtradata() : " ", item.getRotation(), item.getX(), item.getY())); + if(itemsCount > Emulator.getConfig().getInt("hotel.wired.furni.selection.count")) { + throw new WiredSaveException("Too many furni selected"); } - this.setDelay(packet.readInt()); + List newSettings = new ArrayList<>(); + + for (int i = 0; i < itemsCount; i++) { + int itemId = packet.readInt(); + HabboItem it = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(itemId); + + if(it == null) + throw new WiredSaveException(String.format("Item %s not found", itemId)); + + newSettings.add(new WiredMatchFurniSetting(it.getId(), this.checkForWiredResetPermission && it.allowWiredResetState() ? it.getExtradata() : " ", it.getRotation(), it.getX(), it.getY())); + } + + int delay = packet.readInt(); + + if(delay > Emulator.getConfig().getInt("hotel.wired.max_delay", 20)) + throw new WiredSaveException("Delay too long"); + + this.state = setState; + this.direction = setDirection; + this.position = setPosition; + this.settings.clear(); + this.settings.addAll(newSettings); + this.setDelay(delay); return true; } @@ -282,7 +229,7 @@ public class WiredEffectMatchFurni extends InteractionWiredEffect { THashSet remove = new THashSet<>(); for (WiredMatchFurniSetting setting : this.settings) { - HabboItem item = room.getHabboItem(setting.itemId); + HabboItem item = room.getHabboItem(setting.item_id); if (item == null) { remove.add(setting); } @@ -293,4 +240,20 @@ public class WiredEffectMatchFurni extends InteractionWiredEffect { } } } + + static class JsonData { + boolean state; + boolean direction; + boolean position; + List items; + int delay; + + public JsonData(boolean state, boolean direction, boolean position, List items, int delay) { + this.state = state; + this.direction = direction; + this.position = position; + this.items = items; + this.delay = delay; + } + } } diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectMoveFurniAway.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectMoveFurniAway.java index 23414d94..9efd0a32 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectMoveFurniAway.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectMoveFurniAway.java @@ -12,11 +12,15 @@ import com.eu.habbo.habbohotel.wired.WiredHandler; import com.eu.habbo.habbohotel.wired.WiredTriggerType; import com.eu.habbo.messages.ClientMessage; import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.wired.WiredSaveException; import com.eu.habbo.messages.outgoing.rooms.items.FloorItemOnRollerComposer; import gnu.trove.set.hash.THashSet; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; public class WiredEffectMoveFurniAway extends InteractionWiredEffect { public static final WiredEffectType type = WiredEffectType.FLEE; @@ -44,64 +48,47 @@ public class WiredEffectMoveFurniAway extends InteractionWiredEffect { for (HabboItem item : this.items) { RoomTile t = room.getLayout().getTile(item.getX(), item.getY()); - double shortest = 1000.0D; - Habbo target = null; - - for (Habbo habbo : room.getHabbos()) { - if (habbo.getRoomUnit().getCurrentLocation().distance(t) <= shortest) { - shortest = habbo.getRoomUnit().getCurrentLocation().distance(t); - target = habbo; - } - } + RoomUnit target = room.getRoomUnits().stream().min(Comparator.comparingDouble(a -> a.getCurrentLocation().distance(t))).orElse(null); if (target != null) { - if (RoomLayout.tilesAdjecent(target.getRoomUnit().getCurrentLocation(), room.getLayout().getTile(item.getX(), item.getY())) && (target.getRoomUnit().getX() == item.getX() || target.getRoomUnit().getY() == item.getY())) { - final Habbo finalTarget = target; - Emulator.getThreading().run(() -> WiredHandler.handle(WiredTriggerType.COLLISION, finalTarget.getRoomUnit(), room, new Object[]{item}), 500); - + if (target.getCurrentLocation().distance(t) <= 1) { + Emulator.getThreading().run(() -> WiredHandler.handle(WiredTriggerType.COLLISION, target, room, new Object[]{item}), 500); continue; } int x = 0; int y = 0; - if (target.getRoomUnit().getX() == item.getX()) { - if (item.getY() < target.getRoomUnit().getY()) + if (target.getX() == item.getX()) { + if (item.getY() < target.getY()) y--; else y++; - } else if (target.getRoomUnit().getY() == item.getY()) { - if (item.getX() < target.getRoomUnit().getX()) + } else if (target.getY() == item.getY()) { + if (item.getX() < target.getX()) x--; else x++; - } else if (target.getRoomUnit().getX() - item.getX() > target.getRoomUnit().getY() - item.getY()) { - if (target.getRoomUnit().getX() - item.getX() > 0) + } else if (target.getX() - item.getX() > target.getY() - item.getY()) { + if (target.getX() - item.getX() > 0) x--; else x++; } else { - if (target.getRoomUnit().getY() - item.getY() > 0) + if (target.getY() - item.getY() > 0) y--; else y++; } - RoomTile newTile = room.getLayout().getTile((short) (item.getX() + x), (short) (item.getY() + y)); + RoomTile newLocation = room.getLayout().getTile((short) (item.getX() + x), (short) (item.getY() + y)); + RoomTile oldLocation = room.getLayout().getTile(item.getX(), item.getY()); + double oldZ = item.getZ(); - if (newTile != null && newTile.state == RoomTileState.OPEN) { - if (room.getLayout().tileExists(newTile.x, newTile.y)) { - HabboItem topItem = room.getTopItemAt(newTile.x, newTile.y); - - if (topItem == null || topItem.getBaseItem().allowStack()) { - double offsetZ = 0; - - if (topItem != null) - offsetZ = topItem.getZ() + topItem.getBaseItem().getHeight() - item.getZ(); - - room.sendComposer(new FloorItemOnRollerComposer(item, null, newTile, offsetZ, room).compose()); - } + if(newLocation != null && newLocation.state != RoomTileState.INVALID && newLocation != oldLocation && room.furnitureFitsAt(newLocation, item, item.getRotation(), true) == FurnitureMovementError.NONE) { + if(room.moveFurniTo(item, newLocation, item.getRotation(), null, false) == FurnitureMovementError.NONE) { + room.sendComposer(new FloorItemOnRollerComposer(item, null, oldLocation, oldZ, newLocation, item.getZ(), 0, room).compose()); } } } @@ -182,20 +169,35 @@ public class WiredEffectMoveFurniAway extends InteractionWiredEffect { } @Override - public boolean saveData(ClientMessage packet, GameClient gameClient) { + public boolean saveData(ClientMessage packet, GameClient gameClient) throws WiredSaveException { packet.readInt(); packet.readString(); + int itemsCount = packet.readInt(); - int count = packet.readInt(); - if (count > Emulator.getConfig().getInt("hotel.wired.furni.selection.count")) return false; - - this.items.clear(); - - for (int i = 0; i < count; i++) { - this.items.add(Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(packet.readInt())); + if(itemsCount > Emulator.getConfig().getInt("hotel.wired.furni.selection.count")) { + throw new WiredSaveException("Too many furni selected"); } - this.setDelay(packet.readInt()); + List newItems = new ArrayList<>(); + + for (int i = 0; i < itemsCount; i++) { + int itemId = packet.readInt(); + HabboItem it = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(itemId); + + if(it == null) + throw new WiredSaveException(String.format("Item %s not found", itemId)); + + newItems.add(it); + } + + int delay = packet.readInt(); + + 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; } diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectMoveFurniTowards.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectMoveFurniTowards.java index 31f692d6..454b3216 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectMoveFurniTowards.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectMoveFurniTowards.java @@ -11,6 +11,7 @@ import com.eu.habbo.habbohotel.wired.WiredEffectType; import com.eu.habbo.habbohotel.wired.WiredHandler; import com.eu.habbo.messages.ClientMessage; import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.wired.WiredSaveException; import com.eu.habbo.messages.outgoing.rooms.items.FloorItemOnRollerComposer; import com.eu.habbo.threading.runnables.WiredCollissionRunnable; import gnu.trove.map.hash.THashMap; @@ -19,6 +20,7 @@ import gnu.trove.set.hash.THashSet; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; +import java.util.Collection; import java.util.List; /** @@ -128,7 +130,7 @@ public class WiredEffectMoveFurniTowards extends InteractionWiredEffect { } if (startTile != null && layout.tileExists(startTile.x, startTile.y)) { - THashSet roomUnitsAtTile = room.getHabbosAndBotsAt(startTile.x, startTile.y); + Collection roomUnitsAtTile = room.getRoomUnitsAt(startTile); if (roomUnitsAtTile.size() > 0) { target = roomUnitsAtTile.iterator().next(); if (i == 0) { // i = 0 means right next to it @@ -213,13 +215,15 @@ public class WiredEffectMoveFurniTowards extends InteractionWiredEffect { RoomTile newTile = room.getLayout().getTileInFront(room.getLayout().getTile(item.getX(), item.getY()), moveDirection.getValue()); - if (newTile != null) { - lastDirections.put(item.getId(), moveDirection); + RoomTile oldLocation = room.getLayout().getTile(item.getX(), item.getY()); + double oldZ = item.getZ(); - FurnitureMovementError error = room.furnitureFitsAt(newTile, item, item.getRotation()); - if (error == FurnitureMovementError.NONE) { - double offset = room.getStackHeight(newTile.x, newTile.y, false, item) - item.getZ(); - room.sendComposer(new FloorItemOnRollerComposer(item, null, newTile, offset, room).compose()); + if(newTile != null) { + lastDirections.put(item.getId(), moveDirection); + if(newTile.state != RoomTileState.INVALID && newTile != oldLocation && room.furnitureFitsAt(newTile, item, item.getRotation(), true) == FurnitureMovementError.NONE) { + if (room.moveFurniTo(item, newTile, item.getRotation(), null, false) == FurnitureMovementError.NONE) { + room.sendComposer(new FloorItemOnRollerComposer(item, null, oldLocation, oldZ, newTile, item.getZ(), 0, room).compose()); + } } } } @@ -300,20 +304,36 @@ public class WiredEffectMoveFurniTowards extends InteractionWiredEffect { } @Override - public boolean saveData(ClientMessage packet, GameClient gameClient) { + public boolean saveData(ClientMessage packet, GameClient gameClient) throws WiredSaveException { packet.readInt(); packet.readString(); - int count = packet.readInt(); - if (count > Emulator.getConfig().getInt("hotel.wired.furni.selection.count")) return false; + int itemsCount = packet.readInt(); - this.items.clear(); - - for (int i = 0; i < count; i++) { - this.items.add(Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(packet.readInt())); + if(itemsCount > Emulator.getConfig().getInt("hotel.wired.furni.selection.count")) { + throw new WiredSaveException("Too many furni selected"); } - this.setDelay(packet.readInt()); + List newItems = new ArrayList<>(); + + for (int i = 0; i < itemsCount; i++) { + int itemId = packet.readInt(); + HabboItem it = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(itemId); + + if(it == null) + throw new WiredSaveException(String.format("Item %s not found", itemId)); + + newItems.add(it); + } + + int delay = packet.readInt(); + + 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; } diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectMoveRotateFurni.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectMoveRotateFurni.java index f3d3e2ee..d933aaae 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectMoveRotateFurni.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectMoveRotateFurni.java @@ -2,31 +2,25 @@ 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.ICycleable; import com.eu.habbo.habbohotel.items.Item; -import com.eu.habbo.habbohotel.items.interactions.InteractionRoller; import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect; import com.eu.habbo.habbohotel.rooms.*; -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.WiredHandler; -import com.eu.habbo.habbohotel.wired.WiredTriggerType; import com.eu.habbo.messages.ClientMessage; import com.eu.habbo.messages.ServerMessage; import com.eu.habbo.messages.outgoing.rooms.items.FloorItemOnRollerComposer; -import com.eu.habbo.messages.outgoing.rooms.items.FloorItemUpdateComposer; import gnu.trove.set.hash.THashSet; -import org.apache.commons.math3.util.Pair; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.awt.*; import java.sql.ResultSet; import java.sql.SQLException; -import java.util.ArrayList; - -public class WiredEffectMoveRotateFurni extends InteractionWiredEffect { +import java.util.Iterator; +public class WiredEffectMoveRotateFurni extends InteractionWiredEffect implements ICycleable { private static final Logger LOGGER = LoggerFactory.getLogger(WiredEffectMoveRotateFurni.class); @@ -34,13 +28,16 @@ public class WiredEffectMoveRotateFurni extends InteractionWiredEffect { private final THashSet items = new THashSet<>(WiredHandler.MAXIMUM_FURNI_SELECTION / 2); private int direction; private int rotation; + private THashSet itemCooldowns; public WiredEffectMoveRotateFurni(ResultSet set, Item baseItem) throws SQLException { super(set, baseItem); + this.itemCooldowns = new THashSet<>(); } public WiredEffectMoveRotateFurni(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { super(id, userId, item, extradata, limitedStack, limitedSells); + this.itemCooldowns = new THashSet<>(); } @Override @@ -48,120 +45,36 @@ public class WiredEffectMoveRotateFurni extends InteractionWiredEffect { // remove items that are no longer in the room this.items.removeIf(item -> Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null); - THashSet tilesToUpdate = new THashSet<>(Math.min(this.items.size(), 10)); - for (HabboItem item : this.items) { - //Handle rotation - if (this.rotation > 0) { - tilesToUpdate.addAll(room.getLayout().getTilesAt(room.getLayout().getTile(item.getX(), item.getY()), item.getBaseItem().getWidth(), item.getBaseItem().getLength(), item.getRotation())); - int newRotation = this.getNewRotation(item); + if(this.itemCooldowns.contains(item)) + continue; - //Verify if rotation result in a valid position - FurnitureMovementError rotateError = room.furnitureFitsAt(room.getLayout().getTile(item.getX(), item.getY()), item, newRotation); - if (item.getRotation() != newRotation && (rotateError.equals(FurnitureMovementError.TILE_HAS_HABBOS) || rotateError.equals(FurnitureMovementError.TILE_HAS_PETS) || - rotateError.equals(FurnitureMovementError.TILE_HAS_BOTS) || rotateError.equals(FurnitureMovementError.NONE))) { - item.setRotation(newRotation); - if (this.direction == 0) { - tilesToUpdate.addAll(room.getLayout().getTilesAt(room.getLayout().getTile(item.getX(), item.getY()), item.getBaseItem().getWidth(), item.getBaseItem().getLength(), item.getRotation())); - room.sendComposer(new FloorItemUpdateComposer(item).compose()); - for (RoomTile t : tilesToUpdate) { - room.updateHabbosAt(t.x, t.y); - room.updateBotsAt(t.x, t.y); - } - } - } - } + int newRotation = this.rotation > 0 ? this.getNewRotation(item) : item.getRotation(); + RoomTile newLocation = room.getLayout().getTile(item.getX(), item.getY()); + RoomTile oldLocation = room.getLayout().getTile(item.getX(), item.getY()); + double oldZ = item.getZ(); - //handle movement - if (this.direction > 0) { + if(this.direction > 0) { RoomUserRotation moveDirection = this.getMovementDirection(); - boolean validMove; - RoomLayout layout = room.getLayout(); - if (layout == null) return false; - - RoomTile newTile = layout.getTile( - (short) (item.getX() + ((moveDirection == RoomUserRotation.WEST || moveDirection == RoomUserRotation.NORTH_WEST || moveDirection == RoomUserRotation.SOUTH_WEST) ? -1 : (((moveDirection == RoomUserRotation.EAST || moveDirection == RoomUserRotation.SOUTH_EAST || moveDirection == RoomUserRotation.NORTH_EAST) ? 1 : 0)))), - (short) (item.getY() + ((moveDirection == RoomUserRotation.NORTH || moveDirection == RoomUserRotation.NORTH_EAST || moveDirection == RoomUserRotation.NORTH_WEST) ? 1 : ((moveDirection == RoomUserRotation.SOUTH || moveDirection == RoomUserRotation.SOUTH_EAST || moveDirection == RoomUserRotation.SOUTH_WEST) ? -1 : 0))) + newLocation = room.getLayout().getTile( + (short) (item.getX() + ((moveDirection == RoomUserRotation.WEST || moveDirection == RoomUserRotation.NORTH_WEST || moveDirection == RoomUserRotation.SOUTH_WEST) ? -1 : (((moveDirection == RoomUserRotation.EAST || moveDirection == RoomUserRotation.SOUTH_EAST || moveDirection == RoomUserRotation.NORTH_EAST) ? 1 : 0)))), + (short) (item.getY() + ((moveDirection == RoomUserRotation.NORTH || moveDirection == RoomUserRotation.NORTH_EAST || moveDirection == RoomUserRotation.NORTH_WEST) ? 1 : ((moveDirection == RoomUserRotation.SOUTH || moveDirection == RoomUserRotation.SOUTH_EAST || moveDirection == RoomUserRotation.SOUTH_WEST) ? -1 : 0))) ); + } - if (newTile != null) { - boolean hasRoomUnits = false; - for (RoomUnit _roomUnit : room.getHabbosAndBotsAt(newTile)) { - hasRoomUnits = true; - WiredHandler.handle(WiredTriggerType.COLLISION, _roomUnit, room, new Object[]{item}); - } + boolean slideAnimation = item.getRotation() == newRotation; - if (!hasRoomUnits && room.getStackHeight(newTile.x, newTile.y, true, item) != Short.MAX_VALUE) { - java.awt.Rectangle rectangle = new Rectangle(newTile.x, - newTile.y, - item.getBaseItem().getWidth(), - item.getBaseItem().getLength()); - - double offset = -Short.MAX_VALUE; - validMove = true; - for (short x = (short) rectangle.x; x < rectangle.x + rectangle.getWidth(); x++) { - if (!validMove) { - break; - } - - for (short y = (short) rectangle.y; y < rectangle.y + rectangle.getHeight(); y++) { - RoomTile tile = layout.getTile(x, y); - if (tile == null || tile.state == RoomTileState.INVALID || !tile.getAllowStack()) { - validMove = false; - break; - } - - THashSet itemsAtNewTile = room.getItemsAt(tile); - if (item instanceof InteractionRoller && !itemsAtNewTile.isEmpty()) { - validMove = false; - break; - } - - ArrayList>> tileItems = new ArrayList<>(rectangle.width * rectangle.height); - tileItems.add(Pair.create(tile, itemsAtNewTile)); - if (!item.canStackAt(room, tileItems)) { - validMove = false; - break; - } - - HabboItem i = room.getTopItemAt(x, y, item); - if (i != null && !i.getBaseItem().allowStack()) { - validMove = false; - break; - } - - offset = Math.max(room.getStackHeight(newTile.x, newTile.y, false, item) - item.getZ(), offset); - - tilesToUpdate.add(tile); - } - } - if (item.getZ() + offset > 40) { - offset = 40 - item.getZ(); - } - - if (validMove) { - if (this.rotation > 0) { - item.setX(newTile.x); - item.setY(newTile.y); - item.setZ(item.getZ() + offset); - room.sendComposer(new FloorItemUpdateComposer(item).compose()); - for (RoomTile t : tilesToUpdate) { - room.updateHabbosAt(t.x, t.y); - room.updateBotsAt(t.x, t.y); - } - } else { - room.sendComposer(new FloorItemOnRollerComposer(item, null, newTile, offset, room).compose()); - } - } + FurnitureMovementError furniMoveTest = room.furnitureFitsAt(newLocation, item, newRotation, true); + if(newLocation != null && newLocation.state != RoomTileState.INVALID && (newLocation != oldLocation || newRotation != item.getRotation()) && (furniMoveTest == FurnitureMovementError.NONE || ((furniMoveTest == FurnitureMovementError.TILE_HAS_BOTS || furniMoveTest == FurnitureMovementError.TILE_HAS_HABBOS || furniMoveTest == FurnitureMovementError.TILE_HAS_PETS) && newLocation == oldLocation))) { + if(room.furnitureFitsAt(newLocation, item, newRotation, false) == FurnitureMovementError.NONE && room.moveFurniTo(item, newLocation, newRotation, null, !slideAnimation) == FurnitureMovementError.NONE) { + this.itemCooldowns.add(item); + if(slideAnimation) { + room.sendComposer(new FloorItemOnRollerComposer(item, null, oldLocation, oldZ, newLocation, item.getZ(), 0, room).compose()); } } } } - if (!tilesToUpdate.isEmpty()) { - room.updateTiles(tilesToUpdate); - } - return true; } @@ -230,7 +143,7 @@ public class WiredEffectMoveRotateFurni extends InteractionWiredEffect { @Override public void serializeWiredData(ServerMessage message, Room room) { - THashSet items = new THashSet<>(this.items.size() / 2); + THashSet items = new THashSet<>(); for (HabboItem item : this.items) { if (item.getRoomId() != this.getRoomId() || Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null) @@ -294,21 +207,67 @@ public class WiredEffectMoveRotateFurni extends InteractionWiredEffect { */ private int getNewRotation(HabboItem item) { int rotationToAdd = 0; - if (this.rotation == 1) { - rotationToAdd = 2; - } else if (this.rotation == 2) { - rotationToAdd = 6; + + if(item.getMaximumRotations() == 2) { + return item.getRotation() == 0 ? 4 : 0; } - //Random rotation - else if (this.rotation == 3) { - if (Emulator.getRandom().nextInt(2) == 1) { - rotationToAdd = 2; - } else { - rotationToAdd = 6; + else if(item.getMaximumRotations() == 1) { + return item.getRotation(); + } + else if(item.getMaximumRotations() > 4) { + if (this.rotation == 1) { + return item.getRotation() == item.getMaximumRotations() - 1 ? 0 : item.getRotation() + 1; + } else if (this.rotation == 2) { + return item.getRotation() > 0 ? item.getRotation() - 1 : item.getMaximumRotations() - 1; + } else if (this.rotation == 3) { //Random rotation + THashSet possibleRotations = new THashSet<>(); + for (int i = 0; i < item.getMaximumRotations(); i++) + { + possibleRotations.add(i); + } + + possibleRotations.remove(item.getRotation()); + + if(possibleRotations.size() > 0) { + int index = Emulator.getRandom().nextInt(possibleRotations.size()); + Iterator iter = possibleRotations.iterator(); + for (int i = 0; i < index; i++) { + iter.next(); + } + return iter.next(); + } + } + } + else { + if (this.rotation == 1) { + return (item.getRotation() + 2) % 8; + } else if (this.rotation == 2) { + int rot = (item.getRotation() - 2) % 8; + if(rot < 0) { + rot += 8; + } + return rot; + } else if (this.rotation == 3) { //Random rotation + THashSet possibleRotations = new THashSet<>(); + for (int i = 0; i < item.getMaximumRotations(); i++) + { + possibleRotations.add(i * 2); + } + + possibleRotations.remove(item.getRotation()); + + if(possibleRotations.size() > 0) { + int index = Emulator.getRandom().nextInt(possibleRotations.size()); + Iterator iter = possibleRotations.iterator(); + for (int i = 0; i < index; i++) { + iter.next(); + } + return iter.next(); + } } } - return ((item.getRotation() + rotationToAdd) % 8) % (item.getBaseItem().getWidth() > 1 || item.getBaseItem().getLength() > 1 ? 4 : 8); + return item.getRotation(); } /** @@ -339,4 +298,9 @@ public class WiredEffectMoveRotateFurni extends InteractionWiredEffect { } return movemementDirection; } + + @Override + public void cycle(Room room) { + this.itemCooldowns.clear(); + } } \ No newline at end of file diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectTeleport.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectTeleport.java index 652f3780..bfe0ef15 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectTeleport.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectTeleport.java @@ -14,6 +14,7 @@ import com.eu.habbo.habbohotel.wired.WiredEffectType; import com.eu.habbo.habbohotel.wired.WiredHandler; import com.eu.habbo.messages.ClientMessage; import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.wired.WiredSaveException; import com.eu.habbo.messages.outgoing.rooms.users.RoomUserEffectComposer; import com.eu.habbo.threading.runnables.RoomUnitTeleport; import com.eu.habbo.threading.runnables.SendRoomUnitEffectComposer; @@ -78,6 +79,7 @@ public class WiredEffectTeleport extends InteractionWiredEffect { } } + Emulator.getThreading().run(() -> { roomUnit.isWiredTeleporting = true; }, Math.max(0, WiredHandler.TELEPORT_DELAY - 500)); Emulator.getThreading().run(new RoomUnitTeleport(roomUnit, room, tile.x, tile.y, tile.getStackHeight() + (tile.state == RoomTileState.SIT ? -0.5 : 0), roomUnit.getEffectId()), WiredHandler.TELEPORT_DELAY); } @@ -127,20 +129,36 @@ public class WiredEffectTeleport extends InteractionWiredEffect { } @Override - public boolean saveData(ClientMessage packet, GameClient gameClient) { + public boolean saveData(ClientMessage packet, GameClient gameClient) throws WiredSaveException { packet.readInt(); packet.readString(); - int count = packet.readInt(); - if (count > Emulator.getConfig().getInt("hotel.wired.furni.selection.count")) return false; + int itemsCount = packet.readInt(); - this.items.clear(); - - for (int i = 0; i < count; i++) { - this.items.add(Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(packet.readInt())); + if(itemsCount > Emulator.getConfig().getInt("hotel.wired.furni.selection.count")) { + throw new WiredSaveException("Too many furni selected"); } - this.setDelay(packet.readInt()); + List newItems = new ArrayList<>(); + + for (int i = 0; i < itemsCount; i++) { + int itemId = packet.readInt(); + HabboItem it = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(itemId); + + if(it == null) + throw new WiredSaveException(String.format("Item %s not found", itemId)); + + newItems.add(it); + } + + int delay = packet.readInt(); + + 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; } diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectToggleFurni.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectToggleFurni.java index d3025363..21f2926b 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectToggleFurni.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectToggleFurni.java @@ -3,12 +3,20 @@ 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.InteractionCrackable; -import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect; -import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger; +import com.eu.habbo.habbohotel.items.interactions.*; +import com.eu.habbo.habbohotel.items.interactions.games.InteractionGameGate; +import com.eu.habbo.habbohotel.items.interactions.games.InteractionGameScoreboard; +import com.eu.habbo.habbohotel.items.interactions.games.InteractionGameTeamItem; import com.eu.habbo.habbohotel.items.interactions.games.InteractionGameTimer; +import com.eu.habbo.habbohotel.items.interactions.games.battlebanzai.InteractionBattleBanzaiPuck; +import com.eu.habbo.habbohotel.items.interactions.games.battlebanzai.InteractionBattleBanzaiTeleporter; +import com.eu.habbo.habbohotel.items.interactions.games.battlebanzai.InteractionBattleBanzaiTile; import com.eu.habbo.habbohotel.items.interactions.games.freeze.InteractionFreezeBlock; +import com.eu.habbo.habbohotel.items.interactions.games.freeze.InteractionFreezeExitTile; import com.eu.habbo.habbohotel.items.interactions.games.freeze.InteractionFreezeTile; +import com.eu.habbo.habbohotel.items.interactions.games.tag.InteractionTagField; +import com.eu.habbo.habbohotel.items.interactions.games.tag.InteractionTagPole; +import com.eu.habbo.habbohotel.items.interactions.pets.*; import com.eu.habbo.habbohotel.rooms.Room; import com.eu.habbo.habbohotel.rooms.RoomUnit; import com.eu.habbo.habbohotel.users.Habbo; @@ -17,6 +25,7 @@ import com.eu.habbo.habbohotel.wired.WiredEffectType; import com.eu.habbo.habbohotel.wired.WiredHandler; import com.eu.habbo.messages.ClientMessage; import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.wired.WiredSaveException; import gnu.trove.procedure.TObjectProcedure; import gnu.trove.set.hash.THashSet; import org.slf4j.Logger; @@ -34,6 +43,46 @@ public class WiredEffectToggleFurni extends InteractionWiredEffect { private final THashSet items; + private static final List> FORBIDDEN_TYPES = new ArrayList>() { + { + this.add(InteractionWired.class); + this.add(InteractionTeleport.class); + this.add(InteractionPushable.class); + this.add(InteractionTagPole.class); + this.add(InteractionTagField.class); + this.add(InteractionCrackable.class); + this.add(InteractionGameScoreboard.class); + this.add(InteractionGameGate.class); + this.add(InteractionFreezeTile.class); + this.add(InteractionFreezeBlock.class); + this.add(InteractionFreezeExitTile.class); + this.add(InteractionBattleBanzaiTeleporter.class); + this.add(InteractionBattleBanzaiTile.class); + this.add(InteractionMonsterPlantSeed.class); + this.add(InteractionPetBreedingNest.class); + this.add(InteractionPetDrink.class); + this.add(InteractionPetFood.class); + this.add(InteractionPetToy.class); + this.add(InteractionBadgeDisplay.class); + this.add(InteractionClothing.class); + this.add(InteractionVendingMachine.class); + this.add(InteractionGift.class); + this.add(InteractionPressurePlate.class); + this.add(InteractionMannequin.class); + this.add(InteractionGymEquipment.class); + this.add(InteractionHopper.class); + this.add(InteractionObstacle.class); + this.add(InteractionOneWayGate.class); + this.add(InteractionPuzzleBox.class); + this.add(InteractionRoller.class); + this.add(InteractionSwitch.class); + this.add(InteractionTent.class); + this.add(InteractionTrap.class); + this.add(InteractionTrophy.class); + this.add(InteractionWater.class); + } + }; + public WiredEffectToggleFurni(ResultSet set, Item baseItem) throws SQLException { super(set, baseItem); this.items = new THashSet<>(); @@ -92,25 +141,36 @@ public class WiredEffectToggleFurni extends InteractionWiredEffect { } @Override - public boolean saveData(ClientMessage packet, GameClient gameClient) { + public boolean saveData(ClientMessage packet, GameClient gameClient) throws WiredSaveException { packet.readInt(); packet.readString(); - int count = packet.readInt(); - if (count > Emulator.getConfig().getInt("hotel.wired.furni.selection.count")) return false; + int itemsCount = packet.readInt(); - this.items.clear(); - - for (int i = 0; i < count; i++) { - HabboItem item = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(packet.readInt()); - - if (item instanceof InteractionFreezeBlock || item instanceof InteractionFreezeTile || item instanceof InteractionCrackable) - continue; - - this.items.add(item); + if(itemsCount > Emulator.getConfig().getInt("hotel.wired.furni.selection.count")) { + throw new WiredSaveException("Too many furni selected"); } - this.setDelay(packet.readInt()); + List newItems = new ArrayList<>(); + + for (int i = 0; i < itemsCount; i++) { + int itemId = packet.readInt(); + HabboItem it = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(itemId); + + if(it == null) + throw new WiredSaveException(String.format("Item %s not found", itemId)); + + newItems.add(it); + } + + int delay = packet.readInt(); + + 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; } @@ -123,7 +183,7 @@ public class WiredEffectToggleFurni extends InteractionWiredEffect { THashSet itemsToRemove = new THashSet<>(); for (HabboItem item : this.items) { - if (item == null || item.getRoomId() == 0 || item instanceof InteractionFreezeBlock || item instanceof InteractionFreezeTile) { + if (item == null || item.getRoomId() == 0 || FORBIDDEN_TYPES.stream().anyMatch(a -> a.isAssignableFrom(item.getClass()))) { itemsToRemove.add(item); continue; } diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectToggleRandom.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectToggleRandom.java index 98b41137..3a703929 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectToggleRandom.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectToggleRandom.java @@ -3,11 +3,18 @@ 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.InteractionCrackable; -import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect; -import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger; +import com.eu.habbo.habbohotel.items.interactions.*; +import com.eu.habbo.habbohotel.items.interactions.games.InteractionGameGate; +import com.eu.habbo.habbohotel.items.interactions.games.InteractionGameScoreboard; import com.eu.habbo.habbohotel.items.interactions.games.InteractionGameTimer; +import com.eu.habbo.habbohotel.items.interactions.games.battlebanzai.InteractionBattleBanzaiTeleporter; +import com.eu.habbo.habbohotel.items.interactions.games.battlebanzai.InteractionBattleBanzaiTile; import com.eu.habbo.habbohotel.items.interactions.games.freeze.InteractionFreezeBlock; +import com.eu.habbo.habbohotel.items.interactions.games.freeze.InteractionFreezeExitTile; +import com.eu.habbo.habbohotel.items.interactions.games.freeze.InteractionFreezeTile; +import com.eu.habbo.habbohotel.items.interactions.games.tag.InteractionTagField; +import com.eu.habbo.habbohotel.items.interactions.games.tag.InteractionTagPole; +import com.eu.habbo.habbohotel.items.interactions.pets.*; import com.eu.habbo.habbohotel.rooms.Room; import com.eu.habbo.habbohotel.rooms.RoomUnit; import com.eu.habbo.habbohotel.users.HabboItem; @@ -15,6 +22,7 @@ import com.eu.habbo.habbohotel.wired.WiredEffectType; import com.eu.habbo.habbohotel.wired.WiredHandler; import com.eu.habbo.messages.ClientMessage; import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.wired.WiredSaveException; import gnu.trove.procedure.TObjectProcedure; import gnu.trove.set.hash.THashSet; import org.slf4j.Logger; @@ -32,6 +40,46 @@ public class WiredEffectToggleRandom extends InteractionWiredEffect { private final THashSet items = new THashSet<>(); + private static final List> FORBIDDEN_TYPES = new ArrayList>() { + { + this.add(InteractionWired.class); + this.add(InteractionTeleport.class); + this.add(InteractionPushable.class); + this.add(InteractionTagPole.class); + this.add(InteractionTagField.class); + this.add(InteractionCrackable.class); + this.add(InteractionGameScoreboard.class); + this.add(InteractionGameGate.class); + this.add(InteractionFreezeTile.class); + this.add(InteractionFreezeBlock.class); + this.add(InteractionFreezeExitTile.class); + this.add(InteractionBattleBanzaiTeleporter.class); + this.add(InteractionBattleBanzaiTile.class); + this.add(InteractionMonsterPlantSeed.class); + this.add(InteractionPetBreedingNest.class); + this.add(InteractionPetDrink.class); + this.add(InteractionPetFood.class); + this.add(InteractionPetToy.class); + this.add(InteractionBadgeDisplay.class); + this.add(InteractionClothing.class); + this.add(InteractionVendingMachine.class); + this.add(InteractionGift.class); + this.add(InteractionPressurePlate.class); + this.add(InteractionMannequin.class); + this.add(InteractionGymEquipment.class); + this.add(InteractionHopper.class); + this.add(InteractionObstacle.class); + this.add(InteractionOneWayGate.class); + this.add(InteractionPuzzleBox.class); + this.add(InteractionRoller.class); + this.add(InteractionSwitch.class); + this.add(InteractionTent.class); + this.add(InteractionTrap.class); + this.add(InteractionTrophy.class); + this.add(InteractionWater.class); + } + }; + public WiredEffectToggleRandom(ResultSet set, Item baseItem) throws SQLException { super(set, baseItem); } @@ -88,24 +136,36 @@ public class WiredEffectToggleRandom extends InteractionWiredEffect { } @Override - public boolean saveData(ClientMessage packet, GameClient gameClient) { + public boolean saveData(ClientMessage packet, GameClient gameClient) throws WiredSaveException { packet.readInt(); packet.readString(); - this.items.clear(); + int itemsCount = packet.readInt(); - int count = packet.readInt(); - - for (int i = 0; i < count; i++) { - HabboItem item = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(packet.readInt()); - - if (item instanceof InteractionFreezeBlock || item instanceof InteractionGameTimer || item instanceof InteractionCrackable) - continue; - - this.items.add(item); + if(itemsCount > Emulator.getConfig().getInt("hotel.wired.furni.selection.count")) { + throw new WiredSaveException("Too many furni selected"); } - this.setDelay(packet.readInt()); + List newItems = new ArrayList<>(); + + for (int i = 0; i < itemsCount; i++) { + int itemId = packet.readInt(); + HabboItem it = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(itemId); + + if(it == null) + throw new WiredSaveException(String.format("Item %s not found", itemId)); + + newItems.add(it); + } + + int delay = packet.readInt(); + + 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; } @@ -115,7 +175,7 @@ public class WiredEffectToggleRandom extends InteractionWiredEffect { THashSet items = this.items; for (HabboItem item : items) { - if (item.getRoomId() == 0) { + if (item.getRoomId() == 0 || FORBIDDEN_TYPES.stream().anyMatch(a -> a.isAssignableFrom(item.getClass()))) { this.items.remove(item); continue; } diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectTriggerStacks.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectTriggerStacks.java index d58b6a84..da811cd6 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectTriggerStacks.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectTriggerStacks.java @@ -13,6 +13,7 @@ import com.eu.habbo.habbohotel.wired.WiredEffectType; import com.eu.habbo.habbohotel.wired.WiredHandler; import com.eu.habbo.messages.ClientMessage; import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.wired.WiredSaveException; import gnu.trove.procedure.TObjectProcedure; import gnu.trove.set.hash.THashSet; @@ -83,20 +84,36 @@ public class WiredEffectTriggerStacks extends InteractionWiredEffect { } @Override - public boolean saveData(ClientMessage packet, GameClient gameClient) { + public boolean saveData(ClientMessage packet, GameClient gameClient) throws WiredSaveException { packet.readInt(); packet.readString(); - int count = packet.readInt(); - if (count > Emulator.getConfig().getInt("hotel.wired.furni.selection.count")) return false; + int itemsCount = packet.readInt(); - this.items.clear(); - - for (int i = 0; i < count; i++) { - this.items.add(Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(packet.readInt())); + if(itemsCount > Emulator.getConfig().getInt("hotel.wired.furni.selection.count")) { + throw new WiredSaveException("Too many furni selected"); } - this.setDelay(packet.readInt()); + List newItems = new ArrayList<>(); + + for (int i = 0; i < itemsCount; i++) { + int itemId = packet.readInt(); + HabboItem it = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(itemId); + + if(it == null) + throw new WiredSaveException(String.format("Item %s not found", itemId)); + + newItems.add(it); + } + + int delay = packet.readInt(); + + 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; } diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectWhisper.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectWhisper.java index 3cc5872a..56d6f35e 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectWhisper.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectWhisper.java @@ -5,14 +5,16 @@ 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.rooms.Room; -import com.eu.habbo.habbohotel.rooms.RoomChatMessage; -import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; -import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.*; import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.wired.WiredChangeDirectionSetting; import com.eu.habbo.habbohotel.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.habbohotel.wired.WiredTriggerType; import com.eu.habbo.messages.ClientMessage; import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.wired.WiredSaveException; import com.eu.habbo.messages.outgoing.rooms.users.RoomUserWhisperComposer; import gnu.trove.procedure.TObjectProcedure; @@ -68,15 +70,25 @@ public class WiredEffectWhisper extends InteractionWiredEffect { } @Override - public boolean saveData(ClientMessage packet, GameClient gameClient) { + public boolean saveData(ClientMessage packet, GameClient gameClient) throws WiredSaveException { packet.readInt(); - this.message = Emulator.getGameEnvironment().getWordFilter().filter(packet.readString(), null); - if (this.message.length() > 100) { - this.message = ""; + String message = packet.readString(); + + if(gameClient.getHabbo() == null || !gameClient.getHabbo().hasPermission(Permission.ACC_SUPERWIRED)) { + message = Emulator.getGameEnvironment().getWordFilter().filter(message, null); + message = message.substring(0, Math.min(message.length(), Emulator.getConfig().getInt("hotel.wired.message.max_length", 100))); } + packet.readInt(); - this.setDelay(packet.readInt()); + + int delay = packet.readInt(); + + if(delay > Emulator.getConfig().getInt("hotel.wired.max_delay", 20)) + throw new WiredSaveException("Delay too long"); + + this.message = message; + this.setDelay(delay); return true; } @@ -87,7 +99,9 @@ public class WiredEffectWhisper extends InteractionWiredEffect { Habbo habbo = room.getHabbo(roomUnit); if (habbo != null) { - habbo.getClient().sendResponse(new RoomUserWhisperComposer(new RoomChatMessage(this.message.replace("%user%", habbo.getHabboInfo().getUsername()).replace("%online_count%", Emulator.getGameEnvironment().getHabboManager().getOnlineCount() + "").replace("%room_count%", Emulator.getGameEnvironment().getRoomManager().getActiveRooms().size() + ""), habbo, habbo, RoomChatMessageBubbles.WIRED))); + String msg = this.message.replace("%user%", habbo.getHabboInfo().getUsername()).replace("%online_count%", Emulator.getGameEnvironment().getHabboManager().getOnlineCount() + "").replace("%room_count%", Emulator.getGameEnvironment().getRoomManager().getActiveRooms().size() + ""); + habbo.getClient().sendResponse(new RoomUserWhisperComposer(new RoomChatMessage(msg, habbo, habbo, RoomChatMessageBubbles.WIRED))); + Emulator.getThreading().run(() -> WiredHandler.handle(WiredTriggerType.SAY_SOMETHING, roomUnit, room, new Object[]{ msg })); if (habbo.getRoomUnit().isIdle()) { habbo.getRoomUnit().getRoom().unIdle(habbo); @@ -107,17 +121,27 @@ public class WiredEffectWhisper extends InteractionWiredEffect { @Override public String getWiredData() { - return this.getDelay() + "\t" + this.message; + return WiredHandler.getGsonBuilder().create().toJson(new JsonData(this.message, this.getDelay())); } @Override public void loadWiredData(ResultSet set, Room room) throws SQLException { - String wireData = set.getString("wired_data"); - this.message = ""; + String wiredData = set.getString("wired_data"); - if (wireData.split("\t").length >= 2) { - super.setDelay(Integer.valueOf(wireData.split("\t")[0])); - this.message = wireData.split("\t")[1]; + if(wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.setDelay(data.delay); + this.message = data.message; + } + else { + this.message = ""; + + if (wiredData.split("\t").length >= 2) { + super.setDelay(Integer.valueOf(wiredData.split("\t")[0])); + this.message = wiredData.split("\t")[1]; + } + + this.needsUpdate(true); } } @@ -136,4 +160,14 @@ public class WiredEffectWhisper extends InteractionWiredEffect { public boolean requiresTriggeringUser() { return true; } + + static class JsonData { + String message; + int delay; + + public JsonData(String message, int delay) { + this.message = message; + this.delay = delay; + } + } } diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/extra/WiredBlob.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/extra/WiredBlob.java index 0017efe8..8f859fd2 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/extra/WiredBlob.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/extra/WiredBlob.java @@ -68,7 +68,7 @@ public class WiredBlob extends InteractionDefault { GamePlayer player = habbo.getHabboInfo().getGamePlayer(); if (player != null) { - player.addScore(this.POINTS_REWARD); + player.addScore(this.POINTS_REWARD, true); BattleBanzaiGame battleBanzaiGame = (BattleBanzaiGame) room.getGame(BattleBanzaiGame.class); diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerBotReachedFurni.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerBotReachedFurni.java index 73c543c3..36c266b9 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerBotReachedFurni.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerBotReachedFurni.java @@ -25,7 +25,7 @@ import java.util.List; public class WiredTriggerBotReachedFurni extends InteractionWiredTrigger { private static final Logger LOGGER = LoggerFactory.getLogger(WiredTriggerBotReachedFurni.class); - public final static WiredTriggerType type = WiredTriggerType.BOT_REACHED_STF; + public final static WiredTriggerType type = WiredTriggerType.WALKS_ON_FURNI; private THashSet items; private String botName = ""; @@ -73,7 +73,7 @@ public class WiredTriggerBotReachedFurni extends InteractionWiredTrigger { message.appendString(this.botName); message.appendInt(0); message.appendInt(0); - message.appendInt(this.getType().code); + message.appendInt(WiredTriggerType.BOT_REACHED_STF.code); if (!this.isTriggeredByRoomUnit()) { List invalidTriggers = new ArrayList<>(); @@ -114,17 +114,11 @@ public class WiredTriggerBotReachedFurni extends InteractionWiredTrigger { @Override public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { - List bots = room.getBots(this.botName); - - for (Bot bot : bots) { - if (bot.getRoomUnit().equals(roomUnit)) { - for (Object o : stuff) { - if (this.items.contains(o)) - return true; - } + if (stuff.length >= 1) { + if (stuff[0] instanceof HabboItem) { + return this.items.contains(stuff[0]) && room.getBots(this.botName).stream().anyMatch(bot -> bot.getRoomUnit() == roomUnit); } } - return false; } diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerBotReachedHabbo.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerBotReachedHabbo.java index 7da199f7..161f2acf 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerBotReachedHabbo.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerBotReachedHabbo.java @@ -57,16 +57,7 @@ public class WiredTriggerBotReachedHabbo extends InteractionWiredTrigger { @Override public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { - if (stuff.length == 0) - return false; - - List bots = room.getBots(this.botName); - - for (Bot bot : bots) { - if (bot.getRoomUnit().equals(stuff[0])) - return true; - } - return false; + return room.getBots(this.botName).stream().anyMatch(bot -> bot.getRoomUnit() == roomUnit); } @Override diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerHabboSaysKeyword.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerHabboSaysKeyword.java index 9a98f41c..341f912a 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerHabboSaysKeyword.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerHabboSaysKeyword.java @@ -28,14 +28,11 @@ public class WiredTriggerHabboSaysKeyword extends InteractionWiredTrigger { @Override public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { - Habbo habbo = room.getHabbo(roomUnit); - - if (habbo != null) { - if (this.key.length() > 0) { - if (stuff[0] instanceof String) { - if (((String) stuff[0]).toLowerCase().contains(this.key.toLowerCase())) { - return !this.ownerOnly || room.getOwnerId() == habbo.getHabboInfo().getId(); - } + if (this.key.length() > 0) { + if (stuff[0] instanceof String) { + if (((String) stuff[0]).toLowerCase().contains(this.key.toLowerCase())) { + Habbo habbo = room.getHabbo(roomUnit); + return !this.ownerOnly || (habbo != null && room.getOwnerId() == habbo.getHabboInfo().getId()); } } } diff --git a/src/main/java/com/eu/habbo/habbohotel/rooms/Room.java b/src/main/java/com/eu/habbo/habbohotel/rooms/Room.java index b6b9170e..1840a150 100644 --- a/src/main/java/com/eu/habbo/habbohotel/rooms/Room.java +++ b/src/main/java/com/eu/habbo/habbohotel/rooms/Room.java @@ -73,6 +73,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.awt.*; +import java.lang.reflect.InvocationTargetException; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -116,6 +117,7 @@ public class Room implements Comparable, ISerialize, Runnable { public static String PREFIX_FORMAT = "[%prefix%] "; public static int ROLLERS_MAXIMUM_ROLL_AVATARS = 1; public static boolean MUTEAREA_CAN_WHISPER = false; + public static double MAXIMUM_FURNI_HEIGHT = 40d; static { for (int i = 1; i <= 3; i++) { @@ -566,12 +568,14 @@ public class Room implements Comparable, ISerialize, Runnable { return RoomTileState.INVALID; RoomTileState result = RoomTileState.OPEN; - HabboItem highestItem = null; - HabboItem lowestChair = this.getLowestChair(tile); + //HabboItem highestItem = null; + //HabboItem lowestChair = this.getLowestChair(tile); THashSet items = this.getItemsAt(tile); if (items == null) return RoomTileState.INVALID; + HabboItem tallestItem = null; + for (HabboItem item : items) { if (exclude != null && item == exclude) continue; @@ -579,13 +583,16 @@ public class Room implements Comparable, ISerialize, Runnable { return RoomTileState.LAY; } - if (highestItem != null && highestItem.getZ() + Item.getCurrentHeight(highestItem) > item.getZ() + Item.getCurrentHeight(item)) + /*if (highestItem != null && highestItem.getZ() + Item.getCurrentHeight(highestItem) > item.getZ() + Item.getCurrentHeight(item)) continue; - highestItem = item; - if (result == RoomTileState.OPEN) { - result = this.checkStateForItem(item, tile); - } + highestItem = item;*/ + + if(tallestItem != null && tallestItem.getZ() + Item.getCurrentHeight(tallestItem) > item.getZ() + Item.getCurrentHeight(item)) + continue; + + result = this.checkStateForItem(item, tile); + tallestItem = item; /*if (lowestChair != null && item.getZ() > lowestChair.getZ() + 1.5) { continue; @@ -602,7 +609,7 @@ public class Room implements Comparable, ISerialize, Runnable { }*/ } - if (lowestChair != null) return RoomTileState.SIT; + //if (lowestChair != null) return RoomTileState.SIT; return result; } @@ -751,13 +758,20 @@ public class Room implements Comparable, ISerialize, Runnable { THashSet roomUnits = new THashSet<>(); for (Habbo habbo : habbos) { + double oldZ = habbo.getRoomUnit().getZ(); + RoomUserRotation oldRotation = habbo.getRoomUnit().getBodyRotation(); double z = habbo.getRoomUnit().getCurrentLocation().getStackHeight(); + boolean updated = false; - if ((item == null && !habbo.getRoomUnit().cmdSit) || (item != null && !item.getBaseItem().allowSit())) + if (habbo.getRoomUnit().hasStatus(RoomUnitStatus.SIT) && ((item == null && !habbo.getRoomUnit().cmdSit) || (item != null && !item.getBaseItem().allowSit()))) { habbo.getRoomUnit().removeStatus(RoomUnitStatus.SIT); + updated = true; + } - if ((item == null && !habbo.getRoomUnit().cmdLay) || (item != null && !item.getBaseItem().allowLay())) + if (habbo.getRoomUnit().hasStatus(RoomUnitStatus.LAY) && ((item == null && !habbo.getRoomUnit().cmdLay) || (item != null && !item.getBaseItem().allowLay()))) { habbo.getRoomUnit().removeStatus(RoomUnitStatus.LAY); + updated = true; + } if (item != null && (item.getBaseItem().allowSit() || item.getBaseItem().allowLay())) { habbo.getRoomUnit().setZ(item.getZ()); @@ -767,12 +781,16 @@ public class Room implements Comparable, ISerialize, Runnable { habbo.getRoomUnit().setZ(z); habbo.getRoomUnit().setPreviousLocationZ(z); } - roomUnits.add(habbo.getRoomUnit()); + + if(habbo.getRoomUnit().getCurrentLocation().is(x, y) && (oldZ != z || updated || oldRotation != habbo.getRoomUnit().getBodyRotation())) { + habbo.getRoomUnit().statusUpdate(true); + //roomUnits.add(habbo.getRoomUnit()); + } } - if (!roomUnits.isEmpty()) { + /*if (!roomUnits.isEmpty()) { this.sendComposer(new RoomUserStatusComposer(roomUnits, true).compose()); - } + }*/ } public void updateBotsAt(short x, short y) { @@ -1408,7 +1426,7 @@ public class Room implements Comparable, ISerialize, Runnable { } } - HabboItem nextTileChair = this.getLowestChair(tileInFront); + HabboItem nextTileChair = this.getTallestChair(tileInFront); THashSet usersRolledThisTile = new THashSet<>(); @@ -1445,7 +1463,7 @@ public class Room implements Comparable, ISerialize, Runnable { tile.setStackHeight(ridingUnit.getZ() + zOffset); rolledUnitIds.add(ridingUnit.getId()); updatedUnit.remove(ridingUnit); - messages.add(new RoomUnitOnRollerComposer(ridingUnit, roller, ridingUnit.getCurrentLocation(), ridingUnit.getZ(), tile, tile.getStackHeight() + (nextTileChair != null ? -1 : 0), room)); + messages.add(new RoomUnitOnRollerComposer(ridingUnit, roller, ridingUnit.getCurrentLocation(), ridingUnit.getZ(), tile, tile.getStackHeight(), room)); isRiding = true; } } @@ -1454,16 +1472,16 @@ public class Room implements Comparable, ISerialize, Runnable { usersRolledThisTile.add(unit.getId()); rolledUnitIds.add(unit.getId()); updatedUnit.remove(unit); - messages.add(new RoomUnitOnRollerComposer(unit, roller, unit.getCurrentLocation(), unit.getZ() + (isRiding ? 1 : 0), tile, tile.getStackHeight() + (isRiding ? 1 : 0) + (nextTileChair != null ? -1 : 0), room)); + messages.add(new RoomUnitOnRollerComposer(unit, roller, unit.getCurrentLocation(), unit.getZ() + (isRiding ? 1 : 0), tile, tile.getStackHeight() + (isRiding ? 1 : 0), room)); if (itemsOnRoller.isEmpty()) { HabboItem item = room.getTopItemAt(tileInFront.x, tileInFront.y); - if (item != null && itemsNewTile.contains(item)) { + if (item != null && itemsNewTile.contains(item) && !itemsOnRoller.contains(item)) { Emulator.getThreading().run(() -> { if (unit.getGoal() == rollerTile) { try { - item.onWalkOn(unit, room, null); + item.onWalkOn(unit, room, new Object[] { rollerTile, tileInFront }); } catch (Exception e) { LOGGER.error("Caught exception", e); } @@ -1602,23 +1620,22 @@ public class Room implements Comparable, ISerialize, Runnable { } if (!unit.isWalking() && !unit.cmdSit) { - HabboItem topItem = this.getLowestChair(this.getLayout().getTile(unit.getX(), unit.getY())); + RoomTile thisTile = this.getLayout().getTile(unit.getX(), unit.getY()); + HabboItem topItem = this.getTallestChair(thisTile); if (topItem == null || !topItem.getBaseItem().allowSit()) { if (unit.hasStatus(RoomUnitStatus.SIT)) { unit.removeStatus(RoomUnitStatus.SIT); update = true; } - } else { - if (!unit.hasStatus(RoomUnitStatus.SIT) || unit.sitUpdate) { - this.dance(unit, DanceType.NONE); - //int tileHeight = this.layout.getTile(topItem.getX(), topItem.getY()).z; - unit.setStatus(RoomUnitStatus.SIT, (Item.getCurrentHeight(topItem) * 1.0D) + ""); - unit.setZ(topItem.getZ()); - unit.setRotation(RoomUserRotation.values()[topItem.getRotation()]); - unit.sitUpdate = false; - return true; - } + } else if (thisTile.state == RoomTileState.SIT && (!unit.hasStatus(RoomUnitStatus.SIT) || unit.sitUpdate)) { + this.dance(unit, DanceType.NONE); + //int tileHeight = this.layout.getTile(topItem.getX(), topItem.getY()).z; + unit.setStatus(RoomUnitStatus.SIT, (Item.getCurrentHeight(topItem) * 1.0D) + ""); + unit.setZ(topItem.getZ()); + unit.setRotation(RoomUserRotation.values()[topItem.getRotation()]); + unit.sitUpdate = false; + return true; } } } @@ -2171,6 +2188,20 @@ public class Room implements Comparable, ISerialize, Runnable { return null; } + public Game getGameOrCreate(Class gameType) { + Game game = this.getGame(gameType); + if(game == null) { + try { + game = gameType.getDeclaredConstructor(Room.class).newInstance(this); + this.addGame(game); + } catch (Exception e) { + LOGGER.error("Error getting game " + gameType.getName(), e); + } + } + + return game; + } + public ConcurrentSet getGames() { return this.games; } @@ -2957,7 +2988,7 @@ public class Room implements Comparable, ISerialize, Runnable { this.teleportRoomUnitToLocation(roomUnit, x, y, 0.0); } - void teleportRoomUnitToLocation(RoomUnit roomUnit, short x, short y, double z) { + public void teleportRoomUnitToLocation(RoomUnit roomUnit, short x, short y, double z) { if (this.loaded) { RoomTile tile = this.layout.getTile(x, y); @@ -3365,9 +3396,9 @@ public class Room implements Comparable, ISerialize, Runnable { return items; if (this.loaded) { - if (this.tileCache.containsKey(tile)) { - return this.tileCache.get(tile); - } + THashSet cachedItems = this.tileCache.get(tile); + if(cachedItems != null) + return cachedItems; } TIntObjectIterator iterator = this.roomItems.iterator(); @@ -3473,6 +3504,27 @@ public class Room implements Comparable, ISerialize, Runnable { return highestItem; } + public HabboItem getTopItemAt(THashSet tiles, HabboItem exclude) { + HabboItem highestItem = null; + for(RoomTile tile : tiles) { + + if (tile == null) + continue; + + for (HabboItem item : this.getItemsAt(tile.x, tile.y)) { + if (exclude != null && exclude == item) + continue; + + if (highestItem != null && highestItem.getZ() + Item.getCurrentHeight(highestItem) > item.getZ() + Item.getCurrentHeight(item)) + continue; + + highestItem = item; + } + } + + return highestItem; + } + public double getTopHeightAt(int x, int y) { HabboItem item = this.getTopItemAt(x, y); @@ -3515,6 +3567,26 @@ public class Room implements Comparable, ISerialize, Runnable { return lowestChair; } + public HabboItem getTallestChair(RoomTile tile) { + HabboItem lowestChair = null; + + THashSet items = this.getItemsAt(tile); + if (items != null && !items.isEmpty()) { + for (HabboItem item : items) { + + if(!item.getBaseItem().allowSit()) + continue; + + if(lowestChair != null && lowestChair.getZ() + Item.getCurrentHeight(lowestChair) > item.getZ() + Item.getCurrentHeight(item)) + continue; + + lowestChair = item; + } + } + + return lowestChair; + } + public double getStackHeight(short x, short y, boolean calculateHeightmap, HabboItem exclude) { if (x < 0 || y < 0 || this.layout == null) @@ -3542,14 +3614,14 @@ public class Room implements Comparable, ISerialize, Runnable { HabboItem item = this.getTopItemAt(x, y, exclude); if (item != null) { canStack = item.getBaseItem().allowStack(); - height = item.getZ() + Item.getCurrentHeight(item); + height = item.getZ() + (item.getBaseItem().allowSit() ? 0 : Item.getCurrentHeight(item)); } - HabboItem lowestChair = this.getLowestChair(x, y); + /*HabboItem lowestChair = this.getLowestChair(x, y); if (lowestChair != null && lowestChair != exclude) { canStack = true; height = lowestChair.getZ(); - } + }*/ if (calculateHeightmap) { return (canStack ? height * 256.0D : Short.MAX_VALUE); @@ -3625,41 +3697,19 @@ public class Room implements Comparable, ISerialize, Runnable { if (items == null) return false; - HabboItem topItem = null; - HabboItem lowestSitItem = null; - boolean canSitUnder = false; + HabboItem tallestItem = null; for (HabboItem item : items) { - if ((lowestSitItem == null || lowestSitItem.getZ() > item.getZ()) && item.getBaseItem().allowSit()) { - lowestSitItem = item; - canSitUnder = true; - } + if(tallestItem != null && tallestItem.getZ() + Item.getCurrentHeight(tallestItem) > item.getZ() + Item.getCurrentHeight(item)) + continue; - if (lowestSitItem != null && canSitUnder) { - if (item != lowestSitItem) { - double distance = item.getZ() - lowestSitItem.getZ(); - - if (distance >= 0 && distance < 0.8) { - canSitUnder = false; - } - } - } - - if (topItem == null || Item.getCurrentHeight(item) > Item.getCurrentHeight(topItem)) { - topItem = item; - } + tallestItem = item; } - if (topItem == null) + if (tallestItem == null) return false; - if (lowestSitItem == null) - return false; - - if (topItem == lowestSitItem) - return true; - - return topItem.getZ() <= lowestSitItem.getZ() || (canSitUnder); + return tallestItem.getBaseItem().allowSit(); } public boolean canLayAt(int x, int y) { @@ -4070,6 +4120,10 @@ public class Room implements Comparable, ISerialize, Runnable { if (this.layout == null) return; this.updateTiles(this.getLayout().getTilesAt(this.layout.getTile(item.getX(), item.getY()), item.getBaseItem().getWidth(), item.getBaseItem().getLength(), item.getRotation())); + + if(item instanceof InteractionMultiHeight) { + ((InteractionMultiHeight)item).updateUnitsOnItem(this); + } } } @@ -4235,14 +4289,16 @@ public class Room implements Comparable, ISerialize, Runnable { } public void dance(RoomUnit unit, DanceType danceType) { - boolean isDancing = !unit.getDanceType().equals(DanceType.NONE); - unit.setDanceType(danceType); - this.sendComposer(new RoomUserDanceComposer(unit).compose()); + if(unit.getDanceType() != danceType) { + boolean isDancing = !unit.getDanceType().equals(DanceType.NONE); + unit.setDanceType(danceType); + this.sendComposer(new RoomUserDanceComposer(unit).compose()); - if (danceType.equals(DanceType.NONE) && isDancing) { - WiredHandler.handle(WiredTriggerType.STOPS_DANCING, unit, this, new Object[]{unit}); - } else if (!danceType.equals(DanceType.NONE) && !isDancing) { - WiredHandler.handle(WiredTriggerType.STARTS_DANCING, unit, this, new Object[]{unit}); + if (danceType.equals(DanceType.NONE) && isDancing) { + WiredHandler.handle(WiredTriggerType.STOPS_DANCING, unit, this, new Object[]{unit}); + } else if (!danceType.equals(DanceType.NONE) && !isDancing) { + WiredHandler.handle(WiredTriggerType.STARTS_DANCING, unit, this, new Object[]{unit}); + } } } @@ -4365,8 +4421,6 @@ public class Room implements Comparable, ISerialize, Runnable { return FurnitureMovementError.MAX_ITEMS; } - - rotation %= 8; if (this.hasRights(habbo) || this.guildRightLevel(habbo) >= 2 || habbo.hasPermission(Permission.ACC_MOVEROTATE)) { return FurnitureMovementError.NONE; @@ -4388,6 +4442,10 @@ public class Room implements Comparable, ISerialize, Runnable { } public FurnitureMovementError furnitureFitsAt(RoomTile tile, HabboItem item, int rotation) { + return furnitureFitsAt(tile, item, rotation, true); + } + + public FurnitureMovementError furnitureFitsAt(RoomTile tile, HabboItem item, int rotation, boolean checkForUnits) { if (!this.layout.fitsOnMap(tile, item.getBaseItem().getWidth(), item.getBaseItem().getLength(), rotation)) return FurnitureMovementError.INVALID_MOVE; @@ -4395,10 +4453,10 @@ public class Room implements Comparable, ISerialize, Runnable { THashSet occupiedTiles = this.layout.getTilesAt(tile, item.getBaseItem().getWidth(), item.getBaseItem().getLength(), rotation); for (RoomTile t : occupiedTiles) { - - if (this.hasHabbosAt(t.x, t.y)) return FurnitureMovementError.TILE_HAS_HABBOS; - if (this.hasBotsAt(t.x, t.y)) return FurnitureMovementError.TILE_HAS_BOTS; - if (this.hasPetsAt(t.x, t.y)) return FurnitureMovementError.TILE_HAS_PETS; + if(t.state == RoomTileState.INVALID) return FurnitureMovementError.INVALID_MOVE; + if (checkForUnits && this.hasHabbosAt(t.x, t.y)) return FurnitureMovementError.TILE_HAS_HABBOS; + if (checkForUnits && this.hasBotsAt(t.x, t.y)) return FurnitureMovementError.TILE_HAS_BOTS; + if (checkForUnits && this.hasPetsAt(t.x, t.y)) return FurnitureMovementError.TILE_HAS_PETS; } List>> tileFurniList = new ArrayList<>(); @@ -4440,6 +4498,13 @@ public class Room implements Comparable, ISerialize, Runnable { double height = tile.getStackHeight(); + for(RoomTile tile2 : occupiedTiles) { + double sHeight = tile2.getStackHeight(); + if(sHeight > height) { + height = sHeight; + } + } + if (Emulator.getPluginManager().isRegistered(FurnitureBuildheightEvent.class, true)) { FurnitureBuildheightEvent event = Emulator.getPluginManager().fireEvent(new FurnitureBuildheightEvent(item, owner, 0.00, height)); if (event.hasChangedHeight()) { @@ -4498,6 +4563,10 @@ public class Room implements Comparable, ISerialize, Runnable { } public FurnitureMovementError moveFurniTo(HabboItem item, RoomTile tile, int rotation, Habbo actor) { + return moveFurniTo(item, tile, rotation, actor, true); + } + + public FurnitureMovementError moveFurniTo(HabboItem item, RoomTile tile, int rotation, Habbo actor, boolean sendUpdates) { RoomTile oldLocation = this.layout.getTile(item.getX(), item.getY()); boolean pluginHelper = false; @@ -4509,8 +4578,6 @@ public class Room implements Comparable, ISerialize, Runnable { pluginHelper = event.hasPluginHelper(); } - HabboItem topItem = this.getTopItemAt(tile.x, tile.y); - boolean magicTile = item instanceof InteractionStackHelper; Optional stackHelper = this.getItemsAt(tile).stream().filter(i -> i instanceof InteractionStackHelper).findAny(); @@ -4518,8 +4585,10 @@ public class Room implements Comparable, ISerialize, Runnable { //Check if can be placed at new position THashSet occupiedTiles = this.layout.getTilesAt(tile, item.getBaseItem().getWidth(), item.getBaseItem().getLength(), rotation); + HabboItem topItem = this.getTopItemAt(occupiedTiles, null); + if (!stackHelper.isPresent() && !pluginHelper) { - if (topItem != item) { + if (oldLocation != tile) { for (RoomTile t : occupiedTiles) { HabboItem tileTopItem = this.getTopItemAt(t.x, t.y); if (!magicTile && ((tileTopItem != null && tileTopItem != item ? (t.state.equals(RoomTileState.INVALID) || !t.getAllowStack() || !tileTopItem.getBaseItem().allowStack()) : this.calculateTileState(t, item).equals(RoomTileState.INVALID)))) @@ -4543,9 +4612,9 @@ public class Room implements Comparable, ISerialize, Runnable { THashSet oldOccupiedTiles = this.layout.getTilesAt(this.layout.getTile(item.getX(), item.getY()), item.getBaseItem().getWidth(), item.getBaseItem().getLength(), item.getRotation()); int oldRotation = item.getRotation(); - item.setRotation(rotation); if (oldRotation != rotation) { + item.setRotation(rotation); if (Emulator.getPluginManager().isRegistered(FurnitureRotatedEvent.class, true)) { Event furnitureRotatedEvent = new FurnitureRotatedEvent(item, actor, oldRotation); Emulator.getPluginManager().fireEvent(furnitureRotatedEvent); @@ -4555,6 +4624,14 @@ public class Room implements Comparable, ISerialize, Runnable { return FurnitureMovementError.CANCEL_PLUGIN_ROTATE; } } + + if((!stackHelper.isPresent() && topItem != null && topItem != item && !topItem.getBaseItem().allowStack())|| (topItem != null && topItem != item && topItem.getZ() + Item.getCurrentHeight(topItem) + Item.getCurrentHeight(item) > MAXIMUM_FURNI_HEIGHT)) + { + item.setRotation(oldRotation); + return FurnitureMovementError.CANT_STACK; + } + + // ) } //Place at new position @@ -4562,10 +4639,16 @@ public class Room implements Comparable, ISerialize, Runnable { if (stackHelper.isPresent()) { height = stackHelper.get().getExtradata().isEmpty() ? Double.parseDouble("0.0") : (Double.parseDouble(stackHelper.get().getExtradata()) / 100); - } else if (item.equals(topItem) && tile.x == item.getX() && tile.y == item.getY()) { + } else if (item == topItem) { height = item.getZ(); } else { height = this.getStackHeight(tile.x, tile.y, false, item); + for(RoomTile til : occupiedTiles) { + double sHeight = this.getStackHeight(til.x, til.y, false, item); + if(sHeight > height) { + height = sHeight; + } + } } if (Emulator.getPluginManager().isRegistered(FurnitureBuildheightEvent.class, true)) { @@ -4575,7 +4658,8 @@ public class Room implements Comparable, ISerialize, Runnable { } } - if(height > 40d) return FurnitureMovementError.CANT_STACK; + if(height > MAXIMUM_FURNI_HEIGHT) return FurnitureMovementError.CANT_STACK; + if(height < this.getLayout().getHeightAtSquare(tile.x, tile.y)) return FurnitureMovementError.CANT_STACK; //prevent furni going under the floor item.setX(tile.x); item.setY(tile.y); @@ -4584,8 +4668,8 @@ public class Room implements Comparable, ISerialize, Runnable { item.setZ(tile.z); item.setExtradata("" + item.getZ() * 100); } - if (item.getZ() > 40d) { - item.setZ(40); + if (item.getZ() > MAXIMUM_FURNI_HEIGHT) { + item.setZ(MAXIMUM_FURNI_HEIGHT); } @@ -4594,7 +4678,10 @@ public class Room implements Comparable, ISerialize, Runnable { item.needsUpdate(true); Emulator.getThreading().run(item); - this.sendComposer(new FloorItemUpdateComposer(item).compose()); + if(sendUpdates) { + this.sendComposer(new FloorItemUpdateComposer(item).compose()); + } + //Update old & new tiles occupiedTiles.removeAll(oldOccupiedTiles); occupiedTiles.addAll(oldOccupiedTiles); @@ -4606,9 +4693,9 @@ public class Room implements Comparable, ISerialize, Runnable { t.x, t.y, this.getHabbosAt(t.x, t.y) - .stream() - .filter(h -> !h.getRoomUnit().hasStatus(RoomUnitStatus.MOVE)) - .collect(Collectors.toCollection(THashSet::new)) + /*.stream() + .filter(h -> !h.getRoomUnit().hasStatus(RoomUnitStatus.MOVE) || h.getRoomUnit().getGoal() == t) + .collect(Collectors.toCollection(THashSet::new))*/ ); this.updateBotsAt(t.x, t.y); } @@ -4644,8 +4731,8 @@ public class Room implements Comparable, ISerialize, Runnable { item.setZ(tile.z); item.setExtradata("" + item.getZ() * 100); } - if (item.getZ() > 40d) { - item.setZ(40); + if (item.getZ() > MAXIMUM_FURNI_HEIGHT) { + item.setZ(MAXIMUM_FURNI_HEIGHT); } double offset = this.getStackHeight(tile.x, tile.y, false, item) - item.getZ(); this.sendComposer(new FloorItemOnRollerComposer(item, null, tile, offset, this).compose()); @@ -4659,26 +4746,35 @@ public class Room implements Comparable, ISerialize, Runnable { } public THashSet getRoomUnits() { + return getRoomUnits(null); + } + + public THashSet getRoomUnits(RoomTile atTile) { THashSet units = new THashSet<>(); for (Habbo habbo : this.currentHabbos.values()) { - if (habbo != null && habbo.getRoomUnit() != null && habbo.getRoomUnit().getRoom() != null && habbo.getRoomUnit().getRoom().getId() == this.getId()) { + if (habbo != null && habbo.getRoomUnit() != null && habbo.getRoomUnit().getRoom() != null && habbo.getRoomUnit().getRoom().getId() == this.getId() && (atTile == null || habbo.getRoomUnit().getCurrentLocation() == atTile)) { units.add(habbo.getRoomUnit()); } } for (Pet pet : this.currentPets.valueCollection()) { - if (pet != null && pet.getRoomUnit() != null && pet.getRoomUnit().getRoom() != null && pet.getRoomUnit().getRoom().getId() == this.getId()) { + if (pet != null && pet.getRoomUnit() != null && pet.getRoomUnit().getRoom() != null && pet.getRoomUnit().getRoom().getId() == this.getId() && (atTile == null || pet.getRoomUnit().getCurrentLocation() == atTile)) { units.add(pet.getRoomUnit()); } } for (Bot bot : this.currentBots.valueCollection()) { - if (bot != null && bot.getRoomUnit() != null && bot.getRoomUnit().getRoom() != null && bot.getRoomUnit().getRoom().getId() == this.getId()) { + if (bot != null && bot.getRoomUnit() != null && bot.getRoomUnit().getRoom() != null && bot.getRoomUnit().getRoom().getId() == this.getId() && (atTile == null || bot.getRoomUnit().getCurrentLocation() == atTile)) { units.add(bot.getRoomUnit()); } } return units; } + + public Collection getRoomUnitsAt(RoomTile tile) { + THashSet roomUnits = getRoomUnits(); + return roomUnits.stream().filter(unit -> unit.getCurrentLocation() == tile).collect(Collectors.toSet()); + } } \ No newline at end of file diff --git a/src/main/java/com/eu/habbo/habbohotel/rooms/RoomLayout.java b/src/main/java/com/eu/habbo/habbohotel/rooms/RoomLayout.java index 80eec020..f70f3d3e 100644 --- a/src/main/java/com/eu/habbo/habbohotel/rooms/RoomLayout.java +++ b/src/main/java/com/eu/habbo/habbohotel/rooms/RoomLayout.java @@ -273,6 +273,8 @@ public class RoomLayout { List closedList = new LinkedList<>(); openList.add(oldTile.copy()); + RoomTile doorTile = this.room.getLayout().getDoorTile(); + while (!openList.isEmpty()) { RoomTile current = this.lowestFInOpen(openList); if (current.x == newTile.x && current.y == newTile.y) { @@ -286,7 +288,7 @@ public class RoomLayout { for (RoomTile currentAdj : adjacentNodes) { if (closedList.contains(currentAdj)) continue; - if (roomUnit.canOverrideTile(currentAdj) || (currentAdj.state != RoomTileState.BLOCKED && currentAdj.x == doorX && currentAdj.y == doorY)) { + if (roomUnit.canOverrideTile(currentAdj)) { currentAdj.setPrevious(current); currentAdj.sethCosts(this.findTile(openList, newTile.x, newTile.y)); currentAdj.setgCosts(current); @@ -301,9 +303,14 @@ public class RoomLayout { } double height = currentAdj.getStackHeight() - current.getStackHeight(); - if (!ALLOW_FALLING && height < -MAXIMUM_STEP_HEIGHT) continue; - if (currentAdj.state == RoomTileState.OPEN && height > MAXIMUM_STEP_HEIGHT) continue; - if (currentAdj.hasUnits() && ((!isWalktroughRetry && !this.room.isAllowWalkthrough()) || currentAdj.equals(goalLocation))) { + + if ((!ALLOW_FALLING && height < -MAXIMUM_STEP_HEIGHT) || (currentAdj.state == RoomTileState.OPEN && height > MAXIMUM_STEP_HEIGHT)) { + closedList.add(currentAdj); + openList.remove(currentAdj); + continue; + } + + if (currentAdj.hasUnits() && doorTile.distance(currentAdj) > 2 && (!isWalktroughRetry || !this.room.isAllowWalkthrough() || currentAdj.equals(goalLocation))) { closedList.add(currentAdj); openList.remove(currentAdj); continue; @@ -321,7 +328,7 @@ public class RoomLayout { } } - if (this.room.isAllowWalkthrough() && isWalktroughRetry) { + if (this.room.isAllowWalkthrough() && !isWalktroughRetry) { return this.findPath(oldTile, newTile, goalLocation, roomUnit, true); } diff --git a/src/main/java/com/eu/habbo/habbohotel/rooms/RoomManager.java b/src/main/java/com/eu/habbo/habbohotel/rooms/RoomManager.java index 2590f202..0f5b83b0 100644 --- a/src/main/java/com/eu/habbo/habbohotel/rooms/RoomManager.java +++ b/src/main/java/com/eu/habbo/habbohotel/rooms/RoomManager.java @@ -377,7 +377,7 @@ public class RoomManager { public void unloadRoomsForHabbo(Habbo habbo) { List roomsToDispose = new ArrayList<>(); for (Room room : this.activeRooms.values()) { - if (!room.isPublicRoom() && !room.isStaffPromotedRoom() && room.getOwnerId() == habbo.getHabboInfo().getId() && room.getUserCount() == 0 && !this.roomCategories.get(room.getCategory()).isPublic()) { + if (!room.isPublicRoom() && !room.isStaffPromotedRoom() && room.getOwnerId() == habbo.getHabboInfo().getId() && room.getUserCount() == 0 && (this.roomCategories.get(room.getCategory()) == null || !this.roomCategories.get(room.getCategory()).isPublic())) { roomsToDispose.add(room); } } diff --git a/src/main/java/com/eu/habbo/habbohotel/rooms/RoomSpecialTypes.java b/src/main/java/com/eu/habbo/habbohotel/rooms/RoomSpecialTypes.java index 0b912776..8a1a1799 100644 --- a/src/main/java/com/eu/habbo/habbohotel/rooms/RoomSpecialTypes.java +++ b/src/main/java/com/eu/habbo/habbohotel/rooms/RoomSpecialTypes.java @@ -100,7 +100,7 @@ public class RoomSpecialTypes { public InteractionBattleBanzaiTeleporter getRandomTeleporter(Item baseItem, InteractionBattleBanzaiTeleporter exclude) { List teleporterList = new ArrayList<>(); for (InteractionBattleBanzaiTeleporter teleporter : this.banzaiTeleporters.values()) { - if (teleporter.getBaseItem() == baseItem) { + if (baseItem == null || teleporter.getBaseItem() == baseItem) { teleporterList.add(teleporter); } } diff --git a/src/main/java/com/eu/habbo/habbohotel/rooms/RoomTrade.java b/src/main/java/com/eu/habbo/habbohotel/rooms/RoomTrade.java index c6ba64e0..f0706c97 100644 --- a/src/main/java/com/eu/habbo/habbohotel/rooms/RoomTrade.java +++ b/src/main/java/com/eu/habbo/habbohotel/rooms/RoomTrade.java @@ -8,6 +8,8 @@ import com.eu.habbo.messages.outgoing.inventory.AddHabboItemComposer; import com.eu.habbo.messages.outgoing.inventory.InventoryRefreshComposer; import com.eu.habbo.messages.outgoing.rooms.users.RoomUserStatusComposer; import com.eu.habbo.messages.outgoing.trading.*; +import com.eu.habbo.plugin.events.furniture.FurnitureRedeemedEvent; +import com.eu.habbo.plugin.events.trading.TradeConfirmEvent; import com.eu.habbo.threading.runnables.QueryDeleteHabboItem; import gnu.trove.set.hash.THashSet; import org.slf4j.Logger; @@ -145,6 +147,12 @@ public class RoomTrade { RoomTradeUser userOne = this.users.get(0); RoomTradeUser userTwo = this.users.get(1); + boolean tradeConfirmEventRegistered = Emulator.getPluginManager().isRegistered(TradeConfirmEvent.class, true); + TradeConfirmEvent tradeConfirmEvent = new TradeConfirmEvent(userOne, userTwo); + if (tradeConfirmEventRegistered) { + Emulator.getPluginManager().fireEvent(tradeConfirmEvent); + } + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection()) { int tradeId = 0; diff --git a/src/main/java/com/eu/habbo/habbohotel/rooms/RoomUnit.java b/src/main/java/com/eu/habbo/habbohotel/rooms/RoomUnit.java index 9521a75c..91843d65 100644 --- a/src/main/java/com/eu/habbo/habbohotel/rooms/RoomUnit.java +++ b/src/main/java/com/eu/habbo/habbohotel/rooms/RoomUnit.java @@ -37,6 +37,7 @@ public class RoomUnit { private static final Logger LOGGER = LoggerFactory.getLogger(RoomUnit.class); public boolean isWiredTeleporting = false; + public boolean isLeavingTeleporter = false; private final ConcurrentHashMap status; private final THashMap cacheable; public boolean canRotate = true; @@ -242,7 +243,8 @@ public class RoomUnit { //if(!(this.path.size() == 0 && canSitNextTile)) { - if (!room.tileWalkable(next)) { + double height = next.getStackHeight() - this.currentLocation.getStackHeight(); + if (!room.tileWalkable(next) || (!RoomLayout.ALLOW_FALLING && height < -RoomLayout.MAXIMUM_STEP_HEIGHT) || (next.state == RoomTileState.OPEN && height > RoomLayout.MAXIMUM_STEP_HEIGHT)) { this.room = room; this.path.clear(); this.findPath(); @@ -259,10 +261,10 @@ public class RoomUnit { boolean canSitNextTile = room.canSitAt(next.x, next.y); if (canSitNextTile) { - HabboItem lowestChair = room.getLowestChair(next); + HabboItem tallestChair = room.getTallestChair(next); - if (lowestChair != null) - item = lowestChair; + if (tallestChair != null) + item = tallestChair; } if (next.equals(this.goalLocation) && next.state == RoomTileState.SIT && !overrideChecks) { @@ -511,14 +513,14 @@ public class RoomUnit { this.startLocation = this.currentLocation; if (goalLocation != null && !noReset) { + boolean isWalking = this.hasStatus(RoomUnitStatus.MOVE); this.goalLocation = goalLocation; this.findPath(); ///< Quadral: this is where we start formulating a path if (!this.path.isEmpty()) { - this.tilesWalked = 0; + this.tilesWalked = isWalking ? this.tilesWalked : 0; this.cmdSit = false; } else { this.goalLocation = this.currentLocation; - } } } @@ -725,13 +727,12 @@ public class RoomUnit { if (room.getItemsAt(tile).stream().anyMatch(i -> i.canOverrideTile(this, room, tile))) return true; - int tileIndex = (room.getLayout().getMapSizeY() * tile.y) + tile.x + 1; + int tileIndex = (tile.x & 0xFF) | (tile.y << 12); return this.overridableTiles.contains(tileIndex); } public void addOverrideTile(RoomTile tile) { - if (!this.canOverrideTile(tile)) { return; } // Test if the Tile is overridable - int tileIndex = (room.getLayout().getMapSizeY() * tile.y) + tile.x + 1; + int tileIndex = (tile.x & 0xFF) | (tile.y << 12); if (!this.overridableTiles.contains(tileIndex)) { this.overridableTiles.add(tileIndex); } @@ -740,7 +741,7 @@ public class RoomUnit { public void removeOverrideTile(RoomTile tile) { if (room == null || room.getLayout() == null) return; - int tileIndex = (room.getLayout().getMapSizeY() * tile.y) + tile.x + 1; + int tileIndex = (tile.x & 0xFF) | (tile.y << 12); this.overridableTiles.remove(tileIndex); } diff --git a/src/main/java/com/eu/habbo/habbohotel/users/HabboItem.java b/src/main/java/com/eu/habbo/habbohotel/users/HabboItem.java index 93639f45..31f98ca8 100644 --- a/src/main/java/com/eu/habbo/habbohotel/users/HabboItem.java +++ b/src/main/java/com/eu/habbo/habbohotel/users/HabboItem.java @@ -243,6 +243,8 @@ public abstract class HabboItem implements Runnable, IEventTriggers { return this.limitedSells; } + public int getMaximumRotations() { return this.baseItem.getRotations(); } + @Override public void run() { try (Connection connection = Emulator.getDatabase().getDataSource().getConnection()) { @@ -301,12 +303,12 @@ public abstract class HabboItem implements Runnable, IEventTriggers { @Override public void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { - if (objects != null && objects.length >= 1 && objects[0] instanceof InteractionWired) - return; + /*if (objects != null && objects.length >= 1 && objects[0] instanceof InteractionWired) + return;*/ WiredHandler.handle(WiredTriggerType.WALKS_ON_FURNI, roomUnit, room, new Object[]{this}); - if ((this.getBaseItem().allowSit() || this.getBaseItem().allowLay()) && roomUnit.getDanceType() != DanceType.NONE) { + if ((this.getBaseItem().allowSit() || this.getBaseItem().allowLay()) && !roomUnit.getDanceType().equals(DanceType.NONE)) { roomUnit.setDanceType(DanceType.NONE); room.sendComposer(new RoomUserDanceComposer(roomUnit).compose()); } @@ -328,7 +330,9 @@ public abstract class HabboItem implements Runnable, IEventTriggers { @Override public void onWalkOff(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { - WiredHandler.handle(WiredTriggerType.WALKS_OFF_FURNI, roomUnit, room, new Object[]{this}); + if(objects != null && objects.length > 0) { + WiredHandler.handle(WiredTriggerType.WALKS_OFF_FURNI, roomUnit, room, new Object[]{this}); + } } public abstract void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception; @@ -376,23 +380,32 @@ public abstract class HabboItem implements Runnable, IEventTriggers { public void onPickUp(Room room) { if (this.getBaseItem().getEffectF() > 0 || this.getBaseItem().getEffectM() > 0) { + HabboItem topItem2 = room.getTopItemAt(this.getX(), this.getY(), this); + int nextEffectM = 0; + int nextEffectF = 0; + + if(topItem2 != null) { + nextEffectM = topItem2.getBaseItem().getEffectM(); + nextEffectF = topItem2.getBaseItem().getEffectF(); + } + for (Habbo habbo : room.getHabbosOnItem(this)) { if (this.getBaseItem().getEffectM() > 0 && habbo.getHabboInfo().getGender().equals(HabboGender.M) && habbo.getRoomUnit().getEffectId() == this.getBaseItem().getEffectM()) { - room.giveEffect(habbo, 0, -1); + room.giveEffect(habbo, nextEffectM, -1); } if (this.getBaseItem().getEffectF() > 0 && habbo.getHabboInfo().getGender().equals(HabboGender.F) && habbo.getRoomUnit().getEffectId() == this.getBaseItem().getEffectF()) { - room.giveEffect(habbo, 0, -1); + room.giveEffect(habbo, nextEffectF, -1); } } for (Bot bot : room.getBotsAt(room.getLayout().getTile(this.getX(), this.getY()))) { if (this.getBaseItem().getEffectM() > 0 && bot.getGender().equals(HabboGender.M) && bot.getRoomUnit().getEffectId() == this.getBaseItem().getEffectM()) { - room.giveEffect(bot.getRoomUnit(), 0, -1); + room.giveEffect(bot.getRoomUnit(), nextEffectM, -1); } if (this.getBaseItem().getEffectF() > 0 && bot.getGender().equals(HabboGender.F) && bot.getRoomUnit().getEffectId() == this.getBaseItem().getEffectF()) { - room.giveEffect(bot.getRoomUnit(), 0, -1); + room.giveEffect(bot.getRoomUnit(), nextEffectF, -1); } } } @@ -400,6 +413,15 @@ public abstract class HabboItem implements Runnable, IEventTriggers { public void onMove(Room room, RoomTile oldLocation, RoomTile newLocation) { if (this.getBaseItem().getEffectF() > 0 || this.getBaseItem().getEffectM() > 0) { + HabboItem topItem2 = room.getTopItemAt(oldLocation.x, oldLocation.y, this); + int nextEffectM = 0; + int nextEffectF = 0; + + if(topItem2 != null) { + nextEffectM = topItem2.getBaseItem().getEffectM(); + nextEffectF = topItem2.getBaseItem().getEffectF(); + } + List oldHabbos = new ArrayList<>(); List newHabbos = new ArrayList<>(); List oldBots = new ArrayList<>(); @@ -420,11 +442,11 @@ public abstract class HabboItem implements Runnable, IEventTriggers { for (Habbo habbo : oldHabbos) { if (this.getBaseItem().getEffectM() > 0 && habbo.getHabboInfo().getGender().equals(HabboGender.M) && habbo.getRoomUnit().getEffectId() == this.getBaseItem().getEffectM()) { - room.giveEffect(habbo, 0, -1); + room.giveEffect(habbo, nextEffectM, -1); } if (this.getBaseItem().getEffectF() > 0 && habbo.getHabboInfo().getGender().equals(HabboGender.F) && habbo.getRoomUnit().getEffectId() == this.getBaseItem().getEffectF()) { - room.giveEffect(habbo, 0, -1); + room.giveEffect(habbo, nextEffectF, -1); } } @@ -440,11 +462,11 @@ public abstract class HabboItem implements Runnable, IEventTriggers { for (Bot bot : oldBots) { if (this.getBaseItem().getEffectM() > 0 && bot.getGender().equals(HabboGender.M) && bot.getRoomUnit().getEffectId() == this.getBaseItem().getEffectM()) { - room.giveEffect(bot.getRoomUnit(), 0, -1); + room.giveEffect(bot.getRoomUnit(), nextEffectM, -1); } if (this.getBaseItem().getEffectF() > 0 && bot.getGender().equals(HabboGender.F) && bot.getRoomUnit().getEffectId() == this.getBaseItem().getEffectF()) { - room.giveEffect(bot.getRoomUnit(), 0, -1); + room.giveEffect(bot.getRoomUnit(), nextEffectF, -1); } } diff --git a/src/main/java/com/eu/habbo/habbohotel/users/HabboStats.java b/src/main/java/com/eu/habbo/habbohotel/users/HabboStats.java index 8f8f1382..603e9b9e 100644 --- a/src/main/java/com/eu/habbo/habbohotel/users/HabboStats.java +++ b/src/main/java/com/eu/habbo/habbohotel/users/HabboStats.java @@ -506,8 +506,8 @@ public class HabboStats implements Runnable { Constructor c = subClazz.getConstructor(Integer.class, Integer.class, String.class, Integer.class, Integer.class, Boolean.class); c.setAccessible(true); Subscription sub = c.newInstance(set.getInt(1), this.habboInfo.getId(), subscriptionType, startTimestamp, duration, true); - sub.onCreated(); this.subscriptions.add(sub); + sub.onCreated(); return sub; } catch (Exception e) { diff --git a/src/main/java/com/eu/habbo/habbohotel/wired/WiredChangeDirectionSetting.java b/src/main/java/com/eu/habbo/habbohotel/wired/WiredChangeDirectionSetting.java new file mode 100644 index 00000000..748bff4f --- /dev/null +++ b/src/main/java/com/eu/habbo/habbohotel/wired/WiredChangeDirectionSetting.java @@ -0,0 +1,15 @@ +package com.eu.habbo.habbohotel.wired; + +import com.eu.habbo.habbohotel.rooms.RoomUserRotation; + +public class WiredChangeDirectionSetting { + public final int item_id; + public int rotation; + public RoomUserRotation direction; + + public WiredChangeDirectionSetting(int itemId, int rotation, RoomUserRotation direction) { + this.item_id = itemId; + this.rotation = rotation; + this.direction = direction; + } +} diff --git a/src/main/java/com/eu/habbo/habbohotel/wired/WiredHandler.java b/src/main/java/com/eu/habbo/habbohotel/wired/WiredHandler.java index 98924182..9f27ad78 100644 --- a/src/main/java/com/eu/habbo/habbohotel/wired/WiredHandler.java +++ b/src/main/java/com/eu/habbo/habbohotel/wired/WiredHandler.java @@ -27,6 +27,7 @@ import com.eu.habbo.plugin.events.furniture.wired.WiredConditionFailedEvent; import com.eu.habbo.plugin.events.furniture.wired.WiredStackExecutedEvent; import com.eu.habbo.plugin.events.furniture.wired.WiredStackTriggeredEvent; import com.eu.habbo.plugin.events.users.UserWiredRewardReceived; +import com.google.gson.GsonBuilder; import gnu.trove.set.hash.THashSet; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -46,6 +47,8 @@ public class WiredHandler { public static int MAXIMUM_FURNI_SELECTION = 5; public static int TELEPORT_DELAY = 500; + private static GsonBuilder gsonBuilder = null; + public static boolean handle(WiredTriggerType triggerType, RoomUnit roomUnit, Room room, Object[] stuff) { if (triggerType == WiredTriggerType.CUSTOM) return false; @@ -68,6 +71,9 @@ public class WiredHandler { if (triggers == null || triggers.isEmpty()) return false; + long millis = System.currentTimeMillis(); + THashSet effectsToExecute = new THashSet(); + List triggeredTiles = new ArrayList<>(); for (InteractionWiredTrigger trigger : triggers) { RoomTile tile = room.getLayout().getTile(trigger.getX(), trigger.getY()); @@ -75,7 +81,11 @@ public class WiredHandler { if (triggeredTiles.contains(tile)) continue; - if (handle(trigger, roomUnit, room, stuff)) { + THashSet tEffectsToExecute = new THashSet(); + + if (handle(trigger, roomUnit, room, stuff, tEffectsToExecute)) { + effectsToExecute.addAll(tEffectsToExecute); + if (triggerType.equals(WiredTriggerType.SAY_SOMETHING)) talked = true; @@ -83,12 +93,14 @@ public class WiredHandler { } } + for (InteractionWiredEffect effect : effectsToExecute) { + triggerEffect(effect, roomUnit, room, stuff, millis); + } + return talked; } public static boolean handleCustomTrigger(Class triggerType, RoomUnit roomUnit, Room room, Object[] stuff) { - boolean talked = false; - if (!Emulator.isReady) return false; @@ -106,6 +118,9 @@ public class WiredHandler { if (triggers == null || triggers.isEmpty()) return false; + long millis = System.currentTimeMillis(); + THashSet effectsToExecute = new THashSet(); + List triggeredTiles = new ArrayList<>(); for (InteractionWiredTrigger trigger : triggers) { if (trigger.getClass() != triggerType) continue; @@ -115,18 +130,37 @@ public class WiredHandler { if (triggeredTiles.contains(tile)) continue; - if (handle(trigger, roomUnit, room, stuff)) { + THashSet tEffectsToExecute = new THashSet(); + + if (handle(trigger, roomUnit, room, stuff, tEffectsToExecute)) { + effectsToExecute.addAll(tEffectsToExecute); triggeredTiles.add(tile); } } - return talked; + for (InteractionWiredEffect effect : effectsToExecute) { + triggerEffect(effect, roomUnit, room, stuff, millis); + } + + return effectsToExecute.size() > 0; } public static boolean handle(InteractionWiredTrigger trigger, final RoomUnit roomUnit, final Room room, final Object[] stuff) { + long millis = System.currentTimeMillis(); + THashSet effectsToExecute = new THashSet(); + + if(handle(trigger, roomUnit, room, stuff, effectsToExecute)) { + for (InteractionWiredEffect effect : effectsToExecute) { + triggerEffect(effect, roomUnit, room, stuff, millis); + } + return true; + } + return false; + } + + public static boolean handle(InteractionWiredTrigger trigger, final RoomUnit roomUnit, final Room room, final Object[] stuff, final THashSet effectsToExecute) { long millis = System.currentTimeMillis(); if (Emulator.isReady && trigger.canExecute(millis) && trigger.execute(roomUnit, room, stuff)) { - trigger.setCooldown(millis); trigger.activateBox(room); THashSet conditions = room.getRoomSpecialTypes().getConditions(trigger.getX(), trigger.getY()); @@ -152,6 +186,7 @@ public class WiredHandler { } } + trigger.setCooldown(millis); boolean hasExtraRandom = room.getRoomSpecialTypes().hasExtraType(trigger.getX(), trigger.getY(), WiredExtraRandom.class); boolean hasExtraUnseen = room.getRoomSpecialTypes().hasExtraType(trigger.getX(), trigger.getY(), WiredExtraUnseen.class); @@ -173,13 +208,13 @@ public class WiredHandler { if (extra instanceof WiredExtraUnseen) { extra.setExtradata(extra.getExtradata().equals("1") ? "0" : "1"); InteractionWiredEffect effect = ((WiredExtraUnseen) extra).getUnseenEffect(effectList); - triggerEffect(effect, roomUnit, room, stuff, millis); + effectsToExecute.add(effect); // triggerEffect(effect, roomUnit, room, stuff, millis); break; } } } else { for (final InteractionWiredEffect effect : effectList) { - boolean executed = triggerEffect(effect, roomUnit, room, stuff, millis); + boolean executed = effectsToExecute.add(effect); //triggerEffect(effect, roomUnit, room, stuff, millis); if (hasExtraRandom && executed) { break; } @@ -215,6 +250,12 @@ public class WiredHandler { return executed; } + public static GsonBuilder getGsonBuilder() { + if(gsonBuilder == null) { + gsonBuilder = new GsonBuilder(); + } + return gsonBuilder; + } public static boolean executeEffectsAtTiles(THashSet tiles, final RoomUnit roomUnit, final Room room, final Object[] stuff) { for (RoomTile tile : tiles) { diff --git a/src/main/java/com/eu/habbo/habbohotel/wired/WiredMatchFurniSetting.java b/src/main/java/com/eu/habbo/habbohotel/wired/WiredMatchFurniSetting.java index ea6797f1..7771450b 100644 --- a/src/main/java/com/eu/habbo/habbohotel/wired/WiredMatchFurniSetting.java +++ b/src/main/java/com/eu/habbo/habbohotel/wired/WiredMatchFurniSetting.java @@ -1,14 +1,14 @@ package com.eu.habbo.habbohotel.wired; public class WiredMatchFurniSetting { - public final int itemId; + public final int item_id; public final String state; public final int rotation; public final int x; public final int y; public WiredMatchFurniSetting(int itemId, String state, int rotation, int x, int y) { - this.itemId = itemId; + this.item_id = itemId; this.state = state.replace("\t\t\t", " "); this.rotation = rotation; this.x = x; @@ -21,7 +21,7 @@ public class WiredMatchFurniSetting { } public String toString(boolean includeState) { - return this.itemId + "-" + (this.state.isEmpty() || !includeState ? " " : this.state) + "-" + this.rotation + "-" + this.x + "-" + this.y; + return this.item_id + "-" + (this.state.isEmpty() || !includeState ? " " : this.state) + "-" + this.rotation + "-" + this.x + "-" + this.y; } } diff --git a/src/main/java/com/eu/habbo/messages/incoming/catalog/CatalogBuyItemEvent.java b/src/main/java/com/eu/habbo/messages/incoming/catalog/CatalogBuyItemEvent.java index b0264ace..68a54353 100644 --- a/src/main/java/com/eu/habbo/messages/incoming/catalog/CatalogBuyItemEvent.java +++ b/src/main/java/com/eu/habbo/messages/incoming/catalog/CatalogBuyItemEvent.java @@ -7,6 +7,7 @@ import com.eu.habbo.habbohotel.catalog.layouts.*; import com.eu.habbo.habbohotel.items.FurnitureType; import com.eu.habbo.habbohotel.permissions.Permission; import com.eu.habbo.habbohotel.pets.PetManager; +import com.eu.habbo.habbohotel.rooms.RoomManager; import com.eu.habbo.habbohotel.users.HabboBadge; import com.eu.habbo.habbohotel.users.HabboInventory; import com.eu.habbo.habbohotel.users.subscriptions.Subscription; @@ -96,7 +97,7 @@ public class CatalogBuyItemEvent extends MessageHandler { return; } int roomCount = Emulator.getGameEnvironment().getRoomManager().getRoomsForHabbo(this.client.getHabbo()).size(); - int maxRooms = this.client.getHabbo().getHabboStats().hasActiveClub() ? Emulator.getConfig().getInt("hotel.max.rooms.vip") : Emulator.getConfig().getInt("hotel.max.rooms.user"); + int maxRooms = this.client.getHabbo().getHabboStats().hasActiveClub() ? RoomManager.MAXIMUM_ROOMS_HC : RoomManager.MAXIMUM_ROOMS_USER; if (roomCount >= maxRooms) { // checks if a user has the maximum rooms this.client.sendResponse(new CanCreateRoomComposer(roomCount, maxRooms)); // if so throws the max room error. diff --git a/src/main/java/com/eu/habbo/messages/incoming/rooms/items/SetStackHelperHeightEvent.java b/src/main/java/com/eu/habbo/messages/incoming/rooms/items/SetStackHelperHeightEvent.java index a46bb7d2..dce31447 100644 --- a/src/main/java/com/eu/habbo/messages/incoming/rooms/items/SetStackHelperHeightEvent.java +++ b/src/main/java/com/eu/habbo/messages/incoming/rooms/items/SetStackHelperHeightEvent.java @@ -34,7 +34,7 @@ public class SetStackHelperHeightEvent extends MessageHandler { } } } else { - stackerHeight = Math.min(Math.max(stackerHeight, itemTile.z * 100), 4000); + stackerHeight = Math.min(Math.max(stackerHeight, itemTile.z * 100), Room.MAXIMUM_FURNI_HEIGHT * 100); } double height = 0; diff --git a/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserLookAtPoint.java b/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserLookAtPoint.java index 24e8004c..f4f7c005 100644 --- a/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserLookAtPoint.java +++ b/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserLookAtPoint.java @@ -51,7 +51,8 @@ public class RoomUserLookAtPoint extends MessageHandler { if (tile != null) { roomUnit.lookAtPoint(tile); - room.sendComposer(new RoomUserStatusComposer(roomUnit).compose()); + roomUnit.statusUpdate(true); + //room.sendComposer(new RoomUserStatusComposer(roomUnit).compose()); } } } diff --git a/src/main/java/com/eu/habbo/messages/incoming/wired/WiredEffectSaveDataEvent.java b/src/main/java/com/eu/habbo/messages/incoming/wired/WiredEffectSaveDataEvent.java index 98ace187..fbf51226 100644 --- a/src/main/java/com/eu/habbo/messages/incoming/wired/WiredEffectSaveDataEvent.java +++ b/src/main/java/com/eu/habbo/messages/incoming/wired/WiredEffectSaveDataEvent.java @@ -5,6 +5,8 @@ import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect; import com.eu.habbo.habbohotel.permissions.Permission; import com.eu.habbo.habbohotel.rooms.Room; import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.generic.alerts.GenericErrorMessagesComposer; +import com.eu.habbo.messages.outgoing.generic.alerts.UpdateFailedComposer; import com.eu.habbo.messages.outgoing.wired.WiredSavedComposer; public class WiredEffectSaveDataEvent extends MessageHandler { @@ -18,13 +20,19 @@ public class WiredEffectSaveDataEvent extends MessageHandler { if (room.hasRights(this.client.getHabbo()) || room.getOwnerId() == this.client.getHabbo().getHabboInfo().getId() || this.client.getHabbo().hasPermission(Permission.ACC_ANYROOMOWNER) || this.client.getHabbo().hasPermission(Permission.ACC_MOVEROTATE)) { InteractionWiredEffect effect = room.getRoomSpecialTypes().getEffect(itemId); - if (effect != null) { + try { + if (effect == null) + throw new WiredSaveException(String.format("Wired effect with item id %s not found in room", itemId)); + if (effect.saveData(this.packet, this.client)) { this.client.sendResponse(new WiredSavedComposer()); effect.needsUpdate(true); Emulator.getThreading().run(effect); } } + catch (WiredSaveException e) { + this.client.sendResponse(new UpdateFailedComposer(e.getMessage())); + } } } } diff --git a/src/main/java/com/eu/habbo/messages/incoming/wired/WiredSaveException.java b/src/main/java/com/eu/habbo/messages/incoming/wired/WiredSaveException.java new file mode 100644 index 00000000..74feda15 --- /dev/null +++ b/src/main/java/com/eu/habbo/messages/incoming/wired/WiredSaveException.java @@ -0,0 +1,15 @@ +package com.eu.habbo.messages.incoming.wired; + +public class WiredSaveException extends Exception { + + private final String message; + + public WiredSaveException(String message) { + this.message = message; + } + + @Override + public String getMessage() { + return this.message; + } +} diff --git a/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/FloorItemOnRollerComposer.java b/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/FloorItemOnRollerComposer.java index abf2eee4..878b9490 100644 --- a/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/FloorItemOnRollerComposer.java +++ b/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/FloorItemOnRollerComposer.java @@ -8,12 +8,16 @@ import com.eu.habbo.messages.outgoing.MessageComposer; import com.eu.habbo.messages.outgoing.Outgoing; import com.eu.habbo.messages.outgoing.rooms.UpdateStackHeightComposer; import gnu.trove.set.hash.THashSet; +import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; public class FloorItemOnRollerComposer extends MessageComposer { private final HabboItem item; private final HabboItem roller; + private final RoomTile oldLocation; private final RoomTile newLocation; private final double heightOffset; + private final double oldZ; + private final double newZ; private final Room room; public FloorItemOnRollerComposer(HabboItem item, HabboItem roller, RoomTile newLocation, double heightOffset, Room room) { @@ -22,6 +26,20 @@ public class FloorItemOnRollerComposer extends MessageComposer { this.newLocation = newLocation; this.heightOffset = heightOffset; this.room = room; + this.oldLocation = null; + this.oldZ = -1; + this.newZ = -1; + } + + public FloorItemOnRollerComposer(HabboItem item, HabboItem roller, RoomTile oldLocation, double oldZ, RoomTile newLocation, double newZ, double heightOffset, Room room) { + this.item = item; + this.roller = roller; + this.oldLocation = oldLocation; + this.oldZ = oldZ; + this.newLocation = newLocation; + this.newZ = newZ; + this.heightOffset = heightOffset; + this.room = room; } @Override @@ -30,30 +48,32 @@ public class FloorItemOnRollerComposer extends MessageComposer { short oldY = this.item.getY(); this.response.init(Outgoing.ObjectOnRollerComposer); - this.response.appendInt(this.item.getX()); - this.response.appendInt(this.item.getY()); + this.response.appendInt(this.oldLocation != null ? this.oldLocation.x : this.item.getX()); + this.response.appendInt(this.oldLocation != null ? this.oldLocation.y : this.item.getY()); this.response.appendInt(this.newLocation.x); this.response.appendInt(this.newLocation.y); this.response.appendInt(1); this.response.appendInt(this.item.getId()); - this.response.appendString(Double.toString(this.item.getZ())); - this.response.appendString(Double.toString(this.item.getZ() + this.heightOffset)); + this.response.appendString(Double.toString(this.oldLocation != null ? this.oldZ : this.item.getZ())); + this.response.appendString(Double.toString(this.oldLocation != null ? this.newZ : (this.item.getZ() + this.heightOffset))); this.response.appendInt(this.roller != null ? this.roller.getId() : -1); - this.item.onMove(this.room, this.room.getLayout().getTile(this.item.getX(), this.item.getY()), this.newLocation); - this.item.setX(this.newLocation.x); - this.item.setY(this.newLocation.y); - this.item.setZ(this.item.getZ() + this.heightOffset); - this.item.needsUpdate(true); + if(this.oldLocation == null) { + this.item.onMove(this.room, this.room.getLayout().getTile(this.item.getX(), this.item.getY()), this.newLocation); + this.item.setX(this.newLocation.x); + this.item.setY(this.newLocation.y); + this.item.setZ(this.item.getZ() + this.heightOffset); + this.item.needsUpdate(true); - //TODO This is bad - // - THashSet tiles = this.room.getLayout().getTilesAt(this.room.getLayout().getTile(oldX, oldY), this.item.getBaseItem().getWidth(), this.item.getBaseItem().getLength(), this.item.getRotation()); - tiles.addAll(this.room.getLayout().getTilesAt(this.room.getLayout().getTile(this.item.getX(), this.item.getY()), this.item.getBaseItem().getWidth(), this.item.getBaseItem().getLength(), this.item.getRotation())); - this.room.updateTiles(tiles); - this.room.sendComposer(new UpdateStackHeightComposer(oldX, oldY, this.room.getStackHeight(oldX, oldY, true)).compose()); - // - //this.room.updateHabbosAt(RoomLayout.getRectangle(this.item.getX(), this.item.getY(), this.item.getBaseItem().getWidth(), this.item.getBaseItem().getLength(), this.item.getRotation())); + //TODO This is bad + // + THashSet tiles = this.room.getLayout().getTilesAt(this.room.getLayout().getTile(oldX, oldY), this.item.getBaseItem().getWidth(), this.item.getBaseItem().getLength(), this.item.getRotation()); + tiles.addAll(this.room.getLayout().getTilesAt(this.room.getLayout().getTile(this.item.getX(), this.item.getY()), this.item.getBaseItem().getWidth(), this.item.getBaseItem().getLength(), this.item.getRotation())); + this.room.updateTiles(tiles); + //this.room.sendComposer(new UpdateStackHeightComposer(oldX, oldY, this.room.getStackHeight(oldX, oldY, true)).compose()); + // + //this.room.updateHabbosAt(RoomLayout.getRectangle(this.item.getX(), this.item.getY(), this.item.getBaseItem().getWidth(), this.item.getBaseItem().getLength(), this.item.getRotation())); + } return this.response; } diff --git a/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUnitOnRollerComposer.java b/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUnitOnRollerComposer.java index 863792d7..70df0b1c 100644 --- a/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUnitOnRollerComposer.java +++ b/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUnitOnRollerComposer.java @@ -5,10 +5,12 @@ import com.eu.habbo.habbohotel.items.interactions.InteractionRoller; import com.eu.habbo.habbohotel.rooms.Room; import com.eu.habbo.habbohotel.rooms.RoomTile; 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.messages.ServerMessage; import com.eu.habbo.messages.outgoing.MessageComposer; import com.eu.habbo.messages.outgoing.Outgoing; +import gnu.trove.set.hash.THashSet; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -23,6 +25,7 @@ public class RoomUnitOnRollerComposer extends MessageComposer { private final Room room; private int x; private int y; + private HabboItem oldTopItem; public RoomUnitOnRollerComposer(RoomUnit roomUnit, HabboItem roller, RoomTile oldLocation, double oldZ, RoomTile newLocation, double newZ, Room room) { this.roomUnit = roomUnit; @@ -32,6 +35,7 @@ public class RoomUnitOnRollerComposer extends MessageComposer { this.newLocation = newLocation; this.newZ = newZ; this.room = room; + oldTopItem = this.room.getTopItemAt(oldLocation.x, oldLocation.y); } public RoomUnitOnRollerComposer(RoomUnit roomUnit, RoomTile newLocation, Room room) { @@ -42,6 +46,7 @@ public class RoomUnitOnRollerComposer extends MessageComposer { this.newLocation = newLocation; this.newZ = this.newLocation.getStackHeight(); this.room = room; + this.oldTopItem = null; } @Override @@ -62,25 +67,53 @@ public class RoomUnitOnRollerComposer extends MessageComposer { this.response.appendString(this.newZ + ""); if (this.roller != null && room.getLayout() != null) { - RoomTile rollerTile = room.getLayout().getTile(this.roller.getX(), this.roller.getY()); - HabboItem topItem = this.room.getTopItemAt(this.roomUnit.getCurrentLocation().x, this.roomUnit.getCurrentLocation().y); - if (topItem != null) { - try { - topItem.onWalkOff(this.roomUnit, this.room, new Object[]{this}); - } catch (Exception e) { - LOGGER.error("Caught exception", e); - } - } Emulator.getThreading().run(() -> { - if (RoomUnitOnRollerComposer.this.oldLocation == rollerTile && RoomUnitOnRollerComposer.this.roomUnit.getGoal() == rollerTile) { - RoomUnitOnRollerComposer.this.roomUnit.setLocation(room.getLayout().getTile(newLocation.x, newLocation.y)); - RoomUnitOnRollerComposer.this.roomUnit.setPreviousLocationZ(RoomUnitOnRollerComposer.this.newLocation.getStackHeight()); - RoomUnitOnRollerComposer.this.roomUnit.setZ(RoomUnitOnRollerComposer.this.newLocation.getStackHeight()); - RoomUnitOnRollerComposer.this.roomUnit.sitUpdate = true; + if(!this.roomUnit.isWalking() && this.roomUnit.getCurrentLocation() == this.oldLocation) { + HabboItem topItem = this.room.getTopItemAt(this.oldLocation.x, this.oldLocation.y); + HabboItem topItemNewLocation = this.room.getTopItemAt(this.newLocation.x, this.newLocation.y); + if (topItem != null && (oldTopItem == null || oldTopItem != topItemNewLocation)) { + try { + topItem.onWalkOff(this.roomUnit, this.room, new Object[]{this}); + } catch (Exception e) { + LOGGER.error("Caught exception", e); + } + } + + this.roomUnit.setLocation(this.newLocation); + this.roomUnit.setZ(this.newLocation.getStackHeight()); + this.roomUnit.setPreviousLocationZ(this.newLocation.getStackHeight()); + + if (topItemNewLocation != null && topItemNewLocation != roller && oldTopItem != topItemNewLocation) { + try { + topItemNewLocation.onWalkOn(this.roomUnit, this.room, new Object[]{this}); + } catch (Exception e) { + LOGGER.error("Caught exception", e); + } + } } - }, this.room.getRollerSpeed() == 0 ? 250 : InteractionRoller.DELAY); + /* + RoomTile rollerTile = room.getLayout().getTile(this.roller.getX(), this.roller.getY()); + Emulator.getThreading().run(() -> { + if (this.oldLocation == rollerTile && this.roomUnit.getGoal() == rollerTile) { + this.roomUnit.setLocation(newLocation); + this.roomUnit.setGoalLocation(newLocation); + this.roomUnit.setPreviousLocationZ(newLocation.getStackHeight()); + this.roomUnit.setZ(newLocation.getStackHeight()); + this.roomUnit.sitUpdate = true; + + HabboItem topItem = this.room.getTopItemAt(this.roomUnit.getCurrentLocation().x, this.roomUnit.getCurrentLocation().y); + if (topItem != null && topItem != roller && oldTopItem != topItem) { + try { + topItem.onWalkOff(this.roomUnit, this.room, new Object[]{this}); + } catch (Exception e) { + LOGGER.error("Caught exception", e); + } + } + } + }, this.room.getRollerSpeed() == 0 ? 250 : InteractionRoller.DELAY); + */ } else { this.roomUnit.setLocation(this.newLocation); this.roomUnit.setZ(this.newZ); diff --git a/src/main/java/com/eu/habbo/plugin/events/furniture/FurnitureRedeemedEvent.java b/src/main/java/com/eu/habbo/plugin/events/furniture/FurnitureRedeemedEvent.java index dbf63128..ce2dd0dc 100644 --- a/src/main/java/com/eu/habbo/plugin/events/furniture/FurnitureRedeemedEvent.java +++ b/src/main/java/com/eu/habbo/plugin/events/furniture/FurnitureRedeemedEvent.java @@ -4,17 +4,13 @@ import com.eu.habbo.habbohotel.users.Habbo; import com.eu.habbo.habbohotel.users.HabboItem; public class FurnitureRedeemedEvent extends FurnitureUserEvent { - public static final int CREDITS = 0; - public static final int PIXELS = 1; + public static final int CREDITS = -1; + public static final int PIXELS = 0; public static final int DIAMONDS = 5; - public final int amount; - - public final int currencyID; - public FurnitureRedeemedEvent(HabboItem furniture, Habbo habbo, int amount, int currencyID) { super(furniture, habbo); diff --git a/src/main/java/com/eu/habbo/plugin/events/trading/TradeConfirmEvent.java b/src/main/java/com/eu/habbo/plugin/events/trading/TradeConfirmEvent.java new file mode 100644 index 00000000..ee42fd2f --- /dev/null +++ b/src/main/java/com/eu/habbo/plugin/events/trading/TradeConfirmEvent.java @@ -0,0 +1,14 @@ +package com.eu.habbo.plugin.events.trading; + +import com.eu.habbo.habbohotel.rooms.RoomTradeUser; +import com.eu.habbo.plugin.Event; + +public class TradeConfirmEvent extends Event { + public final RoomTradeUser userOne; + public final RoomTradeUser userTwo; + + public TradeConfirmEvent(RoomTradeUser userOne, RoomTradeUser userTwo) { + this.userOne = userOne; + this.userTwo = userTwo; + } +} diff --git a/src/main/java/com/eu/habbo/threading/runnables/BanzaiRandomTeleport.java b/src/main/java/com/eu/habbo/threading/runnables/BanzaiRandomTeleport.java index c372652a..d559daed 100644 --- a/src/main/java/com/eu/habbo/threading/runnables/BanzaiRandomTeleport.java +++ b/src/main/java/com/eu/habbo/threading/runnables/BanzaiRandomTeleport.java @@ -2,9 +2,11 @@ package com.eu.habbo.threading.runnables; import com.eu.habbo.Emulator; import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; import com.eu.habbo.habbohotel.rooms.RoomUnit; import com.eu.habbo.habbohotel.rooms.RoomUserRotation; import com.eu.habbo.habbohotel.users.HabboItem; +import org.slf4j.LoggerFactory; public class BanzaiRandomTeleport implements Runnable { private final HabboItem item; @@ -21,12 +23,52 @@ public class BanzaiRandomTeleport implements Runnable { @Override public void run() { - this.habbo.setCanWalk(true); - this.item.setExtradata("0"); - this.toItem.setExtradata("0"); - this.room.updateItem(this.item); - this.room.updateItem(this.toItem); - this.habbo.setRotation(RoomUserRotation.fromValue(Emulator.getRandom().nextInt(8))); - this.room.teleportRoomUnitToItem(this.habbo, this.toItem); + HabboItem topItemNow = this.room.getTopItemAt(this.habbo.getX(), this.habbo.getY()); + RoomTile lastLocation = this.habbo.getCurrentLocation(); + RoomTile newLocation = this.room.getLayout().getTile(toItem.getX(), toItem.getY()); + + if(topItemNow != null) { + try { + topItemNow.onWalkOff(this.habbo, this.room, new Object[] { lastLocation, newLocation, this }); + } catch (Exception e) { + LoggerFactory.getLogger(BanzaiRandomTeleport.class).error("BanzaiRandomTeleport exception", e); + } + } + + Emulator.getThreading().run(() -> { + if (this.item.getExtradata().equals("1")) { + this.item.setExtradata("0"); + this.room.updateItemState(this.item); + } + }, 500); + + if(!this.toItem.getExtradata().equals("1")) { + this.toItem.setExtradata("1"); + this.room.updateItemState(this.toItem); + } + + Emulator.getThreading().run(() -> { + this.habbo.setCanWalk(true); + HabboItem topItemNext = this.room.getTopItemAt(this.habbo.getX(), this.habbo.getY()); + + if(topItemNext != null) { + try { + topItemNext.onWalkOn(this.habbo, this.room, new Object[] { lastLocation, newLocation, this }); + } catch (Exception e) { + LoggerFactory.getLogger(BanzaiRandomTeleport.class).error("BanzaiRandomTeleport exception", e); + } + } + + if (this.toItem.getExtradata().equals("1")) { + this.toItem.setExtradata("0"); + this.room.updateItemState(this.toItem); + } + }, 750); + + Emulator.getThreading().run(() -> { + this.habbo.setRotation(RoomUserRotation.fromValue(Emulator.getRandom().nextInt(8))); + this.room.teleportRoomUnitToLocation(this.habbo, newLocation.x, newLocation.y, newLocation.getStackHeight()); + }, 250); + } } diff --git a/src/main/java/com/eu/habbo/threading/runnables/BotFollowHabbo.java b/src/main/java/com/eu/habbo/threading/runnables/BotFollowHabbo.java index b6926f62..11642074 100644 --- a/src/main/java/com/eu/habbo/threading/runnables/BotFollowHabbo.java +++ b/src/main/java/com/eu/habbo/threading/runnables/BotFollowHabbo.java @@ -5,16 +5,20 @@ import com.eu.habbo.habbohotel.bots.Bot; 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.wired.WiredHandler; +import com.eu.habbo.habbohotel.wired.WiredTriggerType; public class BotFollowHabbo implements Runnable { private final Bot bot; private final Habbo habbo; private final Room room; + private boolean hasReached; public BotFollowHabbo(Bot bot, Habbo habbo, Room room) { this.bot = bot; this.habbo = habbo; this.room = room; + this.hasReached = false; } @Override @@ -30,6 +34,16 @@ public class BotFollowHabbo implements Runnable { if (target.x < 0 || target.y < 0) target = this.room.getLayout().getTileInFront(this.habbo.getRoomUnit().getCurrentLocation(), this.habbo.getRoomUnit().getBodyRotation().getValue()); + if(this.habbo.getRoomUnit().getCurrentLocation().distance(this.bot.getRoomUnit().getCurrentLocation()) < 2) { + if(!hasReached) { + WiredHandler.handle(WiredTriggerType.BOT_REACHED_AVTR, bot.getRoomUnit(), room, new Object[]{}); + hasReached = true; + } + } + else { + hasReached = false; + } + if (target.x >= 0 && target.y >= 0) { this.bot.getRoomUnit().setGoalLocation(target); this.bot.getRoomUnit().setCanWalk(true); diff --git a/src/main/java/com/eu/habbo/threading/runnables/RoomUnitTeleport.java b/src/main/java/com/eu/habbo/threading/runnables/RoomUnitTeleport.java index 9228596a..9cbe83c6 100644 --- a/src/main/java/com/eu/habbo/threading/runnables/RoomUnitTeleport.java +++ b/src/main/java/com/eu/habbo/threading/runnables/RoomUnitTeleport.java @@ -30,15 +30,15 @@ public class RoomUnitTeleport implements Runnable { this.y = y; this.z = z; this.newEffect = newEffect; - roomUnit.isWiredTeleporting = true; } @Override public void run() { - if (roomUnit == null || roomUnit.getRoom() == null || room.getLayout() == null) + if (roomUnit == null || roomUnit.getRoom() == null || room.getLayout() == null || roomUnit.isLeavingTeleporter) return; - - RoomTile t = this.room.getLayout().getTile((short) this.x, (short) this.y); + + RoomTile lastLocation = this.roomUnit.getCurrentLocation(); + RoomTile newLocation = this.room.getLayout().getTile((short) this.x, (short) this.y); HabboItem topItem = this.room.getTopItemAt(this.roomUnit.getCurrentLocation().x, this.roomUnit.getCurrentLocation().y); if (topItem != null) { @@ -49,23 +49,24 @@ public class RoomUnitTeleport implements Runnable { } } this.roomUnit.setPath(new LinkedList<>()); - this.roomUnit.setCurrentLocation(t); - this.roomUnit.setPreviousLocation(t); + this.roomUnit.setCurrentLocation(newLocation); + this.roomUnit.setPreviousLocation(newLocation); this.roomUnit.setZ(this.z); this.roomUnit.setPreviousLocationZ(this.z); this.roomUnit.removeStatus(RoomUnitStatus.MOVE); - ServerMessage teleportMessage = new RoomUnitOnRollerComposer(this.roomUnit, t, this.room).compose(); - this.roomUnit.setLocation(t); - this.room.sendComposer(teleportMessage); + //ServerMessage teleportMessage = new RoomUnitOnRollerComposer(this.roomUnit, newLocation, this.room).compose(); + this.roomUnit.setLocation(newLocation); + //this.room.sendComposer(teleportMessage); + this.roomUnit.statusUpdate(true); roomUnit.isWiredTeleporting = false; - this.room.updateHabbosAt(t.x, t.y); - this.room.updateBotsAt(t.x, t.y); + this.room.updateHabbosAt(newLocation.x, newLocation.y); + this.room.updateBotsAt(newLocation.x, newLocation.y); topItem = room.getTopItemAt(x, y); if (topItem != null && roomUnit.getCurrentLocation().equals(room.getLayout().getTile((short) x, (short) y))) { try { - topItem.onWalkOn(roomUnit, room, new Object[]{}); + topItem.onWalkOn(roomUnit, room, new Object[]{ lastLocation, newLocation, this }); } catch (Exception e) { } } diff --git a/src/main/java/com/eu/habbo/threading/runnables/RoomUnitWalkToLocation.java b/src/main/java/com/eu/habbo/threading/runnables/RoomUnitWalkToLocation.java index 7a648ff0..a2f65db7 100644 --- a/src/main/java/com/eu/habbo/threading/runnables/RoomUnitWalkToLocation.java +++ b/src/main/java/com/eu/habbo/threading/runnables/RoomUnitWalkToLocation.java @@ -4,6 +4,7 @@ import com.eu.habbo.Emulator; import com.eu.habbo.habbohotel.rooms.Room; import com.eu.habbo.habbohotel.rooms.RoomTile; import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; import java.util.ArrayList; import java.util.List; @@ -47,7 +48,7 @@ public class RoomUnitWalkToLocation implements Runnable { return; } - if (!this.walker.getGoal().equals(this.goalTile)) { + if (!this.walker.getGoal().equals(this.goalTile) || (this.walker.getPath().size() == 0 && !this.walker.hasStatus(RoomUnitStatus.MOVE))) { onFail(); return; } diff --git a/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionFive.java b/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionFive.java index 674dfba3..9072a33d 100644 --- a/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionFive.java +++ b/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionFive.java @@ -3,11 +3,10 @@ package com.eu.habbo.threading.runnables.teleport; import com.eu.habbo.Emulator; import com.eu.habbo.habbohotel.gameclients.GameClient; import com.eu.habbo.habbohotel.items.interactions.InteractionTeleportTile; -import com.eu.habbo.habbohotel.rooms.Room; -import com.eu.habbo.habbohotel.rooms.RoomTile; -import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.rooms.*; import com.eu.habbo.habbohotel.users.Habbo; import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserStatusComposer; import com.eu.habbo.threading.runnables.HabboItemNewState; import com.eu.habbo.threading.runnables.RoomUnitWalkToLocation; @@ -29,6 +28,7 @@ class TeleportActionFive implements Runnable { public void run() { RoomUnit unit = this.client.getHabbo().getRoomUnit(); + unit.isLeavingTeleporter = false; unit.isTeleporting = false; unit.setCanWalk(true); @@ -46,11 +46,16 @@ class TeleportActionFive implements Runnable { List onSuccess = new ArrayList(); onSuccess.add(() -> { unit.setCanLeaveRoomByDoor(true); + + Emulator.getThreading().run(() -> { + unit.isLeavingTeleporter = false; + }, 300); }); unit.setCanLeaveRoomByDoor(false); unit.setGoalLocation(tile); unit.statusUpdate(true); + unit.isLeavingTeleporter = true; Emulator.getThreading().run(new RoomUnitWalkToLocation(unit, tile, room, onSuccess, onSuccess)); } diff --git a/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionFour.java b/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionFour.java index cd2adb5f..6379fa98 100644 --- a/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionFour.java +++ b/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionFour.java @@ -25,6 +25,10 @@ class TeleportActionFour implements Runnable { return; } + if(this.client.getHabbo().getRoomUnit() != null) { + this.client.getHabbo().getRoomUnit().isLeavingTeleporter = true; + } + Emulator.getThreading().run(new TeleportActionFive(this.currentTeleport, this.room, this.client), 500); } } diff --git a/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionThree.java b/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionThree.java index 2a54060a..521c2f54 100644 --- a/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionThree.java +++ b/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionThree.java @@ -54,15 +54,17 @@ class TeleportActionThree implements Runnable { this.client.getHabbo().getRoomUnit().setLocation(teleportLocation); this.client.getHabbo().getRoomUnit().getPath().clear(); this.client.getHabbo().getRoomUnit().removeStatus(RoomUnitStatus.MOVE); - this.client.getHabbo().getRoomUnit().setZ(targetTeleport.getZ()); - this.client.getHabbo().getRoomUnit().setPreviousLocationZ(targetTeleport.getZ()); - this.client.getHabbo().getRoomUnit().setRotation(RoomUserRotation.values()[targetTeleport.getRotation() % 8]); + this.client.getHabbo().getRoomUnit().setZ(teleportLocation.getStackHeight()); + this.client.getHabbo().getRoomUnit().setPreviousLocationZ(teleportLocation.getStackHeight()); if (targetRoom != this.room) { this.room.removeHabbo(this.client.getHabbo(), false); Emulator.getGameEnvironment().getRoomManager().enterRoom(this.client.getHabbo(), targetRoom.getId(), "", Emulator.getConfig().getBoolean("hotel.teleport.locked.allowed"), teleportLocation); } + this.client.getHabbo().getRoomUnit().setRotation(RoomUserRotation.values()[targetTeleport.getRotation() % 8]); + this.client.getHabbo().getRoomUnit().statusUpdate(true); + targetTeleport.setExtradata("2"); targetRoom.updateItem(targetTeleport); //targetRoom.updateHabbo(this.client.getHabbo());