Did massive refactoring to sort everything

Started implementing reliable UDP system
TODO: Implement UDP hole-punching system
This commit is contained in:
Gabriel Tofvesson 2018-07-28 02:14:09 +02:00
parent 2af938169c
commit f45c59e796
22 changed files with 138 additions and 37 deletions

View File

@ -1,6 +1,9 @@
import net.tofvesson.math.MathSerializer;
import net.tofvesson.annotation.SyncedVar;
import net.tofvesson.data.DiffTracked;
import net.tofvesson.data.DiffTrackedArray;
import net.tofvesson.data.SyncHandler;
import net.tofvesson.serializers.MathSerializer;
import net.tofvesson.math.Vector3;
import net.tofvesson.networking.*;
public class Main {
@SyncedVar("NonNegative")
@ -33,7 +36,6 @@ public class Main {
public static void main(String[] args){
Main testObject = new Main();
SyncHandler.Companion.registerSerializer(MathSerializer.Companion.getSingleton());
SyncHandler sync = new SyncHandler();
sync.registerSyncObject(testObject);
sync.registerSyncObject(Main.class);

View File

@ -1,4 +1,4 @@
package net.tofvesson.networking
package net.tofvesson.annotation
/**
* Prevents SyncedVar system from syncing superclasses

View File

@ -1,4 +1,4 @@
package net.tofvesson.networking
package net.tofvesson.annotation
import net.tofvesson.reflect.*
@ -31,7 +31,7 @@ enum class SyncFlag {
fun createFlag(name: String): SyncFlag {
// Do duplication check
if(getByName(name)!=null) throw IllegalArgumentException("Flag \"$name\" is already registered!")
if(getByName(name) !=null) throw IllegalArgumentException("Flag \"$name\" is already registered!")
// Get unsafe
val unsafe = getUnsafe()

View File

@ -0,0 +1,10 @@
package net.tofvesson.data
fun ByteArray.readBits(index: Int, bitCount: Int, bitOffset: Int = 0): Int {
var result = 0
for(i in 0 until bitCount)
result = result or readBit(index, bitOffset+i)
return result
}
fun ByteArray.readBit(index: Int, bitOffset: Int = 0) = (this[index + (bitOffset ushr 3)].toInt() ushr (bitOffset and 7)) and 1

View File

@ -1,4 +1,4 @@
package net.tofvesson.networking
package net.tofvesson.data
import java.util.*

View File

@ -1,4 +1,4 @@
package net.tofvesson.networking
package net.tofvesson.data
class DiffTrackedArray<T>(val elementType: Class<T>, val size: Int, gen: (Int) -> T) {

View File

@ -1,4 +1,4 @@
package net.tofvesson.networking
package net.tofvesson.data
data class Holder(var value: Any?){
companion object {

View File

@ -1,6 +1,7 @@
package net.tofvesson.networking
package net.tofvesson.data
import net.tofvesson.math.collapseLowerByte
import net.tofvesson.exception.InsufficientCapacityException
import net.tofvesson.math.*
import java.nio.ByteBuffer
@Suppress("MemberVisibilityCanBePrivate", "unused")

View File

@ -1,5 +1,7 @@
package net.tofvesson.networking
package net.tofvesson.data
import net.tofvesson.annotation.SyncFlag
import net.tofvesson.exception.UnsupportedTypeException
import java.lang.reflect.Field
import java.util.*

View File

@ -1,6 +1,14 @@
package net.tofvesson.networking
package net.tofvesson.data
import net.tofvesson.annotation.NoUpwardCascade
import net.tofvesson.annotation.SyncFlag
import net.tofvesson.annotation.SyncedVar
import net.tofvesson.exception.UnsupportedTypeException
import net.tofvesson.reflect.access
import net.tofvesson.serializers.DiffTrackedSerializer
import net.tofvesson.serializers.MathSerializer
import net.tofvesson.serializers.PrimitiveArraySerializer
import net.tofvesson.serializers.PrimitiveSerializer
import java.lang.reflect.Field
import java.nio.ByteBuffer
import java.security.NoSuchAlgorithmException
@ -20,6 +28,7 @@ class SyncHandler(private val permissiveMismatchCheck: Boolean = false) {
serializers.add(PrimitiveSerializer.singleton)
serializers.add(PrimitiveArraySerializer.singleton)
serializers.add(DiffTrackedSerializer.singleton)
serializers.add(MathSerializer.singleton)
}
fun registerSerializer(serializer: Serializer) {
@ -121,7 +130,7 @@ class SyncHandler(private val permissiveMismatchCheck: Boolean = false) {
private fun computeObjectSize(value: Any, writeState: WriteState) = computeTypeSize(value.javaClass, value, writeState)
private fun computeClassSize(value: Class<*>, writeState: WriteState) = computeTypeSize(value, null, writeState)
private fun computeTypeSize(type: Class<*>, value: Any?, writeState: WriteState) {
for(field in collectSyncable(type, value==null))
for(field in collectSyncable(type, value == null))
getCompatibleSerializer(field.access().type)
.computeSize(field, SyncFlag.parse(field.getAnnotation(SyncedVar::class.java).value), value, writeState)
}
@ -129,7 +138,7 @@ class SyncHandler(private val permissiveMismatchCheck: Boolean = false) {
private fun readObject(value: Any, writeBuffer: WriteBuffer) = readType(value.javaClass, value, writeBuffer)
private fun readClass(value: Class<*>, writeBuffer: WriteBuffer) = readType(value, null, writeBuffer)
private fun readType(type: Class<*>, value: Any?, writeBuffer: WriteBuffer) {
for(field in collectSyncable(type, value==null))
for(field in collectSyncable(type, value == null))
getCompatibleSerializer(field.type)
.serialize(field, SyncFlag.parse(field.getAnnotation(SyncedVar::class.java).value), value, writeBuffer)
}
@ -137,7 +146,7 @@ class SyncHandler(private val permissiveMismatchCheck: Boolean = false) {
private fun writeObject(value: Any, readBuffer: ReadBuffer) = writeType(value.javaClass, value, readBuffer)
private fun writeClass(value: Class<*>, readBuffer: ReadBuffer) = writeType(value, null, readBuffer)
private fun writeType(type: Class<*>, value: Any?, readBuffer: ReadBuffer) {
for(field in collectSyncable(type, value==null))
for(field in collectSyncable(type, value == null))
getCompatibleSerializer(field.type)
.deserialize(field, SyncFlag.parse(field.getAnnotation(SyncedVar::class.java).value), value, readBuffer)
}

View File

@ -1,7 +1,7 @@
package net.tofvesson.networking
package net.tofvesson.data
import net.tofvesson.math.collapseLowerByte
import net.tofvesson.math.toNumber
import net.tofvesson.exception.InsufficientCapacityException
import net.tofvesson.math.*
import java.nio.ByteBuffer
import kotlin.experimental.and
import kotlin.experimental.or

View File

@ -1,4 +1,4 @@
package net.tofvesson.networking
package net.tofvesson.data
import net.tofvesson.math.collapseLowerByte
@ -10,9 +10,9 @@ data class WriteState(private var _bytes: Int, private var _bits: Int, private v
var header: Int = _header
private set
fun registerBytes(bytes: Int): WriteState { this.bytes += bytes; return this }
fun registerBits(bits: Int) : WriteState { this.bits += bits; return this }
fun registerHeader(header: Int): WriteState{ this.header += header; return this }
fun registerBytes(bytes: Int): WriteState { this.bytes += bytes; return this }
fun registerBits(bits: Int) : WriteState { this.bits += bits; return this }
fun registerHeader(header: Int): WriteState { this.header += header; return this }
fun computeRequiredBytes(additionalBytes: Int = 0, additionalBits: Int = 0) =
bytes + additionalBytes + computeBitFieldOffset(additionalBits)

View File

@ -1,4 +1,4 @@
package net.tofvesson.networking
package net.tofvesson.exception
class InsufficientCapacityException: RuntimeException {
constructor() : super()

View File

@ -1,4 +1,4 @@
package net.tofvesson.networking
package net.tofvesson.exception
class MismatchedFlagException: RuntimeException {
constructor() : super()

View File

@ -1,4 +1,4 @@
package net.tofvesson.networking
package net.tofvesson.exception
class UnsupportedTypeException: RuntimeException {
constructor() : super()

View File

@ -1,4 +1,4 @@
package net.tofvesson.networking
package net.tofvesson.math
import java.nio.ByteBuffer
import kotlin.experimental.or

View File

@ -1,6 +1,6 @@
package net.tofvesson.math
import net.tofvesson.networking.DiffTracked
import net.tofvesson.data.DiffTracked
class Vector3(xPos: Float, yPos: Float, zPos: Float) {

View File

@ -0,0 +1,64 @@
package net.tofvesson.networking
import net.tofvesson.reflect.access
import java.net.DatagramPacket
import java.net.DatagramSocket
import java.net.InetAddress
import java.util.concurrent.atomic.AtomicBoolean
class ReliableUDP(address: InetAddress, port: Short, private val onAccept: (ByteArray, Int, Int) -> Unit, private val automaticAccept: Boolean, acceptTimeout: Long = 10L) {
private enum class PacketType(val bits: Int = (javaClass.getDeclaredField("\$VALUES").access().get(null) as Array<*>).indexOf(this)) {
DATA, ACK, FIN;
companion object {
val fieldSize = (Math.log((javaClass.getDeclaredField("\$VALUES").access().get(null) as Array<*>).size.toDouble()) / Math.log(2.0)).toInt() + 1
}
}
private var socket = DatagramSocket()
private val sync: Thread? = if(automaticAccept) Thread { acceptLoop() } else null
private val stop = AtomicBoolean(false)
private var finInitiated = false
private val packet = DatagramPacket(ByteArray(socket.receiveBufferSize), socket.receiveBufferSize)
init {
socket.connect(address, port.toInt())
socket.soTimeout = 0
sync?.start()
}
private fun acceptLoop(){
while(synchronized(stop){!stop.get()}){
accept()
if(packet.length==0) continue // Drop empty packets
val packetType = PacketType.values()[packet.data[0].toInt()]
when(packetType){
PacketType.DATA -> {
}
PacketType.ACK -> {
}
PacketType.FIN -> {
}
}
}
}
fun accept(){
if(automaticAccept && Thread.currentThread() != sync)
throw IllegalThreadStateException("Current thread isn't setup to accept datagram packets")
socket.receive(packet)
}
fun send(){
if(finInitiated) throw IllegalStateException("Cannot send message after connection is closed!")
}
fun _send(){
}
}

View File

@ -1,5 +1,7 @@
package net.tofvesson.networking
package net.tofvesson.serializers
import net.tofvesson.annotation.SyncFlag
import net.tofvesson.data.*
import java.lang.reflect.Field
class DiffTrackedSerializer private constructor(): Serializer(arrayOf(

View File

@ -1,6 +1,9 @@
package net.tofvesson.math
package net.tofvesson.serializers
import net.tofvesson.networking.*
import net.tofvesson.annotation.SyncFlag
import net.tofvesson.data.*
import net.tofvesson.exception.MismatchedFlagException
import net.tofvesson.math.*
import net.tofvesson.reflect.access
import java.lang.reflect.Field
@ -102,13 +105,13 @@ class MathSerializer: Serializer(arrayOf(
if(nn || pc){
var track = 0
flags = Array(flags.size - resize){
if(flags[track]==SyncFlag.NonNegative && nn){
if(flags[++track]==SyncFlag.NoCompress && pc)
if(flags[track]== SyncFlag.NonNegative && nn){
if(flags[++track]== SyncFlag.NoCompress && pc)
flags[++track]
else flags[track]
}
else if(flags[track]==SyncFlag.NoCompress && nn){
if(flags[++track]==SyncFlag.NonNegative && pc)
else if(flags[track]== SyncFlag.NoCompress && nn){
if(flags[++track]== SyncFlag.NonNegative && pc)
flags[++track]
else flags[track]
}else flags[track]

View File

@ -1,5 +1,7 @@
package net.tofvesson.networking
package net.tofvesson.serializers
import net.tofvesson.annotation.SyncFlag
import net.tofvesson.data.*
import java.lang.reflect.Field
@Suppress("MemberVisibilityCanBePrivate")

View File

@ -1,5 +1,11 @@
package net.tofvesson.networking
package net.tofvesson.serializers
import net.tofvesson.annotation.SyncFlag
import net.tofvesson.data.ReadBuffer
import net.tofvesson.data.Serializer
import net.tofvesson.data.WriteBuffer
import net.tofvesson.data.WriteState
import net.tofvesson.math.*
import net.tofvesson.reflect.*
import java.lang.reflect.Field