Example #1
0
        /// <summary>
        /// Executed in edit mode when scripts are reloaded.
        /// </summary>
        public void InitializeRPCs()
        {
#if UNITY_EDITOR
            if (m_Methods == null)
            {
                m_Methods = new List <RPCMethodInfo>();
            }

            m_Methods.Clear();

            Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();

            foreach (Assembly assembly in assemblies)
            {
                Type[] types = assembly.GetTypes();

                foreach (Type type in types)
                {
                    if (!type.IsSubclassOf(typeof(NetworkBehaviour)) || !type.IsPublic || type.IsAbstract)
                    {
                        continue;
                    }

                    MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

                    foreach (MethodInfo method in methods)
                    {
                        IEnumerable <Attribute> attributes = method.GetCustomAttributes();

                        foreach (Attribute att in attributes)
                        {
                            if (att is NetworkRPCAttribute rpc)
                            {
                                RPCMethodInfo rpcMethod = new RPCMethodInfo(type.Name, method.Name, method.GetParameters()?.Length ?? 0);
                                m_Methods.Add(rpcMethod);
                                break;
                            }
                        }
                    }
                }
            }
#endif
        }
Example #2
0
        /// <summary>
        /// Execute a remote procedure.
        /// </summary>
        /// <param name="netInstanceID">The <see cref="NetworkIdentity.InstanceID"/>.</param>
        /// <param name="function">The name of the function.</param>
        /// <param name="parameters">The function parameters.</param>
        public void Call(NetworkIdentity identity, RPCType type, string function, params object[] parameters)
        {
            int connectionID = NetworkController.Instance.IsServer ? identity.OwnerConnection?.ConnectionID ?? -1 : NetworkController.Instance.ConnectionID;

            if (!NetworkController.Instance.IsServer)
            {
                if (type == RPCType.Target)
                {
                    throw new InvalidOperationException("You cannot send a targetted RPC because you are not the server.");
                }

                if (identity.OwnerConnection == null)
                {
                    throw new InvalidOperationException("The network identity has no owner and cannot execute any RPCs");
                }

                if (identity == null)
                {
                    throw new InvalidOperationException("The network identity specified does not exist on this client: " + identity.InstanceID);
                }

                if (identity.OwnerConnection.ConnectionID != NetworkController.Instance.LocalConnectionID)
                {
                    throw new InvalidOperationException("You are not the owner of this object and cannot execute RPCs on it.");
                }
            }

            int index = m_Methods?.FindIndex(x => x.m_MethodName == function) ?? -1;

            if (index == -1)
            {
                return;
            }

            RPCMethodInfo rpc = m_Methods[index];

            if (rpc.m_ArgumentCount != parameters.Length)
            {
                throw new InvalidOperationException("Given argument count for " + function + " does not match the argument count specified.");
            }

            NetworkWriter writer = GetRPCWriter(NetworkController.Instance.LocalConnectionID, identity.InstanceID, (byte)type, index, rpc.m_ArgumentCount, parameters);

            byte[] data = writer.ToArray();

            switch (type)
            {
            case RPCType.All:
            {
                if (NetworkController.Instance.IsServer)
                {
                    NetworkController.Instance.SendToAll(NetworkController.ReliableSequencedChannel, RPCMsg, data);
                }
                else
                {
                    NetworkController.Instance.Send(connectionID, NetworkController.ReliableSequencedChannel, RPCMsg, data);
                }
                break;
            }

            case RPCType.Others:
            {
                if (NetworkController.Instance.IsServer)
                {
                    NetworkController.Instance.SendToAll(NetworkController.ReliableSequencedChannel, RPCMsg, data);
                }
                else
                {
                    NetworkController.Instance.Send(connectionID, NetworkController.ReliableSequencedChannel, RPCMsg, data);
                }
                break;
            }

            case RPCType.ServerOnly:
            {
                if (NetworkController.Instance.IsServer)
                {
                    NetworkBehaviour networkBehaviour = identity.GetComponent <NetworkBehaviour>();
                    networkBehaviour.InvokeRPC(function, parameters);
                }
                else
                {
                    NetworkController.Instance.Send(connectionID, NetworkController.ReliableSequencedChannel, RPCMsg, data);
                }
                break;
            }

            case RPCType.AllBuffered:
            {
                if (NetworkController.Instance.IsServer)
                {
                    InitBuffer(identity.InstanceID);
                    m_BufferedMessages[identity.InstanceID].Add(new NetworkWriter(writer.ToArray()));
                    NetworkController.Instance.SendToAll(NetworkController.ReliableSequencedChannel, RPCMsg, data);
                }
                else
                {
                    NetworkController.Instance.Send(connectionID, NetworkController.ReliableSequencedChannel, RPCMsg, data);
                }
                break;
            }

            case RPCType.OthersBuffered:
            {
                if (NetworkController.Instance.IsServer)
                {
                    InitBuffer(identity.InstanceID);
                    m_BufferedMessages[identity.InstanceID].Add(new NetworkWriter(writer.ToArray()));
                    NetworkController.Instance.SendToAll(NetworkController.ReliableSequencedChannel, RPCMsg, data);
                }
                else
                {
                    NetworkController.Instance.Send(connectionID, NetworkController.ReliableSequencedChannel, RPCMsg, data);
                }
                break;
            }

            case RPCType.Target:
            {
                if (parameters.Length > 0)
                {
                    NetworkConnection connection = (NetworkConnection)parameters[0];
                    if (connection != null)
                    {
                        connection.Send(NetworkController.ReliableSequencedChannel, RPCMsg, data);
                    }
                }
                break;
            }
            }
        }
