@@ -85,12 +85,18 @@ class ChunkDataThrottleHandlerImpl: ChunkDataThrottleHandler,
8585 const val SECTION_BLOCKS = 16 * 16 * 16
8686 const val BITS_ALL_TRUE = - 1L
8787
88+ const val BV_VISIBLE : Byte = 0
89+ const val BV_OCCLUDING : Byte = 1
90+ const val BV_LAVA : Byte = 11
91+
8892 private var LAVA_MIN = Int .MAX_VALUE
8993 private var LAVA_MAX = Int .MIN_VALUE
90- private var BLOCKS_VIEW = BooleanArray (Block .BLOCK_STATE_REGISTRY .size())
94+ private var BLOCKS_VIEW = ByteArray (Block .BLOCK_STATE_REGISTRY .size())
9195 val ITSELF = IntArray (BLOCKS_VIEW .size) { it }
9296 val FULL_CHUNK = PlayerChunk (BitSet (0 ))
9397
98+ private fun Boolean.toByte (): Byte = if (this ) 1 else 0
99+
94100 }
95101
96102 private val containerReader by Versioned (PalettedContainerReader ::class .java)
@@ -105,7 +111,7 @@ class ChunkDataThrottleHandlerImpl: ChunkDataThrottleHandler,
105111 override fun reload () {
106112 val nonInvisible = config.chunkDataThrottle.nonInvisibleBlocksOverrides
107113 BLOCKS_VIEW = PacketEvents .getAPI().serverManager.version.toClientVersion().let { version ->
108- BooleanArray (Block .BLOCK_STATE_REGISTRY .size()) { id ->
114+ ByteArray (Block .BLOCK_STATE_REGISTRY .size()) { id ->
109115 val wrapped = WrappedBlockState .getByGlobalId(version, id, false )
110116 if (wrapped.type.materialType == MaterialType .LAVA ) {
111117 LAVA_MIN = min(id, LAVA_MIN )
@@ -117,11 +123,15 @@ class ChunkDataThrottleHandlerImpl: ChunkDataThrottleHandler,
117123 SpigotConversionUtil .toBukkitMaterialData(wrapped).itemType
118124 }
119125 if (nonInvisible.contains(material))
120- false
126+ false .toByte()
121127 else when (material) {
122- Material .GLOWSTONE -> true
123- Material .BARRIER -> false
124- else -> material.isOccluding
128+ Material .GLOWSTONE -> true .toByte()
129+ Material .BARRIER -> false .toByte()
130+ else -> material.isOccluding.toByte()
131+ }
132+ }.apply {
133+ for (i in LAVA_MIN .. LAVA_MAX ) {
134+ this [i] = BV_LAVA
125135 }
126136 }
127137 }
@@ -269,8 +279,8 @@ class ChunkDataThrottleHandlerImpl: ChunkDataThrottleHandler,
269279 val world = player.world
270280 val minHeight = world.minHeight
271281 for (block in wrapper.blocks) {
272- if (block.blockId.blocksView) {
273- // Only check full chunk if blocks get broken or transformed to non-blocking
282+ if (block.blockId.blocksView == BV_OCCLUDING ) {
283+ // Only check update if blocks get broken or transformed to non-blocksView
274284 continue
275285 }
276286 checkBlockUpdate(player, block.x, block.y, block.z, minHeight)
@@ -279,8 +289,8 @@ class ChunkDataThrottleHandlerImpl: ChunkDataThrottleHandler,
279289
280290 PacketType .Play .Server .BLOCK_CHANGE -> {
281291 val wrapper = WrapperPlayServerBlockChange (event)
282- if (wrapper.blockId.blocksView) {
283- // Only check full chunk if blocks get broken or transformed to non-blocking
292+ if (wrapper.blockId.blocksView == BV_OCCLUDING ) {
293+ // Only check update if blocks get broken or transformed to non-blocksView
284294 return
285295 }
286296 checkBlockUpdate(event.getPlayer(), wrapper.blockPosition)
@@ -335,10 +345,10 @@ class ChunkDataThrottleHandlerImpl: ChunkDataThrottleHandler,
335345 val palette = section.chunkData.palette
336346 if (palette is SingletonPalette ) {
337347 // This section contains only one block type, and it's already the smallest way.
338- if (palette.idToState(0 ).blocksView) {
348+ if (palette.idToState(0 ).blocksView != BV_VISIBLE ) {
339349 if (index > 0 ) {
340350 // Check if the surface on previous section is invisible
341- checkSurfaceInvisible(bvArr, invisible, id)
351+ checkSurfaceInvisible(bvArr, invisible, id, palette.idToState( 0 ).blocksView )
342352 }
343353 id + = SECTION_BLOCKS
344354 for (i in id until id + 16 * 16 ) bvArr[i] = bvArr[i] or Y_MINUS
@@ -349,13 +359,13 @@ class ChunkDataThrottleHandlerImpl: ChunkDataThrottleHandler,
349359 val data = readBitsData(section.chunkData.storage)
350360 val bits = palette.bits
351361 val states: IntArray
352- val blockingArr: BooleanArray
362+ val blockingArr: ByteArray
353363 when (palette) {
354364 is ListPalette , is MapPalette -> {
355365 states = IntArray (section.chunkData.palette.size()) { i ->
356366 section.chunkData.palette.idToState(i)
357367 }
358- blockingArr = BooleanArray (states.size) { i -> states[i].blocksView }
368+ blockingArr = ByteArray (states.size) { i -> states[i].blocksView }
359369 }
360370 is GlobalPalette -> {
361371 states = ITSELF
@@ -367,13 +377,20 @@ class ChunkDataThrottleHandlerImpl: ChunkDataThrottleHandler,
367377 }
368378
369379 for (i in 0 until SECTION_BLOCKS ) {
370- if (blockingArr[data[i]]) {
371- addNearby(bvArr, id)
372- // Make sure it's not out of bounds, while we are processing bedrock layer
373- if (id >= 0x100 ) {
374- // Check if previous block is complete invisible
375- val previous = id - 0x100
376- invisible[previous] = if (bvArr[previous] == INVISIBLE ) 1 else 2
380+ when (blockingArr[data[i]]) {
381+ BV_OCCLUDING -> {
382+ addNearby(bvArr, id)
383+ // Make sure it's not out of bounds, while we are processing bedrock layer
384+ if (id >= 0x100 ) {
385+ // Check if previous block is complete invisible
386+ val previous = id - 0x100
387+ invisible[previous] = if (bvArr[previous] == INVISIBLE ) 1 else 2
388+ }
389+ }
390+ BV_LAVA -> {
391+ if (id >= 0x100 ) {
392+ invisible[id - 0x100 ] = BV_LAVA
393+ }
377394 }
378395 }
379396 id++
@@ -415,7 +432,7 @@ class ChunkDataThrottleHandlerImpl: ChunkDataThrottleHandler,
415432 // We could do the same thing to the top section,
416433 // but it never happens in vanilla generated chunks,
417434 // so, no.
418- checkSurfaceInvisible(bvArr, invisible, 0x1000 * (8 - 1 ))
435+ checkSurfaceInvisible(bvArr, invisible, 0x1000 * (8 - 1 ), BV_OCCLUDING )
419436 }
420437
421438 val array = invisible.toLongArray()
@@ -551,7 +568,7 @@ class ChunkDataThrottleHandlerImpl: ChunkDataThrottleHandler,
551568 val states = section.container
552569 val palette = containerReader.getPalette(states)
553570 if (palette is SingleValuePalette <BlockState >) {
554- if (palette.valueFor(0 ).blocksView) {
571+ if (palette.valueFor(0 ).blocksView == BV_OCCLUDING ) {
555572 for (y in 0 until 16 ) {
556573 for (j in 0 until 16 ) {
557574 (blockId + arrOffset).let { blocking[it] = blocking[it] or arrValue }
@@ -566,7 +583,7 @@ class ChunkDataThrottleHandlerImpl: ChunkDataThrottleHandler,
566583 val storage = containerReader.getStorage(states)
567584 val blockingArr = when (palette) {
568585 is LinearPalette <BlockState >, is HashMapPalette <BlockState > ->
569- BooleanArray (palette.size + 1 ).apply {
586+ ByteArray (palette.size + 1 ).apply {
570587 // We add one size for safe, cuz this is not thread-safe,
571588 // Players might place extra blocks to the chunk during the process below (storage.get())
572589 for (i in 0 until palette.size)
@@ -580,7 +597,7 @@ class ChunkDataThrottleHandlerImpl: ChunkDataThrottleHandler,
580597
581598 for (y in 0 until 16 ) {
582599 for (j in 0 until 16 ) {
583- if (blockingArr[storage.get(blockId and 0xfff )])
600+ if (blockingArr[storage.get(blockId and 0xfff )] == BV_OCCLUDING )
584601 (blockId + arrOffset).let { blocking[it] = blocking[it] or arrValue }
585602 blockId + = bidStep
586603 }
@@ -590,10 +607,10 @@ class ChunkDataThrottleHandlerImpl: ChunkDataThrottleHandler,
590607 }
591608 }
592609
593- private fun checkSurfaceInvisible (bvArr : ByteArray , invisible : ByteArray , id : Int ) {
610+ private fun checkSurfaceInvisible (bvArr : ByteArray , invisible : ByteArray , id : Int , setTo : Byte ) {
594611 for (i in id - 1 downTo id - 0x101 ) {
595612 if (bvArr[i] == INVISIBLE ) {
596- invisible[i] = 1
613+ invisible[i] = setTo
597614 return
598615 }
599616 }
@@ -733,7 +750,7 @@ class ChunkDataThrottleHandlerImpl: ChunkDataThrottleHandler,
733750 private val Int .blocksView
734751 get() = BLOCKS_VIEW [this ]
735752
736- private val BlockState .blocksView: Boolean
753+ private val BlockState .blocksView
737754 get() = Block .BLOCK_STATE_REGISTRY .getId(this ).blocksView
738755
739756 data class PlayerChunk (
0 commit comments