Compress matter registry packet
# Conflicts: # src/main/kotlin/ru/dbotthepony/mc/otm/core/Ext.kt # src/main/kotlin/ru/dbotthepony/mc/otm/matter/IMatterValue.kt # src/main/kotlin/ru/dbotthepony/mc/otm/matter/MatterManager.kt
This commit is contained in:
parent
26a064fbe2
commit
36c14be025
@ -28,6 +28,9 @@ import net.minecraftforge.items.IItemHandler
|
||||
import net.minecraftforge.registries.ForgeRegistries
|
||||
import net.minecraftforge.registries.ForgeRegistry
|
||||
import net.minecraftforge.registries.IForgeRegistry
|
||||
import ru.dbotthepony.mc.otm.core.util.readInt
|
||||
import java.io.InputStream
|
||||
import java.io.OutputStream
|
||||
import java.lang.ref.Reference
|
||||
import java.lang.ref.WeakReference
|
||||
import java.math.BigInteger
|
||||
@ -344,6 +347,10 @@ fun FriendlyByteBuf.readItemType(): Item? {
|
||||
return ForgeRegistries.ITEMS.getValue(readInt())
|
||||
}
|
||||
|
||||
fun InputStream.readItemType(): Item? {
|
||||
return ForgeRegistries.ITEMS.getValue(readInt())
|
||||
}
|
||||
|
||||
operator fun <T : Comparable<T>> StateHolder<*, *>.get(property: Property<T>): T {
|
||||
return getValue(property)
|
||||
}
|
||||
|
@ -262,3 +262,24 @@ fun FriendlyByteBuf.readBinaryComponent(): Component {
|
||||
fun FriendlyByteBuf.writeBinaryComponent(component: Component) {
|
||||
writeJson(Component.Serializer.toJsonTree(component))
|
||||
}
|
||||
|
||||
fun <S : OutputStream, V> S.writeCollection(collection: Collection<V>, writer: S.(V) -> Unit) {
|
||||
writeVarIntLE(collection.size)
|
||||
|
||||
for (value in collection) {
|
||||
writer(this, value)
|
||||
}
|
||||
}
|
||||
|
||||
fun <S : InputStream, V, C : MutableCollection<V>> S.readCollection(reader: S.() -> V, factory: (Int) -> C): C {
|
||||
val size = readVarIntLE()
|
||||
val collection = factory.invoke(size)
|
||||
|
||||
for (i in 0 until size) {
|
||||
collection.add(reader(this))
|
||||
}
|
||||
|
||||
return collection
|
||||
}
|
||||
|
||||
fun <S : InputStream, V> S.readCollection(reader: S.() -> V) = readCollection(reader, ::ArrayList)
|
||||
|
@ -4,6 +4,10 @@ import net.minecraft.network.FriendlyByteBuf
|
||||
import ru.dbotthepony.mc.otm.core.Decimal
|
||||
import ru.dbotthepony.mc.otm.core.readDecimal
|
||||
import ru.dbotthepony.mc.otm.core.writeDecimal
|
||||
import ru.dbotthepony.mc.otm.core.util.readDouble
|
||||
import ru.dbotthepony.mc.otm.core.util.writeDouble
|
||||
import java.io.InputStream
|
||||
import java.io.OutputStream
|
||||
|
||||
interface IMatterValue : Comparable<IMatterValue> {
|
||||
val matter: Decimal
|
||||
@ -51,6 +55,11 @@ fun FriendlyByteBuf.writeMatterValue(value: IMatterValue) {
|
||||
writeDouble(value.complexity)
|
||||
}
|
||||
|
||||
fun OutputStream.writeMatterValue(value: IMatterValue) {
|
||||
writeDecimal(value.matter)
|
||||
writeDouble(value.complexity)
|
||||
}
|
||||
|
||||
fun FriendlyByteBuf.readMatterValue(): IMatterValue {
|
||||
val matter = readDecimal()
|
||||
val complexity = readDouble()
|
||||
@ -62,6 +71,17 @@ fun FriendlyByteBuf.readMatterValue(): IMatterValue {
|
||||
}
|
||||
}
|
||||
|
||||
fun InputStream.readMatterValue(): IMatterValue {
|
||||
val matter = readDecimal()
|
||||
val complexity = readDouble()
|
||||
|
||||
if (matter.isZero && complexity == 0.0) {
|
||||
return IMatterValue.Companion
|
||||
} else {
|
||||
return MatterValue(matter, complexity)
|
||||
}
|
||||
}
|
||||
|
||||
data class MatterValue(
|
||||
override val matter: Decimal,
|
||||
override val complexity: Double
|
||||
|
@ -11,6 +11,8 @@ import com.google.gson.JsonSyntaxException
|
||||
import com.mojang.blaze3d.platform.InputConstants
|
||||
import com.mojang.brigadier.arguments.StringArgumentType
|
||||
import com.mojang.brigadier.context.CommandContext
|
||||
import it.unimi.dsi.fastutil.io.FastByteArrayInputStream
|
||||
import it.unimi.dsi.fastutil.io.FastByteArrayOutputStream
|
||||
import it.unimi.dsi.fastutil.objects.Object2BooleanFunction
|
||||
import it.unimi.dsi.fastutil.objects.Object2BooleanOpenHashMap
|
||||
import it.unimi.dsi.fastutil.objects.Reference2BooleanFunction
|
||||
@ -78,17 +80,23 @@ import ru.dbotthepony.mc.otm.core.readItemType
|
||||
import ru.dbotthepony.mc.otm.core.registryName
|
||||
import ru.dbotthepony.mc.otm.core.stream
|
||||
import ru.dbotthepony.mc.otm.core.util.readBinaryComponent
|
||||
import ru.dbotthepony.mc.otm.core.util.readCollection
|
||||
import ru.dbotthepony.mc.otm.core.util.writeBinaryComponent
|
||||
import ru.dbotthepony.mc.otm.core.writeItemType
|
||||
import ru.dbotthepony.mc.otm.core.util.writeCollection
|
||||
import ru.dbotthepony.mc.otm.network.MatteryPacket
|
||||
import ru.dbotthepony.mc.otm.network.RegistryNetworkChannel
|
||||
import ru.dbotthepony.mc.otm.registry.RegistryDelegate
|
||||
import ru.dbotthepony.mc.otm.storage.ItemStackWrapper
|
||||
import java.io.DataInputStream
|
||||
import java.io.DataOutputStream
|
||||
import java.io.File
|
||||
import java.io.OutputStream
|
||||
import java.math.BigInteger
|
||||
import java.util.*
|
||||
import java.util.function.Supplier
|
||||
import java.util.stream.Stream
|
||||
import java.util.zip.Deflater
|
||||
import java.util.zip.Inflater
|
||||
import kotlin.ConcurrentModificationException
|
||||
import kotlin.collections.ArrayDeque
|
||||
import kotlin.collections.ArrayList
|
||||
@ -1088,7 +1096,6 @@ object MatterManager {
|
||||
|
||||
fun tooltipEvent(event: ItemTooltipEvent) {
|
||||
val window = minecraft.window.window
|
||||
|
||||
if (InputConstants.isKeyDown(window, GLFW.GLFW_KEY_LEFT_SHIFT) || InputConstants.isKeyDown(window, GLFW.GLFW_KEY_RIGHT_SHIFT)) {
|
||||
val matter = get(event.itemStack, accountForStackSize = false)
|
||||
|
||||
@ -1397,12 +1404,70 @@ object MatterManager {
|
||||
|
||||
val time = SystemTime()
|
||||
|
||||
val result = SyncPacket(
|
||||
buff.readMap(FriendlyByteBuf::readItemType, FriendlyByteBuf::readMatterValue),
|
||||
buff.readMap(FriendlyByteBuf::readItemType) { self -> self.readCollection(::ArrayList, FriendlyByteBuf::readBinaryComponent) }
|
||||
)
|
||||
val bbytes = ByteArray(buff.readableBytes())
|
||||
buff.readBytes(bbytes)
|
||||
|
||||
LOGGER.debug("Reading matter registry packet took ${time.millis}ms")
|
||||
val chunks = ArrayList<ByteArray>()
|
||||
var size = 0
|
||||
val inflater = Inflater()
|
||||
inflater.setInput(bbytes)
|
||||
|
||||
while (!inflater.finished()) {
|
||||
val chunk = ByteArray(4096)
|
||||
val inflated = inflater.inflate(chunk)
|
||||
|
||||
if (inflated == 0) {
|
||||
break
|
||||
} else {
|
||||
size += inflated
|
||||
|
||||
if (size >= 1 shl 24 /* 16 MiB */) {
|
||||
throw IndexOutOfBoundsException("Pipe Bomb")
|
||||
}
|
||||
|
||||
if (inflated == 4096) {
|
||||
chunks.add(chunk)
|
||||
} else {
|
||||
chunks.add(chunk.copyOfRange(0, inflated))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val spliced = ByteArray(size)
|
||||
var pointer = 0
|
||||
|
||||
for (chunk in chunks) {
|
||||
for (i in chunk.indices) {
|
||||
spliced[pointer++] = chunk[i]
|
||||
}
|
||||
}
|
||||
|
||||
val stream = FastByteArrayInputStream(spliced)
|
||||
val data = DataInputStream(stream)
|
||||
|
||||
val valuesSize = data.readInt()
|
||||
val values = Reference2ObjectOpenHashMap<Item, IMatterValue>(valuesSize)
|
||||
val comments = Reference2ObjectOpenHashMap<Item, ArrayList<Component>>()
|
||||
|
||||
for (i in 0 until valuesSize) {
|
||||
val type = data.readItemType()
|
||||
check(values.put(type, data.readMatterValue()) == null) { "Duplicate item type $type" }
|
||||
|
||||
if (data.read() > 0) {
|
||||
comments[type] = data.readCollection { readBinaryComponent()!! }
|
||||
}
|
||||
}
|
||||
|
||||
val commentsSize = data.readInt()
|
||||
|
||||
for (i in 0 until commentsSize) {
|
||||
val type = data.readItemType()
|
||||
check(comments.put(type, data.readCollection { readBinaryComponent()!! }) == null) { "Duplicate commentary item type $type" }
|
||||
}
|
||||
|
||||
val result = SyncPacket(values, comments)
|
||||
|
||||
LOGGER.debug("Reading matter registry packet took ${time.millis}ms (${bbytes.size} bytes compressed, $size bytes total)")
|
||||
|
||||
return result
|
||||
}
|
||||
@ -1413,9 +1478,54 @@ object MatterManager {
|
||||
) : MatteryPacket {
|
||||
override fun write(buff: FriendlyByteBuf) {
|
||||
val time = SystemTime()
|
||||
buff.writeMap(values, FriendlyByteBuf::writeItemType, FriendlyByteBuf::writeMatterValue)
|
||||
buff.writeMap(comments, FriendlyByteBuf::writeItemType) { self, value -> self.writeCollection(value, FriendlyByteBuf::writeBinaryComponent) }
|
||||
LOGGER.debug("Encoding matter registry packet took ${time.millis}ms, written total ${buff.writerIndex() - 1} bytes")
|
||||
|
||||
val stream = FastByteArrayOutputStream()
|
||||
val data = DataOutputStream(stream)
|
||||
|
||||
var commentsSize = comments.size
|
||||
data.writeInt(values.size)
|
||||
|
||||
for ((k, v) in values) {
|
||||
data.writeInt(ForgeRegistries.ITEMS.getID(k))
|
||||
data.writeMatterValue(v)
|
||||
|
||||
val comment = comments[k]
|
||||
|
||||
if (comment != null) {
|
||||
commentsSize--
|
||||
data.write(1)
|
||||
data.writeCollection(comment, OutputStream::writeBinaryComponent)
|
||||
} else {
|
||||
data.write(0)
|
||||
}
|
||||
}
|
||||
|
||||
data.writeInt(commentsSize)
|
||||
|
||||
for ((k, v) in comments) {
|
||||
if (!values.containsKey(k)) {
|
||||
data.writeInt(ForgeRegistries.ITEMS.getID(k))
|
||||
data.writeCollection(v, OutputStream::writeBinaryComponent)
|
||||
}
|
||||
}
|
||||
|
||||
val deflater = Deflater(5)
|
||||
deflater.setInput(stream.array, 0, stream.length)
|
||||
deflater.finish()
|
||||
|
||||
val bytes = ByteArray(4096)
|
||||
|
||||
while (true) {
|
||||
val written = deflater.deflate(bytes)
|
||||
|
||||
if (written == 0) {
|
||||
break
|
||||
} else {
|
||||
buff.writeBytes(bytes, 0, written)
|
||||
}
|
||||
}
|
||||
|
||||
LOGGER.debug("Encoding matter registry packet took ${time.millis}ms, (${stream.length} bytes total, ${buff.writerIndex() - 1} bytes compressed)")
|
||||
}
|
||||
|
||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||
@ -1430,7 +1540,7 @@ object MatterManager {
|
||||
commentary.clear()
|
||||
|
||||
for ((k, v) in comments) {
|
||||
commentary[k] = ArrayList<Component>(v.size).also { it.addAll(v) }
|
||||
commentary[k] = ArrayList(v)
|
||||
}
|
||||
|
||||
LOGGER.debug("Updating matter registry from packet took ${time.millis}ms")
|
||||
|
Loading…
Reference in New Issue
Block a user