mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-19 15:09:15 +00:00
添加显示掉落物名称
This commit is contained in:
@@ -75,7 +75,7 @@ repositories {
|
|||||||
```
|
```
|
||||||
```kotlin
|
```kotlin
|
||||||
dependencies {
|
dependencies {
|
||||||
compileOnly("net.momirealms:craft-engine-core:0.0.65")
|
compileOnly("net.momirealms:craft-engine-core:0.0.66")
|
||||||
compileOnly("net.momirealms:craft-engine-bukkit:0.0.65")
|
compileOnly("net.momirealms:craft-engine-bukkit:0.0.66")
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@@ -1,19 +1,33 @@
|
|||||||
package net.momirealms.craftengine.bukkit.plugin.network.handler;
|
package net.momirealms.craftengine.bukkit.plugin.network.handler;
|
||||||
|
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.momirealms.craftengine.bukkit.entity.data.ItemEntityData;
|
||||||
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.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.ComponentUtils;
|
||||||
import net.momirealms.craftengine.bukkit.util.EntityDataUtils;
|
import net.momirealms.craftengine.bukkit.util.EntityDataUtils;
|
||||||
import net.momirealms.craftengine.core.entity.player.Player;
|
import net.momirealms.craftengine.core.entity.player.Player;
|
||||||
|
import net.momirealms.craftengine.core.item.CustomItem;
|
||||||
|
import net.momirealms.craftengine.core.item.Item;
|
||||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||||
import net.momirealms.craftengine.core.plugin.config.Config;
|
import net.momirealms.craftengine.core.plugin.config.Config;
|
||||||
|
import net.momirealms.craftengine.core.plugin.context.ContextHolder;
|
||||||
|
import net.momirealms.craftengine.core.plugin.context.NetworkTextReplaceContext;
|
||||||
|
import net.momirealms.craftengine.core.plugin.context.PlayerOptionalContext;
|
||||||
|
import net.momirealms.craftengine.core.plugin.context.parameter.DirectContextParameters;
|
||||||
import net.momirealms.craftengine.core.plugin.network.ByteBufPacketEvent;
|
import net.momirealms.craftengine.core.plugin.network.ByteBufPacketEvent;
|
||||||
import net.momirealms.craftengine.core.plugin.network.EntityPacketHandler;
|
import net.momirealms.craftengine.core.plugin.network.EntityPacketHandler;
|
||||||
|
import net.momirealms.craftengine.core.plugin.text.component.ComponentProvider;
|
||||||
|
import net.momirealms.craftengine.core.plugin.text.minimessage.CustomTagResolver;
|
||||||
|
import net.momirealms.craftengine.core.util.AdventureHelper;
|
||||||
|
import net.momirealms.craftengine.core.util.ArrayUtils;
|
||||||
import net.momirealms.craftengine.core.util.FriendlyByteBuf;
|
import net.momirealms.craftengine.core.util.FriendlyByteBuf;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public class CommonItemPacketHandler implements EntityPacketHandler {
|
public class CommonItemPacketHandler implements EntityPacketHandler {
|
||||||
@@ -27,11 +41,14 @@ public class CommonItemPacketHandler implements EntityPacketHandler {
|
|||||||
int id = buf.readVarInt();
|
int id = buf.readVarInt();
|
||||||
boolean changed = false;
|
boolean changed = false;
|
||||||
List<Object> packedItems = FastNMS.INSTANCE.method$ClientboundSetEntityDataPacket$unpack(buf);
|
List<Object> packedItems = FastNMS.INSTANCE.method$ClientboundSetEntityDataPacket$unpack(buf);
|
||||||
|
Component nameToShow = null;
|
||||||
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.UNSAFE_ITEM_DATA_ID) continue;
|
if (entityDataId != EntityDataUtils.UNSAFE_ITEM_DATA_ID) continue;
|
||||||
Object nmsItemStack = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$value(packedItem);
|
Object nmsItemStack = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$value(packedItem);
|
||||||
|
|
||||||
|
// 可能是其他插件导致的问题
|
||||||
if (!CoreReflections.clazz$ItemStack.isInstance(nmsItemStack)) {
|
if (!CoreReflections.clazz$ItemStack.isInstance(nmsItemStack)) {
|
||||||
long time = System.currentTimeMillis();
|
long time = System.currentTimeMillis();
|
||||||
if (time - lastWarningTime > 5000) {
|
if (time - lastWarningTime > 5000) {
|
||||||
@@ -42,15 +59,64 @@ public class CommonItemPacketHandler implements EntityPacketHandler {
|
|||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 处理 drop-display 物品设置
|
||||||
ItemStack itemStack = FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(nmsItemStack);
|
ItemStack itemStack = FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(nmsItemStack);
|
||||||
|
Item<ItemStack> wrappedItem = BukkitItemManager.instance().wrap(itemStack);
|
||||||
|
Optional<CustomItem<ItemStack>> optionalCustomItem = wrappedItem.getCustomItem();
|
||||||
|
String showName = null;
|
||||||
|
if (optionalCustomItem.isPresent()) {
|
||||||
|
showName = optionalCustomItem.get().settings().dropDisplay();
|
||||||
|
} else if (Config.enableDefaultDropDisplay()) {
|
||||||
|
showName = Config.defaultDropDisplayFormat();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果设定了自定义展示名
|
||||||
|
if (showName != null) {
|
||||||
|
PlayerOptionalContext context = NetworkTextReplaceContext.of(user, ContextHolder.builder()
|
||||||
|
.withParameter(DirectContextParameters.COUNT, itemStack.getAmount()));
|
||||||
|
Optional<Component> optionalHoverComponent = wrappedItem.hoverNameComponent();
|
||||||
|
Component hoverComponent;
|
||||||
|
if (optionalHoverComponent.isPresent()) {
|
||||||
|
Map<String, ComponentProvider> tokens = CraftEngine.instance().fontManager().matchTags(AdventureHelper.componentToNbt(optionalHoverComponent.get()));
|
||||||
|
if (tokens.isEmpty()) {
|
||||||
|
hoverComponent = optionalHoverComponent.get();
|
||||||
|
} else {
|
||||||
|
hoverComponent = AdventureHelper.replaceText(optionalHoverComponent.get(), tokens, context);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
hoverComponent = Component.translatable(itemStack.translationKey());
|
||||||
|
}
|
||||||
|
// 展示名称为空,则显示其hover name
|
||||||
|
if (showName.isEmpty()) {
|
||||||
|
nameToShow = hoverComponent;
|
||||||
|
}
|
||||||
|
// 显示自定义格式的名字
|
||||||
|
else {
|
||||||
|
nameToShow = AdventureHelper.miniMessage().deserialize(
|
||||||
|
showName,
|
||||||
|
ArrayUtils.appendElementToArrayTail(context.tagResolvers(), new CustomTagResolver("name", hoverComponent))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 转换为客户端侧物品
|
||||||
Optional<ItemStack> optional = BukkitItemManager.instance().s2c(itemStack, user);
|
Optional<ItemStack> optional = BukkitItemManager.instance().s2c(itemStack, user);
|
||||||
if (optional.isEmpty()) continue;
|
if (optional.isEmpty()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
changed = true;
|
changed = true;
|
||||||
itemStack = optional.get();
|
itemStack = optional.get();
|
||||||
Object serializer = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$serializer(packedItem);
|
Object serializer = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$serializer(packedItem);
|
||||||
packedItems.set(i, FastNMS.INSTANCE.constructor$SynchedEntityData$DataValue(entityDataId, serializer, FastNMS.INSTANCE.method$CraftItemStack$asNMSCopy(itemStack)));
|
packedItems.set(i, FastNMS.INSTANCE.constructor$SynchedEntityData$DataValue(entityDataId, serializer, FastNMS.INSTANCE.method$CraftItemStack$asNMSCopy(itemStack)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// 添加自定义显示名
|
||||||
|
if (nameToShow != null) {
|
||||||
|
changed = true;
|
||||||
|
packedItems.add(ItemEntityData.CustomNameVisible.createEntityData(true));
|
||||||
|
packedItems.add(ItemEntityData.CustomName.createEntityData(Optional.of(ComponentUtils.adventureToMinecraft(nameToShow))));
|
||||||
|
}
|
||||||
if (changed) {
|
if (changed) {
|
||||||
event.setChanged(true);
|
event.setChanged(true);
|
||||||
buf.clear();
|
buf.clear();
|
||||||
|
|||||||
@@ -250,6 +250,10 @@ item:
|
|||||||
default: 10000
|
default: 10000
|
||||||
overrides:
|
overrides:
|
||||||
paper: 20000
|
paper: 20000
|
||||||
|
# Toggle whether to display the names of dropped items by default and configure the display format. This setting can be overridden for individual items.
|
||||||
|
default-drop-display:
|
||||||
|
enable: false
|
||||||
|
format: "<arg:count>x <name>"
|
||||||
|
|
||||||
equipment:
|
equipment:
|
||||||
# The sacrificed-vanilla-armor argument determines which vanilla armor gets completely removed (loses all its trims)
|
# The sacrificed-vanilla-armor argument determines which vanilla armor gets completely removed (loses all its trims)
|
||||||
|
|||||||
@@ -49,6 +49,10 @@ public class ItemSettings {
|
|||||||
Color fireworkColor;
|
Color fireworkColor;
|
||||||
float keepOnDeathChance = 0f;
|
float keepOnDeathChance = 0f;
|
||||||
float destroyOnDeathChance = 0f;
|
float destroyOnDeathChance = 0f;
|
||||||
|
@Nullable
|
||||||
|
String dropDisplay = Config.defaultDropDisplayFormat();
|
||||||
|
@Nullable
|
||||||
|
LegacyChatFormatter glowColor = null;
|
||||||
Map<CustomDataType<?>, Object> customData = new IdentityHashMap<>(4);
|
Map<CustomDataType<?>, Object> customData = new IdentityHashMap<>(4);
|
||||||
|
|
||||||
private ItemSettings() {}
|
private ItemSettings() {}
|
||||||
@@ -113,6 +117,8 @@ public class ItemSettings {
|
|||||||
newSettings.ingredientSubstitutes = settings.ingredientSubstitutes;
|
newSettings.ingredientSubstitutes = settings.ingredientSubstitutes;
|
||||||
newSettings.keepOnDeathChance = settings.keepOnDeathChance;
|
newSettings.keepOnDeathChance = settings.keepOnDeathChance;
|
||||||
newSettings.destroyOnDeathChance = settings.destroyOnDeathChance;
|
newSettings.destroyOnDeathChance = settings.destroyOnDeathChance;
|
||||||
|
newSettings.glowColor = settings.glowColor;
|
||||||
|
newSettings.dropDisplay = settings.dropDisplay;
|
||||||
newSettings.customData = new IdentityHashMap<>(settings.customData);
|
newSettings.customData = new IdentityHashMap<>(settings.customData);
|
||||||
return newSettings;
|
return newSettings;
|
||||||
}
|
}
|
||||||
@@ -243,6 +249,16 @@ public class ItemSettings {
|
|||||||
return this.destroyOnDeathChance;
|
return this.destroyOnDeathChance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public LegacyChatFormatter glowColor() {
|
||||||
|
return this.glowColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public String dropDisplay() {
|
||||||
|
return this.dropDisplay;
|
||||||
|
}
|
||||||
|
|
||||||
public ItemSettings fireworkColor(Color color) {
|
public ItemSettings fireworkColor(Color color) {
|
||||||
this.fireworkColor = color;
|
this.fireworkColor = color;
|
||||||
return this;
|
return this;
|
||||||
@@ -293,6 +309,11 @@ public class ItemSettings {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ItemSettings dropDisplay(String showName) {
|
||||||
|
this.dropDisplay = showName;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public ItemSettings projectileMeta(ProjectileMeta projectileMeta) {
|
public ItemSettings projectileMeta(ProjectileMeta projectileMeta) {
|
||||||
this.projectileMeta = projectileMeta;
|
this.projectileMeta = projectileMeta;
|
||||||
return this;
|
return this;
|
||||||
@@ -353,6 +374,11 @@ public class ItemSettings {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ItemSettings glowColor(LegacyChatFormatter chatFormatter) {
|
||||||
|
this.glowColor = chatFormatter;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface Modifier {
|
public interface Modifier {
|
||||||
|
|
||||||
@@ -395,6 +421,18 @@ public class ItemSettings {
|
|||||||
boolean bool = ResourceConfigUtils.getAsBoolean(value, "renameable");
|
boolean bool = ResourceConfigUtils.getAsBoolean(value, "renameable");
|
||||||
return settings -> settings.renameable(bool);
|
return settings -> settings.renameable(bool);
|
||||||
}));
|
}));
|
||||||
|
registerFactory("drop-display", (value -> {
|
||||||
|
if (value instanceof String name) {
|
||||||
|
return settings -> settings.dropDisplay(name);
|
||||||
|
} else {
|
||||||
|
boolean bool = ResourceConfigUtils.getAsBoolean(value, "drop-display");
|
||||||
|
return settings -> settings.dropDisplay(bool ? "" : null);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
registerFactory("glow-color", (value -> {
|
||||||
|
LegacyChatFormatter chatFormatter = ResourceConfigUtils.getAsEnum(value, LegacyChatFormatter.class, LegacyChatFormatter.WHITE);
|
||||||
|
return settings -> settings.glowColor(chatFormatter);
|
||||||
|
}));
|
||||||
registerFactory("anvil-repair-item", (value -> {
|
registerFactory("anvil-repair-item", (value -> {
|
||||||
List<AnvilRepairItem> anvilRepairItemList = ResourceConfigUtils.parseConfigAsList(value, material -> {
|
List<AnvilRepairItem> anvilRepairItemList = ResourceConfigUtils.parseConfigAsList(value, material -> {
|
||||||
int amount = ResourceConfigUtils.getAsInt(material.getOrDefault("amount", 0), "amount");
|
int amount = ResourceConfigUtils.getAsInt(material.getOrDefault("amount", 0), "amount");
|
||||||
|
|||||||
@@ -193,6 +193,8 @@ public class Config {
|
|||||||
protected Map<Key, Integer> item$custom_model_data_starting_value$overrides;
|
protected Map<Key, Integer> item$custom_model_data_starting_value$overrides;
|
||||||
protected boolean item$always_use_item_model;
|
protected boolean item$always_use_item_model;
|
||||||
protected String item$default_material = "";
|
protected String item$default_material = "";
|
||||||
|
protected boolean item$default_drop_display$enable = false;
|
||||||
|
protected String item$default_drop_display$format = null;
|
||||||
|
|
||||||
protected String equipment$sacrificed_vanilla_armor$type;
|
protected String equipment$sacrificed_vanilla_armor$type;
|
||||||
protected Key equipment$sacrificed_vanilla_armor$asset_id;
|
protected Key equipment$sacrificed_vanilla_armor$asset_id;
|
||||||
@@ -471,6 +473,8 @@ public class Config {
|
|||||||
item$custom_model_data_starting_value$default = config.getInt("item.custom-model-data-starting-value.default", 10000);
|
item$custom_model_data_starting_value$default = config.getInt("item.custom-model-data-starting-value.default", 10000);
|
||||||
item$always_use_item_model = config.getBoolean("item.always-use-item-model", true) && VersionHelper.isOrAbove1_21_2();
|
item$always_use_item_model = config.getBoolean("item.always-use-item-model", true) && VersionHelper.isOrAbove1_21_2();
|
||||||
item$default_material = config.getString("item.default-material", "");
|
item$default_material = config.getString("item.default-material", "");
|
||||||
|
item$default_drop_display$enable = config.getBoolean("item.default-drop-display.enable", false);
|
||||||
|
item$default_drop_display$format = item$default_drop_display$enable ? config.getString("item.default-drop-display.format", "<arg:count>x <name>"): null;
|
||||||
|
|
||||||
Section customModelDataOverridesSection = config.getSection("item.custom-model-data-starting-value.overrides");
|
Section customModelDataOverridesSection = config.getSection("item.custom-model-data-starting-value.overrides");
|
||||||
if (customModelDataOverridesSection != null) {
|
if (customModelDataOverridesSection != null) {
|
||||||
@@ -1175,6 +1179,14 @@ public class Config {
|
|||||||
return instance.resource_pack$optimization$texture$zopfli_iterations;
|
return instance.resource_pack$optimization$texture$zopfli_iterations;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean enableDefaultDropDisplay() {
|
||||||
|
return instance.item$default_drop_display$enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String defaultDropDisplayFormat() {
|
||||||
|
return instance.item$default_drop_display$format;
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean enableEntityCulling() {
|
public static boolean enableEntityCulling() {
|
||||||
return instance.client_optimization$entity_culling$enable;
|
return instance.client_optimization$entity_culling$enable;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package net.momirealms.craftengine.core.plugin.text.minimessage;
|
||||||
|
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.minimessage.Context;
|
||||||
|
import net.kyori.adventure.text.minimessage.ParsingException;
|
||||||
|
import net.kyori.adventure.text.minimessage.tag.Tag;
|
||||||
|
import net.kyori.adventure.text.minimessage.tag.resolver.ArgumentQueue;
|
||||||
|
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
public class CustomTagResolver implements TagResolver {
|
||||||
|
private final String name;
|
||||||
|
private final Component replacement;
|
||||||
|
|
||||||
|
public CustomTagResolver(String name, Component replacement) {
|
||||||
|
this.name = name;
|
||||||
|
this.replacement = replacement;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public Tag resolve(@NotNull String name, @NotNull ArgumentQueue arguments, @NotNull Context ctx) throws ParsingException {
|
||||||
|
if (!has(name)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return Tag.selfClosingInserting(this.replacement);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean has(@NotNull String name) {
|
||||||
|
return this.name.equals(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package net.momirealms.craftengine.core.util;
|
||||||
|
|
||||||
|
public enum LegacyChatFormatter {
|
||||||
|
BLACK,
|
||||||
|
DARK_BLUE,
|
||||||
|
DARK_GREEN,
|
||||||
|
DARK_AQUA,
|
||||||
|
DARK_RED,
|
||||||
|
DARK_PURPLE,
|
||||||
|
GOLD,
|
||||||
|
GRAY,
|
||||||
|
DARK_GRAY,
|
||||||
|
BLUE,
|
||||||
|
GREEN,
|
||||||
|
AQUA,
|
||||||
|
RED,
|
||||||
|
LIGHT_PURPLE,
|
||||||
|
YELLOW,
|
||||||
|
WHITE,
|
||||||
|
OBFUSCATED,
|
||||||
|
BOLD,
|
||||||
|
STRIKETHROUGH,
|
||||||
|
UNDERLINE,
|
||||||
|
ITALIC,
|
||||||
|
RESET;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user