Fixed boolean de-/serialization
Added a more robust mismatch check
This commit is contained in:
parent
87ec95544d
commit
2e32d9d984
@ -9,26 +9,43 @@ public class Main {
|
|||||||
public static long staticTest = 90;
|
public static long staticTest = 90;
|
||||||
|
|
||||||
@SyncedVar
|
@SyncedVar
|
||||||
public static float value = 1337f;
|
public static float value = 1f;
|
||||||
|
|
||||||
|
@SyncedVar
|
||||||
|
public boolean testbool = false;
|
||||||
|
|
||||||
|
@SyncedVar
|
||||||
|
public static boolean testbool1 = true;
|
||||||
|
|
||||||
public static void main(String[] args){
|
public static void main(String[] args){
|
||||||
Main testObject = new Main();
|
Main testObject = new Main();
|
||||||
SyncHandler sync = new SyncHandler();
|
SyncHandler sync = new SyncHandler();
|
||||||
sync.registerSyncObject(testObject);
|
sync.registerSyncObject(testObject);
|
||||||
//sync.registerSyncObject(Main.class);
|
sync.registerSyncObject(Main.class);
|
||||||
|
|
||||||
|
byte[] mismatchCheck = sync.generateMismatchCheck();
|
||||||
byte[] ser = sync.serialize();
|
byte[] ser = sync.serialize();
|
||||||
|
|
||||||
System.out.println("Created and serialized snapshot of field values:\n"+testObject.syncTest+"\n"+staticTest+"\n"+value+"\n");
|
System.out.println("Created and serialized snapshot of field values:\n"+testObject.syncTest+"\n"+staticTest+"\n"+value+"\n"+testObject.testbool+"\n"+testbool1+"\n");
|
||||||
|
|
||||||
testObject.syncTest = 20;
|
testObject.syncTest = 20;
|
||||||
staticTest = 32;
|
staticTest = 32;
|
||||||
value = 9.0f;
|
value = 9.0f;
|
||||||
|
testObject.testbool = true;
|
||||||
|
testbool1 = false;
|
||||||
|
|
||||||
System.out.println("Set a new state of test values:\n"+testObject.syncTest+"\n"+staticTest+"\n"+value+"\n");
|
System.out.println("Set a new state of test values:\n"+testObject.syncTest+"\n"+staticTest+"\n"+value+"\n"+testObject.testbool+"\n"+testbool1+"\n");
|
||||||
|
|
||||||
|
/* Swap the registry order
|
||||||
|
sync.unregisterSyncObject(testObject);
|
||||||
|
sync.unregisterSyncObject(Main.class);
|
||||||
|
sync.registerSyncObject(Main.class);
|
||||||
|
sync.registerSyncObject(testObject);
|
||||||
|
*/
|
||||||
|
if(!sync.doMismatchCheck(mismatchCheck)) throw new RuntimeException("Target sync mismatch");
|
||||||
sync.deserialize(ser);
|
sync.deserialize(ser);
|
||||||
|
|
||||||
System.out.println("Deserialized snapshot values:\n"+testObject.syncTest+"\n"+staticTest+"\n"+value+"\n");
|
System.out.println("Deserialized snapshot values:\n"+testObject.syncTest+"\n"+staticTest+"\n"+value+"\n"+testObject.testbool+"\n"+testbool1+"\n");
|
||||||
|
System.out.println("Snapshot size: "+ser.length+" bytes");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,15 @@ package net.tofvesson.networking
|
|||||||
|
|
||||||
import java.lang.reflect.Field
|
import java.lang.reflect.Field
|
||||||
import java.nio.ByteBuffer
|
import java.nio.ByteBuffer
|
||||||
import kotlin.experimental.and
|
import kotlin.experimental.or
|
||||||
|
import java.security.NoSuchAlgorithmException
|
||||||
|
import java.security.MessageDigest
|
||||||
|
|
||||||
class SyncHandler {
|
|
||||||
|
/**
|
||||||
|
* @param permissiveMismatchCheck This should essentially never be set to true aside from some *very* odd edge cases
|
||||||
|
*/
|
||||||
|
class SyncHandler(private val permissiveMismatchCheck: Boolean = false) {
|
||||||
private val toSync: ArrayList<Pair<Any, Int>> = ArrayList()
|
private val toSync: ArrayList<Pair<Any, Int>> = ArrayList()
|
||||||
|
|
||||||
fun registerSyncObject(value: Any){
|
fun registerSyncObject(value: Any){
|
||||||
@ -12,7 +18,9 @@ class SyncHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun unregisterSyncObject(value: Any){
|
fun unregisterSyncObject(value: Any){
|
||||||
toSync.remove(value)
|
for(i in toSync.indices.reversed())
|
||||||
|
if(toSync[i].first == value)
|
||||||
|
toSync.removeAt(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun serialize(): ByteArray{
|
fun serialize(): ByteArray{
|
||||||
@ -40,7 +48,6 @@ class SyncHandler {
|
|||||||
val headerSize = (headerBits shr 3) + (if((headerBits and 7) != 0) 1 else 0)
|
val headerSize = (headerBits shr 3) + (if((headerBits and 7) != 0) 1 else 0)
|
||||||
var headerIndex = 0
|
var headerIndex = 0
|
||||||
var dataIndex = headerSize
|
var dataIndex = headerSize
|
||||||
var totalSize = headerSize
|
|
||||||
for((entry, _) in toSync){
|
for((entry, _) in toSync){
|
||||||
val result =
|
val result =
|
||||||
if(entry is Class<*>) writeClass(entry, syncData, dataIndex, headerIndex)
|
if(entry is Class<*>) writeClass(entry, syncData, dataIndex, headerIndex)
|
||||||
@ -51,11 +58,24 @@ class SyncHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun generateMismatchCheck(): ByteArray {
|
fun generateMismatchCheck(): ByteArray {
|
||||||
val bitCount = computeBitHeaderCount()
|
val builder = StringBuilder()
|
||||||
val outBuffer = ByteArray(varIntSize(bitCount.toLong()) + varIntSize(toSync.size.toLong()))
|
for((entry, _) in toSync)
|
||||||
writeVarInt(outBuffer, 0, bitCount.toLong())
|
for(field in (entry as? Class<*> ?: entry::class.java).declaredFields){
|
||||||
writeVarInt(outBuffer, varIntSize(bitCount.toLong()), toSync.size.toLong())
|
if((entry is Class<*> && field.modifiers and 8 == 0) || (entry !is Class<*> && field.modifiers and 8 != 0)) continue
|
||||||
return outBuffer
|
val annotation = field.getAnnotation(SyncedVar::class.java)
|
||||||
|
if(annotation!=null)
|
||||||
|
builder
|
||||||
|
.append(if(permissiveMismatchCheck) field.type.name else field.toGenericString())
|
||||||
|
.append(if(annotation.floatEndianSwap) 1 else 0)
|
||||||
|
.append(if(annotation.noCompress) 1 else 0)
|
||||||
|
.append(if(annotation.nonNegative) 1 else 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return try {
|
||||||
|
MessageDigest.getInstance("SHA-1").digest(builder.toString().toByteArray())
|
||||||
|
} catch (e: NoSuchAlgorithmException) {
|
||||||
|
builder.toString().toByteArray()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun doMismatchCheck(check: ByteArray): Boolean {
|
fun doMismatchCheck(check: ByteArray): Boolean {
|
||||||
@ -117,9 +137,9 @@ class SyncHandler {
|
|||||||
return count
|
return count
|
||||||
}
|
}
|
||||||
private fun writeBit(bit: Boolean, buffer: ByteArray, index: Int){
|
private fun writeBit(bit: Boolean, buffer: ByteArray, index: Int){
|
||||||
buffer[index shr 3] = buffer[index shr 3] and (1 shl (index and 7)).toByte()
|
buffer[index shr 3] = buffer[index shr 3].or(((if(bit) 1 else 0) shl (index and 7)).toByte())
|
||||||
}
|
}
|
||||||
private fun readBit(buffer: ByteArray, index: Int): Boolean = buffer[index shr 8].toInt() and (1 shl (index and 7)) != 0
|
private fun readBit(buffer: ByteArray, index: Int): Boolean = buffer[index shr 3].toInt() and (1 shl (index and 7)) != 0
|
||||||
|
|
||||||
private fun computeObjectSize(value: Any) = computeTypeSize(value.javaClass, value)
|
private fun computeObjectSize(value: Any) = computeTypeSize(value.javaClass, value)
|
||||||
private fun computeClassSize(value: Class<*>) = computeTypeSize(value, null)
|
private fun computeClassSize(value: Class<*>) = computeTypeSize(value, null)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user