From c73032266d6a0ed306ea4db27bd468b38dddb502 Mon Sep 17 00:00:00 2001 From: Carm Date: Wed, 11 Oct 2023 22:32:19 +0800 Subject: [PATCH] =?UTF-8?q?feat(item):=20=E4=BC=98=E5=8C=96PreparedItem?= =?UTF-8?q?=E7=9A=84=E7=BB=93=E6=9E=84=EF=BC=8C=E4=BD=BF=E5=85=B6=E9=80=82?= =?UTF-8?q?=E7=94=A8=E4=BA=8E=E6=9B=B4=E5=A4=9A=E9=A1=B9=E7=9B=AE=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/pom.xml | 2 +- platform/bukkit/pom.xml | 2 +- .../bukkit/value/item/ItemModifier.java | 262 ++++++++++++++++++ .../bukkit/value/item/PreparedItem.java | 245 +--------------- platform/bungee/pom.xml | 2 +- pom.xml | 2 +- 6 files changed, 272 insertions(+), 243 deletions(-) create mode 100644 platform/bukkit/src/main/java/cc/carm/lib/mineconfiguration/bukkit/value/item/ItemModifier.java diff --git a/common/pom.xml b/common/pom.xml index 53f113f..234d32c 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -5,7 +5,7 @@ mineconfiguration-parent cc.carm.lib - 2.8.6 + 2.8.7 4.0.0 diff --git a/platform/bukkit/pom.xml b/platform/bukkit/pom.xml index d5ec5da..20a0710 100644 --- a/platform/bukkit/pom.xml +++ b/platform/bukkit/pom.xml @@ -5,7 +5,7 @@ mineconfiguration-parent cc.carm.lib - 2.8.6 + 2.8.7 ../../pom.xml 4.0.0 diff --git a/platform/bukkit/src/main/java/cc/carm/lib/mineconfiguration/bukkit/value/item/ItemModifier.java b/platform/bukkit/src/main/java/cc/carm/lib/mineconfiguration/bukkit/value/item/ItemModifier.java new file mode 100644 index 0000000..d83c454 --- /dev/null +++ b/platform/bukkit/src/main/java/cc/carm/lib/mineconfiguration/bukkit/value/item/ItemModifier.java @@ -0,0 +1,262 @@ +package cc.carm.lib.mineconfiguration.bukkit.value.item; + +import cc.carm.lib.configuration.core.value.type.ConfiguredList; +import cc.carm.lib.mineconfiguration.bukkit.utils.TextParser; +import cc.carm.lib.mineconfiguration.bukkit.value.ConfiguredMessage; +import cc.carm.lib.mineconfiguration.bukkit.value.ConfiguredMessageList; +import cc.carm.lib.mineconfiguration.common.utils.ParamsUtils; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.SkullMeta; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.*; +import java.util.function.BiConsumer; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public abstract class ItemModifier, R> { + + public static final @NotNull Pattern LORE_INSERT_PATTERN = Pattern.compile("^(?:\\{(.*)})?#(.*)#(?:\\{(-?\\d+)(?:,(-?\\d+))?})?$"); + + protected final @NotNull Function<@NotNull Player, @Nullable ItemStack> itemProvider; + + protected @NotNull Map placeholders = new HashMap<>(); + protected @NotNull String[] params; + protected @NotNull Object[] values; + + protected final @NotNull Map insertLore = new HashMap<>(); + + protected @NotNull BiConsumer itemModifier; + protected @NotNull BiConsumer metaModifier; + + protected ItemModifier(@NotNull Function<@NotNull Player, @Nullable ItemStack> itemProvider) { + this.itemProvider = itemProvider; + this.params = new String[0]; + this.values = new Object[0]; + itemModifier = (item, player) -> { + }; + metaModifier = (meta, player) -> { + }; + } + + public abstract @NotNull S getThis(); + + public abstract @Nullable R get(Player player); + + public void applyTo(@Nullable ItemStack item, @Nullable Player player) { + if (item == null) return; + + ItemMeta meta = item.getItemMeta(); + if (meta == null) return; + + Map finalPlaceholders = buildPlaceholders(); + + String name = meta.getDisplayName(); + if (!name.isEmpty()) { + meta.setDisplayName(TextParser.parseText(player, name, finalPlaceholders)); + } + + List parsedLore = parseLore(player, meta.getLore(), insertLore, finalPlaceholders); + if (!parsedLore.isEmpty()) { + meta.setLore(parsedLore); + } + + metaModifier.accept(meta, player); + item.setItemMeta(meta); + itemModifier.accept(item, player); + } + + public S handleMeta(@NotNull BiConsumer modifier) { + this.metaModifier = this.metaModifier.andThen(modifier); + return getThis(); + } + + public S handleItem(@NotNull BiConsumer modifier) { + this.itemModifier = this.itemModifier.andThen(modifier); + return getThis(); + } + + public S params(String[] params) { + this.params = params; + return getThis(); + } + + public S values(Object... values) { + this.values = values; + return getThis(); + } + + public S placeholders(@NotNull Map placeholders) { + this.placeholders = placeholders; + return getThis(); + } + + public S placeholders(@NotNull Consumer> consumer) { + Map placeholders = new HashMap<>(); + consumer.accept(placeholders); + return placeholders(placeholders); + } + + public S insertLore(@NotNull String path, @NotNull LoreContent content) { + insertLore.put(path, content); + return getThis(); + } + + public S insertLore(@NotNull String path, @NotNull List content) { + return insertLore(path, content, false); + } + + public S insertLore(@NotNull String path, @NotNull List content, boolean original) { + return insertLore(path, LoreContent.of(content, original)); + } + + public S insertLore(@NotNull String path, @NotNull String... content) { + return insertLore(path, Arrays.asList(content)); + } + + public S insertLore(@NotNull String path, @NotNull ConfiguredList content) { + return insertLore(path, content.copy()); + } + + public S insertLore(@NotNull String path, + @NotNull ConfiguredMessage content, @NotNull Object... params) { + String c = content.parse(null, params); + if (c == null) return getThis(); + return insertLore(path, c); + } + + public S insertLore(@NotNull String path, + @NotNull ConfiguredMessageList content, @NotNull Object... params) { + List c = content.parse(null, params); + if (c == null || c.isEmpty()) return getThis(); + return insertLore(path, c); + } + + public S amount(int amount) { + return handleItem((item, player) -> item.setAmount(amount)); + } + + public S addEnchantment(Enchantment e) { + return addEnchantment(e, 1); + } + + public S addEnchantment(Enchantment e, int level) { + return addEnchantment(e, level, true); + } + + public S addEnchantment(Enchantment e, int level, boolean ignoreLevelRestriction) { + return handleMeta((meta, player) -> meta.addEnchant(e, level, ignoreLevelRestriction)); + } + + public S addItemFlags(ItemFlag... flags) { + return handleMeta((meta, player) -> meta.addItemFlags(flags)); + } + + public S glow() { + return addItemFlags(ItemFlag.HIDE_ENCHANTS).addEnchantment(Enchantment.DURABILITY); + } + + /** + * @param owner 玩家名 + * @return this + * @deprecated Use {@link #setSkullOwner(OfflinePlayer)} instead. + */ + @Deprecated + public S setSkullOwner(String owner) { + return handleItem((item, player) -> { + if (!(item.getItemMeta() instanceof SkullMeta)) return; + SkullMeta meta = (SkullMeta) item.getItemMeta(); + meta.setOwner(owner); + }); + } + + public S setSkullOwner(UUID owner) { + return setSkullOwner(Bukkit.getOfflinePlayer(owner)); + } + + public S setSkullOwner(OfflinePlayer owner) { + return handleItem((item, player) -> { + if (!(item.getItemMeta() instanceof SkullMeta)) return; + SkullMeta meta = (SkullMeta) item.getItemMeta(); + meta.setOwningPlayer(owner); + }); + } + + + protected Map buildPlaceholders() { + Map finalPlaceholders = new HashMap<>(); + finalPlaceholders.putAll(ParamsUtils.buildParams(params, values)); + finalPlaceholders.putAll(this.placeholders); + return finalPlaceholders; + } + + public static List parseLore(@Nullable Player player, @Nullable List lore, + @NotNull Map insertedLore, + @NotNull Map placeholders) { + List parsedLore = new ArrayList<>(); + if (lore == null || lore.isEmpty()) return parsedLore; + + for (String line : lore) { + Matcher matcher = LORE_INSERT_PATTERN.matcher(line); + if (!matcher.matches()) { + parsedLore.add(TextParser.parseText(player, line, placeholders)); + continue; + } + + String path = matcher.group(2); + LoreContent content = insertedLore.get(path); + if (content == null) continue; + + String prefix = Optional.ofNullable(matcher.group(1)) + .map(s -> TextParser.parseText(player, s, placeholders)) + .orElse(""); + int offset1 = Optional.ofNullable(matcher.group(3)) + .map(Integer::parseInt).orElse(0); + Integer offset2 = Optional.ofNullable(matcher.group(4)) + .map(Integer::parseInt).orElse(null); + + List inserted = parseLoreLine( + player, content, placeholders, prefix, + offset2 == null ? 0 : offset1, offset2 == null ? offset1 : offset2 + ); + + if (content.isOriginal()) { + parsedLore.addAll(inserted); + } else { + parsedLore.addAll(TextParser.parseList(player, inserted, placeholders)); + } + } + return parsedLore; + } + + public static List parseLoreLine(@Nullable Player player, @NotNull LoreContent content, + @NotNull Map placeholders, + @NotNull String parsedPrefix, int upOffset, int downOffset) { + if (content.getContent().isEmpty()) return Collections.emptyList(); + + upOffset = Math.max(0, upOffset); + downOffset = Math.max(0, downOffset); + + List finalLore = new ArrayList<>(); + + for (int i = 0; i < upOffset; i++) finalLore.add(" "); + if (content.isOriginal()) { + content.getContent().stream().map(s -> parsedPrefix + s).forEach(finalLore::add); + } else { + content.getContent().stream().map(s -> parsedPrefix + TextParser.parseText(player, s, placeholders)) + .forEach(finalLore::add); + } + for (int i = 0; i < downOffset; i++) finalLore.add(" "); + + return finalLore; + } +} diff --git a/platform/bukkit/src/main/java/cc/carm/lib/mineconfiguration/bukkit/value/item/PreparedItem.java b/platform/bukkit/src/main/java/cc/carm/lib/mineconfiguration/bukkit/value/item/PreparedItem.java index de73626..288a7a0 100644 --- a/platform/bukkit/src/main/java/cc/carm/lib/mineconfiguration/bukkit/value/item/PreparedItem.java +++ b/platform/bukkit/src/main/java/cc/carm/lib/mineconfiguration/bukkit/value/item/PreparedItem.java @@ -1,31 +1,13 @@ package cc.carm.lib.mineconfiguration.bukkit.value.item; -import cc.carm.lib.configuration.core.value.type.ConfiguredList; -import cc.carm.lib.mineconfiguration.bukkit.utils.TextParser; -import cc.carm.lib.mineconfiguration.bukkit.value.ConfiguredMessage; -import cc.carm.lib.mineconfiguration.bukkit.value.ConfiguredMessageList; -import cc.carm.lib.mineconfiguration.common.utils.ParamsUtils; -import org.bukkit.Bukkit; -import org.bukkit.OfflinePlayer; -import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.inventory.meta.SkullMeta; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.*; -import java.util.function.BiConsumer; -import java.util.function.Consumer; import java.util.function.Function; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -public class PreparedItem { - - public static final @NotNull Pattern LORE_INSERT_PATTERN = Pattern.compile("^(?:\\{(.*)})?#(.*)#(?:\\{(-?\\d+)(?:,(-?\\d+))?})?$"); +public class PreparedItem extends ItemModifier { public static PreparedItem of(@NotNull Function<@NotNull Player, @Nullable ItemStack> itemProvider) { return new PreparedItem(itemProvider); @@ -35,236 +17,21 @@ public class PreparedItem { return of(player -> item); } - protected final @NotNull Function<@NotNull Player, @Nullable ItemStack> itemProvider; - - protected @NotNull Map placeholders = new HashMap<>(); - protected @NotNull String[] params; - protected @NotNull Object[] values; - - protected final @NotNull Map insertLore = new HashMap<>(); - - protected @NotNull BiConsumer itemModifier; - protected @NotNull BiConsumer metaModifier; - - protected PreparedItem(@NotNull Function<@NotNull Player, @Nullable ItemStack> itemProvider) { - this.itemProvider = itemProvider; - this.params = new String[0]; - this.values = new Object[0]; - itemModifier = (item, player) -> { - }; - metaModifier = (meta, player) -> { - }; + public PreparedItem(@NotNull Function<@NotNull Player, @Nullable ItemStack> itemProvider) { + super(itemProvider); } public @Nullable ItemStack get(Player player) { @Nullable ItemStack item = itemProvider.apply(player); if (item == null) return null; - ItemMeta meta = item.getItemMeta(); - if (meta == null) return item; - - - Map finalPlaceholders = buildPlaceholders(); - - String name = meta.getDisplayName(); - if (!name.isEmpty()) { - meta.setDisplayName(TextParser.parseText(player, name, finalPlaceholders)); - } - - List parsedLore = parseLore(player, meta.getLore(), insertLore, finalPlaceholders); - if (!parsedLore.isEmpty()) { - meta.setLore(parsedLore); - } - - metaModifier.accept(meta, player); - item.setItemMeta(meta); - itemModifier.accept(item, player); + applyTo(item, player); return item; } - public PreparedItem handleMeta(@NotNull BiConsumer modifier) { - this.metaModifier = this.metaModifier.andThen(modifier); + @Override + public @NotNull PreparedItem getThis() { return this; } - public PreparedItem handleItem(@NotNull BiConsumer modifier) { - this.itemModifier = this.itemModifier.andThen(modifier); - return this; - } - - public PreparedItem params(String[] params) { - this.params = params; - return this; - } - - public PreparedItem values(Object... values) { - this.values = values; - return this; - } - - public PreparedItem placeholders(@NotNull Map placeholders) { - this.placeholders = placeholders; - return this; - } - - public PreparedItem placeholders(@NotNull Consumer> consumer) { - Map placeholders = new HashMap<>(); - consumer.accept(placeholders); - return placeholders(placeholders); - } - - public PreparedItem insertLore(@NotNull String path, @NotNull LoreContent content) { - insertLore.put(path, content); - return this; - } - - public PreparedItem insertLore(@NotNull String path, @NotNull List content) { - return insertLore(path, content, false); - } - - public PreparedItem insertLore(@NotNull String path, @NotNull List content, boolean original) { - return insertLore(path, LoreContent.of(content, original)); - } - - public PreparedItem insertLore(@NotNull String path, @NotNull String... content) { - return insertLore(path, Arrays.asList(content)); - } - - public PreparedItem insertLore(@NotNull String path, @NotNull ConfiguredList content) { - return insertLore(path, content.copy()); - } - - public PreparedItem insertLore(@NotNull String path, - @NotNull ConfiguredMessage content, @NotNull Object... params) { - String c = content.parse(null, params); - if (c == null) return this; - return insertLore(path, c); - } - - public PreparedItem insertLore(@NotNull String path, - @NotNull ConfiguredMessageList content, @NotNull Object... params) { - List c = content.parse(null, params); - if (c == null || c.isEmpty()) return this; - return insertLore(path, c); - } - - public PreparedItem amount(int amount) { - return handleItem((item, player) -> item.setAmount(amount)); - } - - public PreparedItem addEnchantment(Enchantment e) { - return addEnchantment(e, 1); - } - - public PreparedItem addEnchantment(Enchantment e, int level) { - return addEnchantment(e, level, true); - } - - public PreparedItem addEnchantment(Enchantment e, int level, boolean ignoreLevelRestriction) { - return handleMeta((meta, player) -> meta.addEnchant(e, level, ignoreLevelRestriction)); - } - - public PreparedItem addItemFlags(ItemFlag... flags) { - return handleMeta((meta, player) -> meta.addItemFlags(flags)); - } - - public PreparedItem glow() { - return addItemFlags(ItemFlag.HIDE_ENCHANTS).addEnchantment(Enchantment.DURABILITY); - } - - /** - * @param owner 玩家名 - * @return this - * @deprecated Use {@link #setSkullOwner(OfflinePlayer)} instead. - */ - @Deprecated - public PreparedItem setSkullOwner(String owner) { - return handleItem((item, player) -> { - if (!(item.getItemMeta() instanceof SkullMeta)) return; - SkullMeta meta = (SkullMeta) item.getItemMeta(); - meta.setOwner(owner); - }); - } - - public PreparedItem setSkullOwner(UUID owner) { - return setSkullOwner(Bukkit.getOfflinePlayer(owner)); - } - - public PreparedItem setSkullOwner(OfflinePlayer owner) { - return handleItem((item, player) -> { - if (!(item.getItemMeta() instanceof SkullMeta)) return; - SkullMeta meta = (SkullMeta) item.getItemMeta(); - meta.setOwningPlayer(owner); - }); - } - - - protected Map buildPlaceholders() { - Map finalPlaceholders = new HashMap<>(); - finalPlaceholders.putAll(ParamsUtils.buildParams(params, values)); - finalPlaceholders.putAll(this.placeholders); - return finalPlaceholders; - } - - public static List parseLore(@Nullable Player player, @Nullable List lore, - @NotNull Map insertedLore, - @NotNull Map placeholders) { - List parsedLore = new ArrayList<>(); - if (lore == null || lore.isEmpty()) return parsedLore; - - for (String line : lore) { - Matcher matcher = PreparedItem.LORE_INSERT_PATTERN.matcher(line); - if (!matcher.matches()) { - parsedLore.add(TextParser.parseText(player, line, placeholders)); - continue; - } - - String path = matcher.group(2); - LoreContent content = insertedLore.get(path); - if (content == null) continue; - - String prefix = Optional.ofNullable(matcher.group(1)) - .map(s -> TextParser.parseText(player, s, placeholders)) - .orElse(""); - int offset1 = Optional.ofNullable(matcher.group(3)) - .map(Integer::parseInt).orElse(0); - Integer offset2 = Optional.ofNullable(matcher.group(4)) - .map(Integer::parseInt).orElse(null); - - List inserted = parseLoreLine( - player, content, placeholders, prefix, - offset2 == null ? 0 : offset1, offset2 == null ? offset1 : offset2 - ); - - if (content.isOriginal()) { - parsedLore.addAll(inserted); - } else { - parsedLore.addAll(TextParser.parseList(player, inserted, placeholders)); - } - } - return parsedLore; - } - - public static List parseLoreLine(@Nullable Player player, @NotNull LoreContent content, - @NotNull Map placeholders, - @NotNull String parsedPrefix, int upOffset, int downOffset) { - if (content.getContent().isEmpty()) return Collections.emptyList(); - - upOffset = Math.max(0, upOffset); - downOffset = Math.max(0, downOffset); - - List finalLore = new ArrayList<>(); - - for (int i = 0; i < upOffset; i++) finalLore.add(" "); - if (content.isOriginal()) { - content.getContent().stream().map(s -> parsedPrefix + s).forEach(finalLore::add); - } else { - content.getContent().stream().map(s -> parsedPrefix + TextParser.parseText(player, s, placeholders)) - .forEach(finalLore::add); - } - for (int i = 0; i < downOffset; i++) finalLore.add(" "); - - return finalLore; - } - } \ No newline at end of file diff --git a/platform/bungee/pom.xml b/platform/bungee/pom.xml index e0f96c8..42f5072 100644 --- a/platform/bungee/pom.xml +++ b/platform/bungee/pom.xml @@ -5,7 +5,7 @@ mineconfiguration-parent cc.carm.lib - 2.8.6 + 2.8.7 ../../pom.xml 4.0.0 diff --git a/pom.xml b/pom.xml index a34732d..6f28ed9 100644 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ cc.carm.lib mineconfiguration-parent - 2.8.6 + 2.8.7 pom common