From a4fb33d9459ac73831baec908f18d8f19f3cd6c0 Mon Sep 17 00:00:00 2001 From: LexManos Date: Tue, 27 Jun 2017 15:18:52 -0700 Subject: [PATCH] Add support for loading mod advancements from the mod jar files. --- .../AdvancementManager.java.patch | 10 ++ .../net/minecraftforge/common/ForgeHooks.java | 71 ++++++++- .../common/crafting/CraftingHelper.java | 142 +++++++++++------- src/main/resources/forge_at.cfg | 5 +- 4 files changed, 174 insertions(+), 54 deletions(-) create mode 100644 patches/minecraft/net/minecraft/advancements/AdvancementManager.java.patch diff --git a/patches/minecraft/net/minecraft/advancements/AdvancementManager.java.patch b/patches/minecraft/net/minecraft/advancements/AdvancementManager.java.patch new file mode 100644 index 0000000000..262c73dba2 --- /dev/null +++ b/patches/minecraft/net/minecraft/advancements/AdvancementManager.java.patch @@ -0,0 +1,10 @@ +--- ../src-base/minecraft/net/minecraft/advancements/AdvancementManager.java ++++ ../src-work/minecraft/net/minecraft/advancements/AdvancementManager.java +@@ -66,6 +66,7 @@ + field_192784_c.func_192087_a(); + Map map = this.func_192781_c(); + this.func_192777_a(map); ++ this.field_193768_e |= net.minecraftforge.common.ForgeHooks.loadAdvancements(map); + field_192784_c.func_192083_a(map); + + for (Advancement advancement : field_192784_c.func_192088_b()) diff --git a/src/main/java/net/minecraftforge/common/ForgeHooks.java b/src/main/java/net/minecraftforge/common/ForgeHooks.java index d066108ec6..4515467cfe 100644 --- a/src/main/java/net/minecraftforge/common/ForgeHooks.java +++ b/src/main/java/net/minecraftforge/common/ForgeHooks.java @@ -19,12 +19,16 @@ package net.minecraftforge.common; +import java.io.BufferedReader; +import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; +import java.nio.file.Files; import java.util.ArrayList; import java.util.Deque; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Random; import java.util.Set; import java.util.regex.Matcher; @@ -37,6 +41,8 @@ import com.google.gson.Gson; import com.google.gson.JsonObject; import com.google.gson.JsonParseException; +import net.minecraft.advancements.Advancement; +import net.minecraft.advancements.AdvancementManager; import net.minecraft.block.Block; import net.minecraft.block.BlockLiquid; import net.minecraft.block.material.Material; @@ -94,6 +100,7 @@ import net.minecraft.world.storage.loot.LootEntry; import net.minecraft.world.storage.loot.LootTable; import net.minecraft.world.storage.loot.LootTableManager; import net.minecraft.world.storage.loot.conditions.LootCondition; +import net.minecraftforge.common.crafting.CraftingHelper; import net.minecraftforge.common.util.BlockSnapshot; import net.minecraftforge.event.AnvilUpdateEvent; import net.minecraftforge.event.DifficultyChangeEvent; @@ -118,12 +125,17 @@ import net.minecraftforge.event.entity.player.PlayerInteractEvent; import net.minecraftforge.event.world.BlockEvent; import net.minecraftforge.event.world.NoteBlockEvent; import net.minecraftforge.fluids.IFluidBlock; +import net.minecraftforge.fml.common.FMLLog; +import net.minecraftforge.fml.common.Loader; +import net.minecraftforge.fml.common.ModContainer; import net.minecraftforge.fml.common.eventhandler.Event; import net.minecraftforge.fml.relauncher.ReflectionHelper; - import javax.annotation.Nonnull; import javax.annotation.Nullable; +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.io.IOUtils; + public class ForgeHooks { //TODO: Loot tables? @@ -1232,4 +1244,61 @@ public class ForgeHooks { MinecraftForge.EVENT_BUS.post(new BlockEvent.CropGrowEvent.Post(worldIn, pos, state, worldIn.getBlockState(pos))); } + + public static boolean loadAdvancements(Map map) + { + boolean errored = false; + Loader.instance().setActiveModContainer(null); + //Loader.instance().getActiveModList().forEach((mod) -> loadFactories(mod)); + for (ModContainer mod : Loader.instance().getActiveModList()) + { + errored |= !loadAdvancements(map, mod); + } + Loader.instance().setActiveModContainer(null); + return errored; + } + + private static boolean loadAdvancements(Map map, ModContainer mod) + { + return CraftingHelper.findFiles(mod, "assets/" + mod.getModId() + "/advancements", null, + (root, file) -> + { + + String relative = root.relativize(file).toString(); + if (!"json".equals(FilenameUtils.getExtension(file.toString())) || relative.startsWith("_")) + return true; + + String name = FilenameUtils.removeExtension(relative).replaceAll("\\\\", "/"); + ResourceLocation key = new ResourceLocation(mod.getModId(), name); + + if (!map.containsKey(key)) + { + BufferedReader reader = null; + + try + { + reader = Files.newBufferedReader(file); + Advancement.Builder builder = JsonUtils.fromJson(AdvancementManager.GSON, reader, Advancement.Builder.class); + map.put(key, builder); + } + catch (JsonParseException jsonparseexception) + { + FMLLog.log.error("Parsing error loading built-in advancement " + key, (Throwable)jsonparseexception); + return false; + } + catch (IOException ioexception) + { + FMLLog.log.error("Couldn't read advancement " + key + " from " + file, (Throwable)ioexception); + return false; + } + finally + { + IOUtils.closeQuietly(reader); + } + } + + return true; + } + ); + } } diff --git a/src/main/java/net/minecraftforge/common/crafting/CraftingHelper.java b/src/main/java/net/minecraftforge/common/crafting/CraftingHelper.java index ec00158c73..4439617f72 100644 --- a/src/main/java/net/minecraftforge/common/crafting/CraftingHelper.java +++ b/src/main/java/net/minecraftforge/common/crafting/CraftingHelper.java @@ -34,7 +34,9 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import java.util.function.BiFunction; import java.util.function.BooleanSupplier; +import java.util.function.Function; import javax.annotation.Nonnull; @@ -651,12 +653,80 @@ public class CraftingHelper { } private static boolean loadRecipes(ModContainer mod) + { + JsonContext ctx = new JsonContext(mod.getModId()); + + return findFiles(mod, "assets/" + mod.getModId() + "/recipes", + root -> + { + Path fPath = root.resolve("_constants.json"); + if (fPath != null && Files.exists(fPath)) + { + BufferedReader reader = null; + try + { + reader = Files.newBufferedReader(fPath); + JsonObject[] json = JsonUtils.fromJson(GSON, reader, JsonObject[].class); + ctx.loadConstants(json); + } + catch (IOException e) + { + FMLLog.log.error("Error loading _constants.json: ", e); + return false; + } + finally + { + IOUtils.closeQuietly(reader); + } + } + return true; + }, + (root, file) -> + { + Loader.instance().setActiveModContainer(mod); + + String relative = root.relativize(file).toString(); + if (!"json".equals(FilenameUtils.getExtension(file.toString())) || relative.startsWith("_")) + return true; + + String name = FilenameUtils.removeExtension(relative).replaceAll("\\\\", "/"); + ResourceLocation key = new ResourceLocation(ctx.getModId(), name); + + BufferedReader reader = null; + try + { + reader = Files.newBufferedReader(file); + JsonObject json = JsonUtils.fromJson(GSON, reader, JsonObject.class); + if (json.has("conditions") && !CraftingHelper.processConditions(JsonUtils.getJsonArray(json, "conditions"), ctx)) + return true; + IRecipe recipe = CraftingHelper.getRecipe(json, ctx); + ForgeRegistries.RECIPES.register(recipe.setRegistryName(key)); + } + catch (JsonParseException e) + { + FMLLog.log.error("Parsing error loading recipe {}", key, e); + return false; + } + catch (IOException e) + { + FMLLog.log.error("Couldn't read recipe {} from {}", key, file, e); + return false; + } + finally + { + IOUtils.closeQuietly(reader); + } + return true; + } + ); + } + + + public static boolean findFiles(ModContainer mod, String base, Function preprocessor, BiFunction processor) { FileSystem fs = null; - BufferedReader reader = null; try { - JsonContext ctx = new JsonContext(mod.getModId()); File source = mod.getSource(); if ("minecraft".equals(mod.getModId()) && DEBUG_LOAD_MINECRAFT) @@ -679,7 +749,7 @@ public class CraftingHelper { try { fs = FileSystems.newFileSystem(source.toPath(), null); - root = fs.getPath("/assets/" + ctx.getModId() + "/recipes"); + root = fs.getPath("/" + base); } catch (IOException e) { @@ -689,77 +759,45 @@ public class CraftingHelper { } else if (source.isDirectory()) { - root = source.toPath().resolve("assets/" + ctx.getModId() + "/recipes"); + root = source.toPath().resolve(base); } if (root == null || !Files.exists(root)) return false; - Path fPath = root.resolve("_constants.json"); - if (fPath != null && Files.exists(fPath)) + if (preprocessor != null) { + Boolean cont = preprocessor.apply(root); + if (cont == null || !cont.booleanValue()) + return false; + } + + if (processor != null) + { + Iterator itr = null; try { - reader = Files.newBufferedReader(fPath); - JsonObject[] json = JsonUtils.fromJson(GSON, reader, JsonObject[].class); - ctx.loadConstants(json); + itr = Files.walk(root).iterator(); } catch (IOException e) { - FMLLog.log.error("Error loading _constants.json: ", e); + FMLLog.log.error("Error iterating filesystem for: {}", mod.getModId(), e); return false; } - } - Iterator itr = null; - try - { - itr = Files.walk(root).iterator(); - } - catch (IOException e) - { - FMLLog.log.error("Error iterating recipes for: {}", ctx.getModId(), e); - return false; - } - - Loader.instance().setActiveModContainer(mod); - while (itr != null && itr.hasNext()) - { - Path f = itr.next(); - if (!"json".equals(FilenameUtils.getExtension(f.toString())) || root.relativize(f).toString().startsWith("_")) - continue; - - String name = FilenameUtils.removeExtension(root.relativize(f).toString()).replaceAll("\\\\", "/"); - ResourceLocation key = new ResourceLocation(ctx.getModId(), name); - - IOUtils.closeQuietly(reader); - try + while (itr != null && itr.hasNext()) { - reader = Files.newBufferedReader(f); - JsonObject json = JsonUtils.fromJson(GSON, reader, JsonObject.class); - if (json.has("conditions") && !CraftingHelper.processConditions(JsonUtils.getJsonArray(json, "conditions"), ctx)) - continue; - IRecipe recipe = CraftingHelper.getRecipe(json, ctx); - ForgeRegistries.RECIPES.register(recipe.setRegistryName(key)); + Boolean cont = processor.apply(root, itr.next()); + if (cont == null || !cont.booleanValue()) + return false; } - catch (JsonParseException e) - { - FMLLog.log.error("Parsing error loading recipe {}", key, e); - return false; - } - catch (IOException e) - { - FMLLog.log.error("Couldn't read recipe {} from {}", key, f, e); - return false; - } - } + } return true; } finally { IOUtils.closeQuietly(fs); - IOUtils.closeQuietly(reader); } } } diff --git a/src/main/resources/forge_at.cfg b/src/main/resources/forge_at.cfg index d42f1bf0fa..86b5a4ccf0 100644 --- a/src/main/resources/forge_at.cfg +++ b/src/main/resources/forge_at.cfg @@ -318,4 +318,7 @@ protected net.minecraft.world.Teleporter field_85191_c # destinationCoordinateCa public net.minecraft.util.ResourceLocation func_177516_a(Ljava/lang/String;)[Ljava/lang/String; # splitObjectName # Ingredient -protected net.minecraft.item.crafting.Ingredient ([Lnet/minecraft/item/ItemStack;)V # Ingredient \ No newline at end of file +protected net.minecraft.item.crafting.Ingredient ([Lnet/minecraft/item/ItemStack;)V # Ingredient + +# Advancements +public net.minecraft.advancements.AdvancementManager field_192783_b # GSON \ No newline at end of file