Skip to content

fix editBook sending invalid packet in 1.13+#3677

Open
autowert66 wants to merge 8 commits intoPrismarineJS:masterfrom
autowert66:master
Open

fix editBook sending invalid packet in 1.13+#3677
autowert66 wants to merge 8 commits intoPrismarineJS:masterfrom
autowert66:master

Conversation

@autowert66
Copy link
Copy Markdown
Contributor

After Minecraft 1.17, the packet for editing a book changed.
To support writing newer books, a feature editBookPacketUsesNbt was added, and #3373 updated the code for writing books to use that feature and send the correct package.

However, after checking for the feature, the wrong code gets executed (uses nbt -> non-nbt packet is sent, and vice versa). This effectively breaks all book functionality since the introduction of the book edit packet.

This PR fixes this by updating the packet sent in each case.

Test Results

See source.

version pr upstream
1.8.9 ✔ Success ✔ Success
1.9.4 ✔ Success ✔ Success
1.10.2 ✔ Success ✔ Success
1.11.2 ✔ Success ✔ Success
1.12.2 ✔ Success ✔ Success
1.13.2 ✔ Success
✖ Error
TypeError: SizeOf error for undefined : Cannot read properties of undefined (reading 'present')
at Object.slot (eval at compile (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:262:12), <anonymous>:82:27)
at Object.packet_edit_book (eval at compile (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:262:12), <anonymous>:429:25)
at eval (eval at compile (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:262:12), <anonymous>:894:58)
at packet (eval at compile (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:262:12), <anonymous>:937:9)
at CompiledProtodef.sizeOf (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:89:14)
at e.message (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:96:40)
at tryCatch (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/utils.js:50:16)
at CompiledProtodef.createPacketBuffer (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:96:20)
at Serializer.createPacketBuffer (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/serializer.js:12:23)
at Serializer._transform (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/serializer.js:18:18) {
field: 'play.toServer'
}
1.14.4 ✔ Success
✖ Error
TypeError: SizeOf error for undefined : Cannot read properties of undefined (reading 'present')
at Object.slot (eval at compile (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:262:12), <anonymous>:83:27)
at Object.packet_edit_book (eval at compile (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:262:12), <anonymous>:482:25)
at eval (eval at compile (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:262:12), <anonymous>:976:58)
at packet (eval at compile (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:262:12), <anonymous>:1021:9)
at CompiledProtodef.sizeOf (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:89:14)
at e.message (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:96:40)
at tryCatch (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/utils.js:50:16)
at CompiledProtodef.createPacketBuffer (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:96:20)
at Serializer.createPacketBuffer (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/serializer.js:12:23)
at Serializer._transform (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/serializer.js:18:18) {
field: 'play.toServer'
}
1.15.2 ✔ Success
✖ Error
TypeError: SizeOf error for undefined : Cannot read properties of undefined (reading 'present')
at Object.slot (eval at compile (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:262:12), <anonymous>:83:27)
at Object.packet_edit_book (eval at compile (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:262:12), <anonymous>:482:25)
at eval (eval at compile (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:262:12), <anonymous>:976:58)
at packet (eval at compile (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:262:12), <anonymous>:1021:9)
at CompiledProtodef.sizeOf (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:89:14)
at e.message (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:96:40)
at tryCatch (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/utils.js:50:16)
at CompiledProtodef.createPacketBuffer (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:96:20)
at Serializer.createPacketBuffer (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/serializer.js:12:23)
at Serializer._transform (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/serializer.js:18:18) {
field: 'play.toServer'
}
1.16.5 ✔ Success
✖ Error
TypeError: SizeOf error for undefined : Cannot read properties of undefined (reading 'present')
at Object.slot (eval at compile (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:262:12), <anonymous>:84:27)
at Object.packet_edit_book (eval at compile (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:262:12), <anonymous>:483:25)
at eval (eval at compile (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:262:12), <anonymous>:967:58)
at packet (eval at compile (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:262:12), <anonymous>:1014:9)
at CompiledProtodef.sizeOf (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:89:14)
at e.message (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:96:40)
at tryCatch (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/utils.js:50:16)
at CompiledProtodef.createPacketBuffer (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:96:20)
at Serializer.createPacketBuffer (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/serializer.js:12:23)
at Serializer._transform (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/serializer.js:18:18) {
field: 'play.toServer'
}
1.17 ✔ Success
✖ Error
TypeError: SizeOf error for undefined : Cannot read properties of undefined (reading 'present')
at Object.slot (eval at compile (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:262:12), <anonymous>:84:27)
at Object.packet_edit_book (eval at compile (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:262:12), <anonymous>:519:25)
at eval (eval at compile (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:262:12), <anonymous>:1014:58)
at packet (eval at compile (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:262:12), <anonymous>:1061:9)
at CompiledProtodef.sizeOf (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:89:14)
at e.message (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:96:40)
at tryCatch (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/utils.js:50:16)
at CompiledProtodef.createPacketBuffer (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:96:20)
at Serializer.createPacketBuffer (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/serializer.js:12:23)
at Serializer._transform (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/serializer.js:18:18) {
field: 'play.toServer'
}
1.17.1
✖ Error
TypeError: SizeOf error for undefined : Cannot read properties of undefined (reading 'length')
at eval (eval at compile (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:262:12), <anonymous>:522:39)
at Object.packet_edit_book (eval at compile (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:262:12), <anonymous>:527:9)
at eval (eval at compile (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:262:12), <anonymous>:1027:58)
at packet (eval at compile (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:262:12), <anonymous>:1074:9)
at CompiledProtodef.sizeOf (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:89:14)
at e.message (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:96:40)
at tryCatch (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/utils.js:50:16)
at CompiledProtodef.createPacketBuffer (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:96:20)
at Serializer.createPacketBuffer (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/serializer.js:12:23)
at Serializer._transform (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/serializer.js:18:18) {
field: 'play.toServer'
}
✔ Success
1.18.2 ✔ Success
✖ Error
TypeError: SizeOf error for undefined : Cannot read properties of undefined (reading 'length')
at eval (eval at compile (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:262:12), <anonymous>:541:39)
at Object.packet_edit_book (eval at compile (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:262:12), <anonymous>:546:9)
at eval (eval at compile (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:262:12), <anonymous>:1048:58)
at packet (eval at compile (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:262:12), <anonymous>:1095:9)
at CompiledProtodef.sizeOf (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:89:14)
at e.message (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:96:40)
at tryCatch (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/utils.js:50:16)
at CompiledProtodef.createPacketBuffer (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:96:20)
at Serializer.createPacketBuffer (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/serializer.js:12:23)
at Serializer._transform (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/serializer.js:18:18) {
field: 'play.toServer'
}
1.19.4 ✔ Success
✖ Error
TypeError: SizeOf error for undefined : Cannot read properties of undefined (reading 'length')
at eval (eval at compile (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:262:12), <anonymous>:793:39)
at Object.packet_edit_book (eval at compile (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:262:12), <anonymous>:798:9)
at eval (eval at compile (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:262:12), <anonymous>:1340:58)
at packet (eval at compile (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:262:12), <anonymous>:1380:9)
at CompiledProtodef.sizeOf (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:89:14)
at e.message (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:96:40)
at tryCatch (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/utils.js:50:16)
at CompiledProtodef.createPacketBuffer (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:96:20)
at Serializer.createPacketBuffer (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/serializer.js:12:23)
at Serializer._transform (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/serializer.js:18:18) {
field: 'play.toServer'
}
1.20.6 ✔ Success
✖ Error
TypeError: SizeOf error for undefined : Cannot read properties of undefined (reading 'length')
at eval (eval at compile (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:262:12), <anonymous>:1694:39)
at Object.packet_edit_book (eval at compile (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:262:12), <anonymous>:1699:9)
at eval (eval at compile (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:262:12), <anonymous>:2154:58)
at packet (eval at compile (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:262:12), <anonymous>:2194:9)
at CompiledProtodef.sizeOf (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:89:14)
at e.message (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:96:40)
at tryCatch (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/utils.js:50:16)
at CompiledProtodef.createPacketBuffer (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:96:20)
at Serializer.createPacketBuffer (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/serializer.js:12:23)
at Serializer._transform (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/serializer.js:18:18) {
field: 'play.toServer'
}
1.21.5 ✔ Success
✖ Error
TypeError: SizeOf error for undefined : Cannot read properties of undefined (reading 'length')
at eval (eval at compile (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:262:12), <anonymous>:1892:39)
at Object.packet_edit_book (eval at compile (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:262:12), <anonymous>:1897:9)
at eval (eval at compile (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:262:12), <anonymous>:2354:58)
at packet (eval at compile (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:262:12), <anonymous>:2394:9)
at CompiledProtodef.sizeOf (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:89:14)
at e.message (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:96:40)
at tryCatch (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/utils.js:50:16)
at CompiledProtodef.createPacketBuffer (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/compiler.js:96:20)
at Serializer.createPacketBuffer (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/serializer.js:12:23)
at Serializer._transform (/booktest/node_modules/.pnpm/protodef@1.19.0/node_modules/protodef/src/serializer.js:18:18) {
field: 'play.toServer'
}

