Skip to content

fix: store the hidden book glint on the books, not in packets - #54

Merged
XxFran10xX merged 1 commit into
mainfrom
fix/book-glint-real-items
Oct 20, 2026
Merged

XxFran10xX merged 1 commit into
mainfrom
fix/book-glint-real-items

Conversation

@XxFran10xX

Copy link
Copy Markdown
Contributor

Problem

A player reported that placing a letter in a barrel leaves a fake copy of it on the mouse cursor.

Since 1.21.5, every inventory click sends the server a hash of each stack the client sees. BookGlintHider changed the glint on signed books only in outgoing inventory packets, so the client's copy of every letter or signed book never matched the server's. Paper resyncs a mismatched cursor with ClientboundSetCursorItemPacket, which carries no state id. If that resync from the pick-up click arrives after the client has already placed the book, the client puts the book back on its cursor. The place click reported an empty cursor, which matches the server, so nothing ever corrects it.

Fix

  • New BookGlintStamper stores the glint override (false) on real signed books, so client and server hold the same item.
    • Player inventories are swept every second. Containers in the world are updated when opened: blocks, double chests, entities, and the player's own ender chest.
    • Lecterns are skipped, and so are menus opened with the player or a plugin object as holder, so plugin icons are never changed.
    • Stamped books are tagged tfmccore:hidden_glint. With hide-book-glint: false, only tagged books get their glint back. Books with their own override are never touched.
    • Players are skipped for 5 ticks after editing or using a signed book. ArmourShop (sign skin) and BirdMessenger (open letter) compare the book with their own copy a tick later.
  • BookGlintHider now only rewrites entity packets (dropped items, item frames, displays, equipment), for books the stamper hasn't reached yet. It no longer touches inventory or creative packets.

Testing

  • mvn verify: 827 tests pass, and the 100% line coverage gate passes.
  • Baseline on TFMCDev01 with the old 3.8.1 jar: a fresh book reaches the client with glint off while the server's book has no override. That mismatch causes the ghost.
  • Bot test on TFMCDev01 with this jar (~/glint-test/test.js, real character bot), 21/21 pass:
    • A fresh book's packet is not rewritten.
    • The book is stamped on the server within the sweep, and the client sees the stored item.
    • No inventory packet carried a packet-only glint.
    • Books in a barrel and in the ender chest are stamped on open.
    • Letter flow works: sign → sealed and stamped → placed in a barrel (cursor empty) → opens into an opened letter.
    • An ArmourShop skinned book keeps its signed skin.
    • Option off restores only tagged books (containers on open); option on stamps them again.
    • A dropped book is still shown without glint.

Mineflayer doesn't compute real item hashes, so a bot can't replay the exact click race. With no inventory packet rewritten, a real client now hashes exactly the item the server holds.

Notes

  • Stamped books carry one extra PDC byte. Until the sweep reaches an identical copy that was never stamped, the two won't stack. If a shop compares a stored template of a written book exactly, the template may need re-saving.
  • Unrelated, seen while testing: BirdMessenger breaks a letter's seal on any block right-click while the letter is held, including opening a barrel.

🤖 Generated with Claude Code

Clients hash every stack they click (1.21.5+). Books whose glint was
hidden only in inventory packets never matched the server's copy, so
each click resent the cursor; a resend arriving after the next click
left a ghost book on the cursor (e.g. placing a letter in a barrel).

BookGlintStamper now sets the glint override on real signed books in
player inventories (every second) and in containers when opened,
tagged with tfmccore:hidden_glint so turning the option off restores
only those. BookGlintHider keeps hiding books shown on entities only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@XxFran10xX

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: c487c77f-b25d-4258-97e3-c89a428f3fb2
📥 Commits

Reviewing files that changed from the base of the PR and between efea59f and f7868a2.

📒 Files selected for processing: 8
  • README.md
  • src/main/java/net/tfminecraft/tfmccore/TFMCCore.java
  • src/main/java/net/tfminecraft/tfmccore/books/BookGlintHider.java
  • src/main/java/net/tfminecraft/tfmccore/books/BookGlintStamper.java
  • src/main/resources/config.yml
  • src/test/java/net/tfminecraft/tfmccore/PluginLifecycleCoverageTest.java
  • src/test/java/net/tfminecraft/tfmccore/books/BookGlintHiderTest.java
  • src/test/java/net/tfminecraft/tfmccore/books/BookGlintStamperTest.java

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

📝 Summary

Summary by CodeRabbit

  • New Features

    • Book glint visibility is now synchronised for signed books in player inventories, storage containers and ender chests.
    • Glint settings are applied more consistently when books are opened, edited or interacted with.
    • Previously hidden glints are restored when the setting is disabled.
  • Bug Fixes

    • Improved book glint handling for equipment and entity metadata displays.
  • Documentation

    • Updated configuration guidance covering inventory updates, tagging behaviour and supported display scenarios.

The change adds a listener that applies or restores glint overrides on signed written books in eligible inventories. It also narrows packet handling to entity equipment and metadata packets and registers the listener at startup.

Changes: Book glint handling

Layer / File(s) Summary
Written-book glint updates
src/main/java/net/tfminecraft/tfmccore/books/BookGlintStamper.java, src/test/java/net/tfminecraft/tfmccore/books/BookGlintStamperTest.java, src/main/resources/config.yml, README.md
BookGlintStamper updates eligible signed written books when inventories open and during a 20-tick sweep. It tags books when hiding is enabled, restores their default glint when hiding is disabled, and suppresses sweeps for five ticks after relevant player actions. Tests and documentation cover this behaviour.
Packet handling and plugin registration
src/main/java/net/tfminecraft/tfmccore/TFMCCore.java, src/main/java/net/tfminecraft/tfmccore/books/BookGlintHider.java, src/test/java/net/tfminecraft/tfmccore/PluginLifecycleCoverageTest.java, src/test/java/net/tfminecraft/tfmccore/books/BookGlintHiderTest.java
Startup registers BookGlintStamper. BookGlintHider handles entity equipment and metadata packets, with no inventory or creative-client packet handling. Tests verify listener registration and packet whitelists.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix

Sequence Diagram(s)

sequenceDiagram
  participant InventoryOpenEvent
  participant BukkitScheduler
  participant BookGlintStamper
  participant Cache
  participant Inventory
  opt A storage inventory opens
    InventoryOpenEvent->>BookGlintStamper: Update eligible inventory
    BookGlintStamper->>Cache: Read hideBookGlint
    BookGlintStamper->>Inventory: Inspect and update written books
  end
  opt A scheduled sweep runs
    BukkitScheduler->>BookGlintStamper: Run sweep every 20 ticks
    BookGlintStamper->>Cache: Read hideBookGlint
    BookGlintStamper->>Inventory: Inspect and update eligible inventories
  end
Loading

Suggested reviewers: ryanbarlow97

Merge Risk: ⚪ Minimal · up to f7868

No merge-blocking issue was established. Books placed into an already-open container are updated when that container is reopened, consistent with the documented behavior.

- [ ] Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added the size:L 100-499 effective changed lines (tests excluded in mixed PRs). label Oct 20, 2026
@coderabbitai

coderabbitai Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@XxFran10xX
XxFran10xX merged commit 0c47510 into main Oct 20, 2026
3 checks passed
@XxFran10xX
XxFran10xX deleted the fix/book-glint-real-items branch October 20, 2026 07:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L 100-499 effective changed lines (tests excluded in mixed PRs).

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant