#421 Create SpawnLoader

- Non-static service class which handles the spawnpoints used in AuthMe
This commit is contained in:
ljacqu 2016-03-12 10:27:15 +01:00
parent 8b27444a49
commit 8293766f98
18 changed files with 464 additions and 274 deletions

View File

@ -21,7 +21,6 @@ import fr.xephi.authme.datasource.FlatFile;
import fr.xephi.authme.datasource.MySQL; 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.EssSpawn;
import fr.xephi.authme.hooks.PluginHooks; import fr.xephi.authme.hooks.PluginHooks;
import fr.xephi.authme.listener.AuthMeBlockListener; import fr.xephi.authme.listener.AuthMeBlockListener;
import fr.xephi.authme.listener.AuthMeEntityListener; import fr.xephi.authme.listener.AuthMeEntityListener;
@ -45,8 +44,7 @@ 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;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.SettingsMigrationService; import fr.xephi.authme.settings.SpawnLoader;
import fr.xephi.authme.settings.Spawn;
import fr.xephi.authme.settings.properties.DatabaseSettings; import fr.xephi.authme.settings.properties.DatabaseSettings;
import fr.xephi.authme.settings.properties.EmailSettings; import fr.xephi.authme.settings.properties.EmailSettings;
import fr.xephi.authme.settings.properties.HooksSettings; import fr.xephi.authme.settings.properties.HooksSettings;
@ -55,6 +53,7 @@ import fr.xephi.authme.settings.properties.PurgeSettings;
import fr.xephi.authme.settings.properties.RestrictionSettings; import fr.xephi.authme.settings.properties.RestrictionSettings;
import fr.xephi.authme.settings.properties.SecuritySettings; import fr.xephi.authme.settings.properties.SecuritySettings;
import fr.xephi.authme.util.CollectionUtils; import fr.xephi.authme.util.CollectionUtils;
import fr.xephi.authme.util.FileUtils;
import fr.xephi.authme.util.GeoLiteAPI; 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;
@ -116,7 +115,6 @@ public class AuthMe extends JavaPlugin {
public NewAPI api; public NewAPI api;
public SendMailSSL mail; public SendMailSSL mail;
public DataManager dataManager; public DataManager dataManager;
public Location essentialsSpawn;
/* /*
* Plugin Hooks * Plugin Hooks
* TODO: Move into modules * TODO: Move into modules
@ -134,6 +132,7 @@ public class AuthMe extends JavaPlugin {
private DataSource database; private DataSource database;
private IpAddressManager ipAddressManager; private IpAddressManager ipAddressManager;
private PluginHooks pluginHooks; private PluginHooks pluginHooks;
private SpawnLoader spawnLoader;
/** /**
* Get the plugin's instance. * Get the plugin's instance.
@ -249,10 +248,13 @@ public class AuthMe extends JavaPlugin {
passwordSecurity = new PasswordSecurity(getDataSource(), newSettings, Bukkit.getPluginManager()); passwordSecurity = new PasswordSecurity(getDataSource(), newSettings, Bukkit.getPluginManager());
ipAddressManager = new IpAddressManager(newSettings); ipAddressManager = new IpAddressManager(newSettings);
// Initialize spawn loader
spawnLoader = new SpawnLoader(getDataFolder(), newSettings, pluginHooks);
// Set up the permissions manager and command handler // Set up the permissions manager and command handler
permsMan = initializePermissionsManager(); permsMan = initializePermissionsManager();
commandHandler = initializeCommandHandler(permsMan, messages, passwordSecurity, newSettings, ipAddressManager, commandHandler = initializeCommandHandler(permsMan, messages, passwordSecurity, newSettings, ipAddressManager,
pluginHooks); pluginHooks, spawnLoader);
// Set up Metrics // Set up Metrics
MetricsStarter.setupMetrics(plugin, newSettings); MetricsStarter.setupMetrics(plugin, newSettings);
@ -269,10 +271,6 @@ public class AuthMe extends JavaPlugin {
// Set up the mail API // Set up the mail API
setupMailApi(); setupMailApi();
// Hooks
// Check Essentials
checkEssentialsSpawn();
// Check if the ProtocolLib is available. If so we could listen for // Check if the ProtocolLib is available. If so we could listen for
// inventory protection // inventory protection
checkProtocolLib(); checkProtocolLib();
@ -293,7 +291,7 @@ public class AuthMe extends JavaPlugin {
// Set up the management // Set up the management
ProcessService processService = new ProcessService(newSettings, messages, this, ipAddressManager, ProcessService processService = new ProcessService(newSettings, messages, this, ipAddressManager,
passwordSecurity, pluginHooks); passwordSecurity, pluginHooks, spawnLoader);
management = new Management(this, processService, database, PlayerCache.getInstance()); management = new Management(this, processService, database, PlayerCache.getInstance());
// Set up the BungeeCord hook // Set up the BungeeCord hook
@ -303,7 +301,7 @@ public class AuthMe extends JavaPlugin {
reloadSupportHook(); reloadSupportHook();
// Register event listeners // Register event listeners
registerEventListeners(); registerEventListeners(messages, pluginHooks, spawnLoader);
// Purge on start if enabled // Purge on start if enabled
autoPurge(); autoPurge();
@ -337,7 +335,7 @@ public class AuthMe extends JavaPlugin {
database.reload(); database.reload();
messages.reload(newSettings.getMessagesFile()); messages.reload(newSettings.getMessagesFile());
passwordSecurity.reload(newSettings); passwordSecurity.reload(newSettings);
Spawn.reload(); spawnLoader.initialize(newSettings);
} }
/** /**
@ -369,7 +367,7 @@ public class AuthMe extends JavaPlugin {
/** /**
* Register all event listeners. * Register all event listeners.
*/ */
private void registerEventListeners() { private void registerEventListeners(Messages messages, PluginHooks pluginHooks, SpawnLoader spawnLoader) {
// Get the plugin manager instance // Get the plugin manager instance
PluginManager pluginManager = server.getPluginManager(); PluginManager pluginManager = server.getPluginManager();
@ -377,7 +375,7 @@ public class AuthMe extends JavaPlugin {
pluginManager.registerEvents(new AuthMePlayerListener(this), this); pluginManager.registerEvents(new AuthMePlayerListener(this), this);
pluginManager.registerEvents(new AuthMeBlockListener(), this); pluginManager.registerEvents(new AuthMeBlockListener(), this);
pluginManager.registerEvents(new AuthMeEntityListener(), this); pluginManager.registerEvents(new AuthMeEntityListener(), this);
pluginManager.registerEvents(new AuthMeServerListener(this, messages, pluginHooks), 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 {
@ -425,12 +423,13 @@ public class AuthMe extends JavaPlugin {
private CommandHandler initializeCommandHandler(PermissionsManager permissionsManager, Messages messages, private CommandHandler initializeCommandHandler(PermissionsManager permissionsManager, Messages messages,
PasswordSecurity passwordSecurity, NewSetting settings, PasswordSecurity passwordSecurity, NewSetting settings,
IpAddressManager ipAddressManager, PluginHooks pluginHooks) { IpAddressManager ipAddressManager, PluginHooks pluginHooks,
SpawnLoader spawnLoader) {
HelpProvider helpProvider = new HelpProvider(permissionsManager, settings.getProperty(HELP_HEADER)); HelpProvider helpProvider = new HelpProvider(permissionsManager, settings.getProperty(HELP_HEADER));
Set<CommandDescription> baseCommands = CommandInitializer.buildCommands(); Set<CommandDescription> baseCommands = CommandInitializer.buildCommands();
CommandMapper mapper = new CommandMapper(baseCommands, permissionsManager); CommandMapper mapper = new CommandMapper(baseCommands, permissionsManager);
CommandService commandService = new CommandService(this, mapper, helpProvider, messages, passwordSecurity, CommandService commandService = new CommandService(this, mapper, helpProvider, messages, passwordSecurity,
permissionsManager, settings, ipAddressManager, pluginHooks); permissionsManager, settings, ipAddressManager, pluginHooks, spawnLoader);
return new CommandHandler(commandService); return new CommandHandler(commandService);
} }
@ -465,7 +464,7 @@ public class AuthMe extends JavaPlugin {
private NewSetting createNewSetting() { private NewSetting createNewSetting() {
File configFile = new File(getDataFolder(), "config.yml"); File configFile = new File(getDataFolder(), "config.yml");
return SettingsMigrationService.copyFileFromResource(configFile, "config.yml") return FileUtils.copyFileFromResource(configFile, "config.yml")
? new NewSetting(configFile, getDataFolder()) ? new NewSetting(configFile, getDataFolder())
: null; : null;
} }
@ -633,21 +632,6 @@ public class AuthMe extends JavaPlugin {
}); });
} }
// Get the Essentials plugin
public void checkEssentialsSpawn() {
if (server.getPluginManager().isPluginEnabled("EssentialsSpawn")) {
try {
essentialsSpawn = new EssSpawn().getLocation();
ConsoleLogger.info("Hooked correctly with EssentialsSpawn");
} catch (Exception e) {
essentialsSpawn = null;
ConsoleLogger.showError("Can't read the /plugins/Essentials/spawn.yml file!");
}
} else {
essentialsSpawn = null;
}
}
// 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 (!server.getPluginManager().isPluginEnabled("ProtocolLib")) {
@ -748,7 +732,7 @@ public class AuthMe extends JavaPlugin {
// Return the spawn location of a player // Return the spawn location of a player
@Deprecated @Deprecated
public Location getSpawnLocation(Player player) { public Location getSpawnLocation(Player player) {
return Spawn.getInstance().getSpawnLocation(player); return spawnLoader.getSpawnLocation(player);
} }
private void scheduleRecallEmailTask() { private void scheduleRecallEmailTask() {

View File

@ -159,7 +159,7 @@ public final class CommandInitializer {
.labels("getip", "ip") .labels("getip", "ip")
.description("Get player's IP") .description("Get player's IP")
.detailedDescription("Get the IP address of the specified online player.") .detailedDescription("Get the IP address of the specified online player.")
.withArgument("player", "Player Name", false) .withArgument("player", "Player name", false)
.permissions(OP_ONLY, AdminPermission.GET_IP) .permissions(OP_ONLY, AdminPermission.GET_IP)
.executableCommand(new GetIpCommand()) .executableCommand(new GetIpCommand())
.build(); .build();
@ -170,7 +170,6 @@ public final class CommandInitializer {
.labels("spawn", "home") .labels("spawn", "home")
.description("Teleport to spawn") .description("Teleport to spawn")
.detailedDescription("Teleport to the spawn.") .detailedDescription("Teleport to the spawn.")
.withArgument("player", "Player Name", false)
.permissions(OP_ONLY, AdminPermission.SPAWN) .permissions(OP_ONLY, AdminPermission.SPAWN)
.executableCommand(new SpawnCommand()) .executableCommand(new SpawnCommand())
.build(); .build();

View File

@ -12,6 +12,7 @@ import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.process.Management; import fr.xephi.authme.process.Management;
import fr.xephi.authme.security.PasswordSecurity; import fr.xephi.authme.security.PasswordSecurity;
import fr.xephi.authme.settings.NewSetting; import fr.xephi.authme.settings.NewSetting;
import fr.xephi.authme.settings.SpawnLoader;
import fr.xephi.authme.settings.domain.Property; import fr.xephi.authme.settings.domain.Property;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@ -32,6 +33,7 @@ public class CommandService {
private final NewSetting settings; private final NewSetting settings;
private final IpAddressManager ipAddressManager; private final IpAddressManager ipAddressManager;
private final PluginHooks pluginHooks; private final PluginHooks pluginHooks;
private final SpawnLoader spawnLoader;
/** /**
* Constructor. * Constructor.
@ -47,7 +49,7 @@ public class CommandService {
*/ */
public CommandService(AuthMe authMe, CommandMapper commandMapper, HelpProvider helpProvider, Messages messages, public CommandService(AuthMe authMe, CommandMapper commandMapper, HelpProvider helpProvider, Messages messages,
PasswordSecurity passwordSecurity, PermissionsManager permissionsManager, NewSetting settings, PasswordSecurity passwordSecurity, PermissionsManager permissionsManager, NewSetting settings,
IpAddressManager ipAddressManager, PluginHooks pluginHooks) { IpAddressManager ipAddressManager, PluginHooks pluginHooks, SpawnLoader spawnLoader) {
this.authMe = authMe; this.authMe = authMe;
this.messages = messages; this.messages = messages;
this.helpProvider = helpProvider; this.helpProvider = helpProvider;
@ -57,6 +59,7 @@ public class CommandService {
this.settings = settings; this.settings = settings;
this.ipAddressManager = ipAddressManager; this.ipAddressManager = ipAddressManager;
this.pluginHooks = pluginHooks; this.pluginHooks = pluginHooks;
this.spawnLoader = spawnLoader;
} }
/** /**
@ -202,4 +205,8 @@ public class CommandService {
return pluginHooks; return pluginHooks;
} }
public SpawnLoader getSpawnLoader() {
return spawnLoader;
}
} }

View File

@ -1,9 +1,7 @@
package fr.xephi.authme.command.executable.authme; package fr.xephi.authme.command.executable.authme;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.command.CommandService; import fr.xephi.authme.command.CommandService;
import fr.xephi.authme.command.PlayerCommand; import fr.xephi.authme.command.PlayerCommand;
import fr.xephi.authme.settings.Spawn;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.List; import java.util.List;
@ -12,16 +10,10 @@ public class FirstSpawnCommand extends PlayerCommand {
@Override @Override
public void runCommand(Player player, List<String> arguments, CommandService commandService) { public void runCommand(Player player, List<String> arguments, CommandService commandService) {
// Make sure the command executor is a player if (commandService.getSpawnLoader().getFirstSpawn() != null) {
try { player.teleport(commandService.getSpawnLoader().getFirstSpawn());
if (Spawn.getInstance().getFirstSpawn() != null) {
player.teleport(Spawn.getInstance().getFirstSpawn());
} else { } else {
player.sendMessage("[AuthMe] First spawn has failed, please try to define the first spawn"); player.sendMessage("[AuthMe] First spawn has failed, please try to define the first spawn");
} }
} catch (NullPointerException ex) {
// TODO ljacqu 20151119: Catching NullPointerException is never a good idea. Find what can cause one instead
ConsoleLogger.showError(ex.getMessage());
}
} }
} }

View File

@ -1,9 +1,7 @@
package fr.xephi.authme.command.executable.authme; package fr.xephi.authme.command.executable.authme;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.command.CommandService; import fr.xephi.authme.command.CommandService;
import fr.xephi.authme.command.PlayerCommand; import fr.xephi.authme.command.PlayerCommand;
import fr.xephi.authme.settings.Spawn;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.List; import java.util.List;
@ -12,14 +10,10 @@ public class SetFirstSpawnCommand extends PlayerCommand {
@Override @Override
public void runCommand(Player player, List<String> arguments, CommandService commandService) { public void runCommand(Player player, List<String> arguments, CommandService commandService) {
try { if (commandService.getSpawnLoader().setFirstSpawn(player.getLocation())) {
if (Spawn.getInstance().setFirstSpawn(player.getLocation())) {
player.sendMessage("[AuthMe] Correctly defined new first spawn point"); player.sendMessage("[AuthMe] Correctly defined new first spawn point");
} else { } else {
player.sendMessage("[AuthMe] SetFirstSpawn has failed, please retry"); player.sendMessage("[AuthMe] SetFirstSpawn has failed, please retry");
} }
} catch (NullPointerException ex) {
ConsoleLogger.showError(ex.getMessage());
}
} }
} }

View File

@ -1,9 +1,7 @@
package fr.xephi.authme.command.executable.authme; package fr.xephi.authme.command.executable.authme;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.command.CommandService; import fr.xephi.authme.command.CommandService;
import fr.xephi.authme.command.PlayerCommand; import fr.xephi.authme.command.PlayerCommand;
import fr.xephi.authme.settings.Spawn;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.List; import java.util.List;
@ -12,14 +10,10 @@ public class SetSpawnCommand extends PlayerCommand {
@Override @Override
public void runCommand(Player player, List<String> arguments, CommandService commandService) { public void runCommand(Player player, List<String> arguments, CommandService commandService) {
try { if (commandService.getSpawnLoader().setSpawn(player.getLocation())) {
if (Spawn.getInstance().setSpawn(player.getLocation())) {
player.sendMessage("[AuthMe] Correctly defined new spawn point"); player.sendMessage("[AuthMe] Correctly defined new spawn point");
} else { } else {
player.sendMessage("[AuthMe] SetSpawn has failed, please retry"); player.sendMessage("[AuthMe] SetSpawn has failed, please retry");
} }
} catch (NullPointerException ex) {
ConsoleLogger.showError(ex.getMessage());
}
} }
} }

View File

@ -1,9 +1,7 @@
package fr.xephi.authme.command.executable.authme; package fr.xephi.authme.command.executable.authme;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.command.CommandService; import fr.xephi.authme.command.CommandService;
import fr.xephi.authme.command.PlayerCommand; import fr.xephi.authme.command.PlayerCommand;
import fr.xephi.authme.settings.Spawn;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.List; import java.util.List;
@ -12,14 +10,10 @@ public class SpawnCommand extends PlayerCommand {
@Override @Override
public void runCommand(Player player, List<String> arguments, CommandService commandService) { public void runCommand(Player player, List<String> arguments, CommandService commandService) {
try { if (commandService.getSpawnLoader().getSpawn() != null) {
if (Spawn.getInstance().getSpawn() != null) { player.teleport(commandService.getSpawnLoader().getSpawn());
player.teleport(Spawn.getInstance().getSpawn());
} else { } else {
player.sendMessage("[AuthMe] Spawn has failed, please try to define the spawn"); player.sendMessage("[AuthMe] Spawn has failed, please try to define the spawn");
} }
} catch (NullPointerException ex) {
ConsoleLogger.showError(ex.getMessage());
}
} }
} }

View File

@ -6,6 +6,7 @@ import fr.xephi.authme.hooks.PluginHooks;
import fr.xephi.authme.output.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages; import fr.xephi.authme.output.Messages;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.SpawnLoader;
import fr.xephi.authme.util.GeoLiteAPI; import fr.xephi.authme.util.GeoLiteAPI;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
@ -21,11 +22,13 @@ public class AuthMeServerListener implements Listener {
private final AuthMe plugin; private final AuthMe plugin;
private final Messages messages; private final Messages messages;
private final PluginHooks pluginHooks; private final PluginHooks pluginHooks;
private final SpawnLoader spawnLoader;
public AuthMeServerListener(AuthMe plugin, Messages messages, PluginHooks pluginHooks) { public AuthMeServerListener(AuthMe plugin, Messages messages, PluginHooks pluginHooks, SpawnLoader spawnLoader) {
this.plugin = plugin; this.plugin = plugin;
this.messages = messages; this.messages = messages;
this.pluginHooks = pluginHooks; this.pluginHooks = pluginHooks;
this.spawnLoader = spawnLoader;
} }
@EventHandler(priority = EventPriority.HIGHEST) @EventHandler(priority = EventPriority.HIGHEST)
@ -60,7 +63,7 @@ public class AuthMeServerListener implements Listener {
pluginHooks.unhookCombatPlus(); pluginHooks.unhookCombatPlus();
ConsoleLogger.info("CombatTagPlus has been disabled: unhooking"); ConsoleLogger.info("CombatTagPlus has been disabled: unhooking");
} else if ("EssentialsSpawn".equalsIgnoreCase(pluginName)) { } else if ("EssentialsSpawn".equalsIgnoreCase(pluginName)) {
plugin.essentialsSpawn = null; spawnLoader.unloadEssentialsSpawn();
ConsoleLogger.info("EssentialsSpawn has been disabled: unhooking"); ConsoleLogger.info("EssentialsSpawn has been disabled: unhooking");
} }
@ -87,7 +90,7 @@ public class AuthMeServerListener implements Listener {
} else if ("CombatTagPlus".equalsIgnoreCase(pluginName)) { } else if ("CombatTagPlus".equalsIgnoreCase(pluginName)) {
pluginHooks.tryHookToCombatPlus(); pluginHooks.tryHookToCombatPlus();
} else if ("EssentialsSpawn".equalsIgnoreCase(pluginName)) { } else if ("EssentialsSpawn".equalsIgnoreCase(pluginName)) {
plugin.checkEssentialsSpawn(); spawnLoader.loadEssentialsSpawn();
} }
if (pluginName.equalsIgnoreCase("ProtocolLib")) { if (pluginName.equalsIgnoreCase("ProtocolLib")) {

View File

@ -8,6 +8,7 @@ import fr.xephi.authme.output.Messages;
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.settings.NewSetting; import fr.xephi.authme.settings.NewSetting;
import fr.xephi.authme.settings.SpawnLoader;
import fr.xephi.authme.settings.domain.Property; import fr.xephi.authme.settings.domain.Property;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.event.Event; import org.bukkit.event.Event;
@ -24,15 +25,17 @@ public class ProcessService {
private final IpAddressManager ipAddressManager; private final IpAddressManager ipAddressManager;
private final PasswordSecurity passwordSecurity; private final PasswordSecurity passwordSecurity;
private final PluginHooks pluginHooks; private final PluginHooks pluginHooks;
private final SpawnLoader spawnLoader;
public ProcessService(NewSetting settings, Messages messages, AuthMe authMe, IpAddressManager ipAddressManager, public ProcessService(NewSetting settings, Messages messages, AuthMe authMe, IpAddressManager ipAddressManager,
PasswordSecurity passwordSecurity, PluginHooks pluginHooks) { PasswordSecurity passwordSecurity, PluginHooks pluginHooks, SpawnLoader spawnLoader) {
this.settings = settings; this.settings = settings;
this.messages = messages; this.messages = messages;
this.authMe = authMe; this.authMe = authMe;
this.ipAddressManager = ipAddressManager; this.ipAddressManager = ipAddressManager;
this.passwordSecurity = passwordSecurity; this.passwordSecurity = passwordSecurity;
this.pluginHooks = pluginHooks; this.pluginHooks = pluginHooks;
this.spawnLoader = spawnLoader;
} }
public <T> T getProperty(Property<T> property) { public <T> T getProperty(Property<T> property) {
@ -91,4 +94,8 @@ public class ProcessService {
return pluginHooks; return pluginHooks;
} }
public SpawnLoader getSpawnLoader() {
return spawnLoader;
}
} }

View File

@ -16,7 +16,6 @@ import fr.xephi.authme.process.Process;
import fr.xephi.authme.process.ProcessService; import fr.xephi.authme.process.ProcessService;
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.Spawn;
import fr.xephi.authme.settings.properties.HooksSettings; import fr.xephi.authme.settings.properties.HooksSettings;
import fr.xephi.authme.settings.properties.PluginSettings; import fr.xephi.authme.settings.properties.PluginSettings;
import fr.xephi.authme.settings.properties.RegistrationSettings; import fr.xephi.authme.settings.properties.RegistrationSettings;
@ -90,7 +89,7 @@ public class AsynchronousJoin implements Process {
}); });
return; return;
} }
final Location spawnLoc = Spawn.getInstance().getSpawnLocation(player); final Location spawnLoc = service.getSpawnLoader().getSpawnLocation(player);
final boolean isAuthAvailable = database.isAuthAvailable(name); final boolean isAuthAvailable = database.isAuthAvailable(name);
if (isAuthAvailable) { if (isAuthAvailable) {
if (!Settings.noTeleport) { if (!Settings.noTeleport) {
@ -212,11 +211,14 @@ public class AsynchronousJoin implements Process {
} }
private boolean needFirstSpawn() { private boolean needFirstSpawn() {
if (player.hasPlayedBefore()) if (player.hasPlayedBefore()) {
return false; return false;
Location firstSpawn = Spawn.getInstance().getFirstSpawn(); }
if (firstSpawn == null || firstSpawn.getWorld() == null) Location firstSpawn = service.getSpawnLoader().getFirstSpawn();
if (firstSpawn == null) {
return false; return false;
}
FirstSpawnTeleportEvent tpEvent = new FirstSpawnTeleportEvent(player, player.getLocation(), firstSpawn); FirstSpawnTeleportEvent tpEvent = new FirstSpawnTeleportEvent(player, player.getLocation(), firstSpawn);
plugin.getServer().getPluginManager().callEvent(tpEvent); plugin.getServer().getPluginManager().callEvent(tpEvent);
if (!tpEvent.isCancelled()) { if (!tpEvent.isCancelled()) {

View File

@ -24,7 +24,7 @@ import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import static fr.xephi.authme.settings.SettingsMigrationService.copyFileFromResource; import static fr.xephi.authme.util.FileUtils.copyFileFromResource;
/** /**
* The new settings manager. * The new settings manager.

View File

@ -1,7 +1,6 @@
package fr.xephi.authme.settings; package fr.xephi.authme.settings;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.settings.domain.Property; import fr.xephi.authme.settings.domain.Property;
import fr.xephi.authme.settings.propertymap.PropertyMap; import fr.xephi.authme.settings.propertymap.PropertyMap;
@ -10,14 +9,11 @@ import org.bukkit.configuration.file.FileConfiguration;
import java.io.File; import java.io.File;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import static fr.xephi.authme.settings.properties.RegistrationSettings.DELAY_JOIN_MESSAGE; import static fr.xephi.authme.settings.properties.RegistrationSettings.DELAY_JOIN_MESSAGE;
import static fr.xephi.authme.settings.properties.RegistrationSettings.REMOVE_JOIN_MESSAGE; import static fr.xephi.authme.settings.properties.RegistrationSettings.REMOVE_JOIN_MESSAGE;
import static fr.xephi.authme.settings.properties.RegistrationSettings.REMOVE_LEAVE_MESSAGE; import static fr.xephi.authme.settings.properties.RegistrationSettings.REMOVE_LEAVE_MESSAGE;
import static fr.xephi.authme.settings.properties.RestrictionSettings.ALLOWED_NICKNAME_CHARACTERS; import static fr.xephi.authme.settings.properties.RestrictionSettings.ALLOWED_NICKNAME_CHARACTERS;
import static java.lang.String.format;
/** /**
* Service for verifying that the configuration is up-to-date. * Service for verifying that the configuration is up-to-date.
@ -131,41 +127,4 @@ public final class SettingsMigrationService {
return false; return false;
} }
// -------
// Utilities
// -------
/**
* Copy a resource file (from the JAR) to the given file if it doesn't exist.
*
* @param destinationFile The file to check and copy to (outside of JAR)
* @param resourcePath Absolute path to the resource file (path to file within JAR)
* @return False if the file does not exist and could not be copied, true otherwise
*/
public static boolean copyFileFromResource(File destinationFile, String resourcePath) {
if (destinationFile.exists()) {
return true;
} else if (!destinationFile.getParentFile().exists() && !destinationFile.getParentFile().mkdirs()) {
ConsoleLogger.showError("Cannot create parent directories for '" + destinationFile + "'");
return false;
}
// ClassLoader#getResourceAsStream does not deal with the '\' path separator: replace to '/'
final String normalizedPath = resourcePath.replace("\\", "/");
try (InputStream is = AuthMe.class.getClassLoader().getResourceAsStream(normalizedPath)) {
if (is == null) {
ConsoleLogger.showError(format("Cannot copy resource '%s' to file '%s': cannot load resource",
resourcePath, destinationFile.getPath()));
} else {
Files.copy(is, destinationFile.toPath());
return true;
}
} catch (IOException e) {
ConsoleLogger.logException(format("Cannot copy resource '%s' to file '%s':",
resourcePath, destinationFile.getPath()), e);
}
return false;
}
} }

View File

@ -1,144 +0,0 @@
package fr.xephi.authme.settings;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.util.StringUtils;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Player;
import java.io.File;
/**
* @author Xephi59
* @version $Revision: 1.0 $
*/
public class Spawn extends CustomConfiguration {
private static Spawn spawn;
private static String[] spawnPriority;
private Spawn() {
super(new File(Settings.PLUGIN_FOLDER, "spawn.yml"));
load();
save();
spawnPriority = Settings.spawnPriority.split(",");
}
public static void reload() {
spawn = new Spawn();
}
/**
* Method getInstance.
*
* @return Spawn
*/
public static Spawn getInstance() {
if (spawn == null) {
spawn = new Spawn();
}
return spawn;
}
public boolean setSpawn(Location location) {
if (location == null || location.getWorld() == null) {
return false;
}
set("spawn.world", location.getWorld().getName());
set("spawn.x", location.getX());
set("spawn.y", location.getY());
set("spawn.z", location.getZ());
set("spawn.yaw", location.getYaw());
set("spawn.pitch", location.getPitch());
save();
return true;
}
public boolean setFirstSpawn(Location location) {
if (location == null || location.getWorld() == null) {
return false;
}
set("firstspawn.world", location.getWorld().getName());
set("firstspawn.x", location.getX());
set("firstspawn.y", location.getY());
set("firstspawn.z", location.getZ());
set("firstspawn.yaw", location.getYaw());
set("firstspawn.pitch", location.getPitch());
save();
return true;
}
public Location getSpawn() {
if (containsAll("spawn.world", "spawn.x", "spawn.y", "spawn.z", "spawn.yaw", "spawn.pitch")) {
String worldName = getString("spawn.world");
World world = Bukkit.getWorld(worldName);
if (!StringUtils.isEmpty(worldName) && world != null) {
return new Location(
world, getDouble("spawn.x"), getDouble("spawn.y"), getDouble("spawn.z"),
Float.parseFloat(getString("spawn.yaw")), Float.parseFloat(getString("spawn.pitch"))
);
}
}
return null;
}
public Location getFirstSpawn() {
if (containsAll("firstspawn.world", "firstspawn.x", "firstspawn.y",
"firstspawn.z", "firstspawn.yaw", "firstspawn.pitch")) {
String worldName = getString("firstspawn.world");
World world = Bukkit.getWorld(worldName);
if (!StringUtils.isEmpty(worldName) && world != null) {
return new Location(
world, getDouble("firstspawn.x"), getDouble("firstspawn.y"), getDouble("firstspawn.z"),
Float.parseFloat(getString("firstspawn.yaw")), Float.parseFloat(getString("firstspawn.pitch"))
);
}
}
return null;
}
// Return the spawn location of a player
public Location getSpawnLocation(Player player) {
AuthMe plugin = AuthMe.getInstance();
if (plugin == null || player == null || player.getWorld() == null) {
return null;
}
World world = player.getWorld();
Location spawnLoc = null;
for (String priority : spawnPriority) {
switch (priority.toLowerCase()) {
case "default":
if (world.getSpawnLocation() != null) {
spawnLoc = world.getSpawnLocation();
}
break;
case "multiverse":
if (Settings.multiverse) {
spawnLoc = plugin.getPluginHooks().getMultiverseSpawn(world);
}
break;
case "essentials":
spawnLoc = plugin.essentialsSpawn;
break;
case "authme":
String playerNameLower = player.getName().toLowerCase();
if (PlayerCache.getInstance().isAuthenticated(playerNameLower)) {
spawnLoc = getSpawn();
} else if ((getFirstSpawn() != null) && (!player.hasPlayedBefore() ||
(!plugin.getDataSource().isAuthAvailable(playerNameLower)))) {
spawnLoc = getFirstSpawn();
} else {
spawnLoc = getSpawn();
}
break;
}
if (spawnLoc != null) {
return spawnLoc;
}
}
return world.getSpawnLocation(); // return default location
}
}

View File

@ -0,0 +1,261 @@
package fr.xephi.authme.settings;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.hooks.PluginHooks;
import fr.xephi.authme.settings.properties.RestrictionSettings;
import fr.xephi.authme.util.FileUtils;
import fr.xephi.authme.util.StringUtils;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import java.io.File;
import java.io.IOException;
/**
* Manager for spawn points. It loads spawn definitions from AuthMe and third-party plugins
* and is responsible for returning the correct spawn point as per the settings.
* <p>
* The spawn priority setting defines from which sources and in which order the spawn point
* should be taken from. In AuthMe, we can distinguish between the regular spawn and a "first spawn",
* to which players will be teleported who have joined for the first time.
*/
public class SpawnLoader {
private final File authMeConfigurationFile;
private final PluginHooks pluginHooks;
private FileConfiguration authMeConfiguration;
private String[] spawnPriority;
private Location essentialsSpawn;
/**
* Constructor.
*
* @param pluginFolder The AuthMe data folder
* @param settings The setting instance
* @param pluginHooks The plugin hooks instance
*/
public SpawnLoader(File pluginFolder, NewSetting settings, PluginHooks pluginHooks) {
File spawnFile = new File(pluginFolder, "spawn.yml");
// TODO ljacqu 20160312: Check if resource could be copied and handle the case if not
FileUtils.copyFileFromResource(spawnFile, "spawn.yml");
this.authMeConfigurationFile = new File(pluginFolder, "spawn.yml");
this.pluginHooks = pluginHooks;
initialize(settings);
}
/**
* Retrieve the relevant settings and load the AuthMe spawn.yml file.
*
* @param settings The settings instance
*/
public void initialize(NewSetting settings) {
spawnPriority = settings.getProperty(RestrictionSettings.SPAWN_PRIORITY).split(",");
authMeConfiguration = YamlConfiguration.loadConfiguration(authMeConfigurationFile);
loadEssentialsSpawn();
}
/**
* Return the AuthMe spawn location.
*
* @return The location of the regular AuthMe spawn point
*/
public Location getSpawn() {
return getLocationFromConfiguration(authMeConfiguration, "spawn");
}
/**
* Set the AuthMe spawn point.
*
* @param location The location to use
* @return True upon success, false otherwise
*/
public boolean setSpawn(Location location) {
return setLocation("spawn", location);
}
/**
* Return the AuthMe first spawn location.
*
* @return The location of the AuthMe spawn point for first timers
*/
public Location getFirstSpawn() {
return getLocationFromConfiguration(authMeConfiguration, "firstspawn");
}
/**
* Set the AuthMe first spawn location.
*
* @param location The location to use
* @return True upon success, false otherwise
*/
public boolean setFirstSpawn(Location location) {
return setLocation("firstspawn", location);
}
/**
* Load the spawn point defined in EssentialsSpawn.
*/
public void loadEssentialsSpawn() {
// EssentialsSpawn cannot run without Essentials, so it's fine to get the Essentials data folder
File essentialsFolder = pluginHooks.getEssentialsDataFolder();
if (essentialsFolder == null) {
return;
}
File essentialsSpawnFile = new File(essentialsFolder, "spawn.yml");
if (essentialsSpawnFile.exists()) {
essentialsSpawn = getLocationFromConfiguration(
YamlConfiguration.loadConfiguration(essentialsSpawnFile), "spawns.default");
} else {
essentialsSpawn = null;
ConsoleLogger.info("Essentials spawn file not found: '" + essentialsSpawnFile.getAbsolutePath() + "'");
}
}
/**
* Unset the spawn point defined in EssentialsSpawn.
*/
public void unloadEssentialsSpawn() {
essentialsSpawn = null;
}
/**
* Return the spawn location for the given player. The source of the spawn location varies
* depending on the spawn priority setting.
*
* @param player The player to retrieve the spawn point for
* @return The spawn location, or the default spawn location upon failure
* @see RestrictionSettings#SPAWN_PRIORITY
*/
public Location getSpawnLocation(Player player) {
AuthMe plugin = AuthMe.getInstance();
if (plugin == null || player == null || player.getWorld() == null) {
return null;
}
World world = player.getWorld();
Location spawnLoc = null;
// TODO ljacqu 20160312: We should trim() the entries
for (String priority : spawnPriority) {
switch (priority.toLowerCase()) {
case "default":
if (world.getSpawnLocation() != null) {
spawnLoc = world.getSpawnLocation();
}
break;
case "multiverse":
if (Settings.multiverse) {
spawnLoc = pluginHooks.getMultiverseSpawn(world);
}
break;
case "essentials":
spawnLoc = essentialsSpawn;
break;
case "authme":
String playerNameLower = player.getName().toLowerCase();
if (PlayerCache.getInstance().isAuthenticated(playerNameLower)) {
spawnLoc = getSpawn();
} else if (getFirstSpawn() != null && (!player.hasPlayedBefore() ||
!plugin.getDataSource().isAuthAvailable(playerNameLower))) {
spawnLoc = getFirstSpawn();
} else {
spawnLoc = getSpawn();
}
break;
}
if (spawnLoc != null) {
return spawnLoc;
}
}
return world.getSpawnLocation(); // return default location
}
/**
* Save the location under the given prefix.
*
* @param prefix The prefix to save the spawn under
* @param location The location to persist
* @return True upon success, false otherwise
*/
private boolean setLocation(String prefix, Location location) {
if (location != null && location.getWorld() != null) {
authMeConfiguration.set(prefix + ".world", location.getWorld().getName());
authMeConfiguration.set(prefix + ".x", location.getX());
authMeConfiguration.set(prefix + ".y", location.getY());
authMeConfiguration.set(prefix + ".z", location.getZ());
authMeConfiguration.set(prefix + ".yaw", location.getYaw());
authMeConfiguration.set(prefix + ".pitch", location.getPitch());
return saveAuthMeConfig();
}
return false;
}
private boolean saveAuthMeConfig() {
// TODO ljacqu 20160312: Investigate whether this utility should be put in a Utils class
try {
authMeConfiguration.save(authMeConfigurationFile);
return true;
} catch (IOException e) {
ConsoleLogger.logException("Could not save spawn config (" + authMeConfigurationFile + ")", e);
}
return false;
}
/**
* Build a {@link Location} object from the given path in the file configuration.
*
* @param configuration The file configuration to read from
* @param pathPrefix The path to get the spawn point from
* @return Location corresponding to the values in the path
*/
private static Location getLocationFromConfiguration(FileConfiguration configuration, String pathPrefix) {
if (containsAllSpawnFields(configuration, pathPrefix)) {
String prefix = pathPrefix + ".";
String worldName = configuration.getString(prefix + "world");
World world = Bukkit.getWorld(worldName);
if (!StringUtils.isEmpty(worldName) && world != null) {
return new Location(world, configuration.getDouble(prefix + "x"),
configuration.getDouble(prefix + "y"), configuration.getDouble(prefix + "z"),
getFloat(configuration, prefix + "yaw"), getFloat(configuration, prefix + "pitch"));
}
}
return null;
}
/**
* Return whether the file configuration contains all fields necessary to define a spawn
* under the given path.
*
* @param configuration The file configuration to use
* @param pathPrefix The path to verify
* @return True if all spawn fields are present, false otherwise
*/
private static boolean containsAllSpawnFields(FileConfiguration configuration, String pathPrefix) {
String[] fields = {"world", "x", "y", "z", "yaw", "pitch"};
for (String field : fields) {
if (!configuration.contains(pathPrefix + "." + field)) {
return false;
}
}
return true;
}
/**
* Retrieve a property as a float from the given file configuration.
*
* @param configuration The file configuration to use
* @param path The path of the property to retrieve
* @return The float
*/
private static float getFloat(FileConfiguration configuration, String path) {
Object value = configuration.get(path);
// This behavior is consistent with FileConfiguration#getDouble
return (value instanceof Number) ? ((Number) value).floatValue() : 0;
}
}

View File

@ -0,0 +1,52 @@
package fr.xephi.authme.util;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ConsoleLogger;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import static java.lang.String.format;
/**
* File utilities.
*/
public class FileUtils {
private FileUtils() {
}
/**
* Copy a resource file (from the JAR) to the given file if it doesn't exist.
*
* @param destinationFile The file to check and copy to (outside of JAR)
* @param resourcePath Absolute path to the resource file (path to file within JAR)
* @return False if the file does not exist and could not be copied, true otherwise
*/
public static boolean copyFileFromResource(File destinationFile, String resourcePath) {
if (destinationFile.exists()) {
return true;
} else if (!destinationFile.getParentFile().exists() && !destinationFile.getParentFile().mkdirs()) {
ConsoleLogger.showError("Cannot create parent directories for '" + destinationFile + "'");
return false;
}
// ClassLoader#getResourceAsStream does not deal with the '\' path separator: replace to '/'
final String normalizedPath = resourcePath.replace("\\", "/");
try (InputStream is = AuthMe.class.getClassLoader().getResourceAsStream(normalizedPath)) {
if (is == null) {
ConsoleLogger.showError(format("Cannot copy resource '%s' to file '%s': cannot load resource",
resourcePath, destinationFile.getPath()));
} else {
Files.copy(is, destinationFile.toPath());
return true;
}
} catch (IOException e) {
ConsoleLogger.logException(format("Cannot copy resource '%s' to file '%s':",
resourcePath, destinationFile.getPath()), e);
}
return false;
}
}

View File

@ -11,6 +11,7 @@ import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.process.Management; import fr.xephi.authme.process.Management;
import fr.xephi.authme.security.PasswordSecurity; import fr.xephi.authme.security.PasswordSecurity;
import fr.xephi.authme.settings.NewSetting; import fr.xephi.authme.settings.NewSetting;
import fr.xephi.authme.settings.SpawnLoader;
import fr.xephi.authme.settings.domain.Property; import fr.xephi.authme.settings.domain.Property;
import fr.xephi.authme.settings.properties.SecuritySettings; import fr.xephi.authme.settings.properties.SecuritySettings;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@ -44,6 +45,7 @@ public class CommandServiceTest {
private NewSetting settings; private NewSetting settings;
private IpAddressManager ipAddressManager; private IpAddressManager ipAddressManager;
private PluginHooks pluginHooks; private PluginHooks pluginHooks;
private SpawnLoader spawnLoader;
@Before @Before
public void setUpService() { public void setUpService() {
@ -56,8 +58,9 @@ public class CommandServiceTest {
settings = mock(NewSetting.class); settings = mock(NewSetting.class);
ipAddressManager = mock(IpAddressManager.class); ipAddressManager = mock(IpAddressManager.class);
pluginHooks = mock(PluginHooks.class); pluginHooks = mock(PluginHooks.class);
spawnLoader = mock(SpawnLoader.class);
commandService = new CommandService(authMe, commandMapper, helpProvider, messages, passwordSecurity, commandService = new CommandService(authMe, commandMapper, helpProvider, messages, passwordSecurity,
permissionsManager, settings, ipAddressManager, pluginHooks); permissionsManager, settings, ipAddressManager, pluginHooks, spawnLoader);
} }
@Test @Test

View File

@ -0,0 +1,68 @@
package fr.xephi.authme.settings;
import com.google.common.io.Files;
import fr.xephi.authme.TestHelper;
import fr.xephi.authme.hooks.PluginHooks;
import fr.xephi.authme.settings.properties.RestrictionSettings;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.configuration.file.YamlConfiguration;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import java.io.File;
import java.io.IOException;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
/**
* Test for {@link SpawnLoader}.
*/
public class SpawnLoaderTest {
@Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder();
private File testFolder;
private NewSetting settings;
@Before
public void setup() throws IOException {
// Copy test config into a new temporary folder
testFolder = temporaryFolder.newFolder();
File source = TestHelper.getJarFile("/spawn/spawn-firstspawn.yml");
File destination = new File(testFolder, "spawn.yml");
Files.copy(source, destination);
// Create a settings mock with default values
settings = mock(NewSetting.class);
given(settings.getProperty(RestrictionSettings.SPAWN_PRIORITY))
.willReturn("authme, essentials, multiverse, default");
}
@Test
public void shouldSetSpawn() {
// given
SpawnLoader spawnLoader = new SpawnLoader(testFolder, settings, mock(PluginHooks.class));
World world = mock(World.class);
given(world.getName()).willReturn("new_world");
Location newSpawn = new Location(world, 123, 45.0, -67.89);
// when
boolean result = spawnLoader.setSpawn(newSpawn);
// then
assertThat(result, equalTo(true));
YamlConfiguration configuration = YamlConfiguration.loadConfiguration(new File(testFolder, "spawn.yml"));
assertThat(configuration.getDouble("spawn.x"), equalTo(123.0));
assertThat(configuration.getDouble("spawn.y"), equalTo(45.0));
assertThat(configuration.getDouble("spawn.z"), equalTo(-67.89));
assertThat(configuration.getString("spawn.world"), equalTo("new_world"));
}
}

View File

@ -0,0 +1,15 @@
# Sample spawn.yml file with both spawn and firstspawn defined
spawn:
world: 'world'
x: 300.12
y: 120.34
z: -89.12
yaw: 0.23
pitch: 112.25
firstspawn:
world: 'firstspawn'
x: -30.12
y: 204.43
z: 10.32
yaw: 0.00
pitch: 10.23