|
@@ -4,6 +4,7 @@ class NetworkClient {
|
|
|
|
|
|
var host : NetworkHost;
|
|
var host : NetworkHost;
|
|
var resultID : Int;
|
|
var resultID : Int;
|
|
|
|
+ public var seqID : Int;
|
|
public var ownerObject : NetworkSerializable;
|
|
public var ownerObject : NetworkSerializable;
|
|
|
|
|
|
public function new(h) {
|
|
public function new(h) {
|
|
@@ -29,7 +30,8 @@ class NetworkClient {
|
|
function processMessage( bytes : haxe.io.Bytes, pos : Int ) {
|
|
function processMessage( bytes : haxe.io.Bytes, pos : Int ) {
|
|
var ctx = host.ctx;
|
|
var ctx = host.ctx;
|
|
ctx.setInput(bytes, pos);
|
|
ctx.setInput(bytes, pos);
|
|
- switch( ctx.getByte() ) {
|
|
|
|
|
|
+ var mid = ctx.getByte();
|
|
|
|
+ switch( mid ) {
|
|
case NetworkHost.SYNC:
|
|
case NetworkHost.SYNC:
|
|
var o : hxd.net.NetworkSerializable = cast ctx.refs[ctx.getInt()];
|
|
var o : hxd.net.NetworkSerializable = cast ctx.refs[ctx.getInt()];
|
|
var old = o.__bits;
|
|
var old = o.__bits;
|
|
@@ -45,10 +47,14 @@ class NetworkClient {
|
|
case NetworkHost.UNREG:
|
|
case NetworkHost.UNREG:
|
|
var o : hxd.net.NetworkSerializable = cast ctx.refs[ctx.getInt()];
|
|
var o : hxd.net.NetworkSerializable = cast ctx.refs[ctx.getInt()];
|
|
o.enableReplication = false;
|
|
o.enableReplication = false;
|
|
- ctx.refs[o.__uid] = null;
|
|
|
|
|
|
+ ctx.refs.remove(o.__uid);
|
|
case NetworkHost.FULLSYNC:
|
|
case NetworkHost.FULLSYNC:
|
|
- ctx.refs = [];
|
|
|
|
- @:privateAccess ctx.newObjects = [];
|
|
|
|
|
|
+ ctx.refs = new Map();
|
|
|
|
+ @:privateAccess {
|
|
|
|
+ hxd.net.Serializer.UID = 0;
|
|
|
|
+ hxd.net.Serializer.SEQ = ctx.getByte();
|
|
|
|
+ ctx.newObjects = [];
|
|
|
|
+ };
|
|
while( true ) {
|
|
while( true ) {
|
|
var o = ctx.getAnyRef();
|
|
var o = ctx.getAnyRef();
|
|
if( o == null ) break;
|
|
if( o == null ) break;
|
|
@@ -78,6 +84,8 @@ class NetworkClient {
|
|
} else
|
|
} else
|
|
o.networkRPC(ctx, fid, this);
|
|
o.networkRPC(ctx, fid, this);
|
|
|
|
|
|
|
|
+ if( host.checkEOM ) ctx.addByte(NetworkHost.EOM);
|
|
|
|
+
|
|
host.doSend();
|
|
host.doSend();
|
|
host.targetClient = null;
|
|
host.targetClient = null;
|
|
resultID = old;
|
|
resultID = old;
|
|
@@ -129,6 +137,10 @@ class NetworkHost {
|
|
static inline var RPC_WITH_RESULT = 6;
|
|
static inline var RPC_WITH_RESULT = 6;
|
|
static inline var RPC_RESULT = 7;
|
|
static inline var RPC_RESULT = 7;
|
|
static inline var MSG = 8;
|
|
static inline var MSG = 8;
|
|
|
|
+ static inline var EOM = 0xFF;
|
|
|
|
+
|
|
|
|
+ public var checkEOM(get, never) : Bool;
|
|
|
|
+ inline function get_checkEOM() return true;
|
|
|
|
|
|
public static var current : NetworkHost = null;
|
|
public static var current : NetworkHost = null;
|
|
|
|
|
|
@@ -168,7 +180,7 @@ class NetworkHost {
|
|
}
|
|
}
|
|
|
|
|
|
public function loadSave<T:Serializable>( bytes : haxe.io.Bytes, c : Class<T> ) : T {
|
|
public function loadSave<T:Serializable>( bytes : haxe.io.Bytes, c : Class<T> ) : T {
|
|
- ctx.refs = [];
|
|
|
|
|
|
+ ctx.refs = new Map();
|
|
@:privateAccess ctx.newObjects = [];
|
|
@:privateAccess ctx.newObjects = [];
|
|
ctx.setInput(bytes, 0);
|
|
ctx.setInput(bytes, 0);
|
|
return ctx.getKnownRef(c);
|
|
return ctx.getKnownRef(c);
|
|
@@ -195,6 +207,7 @@ class NetworkHost {
|
|
targetClient = to;
|
|
targetClient = to;
|
|
ctx.addByte(MSG);
|
|
ctx.addByte(MSG);
|
|
ctx.addString(haxe.Serializer.run(msg));
|
|
ctx.addString(haxe.Serializer.run(msg));
|
|
|
|
+ if( checkEOM ) ctx.addByte(EOM);
|
|
doSend();
|
|
doSend();
|
|
targetClient = null;
|
|
targetClient = null;
|
|
}
|
|
}
|
|
@@ -203,6 +216,7 @@ class NetworkHost {
|
|
if( !isAuth )
|
|
if( !isAuth )
|
|
return true;
|
|
return true;
|
|
if( owner == null ) {
|
|
if( owner == null ) {
|
|
|
|
+ if( checkEOM ) ctx.addByte(EOM);
|
|
doSend();
|
|
doSend();
|
|
targetClient = null;
|
|
targetClient = null;
|
|
return true;
|
|
return true;
|
|
@@ -236,18 +250,40 @@ class NetworkHost {
|
|
return ctx;
|
|
return ctx;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ inline function endRPC() {
|
|
|
|
+ if( checkEOM ) ctx.addByte(EOM);
|
|
|
|
+ }
|
|
|
|
+
|
|
function fullSync( c : NetworkClient ) {
|
|
function fullSync( c : NetworkClient ) {
|
|
if( !pendingClients.remove(c) )
|
|
if( !pendingClients.remove(c) )
|
|
return;
|
|
return;
|
|
flush();
|
|
flush();
|
|
|
|
+
|
|
|
|
+ // unique client sequence number
|
|
|
|
+ var seq = clients.length + 1;
|
|
|
|
+ while( true ) {
|
|
|
|
+ var found = false;
|
|
|
|
+ for( c in clients )
|
|
|
|
+ if( c.seqID == seq ) {
|
|
|
|
+ found = true;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ if( !found ) break;
|
|
|
|
+ seq++;
|
|
|
|
+ }
|
|
|
|
+ ctx.addByte(seq);
|
|
|
|
+ c.seqID = seq;
|
|
|
|
+
|
|
clients.push(c);
|
|
clients.push(c);
|
|
var refs = ctx.refs;
|
|
var refs = ctx.refs;
|
|
ctx.begin();
|
|
ctx.begin();
|
|
- ctx.addByte(NetworkHost.FULLSYNC);
|
|
|
|
|
|
+ ctx.addByte(FULLSYNC);
|
|
|
|
+ ctx.addByte(c.seqID);
|
|
for( o in refs )
|
|
for( o in refs )
|
|
if( o != null )
|
|
if( o != null )
|
|
ctx.addAnyRef(o);
|
|
ctx.addAnyRef(o);
|
|
ctx.addAnyRef(null);
|
|
ctx.addAnyRef(null);
|
|
|
|
+ if( checkEOM ) ctx.addByte(EOM);
|
|
targetClient = c;
|
|
targetClient = c;
|
|
doSend();
|
|
doSend();
|
|
targetClient = null;
|
|
targetClient = null;
|
|
@@ -295,13 +331,26 @@ class NetworkHost {
|
|
o.__host = this;
|
|
o.__host = this;
|
|
if( ctx.refs[o.__uid] != null )
|
|
if( ctx.refs[o.__uid] != null )
|
|
return;
|
|
return;
|
|
|
|
+ if( !isAuth ) {
|
|
|
|
+ var owner = o.networkGetOwner();
|
|
|
|
+ if( owner == null || owner != self.ownerObject )
|
|
|
|
+ throw "Can't register "+o+" without ownership (" + owner + " should be " + self.ownerObject + ")";
|
|
|
|
+ }
|
|
if( logger != null )
|
|
if( logger != null )
|
|
- logger("Register " + o+"#"+o.__uid);
|
|
|
|
|
|
+ logger("Register " + o + "#" + o.__uid);
|
|
ctx.addByte(REG);
|
|
ctx.addByte(REG);
|
|
ctx.addAnyRef(o);
|
|
ctx.addAnyRef(o);
|
|
|
|
+ if( checkEOM ) ctx.addByte(EOM);
|
|
}
|
|
}
|
|
|
|
|
|
function unregister( o : NetworkSerializable ) {
|
|
function unregister( o : NetworkSerializable ) {
|
|
|
|
+ if( o.__host == null )
|
|
|
|
+ return;
|
|
|
|
+ if( !isAuth ) {
|
|
|
|
+ var owner = o.networkGetOwner();
|
|
|
|
+ if( owner == null || owner != self.ownerObject )
|
|
|
|
+ throw "Can't unregister "+o+" without ownership (" + owner + " should be " + self.ownerObject + ")";
|
|
|
|
+ }
|
|
flushProps(); // send changes
|
|
flushProps(); // send changes
|
|
o.__host = null;
|
|
o.__host = null;
|
|
o.__bits = 0;
|
|
o.__bits = 0;
|
|
@@ -309,7 +358,8 @@ class NetworkHost {
|
|
logger("Unregister " + o+"#"+o.__uid);
|
|
logger("Unregister " + o+"#"+o.__uid);
|
|
ctx.addByte(UNREG);
|
|
ctx.addByte(UNREG);
|
|
ctx.addInt(o.__uid);
|
|
ctx.addInt(o.__uid);
|
|
- ctx.refs[o.__uid] = null;
|
|
|
|
|
|
+ if( checkEOM ) ctx.addByte(EOM);
|
|
|
|
+ ctx.refs.remove(o.__uid);
|
|
}
|
|
}
|
|
|
|
|
|
function doSend() {
|
|
function doSend() {
|
|
@@ -343,6 +393,7 @@ class NetworkHost {
|
|
ctx.addByte(SYNC);
|
|
ctx.addByte(SYNC);
|
|
ctx.addInt(o.__uid);
|
|
ctx.addInt(o.__uid);
|
|
o.networkFlush(ctx);
|
|
o.networkFlush(ctx);
|
|
|
|
+ if( checkEOM ) ctx.addByte(EOM);
|
|
hasData = true;
|
|
hasData = true;
|
|
}
|
|
}
|
|
var n = o.__next;
|
|
var n = o.__next;
|