Merge branch '768-update-messages-cmd' of https://github.com/AuthMe-Team/AuthMeReloaded

This commit is contained in:
ljacqu 2016-10-18 17:09:13 +02:00
commit dc8d0b9b6b
11 changed files with 285 additions and 60 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 Sat Oct 01 23:33:39 CEST 2016. See commands/commands.tpl.md --> <!-- File auto-generated on Sun Oct 16 21:39:08 CEST 2016. See 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 `< >`
@ -45,6 +45,8 @@ 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** &lt;job>: Converter command for AuthMeReloaded. - **/authme converter** &lt;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.
<br />Requires `authme.admin.updatemessages`
- **/authme help** [query]: View detailed help for /authme commands. - **/authme help** [query]: View detailed help for /authme commands.
- **/login** &lt;password>: Command to log in using AuthMeReloaded. - **/login** &lt;password>: Command to log in using AuthMeReloaded.
<br />Requires `authme.player.login` <br />Requires `authme.player.login`
@ -76,4 +78,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 Sat Oct 01 23:33:39 CEST 2016 This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Sun Oct 16 21:39:08 CEST 2016

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 Sun Oct 02 10:47:16 CEST 2016. See permissions/permission_nodes.tpl.md --> <!-- File auto-generated on Sun Oct 16 21:39:10 CEST 2016. See permissions/permission_nodes.tpl.md -->
## AuthMe Permission Nodes ## AuthMe Permission Nodes
The following are the permission nodes that are currently supported by the latest dev builds. The following are the permission nodes that are currently supported by the latest dev builds.
@ -26,14 +26,16 @@ The following are the permission nodes that are currently supported by the lates
- **authme.admin.spawn** Administrator command to teleport to the AuthMe spawn. - **authme.admin.spawn** Administrator command to teleport to the AuthMe spawn.
- **authme.admin.switchantibot** Administrator command to toggle the AntiBot protection status. - **authme.admin.switchantibot** Administrator command to toggle the AntiBot protection status.
- **authme.admin.unregister** Administrator command to unregister an existing user. - **authme.admin.unregister** Administrator command to unregister an existing user.
- **authme.admin.updatemessages** Permission to use the update messages command.
- **authme.allowmultipleaccounts** Permission to be able to register multiple accounts. - **authme.allowmultipleaccounts** Permission to be able to register multiple accounts.
- **authme.bypassantibot** Permission node to bypass AntiBot protection. - **authme.bypassantibot** Permission node to bypass AntiBot protection.
- **authme.bypassforcesurvival** Permission for users to bypass force-survival mode. - **authme.bypassforcesurvival** Permission for users to bypass force-survival mode.
- **authme.bypasspurge** Permission to bypass the purging process - **authme.bypasspurge** Permission to bypass the purging process.
- **authme.player.*** Permission to use all player (non-admin) commands. - **authme.player.*** Permission to use all player (non-admin) commands.
- **authme.player.canbeforced** Permission for users a login can be forced to. - **authme.player.canbeforced** Permission for users a login can be forced to.
- **authme.player.captcha** Command permission to use captcha. - **authme.player.captcha** Command permission to use captcha.
- **authme.player.changepassword** Command permission to change the password. - **authme.player.changepassword** Command permission to change the password.
- **authme.player.email** Grants all email permissions.
- **authme.player.email.add** Command permission to add an email address. - **authme.player.email.add** Command permission to add an email address.
- **authme.player.email.change** Command permission to change the email address. - **authme.player.email.change** Command permission to change the email address.
- **authme.player.email.recover** Command permission to recover an account using it's email address. - **authme.player.email.recover** Command permission to recover an account using it's email address.
@ -47,4 +49,4 @@ The following are the permission nodes that are currently supported by the lates
--- ---
This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Sun Oct 02 10:47:16 CEST 2016 This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Sun Oct 16 21:39:10 CEST 2016

View File

