Use new enumeration mechanism in ModLauncher, to allow getResources to work. This enables serviceloader-in-mods, and other stuff that might need to visit multiple mod jars. Also, tweaked the visitor code slightly, may result in a trivial performance change. Closing #7302 as it's not really relevant any more.

Signed-off-by: cpw <cpw+github@weeksfamily.ca>
This commit is contained in:
cpw 2020-09-06 17:54:05 -04:00
parent de03eb6e3c
commit b1f73a0760
No known key found for this signature in database
GPG key ID: 8EB3DF749553B1B7
4 changed files with 52 additions and 27 deletions

View file

@ -432,7 +432,7 @@ project(':forge') {
installer 'org.ow2.asm:asm-tree:7.2'
installer 'org.ow2.asm:asm-util:7.2'
installer 'org.ow2.asm:asm-analysis:7.2'
installer 'cpw.mods:modlauncher:6.1.+'
installer 'cpw.mods:modlauncher:7.0.+'
installer 'cpw.mods:grossjava9hacks:1.3.+'
installer 'net.minecraftforge:accesstransformers:2.2.+:shadowed'
installer 'net.minecraftforge:eventbus:3.0.+:service'

View file

@ -75,8 +75,8 @@ public abstract class FMLCommonLaunchHandler
Arrays.stream(FMLLoader.getMCPaths()).forEach(builder::addTransformationPath);
additionalLibraries.forEach(builder::addTransformationPath);
FMLLoader.getLanguageLoadingProvider().getLibraries().forEach(builder::addTransformationPath);
builder.setClassBytesLocator(getClassLoaderLocatorFunction());
builder.setManifestLocator(getClassLoaderManifestLocatorFunction());
builder.setResourceEnumeratorLocator(getClassLoaderResourceEnumerationFunction());
}
public void setup(final IEnvironment environment, final Map<String, ?> arguments)
@ -128,16 +128,17 @@ public abstract class FMLCommonLaunchHandler
}
protected Function<String, Optional<URL>> getClassLoaderLocatorFunction() {
return input->Optional.ofNullable(FMLLoader.getLoadingModList().findURLForResource(input));
protected Function<String, Enumeration<URL>> getClassLoaderResourceEnumerationFunction() {
return input->FMLLoader.getLoadingModList().findAllURLsForResource(input);
}
protected Function<URLConnection, Optional<Manifest>> getClassLoaderManifestLocatorFunction() {
return input -> {
if (input instanceof ModJarURLHandler.ModJarURLConnection) {
return ((ModJarURLHandler.ModJarURLConnection) input).getManifest();
return urlConnection -> {
if (urlConnection instanceof ModJarURLHandler.ModJarURLConnection) {
return ((ModJarURLHandler.ModJarURLConnection) urlConnection).getManifest();
} else {
return Optional.empty();
}
return Optional.empty();
};
}

View file

@ -20,6 +20,7 @@
package net.minecraftforge.fml.loading;
import com.google.common.collect.Streams;
import cpw.mods.modlauncher.api.LamdbaExceptionUtils;
import net.minecraftforge.fml.loading.moddiscovery.BackgroundScanHandler;
import net.minecraftforge.fml.loading.moddiscovery.ModFile;
import net.minecraftforge.fml.loading.moddiscovery.ModFileInfo;
@ -29,11 +30,9 @@ import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* Master list of all mods <em>in the loading context. This class cannot refer outside the
@ -118,21 +117,46 @@ public class LoadingModList
return null;
}
public URL findURLForResource(String resourceName) {
for (ModFileInfo mf : modFiles) {
// strip a leading slash
if (resourceName.startsWith("/")) resourceName = resourceName.substring(1);
final Path resource = mf.getFile().findResource(resourceName);
if (Files.exists(resource)) {
try {
return new URL("modjar://"+mf.getMods().get(0).getModId()+"/"+resourceName);
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
}
public Enumeration<URL> findAllURLsForResource(final String resName) {
final String resourceName;
// strip a leading slash
if (resName.startsWith("/")) {
resourceName = resName.substring(1);
} else {
resourceName = resName;
}
return null;
return new Enumeration<URL>() {
private final Iterator<ModFileInfo> modFileIterator = modFiles.iterator();
private URL next;
@Override
public boolean hasMoreElements() {
if (next!=null) return true;
next = findNextURL();
return next != null;
}
@Override
public URL nextElement() {
if (next == null) {
next = findNextURL();
if (next == null) throw new NoSuchElementException();
}
URL result = next;
next = null;
return result;
}
private URL findNextURL() {
while (modFileIterator.hasNext()) {
final ModFileInfo next = modFileIterator.next();
final Path resource = next.getFile().findResource(resourceName);
if (Files.exists(resource)) {
return LamdbaExceptionUtils.uncheck(()->new URL("modjar://" + next.getMods().get(0).getModId() + "/" + resourceName));
}
}
return null;
}
};
}
public ModFileInfo getModFileById(String modid)

View file

@ -63,7 +63,7 @@ public abstract class AbstractJarFileLocator implements IModLocator {
if (path.length < 1) {
throw new IllegalArgumentException("Missing path");
}
return modJars.get(modFile).getPath(path[0], Arrays.copyOfRange(path, 1, path.length));
return modJars.get(modFile).getPath("",path);
}
@Override