🆙 Update for Frank

This commit is contained in:
duckietm
2026-05-28 10:53:50 +02:00
parent bab43af41e
commit 9ea7acf05c
4 changed files with 31 additions and 62 deletions
@@ -539,5 +539,9 @@ public class Bot implements Runnable {
} }
} }
private static final short[] DEFAULT_OWNER_ACTION_IDS = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
public short[] getOwnerActionIds() {
return DEFAULT_OWNER_ACTION_IDS;
}
} }
@@ -1,12 +1,7 @@
package com.eu.habbo.habbohotel.bots; package com.eu.habbo.habbohotel.bots;
import com.eu.habbo.Emulator; import com.eu.habbo.Emulator;
import com.eu.habbo.habbohotel.rooms.Room; import com.eu.habbo.habbohotel.rooms.*;
import com.eu.habbo.habbohotel.rooms.RoomChatMessage;
import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles;
import com.eu.habbo.habbohotel.rooms.RoomTile;
import com.eu.habbo.habbohotel.rooms.RoomUnitStatus;
import com.eu.habbo.habbohotel.rooms.RoomUserRotation;
import com.eu.habbo.habbohotel.users.Habbo; import com.eu.habbo.habbohotel.users.Habbo;
import com.eu.habbo.messages.outgoing.rooms.users.RoomUserStatusComposer; import com.eu.habbo.messages.outgoing.rooms.users.RoomUserStatusComposer;
import com.eu.habbo.messages.outgoing.rooms.users.RoomUserWhisperComposer; import com.eu.habbo.messages.outgoing.rooms.users.RoomUserWhisperComposer;
@@ -26,37 +21,14 @@ import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.regex.Pattern; import java.util.regex.Pattern;
/**
* Frank, Habbo's mascot. Behaves as a Butler (inherits the give-item
* walk-and-serve flow from ButlerBot via bot_serves) plus a keyword
* to chat-reply layer for the non-item conversational commands
* ("cat", "Vietnam", "Miranda", "help", "Frank Black", "life",
* etc).
*
* Chat replies live in `bot_chat_responses` keyed by bot_type so
* other future scripted bots can reuse the same table. Each row's
* `keys` is a semicolon-separated list of trigger words, `responses`
* is a newline-separated list of replies that Frank picks from at
* random for variety.
*
* Resolution order on each user message: chat reply first (instant,
* no walking) - if no chat keyword hits, fall through to the
* inherited ButlerBot logic so item commands keep working.
*/
public class FrankBot extends ButlerBot { public class FrankBot extends ButlerBot {
private static final Logger LOGGER = LoggerFactory.getLogger(FrankBot.class); private static final Logger LOGGER = LoggerFactory.getLogger(FrankBot.class);
public static final String BOT_TYPE = "frank"; public static final String BOT_TYPE = "frank";
public static final String PERMISSION_USE = "acc_bot_frank"; public static final String PERMISSION_USE = "acc_bot_frank";
private static final String KEY_DOOR_LINES = "__door_lines"; private static final String KEY_DOOR_LINES = "__door_lines";
private static final String KEY_BUSY_WHISPER = "__busy_whisper"; private static final String KEY_BUSY_WHISPER = "__busy_whisper";
private static final String KEY_DOOR_TRIGGERS = "__door_triggers"; private static final String KEY_DOOR_TRIGGERS = "__door_triggers";
// Fallbacks only - the live values are loaded from bot_chat_responses
// and surface to admins via the __door_lines / __busy_whisper /
// __door_triggers rows. These constants are used only if the SQL row
// is missing so Frank does not break on a bad install.
private static final List<String> DEFAULT_DOOR_LINES = List.of( private static final List<String> DEFAULT_DOOR_LINES = List.of(
"Right this way - mind the step!", "Right this way - mind the step!",
"And out you go. Come back soon!", "And out you go. Come back soon!",
@@ -103,6 +75,13 @@ public class FrankBot extends ButlerBot {
} }
} }
private static final short[] FRANK_OWNER_ACTIONS = new short[0];
@Override
public short[] getOwnerActionIds() {
return FRANK_OWNER_ACTIONS;
}
public static void initialise() { public static void initialise() {
chatResponses.clear(); chatResponses.clear();
doorLines = DEFAULT_DOOR_LINES; doorLines = DEFAULT_DOOR_LINES;
@@ -163,8 +142,6 @@ public class FrankBot extends ButlerBot {
} }
} }
} catch (SQLException e) { } catch (SQLException e) {
// Table missing or transient DB issue - log once and let the bot
// fall through to ButlerBot behavior. The chat layer is additive.
LOGGER.warn("FrankBot: could not load bot_chat_responses ({}). Frank will still serve items.", e.getMessage()); LOGGER.warn("FrankBot: could not load bot_chat_responses ({}). Frank will still serve items.", e.getMessage());
} }
@@ -466,9 +443,6 @@ public class FrankBot extends ButlerBot {
private void persistPosition() { private void persistPosition() {
this.needsUpdate(true); this.needsUpdate(true);
// Synchronous so the DB row reflects the home tile / rotation
// we just set, before busy clears and another onUserSay can
// race in and mutate position.
this.run(); this.run();
this.busy.set(false); this.busy.set(false);
} }
@@ -34,6 +34,9 @@ public class BotSaveSettingsEvent extends MessageHandler {
if (bot == null) if (bot == null)
return; return;
if (bot.getOwnerActionIds().length == 0)
return;
int settingId = this.packet.readInt(); int settingId = this.packet.readInt();
switch (settingId) { switch (settingId) {
@@ -86,7 +86,7 @@ public class RoomUsersComposer extends MessageComposer {
this.response.appendInt(habbo.getHabboInfo().getId()); this.response.appendInt(habbo.getHabboInfo().getId());
this.response.appendString(habbo.getHabboInfo().getUsername()); this.response.appendString(habbo.getHabboInfo().getUsername());
this.response.appendString(habbo.getHabboInfo().getMotto()); this.response.appendString(habbo.getHabboInfo().getMotto());
this.response.appendInt(habbo.getHabboInfo().getInfostandBg()); this.response.appendInt(habbo.getHabboInfo().getInfostandBg());
this.response.appendInt(habbo.getHabboInfo().getInfostandStand()); this.response.appendInt(habbo.getHabboInfo().getInfostandStand());
this.response.appendInt(habbo.getHabboInfo().getInfostandOverlay()); this.response.appendInt(habbo.getHabboInfo().getInfostandOverlay());
this.response.appendInt(habbo.getHabboInfo().getInfostandCardBg()); this.response.appendInt(habbo.getHabboInfo().getInfostandCardBg());
@@ -129,7 +129,7 @@ public class RoomUsersComposer extends MessageComposer {
this.response.appendInt(0 - this.bot.getId()); this.response.appendInt(0 - this.bot.getId());
this.response.appendString(this.bot.getName()); this.response.appendString(this.bot.getName());
this.response.appendString(this.bot.getMotto()); this.response.appendString(this.bot.getMotto());
this.response.appendInt(0); this.response.appendInt(0);
this.response.appendInt(0); this.response.appendInt(0);
this.response.appendInt(0); this.response.appendInt(0);
this.response.appendInt(0); this.response.appendInt(0);
@@ -143,17 +143,11 @@ public class RoomUsersComposer extends MessageComposer {
this.response.appendString(this.bot.getGender().name().toUpperCase()); this.response.appendString(this.bot.getGender().name().toUpperCase());
this.response.appendInt(this.bot.getOwnerId()); this.response.appendInt(this.bot.getOwnerId());
this.response.appendString(this.bot.getOwnerName()); this.response.appendString(this.bot.getOwnerName());
this.response.appendInt(10); short[] singleActions = this.bot.getOwnerActionIds();
this.response.appendShort(0); this.response.appendInt(singleActions.length);
this.response.appendShort(1); for (short action : singleActions) {
this.response.appendShort(2); this.response.appendShort(action);
this.response.appendShort(3); }
this.response.appendShort(4);
this.response.appendShort(5);
this.response.appendShort(6);
this.response.appendShort(7);
this.response.appendShort(8);
this.response.appendShort(9);
this.response.appendString("unknown"); this.response.appendString("unknown");
this.response.appendInt(0); this.response.appendInt(0);
this.response.appendInt(0); this.response.appendInt(0);
@@ -163,10 +157,10 @@ public class RoomUsersComposer extends MessageComposer {
this.response.appendInt(0 - bot.getId()); this.response.appendInt(0 - bot.getId());
this.response.appendString(bot.getName()); this.response.appendString(bot.getName());
this.response.appendString(bot.getMotto()); this.response.appendString(bot.getMotto());
this.response.appendInt(0); this.response.appendInt(0);
this.response.appendInt(0); this.response.appendInt(0);
this.response.appendInt(0); this.response.appendInt(0);
this.response.appendInt(0); this.response.appendInt(0);
this.response.appendString(bot.getFigure()); this.response.appendString(bot.getFigure());
this.response.appendInt(bot.getRoomUnit().getId()); this.response.appendInt(bot.getRoomUnit().getId());
this.response.appendInt(bot.getRoomUnit().getX()); this.response.appendInt(bot.getRoomUnit().getX());
@@ -177,17 +171,11 @@ public class RoomUsersComposer extends MessageComposer {
this.response.appendString(bot.getGender().name().toUpperCase()); this.response.appendString(bot.getGender().name().toUpperCase());
this.response.appendInt(bot.getOwnerId()); this.response.appendInt(bot.getOwnerId());
this.response.appendString(bot.getOwnerName()); this.response.appendString(bot.getOwnerName());
this.response.appendInt(10); short[] listActions = bot.getOwnerActionIds();
this.response.appendShort(0); this.response.appendInt(listActions.length);
this.response.appendShort(1); for (short action : listActions) {
this.response.appendShort(2); this.response.appendShort(action);
this.response.appendShort(3); }
this.response.appendShort(4);
this.response.appendShort(5);
this.response.appendShort(6);
this.response.appendShort(7);
this.response.appendShort(8);
this.response.appendShort(9);
this.response.appendString("unknown"); this.response.appendString("unknown");
this.response.appendInt(0); this.response.appendInt(0);
this.response.appendInt(0); this.response.appendInt(0);