forked from openrs2/openrs2
There are now three additional abstract PacketCodec classes: FixedPacketCodec, VariableBytePacketCodec and VariableShortPacketCodec. The PacketLength class has been removed, as it is no longer required. The main reason for this change is that the create suggested names packet is a bit of an oddball: its length field measures the size of the packet in longs, not bytes. The codec for this packet will be able to inherit from PacketCodec directly to implement the custom length logic. Signed-off-by: Graham <gpe@openrs2.org>
parent
431685124a
commit
1bb244b7f7
@ -0,0 +1,37 @@ |
|||||||
|
package org.openrs2.protocol |
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf |
||||||
|
import io.netty.buffer.ByteBufAllocator |
||||||
|
import io.netty.handler.codec.EncoderException |
||||||
|
|
||||||
|
public abstract class FixedPacketCodec<T : Packet>( |
||||||
|
type: Class<T>, |
||||||
|
opcode: Int, |
||||||
|
public val length: Int |
||||||
|
) : PacketCodec<T>(type, opcode) { |
||||||
|
override fun isLengthReadable(input: ByteBuf): Boolean { |
||||||
|
return true |
||||||
|
} |
||||||
|
|
||||||
|
override fun readLength(input: ByteBuf): Int { |
||||||
|
return length |
||||||
|
} |
||||||
|
|
||||||
|
override fun writeLengthPlaceholder(output: ByteBuf) { |
||||||
|
// empty |
||||||
|
} |
||||||
|
|
||||||
|
override fun setLength(output: ByteBuf, index: Int, written: Int) { |
||||||
|
if (written != length) { |
||||||
|
throw EncoderException("Fixed payload length mismatch (expected $length bytes, got $written bytes)") |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
override fun allocateBuffer(alloc: ByteBufAllocator, input: T, preferDirect: Boolean): ByteBuf { |
||||||
|
return if (preferDirect) { |
||||||
|
alloc.ioBuffer(1 + length, 1 + length) |
||||||
|
} else { |
||||||
|
alloc.heapBuffer(1 + length, 1 + length) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -1,6 +0,0 @@ |
|||||||
package org.openrs2.protocol |
|
||||||
|
|
||||||
public object PacketLength { |
|
||||||
public const val VARIABLE_SHORT: Int = -2 |
|
||||||
public const val VARIABLE_BYTE: Int = -1 |
|
||||||
} |
|
@ -0,0 +1,47 @@ |
|||||||
|
package org.openrs2.protocol |
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf |
||||||
|
import io.netty.buffer.ByteBufAllocator |
||||||
|
import io.netty.handler.codec.EncoderException |
||||||
|
|
||||||
|
public abstract class VariableBytePacketCodec<T : Packet>( |
||||||
|
type: Class<T>, |
||||||
|
opcode: Int |
||||||
|
) : PacketCodec<T>(type, opcode) { |
||||||
|
override fun isLengthReadable(input: ByteBuf): Boolean { |
||||||
|
return input.isReadable |
||||||
|
} |
||||||
|
|
||||||
|
override fun readLength(input: ByteBuf): Int { |
||||||
|
return input.readUnsignedByte().toInt() |
||||||
|
} |
||||||
|
|
||||||
|
override fun writeLengthPlaceholder(output: ByteBuf) { |
||||||
|
output.writeZero(1) |
||||||
|
} |
||||||
|
|
||||||
|
override fun setLength(output: ByteBuf, index: Int, written: Int) { |
||||||
|
if (written >= 256) { |
||||||
|
throw EncoderException("Variable byte payload too long: $written bytes") |
||||||
|
} |
||||||
|
|
||||||
|
output.setByte(index, written) |
||||||
|
} |
||||||
|
|
||||||
|
public open fun getLength(input: T): Int { |
||||||
|
return -1 |
||||||
|
} |
||||||
|
|
||||||
|
override fun allocateBuffer(alloc: ByteBufAllocator, input: T, preferDirect: Boolean): ByteBuf { |
||||||
|
val length = getLength(input) |
||||||
|
if (length < 0) { |
||||||
|
return super.allocateBuffer(alloc, input, preferDirect) |
||||||
|
} |
||||||
|
|
||||||
|
return if (preferDirect) { |
||||||
|
alloc.ioBuffer(2 + length, 2 + length) |
||||||
|
} else { |
||||||
|
alloc.heapBuffer(2 + length, 2 + length) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,47 @@ |
|||||||
|
package org.openrs2.protocol |
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf |
||||||
|
import io.netty.buffer.ByteBufAllocator |
||||||
|
import io.netty.handler.codec.EncoderException |
||||||
|
|
||||||
|
public abstract class VariableShortPacketCodec<T : Packet>( |
||||||
|
type: Class<T>, |
||||||
|
opcode: Int |
||||||
|
) : PacketCodec<T>(type, opcode) { |
||||||
|
override fun isLengthReadable(input: ByteBuf): Boolean { |
||||||
|
return input.readableBytes() >= 2 |
||||||
|
} |
||||||
|
|
||||||
|
override fun readLength(input: ByteBuf): Int { |
||||||
|
return input.readUnsignedShort() |
||||||
|
} |
||||||
|
|
||||||
|
override fun writeLengthPlaceholder(output: ByteBuf) { |
||||||
|
output.writeZero(2) |
||||||
|
} |
||||||
|
|
||||||
|
override fun setLength(output: ByteBuf, index: Int, written: Int) { |
||||||
|
if (written >= 65536) { |
||||||
|
throw EncoderException("Variable short payload too long: $written bytes") |
||||||
|
} |
||||||
|
|
||||||
|
output.setShort(index, written) |
||||||
|
} |
||||||
|
|
||||||
|
public open fun getLength(input: T): Int { |
||||||
|
return -2 |
||||||
|
} |
||||||
|
|
||||||
|
override fun allocateBuffer(alloc: ByteBufAllocator, input: T, preferDirect: Boolean): ByteBuf { |
||||||
|
val length = getLength(input) |
||||||
|
if (length < 0) { |
||||||
|
return super.allocateBuffer(alloc, input, preferDirect) |
||||||
|
} |
||||||
|
|
||||||
|
return if (preferDirect) { |
||||||
|
alloc.ioBuffer(3 + length, 3 + length) |
||||||
|
} else { |
||||||
|
alloc.heapBuffer(3 + length, 3 + length) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue