From c7c8e673f01643bf87a86fb2ed37c47a3a68d91c Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Tue, 28 Nov 2017 12:57:39 +0100 Subject: [PATCH 1/2] #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 0e4435c9..2483ed4f 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 055e72af..f424fc37 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 af86b8a3..0ae10a7c 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 09442ed4..f64c6848 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 ab202d2f..a53eaa76 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 2ffe57f5..29b484ad 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)); From 610fed3c7b208dd913b442811af34d985e42b417 Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Wed, 29 Nov 2017 08:38:34 +0100 Subject: [PATCH 2/2] Fix codestyle, add test --- .../fr/xephi/authme/listener/ServerListener.java | 4 ++-- .../xephi/authme/service/PluginHookService.java | 10 +++++----- .../fr/xephi/authme/settings/SpawnLoader.java | 2 +- .../authme/listener/ServerListenerTest.java | 4 ++-- .../authme/service/PluginHookServiceTest.java | 16 ++++++++++++++++ 5 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/main/java/fr/xephi/authme/listener/ServerListener.java b/src/main/java/fr/xephi/authme/listener/ServerListener.java index f424fc37..83898bdc 100644 --- a/src/main/java/fr/xephi/authme/listener/ServerListener.java +++ b/src/main/java/fr/xephi/authme/listener/ServerListener.java @@ -41,7 +41,7 @@ public class ServerListener implements Listener { pluginHookService.unhookEssentials(); ConsoleLogger.info("Essentials has been disabled: unhooking"); } else if ("CMI".equalsIgnoreCase(pluginName)) { - pluginHookService.unhookCMI(); + pluginHookService.unhookCmi(); spawnLoader.unloadCMISpawn(); ConsoleLogger.info("CMI has been disabled: unhooking"); } else if ("Multiverse-Core".equalsIgnoreCase(pluginName)) { @@ -75,7 +75,7 @@ public class ServerListener implements Listener { } else if ("EssentialsSpawn".equalsIgnoreCase(pluginName)) { spawnLoader.loadEssentialsSpawn(); } else if ("CMI".equalsIgnoreCase(pluginName)) { - pluginHookService.tryHookToCMI(); + 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 0ae10a7c..0a204aa0 100644 --- a/src/main/java/fr/xephi/authme/service/PluginHookService.java +++ b/src/main/java/fr/xephi/authme/service/PluginHookService.java @@ -34,7 +34,7 @@ public class PluginHookService { public PluginHookService(PluginManager pluginManager) { this.pluginManager = pluginManager; tryHookToEssentials(); - tryHookToCMI(); + tryHookToCmi(); tryHookToMultiverse(); } @@ -67,7 +67,7 @@ public class PluginHookService { * * @return The CMI data folder, or null if unavailable */ - public File getCMIDataFolder() { + public File getCmiDataFolder() { Plugin plugin = pluginManager.getPlugin("CMI"); if(plugin == null) { return null; @@ -105,7 +105,7 @@ public class PluginHookService { /** * @return true if we have a hook to CMI, false otherwise */ - public boolean isCMIAvailable() { + public boolean isCmiAvailable() { return cmi != null; } @@ -134,7 +134,7 @@ public class PluginHookService { /** * Attempts to create a hook into CMI. */ - public void tryHookToCMI() { + public void tryHookToCmi() { try { cmi = getPlugin(pluginManager, "CMI", Plugin.class); } catch (Exception | NoClassDefFoundError ignored) { @@ -167,7 +167,7 @@ public class PluginHookService { /** * Unhooks from CMI. */ - public void unhookCMI() { + public void unhookCmi() { cmi = null; } diff --git a/src/main/java/fr/xephi/authme/settings/SpawnLoader.java b/src/main/java/fr/xephi/authme/settings/SpawnLoader.java index f64c6848..93d1f57f 100644 --- a/src/main/java/fr/xephi/authme/settings/SpawnLoader.java +++ b/src/main/java/fr/xephi/authme/settings/SpawnLoader.java @@ -135,7 +135,7 @@ public class SpawnLoader implements Reloadable { * Load the spawn point defined in CMI. */ public void loadCMISpawn() { - File cmiFolder = pluginHookService.getCMIDataFolder(); + File cmiFolder = pluginHookService.getCmiDataFolder(); if (cmiFolder == null) { return; } diff --git a/src/test/java/fr/xephi/authme/listener/ServerListenerTest.java b/src/test/java/fr/xephi/authme/listener/ServerListenerTest.java index 29b484ad..8cfdf03e 100644 --- a/src/test/java/fr/xephi/authme/listener/ServerListenerTest.java +++ b/src/test/java/fr/xephi/authme/listener/ServerListenerTest.java @@ -60,7 +60,7 @@ public class ServerListenerTest { checkEnableHandling(ESSENTIALS, () -> verify(pluginHookService).tryHookToEssentials()); checkEnableHandling(ESSENTIALS_SPAWN, () -> verify(spawnLoader).loadEssentialsSpawn()); checkEnableHandling(CMI, () -> { - verify(pluginHookService).tryHookToCMI(); + verify(pluginHookService).tryHookToCmi(); verify(spawnLoader).loadCMISpawn(); }); checkEnableHandling(MULTIVERSE, () -> verify(pluginHookService).tryHookToMultiverse()); @@ -73,7 +73,7 @@ public class ServerListenerTest { checkDisableHandling(ESSENTIALS, () -> verify(pluginHookService).unhookEssentials()); checkDisableHandling(ESSENTIALS_SPAWN, () -> verify(spawnLoader).unloadEssentialsSpawn()); checkDisableHandling(CMI, () -> { - verify(pluginHookService).unhookCMI(); + verify(pluginHookService).unhookCmi(); verify(spawnLoader).unloadCMISpawn(); }); checkDisableHandling(MULTIVERSE, () -> verify(pluginHookService).unhookMultiverse()); diff --git a/src/test/java/fr/xephi/authme/service/PluginHookServiceTest.java b/src/test/java/fr/xephi/authme/service/PluginHookServiceTest.java index 763e6b31..d949db7d 100644 --- a/src/test/java/fr/xephi/authme/service/PluginHookServiceTest.java +++ b/src/test/java/fr/xephi/authme/service/PluginHookServiceTest.java @@ -35,6 +35,8 @@ public class PluginHookServiceTest { /** The plugin name of Essentials. */ private static final String ESSENTIALS = "Essentials"; + /** The plugin name of CMI. */ + private static final String CMI = "CMI"; /** The plugin name of Multiverse-Core. */ private static final String MULTIVERSE = "Multiverse-Core"; @@ -71,6 +73,19 @@ public class PluginHookServiceTest { assertThat(pluginHookService.isEssentialsAvailable(), equalTo(true)); } + @Test + public void shouldHookIntoCmiAtInitialization() { + // given + PluginManager pluginManager = mock(PluginManager.class); + setPluginAvailable(pluginManager, CMI, Plugin.class); + + // when + PluginHookService pluginHookService = new PluginHookService(pluginManager); + + // then + assertThat(pluginHookService.isCmiAvailable(), equalTo(true)); + } + @Test public void shouldHookIntoMultiverseAtInitialization() { // given @@ -175,6 +190,7 @@ public class PluginHookServiceTest { // then assertThat(pluginHookService.isEssentialsAvailable(), equalTo(false)); + assertThat(pluginHookService.isCmiAvailable(), equalTo(false)); assertThat(pluginHookService.isMultiverseAvailable(), equalTo(false)); }