Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] Hide specified item components to clients #94

Merged
merged 5 commits into from
Aug 5, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
218 changes: 218 additions & 0 deletions patches/server/0092-Hide-specified-item-components-to-clients.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: TheFloodDragon <[email protected]>
Date: Sun, 4 Aug 2024 19:36:11 +0800
Subject: [PATCH] Hide specified item components to clients


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 8cca2ac616a2c80268c96b9f95e33f834a0fc8fd..c2c0e88962ea010ece20f9710dfcd83b7b61bf91 100644
--- a/src/main/java/net/minecraft/network/protocol/game/ClientboundContainerSetContentPacket.java
+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundContainerSetContentPacket.java
@@ -23,17 +23,17 @@ public class ClientboundContainerSetContentPacket implements Packet<ClientGamePa
this.items = NonNullList.withSize(contents.size(), ItemStack.EMPTY);

for (int i = 0; i < contents.size(); i++) {
- this.items.set(i, contents.get(i).copy());
+ this.items.set(i, org.dreeam.leaf.util.item.ItemStackObfuscator.stripMeta(contents.get(i), true)); // Leaf - Hide specified item components
}

- this.carriedItem = cursorStack.copy();
+ this.carriedItem = org.dreeam.leaf.util.item.ItemStackObfuscator.stripMeta(cursorStack, true); // Leaf - Hide specified item components
}

private ClientboundContainerSetContentPacket(RegistryFriendlyByteBuf buf) {
this.containerId = buf.readUnsignedByte();
this.stateId = buf.readVarInt();
- this.items = ItemStack.OPTIONAL_LIST_STREAM_CODEC.decode(buf);
- this.carriedItem = ItemStack.OPTIONAL_STREAM_CODEC.decode(buf);
+ this.items = ItemStack.OPTIONAL_LIST_STREAM_CODEC.decode(buf).stream().map(item -> org.dreeam.leaf.util.item.ItemStackObfuscator.stripMeta(item, false)).toList(); // Leaf - Hide specified item components
+ this.carriedItem = org.dreeam.leaf.util.item.ItemStackObfuscator.stripMeta(ItemStack.OPTIONAL_STREAM_CODEC.decode(buf), false); // Leaf - Hide specified item components
}

// Paper start - Handle large packets disconnecting client
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 63f6a2437da9363786b55af0a7cbc5373232d35b..f4c85b78eafb27331ab7c3e45c8493b271583241 100644
--- a/src/main/java/net/minecraft/network/protocol/game/ClientboundContainerSetSlotPacket.java
+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundContainerSetSlotPacket.java
@@ -21,14 +21,14 @@ public class ClientboundContainerSetSlotPacket implements Packet<ClientGamePacke
this.containerId = syncId;
this.stateId = revision;
this.slot = slot;
- this.itemStack = stack.copy();
+ this.itemStack = org.dreeam.leaf.util.item.ItemStackObfuscator.stripMeta(stack, true); // Leaf - Hide specified item components
}

private ClientboundContainerSetSlotPacket(RegistryFriendlyByteBuf buf) {
this.containerId = buf.readByte();
this.stateId = buf.readVarInt();
this.slot = buf.readShort();
- this.itemStack = ItemStack.OPTIONAL_STREAM_CODEC.decode(buf);
+ this.itemStack = org.dreeam.leaf.util.item.ItemStackObfuscator.stripMeta(ItemStack.OPTIONAL_STREAM_CODEC.decode(buf), false); // Leaf - Hide specified item components
}

