mirror of
https://github.com/Winds-Studio/Leaf.git
synced 2025-12-21 07:59:26 +00:00
* [Reimplement] Hide specified item components * try to fix drag problem in creative mode * correct my name * cleanup * Update 0103-Hide-specified-item-components.patch * Move to gameplay
202 lines
9.5 KiB
Diff
202 lines
9.5 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: TheFloodDragon <1610105206@qq.com>
|
|
Date: Tue, 4 Feb 2025 21:11:29 +0800
|
|
Subject: [PATCH] Hide specified item components
|
|
|
|
|
|
diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundContainerSetContentPacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundContainerSetContentPacket.java
|
|
index 8d5939e03a065197af125d95a10134abbccd07ec..8125e0680a274ad867d5bf8541b63475d03bbf0e 100644
|
|
--- a/src/main/java/net/minecraft/network/protocol/game/ClientboundContainerSetContentPacket.java
|
|
+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundContainerSetContentPacket.java
|
|
@@ -54,8 +54,8 @@ public class ClientboundContainerSetContentPacket implements Packet<ClientGamePa
|
|
private void write(RegistryFriendlyByteBuf buf) {
|
|
buf.writeContainerId(this.containerId);
|
|
buf.writeVarInt(this.stateId);
|
|
- ItemStack.OPTIONAL_LIST_STREAM_CODEC.encode(buf, this.items);
|
|
- ItemStack.OPTIONAL_STREAM_CODEC.encode(buf, this.carriedItem);
|
|
+ ItemStack.OPTIONAL_LIST_STREAM_CODEC.encode(buf, org.dreeam.leaf.util.item.ItemStackStripper.strip(this.items, true)); // Leaf - Hide specified item components
|
|
+ ItemStack.OPTIONAL_STREAM_CODEC.encode(buf, org.dreeam.leaf.util.item.ItemStackStripper.strip(this.carriedItem, true)); // Leaf - Hide specified item components
|
|
}
|
|
|
|
@Override
|
|
diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundContainerSetSlotPacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundContainerSetSlotPacket.java
|
|
index 97b6605ba56584a44cfc4361af7389e876496ef2..08fdafbf6d0249adc502e661216f1fcdeee647d2 100644
|
|
--- a/src/main/java/net/minecraft/network/protocol/game/ClientboundContainerSetSlotPacket.java
|
|
+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundContainerSetSlotPacket.java
|
|
@@ -33,7 +33,7 @@ public class ClientboundContainerSetSlotPacket implements Packet<ClientGamePacke
|
|
buf.writeContainerId(this.containerId);
|
|
buf.writeVarInt(this.stateId);
|
|
buf.writeShort(this.slot);
|
|
- ItemStack.OPTIONAL_STREAM_CODEC.encode(buf, this.itemStack);
|
|
+ ItemStack.OPTIONAL_STREAM_CODEC.encode(buf, org.dreeam.leaf.util.item.ItemStackStripper.strip(this.itemStack, true)); // Leaf - Hide specified item components
|
|
}
|
|
|
|
@Override
|
|
diff --git a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java
|
|
index bfc90524bd739ed1d91fe9912e38093b3c28928f..c1f644abcb374addb8ad6a914e670da4f033199b 100644
|
|
--- a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java
|
|
+++ b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java
|
|
@@ -370,7 +370,7 @@ public abstract class AbstractContainerMenu {
|
|
|
|
private void synchronizeCarriedToRemote() {
|
|
if (!this.suppressRemoteUpdates) {
|
|
- if (!ItemStack.matches(this.getCarried(), this.remoteCarried)) {
|
|
+ if (!org.dreeam.leaf.util.item.ItemStackStripper.matchesStripped(this.getCarried(), this.remoteCarried)) { // Leaf - Hide specified item components - Avoid some frequent client animations
|
|
this.remoteCarried = this.getCarried().copy();
|
|
if (this.synchronizer != null) {
|
|
this.synchronizer.sendCarriedChange(this, this.remoteCarried);
|
|
diff --git a/src/main/java/org/dreeam/leaf/config/modules/gameplay/HideItemComponent.java b/src/main/java/org/dreeam/leaf/config/modules/gameplay/HideItemComponent.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..4e647eb06d0c59f5deb99054c9ca2315abb1c8b1
|
|
--- /dev/null
|
|
+++ b/src/main/java/org/dreeam/leaf/config/modules/gameplay/HideItemComponent.java
|
|
@@ -0,0 +1,62 @@
|
|
+package org.dreeam.leaf.config.modules.gameplay;
|
|
+
|
|
+import net.minecraft.core.component.DataComponentType;
|
|
+import net.minecraft.core.registries.BuiltInRegistries;
|
|
+import net.minecraft.resources.ResourceLocation;
|
|
+import org.dreeam.leaf.config.ConfigModules;
|
|
+import org.dreeam.leaf.config.EnumConfigCategory;
|
|
+import org.dreeam.leaf.config.LeafConfig;
|
|
+
|
|
+import java.util.ArrayList;
|
|
+import java.util.List;
|
|
+
|
|
+/**
|
|
+ * HideItemComponent
|
|
+ *
|
|
+ * @author TheFloodDragon
|
|
+ * @since 2025/2/4 18:30
|
|
+ */
|
|
+public class HideItemComponent extends ConfigModules {
|
|
+
|
|
+ public String getBasePath() {
|
|
+ return EnumConfigCategory.GAMEPLAY.getBaseKeyName() + ".hide-item-component";
|
|
+ }
|
|
+
|
|
+ public static boolean enabled = false;
|
|
+ public static List<DataComponentType<?>> hiddenTypes = List.of();
|
|
+
|
|
+ @Override
|
|
+ public void onLoaded() {
|
|
+ config.addCommentRegionBased(getBasePath(), """
|
|
+ Controls whether specified component information would be sent to clients.
|
|
+ It may break resource packs and mods that rely on the information.
|
|
+ Also, it can avoid some frequent client animations.
|
|
+ Attention: This is not same as Paper's item-obfuscation, we only hide specified component information from player's inventory.""",
|
|
+ """
|
|
+ 控制哪些物品组件信息会被发送至客户端.
|
|
+ 可能会导致依赖物品组件的资源包/模组无法正常工作.
|
|
+ 可以避免一些客户端动画效果.
|
|
+ 注意: 此项与 Paper 的 item-obfuscation 不同, 我们只从玩家背包中隐藏物品指定的组件信息.""");
|
|
+ List<String> list = config.getList(getBasePath() + ".hidden-types", new ArrayList<>(), config.pickStringRegionBased("""
|
|
+ Which type of components will be hidden from clients.
|
|
+ It needs a component type list, incorrect things will not work.""",
|
|
+ """
|
|
+ 被隐藏的物品组件类型列表.
|
|
+ 该配置项接受一个物品组件列表, 格式不正确将不会启用."""));
|
|
+ enabled = config.getBoolean(getBasePath() + ".enabled", enabled, config.pickStringRegionBased(
|
|
+ "If enabled, specified item component information from player's inventory will be hided.",
|
|
+ "启用后, 玩家背包内物品的指定组件信息会被隐藏."
|
|
+ ));
|
|
+
|
|
+ final List<DataComponentType<?>> types = new ArrayList<>(list.size());
|
|
+
|
|
+ for (String componentType : list) {
|
|
+ BuiltInRegistries.DATA_COMPONENT_TYPE.get(ResourceLocation.parse(componentType)).ifPresentOrElse(
|
|
+ optional -> types.add(optional.value()),
|
|
+ () -> LeafConfig.LOGGER.warn("Unknown component type: {}", componentType)
|
|
+ );
|
|
+ }
|
|
+
|
|
+ hiddenTypes = types;
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/org/dreeam/leaf/util/item/ItemStackStripper.java b/src/main/java/org/dreeam/leaf/util/item/ItemStackStripper.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..9e70d46e367b3f0b3287f59d11b32ca72b177f55
|
|
--- /dev/null
|
|
+++ b/src/main/java/org/dreeam/leaf/util/item/ItemStackStripper.java
|
|
@@ -0,0 +1,80 @@
|
|
+package org.dreeam.leaf.util.item;
|
|
+
|
|
+import net.minecraft.core.component.DataComponentMap;
|
|
+import net.minecraft.core.component.DataComponentType;
|
|
+import net.minecraft.world.item.ItemStack;
|
|
+import org.dreeam.leaf.config.modules.gameplay.HideItemComponent;
|
|
+
|
|
+import java.util.ArrayList;
|
|
+import java.util.List;
|
|
+import java.util.Objects;
|
|
+
|
|
+/**
|
|
+ * ItemStackStripper
|
|
+ *
|
|
+ * @author TheFloodDragon
|
|
+ * @since 2025/2/4 19:04
|
|
+ */
|
|
+public class ItemStackStripper {
|
|
+
|
|
+ public static ItemStack strip(final ItemStack itemStack, final boolean copy) {
|
|
+ if (!HideItemComponent.enabled || itemStack.isEmpty() || itemStack.getComponentsPatch().isEmpty())
|
|
+ return itemStack;
|
|
+
|
|
+ final ItemStack copied = copy ? itemStack.copy() : itemStack;
|
|
+
|
|
+ // Remove specified types
|
|
+ for (DataComponentType<?> type : HideItemComponent.hiddenTypes) {
|
|
+ // Only remove, no others
|
|
+ copied.remove(type);
|
|
+ }
|
|
+
|
|
+ return copied;
|
|
+ }
|
|
+
|
|
+ public static List<ItemStack> strip(final List<ItemStack> itemStacks, final boolean copy) {
|
|
+ if (!HideItemComponent.enabled) return itemStacks;
|
|
+
|
|
+ final List<ItemStack> copiedItems = new ArrayList<>();
|
|
+
|
|
+ for (ItemStack itemStack : itemStacks) {
|
|
+ if (itemStack.isEmpty() || itemStack.getComponentsPatch().isEmpty()) {
|
|
+ copiedItems.add(itemStack);
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ final ItemStack copied = copy ? itemStack.copy() : itemStack;
|
|
+
|
|
+ // Remove specified types
|
|
+ for (DataComponentType<?> type : HideItemComponent.hiddenTypes) {
|
|
+ // Only remove, no others
|
|
+ copied.remove(type);
|
|
+ }
|
|
+
|
|
+ copiedItems.add(copied);
|
|
+ }
|
|
+
|
|
+ return copiedItems;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Check if two ItemStacks are the same after stripping components
|
|
+ */
|
|
+ public static boolean matchesStripped(ItemStack left, ItemStack right) {
|
|
+ if (HideItemComponent.enabled) {
|
|
+ return left == right || (
|
|
+ left.is(right.getItem()) && left.getCount() == right.getCount() &&
|
|
+ (left.isEmpty() && right.isEmpty() || Objects.equals(strip(left.getComponents()), strip(right.getComponents())))
|
|
+ );
|
|
+ }
|
|
+
|
|
+ return ItemStack.matches(left, right);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * @return a new DataComponentMap with all hidden components removed
|
|
+ */
|
|
+ private static DataComponentMap strip(final DataComponentMap map) {
|
|
+ return map.filter(c -> !HideItemComponent.hiddenTypes.contains(c));
|
|
+ }
|
|
+}
|