예제 #1
0
        /// <summary> Invokes RPC with parameters from the NetMessage. </summary>
        internal void Invoke(object instance, string methodName, NetMessage message, NetConnection sender) {

            RpcMethodInfo rpcInfo = RpcInfoCache.Get(methodName);
            MethodInfo method = rpcInfo.MethodInfoLookup[instance.GetType()];

            if (rpcInfo.TakesRequests && Socket.Request.Dispatch(message, sender, method, instance)) return;

            if (method.ReturnType == typeof (IEnumerator)) {
                var coroutine = (IEnumerator) method.Invoke(instance, message.Parameters);
                var behaviour = (MonoBehaviour) instance;
                if (coroutine != null) behaviour.StartCoroutine(coroutine);
            }
            else method.Invoke(instance, message.Parameters);
        }
예제 #2
0
        /// <summary> Processes a request to assign an RPC method name to a numeric ID. </summary>
        internal void ReceiveAssignmentRequest(NetMessage netMessage, NetConnection connection) {
            // If we aren't responsible for RPC ID assignment, ignore request.
            if (!Socket.ProtocolAuthority) return;

            var rpcName = (string) netMessage.Parameters[0];
            if (!HasId(rpcName)) {
                if (NameCount > 1800) return;
                AssignRemoteRpc(rpcName);
                // Send new assignment to all connections.
                foreach (NetConnection conn in Socket.Connections) {
                    if (conn == connection || conn.IsServer) continue;
                    Socket.Command.Send((int) Cmd.RemoteAssignment, conn, nameToId[rpcName], rpcName);
                }
            }
            Socket.Command.Send((int) Cmd.AssignmentResponse, connection, nameToId[rpcName], rpcName);
        }
예제 #3
0
        /// <summary> Adds the assigned id and remote method name to the RemoteRpcIds dictionary. </summary>
        internal void ReceiveRemoteAssignment(NetMessage netMessage, NetConnection connection) {

            if (!connection.IsServer && !connection.IsPeer) return;

            var rpcId = (ushort)netMessage.Parameters[0];
            var rpcName = (string) netMessage.Parameters[1];

            if (!HasId(rpcName) && !HasName(rpcId)) {
                nameToId.Add(rpcName, rpcId);
                idToName.Add(rpcId, rpcName);
                foreach (NetConnection conn in Socket.Connections) {
                    if (conn == connection || conn.IsServer) continue;
                    Socket.Command.Send((int)Cmd.RemoteAssignment, conn, nameToId[rpcName], rpcName);
                }
            }

            WaitingForRpcs--;
            //NetLog.Trace("Waiting for RPCs: " + WaitingForRpcs);
            if (WaitingForRpcs != 0) return;

            if (IdCount >= RpcInfoCache.Count) Socket.SendRequirementsMet(connection);
            else RequestAssignments(connection);
        }
예제 #4
0
 /// <summary> Sends a message to this connection. </summary>
 internal void Send(NetMessage message) {
     if (this == Socket.Self) NetLog.Warning("Trying to send message to self.");
     if (!message.Reliable) Unreliable.SerializeMessage(message);
     else Reliable.SerializeReliableMessage(message);
 }
예제 #5
0
        /// <summary> Processes a response to an RPC assignment request. The assigned id and method name are added to the LocalRpcs dictionary. </summary>
        internal void ReceiveAssignmentResponse(NetMessage netMessage, NetConnection connection) {

            if (!connection.IsServer && !connection.IsPeer) return;

            var id = (ushort) netMessage.Parameters[0];
            var methodName = (string) netMessage.Parameters[1];

            if (RpcInfoCache.Exists(methodName) && !idToName.ContainsKey(id)) {
                idToName.Add(id, methodName);
                if (!nameToId.ContainsKey(methodName)) nameToId.Add(methodName, id);
            }
            else NetLog.Error("Cannot assign local RPC. ID: " + id + " MethodName: " + methodName);

            if (idToName.Count == RpcInfoCache.Count) Socket.SendRequirementsMet(connection);
        }
예제 #6
0
        /// <summary> Processes a DestroyView command, this destroys the GameObject associated with the provided viewId. </summary>
        private void ReceiveDestroyView(NetMessage message, NetConnection connection) {
            int viewId = (int)message.Parameters[0];
            if (!ViewLookup.ContainsKey(viewId)) return;

            var view = ViewLookup[viewId];
            if (view.Server != connection) return;

            DestroyView(view);
        }
