From c4971d5bf3c8ddddd78e071a405b64a830b991f2 Mon Sep 17 00:00:00 2001 From: Tim203 Date: Tue, 13 Oct 2020 20:04:20 +0200 Subject: [PATCH] Added a translate method to the logger and changed the code style a bit --- .idea/codeStyles/Project.xml | 414 +++++++++++++++++- api/pom.xml | 88 ++-- .../geysermc/floodgate/api/FloodgateApi.java | 23 +- .../floodgate/api/InstanceHolder.java | 3 +- .../floodgate/api/inject/InjectorAddon.java | 25 +- .../api/inject/PlatformInjector.java | 30 +- .../floodgate/api/link/LinkRequest.java | 11 +- .../floodgate/api/link/PlayerLink.java | 34 +- .../floodgate/api/logger/FloodgateLogger.java | 7 +- .../floodgate/api/player/FloodgatePlayer.java | 32 +- bungee/pom.xml | 80 ++-- .../org/geysermc/floodgate/BungeePlugin.java | 13 +- .../command/BungeeCommandRegistration.java | 3 +- .../floodgate/handler/BungeeDataHandler.java | 89 ++-- .../inject/bungee/BungeeInjector.java | 19 +- .../floodgate/listener/BungeeListener.java | 13 +- .../module/BungeePlatformModule.java | 4 +- common/pom.xml | 102 ++--- .../geysermc/floodgate/FloodgatePlatform.java | 40 +- .../floodgate/FloodgatePlayerImpl.java | 21 +- .../geysermc/floodgate/HandshakeHandler.java | 36 +- .../floodgate/addon/AddonManagerAddon.java | 2 +- .../geysermc/floodgate/addon/DebugAddon.java | 13 +- .../addon/debug/ChannelInDebugHandler.java | 10 +- .../addon/debug/ChannelOutDebugHandler.java | 7 +- .../floodgate/api/ProxyFloodgateApi.java | 11 +- .../floodgate/api/SimpleFloodgateApi.java | 38 +- .../floodgate/command/LinkAccountCommand.java | 145 +++--- .../command/UnlinkAccountCommand.java | 43 +- .../floodgate/config/FloodgateConfig.java | 28 +- .../config/ProxyFloodgateConfig.java | 3 +- .../floodgate/config/loader/ConfigLoader.java | 32 +- .../config/updater/ConfigFileUpdater.java | 30 +- .../config/updater/ConfigUpdater.java | 19 +- .../inject/CommonPlatformInjector.java | 22 +- .../floodgate/link/CommonPlayerLink.java | 12 +- .../floodgate/link/DisabledPlayerLink.java | 11 +- .../floodgate/link/LinkRequestImpl.java | 5 +- .../floodgate/link/PlayerLinkLoader.java | 20 +- .../logger/JavaUtilFloodgateLogger.java | 14 +- .../floodgate/module/CommonModule.java | 17 +- .../floodgate/platform/command/Command.java | 16 +- .../platform/command/CommandMessage.java | 4 +- .../platform/command/CommandRegistration.java | 7 +- .../platform/command/CommandUtil.java | 4 +- .../listener/ListenerRegistration.java | 6 +- .../floodgate/register/AddonRegister.java | 3 +- .../floodgate/register/CommandRegister.java | 3 +- .../floodgate/register/ListenerRegister.java | 3 +- .../floodgate/util/LanguageManager.java | 70 +-- .../floodgate/util/MessageFormatter.java | 22 +- .../floodgate/util/ReflectionUtils.java | 179 ++++---- database/pom.xml | 49 +-- database/sqlite/pom.xml | 83 ++-- .../floodgate/database/SqliteDatabase.java | 36 +- pom.xml | 68 +-- spigot/pom.xml | 82 ++-- .../geysermc/floodgate/SpigotPlatform.java | 16 +- .../org/geysermc/floodgate/SpigotPlugin.java | 13 +- .../floodgate/addon/data/SpigotDataAddon.java | 8 +- .../addon/data/SpigotDataHandler.java | 181 ++++---- .../command/SpigotCommandRegistration.java | 5 +- .../floodgate/inject/spigot/CustomList.java | 25 +- .../inject/spigot/SpigotInjector.java | 65 +-- .../floodgate/listener/SpigotListener.java | 13 +- .../floodgate/module/SpigotAddonModule.java | 2 +- .../module/SpigotPlatformModule.java | 4 +- velocity/pom.xml | 116 ++--- .../geysermc/floodgate/VelocityPlugin.java | 25 +- .../addon/data/VelocityDataAddon.java | 8 +- .../addon/data/VelocityProxyDataHandler.java | 43 +- .../addon/data/VelocityServerDataHandler.java | 63 +-- .../command/VelocityCommandRegistration.java | 3 +- .../inject/velocity/VelocityInjector.java | 31 +- .../floodgate/listener/VelocityListener.java | 64 +-- .../logger/Slf4jFloodgateLogger.java | 11 +- .../module/VelocityPlatformModule.java | 4 +- .../floodgate/util/VelocityCommandUtil.java | 4 +- 78 files changed, 1644 insertions(+), 1264 deletions(-) diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml index 51348fa5..bda43a71 100644 --- a/.idea/codeStyles/Project.xml +++ b/.idea/codeStyles/Project.xml @@ -1,7 +1,64 @@ + + + \ No newline at end of file diff --git a/api/pom.xml b/api/pom.xml index 6aab86bc..0964aad1 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -2,14 +2,55 @@ + api + + + + org.apache.maven.plugins + maven-shade-plugin + 3.2.1 + + + package + + shade + + + + + ${outputName} + true + + + + + + + + org.geysermc + common + ${geyser.version} + + + io.netty + netty-transport + 4.1.49.Final + provided + + + com.google.code.findbugs + jsr305 + 3.0.2 + + + + 4.0.0 + parent org.geysermc.floodgate 1.0-SNAPSHOT - 4.0.0 - - api @@ -33,45 +74,4 @@ - - - - org.geysermc - common - ${geyser.version} - - - io.netty - netty-transport - 4.1.49.Final - provided - - - com.google.code.findbugs - jsr305 - 3.0.2 - - - - - - - org.apache.maven.plugins - maven-shade-plugin - 3.2.1 - - - package - - shade - - - - - ${outputName} - true - - - - \ No newline at end of file diff --git a/api/src/main/java/org/geysermc/floodgate/api/FloodgateApi.java b/api/src/main/java/org/geysermc/floodgate/api/FloodgateApi.java index beb60efb..7df084ab 100644 --- a/api/src/main/java/org/geysermc/floodgate/api/FloodgateApi.java +++ b/api/src/main/java/org/geysermc/floodgate/api/FloodgateApi.java @@ -25,12 +25,18 @@ package org.geysermc.floodgate.api; +import java.util.UUID; import org.geysermc.floodgate.api.link.PlayerLink; import org.geysermc.floodgate.api.player.FloodgatePlayer; -import java.util.UUID; - public interface FloodgateApi { + /** + * Returns the Floodgate API instance. + */ + static FloodgateApi getInstance() { + return InstanceHolder.getInstance(); + } + /** * Method to determine if the given online player is a bedrock player * @@ -56,9 +62,9 @@ public interface FloodgateApi { UUID createJavaPlayerId(long xuid); /** - * Checks if the uuid of the player has the {@link #createJavaPlayerId(long)} format. - * This method can't validate a linked player uuid, since that doesn't equal the format. - * Use {@link #isBedrockPlayer(UUID)} if you want to include linked accounts. + * Checks if the uuid of the player has the {@link #createJavaPlayerId(long)} format. This + * method can't validate a linked player uuid, since that doesn't equal the format. Use {@link + * #isBedrockPlayer(UUID)} if you want to include linked accounts. * * @param uuid the uuid to check * @return true if the given uuid has the correct format. @@ -71,11 +77,4 @@ public interface FloodgateApi { default PlayerLink getPlayerLink() { return InstanceHolder.getPlayerLink(); } - - /** - * Returns the Floodgate API instance. - */ - static FloodgateApi getInstance() { - return InstanceHolder.getInstance(); - } } diff --git a/api/src/main/java/org/geysermc/floodgate/api/InstanceHolder.java b/api/src/main/java/org/geysermc/floodgate/api/InstanceHolder.java index a08d6882..f66972a0 100644 --- a/api/src/main/java/org/geysermc/floodgate/api/InstanceHolder.java +++ b/api/src/main/java/org/geysermc/floodgate/api/InstanceHolder.java @@ -25,12 +25,11 @@ package org.geysermc.floodgate.api; +import java.util.UUID; import lombok.Getter; import org.geysermc.floodgate.api.inject.PlatformInjector; import org.geysermc.floodgate.api.link.PlayerLink; -import java.util.UUID; - public final class InstanceHolder { @Getter private static FloodgateApi instance; @Getter private static PlayerLink playerLink; diff --git a/api/src/main/java/org/geysermc/floodgate/api/inject/InjectorAddon.java b/api/src/main/java/org/geysermc/floodgate/api/inject/InjectorAddon.java index 1093ff0a..719186cc 100644 --- a/api/src/main/java/org/geysermc/floodgate/api/inject/InjectorAddon.java +++ b/api/src/main/java/org/geysermc/floodgate/api/inject/InjectorAddon.java @@ -29,30 +29,27 @@ import io.netty.channel.Channel; public interface InjectorAddon { /** - * Called when injecting a specific channel - * (every client that is connected to the server has his own channel). - * Internally used for the Floodgate debugger and data handler but can also be used for - * third party things. + * Called when injecting a specific channel (every client that is connected to the server has + * his own channel). Internally used for the Floodgate debugger and data handler but can also be + * used for third party things. * - * @param channel the channel that the injector is injecting - * @param proxyToServer if the the connection is between the proxy and a server + * @param channel the channel that the injector is injecting + * @param toServer if the the connection is between a proxy and a server */ - void onInject(Channel channel, boolean proxyToServer); + void onInject(Channel channel, boolean toServer); /** - * Called when the player successfully logged in. - * That is the moment that most of the addons can deregister. - * Note that it is entirely optional to remove the addon from the channel, - * the injector won't force the addon to remove. + * Called when the player successfully logged in. That is the moment that most of the addons can + * deregister. Note that it is entirely optional to remove the addon from the channel, the + * injector won't force the addon to remove. * * @param channel the channel that the injector injected */ void onLoginDone(Channel channel); /** - * Called when Floodgate is removing the injection from the server. - * The addon should remove his traces otherwise it is likely that an error will popup after - * the server is injected again. + * Called when Floodgate is removing the injection from the server. The addon should remove his + * traces otherwise it is likely that an error will popup after the server is injected again. * * @param channel the channel that the injector injected */ 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 77fbfe8d..715ac90b 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 @@ -26,17 +26,16 @@ package org.geysermc.floodgate.api.inject; /** - * The global interface of all the Platform Injectors. - * The injector can be used for various things. It is used internally for getting Floodgate - * data out of the handshake packet and for debug mode, but there is also an option to add your - * own addons. - * Note that every Floodgate platform that supports netty should implement this, - * but the platform implementation isn't required to implement this. + * The global interface of all the Platform Injectors. The injector can be used for various things. + * It is used internally for getting Floodgate data out of the handshake packet and for debug mode, + * but there is also an option to add your own addons. Note that every Floodgate platform that + * supports netty should implement this, but the platform implementation isn't required to implement + * this. */ public interface PlatformInjector { /** - * Injects the server connection. - * This will allow various addons (like getting the Floodgate data and debug mode) to work. + * 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 @@ -44,9 +43,8 @@ public interface PlatformInjector { boolean inject() throws Exception; /** - * 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. + * 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 @@ -61,9 +59,8 @@ public interface PlatformInjector { boolean isInjected(); /** - * Adds an addon to the addon list of the Floodgate Injector - * (the addon is called when Floodgate injects a channel). - * See {@link InjectorAddon} for more info. + * Adds an addon to the addon list of the Floodgate Injector (the addon is called when Floodgate + * injects a channel). See {@link InjectorAddon} for more info. * * @param addon the addon to add to the addon list * @return true if the addon has been added, false if the addon is already present @@ -71,9 +68,8 @@ public interface PlatformInjector { boolean addAddon(InjectorAddon addon); /** - * Removes an addon from the addon list of the Floodgate Injector - * (the addon is called when Floodgate injects a channel). - * See {@link InjectorAddon} for more info. + * Removes an addon from the addon list of the Floodgate Injector (the addon is called when + * Floodgate injects a channel). See {@link InjectorAddon} for more info. * * @param addon the class of the addon to remove from the addon list * @param the addon type diff --git a/api/src/main/java/org/geysermc/floodgate/api/link/LinkRequest.java b/api/src/main/java/org/geysermc/floodgate/api/link/LinkRequest.java index c4980d89..f91dacb5 100644 --- a/api/src/main/java/org/geysermc/floodgate/api/link/LinkRequest.java +++ b/api/src/main/java/org/geysermc/floodgate/api/link/LinkRequest.java @@ -25,9 +25,8 @@ package org.geysermc.floodgate.api.link; -import org.geysermc.floodgate.api.player.FloodgatePlayer; - import java.util.UUID; +import org.geysermc.floodgate.api.player.FloodgatePlayer; public interface LinkRequest { /** @@ -64,10 +63,10 @@ public interface LinkRequest { boolean isExpired(long linkTimeout); /** - * Checks if the given FloodgatePlayer is the player requested in this LinkRequest. - * This method will check both the real bedrock username - * {@link FloodgatePlayer#getUsername()} and the edited username - * {@link FloodgatePlayer#getJavaUsername()} and returns true if one of the two matches. + * Checks if the given FloodgatePlayer is the player requested in this LinkRequest. This method + * will check both the real bedrock username {@link FloodgatePlayer#getUsername()} and the + * edited username {@link FloodgatePlayer#getJavaUsername()} and returns true if one of the two + * matches. * * @param player the player to check * @return true if the given player is the player requested diff --git a/api/src/main/java/org/geysermc/floodgate/api/link/PlayerLink.java b/api/src/main/java/org/geysermc/floodgate/api/link/PlayerLink.java index 8e7dfcc9..3a6fd8ae 100644 --- a/api/src/main/java/org/geysermc/floodgate/api/link/PlayerLink.java +++ b/api/src/main/java/org/geysermc/floodgate/api/link/PlayerLink.java @@ -25,22 +25,20 @@ package org.geysermc.floodgate.api.link; -import org.geysermc.floodgate.util.LinkedPlayer; - import java.util.UUID; import java.util.concurrent.CompletableFuture; +import org.geysermc.floodgate.util.LinkedPlayer; /** - * The base class of the PlayerLink database implementation. - * The implementation is responsible for making a connection with the database - * and keeping that connection alive so that Floodgate (or a third party plugin) - * can check for example if a given player is linked. + * The base class of the PlayerLink database implementation. The implementation is responsible for + * making a connection with the database and keeping that connection alive so that Floodgate (or a + * third party plugin) can check for example if a given player is linked. */ public interface PlayerLink { /** - * Called by Floodgate after the initialization of the class. - * In this method the implementation should start the connection with the database and - * create the collections if they don't exist already. + * Called by Floodgate after the initialization of the class. In this method the implementation + * should start the connection with the database and create the collections if they don't exist + * already. */ void load(); @@ -48,8 +46,8 @@ public interface PlayerLink { * Get a linked player by the bedrock uuid * * @param bedrockId the uuid of the bedrock player - * @return a completable future with the {@link LinkedPlayer}. - * The future will have a null value if that Bedrock player isn't linked + * @return a completable future with the {@link LinkedPlayer}. The future will have a null value + * if that Bedrock player isn't linked */ CompletableFuture getLinkedPlayer(UUID bedrockId); @@ -80,10 +78,9 @@ public interface PlayerLink { CompletableFuture unlinkPlayer(UUID javaId); /** - * Return if account linking is enabled. - * The difference between enabled and allowed is that 'enabled' still allows already linked - * people to join with their linked account while 'allow linking' allows people to link - * accounts using the commands. + * Return if account linking is enabled. The difference between enabled and allowed is that + * 'enabled' still allows already linked people to join with their linked account while 'allow + * linking' allows people to link accounts using the commands. */ boolean isEnabled(); @@ -93,10 +90,9 @@ public interface PlayerLink { long getVerifyLinkTimeout(); /** - * Return if account linking is allowed. - * The difference between enabled and allowed is that 'enabled' still allows already linked - * people to join with their linked account while 'allow linking' allows people to link - * accounts using the commands. + * Return if account linking is allowed. The difference between enabled and allowed is that + * 'enabled' still allows already linked people to join with their linked account while 'allow + * linking' allows people to link accounts using the commands. */ boolean isAllowLinking(); diff --git a/api/src/main/java/org/geysermc/floodgate/api/logger/FloodgateLogger.java b/api/src/main/java/org/geysermc/floodgate/api/logger/FloodgateLogger.java index d98e04b0..fdcedb13 100644 --- a/api/src/main/java/org/geysermc/floodgate/api/logger/FloodgateLogger.java +++ b/api/src/main/java/org/geysermc/floodgate/api/logger/FloodgateLogger.java @@ -61,6 +61,8 @@ public interface FloodgateLogger { */ void info(String message, Object... args); + void translatedInfo(String message, Object... args); + /** * Logs a debug message to the console, with 0 or more arguments. * @@ -83,9 +85,8 @@ public interface FloodgateLogger { void enableDebug(); /** - * Disables debug mode for the Floodgate logger. - * Debug messages can still be sent after running this method, - * but they will be hidden from the console. + * Disables debug mode for the Floodgate logger. Debug messages can still be sent after running + * this method, but they will be hidden from the console. */ void disableDebug(); } diff --git a/api/src/main/java/org/geysermc/floodgate/api/player/FloodgatePlayer.java b/api/src/main/java/org/geysermc/floodgate/api/player/FloodgatePlayer.java index 60209050..41796821 100644 --- a/api/src/main/java/org/geysermc/floodgate/api/player/FloodgatePlayer.java +++ b/api/src/main/java/org/geysermc/floodgate/api/player/FloodgatePlayer.java @@ -25,35 +25,36 @@ package org.geysermc.floodgate.api.player; -import org.geysermc.floodgate.util.*; - import java.util.UUID; +import org.geysermc.floodgate.util.DeviceOs; +import org.geysermc.floodgate.util.InputMode; +import org.geysermc.floodgate.util.LinkedPlayer; +import org.geysermc.floodgate.util.RawSkin; +import org.geysermc.floodgate.util.UiProfile; public interface FloodgatePlayer { /** - * Returns the Bedrock username that will be used as username on the server. - * This includes replace spaces (if enabled), username shortened and prefix appended.
- * Note that this field is not used when the player is a {@link LinkedPlayer LinkedPlayer} + * Returns the Bedrock username that will be used as username on the server. This includes + * replace spaces (if enabled), username shortened and prefix appended.
Note that this field + * is not used when the player is a {@link LinkedPlayer LinkedPlayer} */ String getJavaUsername(); /** - * Returns the uuid that will be used as UUID on the server.
- * Note that this field is not used when the player is a {@link LinkedPlayer LinkedPlayer} + * Returns the uuid that will be used as UUID on the server.
Note that this field is not + * used when the player is a {@link LinkedPlayer LinkedPlayer} */ UUID getJavaUniqueId(); /** - * Returns the uuid that the server will use as uuid of that player. - * Will return {@link #getJavaUniqueId()} when not linked or - * {@link LinkedPlayer#getJavaUniqueId()} when linked. + * Returns the uuid that the server will use as uuid of that player. Will return {@link + * #getJavaUniqueId()} when not linked or {@link LinkedPlayer#getJavaUniqueId()} when linked. */ UUID getCorrectUniqueId(); /** - * Returns the username the server will as username for that player. - * Will return {@link #getJavaUsername()} when not linked or - * {@link LinkedPlayer#getJavaUsername()} when linked. + * Returns the username the server will as username for that player. Will return {@link + * #getJavaUsername()} when not linked or {@link LinkedPlayer#getJavaUsername()} when linked. */ String getCorrectUsername(); @@ -63,9 +64,8 @@ public interface FloodgatePlayer { String getVersion(); /** - * Returns the real username of the Bedrock client. - * This username doesn't have a prefix, spaces aren't replaced and the username hasn't been - * shortened. + * Returns the real username of the Bedrock client. This username doesn't have a prefix, spaces + * aren't replaced and the username hasn't been shortened. */ String getUsername(); diff --git a/bungee/pom.xml b/bungee/pom.xml index 00dbdc67..12b9f462 100644 --- a/bungee/pom.xml +++ b/bungee/pom.xml @@ -2,47 +2,7 @@ - - parent - org.geysermc.floodgate - 1.0-SNAPSHOT - - 4.0.0 - bungee - - - - bungeecord-repo - https://oss.sonatype.org/content/repositories/snapshots - - - - - - net.md-5 - bungeecord-api - ${bungee.version} - provided - - - net.md-5 - bungeecord-protocol - ${bungee.version} - provided - - - org.geysermc.floodgate - common - ${project.version} - - - org.javassist - javassist - 3.27.0-GA - - - @@ -70,4 +30,44 @@ + + + + net.md-5 + bungeecord-api + ${bungee.version} + provided + + + net.md-5 + bungeecord-protocol + ${bungee.version} + provided + + + org.geysermc.floodgate + common + ${project.version} + + + org.javassist + javassist + 3.27.0-GA + + + + 4.0.0 + + + parent + org.geysermc.floodgate + 1.0-SNAPSHOT + + + + + bungeecord-repo + https://oss.sonatype.org/content/repositories/snapshots + + \ No newline at end of file diff --git a/bungee/src/main/java/org/geysermc/floodgate/BungeePlugin.java b/bungee/src/main/java/org/geysermc/floodgate/BungeePlugin.java index 2d610973..b8bf412d 100644 --- a/bungee/src/main/java/org/geysermc/floodgate/BungeePlugin.java +++ b/bungee/src/main/java/org/geysermc/floodgate/BungeePlugin.java @@ -28,7 +28,12 @@ package org.geysermc.floodgate; import com.google.inject.Guice; import com.google.inject.Injector; import net.md_5.bungee.api.plugin.Plugin; -import org.geysermc.floodgate.module.*; +import org.geysermc.floodgate.api.logger.FloodgateLogger; +import org.geysermc.floodgate.module.BungeeAddonModule; +import org.geysermc.floodgate.module.BungeeListenerModule; +import org.geysermc.floodgate.module.BungeePlatformModule; +import org.geysermc.floodgate.module.CommandModule; +import org.geysermc.floodgate.module.CommonModule; import org.geysermc.floodgate.util.ReflectionUtils; public final class BungeePlugin extends Plugin { @@ -49,10 +54,8 @@ public final class BungeePlugin extends Plugin { platform = injector.getInstance(FloodgatePlatform.class); long endCtm = System.currentTimeMillis(); - getLogger().info(platform.getLanguageManager().getLogString( - "floodgate.core.finish", - endCtm - ctm - )); + injector.getInstance(FloodgateLogger.class) + .translatedInfo("floodgate.core.finish", endCtm - ctm); } @Override diff --git a/bungee/src/main/java/org/geysermc/floodgate/command/BungeeCommandRegistration.java b/bungee/src/main/java/org/geysermc/floodgate/command/BungeeCommandRegistration.java index e54a2cef..10311896 100644 --- a/bungee/src/main/java/org/geysermc/floodgate/command/BungeeCommandRegistration.java +++ b/bungee/src/main/java/org/geysermc/floodgate/command/BungeeCommandRegistration.java @@ -25,6 +25,7 @@ package org.geysermc.floodgate.command; +import java.util.Locale; import lombok.RequiredArgsConstructor; import net.md_5.bungee.api.CommandSender; import net.md_5.bungee.api.ProxyServer; @@ -35,8 +36,6 @@ import org.geysermc.floodgate.platform.command.CommandRegistration; import org.geysermc.floodgate.platform.command.CommandUtil; import org.geysermc.floodgate.util.LanguageManager; -import java.util.Locale; - @RequiredArgsConstructor public final class BungeeCommandRegistration implements CommandRegistration { private final BungeePlugin plugin; diff --git a/bungee/src/main/java/org/geysermc/floodgate/handler/BungeeDataHandler.java b/bungee/src/main/java/org/geysermc/floodgate/handler/BungeeDataHandler.java index aa0cb189..8bc136ce 100644 --- a/bungee/src/main/java/org/geysermc/floodgate/handler/BungeeDataHandler.java +++ b/bungee/src/main/java/org/geysermc/floodgate/handler/BungeeDataHandler.java @@ -25,10 +25,16 @@ package org.geysermc.floodgate.handler; +import static com.google.common.base.Preconditions.checkNotNull; +import static org.geysermc.floodgate.HandshakeHandler.ResultType; + import com.google.inject.Inject; import com.google.inject.name.Named; import io.netty.channel.Channel; import io.netty.util.AttributeKey; +import java.lang.reflect.Field; +import java.net.InetSocketAddress; +import java.net.SocketAddress; import net.md_5.bungee.api.connection.ProxiedPlayer; import net.md_5.bungee.api.event.PreLoginEvent; import net.md_5.bungee.api.plugin.Plugin; @@ -42,13 +48,6 @@ import org.geysermc.floodgate.config.ProxyFloodgateConfig; import org.geysermc.floodgate.util.BedrockData; import org.geysermc.floodgate.util.ReflectionUtils; -import java.lang.reflect.Field; -import java.net.InetSocketAddress; -import java.net.SocketAddress; - -import static com.google.common.base.Preconditions.checkNotNull; -import static org.geysermc.floodgate.HandshakeHandler.ResultType; - public final class BungeeDataHandler { private static final Field EXTRA_HANDSHAKE_DATA; private static final Field PLAYER_NAME; @@ -57,31 +56,38 @@ public final class BungeeDataHandler { private static final Field PLAYER_REMOTE_ADDRESS; private static final Field CACHED_HANDSHAKE_PACKET; - @Inject - private Plugin plugin; - @Inject - private ProxyFloodgateConfig config; - @Inject - private ProxyFloodgateApi api; - @Inject - private HandshakeHandler handler; + static { + Class initialHandler = ReflectionUtils.getPrefixedClass("connection.InitialHandler"); + EXTRA_HANDSHAKE_DATA = ReflectionUtils.getField(initialHandler, "extraDataInHandshake"); + checkNotNull(EXTRA_HANDSHAKE_DATA, "extraDataInHandshake field cannot be null"); + + PLAYER_NAME = ReflectionUtils.getField(initialHandler, "name"); + checkNotNull(PLAYER_NAME, "Initial name field cannot be null"); + + Class channelWrapper = ReflectionUtils.getPrefixedClass("netty.ChannelWrapper"); + PLAYER_CHANNEL_WRAPPER = ReflectionUtils.getFieldOfType(initialHandler, channelWrapper); + checkNotNull(PLAYER_CHANNEL_WRAPPER, "ChannelWrapper field cannot be null"); + + PLAYER_CHANNEL = ReflectionUtils.getFieldOfType(channelWrapper, Channel.class); + checkNotNull(PLAYER_CHANNEL, "Channel field cannot be null"); + + PLAYER_REMOTE_ADDRESS = ReflectionUtils.getFieldOfType(channelWrapper, SocketAddress.class); + checkNotNull(PLAYER_REMOTE_ADDRESS, "Remote address field cannot be null"); + + Class handshakePacket = ReflectionUtils.getPrefixedClass("protocol.packet.Handshake"); + CACHED_HANDSHAKE_PACKET = ReflectionUtils.getFieldOfType(initialHandler, handshakePacket); + checkNotNull(CACHED_HANDSHAKE_PACKET, "Cached handshake packet field cannot be null"); + } + @Inject @Named("playerAttribute") private AttributeKey playerAttribute; - @Inject - private FloodgateLogger logger; - public BungeeDataHandler(Plugin plugin, ProxyFloodgateConfig config, - ProxyFloodgateApi api, HandshakeHandler handshakeHandler, - AttributeKey playerAttribute, - FloodgateLogger logger) { - this.plugin = plugin; - this.config = config; - this.handler = handshakeHandler; - this.api = api; - this.playerAttribute = playerAttribute; - this.logger = logger; - } + @Inject private Plugin plugin; + @Inject private ProxyFloodgateConfig config; + @Inject private ProxyFloodgateApi api; + @Inject private HandshakeHandler handler; + @Inject private FloodgateLogger logger; public void handlePreLogin(PreLoginEvent event) { event.registerIntent(plugin); @@ -129,8 +135,8 @@ public final class BungeeDataHandler { channel.attr(playerAttribute).set(player); if (!(remoteAddress instanceof InetSocketAddress)) { - logger.info("Player {} doesn't use an InetSocketAddress. " + - "It uses {}. Ignoring the player, I guess.", + logger.info("Player {} doesn't use an InetSocketAddress, it uses {}. " + + "Ignoring the player, I guess.", player.getUsername(), remoteAddress.getClass().getSimpleName() ); } else { @@ -159,27 +165,4 @@ public final class BungeeDataHandler { // Bungeecord will add his data after our data } } - - static { - Class initialHandler = ReflectionUtils.getPrefixedClass("connection.InitialHandler"); - EXTRA_HANDSHAKE_DATA = ReflectionUtils.getField(initialHandler, "extraDataInHandshake"); - checkNotNull(EXTRA_HANDSHAKE_DATA, "extraDataInHandshake field cannot be null"); - - PLAYER_NAME = ReflectionUtils.getField(initialHandler, "name"); - checkNotNull(PLAYER_NAME, "Initial name field cannot be null"); - - Class channelWrapper = ReflectionUtils.getPrefixedClass("netty.ChannelWrapper"); - PLAYER_CHANNEL_WRAPPER = ReflectionUtils.getFieldOfType(initialHandler, channelWrapper); - checkNotNull(PLAYER_CHANNEL_WRAPPER, "ChannelWrapper field cannot be null"); - - PLAYER_CHANNEL = ReflectionUtils.getFieldOfType(channelWrapper, Channel.class); - checkNotNull(PLAYER_CHANNEL, "Channel field cannot be null"); - - PLAYER_REMOTE_ADDRESS = ReflectionUtils.getFieldOfType(channelWrapper, SocketAddress.class); - checkNotNull(PLAYER_REMOTE_ADDRESS, "Remote address field cannot be null"); - - Class handshakePacket = ReflectionUtils.getPrefixedClass("protocol.packet.Handshake"); - CACHED_HANDSHAKE_PACKET = ReflectionUtils.getFieldOfType(initialHandler, handshakePacket); - checkNotNull(CACHED_HANDSHAKE_PACKET, "Cached handshake packet field cannot be null"); - } } 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 4ecef4f7..2b53ace9 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 @@ -26,21 +26,23 @@ package org.geysermc.floodgate.inject.bungee; import io.netty.channel.Channel; -import javassist.*; +import java.util.function.Consumer; +import javassist.ClassPool; +import javassist.CtClass; +import javassist.CtField; +import javassist.CtMethod; +import javassist.Modifier; +import javax.naming.OperationNotSupportedException; import lombok.Getter; import lombok.RequiredArgsConstructor; import org.geysermc.floodgate.api.logger.FloodgateLogger; import org.geysermc.floodgate.inject.CommonPlatformInjector; import org.geysermc.floodgate.util.ReflectionUtils; -import javax.naming.OperationNotSupportedException; -import java.util.function.Consumer; - @RequiredArgsConstructor public final class BungeeInjector extends CommonPlatformInjector { private final FloodgateLogger logger; - @Getter - private boolean injected; + @Getter private boolean injected; @Override public boolean inject() { @@ -54,7 +56,8 @@ public final class BungeeInjector extends CommonPlatformInjector { // create a new field that we can access CtField channelConsumerField = new CtField( - classPool.get("java.util.function.Consumer"), "channelConsumer", handlerBossClass + classPool.get("java.util.function.Consumer"), "channelConsumer", + handlerBossClass ); channelConsumerField.setModifiers(Modifier.PUBLIC | Modifier.STATIC); handlerBossClass.addField(channelConsumerField); @@ -62,7 +65,7 @@ public final class BungeeInjector extends CommonPlatformInjector { // edit a method to call the new field when we need it CtMethod channelActiveMethod = handlerBossClass.getMethod( "channelActive", "(Lio/netty/channel/ChannelHandlerContext;)V"); - channelActiveMethod.insertBefore("" + + channelActiveMethod.insertBefore( "{if (handler != null) {channelConsumer.accept(ctx.channel());}}"); Class clazz = handlerBossClass.toClass(); diff --git a/bungee/src/main/java/org/geysermc/floodgate/listener/BungeeListener.java b/bungee/src/main/java/org/geysermc/floodgate/listener/BungeeListener.java index 4952a496..f9840e4b 100644 --- a/bungee/src/main/java/org/geysermc/floodgate/listener/BungeeListener.java +++ b/bungee/src/main/java/org/geysermc/floodgate/listener/BungeeListener.java @@ -27,6 +27,7 @@ package org.geysermc.floodgate.listener; import com.google.inject.Inject; import com.google.inject.Injector; +import java.util.UUID; import net.md_5.bungee.api.connection.ProxiedPlayer; import net.md_5.bungee.api.event.LoginEvent; import net.md_5.bungee.api.event.PlayerDisconnectEvent; @@ -42,8 +43,6 @@ import org.geysermc.floodgate.api.player.FloodgatePlayer; import org.geysermc.floodgate.handler.BungeeDataHandler; import org.geysermc.floodgate.util.LanguageManager; -import java.util.UUID; - public final class BungeeListener implements Listener { private BungeeDataHandler dataHandler; @Inject private ProxyFloodgateApi api; @@ -80,8 +79,10 @@ public final class BungeeListener implements Listener { FloodgatePlayer player = api.getPlayer(uniqueId); if (player != null) { player.as(FloodgatePlayerImpl.class).setLogin(false); - logger.info(languageManager.getLogString("floodgate.ingame.login_name", - player.getCorrectUsername(), player.getCorrectUniqueId())); + logger.translatedInfo( + "floodgate.ingame.login_name", + player.getCorrectUsername(), uniqueId + ); languageManager.loadLocale(player.getLanguageCode()); } } @@ -98,9 +99,7 @@ public final class BungeeListener implements Listener { ProxiedPlayer player = event.getPlayer(); if (api.removePlayer(player.getUniqueId()) != null) { api.removeEncryptedData(player.getUniqueId()); - logger.info(languageManager.getLogString( - "floodgate.ingame.disconnect_name", player.getName()) - ); + logger.translatedInfo("floodgate.ingame.disconnect_name", player.getName()); } } } diff --git a/bungee/src/main/java/org/geysermc/floodgate/module/BungeePlatformModule.java b/bungee/src/main/java/org/geysermc/floodgate/module/BungeePlatformModule.java index d7ae54d0..e80fbd71 100644 --- a/bungee/src/main/java/org/geysermc/floodgate/module/BungeePlatformModule.java +++ b/bungee/src/main/java/org/geysermc/floodgate/module/BungeePlatformModule.java @@ -80,8 +80,8 @@ public final class BungeePlatformModule extends AbstractModule { @Provides @Singleton - public FloodgateLogger floodgateLogger() { - return new JavaUtilFloodgateLogger(plugin.getLogger()); + public FloodgateLogger floodgateLogger(LanguageManager languageManager) { + return new JavaUtilFloodgateLogger(plugin.getLogger(), languageManager); } /* diff --git a/common/pom.xml b/common/pom.xml index fe1bf758..b803f004 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -2,37 +2,28 @@ - - parent - org.geysermc.floodgate - 1.0-SNAPSHOT - - 4.0.0 - common - - - - nukkitx-release-repo - https://repo.nukkitx.com/maven-releases/ - - true - - - false - - - - nukkitx-snapshot-repo - https://repo.nukkitx.com/maven-snapshots/ - - false - - - true - - - + + + + org.apache.maven.plugins + maven-shade-plugin + 3.2.1 + + + package + + shade + + + + + ${outputName} + true + + + + @@ -64,25 +55,34 @@ - - - - org.apache.maven.plugins - maven-shade-plugin - 3.2.1 - - - package - - shade - - - - - ${outputName} - true - - - - + 4.0.0 + + + parent + org.geysermc.floodgate + 1.0-SNAPSHOT + + + + + nukkitx-release-repo + https://repo.nukkitx.com/maven-releases/ + + true + + + false + + + + nukkitx-snapshot-repo + https://repo.nukkitx.com/maven-snapshots/ + + false + + + true + + + \ No newline at end of file diff --git a/common/src/main/java/org/geysermc/floodgate/FloodgatePlatform.java b/common/src/main/java/org/geysermc/floodgate/FloodgatePlatform.java index 27d8ba62..b778dcf0 100644 --- a/common/src/main/java/org/geysermc/floodgate/FloodgatePlatform.java +++ b/common/src/main/java/org/geysermc/floodgate/FloodgatePlatform.java @@ -29,8 +29,9 @@ import com.google.inject.Inject; import com.google.inject.Injector; import com.google.inject.Module; import com.google.inject.name.Named; -import lombok.AccessLevel; -import lombok.Getter; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.UUID; import org.geysermc.floodgate.api.FloodgateApi; import org.geysermc.floodgate.api.InstanceHolder; import org.geysermc.floodgate.api.inject.PlatformInjector; @@ -43,35 +44,30 @@ import org.geysermc.floodgate.module.ConfigLoadedModule; import org.geysermc.floodgate.module.PostInitializeModule; import org.geysermc.floodgate.util.LanguageManager; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.UUID; - public class FloodgatePlatform { private static final UUID KEY = UUID.randomUUID(); - - private final FloodgateConfig config; private final FloodgateApi api; + private final LanguageManager languageManager; + private final PlatformInjector injector; private final FloodgateLogger logger; - @Getter(AccessLevel.PROTECTED) - private final LanguageManager languageManager; - - private final Injector guice; + private FloodgateConfig config; + private Injector guice; @Inject - private PlatformInjector injector; - - @Inject - public FloodgatePlatform(@Named("dataDirectory") Path dataDirectory, FloodgateApi api, - ConfigLoader configLoader, PlayerLinkLoader playerLinkLoader, - HandshakeHandler handshakeHandler, FloodgateLogger logger, - PlatformInjector platformInjector, LanguageManager languageManager, - Injector injector) { + public FloodgatePlatform(FloodgateApi api, LanguageManager languageManager, + PlatformInjector platformInjector, FloodgateLogger logger) { this.api = api; - this.logger = logger; this.languageManager = languageManager; + this.injector = platformInjector; + this.logger = logger; + } + + @Inject + public void init(@Named("dataDirectory") Path dataDirectory, ConfigLoader configLoader, + PlayerLinkLoader playerLinkLoader, HandshakeHandler handshakeHandler, + Injector injector) { if (!Files.isDirectory(dataDirectory)) { try { @@ -96,7 +92,7 @@ public class FloodgatePlatform { PlayerLink link = playerLinkLoader.load(); - InstanceHolder.setInstance(api, link, platformInjector, KEY); + InstanceHolder.setInstance(api, link, this.injector, KEY); } public boolean enable(Module... postInitializeModules) { diff --git a/common/src/main/java/org/geysermc/floodgate/FloodgatePlayerImpl.java b/common/src/main/java/org/geysermc/floodgate/FloodgatePlayerImpl.java index f80e78dc..06d2f01d 100644 --- a/common/src/main/java/org/geysermc/floodgate/FloodgatePlayerImpl.java +++ b/common/src/main/java/org/geysermc/floodgate/FloodgatePlayerImpl.java @@ -25,6 +25,9 @@ package org.geysermc.floodgate; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; import lombok.Getter; import lombok.Setter; import org.geysermc.floodgate.api.FloodgateApi; @@ -32,11 +35,12 @@ import org.geysermc.floodgate.api.InstanceHolder; import org.geysermc.floodgate.api.ProxyFloodgateApi; import org.geysermc.floodgate.api.link.PlayerLink; import org.geysermc.floodgate.api.player.FloodgatePlayer; -import org.geysermc.floodgate.util.*; - -import java.util.UUID; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; +import org.geysermc.floodgate.util.BedrockData; +import org.geysermc.floodgate.util.DeviceOs; +import org.geysermc.floodgate.util.InputMode; +import org.geysermc.floodgate.util.LinkedPlayer; +import org.geysermc.floodgate.util.RawSkin; +import org.geysermc.floodgate.util.UiProfile; @Getter public final class FloodgatePlayerImpl implements FloodgatePlayer { @@ -57,8 +61,7 @@ public final class FloodgatePlayerImpl implements FloodgatePlayer { /** * Returns true if the player is still logging in */ - @Setter - private boolean login = true; + @Setter private boolean login = true; FloodgatePlayerImpl(BedrockData data, RawSkin skin, String prefix, boolean replaceSpaces) { FloodgateApi api = FloodgateApi.getInstance(); @@ -130,8 +133,8 @@ public final class FloodgatePlayerImpl implements FloodgatePlayer { /** * Fetch and return the LinkedPlayer object associated to the player if the player is linked. * - * @return a future holding the LinkedPlayer or null if the player isn't linked or when - * linking isn't enabled + * @return a future holding the LinkedPlayer or null if the player isn't linked or when linking + * isn't enabled * @see #fetchLinkedPlayer(PlayerLink) for the sync version */ public CompletableFuture fetchLinkedPlayerAsync(PlayerLink link) { diff --git a/common/src/main/java/org/geysermc/floodgate/HandshakeHandler.java b/common/src/main/java/org/geysermc/floodgate/HandshakeHandler.java index 313fd699..60fd29f0 100644 --- a/common/src/main/java/org/geysermc/floodgate/HandshakeHandler.java +++ b/common/src/main/java/org/geysermc/floodgate/HandshakeHandler.java @@ -25,9 +25,15 @@ package org.geysermc.floodgate; +import static org.geysermc.floodgate.util.BedrockData.EXPECTED_LENGTH; + import com.google.common.base.Charsets; import com.google.inject.Inject; -import lombok.*; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; import org.geysermc.floodgate.api.SimpleFloodgateApi; import org.geysermc.floodgate.api.player.FloodgatePlayer; import org.geysermc.floodgate.config.FloodgateConfig; @@ -37,8 +43,6 @@ import org.geysermc.floodgate.util.BedrockData; import org.geysermc.floodgate.util.InvalidFormatException; import org.geysermc.floodgate.util.RawSkin; -import static org.geysermc.floodgate.util.BedrockData.EXPECTED_LENGTH; - @RequiredArgsConstructor public final class HandshakeHandler { private final SimpleFloodgateApi api; @@ -122,19 +126,6 @@ public final class HandshakeHandler { } } - @AllArgsConstructor(access = AccessLevel.PROTECTED) - @Getter - public static class HandshakeResult { - private final ResultType resultType; - private final String[] handshakeData; - private final BedrockData bedrockData; - private final FloodgatePlayer floodgatePlayer; - - public boolean isBungeeData() { - return handshakeData.length == 4 || handshakeData.length == 5; - } - } - public enum ResultType { EXCEPTION, NOT_FLOODGATE_DATA, @@ -148,4 +139,17 @@ public final class HandshakeHandler { cachedResult = new HandshakeResult(this, null, null, null); } } + + @AllArgsConstructor(access = AccessLevel.PROTECTED) + @Getter + public static class HandshakeResult { + private final ResultType resultType; + private final String[] handshakeData; + private final BedrockData bedrockData; + private final FloodgatePlayer floodgatePlayer; + + public boolean isBungeeData() { + return handshakeData.length == 4 || handshakeData.length == 5; + } + } } diff --git a/common/src/main/java/org/geysermc/floodgate/addon/AddonManagerAddon.java b/common/src/main/java/org/geysermc/floodgate/addon/AddonManagerAddon.java index 7cf98b83..c0c21923 100644 --- a/common/src/main/java/org/geysermc/floodgate/addon/AddonManagerAddon.java +++ b/common/src/main/java/org/geysermc/floodgate/addon/AddonManagerAddon.java @@ -36,7 +36,7 @@ public final class AddonManagerAddon implements InjectorAddon { @Inject private CommonPlatformInjector injector; @Override - public void onInject(Channel channel, boolean proxyToServer) { + public void onInject(Channel channel, boolean toServer) { channel.pipeline().addLast("floodgate_addon", new AddonManagerHandler(injector, channel)); } diff --git a/common/src/main/java/org/geysermc/floodgate/addon/DebugAddon.java b/common/src/main/java/org/geysermc/floodgate/addon/DebugAddon.java index ff51c7c1..7a3a1780 100644 --- a/common/src/main/java/org/geysermc/floodgate/addon/DebugAddon.java +++ b/common/src/main/java/org/geysermc/floodgate/addon/DebugAddon.java @@ -28,6 +28,7 @@ package org.geysermc.floodgate.addon; import com.google.inject.Inject; import com.google.inject.name.Named; import io.netty.channel.Channel; +import io.netty.channel.ChannelPipeline; import org.geysermc.floodgate.addon.debug.ChannelInDebugHandler; import org.geysermc.floodgate.addon.debug.ChannelOutDebugHandler; import org.geysermc.floodgate.api.inject.InjectorAddon; @@ -51,13 +52,13 @@ public final class DebugAddon implements InjectorAddon { private String packetDecoder; @Override - public void onInject(Channel channel, boolean proxyToServer) { + public void onInject(Channel channel, boolean toServer) { channel.pipeline().addBefore( packetEncoder, "floodgate_debug_out", - new ChannelOutDebugHandler(implementationName, !proxyToServer, logger) + new ChannelOutDebugHandler(implementationName, toServer, logger) ).addBefore( packetDecoder, "floodgate_debug_in", - new ChannelInDebugHandler(logger, implementationName, !proxyToServer) + new ChannelInDebugHandler(implementationName, toServer, logger) ); } @@ -68,8 +69,10 @@ public final class DebugAddon implements InjectorAddon { @Override public void onRemoveInject(Channel channel) { - channel.pipeline().remove("floodgate_debug_out"); - channel.pipeline().remove("floodgate_debug_in"); + ChannelPipeline pipeline = channel.pipeline(); + + pipeline.remove("floodgate_debug_out"); + pipeline.remove("floodgate_debug_in"); } @Override diff --git a/common/src/main/java/org/geysermc/floodgate/addon/debug/ChannelInDebugHandler.java b/common/src/main/java/org/geysermc/floodgate/addon/debug/ChannelInDebugHandler.java index 2c651c56..c609ac5b 100644 --- a/common/src/main/java/org/geysermc/floodgate/addon/debug/ChannelInDebugHandler.java +++ b/common/src/main/java/org/geysermc/floodgate/addon/debug/ChannelInDebugHandler.java @@ -35,17 +35,21 @@ public final class ChannelInDebugHandler extends SimpleChannelInboundHandler" : "Player ->") + ' ' + implementationType; this.logger = logger; - this.message = (player ? "Player ->" : "Server ->") + ' ' + implementationType; } @Override protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) { int index = msg.readerIndex(); + logger.info("{}:\n{}", message, ByteBufUtil.prettyHexDump(msg)); + + // reset index msg.readerIndex(index); + ctx.fireChannelRead(msg.retain()); } } diff --git a/common/src/main/java/org/geysermc/floodgate/addon/debug/ChannelOutDebugHandler.java b/common/src/main/java/org/geysermc/floodgate/addon/debug/ChannelOutDebugHandler.java index 716a72f1..6cac869a 100644 --- a/common/src/main/java/org/geysermc/floodgate/addon/debug/ChannelOutDebugHandler.java +++ b/common/src/main/java/org/geysermc/floodgate/addon/debug/ChannelOutDebugHandler.java @@ -35,18 +35,21 @@ public final class ChannelOutDebugHandler extends MessageToByteEncoder private final String direction; private final FloodgateLogger logger; - public ChannelOutDebugHandler(String implementationType, boolean player, + public ChannelOutDebugHandler(String implementationType, boolean toServer, FloodgateLogger logger) { - this.direction = implementationType + (player ? " -> Player" : " -> Server"); + this.direction = implementationType + (toServer ? " -> Server" : " -> Player"); this.logger = logger; } @Override protected void encode(ChannelHandlerContext ctx, ByteBuf msg, ByteBuf out) { int index = msg.readerIndex(); + logger.info("{}:\n{}", direction, ByteBufUtil.prettyHexDump(msg)); + // reset index msg.readerIndex(index); + out.writeBytes(msg); } } diff --git a/common/src/main/java/org/geysermc/floodgate/api/ProxyFloodgateApi.java b/common/src/main/java/org/geysermc/floodgate/api/ProxyFloodgateApi.java index 53c5dbed..c6048846 100644 --- a/common/src/main/java/org/geysermc/floodgate/api/ProxyFloodgateApi.java +++ b/common/src/main/java/org/geysermc/floodgate/api/ProxyFloodgateApi.java @@ -25,15 +25,13 @@ package org.geysermc.floodgate.api; -import lombok.RequiredArgsConstructor; -import org.geysermc.floodgate.crypto.FloodgateCipher; -import org.geysermc.floodgate.util.BedrockData; - import java.nio.charset.StandardCharsets; -import java.util.Base64; import java.util.HashMap; import java.util.Map; import java.util.UUID; +import lombok.RequiredArgsConstructor; +import org.geysermc.floodgate.crypto.FloodgateCipher; +import org.geysermc.floodgate.util.BedrockData; @RequiredArgsConstructor public final class ProxyFloodgateApi extends SimpleFloodgateApi { @@ -55,9 +53,6 @@ public final class ProxyFloodgateApi extends SimpleFloodgateApi { public void updateEncryptedData(UUID uuid, BedrockData bedrockData) { try { byte[] encryptedData = cipher.encryptFromString(bedrockData.toString()); - encryptedData = Base64.getEncoder().encode(encryptedData); - //todo maybe bake Base64 support into it? - addEncryptedData(uuid, new String(encryptedData, StandardCharsets.UTF_8)); } catch (Exception exception) { throw new IllegalStateException("We failed to update the BedrockData, " + diff --git a/common/src/main/java/org/geysermc/floodgate/api/SimpleFloodgateApi.java b/common/src/main/java/org/geysermc/floodgate/api/SimpleFloodgateApi.java index 9d13c52d..7b9b9a83 100644 --- a/common/src/main/java/org/geysermc/floodgate/api/SimpleFloodgateApi.java +++ b/common/src/main/java/org/geysermc/floodgate/api/SimpleFloodgateApi.java @@ -25,14 +25,13 @@ package org.geysermc.floodgate.api; -import lombok.RequiredArgsConstructor; -import org.geysermc.floodgate.FloodgatePlayerImpl; -import org.geysermc.floodgate.api.player.FloodgatePlayer; - -import javax.annotation.Nullable; import java.util.HashMap; import java.util.Map; import java.util.UUID; +import javax.annotation.Nullable; +import lombok.RequiredArgsConstructor; +import org.geysermc.floodgate.FloodgatePlayerImpl; +import org.geysermc.floodgate.api.player.FloodgatePlayer; @RequiredArgsConstructor public class SimpleFloodgateApi implements FloodgateApi { @@ -84,29 +83,34 @@ public class SimpleFloodgateApi implements FloodgateApi { */ @Nullable public FloodgatePlayer removePlayer(UUID onlineId, boolean removeLogin) { - FloodgatePlayer player = players.get(onlineId); + FloodgatePlayer selfPlayer = players.get(onlineId); // the player is a non-linked player or a linked player but somehow someone tried to // remove the player by his xuid, we have to find out - if (player != null) { + if (selfPlayer != null) { // we don't allow them to remove a player by his xuid // because a linked player is never registered by his linked java uuid - if (player.getLinkedPlayer() != null) return null; + if (selfPlayer.getLinkedPlayer() != null) { + return null; + } // removeLogin logic - if (!shouldRemove(player, removeLogin)) return null; + if (!shouldRemove(selfPlayer, removeLogin)) { + return null; + } // passed the test players.remove(onlineId); // was the account linked? - return player; + return selfPlayer; } // we still want to be able to remove a linked-player by his linked java uuid - for (FloodgatePlayer player1 : players.values()) { - if (!shouldRemove(player1, removeLogin)) continue; - if (!player1.getCorrectUniqueId().equals(onlineId)) continue; - players.remove(player1.getJavaUniqueId()); - return player1; + for (FloodgatePlayer player : players.values()) { + if (shouldRemove(player, removeLogin) && player.getCorrectUniqueId().equals(onlineId)) { + continue; + } + players.remove(player.getJavaUniqueId()); + return player; } return null; @@ -125,8 +129,8 @@ public class SimpleFloodgateApi implements FloodgateApi { } /** - * Equivalent of {@link #removePlayer(UUID, boolean)} except that it removes a - * FloodgatePlayer instance directly. + * Equivalent of {@link #removePlayer(UUID, boolean)} except that it removes a FloodgatePlayer + * instance directly. */ public boolean removePlayer(FloodgatePlayer player) { boolean removed = players.remove(player.getJavaUniqueId(), player); diff --git a/common/src/main/java/org/geysermc/floodgate/command/LinkAccountCommand.java b/common/src/main/java/org/geysermc/floodgate/command/LinkAccountCommand.java index 08776db8..0daf65a0 100644 --- a/common/src/main/java/org/geysermc/floodgate/command/LinkAccountCommand.java +++ b/common/src/main/java/org/geysermc/floodgate/command/LinkAccountCommand.java @@ -26,6 +26,10 @@ package org.geysermc.floodgate.command; import com.google.inject.Inject; +import java.util.HashMap; +import java.util.Map; +import java.util.Random; +import java.util.UUID; import lombok.Getter; import lombok.NoArgsConstructor; import org.geysermc.floodgate.api.FloodgateApi; @@ -36,11 +40,6 @@ import org.geysermc.floodgate.platform.command.Command; import org.geysermc.floodgate.platform.command.CommandMessage; import org.geysermc.floodgate.platform.command.CommandUtil; -import java.util.HashMap; -import java.util.Map; -import java.util.Random; -import java.util.UUID; - @NoArgsConstructor public final class LinkAccountCommand implements Command { private final Map activeLinkRequests = new HashMap<>(); @@ -56,77 +55,78 @@ public final class LinkAccountCommand implements Command { return; } - link.isLinkedPlayer(uuid).whenComplete((linked, throwable) -> { - if (throwable != null) { - sendMessage(player, locale, CommonCommandMessage.IS_LINKED_ERROR); - return; - } + link.isLinkedPlayer(uuid) + .whenComplete((linked, throwable) -> { + if (throwable != null) { + sendMessage(player, locale, CommonCommandMessage.IS_LINKED_ERROR); + return; + } - if (linked) { - sendMessage(player, locale, Message.ALREADY_LINKED); - return; - } + if (linked) { + sendMessage(player, locale, Message.ALREADY_LINKED); + return; + } - // when the player is a Java player - if (!api.isBedrockPlayer(uuid)) { - if (args.length != 1) { - sendMessage(player, locale, Message.JAVA_USAGE); - return; - } - - String code = String.format("%04d", new Random().nextInt(10000)); - String bedrockUsername = args[0]; - - LinkRequest linkRequest = - new LinkRequestImpl(username, uuid, code, bedrockUsername); - - activeLinkRequests.put(username, linkRequest); - sendMessage( - player, locale, Message.LINK_REQUEST_CREATED, - bedrockUsername, username, code - ); - return; - } - - // when the player is a Bedrock player - - if (args.length != 2) { - sendMessage(player, locale, Message.BEDROCK_USAGE); - return; - } - - String javaUsername = args[0]; - String code = args[1]; - LinkRequest request = activeLinkRequests.getOrDefault(javaUsername, null); - if (request == null || !request.isRequestedPlayer(api.getPlayer(uuid))) { - sendMessage(player, locale, Message.NO_LINK_REQUESTED); - return; - } - - if (!request.getLinkCode().equals(code)) { - sendMessage(player, locale, Message.INVALID_CODE); - return; - } - - // Delete the request, whether it has expired or is successful - activeLinkRequests.remove(javaUsername); - if (request.isExpired(link.getVerifyLinkTimeout())) { - sendMessage(player, locale, Message.LINK_REQUEST_EXPIRED); - return; - } - - link.linkPlayer(uuid, request.getJavaUniqueId(), request.getJavaUsername()) - .whenComplete((aVoid, error) -> { - if (error != null) { - sendMessage(player, locale, Message.LINK_REQUEST_ERROR); + // when the player is a Java player + if (!api.isBedrockPlayer(uuid)) { + if (args.length != 1) { + sendMessage(player, locale, Message.JAVA_USAGE); return; } - commandUtil.kickPlayer( - player, locale, Message.LINK_REQUEST_COMPLETED, - request.getJavaUsername() + + String code = String.format("%04d", new Random().nextInt(10000)); + String bedrockUsername = args[0]; + + LinkRequest linkRequest = + new LinkRequestImpl(username, uuid, code, bedrockUsername); + + activeLinkRequests.put(username, linkRequest); + sendMessage( + player, locale, Message.LINK_REQUEST_CREATED, + bedrockUsername, username, code ); - }); - }); + return; + } + + // when the player is a Bedrock player + + if (args.length != 2) { + sendMessage(player, locale, Message.BEDROCK_USAGE); + return; + } + + String javaUsername = args[0]; + String code = args[1]; + LinkRequest request = activeLinkRequests.getOrDefault(javaUsername, null); + if (request == null || !request.isRequestedPlayer(api.getPlayer(uuid))) { + sendMessage(player, locale, Message.NO_LINK_REQUESTED); + return; + } + + if (!request.getLinkCode().equals(code)) { + sendMessage(player, locale, Message.INVALID_CODE); + return; + } + + // Delete the request, whether it has expired or is successful + activeLinkRequests.remove(javaUsername); + if (request.isExpired(link.getVerifyLinkTimeout())) { + sendMessage(player, locale, Message.LINK_REQUEST_EXPIRED); + return; + } + + link.linkPlayer(uuid, request.getJavaUniqueId(), request.getJavaUsername()) + .whenComplete((unused, error) -> { + if (error != null) { + sendMessage(player, locale, Message.LINK_REQUEST_ERROR); + return; + } + commandUtil.kickPlayer( + player, locale, Message.LINK_REQUEST_COMPLETED, + request.getJavaUsername() + ); + }); + }); } @Override @@ -161,8 +161,7 @@ public final class LinkAccountCommand implements Command { NO_LINK_REQUESTED("floodgate.command.link_account.no_link_requested"), LINK_REQUEST_DISABLED("floodgate.commands.linking_disabled"); - @Getter - private final String message; + @Getter private final String message; Message(String message) { this.message = message; diff --git a/common/src/main/java/org/geysermc/floodgate/command/UnlinkAccountCommand.java b/common/src/main/java/org/geysermc/floodgate/command/UnlinkAccountCommand.java index 242fe12f..86edb15d 100644 --- a/common/src/main/java/org/geysermc/floodgate/command/UnlinkAccountCommand.java +++ b/common/src/main/java/org/geysermc/floodgate/command/UnlinkAccountCommand.java @@ -26,6 +26,7 @@ package org.geysermc.floodgate.command; import com.google.inject.Inject; +import java.util.UUID; import lombok.Getter; import lombok.NoArgsConstructor; import org.geysermc.floodgate.api.FloodgateApi; @@ -34,8 +35,6 @@ import org.geysermc.floodgate.platform.command.Command; import org.geysermc.floodgate.platform.command.CommandMessage; import org.geysermc.floodgate.platform.command.CommandUtil; -import java.util.UUID; - @NoArgsConstructor public final class UnlinkAccountCommand implements Command { @Inject private FloodgateApi api; @@ -49,25 +48,28 @@ public final class UnlinkAccountCommand implements Command { return; } - link.isLinkedPlayer(uuid).whenComplete((linked, throwable) -> { - if (throwable != null) { - sendMessage(player, locale, CommonCommandMessage.IS_LINKED_ERROR); - return; - } + link.isLinkedPlayer(uuid) + .whenComplete((linked, error) -> { + if (error != null) { + sendMessage(player, locale, CommonCommandMessage.IS_LINKED_ERROR); + return; + } - if (!linked) { - sendMessage(player, locale, Message.NOT_LINKED); - return; - } + if (!linked) { + sendMessage(player, locale, Message.NOT_LINKED); + return; + } - link.unlinkPlayer(uuid).whenComplete((aVoid, throwable1) -> - sendMessage(player, locale, - throwable1 == null ? - Message.UNLINK_SUCCESS : - Message.UNLINK_ERROR - ) - ); - }); + link.unlinkPlayer(uuid) + .whenComplete((unused, error1) -> { + if (error1 != null) { + sendMessage(player, locale, Message.UNLINK_ERROR); + return; + } + + sendMessage(player, locale, Message.UNLINK_SUCCESS); + }); + }); } @Override @@ -96,8 +98,7 @@ public final class UnlinkAccountCommand implements Command { UNLINK_ERROR("floodgate.command.unlink_account.error"), LINKING_NOT_ENABLED("floodgate.commands.linking_disabled"); - @Getter - private final String message; + @Getter private final String message; Message(String message) { this.message = message; diff --git a/common/src/main/java/org/geysermc/floodgate/config/FloodgateConfig.java b/common/src/main/java/org/geysermc/floodgate/config/FloodgateConfig.java index ee7570f4..5ab86a36 100644 --- a/common/src/main/java/org/geysermc/floodgate/config/FloodgateConfig.java +++ b/common/src/main/java/org/geysermc/floodgate/config/FloodgateConfig.java @@ -27,14 +27,12 @@ package org.geysermc.floodgate.config; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; +import java.security.Key; import lombok.Getter; -import java.security.Key; - /** - * The global Floodgate configuration file used in every platform. - * Some platforms have their own addition to the global configuration like - * {@link ProxyFloodgateConfig} for the proxies. + * The global Floodgate configuration file used in every platform. Some platforms have their own + * addition to the global configuration like {@link ProxyFloodgateConfig} for the proxies. */ @Getter public class FloodgateConfig { @@ -63,6 +61,16 @@ public class FloodgateConfig { @JsonIgnore private Key key = null; + public void setKey(Key key) { + if (this.key == null) { + this.key = key; + } + } + + public boolean isProxy() { + return this instanceof ProxyFloodgateConfig; + } + @Getter public static class DisconnectMessages { @JsonProperty("invalid-key") @@ -84,14 +92,4 @@ public class FloodgateConfig { @JsonProperty("auto-download") private boolean autoDownload; } - - public void setKey(Key key) { - if (this.key == null) { - this.key = key; - } - } - - public boolean isProxy() { - return this instanceof ProxyFloodgateConfig; - } } diff --git a/common/src/main/java/org/geysermc/floodgate/config/ProxyFloodgateConfig.java b/common/src/main/java/org/geysermc/floodgate/config/ProxyFloodgateConfig.java index ec1a1b4c..d84e4f32 100644 --- a/common/src/main/java/org/geysermc/floodgate/config/ProxyFloodgateConfig.java +++ b/common/src/main/java/org/geysermc/floodgate/config/ProxyFloodgateConfig.java @@ -32,6 +32,7 @@ import lombok.Getter; * The Floodgate configuration used by proxy platforms, currently Velocity and Bungeecord. */ public final class ProxyFloodgateConfig extends FloodgateConfig { + @Getter @JsonProperty(value = "send-floodgate-data") - @Getter private boolean sendFloodgateData; + private boolean sendFloodgateData; } diff --git a/common/src/main/java/org/geysermc/floodgate/config/loader/ConfigLoader.java b/common/src/main/java/org/geysermc/floodgate/config/loader/ConfigLoader.java index a1b8e890..c7f8362e 100644 --- a/common/src/main/java/org/geysermc/floodgate/config/loader/ConfigLoader.java +++ b/common/src/main/java/org/geysermc/floodgate/config/loader/ConfigLoader.java @@ -27,6 +27,12 @@ package org.geysermc.floodgate.config.loader; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.security.Key; import lombok.RequiredArgsConstructor; import org.geysermc.floodgate.api.logger.FloodgateLogger; import org.geysermc.floodgate.config.FloodgateConfig; @@ -35,16 +41,8 @@ import org.geysermc.floodgate.config.updater.ConfigUpdater; import org.geysermc.floodgate.crypto.FloodgateCipher; import org.geysermc.floodgate.crypto.KeyProducer; -import java.io.IOException; -import java.io.InputStream; -import java.net.URISyntaxException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.security.Key; - @RequiredArgsConstructor -public class ConfigLoader { +public final class ConfigLoader { private final Path dataFolder; private final Class configClass; private final ConfigUpdater updater; @@ -116,14 +114,16 @@ public class ConfigLoader { updater.update(defaultConfigPath); } - configInstance = (T) new ObjectMapper(new YAMLFactory()) - .readValue(Files.readAllBytes(configPath), configClass); - } catch (ClassCastException exception) { - logger.error("Provided class {} cannot be cast to the required return type", - configClass.getName()); + FloodgateConfig config = + new ObjectMapper(new YAMLFactory()) + .readValue(Files.readAllBytes(configPath), configClass); - throw new RuntimeException("Failed to load cast the config! " + - "Try to contact the platform developer"); + try { + configInstance = (T) config; + } catch (ClassCastException exception) { + logger.error("Failed to cast config file to required class.", exception); + throw new RuntimeException(exception); + } } catch (Exception exception) { logger.error("Error while loading config", exception); throw new RuntimeException("Failed to load the config! Try to delete the config file"); diff --git a/common/src/main/java/org/geysermc/floodgate/config/updater/ConfigFileUpdater.java b/common/src/main/java/org/geysermc/floodgate/config/updater/ConfigFileUpdater.java index 10092281..d10ecd43 100644 --- a/common/src/main/java/org/geysermc/floodgate/config/updater/ConfigFileUpdater.java +++ b/common/src/main/java/org/geysermc/floodgate/config/updater/ConfigFileUpdater.java @@ -26,27 +26,25 @@ package org.geysermc.floodgate.config.updater; import com.google.inject.Inject; -import org.geysermc.floodgate.api.logger.FloodgateLogger; - import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; import java.util.List; import java.util.Map; +import org.geysermc.floodgate.api.logger.FloodgateLogger; -public class ConfigFileUpdater { - @Inject - private FloodgateLogger logger; +public final class ConfigFileUpdater { + @Inject private FloodgateLogger logger; /** - * Simple config file updater. - * Please note that all the keys should be unique and that this system wasn't made for complex - * configurations. + * Simple config file updater. Please note that all the keys should be unique and that this + * system wasn't made for complex configurations. * * @param configLocation the location of the Floodgate config * @param currentVersion the key value map of the current config - * @param renames name changes introduced in this version. new (key) to old (value) + * @param renames name changes introduced in this version. new (key) to old + * (value) * @param defaultConfigLocation the location of the default Floodgate config * @throws IOException if an I/O error occurs */ @@ -59,7 +57,9 @@ public class ConfigFileUpdater { for (int i = 0; i < newConfig.size(); i++) { line = newConfig.get(i); // we don't have to check comments - if (line.startsWith("#")) continue; + if (line.startsWith("#")) { + continue; + } int splitIndex = line.indexOf(':'); // if the line has a 'key: value' structure @@ -69,11 +69,7 @@ public class ConfigFileUpdater { Object value; logger.info(name); - if (renames.containsKey(name)) { - value = currentVersion.get(renames.get(name)); - } else { - value = currentVersion.get(name); - } + value = currentVersion.get(renames.getOrDefault(name, name)); if (value == null) { notFound.add(name); @@ -102,9 +98,7 @@ public class ConfigFileUpdater { if (notFound.size() > 0) { StringBuilder messageBuilder = new StringBuilder( "Please note that the following keys we not found in the old config and " + - "are now using the default Floodgate config value. " + - "Missing/new keys: " - ); + "are now using the default Floodgate config value. Missing/new keys: "); boolean first = true; for (String value : notFound) { diff --git a/common/src/main/java/org/geysermc/floodgate/config/updater/ConfigUpdater.java b/common/src/main/java/org/geysermc/floodgate/config/updater/ConfigUpdater.java index fad20287..1ed1db19 100644 --- a/common/src/main/java/org/geysermc/floodgate/config/updater/ConfigUpdater.java +++ b/common/src/main/java/org/geysermc/floodgate/config/updater/ConfigUpdater.java @@ -25,9 +25,8 @@ package org.geysermc.floodgate.config.updater; -import lombok.RequiredArgsConstructor; -import org.geysermc.floodgate.api.logger.FloodgateLogger; -import org.yaml.snakeyaml.Yaml; +import static com.google.common.base.Preconditions.checkArgument; +import static org.geysermc.floodgate.util.MessageFormatter.format; import java.io.BufferedReader; import java.io.IOException; @@ -35,17 +34,17 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.HashMap; import java.util.Map; - -import static com.google.common.base.Preconditions.checkArgument; +import lombok.RequiredArgsConstructor; +import org.geysermc.floodgate.api.logger.FloodgateLogger; +import org.yaml.snakeyaml.Yaml; @RequiredArgsConstructor -public class ConfigUpdater { +public final class ConfigUpdater { + private static final int CONFIG_VERSION = 1; private final Path dataFolder; private final ConfigFileUpdater fileUpdater; private final FloodgateLogger logger; - private static final int CONFIG_VERSION = 1; - public void update(Path defaultConfigLocation) { Path configLocation = dataFolder.resolve("config.yml"); @@ -72,8 +71,8 @@ public class ConfigUpdater { int version = (int) versionElement; checkArgument( version == CONFIG_VERSION, - "Config is newer then possible on this version! Expected " + CONFIG_VERSION + ", got " + version - ); + format("Config is newer then possible on this version! Expected {}, got {}", + CONFIG_VERSION, version)); // config is already up-to-date if (version == CONFIG_VERSION) { diff --git a/common/src/main/java/org/geysermc/floodgate/inject/CommonPlatformInjector.java b/common/src/main/java/org/geysermc/floodgate/inject/CommonPlatformInjector.java index 68af30e8..13d35b02 100644 --- a/common/src/main/java/org/geysermc/floodgate/inject/CommonPlatformInjector.java +++ b/common/src/main/java/org/geysermc/floodgate/inject/CommonPlatformInjector.java @@ -26,13 +26,12 @@ package org.geysermc.floodgate.inject; import io.netty.channel.Channel; -import org.geysermc.floodgate.api.inject.InjectorAddon; -import org.geysermc.floodgate.api.inject.PlatformInjector; - import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; +import org.geysermc.floodgate.api.inject.InjectorAddon; +import org.geysermc.floodgate.api.inject.PlatformInjector; public abstract class CommonPlatformInjector implements PlatformInjector { private final Set injectedClients = new HashSet<>(); @@ -58,13 +57,12 @@ public abstract class CommonPlatformInjector implements PlatformInjector { } /** - * Method to loop through all the addons and call - * {@link InjectorAddon#onInject(Channel, boolean)} if - * {@link InjectorAddon#shouldInject()}. + * Method to loop through all the addons and call {@link InjectorAddon#onInject(Channel, + * boolean)} if {@link InjectorAddon#shouldInject()}. * * @param channel the channel to inject - * @param proxyToServer true if the proxy is connecting to a server or false when the player - * is connecting to the proxy or false when the platform isn't a proxy + * @param proxyToServer true if the proxy is connecting to a server or false when the player is + * connecting to the proxy or false when the platform isn't a proxy */ public void injectAddonsCall(Channel channel, boolean proxyToServer) { for (InjectorAddon addon : addons.values()) { @@ -75,8 +73,7 @@ public abstract class CommonPlatformInjector implements PlatformInjector { } /** - * Method to loop through all the addons and call - * {@link InjectorAddon#onLoginDone(Channel)} if + * Method to loop through all the addons and call {@link InjectorAddon#onLoginDone(Channel)} if * {@link InjectorAddon#shouldInject()}. * * @param channel the channel that was injected @@ -90,9 +87,8 @@ public abstract class CommonPlatformInjector implements PlatformInjector { } /** - * Method to loop through all the addons and call - * {@link InjectorAddon#onRemoveInject(Channel)} if - * {@link InjectorAddon#shouldInject()}. + * Method to loop through all the addons and call {@link InjectorAddon#onRemoveInject(Channel)} + * if {@link InjectorAddon#shouldInject()}. * * @param channel the channel that was injected */ diff --git a/common/src/main/java/org/geysermc/floodgate/link/CommonPlayerLink.java b/common/src/main/java/org/geysermc/floodgate/link/CommonPlayerLink.java index d4bff997..2288be6c 100644 --- a/common/src/main/java/org/geysermc/floodgate/link/CommonPlayerLink.java +++ b/common/src/main/java/org/geysermc/floodgate/link/CommonPlayerLink.java @@ -26,24 +26,24 @@ package org.geysermc.floodgate.link; import com.google.inject.Inject; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import lombok.AccessLevel; import lombok.Getter; import org.geysermc.floodgate.api.link.PlayerLink; import org.geysermc.floodgate.api.logger.FloodgateLogger; import org.geysermc.floodgate.config.FloodgateConfig; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - public abstract class CommonPlayerLink implements PlayerLink { + @Getter(AccessLevel.PROTECTED) + private final ExecutorService executorService = Executors.newFixedThreadPool(11); + @Getter private boolean enabled; @Getter private boolean allowLinking; @Getter private long verifyLinkTimeout; + @Inject @Getter(AccessLevel.PROTECTED) - private final ExecutorService executorService = Executors.newFixedThreadPool(11); - - @Inject @Getter(AccessLevel.PROTECTED) private FloodgateLogger logger; @Inject diff --git a/common/src/main/java/org/geysermc/floodgate/link/DisabledPlayerLink.java b/common/src/main/java/org/geysermc/floodgate/link/DisabledPlayerLink.java index e65ca0d0..0c4fa825 100644 --- a/common/src/main/java/org/geysermc/floodgate/link/DisabledPlayerLink.java +++ b/common/src/main/java/org/geysermc/floodgate/link/DisabledPlayerLink.java @@ -25,17 +25,16 @@ package org.geysermc.floodgate.link; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; import org.geysermc.floodgate.api.FloodgateApi; import org.geysermc.floodgate.api.link.PlayerLink; import org.geysermc.floodgate.util.LinkedPlayer; -import java.util.UUID; -import java.util.concurrent.CompletableFuture; - /** - * Simple class used when PlayerLinking is disabled. - * This class has been made because Floodgate doesn't have a default PlayerLink implementation - * anymore and {@link FloodgateApi#getPlayerLink()} returning null} is also not an option. + * Simple class used when PlayerLinking is disabled. This class has been made because Floodgate + * doesn't have a default PlayerLink implementation anymore and {@link FloodgateApi#getPlayerLink()} + * returning null} is also not an option. */ final class DisabledPlayerLink implements PlayerLink { @Override diff --git a/common/src/main/java/org/geysermc/floodgate/link/LinkRequestImpl.java b/common/src/main/java/org/geysermc/floodgate/link/LinkRequestImpl.java index 83c641ed..c2339824 100644 --- a/common/src/main/java/org/geysermc/floodgate/link/LinkRequestImpl.java +++ b/common/src/main/java/org/geysermc/floodgate/link/LinkRequestImpl.java @@ -25,11 +25,10 @@ package org.geysermc.floodgate.link; -import lombok.Getter; -import org.geysermc.floodgate.api.link.LinkRequest; - import java.time.Instant; import java.util.UUID; +import lombok.Getter; +import org.geysermc.floodgate.api.link.LinkRequest; @Getter public final class LinkRequestImpl implements LinkRequest { diff --git a/common/src/main/java/org/geysermc/floodgate/link/PlayerLinkLoader.java b/common/src/main/java/org/geysermc/floodgate/link/PlayerLinkLoader.java index 1ea13a7d..89f050cb 100644 --- a/common/src/main/java/org/geysermc/floodgate/link/PlayerLinkLoader.java +++ b/common/src/main/java/org/geysermc/floodgate/link/PlayerLinkLoader.java @@ -25,15 +25,13 @@ package org.geysermc.floodgate.link; +import static java.util.Objects.requireNonNull; + import com.google.gson.Gson; import com.google.gson.JsonObject; import com.google.inject.Inject; import com.google.inject.Injector; import com.google.inject.name.Named; -import org.geysermc.floodgate.api.link.PlayerLink; -import org.geysermc.floodgate.api.logger.FloodgateLogger; -import org.geysermc.floodgate.config.FloodgateConfig; - import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -43,17 +41,19 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.List; import java.util.stream.Collectors; +import org.geysermc.floodgate.api.link.PlayerLink; +import org.geysermc.floodgate.api.logger.FloodgateLogger; +import org.geysermc.floodgate.config.FloodgateConfig; -import static java.util.Objects.requireNonNull; - -public class PlayerLinkLoader { - @Named("dataDirectory") - @Inject private Path dataDirectory; +public final class PlayerLinkLoader { @Inject private Injector injector; @Inject private FloodgateConfig config; - @Inject private FloodgateLogger logger; + @Inject + @Named("dataDirectory") + private Path dataDirectory; + public PlayerLink load() { FloodgateConfig.PlayerLinkConfig linkConfig = config.getPlayerLink(); if (!linkConfig.isEnabled()) { diff --git a/common/src/main/java/org/geysermc/floodgate/logger/JavaUtilFloodgateLogger.java b/common/src/main/java/org/geysermc/floodgate/logger/JavaUtilFloodgateLogger.java index 2dece7e6..a05ed00b 100644 --- a/common/src/main/java/org/geysermc/floodgate/logger/JavaUtilFloodgateLogger.java +++ b/common/src/main/java/org/geysermc/floodgate/logger/JavaUtilFloodgateLogger.java @@ -25,17 +25,18 @@ package org.geysermc.floodgate.logger; -import lombok.RequiredArgsConstructor; -import org.geysermc.floodgate.api.logger.FloodgateLogger; +import static org.geysermc.floodgate.util.MessageFormatter.format; import java.util.logging.Level; import java.util.logging.Logger; - -import static org.geysermc.floodgate.util.MessageFormatter.format; +import lombok.RequiredArgsConstructor; +import org.geysermc.floodgate.api.logger.FloodgateLogger; +import org.geysermc.floodgate.util.LanguageManager; @RequiredArgsConstructor public final class JavaUtilFloodgateLogger implements FloodgateLogger { private final Logger logger; + private final LanguageManager languageManager; private Level originLevel = null; @Override @@ -58,6 +59,11 @@ public final class JavaUtilFloodgateLogger implements FloodgateLogger { logger.info(format(message, args)); } + @Override + public void translatedInfo(String message, Object... args) { + logger.info(languageManager.getLogString(message, args)); + } + @Override public void debug(String message, Object... args) { logger.fine(format(message, args)); diff --git a/common/src/main/java/org/geysermc/floodgate/module/CommonModule.java b/common/src/main/java/org/geysermc/floodgate/module/CommonModule.java index c8c4e78a..de575dcc 100644 --- a/common/src/main/java/org/geysermc/floodgate/module/CommonModule.java +++ b/common/src/main/java/org/geysermc/floodgate/module/CommonModule.java @@ -30,6 +30,7 @@ import com.google.inject.Provides; import com.google.inject.Singleton; import com.google.inject.name.Named; import io.netty.util.AttributeKey; +import java.nio.file.Path; import lombok.RequiredArgsConstructor; import org.geysermc.floodgate.HandshakeHandler; import org.geysermc.floodgate.api.FloodgateApi; @@ -41,13 +42,15 @@ import org.geysermc.floodgate.config.FloodgateConfig; import org.geysermc.floodgate.config.loader.ConfigLoader; import org.geysermc.floodgate.config.updater.ConfigFileUpdater; import org.geysermc.floodgate.config.updater.ConfigUpdater; -import org.geysermc.floodgate.crypto.*; +import org.geysermc.floodgate.crypto.AesCipher; +import org.geysermc.floodgate.crypto.AesKeyProducer; +import org.geysermc.floodgate.crypto.Base64Topping; +import org.geysermc.floodgate.crypto.FloodgateCipher; +import org.geysermc.floodgate.crypto.KeyProducer; import org.geysermc.floodgate.inject.CommonPlatformInjector; import org.geysermc.floodgate.link.PlayerLinkLoader; import org.geysermc.floodgate.util.LanguageManager; -import java.nio.file.Path; - @RequiredArgsConstructor public final class CommonModule extends AbstractModule { private final Path dataDirectory; @@ -79,9 +82,11 @@ public final class CommonModule extends AbstractModule { @Provides @Singleton - public ConfigLoader configLoader(@Named("configClass") Class configClass, - ConfigUpdater configUpdater, KeyProducer producer, - FloodgateCipher cipher, FloodgateLogger logger) { + public ConfigLoader configLoader( + @Named("configClass") Class configClass, + ConfigUpdater configUpdater, KeyProducer producer, + FloodgateCipher cipher, FloodgateLogger logger) { + return new ConfigLoader( dataDirectory, configClass, configUpdater, producer, cipher, logger ); diff --git a/common/src/main/java/org/geysermc/floodgate/platform/command/Command.java b/common/src/main/java/org/geysermc/floodgate/platform/command/Command.java index dd8e4af8..338c5134 100644 --- a/common/src/main/java/org/geysermc/floodgate/platform/command/Command.java +++ b/common/src/main/java/org/geysermc/floodgate/platform/command/Command.java @@ -32,11 +32,11 @@ import java.util.UUID; */ public interface Command { /** - * Should be implemented when {@link #isRequirePlayer()} is true - * or when the source is a player. + * Should be implemented when {@link #isRequirePlayer()} is true or when the source is a + * player. * - * @param player the player instance (used for example in combination with - * {@link CommandUtil#kickPlayer(Object, String, CommandMessage, Object...)} + * @param player the player instance (used for example in combination with {@link + * CommandUtil#kickPlayer(Object, String, CommandMessage, Object...)} * @param uuid the uuid of the player * @param username the username of the player * @param locale the locale of the player @@ -69,16 +69,16 @@ public interface Command { String getName(); /** - * The permission that is required to execute the specific command. - * Should return null when there is no permission required. + * The permission that is required to execute the specific command. Should return null when + * there is no permission required. * * @return the permission required to execute the command */ String getPermission(); /** - * If the Command requires a Player to execute this command - * or if it doesn't matter if (for example) the console executes the command. + * If the Command requires a Player to execute this command or if it doesn't matter if (for + * example) the console executes the command. * * @return true if this command can only be executed by a player */ diff --git a/common/src/main/java/org/geysermc/floodgate/platform/command/CommandMessage.java b/common/src/main/java/org/geysermc/floodgate/platform/command/CommandMessage.java index 1ce331c8..31021a3c 100644 --- a/common/src/main/java/org/geysermc/floodgate/platform/command/CommandMessage.java +++ b/common/src/main/java/org/geysermc/floodgate/platform/command/CommandMessage.java @@ -26,8 +26,8 @@ package org.geysermc.floodgate.platform.command; /** - * CommandMessage is the interface of a message that can be send to a command source after - * executing a command. Messages are generally implemented using enums. + * CommandMessage is the interface of a message that can be send to a command source after executing + * a command. Messages are generally implemented using enums. */ public interface CommandMessage { /** diff --git a/common/src/main/java/org/geysermc/floodgate/platform/command/CommandRegistration.java b/common/src/main/java/org/geysermc/floodgate/platform/command/CommandRegistration.java index 00ab484d..67953e79 100644 --- a/common/src/main/java/org/geysermc/floodgate/platform/command/CommandRegistration.java +++ b/common/src/main/java/org/geysermc/floodgate/platform/command/CommandRegistration.java @@ -26,10 +26,9 @@ package org.geysermc.floodgate.platform.command; /** - * This class is responsible for registering commands to the command register of the platform - * that is currently in use. So that the commands only have to be written once - * (in the common module) and can be used across all platforms without the need of adding platform - * specific commands. + * This class is responsible for registering commands to the command register of the platform that + * is currently in use. So that the commands only have to be written once (in the common module) and + * can be used across all platforms without the need of adding platform specific commands. */ public interface CommandRegistration { /** diff --git a/common/src/main/java/org/geysermc/floodgate/platform/command/CommandUtil.java b/common/src/main/java/org/geysermc/floodgate/platform/command/CommandUtil.java index eeb0326a..7018e1ac 100644 --- a/common/src/main/java/org/geysermc/floodgate/platform/command/CommandUtil.java +++ b/common/src/main/java/org/geysermc/floodgate/platform/command/CommandUtil.java @@ -26,8 +26,8 @@ package org.geysermc.floodgate.platform.command; /** - * An interface used across all Floodgate platforms to simple stuff in commands like kicking - * players and sending player messages independent of the Floodgate platform implementation. + * An interface used across all Floodgate platforms to simple stuff in commands like kicking players + * and sending player messages independent of the Floodgate platform implementation. */ public interface CommandUtil { /** diff --git a/common/src/main/java/org/geysermc/floodgate/platform/listener/ListenerRegistration.java b/common/src/main/java/org/geysermc/floodgate/platform/listener/ListenerRegistration.java index 055e7cbc..384df1e3 100644 --- a/common/src/main/java/org/geysermc/floodgate/platform/listener/ListenerRegistration.java +++ b/common/src/main/java/org/geysermc/floodgate/platform/listener/ListenerRegistration.java @@ -26,9 +26,9 @@ package org.geysermc.floodgate.platform.listener; /** - * This class is responsible for registering listeners to the listener manager of the platform - * that is currently in use. Unfortunately due to the major differences between the platforms - * (when it comes to listeners) every Floodgate platform has to implement their own listeners. + * This class is responsible for registering listeners to the listener manager of the platform that + * is currently in use. Unfortunately due to the major differences between the platforms (when it + * comes to listeners) every Floodgate platform has to implement their own listeners. * * @param the platform-specific listener class */ diff --git a/common/src/main/java/org/geysermc/floodgate/register/AddonRegister.java b/common/src/main/java/org/geysermc/floodgate/register/AddonRegister.java index fb5eb922..a6f577b9 100644 --- a/common/src/main/java/org/geysermc/floodgate/register/AddonRegister.java +++ b/common/src/main/java/org/geysermc/floodgate/register/AddonRegister.java @@ -27,11 +27,10 @@ package org.geysermc.floodgate.register; import com.google.inject.Inject; import com.google.inject.Injector; +import java.util.Set; import org.geysermc.floodgate.api.inject.InjectorAddon; import org.geysermc.floodgate.api.inject.PlatformInjector; -import java.util.Set; - public final class AddonRegister { @Inject private Injector guice; @Inject private PlatformInjector injector; diff --git a/common/src/main/java/org/geysermc/floodgate/register/CommandRegister.java b/common/src/main/java/org/geysermc/floodgate/register/CommandRegister.java index a1a625bb..2d52873d 100644 --- a/common/src/main/java/org/geysermc/floodgate/register/CommandRegister.java +++ b/common/src/main/java/org/geysermc/floodgate/register/CommandRegister.java @@ -27,12 +27,11 @@ package org.geysermc.floodgate.register; import com.google.inject.Inject; import com.google.inject.Injector; +import java.util.Set; import lombok.RequiredArgsConstructor; import org.geysermc.floodgate.platform.command.Command; import org.geysermc.floodgate.platform.command.CommandRegistration; -import java.util.Set; - @RequiredArgsConstructor(onConstructor = @__(@Inject)) public final class CommandRegister { private final CommandRegistration registration; diff --git a/common/src/main/java/org/geysermc/floodgate/register/ListenerRegister.java b/common/src/main/java/org/geysermc/floodgate/register/ListenerRegister.java index 3ab6e4c8..5268c22e 100644 --- a/common/src/main/java/org/geysermc/floodgate/register/ListenerRegister.java +++ b/common/src/main/java/org/geysermc/floodgate/register/ListenerRegister.java @@ -27,11 +27,10 @@ package org.geysermc.floodgate.register; import com.google.inject.Inject; import com.google.inject.Injector; +import java.util.Set; import lombok.RequiredArgsConstructor; import org.geysermc.floodgate.platform.listener.ListenerRegistration; -import java.util.Set; - @RequiredArgsConstructor(onConstructor = @__(@Inject)) public final class ListenerRegister { private final ListenerRegistration registration; diff --git a/common/src/main/java/org/geysermc/floodgate/util/LanguageManager.java b/common/src/main/java/org/geysermc/floodgate/util/LanguageManager.java index 668a8e63..9850b59e 100644 --- a/common/src/main/java/org/geysermc/floodgate/util/LanguageManager.java +++ b/common/src/main/java/org/geysermc/floodgate/util/LanguageManager.java @@ -26,25 +26,25 @@ package org.geysermc.floodgate.util; import com.google.inject.Inject; -import lombok.Getter; -import lombok.RequiredArgsConstructor; -import org.geysermc.floodgate.api.logger.FloodgateLogger; -import org.geysermc.floodgate.config.FloodgateConfig; - import java.io.InputStream; import java.io.InputStreamReader; +import java.net.URL; import java.nio.charset.StandardCharsets; import java.text.MessageFormat; import java.util.HashMap; import java.util.Locale; import java.util.Map; import java.util.Properties; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.geysermc.floodgate.api.logger.FloodgateLogger; +import org.geysermc.floodgate.config.FloodgateConfig; /** * Manages translations for strings in Floodgate */ @RequiredArgsConstructor -public class LanguageManager { +public final class LanguageManager { private final Map LOCALE_MAPPINGS = new HashMap<>(); private final FloodgateLogger logger; @@ -52,8 +52,22 @@ public class LanguageManager { /** * The locale used in console and as a fallback */ - @Getter - private String defaultLocale; + @Getter private String defaultLocale; + + /** + * Cleans up and formats a locale string + * + * @param locale the locale to format + * @return the formatted locale + */ + private static String formatLocale(String locale) { + try { + String[] parts = locale.toLowerCase().split("_"); + return parts[0] + "_" + parts[1].toUpperCase(); + } catch (Exception e) { + return locale; + } + } /** * Loads the log's locale file once Floodgate loads the config @@ -72,8 +86,7 @@ public class LanguageManager { } String systemLocale = formatLocale( - Locale.getDefault().getLanguage() + "_" + - Locale.getDefault().getCountry() + Locale.getDefault().getLanguage() + "_" + Locale.getDefault().getCountry() ); if (isValidLanguage(systemLocale)) { @@ -88,7 +101,7 @@ public class LanguageManager { /** * Loads a Floodgate locale from resources; if the file doesn't exist it just logs a warning * - * @param locale Locale to load + * @param locale locale to load */ public void loadLocale(String locale) { locale = formatLocale(locale); @@ -120,9 +133,9 @@ public class LanguageManager { /** * Get a formatted language string with the default locale for Floodgate * - * @param key Language string to translate - * @param values Values to put into the string - * @return Translated string or the original message if it was not found in the given locale + * @param key language string to translate + * @param values values to put into the string + * @return translated string or the original message if it was not found in the given locale */ public String getLogString(String key, Object... values) { return getString(key, defaultLocale, values); @@ -131,10 +144,10 @@ public class LanguageManager { /** * Get a formatted language string with the given locale for Floodgate * - * @param key Language string to translate - * @param locale Locale to translate to - * @param values Values to put into the string - * @return Translated string or the original message if it was not found in the given locale + * @param key language string to translate + * @param locale locale to translate to + * @param values values to put into the string + * @return translated string or the original message if it was not found in the given locale */ public String getString(String key, String locale, Object... values) { locale = formatLocale(locale); @@ -162,23 +175,9 @@ public class LanguageManager { return MessageFormat.format(formatString.replace("'", "''").replace("&", "\u00a7"), values); } - /** - * Cleans up and formats a locale string - * - * @param locale The locale to format - * @return The formatted locale - */ - private static String formatLocale(String locale) { - try { - String[] parts = locale.toLowerCase().split("_"); - return parts[0] + "_" + parts[1].toUpperCase(); - } catch (Exception e) { - return locale; - } - } - /** * Ensures that the given locale is supported by Floodgate + * * @param locale the locale to validate * @return true if the given locale is supported by Floodgate */ @@ -187,7 +186,10 @@ public class LanguageManager { return false; } - if (LanguageManager.class.getResource("/languages/texts/" + locale + ".properties") == null) { + URL languageFile = LanguageManager.class + .getResource("/languages/texts/" + locale + ".properties"); + + if (languageFile == null) { logger.warn(locale + " is not a supported Floodgate language."); return false; } diff --git a/common/src/main/java/org/geysermc/floodgate/util/MessageFormatter.java b/common/src/main/java/org/geysermc/floodgate/util/MessageFormatter.java index 3aefb8f0..83adc9f9 100644 --- a/common/src/main/java/org/geysermc/floodgate/util/MessageFormatter.java +++ b/common/src/main/java/org/geysermc/floodgate/util/MessageFormatter.java @@ -31,7 +31,9 @@ public final class MessageFormatter { public static String format(String message, Object... arguments) { // simple variant of slf4j's parameters. - if (arguments == null || arguments.length == 0) return message; + if (arguments == null || arguments.length == 0) { + return message; + } String[] args = new String[arguments.length]; for (int i = 0; i < arguments.length; i++) { @@ -49,30 +51,36 @@ public final class MessageFormatter { if (currentIndex == -1) { // no parameter places left in message, // we'll ignore the remaining parameters and return the message - if (previousIndex == -1) return message; - else { + if (previousIndex == -1) { + return message; + } else { stringBuilder.append(message.substring(previousIndex)); return stringBuilder.toString(); } } - if (previousIndex == -1) stringBuilder.append(message, 0, currentIndex); - else stringBuilder.append(message, previousIndex, currentIndex); + if (previousIndex == -1) { + stringBuilder.append(message, 0, currentIndex); + } else { + stringBuilder.append(message, previousIndex, currentIndex); + } stringBuilder.append(argument); // we finished this argument, so we're past the current delimiter previousIndex = currentIndex + DELIM_LENGTH; } - if (previousIndex != message.length()) + if (previousIndex != message.length()) { stringBuilder.append(message, previousIndex, message.length()); + } return stringBuilder.toString(); } public static int getArgsContentLength(String... args) { int length = 0; - for (String arg : args) + for (String arg : args) { length += arg.length(); + } return length; } } diff --git a/common/src/main/java/org/geysermc/floodgate/util/ReflectionUtils.java b/common/src/main/java/org/geysermc/floodgate/util/ReflectionUtils.java index 4a6c5d24..4184c585 100644 --- a/common/src/main/java/org/geysermc/floodgate/util/ReflectionUtils.java +++ b/common/src/main/java/org/geysermc/floodgate/util/ReflectionUtils.java @@ -25,30 +25,69 @@ package org.geysermc.floodgate.util; -import com.google.common.base.Preconditions; -import lombok.Setter; - -import javax.annotation.Nullable; -import java.lang.reflect.*; - import static org.geysermc.floodgate.util.MessageFormatter.format; +import com.google.common.base.Preconditions; +import java.lang.reflect.AccessibleObject; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import javax.annotation.Nullable; +import lombok.Setter; + public final class ReflectionUtils { private static final Field MODIFIERS_FIELD; /** * The package name that is shared between all the {@link #getPrefixedClass(String)} calls so - * that the className will be a lot shorter. - * Example net.minecraft.server.v1_8R3.PacketHandshakingInSetProtocol will become - * PacketHandshakingInSetProtocol if the prefix is set to net.minecraft.server.v1_8R3 + * that the className will be a lot shorter. Example net.minecraft.server.v1_8R3.PacketHandshakingInSetProtocol + * will become PacketHandshakingInSetProtocol if the prefix is set to + * net.minecraft.server.v1_8R3 */ - @Setter - private static String prefix = null; + @Setter private static String prefix = null; + + static { + Field modifiersField = null; + try { + modifiersField = Field.class.getDeclaredField("modifiers"); + } catch (NoSuchFieldException ignored) { + // Java 12 compatibility, thanks to https://github.com/powermock/powermock/pull/1010 + try { + Method declaredFields = getMethod(Class.class, "getDeclaredFields0", boolean.class); + if (declaredFields == null) { + throw new NoSuchMethodException(); + } + + Field[] fields = castedInvoke(Field.class, declaredFields, false); + if (fields == null) { + throw new Exception(); + } + + for (Field field : fields) { + if ("modifiers".equals(field.getName())) { + modifiersField = field; + break; + } + } + } catch (Exception exception) { + throw new RuntimeException(format( + "Cannot find the modifiers field :/\nJava version: {}\nVendor: {} ({})", + System.getProperty("java.version"), + System.getProperty("java.vendor"), + System.getProperty("java.vendor.url") + )); + } + } + + Preconditions.checkNotNull(modifiersField, "Modifiers field cannot be null!"); + MODIFIERS_FIELD = modifiersField; + } /** - * Get a class that is prefixed with the prefix provided in {@link #setPrefix(String)}. - * Calling this method is equal to calling {@link #getClass(String)} - * with prefix.classname as class name. + * Get a class that is prefixed with the prefix provided in {@link #setPrefix(String)}. Calling + * this method is equal to calling {@link #getClass(String)} with prefix.classname + * as class name. * * @param className the prefix class to find * @return the class if found, otherwise null @@ -59,11 +98,10 @@ public final class ReflectionUtils { } /** - * Get the class from a class name. - * Calling this method is equal to calling {@link Class#forName(String)} where String is the - * class name.
- * This method will return null when the class isn't found instead of throwing the exception, - * but the exception will be printed to the console. + * Get the class from a class name. Calling this method is equal to calling {@link + * Class#forName(String)} where String is the class name.
This method will return null when + * the class isn't found instead of throwing the exception, but the exception will be printed to + * the console. * * @param className the name of the class to find * @return the class or null if the class wasn't found. @@ -79,12 +117,11 @@ public final class ReflectionUtils { } /** - * Get a field of a class. - * Calling this method is equal to calling {@link Class#getField(String)} where String is the - * fieldName when isPublic is true and calling this method is equal to calling - * {@link Class#getDeclaredField(String)} where String is the fieldName when isPublic is - * false.
- * Please note that this method will return null instead of throwing the exception. + * Get a field of a class. Calling this method is equal to calling {@link + * Class#getField(String)} where String is the fieldName when isPublic is true and calling this + * method is equal to calling {@link Class#getDeclaredField(String)} where String is the + * fieldName when isPublic is false.
Please note that this method will return null instead + * of throwing the exception. * * @param clazz the class name to get the field from * @param fieldName the name of the field @@ -104,9 +141,8 @@ public final class ReflectionUtils { } /** - * Get a field from a class, it doesn't matter if the field is public or not. - * This method will first try to get a declared field and if that failed it'll try to get a - * public field. + * Get a field from a class, it doesn't matter if the field is public or not. This method will + * first try to get a declared field and if that failed it'll try to get a public field. * * @param clazz the class to get the field from * @param fieldName the name of the field @@ -134,15 +170,17 @@ public final class ReflectionUtils { Field[] fields = declared ? clazz.getDeclaredFields() : clazz.getFields(); for (Field field : fields) { makeAccessible(field); - if (field.getType() == fieldType) return field; + if (field.getType() == fieldType) { + return field; + } } return null; } /** - * Get a declared field from a class without having to provide a field name.
- * Calling this method is equal to calling {@link #getFieldOfType(Class, Class, boolean)} - * with declared = true. + * Get a declared field from a class without having to provide a field name.
Calling this + * method is equal to calling {@link #getFieldOfType(Class, Class, boolean)} with declared = + * true. * * @param clazz the class to search the field from * @param fieldType the type of the declared field @@ -154,10 +192,9 @@ public final class ReflectionUtils { } /** - * Get the value of a field. - * This method first makes the field accessible and then gets the value.
- * This method will return null instead of throwing an exception, - * but it'll log the stacktrace to the console. + * Get the value of a field. This method first makes the field accessible and then gets the + * value.
This method will return null instead of throwing an exception, but it'll log the + * stacktrace to the console. * * @param instance the instance to get the value from * @param field the field to get the value from @@ -201,8 +238,7 @@ public final class ReflectionUtils { } /** - * Set the value of a field. - * This method make the field accessible and then sets the value.
+ * Set the value of a field. This method make the field accessible and then sets the value.
* This method doesn't throw an exception when failed, but it'll log the error to the console. * * @param instance the instance to set the value to @@ -219,8 +255,8 @@ public final class ReflectionUtils { } /** - * Set the value of a field. - * This method finds the field, and then calls {@link #setValue(Object, Field, Object)}. + * Set the value of a field. This method finds the field, and then calls {@link + * #setValue(Object, Field, Object)}. * * @param instance the instance to set the value to * @param fieldName the field to set the value to @@ -236,10 +272,9 @@ public final class ReflectionUtils { } /** - * Set the value of a final field. - * This method first makes the field accessible, then removes the final modifier and then - * sets the value.
- * This method will not throw exceptions when failed, but it'll log the error to the console. + * Set the value of a final field. This method first makes the field accessible, then + * removes the final modifier and then sets the value.
This method will not throw exceptions + * when failed, but it'll log the error to the console. * * @param instance the instance to set the value to * @param field the field to set the value to @@ -264,11 +299,10 @@ public final class ReflectionUtils { } /** - * Get a method from a class, it doesn't matter if the field is public or not. - * This method will first try to get a declared field and if that failed it'll try to get a - * public field.
- * Instead of throwing an exception when the method wasn't found, it will return null, but - * the exception will be printed in the console. + * Get a method from a class, it doesn't matter if the field is public or not. This method will + * first try to get a declared field and if that failed it'll try to get a public field.
+ * Instead of throwing an exception when the method wasn't found, it will return null, but the + * exception will be printed in the console. * * @param clazz the class to get the method from * @param method the name of the method to find @@ -290,9 +324,8 @@ public final class ReflectionUtils { } /** - * Get a method from a class, it doesn't matter if the method is public or not. - * This method will first try to get a declared method and if that fails it'll try to get a - * public method. + * Get a method from a class, it doesn't matter if the method is public or not. This method will + * first try to get a declared method and if that fails it'll try to get a public method. * * @param clazz the class to get the method from * @param methodName the name of the method to find @@ -309,9 +342,8 @@ public final class ReflectionUtils { } /** - * Get a method from a class, it doesn't matter if the method is public or not. - * This method will first try to get a declared method and if that fails it'll try to get a - * public method. + * Get a method from a class, it doesn't matter if the method is public or not. This method will + * first try to get a declared method and if that fails it'll try to get a public method. * * @param instance the class to get the method from * @param methodName the name of the method to find @@ -402,41 +434,4 @@ public final class ReflectionUtils { } return accessibleObject; } - - static { - Field modifiersField = null; - try { - modifiersField = Field.class.getDeclaredField("modifiers"); - } catch (NoSuchFieldException ignored) { - // Java 12 compatibility, thanks to https://github.com/powermock/powermock/pull/1010 - try { - Method declaredFields = getMethod(Class.class, "getDeclaredFields0", boolean.class); - if (declaredFields == null) { - throw new NoSuchMethodException(); - } - - Field[] fields = castedInvoke(Field.class, declaredFields, false); - if (fields == null) { - throw new Exception(); - } - - for (Field field : fields) { - if ("modifiers".equals(field.getName())) { - modifiersField = field; - break; - } - } - } catch (Exception exception) { - throw new RuntimeException(format("Cannot find the modifiers field :/\n" + - "Java version: {}\nVendor: {} ({})", - System.getProperty("java.version"), - System.getProperty("java.vendor"), - System.getProperty("java.vendor.url") - )); - } - } - - Preconditions.checkNotNull(modifiersField, "Modifiers field cannot be null!"); - MODIFIERS_FIELD = modifiersField; - } } diff --git a/database/pom.xml b/database/pom.xml index dfc6e675..6c8a8f79 100644 --- a/database/pom.xml +++ b/database/pom.xml @@ -1,51 +1,26 @@ - - + parent + org.geysermc.floodgate.database + + 4.0.0 + + sqlite + + database + pom + parent org.geysermc.floodgate 1.0-SNAPSHOT - 4.0.0 - - org.geysermc.floodgate.database - parent - pom - 1.0-SNAPSHOT - - database - - - sqlite - floodgate-${project.name}-database + + 1.0-SNAPSHOT \ No newline at end of file diff --git a/database/sqlite/pom.xml b/database/sqlite/pom.xml index 63cd054a..91b55cbb 100644 --- a/database/sqlite/pom.xml +++ b/database/sqlite/pom.xml @@ -1,62 +1,8 @@ - - - - parent - org.geysermc.floodgate.database - 1.0-SNAPSHOT - - 4.0.0 - sqlite - - - - org.xerial - sqlite-jdbc - 3.30.1 - compile - - - org.geysermc.floodgate - common - 1.0-SNAPSHOT - provided - - - org.projectlombok - lombok - 1.18.12 - provided - - - @@ -84,4 +30,33 @@ + + + + org.xerial + sqlite-jdbc + 3.30.1 + compile + + + org.geysermc.floodgate + common + 1.0-SNAPSHOT + provided + + + org.projectlombok + lombok + 1.18.12 + provided + + + + 4.0.0 + + + parent + org.geysermc.floodgate.database + 1.0-SNAPSHOT + \ No newline at end of file diff --git a/database/sqlite/src/main/java/org/geysermc/floodgate/database/SqliteDatabase.java b/database/sqlite/src/main/java/org/geysermc/floodgate/database/SqliteDatabase.java index 1a04b329..563eddd7 100644 --- a/database/sqlite/src/main/java/org/geysermc/floodgate/database/SqliteDatabase.java +++ b/database/sqlite/src/main/java/org/geysermc/floodgate/database/SqliteDatabase.java @@ -27,14 +27,18 @@ package org.geysermc.floodgate.database; import com.google.inject.Inject; import com.google.inject.name.Named; -import org.geysermc.floodgate.link.CommonPlayerLink; -import org.geysermc.floodgate.util.LinkedPlayer; - import java.nio.file.Path; -import java.sql.*; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; import java.util.UUID; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; +import org.geysermc.floodgate.link.CommonPlayerLink; +import org.geysermc.floodgate.util.LinkedPlayer; public class SqliteDatabase extends CommonPlayerLink { private Connection connection; @@ -51,7 +55,9 @@ public class SqliteDatabase extends CommonPlayerLink { connection = DriverManager.getConnection("jdbc:sqlite:" + databasePath.toString()); Statement statement = connection.createStatement(); statement.setQueryTimeout(30); // set timeout to 30 sec. - statement.executeUpdate("create table if not exists LinkedPlayers (bedrockId string, javaUniqueId string, javaUsername string)"); + statement.executeUpdate( + "create table if not exists LinkedPlayers (bedrockId string, javaUniqueId string, javaUsername string)" + ); } catch (ClassNotFoundException exception) { getLogger().error("The required class to load the SQLite database wasn't found"); } catch (SQLException exception) { @@ -73,10 +79,14 @@ public class SqliteDatabase extends CommonPlayerLink { public CompletableFuture getLinkedPlayer(UUID bedrockId) { return CompletableFuture.supplyAsync(() -> { try { - PreparedStatement query = connection.prepareStatement("select * from LinkedPlayers where bedrockId = ?"); + PreparedStatement query = connection.prepareStatement( + "select * from LinkedPlayers where bedrockId = ?" + ); query.setString(1, bedrockId.toString()); ResultSet result = query.executeQuery(); - if (!result.next()) return null; + if (!result.next()) { + return null; + } String javaUsername = result.getString("javaUsername"); UUID javaUniqueId = UUID.fromString(result.getString("javaUniqueId")); @@ -92,7 +102,9 @@ public class SqliteDatabase extends CommonPlayerLink { public CompletableFuture isLinkedPlayer(UUID bedrockId) { return CompletableFuture.supplyAsync(() -> { try { - PreparedStatement query = connection.prepareStatement("select javaUniqueId from LinkedPlayers where bedrockId = ? or javaUniqueId = ?"); + PreparedStatement query = connection.prepareStatement( + "select javaUniqueId from LinkedPlayers where bedrockId = ? or javaUniqueId = ?" + ); query.setString(1, bedrockId.toString()); query.setString(2, bedrockId.toString()); ResultSet result = query.executeQuery(); @@ -110,7 +122,9 @@ public class SqliteDatabase extends CommonPlayerLink { public CompletableFuture linkPlayer(UUID bedrockId, UUID javaId, String username) { return CompletableFuture.runAsync(() -> { try { - PreparedStatement query = connection.prepareStatement("insert into LinkedPlayers values(?, ?, ?)"); + PreparedStatement query = connection.prepareStatement( + "insert into LinkedPlayers values(?, ?, ?)" + ); query.setString(1, bedrockId.toString()); query.setString(2, javaId.toString()); query.setString(3, username); @@ -126,7 +140,9 @@ public class SqliteDatabase extends CommonPlayerLink { public CompletableFuture unlinkPlayer(UUID javaId) { return CompletableFuture.runAsync(() -> { try { - PreparedStatement query = connection.prepareStatement("delete from LinkedPlayers where javaUniqueId = ? or bedrockId = ?"); + PreparedStatement query = connection.prepareStatement( + "delete from LinkedPlayers where javaUniqueId = ? or bedrockId = ?" + ); query.setString(1, javaId.toString()); query.setString(2, javaId.toString()); query.executeUpdate(); diff --git a/pom.xml b/pom.xml index 11c43303..97efc64d 100644 --- a/pom.xml +++ b/pom.xml @@ -1,12 +1,32 @@ - 4.0.0 - - org.geysermc.floodgate + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> parent - 1.0-SNAPSHOT + + + + org.projectlombok + lombok + 1.18.10 + provided + + + Allows Bedrock players to join Java edition servers while keeping the server in online mode + + + releases + nukkitx-releases + https://repo.nukkitx.com/maven-releases + + + snapshots + nukkitx-snapshots + https://repo.nukkitx.com/maven-snapshots + + + org.geysermc.floodgate + 4.0.0 api common @@ -15,10 +35,13 @@ velocity database - pom floodgate - Allows Bedrock players to join Java edition servers while keeping online mode - https://github.com/GeyserMC/Floodgate + + GeyserMC + https://geysermc.org/ + + + pom 1.1.0 @@ -33,36 +56,13 @@ 1.8 - - GeyserMC - https://geysermc.org/ - - scm:git:https://github.com/GeyserMC/Floodgate.git scm:git:git@github.com:GeyserMC/Floodgate.git https://github.com/GeyserMC/Floodgate/ - - - releases - nukkitx-releases - https://repo.nukkitx.com/maven-releases - - - snapshots - nukkitx-snapshots - https://repo.nukkitx.com/maven-snapshots - - + https://github.com/GeyserMC/Floodgate - - - org.projectlombok - lombok - 1.18.10 - provided - - + 1.0-SNAPSHOT diff --git a/spigot/pom.xml b/spigot/pom.xml index 3600b8eb..d479ddb4 100644 --- a/spigot/pom.xml +++ b/spigot/pom.xml @@ -2,48 +2,7 @@ - - org.geysermc.floodgate - parent - 1.0-SNAPSHOT - - 4.0.0 - spigot - - - - spigot-repo - https://hub.spigotmc.org/nexus/content/repositories/snapshots/ - - - - - - org.spigotmc - spigot-api - ${spigot.version} - provided - - - io.netty - netty-transport - 4.1.43.Final - provided - - - io.netty - netty-codec - 4.1.43.Final - provided - - - org.geysermc.floodgate - common - ${project.version} - - - @@ -71,4 +30,45 @@ + + + + org.spigotmc + spigot-api + ${spigot.version} + provided + + + io.netty + netty-transport + 4.1.43.Final + provided + + + io.netty + netty-codec + 4.1.43.Final + provided + + + org.geysermc.floodgate + common + ${project.version} + + + + 4.0.0 + + + org.geysermc.floodgate + parent + 1.0-SNAPSHOT + + + + + spigot-repo + https://hub.spigotmc.org/nexus/content/repositories/snapshots/ + + diff --git a/spigot/src/main/java/org/geysermc/floodgate/SpigotPlatform.java b/spigot/src/main/java/org/geysermc/floodgate/SpigotPlatform.java index 9a96063d..6c98e4d9 100644 --- a/spigot/src/main/java/org/geysermc/floodgate/SpigotPlatform.java +++ b/spigot/src/main/java/org/geysermc/floodgate/SpigotPlatform.java @@ -26,31 +26,21 @@ package org.geysermc.floodgate; import com.google.inject.Inject; -import com.google.inject.Injector; import com.google.inject.Module; -import com.google.inject.name.Named; import org.bukkit.Bukkit; import org.bukkit.plugin.java.JavaPlugin; import org.geysermc.floodgate.api.FloodgateApi; import org.geysermc.floodgate.api.inject.PlatformInjector; import org.geysermc.floodgate.api.logger.FloodgateLogger; -import org.geysermc.floodgate.config.loader.ConfigLoader; -import org.geysermc.floodgate.link.PlayerLinkLoader; import org.geysermc.floodgate.util.LanguageManager; -import java.nio.file.Path; - public final class SpigotPlatform extends FloodgatePlatform { @Inject private JavaPlugin plugin; @Inject - public SpigotPlatform(@Named("dataDirectory") Path dataDirectory, FloodgateApi api, - ConfigLoader configLoader, PlayerLinkLoader playerLinkLoader, - HandshakeHandler handshakeHandler, FloodgateLogger logger, - PlatformInjector platformInjector, LanguageManager languageManager, - Injector injector) { - super(dataDirectory, api, configLoader, playerLinkLoader, handshakeHandler, - logger, platformInjector, languageManager, injector); + public SpigotPlatform(FloodgateApi api, LanguageManager languageManager, + PlatformInjector platformInjector, FloodgateLogger logger) { + super(api, languageManager, platformInjector, logger); } @Override diff --git a/spigot/src/main/java/org/geysermc/floodgate/SpigotPlugin.java b/spigot/src/main/java/org/geysermc/floodgate/SpigotPlugin.java index 6648e5c8..711df269 100644 --- a/spigot/src/main/java/org/geysermc/floodgate/SpigotPlugin.java +++ b/spigot/src/main/java/org/geysermc/floodgate/SpigotPlugin.java @@ -28,7 +28,12 @@ package org.geysermc.floodgate; import com.google.inject.Guice; import com.google.inject.Injector; import org.bukkit.plugin.java.JavaPlugin; -import org.geysermc.floodgate.module.*; +import org.geysermc.floodgate.api.logger.FloodgateLogger; +import org.geysermc.floodgate.module.CommandModule; +import org.geysermc.floodgate.module.CommonModule; +import org.geysermc.floodgate.module.SpigotAddonModule; +import org.geysermc.floodgate.module.SpigotListenerModule; +import org.geysermc.floodgate.module.SpigotPlatformModule; import org.geysermc.floodgate.util.ReflectionUtils; public final class SpigotPlugin extends JavaPlugin { @@ -48,10 +53,8 @@ public final class SpigotPlugin extends JavaPlugin { platform = injector.getInstance(SpigotPlatform.class); long endCtm = System.currentTimeMillis(); - getLogger().info(platform.getLanguageManager().getLogString( - "floodgate.core.finish", - endCtm - ctm - )); + injector.getInstance(FloodgateLogger.class) + .translatedInfo("floodgate.core.finish", endCtm - ctm); } @Override diff --git a/spigot/src/main/java/org/geysermc/floodgate/addon/data/SpigotDataAddon.java b/spigot/src/main/java/org/geysermc/floodgate/addon/data/SpigotDataAddon.java index 2a5b7e40..c2ec72a7 100644 --- a/spigot/src/main/java/org/geysermc/floodgate/addon/data/SpigotDataAddon.java +++ b/spigot/src/main/java/org/geysermc/floodgate/addon/data/SpigotDataAddon.java @@ -40,14 +40,16 @@ public final class SpigotDataAddon implements InjectorAddon { @Inject private FloodgateConfig config; @Inject private FloodgateLogger logger; - @Inject @Named("playerAttribute") + @Inject + @Named("playerAttribute") private AttributeKey playerAttribute; - @Inject @Named("packetHandler") + @Inject + @Named("packetHandler") private String packetHandlerName; @Override - public void onInject(Channel channel, boolean proxyToServer) { + public void onInject(Channel channel, boolean toServer) { channel.pipeline().addBefore( packetHandlerName, "floodgate_data_handler", new SpigotDataHandler(config, handshakeHandler, playerAttribute, logger) diff --git a/spigot/src/main/java/org/geysermc/floodgate/addon/data/SpigotDataHandler.java b/spigot/src/main/java/org/geysermc/floodgate/addon/data/SpigotDataHandler.java index fe004796..427047ea 100644 --- a/spigot/src/main/java/org/geysermc/floodgate/addon/data/SpigotDataHandler.java +++ b/spigot/src/main/java/org/geysermc/floodgate/addon/data/SpigotDataHandler.java @@ -25,9 +25,23 @@ package org.geysermc.floodgate.addon.data; +import static com.google.common.base.Preconditions.checkNotNull; +import static org.geysermc.floodgate.util.ReflectionUtils.getCastedValue; +import static org.geysermc.floodgate.util.ReflectionUtils.getFieldOfType; +import static org.geysermc.floodgate.util.ReflectionUtils.getMethod; +import static org.geysermc.floodgate.util.ReflectionUtils.getPrefixedClass; +import static org.geysermc.floodgate.util.ReflectionUtils.makeAccessible; +import static org.geysermc.floodgate.util.ReflectionUtils.setValue; + import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.util.AttributeKey; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.util.UUID; import lombok.RequiredArgsConstructor; import org.geysermc.floodgate.HandshakeHandler; import org.geysermc.floodgate.HandshakeHandler.HandshakeResult; @@ -37,16 +51,6 @@ import org.geysermc.floodgate.config.FloodgateConfig; import org.geysermc.floodgate.util.BedrockData; import org.geysermc.floodgate.util.ReflectionUtils; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.net.InetSocketAddress; -import java.net.SocketAddress; -import java.util.UUID; - -import static com.google.common.base.Preconditions.checkNotNull; -import static org.geysermc.floodgate.util.ReflectionUtils.*; - @RequiredArgsConstructor public final class SpigotDataHandler extends SimpleChannelInboundHandler { private static final Field SOCKET_ADDRESS; @@ -69,16 +73,89 @@ public final class SpigotDataHandler extends SimpleChannelInboundHandler private static final Field PROTOCOL_STATE; private static final Object READY_TO_ACCEPT_PROTOCOL_STATE; + static { + Class networkManager = getPrefixedClass("NetworkManager"); + checkNotNull(networkManager, "NetworkManager class cannot be null"); + + SOCKET_ADDRESS = getFieldOfType(networkManager, SocketAddress.class, false); + checkNotNull(SOCKET_ADDRESS, "SocketAddress field cannot be null"); + + HANDSHAKE_PACKET = getPrefixedClass("PacketHandshakingInSetProtocol"); + checkNotNull(HANDSHAKE_PACKET, "PacketHandshakingInSetProtocol cannot be null"); + HANDSHAKE_HOST = getFieldOfType(HANDSHAKE_PACKET, String.class); + checkNotNull(HANDSHAKE_HOST, "Host field from handshake packet cannot be null"); + + LOGIN_START_PACKET = getPrefixedClass("PacketLoginInStart"); + checkNotNull(LOGIN_START_PACKET, "PacketLoginInStart cannot be null"); + + GAME_PROFILE = ReflectionUtils.getClass("com.mojang.authlib.GameProfile"); + checkNotNull(GAME_PROFILE, "GameProfile class cannot be null"); + + Constructor gameProfileConstructor = null; + try { + gameProfileConstructor = GAME_PROFILE.getConstructor(UUID.class, String.class); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } + GAME_PROFILE_CONSTRUCTOR = gameProfileConstructor; + checkNotNull(GAME_PROFILE_CONSTRUCTOR, "GameProfileConstructor cannot be null"); + + LOGIN_LISTENER = getPrefixedClass("LoginListener"); + checkNotNull(LOGIN_LISTENER, "LoginListener cannot be null"); + LOGIN_PROFILE = getFieldOfType(LOGIN_LISTENER, GAME_PROFILE); + checkNotNull(LOGIN_PROFILE, "Profile from LoginListener cannot be null"); + INIT_UUID = getMethod(LOGIN_LISTENER, "initUUID"); + checkNotNull(INIT_UUID, "initUUID from LoginListener cannot be null"); + + Field protocolStateField = null; + for (Field field : LOGIN_LISTENER.getDeclaredFields()) { + if (field.getType().isEnum()) { + protocolStateField = field; + } + } + PROTOCOL_STATE = protocolStateField; + checkNotNull(PROTOCOL_STATE, "Protocol state field from LoginListener cannot be null"); + + Enum[] protocolStates = (Enum[]) PROTOCOL_STATE.getType().getEnumConstants(); + Object readyToAcceptState = null; + for (Enum protocolState : protocolStates) { + if (protocolState.name().equals("READY_TO_ACCEPT")) { + readyToAcceptState = protocolState; + } + } + READY_TO_ACCEPT_PROTOCOL_STATE = readyToAcceptState; + checkNotNull(READY_TO_ACCEPT_PROTOCOL_STATE, + "Ready to accept state from Protocol state cannot be null"); + + Class packetListenerClass = getPrefixedClass("PacketListener"); + PACKET_LISTENER = getFieldOfType(networkManager, packetListenerClass); + checkNotNull(PACKET_LISTENER, "PacketListener cannot be null"); + + LOGIN_HANDLER = getPrefixedClass("LoginListener$LoginHandler"); + checkNotNull(LOGIN_HANDLER, "LoginHandler cannot be null"); + + Constructor loginHandlerConstructor = null; + try { + loginHandlerConstructor = makeAccessible( + LOGIN_HANDLER.getDeclaredConstructor(LOGIN_LISTENER)); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } + LOGIN_HANDLER_CONSTRUCTOR = loginHandlerConstructor; + checkNotNull(LOGIN_HANDLER_CONSTRUCTOR, "LoginHandler constructor cannot be null"); + + FIRE_LOGIN_EVENTS = getMethod(LOGIN_HANDLER, "fireEvents"); + checkNotNull(FIRE_LOGIN_EVENTS, "fireEvents from LoginHandler cannot be null"); + } + /* per player stuff */ private final FloodgateConfig config; private final HandshakeHandler handshakeHandler; private final AttributeKey playerAttribute; private final FloodgateLogger logger; - private Object networkManager; private FloodgatePlayer fPlayer; private boolean bungee; - private boolean done; @Override @@ -103,8 +180,10 @@ public final class SpigotDataHandler extends SimpleChannelInboundHandler break; case INVALID_DATA_LENGTH: int dataLength = result.getBedrockData().getDataLength(); - logger.info(config.getMessages().getInvalidArgumentsLength(), - BedrockData.EXPECTED_LENGTH, dataLength); + logger.info( + config.getMessages().getInvalidArgumentsLength(), + BedrockData.EXPECTED_LENGTH, dataLength + ); ctx.close(); return; default: // only continue when SUCCESS @@ -182,78 +261,4 @@ public final class SpigotDataHandler extends SimpleChannelInboundHandler super.exceptionCaught(ctx, cause); cause.printStackTrace(); } - - static { - Class networkManager = getPrefixedClass("NetworkManager"); - checkNotNull(networkManager, "NetworkManager class cannot be null"); - - SOCKET_ADDRESS = getFieldOfType(networkManager, SocketAddress.class, false); - checkNotNull(SOCKET_ADDRESS, "SocketAddress field cannot be null"); - - HANDSHAKE_PACKET = getPrefixedClass("PacketHandshakingInSetProtocol"); - checkNotNull(HANDSHAKE_PACKET, "PacketHandshakingInSetProtocol cannot be null"); - HANDSHAKE_HOST = getFieldOfType(HANDSHAKE_PACKET, String.class); - checkNotNull(HANDSHAKE_HOST, "Host field from handshake packet cannot be null"); - - LOGIN_START_PACKET = getPrefixedClass("PacketLoginInStart"); - checkNotNull(LOGIN_START_PACKET, "PacketLoginInStart cannot be null"); - - GAME_PROFILE = ReflectionUtils.getClass("com.mojang.authlib.GameProfile"); - checkNotNull(GAME_PROFILE, "GameProfile class cannot be null"); - - Constructor gameProfileConstructor = null; - try { - gameProfileConstructor = GAME_PROFILE.getConstructor(UUID.class, String.class); - } catch (NoSuchMethodException e) { - e.printStackTrace(); - } - GAME_PROFILE_CONSTRUCTOR = gameProfileConstructor; - checkNotNull(GAME_PROFILE_CONSTRUCTOR, "GameProfileConstructor cannot be null"); - - LOGIN_LISTENER = getPrefixedClass("LoginListener"); - checkNotNull(LOGIN_LISTENER, "LoginListener cannot be null"); - LOGIN_PROFILE = getFieldOfType(LOGIN_LISTENER, GAME_PROFILE); - checkNotNull(LOGIN_PROFILE, "Profile from LoginListener cannot be null"); - INIT_UUID = getMethod(LOGIN_LISTENER, "initUUID"); - checkNotNull(INIT_UUID, "initUUID from LoginListener cannot be null"); - - Field protocolStateField = null; - for (Field field : LOGIN_LISTENER.getDeclaredFields()) { - if (field.getType().isEnum()) { - protocolStateField = field; - } - } - PROTOCOL_STATE = protocolStateField; - checkNotNull(PROTOCOL_STATE, "Protocol state field from LoginListener cannot be null"); - - Enum[] protocolStates = (Enum[]) PROTOCOL_STATE.getType().getEnumConstants(); - Object readyToAcceptState = null; - for (Enum protocolState : protocolStates) { - if (protocolState.name().equals("READY_TO_ACCEPT")) { - readyToAcceptState = protocolState; - } - } - READY_TO_ACCEPT_PROTOCOL_STATE = readyToAcceptState; - checkNotNull(READY_TO_ACCEPT_PROTOCOL_STATE, - "Ready to accept state from Protocol state cannot be null"); - - Class packetListenerClass = getPrefixedClass("PacketListener"); - PACKET_LISTENER = getFieldOfType(networkManager, packetListenerClass); - checkNotNull(PACKET_LISTENER, "PacketListener cannot be null"); - - LOGIN_HANDLER = getPrefixedClass("LoginListener$LoginHandler"); - checkNotNull(LOGIN_HANDLER, "LoginHandler cannot be null"); - - Constructor loginHandlerConstructor = null; - try { - loginHandlerConstructor = makeAccessible(LOGIN_HANDLER.getDeclaredConstructor(LOGIN_LISTENER)); - } catch (NoSuchMethodException e) { - e.printStackTrace(); - } - LOGIN_HANDLER_CONSTRUCTOR = loginHandlerConstructor; - checkNotNull(LOGIN_HANDLER_CONSTRUCTOR, "LoginHandler constructor cannot be null"); - - FIRE_LOGIN_EVENTS = getMethod(LOGIN_HANDLER, "fireEvents"); - checkNotNull(FIRE_LOGIN_EVENTS, "fireEvents from LoginHandler cannot be null"); - } } diff --git a/spigot/src/main/java/org/geysermc/floodgate/command/SpigotCommandRegistration.java b/spigot/src/main/java/org/geysermc/floodgate/command/SpigotCommandRegistration.java index e43095a5..3158b89a 100644 --- a/spigot/src/main/java/org/geysermc/floodgate/command/SpigotCommandRegistration.java +++ b/spigot/src/main/java/org/geysermc/floodgate/command/SpigotCommandRegistration.java @@ -45,9 +45,8 @@ public final class SpigotCommandRegistration implements CommandRegistration { public void register(Command command) { String defaultLocale = languageManager.getDefaultLocale(); - plugin.getCommand(command.getName()).setExecutor( - new SpigotCommandWrapper(commandUtil, command, defaultLocale) - ); + plugin.getCommand(command.getName()) + .setExecutor(new SpigotCommandWrapper(commandUtil, command, defaultLocale)); } @RequiredArgsConstructor diff --git a/spigot/src/main/java/org/geysermc/floodgate/inject/spigot/CustomList.java b/spigot/src/main/java/org/geysermc/floodgate/inject/spigot/CustomList.java index 11cbc933..bded8c5d 100644 --- a/spigot/src/main/java/org/geysermc/floodgate/inject/spigot/CustomList.java +++ b/spigot/src/main/java/org/geysermc/floodgate/inject/spigot/CustomList.java @@ -25,13 +25,12 @@ package org.geysermc.floodgate.inject.spigot; -import lombok.AllArgsConstructor; -import lombok.Getter; - import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.ListIterator; +import lombok.AllArgsConstructor; +import lombok.Getter; @AllArgsConstructor @SuppressWarnings({"unchecked", "rawtypes"}) @@ -78,11 +77,21 @@ public abstract class CustomList implements List { } } + @Override + public synchronized void add(int index, Object element) { + originalList.add(index, element); + } + @Override public synchronized boolean remove(Object o) { return originalList.remove(o); } + @Override + public synchronized Object remove(int index) { + return originalList.remove(index); + } + @Override public synchronized boolean containsAll(Collection c) { return originalList.containsAll(c); @@ -133,16 +142,6 @@ public abstract class CustomList implements List { return originalList.set(index, element); } - @Override - public synchronized void add(int index, Object element) { - originalList.add(index, element); - } - - @Override - public synchronized Object remove(int index) { - return originalList.remove(index); - } - @Override public synchronized int indexOf(Object o) { return originalList.indexOf(o); 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 6b9ec96f..3e5ff58d 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 @@ -25,23 +25,33 @@ package org.geysermc.floodgate.inject.spigot; -import io.netty.channel.*; +import io.netty.channel.Channel; +import io.netty.channel.ChannelFuture; +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; +import java.util.HashSet; +import java.util.List; +import java.util.Set; import lombok.Getter; import lombok.RequiredArgsConstructor; import org.geysermc.floodgate.inject.CommonPlatformInjector; import org.geysermc.floodgate.util.ReflectionUtils; -import java.lang.reflect.*; -import java.util.*; - @RequiredArgsConstructor public final class SpigotInjector extends CommonPlatformInjector { - private Object serverConnection; private final Set injectedClients = new HashSet<>(); - @Getter private boolean injected = false; + private Object serverConnection; private String injectedFieldName; + @Getter private boolean injected = false; + @Override @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") public boolean inject() throws Exception { @@ -50,11 +60,11 @@ public final class SpigotInjector extends CommonPlatformInjector { } if (getServerConnection() != null) { - for (Field f : serverConnection.getClass().getDeclaredFields()) { - if (f.getType() == List.class) { - f.setAccessible(true); + for (Field field : serverConnection.getClass().getDeclaredFields()) { + if (field.getType() == List.class) { + field.setAccessible(true); - ParameterizedType parameterType = ((ParameterizedType) f.getGenericType()); + ParameterizedType parameterType = ((ParameterizedType) field.getGenericType()); Type listType = parameterType.getActualTypeArguments()[0]; // the list we search has ChannelFuture as type @@ -62,30 +72,30 @@ public final class SpigotInjector extends CommonPlatformInjector { continue; } - injectedFieldName = f.getName(); - List newList = new CustomList((List) f.get(serverConnection)) { + injectedFieldName = field.getName(); + List newList = new CustomList((List) field.get(serverConnection)) { @Override - public void onAdd(Object o) { + public void onAdd(Object object) { try { - injectClient((ChannelFuture) o); - } catch (Exception e) { - e.printStackTrace(); + injectClient((ChannelFuture) object); + } catch (Exception exception) { + exception.printStackTrace(); } } }; // inject existing synchronized (newList) { - for (Object o : newList) { + for (Object object : newList) { try { - injectClient((ChannelFuture) o); - } catch (Exception e) { - e.printStackTrace(); + injectClient((ChannelFuture) object); + } catch (Exception exception) { + exception.printStackTrace(); } } } - f.set(serverConnection, newList); + field.set(serverConnection, newList); injected = true; return true; } @@ -129,6 +139,7 @@ public final class SpigotInjector extends CommonPlatformInjector { if (serverConnection != null) { Field field = ReflectionUtils.getField(serverConnection.getClass(), injectedFieldName); List list = (List) ReflectionUtils.getValue(serverConnection, field); + if (list instanceof CustomList) { CustomList customList = (CustomList) list; ReflectionUtils.setValue(serverConnection, field, customList.getOriginalList()); @@ -143,15 +154,17 @@ public final class SpigotInjector extends CommonPlatformInjector { } public Object getServerConnection() throws IllegalAccessException, InvocationTargetException { - if (serverConnection != null) return serverConnection; + if (serverConnection != null) { + return serverConnection; + } Class minecraftServer = ReflectionUtils.getPrefixedClass("MinecraftServer"); assert minecraftServer != null; Object minecraftServerInstance = ReflectionUtils.invokeStatic(minecraftServer, "getServer"); - for (Method m : minecraftServer.getDeclaredMethods()) { - if (m.getReturnType().getSimpleName().equals("ServerConnection")) { - if (m.getParameterTypes().length == 0) { - serverConnection = m.invoke(minecraftServerInstance); + for (Method method : minecraftServer.getDeclaredMethods()) { + if (method.getReturnType().getSimpleName().equals("ServerConnection")) { + if (method.getParameterTypes().length == 0) { + serverConnection = method.invoke(minecraftServerInstance); } } } diff --git a/spigot/src/main/java/org/geysermc/floodgate/listener/SpigotListener.java b/spigot/src/main/java/org/geysermc/floodgate/listener/SpigotListener.java index ca0bf023..db660071 100644 --- a/spigot/src/main/java/org/geysermc/floodgate/listener/SpigotListener.java +++ b/spigot/src/main/java/org/geysermc/floodgate/listener/SpigotListener.java @@ -26,6 +26,7 @@ package org.geysermc.floodgate.listener; import com.google.inject.Inject; +import java.util.UUID; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -39,8 +40,6 @@ import org.geysermc.floodgate.api.logger.FloodgateLogger; import org.geysermc.floodgate.api.player.FloodgatePlayer; import org.geysermc.floodgate.util.LanguageManager; -import java.util.UUID; - public final class SpigotListener implements Listener { @Inject private SimpleFloodgateApi api; @Inject private FloodgateLogger logger; @@ -66,8 +65,10 @@ public final class SpigotListener implements Listener { FloodgatePlayer player = api.getPlayer(uniqueId); if (player != null) { player.as(FloodgatePlayerImpl.class).setLogin(false); - logger.info(languageManager.getLogString("floodgate.ingame.login_name", - player.getCorrectUsername(), player.getCorrectUniqueId())); + logger.translatedInfo( + "floodgate.ingame.login_name", + player.getCorrectUsername(), player.getCorrectUniqueId() + ); languageManager.loadLocale(player.getLanguageCode()); } } @@ -76,9 +77,7 @@ public final class SpigotListener implements Listener { public void onPlayerQuit(PlayerQuitEvent event) { Player player = event.getPlayer(); if (api.removePlayer(player.getUniqueId()) != null) { - logger.info(languageManager.getLogString( - "floodgate.ingame.disconnect_name", player.getName()) - ); + logger.translatedInfo("floodgate.ingame.disconnect_name", player.getName()); } } } diff --git a/spigot/src/main/java/org/geysermc/floodgate/module/SpigotAddonModule.java b/spigot/src/main/java/org/geysermc/floodgate/module/SpigotAddonModule.java index 0ce2ca98..17110057 100644 --- a/spigot/src/main/java/org/geysermc/floodgate/module/SpigotAddonModule.java +++ b/spigot/src/main/java/org/geysermc/floodgate/module/SpigotAddonModule.java @@ -29,9 +29,9 @@ import com.google.inject.AbstractModule; import com.google.inject.Singleton; import com.google.inject.multibindings.ProvidesIntoSet; import org.geysermc.floodgate.addon.AddonManagerAddon; +import org.geysermc.floodgate.addon.DebugAddon; import org.geysermc.floodgate.addon.data.SpigotDataAddon; import org.geysermc.floodgate.api.inject.InjectorAddon; -import org.geysermc.floodgate.addon.DebugAddon; import org.geysermc.floodgate.register.AddonRegister; public final class SpigotAddonModule extends AbstractModule { diff --git a/spigot/src/main/java/org/geysermc/floodgate/module/SpigotPlatformModule.java b/spigot/src/main/java/org/geysermc/floodgate/module/SpigotPlatformModule.java index 252c2910..cbd6d918 100644 --- a/spigot/src/main/java/org/geysermc/floodgate/module/SpigotPlatformModule.java +++ b/spigot/src/main/java/org/geysermc/floodgate/module/SpigotPlatformModule.java @@ -72,8 +72,8 @@ public final class SpigotPlatformModule extends AbstractModule { @Provides @Singleton - public FloodgateLogger floodgateLogger() { - return new JavaUtilFloodgateLogger(plugin.getLogger()); + public FloodgateLogger floodgateLogger(LanguageManager languageManager) { + return new JavaUtilFloodgateLogger(plugin.getLogger(), languageManager); } /* diff --git a/velocity/pom.xml b/velocity/pom.xml index bc9cadd2..17aaacb8 100644 --- a/velocity/pom.xml +++ b/velocity/pom.xml @@ -2,64 +2,7 @@ - - parent - org.geysermc.floodgate - 1.0-SNAPSHOT - - 4.0.0 - ${parent.url} - velocity - - - 2.11.2 - - - - - velocity-repo - https://repo.velocitypowered.com/snapshots/ - - - - minecraft-repo - https://libraries.minecraft.net/ - - - sponge-repo - https://repo.spongepowered.org/maven/ - - - - - - com.velocitypowered - velocity-api - ${velocity.version} - provided - - - org.apache.logging.log4j - log4j-core - ${log4j.version} - provided - - - io.netty - netty-all - 4.1.45.Final - provided - - - org.geysermc.floodgate - common - ${project.version} - compile - - - @@ -87,4 +30,61 @@ - \ No newline at end of file + + + com.velocitypowered + velocity-api + ${velocity.version} + provided + + + org.apache.logging.log4j + log4j-core + ${log4j.version} + provided + + + io.netty + netty-all + 4.1.45.Final + provided + + + org.geysermc.floodgate + common + ${project.version} + compile + + + + 4.0.0 + + + parent + org.geysermc.floodgate + 1.0-SNAPSHOT + + + + 2.11.2 + + + + + velocity-repo + https://repo.velocitypowered.com/snapshots/ + + + + minecraft-repo + https://libraries.minecraft.net/ + + + sponge-repo + https://repo.spongepowered.org/maven/ + + + + ${parent.url} + diff --git a/velocity/src/main/java/org/geysermc/floodgate/VelocityPlugin.java b/velocity/src/main/java/org/geysermc/floodgate/VelocityPlugin.java index d06ff099..261859ed 100644 --- a/velocity/src/main/java/org/geysermc/floodgate/VelocityPlugin.java +++ b/velocity/src/main/java/org/geysermc/floodgate/VelocityPlugin.java @@ -30,17 +30,20 @@ import com.google.inject.Injector; import com.velocitypowered.api.event.Subscribe; import com.velocitypowered.api.event.proxy.ProxyInitializeEvent; import com.velocitypowered.api.plugin.annotation.DataDirectory; -import org.geysermc.floodgate.module.*; -import org.geysermc.floodgate.util.ReflectionUtils; -import org.slf4j.Logger; - import java.nio.file.Path; +import org.geysermc.floodgate.api.logger.FloodgateLogger; +import org.geysermc.floodgate.module.CommandModule; +import org.geysermc.floodgate.module.CommonModule; +import org.geysermc.floodgate.module.VelocityAddonModule; +import org.geysermc.floodgate.module.VelocityListenerModule; +import org.geysermc.floodgate.module.VelocityPlatformModule; +import org.geysermc.floodgate.util.ReflectionUtils; public final class VelocityPlugin { private final FloodgatePlatform platform; @Inject - public VelocityPlugin(@DataDirectory Path dataDirectory, Injector guice, Logger logger) { + public VelocityPlugin(@DataDirectory Path dataDirectory, Injector guice) { ReflectionUtils.setPrefix("com.velocitypowered.proxy"); long ctm = System.currentTimeMillis(); @@ -52,15 +55,15 @@ public final class VelocityPlugin { platform = injector.getInstance(FloodgatePlatform.class); long endCtm = System.currentTimeMillis(); - logger.info(platform.getLanguageManager().getLogString( - "floodgate.core.finish", - endCtm - ctm - )); + injector.getInstance(FloodgateLogger.class) + .translatedInfo("floodgate.core.finish", endCtm - ctm); } @Subscribe public void onProxyInitialization(ProxyInitializeEvent event) { - platform.enable(new CommandModule(), new VelocityListenerModule(), - new VelocityAddonModule()); + platform.enable( + new CommandModule(), new VelocityListenerModule(), + new VelocityAddonModule() + ); } } diff --git a/velocity/src/main/java/org/geysermc/floodgate/addon/data/VelocityDataAddon.java b/velocity/src/main/java/org/geysermc/floodgate/addon/data/VelocityDataAddon.java index cfb6e756..da6a2c34 100644 --- a/velocity/src/main/java/org/geysermc/floodgate/addon/data/VelocityDataAddon.java +++ b/velocity/src/main/java/org/geysermc/floodgate/addon/data/VelocityDataAddon.java @@ -28,7 +28,6 @@ package org.geysermc.floodgate.addon.data; import com.google.inject.Inject; import com.google.inject.name.Named; import io.netty.channel.Channel; -import io.netty.channel.EventLoop; import io.netty.util.AttributeKey; import org.geysermc.floodgate.HandshakeHandler; import org.geysermc.floodgate.api.ProxyFloodgateApi; @@ -37,9 +36,6 @@ import org.geysermc.floodgate.api.logger.FloodgateLogger; import org.geysermc.floodgate.api.player.FloodgatePlayer; import org.geysermc.floodgate.config.ProxyFloodgateConfig; -import java.util.HashMap; -import java.util.Map; - public final class VelocityDataAddon implements InjectorAddon { @Inject private HandshakeHandler handshakeHandler; @Inject private ProxyFloodgateConfig config; @@ -63,8 +59,8 @@ public final class VelocityDataAddon implements InjectorAddon { private AttributeKey kickMessageAttribute; @Override - public void onInject(Channel channel, boolean proxyToServer) { - if (proxyToServer) { + public void onInject(Channel channel, boolean toServer) { + if (toServer) { channel.pipeline().addAfter( packetEncoder, "floodgate_data_handler", new VelocityServerDataHandler(config, api) diff --git a/velocity/src/main/java/org/geysermc/floodgate/addon/data/VelocityProxyDataHandler.java b/velocity/src/main/java/org/geysermc/floodgate/addon/data/VelocityProxyDataHandler.java index 30045f23..b9dbb6dc 100644 --- a/velocity/src/main/java/org/geysermc/floodgate/addon/data/VelocityProxyDataHandler.java +++ b/velocity/src/main/java/org/geysermc/floodgate/addon/data/VelocityProxyDataHandler.java @@ -25,10 +25,16 @@ package org.geysermc.floodgate.addon.data; +import static com.google.common.base.Preconditions.checkNotNull; +import static org.geysermc.floodgate.util.ReflectionUtils.getCastedValue; +import static org.geysermc.floodgate.util.ReflectionUtils.getField; +import static org.geysermc.floodgate.util.ReflectionUtils.getPrefixedClass; + import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.util.AttributeKey; import io.netty.util.ReferenceCountUtil; +import java.lang.reflect.Field; import lombok.RequiredArgsConstructor; import org.geysermc.floodgate.HandshakeHandler; import org.geysermc.floodgate.HandshakeHandler.HandshakeResult; @@ -37,26 +43,32 @@ import org.geysermc.floodgate.api.logger.FloodgateLogger; import org.geysermc.floodgate.api.player.FloodgatePlayer; import org.geysermc.floodgate.config.ProxyFloodgateConfig; -import java.lang.reflect.Field; - -import static com.google.common.base.Preconditions.checkNotNull; -import static org.geysermc.floodgate.util.ReflectionUtils.*; - @RequiredArgsConstructor public final class VelocityProxyDataHandler extends SimpleChannelInboundHandler { private static final Field HANDSHAKE; private static final Class HANDSHAKE_PACKET; private static final Field HANDSHAKE_SERVER_ADDRESS; + static { + Class iic = getPrefixedClass("connection.client.InitialInboundConnection"); + checkNotNull(iic, "InitialInboundConnection class cannot be null"); + + HANDSHAKE = getField(iic, "handshake"); + checkNotNull(HANDSHAKE, "Handshake field cannot be null"); + + HANDSHAKE_PACKET = getPrefixedClass("protocol.packet.Handshake"); + checkNotNull(HANDSHAKE_PACKET, "Handshake packet class cannot be null"); + + HANDSHAKE_SERVER_ADDRESS = getField(HANDSHAKE_PACKET, "serverAddress"); + checkNotNull(HANDSHAKE_SERVER_ADDRESS, "Address in the Handshake packet cannot be null"); + } + private final ProxyFloodgateConfig config; private final ProxyFloodgateApi api; private final HandshakeHandler handshakeHandler; - private final AttributeKey playerAttribute; private final AttributeKey kickMessageAttribute; - private final FloodgateLogger logger; - private boolean done; @Override @@ -102,19 +114,4 @@ public final class VelocityProxyDataHandler extends SimpleChannelInboundHandler< logger.info("Floodgate player who is logged in as {} {} joined", player.getCorrectUsername(), player.getCorrectUniqueId()); } - - static { - Class initialInboundConnection = - getPrefixedClass("connection.client.InitialInboundConnection"); - checkNotNull(initialInboundConnection, "InitialInboundConnection class cannot be null"); - - HANDSHAKE = getField(initialInboundConnection, "handshake"); - checkNotNull(HANDSHAKE, "Handshake field cannot be null"); - - HANDSHAKE_PACKET = getPrefixedClass("protocol.packet.Handshake"); - checkNotNull(HANDSHAKE_PACKET, "Handshake packet class cannot be null"); - - HANDSHAKE_SERVER_ADDRESS = getField(HANDSHAKE_PACKET, "serverAddress"); - checkNotNull(HANDSHAKE_SERVER_ADDRESS, "Address field of the Handshake packet cannot be null"); - } } diff --git a/velocity/src/main/java/org/geysermc/floodgate/addon/data/VelocityServerDataHandler.java b/velocity/src/main/java/org/geysermc/floodgate/addon/data/VelocityServerDataHandler.java index ffc619b5..f16a0aad 100644 --- a/velocity/src/main/java/org/geysermc/floodgate/addon/data/VelocityServerDataHandler.java +++ b/velocity/src/main/java/org/geysermc/floodgate/addon/data/VelocityServerDataHandler.java @@ -25,33 +25,55 @@ package org.geysermc.floodgate.addon.data; +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static org.geysermc.floodgate.util.ReflectionUtils.castedInvoke; +import static org.geysermc.floodgate.util.ReflectionUtils.getCastedValue; +import static org.geysermc.floodgate.util.ReflectionUtils.getField; +import static org.geysermc.floodgate.util.ReflectionUtils.getMethod; +import static org.geysermc.floodgate.util.ReflectionUtils.getPrefixedClass; +import static org.geysermc.floodgate.util.ReflectionUtils.invoke; +import static org.geysermc.floodgate.util.ReflectionUtils.setValue; + import com.velocitypowered.api.proxy.Player; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.MessageToMessageEncoder; import io.netty.util.ReferenceCountUtil; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.List; import lombok.RequiredArgsConstructor; import org.geysermc.floodgate.api.ProxyFloodgateApi; import org.geysermc.floodgate.api.player.FloodgatePlayer; import org.geysermc.floodgate.config.ProxyFloodgateConfig; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.List; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static org.geysermc.floodgate.util.ReflectionUtils.*; - @RequiredArgsConstructor -public class VelocityServerDataHandler extends MessageToMessageEncoder { +public final class VelocityServerDataHandler extends MessageToMessageEncoder { private static final Class HANDSHAKE_PACKET; private static final Field HANDSHAKE_ADDRESS; private static final Method GET_ASSOCIATION; private static final Method GET_PLAYER; + static { + HANDSHAKE_PACKET = getPrefixedClass("protocol.packet.Handshake"); + checkNotNull(HANDSHAKE_PACKET, "Handshake packet class cannot be null"); + + HANDSHAKE_ADDRESS = getField(HANDSHAKE_PACKET, "serverAddress"); + checkNotNull(HANDSHAKE_ADDRESS, "Address field of the Handshake packet cannot be null"); + + Class minecraftConnection = getPrefixedClass("connection.MinecraftConnection"); + + GET_ASSOCIATION = getMethod(minecraftConnection, "getAssociation"); + checkNotNull(GET_ASSOCIATION, "getAssociation in MinecraftConnection cannot be null"); + + Class serverConnection = getPrefixedClass("connection.backend.VelocityServerConnection"); + + GET_PLAYER = getMethod(serverConnection, "getPlayer"); + checkNotNull(GET_PLAYER, "getPlayer in VelocityServerConnection cannot be null"); + } + private final ProxyFloodgateConfig config; private final ProxyFloodgateApi api; - private boolean done; @Override @@ -63,7 +85,8 @@ public class VelocityServerDataHandler extends MessageToMessageEncoder { } if (!HANDSHAKE_PACKET.isInstance(packet) || !config.isSendFloodgateData()) { - System.out.println(HANDSHAKE_PACKET.isInstance(packet)+" "+config.isSendFloodgateData()); + System.out.println( + HANDSHAKE_PACKET.isInstance(packet) + " " + config.isSendFloodgateData()); done = true; out.add(packet); return; @@ -99,22 +122,4 @@ public class VelocityServerDataHandler extends MessageToMessageEncoder { done = true; out.add(packet); } - - static { - HANDSHAKE_PACKET = getPrefixedClass("protocol.packet.Handshake"); - checkNotNull(HANDSHAKE_PACKET, "Handshake packet class cannot be null"); - - HANDSHAKE_ADDRESS = getField(HANDSHAKE_PACKET, "serverAddress"); - checkNotNull(HANDSHAKE_ADDRESS, "Address field of the Handshake packet cannot be null"); - - Class minecraftConnection = getPrefixedClass("connection.MinecraftConnection"); - - GET_ASSOCIATION = getMethod(minecraftConnection, "getAssociation"); - checkNotNull(GET_ASSOCIATION, "getAssociation in MinecraftConnection cannot be null"); - - Class serverConnection = getPrefixedClass("connection.backend.VelocityServerConnection"); - - GET_PLAYER = getMethod(serverConnection, "getPlayer"); - checkNotNull(GET_PLAYER, "getPlayer in VelocityServerConnection cannot be null"); - } } diff --git a/velocity/src/main/java/org/geysermc/floodgate/command/VelocityCommandRegistration.java b/velocity/src/main/java/org/geysermc/floodgate/command/VelocityCommandRegistration.java index 443928b2..01f5ba79 100644 --- a/velocity/src/main/java/org/geysermc/floodgate/command/VelocityCommandRegistration.java +++ b/velocity/src/main/java/org/geysermc/floodgate/command/VelocityCommandRegistration.java @@ -28,6 +28,7 @@ package org.geysermc.floodgate.command; import com.velocitypowered.api.command.CommandManager; import com.velocitypowered.api.command.CommandSource; import com.velocitypowered.api.proxy.Player; +import java.util.Locale; import lombok.RequiredArgsConstructor; import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.floodgate.platform.command.Command; @@ -35,8 +36,6 @@ import org.geysermc.floodgate.platform.command.CommandRegistration; import org.geysermc.floodgate.platform.command.CommandUtil; import org.geysermc.floodgate.util.LanguageManager; -import java.util.Locale; - @RequiredArgsConstructor public final class VelocityCommandRegistration implements CommandRegistration { private final CommandManager commandManager; 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 c30fd463..56c74cc8 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 @@ -25,26 +25,31 @@ package org.geysermc.floodgate.inject.velocity; +import static org.geysermc.floodgate.util.ReflectionUtils.castedInvoke; +import static org.geysermc.floodgate.util.ReflectionUtils.getMethod; +import static org.geysermc.floodgate.util.ReflectionUtils.getValue; +import static org.geysermc.floodgate.util.ReflectionUtils.invoke; + import com.velocitypowered.api.proxy.ProxyServer; import io.netty.channel.Channel; import io.netty.channel.ChannelInitializer; +import java.lang.reflect.Method; +import javax.naming.OperationNotSupportedException; import lombok.Getter; import lombok.RequiredArgsConstructor; import org.geysermc.floodgate.inject.CommonPlatformInjector; -import javax.naming.OperationNotSupportedException; -import java.lang.reflect.Method; - -import static org.geysermc.floodgate.util.ReflectionUtils.*; - @RequiredArgsConstructor public final class VelocityInjector extends CommonPlatformInjector { private final ProxyServer server; + @Getter private boolean injected = false; @SuppressWarnings("rawtypes") public boolean inject() { - if (isInjected()) return true; + if (isInjected()) { + return true; + } Object connectionManager = getValue(server, "cm"); @@ -55,16 +60,16 @@ public final class VelocityInjector extends CommonPlatformInjector { Method serverSetter = getMethod(serverInitializerHolder, "set", ChannelInitializer.class); invoke(serverInitializerHolder, serverSetter, - new VelocityChannelInitializer(this, serverInitializer, false)); + new VelocityChannelInitializer(this, serverInitializer, false)); // Proxy <-> Server - Object backendInitializerHolder = getValue(connectionManager,"backendChannelInitializer"); + Object backendInitializerHolder = getValue(connectionManager, "backendChannelInitializer"); ChannelInitializer backendInitializer = castedInvoke(backendInitializerHolder, "get"); Method backendSetter = getMethod(backendInitializerHolder, "set", ChannelInitializer.class); invoke(backendInitializerHolder, backendSetter, - new VelocityChannelInitializer(this, backendInitializer, true)); + new VelocityChannelInitializer(this, backendInitializer, true)); return injected = true; } @@ -80,6 +85,10 @@ public final class VelocityInjector extends CommonPlatformInjector { private static final class VelocityChannelInitializer extends ChannelInitializer { private static final Method initChannel; + static { + initChannel = getMethod(ChannelInitializer.class, "initChannel", Channel.class); + } + private final VelocityInjector injector; private final ChannelInitializer original; private final boolean proxyToServer; @@ -91,9 +100,5 @@ public final class VelocityInjector extends CommonPlatformInjector { injector.injectAddonsCall(channel, proxyToServer); injector.addInjectedClient(channel); } - - static { - initChannel = getMethod(ChannelInitializer.class, "initChannel", Channel.class); - } } } diff --git a/velocity/src/main/java/org/geysermc/floodgate/listener/VelocityListener.java b/velocity/src/main/java/org/geysermc/floodgate/listener/VelocityListener.java index 8f665ffc..ea146254 100644 --- a/velocity/src/main/java/org/geysermc/floodgate/listener/VelocityListener.java +++ b/velocity/src/main/java/org/geysermc/floodgate/listener/VelocityListener.java @@ -25,6 +25,11 @@ package org.geysermc.floodgate.listener; +import static org.geysermc.floodgate.util.ReflectionUtils.getCastedValue; +import static org.geysermc.floodgate.util.ReflectionUtils.getFieldOfType; +import static org.geysermc.floodgate.util.ReflectionUtils.getPrefixedClass; +import static org.geysermc.floodgate.util.ReflectionUtils.getValue; + import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import com.google.inject.Inject; @@ -40,23 +45,36 @@ import com.velocitypowered.api.proxy.Player; import com.velocitypowered.api.util.GameProfile; import io.netty.channel.Channel; import io.netty.util.AttributeKey; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.concurrent.TimeUnit; import net.kyori.adventure.text.TextComponent; import org.geysermc.floodgate.api.ProxyFloodgateApi; import org.geysermc.floodgate.api.logger.FloodgateLogger; import org.geysermc.floodgate.api.player.FloodgatePlayer; import org.geysermc.floodgate.util.LanguageManager; -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.concurrent.TimeUnit; - -import static org.geysermc.floodgate.util.ReflectionUtils.*; - public final class VelocityListener { private static final Field INITIAL_MINECRAFT_CONNECTION; private static final Field MINECRAFT_CONNECTION; private static final Field CHANNEL; + static { + Class initialConnection = getPrefixedClass("connection.client.InitialInboundConnection"); + + Class minecraftConnection = getPrefixedClass("connection.MinecraftConnection"); + INITIAL_MINECRAFT_CONNECTION = getFieldOfType(initialConnection, minecraftConnection); + Class connectedPlayer = getPrefixedClass("connection.client.ConnectedPlayer"); + MINECRAFT_CONNECTION = getFieldOfType(connectedPlayer, minecraftConnection); + CHANNEL = getFieldOfType(minecraftConnection, Channel.class); + } + + private final Cache playerCache = + CacheBuilder.newBuilder() + .maximumSize(500) + .expireAfterAccess(20, TimeUnit.SECONDS) + .build(); + @Inject private ProxyFloodgateApi api; @Inject private LanguageManager languageManager; @Inject private FloodgateLogger logger; @@ -69,12 +87,6 @@ public final class VelocityListener { @Named("kickMessageAttribute") private AttributeKey kickMessageAttribute; - private final Cache playerCache = - CacheBuilder.newBuilder() - .maximumSize(500) - .expireAfterAccess(20, TimeUnit.SECONDS) - .build(); - @Subscribe(order = PostOrder.EARLY) public void onPreLogin(PreLoginEvent event) { FloodgatePlayer player = null; @@ -91,7 +103,9 @@ public final class VelocityListener { } if (kickMessage != null) { - event.setResult(PreLoginEvent.PreLoginComponentResult.denied(TextComponent.of(kickMessage))); + event.setResult( + PreLoginEvent.PreLoginComponentResult.denied(TextComponent.of(kickMessage)) + ); return; } @@ -111,11 +125,13 @@ public final class VelocityListener { } } - @Subscribe + @Subscribe(order = PostOrder.LAST) public void onLogin(LoginEvent event) { - FloodgatePlayer player = api.getPlayer(event.getPlayer().getUniqueId()); - if (player != null) { - languageManager.loadLocale(player.getLanguageCode()); + if (event.getResult().isAllowed()) { + FloodgatePlayer player = api.getPlayer(event.getPlayer().getUniqueId()); + if (player != null) { + languageManager.loadLocale(player.getLanguageCode()); + } } } @@ -129,22 +145,10 @@ public final class VelocityListener { if (fPlayer != null && api.removePlayer(fPlayer)) { api.removeEncryptedData(event.getPlayer().getUniqueId()); - logger.info(languageManager.getLogString( - "floodgate.ingame.disconnect_name", player.getUsername() - )); + logger.translatedInfo("floodgate.ingame.disconnect_name", player.getUsername()); } } catch (Exception exception) { logger.error("Failed to remove the player", exception); } } - - static { - Class initialConnection = getPrefixedClass("connection.client.InitialInboundConnection"); - - Class minecraftConnection = getPrefixedClass("connection.MinecraftConnection"); - INITIAL_MINECRAFT_CONNECTION = getFieldOfType(initialConnection, minecraftConnection); - Class connectedPlayer = getPrefixedClass("connection.client.ConnectedPlayer"); - MINECRAFT_CONNECTION = getFieldOfType(connectedPlayer, minecraftConnection); - CHANNEL = getFieldOfType(minecraftConnection, Channel.class); - } } diff --git a/velocity/src/main/java/org/geysermc/floodgate/logger/Slf4jFloodgateLogger.java b/velocity/src/main/java/org/geysermc/floodgate/logger/Slf4jFloodgateLogger.java index 2f75662f..aaaf8502 100644 --- a/velocity/src/main/java/org/geysermc/floodgate/logger/Slf4jFloodgateLogger.java +++ b/velocity/src/main/java/org/geysermc/floodgate/logger/Slf4jFloodgateLogger.java @@ -25,17 +25,19 @@ package org.geysermc.floodgate.logger; +import static org.geysermc.floodgate.util.MessageFormatter.format; + import lombok.RequiredArgsConstructor; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.core.config.Configurator; import org.geysermc.floodgate.api.logger.FloodgateLogger; +import org.geysermc.floodgate.util.LanguageManager; import org.slf4j.Logger; -import static org.geysermc.floodgate.util.MessageFormatter.format; - @RequiredArgsConstructor public final class Slf4jFloodgateLogger implements FloodgateLogger { private final Logger logger; + private final LanguageManager languageManager; @Override public void error(String message, Object... args) { @@ -57,6 +59,11 @@ public final class Slf4jFloodgateLogger implements FloodgateLogger { logger.info(message, args); } + @Override + public void translatedInfo(String message, Object... args) { + logger.info(languageManager.getLogString(message, args)); + } + @Override public void debug(String message, Object... args) { logger.debug(message, args); 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 b5dbf485..9ee6fc27 100644 --- a/velocity/src/main/java/org/geysermc/floodgate/module/VelocityPlatformModule.java +++ b/velocity/src/main/java/org/geysermc/floodgate/module/VelocityPlatformModule.java @@ -74,8 +74,8 @@ public final class VelocityPlatformModule extends AbstractModule { @Provides @Singleton - public FloodgateLogger floodgateLogger(Logger logger) { - return new Slf4jFloodgateLogger(logger); + public FloodgateLogger floodgateLogger(Logger logger, LanguageManager languageManager) { + return new Slf4jFloodgateLogger(logger, languageManager); } /* diff --git a/velocity/src/main/java/org/geysermc/floodgate/util/VelocityCommandUtil.java b/velocity/src/main/java/org/geysermc/floodgate/util/VelocityCommandUtil.java index fb04ef27..9d392179 100644 --- a/velocity/src/main/java/org/geysermc/floodgate/util/VelocityCommandUtil.java +++ b/velocity/src/main/java/org/geysermc/floodgate/util/VelocityCommandUtil.java @@ -49,9 +49,7 @@ public final class VelocityCommandUtil implements CommandUtil { public TextComponent translateAndTransform(String locale, CommandMessage message, Object... args) { - return TextComponent.of(manager.getString( - message.getMessage(), locale, args - )); + return TextComponent.of(manager.getString(message.getMessage(), locale, args)); } protected Player cast(Object instance) {