improve block entity storage

This commit is contained in:
Bixilon 2021-04-26 15:27:28 +02:00
parent b6909dd928
commit 0c7ba090f0
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
6 changed files with 138 additions and 17 deletions

View File

@ -94,6 +94,5 @@ open class MinecraftLanguage : Translator {
companion object {
private val FORMATTER_ORDER_REGEX = "%(\\w+)\\\$[sd]".toRegex() // %1$s fell from a high place
private val FORMATTER_SPLIT_REGEX = "%[ds]".toRegex() // %s fell from a high place
}
}

View File

@ -14,6 +14,9 @@ package de.bixilon.minosoft.data.world
import de.bixilon.minosoft.data.entities.block.BlockEntity
import de.bixilon.minosoft.data.mappings.blocks.BlockState
import de.bixilon.minosoft.data.world.block.entities.ArrayBlockEntityProvider
import de.bixilon.minosoft.data.world.block.entities.BlockEntityProvider
import de.bixilon.minosoft.data.world.block.entities.MapBlockEntityProvider
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
import glm_.vec3.Vec3i
@ -21,9 +24,8 @@ import glm_.vec3.Vec3i
* Collection of 16x16x16 blocks
*/
class ChunkSection(
val blocks: Array<BlockState?> = arrayOfNulls(ProtocolDefinition.BLOCKS_PER_SECTION),
val blockEntities: Array<BlockEntity?> = arrayOfNulls(ProtocolDefinition.BLOCKS_PER_SECTION),
// ToDo: BlockEntityMeta
var blocks: Array<BlockState?> = arrayOfNulls(ProtocolDefinition.BLOCKS_PER_SECTION),
private var blockEntities: BlockEntityProvider = MapBlockEntityProvider(),
) {
fun getBlockState(inChunkSectionPositions: Vec3i): BlockState? {
@ -34,22 +36,22 @@ class ChunkSection(
blocks[inChunkSectionPositions.index] = blockState
}
fun getBlockState(x: Int, y: Int, z: Int): BlockState? {
return getBlockState(Vec3i(x, y, z))
}
fun setData(chunkSection: ChunkSection) {
for ((index, blockInfo) in chunkSection.blocks.withIndex()) {
blocks[index] = blockInfo
}
blocks = chunkSection.blocks.clone()
}
fun getBlockEntity(inChunkSectionPositions: Vec3i): BlockEntity? {
return blockEntities[inChunkSectionPositions.index]
return blockEntities[inChunkSectionPositions]
}
fun setBlockEntity(inChunkSectionPositions: Vec3i, blockEntity: BlockEntity?) {
blockEntities[inChunkSectionPositions.index] = blockEntity
blockEntities[inChunkSectionPositions] = blockEntity
val blockEntities = blockEntities
if (blockEntities.size > BlockEntityProvider.BLOCK_ENTITY_MAP_LIMIT_UP && blockEntities is MapBlockEntityProvider) {
this.blockEntities = ArrayBlockEntityProvider(blockEntities)
} else if (blockEntities.size <= BlockEntityProvider.BLOCK_ENTITY_MAP_LIMIT_DOWN && blockEntities is ArrayBlockEntityProvider) {
this.blockEntities = MapBlockEntityProvider(blockEntities)
}
}
companion object {

View File

@ -0,0 +1,47 @@
/*
* Minosoft
* Copyright (C) 2021 Moritz Zwerger
*
* 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.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.world.block.entities
import de.bixilon.minosoft.data.entities.block.BlockEntity
import de.bixilon.minosoft.data.world.ChunkSection.Companion.index
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
import glm_.vec3.Vec3i
class ArrayBlockEntityProvider() : BlockEntityProvider {
override var size: Int = 0
private set
constructor(blockEntityProvider: MapBlockEntityProvider) : this() {
for ((position, blockEntity) in blockEntityProvider.blockEntities) {
blockEntities[position.index] = blockEntity
}
}
var blockEntities: Array<BlockEntity?> = arrayOfNulls(ProtocolDefinition.BLOCKS_PER_SECTION)
override fun get(inChunkSectionPosition: Vec3i): BlockEntity? {
return blockEntities[inChunkSectionPosition.index]
}
override fun set(inChunkSectionPosition: Vec3i, blockEntity: BlockEntity?) {
val previous = blockEntities[inChunkSectionPosition.index]
blockEntities[inChunkSectionPosition.index] = blockEntity
if (previous != null && blockEntity == null) {
size--
} else if (previous == null && blockEntity != null) {
size++
}
}
}

View File

@ -0,0 +1,31 @@
/*
* Minosoft
* Copyright (C) 2021 Moritz Zwerger
*
* 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.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.world.block.entities
import de.bixilon.minosoft.data.entities.block.BlockEntity
import glm_.vec3.Vec3i
interface BlockEntityProvider {
val size: Int
operator fun get(inChunkSectionPosition: Vec3i): BlockEntity?
operator fun set(inChunkSectionPosition: Vec3i, blockEntity: BlockEntity?)
companion object {
const val BLOCK_ENTITY_MAP_LIMIT_UP = 100
const val BLOCK_ENTITY_MAP_LIMIT_DOWN = 80
}
}

View File

@ -0,0 +1,46 @@
/*
* Minosoft
* Copyright (C) 2021 Moritz Zwerger
*
* 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.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.world.block.entities
import de.bixilon.minosoft.data.entities.block.BlockEntity
import de.bixilon.minosoft.data.world.ChunkSection.Companion.indexPosition
import glm_.vec3.Vec3i
class MapBlockEntityProvider() : BlockEntityProvider {
override val size: Int
get() = blockEntities.size
var blockEntities: MutableMap<Vec3i, BlockEntity> = mutableMapOf()
constructor(blockEntityProvider: ArrayBlockEntityProvider) : this() {
for ((index, blockEntity) in blockEntityProvider.blockEntities.withIndex()) {
if (blockEntity == null) {
continue
}
blockEntities[index.indexPosition] = blockEntity
}
}
override fun get(inChunkSectionPosition: Vec3i): BlockEntity? {
return blockEntities[inChunkSectionPosition]
}
override fun set(inChunkSectionPosition: Vec3i, blockEntity: BlockEntity?) {
if (blockEntity == null) {
blockEntities.remove(inChunkSectionPosition)
return
}
blockEntities[inChunkSectionPosition] = blockEntity
}
}

View File

@ -133,10 +133,6 @@ class ChunkDataS2CP() : PlayS2CPacket() {
connection.world.unloadChunk(chunkPosition)
connection.fireEvent(ChunkUnloadEvent(connection, chunkPosition))
}
for ((blockPosition, blockEntity) in blockEntities) {
connection.world.setBlockEntity(blockPosition, blockEntity)
}
}
override fun log() {