Example #3
0
        private void OnRPC(NetworkWriter writer)
        {
            ReadRPC(writer, out int connection, out int instanceID, out byte rpcType, out int rpcIndex, out int argumentCount, out object[] arguments);

            NetworkIdentity identity = NetworkIdentityManager.Instance.Get(instanceID);

            if (identity == null)
            {
                if (!NetworkController.Instance.IsServer)
                {
                    InitBuffer(instanceID);
                    m_BufferedMessages[instanceID].Add(new NetworkWriter(writer.ToArray()));
                }
                return;
            }

            if (rpcIndex == -1 || rpcIndex >= m_Methods.Count)
            {
                return;
            }

            if (NetworkController.Instance.IsServer)
            {
                RPCType type = (RPCType)rpcType;

                if (type != RPCType.ServerOnly)
                {
                    if (identity.OwnerConnection == null || identity.OwnerConnection.ConnectionID != connection)
                    {
                        return;
                    }

                    if (NetworkController.Instance.GetConnection(connection) == null)
                    {
                        return;
                    }
                }

                switch (type)
                {
                case RPCType.All:
                    NetworkController.Instance.SendToAll(NetworkController.ReliableSequencedChannel, RPCMsg, writer.ToArray());
                    return;

                case RPCType.AllBuffered:
                    NetworkController.Instance.SendToAll(NetworkController.ReliableSequencedChannel, RPCMsg, writer.ToArray());
                    InitBuffer(instanceID);
                    m_BufferedMessages[instanceID].Add(new NetworkWriter(writer.ToArray()));
                    return;

                case RPCType.Others:
                    NetworkController.Instance.SendToAllExcluding(writer.ToArray(), NetworkController.ReliableSequencedChannel, RPCMsg, connection);
                    return;

                case RPCType.OthersBuffered:
                    NetworkController.Instance.SendToAllExcluding(writer.ToArray(), NetworkController.ReliableSequencedChannel, RPCMsg, connection);
                    InitBuffer(instanceID);
                    m_BufferedMessages[instanceID].Add(new NetworkWriter(writer.ToArray()));
                    return;
                }
            }

            RPCMethodInfo method = m_Methods[rpcIndex];

            NetworkBehaviour behaviour = (NetworkBehaviour)identity.GetComponent(method.m_TypeName);

            behaviour.InvokeRPC(method.m_MethodName, arguments);
        }