private void write(RegistryFriendlyByteBuf buf) {
diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java
index 573c380e123473e35c0b72c44b32c8d6ba8e61c6..feacc41ecf7f4028e0a1cce5d2012ced96a26d30 100644
--- a/src/main/java/net/minecraft/server/level/ServerEntity.java
+++ b/src/main/java/net/minecraft/server/level/ServerEntity.java
@@ -374,7 +374,7 @@ public class ServerEntity {
ItemStack itemstack = ((LivingEntity) this.entity).getItemBySlot(enumitemslot);

if (!itemstack.isEmpty()) {
- list.add(Pair.of(enumitemslot, itemstack.copy()));
+ list.add(Pair.of(enumitemslot, org.dreeam.leaf.util.item.ItemStackObfuscator.stripMeta(itemstack, true))); // Leaf - Hide specified item components
}
}

diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 855fa46cbaaa22003f46e0e63292ad0824d23c86..60ef9bf2425a8d6d54cd59ae15f3f3780924a977 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -2858,7 +2858,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
entity.refreshEntityData(ServerGamePacketListenerImpl.this.player);
// SPIGOT-7136 - Allays
if (entity instanceof Allay) {
- ServerGamePacketListenerImpl.this.send(new ClientboundSetEquipmentPacket(entity.getId(), Arrays.stream(net.minecraft.world.entity.EquipmentSlot.VALUES).map((slot) -> Pair.of(slot, ((LivingEntity) entity).getItemBySlot(slot).copy())).collect(Collectors.toList()), true)); // Paper - sanitize // Gale - JettPack - reduce array allocations
+ ServerGamePacketListenerImpl.this.send(new ClientboundSetEquipmentPacket(entity.getId(), Arrays.stream(net.minecraft.world.entity.EquipmentSlot.VALUES).map((slot) -> Pair.of(slot, org.dreeam.leaf.util.item.ItemStackObfuscator.stripMeta(((LivingEntity) entity).getItemBySlot(slot), true))).collect(Collectors.toList()), true)); // Paper - sanitize // Gale - JettPack - reduce array allocations // Leaf - Hide specified item components
ServerGamePacketListenerImpl.this.player.containerMenu.sendAllDataToRemote();
}
}
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index 7c75298c8ea7a828c2d9cd4e7ffd4d09a0113aed..6036c1a6f61d6c8a220ed97166c8741ea1922ab4 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -3388,7 +3388,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
ItemStack itemstack1 = itemstack;
ItemStack itemstack2 = this.getItemBySlot(enumitemslot);

