diff --git a/api/src/main/java/com/bivashy/auth/api/config/PluginConfig.java b/api/src/main/java/com/bivashy/auth/api/config/PluginConfig.java index 31f50154..40594a9c 100644 --- a/api/src/main/java/com/bivashy/auth/api/config/PluginConfig.java +++ b/api/src/main/java/com/bivashy/auth/api/config/PluginConfig.java @@ -2,6 +2,7 @@ import java.util.List; import java.util.regex.Pattern; +import java.util.stream.IntStream; import com.bivashy.auth.api.config.bossbar.BossBarSettings; import com.bivashy.auth.api.config.database.DatabaseSettings; @@ -42,6 +43,8 @@ public interface PluginConfig { List getAllowedCommands(); + IntStream getLimboPortRange(); + List getAuthenticationSteps(); String getAuthenticationStepName(int index); diff --git a/api/src/main/java/com/bivashy/auth/api/hook/LimboPluginHook.java b/api/src/main/java/com/bivashy/auth/api/hook/LimboPluginHook.java new file mode 100644 index 00000000..e1c5a630 --- /dev/null +++ b/api/src/main/java/com/bivashy/auth/api/hook/LimboPluginHook.java @@ -0,0 +1,9 @@ +package com.bivashy.auth.api.hook; + +import com.bivashy.auth.api.server.proxy.ProxyServer; + +public interface LimboPluginHook extends PluginHook { + + ProxyServer createServer(String serverName); + +} diff --git a/api/src/main/java/com/bivashy/auth/api/server/proxy/limbo/LimboServerWrapper.java b/api/src/main/java/com/bivashy/auth/api/server/proxy/limbo/LimboServerWrapper.java index 67e087dc..32cfeba6 100644 --- a/api/src/main/java/com/bivashy/auth/api/server/proxy/limbo/LimboServerWrapper.java +++ b/api/src/main/java/com/bivashy/auth/api/server/proxy/limbo/LimboServerWrapper.java @@ -2,5 +2,6 @@ import com.bivashy.auth.api.server.proxy.ProxyServer; +@Deprecated public interface LimboServerWrapper extends ProxyServer { } diff --git a/bungee/pom.xml b/bungee/pom.xml index 00771214..1f3b940d 100644 --- a/bungee/pom.xml +++ b/bungee/pom.xml @@ -17,6 +17,7 @@ 6.5.0 0.4.2 2.0.0 + 1.0.6 @@ -87,6 +88,14 @@ provided + + + com.github.bivashy.NanoLimboPlugin + api + ${nanolimbo.version} + provided + + com.github.bivashy.libby diff --git a/bungee/src/main/java/me/mastercapexd/auth/bungee/BungeeAuthPluginBootstrap.java b/bungee/src/main/java/me/mastercapexd/auth/bungee/BungeeAuthPluginBootstrap.java index b1de1f83..2ff8c64a 100644 --- a/bungee/src/main/java/me/mastercapexd/auth/bungee/BungeeAuthPluginBootstrap.java +++ b/bungee/src/main/java/me/mastercapexd/auth/bungee/BungeeAuthPluginBootstrap.java @@ -1,8 +1,10 @@ package me.mastercapexd.auth.bungee; +import java.util.Collection; +import java.util.Collections; + import com.alessiodp.libby.BungeeLibraryManager; -import com.bivashy.auth.api.AuthPlugin; -import com.bivashy.auth.api.management.LoginManagement; +import com.bivashy.auth.api.hook.LimboPluginHook; import com.bivashy.messenger.vk.message.VkMessage; import com.bivashy.messenger.vk.provider.VkApiProvider; import com.ubivashka.vk.bungee.BungeeVkApiPlugin; @@ -10,6 +12,7 @@ import me.mastercapexd.auth.BaseAuthPlugin; import me.mastercapexd.auth.bungee.commands.BungeeCommandsRegistry; import me.mastercapexd.auth.bungee.hooks.BungeeVkPluginHook; +import me.mastercapexd.auth.bungee.hooks.nanolimbo.BungeeNanoLimboPluginHook; import me.mastercapexd.auth.bungee.listener.AuthenticationListener; import me.mastercapexd.auth.bungee.listener.VkDispatchListener; import me.mastercapexd.auth.hooks.VkPluginHook; @@ -22,7 +25,6 @@ public class BungeeAuthPluginBootstrap extends Plugin { private static BungeeAuthPluginBootstrap instance; private BungeeAudiences bungeeAudiences; - private LoginManagement loginManagement; private BaseAuthPlugin authPlugin; public static BungeeAuthPluginBootstrap getInstance() { @@ -39,6 +41,7 @@ public void onEnable() { new BaseLibraryManagement(new BungeeLibraryManager(this))); initializeListener(); initializeCommand(); + initializeLimbo(); if (authPlugin.getConfig().getVKSettings().isEnabled()) initializeVk(); } @@ -57,6 +60,13 @@ private void initializeCommand() { new BungeeCommandsRegistry(this, authPlugin); } + private void initializeLimbo() { + Collection limboPluginHooks = Collections.singleton(new BungeeNanoLimboPluginHook(authPlugin.getConfig().getLimboPortRange())); + limboPluginHooks.stream() + .filter(LimboPluginHook::canHook) + .forEach(limboPluginHook -> authPlugin.putHook(LimboPluginHook.class, limboPluginHook)); + } + private void initializeVk() { authPlugin.putHook(VkPluginHook.class, new BungeeVkPluginHook()); diff --git a/bungee/src/main/java/me/mastercapexd/auth/bungee/BungeeProxyCore.java b/bungee/src/main/java/me/mastercapexd/auth/bungee/BungeeProxyCore.java index 20542fa5..53ad0728 100644 --- a/bungee/src/main/java/me/mastercapexd/auth/bungee/BungeeProxyCore.java +++ b/bungee/src/main/java/me/mastercapexd/auth/bungee/BungeeProxyCore.java @@ -10,11 +10,11 @@ import java.util.stream.Collectors; import com.bivashy.auth.api.AuthPlugin; +import com.bivashy.auth.api.hook.LimboPluginHook; import com.bivashy.auth.api.server.ServerCore; import com.bivashy.auth.api.server.bossbar.ServerBossbar; import com.bivashy.auth.api.server.message.ServerComponent; import com.bivashy.auth.api.server.player.ServerPlayer; -import com.bivashy.auth.api.server.proxy.limbo.LimboServerWrapper; import com.bivashy.auth.api.server.scheduler.ServerScheduler; import com.bivashy.auth.api.server.title.ServerTitle; @@ -25,7 +25,6 @@ import me.mastercapexd.auth.bungee.player.BungeeServerPlayer; import me.mastercapexd.auth.bungee.scheduler.BungeeSchedulerWrapper; import me.mastercapexd.auth.bungee.server.BungeeServer; -import me.mastercapexd.auth.hooks.limbo.LimboHook; import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.config.ServerInfo; @@ -109,15 +108,9 @@ public ServerComponent componentLegacy(String legacy) { @Override public Optional serverFromName(String serverName) { ServerInfo serverInfo = PROXY_SERVER.getServerInfo(serverName); - LimboHook limboHook = AuthPlugin.instance().getHook(LimboHook.class); - if (serverInfo == null && limboHook != null) { - if (!limboHook.isLimbo(serverName)) - return Optional.empty(); - LimboServerWrapper server = limboHook.createLimboWrapper(serverName); - if (!server.isExists()) - return Optional.empty(); - return Optional.of(server); - } + LimboPluginHook limboHook = AuthPlugin.instance().getHook(LimboPluginHook.class); + if (serverInfo == null && limboHook != null) + return Optional.of(limboHook.createServer(serverName)); return Optional.of(new BungeeServer(serverInfo)); } diff --git a/bungee/src/main/java/me/mastercapexd/auth/bungee/hooks/nanolimbo/BungeeNanoLimboPluginHook.java b/bungee/src/main/java/me/mastercapexd/auth/bungee/hooks/nanolimbo/BungeeNanoLimboPluginHook.java new file mode 100644 index 00000000..9841b798 --- /dev/null +++ b/bungee/src/main/java/me/mastercapexd/auth/bungee/hooks/nanolimbo/BungeeNanoLimboPluginHook.java @@ -0,0 +1,58 @@ +package me.mastercapexd.auth.bungee.hooks.nanolimbo; + +import java.net.SocketAddress; +import java.util.stream.IntStream; + +import com.bivashy.auth.api.AuthPlugin; +import com.bivashy.auth.api.config.PluginConfig; +import com.bivashy.auth.api.hook.LimboPluginHook; + +import me.mastercapexd.auth.bungee.BungeeAuthPluginBootstrap; +import me.mastercapexd.auth.bungee.server.BungeeServer; +import me.mastercapexd.auth.hooks.nanolimbo.NanoLimboProvider; +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.config.ServerInfo; +import net.md_5.bungee.api.event.ServerConnectEvent; +import net.md_5.bungee.api.event.ServerConnectEvent.Reason; +import net.md_5.bungee.api.plugin.Listener; +import net.md_5.bungee.event.EventHandler; +import net.md_5.bungee.event.EventPriority; + +public class BungeeNanoLimboPluginHook implements LimboPluginHook, Listener { + + private final int[] limboPorts; + private NanoLimboProvider provider; + + public BungeeNanoLimboPluginHook(IntStream limboPortRange) { + this.limboPorts = limboPortRange.toArray(); + if (!canHook()) + return; + this.provider = new BungeeNanoLimboProvider(ProxyServer.getInstance().getPluginManager().getPlugin("NanoLimboBungee").getClass().getClassLoader()); + ProxyServer.getInstance().getPluginManager().registerListener(BungeeAuthPluginBootstrap.getInstance(), this); + } + + @Override + public com.bivashy.auth.api.server.proxy.ProxyServer createServer(String serverName) { + SocketAddress address = provider.findAvailableAddress(limboPorts).orElseThrow( + () -> new IllegalStateException("Cannot find available port for limbo server!")); + provider.createAndStartLimbo(address); + ServerInfo serverInfo = ProxyServer.getInstance().constructServerInfo(serverName, address, "", false); + ProxyServer.getInstance().getConfig().getServers().put(serverInfo.getName(), serverInfo); + return new BungeeServer(serverInfo); + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onServerChoose(ServerConnectEvent event) { + // TODO: Implement ServerConnectEvent in the InitialServerManagement + if (event.getReason() != Reason.JOIN_PROXY) + return; + PluginConfig config = AuthPlugin.instance().getConfig(); + event.setTarget(config.findServerInfo(config.getAuthServers()).asProxyServer().as(BungeeServer.class).getServerInfo()); + } + + @Override + public boolean canHook() { + return ProxyServer.getInstance().getPluginManager().getPlugin("NanoLimboBungee") != null; + } + +} diff --git a/bungee/src/main/java/me/mastercapexd/auth/bungee/hooks/nanolimbo/BungeeNanoLimboProvider.java b/bungee/src/main/java/me/mastercapexd/auth/bungee/hooks/nanolimbo/BungeeNanoLimboProvider.java new file mode 100644 index 00000000..abf52d04 --- /dev/null +++ b/bungee/src/main/java/me/mastercapexd/auth/bungee/hooks/nanolimbo/BungeeNanoLimboProvider.java @@ -0,0 +1,24 @@ +package me.mastercapexd.auth.bungee.hooks.nanolimbo; + +import me.mastercapexd.auth.hooks.nanolimbo.NanoLimboProvider; +import ua.nanit.limbo.server.data.InfoForwarding; + +public class BungeeNanoLimboProvider implements NanoLimboProvider { + + private final ClassLoader classLoader; + + public BungeeNanoLimboProvider(ClassLoader classLoader) { + this.classLoader = classLoader; + } + + @Override + public InfoForwarding createForwarding() { + return FORWARDING_FACTORY.legacy(); + } + + @Override + public ClassLoader classLoader() { + return classLoader; + } + +} diff --git a/bungee/src/main/resources/bungee.yml b/bungee/src/main/resources/bungee.yml index 8c412cad..17998a56 100644 --- a/bungee/src/main/resources/bungee.yml +++ b/bungee/src/main/resources/bungee.yml @@ -1,5 +1,8 @@ name: mcAuth main: me.mastercapexd.auth.bungee.BungeeAuthPluginBootstrap version: ${project.version} -softDepends: [VK-API,JavaTelegramBotApi] +softDepends: + - VK-API + - JavaTelegramBotApi + - NanoLimboBungee author: bivashy, MasterCapeXD diff --git a/core/pom.xml b/core/pom.xml index 9167008f..30a8d87e 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -25,6 +25,7 @@ 1.7.0 1.4.2 5.0.0-beta.11 + 1.0.6 1.9.15 3.9.4 @@ -162,5 +163,13 @@ ${jda.version} provided + + + + com.github.bivashy.NanoLimboPlugin + api + ${nanolimbo.version} + provided + \ No newline at end of file diff --git a/core/src/main/java/me/mastercapexd/auth/BaseAuthPlugin.java b/core/src/main/java/me/mastercapexd/auth/BaseAuthPlugin.java index cefa1e91..8e923eaa 100644 --- a/core/src/main/java/me/mastercapexd/auth/BaseAuthPlugin.java +++ b/core/src/main/java/me/mastercapexd/auth/BaseAuthPlugin.java @@ -7,6 +7,7 @@ import java.util.HashMap; import java.util.Map; import java.util.concurrent.Executors; +import java.util.stream.IntStream; import com.bivashy.auth.api.AuthPlugin; import com.bivashy.auth.api.AuthPluginProvider; @@ -240,6 +241,16 @@ private void registerConfigurationProcessor() { if (path.isEmpty()) return null; return new File(path.replace("%plugin_folder%", getFolder().getAbsolutePath())); + }) + .registerFieldResolver(IntStream.class, (context) -> { + String number = context.getString(""); + if (number.isEmpty()) + return IntStream.of(0); + if (number.contains("-")) { + String[] range = number.split("-"); + return IntStream.range(Integer.parseInt(range[0]), Integer.parseInt(range[1])); + } + return IntStream.of(Integer.parseInt(number)); }); } diff --git a/core/src/main/java/me/mastercapexd/auth/config/PluginConfigTemplate.java b/core/src/main/java/me/mastercapexd/auth/config/PluginConfigTemplate.java index fe12a8ed..bc01c56f 100644 --- a/core/src/main/java/me/mastercapexd/auth/config/PluginConfigTemplate.java +++ b/core/src/main/java/me/mastercapexd/auth/config/PluginConfigTemplate.java @@ -5,6 +5,7 @@ import java.util.List; import java.util.regex.Pattern; import java.util.stream.Collectors; +import java.util.stream.IntStream; import com.bivashy.auth.api.AuthPlugin; import com.bivashy.auth.api.config.PluginConfig; @@ -37,6 +38,7 @@ import me.mastercapexd.auth.config.vk.BaseVKSettings; public abstract class PluginConfigTemplate implements PluginConfig { + protected final AuthPlugin plugin; private final List allowedPatternCommands; protected ConfigurationSectionHolder configurationRoot; @@ -101,6 +103,8 @@ public abstract class PluginConfigTemplate implements PluginConfig { private ConfigurationDuration joinDelay = new ConfigurationDuration(0); @ConfigField("block-chat") private boolean blockChat = true; + @ConfigField("limbo-port") + private IntStream limboPortRange = IntStream.range(49152, 65535); @ConfigField("authentication-steps") private List authenticationSteps = Arrays.asList("REGISTER", "LOGIN", "VK_LINK", "TELEGRAM_LINK", "GOOGLE_LINK", "ENTER_SERVER"); @@ -287,5 +291,11 @@ public String getAuthenticationStepName(int index) { return index >= 0 && index < authenticationSteps.size() ? authenticationSteps.get(index) : "NULL"; } + @Override + public IntStream getLimboPortRange() { + return limboPortRange; + } + protected abstract ConfigurationSectionHolder createConfiguration(AuthPlugin plugin); + } \ No newline at end of file diff --git a/core/src/main/java/me/mastercapexd/auth/hooks/limbo/LimboHook.java b/core/src/main/java/me/mastercapexd/auth/hooks/limbo/LimboHook.java deleted file mode 100644 index d0ca8225..00000000 --- a/core/src/main/java/me/mastercapexd/auth/hooks/limbo/LimboHook.java +++ /dev/null @@ -1,10 +0,0 @@ -package me.mastercapexd.auth.hooks.limbo; - -import com.bivashy.auth.api.hook.PluginHook; -import com.bivashy.auth.api.server.proxy.limbo.LimboServerWrapper; - -public interface LimboHook extends PluginHook { - boolean isLimbo(String serverName); - - LimboServerWrapper createLimboWrapper(String serverName); -} diff --git a/core/src/main/java/me/mastercapexd/auth/hooks/nanolimbo/InfoForwardingFactory.java b/core/src/main/java/me/mastercapexd/auth/hooks/nanolimbo/InfoForwardingFactory.java new file mode 100644 index 00000000..f3cf93c6 --- /dev/null +++ b/core/src/main/java/me/mastercapexd/auth/hooks/nanolimbo/InfoForwardingFactory.java @@ -0,0 +1,55 @@ +package me.mastercapexd.auth.hooks.nanolimbo; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +import ua.nanit.limbo.server.data.InfoForwarding; +import ua.nanit.limbo.server.data.InfoForwarding.Type; + +// Class for hiding InfoForwarding dirty way initialization +public class InfoForwardingFactory { + + public InfoForwarding none() { + Map map = Collections.singletonMap("type", Type.NONE); + return createForwarding(map); + } + + public InfoForwarding legacy() { + Map map = Collections.singletonMap("type", Type.LEGACY); + return createForwarding(map); + } + + public InfoForwarding modern(byte[] secretKey) { + Map map = new HashMap<>(); + map.put("type", Type.MODERN); + map.put("secretKey", secretKey); + return createForwarding(map); + } + + public InfoForwarding bungeeGuard(Collection tokens) { + Map map = new HashMap<>(); + map.put("type", Type.BUNGEE_GUARD); + map.put("tokens", new ArrayList<>(tokens)); + return createForwarding(map); + } + + private InfoForwarding createForwarding(Map map) { + InfoForwarding forwarding = new InfoForwarding(); + for (Entry entry : map.entrySet()) { + Class clazz = forwarding.getClass(); + try { + Field field = clazz.getDeclaredField(entry.getKey()); + field.setAccessible(true); + field.set(forwarding, entry.getValue()); + } catch (NoSuchFieldException | IllegalAccessException ignored) { + } + } + return forwarding; + } + +} \ No newline at end of file diff --git a/core/src/main/java/me/mastercapexd/auth/hooks/nanolimbo/NanoLimboConfig.java b/core/src/main/java/me/mastercapexd/auth/hooks/nanolimbo/NanoLimboConfig.java new file mode 100644 index 00000000..03671932 --- /dev/null +++ b/core/src/main/java/me/mastercapexd/auth/hooks/nanolimbo/NanoLimboConfig.java @@ -0,0 +1,146 @@ +package me.mastercapexd.auth.hooks.nanolimbo; + +import java.net.SocketAddress; +import java.time.Duration; + +import ua.nanit.limbo.configuration.LimboConfig; +import ua.nanit.limbo.server.data.BossBar; +import ua.nanit.limbo.server.data.InfoForwarding; +import ua.nanit.limbo.server.data.PingData; +import ua.nanit.limbo.server.data.Title; + +public class NanoLimboConfig implements LimboConfig { + private final PingData pingData; + private final SocketAddress address; + private final InfoForwarding forwarding; + + public NanoLimboConfig(SocketAddress address, InfoForwarding forwarding) { + this.pingData = new PingData(); + + this.pingData.setDescription("NanoLimbo"); + this.pingData.setVersion("NanoLimbo"); + + this.address = address; + this.forwarding = forwarding; + } + + @Override + public SocketAddress getAddress() { + return address; + } + + @Override + public int getMaxPlayers() { + return -1; + } + + @Override + public PingData getPingData() { + return pingData; + } + + @Override + public String getDimensionType() { + return "the_end"; + } + + @Override + public int getGameMode() { + return 2; // Adventure game mode + } + + @Override + public InfoForwarding getInfoForwarding() { + return forwarding; + } + + @Override + public long getReadTimeout() { + return Duration.ofSeconds(30).toMillis(); + } + + @Override + public int getDebugLevel() { + return 0; // Display only errors + } + + @Override + public boolean isUseBrandName() { + return false; + } + + @Override + public boolean isUseJoinMessage() { + return false; + } + + @Override + public boolean isUseBossBar() { + return false; + } + + @Override + public boolean isUseTitle() { + return false; + } + + @Override + public boolean isUsePlayerList() { + return false; + } + + @Override + public boolean isUseHeaderAndFooter() { + return false; + } + + @Override + public String getBrandName() { + return null; + } + + @Override + public String getJoinMessage() { + return null; + } + + @Override + public BossBar getBossBar() { + return null; + } + + @Override + public Title getTitle() { + return null; + } + + @Override + public String getPlayerListUsername() { + return ""; + } + + @Override + public String getPlayerListHeader() { + return null; + } + + @Override + public String getPlayerListFooter() { + return null; + } + + @Override + public boolean isUseEpoll() { + return false; + } + + @Override + public int getBossGroupSize() { + return 1; // Default value + } + + @Override + public int getWorkerGroupSize() { + return 4; // Default value + } +} \ No newline at end of file diff --git a/core/src/main/java/me/mastercapexd/auth/hooks/nanolimbo/NanoLimboProvider.java b/core/src/main/java/me/mastercapexd/auth/hooks/nanolimbo/NanoLimboProvider.java new file mode 100644 index 00000000..06448631 --- /dev/null +++ b/core/src/main/java/me/mastercapexd/auth/hooks/nanolimbo/NanoLimboProvider.java @@ -0,0 +1,59 @@ +package me.mastercapexd.auth.hooks.nanolimbo; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.ServerSocket; +import java.net.SocketAddress; +import java.util.Collection; +import java.util.Collections; +import java.util.Optional; +import java.util.stream.IntStream; + +import ua.nanit.limbo.server.Command; +import ua.nanit.limbo.server.CommandHandler; +import ua.nanit.limbo.server.LimboServer; +import ua.nanit.limbo.server.data.InfoForwarding; + +public interface NanoLimboProvider { + + CommandHandler DUMMY_COMMAND_HANDLER = new CommandHandler() { + @Override + public Collection getCommands() { + return Collections.emptyList(); + } + + @Override + public void register(Command command) { + } + + @Override + public boolean executeCommand(String s) { + return false; + } + }; + InfoForwardingFactory FORWARDING_FACTORY = new InfoForwardingFactory(); + + InfoForwarding createForwarding(); + + ClassLoader classLoader(); + + default void createAndStartLimbo(SocketAddress address) { + LimboServer limboServer = new LimboServer(new NanoLimboConfig(address, createForwarding()), DUMMY_COMMAND_HANDLER, classLoader()); + try { + limboServer.start(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + default Optional findAvailableAddress(int[] ports) { + return IntStream.of(ports).filter(port -> { + try (ServerSocket ignored = new ServerSocket(port)) { + return true; + } catch (IOException ignored) { + return false; + } + }).mapToObj(InetSocketAddress::new).findFirst(); + } + +} diff --git a/core/src/main/resources/configurations/config.yml b/core/src/main/resources/configurations/config.yml index bfbdd15d..be29eef9 100644 --- a/core/src/main/resources/configurations/config.yml +++ b/core/src/main/resources/configurations/config.yml @@ -199,6 +199,10 @@ auth-time: 60 # Должен ли обычный чат быть заблокирован у игроков block-chat: true +# Определяет порт на котором работает лимбо. Если у вас не установлен NanoLimboPlugin, эта опция не будет иметь какого либо эффекта. +# Рекомендуется использовать значение 49152-65535. Подробнее: https://en.wikipedia.org/wiki/Ephemeral_port +limbo-port: 49152-65535 + # Доступные команды в ВК,Telegram! # /принять,/accept -> Подтверждение входа через ВК # /отклонить,/decline -> Отклонение входа через ВК diff --git a/velocity/pom.xml b/velocity/pom.xml index 8ca4316b..70c797a9 100644 --- a/velocity/pom.xml +++ b/velocity/pom.xml @@ -12,11 +12,12 @@ 3.1.1 + 3.0.1 0.4.2 6.1.0 3.2.5 - 1.1.7 2.0.0 + 1.0.6 11 @@ -33,8 +34,8 @@ - jnngl-public - https://maven.jnngl.me/public + exceptionflug + https://mvn.exceptionflug.de/repository/exceptionflug-public/ @@ -83,11 +84,19 @@ provided - + - net.elytrium.limboapi + com.velocitypowered + velocity-proxy + ${velocity-proxy.version} + provided + + + + + com.github.bivashy.NanoLimboPlugin api - ${limbo.api.version} + ${nanolimbo.version} provided diff --git a/velocity/src/main/java/me/mastercapexd/auth/velocity/VelocityAuthPluginBootstrap.java b/velocity/src/main/java/me/mastercapexd/auth/velocity/VelocityAuthPluginBootstrap.java index 346e2bbf..f4d8eafa 100644 --- a/velocity/src/main/java/me/mastercapexd/auth/velocity/VelocityAuthPluginBootstrap.java +++ b/velocity/src/main/java/me/mastercapexd/auth/velocity/VelocityAuthPluginBootstrap.java @@ -2,11 +2,14 @@ import java.io.File; import java.nio.file.Path; +import java.util.Collection; +import java.util.Collections; import org.slf4j.Logger; import com.alessiodp.libby.VelocityLibraryManager; import com.bivashy.auth.api.AuthPlugin; +import com.bivashy.auth.api.hook.LimboPluginHook; import com.bivashy.auth.api.server.ServerCore; import com.bivashy.messenger.vk.message.VkMessage; import com.bivashy.messenger.vk.provider.VkApiProvider; @@ -21,12 +24,11 @@ import me.mastercapexd.auth.BaseAuthPlugin; import me.mastercapexd.auth.hooks.VkPluginHook; -import me.mastercapexd.auth.hooks.limbo.LimboHook; import me.mastercapexd.auth.management.BaseLibraryManagement; import me.mastercapexd.auth.velocity.adventure.VelocityAudienceProvider; import me.mastercapexd.auth.velocity.commands.VelocityCommandRegistry; import me.mastercapexd.auth.velocity.hooks.VelocityVkPluginHook; -import me.mastercapexd.auth.velocity.hooks.limbo.LimboAPIHook; +import me.mastercapexd.auth.velocity.hooks.nanolimbo.VelocityNanoLimboPluginHook; import me.mastercapexd.auth.velocity.listener.AuthenticationListener; import me.mastercapexd.auth.velocity.listener.VkDispatchListener; import me.mastercapexd.auth.vk.command.VKCommandRegistry; @@ -86,10 +88,10 @@ private void initializeCommand() { } private void initializeLimbo() { - LimboAPIHook limboAPIHook = new LimboAPIHook(); - if (!limboAPIHook.canHook()) - return; - authPlugin.putHook(LimboHook.class, limboAPIHook); + Collection limboPluginHooks = Collections.singleton(new VelocityNanoLimboPluginHook(authPlugin.getConfig().getLimboPortRange(), proxyServer)); + limboPluginHooks.stream() + .filter(LimboPluginHook::canHook) + .forEach(limboPluginHook -> authPlugin.putHook(LimboPluginHook.class, limboPluginHook)); } public ProxyServer getProxyServer() { diff --git a/velocity/src/main/java/me/mastercapexd/auth/velocity/VelocityProxyCore.java b/velocity/src/main/java/me/mastercapexd/auth/velocity/VelocityProxyCore.java index f405a72d..e1e334c8 100644 --- a/velocity/src/main/java/me/mastercapexd/auth/velocity/VelocityProxyCore.java +++ b/velocity/src/main/java/me/mastercapexd/auth/velocity/VelocityProxyCore.java @@ -8,18 +8,17 @@ import java.util.stream.Collectors; import com.bivashy.auth.api.AuthPlugin; +import com.bivashy.auth.api.hook.LimboPluginHook; import com.bivashy.auth.api.server.ServerCore; import com.bivashy.auth.api.server.bossbar.ServerBossbar; import com.bivashy.auth.api.server.message.ServerComponent; import com.bivashy.auth.api.server.player.ServerPlayer; -import com.bivashy.auth.api.server.proxy.limbo.LimboServerWrapper; import com.bivashy.auth.api.server.scheduler.ServerScheduler; import com.bivashy.auth.api.server.title.ServerTitle; import com.velocitypowered.api.proxy.Player; import com.velocitypowered.api.proxy.ProxyServer; import com.velocitypowered.api.proxy.server.RegisteredServer; -import me.mastercapexd.auth.hooks.limbo.LimboHook; import me.mastercapexd.auth.velocity.api.bossbar.VelocityServerBossbar; import me.mastercapexd.auth.velocity.api.title.VelocityServerTitle; import me.mastercapexd.auth.velocity.component.VelocityComponent; @@ -31,6 +30,7 @@ import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; public class VelocityProxyCore implements ServerCore { + private final ProxyServer server; public VelocityProxyCore(ProxyServer server) { @@ -101,15 +101,9 @@ public ServerComponent componentLegacy(String legacy) { @Override public Optional serverFromName(String serverName) { Optional serverOptional = server.getServer(serverName); - LimboHook limboHook = AuthPlugin.instance().getHook(LimboHook.class); - if (!serverOptional.isPresent() && limboHook != null) { - if (!limboHook.isLimbo(serverName)) - return Optional.empty(); - LimboServerWrapper server = limboHook.createLimboWrapper(serverName); - if (!server.isExists()) - return Optional.empty(); - return Optional.of(server); - } + LimboPluginHook limboHook = AuthPlugin.instance().getHook(LimboPluginHook.class); + if (!serverOptional.isPresent() && limboHook != null) + return Optional.of(limboHook.createServer(serverName)); return serverOptional.map(VelocityProxyServer::new); } @@ -139,4 +133,5 @@ public void runAsync(Runnable task) { public String colorize(String text) { return text; } + } diff --git a/velocity/src/main/java/me/mastercapexd/auth/velocity/hooks/limbo/LimboAPIHook.java b/velocity/src/main/java/me/mastercapexd/auth/velocity/hooks/limbo/LimboAPIHook.java deleted file mode 100644 index 63ee8f81..00000000 --- a/velocity/src/main/java/me/mastercapexd/auth/velocity/hooks/limbo/LimboAPIHook.java +++ /dev/null @@ -1,42 +0,0 @@ -package me.mastercapexd.auth.velocity.hooks.limbo; - -import com.bivashy.auth.api.server.proxy.limbo.LimboServerWrapper; - -import me.mastercapexd.auth.hooks.limbo.LimboHook; -import me.mastercapexd.auth.velocity.VelocityAuthPluginBootstrap; - -public class LimboAPIHook implements LimboHook { - private static final VelocityAuthPluginBootstrap PLUGIN = VelocityAuthPluginBootstrap.getInstance(); - private LimboAPIProvider provider; - - public LimboAPIHook() { - if (!canHook()) - return; - this.provider = new LimboAPIProvider(); - PLUGIN.getProxyServer().getEventManager().register(PLUGIN, provider); - } - - @Override - public boolean isLimbo(String serverName) { - if (provider == null) - return false; - return provider.isLimbo(serverName); - } - - @Override - public LimboServerWrapper createLimboWrapper(String serverName) { - if (provider == null) - return null; - return provider.createLimboWrapper(serverName); - } - - @Override - public boolean canHook() { - try { - net.elytrium.limboapi.api.LimboFactory.class.getName(); - return true; - } catch(NoClassDefFoundError e) { - return false; - } - } -} diff --git a/velocity/src/main/java/me/mastercapexd/auth/velocity/hooks/limbo/LimboAPIProvider.java b/velocity/src/main/java/me/mastercapexd/auth/velocity/hooks/limbo/LimboAPIProvider.java deleted file mode 100644 index 0cdfc994..00000000 --- a/velocity/src/main/java/me/mastercapexd/auth/velocity/hooks/limbo/LimboAPIProvider.java +++ /dev/null @@ -1,47 +0,0 @@ -package me.mastercapexd.auth.velocity.hooks.limbo; - -import java.util.List; -import java.util.stream.Collectors; - -import com.bivashy.auth.api.server.proxy.limbo.LimboServerWrapper; -import com.velocitypowered.api.event.Subscribe; -import com.velocitypowered.api.plugin.PluginContainer; - -import me.mastercapexd.auth.velocity.VelocityAuthPluginBootstrap; -import me.mastercapexd.auth.velocity.hooks.limbo.config.LimboAPIConfig; -import net.elytrium.limboapi.api.LimboFactory; -import net.elytrium.limboapi.api.event.LoginLimboRegisterEvent; - -public class LimboAPIProvider { - public static final String LIMBO_API_NAME = "limboapi"; - private static final VelocityAuthPluginBootstrap PLUGIN = VelocityAuthPluginBootstrap.getInstance(); - private final LimboFactory limboFactory = (LimboFactory) PLUGIN - .getProxyServer() - .getPluginManager() - .getPlugin(LIMBO_API_NAME) - .flatMap(PluginContainer::getInstance) - .orElseThrow(NullPointerException::new); - private final LimboAPIConfig limboAPIConfig = new LimboAPIConfig(); - private final List wrappers; - - public LimboAPIProvider() { - LimboAPIConfig limboConfig = new LimboAPIConfig(); - wrappers = limboConfig.getLimboConfigs() - .stream() - .map(config -> new LimboAPIServer(config.getName(), config.createLimbo(limboFactory))) - .collect(Collectors.toList()); - } - - public LimboServerWrapper createLimboWrapper(String serverName) { - return wrappers.stream().filter(server -> server.getServerName().equals(serverName)).findFirst().orElseThrow(IllegalArgumentException::new); - } - - public boolean isLimbo(String serverName) { - return wrappers.stream().anyMatch(server -> server.getServerName().equals(serverName)); - } - - @Subscribe - public void onLimboLogin(LoginLimboRegisterEvent e) { - PLUGIN.getAuthPlugin().getCore().wrapPlayer(e.getPlayer()).ifPresent(PLUGIN.getAuthPlugin().getLoginManagement()::onLogin); - } -} diff --git a/velocity/src/main/java/me/mastercapexd/auth/velocity/hooks/limbo/LimboAPIServer.java b/velocity/src/main/java/me/mastercapexd/auth/velocity/hooks/limbo/LimboAPIServer.java deleted file mode 100644 index 980cfaba..00000000 --- a/velocity/src/main/java/me/mastercapexd/auth/velocity/hooks/limbo/LimboAPIServer.java +++ /dev/null @@ -1,61 +0,0 @@ -package me.mastercapexd.auth.velocity.hooks.limbo; - -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.UUID; - -import com.bivashy.auth.api.server.player.ServerPlayer; -import com.bivashy.auth.api.server.proxy.limbo.LimboServerWrapper; -import com.velocitypowered.api.proxy.Player; - -import net.elytrium.limboapi.api.Limbo; -import net.elytrium.limboapi.api.LimboSessionHandler; - -public class LimboAPIServer implements LimboServerWrapper { - private final Set onlinePlayers = new HashSet<>(); - private final String name; - private final Limbo limbo; - - public LimboAPIServer(String name, Limbo limbo) { - this.name = name; - this.limbo = limbo; - } - - @Override - public String getServerName() { - return name; - } - - @Override - public void sendPlayer(ServerPlayer... players) { - for (ServerPlayer player : players) { - if (onlinePlayers.contains(player.getUniqueId())) - continue; - onlinePlayers.add(player.getUniqueId()); - Player velocityPlayer = player.getRealPlayer(); - limbo.spawnPlayer(velocityPlayer, new LimboSessionHandler() { - @Override - public void onDisconnect() { - onlinePlayers.remove(player.getUniqueId()); - } - }); - } - } - - @Override - public List getPlayers() { - return Collections.emptyList(); - } - - @Override - public int getPlayersCount() { - return 0; - } - - @Override - public boolean isExists() { - return limbo != null; - } -} diff --git a/velocity/src/main/java/me/mastercapexd/auth/velocity/hooks/limbo/config/LimboAPIConfig.java b/velocity/src/main/java/me/mastercapexd/auth/velocity/hooks/limbo/config/LimboAPIConfig.java deleted file mode 100644 index eb2d9fa0..00000000 --- a/velocity/src/main/java/me/mastercapexd/auth/velocity/hooks/limbo/config/LimboAPIConfig.java +++ /dev/null @@ -1,46 +0,0 @@ -package me.mastercapexd.auth.velocity.hooks.limbo.config; - -import java.io.File; -import java.io.IOException; -import java.util.Collections; -import java.util.List; - -import org.spongepowered.configurate.ConfigurationNode; -import org.spongepowered.configurate.yaml.YamlConfigurationLoader; - -import com.bivashy.auth.api.asset.resource.ResourceReader; -import com.bivashy.configuration.ConfigurationProcessor; -import com.bivashy.configuration.annotation.ConfigField; -import com.bivashy.configuration.configurate.SpongeConfigurateProcessor; - -import me.mastercapexd.auth.velocity.VelocityAuthPluginBootstrap; - -public class LimboAPIConfig { - public static final ConfigurationProcessor CONFIGURATION_PROCESSOR = new SpongeConfigurateProcessor(); - public static final String CONFIGURATION_NAME = "limbo.yml"; - private static final VelocityAuthPluginBootstrap PLUGIN = VelocityAuthPluginBootstrap.getInstance(); - private static final File CONFIGURATION_FILE = new File(PLUGIN.getAuthPlugin().getFolder(), CONFIGURATION_NAME); - private ConfigurationNode node; - @ConfigField("values") - private List limboConfigs; - - public LimboAPIConfig() { - try { - ResourceReader.defaultReader(VelocityAuthPluginBootstrap.getInstance().getClass().getClassLoader(), CONFIGURATION_NAME) - .read() - .write(CONFIGURATION_FILE); - node = YamlConfigurationLoader.builder().file(CONFIGURATION_FILE).build().load(); - CONFIGURATION_PROCESSOR.resolve(node, this); - } catch(IOException e) { - e.printStackTrace(); - } - } - - public List getLimboConfigs() { - return Collections.unmodifiableList(limboConfigs); - } - - public ConfigurationNode getNode() { - return node; - } -} diff --git a/velocity/src/main/java/me/mastercapexd/auth/velocity/hooks/limbo/config/LimboConfig.java b/velocity/src/main/java/me/mastercapexd/auth/velocity/hooks/limbo/config/LimboConfig.java deleted file mode 100644 index 65843fdf..00000000 --- a/velocity/src/main/java/me/mastercapexd/auth/velocity/hooks/limbo/config/LimboConfig.java +++ /dev/null @@ -1,63 +0,0 @@ -package me.mastercapexd.auth.velocity.hooks.limbo.config; - -import com.bivashy.configuration.ConfigurationHolder; -import com.bivashy.configuration.annotation.ConfigField; -import com.bivashy.configuration.holder.ConfigurationSectionHolder; - -import net.elytrium.limboapi.api.Limbo; -import net.elytrium.limboapi.api.LimboFactory; -import net.elytrium.limboapi.api.chunk.Dimension; - -public class LimboConfig implements ConfigurationHolder { - @ConfigField - private Dimension dimension = Dimension.OVERWORLD; - @ConfigField - private long time; - @ConfigField - private double x, y, z; - @ConfigField - private float yaw, pitch; - - private final String name; - - public LimboConfig(ConfigurationSectionHolder sectionHolder) { - LimboAPIConfig.CONFIGURATION_PROCESSOR.resolve(sectionHolder, this); - this.name = sectionHolder.key(); - } - - public Limbo createLimbo(LimboFactory factory) { - return factory.createLimbo(factory.createVirtualWorld(dimension, x, y, z, yaw, pitch)).setWorldTime(time).setName(name); - } - - public Dimension getDimension() { - return dimension; - } - - public long getTime() { - return time; - } - - public double getX() { - return x; - } - - public double getY() { - return y; - } - - public double getZ() { - return z; - } - - public float getYaw() { - return yaw; - } - - public float getPitch() { - return pitch; - } - - public String getName() { - return name; - } -} diff --git a/velocity/src/main/java/me/mastercapexd/auth/velocity/hooks/nanolimbo/VelocityNanoLimboPluginHook.java b/velocity/src/main/java/me/mastercapexd/auth/velocity/hooks/nanolimbo/VelocityNanoLimboPluginHook.java new file mode 100644 index 00000000..0086a689 --- /dev/null +++ b/velocity/src/main/java/me/mastercapexd/auth/velocity/hooks/nanolimbo/VelocityNanoLimboPluginHook.java @@ -0,0 +1,52 @@ +package me.mastercapexd.auth.velocity.hooks.nanolimbo; + +import java.net.InetSocketAddress; +import java.util.stream.IntStream; + +import com.bivashy.auth.api.AuthPlugin; +import com.bivashy.auth.api.config.PluginConfig; +import com.bivashy.auth.api.hook.LimboPluginHook; +import com.velocitypowered.api.event.Subscribe; +import com.velocitypowered.api.event.player.PlayerChooseInitialServerEvent; +import com.velocitypowered.api.proxy.ProxyServer; +import com.velocitypowered.api.proxy.server.ServerInfo; + +import me.mastercapexd.auth.hooks.nanolimbo.NanoLimboProvider; +import me.mastercapexd.auth.velocity.VelocityAuthPluginBootstrap; +import me.mastercapexd.auth.velocity.server.VelocityProxyServer; + +public class VelocityNanoLimboPluginHook implements LimboPluginHook { + + private final int[] limboPorts; + private final ProxyServer proxyServer; + private NanoLimboProvider provider; + + public VelocityNanoLimboPluginHook(IntStream limboPorts, ProxyServer proxyServer) { + this.limboPorts = limboPorts.toArray(); + this.proxyServer = proxyServer; + if (!canHook()) + return; + provider = new VelocityNanoLimboProvider(proxyServer); + proxyServer.getEventManager().register(VelocityAuthPluginBootstrap.getInstance(), this); + } + + @Override + public com.bivashy.auth.api.server.proxy.ProxyServer createServer(String serverName) { + InetSocketAddress address = provider.findAvailableAddress(limboPorts).orElseThrow( + () -> new IllegalStateException("Cannot find available port for limbo server!")); + provider.createAndStartLimbo(address); + return new VelocityProxyServer(proxyServer.registerServer(new ServerInfo(serverName, address))); + } + + @Subscribe + public void onServerChoose(PlayerChooseInitialServerEvent event) { + PluginConfig config = AuthPlugin.instance().getConfig(); + event.setInitialServer(config.findServerInfo(config.getAuthServers()).asProxyServer().as(VelocityProxyServer.class).getServer()); + } + + @Override + public boolean canHook() { + return proxyServer.getPluginManager().isLoaded("nanolimbovelocity"); + } + +} diff --git a/velocity/src/main/java/me/mastercapexd/auth/velocity/hooks/nanolimbo/VelocityNanoLimboProvider.java b/velocity/src/main/java/me/mastercapexd/auth/velocity/hooks/nanolimbo/VelocityNanoLimboProvider.java new file mode 100644 index 00000000..1f7f7f30 --- /dev/null +++ b/velocity/src/main/java/me/mastercapexd/auth/velocity/hooks/nanolimbo/VelocityNanoLimboProvider.java @@ -0,0 +1,50 @@ +package me.mastercapexd.auth.velocity.hooks.nanolimbo; + +import java.net.SocketAddress; +import java.nio.charset.StandardCharsets; +import java.util.Collections; + +import com.velocitypowered.api.proxy.ProxyServer; +import com.velocitypowered.proxy.config.PlayerInfoForwarding; +import com.velocitypowered.proxy.config.VelocityConfiguration; + +import me.mastercapexd.auth.hooks.nanolimbo.NanoLimboProvider; +import ua.nanit.limbo.NanoLimbo; +import ua.nanit.limbo.server.data.InfoForwarding; + +public class VelocityNanoLimboProvider implements NanoLimboProvider { + + private final ClassLoader classLoader; + private final ProxyServer proxyServer; + + public VelocityNanoLimboProvider(ProxyServer proxyServer) { + this.classLoader = NanoLimbo.class.getClassLoader(); + this.proxyServer = proxyServer; + } + + @Override + public void createAndStartLimbo(SocketAddress address) { + NanoLimboProvider.super.createAndStartLimbo(address); + } + + @Override + public InfoForwarding createForwarding() { + VelocityConfiguration velocityConfiguration = (VelocityConfiguration) proxyServer.getConfiguration(); + PlayerInfoForwarding forwardingMode = velocityConfiguration.getPlayerInfoForwardingMode(); + if (forwardingMode == PlayerInfoForwarding.NONE) + return FORWARDING_FACTORY.none(); + if (forwardingMode == PlayerInfoForwarding.LEGACY) + return FORWARDING_FACTORY.legacy(); + if (forwardingMode == PlayerInfoForwarding.MODERN) + return FORWARDING_FACTORY.modern(velocityConfiguration.getForwardingSecret()); + if (forwardingMode == PlayerInfoForwarding.BUNGEEGUARD) + return FORWARDING_FACTORY.bungeeGuard(Collections.singleton(new String(velocityConfiguration.getForwardingSecret(), StandardCharsets.UTF_8))); + return FORWARDING_FACTORY.none(); + } + + @Override + public ClassLoader classLoader() { + return classLoader; + } + +} diff --git a/velocity/src/main/resources/limbo.yml b/velocity/src/main/resources/limbo.yml deleted file mode 100644 index 8bb5ef90..00000000 --- a/velocity/src/main/resources/limbo.yml +++ /dev/null @@ -1,10 +0,0 @@ -values: - auth: # Название лимбо которое нужно указывать в config.yml - # OVERWORLD, THE_END, NETHER - dimension: OVERWORLD - x: 0 - y: 0 - z: 0 - yaw: 90 - pitch: 0 - time: 9000 \ No newline at end of file diff --git a/velocity/src/main/resources/velocity-plugin.json b/velocity/src/main/resources/velocity-plugin.json index 3f0966b4..7ce56fe0 100644 --- a/velocity/src/main/resources/velocity-plugin.json +++ b/velocity/src/main/resources/velocity-plugin.json @@ -15,7 +15,7 @@ "optional": true }, { - "id": "limboapi", + "id": "nanolimbovelocity", "optional": true } ],