From c243adf6aa41c84a20ff096c5a6a04d7c447ca2f Mon Sep 17 00:00:00 2001 From: LexManos Date: Mon, 12 Feb 2024 13:46:29 -0800 Subject: [PATCH] Fix DNS SRV record lookup not working by hacking the module system. Closes #9846 --- .../net/minecraftforge/common/ForgeMod.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/main/java/net/minecraftforge/common/ForgeMod.java b/src/main/java/net/minecraftforge/common/ForgeMod.java index 97e7e0fa0c..b3d44c9531 100644 --- a/src/main/java/net/minecraftforge/common/ForgeMod.java +++ b/src/main/java/net/minecraftforge/common/ForgeMod.java @@ -81,6 +81,7 @@ import net.minecraftforge.server.command.ModIdArgument; import net.minecraftforge.server.permission.events.PermissionGatherEvent; import net.minecraftforge.server.permission.nodes.PermissionNode; import net.minecraftforge.server.permission.nodes.PermissionTypes; +import net.minecraftforge.unsafe.UnsafeHacks; import net.minecraftforge.versions.forge.ForgeVersion; import net.minecraftforge.versions.mcp.MCPVersion; @@ -117,6 +118,7 @@ import org.apache.logging.log4j.MarkerManager; import com.mojang.serialization.Codec; import org.jetbrains.annotations.Nullable; +import java.lang.reflect.Method; import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.function.Consumer; @@ -397,6 +399,8 @@ public class ForgeMod { return uuid.toString(); }); + hackDNSResolver(); + NetworkInitialization.init(); CrashReportCallables.registerCrashCallable("FML", ForgeVersion::getSpec); @@ -558,4 +562,27 @@ public class ForgeMod { ForgeRegistry fReg = (ForgeRegistry) registry; fReg.addAlias(from, to); } + + // net.minecraft.client.multiplayer.resolver.ServerRedirectHandler.createDnsSrvRedirectHandler uses DNSContextFactory + // to resolve DNS records, and that is initialized reflectively by NamingManager. Which in module land isn't allowed. + // So hack it so it is. this is equivalent to doing --add-exports jdk.naming.dns/com.sun.jndi.dns=java.naming + private void hackDNSResolver() { + try { + var target = Class.forName("com.sun.jndi.dns.DnsContextFactory"); + var reader = Class.forName("javax.naming.spi.NamingManager"); + addOpen(target, reader); + } catch (Exception e) { + LOGGER.error(FORGEMOD, "Failed to hack DnsContextFactory, some servers might not work", e); + } + } + + private static Method implAddExportsOrOpens; + private static void addOpen(Class target, Class reader) throws Exception { + if (implAddExportsOrOpens == null) { + implAddExportsOrOpens = Module.class.getDeclaredMethod("implAddExportsOrOpens", String.class, Module.class, boolean.class, boolean.class); + UnsafeHacks.setAccessible(implAddExportsOrOpens); + } + LOGGER.info(FORGEMOD, "Opening {}/{} to {}", target.getModule().getName(), target.getPackageName(), reader.getModule().getName()); + implAddExportsOrOpens.invoke(target.getModule(), target.getPackageName(), reader.getModule(), /*open*/true, /*syncVM*/true); + } }