summaryrefslogtreecommitdiff
path: root/src/main/java/lv/enes/mc/eris_alchemy/EmcLoader.java
blob: 373e56108a1fb54a09b8b075140854afe5dd3af5 (plain) (blame)
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
package lv.enes.mc.eris_alchemy;

import com.google.gson.reflect.TypeToken;
import jakarta.annotation.Nonnull;
import lv.enes.mc.eris_alchemy.recipe.BannedRecipe;
import lv.enes.mc.eris_alchemy.recipe.SimplifiedRecipe;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.packs.resources.ResourceManager;
import org.quiltmc.qsl.resource.loader.api.reloader.SimpleSynchronousResourceReloader;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.*;

import static lv.enes.mc.eris_alchemy.ErisAlchemy.GSON;

public class EmcLoader implements SimpleSynchronousResourceReloader {
	public static final EmcLoader INSTANCE = new EmcLoader();

	@Nonnull
	@Override
	public ResourceLocation getQuiltId() {
		return new ResourceLocation(ErisAlchemy.ID, "emc_loader");
	}

	@Override
	public void onResourceManagerReload(ResourceManager manager) {
		var itemValues = loadAllFiles(manager, "item_emcs", new HashMap<>(), EmcLoader::loadEmcValues);
		var itemTagValues = loadAllFiles(manager, "item_tag_emcs", new HashMap<>(), EmcLoader::loadEmcValues);
		var blockTagValues = loadAllFiles(manager, "block_tag_emcs", new HashMap<>(), EmcLoader::loadEmcValues);

		var fakeRecipes = loadAllFiles(manager, "fake_recipes", new ArrayList<>(), EmcLoader::loadFakeRecipes);

		var bannedRecipes = loadAllFiles(manager, "cycle_cut", new ArrayList<>(), EmcLoader::loadBannedRecipes);

		Emc.reloadData(itemValues, itemTagValues, blockTagValues, fakeRecipes, bannedRecipes);
	}

	private static <T> T loadAllFiles(
			ResourceManager manager,
			String path,
			T arg,
			Loader<T> loader
	) {
		manager.listResources(
				ErisAlchemy.ID + "/" + path,
				loc -> loc.getPath().endsWith(".json") || loc.getPath().endsWith(".json5")
		).forEach((id, res) -> {
			ErisAlchemy.LOGGER.info("Loading {}:{}...", id.getNamespace(), id.getPath());
			try (var is = res.open()) {
				loader.loadFile(arg, id, is);
			} catch (IOException e) {
				ErisAlchemy.LOGGER.error(
						"Error occured while reading {}:{}",
						id.getNamespace(),
						id.getPath(),
						e
				);
			}
		});
		return arg;
	}

	private static void loadBannedRecipes(List<BannedRecipe> recipes, ResourceLocation id, InputStream is)
			throws IOException
	{
		try (var reader = new InputStreamReader(is)) {
			var json = GSON.fromJson(reader, new TypeToken<List<BannedRecipe>>(){});
			recipes.addAll(json);
		}
	}

	private static void loadEmcValues(Map<ResourceLocation, OptionalDouble> map, ResourceLocation id, InputStream is)
			throws IOException
	{
		try (var reader = new InputStreamReader(is)) {
			var json = GSON.fromJson(reader, new TypeToken<Map<ResourceLocation, Double>>(){});
			json.forEach((item, newEmcRaw) -> {
				var newEmc = newEmcRaw == null ? OptionalDouble.empty() : OptionalDouble.of(newEmcRaw);
				var oldEmc = map.get(item);
				if (oldEmc != null && !newEmc.equals(oldEmc)) {
					var oldStr = oldEmc.isEmpty() ? "NONE" : Double.toString(oldEmc.getAsDouble());
					var newStr = newEmc.isEmpty() ? "NONE" : Double.toString(newEmc.getAsDouble());
					ErisAlchemy.LOGGER.warn(
							"Redefining the EMC value for {} from {} to {}",
							item,
							oldStr,
							newStr
					);
				}
				map.put(item, newEmc);
			});
		}
	}

	private static void loadFakeRecipes(List<SimplifiedRecipe> recipes, ResourceLocation id, InputStream is)
		throws IOException
	{
		try (var reader = new InputStreamReader(is)) {
			var json = GSON.fromJson(reader, new TypeToken<List<SimplifiedRecipe>>(){});
			recipes.addAll(json);
		}
	}

	@FunctionalInterface
	private interface Loader<T> {
		void loadFile(T arg, ResourceLocation id, InputStream is) throws IOException;
	}

	private EmcLoader() {}
}