diff --git a/src/main/java/de/bixilon/minosoft/data/mappings/tweaker/VersionTweaker.kt b/src/main/java/de/bixilon/minosoft/data/mappings/tweaker/VersionTweaker.kt index 4ed657b38..71fee6dfe 100644 --- a/src/main/java/de/bixilon/minosoft/data/mappings/tweaker/VersionTweaker.kt +++ b/src/main/java/de/bixilon/minosoft/data/mappings/tweaker/VersionTweaker.kt @@ -115,7 +115,7 @@ object VersionTweaker { @JvmStatic - fun transformBlock(originalBlock: BlockState, sections: Map, inChunkSectionPositions: Vec3i, sectionHeight: Int): BlockState? { + fun transformBlock(originalBlock: BlockState?, sections: Map, inChunkSectionPositions: Vec3i, sectionHeight: Int): BlockState? { // ToDo: Broken return originalBlock } diff --git a/src/main/java/de/bixilon/minosoft/data/world/Chunk.kt b/src/main/java/de/bixilon/minosoft/data/world/Chunk.kt index 769bc2fe1..dd5bf688c 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/Chunk.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/Chunk.kt @@ -18,7 +18,6 @@ import de.bixilon.minosoft.data.world.light.LightAccessor import de.bixilon.minosoft.gui.rendering.util.VecUtil.inChunkSectionPosition import de.bixilon.minosoft.gui.rendering.util.VecUtil.sectionHeight import glm_.vec3.Vec3i -import java.util.* /** * Collection of chunks sections (allocated in y) @@ -71,7 +70,7 @@ class Chunk( } } - fun setRawBlocks(blocks: HashMap) { + fun setRawBlocks(blocks: Map) { for ((location, blockState) in blocks) { setBlockState(location, blockState) } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/WorldRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/WorldRenderer.kt index ea2cca99b..afcfe08fe 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/WorldRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/WorldRenderer.kt @@ -278,7 +278,7 @@ class WorldRenderer( val sections: MutableMap = Collections.synchronizedMap(ConcurrentHashMap()) val chunk = world.getChunk(chunkPosition)!! val lowestSectionHeight = getSectionIndex(sectionHeight) * RenderConstants.CHUNK_SECTIONS_PER_MESH - for (i in lowestSectionHeight until lowestSectionHeight + (RenderConstants.CHUNK_SECTIONS_PER_MESH - 1)) { + for (i in lowestSectionHeight until lowestSectionHeight + RenderConstants.CHUNK_SECTIONS_PER_MESH) { sections[i] = chunk.sections?.get(i) ?: continue } prepareChunkSections(chunkPosition, sections) diff --git a/src/main/java/de/bixilon/minosoft/modding/event/events/MultiBlockChangeEvent.java b/src/main/java/de/bixilon/minosoft/modding/event/events/MultiBlockChangeEvent.java index cdc512ff3..dcd72363e 100644 --- a/src/main/java/de/bixilon/minosoft/modding/event/events/MultiBlockChangeEvent.java +++ b/src/main/java/de/bixilon/minosoft/modding/event/events/MultiBlockChangeEvent.java @@ -19,16 +19,16 @@ import de.bixilon.minosoft.protocol.packets.clientbound.play.PacketMultiBlockCha import glm_.vec2.Vec2i; import glm_.vec3.Vec3i; -import java.util.HashMap; +import java.util.Map; /** * Fired when at least block is changed */ public class MultiBlockChangeEvent extends PlayConnectionEvent { - private final HashMap blocks; + private final Map blocks; private final Vec2i chunkPosition; - public MultiBlockChangeEvent(PlayConnection connection, HashMap blocks, Vec2i position) { + public MultiBlockChangeEvent(PlayConnection connection, Map blocks, Vec2i position) { super(connection); this.blocks = blocks; this.chunkPosition = position; @@ -40,7 +40,7 @@ public class MultiBlockChangeEvent extends PlayConnectionEvent { this.chunkPosition = pkg.getChunkPosition(); } - public HashMap getBlocks() { + public Map getBlocks() { return this.blocks; } diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketBlockChange.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketBlockChange.kt index c2bd1dbc0..d6e79fae4 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketBlockChange.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketBlockChange.kt @@ -62,6 +62,6 @@ class PacketBlockChange(buffer: PlayInByteBuffer) : PlayClientboundPacket() { } override fun log() { - Log.protocol(String.format("[IN] Block change received at %s (block=%s)", blockPosition, block)) + Log.protocol("[IN] Block change received (position=${blockPosition}, block=$block)") } } diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketMultiBlockChange.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketMultiBlockChange.kt index b16ceedda..0c8ca7733 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketMultiBlockChange.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketMultiBlockChange.kt @@ -12,76 +12,74 @@ */ package de.bixilon.minosoft.protocol.packets.clientbound.play + import de.bixilon.minosoft.data.mappings.blocks.BlockState import de.bixilon.minosoft.data.mappings.tweaker.VersionTweaker import de.bixilon.minosoft.gui.rendering.util.VecUtil.inChunkSectionPosition import de.bixilon.minosoft.gui.rendering.util.VecUtil.sectionHeight - - import de.bixilon.minosoft.modding.event.events.MultiBlockChangeEvent import de.bixilon.minosoft.protocol.network.connection.PlayConnection import de.bixilon.minosoft.protocol.packets.clientbound.PlayClientboundPacket import de.bixilon.minosoft.protocol.protocol.PlayInByteBuffer +import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition import de.bixilon.minosoft.protocol.protocol.ProtocolVersions import de.bixilon.minosoft.util.logging.Log import glm_.vec2.Vec2i import glm_.vec3.Vec3i -import java.util.* -class PacketMultiBlockChange() : PlayClientboundPacket() { - val blocks = HashMap() - lateinit var chunkPosition: Vec2i +class PacketMultiBlockChange(buffer: PlayInByteBuffer) : PlayClientboundPacket() { + val blocks: MutableMap = mutableMapOf() + var chunkPosition: Vec2i private set - constructor(buffer: PlayInByteBuffer) : this() { - if (buffer.versionId < ProtocolVersions.V_14W26C) { - chunkPosition = if (buffer.versionId < ProtocolVersions.V_1_7_5) { - Vec2i(buffer.readVarInt(), buffer.readVarInt()) - } else { - buffer.readChunkPosition() + init { + when { + buffer.versionId < ProtocolVersions.V_14W26C -> { + chunkPosition = if (buffer.versionId < ProtocolVersions.V_1_7_5) { + Vec2i(buffer.readVarInt(), buffer.readVarInt()) + } else { + buffer.readChunkPosition() + } + val count = buffer.readShort() + val dataSize = buffer.readInt() + check(dataSize == count * 4) { "MultiBlockChangePacket needs 4 bytes per block change!" } + for (i in 0 until count) { + val raw = buffer.readInt() + val meta = (raw and 0xF) + val blockId = (raw and 0xFFF0 ushr 4) + val y = (raw and 0xFF0000 ushr 16) + val z = (raw and 0x0F000000 ushr 24) + val x = (raw and -0x10000000 ushr 28) + blocks[Vec3i(x, y, z)] = buffer.connection.mapping.getBlockState((blockId shl 4) or meta) + } } - val count = buffer.readShort() - val dataSize = buffer.readInt() - check(dataSize == count * 4) { "MultiBlockChangePacket needs 4 bytes per block change!" } - for (i in 0 until count) { - val raw = buffer.readInt() - val meta = (raw and 0xF) - val blockId = (raw and 0xFFF0 ushr 4) - val y = (raw and 0xFF0000 ushr 16) - val z = (raw and 0x0F000000 ushr 24) - val x = (raw and -0x10000000 ushr 28) - blocks[Vec3i(x, y, z)] = buffer.connection.mapping.getBlockState((blockId shl 4) or meta) + buffer.versionId < ProtocolVersions.V_20W28A -> { + chunkPosition = Vec2i(buffer.readInt(), buffer.readInt()) + val count = buffer.readVarInt() + for (i in 0 until count) { + val position = buffer.readByte().toInt() + val y = buffer.readByte() + val blockId = buffer.readVarInt() + blocks[Vec3i(position and 0xF0 ushr 4 and 0xF, y.toInt(), position and 0xF)] = buffer.connection.mapping.getBlockState(blockId) + } } - return - } - if (buffer.versionId < ProtocolVersions.V_20W28A) { - chunkPosition = Vec2i(buffer.readInt(), buffer.readInt()) - val count = buffer.readVarInt() - for (i in 0 until count) { - val position = buffer.readByte().toInt() - val y = buffer.readByte() - val blockId = buffer.readVarInt() - blocks[Vec3i(position and 0xF0 ushr 4 and 0xF, y.toInt(), position and 0xF)] = buffer.connection.mapping.getBlockState(blockId) + else -> { + val rawPos = buffer.readLong() + chunkPosition = Vec2i((rawPos shr 42).toInt(), (rawPos shl 22 shr 42).toInt()) + val yOffset = (rawPos.toInt() and 0xFFFFF) * ProtocolDefinition.SECTION_HEIGHT_Y + if (buffer.versionId > ProtocolVersions.V_1_16_2_PRE3) { + buffer.readBoolean() // ToDo + } + for (data in buffer.readVarLongArray()) { + blocks[Vec3i((data shr 8 and 0x0F).toInt(), yOffset + (data and 0x0F).toInt(), (data shr 4 and 0xF).toInt())] = buffer.connection.mapping.getBlockState((data ushr 12).toInt()) + } } - return } - val rawPos = buffer.readLong() - chunkPosition = Vec2i((rawPos shr 42).toInt(), (rawPos shl 22 shr 42).toInt()) - val yOffset = (rawPos.toInt() and 0xFFFFF) * 16 - if (buffer.versionId > ProtocolVersions.V_1_16_2_PRE3) { - buffer.readBoolean() // ToDo - } - val count = buffer.readVarInt() - for (i in 0 until count) { - val data = buffer.readVarLong() - blocks[Vec3i((data shr 8 and 0xF).toInt(), yOffset + (data shr 4 and 0xF).toInt(), (data and 0xF).toInt())] = buffer.connection.mapping.getBlockState((data ushr 12).toInt()) - } - return } override fun handle(connection: PlayConnection) { val chunk = connection.world.getChunk(chunkPosition) ?: return // thanks mojang - if (!chunk.isFullyLoaded) { + if (chunk.sections == null) { return } connection.fireEvent(MultiBlockChangeEvent(connection, this)) @@ -90,14 +88,14 @@ class PacketMultiBlockChange() : PlayClientboundPacket() { // tweak if (!connection.version.isFlattened()) { for ((key, value) in blocks) { - val block = VersionTweaker.transformBlock(value!!, chunk.sections!!, key.inChunkSectionPosition, key.sectionHeight) + val block = VersionTweaker.transformBlock(value, chunk.sections!!, key.inChunkSectionPosition, key.sectionHeight) if (block === value) { continue } chunk.setBlockState(key, block) } } - val sectionHeights = HashSet() + val sectionHeights: MutableSet = mutableSetOf() for ((key) in blocks) { sectionHeights.add(key.sectionHeight) } @@ -107,6 +105,6 @@ class PacketMultiBlockChange() : PlayClientboundPacket() { } override fun log() { - Log.protocol(String.format("[IN] Multi block change received at %s (size=%d)", chunkPosition, blocks.size)) + Log.protocol("[IN] Multi block change received (chunkPosition=${chunkPosition}, count=${blocks.size})") } } diff --git a/src/main/java/de/bixilon/minosoft/protocol/protocol/InByteBuffer.java b/src/main/java/de/bixilon/minosoft/protocol/protocol/InByteBuffer.java index f2f298053..ab8111261 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/protocol/InByteBuffer.java +++ b/src/main/java/de/bixilon/minosoft/protocol/protocol/InByteBuffer.java @@ -418,4 +418,16 @@ public class InByteBuffer { public Vec2i readChunkPosition() { return new Vec2i(readInt(), readInt()); } + + public long[] readVarLongArray(int size) { + var ret = new long[size]; + for (int i = 0; i < size; i++) { + ret[i] = readVarLong(); + } + return ret; + } + + public long[] readVarLongArray() { + return readVarLongArray(readVarInt()); + } }