mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-19 15:09:15 +00:00
增强pack.mcmeta校验
This commit is contained in:
@@ -24,6 +24,8 @@ resource-pack:
|
||||
supported-version:
|
||||
min: server
|
||||
max: latest
|
||||
# The description of your resource pack
|
||||
description: "<gray>CraftEngine ResourcePack</gray>"
|
||||
# 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: "<gray>CraftEngine ResourcePack</gray>"
|
||||
- term:
|
||||
type: exact
|
||||
path: "pack.png"
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"pack": {
|
||||
"pack_format": 15,
|
||||
"description": "CraftEngine",
|
||||
"supported_formats": {
|
||||
"min_inclusive": 15,
|
||||
"max_inclusive": 1000
|
||||
},
|
||||
"min_format": 15,
|
||||
"max_format": 1000
|
||||
}
|
||||
}
|
||||
@@ -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<Revision> revisions) throws IOException {
|
||||
JsonObject rawMeta;
|
||||
boolean changed = false;
|
||||
if (!Files.exists(path)) {
|
||||
rawMeta = new JsonObject();
|
||||
changed = true;
|
||||
} else {
|
||||
rawMeta = GsonHelper.readJsonFile(path).getAsJsonObject();
|
||||
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);
|
||||
}
|
||||
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;
|
||||
// 到达了1.21.9
|
||||
if (maxVersion.isAtOrAbove(PackVersion.PACK_FORMAT_CHANGE_VERSION)) {
|
||||
// 同时要兼容低版本
|
||||
packJson.add("min_format", minVersion.getAsJsonArray());
|
||||
packJson.add("max_format", maxVersion.getAsJsonArray());
|
||||
}
|
||||
if (revisions.isEmpty()) {
|
||||
if (changed) {
|
||||
}
|
||||
|
||||
// 验证overlay
|
||||
{
|
||||
PackMcMeta mcMeta = new PackMcMeta(rawMeta);
|
||||
List<Overlay> 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<Revision> 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());
|
||||
}
|
||||
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<OverlayCombination.Segment> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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<String> 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<JsonObject> overlays = new ArrayList<>();
|
||||
collectOverlays(mcmeta1.getAsJsonObject("overlays"), overlays::add);
|
||||
@@ -165,14 +160,11 @@ public class ResolutionMergePackMcMeta implements Resolution {
|
||||
Pair<PackVersion, PackVersion> 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 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<String, Object> arguments) {
|
||||
String description = arguments.getOrDefault("description", "<gray>CraftEngine ResourcePack</gray>").toString();
|
||||
return new ResolutionMergePackMcMeta(description);
|
||||
return new ResolutionMergePackMcMeta();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()));
|
||||
|
||||
@@ -8,6 +8,7 @@ import java.util.List;
|
||||
public record PackVersion(int major, int minor) implements Comparable<PackVersion> {
|
||||
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) {
|
||||
|
||||
@@ -66,6 +66,7 @@ public class Config {
|
||||
protected List<String> resource_pack$merge_external_zips;
|
||||
protected Set<String> 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", "<gray>CraftEngine ResourcePack</gray>");
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user