Merge pull request #183 from simoleo89/fix/command-description-texts

fix(commands): complete and quiet command descriptions
This commit is contained in:
DuckieTM
2026-06-15 07:21:39 +02:00
committed by GitHub
10 changed files with 115 additions and 3 deletions
@@ -435,6 +435,16 @@ ON DUPLICATE KEY UPDATE
`triggers_talking_furniture` = VALUES(`triggers_talking_furniture`);
INSERT IGNORE INTO `emulator_texts` (`key`, `value`) VALUES
('commands.description.acc_modtool_room_info', 'Allows viewing room information in the moderation tool.'),
('commands.description.cmd_add_youtube_playlist', ':add_youtube <base_item_id> <youtube_playlist_id>'),
('commands.description.cmd_disablemassmentions', ':disablemassmentions'),
('commands.description.cmd_disablementions', ':disablementions'),
('commands.description.cmd_give_prefix', ':giveprefix <username> <text> <color> [icon] [effect]'),
('commands.description.cmd_hidewired', ':hidewired'),
('commands.description.cmd_list_prefixes', ':listprefixes <username>'),
('commands.description.cmd_remove_prefix', ':removeprefix <username> <id|all>'),
('commands.description.cmd_setroom_template', ':setroom_template'),
('commands.description.cmd_update_youtube_playlists', ':update_youtube'),
('commands.keys.cmd_setroom_template', 'setroom_template;set_room_template'),
('commands.succes.cmd_setroom_template.verify', 'Copy the current room "%roomname%" to room_templates? Type :setroom_template %generic.yes% to confirm.'),
('commands.succes.cmd_setroom_template', 'Room saved as template id %id% with %items% items (%skipped% skipped - item_id not in items_base).'),
@@ -37,6 +37,10 @@ VALUES
ON DUPLICATE KEY UPDATE
`comment` = VALUES(`comment`);
INSERT IGNORE INTO `emulator_texts` (`key`, `value`) VALUES
('commands.description.cmd_disablementions', ':disablementions'),
('commands.description.cmd_disablemassmentions', ':disablemassmentions');
-- ----------------------------------------------------------------------------
-- 3. Emulator settings: cooldowns, caps and alias lists
@@ -49,6 +49,7 @@ INSERT INTO `permission_definitions` (`permission_key`, `rank_7`, `comment`) VAL
ON DUPLICATE KEY UPDATE `rank_7` = VALUES(`rank_7`);
INSERT INTO `emulator_texts` (`key`, `value`) VALUES
('commands.description.cmd_setroom_template', ':setroom_template'),
('commands.keys.cmd_setroom_template', 'setroom_template;set_room_template'),
('commands.succes.cmd_setroom_template.verify', 'Copy the current room "%roomname%" to room_templates? Type :setroom_template %generic.yes% to confirm.'),
('commands.succes.cmd_setroom_template', 'Room saved as template id %id% with %items% items (%skipped% skipped - item_id not in items_base).'),
@@ -301,6 +301,7 @@ INSERT IGNORE INTO `custom_prefixes_catalog`
INSERT IGNORE INTO `emulator_texts` (`key`, `value`) VALUES
-- GivePrefix command
('commands.description.cmd_give_prefix', ':giveprefix <username> <text> <color> [icon] [effect]'),
('commands.keys.cmd_give_prefix', 'giveprefix'),
('commands.error.cmd_give_prefix.usage', 'Usage: :giveprefix <username> <text> <color> [icon] [effect]'),
('commands.error.cmd_give_prefix.invalid_color', 'Invalid color format. Use hex format (#FF0000).'),
@@ -308,12 +309,14 @@ INSERT IGNORE INTO `emulator_texts` (`key`, `value`) VALUES
('commands.error.cmd_give_prefix.user_not_found', 'User not found or not online.'),
('commands.succes.cmd_give_prefix', 'Prefix {%prefix%} successfully given to %user%!'),
-- ListPrefixes command
('commands.description.cmd_list_prefixes', ':listprefixes <username>'),
('commands.keys.cmd_list_prefixes', 'listprefixes'),
('commands.error.cmd_list_prefixes.usage', 'Usage: :listprefixes <username>'),
('commands.error.cmd_list_prefixes.user_not_found', 'User not found or not online.'),
('commands.succes.cmd_list_prefixes.header', 'Prefixes of %user%:'),
('commands.succes.cmd_list_prefixes.empty', '%user% has no prefixes.'),
-- RemovePrefix command
('commands.description.cmd_remove_prefix', ':removeprefix <username> <id|all>'),
('commands.keys.cmd_remove_prefix', 'removeprefix'),
('commands.error.cmd_remove_prefix.usage', 'Usage: :removeprefix <username> <id|all>'),
('commands.error.cmd_remove_prefix.user_not_found', 'User not found or not online.'),
+10
View File
@@ -15355,7 +15355,9 @@ INSERT INTO `emulator_texts` (`key`, `value`) VALUES
('commands.cmd_promote_offer.list', 'All available offers (%amount%):<br>%list%'),
('commands.cmd_promote_offer.list.entry', '%id%: %title% %description%'),
('commands.description.acc_debug', ':test [header] i:1 s:a b:1'),
('commands.description.acc_modtool_room_info', 'Allows viewing room information in the moderation tool.'),
('commands.description.cmd_about', ':about'),
('commands.description.cmd_add_youtube_playlist', ':add_youtube <base_item_id> <youtube_playlist_id>'),
('commands.description.cmd_alert', ':alert <username> <message>'),
('commands.description.cmd_allow_trading', 'Enables / Disables the tradelock for a user.'),
('commands.description.cmd_badge', ':badge <username> <badge>'),
@@ -15379,6 +15381,8 @@ INSERT INTO `emulator_texts` (`key`, `value`) VALUES
('commands.description.cmd_danceall', ':danceall <dance id>'),
('commands.description.cmd_diagonal', ':diagonal'),
('commands.description.cmd_disable_effects', ':disableffects'),
('commands.description.cmd_disablemassmentions', ':disablemassmentions'),
('commands.description.cmd_disablementions', ':disablementions'),
('commands.description.cmd_disconnect', ':disconnect <username>'),
('commands.description.cmd_duckets', ':duckets <username> <amount>'),
('commands.description.cmd_ejectall', ':ejectall'),
@@ -15395,11 +15399,13 @@ INSERT INTO `emulator_texts` (`key`, `value`) VALUES
('commands.description.cmd_freeze_bots', ':freezebots'),
('commands.description.cmd_furnidata', ':furnidata'),
('commands.description.cmd_gift', ':gift <username> <itemid>'),
('commands.description.cmd_give_prefix', ':giveprefix <username> <text> <color> [icon] [effect]'),
('commands.description.cmd_give_rank', ':giverank <username> <rank>'),
('commands.description.cmd_ha', ':ha <message>'),
('commands.description.cmd_hal', ':hal <url> <message>'),
('commands.description.cmd_hand_item', ':handitem <itemid>'),
('commands.description.cmd_happyhour', ':happyhour'),
('commands.description.cmd_hidewired', ':hidewired'),
('commands.description.cmd_hoverboard', ':hoverboard'),
('commands.description.cmd_hug', ':hug <username>'),
('commands.description.cmd_invisible', ':invisible'),
@@ -15408,6 +15414,7 @@ INSERT INTO `emulator_texts` (`key`, `value`) VALUES
('commands.description.cmd_kill', ':kill <username>'),
('commands.description.cmd_kiss', ':kiss <username>'),
('commands.description.cmd_lay', ':lay'),
('commands.description.cmd_list_prefixes', ':listprefixes <username>'),
('commands.description.cmd_machine_ban', ':machineban <username> [reason]'),
('commands.description.cmd_massbadge', ':massbadge <badge>'),
('commands.description.cmd_masscredits', ':masscredits <amount>'),
@@ -15429,6 +15436,7 @@ INSERT INTO `emulator_texts` (`key`, `value`) VALUES
('commands.description.cmd_push', ':push <username>'),
('commands.description.cmd_redeem', ':redeem'),
('commands.description.cmd_reload_room', ':reload_room'),
('commands.description.cmd_remove_prefix', ':removeprefix <username> <id|all>'),
('commands.description.cmd_roomalert', ':roomalert <message>'),
('commands.description.cmd_roombadge', ':roombadge <badge>'),
('commands.description.cmd_roomcredits', ':roomcredits <amount>'),
@@ -15444,6 +15452,7 @@ INSERT INTO `emulator_texts` (`key`, `value`) VALUES
('commands.description.cmd_set', ':set info'),
('commands.description.cmd_setmax', ':setmax <amount>'),
('commands.description.cmd_setpublic', ':setpublic'),
('commands.description.cmd_setroom_template', ':setroom_template'),
('commands.description.cmd_setrotation', ':rot;rotation'),
('commands.description.cmd_setspeed', ':setspeed <speed>'),
('commands.description.cmd_setstate', ':ss'),
@@ -15486,6 +15495,7 @@ INSERT INTO `emulator_texts` (`key`, `value`) VALUES
('commands.description.cmd_update_polls', ':update_polls'),
('commands.description.cmd_update_texts', ':update_texts'),
('commands.description.cmd_update_wordfilter', ':update_word_filter'),
('commands.description.cmd_update_youtube_playlists', ':update_youtube'),
('commands.description.cmd_userinfo', ':userinfo <username>'),
('commands.description.cmd_welcome', ':welcome <username>'),
('commands.description.cmd_word_quiz', ':wordquiz <question>'),
@@ -52,6 +52,10 @@ public class TextsManager {
return this.texts.getProperty(key, defaultValue);
}
public String getValueQuietly(String key, String defaultValue) {
return this.texts.getProperty(key, defaultValue);
}
public boolean getBoolean(String key) {
return this.getBoolean(key, false);
}
@@ -18,7 +18,7 @@ public class CommandsCommand extends Command {
for (Command c : commands) {
String textKey = "commands.description." + c.permission;
String commandText = Emulator.getTexts().getValue(textKey, "");
String commandText = Emulator.getTexts().getValueQuietly(textKey, "");
String commandLine = ":" + c.keys[0];
String description = "";
@@ -23,10 +23,10 @@ public class AvailableCommandsComposer extends MessageComposer {
for (Command cmd : this.commands) {
this.response.appendString(cmd.keys[0]);
this.response.appendString(
Emulator.getTexts().getValue("commands.description." + cmd.permission, cmd.permission)
Emulator.getTexts().getValueQuietly("commands.description." + cmd.permission, cmd.permission)
);
}
return this.response;
}
}
}
@@ -0,0 +1,45 @@
package com.eu.habbo.core;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import org.junit.jupiter.api.Test;
class CommandDescriptionTextsContractTest {
private static final Path FULL_DATABASE = Path.of("../Default Database/FullDatabase.sql");
private static final Path LIVE_SCHEMA_UPDATE = Path.of("../Database Updates/003_live_required_schema.sql");
private static final List<String> REQUIRED_DESCRIPTION_KEYS = List.of(
"commands.description.acc_modtool_room_info",
"commands.description.cmd_add_youtube_playlist",
"commands.description.cmd_disablemassmentions",
"commands.description.cmd_disablementions",
"commands.description.cmd_give_prefix",
"commands.description.cmd_hidewired",
"commands.description.cmd_list_prefixes",
"commands.description.cmd_remove_prefix",
"commands.description.cmd_setroom_template",
"commands.description.cmd_update_youtube_playlists"
);
@Test
void fullDatabaseDefinesCommandDescriptionsUsedByCommandsList() throws IOException {
assertContainsAllDescriptionKeys(Files.readString(FULL_DATABASE), "FullDatabase.sql");
}
@Test
void liveSchemaUpdateBackfillsCommandDescriptionsForExistingDatabases() throws IOException {
assertContainsAllDescriptionKeys(Files.readString(LIVE_SCHEMA_UPDATE), "003_live_required_schema.sql");
}
private static void assertContainsAllDescriptionKeys(String source, String fileName) {
for (String key : REQUIRED_DESCRIPTION_KEYS) {
assertTrue(source.contains("'" + key + "'"),
fileName + " must define " + key + " to avoid TextsManager missing-key logs");
}
}
}
@@ -0,0 +1,35 @@
package com.eu.habbo.core;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import org.junit.jupiter.api.Test;
class CommandTextLookupContractTest {
private static final Path TEXTS_MANAGER = Path.of("src/main/java/com/eu/habbo/core/TextsManager.java");
private static final Path COMMANDS_COMMAND = Path.of("src/main/java/com/eu/habbo/habbohotel/commands/CommandsCommand.java");
private static final Path AVAILABLE_COMMANDS_COMPOSER = Path.of(
"src/main/java/com/eu/habbo/messages/outgoing/commands/AvailableCommandsComposer.java");
@Test
void textsManagerExposesQuietFallbackLookupForOptionalTexts() throws IOException {
String source = Files.readString(TEXTS_MANAGER);
assertTrue(source.contains("public String getValueQuietly(String key, String defaultValue)"));
assertTrue(source.contains("return this.texts.getProperty(key, defaultValue);"));
}
@Test
void commandListsUseQuietDescriptionLookups() throws IOException {
String commandsCommand = Files.readString(COMMANDS_COMMAND);
String availableCommandsComposer = Files.readString(AVAILABLE_COMMANDS_COMPOSER);
assertTrue(commandsCommand.contains("getValueQuietly(textKey, \"\")"),
":commands should not log an error when an optional command description is missing");
assertTrue(availableCommandsComposer.contains("getValueQuietly(\"commands.description.\" + cmd.permission, cmd.permission)"),
"available commands composer should not log an error when an optional command description is missing");
}
}