[1.18.x] Make mixins work with JarJar (#9506)

Backport of #8900
Update ASM to 9.5
Update JarJar to 0.3.19
Update SecureJarHandler to 1.0.8
This commit is contained in:
SizableShrimp authored and GitHub committed 2023-05-18 03:52:41 -05:00
1 parent 547ce9cb7c
commit 519399f856
9 files changed
+174 -46

No files matched your search

+12 -8
View File
@@ -5,7 +5,7 @@ buildscript {
mavenCentral()
}
dependencies {
classpath 'net.minecraftforge.gradle:ForgeGradle:[5.1.39,)'
classpath 'net.minecraftforge.gradle:ForgeGradle:[5.1.39,5.2.0)'
}
}
@@ -59,23 +59,22 @@ ext {
COREMODS_VERSION = '5.0.1'
EVENTBUS_VERSION = '5.0.3'
MODLAUNCHER_VERSION = '9.1.3'
SECUREJARHANDLER_VERSION = '1.0.3'
SECUREJARHANDLER_VERSION = '1.0.8'
BOOTSTRAPLAUNCHER_VERSION = '1.0.0'
ASM_VERSION = '9.2'
ASM_VERSION = '9.5'
INSTALLER_VERSION = '2.1.+'
MIXIN_VERSION = '0.8.5'
JARJAR_VERSION = '0.3.0'
JARJAR_VERSION = '0.3.19'
GIT_INFO = gradleutils.gitInfo
VERSION = gradleutils.getFilteredMCTagOffsetBranchVersion(true, '[0-9]', MC_VERSION)
// FML_VERSION = gradleutils.getFilteredMCTagOffsetBranchVersion(true, 'FML', MC_VERSION)
FORGE_VERSION = VERSION.substring(MC_VERSION.length() + 1)
SPECIAL_SOURCE = 'net.md-5:SpecialSource:1.10.0'
BINPATCH_TOOL = 'net.minecraftforge:binarypatcher:1.0.12:fatjar'
INSTALLER_TOOLS = 'net.minecraftforge:installertools:1.3.0'
JAR_SPLITTER = 'net.minecraftforge:jarsplitter:1.1.4'
FART = 'net.minecraftforge:ForgeAutoRenamingTool:0.1.22:all'
FART = 'net.minecraftforge:ForgeAutoRenamingTool:0.1.25:all'
MIN_TAG_FOR_CHANGELOG = "39.0"
LAST_RB = GIT_INFO.tag.rsplit('.', 1)[1] as int >= 1 ? GIT_INFO.tag + '.0' : null
}
@@ -258,6 +257,7 @@ def sharedDeps = {
moduleonly "org.ow2.asm:asm-util:${ASM_VERSION}"
moduleonly "org.ow2.asm:asm-analysis:${ASM_VERSION}"
moduleonly "cpw.mods:bootstraplauncher:${BOOTSTRAPLAUNCHER_VERSION}"
moduleonly "net.minecraftforge:JarJarFileSystems:${JARJAR_VERSION}"
installer "cpw.mods:securejarhandler:${SECUREJARHANDLER_VERSION}"
installer "org.ow2.asm:asm:${ASM_VERSION}"
@@ -281,7 +281,8 @@ def sharedDeps = {
installer 'org.jline:jline-terminal:3.12.+' //Dep of TerminaalConsoleeAppender
installer "org.spongepowered:mixin:${MIXIN_VERSION}"
installer 'org.openjdk.nashorn:nashorn-core:15.3'
installer "net.minecraftforge:JarJar:${JARJAR_VERSION}"
installer "net.minecraftforge:JarJarSelector:${JARJAR_VERSION}"
installer "net.minecraftforge:JarJarMetadata:${JARJAR_VERSION}"
/*
installer 'org.lwjgl:lwjgl:3.2.2'
@@ -450,6 +451,7 @@ def sharedFmlonlyForge = { Project prj ->
run.jvmArgs '--add-modules', 'ALL-MODULE-PATH'
// Additions to these JVM module args should be mirrored to server_files/args.txt and other similar blocks in the buildscript
run.jvmArgs '--add-opens', 'java.base/java.util.jar=cpw.mods.securejarhandler'
run.jvmArgs '--add-opens', 'java.base/java.lang.invoke=cpw.mods.securejarhandler'
run.jvmArgs '--add-exports', 'java.base/sun.security.util=cpw.mods.securejarhandler'
run.jvmArgs '--add-exports', 'jdk.naming.dns/com.sun.jndi.dns=java.naming'
}
@@ -640,6 +642,7 @@ project(':fmlonly') {
'--add-modules', 'ALL-MODULE-PATH',
// Additions to these JVM module args should be mirrored to server_files/args.txt and other similar blocks in the buildscript
'--add-opens', 'java.base/java.util.jar=cpw.mods.securejarhandler',
'--add-opens', 'java.base/java.lang.invoke=cpw.mods.securejarhandler',
'--add-exports', 'java.base/sun.security.util=cpw.mods.securejarhandler',
'--add-exports', 'jdk.naming.dns/com.sun.jndi.dns=java.naming'
]
@@ -1200,7 +1203,7 @@ project(':forge') {
}
def baseForgeVersionProperty = project.objects.property(String)
baseForgeVersionProperty.set(project.provider { getLatestForgeVersion(MC_VERSION) }.map { MC_VERSION + '-' + it })
baseForgeVersionProperty.set(project.provider { TeamcityRequests.attemptFindBase(rootDir) ?: getLatestForgeVersion(MC_VERSION) })
baseForgeVersionProperty.finalizeValueOnRead()
def jarCompatibilityTaskSetup = { task ->
task.group = 'jar compatibility'
@@ -1277,6 +1280,7 @@ project(':forge') {
'--add-modules', 'ALL-MODULE-PATH',
// Additions to these JVM module args should be mirrored to server_files/args.txt and other similar blocks in the buildscript
'--add-opens', 'java.base/java.util.jar=cpw.mods.securejarhandler',
'--add-opens', 'java.base/java.lang.invoke=cpw.mods.securejarhandler',
'--add-exports', 'java.base/sun.security.util=cpw.mods.securejarhandler',
'--add-exports', 'jdk.naming.dns/com.sun.jndi.dns=java.naming'
]
+5 -4
View File
@@ -1,11 +1,12 @@
repositories {
maven { url = 'https://maven.minecraftforge.net/' }
mavenCentral()
mavenCentral()
}
dependencies {
implementation 'org.ow2.asm:asm:9.1'
implementation 'org.ow2.asm:asm-tree:9.1'
implementation 'net.minecraftforge:srgutils:0.4.+'
implementation 'org.ow2.asm:asm:9.5'
implementation 'org.ow2.asm:asm-tree:9.5'
implementation 'net.minecraftforge:srgutils:0.5.+'
implementation 'commons-io:commons-io:2.8.0'
implementation 'com.google.code.gson:gson:2.10'
implementation 'org.eclipse.jgit:org.eclipse.jgit:6.5.0.202303070854-r'
}
@@ -0,0 +1,74 @@
package net.minecraftforge.forge.tasks
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import groovy.transform.CompileStatic
import org.eclipse.jgit.api.Git
import javax.annotation.Nullable
import java.util.stream.Collectors
@CompileStatic
class TeamcityRequests {
public static final Gson GSON = new Gson()
@Nullable
static <T> T jsonRequest(TypeToken<T> clazz, String url) throws Exception {
final HttpURLConnection conn = (HttpURLConnection) URI.create(url).toURL().openConnection()
conn.setRequestProperty('Accept', 'application/json')
conn.setReadTimeout(5 * 1000)
conn.setConnectTimeout(5 * 1000)
conn.connect()
if (conn.responseCode !== 200) {
return null
}
try (final InputStream is = conn.getInputStream()) {
GSON.fromJson(new InputStreamReader(is), clazz.getType())
}
}
@Nullable
static Map<String, Build> buildsByCommit() throws IOException {
final Map<String, Build> builds = [:]
jsonRequest(new TypeToken<Builds>() {}, "https://teamcity.minecraftforge.net/guestAuth/app/rest/builds?fields=build:(revisions,number)&locator=buildType:(id:MinecraftForge_MinecraftForge_MinecraftForge_MinecraftForge__Build),count:300,status:SUCCESS")
?.build?.forEach {
it.revisions.revision.each { rev -> builds[rev.version] = it }
}
return builds
}
@Nullable
static String attemptFindBase(File gitPath) {
try (final git = Git.open(gitPath)) {
final Map<String, Build> buildByCommit = buildsByCommit()
for (final commit in git.log().setMaxCount(100).call()) {
// Find the first commit which was built on CI
final build = buildByCommit[commit.id.name]
if (build) {
return build.number
}
}
} catch (Exception ignored) {}
return null
}
static final class Builds {
public List<Build> build
}
static final class Build {
public String number
public Revisions revisions
}
static final class Revisions {
public int count
public List<Revision> revision
}
static final class Revision {
public String version
}
}
@@ -143,8 +143,9 @@ public class Util {
}
}
public static String getLatestForgeVersion(mcVersion) {
def json = new JsonSlurper().parseText(new URL("https://files.minecraftforge.net/net/minecraftforge/forge/promotions_slim.json").getText("UTF-8"))
return json.promos["$mcVersion-latest"]
static String getLatestForgeVersion(mcVersion) {
final json = new JsonSlurper().parseText(new URL('https://files.minecraftforge.net/net/minecraftforge/forge/promotions_slim.json').getText('UTF-8'))
final ver = json.promos["$mcVersion-latest"]
ver === null ? null : (mcVersion + '-' + ver)
}
}
+3 -1
View File
@@ -27,7 +27,9 @@ dependencies {
api('com.electronwill.night-config:toml:3.6.4')
api('cpw.mods:modlauncher:9.0.+')
api('net.minecraftforge:coremods:5.0.+')
api "net.minecraftforge:JarJar:${JARJAR_VERSION}"
api "net.minecraftforge:JarJarSelector:${JARJAR_VERSION}"
api "net.minecraftforge:JarJarMetadata:${JARJAR_VERSION}"
implementation("cpw.mods:securejarhandler:${SECUREJARHANDLER_VERSION}")
implementation('org.apache.logging.log4j:log4j-core:2.17.0')
annotationProcessor('org.apache.logging.log4j:log4j-core:2.17.0')
@@ -5,6 +5,7 @@
package net.minecraftforge.fml.loading.moddiscovery;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import net.minecraftforge.fml.loading.EarlyLoadingException;
import net.minecraftforge.forgespi.language.IModInfo;
@@ -16,10 +17,15 @@ import org.apache.maven.artifact.versioning.ArtifactVersion;
import org.apache.maven.artifact.versioning.VersionRange;
import org.jetbrains.annotations.NotNull;
import java.net.URI;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -34,20 +40,16 @@ public class JarInJarDependencyLocator extends AbstractJarFileDependencyLocator
}
@Override
public List<IModFile> scanMods(final Iterable<IModFile> loadedMods) {
public List<IModFile> scanMods(final Iterable<IModFile> loadedMods)
{
final List<IModFile> sources = Lists.newArrayList();
loadedMods.forEach(sources::add);
final List<IModFile> dependenciesToLoad = JarSelector.detectAndSelect(
sources,
this::loadResourceFromModFile,
this::loadModFileFrom,
this::identifyMod,
this::exception
);
final List<IModFile> dependenciesToLoad = JarSelector.detectAndSelect(sources, this::loadResourceFromModFile, this::loadModFileFrom, this::identifyMod, this::exception);
if (dependenciesToLoad.isEmpty()) {
if (dependenciesToLoad.isEmpty())
{
LOGGER.info("No dependencies to load found. Skipping!");
return Collections.emptyList();
}
@@ -68,46 +70,87 @@ public class JarInJarDependencyLocator extends AbstractJarFileDependencyLocator
return IModFile.Type.GAMELIBRARY.name();
}
@SuppressWarnings("resource")
@Override
protected Optional<IModFile> loadModFileFrom(final IModFile file, final Path path)
{
try
{
final Path pathInModFile = file.findResource(path.toString());
final URI filePathUri = new URI("jij:" + (pathInModFile.toAbsolutePath().toUri().getRawSchemeSpecificPart())).normalize();
final Map<String, ?> outerFsArgs = ImmutableMap.of("packagePath", pathInModFile);
final FileSystem zipFS = FileSystems.newFileSystem(filePathUri, outerFsArgs);
final Path pathInFS = zipFS.getPath("/");
return createMod(pathInFS);
}
catch (Exception e)
{
LOGGER.error("Failed to load mod file {} from {}", path, file.getFileName());
throw new RuntimeException("Failed to load mod file " + file.getFileName(), e);
}
}
protected EarlyLoadingException exception(Collection<JarSelector.ResolutionFailureInformation<IModFile>> failedDependencies)
{
final List<EarlyLoadingException.ExceptionData> errors = failedDependencies.stream()
.filter(entry -> !entry.sources().isEmpty()) //Should never be the case, but just to be sure
.map(entry -> new EarlyLoadingException.ExceptionData(
getErrorTranslationKey(entry),
entry.identifier().group() + ":" + entry.identifier().artifact(),
entry.sources()
.stream()
.flatMap(this::getModWithVersionRangeStream)
.map(this::formatError)
.collect(Collectors.joining(", ")))).toList();
.filter(entry -> !entry.sources().isEmpty()) //Should never be the case, but just to be sure
.map(this::buildExceptionData)
.toList();
return new EarlyLoadingException(failedDependencies.size() + " Dependency restrictions were not met.", null, errors);
}
@NotNull
private EarlyLoadingException.ExceptionData buildExceptionData(final JarSelector.ResolutionFailureInformation<IModFile> entry)
{
return new EarlyLoadingException.ExceptionData(
getErrorTranslationKey(entry),
entry.identifier().group() + ":" + entry.identifier().artifact(),
entry.sources()
.stream()
.flatMap(this::getModWithVersionRangeStream)
.map(this::formatError)
.collect(Collectors.joining(", "))
);
}
@NotNull
private String getErrorTranslationKey(final JarSelector.ResolutionFailureInformation<IModFile> entry)
{
return entry.failureReason() == JarSelector.FailureReason.VERSION_RESOLUTION_FAILED
? "fml.dependencyloading.conflictingdependencies"
: "fml.dependencyloading.mismatchedcontaineddependencies";
return entry.failureReason() == JarSelector.FailureReason.VERSION_RESOLUTION_FAILED ?
"fml.dependencyloading.conflictingdependencies" :
"fml.dependencyloading.mismatchedcontaineddependencies";
}
@NotNull
private Stream<ModWithVersionRange> getModWithVersionRangeStream(final JarSelector.SourceWithRequestedVersionRange<IModFile> file)
{
return file.sources().stream().map(IModFile::getModFileInfo)
.flatMap(modFileInfo -> modFileInfo.getMods().stream())
.map(modInfo -> new ModWithVersionRange(modInfo, file.requestedVersionRange(), file.includedVersion()));
return file.sources()
.stream()
.map(IModFile::getModFileInfo)
.flatMap(modFileInfo -> modFileInfo.getMods().stream())
.map(modInfo -> new ModWithVersionRange(modInfo, file.requestedVersionRange(), file.includedVersion()));
}
@NotNull
private String formatError(final ModWithVersionRange modWithVersionRange)
{
return "\u00a7e" + modWithVersionRange.modInfo().getModId() + "\u00a7r - \u00a74"
+ modWithVersionRange.versionRange().toString() + "\u00a74 - \u00a72"
+ modWithVersionRange.artifactVersion().toString() + "\u00a72";
return "\u00a7e" + modWithVersionRange.modInfo().getModId() + "\u00a7r - \u00a74" + modWithVersionRange.versionRange().toString() + "\u00a74 - \u00a72" + modWithVersionRange.artifactVersion().toString() + "\u00a72";
}
private record ModWithVersionRange(IModInfo modInfo, VersionRange versionRange, ArtifactVersion artifactVersion) {}
@Override
protected String identifyMod(final IModFile modFile)
{
if (modFile.getModFileInfo() == null || modFile.getModInfos().isEmpty())
{
return modFile.getFileName();
}
return modFile.getModInfos().stream().map(IModInfo::getModId).collect(Collectors.joining());
}
private record ModWithVersionRange(IModInfo modInfo, VersionRange versionRange, ArtifactVersion artifactVersion)
{}
}
+1
View File
@@ -1,6 +1,7 @@
-p @MODULE_PATH@
--add-modules @MODULES@
--add-opens java.base/java.util.jar=cpw.mods.securejarhandler
--add-opens java.base/java.lang.invoke=cpw.mods.securejarhandler
--add-exports java.base/sun.security.util=cpw.mods.securejarhandler
--add-exports jdk.naming.dns/com.sun.jndi.dns=java.naming
-Djava.net.preferIPv6Addresses=system
@@ -7,9 +7,11 @@
},
"version": {
"range": "[1.0,)",
"artifactVersion": "1.2"
"artifactVersion": "1.5"
},
"path": "META-INF/jarjar/ForgeJiJTestMod-1.2.jar"
"_pathMixin_should_crash_on_startup": "META-INF/jarjar/ForgeJiJTestMod-1.5.jar",
"path": "META-INF/jarjar/ForgeJiJTestMod-1.2.jar",
"_path_crash_test": "META-INF/jarjar/jijroot-1.3.jar"
}
]
}