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

Reimplement ItemStack Obfuscation #11817

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

Owen1212055
Copy link
Member

@Owen1212055 Owen1212055 commented Dec 25, 2024

Due to the amount of changes to items in the past updates, the previous configuration for obfuscation does not really fit today's representation of items.
This reimplements ItemStack obfuscation in a way that is built in mind to support the new 1.21.4 ItemModel format.

The following data components are obfuscated by default when enabled:

DataComponents.MAX_STACK_SIZE,
DataComponents.MAX_DAMAGE,
DataComponents.DAMAGE,
DataComponents.CUSTOM_NAME,
DataComponents.ITEM_NAME,
DataComponents.LORE,
DataComponents.RARITY,
DataComponents.ENCHANTMENTS,
DataComponents.ATTRIBUTE_MODIFIERS,
DataComponents.CUSTOM_DATA,
DataComponents.WRITABLE_BOOK_CONTENT,
DataComponents.WRITTEN_BOOK_CONTENT,
DataComponents.MAP_ID,
DataComponents.POTION_CONTENTS // New!! Will try to hide if customColor is set

Unlike before, obfuscation for data components can now be configured on a per item model basis. So for example, items with the elytra item model will not obfuscate their damage component in order for their item model to properly read the damage value.

    items:
      all-models:
        also-obfuscate: []
        dont-obfuscate:
        - minecraft:lodestone_tracker
        sanitize-count: true
      enable-item-obfuscation: false
      model-overrides:
        minecraft:elytra:
          also-obfuscate: []
          dont-obfuscate:
          - minecraft:damage
          sanitize-count: true

Tradeoff: No modifying the component map

Components like unbreakable will need to remain on the item, since this current approach ONLY swaps patched values sent to the client. And obviously, marker components don't really have any actual data on them. This keeps the implementation of this obfuscation simple and performant.

But because of this, we cannot add or remove any components.

Default Obfuscation Behavior

Due to the tradeoff listed above, we HAVE to supply a patched value if it is present.
Because of this, the following logic has been implemented:
image

Basically, for every component, we will try to send the prototype in order to keep the item looking identical to its vanilla counterpart.
(Note: The enchantment component forcibly will use an empty value rather than the prototype in order to retain the glint.)

  • For example:
  • diamond_sword[max_damage=10] -> diamond_sword[max_damage=1561]
  • dirt[max_damage=10] -> dirt[max_damage=1] // Use empty value, since not in prototype

QUESTION: Should this behavior be configurable? I know some people use this to save on bandwidth...

These are the current components that have default values, so when configured, will be hidden if not present on the prototype:

Data Component Empty Value
LODESTONE_TRACKER new LodestoneTracker(Optional.empty(), false)
ENCHANTMENTS dummyEnchantments()
MAX_DAMAGE 1
DAMAGE 0
CUSTOM_NAME Component.empty()
TOOLTIP_STYLE ResourceLocation.parse("paper:fake-tooltip")
DEATH_PROTECTION new DeathProtection(List.of())
STORED_ENCHANTMENTS dummyEnchantments()
CAN_PLACE_ON new AdventureModePredicate(List.of(), true)
REPAIR_COST 0
USE_REMAINDER new UseRemainder(ItemStack.EMPTY)
USE_COOLDOWN new UseCooldown(1, Optional.empty())
TOOL new Tool(List.of(), 1F, 1)
REPAIRABLE new Repairable(HolderSet.empty())
CUSTOM_DATA CustomData.EMPTY
POTION_CONTENTS ItemComponentSanitizer::sanitizePotionContents
ENTITY_DATA CustomData.EMPTY
BUCKET_ENTITY_DATA CustomData.EMPTY
BLOCK_ENTITY_DATA CustomData.EMPTY
OMINOUS_BOTTLE_AMPLIFIER new OminousBottleAmplifier(0)
BEES List.of()
LOCK LockCode.NO_LOCK
WRITABLE_BOOK_CONTENT WritableBookContent.EMPTY
WRITTEN_BOOK_CONTENT WrittenBookContent.EMPTY
MAP_ID new MapId(0)

Finally

Please provide any feedback on this new system, as this is a bit different and want to make sure that it is the best for people migrating from the old system. And additionally which new components people would like obfuscated by default.😄


Download the paperclip jar for this pull request: paper-11817.zip

This general principal is that there is no mutation of the patched map, only swapping of the valid values.

Additional work will need to be done to support hiding enchantments whilst keeping the glint, as we either have to append an enchantment, or need to add a glint override.. which kinda defeats the purpose above. Cant add a vanilla enchantment because those can be removed! Further investigation needed.
@Owen1212055 Owen1212055 added the build-pr-jar Enables a workflow to build Paperclip jars on the pull request. label Dec 25, 2024
@Owen1212055 Owen1212055 requested a review from a team as a code owner December 25, 2024 04:28
@kennytv kennytv added the type: feature Request for a new Feature. label Dec 25, 2024
@MiniDigger
Copy link
Member

(needs docs PR)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
build-pr-jar Enables a workflow to build Paperclip jars on the pull request. type: feature Request for a new Feature.
Projects
Status: Awaiting review
Development

Successfully merging this pull request may close these issues.

3 participants