Skip to content

Lectern on 1.21.11 crashes / breaks on Cardboard due to invalid casts and null Bukkit player #560

Description

@Kexs21

Environment

  • Cardboard branch/build: ver/1.21.11, official 1.21.11-14, also reproduced on self-built patched jar
  • Minecraft: 1.21.11
  • Fabric Loader: 0.18.6
  • Java: 21
  • Server mode: online-mode=false
  • Plugins used when reproducing: reproducible even without Bukkit plugins loaded
  • Mods: Fabric server with mods; lectern works in singleplayer with same mods

Problem
Interacting with a lectern on Cardboard 1.21.11 is broken.

Initial behavior:

  • Opening a lectern with a book caused a ClassCastException in LecternMenuMixin#setPlayerInv
  • Root cause: Container passed to LecternMenu(int, Container, ContainerData) was cast to player Inventory, but for lecterns it is not a player inventory

After patching that:

  • Opening the lectern started working
  • Then taking the book caused a NullPointerException because this.player in CraftInventoryView was null
  • I patched this by setting the Bukkit player in ServerPlayerMixin#openHandledScreen_c before the inventory open event for LecternMenu

After that:

  • Opening the lectern works
  • Taking the book works
  • But PlayerTakeLecternBookEvent still logs an error in WorldGuard because CraftInventoryLectern#getHolder() expects ContainerBridge, while the lectern container is not always a ContainerBridge

Observed errors

  1. Original open crash:
java.lang.ClassCastException: class net.minecraft.class_3722$1 cannot be cast to class net.minecraft.class_1661
at ... LecternMenuMixin#setPlayerInv
  1. After first patch:
java.lang.NullPointerException: Cannot invoke "org.bukkit.craftbukkit.entity.CraftHumanEntity.getInventory()" because "this.player" is null
  1. Current remaining issue when taking the book:
Could not pass event PlayerTakeLecternBookEvent to WorldGuard
java.lang.ClassCastException: class net.minecraft.class_3722$1 cannot be cast to class org.cardboardpowered.bridge.world.ContainerBridge
at org.bukkit.craftbukkit.inventory.CraftInventoryLectern.getHolder(CraftInventoryLectern.java:17)

Vanilla source context
LecternMenu in 1.21.11 only has:

  • LecternMenu(int)
  • LecternMenu(int, Container, ContainerData)

So the mixin assumption that the second argument is always Inventory is invalid for lecterns.

Suggested fix direction

  • Do not cast the Container in LecternMenuMixin#setPlayerInv to Inventory without an instanceof check
  • Populate the Bukkit player for LecternMenu later, at menu-open time, where the actual ServerPlayer is known
  • Make CraftInventoryLectern#getHolder() safe when the backing inventory is not a ContainerBridge

Reproduction

  1. Start Cardboard 1.21.11 server
  2. Place lectern
  3. Put written book into lectern
  4. Right click lectern
  5. Try to take the book

Result
Lectern behavior is broken unless Cardboard is manually patched.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions