From d9ceee01b5785c8c13d105a995bad77df0737e4d Mon Sep 17 00:00:00 2001 From: NotAPenguin Date: Tue, 20 Aug 2024 13:43:45 +0200 Subject: [PATCH 1/2] fix crash when metadata array is empty --- .../com/gtnewhorizons/postea/utility/ChunkFixerUtility.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/gtnewhorizons/postea/utility/ChunkFixerUtility.java b/src/main/java/com/gtnewhorizons/postea/utility/ChunkFixerUtility.java index 30d73cc..4558f62 100644 --- a/src/main/java/com/gtnewhorizons/postea/utility/ChunkFixerUtility.java +++ b/src/main/java/com/gtnewhorizons/postea/utility/ChunkFixerUtility.java @@ -66,7 +66,10 @@ public class ChunkFixerUtility { for (int index = 0; index < blockArray.length / 2; index++) { // Horrible bit jank to recreate the actual IDs, because the array is just a byte array. int blockId = ((blockArray[index * 2] & 0xFF) << 8) | (blockArray[index * 2 + 1] & 0xFF); - int metadata = ((metadataArray[index * 2] & 0xFF) << 8) | (metadataArray[index * 2 + 1] & 0xFF); + // If metadata is all zeroes, it isn't stored, so simply check the length and assign zero to + // metadata if it's empty. + int metadata = (metadataArray.length == 0) ? 0 + : (((metadataArray[index * 2] & 0xFF) << 8) | (metadataArray[index * 2 + 1] & 0xFF)); // Skip air. if (blockId == AIR_ID) continue; From ec2b6a90070bc866b490b429bc7df7cd124485ab Mon Sep 17 00:00:00 2001 From: NotAPenguin Date: Tue, 20 Aug 2024 14:00:44 +0200 Subject: [PATCH 2/2] More proper fix --- .../postea/utility/ChunkFixerUtility.java | 25 ++++++++++++++++--- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/gtnewhorizons/postea/utility/ChunkFixerUtility.java b/src/main/java/com/gtnewhorizons/postea/utility/ChunkFixerUtility.java index 4558f62..5237e46 100644 --- a/src/main/java/com/gtnewhorizons/postea/utility/ChunkFixerUtility.java +++ b/src/main/java/com/gtnewhorizons/postea/utility/ChunkFixerUtility.java @@ -60,16 +60,22 @@ public class ChunkFixerUtility { // Blocks16 and Data16 exist only because of NEID. byte[] blockArray = section.getByteArray("Blocks16"); byte[] metadataArray = section.getByteArray("Data16"); + // If metadata array is empty, it was all zeroes. We create a new array to write our new values to, + // and only save this when a nonzero value was written + boolean wasAllZero = false; + if (metadataArray.length == 0) { + wasAllZero = true; + metadataArray = new byte[8192]; + } + // Keep track of if we write a nonzero element to the metadata array + boolean hasWrittenNonZero = false; byte sectionY = section.getByte("Y"); for (int index = 0; index < blockArray.length / 2; index++) { // Horrible bit jank to recreate the actual IDs, because the array is just a byte array. int blockId = ((blockArray[index * 2] & 0xFF) << 8) | (blockArray[index * 2 + 1] & 0xFF); - // If metadata is all zeroes, it isn't stored, so simply check the length and assign zero to - // metadata if it's empty. - int metadata = (metadataArray.length == 0) ? 0 - : (((metadataArray[index * 2] & 0xFF) << 8) | (metadataArray[index * 2 + 1] & 0xFF)); + int metadata = ((metadataArray[index * 2] & 0xFF) << 8) | (metadataArray[index * 2 + 1] & 0xFF); // Skip air. if (blockId == AIR_ID) continue; @@ -87,6 +93,11 @@ public class ChunkFixerUtility { blockConversionInfo.blockName = blockName; blockConversionInfo.blockID = blockId; blockConversionInfo.metadata = (byte) metadata; // Updated + // If we wrote a nonzero metadata, keep track of this because it means the + // new array needs to be written back to NBT + if (metadata != 0) { + hasWrittenNonZero = true; + } blockConversionInfo.world = world; int x = index % 16; @@ -110,6 +121,12 @@ public class ChunkFixerUtility { metadataArray[index * 2 + 1] = (byte) (newMetadata & 0xFF); } } + + // After processing all replacements, if we made a new metadata array and wrote a nonzero value to it, + // write it back to world NBT to save + if (wasAllZero && hasWrittenNonZero) { + section.setByteArray("Data16", metadataArray); + } } }