Fields now know their payload sizes, field synchronizer stream now can be safely embedded into any other data structure
This commit is contained in:
parent
0396a4f7c0
commit
286174d8a7
@ -1,6 +1,7 @@
|
||||
package ru.dbotthepony.mc.otm.network
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectAVLTreeMap
|
||||
import it.unimi.dsi.fastutil.io.FastByteArrayInputStream
|
||||
import it.unimi.dsi.fastutil.io.FastByteArrayOutputStream
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArraySet
|
||||
import it.unimi.dsi.fastutil.objects.Reference2ObjectFunction
|
||||
@ -48,6 +49,10 @@ sealed interface IField<V> : ReadOnlyProperty<Any, V>, Supplier<V>, () -> V {
|
||||
val name: String
|
||||
|
||||
fun write(stream: DataOutputStream, endpoint: FieldSynchronizer.Endpoint)
|
||||
fun read(stream: DataInputStream, payloadSize: Int) {
|
||||
read(stream)
|
||||
}
|
||||
|
||||
fun read(stream: DataInputStream)
|
||||
|
||||
override fun getValue(thisRef: Any, property: KProperty<*>): V {
|
||||
@ -463,7 +468,6 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
||||
}
|
||||
|
||||
val stream = FastByteArrayOutputStream()
|
||||
val dataStream = DataOutputStream(stream)
|
||||
|
||||
if (mappingVersion != this@FieldSynchronizer.mappingVersion) {
|
||||
stream.write(1)
|
||||
@ -486,11 +490,18 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
||||
val id = field.id
|
||||
check(id > 0) { "This should never happen: $field maps to invalid ID: $id!" }
|
||||
stream.writeVarIntLE(id)
|
||||
|
||||
val innerStream = FastByteArrayOutputStream()
|
||||
val dataStream = DataOutputStream(innerStream)
|
||||
|
||||
field.write(dataStream, this)
|
||||
|
||||
stream.writeVarIntLE(innerStream.length)
|
||||
stream.write(innerStream.array, 0, innerStream.length)
|
||||
}
|
||||
|
||||
dirtyFields.clear()
|
||||
dataStream.write(0)
|
||||
stream.write(0)
|
||||
|
||||
return stream
|
||||
}
|
||||
@ -1045,8 +1056,8 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
||||
private val missingFields = ObjectArraySet<String>()
|
||||
private val missingFieldsMap = Int2ObjectAVLTreeMap<String>()
|
||||
|
||||
fun applyNetworkPayload(stream: DataInputStream): Int {
|
||||
if (stream.readBoolean()) {
|
||||
fun applyNetworkPayload(stream: InputStream): Int {
|
||||
if (stream.read() > 0) {
|
||||
idToField.clear()
|
||||
missingFieldsMap.clear()
|
||||
|
||||
@ -1080,28 +1091,24 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
||||
|
||||
while (fieldId != 0) {
|
||||
val field = idToField[fieldId]
|
||||
val payloadSize = stream.readVarIntLE()
|
||||
|
||||
if (field == null) {
|
||||
LOGGER.error("Unable to read field $fieldId (${missingFieldsMap[fieldId]}) because we don't know anything about it!")
|
||||
stream.skipNBytes(payloadSize.toLong())
|
||||
continue
|
||||
}
|
||||
|
||||
field.read(stream)
|
||||
val bytes = ByteArray(payloadSize)
|
||||
stream.read(bytes)
|
||||
field.read(DataInputStream(FastByteArrayInputStream(bytes)), payloadSize)
|
||||
fieldId = stream.readVarIntLE()
|
||||
i++
|
||||
}
|
||||
|
||||
if (stream.read() != -1) {
|
||||
throw IllegalStateException("Stream wasn't fully drain!")
|
||||
}
|
||||
|
||||
return i
|
||||
}
|
||||
|
||||
fun applyNetworkPayload(stream: InputStream): Int {
|
||||
return applyNetworkPayload(DataInputStream(stream))
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val ClearBacklogEntry = { stream: DataOutputStream -> stream.write(MapAction.CLEAR.ordinal + 1) }
|
||||
private val MapActionList = MapAction.values()
|
||||
|
Loading…
Reference in New Issue
Block a user