diff --git a/src/main/java/fr/xephi/authme/service/BukkitService.java b/src/main/java/fr/xephi/authme/service/BukkitService.java index c5425b375..e60ea2046 100644 --- a/src/main/java/fr/xephi/authme/service/BukkitService.java +++ b/src/main/java/fr/xephi/authme/service/BukkitService.java @@ -4,6 +4,7 @@ import com.google.common.collect.Iterables; import fr.xephi.authme.AuthMe; import fr.xephi.authme.initialization.SettingsDependent; import fr.xephi.authme.settings.Settings; +import fr.xephi.authme.settings.properties.HooksSettings; import fr.xephi.authme.settings.properties.PluginSettings; import org.bukkit.BanEntry; import org.bukkit.BanList; @@ -38,6 +39,7 @@ public class BukkitService implements SettingsDependent { private final AuthMe authMe; private boolean useAsyncTasks; + private String pluginChannel; @Inject BukkitService(AuthMe authMe, Settings settings) { @@ -298,6 +300,11 @@ public class BukkitService implements SettingsDependent { @Override public void reload(Settings settings) { useAsyncTasks = settings.getProperty(PluginSettings.USE_ASYNC_TASKS); + if (settings.getProperty(HooksSettings.VELOCITY)) { + pluginChannel = "authme:main"; + } else { + pluginChannel = "BungeeCord"; + } } /** @@ -308,7 +315,7 @@ public class BukkitService implements SettingsDependent { public void sendBungeeMessage(byte[] bytes) { Player player = Iterables.getFirst(getOnlinePlayers(), null); if (player != null) { - player.sendPluginMessage(authMe, "BungeeCord", bytes); + player.sendPluginMessage(authMe, pluginChannel, bytes); } } diff --git a/src/main/java/fr/xephi/authme/service/bungeecord/BungeeReceiver.java b/src/main/java/fr/xephi/authme/service/bungeecord/BungeeReceiver.java index 04f55033e..725e38849 100644 --- a/src/main/java/fr/xephi/authme/service/bungeecord/BungeeReceiver.java +++ b/src/main/java/fr/xephi/authme/service/bungeecord/BungeeReceiver.java @@ -10,6 +10,7 @@ import fr.xephi.authme.initialization.SettingsDependent; import fr.xephi.authme.output.ConsoleLoggerFactory; import fr.xephi.authme.process.Management; import fr.xephi.authme.service.BukkitService; +import fr.xephi.authme.settings.AllowedProxyUuidLoader; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.properties.HooksSettings; import org.bukkit.entity.Player; @@ -18,6 +19,7 @@ import org.bukkit.plugin.messaging.PluginMessageListener; import javax.inject.Inject; import java.util.Optional; +import java.util.UUID; public class BungeeReceiver implements PluginMessageListener, SettingsDependent { @@ -28,28 +30,38 @@ public class BungeeReceiver implements PluginMessageListener, SettingsDependent private final ProxySessionManager proxySessionManager; private final Management management; private final DataSource dataSource; + private final AllowedProxyUuidLoader allowedProxyUUIDLoader; private boolean isEnabled; + private boolean velocity; @Inject BungeeReceiver(AuthMe plugin, BukkitService bukkitService, ProxySessionManager proxySessionManager, - Management management, DataSource dataSource, Settings settings) { + Management management, DataSource dataSource, Settings settings, AllowedProxyUuidLoader allowedProxyUUIDLoader) { this.plugin = plugin; this.bukkitService = bukkitService; this.proxySessionManager = proxySessionManager; this.management = management; this.dataSource = dataSource; + this.allowedProxyUUIDLoader = allowedProxyUUIDLoader; reload(settings); } @Override public void reload(final Settings settings) { - this.isEnabled = settings.getProperty(HooksSettings.BUNGEECORD); + this.velocity = settings.getProperty(HooksSettings.VELOCITY); + this.isEnabled = settings.getProperty(HooksSettings.BUNGEECORD) || velocity; if (this.isEnabled) { final Messenger messenger = plugin.getServer().getMessenger(); - if (!messenger.isIncomingChannelRegistered(plugin, "BungeeCord")) { - messenger.registerIncomingPluginChannel(plugin, "BungeeCord", this); + if (!velocity) { + if (!messenger.isIncomingChannelRegistered(plugin, "BungeeCord")) { + messenger.registerIncomingPluginChannel(plugin, "BungeeCord", this); + } + } else { + if (!messenger.isIncomingChannelRegistered(plugin, "authme:main")) { + messenger.registerIncomingPluginChannel(plugin, "authme:main", this); + } } } } @@ -66,6 +78,13 @@ public class BungeeReceiver implements PluginMessageListener, SettingsDependent in.readFully(dataBytes); final ByteArrayDataInput dataIn = ByteStreams.newDataInput(dataBytes); + if (velocity) { + final String uuid = dataIn.readUTF(); + if (!allowedProxyUUIDLoader.isAllowedProxy(UUID.fromString(uuid))) { + return; + } + } + // Parse type final String typeId = dataIn.readUTF(); final Optional type = MessageType.fromId(typeId); @@ -105,6 +124,13 @@ public class BungeeReceiver implements PluginMessageListener, SettingsDependent * @param in the input to handle */ private void handle(ByteArrayDataInput in) { + if (velocity) { + final String uuid = in.readUTF(); + if (!allowedProxyUUIDLoader.isAllowedProxy(UUID.fromString(uuid))) { + logger.debug("Received a plugin message from an invalid proxy!"); + return; + } + } // Parse type final String typeId = in.readUTF(); final Optional type = MessageType.fromId(typeId); diff --git a/src/main/java/fr/xephi/authme/service/bungeecord/BungeeSender.java b/src/main/java/fr/xephi/authme/service/bungeecord/BungeeSender.java index b99bb1b8e..ad48b5df5 100644 --- a/src/main/java/fr/xephi/authme/service/bungeecord/BungeeSender.java +++ b/src/main/java/fr/xephi/authme/service/bungeecord/BungeeSender.java @@ -23,6 +23,7 @@ public class BungeeSender implements SettingsDependent { private final DataSource dataSource; private boolean isEnabled; + private boolean velocity; private String destinationServerOnLogin; /* @@ -39,13 +40,21 @@ public class BungeeSender implements SettingsDependent { @Override public void reload(final Settings settings) { - this.isEnabled = settings.getProperty(HooksSettings.BUNGEECORD); + this.velocity = settings.getProperty(HooksSettings.VELOCITY); + this.isEnabled = settings.getProperty(HooksSettings.BUNGEECORD) || velocity; + this.destinationServerOnLogin = settings.getProperty(HooksSettings.BUNGEECORD_SERVER); if (this.isEnabled) { final Messenger messenger = plugin.getServer().getMessenger(); - if (!messenger.isOutgoingChannelRegistered(plugin, "BungeeCord")) { - messenger.registerOutgoingPluginChannel(plugin, "BungeeCord"); + if (!velocity) { + if (!messenger.isOutgoingChannelRegistered(plugin, "BungeeCord")) { + messenger.registerOutgoingPluginChannel(plugin, "BungeeCord"); + } + } else { + if (!messenger.isOutgoingChannelRegistered(plugin, "authme:main")) { + messenger.registerOutgoingPluginChannel(plugin, "authme:main"); + } } } } @@ -102,6 +111,7 @@ public class BungeeSender implements SettingsDependent { logger.debug("Tried to send a " + type + " bungeecord message but the plugin was disabled!"); return; } + logger.debug("Sending a " + type + " bungeecord message!"); if (type.isRequiresCaching() && !dataSource.isCached()) { return; } diff --git a/src/main/java/fr/xephi/authme/settings/AllowedProxyUuidLoader.java b/src/main/java/fr/xephi/authme/settings/AllowedProxyUuidLoader.java new file mode 100644 index 000000000..753ca1454 --- /dev/null +++ b/src/main/java/fr/xephi/authme/settings/AllowedProxyUuidLoader.java @@ -0,0 +1,54 @@ +package fr.xephi.authme.settings; + +import fr.xephi.authme.ConsoleLogger; +import fr.xephi.authme.initialization.DataFolder; +import fr.xephi.authme.initialization.Reloadable; +import fr.xephi.authme.output.ConsoleLoggerFactory; +import fr.xephi.authme.settings.properties.HooksSettings; + +import javax.inject.Inject; +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +public class AllowedProxyUuidLoader implements Reloadable { + + private List allowed_proxies; + private final File pluginFolder; + private final Settings settings; + private ConsoleLogger logger; + + @Inject + AllowedProxyUuidLoader(@DataFolder File pluginFolder, Settings settings){ + this.pluginFolder = pluginFolder; + this.settings = settings; + this.logger = ConsoleLoggerFactory.get(AllowedProxyUuidLoader.class); + reload(); + } + + @Override + public void reload() { + allowed_proxies = new ArrayList<>(); + if (settings.getProperty(HooksSettings.VELOCITY)) { + File dir = new File(String.valueOf(pluginFolder), "allowed-proxy"); + + if (!dir.exists()){ + dir.mkdir(); + } + String[] files = dir.list(); + + for (String pathname : files) { + try { + allowed_proxies.add(UUID.fromString(pathname.replaceFirst("\\.txt", ""))); + } catch (IllegalArgumentException e) { + logger.warning("Invalid UUID file in allowed-uuid folder: " + pathname.replaceFirst("\\.txt", "") + ", please delete it."); + } + } + } + } + + public boolean isAllowedProxy(UUID uuid) { + return allowed_proxies.contains(uuid); + } +} diff --git a/src/main/java/fr/xephi/authme/settings/properties/HooksSettings.java b/src/main/java/fr/xephi/authme/settings/properties/HooksSettings.java index 02c6e9ee1..14ddcf2ca 100644 --- a/src/main/java/fr/xephi/authme/settings/properties/HooksSettings.java +++ b/src/main/java/fr/xephi/authme/settings/properties/HooksSettings.java @@ -19,6 +19,14 @@ public final class HooksSettings implements SettingsHolder { public static final Property BUNGEECORD = newProperty("Hooks.bungeecord", false); + @Comment({ + "Do we need to hook with Velocity?", + "NOTE: requires AuthMeBungee on velocity", + " to enabled velocity communications you will also need to", + " copy the file in each 'AuthMeBungee/uuid' to 'AuthMeReloaded/allowed_proxy' folder"}) + public static final Property VELOCITY = + newProperty("Hooks.velocity", false); + @Comment("Send player to this BungeeCord server after register/login") public static final Property BUNGEECORD_SERVER = newProperty("Hooks.sendPlayerTo", ""); diff --git a/src/test/java/fr/xephi/authme/service/BukkitServiceTest.java b/src/test/java/fr/xephi/authme/service/BukkitServiceTest.java index 2e6ee72c7..3c844247b 100644 --- a/src/test/java/fr/xephi/authme/service/BukkitServiceTest.java +++ b/src/test/java/fr/xephi/authme/service/BukkitServiceTest.java @@ -4,6 +4,7 @@ import fr.xephi.authme.AuthMe; import fr.xephi.authme.ReflectionTestUtils; import fr.xephi.authme.events.FailedLoginEvent; import fr.xephi.authme.settings.Settings; +import fr.xephi.authme.settings.properties.HooksSettings; import fr.xephi.authme.settings.properties.PluginSettings; import org.bukkit.Bukkit; import org.bukkit.Server; @@ -56,6 +57,7 @@ public class BukkitServiceTest { given(server.getScheduler()).willReturn(scheduler); given(server.getPluginManager()).willReturn(pluginManager); given(settings.getProperty(PluginSettings.USE_ASYNC_TASKS)).willReturn(true); + given(settings.getProperty(HooksSettings.VELOCITY)).willReturn(false); bukkitService = new BukkitService(authMe, settings); }