Skip to content

Commit 76d460c

Browse files
committed
Add FG2 hacks to discover coremods and accress transformers from dependencies
1 parent 48f83aa commit 76d460c

4 files changed

Lines changed: 176 additions & 2 deletions

File tree

settings.gradle

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ dependencyResolutionManagement.versionCatalogs.register('libs') {
2828

2929
library 'gson', 'com.google.code.gson', 'gson' version '2.11.0'
3030
library 'jopt', 'net.sf.jopt-simple', 'jopt-simple' version '6.0-alpha-3'
31-
library 'srgutils', 'net.minecraftforge', 'srgutils' version '0.6.5'
3231

3332
library 'srgutils', 'net.minecraftforge', 'srgutils' version '0.6.5'
3433

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
/*
2+
* A Gradle plugin for the creation of Minecraft mods and MinecraftForge plugins.
3+
* Copyright (C) 2013-2019 Minecraft Forge
4+
*
5+
* This library is free software; you can redistribute it and/or
6+
* modify it under the terms of the GNU Lesser General Public
7+
* License as published by the Free Software Foundation; either
8+
* version 2.1 of the License, or (at your option) any later version.
9+
*
10+
* This library is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
* Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public
16+
* License along with this library; if not, write to the Free Software
17+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
18+
* USA
19+
*/
20+
21+
package net.minecraftforge.launcher;
22+
23+
import java.io.File;
24+
import java.io.FileInputStream;
25+
import java.io.IOException;
26+
import java.lang.reflect.InvocationTargetException;
27+
import java.lang.reflect.Method;
28+
import java.net.URISyntaxException;
29+
import java.net.URL;
30+
import java.net.URLClassLoader;
31+
import java.util.Arrays;
32+
import java.util.HashMap;
33+
import java.util.HashSet;
34+
import java.util.Map;
35+
import java.util.Set;
36+
import java.util.jar.Attributes;
37+
import java.util.jar.JarFile;
38+
import java.util.jar.Manifest;
39+
40+
import net.minecraftforge.srgutils.MinecraftVersion;
41+
42+
import org.jetbrains.annotations.Nullable;
43+
44+
class FG2Hacks {
45+
/* ----------- COREMOD AND AT HACK --------- */
46+
// coremod hack
47+
private static final String COREMOD_VAR = "fml.coreMods.load";
48+
private static final String COREMOD_MF = "FMLCorePlugin";
49+
// AT hack
50+
private static final String MOD_ATD_CLASS = "net.minecraftforge.fml.common.asm.transformers.ModAccessTransformer";
51+
private static final String MOD_AT_METHOD = "addJar";
52+
53+
private static final MinecraftVersion FG2_START = MinecraftVersion.from("1.8");
54+
private static final MinecraftVersion FG2_END = MinecraftVersion.from("1.12.2");
55+
private static @Nullable MinecraftVersion mcVer(String ver) {
56+
try {
57+
return MinecraftVersion.from(ver);
58+
} catch (IllegalArgumentException e) {
59+
return null;
60+
}
61+
}
62+
63+
static void searchCoremods(String mcVersion) {
64+
MinecraftVersion currentMC = mcVer(mcVersion);
65+
// Check if we're on a known version, between 1.8 and 1.12.2
66+
if (currentMC == null || currentMC.compareTo(FG2_START) < 0 || currentMC.compareTo(FG2_END) > 0)
67+
return;
68+
69+
// initialize AT hack Method
70+
AtRegistrar atRegistrar = new AtRegistrar();
71+
72+
Map<String, File> coreMap = new HashMap<>();
73+
// We're on a legacy Minecraft Version, which means we should be running Java 8, which means the system classloader should be URLClassLoader
74+
URLClassLoader urlClassLoader = (URLClassLoader)FG2Hacks.class.getClassLoader();
75+
// Fine any coremods from the classpath
76+
for (URL url : urlClassLoader.getURLs()) {
77+
try {
78+
searchCoremodAtUrl(url, atRegistrar, coreMap);
79+
} catch (IOException | InvocationTargetException | IllegalAccessException | URISyntaxException e) {
80+
Main.LOGGER.warn("FG2Hacks failed to search for coremod at url " + url, e);
81+
}
82+
}
83+
84+
// Set The env to anything we've found from the classpath
85+
Set<String> coremodsSet = new HashSet<>();
86+
String coremodEnv = System.getProperty(COREMOD_VAR);
87+
if (coremodEnv != null && !coremodEnv.isEmpty())
88+
coremodsSet.addAll(Arrays.asList(coremodEnv.split(",")));
89+
coremodsSet.addAll(coreMap.keySet());
90+
System.setProperty(COREMOD_VAR, String.join(",", coremodsSet));
91+
92+
/*
93+
// ok.. tweaker hack now.
94+
if (!Strings.isNullOrEmpty(common.getTweakClass())) {
95+
common.extras.add("--tweakClass");
96+
common.extras.add("net.minecraftforge.gradle.tweakers.CoremodTweaker");
97+
}
98+
*/
99+
}
100+
101+
private static void searchCoremodAtUrl(URL url, AtRegistrar atRegistrar, Map<String, File> coreMods) throws IOException, InvocationTargetException, IllegalAccessException, URISyntaxException {
102+
if (!url.getProtocol().startsWith("file")) // because file urls start with file://
103+
return;
104+
105+
File coreMod = new File(url.toURI().getPath());
106+
if (!coreMod.exists())
107+
return;
108+
109+
Manifest manifest = null;
110+
if (coreMod.isDirectory()) {
111+
File manifestMF = new File(coreMod, "META-INF/MANIFEST.MF");
112+
if (manifestMF.exists()) {
113+
FileInputStream stream = new FileInputStream(manifestMF);
114+
manifest = new Manifest(stream);
115+
stream.close();
116+
}
117+
} else if (coreMod.getName().endsWith("jar")) {
118+
try (JarFile jar = new JarFile(coreMod)) {
119+
manifest = jar.getManifest();
120+
if (manifest != null)
121+
atRegistrar.addJar(jar, manifest);
122+
}
123+
}
124+
125+
// we got the manifest? use it.
126+
if (manifest != null) {
127+
String clazz = manifest.getMainAttributes().getValue(COREMOD_MF);
128+
if (clazz != null && !clazz.isEmpty()) {
129+
Main.LOGGER.info("Found and added coremod: " + clazz);
130+
coreMods.put(clazz, coreMod);
131+
}
132+
}
133+
}
134+
135+
/**
136+
* Hack to register jar ATs with Minecraft Forge
137+
*/
138+
private static final class AtRegistrar {
139+
private static final Attributes.Name FMLAT = new Attributes.Name("FMLAT");
140+
@Nullable
141+
private Method newMethod = null;
142+
@Nullable
143+
private Method oldMethod = null;
144+
145+
private AtRegistrar() {
146+
try {
147+
Class<?> modAtdClass = Class.forName(MOD_ATD_CLASS);
148+
try {
149+
newMethod = modAtdClass.getDeclaredMethod(MOD_AT_METHOD, JarFile.class, String.class);
150+
} catch (NoSuchMethodException | SecurityException ignored) {
151+
try {
152+
oldMethod = modAtdClass.getDeclaredMethod(MOD_AT_METHOD, JarFile.class);
153+
} catch (NoSuchMethodException | SecurityException ignored2) {
154+
Main.LOGGER.error("Failed to find method " + MOD_ATD_CLASS + '.' + MOD_AT_METHOD);
155+
}
156+
}
157+
} catch (ClassNotFoundException e) {
158+
Main.LOGGER.error("Failed to find class " + MOD_ATD_CLASS);
159+
}
160+
}
161+
162+
public void addJar(JarFile jarFile, Manifest manifest) throws InvocationTargetException, IllegalAccessException {
163+
if (newMethod != null) {
164+
String ats = manifest.getMainAttributes().getValue(FMLAT);
165+
if (ats != null && !ats.isEmpty())
166+
newMethod.invoke(null, jarFile, ats);
167+
} else if (oldMethod != null) {
168+
oldMethod.invoke(null, jarFile);
169+
}
170+
}
171+
}
172+
}

src/main/java/net/minecraftforge/launcher/LegacyDev.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
import java.io.InputStream;
1818
import java.lang.reflect.Field;
1919
import java.util.ArrayList;
20-
import java.util.Collections;
2120
import java.util.Enumeration;
2221
import java.util.HashMap;
2322
import java.util.List;

src/main/java/net/minecraftforge/launcher/Main.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
public final class Main {
3333
static final Logger LOGGER = Logger.create();
3434
private static final boolean DISABLE_ASSETS = Boolean.getBoolean("net.minecraftforge.launcher.skip.assets");
35+
private static final boolean DISABLE_COREMOD_SEARCH = Boolean.getBoolean("net.minecraftforge.launcher.skip.coremod.search");
3536

3637
public static void main(String[] args) throws Throwable {
3738
long start = System.currentTimeMillis();
@@ -168,6 +169,9 @@ private static Launcher run(String[] rawArgs) throws Throwable {
168169
//System.setProperty("net.minecraftforge.gradle.GradleStart.csvDir", CSV_DIR.getCanonicalPath());
169170
}
170171

172+
if (!DISABLE_COREMOD_SEARCH)
173+
FG2Hacks.searchCoremods(versionJson.id);
174+
171175
LOGGER.info("Looking for main class: " + mainClass);
172176
Class<?> main = findMainClass(mainClass);
173177
MethodHandle mainMethod = findMainMethod(main);

0 commit comments

Comments
 (0)