diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b89043..59a7b2e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +**v3.4.0** +* Now validates the json files and gives better error messages when malformed. + **v3.3.0** * You can now disable the large ore veins from spawning in the config. * Fixed a bug where the game would try to read all files in the data folder. diff --git a/gradle.properties b/gradle.properties index f67318f..a63a5fd 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,15 +1,15 @@ # Gradle Settings -org.gradle.jvmargs=-Xmx3G +org.gradle.jvmargs=-Xmx5G # Mod Info -VERSION=3.3.0 +VERSION=3.4.0 AUTHOR=Ewy MODNAME=OreTweaker MODID=oretweaker # Dependencies MC_VERSION=1.18.2 -FORGE_VERSION=40.0.32 +FORGE_VERSION=40.2.2 # Mappings MCP_CHANNEL=official diff --git a/src/main/java/com/ewyboy/oretweaker/json/JSONHandler.java b/src/main/java/com/ewyboy/oretweaker/json/JSONHandler.java index bf9ca3a..98b5e53 100644 --- a/src/main/java/com/ewyboy/oretweaker/json/JSONHandler.java +++ b/src/main/java/com/ewyboy/oretweaker/json/JSONHandler.java @@ -7,6 +7,9 @@ import com.ewyboy.oretweaker.util.ModLogger; import com.google.gson.Gson; import com.google.gson.GsonBuilder; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonToken; +import com.google.gson.stream.MalformedJsonException; import net.minecraftforge.fml.loading.FMLPaths; import java.io.*; @@ -18,6 +21,8 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import static com.google.gson.stream.JsonToken.END_DOCUMENT; + public class JSONHandler { private static final Gson gson = new Gson(); @@ -39,6 +44,14 @@ public static void readAllFiles() { try (Stream paths = Files.walk(Paths.get(FMLPaths.CONFIGDIR.get() + "/oretweaker/data"))) { paths.filter(Files :: isRegularFile).forEach(path -> { if (path.toString().endsWith(".json")) { + try { + if (!isJsonValid(path.toFile(), path.getFileName().toString())) { + ModLogger.error("Invalid JSON: " + path.getFileName()); + return; + } + } catch (IOException e) { + throw new RuntimeException(e); + } ModLogger.info("Reading data: " + path.getFileName()); readJson(path.toFile()); } @@ -49,6 +62,37 @@ public static void readAllFiles() { ModLogger.info(oreConfig.toString()); } + private static boolean isJsonValid(File json, String fileName) throws IOException { + try (Reader reader = new FileReader(json)) { + return isJsonValid(new JsonReader(reader), fileName); + } + } + + private static boolean isJsonValid(final JsonReader jsonReader, String fileName) throws IOException { + try { + JsonToken token; + while ((token = jsonReader.peek()) != END_DOCUMENT && token != null) { + switch (token) { + case BEGIN_ARRAY -> jsonReader.beginArray(); + case END_ARRAY -> jsonReader.endArray(); + case BEGIN_OBJECT -> jsonReader.beginObject(); + case END_OBJECT -> jsonReader.endObject(); + case NAME -> jsonReader.nextName(); + case STRING, NUMBER, BOOLEAN, NULL -> jsonReader.skipValue(); + default -> throw new AssertionError(token); + } + } + return true; + } catch ( final MalformedJsonException exception ) { + throw new MalformedJsonException( + "Malformed JSON " + fileName + ":\n" + + "Make sure your JSON is formatted correctly!\n" + + "You can read more about JSON formatting here: https://github.com/EwyBoy/OreTweaker/wiki/Validating-JSON-File\n\n" + + "Error: " + exception.getLocalizedMessage() + " in " + fileName + ); + } + } + public static boolean containsEntry(OreEntry entry) { for (OreEntry ore : oreConfig.getOreConfig()) { if (ore.getOre().equals(entry.getOre()) && ore.isReplace()) {