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-tree:7.2'
installer 'org.ow2.asm:asm-util:7.2' installer 'org.ow2.asm:asm-util:7.2'
installer 'org.ow2.asm:asm-analysis: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 'cpw.mods:grossjava9hacks:1.3.+'
installer 'net.minecraftforge:accesstransformers:2.2.+:shadowed' installer 'net.minecraftforge:accesstransformers:2.2.+:shadowed'
installer 'net.minecraftforge:eventbus:3.0.+:service' installer 'net.minecraftforge:eventbus:3.0.+:service'

View file

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

View file

@ -20,6 +20,7 @@
package net.minecraftforge.fml.loading; package net.minecraftforge.fml.loading;
import com.google.common.collect.Streams; 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.BackgroundScanHandler;
import net.minecraftforge.fml.loading.moddiscovery.ModFile; import net.minecraftforge.fml.loading.moddiscovery.ModFile;
import net.minecraftforge.fml.loading.moddiscovery.ModFileInfo; import net.minecraftforge.fml.loading.moddiscovery.ModFileInfo;
@ -29,11 +30,9 @@ import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.ArrayList; import java.util.*;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors; 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 * Master list of all mods <em>in the loading context. This class cannot refer outside the
@ -118,22 +117,47 @@ public class LoadingModList
return null; return null;
} }
public URL findURLForResource(String resourceName) { public Enumeration<URL> findAllURLsForResource(final String resName) {
for (ModFileInfo mf : modFiles) { final String resourceName;
// strip a leading slash // strip a leading slash
if (resourceName.startsWith("/")) resourceName = resourceName.substring(1); if (resName.startsWith("/")) {
resourceName = resName.substring(1);
final Path resource = mf.getFile().findResource(resourceName); } else {
if (Files.exists(resource)) { resourceName = resName;
try {
return new URL("modjar://"+mf.getMods().get(0).getModId()+"/"+resourceName);
} catch (MalformedURLException e) {
throw new RuntimeException(e);
} }
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; return null;
} }
};
}
public ModFileInfo getModFileById(String modid) public ModFileInfo getModFileById(String modid)
{ {

View file

@ -63,7 +63,7 @@ public abstract class AbstractJarFileLocator implements IModLocator {
if (path.length < 1) { if (path.length < 1) {
throw new IllegalArgumentException("Missing path"); 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 @Override