#1338 Implement ''/authme messages help' to generate a fully complete help text file (#1349)

This commit is contained in:
ljacqu 2017-10-09 07:19:38 +02:00 committed by GitHub
parent 5be3f8facc
commit 7afda20288
8 changed files with 187 additions and 17 deletions

View File

@ -1,5 +1,5 @@
<!-- AUTO-GENERATED FILE! Do not edit this directly --> <!-- AUTO-GENERATED FILE! Do not edit this directly -->
<!-- File auto-generated on Fri Aug 11 04:37:25 CEST 2017. See docs/commands/commands.tpl.md --> <!-- File auto-generated on Sun Oct 08 19:56:41 CEST 2017. See docs/commands/commands.tpl.md -->
## AuthMe Commands ## AuthMe Commands
You can use the following commands to use the features of AuthMe. Mandatory arguments are marked with `< >` 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 version**: Show detailed information about the installed AuthMeReloaded version, the developers, contributors, and license.
- **/authme converter** [job]: Converter command for AuthMeReloaded. - **/authme converter** [job]: Converter command for AuthMeReloaded.
<br />Requires `authme.admin.converter` <br />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.
<br />Requires `authme.admin.updatemessages` <br />Requires `authme.admin.updatemessages`
- **/authme debug** [child] [arg] [arg]: Allows various operations for debugging. - **/authme debug** [child] [arg] [arg]: Allows various operations for debugging.
<br />Requires `authme.debug.command` <br />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

View File

@ -416,6 +416,7 @@ public class CommandInitializer {
.labels("messages", "msg") .labels("messages", "msg")
.description("Add missing messages") .description("Add missing messages")
.detailedDescription("Adds missing messages to the current messages file.") .detailedDescription("Adds missing messages to the current messages file.")
.withArgument("help", "Add 'help' to update the help messages file", true)
.permission(AdminPermission.UPDATE_MESSAGES) .permission(AdminPermission.UPDATE_MESSAGES)
.executableCommand(MessagesCommand.class) .executableCommand(MessagesCommand.class)
.register(); .register();

View File

@ -2,8 +2,10 @@ package fr.xephi.authme.command.executable.authme;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.command.help.HelpMessagesService;
import fr.xephi.authme.initialization.DataFolder; import fr.xephi.authme.initialization.DataFolder;
import fr.xephi.authme.message.Messages; import fr.xephi.authme.message.Messages;
import fr.xephi.authme.service.HelpTranslationGenerator;
import fr.xephi.authme.service.MessageUpdater; import fr.xephi.authme.service.MessageUpdater;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.PluginSettings; import fr.xephi.authme.settings.properties.PluginSettings;
@ -11,6 +13,7 @@ import org.bukkit.command.CommandSender;
import javax.inject.Inject; import javax.inject.Inject;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.util.List; import java.util.List;
/** /**
@ -28,11 +31,33 @@ public class MessagesCommand implements ExecutableCommand {
private File dataFolder; private File dataFolder;
@Inject @Inject
private Messages messages; private Messages messages;
@Inject
private HelpTranslationGenerator helpTranslationGenerator;
@Inject
private HelpMessagesService helpMessagesService;
@Override @Override
public void executeCommand(CommandSender sender, List<String> arguments) { public void executeCommand(CommandSender sender, List<String> 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 { try {
boolean isFileUpdated = new MessageUpdater( boolean isFileUpdated = new MessageUpdater(
new File(dataFolder, getMessagePath(language)), new File(dataFolder, getMessagePath(language)),

View File

@ -18,7 +18,7 @@ public enum HelpMessage {
RESULT("result"); RESULT("result");
private static final String PREFIX = "common.";
private final String key; private final String key;
/** /**
@ -27,11 +27,17 @@ public enum HelpMessage {
* @param key the message key * @param key the message key
*/ */
HelpMessage(String key) { HelpMessage(String key) {
this.key = "common." + key; this.key = PREFIX + key;
} }
/** @return the message key */ /** @return the message key */
public String getKey() { public String getKey() {
return key; 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());
}
} }

View File

@ -39,7 +39,7 @@ public class HelpMessagesService implements Reloadable {
* @return the localized description * @return the localized description
*/ */
public CommandDescription buildLocalizedDescription(CommandDescription command) { public CommandDescription buildLocalizedDescription(CommandDescription command) {
final String path = getCommandPath(command); final String path = COMMAND_PREFIX + getCommandSubPath(command);
if (!messageFileHandler.hasSection(path)) { if (!messageFileHandler.hasSection(path)) {
// Messages file does not have a section for this command - return the provided command // Messages file does not have a section for this command - return the provided command
return command; return command;
@ -68,7 +68,7 @@ public class HelpMessagesService implements Reloadable {
} }
public String getDescription(CommandDescription command) { 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) { public String getMessage(HelpMessage message) {
@ -81,11 +81,14 @@ public class HelpMessagesService implements Reloadable {
public String getMessage(DefaultPermission defaultPermission) { public String getMessage(DefaultPermission defaultPermission) {
// e.g. {default_permissions_path}.opOnly for DefaultPermission.OP_ONLY // e.g. {default_permissions_path}.opOnly for DefaultPermission.OP_ONLY
String path = DEFAULT_PERMISSIONS_PATH String path = DEFAULT_PERMISSIONS_PATH + getDefaultPermissionsSubPath(defaultPermission);
+ CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, defaultPermission.name());
return messageFileHandler.getMessage(path); return messageFileHandler.getMessage(path);
} }
public static String getDefaultPermissionsSubPath(DefaultPermission defaultPermission) {
return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, defaultPermission.name());
}
@Override @Override
public void reload() { public void reload() {
messageFileHandler = messageFileHandlerProvider.initializeHandler( messageFileHandler = messageFileHandlerProvider.initializeHandler(
@ -99,8 +102,15 @@ public class HelpMessagesService implements Reloadable {
: message; : 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() .stream()
.map(cmd -> cmd.getLabels().get(0)) .map(cmd -> cmd.getLabels().get(0))
.collect(Collectors.joining(".")); .collect(Collectors.joining("."));

View File

@ -19,7 +19,7 @@ public enum HelpSection {
CHILDREN("children"); CHILDREN("children");
private static final String PREFIX = "section.";
private final String key; private final String key;
/** /**
@ -28,11 +28,17 @@ public enum HelpSection {
* @param key the message key * @param key the message key
*/ */
HelpSection(String key) { HelpSection(String key) {
this.key = "section." + key; this.key = PREFIX + key;
} }
/** @return the message key */ /** @return the message key */
public String getKey() { public String getKey() {
return key; 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());
}
} }

View File

@ -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<String, Object> helpEntries = generateHelpMessageEntries();
String helpEntriesYaml = exportToYaml(helpEntries);
Files.write(helpFile.toPath(), helpEntriesYaml.getBytes(), StandardOpenOption.TRUNCATE_EXISTING);
}
private static String exportToYaml(Map<String, Object> 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<String, Object> generateHelpMessageEntries() {
Map<String, Object> messageEntries = new LinkedHashMap<>(HelpMessage.values().length);
for (HelpMessage message : HelpMessage.values()) {
messageEntries.put(message.getEntryKey(), helpMessagesService.getMessage(message));
}
Map<String, String> defaultPermissions = new LinkedHashMap<>();
for (DefaultPermission defaultPermission : DefaultPermission.values()) {
defaultPermissions.put(HelpMessagesService.getDefaultPermissionsSubPath(defaultPermission),
helpMessagesService.getMessage(defaultPermission));
}
messageEntries.put("defaultPermissions", defaultPermissions);
Map<String, String> sectionEntries = new LinkedHashMap<>(HelpSection.values().length);
for (HelpSection section : HelpSection.values()) {
sectionEntries.put(section.getEntryKey(), helpMessagesService.getMessage(section));
}
Map<String, Object> 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<String, Object> commandEntries) {
CommandDescription translatedCommand = helpMessagesService.buildLocalizedDescription(command);
Map<String, Object> commandData = new LinkedHashMap<>();
commandData.put("description", translatedCommand.getDescription());
commandData.put("detailedDescription", translatedCommand.getDetailedDescription());
int i = 1;
for (CommandArgumentDescription argument : translatedCommand.getArguments()) {
Map<String, String> 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));
}
}

View File

@ -38,9 +38,8 @@ public class JoinMessageService {
*/ */
public void sendMessage(String playerName) { public void sendMessage(String playerName) {
String joinMessage = joinMessages.remove(playerName); String joinMessage = joinMessages.remove(playerName);
if (StringUtils.isEmpty(joinMessage)) { if (!StringUtils.isEmpty(joinMessage)) {
return; bukkitService.broadcastMessage(joinMessage);
} }
bukkitService.broadcastMessage(joinMessage);
} }
} }