From a60d90b6fd636a6ffd1c2ca266c6c3d5330a6593 Mon Sep 17 00:00:00 2001 From: Essential CI Date: Mon, 19 Aug 2024 05:41:50 +0000 Subject: [PATCH] Version 1.3.4 --- api/build.gradle.kts | 10 +--- .../src/main/kotlin/essential/universal.kt | 10 +--- .../gg/essential/gradle/BundlePlugin.kt | 2 +- changelog/release-1.3.4.md | 9 ++++ features.properties | 2 +- gradle.properties | 2 +- gradle/libs.versions.toml | 9 ++-- loader | 2 +- .../config/FeatureFlagAbUserIdProvider.java | 24 --------- .../Mixin_RedirectToLocalConnection.java | 10 ---- .../connectionmanager/ConnectionManager.java | 10 +--- .../resources/assets/essential/commit.txt | 2 +- .../util/classloader/IsolatedClassLoader.java | 19 +++++++ .../gg/essential/config/FeatureFlags.java | 52 ------------------- .../quic/backend/QuicBackendLoader.java | 6 +++ 15 files changed, 50 insertions(+), 119 deletions(-) create mode 100644 changelog/release-1.3.4.md delete mode 100644 src/main/java/gg/essential/config/FeatureFlagAbUserIdProvider.java diff --git a/api/build.gradle.kts b/api/build.gradle.kts index 8ce7084..0f84ae1 100644 --- a/api/build.gradle.kts +++ b/api/build.gradle.kts @@ -57,19 +57,13 @@ dependencies { // Core Gui Libraries val ucMcVersion = when (platform.mcVersion) { - 11900, 11902, 11903, 11904, 12000, 12001, 12002, 12004, 12006, 12100 -> mcVersionStr.also { - // Elementa and Vigilance 1.18.1 are good enough for MC 1.19 so we only update UC. - // We do need to exclude the tranitive 1.18 UC though. - configurations.modApi.configure { exclude("gg.essential", "universalcraft-1.18.1-${platform.loaderStr}") } - } 11802 -> "1.18.1" else -> mcVersionStr } - val libMcVersion = if (platform.mcVersion >= 11802) "1.18.1" else mcVersionStr // These versions are configured in gradle/libs.versions.toml - modApi("gg.essential:vigilance-${libMcVersion}-${mcPlatform}:${libs.versions.vigilance.get()}") { exclude(group = "org.jetbrains.kotlin") } modApi("gg.essential:universalcraft-${ucMcVersion}-${mcPlatform}:${libs.versions.universalcraft.get()}") { exclude(group = "org.jetbrains.kotlin") } - modApi("gg.essential:elementa-${libMcVersion}-${mcPlatform}:${libs.versions.elementa.get()}") { exclude(group = "org.jetbrains.kotlin") } + modApi(libs.elementa) + modApi(libs.vigilance) // Miscellaneous Utility Libraries api("com.github.videogame-hacker:Koffee:88ba1b0") { diff --git a/build-logic/src/main/kotlin/essential/universal.kt b/build-logic/src/main/kotlin/essential/universal.kt index 0dba20e..27a4329 100644 --- a/build-logic/src/main/kotlin/essential/universal.kt +++ b/build-logic/src/main/kotlin/essential/universal.kt @@ -66,17 +66,11 @@ fun Project.universalLibs() { compileOnly("commons-codec:commons-codec:1.9") compileOnly("org.apache.httpcomponents:httpclient:4.3.3") // TODO ideally switch to one of the libs we bundle // These versions are configured in gradle/libs.versions.toml - compileOnly("gg.essential:vigilance-1.8.9-forge:${getVersion("vigilance")}") { - attributes { attribute(universalAttr, true) } - isTransitive = false - } compileOnly("gg.essential:universalcraft-1.8.9-forge:${getVersion("universalcraft")}") { attributes { attribute(universalAttr, true) } isTransitive = false } - compileOnly("gg.essential:elementa-1.8.9-forge:${getVersion("elementa")}") { - attributes { attribute(universalAttr, true) } - isTransitive = false - } + compileOnly(catalog.findLibrary("elementa").orElseThrow()) + compileOnly(catalog.findLibrary("vigilance").orElseThrow()) } } diff --git a/build-logic/src/main/kotlin/gg/essential/gradle/BundlePlugin.kt b/build-logic/src/main/kotlin/gg/essential/gradle/BundlePlugin.kt index ac35465..4e015df 100644 --- a/build-logic/src/main/kotlin/gg/essential/gradle/BundlePlugin.kt +++ b/build-logic/src/main/kotlin/gg/essential/gradle/BundlePlugin.kt @@ -169,7 +169,7 @@ private fun Project.configureForFabricLoader(configurations: Configurations, pla .map { it.moduleVersion.id } .forEach { // exclude them from the bundled configuration - bundle.exclude(module = it.name) // name-only so we get the remapped one as well + bundle.exclude(group = it.group, module = it.name) // and instead add them to loom's include configuration dependencies { include(group = it.group, name = it.name, version = it.version) diff --git a/changelog/release-1.3.4.md b/changelog/release-1.3.4.md new file mode 100644 index 0000000..1520262 --- /dev/null +++ b/changelog/release-1.3.4.md @@ -0,0 +1,9 @@ +Title: World Hosting Stability Update +Summary: Improved World Hosting stability and performance + +## World Hosting +- Improved time it takes to connect +- Fixed various "ICE failed" and other timeout on connect issues + +## Bug Fixes +- Added support for Fabric Loader 0.16.1 and above diff --git a/features.properties b/features.properties index f640f6c..7586cdb 100644 --- a/features.properties +++ b/features.properties @@ -1,4 +1,4 @@ always=true -new_ice_backend=0 +new_ice_backend=true updated_gifting_modal=true updated_coins_purchase_modal=true diff --git a/gradle.properties b/gradle.properties index 4821d67..26478a0 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,4 +7,4 @@ org.gradle.configureondemand=true org.gradle.parallel.threads=128 org.gradle.jvmargs=-Xmx16G minecraftVersion=11202 -version=1.3.3.2 +version=1.3.4 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index fcc5b8c..baf8a20 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,10 +1,13 @@ [versions] -universalcraft = "342" -elementa = "657" -vigilance = "297" +universalcraft = "362" +elementa = "665" +vigilance = "306" mixinextras = "0.3.5" [libraries] +universalcraft-standalone = { module = "gg.essential:universalcraft-standalone", version.ref = "universalcraft" } +elementa = { module = "gg.essential:elementa", version.ref = "elementa" } +vigilance = { module = "gg.essential:vigilance", version.ref = "vigilance" } # This is the version shipped by MC 1.19.3, the oldest version on which we used the builtin slf4j. # Do not change this unless you also change on which MC versions we use our relocated slf4j. # Also note that `SELF4JServiceProviderImpl.getRequestedApiVersion` may need to be updated when this is changed. diff --git a/loader b/loader index f1423fd..853e076 160000 --- a/loader +++ b/loader @@ -1 +1 @@ -Subproject commit f1423fd87b591529bb3c6b24521e646d934ab98b +Subproject commit 853e076980e6701897f8fb98a34ed480a6a7b7a8 diff --git a/src/main/java/gg/essential/config/FeatureFlagAbUserIdProvider.java b/src/main/java/gg/essential/config/FeatureFlagAbUserIdProvider.java deleted file mode 100644 index 7887429..0000000 --- a/src/main/java/gg/essential/config/FeatureFlagAbUserIdProvider.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2024 ModCore Inc. All rights reserved. - * - * This code is part of ModCore Inc.'s Essential Mod repository and is protected - * under copyright registration # TX0009138511. For the full license, see: - * https://github.com/EssentialGG/Essential/blob/main/LICENSE - * - * You may not use, copy, reproduce, modify, sell, license, distribute, - * commercialize, or otherwise exploit, or create derivative works based - * upon, this file or any other in this repository, all of which is reserved by Essential. - */ -package gg.essential.config; - -import gg.essential.universal.wrappers.UPlayer; - -import java.util.function.Supplier; - -@AccessedViaReflection("FeatureFlags.abTesting") -public class FeatureFlagAbUserIdProvider implements Supplier { - @Override - public String get() { - return UPlayer.getUUID().toString(); - } -} diff --git a/src/main/java/gg/essential/mixins/transformers/client/network/Mixin_RedirectToLocalConnection.java b/src/main/java/gg/essential/mixins/transformers/client/network/Mixin_RedirectToLocalConnection.java index 6e8df61..091f7ca 100644 --- a/src/main/java/gg/essential/mixins/transformers/client/network/Mixin_RedirectToLocalConnection.java +++ b/src/main/java/gg/essential/mixins/transformers/client/network/Mixin_RedirectToLocalConnection.java @@ -12,7 +12,6 @@ package gg.essential.mixins.transformers.client.network; import gg.essential.Essential; -import gg.essential.config.FeatureFlags; import gg.essential.network.connectionmanager.ice.IIceManager; import gg.essential.network.pingproxy.ProxyPingServer; import gg.essential.network.pingproxy.ProxyPingServerKt; @@ -89,15 +88,6 @@ private static ChannelFuture injectLocalChannel(Bootstrap bootstrap, InetAddress if (user != null) { // ICE connection IIceManager iceManager = Essential.getInstance().getConnectionManager().getIceManager(); - boolean asyncSafe = - //#if FORGE && MC>=11400 - //$$ FeatureFlags.NEW_ICE_BACKEND_ENABLED; - //#else - true; - //#endif - if (!asyncSafe) { - return bootstrap.connect(iceManager.createClientAgent(user)); - } Channel channel = bootstrap.register().syncUninterruptibly().channel(); ChannelPromise connectPromise = channel.newPromise(); Dispatchers.getIO().dispatch(EmptyCoroutineContext.INSTANCE, () -> { diff --git a/src/main/java/gg/essential/network/connectionmanager/ConnectionManager.java b/src/main/java/gg/essential/network/connectionmanager/ConnectionManager.java index b6f258d..aae3d78 100644 --- a/src/main/java/gg/essential/network/connectionmanager/ConnectionManager.java +++ b/src/main/java/gg/essential/network/connectionmanager/ConnectionManager.java @@ -11,7 +11,6 @@ */ package gg.essential.network.connectionmanager; -import gg.essential.config.FeatureFlags; import gg.essential.connectionmanager.common.packet.Packet; import gg.essential.connectionmanager.common.packet.connection.*; import gg.essential.connectionmanager.common.packet.multiplayer.ServerMultiplayerJoinServerPacket; @@ -29,7 +28,6 @@ import gg.essential.network.connectionmanager.handler.mojang.ServerUuidNameMapPacketHandler; import gg.essential.network.connectionmanager.handler.multiplayer.ServerMultiplayerJoinServerPacketHandler; import gg.essential.network.connectionmanager.ice.IIceManager; -import gg.essential.network.connectionmanager.ice.IceManager; import gg.essential.network.connectionmanager.ice.IceManagerMcImpl; import gg.essential.network.connectionmanager.media.ScreenshotManager; import gg.essential.network.connectionmanager.notices.NoticesManager; @@ -162,13 +160,7 @@ public ConnectionManager(@NotNull final MinecraftHook minecraftHook, File baseDi this.managers.add(this.socialManager = new SocialManager(this)); // Ice - if (FeatureFlags.NEW_ICE_BACKEND_ENABLED) { - this.iceManager = new IceManagerMcImpl(this, baseDir.toPath(), uuid -> this.spsManager.getInvitedUsers().contains(uuid)); - } else { - IceManager iceManagerImpl = new IceManager(this, this.spsManager); - this.managers.add(iceManagerImpl); - this.iceManager = iceManagerImpl; - } + this.iceManager = new IceManagerMcImpl(this, baseDir.toPath(), uuid -> this.spsManager.getInvitedUsers().contains(uuid)); //Screenshots this.managers.add(this.screenshotManager = new ScreenshotManager(this, baseDir, lwjgl3)); diff --git a/src/main/resources/assets/essential/commit.txt b/src/main/resources/assets/essential/commit.txt index 0007024..96f6154 100644 --- a/src/main/resources/assets/essential/commit.txt +++ b/src/main/resources/assets/essential/commit.txt @@ -1 +1 @@ -5372d82914 \ No newline at end of file +ffe87e84d7 \ No newline at end of file diff --git a/subprojects/classloaders/src/main/java/gg/essential/util/classloader/IsolatedClassLoader.java b/subprojects/classloaders/src/main/java/gg/essential/util/classloader/IsolatedClassLoader.java index 0c864a7..2999199 100644 --- a/subprojects/classloaders/src/main/java/gg/essential/util/classloader/IsolatedClassLoader.java +++ b/subprojects/classloaders/src/main/java/gg/essential/util/classloader/IsolatedClassLoader.java @@ -24,6 +24,7 @@ import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Predicate; /** * A class loader which strongly prefers loading its own instance of a class rather than using the one from its parent. @@ -50,6 +51,8 @@ public class IsolatedClassLoader extends URLClassLoader { private final Map> classes = new ConcurrentHashMap<>(); + private Predicate resourceFilter; + /** * The conceptual (but not actual) parent of this class loader. *

@@ -73,6 +76,14 @@ public void addClassExclusion(String className) { this.classExclusions.add(className); } + /** + * Sets a resource filter. Resources that match this filter will exclusively be loaded + * from this classloader, and will not be delegated to the parent. + */ + public void setResourceFilter(Predicate resourceFilter) { + this.resourceFilter = resourceFilter; + } + @Override public Class loadClass(String name) throws ClassNotFoundException { // Fast path @@ -146,11 +157,19 @@ public URL getResource(String name) { return url; } + if (resourceFilter != null && resourceFilter.test(name)) { + return null; + } + return delegateParent.getResource(name); } @Override public Enumeration getResources(String name) throws IOException { + if (resourceFilter != null && resourceFilter.test(name)) { + return super.getResources(name); + } + return Iterators.asEnumeration(Iterators.concat( Iterators.forEnumeration(super.getResources(name)), Iterators.forEnumeration(delegateParent.getResources(name)) diff --git a/subprojects/feature-flags/src/main/java/gg/essential/config/FeatureFlags.java b/subprojects/feature-flags/src/main/java/gg/essential/config/FeatureFlags.java index b3b1648..2989c8f 100644 --- a/subprojects/feature-flags/src/main/java/gg/essential/config/FeatureFlags.java +++ b/subprojects/feature-flags/src/main/java/gg/essential/config/FeatureFlags.java @@ -15,14 +15,8 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import java.math.BigInteger; -import java.nio.charset.StandardCharsets; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; import java.util.HashMap; -import java.util.Locale; import java.util.Map; -import java.util.function.Supplier; /** * Various feature flags which control the behavior of Essential.
@@ -47,55 +41,9 @@ public class FeatureFlags { private static final Logger LOGGER = LogManager.getLogger("Essential Logger"); - // Dropping Ice4J in favor of less buggy homebrew ICE implementation - public static final String NEW_ICE_BACKEND = "NEW_ICE_BACKEND"; - public static final boolean NEW_ICE_BACKEND_ENABLED = property(NEW_ICE_BACKEND, abTesting(NEW_ICE_BACKEND, 0)); - // Add any features here that should be displayed in the FeaturesEnabledModal public static final Map> abTestingFlags = new HashMap<>(); - private static boolean property(String featureName, boolean defaultValue) { - boolean result = defaultValue; - String str = System.getProperty("essential.feature." + featureName.toLowerCase(Locale.ROOT)); - if (str != null) { - result = Boolean.parseBoolean(str); - LOGGER.warn("Explicitly {} feature flags \"{}\".", result ? "enabled" : "disabled", featureName); - } - return result; - } - - @SuppressWarnings("unused") // used at build time depending on configuration - private static boolean abTesting(String featureName, int enabledPercentage) { - // To decide which group this user belongs to, we combine their UUID with the feature name, hash it, treat the - // result as an integer and modulo it by 100, at which point we can directly compare it to the percentage. - // This allows us to get an effectively random choice (sha1 results are uniformly distributed) that's the same - // every time (as long as it's the same user) even if we add/remove or re-order the feature flags. - // Additionally, given the algorithm does not depend on the percentage, even when we change how many people are - // in each group, it does not flip for more people than strictly necessary. - Supplier userIdSupplier; - try { - Class cls = Class.forName("gg.essential.config.FeatureFlagAbUserIdProvider"); - //noinspection unchecked - userIdSupplier = (Supplier) cls.getConstructor().newInstance(); - } catch (ReflectiveOperationException e) { - throw new RuntimeException(e); - } - String userId = userIdSupplier.get(); - String combinedId = featureName + ":" + userId; - byte[] combinedHash; - try { - combinedHash = MessageDigest.getInstance("SHA-1").digest(combinedId.getBytes(StandardCharsets.UTF_8)); - } catch (NoSuchAlgorithmException var2) { - throw new RuntimeException(var2); - } - int userValue = new BigInteger(combinedHash).mod(BigInteger.valueOf(100)).intValue(); - boolean enabled = userValue < enabledPercentage; - if (enabled) { - LOGGER.info("Rolled a {}, enabling feature flag \"{}\".", userValue, featureName); - } - return enabled; - } - } diff --git a/subprojects/quic-connector/src/main/java/gg/essential/quic/backend/QuicBackendLoader.java b/subprojects/quic-connector/src/main/java/gg/essential/quic/backend/QuicBackendLoader.java index 97eeedd..869f74f 100644 --- a/subprojects/quic-connector/src/main/java/gg/essential/quic/backend/QuicBackendLoader.java +++ b/subprojects/quic-connector/src/main/java/gg/essential/quic/backend/QuicBackendLoader.java @@ -65,6 +65,12 @@ private static URL findExtractedBundleJar() { loader.addClassExclusion(QuicBackend.class.getName()); loader.addClassExclusion(QuicListener.class.getName()); + + // Netty's NativeLibraryLoader will throw an error if multiple resources for the same native are found on the + // classpath. This is the case with mods such as e4mc and Luna, which include netty-incubator-codec-quic + // without relocating it or loading it in an isolated classloader. We can fix this by only loading natives + // from our classloader, and not allowing delegation to the parent. + loader.setResourceFilter(name -> name.startsWith("META-INF/native/")); } public QuicBackend createImpl(Logger logger, QuicListener listener) {