For the love of god
This commit is contained in:
parent
10e71d2ab8
commit
a36e47c629
@ -1,14 +1,20 @@
|
|||||||
package ru.dbotthepony.mc.otm.network
|
package ru.dbotthepony.mc.otm.network
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.io.FastByteArrayInputStream
|
import it.unimi.dsi.fastutil.io.FastByteArrayInputStream
|
||||||
|
import it.unimi.dsi.fastutil.objects.Object2ObjectFunction
|
||||||
|
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap
|
||||||
import net.minecraft.core.BlockPos
|
import net.minecraft.core.BlockPos
|
||||||
import net.minecraft.network.FriendlyByteBuf
|
import net.minecraft.network.FriendlyByteBuf
|
||||||
|
import net.minecraft.world.level.Level
|
||||||
import net.minecraftforge.network.NetworkDirection
|
import net.minecraftforge.network.NetworkDirection
|
||||||
import net.minecraftforge.network.NetworkEvent
|
import net.minecraftforge.network.NetworkEvent
|
||||||
import org.apache.logging.log4j.LogManager
|
import org.apache.logging.log4j.LogManager
|
||||||
import ru.dbotthepony.mc.otm.android.feature.ItemEntityDataPacket
|
import ru.dbotthepony.mc.otm.android.feature.ItemEntityDataPacket
|
||||||
import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity
|
import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity
|
||||||
import ru.dbotthepony.mc.otm.client.minecraft
|
import ru.dbotthepony.mc.otm.client.minecraft
|
||||||
|
import ru.dbotthepony.mc.otm.client.onceClient
|
||||||
|
import java.lang.ref.SoftReference
|
||||||
|
import java.util.WeakHashMap
|
||||||
import java.util.function.Supplier
|
import java.util.function.Supplier
|
||||||
|
|
||||||
class BlockEntitySyncPacket(val position: BlockPos, val buffer: ByteArray, val validBytes: Int) : MatteryPacket {
|
class BlockEntitySyncPacket(val position: BlockPos, val buffer: ByteArray, val validBytes: Int) : MatteryPacket {
|
||||||
@ -17,23 +23,63 @@ class BlockEntitySyncPacket(val position: BlockPos, val buffer: ByteArray, val v
|
|||||||
buff.writeBytes(buffer, 0, validBytes)
|
buff.writeBytes(buffer, 0, validBytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun execute() {
|
||||||
|
val level = minecraft.player?.level
|
||||||
|
|
||||||
|
if (level == null) {
|
||||||
|
LOGGER.error("Received BlockEntitySyncPacket before we are in valid level.")
|
||||||
|
|
||||||
|
onceClient {
|
||||||
|
execute()
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val blockEntity = level.getBlockEntity(position)
|
||||||
|
|
||||||
|
if (blockEntity == null) {
|
||||||
|
LOGGER.warn("Putting BlockEntitySyncPacket received for $position into backlog because there is literally no block entity there!")
|
||||||
|
LOGGER.warn("This is CERTAINLY a bug in one of optimizing mods you have or server has installed!")
|
||||||
|
LOGGER.warn("This can cause memory leak.")
|
||||||
|
|
||||||
|
backlog.computeIfAbsent(level) { Object2ObjectOpenHashMap() }
|
||||||
|
.computeIfAbsent(position, Object2ObjectFunction { ArrayList() })
|
||||||
|
.add(this)
|
||||||
|
|
||||||
|
return
|
||||||
|
} else if (blockEntity !is MatteryBlockEntity) {
|
||||||
|
LOGGER.warn("Dropping BlockEntitySyncPacket received for $position, because there is $blockEntity which is not MatteryBlockEntity!")
|
||||||
|
backlog[level]?.remove(position)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val packets = backlog[level]?.remove(position)
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (packets != null) {
|
||||||
|
for (packet in packets) {
|
||||||
|
blockEntity.synchronizer.read(FastByteArrayInputStream(packet.buffer, 0, packet.validBytes))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
blockEntity.synchronizer.read(FastByteArrayInputStream(buffer, 0, validBytes))
|
||||||
|
} catch(err: Throwable) {
|
||||||
|
LOGGER.error("Exception while reading synchronized BlockEntity data!\nPosition: $position\nBlock: ${level.getBlockState(position)}\nBlock entity: $blockEntity", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||||
context.packetHandled = true
|
context.packetHandled = true
|
||||||
|
|
||||||
context.enqueueWork {
|
context.enqueueWork {
|
||||||
val level = minecraft.player?.level ?: return@enqueueWork
|
execute()
|
||||||
val blockEntity = level.getBlockEntity(position) as? MatteryBlockEntity ?: return@enqueueWork
|
|
||||||
|
|
||||||
try {
|
|
||||||
blockEntity.synchronizer.read(FastByteArrayInputStream(buffer, 0, validBytes))
|
|
||||||
} catch(err: Throwable) {
|
|
||||||
LOGGER.error("Exception while reading synchronized BlockEntity data!\nPosition: $position\nBlock: ${level.getBlockState(position)}\nBlock entity: $blockEntity", err)
|
|
||||||
throw err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
private val backlog = WeakHashMap<Level, Object2ObjectOpenHashMap<BlockPos, ArrayList<BlockEntitySyncPacket>>>()
|
||||||
|
|
||||||
fun read(buff: FriendlyByteBuf): BlockEntitySyncPacket {
|
fun read(buff: FriendlyByteBuf): BlockEntitySyncPacket {
|
||||||
val position = buff.readBlockPos()
|
val position = buff.readBlockPos()
|
||||||
val size = buff.readableBytes()
|
val size = buff.readableBytes()
|
||||||
@ -47,7 +93,7 @@ class BlockEntitySyncPacket(val position: BlockPos, val buffer: ByteArray, val v
|
|||||||
}
|
}
|
||||||
|
|
||||||
object WorldNetworkChannel : MatteryNetworkChannel(
|
object WorldNetworkChannel : MatteryNetworkChannel(
|
||||||
version = "2",
|
version = "3",
|
||||||
name = "world"
|
name = "world"
|
||||||
) {
|
) {
|
||||||
fun register() {
|
fun register() {
|
||||||
|
Loading…
Reference in New Issue
Block a user