234 lines
9.2 KiB
Java
234 lines
9.2 KiB
Java
package net.minecraft.advancements;
|
|
|
|
import com.google.common.collect.Maps;
|
|
import com.google.gson.Gson;
|
|
import com.google.gson.GsonBuilder;
|
|
import com.google.gson.JsonDeserializationContext;
|
|
import com.google.gson.JsonDeserializer;
|
|
import com.google.gson.JsonElement;
|
|
import com.google.gson.JsonObject;
|
|
import com.google.gson.JsonParseException;
|
|
import java.io.BufferedReader;
|
|
import java.io.Closeable;
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
import java.io.Reader;
|
|
import java.lang.reflect.Type;
|
|
import java.net.URI;
|
|
import java.net.URISyntaxException;
|
|
import java.net.URL;
|
|
import java.nio.charset.StandardCharsets;
|
|
import java.nio.file.FileSystem;
|
|
import java.nio.file.FileSystems;
|
|
import java.nio.file.Files;
|
|
import java.nio.file.Path;
|
|
import java.nio.file.Paths;
|
|
import java.util.Collections;
|
|
import java.util.Iterator;
|
|
import java.util.Map;
|
|
import javax.annotation.Nullable;
|
|
import net.minecraft.item.crafting.CraftingManager;
|
|
import net.minecraft.util.EnumTypeAdapterFactory;
|
|
import net.minecraft.util.JsonUtils;
|
|
import net.minecraft.util.ResourceLocation;
|
|
import net.minecraft.util.text.ITextComponent;
|
|
import net.minecraft.util.text.Style;
|
|
import org.apache.commons.io.FileUtils;
|
|
import org.apache.commons.io.FilenameUtils;
|
|
import org.apache.commons.io.IOUtils;
|
|
import org.apache.logging.log4j.LogManager;
|
|
import org.apache.logging.log4j.Logger;
|
|
|
|
public class AdvancementManager
|
|
{
|
|
private static final Logger LOGGER = LogManager.getLogger();
|
|
public static final Gson GSON = (new GsonBuilder()).registerTypeHierarchyAdapter(Advancement.Builder.class, new JsonDeserializer<Advancement.Builder>()
|
|
{
|
|
public Advancement.Builder deserialize(JsonElement p_deserialize_1_, Type p_deserialize_2_, JsonDeserializationContext p_deserialize_3_) throws JsonParseException
|
|
{
|
|
JsonObject jsonobject = JsonUtils.getJsonObject(p_deserialize_1_, "advancement");
|
|
return Advancement.Builder.deserialize(jsonobject, p_deserialize_3_);
|
|
}
|
|
}).registerTypeAdapter(AdvancementRewards.class, new AdvancementRewards.Deserializer()).registerTypeHierarchyAdapter(ITextComponent.class, new ITextComponent.Serializer()).registerTypeHierarchyAdapter(Style.class, new Style.Serializer()).registerTypeAdapterFactory(new EnumTypeAdapterFactory()).create();
|
|
private static final AdvancementList ADVANCEMENT_LIST = new AdvancementList();
|
|
/** The directory where this manager looks for custom advancement files. */
|
|
private final File advancementsDir;
|
|
private boolean hasErrored;
|
|
|
|
public AdvancementManager(@Nullable File advancementsDirIn)
|
|
{
|
|
this.advancementsDir = advancementsDirIn;
|
|
this.reload();
|
|
}
|
|
|
|
public void reload()
|
|
{
|
|
this.hasErrored = false;
|
|
ADVANCEMENT_LIST.clear();
|
|
Map<ResourceLocation, Advancement.Builder> map = this.loadCustomAdvancements();
|
|
this.loadBuiltInAdvancements(map);
|
|
this.hasErrored |= net.minecraftforge.common.ForgeHooks.loadAdvancements(map);
|
|
ADVANCEMENT_LIST.loadAdvancements(map);
|
|
|
|
for (Advancement advancement : ADVANCEMENT_LIST.getRoots())
|
|
{
|
|
if (advancement.getDisplay() != null)
|
|
{
|
|
AdvancementTreeNode.layout(advancement);
|
|
}
|
|
}
|
|
}
|
|
|
|
public boolean hasErrored()
|
|
{
|
|
return this.hasErrored;
|
|
}
|
|
|
|
private Map<ResourceLocation, Advancement.Builder> loadCustomAdvancements()
|
|
{
|
|
if (this.advancementsDir == null)
|
|
{
|
|
return Maps.<ResourceLocation, Advancement.Builder>newHashMap();
|
|
}
|
|
else
|
|
{
|
|
Map<ResourceLocation, Advancement.Builder> map = Maps.<ResourceLocation, Advancement.Builder>newHashMap();
|
|
this.advancementsDir.mkdirs();
|
|
|
|
for (File file1 : FileUtils.listFiles(this.advancementsDir, new String[] {"json"}, true))
|
|
{
|
|
String s = FilenameUtils.removeExtension(this.advancementsDir.toURI().relativize(file1.toURI()).toString());
|
|
String[] astring = s.split("/", 2);
|
|
|
|
if (astring.length == 2)
|
|
{
|
|
ResourceLocation resourcelocation = new ResourceLocation(astring[0], astring[1]);
|
|
|
|
try
|
|
{
|
|
Advancement.Builder advancement$builder = (Advancement.Builder)JsonUtils.gsonDeserialize(GSON, FileUtils.readFileToString(file1, StandardCharsets.UTF_8), Advancement.Builder.class);
|
|
|
|
if (advancement$builder == null)
|
|
{
|
|
LOGGER.error("Couldn't load custom advancement " + resourcelocation + " from " + file1 + " as it's empty or null");
|
|
}
|
|
else
|
|
{
|
|
map.put(resourcelocation, advancement$builder);
|
|
}
|
|
}
|
|
catch (IllegalArgumentException | JsonParseException jsonparseexception)
|
|
{
|
|
LOGGER.error("Parsing error loading custom advancement " + resourcelocation, (Throwable)jsonparseexception);
|
|
this.hasErrored = true;
|
|
}
|
|
catch (IOException ioexception)
|
|
{
|
|
LOGGER.error("Couldn't read custom advancement " + resourcelocation + " from " + file1, (Throwable)ioexception);
|
|
this.hasErrored = true;
|
|
}
|
|
}
|
|
}
|
|
return map;
|
|
}
|
|
}
|
|
|
|
private void loadBuiltInAdvancements(Map<ResourceLocation, Advancement.Builder> map)
|
|
{
|
|
FileSystem filesystem = null;
|
|
|
|
try
|
|
{
|
|
URL url = AdvancementManager.class.getResource("/assets/.mcassetsroot");
|
|
|
|
if (url != null)
|
|
{
|
|
URI uri = url.toURI();
|
|
Path path;
|
|
|
|
if ("file".equals(uri.getScheme()))
|
|
{
|
|
path = Paths.get(CraftingManager.class.getResource("/assets/minecraft/advancements").toURI());
|
|
}
|
|
else
|
|
{
|
|
if (!"jar".equals(uri.getScheme()))
|
|
{
|
|
LOGGER.error("Unsupported scheme " + uri + " trying to list all built-in advancements (NYI?)");
|
|
this.hasErrored = true;
|
|
return;
|
|
}
|
|
|
|
filesystem = FileSystems.newFileSystem(uri, Collections.emptyMap());
|
|
path = filesystem.getPath("/assets/minecraft/advancements");
|
|
}
|
|
|
|
Iterator<Path> iterator = Files.walk(path).iterator();
|
|
|
|
while (iterator.hasNext())
|
|
{
|
|
Path path1 = iterator.next();
|
|
|
|
if ("json".equals(FilenameUtils.getExtension(path1.toString())))
|
|
{
|
|
Path path2 = path.relativize(path1);
|
|
String s = FilenameUtils.removeExtension(path2.toString()).replaceAll("\\\\", "/");
|
|
ResourceLocation resourcelocation = new ResourceLocation("minecraft", s);
|
|
|
|
if (!map.containsKey(resourcelocation))
|
|
{
|
|
BufferedReader bufferedreader = null;
|
|
|
|
try
|
|
{
|
|
bufferedreader = Files.newBufferedReader(path1);
|
|
Advancement.Builder advancement$builder = (Advancement.Builder)JsonUtils.fromJson(GSON, bufferedreader, Advancement.Builder.class);
|
|
map.put(resourcelocation, advancement$builder);
|
|
}
|
|
catch (JsonParseException jsonparseexception)
|
|
{
|
|
LOGGER.error("Parsing error loading built-in advancement " + resourcelocation, (Throwable)jsonparseexception);
|
|
this.hasErrored = true;
|
|
}
|
|
catch (IOException ioexception)
|
|
{
|
|
LOGGER.error("Couldn't read advancement " + resourcelocation + " from " + path1, (Throwable)ioexception);
|
|
this.hasErrored = true;
|
|
}
|
|
finally
|
|
{
|
|
IOUtils.closeQuietly((Reader)bufferedreader);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
LOGGER.error("Couldn't find .mcassetsroot");
|
|
this.hasErrored = true;
|
|
}
|
|
catch (IOException | URISyntaxException urisyntaxexception)
|
|
{
|
|
LOGGER.error("Couldn't get a list of all built-in advancement files", (Throwable)urisyntaxexception);
|
|
this.hasErrored = true;
|
|
return;
|
|
}
|
|
finally
|
|
{
|
|
IOUtils.closeQuietly((Closeable)filesystem);
|
|
}
|
|
}
|
|
|
|
@Nullable
|
|
public Advancement getAdvancement(ResourceLocation id)
|
|
{
|
|
return ADVANCEMENT_LIST.getAdvancement(id);
|
|
}
|
|
|
|
public Iterable<Advancement> getAdvancements()
|
|
{
|
|
return ADVANCEMENT_LIST.getAdvancements();
|
|
}
|
|
} |