From 465e66df7203135c55a45070c25ec0aa13e28070 Mon Sep 17 00:00:00 2001 From: Tim203 Date: Mon, 21 Mar 2022 14:41:53 +0100 Subject: [PATCH] Added metrics and fixed relocations not applying for child projects --- build-logic/src/main/kotlin/extensions.kt | 14 +- .../floodgate.shadow-conventions.gradle.kts | 24 ++- .../module/BungeePlatformModule.java | 7 + .../floodgate/util/BungeePlatformUtils.java | 46 ++++++ core/build.gradle.kts | 1 + .../geysermc/floodgate/FloodgatePlatform.java | 5 +- .../floodgate/command/WhitelistCommand.java | 2 +- .../config/{loader => }/ConfigLoader.java | 4 +- .../floodgate/config/FloodgateConfig.java | 4 +- .../floodgate/module/CommonModule.java | 2 +- .../platform/command/CommandUtil.java | 6 +- .../platform/util/PlatformUtils.java | 37 ++--- .../floodgate/platform/util/PlayerType.java | 32 ++++ .../audience/ProfileAudienceArgument.java | 2 +- .../geysermc/floodgate/util/Constants.java | 2 + .../org/geysermc/floodgate/util/Metrics.java | 143 ++++++++++++++++++ .../module/SpigotPlatformModule.java | 7 + .../geysermc/floodgate/util/ClassNames.java | 17 +++ .../floodgate/util/SpigotPlatformUtils.java | 48 ++++++ velocity/build.gradle.kts | 2 +- .../module/VelocityPlatformModule.java | 3 + .../floodgate/util/VelocityPlatformUtils.java | 46 ++++++ 22 files changed, 406 insertions(+), 48 deletions(-) create mode 100644 bungee/src/main/java/org/geysermc/floodgate/util/BungeePlatformUtils.java rename core/src/main/java/org/geysermc/floodgate/config/{loader => }/ConfigLoader.java (97%) create mode 100644 core/src/main/java/org/geysermc/floodgate/platform/util/PlayerType.java create mode 100644 core/src/main/java/org/geysermc/floodgate/util/Metrics.java create mode 100644 spigot/src/main/java/org/geysermc/floodgate/util/SpigotPlatformUtils.java create mode 100644 velocity/src/main/java/org/geysermc/floodgate/util/VelocityPlatformUtils.java diff --git a/build-logic/src/main/kotlin/extensions.kt b/build-logic/src/main/kotlin/extensions.kt index 1b781cb2..a31a492d 100644 --- a/build-logic/src/main/kotlin/extensions.kt +++ b/build-logic/src/main/kotlin/extensions.kt @@ -23,11 +23,9 @@ * @link https://github.com/GeyserMC/Floodgate */ -import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar import net.kyori.indra.git.IndraGitExtension import org.gradle.api.Project import org.gradle.api.artifacts.ProjectDependency -import org.gradle.kotlin.dsl.named import org.gradle.kotlin.dsl.the fun Project.isSnapshot(): Boolean = @@ -54,13 +52,8 @@ fun Project.buildNumber(): Int = fun Project.buildNumberAsString(): String = buildNumber().takeIf { it != -1 }?.toString() ?: "??" -fun Project.relocate(pattern: String) { - tasks.named("shadowJar") { - relocate(pattern, "org.geysermc.floodgate.shaded.$pattern") - } -} - val providedDependencies = mutableMapOf>() +val relocatedPackages = mutableMapOf>() fun Project.provided(pattern: String, name: String, version: String, excludedOn: Int = 0b110) { providedDependencies.getOrPut(project.name) { mutableSetOf() } @@ -73,5 +66,10 @@ fun Project.provided(pattern: String, name: String, version: String, excludedOn: fun Project.provided(dependency: ProjectDependency) = provided(dependency.group!!, dependency.name, dependency.version!!) + +fun Project.relocate(pattern: String) = + relocatedPackages.getOrPut(project.name) { mutableSetOf() } + .add(pattern) + private fun calcExclusion(section: String, bit: Int, excludedOn: Int): String = if (excludedOn and bit > 0) section else "" \ No newline at end of file diff --git a/build-logic/src/main/kotlin/floodgate.shadow-conventions.gradle.kts b/build-logic/src/main/kotlin/floodgate.shadow-conventions.gradle.kts index 5405f480..a0bd500b 100644 --- a/build-logic/src/main/kotlin/floodgate.shadow-conventions.gradle.kts +++ b/build-logic/src/main/kotlin/floodgate.shadow-conventions.gradle.kts @@ -24,9 +24,31 @@ tasks { exclude(dependency(string)) } } + + // relocations made in included project dependencies are for whatever reason not + // forwarded to the project implementing the dependency. + // (e.g. a relocation in `core` will relocate for core. But when you include `core` in + // for example Velocity, the relocation will be gone for Velocity) + addRelocations(project, sJar) } } named("build") { dependsOn(shadowJar) } -} \ No newline at end of file +} + +fun addRelocations(project: Project, shadowJar: ShadowJar) { + callAddRelocations(project.configurations.api.get(), shadowJar) + callAddRelocations(project.configurations.implementation.get(), shadowJar) + + relocatedPackages[project.name]?.forEach { pattern -> + println("Relocating $pattern for ${shadowJar.project.name}") + shadowJar.relocate(pattern, "org.geysermc.floodgate.shadow.$pattern") + } +} + +fun callAddRelocations(configuration: Configuration, shadowJar: ShadowJar) = + configuration.dependencies.forEach { + if (it is ProjectDependency) + addRelocations(it.dependencyProject, shadowJar) + } \ No newline at end of file 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 7bd1661a..cbe9b5e5 100644 --- a/bungee/src/main/java/org/geysermc/floodgate/module/BungeePlatformModule.java +++ b/bungee/src/main/java/org/geysermc/floodgate/module/BungeePlatformModule.java @@ -46,6 +46,7 @@ import org.geysermc.floodgate.logger.JavaUtilFloodgateLogger; import org.geysermc.floodgate.platform.command.CommandUtil; import org.geysermc.floodgate.platform.listener.ListenerRegistration; import org.geysermc.floodgate.platform.pluginmessage.PluginMessageUtils; +import org.geysermc.floodgate.platform.util.PlatformUtils; import org.geysermc.floodgate.player.FloodgateCommandPreprocessor; import org.geysermc.floodgate.player.UserAudience; import org.geysermc.floodgate.pluginmessage.BungeePluginMessageRegistration; @@ -55,12 +56,18 @@ import org.geysermc.floodgate.pluginmessage.PluginMessageManager; import org.geysermc.floodgate.pluginmessage.PluginMessageRegistration; import org.geysermc.floodgate.skin.SkinApplier; import org.geysermc.floodgate.util.BungeeCommandUtil; +import org.geysermc.floodgate.util.BungeePlatformUtils; import org.geysermc.floodgate.util.LanguageManager; @RequiredArgsConstructor public final class BungeePlatformModule extends AbstractModule { private final BungeePlugin plugin; + @Override + protected void configure() { + bind(PlatformUtils.class).to(BungeePlatformUtils.class); + } + @Provides @Singleton public Plugin bungeePlugin() { diff --git a/bungee/src/main/java/org/geysermc/floodgate/util/BungeePlatformUtils.java b/bungee/src/main/java/org/geysermc/floodgate/util/BungeePlatformUtils.java new file mode 100644 index 00000000..44540da2 --- /dev/null +++ b/bungee/src/main/java/org/geysermc/floodgate/util/BungeePlatformUtils.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Floodgate + */ + +package org.geysermc.floodgate.util; + +import java.util.List; +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.protocol.ProtocolConstants; +import org.geysermc.floodgate.platform.util.PlatformUtils; + +public final class BungeePlatformUtils extends PlatformUtils { + private final ProxyServer proxyServer = ProxyServer.getInstance(); + + @Override + public AuthType authType() { + return proxyServer.getConfig().isOnlineMode() ? AuthType.ONLINE : AuthType.OFFLINE; + } + + @Override + public String minecraftVersion() { + List versions = ProtocolConstants.SUPPORTED_VERSIONS; + return versions.get(versions.size() - 1); + } +} diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 8a1d04e0..adafc1a6 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -26,6 +26,7 @@ relocate("org.bstats") configure { val constantsFile = "src/main/java/org/geysermc/floodgate/util/Constants.java" + replaceToken("\${floodgateVersion}", fullVersion(), constantsFile) replaceToken("\${branch}", branchName(), constantsFile) replaceToken("\${buildNumber}", buildNumber(), constantsFile) } diff --git a/core/src/main/java/org/geysermc/floodgate/FloodgatePlatform.java b/core/src/main/java/org/geysermc/floodgate/FloodgatePlatform.java index 245ef777..7b963d73 100644 --- a/core/src/main/java/org/geysermc/floodgate/FloodgatePlatform.java +++ b/core/src/main/java/org/geysermc/floodgate/FloodgatePlatform.java @@ -40,13 +40,14 @@ import org.geysermc.floodgate.api.inject.PlatformInjector; import org.geysermc.floodgate.api.link.PlayerLink; import org.geysermc.floodgate.api.logger.FloodgateLogger; import org.geysermc.floodgate.api.packet.PacketHandlers; +import org.geysermc.floodgate.config.ConfigLoader; import org.geysermc.floodgate.config.FloodgateConfig; import org.geysermc.floodgate.config.FloodgateConfigHolder; -import org.geysermc.floodgate.config.loader.ConfigLoader; import org.geysermc.floodgate.link.PlayerLinkLoader; import org.geysermc.floodgate.module.ConfigLoadedModule; import org.geysermc.floodgate.module.PostInitializeModule; import org.geysermc.floodgate.news.NewsChecker; +import org.geysermc.floodgate.util.Metrics; import org.geysermc.floodgate.util.PrefixCheckTask; public class FloodgatePlatform { @@ -123,6 +124,8 @@ public class FloodgatePlatform { PrefixCheckTask.checkAndExecuteDelayed(config, logger); + guice.getInstance(Metrics.class); + return true; } diff --git a/core/src/main/java/org/geysermc/floodgate/command/WhitelistCommand.java b/core/src/main/java/org/geysermc/floodgate/command/WhitelistCommand.java index cce707cc..45287f9e 100644 --- a/core/src/main/java/org/geysermc/floodgate/command/WhitelistCommand.java +++ b/core/src/main/java/org/geysermc/floodgate/command/WhitelistCommand.java @@ -44,7 +44,7 @@ import org.geysermc.floodgate.config.ProxyFloodgateConfig; import org.geysermc.floodgate.platform.command.CommandUtil; import org.geysermc.floodgate.platform.command.FloodgateCommand; import org.geysermc.floodgate.platform.command.TranslatableMessage; -import org.geysermc.floodgate.platform.util.PlatformUtils.PlayerType; +import org.geysermc.floodgate.platform.util.PlayerType; import org.geysermc.floodgate.player.UserAudience; import org.geysermc.floodgate.player.audience.ProfileAudience; import org.geysermc.floodgate.player.audience.ProfileAudienceArgument; diff --git a/core/src/main/java/org/geysermc/floodgate/config/loader/ConfigLoader.java b/core/src/main/java/org/geysermc/floodgate/config/ConfigLoader.java similarity index 97% rename from core/src/main/java/org/geysermc/floodgate/config/loader/ConfigLoader.java rename to core/src/main/java/org/geysermc/floodgate/config/ConfigLoader.java index b261e63f..43cbfb3e 100644 --- a/core/src/main/java/org/geysermc/floodgate/config/loader/ConfigLoader.java +++ b/core/src/main/java/org/geysermc/floodgate/config/ConfigLoader.java @@ -23,7 +23,7 @@ * @link https://github.com/GeyserMC/Floodgate */ -package org.geysermc.floodgate.config.loader; +package org.geysermc.floodgate.config; import java.nio.file.Files; import java.nio.file.Path; @@ -36,8 +36,6 @@ import org.geysermc.configutils.file.codec.PathFileCodec; import org.geysermc.configutils.file.template.ResourceTemplateReader; import org.geysermc.configutils.updater.change.Changes; import org.geysermc.floodgate.api.logger.FloodgateLogger; -import org.geysermc.floodgate.config.FloodgateConfig; -import org.geysermc.floodgate.config.ProxyFloodgateConfig; import org.geysermc.floodgate.crypto.FloodgateCipher; import org.geysermc.floodgate.crypto.KeyProducer; diff --git a/core/src/main/java/org/geysermc/floodgate/config/FloodgateConfig.java b/core/src/main/java/org/geysermc/floodgate/config/FloodgateConfig.java index 9fb105d8..167c40f6 100644 --- a/core/src/main/java/org/geysermc/floodgate/config/FloodgateConfig.java +++ b/core/src/main/java/org/geysermc/floodgate/config/FloodgateConfig.java @@ -29,11 +29,9 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.security.Key; -import java.util.UUID; import lombok.Getter; import org.geysermc.configutils.loader.callback.CallbackResult; import org.geysermc.configutils.loader.callback.GenericPostInitializeCallback; -import org.geysermc.floodgate.config.loader.ConfigLoader; /** * The global Floodgate configuration file used in every platform. Some platforms have their own @@ -99,6 +97,6 @@ public class FloodgateConfig implements GenericPostInitializeCallback getOnlineUsernames(PlayerType limitTo); - - enum PlayerType { - ALL_PLAYERS, - ONLY_BEDROCK, - ONLY_JAVA + public enum AuthType { + ONLINE, + PROXIED, + OFFLINE } } diff --git a/core/src/main/java/org/geysermc/floodgate/platform/util/PlayerType.java b/core/src/main/java/org/geysermc/floodgate/platform/util/PlayerType.java new file mode 100644 index 00000000..f8c0c97c --- /dev/null +++ b/core/src/main/java/org/geysermc/floodgate/platform/util/PlayerType.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Floodgate + */ + +package org.geysermc.floodgate.platform.util; + +public enum PlayerType { + ALL_PLAYERS, + ONLY_BEDROCK, + ONLY_JAVA +} diff --git a/core/src/main/java/org/geysermc/floodgate/player/audience/ProfileAudienceArgument.java b/core/src/main/java/org/geysermc/floodgate/player/audience/ProfileAudienceArgument.java index d9ed8e47..9c425637 100644 --- a/core/src/main/java/org/geysermc/floodgate/player/audience/ProfileAudienceArgument.java +++ b/core/src/main/java/org/geysermc/floodgate/player/audience/ProfileAudienceArgument.java @@ -37,7 +37,7 @@ import java.util.UUID; import lombok.RequiredArgsConstructor; import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.floodgate.platform.command.CommandUtil; -import org.geysermc.floodgate.platform.util.PlatformUtils.PlayerType; +import org.geysermc.floodgate.platform.util.PlayerType; import org.geysermc.floodgate.player.UserAudience; public class ProfileAudienceArgument extends CommandArgument { diff --git a/core/src/main/java/org/geysermc/floodgate/util/Constants.java b/core/src/main/java/org/geysermc/floodgate/util/Constants.java index 86fbc65b..5e97aba3 100644 --- a/core/src/main/java/org/geysermc/floodgate/util/Constants.java +++ b/core/src/main/java/org/geysermc/floodgate/util/Constants.java @@ -26,8 +26,10 @@ package org.geysermc.floodgate.util; public final class Constants { + public static final String VERSION = "${floodgateVersion}"; public static final int BUILD_NUMBER = Integer.parseInt("${buildNumber}"); public static final String GIT_BRANCH = "${branch}"; + public static final int METRICS_ID = 14649; public static final char COLOR_CHAR = 'ยง'; diff --git a/core/src/main/java/org/geysermc/floodgate/util/Metrics.java b/core/src/main/java/org/geysermc/floodgate/util/Metrics.java new file mode 100644 index 00000000..50ea1025 --- /dev/null +++ b/core/src/main/java/org/geysermc/floodgate/util/Metrics.java @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Floodgate + */ + +package org.geysermc.floodgate.util; + +import com.google.inject.Inject; +import java.util.Collections; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import javax.inject.Named; +import org.bstats.MetricsBase; +import org.bstats.charts.DrilldownPie; +import org.bstats.charts.SimplePie; +import org.bstats.charts.SingleLineChart; +import org.bstats.json.JsonObjectBuilder; +import org.geysermc.floodgate.api.FloodgateApi; +import org.geysermc.floodgate.api.logger.FloodgateLogger; +import org.geysermc.floodgate.config.FloodgateConfig; +import org.geysermc.floodgate.config.FloodgateConfig.MetricsConfig; +import org.geysermc.floodgate.platform.util.PlatformUtils; + +public final class Metrics { + private final MetricsBase metricsBase; + + @Inject + Metrics(FloodgateConfig config, PlatformUtils platformUtils, FloodgateApi api, + @Named("implementationName") String implementationName, FloodgateLogger logger) { + + MetricsConfig metricsConfig = config.getMetrics(); + + metricsBase = new MetricsBase( + "server-implementation", + metricsConfig.getUuid(), + Constants.METRICS_ID, + metricsConfig.isEnabled(), + this::appendPlatformData, + jsonObjectBuilder -> { /* NOP */ }, + null, + () -> true, // remove this if/when we add some form of reload support + logger::error, + logger::info, + Constants.DEBUG_MODE, + Constants.DEBUG_MODE, + Constants.DEBUG_MODE + ); + + metricsBase.addCustomChart( + new SingleLineChart("players", api::getPlayerCount) + ); + + metricsBase.addCustomChart( + new DrilldownPie("player_count", () -> { + int playerCount = api.getPlayerCount(); + // 0 = 0 - 4, 9 = 5 - 9, etc. + int category = playerCount / 5 * 5; + String categoryName = category + " - " + (category + 4); + + return Collections.singletonMap( + categoryName, + Collections.singletonMap(implementationName, 1) + ); + }) + ); + + metricsBase.addCustomChart( + new SimplePie("authentication", + () -> platformUtils.authType().name().toLowerCase(Locale.ROOT)) + ); + + metricsBase.addCustomChart( + new SimplePie("floodgate_version", () -> Constants.VERSION) + ); + + metricsBase.addCustomChart(new SimplePie("platform", () -> implementationName)); + + metricsBase.addCustomChart( + new DrilldownPie("minecraft_version", () -> { + // e.g.: 1.16.5 => (Spigot, 1) + return Collections.singletonMap( + platformUtils.minecraftVersion(), + Collections.singletonMap(implementationName, 1) + ); + }) + ); + + // Source: Geyser + metricsBase.addCustomChart(new DrilldownPie("java_version", () -> { + Map> map = new HashMap<>(); + String javaVersion = System.getProperty("java.version"); + Map entry = new HashMap<>(); + entry.put(javaVersion, 1); + + String majorVersion = javaVersion.split("\\.")[0]; + String release; + + int indexOf = javaVersion.lastIndexOf('.'); + + if (majorVersion.equals("1")) { + release = "Java " + javaVersion.substring(0, indexOf); + } else { + Matcher versionMatcher = Pattern.compile("\\d+").matcher(majorVersion); + if (versionMatcher.find()) { + majorVersion = versionMatcher.group(0); + } + release = "Java " + majorVersion; + } + map.put(release, entry); + return map; + })); + } + + private void appendPlatformData(JsonObjectBuilder builder) { + builder.appendField("osName", System.getProperty("os.name")); + builder.appendField("osArch", System.getProperty("os.arch")); + builder.appendField("osVersion", System.getProperty("os.version")); + builder.appendField("coreCount", Runtime.getRuntime().availableProcessors()); + } +} 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 94d8f12a..5547046b 100644 --- a/spigot/src/main/java/org/geysermc/floodgate/module/SpigotPlatformModule.java +++ b/spigot/src/main/java/org/geysermc/floodgate/module/SpigotPlatformModule.java @@ -42,6 +42,7 @@ import org.geysermc.floodgate.logger.JavaUtilFloodgateLogger; import org.geysermc.floodgate.platform.command.CommandUtil; import org.geysermc.floodgate.platform.listener.ListenerRegistration; import org.geysermc.floodgate.platform.pluginmessage.PluginMessageUtils; +import org.geysermc.floodgate.platform.util.PlatformUtils; import org.geysermc.floodgate.pluginmessage.PluginMessageRegistration; import org.geysermc.floodgate.pluginmessage.SpigotPluginMessageRegistration; import org.geysermc.floodgate.pluginmessage.SpigotPluginMessageUtils; @@ -49,12 +50,18 @@ import org.geysermc.floodgate.pluginmessage.SpigotSkinApplier; import org.geysermc.floodgate.skin.SkinApplier; import org.geysermc.floodgate.util.LanguageManager; import org.geysermc.floodgate.util.SpigotCommandUtil; +import org.geysermc.floodgate.util.SpigotPlatformUtils; import org.geysermc.floodgate.util.SpigotVersionSpecificMethods; @RequiredArgsConstructor public final class SpigotPlatformModule extends AbstractModule { private final SpigotPlugin plugin; + @Override + protected void configure() { + bind(PlatformUtils.class).to(SpigotPlatformUtils.class); + } + @Provides @Singleton public JavaPlugin javaPlugin() { diff --git a/spigot/src/main/java/org/geysermc/floodgate/util/ClassNames.java b/spigot/src/main/java/org/geysermc/floodgate/util/ClassNames.java index 60d38a38..02d93c86 100644 --- a/spigot/src/main/java/org/geysermc/floodgate/util/ClassNames.java +++ b/spigot/src/main/java/org/geysermc/floodgate/util/ClassNames.java @@ -58,6 +58,7 @@ public class ClassNames { public static final Field HANDSHAKE_HOST; public static final Field LOGIN_PROFILE; public static final Field PACKET_LISTENER; + @Nullable public static final Field PAPER_DISABLE_USERNAME_VALIDATION; @@ -67,6 +68,10 @@ public class ClassNames { public static final Method INIT_UUID; public static final Method FIRE_LOGIN_EVENTS; + public static final Class SPIGOT_CONFIG; + public static final Field BUNGEE; + public static final Method GET_VERSION; + static { String version = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3]; SPIGOT_MAPPING_PREFIX = "net.minecraft.server." + version; @@ -162,12 +167,24 @@ public class ClassNames { FIRE_LOGIN_EVENTS = getMethod(LOGIN_HANDLER, "fireEvents"); checkNotNull(FIRE_LOGIN_EVENTS, "fireEvents from LoginHandler"); + PAPER_DISABLE_USERNAME_VALIDATION = getField(LOGIN_LISTENER, "iKnowThisMayNotBeTheBestIdeaButPleaseDisableUsernameValidation"); + if (Constants.DEBUG_MODE) { System.out.println("Paper disable username validation field exists? " + (PAPER_DISABLE_USERNAME_VALIDATION != null)); } + + // SpigotPlatformUtils + SPIGOT_CONFIG = ReflectionUtils.getClass("org.spigotmc.SpigotConfig"); + checkNotNull(SPIGOT_CONFIG, "Spigot config"); + + BUNGEE = ReflectionUtils.getField(SPIGOT_CONFIG, "bungee"); + checkNotNull(BUNGEE, "Bungee field"); + + GET_VERSION = ReflectionUtils.getMethod(MINECRAFT_SERVER, "getVersion"); + checkNotNull(GET_VERSION, "Minecraft server version"); } private static Class getClassOrFallBack(String className, String fallbackName) { diff --git a/spigot/src/main/java/org/geysermc/floodgate/util/SpigotPlatformUtils.java b/spigot/src/main/java/org/geysermc/floodgate/util/SpigotPlatformUtils.java new file mode 100644 index 00000000..052334cc --- /dev/null +++ b/spigot/src/main/java/org/geysermc/floodgate/util/SpigotPlatformUtils.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Floodgate + */ + +package org.geysermc.floodgate.util; + +import org.bukkit.Bukkit; +import org.geysermc.floodgate.platform.util.PlatformUtils; + +public class SpigotPlatformUtils extends PlatformUtils { + @Override + @SuppressWarnings("ConstantConditions") + public AuthType authType() { + if (Bukkit.getOnlineMode()) { + return AuthType.ONLINE; + } + + boolean bungeeEnabled = ReflectionUtils.getCastedValue(null, ClassNames.BUNGEE); + return bungeeEnabled ? AuthType.PROXIED : AuthType.OFFLINE; + } + + @Override + public String minecraftVersion() { + Object instance = ReflectionUtils.invokeStatic(ClassNames.MINECRAFT_SERVER, "getServer"); + return ReflectionUtils.castedInvoke(instance, ClassNames.GET_VERSION); + } +} diff --git a/velocity/build.gradle.kts b/velocity/build.gradle.kts index 5fa61663..2ddcfae5 100644 --- a/velocity/build.gradle.kts +++ b/velocity/build.gradle.kts @@ -5,7 +5,7 @@ var guavaVersion = "25.1-jre" dependencies { api(projects.core) - api("cloud.commandframework", "cloud-velocity", Versions.cloudVersion) + implementation("cloud.commandframework", "cloud-velocity", Versions.cloudVersion) } relocate("cloud.commandframework") 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 209c07c6..8678af5e 100644 --- a/velocity/src/main/java/org/geysermc/floodgate/module/VelocityPlatformModule.java +++ b/velocity/src/main/java/org/geysermc/floodgate/module/VelocityPlatformModule.java @@ -48,6 +48,7 @@ import org.geysermc.floodgate.logger.Slf4jFloodgateLogger; import org.geysermc.floodgate.platform.command.CommandUtil; import org.geysermc.floodgate.platform.listener.ListenerRegistration; import org.geysermc.floodgate.platform.pluginmessage.PluginMessageUtils; +import org.geysermc.floodgate.platform.util.PlatformUtils; import org.geysermc.floodgate.player.FloodgateCommandPreprocessor; import org.geysermc.floodgate.player.UserAudience; import org.geysermc.floodgate.pluginmessage.PluginMessageManager; @@ -57,6 +58,7 @@ import org.geysermc.floodgate.pluginmessage.VelocityPluginMessageUtils; import org.geysermc.floodgate.skin.SkinApplier; import org.geysermc.floodgate.util.LanguageManager; import org.geysermc.floodgate.util.VelocityCommandUtil; +import org.geysermc.floodgate.util.VelocityPlatformUtils; import org.geysermc.floodgate.util.VelocitySkinApplier; import org.slf4j.Logger; @@ -67,6 +69,7 @@ public final class VelocityPlatformModule extends AbstractModule { @Override protected void configure() { bind(CommandUtil.class).to(VelocityCommandUtil.class); + bind(PlatformUtils.class).to(VelocityPlatformUtils.class); } @Provides diff --git a/velocity/src/main/java/org/geysermc/floodgate/util/VelocityPlatformUtils.java b/velocity/src/main/java/org/geysermc/floodgate/util/VelocityPlatformUtils.java new file mode 100644 index 00000000..4abafe61 --- /dev/null +++ b/velocity/src/main/java/org/geysermc/floodgate/util/VelocityPlatformUtils.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Floodgate + */ + +package org.geysermc.floodgate.util; + +import com.google.inject.Inject; +import com.velocitypowered.api.network.ProtocolVersion; +import com.velocitypowered.api.proxy.ProxyServer; +import org.geysermc.floodgate.platform.util.PlatformUtils; + +public final class VelocityPlatformUtils extends PlatformUtils { + @Inject + private ProxyServer server; + + @Override + public AuthType authType() { + return server.getConfiguration().isOnlineMode() ? AuthType.ONLINE : AuthType.OFFLINE; + } + + @Override + public String minecraftVersion() { + return ProtocolVersion.MAXIMUM_VERSION.getMostRecentSupportedVersion(); + } +}