The error in version 1.17.1 is related to a previously incorrect version range for the editBookPacketUsesNbt feature, which was fixed in PrismarineJS/minecraft-data#1013 and will be resolved once PrismarineJS/node-minecraft-data updates minecraft-data.

@autowert66
Copy link
Copy Markdown
Contributor Author

Should fix #3495

autowert66 and others added 7 commits April 2, 2026 06:10
Verifies that the edit_book packet sends the correct fields for both
NBT-based versions (1.13-1.16.5) and non-NBT versions (1.17.1+),
ensuring the fix for swapped packet fields is covered by tests.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Exercises both writeBook and signBook from a non-hotbar inventory slot,
verifying that the edit_book packet field assignments work correctly
across NBT and non-NBT code paths.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The editBook test was added but immediately excluded, meaning it never
actually ran in CI. Remove it from the excludedTests array so the test
exercises the writeBook/signBook code path it was written to validate.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
In MC 1.20.5+ the server returns book items using structured components
(writable_book_content / written_book_content) instead of NBT, so
book.nbt is null and accessing book.nbt.value.pages throws.

Additionally, for some versions the server may not echo back page data
in the set_slot response for writable_book at all.

This commit adds helper functions that extract pages, title, and author
from either the legacy NBT format or the new componentMap, and makes
content assertions conditional on the data actually being present.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants