#432 Create custom dependency injector

This commit is contained in:
ljacqu 2016-04-27 22:49:20 +02:00
parent 59d3bc95c0
commit 02079f1f5c
51 changed files with 1347 additions and 278 deletions

View File

@ -405,6 +405,13 @@
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
<!-- javax.inject API -->
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
<!-- Maxmind GeoIp API --> <!-- Maxmind GeoIp API -->
<dependency> <dependency>
<groupId>com.maxmind.geoip</groupId> <groupId>com.maxmind.geoip</groupId>

View File

@ -9,6 +9,7 @@ import fr.xephi.authme.settings.properties.ProtectionSettings;
import fr.xephi.authme.util.BukkitService; import fr.xephi.authme.util.BukkitService;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import javax.inject.Inject;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -27,6 +28,7 @@ public class AntiBot {
private final List<String> antibotPlayers = new ArrayList<>(); private final List<String> antibotPlayers = new ArrayList<>();
private AntiBotStatus antiBotStatus = AntiBotStatus.DISABLED; private AntiBotStatus antiBotStatus = AntiBotStatus.DISABLED;
@Inject
public AntiBot(NewSetting settings, Messages messages, PermissionsManager permissionsManager, public AntiBot(NewSetting settings, Messages messages, PermissionsManager permissionsManager,
BukkitService bukkitService) { BukkitService bukkitService) {
this.settings = settings; this.settings = settings;

View File

@ -7,12 +7,8 @@ import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.cache.backup.JsonCache; import fr.xephi.authme.cache.backup.JsonCache;
import fr.xephi.authme.cache.limbo.LimboCache; import fr.xephi.authme.cache.limbo.LimboCache;
import fr.xephi.authme.cache.limbo.LimboPlayer; import fr.xephi.authme.cache.limbo.LimboPlayer;
import fr.xephi.authme.command.CommandDescription;
import fr.xephi.authme.command.CommandHandler; import fr.xephi.authme.command.CommandHandler;
import fr.xephi.authme.command.CommandInitializer; 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.CacheDataSource;
import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.datasource.DataSourceType; import fr.xephi.authme.datasource.DataSourceType;
@ -21,8 +17,11 @@ import fr.xephi.authme.datasource.MySQL;
import fr.xephi.authme.datasource.SQLite; import fr.xephi.authme.datasource.SQLite;
import fr.xephi.authme.hooks.BungeeCordMessage; import fr.xephi.authme.hooks.BungeeCordMessage;
import fr.xephi.authme.hooks.PluginHooks; 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.AuthMeBlockListener;
import fr.xephi.authme.listener.AuthMeEntityListener;
import fr.xephi.authme.listener.AuthMeInventoryPacketAdapter; import fr.xephi.authme.listener.AuthMeInventoryPacketAdapter;
import fr.xephi.authme.listener.AuthMePlayerListener; import fr.xephi.authme.listener.AuthMePlayerListener;
import fr.xephi.authme.listener.AuthMePlayerListener16; import fr.xephi.authme.listener.AuthMePlayerListener16;
@ -38,7 +37,6 @@ import fr.xephi.authme.output.Messages;
import fr.xephi.authme.permission.PermissionsManager; import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.permission.PlayerStatePermission; import fr.xephi.authme.permission.PlayerStatePermission;
import fr.xephi.authme.process.Management; import fr.xephi.authme.process.Management;
import fr.xephi.authme.process.ProcessService;
import fr.xephi.authme.security.PasswordSecurity; import fr.xephi.authme.security.PasswordSecurity;
import fr.xephi.authme.security.crypts.SHA256; import fr.xephi.authme.security.crypts.SHA256;
import fr.xephi.authme.settings.NewSetting; import fr.xephi.authme.settings.NewSetting;
@ -61,7 +59,6 @@ import fr.xephi.authme.util.GeoLiteAPI;
import fr.xephi.authme.util.MigrationService; import fr.xephi.authme.util.MigrationService;
import fr.xephi.authme.util.StringUtils; import fr.xephi.authme.util.StringUtils;
import fr.xephi.authme.util.Utils; import fr.xephi.authme.util.Utils;
import fr.xephi.authme.util.ValidationService;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
@ -71,6 +68,7 @@ import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitScheduler;
import org.bukkit.scheduler.BukkitTask; import org.bukkit.scheduler.BukkitTask;
import java.io.File; import java.io.File;
@ -80,14 +78,12 @@ import java.util.Calendar;
import java.util.Collection; import java.util.Collection;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Logger; import java.util.logging.Logger;
import static fr.xephi.authme.settings.properties.EmailSettings.MAIL_ACCOUNT; 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.MAIL_PASSWORD;
import static fr.xephi.authme.settings.properties.EmailSettings.RECALL_PLAYERS; import static fr.xephi.authme.settings.properties.EmailSettings.RECALL_PLAYERS;
import static fr.xephi.authme.settings.properties.PluginSettings.HELP_HEADER;
/** /**
* The AuthMe main class. * The AuthMe main class.
@ -103,7 +99,6 @@ public class AuthMe extends JavaPlugin {
// Private Instances // Private Instances
private static AuthMe plugin; private static AuthMe plugin;
private static Server server;
/* /*
* Maps and stuff * Maps and stuff
*/ */
@ -138,7 +133,6 @@ public class AuthMe extends JavaPlugin {
private DataSource database; private DataSource database;
private PluginHooks pluginHooks; private PluginHooks pluginHooks;
private SpawnLoader spawnLoader; private SpawnLoader spawnLoader;
private AntiBot antiBot;
private boolean autoPurging; private boolean autoPurging;
private BukkitService bukkitService; private BukkitService bukkitService;
@ -215,17 +209,15 @@ public class AuthMe extends JavaPlugin {
@Override @Override
public void onEnable() { public void onEnable() {
// Set various instances // Set various instances
server = getServer();
plugin = this; plugin = this;
ConsoleLogger.setLogger(getLogger()); ConsoleLogger.setLogger(getLogger());
setPluginInfos(); setPluginInfos();
// Load settings and custom configurations, if it fails, stop the server due to security reasons. // Load settings and custom configurations, if it fails, stop the server due to security reasons.
newSettings = createNewSetting(); newSettings = createNewSetting();
if (newSettings == null) { if (newSettings == null) {
ConsoleLogger.showError("Could not load configuration. Aborting."); ConsoleLogger.showError("Could not load configuration. Aborting.");
server.shutdown(); getServer().shutdown();
return; return;
} }
ConsoleLogger.setLoggingOptions(newSettings.getProperty(SecuritySettings.USE_LOGGING), ConsoleLogger.setLoggingOptions(newSettings.getProperty(SecuritySettings.USE_LOGGING),
@ -233,7 +225,7 @@ public class AuthMe extends JavaPlugin {
// Old settings manager // Old settings manager
if (!loadSettings()) { if (!loadSettings()) {
server.shutdown(); getServer().shutdown();
setEnabled(false); setEnabled(false);
return; return;
} }
@ -249,23 +241,40 @@ public class AuthMe extends JavaPlugin {
stopOrUnload(); stopOrUnload();
return; return;
} }
bukkitService = new BukkitService(this);
pluginHooks = new PluginHooks(server.getPluginManager());
MigrationService.changePlainTextToSha256(newSettings, database, new SHA256()); MigrationService.changePlainTextToSha256(newSettings, database, new SHA256());
passwordSecurity = new PasswordSecurity(getDataSource(), newSettings, Bukkit.getPluginManager());
// Initialize spawn loader
spawnLoader = new SpawnLoader(getDataFolder(), newSettings, pluginHooks); AuthMeServiceInitializer initializer = new AuthMeServiceInitializer("fr.xephi.authme");
permsMan = initializePermissionsManager(); // Register elements of the Bukkit / JavaPlugin environment
antiBot = new AntiBot(newSettings, messages, permsMan, bukkitService); initializer.register(AuthMe.class, this);
ValidationService validationService = new ValidationService(newSettings, database, permsMan); initializer.register(Server.class, getServer());
commandHandler = initializeCommandHandler(permsMan, messages, passwordSecurity, newSettings, initializer.register(PluginManager.class, getServer().getPluginManager());
pluginHooks, spawnLoader, antiBot, validationService, bukkitService); initializer.register(BukkitScheduler.class, getServer().getScheduler());
initializer.provide(DataFolder.class, getDataFolder());
// Register elements we instantiate manually
initializer.register(newSettings);
initializer.register(messages);
initializer.register(DataSource.class, database);
initializer.provide(BaseCommands.class, CommandInitializer.buildCommands());
// Some statically injected things
initializer.register(PlayerCache.class, PlayerCache.getInstance());
initializer.register(LimboCache.class, LimboCache.getInstance());
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 // Set up Metrics
MetricsStarter.setupMetrics(plugin, newSettings); MetricsStarter.setupMetrics(this, newSettings);
// Set console filter // Set console filter
setupConsoleFilter(); setupConsoleFilter();
@ -282,22 +291,12 @@ public class AuthMe extends JavaPlugin {
// End of Hooks // End of Hooks
// Do a backup on start // 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 // Setup the inventory backup
playerBackup = new JsonCache(); 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 // Set up the BungeeCord hook
setupBungeeCordHook(newSettings); setupBungeeCordHook(newSettings);
@ -306,7 +305,7 @@ public class AuthMe extends JavaPlugin {
reloadSupportHook(); reloadSupportHook();
// Register event listeners // Register event listeners
registerEventListeners(messages, database, management, pluginHooks, spawnLoader, antiBot); registerEventListeners(initializer);
// Start Email recall task if needed // Start Email recall task if needed
scheduleRecallEmailTask(); scheduleRecallEmailTask();
@ -370,29 +369,27 @@ public class AuthMe extends JavaPlugin {
/** /**
* Register all event listeners. * Register all event listeners.
*/ */
private void registerEventListeners(Messages messages, DataSource dataSource, Management management, private void registerEventListeners(AuthMeServiceInitializer initializer) {
PluginHooks pluginHooks, SpawnLoader spawnLoader, AntiBot antiBot) {
// Get the plugin manager instance // Get the plugin manager instance
PluginManager pluginManager = server.getPluginManager(); PluginManager pluginManager = getServer().getPluginManager();
// Register event listeners // Register event listeners
pluginManager.registerEvents(new AuthMePlayerListener( pluginManager.registerEvents(initializer.get(AuthMePlayerListener.class), this);
this, newSettings, messages, dataSource, antiBot, management, bukkitService), this); pluginManager.registerEvents(initializer.get(AuthMeBlockListener.class), this);
pluginManager.registerEvents(new AuthMeBlockListener(), this); pluginManager.registerEvents(initializer.get(AuthMePlayerListener.class), this);
pluginManager.registerEvents(new AuthMeEntityListener(), this); pluginManager.registerEvents(initializer.get(AuthMeServerListener.class), this);
pluginManager.registerEvents(new AuthMeServerListener(this, messages, pluginHooks, spawnLoader), this);
// Try to register 1.6 player listeners // Try to register 1.6 player listeners
try { try {
Class.forName("org.bukkit.event.player.PlayerEditBookEvent"); Class.forName("org.bukkit.event.player.PlayerEditBookEvent");
pluginManager.registerEvents(new AuthMePlayerListener16(), this); pluginManager.registerEvents(initializer.get(AuthMePlayerListener16.class), this);
} catch (ClassNotFoundException ignore) { } catch (ClassNotFoundException ignore) {
} }
// Try to register 1.8 player listeners // Try to register 1.8 player listeners
try { try {
Class.forName("org.bukkit.event.player.PlayerInteractAtEntityEvent"); Class.forName("org.bukkit.event.player.PlayerInteractAtEntityEvent");
pluginManager.registerEvents(new AuthMePlayerListener18(), this); pluginManager.registerEvents(initializer.get(AuthMePlayerListener18.class), this);
} catch (ClassNotFoundException ignore) { } catch (ClassNotFoundException ignore) {
} }
} }
@ -426,30 +423,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. * Load the plugin's settings.
* *
@ -462,7 +435,7 @@ public class AuthMe extends JavaPlugin {
} catch (Exception e) { } catch (Exception e) {
ConsoleLogger.logException("Can't load the configuration file... Something went wrong. " ConsoleLogger.logException("Can't load the configuration file... Something went wrong. "
+ "To avoid security issues the server will shut down!", e); + "To avoid security issues the server will shut down!", e);
server.shutdown(); getServer().shutdown();
} }
return false; return false;
} }
@ -507,14 +480,15 @@ public class AuthMe extends JavaPlugin {
// Do backup on stop if enabled // Do backup on stop if enabled
if (newSettings != null) { 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() { new Thread(new Runnable() {
@Override @Override
public void run() { public void run() {
List<Integer> pendingTasks = new ArrayList<>(); List<Integer> pendingTasks = new ArrayList<>();
for (BukkitTask pendingTask : getServer().getScheduler().getPendingTasks()) { for (BukkitTask pendingTask : getServer().getScheduler().getPendingTasks()) {
if (pendingTask.getOwner().equals(plugin) && !pendingTask.isSync()) { if (pendingTask.getOwner().equals(pluginInstance) && !pendingTask.isSync()) {
pendingTasks.add(pendingTask.getTaskId()); pendingTasks.add(pendingTask.getTaskId());
} }
} }
@ -553,9 +527,9 @@ public class AuthMe extends JavaPlugin {
public void stopOrUnload() { public void stopOrUnload() {
if (Settings.isStopEnabled) { if (Settings.isStopEnabled) {
ConsoleLogger.showError("THE SERVER IS GOING TO SHUT DOWN AS DEFINED IN THE CONFIGURATION!"); ConsoleLogger.showError("THE SERVER IS GOING TO SHUT DOWN AS DEFINED IN THE CONFIGURATION!");
server.shutdown(); getServer().shutdown();
} else { } else {
server.getPluginManager().disablePlugin(AuthMe.getInstance()); getServer().getPluginManager().disablePlugin(AuthMe.getInstance());
} }
} }
@ -598,7 +572,7 @@ public class AuthMe extends JavaPlugin {
database = dataSource; database = dataSource;
if (DataSourceType.SQLITE == dataSourceType) { if (DataSourceType.SQLITE == dataSourceType) {
server.getScheduler().runTaskAsynchronously(this, new Runnable() { getServer().getScheduler().runTaskAsynchronously(this, new Runnable() {
@Override @Override
public void run() { public void run() {
int accounts = database.getAccountsRegistered(); int accounts = database.getAccountsRegistered();
@ -611,15 +585,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 // Set the console filter to remove the passwords
private void setLog4JFilter() { private void setLog4JFilter() {
Bukkit.getScheduler().scheduleSyncDelayedTask(this, new Runnable() { Bukkit.getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
@ -636,7 +601,7 @@ public class AuthMe extends JavaPlugin {
// Check the presence of the ProtocolLib plugin // Check the presence of the ProtocolLib plugin
public void checkProtocolLib() { public void checkProtocolLib() {
if (!server.getPluginManager().isPluginEnabled("ProtocolLib")) { if (!getServer().getPluginManager().isPluginEnabled("ProtocolLib")) {
if (newSettings.getProperty(RestrictionSettings.PROTECT_INVENTORY_BEFORE_LOGIN)) { if (newSettings.getProperty(RestrictionSettings.PROTECT_INVENTORY_BEFORE_LOGIN)) {
ConsoleLogger.showError("WARNING! The protectInventory feature requires ProtocolLib! Disabling it..."); ConsoleLogger.showError("WARNING! The protectInventory feature requires ProtocolLib! Disabling it...");
Settings.protectInventoryBeforeLogInEnabled = false; Settings.protectInventoryBeforeLogInEnabled = false;
@ -671,7 +636,7 @@ public class AuthMe extends JavaPlugin {
// Save Player Data // Save Player Data
private void savePlayer(Player player) { private void savePlayer(Player player) {
if (Utils.isNPC(player) || Utils.isUnrestricted(player)) { if (safeIsNpc(player) || Utils.isUnrestricted(player)) {
return; return;
} }
String name = player.getName().toLowerCase(); String name = player.getName().toLowerCase();
@ -699,6 +664,10 @@ public class AuthMe extends JavaPlugin {
PlayerCache.getInstance().removePlayer(name); 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 // Select the player to kick when a vip player joins the server when full
public Player generateKickPlayer(Collection<? extends Player> collection) { public Player generateKickPlayer(Collection<? extends Player> collection) {
for (Player player : collection) { for (Player player : collection) {
@ -715,7 +684,7 @@ public class AuthMe extends JavaPlugin {
return; return;
} }
autoPurging = true; autoPurging = true;
server.getScheduler().runTaskAsynchronously(this, new Runnable() { getServer().getScheduler().runTaskAsynchronously(this, new Runnable() {
@Override @Override
public void run() { public void run() {
ConsoleLogger.info("AutoPurging the Database..."); ConsoleLogger.info("AutoPurging the Database...");
@ -772,6 +741,7 @@ public class AuthMe extends JavaPlugin {
public String replaceAllInfo(String message, Player player) { public String replaceAllInfo(String message, Player player) {
String playersOnline = Integer.toString(bukkitService.getOnlinePlayers().size()); String playersOnline = Integer.toString(bukkitService.getOnlinePlayers().size());
String ipAddress = Utils.getPlayerIp(player); String ipAddress = Utils.getPlayerIp(player);
Server server = getServer();
return message return message
.replace("&", "\u00a7") .replace("&", "\u00a7")
.replace("{PLAYER}", player.getName()) .replace("{PLAYER}", player.getName())

View File

@ -2,32 +2,37 @@ package fr.xephi.authme;
import fr.xephi.authme.hooks.PluginHooks; import fr.xephi.authme.hooks.PluginHooks;
import fr.xephi.authme.permission.PermissionsManager; import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.settings.NewSetting;
import fr.xephi.authme.settings.properties.PurgeSettings; import fr.xephi.authme.settings.properties.PurgeSettings;
import fr.xephi.authme.util.BukkitService; import fr.xephi.authme.util.BukkitService;
import fr.xephi.authme.util.Utils; import fr.xephi.authme.util.Utils;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.bukkit.Server;
import javax.inject.Inject;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import static fr.xephi.authme.util.StringUtils.makePath;
/** /**
*/ */
public class DataManager { public class DataManager {
private final AuthMe plugin; @Inject
private final PluginHooks pluginHooks; private Server server;
private final BukkitService bukkitService; @Inject
private PluginHooks pluginHooks;
@Inject
private BukkitService bukkitService;
@Inject
private NewSetting settings;
@Inject
private PermissionsManager permissionsManager;
/* DataManager() { }
* Constructor.
*/
public DataManager(AuthMe plugin, PluginHooks pluginHooks, BukkitService bukkitService) {
this.plugin = plugin;
this.pluginHooks = pluginHooks;
this.bukkitService = bukkitService;
}
private List<OfflinePlayer> getOfflinePlayers(List<String> names) { private List<OfflinePlayer> getOfflinePlayers(List<String> names) {
List<OfflinePlayer> result = new ArrayList<>(); List<OfflinePlayer> result = new ArrayList<>();
@ -98,9 +103,8 @@ public class DataManager {
public synchronized void purgeDat(List<String> cleared) { public synchronized void purgeDat(List<String> cleared) {
int i = 0; int i = 0;
File dataFolder = new File(plugin.getServer().getWorldContainer() File dataFolder = new File(server.getWorldContainer(),
+ File.separator + plugin.getSettings().getProperty(PurgeSettings.DEFAULT_WORLD) makePath(settings.getProperty(PurgeSettings.DEFAULT_WORLD), "players"));
+ File.separator + "players");
List<OfflinePlayer> offlinePlayers = getOfflinePlayers(cleared); List<OfflinePlayer> offlinePlayers = getOfflinePlayers(cleared);
for (OfflinePlayer player : offlinePlayers) { for (OfflinePlayer player : offlinePlayers) {
File playerFile = new File(dataFolder, Utils.getUUIDorName(player) + ".dat"); 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: What is this method for? Is it correct?
// TODO: Make it work with OfflinePlayers group data. // TODO: Make it work with OfflinePlayers group data.
public synchronized void purgePermissions(List<String> cleared) { 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) { for (String name : cleared) {
permsMan.removeAllGroups(bukkitService.getPlayerExact(name)); permissionsManager.removeAllGroups(bukkitService.getPlayerExact(name));
} }
ConsoleLogger.info("AutoPurge: Removed permissions from " + cleared.size() + " player(s)."); ConsoleLogger.info("AutoPurge: Removed permissions from " + cleared.size() + " player(s).");
} }

View File

@ -3,6 +3,8 @@ package fr.xephi.authme.api;
import fr.xephi.authme.AuthMe; import fr.xephi.authme.AuthMe;
import fr.xephi.authme.cache.auth.PlayerAuth; import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.cache.auth.PlayerCache; import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.process.Management;
import fr.xephi.authme.security.PasswordSecurity; import fr.xephi.authme.security.PasswordSecurity;
import fr.xephi.authme.security.crypts.HashedPassword; import fr.xephi.authme.security.crypts.HashedPassword;
import fr.xephi.authme.util.Utils; import fr.xephi.authme.util.Utils;
@ -12,6 +14,8 @@ import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import javax.inject.Inject;
/** /**
* Deprecated API of AuthMe. Please use {@link NewAPI} instead. * 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 final String newline = System.getProperty("line.separator");
public static AuthMe instance; public static AuthMe instance;
private static DataSource dataSource;
private static PasswordSecurity passwordSecurity; private static PasswordSecurity passwordSecurity;
private static Management management;
/** /**
* Constructor for the deprecated API. * Constructor for the deprecated API.
@ -28,9 +34,12 @@ public class API {
* @param instance AuthMe * @param instance AuthMe
*/ */
@Deprecated @Deprecated
public API(AuthMe instance) { @Inject
API(AuthMe instance, DataSource dataSource, PasswordSecurity passwordSecurity, Management management) {
API.instance = instance; API.instance = instance;
passwordSecurity = instance.getPasswordSecurity(); API.dataSource = dataSource;
API.passwordSecurity = passwordSecurity;
API.management = management;
} }
/** /**
@ -109,7 +118,7 @@ public class API {
@Deprecated @Deprecated
public static boolean isRegistered(String playerName) { public static boolean isRegistered(String playerName) {
String player = playerName.toLowerCase(); String player = playerName.toLowerCase();
return instance.getDataSource().isAuthAvailable(player); return dataSource.isAuthAvailable(player);
} }
/** /**
@ -144,7 +153,7 @@ public class API {
.lastLogin(0) .lastLogin(0)
.realName(playerName) .realName(playerName)
.build(); .build();
return instance.getDataSource().saveAuth(auth); return dataSource.saveAuth(auth);
} }
/** /**
@ -154,7 +163,7 @@ public class API {
*/ */
@Deprecated @Deprecated
public static void forceLogin(Player player) { public static void forceLogin(Player player) {
instance.getManagement().performLogin(player, "dontneed", true); management.performLogin(player, "dontneed", true);
} }
@Deprecated @Deprecated

View File

@ -12,6 +12,8 @@ import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.security.crypts.HashedPassword; import fr.xephi.authme.security.crypts.HashedPassword;
import fr.xephi.authme.util.Utils; import fr.xephi.authme.util.Utils;
import javax.inject.Inject;
/** /**
* The current API of AuthMe. Recommended method of retrieving the API object: * The current API of AuthMe. Recommended method of retrieving the API object:
* <code> * <code>
@ -28,6 +30,7 @@ public class NewAPI {
* *
* @param plugin The AuthMe plugin instance * @param plugin The AuthMe plugin instance
*/ */
@Inject
public NewAPI(AuthMe plugin) { public NewAPI(AuthMe plugin) {
this.plugin = plugin; this.plugin = plugin;
} }

View File

@ -1,14 +1,14 @@
package fr.xephi.authme.command; package fr.xephi.authme.command;
import java.util.ArrayList;
import java.util.List;
import fr.xephi.authme.AuthMe; import fr.xephi.authme.AuthMe;
import fr.xephi.authme.command.help.HelpProvider; import fr.xephi.authme.command.help.HelpProvider;
import fr.xephi.authme.util.StringUtils;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender; 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} * 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 * @param commandService The CommandService instance
*/ */
@Inject
public CommandHandler(CommandService commandService) { public CommandHandler(CommandService commandService) {
this.commandService = commandService; this.commandService = commandService;
} }

View File

@ -1,11 +1,13 @@
package fr.xephi.authme.command; package fr.xephi.authme.command;
import fr.xephi.authme.command.executable.HelpCommand; import fr.xephi.authme.command.executable.HelpCommand;
import fr.xephi.authme.initialization.BaseCommands;
import fr.xephi.authme.permission.PermissionsManager; import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.util.CollectionUtils; import fr.xephi.authme.util.CollectionUtils;
import fr.xephi.authme.util.StringUtils; import fr.xephi.authme.util.StringUtils;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import javax.inject.Inject;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
@ -28,7 +30,8 @@ public class CommandMapper {
private final Set<CommandDescription> baseCommands; private final Set<CommandDescription> baseCommands;
private final PermissionsManager permissionsManager; private final PermissionsManager permissionsManager;
public CommandMapper(Set<CommandDescription> baseCommands, PermissionsManager permissionsManager) { @Inject
public CommandMapper(@BaseCommands Set<CommandDescription> baseCommands, PermissionsManager permissionsManager) {
this.baseCommands = baseCommands; this.baseCommands = baseCommands;
this.permissionsManager = permissionsManager; this.permissionsManager = permissionsManager;
} }

View File

@ -19,6 +19,7 @@ import fr.xephi.authme.util.ValidationService;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import javax.inject.Inject;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
@ -28,39 +29,30 @@ import java.util.List;
*/ */
public class CommandService { public class CommandService {
private final AuthMe authMe; @Inject
private final Messages messages; private AuthMe authMe;
private final HelpProvider helpProvider; @Inject
private final CommandMapper commandMapper; private Messages messages;
private final PasswordSecurity passwordSecurity; @Inject
private final PermissionsManager permissionsManager; private HelpProvider helpProvider;
private final NewSetting settings; @Inject
private final PluginHooks pluginHooks; private CommandMapper commandMapper;
private final SpawnLoader spawnLoader; @Inject
private final AntiBot antiBot; private PasswordSecurity passwordSecurity;
private final ValidationService validationService; @Inject
private final BukkitService bukkitService; private PermissionsManager permissionsManager;
@Inject
/* private NewSetting settings;
* Constructor. @Inject
*/ private PluginHooks pluginHooks;
public CommandService(AuthMe authMe, CommandMapper commandMapper, HelpProvider helpProvider, Messages messages, @Inject
PasswordSecurity passwordSecurity, PermissionsManager permissionsManager, NewSetting settings, private SpawnLoader spawnLoader;
PluginHooks pluginHooks, SpawnLoader spawnLoader, AntiBot antiBot, @Inject
ValidationService validationService, BukkitService bukkitService) { private AntiBot antiBot;
this.authMe = authMe; @Inject
this.messages = messages; private ValidationService validationService;
this.helpProvider = helpProvider; @Inject
this.commandMapper = commandMapper; private BukkitService bukkitService;
this.passwordSecurity = passwordSecurity;
this.permissionsManager = permissionsManager;
this.settings = settings;
this.pluginHooks = pluginHooks;
this.spawnLoader = spawnLoader;
this.antiBot = antiBot;
this.validationService = validationService;
this.bukkitService = bukkitService;
}
/** /**
* Send a message to a player. * Send a message to a player.

View File

@ -10,10 +10,13 @@ import fr.xephi.authme.command.FoundCommandResult;
import fr.xephi.authme.permission.DefaultPermission; import fr.xephi.authme.permission.DefaultPermission;
import fr.xephi.authme.permission.PermissionNode; import fr.xephi.authme.permission.PermissionNode;
import fr.xephi.authme.permission.PermissionsManager; 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 fr.xephi.authme.util.CollectionUtils;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import javax.inject.Inject;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -45,9 +48,10 @@ public class HelpProvider {
private final PermissionsManager permissionsManager; private final PermissionsManager permissionsManager;
private final String helpHeader; private final String helpHeader;
public HelpProvider(PermissionsManager permissionsManager, String helpHeader) { @Inject
public HelpProvider(PermissionsManager permissionsManager, NewSetting settings) {
this.permissionsManager = permissionsManager; this.permissionsManager = permissionsManager;
this.helpHeader = helpHeader; this.helpHeader = settings.getProperty(PluginSettings.HELP_HEADER);
} }
public List<String> printHelp(CommandSender sender, FoundCommandResult result, int options) { public List<String> printHelp(CommandSender sender, FoundCommandResult result, int options) {

View File

@ -11,6 +11,7 @@ import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.PluginManager;
import javax.inject.Inject;
import java.io.File; import java.io.File;
/** /**
@ -28,6 +29,7 @@ public class PluginHooks {
* *
* @param pluginManager The server's plugin manager * @param pluginManager The server's plugin manager
*/ */
@Inject
public PluginHooks(PluginManager pluginManager) { public PluginHooks(PluginManager pluginManager) {
this.pluginManager = pluginManager; this.pluginManager = pluginManager;
tryHookToCombatPlus(); tryHookToCombatPlus();
@ -75,13 +77,23 @@ public class PluginHooks {
return null; 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. * Query the CombatTagPlus plugin whether the given player is an NPC.
* *
* @param player The player to verify * @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 * @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); return combatTagPlus != null && combatTagPlus.getNpcPlayerHelper().isNpc(player);
} }

View File

@ -0,0 +1,286 @@
package fr.xephi.authme.initialization;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
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.lang.reflect.Type;
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<>();
}
/**
* 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<?>>());
}
/**
* Registers an instantiation by its type.
*
* @param object the object to register
* @throws IllegalStateException if an object of the same type has already been registered
*/
public void register(Object object) {
if (object instanceof Type) {
throw new IllegalStateException("You tried to register a Type object: '" + object
+ "'. This likely indicates an error. Please use register(Class<T>, T) if really desired.");
}
storeObject(object);
}
/**
* 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);
}
/**
* 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 getObject(clazz);
}
// First time we come across clazz, need to instantiate it. Add the clazz to the list of traversed
// classes in a new list, so each path we need to take has its own Set.
validatePackage(clazz);
validateInstantiable(clazz);
traversedClasses = new HashSet<>(traversedClasses);
traversedClasses.add(clazz);
System.out.println(Strings.repeat(" ", traversedClasses.size() * 2) + "- Instantiating " + clazz);
return instantiate(clazz, traversedClasses);
}
/**
* 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);
storeObject(object);
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;
}
/**
* Internal method to retrieve an object from the objects map for <b>non-annotation classes</b>.
* In such cases, the type of the entry always corresponds to the key, i.e. the entry of key
* {@code Class<T>} is guaranteed to be of type {@code T}.
* <p>
* To retrieve values identified with an annotation, use {@code objects.get(clazz)} directly.
* We do not know or control the type of the value of keys of annotation classes.
*
* @param clazz the class to retrieve the implementation of
* @param <T> the type
* @return the implementation
*/
private <T> T getObject(Class<T> clazz) {
Object o = objects.get(clazz);
if (o == null) {
throw new NullPointerException("No instance of " + clazz + " available");
}
return clazz.cast(o);
}
/**
* 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.getParameterCount() == 0) {
try {
method.setAccessible(true);
method.invoke(object);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new UnsupportedOperationException(e);
}
} else {
throw new IllegalStateException("@PostConstruct methods must have an empty parameter list. " +
"Found parameters in " + method + " belonging to " + object.getClass());
}
}
}
}
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;
}
}

View File

@ -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)
@Retention(RetentionPolicy.RUNTIME)
public @interface BaseCommands {
}

View File

@ -0,0 +1,77 @@
package fr.xephi.authme.initialization;
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) {
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
*/
@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;
}
}

View File

@ -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)
@Retention(RetentionPolicy.RUNTIME)
public @interface DataFolder {
}

View File

@ -0,0 +1,112 @@
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.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 {
fields[i].set(instance, values[i]);
} catch (IllegalAccessException e) {
throw new UnsupportedOperationException(e);
}
}
return instance;
}
private static Class<?> getFirstNonInjectAnnotation(Field field) {
for (Annotation annotation : field.getAnnotations()) {
if (annotation.annotationType() != Inject.class) {
return annotation.annotationType();
}
}
return null;
}
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)) {
field.setAccessible(true);
fields.add(field);
}
}
return fields;
}
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;
}
}

View File

@ -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);
}

View File

@ -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.NewSetting;
import fr.xephi.authme.settings.properties.DatabaseSettings; import fr.xephi.authme.settings.properties.DatabaseSettings;
import fr.xephi.authme.settings.properties.PluginSettings; import fr.xephi.authme.settings.properties.PluginSettings;

View File

@ -18,6 +18,7 @@ import fr.xephi.authme.permission.PlayerStatePermission;
import fr.xephi.authme.process.Management; import fr.xephi.authme.process.Management;
import fr.xephi.authme.settings.NewSetting; import fr.xephi.authme.settings.NewSetting;
import fr.xephi.authme.settings.Settings; 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.HooksSettings;
import fr.xephi.authme.settings.properties.RegistrationSettings; import fr.xephi.authme.settings.properties.RegistrationSettings;
import fr.xephi.authme.settings.properties.RestrictionSettings; import fr.xephi.authme.settings.properties.RestrictionSettings;
@ -53,6 +54,7 @@ import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerRespawnEvent; import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.event.player.PlayerShearEntityEvent; import org.bukkit.event.player.PlayerShearEntityEvent;
import javax.inject.Inject;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import static fr.xephi.authme.listener.ListenerService.shouldCancelEvent; import static fr.xephi.authme.listener.ListenerService.shouldCancelEvent;
@ -67,24 +69,22 @@ public class AuthMePlayerListener implements Listener {
public static final ConcurrentHashMap<String, String> joinMessage = new ConcurrentHashMap<>(); public static final ConcurrentHashMap<String, String> joinMessage = new ConcurrentHashMap<>();
public static final ConcurrentHashMap<String, Boolean> causeByAuthMe = new ConcurrentHashMap<>(); public static final ConcurrentHashMap<String, Boolean> causeByAuthMe = new ConcurrentHashMap<>();
private final AuthMe plugin; @Inject
private final NewSetting settings; private AuthMe plugin;
private final Messages m; @Inject
private final DataSource dataSource; private NewSetting settings;
private final AntiBot antiBot; @Inject
private final Management management; private Messages m;
private final BukkitService bukkitService; @Inject
private DataSource dataSource;
public AuthMePlayerListener(AuthMe plugin, NewSetting settings, Messages messages, DataSource dataSource, @Inject
AntiBot antiBot, Management management, BukkitService bukkitService) { private AntiBot antiBot;
this.plugin = plugin; @Inject
this.settings = settings; private Management management;
this.m = messages; @Inject
this.dataSource = dataSource; private BukkitService bukkitService;
this.antiBot = antiBot; @Inject
this.management = management; private SpawnLoader spawnLoader;
this.bukkitService = bukkitService;
}
private void handleChat(AsyncPlayerChatEvent event) { private void handleChat(AsyncPlayerChatEvent event) {
if (settings.getProperty(RestrictionSettings.ALLOW_CHAT)) { if (settings.getProperty(RestrictionSettings.ALLOW_CHAT)) {
@ -201,7 +201,7 @@ public class AuthMePlayerListener implements Listener {
return; return;
} }
Location spawn = plugin.getSpawnLocation(player); Location spawn = spawnLoader.getSpawnLocation(player);
if (spawn != null && spawn.getWorld() != null) { if (spawn != null && spawn.getWorld() != null) {
if (!player.getWorld().equals(spawn.getWorld())) { if (!player.getWorld().equals(spawn.getWorld())) {
player.teleport(spawn); player.teleport(spawn);
@ -517,7 +517,7 @@ public class AuthMePlayerListener implements Listener {
Player player = event.getPlayer(); Player player = event.getPlayer();
String name = player.getName().toLowerCase(); String name = player.getName().toLowerCase();
Location spawn = plugin.getSpawnLocation(player); Location spawn = spawnLoader.getSpawnLocation(player);
if (Settings.isSaveQuitLocationEnabled && dataSource.isAuthAvailable(name)) { if (Settings.isSaveQuitLocationEnabled && dataSource.isAuthAvailable(name)) {
PlayerAuth auth = PlayerAuth.builder() PlayerAuth auth = PlayerAuth.builder()
.name(name) .name(name)

View File

@ -15,21 +15,20 @@ import org.bukkit.event.server.PluginDisableEvent;
import org.bukkit.event.server.PluginEnableEvent; import org.bukkit.event.server.PluginEnableEvent;
import org.bukkit.event.server.ServerListPingEvent; import org.bukkit.event.server.ServerListPingEvent;
import javax.inject.Inject;
/** /**
*/ */
public class AuthMeServerListener implements Listener { public class AuthMeServerListener implements Listener {
private final AuthMe plugin; @Inject
private final Messages messages; private AuthMe plugin;
private final PluginHooks pluginHooks; @Inject
private final SpawnLoader spawnLoader; private Messages messages;
@Inject
public AuthMeServerListener(AuthMe plugin, Messages messages, PluginHooks pluginHooks, SpawnLoader spawnLoader) { private PluginHooks pluginHooks;
this.plugin = plugin; @Inject
this.messages = messages; private SpawnLoader spawnLoader;
this.pluginHooks = pluginHooks;
this.spawnLoader = spawnLoader;
}
@EventHandler(priority = EventPriority.HIGHEST) @EventHandler(priority = EventPriority.HIGHEST)
public void onServerPing(ServerListPingEvent event) { public void onServerPing(ServerListPingEvent event) {

View File

@ -11,8 +11,11 @@ import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.cache.auth.PlayerCache; import fr.xephi.authme.cache.auth.PlayerCache;
import javax.inject.Inject;
public class AuthMeTabCompletePacketAdapter extends PacketAdapter { public class AuthMeTabCompletePacketAdapter extends PacketAdapter {
@Inject
public AuthMeTabCompletePacketAdapter(AuthMe plugin) { public AuthMeTabCompletePacketAdapter(AuthMe plugin) {
super(plugin, ListenerPriority.NORMAL, PacketType.Play.Client.TAB_COMPLETE); super(plugin, ListenerPriority.NORMAL, PacketType.Play.Client.TAB_COMPLETE);
} }

View File

@ -19,6 +19,7 @@ import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.util.BukkitService; import fr.xephi.authme.util.BukkitService;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import javax.inject.Inject;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.util.Arrays; import java.util.Arrays;
import java.util.logging.Level; import java.util.logging.Level;
@ -27,6 +28,7 @@ public class AuthMeTablistPacketAdapter extends PacketAdapter {
private final BukkitService bukkitService; private final BukkitService bukkitService;
@Inject
public AuthMeTablistPacketAdapter(AuthMe plugin, BukkitService bukkitService) { public AuthMeTablistPacketAdapter(AuthMe plugin, BukkitService bukkitService) {
super(plugin, ListenerPriority.NORMAL, PacketType.Play.Server.PLAYER_INFO); super(plugin, ListenerPriority.NORMAL, PacketType.Play.Server.PLAYER_INFO);
this.bukkitService = bukkitService; this.bukkitService = bukkitService;

View File

@ -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; import java.awt.image.BufferedImage;
/** /**

View File

@ -2,7 +2,6 @@ package fr.xephi.authme.mail;
import fr.xephi.authme.AuthMe; import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.ImageGenerator;
import fr.xephi.authme.cache.auth.PlayerAuth; import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.settings.NewSetting; import fr.xephi.authme.settings.NewSetting;
import fr.xephi.authme.settings.properties.EmailSettings; import fr.xephi.authme.settings.properties.EmailSettings;

View File

@ -2,6 +2,7 @@ package fr.xephi.authme.permission;
import de.bananaco.bpermissions.api.ApiLayer; import de.bananaco.bpermissions.api.ApiLayer;
import de.bananaco.bpermissions.api.CalculableType; import de.bananaco.bpermissions.api.CalculableType;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.command.CommandDescription; import fr.xephi.authme.command.CommandDescription;
import fr.xephi.authme.util.CollectionUtils; import fr.xephi.authme.util.CollectionUtils;
import net.milkbowl.vault.permission.Permission; 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.PermissionUser;
import ru.tehkode.permissions.bukkit.PermissionsEx; import ru.tehkode.permissions.bukkit.PermissionsEx;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.logging.Logger;
/** /**
* <p> * <p>
@ -48,10 +50,7 @@ public class PermissionsManager implements PermissionsService {
* Server instance. * Server instance.
*/ */
private final Server server; private final Server server;
/** private final PluginManager pluginManager;
* Logger instance.
*/
private Logger log;
/** /**
* Type of permissions system that is currently used. * Type of permissions system that is currently used.
* Null if no permissions system is hooked and/or used. * Null if no permissions system is hooked and/or used.
@ -70,11 +69,11 @@ public class PermissionsManager implements PermissionsService {
* Constructor. * Constructor.
* *
* @param server Server instance * @param server Server instance
* @param log Logger
*/ */
public PermissionsManager(Server server, Logger log) { @Inject
public PermissionsManager(Server server, PluginManager pluginManager) {
this.server = server; this.server = server;
this.log = log; this.pluginManager = pluginManager;
} }
/** /**
@ -100,39 +99,37 @@ public class PermissionsManager implements PermissionsService {
* *
* @return The detected permissions system. * @return The detected permissions system.
*/ */
@PostConstruct
public PermissionsSystemType setup() { public PermissionsSystemType setup() {
// Force-unhook from current hooked permissions systems // Force-unhook from current hooked permissions systems
unhook(); unhook();
// Define the plugin manager
final PluginManager pluginManager = this.server.getPluginManager();
// Reset used permissions system type flag // Reset used permissions system type flag
permsType = null; permsType = null;
// Loop through all the available permissions system types // 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 to find and hook the current plugin if available, print an error if failed
try { try {
// Try to find the plugin for the current permissions system // Try to find the plugin for the current permissions system
Plugin plugin = pluginManager.getPlugin(type.getPluginName()); Plugin plugin = pluginManager.getPlugin(type.getPluginName());
// Make sure a plugin with this name was found // Make sure a plugin with this name was found
if(plugin == null) if (plugin == null)
continue; continue;
// Make sure the plugin is enabled before hooking // Make sure the plugin is enabled before hooking
if(!plugin.isEnabled()) { if (!plugin.isEnabled()) {
this.log.info("Not hooking into " + type.getName() + " because it's disabled!"); ConsoleLogger.info("Not hooking into " + type.getName() + " because it's disabled!");
continue; continue;
} }
// Use the proper method to hook this plugin // Use the proper method to hook this plugin
switch(type) { switch (type) {
case PERMISSIONS_EX: case PERMISSIONS_EX:
// Get the permissions manager for PermissionsEx and make sure it isn't null // Get the permissions manager for PermissionsEx and make sure it isn't null
if(PermissionsEx.getPermissionManager() == null) { if (PermissionsEx.getPermissionManager() == null) {
this.log.info("Failed to hook into " + type.getName() + "!"); ConsoleLogger.info("Failed to hook into " + type.getName() + "!");
continue; continue;
} }
@ -146,8 +143,8 @@ public class PermissionsManager implements PermissionsService {
case Z_PERMISSIONS: case Z_PERMISSIONS:
// Set the zPermissions service and make sure it's valid // Set the zPermissions service and make sure it's valid
zPermissionsService = Bukkit.getServicesManager().load(ZPermissionsService.class); zPermissionsService = Bukkit.getServicesManager().load(ZPermissionsService.class);
if(zPermissionsService == null) { if (zPermissionsService == null) {
this.log.info("Failed to hook into " + type.getName() + "!"); ConsoleLogger.info("Failed to hook into " + type.getName() + "!");
continue; continue;
} }
@ -157,14 +154,14 @@ public class PermissionsManager implements PermissionsService {
// Get the permissions provider service // Get the permissions provider service
RegisteredServiceProvider<Permission> permissionProvider = this.server.getServicesManager().getRegistration(Permission.class); RegisteredServiceProvider<Permission> permissionProvider = this.server.getServicesManager().getRegistration(Permission.class);
if (permissionProvider == null) { if (permissionProvider == null) {
this.log.info("Failed to hook into " + type.getName() + "!"); ConsoleLogger.info("Failed to hook into " + type.getName() + "!");
continue; continue;
} }
// Get the Vault provider and make sure it's valid // Get the Vault provider and make sure it's valid
vaultPerms = permissionProvider.getProvider(); vaultPerms = permissionProvider.getProvider();
if(vaultPerms == null) { if (vaultPerms == null) {
this.log.info("Not using " + type.getName() + " because it's disabled!"); ConsoleLogger.info("Not using " + type.getName() + " because it's disabled!");
continue; continue;
} }
@ -177,19 +174,19 @@ public class PermissionsManager implements PermissionsService {
this.permsType = type; this.permsType = type;
// Show a success message // Show a success message
this.log.info("Hooked into " + type.getName() + "!"); ConsoleLogger.info("Hooked into " + type.getName() + "!");
// Return the used permissions system type // Return the used permissions system type
return type; return type;
} catch (Exception ex) { } catch (Exception ex) {
// An error occurred, show a warning message // 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 // 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; return null;
} }
@ -201,7 +198,7 @@ public class PermissionsManager implements PermissionsService {
this.permsType = null; this.permsType = null;
// Print a status message to the console // 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") || if (pluginName.equals("PermissionsEx") || pluginName.equals("PermissionsBukkit") ||
pluginName.equals("bPermissions") || pluginName.equals("GroupManager") || pluginName.equals("bPermissions") || pluginName.equals("GroupManager") ||
pluginName.equals("zPermissions") || pluginName.equals("Vault")) { 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(); setup();
} }
} }
@ -251,7 +248,7 @@ public class PermissionsManager implements PermissionsService {
if (pluginName.equals("PermissionsEx") || pluginName.equals("PermissionsBukkit") || if (pluginName.equals("PermissionsEx") || pluginName.equals("PermissionsBukkit") ||
pluginName.equals("bPermissions") || pluginName.equals("GroupManager") || pluginName.equals("bPermissions") || pluginName.equals("GroupManager") ||
pluginName.equals("zPermissions") || pluginName.equals("Vault")) { pluginName.equals("zPermissions") || pluginName.equals("Vault")) {
this.log.info(pluginName + " plugin disabled, updating hooks!"); ConsoleLogger.info(pluginName + " plugin disabled, updating hooks!");
setup(); setup();
} }
} }

View File

@ -3,6 +3,7 @@ package fr.xephi.authme.process;
import fr.xephi.authme.AuthMe; import fr.xephi.authme.AuthMe;
import fr.xephi.authme.cache.auth.PlayerCache; import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.datasource.DataSource; 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.AsyncAddEmail;
import fr.xephi.authme.process.email.AsyncChangeEmail; import fr.xephi.authme.process.email.AsyncChangeEmail;
import fr.xephi.authme.process.join.AsynchronousJoin; 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.entity.Player;
import org.bukkit.scheduler.BukkitScheduler; import org.bukkit.scheduler.BukkitScheduler;
import javax.inject.Inject;
/** /**
*/ */
public class Management { public class Management {
private final AuthMe plugin; @Inject
private final BukkitScheduler sched; private AuthMe plugin;
private final ProcessService processService; @Inject
private final DataSource dataSource; private BukkitScheduler sched;
private final PlayerCache playerCache; @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) { Management() { }
this.plugin = plugin;
this.sched = this.plugin.getServer().getScheduler();
this.processService = processService;
this.dataSource = dataSource;
this.playerCache = playerCache;
}
public void performLogin(final Player player, final String password, final boolean forceLogin) { public void performLogin(final Player player, final String password, final boolean forceLogin) {
runTask(new AsynchronousLogin(player, password, forceLogin, plugin, dataSource, processService)); runTask(new AsynchronousLogin(player, password, forceLogin, plugin, dataSource, processService));
@ -49,7 +53,7 @@ public class Management {
} }
public void performJoin(final Player player) { 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) { public void performQuit(final Player player, final boolean isKick) {

View File

@ -17,6 +17,7 @@ import org.bukkit.entity.Player;
import org.bukkit.event.Event; import org.bukkit.event.Event;
import org.bukkit.scheduler.BukkitTask; import org.bukkit.scheduler.BukkitTask;
import javax.inject.Inject;
import java.util.Collection; import java.util.Collection;
/** /**
@ -24,29 +25,24 @@ import java.util.Collection;
*/ */
public class ProcessService { public class ProcessService {
private final NewSetting settings; @Inject
private final Messages messages; private NewSetting settings;
private final AuthMe authMe; @Inject
private final DataSource dataSource; private Messages messages;
private final PasswordSecurity passwordSecurity; @Inject
private final PluginHooks pluginHooks; private AuthMe authMe;
private final SpawnLoader spawnLoader; @Inject
private final ValidationService validationService; private DataSource dataSource;
private final BukkitService bukkitService; @Inject
private PasswordSecurity passwordSecurity;
public ProcessService(NewSetting settings, Messages messages, AuthMe authMe, DataSource dataSource, @Inject
PasswordSecurity passwordSecurity, PluginHooks pluginHooks, SpawnLoader spawnLoader, private PluginHooks pluginHooks;
ValidationService validationService, BukkitService bukkitService) { @Inject
this.settings = settings; private SpawnLoader spawnLoader;
this.messages = messages; @Inject
this.authMe = authMe; private ValidationService validationService;
this.dataSource = dataSource; @Inject
this.passwordSecurity = passwordSecurity; private BukkitService bukkitService;
this.pluginHooks = pluginHooks;
this.spawnLoader = spawnLoader;
this.validationService = validationService;
this.bukkitService = bukkitService;
}
/** /**
* Retrieve a property's value. * Retrieve a property's value.

View File

@ -9,6 +9,7 @@ import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.events.FirstSpawnTeleportEvent; import fr.xephi.authme.events.FirstSpawnTeleportEvent;
import fr.xephi.authme.events.ProtectInventoryEvent; import fr.xephi.authme.events.ProtectInventoryEvent;
import fr.xephi.authme.events.SpawnTeleportEvent; import fr.xephi.authme.events.SpawnTeleportEvent;
import fr.xephi.authme.hooks.PluginHooks;
import fr.xephi.authme.listener.AuthMePlayerListener; import fr.xephi.authme.listener.AuthMePlayerListener;
import fr.xephi.authme.output.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.permission.PlayerStatePermission; import fr.xephi.authme.permission.PlayerStatePermission;
@ -45,18 +46,20 @@ public class AsynchronousJoin implements Process {
private final String name; private final String name;
private final ProcessService service; private final ProcessService service;
private final PlayerCache playerCache; private final PlayerCache playerCache;
private final PluginHooks pluginHooks;
private final boolean disableCollisions = MethodUtils private final boolean disableCollisions = MethodUtils
.getAccessibleMethod(LivingEntity.class, "setCollidable", new Class[]{}) != null; .getAccessibleMethod(LivingEntity.class, "setCollidable", new Class[]{}) != null;
public AsynchronousJoin(Player player, AuthMe plugin, DataSource database, PlayerCache playerCache, public AsynchronousJoin(Player player, AuthMe plugin, DataSource database, PlayerCache playerCache,
ProcessService service) { PluginHooks pluginHooks, ProcessService service) {
this.player = player; this.player = player;
this.plugin = plugin; this.plugin = plugin;
this.database = database; this.database = database;
this.name = player.getName().toLowerCase(); this.name = player.getName().toLowerCase();
this.service = service; this.service = service;
this.playerCache = playerCache; this.playerCache = playerCache;
this.pluginHooks = pluginHooks;
} }
@Override @Override
@ -190,7 +193,7 @@ public class AsynchronousJoin implements Process {
player.setWalkSpeed(0.0f); player.setWalkSpeed(0.0f);
} }
player.setNoDamageTicks(registrationTimeout); 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"); player.performCommand("motd");
} }
if (service.getProperty(RegistrationSettings.APPLY_BLIND_EFFECT)) { if (service.getProperty(RegistrationSettings.APPLY_BLIND_EFFECT)) {

View File

@ -8,6 +8,7 @@ import fr.xephi.authme.settings.NewSetting;
import fr.xephi.authme.settings.properties.SecuritySettings; import fr.xephi.authme.settings.properties.SecuritySettings;
import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.PluginManager;
import javax.inject.Inject;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
@ -22,6 +23,7 @@ public class PasswordSecurity {
private final DataSource dataSource; private final DataSource dataSource;
private final PluginManager pluginManager; private final PluginManager pluginManager;
@Inject
public PasswordSecurity(DataSource dataSource, NewSetting settings, PluginManager pluginManager) { public PasswordSecurity(DataSource dataSource, NewSetting settings, PluginManager pluginManager) {
this.settings = settings; this.settings = settings;
this.algorithm = settings.getProperty(SecuritySettings.PASSWORD_HASH); this.algorithm = settings.getProperty(SecuritySettings.PASSWORD_HASH);

View File

@ -4,6 +4,7 @@ import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.cache.auth.PlayerCache; import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.hooks.PluginHooks; import fr.xephi.authme.hooks.PluginHooks;
import fr.xephi.authme.initialization.DataFolder;
import fr.xephi.authme.settings.properties.RestrictionSettings; import fr.xephi.authme.settings.properties.RestrictionSettings;
import fr.xephi.authme.util.FileUtils; import fr.xephi.authme.util.FileUtils;
import fr.xephi.authme.util.StringUtils; 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.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import javax.inject.Inject;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@ -40,7 +42,8 @@ public class SpawnLoader {
* @param settings The setting instance * @param settings The setting instance
* @param pluginHooks The plugin hooks 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"); File spawnFile = new File(pluginFolder, "spawn.yml");
// TODO ljacqu 20160312: Check if resource could be copied and handle the case if not // TODO ljacqu 20160312: Check if resource could be copied and handle the case if not
FileUtils.copyFileFromResource(spawnFile, "spawn.yml"); FileUtils.copyFileFromResource(spawnFile, "spawn.yml");

View File

@ -7,6 +7,7 @@ import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitTask; import org.bukkit.scheduler.BukkitTask;
import javax.inject.Inject;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Arrays; import java.util.Arrays;
@ -28,6 +29,7 @@ public class BukkitService {
private final boolean getOnlinePlayersIsCollection; private final boolean getOnlinePlayersIsCollection;
private Method getOnlinePlayers; private Method getOnlinePlayers;
@Inject
public BukkitService(AuthMe authMe) { public BukkitService(AuthMe authMe) {
this.authMe = authMe; this.authMe = authMe;
getOnlinePlayersIsCollection = initializeOnlinePlayersIsCollectionField(); getOnlinePlayersIsCollection = initializeOnlinePlayersIsCollectionField();

View File

@ -165,8 +165,9 @@ public final class Utils {
}); });
} }
@Deprecated
public static boolean isNPC(Player player) { 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) { public static void teleportToSpawn(Player player) {

View File

@ -10,6 +10,7 @@ import fr.xephi.authme.settings.properties.RestrictionSettings;
import fr.xephi.authme.settings.properties.SecuritySettings; import fr.xephi.authme.settings.properties.SecuritySettings;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import javax.inject.Inject;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
@ -22,6 +23,7 @@ public class ValidationService {
private final DataSource dataSource; private final DataSource dataSource;
private final PermissionsManager permissionsManager; private final PermissionsManager permissionsManager;
@Inject
public ValidationService(NewSetting settings, DataSource dataSource, PermissionsManager permissionsManager) { public ValidationService(NewSetting settings, DataSource dataSource, PermissionsManager permissionsManager) {
this.settings = settings; this.settings = settings;
this.dataSource = dataSource; this.dataSource = dataSource;

View File

@ -18,10 +18,10 @@ import fr.xephi.authme.util.BukkitService;
import fr.xephi.authme.util.ValidationService; import fr.xephi.authme.util.ValidationService;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
import org.mockito.InjectMocks;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner; import org.mockito.runners.MockitoJUnitRunner;
@ -41,6 +41,7 @@ import static org.mockito.Mockito.verify;
@RunWith(MockitoJUnitRunner.class) @RunWith(MockitoJUnitRunner.class)
public class CommandServiceTest { public class CommandServiceTest {
@InjectMocks
private CommandService commandService; private CommandService commandService;
@Mock @Mock
private AuthMe authMe; private AuthMe authMe;
@ -67,12 +68,6 @@ public class CommandServiceTest {
@Mock @Mock
private BukkitService bukkitService; private BukkitService bukkitService;
@Before
public void setUpService() {
commandService = new CommandService(authMe, commandMapper, helpProvider, messages, passwordSecurity,
permissionsManager, settings, pluginHooks, spawnLoader, antiBot, validationService, bukkitService);
}
@Test @Test
public void shouldSendMessage() { public void shouldSendMessage() {
// given // given

View File

@ -6,6 +6,8 @@ import fr.xephi.authme.command.FoundResultStatus;
import fr.xephi.authme.command.TestCommandsUtil; import fr.xephi.authme.command.TestCommandsUtil;
import fr.xephi.authme.permission.PermissionsManager; import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.permission.PlayerPermission; import fr.xephi.authme.permission.PlayerPermission;
import fr.xephi.authme.settings.NewSetting;
import fr.xephi.authme.settings.properties.PluginSettings;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.junit.Before; import org.junit.Before;
@ -52,7 +54,9 @@ public class HelpProviderTest {
@Before @Before
public void setUpHelpProvider() { public void setUpHelpProvider() {
permissionsManager = mock(PermissionsManager.class); permissionsManager = mock(PermissionsManager.class);
helpProvider = new HelpProvider(permissionsManager, HELP_HEADER); NewSetting settings = mock(NewSetting.class);
given(settings.getProperty(PluginSettings.HELP_HEADER)).willReturn(HELP_HEADER);
helpProvider = new HelpProvider(permissionsManager, settings);
sender = mock(CommandSender.class); sender = mock(CommandSender.class);
} }

View File

@ -0,0 +1,194 @@
package fr.xephi.authme.initialization;
import fr.xephi.authme.initialization.samples.BadFieldInjection;
import fr.xephi.authme.initialization.samples.BetaManager;
import fr.xephi.authme.initialization.samples.CircularClasses;
import fr.xephi.authme.initialization.samples.ClassWithAbstractDependency;
import fr.xephi.authme.initialization.samples.ClassWithAnnotations;
import fr.xephi.authme.initialization.samples.Duration;
import fr.xephi.authme.initialization.samples.FieldInjectionWithAnnotations;
import fr.xephi.authme.initialization.samples.InvalidClass;
import fr.xephi.authme.initialization.samples.InvalidPostConstruct;
import fr.xephi.authme.initialization.samples.PostConstructTestClass;
import fr.xephi.authme.initialization.samples.ProvidedClass;
import fr.xephi.authme.initialization.samples.Size;
import org.junit.Before;
import org.junit.Test;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertThat;
/**
* Test for {@link AuthMeServiceInitializer}.
*/
public class AuthMeServiceInitializerTest {
private static final String ALLOWED_PACKAGE = "fr.xephi.authme.initialization";
private AuthMeServiceInitializer initializer;
@Before
public void setInitializer() {
initializer = new AuthMeServiceInitializer(ALLOWED_PACKAGE);
initializer.register(new ProvidedClass(""));
}
@Test
public void shouldInitializeElements() {
// given / when
BetaManager betaManager = initializer.get(BetaManager.class);
// then
assertThat(betaManager, not(nullValue()));
for (Object o : betaManager.getDependencies()) {
assertThat(o, not(nullValue()));
}
}
@Test(expected = IllegalStateException.class)
public void shouldThrowForInvalidPackage() {
// given / when / then
initializer.get(InvalidClass.class);
}
@Test
public void shouldPassValueByAnnotation() {
// given
int size = 12;
long duration = -15482L;
initializer.provide(Size.class, size);
initializer.provide(Duration.class, duration);
// when
ClassWithAnnotations object = initializer.get(ClassWithAnnotations.class);
// then
assertThat(object, not(nullValue()));
assertThat(object.getSize(), equalTo(size));
assertThat(object.getDuration(), equalTo(duration));
// some sample check to make sure we only have one instance of GammaService
assertThat(object.getGammaService(), equalTo(initializer.get(BetaManager.class).getDependencies()[1]));
}
@Test(expected = RuntimeException.class)
public void shouldRecognizeCircularReferences() {
// given / when / then
initializer.get(CircularClasses.Circular3.class);
}
@Test(expected = RuntimeException.class)
public void shouldThrowForUnregisteredAnnotation() {
// given
initializer.provide(Size.class, 4523);
// when / then
initializer.get(ClassWithAnnotations.class);
}
@Test(expected = RuntimeException.class)
public void shouldThrowForFieldInjectionWithNoDefaultConstructor() {
// given / when / then
initializer.get(BadFieldInjection.class);
}
@Test
public void shouldInjectFieldsWithAnnotationsProperly() {
// given
initializer.provide(Size.class, 2809375);
initializer.provide(Duration.class, 13095L);
// when
FieldInjectionWithAnnotations result = initializer.get(FieldInjectionWithAnnotations.class);
// then
assertThat(result.getSize(), equalTo(2809375));
assertThat(result.getDuration(), equalTo(13095L));
assertThat(result.getBetaManager(), not(nullValue()));
assertThat(result.getClassWithAnnotations(), not(nullValue()));
assertThat(result.getClassWithAnnotations().getGammaService(),
equalTo(result.getBetaManager().getDependencies()[1]));
}
@Test(expected = RuntimeException.class)
public void shouldThrowForAnnotationAsKey() {
// given / when / then
initializer.get(Size.class);
}
@Test(expected = RuntimeException.class)
public void shouldThrowForSecondRegistration() {
// given / when / then
initializer.register(new ProvidedClass(""));
}
@Test(expected = RuntimeException.class)
public void shouldThrowForSecondAnnotationRegistration() {
// given
initializer.provide(Size.class, 12);
// when / then
initializer.provide(Size.class, -8);
}
@Test(expected = NullPointerException.class)
public void shouldThrowForNullValueAssociatedToAnnotation() {
// given / when / then
initializer.provide(Duration.class, null);
}
@Test(expected = NullPointerException.class)
public void shouldThrowForRegisterWithNull() {
// given / when / then
initializer.register(String.class, null);
}
@Test(expected = RuntimeException.class)
public void shouldThrowForRegisterOfType() {
// given / when / then
// this most likely means that the second argument was forgotten, so throw an error and force
// the API user to use the explicit register(Class.class, String.class) if really, really desired
// (Though for such generic types, an annotation would be a lot better)
initializer.register(String.class);
}
@Test
public void shouldExecutePostConstructMethod() {
// given
initializer.provide(Size.class, 15123);
// when
PostConstructTestClass testClass = initializer.get(PostConstructTestClass.class);
// then
assertThat(testClass.werePostConstructsCalled(), equalTo(true));
assertThat(testClass.getBetaManager(), not(nullValue()));
}
@Test(expected = RuntimeException.class)
public void shouldThrowForInvalidPostConstructMethod() {
// given / when / then
initializer.get(InvalidPostConstruct.class);
}
@Test(expected = RuntimeException.class)
public void shouldThrowForAbstractNonRegisteredDependency() {
// given / when / then
initializer.get(ClassWithAbstractDependency.class);
}
@Test
public void shouldInstantiateWithImplementationOfAbstractDependency() {
// given
ClassWithAbstractDependency.ConcreteDependency concrete = new ClassWithAbstractDependency.ConcreteDependency();
initializer.register(ClassWithAbstractDependency.AbstractDependency.class, concrete);
// when
ClassWithAbstractDependency cwad = initializer.get(ClassWithAbstractDependency.class);
// then
assertThat(cwad.getAbstractDependency() == concrete, equalTo(true));
assertThat(cwad.getAlphaService(), not(nullValue()));
}
}

View File

@ -0,0 +1,20 @@
package fr.xephi.authme.initialization.samples;
import javax.inject.Inject;
/**
* Sample - class with dependency to ProvidedClass.
*/
public class AlphaService {
private ProvidedClass providedClass;
@Inject
AlphaService(ProvidedClass providedClass) {
this.providedClass = providedClass;
}
public ProvidedClass getProvidedClass() {
return providedClass;
}
}

View File

@ -0,0 +1,16 @@
package fr.xephi.authme.initialization.samples;
import javax.inject.Inject;
/**
* Sample class with invalid field injection (requires default constructor).
*/
public class BadFieldInjection {
@Inject
private AlphaService alphaService;
public BadFieldInjection(BetaManager betaManager) {
throw new IllegalStateException("Should never be called");
}
}

View File

@ -0,0 +1,20 @@
package fr.xephi.authme.initialization.samples;
import javax.inject.Inject;
/**
* Sample - depends on Provided, alpha and gamma.
*/
public class BetaManager {
@Inject
private ProvidedClass providedClass;
@Inject
private GammaService gammaService;
@Inject
private AlphaService alphaService;
public Object[] getDependencies() {
return new Object[]{providedClass, gammaService, alphaService};
}
}

View File

@ -0,0 +1,30 @@
package fr.xephi.authme.initialization.samples;
import javax.inject.Inject;
/**
* Classes with circular dependencies.
*/
public class CircularClasses {
public static final class Circular1 {
@Inject
public Circular1(AlphaService alphaService, Circular3 circular3) {
// --
}
}
public static final class Circular2 {
@Inject
public Circular2(Circular1 circular1) {
// --
}
}
public static final class Circular3 {
@Inject
public Circular3(Circular2 circular2, BetaManager betaManager) {
// --
}
}
}

View File

@ -0,0 +1,32 @@
package fr.xephi.authme.initialization.samples;
import javax.inject.Inject;
/**
* Test with an abstract class declared as dependency.
*/
public class ClassWithAbstractDependency {
private final AlphaService alphaService;
private final AbstractDependency abstractDependency;
@Inject
public ClassWithAbstractDependency(AlphaService as, AbstractDependency ad) {
this.alphaService = as;
this.abstractDependency = ad;
}
public AlphaService getAlphaService() {
return alphaService;
}
public AbstractDependency getAbstractDependency() {
return abstractDependency;
}
public static abstract class AbstractDependency {
}
public static final class ConcreteDependency extends AbstractDependency {
}
}

View File

@ -0,0 +1,29 @@
package fr.xephi.authme.initialization.samples;
import javax.inject.Inject;
public class ClassWithAnnotations {
private int size;
private GammaService gammaService;
private long duration;
@Inject
ClassWithAnnotations(@Size int size, GammaService gammaService, @Duration long duration) {
this.size = size;
this.gammaService = gammaService;
this.duration = duration;
}
public int getSize() {
return size;
}
public GammaService getGammaService() {
return gammaService;
}
public long getDuration() {
return duration;
}
}

View File

@ -0,0 +1,14 @@
package fr.xephi.authme.initialization.samples;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Sample annotation.
*/
@Target({ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Duration {
}

View File

@ -0,0 +1,40 @@
package fr.xephi.authme.initialization.samples;
import javax.inject.Inject;
/**
* Sample - field injection, including custom annotations.
*/
public class FieldInjectionWithAnnotations {
@Inject
private BetaManager betaManager;
@Inject
@Size
private int size;
@Duration
@Inject
private long duration;
@Inject
protected ClassWithAnnotations classWithAnnotations;
FieldInjectionWithAnnotations() {
}
public BetaManager getBetaManager() {
return betaManager;
}
public int getSize() {
return size;
}
public long getDuration() {
return duration;
}
public ClassWithAnnotations getClassWithAnnotations() {
return classWithAnnotations;
}
}

View File

@ -0,0 +1,20 @@
package fr.xephi.authme.initialization.samples;
import javax.inject.Inject;
/**
* Sample - class dependent on alpha and provided.
*/
public class GammaService {
private AlphaService alphaService;
@Inject
GammaService(AlphaService alphaService) {
this.alphaService = alphaService;
}
public AlphaService getAlphaService() {
return alphaService;
}
}

View File

@ -0,0 +1,14 @@
package fr.xephi.authme.initialization.samples;
import javax.inject.Inject;
/**
* Sample - invalid class, since Integer parameter type is outside of the allowed package and not annotated.
*/
public class InvalidClass {
@Inject
public InvalidClass(AlphaService alphaService, Integer i) {
throw new IllegalStateException("Should never be called");
}
}

View File

@ -0,0 +1,19 @@
package fr.xephi.authme.initialization.samples;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
/**
* Class with invalid @PostConstruct method.
*/
public class InvalidPostConstruct {
@Inject
private AlphaService alphaService;
@Inject
private ProvidedClass providedClass;
@PostConstruct
public void invalidPostConstr(BetaManager betaManager) {
}
}

View File

@ -0,0 +1,37 @@
package fr.xephi.authme.initialization.samples;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
/**
* Sample class for testing the execution of the @PostConstruct method.
*/
public class PostConstructTestClass {
@Inject
@Size
private int size;
@Inject
private BetaManager betaManager;
private boolean wasPostConstructCalled = false;
private boolean wasSecondPostConstructCalled = false;
@PostConstruct
protected void setFieldToTrue() {
wasPostConstructCalled = true;
}
@PostConstruct
public int otherPostConstructMethod() {
wasSecondPostConstructCalled = true;
return 42;
}
public boolean werePostConstructsCalled() {
return wasPostConstructCalled && wasSecondPostConstructCalled;
}
public BetaManager getBetaManager() {
return betaManager;
}
}

View File

@ -0,0 +1,18 @@
package fr.xephi.authme.initialization.samples;
import javax.inject.Inject;
/**
* Sample - class that is always provided to the initializer beforehand.
*/
public class ProvidedClass {
@Inject
public ProvidedClass() {
throw new IllegalStateException("Should never be called (tests always provide this class)");
}
public ProvidedClass(String manualConstructor) {
}
}

View File

@ -0,0 +1,14 @@
package fr.xephi.authme.initialization.samples;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Sample annotation.
*/
@Target({ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Size {
}

View File

@ -13,9 +13,9 @@ import fr.xephi.authme.settings.properties.SecuritySettings;
import fr.xephi.authme.util.BukkitService; import fr.xephi.authme.util.BukkitService;
import fr.xephi.authme.util.ValidationService; import fr.xephi.authme.util.ValidationService;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner; import org.mockito.runners.MockitoJUnitRunner;
@ -31,6 +31,7 @@ import static org.mockito.Mockito.verify;
@RunWith(MockitoJUnitRunner.class) @RunWith(MockitoJUnitRunner.class)
public class ProcessServiceTest { public class ProcessServiceTest {
@InjectMocks
private ProcessService processService; private ProcessService processService;
@Mock @Mock
private ValidationService validationService; private ValidationService validationService;
@ -51,12 +52,6 @@ public class ProcessServiceTest {
@Mock @Mock
private BukkitService bukkitService; private BukkitService bukkitService;
@Before
public void setUpService() {
processService = new ProcessService(settings, messages, authMe, dataSource, passwordSecurity,
pluginHooks, spawnLoader, validationService, bukkitService);
}
@Test @Test
public void shouldGetProperty() { public void shouldGetProperty() {
// given // given