93 lines
2.1 KiB
Kotlin
93 lines
2.1 KiB
Kotlin
package ru.dbotthepony.kstarbound.network
|
|
|
|
import io.netty.buffer.ByteBuf
|
|
import it.unimi.dsi.fastutil.bytes.ByteArrayList
|
|
import ru.dbotthepony.kstarbound.client.ClientConnection
|
|
import ru.dbotthepony.kstarbound.server.ServerConnection
|
|
import java.io.DataInputStream
|
|
import java.io.DataOutputStream
|
|
import kotlin.reflect.KClass
|
|
import kotlin.reflect.full.isSubclassOf
|
|
|
|
fun ByteBuf.writeUTF(value: String) {
|
|
writeBytes(value.toByteArray().also { check(!it.any { it.toInt() == 0 }) { "Provided UTF string contains NUL" } })
|
|
writeByte(0)
|
|
}
|
|
|
|
fun ByteBuf.readUTF(): String {
|
|
val bytes = ByteArrayList()
|
|
var read = readByte()
|
|
|
|
while (read.toInt() != 0) {
|
|
bytes.add(read)
|
|
read = readByte()
|
|
}
|
|
|
|
return String(bytes.toByteArray())
|
|
}
|
|
|
|
enum class ConnectionSide {
|
|
SERVER,
|
|
CLIENT;
|
|
|
|
val opposite: ConnectionSide
|
|
get() = if (this == SERVER) CLIENT else SERVER
|
|
}
|
|
|
|
enum class ConnectionState {
|
|
FRESH,
|
|
WORKING,
|
|
CLOSED;
|
|
}
|
|
|
|
enum class PacketDirection(val acceptOnClient: Boolean, val acceptOnServer: Boolean) {
|
|
FROM_SERVER(true, false),
|
|
FROM_CLIENT(false, true),
|
|
BI_DIRECTIONAL(true, true);
|
|
|
|
fun acceptedOn(side: ConnectionSide): Boolean {
|
|
if (side == ConnectionSide.SERVER)
|
|
return acceptOnServer
|
|
|
|
return acceptOnClient
|
|
}
|
|
|
|
companion object {
|
|
fun get(type: KClass<out IPacket>): PacketDirection {
|
|
return of(type.isSubclassOf(IClientPacket::class), type.isSubclassOf(IServerPacket::class))
|
|
}
|
|
|
|
fun of(allowedOnClient: Boolean, allowedOnServer: Boolean): PacketDirection {
|
|
if (allowedOnServer && allowedOnClient)
|
|
return BI_DIRECTIONAL
|
|
else if (allowedOnServer)
|
|
return FROM_CLIENT
|
|
else if (allowedOnClient)
|
|
return FROM_SERVER
|
|
else
|
|
throw IllegalArgumentException("Packet is not allowed on either side")
|
|
}
|
|
}
|
|
}
|
|
|
|
enum class ConnectionType {
|
|
NETWORK,
|
|
MEMORY;
|
|
}
|
|
|
|
fun interface IPacketReader<T : IPacket> {
|
|
fun read(stream: DataInputStream, isLegacy: Boolean): T
|
|
}
|
|
|
|
interface IPacket {
|
|
fun write(stream: DataOutputStream, isLegacy: Boolean)
|
|
}
|
|
|
|
interface IServerPacket : IPacket {
|
|
fun play(connection: ServerConnection)
|
|
}
|
|
|
|
interface IClientPacket : IPacket {
|
|
fun play(connection: ClientConnection)
|
|
}
|