mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-10 07:48:29 -04:00
chunk reading: check early if data is empty
Now it does not allocate chunk data when the section is truly empty (servers sometimes send the opposite and then it turns out that they are empty)
This commit is contained in:
parent
1b869e4761
commit
d3dfcb2a92
@ -15,6 +15,7 @@ package de.bixilon.minosoft.data.world.container.palette
|
|||||||
|
|
||||||
import de.bixilon.minosoft.data.registries.registries.registry.AbstractRegistry
|
import de.bixilon.minosoft.data.registries.registries.registry.AbstractRegistry
|
||||||
import de.bixilon.minosoft.data.world.container.palette.data.PaletteData
|
import de.bixilon.minosoft.data.world.container.palette.data.PaletteData
|
||||||
|
import de.bixilon.minosoft.data.world.container.palette.palettes.BlockStatePaletteFactory
|
||||||
import de.bixilon.minosoft.data.world.container.palette.palettes.PaletteFactory
|
import de.bixilon.minosoft.data.world.container.palette.palettes.PaletteFactory
|
||||||
import de.bixilon.minosoft.protocol.protocol.buffers.play.PlayInByteBuffer
|
import de.bixilon.minosoft.protocol.protocol.buffers.play.PlayInByteBuffer
|
||||||
|
|
||||||
@ -41,16 +42,27 @@ object PalettedContainerReader {
|
|||||||
val data = PaletteData.create(buffer.versionId, palette.bits, factory.containerSize)
|
val data = PaletteData.create(buffer.versionId, palette.bits, factory.containerSize)
|
||||||
try {
|
try {
|
||||||
data.read(buffer)
|
data.read(buffer)
|
||||||
|
if (factory == BlockStatePaletteFactory && data.isEmpty) { // id 0 is air
|
||||||
|
return null
|
||||||
|
}
|
||||||
val container = PalettedContainer(factory.edgeBits, palette, data)
|
val container = PalettedContainer(factory.edgeBits, palette, data)
|
||||||
|
|
||||||
if (container.isEmpty) return null
|
if (container.isEmpty) return null
|
||||||
val unpacked = container.unpack<T>()
|
val unpacked = container.unpack<T>()
|
||||||
|
|
||||||
if (unpacked.isEmpty()) return null
|
if (unpacked.isAllNull()) return null
|
||||||
|
|
||||||
return unpacked
|
return unpacked
|
||||||
} finally {
|
} finally {
|
||||||
data.free()
|
data.free()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun <T> Array<T>.isAllNull(): Boolean {
|
||||||
|
for (entry in this) {
|
||||||
|
if (entry == null) continue
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ package de.bixilon.minosoft.data.world.container.palette.data
|
|||||||
import de.bixilon.minosoft.protocol.protocol.buffers.play.PlayInByteBuffer
|
import de.bixilon.minosoft.protocol.protocol.buffers.play.PlayInByteBuffer
|
||||||
|
|
||||||
class EmptyPaletteData(override val size: Int) : PaletteData {
|
class EmptyPaletteData(override val size: Int) : PaletteData {
|
||||||
|
override val isEmpty: Boolean get() = true
|
||||||
|
|
||||||
override fun free() = Unit
|
override fun free() = Unit
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ import de.bixilon.minosoft.data.world.container.palette.data.array.ArrayPaletteD
|
|||||||
import de.bixilon.minosoft.protocol.protocol.buffers.play.PlayInByteBuffer
|
import de.bixilon.minosoft.protocol.protocol.buffers.play.PlayInByteBuffer
|
||||||
|
|
||||||
interface PaletteData {
|
interface PaletteData {
|
||||||
|
val isEmpty: Boolean
|
||||||
val size: Int
|
val size: Int
|
||||||
|
|
||||||
fun get(index: Int): Int
|
fun get(index: Int): Int
|
||||||
|
@ -27,25 +27,40 @@ class ArrayPaletteData(
|
|||||||
private val valuesPerLong = Long.SIZE_BITS / elementBits
|
private val valuesPerLong = Long.SIZE_BITS / elementBits
|
||||||
private lateinit var data: LongArray
|
private lateinit var data: LongArray
|
||||||
|
|
||||||
|
override var isEmpty = true
|
||||||
|
|
||||||
init {
|
init {
|
||||||
check(elementBits in 0..32)
|
check(elementBits in 0..32)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun read(buffer: PlayInByteBuffer) {
|
private fun calculateLongs(): Int {
|
||||||
val packetSize = buffer.readVarInt()
|
if (versionId < LONG_BIT_SPLITTING_VERSION) {
|
||||||
val size: Int = if (versionId < LONG_BIT_SPLITTING_VERSION) {
|
|
||||||
val bits = this.size * elementBits
|
val bits = this.size * elementBits
|
||||||
|
|
||||||
(bits + (Long.SIZE_BITS - 1)) / Long.SIZE_BITS // divide up
|
return (bits + (Long.SIZE_BITS - 1)) / Long.SIZE_BITS // divide up
|
||||||
} else {
|
|
||||||
(this.size + valuesPerLong - 1) / valuesPerLong
|
|
||||||
}
|
}
|
||||||
this.data = ALLOCATOR.allocate(this.size)
|
return (this.size + valuesPerLong - 1) / valuesPerLong
|
||||||
if (packetSize != size) {
|
}
|
||||||
|
|
||||||
|
private fun checkEmpty(size: Int): Boolean {
|
||||||
|
for (i in 0 until size) {
|
||||||
|
if (this.data[i] != 0L) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun read(buffer: PlayInByteBuffer) {
|
||||||
|
val packetSize = buffer.readVarInt()
|
||||||
|
val longs = calculateLongs()
|
||||||
|
this.data = ALLOCATOR.allocate(longs)
|
||||||
|
if (packetSize != longs) {
|
||||||
buffer.pointer += packetSize * Long.SIZE_BYTES // data is ignored
|
buffer.pointer += packetSize * Long.SIZE_BYTES // data is ignored
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
buffer.readLongArray(this.data, size)
|
buffer.readLongArray(this.data, longs)
|
||||||
|
this.isEmpty = checkEmpty(longs)
|
||||||
}
|
}
|
||||||
|
|
||||||
override operator fun get(index: Int): Int {
|
override operator fun get(index: Int): Int {
|
||||||
|
@ -305,12 +305,4 @@ object ChunkUtil {
|
|||||||
fun ChunkPosition.isInViewDistance(viewDistance: Int, cameraPosition: ChunkPosition): Boolean {
|
fun ChunkPosition.isInViewDistance(viewDistance: Int, cameraPosition: ChunkPosition): Boolean {
|
||||||
return abs(this.x - cameraPosition.x) <= viewDistance && abs(this.y - cameraPosition.y) <= viewDistance
|
return abs(this.x - cameraPosition.x) <= viewDistance && abs(this.y - cameraPosition.y) <= viewDistance
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Array<BlockState?>.isEmpty(): Boolean {
|
|
||||||
for (entry in this) {
|
|
||||||
if (entry == null) continue
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user