mojira.dev

Fungus

More than one avatar was detected! There might be multiple accounts sharing this same name.

Assigned

No issues.

Reported

MC-142818 Music turning off when submerging in water Duplicate MC-138028 Ranged weapons behaving incorrectly Cannot Reproduce MC-134314 Iron horse armour appearing incorrectly Awaiting Response

Comments

This issue emerged at 25w09a, when the collision code was modified, and until now (25w20a) it still exists. Actually this problem is so severe that almost any survival servers running continuously where players AFK for several days are bound to crash. Hope it will receive immediate attention.

Cause any item dropped from the block that was broken by player in survival mode depends on the loot table, and the the contents of include and exclude in copy_components function of item modifier of the loot table determines what components to keep when a block entity is broken. Checking data/minecraft/loot_table/blocks/shulker_box.json from vanilla datapack, you can find

{
  "type": "minecraft:block",
  "pools": [
    {
      "bonus_rolls": 0.0,
      "entries": [
        {
          "type": "minecraft:item",
          "functions": [
            {
              "function": "minecraft:copy_components",
              "include": [
                "minecraft:custom_name",
                "minecraft:container",
                "minecraft:lock",
                "minecraft:container_loot"
              ],
              "source": "block_entity"
            }
          ],
          "name": "minecraft:shulker_box"
        }
      ],
      "rolls": 1.0
    }
  ],
  "random_sequence": "minecraft:blocks/shulker_box"
}

Obviously there are 4 kinds of components in total are kept. If you wanna add new component types, just write down a datapack where the loot table of shulker box are copied to the same relative path, and yet plus your expected components like minecraft:rarity into include. Though all shulker boxes might resolved by the same steps, it is the most effective methods without modifying the source code of Minecraft by modding or something else.


If you are familiar with modding, taking yarn mapping for example, you need to mixin like

@Mixin(CopyComponentsLootFunction.class)
public abstract class CopyComponentsLootFunctionMixin implements CCLFTouch {
    @Final @Shadow
    @SuppressWarnings("OptionalUsedAsFieldOrParameterType")
    private Optional<List<ComponentType<?>>> include;

    @Mutable @Final @Shadow
    private Predicate<ComponentType<?>> filter;

    @Override
    public void mod$touch(List<ComponentType<?>> types) {
        include.ifPresent(componentTypes ->
                filter = Stream.concat(componentTypes.stream(), types.stream()).toList()::contains);
    }
}

And place the following hook (in Kotlin, you can convert it to Java version) after the server started and datapack reloaded

Registries.BLOCK.iterateEntries(BlockTags.SHULKER_BOXES).forEach { entry ->
    val lootTable = server.reloadableRegistries.getLootTable(entry.value().lootTableKey.get()) as LootTableAccessor
    (lootTable.pools[0]?.entries[0] as? LeafEntry as? LeafEntryAccessor)
        ?.functions?.filterIsInstance<CopyComponentsLootFunction>()?.forEach {
            (it as CCLFTouch).`mod$touch`(listOf(DataComponentTypes.RARITY))
        }
}

Where server is MinecraftServer instance, CCLFTouch is a defined interface, LootTableAccessor and LeafEntryAccessor are used to access certain private fields, which are trivial.

Affects 19w04b, and also occurs when /fill is used to remove campfires