refactor palette

This commit is contained in:
Bixilon 2021-04-06 12:44:16 +02:00
parent 7018f3ca63
commit 01ebe2ff3a
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
7 changed files with 97 additions and 124 deletions

View File

@ -82,6 +82,10 @@ class VersionMapping {
internal val models: MutableMap<ResourceLocation, BlockModel> = mutableMapOf() internal val models: MutableMap<ResourceLocation, BlockModel> = mutableMapOf()
val blockStateCount: Int
get() = blockStateIdMap.size + (parentMapping?.blockStateCount ?: 0)
var isFullyLoaded = false var isFullyLoaded = false
private set private set

View File

@ -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 <https://www.gnu.org/licenses/>.
*
* 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();
}
}
}

View File

@ -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 <https://www.gnu.org/licenses/>.
*
* 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()
}
}

View File

@ -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 <https://www.gnu.org/licenses/>.
*
* 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();
}
}

View File

@ -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 <https://www.gnu.org/licenses/>.
*
* 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
}
}

View File

@ -21,16 +21,14 @@ interface Palette {
val bitsPerBlock: Int val bitsPerBlock: Int
fun read(buffer: PlayInByteBuffer)
companion object { companion object {
fun choosePalette(bitsPerBlock: Int): Palette { fun choosePalette(bitsPerBlock: Int, buffer: PlayInByteBuffer): Palette {
if (bitsPerBlock <= 4) { if (bitsPerBlock <= 4) {
return IndirectPalette(4) return IndirectPalette(4, buffer)
} else if (bitsPerBlock <= 8) { } else if (bitsPerBlock <= 8) {
return IndirectPalette(bitsPerBlock) return IndirectPalette(bitsPerBlock, buffer)
} }
return DirectPalette() return DirectPalette(buffer)
} }
} }
} }

View File

@ -156,8 +156,8 @@ object ChunkUtil {
buffer.readShort() // block count buffer.readShort() // block count
} }
val palette = choosePalette(buffer.readUnsignedByte().toInt()) val palette = choosePalette(buffer.readUnsignedByte(), buffer)
palette.read(buffer)
val individualValueMask = (1 shl palette.bitsPerBlock) - 1 val individualValueMask = (1 shl palette.bitsPerBlock) - 1
val data = buffer.readLongArray() val data = buffer.readLongArray()