Skip to content

Commit

Permalink
Apply SJH updates and remove deprecated members (#38)
Browse files Browse the repository at this point in the history
  • Loading branch information
Technici4n authored Nov 30, 2023
1 parent a952595 commit ae8840b
Show file tree
Hide file tree
Showing 13 changed files with 92 additions and 119 deletions.
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ changelog {
disableAutomaticPublicationRegistration()
}

logger.lifecycle("FML version {}", gradleutils.getTagOffsetVersion())

allprojects {
apply plugin: 'java-library'
apply plugin: 'jacoco'
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ accesstransformers_version=9.0.0
coremods_version=6.0.0
eventbus_version=7.0.16
modlauncher_version=10.0.9
securejarhandler_version=2.1.10
securejarhandler_version=2.1.23
bootstraplauncher_version=1.1.2
asm_version=9.5
mixin_version=0.8.5
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
package net.neoforged.fml.loading;

import com.mojang.logging.LogUtils;
import cpw.mods.jarhandling.JarContentsBuilder;
import cpw.mods.jarhandling.JarMetadata;
import cpw.mods.jarhandling.SecureJar;
import cpw.mods.modlauncher.api.LamdbaExceptionUtils;
import cpw.mods.modlauncher.api.NamedPath;
Expand All @@ -14,7 +16,6 @@

import java.io.IOException;
import java.io.UncheckedIOException;
import java.lang.module.ModuleDescriptor;
import java.nio.file.AccessDeniedException;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.Files;
Expand Down Expand Up @@ -81,22 +82,26 @@ private static void scan(final Path gameDirectory) {
// Skip if the mods dir doesn't exist yet.
return;
}
try (var walk = Files.walk(modsDir, 1)){
walk.forEach(ModDirTransformerDiscoverer::visitFile);
try (var walk = Files.walk(modsDir, 1)) {
// Collect to list first, and then parallel stream it.
// Before JDK 19, Files.walk streams are not parallelized efficiently for small numbers of elements.
// See https://bugs.openjdk.org/browse/JDK-8280915.
walk.toList().parallelStream()
.filter(ModDirTransformerDiscoverer::shouldLoadInServiceLayer)
.forEachOrdered(p -> found.add(new NamedPath(p.getFileName().toString(), p)));
} catch (IOException | IllegalStateException ioe) {
LOGGER.error("Error during early discovery", ioe);
}
}

private static void visitFile(Path path) {
if (!Files.isRegularFile(path)) return;
if (!path.toString().endsWith(".jar")) return;
if (LamdbaExceptionUtils.uncheck(() -> Files.size(path)) == 0) return;
private static boolean shouldLoadInServiceLayer(Path path) {
if (!Files.isRegularFile(path)) return false;
if (!path.toString().endsWith(".jar")) return false;
if (LamdbaExceptionUtils.uncheck(() -> Files.size(path)) == 0) return false;

SecureJar jar = SecureJar.from(path);
jar.moduleDataProvider().descriptor().provides().stream()
.map(ModuleDescriptor.Provides::service)
.filter(SERVICES::contains)
.forEach(s -> found.add(new NamedPath(s, path)));
JarMetadata metadata = JarMetadata.from(new JarContentsBuilder().paths(path).build());
return metadata.providers().stream()
.map(SecureJar.Provider::serviceName)
.anyMatch(SERVICES::contains);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
package net.neoforged.fml.loading.moddiscovery;

import com.mojang.logging.LogUtils;
import cpw.mods.jarhandling.JarMetadata;
import cpw.mods.jarhandling.JarContentsBuilder;
import cpw.mods.jarhandling.SecureJar;
import net.neoforged.fml.loading.LogMarkers;
import net.neoforged.neoforgespi.language.IConfigurable;
Expand All @@ -25,7 +25,6 @@
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.jar.Manifest;

public abstract class AbstractModProvider implements IModProvider
{
Expand All @@ -34,30 +33,27 @@ public abstract class AbstractModProvider implements IModProvider
protected static final String MANIFEST = "META-INF/MANIFEST.MF";

protected IModLocator.ModFileOrException createMod(Path... path) {
var mjm = new ModJarMetadata();
var sj = SecureJar.from(
Manifest::new,
jar -> jar.moduleDataProvider().findFile(MODS_TOML).isPresent() ? mjm : JarMetadata.from(jar, path),
null,
path
);
var jarContents = new JarContentsBuilder()
.paths(path)
.build();

IModFile mod;
var type = sj.moduleDataProvider().getManifest().getMainAttributes().getValue(ModFile.TYPE);
var type = jarContents.getManifest().getMainAttributes().getValue(ModFile.TYPE);
if (type == null) {
type = getDefaultJarModType();
}
if (sj.moduleDataProvider().findFile(MODS_TOML).isPresent()) {
if (jarContents.findFile(MODS_TOML).isPresent()) {
LOGGER.debug(LogMarkers.SCAN, "Found {} mod of type {}: {}", MODS_TOML, type, path);
mod = new ModFile(sj, this, ModFileParser::modsTomlParser);
var mjm = new ModJarMetadata(jarContents);
mod = new ModFile(SecureJar.from(jarContents, mjm), this, ModFileParser::modsTomlParser);
mjm.setModFile(mod);
} else if (type != null) {
LOGGER.debug(LogMarkers.SCAN, "Found {} mod of type {}: {}", MANIFEST, type, path);
mod = new ModFile(sj, this, this::manifestParser, type);
mod = new ModFile(SecureJar.from(jarContents), this, this::manifestParser, type);
} else {
return new IModLocator.ModFileOrException(null, new ModFileLoadingException("Invalid mod file found "+ Arrays.toString(path)));
}

mjm.setModFile(mod);
return new IModLocator.ModFileOrException(mod, null);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
package net.neoforged.fml.loading.moddiscovery;

import com.mojang.logging.LogUtils;
import cpw.mods.jarhandling.JarContentsBuilder;
import cpw.mods.jarhandling.SecureJar;
import net.neoforged.fml.loading.LogMarkers;
import net.neoforged.neoforgespi.locating.IModFile;
import net.neoforged.neoforgespi.locating.IModLocator;
Expand All @@ -31,12 +33,17 @@ public record ExplodedMod(String modid, List<Path> paths) {}

@Override
public List<IModLocator.ModFileOrException> scanMods() {
explodedMods.forEach(explodedMod ->
ModJarMetadata.buildFile(this,
jar->jar.moduleDataProvider().findFile("/META-INF/mods.toml").isPresent(),
null,
explodedMod.paths().toArray(Path[]::new))
.ifPresentOrElse(f->mods.put(explodedMod, f), () -> LOGGER.warn(LogMarkers.LOADING, "Failed to find exploded resource mods.toml in directory {}", explodedMod.paths().get(0).toString())));
explodedMods.forEach(explodedMod -> {
var jarContents = new JarContentsBuilder().paths(explodedMod.paths().toArray(Path[]::new)).build();
if (jarContents.findFile(AbstractModProvider.MODS_TOML).isPresent()) {
var mjm = new ModJarMetadata(jarContents);
var mf = new ModFile(SecureJar.from(jarContents, mjm), this, ModFileParser::modsTomlParser);
mjm.setModFile(mf);
mods.put(explodedMod, mf);
} else {
LOGGER.warn(LogMarkers.LOADING, "Failed to find exploded resource mods.toml in directory {}", explodedMod.paths().get(0).toString());
}
});
return mods.values().stream().map(mf->new IModLocator.ModFileOrException(mf, null)).toList();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import com.electronwill.nightconfig.core.Config;
import com.mojang.logging.LogUtils;
import cpw.mods.jarhandling.JarContentsBuilder;
import cpw.mods.jarhandling.SecureJar;
import net.neoforged.fml.loading.FMLLoader;
import net.neoforged.fml.loading.LogMarkers;
Expand Down Expand Up @@ -34,7 +35,14 @@ public class MinecraftLocator extends AbstractModProvider implements IModLocator
public List<IModLocator.ModFileOrException> scanMods() {
final var launchHandler = FMLLoader.getLaunchHandler();
var baseMC = launchHandler.getMinecraftPaths();
var mcjar = ModJarMetadata.buildFile(j->ModFileFactory.FACTORY.build(j, this, this::buildMinecraftTOML), j->true, baseMC.minecraftFilter(), baseMC.minecraftPaths().toArray(Path[]::new)).orElseThrow();
var mcJarContents = new JarContentsBuilder()
.paths(baseMC.minecraftPaths().toArray(Path[]::new))
.pathFilter(baseMC.minecraftFilter())
.build();
var mcJarMetadata = new ModJarMetadata(mcJarContents);
var mcSecureJar = SecureJar.from(mcJarContents, mcJarMetadata);
var mcjar = ModFileFactory.FACTORY.build(mcSecureJar, this, this::buildMinecraftTOML);
mcJarMetadata.setModFile(mcjar);
var artifacts = baseMC.otherArtifacts().stream()
.map(SecureJar::from)
.map(sj -> new ModFile(sj, this, ModFileParser::modsTomlParser))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,8 @@
import java.util.jar.Manifest;

public class ModFile implements IModFile {
// Mods either must have a mods.toml or a manifest. We can no longer just put any jar on the classpath.
@Deprecated(forRemoval = true, since = "1.18")
public static final Manifest DEFAULTMANIFEST;
private static final Logger LOGGER = LogUtils.getLogger();

static {
DEFAULTMANIFEST = new Manifest();
DEFAULTMANIFEST.getMainAttributes().putValue("FMLModType", "MOD");
}

private final String jarVersion;
private final ModFileFactory.ModFileInfoParser parser;
private Map<String, Object> fileProperties;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,50 +5,20 @@

package net.neoforged.fml.loading.moddiscovery;

import cpw.mods.jarhandling.JarContents;
import cpw.mods.jarhandling.JarMetadata;
import cpw.mods.jarhandling.SecureJar;
import cpw.mods.jarhandling.LazyJarMetadata;
import net.neoforged.neoforgespi.locating.IModFile;
import net.neoforged.neoforgespi.locating.IModLocator;

import java.lang.module.ModuleDescriptor;
import java.nio.file.Path;
import java.util.Objects;
import java.util.Optional;
import java.util.function.BiPredicate;
import java.util.function.Function;
import java.util.function.Predicate;

public final class ModJarMetadata implements JarMetadata {
public final class ModJarMetadata extends LazyJarMetadata implements JarMetadata {
private final JarContents jarContents;
private IModFile modFile;
private ModuleDescriptor descriptor;

// TODO: Remove helper functions to cleanup api
@Deprecated(forRemoval = true, since="1.18")
static Optional<IModFile> buildFile(IModLocator locator, Predicate<SecureJar> jarTest, BiPredicate<String, String> filter, Path... files) {
return buildFile(j->new ModFile(j, locator, ModFileParser::modsTomlParser), jarTest, filter, files);
}

// TODO: Remove helper functions to cleanup api
@Deprecated(forRemoval = true, since="1.18")
static IModFile buildFile(IModLocator locator, Path... files) {
return buildFile(locator, j->true, null, files).orElseThrow(()->new IllegalArgumentException("Failed to find valid JAR file"));
}

// TODO: Remove helper functions to cleanup api
@Deprecated(forRemoval = true, since="1.18")
static Optional<IModFile> buildFile(Function<SecureJar, IModFile> mfConstructor, Predicate<SecureJar> jarTest, BiPredicate<String, String> filter, Path... files) {
var mjm = new ModJarMetadata();
var sj = SecureJar.from(()->ModFile.DEFAULTMANIFEST, j->mjm, filter, files);
if (jarTest.test(sj)) {
var mf = mfConstructor.apply(sj);
mjm.setModFile(mf);
return Optional.of(mf);
} else {
return Optional.empty();
}
}

ModJarMetadata() {
ModJarMetadata(JarContents jarContents) {
this.jarContents = jarContents;
}

public void setModFile(IModFile file) {
Expand All @@ -66,17 +36,15 @@ public String version() {
}

@Override
public ModuleDescriptor descriptor() {
if (descriptor != null) return descriptor;
public ModuleDescriptor computeDescriptor() {
var bld = ModuleDescriptor.newAutomaticModule(name())
.version(version())
.packages(modFile.getSecureJar().getPackages());
modFile.getSecureJar().getProviders().stream()
.packages(jarContents.getPackagesExcluding("assets", "data"));
jarContents.getMetaInfServices().stream()
.filter(p -> !p.providers().isEmpty())
.forEach(p -> bld.provides(p.serviceName(), p.providers()));
modFile.getModFileInfo().usesServices().forEach(bld::uses);
descriptor = bld.build();
return descriptor;
return bld.build();
}

public IModFile modFile() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@

package net.neoforged.fml.loading.targets;

import cpw.mods.jarhandling.JarContentsBuilder;
import cpw.mods.jarhandling.SecureJar;
import cpw.mods.niofs.union.UnionPathFilter;
import net.neoforged.fml.loading.FileUtils;

import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.function.BiPredicate;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream;
Expand Down Expand Up @@ -88,12 +89,12 @@ protected static Path findJarOnClasspath(String[] classpath, String match) {
.orElseThrow(() -> new IllegalStateException("Could not find " + match + " in classpath"));
}

protected BiPredicate<String, String> getMcFilter(Path extra, List<Path> minecraft, Stream.Builder<List<Path>> mods) {
protected UnionPathFilter getMcFilter(Path extra, List<Path> minecraft, Stream.Builder<List<Path>> mods) {
final var packages = getExcludedPrefixes();
final var extraPath = extra.toString().replace('\\', '/');

// We serve everything, except for things in the forge packages.
BiPredicate<String, String> mcFilter = (path, base) -> {
UnionPathFilter mcFilter = (path, base) -> {
if (base.equals(extraPath) ||
path.endsWith("/")) return true;
for (var pkg : packages)
Expand All @@ -102,12 +103,15 @@ protected BiPredicate<String, String> getMcFilter(Path extra, List<Path> minecra
};

// We need to separate out our resources/code so that we can show up as a different data pack.
var modJar = SecureJar.from((path, base) -> {
if (!path.endsWith(".class")) return true;
for (var pkg : packages)
if (path.startsWith(pkg)) return true;
return false;
}, minecraft.stream().distinct().toArray(Path[]::new));
var modJar = SecureJar.from(new JarContentsBuilder()
.pathFilter((path, base) -> {
if (!path.endsWith(".class")) return true;
for (var pkg : packages)
if (path.startsWith(pkg)) return true;
return false;
})
.paths(minecraft.stream().distinct().toArray(Path[]::new))
.build());
//modJar.getPackages().stream().sorted().forEach(System.out::println);
mods.add(List.of(modJar.getRootPath()));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import cpw.mods.modlauncher.api.ILaunchHandlerService;
import cpw.mods.modlauncher.api.ITransformingClassLoaderBuilder;
import cpw.mods.modlauncher.api.ServiceRunner;
import cpw.mods.niofs.union.UnionPathFilter;
import net.neoforged.fml.loading.FMLLoader;
import net.neoforged.fml.loading.FileUtils;
import net.neoforged.fml.loading.LogMarkers;
Expand All @@ -29,11 +30,10 @@
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.function.BiPredicate;
import java.util.stream.Collectors;

public abstract class CommonLaunchHandler implements ILaunchHandlerService {
public record LocatedPaths(List<Path> minecraftPaths, BiPredicate<String, String> minecraftFilter, List<List<Path>> otherModPaths, List<Path> otherArtifacts) {}
public record LocatedPaths(List<Path> minecraftPaths, UnionPathFilter minecraftFilter, List<List<Path>> otherModPaths, List<Path> otherArtifacts) {}

protected static final Logger LOGGER = LogUtils.getLogger();

Expand Down
Loading

0 comments on commit ae8840b

Please sign in to comment.