Merge pull request #289 from AuthMe-Team/master

[DO NOT MERGE] Merge from AuthMe-Team
This commit is contained in:
Alexandre Vanhecke 2015-12-09 10:30:43 +01:00
commit 8fe0006ef5
127 changed files with 3979 additions and 2770 deletions

View File

@ -5,6 +5,8 @@
<value>
<option name="AUTODETECT_INDENTS" value="false" />
<option name="LINE_SEPARATOR" value="&#10;" />
<option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="99" />
<option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="99" />
<option name="JD_ADD_BLANK_AFTER_PARM_COMMENTS" value="true" />
<option name="JD_ADD_BLANK_AFTER_RETURN" value="true" />
<XML>

10
pom.xml
View File

@ -5,7 +5,7 @@
<groupId>fr.xephi</groupId>
<artifactId>authme</artifactId>
<version>5.1-SNAPSHOT</version>
<version>5.2-SNAPSHOT</version>
<packaging>jar</packaging>
<name>AuthMeReloaded</name>
@ -285,7 +285,7 @@
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>2.4.1</version>
<version>2.4.3</version>
<scope>compile</scope>
<exclusions>
<exclusion>
@ -298,7 +298,7 @@
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jdk14</artifactId>
<version>1.7.12</version>
<version>1.7.13</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
@ -502,6 +502,10 @@
<artifactId>AllPay</artifactId>
<groupId>com.fernferret.allpay</groupId>
</exclusion>
<exclusion>
<artifactId>Vault</artifactId>
<groupId>net.milkbowl.vault</groupId>
</exclusion>
<exclusion>
<artifactId>VaultAPI</artifactId>
<groupId>net.milkbowl.vault</groupId>

View File

