Merge branch 'master' of https://github.com/AuthMe-Team/AuthMeReloaded into commands-refactor

Conflicts:
	src/main/java/fr/xephi/authme/command/CommandUtils.java
	src/main/java/fr/xephi/authme/command/executable/captcha/CaptchaCommand.java
This commit is contained in:
ljacqu
2015-12-17 22:32:26 +01:00
38 changed files with 375 additions and 182 deletions
@@ -203,7 +203,7 @@ public class DataManager {
} catch (Exception ignored) {
}
}
ConsoleLogger.info("AutoPurgeDatabase : Removed " + i + " permissions");
ConsoleLogger.info("AutoPurgeDatabase : Removed " + i + "permissions");
/*int i = 0;
for (String name : cleared) {
+22 -2
View File
@@ -5,7 +5,6 @@ import com.google.common.io.Files;
import com.google.gson.*;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.util.Utils;
import org.bukkit.entity.Player;
import java.io.File;
@@ -109,7 +108,7 @@ public class JsonCache {
}
File file = new File(cacheDir, path);
if (file.exists()) {
Utils.purgeDirectory(file);
purgeDirectory(file);
if (!file.delete()) {
ConsoleLogger.showError("Failed to remove" + player.getName() + "cache.");
}
@@ -194,4 +193,25 @@ public class JsonCache {
}
}
/**
* Delete a given directory and all its content.
*
* @param directory The directory to remove
*/
private static void purgeDirectory(File directory) {
if (!directory.isDirectory()) {
return;
}
File[] files = directory.listFiles();
if (files == null) {
return;
}
for (File target : files) {
if (target.isDirectory()) {
purgeDirectory(target);
}
target.delete();
}
}
}
@@ -1,7 +1,12 @@
package fr.xephi.authme.command;
import com.google.common.collect.Lists;
import fr.xephi.authme.util.CollectionUtils;
import fr.xephi.authme.util.StringUtils;
import java.util.ArrayList;
import java.util.List;
public final class CommandUtils {
public static int getMinNumberOfArguments(CommandDescription command) {
@@ -23,10 +28,20 @@ public final class CommandUtils {
* 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 String constructCommandPath(CommandDescription command) {
List<String> labels = new ArrayList<>();
CommandDescription currentCommand = command;
while (currentCommand != null) {
labels.add(currentCommand.getLabels().get(0));
currentCommand = currentCommand.getParent();
}
return "/" + labelsToString(Lists.reverse(labels));
}
}
@@ -52,7 +52,7 @@ public class UnregisterAdminCommand extends ExecutableCommand {
}
// Unregister the player
Player target = Bukkit.getPlayer(playerNameLowerCase);
Player target = Utils.getPlayer(playerNameLowerCase);
PlayerCache.getInstance().removePlayer(playerNameLowerCase);
Utils.setGroup(target, Utils.GroupType.UNREGISTERED);
if (target != null && target.isOnline()) {
@@ -68,11 +68,9 @@ public class UnregisterAdminCommand extends ExecutableCommand {
LimboCache.getInstance().getLimboPlayer(playerNameLowerCase).setMessageTaskId(
scheduler.runTaskAsynchronously(plugin,
new MessageTask(plugin, playerNameLowerCase, m.retrieve(MessageKey.REGISTER_MESSAGE), interval)));
if (Settings.applyBlindEffect)
target.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, Settings.getRegistrationTimeout * 20, 2));
if (!Settings.isMovementAllowed && Settings.isRemoveSpeedEnabled) {
target.setWalkSpeed(0.0f);
target.setFlySpeed(0.0f);
if (Settings.applyBlindEffect) {
target.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS,
Settings.getRegistrationTimeout * 20, 2));
}
m.send(target, MessageKey.UNREGISTERED_SUCCESS);
@@ -57,9 +57,7 @@ public class CaptchaCommand extends ExecutableCommand {
plugin.cap.remove(playerNameLowerCase);
String randStr = new RandomString(Settings.captchaLength).nextString();
plugin.cap.put(playerNameLowerCase, randStr);
for (String s : m.retrieve(MessageKey.CAPTCHA_WRONG_ERROR)) {
player.sendMessage(s.replace("THE_CAPTCHA", plugin.cap.get(playerNameLowerCase)));
}
m.send(player, MessageKey.CAPTCHA_WRONG_ERROR, plugin.cap.get(playerNameLowerCase));
return;
}
@@ -1,5 +1,6 @@
package fr.xephi.authme.datasource;
import com.google.common.base.Optional;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
@@ -21,7 +22,7 @@ public class CacheDataSource implements DataSource {
private final DataSource source;
private final ExecutorService exec;
private final LoadingCache<String, PlayerAuth> cachedAuths;
private final LoadingCache<String, Optional<PlayerAuth>> cachedAuths;
/**
* Constructor for CacheDataSource.
@@ -33,9 +34,9 @@ public class CacheDataSource implements DataSource {
this.exec = Executors.newCachedThreadPool();
cachedAuths = CacheBuilder.newBuilder()
.expireAfterWrite(5, TimeUnit.MINUTES)
.removalListener(RemovalListeners.asynchronous(new RemovalListener<String, PlayerAuth>() {
.removalListener(RemovalListeners.asynchronous(new RemovalListener<String, Optional<PlayerAuth>>() {
@Override
public void onRemoval(RemovalNotification<String, PlayerAuth> removalNotification) {
public void onRemoval(RemovalNotification<String, Optional<PlayerAuth>> removalNotification) {
String name = removalNotification.getKey();
if (PlayerCache.getInstance().isAuthenticated(name)) {
cachedAuths.getUnchecked(name);
@@ -43,9 +44,9 @@ public class CacheDataSource implements DataSource {
}
}, exec))
.build(
new CacheLoader<String, PlayerAuth>() {
public PlayerAuth load(String key) {
return source.getAuth(key);
new CacheLoader<String, Optional<PlayerAuth>>() {
public Optional<PlayerAuth> load(String key) {
return Optional.fromNullable(source.getAuth(key));
}
});
}
@@ -76,7 +77,7 @@ public class CacheDataSource implements DataSource {
@Override
public synchronized PlayerAuth getAuth(String user) {
user = user.toLowerCase();
return cachedAuths.getUnchecked(user);
return cachedAuths.getUnchecked(user).orNull();
}
/**
@@ -178,9 +179,9 @@ public class CacheDataSource implements DataSource {
public int purgeDatabase(long until) {
int cleared = source.purgeDatabase(until);
if (cleared > 0) {
for (PlayerAuth auth : cachedAuths.asMap().values()) {
if (auth != null && auth.getLastLogin() < until) {
cachedAuths.invalidate(auth.getNickname());
for (Optional<PlayerAuth> auth : cachedAuths.asMap().values()) {
if (auth.isPresent() && auth.get().getLastLogin() < until) {
cachedAuths.invalidate(auth.get().getNickname());
}
}
}
@@ -36,6 +36,7 @@ public class AuthMeEntityListener implements Listener {
}
}
// TODO: npc status can be used to bypass security!!!
/**
* Method onEntityDamage.
*
@@ -53,7 +54,6 @@ public class AuthMeEntityListener implements Listener {
return;
}
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC(player)) {
return;
}
@@ -78,7 +78,6 @@ public class AuthMeEntityListener implements Listener {
return;
}
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC((Player) entity)) {
return;
}
@@ -104,7 +103,6 @@ public class AuthMeEntityListener implements Listener {
return;
}
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC(player)) {
return;
}
@@ -128,7 +126,6 @@ public class AuthMeEntityListener implements Listener {
return;
}
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC((Player) entity)) {
return;
}
@@ -152,7 +149,6 @@ public class AuthMeEntityListener implements Listener {
return;
}
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC((Player) entity)) {
return;
}
@@ -177,7 +173,6 @@ public class AuthMeEntityListener implements Listener {
return;
}
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC((Player) entity)) {
return;
}
@@ -201,7 +196,6 @@ public class AuthMeEntityListener implements Listener {
return;
}
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC((Player) entity)) {
return;
}
@@ -210,7 +204,6 @@ public class AuthMeEntityListener implements Listener {
}
// TODO: Need to check this, player can't throw snowball but the item is taken.
/**
* Method onProjectileLaunch.
*
@@ -245,7 +238,6 @@ public class AuthMeEntityListener implements Listener {
return;
}
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC(player)) {
return;
}
@@ -270,7 +262,6 @@ public class AuthMeEntityListener implements Listener {
return;
}
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC(player)) {
return;
}
@@ -229,7 +229,7 @@ public class AuthMePlayerListener implements Listener {
if (auth != null && !auth.getRealName().equals("Player") && !auth.getRealName().equals(event.getName())) {
event.setLoginResult(AsyncPlayerPreLoginEvent.Result.KICK_OTHER);
event.setKickMessage("You should join using username: " + ChatColor.AQUA + auth.getRealName() +
ChatColor.RESET + "\nnot :" + ChatColor.RED + event.getName()); // TODO: write a better message
ChatColor.RESET + "\nnot: " + ChatColor.RED + event.getName()); // TODO: write a better message
return;
}
@@ -288,7 +288,7 @@ public class AuthMePlayerListener implements Listener {
pl.kickPlayer(m.retrieveSingle(MessageKey.KICK_FOR_VIP));
event.allow();
} else {
ConsoleLogger.info("The player " + event.getPlayer().getName() + " tryed to join, but the server was full");
ConsoleLogger.info("The player " + event.getPlayer().getName() + " tried to join, but the server was full");
event.setKickMessage(m.retrieveSingle(MessageKey.KICK_FULL_SERVER));
event.setResult(PlayerLoginEvent.Result.KICK_FULL);
}
@@ -22,6 +22,7 @@ public class AuthMePlayerListener16 implements Listener {
this.plugin = plugin;
}
// TODO: npc status can be used to bypass security!!!
/**
* Method onPlayerEditBook.
*
@@ -33,7 +34,6 @@ public class AuthMePlayerListener16 implements Listener {
return;
}
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC(event.getPlayer())) {
return;
}
@@ -22,6 +22,7 @@ public class AuthMePlayerListener18 implements Listener {
this.plugin = plugin;
}
// TODO: npc status can be used to bypass security!!!
/**
* Method onPlayerInteractAtEntity.
*
@@ -33,7 +34,6 @@ public class AuthMePlayerListener18 implements Listener {
return;
}
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC(event.getPlayer())) {
return;
}
@@ -79,7 +79,7 @@ public enum MessageKey {
INVALID_NAME_LENGTH("name_len"),
INVALID_NAME_CHARACTERS("regex"),
INVALID_NAME_CHARACTERS("regex", "REG_EX"),
ADD_EMAIL_MESSAGE("add_email"),
@@ -87,7 +87,7 @@ public enum MessageKey {
USAGE_CAPTCHA("usage_captcha"),
CAPTCHA_WRONG_ERROR("wrong_captcha"),
CAPTCHA_WRONG_ERROR("wrong_captcha", "THE_CAPTCHA"),
CAPTCHA_SUCCESS("valid_captcha"),
@@ -119,16 +119,32 @@ public enum MessageKey {
ANTIBOT_AUTO_ENABLED_MESSAGE("antibot_auto_enabled"),
ANTIBOT_AUTO_DISABLED_MESSAGE("antibot_auto_disabled");
ANTIBOT_AUTO_DISABLED_MESSAGE("antibot_auto_disabled", "%m");
private String key;
private String[] tags;
MessageKey(String key) {
MessageKey(String key, String... tags) {
this.key = key;
this.tags = tags;
}
/**
* Return the key used in the messages file.
*
* @return The key
*/
public String getKey() {
return key;
}
/**
* Return a list of tags (texts) that are replaced with actual content in AuthMe.
*
* @return List of tags
*/
public String[] getTags() {
return tags;
}
}
@@ -47,6 +47,31 @@ public class Messages {
}
}
/**
* Send the given message code to the player with the given tag replacements. Note that this method
* issues an exception if the number of supplied replacements doesn't correspond to the number of tags
* the message key contains.
*
* @param sender The entity to send the message to
* @param key The key of the message to send
* @param replacements The replacements to apply for the tags
*/
public void send(CommandSender sender, MessageKey key, String... replacements) {
String message = retrieveSingle(key);
String[] tags = key.getTags();
if (replacements.length != tags.length) {
throw new RuntimeException("Given replacement size does not match the tags in message key '" + key + "'");
}
for (int i = 0; i < tags.length; ++i) {
message = message.replace(tags[i], replacements[i]);
}
for (String line : message.split("\n")) {
sender.sendMessage(line);
}
}
/**
* Retrieve the message from the text file and return it split by new line as an array.
*
@@ -10,9 +10,9 @@ import fr.xephi.authme.events.FirstSpawnTeleportEvent;
import fr.xephi.authme.events.ProtectInventoryEvent;
import fr.xephi.authme.events.SpawnTeleportEvent;
import fr.xephi.authme.listener.AuthMePlayerListener;
import fr.xephi.authme.permission.PlayerPermission;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages;
import fr.xephi.authme.permission.PlayerPermission;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.Spawn;
import fr.xephi.authme.task.MessageTask;
@@ -78,9 +78,9 @@ public class AsynchronousJoin {
return;
}
if (Settings.getMaxJoinPerIp > 0
&& !plugin.getPermissionsManager().hasPermission(player, PlayerPermission.ALLOW_MULTIPLE_ACCOUNTS)
&& !ip.equalsIgnoreCase("127.0.0.1")
&& !ip.equalsIgnoreCase("localhost")) {
&& !plugin.getPermissionsManager().hasPermission(player, PlayerPermission.ALLOW_MULTIPLE_ACCOUNTS)
&& !ip.equalsIgnoreCase("127.0.0.1")
&& !ip.equalsIgnoreCase("localhost")) {
if (plugin.hasJoinedIp(player.getName(), ip)) {
sched.scheduleSyncDelayedTask(plugin, new Runnable() {
@@ -203,10 +203,6 @@ public class AsynchronousJoin {
if (Settings.applyBlindEffect) {
player.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, timeOut, 2));
}
if (!Settings.isMovementAllowed && Settings.isRemoveSpeedEnabled) {
player.setWalkSpeed(0.0f);
player.setFlySpeed(0.0f);
}
}
});
@@ -236,8 +232,7 @@ public class AsynchronousJoin {
? m.retrieve(MessageKey.REGISTER_EMAIL_MESSAGE)
: m.retrieve(MessageKey.REGISTER_MESSAGE);
}
if (LimboCache.getInstance().getLimboPlayer(name) != null)
{
if (LimboCache.getInstance().getLimboPlayer(name) != null) {
BukkitTask msgTask = sched.runTaskAsynchronously(plugin, new MessageTask(plugin, name, msg, msgInterval));
LimboCache.getInstance().getLimboPlayer(name).setMessageTaskId(msgTask);
}
@@ -57,20 +57,10 @@ public class AsynchronousLogin {
this.database = data;
}
/**
* Method getIP.
*
* @return String
*/
protected String getIP() {
return plugin.getIP(player);
}
/**
* Method needsCaptcha.
*
* @return boolean
*/
protected boolean needsCaptcha() {
if (Settings.useCaptcha) {
if (!plugin.captcha.containsKey(name)) {
@@ -82,9 +72,7 @@ public class AsynchronousLogin {
}
if (plugin.captcha.containsKey(name) && plugin.captcha.get(name) > Settings.maxLoginTry) {
plugin.cap.putIfAbsent(name, rdm.nextString());
for (String s : m.retrieve(MessageKey.USAGE_CAPTCHA)) {
player.sendMessage(s.replace("THE_CAPTCHA", plugin.cap.get(name)).replace("<theCaptcha>", plugin.cap.get(name)));
}
m.send(player, MessageKey.USAGE_CAPTCHA, plugin.cap.get(name));
return true;
}
}
@@ -230,12 +218,6 @@ public class AsynchronousLogin {
}
}
/**
* Method displayOtherAccounts.
*
* @param auth PlayerAuth
* @param p Player
*/
public void displayOtherAccounts(PlayerAuth auth, Player p) {
if (!Settings.displayOtherAccounts) {
return;
@@ -189,11 +189,6 @@ public class ProcessSyncronousPlayerLogin implements Runnable {
player.removePotionEffect(PotionEffectType.BLINDNESS);
}
if (!Settings.isMovementAllowed && Settings.isRemoveSpeedEnabled) {
player.setWalkSpeed(0.2f);
player.setFlySpeed(0.1f);
}
// The Login event now fires (as intended) after everything is processed
Bukkit.getServer().getPluginManager().callEvent(new LoginEvent(player, true));
player.saveData();
@@ -80,10 +80,6 @@ public class ProcessSyncronousPlayerLogout implements Runnable {
if (!Settings.isMovementAllowed) {
player.setAllowFlight(true);
player.setFlying(true);
if (!Settings.isMovementAllowed && Settings.isRemoveSpeedEnabled) {
player.setFlySpeed(0.0f);
player.setWalkSpeed(0.0f);
}
}
// Player is now logout... Time to fire event !
Bukkit.getServer().getPluginManager().callEvent(new LogoutEvent(player));
@@ -141,8 +141,10 @@ public class AsyncRegister {
return;
}
if (!Settings.forceRegLogin) {
PlayerCache.getInstance().addPlayer(auth);
database.setLogged(name);
//PlayerCache.getInstance().addPlayer(auth);
//database.setLogged(name);
// TODO: check this...
plugin.getManagement().performLogin(player, "dontneed", true);
}
plugin.otherAccounts.addPlayer(player.getUniqueId());
ProcessSyncPasswordRegister sync = new ProcessSyncPasswordRegister(player, plugin);
@@ -128,11 +128,6 @@ public class ProcessSyncPasswordRegister implements Runnable {
player.removePotionEffect(PotionEffectType.BLINDNESS);
}
if (!Settings.isMovementAllowed && Settings.isRemoveSpeedEnabled) {
player.setWalkSpeed(0.0f);
player.setFlySpeed(0.0f);
}
// The LoginEvent now fires (as intended) after everything is processed
plugin.getServer().getPluginManager().callEvent(new LoginEvent(player, true));
player.saveData();
@@ -104,10 +104,6 @@ public class AsynchronousUnregister {
if (Settings.applyBlindEffect) {
player.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, timeOut, 2));
}
if (!Settings.isMovementAllowed && Settings.isRemoveSpeedEnabled) {
player.setWalkSpeed(0.0f);
player.setFlySpeed(0.0f);
}
m.send(player, MessageKey.UNREGISTERED_SUCCESS);
ConsoleLogger.info(player.getDisplayName() + " unregistered himself");
Utils.teleportToSpawn(player);
@@ -15,7 +15,6 @@ import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Player;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
@@ -207,27 +206,6 @@ public final class Utils {
}
}
/**
* Delete a given directory and all his content.
*
* @param directory File
*/
public static void purgeDirectory(File directory) {
if (!directory.isDirectory()) {
return;
}
File[] files = directory.listFiles();
if (files == null) {
return;
}
for (File target : files) {
if (target.isDirectory()) {
purgeDirectory(target);
}
target.delete();
}
}
/**
* Safe way to retrieve the list of online players from the server. Depending on the
* implementation of the server, either an array of {@link Player} instances is being returned,