ncannasse 9 rokov pred
rodič
commit
df6554ffae
3 zmenil súbory, kde vykonal 43 pridanie a 2 odobranie
  1. 2 1
      hxd/net/LocalHost.hx
  2. 23 1
      hxd/net/Macros.hx
  3. 18 0
      hxd/net/NetworkHost.hx

+ 2 - 1
hxd/net/LocalHost.hx

@@ -12,7 +12,7 @@ class LocalClient extends NetworkClient {
 	public function new(host, s) {
 		super(host);
 		this.socket = s;
-		s.onData = readData;
+		if( s != null ) s.onData = readData;
 	}
 
 	override function error(msg:String) {
@@ -100,6 +100,7 @@ class LocalHost extends NetworkHost {
 		close();
 		isAuth = false;
 		socket = new Socket();
+		self = new LocalClient(this, null);
 		socket.bind(host, port, function(s) {
 			var c = new LocalClient(this, s);
 			pendingClients.push(c);

+ 23 - 1
hxd/net/Macros.hx

@@ -22,6 +22,11 @@ enum RpcMode {
 		When called on the server: will execute locally.
 	*/
 	Server;
+	/*
+		When called on the client: will forward the call to the server if not the owner, or else execute locally.
+		When called on the server: will forward the call to the owner
+	*/
+	Owner;
 }
 
 enum PropTypeDesc {
@@ -718,8 +723,9 @@ class Macros {
 						case EConst(CIdent("all")):
 						case EConst(CIdent("client")): mode = Client;
 						case EConst(CIdent("server")): mode = Server;
+						case EConst(CIdent("owner")): mode = Owner;
 						default:
-							Context.error("Unexpected Rpc mode : should be all|client|server", meta.params[0].pos);
+							Context.error("Unexpected Rpc mode : should be all|client|server|owner", meta.params[0].pos);
 						}
 					rpc.push( { f : f, mode:mode } );
 					superRPC.set(f.name, true);
@@ -934,6 +940,22 @@ class Macros {
 						}
 						$doCall;
 					}
+				case Owner:
+					macro {
+						if( __host == null ) return;
+						var owner = networkGetOwner();
+						if( owner == null ) throw "Calling RPC(owner) function on a not owned object";
+						if( owner != __host.self.ownerObject ) @:privateAccess {
+							var old = __host.targetClient;
+							if( __host.setTargetOwner(owner) ) {
+								$forwardRPC;
+								__host.setTargetOwner(null);
+							}
+							__host.targetClient = old;
+							return;
+						}
+						$doCall;
+					}
 				};
 
 				var rpc : Field = {

+ 18 - 0
hxd/net/NetworkHost.hx

@@ -196,6 +196,24 @@ class NetworkHost {
 		targetClient = null;
 	}
 
+	function setTargetOwner( owner : NetworkSerializable ) {
+		if( !isAuth )
+			return true;
+		if( owner == null ) {
+			doSend();
+			targetClient = null;
+			return true;
+		}
+		flush();
+		targetClient = null;
+		for( c in clients )
+			if( c.ownerObject == owner ) {
+				targetClient = c;
+				break;
+			}
+		return targetClient != null; // owner not connected
+	}
+
 	function beginRPC(o:NetworkSerializable, id:Int, onResult:Serializer->Void) {
 		flushProps();
 		hasData = true;