From c7c8e673f01643bf87a86fb2ed37c47a3a68d91c Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Tue, 28 Nov 2017 12:57:39 +0100 Subject: [PATCH] #1423 Implement CMI spawn integration --- docs/config.md | 24 +++---- .../xephi/authme/listener/ServerListener.java | 7 ++ .../authme/service/PluginHookService.java | 45 +++++++++++- .../fr/xephi/authme/settings/SpawnLoader.java | 72 +++++++++++++++++++ .../properties/RestrictionSettings.java | 4 +- .../authme/listener/ServerListenerTest.java | 9 +++ 6 files changed, 145 insertions(+), 16 deletions(-) diff --git a/docs/config.md b/docs/config.md index 0e4435c90..2483ed4fb 100644 --- a/docs/config.md +++ b/docs/config.md @@ -1,8 +1,8 @@ - + ## AuthMe Configuration -The first time you run AuthMe it will create a config.yml file in the plugins/AuthMe folder, +The first time you run AuthMe it will create a config.yml file in the plugins/AuthMe folder, with which you can configure various settings. This following is the initial contents of the generated config.yml file. @@ -131,7 +131,7 @@ settings: # Hide the chat log from players who are not authenticated? hideChat: false # Allowed commands for unauthenticated players - allowCommands: + allowCommands: - '/login' - '/register' - '/l' @@ -158,7 +158,7 @@ settings: enabled: false # WorldNames where we need to force the spawn location # Case-sensitive! - worlds: + worlds: - 'world' - 'world_nether' - 'world_the_end' @@ -202,8 +202,8 @@ settings: # Should we display all other accounts from a player when he joins? # permission: /authme.admin.accounts displayOtherAccounts: true - # Spawn priority; values: authme, essentials, multiverse, default - spawnPriority: 'authme,essentials,multiverse,default' + # Spawn priority; values: authme, essentials, cmi, multiverse, default + spawnPriority: 'authme,essentials,cmi,multiverse,default' # Maximum Login authorized by IP maxLoginPerIp: 0 # Maximum Join authorized by IP @@ -258,7 +258,7 @@ settings: # - '123456' # - 'password' # - 'help' - unsafePasswords: + unsafePasswords: - '123456' - 'password' - 'qwerty' @@ -364,7 +364,7 @@ Email: # Delay in minute for the recall scheduler delayRecall: 5 # Blacklist these domains for emails - emailBlacklisted: + emailBlacklisted: - '10minutemail.com' # Whitelist ONLY these domains for emails emailWhitelisted: [] @@ -391,12 +391,12 @@ Protection: # Countries allowed to join the server and register. For country codes, see # http://dev.maxmind.com/geoip/legacy/codes/iso3166/ # PLEASE USE QUOTES! - countries: + countries: - 'US' - 'GB' # Countries not allowed to join the server and register # PLEASE USE QUOTES! - countriesBlacklist: + countriesBlacklist: - 'A1' # Do we need to enable automatic antibot system? enableAntiBot: true @@ -555,9 +555,9 @@ Converter: password: '' ``` -To change settings on a running server, save your changes to config.yml and use +To change settings on a running server, save your changes to config.yml and use `/authme reload`. --- -This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Tue Oct 31 15:56:59 CET 2017 +This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Tue Nov 28 12:49:57 CET 2017 diff --git a/src/main/java/fr/xephi/authme/listener/ServerListener.java b/src/main/java/fr/xephi/authme/listener/ServerListener.java index 055e72af0..f424fc37f 100644 --- a/src/main/java/fr/xephi/authme/listener/ServerListener.java +++ b/src/main/java/fr/xephi/authme/listener/ServerListener.java @@ -40,6 +40,10 @@ public class ServerListener implements Listener { if ("Essentials".equalsIgnoreCase(pluginName)) { pluginHookService.unhookEssentials(); ConsoleLogger.info("Essentials has been disabled: unhooking"); + } else if ("CMI".equalsIgnoreCase(pluginName)) { + pluginHookService.unhookCMI(); + spawnLoader.unloadCMISpawn(); + ConsoleLogger.info("CMI has been disabled: unhooking"); } else if ("Multiverse-Core".equalsIgnoreCase(pluginName)) { pluginHookService.unhookMultiverse(); ConsoleLogger.info("Multiverse-Core has been disabled: unhooking"); @@ -70,6 +74,9 @@ public class ServerListener implements Listener { pluginHookService.tryHookToMultiverse(); } else if ("EssentialsSpawn".equalsIgnoreCase(pluginName)) { spawnLoader.loadEssentialsSpawn(); + } else if ("CMI".equalsIgnoreCase(pluginName)) { + pluginHookService.tryHookToCMI(); + spawnLoader.loadCMISpawn(); } else if ("ProtocolLib".equalsIgnoreCase(pluginName)) { protocolLibService.setup(); } diff --git a/src/main/java/fr/xephi/authme/service/PluginHookService.java b/src/main/java/fr/xephi/authme/service/PluginHookService.java index af86b8a3a..0ae10a7c1 100644 --- a/src/main/java/fr/xephi/authme/service/PluginHookService.java +++ b/src/main/java/fr/xephi/authme/service/PluginHookService.java @@ -22,6 +22,7 @@ public class PluginHookService { private final PluginManager pluginManager; private Essentials essentials; + private Plugin cmi; private MultiverseCore multiverse; /** @@ -33,6 +34,7 @@ public class PluginHookService { public PluginHookService(PluginManager pluginManager) { this.pluginManager = pluginManager; tryHookToEssentials(); + tryHookToCMI(); tryHookToMultiverse(); } @@ -60,6 +62,19 @@ public class PluginHookService { return null; } + /** + * If CMI is hooked into, return CMI' data folder. + * + * @return The CMI data folder, or null if unavailable + */ + public File getCMIDataFolder() { + Plugin plugin = pluginManager.getPlugin("CMI"); + if(plugin == null) { + return null; + } + return plugin.getDataFolder(); + } + /** * Return the spawn of the given world as defined by Multiverse (if available). * @@ -76,10 +91,10 @@ public class PluginHookService { return null; } - // ------ // "Is plugin available" methods // ------ + /** * @return true if we have a hook to Essentials, false otherwise */ @@ -87,6 +102,13 @@ public class PluginHookService { return essentials != null; } + /** + * @return true if we have a hook to CMI, false otherwise + */ + public boolean isCMIAvailable() { + return cmi != null; + } + /** * @return true if we have a hook to Multiverse, false otherwise */ @@ -109,6 +131,17 @@ public class PluginHookService { } } + /** + * Attempts to create a hook into CMI. + */ + public void tryHookToCMI() { + try { + cmi = getPlugin(pluginManager, "CMI", Plugin.class); + } catch (Exception | NoClassDefFoundError ignored) { + cmi = null; + } + } + /** * Attempts to create a hook into Multiverse. */ @@ -123,6 +156,7 @@ public class PluginHookService { // ------ // Unhook methods // ------ + /** * Unhooks from Essentials. */ @@ -130,6 +164,13 @@ public class PluginHookService { essentials = null; } + /** + * Unhooks from CMI. + */ + public void unhookCMI() { + cmi = null; + } + /** * Unhooks from Multiverse. */ @@ -140,6 +181,7 @@ public class PluginHookService { // ------ // Helpers // ------ + private static T getPlugin(PluginManager pluginManager, String name, Class clazz) throws Exception, NoClassDefFoundError { if (pluginManager.isPluginEnabled(name)) { @@ -150,5 +192,4 @@ public class PluginHookService { return null; } - } diff --git a/src/main/java/fr/xephi/authme/settings/SpawnLoader.java b/src/main/java/fr/xephi/authme/settings/SpawnLoader.java index 09442ed44..f64c68488 100644 --- a/src/main/java/fr/xephi/authme/settings/SpawnLoader.java +++ b/src/main/java/fr/xephi/authme/settings/SpawnLoader.java @@ -35,6 +35,7 @@ public class SpawnLoader implements Reloadable { private FileConfiguration authMeConfiguration; private String[] spawnPriority; private Location essentialsSpawn; + private Location cmiSpawn; /** * Constructor. @@ -130,6 +131,32 @@ public class SpawnLoader implements Reloadable { essentialsSpawn = null; } + /** + * Load the spawn point defined in CMI. + */ + public void loadCMISpawn() { + File cmiFolder = pluginHookService.getCMIDataFolder(); + if (cmiFolder == null) { + return; + } + + File cmiConfig = new File(cmiFolder, "config.yml"); + if (cmiConfig.exists()) { + cmiSpawn = getLocationFromConfigurationUpper( + YamlConfiguration.loadConfiguration(cmiConfig), "Spawn.Main"); + } else { + cmiSpawn = null; + ConsoleLogger.info("CMI config file not found: '" + cmiConfig.getAbsolutePath() + "'"); + } + } + + /** + * Unset the spawn point defined in CMI. + */ + public void unloadCMISpawn() { + cmiSpawn = null; + } + /** * Return the spawn location for the given player. The source of the spawn location varies * depending on the spawn priority setting. @@ -162,6 +189,9 @@ public class SpawnLoader implements Reloadable { case "essentials": spawnLoc = essentialsSpawn; break; + case "cmi": + spawnLoc = cmiSpawn; + break; case "authme": spawnLoc = getSpawn(); break; @@ -242,6 +272,28 @@ public class SpawnLoader implements Reloadable { return null; } + /** + * 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 getLocationFromConfigurationUpper(FileConfiguration configuration, String pathPrefix) { + if (containsAllSpawnFieldsUpper(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. @@ -261,6 +313,25 @@ public class SpawnLoader implements Reloadable { return true; } + /** + * 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 containsAllSpawnFieldsUpper(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. * @@ -274,4 +345,5 @@ public class SpawnLoader implements Reloadable { // This behavior is consistent with FileConfiguration#getDouble return (value instanceof Number) ? ((Number) value).floatValue() : 0; } + } diff --git a/src/main/java/fr/xephi/authme/settings/properties/RestrictionSettings.java b/src/main/java/fr/xephi/authme/settings/properties/RestrictionSettings.java index ab202d2f1..a53eaa765 100644 --- a/src/main/java/fr/xephi/authme/settings/properties/RestrictionSettings.java +++ b/src/main/java/fr/xephi/authme/settings/properties/RestrictionSettings.java @@ -140,9 +140,9 @@ public final class RestrictionSettings implements SettingsHolder { public static final Property DISPLAY_OTHER_ACCOUNTS = newProperty("settings.restrictions.displayOtherAccounts", true); - @Comment("Spawn priority; values: authme, essentials, multiverse, default") + @Comment("Spawn priority; values: authme, essentials, cmi, multiverse, default") public static final Property SPAWN_PRIORITY = - newProperty("settings.restrictions.spawnPriority", "authme,essentials,multiverse,default"); + newProperty("settings.restrictions.spawnPriority", "authme,essentials,cmi,multiverse,default"); @Comment("Maximum Login authorized by IP") public static final Property MAX_LOGIN_PER_IP = diff --git a/src/test/java/fr/xephi/authme/listener/ServerListenerTest.java b/src/test/java/fr/xephi/authme/listener/ServerListenerTest.java index 2ffe57f58..29b484ad5 100644 --- a/src/test/java/fr/xephi/authme/listener/ServerListenerTest.java +++ b/src/test/java/fr/xephi/authme/listener/ServerListenerTest.java @@ -31,6 +31,7 @@ public class ServerListenerTest { private static final String ESSENTIALS = "Essentials"; private static final String ESSENTIALS_SPAWN = "EssentialsSpawn"; + private static final String CMI = "CMI"; private static final String MULTIVERSE = "Multiverse-Core"; private static final String PROTOCOL_LIB = "ProtocolLib"; @@ -58,6 +59,10 @@ public class ServerListenerTest { public void shouldForwardPluginNameOnEnable() { checkEnableHandling(ESSENTIALS, () -> verify(pluginHookService).tryHookToEssentials()); checkEnableHandling(ESSENTIALS_SPAWN, () -> verify(spawnLoader).loadEssentialsSpawn()); + checkEnableHandling(CMI, () -> { + verify(pluginHookService).tryHookToCMI(); + verify(spawnLoader).loadCMISpawn(); + }); checkEnableHandling(MULTIVERSE, () -> verify(pluginHookService).tryHookToMultiverse()); checkEnableHandling(PROTOCOL_LIB, () -> verify(protocolLibService).setup()); checkEnableHandling("UnknownPlugin", () -> verifyZeroInteractions(pluginHookService, spawnLoader)); @@ -67,6 +72,10 @@ public class ServerListenerTest { public void shouldForwardPluginNameOnDisable() { checkDisableHandling(ESSENTIALS, () -> verify(pluginHookService).unhookEssentials()); checkDisableHandling(ESSENTIALS_SPAWN, () -> verify(spawnLoader).unloadEssentialsSpawn()); + checkDisableHandling(CMI, () -> { + verify(pluginHookService).unhookCMI(); + verify(spawnLoader).unloadCMISpawn(); + }); checkDisableHandling(MULTIVERSE, () -> verify(pluginHookService).unhookMultiverse()); checkDisableHandling(PROTOCOL_LIB, () -> verify(protocolLibService).disable()); checkDisableHandling("UnknownPlugin", () -> verifyZeroInteractions(pluginHookService, spawnLoader));