aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/com/anthonyhilyard/iceberg/util/DynamicResourcePack.java
blob: a59449a437b05b3697550403a39d9e8bc1807f82 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
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, Predicate<ResourceLocation> 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(new ResourceLocation(entry.getKey().namespace, 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()
	{
	}
}