Ejemplo n.º 1
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;
            }
            }
        }
Ejemplo n.º 2
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);
        }