mirror of
https://github.com/Winds-Studio/Leaf.git
synced 2025-12-25 09:59:15 +00:00
Reimplement Hide specified item components (#215)
* [Reimplement] Hide specified item components * cleanup
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user