Ability to add custom chat bubbles + other fixes

This commit is contained in:
ArpyAge 2025-01-16 22:28:11 +01:00
parent c2e5424122
commit a8b00dd742
9 changed files with 227 additions and 70 deletions

View File

@ -4,3 +4,18 @@ INSERT INTO `emulator_settings` (`key`, `value`) VALUES ('hotel.bot.limit.walkin
--New permission --New permission
ALTER TABLE `permissions` ADD COLUMN `acc_unignorable` ENUM('0','1') NOT NULL DEFAULT '0' AFTER `acc_infinite_friends`; 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');

View File

@ -19,6 +19,7 @@ import com.eu.habbo.habbohotel.navigation.NavigatorManager;
import com.eu.habbo.habbohotel.permissions.PermissionsManager; import com.eu.habbo.habbohotel.permissions.PermissionsManager;
import com.eu.habbo.habbohotel.pets.PetManager; import com.eu.habbo.habbohotel.pets.PetManager;
import com.eu.habbo.habbohotel.polls.PollManager; 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.rooms.RoomManager;
import com.eu.habbo.habbohotel.users.HabboManager; import com.eu.habbo.habbohotel.users.HabboManager;
import com.eu.habbo.habbohotel.users.subscriptions.SubscriptionManager; import com.eu.habbo.habbohotel.users.subscriptions.SubscriptionManager;
@ -56,6 +57,7 @@ public class GameEnvironment {
private PollManager pollManager; private PollManager pollManager;
private SubscriptionManager subscriptionManager; private SubscriptionManager subscriptionManager;
private CalendarManager calendarManager; private CalendarManager calendarManager;
private RoomChatBubbleManager roomChatBubbleManager;
public void load() throws Exception { public void load() throws Exception {
LOGGER.info("GameEnvironment -> Loading..."); LOGGER.info("GameEnvironment -> Loading...");
@ -81,6 +83,7 @@ public class GameEnvironment {
this.craftingManager = new CraftingManager(); this.craftingManager = new CraftingManager();
this.pollManager = new PollManager(); this.pollManager = new PollManager();
this.calendarManager = new CalendarManager(); this.calendarManager = new CalendarManager();
this.roomChatBubbleManager = new RoomChatBubbleManager();
this.roomManager.loadPublicRooms(); this.roomManager.loadPublicRooms();
this.navigatorManager.loadNavigator(); this.navigatorManager.loadNavigator();
@ -212,4 +215,8 @@ public class GameEnvironment {
} }
public CalendarManager getCalendarManager() { return this.calendarManager; } public CalendarManager getCalendarManager() { return this.calendarManager; }
public RoomChatBubbleManager getRoomChatBubbleManager() {
return roomChatBubbleManager;
}
} }

View File

@ -367,6 +367,7 @@ public class MarketPlace {
THashSet<MarketPlaceOffer> offers = new THashSet<>(); THashSet<MarketPlaceOffer> offers = new THashSet<>();
offers.addAll(client.getHabbo().getInventory().getMarketplaceItems()); offers.addAll(client.getHabbo().getInventory().getMarketplaceItems());
synchronized (client.getHabbo().getInventory()) {
for (MarketPlaceOffer offer : offers) { for (MarketPlaceOffer offer : offers) {
if (offer.getState().equals(MarketPlaceState.SOLD)) { if (offer.getState().equals(MarketPlaceState.SOLD)) {
client.getHabbo().getInventory().removeMarketplaceOffer(offer); client.getHabbo().getInventory().removeMarketplaceOffer(offer);
@ -376,6 +377,7 @@ public class MarketPlace {
Emulator.getThreading().run(offer); Emulator.getThreading().run(offer);
} }
} }
}
offers.clear(); offers.clear();

View File

@ -294,6 +294,7 @@ public class CommandHandler {
addCommand(new AddYoutubePlaylistCommand()); addCommand(new AddYoutubePlaylistCommand());
addCommand(new SoftKickCommand()); addCommand(new SoftKickCommand());
addCommand(new SubscriptionCommand()); addCommand(new SubscriptionCommand());
addCommand(new UpdateChatBubblesCommand());
addCommand(new TestCommand()); addCommand(new TestCommand());
} }

View File

@ -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;
}
}

View File

@ -4663,7 +4663,7 @@ public class Room implements Comparable<Room>, ISerialize, Runnable {
if (Emulator.getPluginManager().isRegistered(FurnitureBuildheightEvent.class, true)) { if (Emulator.getPluginManager().isRegistered(FurnitureBuildheightEvent.class, true)) {
FurnitureBuildheightEvent event = Emulator.getPluginManager().fireEvent(new FurnitureBuildheightEvent(item, owner, 0.00, height)); FurnitureBuildheightEvent event = Emulator.getPluginManager().fireEvent(new FurnitureBuildheightEvent(item, owner, 0.00, height));
if (event.hasChangedHeight()) { 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<Room>, ISerialize, Runnable {
if (Emulator.getPluginManager().isRegistered(FurnitureBuildheightEvent.class, true)) { if (Emulator.getPluginManager().isRegistered(FurnitureBuildheightEvent.class, true)) {
FurnitureBuildheightEvent event = Emulator.getPluginManager().fireEvent(new FurnitureBuildheightEvent(item, actor, 0.00, height)); FurnitureBuildheightEvent event = Emulator.getPluginManager().fireEvent(new FurnitureBuildheightEvent(item, actor, 0.00, height));
if (event.hasChangedHeight()) { if (event.hasChangedHeight()) {
height = event.getUpdatedHeight(); height = this.getLayout().getHeightAtSquare(tile.x, tile.y) + event.getUpdatedHeight();
pluginHeight = true; pluginHeight = true;
} }
} }

View File

@ -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);
}
}
}

View File

@ -1,86 +1,160 @@
package com.eu.habbo.habbohotel.rooms; package com.eu.habbo.habbohotel.rooms;
public enum RoomChatMessageBubbles { import java.util.HashMap;
NORMAL(0, "", true, true), import java.util.Map;
ALERT(1, "", true, true),
BOT(2, "", true, true), public class RoomChatMessageBubbles {
RED(3, "", true, true), private static final Map<Integer, RoomChatMessageBubbles> BUBBLES = new HashMap<>();
BLUE(4, "", true, true),
YELLOW(5, "", true, true), public static final RoomChatMessageBubbles NORMAL = new RoomChatMessageBubbles(0, "NORMAL", "", true, true);
GREEN(6, "", true, true), public static final RoomChatMessageBubbles ALERT = new RoomChatMessageBubbles(1, "ALERT", "", true, true);
BLACK(7, "", true, true), public static final RoomChatMessageBubbles BOT = new RoomChatMessageBubbles(2, "BOT", "", true, true);
FORTUNE_TELLER(8, "", false, false), public static final RoomChatMessageBubbles RED = new RoomChatMessageBubbles(3, "RED", "", true, true);
ZOMBIE_ARM(9, "", true, false), public static final RoomChatMessageBubbles BLUE = new RoomChatMessageBubbles(4, "BLUE", "", true, true);
SKELETON(10, "", true, false), public static final RoomChatMessageBubbles YELLOW = new RoomChatMessageBubbles(5, "YELLOW", "", true, true);
LIGHT_BLUE(11, "", true, true), public static final RoomChatMessageBubbles GREEN = new RoomChatMessageBubbles(6, "GREEN", "", true, true);
PINK(12, "", true, true), public static final RoomChatMessageBubbles BLACK = new RoomChatMessageBubbles(7, "BLACK", "", true, true);
PURPLE(13, "", true, true), public static final RoomChatMessageBubbles FORTUNE_TELLER = new RoomChatMessageBubbles(8, "FORTUNE_TELLER", "", false, false);
DARK_YEWLLOW(14, "", true, true), public static final RoomChatMessageBubbles ZOMBIE_ARM = new RoomChatMessageBubbles(9, "ZOMBIE_ARM", "", true, false);
DARK_BLUE(15, "", true, true), public static final RoomChatMessageBubbles SKELETON = new RoomChatMessageBubbles(10, "SKELETON", "", true, false);
HEARTS(16, "", true, true), public static final RoomChatMessageBubbles LIGHT_BLUE = new RoomChatMessageBubbles(11, "LIGHT_BLUE", "", true, true);
ROSES(17, "", true, true), public static final RoomChatMessageBubbles PINK = new RoomChatMessageBubbles(12, "PINK", "", true, true);
UNUSED(18, "", true, true), //? public static final RoomChatMessageBubbles PURPLE = new RoomChatMessageBubbles(13, "PURPLE", "", true, true);
PIG(19, "", true, true), public static final RoomChatMessageBubbles DARK_YELLOW = new RoomChatMessageBubbles(14, "DARK_YELLOW", "", true, true);
DOG(20, "", true, true), public static final RoomChatMessageBubbles DARK_BLUE = new RoomChatMessageBubbles(15, "DARK_BLUE", "", true, true);
BLAZE_IT(21, "", true, true), public static final RoomChatMessageBubbles HEARTS = new RoomChatMessageBubbles(16, "HEARTS", "", true, true);
DRAGON(22, "", true, true), public static final RoomChatMessageBubbles ROSES = new RoomChatMessageBubbles(17, "ROSES", "", true, true);
STAFF(23, "", false, true), public static final RoomChatMessageBubbles UNUSED = new RoomChatMessageBubbles(18, "UNUSED", "", true, true);
BATS(24, "", true, false), public static final RoomChatMessageBubbles PIG = new RoomChatMessageBubbles(19, "PIG", "", true, true);
MESSENGER(25, "", true, false), public static final RoomChatMessageBubbles DOG = new RoomChatMessageBubbles(20, "DOG", "", true, true);
STEAMPUNK(26, "", true, false), public static final RoomChatMessageBubbles BLAZE_IT = new RoomChatMessageBubbles(21, "BLAZE_IT", "", true, true);
THUNDER(27, "", true, true), public static final RoomChatMessageBubbles DRAGON = new RoomChatMessageBubbles(22, "DRAGON", "", true, true);
PARROT(28, "", false, false), public static final RoomChatMessageBubbles STAFF = new RoomChatMessageBubbles(23, "STAFF", "", false, true);
PIRATE(29, "", false, false), public static final RoomChatMessageBubbles BATS = new RoomChatMessageBubbles(24, "BATS", "", true, false);
BOT_GUIDE(30, "", true, true), public static final RoomChatMessageBubbles MESSENGER = new RoomChatMessageBubbles(25, "MESSENGER", "", true, false);
BOT_RENTABLE(31, "", true, true), public static final RoomChatMessageBubbles STEAMPUNK = new RoomChatMessageBubbles(26, "STEAMPUNK", "", true, false);
SCARY_THING(32, "", true, false), public static final RoomChatMessageBubbles THUNDER = new RoomChatMessageBubbles(27, "THUNDER", "", true, true);
FRANK(33, "", true, false), public static final RoomChatMessageBubbles PARROT = new RoomChatMessageBubbles(28, "PARROT", "", false, false);
WIRED(34, "", false, true), public static final RoomChatMessageBubbles PIRATE = new RoomChatMessageBubbles(29, "PIRATE", "", false, false);
GOAT(35, "", true, false), public static final RoomChatMessageBubbles BOT_GUIDE = new RoomChatMessageBubbles(30, "BOT_GUIDE", "", true, true);
SANTA(36, "", true, false), public static final RoomChatMessageBubbles BOT_RENTABLE = new RoomChatMessageBubbles(31, "BOT_RENTABLE", "", true, true);
AMBASSADOR(37, "acc_ambassador", false, true), public static final RoomChatMessageBubbles SCARY_THING = new RoomChatMessageBubbles(32, "SCARY_THING", "", true, false);
RADIO(38, "", true, false), public static final RoomChatMessageBubbles FRANK = new RoomChatMessageBubbles(33, "FRANK", "", true, false);
UNKNOWN_39(39, "", true, false), public static final RoomChatMessageBubbles WIRED = new RoomChatMessageBubbles(34, "WIRED", "", false, true);
UNKNOWN_40(40, "", true, false), public static final RoomChatMessageBubbles GOAT = new RoomChatMessageBubbles(35, "GOAT", "", true, false);
UNKNOWN_41(41, "", true, false), public static final RoomChatMessageBubbles SANTA = new RoomChatMessageBubbles(36, "SANTA", "", true, false);
UNKNOWN_42(42, "", true, false), public static final RoomChatMessageBubbles AMBASSADOR = new RoomChatMessageBubbles(37, "AMBASSADOR", "acc_ambassador", false, true);
UNKNOWN_43(43, "", true, false), public static final RoomChatMessageBubbles RADIO = new RoomChatMessageBubbles(38, "RADIO", "", true, false);
UNKNOWN_44(44, "", true, false), public static final RoomChatMessageBubbles UNKNOWN_39 = new RoomChatMessageBubbles(39, "UNKNOWN_39", "", true, false);
UNKNOWN_45(45, "", 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 int type;
private final String name;
private final String permission; private final String permission;
private final boolean overridable; private final boolean overridable;
private final boolean triggersTalkingFurniture; 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.type = type;
this.name = name;
this.permission = permission; this.permission = permission;
this.overridable = overridable; this.overridable = overridable;
this.triggersTalkingFurniture = triggersTalkingFurniture; this.triggersTalkingFurniture = triggersTalkingFurniture;
} }
public static RoomChatMessageBubbles getBubble(int bubbleId) { public static RoomChatMessageBubbles getBubble(int id) {
try { return BUBBLES.getOrDefault(id, NORMAL);
return values()[bubbleId];
} catch (Exception e) {
return NORMAL;
} }
private static void registerBubble(RoomChatMessageBubbles bubble) {
BUBBLES.put(bubble.getType(), bubble);
} }
public int getType() { public int getType() {
return this.type; return type;
}
public String name() {
return name;
} }
public String getPermission() { public String getPermission() {
return this.permission; return permission;
} }
public boolean isOverridable() { public boolean isOverridable() {
return this.overridable; return overridable;
} }
public boolean triggersTalkingFurniture() { 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]);
} }
} }

View File

@ -323,7 +323,7 @@ public class RoomUnit {
zHeight += room.getLayout().getHeightAtSquare(next.x, next.y); zHeight += room.getLayout().getHeightAtSquare(next.x, next.y);
} }
Optional<HabboItem> stackHelper = this.room.getItemsAt(next).stream().filter(i -> i instanceof InteractionTileWalkMagic).findAny(); Optional<HabboItem> stackHelper = room.getItemsAt(next).stream().filter(i -> i instanceof InteractionTileWalkMagic).findAny();
if (stackHelper.isPresent()) { if (stackHelper.isPresent()) {
zHeight = stackHelper.get().getZ(); zHeight = stackHelper.get().getZ();
} }