@ -1,8 +1,8 @@
package fr.xephi.authme;
import fr.xephi.authme.permission.UserPermission;
import fr.xephi.authme.settings.MessageKey;
import fr.xephi.authme.settings.Messages;
import fr.xephi.authme.permission.PlayerPermission;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.util.Wrapper;
import org.bukkit.Bukkit;
@ -73,7 +73,7 @@ public class AntiBot {
if (antiBotStatus == AntiBotStatus.ACTIVE || antiBotStatus == AntiBotStatus.DISABLED) {
return;
}
if (plugin.getPermissionsManager().hasPermission(player, UserPermission.BYPASS_ANTIBOT)) {
if (plugin.getPermissionsManager().hasPermission(player, PlayerPermission.BYPASS_ANTIBOT)) {
return;
}

View File

@ -10,6 +10,7 @@ import fr.xephi.authme.cache.backup.JsonCache;
import fr.xephi.authme.cache.limbo.LimboCache;
import fr.xephi.authme.cache.limbo.LimboPlayer;
import fr.xephi.authme.command.CommandHandler;
import fr.xephi.authme.command.CommandInitializer;
import fr.xephi.authme.converter.Converter;
import fr.xephi.authme.converter.ForceFlatToSqlite;
import fr.xephi.authme.datasource.*;
@ -17,13 +18,18 @@ import fr.xephi.authme.hooks.BungeeCordMessage;
import fr.xephi.authme.hooks.EssSpawn;
import fr.xephi.authme.listener.*;
import fr.xephi.authme.modules.ModuleManager;
import fr.xephi.authme.output.ConsoleFilter;
import fr.xephi.authme.output.Log4JFilter;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages;
import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.permission.UserPermission;
import fr.xephi.authme.permission.PlayerPermission;
import fr.xephi.authme.process.Management;
import fr.xephi.authme.settings.*;
import fr.xephi.authme.util.GeoLiteAPI;
import fr.xephi.authme.util.StringUtils;
import fr.xephi.authme.util.Utils;
import fr.xephi.authme.util.Wrapper;
import net.minelink.ctplus.CombatTagPlus;
import org.apache.logging.log4j.LogManager;
import org.bukkit.Bukkit;
@ -66,8 +72,9 @@ public class AuthMe extends JavaPlugin {
private static AuthMe plugin;
private static Server server;
private static Wrapper wrapper = Wrapper.getInstance();
public Management management;
private Management management;
public NewAPI api;
public SendMailSSL mail;
public DataManager dataManager;
@ -227,7 +234,7 @@ public class AuthMe extends JavaPlugin {
this.otherAccounts = OtherAccounts.getInstance();
// Setup messages
this.messages = new Messages(Settings.messageFile, Settings.messagesLanguage);
this.messages = Messages.getInstance();
// Set up Metrics
setupMetrics();
@ -427,8 +434,7 @@ public class AuthMe extends JavaPlugin {
* Set up the command handler.
*/
private void setupCommandHandler() {
this.commandHandler = new CommandHandler(false);
this.commandHandler.init();
this.commandHandler = new CommandHandler(CommandInitializer.getBaseCommands());
}
/**
@ -735,7 +741,7 @@ public class AuthMe extends JavaPlugin {
public Player generateKickPlayer(Collection<? extends Player> collection) {
Player player = null;
for (Player p : collection) {
if (!getPermissionsManager().hasPermission(p, UserPermission.IS_VIP)) {
if (!getPermissionsManager().hasPermission(p, PlayerPermission.IS_VIP)) {
player = p;
break;
}
@ -951,13 +957,14 @@ public class AuthMe extends JavaPlugin {
@Override
public boolean onCommand(CommandSender sender, Command cmd,
String commandLabel, String[] args) {
// Get the command handler, and make sure it's valid
CommandHandler commandHandler = this.getCommandHandler();
if (commandHandler == null)
// Make sure the command handler has been initialized
if (commandHandler == null) {
wrapper.getLogger().severe("AuthMe command handler is not available");
return false;
}
// Handle the command, return the result
return commandHandler.onCommand(sender, cmd, commandLabel, args);
// Handle the command
return commandHandler.processCommand(sender, commandLabel, args);
}
/**

View File

@ -1,42 +0,0 @@
package fr.xephi.authme;
import java.util.logging.Filter;
import java.util.logging.LogRecord;
/**
* Console filter Class
*
* @author Xephi59
* @version $Revision: 1.0 $
*/
public class ConsoleFilter implements Filter {
public ConsoleFilter() {
}
/**
* Method isLoggable.
*
* @param record LogRecord
*
* @return boolean * @see java.util.logging.Filter#isLoggable(LogRecord)
*/
@Override
public boolean isLoggable(LogRecord record) {
try {
if (record == null || record.getMessage() == null)
return true;
String logM = record.getMessage().toLowerCase();
if (!logM.contains("issued server command:"))
return true;
if (!logM.contains("/login ") && !logM.contains("/l ") && !logM.contains("/reg ") && !logM.contains("/changepassword ") && !logM.contains("/unregister ") && !logM.contains("/authme register ") && !logM.contains("/authme changepassword ") && !logM.contains("/authme reg ") && !logM.contains("/authme cp ") && !logM.contains("/register "))
return true;
String playerName = record.getMessage().split(" ")[0];
record.setMessage(playerName + " issued an AuthMe command!");
return true;
} catch (NullPointerException npe) {
return true;
}
}
}

View File

@ -2,7 +2,6 @@ package fr.xephi.authme;
import com.google.common.base.Throwables;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.util.StringUtils;
import fr.xephi.authme.util.Wrapper;
import java.io.IOException;
@ -17,8 +16,10 @@ import java.util.Date;
*/
public final class ConsoleLogger {
private static final String NEW_LINE = System.getProperty("line.separator");
private static final DateFormat DATE_FORMAT = new SimpleDateFormat("[MM-dd HH:mm:ss]");
private static Wrapper wrapper = Wrapper.getInstance();
private static final DateFormat df = new SimpleDateFormat("[MM-dd HH:mm:ss]");
private ConsoleLogger() {
// Service class
@ -57,11 +58,11 @@ public final class ConsoleLogger {
*/
private static void writeLog(String message) {
String dateTime;
synchronized (df) {
dateTime = df.format(new Date());
synchronized (DATE_FORMAT) {
dateTime = DATE_FORMAT.format(new Date());
}
try {
Files.write(Settings.LOG_FILE.toPath(), (dateTime + ": " + message + StringUtils.newline).getBytes(),
Files.write(Settings.LOG_FILE.toPath(), (dateTime + ": " + message + NEW_LINE).getBytes(),
StandardOpenOption.APPEND,
StandardOpenOption.CREATE);
} catch (IOException ignored) {
@ -77,6 +78,6 @@ public final class ConsoleLogger {
if (!Settings.useLogging) {
return;
}
writeLog("" + Throwables.getStackTraceAsString(ex));
writeLog(Throwables.getStackTraceAsString(ex));
}
}

View File

@ -48,7 +48,7 @@ public class SendMailSSL {
final String subject = Settings.getMailSubject;
final String smtp = Settings.getmailSMTP;
final String password = Settings.getmailPassword;
final String mailText = Settings.getMailText.replace("<playername>", auth.getNickname()).replace("<servername>", plugin.getServer().getServerName()).replace("<generatedpass>", newPass);
final String mailText = Settings.getMailText.replace("%playername%", auth.getNickname()).replace("%servername%", plugin.getServer().getServerName()).replace("%generatedpass%", newPass);
final String mail = auth.getEmail();
Bukkit.getScheduler().runTaskAsynchronously(plugin, new Runnable() {
@ -76,7 +76,7 @@ public class SendMailSSL {
ImageIO.write(gen.generateImage(), "jpg", file);
DataSource source = new FileDataSource(file);
String tag = email.embed(source, auth.getNickname() + "_new_pass.jpg");
content = content.replace("<image>", "<img src=\"cid:" + tag + "\">");
content = content.replace("%image%", "<img src=\"cid:" + tag + "\">");
} catch (Exception e) {
ConsoleLogger.showError("Unable to send new password as image! Using normal text! Dest: " + mail);
}
@ -86,8 +86,7 @@ public class SendMailSSL {
try {
email.send();
} catch (Exception e) {
e.printStackTrace();
ConsoleLogger.showError("Fail to send a mail to " + mail);
ConsoleLogger.showError("Fail to send a mail to " + mail + " cause " + e.getLocalizedMessage());
}
if (file != null)
//noinspection ResultOfMethodCallIgnored

View File

@ -170,7 +170,7 @@ public class API {
*/
@Deprecated
public static void forceLogin(Player player) {
instance.management.performLogin(player, "dontneed", true);
instance.getManagement().performLogin(player, "dontneed", true);
}
/**

View File

@ -170,7 +170,7 @@ public class NewAPI {
* @param player * player
*/
public void forceLogin(Player player) {
plugin.management.performLogin(player, "dontneed", true);
plugin.getManagement().performLogin(player, "dontneed", true);
}
/**
@ -179,7 +179,7 @@ public class NewAPI {
* @param player * player
*/
public void forceLogout(Player player) {
plugin.management.performLogout(player);
plugin.getManagement().performLogout(player);
}
/**
@ -189,7 +189,7 @@ public class NewAPI {
* @param password String
*/
public void forceRegister(Player player, String password) {
plugin.management.performRegister(player, password, null);
plugin.getManagement().performRegister(player, password, null);
}
/**
@ -198,6 +198,6 @@ public class NewAPI {
* @param player * player
*/
public void forceUnregister(Player player) {
plugin.management.performUnregister(player, "", true);
plugin.getManagement().performUnregister(player, "", true);
}
}

View File

@ -23,9 +23,8 @@ public class PlayerAuth {
/**
*
*/
public PlayerAuth(String serialized)
{
this.unserialize(serialized);
public PlayerAuth(String serialized) {
this.deserialize(serialized);
}
/**
@ -163,8 +162,10 @@ public class PlayerAuth {
* @param email String
* @param realName String
*/
public PlayerAuth(String nickname, String hash, String salt, int groupId, String ip, long lastLogin, double x, double y, double z, String world, String email, String realName) {
this.nickname = nickname;
public PlayerAuth(String nickname, String hash, String salt, int groupId, String ip,
long lastLogin, double x, double y, double z, String world, String email,
String realName) {
this.nickname = nickname.toLowerCase();
this.hash = hash;
this.ip = ip;
this.lastLogin = lastLogin;
@ -203,7 +204,7 @@ public class PlayerAuth {
* @param nickname String
*/
public void setName(String nickname) {
this.nickname = nickname;
this.nickname = nickname.toLowerCase();
}
/**
@ -455,46 +456,137 @@ public class PlayerAuth {
}
/**
* Method to serialize playerauth
* Method to serialize PlayerAuth
*
* @return String
*/
public String serialize()
{
StringBuilder str = new StringBuilder();
str.append(this.nickname).append(';');
str.append(this.realName).append(';');
str.append(this.ip).append(';');
str.append(this.email).append(';');
str.append(this.hash).append(';');
str.append(this.salt).append(';');
str.append(this.groupId).append(';');
str.append(this.lastLogin).append(';');
str.append(this.world).append(';');
str.append(this.x).append(';');
str.append(this.y).append(';');
str.append(this.z);
return str.toString();
public String serialize() {
StringBuilder str = new StringBuilder();
char d = ';';
str.append(this.nickname).append(d);
str.append(this.realName).append(d);
str.append(this.ip).append(d);
str.append(this.email).append(d);
str.append(this.hash).append(d);
str.append(this.salt).append(d);
str.append(this.groupId).append(d);
str.append(this.lastLogin).append(d);
str.append(this.world).append(d);
str.append(this.x).append(d);
str.append(this.y).append(d);
str.append(this.z);
return str.toString();
}
/**
* Method to unserialize playerauth
*
* Method to deserialize PlayerAuth
*/
public void unserialize(String str)
{
String[] args = str.split(";");
this.nickname = args[0];
this.realName = args[1];
this.ip = args[2];
this.email = args[3];
this.hash = args[4];
this.salt = args[5];
this.groupId = Integer.parseInt(args[6]);
this.lastLogin = Long.parseLong(args[7]);
this.world = args[8];
this.x = Double.parseDouble(args[9]);
this.y = Double.parseDouble(args[10]);
this.z = Double.parseDouble(args[11]);
public void deserialize(String str) {
String[] args = str.split(";");
this.nickname = args[0];
this.realName = args[1];
this.ip = args[2];
this.email = args[3];
this.hash = args[4];
this.salt = args[5];
this.groupId = Integer.parseInt(args[6]);
this.lastLogin = Long.parseLong(args[7]);
this.world = args[8];
this.x = Double.parseDouble(args[9]);
this.y = Double.parseDouble(args[10]);
this.z = Double.parseDouble(args[11]);
}
public static Builder builder() {
return new Builder();
}
public static final class Builder {
private String name;
private String realName = "Player";
private String hash = "";
private String salt = "";
private String ip = "127.0.0.1";
private String world = "world";
private double x = 0.0f;
private double y = 0.0f;
private double z = 0.0f;
private long lastLogin = System.currentTimeMillis();
private int groupId = -1;
private String email = "your@email.com";
public PlayerAuth build() {
return new PlayerAuth(
name,
hash,
salt,
groupId,
ip,
lastLogin,
x, y, z, world,
email,
realName
);
}
public Builder name(String name) {
this.name = name.toLowerCase();
return this;
}
public Builder realName(String realName) {
this.realName = realName;
return this;
}
public Builder hash(String hash) {
this.hash = hash;
return this;
}
public Builder salt(String salt) {
this.salt = salt;
return this;
}
public Builder ip(String ip) {
this.ip = ip;
return this;
}
public Builder locWorld(String world) {
this.world = world;
return this;
}
public Builder locX(double x) {
this.x = x;
return this;
}
public Builder locY(double y) {
this.y = y;
return this;
}
public Builder locZ(double z) {
this.z = z;
return this;
}
public Builder lastLogin(long lastLogin) {
this.lastLogin = lastLogin;
return this;
}
public Builder groupId(int groupId) {
this.groupId = groupId;
return this;
}
public Builder email(String email) {
this.email = email;
return this;
}
}
}

View File

@ -14,6 +14,8 @@ import org.bukkit.entity.Player;
import java.util.concurrent.ConcurrentHashMap;
import static com.google.common.base.Preconditions.checkNotNull;
/**
*/
public class LimboCache {
@ -117,7 +119,8 @@ public class LimboCache {
* @param name String
*/
public void deleteLimboPlayer(String name) {
cache.remove(name);
checkNotNull(name);
cache.remove(name.toLowerCase());
}
/**
@ -128,7 +131,8 @@ public class LimboCache {
* @return LimboPlayer
*/
public LimboPlayer getLimboPlayer(String name) {
return cache.get(name);
checkNotNull(name);
return cache.get(name.toLowerCase());
}
/**
@ -139,7 +143,8 @@ public class LimboCache {
* @return boolean
*/
public boolean hasLimboPlayer(String name) {
return cache.containsKey(name);
checkNotNull(name);
return cache.containsKey(name.toLowerCase());
}
/**
@ -148,9 +153,8 @@ public class LimboCache {
* @param player Player
*/
public void updateLimboPlayer(Player player) {
if (this.hasLimboPlayer(player.getName().toLowerCase())) {
this.deleteLimboPlayer(player.getName().toLowerCase());
}
checkNotNull(player);
deleteLimboPlayer(player.getName().toLowerCase());
addLimboPlayer(player);
}

View File

@ -108,8 +108,9 @@ public class LimboPlayer {
* @param i BukkitTask
*/
public void setTimeoutTaskId(BukkitTask i) {
if (this.timeoutTaskId != null)
if (this.timeoutTaskId != null) {
this.timeoutTaskId.cancel();
}
this.timeoutTaskId = i;
}
@ -128,11 +129,27 @@ public class LimboPlayer {
* @param messageTaskId BukkitTask
*/
public void setMessageTaskId(BukkitTask messageTaskId) {
if (this.messageTaskId != null)
if (this.messageTaskId != null) {
this.messageTaskId.cancel();
}
this.messageTaskId = messageTaskId;
}
/**
* Method clearTask.
*
*/
public void clearTask() {
if (messageTaskId != null) {
messageTaskId.cancel();
}
messageTaskId = null;
if (timeoutTaskId != null) {
timeoutTaskId.cancel();
}
timeoutTaskId = null;
}
/**
* Method isFlying.
*

View File

@ -1,23 +1,22 @@
package fr.xephi.authme.command;
/**
* Wrapper for the description of a command argument.
*/
public class CommandArgumentDescription {
// TODO: Allow argument to consist of infinite parts. <label ...>
/**
* Argument label (one-word description of the argument).
*/
private String label;
private final String label;
/**
* Argument description.
*/
private String description;
private final String description;
/**
* Defines whether the argument is optional.
*/
private boolean isOptional = false;
private final boolean isOptional;
/**
* Constructor.
@ -51,7 +50,7 @@ public class CommandArgumentDescription {
}
/**
* Check whether the argument is optional.
* Return whether the argument is optional.
*
* @return True if the argument is optional, false otherwise.
*/

View File

@ -1,6 +1,8 @@
package fr.xephi.authme.command;
import fr.xephi.authme.permission.DefaultPermission;
import fr.xephi.authme.permission.PermissionNode;
import fr.xephi.authme.util.CollectionUtils;
import fr.xephi.authme.util.StringUtils;
import org.bukkit.command.CommandSender;
@ -15,9 +17,9 @@ import java.util.List;
* Command description - defines which labels ("names") will lead to a command and points to the
* {@link ExecutableCommand} implementation that executes the logic of the command.
*
* CommandDescription is built hierarchically and have one parent or {@code null} for base commands (main commands
* such as /authme) and may have multiple children extending the mapping of the parent: e.g. if /authme has a child
* whose label is "register", then "/authme register" is the command that the child defines.
* CommandDescription instances are built hierarchically and have one parent or {@code null} for base commands
* (main commands such as /authme) and may have multiple children extending the mapping of the parent: e.g. if
* /authme has a child whose label is "register", then "/authme register" is the command that the child defines.
*/
public class CommandDescription {
@ -50,95 +52,53 @@ public class CommandDescription {
* The arguments the command takes.
*/
private List<CommandArgumentDescription> arguments;
/**
* Defines whether there is an argument maximum or not.
*/
private boolean noArgumentMaximum;
/**
* Defines the command permissions.
*/
private CommandPermissions permissions;
/**
* Constructor.
*
* @param executableCommand The executable command, or null.
* @param labels List of command labels.
* @param description Command description.
* @param detailedDescription Detailed comment description.
* @param parent Parent command.
*/
public CommandDescription(ExecutableCommand executableCommand, List<String> labels, String description, String detailedDescription, CommandDescription parent) {
this(executableCommand, labels, description, detailedDescription, parent, null);
}
/**
* Constructor.
*
* @param executableCommand The executable command, or null.
* @param labels List of command labels.
* @param description Command description.
* @param detailedDescription Detailed comment description.
* @param parent Parent command.
* @param arguments Command arguments.
*/
public CommandDescription(ExecutableCommand executableCommand, List<String> labels, String description, String detailedDescription, CommandDescription parent, List<CommandArgumentDescription> arguments) {
setExecutableCommand(executableCommand);
this.labels = labels;
this.description = description;
this.detailedDescription = detailedDescription;
setParent(parent);
setArguments(arguments);
}
/**
* Private constructor. Use {@link CommandDescription#builder()} to create instances of this class.
* <p />
* Note for developers: Instances should be created with {@link CommandDescription#createInstance} to be properly
* registered in the command tree.
*/
private CommandDescription() {
}
/**
* Create an instance for internal use.
*
* @param executableCommand The executable command, or null.
* @param labels List of command labels.
* @param description Command description.
* @param detailedDescription Detailed comment description.
* @param executableCommand The executable command, or null.
* @param parent Parent command.
* @param arguments Command arguments.
* @param permissions The permissions required to execute this command.
*
* @return The created instance
* @see CommandDescription#builder()
*/
private CommandDescription(List<String> labels, String description, String detailedDescription,
ExecutableCommand executableCommand, CommandDescription parent,
List<CommandArgumentDescription> arguments, boolean noArgumentMaximum,
CommandPermissions permissions) {
this.labels = labels;
this.description = description;
this.detailedDescription = detailedDescription;
this.executableCommand = executableCommand;
this.parent = parent;
this.arguments = arguments;
this.noArgumentMaximum = noArgumentMaximum;
this.permissions = permissions;
private static CommandDescription createInstance(List<String> labels, String description,
String detailedDescription, ExecutableCommand executableCommand,
CommandDescription parent, List<CommandArgumentDescription> arguments,
CommandPermissions permissions) {
CommandDescription instance = new CommandDescription();
instance.labels = labels;
instance.description = description;
instance.detailedDescription = detailedDescription;
instance.executableCommand = executableCommand;
instance.parent = parent;
instance.arguments = arguments;
instance.permissions = permissions;
if (parent != null) {
// Passing `this` in constructor is not very nice; consider creating a "static create()" method instead
parent.addChild(this);
parent.addChild(instance);
}
return instance;
}
/**
* Check whether two labels are equal to each other.
*
* @param commandLabel The first command label.
* @param otherCommandLabel The other command label.
*
* @return True if the labels are equal to each other.
*/
private static boolean commandLabelEquals(String commandLabel, String otherCommandLabel) {
// Trim the command labels from unwanted whitespaces
commandLabel = commandLabel.trim();
otherCommandLabel = otherCommandLabel.trim();
// Check whether the the two command labels are equal (case insensitive)
return (commandLabel.equalsIgnoreCase(otherCommandLabel));
}
/**
* Get the label most similar to the reference. The first label will be returned if no reference was supplied.
*
@ -190,12 +150,11 @@ public class CommandDescription {
* @return True if this command label equals to the param command.
*/
public boolean hasLabel(String commandLabel) {
// Check whether any command matches with the argument
for (String entry : this.labels)
if (commandLabelEquals(entry, commandLabel))
for (String label : this.labels) {
if (label.equalsIgnoreCase(commandLabel)) {
return true;
// No match found, return false
}
}
return false;
}
@ -208,53 +167,17 @@ public class CommandDescription {
* @return True if the command reference is suitable to this command label, false otherwise.
*/
public boolean isSuitableLabel(CommandParts commandReference) {
// Make sure the command reference is valid
if (commandReference.getCount() <= 0)
return false;
// Get the parent count
//getParent() = getParent().getParentCount() + 1
String element = commandReference.get(getParentCount());
// Check whether this command description has this command label
return hasLabel(element);
}
/**
* Get the absolute command label, without a starting slash.
*
* @return The absolute label
*/
public String getAbsoluteLabel() {
return getAbsoluteLabel(false);
}
/**
* Get the absolute command label.
*
* @param includeSlash boolean
*
* @return Absolute command label.
*/
public String getAbsoluteLabel(boolean includeSlash) {
return getAbsoluteLabel(includeSlash, null);
}
/**
* Get the absolute command label.
*
* @param includeSlash
* @param reference
*
* @return Absolute command label.
*/
public String getAbsoluteLabel(boolean includeSlash, CommandParts reference) {
// Get the command reference, and make sure it is valid
CommandParts out = getCommandReference(reference);
if (out == null)
return "";
// Return the result
return (includeSlash ? "/" : "") + out.toString();
for (String label : labels) {
if (label.equalsIgnoreCase(element)) {
return true;
}
}
return false;
}
/**
@ -269,8 +192,9 @@ public class CommandDescription {
List<String> referenceList = new ArrayList<>();
// Check whether this command has a parent, if so, add the absolute parent command
if (getParent() != null)
if (getParent() != null) {
referenceList.addAll(getParent().getCommandReference(reference).getList());
}
// Get the current label
referenceList.add(getLabel(reference));
@ -307,7 +231,8 @@ public class CommandDescription {
CommandParts reference = getCommandReference(other);
// Compare the two references, return the result
return reference.getDifference(new CommandParts(other.getRange(0, reference.getCount())), fullCompare);
return CommandUtils.getDifference(reference.getList(),
CollectionUtils.getRange(other.getList(), 0, reference.getList().size()), fullCompare);
}
/**
@ -328,15 +253,6 @@ public class CommandDescription {
this.executableCommand = executableCommand;
}
/**
* Check whether this command is executable, based on the assigned executable command.
*
* @return True if this command is executable.
*/
public boolean isExecutable() {
return this.executableCommand != null;
}
/**
* Execute the command, if possible.
*
@ -347,10 +263,6 @@ public class CommandDescription {
* @return True on success, false on failure.
*/
public boolean execute(CommandSender sender, CommandParts commandReference, CommandParts commandArguments) {
// Make sure the command is executable
if (!isExecutable())
return false;
// Execute the command, return the result
return getExecutableCommand().executeCommand(sender, commandReference, commandArguments);
}
@ -461,7 +373,7 @@ public class CommandDescription {
*/
public boolean isChild(CommandDescription commandDescription) {
// Make sure the description is valid
if (commandDescription == null) // TODO: After builder, commandDescription == null -> never
if (commandDescription == null)
return false;
// Check whether this child exists, return the result
@ -480,10 +392,6 @@ public class CommandDescription {
if (argument == null)
return false;
// Make sure the argument isn't added already
if (hasArgument(argument))
return true;
// Add the argument, return the result
return this.arguments.add(argument);
}
@ -497,81 +405,13 @@ public class CommandDescription {
return this.arguments;
}
/**
* Set the arguments of this command.
*
* @param arguments New command arguments. Null to clear the list of arguments.
*/
public void setArguments(List<CommandArgumentDescription> arguments) {
// Convert null into an empty argument list
if (arguments == null) {
// Note ljacqu 20151128: Temporary workaround to avoid null pointer exception. Soon we won't need setters
// on the main class (-> complete instantiation via Builder)
// TODO Remove this method once unused
this.arguments = new ArrayList<>();
} else {
this.arguments = arguments;
}
}
/**
* Check whether an argument exists.
*
* @param argument The argument to check for.
*
* @return True if this argument already exists, false otherwise.
*/
public boolean hasArgument(CommandArgumentDescription argument) {
return argument != null && arguments.contains(argument);
}
/**
* Check whether this command has any arguments.
*
* @return True if this command has any arguments.
*/
public boolean hasArguments() {
return !arguments.isEmpty();
}
/**
* The minimum number of arguments required for this command.
*
* @return The minimum number of required arguments.
*/
public int getMinimumArguments() {
// Get the number of required and optional arguments
int requiredArguments = 0;
int optionalArgument = 0;
// Loop through each argument
for (CommandArgumentDescription argument : this.arguments) {
// Check whether the command is optional
if (!argument.isOptional()) {
requiredArguments += optionalArgument + 1;
optionalArgument = 0;
} else
optionalArgument++;
}
// Return the number of required arguments
return requiredArguments;
}
/**
* Get the maximum number of arguments.
*
* @return The maximum number of arguments. A negative number will be returned if there's no maximum.
*/
public int getMaximumArguments() {
// Check whether there is a maximum set
if (this.noArgumentMaximum)
// TODO ljacqu 20151128: Magic number
return -1;
// Return the maximum based on the registered arguments
return this.arguments.size();
return !getArguments().isEmpty();
}
/**
@ -580,16 +420,7 @@ public class CommandDescription {
* @return Command description.
*/
public String getDescription() {
return hasDescription() ? this.description : this.detailedDescription;
}
/**
* Check whether this command has any description.
*
* @return True if this command has any description.
*/
public boolean hasDescription() {
return !StringUtils.isEmpty(description);
return description;
}
/**
@ -598,7 +429,7 @@ public class CommandDescription {
* @return Command detailed description.
*/
public String getDetailedDescription() {
return !StringUtils.isEmpty(detailedDescription) ? this.detailedDescription : this.description;
return detailedDescription;
}
/**
@ -614,16 +445,17 @@ public class CommandDescription {
return null;
// Check whether this description is for the last element in the command reference, if so return the current command
if (queryReference.getCount() <= getParentCount() + 1)
if (queryReference.getCount() <= getParentCount() + 1) {
return new FoundCommandResult(
this,
getCommandReference(queryReference),
new CommandParts(),
new CommandParts(new ArrayList<String>()),
queryReference);
}
// Get the new command reference and arguments
CommandParts newReference = new CommandParts(queryReference.getRange(0, getParentCount() + 1));
CommandParts newArguments = new CommandParts(queryReference.getRange(getParentCount() + 1));
CommandParts newReference = new CommandParts(CollectionUtils.getRange(queryReference.getList(), 0, getParentCount() + 1));
CommandParts newArguments = new CommandParts(CollectionUtils.getRange(queryReference.getList(), getParentCount() + 1));
// Handle the child's, if this command has any
if (getChildren().size() > 0) {
@ -663,28 +495,6 @@ public class CommandDescription {
return null;
}
/**
* Check whether there's any command description that matches the specified command reference.
*
* @param commandReference The command reference.
*
* @return True if so, false otherwise.
*/
public boolean hasSuitableCommand(CommandParts commandReference) {
return findCommand(commandReference) != null;
}
/**
* Check if the remaining command reference elements are suitable with arguments of the current command description.
*
* @param commandReference The command reference.
*
* @return True if the arguments are suitable, false otherwise.
*/
public boolean hasSuitableArguments(CommandParts commandReference) {
return getSuitableArgumentsDifference(commandReference) == 0;
}
/**
* Check if the remaining command reference elements are suitable with arguments of the current command description,
* and get the difference in argument count.
@ -703,16 +513,18 @@ public class CommandDescription {
int remainingElementCount = commandReference.getCount() - getParentCount() - 1;
// Check if there are too few arguments
if (getMinimumArguments() > remainingElementCount) {
return Math.abs(getMinimumArguments() - remainingElementCount);
int minArguments = CommandUtils.getMinNumberOfArguments(this);
if (minArguments > remainingElementCount) {
return Math.abs(minArguments - remainingElementCount);
}
// Check if there are too many arguments
if (getMaximumArguments() < remainingElementCount && getMaximumArguments() >= 0) {
return Math.abs(remainingElementCount - getMaximumArguments());
int maxArguments = CommandUtils.getMaxNumberOfArguments(this);
if (maxArguments >= 0 && maxArguments < remainingElementCount) {
return Math.abs(remainingElementCount - maxArguments);
}
// The arguments seem to be EQUALS, return the result
// The argument count is the same
return 0;
}
@ -725,89 +537,86 @@ public class CommandDescription {
return this.permissions;
}
public static CommandBuilder builder() {
return new CommandBuilder();
}
/**
* Set the command permissions.
*
* @param permissionNode The permission node required.
* @param defaultPermission The default permission.
* Builder for initializing CommandDescription objects.
*/
public void setCommandPermissions(PermissionNode permissionNode, CommandPermissions.DefaultPermission defaultPermission) {
this.permissions = new CommandPermissions(permissionNode, defaultPermission);
}
public static Builder builder() {
return new Builder();
}
public static final class Builder {
public static final class CommandBuilder {
private List<String> labels;
private String description;
private String detailedDescription;
private ExecutableCommand executableCommand;
private CommandDescription parent;
private List<CommandArgumentDescription> arguments = new ArrayList<>();
private boolean noArgumentMaximum;
private CommandPermissions permissions;
/**
* Build a CommandDescription from the builder.
* Build a CommandDescription from the builder or throw an exception if mandatory
* fields have not been set.
*
* @return The generated CommandDescription object
*/
public CommandDescription build() {
return new CommandDescription(
return createInstance(
getOrThrow(labels, "labels"),
firstNonNull(description, ""),
firstNonNull(detailedDescription, ""),
getOrThrow(executableCommand, "executableCommand"),
firstNonNull(parent, null),
arguments,
noArgumentMaximum,
firstNonNull(permissions, null)
);
}
public Builder labels(List<String> labels) {
public CommandBuilder labels(List<String> labels) {
this.labels = labels;
return this;
}
public Builder labels(String... labels) {
public CommandBuilder labels(String... labels) {
return labels(asMutableList(labels));
}
public Builder description(String description) {
public CommandBuilder description(String description) {
this.description = description;
return this;
}
public Builder detailedDescription(String detailedDescription) {
public CommandBuilder detailedDescription(String detailedDescription) {
this.detailedDescription = detailedDescription;
return this;
}
public Builder executableCommand(ExecutableCommand executableCommand) {
public CommandBuilder executableCommand(ExecutableCommand executableCommand) {
this.executableCommand = executableCommand;
return this;
}
public Builder parent(CommandDescription parent) {
public CommandBuilder parent(CommandDescription parent) {
this.parent = parent;
return this;
}
public Builder withArgument(String label, String description, boolean isOptional) {
/**
* Add an argument that the command description requires. This method can be called multiples times to add
* multiple arguments.
*
* @param label The label of the argument (single word name of the argument)
* @param description The description of the argument
* @param isOptional True if the argument is option, false if it is mandatory
*
* @return The builder
*/
public CommandBuilder withArgument(String label, String description, boolean isOptional) {
arguments.add(new CommandArgumentDescription(label, description, isOptional));
return this;
}
public Builder noArgumentMaximum(boolean noArgumentMaximum) {
this.noArgumentMaximum = noArgumentMaximum;
return this;
}
public Builder permissions(CommandPermissions.DefaultPermission defaultPermission,
PermissionNode... permissionNodes) {
public CommandBuilder permissions(DefaultPermission defaultPermission,
PermissionNode... permissionNodes) {
this.permissions = new CommandPermissions(asMutableList(permissionNodes), defaultPermission);
return this;
}

View File

@ -2,209 +2,236 @@ package fr.xephi.authme.command;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.command.help.HelpProvider;
import fr.xephi.authme.util.CollectionUtils;
import fr.xephi.authme.util.StringUtils;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
/**
* The AuthMe command handler, responsible for mapping incoming commands to the correct {@link CommandDescription}
* or to display help messages for unknown invocations.
*/
public class CommandHandler {
/**
* The command manager instance.
* The threshold for assuming an existing command. If the difference is below this value, we assume
* that the user meant the similar command and we will run it.
*/
private CommandManager commandManager;
private static final double ASSUME_COMMAND_THRESHOLD = 0.12;
/**
* Constructor.
*
* @param init True to immediately initialize.
* The threshold for suggesting a similar command. If the difference is below this value, we will
* ask the player whether he meant the similar command.
*/
public CommandHandler(boolean init) {
// Initialize
if (init)
init();
private static final double SUGGEST_COMMAND_THRESHOLD = 0.75;
private final Set<CommandDescription> commands;
/**
* Create a command handler.
*
* @param commands The collection of available AuthMe commands
*/
public CommandHandler(Set<CommandDescription> commands) {
this.commands = commands;
}
/**
* Initialize the command handler.
*
* @return True if succeed, false on failure. True will also be returned if the command handler was already
* initialized.
*/
public boolean init() {
// Make sure the handler isn't initialized already
if (isInit())
return true;
// Initialize the command manager
this.commandManager = new CommandManager(false);
this.commandManager.registerCommands();
// Return the result
return true;
}
/**
* Check whether the command handler is initialized.
*
* @return True if the command handler is initialized.
*/
public boolean isInit() {
return this.commandManager != null;
}
/**
* Destroy the command handler.
*
* @return True if the command handler was destroyed successfully, false otherwise. True will also be returned if
* the command handler wasn't initialized.
*/
public boolean destroy() {
// Make sure the command handler is initialized
if (!isInit())
return true;
// Unset the command manager
this.commandManager = null;
return true;
}
/**
* Get the command manager.
*
* @return Command manager instance.
*/
public CommandManager getCommandManager() {
return this.commandManager;
}
/**
* Process a command.
* Map a command that was invoked to the proper {@link CommandDescription} or return a useful error
* message upon failure.
*
* @param sender The command sender (Bukkit).
* @param bukkitCommand The command (Bukkit).
* @param bukkitCommandLabel The command label (Bukkit).
* @param bukkitArgs The command arguments (Bukkit).
*
* @return True if the command was executed, false otherwise.
*/
public boolean onCommand(CommandSender sender, org.bukkit.command.Command bukkitCommand, String bukkitCommandLabel, String[] bukkitArgs) {
// Process the arguments
List<String> args = processArguments(bukkitArgs);
public boolean processCommand(CommandSender sender, String bukkitCommandLabel, String[] bukkitArgs) {
List<String> commandArgs = skipEmptyArguments(bukkitArgs);
// Add the Bukkit command label to the front so we get a list like [authme, register, pass, passConfirm]
commandArgs.add(0, bukkitCommandLabel);
// Create a command reference, and make sure at least one command part is available
CommandParts commandReference = new CommandParts(bukkitCommandLabel, args);
if (commandReference.getCount() == 0)
return false;
// TODO: remove commandParts
CommandParts commandReference = new CommandParts(commandArgs);
// Get a suitable command for this reference, and make sure it isn't null
FoundCommandResult result = this.commandManager.findCommand(commandReference);
FoundCommandResult result = findCommand(commandReference);
if (result == null) {
// TODO ljacqu 20151204: Log more information to the console (bukkitCommandLabel)
sender.sendMessage(ChatColor.DARK_RED + "Failed to parse " + AuthMe.getPluginName() + " command!");
return false;
}
// Get the base command
String baseCommand = commandReference.get(0);
String baseCommand = commandArgs.get(0);
// Make sure the difference between the command reference and the actual command isn't too big
final double commandDifference = result.getDifference();
if (commandDifference > 0.12) {
// Show the unknown command warning
sender.sendMessage(ChatColor.DARK_RED + "Unknown command!");
if (commandDifference <= ASSUME_COMMAND_THRESHOLD) {
// Show a command suggestion if available and the difference isn't too big
if (commandDifference < 0.75)
if (result.getCommandDescription() != null)
sender.sendMessage(ChatColor.YELLOW + "Did you mean " + ChatColor.GOLD + "/" + result.getCommandDescription().getCommandReference(commandReference) + ChatColor.YELLOW + "?");
// Show a message when the command handler is assuming a command
if (commandDifference > 0) {
sendCommandAssumptionMessage(sender, result, commandReference);
}
// Show the help command
sender.sendMessage(ChatColor.YELLOW + "Use the command " + ChatColor.GOLD + "/" + baseCommand + " help" + ChatColor.YELLOW + " to view help.");
return true;
if (!result.hasPermission(sender)) {
sender.sendMessage(ChatColor.DARK_RED + "You don't have permission to use this command!");
} else if (!result.hasProperArguments()) {
sendImproperArgumentsMessage(sender, result, commandReference, baseCommand);
} else {
return result.executeCommand(sender);
}
} else {
sendUnknownCommandMessage(sender, commandDifference, result, baseCommand);
}
// Show a message when the command handler is assuming a command
if (commandDifference > 0) {
// Get the suggested command
CommandParts suggestedCommandParts = new CommandParts(result.getCommandDescription().getCommandReference(commandReference));
// Show the suggested command
sender.sendMessage(ChatColor.DARK_RED + "Unknown command, assuming " + ChatColor.GOLD + "/" + suggestedCommandParts +
ChatColor.DARK_RED + "!");
}
// Make sure the command is executable
if (!result.isExecutable()) {
// Get the command reference
CommandParts helpCommandReference = new CommandParts(result.getCommandReference().getRange(1));
// Show the unknown command warning
sender.sendMessage(ChatColor.DARK_RED + "Invalid command!");
// Show the help command
sender.sendMessage(ChatColor.YELLOW + "Use the command " + ChatColor.GOLD + "/" + baseCommand + " help " + helpCommandReference + ChatColor.YELLOW + " to view help.");
return true;
}
// Make sure the command sender has permission
if (!result.hasPermission(sender)) {
// Show the no permissions warning
sender.sendMessage(ChatColor.DARK_RED + "You don't have permission to use this command!");
return true;
}
// Make sure the command sender has permission
if (!result.hasProperArguments()) {
// Get the command and the suggested command reference
CommandParts suggestedCommandReference = new CommandParts(result.getCommandDescription().getCommandReference(commandReference));
CommandParts helpCommandReference = new CommandParts(suggestedCommandReference.getRange(1));
// Show the invalid arguments warning
sender.sendMessage(ChatColor.DARK_RED + "Incorrect command arguments!");
// Show the command argument help
HelpProvider.showHelp(sender, commandReference, suggestedCommandReference, true, false, true, false, false, false);
// Show the command to use for detailed help
sender.sendMessage(ChatColor.GOLD + "Detailed help: " + ChatColor.WHITE + "/" + baseCommand + " help " + helpCommandReference);
return true;
}
// Execute the command if it's suitable
return result.executeCommand(sender);
return true;
}
/**
* Process the command arguments, and return them as an array list.
* Skip all entries of the given array that are simply whitespace.
*
* @param args The command arguments to process.
*
* @return The processed command arguments.
* @param args The array to process
* @return List of the items that are not empty
*/
private List<String> processArguments(String[] args) {
// Convert the array into a list of arguments
List<String> arguments = new ArrayList<>(Arrays.asList(args));
/// Remove all empty arguments
for (int i = 0; i < arguments.size(); i++) {
// Get the argument value
final String arg = arguments.get(i);
// Check whether the argument value is empty
if (arg.trim().length() == 0) {
// Remove the current argument
arguments.remove(i);
// Decrease the index by one, continue to the next argument
i--;
private static List<String> skipEmptyArguments(String[] args) {
List<String> cleanArguments = new ArrayList<>(args.length);
for (String argument : args) {
if (!StringUtils.isEmpty(argument)) {
cleanArguments.add(argument);
}
}
return cleanArguments;
}
// Return the argument
return arguments;
private static CommandDescription mapToBase(String commandLabel) {
for (CommandDescription command : CommandInitializer.getBaseCommands()) {
if (command.getLabels().contains(commandLabel)) {
return command;
}
}
return null;
}
/**
* Find the best suitable command for the specified reference.
*
* @param queryReference The query reference to find a command for.
*
* @return The command found, or null.
*/
public FoundCommandResult findCommand(CommandParts queryReference) {
// Make sure the command reference is valid
if (queryReference.getCount() <= 0)
return null;
for (CommandDescription commandDescription : commands) {
// Check whether there's a command description available for the
// current command
if (!commandDescription.isSuitableLabel(queryReference))
continue;
// Find the command reference, return the result
return commandDescription.findCommand(queryReference);
}
// No applicable command description found, return false
return null;
}
/**
* Find the best suitable command for the specified reference.
*
* @param commandParts The query reference to find a command for.
*
* @return The command found, or null.
*/
private CommandDescription findCommand(List<String> commandParts) {
// Make sure the command reference is valid
if (commandParts.isEmpty()) {
return null;
}
// TODO ljacqu 20151129: Since we only use .contains() on the CommandDescription#labels after init, change
// the type to set for faster lookup
Iterable<CommandDescription> commandsToScan = CommandInitializer.getBaseCommands();
CommandDescription result = null;
for (String label : commandParts) {
result = findLabel(label, commandsToScan);
if (result == null) {
return null;
}
commandsToScan = result.getChildren();
}
return result;
}
private static CommandDescription findLabel(String label, Iterable<CommandDescription> commands) {
if (commands == null) {
return null;
}
for (CommandDescription command : commands) {
if (command.getLabels().contains(label)) { // TODO ljacqu should be case-insensitive
return command;
}
}
return null;
}
/**
* Show an "unknown command" to the user and suggests an existing command if its similarity is within
* the defined threshold.
*
* @param sender The command sender
* @param commandDifference The difference between the invoked command and the existing one
* @param result The command that was found during the mapping process
* @param baseCommand The base command (TODO: This is probably already in FoundCommandResult)
*/
private static void sendUnknownCommandMessage(CommandSender sender, double commandDifference,
FoundCommandResult result, String baseCommand) {
CommandParts commandReference = result.getCommandReference();
sender.sendMessage(ChatColor.DARK_RED + "Unknown command!");
// Show a command suggestion if available and the difference isn't too big
if (commandDifference < SUGGEST_COMMAND_THRESHOLD && result.getCommandDescription() != null) {
sender.sendMessage(ChatColor.YELLOW + "Did you mean " + ChatColor.GOLD + "/"
+ result.getCommandDescription().getCommandReference(commandReference) + ChatColor.YELLOW + "?");
}
sender.sendMessage(ChatColor.YELLOW + "Use the command " + ChatColor.GOLD + "/" + baseCommand + " help"
+ ChatColor.YELLOW + " to view help.");
}
private static void sendImproperArgumentsMessage(CommandSender sender, FoundCommandResult result,
CommandParts commandReference, String baseCommand) {
// Get the command and the suggested command reference
List<String> suggestedCommandReference =
result.getCommandDescription().getCommandReference(commandReference).getList();
List<String> helpCommandReference = CollectionUtils.getRange(suggestedCommandReference, 1);
// Show the invalid arguments warning
sender.sendMessage(ChatColor.DARK_RED + "Incorrect command arguments!");
// Show the command argument help
HelpProvider.showHelp(sender, commandReference, new CommandParts(suggestedCommandReference),
true, false, true, false, false, false);
// Show the command to use for detailed help
sender.sendMessage(ChatColor.GOLD + "Detailed help: " + ChatColor.WHITE + "/" + baseCommand
+ " help " + CommandUtils.labelsToString(helpCommandReference));
}
private static void sendCommandAssumptionMessage(CommandSender sender, FoundCommandResult result,
CommandParts commandReference) {
List<String> assumedCommandParts =
result.getCommandDescription().getCommandReference(commandReference).getList();
sender.sendMessage(ChatColor.DARK_RED + "Unknown command, assuming " + ChatColor.GOLD + "/"
+ CommandUtils.labelsToString(assumedCommandParts) + ChatColor.DARK_RED + "!");
}
}

View File

@ -0,0 +1,509 @@
package fr.xephi.authme.command;
import fr.xephi.authme.command.executable.HelpCommand;
import fr.xephi.authme.command.executable.authme.AccountsCommand;
import fr.xephi.authme.command.executable.authme.AuthMeCommand;
import fr.xephi.authme.command.executable.authme.ChangePasswordAdminCommand;
import fr.xephi.authme.command.executable.authme.FirstSpawnCommand;
import fr.xephi.authme.command.executable.authme.ForceLoginCommand;
import fr.xephi.authme.command.executable.authme.GetEmailCommand;
import fr.xephi.authme.command.executable.authme.GetIpCommand;
import fr.xephi.authme.command.executable.authme.LastLoginCommand;
import fr.xephi.authme.command.executable.authme.PurgeBannedPlayersCommand;
import fr.xephi.authme.command.executable.authme.PurgeCommand;
import fr.xephi.authme.command.executable.authme.PurgeLastPositionCommand;
import fr.xephi.authme.command.executable.authme.RegisterAdminCommand;
import fr.xephi.authme.command.executable.authme.ReloadCommand;
import fr.xephi.authme.command.executable.authme.SetEmailCommand;
import fr.xephi.authme.command.executable.authme.SetFirstSpawnCommand;
import fr.xephi.authme.command.executable.authme.SetSpawnCommand;
import fr.xephi.authme.command.executable.authme.SpawnCommand;
import fr.xephi.authme.command.executable.authme.SwitchAntiBotCommand;
import fr.xephi.authme.command.executable.authme.UnregisterAdminCommand;
import fr.xephi.authme.command.executable.authme.VersionCommand;
import fr.xephi.authme.command.executable.captcha.CaptchaCommand;
import fr.xephi.authme.command.executable.changepassword.ChangePasswordCommand;
import fr.xephi.authme.command.executable.converter.ConverterCommand;
import fr.xephi.authme.command.executable.email.AddEmailCommand;
import fr.xephi.authme.command.executable.email.ChangeEmailCommand;
import fr.xephi.authme.command.executable.email.RecoverEmailCommand;
import fr.xephi.authme.command.executable.login.LoginCommand;
import fr.xephi.authme.command.executable.logout.LogoutCommand;
import fr.xephi.authme.command.executable.register.RegisterCommand;
import fr.xephi.authme.command.executable.unregister.UnregisterCommand;
import fr.xephi.authme.permission.AdminPermission;
import fr.xephi.authme.permission.PlayerPermission;
import fr.xephi.authme.util.Wrapper;
import java.util.*;
import static fr.xephi.authme.permission.DefaultPermission.ALLOWED;
import static fr.xephi.authme.permission.DefaultPermission.OP_ONLY;
/**
* Initializes all available AuthMe commands.
*/
public final class CommandInitializer {
private static Set<CommandDescription> baseCommands;
private CommandInitializer() {
// Helper class
}
public static Set<CommandDescription> getBaseCommands() {
if (baseCommands == null) {
Wrapper.getInstance().getLogger().info("Initializing AuthMe commands");
initializeCommands();
}
return baseCommands;
}
private static void initializeCommands() {
// Create a list of help command labels
final List<String> helpCommandLabels = Arrays.asList("help", "hlp", "h", "sos", "?");
final ExecutableCommand helpCommandExecutable = new HelpCommand();
// Register the base AuthMe Reloaded command
final CommandDescription AUTHME_BASE = CommandDescription.builder()
.labels("authme")
.description("Main command")
.detailedDescription("The main AuthMeReloaded command. The root for all admin commands.")
.executableCommand(new AuthMeCommand())
.build();
// Register the help command
CommandDescription.builder()
.parent(AUTHME_BASE)
.labels(helpCommandLabels)
.description("View help")
.detailedDescription("View detailed help pages about AuthMeReloaded commands.")
.withArgument("query", "The command or query to view help for.", true)
.executableCommand(helpCommandExecutable)
.build();
// Register the register command
CommandDescription.builder()
.parent(AUTHME_BASE)
.labels("register", "reg", "r")
.description("Register a player")
.detailedDescription("Register the specified player with the specified password.")
.withArgument("player", "Player name", false)
.withArgument("password", "Password", false)
.permissions(OP_ONLY, AdminPermission.REGISTER)
.executableCommand(new RegisterAdminCommand())
.build();
// Register the unregister command
CommandDescription.builder()
.parent(AUTHME_BASE)
.labels("unregister", "unreg", "unr")
.description("Unregister a player")
.detailedDescription("Unregister the specified player.")
.withArgument("player", "Player name", false)
.permissions(OP_ONLY, AdminPermission.UNREGISTER)
.executableCommand(new UnregisterAdminCommand())
.build();
// Register the forcelogin command
CommandDescription.builder()
.parent(AUTHME_BASE)
.labels("forcelogin", "login")
.description("Enforce login player")
.detailedDescription("Enforce the specified player to login.")
.withArgument("player", "Online player name", true)
.permissions(OP_ONLY, PlayerPermission.CAN_LOGIN_BE_FORCED)
.executableCommand(new ForceLoginCommand())
.build();
// Register the changepassword command
CommandDescription.builder()
.parent(AUTHME_BASE)
.labels("password", "changepassword", "changepass", "cp")
.description("Change a player's password")
.detailedDescription("Change the password of a player.")
.withArgument("player", "Player name", false)
.withArgument("pwd", "New password", false)
.permissions(OP_ONLY, AdminPermission.CHANGE_PASSWORD)
.executableCommand(new ChangePasswordAdminCommand())
.build();
// Register the last login command
CommandDescription.builder()
.parent(AUTHME_BASE)
.labels("lastlogin", "ll")
.description("Player's last login")
.detailedDescription("View the date of the specified players last login.")
.withArgument("player", "Player name", true)
.permissions(OP_ONLY, AdminPermission.LAST_LOGIN)
.executableCommand(new LastLoginCommand())
.build();
// Register the accounts command
CommandDescription.builder()
.parent(AUTHME_BASE)
.labels("accounts", "account")
.description("Display player accounts")
.detailedDescription("Display all accounts of a player by his player name or IP.")
.withArgument("player", "Player name or IP", true)
.permissions(OP_ONLY, AdminPermission.ACCOUNTS)
.executableCommand(new AccountsCommand())
.build();
// Register the getemail command
CommandDescription.builder()
.parent(AUTHME_BASE)
.labels("getemail", "getmail", "email", "mail")
.description("Display player's email")
.detailedDescription("Display the email address of the specified player if set.")
.permissions(OP_ONLY, AdminPermission.GET_EMAIL)
.withArgument("player", "Player name", true)
.executableCommand(new GetEmailCommand())
.build();
// Register the setemail command
CommandDescription.builder()
.executableCommand(new SetEmailCommand())
.parent(AUTHME_BASE)
.labels("chgemail", "chgmail", "setemail", "setmail")
.description("Change player's email")
.detailedDescription("Change the email address of the specified player.")
.permissions(OP_ONLY, AdminPermission.CHANGE_EMAIL)
.withArgument("player", "Player name", false)
.withArgument("email", "Player email", false)
.build();
// Register the getip command
CommandDescription.builder()
.executableCommand(new GetIpCommand())
.parent(AUTHME_BASE)
.labels("getip", "ip")
.description("Get player's IP")
.detailedDescription("Get the IP address of the specified online player.")
.permissions(OP_ONLY, AdminPermission.GET_IP)
.withArgument("player", "Player Name", false)
.build();
// Register the spawn command
CommandDescription.builder()
.executableCommand(new SpawnCommand())
.parent(AUTHME_BASE)
.labels("spawn", "home")
.description("Teleport to spawn")
.detailedDescription("Teleport to the spawn.")
.permissions(OP_ONLY, AdminPermission.SPAWN)
.withArgument("player", "Player Name", false)
.build();
// Register the setspawn command
CommandDescription.builder()
.executableCommand(new SetSpawnCommand())
.parent(AUTHME_BASE)
.labels("setspawn", "chgspawn")
.description("Change the spawn")
.detailedDescription("Change the player's spawn to your current position.")
.permissions(OP_ONLY, AdminPermission.SET_SPAWN)
.build();
// Register the firstspawn command
CommandDescription.builder()
.executableCommand(new FirstSpawnCommand())
.parent(AUTHME_BASE)
.labels("firstspawn", "firsthome")
.description("Teleport to first spawn")
.detailedDescription("Teleport to the first spawn.")
.permissions(OP_ONLY, AdminPermission.FIRST_SPAWN)
.build();
// Register the setfirstspawn command
CommandDescription.builder()
.executableCommand(new SetFirstSpawnCommand())
.parent(AUTHME_BASE)
.labels("setfirstspawn", "chgfirstspawn")
.description("Change the first spawn")
.detailedDescription("Change the first player's spawn to your current position.")
.permissions(OP_ONLY, AdminPermission.SET_FIRST_SPAWN)
.build();
// Register the purge command
CommandDescription.builder()
.executableCommand(new PurgeCommand())
.parent(AUTHME_BASE)
.labels("purge", "delete")
.description("Purge old data")
.detailedDescription("Purge old AuthMeReloaded data longer than the specified amount of days ago.")
.permissions(OP_ONLY, AdminPermission.PURGE)
.withArgument("days", "Number of days", false)
.build();
// Register the purgelastposition command
CommandDescription.builder()
.executableCommand(new PurgeLastPositionCommand())
.parent(AUTHME_BASE)
.labels("resetpos", "purgelastposition", "purgelastpos", "resetposition",
"resetlastposition", "resetlastpos")
.description("Purge player's last position")
.detailedDescription("Purge the last know position of the specified player.")
.permissions(OP_ONLY, AdminPermission.PURGE_LAST_POSITION)
.withArgument("player", "Player name", false)
.build();
// Register the purgebannedplayers command
CommandDescription.builder()
.executableCommand(new PurgeBannedPlayersCommand())
.parent(AUTHME_BASE)
.labels("purgebannedplayers", "purgebannedplayer", "deletebannedplayers", "deletebannedplayer")
.description("Purge banned players data")
.detailedDescription("Purge all AuthMeReloaded data for banned players.")
.permissions(OP_ONLY, AdminPermission.PURGE_BANNED_PLAYERS)
.build();
// Register the switchantibot command
CommandDescription.builder()
.executableCommand(new SwitchAntiBotCommand())
.parent(AUTHME_BASE)
.labels("switchantibot", "toggleantibot", "antibot")
.description("Switch AntiBot mode")
.detailedDescription("Switch or toggle the AntiBot mode to the specified state.")
.permissions(OP_ONLY, AdminPermission.SWITCH_ANTIBOT)
.withArgument("mode", "ON / OFF", true)
.build();
// Register the reload command
CommandDescription.builder()
.executableCommand(new ReloadCommand())
.parent(AUTHME_BASE)
.labels("reload", "rld")
.description("Reload plugin")
.detailedDescription("Reload the AuthMeReloaded plugin.")
.permissions(OP_ONLY, AdminPermission.RELOAD)
.build();
// Register the version command
CommandDescription.builder()
.parent(AUTHME_BASE)
.labels("version", "ver", "v", "about", "info")
.description("Version info")
.detailedDescription("Show detailed information about the installed AuthMeReloaded version, and shows the "
+ "developers, contributors, license and other information.")
.executableCommand(new VersionCommand())
.build();
// Register the base login command
final CommandDescription LOGIN_BASE = CommandDescription.builder()
.executableCommand(new LoginCommand())
.labels("login", "l")
.description("Login command")
.detailedDescription("Command to log in using AuthMeReloaded.")
.parent(null)
.permissions(ALLOWED, PlayerPermission.LOGIN)
.withArgument("password", "Login password", false)
.build();
// Register the help command
CommandDescription.builder()
.executableCommand(helpCommandExecutable)
.parent(LOGIN_BASE)
.labels(helpCommandLabels)
.description("View Help")
.detailedDescription("View detailed help pages about AuthMeReloaded login commands.")
.withArgument("query", "The command or query to view help for.", true)
.build();
// Register the base logout command
CommandDescription LOGOUT_BASE = CommandDescription.builder()
.executableCommand(new LogoutCommand())
.parent(null)
.labels("logout")
.description("Logout command")
.detailedDescription("Command to logout using AuthMeReloaded.")
.permissions(ALLOWED, PlayerPermission.LOGOUT)
.build();
// Register the help command
CommandDescription.builder()
.executableCommand(helpCommandExecutable)
.parent(LOGOUT_BASE)
.labels(helpCommandLabels)
.description("View help")
.detailedDescription("View detailed help pages about AuthMeReloaded logout commands.")
.withArgument("query", "The command or query to view help for.", true)
.build();
// Register the base register command
final CommandDescription REGISTER_BASE = CommandDescription.builder()
.parent(null)
.labels("register", "reg")
.description("Registration command")
.detailedDescription("Command to register using AuthMeReloaded.")
.withArgument("password", "Password", false)
.withArgument("verifyPassword", "Verify password", false)
.permissions(ALLOWED, PlayerPermission.REGISTER)
.executableCommand(new RegisterCommand())
.build();
// Register the help command
CommandDescription.builder()
.executableCommand(helpCommandExecutable)
.parent(REGISTER_BASE)
.labels(helpCommandLabels)
.description("View help")
.detailedDescription("View detailed help pages about AuthMeReloaded register commands.")
.withArgument("query", "The command or query to view help for.", true)
.build();
// Register the base unregister command
CommandDescription UNREGISTER_BASE = CommandDescription.builder()
.executableCommand(new UnregisterCommand())
.parent(null)
.labels("unreg", "unregister")
.description("Unregistration Command")
.detailedDescription("Command to unregister using AuthMeReloaded.")
.permissions(ALLOWED, PlayerPermission.UNREGISTER)
.withArgument("password", "Password", false)
.build();
// Register the help command
CommandDescription.builder()
.executableCommand(helpCommandExecutable)
.parent(UNREGISTER_BASE)
.labels(helpCommandLabels)
.description("View help")
.detailedDescription("View detailed help pages about AuthMeReloaded unregister commands.")
.withArgument("query", "The command or query to view help for.", true)
.build();
// Register the base changepassword command
final CommandDescription CHANGE_PASSWORD_BASE = CommandDescription.builder()
.executableCommand(new ChangePasswordCommand())
.parent(null)
.labels("changepassword", "changepass", "cp")
.description("Change password Command")
.detailedDescription("Command to change your password using AuthMeReloaded.")
.permissions(ALLOWED, PlayerPermission.CHANGE_PASSWORD)
.withArgument("password", "Password", false)
.withArgument("verifyPassword", "Verify password.", false)
.build();
// Register the help command
CommandDescription.builder()
.executableCommand(helpCommandExecutable)
.parent(CHANGE_PASSWORD_BASE)
.labels(helpCommandLabels)
.description("View help")
.detailedDescription("View detailed help pages about AuthMeReloaded changepassword commands.")
.withArgument("query", "The command or query to view help for.", true)
.build();
// Register the base Email command
CommandDescription EMAIL_BASE = CommandDescription.builder()
.executableCommand(helpCommandExecutable)
.parent(null)
.labels("email", "mail")
.description("Email command")
.detailedDescription("The AuthMeReloaded Email command base.")
.build();
// Register the help command
CommandDescription.builder()
.executableCommand(helpCommandExecutable)
.parent(EMAIL_BASE)
.labels(helpCommandLabels)
.description("View help")
.detailedDescription("View detailed help pages about AuthMeReloaded email commands.")
.withArgument("query", "The command or query to view help for.", true)
.build();
// Register the add command
CommandDescription.builder()
.executableCommand(new AddEmailCommand())
.parent(EMAIL_BASE)
.labels("add", "addemail", "addmail")
.description("Add Email")
.detailedDescription("Add a new email address to your account.")
.permissions(ALLOWED, PlayerPermission.ADD_EMAIL)
.withArgument("email", "Email address", false)
.withArgument("verifyEmail", "Email address verification", false)
.build();
// Register the change command
CommandDescription.builder()
.executableCommand(new ChangeEmailCommand())
.parent(EMAIL_BASE)
.labels("change", "changeemail", "changemail")
.description("Change Email")
.detailedDescription("Change an email address of your account.")
.permissions(ALLOWED, PlayerPermission.CHANGE_EMAIL)
.withArgument("oldEmail", "Old email address", false)
.withArgument("newEmail", "New email address", false)
.build();
// Register the recover command
CommandDescription.builder()
.executableCommand(new RecoverEmailCommand())
.parent(EMAIL_BASE)
.labels("recover", "recovery", "recoveremail", "recovermail")
.description("Recover password using Email")
.detailedDescription("Recover your account using an Email address by sending a mail containing " +
"a new password.")
.permissions(ALLOWED, PlayerPermission.RECOVER_EMAIL)
.withArgument("email", "Email address", false)
.build();
// Register the base captcha command
CommandDescription CAPTCHA_BASE = CommandDescription.builder()
.executableCommand(new CaptchaCommand())
.parent(null)
.labels("captcha", "capt")
.description("Captcha Command")
.detailedDescription("Captcha command for AuthMeReloaded.")
.permissions(ALLOWED, PlayerPermission.CAPTCHA)
.withArgument("captcha", "The Captcha", false)
.build();
// Register the help command
CommandDescription.builder()
.executableCommand(helpCommandExecutable)
.parent(CAPTCHA_BASE)
.labels(helpCommandLabels)
.description("View help")
.detailedDescription("View detailed help pages about AuthMeReloaded captcha commands.")
.withArgument("query", "The command or query to view help for.", true)
.build();
// Register the base converter command
CommandDescription CONVERTER_BASE = CommandDescription.builder()
.executableCommand(new ConverterCommand())
.parent(null)
.labels("converter", "convert", "conv")
.description("Converter Command")
.detailedDescription("Converter command for AuthMeReloaded.")
.permissions(OP_ONLY, AdminPermission.CONVERTER)
.withArgument("job", "Conversion job: flattosql / flattosqlite /| xauth / crazylogin / rakamak / " +
"royalauth / vauth / sqltoflat", false)
.build();
// Register the help command
CommandDescription.builder()
.executableCommand(helpCommandExecutable)
.parent(CONVERTER_BASE)
.labels(helpCommandLabels)
.description("View help")
.detailedDescription("View detailed help pages about AuthMeReloaded converter commands.")
.withArgument("query", "The command or query to view help for.", true)
.build();
// Add the base commands to the commands array
baseCommands = new HashSet<>(Arrays.asList(
AUTHME_BASE,
LOGIN_BASE,
LOGOUT_BASE,
REGISTER_BASE,
UNREGISTER_BASE,
CHANGE_PASSWORD_BASE,
EMAIL_BASE,
CAPTCHA_BASE,
CONVERTER_BASE));
}
}

View File

@ -1,519 +0,0 @@
package fr.xephi.authme.command;
import fr.xephi.authme.command.executable.HelpCommand;
import fr.xephi.authme.command.executable.authme.*;
import fr.xephi.authme.command.executable.captcha.CaptchaCommand;
import fr.xephi.authme.command.executable.converter.ConverterCommand;
import fr.xephi.authme.command.executable.email.AddEmailCommand;
import fr.xephi.authme.command.executable.email.ChangeEmailCommand;
import fr.xephi.authme.command.executable.email.RecoverEmailCommand;
import fr.xephi.authme.command.executable.login.LoginCommand;
import fr.xephi.authme.command.executable.logout.LogoutCommand;
import fr.xephi.authme.permission.AdminPermission;
import fr.xephi.authme.permission.UserPermission;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static fr.xephi.authme.command.CommandPermissions.DefaultPermission.ALLOWED;
import static fr.xephi.authme.command.CommandPermissions.DefaultPermission.OP_ONLY;
/**
*/
public class CommandManager {
/**
* The list of commandDescriptions.
*/
private final List<CommandDescription> commandDescriptions = new ArrayList<>();
/**
* Constructor.
*
* @param registerCommands True to register the commands, false otherwise.
*/
public CommandManager(boolean registerCommands) {
// Register the commands
if (registerCommands)
registerCommands();
}
/**
* Register all commands.
*/
public void registerCommands() {
// Create a list of help command labels
final List<String> helpCommandLabels = Arrays.asList("help", "hlp", "h", "sos", "?");
ExecutableCommand helpCommandExecutable = new HelpCommand();
// Register the base AuthMe Reloaded command
CommandDescription authMeBaseCommand = CommandDescription.builder()
.executableCommand(new AuthMeCommand())
.labels("authme")
.description("Main command")
.detailedDescription("The main AuthMeReloaded command. The root for all admin commands.")
.parent(null)
.build();
// Register the help command
CommandDescription authMeHelpCommand = CommandDescription.builder()
.executableCommand(helpCommandExecutable)
.labels(helpCommandLabels)
.description("View help")
.detailedDescription("View detailed help pages about AuthMeReloaded commands.")
.parent(authMeBaseCommand)
.withArgument("query", "The command or query to view help for.", true)
.build();
// Register the register command
CommandDescription registerCommand = CommandDescription.builder()
.executableCommand(new RegisterCommand())
.labels("register", "reg", "r")
.description("Register a player")
.detailedDescription("Register the specified player with the specified password.")
.parent(authMeBaseCommand)
.permissions(OP_ONLY, UserPermission.REGISTER)
.withArgument("player", "Player name", false)
.withArgument("password", "Password", false)
.build();
// Register the unregister command
CommandDescription unregisterCommand = CommandDescription.builder()
.executableCommand(new UnregisterCommand())
.labels("unregister", "unreg", "unr")
.description("Unregister a player")
.detailedDescription("Unregister the specified player.")
.parent(authMeBaseCommand)
.permissions(OP_ONLY, UserPermission.UNREGISTER)
.withArgument("player", "Player name", false)
.build();
// Register the forcelogin command
CommandDescription forceLoginCommand = CommandDescription.builder()
.executableCommand(new ForceLoginCommand())
.labels("forcelogin", "login")
.description("Enforce login player")
.detailedDescription("Enforce the specified player to login.")
.parent(authMeBaseCommand)
.permissions(OP_ONLY, UserPermission.CAN_LOGIN_BE_FORCED)
.withArgument("player", "Online player name", true)
.build();
// Register the changepassword command
CommandDescription changePasswordCommand = CommandDescription.builder()
.executableCommand(new ChangePasswordCommand())
.labels("password", "changepassword", "changepass", "cp")
.description("Change a player's password")
.detailedDescription("Change the password of a player.")
.parent(authMeBaseCommand)
.permissions(OP_ONLY, UserPermission.CHANGE_PASSWORD)
.withArgument("player", "Player name", false)
.withArgument("pwd", "New password", false)
.build();
// Register the last login command
CommandDescription lastLoginCommand = CommandDescription.builder()
.executableCommand(new LastLoginCommand())
.labels("lastlogin", "ll")
.description("Player's last login")
.detailedDescription("View the date of the specified players last login.")
.parent(authMeBaseCommand)
.permissions(OP_ONLY, AdminPermission.LAST_LOGIN)
.withArgument("player", "Player name", true)
.build();
// Register the accounts command
CommandDescription accountsCommand = CommandDescription.builder()
.executableCommand(new AccountsCommand())
.labels("accounts", "account")
.description("Display player accounts")
.detailedDescription("Display all accounts of a player by his player name or IP.")
.parent(authMeBaseCommand)
.permissions(OP_ONLY, AdminPermission.ACCOUNTS)
.withArgument("player", "Player name or IP", true)
.build();
// Register the getemail command
CommandDescription getEmailCommand = new CommandDescription(new GetEmailCommand(), new ArrayList<String>() {
{
add("getemail");
add("getmail");
add("email");
add("mail");
}
}, "Display player's email", "Display the email address of the specified player if set.", authMeBaseCommand);
getEmailCommand.setCommandPermissions(AdminPermission.GET_EMAIL, OP_ONLY);
getEmailCommand.addArgument(new CommandArgumentDescription("player", "Player name", true));
// Register the setemail command
CommandDescription setEmailCommand = new CommandDescription(new SetEmailCommand(), new ArrayList<String>() {
{
add("chgemail");
add("chgmail");
add("setemail");
add("setmail");
}
}, "Change player's email", "Change the email address of the specified player.", authMeBaseCommand);
setEmailCommand.setCommandPermissions(AdminPermission.CHANGE_EMAIL, OP_ONLY);
setEmailCommand.addArgument(new CommandArgumentDescription("player", "Player name", false));
setEmailCommand.addArgument(new CommandArgumentDescription("email", "Player email", false));
// Register the getip command
CommandDescription getIpCommand = new CommandDescription(new GetIpCommand(), new ArrayList<String>() {
{
add("getip");
add("ip");
}
}, "Get player's IP", "Get the IP address of the specified online player.", authMeBaseCommand);
getIpCommand.setCommandPermissions(AdminPermission.GET_IP, OP_ONLY);
getIpCommand.addArgument(new CommandArgumentDescription("player", "Online player name", true));
// Register the spawn command
CommandDescription spawnCommand = new CommandDescription(new SpawnCommand(), new ArrayList<String>() {
{
add("spawn");
add("home");
}
}, "Teleport to spawn", "Teleport to the spawn.", authMeBaseCommand);
spawnCommand.setCommandPermissions(AdminPermission.SPAWN, OP_ONLY);
// Register the setspawn command
CommandDescription setSpawnCommand = new CommandDescription(new SetSpawnCommand(), new ArrayList<String>() {
{
add("setspawn");
add("chgspawn");
}
}, "Change the spawn", "Change the player's spawn to your current position.", authMeBaseCommand);
setSpawnCommand.setCommandPermissions(AdminPermission.SET_SPAWN, OP_ONLY);
// Register the firstspawn command
CommandDescription firstSpawnCommand = new CommandDescription(new FirstSpawnCommand(), new ArrayList<String>() {
{
add("firstspawn");
add("firsthome");
}
}, "Teleport to first spawn", "Teleport to the first spawn.", authMeBaseCommand);
firstSpawnCommand.setCommandPermissions(AdminPermission.FIRST_SPAWN, OP_ONLY);
// Register the setfirstspawn command
CommandDescription setFirstSpawnCommand = new CommandDescription(new SetFirstSpawnCommand(), new ArrayList<String>() {
{
add("setfirstspawn");
add("chgfirstspawn");
}
}, "Change the first spawn", "Change the first player's spawn to your current position.", authMeBaseCommand);
setFirstSpawnCommand.setCommandPermissions(AdminPermission.SET_FIRST_SPAWN, OP_ONLY);
// Register the purge command
CommandDescription purgeCommand = new CommandDescription(new PurgeCommand(), new ArrayList<String>() {
{
add("purge");
add("delete");
}
}, "Purge old data", "Purge old AuthMeReloaded data longer than the specified amount of days ago.", authMeBaseCommand);
purgeCommand.setCommandPermissions(AdminPermission.PURGE, OP_ONLY);
purgeCommand.addArgument(new CommandArgumentDescription("days", "Number of days", false));
// Register the purgelastposition command
CommandDescription purgeLastPositionCommand = new CommandDescription(new PurgeLastPositionCommand(), new ArrayList<String>() {
{
add("resetpos");
add("purgelastposition");
add("purgelastpos");
add("resetposition");
add("resetlastposition");
add("resetlastpos");
}
}, "Purge player's last position", "Purge the last know position of the specified player.", authMeBaseCommand);
purgeLastPositionCommand.setCommandPermissions(AdminPermission.PURGE_LAST_POSITION, OP_ONLY);
purgeLastPositionCommand.addArgument(new CommandArgumentDescription("player", "Player name", true));
// Register the purgebannedplayers command
CommandDescription purgeBannedPlayersCommand = new CommandDescription(new PurgeBannedPlayersCommand(), new ArrayList<String>() {
{
add("purgebannedplayers");
add("purgebannedplayer");
add("deletebannedplayers");
add("deletebannedplayer");
}
}, "Purge banned palyers data", "Purge all AuthMeReloaded data for banned players.", authMeBaseCommand);
purgeBannedPlayersCommand.setCommandPermissions(AdminPermission.PURGE_BANNED_PLAYERS, OP_ONLY);
// Register the switchantibot command
CommandDescription switchAntiBotCommand = new CommandDescription(new SwitchAntiBotCommand(), new ArrayList<String>() {
{
add("switchantibot");
add("toggleantibot");
add("antibot");
}
}, "Switch AntiBot mode", "Switch or toggle the AntiBot mode to the specified state.", authMeBaseCommand);
switchAntiBotCommand.setCommandPermissions(AdminPermission.SWITCH_ANTIBOT, OP_ONLY);
switchAntiBotCommand.addArgument(new CommandArgumentDescription("mode", "ON / OFF", true));
// // Register the resetname command
// CommandDescription resetNameCommand = new CommandDescription(
// new ResetNameCommand(),
// new ArrayList<String>() {{
// add("resetname");
// add("resetnames");
// }},
// "Reset name",
// "Reset name",
// authMeCommand);
// resetNameCommand.setCommandPermissions("authme.admin.resetname",
// CommandPermissions.DefaultPermission.OP_ONLY);
// Register the reload command
CommandDescription reloadCommand = new CommandDescription(new ReloadCommand(), new ArrayList<String>() {
{
add("reload");
add("rld");
}
}, "Reload plugin", "Reload the AuthMeReloaded plugin.", authMeBaseCommand);
reloadCommand.setCommandPermissions(AdminPermission.RELOAD, OP_ONLY);
// Register the version command
CommandDescription versionCommand = CommandDescription.builder()
.executableCommand(new VersionCommand())
.labels("version", "ver", "v", "about", "info")
.description("Version info")
.detailedDescription("Show detailed information about the installed AuthMeReloaded version, and shows the "
+ "developers, contributors, license and other information.")
.parent(authMeBaseCommand)
.build();
// Register the base login command
CommandDescription loginBaseCommand = CommandDescription.builder()
.executableCommand(new LoginCommand())
.labels("login", "l")
.description("Login command")
.detailedDescription("Command to log in using AuthMeReloaded.")
.parent(null)
.permissions(ALLOWED, UserPermission.LOGIN)
.withArgument("password", "Login password", false)
.build();
// Register the help command
CommandDescription loginHelpCommand = new CommandDescription(helpCommandExecutable, helpCommandLabels,
"View help", "View detailed help pages about AuthMeReloaded login commands.", loginBaseCommand);
loginHelpCommand.addArgument(new CommandArgumentDescription("query", "The command or query to view help for.", true));
// Register the base logout command
CommandDescription logoutBaseCommand = new CommandDescription(new LogoutCommand(), new ArrayList<String>() {
{
add("logout");
}
}, "Logout command", "Command to logout using AuthMeReloaded.", null);
logoutBaseCommand.setCommandPermissions(UserPermission.LOGOUT, CommandPermissions.DefaultPermission.ALLOWED);
// Register the help command
CommandDescription logoutHelpCommand = new CommandDescription(helpCommandExecutable, helpCommandLabels,
"View help", "View detailed help pages about AuthMeReloaded logout commands.", logoutBaseCommand);
logoutHelpCommand.addArgument(new CommandArgumentDescription("query", "The command or query to view help for.", true));
// Register the base register command
CommandDescription registerBaseCommand = new CommandDescription(new fr.xephi.authme.command.executable.register.RegisterCommand(), new ArrayList<String>() {
{
add("register");
add("reg");
}
}, "Registration command", "Command to register using AuthMeReloaded.", null);
registerBaseCommand.setCommandPermissions(UserPermission.REGISTER, CommandPermissions.DefaultPermission.ALLOWED);
registerBaseCommand.addArgument(new CommandArgumentDescription("password", "Password", false));
registerBaseCommand.addArgument(new CommandArgumentDescription("verifyPassword", "Verify password", false));
// Register the help command
CommandDescription registerHelpCommand = new CommandDescription(helpCommandExecutable, helpCommandLabels,
"View help", "View detailed help pages about AuthMeReloaded register commands.", registerBaseCommand);
registerHelpCommand.addArgument(new CommandArgumentDescription("query", "The command or query to view help for.", true));
// Register the base unregister command
CommandDescription unregisterBaseCommand = new CommandDescription(new fr.xephi.authme.command.executable.unregister.UnregisterCommand(), new ArrayList<String>() {
{
add("unregister");
add("unreg");
}
}, "Unregistration command", "Command to unregister using AuthMeReloaded.", null);
unregisterBaseCommand.setCommandPermissions(UserPermission.UNREGISTER, CommandPermissions.DefaultPermission.ALLOWED);
unregisterBaseCommand.addArgument(new CommandArgumentDescription("password", "Password", false));
// Register the help command
CommandDescription unregisterHelpCommand = new CommandDescription(helpCommandExecutable, helpCommandLabels, "View help", "View detailed help pages about AuthMeReloaded unregister commands.", unregisterBaseCommand);
unregisterHelpCommand.addArgument(new CommandArgumentDescription("query", "The command or query to view help for.", true));
// Register the base changepassword command
CommandDescription changePasswordBaseCommand = new CommandDescription(new fr.xephi.authme.command.executable.changepassword.ChangePasswordCommand(), new ArrayList<String>() {
{
add("changepassword");
add("changepass");
}
}, "Change password command", "Command to change your password using AuthMeReloaded.", null);
changePasswordBaseCommand.setCommandPermissions(UserPermission.CHANGE_PASSWORD, CommandPermissions.DefaultPermission.ALLOWED);
changePasswordBaseCommand.addArgument(new CommandArgumentDescription("password", "Password", false));
changePasswordBaseCommand.addArgument(new CommandArgumentDescription("verifyPassword", "Verify password", false));
// Register the help command
CommandDescription changePasswordHelpCommand = new CommandDescription(helpCommandExecutable, helpCommandLabels,
"View help", "View detailed help pages about AuthMeReloaded change password commands.", changePasswordBaseCommand);
changePasswordHelpCommand.addArgument(new CommandArgumentDescription("query", "The command or query to view help for.", true));
// Register the base Dungeon Maze command
CommandDescription emailBaseCommand = new CommandDescription(helpCommandExecutable, new ArrayList<String>() {
{
add("email");
add("mail");
}
}, "E-mail command", "The AuthMe Reloaded E-mail command. The root for all E-mail commands.", null);
// Register the help command
CommandDescription emailHelpCommand = new CommandDescription(helpCommandExecutable, helpCommandLabels,
"View help", "View detailed help pages about AuthMeReloaded help commands.", emailBaseCommand);
emailHelpCommand.addArgument(new CommandArgumentDescription("query", "The command or query to view help for.", true));
// Register the add command
CommandDescription addEmailCommand = new CommandDescription(new AddEmailCommand(), new ArrayList<String>() {
{
add("add");
add("addemail");
add("addmail");
}
}, "Add E-mail", "Add an new E-Mail address to your account.", emailBaseCommand);
addEmailCommand.setCommandPermissions(UserPermission.ADD_EMAIL, CommandPermissions.DefaultPermission.ALLOWED);
addEmailCommand.addArgument(new CommandArgumentDescription("email", "Email address", false));
addEmailCommand.addArgument(new CommandArgumentDescription("verifyEmail", "Email address verification", false));
// Register the change command
CommandDescription changeEmailCommand = new CommandDescription(new ChangeEmailCommand(), new ArrayList<String>() {
{
add("change");
add("changeemail");
add("changemail");
}
}, "Change E-mail", "Change an E-Mail address of your account.", emailBaseCommand);
changeEmailCommand.setCommandPermissions(UserPermission.CHANGE_EMAIL, CommandPermissions.DefaultPermission.ALLOWED);
changeEmailCommand.addArgument(new CommandArgumentDescription("oldEmail", "Old email address", false));
changeEmailCommand.addArgument(new CommandArgumentDescription("newEmail", "New email address", false));
// Register the recover command
CommandDescription recoverEmailCommand = new CommandDescription(new RecoverEmailCommand(), new ArrayList<String>() {
{
add("recover");
add("recovery");
add("recoveremail");
add("recovermail");
}
}, "Recover using E-mail", "Recover your account using an E-mail address.", emailBaseCommand);
recoverEmailCommand.setCommandPermissions(UserPermission.RECOVER_EMAIL, CommandPermissions.DefaultPermission.ALLOWED);
recoverEmailCommand.addArgument(new CommandArgumentDescription("email", "Email address", false));
// Register the base captcha command
CommandDescription captchaBaseCommand = new CommandDescription(new CaptchaCommand(), new ArrayList<String>() {
{
add("captcha");
add("capt");
}
}, "Captcha command", "Captcha command for AuthMeReloaded.", null);
captchaBaseCommand.setCommandPermissions(UserPermission.CAPTCHA, CommandPermissions.DefaultPermission.ALLOWED);
captchaBaseCommand.addArgument(new CommandArgumentDescription("captcha", "The captcha", false));
// Register the help command
CommandDescription captchaHelpCommand = new CommandDescription(helpCommandExecutable, helpCommandLabels,
"View help", "View detailed help pages about AuthMeReloaded change captcha commands.", captchaBaseCommand);
captchaHelpCommand.addArgument(new CommandArgumentDescription("query", "The command or query to view help for.", true));
// Register the base converter command
CommandDescription converterBaseCommand = new CommandDescription(new ConverterCommand(), new ArrayList<String>() {
{
add("converter");
add("convert");
add("conv");
}
}, "Convert command", "Convert command for AuthMeReloaded.", null);
converterBaseCommand.setCommandPermissions(UserPermission.CONVERTER, OP_ONLY);
converterBaseCommand.addArgument(new CommandArgumentDescription("job", "Conversion job: flattosql / flattosqlite /| xauth / crazylogin / rakamak / royalauth / vauth / sqltoflat", false));
// Register the help command
CommandDescription converterHelpCommand = new CommandDescription(helpCommandExecutable, helpCommandLabels,
"View help", "View detailed help pages about AuthMeReloaded change captcha commands.", converterBaseCommand);
converterHelpCommand.addArgument(new CommandArgumentDescription("query", "The command or query to view help for.", true));
// Add the base commands to the commands array
this.commandDescriptions.add(authMeBaseCommand);
this.commandDescriptions.add(loginBaseCommand);
this.commandDescriptions.add(logoutBaseCommand);
this.commandDescriptions.add(registerBaseCommand);
this.commandDescriptions.add(unregisterBaseCommand);
this.commandDescriptions.add(changePasswordBaseCommand);
this.commandDescriptions.add(emailBaseCommand);
this.commandDescriptions.add(captchaBaseCommand);
this.commandDescriptions.add(converterBaseCommand);
}
/**
* Get the list of command descriptions
*
* @return List of command descriptions.
*/
public List<CommandDescription> getCommandDescriptions() {
return this.commandDescriptions;
}
/**
* Get the number of command description count.
*
* @return Command description count.
*/
public int getCommandDescriptionCount() {
return this.getCommandDescriptions().size();
}
/**
* Find the best suitable command for the specified reference.
*
* @param queryReference The query reference to find a command for.
*
* @return The command found, or null.
*/
public FoundCommandResult findCommand(CommandParts queryReference) {
// Make sure the command reference is valid
if (queryReference.getCount() <= 0)
return null;
// Get the base command description
for (CommandDescription commandDescription : this.commandDescriptions) {
// Check whether there's a command description available for the
// current command
if (!commandDescription.isSuitableLabel(queryReference))
continue;
// Find the command reference, return the result
return commandDescription.findCommand(queryReference);
}
// No applicable command description found, return false
return null;
}
}

View File

@ -14,12 +14,6 @@ public class CommandParts {
*/
private final List<String> parts = new ArrayList<>();
/**
* Constructor.
*/
public CommandParts() {
}
/**
* Constructor.
*
@ -29,15 +23,6 @@ public class CommandParts {
this.parts.add(part);
}
/**
* Constructor.
*
* @param commandParts The command parts instance.
*/
public CommandParts(CommandParts commandParts) {
this.parts.addAll(commandParts.getList());
}
/**
* Constructor.
*
@ -47,17 +32,6 @@ public class CommandParts {
this.parts.addAll(parts);
}
/**
* Constructor.
*
* @param base The base part.
* @param parts The list of additional parts.
*/
public CommandParts(String base, List<String> parts) {
this.parts.add(base);
this.parts.addAll(parts);
}
/**
* Get the command parts.
*
@ -67,41 +41,6 @@ public class CommandParts {
return this.parts;
}
/**
* Add a part.
*
* @param part The part to add.
*
* @return The result.
*/
public boolean add(String part) {
return this.parts.add(part);
}
/**
* Add some parts.
*
* @param parts The parts to add.
*
* @return The result.
*/
public boolean add(List<String> parts) {
return this.parts.addAll(parts);
}
/**
* Add some parts.
*
* @param parts The parts to add.
*
* @return The result.
*/
public boolean add(String[] parts) {
for (String entry : parts)
add(entry);
return true;
}
/**
* Get the number of parts.
*
@ -112,7 +51,7 @@ public class CommandParts {
}
/**
* Get a part by it's index.
* Get a part by its index.
*
* @param i Part index.
*
@ -127,74 +66,6 @@ public class CommandParts {
return this.parts.get(i);
}
/**
* Get a range of the parts starting at the specified index up to the end of the range.
*
* @param start The starting index.
*
* @return The parts range. Arguments that were out of bound are not included.
*/
public List<String> getRange(int start) {
return getRange(start, getCount() - start);
}
/**
* Get a range of the parts.
*
* @param start The starting index.
* @param count The number of parts to get.
*
* @return The parts range. Parts that were out of bound are not included.
*/
public List<String> getRange(int start, int count) {
// Create a new list to put the range into
List<String> elements = new ArrayList<>();
// Get the range
for (int i = start; i < start + count; i++) {
// Get the part and add it if it's valid
String element = get(i);
if (element != null)
elements.add(element);
}
// Return the list of parts
return elements;
}
/**
* Get the difference value between two references. This won't do a full compare, just the last reference parts instead.
*
* @param other The other reference.
*
* @return The result from zero to above. A negative number will be returned on error.
*/
public double getDifference(CommandParts other) {
return getDifference(other, false);
}
/**
* Get the difference value between two references.
*
* @param other The other reference.
* @param fullCompare True to compare the full references as far as the range reaches.
*
* @return The result from zero to above. A negative number will be returned on error.
*/
public double getDifference(CommandParts other, boolean fullCompare) {
// Make sure the other reference is correct
if (other == null)
return -1;
// Get the range to use
int range = Math.min(this.getCount(), other.getCount());
// Get and the difference
if (fullCompare)
return StringUtils.getDifference(this.toString(), other.toString());
return StringUtils.getDifference(this.getRange(range - 1, 1).toString(), other.getRange(range - 1, 1).toString());
}
/**
* Convert the parts to a string.
*

View File

@ -1,12 +1,12 @@
package fr.xephi.authme.command;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.permission.DefaultPermission;
import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.permission.PermissionNode;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
/**
@ -22,18 +22,6 @@ public class CommandPermissions {
*/
private DefaultPermission defaultPermission;
/**
* Constructor.
*
* @param permissionNode The permission node required to execute a command.
* @param defaultPermission The default permission if the permission nodes couldn't be used.
*/
public CommandPermissions(PermissionNode permissionNode, DefaultPermission defaultPermission) {
this.permissionNodes = new ArrayList<>();
this.permissionNodes.add(permissionNode);
this.defaultPermission = defaultPermission;
}
/**
* Constructor.
*
@ -54,16 +42,6 @@ public class CommandPermissions {
return this.permissionNodes;
}
/**
* Get the number of permission nodes set.
*
* @return Permission node count.
*/
public int getPermissionNodeCount() {
return this.permissionNodes.size();
}
/**
* Check whether this command requires any permission to be executed. This is based on the getPermission() method.
*
@ -73,31 +51,28 @@ public class CommandPermissions {
*/
public boolean hasPermission(CommandSender sender) {
// Make sure any permission node is set
if (getPermissionNodeCount() == 0)
if (permissionNodes.isEmpty()) {
return true;
}
// Get the default permission
PermissionsManager permissionsManager = AuthMe.getInstance().getPermissionsManager();
final boolean defaultPermission = getDefaultPermissionCommandSender(sender);
// Make sure the command sender is a player, if not use the default
if (!(sender instanceof Player))
if (!(sender instanceof Player)) {
return defaultPermission;
}
// Get the player instance
Player player = (Player) sender;
// Get the permissions manager, and make sure it's instance is valid
PermissionsManager permissionsManager = AuthMe.getInstance().getPermissionsManager();
if (permissionsManager == null)
return false;
// Check whether the player has permission, return the result
for (PermissionNode node : this.permissionNodes) {
if (!permissionsManager.hasPermission(player, node, defaultPermission)) {
return false;
}
}
return true;
return permissionsManager.hasPermission(player, this.permissionNodes, defaultPermission);
}
/**
@ -109,14 +84,6 @@ public class CommandPermissions {
return this.defaultPermission;
}
/**
* Set the default permission used if the permission nodes couldn't be used.
*
* @param defaultPermission The default permission.
*/
public void setDefaultPermission(DefaultPermission defaultPermission) {
this.defaultPermission = defaultPermission;
}
/**
* Get the default permission for a specified command sender.
@ -138,12 +105,4 @@ public class CommandPermissions {
return false;
}
}
/**
*/
public enum DefaultPermission {
NOT_ALLOWED,
OP_ONLY,
ALLOWED
}
}

View File

@ -0,0 +1,57 @@
package fr.xephi.authme.command;
import java.util.List;
import fr.xephi.authme.util.CollectionUtils;
import fr.xephi.authme.util.StringUtils;
public final class CommandUtils {
public static int getMinNumberOfArguments(CommandDescription command) {
int mandatoryArguments = 0;
for (CommandArgumentDescription argument : command.getArguments()) {
if (!argument.isOptional()) {
++mandatoryArguments;
}
}
return mandatoryArguments;
}
public static int getMaxNumberOfArguments(CommandDescription command) {
return command.getArguments().size();
}
/**
* Provide a textual representation of a list of labels to show it as a command. For example, a list containing
* the items ["authme", "register", "player"] it will return "authme register player".
*
* @param labels The labels to format
* @return The space-separated labels
*/
public static String labelsToString(Iterable<String> labels) {
return StringUtils.join(" ", labels);
}
public static double getDifference(List<String> labels1, List<String> labels2, boolean fullCompare) {
// Make sure the other reference is correct
if (labels1 == null || labels2 == null) {
return -1;
}
// Get the range to use
int range = Math.min(labels1.size(), labels2.size());
// Get and the difference
if (fullCompare) {
return StringUtils.getDifference(CommandUtils.labelsToString(labels1), CommandUtils.labelsToString(labels2));
}
return StringUtils.getDifference(
labelsToString(CollectionUtils.getRange(labels1, range - 1, 1)),
labelsToString(CollectionUtils.getRange(labels2, range - 1, 1)));
}
}

View File

@ -61,27 +61,13 @@ public class FoundCommandResult {
return this.commandDescription;
}
/**
* Set the command description.
*
* @param commandDescription The command description.
*/
public void setCommandDescription(CommandDescription commandDescription) {
this.commandDescription = commandDescription;
}
/**
* Check whether the command is executable.
*
* @return True if the command is executable, false otherwise.
*/
public boolean isExecutable() {
// Make sure the command description is valid
if (this.commandDescription == null)
return false;
// Check whether the command is executable, return the result
return this.commandDescription.isExecutable();
return commandDescription != null;
}
/**
@ -153,10 +139,11 @@ public class FoundCommandResult {
*/
public double getDifference() {
// Get the difference through the command found
if (this.commandDescription != null)
if (this.commandDescription != null) {
return this.commandDescription.getCommandDifference(this.queryReference);
}
// Get the difference from the query reference
return this.queryReference.getDifference(commandReference, true);
return CommandUtils.getDifference(queryReference.getList(), commandReference.getList(), true);
}
}

View File

@ -5,8 +5,8 @@ import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.settings.MessageKey;
import fr.xephi.authme.settings.Messages;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;

View File

@ -7,8 +7,8 @@ import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.security.PasswordSecurity;
import fr.xephi.authme.settings.MessageKey;
import fr.xephi.authme.settings.Messages;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages;
import fr.xephi.authme.settings.Settings;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
@ -16,8 +16,9 @@ import org.bukkit.command.CommandSender;
import java.security.NoSuchAlgorithmException;
/**
* Admin command for changing a player's password.
*/
public class ChangePasswordCommand extends ExecutableCommand {
public class ChangePasswordAdminCommand extends ExecutableCommand {
@Override
public boolean executeCommand(final CommandSender sender, CommandParts commandReference, CommandParts commandArguments) {
@ -31,23 +32,26 @@ public class ChangePasswordCommand extends ExecutableCommand {
// Validate the password
String playerPassLowerCase = playerPass.toLowerCase();
if (playerPassLowerCase.contains("delete") || playerPassLowerCase.contains("where") || playerPassLowerCase.contains("insert") || playerPassLowerCase.contains("modify") || playerPassLowerCase.contains("from") || playerPassLowerCase.contains("select") || playerPassLowerCase.contains(";") || playerPassLowerCase.contains("null") || !playerPassLowerCase.matches(Settings.getPassRegex)) {
m.send(sender, MessageKey.PASSWORD_IS_USERNAME_ERROR);
if (playerPassLowerCase.contains("delete") || playerPassLowerCase.contains("where")
|| playerPassLowerCase.contains("insert") || playerPassLowerCase.contains("modify")
|| playerPassLowerCase.contains("from") || playerPassLowerCase.contains("select")
|| playerPassLowerCase.contains(";") || playerPassLowerCase.contains("null")
|| !playerPassLowerCase.matches(Settings.getPassRegex)) {
m.send(sender, MessageKey.PASSWORD_MATCH_ERROR);
return true;
}
if (playerPassLowerCase.equalsIgnoreCase(playerName)) {
m.send(sender, MessageKey.PASSWORD_IS_USERNAME_ERROR);
return true;
}
if (playerPassLowerCase.length() < Settings.getPasswordMinLen || playerPassLowerCase.length() > Settings.passwordMaxLength) {
if (playerPassLowerCase.length() < Settings.getPasswordMinLen
|| playerPassLowerCase.length() > Settings.passwordMaxLength) {
m.send(sender, MessageKey.INVALID_PASSWORD_LENGTH);
return true;
}
if (!Settings.unsafePasswords.isEmpty()) {
if (Settings.unsafePasswords.contains(playerPassLowerCase)) {
m.send(sender, MessageKey.PASSWORD_UNSAFE_ERROR);
return true;
}
if (!Settings.unsafePasswords.isEmpty() && Settings.unsafePasswords.contains(playerPassLowerCase)) {
m.send(sender, MessageKey.PASSWORD_UNSAFE_ERROR);
return true;
}
// Set the password
final String playerNameLowerCase = playerName.toLowerCase();

View File

@ -3,7 +3,7 @@ package fr.xephi.authme.command.executable.authme;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.permission.UserPermission;
import fr.xephi.authme.permission.PlayerPermission;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@ -30,11 +30,11 @@ public class ForceLoginCommand extends ExecutableCommand {
sender.sendMessage("Player needs to be online!");
return true;
}
if (!plugin.getPermissionsManager().hasPermission(player, UserPermission.CAN_LOGIN_BE_FORCED)) {
if (!plugin.getPermissionsManager().hasPermission(player, PlayerPermission.CAN_LOGIN_BE_FORCED)) {
sender.sendMessage("You cannot force login for the player " + playerName + "!");
return true;
}
plugin.management.performLogin(player, "dontneed", true);
plugin.getManagement().performLogin(player, "dontneed", true);
sender.sendMessage("Force Login for " + playerName + " performed!");
} catch (Exception e) {
sender.sendMessage("An error occurred while trying to get that player!");

View File

@ -4,8 +4,8 @@ import fr.xephi.authme.AuthMe;
import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.settings.MessageKey;
import fr.xephi.authme.settings.Messages;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages;
import org.bukkit.command.CommandSender;
/**

View File

@ -4,8 +4,8 @@ import fr.xephi.authme.AuthMe;
import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.settings.MessageKey;
import fr.xephi.authme.settings.Messages;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages;
import org.bukkit.command.CommandSender;
import java.util.Date;

View File

@ -5,8 +5,8 @@ import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.settings.MessageKey;
import fr.xephi.authme.settings.Messages;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;

View File

@ -6,8 +6,8 @@ import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.security.PasswordSecurity;
import fr.xephi.authme.settings.MessageKey;
import fr.xephi.authme.settings.Messages;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages;
import fr.xephi.authme.settings.Settings;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
@ -15,8 +15,9 @@ import org.bukkit.command.CommandSender;
import java.security.NoSuchAlgorithmException;
/**
* Admin command to register a user.
*/
public class RegisterCommand extends ExecutableCommand {
public class RegisterAdminCommand extends ExecutableCommand {
/**
* Execute the command.
@ -42,8 +43,12 @@ public class RegisterCommand extends ExecutableCommand {
final String playerPassLowerCase = playerPass.toLowerCase();
// Command logic
if (playerPassLowerCase.contains("delete") || playerPassLowerCase.contains("where") || playerPassLowerCase.contains("insert") || playerPassLowerCase.contains("modify") || playerPassLowerCase.contains("from") || playerPassLowerCase.contains("select") || playerPassLowerCase.contains(";") || playerPassLowerCase.contains("null") || !playerPassLowerCase.matches(Settings.getPassRegex)) {
m.send(sender, MessageKey.PASSWORD_IS_USERNAME_ERROR);
if (playerPassLowerCase.contains("delete") || playerPassLowerCase.contains("where")
|| playerPassLowerCase.contains("insert") || playerPassLowerCase.contains("modify")
|| playerPassLowerCase.contains("from") || playerPassLowerCase.contains("select")
|| playerPassLowerCase.contains(";") || playerPassLowerCase.contains("null")
|| !playerPassLowerCase.matches(Settings.getPassRegex)) {
m.send(sender, MessageKey.PASSWORD_MATCH_ERROR);
return true;
}
if (playerPassLowerCase.equalsIgnoreCase(playerName)) {

View File

@ -6,8 +6,8 @@ import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.settings.MessageKey;
import fr.xephi.authme.settings.Messages;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.util.Profiler;
import org.bukkit.command.CommandSender;
@ -41,7 +41,7 @@ public class ReloadCommand extends ExecutableCommand {
try {
Settings.reload();
plugin.setMessages(new Messages(Settings.messageFile, Settings.messagesLanguage));
Messages.getInstance().reloadManager();
plugin.getModuleManager().reloadModules();
plugin.setupDatabase();
} catch (Exception e) {

View File

@ -5,8 +5,8 @@ import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.settings.MessageKey;
import fr.xephi.authme.settings.Messages;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages;
import fr.xephi.authme.settings.Settings;
import org.bukkit.command.CommandSender;

View File

@ -2,11 +2,15 @@ package fr.xephi.authme.command.executable.authme;
import fr.xephi.authme.AntiBot;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.CommandUtils;
import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.command.help.HelpProvider;
import fr.xephi.authme.util.CollectionUtils;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import java.util.List;
/**
*/
public class SwitchAntiBotCommand extends ExecutableCommand {
@ -32,16 +36,16 @@ public class SwitchAntiBotCommand extends ExecutableCommand {
}
// Enable the mod
if (newState.equalsIgnoreCase("ON")) {
if ("ON".equalsIgnoreCase(newState)) {
AntiBot.overrideAntiBotStatus(true);
sender.sendMessage("[AuthMe] AntiBot Manual Ovverride: enabled!");
sender.sendMessage("[AuthMe] AntiBot Manual Override: enabled!");
return true;
}
// Disable the mod
if (newState.equalsIgnoreCase("OFF")) {
if ("OFF".equalsIgnoreCase(newState)) {
AntiBot.overrideAntiBotStatus(false);
sender.sendMessage("[AuthMe] AntiBotMod Manual Ovverride: disabled!");
sender.sendMessage("[AuthMe] AntiBotMod Manual Override: disabled!");
return true;
}
@ -52,8 +56,9 @@ public class SwitchAntiBotCommand extends ExecutableCommand {
HelpProvider.showHelp(sender, commandReference, commandReference, true, false, true, false, false, false);
// Show the command to use for detailed help
CommandParts helpCommandReference = new CommandParts(commandReference.getRange(1));
sender.sendMessage(ChatColor.GOLD + "Detailed help: " + ChatColor.WHITE + "/" + commandReference.get(0) + " help " + helpCommandReference);
List<String> helpCommandReference = CollectionUtils.getRange(commandReference.getList(), 1);
sender.sendMessage(ChatColor.GOLD + "Detailed help: " + ChatColor.WHITE + "/"
+ commandReference.get(0) + " help " + CommandUtils.labelsToString(helpCommandReference));
return true;
}
}

View File

@ -6,8 +6,8 @@ import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.cache.limbo.LimboCache;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.settings.MessageKey;
import fr.xephi.authme.settings.Messages;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.task.MessageTask;
import fr.xephi.authme.task.TimeoutTask;
@ -21,8 +21,9 @@ import org.bukkit.scheduler.BukkitScheduler;
import org.bukkit.scheduler.BukkitTask;
/**
* Admin command to unregister a player.
*/
public class UnregisterCommand extends ExecutableCommand {
public class UnregisterAdminCommand extends ExecutableCommand {
/**
* Execute the command.

View File

@ -5,9 +5,10 @@ import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.security.RandomString;
import fr.xephi.authme.settings.MessageKey;
import fr.xephi.authme.settings.Messages;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.util.Wrapper;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@ -30,10 +31,11 @@ public class CaptchaCommand extends ExecutableCommand {
String captcha = commandArguments.get(0);
// AuthMe plugin instance
final AuthMe plugin = AuthMe.getInstance();
final Wrapper wrapper = Wrapper.getInstance();
final AuthMe plugin = wrapper.getAuthMe();
// Messages instance
final Messages m = plugin.getMessages();
final Messages m = wrapper.getMessages();
// Command logic
if (PlayerCache.getInstance().isAuthenticated(playerNameLowerCase)) {

View File

@ -4,8 +4,8 @@ import fr.xephi.authme.AuthMe;
import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.settings.MessageKey;
import fr.xephi.authme.settings.Messages;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.task.ChangePasswordTask;
import fr.xephi.authme.util.Wrapper;
@ -13,6 +13,7 @@ import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
/**
* The command for a player to change his password with.
*/
public class ChangePasswordCommand extends ExecutableCommand {
@ -27,10 +28,10 @@ public class ChangePasswordCommand extends ExecutableCommand {
final Messages m = wrapper.getMessages();
// Get the passwords
String playerPass = commandArguments.get(0);
String playerPassVerify = commandArguments.get(1);
String oldPassword = commandArguments.get(0);
String newPassword = commandArguments.get(1);
// Get the player instance and make sure it's authenticated
// Get the player instance and make sure he's authenticated
Player player = (Player) sender;
String name = player.getName().toLowerCase();
final PlayerCache playerCache = wrapper.getPlayerCache();
@ -40,8 +41,7 @@ public class ChangePasswordCommand extends ExecutableCommand {
}
// Make sure the password is allowed
// TODO ljacqu 20151121: The password confirmation appears to be never verified
String playerPassLowerCase = playerPass.toLowerCase();
String playerPassLowerCase = newPassword.toLowerCase();
if (playerPassLowerCase.contains("delete") || playerPassLowerCase.contains("where")
|| playerPassLowerCase.contains("insert") || playerPassLowerCase.contains("modify")
|| playerPassLowerCase.contains("from") || playerPassLowerCase.contains("select")
@ -66,8 +66,8 @@ public class ChangePasswordCommand extends ExecutableCommand {
// Set the password
final AuthMe plugin = wrapper.getAuthMe();
wrapper.getServer().getScheduler().runTaskAsynchronously(plugin,
new ChangePasswordTask(plugin, player, playerPass, playerPassVerify));
wrapper.getScheduler().runTaskAsynchronously(plugin,
new ChangePasswordTask(plugin, player, oldPassword, newPassword));
return true;
}
}

View File

@ -4,8 +4,8 @@ import fr.xephi.authme.AuthMe;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.converter.*;
import fr.xephi.authme.settings.MessageKey;
import fr.xephi.authme.settings.Messages;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;

View File

@ -8,8 +8,8 @@ import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.security.PasswordSecurity;
import fr.xephi.authme.security.RandomString;
import fr.xephi.authme.settings.MessageKey;
import fr.xephi.authme.settings.Messages;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.util.Wrapper;
import org.bukkit.command.CommandSender;

View File

@ -5,8 +5,8 @@ import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.process.Management;
import fr.xephi.authme.security.RandomString;
import fr.xephi.authme.settings.MessageKey;
import fr.xephi.authme.settings.Messages;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.util.Wrapper;
import org.bukkit.command.CommandSender;
@ -55,7 +55,7 @@ public class RegisterCommand extends ExecutableCommand {
}
if (commandArguments.getCount() > 1 && Settings.getEnablePasswordVerifier) {
if (!commandArguments.get(0).equals(commandArguments.get(1))) {
m.send(player, MessageKey.PASSWORD_IS_USERNAME_ERROR);
m.send(player, MessageKey.PASSWORD_MATCH_ERROR);
return true;
}
}

View File

@ -4,8 +4,8 @@ import fr.xephi.authme.AuthMe;
import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.settings.MessageKey;
import fr.xephi.authme.settings.Messages;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@ -49,7 +49,7 @@ public class UnregisterCommand extends ExecutableCommand {
}
// Unregister the player
plugin.management.performUnregister(player, playerPass, false);
plugin.getManagement().performUnregister(player, playerPass, false);
return true;
}
}

View File

@ -1,20 +1,22 @@
package fr.xephi.authme.command.help;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.command.CommandArgumentDescription;
import fr.xephi.authme.command.CommandDescription;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.CommandPermissions;
import fr.xephi.authme.permission.PermissionNode;
import fr.xephi.authme.util.CollectionUtils;
import fr.xephi.authme.util.StringUtils;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
*/
@ -39,9 +41,7 @@ public class HelpPrinter {
* @param command The command to print the description help for.
*/
public static void printCommandDescription(CommandSender sender, CommandDescription command) {
// Print the regular description, if available
if (command.hasDescription())
sender.sendMessage(ChatColor.GOLD + "Short Description: " + ChatColor.WHITE + command.getDescription());
sender.sendMessage(ChatColor.GOLD + "Short Description: " + ChatColor.WHITE + command.getDescription());
// Print the detailed description, if available
if (!StringUtils.isEmpty(command.getDetailedDescription())) {
@ -59,7 +59,7 @@ public class HelpPrinter {
@SuppressWarnings("StringConcatenationInsideStringBufferAppend")
public static void printArguments(CommandSender sender, CommandDescription command) {
// Make sure there are any commands to print
if (!command.hasArguments() && command.getMaximumArguments() >= 0)
if (!command.hasArguments())
return;
// Print the header
@ -78,10 +78,6 @@ public class HelpPrinter {
// Print the syntax
sender.sendMessage(argString.toString());
}
// Show the unlimited arguments argument
if (command.getMaximumArguments() < 0)
sender.sendMessage(" " + ChatColor.YELLOW + ChatColor.ITALIC + "... : " + ChatColor.WHITE + "Any additional arguments." + ChatColor.GRAY + ChatColor.ITALIC + " (Optional)");
}
/**
@ -91,14 +87,11 @@ public class HelpPrinter {
* @param command The command to print the permissions help for.
*/
public static void printPermissions(CommandSender sender, CommandDescription command) {
// Get the permissions and make sure it isn't null
// Get the permissions and make sure they aren't missing
CommandPermissions permissions = command.getCommandPermissions();
if (permissions == null)
return;
// Make sure any permission node is set
if (permissions.getPermissionNodeCount() <= 0)
if (permissions == null || CollectionUtils.isEmpty(permissions.getPermissionNodes())) {
return;
}
// Print the header
sender.sendMessage(ChatColor.GOLD + "Permissions:");
@ -113,13 +106,16 @@ public class HelpPrinter {
}
// Print the default permission
// TODO ljacqu 20151205: This is duplicating the logic in PermissionsManager#evaluateDefaultPermission
// Either use the command manager here, or if that's too heavy, look into moving certain permissions logic
// into a Utils class
switch (permissions.getDefaultPermission()) {
case ALLOWED:
sender.sendMessage(ChatColor.GOLD + " Default: " + ChatColor.GRAY + ChatColor.ITALIC + "Permission!");
break;
case OP_ONLY:
final String defaultPermsString = ChatColor.GRAY + (permissions.getDefaultPermissionCommandSender(sender) ? ChatColor.ITALIC + " (Permission!)" : ChatColor.ITALIC + " (No Permission!)");
final String defaultPermsString = ChatColor.GRAY + (sender.isOp() ? ChatColor.ITALIC + " (Permission!)" : ChatColor.ITALIC + " (No Permission!)");
sender.sendMessage(ChatColor.GOLD + " Default: " + ChatColor.YELLOW + ChatColor.ITALIC + "OP's Only!" + defaultPermsString);
break;

View File

@ -3,12 +3,17 @@ package fr.xephi.authme.command.help;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.command.CommandDescription;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.CommandUtils;
import fr.xephi.authme.command.FoundCommandResult;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.util.CollectionUtils;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import java.util.ArrayList;
import java.util.List;
/**
*/
public class HelpProvider {
@ -39,9 +44,14 @@ public class HelpProvider {
*/
public static void showHelp(CommandSender sender, CommandParts reference, CommandParts helpQuery, boolean showCommand, boolean showDescription, boolean showArguments, boolean showPermissions, boolean showAlternatives, boolean showCommands) {
// Find the command for this help query, one with and one without a prefixed base command
FoundCommandResult result = AuthMe.getInstance().getCommandHandler().getCommandManager().findCommand(new CommandParts(helpQuery.getList()));
CommandParts commandReferenceOther = new CommandParts(reference.get(0), helpQuery.getList());
FoundCommandResult resultOther = AuthMe.getInstance().getCommandHandler().getCommandManager().findCommand(commandReferenceOther);
FoundCommandResult result = AuthMe.getInstance().getCommandHandler().findCommand(new CommandParts(helpQuery.getList()));
// TODO ljacqu 20151204 Fix me to nicer code
List<String> parts = new ArrayList<>(helpQuery.getList());
parts.add(0, reference.get(0));
CommandParts commandReferenceOther = new CommandParts(parts);
FoundCommandResult resultOther = AuthMe.getInstance().getCommandHandler().findCommand(commandReferenceOther);
if (resultOther != null) {
if (result == null)
result = resultOther;
@ -78,13 +88,14 @@ public class HelpProvider {
// Show the unknown command warning
sender.sendMessage(ChatColor.DARK_RED + "No help found for '" + helpQuery + "'!");
// Get the suggested command
CommandParts suggestedCommandParts = new CommandParts(result.getCommandDescription().getCommandReference(commandReference).getRange(1));
// Show a command suggestion if available and the difference isn't too big
if (commandDifference < 0.75)
if (result.getCommandDescription() != null)
sender.sendMessage(ChatColor.YELLOW + "Did you mean " + ChatColor.GOLD + "/" + baseCommand + " help " + suggestedCommandParts + ChatColor.YELLOW + "?");
if (commandDifference < 0.75 && result.getCommandDescription() != null) {
// Get the suggested command
List<String> suggestedCommandParts = CollectionUtils.getRange(
result.getCommandDescription().getCommandReference(commandReference).getList(), 1);
sender.sendMessage(ChatColor.YELLOW + "Did you mean " + ChatColor.GOLD + "/" + baseCommand
+ " help " + CommandUtils.labelsToString(suggestedCommandParts) + ChatColor.YELLOW + "?");
}
// Show the help command
sender.sendMessage(ChatColor.YELLOW + "Use the command " + ChatColor.GOLD + "/" + baseCommand + " help" + ChatColor.YELLOW + " to view help.");
@ -94,10 +105,12 @@ public class HelpProvider {
// Show a message when the command handler is assuming a command
if (commandDifference > 0) {
// Get the suggested command
CommandParts suggestedCommandParts = new CommandParts(result.getCommandDescription().getCommandReference(commandReference).getRange(1));
List<String> suggestedCommandParts = CollectionUtils.getRange(
result.getCommandDescription().getCommandReference(commandReference).getList(), 1);
// Show the suggested command
sender.sendMessage(ChatColor.DARK_RED + "No help found, assuming '" + ChatColor.GOLD + suggestedCommandParts + ChatColor.DARK_RED + "'!");
sender.sendMessage(ChatColor.DARK_RED + "No help found, assuming '" + ChatColor.GOLD
+ CommandUtils.labelsToString(suggestedCommandParts) + ChatColor.DARK_RED + "'!");
}
// Print the help header

View File

@ -3,6 +3,8 @@ package fr.xephi.authme.command.help;
import fr.xephi.authme.command.CommandArgumentDescription;
import fr.xephi.authme.command.CommandDescription;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.CommandUtils;
import fr.xephi.authme.util.CollectionUtils;
import fr.xephi.authme.util.StringUtils;
import org.bukkit.ChatColor;
@ -35,8 +37,8 @@ public final class HelpSyntaxHelper {
// Get the help command reference, and the command label
CommandParts helpCommandReference = commandDescription.getCommandReference(commandReference);
final String parentCommand = new CommandParts(
helpCommandReference.getRange(0, helpCommandReference.getCount() - 1)).toString();
final String parentCommand = CommandUtils.labelsToString(
CollectionUtils.getRange(helpCommandReference.getList(), 0, helpCommandReference.getCount() - 1));
// Check whether the alternative label should be used
String commandLabel;
@ -61,11 +63,6 @@ public final class HelpSyntaxHelper {
sb.append(ChatColor.ITALIC).append(formatArgument(arg));
}
// Add some dots if the command allows unlimited arguments
if (commandDescription.getMaximumArguments() < 0) {
sb.append(ChatColor.ITALIC).append(" ...");
}
// Return the build command syntax
return sb.toString();
}

View File

@ -5,7 +5,7 @@ import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.datasource.FlatFile;
import fr.xephi.authme.settings.MessageKey;
import fr.xephi.authme.output.MessageKey;
import org.bukkit.command.CommandSender;
import java.util.List;

View File

@ -42,16 +42,16 @@ public class vAuthFileReader {
String name = line.split(": ")[0];
String password = line.split(": ")[1];
PlayerAuth auth;
if (isUUIDinstance(password)) {
String playerName;
if (isUuidInstance(password)) {
String pname;
try {
playerName = Bukkit.getOfflinePlayer(UUID.fromString(name)).getName();
pname = Bukkit.getOfflinePlayer(UUID.fromString(name)).getName();
} catch (Exception | NoSuchMethodError e) {
playerName = getName(UUID.fromString(name));
pname = getName(UUID.fromString(name));
}
if (playerName == null)
if (pname == null)
continue;
auth = new PlayerAuth(playerName.toLowerCase(), password, "127.0.0.1", System.currentTimeMillis(), "your@email.com", playerName);
auth = new PlayerAuth(pname.toLowerCase(), password, "127.0.0.1", System.currentTimeMillis(), "your@email.com", pname);
} else {
auth = new PlayerAuth(name.toLowerCase(), password, "127.0.0.1", System.currentTimeMillis(), "your@email.com", name);
}
@ -64,17 +64,8 @@ public class vAuthFileReader {
}
/**
* Method isUUIDinstance.
*
* @param s String
*
* @return boolean
*/
private boolean isUUIDinstance(String s) {
if (String.valueOf(s.charAt(8)).equalsIgnoreCase("-"))
return true;
return true;
private static boolean isUuidInstance(String s) {
return s.length() > 8 && s.charAt(8) == '-';
}
/**

File diff suppressed because it is too large Load Diff

View File

@ -32,6 +32,12 @@ public class AuthMeBlockListener implements Listener {
if (Utils.checkAuth(event.getPlayer())) {
return;
}
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC(event.getPlayer())) {
return;
}
event.setCancelled(true);
}
@ -45,6 +51,12 @@ public class AuthMeBlockListener implements Listener {
if (Utils.checkAuth(event.getPlayer())) {
return;
}
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC(event.getPlayer())) {
return;
}
event.setCancelled(true);
}

View File

@ -49,7 +49,12 @@ public class AuthMeEntityListener implements Listener {
}
Player player = (Player) entity;
if (Utils.checkAuth(player)) {
if (Utils.checkAuth(player) ) {
return;
}
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC(player)) {
return;
}
player.setFireTicks(0);
@ -73,6 +78,11 @@ public class AuthMeEntityListener implements Listener {
return;
}
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC((Player) entity)) {
return;
}
event.setTarget(null);
event.setCancelled(true);
}
@ -83,7 +93,7 @@ public class AuthMeEntityListener implements Listener {
* @param event EntityDamageByEntityEvent
*/
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
public void onDmg(EntityDamageByEntityEvent event) {
public void onDamage(EntityDamageByEntityEvent event) {
Entity entity = event.getDamager();
if (entity == null || !(entity instanceof Player)) {
return;
@ -94,6 +104,11 @@ public class AuthMeEntityListener implements Listener {
return;
}
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC(player)) {
return;
}
event.setCancelled(true);
}
@ -113,6 +128,11 @@ public class AuthMeEntityListener implements Listener {
return;
}
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC((Player) entity)) {
return;
}
event.setCancelled(true);
}
@ -132,6 +152,11 @@ public class AuthMeEntityListener implements Listener {
return;
}
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC((Player) entity)) {
return;
}
event.setAmount(0);
event.setCancelled(true);
}
@ -152,6 +177,11 @@ public class AuthMeEntityListener implements Listener {
return;
}
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC((Player) entity)) {
return;
}
event.setCancelled(true);
}
@ -171,6 +201,11 @@ public class AuthMeEntityListener implements Listener {
return;
}
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC((Player) entity)) {
return;
}
event.setCancelled(true);
}
@ -210,6 +245,11 @@ public class AuthMeEntityListener implements Listener {
return;
}
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC(player)) {
return;
}
event.setCancelled(true);
}
@ -230,6 +270,11 @@ public class AuthMeEntityListener implements Listener {
return;
}
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC(player)) {
return;
}
event.setCancelled(true);
}

View File

@ -9,10 +9,10 @@ import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.cache.limbo.LimboCache;
import fr.xephi.authme.cache.limbo.LimboPlayer;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages;
import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.permission.UserPermission;
import fr.xephi.authme.settings.MessageKey;
import fr.xephi.authme.settings.Messages;
import fr.xephi.authme.permission.PlayerPermission;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.util.GeoLiteAPI;
import fr.xephi.authme.util.Utils;
@ -28,7 +28,24 @@ import org.bukkit.event.block.SignChangeEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryOpenEvent;
import org.bukkit.event.player.*;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.event.player.AsyncPlayerPreLoginEvent;
import org.bukkit.event.player.PlayerBedEnterEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.event.player.PlayerFishEvent;
import org.bukkit.event.player.PlayerGameModeChangeEvent;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerItemConsumeEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerKickEvent;
import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerPickupItemEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.event.player.PlayerShearEntityEvent;
import java.util.concurrent.ConcurrentHashMap;
@ -53,8 +70,7 @@ public class AuthMePlayerListener implements Listener {
}
final Player player = event.getPlayer();
if(Utils.checkAuth(player)) {
if (Utils.checkAuth(player)) {
for (Player p : Utils.getOnlinePlayers()) {
if (!PlayerCache.getInstance().isAuthenticated(p.getName())) {
event.getRecipients().remove(p); // TODO: it should be configurable
@ -64,6 +80,11 @@ public class AuthMePlayerListener implements Listener {
}
event.setCancelled(true);
sendLoginRegisterMSG(player);
}
// TODO: new name
private void sendLoginRegisterMSG(final Player player) {
plugin.getServer().getScheduler().runTaskAsynchronously(plugin, new Runnable() {
@Override
public void run() {
@ -93,6 +114,7 @@ public class AuthMePlayerListener implements Listener {
return;
}
event.setCancelled(true);
sendLoginRegisterMSG(event.getPlayer());
}
@EventHandler(ignoreCancelled = true, priority = EventPriority.NORMAL)
@ -167,20 +189,26 @@ public class AuthMePlayerListener implements Listener {
}
}
@EventHandler(priority = EventPriority.HIGHEST)
@EventHandler(priority = EventPriority.LOWEST)
public void onPlayerJoin(PlayerJoinEvent event) {
if (event.getPlayer() == null || Utils.isNPC(event.getPlayer())) {
final Player player = event.getPlayer();
if (player == null) {
return;
}
final Player player = event.getPlayer();
final String name = player.getName().toLowerCase();
final String joinMsg = event.getJoinMessage();
final boolean delay = Settings.delayJoinLeaveMessages && joinMsg != null;
/* IMPOSSIBLE!!!! TODO: check this!
if(Utils.isNPC(player)) {
return;
}
*/
String name = player.getName().toLowerCase();
String joinMsg = event.getJoinMessage();
// Remove the join message while the player isn't logging in
if (delay) {
if (Settings.delayJoinLeaveMessages && joinMsg != null) {
event.setJoinMessage(null);
joinMessage.put(name, joinMsg);
}
// Shedule login task so works after the prelogin
@ -188,9 +216,6 @@ public class AuthMePlayerListener implements Listener {
Bukkit.getScheduler().runTask(plugin, new Runnable() {
@Override
public void run() {
if (delay) {
joinMessage.put(name, joinMsg);
}
plugin.getManagement().performJoin(player);
}
});
@ -198,38 +223,57 @@ public class AuthMePlayerListener implements Listener {
@EventHandler(priority = EventPriority.HIGHEST)
public void onPreLogin(AsyncPlayerPreLoginEvent event) {
if (!plugin.canConnect()) {
event.setLoginResult(AsyncPlayerPreLoginEvent.Result.KICK_OTHER);
event.setKickMessage("Server is loading, please wait before joining!");
return;
}
if (Settings.enableProtection) {
String countryCode = GeoLiteAPI.getCountryCode(event.getAddress().getHostAddress());
if (!Settings.countriesBlacklist.isEmpty() && Settings.countriesBlacklist.contains(countryCode)) {
event.setLoginResult(AsyncPlayerPreLoginEvent.Result.KICK_OTHER);
event.setKickMessage(m.retrieveSingle(MessageKey.COUNTRY_BANNED_ERROR));
return;
}
if (!Settings.countries.isEmpty() && !Settings.countries.contains(countryCode)) {
event.setLoginResult(AsyncPlayerPreLoginEvent.Result.KICK_OTHER);
event.setKickMessage(m.retrieveSingle(MessageKey.COUNTRY_BANNED_ERROR));
return;
}
}
final String name = event.getName().toLowerCase();
final Player player = Utils.getPlayer(name);
if (player == null || Utils.isNPC(player)) {
if (player == null) {
return;
}
// Check if forceSingleSession is set to true, so kick player that has
// joined with same nick of online player
if (Settings.isForceSingleSessionEnabled && player.isOnline()) {
event.disallow(AsyncPlayerPreLoginEvent.Result.KICK_OTHER, m.getString("same_nick"));
if (LimboCache.getInstance().hasLimboPlayer(name))
Bukkit.getScheduler().runTaskAsynchronously(plugin, new Runnable() {
@Override
public void run() {
LimboPlayer limbo = LimboCache.getInstance().getLimboPlayer(name);
if (limbo != null && PlayerCache.getInstance().isAuthenticated(name)) {
Utils.addNormal(player, limbo.getGroup());
LimboCache.getInstance().deleteLimboPlayer(name);
}
}
});
if (Settings.isForceSingleSessionEnabled) {
event.setLoginResult(AsyncPlayerPreLoginEvent.Result.KICK_OTHER);
event.setKickMessage(m.retrieveSingle(MessageKey.USERNAME_ALREADY_ONLINE_ERROR));
LimboPlayer limbo = LimboCache.getInstance().getLimboPlayer(name);
if (limbo != null && PlayerCache.getInstance().isAuthenticated(name)) {
Utils.addNormal(player, limbo.getGroup());
LimboCache.getInstance().deleteLimboPlayer(name);
}
}
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onPlayerLogin(PlayerLoginEvent event) {
if (event.getPlayer() == null) {
final Player player = event.getPlayer();
if (player == null || Utils.isUnrestricted(player)) {
return;
}
if (event.getResult() == PlayerLoginEvent.Result.KICK_FULL) {
// Get the permissions manager
PermissionsManager permsMan = plugin.getPermissionsManager();
if (event.getResult() == PlayerLoginEvent.Result.KICK_FULL
&& permsMan.hasPermission(player, PlayerPermission.IS_VIP)) {
int playersOnline = Utils.getOnlinePlayers().size();
if (playersOnline > plugin.getServer().getMaxPlayers()) {
event.allow();
@ -250,45 +294,19 @@ public class AuthMePlayerListener implements Listener {
return;
}
// Get the permissions manager
PermissionsManager permsMan = plugin.getPermissionsManager();
final Player player = event.getPlayer();
if (event.getResult() == PlayerLoginEvent.Result.KICK_FULL && !permsMan.hasPermission(player, UserPermission.IS_VIP)) {
if (event.getResult() == PlayerLoginEvent.Result.KICK_FULL && !permsMan.hasPermission(player, PlayerPermission.IS_VIP)) {
event.setKickMessage(m.retrieveSingle(MessageKey.KICK_FULL_SERVER));
event.setResult(PlayerLoginEvent.Result.KICK_FULL);
return;
}
if (Utils.isNPC(player) || Utils.isUnrestricted(player)) {
return;
}
final String name = player.getName().toLowerCase();
boolean isAuthAvailable = plugin.database.isAuthAvailable(name);
if (!Settings.countriesBlacklist.isEmpty() && !isAuthAvailable && !permsMan.hasPermission(player, UserPermission.BYPASS_ANTIBOT)) {
String code = GeoLiteAPI.getCountryCode(event.getAddress().getHostAddress());
if (Settings.countriesBlacklist.contains(code)) {
event.setKickMessage(m.retrieveSingle(MessageKey.COUNTRY_BANNED_ERROR));
event.setResult(PlayerLoginEvent.Result.KICK_OTHER);
return;
}
}
if (Settings.enableProtection && !Settings.countries.isEmpty() && !isAuthAvailable && !permsMan.hasPermission(player, UserPermission.BYPASS_ANTIBOT)) {
String code = GeoLiteAPI.getCountryCode(event.getAddress().getHostAddress());
if (!Settings.countries.contains(code)) {
event.setKickMessage(m.retrieveSingle(MessageKey.COUNTRY_BANNED_ERROR));
event.setResult(PlayerLoginEvent.Result.KICK_OTHER);
return;
}
}
// TODO: Add message to the messages file!!!
if (Settings.isKickNonRegisteredEnabled && !isAuthAvailable) {
if (Settings.antiBotInAction) {
event.setKickMessage("AntiBot service in action! You actually need to be registered!");
event.setKickMessage(m.retrieveSingle(MessageKey.KICK_ANTIBOT));
event.setResult(PlayerLoginEvent.Result.KICK_OTHER);
return;
} else {
@ -321,61 +339,77 @@ public class AuthMePlayerListener implements Listener {
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerQuit(PlayerQuitEvent event) {
if (event.getPlayer() == null) {
Player player = event.getPlayer();
if (player == null) {
return;
}
Player player = event.getPlayer();
if (!Utils.checkAuth(player) && Settings.delayJoinLeaveMessages) {
if (Settings.delayJoinLeaveMessages && !Utils.checkAuth(player)) {
event.setQuitMessage(null);
}
plugin.management.performQuit(player, false);
plugin.getManagement().performQuit(player, false);
}
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
public void onPlayerKick(PlayerKickEvent event) {
if (event.getPlayer() == null) {
Player player = event.getPlayer();
if (player == null) {
return;
}
if ((!Settings.isForceSingleSessionEnabled) && (event.getReason().contains(m.getString("same_nick")))) {
if ((!Settings.isForceSingleSessionEnabled)
&& (event.getReason().equals(m.retrieveSingle(MessageKey.USERNAME_ALREADY_ONLINE_ERROR)))) {
event.setCancelled(true);
return;
}
Player player = event.getPlayer();
plugin.management.performQuit(player, true);
plugin.getManagement().performQuit(player, true);
}
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
public void onPlayerPickupItem(PlayerPickupItemEvent event) {
if (Utils.checkAuth(event.getPlayer()))
Player player = event.getPlayer();
// TODO: npc status can be used to bypass security!!!
if (Utils.checkAuth(player) || Utils.isNPC(player)) {
return;
}
event.setCancelled(true);
}
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
public void onPlayerInteract(PlayerInteractEvent event) {
Player player = event.getPlayer();
if (player == null || Utils.checkAuth(player))
// TODO: npc status can be used to bypass security!!!
if (Utils.checkAuth(player) || Utils.isNPC(player)) {
return;
}
event.setCancelled(true);
}
@EventHandler(ignoreCancelled = true, priority = EventPriority.NORMAL)
public void onPlayerConsumeItem(PlayerItemConsumeEvent event) {
if (Utils.checkAuth(event.getPlayer()))
Player player = event.getPlayer();
// TODO: npc status can be used to bypass security!!!
if (Utils.checkAuth(player) || Utils.isNPC(player)) {
return;
}
event.setCancelled(true);
}
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
public void onPlayerInventoryOpen(InventoryOpenEvent event) {
final Player player = (Player) event.getPlayer();
if (Utils.checkAuth(player))
// TODO: npc status can be used to bypass security!!!
if (Utils.checkAuth(player) || Utils.isNPC(player)) {
return;
}
event.setCancelled(true);
/*
@ -383,7 +417,6 @@ public class AuthMePlayerListener implements Listener {
* real, cause no packet is send to server by client for the main inv
*/
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
@Override
public void run() {
player.closeInventory();
@ -399,6 +432,10 @@ public class AuthMePlayerListener implements Listener {
return;
if (Utils.checkAuth((Player) event.getWhoClicked()))
return;
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC((Player) event.getWhoClicked()))
return;
event.setCancelled(true);
}
@ -408,50 +445,85 @@ public class AuthMePlayerListener implements Listener {
if (!(damager instanceof Player)) {
return;
}
if (Utils.checkAuth((Player) damager))
if (Utils.checkAuth((Player) damager)) {
return;
}
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC((Player) damager)) {
return;
}
event.setCancelled(true);
}
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
public void onPlayerInteractEntity(PlayerInteractEntityEvent event) {
Player player = event.getPlayer();
if (player == null || Utils.checkAuth(player))
if (Utils.checkAuth(event.getPlayer())) {
return;
}
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC(event.getPlayer())) {
return;
}
event.setCancelled(true);
}
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
public void onPlayerDropItem(PlayerDropItemEvent event) {
if (Utils.checkAuth(event.getPlayer()))
if (Utils.checkAuth(event.getPlayer())) {
return;
}
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC(event.getPlayer())) {
return;
}
event.setCancelled(true);
}
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
public void onPlayerBedEnter(PlayerBedEnterEvent event) {
if (Utils.checkAuth(event.getPlayer()))
if (Utils.checkAuth(event.getPlayer())) {
return;
}
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC(event.getPlayer())) {
return;
}
event.setCancelled(true);
}
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
public void onSignChange(SignChangeEvent event) {
if (Utils.checkAuth(event.getPlayer()))
if (Utils.checkAuth(event.getPlayer())) {
return;
}
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC(event.getPlayer())) {
return;
}
event.setCancelled(true);
}
@EventHandler(priority = EventPriority.HIGHEST)
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
public void onPlayerRespawn(PlayerRespawnEvent event) {
Player player = event.getPlayer();
if (player == null || Utils.checkAuth(player))
if (Utils.checkAuth(event.getPlayer())) {
return;
}
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC(event.getPlayer())) {
return;
}
Player player = event.getPlayer();
String name = player.getName().toLowerCase();
Location spawn = plugin.getSpawnLocation(player);
if (Settings.isSaveQuitLocationEnabled && plugin.database.isAuthAvailable(name)) {
final PlayerAuth auth = new PlayerAuth(name, spawn.getX(), spawn.getY(), spawn.getZ(), spawn.getWorld().getName(), player.getName());
PlayerAuth auth = new PlayerAuth(name, spawn.getX(), spawn.getY(), spawn.getZ(), spawn.getWorld().getName(), player.getName());
plugin.database.updateQuitLoc(auth);
}
if (spawn != null && spawn.getWorld() != null) {
@ -461,13 +533,19 @@ public class AuthMePlayerListener implements Listener {
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
public void onPlayerGameModeChange(PlayerGameModeChangeEvent event) {
if (Utils.checkAuth(event.getPlayer())) {
return;
}
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC(event.getPlayer())) {
return;
}
Player player = event.getPlayer();
if (player == null)
return;
if (plugin.getPermissionsManager().hasPermission(player, UserPermission.BYPASS_FORCE_SURVIVAL))
return;
if (Utils.checkAuth(player))
if (plugin.getPermissionsManager().hasPermission(player, PlayerPermission.BYPASS_FORCE_SURVIVAL)) {
return;
}
String name = player.getName().toLowerCase();
if (causeByAuthMe.containsKey(name)) {
@ -479,17 +557,27 @@ public class AuthMePlayerListener implements Listener {
@EventHandler(ignoreCancelled = true, priority = EventPriority.NORMAL)
public void onPlayerShear(PlayerShearEntityEvent event) {
Player player = event.getPlayer();
if (player == null || Utils.checkAuth(player))
if (Utils.checkAuth(event.getPlayer())) {
return;
}
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC(event.getPlayer())) {
return;
}
event.setCancelled(true);
}
@EventHandler(ignoreCancelled = true, priority = EventPriority.NORMAL)
public void onPlayerFish(PlayerFishEvent event) {
Player player = event.getPlayer();
if (player == null || Utils.checkAuth(player))
if (Utils.checkAuth(event.getPlayer())) {
return;
}
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC(event.getPlayer())) {
return;
}
event.setCancelled(true);
}

View File

@ -32,6 +32,11 @@ public class AuthMePlayerListener16 implements Listener {
if (Utils.checkAuth(event.getPlayer())) {
return;
}
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC(event.getPlayer())) {
return;
}
event.setCancelled(true);
}

View File

@ -32,6 +32,11 @@ public class AuthMePlayerListener18 implements Listener {
if (Utils.checkAuth(event.getPlayer())) {
return;
}
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC(event.getPlayer())) {
return;
}
event.setCancelled(true);
}

View File

@ -2,8 +2,8 @@ package fr.xephi.authme.listener;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.settings.MessageKey;
import fr.xephi.authme.settings.Messages;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.util.GeoLiteAPI;
import org.bukkit.event.EventHandler;
@ -43,19 +43,13 @@ public class AuthMeServerListener implements Listener {
}
String countryCode = GeoLiteAPI.getCountryCode(event.getAddress().getHostAddress());
if (!Settings.countriesBlacklist.isEmpty()) {
if (Settings.countriesBlacklist.contains(countryCode)) {
event.setMotd(m.retrieveSingle(MessageKey.COUNTRY_BANNED_ERROR));
return;
}
if (!Settings.countriesBlacklist.isEmpty() && Settings.countriesBlacklist.contains(countryCode)) {
event.setMotd(m.retrieveSingle(MessageKey.COUNTRY_BANNED_ERROR));
return;
}
if (!Settings.countries.isEmpty()) {
if (Settings.countries.contains(countryCode)) {
event.setMotd(plugin.getServer().getMotd());
} else {
event.setMotd(m.retrieveSingle(MessageKey.COUNTRY_BANNED_ERROR));
}
if (!Settings.countries.isEmpty() && !Settings.countries.contains(countryCode)) {
event.setMotd(m.retrieveSingle(MessageKey.COUNTRY_BANNED_ERROR));
}
}

View File

@ -0,0 +1,26 @@
package fr.xephi.authme.output;
import java.util.logging.Filter;
import java.util.logging.LogRecord;
/**
* Console filter to replace sensitive AuthMe commands with a generic message.
*
* @author Xephi59
*/
public class ConsoleFilter implements Filter {
@Override
public boolean isLoggable(LogRecord record) {
if (record == null || record.getMessage() == null) {
return true;
}
if (LogFilterHelper.isSensitiveAuthMeCommand(record.getMessage())) {
String playerName = record.getMessage().split(" ")[0];
record.setMessage(playerName + " issued an AuthMe command");
}
return true;
}
}

View File

@ -1,8 +1,8 @@
package fr.xephi.authme;
package fr.xephi.authme.output;
import fr.xephi.authme.util.StringUtils;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.core.Filter;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.Logger;
import org.apache.logging.log4j.message.Message;
@ -11,16 +11,8 @@ import org.apache.logging.log4j.message.Message;
* Implements a filter for Log4j to skip sensitive AuthMe commands.
*
* @author Xephi59
* @version $Revision: 1.0 $
*/
public class Log4JFilter implements org.apache.logging.log4j.core.Filter {
/**
* List of commands (lower-case) to skip.
*/
private static final String[] COMMANDS_TO_SKIP = {"/login ", "/l ", "/reg ", "/changepassword ",
"/unregister ", "/authme register ", "/authme changepassword ", "/authme reg ", "/authme cp ",
"/register "};
public class Log4JFilter implements Filter {
/**
* Constructor.
@ -30,12 +22,11 @@ public class Log4JFilter implements org.apache.logging.log4j.core.Filter {
/**
* Validates a Message instance and returns the {@link Result} value
* depending depending on whether the message contains sensitive AuthMe
* data.
* depending on whether the message contains sensitive AuthMe data.
*
* @param message the Message object to verify
* @param message The Message object to verify
*
* @return the Result value
* @return The Result value
*/
private static Result validateMessage(Message message) {
if (message == null) {
@ -46,23 +37,16 @@ public class Log4JFilter implements org.apache.logging.log4j.core.Filter {
/**
* Validates a message and returns the {@link Result} value depending
* depending on whether the message contains sensitive AuthMe data.
* on whether the message contains sensitive AuthMe data.
*
* @param message the message to verify
* @param message The message to verify
*
* @return the Result value
* @return The Result value
*/
private static Result validateMessage(String message) {
if (message == null) {
return Result.NEUTRAL;
}
String lowerMessage = message.toLowerCase();
if (lowerMessage.contains("issued server command:")
&& StringUtils.containsAny(lowerMessage, COMMANDS_TO_SKIP)) {
return Result.DENY;
}
return Result.NEUTRAL;
return LogFilterHelper.isSensitiveAuthMeCommand(message)
? Result.DENY
: Result.NEUTRAL;
}
@Override
@ -74,14 +58,12 @@ public class Log4JFilter implements org.apache.logging.log4j.core.Filter {
}
@Override
public Result filter(Logger arg0, Level arg1, Marker arg2, String message,
Object... arg4) {
public Result filter(Logger arg0, Level arg1, Marker arg2, String message, Object... arg4) {
return validateMessage(message);
}
@Override
public Result filter(Logger arg0, Level arg1, Marker arg2, Object message,
Throwable arg4) {
public Result filter(Logger arg0, Level arg1, Marker arg2, Object message, Throwable arg4) {
if (message == null) {
return Result.NEUTRAL;
}
@ -89,8 +71,7 @@ public class Log4JFilter implements org.apache.logging.log4j.core.Filter {
}
@Override
public Result filter(Logger arg0, Level arg1, Marker arg2, Message message,
Throwable arg4) {
public Result filter(Logger arg0, Level arg1, Marker arg2, Message message, Throwable arg4) {
return validateMessage(message);
}

View File

@ -0,0 +1,34 @@
package fr.xephi.authme.output;
import fr.xephi.authme.util.StringUtils;
/**
* Service class for the log filters.
*/
public final class LogFilterHelper {
private static final String ISSUED_COMMAND_TEXT = "issued server command:";
private static final String[] COMMANDS_TO_SKIP = {"/login ", "/l ", "/reg ", "/changepassword ",
"/unregister ", "/authme register ", "/authme changepassword ", "/authme reg ", "/authme cp ",
"/register "};
private LogFilterHelper() {
// Util class
}
/**
* Validate a message and return whether the message contains a sensitive AuthMe command.
*
* @param message The message to verify
*
* @return True if it is a sensitive AuthMe command, false otherwise
*/
public static boolean isSensitiveAuthMeCommand(String message) {
if (message == null) {
return false;
}
String lowerMessage = message.toLowerCase();
return lowerMessage.contains(ISSUED_COMMAND_TEXT) && StringUtils.containsAny(lowerMessage, COMMANDS_TO_SKIP);
}
}

View File

@ -1,10 +1,12 @@
package fr.xephi.authme.settings;
package fr.xephi.authme.output;
/**
* Keys for translatable messages managed by {@link Messages}.
*/
public enum MessageKey {
KICK_ANTIBOT("kick_antibot"),
UNKNOWN_USER("unknown_user"),
UNSAFE_QUIT_LOCATION("unsafe_spawn"),

View File

@ -0,0 +1,82 @@
package fr.xephi.authme.output;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.util.StringUtils;
import org.bukkit.command.CommandSender;
/**
* Class for retrieving and sending translatable messages to players.
* This class detects when the language settings have changed and will
* automatically update to use a new language file.
*/
public class Messages {
private static Messages singleton;
private final String language;
private MessagesManager manager;
private Messages(String language, MessagesManager manager) {
this.language = language;
this.manager = manager;
}
/**
* Get the instance of Messages.
*
* @return The Messages instance
*/
public static Messages getInstance() {
if (singleton == null) {
MessagesManager manager = new MessagesManager(Settings.messageFile);
singleton = new Messages(Settings.messagesLanguage, manager);
}
return singleton;
}
/**
* Send the given message code to the player.
*
* @param sender The entity to send the message to
* @param key The key of the message to send
*/
public void send(CommandSender sender, MessageKey key) {
String[] lines = manager.retrieve(key.getKey());
for (String line : lines) {
sender.sendMessage(line);
}
}
/**
* Retrieve the message from the text file and return it split by new line as an array.
*
* @param key The message key to retrieve
*
* @return The message split by new lines
*/
public String[] retrieve(MessageKey key) {
if (!Settings.messagesLanguage.equalsIgnoreCase(language)) {
reloadManager();
}
return manager.retrieve(key.getKey());
}
/**
* Retrieve the message from the text file.
*
* @param key The message key to retrieve
*
* @return The message from the file
*/
public String retrieveSingle(MessageKey key) {
return StringUtils.join("\n", retrieve(key));
}
/**
* Reload the messages manager.
*/
public void reloadManager() {
manager = new MessagesManager(Settings.messageFile);
}
}

View File

@ -0,0 +1,62 @@
package fr.xephi.authme.output;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.settings.CustomConfiguration;
import java.io.File;
/**
* Class responsible for reading messages from a file and formatting them for Minecraft.
* <p />
* This class is used within {@link Messages}, which offers a high-level interface for accessing
* or sending messages from a properties file.
*/
class MessagesManager extends CustomConfiguration {
/** The section symbol, used in Minecraft for formatting codes. */
private static final String SECTION_SIGN = "\u00a7";
/**
* Constructor for Messages.
*
* @param file the configuration file
*/
MessagesManager(File file) {
super(file);
load();
}
/**
* Retrieve the message from the configuration file.
*
* @param key The key to retrieve
*
* @return The message
*/
String[] retrieve(String key) {
String message = (String) get(key);
if (message != null) {
return formatMessage(message);
}
// Message is null: log key not being found and send error back as message
String retrievalError = "Error getting message with key '" + key + "'. ";
ConsoleLogger.showError(retrievalError + "Please verify your config file at '"
+ getConfigFile().getName() + "'");
return new String[]{
retrievalError + "Please contact the admin to verify or update the AuthMe messages file."};
}
static String[] formatMessage(String message) {
// TODO: Check that the codes actually exist, i.e. replace &c but not &y
// TODO: Allow '&' to be retained with the code '&&'
String[] lines = message.split("&n");
for (int i = 0; i < lines.length; ++i) {
// We don't initialize a StringBuilder here because mostly we will only have one entry
lines[i] = lines[i].replace("&", SECTION_SIGN);
}
return lines;
}
}

View File

@ -1,55 +1,131 @@
package fr.xephi.authme.permission;
/**
* AuthMe admin permissions.
* AuthMe admin command permissions.
*/
public enum AdminPermission implements PermissionNode {
/**
* Administrator command to register a new user.
*/
REGISTER("authme.admin.register"),
/**
* Administrator command to unregister an existing user.
*/
UNREGISTER("authme.admin.unregister"),
/**
* Administrator command to force-login an existing user.
*/
FORCE_LOGIN("authme.admin.forcelogin"),
/**
* Administrator command to change the password of a user.
*/
CHANGE_PASSWORD("authme.admin.changepassword"),
/**
* Administrator command to see the last login date and time of a user.
*/
LAST_LOGIN("authme.admin.lastlogin"),
/**
* Administrator command to see all accounts associated with a user.
*/
ACCOUNTS("authme.admin.accounts"),
/**
* Administrator command to get the email address of a user, if set.
*/
GET_EMAIL("authme.admin.getemail"),
CHANGE_EMAIL("authme.admin.chgemail"),
/**
* Administrator command to set or change the email address of a user.
*/
CHANGE_EMAIL("authme.admin.changemail"),
/**
* Administrator command to get the last known IP of a user.
*/
GET_IP("authme.admin.getip"),
/**
* Administrator command to teleport to the AuthMe spawn.
*/
SPAWN("authme.admin.spawn"),
/**
* Administrator command to set the AuthMe spawn.
*/
SET_SPAWN("authme.admin.setspawn"),
/**
* Administrator command to teleport to the first AuthMe spawn.
*/
FIRST_SPAWN("authme.admin.firstspawn"),
/**
* Administrator command to set the first AuthMe spawn.
*/
SET_FIRST_SPAWN("authme.admin.setfirstspawn"),
/**
* Administrator command to purge old user data.
*/
PURGE("authme.admin.purge"),
/**
* Administrator command to purge the last position of a user.
*/
PURGE_LAST_POSITION("authme.admin.purgelastpos"),
/**
* Administrator command to purge all data associated with banned players.
*/
PURGE_BANNED_PLAYERS("authme.admin.purgebannedplayers"),
/**
* Administrator command to toggle the AntiBot protection status.
*/
SWITCH_ANTIBOT("authme.admin.switchantibot"),
RELOAD("authme.admin.reload");
/**
* Administrator command to convert old or other data to AuthMe data.
*/
CONVERTER("authme.admin.converter"),
/**
* Administrator command to reload the plugin configuration.
*/
RELOAD("authme.admin.reload"),
/**
* Give access to all admin commands.
*/
ADMIN_ALL("authme.admin.*");
/**
* The permission node.
*/
private String node;
/**
* Constructor.
*
* @param node Permission node.
*/
AdminPermission(String node) {
this.node = node;
}
@Override
public String getNode() {
return node;
}
AdminPermission(String node) {
this.node = node;
@Override
public PermissionNode getWildcardNode() {
return ADMIN_ALL;
}
}

View File

@ -0,0 +1,16 @@
package fr.xephi.authme.permission;
/**
* The default permission for a command if there is no support for permission nodes.
*/
public enum DefaultPermission {
/** No one can execute the command. */
NOT_ALLOWED,
/** Only players with the OP status may execute the command. */
OP_ONLY,
/** The command can be executed by anyone. */
ALLOWED
}

View File

@ -5,7 +5,18 @@ package fr.xephi.authme.permission;
*/
public interface PermissionNode {
/** Return the node of the permission, e.g. "authme.unregister". */
/**
* Return the node of the permission, e.g. "authme.player.unregister".
*
* @return The name of the permission node
*/
String getNode();
/**
* Return the wildcard node that also grants the permission.
*
* @return The wildcard permission node (e.g. "authme.player.*")
*/
PermissionNode getWildcardNode();
}

View File

@ -5,11 +5,14 @@ import com.nijiko.permissions.PermissionHandler;
import com.nijikokun.bukkit.Permissions.Permissions;
import de.bananaco.bpermissions.api.ApiLayer;
import de.bananaco.bpermissions.api.CalculableType;
import fr.xephi.authme.command.CommandDescription;
import fr.xephi.authme.util.CollectionUtils;
import net.milkbowl.vault.permission.Permission;
import org.anjocaido.groupmanager.GroupManager;
import org.anjocaido.groupmanager.permissions.AnjoPermissionsHandler;
import org.bukkit.Bukkit;
import org.bukkit.Server;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.server.PluginDisableEvent;
import org.bukkit.event.server.PluginEnableEvent;
@ -38,7 +41,7 @@ import java.util.logging.Logger;
* @author Tim Visée, http://timvisee.com
* @version 0.2.1
*/
public class PermissionsManager {
public class PermissionsManager implements PermissionsService {
/**
* Vault instance.
@ -100,8 +103,8 @@ public class PermissionsManager {
*
* @return The name of the permissions system used.
*/
public String getUsedPermissionsSystemType() {
return this.permsType.getName();
public PermissionsSystemType getSystem() {
return permsType;
}
/**
@ -295,35 +298,7 @@ public class PermissionsManager {
}
}
/**
* Get the logger instance.
*
* @return Logger instance.
*/
public Logger getLogger() {
return this.log;
}
/**
* Set the logger instance.
*
* @param log Logger instance.
*/
public void setLogger(Logger log) {
this.log = log;
}
/**
* Check if the player has permission. If no permissions system is used, the player has to be OP.
*
* @param player The player.
* @param permsNode Permissions node.
*
* @return True if the player has permission.
*/
public boolean hasPermission(Player player, String permsNode) {
return hasPermission(player, permsNode, player.isOp());
}
/**
* Check if the player has permission for the given permissions node. If no permissions system is used,
@ -339,7 +314,42 @@ public class PermissionsManager {
}
public boolean hasPermission(Player player, PermissionNode permissionNode, boolean def) {
return hasPermission(player, permissionNode.getNode(), def);
return hasPermission(player, permissionNode.getNode(), def)
|| hasPermission(player, permissionNode.getWildcardNode().getNode(), def);
}
public boolean hasPermission(Player player, Iterable<PermissionNode> nodes, boolean def) {
for (PermissionNode node : nodes) {
if (!hasPermission(player, node, def)) {
return false;
}
}
return true;
}
public boolean hasPermission(Player player, CommandDescription command) {
if (command.getCommandPermissions() == null
|| CollectionUtils.isEmpty(command.getCommandPermissions().getPermissionNodes())) {
return true;
}
DefaultPermission defaultPermission = command.getCommandPermissions().getDefaultPermission();
boolean def = evaluateDefaultPermission(defaultPermission, player);
return hasPermission(player, command.getCommandPermissions().getPermissionNodes(), def);
}
public static boolean evaluateDefaultPermission(DefaultPermission defaultPermission, CommandSender sender) {
switch (defaultPermission) {
case ALLOWED:
return true;
case OP_ONLY:
return sender.isOp();
case NOT_ALLOWED:
default:
return false;
}
}
/**
@ -351,7 +361,7 @@ public class PermissionsManager {
*
* @return True if the player has permission.
*/
public boolean hasPermission(Player player, String permsNode, boolean def) {
private boolean hasPermission(Player player, String permsNode, boolean def) {
// If no permissions system is used, return the default value
if (!isEnabled())
return def;
@ -914,34 +924,5 @@ public class PermissionsManager {
return removeGroups(player, groupNames);
}
private enum PermissionsSystemType {
NONE("None"),
PERMISSIONS_EX("PermissionsEx"),
PERMISSIONS_BUKKIT("Permissions Bukkit"),
B_PERMISSIONS("bPermissions"),
ESSENTIALS_GROUP_MANAGER("Essentials Group Manager"),
Z_PERMISSIONS("zPermissions"),
VAULT("Vault"),
PERMISSIONS("Permissions");
public final String name;
/**
* Constructor for PermissionsSystemType.
*
* @param name String
*/
PermissionsSystemType(String name) {
this.name = name;
}
/**
* Method getName.
*
* @return String
*/
public String getName() {
return this.name;
}
}
}

View File

@ -0,0 +1,39 @@
package fr.xephi.authme.permission;
import fr.xephi.authme.command.CommandDescription;
import org.bukkit.entity.Player;
/**
* Interface for dealing with permissions.
*/
public interface PermissionsService {
/**
* Check if the player has the given permission.
*
* @param player The player
* @param permission The permission node to check
* @param def Default returned if no permissions system is used
*
* @return True if the player has permission
*/
boolean hasPermission(Player player, PermissionNode permission, boolean def);
/**
* Check if the player has the permissions for the given command.
*
* @param player The player
* @param command The command whose permissions should be checked
*
* @return True if the player may execute the command
*/
boolean hasPermission(Player player, CommandDescription command);
/**
* Return the permission system the service is working with.
*
* @return The permission system AuthMe is hooked into
*/
PermissionsSystemType getSystem();
}

View File

@ -0,0 +1,38 @@
package fr.xephi.authme.permission;
/**
* Enum representing the permissions systems AuthMe supports.
*/
public enum PermissionsSystemType {
NONE("None"),
PERMISSIONS_EX("PermissionsEx"),
PERMISSIONS_BUKKIT("Permissions Bukkit"),
B_PERMISSIONS("bPermissions"),
ESSENTIALS_GROUP_MANAGER("Essentials Group Manager"),
Z_PERMISSIONS("zPermissions"),
VAULT("Vault"),
PERMISSIONS("Permissions");
public final String name;
/**
* Constructor for PermissionsSystemType.
*
* @param name The name the permissions manager goes by
*/
PermissionsSystemType(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
}

View File

@ -0,0 +1,111 @@
package fr.xephi.authme.permission;
/**
* AuthMe player permission nodes, for regular players.
*/
public enum PlayerPermission implements PermissionNode {
/**
* Permission node to bypass AntiBot protection.
*/
BYPASS_ANTIBOT("authme.player.bypassantibot"),
/**
* Permission node to identify VIP users.
*/
IS_VIP("authme.player.vip"),
/**
* Command permission to login.
*/
LOGIN("authme.player.login"),
/**
* Command permission to logout.
*/
LOGOUT("authme.player.logout"),
/**
* Command permission to register.
*/
REGISTER("authme.player.register"),
/**
* Command permission to unregister.
*/
UNREGISTER("authme.player.unregister"),
/**
* Command permission to change the password.
*/
CHANGE_PASSWORD("authme.player.changepassword"),
/**
* Command permission to add an email address.
*/
ADD_EMAIL("authme.player.email.add"),
/**
* Command permission to change the email address.
*/
CHANGE_EMAIL("authme.player.email.change"),
/**
* Command permission to recover an account using it's email address.
*/
RECOVER_EMAIL("authme.player.email.recover"),
/**
* Command permission to use captcha.
*/
CAPTCHA("authme.player.captcha"),
/**
* Permission for users a login can be forced to.
*/
CAN_LOGIN_BE_FORCED("authme.player.canbeforced"),
/**
* Permission for users to bypass force-survival mode.
*/
BYPASS_FORCE_SURVIVAL("authme.player.bypassforcesurvival"),
/**
* Permission for users to allow two accounts.
*/
ALLOW_MULTIPLE_ACCOUNTS("authme.player.allow2accounts"),
/**
* Permission for user to see other accounts.
*/
SEE_OTHER_ACCOUNTS("authme.player.seeotheraccounts"),
/**
* Permission to use all player (non-admin) commands.
*/
PLAYER_ALL("authme.player.*");
/**
* The permission node.
*/
private String node;
/**
* Constructor.
*
* @param node Permission node.
*/
PlayerPermission(String node) {
this.node = node;
}
@Override
public String getNode() {
return node;
}
@Override
public PermissionNode getWildcardNode() {
return PLAYER_ALL;
}
}

View File

@ -1,52 +0,0 @@
package fr.xephi.authme.permission;
/**
* AuthMe user permission nodes.
*/
public enum UserPermission implements PermissionNode {
BYPASS_ANTIBOT("authme.bypassantibot"),
IS_VIP("authme.vip"),
LOGIN("authme.login"),
LOGOUT("authme.logout"),
REGISTER("authme.register"),
UNREGISTER("authme.unregister"),
CHANGE_PASSWORD("authme.changepassword"),
ADD_EMAIL("authme.email.add"),
CHANGE_EMAIL("authme.email.change"),
RECOVER_EMAIL("authme.email.recover"),
CAPTCHA("authme.captcha"),
CONVERTER("authme.converter"),
CAN_LOGIN_BE_FORCED("authme.canbeforced"),
BYPASS_FORCE_SURVIVAL("authme.bypassforcesurvival"),
ALLOW_MULTIPLE_ACCOUNTS("authme.allow2accounts"),
SEE_OTHER_ACCOUNTS("authme.seeOtherAccounts");
private String node;
@Override
public String getNode() {
return node;
}
UserPermission(String node) {
this.node = node;
}
}

View File

@ -4,9 +4,9 @@ import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.permission.UserPermission;
import fr.xephi.authme.settings.MessageKey;
import fr.xephi.authme.settings.Messages;
import fr.xephi.authme.permission.PlayerPermission;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages;
import fr.xephi.authme.settings.Settings;
import org.bukkit.entity.Player;
@ -39,7 +39,7 @@ public class AsyncChangeEmail {
String playerName = player.getName().toLowerCase();
if (Settings.getmaxRegPerEmail > 0) {
if (!plugin.getPermissionsManager().hasPermission(player, UserPermission.ALLOW_MULTIPLE_ACCOUNTS)
if (!plugin.getPermissionsManager().hasPermission(player, PlayerPermission.ALLOW_MULTIPLE_ACCOUNTS)
&& plugin.database.getAllAuthsByEmail(newEmail).size() >= Settings.getmaxRegPerEmail) {
m.send(player, MessageKey.MAX_REGISTER_EXCEEDED);
return;

View File

@ -10,9 +10,9 @@ import fr.xephi.authme.events.FirstSpawnTeleportEvent;
import fr.xephi.authme.events.ProtectInventoryEvent;
import fr.xephi.authme.events.SpawnTeleportEvent;
import fr.xephi.authme.listener.AuthMePlayerListener;
import fr.xephi.authme.permission.UserPermission;
import fr.xephi.authme.settings.MessageKey;
import fr.xephi.authme.settings.Messages;
import fr.xephi.authme.permission.PlayerPermission;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.Spawn;
import fr.xephi.authme.task.MessageTask;
@ -50,33 +50,16 @@ public class AsynchronousJoin {
}
public void process() {
if (AuthMePlayerListener.gameMode.containsKey(name))
AuthMePlayerListener.gameMode.remove(name);
AuthMePlayerListener.gameMode.putIfAbsent(name, player.getGameMode());
if (Utils.isNPC(player) || Utils.isUnrestricted(player)) {
if (Utils.isUnrestricted(player)) {
return;
}
AuthMePlayerListener.gameMode.put(name, player.getGameMode());
if (plugin.ess != null && Settings.disableSocialSpy) {
plugin.ess.getUser(player).setSocialSpyEnabled(false);
}
if (!plugin.canConnect()) {
final GameMode gM = AuthMePlayerListener.gameMode.get(name);
sched.scheduleSyncDelayedTask(plugin, new Runnable() {
@Override
public void run() {
AuthMePlayerListener.causeByAuthMe.putIfAbsent(name, true);
player.setGameMode(gM);
player.kickPlayer("Server is loading, please wait before joining!");
}
});
return;
}
final String ip = plugin.getIP(player);
if (Settings.isAllowRestrictedIp && !Settings.getRestrictedIp(name, ip)) {
final GameMode gM = AuthMePlayerListener.gameMode.get(name);
@ -95,7 +78,7 @@ public class AsynchronousJoin {
return;
}
if (Settings.getMaxJoinPerIp > 0
&& !plugin.getPermissionsManager().hasPermission(player, UserPermission.ALLOW_MULTIPLE_ACCOUNTS)
&& !plugin.getPermissionsManager().hasPermission(player, PlayerPermission.ALLOW_MULTIPLE_ACCOUNTS)
&& !ip.equalsIgnoreCase("127.0.0.1")
&& !ip.equalsIgnoreCase("localhost")) {
if (plugin.hasJoinedIp(player.getName(), ip)) {
@ -238,7 +221,7 @@ public class AsynchronousJoin {
PlayerCache.getInstance().removePlayer(name);
if (auth != null && auth.getIp().equals(ip)) {
m.send(player, MessageKey.SESSION_RECONNECTION);
plugin.management.performLogin(player, "dontneed", true);
plugin.getManagement().performLogin(player, "dontneed", true);
return;
} else if (Settings.sessionExpireOnIpChange) {
m.send(player, MessageKey.SESSION_EXPIRED);
@ -253,8 +236,11 @@ public class AsynchronousJoin {
? m.retrieve(MessageKey.REGISTER_EMAIL_MESSAGE)
: m.retrieve(MessageKey.REGISTER_MESSAGE);
}
BukkitTask msgTask = sched.runTaskAsynchronously(plugin, new MessageTask(plugin, name, msg, msgInterval));
LimboCache.getInstance().getLimboPlayer(name).setMessageTaskId(msgTask);
if (LimboCache.getInstance().getLimboPlayer(name) != null)
{
BukkitTask msgTask = sched.runTaskAsynchronously(plugin, new MessageTask(plugin, name, msg, msgInterval));
LimboCache.getInstance().getLimboPlayer(name).setMessageTaskId(msgTask);
}
}
private boolean needFirstSpawn() {

View File

@ -8,11 +8,11 @@ import fr.xephi.authme.cache.limbo.LimboCache;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.events.AuthMeAsyncPreLoginEvent;
import fr.xephi.authme.listener.AuthMePlayerListener;
import fr.xephi.authme.permission.UserPermission;
import fr.xephi.authme.permission.PlayerPermission;
import fr.xephi.authme.security.PasswordSecurity;
import fr.xephi.authme.security.RandomString;
import fr.xephi.authme.settings.MessageKey;
import fr.xephi.authme.settings.Messages;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.task.MessageTask;
import fr.xephi.authme.util.Utils;
@ -80,15 +80,12 @@ public class AsynchronousLogin {
plugin.captcha.remove(name);
plugin.captcha.putIfAbsent(name, i);
}
if (plugin.captcha.containsKey(name) && plugin.captcha.get(name) >= Settings.maxLoginTry) {
plugin.cap.put(name, rdm.nextString());
if (plugin.captcha.containsKey(name) && plugin.captcha.get(name) > Settings.maxLoginTry) {
plugin.cap.putIfAbsent(name, rdm.nextString());
for (String s : m.retrieve(MessageKey.USAGE_CAPTCHA)) {
player.sendMessage(s.replace("THE_CAPTCHA", plugin.cap.get(name)).replace("<theCaptcha>", plugin.cap.get(name)));
}
return true;
} else if (plugin.captcha.containsKey(name) && plugin.captcha.get(name) >= Settings.maxLoginTry) {
plugin.captcha.remove(name);
plugin.cap.remove(name);
}
}
return false;
@ -120,7 +117,7 @@ public class AsynchronousLogin {
}
return null;
}
if (Settings.getMaxLoginPerIp > 0 && !plugin.getPermissionsManager().hasPermission(player, UserPermission.ALLOW_MULTIPLE_ACCOUNTS) && !getIP().equalsIgnoreCase("127.0.0.1") && !getIP().equalsIgnoreCase("localhost")) {
if (Settings.getMaxLoginPerIp > 0 && !plugin.getPermissionsManager().hasPermission(player, PlayerPermission.ALLOW_MULTIPLE_ACCOUNTS) && !getIP().equalsIgnoreCase("127.0.0.1") && !getIP().equalsIgnoreCase("localhost")) {
if (plugin.isLoggedIp(name, getIP())) {
m.send(player, MessageKey.ALREADY_LOGGED_IN_ERROR);
return null;
@ -135,6 +132,13 @@ public class AsynchronousLogin {
m.send(player, MessageKey.ACCOUNT_NOT_ACTIVATED);
return null;
}
if (Settings.preventOtherCase && !player.getName().equals(pAuth.getRealName()))
{
// TODO: Add a message like : MessageKey.INVALID_NAME_CASE
m.send(player, MessageKey.USERNAME_ALREADY_ONLINE_ERROR);
return null;
}
AuthMeAsyncPreLoginEvent event = new AuthMeAsyncPreLoginEvent(player);
Bukkit.getServer().getPluginManager().callEvent(event);
if (!event.canLogin())
@ -268,7 +272,7 @@ public class AsynchronousLogin {
* uuidaccounts + "."; } }
*/
for (Player player : Utils.getOnlinePlayers()) {
if (plugin.getPermissionsManager().hasPermission(player, UserPermission.SEE_OTHER_ACCOUNTS)) {
if (plugin.getPermissionsManager().hasPermission(player, PlayerPermission.SEE_OTHER_ACCOUNTS)) {
player.sendMessage("[AuthMe] The player " + auth.getNickname() + " has " + auths.size() + " accounts");
player.sendMessage(message.toString());
// player.sendMessage(uuidaccounts.replace("%size%",

View File

@ -5,8 +5,8 @@ import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.cache.limbo.LimboCache;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.settings.MessageKey;
import fr.xephi.authme.settings.Messages;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages;
import fr.xephi.authme.util.Utils;
import fr.xephi.authme.util.Utils.GroupType;
import org.bukkit.entity.Player;

View File

@ -4,8 +4,8 @@ import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.cache.limbo.LimboCache;
import fr.xephi.authme.events.LogoutEvent;
import fr.xephi.authme.settings.MessageKey;
import fr.xephi.authme.settings.Messages;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.task.MessageTask;
import fr.xephi.authme.task.TimeoutTask;

View File

@ -47,7 +47,7 @@ public class AsynchronousQuit {
public void process() {
if (player == null)
return;
if (Utils.isNPC(player) || Utils.isUnrestricted(player)) {
if (Utils.isUnrestricted(player)) {
return;
}

View File

@ -5,16 +5,13 @@ import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.permission.UserPermission;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages;
import fr.xephi.authme.permission.PlayerPermission;
import fr.xephi.authme.security.PasswordSecurity;
import fr.xephi.authme.settings.MessageKey;
import fr.xephi.authme.settings.Messages;
import fr.xephi.authme.settings.Settings;
import org.bukkit.entity.Player;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
/**
*/
public class AsyncRegister {
@ -22,7 +19,8 @@ public class AsyncRegister {
protected final Player player;
protected final String name;
protected final String password;
protected String email = "";
private final String ip;
private String email = "";
private final AuthMe plugin;
private final DataSource database;
private final Messages m;
@ -35,13 +33,10 @@ public class AsyncRegister {
this.email = email;
this.plugin = plugin;
this.database = data;
this.ip = plugin.getIP(player);
}
protected String getIp() {
return plugin.getIP(player);
}
protected boolean preRegisterCheck() throws Exception {
private boolean preRegisterCheck() throws Exception {
String passLow = password.toLowerCase();
if (PlayerCache.getInstance().isAuthenticated(name)) {
m.send(player, MessageKey.ALREADY_LOGGED_IN_ERROR);
@ -65,10 +60,10 @@ public class AsyncRegister {
m.send(player, MessageKey.NAME_ALREADY_REGISTERED);
return false;
} else if (Settings.getmaxRegPerIp > 0
&& !plugin.getPermissionsManager().hasPermission(player, UserPermission.ALLOW_MULTIPLE_ACCOUNTS)
&& database.getAllAuthsByIp(getIp()).size() >= Settings.getmaxRegPerIp
&& !getIp().equalsIgnoreCase("127.0.0.1")
&& !getIp().equalsIgnoreCase("localhost")) {
&& !plugin.getPermissionsManager().hasPermission(player, PlayerPermission.ALLOW_MULTIPLE_ACCOUNTS)
&& !ip.equalsIgnoreCase("127.0.0.1")
&& !ip.equalsIgnoreCase("localhost")
&& database.getAllAuthsByIp(ip).size() >= Settings.getmaxRegPerIp) {
m.send(player, MessageKey.MAX_REGISTER_EXCEEDED);
return false;
}
@ -81,16 +76,10 @@ public class AsyncRegister {
return;
}
if (!email.isEmpty() && !email.equals("")) {
if (Settings.getmaxRegPerEmail > 0
&& !plugin.getPermissionsManager().hasPermission(player, UserPermission.ALLOW_MULTIPLE_ACCOUNTS)
&& database.getAllAuthsByEmail(email).size() >= Settings.getmaxRegPerEmail) {
m.send(player, MessageKey.MAX_REGISTER_EXCEEDED);
return;
}
emailRegister();
return;
} else {
passwordRegister();
}
passwordRegister();
} catch (Exception e) {
ConsoleLogger.showError(e.getMessage());
ConsoleLogger.writeStackTrace(e);
@ -98,20 +87,32 @@ public class AsyncRegister {
}
}
protected void emailRegister() throws Exception {
private void emailRegister() throws Exception {
if (Settings.getmaxRegPerEmail > 0
&& !plugin.getPermissionsManager().hasPermission(player, UserPermission.ALLOW_MULTIPLE_ACCOUNTS)
&& database.getAllAuthsByEmail(email).size() >= Settings.getmaxRegPerEmail) {
&& !plugin.getPermissionsManager().hasPermission(player, PlayerPermission.ALLOW_MULTIPLE_ACCOUNTS)
&& database.getAllAuthsByEmail(email).size() >= Settings.getmaxRegPerEmail) {
m.send(player, MessageKey.MAX_REGISTER_EXCEEDED);
return;
}
PlayerAuth auth;
final String hashNew = PasswordSecurity.getHash(Settings.getPasswordHash, password, name);
auth = new PlayerAuth(name, hashNew, getIp(), 0, (int) player.getLocation().getX(), (int) player.getLocation().getY(), (int) player.getLocation().getZ(), player.getLocation().getWorld().getName(), email, player.getName());
if (PasswordSecurity.userSalt.containsKey(name)) {
auth.setSalt(PasswordSecurity.userSalt.get(name));
final String salt = PasswordSecurity.userSalt.get(name);
PlayerAuth auth = PlayerAuth.builder()
.name(name)
.realName(player.getName())
.hash(hashNew)
.ip(ip)
.locWorld(player.getLocation().getWorld().getName())
.locX(player.getLocation().getX())
.locY(player.getLocation().getY())
.locZ(player.getLocation().getZ())
.email(email)
.salt(salt != null ? salt : "")
.build();
if (!database.saveAuth(auth)) {
m.send(player, MessageKey.ERROR);
return;
}
database.saveAuth(auth);
database.updateEmail(auth);
database.updateSession(auth);
plugin.mail.main(auth, password);
@ -120,21 +121,21 @@ public class AsyncRegister {
}
protected void passwordRegister() {
PlayerAuth auth;
String hash;
try {
hash = PasswordSecurity.getHash(Settings.getPasswordHash, password, name);
} catch (NoSuchAlgorithmException e) {
ConsoleLogger.showError(e.getMessage());
m.send(player, MessageKey.ERROR);
return;
}
if (Settings.getMySQLColumnSalt.isEmpty() && !PasswordSecurity.userSalt.containsKey(name)) {
auth = new PlayerAuth(name, hash, getIp(), new Date().getTime(), "your@email.com", player.getName());
} else {
auth = new PlayerAuth(name, hash, PasswordSecurity.userSalt.get(name), getIp(), new Date().getTime(), player.getName());
}
private void passwordRegister() throws Exception {
final String hashNew = PasswordSecurity.getHash(Settings.getPasswordHash, password, name);
final String salt = PasswordSecurity.userSalt.get(name);
PlayerAuth auth = PlayerAuth.builder()
.name(name)
.realName(player.getName())
.hash(hashNew)
.ip(ip)
.locWorld(player.getLocation().getWorld().getName())
.locX(player.getLocation().getX())
.locY(player.getLocation().getY())
.locZ(player.getLocation().getZ())
.salt(salt != null ? salt : "")
.build();
if (!database.saveAuth(auth)) {
m.send(player, MessageKey.ERROR);
return;

View File

@ -4,8 +4,8 @@ import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.cache.limbo.LimboCache;
import fr.xephi.authme.cache.limbo.LimboPlayer;
import fr.xephi.authme.settings.MessageKey;
import fr.xephi.authme.settings.Messages;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.task.MessageTask;
import fr.xephi.authme.task.TimeoutTask;

View File

@ -6,8 +6,8 @@ import fr.xephi.authme.cache.limbo.LimboCache;
import fr.xephi.authme.cache.limbo.LimboPlayer;
import fr.xephi.authme.events.LoginEvent;
import fr.xephi.authme.events.RestoreInventoryEvent;
import fr.xephi.authme.settings.MessageKey;
import fr.xephi.authme.settings.Messages;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.task.MessageTask;
import fr.xephi.authme.task.TimeoutTask;
@ -41,15 +41,13 @@ public class ProcessSyncronousPasswordRegister implements Runnable {
this.plugin = plugin;
}
protected void forceCommands() {
private void forceCommands() {
for (String command : Settings.forceRegisterCommands) {
try {
player.performCommand(command.replace("%p", player.getName()));
} catch (Exception ignored) {
}
player.performCommand(command.replace("%p", player.getName()));
}
for (String command : Settings.forceRegisterCommandsAsConsole) {
Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), command.replace("%p", player.getName()));
Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(),
command.replace("%p", player.getName()));
}
}
@ -58,20 +56,21 @@ public class ProcessSyncronousPasswordRegister implements Runnable {
*
* @param player Player
*/
protected void forceLogin(Player player) {
private void forceLogin(Player player) {
Utils.teleportToSpawn(player);
if (LimboCache.getInstance().hasLimboPlayer(name))
LimboCache.getInstance().deleteLimboPlayer(name);
LimboCache.getInstance().addLimboPlayer(player);
LimboCache cache = LimboCache.getInstance();
cache.updateLimboPlayer(player);
int delay = Settings.getRegistrationTimeout * 20;
int interval = Settings.getWarnMessageInterval;
BukkitScheduler sched = plugin.getServer().getScheduler();
BukkitTask task;
if (delay != 0) {
BukkitTask id = sched.runTaskLaterAsynchronously(plugin, new TimeoutTask(plugin, name, player), delay);
LimboCache.getInstance().getLimboPlayer(name).setTimeoutTaskId(id);
task = sched.runTaskLaterAsynchronously(plugin, new TimeoutTask(plugin, name, player), delay);
cache.getLimboPlayer(name).setTimeoutTaskId(task);
}
BukkitTask msgT = sched.runTaskAsynchronously(plugin, new MessageTask(plugin, name, m.retrieve(MessageKey.LOGIN_MESSAGE), interval));
LimboCache.getInstance().getLimboPlayer(name).setMessageTaskId(msgT);
task = sched.runTaskAsynchronously(plugin, new MessageTask(plugin, name,
m.retrieve(MessageKey.LOGIN_MESSAGE), interval));
cache.getLimboPlayer(name).setMessageTaskId(task);
if (player.isInsideVehicle() && player.getVehicle() != null) {
player.getVehicle().eject();
}
@ -97,33 +96,39 @@ public class ProcessSyncronousPasswordRegister implements Runnable {
}
}
limbo.getTimeoutTaskId().cancel();
limbo.getMessageTaskId().cancel();
LimboCache.getInstance().deleteLimboPlayer(name);
}
if (!Settings.getRegisteredGroup.isEmpty()) {
Utils.setGroup(player, Utils.GroupType.REGISTERED);
}
m.send(player, MessageKey.REGISTER_SUCCESS);
if (!Settings.getmailAccount.isEmpty())
if (!Settings.getmailAccount.isEmpty()) {
m.send(player, MessageKey.ADD_EMAIL_MESSAGE);
}
if (player.getGameMode() != GameMode.CREATIVE && !Settings.isMovementAllowed) {
player.setAllowFlight(false);
player.setFlying(false);
}
if (Settings.applyBlindEffect)
if (Settings.applyBlindEffect) {
player.removePotionEffect(PotionEffectType.BLINDNESS);
if (!Settings.isMovementAllowed && Settings.isRemoveSpeedEnabled) {
player.setWalkSpeed(0.2f);
player.setFlySpeed(0.1f);
}
if (!Settings.isMovementAllowed && Settings.isRemoveSpeedEnabled) {
player.setWalkSpeed(0.0f);
player.setFlySpeed(0.0f);
}
// The LoginEvent now fires (as intended) after everything is processed
plugin.getServer().getPluginManager().callEvent(new LoginEvent(player, true));
player.saveData();
if (!Settings.noConsoleSpam)
if (!Settings.noConsoleSpam) {
ConsoleLogger.info(player.getName() + " registered " + plugin.getIP(player));
}
// Kick Player after Registration is enabled, kick the player
if (Settings.forceRegKick) {
@ -138,7 +143,7 @@ public class ProcessSyncronousPasswordRegister implements Runnable {
}
// Register is finish and player is logged, display welcome message
if (Settings.useWelcomeMessage)
if (Settings.useWelcomeMessage) {
if (Settings.broadcastWelcomeMessage) {
for (String s : Settings.welcomeMsg) {
plugin.getServer().broadcastMessage(plugin.replaceAllInfo(s, player));
@ -148,6 +153,7 @@ public class ProcessSyncronousPasswordRegister implements Runnable {
player.sendMessage(plugin.replaceAllInfo(s, player));
}
}
}
// Register is now finish , we can force all commands
forceCommands();

View File

@ -7,8 +7,8 @@ import fr.xephi.authme.cache.backup.JsonCache;
import fr.xephi.authme.cache.limbo.LimboCache;
import fr.xephi.authme.cache.limbo.LimboPlayer;
import fr.xephi.authme.security.PasswordSecurity;
import fr.xephi.authme.settings.MessageKey;
import fr.xephi.authme.settings.Messages;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.task.MessageTask;
import fr.xephi.authme.task.TimeoutTask;

View File

@ -1,115 +0,0 @@
package fr.xephi.authme.settings;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.util.StringUtils;
import org.bukkit.command.CommandSender;
import java.io.File;
/**
* Class for retrieving and sending translatable messages to players.
*/
// TODO ljacqu 20151124: This class is a weird mix between singleton and POJO
// TODO: change it into POJO
public class Messages extends CustomConfiguration {
/** The section symbol, used in Minecraft for formatting codes. */
private static final String SECTION_SIGN = "\u00a7";
private static Messages singleton;
private String language;
/**
* Constructor for Messages.
*
* @param file the configuration file
* @param lang the code of the language to use
*/
public Messages(File file, String lang) {
super(file);
load();
this.language = lang;
}
public static Messages getInstance() {
if (singleton == null) {
singleton = new Messages(Settings.messageFile, Settings.messagesLanguage);
}
return singleton;
}
/**
* Send the given message code to the player.
*
* @param sender The entity to send the message to
* @param key The key of the message to send
*/
public void send(CommandSender sender, MessageKey key) {
String[] lines = retrieve(key);
for (String line : lines) {
sender.sendMessage(line);
}
}
/**
* Retrieve the message from the text file and return it split by new line as an array.
*
* @param key The message key to retrieve
*
* @return The message split by new lines
*/
public String[] retrieve(MessageKey key) {
return retrieve(key.getKey());
}
/**
* Retrieve the message from the text file.
*
* @param key The message key to retrieve
*
* @return The message from the file
*/
public String retrieveSingle(MessageKey key) {
return StringUtils.join("\n", retrieve(key.getKey()));
}
/**
* Retrieve the message from the configuration file.
*
* @param key The key to retrieve
*
* @return The message
*/
private String[] retrieve(String key) {
if (!Settings.messagesLanguage.equalsIgnoreCase(language)) {
reloadMessages();
}
String message = (String) get(key);
if (message != null) {
return formatMessage(message);
}
// Message is null: log key not being found and send error back as message
String retrievalError = "Error getting message with key '" + key + "'. ";
ConsoleLogger.showError(retrievalError + "Please verify your config file at '"
+ getConfigFile().getName() + "'");
return new String[]{
retrievalError + "Please contact the admin to verify or update the AuthMe messages file."};
}
private static String[] formatMessage(String message) {
// TODO: Check that the codes actually exist, i.e. replace &c but not &y
// TODO: Allow '&' to be retained with the code '&&'
String[] lines = message.split("&n");
for (int i = 0; i < lines.length; ++i) {
// We don't initialize a StringBuilder here because mostly we will only have one entry
lines[i] = lines[i].replace("&", SECTION_SIGN);
}
return lines;
}
public void reloadMessages() {
singleton = new Messages(Settings.messageFile, Settings.messagesLanguage);
}
}

View File

@ -8,7 +8,11 @@ import fr.xephi.authme.security.HashAlgorithm;
import fr.xephi.authme.util.Wrapper;
import org.bukkit.configuration.file.YamlConfiguration;
import com.google.common.base.Charsets;
import com.google.common.io.Files;
import java.io.*;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
@ -17,12 +21,13 @@ import java.util.regex.Pattern;
/**
*/
public final class Settings extends YamlConfiguration {
public final class Settings {
public static final File PLUGIN_FOLDER = Wrapper.getInstance().getDataFolder();
public static final File MODULE_FOLDER = new File(PLUGIN_FOLDER, "modules");
public static final File CACHE_FOLDER = new File(PLUGIN_FOLDER, "cache");
public static final File AUTH_FILE = new File(PLUGIN_FOLDER, "auths.db");
public static final File EMAIL_FILE = new File(PLUGIN_FOLDER, "email.html");
public static final File SETTINGS_FILE = new File(PLUGIN_FOLDER, "config.yml");
public static final File LOG_FILE = new File(PLUGIN_FOLDER, "authme.log");
// This is not an option!
@ -68,7 +73,7 @@ public final class Settings extends YamlConfiguration {
enableProtection, enableAntiBot, recallEmail, useWelcomeMessage,
broadcastWelcomeMessage, forceRegKick, forceRegLogin,
checkVeryGames, delayJoinLeaveMessages, noTeleport, applyBlindEffect,
customAttributes, generateImage, isRemoveSpeedEnabled, isMySQLWebsite;
customAttributes, generateImage, isRemoveSpeedEnabled, preventOtherCase;
public static String helpHeader, getNickRegex, getUnloggedinGroup, getMySQLHost,
getMySQLPort, getMySQLUsername, getMySQLPassword, getMySQLDatabase,
getMySQLTablename, getMySQLColumnName, getMySQLColumnPassword,
@ -116,7 +121,7 @@ public final class Settings extends YamlConfiguration {
if (!exist) {
plugin.saveDefaultConfig();
}
instance.load(SETTINGS_FILE);
configFile.load(SETTINGS_FILE);
if (exist) {
instance.mergeConfig();
}
@ -184,7 +189,12 @@ public final class Settings extends YamlConfiguration {
getMySQLColumnRealName = configFile.getString("DataSource.mySQLRealName", "realname");
getNonActivatedGroup = configFile.getInt("ExternalBoardOptions.nonActivedUserGroup", -1);
unRegisteredGroup = configFile.getString("GroupOptions.UnregisteredPlayerGroup", "");
getUnrestrictedName = configFile.getStringList("settings.unrestrictions.UnrestrictedName");
getUnrestrictedName = new ArrayList<>();
for (String name : configFile.getStringList("settings.unrestrictions.UnrestrictedName")) {
getUnrestrictedName.add(name.toLowerCase());
}
getRegisteredGroup = configFile.getString("GroupOptions.RegisteredPlayerGroup", "");
getEnablePasswordVerifier = configFile.getBoolean("settings.restrictions.enablePasswordVerifier", true);
@ -226,7 +236,7 @@ public final class Settings extends YamlConfiguration {
maxLoginTry = configFile.getInt("Security.captcha.maxLoginTry", 5);
captchaLength = configFile.getInt("Security.captcha.captchaLength", 5);
getMailSubject = configFile.getString("Email.mailSubject", "Your new AuthMe Password");
getMailText = configFile.getString("Email.mailText", "Dear <playername>, <br /><br /> This is your new AuthMe password for the server <br /><br /> <servername> : <br /><br /> <generatedpass><br /><br />Do not forget to change password after login! <br /> /changepassword <generatedpass> newPassword");
getMailText = loadEmailText();
emailRegistration = configFile.getBoolean("settings.registration.enableEmailRegistrationSystem", false);
saltLength = configFile.getInt("settings.security.doubleMD5SaltLength", 8);
getmaxRegPerEmail = configFile.getInt("Email.maxRegPerEmail", 1);
@ -284,20 +294,47 @@ public final class Settings extends YamlConfiguration {
forceRegisterCommandsAsConsole = configFile.getStringList("settings.forceRegisterCommandsAsConsole");
customAttributes = configFile.getBoolean("Hooks.customAttributes");
generateImage = configFile.getBoolean("Email.generateImage", false);
isMySQLWebsite = configFile.getBoolean("DataSource.mySQLWebsite", false);
preventOtherCase = configFile.getBoolean("settings.preventOtherCase", false);
// Load the welcome message
getWelcomeMessage();
}
/**
* Method setValue.
*
* @param key String
* @param value Object
*/
public static void setValue(String key, Object value) {
private static String loadEmailText() {
if (!EMAIL_FILE.exists())
saveDefaultEmailText();
StringBuilder str = new StringBuilder();
try {
BufferedReader in = new BufferedReader(new FileReader(EMAIL_FILE));
String s;
while ((s = in.readLine()) != null)
str.append(s);
in.close();
} catch(IOException e)
{
}
return str.toString();
}
private static void saveDefaultEmailText() {
InputStream file = plugin.getResource("email.html");
StringBuilder str = new StringBuilder();
try {
BufferedReader in = new BufferedReader(new InputStreamReader(file, Charset.forName("utf-8")));
String s;
while ((s = in.readLine()) != null)
str.append(s);
in.close();
Files.touch(EMAIL_FILE);
Files.write(str.toString(), EMAIL_FILE, Charsets.UTF_8);
}
catch(Exception e)
{
}
}
public static void setValue(String key, Object value) {
instance.set(key, value);
save();
}
@ -368,9 +405,9 @@ public final class Settings extends YamlConfiguration {
*/
public static boolean save() {
try {
instance.save(SETTINGS_FILE);
configFile.save(SETTINGS_FILE);
return true;
} catch (Exception ex) {
} catch (IOException ex) {
return false;
}
}
@ -588,7 +625,7 @@ public final class Settings extends YamlConfiguration {
set("VeryGames.enableIpCheck", false);
changes = true;
}
if (getString("settings.restrictions.allowedNicknameCharacters").equals("[a-zA-Z0-9_?]*")) {
if (configFile.getString("settings.restrictions.allowedNicknameCharacters").equals("[a-zA-Z0-9_?]*")) {
set("settings.restrictions.allowedNicknameCharacters", "[a-zA-Z0-9_]*");
changes = true;
}
@ -676,9 +713,17 @@ public final class Settings extends YamlConfiguration {
set("DataSource.mySQLRealName", "realname");
changes = true;
}
if (!contains("DataSource.mySQLQueryCache")) {
set("DataSource.mySQLWebsite", false);
changes = true;
if (!contains("settings.preventOtherCase"))
{
set("settings.preventOtherCase", false);
changes = true;
}
if (contains("Email.mailText"))
{
set("Email.mailText", null);
ConsoleLogger.showError("Remove Email.mailText from config, we now use the email.html file");
}
if (changes) {
@ -687,19 +732,30 @@ public final class Settings extends YamlConfiguration {
}
}
private static boolean contains(String path) {
return configFile.contains(path);
}
// public because it's used in AuthMe at one place
public void set(String path, Object value) {
configFile.set(path, value);
}
/**
* Saves current configuration (plus defaults) to disk.
* <p/>
* <p>
* If defaults and configuration are empty, saves blank file.
*
* @return True if saved successfully
*/
public final boolean saveDefaults() {
options().copyDefaults(true);
options().copyHeader(true);
configFile.options()
.copyDefaults(true)
.copyHeader(true);
boolean success = save();
options().copyDefaults(false);
options().copyHeader(false);
configFile.options()
.copyDefaults(false)
.copyHeader(false);
return success;
}
}

View File

@ -5,8 +5,8 @@ import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.security.PasswordSecurity;
import fr.xephi.authme.settings.MessageKey;
import fr.xephi.authme.settings.Messages;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages;
import fr.xephi.authme.settings.Settings;
import org.bukkit.entity.Player;

View File

@ -2,8 +2,8 @@ package fr.xephi.authme.task;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.settings.MessageKey;
import fr.xephi.authme.settings.Messages;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;

View File

@ -0,0 +1,52 @@
package fr.xephi.authme.util;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* Utils class for collections.
*/
public final class CollectionUtils {
private CollectionUtils() {
}
/**
* Get a range from a list based on start and count parameters in a safe way.
*
* @param start The start index
* @param count The number of elements to add
*
* @return The sublist consisting at most of {@code count} elements (less if the parameters
* exceed the size of the list)
*/
public static <T> List<T> getRange(List<T> list, int start, int count) {
if (start >= list.size() || count <= 0) {
return new ArrayList<>();
} else if (start < 0) {
start = 0;
}
int end = Math.min(list.size(), start + count);
return list.subList(start, end);
}
/**
* Get all elements from a list starting from the given index.
*
* @param start The start index
*
* @return The sublist of all elements from index {@code start} and on; empty list
* if the start index exceeds the list's size
*/
public static <T> List<T> getRange(List<T> list, int start) {
if (start >= list.size()) {
return new ArrayList<>();
}
return getRange(list, start, list.size() - start);
}
public static <T> boolean isEmpty(Collection<T> coll) {
return coll == null || coll.isEmpty();
}
}

View File

@ -13,8 +13,6 @@ import java.util.Arrays;
*/
public final class StringUtils {
public static final String newline = System.getProperty("line.separator");
private StringUtils() {
// Utility class
}
@ -29,8 +27,9 @@ public final class StringUtils {
*/
public static double getDifference(String first, String second) {
// Make sure the strings are valid.
if (first == null || second == null)
if (first == null || second == null) {
return 1.0;
}
// Create a string similarity service instance, to allow comparison
StringSimilarityService service = new StringSimilarityServiceImpl(new LevenshteinDistanceStrategy());

View File

@ -7,7 +7,7 @@ import fr.xephi.authme.cache.limbo.LimboCache;
import fr.xephi.authme.cache.limbo.LimboPlayer;
import fr.xephi.authme.events.AuthMeTeleportEvent;
import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.permission.UserPermission;
import fr.xephi.authme.permission.PlayerPermission;
import fr.xephi.authme.settings.Settings;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
@ -137,7 +137,7 @@ public final class Utils {
// TODO: Move to a Manager
public static boolean checkAuth(Player player) {
if (player == null || Utils.isUnrestricted(player) || Utils.isNPC(player)) {
if (player == null || Utils.isUnrestricted(player)) {
return true;
}
@ -156,8 +156,9 @@ public final class Utils {
}
public static boolean isUnrestricted(Player player) {
return Settings.isAllowRestrictedIp && !Settings.getUnrestrictedName.isEmpty()
&& (Settings.getUnrestrictedName.contains(player.getName()));
return Settings.isAllowRestrictedIp
&& !Settings.getUnrestrictedName.isEmpty()
&& (Settings.getUnrestrictedName.contains(player.getName().toLowerCase()));
}
/**
@ -201,7 +202,7 @@ public final class Utils {
* @param player the player to modify.
*/
public static void forceGM(Player player) {
if (!plugin.getPermissionsManager().hasPermission(player, UserPermission.BYPASS_FORCE_SURVIVAL)) {
if (!plugin.getPermissionsManager().hasPermission(player, PlayerPermission.BYPASS_FORCE_SURVIVAL)) {
player.setGameMode(GameMode.SURVIVAL);
}
}

View File

@ -2,7 +2,7 @@ package fr.xephi.authme.util;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.settings.Messages;
import fr.xephi.authme.output.Messages;
import org.bukkit.Bukkit;
import org.bukkit.Server;
import org.bukkit.scheduler.BukkitScheduler;

View File

@ -259,6 +259,9 @@ settings:
delayJoinLeaveMessages: true
# Do we need to add potion effect Blinding before login/register ?
applyBlindEffect: false
# Do we need to prevent people to login without another case ?
# Xephi is registered, also Xephi can login, but not XEPHI/xephi/XePhI
preventOtherCase: false
ExternalBoardOptions:
# MySQL column for the salt , needed for some forum/cms support
mySQLColumnSalt: ''
@ -388,12 +391,14 @@ Protection:
# Enable some servers protection ( country based login, antibot )
enableProtection: false
# Countries allowed to join the server and register, see http://dev.bukkit.org/bukkit-plugins/authme-reloaded/pages/countries-codes/ for countries' codes
# PLEASE USE QUOTES!
countries:
- US
- GB
- 'US'
- 'GB'
# Countries blacklisted automatically ( without any needed to enable protection )
# PLEASE USE QUOTES!
countriesBlacklist:
- A1
- 'A1'
# Do we need to enable automatic antibot system?
enableAntiBot: false
# Max number of player allowed to login in 5 secs before enable AntiBot system automatically

View File

@ -0,0 +1,16 @@
<h1>
Dear %playername%,
</h1>
<p>
This is your new AuthMe password for the server %servername%:
%generatedpass%
%image%
Do not forget to change password after login!
/changepassword %generatedpass% newPassword'
See you on %servername%!
</p>

View File

@ -1,3 +1,4 @@
kick_antibot: 'AntiBot protection mode is enabled! You have to wait some minutes before joining the server.'
unknown_user: '&cCan''t find the requested user in the database!'
unsafe_spawn: '&cYour quit location was unsafe, you have been teleported to the world''s spawnpoint.'
not_logged_in: '&cYou''re not logged in!'

View File

@ -0,0 +1,135 @@
package fr.xephi.authme.command;
import fr.xephi.authme.permission.DefaultPermission;
import fr.xephi.authme.permission.PlayerPermission;
import fr.xephi.authme.util.WrapperMock;
import org.bukkit.command.CommandSender;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.stringContainsInOrder;
import static org.mockito.BDDMockito.given;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
/**
* Test for {@link CommandHandler}.
*/
public class CommandHandlerTest {
private static Set<CommandDescription> commands;
private static CommandHandler handler;
@BeforeClass
public static void setUpCommandHandler() {
WrapperMock.createInstance();
CommandDescription authMeBase = createCommand(null, null, singletonList("authme"));
createCommand(PlayerPermission.LOGIN, authMeBase, singletonList("login"), newArgument("password", false));
createCommand(PlayerPermission.LOGIN, authMeBase, asList("register", "reg"),
newArgument("password", false), newArgument("confirmation", false));
CommandDescription testBase = createCommand(null, null, singletonList("test"), newArgument("test", true));
commands = new HashSet<>(asList(authMeBase, testBase));
handler = new CommandHandler(commands);
}
@Test
@Ignore
public void shouldForwardCommandToExecutable() {
// given
CommandSender sender = Mockito.mock(CommandSender.class);
given(sender.isOp()).willReturn(true);
String bukkitLabel = "authme";
String[] args = {"login", "password"};
// when
handler.processCommand(sender, bukkitLabel, args);
// then
final CommandDescription loginCmd = getChildWithLabel("login", getCommandWithLabel("authme", commands));
verify(sender, never()).sendMessage(anyString());
verify(loginCmd.getExecutableCommand()).executeCommand(
eq(sender), any(CommandParts.class), any(CommandParts.class));
}
@Test
@Ignore // TODO ljacqu Fix test --> command classes too tightly coupled at the moment
public void shouldRejectCommandWithTooManyArguments() {
// given
CommandSender sender = Mockito.mock(CommandSender.class);
given(sender.isOp()).willReturn(true);
String bukkitLabel = "authme";
String[] args = {"login", "password", "__unneededArgument__"};
// when
boolean result = handler.processCommand(sender, bukkitLabel, args);
// then
assertThat(result, equalTo(true));
assertSenderGotMessageContaining("help", sender);
}
private static CommandDescription createCommand(PlayerPermission permission, CommandDescription parent,
List<String> labels, CommandArgumentDescription... arguments) {
CommandDescription.CommandBuilder command = CommandDescription.builder()
.labels(labels)
.parent(parent)
.permissions(DefaultPermission.OP_ONLY, permission)
.description("Test")
.detailedDescription("Test command")
.executableCommand(mock(ExecutableCommand.class));
if (arguments != null && arguments.length > 0) {
for (CommandArgumentDescription argument : arguments) {
command.withArgument(argument.getLabel(), "Test description", argument.isOptional());
}
}
return command.build();
}
private static CommandArgumentDescription newArgument(String label, boolean isOptional) {
return new CommandArgumentDescription(label, "Test description", isOptional);
}
private void assertSenderGotMessageContaining(String text, CommandSender sender) {
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
verify(sender).sendMessage(captor.capture());
assertThat(captor.getValue(), stringContainsInOrder(text));
}
private static CommandDescription getCommandWithLabel(String label, Collection<CommandDescription> commands) {
for (CommandDescription command : commands) {
if (command.getLabels().contains(label)) {
return command;
}
}
return null;
}
private static CommandDescription getChildWithLabel(String label, CommandDescription command) {
for (CommandDescription child : command.getChildren()) {
if (child.getLabels().contains(label)) {
return child;
}
}
return null;
}
}

View File

@ -1,16 +1,23 @@
package fr.xephi.authme.command;
import fr.xephi.authme.permission.AdminPermission;
import fr.xephi.authme.permission.PermissionNode;
import fr.xephi.authme.util.StringUtils;
import fr.xephi.authme.util.WrapperMock;
import org.junit.BeforeClass;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
import static fr.xephi.authme.permission.DefaultPermission.OP_ONLY;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.nullValue;
@ -18,9 +25,9 @@ import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
/**
* Test for {@link CommandManager}, especially to guarantee the integrity of the defined commands.
* Test for {@link CommandInitializer} to guarantee the integrity of the defined commands.
*/
public class CommandManagerTest {
public class CommandInitializerTest {
/**
* Defines the maximum allowed depths for nesting CommandDescription instances.
@ -28,24 +35,21 @@ public class CommandManagerTest {
*/
private static int MAX_ALLOWED_DEPTH = 1;
private static CommandManager manager;
private static Set<CommandDescription> commands;
@BeforeClass
public static void initializeCommandManager() {
manager = new CommandManager(true);
WrapperMock.createInstance();
commands = CommandInitializer.getBaseCommands();
}
@Test
public void shouldInitializeCommands() {
// given/when
int commandCount = manager.getCommandDescriptionCount();
List<CommandDescription> commands = manager.getCommandDescriptions();
// then
// given/when/then
// It obviously doesn't make sense to test much of the concrete data
// that is being initialized; we just want to guarantee with this test
// that data is indeed being initialized and we take a few "probes"
assertThat(commandCount, equalTo(9));
assertThat(commands.size(), equalTo(9));
assertThat(commandsIncludeLabel(commands, "authme"), equalTo(true));
assertThat(commandsIncludeLabel(commands, "register"), equalTo(true));
assertThat(commandsIncludeLabel(commands, "help"), equalTo(false));
@ -62,7 +66,7 @@ public class CommandManagerTest {
};
// when/then
walkThroughCommands(manager.getCommandDescriptions(), descriptionTester);
walkThroughCommands(commands, descriptionTester);
}
/** Ensure that all children of a command stored the parent. */
@ -84,7 +88,28 @@ public class CommandManagerTest {
};
// when/then
walkThroughCommands(manager.getCommandDescriptions(), connectionTester);
walkThroughCommands(commands, connectionTester);
}
@Test
public void shouldUseProperLowerCaseLabels() {
// given
final Pattern invalidPattern = Pattern.compile("\\s");
BiConsumer labelFormatTester = new BiConsumer() {
@Override
public void accept(CommandDescription command, int depth) {
for (String label : command.getLabels()) {
if (!label.equals(label.toLowerCase())) {
fail("Label '" + label + "' should be lowercase");
} else if (invalidPattern.matcher(label).matches()) {
fail("Label '" + label + "' has whitespace");
}
}
}
};
// when/then
walkThroughCommands(commands, labelFormatTester);
}
@Test
@ -105,7 +130,7 @@ public class CommandManagerTest {
};
// when/then
walkThroughCommands(manager.getCommandDescriptions(), uniqueMappingTester);
walkThroughCommands(commands, uniqueMappingTester);
}
/**
@ -132,7 +157,7 @@ public class CommandManagerTest {
};
// when/then
walkThroughCommands(manager.getCommandDescriptions(), descriptionTester);
walkThroughCommands(commands, descriptionTester);
}
/**
@ -143,7 +168,6 @@ public class CommandManagerTest {
public void shouldNotHaveMultipleInstancesOfSameExecutableCommandSubType() {
// given
final Map<Class<? extends ExecutableCommand>, ExecutableCommand> implementations = new HashMap<>();
CommandManager manager = new CommandManager(true);
BiConsumer descriptionTester = new BiConsumer() {
@Override
public void accept(CommandDescription command, int depth) {
@ -160,10 +184,7 @@ public class CommandManagerTest {
}
};
// when
List<CommandDescription> commands = manager.getCommandDescriptions();
// then
// when/then
walkThroughCommands(commands, descriptionTester);
}
@ -186,7 +207,7 @@ public class CommandManagerTest {
};
// when/then
walkThroughCommands(manager.getCommandDescriptions(), argumentOrderTester);
walkThroughCommands(commands, argumentOrderTester);
}
/**
@ -209,18 +230,54 @@ public class CommandManagerTest {
};
// when/then
walkThroughCommands(manager.getCommandDescriptions(), noArgumentForParentChecker);
walkThroughCommands(commands, noArgumentForParentChecker);
}
/**
* Test that commands defined with the OP_ONLY default permission have at least one admin permission node.
*/
@Test
public void shouldNotHavePlayerPermissionIfDefaultsToOpOnly() {
// given
BiConsumer adminPermissionChecker = new BiConsumer() {
// The only exception to this check is the force login command, which should default to OP_ONLY
// but semantically it is a player permission
final List<String> forceLoginLabels = Arrays.asList("forcelogin", "login");
@Override
public void accept(CommandDescription command, int depth) {
CommandPermissions permissions = command.getCommandPermissions();
if (permissions != null && OP_ONLY.equals(permissions.getDefaultPermission())) {
if (!hasAdminNode(permissions) && !command.getLabels().equals(forceLoginLabels)) {
fail("The command with labels " + command.getLabels() + " has OP_ONLY default "
+ "permission but no permission node on admin level");
}
}
}
private boolean hasAdminNode(CommandPermissions permissions) {
for (PermissionNode node : permissions.getPermissionNodes()) {
if (node instanceof AdminPermission) {
return true;
}
}
return false;
}
};
// when/then
walkThroughCommands(commands, adminPermissionChecker);
}
// ------------
// Helper methods
// ------------
private static void walkThroughCommands(List<CommandDescription> commands, BiConsumer consumer) {
private static void walkThroughCommands(Collection<CommandDescription> commands, BiConsumer consumer) {
walkThroughCommands(commands, consumer, 0);
}
private static void walkThroughCommands(List<CommandDescription> commands, BiConsumer consumer, int depth) {
private static void walkThroughCommands(Collection<CommandDescription> commands, BiConsumer consumer, int depth) {
for (CommandDescription command : commands) {
consumer.accept(command, depth);
if (command.hasChildren()) {
@ -243,12 +300,12 @@ public class CommandManagerTest {
}
/**
* Get the absolute label that a command defines. Note: Assumes that only the passed command might have
* Get the absolute binding that a command defines. Note: Assumes that only the passed command can have
* multiple labels; only considering the first label for all of the command's parents.
*
* @param command The command to verify
* @param command The command to process
*
* @return The full command binding
* @return List of all bindings that lead to the command
*/
private static List<String> getAbsoluteLabels(CommandDescription command) {
String parentPath = "";

View File

@ -3,6 +3,7 @@ package fr.xephi.authme.command;
import org.junit.Test;
import java.util.Arrays;
import java.util.Collections;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
@ -27,7 +28,7 @@ public class CommandPartsTest {
@Test
public void shouldPrintEmptyStringForNoArguments() {
// given
CommandParts parts = new CommandParts();
CommandParts parts = new CommandParts(Collections.EMPTY_LIST);
// when
String str = parts.toString();

View File

@ -0,0 +1,73 @@
package fr.xephi.authme.command.executable.captcha;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.util.WrapperMock;
import org.bukkit.command.BlockCommandSender;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.mockito.Mockito;
import java.util.Collections;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
/**
* Test for {@link CaptchaCommand}.
*/
public class CaptchaCommandTest {
private WrapperMock wrapperMock;
@Before
public void setUpWrapperMock() {
wrapperMock = WrapperMock.createInstance();
Settings.useCaptcha = true;
}
@Test
public void shouldRejectNonPlayerSender() {
// given
CommandSender sender = Mockito.mock(BlockCommandSender.class);
ExecutableCommand command = new CaptchaCommand();
// when
boolean result = command.executeCommand(sender, new CommandParts(Collections.EMPTY_LIST), new CommandParts(Collections.EMPTY_LIST));
// then
assertThat(result, equalTo(true));
assertThat(wrapperMock.wasMockCalled(AuthMe.class), equalTo(false));
assertThat(wrapperMock.wasMockCalled(Messages.class), equalTo(false));
}
@Test
@Ignore
public void shouldRejectIfCaptchaIsNotUsed() {
// given
Player player = mockPlayerWithName("testplayer");
ExecutableCommand command = new CaptchaCommand();
// when
boolean result = command.executeCommand(player, new CommandParts(Collections.EMPTY_LIST), new CommandParts(Collections.EMPTY_LIST));
// then
assertThat(result, equalTo(true));
verify(wrapperMock.getMessages()).send(player, MessageKey.USAGE_LOGIN);
}
private static Player mockPlayerWithName(String name) {
Player player = Mockito.mock(Player.class);
when(player.getName()).thenReturn(name);
return player;
}
}

View File

@ -4,8 +4,8 @@ import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ReflectionTestUtils;
import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.settings.MessageKey;
import fr.xephi.authme.settings.Messages;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.task.ChangePasswordTask;
import fr.xephi.authme.util.WrapperMock;
@ -13,17 +13,16 @@ import org.bukkit.Server;
import org.bukkit.command.BlockCommandSender;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitScheduler;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import java.util.Arrays;
import java.util.Collections;
import static java.util.Arrays.asList;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.mockito.BDDMockito.given;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.*;
@ -57,7 +56,7 @@ public class ChangePasswordCommandTest {
CommandParts arguments = mock(CommandParts.class);
// when
command.executeCommand(sender, new CommandParts(), arguments);
command.executeCommand(sender, newParts(), arguments);
// then
verify(arguments, never()).get(anyInt());
@ -71,7 +70,7 @@ public class ChangePasswordCommandTest {
ChangePasswordCommand command = new ChangePasswordCommand();
// when
command.executeCommand(sender, new CommandParts(), new CommandParts("pass"));
command.executeCommand(sender, newParts(), new CommandParts("pass"));
// then
verify(messagesMock).send(sender, MessageKey.NOT_LOGGED_IN);
@ -85,7 +84,7 @@ public class ChangePasswordCommandTest {
ChangePasswordCommand command = new ChangePasswordCommand();
// when
command.executeCommand(sender, new CommandParts(), new CommandParts("!pass"));
command.executeCommand(sender, newParts(), newParts("old123", "!pass"));
// then
verify(messagesMock).send(sender, MessageKey.PASSWORD_MATCH_ERROR);
@ -100,7 +99,7 @@ public class ChangePasswordCommandTest {
ChangePasswordCommand command = new ChangePasswordCommand();
// when
command.executeCommand(sender, new CommandParts(), new CommandParts("Tester"));
command.executeCommand(sender, newParts(), newParts("old_", "Tester"));
// then
verify(messagesMock).send(sender, MessageKey.PASSWORD_IS_USERNAME_ERROR);
@ -115,7 +114,7 @@ public class ChangePasswordCommandTest {
Settings.passwordMaxLength = 3;
// when
command.executeCommand(sender, new CommandParts(), new CommandParts("test"));
command.executeCommand(sender, newParts(), newParts("12", "test"));
// then
verify(messagesMock).send(sender, MessageKey.INVALID_PASSWORD_LENGTH);
@ -130,7 +129,7 @@ public class ChangePasswordCommandTest {
Settings.getPasswordMinLen = 7;
// when
command.executeCommand(sender, new CommandParts(), new CommandParts("tester"));
command.executeCommand(sender, newParts(), newParts("oldverylongpassword", "tester"));
// then
verify(messagesMock).send(sender, MessageKey.INVALID_PASSWORD_LENGTH);
@ -145,7 +144,7 @@ public class ChangePasswordCommandTest {
Settings.unsafePasswords = asList("test", "abc123");
// when
command.executeCommand(sender, new CommandParts(), new CommandParts("abc123"));
command.executeCommand(sender, newParts(), newParts("oldpw", "abc123"));
// then
verify(messagesMock).send(sender, MessageKey.PASSWORD_UNSAFE_ERROR);
@ -157,16 +156,14 @@ public class ChangePasswordCommandTest {
// given
CommandSender sender = initPlayerWithName("parker", true);
ChangePasswordCommand command = new ChangePasswordCommand();
BukkitScheduler schedulerMock = mock(BukkitScheduler.class);
given(wrapperMock.getServer().getScheduler()).willReturn(schedulerMock);
// when
command.executeCommand(sender, new CommandParts(), new CommandParts(asList("abc123", "abc123")));
command.executeCommand(sender, newParts(), newParts("abc123", "abc123"));
// then
verify(messagesMock, never()).send(eq(sender), any(MessageKey.class));
ArgumentCaptor<ChangePasswordTask> taskCaptor = ArgumentCaptor.forClass(ChangePasswordTask.class);
verify(schedulerMock).runTaskAsynchronously(any(AuthMe.class), taskCaptor.capture());
verify(wrapperMock.getScheduler()).runTaskAsynchronously(any(AuthMe.class), taskCaptor.capture());
ChangePasswordTask task = taskCaptor.getValue();
assertThat((String) ReflectionTestUtils.getFieldValue(ChangePasswordTask.class, task, "newPassword"),
equalTo("abc123"));
@ -179,4 +176,8 @@ public class ChangePasswordCommandTest {
return player;
}
private static CommandParts newParts(String... parts) {
return new CommandParts(Arrays.asList(parts));
}
}

View File

@ -11,6 +11,7 @@ import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import java.util.ArrayList;
import java.util.Arrays;
import static org.mockito.Mockito.never;
@ -40,7 +41,7 @@ public class AddEmailCommandTest {
AddEmailCommand command = new AddEmailCommand();
// when
command.executeCommand(sender, new CommandParts(), new CommandParts());
command.executeCommand(sender, newParts(), newParts());
// then
verify(authMeMock, never()).getManagement();
@ -53,11 +54,15 @@ public class AddEmailCommandTest {
AddEmailCommand command = new AddEmailCommand();
// when
command.executeCommand(sender, new CommandParts(),
command.executeCommand(sender, newParts(),
new CommandParts(Arrays.asList("mail@example", "other_example")));
// then
verify(authMeMock).getManagement();
verify(managementMock).performAddEmail(sender, "mail@example", "other_example");
}
private static CommandParts newParts() {
return new CommandParts(new ArrayList<String>());
}
}

View File

@ -11,6 +11,7 @@ import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import java.util.ArrayList;
import java.util.Arrays;
import static org.mockito.Mockito.never;
@ -40,7 +41,7 @@ public class ChangeEmailCommandTest {
ChangeEmailCommand command = new ChangeEmailCommand();
// when
command.executeCommand(sender, new CommandParts(), new CommandParts());
command.executeCommand(sender, newParts(), newParts());
// then
verify(authMeMock, never()).getManagement();
@ -53,11 +54,15 @@ public class ChangeEmailCommandTest {
ChangeEmailCommand command = new ChangeEmailCommand();
// when
command.executeCommand(sender, new CommandParts(),
command.executeCommand(sender, newParts(),
new CommandParts(Arrays.asList("new.mail@example.org", "old_mail@example.org")));
// then
verify(authMeMock).getManagement();
verify(managementMock).performChangeEmail(sender, "new.mail@example.org", "old_mail@example.org");
}
private static CommandParts newParts() {
return new CommandParts(new ArrayList<String>());
}
}

View File

@ -9,6 +9,8 @@ import org.junit.Ignore;
import org.junit.Test;
import org.mockito.Mockito;
import java.util.Collections;
/**
* Test for {@link RecoverEmailCommand}.
*/
@ -27,7 +29,7 @@ public class RecoverEmailCommandTest {
RecoverEmailCommand command = new RecoverEmailCommand();
// when
command.executeCommand(sender, new CommandParts(), new CommandParts());
command.executeCommand(sender, new CommandParts(Collections.EMPTY_LIST), new CommandParts(Collections.EMPTY_LIST));
// then
}

View File

@ -11,6 +11,8 @@ import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import java.util.ArrayList;
import static org.mockito.Matchers.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
@ -38,7 +40,7 @@ public class LoginCommandTest {
LoginCommand command = new LoginCommand();
// when
command.executeCommand(sender, new CommandParts(), new CommandParts());
command.executeCommand(sender, newParts(), newParts());
// then
Mockito.verify(managementMock, never()).performLogin(any(Player.class), anyString(), anyBoolean());
@ -51,7 +53,7 @@ public class LoginCommandTest {
LoginCommand command = new LoginCommand();
// when
command.executeCommand(sender, new CommandParts(), new CommandParts("password"));
command.executeCommand(sender, newParts(), new CommandParts("password"));
// then
Mockito.verify(managementMock).performLogin(eq(sender), eq("password"), eq(false));
@ -64,11 +66,15 @@ public class LoginCommandTest {
LoginCommand command = new LoginCommand();
// when
command.executeCommand(sender, new CommandParts(), new CommandParts());
command.executeCommand(sender, newParts(), newParts());
// then
// TODO ljacqu 20151121: May make sense to handle null password in LoginCommand instead of forwarding the call
String password = null;
Mockito.verify(managementMock).performLogin(eq(sender), eq(password), eq(false));
}
private static CommandParts newParts() {
return new CommandParts(new ArrayList<String>());
}
}

View File

@ -12,6 +12,8 @@ import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import java.util.ArrayList;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
@ -40,7 +42,7 @@ public class LogoutCommandTest {
LogoutCommand command = new LogoutCommand();
// when
command.executeCommand(sender, new CommandParts(), new CommandParts());
command.executeCommand(sender, new CommandParts(new ArrayList<String>()), new CommandParts(new ArrayList<String>()));
// then
Mockito.verify(managementMock, never()).performLogout(any(Player.class));
@ -53,7 +55,7 @@ public class LogoutCommandTest {
LogoutCommand command = new LogoutCommand();
// when
command.executeCommand(sender, new CommandParts(), new CommandParts("password"));
command.executeCommand(sender, new CommandParts(new ArrayList<String>()), new CommandParts("password"));
// then
Mockito.verify(managementMock).performLogout(sender);

View File

@ -2,8 +2,8 @@ package fr.xephi.authme.command.executable.register;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.process.Management;
import fr.xephi.authme.settings.MessageKey;
import fr.xephi.authme.settings.Messages;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.util.WrapperMock;
import org.bukkit.command.BlockCommandSender;
@ -14,6 +14,8 @@ import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
import java.util.ArrayList;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
import static org.mockito.Matchers.any;
@ -48,7 +50,7 @@ public class RegisterCommandTest {
ArgumentCaptor<String> messageCaptor = ArgumentCaptor.forClass(String.class);
// when
command.executeCommand(sender, new CommandParts(), new CommandParts());
command.executeCommand(sender, newParts(), newParts());
// then
verify(sender).sendMessage(messageCaptor.capture());
@ -63,7 +65,7 @@ public class RegisterCommandTest {
RegisterCommand command = new RegisterCommand();
// when
command.executeCommand(sender, new CommandParts(), new CommandParts());
command.executeCommand(sender, newParts(), newParts());
// then
verify(messagesMock).send(sender, MessageKey.USAGE_REGISTER);
@ -77,9 +79,13 @@ public class RegisterCommandTest {
RegisterCommand command = new RegisterCommand();
// when
command.executeCommand(sender, new CommandParts(), new CommandParts("password"));
command.executeCommand(sender, newParts(), new CommandParts("password"));
// then
verify(managementMock).performRegister(sender, "password", "");
}
private static CommandParts newParts() {
return new CommandParts(new ArrayList<String>());
}
}

View File

@ -3,10 +3,12 @@ package fr.xephi.authme.command.help;
import fr.xephi.authme.command.CommandDescription;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.command.executable.authme.RegisterCommand;
import fr.xephi.authme.command.executable.authme.RegisterAdminCommand;
import org.junit.Test;
import org.mockito.Mockito;
import java.util.ArrayList;
import static org.bukkit.ChatColor.BOLD;
import static org.bukkit.ChatColor.ITALIC;
import static org.bukkit.ChatColor.WHITE;
@ -27,8 +29,7 @@ public class HelpSyntaxHelperTest {
.build();
// when
String result = HelpSyntaxHelper.getCommandSyntax(
description, new CommandParts(), "", false);
String result = HelpSyntaxHelper.getCommandSyntax(description, newParts(), "", false);
// then
assertThat(result, equalTo(WHITE + "/authme register" + ITALIC + " [name]"));
@ -42,8 +43,7 @@ public class HelpSyntaxHelperTest {
.build();
// when
String result = HelpSyntaxHelper.getCommandSyntax(
description, new CommandParts(), null, false);
String result = HelpSyntaxHelper.getCommandSyntax(description, newParts(), null, false);
// then
assertThat(result, equalTo(WHITE + "/authme register" + ITALIC + " <test>"));
@ -58,8 +58,7 @@ public class HelpSyntaxHelperTest {
.build();
// when
String result = HelpSyntaxHelper.getCommandSyntax(
description, new CommandParts(), "", false);
String result = HelpSyntaxHelper.getCommandSyntax(description, newParts(), "", false);
// then
assertThat(result, equalTo(WHITE + "/authme register" + ITALIC + " [name]" + ITALIC + " <test>"));
@ -74,8 +73,7 @@ public class HelpSyntaxHelperTest {
.build();
// when
String result = HelpSyntaxHelper.getCommandSyntax(
description, new CommandParts(), "", true);
String result = HelpSyntaxHelper.getCommandSyntax(description, newParts(), "", true);
// then
assertThat(result, equalTo(WHITE + "/authme "
@ -89,8 +87,7 @@ public class HelpSyntaxHelperTest {
CommandDescription description = getDescriptionBuilder().build();
// when
String result = HelpSyntaxHelper.getCommandSyntax(
description, new CommandParts(), null, true);
String result = HelpSyntaxHelper.getCommandSyntax(description, newParts(), null, true);
// then
assertThat(result, equalTo(WHITE + "/authme " + YELLOW + BOLD + "register" + YELLOW));
@ -104,34 +101,18 @@ public class HelpSyntaxHelperTest {
.build();
// when
String result = HelpSyntaxHelper.getCommandSyntax(
description, new CommandParts(), "alt", false);
String result = HelpSyntaxHelper.getCommandSyntax(description, newParts(), "alt", false);
// then
assertThat(result, equalTo(WHITE + "/authme alt" + ITALIC + " [name]"));
}
@Test
public void shouldHighlightCommandWithAltLabelAndUnlimitedArguments() {
// given
CommandDescription description = getDescriptionBuilder()
.withArgument("name", "", true)
.withArgument("test", "", false)
.noArgumentMaximum(true)
.build();
// when
String result = HelpSyntaxHelper.getCommandSyntax(
description, new CommandParts(), "test", true);
// then
assertThat(result, equalTo(WHITE + "/authme "
+ YELLOW + BOLD + "test"
+ YELLOW + ITALIC + " [name]" + ITALIC + " <test>" + ITALIC + " ..."));
private static CommandParts newParts() {
// TODO ljacqu 20151204: Remove this method once CommandParts has been removed
return new CommandParts(new ArrayList<String>());
}
private static CommandDescription.Builder getDescriptionBuilder() {
private static CommandDescription.CommandBuilder getDescriptionBuilder() {
CommandDescription base = CommandDescription.builder()
.labels("authme")
.description("Base command")
@ -141,7 +122,7 @@ public class HelpSyntaxHelperTest {
.build();
return CommandDescription.builder()
.executableCommand(Mockito.mock(RegisterCommand.class))
.executableCommand(Mockito.mock(RegisterAdminCommand.class))
.labels("register", "r")
.description("Register a player")
.detailedDescription("Register the specified player with the specified password.")

View File

@ -0,0 +1,77 @@
package fr.xephi.authme.output;
import org.junit.Test;
import org.mockito.Mockito;
import java.util.logging.LogRecord;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
/**
* Test for {@link ConsoleFilter}.
*/
public class ConsoleFilterTest {
private final ConsoleFilter filter = new ConsoleFilter();
private static final String SENSITIVE_COMMAND = "User issued server command: /login test test";
private static final String NORMAL_COMMAND = "User issued server command: /motd 2";
@Test
public void shouldReplaceSensitiveRecord() {
// given
LogRecord record = createRecord(SENSITIVE_COMMAND);
// when
boolean result = filter.isLoggable(record);
// then
assertThat(result, equalTo(true));
verify(record).setMessage("User issued an AuthMe command");
}
@Test
public void shouldNotFilterRegularCommand() {
// given
LogRecord record = createRecord(NORMAL_COMMAND);
// when
boolean result = filter.isLoggable(record);
// then
assertThat(result, equalTo(true));
verify(record, never()).setMessage("User issued an AuthMe command");
}
@Test
public void shouldManageRecordWithNullMessage() {
// given
LogRecord record = createRecord(null);
// when
boolean result = filter.isLoggable(record);
// then
assertThat(result, equalTo(true));
verify(record, never()).setMessage("User issued an AuthMe command");
}
/**
* Creates a mock of {@link LogRecord} and sets it to return the given message.
*
* @param message The message to set.
*
* @return Mock of LogRecord
*/
private static LogRecord createRecord(String message) {
LogRecord record = Mockito.mock(LogRecord.class);
when(record.getMessage()).thenReturn(message);
return record;
}
}

View File

@ -1,4 +1,4 @@
package fr.xephi.authme;
package fr.xephi.authme.output;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
@ -12,8 +12,6 @@ import org.mockito.Mockito;
/**
* Test for {@link Log4JFilter}.
* @author Gabriele
* @version $Revision: 1.0 $
*/
public class Log4JFilterTest {

View File

@ -1,4 +1,4 @@
package fr.xephi.authme.settings;
package fr.xephi.authme.output;
import fr.xephi.authme.util.StringUtils;
import org.junit.Test;

Some files were not shown because too many files have changed in this diff Show More