Merge pull request #125 from AuthMe-Team/432-dependency-injection

432 dependency injection
This commit is contained in:
ljacqu
2016-05-03 18:54:35 +02:00
85 changed files with 2076 additions and 721 deletions
@@ -9,6 +9,7 @@ import fr.xephi.authme.settings.properties.ProtectionSettings;
import fr.xephi.authme.util.BukkitService;
import org.bukkit.entity.Player;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.List;
@@ -27,6 +28,7 @@ public class AntiBot {
private final List<String> antibotPlayers = new ArrayList<>();
private AntiBotStatus antiBotStatus = AntiBotStatus.DISABLED;
@Inject
public AntiBot(NewSetting settings, Messages messages, PermissionsManager permissionsManager,
BukkitService bukkitService) {
this.settings = settings;
+88 -122
View File
@@ -1,32 +1,5 @@
package fr.xephi.authme;
import static fr.xephi.authme.settings.properties.EmailSettings.MAIL_ACCOUNT;
import static fr.xephi.authme.settings.properties.EmailSettings.MAIL_PASSWORD;
import static fr.xephi.authme.settings.properties.EmailSettings.RECALL_PLAYERS;
import static fr.xephi.authme.settings.properties.PluginSettings.HELP_HEADER;
import java.io.File;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Logger;
import org.apache.logging.log4j.LogManager;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Server;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitTask;
import fr.xephi.authme.api.API;
import fr.xephi.authme.api.NewAPI;
import fr.xephi.authme.cache.auth.PlayerAuth;
@@ -34,12 +7,8 @@ import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.cache.backup.JsonCache;
import fr.xephi.authme.cache.limbo.LimboCache;
import fr.xephi.authme.cache.limbo.LimboPlayer;
import fr.xephi.authme.command.CommandDescription;
import fr.xephi.authme.command.CommandHandler;
import fr.xephi.authme.command.CommandInitializer;
import fr.xephi.authme.command.CommandMapper;
import fr.xephi.authme.command.CommandService;
import fr.xephi.authme.command.help.HelpProvider;
import fr.xephi.authme.datasource.CacheDataSource;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.datasource.DataSourceType;
@@ -48,8 +17,11 @@ import fr.xephi.authme.datasource.MySQL;
import fr.xephi.authme.datasource.SQLite;
import fr.xephi.authme.hooks.BungeeCordMessage;
import fr.xephi.authme.hooks.PluginHooks;
import fr.xephi.authme.initialization.AuthMeServiceInitializer;
import fr.xephi.authme.initialization.BaseCommands;
import fr.xephi.authme.initialization.DataFolder;
import fr.xephi.authme.initialization.MetricsStarter;
import fr.xephi.authme.listener.AuthMeBlockListener;
import fr.xephi.authme.listener.AuthMeEntityListener;
import fr.xephi.authme.listener.AuthMeInventoryPacketAdapter;
import fr.xephi.authme.listener.AuthMePlayerListener;
import fr.xephi.authme.listener.AuthMePlayerListener16;
@@ -66,7 +38,6 @@ import fr.xephi.authme.output.Messages;
import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.permission.PlayerStatePermission;
import fr.xephi.authme.process.Management;
import fr.xephi.authme.process.ProcessService;
import fr.xephi.authme.security.PasswordSecurity;
import fr.xephi.authme.security.crypts.SHA256;
import fr.xephi.authme.settings.NewSetting;
@@ -89,7 +60,31 @@ import fr.xephi.authme.util.GeoLiteAPI;
import fr.xephi.authme.util.MigrationService;
import fr.xephi.authme.util.StringUtils;
import fr.xephi.authme.util.Utils;
import fr.xephi.authme.util.ValidationService;
import org.apache.logging.log4j.LogManager;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Server;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitScheduler;
import org.bukkit.scheduler.BukkitTask;
import java.io.File;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Logger;
import static fr.xephi.authme.settings.properties.EmailSettings.MAIL_ACCOUNT;
import static fr.xephi.authme.settings.properties.EmailSettings.MAIL_PASSWORD;
import static fr.xephi.authme.settings.properties.EmailSettings.RECALL_PLAYERS;
/**
* The AuthMe main class.
@@ -105,7 +100,6 @@ public class AuthMe extends JavaPlugin {
// Private Instances
private static AuthMe plugin;
private static Server server;
/*
* Maps and stuff
*/
@@ -140,7 +134,6 @@ public class AuthMe extends JavaPlugin {
private DataSource database;
private PluginHooks pluginHooks;
private SpawnLoader spawnLoader;
private AntiBot antiBot;
private boolean autoPurging;
private BukkitService bukkitService;
@@ -217,17 +210,15 @@ public class AuthMe extends JavaPlugin {
@Override
public void onEnable() {
// Set various instances
server = getServer();
plugin = this;
ConsoleLogger.setLogger(getLogger());
setPluginInfos();
// Load settings and custom configurations, if it fails, stop the server due to security reasons.
newSettings = createNewSetting();
if (newSettings == null) {
ConsoleLogger.showError("Could not load configuration. Aborting.");
server.shutdown();
getServer().shutdown();
return;
}
ConsoleLogger.setLoggingOptions(newSettings.getProperty(SecuritySettings.USE_LOGGING),
@@ -235,7 +226,7 @@ public class AuthMe extends JavaPlugin {
// Old settings manager
if (!loadSettings()) {
server.shutdown();
getServer().shutdown();
setEnabled(false);
return;
}
@@ -251,23 +242,40 @@ public class AuthMe extends JavaPlugin {
stopOrUnload();
return;
}
bukkitService = new BukkitService(this);
pluginHooks = new PluginHooks(server.getPluginManager());
MigrationService.changePlainTextToSha256(newSettings, database, new SHA256());
passwordSecurity = new PasswordSecurity(getDataSource(), newSettings, Bukkit.getPluginManager());
// Initialize spawn loader
spawnLoader = new SpawnLoader(getDataFolder(), newSettings, pluginHooks);
permsMan = initializePermissionsManager();
antiBot = new AntiBot(newSettings, messages, permsMan, bukkitService);
ValidationService validationService = new ValidationService(newSettings, database, permsMan);
commandHandler = initializeCommandHandler(permsMan, messages, passwordSecurity, newSettings,
pluginHooks, spawnLoader, antiBot, validationService, bukkitService);
AuthMeServiceInitializer initializer = new AuthMeServiceInitializer("fr.xephi.authme");
// Register elements of the Bukkit / JavaPlugin environment
initializer.register(AuthMe.class, this);
initializer.register(Server.class, getServer());
initializer.register(PluginManager.class, getServer().getPluginManager());
initializer.register(BukkitScheduler.class, getServer().getScheduler());
initializer.provide(DataFolder.class, getDataFolder());
// Register elements we instantiate manually
initializer.register(NewSetting.class, newSettings);
initializer.register(Messages.class, messages);
initializer.register(DataSource.class, database);
// Some statically injected things
initializer.register(PlayerCache.class, PlayerCache.getInstance());
initializer.register(LimboCache.class, LimboCache.getInstance());
initializer.provide(BaseCommands.class, CommandInitializer.buildCommands(initializer));
permsMan = initializer.get(PermissionsManager.class);
bukkitService = initializer.get(BukkitService.class);
pluginHooks = initializer.get(PluginHooks.class);
passwordSecurity = initializer.get(PasswordSecurity.class);
spawnLoader = initializer.get(SpawnLoader.class);
commandHandler = initializer.get(CommandHandler.class);
api = initializer.get(NewAPI.class);
management = initializer.get(Management.class);
dataManager = initializer.get(DataManager.class);
initializer.get(API.class);
// Set up Metrics
MetricsStarter.setupMetrics(plugin, newSettings);
MetricsStarter.setupMetrics(this, newSettings);
// Set console filter
setupConsoleFilter();
@@ -284,22 +292,12 @@ public class AuthMe extends JavaPlugin {
// End of Hooks
// Do a backup on start
new PerformBackup(plugin, newSettings).doBackup(PerformBackup.BackupCause.START);
new PerformBackup(this, newSettings).doBackup(PerformBackup.BackupCause.START);
// Setup the inventory backup
playerBackup = new JsonCache();
// Set the DataManager
dataManager = new DataManager(this, pluginHooks, bukkitService);
// Set up the new API
setupApi();
// Set up the management
ProcessService processService = new ProcessService(newSettings, messages, this, database,
passwordSecurity, pluginHooks, spawnLoader, validationService, bukkitService);
management = new Management(this, processService, database, PlayerCache.getInstance());
// Set up the BungeeCord hook
setupBungeeCordHook(newSettings);
@@ -308,8 +306,7 @@ public class AuthMe extends JavaPlugin {
reloadSupportHook();
// Register event listeners
registerEventListeners(
messages, database, management, pluginHooks, spawnLoader, antiBot, bukkitService, validationService);
registerEventListeners(initializer);
// Start Email recall task if needed
scheduleRecallEmailTask();
@@ -373,38 +370,34 @@ public class AuthMe extends JavaPlugin {
/**
* Register all event listeners.
*/
private void registerEventListeners(Messages messages, DataSource dataSource, Management management,
PluginHooks pluginHooks, SpawnLoader spawnLoader, AntiBot antiBot,
BukkitService bukkitService, ValidationService validationService) {
private void registerEventListeners(AuthMeServiceInitializer initializer) {
// Get the plugin manager instance
PluginManager pluginManager = server.getPluginManager();
PluginManager pluginManager = getServer().getPluginManager();
// Register event listeners
pluginManager.registerEvents(new AuthMePlayerListener(
this, newSettings, messages, dataSource, antiBot, management, bukkitService, validationService), this);
pluginManager.registerEvents(new AuthMeBlockListener(), this);
pluginManager.registerEvents(new AuthMeEntityListener(), this);
pluginManager.registerEvents(new AuthMeServerListener(
this, messages, newSettings, pluginHooks, spawnLoader, validationService), this);
pluginManager.registerEvents(initializer.get(AuthMePlayerListener.class), this);
pluginManager.registerEvents(initializer.get(AuthMeBlockListener.class), this);
pluginManager.registerEvents(initializer.get(AuthMePlayerListener.class), this);
pluginManager.registerEvents(initializer.get(AuthMeServerListener.class), this);
// Try to register 1.6 player listeners
try {
Class.forName("org.bukkit.event.player.PlayerEditBookEvent");
pluginManager.registerEvents(new AuthMePlayerListener16(), this);
pluginManager.registerEvents(initializer.get(AuthMePlayerListener16.class), this);
} catch (ClassNotFoundException ignore) {
}
// Try to register 1.8 player listeners
try {
Class.forName("org.bukkit.event.player.PlayerInteractAtEntityEvent");
pluginManager.registerEvents(new AuthMePlayerListener18(), this);
pluginManager.registerEvents(initializer.get(AuthMePlayerListener18.class), this);
} catch (ClassNotFoundException ignore) {
}
// Try to register 1.9 player listeners
try {
Class.forName("org.spigotmc.event.player.PlayerSpawnLocationEvent");
pluginManager.registerEvents(new AuthMePlayerListener19(this), this);
pluginManager.registerEvents(initializer.get(AuthMePlayerListener19.class), this);
} catch (ClassNotFoundException ignore) {
}
}
@@ -438,30 +431,6 @@ public class AuthMe extends JavaPlugin {
}
}
private CommandHandler initializeCommandHandler(PermissionsManager permissionsManager, Messages messages,
PasswordSecurity passwordSecurity, NewSetting settings,
PluginHooks pluginHooks, SpawnLoader spawnLoader, AntiBot antiBot,
ValidationService validationService, BukkitService bukkitService) {
HelpProvider helpProvider = new HelpProvider(permissionsManager, settings.getProperty(HELP_HEADER));
Set<CommandDescription> baseCommands = CommandInitializer.buildCommands();
CommandMapper mapper = new CommandMapper(baseCommands, permissionsManager);
CommandService commandService = new CommandService(this, mapper, helpProvider, messages, passwordSecurity,
permissionsManager, settings, pluginHooks, spawnLoader, antiBot, validationService, bukkitService);
return new CommandHandler(commandService);
}
/**
* Set up the API. This sets up the new and the old API.
*/
@SuppressWarnings("deprecation")
private void setupApi() {
// Set up the API
api = new NewAPI(this);
// Set up the deprecated API
new API(this);
}
/**
* Load the plugin's settings.
*
@@ -474,7 +443,7 @@ public class AuthMe extends JavaPlugin {
} catch (Exception e) {
ConsoleLogger.logException("Can't load the configuration file... Something went wrong. "
+ "To avoid security issues the server will shut down!", e);
server.shutdown();
getServer().shutdown();
}
return false;
}
@@ -519,14 +488,15 @@ public class AuthMe extends JavaPlugin {
// Do backup on stop if enabled
if (newSettings != null) {
new PerformBackup(plugin, newSettings).doBackup(PerformBackup.BackupCause.STOP);
new PerformBackup(this, newSettings).doBackup(PerformBackup.BackupCause.STOP);
}
final AuthMe pluginInstance = this;
new Thread(new Runnable() {
@Override
public void run() {
List<Integer> pendingTasks = new ArrayList<>();
for (BukkitTask pendingTask : getServer().getScheduler().getPendingTasks()) {
if (pendingTask.getOwner().equals(plugin) && !pendingTask.isSync()) {
if (pendingTask.getOwner().equals(pluginInstance) && !pendingTask.isSync()) {
pendingTasks.add(pendingTask.getTaskId());
}
}
@@ -565,9 +535,9 @@ public class AuthMe extends JavaPlugin {
public void stopOrUnload() {
if (Settings.isStopEnabled) {
ConsoleLogger.showError("THE SERVER IS GOING TO SHUT DOWN AS DEFINED IN THE CONFIGURATION!");
server.shutdown();
getServer().shutdown();
} else {
server.getPluginManager().disablePlugin(AuthMe.getInstance());
getServer().getPluginManager().disablePlugin(AuthMe.getInstance());
}
}
@@ -610,7 +580,7 @@ public class AuthMe extends JavaPlugin {
database = dataSource;
if (DataSourceType.SQLITE == dataSourceType) {
server.getScheduler().runTaskAsynchronously(this, new Runnable() {
getServer().getScheduler().runTaskAsynchronously(this, new Runnable() {
@Override
public void run() {
int accounts = database.getAccountsRegistered();
@@ -623,15 +593,6 @@ public class AuthMe extends JavaPlugin {
}
}
/**
* Set up the permissions manager.
*/
private PermissionsManager initializePermissionsManager() {
PermissionsManager manager = new PermissionsManager(Bukkit.getServer(), getLogger());
manager.setup();
return manager;
}
// Set the console filter to remove the passwords
private void setLog4JFilter() {
Bukkit.getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
@@ -648,7 +609,7 @@ public class AuthMe extends JavaPlugin {
// Check the presence of the ProtocolLib plugin
public void checkProtocolLib() {
if (!server.getPluginManager().isPluginEnabled("ProtocolLib")) {
if (!getServer().getPluginManager().isPluginEnabled("ProtocolLib")) {
if (newSettings.getProperty(RestrictionSettings.PROTECT_INVENTORY_BEFORE_LOGIN)) {
ConsoleLogger.showError("WARNING! The protectInventory feature requires ProtocolLib! Disabling it...");
Settings.protectInventoryBeforeLogInEnabled = false;
@@ -683,7 +644,7 @@ public class AuthMe extends JavaPlugin {
// Save Player Data
private void savePlayer(Player player) {
if (Utils.isNPC(player) || Utils.isUnrestricted(player)) {
if (safeIsNpc(player) || Utils.isUnrestricted(player)) {
return;
}
String name = player.getName().toLowerCase();
@@ -711,6 +672,10 @@ public class AuthMe extends JavaPlugin {
PlayerCache.getInstance().removePlayer(name);
}
private boolean safeIsNpc(Player player) {
return pluginHooks != null && pluginHooks.isNpc(player) || player.hasMetadata("NPC");
}
// Select the player to kick when a vip player joins the server when full
public Player generateKickPlayer(Collection<? extends Player> collection) {
for (Player player : collection) {
@@ -727,7 +692,7 @@ public class AuthMe extends JavaPlugin {
return;
}
autoPurging = true;
server.getScheduler().runTaskAsynchronously(this, new Runnable() {
getServer().getScheduler().runTaskAsynchronously(this, new Runnable() {
@Override
public void run() {
ConsoleLogger.info("AutoPurging the Database...");
@@ -784,6 +749,7 @@ public class AuthMe extends JavaPlugin {
public String replaceAllInfo(String message, Player player) {
String playersOnline = Integer.toString(bukkitService.getOnlinePlayers().size());
String ipAddress = Utils.getPlayerIp(player);
Server server = getServer();
return message
.replace("&", "\u00a7")
.replace("{PLAYER}", player.getName())
+19 -21
View File
@@ -2,32 +2,37 @@ package fr.xephi.authme;
import fr.xephi.authme.hooks.PluginHooks;
import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.settings.NewSetting;
import fr.xephi.authme.settings.properties.PurgeSettings;
import fr.xephi.authme.util.BukkitService;
import fr.xephi.authme.util.Utils;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.Server;
import javax.inject.Inject;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import static fr.xephi.authme.util.StringUtils.makePath;
/**
*/
public class DataManager {
private final AuthMe plugin;
private final PluginHooks pluginHooks;
private final BukkitService bukkitService;
@Inject
private Server server;
@Inject
private PluginHooks pluginHooks;
@Inject
private BukkitService bukkitService;
@Inject
private NewSetting settings;
@Inject
private PermissionsManager permissionsManager;
/*
* Constructor.
*/
public DataManager(AuthMe plugin, PluginHooks pluginHooks, BukkitService bukkitService) {
this.plugin = plugin;
this.pluginHooks = pluginHooks;
this.bukkitService = bukkitService;
}
DataManager() { }
private List<OfflinePlayer> getOfflinePlayers(List<String> names) {
List<OfflinePlayer> result = new ArrayList<>();
@@ -98,9 +103,8 @@ public class DataManager {
public synchronized void purgeDat(List<String> cleared) {
int i = 0;
File dataFolder = new File(plugin.getServer().getWorldContainer()
+ File.separator + plugin.getSettings().getProperty(PurgeSettings.DEFAULT_WORLD)
+ File.separator + "players");
File dataFolder = new File(server.getWorldContainer(),
makePath(settings.getProperty(PurgeSettings.DEFAULT_WORLD), "players"));
List<OfflinePlayer> offlinePlayers = getOfflinePlayers(cleared);
for (OfflinePlayer player : offlinePlayers) {
File playerFile = new File(dataFolder, Utils.getUUIDorName(player) + ".dat");
@@ -142,14 +146,8 @@ public class DataManager {
// TODO: What is this method for? Is it correct?
// TODO: Make it work with OfflinePlayers group data.
public synchronized void purgePermissions(List<String> cleared) {
// Get the permissions manager, and make sure it's valid
PermissionsManager permsMan = plugin.getPermissionsManager();
if (permsMan == null) {
ConsoleLogger.showError("Unable to access permissions manager instance!");
return;
}
for (String name : cleared) {
permsMan.removeAllGroups(bukkitService.getPlayerExact(name));
permissionsManager.removeAllGroups(bukkitService.getPlayerExact(name));
}
ConsoleLogger.info("AutoPurge: Removed permissions from " + cleared.size() + " player(s).");
}
+14 -5
View File
@@ -3,6 +3,8 @@ package fr.xephi.authme.api;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.process.Management;
import fr.xephi.authme.security.PasswordSecurity;
import fr.xephi.authme.security.crypts.HashedPassword;
import fr.xephi.authme.util.Utils;
@@ -12,6 +14,8 @@ import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin;
import javax.inject.Inject;
/**
* Deprecated API of AuthMe. Please use {@link NewAPI} instead.
*/
@@ -20,7 +24,9 @@ public class API {
public static final String newline = System.getProperty("line.separator");
public static AuthMe instance;
private static DataSource dataSource;
private static PasswordSecurity passwordSecurity;
private static Management management;
/**
* Constructor for the deprecated API.
@@ -28,9 +34,12 @@ public class API {
* @param instance AuthMe
*/
@Deprecated
public API(AuthMe instance) {
@Inject
API(AuthMe instance, DataSource dataSource, PasswordSecurity passwordSecurity, Management management) {
API.instance = instance;
passwordSecurity = instance.getPasswordSecurity();
API.dataSource = dataSource;
API.passwordSecurity = passwordSecurity;
API.management = management;
}
/**
@@ -109,7 +118,7 @@ public class API {
@Deprecated
public static boolean isRegistered(String playerName) {
String player = playerName.toLowerCase();
return instance.getDataSource().isAuthAvailable(player);
return dataSource.isAuthAvailable(player);
}
/**
@@ -144,7 +153,7 @@ public class API {
.lastLogin(0)
.realName(playerName)
.build();
return instance.getDataSource().saveAuth(auth);
return dataSource.saveAuth(auth);
}
/**
@@ -154,7 +163,7 @@ public class API {
*/
@Deprecated
public static void forceLogin(Player player) {
instance.getManagement().performLogin(player, "dontneed", true);
management.performLogin(player, "dontneed", true);
}
@Deprecated
@@ -12,6 +12,8 @@ import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.security.crypts.HashedPassword;
import fr.xephi.authme.util.Utils;
import javax.inject.Inject;
/**
* The current API of AuthMe. Recommended method of retrieving the API object:
* <code>
@@ -28,6 +30,7 @@ public class NewAPI {
*
* @param plugin The AuthMe plugin instance
*/
@Inject
public NewAPI(AuthMe plugin) {
this.plugin = plugin;
}
@@ -1,14 +1,14 @@
package fr.xephi.authme.command;
import java.util.ArrayList;
import java.util.List;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.command.help.HelpProvider;
import fr.xephi.authme.util.StringUtils;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import fr.xephi.authme.util.StringUtils;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.List;
/**
* The AuthMe command handler, responsible for mapping incoming commands to the correct {@link CommandDescription}
@@ -29,6 +29,7 @@ public class CommandHandler {
*
* @param commandService The CommandService instance
*/
@Inject
public CommandHandler(CommandService commandService) {
this.commandService = commandService;
}
@@ -33,6 +33,7 @@ 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.initialization.AuthMeServiceInitializer;
import fr.xephi.authme.permission.AdminPermission;
import fr.xephi.authme.permission.PlayerPermission;
@@ -53,13 +54,13 @@ public final class CommandInitializer {
// Helper class
}
public static Set<CommandDescription> buildCommands() {
public static Set<CommandDescription> buildCommands(AuthMeServiceInitializer initializer) {
// 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())
.executableCommand(initializer.newInstance(AuthMeCommand.class))
.build();
// Register the register command
@@ -71,7 +72,7 @@ public final class CommandInitializer {
.withArgument("player", "Player name", false)
.withArgument("password", "Password", false)
.permissions(OP_ONLY, AdminPermission.REGISTER)
.executableCommand(new RegisterAdminCommand())
.executableCommand(initializer.newInstance(RegisterAdminCommand.class))
.build();
// Register the unregister command
@@ -82,7 +83,7 @@ public final class CommandInitializer {
.detailedDescription("Unregister the specified player.")
.withArgument("player", "Player name", false)
.permissions(OP_ONLY, AdminPermission.UNREGISTER)
.executableCommand(new UnregisterAdminCommand())
.executableCommand(initializer.newInstance(UnregisterAdminCommand.class))
.build();
// Register the forcelogin command
@@ -93,7 +94,7 @@ public final class CommandInitializer {
.detailedDescription("Enforce the specified player to login.")
.withArgument("player", "Online player name", true)
.permissions(OP_ONLY, AdminPermission.FORCE_LOGIN)
.executableCommand(new ForceLoginCommand())
.executableCommand(initializer.newInstance(ForceLoginCommand.class))
.build();
// Register the changepassword command
@@ -105,7 +106,7 @@ public final class CommandInitializer {
.withArgument("player", "Player name", false)
.withArgument("pwd", "New password", false)
.permissions(OP_ONLY, AdminPermission.CHANGE_PASSWORD)
.executableCommand(new ChangePasswordAdminCommand())
.executableCommand(initializer.newInstance(ChangePasswordAdminCommand.class))
.build();
// Register the last login command
@@ -116,7 +117,7 @@ public final class CommandInitializer {
.detailedDescription("View the date of the specified players last login.")
.withArgument("player", "Player name", true)
.permissions(OP_ONLY, AdminPermission.LAST_LOGIN)
.executableCommand(new LastLoginCommand())
.executableCommand(initializer.newInstance(LastLoginCommand.class))
.build();
// Register the accounts command
@@ -127,7 +128,7 @@ public final class CommandInitializer {
.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())
.executableCommand(initializer.newInstance(AccountsCommand.class))
.build();
// Register the getemail command
@@ -138,7 +139,7 @@ public final class CommandInitializer {
.detailedDescription("Display the email address of the specified player if set.")
.withArgument("player", "Player name", true)
.permissions(OP_ONLY, AdminPermission.GET_EMAIL)
.executableCommand(new GetEmailCommand())
.executableCommand(initializer.newInstance(GetEmailCommand.class))
.build();
// Register the setemail command
@@ -150,7 +151,7 @@ public final class CommandInitializer {
.withArgument("player", "Player name", false)
.withArgument("email", "Player email", false)
.permissions(OP_ONLY, AdminPermission.CHANGE_EMAIL)
.executableCommand(new SetEmailCommand())
.executableCommand(initializer.newInstance(SetEmailCommand.class))
.build();
// Register the getip command
@@ -161,7 +162,7 @@ public final class CommandInitializer {
.detailedDescription("Get the IP address of the specified online player.")
.withArgument("player", "Player name", false)
.permissions(OP_ONLY, AdminPermission.GET_IP)
.executableCommand(new GetIpCommand())
.executableCommand(initializer.newInstance(GetIpCommand.class))
.build();
// Register the spawn command
@@ -171,7 +172,7 @@ public final class CommandInitializer {
.description("Teleport to spawn")
.detailedDescription("Teleport to the spawn.")
.permissions(OP_ONLY, AdminPermission.SPAWN)
.executableCommand(new SpawnCommand())
.executableCommand(initializer.newInstance(SpawnCommand.class))
.build();
// Register the setspawn command
@@ -181,7 +182,7 @@ public final class CommandInitializer {
.description("Change the spawn")
.detailedDescription("Change the player's spawn to your current position.")
.permissions(OP_ONLY, AdminPermission.SET_SPAWN)
.executableCommand(new SetSpawnCommand())
.executableCommand(initializer.newInstance(SetSpawnCommand.class))
.build();
// Register the firstspawn command
@@ -191,7 +192,7 @@ public final class CommandInitializer {
.description("Teleport to first spawn")
.detailedDescription("Teleport to the first spawn.")
.permissions(OP_ONLY, AdminPermission.FIRST_SPAWN)
.executableCommand(new FirstSpawnCommand())
.executableCommand(initializer.newInstance(FirstSpawnCommand.class))
.build();
// Register the setfirstspawn command
@@ -201,7 +202,7 @@ public final class CommandInitializer {
.description("Change the first spawn")
.detailedDescription("Change the first player's spawn to your current position.")
.permissions(OP_ONLY, AdminPermission.SET_FIRST_SPAWN)
.executableCommand(new SetFirstSpawnCommand())
.executableCommand(initializer.newInstance(SetFirstSpawnCommand.class))
.build();
// Register the purge command
@@ -212,7 +213,7 @@ public final class CommandInitializer {
.detailedDescription("Purge old AuthMeReloaded data longer than the specified amount of days ago.")
.withArgument("days", "Number of days", false)
.permissions(OP_ONLY, AdminPermission.PURGE)
.executableCommand(new PurgeCommand())
.executableCommand(initializer.newInstance(PurgeCommand.class))
.build();
// Register the purgelastposition command
@@ -224,7 +225,7 @@ public final class CommandInitializer {
.detailedDescription("Purge the last know position of the specified player or all of them.")
.withArgument("player/*", "Player name or * for all players", false)
.permissions(OP_ONLY, AdminPermission.PURGE_LAST_POSITION)
.executableCommand(new PurgeLastPositionCommand())
.executableCommand(initializer.newInstance(PurgeLastPositionCommand.class))
.build();
// Register the purgebannedplayers command
@@ -234,7 +235,7 @@ public final class CommandInitializer {
.description("Purge banned players data")
.detailedDescription("Purge all AuthMeReloaded data for banned players.")
.permissions(OP_ONLY, AdminPermission.PURGE_BANNED_PLAYERS)
.executableCommand(new PurgeBannedPlayersCommand())
.executableCommand(initializer.newInstance(PurgeBannedPlayersCommand.class))
.build();
// Register the switchantibot command
@@ -245,7 +246,7 @@ public final class CommandInitializer {
.detailedDescription("Switch or toggle the AntiBot mode to the specified state.")
.withArgument("mode", "ON / OFF", true)
.permissions(OP_ONLY, AdminPermission.SWITCH_ANTIBOT)
.executableCommand(new SwitchAntiBotCommand())
.executableCommand(initializer.newInstance(SwitchAntiBotCommand.class))
.build();
// Register the reload command
@@ -255,7 +256,7 @@ public final class CommandInitializer {
.description("Reload plugin")
.detailedDescription("Reload the AuthMeReloaded plugin.")
.permissions(OP_ONLY, AdminPermission.RELOAD)
.executableCommand(new ReloadCommand())
.executableCommand(initializer.newInstance(ReloadCommand.class))
.build();
// Register the version command
@@ -265,7 +266,7 @@ public final class CommandInitializer {
.description("Version info")
.detailedDescription("Show detailed information about the installed AuthMeReloaded version, the "
+ "developers, contributors, and license.")
.executableCommand(new VersionCommand())
.executableCommand(initializer.newInstance(VersionCommand.class))
.build();
CommandDescription.builder()
@@ -276,7 +277,7 @@ public final class CommandInitializer {
.withArgument("job", "Conversion job: xauth / crazylogin / rakamak / " +
"royalauth / vauth / sqlitetosql", false)
.permissions(OP_ONLY, AdminPermission.CONVERTER)
.executableCommand(new ConverterCommand())
.executableCommand(initializer.newInstance(ConverterCommand.class))
.build();
// Register the base login command
@@ -287,7 +288,7 @@ public final class CommandInitializer {
.detailedDescription("Command to log in using AuthMeReloaded.")
.withArgument("password", "Login password", false)
.permissions(ALLOWED, PlayerPermission.LOGIN)
.executableCommand(new LoginCommand())
.executableCommand(initializer.newInstance(LoginCommand.class))
.build();
// Register the base logout command
@@ -297,7 +298,7 @@ public final class CommandInitializer {
.description("Logout command")
.detailedDescription("Command to logout using AuthMeReloaded.")
.permissions(ALLOWED, PlayerPermission.LOGOUT)
.executableCommand(new LogoutCommand())
.executableCommand(initializer.newInstance(LogoutCommand.class))
.build();
// Register the base register command
@@ -309,7 +310,7 @@ public final class CommandInitializer {
.withArgument("password", "Password", true)
.withArgument("verifyPassword", "Verify password", true)
.permissions(ALLOWED, PlayerPermission.REGISTER)
.executableCommand(new RegisterCommand())
.executableCommand(initializer.newInstance(RegisterCommand.class))
.build();
// Register the base unregister command
@@ -320,7 +321,7 @@ public final class CommandInitializer {
.detailedDescription("Command to unregister using AuthMeReloaded.")
.withArgument("password", "Password", false)
.permissions(ALLOWED, PlayerPermission.UNREGISTER)
.executableCommand(new UnregisterCommand())
.executableCommand(initializer.newInstance(UnregisterCommand.class))
.build();
// Register the base changepassword command
@@ -332,7 +333,7 @@ public final class CommandInitializer {
.withArgument("oldPassword", "Old Password", false)
.withArgument("newPassword", "New Password.", false)
.permissions(ALLOWED, PlayerPermission.CHANGE_PASSWORD)
.executableCommand(new ChangePasswordCommand())
.executableCommand(initializer.newInstance(ChangePasswordCommand.class))
.build();
// Register the base Email command
@@ -341,7 +342,7 @@ public final class CommandInitializer {
.labels("email", "mail")
.description("Email command")
.detailedDescription("The AuthMeReloaded Email command base.")
.executableCommand(new EmailBaseCommand())
.executableCommand(initializer.newInstance(EmailBaseCommand.class))
.build();
// Register the add command
@@ -353,7 +354,7 @@ public final class CommandInitializer {
.withArgument("email", "Email address", false)
.withArgument("verifyEmail", "Email address verification", false)
.permissions(ALLOWED, PlayerPermission.ADD_EMAIL)
.executableCommand(new AddEmailCommand())
.executableCommand(initializer.newInstance(AddEmailCommand.class))
.build();
// Register the change command
@@ -365,7 +366,7 @@ public final class CommandInitializer {
.withArgument("oldEmail", "Old email address", false)
.withArgument("newEmail", "New email address", false)
.permissions(ALLOWED, PlayerPermission.CHANGE_EMAIL)
.executableCommand(new ChangeEmailCommand())
.executableCommand(initializer.newInstance(ChangeEmailCommand.class))
.build();
// Register the recover command
@@ -377,7 +378,7 @@ public final class CommandInitializer {
"a new password.")
.withArgument("email", "Email address", false)
.permissions(ALLOWED, PlayerPermission.RECOVER_EMAIL)
.executableCommand(new RecoverEmailCommand())
.executableCommand(initializer.newInstance(RecoverEmailCommand.class))
.build();
// Register the base captcha command
@@ -388,7 +389,7 @@ public final class CommandInitializer {
.detailedDescription("Captcha command for AuthMeReloaded.")
.withArgument("captcha", "The Captcha", false)
.permissions(ALLOWED, PlayerPermission.CAPTCHA)
.executableCommand(new CaptchaCommand())
.executableCommand(initializer.newInstance(CaptchaCommand.class))
.build();
Set<CommandDescription> baseCommands = ImmutableSet.of(
@@ -401,7 +402,7 @@ public final class CommandInitializer {
EMAIL_BASE,
CAPTCHA_BASE);
setHelpOnAllBases(baseCommands);
setHelpOnAllBases(baseCommands, initializer);
return baseCommands;
}
@@ -409,9 +410,11 @@ public final class CommandInitializer {
* Set the help command on all base commands, e.g. to register /authme help or /register help.
*
* @param commands The list of base commands to register a help child command on
* @param initializer The service initializer
*/
private static void setHelpOnAllBases(Collection<CommandDescription> commands) {
final HelpCommand helpCommandExecutable = new HelpCommand();
private static void setHelpOnAllBases(Collection<CommandDescription> commands,
AuthMeServiceInitializer initializer) {
final HelpCommand helpCommandExecutable = initializer.newInstance(HelpCommand.class);
final List<String> helpCommandLabels = Arrays.asList("help", "hlp", "h", "sos", "?");
for (CommandDescription base : commands) {
@@ -1,11 +1,13 @@
package fr.xephi.authme.command;
import fr.xephi.authme.command.executable.HelpCommand;
import fr.xephi.authme.initialization.BaseCommands;
import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.util.CollectionUtils;
import fr.xephi.authme.util.StringUtils;
import org.bukkit.command.CommandSender;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@@ -28,7 +30,8 @@ public class CommandMapper {
private final Set<CommandDescription> baseCommands;
private final PermissionsManager permissionsManager;
public CommandMapper(Set<CommandDescription> baseCommands, PermissionsManager permissionsManager) {
@Inject
public CommandMapper(@BaseCommands Set<CommandDescription> baseCommands, PermissionsManager permissionsManager) {
this.baseCommands = baseCommands;
this.permissionsManager = permissionsManager;
}
@@ -1,10 +1,7 @@
package fr.xephi.authme.command;
import fr.xephi.authme.AntiBot;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.command.help.HelpProvider;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.hooks.PluginHooks;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages;
@@ -19,6 +16,7 @@ import fr.xephi.authme.util.ValidationService;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import javax.inject.Inject;
import java.util.Collection;
import java.util.List;
@@ -28,39 +26,28 @@ import java.util.List;
*/
public class CommandService {
private final AuthMe authMe;
private final Messages messages;
private final HelpProvider helpProvider;
private final CommandMapper commandMapper;
private final PasswordSecurity passwordSecurity;
private final PermissionsManager permissionsManager;
private final NewSetting settings;
private final PluginHooks pluginHooks;
private final SpawnLoader spawnLoader;
private final AntiBot antiBot;
private final ValidationService validationService;
private final BukkitService bukkitService;
/*
* Constructor.
*/
public CommandService(AuthMe authMe, CommandMapper commandMapper, HelpProvider helpProvider, Messages messages,
PasswordSecurity passwordSecurity, PermissionsManager permissionsManager, NewSetting settings,
PluginHooks pluginHooks, SpawnLoader spawnLoader, AntiBot antiBot,
ValidationService validationService, BukkitService bukkitService) {
this.authMe = authMe;
this.messages = messages;
this.helpProvider = helpProvider;
this.commandMapper = commandMapper;
this.passwordSecurity = passwordSecurity;
this.permissionsManager = permissionsManager;
this.settings = settings;
this.pluginHooks = pluginHooks;
this.spawnLoader = spawnLoader;
this.antiBot = antiBot;
this.validationService = validationService;
this.bukkitService = bukkitService;
}
@Inject
private AuthMe authMe;
@Inject
private Messages messages;
@Inject
private HelpProvider helpProvider;
@Inject
private CommandMapper commandMapper;
@Inject
private PasswordSecurity passwordSecurity;
@Inject
private PermissionsManager permissionsManager;
@Inject
private NewSetting settings;
@Inject
private PluginHooks pluginHooks;
@Inject
private SpawnLoader spawnLoader;
@Inject
private ValidationService validationService;
@Inject
private BukkitService bukkitService;
/**
* Send a message to a player.
@@ -103,15 +90,6 @@ public class CommandService {
authMe.getServer().getScheduler().runTaskAsynchronously(authMe, task);
}
/**
* Return the AuthMe data source.
*
* @return The used data source
*/
public DataSource getDataSource() {
return authMe.getDataSource();
}
/**
* Return the AuthMe instance for further manipulation. Use only if other methods from
* the command service cannot be used.
@@ -122,15 +100,6 @@ public class CommandService {
return authMe;
}
/**
* Return the PasswordSecurity instance.
*
* @return The password security instance
*/
public PasswordSecurity getPasswordSecurity() {
return passwordSecurity;
}
/**
* Output the help for a given command.
*
@@ -193,10 +162,6 @@ public class CommandService {
return settings;
}
public PlayerCache getPlayerCache() {
return PlayerCache.getInstance();
}
public PluginHooks getPluginHooks() {
return pluginHooks;
}
@@ -205,10 +170,6 @@ public class CommandService {
return spawnLoader;
}
public AntiBot getAntiBot() {
return antiBot;
}
/**
* Verifies whether a password is valid according to the plugin settings.
*
@@ -3,10 +3,13 @@ package fr.xephi.authme.command.executable.authme;
import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.command.CommandService;
import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages;
import fr.xephi.authme.util.StringUtils;
import org.bukkit.command.CommandSender;
import javax.inject.Inject;
import java.util.List;
/**
@@ -14,6 +17,11 @@ import java.util.List;
*/
public class AccountsCommand implements ExecutableCommand {
@Inject
private DataSource dataSource;
@Inject
private Messages messages;
@Override
public void executeCommand(final CommandSender sender, List<String> arguments,
final CommandService commandService) {
@@ -24,15 +32,15 @@ public class AccountsCommand implements ExecutableCommand {
commandService.runTaskAsynchronously(new Runnable() {
@Override
public void run() {
PlayerAuth auth = commandService.getDataSource().getAuth(playerName.toLowerCase());
PlayerAuth auth = dataSource.getAuth(playerName.toLowerCase());
if (auth == null) {
commandService.send(sender, MessageKey.UNKNOWN_USER);
messages.send(sender, MessageKey.UNKNOWN_USER);
return;
}
List<String> accountList = commandService.getDataSource().getAllAuthsByIp(auth.getIp());
List<String> accountList = dataSource.getAllAuthsByIp(auth.getIp());
if (accountList.isEmpty()) {
commandService.send(sender, MessageKey.USER_NOT_REGISTERED);
messages.send(sender, MessageKey.USER_NOT_REGISTERED);
} else if (accountList.size() == 1) {
sender.sendMessage("[AuthMe] " + playerName + " is a single account player");
} else {
@@ -44,7 +52,7 @@ public class AccountsCommand implements ExecutableCommand {
commandService.runTaskAsynchronously(new Runnable() {
@Override
public void run() {
List<String> accountList = commandService.getDataSource().getAllAuthsByIp(playerName);
List<String> accountList = dataSource.getAllAuthsByIp(playerName);
if (accountList.isEmpty()) {
sender.sendMessage("[AuthMe] This IP does not exist in the database.");
} else if (accountList.size() == 1) {
@@ -2,13 +2,16 @@ package fr.xephi.authme.command.executable.authme;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.command.CommandService;
import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.security.PasswordSecurity;
import fr.xephi.authme.security.crypts.HashedPassword;
import org.bukkit.command.CommandSender;
import javax.inject.Inject;
import java.util.List;
/**
@@ -16,6 +19,15 @@ import java.util.List;
*/
public class ChangePasswordAdminCommand implements ExecutableCommand {
@Inject
private PasswordSecurity passwordSecurity;
@Inject
private PlayerCache playerCache;
@Inject
private DataSource dataSource;
@Override
public void executeCommand(final CommandSender sender, List<String> arguments,
final CommandService commandService) {
@@ -36,10 +48,9 @@ public class ChangePasswordAdminCommand implements ExecutableCommand {
@Override
public void run() {
DataSource dataSource = commandService.getDataSource();
PlayerAuth auth = null;
if (commandService.getPlayerCache().isAuthenticated(playerNameLowerCase)) {
auth = commandService.getPlayerCache().getAuth(playerNameLowerCase);
if (playerCache.isAuthenticated(playerNameLowerCase)) {
auth = playerCache.getAuth(playerNameLowerCase);
} else if (dataSource.isAuthAvailable(playerNameLowerCase)) {
auth = dataSource.getAuth(playerNameLowerCase);
}
@@ -48,8 +59,7 @@ public class ChangePasswordAdminCommand implements ExecutableCommand {
return;
}
HashedPassword hashedPassword = commandService.getPasswordSecurity()
.computeHash(playerPass, playerNameLowerCase);
HashedPassword hashedPassword = passwordSecurity.computeHash(playerPass, playerNameLowerCase);
auth.setPassword(hashedPassword);
if (!dataSource.updatePassword(auth)) {
@@ -3,9 +3,11 @@ package fr.xephi.authme.command.executable.authme;
import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.command.CommandService;
import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.output.MessageKey;
import org.bukkit.command.CommandSender;
import javax.inject.Inject;
import java.util.List;
/**
@@ -13,11 +15,14 @@ import java.util.List;
*/
public class GetEmailCommand implements ExecutableCommand {
@Inject
private DataSource dataSource;
@Override
public void executeCommand(CommandSender sender, List<String> arguments, CommandService commandService) {
String playerName = arguments.isEmpty() ? sender.getName() : arguments.get(0);
PlayerAuth auth = commandService.getDataSource().getAuth(playerName);
PlayerAuth auth = dataSource.getAuth(playerName);
if (auth == null) {
commandService.send(sender, MessageKey.UNKNOWN_USER);
} else {
@@ -3,9 +3,11 @@ package fr.xephi.authme.command.executable.authme;
import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.command.CommandService;
import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.output.MessageKey;
import org.bukkit.command.CommandSender;
import javax.inject.Inject;
import java.util.Date;
import java.util.List;
@@ -14,12 +16,15 @@ import java.util.List;
*/
public class LastLoginCommand implements ExecutableCommand {
@Inject
private DataSource dataSource;
@Override
public void executeCommand(CommandSender sender, List<String> arguments, CommandService commandService) {
// Get the player
String playerName = (arguments.size() >= 1) ? arguments.get(0) : sender.getName();
PlayerAuth auth = commandService.getDataSource().getAuth(playerName);
PlayerAuth auth = dataSource.getAuth(playerName);
if (auth == null) {
commandService.send(sender, MessageKey.USER_NOT_REGISTERED);
return;
@@ -3,10 +3,12 @@ package fr.xephi.authme.command.executable.authme;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.command.CommandService;
import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.settings.properties.PurgeSettings;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.List;
@@ -16,6 +18,9 @@ import java.util.List;
*/
public class PurgeBannedPlayersCommand implements ExecutableCommand {
@Inject
private DataSource dataSource;
@Override
public void executeCommand(CommandSender sender, List<String> arguments, CommandService commandService) {
// AuthMe plugin instance
@@ -23,12 +28,12 @@ public class PurgeBannedPlayersCommand implements ExecutableCommand {
// Get the list of banned players
List<String> bannedPlayers = new ArrayList<>();
for (OfflinePlayer offlinePlayer : plugin.getServer().getBannedPlayers()) {
for (OfflinePlayer offlinePlayer : commandService.getBukkitService().getBannedPlayers()) {
bannedPlayers.add(offlinePlayer.getName().toLowerCase());
}
// Purge the banned players
commandService.getDataSource().purgeBanned(bannedPlayers);
dataSource.purgeBanned(bannedPlayers);
if (commandService.getProperty(PurgeSettings.REMOVE_ESSENTIALS_FILES)
&& commandService.getPluginHooks().isEssentialsAvailable())
plugin.dataManager.purgeEssentials(bannedPlayers);
@@ -3,10 +3,12 @@ package fr.xephi.authme.command.executable.authme;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.command.CommandService;
import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.settings.properties.PurgeSettings;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import javax.inject.Inject;
import java.util.Calendar;
import java.util.List;
@@ -18,6 +20,9 @@ public class PurgeCommand implements ExecutableCommand {
private static final int MINIMUM_LAST_SEEN_DAYS = 30;
@Inject
private DataSource dataSource;
@Override
public void executeCommand(CommandSender sender, List<String> arguments, CommandService commandService) {
// Get the days parameter
@@ -45,7 +50,7 @@ public class PurgeCommand implements ExecutableCommand {
long until = calendar.getTimeInMillis();
// Purge the data, get the purged values
List<String> purged = commandService.getDataSource().autoPurgeDatabase(until);
List<String> purged = dataSource.autoPurgeDatabase(until);
// Show a status message
sender.sendMessage(ChatColor.GOLD + "Deleted " + purged.size() + " user accounts");
@@ -3,9 +3,11 @@ package fr.xephi.authme.command.executable.authme;
import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.command.CommandService;
import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.output.MessageKey;
import org.bukkit.command.CommandSender;
import javax.inject.Inject;
import java.util.List;
/**
@@ -13,26 +15,29 @@ import java.util.List;
*/
public class PurgeLastPositionCommand implements ExecutableCommand {
@Inject
private DataSource dataSource;
@Override
public void executeCommand(final CommandSender sender, List<String> arguments, CommandService commandService) {
String playerName = arguments.isEmpty() ? sender.getName() : arguments.get(0);
if ("*".equals(playerName)) {
for (PlayerAuth auth : commandService.getDataSource().getAllAuths()) {
for (PlayerAuth auth : dataSource.getAllAuths()) {
resetLastPosition(auth);
commandService.getDataSource().updateQuitLoc(auth);
dataSource.updateQuitLoc(auth);
}
sender.sendMessage("All players last position locations are now reset");
} else {
// Get the user auth and make sure the user exists
PlayerAuth auth = commandService.getDataSource().getAuth(playerName);
PlayerAuth auth = dataSource.getAuth(playerName);
if (auth == null) {
commandService.send(sender, MessageKey.UNKNOWN_USER);
return;
}
resetLastPosition(auth);
commandService.getDataSource().updateQuitLoc(auth);
dataSource.updateQuitLoc(auth);
sender.sendMessage(playerName + "'s last position location is now reset");
}
}
@@ -1,22 +1,30 @@
package fr.xephi.authme.command.executable.authme;
import java.util.List;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.command.CommandService;
import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.security.PasswordSecurity;
import fr.xephi.authme.security.crypts.HashedPassword;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import javax.inject.Inject;
import java.util.List;
/**
* Admin command to register a user.
*/
public class RegisterAdminCommand implements ExecutableCommand {
@Inject
private PasswordSecurity passwordSecurity;
@Inject
private DataSource dataSource;
@Override
public void executeCommand(final CommandSender sender, List<String> arguments,
final CommandService commandService) {
@@ -36,33 +44,31 @@ public class RegisterAdminCommand implements ExecutableCommand {
@Override
public void run() {
if (commandService.getDataSource().isAuthAvailable(playerNameLowerCase)) {
if (dataSource.isAuthAvailable(playerNameLowerCase)) {
commandService.send(sender, MessageKey.NAME_ALREADY_REGISTERED);
return;
}
HashedPassword hashedPassword = commandService.getPasswordSecurity()
.computeHash(playerPass, playerNameLowerCase);
HashedPassword hashedPassword = passwordSecurity.computeHash(playerPass, playerNameLowerCase);
PlayerAuth auth = PlayerAuth.builder()
.name(playerNameLowerCase)
.realName(playerName)
.password(hashedPassword)
.build();
if (!commandService.getDataSource().saveAuth(auth)) {
if (!dataSource.saveAuth(auth)) {
commandService.send(sender, MessageKey.ERROR);
return;
}
commandService.getDataSource().setUnlogged(playerNameLowerCase);
dataSource.setUnlogged(playerNameLowerCase);
commandService.send(sender, MessageKey.REGISTER_SUCCESS);
ConsoleLogger.info(sender.getName() + " registered " + playerName);
Player player = commandService.getPlayer(playerName);
final Player player = commandService.getPlayer(playerName);
if (player != null) {
final Player p = player;
p.getServer().getScheduler().scheduleSyncDelayedTask(commandService.getAuthMe(), new Runnable() {
commandService.getBukkitService().scheduleSyncDelayedTask(new Runnable() {
@Override
public void run() {
p.kickPlayer("An admin just registered you, please log in again");
player.kickPlayer("An admin just registered you, please log in again");
}
});
}
@@ -8,6 +8,7 @@ import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.output.MessageKey;
import org.bukkit.command.CommandSender;
import javax.inject.Inject;
import java.util.List;
/**
@@ -15,6 +16,12 @@ import java.util.List;
*/
public class SetEmailCommand implements ExecutableCommand {
@Inject
private DataSource dataSource;
@Inject
private PlayerCache playerCache;
@Override
public void executeCommand(final CommandSender sender, List<String> arguments,
final CommandService commandService) {
@@ -32,7 +39,6 @@ public class SetEmailCommand implements ExecutableCommand {
@Override
public void run() {
// Validate the user
DataSource dataSource = commandService.getDataSource();
PlayerAuth auth = dataSource.getAuth(playerName);
if (auth == null) {
commandService.send(sender, MessageKey.UNKNOWN_USER);
@@ -50,8 +56,8 @@ public class SetEmailCommand implements ExecutableCommand {
}
// Update the player cache
if (PlayerCache.getInstance().getAuth(playerName) != null) {
PlayerCache.getInstance().updatePlayer(auth);
if (playerCache.getAuth(playerName) != null) {
playerCache.updatePlayer(auth);
}
// Show a status message
@@ -8,6 +8,7 @@ import fr.xephi.authme.command.help.HelpProvider;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import javax.inject.Inject;
import java.util.Arrays;
import java.util.List;
@@ -16,9 +17,11 @@ import java.util.List;
*/
public class SwitchAntiBotCommand implements ExecutableCommand {
@Inject
private AntiBot antiBot;
@Override
public void executeCommand(final CommandSender sender, List<String> arguments, CommandService commandService) {
AntiBot antiBot = commandService.getAntiBot();
if (arguments.isEmpty()) {
sender.sendMessage("[AuthMe] AntiBot status: " + antiBot.getAntiBotStatus().name());
return;
@@ -6,6 +6,7 @@ import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.cache.limbo.LimboCache;
import fr.xephi.authme.command.CommandService;
import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.settings.properties.RegistrationSettings;
import fr.xephi.authme.settings.properties.RestrictionSettings;
@@ -19,6 +20,7 @@ import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.scheduler.BukkitTask;
import javax.inject.Inject;
import java.util.List;
import static fr.xephi.authme.util.BukkitService.TICKS_PER_SECOND;
@@ -28,6 +30,12 @@ import static fr.xephi.authme.util.BukkitService.TICKS_PER_SECOND;
*/
public class UnregisterAdminCommand implements ExecutableCommand {
@Inject
private DataSource dataSource;
@Inject
private PlayerCache playerCache;
@Override
public void executeCommand(final CommandSender sender, List<String> arguments, CommandService commandService) {
// Get the player name
@@ -35,20 +43,20 @@ public class UnregisterAdminCommand implements ExecutableCommand {
String playerNameLowerCase = playerName.toLowerCase();
// Make sure the user is valid
if (!commandService.getDataSource().isAuthAvailable(playerNameLowerCase)) {
if (!dataSource.isAuthAvailable(playerNameLowerCase)) {
commandService.send(sender, MessageKey.UNKNOWN_USER);
return;
}
// Remove the player
if (!commandService.getDataSource().removeAuth(playerNameLowerCase)) {
if (!dataSource.removeAuth(playerNameLowerCase)) {
commandService.send(sender, MessageKey.ERROR);
return;
}
// Unregister the player
Player target = commandService.getPlayer(playerNameLowerCase);
PlayerCache.getInstance().removePlayer(playerNameLowerCase);
playerCache.removePlayer(playerNameLowerCase);
Utils.setGroup(target, Utils.GroupType.UNREGISTERED);
if (target != null && target.isOnline()) {
if (commandService.getProperty(RegistrationSettings.FORCE)) {
@@ -8,6 +8,7 @@ import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.task.ChangePasswordTask;
import org.bukkit.entity.Player;
import javax.inject.Inject;
import java.util.List;
/**
@@ -15,13 +16,15 @@ import java.util.List;
*/
public class ChangePasswordCommand extends PlayerCommand {
@Inject
private PlayerCache playerCache;
@Override
public void runCommand(Player player, List<String> arguments, CommandService commandService) {
String oldPassword = arguments.get(0);
String newPassword = arguments.get(1);
String name = player.getName().toLowerCase();
final PlayerCache playerCache = commandService.getPlayerCache();
if (!playerCache.isAuthenticated(name)) {
commandService.send(player, MessageKey.NOT_LOGGED_IN);
return;
@@ -8,16 +8,27 @@ import fr.xephi.authme.command.CommandService;
import fr.xephi.authme.command.PlayerCommand;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.security.PasswordSecurity;
import fr.xephi.authme.security.RandomString;
import fr.xephi.authme.security.crypts.HashedPassword;
import fr.xephi.authme.settings.properties.EmailSettings;
import fr.xephi.authme.util.StringUtils;
import org.bukkit.entity.Player;
import javax.inject.Inject;
import java.util.List;
public class RecoverEmailCommand extends PlayerCommand {
@Inject
private PasswordSecurity passwordSecurity;
@Inject
private DataSource dataSource;
@Inject
private PlayerCache playerCache;
@Override
public void runCommand(Player player, List<String> arguments, CommandService commandService) {
final String playerMail = arguments.get(0);
@@ -29,7 +40,6 @@ public class RecoverEmailCommand extends PlayerCommand {
commandService.send(player, MessageKey.ERROR);
return;
}
DataSource dataSource = commandService.getDataSource();
if (dataSource.isAuthAvailable(playerName)) {
if (PlayerCache.getInstance().isAuthenticated(playerName)) {
commandService.send(player, MessageKey.ALREADY_LOGGED_IN_ERROR);
@@ -37,10 +47,10 @@ public class RecoverEmailCommand extends PlayerCommand {
}
String thePass = RandomString.generate(commandService.getProperty(EmailSettings.RECOVERY_PASSWORD_LENGTH));
HashedPassword hashNew = commandService.getPasswordSecurity().computeHash(thePass, playerName);
HashedPassword hashNew = passwordSecurity.computeHash(thePass, playerName);
PlayerAuth auth;
if (PlayerCache.getInstance().isAuthenticated(playerName)) {
auth = PlayerCache.getInstance().getAuth(playerName);
if (playerCache.isAuthenticated(playerName)) {
auth = playerCache.getAuth(playerName);
} else if (dataSource.isAuthAvailable(playerName)) {
auth = dataSource.getAuth(playerName);
} else {
@@ -10,10 +10,13 @@ import fr.xephi.authme.command.FoundCommandResult;
import fr.xephi.authme.permission.DefaultPermission;
import fr.xephi.authme.permission.PermissionNode;
import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.settings.NewSetting;
import fr.xephi.authme.settings.properties.PluginSettings;
import fr.xephi.authme.util.CollectionUtils;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.List;
@@ -45,9 +48,10 @@ public class HelpProvider {
private final PermissionsManager permissionsManager;
private final String helpHeader;
public HelpProvider(PermissionsManager permissionsManager, String helpHeader) {
@Inject
public HelpProvider(PermissionsManager permissionsManager, NewSetting settings) {
this.permissionsManager = permissionsManager;
this.helpHeader = helpHeader;
this.helpHeader = settings.getProperty(PluginSettings.HELP_HEADER);
}
public List<String> printHelp(CommandSender sender, FoundCommandResult result, int options) {
@@ -1,19 +1,18 @@
package fr.xephi.authme.hooks;
import java.io.File;
import com.earth2me.essentials.Essentials;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVWorldManager;
import fr.xephi.authme.ConsoleLogger;
import net.minelink.ctplus.CombatTagPlus;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager;
import com.earth2me.essentials.Essentials;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVWorldManager;
import fr.xephi.authme.ConsoleLogger;
import net.minelink.ctplus.CombatTagPlus;
import javax.inject.Inject;
import java.io.File;
/**
* Hooks into third-party plugins and allows to perform actions on them.
@@ -30,6 +29,7 @@ public class PluginHooks {
*
* @param pluginManager The server's plugin manager
*/
@Inject
public PluginHooks(PluginManager pluginManager) {
this.pluginManager = pluginManager;
tryHookToCombatPlus();
@@ -77,13 +77,23 @@ public class PluginHooks {
return null;
}
/**
* Checks whether the player is an NPC.
*
* @param player The player to process
* @return True if player is NPC, false otherwise
*/
public boolean isNpc(Player player) {
return player.hasMetadata("NPC") || isNpcInCombatTagPlus(player);
}
/**
* Query the CombatTagPlus plugin whether the given player is an NPC.
*
* @param player The player to verify
* @return True if the player is an NPC according to CombatTagPlus, false if not or if the plugin is unavailable
*/
public boolean isNpcInCombatTagPlus(Player player) {
private boolean isNpcInCombatTagPlus(Player player) {
return combatTagPlus != null && combatTagPlus.getNpcPlayerHelper().isNpc(player);
}
@@ -0,0 +1,263 @@
package fr.xephi.authme.initialization;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableSet;
import javax.annotation.PostConstruct;
import javax.inject.Provider;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* Dependency injector of AuthMe: initializes and injects services and tasks.
* <p>
* Only constructor and field injection are supported, indicated with the JSR330
* {@link javax.inject.Inject @Inject} annotation.
* <p>
* {@link PostConstruct @PostConstruct} methods are recognized and invoked upon
* instantiation. Note that the parent classes are <i>not</i> scanned for such methods.
*/
public class AuthMeServiceInitializer {
private final Set<String> ALLOWED_PACKAGES;
private final Map<Class<?>, Object> objects;
/**
* Constructor.
*
* @param allowedPackages list of allowed packages. Only classes whose package
* starts with any of the given entries will be instantiated
*/
public AuthMeServiceInitializer(String... allowedPackages) {
ALLOWED_PACKAGES = ImmutableSet.copyOf(allowedPackages);
objects = new HashMap<>();
objects.put(getClass(), this);
}
/**
* Retrieves or instantiates an object of the given type.
*
* @param clazz the class to retrieve the value for
* @param <T> the class' type
* @return object of the class' type
*/
public <T> T get(Class<T> clazz) {
return get(clazz, new HashSet<Class<?>>());
}
/**
* Register an object with a custom class (supertype). Use this for example to specify a
* concrete implementation of an interface or an abstract class.
*
* @param clazz the class to register the object for
* @param object the object
* @param <T> the class' type
*/
public <T> void register(Class<? super T> clazz, T object) {
if (objects.containsKey(clazz)) {
throw new IllegalStateException("There is already an object present for " + clazz);
}
Preconditions.checkNotNull(object);
objects.put(clazz, object);
}
/**
* Associate an annotation with a value.
*
* @param annotation the annotation
* @param value the value
*/
public void provide(Class<? extends Annotation> annotation, Object value) {
if (objects.containsKey(annotation)) {
throw new IllegalStateException("Annotation @" + annotation.getClass().getSimpleName()
+ " already registered");
}
Preconditions.checkNotNull(value);
objects.put(annotation, value);
}
/**
* Creates a new instance of the given class and does <i>not</i> keep track of it afterwards,
* unlike {@link #get(Class)} (singleton scope).
*
* @param clazz the class to instantiate
* @param <T> the class' type
* @return new instance of class T
*/
public <T> T newInstance(Class<T> clazz) {
return instantiate(clazz, new HashSet<Class<?>>());
}
/**
* Returns an instance of the given class or the value associated with an annotation,
* by retrieving it or by instantiating it if not yet present.
*
* @param clazz the class to retrieve a value for
* @param traversedClasses the list of traversed classes
* @param <T> the class' type
* @return instance or associated value (for annotations)
*/
private <T> T get(Class<T> clazz, Set<Class<?>> traversedClasses) {
if (Annotation.class.isAssignableFrom(clazz)) {
throw new UnsupportedOperationException("Cannot retrieve annotated elements in this way!");
} else if (objects.containsKey(clazz)) {
return clazz.cast(objects.get(clazz));
}
// First time we come across clazz, need to instantiate it. Validate that we can do so
validatePackage(clazz);
validateInstantiable(clazz);
// Add the clazz to the list of traversed classes in a new Set, so each path we take has its own Set.
traversedClasses = new HashSet<>(traversedClasses);
traversedClasses.add(clazz);
T object = instantiate(clazz, traversedClasses);
storeObject(object);
return object;
}
/**
* Instantiates the given class by locating an @Inject constructor and retrieving
* or instantiating its parameters.
*
* @param clazz the class to instantiate
* @param traversedClasses collection of classes already traversed
* @param <T> the class' type
* @return the instantiated object
*/
private <T> T instantiate(Class<T> clazz, Set<Class<?>> traversedClasses) {
Injection<T> injection = firstNotNull(ConstructorInjection.provide(clazz), FieldInjection.provide(clazz));
if (injection == null) {
throw new IllegalStateException("Did not find injection method for " + clazz + ". Make sure you have "
+ "a constructor with @Inject or fields with @Inject. Fields with @Inject require "
+ "the default constructor");
}
validateInjectionHasNoCircularDependencies(injection.getDependencies(), traversedClasses);
Object[] dependencies = resolveDependencies(injection, traversedClasses);
T object = injection.instantiateWith(dependencies);
executePostConstructMethods(object);
return object;
}
/**
* Resolves the dependencies for the given constructor, i.e. returns a collection that satisfy
* the constructor's parameter types by retrieving elements or instantiating them where necessary.
*
* @param injection the injection parameters
* @param traversedClasses collection of traversed classes
* @return array with the parameters to use in the constructor
*/
private Object[] resolveDependencies(Injection<?> injection, Set<Class<?>> traversedClasses) {
Class<?>[] dependencies = injection.getDependencies();
Class<?>[] annotations = injection.getDependencyAnnotations();
Object[] values = new Object[dependencies.length];
for (int i = 0; i < dependencies.length; ++i) {
if (annotations[i] != null) {
Object value = objects.get(annotations[i]);
if (value == null) {
throw new IllegalStateException("Value for field with @" + annotations[i].getSimpleName()
+ " must be registered beforehand");
}
values[i] = value;
} else {
values[i] = get(dependencies[i], traversedClasses);
}
}
return values;
}
/**
* Stores the given object with its class as key. Throws an exception if the key already has
* a value associated to it.
*
* @param object the object to store
*/
private void storeObject(Object object) {
if (objects.containsKey(object.getClass())) {
throw new IllegalStateException("There is already an object present for " + object.getClass());
}
Preconditions.checkNotNull(object);
objects.put(object.getClass(), object);
}
/**
* Validates that none of the dependencies' types are present in the given collection
* of traversed classes. This prevents circular dependencies.
*
* @param dependencies the dependencies of the class
* @param traversedClasses the collection of traversed classes
*/
private static void validateInjectionHasNoCircularDependencies(Class<?>[] dependencies,
Set<Class<?>> traversedClasses) {
for (Class<?> clazz : dependencies) {
if (traversedClasses.contains(clazz)) {
throw new IllegalStateException("Found cyclic dependency - already traversed '" + clazz
+ "' (full traversal list: " + traversedClasses + ")");
}
}
}
/**
* Validates the package of a parameter type to ensure that it is part of the allowed packages.
* This ensures that we don't try to instantiate things that are beyond our reach in case some
* external parameter type has not been registered.
*
* @param clazz the class to validate
*/
private void validatePackage(Class<?> clazz) {
if (clazz.getPackage() == null) {
throw new IllegalStateException("Primitive types must be provided explicitly (or use an annotation).");
}
String packageName = clazz.getPackage().getName();
for (String allowedPackage : ALLOWED_PACKAGES) {
if (packageName.startsWith(allowedPackage)) {
return;
}
}
throw new IllegalStateException("Class " + clazz + " with package " + packageName + " is outside of the "
+ "allowed packages. It must be provided explicitly or the package must be passed to the constructor.");
}
private static void executePostConstructMethods(Object object) {
for (Method method : object.getClass().getDeclaredMethods()) {
if (method.isAnnotationPresent(PostConstruct.class)) {
if (method.getParameterTypes().length == 0 && !Modifier.isStatic(method.getModifiers())) {
try {
method.setAccessible(true);
method.invoke(object);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new UnsupportedOperationException(e);
}
} else {
throw new IllegalStateException(String.format("@PostConstruct methods may not be static or have "
+ " any parameters. Method '%s' of class '%s' is either static or has parameters",
method.getName(), object.getClass().getSimpleName()));
}
}
}
}
private static void validateInstantiable(Class<?> clazz) {
if (clazz.isEnum() || clazz.isInterface() || Modifier.isAbstract(clazz.getModifiers())) {
throw new IllegalStateException("Class " + clazz.getSimpleName() + " cannot be instantiated");
}
}
@SafeVarargs
private static <T> Injection<T> firstNotNull(Provider<? extends Injection<T>>... providers) {
for (Provider<? extends Injection<T>> provider : providers) {
Injection<T> object = provider.get();
if (object != null) {
return object;
}
}
return null;
}
}
@@ -0,0 +1,14 @@
package fr.xephi.authme.initialization;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Annotation to denote the collection of AuthMe commands.
*/
@Target({ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface BaseCommands {
}
@@ -0,0 +1,86 @@
package fr.xephi.authme.initialization;
import com.google.common.base.Preconditions;
import javax.inject.Inject;
import javax.inject.Provider;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
/**
* Functionality for constructor injection.
*/
class ConstructorInjection<T> implements Injection<T> {
private final Constructor<T> constructor;
private ConstructorInjection(Constructor<T> constructor) {
this.constructor = constructor;
}
@Override
public Class<?>[] getDependencies() {
return constructor.getParameterTypes();
}
@Override
public Class<?>[] getDependencyAnnotations() {
Annotation[][] parameterAnnotations = constructor.getParameterAnnotations();
Class<?>[] annotations = new Class<?>[parameterAnnotations.length];
for (int i = 0; i < parameterAnnotations.length; ++i) {
annotations[i] = parameterAnnotations[i].length > 0
? parameterAnnotations[i][0].annotationType()
: null;
}
return annotations;
}
@Override
public T instantiateWith(Object... values) {
validateNoNullValues(values);
try {
return constructor.newInstance(values);
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
throw new UnsupportedOperationException(e);
}
}
public static <T> Provider<ConstructorInjection<T>> provide(final Class<T> clazz) {
return new Provider<ConstructorInjection<T>>() {
@Override
public ConstructorInjection<T> get() {
Constructor<T> constructor = getInjectionConstructor(clazz);
return constructor == null ? null : new ConstructorInjection<>(constructor);
}
};
}
/**
* Gets the first found constructor annotated with {@link Inject} of the given class
* and marks it as accessible.
*
* @param clazz the class to process
* @param <T> the class' type
* @return injection constructor for the class, null if not applicable
*/
@SuppressWarnings("unchecked")
private static <T> Constructor<T> getInjectionConstructor(Class<T> clazz) {
Constructor<?>[] constructors = clazz.getDeclaredConstructors();
for (Constructor<?> constructor : constructors) {
if (constructor.isAnnotationPresent(Inject.class)) {
constructor.setAccessible(true);
return (Constructor<T>) constructor;
}
}
return null;
}
private static void validateNoNullValues(Object[] array) {
for (Object entry : array) {
Preconditions.checkNotNull(entry);
}
}
}
@@ -0,0 +1,14 @@
package fr.xephi.authme.initialization;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Annotation for specifying the plugin's data folder.
*/
@Target({ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface DataFolder {
}
@@ -0,0 +1,127 @@
package fr.xephi.authme.initialization;
import com.google.common.base.Preconditions;
import javax.inject.Inject;
import javax.inject.Provider;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* Functionality for field injection.
*/
class FieldInjection<T> implements Injection<T> {
private final Field[] fields;
private final Constructor<T> defaultConstructor;
private FieldInjection(Constructor<T> defaultConstructor, Collection<Field> fields) {
this.fields = fields.toArray(new Field[fields.size()]);
this.defaultConstructor = defaultConstructor;
}
@Override
public Class<?>[] getDependencies() {
Class<?>[] types = new Class<?>[fields.length];
for (int i = 0; i < fields.length; ++i) {
types[i] = fields[i].getType();
}
return types;
}
@Override
public Class<?>[] getDependencyAnnotations() {
Class<?>[] annotations = new Class<?>[fields.length];
for (int i = 0; i < fields.length; ++i) {
annotations[i] = getFirstNonInjectAnnotation(fields[i]);
}
return annotations;
}
@Override
public T instantiateWith(Object... values) {
Preconditions.checkArgument(values.length == fields.length,
"The number of values must be equal to the number of fields");
T instance;
try {
instance = defaultConstructor.newInstance();
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
throw new UnsupportedOperationException(e);
}
for (int i = 0; i < fields.length; ++i) {
try {
Preconditions.checkNotNull(values[i]);
fields[i].set(instance, values[i]);
} catch (IllegalAccessException e) {
throw new UnsupportedOperationException(e);
}
}
return instance;
}
/**
* Returns a provider for a {@code FieldInjection<T>} instance, i.e. a provides an object
* with which field injection can be performed on the given class if applicable. The provided
* value is {@code null} if field injection cannot be applied to the class.
*
* @param clazz the class to provide field injection for
* @param <T> the class' type
* @return field injection provider for the given class
*/
public static <T> Provider<FieldInjection<T>> provide(final Class<T> clazz) {
return new Provider<FieldInjection<T>>() {
@Override
public FieldInjection<T> get() {
Constructor<T> constructor = getDefaultConstructor(clazz);
if (constructor == null) {
return null;
}
List<Field> fields = getInjectionFields(clazz);
return fields == null ? null : new FieldInjection<>(constructor, fields);
}
};
}
private static List<Field> getInjectionFields(Class<?> clazz) {
List<Field> fields = new ArrayList<>();
for (Field field : clazz.getDeclaredFields()) {
if (field.isAnnotationPresent(Inject.class)) {
if (Modifier.isStatic(field.getModifiers())) {
throw new IllegalStateException(String.format("Field '%s' in class '%s' is static but "
+ "annotated with @Inject", field.getName(), clazz.getSimpleName()));
}
field.setAccessible(true);
fields.add(field);
}
}
return fields;
}
private static Class<?> getFirstNonInjectAnnotation(Field field) {
for (Annotation annotation : field.getAnnotations()) {
if (annotation.annotationType() != Inject.class) {
return annotation.annotationType();
}
}
return null;
}
private static <T> Constructor<T> getDefaultConstructor(Class<T> clazz) {
try {
Constructor<?> defaultConstructor = clazz.getDeclaredConstructor();
defaultConstructor.setAccessible(true);
return (Constructor<T>) defaultConstructor;
} catch (NoSuchMethodException ignore) {
// no default constructor available
}
return null;
}
}
@@ -0,0 +1,36 @@
package fr.xephi.authme.initialization;
/**
* Common interface for all injection methods.
*
* @param <T> the type of the concerned object
*/
interface Injection<T> {
/**
* Returns the dependencies that must be provided to instantiate the given item.
*
* @return list of dependencies
* @see #instantiateWith
*/
Class<?>[] getDependencies();
/**
* Returns the annotation on each dependency if available. The indices of this
* array correspond to the ones of {@link #getDependencies()}. If no annotation
* is available, {@code null} is stored. If multiple annotations are present, only
* one is stored (no guarantee on which one).
*
* @return annotation for each dependency
*/
Class<?>[] getDependencyAnnotations();
/**
* Creates a new instance with the given values as dependencies. The given values
* must correspond to {@link #getDependencies()} in size, order and type.
*
* @param values the values to set for the dependencies
* @return resulting object
*/
T instantiateWith(Object... values);
}
@@ -1,5 +1,7 @@
package fr.xephi.authme;
package fr.xephi.authme.initialization;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.settings.NewSetting;
import fr.xephi.authme.settings.properties.DatabaseSettings;
import fr.xephi.authme.settings.properties.PluginSettings;
@@ -18,6 +18,7 @@ import fr.xephi.authme.permission.PlayerStatePermission;
import fr.xephi.authme.process.Management;
import fr.xephi.authme.settings.NewSetting;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.SpawnLoader;
import fr.xephi.authme.settings.properties.HooksSettings;
import fr.xephi.authme.settings.properties.ProtectionSettings;
import fr.xephi.authme.settings.properties.RegistrationSettings;
@@ -54,6 +55,7 @@ import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.event.player.PlayerShearEntityEvent;
import javax.inject.Inject;
import java.util.concurrent.ConcurrentHashMap;
import static fr.xephi.authme.listener.ListenerService.shouldCancelEvent;
@@ -68,27 +70,24 @@ public class AuthMePlayerListener implements Listener {
public static final ConcurrentHashMap<String, String> joinMessage = new ConcurrentHashMap<>();
public static final ConcurrentHashMap<String, Boolean> causeByAuthMe = new ConcurrentHashMap<>();
private final AuthMe plugin;
private final NewSetting settings;
private final Messages m;
private final DataSource dataSource;
private final AntiBot antiBot;
private final Management management;
private final BukkitService bukkitService;
private final ValidationService validationService;
public AuthMePlayerListener(AuthMe plugin, NewSetting settings, Messages messages, DataSource dataSource,
AntiBot antiBot, Management management, BukkitService bukkitService,
ValidationService validationService) {
this.plugin = plugin;
this.settings = settings;
this.m = messages;
this.dataSource = dataSource;
this.antiBot = antiBot;
this.management = management;
this.bukkitService = bukkitService;
this.validationService = validationService;
}
@Inject
private AuthMe plugin;
@Inject
private NewSetting settings;
@Inject
private Messages m;
@Inject
private DataSource dataSource;
@Inject
private AntiBot antiBot;
@Inject
private Management management;
@Inject
private BukkitService bukkitService;
@Inject
private SpawnLoader spawnLoader;
@Inject
private ValidationService validationService;
private void handleChat(AsyncPlayerChatEvent event) {
if (settings.getProperty(RestrictionSettings.ALLOW_CHAT)) {
@@ -205,7 +204,7 @@ public class AuthMePlayerListener implements Listener {
return;
}
Location spawn = plugin.getSpawnLocation(player);
Location spawn = spawnLoader.getSpawnLocation(player);
if (spawn != null && spawn.getWorld() != null) {
if (!player.getWorld().equals(spawn.getWorld())) {
player.teleport(spawn);
@@ -513,7 +512,7 @@ public class AuthMePlayerListener implements Listener {
Player player = event.getPlayer();
String name = player.getName().toLowerCase();
Location spawn = plugin.getSpawnLocation(player);
Location spawn = spawnLoader.getSpawnLocation(player);
if (Settings.isSaveQuitLocationEnabled && dataSource.isAuthAvailable(name)) {
PlayerAuth auth = PlayerAuth.builder()
.name(name)
@@ -7,16 +7,17 @@ import org.spigotmc.event.player.PlayerSpawnLocationEvent;
import fr.xephi.authme.AuthMe;
import javax.inject.Inject;
/**
* Listener of player events for events introduced in Minecraft 1.9.
*/
public class AuthMePlayerListener19 implements Listener {
private final AuthMe plugin;
@Inject
private AuthMe plugin;
public AuthMePlayerListener19(AuthMe plugin) {
this.plugin = plugin;
}
public AuthMePlayerListener19() { }
@EventHandler(priority = EventPriority.LOWEST)
public void onPlayerSpawn(PlayerSpawnLocationEvent event) {
@@ -16,26 +16,24 @@ import org.bukkit.event.server.PluginDisableEvent;
import org.bukkit.event.server.PluginEnableEvent;
import org.bukkit.event.server.ServerListPingEvent;
import javax.inject.Inject;
/**
*/
public class AuthMeServerListener implements Listener {
private final AuthMe plugin;
private final Messages messages;
private final NewSetting settings;
private final PluginHooks pluginHooks;
private final SpawnLoader spawnLoader;
private final ValidationService validationService;
public AuthMeServerListener(AuthMe plugin, Messages messages, NewSetting settings, PluginHooks pluginHooks,
SpawnLoader spawnLoader, ValidationService validationService) {
this.plugin = plugin;
this.messages = messages;
this.settings = settings;
this.pluginHooks = pluginHooks;
this.spawnLoader = spawnLoader;
this.validationService = validationService;
}
@Inject
private AuthMe plugin;
@Inject
private Messages messages;
@Inject
private NewSetting settings;
@Inject
private PluginHooks pluginHooks;
@Inject
private SpawnLoader spawnLoader;
@Inject
private ValidationService validationService;
@EventHandler(priority = EventPriority.HIGHEST)
public void onServerPing(ServerListPingEvent event) {
@@ -11,8 +11,11 @@ import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.cache.auth.PlayerCache;
import javax.inject.Inject;
public class AuthMeTabCompletePacketAdapter extends PacketAdapter {
@Inject
public AuthMeTabCompletePacketAdapter(AuthMe plugin) {
super(plugin, ListenerPriority.NORMAL, PacketType.Play.Client.TAB_COMPLETE);
}
@@ -14,14 +14,13 @@ import com.comphenix.protocol.wrappers.EnumWrappers.PlayerInfoAction;
import com.comphenix.protocol.wrappers.PlayerInfoData;
import com.comphenix.protocol.wrappers.WrappedChatComponent;
import com.comphenix.protocol.wrappers.WrappedGameProfile;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.util.BukkitService;
import org.bukkit.entity.Player;
import javax.inject.Inject;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.logging.Level;
@@ -30,6 +29,7 @@ public class AuthMeTablistPacketAdapter extends PacketAdapter {
private final BukkitService bukkitService;
@Inject
public AuthMeTablistPacketAdapter(AuthMe plugin, BukkitService bukkitService) {
super(plugin, ListenerPriority.NORMAL, PacketType.Play.Server.PLAYER_INFO);
this.bukkitService = bukkitService;
@@ -1,6 +1,9 @@
package fr.xephi.authme;
package fr.xephi.authme.mail;
import java.awt.*;
import java.awt.Color;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
/**
@@ -2,7 +2,6 @@ package fr.xephi.authme.mail;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.ImageGenerator;
import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.settings.NewSetting;
import fr.xephi.authme.settings.properties.EmailSettings;
@@ -2,6 +2,7 @@ package fr.xephi.authme.permission;
import de.bananaco.bpermissions.api.ApiLayer;
import de.bananaco.bpermissions.api.CalculableType;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.command.CommandDescription;
import fr.xephi.authme.util.CollectionUtils;
import net.milkbowl.vault.permission.Permission;
@@ -20,11 +21,12 @@ import org.tyrannyofheaven.bukkit.zPermissions.ZPermissionsService;
import ru.tehkode.permissions.PermissionUser;
import ru.tehkode.permissions.bukkit.PermissionsEx;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
/**
* <p>
@@ -48,10 +50,7 @@ public class PermissionsManager implements PermissionsService {
* Server instance.
*/
private final Server server;
/**
* Logger instance.
*/
private Logger log;
private final PluginManager pluginManager;
/**
* Type of permissions system that is currently used.
* Null if no permissions system is hooked and/or used.
@@ -70,11 +69,11 @@ public class PermissionsManager implements PermissionsService {
* Constructor.
*
* @param server Server instance
* @param log Logger
*/
public PermissionsManager(Server server, Logger log) {
@Inject
public PermissionsManager(Server server, PluginManager pluginManager) {
this.server = server;
this.log = log;
this.pluginManager = pluginManager;
}
/**
@@ -100,39 +99,37 @@ public class PermissionsManager implements PermissionsService {
*
* @return The detected permissions system.
*/
@PostConstruct
public PermissionsSystemType setup() {
// Force-unhook from current hooked permissions systems
unhook();
// Define the plugin manager
final PluginManager pluginManager = this.server.getPluginManager();
// Reset used permissions system type flag
permsType = null;
// Loop through all the available permissions system types
for(PermissionsSystemType type : PermissionsSystemType.values()) {
for (PermissionsSystemType type : PermissionsSystemType.values()) {
// Try to find and hook the current plugin if available, print an error if failed
try {
// Try to find the plugin for the current permissions system
Plugin plugin = pluginManager.getPlugin(type.getPluginName());
// Make sure a plugin with this name was found
if(plugin == null)
if (plugin == null)
continue;
// Make sure the plugin is enabled before hooking
if(!plugin.isEnabled()) {
this.log.info("Not hooking into " + type.getName() + " because it's disabled!");
if (!plugin.isEnabled()) {
ConsoleLogger.info("Not hooking into " + type.getName() + " because it's disabled!");
continue;
}
// Use the proper method to hook this plugin
switch(type) {
switch (type) {
case PERMISSIONS_EX:
// Get the permissions manager for PermissionsEx and make sure it isn't null
if(PermissionsEx.getPermissionManager() == null) {
this.log.info("Failed to hook into " + type.getName() + "!");
if (PermissionsEx.getPermissionManager() == null) {
ConsoleLogger.info("Failed to hook into " + type.getName() + "!");
continue;
}
@@ -146,8 +143,8 @@ public class PermissionsManager implements PermissionsService {
case Z_PERMISSIONS:
// Set the zPermissions service and make sure it's valid
zPermissionsService = Bukkit.getServicesManager().load(ZPermissionsService.class);
if(zPermissionsService == null) {
this.log.info("Failed to hook into " + type.getName() + "!");
if (zPermissionsService == null) {
ConsoleLogger.info("Failed to hook into " + type.getName() + "!");
continue;
}
@@ -157,14 +154,14 @@ public class PermissionsManager implements PermissionsService {
// Get the permissions provider service
RegisteredServiceProvider<Permission> permissionProvider = this.server.getServicesManager().getRegistration(Permission.class);
if (permissionProvider == null) {
this.log.info("Failed to hook into " + type.getName() + "!");
ConsoleLogger.info("Failed to hook into " + type.getName() + "!");
continue;
}
// Get the Vault provider and make sure it's valid
vaultPerms = permissionProvider.getProvider();
if(vaultPerms == null) {
this.log.info("Not using " + type.getName() + " because it's disabled!");
if (vaultPerms == null) {
ConsoleLogger.info("Not using " + type.getName() + " because it's disabled!");
continue;
}
@@ -177,19 +174,19 @@ public class PermissionsManager implements PermissionsService {
this.permsType = type;
// Show a success message
this.log.info("Hooked into " + type.getName() + "!");
ConsoleLogger.info("Hooked into " + type.getName() + "!");
// Return the used permissions system type
return type;
} catch (Exception ex) {
// An error occurred, show a warning message
this.log.info("Error while hooking into " + type.getName() + "!");
ConsoleLogger.logException("Error while hooking into " + type.getName(), ex);
}
}
// No recognized permissions system found, show a message and return
this.log.info("No supported permissions system found! Permissions are disabled!");
ConsoleLogger.info("No supported permissions system found! Permissions are disabled!");
return null;
}
@@ -201,7 +198,7 @@ public class PermissionsManager implements PermissionsService {
this.permsType = null;
// Print a status message to the console
this.log.info("Unhooked from Permissions!");
ConsoleLogger.info("Unhooked from Permissions!");
}
/**
@@ -232,7 +229,7 @@ public class PermissionsManager implements PermissionsService {
if (pluginName.equals("PermissionsEx") || pluginName.equals("PermissionsBukkit") ||
pluginName.equals("bPermissions") || pluginName.equals("GroupManager") ||
pluginName.equals("zPermissions") || pluginName.equals("Vault")) {
this.log.info(pluginName + " plugin enabled, dynamically updating permissions hooks!");
ConsoleLogger.info(pluginName + " plugin enabled, dynamically updating permissions hooks!");
setup();
}
}
@@ -251,7 +248,7 @@ public class PermissionsManager implements PermissionsService {
if (pluginName.equals("PermissionsEx") || pluginName.equals("PermissionsBukkit") ||
pluginName.equals("bPermissions") || pluginName.equals("GroupManager") ||
pluginName.equals("zPermissions") || pluginName.equals("Vault")) {
this.log.info(pluginName + " plugin disabled, updating hooks!");
ConsoleLogger.info(pluginName + " plugin disabled, updating hooks!");
setup();
}
}
@@ -3,6 +3,7 @@ package fr.xephi.authme.process;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.hooks.PluginHooks;
import fr.xephi.authme.process.email.AsyncAddEmail;
import fr.xephi.authme.process.email.AsyncChangeEmail;
import fr.xephi.authme.process.join.AsynchronousJoin;
@@ -14,23 +15,26 @@ import fr.xephi.authme.process.unregister.AsynchronousUnregister;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitScheduler;
import javax.inject.Inject;
/**
*/
public class Management {
private final AuthMe plugin;
private final BukkitScheduler sched;
private final ProcessService processService;
private final DataSource dataSource;
private final PlayerCache playerCache;
@Inject
private AuthMe plugin;
@Inject
private BukkitScheduler sched;
@Inject
private ProcessService processService;
@Inject
private DataSource dataSource;
@Inject
private PlayerCache playerCache;
@Inject
private PluginHooks pluginHooks;
public Management(AuthMe plugin, ProcessService processService, DataSource dataSource, PlayerCache playerCache) {
this.plugin = plugin;
this.sched = this.plugin.getServer().getScheduler();
this.processService = processService;
this.dataSource = dataSource;
this.playerCache = playerCache;
}
Management() { }
public void performLogin(final Player player, final String password, final boolean forceLogin) {
runTask(new AsynchronousLogin(player, password, forceLogin, plugin, dataSource, processService));
@@ -49,7 +53,7 @@ public class Management {
}
public void performJoin(final Player player) {
runTask(new AsynchronousJoin(player, plugin, dataSource, playerCache, processService));
runTask(new AsynchronousJoin(player, plugin, dataSource, playerCache, pluginHooks, processService));
}
public void performQuit(final Player player, final boolean isKick) {
@@ -17,6 +17,7 @@ import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.scheduler.BukkitTask;
import javax.inject.Inject;
import java.util.Collection;
/**
@@ -24,29 +25,24 @@ import java.util.Collection;
*/
public class ProcessService {
private final NewSetting settings;
private final Messages messages;
private final AuthMe authMe;
private final DataSource dataSource;
private final PasswordSecurity passwordSecurity;
private final PluginHooks pluginHooks;
private final SpawnLoader spawnLoader;
private final ValidationService validationService;
private final BukkitService bukkitService;
public ProcessService(NewSetting settings, Messages messages, AuthMe authMe, DataSource dataSource,
PasswordSecurity passwordSecurity, PluginHooks pluginHooks, SpawnLoader spawnLoader,
ValidationService validationService, BukkitService bukkitService) {
this.settings = settings;
this.messages = messages;
this.authMe = authMe;
this.dataSource = dataSource;
this.passwordSecurity = passwordSecurity;
this.pluginHooks = pluginHooks;
this.spawnLoader = spawnLoader;
this.validationService = validationService;
this.bukkitService = bukkitService;
}
@Inject
private NewSetting settings;
@Inject
private Messages messages;
@Inject
private AuthMe authMe;
@Inject
private DataSource dataSource;
@Inject
private PasswordSecurity passwordSecurity;
@Inject
private PluginHooks pluginHooks;
@Inject
private SpawnLoader spawnLoader;
@Inject
private ValidationService validationService;
@Inject
private BukkitService bukkitService;
/**
* Retrieve a property's value.
@@ -9,6 +9,7 @@ import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.events.FirstSpawnTeleportEvent;
import fr.xephi.authme.events.ProtectInventoryEvent;
import fr.xephi.authme.events.SpawnTeleportEvent;
import fr.xephi.authme.hooks.PluginHooks;
import fr.xephi.authme.listener.AuthMePlayerListener;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.permission.PlayerStatePermission;
@@ -45,18 +46,20 @@ public class AsynchronousJoin implements Process {
private final String name;
private final ProcessService service;
private final PlayerCache playerCache;
private final PluginHooks pluginHooks;
private final boolean disableCollisions = MethodUtils
.getAccessibleMethod(LivingEntity.class, "setCollidable", new Class[]{}) != null;
public AsynchronousJoin(Player player, AuthMe plugin, DataSource database, PlayerCache playerCache,
ProcessService service) {
PluginHooks pluginHooks, ProcessService service) {
this.player = player;
this.plugin = plugin;
this.database = database;
this.name = player.getName().toLowerCase();
this.service = service;
this.playerCache = playerCache;
this.pluginHooks = pluginHooks;
}
@Override
@@ -190,7 +193,7 @@ public class AsynchronousJoin implements Process {
player.setWalkSpeed(0.0f);
}
player.setNoDamageTicks(registrationTimeout);
if (plugin.getPluginHooks().isEssentialsAvailable() && service.getProperty(HooksSettings.USE_ESSENTIALS_MOTD)) {
if (pluginHooks.isEssentialsAvailable() && service.getProperty(HooksSettings.USE_ESSENTIALS_MOTD)) {
player.performCommand("motd");
}
if (service.getProperty(RegistrationSettings.APPLY_BLIND_EFFECT)) {
@@ -2,32 +2,43 @@ package fr.xephi.authme.security;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.events.PasswordEncryptionEvent;
import fr.xephi.authme.initialization.AuthMeServiceInitializer;
import fr.xephi.authme.security.crypts.EncryptionMethod;
import fr.xephi.authme.security.crypts.HashedPassword;
import fr.xephi.authme.settings.NewSetting;
import fr.xephi.authme.settings.properties.SecuritySettings;
import org.bukkit.plugin.PluginManager;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
/**
* Manager class for password-related operations.
*/
public class PasswordSecurity {
private final NewSetting settings;
@Inject
private NewSetting settings;
@Inject
private DataSource dataSource;
@Inject
private PluginManager pluginManager;
@Inject
private AuthMeServiceInitializer initializer;
private HashAlgorithm algorithm;
private boolean supportOldAlgorithm;
private final DataSource dataSource;
private final PluginManager pluginManager;
public PasswordSecurity(DataSource dataSource, NewSetting settings, PluginManager pluginManager) {
this.settings = settings;
/**
* Load or reload the configuration.
*/
@PostConstruct
public void reload() {
this.algorithm = settings.getProperty(SecuritySettings.PASSWORD_HASH);
this.supportOldAlgorithm = settings.getProperty(SecuritySettings.SUPPORT_OLD_PASSWORD_HASH);
this.dataSource = dataSource;
this.pluginManager = pluginManager;
}
/**
@@ -73,14 +84,6 @@ public class PasswordSecurity {
|| supportOldAlgorithm && compareWithAllEncryptionMethods(password, hashedPassword, playerLowerCase);
}
/**
* Reload the configuration.
*/
public void reload() {
this.algorithm = settings.getProperty(SecuritySettings.PASSWORD_HASH);
this.supportOldAlgorithm = settings.getProperty(SecuritySettings.SUPPORT_OLD_PASSWORD_HASH);
}
/**
* Compare the given hash with all available encryption methods to support
* the migration to a new encryption method. Upon a successful match, the password
@@ -95,7 +98,7 @@ public class PasswordSecurity {
private boolean compareWithAllEncryptionMethods(String password, HashedPassword hashedPassword, String playerName) {
for (HashAlgorithm algorithm : HashAlgorithm.values()) {
if (!HashAlgorithm.CUSTOM.equals(algorithm)) {
EncryptionMethod method = initializeEncryptionMethod(algorithm, settings);
EncryptionMethod method = initializeEncryptionMethod(algorithm);
if (methodMatches(method, password, hashedPassword, playerName)) {
hashPasswordForNewAlgorithm(password, playerName);
return true;
@@ -133,7 +136,7 @@ public class PasswordSecurity {
* @return The encryption method
*/
private EncryptionMethod initializeEncryptionMethodWithEvent(HashAlgorithm algorithm, String playerName) {
EncryptionMethod method = initializeEncryptionMethod(algorithm, settings);
EncryptionMethod method = initializeEncryptionMethod(algorithm);
PasswordEncryptionEvent event = new PasswordEncryptionEvent(method, playerName);
pluginManager.callEvent(event);
return event.getMethod();
@@ -143,30 +146,14 @@ public class PasswordSecurity {
* Initialize the encryption method associated with the given hash algorithm.
*
* @param algorithm The algorithm to retrieve the encryption method for
* @param settings The settings instance to pass to the constructor if required
*
* @return The associated encryption method, or null if CUSTOM / deprecated
*/
public static EncryptionMethod initializeEncryptionMethod(HashAlgorithm algorithm,
NewSetting settings) {
try {
if (HashAlgorithm.CUSTOM.equals(algorithm) || HashAlgorithm.PLAINTEXT.equals(algorithm)) {
return null;
}
Constructor<?> constructor = algorithm.getClazz().getConstructors()[0];
Class<?>[] parameters = constructor.getParameterTypes();
if (parameters.length == 0) {
return (EncryptionMethod) constructor.newInstance();
} else if (parameters.length == 1 && parameters[0] == NewSetting.class) {
return (EncryptionMethod) constructor.newInstance(settings);
} else {
throw new UnsupportedOperationException("Did not find default constructor or constructor with settings "
+ "parameter in class " + algorithm.getClazz().getSimpleName());
}
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
throw new UnsupportedOperationException("Constructor for '" + algorithm.getClazz().getSimpleName()
+ "' could not be invoked. (Is there no default constructor?)", e);
public EncryptionMethod initializeEncryptionMethod(HashAlgorithm algorithm) {
if (HashAlgorithm.CUSTOM.equals(algorithm) || HashAlgorithm.PLAINTEXT.equals(algorithm)) {
return null;
}
return initializer.newInstance(algorithm.getClazz());
}
private void hashPasswordForNewAlgorithm(String password, String playerName) {
@@ -9,13 +9,15 @@ import fr.xephi.authme.settings.NewSetting;
import fr.xephi.authme.settings.properties.HooksSettings;
import fr.xephi.authme.util.StringUtils;
import javax.inject.Inject;
@Recommendation(Usage.RECOMMENDED) // provided the salt length is >= 8
@HasSalt(value = SaltType.TEXT) // length depends on Settings.bCryptLog2Rounds
@HasSalt(value = SaltType.TEXT) // length depends on the bcryptLog2Rounds setting
public class BCRYPT implements EncryptionMethod {
private final int bCryptLog2Rounds;
@Inject
public BCRYPT(NewSetting settings) {
this.bCryptLog2Rounds = settings.getProperty(HooksSettings.BCRYPT_LOG2_ROUND);
}
@@ -8,14 +8,17 @@ import fr.xephi.authme.security.crypts.description.Usage;
import fr.xephi.authme.settings.NewSetting;
import fr.xephi.authme.settings.properties.SecuritySettings;
import javax.inject.Inject;
import static fr.xephi.authme.security.HashUtils.md5;
@Recommendation(Usage.ACCEPTABLE) // presuming that length is something sensible (>= 8)
@HasSalt(value = SaltType.TEXT) // length defined by Settings.saltLength
@HasSalt(value = SaltType.TEXT) // length defined by the doubleMd5SaltLength setting
public class SALTED2MD5 extends SeparateSaltMethod {
private final int saltLength;
@Inject
public SALTED2MD5(NewSetting settings) {
saltLength = settings.getProperty(SecuritySettings.DOUBLE_MD5_SALT_LENGTH);
}
@@ -4,6 +4,7 @@ import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.hooks.PluginHooks;
import fr.xephi.authme.initialization.DataFolder;
import fr.xephi.authme.settings.properties.RestrictionSettings;
import fr.xephi.authme.util.FileUtils;
import fr.xephi.authme.util.StringUtils;
@@ -14,6 +15,7 @@ import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import javax.inject.Inject;
import java.io.File;
import java.io.IOException;
@@ -40,7 +42,8 @@ public class SpawnLoader {
* @param settings The setting instance
* @param pluginHooks The plugin hooks instance
*/
public SpawnLoader(File pluginFolder, NewSetting settings, PluginHooks pluginHooks) {
@Inject
public SpawnLoader(@DataFolder File pluginFolder, NewSetting settings, PluginHooks pluginHooks) {
File spawnFile = new File(pluginFolder, "spawn.yml");
// TODO ljacqu 20160312: Check if resource could be copied and handle the case if not
FileUtils.copyFileFromResource(spawnFile, "spawn.yml");
@@ -7,6 +7,7 @@ import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitTask;
import javax.inject.Inject;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
@@ -28,6 +29,7 @@ public class BukkitService {
private final boolean getOnlinePlayersIsCollection;
private Method getOnlinePlayers;
@Inject
public BukkitService(AuthMe authMe) {
this.authMe = authMe;
getOnlinePlayersIsCollection = initializeOnlinePlayersIsCollectionField();
@@ -165,8 +165,9 @@ public final class Utils {
});
}
@Deprecated
public static boolean isNPC(Player player) {
return player.hasMetadata("NPC") || plugin.getPluginHooks().isNpcInCombatTagPlus(player);
return plugin.getPluginHooks().isNpc(player);
}
public static void teleportToSpawn(Player player) {
@@ -12,6 +12,7 @@ import fr.xephi.authme.settings.properties.RestrictionSettings;
import fr.xephi.authme.settings.properties.SecuritySettings;
import org.bukkit.command.CommandSender;
import javax.inject.Inject;
import java.util.Collection;
import java.util.List;
@@ -24,6 +25,7 @@ public class ValidationService {
private final DataSource dataSource;
private final PermissionsManager permissionsManager;
@Inject
public ValidationService(NewSetting settings, DataSource dataSource, PermissionsManager permissionsManager) {
this.settings = settings;
this.dataSource = dataSource;