diff --git a/common-files/src/main/resources/config.yml b/common-files/src/main/resources/config.yml
index 4e33699a4..7947a3357 100644
--- a/common-files/src/main/resources/config.yml
+++ b/common-files/src/main/resources/config.yml
@@ -24,6 +24,8 @@ resource-pack:
supported-version:
min: server
max: latest
+ # The description of your resource pack
+ description: "CraftEngine ResourcePack"
# Remove 1.21.5+ tinted_leaves particles
remove-tinted-leaves-particle: true
# Define the name of the overlay folders
@@ -65,7 +67,6 @@ resource-pack:
path: "pack.mcmeta"
resolution:
type: merge_pack_mcmeta
- description: "CraftEngine ResourcePack"
- term:
type: exact
path: "pack.png"
diff --git a/common-files/src/main/resources/resources/default/resourcepack/pack.mcmeta b/common-files/src/main/resources/resources/default/resourcepack/pack.mcmeta
deleted file mode 100644
index 4d5e8390e..000000000
--- a/common-files/src/main/resources/resources/default/resourcepack/pack.mcmeta
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "pack": {
- "pack_format": 15,
- "description": "CraftEngine",
- "supported_formats": {
- "min_inclusive": 15,
- "max_inclusive": 1000
- },
- "min_format": 15,
- "max_format": 1000
- }
-}
\ No newline at end of file
diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java b/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java
index f64c064f1..140421668 100644
--- a/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java
+++ b/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java
@@ -788,19 +788,28 @@ public abstract class AbstractPackManager implements PackManager {
this.generateClientLang(generatedPackPath);
this.generateEquipments(generatedPackPath, revisions::add);
this.generateParticle(generatedPackPath);
- this.generatePackMetadata(generatedPackPath.resolve("pack.mcmeta"), revisions);
+
+ Path packMcMetaPath = generatedPackPath.resolve("pack.mcmeta");
+ JsonObject packMcMeta = Files.isRegularFile(packMcMetaPath) ? GsonHelper.readJsonFile(packMcMetaPath).getAsJsonObject() : new JsonObject();
+ // 生成revision overlay
+ this.generateRevisionOverlays(packMcMeta, revisions);
+
if (Config.excludeShaders()) {
this.removeAllShaders(generatedPackPath);
}
long time2 = System.currentTimeMillis();
this.plugin.logger().info(TranslationManager.instance().translateLog("info.resource_pack.generate.finish", String.valueOf(time2 - time1)));
+ // 校验资源包
if (Config.validateResourcePack()) {
- this.validateResourcePack(generatedPackPath);
+ this.validateResourcePack(generatedPackPath, packMcMeta);
}
long time3 = System.currentTimeMillis();
if (Config.validateResourcePack()) {
this.plugin.logger().info(TranslationManager.instance().translateLog("info.resource_pack.validate.finish", String.valueOf(time3 - time2)));
}
+ // 验证完成后,应该重新校验pack.mcmeta并写入
+ this.validatePackMetadata(generatedPackPath.resolve("pack.mcmeta"), packMcMeta);
+ // 优化资源包
if (Config.optimizeResourcePack()) {
this.optimizeResourcePack(generatedPackPath);
}
@@ -824,29 +833,61 @@ public abstract class AbstractPackManager implements PackManager {
}
}
- private void generatePackMetadata(Path path, Set revisions) throws IOException {
- JsonObject rawMeta;
- boolean changed = false;
- if (!Files.exists(path)) {
- rawMeta = new JsonObject();
- changed = true;
- } else {
- rawMeta = GsonHelper.readJsonFile(path).getAsJsonObject();
- }
- if (!rawMeta.has("pack")) {
- JsonObject pack = new JsonObject();
- rawMeta.add("pack", pack);
- pack.addProperty("pack_format", Config.packMinVersion().majorPackFormat());
- JsonObject supportedFormats = new JsonObject();
- supportedFormats.addProperty("min_inclusive", Config.packMinVersion().majorPackFormat());
- supportedFormats.addProperty("max_inclusive", Config.packMaxVersion().majorPackFormat());
- pack.add("supported_formats", supportedFormats);
- changed = true;
- }
- if (revisions.isEmpty()) {
- if (changed) {
- GsonHelper.writeJsonFile(rawMeta, path);
+ private void validatePackMetadata(Path path, JsonObject rawMeta) throws IOException {
+ // 获取设定的最大和最小值
+ PackVersion minVersion = Config.packMinVersion().packFormat();
+ PackVersion maxVersion = Config.packMaxVersion().packFormat();
+
+ // 设置pack
+ {
+ JsonObject packJson = new JsonObject();
+ rawMeta.add("pack", packJson);
+ JsonElement description = AdventureHelper.componentToJsonElement(AdventureHelper.miniMessage().deserialize(Config.packDescription()));
+ packJson.add("description", description);
+ // 需要旧版本兼容性
+ if (minVersion.isBelow(PackVersion.PACK_FORMAT_CHANGE_VERSION)) {
+ packJson.addProperty("pack_format", minVersion.major());
+ JsonObject supportedVersions = new JsonObject();
+ supportedVersions.addProperty("min_inclusive", minVersion.major());
+ supportedVersions.addProperty("max_inclusive", maxVersion.major());
+ packJson.add("supported_formats", supportedVersions);
}
+ // 到达了1.21.9
+ if (maxVersion.isAtOrAbove(PackVersion.PACK_FORMAT_CHANGE_VERSION)) {
+ // 同时要兼容低版本
+ packJson.add("min_format", minVersion.getAsJsonArray());
+ packJson.add("max_format", maxVersion.getAsJsonArray());
+ }
+ }
+
+ // 验证overlay
+ {
+ PackMcMeta mcMeta = new PackMcMeta(rawMeta);
+ List overlays = mcMeta.overlays();
+ if (!overlays.isEmpty()) {
+ boolean legacySupported = false;
+ for (Overlay overlay : overlays) {
+ if (overlay.minVersion().isBelow(PackVersion.PACK_FORMAT_CHANGE_VERSION)) {
+ legacySupported = true;
+ break;
+ }
+ }
+ JsonArray newOverlayEntries = new JsonArray();
+ for (Overlay overlay : overlays) {
+ newOverlayEntries.add(overlay.getAsOverlayEntry(legacySupported));
+ }
+ JsonObject overlaysJson = new JsonObject();
+ overlaysJson.add("entries", newOverlayEntries);
+ rawMeta.add("overlays", overlaysJson);
+ }
+ }
+
+ GsonHelper.writeJsonFile(rawMeta, path);
+ }
+
+ // 这里都是随便写写的,重点在之后的校验里
+ private void generateRevisionOverlays(JsonObject rawMeta, Set revisions) throws IOException {
+ if (revisions.isEmpty()) {
return;
}
JsonObject overlays;
@@ -865,18 +906,15 @@ public abstract class AbstractPackManager implements PackManager {
}
for (Revision revision : revisions) {
JsonObject entry = new JsonObject();
- if (revision.minPackVersion().major() < 65) {
- JsonArray formatsArray = new JsonArray();
- entry.add("formats", formatsArray);
- formatsArray.add(revision.minPackVersion().major());
- formatsArray.add(revision.maxPackVersion().major());
- }
+ JsonArray formatsArray = new JsonArray();
+ entry.add("formats", formatsArray);
+ formatsArray.add(revision.minPackVersion().major());
+ formatsArray.add(revision.maxPackVersion().major());
entry.add("min_format", revision.minPackVersion().getAsJsonArray());
entry.add("max_format", revision.maxPackVersion().getAsJsonArray());
entry.addProperty("directory", Config.createOverlayFolderName(revision.versionString()));
entries.add(entry);
}
- GsonHelper.writeJsonFile(rawMeta, path);
}
private void removeAllShaders(Path path) {
@@ -1186,18 +1224,8 @@ public abstract class AbstractPackManager implements PackManager {
}
}
- private void validateResourcePack(Path path) {
- Path packMcMetaPath = path.resolve("pack.mcmeta");
- PackMcMeta packMeta;
- JsonObject packMetaJson;
- try {
- packMetaJson = GsonHelper.readJsonFile(packMcMetaPath).getAsJsonObject();
- packMeta = new PackMcMeta(packMetaJson);
- } catch (IOException e) {
- this.plugin.logger().warn("Failed to read pack.mcmeta " + packMcMetaPath.toAbsolutePath(), e);
- return;
- }
-
+ private void validateResourcePack(Path path, JsonObject packMetaJson) {
+ PackMcMeta packMeta = new PackMcMeta(packMetaJson);
List segments = new ArrayList<>();
// 完全小于1.21.11或完全大于1.21.11
if (Config.packMaxVersion().isBelow(MinecraftVersion.V1_21_11) || Config.packMinVersion().isAtOrAbove(MinecraftVersion.V1_21_11)) {
@@ -1292,7 +1320,7 @@ public abstract class AbstractPackManager implements PackManager {
GsonHelper.writeJsonFile(entry.atlas(), atlasPath);
if (!atlasToAdd.containsKey(directoryName)) {
Overlay overlay = new Overlay(new PackVersion(min), new PackVersion(max), directoryName);
- atlasToAdd.put(directoryName, overlay.getAsOverlayEntry());
+ atlasToAdd.put(directoryName, overlay.getAsOverlayEntry(true));
}
} catch (IOException e) {
this.plugin.logger().warn("Failed to write atlas " + atlasPath.toAbsolutePath(), e);
@@ -1326,7 +1354,7 @@ public abstract class AbstractPackManager implements PackManager {
GsonHelper.writeJsonFile(entry.atlas(), atlasPath);
if (!atlasToAdd.containsKey(directoryName)) {
Overlay overlay = new Overlay(new PackVersion(min), new PackVersion(max), directoryName);
- atlasToAdd.put(directoryName, overlay.getAsOverlayEntry());
+ atlasToAdd.put(directoryName, overlay.getAsOverlayEntry(true));
}
} catch (IOException e) {
this.plugin.logger().warn("Failed to write atlas " + atlasPath.toAbsolutePath(), e);
@@ -1347,11 +1375,6 @@ public abstract class AbstractPackManager implements PackManager {
for (JsonElement entry : atlasToAdd.values()) {
overlayEntries.add(entry);
}
- try {
- GsonHelper.writeJsonFile(packMetaJson, packMcMetaPath);
- } catch (IOException e) {
- this.plugin.logger().warn("Failed to write pack.mcmeta", e);
- }
}
}
diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/resolution/ResolutionMergePackMcMeta.java b/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/resolution/ResolutionMergePackMcMeta.java
index 38063ac9e..ef7057ec0 100644
--- a/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/resolution/ResolutionMergePackMcMeta.java
+++ b/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/resolution/ResolutionMergePackMcMeta.java
@@ -9,7 +9,6 @@ import net.momirealms.craftengine.core.pack.conflict.PathContext;
import net.momirealms.craftengine.core.pack.mcmeta.PackVersion;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.plugin.config.Config;
-import net.momirealms.craftengine.core.util.AdventureHelper;
import net.momirealms.craftengine.core.util.GsonHelper;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.Pair;
@@ -26,13 +25,7 @@ public class ResolutionMergePackMcMeta implements Resolution {
public static final Factory FACTORY = new Factory();
public static final Set STANDARD_PACK_KEYS = ImmutableSet.of("pack", "features", "filter", "overlays", "language");
- private final String description;
-
- public ResolutionMergePackMcMeta(String description) {
- this.description = description;
- }
-
- public static void merge(Path file1, Path file2, JsonElement customDescription) throws IOException {
+ public static void merge(Path file1, Path file2) throws IOException {
// 第一步,解析全部的mcmeta文件为json对象
JsonObject mcmeta1;
try {
@@ -49,13 +42,15 @@ public class ResolutionMergePackMcMeta implements Resolution {
return;
}
JsonObject merged = new JsonObject();
- // 第三步,处理pack区域
- JsonObject pack1 = mcmeta1.getAsJsonObject("pack");
- JsonObject pack2 = mcmeta2.getAsJsonObject("pack");
- JsonObject mergedPack = new JsonObject();
- mergedPack.add("description", customDescription);
- merged.add("pack", mergedPack);
- mergePack(mergedPack, pack1, pack2);
+
+// 注释: 无需处理,由后续验证合并
+// //第二步,处理pack区域
+// JsonObject pack1 = mcmeta1.getAsJsonObject("pack");
+// JsonObject pack2 = mcmeta2.getAsJsonObject("pack");
+// JsonObject mergedPack = new JsonObject();
+// merged.add("pack", mergedPack);
+// mergePack(mergedPack, pack1, pack2);
+
// 第三步,合并overlays
List overlays = new ArrayList<>();
collectOverlays(mcmeta1.getAsJsonObject("overlays"), overlays::add);
@@ -165,14 +160,11 @@ public class ResolutionMergePackMcMeta implements Resolution {
Pair supportedVersions = getSupportedVersions(entryJson);
PackVersion min = PackVersion.getHigher(supportedVersions.left(), PackVersion.MIN_OVERLAY_VERSION);
PackVersion max = PackVersion.getHigher(supportedVersions.right(), PackVersion.MIN_OVERLAY_VERSION);
- // https://minecraft.wiki/w/Java_Edition_25w31a
- if (min.major() < 65) {
- // 旧版格式支持
- JsonArray supportedFormats = new JsonArray();
- supportedFormats.add(min.major());
- supportedFormats.add(max.major());
- entryJson.add("formats", supportedFormats);
- }
+ // 旧版格式支持
+ JsonArray supportedFormats = new JsonArray();
+ supportedFormats.add(min.major());
+ supportedFormats.add(max.major());
+ entryJson.add("formats", supportedFormats);
// 新版格式支持
JsonArray minFormat = new JsonArray();
minFormat.add(min.major());
@@ -285,7 +277,7 @@ public class ResolutionMergePackMcMeta implements Resolution {
@Override
public void run(PathContext existing, PathContext conflict) {
try {
- merge(existing.path(), conflict.path(), AdventureHelper.componentToJsonElement(AdventureHelper.miniMessage().deserialize(this.description)));
+ merge(existing.path(), conflict.path());
} catch (Exception e) {
CraftEngine.instance().logger().severe("Failed to merge pack.mcmeta when resolving file conflicts for '" + existing.path() + "' and '" + conflict.path() + "'", e);
}
@@ -299,8 +291,7 @@ public class ResolutionMergePackMcMeta implements Resolution {
public static class Factory implements ResolutionFactory {
@Override
public Resolution create(Map arguments) {
- String description = arguments.getOrDefault("description", "CraftEngine ResourcePack").toString();
- return new ResolutionMergePackMcMeta(description);
+ return new ResolutionMergePackMcMeta();
}
}
}
diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/mcmeta/Overlay.java b/core/src/main/java/net/momirealms/craftengine/core/pack/mcmeta/Overlay.java
index b995fa8cd..a40b02acc 100644
--- a/core/src/main/java/net/momirealms/craftengine/core/pack/mcmeta/Overlay.java
+++ b/core/src/main/java/net/momirealms/craftengine/core/pack/mcmeta/Overlay.java
@@ -41,7 +41,7 @@ public class Overlay {
'}';
}
- public JsonObject getAsOverlayEntry() {
+ public JsonObject getAsOverlayEntry(boolean legacy) {
JsonObject entry = new JsonObject();
entry.addProperty("directory", this.directory);
JsonArray minFormat = new JsonArray();
@@ -52,7 +52,7 @@ public class Overlay {
maxFormat.add(new JsonPrimitive(this.maxVersion.major()));
maxFormat.add(new JsonPrimitive(this.maxVersion.minor()));
entry.add("max_format", maxFormat);
- if (this.minVersion.major() < 65) {
+ if (legacy) {
JsonArray formats = new JsonArray();
formats.add(new JsonPrimitive(this.minVersion.major()));
formats.add(new JsonPrimitive(this.maxVersion.major()));
diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/mcmeta/PackVersion.java b/core/src/main/java/net/momirealms/craftengine/core/pack/mcmeta/PackVersion.java
index 2e321e26f..4022e9bd5 100644
--- a/core/src/main/java/net/momirealms/craftengine/core/pack/mcmeta/PackVersion.java
+++ b/core/src/main/java/net/momirealms/craftengine/core/pack/mcmeta/PackVersion.java
@@ -8,6 +8,7 @@ import java.util.List;
public record PackVersion(int major, int minor) implements Comparable {
public static final PackVersion MIN_PACK_VERSION = new PackVersion(15, 0); // 1.20
public static final PackVersion MIN_OVERLAY_VERSION = new PackVersion(18, 0); // 1.20
+ public static final PackVersion PACK_FORMAT_CHANGE_VERSION = new PackVersion(65, 0); // 25w31a
public static final PackVersion MAX_PACK_VERSION = new PackVersion(1000, 0); // future
public PackVersion(int major) {
diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/Config.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/Config.java
index 49fbf150b..1c1b0d093 100644
--- a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/Config.java
+++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/Config.java
@@ -66,6 +66,7 @@ public class Config {
protected List resource_pack$merge_external_zips;
protected Set resource_pack$exclude_file_extensions;
protected Path resource_pack$path;
+ protected String resource_pack$description;
protected boolean resource_pack$protection$crash_tools$method_1;
protected boolean resource_pack$protection$crash_tools$method_2;
@@ -329,6 +330,7 @@ public class Config {
// resource pack
resource_pack$path = resolvePath(config.getString("resource-pack.path", "./generated/resource_pack.zip"));
+ resource_pack$description = config.getString("resource-pack.description", "CraftEngine ResourcePack");
resource_pack$override_uniform_font = config.getBoolean("resource-pack.override-uniform-font", false);
resource_pack$generate_mod_assets = config.getBoolean("resource-pack.generate-mod-assets", false);
resource_pack$remove_tinted_leaves_particle = config.getBoolean("resource-pack.remove-tinted-leaves-particle", true);
@@ -1130,6 +1132,10 @@ public class Config {
return instance.equipment$sacrificed_vanilla_armor$humanoid_leggings;
}
+ public static String packDescription() {
+ return instance.resource_pack$description;
+ }
+
public static String sacrificedVanillaArmorType() {
return instance.equipment$sacrificed_vanilla_armor$type;
}
diff --git a/gradle.properties b/gradle.properties
index 0c853f64d..27f3fbb86 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,8 +1,8 @@
org.gradle.jvmargs=-Xmx4G
# Project settings
-project_version=0.0.66.5
-config_version=63
+project_version=0.0.66.6
+config_version=64
lang_version=46
project_group=net.momirealms
latest_supported_version=1.21.11