KStarbound/src/main/kotlin/ru/dbotthepony/kstarbound/network/API.kt

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)
}