Repository: PaperMC/Paper
File: paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java (Java)

Code before:
        this.getHandle().maxHealthCache = this.getMaxHealth();
    }

    @Override
    public void sendHealthUpdate(double health, int foodLevel, float saturation) {
        this.getHandle().connection.send(new ClientboundSetHealthPacket((float) health, foodLevel, saturation));
    }

    @Override
    public void sendHealthUpdate() {
        FoodData foodData = this.getHandle().getFoodData();
        // Paper start - cancellable death event
        ClientboundSetHealthPacket packet = new ClientboundSetHealthPacket(this.getScaledHealth(), foodData.getFoodLevel(), foodData.getSaturationLevel());
        if (this.getHandle().queueHealthUpdatePacket) {
            this.getHandle().queuedHealthUpdatePacket = packet;
        } else {
            this.getHandle().connection.send(packet);
        }
        // Paper end
    }

    public void injectScaledMaxHealth(Collection<AttributeInstance> collection, boolean force) {
        if (!this.scaledHealth && !force) {
            return;
        }
        Iterator<AttributeInstance> iterator = collection.iterator();
        while (iterator.hasNext()) {
            AttributeInstance genericInstance = iterator.next();
            if (genericInstance.getAttribute() == Attributes.MAX_HEALTH) {
                iterator.remove();
                break;
            }
        }
        collection.add(getScaledMaxHealth());
    }

    public AttributeInstance getScaledMaxHealth() {
        AttributeInstance dummy = new AttributeInstance(Attributes.MAX_HEALTH, (attribute) -> { });
        double healthMod = this.scaledHealth ? this.healthScale : this.getMaxHealth();
        if (healthMod >= Float.MAX_VALUE || healthMod <= 0) {
            healthMod = 20; // Reset health
            this.getServer().getLogger().warning(this.getName() + " tried to crash the server with a large health attribute");
        }
        dummy.setBaseValue(healthMod);
        return dummy;
    }

    @Override
    public org.bukkit.entity.Entity getSpectatorTarget() {
        Entity followed = this.getHandle().getCamera();
        return followed == this.getHandle() ? null : followed.getBukkitEntity();

Review comment (suggestion):
I would not override this. The behavior is a bit different here in that it resolves the book item.
Your improvement to openBook on adventure is fine tho, but I would keep this the same.

Calling openItemGui is a bit different, so this should be kept the same, only adventure book should be changed.

Code after:
        // Paper start - Locale change event
        final String locale = this.getHandle().language;
        return locale != null ? locale : "en_us";
        // Paper end
    }

    // Paper start
    public void setAffectsSpawning(boolean affects) {
        this.getHandle().affectsSpawning = affects;
    }

    @Override
    public boolean getAffectsSpawning() {
        return this.getHandle().affectsSpawning;
    }
    // Paper end

    @Override
    public void updateCommands() {
        if (this.getHandle().connection == null) return;

        this.server.getServer().getCommands().sendCommands(this.getHandle());
    }

    @Override
    public void openSign(@NonNull Sign sign, @NonNull Side side) {
        CraftSign.openSign(sign, this, side);
    }

    @Override
    public void openVirtualSign(Position block, Side side) {
        if (this.getHandle().connection == null) return;

        this.getHandle().connection.send(new ClientboundOpenSignEditorPacket(MCUtil.toBlockPos(block), side == Side.FRONT));
    }

    @Override
    public void showDemoScreen() {
        if (this.getHandle().connection == null) return;

        this.getHandle().connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.DEMO_EVENT, ClientboundGameEventPacket.DEMO_PARAM_INTRO));
    }

    @Override
    public boolean isAllowingServerListings() {
        return this.getHandle().allowsListing();
    }

    // Paper start
    @Override
    public net.kyori.adventure.text.Component displayName() {