diff --git a/src/main/java/net/minecraftforge/fml/client/ClientModLoader.java b/src/main/java/net/minecraftforge/fml/client/ClientModLoader.java index b49df05a1..27168a54b 100644 --- a/src/main/java/net/minecraftforge/fml/client/ClientModLoader.java +++ b/src/main/java/net/minecraftforge/fml/client/ClientModLoader.java @@ -63,7 +63,6 @@ import net.minecraftforge.fml.VersionChecker; import net.minecraftforge.fml.client.gui.screen.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; @@ -188,7 +187,7 @@ public class ClientModLoader } private static void clientPackFinder(Map modResourcePacks, BiConsumer packSetter, Consumer consumer, ResourcePackInfo.IFactory factory) { - List hiddenPacks = new ArrayList<>(); + List hiddenPacks = new ArrayList<>(); for (Entry e : modResourcePacks.entrySet()) { IModInfo mod = e.getKey().getModInfos().get(0); diff --git a/src/main/java/net/minecraftforge/fml/packs/DelegatableResourcePack.java b/src/main/java/net/minecraftforge/fml/packs/DelegatableResourcePack.java deleted file mode 100644 index 67b501afa..000000000 --- a/src/main/java/net/minecraftforge/fml/packs/DelegatableResourcePack.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2020. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -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); -} diff --git a/src/main/java/net/minecraftforge/fml/packs/DelegatingResourcePack.java b/src/main/java/net/minecraftforge/fml/packs/DelegatingResourcePack.java index 9fa52d176..9f0fe9e1c 100644 --- a/src/main/java/net/minecraftforge/fml/packs/DelegatingResourcePack.java +++ b/src/main/java/net/minecraftforge/fml/packs/DelegatingResourcePack.java @@ -22,14 +22,13 @@ 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.*; import java.util.function.Predicate; import java.util.stream.Collectors; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import net.minecraft.resources.IResourcePack; import net.minecraft.resources.ResourcePack; import net.minecraft.resources.ResourcePackFileNotFoundException; import net.minecraft.resources.ResourcePackType; @@ -39,31 +38,38 @@ import net.minecraft.util.ResourceLocation; public class DelegatingResourcePack extends ResourcePack { - private final List delegates = new ArrayList<>(); + + private final List delegates; + private final Map> namespacesAssets; + private final Map> namespacesData; + 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 packs) + public DelegatingResourcePack(String id, String name, PackMetadataSection packInfo, List packs) { super(new File(id)); this.name = name; this.packInfo = packInfo; - packs.forEach(this::addDelegate); + this.delegates = ImmutableList.copyOf(packs); + this.namespacesAssets = this.buildNamespaceMap(ResourcePackType.CLIENT_RESOURCES, delegates); + this.namespacesData = this.buildNamespaceMap(ResourcePackType.SERVER_DATA, delegates); } - public void addDelegate(DelegatableResourcePack pack) + private Map> buildNamespaceMap(ResourcePackType type, List packList) { - synchronized(delegates) + Map> map = new HashMap<>(); + for (IResourcePack pack : packList) { - this.delegates.add(pack); + for (String namespace : pack.getResourceNamespaces(type)) + { + map.computeIfAbsent(namespace, k -> new ArrayList<>()).add(pack); + } } + map.replaceAll((k, list) -> ImmutableList.copyOf(list)); + return ImmutableMap.copyOf(map); } - + @Override public String getName() { @@ -84,69 +90,84 @@ public class DelegatingResourcePack extends ResourcePack @Override public Collection getAllResourceLocations(ResourcePackType type, String pathIn, String pathIn2, int maxDepth, Predicate filter) { - synchronized(delegates) - { - return delegates.stream() - .flatMap(r -> r.getAllResourceLocations(type, pathIn, pathIn2, maxDepth, filter).stream()) - .collect(Collectors.toList()); - } + return delegates.stream() + .flatMap(r -> r.getAllResourceLocations(type, pathIn, pathIn2, maxDepth, filter).stream()) + .collect(Collectors.toList()); } @Override public Set getResourceNamespaces(ResourcePackType type) { - synchronized (delegates) - { - return delegates.stream() - .flatMap(r -> r.getResourceNamespaces(type).stream()) - .collect(Collectors.toSet()); - } + return type == ResourcePackType.CLIENT_RESOURCES ? namespacesAssets.keySet() : namespacesData.keySet(); } @Override public void close() { - synchronized(delegates) + for (IResourcePack pack : delegates) { - for (ResourcePack pack : delegates) - { - pack.close(); - } + pack.close(); } } + @Override + public InputStream getRootResourceStream(String fileName) throws IOException + { + // root resources do not make sense here + throw new ResourcePackFileNotFoundException(this.file, fileName); + } + @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); - } - } - } - } + // never called, we override all methods that call this throw new ResourcePackFileNotFoundException(this.file, resourcePath); } @Override protected boolean resourceExists(String resourcePath) { - synchronized (delegates) + // never called, we override all methods that call this + return false; + } + + @Override + public InputStream getResourceStream(ResourcePackType type, ResourceLocation location) throws IOException + { + for (IResourcePack pack : getCandidatePacks(type, location)) { - for (DelegatableResourcePack pack : delegates) + if (pack.resourceExists(type, location)) { - if (pack.resourceExists(resourcePath)) - { - return true; - } + return pack.getResourceStream(type, location); + } + } + throw new ResourcePackFileNotFoundException(this.file, getFullPath(type, location)); + } + + @Override + public boolean resourceExists(ResourcePackType type, ResourceLocation location) + { + for (IResourcePack pack : getCandidatePacks(type, location)) + { + if (pack.resourceExists(type, location)) + { + return true; } } return false; } + + private List getCandidatePacks(ResourcePackType type, ResourceLocation location) + { + Map> map = type == ResourcePackType.CLIENT_RESOURCES ? namespacesAssets : namespacesData; + List packsWithNamespace = map.get(location.getNamespace()); + return packsWithNamespace == null ? Collections.emptyList() : packsWithNamespace; + } + + private static String getFullPath(ResourcePackType type, ResourceLocation location) + { + // stolen from ResourcePack + return String.format("%s/%s/%s", type.getDirectoryName(), location.getNamespace(), location.getPath()); + } + } diff --git a/src/main/java/net/minecraftforge/fml/packs/ModFileResourcePack.java b/src/main/java/net/minecraftforge/fml/packs/ModFileResourcePack.java index bdde12715..cf85dfb97 100644 --- a/src/main/java/net/minecraftforge/fml/packs/ModFileResourcePack.java +++ b/src/main/java/net/minecraftforge/fml/packs/ModFileResourcePack.java @@ -19,6 +19,7 @@ package net.minecraftforge.fml.packs; +import net.minecraft.resources.ResourcePack; import net.minecraft.resources.ResourcePackFileNotFoundException; import net.minecraft.resources.ResourcePackInfo; import net.minecraft.resources.ResourcePackType; @@ -39,7 +40,7 @@ import java.util.stream.Collectors; import com.google.common.base.Joiner; -public class ModFileResourcePack extends DelegatableResourcePack +public class ModFileResourcePack extends ResourcePack { private final ModFile modFile; private ResourcePackInfo packInfo; @@ -61,7 +62,7 @@ public class ModFileResourcePack extends DelegatableResourcePack } @Override - public InputStream getInputStream(String name) throws IOException + protected InputStream getInputStream(String name) throws IOException { final Path path = modFile.getLocator().findPath(modFile, name); if(!Files.exists(path)) @@ -70,7 +71,7 @@ public class ModFileResourcePack extends DelegatableResourcePack } @Override - public boolean resourceExists(String name) + protected boolean resourceExists(String name) { return Files.exists(modFile.getLocator().findPath(modFile, name)); }