Skip to content

Commit e5de022

Browse files
committed
fix 1.7.10 chunk reading + tests
This only happens with custom servers, vanilla does not use the single chunk packet, only the batched chunk packet (always 5 afaik). This was seen on via backwards. Reported by Couleur on matrix.
1 parent 59c343d commit e5de022

File tree

6 files changed

+38
-17
lines changed

6 files changed

+38
-17
lines changed

src/integration-test/kotlin/de/bixilon/minosoft/protocol/packets/s2c/play/chunk/ChunkS2CPTest.kt

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* Minosoft
3-
* Copyright (C) 2020-2025 Moritz Zwerger
3+
* Copyright (C) 2020-2026 Moritz Zwerger
44
*
55
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
66
*
@@ -120,6 +120,30 @@ class ChunkS2CPTest {
120120
assertEquals(blocks[4]!![4, 3, 4]!!.block.identifier, MinecraftBlocks.STONE)
121121
}
122122

123+
fun `viabackwards 1_8_9`() {
124+
val packet = read("viabackwards_1_8_9", "1.8.9", dimension = DimensionProperties(light = true, skyLight = true, minY = 0, height = 256))
125+
assertEquals(packet.position, ChunkPosition(5843 - 1))
126+
val blocks = packet.prototype.blocks
127+
assertNotNull(blocks); blocks!!
128+
129+
assertEquals(blocks[4]!![0, 0, 0]!!.block.identifier, MinecraftBlocks.STONE)
130+
assertEquals(blocks[5]!![129]!!.block.identifier, MinecraftBlocks.TERRACOTTA)
131+
assertEquals(blocks[5]!![205]!!.block.identifier, MinecraftBlocks.TERRACOTTA)
132+
assertEquals(blocks[6]!![361]!!.block.identifier, MinecraftBlocks.COBBLESTONE_WALL)
133+
}
134+
135+
fun `viabackwards 1_7_10`() {
136+
val packet = read("viabackwards_1_7_10", "1.7.10", dimension = DimensionProperties(light = true, skyLight = true, minY = 0, height = 256))
137+
assertEquals(packet.position, ChunkPosition(5843 - 1))
138+
val blocks = packet.prototype.blocks
139+
assertNotNull(blocks); blocks!!
140+
141+
assertEquals(blocks[4]!![0, 0, 0]!!.block.identifier, MinecraftBlocks.STONE)
142+
assertEquals(blocks[5]!![129]!!.block.identifier, MinecraftBlocks.TERRACOTTA)
143+
assertEquals(blocks[5]!![205]!!.block.identifier, MinecraftBlocks.TERRACOTTA)
144+
assertEquals(blocks[6]!![361]!!.block.identifier, MinecraftBlocks.COBBLESTONE_WALL)
145+
}
146+
123147
// fun benchmark() {
124148
// val start = now()
125149
// for (i in 0 until 10000) {
Binary file not shown.
Binary file not shown.

src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/block/chunk/ChunkS2CP.kt

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* Minosoft
3-
* Copyright (C) 2020-2025 Moritz Zwerger
3+
* Copyright (C) 2020-2026 Moritz Zwerger
44
*
55
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
66
*
@@ -58,7 +58,7 @@ class ChunkS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket {
5858
val prototype: ChunkData = ChunkData()
5959
var action: ChunkAction = ChunkAction.CREATE
6060
private set
61-
private lateinit var readingData: ChunkReadingData
61+
private var readingData: ChunkReadingData? = null
6262

6363
init {
6464
val dimension = buffer.session.world.dimension
@@ -67,15 +67,12 @@ class ChunkS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket {
6767
action = if (buffer.readBoolean()) ChunkAction.CREATE else ChunkAction.UPDATE
6868
}
6969
if (buffer.versionId < V_14W26A) { // ToDo
70-
val sectionBitMask = BitSet.valueOf(buffer.readByteArray(2))
71-
val addBitMask = BitSet.valueOf(buffer.readByteArray(2))
70+
val sectionBitMask = buffer.readLegacyBitSet(2)
71+
val addBitMask = buffer.readLegacyBitSet(2)
7272

7373
// decompress chunk data
74-
val decompressed: PlayInByteBuffer = if (buffer.versionId < V_14W28A) {
75-
PlayInByteBuffer(buffer.readByteArray(buffer.readInt()).decompress(), buffer.session)
76-
} else {
77-
buffer
78-
}
74+
val decompressed = if (buffer.versionId < V_14W28A) PlayInByteBuffer(buffer.readByteArray(buffer.readInt()).decompress(), buffer.session) else buffer
75+
7976
val chunkData = ChunkPacketUtil.readChunkPacket(decompressed, dimension, sectionBitMask, addBitMask, action == ChunkAction.CREATE, dimension.skyLight)
8077
if (chunkData == null) {
8178
action = ChunkAction.UNLOAD
@@ -175,7 +172,7 @@ class ChunkS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket {
175172
}
176173

177174
private fun ChunkReadingData.readChunkData() {
178-
val chunkData = if (readingData.buffer.versionId < V_21W37A) ChunkPacketUtil.readChunkPacket(buffer, dimension, sectionBitMask!!, null, action == ChunkAction.CREATE, dimension.skyLight) else ChunkPacketUtil.readPaletteChunk(buffer, dimension, null, complete = true, skylight = false)
175+
val chunkData = if (buffer.versionId < V_21W37A) ChunkPacketUtil.readChunkPacket(buffer, dimension, sectionBitMask!!, null, action == ChunkAction.CREATE, dimension.skyLight) else ChunkPacketUtil.readPaletteChunk(buffer, dimension, null, complete = true, skylight = false)
179176
ALLOCATOR.free(data)
180177
if (chunkData == null) {
181178
action = ChunkAction.UNLOAD
@@ -185,7 +182,7 @@ class ChunkS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket {
185182
}
186183

187184
fun parse() {
188-
this.readingData.readChunkData()
185+
this.readingData?.readChunkData()
189186
}
190187

191188
override fun handle(session: PlaySession) {

src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/sign/SignTextS2CP.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* Minosoft
3-
* Copyright (C) 2020-2025 Moritz Zwerger
3+
* Copyright (C) 2020-2026 Moritz Zwerger
44
*
55
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
66
*
@@ -36,6 +36,6 @@ class SignTextS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket {
3636
}
3737

3838
override fun log(reducedLog: Boolean) {
39-
Log.log(LogMessageType.NETWORK_IN, level = LogLevels.VERBOSE) { "Sign text (position=$position, lines=$lines" }
39+
Log.log(LogMessageType.NETWORK_IN, level = LogLevels.VERBOSE) { "Sign text (position=$position, lines=${lines.contentToString()}" }
4040
}
4141
}

src/main/java/de/bixilon/minosoft/util/KUtil.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* Minosoft
3-
* Copyright (C) 2020-2025 Moritz Zwerger
3+
* Copyright (C) 2020-2026 Moritz Zwerger
44
*
55
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
66
*
@@ -240,10 +240,10 @@ object KUtil {
240240
}
241241

242242
fun PlayInByteBuffer.dump(name: String) {
243-
val pointer = offset
243+
val offset = this@dump.offset
244244
this.offset = data.offset
245245
val data = readRemaining()
246-
this.offset = pointer
246+
this.offset = offset
247247

248248
val path = "/home/moritz/${name}_${Versions.getById(this.versionId)?.name?.replace(".", "_")}.bin"
249249
val stream = FileOutputStream(path)

0 commit comments

Comments
 (0)