From 01ebe2ff3a37197e0bf3a2c26634a7d1c99f0503 Mon Sep 17 00:00:00 2001 From: Bixilon Date: Tue, 6 Apr 2021 12:44:16 +0200 Subject: [PATCH] refactor palette --- .../data/mappings/versions/VersionMapping.kt | 4 ++ .../data/world/palette/DirectPalette.java | 48 ------------- .../data/world/palette/DirectPalette.kt | 42 ++++++++++++ .../data/world/palette/IndirectPalette.java | 68 ------------------- .../data/world/palette/IndirectPalette.kt | 45 ++++++++++++ .../minosoft/data/world/palette/Palette.kt | 10 ++- .../bixilon/minosoft/util/chunk/ChunkUtil.kt | 4 +- 7 files changed, 97 insertions(+), 124 deletions(-) delete mode 100644 src/main/java/de/bixilon/minosoft/data/world/palette/DirectPalette.java create mode 100644 src/main/java/de/bixilon/minosoft/data/world/palette/DirectPalette.kt delete mode 100644 src/main/java/de/bixilon/minosoft/data/world/palette/IndirectPalette.java create mode 100644 src/main/java/de/bixilon/minosoft/data/world/palette/IndirectPalette.kt diff --git a/src/main/java/de/bixilon/minosoft/data/mappings/versions/VersionMapping.kt b/src/main/java/de/bixilon/minosoft/data/mappings/versions/VersionMapping.kt index 00f774bac..1c160c40e 100644 --- a/src/main/java/de/bixilon/minosoft/data/mappings/versions/VersionMapping.kt +++ b/src/main/java/de/bixilon/minosoft/data/mappings/versions/VersionMapping.kt @@ -82,6 +82,10 @@ class VersionMapping { internal val models: MutableMap = mutableMapOf() + val blockStateCount: Int + get() = blockStateIdMap.size + (parentMapping?.blockStateCount ?: 0) + + var isFullyLoaded = false private set diff --git a/src/main/java/de/bixilon/minosoft/data/world/palette/DirectPalette.java b/src/main/java/de/bixilon/minosoft/data/world/palette/DirectPalette.java deleted file mode 100644 index 106819e62..000000000 --- a/src/main/java/de/bixilon/minosoft/data/world/palette/DirectPalette.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Minosoft - * Copyright (C) 2020 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 . - * - * This software is not affiliated with Mojang AB, the original developer of Minecraft. - */ - -package de.bixilon.minosoft.data.world.palette; - -import de.bixilon.minosoft.data.mappings.blocks.BlockState; -import de.bixilon.minosoft.data.mappings.versions.VersionMapping; -import de.bixilon.minosoft.protocol.protocol.PlayInByteBuffer; - -import static de.bixilon.minosoft.protocol.protocol.ProtocolVersions.V_17W47A; -import static de.bixilon.minosoft.protocol.protocol.ProtocolVersions.V_18W10D; - -public class DirectPalette implements Palette { - int versionId; - VersionMapping mapping; - - @Override - public BlockState blockById(int id) { - return this.mapping.getBlockState(id); - } - - @Override - public int getBitsPerBlock() { - if (this.versionId < V_18W10D) { - return 13; - } - return 14; - } - - @Override - public void read(PlayInByteBuffer buffer) { - this.versionId = buffer.getVersionId(); - this.mapping = buffer.getConnection().getMapping(); - if (buffer.getVersionId() < V_17W47A) { - buffer.readVarInt(); - } - } -} diff --git a/src/main/java/de/bixilon/minosoft/data/world/palette/DirectPalette.kt b/src/main/java/de/bixilon/minosoft/data/world/palette/DirectPalette.kt new file mode 100644 index 000000000..2e761dc5d --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/data/world/palette/DirectPalette.kt @@ -0,0 +1,42 @@ +/* + * Minosoft + * Copyright (C) 2020 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 . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ +package de.bixilon.minosoft.data.world.palette + +import de.bixilon.minosoft.data.mappings.blocks.BlockState +import de.bixilon.minosoft.protocol.network.connection.PlayConnection +import de.bixilon.minosoft.protocol.protocol.PlayInByteBuffer +import de.bixilon.minosoft.protocol.protocol.ProtocolVersions +import kotlin.math.ceil +import kotlin.math.ln + +class DirectPalette(buffer: PlayInByteBuffer) : Palette { + private var connection: PlayConnection = buffer.connection + + init { + if (buffer.versionId < ProtocolVersions.V_17W47A) { + buffer.readVarInt() + } + } + + override fun blockById(id: Int): BlockState? { + return connection.mapping.getBlockState(id) + } + + override val bitsPerBlock: Int + get() { + if (this.connection.version.versionId < ProtocolVersions.V_18W10D) { + return 13 + } + return ceil(ln(connection.mapping.blockStateCount.toDouble()) / ln(2.0)).toInt() + } +} diff --git a/src/main/java/de/bixilon/minosoft/data/world/palette/IndirectPalette.java b/src/main/java/de/bixilon/minosoft/data/world/palette/IndirectPalette.java deleted file mode 100644 index 60ef22b1b..000000000 --- a/src/main/java/de/bixilon/minosoft/data/world/palette/IndirectPalette.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Minosoft - * Copyright (C) 2020 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 . - * - * This software is not affiliated with Mojang AB, the original developer of Minecraft. - */ - -package de.bixilon.minosoft.data.world.palette; - -import de.bixilon.minosoft.config.StaticConfiguration; -import de.bixilon.minosoft.data.mappings.blocks.BlockState; -import de.bixilon.minosoft.data.mappings.versions.VersionMapping; -import de.bixilon.minosoft.protocol.protocol.PlayInByteBuffer; -import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition; -import de.bixilon.minosoft.util.logging.Log; - -public class IndirectPalette implements Palette { - private final int bitsPerBlock; - private int[] palette; - int versionId; - VersionMapping mapping; - - public IndirectPalette(int bitsPerBlock) { - this.bitsPerBlock = bitsPerBlock; - } - - @Override - public BlockState blockById(int blockId) { - if (blockId < this.palette.length) { - blockId = this.palette[blockId]; - } - BlockState block = this.mapping.getBlockState(blockId); - if (StaticConfiguration.DEBUG_MODE) { - if (block == null) { - if (blockId == ProtocolDefinition.NULL_BLOCK_ID) { - return null; - } - String blockName; - if (this.versionId <= ProtocolDefinition.PRE_FLATTENING_VERSION_ID) { - blockName = String.format("%d:%d", blockId >> 4, blockId & 0xF); - } else { - blockName = String.valueOf(blockId); - } - Log.warn(String.format("Server sent unknown block: %s", blockName)); - return null; - } - } - return block; - } - - @Override - public int getBitsPerBlock() { - return this.bitsPerBlock; - } - - @Override - public void read(PlayInByteBuffer buffer) { - this.versionId = buffer.getVersionId(); - this.mapping = buffer.getConnection().getMapping(); - this.palette = buffer.readVarIntArray(); - } -} diff --git a/src/main/java/de/bixilon/minosoft/data/world/palette/IndirectPalette.kt b/src/main/java/de/bixilon/minosoft/data/world/palette/IndirectPalette.kt new file mode 100644 index 000000000..76b376a5b --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/data/world/palette/IndirectPalette.kt @@ -0,0 +1,45 @@ +/* + * Minosoft + * Copyright (C) 2020 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 . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ +package de.bixilon.minosoft.data.world.palette + +import de.bixilon.minosoft.config.StaticConfiguration +import de.bixilon.minosoft.data.mappings.blocks.BlockState +import de.bixilon.minosoft.protocol.protocol.PlayInByteBuffer +import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition +import de.bixilon.minosoft.util.logging.Log + +class IndirectPalette( + override val bitsPerBlock: Int, + buffer: PlayInByteBuffer, +) : Palette { + private val connection = buffer.connection + private var palette = buffer.readVarIntArray() + + override fun blockById(blockId: Int): BlockState? { + var realBlockId = blockId + if (realBlockId < palette.size) { + realBlockId = palette[realBlockId] + } + val block = connection.mapping.getBlockState(realBlockId) + + if (StaticConfiguration.DEBUG_MODE && block == null && realBlockId != ProtocolDefinition.NULL_BLOCK_ID) { + val blockName: String = if (connection.version.isFlattened()) { + realBlockId.toString() + } else { + "(${realBlockId shr 4}:${realBlockId and 0x0F}" + } + Log.warn("Server sent unknown block: $blockName") + } + return block + } +} diff --git a/src/main/java/de/bixilon/minosoft/data/world/palette/Palette.kt b/src/main/java/de/bixilon/minosoft/data/world/palette/Palette.kt index 245d2c3af..417e4b4af 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/palette/Palette.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/palette/Palette.kt @@ -21,16 +21,14 @@ interface Palette { val bitsPerBlock: Int - fun read(buffer: PlayInByteBuffer) - companion object { - fun choosePalette(bitsPerBlock: Int): Palette { + fun choosePalette(bitsPerBlock: Int, buffer: PlayInByteBuffer): Palette { if (bitsPerBlock <= 4) { - return IndirectPalette(4) + return IndirectPalette(4, buffer) } else if (bitsPerBlock <= 8) { - return IndirectPalette(bitsPerBlock) + return IndirectPalette(bitsPerBlock, buffer) } - return DirectPalette() + return DirectPalette(buffer) } } } diff --git a/src/main/java/de/bixilon/minosoft/util/chunk/ChunkUtil.kt b/src/main/java/de/bixilon/minosoft/util/chunk/ChunkUtil.kt index d2f58538f..d8e64b69a 100644 --- a/src/main/java/de/bixilon/minosoft/util/chunk/ChunkUtil.kt +++ b/src/main/java/de/bixilon/minosoft/util/chunk/ChunkUtil.kt @@ -156,8 +156,8 @@ object ChunkUtil { buffer.readShort() // block count } - val palette = choosePalette(buffer.readUnsignedByte().toInt()) - palette.read(buffer) + val palette = choosePalette(buffer.readUnsignedByte(), buffer) + val individualValueMask = (1 shl palette.bitsPerBlock) - 1 val data = buffer.readLongArray()