mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-20 07:29:17 +00:00
物品映射重构1
This commit is contained in:
@@ -54,11 +54,15 @@ public class BukkitCustomItem extends AbstractCustomItem<ItemStack> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Object clientItem() {
|
public Object clientItem() {
|
||||||
return clientItem;
|
return this.clientItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object item() {
|
public Object item() {
|
||||||
return item;
|
return this.item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasClientboundMaterial() {
|
||||||
|
return this.clientItem != this.item;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Builder<ItemStack> builder(Object item, Object clientBoundItem) {
|
public static Builder<ItemStack> builder(Object item, Object clientBoundItem) {
|
||||||
|
|||||||
@@ -125,23 +125,23 @@ public class BukkitItemManager extends AbstractItemManager<ItemStack> {
|
|||||||
@Override
|
@Override
|
||||||
public Item<ItemStack> s2c(Item<ItemStack> item, Player player) {
|
public Item<ItemStack> s2c(Item<ItemStack> item, Player player) {
|
||||||
if (item.isEmpty()) return item;
|
if (item.isEmpty()) return item;
|
||||||
return this.networkItemHandler.s2c(item, player);
|
return this.networkItemHandler.s2c(item, player).orElse(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Item<ItemStack> c2s(Item<ItemStack> item) {
|
public Item<ItemStack> c2s(Item<ItemStack> item) {
|
||||||
if (item.isEmpty()) return item;
|
if (item.isEmpty()) return item;
|
||||||
return this.networkItemHandler.c2s(item);
|
return this.networkItemHandler.c2s(item).orElse(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemStack s2c(ItemStack item, Player player) {
|
public Optional<ItemStack> s2c(ItemStack item, Player player) {
|
||||||
if (item.isEmpty()) return item;
|
if (item.isEmpty()) return Optional.empty();
|
||||||
return s2c(wrap(item), player).getItem();
|
return this.networkItemHandler.s2c(wrap(item), player).map(Item::getItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemStack c2s(ItemStack item) {
|
public Optional<ItemStack> c2s(ItemStack item) {
|
||||||
if (item.isEmpty()) return item;
|
if (item.isEmpty()) return Optional.empty();
|
||||||
return c2s(wrap(item)).getItem();
|
return this.networkItemHandler.c2s(wrap(item)).map(Item::getItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -23,6 +23,11 @@ public class ComponentItemWrapper implements ItemWrapper<ItemStack> {
|
|||||||
private final ItemStack item;
|
private final ItemStack item;
|
||||||
private final Object handle;
|
private final Object handle;
|
||||||
|
|
||||||
|
public ComponentItemWrapper(final Object handle) {
|
||||||
|
this.handle = handle;
|
||||||
|
this.item = FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(handle);
|
||||||
|
}
|
||||||
|
|
||||||
public ComponentItemWrapper(final ItemStack item) {
|
public ComponentItemWrapper(final ItemStack item) {
|
||||||
this.item = ItemStackUtils.ensureCraftItemStack(item);
|
this.item = ItemStackUtils.ensureCraftItemStack(item);
|
||||||
this.handle = FastNMS.INSTANCE.field$CraftItemStack$handle(this.item);
|
this.handle = FastNMS.INSTANCE.field$CraftItemStack$handle(this.item);
|
||||||
|
|||||||
@@ -32,54 +32,70 @@ import java.util.function.BiConsumer;
|
|||||||
public final class LegacyNetworkItemHandler implements NetworkItemHandler<ItemStack> {
|
public final class LegacyNetworkItemHandler implements NetworkItemHandler<ItemStack> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Item<ItemStack> c2s(Item<ItemStack> wrapped) {
|
public Optional<Item<ItemStack>> c2s(Item<ItemStack> wrapped) {
|
||||||
|
boolean forceReturn = false;
|
||||||
|
|
||||||
Optional<CustomItem<ItemStack>> optionalCustomItem = wrapped.getCustomItem();
|
Optional<CustomItem<ItemStack>> optionalCustomItem = wrapped.getCustomItem();
|
||||||
if (optionalCustomItem.isPresent()) {
|
if (optionalCustomItem.isPresent()) {
|
||||||
BukkitCustomItem customItem = (BukkitCustomItem) optionalCustomItem.get();
|
BukkitCustomItem customItem = (BukkitCustomItem) optionalCustomItem.get();
|
||||||
if (customItem.item() != FastNMS.INSTANCE.method$ItemStack$getItem(wrapped.getLiteralObject())) {
|
if (customItem.item() != FastNMS.INSTANCE.method$ItemStack$getItem(wrapped.getLiteralObject())) {
|
||||||
wrapped = wrapped.unsafeTransmuteCopy(customItem.item(), wrapped.count());
|
wrapped = wrapped.unsafeTransmuteCopy(customItem.item(), wrapped.count());
|
||||||
|
forceReturn = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CompoundTag networkData = (CompoundTag) wrapped.getTag(NETWORK_ITEM_TAG);
|
CompoundTag networkData = (CompoundTag) wrapped.getTag(NETWORK_ITEM_TAG);
|
||||||
if (networkData == null) return wrapped;
|
if (networkData != null) {
|
||||||
wrapped.removeTag(NETWORK_ITEM_TAG);
|
forceReturn = true;
|
||||||
for (Map.Entry<String, Tag> entry : networkData.entrySet()) {
|
// 移除tag
|
||||||
if (entry.getValue() instanceof CompoundTag tag) {
|
wrapped.removeTag(NETWORK_ITEM_TAG);
|
||||||
NetworkItemHandler.apply(entry.getKey(), tag, wrapped);
|
// 恢复物品
|
||||||
|
for (Map.Entry<String, Tag> entry : networkData.entrySet()) {
|
||||||
|
if (entry.getValue() instanceof CompoundTag tag) {
|
||||||
|
NetworkItemHandler.apply(entry.getKey(), tag, wrapped);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return wrapped;
|
|
||||||
|
return forceReturn ? Optional.empty() : Optional.of(wrapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Item<ItemStack> s2c(Item<ItemStack> wrapped, Player player) {
|
public Optional<Item<ItemStack>> s2c(Item<ItemStack> wrapped, Player player) {
|
||||||
// todo 处理bundle和container
|
boolean forceReturn = false;
|
||||||
|
// todo 处理bundle
|
||||||
|
|
||||||
|
// todo 处理container
|
||||||
|
|
||||||
// todo 处理book
|
// todo 处理book
|
||||||
|
|
||||||
Optional<CustomItem<ItemStack>> optionalCustomItem = wrapped.getCustomItem();
|
Optional<CustomItem<ItemStack>> optionalCustomItem = wrapped.getCustomItem();
|
||||||
// 不是自定义物品或修改过的原版物品
|
// 不是自定义物品或修改过的原版物品
|
||||||
if (optionalCustomItem.isEmpty()) {
|
if (optionalCustomItem.isEmpty()) {
|
||||||
if (!Config.interceptItem()) return wrapped;
|
if (!Config.interceptItem()) {
|
||||||
return new OtherItem(wrapped).process(NetworkTextReplaceContext.of(player));
|
return forceReturn ? Optional.of(wrapped) : Optional.empty();
|
||||||
|
}
|
||||||
|
return new OtherItem(wrapped, forceReturn).process(NetworkTextReplaceContext.of(player));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 应用client-bound-material
|
// 应用 client-bound-material
|
||||||
BukkitCustomItem customItem = (BukkitCustomItem) optionalCustomItem.get();
|
BukkitCustomItem customItem = (BukkitCustomItem) optionalCustomItem.get();
|
||||||
Object serverItem = FastNMS.INSTANCE.method$ItemStack$getItem(wrapped.getLiteralObject());
|
if (customItem.hasClientboundMaterial() && FastNMS.INSTANCE.method$ItemStack$getItem(wrapped.getLiteralObject()) != customItem.clientItem()) {
|
||||||
boolean hasDifferentMaterial = serverItem == customItem.item() && serverItem != customItem.clientItem();
|
|
||||||
if (hasDifferentMaterial) {
|
|
||||||
wrapped = wrapped.unsafeTransmuteCopy(customItem.clientItem(), wrapped.count());
|
wrapped = wrapped.unsafeTransmuteCopy(customItem.clientItem(), wrapped.count());
|
||||||
|
forceReturn = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 没有客户端侧组件
|
// 没有客户端侧组件
|
||||||
if (!customItem.hasClientBoundDataModifier()) {
|
if (!customItem.hasClientBoundDataModifier()) {
|
||||||
if (!Config.interceptItem()) return wrapped;
|
if (!Config.interceptItem()) {
|
||||||
return new OtherItem(wrapped).process(NetworkTextReplaceContext.of(player));
|
return forceReturn ? Optional.of(wrapped) : Optional.empty();
|
||||||
|
}
|
||||||
|
return new OtherItem(wrapped, forceReturn).process(NetworkTextReplaceContext.of(player));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 应用client-bound-data
|
// 应用client-bound-data
|
||||||
CompoundTag tag = new CompoundTag();
|
CompoundTag tag = new CompoundTag();
|
||||||
|
// 创建context
|
||||||
Tag argumentTag = wrapped.getTag(ArgumentsModifier.ARGUMENTS_TAG);
|
Tag argumentTag = wrapped.getTag(ArgumentsModifier.ARGUMENTS_TAG);
|
||||||
ItemBuildContext context;
|
ItemBuildContext context;
|
||||||
if (argumentTag instanceof CompoundTag arguments) {
|
if (argumentTag instanceof CompoundTag arguments) {
|
||||||
@@ -91,12 +107,15 @@ public final class LegacyNetworkItemHandler implements NetworkItemHandler<ItemSt
|
|||||||
} else {
|
} else {
|
||||||
context = ItemBuildContext.of(player);
|
context = ItemBuildContext.of(player);
|
||||||
}
|
}
|
||||||
|
// 准备阶段
|
||||||
for (ItemDataModifier<ItemStack> modifier : customItem.clientBoundDataModifiers()) {
|
for (ItemDataModifier<ItemStack> modifier : customItem.clientBoundDataModifiers()) {
|
||||||
modifier.prepareNetworkItem(wrapped, context, tag);
|
modifier.prepareNetworkItem(wrapped, context, tag);
|
||||||
}
|
}
|
||||||
|
// 应用阶段
|
||||||
for (ItemDataModifier<ItemStack> modifier : customItem.clientBoundDataModifiers()) {
|
for (ItemDataModifier<ItemStack> modifier : customItem.clientBoundDataModifiers()) {
|
||||||
modifier.apply(wrapped, context);
|
modifier.apply(wrapped, context);
|
||||||
}
|
}
|
||||||
|
// 如果拦截物品的描述名称等
|
||||||
if (Config.interceptItem()) {
|
if (Config.interceptItem()) {
|
||||||
if (!tag.containsKey("display.Name")) {
|
if (!tag.containsKey("display.Name")) {
|
||||||
processCustomName(wrapped, tag::put, context);
|
processCustomName(wrapped, tag::put, context);
|
||||||
@@ -105,10 +124,12 @@ public final class LegacyNetworkItemHandler implements NetworkItemHandler<ItemSt
|
|||||||
processLore(wrapped, tag::put, context);
|
processLore(wrapped, tag::put, context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 如果tag不空,则需要返回
|
||||||
if (!tag.isEmpty()) {
|
if (!tag.isEmpty()) {
|
||||||
wrapped.setTag(tag, NETWORK_ITEM_TAG);
|
wrapped.setTag(tag, NETWORK_ITEM_TAG);
|
||||||
|
forceReturn = true;
|
||||||
}
|
}
|
||||||
return wrapped;
|
return forceReturn ? Optional.of(wrapped) : Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean processCustomName(Item<ItemStack> item, BiConsumer<String, CompoundTag> callback, Context context) {
|
public static boolean processCustomName(Item<ItemStack> item, BiConsumer<String, CompoundTag> callback, Context context) {
|
||||||
@@ -157,12 +178,14 @@ public final class LegacyNetworkItemHandler implements NetworkItemHandler<ItemSt
|
|||||||
private final Item<ItemStack> item;
|
private final Item<ItemStack> item;
|
||||||
private boolean globalChanged = false;
|
private boolean globalChanged = false;
|
||||||
private CompoundTag networkTag;
|
private CompoundTag networkTag;
|
||||||
|
private final boolean forceReturn;
|
||||||
|
|
||||||
public OtherItem(Item<ItemStack> item) {
|
public OtherItem(Item<ItemStack> item, boolean forceReturn) {
|
||||||
this.item = item;
|
this.item = item;
|
||||||
|
this.forceReturn = forceReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Item<ItemStack> process(Context context) {
|
public Optional<Item<ItemStack>> process(Context context) {
|
||||||
if (processLore(this.item, (s, c) -> networkTag().put(s, c), context)) {
|
if (processLore(this.item, (s, c) -> networkTag().put(s, c), context)) {
|
||||||
this.globalChanged = true;
|
this.globalChanged = true;
|
||||||
}
|
}
|
||||||
@@ -171,8 +194,12 @@ public final class LegacyNetworkItemHandler implements NetworkItemHandler<ItemSt
|
|||||||
}
|
}
|
||||||
if (this.globalChanged) {
|
if (this.globalChanged) {
|
||||||
this.item.setTag(this.networkTag, NETWORK_ITEM_TAG);
|
this.item.setTag(this.networkTag, NETWORK_ITEM_TAG);
|
||||||
|
return Optional.of(this.item);
|
||||||
|
} else if (this.forceReturn) {
|
||||||
|
return Optional.of(this.item);
|
||||||
|
} else {
|
||||||
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
return this.item;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompoundTag networkTag() {
|
public CompoundTag networkTag() {
|
||||||
|
|||||||
@@ -30,25 +30,47 @@ import java.util.function.Supplier;
|
|||||||
public final class ModernNetworkItemHandler implements NetworkItemHandler<ItemStack> {
|
public final class ModernNetworkItemHandler implements NetworkItemHandler<ItemStack> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Item<ItemStack> c2s(Item<ItemStack> wrapped) {
|
public Optional<Item<ItemStack>> c2s(Item<ItemStack> wrapped) {
|
||||||
|
boolean forceReturn = false;
|
||||||
|
|
||||||
|
// 处理收纳袋
|
||||||
if (wrapped.hasComponent(ComponentTypes.BUNDLE_CONTENTS)) {
|
if (wrapped.hasComponent(ComponentTypes.BUNDLE_CONTENTS)) {
|
||||||
Object bundleContents = wrapped.getExactComponent(ComponentTypes.BUNDLE_CONTENTS);
|
Object bundleContents = wrapped.getExactComponent(ComponentTypes.BUNDLE_CONTENTS);
|
||||||
List<Object> newItems = new ArrayList<>();
|
List<Object> newItems = new ArrayList<>();
|
||||||
|
boolean changed = false;
|
||||||
for (Object previousItem : FastNMS.INSTANCE.method$BundleContents$items(bundleContents)) {
|
for (Object previousItem : FastNMS.INSTANCE.method$BundleContents$items(bundleContents)) {
|
||||||
ItemStack itemStack = BukkitItemManager.instance().c2s(FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(previousItem));
|
Optional<ItemStack> itemStack = BukkitItemManager.instance().c2s(FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(previousItem));
|
||||||
newItems.add(FastNMS.INSTANCE.field$CraftItemStack$handle(itemStack));
|
if (itemStack.isPresent()) {
|
||||||
|
newItems.add(FastNMS.INSTANCE.field$CraftItemStack$handle(itemStack.get()));
|
||||||
|
changed = true;
|
||||||
|
} else {
|
||||||
|
newItems.add(previousItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (changed) {
|
||||||
|
wrapped.setExactComponent(ComponentTypes.BUNDLE_CONTENTS, FastNMS.INSTANCE.constructor$BundleContents(newItems));
|
||||||
|
forceReturn = true;
|
||||||
}
|
}
|
||||||
wrapped.setExactComponent(ComponentTypes.BUNDLE_CONTENTS, FastNMS.INSTANCE.constructor$BundleContents(newItems));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 处理潜影盒等
|
||||||
if (wrapped.hasComponent(ComponentTypes.CONTAINER)) {
|
if (wrapped.hasComponent(ComponentTypes.CONTAINER)) {
|
||||||
Object containerContents = wrapped.getExactComponent(ComponentTypes.CONTAINER);
|
Object containerContents = wrapped.getExactComponent(ComponentTypes.CONTAINER);
|
||||||
List<Object> newItems = new ArrayList<>();
|
List<Object> newItems = new ArrayList<>();
|
||||||
|
boolean changed = false;
|
||||||
for (Object previousItem : FastNMS.INSTANCE.field$ItemContainerContents$items(containerContents)) {
|
for (Object previousItem : FastNMS.INSTANCE.field$ItemContainerContents$items(containerContents)) {
|
||||||
ItemStack itemStack = BukkitItemManager.instance().c2s(FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(previousItem));
|
Optional<ItemStack> itemStack = BukkitItemManager.instance().c2s(FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(previousItem));
|
||||||
newItems.add(FastNMS.INSTANCE.field$CraftItemStack$handle(itemStack));
|
if (itemStack.isPresent()) {
|
||||||
|
newItems.add(FastNMS.INSTANCE.field$CraftItemStack$handle(itemStack.get()));
|
||||||
|
changed = true;
|
||||||
|
} else {
|
||||||
|
newItems.add(previousItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (changed) {
|
||||||
|
wrapped.setExactComponent(ComponentTypes.CONTAINER, FastNMS.INSTANCE.method$ItemContainerContents$fromItems(newItems));
|
||||||
|
forceReturn = true;
|
||||||
}
|
}
|
||||||
wrapped.setExactComponent(ComponentTypes.CONTAINER, FastNMS.INSTANCE.method$ItemContainerContents$fromItems(newItems));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 先尝试恢复client-bound-material
|
// 先尝试恢复client-bound-material
|
||||||
@@ -57,79 +79,112 @@ public final class ModernNetworkItemHandler implements NetworkItemHandler<ItemSt
|
|||||||
BukkitCustomItem customItem = (BukkitCustomItem) optionalCustomItem.get();
|
BukkitCustomItem customItem = (BukkitCustomItem) optionalCustomItem.get();
|
||||||
if (customItem.item() != FastNMS.INSTANCE.method$ItemStack$getItem(wrapped.getLiteralObject())) {
|
if (customItem.item() != FastNMS.INSTANCE.method$ItemStack$getItem(wrapped.getLiteralObject())) {
|
||||||
wrapped = wrapped.unsafeTransmuteCopy(customItem.item(), wrapped.count());
|
wrapped = wrapped.unsafeTransmuteCopy(customItem.item(), wrapped.count());
|
||||||
|
forceReturn = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 没有 custom data 则忽略
|
// 获取custom data
|
||||||
Tag customData = wrapped.getSparrowNBTComponent(ComponentTypes.CUSTOM_DATA);
|
Tag customData = wrapped.getSparrowNBTComponent(ComponentTypes.CUSTOM_DATA);
|
||||||
if (!(customData instanceof CompoundTag compoundTag)) {
|
if (customData instanceof CompoundTag compoundTag) {
|
||||||
return wrapped;
|
CompoundTag networkData = compoundTag.getCompound(NETWORK_ITEM_TAG);
|
||||||
}
|
if (networkData != null) {
|
||||||
|
forceReturn = true;
|
||||||
|
// 移除此tag
|
||||||
|
compoundTag.remove(NETWORK_ITEM_TAG);
|
||||||
|
|
||||||
// 未曾应用过 client-bound-data
|
// 恢复物品
|
||||||
CompoundTag networkData = compoundTag.getCompound(NETWORK_ITEM_TAG);
|
for (Map.Entry<String, Tag> entry : networkData.entrySet()) {
|
||||||
if (networkData == null) {
|
if (entry.getValue() instanceof CompoundTag tag) {
|
||||||
return wrapped;
|
NetworkItemHandler.apply(entry.getKey(), tag, wrapped);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 移除此tag
|
// 如果清空了,则直接移除这个组件
|
||||||
compoundTag.remove(NETWORK_ITEM_TAG);
|
if (compoundTag.isEmpty()) wrapped.resetComponent(ComponentTypes.CUSTOM_DATA);
|
||||||
for (Map.Entry<String, Tag> entry : networkData.entrySet()) {
|
// 否则设置为新的
|
||||||
if (entry.getValue() instanceof CompoundTag tag) {
|
else wrapped.setNBTComponent(ComponentTypes.CUSTOM_DATA, compoundTag);
|
||||||
NetworkItemHandler.apply(entry.getKey(), tag, wrapped);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (compoundTag.isEmpty()) wrapped.resetComponent(ComponentTypes.CUSTOM_DATA);
|
return forceReturn ? Optional.of(wrapped) : Optional.empty();
|
||||||
else wrapped.setNBTComponent(ComponentTypes.CUSTOM_DATA, compoundTag);
|
|
||||||
return wrapped;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Item<ItemStack> s2c(Item<ItemStack> wrapped, Player player) {
|
public Optional<Item<ItemStack>> s2c(Item<ItemStack> wrapped, Player player) {
|
||||||
|
boolean forceReturn = false;
|
||||||
|
|
||||||
|
// 处理收纳袋
|
||||||
if (wrapped.hasComponent(ComponentTypes.BUNDLE_CONTENTS)) {
|
if (wrapped.hasComponent(ComponentTypes.BUNDLE_CONTENTS)) {
|
||||||
Object bundleContents = wrapped.getExactComponent(ComponentTypes.BUNDLE_CONTENTS);
|
Object bundleContents = wrapped.getExactComponent(ComponentTypes.BUNDLE_CONTENTS);
|
||||||
List<Object> newItems = new ArrayList<>();
|
List<Object> newItems = new ArrayList<>();
|
||||||
|
boolean changed = false;
|
||||||
for (Object previousItem : FastNMS.INSTANCE.method$BundleContents$items(bundleContents)) {
|
for (Object previousItem : FastNMS.INSTANCE.method$BundleContents$items(bundleContents)) {
|
||||||
ItemStack itemStack = BukkitItemManager.instance().s2c(FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(previousItem), player);
|
Optional<ItemStack> itemStack = BukkitItemManager.instance().s2c(FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(previousItem), player);
|
||||||
newItems.add(FastNMS.INSTANCE.field$CraftItemStack$handle(itemStack));
|
if (itemStack.isPresent()) {
|
||||||
|
newItems.add(FastNMS.INSTANCE.field$CraftItemStack$handle(itemStack.get()));
|
||||||
|
changed = true;
|
||||||
|
} else {
|
||||||
|
newItems.add(previousItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (changed) {
|
||||||
|
wrapped.setExactComponent(ComponentTypes.BUNDLE_CONTENTS, FastNMS.INSTANCE.constructor$BundleContents(newItems));
|
||||||
|
forceReturn = true;
|
||||||
}
|
}
|
||||||
wrapped.setExactComponent(ComponentTypes.BUNDLE_CONTENTS, FastNMS.INSTANCE.constructor$BundleContents(newItems));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 处理潜影盒等
|
||||||
if (wrapped.hasComponent(ComponentTypes.CONTAINER)) {
|
if (wrapped.hasComponent(ComponentTypes.CONTAINER)) {
|
||||||
Object containerContents = wrapped.getExactComponent(ComponentTypes.CONTAINER);
|
Object containerContents = wrapped.getExactComponent(ComponentTypes.CONTAINER);
|
||||||
List<Object> newItems = new ArrayList<>();
|
List<Object> newItems = new ArrayList<>();
|
||||||
for (Object previousItem : FastNMS.INSTANCE.field$ItemContainerContents$items(containerContents)) {
|
for (Object previousItem : FastNMS.INSTANCE.field$ItemContainerContents$items(containerContents)) {
|
||||||
ItemStack itemStack = BukkitItemManager.instance().s2c(FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(previousItem), player);
|
boolean changed = false;
|
||||||
newItems.add(FastNMS.INSTANCE.field$CraftItemStack$handle(itemStack));
|
Optional<ItemStack> itemStack = BukkitItemManager.instance().s2c(FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(previousItem), player);
|
||||||
|
if (itemStack.isPresent()) {
|
||||||
|
newItems.add(FastNMS.INSTANCE.field$CraftItemStack$handle(itemStack.get()));
|
||||||
|
changed = true;
|
||||||
|
} else {
|
||||||
|
newItems.add(previousItem);
|
||||||
|
}
|
||||||
|
if (changed) {
|
||||||
|
wrapped.setExactComponent(ComponentTypes.CONTAINER, FastNMS.INSTANCE.method$ItemContainerContents$fromItems(newItems));
|
||||||
|
forceReturn = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
wrapped.setExactComponent(ComponentTypes.CONTAINER, FastNMS.INSTANCE.method$ItemContainerContents$fromItems(newItems));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo 处理book
|
// todo 处理book
|
||||||
|
|
||||||
// 不是自定义物品或修改过的原版物品
|
// 不是自定义物品或修改过的原版物品
|
||||||
Item<ItemStack> original = wrapped;
|
|
||||||
Optional<CustomItem<ItemStack>> optionalCustomItem = wrapped.getCustomItem();
|
Optional<CustomItem<ItemStack>> optionalCustomItem = wrapped.getCustomItem();
|
||||||
if (optionalCustomItem.isEmpty()) {
|
if (optionalCustomItem.isEmpty()) {
|
||||||
if (!Config.interceptItem()) return wrapped;
|
if (!Config.interceptItem()) {
|
||||||
return new OtherItem(wrapped).process(NetworkTextReplaceContext.of(player));
|
return forceReturn ? Optional.of(wrapped) : Optional.empty();
|
||||||
|
}
|
||||||
|
return new OtherItem(wrapped, forceReturn).process(NetworkTextReplaceContext.of(player));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 应用 client-bound-data
|
|
||||||
BukkitCustomItem customItem = (BukkitCustomItem) optionalCustomItem.get();
|
BukkitCustomItem customItem = (BukkitCustomItem) optionalCustomItem.get();
|
||||||
Object serverItem = FastNMS.INSTANCE.method$ItemStack$getItem(wrapped.getLiteralObject());
|
// 提前复制,这和物品类型相关
|
||||||
boolean hasDifferentMaterial = serverItem == customItem.item() && serverItem != customItem.clientItem();
|
Item<ItemStack> original = wrapped;
|
||||||
if (hasDifferentMaterial) {
|
// 应用 client-bound-material前提是服务端侧物品类型和客户端侧的不同
|
||||||
|
if (customItem.hasClientboundMaterial() && FastNMS.INSTANCE.method$ItemStack$getItem(wrapped.getLiteralObject()) != customItem.clientItem()) {
|
||||||
wrapped = wrapped.unsafeTransmuteCopy(customItem.clientItem(), wrapped.count());
|
wrapped = wrapped.unsafeTransmuteCopy(customItem.clientItem(), wrapped.count());
|
||||||
|
forceReturn = true;
|
||||||
}
|
}
|
||||||
|
// 没有 client-bound-data
|
||||||
if (!customItem.hasClientBoundDataModifier()) {
|
if (!customItem.hasClientBoundDataModifier()) {
|
||||||
if (!Config.interceptItem()) return wrapped;
|
if (!Config.interceptItem()) {
|
||||||
return new OtherItem(wrapped).process(NetworkTextReplaceContext.of(player));
|
return forceReturn ? Optional.of(wrapped) : Optional.empty();
|
||||||
|
}
|
||||||
|
return new OtherItem(wrapped, forceReturn).process(NetworkTextReplaceContext.of(player));
|
||||||
}
|
}
|
||||||
CompoundTag customData = Optional.ofNullable(wrapped.getSparrowNBTComponent(ComponentTypes.CUSTOM_DATA)).map(CompoundTag.class::cast).orElse(new CompoundTag());
|
// 获取custom data
|
||||||
|
CompoundTag customData = Optional.ofNullable(wrapped.getSparrowNBTComponent(ComponentTypes.CUSTOM_DATA))
|
||||||
|
.map(CompoundTag.class::cast)
|
||||||
|
.orElseGet(CompoundTag::new);
|
||||||
CompoundTag arguments = customData.getCompound(ArgumentsModifier.ARGUMENTS_TAG);
|
CompoundTag arguments = customData.getCompound(ArgumentsModifier.ARGUMENTS_TAG);
|
||||||
|
// 创建context
|
||||||
ItemBuildContext context;
|
ItemBuildContext context;
|
||||||
if (arguments == null) {
|
if (arguments == null) {
|
||||||
context = ItemBuildContext.of(player);
|
context = ItemBuildContext.of(player);
|
||||||
@@ -140,13 +195,16 @@ public final class ModernNetworkItemHandler implements NetworkItemHandler<ItemSt
|
|||||||
}
|
}
|
||||||
context = ItemBuildContext.of(player, builder);
|
context = ItemBuildContext.of(player, builder);
|
||||||
}
|
}
|
||||||
|
// 准备阶段
|
||||||
CompoundTag tag = new CompoundTag();
|
CompoundTag tag = new CompoundTag();
|
||||||
for (ItemDataModifier<ItemStack> modifier : customItem.clientBoundDataModifiers()) {
|
for (ItemDataModifier<ItemStack> modifier : customItem.clientBoundDataModifiers()) {
|
||||||
modifier.prepareNetworkItem(original, context, tag);
|
modifier.prepareNetworkItem(original, context, tag);
|
||||||
}
|
}
|
||||||
|
// 应用阶段
|
||||||
for (ItemDataModifier<ItemStack> modifier : customItem.clientBoundDataModifiers()) {
|
for (ItemDataModifier<ItemStack> modifier : customItem.clientBoundDataModifiers()) {
|
||||||
modifier.apply(wrapped, context);
|
modifier.apply(wrapped, context);
|
||||||
}
|
}
|
||||||
|
// 如果拦截物品的描述名称等
|
||||||
if (Config.interceptItem()) {
|
if (Config.interceptItem()) {
|
||||||
if (!tag.containsKey(ComponentIds.ITEM_NAME)) {
|
if (!tag.containsKey(ComponentIds.ITEM_NAME)) {
|
||||||
if (VersionHelper.isOrAbove1_21_5()) processModernItemName(wrapped, () -> tag, context);
|
if (VersionHelper.isOrAbove1_21_5()) processModernItemName(wrapped, () -> tag, context);
|
||||||
@@ -161,11 +219,13 @@ public final class ModernNetworkItemHandler implements NetworkItemHandler<ItemSt
|
|||||||
else processLegacyLore(wrapped, () -> tag, context);
|
else processLegacyLore(wrapped, () -> tag, context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 如果tag不空,则需要返回
|
||||||
if (!tag.isEmpty()) {
|
if (!tag.isEmpty()) {
|
||||||
customData.put(NETWORK_ITEM_TAG, tag);
|
customData.put(NETWORK_ITEM_TAG, tag);
|
||||||
wrapped.setNBTComponent(ComponentTypes.CUSTOM_DATA, customData);
|
wrapped.setNBTComponent(ComponentTypes.CUSTOM_DATA, customData);
|
||||||
|
forceReturn = true;
|
||||||
}
|
}
|
||||||
return wrapped;
|
return forceReturn ? Optional.of(wrapped) : Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean processLegacyLore(Item<ItemStack> item, Supplier<CompoundTag> tag, Context context) {
|
public static boolean processLegacyLore(Item<ItemStack> item, Supplier<CompoundTag> tag, Context context) {
|
||||||
@@ -274,14 +334,16 @@ public final class ModernNetworkItemHandler implements NetworkItemHandler<ItemSt
|
|||||||
|
|
||||||
static class OtherItem {
|
static class OtherItem {
|
||||||
private final Item<ItemStack> item;
|
private final Item<ItemStack> item;
|
||||||
|
private final boolean forceReturn;
|
||||||
private boolean globalChanged = false;
|
private boolean globalChanged = false;
|
||||||
private CompoundTag tag;
|
private CompoundTag tag;
|
||||||
|
|
||||||
public OtherItem(Item<ItemStack> item) {
|
public OtherItem(Item<ItemStack> item, boolean forceReturn) {
|
||||||
this.item = item;
|
this.item = item;
|
||||||
|
this.forceReturn = forceReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Item<ItemStack> process(Context context) {
|
public Optional<Item<ItemStack>> process(Context context) {
|
||||||
if (VersionHelper.isOrAbove1_21_5()) {
|
if (VersionHelper.isOrAbove1_21_5()) {
|
||||||
if (processModernLore(this.item, this::getOrCreateTag, context))
|
if (processModernLore(this.item, this::getOrCreateTag, context))
|
||||||
this.globalChanged = true;
|
this.globalChanged = true;
|
||||||
@@ -298,11 +360,17 @@ public final class ModernNetworkItemHandler implements NetworkItemHandler<ItemSt
|
|||||||
this.globalChanged = true;
|
this.globalChanged = true;
|
||||||
}
|
}
|
||||||
if (this.globalChanged) {
|
if (this.globalChanged) {
|
||||||
CompoundTag customData = Optional.ofNullable(this.item.getSparrowNBTComponent(ComponentTypes.CUSTOM_DATA)).map(CompoundTag.class::cast).orElse(new CompoundTag());
|
CompoundTag customData = Optional.ofNullable(this.item.getSparrowNBTComponent(ComponentTypes.CUSTOM_DATA))
|
||||||
|
.map(CompoundTag.class::cast)
|
||||||
|
.orElseGet(CompoundTag::new);
|
||||||
customData.put(NETWORK_ITEM_TAG, getOrCreateTag());
|
customData.put(NETWORK_ITEM_TAG, getOrCreateTag());
|
||||||
this.item.setNBTComponent(ComponentKeys.CUSTOM_DATA, customData);
|
this.item.setNBTComponent(ComponentKeys.CUSTOM_DATA, customData);
|
||||||
|
return Optional.of(this.item);
|
||||||
|
} else if (this.forceReturn) {
|
||||||
|
return Optional.of(this.item);
|
||||||
|
} else {
|
||||||
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
return this.item;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private CompoundTag getOrCreateTag() {
|
private CompoundTag getOrCreateTag() {
|
||||||
|
|||||||
@@ -3200,12 +3200,26 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
|
|||||||
int stateId = buf.readVarInt();
|
int stateId = buf.readVarInt();
|
||||||
int listSize = buf.readVarInt();
|
int listSize = buf.readVarInt();
|
||||||
List<ItemStack> items = new ArrayList<>(listSize);
|
List<ItemStack> items = new ArrayList<>(listSize);
|
||||||
|
boolean changed = false;
|
||||||
Object friendlyBuf = FastNMS.INSTANCE.constructor$FriendlyByteBuf(buf);
|
Object friendlyBuf = FastNMS.INSTANCE.constructor$FriendlyByteBuf(buf);
|
||||||
for (int i = 0; i < listSize; i++) {
|
for (int i = 0; i < listSize; i++) {
|
||||||
ItemStack itemStack = BukkitItemManager.instance().s2c(FastNMS.INSTANCE.method$FriendlyByteBuf$readItem(friendlyBuf), serverPlayer);
|
ItemStack itemStack = FastNMS.INSTANCE.method$FriendlyByteBuf$readItem(friendlyBuf);
|
||||||
items.add(itemStack);
|
Optional<ItemStack> optional = BukkitItemManager.instance().s2c(itemStack, serverPlayer);
|
||||||
|
if (optional.isPresent()) {
|
||||||
|
items.add(optional.get());
|
||||||
|
changed = true;
|
||||||
|
} else {
|
||||||
|
items.add(itemStack);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ItemStack carriedItem = BukkitItemManager.instance().s2c(FastNMS.INSTANCE.method$FriendlyByteBuf$readItem(friendlyBuf), serverPlayer);
|
ItemStack carriedItem = FastNMS.INSTANCE.method$FriendlyByteBuf$readItem(friendlyBuf);
|
||||||
|
ItemStack newCarriedItem = carriedItem;
|
||||||
|
Optional<ItemStack> optional = BukkitItemManager.instance().s2c(carriedItem, serverPlayer);
|
||||||
|
if (optional.isPresent()) {
|
||||||
|
changed = true;
|
||||||
|
newCarriedItem = optional.get();
|
||||||
|
}
|
||||||
|
if (!changed) return;
|
||||||
event.setChanged(true);
|
event.setChanged(true);
|
||||||
buf.clear();
|
buf.clear();
|
||||||
buf.writeVarInt(event.packetID());
|
buf.writeVarInt(event.packetID());
|
||||||
@@ -3216,7 +3230,7 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
|
|||||||
for (ItemStack itemStack : items) {
|
for (ItemStack itemStack : items) {
|
||||||
FastNMS.INSTANCE.method$FriendlyByteBuf$writeItem(newFriendlyBuf, itemStack);
|
FastNMS.INSTANCE.method$FriendlyByteBuf$writeItem(newFriendlyBuf, itemStack);
|
||||||
}
|
}
|
||||||
FastNMS.INSTANCE.method$FriendlyByteBuf$writeItem(newFriendlyBuf, carriedItem);
|
FastNMS.INSTANCE.method$FriendlyByteBuf$writeItem(newFriendlyBuf, newCarriedItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3235,18 +3249,19 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
|
|||||||
try {
|
try {
|
||||||
itemStack = FastNMS.INSTANCE.method$FriendlyByteBuf$readItem(friendlyBuf);
|
itemStack = FastNMS.INSTANCE.method$FriendlyByteBuf$readItem(friendlyBuf);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// 其他插件干的,比如某ty*****er,不要赖到ce头上
|
// 其他插件干的,发送了非法的物品
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
itemStack = BukkitItemManager.instance().s2c(itemStack, serverPlayer);
|
BukkitItemManager.instance().s2c(itemStack, serverPlayer).ifPresent((newItemStack) -> {
|
||||||
event.setChanged(true);
|
event.setChanged(true);
|
||||||
buf.clear();
|
buf.clear();
|
||||||
buf.writeVarInt(event.packetID());
|
buf.writeVarInt(event.packetID());
|
||||||
buf.writeContainerId(containerId);
|
buf.writeContainerId(containerId);
|
||||||
buf.writeVarInt(stateId);
|
buf.writeVarInt(stateId);
|
||||||
buf.writeShort(slot);
|
buf.writeShort(slot);
|
||||||
Object newFriendlyBuf = FastNMS.INSTANCE.constructor$FriendlyByteBuf(buf);
|
Object newFriendlyBuf = FastNMS.INSTANCE.constructor$FriendlyByteBuf(buf);
|
||||||
FastNMS.INSTANCE.method$FriendlyByteBuf$writeItem(newFriendlyBuf, itemStack);
|
FastNMS.INSTANCE.method$FriendlyByteBuf$writeItem(newFriendlyBuf, newItemStack);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3258,12 +3273,14 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
|
|||||||
if (!(user instanceof BukkitServerPlayer serverPlayer)) return;
|
if (!(user instanceof BukkitServerPlayer serverPlayer)) return;
|
||||||
FriendlyByteBuf buf = event.getBuffer();
|
FriendlyByteBuf buf = event.getBuffer();
|
||||||
Object friendlyBuf = FastNMS.INSTANCE.constructor$FriendlyByteBuf(buf);
|
Object friendlyBuf = FastNMS.INSTANCE.constructor$FriendlyByteBuf(buf);
|
||||||
ItemStack itemStack = BukkitItemManager.instance().s2c(FastNMS.INSTANCE.method$FriendlyByteBuf$readItem(friendlyBuf), serverPlayer);
|
ItemStack itemStack = FastNMS.INSTANCE.method$FriendlyByteBuf$readItem(friendlyBuf);
|
||||||
event.setChanged(true);
|
BukkitItemManager.instance().s2c(itemStack, serverPlayer).ifPresent((newItemStack) -> {
|
||||||
buf.clear();
|
event.setChanged(true);
|
||||||
buf.writeVarInt(event.packetID());
|
buf.clear();
|
||||||
Object newFriendlyBuf = FastNMS.INSTANCE.constructor$FriendlyByteBuf(buf);
|
buf.writeVarInt(event.packetID());
|
||||||
FastNMS.INSTANCE.method$FriendlyByteBuf$writeItem(newFriendlyBuf, itemStack);
|
Object newFriendlyBuf = FastNMS.INSTANCE.constructor$FriendlyByteBuf(buf);
|
||||||
|
FastNMS.INSTANCE.method$FriendlyByteBuf$writeItem(newFriendlyBuf, newItemStack);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3274,7 +3291,7 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
|
|||||||
if (Config.disableItemOperations()) return;
|
if (Config.disableItemOperations()) return;
|
||||||
if (!(user instanceof BukkitServerPlayer serverPlayer)) return;
|
if (!(user instanceof BukkitServerPlayer serverPlayer)) return;
|
||||||
FriendlyByteBuf buf = event.getBuffer();
|
FriendlyByteBuf buf = event.getBuffer();
|
||||||
|
boolean changed = false;
|
||||||
Object friendlyBuf = FastNMS.INSTANCE.constructor$FriendlyByteBuf(buf);
|
Object friendlyBuf = FastNMS.INSTANCE.constructor$FriendlyByteBuf(buf);
|
||||||
int entity = buf.readVarInt();
|
int entity = buf.readVarInt();
|
||||||
List<com.mojang.datafixers.util.Pair<Object, ItemStack>> slots = Lists.newArrayList();
|
List<com.mojang.datafixers.util.Pair<Object, ItemStack>> slots = Lists.newArrayList();
|
||||||
@@ -3282,23 +3299,29 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
|
|||||||
do {
|
do {
|
||||||
slotMask = buf.readByte();
|
slotMask = buf.readByte();
|
||||||
Object equipmentSlot = CoreReflections.instance$EquipmentSlot$values[slotMask & 127];
|
Object equipmentSlot = CoreReflections.instance$EquipmentSlot$values[slotMask & 127];
|
||||||
ItemStack itemStack = BukkitItemManager.instance().s2c(FastNMS.INSTANCE.method$FriendlyByteBuf$readItem(friendlyBuf), serverPlayer);
|
ItemStack itemStack = FastNMS.INSTANCE.method$FriendlyByteBuf$readItem(friendlyBuf);
|
||||||
|
Optional<ItemStack> optional = BukkitItemManager.instance().s2c(itemStack, serverPlayer);
|
||||||
|
if (optional.isPresent()) {
|
||||||
|
changed = true;
|
||||||
|
itemStack = optional.get();
|
||||||
|
}
|
||||||
slots.add(com.mojang.datafixers.util.Pair.of(equipmentSlot, itemStack));
|
slots.add(com.mojang.datafixers.util.Pair.of(equipmentSlot, itemStack));
|
||||||
} while ((slotMask & -128) != 0);
|
} while ((slotMask & -128) != 0);
|
||||||
|
if (changed) {
|
||||||
event.setChanged(true);
|
event.setChanged(true);
|
||||||
buf.clear();
|
buf.clear();
|
||||||
buf.writeVarInt(event.packetID());
|
buf.writeVarInt(event.packetID());
|
||||||
buf.writeVarInt(entity);
|
buf.writeVarInt(entity);
|
||||||
int i = slots.size();
|
int i = slots.size();
|
||||||
Object newFriendlyBuf = FastNMS.INSTANCE.constructor$FriendlyByteBuf(buf);
|
Object newFriendlyBuf = FastNMS.INSTANCE.constructor$FriendlyByteBuf(buf);
|
||||||
for (int j = 0; j < i; ++j) {
|
for (int j = 0; j < i; ++j) {
|
||||||
com.mojang.datafixers.util.Pair<Object, ItemStack> pair = slots.get(j);
|
com.mojang.datafixers.util.Pair<Object, ItemStack> pair = slots.get(j);
|
||||||
Enum<?> equipmentSlot = (Enum<?>) pair.getFirst();
|
Enum<?> equipmentSlot = (Enum<?>) pair.getFirst();
|
||||||
boolean bl = j != i - 1;
|
boolean bl = j != i - 1;
|
||||||
int k = equipmentSlot.ordinal();
|
int k = equipmentSlot.ordinal();
|
||||||
buf.writeByte(bl ? k | -128 : k);
|
buf.writeByte(bl ? k | -128 : k);
|
||||||
FastNMS.INSTANCE.method$FriendlyByteBuf$writeItem(newFriendlyBuf, pair.getSecond());
|
FastNMS.INSTANCE.method$FriendlyByteBuf$writeItem(newFriendlyBuf, pair.getSecond());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3312,14 +3335,15 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
|
|||||||
FriendlyByteBuf buf = event.getBuffer();
|
FriendlyByteBuf buf = event.getBuffer();
|
||||||
int slot = buf.readVarInt();
|
int slot = buf.readVarInt();
|
||||||
Object friendlyBuf = FastNMS.INSTANCE.constructor$FriendlyByteBuf(buf);
|
Object friendlyBuf = FastNMS.INSTANCE.constructor$FriendlyByteBuf(buf);
|
||||||
ItemStack itemStack = BukkitItemManager.instance().s2c(FastNMS.INSTANCE.method$FriendlyByteBuf$readItem(friendlyBuf), serverPlayer);
|
ItemStack itemStack = FastNMS.INSTANCE.method$FriendlyByteBuf$readItem(friendlyBuf);
|
||||||
|
BukkitItemManager.instance().s2c(itemStack, serverPlayer).ifPresent((newItemStack) -> {
|
||||||
event.setChanged(true);
|
event.setChanged(true);
|
||||||
buf.clear();
|
buf.clear();
|
||||||
buf.writeVarInt(event.packetID());
|
buf.writeVarInt(event.packetID());
|
||||||
buf.writeVarInt(slot);
|
buf.writeVarInt(slot);
|
||||||
Object newFriendlyBuf = FastNMS.INSTANCE.constructor$FriendlyByteBuf(buf);
|
Object newFriendlyBuf = FastNMS.INSTANCE.constructor$FriendlyByteBuf(buf);
|
||||||
FastNMS.INSTANCE.method$FriendlyByteBuf$writeItem(newFriendlyBuf, itemStack);
|
FastNMS.INSTANCE.method$FriendlyByteBuf$writeItem(newFriendlyBuf, newItemStack);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3340,18 +3364,18 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
|
|||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
itemStack = BukkitItemManager.instance().c2s(itemStack);
|
BukkitItemManager.instance().c2s(itemStack).ifPresent((newItemStack) -> {
|
||||||
|
event.setChanged(true);
|
||||||
event.setChanged(true);
|
buf.clear();
|
||||||
buf.clear();
|
buf.writeVarInt(event.packetID());
|
||||||
buf.writeVarInt(event.packetID());
|
buf.writeShort(slotNum);
|
||||||
buf.writeShort(slotNum);
|
Object newFriendlyBuf = FastNMS.INSTANCE.constructor$FriendlyByteBuf(buf);
|
||||||
Object newFriendlyBuf = FastNMS.INSTANCE.constructor$FriendlyByteBuf(buf);
|
if (VersionHelper.isOrAbove1_20_5()) {
|
||||||
if (VersionHelper.isOrAbove1_20_5()) {
|
FastNMS.INSTANCE.method$FriendlyByteBuf$writeUntrustedItem(newFriendlyBuf, newItemStack);
|
||||||
FastNMS.INSTANCE.method$FriendlyByteBuf$writeUntrustedItem(newFriendlyBuf, itemStack);
|
} else {
|
||||||
} else {
|
FastNMS.INSTANCE.method$FriendlyByteBuf$writeItem(newFriendlyBuf, newItemStack);
|
||||||
FastNMS.INSTANCE.method$FriendlyByteBuf$writeItem(newFriendlyBuf, itemStack);
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3361,7 +3385,7 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
|
|||||||
public void onPacketReceive(NetWorkUser user, ByteBufPacketEvent event) {
|
public void onPacketReceive(NetWorkUser user, ByteBufPacketEvent event) {
|
||||||
if (Config.disableItemOperations()) return;
|
if (Config.disableItemOperations()) return;
|
||||||
FriendlyByteBuf buf = event.getBuffer();
|
FriendlyByteBuf buf = event.getBuffer();
|
||||||
|
boolean changed = false;
|
||||||
Object friendlyBuf = FastNMS.INSTANCE.constructor$FriendlyByteBuf(buf);
|
Object friendlyBuf = FastNMS.INSTANCE.constructor$FriendlyByteBuf(buf);
|
||||||
int containerId = buf.readContainerId();
|
int containerId = buf.readContainerId();
|
||||||
int stateId = buf.readVarInt();
|
int stateId = buf.readVarInt();
|
||||||
@@ -3372,27 +3396,37 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
|
|||||||
Int2ObjectMap<ItemStack> changedSlots = new Int2ObjectOpenHashMap<>(i);
|
Int2ObjectMap<ItemStack> changedSlots = new Int2ObjectOpenHashMap<>(i);
|
||||||
for (int j = 0; j < i; ++j) {
|
for (int j = 0; j < i; ++j) {
|
||||||
int k = buf.readShort();
|
int k = buf.readShort();
|
||||||
ItemStack itemStack = BukkitItemManager.instance().c2s(FastNMS.INSTANCE.method$FriendlyByteBuf$readItem(friendlyBuf));
|
ItemStack itemStack = FastNMS.INSTANCE.method$FriendlyByteBuf$readItem(friendlyBuf);
|
||||||
|
Optional<ItemStack> optional = BukkitItemManager.instance().c2s(itemStack);
|
||||||
|
if (optional.isPresent()) {
|
||||||
|
changed = true;
|
||||||
|
itemStack = optional.get();
|
||||||
|
}
|
||||||
changedSlots.put(k, itemStack);
|
changedSlots.put(k, itemStack);
|
||||||
}
|
}
|
||||||
ItemStack carriedItem = BukkitItemManager.instance().c2s(FastNMS.INSTANCE.method$FriendlyByteBuf$readItem(friendlyBuf));
|
ItemStack carriedItem = FastNMS.INSTANCE.method$FriendlyByteBuf$readItem(friendlyBuf);
|
||||||
|
Optional<ItemStack> optional = BukkitItemManager.instance().c2s(carriedItem);
|
||||||
event.setChanged(true);
|
if (optional.isPresent()) {
|
||||||
buf.clear();
|
changed = true;
|
||||||
buf.writeVarInt(event.packetID());
|
carriedItem = optional.get();
|
||||||
buf.writeContainerId(containerId);
|
}
|
||||||
buf.writeVarInt(stateId);
|
if (changed) {
|
||||||
buf.writeShort(slotNum);
|
event.setChanged(true);
|
||||||
buf.writeByte(buttonNum);
|
buf.clear();
|
||||||
buf.writeVarInt(clickType);
|
buf.writeVarInt(event.packetID());
|
||||||
buf.writeVarInt(changedSlots.size());
|
buf.writeContainerId(containerId);
|
||||||
Object newFriendlyBuf = FastNMS.INSTANCE.constructor$FriendlyByteBuf(buf);
|
buf.writeVarInt(stateId);
|
||||||
changedSlots.forEach((k, v) -> {
|
buf.writeShort(slotNum);
|
||||||
buf.writeShort(k);
|
buf.writeByte(buttonNum);
|
||||||
FastNMS.INSTANCE.method$FriendlyByteBuf$writeItem(newFriendlyBuf, v);
|
buf.writeVarInt(clickType);
|
||||||
});
|
buf.writeVarInt(changedSlots.size());
|
||||||
FastNMS.INSTANCE.method$FriendlyByteBuf$writeItem(newFriendlyBuf, carriedItem);
|
Object newFriendlyBuf = FastNMS.INSTANCE.constructor$FriendlyByteBuf(buf);
|
||||||
|
changedSlots.forEach((k, v) -> {
|
||||||
|
buf.writeShort(k);
|
||||||
|
FastNMS.INSTANCE.method$FriendlyByteBuf$writeItem(newFriendlyBuf, v);
|
||||||
|
});
|
||||||
|
FastNMS.INSTANCE.method$FriendlyByteBuf$writeItem(newFriendlyBuf, carriedItem);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ 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.Optional;
|
||||||
|
|
||||||
public class CommonItemPacketHandler implements EntityPacketHandler {
|
public class CommonItemPacketHandler implements EntityPacketHandler {
|
||||||
public static final CommonItemPacketHandler INSTANCE = new CommonItemPacketHandler();
|
public static final CommonItemPacketHandler INSTANCE = new CommonItemPacketHandler();
|
||||||
@@ -24,7 +25,7 @@ public class CommonItemPacketHandler implements EntityPacketHandler {
|
|||||||
if (Config.disableItemOperations()) return;
|
if (Config.disableItemOperations()) return;
|
||||||
FriendlyByteBuf buf = event.getBuffer();
|
FriendlyByteBuf buf = event.getBuffer();
|
||||||
int id = buf.readVarInt();
|
int id = buf.readVarInt();
|
||||||
|
boolean changed = false;
|
||||||
List<Object> packedItems = FastNMS.INSTANCE.method$ClientboundSetEntityDataPacket$unpack(buf);
|
List<Object> packedItems = FastNMS.INSTANCE.method$ClientboundSetEntityDataPacket$unpack(buf);
|
||||||
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);
|
||||||
@@ -41,16 +42,21 @@ public class CommonItemPacketHandler implements EntityPacketHandler {
|
|||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ItemStack itemStack = BukkitItemManager.instance().s2c(FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(nmsItemStack), user);
|
ItemStack itemStack = FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(nmsItemStack);
|
||||||
|
Optional<ItemStack> optional = BukkitItemManager.instance().s2c(itemStack, user);
|
||||||
|
if (optional.isEmpty()) continue;
|
||||||
|
changed = true;
|
||||||
|
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 (changed) {
|
||||||
event.setChanged(true);
|
event.setChanged(true);
|
||||||
buf.clear();
|
buf.clear();
|
||||||
buf.writeVarInt(event.packetID());
|
buf.writeVarInt(event.packetID());
|
||||||
buf.writeVarInt(id);
|
buf.writeVarInt(id);
|
||||||
FastNMS.INSTANCE.method$ClientboundSetEntityDataPacket$pack(packedItems, buf);
|
FastNMS.INSTANCE.method$ClientboundSetEntityDataPacket$pack(packedItems, buf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ 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.Optional;
|
||||||
|
|
||||||
public class ItemDisplayPacketHandler implements EntityPacketHandler {
|
public class ItemDisplayPacketHandler implements EntityPacketHandler {
|
||||||
public static final ItemDisplayPacketHandler INSTANCE = new ItemDisplayPacketHandler();
|
public static final ItemDisplayPacketHandler INSTANCE = new ItemDisplayPacketHandler();
|
||||||
@@ -20,24 +21,28 @@ public class ItemDisplayPacketHandler implements EntityPacketHandler {
|
|||||||
if (Config.disableItemOperations()) return;
|
if (Config.disableItemOperations()) return;
|
||||||
FriendlyByteBuf buf = event.getBuffer();
|
FriendlyByteBuf buf = event.getBuffer();
|
||||||
int id = buf.readVarInt();
|
int id = buf.readVarInt();
|
||||||
|
boolean changed = false;
|
||||||
List<Object> packedItems = FastNMS.INSTANCE.method$ClientboundSetEntityDataPacket$unpack(buf);
|
List<Object> packedItems = FastNMS.INSTANCE.method$ClientboundSetEntityDataPacket$unpack(buf);
|
||||||
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 != ItemDisplayEntityData.DisplayedItem.id()) continue;
|
if (entityDataId != ItemDisplayEntityData.DisplayedItem.id()) continue;
|
||||||
Object nmsItemStack = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$value(packedItem);
|
Object nmsItemStack = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$value(packedItem);
|
||||||
ItemStack itemStack = BukkitItemManager.instance().s2c(FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(nmsItemStack), user);
|
ItemStack itemStack = FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(nmsItemStack);
|
||||||
|
Optional<ItemStack> optional = BukkitItemManager.instance().s2c(itemStack, user);
|
||||||
|
if (optional.isEmpty()) continue;
|
||||||
|
changed = true;
|
||||||
|
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(
|
packedItems.set(i, FastNMS.INSTANCE.constructor$SynchedEntityData$DataValue(entityDataId, serializer, FastNMS.INSTANCE.method$CraftItemStack$asNMSCopy(itemStack)));
|
||||||
entityDataId, serializer, FastNMS.INSTANCE.method$CraftItemStack$asNMSCopy(itemStack)
|
|
||||||
));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (changed) {
|
||||||
event.setChanged(true);
|
event.setChanged(true);
|
||||||
buf.clear();
|
buf.clear();
|
||||||
buf.writeVarInt(event.packetID());
|
buf.writeVarInt(event.packetID());
|
||||||
buf.writeVarInt(id);
|
buf.writeVarInt(id);
|
||||||
FastNMS.INSTANCE.method$ClientboundSetEntityDataPacket$pack(packedItems, buf);
|
FastNMS.INSTANCE.method$ClientboundSetEntityDataPacket$pack(packedItems, buf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,16 +14,18 @@ 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.Optional;
|
||||||
|
|
||||||
public class ItemFramePacketHandler implements EntityPacketHandler {
|
public class ItemFramePacketHandler implements EntityPacketHandler {
|
||||||
public static final ItemFramePacketHandler INSTANCE = new ItemFramePacketHandler();
|
public static final ItemFramePacketHandler INSTANCE = new ItemFramePacketHandler();
|
||||||
private static long lastWarningTime = 0;
|
private static long LAST_WARN_TIME = 0;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleSetEntityData(Player user, ByteBufPacketEvent event) {
|
public void handleSetEntityData(Player user, ByteBufPacketEvent event) {
|
||||||
if (Config.disableItemOperations()) return;
|
if (Config.disableItemOperations()) return;
|
||||||
FriendlyByteBuf buf = event.getBuffer();
|
FriendlyByteBuf buf = event.getBuffer();
|
||||||
int id = buf.readVarInt();
|
int id = buf.readVarInt();
|
||||||
|
boolean changed = false;
|
||||||
List<Object> packedItems = FastNMS.INSTANCE.method$ClientboundSetEntityDataPacket$unpack(buf);
|
List<Object> packedItems = FastNMS.INSTANCE.method$ClientboundSetEntityDataPacket$unpack(buf);
|
||||||
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);
|
||||||
@@ -32,26 +34,29 @@ public class ItemFramePacketHandler implements EntityPacketHandler {
|
|||||||
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 - LAST_WARN_TIME > 5000) {
|
||||||
BukkitServerPlayer serverPlayer = (BukkitServerPlayer) user;
|
BukkitServerPlayer serverPlayer = (BukkitServerPlayer) user;
|
||||||
CraftEngine.instance().logger().severe("An issue was detected while applying item-related entity data for '" + serverPlayer.name() +
|
CraftEngine.instance().logger().severe("An issue was detected while applying item-related entity data for '" + serverPlayer.name() +
|
||||||
"'. Please execute the command '/ce debug entity-id " + serverPlayer.world().name() + " " + id + "' and provide a screenshot for further investigation.");
|
"'. Please execute the command '/ce debug entity-id " + serverPlayer.world().name() + " " + id + "' and provide a screenshot for further investigation.");
|
||||||
lastWarningTime = time;
|
LAST_WARN_TIME = time;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ItemStack itemStack = BukkitItemManager.instance().s2c(FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(nmsItemStack), user);
|
ItemStack itemStack = FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(nmsItemStack);
|
||||||
|
Optional<ItemStack> optional = BukkitItemManager.instance().s2c(itemStack, user);
|
||||||
|
if (optional.isEmpty()) continue;
|
||||||
|
changed = true;
|
||||||
|
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(
|
packedItems.set(i, FastNMS.INSTANCE.constructor$SynchedEntityData$DataValue(entityDataId, serializer, FastNMS.INSTANCE.method$CraftItemStack$asNMSCopy(itemStack)));
|
||||||
entityDataId, serializer, FastNMS.INSTANCE.method$CraftItemStack$asNMSCopy(itemStack)
|
|
||||||
));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (changed) {
|
||||||
event.setChanged(true);
|
event.setChanged(true);
|
||||||
buf.clear();
|
buf.clear();
|
||||||
buf.writeVarInt(event.packetID());
|
buf.writeVarInt(event.packetID());
|
||||||
buf.writeVarInt(id);
|
buf.writeVarInt(id);
|
||||||
FastNMS.INSTANCE.method$ClientboundSetEntityDataPacket$pack(packedItems, buf);
|
FastNMS.INSTANCE.method$ClientboundSetEntityDataPacket$pack(packedItems, buf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import net.momirealms.sparrow.nbt.Tag;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
public interface NetworkItemHandler<T> {
|
public interface NetworkItemHandler<T> {
|
||||||
Operation[] BY_INDEX = new Operation[] {Operation.ADD, Operation.REMOVE, Operation.RESET};
|
Operation[] BY_INDEX = new Operation[] {Operation.ADD, Operation.REMOVE, Operation.RESET};
|
||||||
@@ -17,9 +18,9 @@ public interface NetworkItemHandler<T> {
|
|||||||
String NETWORK_OPERATION = "type";
|
String NETWORK_OPERATION = "type";
|
||||||
String NETWORK_VALUE = "value";
|
String NETWORK_VALUE = "value";
|
||||||
|
|
||||||
Item<T> s2c(Item<T> itemStack, Player player);
|
Optional<Item<T>> s2c(Item<T> itemStack, Player player);
|
||||||
|
|
||||||
Item<T> c2s(Item<T> itemStack);
|
Optional<Item<T>> c2s(Item<T> itemStack);
|
||||||
|
|
||||||
static CompoundTag pack(Operation operation, @Nullable Tag value) {
|
static CompoundTag pack(Operation operation, @Nullable Tag value) {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
|
|||||||
Reference in New Issue
Block a user