예제 #1
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);
            }
        }
예제 #2
0
        internal bool Dispatch(NetMessage message, NetConnection connection, MethodInfo method, object instance)
        {
            List <Type> paramTypes = RpcInfoCache.ParamTypes(method.Name);

            if (paramTypes.Count >= message.Parameters.Length)
            {
                return(false);
            }

            if (method.ReturnType == typeof(IEnumerator) || method.ReturnType == typeof(void))
            {
                return(false);
            }

            ushort requestId = (ushort)message.Parameters[message.Parameters.Length - 1];

            object[] culledParams = new object[paramTypes.Count];

            for (int i = 0; i < paramTypes.Count; i++)
            {
                culledParams[i] = message.Parameters[i];
            }

            message.Parameters = culledParams;

            object result = method.Invoke(instance, message.Parameters);

            connection.Send(NetMessage.Create((ushort)Cmd.RequestResponse, message.ViewId,
                                              new object[] { requestId, true, result }, true));

            return(true);
        }
예제 #3
0
 /// <summary> Registers an instance of a MonoBehaviour to receive RPCs not associated with a NetView. </summary>
 public void RegisterRpcListener(MonoBehaviour listener)
 {
     foreach (KeyValuePair <string, RpcMethodInfo> cachedRpc in RpcInfoCache.RpcMethods())
     {
         if (!cachedRpc.Value.MethodInfoLookup.ContainsKey(listener.GetType()))
         {
             continue;
         }
         rpcObjectInstances.Add(cachedRpc.Value.Name, listener);
     }
 }
예제 #4
0
        /// <summary> Awake is a Unity convention. Unity invokes this method first when instantiated. </summary>
        private void Awake()
        {
            Application.runInBackground = true;
            Application.targetFrameRate = TargetFrameRate;

            Request = new RequestDispatcher(this);
            Rpc     = new RpcDispatcher(this);

            RpcInfoCache.RpcMethods();

            RegisterCommandParams();
        }
예제 #5
0
        /// <summary> Called by the server to generate IDs for local RPCs. </summary>
        internal void AssignLocalRpcs()
        {
            int i = 0;

            foreach (KeyValuePair <string, RpcMethodInfo> kvp in RpcInfoCache.RpcMethods())
            {
                for (i++; i < 1800; i++)
                {
                    if (HasName((ushort)i))
                    {
                        continue;
                    }
                    idToName.Add((ushort)i, kvp.Value.Name);
                    nameToId.Add(kvp.Value.Name, (ushort)i);
                    break;
                }
            }
        }
예제 #6
0
        /// <summary> Post-instantiation configuration of NetView. </summary>
        private void RegisterNetView(NetView view)
        {
            if (view.CachedRpcObjects == null)
            {
                view.SetRpcCache(RpcInfoCache.CreateInstanceLookup(view.gameObject));
            }
            view.Scope.Trans = view.gameObject.transform;
            view.Socket      = Socket;
            view.ViewManager = this;

            if (!ViewLookup.ContainsKey(view.Id))
            {
                ViewLookup.Add(view.Id, view);
            }
            if (!Views.Contains(view))
            {
                Views.Add(view);
            }
        }
예제 #7
0
        /// <summary> Sends a request to the server for each local RPC method name that needs an ID assignment. </summary>
        internal void RequestAssignments(NetConnection connection)
        {
            foreach (string methodName in RpcInfoCache.RpcMethods().Keys)
            {
                if (HasId(methodName))
                {
                    if (!HasName(NameToId(methodName)))
                    {
                        idToName.Add(NameToId(methodName), methodName);
                    }
                    continue;
                }
                Socket.Command.Send((int)Cmd.AssignmentRequest, connection, methodName);
            }

            if (IdCount >= RpcInfoCache.Count)
            {
                Socket.SendRequirementsMet(connection);
            }
        }
예제 #8
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);
            }
        }
예제 #9
0
 internal List <Type> ParamTypes(ushort id)
 {
     return(RpcInfoCache.ParamTypes(IdToName(id)));
 }
예제 #10
0
 /// <summary> Returns true if the provided rpcID is associated with a method. </summary>
 internal bool Exists(ushort rpcId)
 {
     return(HasName(rpcId) && RpcInfoCache.Exists(IdToName(rpcId)));
 }
예제 #11
0
 /// <summary> Returns true if the RPC method has a return value or has a NetRequest parameter. </summary>
 internal bool TakesRequests(ushort rpcId)
 {
     return(HasName(rpcId) && RpcInfoCache.TakesRequests(IdToName(rpcId)));
 }