mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-19 15:09:15 +00:00
记录点
This commit is contained in:
@@ -2,12 +2,14 @@ package net.momirealms.craftengine.bukkit.sound;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import net.momirealms.craftengine.bukkit.api.CraftEngineFurniture;
|
||||
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MBuiltInRegistries;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MRegistries;
|
||||
import net.momirealms.craftengine.bukkit.util.ComponentUtils;
|
||||
import net.momirealms.craftengine.bukkit.util.KeyUtils;
|
||||
import net.momirealms.craftengine.core.entity.furniture.AnchorType;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.sound.AbstractSoundManager;
|
||||
import net.momirealms.craftengine.core.sound.JukeboxSong;
|
||||
@@ -15,6 +17,7 @@ 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.VersionHelper;
|
||||
import org.bukkit.Location;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
|
||||
@@ -94,17 +94,9 @@ resource-pack:
|
||||
resolution:
|
||||
type: merge_font
|
||||
# Validate if there is any error in the resource pack, such as missing textures or models.
|
||||
# Validation may not always be accurate due to the presence of resource pack overlays.
|
||||
# If your resource pack is compliant with the standard, you can disable validation to improve the resource pack generation speed.
|
||||
validation:
|
||||
enable: true
|
||||
# Determines on which versions the resource pack validation will be performed.
|
||||
# Allowed values:
|
||||
# - 1.20.1, 1.21, 1.21.8, etc.
|
||||
# - latest: the latest client version
|
||||
# - server: the current server version
|
||||
test-versions:
|
||||
- server
|
||||
# Fix textures that are not within the atlas. It is unreasonable to always rely on plugins to fix your mistakes.
|
||||
# CraftEngine will only fix the atlas of resource pack under the first version specified in the test-versions.
|
||||
# You should strive to make your resource pack more standardized after gaining some experience with resource packs.
|
||||
|
||||
@@ -40,14 +40,16 @@ argument.parse.failure.either: "<red>Could not resolve <arg:1> or <arg:2> from '
|
||||
argument.parse.failure.namedtextcolor: "<red>'<arg:0>' is not a named text color</red>"
|
||||
info.pack.load: "Loaded pack: <arg:0>. Default namespace: <arg:1>"
|
||||
info.resource.load: "Loaded <arg:0> in <arg:1>ms (<arg:2>)"
|
||||
info.resource_pack.start: "Generating resource pack..."
|
||||
info.resource_pack.generate: "Generated resource pack in <arg:0>ms"
|
||||
info.resource_pack.validate: "Validated resource pack in <arg:0>ms"
|
||||
info.resource_pack.optimize: "Optimized resource pack in <arg:0>ms"
|
||||
info.resource_pack.generate.start: "Generating resource pack..."
|
||||
info.resource_pack.generate.finish: "Generated resource pack in <arg:0>ms"
|
||||
info.resource_pack.validate.start: "Validating resource pack... (Progress: <arg:0>/<arg:1> | Pack Format: <arg:2>~<arg:3> | Overlays: <arg:4>)"
|
||||
info.resource_pack.validate.finish: "Validated resource pack in <arg:0>ms"
|
||||
info.resource_pack.optimize.json: "> Optimizing json files..."
|
||||
info.resource_pack.optimize.texture: "> Optimizing textures..."
|
||||
info.resource_pack.optimize.result: "□ Before/After/Ratio: <arg:0>/<arg:1>/<arg:2>%"
|
||||
info.resource_pack.create: "Created resource pack zip in <arg:0>ms"
|
||||
info.resource_pack.optimize.finish: "Optimized resource pack in <arg:0>ms"
|
||||
info.resource_pack.create.start: "Creating the resource pack zip..."
|
||||
info.resource_pack.create.finish: "Created resource pack zip in <arg:0>ms"
|
||||
info.resource_pack.upload: "Completed uploading resource pack"
|
||||
info.host.self.netty_server: "Netty HTTP server started on port: <arg:0>"
|
||||
info.host.cache.load: "[<arg:0>] Loaded cached resource pack metadata"
|
||||
|
||||
@@ -40,14 +40,16 @@ argument.parse.failure.either: "<red>无法从 '<arg:0>' 解析 <arg:1> 或 <arg
|
||||
argument.parse.failure.namedtextcolor: "<red>'<arg:0>' 不是颜色代码</red>"
|
||||
info.pack.load: "已加载包: <arg:0>. 默认命名空间: <arg:1>"
|
||||
info.resource.load: "加载 <arg:0> 耗时 <arg:1>ms (<arg:2>)"
|
||||
info.resource_pack.start: "正在开始生成资源包..."
|
||||
info.resource_pack.generate: "生成资源包耗时 <arg:0>ms"
|
||||
info.resource_pack.validate: "验证资源包耗时 <arg:0>ms"
|
||||
info.resource_pack.optimize: "优化资源包耗时 <arg:0>ms"
|
||||
info.resource_pack.generate.start: "正在开始生成资源包..."
|
||||
info.resource_pack.generate.finish: "生成资源包耗时 <arg:0>ms"
|
||||
info.resource_pack.validate.start: "正在验证资源包... (进度: <arg:0>/<arg:1> | 资源包格式: <arg:2>~<arg:3> | 叠加资源包: <arg:4>)"
|
||||
info.resource_pack.validate.finish: "验证资源包耗时 <arg:0>ms"
|
||||
info.resource_pack.optimize.json: "> 正在优化json文件..."
|
||||
info.resource_pack.optimize.texture: "> 正在优化贴图文件..."
|
||||
info.resource_pack.optimize.result: "□ 优化前/优化后/比例: <arg:0>/<arg:1>/<arg:2>%"
|
||||
info.resource_pack.create: "创建资源包文件耗时 <arg:0>ms"
|
||||
info.resource_pack.optimize.finish: "优化资源包耗时 <arg:0>ms"
|
||||
info.resource_pack.create.start: "正在创建资源包压缩文件..."
|
||||
info.resource_pack.create.finish: "创建资源包文件耗时 <arg:0>ms"
|
||||
info.resource_pack.upload: "资源包上传完成"
|
||||
info.host.self.netty_server: "Netty HTTP 服务已在端口 <arg:0> 开启"
|
||||
info.host.cache.load: "[<arg:0>] 已加载缓存的资源包元数据"
|
||||
|
||||
@@ -406,19 +406,19 @@ public abstract class AbstractItemManager<I> extends AbstractModelGenerator impl
|
||||
}
|
||||
|
||||
private boolean isModernFormatRequired() {
|
||||
return Config.packMaxVersion().isAtOrAbove(MinecraftVersions.V1_21_4);
|
||||
return Config.packMaxVersion().isAtOrAbove(MinecraftVersion.V1_21_4);
|
||||
}
|
||||
|
||||
private boolean needsLegacyCompatibility() {
|
||||
return Config.packMinVersion().isBelow(MinecraftVersions.V1_21_4);
|
||||
return Config.packMinVersion().isBelow(MinecraftVersion.V1_21_4);
|
||||
}
|
||||
|
||||
private boolean needsCustomModelDataCompatibility() {
|
||||
return Config.packMinVersion().isBelow(MinecraftVersions.V1_21_2);
|
||||
return Config.packMinVersion().isBelow(MinecraftVersion.V1_21_2);
|
||||
}
|
||||
|
||||
private boolean needsItemModelCompatibility() {
|
||||
return Config.packMaxVersion().isAtOrAbove(MinecraftVersions.V1_21_2) && VersionHelper.isOrAbove1_21_2(); //todo 能否通过客户端包解决问题
|
||||
return Config.packMaxVersion().isAtOrAbove(MinecraftVersion.V1_21_2) && VersionHelper.isOrAbove1_21_2(); //todo 能否通过客户端包解决问题
|
||||
}
|
||||
|
||||
public Map<Key, IdAllocator> idAllocators() {
|
||||
|
||||
@@ -20,6 +20,8 @@ import net.momirealms.craftengine.core.pack.host.ResourcePackHosts;
|
||||
import net.momirealms.craftengine.core.pack.host.impl.NoneHost;
|
||||
import net.momirealms.craftengine.core.pack.mcmeta.Overlay;
|
||||
import net.momirealms.craftengine.core.pack.mcmeta.PackMcMeta;
|
||||
import net.momirealms.craftengine.core.pack.mcmeta.PackVersion;
|
||||
import net.momirealms.craftengine.core.pack.mcmeta.overlay.OverlayCombination;
|
||||
import net.momirealms.craftengine.core.pack.model.ItemModel;
|
||||
import net.momirealms.craftengine.core.pack.model.LegacyOverridesModel;
|
||||
import net.momirealms.craftengine.core.pack.model.ModernItemModel;
|
||||
@@ -742,8 +744,8 @@ public abstract class AbstractPackManager implements PackManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateResourcePack() throws Exception {
|
||||
this.plugin.logger().info(TranslationManager.instance().translateLog("info.resource_pack.start"));
|
||||
public void generateResourcePack() {
|
||||
this.plugin.logger().info(TranslationManager.instance().translateLog("info.resource_pack.generate.start"));
|
||||
long time1 = System.currentTimeMillis();
|
||||
|
||||
// Create cache data
|
||||
@@ -791,19 +793,22 @@ public abstract class AbstractPackManager implements PackManager {
|
||||
this.removeAllShaders(generatedPackPath);
|
||||
}
|
||||
long time2 = System.currentTimeMillis();
|
||||
this.plugin.logger().info(TranslationManager.instance().translateLog("info.resource_pack.generate", String.valueOf(time2 - time1)));
|
||||
this.plugin.logger().info(TranslationManager.instance().translateLog("info.resource_pack.generate.finish", String.valueOf(time2 - time1)));
|
||||
if (Config.validateResourcePack()) {
|
||||
for (MinecraftVersion version : Config.validationTestVersions()) {
|
||||
this.validateResourcePack(generatedPackPath, version);
|
||||
}
|
||||
this.validateResourcePack(generatedPackPath);
|
||||
}
|
||||
long time3 = System.currentTimeMillis();
|
||||
this.plugin.logger().info(TranslationManager.instance().translateLog("info.resource_pack.validate", String.valueOf(time3 - time2)));
|
||||
if (Config.validateResourcePack()) {
|
||||
this.plugin.logger().info(TranslationManager.instance().translateLog("info.resource_pack.validate.finish", String.valueOf(time3 - time2)));
|
||||
}
|
||||
if (Config.optimizeResourcePack()) {
|
||||
this.optimizeResourcePack(generatedPackPath);
|
||||
}
|
||||
long time4 = System.currentTimeMillis();
|
||||
this.plugin.logger().info(TranslationManager.instance().translateLog("info.resource_pack.optimize", String.valueOf(time4 - time3)));
|
||||
if (Config.optimizeResourcePack()) {
|
||||
this.plugin.logger().info(TranslationManager.instance().translateLog("info.resource_pack.optimize.finish", String.valueOf(time4 - time3)));
|
||||
}
|
||||
this.plugin.logger().info(TranslationManager.instance().translateLog("info.resource_pack.create.start"));
|
||||
Path finalPath = resourcePackPath();
|
||||
Files.createDirectories(finalPath.getParent());
|
||||
try {
|
||||
@@ -812,8 +817,10 @@ public abstract class AbstractPackManager implements PackManager {
|
||||
this.plugin.logger().severe("Error zipping resource pack", e);
|
||||
}
|
||||
long time5 = System.currentTimeMillis();
|
||||
this.plugin.logger().info(TranslationManager.instance().translateLog("info.resource_pack.create", String.valueOf(time5 - time4)));
|
||||
this.plugin.logger().info(TranslationManager.instance().translateLog("info.resource_pack.create.finish", String.valueOf(time5 - time4)));
|
||||
this.generationEventDispatcher.accept(generatedPackPath, finalPath);
|
||||
} catch (IOException e) {
|
||||
this.plugin.logger().severe("Error generating resource pack", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1177,8 +1184,7 @@ public abstract class AbstractPackManager implements PackManager {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("DuplicatedCode")
|
||||
private void validateResourcePack(Path path, MinecraftVersion version) {
|
||||
private void validateResourcePack(Path path) {
|
||||
Path packMcMetaPath = path.resolve("pack.mcmeta");
|
||||
PackMcMeta packMeta;
|
||||
try {
|
||||
@@ -1188,27 +1194,150 @@ public abstract class AbstractPackManager implements PackManager {
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取当前版本生效的overlays
|
||||
List<String> overlayDirectories = new ArrayList<>();
|
||||
for (Overlay overlay : packMeta.overlays()) {
|
||||
if (overlay.test(version)) {
|
||||
overlayDirectories.add(overlay.directory());
|
||||
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)) {
|
||||
OverlayCombination combination = new OverlayCombination(packMeta.overlays(), Config.packMinVersion().packFormat().major(), Config.packMaxVersion().packFormat().major());
|
||||
while (combination.hasNext()) {
|
||||
OverlayCombination.Segment segment = combination.nextSegment();
|
||||
if (segment != null) {
|
||||
segments.add(segment);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
overlayDirectories = overlayDirectories.stream().distinct().toList();
|
||||
|
||||
List<Path> rootPathList = new ArrayList<>();
|
||||
rootPathList.add(path);
|
||||
for (String directory : overlayDirectories) {
|
||||
Path resolve = path.resolve(directory);
|
||||
if (Files.isDirectory(resolve)) {
|
||||
rootPathList.add(resolve);
|
||||
// 混合版本
|
||||
else {
|
||||
OverlayCombination combinationLegacy = new OverlayCombination(packMeta.overlays(), Config.packMinVersion().packFormat().major(), MinecraftVersion.V1_21_11.packFormat().major() - 1);
|
||||
while (combinationLegacy.hasNext()) {
|
||||
OverlayCombination.Segment segment = combinationLegacy.nextSegment();
|
||||
if (segment != null) {
|
||||
segments.add(segment);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
OverlayCombination combinationModern = new OverlayCombination(packMeta.overlays(), MinecraftVersion.V1_21_11.packFormat().major(), Config.packMaxVersion().packFormat().major());
|
||||
while (combinationModern.hasNext()) {
|
||||
OverlayCombination.Segment segment = combinationModern.nextSegment();
|
||||
if (segment != null) {
|
||||
segments.add(segment);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 收集全部overlay,按照正确的顺序加载
|
||||
Path[] rootPaths = rootPathList.toArray(new Path[0]);
|
||||
AtlasFixer itemFixer = new AtlasFixer();
|
||||
AtlasFixer blockFixer = new AtlasFixer();
|
||||
|
||||
boolean hasNonOverlaySupport = false;
|
||||
if (!segments.isEmpty()) {
|
||||
// 第一个segment一定是最小的
|
||||
hasNonOverlaySupport = segments.getFirst().min() <= MinecraftVersion.V1_20_1.packFormat().major();
|
||||
}
|
||||
|
||||
for (int i = 0, size = segments.size(); i < size; i++) {
|
||||
OverlayCombination.Segment segment = segments.get(i);
|
||||
List<Path> rootPathList = new ArrayList<>();
|
||||
rootPathList.add(path);
|
||||
List<Overlay> overlayInOrder = new ArrayList<>(segment.overlays().size());
|
||||
for (Overlay overlay : packMeta.overlays()) {
|
||||
if (segment.overlays().contains(overlay)) {
|
||||
Path resolve = path.resolve(overlay.directory());
|
||||
if (Files.isDirectory(resolve)) {
|
||||
overlayInOrder.add(overlay);
|
||||
rootPathList.add(resolve);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.plugin.logger().info(TranslationManager.instance().translateLog("info.resource_pack.validate.start",
|
||||
String.valueOf(i + 1), String.valueOf(size), String.valueOf(segment.min()), String.valueOf(segment.max()), overlayInOrder.stream().map(Overlay::directory).toList().toString()));
|
||||
ValidationResult result = validateOverlayedResourcePack(rootPathList.toArray(new Path[0]), segment.max() >= MinecraftVersion.V1_21_11.packFormat().major());
|
||||
if (Config.fixTextureAtlas()) {
|
||||
// 有修复物品
|
||||
if (result.fixedItemAtlas != null) {
|
||||
itemFixer.addEntry(segment.min(), segment.max(), result.fixedItemAtlas);
|
||||
}
|
||||
// 有修复方块
|
||||
if (result.fixedBlockAtlas != null) {
|
||||
blockFixer.addEntry(segment.min(), segment.max(), result.fixedBlockAtlas);
|
||||
} else if (hasNonOverlaySupport) {
|
||||
// 如果有低版本的支持,那么要通过overlay复原atlas
|
||||
blockFixer.addEntry(segment.min(), segment.max(), Objects.requireNonNullElseGet(result.originalBlockAtlas, JsonObject::new));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 尝试修复atlas
|
||||
if (Config.fixTextureAtlas()) {
|
||||
Map<String, JsonObject> atlasToAdd = new LinkedHashMap<>();
|
||||
// 物品
|
||||
for (AtlasFixer.Entry entry : itemFixer.entries()) {
|
||||
int min = entry.min();
|
||||
int max = entry.max();
|
||||
MinecraftVersion minV = MinecraftVersion.byMajorPackFormat(min).getFirst();
|
||||
MinecraftVersion maxV = MinecraftVersion.byMajorPackFormat(max).getLast();
|
||||
String directoryName = Config.createOverlayFolderName(minV.version().replace("\\.", "_") + "-" + maxV.version().replace("\\.", "_"));
|
||||
Path atlasPath = path.resolve(directoryName)
|
||||
.resolve("assets")
|
||||
.resolve("minecraft")
|
||||
.resolve("atlases")
|
||||
.resolve("items.json");
|
||||
try {
|
||||
Files.createDirectories(atlasPath.getParent());
|
||||
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());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
this.plugin.logger().warn("Failed to write atlas " + atlasPath.toAbsolutePath(), e);
|
||||
}
|
||||
}
|
||||
// 方块
|
||||
for (AtlasFixer.Entry entry : itemFixer.entries()) {
|
||||
int min = entry.min();
|
||||
int max = entry.max();
|
||||
MinecraftVersion minV = MinecraftVersion.byMajorPackFormat(min).getFirst();
|
||||
MinecraftVersion maxV = MinecraftVersion.byMajorPackFormat(max).getLast();
|
||||
String directoryName = Config.createOverlayFolderName(minV.version().replace("\\.", "_") + "-" + maxV.version().replace("\\.", "_"));
|
||||
// 这个版本不认可overlay,得把atlas直接写进主包内
|
||||
if (min <= MinecraftVersion.V1_20_1.packFormat().major()) {
|
||||
Path atlasPath = path.resolve("assets")
|
||||
.resolve("minecraft")
|
||||
.resolve("atlases")
|
||||
.resolve("blocks.json");
|
||||
try {
|
||||
Files.createDirectories(atlasPath.getParent());
|
||||
GsonHelper.writeJsonFile(entry.atlas(), atlasPath);
|
||||
} catch (IOException e) {
|
||||
this.plugin.logger().warn("Failed to write atlas " + atlasPath.toAbsolutePath(), e);
|
||||
}
|
||||
} else {
|
||||
Path atlasPath = path.resolve(directoryName)
|
||||
.resolve("assets")
|
||||
.resolve("minecraft")
|
||||
.resolve("atlases")
|
||||
.resolve("blocks.json");
|
||||
try {
|
||||
Files.createDirectories(atlasPath.getParent());
|
||||
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());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
this.plugin.logger().warn("Failed to write atlas " + atlasPath.toAbsolutePath(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("DuplicatedCode")
|
||||
private ValidationResult validateOverlayedResourcePack(Path[] rootPaths, boolean above1_21_11) {
|
||||
Multimap<Key, Key> glyphToFonts = HashMultimap.create(128, 32); // 图片到字体的映射
|
||||
Multimap<Key, Key> modelToItemDefinitions = HashMultimap.create(128, 4); // 模型到物品的映射
|
||||
Multimap<Key, String> modelToBlockStates = HashMultimap.create(128, 32); // 模型到方块的映射
|
||||
@@ -1216,9 +1345,6 @@ public abstract class AbstractPackManager implements PackManager {
|
||||
Multimap<Key, Key> textureToEquipments = HashMultimap.create(128, 8); // 纹理到盔甲的映射
|
||||
Multimap<Key, Key> oggToSoundEvents = HashMultimap.create(128, 4); // 音频到声音的映射
|
||||
|
||||
Map<Path, JsonObject> blockAtlasJsons = new HashMap<>();
|
||||
Map<Path, JsonObject> itemAtlasJsons = new HashMap<>();
|
||||
|
||||
JsonObject lastBlocksAtlas = null;
|
||||
JsonObject lastItemAtlas = null;
|
||||
|
||||
@@ -1231,39 +1357,27 @@ public abstract class AbstractPackManager implements PackManager {
|
||||
.resolve("blocks.json");
|
||||
if (Files.exists(blockAtlasFile)) {
|
||||
try {
|
||||
JsonObject atlasJsonObject = GsonHelper.readJsonFile(blockAtlasFile).getAsJsonObject();
|
||||
blockAtlasJsons.put(blockAtlasFile, atlasJsonObject);
|
||||
lastBlocksAtlas = atlasJsonObject;
|
||||
lastBlocksAtlas = GsonHelper.readJsonFile(blockAtlasFile).getAsJsonObject();
|
||||
} catch (IOException | JsonParseException e) {
|
||||
TranslationManager.instance().log("warning.config.resource_pack.generation.malformatted_json", blockAtlasFile.toAbsolutePath().toString());
|
||||
}
|
||||
}
|
||||
Path itemAtlasFile = rootPath
|
||||
.resolve("assets")
|
||||
.resolve("minecraft")
|
||||
.resolve("atlases")
|
||||
.resolve("items.json");
|
||||
if (Files.exists(itemAtlasFile)) {
|
||||
try {
|
||||
JsonObject atlasJsonObject = GsonHelper.readJsonFile(itemAtlasFile).getAsJsonObject();
|
||||
itemAtlasJsons.put(itemAtlasFile, atlasJsonObject);
|
||||
lastItemAtlas = atlasJsonObject;
|
||||
} catch (IOException | JsonParseException e) {
|
||||
TranslationManager.instance().log("warning.config.resource_pack.generation.malformatted_json", itemAtlasFile.toAbsolutePath().toString());
|
||||
if (above1_21_11) {
|
||||
Path itemAtlasFile = rootPath
|
||||
.resolve("assets")
|
||||
.resolve("minecraft")
|
||||
.resolve("atlases")
|
||||
.resolve("items.json");
|
||||
if (Files.exists(itemAtlasFile)) {
|
||||
try {
|
||||
lastItemAtlas = GsonHelper.readJsonFile(itemAtlasFile).getAsJsonObject();
|
||||
} catch (IOException | JsonParseException e) {
|
||||
TranslationManager.instance().log("warning.config.resource_pack.generation.malformatted_json", itemAtlasFile.toAbsolutePath().toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 添加必要的基础atlas路径,方便后续修复
|
||||
Path defaultBlockAtlas = path.resolve("assets").resolve("minecraft").resolve("atlases").resolve("blocks.json");
|
||||
if (!blockAtlasJsons.containsKey(defaultBlockAtlas)) {
|
||||
blockAtlasJsons.put(defaultBlockAtlas, new JsonObject());
|
||||
}
|
||||
Path defaultItemAtlas = path.resolve("assets").resolve("minecraft").resolve("atlases").resolve("items.json");
|
||||
if (!itemAtlasJsons.containsKey(defaultItemAtlas)) {
|
||||
itemAtlasJsons.put(defaultItemAtlas, new JsonObject());
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
|
||||
@@ -1274,7 +1388,7 @@ public abstract class AbstractPackManager implements PackManager {
|
||||
*/
|
||||
Atlas blockAtlas;
|
||||
Atlas itemAtlas;
|
||||
if (version.isAtOrAbove(MinecraftVersions.V1_21_11)) {
|
||||
if (above1_21_11) {
|
||||
blockAtlas = new Atlas(ListUtils.newNonNullList(lastBlocksAtlas, this.vanillaBlockAtlas));
|
||||
itemAtlas = new Atlas(ListUtils.newNonNullList(lastItemAtlas, this.vanillaItemAtlas));
|
||||
} else {
|
||||
@@ -1292,7 +1406,7 @@ public abstract class AbstractPackManager implements PackManager {
|
||||
namespaces = FileUtils.collectNamespaces(assetsPath);
|
||||
} catch (IOException e) {
|
||||
this.plugin.logger().warn("Failed to collect namespaces for " + assetsPath.toAbsolutePath(), e);
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
for (Path namespacePath : namespaces) {
|
||||
@@ -1697,59 +1811,71 @@ public abstract class AbstractPackManager implements PackManager {
|
||||
|
||||
// 尝试修复
|
||||
if (Config.fixTextureAtlas()) {
|
||||
// 只用了方块图集,那么修复的东西丢方块图集
|
||||
if (blockAtlasInUse) {
|
||||
if (above1_21_11) {
|
||||
// 只用了方块图集,那么修复的东西丢方块图集
|
||||
if (blockAtlasInUse) {
|
||||
for (Key key : tempTextureToFix) {
|
||||
blockAtlasesToFix.put(key, entry.getKey());
|
||||
}
|
||||
}
|
||||
// 只用了物品图集,那么修复的东西丢物品图集
|
||||
if (itemAtlasInUse) {
|
||||
for (Key key : tempTextureToFix) {
|
||||
itemAtlasesToFix.put(key, entry.getKey());
|
||||
}
|
||||
}
|
||||
// 如果都没有,先暂定
|
||||
if (!itemAtlasInUse && !blockAtlasInUse) {
|
||||
for (Key key : tempTextureToFix) {
|
||||
anyAtlasesToFix.put(key, entry.getKey());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 对于较低的版本,全部塞blocks里
|
||||
for (Key key : tempTextureToFix) {
|
||||
blockAtlasesToFix.put(key, entry.getKey());
|
||||
}
|
||||
}
|
||||
// 只用了物品图集,那么修复的东西丢物品图集
|
||||
if (itemAtlasInUse) {
|
||||
for (Key key : tempTextureToFix) {
|
||||
itemAtlasesToFix.put(key, entry.getKey());
|
||||
}
|
||||
}
|
||||
// 如果都没有,先暂定
|
||||
if (!itemAtlasInUse && !blockAtlasInUse) {
|
||||
for (Key key : tempTextureToFix) {
|
||||
anyAtlasesToFix.put(key, entry.getKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Config.fixTextureAtlas() && !Config.enableObfuscation()) {
|
||||
// 获取两个 Multimap 的所有 key
|
||||
// 找出相同的 key
|
||||
Set<Key> commonKeys = new LinkedHashSet<>(blockAtlasesToFix.keySet());
|
||||
commonKeys.retainAll(itemAtlasesToFix.keySet());
|
||||
ValidationResult result = null;
|
||||
|
||||
// 都是有问题的模型
|
||||
if (!commonKeys.isEmpty()) {
|
||||
for (Key sprite : commonKeys) {
|
||||
List<Key> duplicated = new ArrayList<>();
|
||||
duplicated.addAll(blockAtlasesToFix.get(sprite));
|
||||
duplicated.addAll(itemAtlasesToFix.get(sprite));
|
||||
TranslationManager.instance().log("warning.config.resource_pack.generation.duplicated_sprite", duplicated.toString(), sprite.asString(), "minecraft:textures/atlas/blocks.png", "minecraft:textures/atlas/items.png");
|
||||
for (Key duplicatedModel : duplicated) {
|
||||
// model已经塌房了,就不进入后续遍历了
|
||||
blockModels.remove(duplicatedModel);
|
||||
itemModels.remove(duplicatedModel);
|
||||
if (Config.fixTextureAtlas() && !Config.enableObfuscation()) {
|
||||
|
||||
if (above1_21_11) {
|
||||
// 获取两个 Multimap 的所有 key
|
||||
// 找出相同的 key
|
||||
Set<Key> commonKeys = new LinkedHashSet<>(blockAtlasesToFix.keySet());
|
||||
commonKeys.retainAll(itemAtlasesToFix.keySet());
|
||||
|
||||
// 都是有问题的模型
|
||||
if (!commonKeys.isEmpty()) {
|
||||
for (Key sprite : commonKeys) {
|
||||
List<Key> duplicated = new ArrayList<>();
|
||||
duplicated.addAll(blockAtlasesToFix.get(sprite));
|
||||
duplicated.addAll(itemAtlasesToFix.get(sprite));
|
||||
TranslationManager.instance().log("warning.config.resource_pack.generation.duplicated_sprite", duplicated.toString(), sprite.asString(), "minecraft:textures/atlas/blocks.png", "minecraft:textures/atlas/items.png");
|
||||
for (Key duplicatedModel : duplicated) {
|
||||
// model已经塌房了,就不进入后续遍历了
|
||||
blockModels.remove(duplicatedModel);
|
||||
itemModels.remove(duplicatedModel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 将任意atlas的优先分配到items上,非必要不要到blocks上
|
||||
for (Map.Entry<Key, Collection<Key>> entry : anyAtlasesToFix.asMap().entrySet()) {
|
||||
if (blockAtlasesToFix.containsKey(entry.getKey())) {
|
||||
blockAtlasesToFix.putAll(entry.getKey(), entry.getValue());
|
||||
} else {
|
||||
itemAtlasesToFix.putAll(entry.getKey(), entry.getValue());
|
||||
// 将任意atlas的优先分配到items上,非必要不要到blocks上
|
||||
for (Map.Entry<Key, Collection<Key>> entry : anyAtlasesToFix.asMap().entrySet()) {
|
||||
if (blockAtlasesToFix.containsKey(entry.getKey())) {
|
||||
blockAtlasesToFix.putAll(entry.getKey(), entry.getValue());
|
||||
} else {
|
||||
itemAtlasesToFix.putAll(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 清空任意atlas分配,因为已经重分配了
|
||||
anyAtlasesToFix.clear();
|
||||
// 清空任意atlas分配,因为已经重分配了
|
||||
anyAtlasesToFix.clear();
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -1757,13 +1883,7 @@ public abstract class AbstractPackManager implements PackManager {
|
||||
后续我们先对剩余的正常模型进行贴图路径验证(此阶段不验证那些存在atlas问题的模型,理论已被全部移除)
|
||||
|
||||
*/
|
||||
|
||||
// 如果最低支持版本太低了,那么全部塞blocks.json里
|
||||
if (!Config.packMinVersion().isAtOrAbove(MinecraftVersions.V1_21_11)) {
|
||||
blockAtlasesToFix.putAll(itemAtlasesToFix);
|
||||
itemAtlasesToFix.clear();
|
||||
}
|
||||
|
||||
JsonObject fixedItemAtlas = null;
|
||||
if (!itemAtlasesToFix.isEmpty() && itemAtlas != null) {
|
||||
List<JsonObject> sourcesToAdd = new ArrayList<>(itemAtlasesToFix.size());
|
||||
for (Key itemTexture : itemAtlasesToFix.keySet()) {
|
||||
@@ -1773,25 +1893,18 @@ public abstract class AbstractPackManager implements PackManager {
|
||||
source.addProperty("resource", itemTexture.asString());
|
||||
sourcesToAdd.add(source);
|
||||
}
|
||||
for (Map.Entry<Path, JsonObject> atlas : itemAtlasJsons.entrySet()) {
|
||||
JsonObject right = atlas.getValue();
|
||||
JsonArray sources = right.getAsJsonArray("sources");
|
||||
if (sources == null) {
|
||||
sources = new JsonArray();
|
||||
right.add("sources", sources);
|
||||
}
|
||||
for (JsonObject source : sourcesToAdd) {
|
||||
sources.add(source);
|
||||
}
|
||||
try {
|
||||
Files.createDirectories(atlas.getKey().getParent());
|
||||
GsonHelper.writeJsonFile(right, atlas.getKey());
|
||||
} catch (IOException e) {
|
||||
this.plugin.logger().warn("Failed to write atlas to json file", e);
|
||||
}
|
||||
fixedItemAtlas = lastItemAtlas == null ? new JsonObject() : lastItemAtlas;
|
||||
JsonArray sources = fixedItemAtlas.getAsJsonArray("sources");
|
||||
if (sources == null) {
|
||||
sources = new JsonArray();
|
||||
fixedItemAtlas.add("sources", sources);
|
||||
}
|
||||
for (JsonObject source : sourcesToAdd) {
|
||||
sources.add(source);
|
||||
}
|
||||
}
|
||||
|
||||
JsonObject fixedBlockAtlas = null;
|
||||
if (!blockAtlasesToFix.isEmpty()) {
|
||||
List<JsonObject> sourcesToAdd = new ArrayList<>(blockAtlasesToFix.size());
|
||||
for (Key blockTexture : blockAtlasesToFix.keySet()) {
|
||||
@@ -1801,23 +1914,20 @@ public abstract class AbstractPackManager implements PackManager {
|
||||
source.addProperty("resource", blockTexture.asString());
|
||||
sourcesToAdd.add(source);
|
||||
}
|
||||
for (Map.Entry<Path, JsonObject> atlas : blockAtlasJsons.entrySet()) {
|
||||
JsonObject right = atlas.getValue();
|
||||
JsonArray sources = right.getAsJsonArray("sources");
|
||||
if (sources == null) {
|
||||
sources = new JsonArray();
|
||||
right.add("sources", sources);
|
||||
}
|
||||
for (JsonObject source : sourcesToAdd) {
|
||||
sources.add(source);
|
||||
}
|
||||
try {
|
||||
Files.createDirectories(atlas.getKey().getParent());
|
||||
GsonHelper.writeJsonFile(right, atlas.getKey());
|
||||
} catch (IOException e) {
|
||||
this.plugin.logger().warn("Failed to write atlas to json file", e);
|
||||
}
|
||||
fixedBlockAtlas = lastBlocksAtlas == null ? new JsonObject() : lastBlocksAtlas;
|
||||
JsonArray sources = fixedBlockAtlas.getAsJsonArray("sources");
|
||||
if (sources == null) {
|
||||
sources = new JsonArray();
|
||||
fixedBlockAtlas.add("sources", sources);
|
||||
}
|
||||
for (JsonObject source : sourcesToAdd) {
|
||||
sources.add(source);
|
||||
}
|
||||
}
|
||||
|
||||
// 至少有一个修复
|
||||
if (fixedBlockAtlas != null || fixedItemAtlas != null) {
|
||||
result = new ValidationResult(fixedItemAtlas, lastItemAtlas, fixedBlockAtlas, lastBlocksAtlas);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1861,12 +1971,23 @@ public abstract class AbstractPackManager implements PackManager {
|
||||
break outer;
|
||||
}
|
||||
}
|
||||
TranslationManager.instance().log("warning.config.resource_pack.generation.missing_model_texture", entry.getValue().stream().distinct().toList().toString(), texturePath);
|
||||
TranslationManager.instance().log("warning.config.resource_pack.generation.missing_model_texture", entry.getValue().toString(), texturePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result == null) {
|
||||
result = new ValidationResult(null, lastItemAtlas, null, lastBlocksAtlas);
|
||||
}
|
||||
|
||||
// todo 验证 unstitch 和 paletted permutations
|
||||
return result;
|
||||
}
|
||||
|
||||
protected record ValidationResult(JsonObject fixedItemAtlas,
|
||||
JsonObject originalItemAtlas,
|
||||
JsonObject fixedBlockAtlas,
|
||||
JsonObject originalBlockAtlas) {
|
||||
}
|
||||
|
||||
// 经过这一步拿到的模型为包含全部父贴图的模型
|
||||
@@ -1997,7 +2118,7 @@ public abstract class AbstractPackManager implements PackManager {
|
||||
|
||||
private void generateParticle(Path generatedPackPath) {
|
||||
if (!Config.removeTintedLeavesParticle()) return;
|
||||
if (Config.packMaxVersion().isBelow(MinecraftVersions.V1_21_5)) return;
|
||||
if (Config.packMaxVersion().isBelow(MinecraftVersion.V1_21_5)) return;
|
||||
JsonObject particleJson = new JsonObject();
|
||||
JsonArray textures = new JsonArray();
|
||||
textures.add("empty");
|
||||
@@ -2033,8 +2154,8 @@ public abstract class AbstractPackManager implements PackManager {
|
||||
List<Tuple<Key, Boolean, Boolean>> collectedTrims = new ArrayList<>();
|
||||
|
||||
// 为trim类型提供的两个兼容性值
|
||||
boolean needLegacyCompatibility = Config.packMinVersion().isBelow(MinecraftVersions.V1_21_2);
|
||||
boolean needModernCompatibility = Config.packMaxVersion().isAtOrAbove(MinecraftVersions.V1_21_2);
|
||||
boolean needLegacyCompatibility = Config.packMinVersion().isBelow(MinecraftVersion.V1_21_2);
|
||||
boolean needModernCompatibility = Config.packMaxVersion().isAtOrAbove(MinecraftVersion.V1_21_2);
|
||||
|
||||
for (Equipment equipment : this.plugin.itemManager().equipments().values()) {
|
||||
if (equipment instanceof ComponentBasedEquipment componentBasedEquipment) {
|
||||
@@ -2214,7 +2335,7 @@ public abstract class AbstractPackManager implements PackManager {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Config.packMaxVersion().isAtOrAbove(MinecraftVersions.V1_21_4)) {
|
||||
if (Config.packMaxVersion().isAtOrAbove(MinecraftVersion.V1_21_4)) {
|
||||
Path equipmentPath = generatedPackPath
|
||||
.resolve("assets")
|
||||
.resolve(assetId.namespace())
|
||||
@@ -2247,7 +2368,7 @@ public abstract class AbstractPackManager implements PackManager {
|
||||
this.plugin.logger().severe("Error writing equipment file", e);
|
||||
}
|
||||
}
|
||||
if (Config.packMaxVersion().isAtOrAbove(MinecraftVersions.V1_21_2) && Config.packMinVersion().isBelow(MinecraftVersions.V1_21_4)) {
|
||||
if (Config.packMaxVersion().isAtOrAbove(MinecraftVersion.V1_21_2) && Config.packMinVersion().isBelow(MinecraftVersion.V1_21_4)) {
|
||||
Path equipmentPath = generatedPackPath
|
||||
.resolve("assets")
|
||||
.resolve(assetId.namespace())
|
||||
@@ -2303,7 +2424,7 @@ public abstract class AbstractPackManager implements PackManager {
|
||||
return null;
|
||||
}
|
||||
boolean shouldPreserve = false;
|
||||
if (Config.packMinVersion().isBelow(MinecraftVersions.V1_21_2)) {
|
||||
if (Config.packMinVersion().isBelow(MinecraftVersion.V1_21_2)) {
|
||||
Path legacyTarget = generatedPackPath
|
||||
.resolve("assets")
|
||||
.resolve(assetId.namespace())
|
||||
@@ -2323,7 +2444,7 @@ public abstract class AbstractPackManager implements PackManager {
|
||||
shouldPreserve = true;
|
||||
}
|
||||
}
|
||||
if (Config.packMaxVersion().isAtOrAbove(MinecraftVersions.V1_21_2)) {
|
||||
if (Config.packMaxVersion().isAtOrAbove(MinecraftVersion.V1_21_2)) {
|
||||
Path modernTarget = generatedPackPath
|
||||
.resolve("assets")
|
||||
.resolve(assetId.namespace())
|
||||
@@ -2362,7 +2483,7 @@ public abstract class AbstractPackManager implements PackManager {
|
||||
return null;
|
||||
}
|
||||
boolean shouldPreserve = false;
|
||||
if (Config.packMinVersion().isBelow(MinecraftVersions.V1_21_2)) {
|
||||
if (Config.packMinVersion().isBelow(MinecraftVersion.V1_21_2)) {
|
||||
Path legacyTarget = generatedPackPath
|
||||
.resolve("assets")
|
||||
.resolve(assetId.namespace())
|
||||
@@ -2382,7 +2503,7 @@ public abstract class AbstractPackManager implements PackManager {
|
||||
shouldPreserve = true;
|
||||
}
|
||||
}
|
||||
if (Config.packMaxVersion().isAtOrAbove(MinecraftVersions.V1_21_2)) {
|
||||
if (Config.packMaxVersion().isAtOrAbove(MinecraftVersion.V1_21_2)) {
|
||||
Path modernTarget = generatedPackPath
|
||||
.resolve("assets")
|
||||
.resolve(assetId.namespace())
|
||||
@@ -2665,8 +2786,8 @@ public abstract class AbstractPackManager implements PackManager {
|
||||
}
|
||||
|
||||
private void generateModernItemModels1_21_2(Path generatedPackPath) {
|
||||
if (Config.packMaxVersion().isBelow(MinecraftVersions.V1_21_2)) return;
|
||||
if (Config.packMinVersion().isAtOrAbove(MinecraftVersions.V1_21_4)) return;
|
||||
if (Config.packMaxVersion().isBelow(MinecraftVersion.V1_21_2)) return;
|
||||
if (Config.packMinVersion().isAtOrAbove(MinecraftVersion.V1_21_4)) return;
|
||||
|
||||
// 此段代码生成1.21.2专用的item model文件,情况非常复杂!
|
||||
for (Map.Entry<Key, TreeSet<LegacyOverridesModel>> entry : this.plugin.itemManager().modernItemModels1_21_2().entrySet()) {
|
||||
@@ -2748,7 +2869,7 @@ public abstract class AbstractPackManager implements PackManager {
|
||||
}
|
||||
|
||||
private void generateModernItemModels1_21_4(Path generatedPackPath, Consumer<Revision> callback) {
|
||||
if (Config.packMaxVersion().isBelow(MinecraftVersions.V1_21_4)) return;
|
||||
if (Config.packMaxVersion().isBelow(MinecraftVersion.V1_21_4)) return;
|
||||
for (Map.Entry<Key, ModernItemModel> entry : this.plugin.itemManager().modernItemModels1_21_4().entrySet()) {
|
||||
Key key = entry.getKey();
|
||||
Path itemPath = generatedPackPath
|
||||
@@ -2802,7 +2923,7 @@ public abstract class AbstractPackManager implements PackManager {
|
||||
}
|
||||
|
||||
private void generateModernItemOverrides(Path generatedPackPath, Consumer<Revision> callback) {
|
||||
if (Config.packMaxVersion().isBelow(MinecraftVersions.V1_21_4)) return;
|
||||
if (Config.packMaxVersion().isBelow(MinecraftVersion.V1_21_4)) return;
|
||||
for (Map.Entry<Key, TreeMap<Integer, ModernItemModel>> entry : this.plugin.itemManager().modernItemOverrides().entrySet()) {
|
||||
Key vanillaItemModel = entry.getKey();
|
||||
Path overridedItemPath = generatedPackPath
|
||||
@@ -2893,7 +3014,7 @@ public abstract class AbstractPackManager implements PackManager {
|
||||
}
|
||||
|
||||
private void generateLegacyItemOverrides(Path generatedPackPath) {
|
||||
if (Config.packMinVersion().isAtOrAbove(MinecraftVersions.V1_21_4)) return;
|
||||
if (Config.packMinVersion().isAtOrAbove(MinecraftVersion.V1_21_4)) return;
|
||||
for (Map.Entry<Key, TreeSet<LegacyOverridesModel>> entry : this.plugin.itemManager().legacyItemOverrides().entrySet()) {
|
||||
Key vanillaLegacyModel = entry.getKey();
|
||||
Path overridedItemPath = generatedPackPath
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
package net.momirealms.craftengine.core.pack;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
class AtlasFixer {
|
||||
private final List<Entry> entries;
|
||||
|
||||
public AtlasFixer() {
|
||||
this.entries = new ArrayList<>();
|
||||
}
|
||||
|
||||
// 理论是从小到大加的
|
||||
public void addEntry(int min, int max, JsonObject atlas) {
|
||||
if (this.entries.isEmpty()) {
|
||||
this.entries.add(new Entry(min, max, atlas));
|
||||
} else {
|
||||
Entry last = this.entries.getLast();
|
||||
// 相同则扩大区间
|
||||
if (last.atlas.equals(atlas)) {
|
||||
last.setMax(max);
|
||||
}
|
||||
// 不同则另加元素
|
||||
else {
|
||||
this.entries.add(new Entry(min, max, atlas));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<Entry> entries() {
|
||||
return entries;
|
||||
}
|
||||
|
||||
protected static class Entry {
|
||||
private int min, max;
|
||||
private final JsonObject atlas;
|
||||
|
||||
public Entry(int min, int max, JsonObject atlas) {
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
this.atlas = atlas;
|
||||
}
|
||||
|
||||
public int min() {
|
||||
return min;
|
||||
}
|
||||
|
||||
public int max() {
|
||||
return max;
|
||||
}
|
||||
|
||||
public JsonObject atlas() {
|
||||
return atlas;
|
||||
}
|
||||
|
||||
public void setMin(int min) {
|
||||
this.min = min;
|
||||
}
|
||||
|
||||
public void setMax(int max) {
|
||||
this.max = max;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,33 @@ public class Overlay {
|
||||
this.maxVersion = supportedVersions.right();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Overlay{" +
|
||||
"minVersion=" + minVersion +
|
||||
", maxVersion=" + maxVersion +
|
||||
", directory='" + directory + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
public JsonObject getAsOverlayEntry() {
|
||||
JsonObject entry = new JsonObject();
|
||||
entry.addProperty("directory", this.directory);
|
||||
JsonArray minFormat = new JsonArray();
|
||||
minFormat.add(new JsonPrimitive(this.minVersion.major()));
|
||||
minFormat.add(new JsonPrimitive(this.minVersion.minor()));
|
||||
entry.add("min_format", minFormat);
|
||||
JsonArray maxFormat = new JsonArray();
|
||||
maxFormat.add(new JsonPrimitive(this.maxVersion.major()));
|
||||
maxFormat.add(new JsonPrimitive(this.maxVersion.minor()));
|
||||
entry.add("max_format", maxFormat);
|
||||
JsonArray formats = new JsonArray();
|
||||
formats.add(new JsonPrimitive(this.minVersion.major()));
|
||||
formats.add(new JsonPrimitive(this.maxVersion.major()));
|
||||
entry.add("formats", formats);
|
||||
return entry;
|
||||
}
|
||||
|
||||
public PackVersion minVersion() {
|
||||
return minVersion;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,10 @@ public record PackVersion(int major, int minor) implements Comparable<PackVersio
|
||||
public static final PackVersion MIN_PACK_VERSION = new PackVersion(15, 0); // 1.20
|
||||
public static final PackVersion MAX_PACK_VERSION = new PackVersion(1000, 0); // future
|
||||
|
||||
public PackVersion(int major) {
|
||||
this(major, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@NotNull PackVersion o) {
|
||||
// 首先比较 major 版本
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
package net.momirealms.craftengine.core.pack.mcmeta.overlay;
|
||||
|
||||
import net.momirealms.craftengine.core.pack.mcmeta.Overlay;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class OverlayCombination {
|
||||
private final List<VersionBasedEvent> versionBasedEvents;
|
||||
private final List<Overlay> currentOverlays;
|
||||
private int cursor;
|
||||
private int version;
|
||||
|
||||
public OverlayCombination(List<Overlay> overlays, int minVersion, int maxVersion) {
|
||||
this.versionBasedEvents = new ArrayList<>();
|
||||
this.currentOverlays = new ArrayList<>();
|
||||
this.version = minVersion;
|
||||
this.cursor = 0;
|
||||
|
||||
Map<Integer, List<Event>> eventsByVersion = new TreeMap<>();
|
||||
eventsByVersion.computeIfAbsent(minVersion, k -> new ArrayList<>());
|
||||
eventsByVersion.computeIfAbsent(maxVersion + 1, k -> new ArrayList<>());
|
||||
for (Overlay overlay : overlays) {
|
||||
if (overlay.minVersion().major() > maxVersion) {
|
||||
continue;
|
||||
}
|
||||
if (overlay.maxVersion().major() < minVersion) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 取最小中的较大值
|
||||
int join = Math.max(overlay.minVersion().major(), minVersion);
|
||||
// 去最大中的较小值
|
||||
int leave = Math.min(overlay.maxVersion().major(), maxVersion);
|
||||
List<Event> joinEvents = eventsByVersion.computeIfAbsent(join, k -> new ArrayList<>());
|
||||
joinEvents.add(new Event(overlay, Operation.JOIN));
|
||||
List<Event> leaveEvents = eventsByVersion.computeIfAbsent(leave + 1, k -> new ArrayList<>());
|
||||
leaveEvents.add(new Event(overlay, Operation.LEAVE));
|
||||
}
|
||||
|
||||
for (Map.Entry<Integer, List<Event>> entry : eventsByVersion.entrySet()) {
|
||||
this.versionBasedEvents.add(new VersionBasedEvent(entry.getKey(), entry.getValue()));
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
return this.cursor < this.versionBasedEvents.size();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public OverlayCombination.Segment nextSegment() {
|
||||
Segment next = next();
|
||||
if (next == null) {
|
||||
return null;
|
||||
}
|
||||
// 第一次100%有问题
|
||||
if (next.min > next.max) {
|
||||
return next();
|
||||
}
|
||||
return next;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private OverlayCombination.Segment next() {
|
||||
// 已经没有事件里
|
||||
if (this.cursor >= this.versionBasedEvents.size()) {
|
||||
return null;
|
||||
}
|
||||
// 获取事件
|
||||
VersionBasedEvent events = this.versionBasedEvents.get(this.cursor);
|
||||
// 将上一个版本和上次记录的版本打为一个overlay返回
|
||||
Segment segment = new Segment(this.version, events.version - 1, Set.copyOf(this.currentOverlays));
|
||||
this.version = events.version;
|
||||
// 变更当前成员
|
||||
for (Event event : events.events) {
|
||||
if (event.operation() == Operation.LEAVE) {
|
||||
this.currentOverlays.remove(event.overlay);
|
||||
} else if (event.operation() == Operation.JOIN) {
|
||||
this.currentOverlays.add(event.overlay);
|
||||
}
|
||||
}
|
||||
this.cursor++;
|
||||
return segment;
|
||||
}
|
||||
|
||||
public record Segment(int min, int max, Set<Overlay> overlays) {
|
||||
|
||||
@Override
|
||||
public @NotNull String toString() {
|
||||
return "OverlaySegment{" +
|
||||
"min=" + min +
|
||||
", max=" + max +
|
||||
", overlays=" + overlays +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
record Event(Overlay overlay, Operation operation) {
|
||||
}
|
||||
|
||||
record VersionBasedEvent(int version, List<Event> events) {
|
||||
}
|
||||
|
||||
enum Operation {
|
||||
JOIN, LEAVE
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,6 @@ import com.google.gson.JsonObject;
|
||||
import net.momirealms.craftengine.core.pack.revision.Revision;
|
||||
import net.momirealms.craftengine.core.util.GsonHelper;
|
||||
import net.momirealms.craftengine.core.util.MinecraftVersion;
|
||||
import net.momirealms.craftengine.core.util.MinecraftVersions;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -33,13 +32,13 @@ public class ModernItemModel {
|
||||
|
||||
public JsonObject toJson(MinecraftVersion version) {
|
||||
JsonObject json = new JsonObject();
|
||||
if (this.oversizedInGui && version.isAtOrAbove(MinecraftVersions.V1_21_6)) {
|
||||
if (this.oversizedInGui && version.isAtOrAbove(MinecraftVersion.V1_21_6)) {
|
||||
json.addProperty("oversized_in_gui", true);
|
||||
}
|
||||
if (!this.handAnimationOnSwap) {
|
||||
json.addProperty("hand_animation_on_swap", false);
|
||||
}
|
||||
if (this.swapAnimationScale != 1.0f && version.isAtOrAbove(MinecraftVersions.V1_21_11)) {
|
||||
if (this.swapAnimationScale != 1.0f && version.isAtOrAbove(MinecraftVersion.V1_21_11)) {
|
||||
json.addProperty("swap_animation_scale", this.swapAnimationScale);
|
||||
}
|
||||
json.add("model", this.itemModel.apply(version));
|
||||
|
||||
@@ -7,7 +7,6 @@ import net.momirealms.craftengine.core.pack.revision.Revision;
|
||||
import net.momirealms.craftengine.core.pack.revision.Revisions;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.MinecraftVersion;
|
||||
import net.momirealms.craftengine.core.util.MinecraftVersions;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
@@ -38,7 +37,7 @@ public class DisplayContextSelectProperty implements SelectProperty {
|
||||
|
||||
@Override
|
||||
public @Nullable JsonElement remap(JsonElement element, MinecraftVersion version) {
|
||||
if (version.isBelow(MinecraftVersions.V1_21_9) && element instanceof JsonPrimitive primitive && primitive.isString()) {
|
||||
if (version.isBelow(MinecraftVersion.V1_21_9) && element instanceof JsonPrimitive primitive && primitive.isString()) {
|
||||
if (primitive.getAsString().equals("on_shelf")) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import net.momirealms.craftengine.core.pack.revision.Revision;
|
||||
import net.momirealms.craftengine.core.pack.revision.Revisions;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.MinecraftVersion;
|
||||
import net.momirealms.craftengine.core.util.MinecraftVersions;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -31,7 +30,7 @@ public class PlayerHeadSpecialModel implements SpecialModel {
|
||||
@Override
|
||||
public JsonObject apply(MinecraftVersion version) {
|
||||
JsonObject json = new JsonObject();
|
||||
if (version.isAtOrAbove(MinecraftVersions.V1_21_6)) {
|
||||
if (version.isAtOrAbove(MinecraftVersion.V1_21_6)) {
|
||||
json.addProperty("type", type().toString());
|
||||
} else {
|
||||
json.addProperty("type", SpecialModels.HEAD.toString());
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package net.momirealms.craftengine.core.pack.revision;
|
||||
|
||||
import net.momirealms.craftengine.core.util.MinecraftVersion;
|
||||
import net.momirealms.craftengine.core.util.MinecraftVersions;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@@ -37,7 +36,7 @@ public interface Revision {
|
||||
|
||||
@Override
|
||||
public MinecraftVersion maxVersion() {
|
||||
return MinecraftVersions.FUTURE;
|
||||
return MinecraftVersion.FUTURE;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -61,7 +60,7 @@ public interface Revision {
|
||||
@Override
|
||||
public int maxPackVersion() {
|
||||
// todo 重构revision系统
|
||||
return MinecraftVersions.FUTURE.packFormat().major();
|
||||
return MinecraftVersion.FUTURE.packFormat().major();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package net.momirealms.craftengine.core.pack.revision;
|
||||
|
||||
import net.momirealms.craftengine.core.util.MinecraftVersions;
|
||||
import net.momirealms.craftengine.core.util.MinecraftVersion;
|
||||
|
||||
public final class Revisions {
|
||||
private Revisions() {}
|
||||
|
||||
public static final Revision SINCE_1_21_6 = Revision.since(MinecraftVersions.V1_21_6);
|
||||
public static final Revision SINCE_1_21_2 = Revision.since(MinecraftVersions.V1_21_2);
|
||||
public static final Revision SINCE_1_21_9 = Revision.since(MinecraftVersions.V1_21_9);
|
||||
public static final Revision SINCE_1_21_6 = Revision.since(MinecraftVersion.V1_21_6);
|
||||
public static final Revision SINCE_1_21_2 = Revision.since(MinecraftVersion.V1_21_2);
|
||||
public static final Revision SINCE_1_21_9 = Revision.since(MinecraftVersion.V1_21_9);
|
||||
}
|
||||
|
||||
@@ -611,12 +611,12 @@ public class Config {
|
||||
|
||||
private static MinecraftVersion getVersion(String version) {
|
||||
if (version.equalsIgnoreCase("latest")) {
|
||||
return new MinecraftVersion(PluginProperties.getValue("latest-version"));
|
||||
return MinecraftVersion.byName(PluginProperties.getValue("latest-version"));
|
||||
}
|
||||
if (version.equalsIgnoreCase("server")) {
|
||||
return VersionHelper.MINECRAFT_VERSION;
|
||||
}
|
||||
return MinecraftVersion.parse(version);
|
||||
return MinecraftVersion.byName(version);
|
||||
}
|
||||
|
||||
public static Locale forcedLocale() {
|
||||
|
||||
@@ -1,13 +1,25 @@
|
||||
package net.momirealms.craftengine.core.util;
|
||||
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import net.momirealms.craftengine.core.pack.mcmeta.PackVersion;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
public class MinecraftVersion implements Comparable<MinecraftVersion> {
|
||||
private static final Map<Integer, PackVersion> PACK_FORMATS = new HashMap<>();
|
||||
|
||||
public final class MinecraftVersion implements Comparable<MinecraftVersion> {
|
||||
public static final Map<Integer, PackVersion> PACK_FORMATS = new HashMap<>();
|
||||
static {
|
||||
PACK_FORMATS.put(1_17_00, new PackVersion(7, 0));
|
||||
PACK_FORMATS.put(1_17_01, new PackVersion(7, 0));
|
||||
PACK_FORMATS.put(1_18_00, new PackVersion(8, 0));
|
||||
PACK_FORMATS.put(1_18_01, new PackVersion(8, 0));
|
||||
PACK_FORMATS.put(1_18_02, new PackVersion(8, 0));
|
||||
PACK_FORMATS.put(1_19_00, new PackVersion(9, 0));
|
||||
PACK_FORMATS.put(1_19_01, new PackVersion(9, 0));
|
||||
PACK_FORMATS.put(1_19_02, new PackVersion(9, 0));
|
||||
PACK_FORMATS.put(1_19_03, new PackVersion(12, 0));
|
||||
PACK_FORMATS.put(1_19_04, new PackVersion(13, 0));
|
||||
PACK_FORMATS.put(1_20_00, new PackVersion(15, 0));
|
||||
PACK_FORMATS.put(1_20_01, new PackVersion(15, 0));
|
||||
PACK_FORMATS.put(1_20_02, new PackVersion(18, 0));
|
||||
@@ -27,15 +39,62 @@ public final class MinecraftVersion implements Comparable<MinecraftVersion> {
|
||||
PACK_FORMATS.put(1_21_09, new PackVersion(69, 0));
|
||||
PACK_FORMATS.put(1_21_10, new PackVersion(69, 0));
|
||||
PACK_FORMATS.put(1_21_11, new PackVersion(75, 0));
|
||||
PACK_FORMATS.put(99_99_99, new PackVersion(1000, 0));
|
||||
PACK_FORMATS.put(1_26_01, new PackVersion(76, 0));
|
||||
PACK_FORMATS.put(1_99_99, new PackVersion(1000, 0));
|
||||
}
|
||||
|
||||
private static final Map<String, MinecraftVersion> BY_NAME = new LinkedHashMap<>();
|
||||
private static final Multimap<Integer, MinecraftVersion> BY_PACK_FORMAT = ArrayListMultimap.create();
|
||||
public static final MinecraftVersion V1_17 = new MinecraftVersion("1.17");
|
||||
public static final MinecraftVersion V1_17_1 = new MinecraftVersion("1.17.1");
|
||||
public static final MinecraftVersion V1_18 = new MinecraftVersion("1.18");
|
||||
public static final MinecraftVersion V1_18_1 = new MinecraftVersion("1.18.1");
|
||||
public static final MinecraftVersion V1_18_2 = new MinecraftVersion("1.18.2");
|
||||
public static final MinecraftVersion V1_19 = new MinecraftVersion("1.19");
|
||||
public static final MinecraftVersion V1_19_1 = new MinecraftVersion("1.19.1");
|
||||
public static final MinecraftVersion V1_19_2 = new MinecraftVersion("1.19.2");
|
||||
public static final MinecraftVersion V1_19_3 = new MinecraftVersion("1.19.3");
|
||||
public static final MinecraftVersion V1_19_4 = new MinecraftVersion("1.19.4");
|
||||
public static final MinecraftVersion V1_20 = new MinecraftVersion("1.20");
|
||||
public static final MinecraftVersion V1_20_1 = new MinecraftVersion("1.20.1");
|
||||
public static final MinecraftVersion V1_20_2 = new MinecraftVersion("1.20.2");
|
||||
public static final MinecraftVersion V1_20_3 = new MinecraftVersion("1.20.3");
|
||||
public static final MinecraftVersion V1_20_4 = new MinecraftVersion("1.20.4");
|
||||
public static final MinecraftVersion V1_20_5 = new MinecraftVersion("1.20.5");
|
||||
public static final MinecraftVersion V1_20_6 = new MinecraftVersion("1.20.6");
|
||||
public static final MinecraftVersion V1_21 = new MinecraftVersion("1.21");
|
||||
public static final MinecraftVersion V1_21_1 = new MinecraftVersion("1.21.1");
|
||||
public static final MinecraftVersion V1_21_2 = new MinecraftVersion("1.21.2");
|
||||
public static final MinecraftVersion V1_21_3 = new MinecraftVersion("1.21.3");
|
||||
public static final MinecraftVersion V1_21_4 = new MinecraftVersion("1.21.4");
|
||||
public static final MinecraftVersion V1_21_5 = new MinecraftVersion("1.21.5");
|
||||
public static final MinecraftVersion V1_21_6 = new MinecraftVersion("1.21.6");
|
||||
public static final MinecraftVersion V1_21_7 = new MinecraftVersion("1.21.7");
|
||||
public static final MinecraftVersion V1_21_8 = new MinecraftVersion("1.21.8");
|
||||
public static final MinecraftVersion V1_21_9 = new MinecraftVersion("1.21.9");
|
||||
public static final MinecraftVersion V1_21_10 = new MinecraftVersion("1.21.10");
|
||||
public static final MinecraftVersion V1_21_11 = new MinecraftVersion("1.21.11");
|
||||
public static final MinecraftVersion V26_1 = new MinecraftVersion("26.1");
|
||||
public static final MinecraftVersion FUTURE = new MinecraftVersion("99.99");
|
||||
|
||||
private final int version;
|
||||
private final String versionString;
|
||||
private final PackVersion packFormat;
|
||||
|
||||
public static MinecraftVersion parse(final String version) {
|
||||
return new MinecraftVersion(version);
|
||||
public static MinecraftVersion byName(final String version) {
|
||||
MinecraftVersion mcV = BY_NAME.get(version);
|
||||
if (mcV == null) {
|
||||
throw new IllegalArgumentException("Unsupported version: " + version);
|
||||
}
|
||||
return mcV;
|
||||
}
|
||||
|
||||
public static List<MinecraftVersion> byMajorPackFormat(final int packFormat) {
|
||||
List<MinecraftVersion> minecraftVersions = (List<MinecraftVersion>) BY_PACK_FORMAT.get(packFormat);
|
||||
if (minecraftVersions.isEmpty()) {
|
||||
throw new IllegalArgumentException("Unsupported pack format: " + packFormat);
|
||||
}
|
||||
return minecraftVersions;
|
||||
}
|
||||
|
||||
public String version() {
|
||||
@@ -46,10 +105,12 @@ public final class MinecraftVersion implements Comparable<MinecraftVersion> {
|
||||
return packFormat;
|
||||
}
|
||||
|
||||
public MinecraftVersion(String version) {
|
||||
private MinecraftVersion(String version) {
|
||||
this.version = VersionHelper.parseVersionToInteger(version);
|
||||
this.versionString = version;
|
||||
this.packFormat = PACK_FORMATS.get(this.version);
|
||||
this.packFormat = Objects.requireNonNull(PACK_FORMATS.get(this.version));
|
||||
BY_NAME.put(this.versionString, this);
|
||||
BY_PACK_FORMAT.put(this.packFormat.major(), this);
|
||||
}
|
||||
|
||||
public boolean isAtOrAbove(MinecraftVersion other) {
|
||||
@@ -60,7 +121,7 @@ public final class MinecraftVersion implements Comparable<MinecraftVersion> {
|
||||
return version <= other.version;
|
||||
}
|
||||
|
||||
public boolean isAt(MinecraftVersion other) {
|
||||
public boolean is(MinecraftVersion other) {
|
||||
return version == other.version;
|
||||
}
|
||||
|
||||
@@ -80,7 +141,7 @@ public final class MinecraftVersion implements Comparable<MinecraftVersion> {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return version;
|
||||
return this.version;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
package net.momirealms.craftengine.core.util;
|
||||
|
||||
public final class MinecraftVersions {
|
||||
private MinecraftVersions() {}
|
||||
|
||||
public static final MinecraftVersion V1_20 = new MinecraftVersion("1.20");
|
||||
public static final MinecraftVersion V1_20_1 = new MinecraftVersion("1.20.1");
|
||||
public static final MinecraftVersion V1_20_2 = new MinecraftVersion("1.20.2");
|
||||
public static final MinecraftVersion V1_20_3 = new MinecraftVersion("1.20.3");
|
||||
public static final MinecraftVersion V1_20_4 = new MinecraftVersion("1.20.4");
|
||||
public static final MinecraftVersion V1_20_5 = new MinecraftVersion("1.20.5");
|
||||
public static final MinecraftVersion V1_20_6 = new MinecraftVersion("1.20.6");
|
||||
public static final MinecraftVersion V1_21 = new MinecraftVersion("1.21");
|
||||
public static final MinecraftVersion V1_21_1 = new MinecraftVersion("1.21.1");
|
||||
public static final MinecraftVersion V1_21_2 = new MinecraftVersion("1.21.2");
|
||||
public static final MinecraftVersion V1_21_3 = new MinecraftVersion("1.21.3");
|
||||
public static final MinecraftVersion V1_21_4 = new MinecraftVersion("1.21.4");
|
||||
public static final MinecraftVersion V1_21_5 = new MinecraftVersion("1.21.5");
|
||||
public static final MinecraftVersion V1_21_6 = new MinecraftVersion("1.21.6");
|
||||
public static final MinecraftVersion V1_21_7 = new MinecraftVersion("1.21.7");
|
||||
public static final MinecraftVersion V1_21_8 = new MinecraftVersion("1.21.8");
|
||||
public static final MinecraftVersion V1_21_9 = new MinecraftVersion("1.21.9");
|
||||
public static final MinecraftVersion V1_21_10 = new MinecraftVersion("1.21.10");
|
||||
public static final MinecraftVersion V1_21_11 = new MinecraftVersion("1.21.11");
|
||||
public static final MinecraftVersion FUTURE = new MinecraftVersion("1.99.99");
|
||||
}
|
||||
@@ -38,6 +38,7 @@ public class VersionHelper {
|
||||
private static final boolean v1_21_9;
|
||||
private static final boolean v1_21_10;
|
||||
private static final boolean v1_21_11;
|
||||
private static final boolean v26_1;
|
||||
private static final Class<?> UNOBFUSCATED_CLAZZ = Objects.requireNonNull(ReflectionUtils.getClazz(
|
||||
"net.minecraft.obfuscate.DontObfuscate", // 因为无混淆版本没有这个类所以说多写几个防止找不到了
|
||||
"net.minecraft.data.Main",
|
||||
@@ -57,7 +58,7 @@ public class VersionHelper {
|
||||
.split("-", 2)[0] // 1.21.10-rc1 -> 1.21.10
|
||||
.split("_", 2)[0]; // 1.21.11_unobfuscated -> 1.21.11
|
||||
|
||||
MINECRAFT_VERSION = new MinecraftVersion(versionString);
|
||||
MINECRAFT_VERSION = MinecraftVersion.byName(versionString);
|
||||
|
||||
String[] split = versionString.split("\\.");
|
||||
int major = Integer.parseInt(split[1]);
|
||||
@@ -86,6 +87,7 @@ public class VersionHelper {
|
||||
v1_21_9 = version >= 12109;
|
||||
v1_21_10 = version >= 12110;
|
||||
v1_21_11 = version >= 12111;
|
||||
v26_1 = version >= 12601;
|
||||
|
||||
majorVersion = major;
|
||||
minorVersion = minor;
|
||||
@@ -102,8 +104,9 @@ public class VersionHelper {
|
||||
}
|
||||
|
||||
public static int parseVersionToInteger(String versionString) {
|
||||
int major = 0;
|
||||
int minor = 0;
|
||||
int v1 = 0;
|
||||
int v2 = 0;
|
||||
int v3 = 0;
|
||||
int currentNumber = 0;
|
||||
int part = 0;
|
||||
for (int i = 0; i < versionString.length(); i++) {
|
||||
@@ -111,8 +114,11 @@ public class VersionHelper {
|
||||
if (c >= '0' && c <= '9') {
|
||||
currentNumber = currentNumber * 10 + (c - '0');
|
||||
} else if (c == '.') {
|
||||
if (part == 0) {
|
||||
v1 = currentNumber;
|
||||
}
|
||||
if (part == 1) {
|
||||
major = currentNumber;
|
||||
v2 = currentNumber;
|
||||
}
|
||||
part++;
|
||||
currentNumber = 0;
|
||||
@@ -121,12 +127,23 @@ public class VersionHelper {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (part == 1) {
|
||||
major = currentNumber;
|
||||
} else if (part == 2) {
|
||||
minor = currentNumber;
|
||||
// 处理最后一个数字部分
|
||||
if (part == 0) { // 没有点号:如 "26"
|
||||
v1 = currentNumber;
|
||||
} else if (part == 1) { // 一个点号:如 "26.1"
|
||||
v2 = currentNumber;
|
||||
} else if (part == 2) { // 两个点号:如 "1.2.3"
|
||||
v3 = currentNumber;
|
||||
}
|
||||
|
||||
// 新版命名法
|
||||
if (v1 >= 26) {
|
||||
return 10000 + v1 * 100 + v2;
|
||||
}
|
||||
// 旧版命名法
|
||||
else {
|
||||
return 10000 + v2 * 100 + v3;
|
||||
}
|
||||
return 10000 + major * 100 + minor;
|
||||
}
|
||||
|
||||
public static int majorVersion() {
|
||||
@@ -269,4 +286,8 @@ public class VersionHelper {
|
||||
public static boolean isOrAbove1_21_11() {
|
||||
return v1_21_11;
|
||||
}
|
||||
|
||||
public static boolean isOrAbove26_1() {
|
||||
return v26_1;
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@ org.gradle.jvmargs=-Xmx4G
|
||||
# Project settings
|
||||
project_version=0.0.66.5
|
||||
config_version=63
|
||||
lang_version=45
|
||||
lang_version=46
|
||||
project_group=net.momirealms
|
||||
latest_supported_version=1.21.11
|
||||
|
||||
@@ -38,7 +38,7 @@ zstd_version=1.5.7-6
|
||||
commons_io_version=2.21.0
|
||||
commons_lang3_version=3.20.0
|
||||
sparrow_nbt_version=0.10.9
|
||||
sparrow_util_version=0.75
|
||||
sparrow_util_version=0.76
|
||||
fastutil_version=8.5.18
|
||||
netty_version=4.1.128.Final
|
||||
joml_version=1.10.8
|
||||
|
||||
Reference in New Issue
Block a user