mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-23 08:59:27 +00:00
新增动态lore
This commit is contained in:
@@ -4,11 +4,14 @@ import com.google.gson.JsonElement;
|
|||||||
import net.momirealms.craftengine.bukkit.item.ComponentItemWrapper;
|
import net.momirealms.craftengine.bukkit.item.ComponentItemWrapper;
|
||||||
import net.momirealms.craftengine.bukkit.item.ComponentTypes;
|
import net.momirealms.craftengine.bukkit.item.ComponentTypes;
|
||||||
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||||
|
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
|
||||||
|
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MRegistryOps;
|
||||||
import net.momirealms.craftengine.bukkit.util.EnchantmentUtils;
|
import net.momirealms.craftengine.bukkit.util.EnchantmentUtils;
|
||||||
import net.momirealms.craftengine.core.item.Enchantment;
|
import net.momirealms.craftengine.core.item.Enchantment;
|
||||||
import net.momirealms.craftengine.core.item.Trim;
|
import net.momirealms.craftengine.core.item.Trim;
|
||||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||||
import net.momirealms.craftengine.core.util.Key;
|
import net.momirealms.craftengine.core.util.Key;
|
||||||
|
import net.momirealms.sparrow.nbt.CompoundTag;
|
||||||
import net.momirealms.sparrow.nbt.Tag;
|
import net.momirealms.sparrow.nbt.Tag;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
@@ -38,29 +41,136 @@ public class ComponentItemFactory1_20_5 extends BukkitItemFactory<ComponentItemW
|
|||||||
return new ComponentItemWrapper(item);
|
return new ComponentItemWrapper(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
protected Object getJavaTag(ComponentItemWrapper item, Object... path) {
|
protected Object getJavaTag(ComponentItemWrapper item, Object... path) {
|
||||||
throw new UnsupportedOperationException("This feature is not available on 1.20.5+");
|
Map<String, Object> rootMap = (Map<String, Object>) item.getJavaComponent(ComponentTypes.CUSTOM_DATA).orElse(null);
|
||||||
|
if (rootMap == null) return null;
|
||||||
|
Object currentObj = rootMap;
|
||||||
|
for (int i = 0; i < path.length; i++) {
|
||||||
|
Object pathSegment = path[i];
|
||||||
|
if (pathSegment == null) return null;
|
||||||
|
String key = pathSegment.toString();
|
||||||
|
currentObj = ((Map<String, Object>) currentObj).get(key);
|
||||||
|
if (currentObj == null) return null;
|
||||||
|
if (i == path.length - 1) {
|
||||||
|
return currentObj;
|
||||||
|
}
|
||||||
|
if (!(currentObj instanceof Map)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return currentObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Tag getNBTTag(ComponentItemWrapper item, Object... path) {
|
protected Tag getNBTTag(ComponentItemWrapper item, Object... path) {
|
||||||
throw new UnsupportedOperationException("This feature is not available on 1.20.5+");
|
CompoundTag rootTag = (CompoundTag) item.getSparrowNBTComponent(ComponentTypes.CUSTOM_DATA).orElse(null);
|
||||||
|
if (rootTag == null) return null;
|
||||||
|
Tag currentTag = rootTag;
|
||||||
|
for (int i = 0; i < path.length; i++) {
|
||||||
|
Object pathSegment = path[i];
|
||||||
|
if (pathSegment == null) return null;
|
||||||
|
CompoundTag t = (CompoundTag) currentTag;
|
||||||
|
String key = pathSegment.toString();
|
||||||
|
currentTag = t.get(key);
|
||||||
|
if (currentTag == null) return null;
|
||||||
|
if (i == path.length - 1) {
|
||||||
|
return currentTag;
|
||||||
|
}
|
||||||
|
if (!(currentTag instanceof CompoundTag)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return currentTag;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void setTag(ComponentItemWrapper item, Object value, Object... path) {
|
protected void setTag(ComponentItemWrapper item, Object value, Object... path) {
|
||||||
throw new UnsupportedOperationException("This feature is not available on 1.20.5+");
|
Tag valueTag;
|
||||||
|
if (value instanceof Tag tag) {
|
||||||
|
valueTag = tag;
|
||||||
|
} else if (value instanceof JsonElement je) {
|
||||||
|
valueTag = MRegistryOps.JSON.convertTo(MRegistryOps.SPARROW_NBT, je);
|
||||||
|
} else if (CoreReflections.clazz$Tag.isInstance(value)) {
|
||||||
|
valueTag = MRegistryOps.NBT.convertTo(MRegistryOps.SPARROW_NBT, value);
|
||||||
|
} else {
|
||||||
|
assert MRegistryOps.JAVA != null;
|
||||||
|
valueTag = MRegistryOps.JAVA.convertTo(MRegistryOps.SPARROW_NBT, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
CompoundTag rootTag = (CompoundTag) item.getSparrowNBTComponent(ComponentTypes.CUSTOM_DATA).orElse(new CompoundTag());
|
||||||
|
|
||||||
|
if (path == null || path.length == 0) {
|
||||||
|
if (valueTag instanceof CompoundTag) {
|
||||||
|
rootTag = (CompoundTag) valueTag;
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Cannot set non-CompoundTag as root without path");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
CompoundTag currentTag = rootTag;
|
||||||
|
for (int i = 0; i < path.length - 1; i++) {
|
||||||
|
Object pathSegment = path[i];
|
||||||
|
if (pathSegment == null) throw new NullPointerException("Path segment cannot be null");
|
||||||
|
|
||||||
|
String key = pathSegment.toString();
|
||||||
|
Tag nextTag = currentTag.get(key);
|
||||||
|
|
||||||
|
if (!(nextTag instanceof CompoundTag)) {
|
||||||
|
nextTag = new CompoundTag();
|
||||||
|
currentTag.put(key, nextTag);
|
||||||
|
}
|
||||||
|
currentTag = (CompoundTag) nextTag;
|
||||||
|
}
|
||||||
|
|
||||||
|
String finalKey = path[path.length - 1].toString();
|
||||||
|
currentTag.put(finalKey, valueTag);
|
||||||
|
}
|
||||||
|
|
||||||
|
item.setSparrowNBTComponent(ComponentTypes.CUSTOM_DATA, rootTag);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean hasTag(ComponentItemWrapper item, Object... path) {
|
protected boolean hasTag(ComponentItemWrapper item, Object... path) {
|
||||||
throw new UnsupportedOperationException("This feature is not available on 1.20.5+");
|
return getNBTTag(item, path) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean removeTag(ComponentItemWrapper item, Object... path) {
|
protected boolean removeTag(ComponentItemWrapper item, Object... path) {
|
||||||
throw new UnsupportedOperationException("This feature is not available on 1.20.5+");
|
CompoundTag rootTag = (CompoundTag) item.getSparrowNBTComponent(ComponentTypes.CUSTOM_DATA).orElse(null);
|
||||||
|
if (rootTag == null || path == null || path.length == 0) return false;
|
||||||
|
|
||||||
|
if (path.length == 1) {
|
||||||
|
String key = path[0].toString();
|
||||||
|
if (rootTag.containsKey(key)) {
|
||||||
|
rootTag.remove(key);
|
||||||
|
item.setSparrowNBTComponent(ComponentTypes.CUSTOM_DATA, rootTag);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
CompoundTag parentTag = rootTag;
|
||||||
|
for (int i = 0; i < path.length - 1; i++) {
|
||||||
|
Object pathSegment = path[i];
|
||||||
|
if (pathSegment == null) return false;
|
||||||
|
|
||||||
|
String key = pathSegment.toString();
|
||||||
|
Tag childTag = parentTag.get(key);
|
||||||
|
|
||||||
|
if (!(childTag instanceof CompoundTag)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
parentTag = (CompoundTag) childTag;
|
||||||
|
}
|
||||||
|
|
||||||
|
String finalKey = path[path.length - 1].toString();
|
||||||
|
if (parentTag.containsKey(finalKey)) {
|
||||||
|
parentTag.remove(finalKey);
|
||||||
|
item.setSparrowNBTComponent(ComponentTypes.CUSTOM_DATA, rootTag);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package net.momirealms.craftengine.bukkit.plugin.network.handler;
|
|||||||
|
|
||||||
import net.momirealms.craftengine.bukkit.item.BukkitItemManager;
|
import net.momirealms.craftengine.bukkit.item.BukkitItemManager;
|
||||||
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||||
|
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
|
||||||
import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer;
|
import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer;
|
||||||
import net.momirealms.craftengine.bukkit.util.EntityDataUtils;
|
import net.momirealms.craftengine.bukkit.util.EntityDataUtils;
|
||||||
import net.momirealms.craftengine.core.plugin.network.ByteBufPacketEvent;
|
import net.momirealms.craftengine.core.plugin.network.ByteBufPacketEvent;
|
||||||
@@ -25,7 +26,8 @@ public class CommonItemPacketHandler implements EntityPacketHandler {
|
|||||||
for (int i = 0; i < packedItems.size(); i++) {
|
for (int i = 0; i < packedItems.size(); i++) {
|
||||||
Object packedItem = packedItems.get(i);
|
Object packedItem = packedItems.get(i);
|
||||||
int entityDataId = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$id(packedItem);
|
int entityDataId = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$id(packedItem);
|
||||||
if (entityDataId == EntityDataUtils.ITEM_DATA_ID) {
|
// TODO 检查为什么会导致问题,难道是其他插件乱发entity id?
|
||||||
|
if (entityDataId == EntityDataUtils.ITEM_DATA_ID && CoreReflections.clazz$ItemStack.isInstance(packedItem)) {
|
||||||
Object nmsItemStack = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$value(packedItem);
|
Object nmsItemStack = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$value(packedItem);
|
||||||
ItemStack itemStack = FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(nmsItemStack);
|
ItemStack itemStack = FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(nmsItemStack);
|
||||||
Optional<ItemStack> optional = BukkitItemManager.instance().s2c(itemStack, (BukkitServerPlayer) user);
|
Optional<ItemStack> optional = BukkitItemManager.instance().s2c(itemStack, (BukkitServerPlayer) user);
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import net.momirealms.craftengine.core.plugin.config.ConfigParser;
|
|||||||
import net.momirealms.craftengine.core.plugin.context.ContextHolder;
|
import net.momirealms.craftengine.core.plugin.context.ContextHolder;
|
||||||
import net.momirealms.craftengine.core.plugin.context.PlayerOptionalContext;
|
import net.momirealms.craftengine.core.plugin.context.PlayerOptionalContext;
|
||||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||||
import net.momirealms.craftengine.core.plugin.locale.TranslationManager;
|
|
||||||
import net.momirealms.craftengine.core.util.*;
|
import net.momirealms.craftengine.core.util.*;
|
||||||
import org.ahocorasick.trie.Token;
|
import org.ahocorasick.trie.Token;
|
||||||
import org.ahocorasick.trie.Trie;
|
import org.ahocorasick.trie.Trie;
|
||||||
@@ -44,10 +43,8 @@ public abstract class AbstractFontManager implements FontManager {
|
|||||||
protected Trie emojiKeywordTrie;
|
protected Trie emojiKeywordTrie;
|
||||||
protected Map<String, Component> tagMapper;
|
protected Map<String, Component> tagMapper;
|
||||||
protected Map<String, Emoji> emojiMapper;
|
protected Map<String, Emoji> emojiMapper;
|
||||||
|
|
||||||
protected List<Emoji> emojiList;
|
protected List<Emoji> emojiList;
|
||||||
protected List<String> allEmojiSuggestions;
|
protected List<String> allEmojiSuggestions;
|
||||||
protected Set<Path> existingImagePaths = new HashSet<>();
|
|
||||||
|
|
||||||
public AbstractFontManager(CraftEngine plugin) {
|
public AbstractFontManager(CraftEngine plugin) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
@@ -68,7 +65,6 @@ public abstract class AbstractFontManager implements FontManager {
|
|||||||
this.images.clear();
|
this.images.clear();
|
||||||
this.illegalChars.clear();
|
this.illegalChars.clear();
|
||||||
this.emojis.clear();
|
this.emojis.clear();
|
||||||
this.existingImagePaths.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -472,14 +468,11 @@ public abstract class AbstractFontManager implements FontManager {
|
|||||||
if (character.startsWith("\\u")) {
|
if (character.startsWith("\\u")) {
|
||||||
chars = List.of(CharacterUtils.decodeUnicodeToChars(character));
|
chars = List.of(CharacterUtils.decodeUnicodeToChars(character));
|
||||||
} else {
|
} else {
|
||||||
if (CharacterUtils.containsCombinedCharacter(character)) {
|
// ??? TODO 需要测试特殊字符集
|
||||||
TranslationManager.instance().log("warning.config.image.invalid_char", path.toString(), id.toString());
|
// if (CharacterUtils.containsCombinedCharacter(character)) {
|
||||||
}
|
// TranslationManager.instance().log("warning.config.image.invalid_char", path.toString(), id.toString());
|
||||||
StringBuilder stringBuilder = new StringBuilder();
|
// }
|
||||||
for (char c : character.toCharArray()) {
|
chars = List.of(character.toCharArray());
|
||||||
stringBuilder.append(String.format("\\u%04x", (int) c));
|
|
||||||
}
|
|
||||||
chars = List.of(CharacterUtils.decodeUnicodeToChars(stringBuilder.toString()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -510,30 +503,26 @@ public abstract class AbstractFontManager implements FontManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Object heightObj = section.get("height");
|
Object heightObj = section.get("height");
|
||||||
|
|
||||||
if (!resourceLocation.endsWith(".png")) resourceLocation += ".png";
|
if (!resourceLocation.endsWith(".png")) resourceLocation += ".png";
|
||||||
Key namespacedPath = Key.of(resourceLocation);
|
|
||||||
Path targetImagePath = pack.resourcePackFolder()
|
|
||||||
.resolve("assets")
|
|
||||||
.resolve(namespacedPath.namespace())
|
|
||||||
.resolve("textures")
|
|
||||||
.resolve(namespacedPath.value());
|
|
||||||
|
|
||||||
if (!doesImageFileExist(targetImagePath)) {
|
|
||||||
// TranslationManager.instance().log("warning.config.image.file_not_found", path.toString(), id.toString(), targetImagePath.toString());
|
|
||||||
// DO NOT RETURN, JUST GIVE WARNINGS
|
|
||||||
} else if (heightObj == null) {
|
|
||||||
try (InputStream in = Files.newInputStream(targetImagePath)) {
|
|
||||||
BufferedImage image = ImageIO.read(in);
|
|
||||||
heightObj = image.getHeight() / codepointGrid.length;
|
|
||||||
} catch (IOException e) {
|
|
||||||
plugin.logger().warn("Failed to load image " + targetImagePath, e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (heightObj == null) {
|
if (heightObj == null) {
|
||||||
throw new LocalizedResourceConfigException("warning.config.image.missing_height", path, id);
|
Key namespacedPath = Key.of(resourceLocation);
|
||||||
|
Path targetImagePath = pack.resourcePackFolder()
|
||||||
|
.resolve("assets")
|
||||||
|
.resolve(namespacedPath.namespace())
|
||||||
|
.resolve("textures")
|
||||||
|
.resolve(namespacedPath.value());
|
||||||
|
if (Files.exists(targetImagePath)) {
|
||||||
|
try (InputStream in = Files.newInputStream(targetImagePath)) {
|
||||||
|
BufferedImage image = ImageIO.read(in);
|
||||||
|
heightObj = image.getHeight() / codepointGrid.length;
|
||||||
|
} catch (IOException e) {
|
||||||
|
plugin.logger().warn("Failed to load image " + targetImagePath, e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new LocalizedResourceConfigException("warning.config.image.missing_height", path, id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int height = ResourceConfigUtils.getAsInt(heightObj, "height");
|
int height = ResourceConfigUtils.getAsInt(heightObj, "height");
|
||||||
@@ -545,22 +534,11 @@ public abstract class AbstractFontManager implements FontManager {
|
|||||||
BitmapImage bitmapImage = new BitmapImage(id, fontKey, height, ascent, resourceLocation, codepointGrid);
|
BitmapImage bitmapImage = new BitmapImage(id, fontKey, height, ascent, resourceLocation, codepointGrid);
|
||||||
for (int[] y : codepointGrid) {
|
for (int[] y : codepointGrid) {
|
||||||
for (int x : y) {
|
for (int x : y) {
|
||||||
font.addBitMapImage(x, bitmapImage);
|
font.addBitmapImage(x, bitmapImage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
images.put(id, bitmapImage);
|
images.put(id, bitmapImage);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean doesImageFileExist(Path path) {
|
|
||||||
if (existingImagePaths.contains(path)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
boolean exist = Files.exists(path);
|
|
||||||
if (exist) {
|
|
||||||
existingImagePaths.add(path);
|
|
||||||
}
|
|
||||||
return exist;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ public class Font {
|
|||||||
return this.idToCodepoint.get(codepoint);
|
return this.idToCodepoint.get(codepoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addBitMapImage(int codepoint, BitmapImage image) {
|
public void addBitmapImage(int codepoint, BitmapImage image) {
|
||||||
this.idToCodepoint.put(codepoint, image);
|
this.idToCodepoint.put(codepoint, image);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -439,16 +439,25 @@ public abstract class AbstractItemManager<I> extends AbstractModelGenerator impl
|
|||||||
}, "external");
|
}, "external");
|
||||||
registerDataFunction((obj) -> {
|
registerDataFunction((obj) -> {
|
||||||
String name = obj.toString();
|
String name = obj.toString();
|
||||||
return new CustomNameModifier<>(name);
|
return new CustomNameModifier<>(Config.nonItalic() ? "<!i>" + name : name);
|
||||||
}, "custom-name");
|
}, "custom-name");
|
||||||
registerDataFunction((obj) -> {
|
registerDataFunction((obj) -> {
|
||||||
String name = obj.toString();
|
String name = obj.toString();
|
||||||
return new ItemNameModifier<>(name);
|
return new ItemNameModifier<>(Config.nonItalic() ? "<!i>" + name : name);
|
||||||
}, "item-name", "display-name");
|
}, "item-name", "display-name");
|
||||||
registerDataFunction((obj) -> {
|
registerDataFunction((obj) -> {
|
||||||
List<String> name = MiscUtils.getAsStringList(obj);
|
List<String> lore = MiscUtils.getAsStringList(obj).stream().map(it -> "<!i>" + it).toList();
|
||||||
return new LoreModifier<>(name);
|
return new LoreModifier<>(lore);
|
||||||
}, "lore", "display-lore", "description");
|
}, "lore", "display-lore", "description");
|
||||||
|
registerDataFunction((obj) -> {
|
||||||
|
Map<String, List<String>> dynamicLore = new LinkedHashMap<>();
|
||||||
|
if (obj instanceof Map<?, ?> map) {
|
||||||
|
for (Map.Entry<?, ?> entry : map.entrySet()) {
|
||||||
|
dynamicLore.put(entry.getKey().toString(), MiscUtils.getAsStringList(entry.getValue()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new DynamicLoreModifier<>(dynamicLore);
|
||||||
|
}, "dynamic-lore");
|
||||||
registerDataFunction((obj) -> {
|
registerDataFunction((obj) -> {
|
||||||
Map<String, Object> data = MiscUtils.castToMap(obj, false);
|
Map<String, Object> data = MiscUtils.castToMap(obj, false);
|
||||||
return new TagsModifier<>(data);
|
return new TagsModifier<>(data);
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import net.momirealms.craftengine.core.item.ComponentKeys;
|
|||||||
import net.momirealms.craftengine.core.item.Item;
|
import net.momirealms.craftengine.core.item.Item;
|
||||||
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
||||||
import net.momirealms.craftengine.core.item.NetworkItemHandler;
|
import net.momirealms.craftengine.core.item.NetworkItemHandler;
|
||||||
import net.momirealms.craftengine.core.plugin.config.Config;
|
|
||||||
import net.momirealms.craftengine.core.util.AdventureHelper;
|
import net.momirealms.craftengine.core.util.AdventureHelper;
|
||||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||||
import net.momirealms.sparrow.nbt.CompoundTag;
|
import net.momirealms.sparrow.nbt.CompoundTag;
|
||||||
@@ -14,7 +13,7 @@ public class CustomNameModifier<I> implements ItemDataModifier<I> {
|
|||||||
private final String argument;
|
private final String argument;
|
||||||
|
|
||||||
public CustomNameModifier(String argument) {
|
public CustomNameModifier(String argument) {
|
||||||
this.argument = Config.nonItalic() ? "<!i>" + argument : argument;
|
this.argument = argument;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
package net.momirealms.craftengine.core.item.modifier;
|
||||||
|
|
||||||
|
import net.momirealms.craftengine.core.item.ComponentKeys;
|
||||||
|
import net.momirealms.craftengine.core.item.Item;
|
||||||
|
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
||||||
|
import net.momirealms.craftengine.core.item.NetworkItemHandler;
|
||||||
|
import net.momirealms.craftengine.core.util.AdventureHelper;
|
||||||
|
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||||
|
import net.momirealms.sparrow.nbt.CompoundTag;
|
||||||
|
import net.momirealms.sparrow.nbt.Tag;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class DynamicLoreModifier<I> implements ItemDataModifier<I> {
|
||||||
|
private final Map<String, List<String>> displayContexts;
|
||||||
|
private final String defaultContext;
|
||||||
|
|
||||||
|
public DynamicLoreModifier(Map<String, List<String>> displayContexts) {
|
||||||
|
this.defaultContext = displayContexts.keySet().iterator().next();
|
||||||
|
this.displayContexts = displayContexts;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String name() {
|
||||||
|
return "dynamic-lore";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void apply(Item<I> item, ItemBuildContext context) {
|
||||||
|
String displayContext = Optional.ofNullable(item.getJavaTag("craftengine:display_context")).orElse(this.defaultContext).toString();
|
||||||
|
List<String> lore = this.displayContexts.get(displayContext);
|
||||||
|
if (lore == null) {
|
||||||
|
lore = this.displayContexts.get(this.defaultContext);
|
||||||
|
}
|
||||||
|
item.loreComponent(lore.stream().map(it -> AdventureHelper.miniMessage().deserialize(it, context.tagResolvers())).toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void prepareNetworkItem(Item<I> item, ItemBuildContext context, CompoundTag networkData) {
|
||||||
|
if (VersionHelper.isOrAbove1_20_5()) {
|
||||||
|
Tag previous = item.getNBTComponent(ComponentKeys.LORE);
|
||||||
|
if (previous != null) {
|
||||||
|
networkData.put(ComponentKeys.LORE.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous));
|
||||||
|
} else {
|
||||||
|
networkData.put(ComponentKeys.LORE.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Tag previous = item.getNBTTag("display", "Lore");
|
||||||
|
if (previous != null) {
|
||||||
|
networkData.put("display.Lore", NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous));
|
||||||
|
} else {
|
||||||
|
networkData.put("display.Lore", NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,7 +4,6 @@ import net.momirealms.craftengine.core.item.ComponentKeys;
|
|||||||
import net.momirealms.craftengine.core.item.Item;
|
import net.momirealms.craftengine.core.item.Item;
|
||||||
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
||||||
import net.momirealms.craftengine.core.item.NetworkItemHandler;
|
import net.momirealms.craftengine.core.item.NetworkItemHandler;
|
||||||
import net.momirealms.craftengine.core.plugin.config.Config;
|
|
||||||
import net.momirealms.craftengine.core.util.AdventureHelper;
|
import net.momirealms.craftengine.core.util.AdventureHelper;
|
||||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||||
import net.momirealms.sparrow.nbt.CompoundTag;
|
import net.momirealms.sparrow.nbt.CompoundTag;
|
||||||
@@ -14,7 +13,7 @@ public class ItemNameModifier<I> implements ItemDataModifier<I> {
|
|||||||
private final String argument;
|
private final String argument;
|
||||||
|
|
||||||
public ItemNameModifier(String argument) {
|
public ItemNameModifier(String argument) {
|
||||||
this.argument = Config.nonItalic() ? "<!i>" + argument : argument;
|
this.argument = argument;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import net.momirealms.craftengine.core.item.ComponentKeys;
|
|||||||
import net.momirealms.craftengine.core.item.Item;
|
import net.momirealms.craftengine.core.item.Item;
|
||||||
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
||||||
import net.momirealms.craftengine.core.item.NetworkItemHandler;
|
import net.momirealms.craftengine.core.item.NetworkItemHandler;
|
||||||
import net.momirealms.craftengine.core.plugin.config.Config;
|
|
||||||
import net.momirealms.craftengine.core.util.AdventureHelper;
|
import net.momirealms.craftengine.core.util.AdventureHelper;
|
||||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||||
import net.momirealms.sparrow.nbt.CompoundTag;
|
import net.momirealms.sparrow.nbt.CompoundTag;
|
||||||
@@ -16,7 +15,7 @@ public class LoreModifier<I> implements ItemDataModifier<I> {
|
|||||||
private final List<String> argument;
|
private final List<String> argument;
|
||||||
|
|
||||||
public LoreModifier(List<String> argument) {
|
public LoreModifier(List<String> argument) {
|
||||||
this.argument = Config.nonItalic() ? argument.stream().map(it -> "<!i>" + it).toList() : argument;
|
this.argument = argument;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -26,8 +25,7 @@ public class LoreModifier<I> implements ItemDataModifier<I> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void apply(Item<I> item, ItemBuildContext context) {
|
public void apply(Item<I> item, ItemBuildContext context) {
|
||||||
item.loreComponent(this.argument.stream().map(it -> AdventureHelper.miniMessage().deserialize(
|
item.loreComponent(this.argument.stream().map(it -> AdventureHelper.miniMessage().deserialize(it, context.tagResolvers())).toList());
|
||||||
it, context.tagResolvers())).toList());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -488,6 +488,7 @@ public abstract class AbstractPackManager implements PackManager {
|
|||||||
this.plugin.logger().info("Loaded packs. Took " + String.format("%.2f", ((o2 - o1) / 1_000_000.0)) + " ms");
|
this.plugin.logger().info("Loaded packs. Took " + String.format("%.2f", ((o2 - o1) / 1_000_000.0)) + " ms");
|
||||||
for (Map.Entry<ConfigParser, List<CachedConfigSection>> entry : cachedConfigs.entrySet()) {
|
for (Map.Entry<ConfigParser, List<CachedConfigSection>> entry : cachedConfigs.entrySet()) {
|
||||||
ConfigParser parser = entry.getKey();
|
ConfigParser parser = entry.getKey();
|
||||||
|
if (!predicate.test(parser)) continue;
|
||||||
long t1 = System.nanoTime();
|
long t1 = System.nanoTime();
|
||||||
for (CachedConfigSection cached : entry.getValue()) {
|
for (CachedConfigSection cached : entry.getValue()) {
|
||||||
for (Map.Entry<String, Object> configEntry : cached.config().entrySet()) {
|
for (Map.Entry<String, Object> configEntry : cached.config().entrySet()) {
|
||||||
@@ -497,7 +498,7 @@ public abstract class AbstractPackManager implements PackManager {
|
|||||||
if (parser.supportsParsingObject()) {
|
if (parser.supportsParsingObject()) {
|
||||||
// do not apply templates
|
// do not apply templates
|
||||||
parser.parseObject(cached.pack(), cached.filePath(), id, configEntry.getValue());
|
parser.parseObject(cached.pack(), cached.filePath(), id, configEntry.getValue());
|
||||||
} else if (predicate.test(parser)) {
|
} else {
|
||||||
if (configEntry.getValue() instanceof Map<?, ?> configSection0) {
|
if (configEntry.getValue() instanceof Map<?, ?> configSection0) {
|
||||||
Map<String, Object> config = castToMap(configSection0, false);
|
Map<String, Object> config = castToMap(configSection0, false);
|
||||||
if ((boolean) config.getOrDefault("enable", true)) {
|
if ((boolean) config.getOrDefault("enable", true)) {
|
||||||
|
|||||||
@@ -160,7 +160,7 @@ public class Config {
|
|||||||
BasicFileAttributes attributes = Files.readAttributes(this.configFilePath, BasicFileAttributes.class);
|
BasicFileAttributes attributes = Files.readAttributes(this.configFilePath, BasicFileAttributes.class);
|
||||||
long lastModified = attributes.lastModifiedTime().toMillis();
|
long lastModified = attributes.lastModifiedTime().toMillis();
|
||||||
long size = attributes.size();
|
long size = attributes.size();
|
||||||
if (lastModified != this.lastModified || size != this.size) {
|
if (lastModified != this.lastModified || size != this.size || this.config == null) {
|
||||||
byte[] configFileBytes = Files.readAllBytes(this.configFilePath);
|
byte[] configFileBytes = Files.readAllBytes(this.configFilePath);
|
||||||
try (InputStream inputStream = new ByteArrayInputStream(configFileBytes)) {
|
try (InputStream inputStream = new ByteArrayInputStream(configFileBytes)) {
|
||||||
this.config = YamlDocument.create(inputStream);
|
this.config = YamlDocument.create(inputStream);
|
||||||
|
|||||||
@@ -114,14 +114,14 @@ public class TemplateManagerImpl implements TemplateManager {
|
|||||||
Map<String, Object> results = new LinkedHashMap<>();
|
Map<String, Object> results = new LinkedHashMap<>();
|
||||||
for (Object processedTemplate : processedTemplates) {
|
for (Object processedTemplate : processedTemplates) {
|
||||||
if (processedTemplate instanceof Map<?, ?> map) {
|
if (processedTemplate instanceof Map<?, ?> map) {
|
||||||
deepMergeMaps(results, MiscUtils.castToMap(map, false));
|
MiscUtils.deepMergeMaps(results, MiscUtils.castToMap(map, false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (processingResult.overrides() instanceof Map<?, ?> overrides) {
|
if (processingResult.overrides() instanceof Map<?, ?> overrides) {
|
||||||
results.putAll(MiscUtils.castToMap(overrides, false));
|
results.putAll(MiscUtils.castToMap(overrides, false));
|
||||||
}
|
}
|
||||||
if (processingResult.merges() instanceof Map<?, ?> merges) {
|
if (processingResult.merges() instanceof Map<?, ?> merges) {
|
||||||
deepMergeMaps(results, MiscUtils.castToMap(merges, false));
|
MiscUtils.deepMergeMaps(results, MiscUtils.castToMap(merges, false));
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
} else if (firstTemplate instanceof List<?>) {
|
} else if (firstTemplate instanceof List<?>) {
|
||||||
@@ -155,7 +155,7 @@ public class TemplateManagerImpl implements TemplateManager {
|
|||||||
if (processingResult.overrides() instanceof Map<?,?> overrides) {
|
if (processingResult.overrides() instanceof Map<?,?> overrides) {
|
||||||
Map<String, Object> output = new LinkedHashMap<>(MiscUtils.castToMap(overrides, false));
|
Map<String, Object> output = new LinkedHashMap<>(MiscUtils.castToMap(overrides, false));
|
||||||
if (processingResult.merges() instanceof Map<?,?> merges) {
|
if (processingResult.merges() instanceof Map<?,?> merges) {
|
||||||
deepMergeMaps(output, MiscUtils.castToMap(merges, false));
|
MiscUtils.deepMergeMaps(output, MiscUtils.castToMap(merges, false));
|
||||||
}
|
}
|
||||||
return output;
|
return output;
|
||||||
} else if (processingResult.overrides() instanceof List<?> overrides) {
|
} else if (processingResult.overrides() instanceof List<?> overrides) {
|
||||||
@@ -329,28 +329,4 @@ public class TemplateManagerImpl implements TemplateManager {
|
|||||||
Object merges,
|
Object merges,
|
||||||
Map<String, TemplateArgument> arguments
|
Map<String, TemplateArgument> arguments
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
private void deepMergeMaps(Map<String, Object> baseMap, Map<String, Object> mapToMerge) {
|
|
||||||
for (Map.Entry<String, Object> entry : mapToMerge.entrySet()) {
|
|
||||||
String key = entry.getKey();
|
|
||||||
Object value = entry.getValue();
|
|
||||||
if (baseMap.containsKey(key)) {
|
|
||||||
Object existingValue = baseMap.get(key);
|
|
||||||
if (existingValue instanceof Map && value instanceof Map) {
|
|
||||||
Map<String, Object> existingMap = (Map<String, Object>) existingValue;
|
|
||||||
Map<String, Object> newMap = (Map<String, Object>) value;
|
|
||||||
deepMergeMaps(existingMap, newMap);
|
|
||||||
} else if (existingValue instanceof List && value instanceof List) {
|
|
||||||
List<Object> existingList = (List<Object>) existingValue;
|
|
||||||
List<Object> newList = (List<Object>) value;
|
|
||||||
existingList.addAll(newList);
|
|
||||||
} else {
|
|
||||||
baseMap.put(key, value);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
baseMap.put(key, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,19 +11,16 @@ public class CharacterUtils {
|
|||||||
private CharacterUtils() {}
|
private CharacterUtils() {}
|
||||||
|
|
||||||
public static char[] decodeUnicodeToChars(String unicodeString) {
|
public static char[] decodeUnicodeToChars(String unicodeString) {
|
||||||
String processedString = unicodeString.replace("\\u", "");
|
int count = unicodeString.length() / 6;
|
||||||
int length = processedString.length() / 4;
|
if (unicodeString.length() % 6 != 0) {
|
||||||
char[] chars = new char[length];
|
throw new LocalizedResourceConfigException("warning.config.image.invalid_unicode_string_length");
|
||||||
for (int i = 0; i < length; i++) {
|
}
|
||||||
String hex = processedString.substring(i * 4, i * 4 + 4);
|
char[] chars = new char[count];
|
||||||
|
for (int i = 0, j = 0; j < count; i += 6, j++) {
|
||||||
|
String hex = unicodeString.substring(i + 2, i + 6);
|
||||||
try {
|
try {
|
||||||
int codePoint = Integer.parseInt(hex, 16);
|
int codePoint = Integer.parseInt(hex, 16);
|
||||||
if (Character.isSupplementaryCodePoint(codePoint)) {
|
chars[j] = (char) codePoint;
|
||||||
chars[i] = Character.highSurrogate(codePoint);
|
|
||||||
chars[++i] = Character.lowSurrogate(codePoint);
|
|
||||||
} else {
|
|
||||||
chars[i] = (char) codePoint;
|
|
||||||
}
|
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
throw new LocalizedResourceConfigException("warning.config.image.invalid_hex_value", e, hex);
|
throw new LocalizedResourceConfigException("warning.config.image.invalid_hex_value", e, hex);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -99,4 +99,28 @@ public class MiscUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static void deepMergeMaps(Map<String, Object> baseMap, Map<String, Object> mapToMerge) {
|
||||||
|
for (Map.Entry<String, Object> entry : mapToMerge.entrySet()) {
|
||||||
|
String key = entry.getKey();
|
||||||
|
Object value = entry.getValue();
|
||||||
|
if (baseMap.containsKey(key)) {
|
||||||
|
Object existingValue = baseMap.get(key);
|
||||||
|
if (existingValue instanceof Map && value instanceof Map) {
|
||||||
|
Map<String, Object> existingMap = (Map<String, Object>) existingValue;
|
||||||
|
Map<String, Object> newMap = (Map<String, Object>) value;
|
||||||
|
deepMergeMaps(existingMap, newMap);
|
||||||
|
} else if (existingValue instanceof List && value instanceof List) {
|
||||||
|
List<Object> existingList = (List<Object>) existingValue;
|
||||||
|
List<Object> newList = (List<Object>) value;
|
||||||
|
existingList.addAll(newList);
|
||||||
|
} else {
|
||||||
|
baseMap.put(key, value);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
baseMap.put(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ org.gradle.jvmargs=-Xmx1G
|
|||||||
|
|
||||||
# Project settings
|
# Project settings
|
||||||
# Rule: [major update].[feature update].[bug fix]
|
# Rule: [major update].[feature update].[bug fix]
|
||||||
project_version=0.0.56.1
|
project_version=0.0.56.2
|
||||||
config_version=34
|
config_version=34
|
||||||
lang_version=15
|
lang_version=15
|
||||||
project_group=net.momirealms
|
project_group=net.momirealms
|
||||||
|
|||||||
Reference in New Issue
Block a user