diff --git a/api/src/main/java/org/geysermc/floodgate/api/inject/PlatformInjector.java b/api/src/main/java/org/geysermc/floodgate/api/inject/PlatformInjector.java index 5fe765e5..4c28ac40 100644 --- a/api/src/main/java/org/geysermc/floodgate/api/inject/PlatformInjector.java +++ b/api/src/main/java/org/geysermc/floodgate/api/inject/PlatformInjector.java @@ -37,10 +37,9 @@ public interface PlatformInjector { * Injects the server connection. This will allow various addons (like getting the Floodgate * data and debug mode) to work. * - * @return true if the connection has successfully been injected - * @throws Exception if something went wrong while injecting the server connection + * @throws Exception if the platform couldn't be injected */ - boolean inject() throws Exception; + void inject() throws Exception; /** * Some platforms may not be able to remove their injection process. If so, this method will @@ -56,10 +55,9 @@ public interface PlatformInjector { * Removes the injection from the server. Please note that this function should only be used * internally (on plugin shutdown). This method will also remove every added addon. * - * @return true if the injection has successfully been removed - * @throws Exception if something went wrong while removing the injection + * @throws Exception if the platform injection could not be removed */ - boolean removeInjection() throws Exception; + void removeInjection() throws Exception; /** * If the server connection is currently injected. diff --git a/bungee/src/main/java/org/geysermc/floodgate/inject/bungee/BungeeInjector.java b/bungee/src/main/java/org/geysermc/floodgate/inject/bungee/BungeeInjector.java index 7181edd2..e6a3e964 100644 --- a/bungee/src/main/java/org/geysermc/floodgate/inject/bungee/BungeeInjector.java +++ b/bungee/src/main/java/org/geysermc/floodgate/inject/bungee/BungeeInjector.java @@ -49,27 +49,21 @@ public final class BungeeInjector extends CommonPlatformInjector { @Getter private boolean injected; @Override - public boolean inject() { - try { - // Can everyone just switch to Velocity please :) + public void inject() { + // Can everyone just switch to Velocity please :) - Field framePrepender = ReflectionUtils.getField(PipelineUtils.class, "framePrepender"); + Field framePrepender = ReflectionUtils.getField(PipelineUtils.class, "framePrepender"); - // Required in order to inject into both Geyser <-> proxy AND proxy <-> server - // (Instead of just replacing the ChannelInitializer which is only called for - // player <-> proxy) - BungeeCustomPrepender customPrepender = new BungeeCustomPrepender( - this, ReflectionUtils.castedStaticValue(framePrepender) - ); + // Required in order to inject into both Geyser <-> proxy AND proxy <-> server + // (Instead of just replacing the ChannelInitializer which is only called for + // player <-> proxy) + BungeeCustomPrepender customPrepender = new BungeeCustomPrepender( + this, ReflectionUtils.castedStaticValue(framePrepender) + ); - BungeeReflectionUtils.setFieldValue(null, framePrepender, customPrepender); + BungeeReflectionUtils.setFieldValue(null, framePrepender, customPrepender); - injected = true; - return true; - } catch (Exception e) { - e.printStackTrace(); - return false; - } + injected = true; } @Override @@ -78,9 +72,9 @@ public final class BungeeInjector extends CommonPlatformInjector { } @Override - public boolean removeInjection() { - logger.error("Floodgate cannot remove itself from Bungee without a reboot"); - return false; + public void removeInjection() { + throw new IllegalStateException( + "Floodgate cannot remove itself from Bungee without a reboot"); } void injectClient(Channel channel, boolean clientToProxy) { diff --git a/core/src/main/java/org/geysermc/floodgate/FloodgatePlatform.java b/core/src/main/java/org/geysermc/floodgate/FloodgatePlatform.java index 3f511d83..dfb81699 100644 --- a/core/src/main/java/org/geysermc/floodgate/FloodgatePlatform.java +++ b/core/src/main/java/org/geysermc/floodgate/FloodgatePlatform.java @@ -64,20 +64,15 @@ public class FloodgatePlatform { guice.getInstance(NewsChecker.class).start(); } - public boolean enable(Module... postInitializeModules) { + public void enable(Module... postInitializeModules) throws RuntimeException { if (injector == null) { - logger.error("Failed to find the platform injector!"); - return false; + throw new RuntimeException("Failed to find the platform injector!"); } try { - if (!injector.inject()) { - logger.error("Failed to inject the packet listener!"); - return false; - } + injector.inject(); } catch (Exception exception) { - logger.error("Failed to inject the packet listener!", exception); - return false; + throw new RuntimeException("Failed to inject the packet listener!", exception); } this.guice = guice.createChildInjector(new PostInitializeModule(postInitializeModules)); @@ -85,8 +80,6 @@ public class FloodgatePlatform { PrefixCheckTask.checkAndExecuteDelayed(config, logger); guice.getInstance(Metrics.class); - - return true; } public void disable() { @@ -94,11 +87,9 @@ public class FloodgatePlatform { if (injector != null && injector.canRemoveInjection()) { try { - if (!injector.removeInjection()) { - logger.error("Failed to remove the injection!"); - } + injector.removeInjection(); } catch (Exception exception) { - logger.error("Failed to remove the injection!", exception); + throw new RuntimeException("Failed to remove the injection!", exception); } } } diff --git a/core/src/main/java/org/geysermc/floodgate/util/ReflectionUtils.java b/core/src/main/java/org/geysermc/floodgate/util/ReflectionUtils.java index 80352d87..dfbc9d6a 100644 --- a/core/src/main/java/org/geysermc/floodgate/util/ReflectionUtils.java +++ b/core/src/main/java/org/geysermc/floodgate/util/ReflectionUtils.java @@ -424,7 +424,7 @@ public final class ReflectionUtils { } @Nullable - public static Method getMethod( + public static Method getMethodThatReturns( Class clazz, Class returnType, boolean declared, diff --git a/spigot/src/main/java/org/geysermc/floodgate/SpigotPlatform.java b/spigot/src/main/java/org/geysermc/floodgate/SpigotPlatform.java deleted file mode 100644 index f80efeb6..00000000 --- a/spigot/src/main/java/org/geysermc/floodgate/SpigotPlatform.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * @author GeyserMC - * @link https://github.com/GeyserMC/Floodgate - */ - -package org.geysermc.floodgate; - -import com.google.inject.Inject; -import com.google.inject.Module; -import org.bukkit.Bukkit; -import org.bukkit.plugin.java.JavaPlugin; - -public final class SpigotPlatform extends FloodgatePlatform { - @Inject private JavaPlugin plugin; - - @Override - public boolean enable(Module... postInitializeModules) { - boolean success = super.enable(postInitializeModules); - if (!success) { - Bukkit.getPluginManager().disablePlugin(plugin); - return false; - } - return true; - } -} diff --git a/spigot/src/main/java/org/geysermc/floodgate/SpigotPlugin.java b/spigot/src/main/java/org/geysermc/floodgate/SpigotPlugin.java index 6254cc17..2a5af4ee 100644 --- a/spigot/src/main/java/org/geysermc/floodgate/SpigotPlugin.java +++ b/spigot/src/main/java/org/geysermc/floodgate/SpigotPlugin.java @@ -27,6 +27,7 @@ package org.geysermc.floodgate; import com.google.inject.Guice; import com.google.inject.Injector; +import org.bukkit.Bukkit; import org.bukkit.plugin.java.JavaPlugin; import org.geysermc.floodgate.api.handshake.HandshakeHandlers; import org.geysermc.floodgate.api.logger.FloodgateLogger; @@ -43,7 +44,7 @@ import org.geysermc.floodgate.util.SpigotProtocolSupportHandler; import org.geysermc.floodgate.util.SpigotProtocolSupportListener; public final class SpigotPlugin extends JavaPlugin { - private SpigotPlatform platform; + private FloodgatePlatform platform; private Injector injector; @Override @@ -54,7 +55,7 @@ public final class SpigotPlugin extends JavaPlugin { new SpigotPlatformModule(this) ); - platform = injector.getInstance(SpigotPlatform.class); + platform = injector.getInstance(FloodgatePlatform.class); long endCtm = System.currentTimeMillis(); injector.getInstance(FloodgateLogger.class) @@ -66,14 +67,18 @@ public final class SpigotPlugin extends JavaPlugin { boolean usePaperListener = ReflectionUtils.getClassSilently( "com.destroystokyo.paper.event.profile.PreFillProfileEvent") != null; - platform.enable( - new SpigotCommandModule(this), - new SpigotAddonModule(), - new PluginMessageModule(), - (usePaperListener ? new PaperListenerModule() : new SpigotListenerModule()) - ); + try { + platform.enable( + new SpigotCommandModule(this), + new SpigotAddonModule(), + new PluginMessageModule(), + (usePaperListener ? new PaperListenerModule() : new SpigotListenerModule()) + ); + } catch (Exception exception) { + Bukkit.getPluginManager().disablePlugin(this); + throw exception; + } - //todo add proper support for disabling things on shutdown and enabling this on enable injector.getInstance(HandshakeHandlers.class) .addHandshakeHandler(injector.getInstance(SpigotHandshakeHandler.class)); diff --git a/spigot/src/main/java/org/geysermc/floodgate/inject/spigot/SpigotInjector.java b/spigot/src/main/java/org/geysermc/floodgate/inject/spigot/SpigotInjector.java index 9ea99b1a..2a718b0a 100644 --- a/spigot/src/main/java/org/geysermc/floodgate/inject/spigot/SpigotInjector.java +++ b/spigot/src/main/java/org/geysermc/floodgate/inject/spigot/SpigotInjector.java @@ -31,7 +31,6 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.channel.ChannelInitializer; import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; @@ -51,54 +50,56 @@ public final class SpigotInjector extends CommonPlatformInjector { @Override @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") - public boolean inject() throws Exception { + public void inject() throws Exception { if (isInjected()) { - return true; + return; } - if (getServerConnection() != null) { - for (Field field : serverConnection.getClass().getDeclaredFields()) { - if (field.getType() == List.class) { - field.setAccessible(true); + Object serverConnection = getServerConnection(); + if (serverConnection == null) { + throw new RuntimeException("Unable to find server connection"); + } - ParameterizedType parameterType = ((ParameterizedType) field.getGenericType()); - Type listType = parameterType.getActualTypeArguments()[0]; + for (Field field : serverConnection.getClass().getDeclaredFields()) { + if (field.getType() == List.class) { + field.setAccessible(true); - // the list we search has ChannelFuture as type - if (listType != ChannelFuture.class) { - continue; - } + ParameterizedType parameterType = ((ParameterizedType) field.getGenericType()); + Type listType = parameterType.getActualTypeArguments()[0]; - injectedFieldName = field.getName(); - List newList = new CustomList((List) field.get(serverConnection)) { - @Override - public void onAdd(Object object) { - try { - injectClient((ChannelFuture) object); - } catch (Exception exception) { - exception.printStackTrace(); - } - } - }; - - // inject existing - synchronized (newList) { - for (Object object : newList) { - try { - injectClient((ChannelFuture) object); - } catch (Exception exception) { - exception.printStackTrace(); - } - } - } - - field.set(serverConnection, newList); - injected = true; - return true; + // the list we search has ChannelFuture as type + if (listType != ChannelFuture.class) { + continue; } + + injectedFieldName = field.getName(); + List newList = new CustomList((List) field.get(serverConnection)) { + @Override + public void onAdd(Object object) { + try { + injectClient((ChannelFuture) object); + } catch (Exception exception) { + exception.printStackTrace(); + } + } + }; + + // inject existing + synchronized (newList) { + for (Object object : newList) { + try { + injectClient((ChannelFuture) object); + } catch (Exception exception) { + exception.printStackTrace(); + } + } + } + + field.set(serverConnection, newList); + injected = true; + return; } } - return false; } public void injectClient(ChannelFuture future) { @@ -120,9 +121,9 @@ public final class SpigotInjector extends CommonPlatformInjector { } @Override - public boolean removeInjection() throws Exception { + public void removeInjection() { if (!isInjected()) { - return true; + return; } // remove injection from clients @@ -146,10 +147,9 @@ public final class SpigotInjector extends CommonPlatformInjector { } injected = false; - return true; } - public Object getServerConnection() throws IllegalAccessException, InvocationTargetException { + public Object getServerConnection() { if (serverConnection != null) { return serverConnection; } @@ -158,14 +158,11 @@ public final class SpigotInjector extends CommonPlatformInjector { // method by CraftBukkit to get the instance of the MinecraftServer Object minecraftServerInstance = ReflectionUtils.invokeStatic(minecraftServer, "getServer"); - for (Method method : minecraftServer.getDeclaredMethods()) { - if (ClassNames.SERVER_CONNECTION.equals(method.getReturnType())) { - // making sure that it's a getter - if (method.getParameterTypes().length == 0) { - serverConnection = method.invoke(minecraftServerInstance); - } - } - } + Method method = ReflectionUtils.getMethodThatReturns( + minecraftServer, ClassNames.SERVER_CONNECTION, true + ); + + serverConnection = ReflectionUtils.invoke(minecraftServerInstance, method); return serverConnection; } diff --git a/velocity/src/main/java/org/geysermc/floodgate/inject/velocity/VelocityInjector.java b/velocity/src/main/java/org/geysermc/floodgate/inject/velocity/VelocityInjector.java index 1a4d43b1..4d122cf1 100644 --- a/velocity/src/main/java/org/geysermc/floodgate/inject/velocity/VelocityInjector.java +++ b/velocity/src/main/java/org/geysermc/floodgate/inject/velocity/VelocityInjector.java @@ -36,21 +36,19 @@ import io.netty.channel.ChannelInitializer; import java.lang.reflect.Method; import lombok.Getter; import lombok.RequiredArgsConstructor; -import org.geysermc.floodgate.api.logger.FloodgateLogger; import org.geysermc.floodgate.inject.CommonPlatformInjector; @RequiredArgsConstructor public final class VelocityInjector extends CommonPlatformInjector { private final ProxyServer server; - private final FloodgateLogger logger; @Getter private boolean injected; @Override @SuppressWarnings("rawtypes") - public boolean inject() { + public void inject() { if (isInjected()) { - return true; + return; } Object connectionManager = getValue(server, "cm"); @@ -72,7 +70,8 @@ public final class VelocityInjector extends CommonPlatformInjector { Method backendSetter = getMethod(backendInitializerHolder, "set", ChannelInitializer.class); invoke(backendInitializerHolder, backendSetter, new VelocityChannelInitializer(this, backendInitializer, true)); - return injected = true; + + injected = true; } @Override @@ -81,9 +80,9 @@ public final class VelocityInjector extends CommonPlatformInjector { } @Override - public boolean removeInjection() { - logger.error("Floodgate cannot remove itself from Velocity without a reboot"); - return false; + public void removeInjection() { + throw new IllegalStateException( + "Floodgate cannot remove itself from Velocity without a reboot"); } @RequiredArgsConstructor diff --git a/velocity/src/main/java/org/geysermc/floodgate/module/VelocityPlatformModule.java b/velocity/src/main/java/org/geysermc/floodgate/module/VelocityPlatformModule.java index 85fc7be5..b5244c3a 100644 --- a/velocity/src/main/java/org/geysermc/floodgate/module/VelocityPlatformModule.java +++ b/velocity/src/main/java/org/geysermc/floodgate/module/VelocityPlatformModule.java @@ -124,8 +124,8 @@ public final class VelocityPlatformModule extends AbstractModule { @Provides @Singleton - public CommonPlatformInjector platformInjector(ProxyServer server, FloodgateLogger logger) { - return new VelocityInjector(server, logger); + public CommonPlatformInjector platformInjector(ProxyServer server) { + return new VelocityInjector(server); } @Provides