Restore Programmer Art injection support (1.19.3) ()

* Restore Programmer Art resource pack injection support

* Add Programmer Art injection testmod

* Fix license formatting

* Remove unnecessary `@Environment` annotation
This commit is contained in:
Julian Burner 2023-03-15 13:00:49 +01:00 committed by GitHub
parent 93582b958a
commit 68296ad5e5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 233 additions and 7 deletions
fabric-resource-loader-v0/src
client
java/net/fabricmc/fabric
impl/client/resource/loader
mixin/resource/loader/client
resources
main/java/net/fabricmc/fabric/impl/resource/loader
testmod
java/net/fabricmc/fabric/test/resource/loader
resources
assets/fabric-resource-loader-v0-testmod
blockstates
models
textures/block
fabric.mod.json
programmer_art/assets/fabric-resource-loader-v0-testmod/textures/block

View file

@ -0,0 +1,98 @@
/*
* 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.client.resource.loader;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Set;
import org.jetbrains.annotations.Nullable;
import net.minecraft.resource.AbstractFileResourcePack;
import net.minecraft.resource.InputSupplier;
import net.minecraft.resource.ResourceType;
import net.minecraft.resource.metadata.ResourceMetadataReader;
import net.minecraft.util.Identifier;
import net.minecraft.util.PathUtil;
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.
*/
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 InputSupplier<InputStream> openRoot(String... pathSegments) {
PathUtil.validatePath(pathSegments);
return this.originalResourcePack.openRoot(String.join("/", pathSegments));
}
@Override
public InputSupplier<InputStream> open(ResourceType type, Identifier id) {
InputSupplier<InputStream> originalPackData = this.originalResourcePack.open(type, id);
if (originalPackData != null) {
return originalPackData;
}
return super.open(type, id);
}
@Override
public void findResources(ResourceType type, String namespace, String prefix, ResultConsumer consumer) {
super.findResources(type, namespace, prefix, consumer);
this.originalResourcePack.findResources(type, namespace, prefix, consumer);
}
@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();
}
}

View file

@ -0,0 +1,65 @@
/*
* 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 java.util.ArrayList;
import java.util.List;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyArg;
import net.minecraft.client.resource.DefaultClientResourcePackProvider;
import net.minecraft.resource.AbstractFileResourcePack;
import net.minecraft.resource.ResourcePackProfile;
import net.minecraft.resource.ResourcePackSource;
import net.minecraft.resource.ResourceType;
import net.minecraft.text.Text;
import net.fabricmc.fabric.api.resource.ModResourcePack;
import net.fabricmc.fabric.impl.client.resource.loader.ProgrammerArtResourcePack;
import net.fabricmc.fabric.impl.resource.loader.ModResourcePackUtil;
@Mixin(DefaultClientResourcePackProvider.class)
public class DefaultClientResourcePackProviderMixin {
/**
* Injects into the method which registers/creates the Programmer Art resource pack,
* and replaces the local {@link net.minecraft.resource.ResourcePackProfile.PackFactory}
* instance with our custom Programmer Art wrapper that supports loading from mods.
*/
@ModifyArg(
method = "create(Ljava/lang/String;Lnet/minecraft/resource/ResourcePackProfile$PackFactory;Lnet/minecraft/text/Text;)Lnet/minecraft/resource/ResourcePackProfile;",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/resource/ResourcePackProfile;create(Ljava/lang/String;Lnet/minecraft/text/Text;ZLnet/minecraft/resource/ResourcePackProfile$PackFactory;Lnet/minecraft/resource/ResourceType;Lnet/minecraft/resource/ResourcePackProfile$InsertionPosition;Lnet/minecraft/resource/ResourcePackSource;)Lnet/minecraft/resource/ResourcePackProfile;"
),
index = 3
)
private ResourcePackProfile.PackFactory onCreateProgrammerArtResourcePack(String name, Text displayName, boolean alwaysEnabled,
ResourcePackProfile.PackFactory packFactory, ResourceType type, ResourcePackProfile.InsertionPosition position, ResourcePackSource source) {
return factory -> new ProgrammerArtResourcePack((AbstractFileResourcePack) packFactory.open(name), getProgrammerArtModResourcePacks());
}
/**
* {@return} all baked-in mod resource packs that provide Programmer Art resources.
*/
private static List<ModResourcePack> getProgrammerArtModResourcePacks() {
List<ModResourcePack> packs = new ArrayList<>();
ModResourcePackUtil.appendModResourcePacks(packs, ResourceType.CLIENT_RESOURCES, "programmer_art");
return packs;
}
}