@ -11,6 +11,7 @@ import fr.xephi.authme.command.executable.authme.ForceLoginCommand;
import fr.xephi.authme.command.executable.authme.GetEmailCommand; import fr.xephi.authme.command.executable.authme.GetEmailCommand;
import fr.xephi.authme.command.executable.authme.GetIpCommand; import fr.xephi.authme.command.executable.authme.GetIpCommand;
import fr.xephi.authme.command.executable.authme.LastLoginCommand; import fr.xephi.authme.command.executable.authme.LastLoginCommand;
import fr.xephi.authme.command.executable.authme.MessagesCommand;
import fr.xephi.authme.command.executable.authme.PurgeBannedPlayersCommand; import fr.xephi.authme.command.executable.authme.PurgeBannedPlayersCommand;
import fr.xephi.authme.command.executable.authme.PurgeCommand; import fr.xephi.authme.command.executable.authme.PurgeCommand;
import fr.xephi.authme.command.executable.authme.PurgeLastPositionCommand; import fr.xephi.authme.command.executable.authme.PurgeLastPositionCommand;
@ -289,6 +290,15 @@ public class CommandInitializer {
.executableCommand(ConverterCommand.class) .executableCommand(ConverterCommand.class)
.build(); .build();
CommandDescription.builder()
.parent(AUTHME_BASE)
.labels("messages", "msg")
.description("Add missing messages")
.detailedDescription("Adds missing messages to the current messages file.")
.permission(AdminPermission.UPDATE_MESSAGES)
.executableCommand(MessagesCommand.class)
.build();
// Register the base login command // Register the base login command
final CommandDescription LOGIN_BASE = CommandDescription.builder() final CommandDescription LOGIN_BASE = CommandDescription.builder()
.parent(null) .parent(null)

View File

@ -0,0 +1,54 @@
package fr.xephi.authme.command.executable.authme;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.initialization.DataFolder;
import fr.xephi.authme.message.Messages;
import fr.xephi.authme.service.MessageUpdater;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.PluginSettings;
import org.bukkit.command.CommandSender;
import javax.inject.Inject;
import java.io.File;
import java.util.List;
/**
* Messages command, updates the user's messages file with any missing files
* from the provided file in the JAR.
*/
public class MessagesCommand implements ExecutableCommand {
private static final String DEFAULT_LANGUAGE = "en";
@Inject
private Settings settings;
@Inject
@DataFolder
private File dataFolder;
@Inject
private Messages messages;
@Override
public void executeCommand(CommandSender sender, List<String> arguments) {
final String language = settings.getProperty(PluginSettings.MESSAGES_LANGUAGE);
try {
boolean isFileUpdated = new MessageUpdater(
new File(dataFolder, getMessagePath(language)),
getMessagePath(language),
getMessagePath(DEFAULT_LANGUAGE))
.executeCopy(sender);
if (isFileUpdated) {
messages.reload();
}
} catch (Exception e) {
sender.sendMessage("Could not update messages: " + e.getMessage());
ConsoleLogger.logException("Could not update messages:", e);
}
}
private static String getMessagePath(String code) {
return "messages/messages_" + code + ".yml";
}
}

View File

@ -8,126 +8,125 @@ public enum AdminPermission implements PermissionNode {
/** /**
* Administrator command to register a new user. * Administrator command to register a new user.
*/ */
REGISTER("authme.admin.register", DefaultPermission.OP_ONLY), REGISTER("authme.admin.register"),
/** /**
* Administrator command to unregister an existing user. * Administrator command to unregister an existing user.
*/ */
UNREGISTER("authme.admin.unregister", DefaultPermission.OP_ONLY), UNREGISTER("authme.admin.unregister"),
/** /**
* Administrator command to force-login an existing user. * Administrator command to force-login an existing user.
*/ */
FORCE_LOGIN("authme.admin.forcelogin", DefaultPermission.OP_ONLY), FORCE_LOGIN("authme.admin.forcelogin"),
/** /**
* Administrator command to change the password of a user. * Administrator command to change the password of a user.
*/ */
CHANGE_PASSWORD("authme.admin.changepassword", DefaultPermission.OP_ONLY), CHANGE_PASSWORD("authme.admin.changepassword"),
/** /**
* Administrator command to see the last login date and time of a user. * Administrator command to see the last login date and time of a user.
*/ */
LAST_LOGIN("authme.admin.lastlogin", DefaultPermission.OP_ONLY), LAST_LOGIN("authme.admin.lastlogin"),
/** /**
* Administrator command to see all accounts associated with a user. * Administrator command to see all accounts associated with a user.
*/ */
ACCOUNTS("authme.admin.accounts", DefaultPermission.OP_ONLY), ACCOUNTS("authme.admin.accounts"),
/** /**
* Administrator command to get the email address of a user, if set. * Administrator command to get the email address of a user, if set.
*/ */
GET_EMAIL("authme.admin.getemail", DefaultPermission.OP_ONLY), GET_EMAIL("authme.admin.getemail"),
/** /**
* Administrator command to set or change the email address of a user. * Administrator command to set or change the email address of a user.
*/ */
CHANGE_EMAIL("authme.admin.changemail", DefaultPermission.OP_ONLY), CHANGE_EMAIL("authme.admin.changemail"),
/** /**
* Administrator command to get the last known IP of a user. * Administrator command to get the last known IP of a user.
*/ */
GET_IP("authme.admin.getip", DefaultPermission.OP_ONLY), GET_IP("authme.admin.getip"),
/** /**
* Administrator command to teleport to the AuthMe spawn. * Administrator command to teleport to the AuthMe spawn.
*/ */
SPAWN("authme.admin.spawn", DefaultPermission.OP_ONLY), SPAWN("authme.admin.spawn"),
/** /**
* Administrator command to set the AuthMe spawn. * Administrator command to set the AuthMe spawn.
*/ */
SET_SPAWN("authme.admin.setspawn", DefaultPermission.OP_ONLY), SET_SPAWN("authme.admin.setspawn"),
/** /**
* Administrator command to teleport to the first AuthMe spawn. * Administrator command to teleport to the first AuthMe spawn.
*/ */
FIRST_SPAWN("authme.admin.firstspawn", DefaultPermission.OP_ONLY), FIRST_SPAWN("authme.admin.firstspawn"),
/** /**
* Administrator command to set the first AuthMe spawn. * Administrator command to set the first AuthMe spawn.
*/ */
SET_FIRST_SPAWN("authme.admin.setfirstspawn", DefaultPermission.OP_ONLY), SET_FIRST_SPAWN("authme.admin.setfirstspawn"),
/** /**
* Administrator command to purge old user data. * Administrator command to purge old user data.
*/ */
PURGE("authme.admin.purge", DefaultPermission.OP_ONLY), PURGE("authme.admin.purge"),
/** /**
* Administrator command to purge the last position of a user. * Administrator command to purge the last position of a user.
*/ */
PURGE_LAST_POSITION("authme.admin.purgelastpos", DefaultPermission.OP_ONLY), PURGE_LAST_POSITION("authme.admin.purgelastpos"),
/** /**
* Administrator command to purge all data associated with banned players. * Administrator command to purge all data associated with banned players.
*/ */
PURGE_BANNED_PLAYERS("authme.admin.purgebannedplayers", DefaultPermission.OP_ONLY), PURGE_BANNED_PLAYERS("authme.admin.purgebannedplayers"),
/** /**
* Administrator command to toggle the AntiBot protection status. * Administrator command to toggle the AntiBot protection status.
*/ */
SWITCH_ANTIBOT("authme.admin.switchantibot", DefaultPermission.OP_ONLY), SWITCH_ANTIBOT("authme.admin.switchantibot"),
/** /**
* Administrator command to convert old or other data to AuthMe data. * Administrator command to convert old or other data to AuthMe data.
*/ */
CONVERTER("authme.admin.converter", DefaultPermission.OP_ONLY), CONVERTER("authme.admin.converter"),
/** /**
* Administrator command to reload the plugin configuration. * Administrator command to reload the plugin configuration.
*/ */
RELOAD("authme.admin.reload", DefaultPermission.OP_ONLY), RELOAD("authme.admin.reload"),
/** /**
* Permission to see Antibot messages. * Permission to see Antibot messages.
*/ */
ANTIBOT_MESSAGES("authme.admin.antibotmessages", DefaultPermission.OP_ONLY), ANTIBOT_MESSAGES("authme.admin.antibotmessages"),
/**
* Permission to use the update messages command.
*/
UPDATE_MESSAGES("authme.admin.updatemessages"),
/** /**
* Permission to see the other accounts of the players that log in. * Permission to see the other accounts of the players that log in.
*/ */
SEE_OTHER_ACCOUNTS("authme.admin.seeotheraccounts", DefaultPermission.OP_ONLY); SEE_OTHER_ACCOUNTS("authme.admin.seeotheraccounts");
/** /**
* The permission node. * The permission node.
*/ */
private String node; private String node;
/**
* The default permission level
*/
private DefaultPermission defaultPermission;
/** /**
* Constructor. * Constructor.
* *
* @param node Permission node. * @param node Permission node.
*/ */
AdminPermission(String node, DefaultPermission defaultPermission) { AdminPermission(String node) {
this.node = node; this.node = node;
this.defaultPermission = defaultPermission;
} }
@Override @Override
@ -137,6 +136,6 @@ public enum AdminPermission implements PermissionNode {
@Override @Override
public DefaultPermission getDefaultPermission() { public DefaultPermission getDefaultPermission() {
return defaultPermission; return DefaultPermission.OP_ONLY;
} }
} }

View File

@ -8,76 +8,70 @@ public enum PlayerPermission implements PermissionNode {
/** /**
* Command permission to login. * Command permission to login.
*/ */
LOGIN("authme.player.login", DefaultPermission.ALLOWED), LOGIN("authme.player.login"),
/** /**
* Command permission to logout. * Command permission to logout.
*/ */
LOGOUT("authme.player.logout", DefaultPermission.ALLOWED), LOGOUT("authme.player.logout"),
/** /**
* Command permission to register. * Command permission to register.
*/ */
REGISTER("authme.player.register", DefaultPermission.ALLOWED), REGISTER("authme.player.register"),
/** /**
* Command permission to unregister. * Command permission to unregister.
*/ */
UNREGISTER("authme.player.unregister", DefaultPermission.ALLOWED), UNREGISTER("authme.player.unregister"),
/** /**
* Command permission to change the password. * Command permission to change the password.
*/ */
CHANGE_PASSWORD("authme.player.changepassword", DefaultPermission.ALLOWED), CHANGE_PASSWORD("authme.player.changepassword"),
/** /**
* Command permission to add an email address. * Command permission to add an email address.
*/ */
ADD_EMAIL("authme.player.email.add", DefaultPermission.ALLOWED), ADD_EMAIL("authme.player.email.add"),
/** /**
* Command permission to change the email address. * Command permission to change the email address.
*/ */
CHANGE_EMAIL("authme.player.email.change", DefaultPermission.ALLOWED), CHANGE_EMAIL("authme.player.email.change"),
/** /**
* Command permission to recover an account using it's email address. * Command permission to recover an account using it's email address.
*/ */
RECOVER_EMAIL("authme.player.email.recover", DefaultPermission.ALLOWED), RECOVER_EMAIL("authme.player.email.recover"),
/** /**
* Command permission to use captcha. * Command permission to use captcha.
*/ */
CAPTCHA("authme.player.captcha", DefaultPermission.ALLOWED), CAPTCHA("authme.player.captcha"),
/** /**
* Permission for users a login can be forced to. * Permission for users a login can be forced to.
*/ */
CAN_LOGIN_BE_FORCED("authme.player.canbeforced", DefaultPermission.ALLOWED), CAN_LOGIN_BE_FORCED("authme.player.canbeforced"),
/** /**
* Permission to use to see own other accounts. * Permission to use to see own other accounts.
*/ */
SEE_OWN_ACCOUNTS("authme.player.seeownaccounts", DefaultPermission.ALLOWED); SEE_OWN_ACCOUNTS("authme.player.seeownaccounts");
/** /**
* The permission node. * The permission node.
*/ */
private String node; private String node;
/**
* The default permission level
*/
private DefaultPermission defaultPermission;
/** /**
* Constructor. * Constructor.
* *
* @param node Permission node. * @param node Permission node.
*/ */
PlayerPermission(String node, DefaultPermission defaultPermission) { PlayerPermission(String node) {
this.node = node; this.node = node;
this.defaultPermission = defaultPermission;
} }
@Override @Override
@ -87,7 +81,7 @@ public enum PlayerPermission implements PermissionNode {
@Override @Override
public DefaultPermission getDefaultPermission() { public DefaultPermission getDefaultPermission() {
return defaultPermission; return DefaultPermission.ALLOWED;
} }
} }

View File

@ -27,7 +27,7 @@ public enum PlayerStatePermission implements PermissionNode {
ALLOW_MULTIPLE_ACCOUNTS("authme.allowmultipleaccounts", DefaultPermission.OP_ONLY), ALLOW_MULTIPLE_ACCOUNTS("authme.allowmultipleaccounts", DefaultPermission.OP_ONLY),
/** /**
* Permission to bypass the purging process * Permission to bypass the purging process.
*/ */
BYPASS_PURGE("authme.bypasspurge", DefaultPermission.NOT_ALLOWED); BYPASS_PURGE("authme.bypasspurge", DefaultPermission.NOT_ALLOWED);
@ -44,7 +44,8 @@ public enum PlayerStatePermission implements PermissionNode {
/** /**
* Constructor. * Constructor.
* *
* @param node Permission node. * @param node Permission node
* @param defaultPermission The default permission
*/ */
PlayerStatePermission(String node, DefaultPermission defaultPermission) { PlayerStatePermission(String node, DefaultPermission defaultPermission) {
this.node = node; this.node = node;

View File

@ -0,0 +1,139 @@
package fr.xephi.authme.service;
import com.github.authme.configme.SettingsManager;
import com.github.authme.configme.knownproperties.ConfigurationData;
import com.github.authme.configme.properties.Property;
import com.github.authme.configme.properties.StringProperty;
import com.github.authme.configme.resource.YamlFileResource;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.util.FileUtils;
import fr.xephi.authme.util.StringUtils;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* Updates a user's messages file with messages from the JAR files.
*/
public class MessageUpdater {
private final FileConfiguration userConfiguration;
private final FileConfiguration localJarConfiguration;
private final FileConfiguration defaultJarConfiguration;
private final List<Property<String>> properties;
private final SettingsManager settingsManager;
private boolean hasMissingMessages = false;
/**
* Constructor.
*
* @param userFile messages file in the data folder
* @param localJarFile path to messages file in JAR in local language
* @param defaultJarFile path to messages file in JAR for default language
* @throws Exception if userFile does not exist or no JAR messages file can be loaded
*/
public MessageUpdater(File userFile, String localJarFile, String defaultJarFile) throws Exception {
if (!userFile.exists()) {
throw new Exception("Local messages file does not exist");
}
userConfiguration = YamlConfiguration.loadConfiguration(userFile);
localJarConfiguration = loadJarFileOrSendError(localJarFile);
defaultJarConfiguration = localJarFile.equals(defaultJarFile) ? null : loadJarFileOrSendError(defaultJarFile);
if (localJarConfiguration == null && defaultJarConfiguration == null) {
throw new Exception("Could not load any JAR messages file to copy from");
}
properties = buildPropertyEntriesForMessageKeys();
settingsManager = new SettingsManager(
new YamlFileResource(userFile), (r, p) -> true, new ConfigurationData((List) properties));
}
/**
* Copies missing messages to the messages file.
*
* @param sender sender starting the copy process
* @return true if the messages file was updated, false otherwise
* @throws Exception if an error occurs during saving
*/
public boolean executeCopy(CommandSender sender) throws Exception {
copyMissingMessages();
if (!hasMissingMessages) {
sender.sendMessage("No new messages to add");
return false;
}
// Save user configuration file
try {
settingsManager.save();
sender.sendMessage("Message file updated with new messages");
return true;
} catch (Exception e) {
throw new Exception("Could not save to messages file: " + StringUtils.formatException(e));
}
}
@SuppressWarnings("unchecked")
private void copyMissingMessages() {
for (Property<String> property : properties) {
String message = userConfiguration.getString(property.getPath());
if (message == null) {
hasMissingMessages = true;
message = getMessageFromJar(property.getPath());
}
settingsManager.setProperty(property, message);
}
}
private String getMessageFromJar(String key) {
String message = (localJarConfiguration == null ? null : localJarConfiguration.getString(key));
if (message != null) {
return message;
}
return (defaultJarConfiguration == null) ? null : defaultJarConfiguration.getString(key);
}
private static FileConfiguration loadJarFileOrSendError(String jarPath) {
try (InputStream stream = FileUtils.getResourceFromJar(jarPath)) {
if (stream == null) {
ConsoleLogger.info("Could not load '" + jarPath + "' from JAR");
return null;
}
InputStreamReader isr = new InputStreamReader(stream);
FileConfiguration configuration = YamlConfiguration.loadConfiguration(isr);
close(isr);
return configuration;
} catch (IOException e) {
ConsoleLogger.logException("Exception while handling JAR path '" + jarPath + "'", e);
}
return null;
}
private static List<Property<String>> buildPropertyEntriesForMessageKeys() {
return Arrays.stream(MessageKey.values())
.map(key -> new StringProperty(key.getKey(), ""))
.collect(Collectors.toList());
}
private static void close(Closeable closeable) {
if (closeable != null) {
try {
closeable.close();
} catch (IOException e) {
ConsoleLogger.info("Cannot close '" + closeable + "': " + StringUtils.formatException(e));
}
}
}
}

View File

@ -23,7 +23,7 @@ public final class FileUtils {
* Copy a resource file (from the JAR) to the given file if it doesn't exist. * Copy a resource file (from the JAR) to the given file if it doesn't exist.
* *
* @param destinationFile The file to check and copy to (outside of JAR) * @param destinationFile The file to check and copy to (outside of JAR)
* @param resourcePath Absolute path to the resource file (path to file within JAR) * @param resourcePath Local path to the resource file (path to file within JAR)
* *
* @return False if the file does not exist and could not be copied, true otherwise * @return False if the file does not exist and could not be copied, true otherwise
*/ */
@ -35,9 +35,7 @@ public final class FileUtils {
return false; return false;
} }
// ClassLoader#getResourceAsStream does not deal with the '\' path separator: replace to '/' try (InputStream is = getResourceFromJar(resourcePath)) {
final String normalizedPath = resourcePath.replace("\\", "/");
try (InputStream is = AuthMe.class.getClassLoader().getResourceAsStream(normalizedPath)) {
if (is == null) { if (is == null) {
ConsoleLogger.warning(format("Cannot copy resource '%s' to file '%s': cannot load resource", ConsoleLogger.warning(format("Cannot copy resource '%s' to file '%s': cannot load resource",
resourcePath, destinationFile.getPath())); resourcePath, destinationFile.getPath()));
@ -52,6 +50,18 @@ public final class FileUtils {
return false; return false;
} }
/**
* Returns a JAR file as stream. Returns null if it doesn't exist.
*
* @param path the local path (starting from resources project, e.g. "config.yml" for 'resources/config.yml')
* @return the stream if the file exists, or false otherwise
*/
public static InputStream getResourceFromJar(String path) {
// ClassLoader#getResourceAsStream does not deal with the '\' path separator: replace to '/'
final String normalizedPath = path.replace("\\", "/");
return AuthMe.class.getClassLoader().getResourceAsStream(normalizedPath);
}
/** /**
* Delete a given directory and all its content. * Delete a given directory and all its content.
* *

View File

@ -48,6 +48,7 @@ permissions:
description: Give access to all admin commands. description: Give access to all admin commands.
children: children:
authme.admin.accounts: true authme.admin.accounts: true
authme.admin.antibotmessages: true
authme.admin.changemail: true authme.admin.changemail: true
authme.admin.changepassword: true authme.admin.changepassword: true
authme.admin.converter: true authme.admin.converter: true
@ -66,6 +67,7 @@ permissions:
authme.admin.spawn: true authme.admin.spawn: true
authme.admin.switchantibot: true authme.admin.switchantibot: true
authme.admin.unregister: true authme.admin.unregister: true
authme.admin.updatemessages: true
authme.admin.register: authme.admin.register:
description: Administrator command to register a new user. description: Administrator command to register a new user.
default: op default: op
@ -127,7 +129,10 @@ permissions:
description: Administrator command to reload the plugin configuration. description: Administrator command to reload the plugin configuration.
default: op default: op
authme.admin.antibotmessages: authme.admin.antibotmessages:
description: Permission to see Antibot messages description: Permission to see Antibot messages.
default: op
authme.admin.updatemessages:
description: Permission to use the update messages command.
default: op default: op
authme.player.*: authme.player.*:
description: Permission to use all player (non-admin) commands. description: Permission to use all player (non-admin) commands.

View File

@ -11,6 +11,8 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;
/** /**
@ -119,6 +121,13 @@ public class FileUtilsTest {
// Nothing happens // Nothing happens
} }
@Test
public void shouldGetResourceFromJar() {
// given / when / then
assertThat(FileUtils.getResourceFromJar("config.yml"), not(nullValue()));
assertThat(FileUtils.getResourceFromJar("does-not-exist"), nullValue());
}
@Test @Test
public void shouldConstructPath() { public void shouldConstructPath() {
// given/when // given/when