diff --git a/docs/commands.md b/docs/commands.md index 7e4bd7ed..9e2176ee 100644 --- a/docs/commands.md +++ b/docs/commands.md @@ -1,5 +1,5 @@ - + ## AuthMe Commands You can use the following commands to use the features of AuthMe. Mandatory arguments are marked with `< >` @@ -49,7 +49,7 @@ brackets; optional arguments are enclosed in square brackets (`[ ]`). - **/authme version**: Show detailed information about the installed AuthMeReloaded version, the developers, contributors, and license. - **/authme converter** [job]: Converter command for AuthMeReloaded.
Requires `authme.admin.converter` -- **/authme messages**: Adds missing messages to the current messages file. +- **/authme messages** [help]: Adds missing messages to the current messages file.
Requires `authme.admin.updatemessages` - **/authme debug** [child] [arg] [arg]: Allows various operations for debugging.
Requires `authme.debug.command` @@ -90,4 +90,4 @@ brackets; optional arguments are enclosed in square brackets (`[ ]`). --- -This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Fri Aug 11 04:37:25 CEST 2017 +This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Sun Oct 08 19:56:41 CEST 2017 diff --git a/src/main/java/fr/xephi/authme/command/CommandInitializer.java b/src/main/java/fr/xephi/authme/command/CommandInitializer.java index d5a1e1ca..83d71027 100644 --- a/src/main/java/fr/xephi/authme/command/CommandInitializer.java +++ b/src/main/java/fr/xephi/authme/command/CommandInitializer.java @@ -416,6 +416,7 @@ public class CommandInitializer { .labels("messages", "msg") .description("Add missing messages") .detailedDescription("Adds missing messages to the current messages file.") + .withArgument("help", "Add 'help' to update the help messages file", true) .permission(AdminPermission.UPDATE_MESSAGES) .executableCommand(MessagesCommand.class) .register(); diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/MessagesCommand.java b/src/main/java/fr/xephi/authme/command/executable/authme/MessagesCommand.java index a7d38d5a..bf778d9e 100644 --- a/src/main/java/fr/xephi/authme/command/executable/authme/MessagesCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/authme/MessagesCommand.java @@ -2,8 +2,10 @@ package fr.xephi.authme.command.executable.authme; import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.command.ExecutableCommand; +import fr.xephi.authme.command.help.HelpMessagesService; import fr.xephi.authme.initialization.DataFolder; import fr.xephi.authme.message.Messages; +import fr.xephi.authme.service.HelpTranslationGenerator; import fr.xephi.authme.service.MessageUpdater; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.properties.PluginSettings; @@ -11,6 +13,7 @@ import org.bukkit.command.CommandSender; import javax.inject.Inject; import java.io.File; +import java.io.IOException; import java.util.List; /** @@ -28,11 +31,33 @@ public class MessagesCommand implements ExecutableCommand { private File dataFolder; @Inject private Messages messages; + @Inject + private HelpTranslationGenerator helpTranslationGenerator; + @Inject + private HelpMessagesService helpMessagesService; @Override public void executeCommand(CommandSender sender, List arguments) { - final String language = settings.getProperty(PluginSettings.MESSAGES_LANGUAGE); + if (!arguments.isEmpty() && "help".equalsIgnoreCase(arguments.get(0))) { + updateHelpFile(sender); + } else { + updateMessagesFile(sender); + } + } + private void updateHelpFile(CommandSender sender) { + try { + helpTranslationGenerator.updateHelpFile(); + sender.sendMessage("Successfully updated the help file"); + helpMessagesService.reload(); + } catch (IOException e) { + sender.sendMessage("Could not update help file: " + e.getMessage()); + ConsoleLogger.logException("Could not update help file:", e); + } + } + + private void updateMessagesFile(CommandSender sender) { + final String language = settings.getProperty(PluginSettings.MESSAGES_LANGUAGE); try { boolean isFileUpdated = new MessageUpdater( new File(dataFolder, getMessagePath(language)), diff --git a/src/main/java/fr/xephi/authme/command/help/HelpMessage.java b/src/main/java/fr/xephi/authme/command/help/HelpMessage.java index 82023beb..ae306a40 100644 --- a/src/main/java/fr/xephi/authme/command/help/HelpMessage.java +++ b/src/main/java/fr/xephi/authme/command/help/HelpMessage.java @@ -18,7 +18,7 @@ public enum HelpMessage { RESULT("result"); - + private static final String PREFIX = "common."; private final String key; /** @@ -27,11 +27,17 @@ public enum HelpMessage { * @param key the message key */ HelpMessage(String key) { - this.key = "common." + key; + this.key = PREFIX + key; } /** @return the message key */ public String getKey() { return key; } + + /** @return the key without the common prefix */ + public String getEntryKey() { + // Note ljacqu 20171008: #getKey is called more often than this method, so we optimize for the former method + return key.substring(PREFIX.length()); + } } diff --git a/src/main/java/fr/xephi/authme/command/help/HelpMessagesService.java b/src/main/java/fr/xephi/authme/command/help/HelpMessagesService.java index 7058c0cb..2a94b675 100644 --- a/src/main/java/fr/xephi/authme/command/help/HelpMessagesService.java +++ b/src/main/java/fr/xephi/authme/command/help/HelpMessagesService.java @@ -39,7 +39,7 @@ public class HelpMessagesService implements Reloadable { * @return the localized description */ public CommandDescription buildLocalizedDescription(CommandDescription command) { - final String path = getCommandPath(command); + final String path = COMMAND_PREFIX + getCommandSubPath(command); if (!messageFileHandler.hasSection(path)) { // Messages file does not have a section for this command - return the provided command return command; @@ -68,7 +68,7 @@ public class HelpMessagesService implements Reloadable { } public String getDescription(CommandDescription command) { - return getText(getCommandPath(command) + DESCRIPTION_SUFFIX, command::getDescription); + return getText(COMMAND_PREFIX + getCommandSubPath(command) + DESCRIPTION_SUFFIX, command::getDescription); } public String getMessage(HelpMessage message) { @@ -81,11 +81,14 @@ public class HelpMessagesService implements Reloadable { public String getMessage(DefaultPermission defaultPermission) { // e.g. {default_permissions_path}.opOnly for DefaultPermission.OP_ONLY - String path = DEFAULT_PERMISSIONS_PATH - + CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, defaultPermission.name()); + String path = DEFAULT_PERMISSIONS_PATH + getDefaultPermissionsSubPath(defaultPermission); return messageFileHandler.getMessage(path); } + public static String getDefaultPermissionsSubPath(DefaultPermission defaultPermission) { + return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, defaultPermission.name()); + } + @Override public void reload() { messageFileHandler = messageFileHandlerProvider.initializeHandler( @@ -99,8 +102,15 @@ public class HelpMessagesService implements Reloadable { : message; } - private static String getCommandPath(CommandDescription command) { - return COMMAND_PREFIX + CommandUtils.constructParentList(command) + /** + * Returns the command subpath for the given command (i.e. the path to the translations for the given + * command under "commands"). + * + * @param command the command to process + * @return the subpath for the command's texts + */ + public static String getCommandSubPath(CommandDescription command) { + return CommandUtils.constructParentList(command) .stream() .map(cmd -> cmd.getLabels().get(0)) .collect(Collectors.joining(".")); diff --git a/src/main/java/fr/xephi/authme/command/help/HelpSection.java b/src/main/java/fr/xephi/authme/command/help/HelpSection.java index 23f6b1ee..506262bf 100644 --- a/src/main/java/fr/xephi/authme/command/help/HelpSection.java +++ b/src/main/java/fr/xephi/authme/command/help/HelpSection.java @@ -19,7 +19,7 @@ public enum HelpSection { CHILDREN("children"); - + private static final String PREFIX = "section."; private final String key; /** @@ -28,11 +28,17 @@ public enum HelpSection { * @param key the message key */ HelpSection(String key) { - this.key = "section." + key; + this.key = PREFIX + key; } /** @return the message key */ public String getKey() { return key; } + + /** @return the key without the common prefix */ + public String getEntryKey() { + // Note ljacqu 20171008: #getKey is called more often than this method, so we optimize for the former method + return key.substring(PREFIX.length()); + } } diff --git a/src/main/java/fr/xephi/authme/service/HelpTranslationGenerator.java b/src/main/java/fr/xephi/authme/service/HelpTranslationGenerator.java new file mode 100644 index 00000000..6ecd0549 --- /dev/null +++ b/src/main/java/fr/xephi/authme/service/HelpTranslationGenerator.java @@ -0,0 +1,123 @@ +package fr.xephi.authme.service; + +import com.google.common.collect.ImmutableMap; +import fr.xephi.authme.command.CommandArgumentDescription; +import fr.xephi.authme.command.CommandDescription; +import fr.xephi.authme.command.CommandInitializer; +import fr.xephi.authme.command.help.HelpMessage; +import fr.xephi.authme.command.help.HelpMessagesService; +import fr.xephi.authme.command.help.HelpSection; +import fr.xephi.authme.initialization.DataFolder; +import fr.xephi.authme.permission.DefaultPermission; +import fr.xephi.authme.settings.Settings; +import fr.xephi.authme.settings.properties.PluginSettings; +import org.yaml.snakeyaml.DumperOptions; +import org.yaml.snakeyaml.Yaml; + +import javax.inject.Inject; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.StandardOpenOption; +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * Generates the full command structure for the help translation and saves it to the current help file, + * preserving already existing entries. + */ +public class HelpTranslationGenerator { + + @Inject + private CommandInitializer commandInitializer; + + @Inject + private HelpMessagesService helpMessagesService; + + @Inject + private Settings settings; + + @DataFolder + @Inject + private File dataFolder; + + /** + * Updates the help file to contain entries for all commands. + * + * @throws IOException if the help file cannot be written to + */ + public void updateHelpFile() throws IOException { + String languageCode = settings.getProperty(PluginSettings.MESSAGES_LANGUAGE); + File helpFile = new File(dataFolder, "messages/help_" + languageCode + ".yml"); + Map helpEntries = generateHelpMessageEntries(); + + String helpEntriesYaml = exportToYaml(helpEntries); + Files.write(helpFile.toPath(), helpEntriesYaml.getBytes(), StandardOpenOption.TRUNCATE_EXISTING); + } + + private static String exportToYaml(Map helpEntries) { + DumperOptions options = new DumperOptions(); + options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); + options.setAllowUnicode(true); + return new Yaml(options).dump(helpEntries); + } + + /** + * Generates entries for a complete help text file. + * + * @return help text entries to save + */ + private Map generateHelpMessageEntries() { + Map messageEntries = new LinkedHashMap<>(HelpMessage.values().length); + for (HelpMessage message : HelpMessage.values()) { + messageEntries.put(message.getEntryKey(), helpMessagesService.getMessage(message)); + } + + Map defaultPermissions = new LinkedHashMap<>(); + for (DefaultPermission defaultPermission : DefaultPermission.values()) { + defaultPermissions.put(HelpMessagesService.getDefaultPermissionsSubPath(defaultPermission), + helpMessagesService.getMessage(defaultPermission)); + } + messageEntries.put("defaultPermissions", defaultPermissions); + + Map sectionEntries = new LinkedHashMap<>(HelpSection.values().length); + for (HelpSection section : HelpSection.values()) { + sectionEntries.put(section.getEntryKey(), helpMessagesService.getMessage(section)); + } + + Map commandEntries = new LinkedHashMap<>(); + for (CommandDescription command : commandInitializer.getCommands()) { + generateCommandEntries(command, commandEntries); + } + + return ImmutableMap.of( + "common", messageEntries, + "section", sectionEntries, + "commands", commandEntries); + } + + /** + * Adds YAML entries for the provided command its children to the given map. + * + * @param command the command to process (including its children) + * @param commandEntries the map to add the generated entries to + */ + private void generateCommandEntries(CommandDescription command, Map commandEntries) { + CommandDescription translatedCommand = helpMessagesService.buildLocalizedDescription(command); + Map commandData = new LinkedHashMap<>(); + commandData.put("description", translatedCommand.getDescription()); + commandData.put("detailedDescription", translatedCommand.getDetailedDescription()); + + int i = 1; + for (CommandArgumentDescription argument : translatedCommand.getArguments()) { + Map argumentData = new LinkedHashMap<>(2); + argumentData.put("label", argument.getName()); + argumentData.put("description", argument.getDescription()); + commandData.put("arg" + i, argumentData); + ++i; + } + + commandEntries.put(HelpMessagesService.getCommandSubPath(translatedCommand), commandData); + translatedCommand.getChildren().forEach(child -> generateCommandEntries(child, commandEntries)); + } +} diff --git a/src/main/java/fr/xephi/authme/service/JoinMessageService.java b/src/main/java/fr/xephi/authme/service/JoinMessageService.java index 2fa5766c..29f2caa0 100644 --- a/src/main/java/fr/xephi/authme/service/JoinMessageService.java +++ b/src/main/java/fr/xephi/authme/service/JoinMessageService.java @@ -38,9 +38,8 @@ public class JoinMessageService { */ public void sendMessage(String playerName) { String joinMessage = joinMessages.remove(playerName); - if (StringUtils.isEmpty(joinMessage)) { - return; + if (!StringUtils.isEmpty(joinMessage)) { + bukkitService.broadcastMessage(joinMessage); } - bukkitService.broadcastMessage(joinMessage); } }