View file

@ -4,6 +4,7 @@
"compatibilityLevel": "JAVA_16",
"client": [
"VanillaResourcePackProviderMixin",
"DefaultClientResourcePackProviderMixin",
"CreateWorldScreenMixin",
"FontManagerMixin",
"GameOptionsMixin",

View file

@ -70,13 +70,17 @@ public abstract class GroupResourcePack implements ResourcePack {
}
@Override
public void findResources(ResourceType type, String namespace, String prefix, ResultConsumer arg) {
public void findResources(ResourceType type, String namespace, String prefix, ResultConsumer consumer) {
List<ModResourcePack> packs = this.namespacedPacks.get(namespace);
if (packs == null) {
return;
}
for (int i = packs.size() - 1; i >= 0; i--) {
ResourcePack pack = packs.get(i);
pack.findResources(type, namespace, prefix, arg);
pack.findResources(type, namespace, prefix, consumer);
}
}

View file

@ -76,9 +76,8 @@ public class ModResourcePackCreator implements ResourcePackProvider {
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.
// @TODO: "inserted on top" comment is deprecated, it does not guarantee the condition "applied before user resource packs".
// Mod resource packs must always be enabled to avoid issues, and they are inserted
// on top to ensure that they are applied after vanilla built-in resource packs.
MutableText title = Text.translatable("pack.name.fabricMods");
ResourcePackProfile resourcePackProfile = ResourcePackProfile.create("fabric", title,
true, factory -> new FabricModResourcePack(this.type, packs), type, ResourcePackProfile.InsertionPosition.TOP,

View file

@ -68,7 +68,7 @@ public final class ModResourcePackUtil {
continue;
}
ModResourcePack pack = ModNioResourcePack.create(new Identifier("fabric", container.getMetadata().getId()), getName(container.getMetadata()), container, null, type, ResourcePackActivationType.ALWAYS_ENABLED);
ModResourcePack pack = ModNioResourcePack.create(new Identifier("fabric", container.getMetadata().getId()), getName(container.getMetadata()), container, subPath, type, ResourcePackActivationType.ALWAYS_ENABLED);
if (pack != null) {
packs.add(pack);

View file

@ -0,0 +1,42 @@
/*
* 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.test.resource.loader;
import net.minecraft.block.AbstractBlock;
import net.minecraft.block.Block;
import net.minecraft.block.Blocks;
import net.minecraft.item.BlockItem;
import net.minecraft.item.Item;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.util.Identifier;
import net.fabricmc.api.ModInitializer;
public class VanillaBuiltinResourcePackInjectionTestMod implements ModInitializer {
public static final String MODID = "fabric-resource-loader-v0-testmod";
public static final Block TEST_BLOCK = new Block(AbstractBlock.Settings.copy(Blocks.STONE));
@Override
public void onInitialize() {
Identifier id = new Identifier(MODID, "testblock");
Registry.register(Registries.BLOCK, id, TEST_BLOCK);
Registry.register(Registries.ITEM, id, new BlockItem(TEST_BLOCK, new Item.Settings()));
}
}

View file

@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "fabric-resource-loader-v0-testmod:block/testblock"
}
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "block/cube_all",
"textures": {
"all": "fabric-resource-loader-v0-testmod:block/testblock"
}
}

View file

@ -0,0 +1,3 @@
{
"parent": "fabric-resource-loader-v0-testmod:block/testblock"
}

View file

@ -11,7 +11,8 @@
"entrypoints": {
"main": [
"net.fabricmc.fabric.test.resource.loader.BuiltinResourcePackTestMod",
"net.fabricmc.fabric.test.resource.loader.ResourceReloadListenerTestMod"
"net.fabricmc.fabric.test.resource.loader.ResourceReloadListenerTestMod",
"net.fabricmc.fabric.test.resource.loader.VanillaBuiltinResourcePackInjectionTestMod"
],
"server": [
"net.fabricmc.fabric.test.resource.loader.LanguageTestMod"