mirror of
https://github.com/MinecraftForge/MinecraftForge.git
synced 2026-11-13 00:37:52 +00:00
Add support for loading mod advancements from the mod jar files.
This commit is contained in:
1 parent
cab4f783e9
commit
a4fb33d945
4 files changed
+174
-54
No files matched your search
@@ -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<ResourceLocation, Advancement.Builder> 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<ResourceLocation, Advancement.Builder> 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;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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<Path, Boolean> preprocessor, BiFunction<Path, Path, Boolean> 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<Path> 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<Path> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user