9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-27 19:09:08 +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

@@ -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),