- if (this.equipmentHasChanged(itemstack1, itemstack2)) {
+ if (this.equipmentHasChanged(org.dreeam.leaf.util.item.ItemStackObfuscator.stripMeta(itemstack1, true), org.dreeam.leaf.util.item.ItemStackObfuscator.stripMeta(itemstack2, true))) { // Leaf - Hide specified item components
// Paper start - PlayerArmorChangeEvent
if (this instanceof ServerPlayer && enumitemslot.getType() == EquipmentSlot.Type.HUMANOID_ARMOR) {
final org.bukkit.inventory.ItemStack oldItem = CraftItemStack.asBukkitCopy(itemstack1);
@@ -3472,7 +3472,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
equipmentChanges.forEach((enumitemslot, itemstack) -> {
ItemStack itemstack1 = itemstack.copy();

- list.add(Pair.of(enumitemslot, itemstack1));
+ list.add(Pair.of(enumitemslot, org.dreeam.leaf.util.item.ItemStackObfuscator.stripMeta(itemstack1, true))); // Leaf - Hide specified item components
switch (enumitemslot.getType()) {
case HAND:
this.setLastHandItem(enumitemslot, itemstack1);
diff --git a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java
index c491291b522aebf34c7d990d2b485d1a0d19cdcd..267f638bb704002a30b1f5cb4e33b6a89cf0773c 100644
--- a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java
+++ b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java
@@ -295,7 +295,7 @@ public abstract class AbstractContainerMenu {
private void triggerSlotListeners(int slot, ItemStack stack, Supplier<ItemStack> copySupplier) {
ItemStack itemstack1 = (ItemStack) this.lastSlots.get(slot);

- if (!ItemStack.matches(itemstack1, stack)) {
+ if (!ItemStack.matches(org.dreeam.leaf.util.item.ItemStackObfuscator.stripMeta(itemstack1, true), org.dreeam.leaf.util.item.ItemStackObfuscator.stripMeta(stack, true))) { // Leaf - Hide specified item components
ItemStack itemstack2 = (ItemStack) copySupplier.get();

this.lastSlots.set(slot, itemstack2);
@@ -314,7 +314,7 @@ public abstract class AbstractContainerMenu {
if (!this.suppressRemoteUpdates) {
ItemStack itemstack1 = (ItemStack) this.remoteSlots.get(slot);

- if (!ItemStack.matches(itemstack1, stack)) {
+ if (!ItemStack.matches(org.dreeam.leaf.util.item.ItemStackObfuscator.stripMeta(itemstack1, true), org.dreeam.leaf.util.item.ItemStackObfuscator.stripMeta(stack, true))) { // Leaf - Hide specified item components
ItemStack itemstack2 = (ItemStack) copySupplier.get();

this.remoteSlots.set(slot, itemstack2);
@@ -342,7 +342,7 @@ public abstract class AbstractContainerMenu {

private void synchronizeCarriedToRemote() {
if (!this.suppressRemoteUpdates) {
- if (!ItemStack.matches(this.getCarried(), this.remoteCarried)) {
+ if (!ItemStack.matches(org.dreeam.leaf.util.item.ItemStackObfuscator.stripMeta(this.getCarried(), true), org.dreeam.leaf.util.item.ItemStackObfuscator.stripMeta(this.remoteCarried, true))) { // Leaf - Hide specified item components
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/misc/HiddenItemComponents.java b/src/main/java/org/dreeam/leaf/config/modules/misc/HiddenItemComponents.java
new file mode 100644
index 0000000000000000000000000000000000000000..d1c1bbd246ff2ec4e78ef3230762f2747a5e315e
--- /dev/null
+++ b/src/main/java/org/dreeam/leaf/config/modules/misc/HiddenItemComponents.java
@@ -0,0 +1,43 @@
+package org.dreeam.leaf.config.modules.misc;
+
+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.Collections;
+import java.util.List;
+
+public class HiddenItemComponents extends ConfigModules {
+
+ public String getBasePath() {
+ return EnumConfigCategory.MISC.getBaseKeyName();
+ }
+
+ public static List<DataComponentType<?>> hiddenItemComponentTypes = Collections.emptyList();
+
+ @Override
+ public void onLoaded() {
+ List<String> list = config.getList(getBasePath() + ".hidden-item-components", Collections.emptyList(), """
+ Controls whether specified component information is sent to clients.
+ This may break resource packs and mods that rely on this information.
+ It needs a component type list, incorrect things will not work.
+ You can fill it with ["custom_data"] to hide components of CUSTOM_DATA.
+ Also, it can avoid some frequent client animations.
+ NOTICE: You must know what you're filling in and how it works! It will handle all itemStacks!
+ """);
+ List<DataComponentType<?>> types = new ArrayList<>(list.size());
+ for (String id : list) {
+ // Find and check
+ DataComponentType<?> type = BuiltInRegistries.DATA_COMPONENT_TYPE.get(ResourceLocation.parse(id));
+ if (type != null) {
+ types.add(type);
+ } else LeafConfig.LOGGER.warn("Unknown component type: {}", id);
+ }
+ hiddenItemComponentTypes = types;
+ }
+
+}
diff --git a/src/main/java/org/dreeam/leaf/util/item/ItemStackObfuscator.java b/src/main/java/org/dreeam/leaf/util/item/ItemStackObfuscator.java
new file mode 100644
index 0000000000000000000000000000000000000000..4130aaf0df48b6f17206059a3343419f6bfbc0fe
--- /dev/null
+++ b/src/main/java/org/dreeam/leaf/util/item/ItemStackObfuscator.java
@@ -0,0 +1,31 @@
+package org.dreeam.leaf.util.item;
+
+import net.minecraft.core.component.DataComponentType;
+import net.minecraft.world.item.ItemStack;
+import org.dreeam.leaf.config.modules.misc.HiddenItemComponents;
+
+import java.util.List;
+
+public class ItemStackObfuscator {
+
+ // Leaf start - Hide specified item components
+ public static ItemStack stripMeta(final ItemStack itemStack, final boolean copyItemStack) {
+ if (itemStack.isEmpty() || itemStack.getComponentsPatch().isEmpty()) return itemStack;
+
+ final ItemStack copy = copyItemStack ? itemStack.copy() : itemStack;
+
+ // Get the types which need to hide
+ List<DataComponentType<?>> hiddenTypes = HiddenItemComponents.hiddenItemComponentTypes;
+ if (hiddenTypes.isEmpty()) return copy;
+
+ // Remove specified types
+ for (DataComponentType<?> type : hiddenTypes) {
+ // Only remove, no others
+ copy.remove(type);
+ }
+
+ return copy;
+ }
+ // Leaf end - Hide specified item components
+
+}
Loading