diff --git a/sqlupdates/Update 3_5_3 to 3_5_4.sql b/sqlupdates/Update 3_5_3 to 3_5_4.sql index 7789a918..9b25869e 100644 --- a/sqlupdates/Update 3_5_3 to 3_5_4.sql +++ b/sqlupdates/Update 3_5_3 to 3_5_4.sql @@ -3,4 +3,19 @@ INSERT INTO `emulator_settings` (`key`, `value`) VALUES ('hotel.bot.limit.walkin INSERT INTO `emulator_settings` (`key`, `value`) VALUES ('hotel.bot.limit.walking.distance.radius', '5'); --New permission -ALTER TABLE `permissions` ADD COLUMN `acc_unignorable` ENUM('0','1') NOT NULL DEFAULT '0' AFTER `acc_infinite_friends`; \ No newline at end of file +ALTER TABLE `permissions` ADD COLUMN `acc_unignorable` ENUM('0','1') NOT NULL DEFAULT '0' AFTER `acc_infinite_friends`; +ALTER TABLE `permissions` ADD COLUMN `cmd_update_chat_bubbles` ENUM('0','1') NOT NULL DEFAULT '0'; + +--New table for custom chat bubbles +CREATE TABLE chat_bubbles ( + type INT(11) PRIMARY KEY AUTO_INCREMENT COMMENT "Only 46 and higher will work", + name VARCHAR(255) NOT NULL DEFAULT '', + permission VARCHAR(255) NOT NULL DEFAULT '', + overridable BOOLEAN NOT NULL DEFAULT TRUE, + triggers_talking_furniture BOOLEAN NOT NULL DEFAULT FALSE +); + +--New texts for update chat bubbles command +INSERT INTO `emulator_texts` (`key`, `value`) VALUES ('commands.keys.cmd_update_chat_bubbles', 'update_chat_bubbles'); +INSERT INTO `emulator_texts` (`key`, `value`) VALUES ('commands.success.cmd_update_chat_bubbles', 'Successfully updated chat bubbles'); +INSERT INTO `emulator_texts` (`key`, `value`) VALUES ('commands.description.cmd_update_chat_bubbles', ':update_chat_bubbles'); \ No newline at end of file diff --git a/src/main/java/com/eu/habbo/habbohotel/GameEnvironment.java b/src/main/java/com/eu/habbo/habbohotel/GameEnvironment.java index 7944ae8c..879e2d6b 100644 --- a/src/main/java/com/eu/habbo/habbohotel/GameEnvironment.java +++ b/src/main/java/com/eu/habbo/habbohotel/GameEnvironment.java @@ -19,6 +19,7 @@ import com.eu.habbo.habbohotel.navigation.NavigatorManager; import com.eu.habbo.habbohotel.permissions.PermissionsManager; import com.eu.habbo.habbohotel.pets.PetManager; import com.eu.habbo.habbohotel.polls.PollManager; +import com.eu.habbo.habbohotel.rooms.RoomChatBubbleManager; import com.eu.habbo.habbohotel.rooms.RoomManager; import com.eu.habbo.habbohotel.users.HabboManager; import com.eu.habbo.habbohotel.users.subscriptions.SubscriptionManager; @@ -56,6 +57,7 @@ public class GameEnvironment { private PollManager pollManager; private SubscriptionManager subscriptionManager; private CalendarManager calendarManager; + private RoomChatBubbleManager roomChatBubbleManager; public void load() throws Exception { LOGGER.info("GameEnvironment -> Loading..."); @@ -81,6 +83,7 @@ public class GameEnvironment { this.craftingManager = new CraftingManager(); this.pollManager = new PollManager(); this.calendarManager = new CalendarManager(); + this.roomChatBubbleManager = new RoomChatBubbleManager(); this.roomManager.loadPublicRooms(); this.navigatorManager.loadNavigator(); @@ -212,4 +215,8 @@ public class GameEnvironment { } public CalendarManager getCalendarManager() { return this.calendarManager; } + + public RoomChatBubbleManager getRoomChatBubbleManager() { + return roomChatBubbleManager; + } } diff --git a/src/main/java/com/eu/habbo/habbohotel/catalog/marketplace/MarketPlace.java b/src/main/java/com/eu/habbo/habbohotel/catalog/marketplace/MarketPlace.java index f4d9aef5..b46d2a28 100644 --- a/src/main/java/com/eu/habbo/habbohotel/catalog/marketplace/MarketPlace.java +++ b/src/main/java/com/eu/habbo/habbohotel/catalog/marketplace/MarketPlace.java @@ -367,13 +367,15 @@ public class MarketPlace { THashSet offers = new THashSet<>(); offers.addAll(client.getHabbo().getInventory().getMarketplaceItems()); - for (MarketPlaceOffer offer : offers) { - if (offer.getState().equals(MarketPlaceState.SOLD)) { - client.getHabbo().getInventory().removeMarketplaceOffer(offer); - credits += offer.getPrice(); - removeUser(offer); - offer.needsUpdate(true); - Emulator.getThreading().run(offer); + synchronized (client.getHabbo().getInventory()) { + for (MarketPlaceOffer offer : offers) { + if (offer.getState().equals(MarketPlaceState.SOLD)) { + client.getHabbo().getInventory().removeMarketplaceOffer(offer); + credits += offer.getPrice(); + removeUser(offer); + offer.needsUpdate(true); + Emulator.getThreading().run(offer); + } } } diff --git a/src/main/java/com/eu/habbo/habbohotel/commands/CommandHandler.java b/src/main/java/com/eu/habbo/habbohotel/commands/CommandHandler.java index b2f98f3a..6479f25a 100644 --- a/src/main/java/com/eu/habbo/habbohotel/commands/CommandHandler.java +++ b/src/main/java/com/eu/habbo/habbohotel/commands/CommandHandler.java @@ -294,6 +294,7 @@ public class CommandHandler { addCommand(new AddYoutubePlaylistCommand()); addCommand(new SoftKickCommand()); addCommand(new SubscriptionCommand()); + addCommand(new UpdateChatBubblesCommand()); addCommand(new TestCommand()); } diff --git a/src/main/java/com/eu/habbo/habbohotel/commands/UpdateChatBubblesCommand.java b/src/main/java/com/eu/habbo/habbohotel/commands/UpdateChatBubblesCommand.java new file mode 100644 index 00000000..d3be00ba --- /dev/null +++ b/src/main/java/com/eu/habbo/habbohotel/commands/UpdateChatBubblesCommand.java @@ -0,0 +1,20 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; + +public class UpdateChatBubblesCommand extends Command { + + public UpdateChatBubblesCommand() { + super("cmd_update_chat_bubbles", Emulator.getTexts().getValue("commands.keys.cmd_update_chat_bubbles").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) { + RoomChatMessageBubbles.removeDynamicBubbles(); + Emulator.getGameEnvironment().getRoomChatBubbleManager().reload(); + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.success.cmd_update_chat_bubbles"), RoomChatMessageBubbles.ALERT); + return true; + } +} 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 0d3ea36a..25cc6240 100644 --- a/src/main/java/com/eu/habbo/habbohotel/rooms/Room.java +++ b/src/main/java/com/eu/habbo/habbohotel/rooms/Room.java @@ -4663,7 +4663,7 @@ public class Room implements Comparable, ISerialize, Runnable { if (Emulator.getPluginManager().isRegistered(FurnitureBuildheightEvent.class, true)) { FurnitureBuildheightEvent event = Emulator.getPluginManager().fireEvent(new FurnitureBuildheightEvent(item, owner, 0.00, height)); if (event.hasChangedHeight()) { - height = event.getUpdatedHeight(); + height = this.getLayout().getHeightAtSquare(tile.x, tile.y) + event.getUpdatedHeight(); } } @@ -4842,7 +4842,7 @@ public class Room implements Comparable, ISerialize, Runnable { if (Emulator.getPluginManager().isRegistered(FurnitureBuildheightEvent.class, true)) { FurnitureBuildheightEvent event = Emulator.getPluginManager().fireEvent(new FurnitureBuildheightEvent(item, actor, 0.00, height)); if (event.hasChangedHeight()) { - height = event.getUpdatedHeight(); + height = this.getLayout().getHeightAtSquare(tile.x, tile.y) + event.getUpdatedHeight(); pluginHeight = true; } } diff --git a/src/main/java/com/eu/habbo/habbohotel/rooms/RoomChatBubbleManager.java b/src/main/java/com/eu/habbo/habbohotel/rooms/RoomChatBubbleManager.java new file mode 100644 index 00000000..f84c97ad --- /dev/null +++ b/src/main/java/com/eu/habbo/habbohotel/rooms/RoomChatBubbleManager.java @@ -0,0 +1,38 @@ +package com.eu.habbo.habbohotel.rooms; + +import com.eu.habbo.Emulator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +public class RoomChatBubbleManager { + private static final Logger LOGGER = LoggerFactory.getLogger(RoomChatBubbleManager.class); + + public RoomChatBubbleManager() { + this.reload(); + } + + public void reload() { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); + PreparedStatement statement = connection.prepareStatement("SELECT * FROM chat_bubbles")) { + + try (ResultSet resultSet = statement.executeQuery()) { + while (resultSet.next()) { + int type = resultSet.getInt("type"); + String name = resultSet.getString("name"); + String permission = resultSet.getString("permission"); + boolean overridable = resultSet.getBoolean("overridable"); + boolean triggersTalkingFurniture = resultSet.getBoolean("triggers_talking_furniture"); + + RoomChatMessageBubbles.addDynamicBubble(type, name, permission, overridable, triggersTalkingFurniture); + } + } + } catch (SQLException e) { + LOGGER.error("Failed to load chat bubbles from database.", e); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/eu/habbo/habbohotel/rooms/RoomChatMessageBubbles.java b/src/main/java/com/eu/habbo/habbohotel/rooms/RoomChatMessageBubbles.java index 31b7e905..7fbbf15d 100644 --- a/src/main/java/com/eu/habbo/habbohotel/rooms/RoomChatMessageBubbles.java +++ b/src/main/java/com/eu/habbo/habbohotel/rooms/RoomChatMessageBubbles.java @@ -1,86 +1,160 @@ package com.eu.habbo.habbohotel.rooms; -public enum RoomChatMessageBubbles { - NORMAL(0, "", true, true), - ALERT(1, "", true, true), - BOT(2, "", true, true), - RED(3, "", true, true), - BLUE(4, "", true, true), - YELLOW(5, "", true, true), - GREEN(6, "", true, true), - BLACK(7, "", true, true), - FORTUNE_TELLER(8, "", false, false), - ZOMBIE_ARM(9, "", true, false), - SKELETON(10, "", true, false), - LIGHT_BLUE(11, "", true, true), - PINK(12, "", true, true), - PURPLE(13, "", true, true), - DARK_YEWLLOW(14, "", true, true), - DARK_BLUE(15, "", true, true), - HEARTS(16, "", true, true), - ROSES(17, "", true, true), - UNUSED(18, "", true, true), //? - PIG(19, "", true, true), - DOG(20, "", true, true), - BLAZE_IT(21, "", true, true), - DRAGON(22, "", true, true), - STAFF(23, "", false, true), - BATS(24, "", true, false), - MESSENGER(25, "", true, false), - STEAMPUNK(26, "", true, false), - THUNDER(27, "", true, true), - PARROT(28, "", false, false), - PIRATE(29, "", false, false), - BOT_GUIDE(30, "", true, true), - BOT_RENTABLE(31, "", true, true), - SCARY_THING(32, "", true, false), - FRANK(33, "", true, false), - WIRED(34, "", false, true), - GOAT(35, "", true, false), - SANTA(36, "", true, false), - AMBASSADOR(37, "acc_ambassador", false, true), - RADIO(38, "", true, false), - UNKNOWN_39(39, "", true, false), - UNKNOWN_40(40, "", true, false), - UNKNOWN_41(41, "", true, false), - UNKNOWN_42(42, "", true, false), - UNKNOWN_43(43, "", true, false), - UNKNOWN_44(44, "", true, false), - UNKNOWN_45(45, "", true, false); +import java.util.HashMap; +import java.util.Map; + +public class RoomChatMessageBubbles { + private static final Map BUBBLES = new HashMap<>(); + + public static final RoomChatMessageBubbles NORMAL = new RoomChatMessageBubbles(0, "NORMAL", "", true, true); + public static final RoomChatMessageBubbles ALERT = new RoomChatMessageBubbles(1, "ALERT", "", true, true); + public static final RoomChatMessageBubbles BOT = new RoomChatMessageBubbles(2, "BOT", "", true, true); + public static final RoomChatMessageBubbles RED = new RoomChatMessageBubbles(3, "RED", "", true, true); + public static final RoomChatMessageBubbles BLUE = new RoomChatMessageBubbles(4, "BLUE", "", true, true); + public static final RoomChatMessageBubbles YELLOW = new RoomChatMessageBubbles(5, "YELLOW", "", true, true); + public static final RoomChatMessageBubbles GREEN = new RoomChatMessageBubbles(6, "GREEN", "", true, true); + public static final RoomChatMessageBubbles BLACK = new RoomChatMessageBubbles(7, "BLACK", "", true, true); + public static final RoomChatMessageBubbles FORTUNE_TELLER = new RoomChatMessageBubbles(8, "FORTUNE_TELLER", "", false, false); + public static final RoomChatMessageBubbles ZOMBIE_ARM = new RoomChatMessageBubbles(9, "ZOMBIE_ARM", "", true, false); + public static final RoomChatMessageBubbles SKELETON = new RoomChatMessageBubbles(10, "SKELETON", "", true, false); + public static final RoomChatMessageBubbles LIGHT_BLUE = new RoomChatMessageBubbles(11, "LIGHT_BLUE", "", true, true); + public static final RoomChatMessageBubbles PINK = new RoomChatMessageBubbles(12, "PINK", "", true, true); + public static final RoomChatMessageBubbles PURPLE = new RoomChatMessageBubbles(13, "PURPLE", "", true, true); + public static final RoomChatMessageBubbles DARK_YELLOW = new RoomChatMessageBubbles(14, "DARK_YELLOW", "", true, true); + public static final RoomChatMessageBubbles DARK_BLUE = new RoomChatMessageBubbles(15, "DARK_BLUE", "", true, true); + public static final RoomChatMessageBubbles HEARTS = new RoomChatMessageBubbles(16, "HEARTS", "", true, true); + public static final RoomChatMessageBubbles ROSES = new RoomChatMessageBubbles(17, "ROSES", "", true, true); + public static final RoomChatMessageBubbles UNUSED = new RoomChatMessageBubbles(18, "UNUSED", "", true, true); + public static final RoomChatMessageBubbles PIG = new RoomChatMessageBubbles(19, "PIG", "", true, true); + public static final RoomChatMessageBubbles DOG = new RoomChatMessageBubbles(20, "DOG", "", true, true); + public static final RoomChatMessageBubbles BLAZE_IT = new RoomChatMessageBubbles(21, "BLAZE_IT", "", true, true); + public static final RoomChatMessageBubbles DRAGON = new RoomChatMessageBubbles(22, "DRAGON", "", true, true); + public static final RoomChatMessageBubbles STAFF = new RoomChatMessageBubbles(23, "STAFF", "", false, true); + public static final RoomChatMessageBubbles BATS = new RoomChatMessageBubbles(24, "BATS", "", true, false); + public static final RoomChatMessageBubbles MESSENGER = new RoomChatMessageBubbles(25, "MESSENGER", "", true, false); + public static final RoomChatMessageBubbles STEAMPUNK = new RoomChatMessageBubbles(26, "STEAMPUNK", "", true, false); + public static final RoomChatMessageBubbles THUNDER = new RoomChatMessageBubbles(27, "THUNDER", "", true, true); + public static final RoomChatMessageBubbles PARROT = new RoomChatMessageBubbles(28, "PARROT", "", false, false); + public static final RoomChatMessageBubbles PIRATE = new RoomChatMessageBubbles(29, "PIRATE", "", false, false); + public static final RoomChatMessageBubbles BOT_GUIDE = new RoomChatMessageBubbles(30, "BOT_GUIDE", "", true, true); + public static final RoomChatMessageBubbles BOT_RENTABLE = new RoomChatMessageBubbles(31, "BOT_RENTABLE", "", true, true); + public static final RoomChatMessageBubbles SCARY_THING = new RoomChatMessageBubbles(32, "SCARY_THING", "", true, false); + public static final RoomChatMessageBubbles FRANK = new RoomChatMessageBubbles(33, "FRANK", "", true, false); + public static final RoomChatMessageBubbles WIRED = new RoomChatMessageBubbles(34, "WIRED", "", false, true); + public static final RoomChatMessageBubbles GOAT = new RoomChatMessageBubbles(35, "GOAT", "", true, false); + public static final RoomChatMessageBubbles SANTA = new RoomChatMessageBubbles(36, "SANTA", "", true, false); + public static final RoomChatMessageBubbles AMBASSADOR = new RoomChatMessageBubbles(37, "AMBASSADOR", "acc_ambassador", false, true); + public static final RoomChatMessageBubbles RADIO = new RoomChatMessageBubbles(38, "RADIO", "", true, false); + public static final RoomChatMessageBubbles UNKNOWN_39 = new RoomChatMessageBubbles(39, "UNKNOWN_39", "", true, false); + public static final RoomChatMessageBubbles UNKNOWN_40 = new RoomChatMessageBubbles(40, "UNKNOWN_40", "", true, false); + public static final RoomChatMessageBubbles UNKNOWN_41 = new RoomChatMessageBubbles(41, "UNKNOWN_41", "", true, false); + public static final RoomChatMessageBubbles UNKNOWN_42 = new RoomChatMessageBubbles(42, "UNKNOWN_42", "", true, false); + public static final RoomChatMessageBubbles UNKNOWN_43 = new RoomChatMessageBubbles(43, "UNKNOWN_43", "", true, false); + public static final RoomChatMessageBubbles UNKNOWN_44 = new RoomChatMessageBubbles(44, "UNKNOWN_44", "", true, false); + public static final RoomChatMessageBubbles UNKNOWN_45 = new RoomChatMessageBubbles(45, "UNKNOWN_45", "", true, false); + + static { + registerBubble(NORMAL); + registerBubble(ALERT); + registerBubble(BOT); + registerBubble(RED); + registerBubble(BLUE); + registerBubble(YELLOW); + registerBubble(GREEN); + registerBubble(BLACK); + registerBubble(FORTUNE_TELLER); + registerBubble(ZOMBIE_ARM); + registerBubble(SKELETON); + registerBubble(LIGHT_BLUE); + registerBubble(PINK); + registerBubble(PURPLE); + registerBubble(DARK_YELLOW); + registerBubble(DARK_BLUE); + registerBubble(HEARTS); + registerBubble(ROSES); + registerBubble(UNUSED); + registerBubble(PIG); + registerBubble(DOG); + registerBubble(BLAZE_IT); + registerBubble(DRAGON); + registerBubble(STAFF); + registerBubble(BATS); + registerBubble(MESSENGER); + registerBubble(STEAMPUNK); + registerBubble(THUNDER); + registerBubble(PARROT); + registerBubble(PIRATE); + registerBubble(BOT_GUIDE); + registerBubble(BOT_RENTABLE); + registerBubble(SCARY_THING); + registerBubble(FRANK); + registerBubble(WIRED); + registerBubble(GOAT); + registerBubble(SANTA); + registerBubble(AMBASSADOR); + registerBubble(RADIO); + registerBubble(UNKNOWN_39); + registerBubble(UNKNOWN_40); + registerBubble(UNKNOWN_41); + registerBubble(UNKNOWN_42); + registerBubble(UNKNOWN_43); + registerBubble(UNKNOWN_44); + registerBubble(UNKNOWN_45); + } private final int type; + private final String name; private final String permission; private final boolean overridable; private final boolean triggersTalkingFurniture; - RoomChatMessageBubbles(int type, String permission, boolean overridable, boolean triggersTalkingFurniture) { + private RoomChatMessageBubbles(int type, String name, String permission, boolean overridable, boolean triggersTalkingFurniture) { this.type = type; + this.name = name; this.permission = permission; this.overridable = overridable; this.triggersTalkingFurniture = triggersTalkingFurniture; } - public static RoomChatMessageBubbles getBubble(int bubbleId) { - try { - return values()[bubbleId]; - } catch (Exception e) { - return NORMAL; - } + public static RoomChatMessageBubbles getBubble(int id) { + return BUBBLES.getOrDefault(id, NORMAL); + } + + private static void registerBubble(RoomChatMessageBubbles bubble) { + BUBBLES.put(bubble.getType(), bubble); } public int getType() { - return this.type; + return type; + } + + public String name() { + return name; } public String getPermission() { - return this.permission; + return permission; } public boolean isOverridable() { - return this.overridable; + return overridable; } public boolean triggersTalkingFurniture() { - return this.triggersTalkingFurniture; + return triggersTalkingFurniture; } -} + + public static void addDynamicBubble(int type, String name, String permission, boolean overridable, boolean triggersTalkingFurniture) { + registerBubble(new RoomChatMessageBubbles(type, name, permission, overridable, triggersTalkingFurniture)); + } + + public static void removeDynamicBubbles() { + synchronized (BUBBLES) { + BUBBLES.entrySet().removeIf(entry -> entry.getKey() > 45); + } + } + + public static RoomChatMessageBubbles[] values() { + return BUBBLES.values().toArray(new RoomChatMessageBubbles[0]); + } +} \ No newline at end of file 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 52d4feb4..a8e5ff85 100644 --- a/src/main/java/com/eu/habbo/habbohotel/rooms/RoomUnit.java +++ b/src/main/java/com/eu/habbo/habbohotel/rooms/RoomUnit.java @@ -323,7 +323,7 @@ public class RoomUnit { zHeight += room.getLayout().getHeightAtSquare(next.x, next.y); } - Optional stackHelper = this.room.getItemsAt(next).stream().filter(i -> i instanceof InteractionTileWalkMagic).findAny(); + Optional stackHelper = room.getItemsAt(next).stream().filter(i -> i instanceof InteractionTileWalkMagic).findAny(); if (stackHelper.isPresent()) { zHeight = stackHelper.get().getZ(); }