From 9a7e9150f93696fd8c865a458f24a3ae500e5773 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Sun, 25 Sep 2022 23:16:33 +0700 Subject: [PATCH] Use variable length ints and longs --- .../ru/dbotthepony/mc/otm/core/DataStreams.kt | 34 +++++++++++++++++-- .../mc/otm/network/FieldSynchronizer.kt | 10 +----- 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/DataStreams.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/DataStreams.kt index 001b869b5..547c33d93 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/DataStreams.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/DataStreams.kt @@ -51,6 +51,7 @@ val ImpreciseFractionValueCodec = StreamCodec(DataInputStream::readImpreciseFrac val BigDecimalValueCodec = StreamCodec(DataInputStream::readBigDecimal, DataOutputStream::writeBigDecimal) val UUIDValueCodec = StreamCodec({ s -> UUID(s.readLong(), s.readLong()) }, { s, v -> s.writeLong(v.mostSignificantBits); s.writeLong(v.leastSignificantBits) }) val VarIntValueCodec = StreamCodec(DataInputStream::readVarIntLE, DataOutputStream::writeVarIntLE) +val VarLongValueCodec = StreamCodec(DataInputStream::readVarLongLE, DataOutputStream::writeVarLongLE) class EnumValueCodec>(private val clazz: Class) : IStreamCodec { private val values = clazz.enumConstants @@ -131,6 +132,7 @@ fun OutputStream.writeFloat(value: Float) = writeInt(value.toBits()) fun InputStream.readFloat() = Float.fromBits(readInt()) fun OutputStream.writeDouble(value: Double) = writeLong(value.toBits()) fun InputStream.readDouble() = Double.fromBits(readLong()) + fun InputStream.readVarIntLE(): Int { var result = 0 var read = read() @@ -159,6 +161,34 @@ fun OutputStream.writeVarIntLE(value: Int) { write(written) } +fun InputStream.readVarLongLE(): Long { + var result = 0L + var read = read() + var i = 0 + + while (read and 128 != 0) { + result = result or ((read and 127) shl i).toLong() + read = read() + i += 7 + } + + result = result or ((read and 127) shl i).toLong() + + return result +} + +fun OutputStream.writeVarLongLE(value: Long) { + require(value >= 0L) { "Negative number provided: $value" } + var written = value + + while (written >= 128) { + write(((written and 127) or 128).toInt()) + written = written ushr 7 + } + + write(written.toInt()) +} + private data class IndexedStreamCodec( val condition: Predicate, val id: Int, @@ -185,8 +215,8 @@ private val codecs: List> = com.google.common.collect.Immu it.add(IndexedStreamCodec(codecID++, BooleanValueCodec)) it.add(IndexedStreamCodec(codecID++, ByteValueCodec)) it.add(IndexedStreamCodec(codecID++, ShortValueCodec)) - it.add(IndexedStreamCodec(codecID++, IntValueCodec)) - it.add(IndexedStreamCodec(codecID++, LongValueCodec)) + it.add(IndexedStreamCodec(codecID++, VarIntValueCodec)) + it.add(IndexedStreamCodec(codecID++, VarLongValueCodec)) it.add(IndexedStreamCodec(codecID++, FloatValueCodec)) it.add(IndexedStreamCodec(codecID++, DoubleValueCodec)) it.add(IndexedStreamCodec(codecID++, ItemStackValueCodec)) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/network/FieldSynchronizer.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/network/FieldSynchronizer.kt index ab899224f..94f444ec8 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/network/FieldSynchronizer.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/network/FieldSynchronizer.kt @@ -98,7 +98,7 @@ class FieldSynchronizer { getter: FieldGetter? = null, setter: FieldSetter? = null, ): Field { - return Field(value, LongValueCodec, getter, setter) + return Field(value, VarLongValueCodec, getter, setter) } fun float( @@ -129,14 +129,6 @@ class FieldSynchronizer { value: Int = 0, getter: FieldGetter? = null, setter: FieldSetter? = null, - ): Field { - return Field(value, IntValueCodec, getter, setter) - } - - fun varInt( - value: Int = 0, - getter: FieldGetter? = null, - setter: FieldSetter? = null, ): Field { return Field(value, VarIntValueCodec, getter, setter) }