예제 #7
0
 internal void Dispatch(NetMessage message, NetConnection connection) {
     if (targets.ContainsKey(message.MessageId)) targets[message.MessageId](message, connection);
     else if (streamTargets.ContainsKey(message.MessageId))
         streamTargets[message.MessageId]((NetStream) message.Parameters[0], connection);
 }
예제 #8
0
 /// <summary> Sends an RPC to connections that are in-scope for the provided view. </summary>
 internal void Send(NetView view, NetMessage netMessage, RpcTarget target) {
     switch (target) {
         case (RpcTarget.All):
             for (int i = 0; i < Socket.Connections.Count; i++) {
                 var connection = Socket.Connections[i];
                 if (!connection.HasScope) continue;
                 if (view.Group != 0 && !connection.InGroup(view.Group)) continue;
                 if ((netMessage.Reliable && connection.Scope.In(view.Id)) || connection.Scope.In(view.Id, syncFrame) || view.IsController(connection)) connection.Send(netMessage);
             }
             break;
         case (RpcTarget.Controllers):
             foreach (NetConnection controller in view.Controllers) {
                 if (controller == Socket.Self) continue;
                 controller.Send(netMessage);
             }
             break;
         case (RpcTarget.NonControllers):
             for (int i = 0; i < Socket.Connections.Count; i++) {
                 var connection = Socket.Connections[i];
                 if (connection.IsServer || !connection.HasScope) continue;
                 if (view.IsController(connection)) continue;
                 if (view.Group != 0 && !connection.InGroup(view.Group)) continue;
                 if ((netMessage.Reliable && connection.Scope.In(view.Id)) || connection.Scope.In(view.Id, syncFrame)) connection.Send(netMessage);
             }
             break;
         case (RpcTarget.Server):
             if (view.Server != Socket.Self) view.Server.Send(netMessage);
             else NetLog.Warning("Trying to send message to self.");
             break;
         case (RpcTarget.AllInclOutOfScope):
             for (int i = 0; i < Socket.Connections.Count; i++) {
                 var connection = Socket.Connections[i];
                 if (view.Group != 0 && !connection.InGroup(view.Group)) continue;
                 connection.Send(netMessage);
             }
             break;
     }
 }
예제 #9
0
        private void ReceiveCreateView(NetMessage message, NetConnection server) {
            if (!server.IsServer && !server.IsPeer) return;

            int viewId = (int)message.Parameters[0];
            int group = (int)message.Parameters[1];
            string prefabRoot = (string)message.Parameters[2];
            var stream = (NetStream)message.Parameters[3];

            NetView.Relation relation = default(NetView.Relation);
            NetConnection controller = null;
            switch (message.MessageId) {
                case (int)ViewCmd.CreateOwnerView:
                    controller = Socket.Self;
                    relation = NetView.Relation.Owner;
                    break;
                case (int)ViewCmd.CreatePeerView:
                    relation = NetView.Relation.Peer;
                    break;
                case (int)ViewCmd.CreateCreatorView:
                    server = Socket.Self;
                    relation = NetView.Relation.Creator;
                    break;
                case (int)ViewCmd.CreateProxyView:
                    relation = NetView.Relation.Proxy;
                    break;
            }

            if (relation == NetView.Relation.Creator || relation == NetView.Relation.Peer) {
                var ipendpoint = (IPEndPoint)message.Parameters[4];
                if (ipendpoint != null) {
                    if (Socket.EndpointConnected(ipendpoint)) controller = Socket.EndpointToConnection(ipendpoint);
                    else NetLog.Error("Failed to create view, controller endpoint not connected: " + ipendpoint);
                }
            }

            var view = CreateView(controller, server, viewId, group, prefabRoot, relation);
            view.TriggerReadInstantiateData(stream);
            if (OnNetViewCreated != null) OnNetViewCreated(view);
        }
예제 #10
0
        /// <summary> Handles the OutOfScope command by triggering the OnOutOfScope delegate for the view. </summary>
        private void ReceiveOutOfScope(NetMessage message, NetConnection connection) {
            if (!connection.IsServer && !connection.IsPeer) return;

            int viewId = (int)message.Parameters[0];
            if (!ViewLookup.ContainsKey(viewId)) return;
            ViewLookup[viewId].Scope.FireOutEvent();
        }
예제 #11
0
        /// <summary> Handles the ChangeServer command by changing the View's Server to that of the sender. </summary>
        internal void ReceiveChangeServer(NetMessage message, NetConnection connection) {
            if (!connection.IsServer && !connection.IsPeer) return;

            int viewId = (int)message.Parameters[0];
            if (!ViewLookup.ContainsKey(viewId)) return;
            ViewLookup[viewId].Server = connection;
        }
