mirror of
https://github.com/FabricMC/fabric.git
synced 2025-04-21 03:10:54 -04:00
Resource loader improvements (#1186)
* Add resource pack activation type, programmer art API, group mod resource packs.
* Add missing license headers.
* Cleanup and add documentation.
* Fix performance issues.
* Rename invoker.
* Add comment in ReloadableResourceManagerImplMixin.
* Add package-info to resource loader.
(cherry picked from commit 73b29211a6
)
This commit is contained in:
parent
96f0bfaa41
commit
0ea93ebaf8
21 changed files with 715 additions and 86 deletions
fabric-resource-loader-v0/src
main
java/net/fabricmc/fabric
api/resource
impl/resource/loader
FabricModResourcePack.javaGroupResourcePack.javaModNioResourcePack.javaModResourcePackCreator.javaModResourcePackUtil.javaResourceManagerHelperImpl.java
client/pack
mixin/resource/loader
resources
testmod
java/net/fabricmc/fabric/test/resource/loader
resources/resourcepacks/test
|
@ -24,7 +24,7 @@ import net.fabricmc.fabric.impl.resource.loader.ResourceManagerHelperImpl;
|
|||
import net.fabricmc.loader.api.ModContainer;
|
||||
|
||||
/**
|
||||
* Helper for working with {@link ResourceManager} instances.
|
||||
* Helper for working with {@link ResourceManager} instances, and other resource loader generalities.
|
||||
*/
|
||||
public interface ResourceManagerHelper {
|
||||
/**
|
||||
|
@ -55,6 +55,26 @@ public interface ResourceManagerHelper {
|
|||
return ResourceManagerHelperImpl.get(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a built-in resource pack.
|
||||
*
|
||||
* <p>A built-in resource pack is an extra resource pack provided by your mod which is not always active, it's similar to the "Programmer Art" resource pack.
|
||||
*
|
||||
* <p>Why and when to use it? A built-in resource pack should be used to provide extra assets/data that should be optional with your mod but still directly provided by it.
|
||||
* For example it could provide textures of your mod in another resolution, or could allow to provide different styles of your assets.
|
||||
*
|
||||
* <p>The path in which the resource pack is located is in the mod JAR file under the {@code "resourcepacks/<id path>"} directory. {@code id path} being the path specified
|
||||
* in the identifier of this built-in resource pack.
|
||||
*
|
||||
* @param id the identifier of the resource pack
|
||||
* @param container the mod container
|
||||
* @param activationType the activation type of the resource pack
|
||||
* @return {@code true} if successfully registered the resource pack, else {@code false}
|
||||
*/
|
||||
static boolean registerBuiltinResourcePack(Identifier id, ModContainer container, ResourcePackActivationType activationType) {
|
||||
return ResourceManagerHelperImpl.registerBuiltinResourcePack(id, "resourcepacks/" + id.getPath(), container, activationType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a built-in resource pack.
|
||||
*
|
||||
|
@ -68,13 +88,17 @@ public interface ResourceManagerHelper {
|
|||
* <p>Note about the enabled by default parameter: a resource pack cannot be enabled by default, only data packs can.
|
||||
* Making this work for resource packs is near impossible without touching how Vanilla handles disabled resource packs.
|
||||
*
|
||||
* @param id The identifier of the resource pack.
|
||||
* @param subPath The sub path in the mod resources.
|
||||
* @param container The mod container.
|
||||
* @param enabledByDefault True if enabled by default, else false.
|
||||
* @return True if successfully registered the resource pack, else false.
|
||||
* @param id the identifier of the resource pack
|
||||
* @param subPath the sub path in the mod resources
|
||||
* @param container the mod container
|
||||
* @param enabledByDefault {@code true} if enabled by default, else {@code false}
|
||||
* @return {@code true} if successfully registered the resource pack, else {@code false}
|
||||
* @deprecated Please use {@link #registerBuiltinResourcePack(Identifier, ModContainer, ResourcePackActivationType)} instead, the {@code sub path} should be removed in a future
|
||||
* release in favor of the identifier path.
|
||||
*/
|
||||
@Deprecated
|
||||
static boolean registerBuiltinResourcePack(Identifier id, String subPath, ModContainer container, boolean enabledByDefault) {
|
||||
return ResourceManagerHelperImpl.registerBuiltinResourcePack(id, subPath, container, enabledByDefault);
|
||||
return ResourceManagerHelperImpl.registerBuiltinResourcePack(id, subPath, container,
|
||||
enabledByDefault ? ResourcePackActivationType.DEFAULT_ENABLED : ResourcePackActivationType.NORMAL);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.api.resource;
|
||||
|
||||
/**
|
||||
* Represents the resource pack activation type.
|
||||
*/
|
||||
public enum ResourcePackActivationType {
|
||||
/**
|
||||
* Normal activation. The user has full control over the activation of the resource pack.
|
||||
*/
|
||||
NORMAL,
|
||||
/**
|
||||
* Enabled by default. The user has still full control over the activation of the resource pack.
|
||||
*
|
||||
* <p>Note: this setting can only be satisfied on data packs, client resource packs cannot be by default enabled.
|
||||
*/
|
||||
DEFAULT_ENABLED,
|
||||
/**
|
||||
* Always enabled. The user cannot disable the resource pack.
|
||||
*/
|
||||
ALWAYS_ENABLED;
|
||||
|
||||
/**
|
||||
* Returns whether this resource pack will be enabled by default or not.
|
||||
*
|
||||
* @return {@code true} if enabled by default, else {@code false}
|
||||
*/
|
||||
public boolean isEnabledByDefault() {
|
||||
return this == DEFAULT_ENABLED || this == ALWAYS_ENABLED;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The Resource Loader, version 0.
|
||||
*
|
||||
* <p><h3>Quick note about vocabulary in Resource Loader and Minecraft:</h3>
|
||||
* <ul>
|
||||
* <li>Resource Pack refers to both client-sided resource pack and data pack.</li>
|
||||
* <li>Virtual Resource Pack refers to a resource pack that may be generated at runtime, or simply doesn't exist directly on disk.</li>
|
||||
* <li>Group Resource Pack refers to a virtual resource pack that groups multiple resource packs together.</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*
|
||||
* <p><h3>Modded Resource Pack Handling</h3></p>
|
||||
* <p>The Resource Loader will create a resource pack for each mod that provides resources in {@code assets} or {@code data}
|
||||
* sub-directories.
|
||||
* Those mod resource packs are grouped into a single always-enabled group resource pack which is shown in the resource pack screen.</p>
|
||||
*
|
||||
* <p><h4>Built-in Mod Resource Pack</h4></p>
|
||||
* <p>The Resource Loader adds manually registered mod resource packs. Those resource packs are registered with
|
||||
* {@link net.fabricmc.fabric.api.resource.ResourceManagerHelper#registerBuiltinResourcePack(net.minecraft.util.Identifier, net.fabricmc.loader.api.ModContainer, net.fabricmc.fabric.api.resource.ResourcePackActivationType)}</p>
|
||||
*
|
||||
* <p><h4>Programmer Art Resource Pack</h4></p>
|
||||
* <p>The Resource Loader will inject resources into the Programmer Art resource pack for each mod that provides
|
||||
* Programmer Art resources in the {@code programmer_art} top-level directory of the mod
|
||||
* whose structure is similar to a normal resource pack.</p>
|
||||
*
|
||||
* <p><h3>Resource Reload Listener</h3></p>
|
||||
* <p>The Resource Loader allows mods to register resource reload listeners through
|
||||
* {@link net.fabricmc.fabric.api.resource.ResourceManagerHelper#registerReloadListener(net.fabricmc.fabric.api.resource.IdentifiableResourceReloadListener)},
|
||||
* which are triggered when resources are reloaded.
|
||||
* A resource reload listener can depend on another and vanilla resource reload listener identifiers may be found in {@link net.fabricmc.fabric.api.resource.ResourceReloadListenerKeys}.</p>
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.api.resource;
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.impl.resource.loader;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import net.minecraft.SharedConstants;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.minecraft.resource.AbstractFileResourcePack;
|
||||
import net.minecraft.resource.ResourceType;
|
||||
import net.minecraft.resource.metadata.ResourceMetadataReader;
|
||||
|
||||
import net.fabricmc.fabric.api.resource.ModResourcePack;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
|
||||
/**
|
||||
* The Fabric mods resource pack, holds all the mod resource packs as one pack.
|
||||
*/
|
||||
public class FabricModResourcePack extends GroupResourcePack {
|
||||
public FabricModResourcePack(ResourceType type, List<ModResourcePack> packs) {
|
||||
super(type, packs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream openRoot(String fileName) throws IOException {
|
||||
if ("pack.mcmeta".equals(fileName)) {
|
||||
String description = "Mod resources.";
|
||||
String pack = String.format("{\"pack\":{\"pack_format\":" + type.getPackVersion(SharedConstants.getGameVersion()) + ",\"description\":\"%s\"}}", description);
|
||||
return IOUtils.toInputStream(pack, Charsets.UTF_8);
|
||||
} else if ("pack.png".equals(fileName)) {
|
||||
InputStream stream = FabricLoader.getInstance().getModContainer("fabric-resource-loader-v0")
|
||||
.flatMap(container -> container.getMetadata().getIconPath(512).map(container::getPath))
|
||||
.filter(Files::exists)
|
||||
.map(iconPath -> {
|
||||
try {
|
||||
return Files.newInputStream(iconPath);
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
}
|
||||
}).orElse(null);
|
||||
|
||||
if (stream != null) {
|
||||
return stream;
|
||||
}
|
||||
}
|
||||
|
||||
// ReloadableResourceManagerImpl gets away with FileNotFoundException.
|
||||
throw new FileNotFoundException("\"" + fileName + "\" in Fabric mod resource pack");
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> @Nullable T parseMetadata(ResourceMetadataReader<T> metaReader) throws IOException {
|
||||
try {
|
||||
InputStream inputStream = this.openRoot("pack.mcmeta");
|
||||
Throwable error = null;
|
||||
T metadata;
|
||||
|
||||
try {
|
||||
metadata = AbstractFileResourcePack.parseMetadata(metaReader, inputStream);
|
||||
} catch (Throwable e) {
|
||||
error = e;
|
||||
throw e;
|
||||
} finally {
|
||||
if (inputStream != null) {
|
||||
if (error != null) {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (Throwable e) {
|
||||
error.addSuppressed(e);
|
||||
}
|
||||
} else {
|
||||
inputStream.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return metadata;
|
||||
} catch (FileNotFoundException | RuntimeException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Fabric Mods";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.impl.resource.loader;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
|
||||
import net.minecraft.resource.Resource;
|
||||
import net.minecraft.resource.ResourceImpl;
|
||||
import net.minecraft.resource.ResourceNotFoundException;
|
||||
import net.minecraft.resource.ResourcePack;
|
||||
import net.minecraft.resource.ResourceType;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import net.fabricmc.fabric.api.resource.ModResourcePack;
|
||||
import net.fabricmc.fabric.mixin.resource.loader.NamespaceResourceManagerAccessor;
|
||||
|
||||
/**
|
||||
* Represents a group resource pack, holds multiple resource packs as one.
|
||||
*/
|
||||
public abstract class GroupResourcePack implements ResourcePack {
|
||||
protected final ResourceType type;
|
||||
protected final List<ModResourcePack> packs;
|
||||
protected final Object2ObjectMap<String, List<ModResourcePack>> namespacedPacks = new Object2ObjectOpenHashMap<>();
|
||||
|
||||
public GroupResourcePack(ResourceType type, List<ModResourcePack> packs) {
|
||||
this.type = type;
|
||||
this.packs = packs;
|
||||
this.packs.forEach(pack -> pack.getNamespaces(this.type)
|
||||
.forEach(namespace -> this.namespacedPacks.computeIfAbsent(namespace, value -> new ArrayList<>())
|
||||
.add(pack)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream open(ResourceType type, Identifier id) throws IOException {
|
||||
List<ModResourcePack> packs = this.namespacedPacks.get(id.getNamespace());
|
||||
|
||||
if (packs != null) {
|
||||
for (int i = packs.size() - 1; i >= 0; i--) {
|
||||
ResourcePack pack = packs.get(i);
|
||||
|
||||
if (pack.contains(type, id)) {
|
||||
return pack.open(type, id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new ResourceNotFoundException(null,
|
||||
String.format("%s/%s/%s", type.getDirectory(), id.getNamespace(), id.getPath()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Identifier> findResources(ResourceType type, String namespace, String prefix, int maxDepth, Predicate<String> pathFilter) {
|
||||
List<ModResourcePack> packs = this.namespacedPacks.get(namespace);
|
||||
|
||||
if (packs == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
Set<Identifier> resources = new HashSet<>();
|
||||
|
||||
for (int i = packs.size() - 1; i >= 0; i--) {
|
||||
ResourcePack pack = packs.get(i);
|
||||
Collection<Identifier> modResources = pack.findResources(type, namespace, prefix, maxDepth, pathFilter);
|
||||
|
||||
resources.addAll(modResources);
|
||||
}
|
||||
|
||||
return resources;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(ResourceType type, Identifier id) {
|
||||
List<ModResourcePack> packs = this.namespacedPacks.get(id.getNamespace());
|
||||
|
||||
if (packs == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = packs.size() - 1; i >= 0; i--) {
|
||||
ResourcePack pack = packs.get(i);
|
||||
|
||||
if (pack.contains(type, id)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getNamespaces(ResourceType type) {
|
||||
return this.namespacedPacks.keySet();
|
||||
}
|
||||
|
||||
public void appendResources(NamespaceResourceManagerAccessor manager, Identifier id, List<Resource> resources) throws IOException {
|
||||
List<ModResourcePack> packs = this.namespacedPacks.get(id.getNamespace());
|
||||
|
||||
if (packs == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Identifier metadataId = NamespaceResourceManagerAccessor.fabric$accessor_getMetadataPath(id);
|
||||
|
||||
for (ModResourcePack pack : packs) {
|
||||
if (pack.contains(manager.getType(), id)) {
|
||||
InputStream metadataInputStream = pack.contains(manager.getType(), metadataId) ? manager.fabric$accessor_open(metadataId, pack) : null;
|
||||
resources.add(new ResourceImpl(pack.getName(), id, manager.fabric$accessor_open(id, pack), metadataInputStream));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getFullName() {
|
||||
return this.getName() + " (" + this.packs.stream().map(ResourcePack::getName).collect(Collectors.joining(", ")) + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
this.packs.forEach(ResourcePack::close);
|
||||
}
|
||||
}
|
|
@ -40,6 +40,7 @@ import net.minecraft.util.Identifier;
|
|||
import net.minecraft.util.InvalidIdentifierException;
|
||||
|
||||
import net.fabricmc.fabric.api.resource.ModResourcePack;
|
||||
import net.fabricmc.fabric.api.resource.ResourcePackActivationType;
|
||||
import net.fabricmc.loader.api.metadata.ModMetadata;
|
||||
|
||||
public class ModNioResourcePack extends AbstractFileResourcePack implements ModResourcePack {
|
||||
|
@ -51,9 +52,9 @@ public class ModNioResourcePack extends AbstractFileResourcePack implements ModR
|
|||
private final boolean cacheable;
|
||||
private final AutoCloseable closer;
|
||||
private final String separator;
|
||||
private final boolean defaultEnabled;
|
||||
private final ResourcePackActivationType activationType;
|
||||
|
||||
public ModNioResourcePack(ModMetadata modInfo, Path path, ResourceType type, AutoCloseable closer, boolean defaultEnabled) {
|
||||
public ModNioResourcePack(ModMetadata modInfo, Path path, ResourceType type, AutoCloseable closer, ResourcePackActivationType activationType) {
|
||||
super(null);
|
||||
this.modInfo = modInfo;
|
||||
this.basePath = path.toAbsolutePath().normalize();
|
||||
|
@ -61,8 +62,7 @@ public class ModNioResourcePack extends AbstractFileResourcePack implements ModR
|
|||
this.cacheable = false; /* TODO */
|
||||
this.closer = closer;
|
||||
this.separator = basePath.getFileSystem().getSeparator();
|
||||
// Specific to registered built-in resource packs.
|
||||
this.defaultEnabled = defaultEnabled;
|
||||
this.activationType = activationType;
|
||||
}
|
||||
|
||||
private Path getPath(String filename) {
|
||||
|
@ -203,8 +203,8 @@ public class ModNioResourcePack extends AbstractFileResourcePack implements ModR
|
|||
return modInfo;
|
||||
}
|
||||
|
||||
public boolean shouldBeEnabledByDefault() {
|
||||
return this.defaultEnabled;
|
||||
public ResourcePackActivationType getActivationType() {
|
||||
return this.activationType;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -20,7 +20,6 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import net.minecraft.resource.ResourcePack;
|
||||
import net.minecraft.resource.ResourcePackProfile;
|
||||
import net.minecraft.resource.ResourcePackProvider;
|
||||
import net.minecraft.resource.ResourcePackSource;
|
||||
|
@ -68,19 +67,16 @@ public class ModResourcePackCreator implements ResourcePackProvider {
|
|||
*/
|
||||
|
||||
// Build a list of mod resource packs.
|
||||
List<ResourcePack> packs = new ArrayList<>();
|
||||
ModResourcePackUtil.appendModResourcePacks(packs, type);
|
||||
|
||||
for (ResourcePack pack : packs) {
|
||||
if (!(pack instanceof ModResourcePack)) {
|
||||
throw new RuntimeException("Not a ModResourcePack!");
|
||||
}
|
||||
List<ModResourcePack> packs = new ArrayList<>();
|
||||
ModResourcePackUtil.appendModResourcePacks(packs, type, null);
|
||||
|
||||
if (!packs.isEmpty()) {
|
||||
// Make the resource pack profile for mod resource packs.
|
||||
// Mod resource packs must always be enabled to avoid issues
|
||||
// and inserted on top to ensure that they are applied before user resource packs and after default/programmer art resource pack.
|
||||
ResourcePackProfile resourcePackProfile = ResourcePackProfile.of("fabric/" + ((ModResourcePack) pack).getFabricModMetadata().getId(),
|
||||
true, () -> pack, factory, ResourcePackProfile.InsertionPosition.TOP,
|
||||
// @TODO: "inserted on top" comment is deprecated, it does not guarantee the condition "applied before user resource packs".
|
||||
ResourcePackProfile resourcePackProfile = ResourcePackProfile.of("Fabric Mods",
|
||||
true, () -> new FabricModResourcePack(this.type, packs), factory, ResourcePackProfile.InsertionPosition.TOP,
|
||||
RESOURCE_PACK_SOURCE);
|
||||
|
||||
if (resourcePackProfile != null) {
|
||||
|
|
|
@ -17,16 +17,19 @@
|
|||
package net.fabricmc.fabric.impl.resource.loader;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.minecraft.SharedConstants;
|
||||
import net.minecraft.resource.ResourcePack;
|
||||
import net.minecraft.resource.ResourceType;
|
||||
|
||||
import net.fabricmc.fabric.api.resource.ModResourcePack;
|
||||
import net.fabricmc.fabric.api.resource.ResourcePackActivationType;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.fabricmc.loader.api.ModContainer;
|
||||
import net.fabricmc.loader.api.metadata.ModMetadata;
|
||||
|
@ -35,19 +38,39 @@ import net.fabricmc.loader.api.metadata.ModMetadata;
|
|||
* Internal utilities for managing resource packs.
|
||||
*/
|
||||
public final class ModResourcePackUtil {
|
||||
private ModResourcePackUtil() { }
|
||||
|
||||
public static void appendModResourcePacks(List<ResourcePack> packList, ResourceType type) {
|
||||
private ModResourcePackUtil() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends mod resource packs to the given list.
|
||||
*
|
||||
* @param packs the resource pack list to append
|
||||
* @param type the type of resource
|
||||
* @param subPath the resource pack sub path directory in mods, may be {@code null}
|
||||
*/
|
||||
public static void appendModResourcePacks(List<ModResourcePack> packs, ResourceType type, @Nullable String subPath) {
|
||||
for (ModContainer container : FabricLoader.getInstance().getAllMods()) {
|
||||
if (container.getMetadata().getType().equals("builtin")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Path path = container.getRootPath();
|
||||
ResourcePack pack = new ModNioResourcePack(container.getMetadata(), path, type, null, true);
|
||||
|
||||
if (subPath != null) {
|
||||
Path childPath = path.resolve(subPath.replaceAll("/", path.getFileSystem().getSeparator())).toAbsolutePath().normalize();
|
||||
|
||||
if (!childPath.startsWith(path) || !Files.exists(childPath)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
path = childPath;
|
||||
}
|
||||
|
||||
ModResourcePack pack = new ModNioResourcePack(container.getMetadata(), path, type, null, ResourcePackActivationType.ALWAYS_ENABLED);
|
||||
|
||||
if (!pack.getNamespaces(type).isEmpty()) {
|
||||
packList.add(pack);
|
||||
packs.add(pack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@ import net.minecraft.util.Pair;
|
|||
|
||||
import net.fabricmc.fabric.api.resource.IdentifiableResourceReloadListener;
|
||||
import net.fabricmc.fabric.api.resource.ResourceManagerHelper;
|
||||
import net.fabricmc.fabric.api.resource.ResourcePackActivationType;
|
||||
import net.fabricmc.loader.api.ModContainer;
|
||||
|
||||
public class ResourceManagerHelperImpl implements ResourceManagerHelper {
|
||||
|
@ -57,14 +58,15 @@ public class ResourceManagerHelperImpl implements ResourceManagerHelper {
|
|||
/**
|
||||
* Registers a built-in resource pack. Internal implementation.
|
||||
*
|
||||
* @param id The identifier of the resource pack.
|
||||
* @param subPath The sub path in the mod resources.
|
||||
* @param container The mod container.
|
||||
* @param enabledByDefault True if enabled by default, else false.
|
||||
* @return True if successfully registered the resource pack, else false.
|
||||
* @param id the identifier of the resource pack
|
||||
* @param subPath the sub path in the mod resources
|
||||
* @param container the mod container
|
||||
* @param activationType the activation type of the resource pack
|
||||
* @return {@code true} if successfully registered the resource pack, else {@code false}
|
||||
* @see ResourceManagerHelper#registerBuiltinResourcePack(Identifier, ModContainer, ResourcePackActivationType)
|
||||
* @see ResourceManagerHelper#registerBuiltinResourcePack(Identifier, String, ModContainer, boolean)
|
||||
*/
|
||||
public static boolean registerBuiltinResourcePack(Identifier id, String subPath, ModContainer container, boolean enabledByDefault) {
|
||||
public static boolean registerBuiltinResourcePack(Identifier id, String subPath, ModContainer container, ResourcePackActivationType activationType) {
|
||||
String separator = container.getRootPath().getFileSystem().getSeparator();
|
||||
subPath = subPath.replace("/", separator);
|
||||
|
||||
|
@ -76,14 +78,14 @@ public class ResourceManagerHelperImpl implements ResourceManagerHelper {
|
|||
|
||||
String name = id.getNamespace() + "/" + id.getPath();
|
||||
|
||||
builtinResourcePacks.add(new Pair<>(name, new ModNioResourcePack(container.getMetadata(), resourcePackPath, ResourceType.CLIENT_RESOURCES, null, enabledByDefault) {
|
||||
builtinResourcePacks.add(new Pair<>(name, new ModNioResourcePack(container.getMetadata(), resourcePackPath, ResourceType.CLIENT_RESOURCES, null, activationType) {
|
||||
@Override
|
||||
public String getName() {
|
||||
return name; // Built-in resource pack provided by a mod, the name is overriden.
|
||||
}
|
||||
}));
|
||||
|
||||
builtinResourcePacks.add(new Pair<>(name, new ModNioResourcePack(container.getMetadata(), resourcePackPath, ResourceType.SERVER_DATA, null, enabledByDefault) {
|
||||
builtinResourcePacks.add(new Pair<>(name, new ModNioResourcePack(container.getMetadata(), resourcePackPath, ResourceType.SERVER_DATA, null, activationType) {
|
||||
@Override
|
||||
public String getName() {
|
||||
return name; // Built-in resource pack provided by a mod, the name is overriden.
|
||||
|
@ -96,10 +98,13 @@ public class ResourceManagerHelperImpl implements ResourceManagerHelper {
|
|||
public static void registerBuiltinResourcePacks(ResourceType resourceType, Consumer<ResourcePackProfile> consumer, ResourcePackProfile.Factory factory) {
|
||||
// Loop through each registered built-in resource packs and add them if valid.
|
||||
for (Pair<String, ModNioResourcePack> entry : builtinResourcePacks) {
|
||||
ModNioResourcePack pack = entry.getRight();
|
||||
|
||||
// Add the built-in pack only if namespaces for the specified resource type are present.
|
||||
if (!entry.getRight().getNamespaces(resourceType).isEmpty()) {
|
||||
if (!pack.getNamespaces(resourceType).isEmpty()) {
|
||||
// Make the resource pack profile for built-in pack, should never be always enabled.
|
||||
ResourcePackProfile profile = ResourcePackProfile.of(entry.getLeft(), false,
|
||||
ResourcePackProfile profile = ResourcePackProfile.of(entry.getLeft(),
|
||||
pack.getActivationType() == ResourcePackActivationType.ALWAYS_ENABLED,
|
||||
entry::getRight, factory, ResourcePackProfile.InsertionPosition.TOP, ResourcePackSource.PACK_SOURCE_BUILTIN);
|
||||
if (profile != null) {
|
||||
consumer.accept(profile);
|
||||
|
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.impl.resource.loader.client.pack;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.minecraft.resource.AbstractFileResourcePack;
|
||||
import net.minecraft.resource.ResourceType;
|
||||
import net.minecraft.resource.metadata.ResourceMetadataReader;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.resource.ModResourcePack;
|
||||
import net.fabricmc.fabric.impl.resource.loader.GroupResourcePack;
|
||||
|
||||
/**
|
||||
* Represents the Programmer Art resource pack with support for modded content.
|
||||
*
|
||||
* <p>Any vanilla resources are provided like in Vanilla through the original programmer art, any missing resources
|
||||
* will be searched in the provided modded resource packs.
|
||||
*/
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class ProgrammerArtResourcePack extends GroupResourcePack {
|
||||
private final AbstractFileResourcePack originalResourcePack;
|
||||
|
||||
public ProgrammerArtResourcePack(AbstractFileResourcePack originalResourcePack, List<ModResourcePack> modResourcePacks) {
|
||||
super(ResourceType.CLIENT_RESOURCES, modResourcePacks);
|
||||
this.originalResourcePack = originalResourcePack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream openRoot(String fileName) throws IOException {
|
||||
if (!fileName.contains("/") && !fileName.contains("\\")) {
|
||||
// There should be nothing to read at the root of mod's Programmer Art extensions.
|
||||
return this.originalResourcePack.openRoot(fileName);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Root resources can only be filenames, not paths (no / allowed!)");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream open(ResourceType type, Identifier id) throws IOException {
|
||||
if (this.originalResourcePack.contains(type, id)) {
|
||||
return this.originalResourcePack.open(type, id);
|
||||
}
|
||||
|
||||
return super.open(type, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Identifier> findResources(ResourceType type, String namespace, String prefix, int maxDepth, Predicate<String> pathFilter) {
|
||||
Set<Identifier> resources = new HashSet<>(this.originalResourcePack.findResources(type, namespace, prefix, maxDepth, pathFilter));
|
||||
|
||||
resources.addAll(super.findResources(type, namespace, prefix, maxDepth, pathFilter));
|
||||
|
||||
return resources;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(ResourceType type, Identifier id) {
|
||||
return this.originalResourcePack.contains(type, id) || super.contains(type, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getNamespaces(ResourceType type) {
|
||||
Set<String> namespaces = this.originalResourcePack.getNamespaces(type);
|
||||
|
||||
namespaces.addAll(super.getNamespaces(type));
|
||||
|
||||
return namespaces;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> @Nullable T parseMetadata(ResourceMetadataReader<T> metaReader) throws IOException {
|
||||
return this.originalResourcePack.parseMetadata(metaReader);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Programmer Art";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
this.originalResourcePack.close();
|
||||
super.close();
|
||||
}
|
||||
}
|
|
@ -46,7 +46,7 @@ public class MinecraftServerMixin {
|
|||
if (((ResourcePackProfileAccessor) profile).getResourcePackSource() == ResourcePackSource.PACK_SOURCE_BUILTIN && !profileName.equals("vanilla")) {
|
||||
ResourcePack pack = profile.createResourcePack();
|
||||
// Prevents automatic load for built-in data packs provided by mods.
|
||||
return pack instanceof ModNioResourcePack && !((ModNioResourcePack) pack).shouldBeEnabledByDefault();
|
||||
return pack instanceof ModNioResourcePack && !((ModNioResourcePack) pack).getActivationType().isEnabledByDefault();
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.mixin.resource.loader;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
|
||||
import net.minecraft.resource.NamespaceResourceManager;
|
||||
import net.minecraft.resource.ResourcePack;
|
||||
import net.minecraft.resource.ResourceType;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
@Mixin(NamespaceResourceManager.class)
|
||||
public interface NamespaceResourceManagerAccessor {
|
||||
@Accessor("type")
|
||||
ResourceType getType();
|
||||
|
||||
@Invoker("open")
|
||||
InputStream fabric$accessor_open(Identifier id, ResourcePack pack) throws IOException;
|
||||
|
||||
@Invoker("getMetadataPath")
|
||||
static Identifier fabric$accessor_getMetadataPath(Identifier id) {
|
||||
throw new UnsupportedOperationException("Invoker injection failed.");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.mixin.resource.loader;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||
|
||||
import net.minecraft.resource.NamespaceResourceManager;
|
||||
import net.minecraft.resource.Resource;
|
||||
import net.minecraft.resource.ResourcePack;
|
||||
import net.minecraft.resource.ResourceType;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import net.fabricmc.fabric.impl.resource.loader.GroupResourcePack;
|
||||
|
||||
@Mixin(NamespaceResourceManager.class)
|
||||
public class NamespaceResourceManagerMixin {
|
||||
private final ThreadLocal<List<Resource>> fabric$getAllResources$resources = new ThreadLocal<>();
|
||||
|
||||
@Inject(
|
||||
method = "getAllResources",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/resource/NamespaceResourceManager;getMetadataPath(Lnet/minecraft/util/Identifier;)Lnet/minecraft/util/Identifier;"
|
||||
),
|
||||
locals = LocalCapture.CAPTURE_FAILHARD
|
||||
)
|
||||
private void onGetAllResources(Identifier id, CallbackInfoReturnable<List<Resource>> cir, List<Resource> resources) {
|
||||
this.fabric$getAllResources$resources.set(resources);
|
||||
}
|
||||
|
||||
@Redirect(
|
||||
method = "getAllResources",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/resource/ResourcePack;contains(Lnet/minecraft/resource/ResourceType;Lnet/minecraft/util/Identifier;)Z"
|
||||
)
|
||||
)
|
||||
private boolean onResourceAdd(ResourcePack pack, ResourceType type, Identifier id) throws IOException {
|
||||
if (pack instanceof GroupResourcePack) {
|
||||
((GroupResourcePack) pack).appendResources((NamespaceResourceManagerAccessor) this, id, this.fabric$getAllResources$resources.get());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return pack.contains(type, id);
|
||||
}
|
||||
}
|
|
@ -19,6 +19,7 @@ package net.fabricmc.fabric.mixin.resource.loader;
|
|||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
@ -28,12 +29,14 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
|||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import net.minecraft.resource.ReloadableResourceManagerImpl;
|
||||
import net.minecraft.resource.ResourcePack;
|
||||
import net.minecraft.resource.ResourceReloadListener;
|
||||
import net.minecraft.resource.ResourceType;
|
||||
import net.minecraft.resource.ResourcePack;
|
||||
import net.minecraft.resource.ResourceReloadMonitor;
|
||||
import net.minecraft.util.Unit;
|
||||
|
||||
import net.fabricmc.fabric.impl.resource.loader.GroupResourcePack;
|
||||
import net.fabricmc.fabric.impl.resource.loader.ResourceManagerHelperImpl;
|
||||
|
||||
@Mixin(ReloadableResourceManagerImpl.class)
|
||||
|
@ -47,7 +50,20 @@ public class ReloadableResourceManagerImplMixin {
|
|||
private List<ResourceReloadListener> listeners;
|
||||
|
||||
@Inject(at = @At(value = "INVOKE", target = "Lorg/apache/logging/log4j/Logger;isDebugEnabled()Z", remap = false), method = "beginMonitoredReload")
|
||||
public void reload(Executor prepareExecutor, Executor applyExecutor, CompletableFuture<Unit> initialStage, List<ResourcePack> packs, CallbackInfoReturnable<ResourceReloadMonitor> info) {
|
||||
private void reload(Executor prepareExecutor, Executor applyExecutor, CompletableFuture<Unit> initialStage, List<ResourcePack> packs, CallbackInfoReturnable<ResourceReloadMonitor> info) {
|
||||
ResourceManagerHelperImpl.sort(type, this.listeners);
|
||||
}
|
||||
|
||||
// private static synthetic method_29491(Ljava/util/List;)Ljava/lang/Object;
|
||||
// Supplier lambda in beginMonitoredReload method.
|
||||
@Inject(method = "method_29491", at = @At("HEAD"), cancellable = true)
|
||||
private static void getResourcePackNames(List<ResourcePack> packs, CallbackInfoReturnable<String> cir) {
|
||||
cir.setReturnValue(packs.stream().map(pack -> {
|
||||
if (pack instanceof GroupResourcePack) {
|
||||
return ((GroupResourcePack) pack).getFullName();
|
||||
} else {
|
||||
return pack.getName();
|
||||
}
|
||||
}).collect(Collectors.joining(", ")));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,17 +16,27 @@
|
|||
|
||||
package net.fabricmc.fabric.mixin.resource.loader.client;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import net.minecraft.resource.AbstractFileResourcePack;
|
||||
import net.minecraft.resource.ResourcePack;
|
||||
import net.minecraft.resource.ResourcePackProfile;
|
||||
import net.minecraft.client.resource.ClientBuiltinResourcePackProvider;
|
||||
import net.minecraft.resource.ResourceType;
|
||||
|
||||
import net.fabricmc.fabric.api.resource.ModResourcePack;
|
||||
import net.fabricmc.fabric.impl.resource.loader.ModResourcePackCreator;
|
||||
import net.fabricmc.fabric.impl.resource.loader.ModResourcePackUtil;
|
||||
import net.fabricmc.fabric.impl.resource.loader.client.pack.ProgrammerArtResourcePack;
|
||||
|
||||
@Mixin(ClientBuiltinResourcePackProvider.class)
|
||||
public class ClientBuiltinResourcePackProviderMixin {
|
||||
|
@ -35,4 +45,24 @@ public class ClientBuiltinResourcePackProviderMixin {
|
|||
// Register mod and built-in resource packs after the vanilla built-in resource packs are registered.
|
||||
ModResourcePackCreator.CLIENT_RESOURCE_PACK_PROVIDER.register(consumer, factory);
|
||||
}
|
||||
|
||||
// ClientBuiltinResourcePackProvider#method_25454 first lambda.
|
||||
@Inject(method = "method_25457", at = @At("RETURN"), cancellable = true)
|
||||
private static void onSupplyZipProgrammerArtPack(File file, CallbackInfoReturnable<ResourcePack> cir) {
|
||||
AbstractFileResourcePack originalPack = (AbstractFileResourcePack) cir.getReturnValue();
|
||||
cir.setReturnValue(new ProgrammerArtResourcePack(originalPack, getProgrammerArtModResourcePacks()));
|
||||
}
|
||||
|
||||
// ClientBuiltinResourcePackProvider#method_25454 second lambda.
|
||||
@Inject(method = "method_25456", at = @At("RETURN"), cancellable = true)
|
||||
private static void onSupplyDirProgrammerArtPack(File file, CallbackInfoReturnable<ResourcePack> cir) {
|
||||
AbstractFileResourcePack originalPack = (AbstractFileResourcePack) cir.getReturnValue();
|
||||
cir.setReturnValue(new ProgrammerArtResourcePack(originalPack, getProgrammerArtModResourcePacks()));
|
||||
}
|
||||
|
||||
private static List<ModResourcePack> getProgrammerArtModResourcePacks() {
|
||||
List<ModResourcePack> packs = new ArrayList<>();
|
||||
ModResourcePackUtil.appendModResourcePacks(packs, ResourceType.CLIENT_RESOURCES, "programmer_art");
|
||||
return packs;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ public class CreateWorldScreenMixin {
|
|||
for (ResourcePackProfile profile : moddedResourcePacks) {
|
||||
ResourcePack pack = profile.createResourcePack();
|
||||
|
||||
if (pack instanceof ModNioResourcePack && ((ModNioResourcePack) pack).shouldBeEnabledByDefault()) {
|
||||
if (pack instanceof ModNioResourcePack && ((ModNioResourcePack) pack).getActivationType().isEnabledByDefault()) {
|
||||
enabled.add(profile.getName());
|
||||
} else {
|
||||
disabled.add(profile.getName());
|
||||
|
|
|
@ -48,7 +48,7 @@ public class GameOptionsMixin {
|
|||
for (ResourcePackProfile profile : profiles) {
|
||||
ResourcePack pack = profile.createResourcePack();
|
||||
if (profile.getSource() == ModResourcePackCreator.RESOURCE_PACK_SOURCE
|
||||
|| (pack instanceof ModNioResourcePack && ((ModNioResourcePack) pack).shouldBeEnabledByDefault())) {
|
||||
|| (pack instanceof ModNioResourcePack && ((ModNioResourcePack) pack).getActivationType().isEnabledByDefault())) {
|
||||
this.resourcePacks.add(profile.getName());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.mixin.resource.loader.client;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import net.minecraft.client.gui.screen.pack.PackListWidget;
|
||||
import net.minecraft.client.gui.screen.pack.PackScreen;
|
||||
import net.minecraft.client.gui.screen.pack.ResourcePackOrganizer;
|
||||
|
||||
import net.fabricmc.fabric.impl.resource.loader.ModResourcePackCreator;
|
||||
|
||||
@Mixin(PackScreen.class)
|
||||
public class PackScreenMixin {
|
||||
@Inject(method = "method_29672", at = @At("HEAD"), cancellable = true)
|
||||
private void addPackEntry(PackListWidget packListWidget, ResourcePackOrganizer.Pack pack, CallbackInfo info) {
|
||||
// Every mod resource packs should be hidden from the user.
|
||||
// Registered built-in resource packs should not be hidden as they are optional for the user.
|
||||
if (pack.getSource() == ModResourcePackCreator.RESOURCE_PACK_SOURCE) {
|
||||
info.cancel();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,6 +7,8 @@
|
|||
"DefaultResourcePackMixin",
|
||||
"KeyedResourceReloadListenerMixin",
|
||||
"MinecraftServerMixin",
|
||||
"NamespaceResourceManagerAccessor",
|
||||
"NamespaceResourceManagerMixin",
|
||||
"ReloadableResourceManagerImplMixin",
|
||||
"ResourcePackManagerMixin",
|
||||
"ResourcePackManagerAccessor",
|
||||
|
@ -17,8 +19,7 @@
|
|||
"client.CreateWorldScreenMixin",
|
||||
"client.FontManagerResourceReloadListenerMixin",
|
||||
"client.GameOptionsMixin",
|
||||
"client.KeyedResourceReloadListenerClientMixin",
|
||||
"client.PackScreenMixin"
|
||||
"client.KeyedResourceReloadListenerClientMixin"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
|
|
|
@ -23,6 +23,7 @@ import net.minecraft.util.Identifier;
|
|||
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.fabricmc.fabric.api.resource.ResourceManagerHelper;
|
||||
import net.fabricmc.fabric.api.resource.ResourcePackActivationType;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
|
||||
public class BuiltinResourcePackTestMod implements ModInitializer {
|
||||
|
@ -34,7 +35,8 @@ public class BuiltinResourcePackTestMod implements ModInitializer {
|
|||
public void onInitialize() {
|
||||
// Should always be present as it's **this** mod.
|
||||
FabricLoader.getInstance().getModContainer(MODID)
|
||||
.map(container -> ResourceManagerHelper.registerBuiltinResourcePack(new Identifier(MODID, "test"), "resourcepacks/test", container, false))
|
||||
.map(container -> ResourceManagerHelper.registerBuiltinResourcePack(new Identifier(MODID, "test"),
|
||||
container, ResourcePackActivationType.NORMAL))
|
||||
.filter(success -> !success).ifPresent(success -> LOGGER.warn("Could not register built-in resource pack."));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"pack": {
|
||||
"pack_format": 6,
|
||||
"pack_format": 7,
|
||||
"description": "Fabric Resource Loader Test Builtin Pack."
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue