9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-25 01:49:30 +00:00

盔甲重构part4

This commit is contained in:
XiaoMoMi
2025-07-04 04:03:41 +08:00
parent 7aedabc638
commit d3db03b4b5
22 changed files with 250 additions and 195 deletions

View File

@@ -137,6 +137,7 @@ public class BukkitFurniture implements Furniture {
@NotNull
public Object spawnPacket(Player player) {
// TODO hasPermission might be slow, can we use a faster way in the future?
// TODO Make it based on conditions. So we can dynamically control which furniture should be sent to the player
if (!this.minimized || player.hasPermission(FurnitureManager.FURNITURE_ADMIN_NODE)) {
return this.cachedSpawnPacket;
} else {

View File

@@ -1,5 +1,9 @@
package net.momirealms.craftengine.bukkit.item;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import net.momirealms.craftengine.bukkit.item.behavior.AxeItemBehavior;
import net.momirealms.craftengine.bukkit.item.behavior.FlintAndSteelItemBehavior;
import net.momirealms.craftengine.bukkit.item.factory.BukkitItemFactory;
@@ -23,6 +27,7 @@ import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigExce
import net.momirealms.craftengine.core.registry.BuiltInRegistries;
import net.momirealms.craftengine.core.registry.Holder;
import net.momirealms.craftengine.core.registry.WritableRegistry;
import net.momirealms.craftengine.core.util.GsonHelper;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.ResourceKey;
import net.momirealms.craftengine.core.util.VersionHelper;
@@ -34,6 +39,9 @@ import org.bukkit.event.HandlerList;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
public class BukkitItemManager extends AbstractItemManager<ItemStack> {
@@ -143,7 +151,9 @@ public class BukkitItemManager extends AbstractItemManager<ItemStack> {
protected void registerArmorTrimPattern(Collection<Key> equipments) {
if (equipments.isEmpty()) return;
this.lastRegisteredPatterns = new HashSet<>(equipments);
this.lastRegisteredPatterns.add(Config.sacrificedAssetId());
// 可能还没加载
if (Config.sacrificedAssetId() != null)
this.lastRegisteredPatterns.add(Config.sacrificedAssetId());
Object registry = FastNMS.INSTANCE.method$RegistryAccess$lookupOrThrow(FastNMS.INSTANCE.registryAccess(), MRegistries.TRIM_PATTERN);
try {
CoreReflections.field$MappedRegistry$frozen.set(registry, false);
@@ -168,9 +178,50 @@ public class BukkitItemManager extends AbstractItemManager<ItemStack> {
}
private void persistLastRegisteredPatterns() {
Path persistTrimPatternPath = this.plugin.dataFolderPath()
.resolve("cache")
.resolve("trim_patterns.json");
try {
Files.createDirectories(persistTrimPatternPath.getParent());
JsonObject json = new JsonObject();
JsonArray jsonElements = new JsonArray();
for (Key key : this.lastRegisteredPatterns) {
jsonElements.add(new JsonPrimitive(key.toString()));
}
json.add("patterns", jsonElements);
if (jsonElements.isEmpty()) {
if (Files.exists(persistTrimPatternPath)) {
Files.delete(persistTrimPatternPath);
}
} else {
GsonHelper.writeJsonFile(json, persistTrimPatternPath);
}
} catch (IOException e) {
this.plugin.logger().warn("Failed to persist registered trim patterns.", e);
}
}
// 需要持久化存储上一次注册的新trim类型如果注册晚了加载世界可能导致一些物品损坏
private void loadLastRegisteredPatterns() {
Path persistTrimPatternPath = this.plugin.dataFolderPath()
.resolve("cache")
.resolve("trim_patterns.json");
if (Files.exists(persistTrimPatternPath) && Files.isRegularFile(persistTrimPatternPath)) {
try {
JsonObject cache = GsonHelper.readJsonFile(persistTrimPatternPath).getAsJsonObject();
JsonArray patterns = cache.getAsJsonArray("patterns");
Set<Key> trims = new HashSet<>();
for (JsonElement element : patterns) {
if (element instanceof JsonPrimitive primitive) {
trims.add(Key.of(primitive.getAsString()));
}
}
this.registerArmorTrimPattern(trims);
this.lastRegisteredPatterns = trims;
} catch (IOException e) {
this.plugin.logger().warn("Failed to load registered trim patterns.", e);
}
}
}
private void registerCustomTrimMaterial() {

View File

@@ -27,7 +27,7 @@ import java.util.Optional;
import java.util.function.BiConsumer;
@SuppressWarnings("DuplicatedCode")
public class LegacyNetworkItemHandler implements NetworkItemHandler<ItemStack> {
public final class LegacyNetworkItemHandler implements NetworkItemHandler<ItemStack> {
@Override
public Optional<Item<ItemStack>> c2s(Item<ItemStack> wrapped) {

View File

@@ -15,12 +15,14 @@ import net.momirealms.craftengine.bukkit.util.ComponentUtils;
import net.momirealms.craftengine.bukkit.util.ItemUtils;
import net.momirealms.craftengine.bukkit.util.LegacyInventoryUtils;
import net.momirealms.craftengine.core.item.*;
import net.momirealms.craftengine.core.item.equipment.TrimBasedEquipment;
import net.momirealms.craftengine.core.item.recipe.*;
import net.momirealms.craftengine.core.item.recipe.Recipe;
import net.momirealms.craftengine.core.item.recipe.input.CraftingInput;
import net.momirealms.craftengine.core.item.recipe.input.SingleItemInput;
import net.momirealms.craftengine.core.item.recipe.input.SmithingInput;
import net.momirealms.craftengine.core.item.setting.AnvilRepairItem;
import net.momirealms.craftengine.core.item.setting.ItemEquipment;
import net.momirealms.craftengine.core.plugin.config.Config;
import net.momirealms.craftengine.core.plugin.context.ContextHolder;
import net.momirealms.craftengine.core.registry.BuiltInRegistries;
@@ -933,6 +935,24 @@ public class RecipeEventListener implements Listener {
}
}
@EventHandler(ignoreCancelled = true)
public void onSmithingTrim(PrepareSmithingEvent event) {
SmithingInventory inventory = event.getInventory();
if (!(inventory.getRecipe() instanceof SmithingTrimRecipe)) return;
ItemStack equipment = inventory.getInputEquipment();
if (equipment == null) return;
Item<ItemStack> wrappedEquipment = this.itemManager.wrap(equipment);
Optional<CustomItem<ItemStack>> optionalCustomItem = wrappedEquipment.getCustomItem();
if (optionalCustomItem.isEmpty()) return;
CustomItem<ItemStack> customItem = optionalCustomItem.get();
ItemEquipment itemEquipmentSettings = customItem.settings().equipment();
if (itemEquipmentSettings == null) return;
// 不允许trim类型的盔甲再次被使用trim
if (itemEquipmentSettings.equipment() instanceof TrimBasedEquipment) {
event.setResult(null);
}
}
@EventHandler(ignoreCancelled = true)
public void onSmithingTransform(PrepareSmithingEvent event) {
if (!Config.enableRecipeSystem()) return;

View File

@@ -138,6 +138,7 @@ public class BukkitCraftEngine extends CraftEngine {
super.onPluginLoad();
super.blockManager.init();
super.networkManager = new BukkitNetworkManager(this);
super.itemManager = new BukkitItemManager(this);
this.successfullyLoaded = true;
super.compatibilityManager().onLoad();
}
@@ -182,7 +183,6 @@ public class BukkitCraftEngine extends CraftEngine {
PacketConsumers.initEntities(RegistryUtils.currentEntityTypeRegistrySize());
super.packManager = new BukkitPackManager(this);
super.senderFactory = new BukkitSenderFactory(this);
super.itemManager = new BukkitItemManager(this);
super.recipeManager = new BukkitRecipeManager(this);
super.commandManager = new BukkitCommandManager(this);
super.itemBrowserManager = new ItemBrowserManagerImpl(this);

View File

@@ -76,9 +76,7 @@ resource-pack:
# Send the resource pack on joining the server
send-on-join: true
kick-if-declined: true
prompt: |
<yellow>To fully experience our server,
please accept our custom resource pack.</yellow>
prompt: "<yellow>To fully experience our server,<newline>please accept our custom resource pack.</yellow>"
# If you are hosting the resource pack by yourself, replace `localhost` with your server ip otherwise it would only work on your local pc
# If using BungeeCord or Velocity, consider using a proxy-side plugin to handle resource pack delivery.
# Read this page for more host types: https://mo-mi.gitbook.io/xiaomomi-plugins/craftengine/plugin-wiki/craftengine/resource-pack/host
@@ -140,7 +138,7 @@ resource-pack:
item:
# Make custom-model-data and item-model clientside by default
client-bound-model: false
client-bound-model: true
equipment:
# The sacrificed-vanilla-armor argument determines which vanilla armor gets completely removed (loses all its trims)

View File

@@ -307,15 +307,21 @@ templates:
- default:topaz_tools
equipment:
asset-id: default:topaz
$$>=1.21.2:
slot: ${slot}
model:
template: default:model/armor_trim
equipments#topaz:
default:topaz:
type:
$$>=1.21.2: component
$$<1.21.2: trim
humanoid: minecraft:entity/equipment/humanoid/topaz
humanoid-leggings: minecraft:entity/equipment/humanoid_leggings/topaz
$$>=1.21.2:
default:topaz:
type: component
humanoid: minecraft:topaz
humanoid-leggings: minecraft:topaz
$$<1.21.2:
default:topaz:
type: trim
humanoid: minecraft:entity/equipment/humanoid/topaz
humanoid-leggings: minecraft:entity/equipment/humanoid_leggings/topaz
recipes#topaz:
default:topaz_shovel:
type: shaped
@@ -377,49 +383,48 @@ recipes#topaz:
result:
id: default:topaz_pickaxe
count: 1
$$>=1.21.2#armor:
default:topaz_helmet:
type: shaped
pattern:
- AAA
- A A
ingredients:
A: default:topaz
result:
id: default:topaz_helmet
count: 1
default:topaz_chestplate:
type: shaped
pattern:
- A A
- AAA
- AAA
ingredients:
A: default:topaz
result:
id: default:topaz_chestplate
count: 1
default:topaz_leggings:
type: shaped
pattern:
- AAA
- A A
- A A
ingredients:
A: default:topaz
result:
id: default:topaz_leggings
count: 1
default:topaz_boots:
type: shaped
pattern:
- A A
- A A
ingredients:
A: default:topaz
result:
id: default:topaz_boots
count: 1
default:topaz_helmet:
type: shaped
pattern:
- AAA
- A A
ingredients:
A: default:topaz
result:
id: default:topaz_helmet
count: 1
default:topaz_chestplate:
type: shaped
pattern:
- A A
- AAA
- AAA
ingredients:
A: default:topaz
result:
id: default:topaz_chestplate
count: 1
default:topaz_leggings:
type: shaped
pattern:
- AAA
- A A
- A A
ingredients:
A: default:topaz
result:
id: default:topaz_leggings
count: 1
default:topaz_boots:
type: shaped
pattern:
- A A
- A A
ingredients:
A: default:topaz
result:
id: default:topaz_boots
count: 1
default:topaz_bow:
type: smithing_transform
base: minecraft:bow

View File

@@ -1,6 +1,6 @@
author: XiaoMoMi
version: 0.0.1
description:
description: Fix broken vanilla armor
namespace: minecraft
enable:
$$>=1.21.2: false

View File

@@ -390,6 +390,7 @@ warning.config.resource_pack.generation.missing_item_model: "<yellow>Item '<arg:
warning.config.resource_pack.generation.missing_block_model: "<yellow>Block state '<arg:0>' is missing model file: '<arg:1>'</yellow>"
warning.config.resource_pack.generation.missing_parent_model: "<yellow>Model '<arg:0>' cannot find parent model: '<arg:1>'</yellow>"
warning.config.resource_pack.generation.malformatted_json: "<yellow>Json file '<arg:0>' is malformatted.</yellow>"
warning.config.resource_pack.generation.missing_equipment_texture: "<yellow>Equipment '<arg:0>' is missing texture '<arg:1>'</yellow>"
warning.config.resource_pack.invalid_overlay_format: "<yellow>Issue found in config.yml at 'resource-pack.overlay-format' - Invalid overlay format '<arg:0>'. Overlay format must contain the placeholder '{version}'.</yellow>"
warning.config.equipment.duplicate: "<yellow>Issue found in file <arg:0> - Duplicated equipment '<arg:1>'. Please check if there is the same configuration in other files.</yellow>"
warning.config.equipment.missing_type: "<yellow>Issue found in file <arg:0> - The equipment '<arg:1>' is missing the required 'type' argument.</yellow>"

View File

@@ -304,7 +304,7 @@ warning.config.loot_table.entry.item.missing_item: "<yellow>在文件 <arg:0>
warning.config.loot_table.condition.missing_type: "<yellow>在文件 <arg:0> 发现问题 - '<arg:1>' 的战利品表配置错误 某个条件缺少必需的 'type' 参数</yellow>"
warning.config.loot_table.condition.invalid_type: "<yellow>在文件 <arg:0> 发现问题 - '<arg:1>' 的战利品表配置错误 某个条件使用了无效的条件类型 '<arg:2>'</yellow>"
warning.config.host.missing_type: "<yellow>在 config.yml 的 'resource-pack.delivery.hosting' 处发现问题 - 缺少必需的 'type' 参数</yellow>"
warning.config.host.invalid_type: "<yellow>在 config.yml 的 'resource-pack.delivery.hosting' 处发现问题 - 无效的托管类型 '' 请参考 https://mo-mi.gitbook.io/xiaomomi-plugins/craftengine/plugin-wiki/craftengine/resource-pack/host</yellow>"
warning.config.host.invalid_type: "<yellow>在 config.yml 的 'resource-pack.delivery.hosting' 处发现问题 - 无效的托管类型 '<arg:0>' 请参考 https://mo-mi.gitbook.io/xiaomomi-plugins/craftengine/plugin-wiki/craftengine/resource-pack/host</yellow>"
warning.config.host.external.missing_url: "<yellow>在 config.yml 的 'resource-pack.delivery.hosting' 处发现问题 - 外部托管缺少必需的 'url' 参数</yellow>"
warning.config.host.alist.missing_api_url: "<yellow>在 config.yml 的 'resource-pack.delivery.hosting' 处发现问题 - Alist 托管缺少必需的 'api-url' 参数</yellow>"
warning.config.host.alist.missing_username: "<yellow>在 config.yml 的 'resource-pack.delivery.hosting' 处发现问题 - Alist 托管缺少必需的 'username' 参数或环境变量 'CE_ALIST_USERNAME'</yellow>"
@@ -390,8 +390,9 @@ warning.config.resource_pack.generation.missing_item_model: "<yellow>物品'<arg
warning.config.resource_pack.generation.missing_block_model: "<yellow>方块状态'<arg:0>'缺少模型文件: '<arg:1>'</yellow>"
warning.config.resource_pack.generation.missing_parent_model: "<yellow>模型'<arg:0>'找不到父级模型文件: '<arg:1>'</yellow>"
warning.config.resource_pack.generation.malformatted_json: "<yellow>Json文件 '<arg:0>' 格式错误.</yellow>"
warning.config.resource_pack.generation.missing_equipment_texture: "<yellow>装备 '<arg:0>' 缺少纹理 '<arg:1>'</yellow>"
warning.config.resource_pack.invalid_overlay_format: "<yellow>在 config.yml 的 'resource-pack.overlay-format' 处发现问题 - 无效的overlay格式 '<arg:0>'. Overlay格式必须包含占位符 '{version}'.</yellow>"
warning.config.equipment.duplicate: "<yellow>Issue found in file <arg:0> - Duplicated equipment '<arg:1>'. Please check if there is the same configuration in other files.</yellow>"
warning.config.equipment.missing_type: "<yellow>Issue found in file <arg:0> - The equipment '<arg:1>' is missing the required 'type' argument.</yellow>"
warning.config.equipment.invalid_type: "<yellow>Issue found in file <arg:0> - The equipment '<arg:1>' is using an invalid 'type' argument.</yellow>"
warning.config.equipment.invalid_sacrificed_armor: "<yellow>Issue found in config.yml at 'equipment.sacrificed-vanilla-armor' - Invalid vanilla armor type '<arg:0>'.</yellow>"
warning.config.equipment.duplicate: "<yellow>在文件 <arg:0> 发现问题 - 重复的装备配置 '<arg:1>'。请检查其他文件中是否存在相同配置</yellow>"
warning.config.equipment.missing_type: "<yellow>在文件 <arg:0> 发现问题 - 装备 '<arg:1>' 缺少必需的 'type' 参数</yellow>"
warning.config.equipment.invalid_type: "<yellow>在文件 <arg:0> 发现问题 - 装备 '<arg:1>' 使用了无效的 'type' 参数</yellow>"
warning.config.equipment.invalid_sacrificed_armor: "<yellow> config.yml 'equipment.sacrificed-vanilla-armor' 处发现问题 - 无效的原版盔甲类型 '<arg:0>'</yellow>"

View File

@@ -1,6 +1,5 @@
package net.momirealms.craftengine.core.item;
import com.google.common.collect.ImmutableMap;
import net.momirealms.craftengine.core.item.behavior.ItemBehavior;
import net.momirealms.craftengine.core.item.modifier.ItemDataModifier;
import net.momirealms.craftengine.core.plugin.context.PlayerOptionalContext;
@@ -20,9 +19,7 @@ public abstract class AbstractCustomItem<I> implements CustomItem<I> {
protected final Key material;
protected final Key clientBoundMaterial;
protected final ItemDataModifier<I>[] modifiers;
protected final Map<String, ItemDataModifier<I>> modifierMap;
protected final ItemDataModifier<I>[] clientBoundModifiers;
protected final Map<String, ItemDataModifier<I>> clientBoundModifierMap;
protected final List<ItemBehavior> behaviors;
protected final ItemSettings settings;
protected final Map<EventTrigger, List<Function<PlayerOptionalContext>>> events;
@@ -44,13 +41,6 @@ public abstract class AbstractCustomItem<I> implements CustomItem<I> {
this.clientBoundModifiers = clientBoundModifiers.toArray(new ItemDataModifier[0]);
this.behaviors = List.copyOf(behaviors);
this.settings = settings;
ImmutableMap.Builder<String, ItemDataModifier<I>> modifierMapBuilder = ImmutableMap.builder();
for (ItemDataModifier<I> modifier : modifiers) {
modifierMapBuilder.put(modifier.name(), modifier);
}
this.modifierMap = modifierMapBuilder.build();
ImmutableMap.Builder<String, ItemDataModifier<I>> clientSideModifierMapBuilder = ImmutableMap.builder();
this.clientBoundModifierMap = clientSideModifierMapBuilder.build();
}
@Override
@@ -85,11 +75,6 @@ public abstract class AbstractCustomItem<I> implements CustomItem<I> {
return this.modifiers;
}
@Override
public Map<String, ItemDataModifier<I>> dataModifierMap() {
return this.modifierMap;
}
@Override
public boolean hasClientBoundDataModifier() {
return this.clientBoundModifiers.length != 0;
@@ -100,11 +85,6 @@ public abstract class AbstractCustomItem<I> implements CustomItem<I> {
return this.clientBoundModifiers;
}
@Override
public Map<String, ItemDataModifier<I>> clientBoundDataModifierMap() {
return this.clientBoundModifierMap;
}
@Override
public ItemSettings settings() {
return this.settings;

View File

@@ -4,9 +4,7 @@ import net.momirealms.craftengine.core.item.behavior.ItemBehavior;
import net.momirealms.craftengine.core.item.behavior.ItemBehaviors;
import net.momirealms.craftengine.core.item.data.Enchantment;
import net.momirealms.craftengine.core.item.data.JukeboxPlayable;
import net.momirealms.craftengine.core.item.equipment.Equipment;
import net.momirealms.craftengine.core.item.equipment.Equipments;
import net.momirealms.craftengine.core.item.equipment.TrimBasedEquipment;
import net.momirealms.craftengine.core.item.equipment.*;
import net.momirealms.craftengine.core.item.modifier.*;
import net.momirealms.craftengine.core.item.setting.EquipmentData;
import net.momirealms.craftengine.core.pack.LoadingSequence;
@@ -289,6 +287,17 @@ public abstract class AbstractItemManager<I> extends AbstractModelGenerator impl
}
}
public void addOrMergeEquipment(ComponentBasedEquipment equipment) {
Equipment previous = this.equipments.get(equipment.assetId());
if (previous instanceof ComponentBasedEquipment another) {
for (Map.Entry<EquipmentLayerType, List<ComponentBasedEquipment.Layer>> entry : equipment.layers().entrySet()) {
another.addLayer(entry.getKey(), entry.getValue());
}
} else {
this.equipments.put(equipment.assetId(), equipment);
}
}
public class ItemParser implements ConfigParser {
public static final String[] CONFIG_SECTION_NAME = new String[] {"items", "item"};

View File

@@ -25,14 +25,10 @@ public interface CustomItem<I> extends BuildableItem<I> {
ItemDataModifier<I>[] dataModifiers();
Map<String, ItemDataModifier<I>> dataModifierMap();
boolean hasClientBoundDataModifier();
ItemDataModifier<I>[] clientBoundDataModifiers();
Map<String, ItemDataModifier<I>> clientBoundDataModifierMap();
ItemSettings settings();
default boolean is(Key tag) {

View File

@@ -320,6 +320,7 @@ public class ItemSettings {
Map<String, Object> args = MiscUtils.castToMap(value, false);
EquipmentData data = EquipmentData.fromMap(args);
ComponentBasedEquipment componentBasedEquipment = ComponentBasedEquipment.FACTORY.create(data.assetId(), args);
((AbstractItemManager<?>) CraftEngine.instance().itemManager()).addOrMergeEquipment(componentBasedEquipment);
ItemEquipment itemEquipment = new ItemEquipment(Tristate.FALSE, data, componentBasedEquipment);
return settings -> settings.equipment(itemEquipment);
}));

View File

@@ -11,7 +11,10 @@ import net.momirealms.craftengine.core.util.VersionHelper;
import net.momirealms.sparrow.nbt.CompoundTag;
import net.momirealms.sparrow.nbt.Tag;
import java.util.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

View File

@@ -1188,74 +1188,7 @@ public abstract class AbstractPackManager implements PackManager {
for (Equipment equipment : this.plugin.itemManager().equipments().values()) {
if (equipment instanceof ComponentBasedEquipment componentBasedEquipment) {
// 现代的盔甲生成
Key assetId = componentBasedEquipment.assetId();
if (Config.packMaxVersion().isAtOrAbove(MinecraftVersions.V1_21_4)) {
Path equipmentPath = generatedPackPath
.resolve("assets")
.resolve(assetId.namespace())
.resolve("equipment")
.resolve(assetId.value() + ".json");
JsonObject equipmentJson = null;
if (Files.exists(equipmentPath)) {
try (BufferedReader reader = Files.newBufferedReader(equipmentPath)) {
equipmentJson = JsonParser.parseReader(reader).getAsJsonObject();
} catch (IOException e) {
plugin.logger().warn("Failed to load existing sounds.json", e);
return;
}
}
if (equipmentJson != null) {
equipmentJson = GsonHelper.deepMerge(equipmentJson, componentBasedEquipment.get());
} else {
equipmentJson = componentBasedEquipment.get();
}
try {
Files.createDirectories(equipmentPath.getParent());
} catch (IOException e) {
plugin.logger().severe("Error creating " + equipmentPath.toAbsolutePath());
return;
}
try {
GsonHelper.writeJsonFile(equipmentJson, equipmentPath);
} catch (IOException e) {
this.plugin.logger().severe("Error writing equipment file", e);
}
}
if (Config.packMaxVersion().isAtOrAbove(MinecraftVersions.V1_21_2) && Config.packMinVersion().isBelow(MinecraftVersions.V1_21_4)) {
Path equipmentPath = generatedPackPath
.resolve("assets")
.resolve(assetId.namespace())
.resolve("models")
.resolve("equipment")
.resolve(assetId.value() + ".json");
JsonObject equipmentJson = null;
if (Files.exists(equipmentPath)) {
try (BufferedReader reader = Files.newBufferedReader(equipmentPath)) {
equipmentJson = JsonParser.parseReader(reader).getAsJsonObject();
} catch (IOException e) {
plugin.logger().warn("Failed to load existing sounds.json", e);
return;
}
}
if (equipmentJson != null) {
equipmentJson = GsonHelper.deepMerge(equipmentJson, componentBasedEquipment.get());
} else {
equipmentJson = componentBasedEquipment.get();
}
try {
Files.createDirectories(equipmentPath.getParent());
} catch (IOException e) {
plugin.logger().severe("Error creating " + equipmentPath.toAbsolutePath());
return;
}
try {
GsonHelper.writeJsonFile(equipmentJson, equipmentPath);
} catch (IOException e) {
this.plugin.logger().severe("Error writing equipment file", e);
}
}
processComponentBasedEquipment(componentBasedEquipment, generatedPackPath);
} else if (equipment instanceof TrimBasedEquipment trimBasedEquipment) {
Key assetId = trimBasedEquipment.assetId();
Pair<Boolean, Boolean> result = processTrimBasedEquipment(trimBasedEquipment, generatedPackPath);
@@ -1423,6 +1356,77 @@ public abstract class AbstractPackManager implements PackManager {
}
}
private void processComponentBasedEquipment(ComponentBasedEquipment componentBasedEquipment, Path generatedPackPath) {
Key assetId = componentBasedEquipment.assetId();
if (Config.packMaxVersion().isAtOrAbove(MinecraftVersions.V1_21_4)) {
Path equipmentPath = generatedPackPath
.resolve("assets")
.resolve(assetId.namespace())
.resolve("equipment")
.resolve(assetId.value() + ".json");
JsonObject equipmentJson = null;
if (Files.exists(equipmentPath)) {
try (BufferedReader reader = Files.newBufferedReader(equipmentPath)) {
equipmentJson = JsonParser.parseReader(reader).getAsJsonObject();
} catch (IOException e) {
plugin.logger().warn("Failed to load existing sounds.json", e);
return;
}
}
if (equipmentJson != null) {
equipmentJson = GsonHelper.deepMerge(equipmentJson, componentBasedEquipment.get());
} else {
equipmentJson = componentBasedEquipment.get();
}
try {
Files.createDirectories(equipmentPath.getParent());
} catch (IOException e) {
plugin.logger().severe("Error creating " + equipmentPath.toAbsolutePath());
return;
}
try {
GsonHelper.writeJsonFile(equipmentJson, equipmentPath);
} catch (IOException e) {
this.plugin.logger().severe("Error writing equipment file", e);
}
}
if (Config.packMaxVersion().isAtOrAbove(MinecraftVersions.V1_21_2) && Config.packMinVersion().isBelow(MinecraftVersions.V1_21_4)) {
Path equipmentPath = generatedPackPath
.resolve("assets")
.resolve(assetId.namespace())
.resolve("models")
.resolve("equipment")
.resolve(assetId.value() + ".json");
JsonObject equipmentJson = null;
if (Files.exists(equipmentPath)) {
try (BufferedReader reader = Files.newBufferedReader(equipmentPath)) {
equipmentJson = JsonParser.parseReader(reader).getAsJsonObject();
} catch (IOException e) {
plugin.logger().warn("Failed to load existing sounds.json", e);
return;
}
}
if (equipmentJson != null) {
equipmentJson = GsonHelper.deepMerge(equipmentJson, componentBasedEquipment.get());
} else {
equipmentJson = componentBasedEquipment.get();
}
try {
Files.createDirectories(equipmentPath.getParent());
} catch (IOException e) {
plugin.logger().severe("Error creating " + equipmentPath.toAbsolutePath());
return;
}
try {
GsonHelper.writeJsonFile(equipmentJson, equipmentPath);
} catch (IOException e) {
this.plugin.logger().severe("Error writing equipment file", e);
}
}
}
@Nullable
private Pair<Boolean, Boolean> processTrimBasedEquipment(TrimBasedEquipment trimBasedEquipment, Path generatedPackPath) {
Key assetId = trimBasedEquipment.assetId();
@@ -1439,7 +1443,7 @@ public abstract class AbstractPackManager implements PackManager {
.resolve("textures")
.resolve(humanoidResourceLocation.value() + ".png");
if (!Files.exists(texture) || !Files.isRegularFile(texture)) {
// todo 说话
TranslationManager.instance().log("warning.config.resource_pack.generation.missing_equipment_texture", assetId.asString(), texture.toString());
return null;
}
boolean shouldPreserve = false;
@@ -1498,7 +1502,7 @@ public abstract class AbstractPackManager implements PackManager {
.resolve("textures")
.resolve(humanoidLeggingsResourceLocation.value() + ".png");
if (!Files.exists(texture) && !Files.isRegularFile(texture)) {
// todo 说话
TranslationManager.instance().log("warning.config.resource_pack.generation.missing_equipment_texture", assetId.asString(), texture.toString());
return null;
}
boolean shouldPreserve = false;

View File

@@ -77,17 +77,14 @@ public class AlistHost implements ResourcePackHost {
}
private void readCacheFromDisk() {
Path cachePath = CraftEngine.instance().dataFolderPath().resolve("alist.cache");
if (!Files.exists(cachePath)) return;
Path cachePath = CraftEngine.instance().dataFolderPath().resolve("cache").resolve("alist.json");
if (!Files.exists(cachePath) || !Files.isRegularFile(cachePath)) return;
try (InputStream is = Files.newInputStream(cachePath)) {
Map<String, String> cache = GsonHelper.get().fromJson(
new InputStreamReader(is),
new TypeToken<Map<String, String>>(){}.getType()
);
this.cachedSha1 = cache.get("sha1");
CraftEngine.instance().logger().info("[Alist] Loaded cached resource pack metadata");
} catch (Exception e) {
CraftEngine.instance().logger().warn("[Alist] Failed to load cache " + cachePath, e);
@@ -97,9 +94,9 @@ public class AlistHost implements ResourcePackHost {
private void saveCacheToDisk() {
Map<String, String> cache = new HashMap<>();
cache.put("sha1", this.cachedSha1 != null ? this.cachedSha1 : "");
Path cachePath = CraftEngine.instance().dataFolderPath().resolve("alist.cache");
Path cachePath = CraftEngine.instance().dataFolderPath().resolve("cache").resolve("alist.json");
try {
Files.createDirectories(cachePath.getParent());
Files.writeString(
cachePath,
GsonHelper.get().toJson(cache),

View File

@@ -49,18 +49,15 @@ public class DropboxHost implements ResourcePackHost {
}
public void readCacheFromDisk() {
Path cachePath = CraftEngine.instance().dataFolderPath().resolve("dropbox.cache");
Path cachePath = CraftEngine.instance().dataFolderPath().resolve("cache").resolve("dropbox.json");
if (!Files.exists(cachePath)) return;
try (InputStream is = Files.newInputStream(cachePath)) {
JsonObject cache = GsonHelper.parseJsonToJsonObject(new String(is.readAllBytes(), StandardCharsets.UTF_8));
this.url = getString(cache, "url");
this.sha1 = getString(cache, "sha1");
this.refreshToken = getString(cache, "refresh_token");
this.accessToken = getString(cache, "access_token");
this.expiresAt = getLong(cache, "expires_at");
CraftEngine.instance().logger().info("[Dropbox] Loaded cached resource pack info");
} catch (Exception e) {
CraftEngine.instance().logger().warn("[Dropbox] Failed to load cache " + cachePath, e);
@@ -74,9 +71,9 @@ public class DropboxHost implements ResourcePackHost {
cache.addProperty("refresh_token", this.refreshToken);
cache.addProperty("access_token", this.accessToken);
cache.addProperty("expires_at", this.expiresAt);
Path cachePath = CraftEngine.instance().dataFolderPath().resolve("dropbox.cache");
Path cachePath = CraftEngine.instance().dataFolderPath().resolve("cache").resolve("dropbox.json");
try {
Files.createDirectories(cachePath);
Files.writeString(
cachePath,
GsonHelper.get().toJson(cache),

View File

@@ -45,23 +45,19 @@ public class GitLabHost implements ResourcePackHost {
}
public void readCacheFromDisk() {
Path cachePath = CraftEngine.instance().dataFolderPath().resolve("gitlab.cache");
if (!Files.exists(cachePath)) return;
Path cachePath = CraftEngine.instance().dataFolderPath().resolve("cache").resolve("gitlab.json");
if (!Files.exists(cachePath) || !Files.isRegularFile(cachePath)) return;
try (InputStream is = Files.newInputStream(cachePath)) {
Map<String, String> cache = GsonHelper.get().fromJson(
new InputStreamReader(is),
new TypeToken<Map<String, String>>(){}.getType()
);
this.url = cache.get("url");
this.sha1 = cache.get("sha1");
String uuidString = cache.get("uuid");
if (uuidString != null && !uuidString.isEmpty()) {
this.uuid = UUID.fromString(uuidString);
}
CraftEngine.instance().logger().info("[GitLab] Loaded cached resource pack info");
} catch (Exception e) {
CraftEngine.instance().logger().warn(
@@ -74,9 +70,9 @@ public class GitLabHost implements ResourcePackHost {
cache.put("url", this.url);
cache.put("sha1", this.sha1);
cache.put("uuid", this.uuid != null ? this.uuid.toString() : "");
Path cachePath = CraftEngine.instance().dataFolderPath().resolve("gitlab.cache");
Path cachePath = CraftEngine.instance().dataFolderPath().resolve("cache").resolve("gitlab.json");
try {
Files.createDirectories(cachePath.getParent());
Files.writeString(
cachePath,
GsonHelper.get().toJson(cache),

View File

@@ -56,23 +56,19 @@ public class LobFileHost implements ResourcePackHost {
}
public void readCacheFromDisk() {
Path cachePath = CraftEngine.instance().dataFolderPath().resolve("lobfile.cache");
if (!Files.exists(cachePath)) return;
Path cachePath = CraftEngine.instance().dataFolderPath().resolve("cache").resolve("lobfile.json");
if (!Files.exists(cachePath) || !Files.isRegularFile(cachePath)) return;
try (InputStream is = Files.newInputStream(cachePath)) {
Map<String, String> cache = GsonHelper.get().fromJson(
new InputStreamReader(is),
new TypeToken<Map<String, String>>(){}.getType()
);
this.url = cache.get("url");
this.sha1 = cache.get("sha1");
String uuidString = cache.get("uuid");
if (uuidString != null && !uuidString.isEmpty()) {
this.uuid = UUID.fromString(uuidString);
}
CraftEngine.instance().logger().info("[LobFile] Loaded cached resource pack info");
} catch (Exception e) {
CraftEngine.instance().logger().warn(
@@ -85,9 +81,9 @@ public class LobFileHost implements ResourcePackHost {
cache.put("url", this.url);
cache.put("sha1", this.sha1);
cache.put("uuid", this.uuid != null ? this.uuid.toString() : "");
Path cachePath = CraftEngine.instance().dataFolderPath().resolve("lobfile.cache");
Path cachePath = CraftEngine.instance().dataFolderPath().resolve("cache").resolve("lobfile.json");
try {
Files.createDirectories(cachePath.getParent());
Files.writeString(
cachePath,
GsonHelper.get().toJson(cache),

View File

@@ -61,9 +61,8 @@ public class OneDriveHost implements ResourcePackHost {
}
public void readCacheFromDisk() {
Path cachePath = CraftEngine.instance().dataFolderPath().resolve("onedrive.cache");
if (!Files.exists(cachePath)) return;
Path cachePath = CraftEngine.instance().dataFolderPath().resolve("cache").resolve("onedrive.json");
if (!Files.exists(cachePath) || !Files.isRegularFile(cachePath)) return;
try (InputStream is = Files.newInputStream(cachePath)) {
Map<String, String> cache = GsonHelper.get().fromJson(
new InputStreamReader(is),
@@ -91,9 +90,9 @@ public class OneDriveHost implements ResourcePackHost {
cache.put("refresh-token-expires-in", String.valueOf(this.refreshToken.right().getTime()));
cache.put("sha1", this.sha1);
cache.put("file-id", this.fileId);
Path cachePath = CraftEngine.instance().dataFolderPath().resolve("onedrive.cache");
Path cachePath = CraftEngine.instance().dataFolderPath().resolve("cache").resolve("onedrive.json");
try {
Files.createDirectories(cachePath.getParent());
Files.writeString(
cachePath,
GsonHelper.get().toJson(cache),

View File

@@ -2,7 +2,7 @@ org.gradle.jvmargs=-Xmx1G
# Project settings
# Rule: [major update].[feature update].[bug fix]
project_version=0.0.59.2
project_version=0.0.59.3
config_version=41
lang_version=21
project_group=net.momirealms