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