diff options
-rw-r--r-- | gradle.properties | 2 | ||||
-rw-r--r-- | src/main/java/com/anthonyhilyard/iceberg/util/DynamicResourcePack.java | 151 |
2 files changed, 152 insertions, 1 deletions
diff --git a/gradle.properties b/gradle.properties index ae93acc..4bc6215 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,6 +6,6 @@ org.gradle.daemon=false name=${rootProject.name} group=com.anthonyhilyard.${name.toLowerCase()} author=anthonyhilyard -version=1.0.24 +version=1.0.25 mcVersion=1.17.1 forgeVersion=37.0.90 diff --git a/src/main/java/com/anthonyhilyard/iceberg/util/DynamicResourcePack.java b/src/main/java/com/anthonyhilyard/iceberg/util/DynamicResourcePack.java new file mode 100644 index 0000000..127fc60 --- /dev/null +++ b/src/main/java/com/anthonyhilyard/iceberg/util/DynamicResourcePack.java @@ -0,0 +1,151 @@ +package com.anthonyhilyard.iceberg.util; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.function.Predicate; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.packs.PackResources; +import net.minecraft.server.packs.PackType; +import net.minecraft.server.packs.metadata.MetadataSectionSerializer; + +/** + * DynamicResourcePack allows resources that are defined arbitrarily to do cool things with resources. + * For example, resources that change in response to game state, resource proxies, or resources downloaded from the internet. + */ +public class DynamicResourcePack implements PackResources +{ + private record DynamicResourceKey(String type, String namespace, String path) {} + + private final String packName; + private Map<DynamicResourceKey, Supplier<InputStream>> dynamicResourceMap = new HashMap<DynamicResourceKey, Supplier<InputStream>>(); + + public DynamicResourcePack(String packName) + { + this.packName = packName; + } + + public void clear() + { + dynamicResourceMap.clear(); + } + + public boolean removeResource(PackType type, ResourceLocation location) + { + DynamicResourceKey key = new DynamicResourceKey(type.getDirectory(), location.getNamespace(), location.getPath()); + if (dynamicResourceMap.containsKey(key)) + { + dynamicResourceMap.remove(key); + return true; + } + else + { + return false; + } + } + + public boolean registerResource(PackType type, ResourceLocation location, Supplier<InputStream> resourceSupplier) + { + return register(type.getDirectory(), location.getNamespace(), location.getPath(), resourceSupplier); + } + + public boolean registerRootResource(String path, Supplier<InputStream> resourceSupplier) + { + return register("root", "", path, resourceSupplier); + } + + private boolean register(String directory, String namespace, String path, Supplier<InputStream> resourceSupplier) + { + DynamicResourceKey key = new DynamicResourceKey(directory, namespace, path); + if (!dynamicResourceMap.containsKey(key)) + { + dynamicResourceMap.put(key, resourceSupplier); + return true; + } + return false; + } + + @Override + public InputStream getRootResource(String path) throws IOException + { + return getResource("root", "", path); + } + + @Override + public InputStream getResource(PackType type, ResourceLocation location) throws IOException + { + return getResource(type.getDirectory(), location.getNamespace(), location.getPath()); + } + + private InputStream getResource(String directory, String namespace, String path) throws IOException + { + DynamicResourceKey key = new DynamicResourceKey(directory, namespace, path); + if (dynamicResourceMap.containsKey(key)) + { + return dynamicResourceMap.get(key).get(); + } + else + { + throw new FileNotFoundException("Can't find dynamic resource " + path + ". Please ensure it has been registered."); + } + } + + @Override + public Collection<ResourceLocation> getResources(PackType type, String namespace, String path, int maxDepth, Predicate<String> filter) + { + return dynamicResourceMap.entrySet().stream() + .filter(entry -> entry.getKey().namespace.contentEquals(namespace)) + .filter(entry -> entry.getKey().path.startsWith(path)) + .filter(entry -> entry.getKey().type.contentEquals(type.getDirectory())) + .filter(entry -> filter.test(entry.getKey().path)) + .map(entry -> new ResourceLocation(namespace, entry.getKey().path)) + .collect(Collectors.toList()); + } + + @Override + public boolean hasResource(PackType type, ResourceLocation location) + { + return dynamicResourceMap.containsKey(new DynamicResourceKey(type.getDirectory(), location.getNamespace(), location.getPath())); + } + + @Override + public Set<String> getNamespaces(PackType type) + { + Set<String> namespaces = new HashSet<>(); + for (DynamicResourceKey key : dynamicResourceMap.keySet()) + { + if (type.getDirectory().contentEquals(key.type)) + { + namespaces.add(key.namespace); + } + } + return namespaces; + } + + @Override + public <T> T getMetadataSection(MetadataSectionSerializer<T> p_10291_) throws IOException + { + // Does nothing for now. + // TODO: Add metadata? Probably not needed right? + return null; + } + + @Override + public String getName() + { + return packName; + } + + @Override + public void close() + { + } +} |