Update matter registry networking
This commit is contained in:
parent
5b403d3d47
commit
0db98ef8f8
@ -53,14 +53,6 @@ fun InputStream.readBigDecimal(): BigDecimal {
|
||||
return BigDecimal(BigInteger(bytes), scale)
|
||||
}
|
||||
|
||||
fun InputStream.readBinaryComponent(): Component? {
|
||||
return Component.Serializer.fromJson(readBinaryJson())
|
||||
}
|
||||
|
||||
fun OutputStream.writeBinaryComponent(component: Component) {
|
||||
writeBinaryJson(Component.Serializer.toJsonTree(component))
|
||||
}
|
||||
|
||||
fun <S : OutputStream, V> S.writeCollection(collection: Collection<V>, writer: S.(V) -> Unit) {
|
||||
writeVarIntLE(collection.size)
|
||||
|
||||
@ -246,12 +238,3 @@ fun OutputStream.writeBinaryString(input: String) {
|
||||
writeVarIntLE(bytes.size)
|
||||
write(bytes)
|
||||
}
|
||||
|
||||
fun InputStream.readResourceLocation(): ResourceLocation {
|
||||
return ResourceLocation(readBinaryString(), readBinaryString())
|
||||
}
|
||||
|
||||
fun OutputStream.writeResourceLocation(value: ResourceLocation) {
|
||||
writeBinaryString(value.namespace)
|
||||
writeBinaryString(value.path)
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import com.google.gson.JsonSyntaxException
|
||||
import com.mojang.brigadier.arguments.StringArgumentType
|
||||
import com.mojang.brigadier.context.CommandContext
|
||||
import com.mojang.serialization.JsonOps
|
||||
import io.netty.buffer.ByteBufAllocator
|
||||
import it.unimi.dsi.fastutil.io.FastByteArrayInputStream
|
||||
import it.unimi.dsi.fastutil.io.FastByteArrayOutputStream
|
||||
import it.unimi.dsi.fastutil.objects.Object2BooleanFunction
|
||||
@ -26,8 +27,10 @@ import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet
|
||||
import net.minecraft.ChatFormatting
|
||||
import net.minecraft.commands.CommandSourceStack
|
||||
import net.minecraft.commands.Commands
|
||||
import net.minecraft.core.RegistryAccess
|
||||
import net.minecraft.core.registries.BuiltInRegistries
|
||||
import net.minecraft.network.FriendlyByteBuf
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.network.chat.MutableComponent
|
||||
import net.minecraft.network.codec.StreamCodec
|
||||
@ -53,13 +56,13 @@ import net.minecraft.world.level.ItemLike
|
||||
import net.neoforged.bus.api.IEventBus
|
||||
import net.neoforged.fml.ModList
|
||||
import net.neoforged.neoforge.capabilities.Capabilities
|
||||
import net.neoforged.neoforge.common.crafting.IShapedRecipe
|
||||
import net.neoforged.neoforge.event.AddReloadListenerEvent
|
||||
import net.neoforged.neoforge.event.OnDatapackSyncEvent
|
||||
import net.neoforged.neoforge.event.RegisterCommandsEvent
|
||||
import net.neoforged.neoforge.event.entity.player.ItemTooltipEvent
|
||||
import net.neoforged.neoforge.event.server.ServerStartedEvent
|
||||
import net.neoforged.neoforge.network.PacketDistributor
|
||||
import net.neoforged.neoforge.network.connection.ConnectionType
|
||||
import net.neoforged.neoforge.network.handling.IPayloadContext
|
||||
import net.neoforged.neoforge.registries.DeferredRegister
|
||||
import net.neoforged.neoforge.server.command.EnumArgument
|
||||
@ -86,6 +89,7 @@ import ru.dbotthepony.mc.otm.core.getReverseTag
|
||||
import ru.dbotthepony.mc.otm.core.isNotEmpty
|
||||
import ru.dbotthepony.mc.otm.core.math.Decimal
|
||||
import ru.dbotthepony.mc.otm.core.math.isZero
|
||||
import ru.dbotthepony.mc.otm.core.readComponent
|
||||
import ru.dbotthepony.mc.otm.core.readItemType
|
||||
import ru.dbotthepony.mc.otm.core.registryName
|
||||
import ru.dbotthepony.mc.otm.core.stream
|
||||
@ -97,6 +101,7 @@ 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.util.writeCollection
|
||||
import ru.dbotthepony.mc.otm.core.writeComponent
|
||||
import ru.dbotthepony.mc.otm.core.writeItemType
|
||||
import ru.dbotthepony.mc.otm.matter.MatterManager.Finder
|
||||
import ru.dbotthepony.mc.otm.milliTime
|
||||
@ -1706,7 +1711,7 @@ object MatterManager {
|
||||
matterValues[item] = value
|
||||
}
|
||||
|
||||
syncRegistry(PacketDistributor::sendToAllPlayers)
|
||||
syncRegistry(server.registryAccess(), PacketDistributor::sendToAllPlayers)
|
||||
}
|
||||
|
||||
fun onDataPackSync(event: OnDatapackSyncEvent) {
|
||||
@ -1714,9 +1719,9 @@ object MatterManager {
|
||||
return
|
||||
|
||||
if (event.player == null) {
|
||||
syncRegistry(PacketDistributor::sendToAllPlayers)
|
||||
syncRegistry(event.playerList.server.registryAccess(), PacketDistributor::sendToAllPlayers)
|
||||
} else {
|
||||
syncRegistry { PacketDistributor.sendToPlayer(event.player as ServerPlayer, it) }
|
||||
syncRegistry(event.playerList.server.registryAccess()) { PacketDistributor.sendToPlayer(event.player as ServerPlayer, it) }
|
||||
}
|
||||
}
|
||||
|
||||
@ -1732,56 +1737,65 @@ object MatterManager {
|
||||
|
||||
private val receivedPackets = ArrayList<SyncPacket>()
|
||||
|
||||
private fun syncRegistry(distributor: (CustomPacketPayload) -> Unit) {
|
||||
private fun syncRegistry(registry: RegistryAccess, distributor: (CustomPacketPayload) -> Unit) {
|
||||
val time = SystemTime()
|
||||
val stream = FastByteArrayOutputStream()
|
||||
val data = DataOutputStream(stream)
|
||||
|
||||
var commentsSize = commentary.size
|
||||
data.writeInt(matterValues.size)
|
||||
|
||||
for ((k, v) in matterValues) {
|
||||
data.writeItemType(k)
|
||||
data.writeMatterValue(v)
|
||||
|
||||
val comment = commentary[k]
|
||||
|
||||
if (comment != null) {
|
||||
commentsSize--
|
||||
data.write(1)
|
||||
data.writeCollection(comment, OutputStream::writeBinaryComponent)
|
||||
} else {
|
||||
data.write(0)
|
||||
}
|
||||
}
|
||||
|
||||
data.writeInt(commentsSize)
|
||||
|
||||
for ((k, v) in commentary) {
|
||||
if (!matterValues.containsKey(k)) {
|
||||
data.writeItemType(k)
|
||||
data.writeCollection(v, OutputStream::writeBinaryComponent)
|
||||
}
|
||||
}
|
||||
|
||||
val deflater = Deflater(5)
|
||||
deflater.setInput(stream.array, 0, stream.length)
|
||||
deflater.finish()
|
||||
val writable = ByteBufAllocator.DEFAULT.heapBuffer()
|
||||
|
||||
val chunks = ArrayList<SyncPacket>()
|
||||
var totalSize = 0
|
||||
var first = true
|
||||
val totalSize: Int
|
||||
var compressedSize: Int = 0
|
||||
|
||||
while (true) {
|
||||
val bytes = ByteArray(2 shl 20 - 1024)
|
||||
val written = deflater.deflate(bytes)
|
||||
try {
|
||||
val data = RegistryFriendlyByteBuf(writable, registry, ConnectionType.NEOFORGE)
|
||||
|
||||
if (written == 0) {
|
||||
break
|
||||
} else {
|
||||
totalSize += written
|
||||
chunks.add(SyncPacket(bytes, written, if (first) { first = false; FIRST } else NORMAL))
|
||||
var commentsSize = commentary.size
|
||||
data.writeInt(matterValues.size)
|
||||
|
||||
for ((k, v) in matterValues) {
|
||||
data.writeItemType(k)
|
||||
data.writeMatterValue(v)
|
||||
|
||||
val comment = commentary[k]
|
||||
|
||||
if (comment != null) {
|
||||
commentsSize--
|
||||
data.writeBoolean(true)
|
||||
data.writeCollection(comment) { _, it -> data.writeComponent(it) }
|
||||
} else {
|
||||
data.writeBoolean(false)
|
||||
}
|
||||
}
|
||||
|
||||
data.writeInt(commentsSize)
|
||||
|
||||
for ((k, v) in commentary) {
|
||||
if (!matterValues.containsKey(k)) {
|
||||
data.writeItemType(k)
|
||||
data.writeCollection(v) { _, it -> data.writeComponent(it) }
|
||||
}
|
||||
}
|
||||
|
||||
val deflater = Deflater(5)
|
||||
deflater.setInput(data.array(), data.arrayOffset(), data.readableBytes())
|
||||
deflater.finish()
|
||||
|
||||
totalSize = data.readableBytes()
|
||||
|
||||
var first = true
|
||||
|
||||
while (true) {
|
||||
val bytes = ByteArray(2 shl 20 - 1024 /* 1 MiB - 1 KiB */)
|
||||
val written = deflater.deflate(bytes)
|
||||
|
||||
if (written == 0) {
|
||||
break
|
||||
} else {
|
||||
compressedSize += written
|
||||
chunks.add(SyncPacket(bytes, written, if (first) { first = false; FIRST } else NORMAL))
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
writable.release()
|
||||
}
|
||||
|
||||
if (chunks.size == 1) {
|
||||
@ -1790,14 +1804,14 @@ object MatterManager {
|
||||
chunks.last().mode = LAST
|
||||
}
|
||||
|
||||
LOGGER.debug("Encoding matter registry packet took ${time.millis}ms, (${stream.length} bytes total, $totalSize bytes compressed)")
|
||||
LOGGER.debug("Encoding matter registry packets took ${time.millis}ms, (${totalSize} bytes total, $compressedSize bytes compressed)")
|
||||
|
||||
for (chunk in chunks) {
|
||||
distributor.invoke(chunk)
|
||||
}
|
||||
}
|
||||
|
||||
private fun playRegistryPackets() {
|
||||
private fun playRegistryPackets(registry: RegistryAccess) {
|
||||
val time = SystemTime()
|
||||
var totalCompressedSize = 0
|
||||
|
||||
@ -1820,66 +1834,53 @@ object MatterManager {
|
||||
|
||||
receivedPackets.clear()
|
||||
|
||||
val chunks = ArrayList<ByteArray>()
|
||||
var size = 0
|
||||
val inflater = Inflater()
|
||||
inflater.setInput(compressed)
|
||||
val spliced = ByteBufAllocator.DEFAULT.buffer(receivedPackets.sumOf { it.length })
|
||||
|
||||
while (!inflater.finished()) {
|
||||
val chunk = ByteArray(2 shl 16)
|
||||
val inflated = inflater.inflate(chunk)
|
||||
try {
|
||||
val buffer = ByteArray(2 shl 16)
|
||||
val inflater = Inflater()
|
||||
inflater.setInput(compressed)
|
||||
|
||||
if (inflated == 0) {
|
||||
break
|
||||
} else {
|
||||
size += inflated
|
||||
while (!inflater.finished()) {
|
||||
val inflated = inflater.inflate(buffer)
|
||||
|
||||
if (size >= 1 shl 24 /* 16 MiB */) {
|
||||
throw IndexOutOfBoundsException("Pipe Bomb")
|
||||
}
|
||||
|
||||
if (inflated == 2 shl 16) {
|
||||
chunks.add(chunk)
|
||||
if (inflated == 0) {
|
||||
break
|
||||
} else {
|
||||
chunks.add(chunk.copyOfRange(0, inflated))
|
||||
spliced.writeBytes(buffer, 0, inflated)
|
||||
|
||||
if (spliced.writerIndex() >= 1 shl 24 /* 16 MiB */) {
|
||||
throw IndexOutOfBoundsException("Pipe Bomb")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val spliced = ByteArray(size)
|
||||
var pointer2 = 0
|
||||
val data = RegistryFriendlyByteBuf(spliced, registry, ConnectionType.NEOFORGE)
|
||||
val valuesSize = data.readInt()
|
||||
|
||||
for (chunk in chunks) {
|
||||
for (i in chunk.indices) {
|
||||
spliced[pointer2++] = chunk[i]
|
||||
matterValues.clear()
|
||||
commentary.clear()
|
||||
|
||||
for (i in 0 until valuesSize) {
|
||||
val type = data.readItemType()
|
||||
check(matterValues.put(type, data.readMatterValue()) == null) { "Duplicate item type $type" }
|
||||
|
||||
if (data.readBoolean()) {
|
||||
commentary[type] = data.readCollection(::ArrayList) { data.readComponent() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val stream = FastByteArrayInputStream(spliced)
|
||||
val data = DataInputStream(stream)
|
||||
val commentsSize = data.readInt()
|
||||
|
||||
val valuesSize = data.readInt()
|
||||
|
||||
matterValues.clear()
|
||||
commentary.clear()
|
||||
|
||||
for (i in 0 until valuesSize) {
|
||||
val type = data.readItemType()
|
||||
check(matterValues.put(type, data.readMatterValue()) == null) { "Duplicate item type $type" }
|
||||
|
||||
if (data.read() > 0) {
|
||||
commentary[type] = data.readCollection { readBinaryComponent()!! }
|
||||
for (i in 0 until commentsSize) {
|
||||
val type = data.readItemType()
|
||||
check(commentary.put(type, data.readCollection(::ArrayList) { data.readComponent() }) == null) { "Duplicate commentary item type $type" }
|
||||
}
|
||||
|
||||
LOGGER.debug("Decoding matter registry packets took ${time.millis}ms ($totalCompressedSize bytes compressed, ${spliced.writerIndex()} bytes total)")
|
||||
} finally {
|
||||
spliced.release()
|
||||
}
|
||||
|
||||
val commentsSize = data.readInt()
|
||||
|
||||
for (i in 0 until commentsSize) {
|
||||
val type = data.readItemType()
|
||||
check(commentary.put(type, data.readCollection { readBinaryComponent()!! }) == null) { "Duplicate commentary item type $type" }
|
||||
}
|
||||
|
||||
LOGGER.debug("Decoding matter registry packets took ${time.millis}ms ($totalCompressedSize bytes compressed, $size bytes total)")
|
||||
}
|
||||
|
||||
fun readSyncPacket(buff: FriendlyByteBuf): SyncPacket {
|
||||
@ -1918,11 +1919,11 @@ object MatterManager {
|
||||
receivedPackets.add(this)
|
||||
} else if (mode == LAST) {
|
||||
receivedPackets.add(this)
|
||||
playRegistryPackets()
|
||||
playRegistryPackets(context.player().registryAccess())
|
||||
} else if (mode == FIRST_AND_LAST) {
|
||||
receivedPackets.clear()
|
||||
receivedPackets.add(this)
|
||||
playRegistryPackets()
|
||||
playRegistryPackets(context.player().registryAccess())
|
||||
} else {
|
||||
receivedPackets.add(this)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user