mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-18 11:54:59 -04:00
network, rendering: fix block changes
This commit is contained in:
parent
6afe5d64bd
commit
d8790e3de0
@ -115,7 +115,7 @@ object VersionTweaker {
|
|||||||
|
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun transformBlock(originalBlock: BlockState, sections: Map<Int, ChunkSection>, inChunkSectionPositions: Vec3i, sectionHeight: Int): BlockState? {
|
fun transformBlock(originalBlock: BlockState?, sections: Map<Int, ChunkSection>, inChunkSectionPositions: Vec3i, sectionHeight: Int): BlockState? {
|
||||||
// ToDo: Broken
|
// ToDo: Broken
|
||||||
return originalBlock
|
return originalBlock
|
||||||
}
|
}
|
||||||
|
@ -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.inChunkSectionPosition
|
||||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.sectionHeight
|
import de.bixilon.minosoft.gui.rendering.util.VecUtil.sectionHeight
|
||||||
import glm_.vec3.Vec3i
|
import glm_.vec3.Vec3i
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Collection of chunks sections (allocated in y)
|
* Collection of chunks sections (allocated in y)
|
||||||
@ -71,7 +70,7 @@ class Chunk(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setRawBlocks(blocks: HashMap<Vec3i, BlockState?>) {
|
fun setRawBlocks(blocks: Map<Vec3i, BlockState?>) {
|
||||||
for ((location, blockState) in blocks) {
|
for ((location, blockState) in blocks) {
|
||||||
setBlockState(location, blockState)
|
setBlockState(location, blockState)
|
||||||
}
|
}
|
||||||
|
@ -278,7 +278,7 @@ class WorldRenderer(
|
|||||||
val sections: MutableMap<Int, ChunkSection> = Collections.synchronizedMap(ConcurrentHashMap())
|
val sections: MutableMap<Int, ChunkSection> = Collections.synchronizedMap(ConcurrentHashMap())
|
||||||
val chunk = world.getChunk(chunkPosition)!!
|
val chunk = world.getChunk(chunkPosition)!!
|
||||||
val lowestSectionHeight = getSectionIndex(sectionHeight) * RenderConstants.CHUNK_SECTIONS_PER_MESH
|
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
|
sections[i] = chunk.sections?.get(i) ?: continue
|
||||||
}
|
}
|
||||||
prepareChunkSections(chunkPosition, sections)
|
prepareChunkSections(chunkPosition, sections)
|
||||||
|
@ -19,16 +19,16 @@ import de.bixilon.minosoft.protocol.packets.clientbound.play.PacketMultiBlockCha
|
|||||||
import glm_.vec2.Vec2i;
|
import glm_.vec2.Vec2i;
|
||||||
import glm_.vec3.Vec3i;
|
import glm_.vec3.Vec3i;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fired when at least block is changed
|
* Fired when at least block is changed
|
||||||
*/
|
*/
|
||||||
public class MultiBlockChangeEvent extends PlayConnectionEvent {
|
public class MultiBlockChangeEvent extends PlayConnectionEvent {
|
||||||
private final HashMap<Vec3i, BlockState> blocks;
|
private final Map<Vec3i, BlockState> blocks;
|
||||||
private final Vec2i chunkPosition;
|
private final Vec2i chunkPosition;
|
||||||
|
|
||||||
public MultiBlockChangeEvent(PlayConnection connection, HashMap<Vec3i, BlockState> blocks, Vec2i position) {
|
public MultiBlockChangeEvent(PlayConnection connection, Map<Vec3i, BlockState> blocks, Vec2i position) {
|
||||||
super(connection);
|
super(connection);
|
||||||
this.blocks = blocks;
|
this.blocks = blocks;
|
||||||
this.chunkPosition = position;
|
this.chunkPosition = position;
|
||||||
@ -40,7 +40,7 @@ public class MultiBlockChangeEvent extends PlayConnectionEvent {
|
|||||||
this.chunkPosition = pkg.getChunkPosition();
|
this.chunkPosition = pkg.getChunkPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
public HashMap<Vec3i, BlockState> getBlocks() {
|
public Map<Vec3i, BlockState> getBlocks() {
|
||||||
return this.blocks;
|
return this.blocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,6 +62,6 @@ class PacketBlockChange(buffer: PlayInByteBuffer) : PlayClientboundPacket() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun log() {
|
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)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,76 +12,74 @@
|
|||||||
*/
|
*/
|
||||||
package de.bixilon.minosoft.protocol.packets.clientbound.play
|
package de.bixilon.minosoft.protocol.packets.clientbound.play
|
||||||
|
|
||||||
|
|
||||||
import de.bixilon.minosoft.data.mappings.blocks.BlockState
|
import de.bixilon.minosoft.data.mappings.blocks.BlockState
|
||||||
import de.bixilon.minosoft.data.mappings.tweaker.VersionTweaker
|
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.inChunkSectionPosition
|
||||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.sectionHeight
|
import de.bixilon.minosoft.gui.rendering.util.VecUtil.sectionHeight
|
||||||
|
|
||||||
|
|
||||||
import de.bixilon.minosoft.modding.event.events.MultiBlockChangeEvent
|
import de.bixilon.minosoft.modding.event.events.MultiBlockChangeEvent
|
||||||
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||||
import de.bixilon.minosoft.protocol.packets.clientbound.PlayClientboundPacket
|
import de.bixilon.minosoft.protocol.packets.clientbound.PlayClientboundPacket
|
||||||
import de.bixilon.minosoft.protocol.protocol.PlayInByteBuffer
|
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.protocol.protocol.ProtocolVersions
|
||||||
import de.bixilon.minosoft.util.logging.Log
|
import de.bixilon.minosoft.util.logging.Log
|
||||||
import glm_.vec2.Vec2i
|
import glm_.vec2.Vec2i
|
||||||
import glm_.vec3.Vec3i
|
import glm_.vec3.Vec3i
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
class PacketMultiBlockChange() : PlayClientboundPacket() {
|
class PacketMultiBlockChange(buffer: PlayInByteBuffer) : PlayClientboundPacket() {
|
||||||
val blocks = HashMap<Vec3i, BlockState?>()
|
val blocks: MutableMap<Vec3i, BlockState?> = mutableMapOf()
|
||||||
lateinit var chunkPosition: Vec2i
|
var chunkPosition: Vec2i
|
||||||
private set
|
private set
|
||||||
|
|
||||||
constructor(buffer: PlayInByteBuffer) : this() {
|
init {
|
||||||
if (buffer.versionId < ProtocolVersions.V_14W26C) {
|
when {
|
||||||
chunkPosition = if (buffer.versionId < ProtocolVersions.V_1_7_5) {
|
buffer.versionId < ProtocolVersions.V_14W26C -> {
|
||||||
Vec2i(buffer.readVarInt(), buffer.readVarInt())
|
chunkPosition = if (buffer.versionId < ProtocolVersions.V_1_7_5) {
|
||||||
} else {
|
Vec2i(buffer.readVarInt(), buffer.readVarInt())
|
||||||
buffer.readChunkPosition()
|
} 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()
|
buffer.versionId < ProtocolVersions.V_20W28A -> {
|
||||||
val dataSize = buffer.readInt()
|
chunkPosition = Vec2i(buffer.readInt(), buffer.readInt())
|
||||||
check(dataSize == count * 4) { "MultiBlockChangePacket needs 4 bytes per block change!" }
|
val count = buffer.readVarInt()
|
||||||
for (i in 0 until count) {
|
for (i in 0 until count) {
|
||||||
val raw = buffer.readInt()
|
val position = buffer.readByte().toInt()
|
||||||
val meta = (raw and 0xF)
|
val y = buffer.readByte()
|
||||||
val blockId = (raw and 0xFFF0 ushr 4)
|
val blockId = buffer.readVarInt()
|
||||||
val y = (raw and 0xFF0000 ushr 16)
|
blocks[Vec3i(position and 0xF0 ushr 4 and 0xF, y.toInt(), position and 0xF)] = buffer.connection.mapping.getBlockState(blockId)
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
return
|
else -> {
|
||||||
}
|
val rawPos = buffer.readLong()
|
||||||
if (buffer.versionId < ProtocolVersions.V_20W28A) {
|
chunkPosition = Vec2i((rawPos shr 42).toInt(), (rawPos shl 22 shr 42).toInt())
|
||||||
chunkPosition = Vec2i(buffer.readInt(), buffer.readInt())
|
val yOffset = (rawPos.toInt() and 0xFFFFF) * ProtocolDefinition.SECTION_HEIGHT_Y
|
||||||
val count = buffer.readVarInt()
|
if (buffer.versionId > ProtocolVersions.V_1_16_2_PRE3) {
|
||||||
for (i in 0 until count) {
|
buffer.readBoolean() // ToDo
|
||||||
val position = buffer.readByte().toInt()
|
}
|
||||||
val y = buffer.readByte()
|
for (data in buffer.readVarLongArray()) {
|
||||||
val blockId = buffer.readVarInt()
|
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())
|
||||||
blocks[Vec3i(position and 0xF0 ushr 4 and 0xF, y.toInt(), position and 0xF)] = buffer.connection.mapping.getBlockState(blockId)
|
}
|
||||||
}
|
}
|
||||||
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) {
|
override fun handle(connection: PlayConnection) {
|
||||||
val chunk = connection.world.getChunk(chunkPosition) ?: return // thanks mojang
|
val chunk = connection.world.getChunk(chunkPosition) ?: return // thanks mojang
|
||||||
if (!chunk.isFullyLoaded) {
|
if (chunk.sections == null) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
connection.fireEvent(MultiBlockChangeEvent(connection, this))
|
connection.fireEvent(MultiBlockChangeEvent(connection, this))
|
||||||
@ -90,14 +88,14 @@ class PacketMultiBlockChange() : PlayClientboundPacket() {
|
|||||||
// tweak
|
// tweak
|
||||||
if (!connection.version.isFlattened()) {
|
if (!connection.version.isFlattened()) {
|
||||||
for ((key, value) in blocks) {
|
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) {
|
if (block === value) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
chunk.setBlockState(key, block)
|
chunk.setBlockState(key, block)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val sectionHeights = HashSet<Int>()
|
val sectionHeights: MutableSet<Int> = mutableSetOf()
|
||||||
for ((key) in blocks) {
|
for ((key) in blocks) {
|
||||||
sectionHeights.add(key.sectionHeight)
|
sectionHeights.add(key.sectionHeight)
|
||||||
}
|
}
|
||||||
@ -107,6 +105,6 @@ class PacketMultiBlockChange() : PlayClientboundPacket() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun log() {
|
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})")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -418,4 +418,16 @@ public class InByteBuffer {
|
|||||||
public Vec2i readChunkPosition() {
|
public Vec2i readChunkPosition() {
|
||||||
return new Vec2i(readInt(), readInt());
|
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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user