diff options
| author | Marlian <84173858+MCbabel@users.noreply.github.com> | 2026-03-10 04:02:39 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-03-09 22:02:39 -0500 |
| commit | 3bcf588fbe041bd9d81f51348c3e98876dc9d4e2 (patch) | |
| tree | af3dfc0f2e28ed9f2e7cb752eb410ec55a4d4df0 /Minecraft.Client/Common | |
| parent | 58c236ead5c35248a9c993c7b296e41c2799d305 (diff) | |
Fix crash when loading saved tutorial worlds (#1001)
writeRuleFile() was missing the schematic file count integer before the schematic entries. The reader in readRuleFile() expected this count, causing a stream misalignment that led to an assertion failure (Unrecognised schematic version) when reloading a saved tutorial world.
The fix writes the count on save and adds backward-compatible reading that detects old saves (without count) via a peek heuristic and falls back to count-less parsing.
Co-authored-by: MCbabel <MCbabel@users.noreply.github.com>
Diffstat (limited to 'Minecraft.Client/Common')
| -rw-r--r-- | Minecraft.Client/Common/GameRules/GameRuleManager.cpp | 38 |
1 files changed, 29 insertions, 9 deletions
diff --git a/Minecraft.Client/Common/GameRules/GameRuleManager.cpp b/Minecraft.Client/Common/GameRules/GameRuleManager.cpp index ff294a65..95434c08 100644 --- a/Minecraft.Client/Common/GameRules/GameRuleManager.cpp +++ b/Minecraft.Client/Common/GameRules/GameRuleManager.cpp @@ -344,6 +344,7 @@ void GameRuleManager::writeRuleFile(DataOutputStream *dos) // Write schematic files. unordered_map<wstring, ConsoleSchematicFile *> *files; files = getLevelGenerationOptions()->getUnfinishedSchematicFiles(); + dos->writeInt((int)files->size()); for ( auto& it : *files ) { const wstring& filename = it.first; @@ -497,17 +498,36 @@ bool GameRuleManager::readRuleFile(LevelGenerationOptions *lgo, byte *dIn, UINT }*/ // subfile + // Old saves didn't write a numFiles count before the schematic entries. + // Detect this: a real count is small, but a UTF filename prefix reads as a large int. UINT numFiles = contentDis->readInt(); - for (UINT i = 0; i < numFiles; i++) - { - wstring sFilename = contentDis->readUTF(); - int length = contentDis->readInt(); - byteArray ba( length ); - - contentDis->read(ba); - - levelGenerator->loadSchematicFile(sFilename, ba.data, ba.length); + if (lgo->isFromSave() && numFiles > 100) + { + contentDis->skip(-4); + while (true) + { + int peek = contentDis->readInt(); + if (peek <= 100) { contentDis->skip(-4); break; } + contentDis->skip(-4); + + wstring sFilename = contentDis->readUTF(); + int length = contentDis->readInt(); + byteArray ba( length ); + contentDis->read(ba); + levelGenerator->loadSchematicFile(sFilename, ba.data, ba.length); + } + } + else + { + for (UINT i = 0; i < numFiles; i++) + { + wstring sFilename = contentDis->readUTF(); + int length = contentDis->readInt(); + byteArray ba( length ); + contentDis->read(ba); + levelGenerator->loadSchematicFile(sFilename, ba.data, ba.length); + } } LEVEL_GEN_ID lgoID = LEVEL_GEN_ID_NULL; |