예제 #12
0
        private void ReceiveMessage(NetMessage message, NetConnection connection) {
            if (!ViewLookup.ContainsKey((int)message.ViewId)) return;

            string methodName = Socket.Rpc.IdToName(message.MessageId);
            var view = ViewLookup[(int)message.ViewId];

            if (!view.IsController(connection) && connection != view.Server) {
                if (!connection.IsServer) {
                    NetLog.Warning("Connection attempting to send to unauthorized View: " + connection.Endpoint);
                    return;
                }
                view.Server = connection;
            }
            view.DispatchRpc(methodName, message, connection);
        }
예제 #13
0
 private void DeliverSyncStream(NetMessage message, NetConnection connection) {
     if (!ViewLookup.ContainsKey((int)message.ViewId)) return;
     var view = ViewLookup[(int)message.ViewId];
     if (!view.IsController(connection) && connection != view.Server) {
         if (!connection.IsServer) {
             NetLog.Warning("Connection attempting to send to unauthorized View: " + connection.Endpoint);
             return;
         }
         view.Server = connection;
     }
     view.TriggerReadSync((NetStream)message.Parameters[0]);
 }
예제 #14
0
        /// <summary> 
        /// Serializes a NetMessage to the reliable stream.
        /// If there is no current stream, one is prepared.
        /// If the current stream cannot fit the message, it is sent and a new stream is prepared.
        /// </summary>
        internal void SerializeReliableMessage(NetMessage message) {
            if (sendWindow.Count >= 512) return;

            if (sendStream == null) InitializeStream();

            if (!NetSerializer.TryWriteMessage(sendStream, message)) {
                if (retryingSerialization) {
                    NetLog.Warning("SerializeReliableMessage failed.");
                    retryingSerialization = false;
                    return;
                }

                retryingSerialization = true;
                FlushStream();
                SerializeReliableMessage(message);
            }

            if (retryingSerialization) retryingSerialization = false;
        }
예제 #15
0
 internal void MessageReceived(NetMessage message, NetConnection connection) {
     if (OnMessageReceived != null) OnMessageReceived(message, connection);
 }
예제 #16
0
        /// <summary> Sends an RPC to connections that are in-scope for the provided view. </summary>
        internal void Send(NetView view, NetMessage netMessage, RpcTarget target)
        {
            switch (target)
            {
            case (RpcTarget.All):
                for (int i = 0; i < Socket.Connections.Count; i++)
                {
                    var connection = Socket.Connections[i];
                    if (!connection.HasScope)
                    {
                        continue;
                    }
                    if (view.Group != 0 && !connection.InGroup(view.Group))
                    {
                        continue;
                    }
                    if ((netMessage.Reliable && connection.Scope.In(view.Id)) || connection.Scope.In(view.Id, syncFrame) || view.IsController(connection))
                    {
                        connection.Send(netMessage);
                    }
                }
                break;

            case (RpcTarget.Controllers):
                foreach (NetConnection controller in view.Controllers)
                {
                    if (controller == Socket.Self)
                    {
                        continue;
                    }
                    controller.Send(netMessage);
                }
                break;

            case (RpcTarget.NonControllers):
                for (int i = 0; i < Socket.Connections.Count; i++)
                {
                    var connection = Socket.Connections[i];
                    if (connection.IsServer || !connection.HasScope)
                    {
                        continue;
                    }
                    if (view.IsController(connection))
                    {
                        continue;
                    }
                    if (view.Group != 0 && !connection.InGroup(view.Group))
                    {
                        continue;
                    }
                    if ((netMessage.Reliable && connection.Scope.In(view.Id)) || connection.Scope.In(view.Id, syncFrame))
                    {
                        connection.Send(netMessage);
                    }
                }
                break;

            case (RpcTarget.Server):
                if (view.Server != Socket.Self)
                {
                    view.Server.Send(netMessage);
                }
                else
                {
                    NetLog.Warning("Trying to send message to self.");
                }
                break;

            case (RpcTarget.AllInclOutOfScope):
                for (int i = 0; i < Socket.Connections.Count; i++)
                {
                    var connection = Socket.Connections[i];
                    if (view.Group != 0 && !connection.InGroup(view.Group))
                    {
                        continue;
                    }
                    connection.Send(netMessage);
                }
                break;
            }
        }