Combine all hidden mod resource packs into a single sortable pack
Fix mod datapacks sorting under vanilla
This commit is contained in:
parent
8482293b40
commit
ca980a56bc
7 changed files with 220 additions and 52 deletions
|
@ -19,15 +19,37 @@
|
|||
|
||||
package net.minecraftforge.fml.client;
|
||||
|
||||
import static net.minecraftforge.fml.Logging.CORE;
|
||||
import static net.minecraftforge.fml.loading.LogMarkers.LOADING;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.resources.DownloadingPackFinder;
|
||||
import net.minecraft.client.resources.ClientResourcePackInfo;
|
||||
import net.minecraft.client.resources.DownloadingPackFinder;
|
||||
import net.minecraft.profiler.IProfiler;
|
||||
import net.minecraft.resources.IFutureReloadListener;
|
||||
import net.minecraft.resources.IReloadableResourceManager;
|
||||
import net.minecraft.resources.IResourceManager;
|
||||
import net.minecraft.resources.ResourcePackInfo;
|
||||
import net.minecraft.resources.ResourcePackList;
|
||||
import net.minecraft.resources.data.PackMetadataSection;
|
||||
import net.minecraft.util.text.TranslationTextComponent;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.client.event.ModelRegistryEvent;
|
||||
|
@ -46,27 +68,12 @@ import net.minecraftforge.fml.VersionChecker;
|
|||
import net.minecraftforge.fml.client.gui.LoadingErrorScreen;
|
||||
import net.minecraftforge.fml.client.registry.RenderingRegistry;
|
||||
import net.minecraftforge.fml.loading.moddiscovery.ModFile;
|
||||
import net.minecraftforge.fml.packs.DelegatableResourcePack;
|
||||
import net.minecraftforge.fml.packs.DelegatingResourcePack;
|
||||
import net.minecraftforge.fml.packs.ModFileResourcePack;
|
||||
import net.minecraftforge.fml.packs.ResourcePackLoader;
|
||||
import net.minecraftforge.fml.server.LanguageHook;
|
||||
import net.minecraftforge.forgespi.language.IModInfo;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static net.minecraftforge.fml.Logging.CORE;
|
||||
import static net.minecraftforge.fml.loading.LogMarkers.LOADING;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class ClientModLoader
|
||||
|
@ -173,17 +180,18 @@ public class ClientModLoader
|
|||
return loading;
|
||||
}
|
||||
|
||||
private static <T extends ResourcePackInfo> ResourcePackLoader.IPackInfoFinder<T> buildPackFinder(Map<ModFile, ModFileResourcePack> modResourcePacks, BiConsumer<ModFileResourcePack, T> packSetter) {
|
||||
private static <T extends ResourcePackInfo> ResourcePackLoader.IPackInfoFinder<T> buildPackFinder(Map<ModFile, ? extends ModFileResourcePack> modResourcePacks, BiConsumer<? super ModFileResourcePack, ? super T> packSetter) {
|
||||
return (packList, factory) -> clientPackFinder(modResourcePacks, packSetter, packList, factory);
|
||||
}
|
||||
|
||||
private static <T extends ResourcePackInfo> void clientPackFinder(Map<ModFile, ModFileResourcePack> modResourcePacks, BiConsumer<ModFileResourcePack, T> packSetter, Map<String, T> packList, ResourcePackInfo.IFactory<T> factory) {
|
||||
for (Map.Entry<ModFile, ModFileResourcePack> e : modResourcePacks.entrySet())
|
||||
private static <T extends ResourcePackInfo> void clientPackFinder(Map<ModFile, ? extends ModFileResourcePack> modResourcePacks, BiConsumer<? super ModFileResourcePack, ? super T> packSetter, Map<String, T> packList, ResourcePackInfo.IFactory<? extends T> factory) {
|
||||
List<DelegatableResourcePack> hiddenPacks = new ArrayList<>();
|
||||
for (Entry<ModFile, ? extends ModFileResourcePack> e : modResourcePacks.entrySet())
|
||||
{
|
||||
IModInfo mod = e.getKey().getModInfos().get(0);
|
||||
if (Objects.equals(mod.getModId(), "minecraft")) continue; // skip the minecraft "mod"
|
||||
final String name = "mod:" + mod.getModId();
|
||||
final T packInfo = ResourcePackInfo.createResourcePack(name, true, e::getValue, factory, ResourcePackInfo.Priority.BOTTOM);
|
||||
final T packInfo = ResourcePackInfo.createResourcePack(name, false, e::getValue, factory, ResourcePackInfo.Priority.BOTTOM);
|
||||
if (packInfo == null) {
|
||||
// Vanilla only logs an error, instead of propagating, so handle null and warn that something went wrong
|
||||
ModLoader.get().addWarning(new ModLoadingWarning(mod, ModLoadingStage.ERROR, "fml.modloading.brokenresources", e.getKey()));
|
||||
|
@ -191,7 +199,15 @@ public class ClientModLoader
|
|||
}
|
||||
packSetter.accept(e.getValue(), packInfo);
|
||||
LOGGER.debug(CORE, "Generating PackInfo named {} for mod file {}", name, e.getKey().getFilePath());
|
||||
packList.put(name, packInfo);
|
||||
if (mod.getOwningFile().showAsResourcePack()) {
|
||||
packList.put(name, packInfo);
|
||||
} else {
|
||||
hiddenPacks.add(e.getValue());
|
||||
}
|
||||
}
|
||||
final T packInfo = ResourcePackInfo.createResourcePack("mod_resources", true, () -> new DelegatingResourcePack("mod_resources", "Mod Resources",
|
||||
new PackMetadataSection(new TranslationTextComponent("fml.resources.modresources", hiddenPacks.size()), 4),
|
||||
hiddenPacks), factory, ResourcePackInfo.Priority.BOTTOM);
|
||||
packList.put("mod_resources", packInfo);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
package net.minecraftforge.fml.packs;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import net.minecraft.resources.ResourcePack;
|
||||
|
||||
public abstract class DelegatableResourcePack extends ResourcePack
|
||||
{
|
||||
protected DelegatableResourcePack(File resourcePackFileIn)
|
||||
{
|
||||
super(resourcePackFileIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract InputStream getInputStream(String resourcePath) throws IOException;
|
||||
|
||||
@Override
|
||||
public abstract boolean resourceExists(String resourcePath);
|
||||
}
|
|
@ -0,0 +1,133 @@
|
|||
package net.minecraftforge.fml.packs;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import net.minecraft.resources.ResourcePack;
|
||||
import net.minecraft.resources.ResourcePackFileNotFoundException;
|
||||
import net.minecraft.resources.ResourcePackType;
|
||||
import net.minecraft.resources.data.IMetadataSectionSerializer;
|
||||
import net.minecraft.resources.data.PackMetadataSection;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
public class DelegatingResourcePack extends ResourcePack
|
||||
{
|
||||
private final List<DelegatableResourcePack> delegates = new ArrayList<>();
|
||||
private final String name;
|
||||
private final PackMetadataSection packInfo;
|
||||
|
||||
public DelegatingResourcePack(String id, String name, PackMetadataSection packInfo)
|
||||
{
|
||||
this(id, name, packInfo, Collections.emptyList());
|
||||
}
|
||||
|
||||
public DelegatingResourcePack(String id, String name, PackMetadataSection packInfo, List<DelegatableResourcePack> packs)
|
||||
{
|
||||
super(new File(id));
|
||||
this.name = name;
|
||||
this.packInfo = packInfo;
|
||||
packs.forEach(this::addDelegate);
|
||||
}
|
||||
|
||||
public void addDelegate(DelegatableResourcePack pack)
|
||||
{
|
||||
synchronized(delegates)
|
||||
{
|
||||
this.delegates.add(pack);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T> T getMetadata(IMetadataSectionSerializer<T> deserializer) throws IOException
|
||||
{
|
||||
if (deserializer.getSectionName().equals("pack"))
|
||||
{
|
||||
return (T) packInfo;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ResourceLocation> getAllResourceLocations(ResourcePackType type, String pathIn, int maxDepth, Predicate<String> filter)
|
||||
{
|
||||
synchronized(delegates)
|
||||
{
|
||||
return delegates.stream()
|
||||
.flatMap(r -> r.getAllResourceLocations(type, pathIn, maxDepth, filter).stream())
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getResourceNamespaces(ResourcePackType type)
|
||||
{
|
||||
synchronized (delegates)
|
||||
{
|
||||
return delegates.stream()
|
||||
.flatMap(r -> r.getResourceNamespaces(type).stream())
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException
|
||||
{
|
||||
synchronized(delegates)
|
||||
{
|
||||
for (ResourcePack pack : delegates)
|
||||
{
|
||||
pack.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InputStream getInputStream(String resourcePath) throws IOException
|
||||
{
|
||||
if (!resourcePath.equals("pack.png")) // Mods shouldn't be able to mess with the pack icon
|
||||
{
|
||||
synchronized (delegates)
|
||||
{
|
||||
for (DelegatableResourcePack pack : delegates)
|
||||
{
|
||||
if (pack.resourceExists(resourcePath))
|
||||
{
|
||||
return pack.getInputStream(resourcePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new ResourcePackFileNotFoundException(this.file, resourcePath);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean resourceExists(String resourcePath)
|
||||
{
|
||||
synchronized (delegates)
|
||||
{
|
||||
for (DelegatableResourcePack pack : delegates)
|
||||
{
|
||||
if (pack.resourceExists(resourcePath))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -52,7 +52,7 @@ import org.apache.logging.log4j.Logger;
|
|||
|
||||
import static net.minecraftforge.fml.Logging.CORE;
|
||||
|
||||
public class ModFileResourcePack extends ResourcePack
|
||||
public class ModFileResourcePack extends DelegatableResourcePack
|
||||
{
|
||||
private final ModFile modFile;
|
||||
private ResourcePackInfo packInfo;
|
||||
|
@ -74,14 +74,14 @@ public class ModFileResourcePack extends ResourcePack
|
|||
}
|
||||
|
||||
@Override
|
||||
protected InputStream getInputStream(String name) throws IOException
|
||||
public InputStream getInputStream(String name) throws IOException
|
||||
{
|
||||
final Path path = modFile.getLocator().findPath(modFile, name);
|
||||
return Files.newInputStream(path, StandardOpenOption.READ);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean resourceExists(String name)
|
||||
public boolean resourceExists(String name)
|
||||
{
|
||||
return Files.exists(modFile.getLocator().findPath(modFile, name));
|
||||
}
|
||||
|
@ -146,7 +146,6 @@ public class ModFileResourcePack extends ResourcePack
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void close() throws IOException
|
||||
{
|
||||
|
@ -160,9 +159,4 @@ public class ModFileResourcePack extends ResourcePack
|
|||
<T extends ResourcePackInfo> T getPackInfo() {
|
||||
return (T)this.packInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHidden() {
|
||||
return !modFile.getModFileInfo().showAsResourcePack();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ import org.apache.logging.log4j.LogManager;
|
|||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import net.minecraft.resources.IPackFinder;
|
||||
import net.minecraft.resources.ResourcePack;
|
||||
import net.minecraft.resources.ResourcePackInfo;
|
||||
import net.minecraft.resources.ResourcePackList;
|
||||
import net.minecraftforge.fml.ModList;
|
||||
|
@ -49,7 +50,7 @@ public class ResourcePackLoader
|
|||
map(ModFileInfo::getFile).map(mf->modResourcePacks.get(mf));
|
||||
}
|
||||
|
||||
public static <T extends ResourcePackInfo> void loadResourcePacks(ResourcePackList<T> resourcePacks, BiFunction<Map<ModFile, ModFileResourcePack>, BiConsumer<ModFileResourcePack, T>, IPackInfoFinder> packFinder) {
|
||||
public static <T extends ResourcePackInfo> void loadResourcePacks(ResourcePackList<T> resourcePacks, BiFunction<Map<ModFile, ? extends ModFileResourcePack>, BiConsumer<? super ModFileResourcePack, T>, IPackInfoFinder> packFinder) {
|
||||
resourcePackList = resourcePacks;
|
||||
modResourcePacks = ModList.get().getModFiles().stream().
|
||||
filter(mf->!Objects.equals(mf.getModLoader(),"minecraft")).
|
||||
|
|
|
@ -19,8 +19,23 @@
|
|||
|
||||
package net.minecraftforge.fml.server;
|
||||
|
||||
import net.minecraft.network.ProtocolType;
|
||||
import static net.minecraftforge.fml.Logging.CORE;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.logging.log4j.Marker;
|
||||
import org.apache.logging.log4j.MarkerManager;
|
||||
|
||||
import net.minecraft.network.NetworkManager;
|
||||
import net.minecraft.network.ProtocolType;
|
||||
import net.minecraft.network.handshake.client.CHandshakePacket;
|
||||
import net.minecraft.network.login.server.SDisconnectLoginPacket;
|
||||
import net.minecraft.resources.ResourcePackInfo;
|
||||
|
@ -36,8 +51,8 @@ import net.minecraftforge.fml.ModLoadingWarning;
|
|||
import net.minecraftforge.fml.config.ConfigTracker;
|
||||
import net.minecraftforge.fml.config.ModConfig;
|
||||
import net.minecraftforge.fml.event.server.FMLServerAboutToStartEvent;
|
||||
import net.minecraftforge.fml.event.server.FMLServerStartingEvent;
|
||||
import net.minecraftforge.fml.event.server.FMLServerStartedEvent;
|
||||
import net.minecraftforge.fml.event.server.FMLServerStartingEvent;
|
||||
import net.minecraftforge.fml.event.server.FMLServerStoppedEvent;
|
||||
import net.minecraftforge.fml.event.server.FMLServerStoppingEvent;
|
||||
import net.minecraftforge.fml.loading.FileUtils;
|
||||
|
@ -49,19 +64,6 @@ import net.minecraftforge.fml.network.NetworkRegistry;
|
|||
import net.minecraftforge.fml.packs.ModFileResourcePack;
|
||||
import net.minecraftforge.fml.packs.ResourcePackLoader;
|
||||
import net.minecraftforge.forgespi.language.IModInfo;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.logging.log4j.Marker;
|
||||
import org.apache.logging.log4j.MarkerManager;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import static net.minecraftforge.fml.Logging.CORE;
|
||||
|
||||
public class ServerLifecycleHooks
|
||||
{
|
||||
|
@ -193,17 +195,17 @@ public class ServerLifecycleHooks
|
|||
System.exit(retVal);
|
||||
}
|
||||
|
||||
private static <T extends ResourcePackInfo> ResourcePackLoader.IPackInfoFinder<T> buildPackFinder(Map<ModFile, ModFileResourcePack> modResourcePacks, BiConsumer<ModFileResourcePack, T> packSetter) {
|
||||
private static <T extends ResourcePackInfo> ResourcePackLoader.IPackInfoFinder<T> buildPackFinder(Map<ModFile, ? extends ModFileResourcePack> modResourcePacks, BiConsumer<? super ModFileResourcePack, ? super T> packSetter) {
|
||||
return (packList, factory) -> serverPackFinder(modResourcePacks, packSetter, packList, factory);
|
||||
}
|
||||
|
||||
private static <T extends ResourcePackInfo> void serverPackFinder(Map<ModFile, ModFileResourcePack> modResourcePacks, BiConsumer<ModFileResourcePack, T> packSetter, Map<String, T> packList, ResourcePackInfo.IFactory<T> factory) {
|
||||
for (Map.Entry<ModFile, ModFileResourcePack> e : modResourcePacks.entrySet())
|
||||
private static <T extends ResourcePackInfo> void serverPackFinder(Map<ModFile, ? extends ModFileResourcePack> modResourcePacks, BiConsumer<? super ModFileResourcePack, ? super T> packSetter, Map<String, T> packList, ResourcePackInfo.IFactory<? extends T> factory) {
|
||||
for (Entry<ModFile, ? extends ModFileResourcePack> e : modResourcePacks.entrySet())
|
||||
{
|
||||
IModInfo mod = e.getKey().getModInfos().get(0);
|
||||
if (Objects.equals(mod.getModId(), "minecraft")) continue; // skip the minecraft "mod"
|
||||
final String name = "mod:" + mod.getModId();
|
||||
final T packInfo = ResourcePackInfo.createResourcePack(name, true, e::getValue, factory, ResourcePackInfo.Priority.BOTTOM);
|
||||
final T packInfo = ResourcePackInfo.createResourcePack(name, true, e::getValue, factory, ResourcePackInfo.Priority.TOP);
|
||||
if (packInfo == null) {
|
||||
// Vanilla only logs an error, instead of propagating, so handle null and warn that something went wrong
|
||||
ModLoader.get().addWarning(new ModLoadingWarning(mod, ModLoadingStage.ERROR, "fml.modloading.brokenresources", e.getKey()));
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
"fml.modloading.brokenfile.optifine": "File {2} is an incompatible version of OptiFine",
|
||||
"fml.modloading.brokenfile.invalidzip": "File {2} is not a jar file",
|
||||
"fml.modloading.brokenresources": "File {2} failed to load a valid ResourcePackInfo",
|
||||
"fml.resources.modresources": "Resources for {0} mod files",
|
||||
|
||||
"fml.messages.artifactversion.ornotinstalled":"{0,ornull,fml.messages.artifactversion.notinstalled}",
|
||||
"fml.messages.artifactversion":"{0,ornull,fml.messages.artifactversion.none}",
|
||||
|
|
Loading…
Reference in a new issue