diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 00000000..f2fea4f5 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,33 @@ +--- +name: Bug report +about: Create a report to help us improve +title: "[BUG]" +labels: Bug +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Operating System [e.g. Windows]:** + +**Version/Commit [e.g. 2.2.6]:** + +**Java Version [e.g. Temurin 21]:** + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 00000000..956fa874 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: "[Feature Request]" +labels: Feature +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/Applications/Console/src/main/java/com/agentdid127/resourcepack/Main.java b/Applications/Console/src/main/java/com/agentdid127/resourcepack/Main.java index 3d4e7736..ef75397e 100644 --- a/Applications/Console/src/main/java/com/agentdid127/resourcepack/Main.java +++ b/Applications/Console/src/main/java/com/agentdid127/resourcepack/Main.java @@ -32,7 +32,7 @@ public static void main(String[] args) throws IOException { boolean debug = optionSet.valueOf(Options.DEBUG); PrintStream out = System.out; - GsonBuilder gsonBuilder = new GsonBuilder().disableHtmlEscaping().setStrictness(Strictness.LENIENT); + GsonBuilder gsonBuilder = new GsonBuilder().disableHtmlEscaping(); if (!minify) { gsonBuilder.setPrettyPrinting(); } diff --git a/Applications/Gui/src/main/java/com/agentdid127/resourcepack/GUI.java b/Applications/Gui/src/main/java/com/agentdid127/resourcepack/GUI.java index a66d52fa..00827e9b 100644 --- a/Applications/Gui/src/main/java/com/agentdid127/resourcepack/GUI.java +++ b/Applications/Gui/src/main/java/com/agentdid127/resourcepack/GUI.java @@ -18,7 +18,7 @@ import java.util.Objects; public class GUI extends JPanel { - private static final Gson GSON = new GsonBuilder().disableHtmlEscaping().setStrictness(Strictness.LENIENT).disableHtmlEscaping().create(); + private static final Gson GSON = new GsonBuilder().disableHtmlEscaping().disableHtmlEscaping().create(); private PrintStream out; private final JTextArea outputLogPane; diff --git a/conversions/Backwards/src/main/java/com/agentdid127/resourcepack/backwards/impl/ModelConverter.java b/conversions/Backwards/src/main/java/com/agentdid127/resourcepack/backwards/impl/ModelConverter.java index 0f6fbdc5..a49b97bc 100644 --- a/conversions/Backwards/src/main/java/com/agentdid127/resourcepack/backwards/impl/ModelConverter.java +++ b/conversions/Backwards/src/main/java/com/agentdid127/resourcepack/backwards/impl/ModelConverter.java @@ -24,6 +24,8 @@ public class ModelConverter extends Converter { private final int to; private final int from; + private Pack pack; + public ModelConverter(PackConverter packConverter, int from, int to) { super(packConverter); this.from = from; @@ -43,6 +45,7 @@ public boolean shouldConvert(Gson gson, int from, int to) { */ @Override public void convert(Pack pack) throws IOException { + this.pack = pack; Path models = pack.getWorkingPath().resolve("assets/minecraft/models".replace("/", File.separator)); if (models.toFile().exists()) { findFiles(models); @@ -58,7 +61,7 @@ public void convert(Pack pack) throws IOException { protected void findFiles(Path path) throws IOException { File directory = path.toFile(); for (File file : Objects.requireNonNull(directory.listFiles())) { - if (file.isDirectory()) + if (!file.isDirectory()) continue; remapModelJson(file.toPath()); findFiles(file.toPath()); @@ -72,8 +75,9 @@ protected void findFiles(Path path) throws IOException { * @throws IOException */ protected void remapModelJson(Path models) throws IOException { - if (!models.toFile().exists()) + if (!models.toFile().exists()) { return; + } Files.list(models) .filter(path1 -> path1.toString().endsWith(".json")) .forEach(model -> { @@ -93,6 +97,21 @@ protected void remapModelJson(Path models) throws IOException { return; } + if (to < Util.getVersionProtocol(packConverter.getGson(), "1.21.4") + && from >= Util.getVersionProtocol(packConverter.getGson(), "1.21.4")) { + // Check for new overrides + if (jsonObject.has("model") && jsonObject.get("model").isJsonObject()) { + JsonObject modelJson = jsonObject.get("model").getAsJsonObject(); + // Convert damages, and model data + + if (isDamageModel(modelJson)) { + jsonObject = createDamageModel(modelJson, model); + } else if (isCustomModelData(modelJson)) { + jsonObject = createCustomModelData(modelJson, model); + } + } + } + // Parent Stuff if (jsonObject.has("parent")) { // Change parent to lowercase @@ -228,7 +247,17 @@ else if (value.startsWith("item/")) if (!JsonUtil.readJson(packConverter.getGson(), model).equals(jsonObject)) { Logger.debug("Updating Model: " + model.getFileName()); - JsonUtil.writeJson(packConverter.getGson(), model, jsonObject); + if (to < Util.getVersionProtocol(packConverter.getGson(), "1.21.4") + && from >= Util.getVersionProtocol(packConverter.getGson(), "1.21.4")) { + Path itemsPath = pack.getWorkingPath().resolve("assets/minecraft/models/item"); + if (!itemsPath.toFile().exists()) { + itemsPath.toFile().mkdirs(); + } + JsonUtil.writeJson(packConverter.getGson(), itemsPath.resolve(model.toFile().getName()), jsonObject); + Files.delete(model); + } else { + JsonUtil.writeJson(packConverter.getGson(), model, jsonObject); + } } } catch (IOException e) { throw Util.propagate(e); @@ -490,4 +519,84 @@ private static JsonObject updateDisplayThirdPerson(Gson gson, JsonObject old) { return newObject; } + + + private JsonObject createDamageModel(JsonObject modelNew, Path original) throws IOException { + if (pack == null) return null; + JsonArray entries = modelNew.get("entries").getAsJsonArray(); + + String texture = modelNew.get("fallback").getAsJsonObject().get("model").getAsString(); + + JsonObject out = new JsonObject(); + out.addProperty("parent", "item/handheld"); + JsonObject textures = new JsonObject(); + out.add("textures", textures); + textures.addProperty("layer0", texture); + + JsonObject fallback = new JsonObject(); + fallback.addProperty("type", "model"); + fallback.addProperty("model", original.toFile().getAbsolutePath().replace(pack.getWorkingPath().resolve("assets/minecraft/models").toFile().getAbsolutePath() + "/", "").replace(".json", "")); + + JsonArray overrides = new JsonArray(); + for (JsonElement entry : entries) { + JsonObject override = new JsonObject(); + if (entry.isJsonObject()) { + long customModelData = entry.getAsJsonObject().get("threshold").getAsLong(); + String overrideModel = override.getAsJsonObject().get("model").getAsJsonObject().get("model").getAsString(); + + override.addProperty("model", overrideModel); + JsonObject predicate = new JsonObject(); + predicate.addProperty("damage", customModelData); + override.add("predicate", predicate); + entries.add(entry); + } + } + out.add("overrides", overrides); + + return out; + } + + + private JsonObject createCustomModelData(JsonObject modelNew, Path original) throws IOException { + if (pack == null) return null; + JsonArray entries = modelNew.get("entries").getAsJsonArray(); + + String texture = modelNew.get("fallback").getAsJsonObject().get("model").getAsString(); + + JsonObject out = new JsonObject(); + out.addProperty("parent", "item/generated"); + JsonObject textures = new JsonObject(); + out.add("textures", textures); + textures.addProperty("layer0", texture); + + JsonObject fallback = new JsonObject(); + fallback.addProperty("type", "model"); + fallback.addProperty("model", original.toFile().getAbsolutePath().replace(pack.getWorkingPath().resolve("assets/minecraft/models").toFile().getAbsolutePath() + "/", "").replace(".json", "")); + + JsonArray overrides = new JsonArray(); + for (JsonElement entry : entries) { + JsonObject override = new JsonObject(); + if (entry.isJsonObject()) { + long customModelData = entry.getAsJsonObject().get("threshold").getAsLong(); + String overrideModel = entry.getAsJsonObject().get("model").getAsJsonObject().get("model").getAsString(); + + override.addProperty("model", overrideModel); + JsonObject predicate = new JsonObject(); + predicate.addProperty("custom_model_data", customModelData); + override.add("predicate", predicate); + overrides.add(override); + } + } + out.add("overrides", overrides); + + return out; + } + + private boolean isDamageModel(JsonObject model) { + return model.has("property") && model.get("property").getAsString().equals("damage"); + } + + private boolean isCustomModelData(JsonObject model) { + return model.has("property") && model.get("property").getAsString().equals("custom_model_data"); + } } \ No newline at end of file diff --git a/conversions/Forwards/src/main/java/com/agentdid127/resourcepack/forwards/impl/other/ModelConverter.java b/conversions/Forwards/src/main/java/com/agentdid127/resourcepack/forwards/impl/other/ModelConverter.java index f930faf5..70549ed9 100644 --- a/conversions/Forwards/src/main/java/com/agentdid127/resourcepack/forwards/impl/other/ModelConverter.java +++ b/conversions/Forwards/src/main/java/com/agentdid127/resourcepack/forwards/impl/other/ModelConverter.java @@ -296,9 +296,9 @@ protected void remapModelJson(Path rootPath, Path model) throws IOException { // Convert damages, and model data if (isDamageModel(overridesArray)) { - createDamageModel(overridesArray, model); + createDamageModel(jsonObject, model); } else if (isCustomModelData(overridesArray)) { - createCustomModelData(overridesArray, model); + createCustomModelData(jsonObject, model); } // remove old damages @@ -306,7 +306,6 @@ protected void remapModelJson(Path rootPath, Path model) throws IOException { } } - if (!JsonUtil.readJson(packConverter.getGson(), model).equals(jsonObject)) { Logger.debug("Updating Model: " + model.getFileName()); JsonUtil.writeJson(packConverter.getGson(), model, jsonObject); @@ -321,12 +320,23 @@ protected void remapModelJson(Path rootPath, Path model) throws IOException { /** * Creates a Damage-based item in the new directory for 1.21.4+ * - * @param overrides overrides system from old model + * @param oldModel old model * @param original original model file * @throws IOException if we can't save the new file. */ - private void createDamageModel(JsonArray overrides, Path original) throws IOException { + private void createDamageModel(JsonObject oldModel, Path original) throws IOException { if (pack == null) return; + JsonArray overrides = oldModel.get("overrides").getAsJsonArray(); + String texture = null; + if (oldModel.has("textures")) { + JsonObject textures = oldModel.get("textures").getAsJsonObject(); + for (JsonElement element : textures.asMap().values()) { + if (element.isJsonPrimitive()) { + texture = element.getAsString(); + break; + } + } + } Path itemsPath = pack.getWorkingPath().resolve("assets/minecraft/items"); if (!itemsPath.toFile().exists()) { itemsPath.toFile().mkdirs(); @@ -339,16 +349,20 @@ private void createDamageModel(JsonArray overrides, Path original) throws IOExce JsonObject fallback = new JsonObject(); fallback.addProperty("type", "model"); - - fallback.addProperty("model", original.toFile().getAbsolutePath().replace(pack.getWorkingPath().resolve("assets/minecraft/models").toFile().getAbsolutePath() + "/", "").replace(".json", "")); + fallback.addProperty("model", texture); model.add("fallback", fallback); - // iterate through old override entries, and migrate to new file. JsonArray entries = new JsonArray(); for (JsonElement override : overrides) { JsonObject entry = new JsonObject(); if (override.isJsonObject()) { + if (!override.getAsJsonObject().has("predicate")) { + continue; + } + if (!override.getAsJsonObject().get("predicate").getAsJsonObject().has("damage")) { + continue; + } double damage = override.getAsJsonObject().get("predicate").getAsJsonObject().get("damage").getAsDouble(); String entryModel = override.getAsJsonObject().get("model").getAsString(); @@ -371,12 +385,23 @@ private void createDamageModel(JsonArray overrides, Path original) throws IOExce /** * Creates a Custom Model Data based item in the 1.21.4+ format. * - * @param overrides old overrides + * @param oldModel old model * @param original original model file path * @throws IOException if we can't save the new file. */ - private void createCustomModelData(JsonArray overrides, Path original) throws IOException { + private void createCustomModelData(JsonObject oldModel, Path original) throws IOException { if (pack == null) return; + JsonArray overrides = oldModel.get("overrides").getAsJsonArray(); + String texture = null; + if (oldModel.has("textures")) { + JsonObject textures = oldModel.get("textures").getAsJsonObject(); + for (JsonElement element : textures.asMap().values()) { + if (element.isJsonPrimitive()) { + texture = element.getAsString(); + break; + } + } + } Path itemsPath = pack.getWorkingPath().resolve("assets/minecraft/items"); if (!itemsPath.toFile().exists()) { itemsPath.toFile().mkdirs(); @@ -389,13 +414,19 @@ private void createCustomModelData(JsonArray overrides, Path original) throws IO JsonObject fallback = new JsonObject(); fallback.addProperty("type", "model"); - fallback.addProperty("model", original.toFile().getAbsolutePath().replace(pack.getWorkingPath().resolve("assets/minecraft/models").toFile().getAbsolutePath() + "/", "").replace(".json", "")); + fallback.addProperty("model", texture); model.add("fallback", fallback); JsonArray entries = new JsonArray(); for (JsonElement override : overrides) { JsonObject entry = new JsonObject(); if (override.isJsonObject()) { + if (!override.getAsJsonObject().has("predicate")) { + continue; + } + if (!override.getAsJsonObject().get("predicate").getAsJsonObject().has("custom_model_data")) { + continue; + } long customModelData = override.getAsJsonObject().get("predicate").getAsJsonObject().get("custom_model_data").getAsLong(); String entryModel = override.getAsJsonObject().get("model").getAsString(); diff --git a/library/src/main/java/com/agentdid127/resourcepack/library/utilities/JsonUtil.java b/library/src/main/java/com/agentdid127/resourcepack/library/utilities/JsonUtil.java index 789f111d..3eb03f62 100644 --- a/library/src/main/java/com/agentdid127/resourcepack/library/utilities/JsonUtil.java +++ b/library/src/main/java/com/agentdid127/resourcepack/library/utilities/JsonUtil.java @@ -76,7 +76,6 @@ public static T readJson(Gson gson, Path path, Class clazz) throws IOExce String json = Util.readFromFile(path); if (isJson(gson, json)) { JsonReader reader = new JsonReader(new StringReader(json)); - reader.setStrictness(Strictness.LENIENT); return gson.fromJson(reader, clazz); } else { return null;