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> <value>
<option name="AUTODETECT_INDENTS" value="false" /> <option name="AUTODETECT_INDENTS" value="false" />
<option name="LINE_SEPARATOR" value="&#10;" /> <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_PARM_COMMENTS" value="true" />
<option name="JD_ADD_BLANK_AFTER_RETURN" value="true" /> <option name="JD_ADD_BLANK_AFTER_RETURN" value="true" />
<XML> <XML>

10
pom.xml
View File

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

View File

@ -1,8 +1,8 @@
package fr.xephi.authme; package fr.xephi.authme;
import fr.xephi.authme.permission.UserPermission; import fr.xephi.authme.permission.PlayerPermission;
import fr.xephi.authme.settings.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.settings.Messages; import fr.xephi.authme.output.Messages;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.util.Wrapper; import fr.xephi.authme.util.Wrapper;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -73,7 +73,7 @@ public class AntiBot {
if (antiBotStatus == AntiBotStatus.ACTIVE || antiBotStatus == AntiBotStatus.DISABLED) { if (antiBotStatus == AntiBotStatus.ACTIVE || antiBotStatus == AntiBotStatus.DISABLED) {
return; return;
} }
if (plugin.getPermissionsManager().hasPermission(player, UserPermission.BYPASS_ANTIBOT)) { if (plugin.getPermissionsManager().hasPermission(player, PlayerPermission.BYPASS_ANTIBOT)) {
return; 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.LimboCache;
import fr.xephi.authme.cache.limbo.LimboPlayer; import fr.xephi.authme.cache.limbo.LimboPlayer;
import fr.xephi.authme.command.CommandHandler; import fr.xephi.authme.command.CommandHandler;
import fr.xephi.authme.command.CommandInitializer;
import fr.xephi.authme.converter.Converter; import fr.xephi.authme.converter.Converter;
import fr.xephi.authme.converter.ForceFlatToSqlite; import fr.xephi.authme.converter.ForceFlatToSqlite;
import fr.xephi.authme.datasource.*; 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.hooks.EssSpawn;
import fr.xephi.authme.listener.*; import fr.xephi.authme.listener.*;
import fr.xephi.authme.modules.ModuleManager; 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.PermissionsManager;
import fr.xephi.authme.permission.UserPermission; import fr.xephi.authme.permission.PlayerPermission;
import fr.xephi.authme.process.Management; import fr.xephi.authme.process.Management;
import fr.xephi.authme.settings.*; import fr.xephi.authme.settings.*;
import fr.xephi.authme.util.GeoLiteAPI; import fr.xephi.authme.util.GeoLiteAPI;
import fr.xephi.authme.util.StringUtils; import fr.xephi.authme.util.StringUtils;
import fr.xephi.authme.util.Utils; import fr.xephi.authme.util.Utils;
import fr.xephi.authme.util.Wrapper;
import net.minelink.ctplus.CombatTagPlus; import net.minelink.ctplus.CombatTagPlus;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -66,8 +72,9 @@ public class AuthMe extends JavaPlugin {
private static AuthMe plugin; private static AuthMe plugin;
private static Server server; private static Server server;
private static Wrapper wrapper = Wrapper.getInstance();
public Management management; private Management management;
public NewAPI api; public NewAPI api;
public SendMailSSL mail; public SendMailSSL mail;
public DataManager dataManager; public DataManager dataManager;
@ -227,7 +234,7 @@ public class AuthMe extends JavaPlugin {
this.otherAccounts = OtherAccounts.getInstance(); this.otherAccounts = OtherAccounts.getInstance();
// Setup messages // Setup messages
this.messages = new Messages(Settings.messageFile, Settings.messagesLanguage); this.messages = Messages.getInstance();
// Set up Metrics // Set up Metrics
setupMetrics(); setupMetrics();
@ -427,8 +434,7 @@ public class AuthMe extends JavaPlugin {
* Set up the command handler. * Set up the command handler.
*/ */
private void setupCommandHandler() { private void setupCommandHandler() {
this.commandHandler = new CommandHandler(false); this.commandHandler = new CommandHandler(CommandInitializer.getBaseCommands());
this.commandHandler.init();
} }
/** /**
@ -735,7 +741,7 @@ public class AuthMe extends JavaPlugin {
public Player generateKickPlayer(Collection<? extends Player> collection) { public Player generateKickPlayer(Collection<? extends Player> collection) {
Player player = null; Player player = null;
for (Player p : collection) { for (Player p : collection) {
if (!getPermissionsManager().hasPermission(p, UserPermission.IS_VIP)) { if (!getPermissionsManager().hasPermission(p, PlayerPermission.IS_VIP)) {
player = p; player = p;
break; break;
} }
@ -951,13 +957,14 @@ public class AuthMe extends JavaPlugin {
@Override @Override
public boolean onCommand(CommandSender sender, Command cmd, public boolean onCommand(CommandSender sender, Command cmd,
String commandLabel, String[] args) { String commandLabel, String[] args) {
// Get the command handler, and make sure it's valid // Make sure the command handler has been initialized
CommandHandler commandHandler = this.getCommandHandler(); if (commandHandler == null) {
if (commandHandler == null) wrapper.getLogger().severe("AuthMe command handler is not available");
return false; return false;
}
// Handle the command, return the result // Handle the command
return commandHandler.onCommand(sender, cmd, commandLabel, args); 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 com.google.common.base.Throwables;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.util.StringUtils;
import fr.xephi.authme.util.Wrapper; import fr.xephi.authme.util.Wrapper;
import java.io.IOException; import java.io.IOException;
@ -17,8 +16,10 @@ import java.util.Date;
*/ */
public final class ConsoleLogger { 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 Wrapper wrapper = Wrapper.getInstance();
private static final DateFormat df = new SimpleDateFormat("[MM-dd HH:mm:ss]");
private ConsoleLogger() { private ConsoleLogger() {
// Service class // Service class
@ -57,11 +58,11 @@ public final class ConsoleLogger {
*/ */
private static void writeLog(String message) { private static void writeLog(String message) {
String dateTime; String dateTime;
synchronized (df) { synchronized (DATE_FORMAT) {
dateTime = df.format(new Date()); dateTime = DATE_FORMAT.format(new Date());
} }
try { 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.APPEND,
StandardOpenOption.CREATE); StandardOpenOption.CREATE);
} catch (IOException ignored) { } catch (IOException ignored) {
@ -77,6 +78,6 @@ public final class ConsoleLogger {
if (!Settings.useLogging) { if (!Settings.useLogging) {
return; 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 subject = Settings.getMailSubject;
final String smtp = Settings.getmailSMTP; final String smtp = Settings.getmailSMTP;
final String password = Settings.getmailPassword; 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(); final String mail = auth.getEmail();
Bukkit.getScheduler().runTaskAsynchronously(plugin, new Runnable() { Bukkit.getScheduler().runTaskAsynchronously(plugin, new Runnable() {
@ -76,7 +76,7 @@ public class SendMailSSL {
ImageIO.write(gen.generateImage(), "jpg", file); ImageIO.write(gen.generateImage(), "jpg", file);
DataSource source = new FileDataSource(file); DataSource source = new FileDataSource(file);
String tag = email.embed(source, auth.getNickname() + "_new_pass.jpg"); 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) { } catch (Exception e) {
ConsoleLogger.showError("Unable to send new password as image! Using normal text! Dest: " + mail); ConsoleLogger.showError("Unable to send new password as image! Using normal text! Dest: " + mail);
} }
@ -86,8 +86,7 @@ public class SendMailSSL {
try { try {
email.send(); email.send();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); ConsoleLogger.showError("Fail to send a mail to " + mail + " cause " + e.getLocalizedMessage());
ConsoleLogger.showError("Fail to send a mail to " + mail);
} }
if (file != null) if (file != null)
//noinspection ResultOfMethodCallIgnored //noinspection ResultOfMethodCallIgnored

View File

@ -170,7 +170,7 @@ public class API {
*/ */
@Deprecated @Deprecated
public static void forceLogin(Player player) { 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 * @param player * player
*/ */
public void forceLogin(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 * @param player * player
*/ */
public void forceLogout(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 * @param password String
*/ */
public void forceRegister(Player player, String password) { 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 * @param player * player
*/ */
public void forceUnregister(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) public PlayerAuth(String serialized) {
{ this.deserialize(serialized);
this.unserialize(serialized);
} }
/** /**
@ -163,8 +162,10 @@ public class PlayerAuth {
* @param email String * @param email String
* @param realName 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) { public PlayerAuth(String nickname, String hash, String salt, int groupId, String ip,
this.nickname = nickname; long lastLogin, double x, double y, double z, String world, String email,
String realName) {
this.nickname = nickname.toLowerCase();
this.hash = hash; this.hash = hash;
this.ip = ip; this.ip = ip;
this.lastLogin = lastLogin; this.lastLogin = lastLogin;
@ -203,7 +204,7 @@ public class PlayerAuth {
* @param nickname String * @param nickname String
*/ */
public void setName(String nickname) { public void setName(String nickname) {
this.nickname = nickname; this.nickname = nickname.toLowerCase();
} }
/** /**
@ -455,34 +456,32 @@ public class PlayerAuth {
} }
/** /**
* Method to serialize playerauth * Method to serialize PlayerAuth
* *
* @return String * @return String
*/ */
public String serialize() public String serialize() {
{
StringBuilder str = new StringBuilder(); StringBuilder str = new StringBuilder();
str.append(this.nickname).append(';'); char d = ';';
str.append(this.realName).append(';'); str.append(this.nickname).append(d);
str.append(this.ip).append(';'); str.append(this.realName).append(d);
str.append(this.email).append(';'); str.append(this.ip).append(d);
str.append(this.hash).append(';'); str.append(this.email).append(d);
str.append(this.salt).append(';'); str.append(this.hash).append(d);
str.append(this.groupId).append(';'); str.append(this.salt).append(d);
str.append(this.lastLogin).append(';'); str.append(this.groupId).append(d);
str.append(this.world).append(';'); str.append(this.lastLogin).append(d);
str.append(this.x).append(';'); str.append(this.world).append(d);
str.append(this.y).append(';'); str.append(this.x).append(d);
str.append(this.y).append(d);
str.append(this.z); str.append(this.z);
return str.toString(); return str.toString();
} }
/** /**
* Method to unserialize playerauth * Method to deserialize PlayerAuth
*
*/ */
public void unserialize(String str) public void deserialize(String str) {
{
String[] args = str.split(";"); String[] args = str.split(";");
this.nickname = args[0]; this.nickname = args[0];
this.realName = args[1]; this.realName = args[1];
@ -497,4 +496,97 @@ public class PlayerAuth {
this.y = Double.parseDouble(args[10]); this.y = Double.parseDouble(args[10]);
this.z = Double.parseDouble(args[11]); 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 java.util.concurrent.ConcurrentHashMap;
import static com.google.common.base.Preconditions.checkNotNull;
/** /**
*/ */
public class LimboCache { public class LimboCache {
@ -117,7 +119,8 @@ public class LimboCache {
* @param name String * @param name String
*/ */
public void deleteLimboPlayer(String name) { public void deleteLimboPlayer(String name) {
cache.remove(name); checkNotNull(name);
cache.remove(name.toLowerCase());
} }
/** /**
@ -128,7 +131,8 @@ public class LimboCache {
* @return LimboPlayer * @return LimboPlayer
*/ */
public LimboPlayer getLimboPlayer(String name) { 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 * @return boolean
*/ */
public boolean hasLimboPlayer(String name) { 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 * @param player Player
*/ */
public void updateLimboPlayer(Player player) { public void updateLimboPlayer(Player player) {
if (this.hasLimboPlayer(player.getName().toLowerCase())) { checkNotNull(player);
this.deleteLimboPlayer(player.getName().toLowerCase()); deleteLimboPlayer(player.getName().toLowerCase());
}
addLimboPlayer(player); addLimboPlayer(player);
} }

View File

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

View File

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

View File

@ -1,6 +1,8 @@
package fr.xephi.authme.command; package fr.xephi.authme.command;
import fr.xephi.authme.permission.DefaultPermission;
import fr.xephi.authme.permission.PermissionNode; import fr.xephi.authme.permission.PermissionNode;
import fr.xephi.authme.util.CollectionUtils;
import fr.xephi.authme.util.StringUtils; import fr.xephi.authme.util.StringUtils;
import org.bukkit.command.CommandSender; 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 * 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. * {@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 * CommandDescription instances are built hierarchically and have one parent or {@code null} for base commands
* such as /authme) and may have multiple children extending the mapping of the parent: e.g. if /authme has a child * (main commands such as /authme) and may have multiple children extending the mapping of the parent: e.g. if
* whose label is "register", then "/authme register" is the command that the child defines. * /authme has a child whose label is "register", then "/authme register" is the command that the child defines.
*/ */
public class CommandDescription { public class CommandDescription {
@ -50,95 +52,53 @@ public class CommandDescription {
* The arguments the command takes. * The arguments the command takes.
*/ */
private List<CommandArgumentDescription> arguments; private List<CommandArgumentDescription> arguments;
/**
* Defines whether there is an argument maximum or not.
*/
private boolean noArgumentMaximum;
/** /**
* Defines the command permissions. * Defines the command permissions.
*/ */
private CommandPermissions 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. * 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 labels List of command labels.
* @param description Command description. * @param description Command description.
* @param detailedDescription Detailed comment description. * @param detailedDescription Detailed comment description.
* @param executableCommand The executable command, or null.
* @param parent Parent command. * @param parent Parent command.
* @param arguments Command arguments. * @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, private static CommandDescription createInstance(List<String> labels, String description,
ExecutableCommand executableCommand, CommandDescription parent, String detailedDescription, ExecutableCommand executableCommand,
List<CommandArgumentDescription> arguments, boolean noArgumentMaximum, CommandDescription parent, List<CommandArgumentDescription> arguments,
CommandPermissions permissions) { CommandPermissions permissions) {
this.labels = labels; CommandDescription instance = new CommandDescription();
this.description = description; instance.labels = labels;
this.detailedDescription = detailedDescription; instance.description = description;
this.executableCommand = executableCommand; instance.detailedDescription = detailedDescription;
this.parent = parent; instance.executableCommand = executableCommand;
this.arguments = arguments; instance.parent = parent;
this.noArgumentMaximum = noArgumentMaximum; instance.arguments = arguments;
this.permissions = permissions; instance.permissions = permissions;
if (parent != null) { if (parent != null) {
// Passing `this` in constructor is not very nice; consider creating a "static create()" method instead parent.addChild(instance);
parent.addChild(this);
} }
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. * 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. * @return True if this command label equals to the param command.
*/ */
public boolean hasLabel(String commandLabel) { public boolean hasLabel(String commandLabel) {
// Check whether any command matches with the argument for (String label : this.labels) {
for (String entry : this.labels) if (label.equalsIgnoreCase(commandLabel)) {
if (commandLabelEquals(entry, commandLabel))
return true; return true;
}
// No match found, return false }
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. * @return True if the command reference is suitable to this command label, false otherwise.
*/ */
public boolean isSuitableLabel(CommandParts commandReference) { public boolean isSuitableLabel(CommandParts commandReference) {
// Make sure the command reference is valid
if (commandReference.getCount() <= 0)
return false;
// Get the parent count // Get the parent count
//getParent() = getParent().getParentCount() + 1
String element = commandReference.get(getParentCount()); String element = commandReference.get(getParentCount());
// Check whether this command description has this command label // Check whether this command description has this command label
return hasLabel(element); for (String label : labels) {
if (label.equalsIgnoreCase(element)) {
return true;
} }
/**
* Get the absolute command label, without a starting slash.
*
* @return The absolute label
*/
public String getAbsoluteLabel() {
return getAbsoluteLabel(false);
} }
return 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();
} }
/** /**
@ -269,8 +192,9 @@ public class CommandDescription {
List<String> referenceList = new ArrayList<>(); List<String> referenceList = new ArrayList<>();
// Check whether this command has a parent, if so, add the absolute parent command // 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()); referenceList.addAll(getParent().getCommandReference(reference).getList());
}
// Get the current label // Get the current label
referenceList.add(getLabel(reference)); referenceList.add(getLabel(reference));
@ -307,7 +231,8 @@ public class CommandDescription {
CommandParts reference = getCommandReference(other); CommandParts reference = getCommandReference(other);
// Compare the two references, return the result // 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; 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. * Execute the command, if possible.
* *
@ -347,10 +263,6 @@ public class CommandDescription {
* @return True on success, false on failure. * @return True on success, false on failure.
*/ */
public boolean execute(CommandSender sender, CommandParts commandReference, CommandParts commandArguments) { 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 // Execute the command, return the result
return getExecutableCommand().executeCommand(sender, commandReference, commandArguments); return getExecutableCommand().executeCommand(sender, commandReference, commandArguments);
} }
@ -461,7 +373,7 @@ public class CommandDescription {
*/ */
public boolean isChild(CommandDescription commandDescription) { public boolean isChild(CommandDescription commandDescription) {
// Make sure the description is valid // Make sure the description is valid
if (commandDescription == null) // TODO: After builder, commandDescription == null -> never if (commandDescription == null)
return false; return false;
// Check whether this child exists, return the result // Check whether this child exists, return the result
@ -480,10 +392,6 @@ public class CommandDescription {
if (argument == null) if (argument == null)
return false; return false;
// Make sure the argument isn't added already
if (hasArgument(argument))
return true;
// Add the argument, return the result // Add the argument, return the result
return this.arguments.add(argument); return this.arguments.add(argument);
} }
@ -497,81 +405,13 @@ public class CommandDescription {
return this.arguments; 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. * Check whether this command has any arguments.
* *
* @return True if this command has any arguments. * @return True if this command has any arguments.
*/ */
public boolean hasArguments() { public boolean hasArguments() {
return !arguments.isEmpty(); return !getArguments().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();
} }
/** /**
@ -580,16 +420,7 @@ public class CommandDescription {
* @return Command description. * @return Command description.
*/ */
public String getDescription() { public String getDescription() {
return hasDescription() ? this.description : this.detailedDescription; return description;
}
/**
* Check whether this command has any description.
*
* @return True if this command has any description.
*/
public boolean hasDescription() {
return !StringUtils.isEmpty(description);
} }
/** /**
@ -598,7 +429,7 @@ public class CommandDescription {
* @return Command detailed description. * @return Command detailed description.
*/ */
public String getDetailedDescription() { public String getDetailedDescription() {
return !StringUtils.isEmpty(detailedDescription) ? this.detailedDescription : this.description; return detailedDescription;
} }
/** /**
@ -614,16 +445,17 @@ public class CommandDescription {
return null; return null;
// Check whether this description is for the last element in the command reference, if so return the current command // 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( return new FoundCommandResult(
this, this,
getCommandReference(queryReference), getCommandReference(queryReference),
new CommandParts(), new CommandParts(new ArrayList<String>()),
queryReference); queryReference);
}
// Get the new command reference and arguments // Get the new command reference and arguments
CommandParts newReference = new CommandParts(queryReference.getRange(0, getParentCount() + 1)); CommandParts newReference = new CommandParts(CollectionUtils.getRange(queryReference.getList(), 0, getParentCount() + 1));
CommandParts newArguments = new CommandParts(queryReference.getRange(getParentCount() + 1)); CommandParts newArguments = new CommandParts(CollectionUtils.getRange(queryReference.getList(), getParentCount() + 1));
// Handle the child's, if this command has any // Handle the child's, if this command has any
if (getChildren().size() > 0) { if (getChildren().size() > 0) {
@ -663,28 +495,6 @@ public class CommandDescription {
return null; 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, * Check if the remaining command reference elements are suitable with arguments of the current command description,
* and get the difference in argument count. * and get the difference in argument count.
@ -703,16 +513,18 @@ public class CommandDescription {
int remainingElementCount = commandReference.getCount() - getParentCount() - 1; int remainingElementCount = commandReference.getCount() - getParentCount() - 1;
// Check if there are too few arguments // Check if there are too few arguments
if (getMinimumArguments() > remainingElementCount) { int minArguments = CommandUtils.getMinNumberOfArguments(this);
return Math.abs(getMinimumArguments() - remainingElementCount); if (minArguments > remainingElementCount) {
return Math.abs(minArguments - remainingElementCount);
} }
// Check if there are too many arguments // Check if there are too many arguments
if (getMaximumArguments() < remainingElementCount && getMaximumArguments() >= 0) { int maxArguments = CommandUtils.getMaxNumberOfArguments(this);
return Math.abs(remainingElementCount - getMaximumArguments()); 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; return 0;
} }
@ -725,88 +537,85 @@ public class CommandDescription {
return this.permissions; return this.permissions;
} }
public static CommandBuilder builder() {
return new CommandBuilder();
}
/** /**
* Set the command permissions. * Builder for initializing CommandDescription objects.
*
* @param permissionNode The permission node required.
* @param defaultPermission The default permission.
*/ */
public void setCommandPermissions(PermissionNode permissionNode, CommandPermissions.DefaultPermission defaultPermission) { public static final class CommandBuilder {
this.permissions = new CommandPermissions(permissionNode, defaultPermission);
}
public static Builder builder() {
return new Builder();
}
public static final class Builder {
private List<String> labels; private List<String> labels;
private String description; private String description;
private String detailedDescription; private String detailedDescription;
private ExecutableCommand executableCommand; private ExecutableCommand executableCommand;
private CommandDescription parent; private CommandDescription parent;
private List<CommandArgumentDescription> arguments = new ArrayList<>(); private List<CommandArgumentDescription> arguments = new ArrayList<>();
private boolean noArgumentMaximum;
private CommandPermissions permissions; 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 * @return The generated CommandDescription object
*/ */
public CommandDescription build() { public CommandDescription build() {
return new CommandDescription( return createInstance(
getOrThrow(labels, "labels"), getOrThrow(labels, "labels"),
firstNonNull(description, ""), firstNonNull(description, ""),
firstNonNull(detailedDescription, ""), firstNonNull(detailedDescription, ""),
getOrThrow(executableCommand, "executableCommand"), getOrThrow(executableCommand, "executableCommand"),
firstNonNull(parent, null), firstNonNull(parent, null),
arguments, arguments,
noArgumentMaximum,
firstNonNull(permissions, null) firstNonNull(permissions, null)
); );
} }
public Builder labels(List<String> labels) { public CommandBuilder labels(List<String> labels) {
this.labels = labels; this.labels = labels;
return this; return this;
} }
public Builder labels(String... labels) { public CommandBuilder labels(String... labels) {
return labels(asMutableList(labels)); return labels(asMutableList(labels));
} }
public Builder description(String description) { public CommandBuilder description(String description) {
this.description = description; this.description = description;
return this; return this;
} }
public Builder detailedDescription(String detailedDescription) { public CommandBuilder detailedDescription(String detailedDescription) {
this.detailedDescription = detailedDescription; this.detailedDescription = detailedDescription;
return this; return this;
} }
public Builder executableCommand(ExecutableCommand executableCommand) { public CommandBuilder executableCommand(ExecutableCommand executableCommand) {
this.executableCommand = executableCommand; this.executableCommand = executableCommand;
return this; return this;
} }
public Builder parent(CommandDescription parent) { public CommandBuilder parent(CommandDescription parent) {
this.parent = parent; this.parent = parent;
return this; 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)); arguments.add(new CommandArgumentDescription(label, description, isOptional));
return this; return this;
} }
public Builder noArgumentMaximum(boolean noArgumentMaximum) { public CommandBuilder permissions(DefaultPermission defaultPermission,
this.noArgumentMaximum = noArgumentMaximum;
return this;
}
public Builder permissions(CommandPermissions.DefaultPermission defaultPermission,
PermissionNode... permissionNodes) { PermissionNode... permissionNodes) {
this.permissions = new CommandPermissions(asMutableList(permissionNodes), defaultPermission); this.permissions = new CommandPermissions(asMutableList(permissionNodes), defaultPermission);
return this; return this;

View File

@ -2,209 +2,236 @@ package fr.xephi.authme.command;
import fr.xephi.authme.AuthMe; import fr.xephi.authme.AuthMe;
import fr.xephi.authme.command.help.HelpProvider; 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.ChatColor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; 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 { 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. * 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.
* @param init True to immediately initialize.
*/ */
public CommandHandler(boolean init) { private static final double SUGGEST_COMMAND_THRESHOLD = 0.75;
// Initialize
if (init) private final Set<CommandDescription> commands;
init();
/**
* Create a command handler.
*
* @param commands The collection of available AuthMe commands
*/
public CommandHandler(Set<CommandDescription> commands) {
this.commands = commands;
} }
/** /**
* Initialize the command handler. * Map a command that was invoked to the proper {@link CommandDescription} or return a useful error
* * message upon failure.
* @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.
* *
* @param sender The command sender (Bukkit). * @param sender The command sender (Bukkit).
* @param bukkitCommand The command (Bukkit).
* @param bukkitCommandLabel The command label (Bukkit). * @param bukkitCommandLabel The command label (Bukkit).
* @param bukkitArgs The command arguments (Bukkit). * @param bukkitArgs The command arguments (Bukkit).
* *
* @return True if the command was executed, false otherwise. * @return True if the command was executed, false otherwise.
*/ */
public boolean onCommand(CommandSender sender, org.bukkit.command.Command bukkitCommand, String bukkitCommandLabel, String[] bukkitArgs) { public boolean processCommand(CommandSender sender, String bukkitCommandLabel, String[] bukkitArgs) {
// Process the arguments List<String> commandArgs = skipEmptyArguments(bukkitArgs);
List<String> args = processArguments(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 // TODO: remove commandParts
CommandParts commandReference = new CommandParts(bukkitCommandLabel, args); CommandParts commandReference = new CommandParts(commandArgs);
if (commandReference.getCount() == 0)
return false;
// Get a suitable command for this reference, and make sure it isn't null // 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) { if (result == null) {
// TODO ljacqu 20151204: Log more information to the console (bukkitCommandLabel)
sender.sendMessage(ChatColor.DARK_RED + "Failed to parse " + AuthMe.getPluginName() + " command!"); sender.sendMessage(ChatColor.DARK_RED + "Failed to parse " + AuthMe.getPluginName() + " command!");
return false; 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 // Make sure the difference between the command reference and the actual command isn't too big
final double commandDifference = result.getDifference(); final double commandDifference = result.getDifference();
if (commandDifference > 0.12) { if (commandDifference <= ASSUME_COMMAND_THRESHOLD) {
// Show the unknown command warning
sender.sendMessage(ChatColor.DARK_RED + "Unknown command!");
// 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 the help command
sender.sendMessage(ChatColor.YELLOW + "Use the command " + ChatColor.GOLD + "/" + baseCommand + " help" + ChatColor.YELLOW + " to view help.");
return true;
}
// Show a message when the command handler is assuming a command // Show a message when the command handler is assuming a command
if (commandDifference > 0) { if (commandDifference > 0) {
// Get the suggested command sendCommandAssumptionMessage(sender, result, commandReference);
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)) { if (!result.hasPermission(sender)) {
// Show the no permissions warning
sender.sendMessage(ChatColor.DARK_RED + "You don't have permission to use this command!"); 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);
}
return true; return true;
} }
// Make sure the command sender has permission /**
if (!result.hasProperArguments()) { * Skip all entries of the given array that are simply whitespace.
*
* @param args The array to process
* @return List of the items that are not empty
*/
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;
}
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 // Get the command and the suggested command reference
CommandParts suggestedCommandReference = new CommandParts(result.getCommandDescription().getCommandReference(commandReference)); List<String> suggestedCommandReference =
CommandParts helpCommandReference = new CommandParts(suggestedCommandReference.getRange(1)); result.getCommandDescription().getCommandReference(commandReference).getList();
List<String> helpCommandReference = CollectionUtils.getRange(suggestedCommandReference, 1);
// Show the invalid arguments warning // Show the invalid arguments warning
sender.sendMessage(ChatColor.DARK_RED + "Incorrect command arguments!"); sender.sendMessage(ChatColor.DARK_RED + "Incorrect command arguments!");
// Show the command argument help // Show the command argument help
HelpProvider.showHelp(sender, commandReference, suggestedCommandReference, true, false, true, false, false, false); HelpProvider.showHelp(sender, commandReference, new CommandParts(suggestedCommandReference),
true, false, true, false, false, false);
// Show the command to use for detailed help // Show the command to use for detailed help
sender.sendMessage(ChatColor.GOLD + "Detailed help: " + ChatColor.WHITE + "/" + baseCommand + " help " + helpCommandReference); sender.sendMessage(ChatColor.GOLD + "Detailed help: " + ChatColor.WHITE + "/" + baseCommand
return true; + " help " + CommandUtils.labelsToString(helpCommandReference));
} }
// Execute the command if it's suitable private static void sendCommandAssumptionMessage(CommandSender sender, FoundCommandResult result,
return result.executeCommand(sender); CommandParts commandReference) {
} List<String> assumedCommandParts =
result.getCommandDescription().getCommandReference(commandReference).getList();
/** sender.sendMessage(ChatColor.DARK_RED + "Unknown command, assuming " + ChatColor.GOLD + "/"
* Process the command arguments, and return them as an array list. + CommandUtils.labelsToString(assumedCommandParts) + ChatColor.DARK_RED + "!");
*
* @param args The command arguments to process.
*
* @return The processed command arguments.
*/
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--;
}
}
// Return the argument
return arguments;
} }
} }

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<>(); private final List<String> parts = new ArrayList<>();
/**
* Constructor.
*/
public CommandParts() {
}
/** /**
* Constructor. * Constructor.
* *
@ -29,15 +23,6 @@ public class CommandParts {
this.parts.add(part); this.parts.add(part);
} }
/**
* Constructor.
*
* @param commandParts The command parts instance.
*/
public CommandParts(CommandParts commandParts) {
this.parts.addAll(commandParts.getList());
}
/** /**
* Constructor. * Constructor.
* *
@ -47,17 +32,6 @@ public class CommandParts {
this.parts.addAll(parts); 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. * Get the command parts.
* *
@ -67,41 +41,6 @@ public class CommandParts {
return this.parts; 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. * 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. * @param i Part index.
* *
@ -127,74 +66,6 @@ public class CommandParts {
return this.parts.get(i); 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. * Convert the parts to a string.
* *

View File

@ -1,12 +1,12 @@
package fr.xephi.authme.command; package fr.xephi.authme.command;
import fr.xephi.authme.AuthMe; import fr.xephi.authme.AuthMe;
import fr.xephi.authme.permission.DefaultPermission;
import fr.xephi.authme.permission.PermissionsManager; import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.permission.PermissionNode; import fr.xephi.authme.permission.PermissionNode;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
@ -22,18 +22,6 @@ public class CommandPermissions {
*/ */
private DefaultPermission defaultPermission; 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. * Constructor.
* *
@ -54,16 +42,6 @@ public class CommandPermissions {
return this.permissionNodes; 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. * 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) { public boolean hasPermission(CommandSender sender) {
// Make sure any permission node is set // Make sure any permission node is set
if (getPermissionNodeCount() == 0) if (permissionNodes.isEmpty()) {
return true; return true;
}
// Get the default permission PermissionsManager permissionsManager = AuthMe.getInstance().getPermissionsManager();
final boolean defaultPermission = getDefaultPermissionCommandSender(sender); final boolean defaultPermission = getDefaultPermissionCommandSender(sender);
// Make sure the command sender is a player, if not use the default // Make sure the command sender is a player, if not use the default
if (!(sender instanceof Player)) if (!(sender instanceof Player)) {
return defaultPermission; return defaultPermission;
}
// Get the player instance // Get the player instance
Player player = (Player) sender; Player player = (Player) sender;
// Get the permissions manager, and make sure it's instance is valid // Get the permissions manager, and make sure it's instance is valid
PermissionsManager permissionsManager = AuthMe.getInstance().getPermissionsManager();
if (permissionsManager == null) if (permissionsManager == null)
return false; return false;
// Check whether the player has permission, return the result // Check whether the player has permission, return the result
for (PermissionNode node : this.permissionNodes) { return permissionsManager.hasPermission(player, this.permissionNodes, defaultPermission);
if (!permissionsManager.hasPermission(player, node, defaultPermission)) {
return false;
}
}
return true;
} }
/** /**
@ -109,14 +84,6 @@ public class CommandPermissions {
return this.defaultPermission; 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. * Get the default permission for a specified command sender.
@ -138,12 +105,4 @@ public class CommandPermissions {
return false; 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; 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. * Check whether the command is executable.
* *
* @return True if the command is executable, false otherwise. * @return True if the command is executable, false otherwise.
*/ */
public boolean isExecutable() { public boolean isExecutable() {
// Make sure the command description is valid return commandDescription != null;
if (this.commandDescription == null)
return false;
// Check whether the command is executable, return the result
return this.commandDescription.isExecutable();
} }
/** /**
@ -153,10 +139,11 @@ public class FoundCommandResult {
*/ */
public double getDifference() { public double getDifference() {
// Get the difference through the command found // Get the difference through the command found
if (this.commandDescription != null) if (this.commandDescription != null) {
return this.commandDescription.getCommandDifference(this.queryReference); return this.commandDescription.getCommandDifference(this.queryReference);
}
// Get the difference from the query reference // 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.cache.auth.PlayerAuth;
import fr.xephi.authme.command.CommandParts; import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.settings.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.settings.Messages; import fr.xephi.authme.output.Messages;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender; 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.CommandParts;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.security.PasswordSecurity; import fr.xephi.authme.security.PasswordSecurity;
import fr.xephi.authme.settings.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.settings.Messages; import fr.xephi.authme.output.Messages;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@ -16,8 +16,9 @@ import org.bukkit.command.CommandSender;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
/** /**
* Admin command for changing a player's password.
*/ */
public class ChangePasswordCommand extends ExecutableCommand { public class ChangePasswordAdminCommand extends ExecutableCommand {
@Override @Override
public boolean executeCommand(final CommandSender sender, CommandParts commandReference, CommandParts commandArguments) { public boolean executeCommand(final CommandSender sender, CommandParts commandReference, CommandParts commandArguments) {
@ -31,24 +32,27 @@ public class ChangePasswordCommand extends ExecutableCommand {
// Validate the password // Validate the password
String playerPassLowerCase = playerPass.toLowerCase(); 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)) { if (playerPassLowerCase.contains("delete") || playerPassLowerCase.contains("where")
m.send(sender, MessageKey.PASSWORD_IS_USERNAME_ERROR); || 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; return true;
} }
if (playerPassLowerCase.equalsIgnoreCase(playerName)) { if (playerPassLowerCase.equalsIgnoreCase(playerName)) {
m.send(sender, MessageKey.PASSWORD_IS_USERNAME_ERROR); m.send(sender, MessageKey.PASSWORD_IS_USERNAME_ERROR);
return true; 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); m.send(sender, MessageKey.INVALID_PASSWORD_LENGTH);
return true; return true;
} }
if (!Settings.unsafePasswords.isEmpty()) { if (!Settings.unsafePasswords.isEmpty() && Settings.unsafePasswords.contains(playerPassLowerCase)) {
if (Settings.unsafePasswords.contains(playerPassLowerCase)) {
m.send(sender, MessageKey.PASSWORD_UNSAFE_ERROR); m.send(sender, MessageKey.PASSWORD_UNSAFE_ERROR);
return true; return true;
} }
}
// Set the password // Set the password
final String playerNameLowerCase = playerName.toLowerCase(); final String playerNameLowerCase = playerName.toLowerCase();
Bukkit.getScheduler().runTaskAsynchronously(plugin, new Runnable() { Bukkit.getScheduler().runTaskAsynchronously(plugin, new Runnable() {

View File

@ -3,7 +3,7 @@ package fr.xephi.authme.command.executable.authme;
import fr.xephi.authme.AuthMe; import fr.xephi.authme.AuthMe;
import fr.xephi.authme.command.CommandParts; import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand; 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.Bukkit;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -30,11 +30,11 @@ public class ForceLoginCommand extends ExecutableCommand {
sender.sendMessage("Player needs to be online!"); sender.sendMessage("Player needs to be online!");
return true; 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 + "!"); sender.sendMessage("You cannot force login for the player " + playerName + "!");
return true; return true;
} }
plugin.management.performLogin(player, "dontneed", true); plugin.getManagement().performLogin(player, "dontneed", true);
sender.sendMessage("Force Login for " + playerName + " performed!"); sender.sendMessage("Force Login for " + playerName + " performed!");
} catch (Exception e) { } catch (Exception e) {
sender.sendMessage("An error occurred while trying to get that player!"); 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.cache.auth.PlayerAuth;
import fr.xephi.authme.command.CommandParts; import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.settings.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.settings.Messages; import fr.xephi.authme.output.Messages;
import org.bukkit.command.CommandSender; 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.cache.auth.PlayerAuth;
import fr.xephi.authme.command.CommandParts; import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.settings.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.settings.Messages; import fr.xephi.authme.output.Messages;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import java.util.Date; 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.cache.auth.PlayerAuth;
import fr.xephi.authme.command.CommandParts; import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.settings.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.settings.Messages; import fr.xephi.authme.output.Messages;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; 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.CommandParts;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.security.PasswordSecurity; import fr.xephi.authme.security.PasswordSecurity;
import fr.xephi.authme.settings.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.settings.Messages; import fr.xephi.authme.output.Messages;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@ -15,8 +15,9 @@ import org.bukkit.command.CommandSender;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
/** /**
* Admin command to register a user.
*/ */
public class RegisterCommand extends ExecutableCommand { public class RegisterAdminCommand extends ExecutableCommand {
/** /**
* Execute the command. * Execute the command.
@ -42,8 +43,12 @@ public class RegisterCommand extends ExecutableCommand {
final String playerPassLowerCase = playerPass.toLowerCase(); final String playerPassLowerCase = playerPass.toLowerCase();
// Command logic // 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)) { if (playerPassLowerCase.contains("delete") || playerPassLowerCase.contains("where")
m.send(sender, MessageKey.PASSWORD_IS_USERNAME_ERROR); || 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; return true;
} }
if (playerPassLowerCase.equalsIgnoreCase(playerName)) { if (playerPassLowerCase.equalsIgnoreCase(playerName)) {

View File

@ -6,8 +6,8 @@ import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.command.CommandParts; import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.settings.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.settings.Messages; import fr.xephi.authme.output.Messages;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.util.Profiler; import fr.xephi.authme.util.Profiler;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@ -41,7 +41,7 @@ public class ReloadCommand extends ExecutableCommand {
try { try {
Settings.reload(); Settings.reload();
plugin.setMessages(new Messages(Settings.messageFile, Settings.messagesLanguage)); Messages.getInstance().reloadManager();
plugin.getModuleManager().reloadModules(); plugin.getModuleManager().reloadModules();
plugin.setupDatabase(); plugin.setupDatabase();
} catch (Exception e) { } 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.cache.auth.PlayerCache;
import fr.xephi.authme.command.CommandParts; import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.settings.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.settings.Messages; import fr.xephi.authme.output.Messages;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import org.bukkit.command.CommandSender; 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.AntiBot;
import fr.xephi.authme.command.CommandParts; import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.CommandUtils;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.command.help.HelpProvider; import fr.xephi.authme.command.help.HelpProvider;
import fr.xephi.authme.util.CollectionUtils;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import java.util.List;
/** /**
*/ */
public class SwitchAntiBotCommand extends ExecutableCommand { public class SwitchAntiBotCommand extends ExecutableCommand {
@ -32,16 +36,16 @@ public class SwitchAntiBotCommand extends ExecutableCommand {
} }
// Enable the mod // Enable the mod
if (newState.equalsIgnoreCase("ON")) { if ("ON".equalsIgnoreCase(newState)) {
AntiBot.overrideAntiBotStatus(true); AntiBot.overrideAntiBotStatus(true);
sender.sendMessage("[AuthMe] AntiBot Manual Ovverride: enabled!"); sender.sendMessage("[AuthMe] AntiBot Manual Override: enabled!");
return true; return true;
} }
// Disable the mod // Disable the mod
if (newState.equalsIgnoreCase("OFF")) { if ("OFF".equalsIgnoreCase(newState)) {
AntiBot.overrideAntiBotStatus(false); AntiBot.overrideAntiBotStatus(false);
sender.sendMessage("[AuthMe] AntiBotMod Manual Ovverride: disabled!"); sender.sendMessage("[AuthMe] AntiBotMod Manual Override: disabled!");
return true; return true;
} }
@ -52,8 +56,9 @@ public class SwitchAntiBotCommand extends ExecutableCommand {
HelpProvider.showHelp(sender, commandReference, commandReference, true, false, true, false, false, false); HelpProvider.showHelp(sender, commandReference, commandReference, true, false, true, false, false, false);
// Show the command to use for detailed help // Show the command to use for detailed help
CommandParts helpCommandReference = new CommandParts(commandReference.getRange(1)); List<String> helpCommandReference = CollectionUtils.getRange(commandReference.getList(), 1);
sender.sendMessage(ChatColor.GOLD + "Detailed help: " + ChatColor.WHITE + "/" + commandReference.get(0) + " help " + helpCommandReference); sender.sendMessage(ChatColor.GOLD + "Detailed help: " + ChatColor.WHITE + "/"
+ commandReference.get(0) + " help " + CommandUtils.labelsToString(helpCommandReference));
return true; 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.cache.limbo.LimboCache;
import fr.xephi.authme.command.CommandParts; import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.settings.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.settings.Messages; import fr.xephi.authme.output.Messages;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.task.MessageTask; import fr.xephi.authme.task.MessageTask;
import fr.xephi.authme.task.TimeoutTask; import fr.xephi.authme.task.TimeoutTask;
@ -21,8 +21,9 @@ import org.bukkit.scheduler.BukkitScheduler;
import org.bukkit.scheduler.BukkitTask; import org.bukkit.scheduler.BukkitTask;
/** /**
* Admin command to unregister a player.
*/ */
public class UnregisterCommand extends ExecutableCommand { public class UnregisterAdminCommand extends ExecutableCommand {
/** /**
* Execute the command. * 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.CommandParts;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.security.RandomString; import fr.xephi.authme.security.RandomString;
import fr.xephi.authme.settings.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.settings.Messages; import fr.xephi.authme.output.Messages;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.util.Wrapper;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -30,10 +31,11 @@ public class CaptchaCommand extends ExecutableCommand {
String captcha = commandArguments.get(0); String captcha = commandArguments.get(0);
// AuthMe plugin instance // AuthMe plugin instance
final AuthMe plugin = AuthMe.getInstance(); final Wrapper wrapper = Wrapper.getInstance();
final AuthMe plugin = wrapper.getAuthMe();
// Messages instance // Messages instance
final Messages m = plugin.getMessages(); final Messages m = wrapper.getMessages();
// Command logic // Command logic
if (PlayerCache.getInstance().isAuthenticated(playerNameLowerCase)) { 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.cache.auth.PlayerCache;
import fr.xephi.authme.command.CommandParts; import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.settings.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.settings.Messages; import fr.xephi.authme.output.Messages;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.task.ChangePasswordTask; import fr.xephi.authme.task.ChangePasswordTask;
import fr.xephi.authme.util.Wrapper; import fr.xephi.authme.util.Wrapper;
@ -13,6 +13,7 @@ import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
/** /**
* The command for a player to change his password with.
*/ */
public class ChangePasswordCommand extends ExecutableCommand { public class ChangePasswordCommand extends ExecutableCommand {
@ -27,10 +28,10 @@ public class ChangePasswordCommand extends ExecutableCommand {
final Messages m = wrapper.getMessages(); final Messages m = wrapper.getMessages();
// Get the passwords // Get the passwords
String playerPass = commandArguments.get(0); String oldPassword = commandArguments.get(0);
String playerPassVerify = commandArguments.get(1); 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; Player player = (Player) sender;
String name = player.getName().toLowerCase(); String name = player.getName().toLowerCase();
final PlayerCache playerCache = wrapper.getPlayerCache(); final PlayerCache playerCache = wrapper.getPlayerCache();
@ -40,8 +41,7 @@ public class ChangePasswordCommand extends ExecutableCommand {
} }
// Make sure the password is allowed // Make sure the password is allowed
// TODO ljacqu 20151121: The password confirmation appears to be never verified String playerPassLowerCase = newPassword.toLowerCase();
String playerPassLowerCase = playerPass.toLowerCase();
if (playerPassLowerCase.contains("delete") || playerPassLowerCase.contains("where") if (playerPassLowerCase.contains("delete") || playerPassLowerCase.contains("where")
|| playerPassLowerCase.contains("insert") || playerPassLowerCase.contains("modify") || playerPassLowerCase.contains("insert") || playerPassLowerCase.contains("modify")
|| playerPassLowerCase.contains("from") || playerPassLowerCase.contains("select") || playerPassLowerCase.contains("from") || playerPassLowerCase.contains("select")
@ -66,8 +66,8 @@ public class ChangePasswordCommand extends ExecutableCommand {
// Set the password // Set the password
final AuthMe plugin = wrapper.getAuthMe(); final AuthMe plugin = wrapper.getAuthMe();
wrapper.getServer().getScheduler().runTaskAsynchronously(plugin, wrapper.getScheduler().runTaskAsynchronously(plugin,
new ChangePasswordTask(plugin, player, playerPass, playerPassVerify)); new ChangePasswordTask(plugin, player, oldPassword, newPassword));
return true; return true;
} }
} }

View File

@ -4,8 +4,8 @@ import fr.xephi.authme.AuthMe;
import fr.xephi.authme.command.CommandParts; import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.converter.*; import fr.xephi.authme.converter.*;
import fr.xephi.authme.settings.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.settings.Messages; import fr.xephi.authme.output.Messages;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender; 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.command.ExecutableCommand;
import fr.xephi.authme.security.PasswordSecurity; import fr.xephi.authme.security.PasswordSecurity;
import fr.xephi.authme.security.RandomString; import fr.xephi.authme.security.RandomString;
import fr.xephi.authme.settings.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.settings.Messages; import fr.xephi.authme.output.Messages;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.util.Wrapper; import fr.xephi.authme.util.Wrapper;
import org.bukkit.command.CommandSender; 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.command.ExecutableCommand;
import fr.xephi.authme.process.Management; import fr.xephi.authme.process.Management;
import fr.xephi.authme.security.RandomString; import fr.xephi.authme.security.RandomString;
import fr.xephi.authme.settings.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.settings.Messages; import fr.xephi.authme.output.Messages;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.util.Wrapper; import fr.xephi.authme.util.Wrapper;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@ -55,7 +55,7 @@ public class RegisterCommand extends ExecutableCommand {
} }
if (commandArguments.getCount() > 1 && Settings.getEnablePasswordVerifier) { if (commandArguments.getCount() > 1 && Settings.getEnablePasswordVerifier) {
if (!commandArguments.get(0).equals(commandArguments.get(1))) { 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; return true;
} }
} }

View File

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

View File

@ -1,20 +1,22 @@
package fr.xephi.authme.command.help; 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.AuthMe;
import fr.xephi.authme.command.CommandArgumentDescription; import fr.xephi.authme.command.CommandArgumentDescription;
import fr.xephi.authme.command.CommandDescription; import fr.xephi.authme.command.CommandDescription;
import fr.xephi.authme.command.CommandParts; import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.CommandPermissions; import fr.xephi.authme.command.CommandPermissions;
import fr.xephi.authme.permission.PermissionNode; import fr.xephi.authme.permission.PermissionNode;
import fr.xephi.authme.util.CollectionUtils;
import fr.xephi.authme.util.StringUtils; 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,8 +41,6 @@ public class HelpPrinter {
* @param command The command to print the description help for. * @param command The command to print the description help for.
*/ */
public static void printCommandDescription(CommandSender sender, CommandDescription command) { 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 // Print the detailed description, if available
@ -59,7 +59,7 @@ public class HelpPrinter {
@SuppressWarnings("StringConcatenationInsideStringBufferAppend") @SuppressWarnings("StringConcatenationInsideStringBufferAppend")
public static void printArguments(CommandSender sender, CommandDescription command) { public static void printArguments(CommandSender sender, CommandDescription command) {
// Make sure there are any commands to print // Make sure there are any commands to print
if (!command.hasArguments() && command.getMaximumArguments() >= 0) if (!command.hasArguments())
return; return;
// Print the header // Print the header
@ -78,10 +78,6 @@ public class HelpPrinter {
// Print the syntax // Print the syntax
sender.sendMessage(argString.toString()); 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. * @param command The command to print the permissions help for.
*/ */
public static void printPermissions(CommandSender sender, CommandDescription command) { 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(); CommandPermissions permissions = command.getCommandPermissions();
if (permissions == null) if (permissions == null || CollectionUtils.isEmpty(permissions.getPermissionNodes())) {
return;
// Make sure any permission node is set
if (permissions.getPermissionNodeCount() <= 0)
return; return;
}
// Print the header // Print the header
sender.sendMessage(ChatColor.GOLD + "Permissions:"); sender.sendMessage(ChatColor.GOLD + "Permissions:");
@ -113,13 +106,16 @@ public class HelpPrinter {
} }
// Print the default permission // 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()) { switch (permissions.getDefaultPermission()) {
case ALLOWED: case ALLOWED:
sender.sendMessage(ChatColor.GOLD + " Default: " + ChatColor.GRAY + ChatColor.ITALIC + "Permission!"); sender.sendMessage(ChatColor.GOLD + " Default: " + ChatColor.GRAY + ChatColor.ITALIC + "Permission!");
break; break;
case OP_ONLY: 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); sender.sendMessage(ChatColor.GOLD + " Default: " + ChatColor.YELLOW + ChatColor.ITALIC + "OP's Only!" + defaultPermsString);
break; break;

View File

@ -3,12 +3,17 @@ package fr.xephi.authme.command.help;
import fr.xephi.authme.AuthMe; import fr.xephi.authme.AuthMe;
import fr.xephi.authme.command.CommandDescription; import fr.xephi.authme.command.CommandDescription;
import fr.xephi.authme.command.CommandParts; import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.CommandUtils;
import fr.xephi.authme.command.FoundCommandResult; import fr.xephi.authme.command.FoundCommandResult;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.util.CollectionUtils;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import java.util.ArrayList;
import java.util.List;
/** /**
*/ */
public class HelpProvider { 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) { 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 // 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())); FoundCommandResult result = AuthMe.getInstance().getCommandHandler().findCommand(new CommandParts(helpQuery.getList()));
CommandParts commandReferenceOther = new CommandParts(reference.get(0), helpQuery.getList());
FoundCommandResult resultOther = AuthMe.getInstance().getCommandHandler().getCommandManager().findCommand(commandReferenceOther); // 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 (resultOther != null) {
if (result == null) if (result == null)
result = resultOther; result = resultOther;
@ -78,13 +88,14 @@ public class HelpProvider {
// Show the unknown command warning // Show the unknown command warning
sender.sendMessage(ChatColor.DARK_RED + "No help found for '" + helpQuery + "'!"); 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 // Show a command suggestion if available and the difference isn't too big
if (commandDifference < 0.75) if (commandDifference < 0.75 && result.getCommandDescription() != null) {
if (result.getCommandDescription() != null) // Get the suggested command
sender.sendMessage(ChatColor.YELLOW + "Did you mean " + ChatColor.GOLD + "/" + baseCommand + " help " + suggestedCommandParts + ChatColor.YELLOW + "?"); 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 // Show the help command
sender.sendMessage(ChatColor.YELLOW + "Use the command " + ChatColor.GOLD + "/" + baseCommand + " help" + ChatColor.YELLOW + " to view help."); 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 // Show a message when the command handler is assuming a command
if (commandDifference > 0) { if (commandDifference > 0) {
// Get the suggested command // 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 // 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 // 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.CommandArgumentDescription;
import fr.xephi.authme.command.CommandDescription; import fr.xephi.authme.command.CommandDescription;
import fr.xephi.authme.command.CommandParts; 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 fr.xephi.authme.util.StringUtils;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
@ -35,8 +37,8 @@ public final class HelpSyntaxHelper {
// Get the help command reference, and the command label // Get the help command reference, and the command label
CommandParts helpCommandReference = commandDescription.getCommandReference(commandReference); CommandParts helpCommandReference = commandDescription.getCommandReference(commandReference);
final String parentCommand = new CommandParts( final String parentCommand = CommandUtils.labelsToString(
helpCommandReference.getRange(0, helpCommandReference.getCount() - 1)).toString(); CollectionUtils.getRange(helpCommandReference.getList(), 0, helpCommandReference.getCount() - 1));
// Check whether the alternative label should be used // Check whether the alternative label should be used
String commandLabel; String commandLabel;
@ -61,11 +63,6 @@ public final class HelpSyntaxHelper {
sb.append(ChatColor.ITALIC).append(formatArgument(arg)); 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 the build command syntax
return sb.toString(); 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.cache.auth.PlayerAuth;
import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.datasource.FlatFile; import fr.xephi.authme.datasource.FlatFile;
import fr.xephi.authme.settings.MessageKey; import fr.xephi.authme.output.MessageKey;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import java.util.List; import java.util.List;

View File

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

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

View File

@ -52,6 +52,11 @@ public class AuthMeEntityListener implements Listener {
if (Utils.checkAuth(player) ) { if (Utils.checkAuth(player) ) {
return; return;
} }
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC(player)) {
return;
}
player.setFireTicks(0); player.setFireTicks(0);
event.setDamage(0); event.setDamage(0);
event.setCancelled(true); event.setCancelled(true);
@ -73,6 +78,11 @@ public class AuthMeEntityListener implements Listener {
return; return;
} }
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC((Player) entity)) {
return;
}
event.setTarget(null); event.setTarget(null);
event.setCancelled(true); event.setCancelled(true);
} }
@ -83,7 +93,7 @@ public class AuthMeEntityListener implements Listener {
* @param event EntityDamageByEntityEvent * @param event EntityDamageByEntityEvent
*/ */
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST) @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
public void onDmg(EntityDamageByEntityEvent event) { public void onDamage(EntityDamageByEntityEvent event) {
Entity entity = event.getDamager(); Entity entity = event.getDamager();
if (entity == null || !(entity instanceof Player)) { if (entity == null || !(entity instanceof Player)) {
return; return;
@ -94,6 +104,11 @@ public class AuthMeEntityListener implements Listener {
return; return;
} }
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC(player)) {
return;
}
event.setCancelled(true); event.setCancelled(true);
} }
@ -113,6 +128,11 @@ public class AuthMeEntityListener implements Listener {
return; return;
} }
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC((Player) entity)) {
return;
}
event.setCancelled(true); event.setCancelled(true);
} }
@ -132,6 +152,11 @@ public class AuthMeEntityListener implements Listener {
return; return;
} }
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC((Player) entity)) {
return;
}
event.setAmount(0); event.setAmount(0);
event.setCancelled(true); event.setCancelled(true);
} }
@ -152,6 +177,11 @@ public class AuthMeEntityListener implements Listener {
return; return;
} }
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC((Player) entity)) {
return;
}
event.setCancelled(true); event.setCancelled(true);
} }
@ -171,6 +201,11 @@ public class AuthMeEntityListener implements Listener {
return; return;
} }
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC((Player) entity)) {
return;
}
event.setCancelled(true); event.setCancelled(true);
} }
@ -210,6 +245,11 @@ public class AuthMeEntityListener implements Listener {
return; return;
} }
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC(player)) {
return;
}
event.setCancelled(true); event.setCancelled(true);
} }
@ -230,6 +270,11 @@ public class AuthMeEntityListener implements Listener {
return; return;
} }
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC(player)) {
return;
}
event.setCancelled(true); 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.auth.PlayerCache;
import fr.xephi.authme.cache.limbo.LimboCache; import fr.xephi.authme.cache.limbo.LimboCache;
import fr.xephi.authme.cache.limbo.LimboPlayer; 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.PermissionsManager;
import fr.xephi.authme.permission.UserPermission; import fr.xephi.authme.permission.PlayerPermission;
import fr.xephi.authme.settings.MessageKey;
import fr.xephi.authme.settings.Messages;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.util.GeoLiteAPI; import fr.xephi.authme.util.GeoLiteAPI;
import fr.xephi.authme.util.Utils; 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.entity.EntityDamageByEntityEvent;
import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryOpenEvent; 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; import java.util.concurrent.ConcurrentHashMap;
@ -53,7 +70,6 @@ public class AuthMePlayerListener implements Listener {
} }
final Player player = event.getPlayer(); final Player player = event.getPlayer();
if (Utils.checkAuth(player)) { if (Utils.checkAuth(player)) {
for (Player p : Utils.getOnlinePlayers()) { for (Player p : Utils.getOnlinePlayers()) {
if (!PlayerCache.getInstance().isAuthenticated(p.getName())) { if (!PlayerCache.getInstance().isAuthenticated(p.getName())) {
@ -64,6 +80,11 @@ public class AuthMePlayerListener implements Listener {
} }
event.setCancelled(true); event.setCancelled(true);
sendLoginRegisterMSG(player);
}
// TODO: new name
private void sendLoginRegisterMSG(final Player player) {
plugin.getServer().getScheduler().runTaskAsynchronously(plugin, new Runnable() { plugin.getServer().getScheduler().runTaskAsynchronously(plugin, new Runnable() {
@Override @Override
public void run() { public void run() {
@ -93,6 +114,7 @@ public class AuthMePlayerListener implements Listener {
return; return;
} }
event.setCancelled(true); event.setCancelled(true);
sendLoginRegisterMSG(event.getPlayer());
} }
@EventHandler(ignoreCancelled = true, priority = EventPriority.NORMAL) @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) { public void onPlayerJoin(PlayerJoinEvent event) {
if (event.getPlayer() == null || Utils.isNPC(event.getPlayer())) { final Player player = event.getPlayer();
if (player == null) {
return; return;
} }
final Player player = event.getPlayer(); /* IMPOSSIBLE!!!! TODO: check this!
final String name = player.getName().toLowerCase(); if(Utils.isNPC(player)) {
final String joinMsg = event.getJoinMessage(); return;
final boolean delay = Settings.delayJoinLeaveMessages && joinMsg != null; }
*/
String name = player.getName().toLowerCase();
String joinMsg = event.getJoinMessage();
// Remove the join message while the player isn't logging in // Remove the join message while the player isn't logging in
if (delay) { if (Settings.delayJoinLeaveMessages && joinMsg != null) {
event.setJoinMessage(null); event.setJoinMessage(null);
joinMessage.put(name, joinMsg);
} }
// Shedule login task so works after the prelogin // Shedule login task so works after the prelogin
@ -188,9 +216,6 @@ public class AuthMePlayerListener implements Listener {
Bukkit.getScheduler().runTask(plugin, new Runnable() { Bukkit.getScheduler().runTask(plugin, new Runnable() {
@Override @Override
public void run() { public void run() {
if (delay) {
joinMessage.put(name, joinMsg);
}
plugin.getManagement().performJoin(player); plugin.getManagement().performJoin(player);
} }
}); });
@ -198,38 +223,57 @@ public class AuthMePlayerListener implements Listener {
@EventHandler(priority = EventPriority.HIGHEST) @EventHandler(priority = EventPriority.HIGHEST)
public void onPreLogin(AsyncPlayerPreLoginEvent event) { 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 String name = event.getName().toLowerCase();
final Player player = Utils.getPlayer(name); final Player player = Utils.getPlayer(name);
if (player == null || Utils.isNPC(player)) { if (player == null) {
return; return;
} }
// Check if forceSingleSession is set to true, so kick player that has // Check if forceSingleSession is set to true, so kick player that has
// joined with same nick of online player // joined with same nick of online player
if (Settings.isForceSingleSessionEnabled && player.isOnline()) { if (Settings.isForceSingleSessionEnabled) {
event.disallow(AsyncPlayerPreLoginEvent.Result.KICK_OTHER, m.getString("same_nick")); event.setLoginResult(AsyncPlayerPreLoginEvent.Result.KICK_OTHER);
if (LimboCache.getInstance().hasLimboPlayer(name)) event.setKickMessage(m.retrieveSingle(MessageKey.USERNAME_ALREADY_ONLINE_ERROR));
Bukkit.getScheduler().runTaskAsynchronously(plugin, new Runnable() {
@Override
public void run() {
LimboPlayer limbo = LimboCache.getInstance().getLimboPlayer(name); LimboPlayer limbo = LimboCache.getInstance().getLimboPlayer(name);
if (limbo != null && PlayerCache.getInstance().isAuthenticated(name)) { if (limbo != null && PlayerCache.getInstance().isAuthenticated(name)) {
Utils.addNormal(player, limbo.getGroup()); Utils.addNormal(player, limbo.getGroup());
LimboCache.getInstance().deleteLimboPlayer(name); LimboCache.getInstance().deleteLimboPlayer(name);
} }
} }
});
}
} }
@EventHandler(priority = EventPriority.HIGHEST) @EventHandler(priority = EventPriority.HIGHEST)
public void onPlayerLogin(PlayerLoginEvent event) { public void onPlayerLogin(PlayerLoginEvent event) {
if (event.getPlayer() == null) { final Player player = event.getPlayer();
if (player == null || Utils.isUnrestricted(player)) {
return; 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(); int playersOnline = Utils.getOnlinePlayers().size();
if (playersOnline > plugin.getServer().getMaxPlayers()) { if (playersOnline > plugin.getServer().getMaxPlayers()) {
event.allow(); event.allow();
@ -250,45 +294,19 @@ public class AuthMePlayerListener implements Listener {
return; return;
} }
// Get the permissions manager if (event.getResult() == PlayerLoginEvent.Result.KICK_FULL && !permsMan.hasPermission(player, PlayerPermission.IS_VIP)) {
PermissionsManager permsMan = plugin.getPermissionsManager();
final Player player = event.getPlayer();
if (event.getResult() == PlayerLoginEvent.Result.KICK_FULL && !permsMan.hasPermission(player, UserPermission.IS_VIP)) {
event.setKickMessage(m.retrieveSingle(MessageKey.KICK_FULL_SERVER)); event.setKickMessage(m.retrieveSingle(MessageKey.KICK_FULL_SERVER));
event.setResult(PlayerLoginEvent.Result.KICK_FULL); event.setResult(PlayerLoginEvent.Result.KICK_FULL);
return; return;
} }
if (Utils.isNPC(player) || Utils.isUnrestricted(player)) {
return;
}
final String name = player.getName().toLowerCase(); final String name = player.getName().toLowerCase();
boolean isAuthAvailable = plugin.database.isAuthAvailable(name); 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!!! // TODO: Add message to the messages file!!!
if (Settings.isKickNonRegisteredEnabled && !isAuthAvailable) { if (Settings.isKickNonRegisteredEnabled && !isAuthAvailable) {
if (Settings.antiBotInAction) { 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); event.setResult(PlayerLoginEvent.Result.KICK_OTHER);
return; return;
} else { } else {
@ -321,61 +339,77 @@ public class AuthMePlayerListener implements Listener {
@EventHandler(priority = EventPriority.MONITOR) @EventHandler(priority = EventPriority.MONITOR)
public void onPlayerQuit(PlayerQuitEvent event) { public void onPlayerQuit(PlayerQuitEvent event) {
if (event.getPlayer() == null) { Player player = event.getPlayer();
if (player == null) {
return; return;
} }
Player player = event.getPlayer(); if (Settings.delayJoinLeaveMessages && !Utils.checkAuth(player)) {
if (!Utils.checkAuth(player) && Settings.delayJoinLeaveMessages) {
event.setQuitMessage(null); event.setQuitMessage(null);
} }
plugin.management.performQuit(player, false); plugin.getManagement().performQuit(player, false);
} }
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
public void onPlayerKick(PlayerKickEvent event) { public void onPlayerKick(PlayerKickEvent event) {
if (event.getPlayer() == null) { Player player = event.getPlayer();
if (player == null) {
return; 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); event.setCancelled(true);
return; return;
} }
Player player = event.getPlayer(); plugin.getManagement().performQuit(player, true);
plugin.management.performQuit(player, true);
} }
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
public void onPlayerPickupItem(PlayerPickupItemEvent event) { 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; return;
}
event.setCancelled(true); event.setCancelled(true);
} }
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST) @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
public void onPlayerInteract(PlayerInteractEvent event) { public void onPlayerInteract(PlayerInteractEvent event) {
Player player = event.getPlayer(); 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; return;
}
event.setCancelled(true); event.setCancelled(true);
} }
@EventHandler(ignoreCancelled = true, priority = EventPriority.NORMAL) @EventHandler(ignoreCancelled = true, priority = EventPriority.NORMAL)
public void onPlayerConsumeItem(PlayerItemConsumeEvent event) { 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; return;
}
event.setCancelled(true); event.setCancelled(true);
} }
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
public void onPlayerInventoryOpen(InventoryOpenEvent event) { public void onPlayerInventoryOpen(InventoryOpenEvent event) {
final Player player = (Player) event.getPlayer(); 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; return;
}
event.setCancelled(true); 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 * real, cause no packet is send to server by client for the main inv
*/ */
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() { Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
@Override @Override
public void run() { public void run() {
player.closeInventory(); player.closeInventory();
@ -399,6 +432,10 @@ public class AuthMePlayerListener implements Listener {
return; return;
if (Utils.checkAuth((Player) event.getWhoClicked())) if (Utils.checkAuth((Player) event.getWhoClicked()))
return; return;
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC((Player) event.getWhoClicked()))
return;
event.setCancelled(true); event.setCancelled(true);
} }
@ -408,50 +445,85 @@ public class AuthMePlayerListener implements Listener {
if (!(damager instanceof Player)) { if (!(damager instanceof Player)) {
return; return;
} }
if (Utils.checkAuth((Player) damager)) if (Utils.checkAuth((Player) damager)) {
return; return;
}
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC((Player) damager)) {
return;
}
event.setCancelled(true); event.setCancelled(true);
} }
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST) @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
public void onPlayerInteractEntity(PlayerInteractEntityEvent event) { public void onPlayerInteractEntity(PlayerInteractEntityEvent event) {
Player player = event.getPlayer(); if (Utils.checkAuth(event.getPlayer())) {
if (player == null || Utils.checkAuth(player))
return; return;
}
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC(event.getPlayer())) {
return;
}
event.setCancelled(true); event.setCancelled(true);
} }
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST) @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
public void onPlayerDropItem(PlayerDropItemEvent event) { public void onPlayerDropItem(PlayerDropItemEvent event) {
if (Utils.checkAuth(event.getPlayer())) if (Utils.checkAuth(event.getPlayer())) {
return; return;
}
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC(event.getPlayer())) {
return;
}
event.setCancelled(true); event.setCancelled(true);
} }
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST) @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
public void onPlayerBedEnter(PlayerBedEnterEvent event) { public void onPlayerBedEnter(PlayerBedEnterEvent event) {
if (Utils.checkAuth(event.getPlayer())) if (Utils.checkAuth(event.getPlayer())) {
return; return;
}
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC(event.getPlayer())) {
return;
}
event.setCancelled(true); event.setCancelled(true);
} }
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST) @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
public void onSignChange(SignChangeEvent event) { public void onSignChange(SignChangeEvent event) {
if (Utils.checkAuth(event.getPlayer())) if (Utils.checkAuth(event.getPlayer())) {
return; return;
}
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC(event.getPlayer())) {
return;
}
event.setCancelled(true); event.setCancelled(true);
} }
@EventHandler(priority = EventPriority.HIGHEST) @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
public void onPlayerRespawn(PlayerRespawnEvent event) { public void onPlayerRespawn(PlayerRespawnEvent event) {
Player player = event.getPlayer(); if (Utils.checkAuth(event.getPlayer())) {
if (player == null || Utils.checkAuth(player))
return; 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(); String name = player.getName().toLowerCase();
Location spawn = plugin.getSpawnLocation(player); Location spawn = plugin.getSpawnLocation(player);
if (Settings.isSaveQuitLocationEnabled && plugin.database.isAuthAvailable(name)) { 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); plugin.database.updateQuitLoc(auth);
} }
if (spawn != null && spawn.getWorld() != null) { if (spawn != null && spawn.getWorld() != null) {
@ -461,13 +533,19 @@ public class AuthMePlayerListener implements Listener {
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
public void onPlayerGameModeChange(PlayerGameModeChangeEvent event) { 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(); Player player = event.getPlayer();
if (player == null) if (plugin.getPermissionsManager().hasPermission(player, PlayerPermission.BYPASS_FORCE_SURVIVAL)) {
return;
if (plugin.getPermissionsManager().hasPermission(player, UserPermission.BYPASS_FORCE_SURVIVAL))
return;
if (Utils.checkAuth(player))
return; return;
}
String name = player.getName().toLowerCase(); String name = player.getName().toLowerCase();
if (causeByAuthMe.containsKey(name)) { if (causeByAuthMe.containsKey(name)) {
@ -479,17 +557,27 @@ public class AuthMePlayerListener implements Listener {
@EventHandler(ignoreCancelled = true, priority = EventPriority.NORMAL) @EventHandler(ignoreCancelled = true, priority = EventPriority.NORMAL)
public void onPlayerShear(PlayerShearEntityEvent event) { public void onPlayerShear(PlayerShearEntityEvent event) {
Player player = event.getPlayer(); if (Utils.checkAuth(event.getPlayer())) {
if (player == null || Utils.checkAuth(player))
return; return;
}
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC(event.getPlayer())) {
return;
}
event.setCancelled(true); event.setCancelled(true);
} }
@EventHandler(ignoreCancelled = true, priority = EventPriority.NORMAL) @EventHandler(ignoreCancelled = true, priority = EventPriority.NORMAL)
public void onPlayerFish(PlayerFishEvent event) { public void onPlayerFish(PlayerFishEvent event) {
Player player = event.getPlayer(); if (Utils.checkAuth(event.getPlayer())) {
if (player == null || Utils.checkAuth(player))
return; return;
}
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC(event.getPlayer())) {
return;
}
event.setCancelled(true); event.setCancelled(true);
} }

View File

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

View File

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

View File

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

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.Level;
import org.apache.logging.log4j.Marker; 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.LogEvent;
import org.apache.logging.log4j.core.Logger; import org.apache.logging.log4j.core.Logger;
import org.apache.logging.log4j.message.Message; 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. * Implements a filter for Log4j to skip sensitive AuthMe commands.
* *
* @author Xephi59 * @author Xephi59
* @version $Revision: 1.0 $
*/ */
public class Log4JFilter implements org.apache.logging.log4j.core.Filter { public class Log4JFilter implements 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 "};
/** /**
* Constructor. * 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 * Validates a Message instance and returns the {@link Result} value
* depending depending on whether the message contains sensitive AuthMe * depending on whether the message contains sensitive AuthMe data.
* 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) { private static Result validateMessage(Message message) {
if (message == null) { 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 * 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) { private static Result validateMessage(String message) {
if (message == null) { return LogFilterHelper.isSensitiveAuthMeCommand(message)
return Result.NEUTRAL; ? Result.DENY
} : Result.NEUTRAL;
String lowerMessage = message.toLowerCase();
if (lowerMessage.contains("issued server command:")
&& StringUtils.containsAny(lowerMessage, COMMANDS_TO_SKIP)) {
return Result.DENY;
}
return Result.NEUTRAL;
} }
@Override @Override
@ -74,14 +58,12 @@ public class Log4JFilter implements org.apache.logging.log4j.core.Filter {
} }
@Override @Override
public Result filter(Logger arg0, Level arg1, Marker arg2, String message, public Result filter(Logger arg0, Level arg1, Marker arg2, String message, Object... arg4) {
Object... arg4) {
return validateMessage(message); return validateMessage(message);
} }
@Override @Override
public Result filter(Logger arg0, Level arg1, Marker arg2, Object message, public Result filter(Logger arg0, Level arg1, Marker arg2, Object message, Throwable arg4) {
Throwable arg4) {
if (message == null) { if (message == null) {
return Result.NEUTRAL; return Result.NEUTRAL;
} }
@ -89,8 +71,7 @@ public class Log4JFilter implements org.apache.logging.log4j.core.Filter {
} }
@Override @Override
public Result filter(Logger arg0, Level arg1, Marker arg2, Message message, public Result filter(Logger arg0, Level arg1, Marker arg2, Message message, Throwable arg4) {
Throwable arg4) {
return validateMessage(message); 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}. * Keys for translatable messages managed by {@link Messages}.
*/ */
public enum MessageKey { public enum MessageKey {
KICK_ANTIBOT("kick_antibot"),
UNKNOWN_USER("unknown_user"), UNKNOWN_USER("unknown_user"),
UNSAFE_QUIT_LOCATION("unsafe_spawn"), 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; package fr.xephi.authme.permission;
/** /**
* AuthMe admin permissions. * AuthMe admin command permissions.
*/ */
public enum AdminPermission implements PermissionNode { public enum AdminPermission implements PermissionNode {
/**
* Administrator command to register a new user.
*/
REGISTER("authme.admin.register"), REGISTER("authme.admin.register"),
/**
* Administrator command to unregister an existing user.
*/
UNREGISTER("authme.admin.unregister"), UNREGISTER("authme.admin.unregister"),
/**
* Administrator command to force-login an existing user.
*/
FORCE_LOGIN("authme.admin.forcelogin"), FORCE_LOGIN("authme.admin.forcelogin"),
/**
* Administrator command to change the password of a user.
*/
CHANGE_PASSWORD("authme.admin.changepassword"), CHANGE_PASSWORD("authme.admin.changepassword"),
/**
* Administrator command to see the last login date and time of a user.
*/
LAST_LOGIN("authme.admin.lastlogin"), LAST_LOGIN("authme.admin.lastlogin"),
/**
* Administrator command to see all accounts associated with a user.
*/
ACCOUNTS("authme.admin.accounts"), ACCOUNTS("authme.admin.accounts"),
/**
* Administrator command to get the email address of a user, if set.
*/
GET_EMAIL("authme.admin.getemail"), 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"), GET_IP("authme.admin.getip"),
/**
* Administrator command to teleport to the AuthMe spawn.
*/
SPAWN("authme.admin.spawn"), SPAWN("authme.admin.spawn"),
/**
* Administrator command to set the AuthMe spawn.
*/
SET_SPAWN("authme.admin.setspawn"), SET_SPAWN("authme.admin.setspawn"),
/**
* Administrator command to teleport to the first AuthMe spawn.
*/
FIRST_SPAWN("authme.admin.firstspawn"), FIRST_SPAWN("authme.admin.firstspawn"),
/**
* Administrator command to set the first AuthMe spawn.
*/
SET_FIRST_SPAWN("authme.admin.setfirstspawn"), SET_FIRST_SPAWN("authme.admin.setfirstspawn"),
/**
* Administrator command to purge old user data.
*/
PURGE("authme.admin.purge"), PURGE("authme.admin.purge"),
/**
* Administrator command to purge the last position of a user.
*/
PURGE_LAST_POSITION("authme.admin.purgelastpos"), PURGE_LAST_POSITION("authme.admin.purgelastpos"),
/**
* Administrator command to purge all data associated with banned players.
*/
PURGE_BANNED_PLAYERS("authme.admin.purgebannedplayers"), PURGE_BANNED_PLAYERS("authme.admin.purgebannedplayers"),
/**
* Administrator command to toggle the AntiBot protection status.
*/
SWITCH_ANTIBOT("authme.admin.switchantibot"), 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; private String node;
/**
* Constructor.
*
* @param node Permission node.
*/
AdminPermission(String node) {
this.node = node;
}
@Override @Override
public String getNode() { public String getNode() {
return node; return node;
} }
AdminPermission(String node) { @Override
this.node = node; 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 { 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(); 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 com.nijikokun.bukkit.Permissions.Permissions;
import de.bananaco.bpermissions.api.ApiLayer; import de.bananaco.bpermissions.api.ApiLayer;
import de.bananaco.bpermissions.api.CalculableType; 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 net.milkbowl.vault.permission.Permission;
import org.anjocaido.groupmanager.GroupManager; import org.anjocaido.groupmanager.GroupManager;
import org.anjocaido.groupmanager.permissions.AnjoPermissionsHandler; import org.anjocaido.groupmanager.permissions.AnjoPermissionsHandler;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Server; import org.bukkit.Server;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.server.PluginDisableEvent; import org.bukkit.event.server.PluginDisableEvent;
import org.bukkit.event.server.PluginEnableEvent; import org.bukkit.event.server.PluginEnableEvent;
@ -38,7 +41,7 @@ import java.util.logging.Logger;
* @author Tim Visée, http://timvisee.com * @author Tim Visée, http://timvisee.com
* @version 0.2.1 * @version 0.2.1
*/ */
public class PermissionsManager { public class PermissionsManager implements PermissionsService {
/** /**
* Vault instance. * Vault instance.
@ -100,8 +103,8 @@ public class PermissionsManager {
* *
* @return The name of the permissions system used. * @return The name of the permissions system used.
*/ */
public String getUsedPermissionsSystemType() { public PermissionsSystemType getSystem() {
return this.permsType.getName(); 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, * 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) { 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. * @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 no permissions system is used, return the default value
if (!isEnabled()) if (!isEnabled())
return def; return def;
@ -914,34 +924,5 @@ public class PermissionsManager {
return removeGroups(player, groupNames); 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.ConsoleLogger;
import fr.xephi.authme.cache.auth.PlayerAuth; import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.cache.auth.PlayerCache; import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.permission.UserPermission; import fr.xephi.authme.permission.PlayerPermission;
import fr.xephi.authme.settings.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.settings.Messages; import fr.xephi.authme.output.Messages;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -39,7 +39,7 @@ public class AsyncChangeEmail {
String playerName = player.getName().toLowerCase(); String playerName = player.getName().toLowerCase();
if (Settings.getmaxRegPerEmail > 0) { 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) { && plugin.database.getAllAuthsByEmail(newEmail).size() >= Settings.getmaxRegPerEmail) {
m.send(player, MessageKey.MAX_REGISTER_EXCEEDED); m.send(player, MessageKey.MAX_REGISTER_EXCEEDED);
return; return;

View File

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

View File

@ -8,11 +8,11 @@ import fr.xephi.authme.cache.limbo.LimboCache;
import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.events.AuthMeAsyncPreLoginEvent; import fr.xephi.authme.events.AuthMeAsyncPreLoginEvent;
import fr.xephi.authme.listener.AuthMePlayerListener; 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.PasswordSecurity;
import fr.xephi.authme.security.RandomString; import fr.xephi.authme.security.RandomString;
import fr.xephi.authme.settings.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.settings.Messages; import fr.xephi.authme.output.Messages;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.task.MessageTask; import fr.xephi.authme.task.MessageTask;
import fr.xephi.authme.util.Utils; import fr.xephi.authme.util.Utils;
@ -80,15 +80,12 @@ public class AsynchronousLogin {
plugin.captcha.remove(name); plugin.captcha.remove(name);
plugin.captcha.putIfAbsent(name, i); plugin.captcha.putIfAbsent(name, i);
} }
if (plugin.captcha.containsKey(name) && plugin.captcha.get(name) >= Settings.maxLoginTry) { if (plugin.captcha.containsKey(name) && plugin.captcha.get(name) > Settings.maxLoginTry) {
plugin.cap.put(name, rdm.nextString()); plugin.cap.putIfAbsent(name, rdm.nextString());
for (String s : m.retrieve(MessageKey.USAGE_CAPTCHA)) { for (String s : m.retrieve(MessageKey.USAGE_CAPTCHA)) {
player.sendMessage(s.replace("THE_CAPTCHA", plugin.cap.get(name)).replace("<theCaptcha>", plugin.cap.get(name))); player.sendMessage(s.replace("THE_CAPTCHA", plugin.cap.get(name)).replace("<theCaptcha>", plugin.cap.get(name)));
} }
return true; return true;
} else if (plugin.captcha.containsKey(name) && plugin.captcha.get(name) >= Settings.maxLoginTry) {
plugin.captcha.remove(name);
plugin.cap.remove(name);
} }
} }
return false; return false;
@ -120,7 +117,7 @@ public class AsynchronousLogin {
} }
return null; 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())) { if (plugin.isLoggedIp(name, getIP())) {
m.send(player, MessageKey.ALREADY_LOGGED_IN_ERROR); m.send(player, MessageKey.ALREADY_LOGGED_IN_ERROR);
return null; return null;
@ -135,6 +132,13 @@ public class AsynchronousLogin {
m.send(player, MessageKey.ACCOUNT_NOT_ACTIVATED); m.send(player, MessageKey.ACCOUNT_NOT_ACTIVATED);
return null; 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); AuthMeAsyncPreLoginEvent event = new AuthMeAsyncPreLoginEvent(player);
Bukkit.getServer().getPluginManager().callEvent(event); Bukkit.getServer().getPluginManager().callEvent(event);
if (!event.canLogin()) if (!event.canLogin())
@ -268,7 +272,7 @@ public class AsynchronousLogin {
* uuidaccounts + "."; } } * uuidaccounts + "."; } }
*/ */
for (Player player : Utils.getOnlinePlayers()) { 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("[AuthMe] The player " + auth.getNickname() + " has " + auths.size() + " accounts");
player.sendMessage(message.toString()); player.sendMessage(message.toString());
// player.sendMessage(uuidaccounts.replace("%size%", // 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.auth.PlayerCache;
import fr.xephi.authme.cache.limbo.LimboCache; import fr.xephi.authme.cache.limbo.LimboCache;
import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.settings.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.settings.Messages; import fr.xephi.authme.output.Messages;
import fr.xephi.authme.util.Utils; import fr.xephi.authme.util.Utils;
import fr.xephi.authme.util.Utils.GroupType; import fr.xephi.authme.util.Utils.GroupType;
import org.bukkit.entity.Player; 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.ConsoleLogger;
import fr.xephi.authme.cache.limbo.LimboCache; import fr.xephi.authme.cache.limbo.LimboCache;
import fr.xephi.authme.events.LogoutEvent; import fr.xephi.authme.events.LogoutEvent;
import fr.xephi.authme.settings.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.settings.Messages; import fr.xephi.authme.output.Messages;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.task.MessageTask; import fr.xephi.authme.task.MessageTask;
import fr.xephi.authme.task.TimeoutTask; import fr.xephi.authme.task.TimeoutTask;

View File

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

View File

@ -4,8 +4,8 @@ import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.cache.limbo.LimboCache; import fr.xephi.authme.cache.limbo.LimboCache;
import fr.xephi.authme.cache.limbo.LimboPlayer; import fr.xephi.authme.cache.limbo.LimboPlayer;
import fr.xephi.authme.settings.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.settings.Messages; import fr.xephi.authme.output.Messages;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.task.MessageTask; import fr.xephi.authme.task.MessageTask;
import fr.xephi.authme.task.TimeoutTask; 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.cache.limbo.LimboPlayer;
import fr.xephi.authme.events.LoginEvent; import fr.xephi.authme.events.LoginEvent;
import fr.xephi.authme.events.RestoreInventoryEvent; import fr.xephi.authme.events.RestoreInventoryEvent;
import fr.xephi.authme.settings.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.settings.Messages; import fr.xephi.authme.output.Messages;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.task.MessageTask; import fr.xephi.authme.task.MessageTask;
import fr.xephi.authme.task.TimeoutTask; import fr.xephi.authme.task.TimeoutTask;
@ -41,15 +41,13 @@ public class ProcessSyncronousPasswordRegister implements Runnable {
this.plugin = plugin; this.plugin = plugin;
} }
protected void forceCommands() { private void forceCommands() {
for (String command : Settings.forceRegisterCommands) { for (String command : Settings.forceRegisterCommands) {
try {
player.performCommand(command.replace("%p", player.getName())); player.performCommand(command.replace("%p", player.getName()));
} catch (Exception ignored) {
}
} }
for (String command : Settings.forceRegisterCommandsAsConsole) { 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 * @param player Player
*/ */
protected void forceLogin(Player player) { private void forceLogin(Player player) {
Utils.teleportToSpawn(player); Utils.teleportToSpawn(player);
if (LimboCache.getInstance().hasLimboPlayer(name)) LimboCache cache = LimboCache.getInstance();
LimboCache.getInstance().deleteLimboPlayer(name); cache.updateLimboPlayer(player);
LimboCache.getInstance().addLimboPlayer(player);
int delay = Settings.getRegistrationTimeout * 20; int delay = Settings.getRegistrationTimeout * 20;
int interval = Settings.getWarnMessageInterval; int interval = Settings.getWarnMessageInterval;
BukkitScheduler sched = plugin.getServer().getScheduler(); BukkitScheduler sched = plugin.getServer().getScheduler();
BukkitTask task;
if (delay != 0) { if (delay != 0) {
BukkitTask id = sched.runTaskLaterAsynchronously(plugin, new TimeoutTask(plugin, name, player), delay); task = sched.runTaskLaterAsynchronously(plugin, new TimeoutTask(plugin, name, player), delay);
LimboCache.getInstance().getLimboPlayer(name).setTimeoutTaskId(id); cache.getLimboPlayer(name).setTimeoutTaskId(task);
} }
BukkitTask msgT = sched.runTaskAsynchronously(plugin, new MessageTask(plugin, name, m.retrieve(MessageKey.LOGIN_MESSAGE), interval)); task = sched.runTaskAsynchronously(plugin, new MessageTask(plugin, name,
LimboCache.getInstance().getLimboPlayer(name).setMessageTaskId(msgT); m.retrieve(MessageKey.LOGIN_MESSAGE), interval));
cache.getLimboPlayer(name).setMessageTaskId(task);
if (player.isInsideVehicle() && player.getVehicle() != null) { if (player.isInsideVehicle() && player.getVehicle() != null) {
player.getVehicle().eject(); player.getVehicle().eject();
} }
@ -97,33 +96,39 @@ public class ProcessSyncronousPasswordRegister implements Runnable {
} }
} }
limbo.getTimeoutTaskId().cancel();
limbo.getMessageTaskId().cancel();
LimboCache.getInstance().deleteLimboPlayer(name); LimboCache.getInstance().deleteLimboPlayer(name);
} }
if (!Settings.getRegisteredGroup.isEmpty()) { if (!Settings.getRegisteredGroup.isEmpty()) {
Utils.setGroup(player, Utils.GroupType.REGISTERED); Utils.setGroup(player, Utils.GroupType.REGISTERED);
} }
m.send(player, MessageKey.REGISTER_SUCCESS); m.send(player, MessageKey.REGISTER_SUCCESS);
if (!Settings.getmailAccount.isEmpty())
if (!Settings.getmailAccount.isEmpty()) {
m.send(player, MessageKey.ADD_EMAIL_MESSAGE); m.send(player, MessageKey.ADD_EMAIL_MESSAGE);
}
if (player.getGameMode() != GameMode.CREATIVE && !Settings.isMovementAllowed) { if (player.getGameMode() != GameMode.CREATIVE && !Settings.isMovementAllowed) {
player.setAllowFlight(false); player.setAllowFlight(false);
player.setFlying(false); player.setFlying(false);
} }
if (Settings.applyBlindEffect)
if (Settings.applyBlindEffect) {
player.removePotionEffect(PotionEffectType.BLINDNESS); 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 // The LoginEvent now fires (as intended) after everything is processed
plugin.getServer().getPluginManager().callEvent(new LoginEvent(player, true)); plugin.getServer().getPluginManager().callEvent(new LoginEvent(player, true));
player.saveData(); player.saveData();
if (!Settings.noConsoleSpam) if (!Settings.noConsoleSpam) {
ConsoleLogger.info(player.getName() + " registered " + plugin.getIP(player)); ConsoleLogger.info(player.getName() + " registered " + plugin.getIP(player));
}
// Kick Player after Registration is enabled, kick the player // Kick Player after Registration is enabled, kick the player
if (Settings.forceRegKick) { if (Settings.forceRegKick) {
@ -138,7 +143,7 @@ public class ProcessSyncronousPasswordRegister implements Runnable {
} }
// Register is finish and player is logged, display welcome message // Register is finish and player is logged, display welcome message
if (Settings.useWelcomeMessage) if (Settings.useWelcomeMessage) {
if (Settings.broadcastWelcomeMessage) { if (Settings.broadcastWelcomeMessage) {
for (String s : Settings.welcomeMsg) { for (String s : Settings.welcomeMsg) {
plugin.getServer().broadcastMessage(plugin.replaceAllInfo(s, player)); plugin.getServer().broadcastMessage(plugin.replaceAllInfo(s, player));
@ -148,6 +153,7 @@ public class ProcessSyncronousPasswordRegister implements Runnable {
player.sendMessage(plugin.replaceAllInfo(s, player)); player.sendMessage(plugin.replaceAllInfo(s, player));
} }
} }
}
// Register is now finish , we can force all commands // Register is now finish , we can force all commands
forceCommands(); 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.LimboCache;
import fr.xephi.authme.cache.limbo.LimboPlayer; import fr.xephi.authme.cache.limbo.LimboPlayer;
import fr.xephi.authme.security.PasswordSecurity; import fr.xephi.authme.security.PasswordSecurity;
import fr.xephi.authme.settings.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.settings.Messages; import fr.xephi.authme.output.Messages;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.task.MessageTask; import fr.xephi.authme.task.MessageTask;
import fr.xephi.authme.task.TimeoutTask; 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 fr.xephi.authme.util.Wrapper;
import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.file.YamlConfiguration;
import com.google.common.base.Charsets;
import com.google.common.io.Files;
import java.io.*; import java.io.*;
import java.nio.charset.Charset;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Iterator; 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 PLUGIN_FOLDER = Wrapper.getInstance().getDataFolder();
public static final File MODULE_FOLDER = new File(PLUGIN_FOLDER, "modules"); 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 CACHE_FOLDER = new File(PLUGIN_FOLDER, "cache");
public static final File AUTH_FILE = new File(PLUGIN_FOLDER, "auths.db"); 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 SETTINGS_FILE = new File(PLUGIN_FOLDER, "config.yml");
public static final File LOG_FILE = new File(PLUGIN_FOLDER, "authme.log"); public static final File LOG_FILE = new File(PLUGIN_FOLDER, "authme.log");
// This is not an option! // This is not an option!
@ -68,7 +73,7 @@ public final class Settings extends YamlConfiguration {
enableProtection, enableAntiBot, recallEmail, useWelcomeMessage, enableProtection, enableAntiBot, recallEmail, useWelcomeMessage,
broadcastWelcomeMessage, forceRegKick, forceRegLogin, broadcastWelcomeMessage, forceRegKick, forceRegLogin,
checkVeryGames, delayJoinLeaveMessages, noTeleport, applyBlindEffect, checkVeryGames, delayJoinLeaveMessages, noTeleport, applyBlindEffect,
customAttributes, generateImage, isRemoveSpeedEnabled, isMySQLWebsite; customAttributes, generateImage, isRemoveSpeedEnabled, preventOtherCase;
public static String helpHeader, getNickRegex, getUnloggedinGroup, getMySQLHost, public static String helpHeader, getNickRegex, getUnloggedinGroup, getMySQLHost,
getMySQLPort, getMySQLUsername, getMySQLPassword, getMySQLDatabase, getMySQLPort, getMySQLUsername, getMySQLPassword, getMySQLDatabase,
getMySQLTablename, getMySQLColumnName, getMySQLColumnPassword, getMySQLTablename, getMySQLColumnName, getMySQLColumnPassword,
@ -116,7 +121,7 @@ public final class Settings extends YamlConfiguration {
if (!exist) { if (!exist) {
plugin.saveDefaultConfig(); plugin.saveDefaultConfig();
} }
instance.load(SETTINGS_FILE); configFile.load(SETTINGS_FILE);
if (exist) { if (exist) {
instance.mergeConfig(); instance.mergeConfig();
} }
@ -184,7 +189,12 @@ public final class Settings extends YamlConfiguration {
getMySQLColumnRealName = configFile.getString("DataSource.mySQLRealName", "realname"); getMySQLColumnRealName = configFile.getString("DataSource.mySQLRealName", "realname");
getNonActivatedGroup = configFile.getInt("ExternalBoardOptions.nonActivedUserGroup", -1); getNonActivatedGroup = configFile.getInt("ExternalBoardOptions.nonActivedUserGroup", -1);
unRegisteredGroup = configFile.getString("GroupOptions.UnregisteredPlayerGroup", ""); 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", ""); getRegisteredGroup = configFile.getString("GroupOptions.RegisteredPlayerGroup", "");
getEnablePasswordVerifier = configFile.getBoolean("settings.restrictions.enablePasswordVerifier", true); getEnablePasswordVerifier = configFile.getBoolean("settings.restrictions.enablePasswordVerifier", true);
@ -226,7 +236,7 @@ public final class Settings extends YamlConfiguration {
maxLoginTry = configFile.getInt("Security.captcha.maxLoginTry", 5); maxLoginTry = configFile.getInt("Security.captcha.maxLoginTry", 5);
captchaLength = configFile.getInt("Security.captcha.captchaLength", 5); captchaLength = configFile.getInt("Security.captcha.captchaLength", 5);
getMailSubject = configFile.getString("Email.mailSubject", "Your new AuthMe Password"); 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); emailRegistration = configFile.getBoolean("settings.registration.enableEmailRegistrationSystem", false);
saltLength = configFile.getInt("settings.security.doubleMD5SaltLength", 8); saltLength = configFile.getInt("settings.security.doubleMD5SaltLength", 8);
getmaxRegPerEmail = configFile.getInt("Email.maxRegPerEmail", 1); getmaxRegPerEmail = configFile.getInt("Email.maxRegPerEmail", 1);
@ -284,19 +294,46 @@ public final class Settings extends YamlConfiguration {
forceRegisterCommandsAsConsole = configFile.getStringList("settings.forceRegisterCommandsAsConsole"); forceRegisterCommandsAsConsole = configFile.getStringList("settings.forceRegisterCommandsAsConsole");
customAttributes = configFile.getBoolean("Hooks.customAttributes"); customAttributes = configFile.getBoolean("Hooks.customAttributes");
generateImage = configFile.getBoolean("Email.generateImage", false); generateImage = configFile.getBoolean("Email.generateImage", false);
isMySQLWebsite = configFile.getBoolean("DataSource.mySQLWebsite", false); preventOtherCase = configFile.getBoolean("settings.preventOtherCase", false);
// Load the welcome message // Load the welcome message
getWelcomeMessage(); getWelcomeMessage();
} }
/** private static String loadEmailText() {
* Method setValue. if (!EMAIL_FILE.exists())
* saveDefaultEmailText();
* @param key String StringBuilder str = new StringBuilder();
* @param value Object 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) { public static void setValue(String key, Object value) {
instance.set(key, value); instance.set(key, value);
save(); save();
@ -368,9 +405,9 @@ public final class Settings extends YamlConfiguration {
*/ */
public static boolean save() { public static boolean save() {
try { try {
instance.save(SETTINGS_FILE); configFile.save(SETTINGS_FILE);
return true; return true;
} catch (Exception ex) { } catch (IOException ex) {
return false; return false;
} }
} }
@ -588,7 +625,7 @@ public final class Settings extends YamlConfiguration {
set("VeryGames.enableIpCheck", false); set("VeryGames.enableIpCheck", false);
changes = true; 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_]*"); set("settings.restrictions.allowedNicknameCharacters", "[a-zA-Z0-9_]*");
changes = true; changes = true;
} }
@ -676,30 +713,49 @@ public final class Settings extends YamlConfiguration {
set("DataSource.mySQLRealName", "realname"); set("DataSource.mySQLRealName", "realname");
changes = true; changes = true;
} }
if (!contains("DataSource.mySQLQueryCache")) {
set("DataSource.mySQLWebsite", false); if (!contains("settings.preventOtherCase"))
{
set("settings.preventOtherCase", false);
changes = true; 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) { if (changes) {
plugin.getLogger().warning("Merged new Config Options - I'm not an error, please don't report me"); plugin.getLogger().warning("Merged new Config Options - I'm not an error, please don't report me");
plugin.getLogger().warning("Please check your config.yml file for new configs!"); plugin.getLogger().warning("Please check your config.yml file for new configs!");
} }
} }
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. * Saves current configuration (plus defaults) to disk.
* <p/> * <p>
* If defaults and configuration are empty, saves blank file. * If defaults and configuration are empty, saves blank file.
* *
* @return True if saved successfully * @return True if saved successfully
*/ */
public final boolean saveDefaults() { public final boolean saveDefaults() {
options().copyDefaults(true); configFile.options()
options().copyHeader(true); .copyDefaults(true)
.copyHeader(true);
boolean success = save(); boolean success = save();
options().copyDefaults(false); configFile.options()
options().copyHeader(false); .copyDefaults(false)
.copyHeader(false);
return success; 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.PlayerAuth;
import fr.xephi.authme.cache.auth.PlayerCache; import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.security.PasswordSecurity; import fr.xephi.authme.security.PasswordSecurity;
import fr.xephi.authme.settings.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.settings.Messages; import fr.xephi.authme.output.Messages;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import org.bukkit.entity.Player; 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.AuthMe;
import fr.xephi.authme.cache.auth.PlayerCache; import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.settings.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.settings.Messages; import fr.xephi.authme.output.Messages;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.entity.Player; 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 final class StringUtils {
public static final String newline = System.getProperty("line.separator");
private StringUtils() { private StringUtils() {
// Utility class // Utility class
} }
@ -29,8 +27,9 @@ public final class StringUtils {
*/ */
public static double getDifference(String first, String second) { public static double getDifference(String first, String second) {
// Make sure the strings are valid. // Make sure the strings are valid.
if (first == null || second == null) if (first == null || second == null) {
return 1.0; return 1.0;
}
// Create a string similarity service instance, to allow comparison // Create a string similarity service instance, to allow comparison
StringSimilarityService service = new StringSimilarityServiceImpl(new LevenshteinDistanceStrategy()); 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.cache.limbo.LimboPlayer;
import fr.xephi.authme.events.AuthMeTeleportEvent; import fr.xephi.authme.events.AuthMeTeleportEvent;
import fr.xephi.authme.permission.PermissionsManager; 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 fr.xephi.authme.settings.Settings;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.GameMode; import org.bukkit.GameMode;
@ -137,7 +137,7 @@ public final class Utils {
// TODO: Move to a Manager // TODO: Move to a Manager
public static boolean checkAuth(Player player) { public static boolean checkAuth(Player player) {
if (player == null || Utils.isUnrestricted(player) || Utils.isNPC(player)) { if (player == null || Utils.isUnrestricted(player)) {
return true; return true;
} }
@ -156,8 +156,9 @@ public final class Utils {
} }
public static boolean isUnrestricted(Player player) { public static boolean isUnrestricted(Player player) {
return Settings.isAllowRestrictedIp && !Settings.getUnrestrictedName.isEmpty() return Settings.isAllowRestrictedIp
&& (Settings.getUnrestrictedName.contains(player.getName())); && !Settings.getUnrestrictedName.isEmpty()
&& (Settings.getUnrestrictedName.contains(player.getName().toLowerCase()));
} }
/** /**
@ -201,7 +202,7 @@ public final class Utils {
* @param player the player to modify. * @param player the player to modify.
*/ */
public static void forceGM(Player player) { 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); player.setGameMode(GameMode.SURVIVAL);
} }
} }

View File

@ -2,7 +2,7 @@ package fr.xephi.authme.util;
import fr.xephi.authme.AuthMe; import fr.xephi.authme.AuthMe;
import fr.xephi.authme.cache.auth.PlayerCache; 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.Bukkit;
import org.bukkit.Server; import org.bukkit.Server;
import org.bukkit.scheduler.BukkitScheduler; import org.bukkit.scheduler.BukkitScheduler;

View File

@ -259,6 +259,9 @@ settings:
delayJoinLeaveMessages: true delayJoinLeaveMessages: true
# Do we need to add potion effect Blinding before login/register ? # Do we need to add potion effect Blinding before login/register ?
applyBlindEffect: false 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: ExternalBoardOptions:
# MySQL column for the salt , needed for some forum/cms support # MySQL column for the salt , needed for some forum/cms support
mySQLColumnSalt: '' mySQLColumnSalt: ''
@ -388,12 +391,14 @@ Protection:
# Enable some servers protection ( country based login, antibot ) # Enable some servers protection ( country based login, antibot )
enableProtection: false 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 # 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: countries:
- US - 'US'
- GB - 'GB'
# Countries blacklisted automatically ( without any needed to enable protection ) # Countries blacklisted automatically ( without any needed to enable protection )
# PLEASE USE QUOTES!
countriesBlacklist: countriesBlacklist:
- A1 - 'A1'
# Do we need to enable automatic antibot system? # Do we need to enable automatic antibot system?
enableAntiBot: false enableAntiBot: false
# Max number of player allowed to login in 5 secs before enable AntiBot system automatically # 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!' 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.' unsafe_spawn: '&cYour quit location was unsafe, you have been teleported to the world''s spawnpoint.'
not_logged_in: '&cYou''re not logged in!' 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; 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.StringUtils;
import fr.xephi.authme.util.WrapperMock;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; 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.equalTo;
import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.nullValue; import static org.hamcrest.Matchers.nullValue;
@ -18,9 +25,9 @@ import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail; 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. * 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 int MAX_ALLOWED_DEPTH = 1;
private static CommandManager manager; private static Set<CommandDescription> commands;
@BeforeClass @BeforeClass
public static void initializeCommandManager() { public static void initializeCommandManager() {
manager = new CommandManager(true); WrapperMock.createInstance();
commands = CommandInitializer.getBaseCommands();
} }
@Test @Test
public void shouldInitializeCommands() { public void shouldInitializeCommands() {
// given/when // given/when/then
int commandCount = manager.getCommandDescriptionCount();
List<CommandDescription> commands = manager.getCommandDescriptions();
// then
// It obviously doesn't make sense to test much of the concrete data // 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 is being initialized; we just want to guarantee with this test
// that data is indeed being initialized and we take a few "probes" // 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, "authme"), equalTo(true));
assertThat(commandsIncludeLabel(commands, "register"), equalTo(true)); assertThat(commandsIncludeLabel(commands, "register"), equalTo(true));
assertThat(commandsIncludeLabel(commands, "help"), equalTo(false)); assertThat(commandsIncludeLabel(commands, "help"), equalTo(false));
@ -62,7 +66,7 @@ public class CommandManagerTest {
}; };
// when/then // when/then
walkThroughCommands(manager.getCommandDescriptions(), descriptionTester); walkThroughCommands(commands, descriptionTester);
} }
/** Ensure that all children of a command stored the parent. */ /** Ensure that all children of a command stored the parent. */
@ -84,7 +88,28 @@ public class CommandManagerTest {
}; };
// when/then // 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 @Test
@ -105,7 +130,7 @@ public class CommandManagerTest {
}; };
// when/then // when/then
walkThroughCommands(manager.getCommandDescriptions(), uniqueMappingTester); walkThroughCommands(commands, uniqueMappingTester);
} }
/** /**
@ -132,7 +157,7 @@ public class CommandManagerTest {
}; };
// when/then // when/then
walkThroughCommands(manager.getCommandDescriptions(), descriptionTester); walkThroughCommands(commands, descriptionTester);
} }
/** /**
@ -143,7 +168,6 @@ public class CommandManagerTest {
public void shouldNotHaveMultipleInstancesOfSameExecutableCommandSubType() { public void shouldNotHaveMultipleInstancesOfSameExecutableCommandSubType() {
// given // given
final Map<Class<? extends ExecutableCommand>, ExecutableCommand> implementations = new HashMap<>(); final Map<Class<? extends ExecutableCommand>, ExecutableCommand> implementations = new HashMap<>();
CommandManager manager = new CommandManager(true);
BiConsumer descriptionTester = new BiConsumer() { BiConsumer descriptionTester = new BiConsumer() {
@Override @Override
public void accept(CommandDescription command, int depth) { public void accept(CommandDescription command, int depth) {
@ -160,10 +184,7 @@ public class CommandManagerTest {
} }
}; };
// when // when/then
List<CommandDescription> commands = manager.getCommandDescriptions();
// then
walkThroughCommands(commands, descriptionTester); walkThroughCommands(commands, descriptionTester);
} }
@ -186,7 +207,7 @@ public class CommandManagerTest {
}; };
// when/then // when/then
walkThroughCommands(manager.getCommandDescriptions(), argumentOrderTester); walkThroughCommands(commands, argumentOrderTester);
} }
/** /**
@ -209,18 +230,54 @@ public class CommandManagerTest {
}; };
// when/then // 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 // Helper methods
// ------------ // ------------
private static void walkThroughCommands(List<CommandDescription> commands, BiConsumer consumer) { private static void walkThroughCommands(Collection<CommandDescription> commands, BiConsumer consumer) {
walkThroughCommands(commands, consumer, 0); 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) { for (CommandDescription command : commands) {
consumer.accept(command, depth); consumer.accept(command, depth);
if (command.hasChildren()) { 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. * 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) { private static List<String> getAbsoluteLabels(CommandDescription command) {
String parentPath = ""; String parentPath = "";

View File

@ -3,6 +3,7 @@ package fr.xephi.authme.command;
import org.junit.Test; import org.junit.Test;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;
@ -27,7 +28,7 @@ public class CommandPartsTest {
@Test @Test
public void shouldPrintEmptyStringForNoArguments() { public void shouldPrintEmptyStringForNoArguments() {
// given // given
CommandParts parts = new CommandParts(); CommandParts parts = new CommandParts(Collections.EMPTY_LIST);
// when // when
String str = parts.toString(); 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.ReflectionTestUtils;
import fr.xephi.authme.cache.auth.PlayerCache; import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.command.CommandParts; import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.settings.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.settings.Messages; import fr.xephi.authme.output.Messages;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.task.ChangePasswordTask; import fr.xephi.authme.task.ChangePasswordTask;
import fr.xephi.authme.util.WrapperMock; import fr.xephi.authme.util.WrapperMock;
@ -13,17 +13,16 @@ import org.bukkit.Server;
import org.bukkit.command.BlockCommandSender; import org.bukkit.command.BlockCommandSender;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitScheduler;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
import static org.mockito.BDDMockito.given;
import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.*; import static org.mockito.Mockito.*;
@ -57,7 +56,7 @@ public class ChangePasswordCommandTest {
CommandParts arguments = mock(CommandParts.class); CommandParts arguments = mock(CommandParts.class);
// when // when
command.executeCommand(sender, new CommandParts(), arguments); command.executeCommand(sender, newParts(), arguments);
// then // then
verify(arguments, never()).get(anyInt()); verify(arguments, never()).get(anyInt());
@ -71,7 +70,7 @@ public class ChangePasswordCommandTest {
ChangePasswordCommand command = new ChangePasswordCommand(); ChangePasswordCommand command = new ChangePasswordCommand();
// when // when
command.executeCommand(sender, new CommandParts(), new CommandParts("pass")); command.executeCommand(sender, newParts(), new CommandParts("pass"));
// then // then
verify(messagesMock).send(sender, MessageKey.NOT_LOGGED_IN); verify(messagesMock).send(sender, MessageKey.NOT_LOGGED_IN);
@ -85,7 +84,7 @@ public class ChangePasswordCommandTest {
ChangePasswordCommand command = new ChangePasswordCommand(); ChangePasswordCommand command = new ChangePasswordCommand();
// when // when
command.executeCommand(sender, new CommandParts(), new CommandParts("!pass")); command.executeCommand(sender, newParts(), newParts("old123", "!pass"));
// then // then
verify(messagesMock).send(sender, MessageKey.PASSWORD_MATCH_ERROR); verify(messagesMock).send(sender, MessageKey.PASSWORD_MATCH_ERROR);
@ -100,7 +99,7 @@ public class ChangePasswordCommandTest {
ChangePasswordCommand command = new ChangePasswordCommand(); ChangePasswordCommand command = new ChangePasswordCommand();
// when // when
command.executeCommand(sender, new CommandParts(), new CommandParts("Tester")); command.executeCommand(sender, newParts(), newParts("old_", "Tester"));
// then // then
verify(messagesMock).send(sender, MessageKey.PASSWORD_IS_USERNAME_ERROR); verify(messagesMock).send(sender, MessageKey.PASSWORD_IS_USERNAME_ERROR);
@ -115,7 +114,7 @@ public class ChangePasswordCommandTest {
Settings.passwordMaxLength = 3; Settings.passwordMaxLength = 3;
// when // when
command.executeCommand(sender, new CommandParts(), new CommandParts("test")); command.executeCommand(sender, newParts(), newParts("12", "test"));
// then // then
verify(messagesMock).send(sender, MessageKey.INVALID_PASSWORD_LENGTH); verify(messagesMock).send(sender, MessageKey.INVALID_PASSWORD_LENGTH);
@ -130,7 +129,7 @@ public class ChangePasswordCommandTest {
Settings.getPasswordMinLen = 7; Settings.getPasswordMinLen = 7;
// when // when
command.executeCommand(sender, new CommandParts(), new CommandParts("tester")); command.executeCommand(sender, newParts(), newParts("oldverylongpassword", "tester"));
// then // then
verify(messagesMock).send(sender, MessageKey.INVALID_PASSWORD_LENGTH); verify(messagesMock).send(sender, MessageKey.INVALID_PASSWORD_LENGTH);
@ -145,7 +144,7 @@ public class ChangePasswordCommandTest {
Settings.unsafePasswords = asList("test", "abc123"); Settings.unsafePasswords = asList("test", "abc123");
// when // when
command.executeCommand(sender, new CommandParts(), new CommandParts("abc123")); command.executeCommand(sender, newParts(), newParts("oldpw", "abc123"));
// then // then
verify(messagesMock).send(sender, MessageKey.PASSWORD_UNSAFE_ERROR); verify(messagesMock).send(sender, MessageKey.PASSWORD_UNSAFE_ERROR);
@ -157,16 +156,14 @@ public class ChangePasswordCommandTest {
// given // given
CommandSender sender = initPlayerWithName("parker", true); CommandSender sender = initPlayerWithName("parker", true);
ChangePasswordCommand command = new ChangePasswordCommand(); ChangePasswordCommand command = new ChangePasswordCommand();
BukkitScheduler schedulerMock = mock(BukkitScheduler.class);
given(wrapperMock.getServer().getScheduler()).willReturn(schedulerMock);
// when // when
command.executeCommand(sender, new CommandParts(), new CommandParts(asList("abc123", "abc123"))); command.executeCommand(sender, newParts(), newParts("abc123", "abc123"));
// then // then
verify(messagesMock, never()).send(eq(sender), any(MessageKey.class)); verify(messagesMock, never()).send(eq(sender), any(MessageKey.class));
ArgumentCaptor<ChangePasswordTask> taskCaptor = ArgumentCaptor.forClass(ChangePasswordTask.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(); ChangePasswordTask task = taskCaptor.getValue();
assertThat((String) ReflectionTestUtils.getFieldValue(ChangePasswordTask.class, task, "newPassword"), assertThat((String) ReflectionTestUtils.getFieldValue(ChangePasswordTask.class, task, "newPassword"),
equalTo("abc123")); equalTo("abc123"));
@ -179,4 +176,8 @@ public class ChangePasswordCommandTest {
return player; 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.junit.Test;
import org.mockito.Mockito; import org.mockito.Mockito;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import static org.mockito.Mockito.never; import static org.mockito.Mockito.never;
@ -40,7 +41,7 @@ public class AddEmailCommandTest {
AddEmailCommand command = new AddEmailCommand(); AddEmailCommand command = new AddEmailCommand();
// when // when
command.executeCommand(sender, new CommandParts(), new CommandParts()); command.executeCommand(sender, newParts(), newParts());
// then // then
verify(authMeMock, never()).getManagement(); verify(authMeMock, never()).getManagement();
@ -53,11 +54,15 @@ public class AddEmailCommandTest {
AddEmailCommand command = new AddEmailCommand(); AddEmailCommand command = new AddEmailCommand();
// when // when
command.executeCommand(sender, new CommandParts(), command.executeCommand(sender, newParts(),
new CommandParts(Arrays.asList("mail@example", "other_example"))); new CommandParts(Arrays.asList("mail@example", "other_example")));
// then // then
verify(authMeMock).getManagement(); verify(authMeMock).getManagement();
verify(managementMock).performAddEmail(sender, "mail@example", "other_example"); 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.junit.Test;
import org.mockito.Mockito; import org.mockito.Mockito;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import static org.mockito.Mockito.never; import static org.mockito.Mockito.never;
@ -40,7 +41,7 @@ public class ChangeEmailCommandTest {
ChangeEmailCommand command = new ChangeEmailCommand(); ChangeEmailCommand command = new ChangeEmailCommand();
// when // when
command.executeCommand(sender, new CommandParts(), new CommandParts()); command.executeCommand(sender, newParts(), newParts());
// then // then
verify(authMeMock, never()).getManagement(); verify(authMeMock, never()).getManagement();
@ -53,11 +54,15 @@ public class ChangeEmailCommandTest {
ChangeEmailCommand command = new ChangeEmailCommand(); ChangeEmailCommand command = new ChangeEmailCommand();
// when // when
command.executeCommand(sender, new CommandParts(), command.executeCommand(sender, newParts(),
new CommandParts(Arrays.asList("new.mail@example.org", "old_mail@example.org"))); new CommandParts(Arrays.asList("new.mail@example.org", "old_mail@example.org")));
// then // then
verify(authMeMock).getManagement(); verify(authMeMock).getManagement();
verify(managementMock).performChangeEmail(sender, "new.mail@example.org", "old_mail@example.org"); 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.junit.Test;
import org.mockito.Mockito; import org.mockito.Mockito;
import java.util.Collections;
/** /**
* Test for {@link RecoverEmailCommand}. * Test for {@link RecoverEmailCommand}.
*/ */
@ -27,7 +29,7 @@ public class RecoverEmailCommandTest {
RecoverEmailCommand command = new RecoverEmailCommand(); RecoverEmailCommand command = new RecoverEmailCommand();
// when // when
command.executeCommand(sender, new CommandParts(), new CommandParts()); command.executeCommand(sender, new CommandParts(Collections.EMPTY_LIST), new CommandParts(Collections.EMPTY_LIST));
// then // then
} }

View File

@ -11,6 +11,8 @@ import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.mockito.Mockito; import org.mockito.Mockito;
import java.util.ArrayList;
import static org.mockito.Matchers.*; import static org.mockito.Matchers.*;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never; import static org.mockito.Mockito.never;
@ -38,7 +40,7 @@ public class LoginCommandTest {
LoginCommand command = new LoginCommand(); LoginCommand command = new LoginCommand();
// when // when
command.executeCommand(sender, new CommandParts(), new CommandParts()); command.executeCommand(sender, newParts(), newParts());
// then // then
Mockito.verify(managementMock, never()).performLogin(any(Player.class), anyString(), anyBoolean()); Mockito.verify(managementMock, never()).performLogin(any(Player.class), anyString(), anyBoolean());
@ -51,7 +53,7 @@ public class LoginCommandTest {
LoginCommand command = new LoginCommand(); LoginCommand command = new LoginCommand();
// when // when
command.executeCommand(sender, new CommandParts(), new CommandParts("password")); command.executeCommand(sender, newParts(), new CommandParts("password"));
// then // then
Mockito.verify(managementMock).performLogin(eq(sender), eq("password"), eq(false)); Mockito.verify(managementMock).performLogin(eq(sender), eq("password"), eq(false));
@ -64,11 +66,15 @@ public class LoginCommandTest {
LoginCommand command = new LoginCommand(); LoginCommand command = new LoginCommand();
// when // when
command.executeCommand(sender, new CommandParts(), new CommandParts()); command.executeCommand(sender, newParts(), newParts());
// then // then
// TODO ljacqu 20151121: May make sense to handle null password in LoginCommand instead of forwarding the call // TODO ljacqu 20151121: May make sense to handle null password in LoginCommand instead of forwarding the call
String password = null; String password = null;
Mockito.verify(managementMock).performLogin(eq(sender), eq(password), eq(false)); 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.junit.Test;
import org.mockito.Mockito; import org.mockito.Mockito;
import java.util.ArrayList;
import static org.mockito.Matchers.any; import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never; import static org.mockito.Mockito.never;
@ -40,7 +42,7 @@ public class LogoutCommandTest {
LogoutCommand command = new LogoutCommand(); LogoutCommand command = new LogoutCommand();
// when // when
command.executeCommand(sender, new CommandParts(), new CommandParts()); command.executeCommand(sender, new CommandParts(new ArrayList<String>()), new CommandParts(new ArrayList<String>()));
// then // then
Mockito.verify(managementMock, never()).performLogout(any(Player.class)); Mockito.verify(managementMock, never()).performLogout(any(Player.class));
@ -53,7 +55,7 @@ public class LogoutCommandTest {
LogoutCommand command = new LogoutCommand(); LogoutCommand command = new LogoutCommand();
// when // when
command.executeCommand(sender, new CommandParts(), new CommandParts("password")); command.executeCommand(sender, new CommandParts(new ArrayList<String>()), new CommandParts("password"));
// then // then
Mockito.verify(managementMock).performLogout(sender); 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.command.CommandParts;
import fr.xephi.authme.process.Management; import fr.xephi.authme.process.Management;
import fr.xephi.authme.settings.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.settings.Messages; import fr.xephi.authme.output.Messages;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.util.WrapperMock; import fr.xephi.authme.util.WrapperMock;
import org.bukkit.command.BlockCommandSender; import org.bukkit.command.BlockCommandSender;
@ -14,6 +14,8 @@ import org.junit.Test;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
import org.mockito.Mockito; import org.mockito.Mockito;
import java.util.ArrayList;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;
import static org.mockito.Matchers.any; import static org.mockito.Matchers.any;
@ -48,7 +50,7 @@ public class RegisterCommandTest {
ArgumentCaptor<String> messageCaptor = ArgumentCaptor.forClass(String.class); ArgumentCaptor<String> messageCaptor = ArgumentCaptor.forClass(String.class);
// when // when
command.executeCommand(sender, new CommandParts(), new CommandParts()); command.executeCommand(sender, newParts(), newParts());
// then // then
verify(sender).sendMessage(messageCaptor.capture()); verify(sender).sendMessage(messageCaptor.capture());
@ -63,7 +65,7 @@ public class RegisterCommandTest {
RegisterCommand command = new RegisterCommand(); RegisterCommand command = new RegisterCommand();
// when // when
command.executeCommand(sender, new CommandParts(), new CommandParts()); command.executeCommand(sender, newParts(), newParts());
// then // then
verify(messagesMock).send(sender, MessageKey.USAGE_REGISTER); verify(messagesMock).send(sender, MessageKey.USAGE_REGISTER);
@ -77,9 +79,13 @@ public class RegisterCommandTest {
RegisterCommand command = new RegisterCommand(); RegisterCommand command = new RegisterCommand();
// when // when
command.executeCommand(sender, new CommandParts(), new CommandParts("password")); command.executeCommand(sender, newParts(), new CommandParts("password"));
// then // then
verify(managementMock).performRegister(sender, "password", ""); 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.CommandDescription;
import fr.xephi.authme.command.CommandParts; import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand; 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.junit.Test;
import org.mockito.Mockito; import org.mockito.Mockito;
import java.util.ArrayList;
import static org.bukkit.ChatColor.BOLD; import static org.bukkit.ChatColor.BOLD;
import static org.bukkit.ChatColor.ITALIC; import static org.bukkit.ChatColor.ITALIC;
import static org.bukkit.ChatColor.WHITE; import static org.bukkit.ChatColor.WHITE;
@ -27,8 +29,7 @@ public class HelpSyntaxHelperTest {
.build(); .build();
// when // when
String result = HelpSyntaxHelper.getCommandSyntax( String result = HelpSyntaxHelper.getCommandSyntax(description, newParts(), "", false);
description, new CommandParts(), "", false);
// then // then
assertThat(result, equalTo(WHITE + "/authme register" + ITALIC + " [name]")); assertThat(result, equalTo(WHITE + "/authme register" + ITALIC + " [name]"));
@ -42,8 +43,7 @@ public class HelpSyntaxHelperTest {
.build(); .build();
// when // when
String result = HelpSyntaxHelper.getCommandSyntax( String result = HelpSyntaxHelper.getCommandSyntax(description, newParts(), null, false);
description, new CommandParts(), null, false);
// then // then
assertThat(result, equalTo(WHITE + "/authme register" + ITALIC + " <test>")); assertThat(result, equalTo(WHITE + "/authme register" + ITALIC + " <test>"));
@ -58,8 +58,7 @@ public class HelpSyntaxHelperTest {
.build(); .build();
// when // when
String result = HelpSyntaxHelper.getCommandSyntax( String result = HelpSyntaxHelper.getCommandSyntax(description, newParts(), "", false);
description, new CommandParts(), "", false);
// then // then
assertThat(result, equalTo(WHITE + "/authme register" + ITALIC + " [name]" + ITALIC + " <test>")); assertThat(result, equalTo(WHITE + "/authme register" + ITALIC + " [name]" + ITALIC + " <test>"));
@ -74,8 +73,7 @@ public class HelpSyntaxHelperTest {
.build(); .build();
// when // when
String result = HelpSyntaxHelper.getCommandSyntax( String result = HelpSyntaxHelper.getCommandSyntax(description, newParts(), "", true);
description, new CommandParts(), "", true);
// then // then
assertThat(result, equalTo(WHITE + "/authme " assertThat(result, equalTo(WHITE + "/authme "
@ -89,8 +87,7 @@ public class HelpSyntaxHelperTest {
CommandDescription description = getDescriptionBuilder().build(); CommandDescription description = getDescriptionBuilder().build();
// when // when
String result = HelpSyntaxHelper.getCommandSyntax( String result = HelpSyntaxHelper.getCommandSyntax(description, newParts(), null, true);
description, new CommandParts(), null, true);
// then // then
assertThat(result, equalTo(WHITE + "/authme " + YELLOW + BOLD + "register" + YELLOW)); assertThat(result, equalTo(WHITE + "/authme " + YELLOW + BOLD + "register" + YELLOW));
@ -104,34 +101,18 @@ public class HelpSyntaxHelperTest {
.build(); .build();
// when // when
String result = HelpSyntaxHelper.getCommandSyntax( String result = HelpSyntaxHelper.getCommandSyntax(description, newParts(), "alt", false);
description, new CommandParts(), "alt", false);
// then // then
assertThat(result, equalTo(WHITE + "/authme alt" + ITALIC + " [name]")); assertThat(result, equalTo(WHITE + "/authme alt" + ITALIC + " [name]"));
} }
@Test private static CommandParts newParts() {
public void shouldHighlightCommandWithAltLabelAndUnlimitedArguments() { // TODO ljacqu 20151204: Remove this method once CommandParts has been removed
// given return new CommandParts(new ArrayList<String>());
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 CommandDescription.CommandBuilder getDescriptionBuilder() {
private static CommandDescription.Builder getDescriptionBuilder() {
CommandDescription base = CommandDescription.builder() CommandDescription base = CommandDescription.builder()
.labels("authme") .labels("authme")
.description("Base command") .description("Base command")
@ -141,7 +122,7 @@ public class HelpSyntaxHelperTest {
.build(); .build();
return CommandDescription.builder() return CommandDescription.builder()
.executableCommand(Mockito.mock(RegisterCommand.class)) .executableCommand(Mockito.mock(RegisterAdminCommand.class))
.labels("register", "r") .labels("register", "r")
.description("Register a player") .description("Register a player")
.detailedDescription("Register the specified player with the specified password.") .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.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;
@ -12,8 +12,6 @@ import org.mockito.Mockito;
/** /**
* Test for {@link Log4JFilter}. * Test for {@link Log4JFilter}.
* @author Gabriele
* @version $Revision: 1.0 $
*/ */
public class Log4JFilterTest { 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 fr.xephi.authme.util.StringUtils;
import org.junit.Test; import org.junit.Test;

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