|
|
@ -1,14 +1,9 @@
|
|
|
|
package ru.dbotthepony.mc.otm.network
|
|
|
|
package ru.dbotthepony.mc.otm.network
|
|
|
|
|
|
|
|
|
|
|
|
import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap
|
|
|
|
|
|
|
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
|
|
|
|
|
|
|
|
import it.unimi.dsi.fastutil.io.FastByteArrayInputStream
|
|
|
|
|
|
|
|
import it.unimi.dsi.fastutil.io.FastByteArrayOutputStream
|
|
|
|
import it.unimi.dsi.fastutil.io.FastByteArrayOutputStream
|
|
|
|
import it.unimi.dsi.fastutil.objects.ObjectArraySet
|
|
|
|
|
|
|
|
import it.unimi.dsi.fastutil.objects.Reference2ObjectFunction
|
|
|
|
import it.unimi.dsi.fastutil.objects.Reference2ObjectFunction
|
|
|
|
import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap
|
|
|
|
import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap
|
|
|
|
import it.unimi.dsi.fastutil.objects.ReferenceArraySet
|
|
|
|
import it.unimi.dsi.fastutil.objects.ReferenceArraySet
|
|
|
|
import net.minecraft.nbt.NbtAccounter
|
|
|
|
|
|
|
|
import net.minecraft.world.item.ItemStack
|
|
|
|
import net.minecraft.world.item.ItemStack
|
|
|
|
import org.apache.logging.log4j.LogManager
|
|
|
|
import org.apache.logging.log4j.LogManager
|
|
|
|
import ru.dbotthepony.mc.otm.core.*
|
|
|
|
import ru.dbotthepony.mc.otm.core.*
|
|
|
@ -40,9 +35,6 @@ import java.lang.ref.WeakReference
|
|
|
|
import java.math.BigDecimal
|
|
|
|
import java.math.BigDecimal
|
|
|
|
import java.util.*
|
|
|
|
import java.util.*
|
|
|
|
import java.util.function.Supplier
|
|
|
|
import java.util.function.Supplier
|
|
|
|
import kotlin.ConcurrentModificationException
|
|
|
|
|
|
|
|
import kotlin.collections.ArrayList
|
|
|
|
|
|
|
|
import kotlin.collections.HashMap
|
|
|
|
|
|
|
|
import kotlin.properties.ReadOnlyProperty
|
|
|
|
import kotlin.properties.ReadOnlyProperty
|
|
|
|
import kotlin.reflect.KMutableProperty0
|
|
|
|
import kotlin.reflect.KMutableProperty0
|
|
|
|
import kotlin.reflect.KProperty
|
|
|
|
import kotlin.reflect.KProperty
|
|
|
@ -66,13 +58,8 @@ sealed interface IField<V> : ReadOnlyProperty<Any?, V>, Supplier<V>, () -> V {
|
|
|
|
fun markDirty()
|
|
|
|
fun markDirty()
|
|
|
|
fun markDirty(endpoint: FieldSynchronizer.Endpoint)
|
|
|
|
fun markDirty(endpoint: FieldSynchronizer.Endpoint)
|
|
|
|
val value: V
|
|
|
|
val value: V
|
|
|
|
val name: String
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fun write(stream: DataOutputStream, endpoint: FieldSynchronizer.Endpoint)
|
|
|
|
fun write(stream: DataOutputStream, endpoint: FieldSynchronizer.Endpoint)
|
|
|
|
fun read(stream: DataInputStream, payloadSize: Int) {
|
|
|
|
|
|
|
|
read(stream)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fun read(stream: DataInputStream)
|
|
|
|
fun read(stream: DataInputStream)
|
|
|
|
|
|
|
|
|
|
|
|
override fun getValue(thisRef: Any?, property: KProperty<*>): V {
|
|
|
|
override fun getValue(thisRef: Any?, property: KProperty<*>): V {
|
|
|
@ -128,12 +115,6 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
|
|
|
|
|
|
|
|
|
|
|
private var nextFieldID = 0
|
|
|
|
private var nextFieldID = 0
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* returns dummy field name
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
fun nextFieldName() = "___field_${nextFieldID++}"
|
|
|
|
|
|
|
|
private var mappingVersion = 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
val hasObservers: Boolean get() = observers.isNotEmpty()
|
|
|
|
val hasObservers: Boolean get() = observers.isNotEmpty()
|
|
|
|
val isEmpty: Boolean get() = fields.isEmpty()
|
|
|
|
val isEmpty: Boolean get() = fields.isEmpty()
|
|
|
|
val isNotEmpty: Boolean get() = fields.isNotEmpty()
|
|
|
|
val isNotEmpty: Boolean get() = fields.isNotEmpty()
|
|
|
@ -157,68 +138,68 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
|
|
|
hasChanges = false
|
|
|
|
hasChanges = false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@JvmOverloads fun byte(getter: () -> Byte, name: String? = nextFieldName()) = ComputedField(getter, ByteValueCodec, name ?: nextFieldName())
|
|
|
|
fun byte(getter: () -> Byte) = ComputedField(getter, ByteValueCodec)
|
|
|
|
@JvmOverloads fun bool(getter: () -> Boolean, name: String? = nextFieldName()) = ComputedField(getter, BooleanValueCodec, name ?: nextFieldName())
|
|
|
|
fun bool(getter: () -> Boolean) = ComputedField(getter, BooleanValueCodec)
|
|
|
|
@JvmOverloads fun short(getter: () -> Short, name: String? = nextFieldName()) = ComputedField(getter, ShortValueCodec, name ?: nextFieldName())
|
|
|
|
fun short(getter: () -> Short) = ComputedField(getter, ShortValueCodec)
|
|
|
|
@JvmOverloads fun long(getter: () -> Long, name: String? = nextFieldName()) = ComputedField(getter, VarLongValueCodec, name ?: nextFieldName())
|
|
|
|
fun long(getter: () -> Long) = ComputedField(getter, VarLongValueCodec)
|
|
|
|
@JvmOverloads fun fixedLong(getter: () -> Long, name: String? = nextFieldName()) = ComputedField(getter, LongValueCodec, name ?: nextFieldName())
|
|
|
|
fun fixedLong(getter: () -> Long) = ComputedField(getter, LongValueCodec)
|
|
|
|
@JvmOverloads fun float(getter: () -> Float, name: String? = nextFieldName()) = ComputedField(getter, FloatValueCodec, name ?: nextFieldName())
|
|
|
|
fun float(getter: () -> Float) = ComputedField(getter, FloatValueCodec)
|
|
|
|
@JvmOverloads fun double(getter: () -> Double, name: String? = nextFieldName()) = ComputedField(getter, DoubleValueCodec, name ?: nextFieldName())
|
|
|
|
fun double(getter: () -> Double) = ComputedField(getter, DoubleValueCodec)
|
|
|
|
@JvmOverloads fun uuid(getter: () -> UUID, name: String? = nextFieldName()) = ComputedField(getter, UUIDValueCodec, name ?: nextFieldName())
|
|
|
|
fun uuid(getter: () -> UUID) = ComputedField(getter, UUIDValueCodec)
|
|
|
|
@JvmOverloads fun int(getter: () -> Int, name: String? = nextFieldName()) = ComputedField(getter, VarIntValueCodec, name ?: nextFieldName())
|
|
|
|
fun int(getter: () -> Int) = ComputedField(getter, VarIntValueCodec)
|
|
|
|
@JvmOverloads fun fixedInt(getter: () -> Int, name: String? = nextFieldName()) = ComputedField(getter, IntValueCodec, name ?: nextFieldName())
|
|
|
|
fun fixedInt(getter: () -> Int) = ComputedField(getter, IntValueCodec)
|
|
|
|
@JvmOverloads fun fraction(getter: () -> Decimal, name: String? = nextFieldName()) = ComputedField(getter, ImpreciseFractionValueCodec, name ?: nextFieldName())
|
|
|
|
fun fraction(getter: () -> Decimal) = ComputedField(getter, ImpreciseFractionValueCodec)
|
|
|
|
@JvmOverloads fun bigDecimal(getter: () -> BigDecimal, name: String? = nextFieldName()) = ComputedField(getter, BigDecimalValueCodec, name ?: nextFieldName())
|
|
|
|
fun bigDecimal(getter: () -> BigDecimal) = ComputedField(getter, BigDecimalValueCodec)
|
|
|
|
@JvmOverloads fun item(getter: () -> ItemStack, name: String? = nextFieldName()) = ComputedField(getter, ItemStackValueCodec, name ?: nextFieldName())
|
|
|
|
fun item(getter: () -> ItemStack) = ComputedField(getter, ItemStackValueCodec)
|
|
|
|
@JvmOverloads fun string(getter: () -> String, name: String? = nextFieldName()) = ComputedField(getter, BinaryStringCodec, name ?: nextFieldName())
|
|
|
|
fun string(getter: () -> String) = ComputedField(getter, BinaryStringCodec)
|
|
|
|
|
|
|
|
|
|
|
|
@JvmOverloads fun byte(getter: KProperty0<Byte>, name: String? = nextFieldName()) = ComputedField(getter, ByteValueCodec, name ?: nextFieldName())
|
|
|
|
fun byte(getter: KProperty0<Byte>) = ComputedField(getter, ByteValueCodec)
|
|
|
|
@JvmOverloads fun bool(getter: KProperty0<Boolean>, name: String? = nextFieldName()) = ComputedField(getter, BooleanValueCodec, name ?: nextFieldName())
|
|
|
|
fun bool(getter: KProperty0<Boolean>) = ComputedField(getter, BooleanValueCodec)
|
|
|
|
@JvmOverloads fun short(getter: KProperty0<Short>, name: String? = nextFieldName()) = ComputedField(getter, ShortValueCodec, name ?: nextFieldName())
|
|
|
|
fun short(getter: KProperty0<Short>) = ComputedField(getter, ShortValueCodec)
|
|
|
|
@JvmOverloads fun long(getter: KProperty0<Long>, name: String? = nextFieldName()) = ComputedField(getter, VarLongValueCodec, name ?: nextFieldName())
|
|
|
|
fun long(getter: KProperty0<Long>) = ComputedField(getter, VarLongValueCodec)
|
|
|
|
@JvmOverloads fun fixedLong(getter: KProperty0<Long>, name: String? = nextFieldName()) = ComputedField(getter, LongValueCodec, name ?: nextFieldName())
|
|
|
|
fun fixedLong(getter: KProperty0<Long>) = ComputedField(getter, LongValueCodec)
|
|
|
|
@JvmOverloads fun float(getter: KProperty0<Float>, name: String? = nextFieldName()) = ComputedField(getter, FloatValueCodec, name ?: nextFieldName())
|
|
|
|
fun float(getter: KProperty0<Float>) = ComputedField(getter, FloatValueCodec)
|
|
|
|
@JvmOverloads fun double(getter: KProperty0<Double>, name: String? = nextFieldName()) = ComputedField(getter, DoubleValueCodec, name ?: nextFieldName())
|
|
|
|
fun double(getter: KProperty0<Double>) = ComputedField(getter, DoubleValueCodec)
|
|
|
|
@JvmOverloads fun uuid(getter: KProperty0<UUID>, name: String? = nextFieldName()) = ComputedField(getter, UUIDValueCodec, name ?: nextFieldName())
|
|
|
|
fun uuid(getter: KProperty0<UUID>) = ComputedField(getter, UUIDValueCodec)
|
|
|
|
@JvmOverloads fun int(getter: KProperty0<Int>, name: String? = nextFieldName()) = ComputedField(getter, VarIntValueCodec, name ?: nextFieldName())
|
|
|
|
fun int(getter: KProperty0<Int>) = ComputedField(getter, VarIntValueCodec)
|
|
|
|
@JvmOverloads fun fixedInt(getter: KProperty0<Int>, name: String? = nextFieldName()) = ComputedField(getter, IntValueCodec, name ?: nextFieldName())
|
|
|
|
fun fixedInt(getter: KProperty0<Int>) = ComputedField(getter, IntValueCodec)
|
|
|
|
@JvmOverloads fun fraction(getter: KProperty0<Decimal>, name: String? = nextFieldName()) = ComputedField(getter, ImpreciseFractionValueCodec, name ?: nextFieldName())
|
|
|
|
fun fraction(getter: KProperty0<Decimal>) = ComputedField(getter, ImpreciseFractionValueCodec)
|
|
|
|
@JvmOverloads fun bigDecimal(getter: KProperty0<BigDecimal>, name: String? = nextFieldName()) = ComputedField(getter, BigDecimalValueCodec, name ?: nextFieldName())
|
|
|
|
fun bigDecimal(getter: KProperty0<BigDecimal>) = ComputedField(getter, BigDecimalValueCodec)
|
|
|
|
@JvmOverloads fun item(getter: KProperty0<ItemStack>, name: String? = nextFieldName()) = ComputedField(getter, ItemStackValueCodec, name ?: nextFieldName())
|
|
|
|
fun item(getter: KProperty0<ItemStack>) = ComputedField(getter, ItemStackValueCodec)
|
|
|
|
@JvmOverloads fun string(getter: KProperty0<String>, name: String? = nextFieldName()) = ComputedField(getter, BinaryStringCodec, name ?: nextFieldName())
|
|
|
|
fun string(getter: KProperty0<String>) = ComputedField(getter, BinaryStringCodec)
|
|
|
|
|
|
|
|
|
|
|
|
@JvmOverloads fun byte(getter: Supplier<Byte>, name: String? = nextFieldName()) = ComputedField(getter::get, ByteValueCodec, name ?: nextFieldName())
|
|
|
|
fun byte(getter: Supplier<Byte>) = ComputedField(getter::get, ByteValueCodec)
|
|
|
|
@JvmOverloads fun bool(getter: Supplier<Boolean>, name: String? = nextFieldName()) = ComputedField(getter::get, BooleanValueCodec, name ?: nextFieldName())
|
|
|
|
fun bool(getter: Supplier<Boolean>) = ComputedField(getter::get, BooleanValueCodec)
|
|
|
|
@JvmOverloads fun short(getter: Supplier<Short>, name: String? = nextFieldName()) = ComputedField(getter::get, ShortValueCodec, name ?: nextFieldName())
|
|
|
|
fun short(getter: Supplier<Short>) = ComputedField(getter::get, ShortValueCodec)
|
|
|
|
@JvmOverloads fun long(getter: Supplier<Long>, name: String? = nextFieldName()) = ComputedField(getter::get, VarLongValueCodec, name ?: nextFieldName())
|
|
|
|
fun long(getter: Supplier<Long>) = ComputedField(getter::get, VarLongValueCodec)
|
|
|
|
@JvmOverloads fun fixedLong(getter: Supplier<Long>, name: String? = nextFieldName()) = ComputedField(getter::get, LongValueCodec, name ?: nextFieldName())
|
|
|
|
fun fixedLong(getter: Supplier<Long>) = ComputedField(getter::get, LongValueCodec)
|
|
|
|
@JvmOverloads fun float(getter: Supplier<Float>, name: String? = nextFieldName()) = ComputedField(getter::get, FloatValueCodec, name ?: nextFieldName())
|
|
|
|
fun float(getter: Supplier<Float>) = ComputedField(getter::get, FloatValueCodec)
|
|
|
|
@JvmOverloads fun double(getter: Supplier<Double>, name: String? = nextFieldName()) = ComputedField(getter::get, DoubleValueCodec, name ?: nextFieldName())
|
|
|
|
fun double(getter: Supplier<Double>) = ComputedField(getter::get, DoubleValueCodec)
|
|
|
|
@JvmOverloads fun uuid(getter: Supplier<UUID>, name: String? = nextFieldName()) = ComputedField(getter::get, UUIDValueCodec, name ?: nextFieldName())
|
|
|
|
fun uuid(getter: Supplier<UUID>) = ComputedField(getter::get, UUIDValueCodec)
|
|
|
|
@JvmOverloads fun int(getter: Supplier<Int>, name: String? = nextFieldName()) = ComputedField(getter::get, VarIntValueCodec, name ?: nextFieldName())
|
|
|
|
fun int(getter: Supplier<Int>) = ComputedField(getter::get, VarIntValueCodec)
|
|
|
|
@JvmOverloads fun fixedInt(getter: Supplier<Int>, name: String? = nextFieldName()) = ComputedField(getter::get, IntValueCodec, name ?: nextFieldName())
|
|
|
|
fun fixedInt(getter: Supplier<Int>) = ComputedField(getter::get, IntValueCodec)
|
|
|
|
@JvmOverloads fun fraction(getter: Supplier<Decimal>, name: String? = nextFieldName()) = ComputedField(getter::get, ImpreciseFractionValueCodec, name ?: nextFieldName())
|
|
|
|
fun fraction(getter: Supplier<Decimal>) = ComputedField(getter::get, ImpreciseFractionValueCodec)
|
|
|
|
@JvmOverloads fun bigDecimal(getter: Supplier<BigDecimal>, name: String? = nextFieldName()) = ComputedField(getter::get, BigDecimalValueCodec, name ?: nextFieldName())
|
|
|
|
fun bigDecimal(getter: Supplier<BigDecimal>) = ComputedField(getter::get, BigDecimalValueCodec)
|
|
|
|
@JvmOverloads fun item(getter: Supplier<ItemStack>, name: String? = nextFieldName()) = ComputedField(getter::get, ItemStackValueCodec, name ?: nextFieldName())
|
|
|
|
fun item(getter: Supplier<ItemStack>) = ComputedField(getter::get, ItemStackValueCodec)
|
|
|
|
@JvmOverloads fun string(getter: Supplier<String>, name: String? = nextFieldName()) = ComputedField(getter::get, BinaryStringCodec, name ?: nextFieldName())
|
|
|
|
fun string(getter: Supplier<String>) = ComputedField(getter::get, BinaryStringCodec)
|
|
|
|
|
|
|
|
|
|
|
|
@JvmOverloads fun <T : Enum<T>> enum(type: Class<T>, getter: () -> T, name: String? = nextFieldName()) = ComputedField(getter, EnumValueCodec.of(type), name ?: nextFieldName())
|
|
|
|
fun <T : Enum<T>> enum(type: Class<T>, getter: () -> T) = ComputedField(getter, EnumValueCodec.of(type))
|
|
|
|
inline fun <reified T : Enum<T>> enum(noinline getter: () -> T, name: String? = nextFieldName()) = ComputedField(getter, EnumValueCodec.of(T::class.java), name ?: nextFieldName())
|
|
|
|
inline fun <reified T : Enum<T>> enum(noinline getter: () -> T) = ComputedField(getter, EnumValueCodec.of(T::class.java))
|
|
|
|
|
|
|
|
|
|
|
|
@JvmOverloads fun <T : Enum<T>> enum(type: Class<T>, getter: KProperty0<T>, name: String? = nextFieldName()) = ComputedField(getter, EnumValueCodec.of(type), name ?: nextFieldName())
|
|
|
|
fun <T : Enum<T>> enum(type: Class<T>, getter: KProperty0<T>) = ComputedField(getter, EnumValueCodec.of(type))
|
|
|
|
inline fun <reified T : Enum<T>> enum(getter: KProperty0<T>, name: String? = nextFieldName()) = ComputedField(getter, EnumValueCodec.of(T::class.java), name ?: nextFieldName())
|
|
|
|
inline fun <reified T : Enum<T>> enum(getter: KProperty0<T>) = ComputedField(getter, EnumValueCodec.of(T::class.java))
|
|
|
|
|
|
|
|
|
|
|
|
@JvmOverloads fun <T : Enum<T>> enum(type: Class<T>, getter: Supplier<T>, name: String? = nextFieldName()) = ComputedField(getter::get, EnumValueCodec.of(type), name ?: nextFieldName())
|
|
|
|
fun <T : Enum<T>> enum(type: Class<T>, getter: Supplier<T>) = ComputedField(getter::get, EnumValueCodec.of(type))
|
|
|
|
inline fun <reified T : Enum<T>> enum(getter: Supplier<T>, name: String? = nextFieldName()) = ComputedField(getter::get, EnumValueCodec.of(T::class.java), name ?: nextFieldName())
|
|
|
|
inline fun <reified T : Enum<T>> enum(getter: Supplier<T>) = ComputedField(getter::get, EnumValueCodec.of(T::class.java))
|
|
|
|
|
|
|
|
|
|
|
|
@JvmOverloads
|
|
|
|
@JvmOverloads
|
|
|
|
fun byte(
|
|
|
|
fun byte(
|
|
|
|
value: Byte = 0,
|
|
|
|
value: Byte = 0,
|
|
|
|
getter: FieldGetter<Byte>? = null,
|
|
|
|
getter: FieldGetter<Byte>? = null,
|
|
|
|
setter: FieldSetter<Byte>? = null,
|
|
|
|
setter: FieldSetter<Byte>? = null,
|
|
|
|
name: String? = nextFieldName(),
|
|
|
|
|
|
|
|
): Field<Byte> {
|
|
|
|
): Field<Byte> {
|
|
|
|
return Field(value, ByteValueCodec, getter, setter, name = name ?: nextFieldName())
|
|
|
|
return Field(value, ByteValueCodec, getter, setter)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@JvmOverloads
|
|
|
|
@JvmOverloads
|
|
|
@ -226,9 +207,9 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
|
|
|
value: Boolean = false,
|
|
|
|
value: Boolean = false,
|
|
|
|
getter: FieldGetter<Boolean>? = null,
|
|
|
|
getter: FieldGetter<Boolean>? = null,
|
|
|
|
setter: FieldSetter<Boolean>? = null,
|
|
|
|
setter: FieldSetter<Boolean>? = null,
|
|
|
|
name: String? = nextFieldName(),
|
|
|
|
|
|
|
|
): Field<Boolean> {
|
|
|
|
): Field<Boolean> {
|
|
|
|
return Field(value, BooleanValueCodec, getter, setter, name = name ?: nextFieldName())
|
|
|
|
return Field(value, BooleanValueCodec, getter, setter)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@JvmOverloads
|
|
|
|
@JvmOverloads
|
|
|
@ -236,9 +217,9 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
|
|
|
value: Short = 0,
|
|
|
|
value: Short = 0,
|
|
|
|
getter: FieldGetter<Short>? = null,
|
|
|
|
getter: FieldGetter<Short>? = null,
|
|
|
|
setter: FieldSetter<Short>? = null,
|
|
|
|
setter: FieldSetter<Short>? = null,
|
|
|
|
name: String? = nextFieldName(),
|
|
|
|
|
|
|
|
): Field<Short> {
|
|
|
|
): Field<Short> {
|
|
|
|
return Field(value, ShortValueCodec, getter, setter, name = name ?: nextFieldName())
|
|
|
|
return Field(value, ShortValueCodec, getter, setter)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@JvmOverloads
|
|
|
|
@JvmOverloads
|
|
|
@ -246,9 +227,9 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
|
|
|
value: Long = 0L,
|
|
|
|
value: Long = 0L,
|
|
|
|
getter: FieldGetter<Long>? = null,
|
|
|
|
getter: FieldGetter<Long>? = null,
|
|
|
|
setter: FieldSetter<Long>? = null,
|
|
|
|
setter: FieldSetter<Long>? = null,
|
|
|
|
name: String? = nextFieldName(),
|
|
|
|
|
|
|
|
): Field<Long> {
|
|
|
|
): Field<Long> {
|
|
|
|
return Field(value, VarLongValueCodec, getter, setter, name = name ?: nextFieldName())
|
|
|
|
return Field(value, VarLongValueCodec, getter, setter)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@JvmOverloads
|
|
|
|
@JvmOverloads
|
|
|
@ -256,9 +237,9 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
|
|
|
value: Long = 0L,
|
|
|
|
value: Long = 0L,
|
|
|
|
getter: FieldGetter<Long>? = null,
|
|
|
|
getter: FieldGetter<Long>? = null,
|
|
|
|
setter: FieldSetter<Long>? = null,
|
|
|
|
setter: FieldSetter<Long>? = null,
|
|
|
|
name: String? = nextFieldName(),
|
|
|
|
|
|
|
|
): Field<Long> {
|
|
|
|
): Field<Long> {
|
|
|
|
return Field(value, LongValueCodec, getter, setter, name = name ?: nextFieldName())
|
|
|
|
return Field(value, LongValueCodec, getter, setter)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@JvmOverloads
|
|
|
|
@JvmOverloads
|
|
|
@ -266,9 +247,9 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
|
|
|
value: Float = 0f,
|
|
|
|
value: Float = 0f,
|
|
|
|
getter: FieldGetter<Float>? = null,
|
|
|
|
getter: FieldGetter<Float>? = null,
|
|
|
|
setter: FieldSetter<Float>? = null,
|
|
|
|
setter: FieldSetter<Float>? = null,
|
|
|
|
name: String? = nextFieldName(),
|
|
|
|
|
|
|
|
): Field<Float> {
|
|
|
|
): Field<Float> {
|
|
|
|
return Field(value, FloatValueCodec, getter, setter, name = name ?: nextFieldName())
|
|
|
|
return Field(value, FloatValueCodec, getter, setter)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@JvmOverloads
|
|
|
|
@JvmOverloads
|
|
|
@ -276,9 +257,9 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
|
|
|
value: Double = 0.0,
|
|
|
|
value: Double = 0.0,
|
|
|
|
getter: FieldGetter<Double>? = null,
|
|
|
|
getter: FieldGetter<Double>? = null,
|
|
|
|
setter: FieldSetter<Double>? = null,
|
|
|
|
setter: FieldSetter<Double>? = null,
|
|
|
|
name: String? = nextFieldName(),
|
|
|
|
|
|
|
|
): Field<Double> {
|
|
|
|
): Field<Double> {
|
|
|
|
return Field(value, DoubleValueCodec, getter, setter, name = name ?: nextFieldName())
|
|
|
|
return Field(value, DoubleValueCodec, getter, setter)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@JvmOverloads
|
|
|
|
@JvmOverloads
|
|
|
@ -286,9 +267,9 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
|
|
|
value: UUID = UUID(0L, 0L),
|
|
|
|
value: UUID = UUID(0L, 0L),
|
|
|
|
getter: FieldGetter<UUID>? = null,
|
|
|
|
getter: FieldGetter<UUID>? = null,
|
|
|
|
setter: FieldSetter<UUID>? = null,
|
|
|
|
setter: FieldSetter<UUID>? = null,
|
|
|
|
name: String? = nextFieldName(),
|
|
|
|
|
|
|
|
): Field<UUID> {
|
|
|
|
): Field<UUID> {
|
|
|
|
return Field(value, UUIDValueCodec, getter, setter, name = name ?: nextFieldName())
|
|
|
|
return Field(value, UUIDValueCodec, getter, setter)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@JvmOverloads
|
|
|
|
@JvmOverloads
|
|
|
@ -296,9 +277,9 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
|
|
|
value: Int = 0,
|
|
|
|
value: Int = 0,
|
|
|
|
getter: FieldGetter<Int>? = null,
|
|
|
|
getter: FieldGetter<Int>? = null,
|
|
|
|
setter: FieldSetter<Int>? = null,
|
|
|
|
setter: FieldSetter<Int>? = null,
|
|
|
|
name: String? = nextFieldName(),
|
|
|
|
|
|
|
|
): Field<Int> {
|
|
|
|
): Field<Int> {
|
|
|
|
return Field(value, VarIntValueCodec, getter, setter, name = name ?: nextFieldName())
|
|
|
|
return Field(value, VarIntValueCodec, getter, setter)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@JvmOverloads
|
|
|
|
@JvmOverloads
|
|
|
@ -306,9 +287,9 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
|
|
|
value: String = "",
|
|
|
|
value: String = "",
|
|
|
|
getter: FieldGetter<String>? = null,
|
|
|
|
getter: FieldGetter<String>? = null,
|
|
|
|
setter: FieldSetter<String>? = null,
|
|
|
|
setter: FieldSetter<String>? = null,
|
|
|
|
name: String? = nextFieldName(),
|
|
|
|
|
|
|
|
): Field<String> {
|
|
|
|
): Field<String> {
|
|
|
|
return Field(value, BinaryStringCodec, getter, setter, name = name ?: nextFieldName())
|
|
|
|
return Field(value, BinaryStringCodec, getter, setter)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@JvmOverloads
|
|
|
|
@JvmOverloads
|
|
|
@ -316,9 +297,9 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
|
|
|
value: Int = 0,
|
|
|
|
value: Int = 0,
|
|
|
|
getter: FieldGetter<Int>? = null,
|
|
|
|
getter: FieldGetter<Int>? = null,
|
|
|
|
setter: FieldSetter<Int>? = null,
|
|
|
|
setter: FieldSetter<Int>? = null,
|
|
|
|
name: String? = nextFieldName(),
|
|
|
|
|
|
|
|
): Field<Int> {
|
|
|
|
): Field<Int> {
|
|
|
|
return Field(value, IntValueCodec, getter, setter, name = name ?: nextFieldName())
|
|
|
|
return Field(value, IntValueCodec, getter, setter)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@JvmOverloads
|
|
|
|
@JvmOverloads
|
|
|
@ -326,9 +307,9 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
|
|
|
value: Decimal = Decimal.ZERO,
|
|
|
|
value: Decimal = Decimal.ZERO,
|
|
|
|
getter: FieldGetter<Decimal>? = null,
|
|
|
|
getter: FieldGetter<Decimal>? = null,
|
|
|
|
setter: FieldSetter<Decimal>? = null,
|
|
|
|
setter: FieldSetter<Decimal>? = null,
|
|
|
|
name: String? = nextFieldName(),
|
|
|
|
|
|
|
|
): Field<Decimal> {
|
|
|
|
): Field<Decimal> {
|
|
|
|
return Field(value, ImpreciseFractionValueCodec, getter, setter, name = name ?: nextFieldName())
|
|
|
|
return Field(value, ImpreciseFractionValueCodec, getter, setter)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@JvmOverloads
|
|
|
|
@JvmOverloads
|
|
|
@ -336,9 +317,9 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
|
|
|
value: BigDecimal = BigDecimal.ZERO,
|
|
|
|
value: BigDecimal = BigDecimal.ZERO,
|
|
|
|
getter: FieldGetter<BigDecimal>? = null,
|
|
|
|
getter: FieldGetter<BigDecimal>? = null,
|
|
|
|
setter: FieldSetter<BigDecimal>? = null,
|
|
|
|
setter: FieldSetter<BigDecimal>? = null,
|
|
|
|
name: String? = nextFieldName(),
|
|
|
|
|
|
|
|
): Field<BigDecimal> {
|
|
|
|
): Field<BigDecimal> {
|
|
|
|
return Field(value, BigDecimalValueCodec, getter, setter, name = name ?: nextFieldName())
|
|
|
|
return Field(value, BigDecimalValueCodec, getter, setter)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@JvmOverloads
|
|
|
|
@JvmOverloads
|
|
|
@ -347,9 +328,9 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
|
|
|
value: T = type.enumConstants[0],
|
|
|
|
value: T = type.enumConstants[0],
|
|
|
|
getter: FieldGetter<T>? = null,
|
|
|
|
getter: FieldGetter<T>? = null,
|
|
|
|
setter: FieldSetter<T>? = null,
|
|
|
|
setter: FieldSetter<T>? = null,
|
|
|
|
name: String? = nextFieldName(),
|
|
|
|
|
|
|
|
): Field<T> {
|
|
|
|
): Field<T> {
|
|
|
|
return Field(value, EnumValueCodec.of(type), getter, setter, name = name ?: nextFieldName())
|
|
|
|
return Field(value, EnumValueCodec.of(type), getter, setter)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@JvmOverloads
|
|
|
|
@JvmOverloads
|
|
|
@ -357,9 +338,9 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
|
|
|
value: T,
|
|
|
|
value: T,
|
|
|
|
getter: FieldGetter<T>? = null,
|
|
|
|
getter: FieldGetter<T>? = null,
|
|
|
|
setter: FieldSetter<T>? = null,
|
|
|
|
setter: FieldSetter<T>? = null,
|
|
|
|
name: String? = nextFieldName(),
|
|
|
|
|
|
|
|
): Field<T> {
|
|
|
|
): Field<T> {
|
|
|
|
return Field(value, EnumValueCodec.of(value::class.java), getter, setter, name = name ?: nextFieldName())
|
|
|
|
return Field(value, EnumValueCodec.of(value::class.java), getter, setter)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@JvmOverloads
|
|
|
|
@JvmOverloads
|
|
|
@ -368,17 +349,14 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
|
|
|
getter: FieldGetter<ItemStack>? = null,
|
|
|
|
getter: FieldGetter<ItemStack>? = null,
|
|
|
|
setter: FieldSetter<ItemStack>? = null,
|
|
|
|
setter: FieldSetter<ItemStack>? = null,
|
|
|
|
observe: Boolean = true,
|
|
|
|
observe: Boolean = true,
|
|
|
|
name: String? = nextFieldName(),
|
|
|
|
|
|
|
|
): Field<ItemStack> {
|
|
|
|
): Field<ItemStack> {
|
|
|
|
return Field(value, ItemStackValueCodec, getter, setter, isObserver = observe, name = name ?: nextFieldName())
|
|
|
|
return Field(value, ItemStackValueCodec, getter, setter, isObserver = observe)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@JvmOverloads
|
|
|
|
|
|
|
|
fun item(
|
|
|
|
fun item(
|
|
|
|
delegate: KMutableProperty0<ItemStack>,
|
|
|
|
delegate: KMutableProperty0<ItemStack>,
|
|
|
|
name: String? = nextFieldName(),
|
|
|
|
|
|
|
|
): ObservedField<ItemStack> {
|
|
|
|
): ObservedField<ItemStack> {
|
|
|
|
return ObservedField(delegate, ItemStackValueCodec, name = name ?: nextFieldName())
|
|
|
|
return ObservedField(delegate, ItemStackValueCodec)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@JvmOverloads
|
|
|
|
@JvmOverloads
|
|
|
@ -388,7 +366,6 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
|
|
|
callback: ((changes: Collection<MapChangeset<K, V>>) -> Unit)? = null,
|
|
|
|
callback: ((changes: Collection<MapChangeset<K, V>>) -> Unit)? = null,
|
|
|
|
backingMap: MutableMap<K, V> = HashMap(),
|
|
|
|
backingMap: MutableMap<K, V> = HashMap(),
|
|
|
|
observingBackingMap: MutableMap<K, V>? = null,
|
|
|
|
observingBackingMap: MutableMap<K, V>? = null,
|
|
|
|
name: String? = nextFieldName(),
|
|
|
|
|
|
|
|
): Map<K, V> {
|
|
|
|
): Map<K, V> {
|
|
|
|
return Map(
|
|
|
|
return Map(
|
|
|
|
keyCodec = keyCodec,
|
|
|
|
keyCodec = keyCodec,
|
|
|
@ -396,7 +373,6 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
|
|
|
callback = callback,
|
|
|
|
callback = callback,
|
|
|
|
backingMap = backingMap,
|
|
|
|
backingMap = backingMap,
|
|
|
|
observingBackingMap = observingBackingMap,
|
|
|
|
observingBackingMap = observingBackingMap,
|
|
|
|
name = name ?: nextFieldName(),
|
|
|
|
|
|
|
|
)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -516,36 +492,11 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
val stream = FastByteArrayOutputStream()
|
|
|
|
val stream = FastByteArrayOutputStream()
|
|
|
|
|
|
|
|
val dataStream = DataOutputStream(stream)
|
|
|
|
if (mappingVersion != this@FieldSynchronizer.mappingVersion) {
|
|
|
|
|
|
|
|
stream.write(1)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (field in fields) {
|
|
|
|
|
|
|
|
check(field.id > 0) { "This should never happen: $field maps to invalid ID: ${field.id}!" }
|
|
|
|
|
|
|
|
stream.writeVarIntLE(field.id)
|
|
|
|
|
|
|
|
val bytes = field.name.toByteArray(Charsets.UTF_8)
|
|
|
|
|
|
|
|
stream.writeVarIntLE(bytes.size)
|
|
|
|
|
|
|
|
stream.write(bytes)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
stream.writeVarIntLE(0)
|
|
|
|
|
|
|
|
mappingVersion = this@FieldSynchronizer.mappingVersion
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
stream.write(0)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (field in dirtyFields) {
|
|
|
|
for (field in dirtyFields) {
|
|
|
|
val id = field.id
|
|
|
|
stream.writeVarIntLE(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)
|
|
|
|
field.write(dataStream, this)
|
|
|
|
|
|
|
|
|
|
|
|
stream.writeVarIntLE(innerStream.length)
|
|
|
|
|
|
|
|
stream.write(innerStream.array, 0, innerStream.length)
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
dirtyFields.clear()
|
|
|
|
dirtyFields.clear()
|
|
|
@ -570,15 +521,11 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Suppress("LeakingThis")
|
|
|
|
@Suppress("LeakingThis")
|
|
|
|
abstract inner class AbstractField<V>(
|
|
|
|
abstract inner class AbstractField<V> : IField<V> {
|
|
|
|
final override val name: String = nextFieldName(),
|
|
|
|
val id: Int = fields.size + 1
|
|
|
|
) : IField<V> {
|
|
|
|
|
|
|
|
var id: Int = fields.size + 1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
init {
|
|
|
|
init {
|
|
|
|
check(!fields.any { it.name == name }) { "Duplicate field name $name" }
|
|
|
|
|
|
|
|
fields.add(this)
|
|
|
|
fields.add(this)
|
|
|
|
mappingVersion++
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -591,8 +538,7 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
|
|
|
private val getter: FieldGetter<V>? = null,
|
|
|
|
private val getter: FieldGetter<V>? = null,
|
|
|
|
private val setter: FieldSetter<V>? = null,
|
|
|
|
private val setter: FieldSetter<V>? = null,
|
|
|
|
isObserver: Boolean = false,
|
|
|
|
isObserver: Boolean = false,
|
|
|
|
name: String = nextFieldName(),
|
|
|
|
) : AbstractField<V>(), IMutableField<V> {
|
|
|
|
) : AbstractField<V>(name), IMutableField<V> {
|
|
|
|
|
|
|
|
private var remote: V = codec.copy(field)
|
|
|
|
private var remote: V = codec.copy(field)
|
|
|
|
|
|
|
|
|
|
|
|
init {
|
|
|
|
init {
|
|
|
@ -691,9 +637,8 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
|
|
|
inner class ComputedField<V>(
|
|
|
|
inner class ComputedField<V>(
|
|
|
|
private val getter: () -> V,
|
|
|
|
private val getter: () -> V,
|
|
|
|
private val codec: IStreamCodec<V>,
|
|
|
|
private val codec: IStreamCodec<V>,
|
|
|
|
name: String = nextFieldName(),
|
|
|
|
|
|
|
|
private val observer: (new: V) -> Unit = {}
|
|
|
|
private val observer: (new: V) -> Unit = {}
|
|
|
|
) : AbstractField<V>(name), IField<V> {
|
|
|
|
) : AbstractField<V>(), IField<V> {
|
|
|
|
private var remote: V? = null
|
|
|
|
private var remote: V? = null
|
|
|
|
private var clientValue: V? = null
|
|
|
|
private var clientValue: V? = null
|
|
|
|
private var isDirty = false
|
|
|
|
private var isDirty = false
|
|
|
@ -750,14 +695,14 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
|
|
|
get() = getter.invoke()
|
|
|
|
get() = getter.invoke()
|
|
|
|
set(value) { setter.invoke(value) }
|
|
|
|
set(value) { setter.invoke(value) }
|
|
|
|
|
|
|
|
|
|
|
|
constructor(field: KMutableProperty0<V>, codec: IStreamCodec<V>, name: String = nextFieldName()) : super(name) {
|
|
|
|
constructor(field: KMutableProperty0<V>, codec: IStreamCodec<V>) : super() {
|
|
|
|
this.codec = codec
|
|
|
|
this.codec = codec
|
|
|
|
getter = field::get
|
|
|
|
getter = field::get
|
|
|
|
setter = field::set
|
|
|
|
setter = field::set
|
|
|
|
remote = codec.copy(value)
|
|
|
|
remote = codec.copy(value)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
constructor(getter: () -> V, setter: (V) -> Unit, codec: IStreamCodec<V>, name: String = nextFieldName()) : super(name) {
|
|
|
|
constructor(getter: () -> V, setter: (V) -> Unit, codec: IStreamCodec<V>) : super() {
|
|
|
|
this.codec = codec
|
|
|
|
this.codec = codec
|
|
|
|
this.getter = getter
|
|
|
|
this.getter = getter
|
|
|
|
this.setter = setter
|
|
|
|
this.setter = setter
|
|
|
@ -806,8 +751,7 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
|
|
|
private val backingMap: MutableMap<K, V>,
|
|
|
|
private val backingMap: MutableMap<K, V>,
|
|
|
|
private val observingBackingMap: MutableMap<K, V>? = null,
|
|
|
|
private val observingBackingMap: MutableMap<K, V>? = null,
|
|
|
|
private val callback: ((changes: Collection<MapChangeset<K, V>>) -> Unit)? = null,
|
|
|
|
private val callback: ((changes: Collection<MapChangeset<K, V>>) -> Unit)? = null,
|
|
|
|
name: String = nextFieldName(),
|
|
|
|
) : AbstractField<MutableMap<K, V>>(), IField<MutableMap<K, V>> {
|
|
|
|
) : AbstractField<MutableMap<K, V>>(name), IField<MutableMap<K, V>> {
|
|
|
|
|
|
|
|
private var isDirty = false
|
|
|
|
private var isDirty = false
|
|
|
|
private var sentAllValues = false
|
|
|
|
private var sentAllValues = false
|
|
|
|
private var isRemote = false
|
|
|
|
private var isRemote = false
|
|
|
@ -1116,63 +1060,15 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
|
|
|
return values
|
|
|
|
return values
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private val idToField = Int2ObjectOpenHashMap<IField<*>>()
|
|
|
|
fun read(stream: InputStream): Int {
|
|
|
|
private val missingFields = ObjectArraySet<String>()
|
|
|
|
var fieldId = stream.readVarIntLE()
|
|
|
|
private val missingFieldsMap = Int2ObjectArrayMap<String>()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fun read(stream: InputStream, sizeLimit: NbtAccounter = NbtAccounter(1L shl 21 /* 2 MiB */)): Int {
|
|
|
|
|
|
|
|
if (stream.read() > 0) {
|
|
|
|
|
|
|
|
idToField.clear()
|
|
|
|
|
|
|
|
missingFieldsMap.clear()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var fieldId = stream.readVarIntLE(sizeLimit)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while (fieldId != 0) {
|
|
|
|
|
|
|
|
val size = stream.readVarIntLE(sizeLimit)
|
|
|
|
|
|
|
|
val nameBytes = ByteArray(size)
|
|
|
|
|
|
|
|
stream.read(nameBytes)
|
|
|
|
|
|
|
|
val name = String(nameBytes, Charsets.UTF_8)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
val findField = fields.firstOrNull { it.name == name }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (findField == null) {
|
|
|
|
|
|
|
|
if (missingFields.add(name)) {
|
|
|
|
|
|
|
|
LOGGER.error("Unable to find field $name in $this, expect issues!")
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
missingFieldsMap[fieldId] = name
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
idToField[fieldId] = findField
|
|
|
|
|
|
|
|
findField.id = fieldId
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fieldId = stream.readVarIntLE(sizeLimit)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (idToField.isEmpty()) {
|
|
|
|
|
|
|
|
throw IllegalStateException("Can't read anything, field ID mapping is empty!")
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var fieldId = stream.readVarIntLE(sizeLimit)
|
|
|
|
|
|
|
|
var i = 0
|
|
|
|
var i = 0
|
|
|
|
|
|
|
|
val dataStream = DataInputStream(stream)
|
|
|
|
|
|
|
|
|
|
|
|
while (fieldId != 0) {
|
|
|
|
while (fieldId != 0) {
|
|
|
|
val field = idToField[fieldId]
|
|
|
|
val field = fields.getOrNull(fieldId - 1) ?: throw IllegalArgumentException("Unknown field ID ${fieldId - 1}")
|
|
|
|
val payloadSize = stream.readVarIntLE(sizeLimit)
|
|
|
|
field.read(dataStream)
|
|
|
|
|
|
|
|
fieldId = stream.readVarIntLE()
|
|
|
|
if (field == null) {
|
|
|
|
|
|
|
|
LOGGER.error("Unable to read field $fieldId (${missingFieldsMap[fieldId]}) because we don't know anything about it! Skipping $payloadSize bytes", IllegalStateException("Unknown field $fieldId"))
|
|
|
|
|
|
|
|
sizeLimit.accountBytes(payloadSize.toLong())
|
|
|
|
|
|
|
|
stream.skipNBytes(payloadSize.toLong())
|
|
|
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sizeLimit.accountBytes(payloadSize.toLong())
|
|
|
|
|
|
|
|
val bytes = ByteArray(payloadSize)
|
|
|
|
|
|
|
|
stream.read(bytes)
|
|
|
|
|
|
|
|
field.read(DataInputStream(FastByteArrayInputStream(bytes)), payloadSize)
|
|
|
|
|
|
|
|
fieldId = stream.readVarIntLE(sizeLimit)
|
|
|
|
|
|
|
|
i++
|
|
|
|
i++
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -1183,6 +1079,5 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
|
|
|
private val ClearBacklogEntry = { stream: DataOutputStream -> stream.write(MapAction.CLEAR.ordinal + 1) }
|
|
|
|
private val ClearBacklogEntry = { stream: DataOutputStream -> stream.write(MapAction.CLEAR.ordinal + 1) }
|
|
|
|
private val MapActionList = MapAction.values()
|
|
|
|
private val MapActionList = MapAction.values()
|
|
|
|
private val ClearMapChangeset = MapChangeset(MapAction.CLEAR, null, null)
|
|
|
|
private val ClearMapChangeset = MapChangeset(MapAction.CLEAR, null, null)
|
|
|
|
private val LOGGER = LogManager.getLogger()
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|