示例#1
0
        protected internal void SendServerRpcInternal(Type invokeClass, string cmdName, NetworkWriter writer, int channelId, bool requireAuthority = true)
        {
            ValidateServerRpc(invokeClass, cmdName, requireAuthority);

            // construct the message
            var message = new ServerRpcMessage
            {
                netId          = NetId,
                componentIndex = ComponentIndex,
                // type+func so Inventory.RpcUse != Equipment.RpcUse
                functionHash = RemoteCallHelper.GetMethodHash(invokeClass, cmdName),
                // segment to avoid reader allocations
                payload = writer.ToArraySegment()
            };

            Client.Send(message, channelId);
        }
示例#2
0
        /// <summary>
        /// Handle ServerRpc from specific player, this could be one of multiple players on a single client
        /// </summary>
        /// <param name="conn"></param>
        /// <param name="msg"></param>
        void OnServerRpcMessage(INetworkConnection conn, ServerRpcMessage msg)
        {
            if (!SpawnedObjects.TryGetValue(msg.netId, out NetworkIdentity identity) || identity is null)
            {
                if (logger.WarnEnabled())
                {
                    logger.LogWarning("Spawned object not found when handling ServerRpc message [netId=" + msg.netId + "]");
                }
                return;
            }
            Skeleton skeleton = RemoteCallHelper.GetSkeleton(msg.functionHash);

            if (skeleton.invokeType != MirageInvokeType.ServerRpc)
            {
                throw new MethodInvocationException($"Invalid ServerRpc for id {msg.functionHash}");
            }

            // ServerRpcs can be for player objects, OR other objects with client-authority
            // -> so if this connection's controller has a different netId then
            //    only allow the ServerRpc if clientAuthorityOwner
            if (skeleton.cmdRequireAuthority && identity.ConnectionToClient != conn)
            {
                if (logger.WarnEnabled())
                {
                    logger.LogWarning("ServerRpc for object without authority [netId=" + msg.netId + "]");
                }
                return;
            }

            if (logger.LogEnabled())
            {
                logger.Log("OnServerRpcMessage for netId=" + msg.netId + " conn=" + conn);
            }

            using (PooledNetworkReader networkReader = NetworkReaderPool.GetReader(msg.payload))
            {
                networkReader.ObjectLocator = this;
                identity.HandleRemoteCall(skeleton, msg.componentIndex, networkReader, conn, msg.replyId);
            }
        }
示例#3
0
        protected internal UniTask <T> SendServerRpcWithReturn <T>(Type invokeClass, string cmdName, NetworkWriter writer, int channelId, bool requireAuthority = true)
        {
            ValidateServerRpc(invokeClass, cmdName, requireAuthority);

            (UniTask <T> task, int id) = ClientObjectManager.CreateReplyTask <T>();

            // construct the message
            var message = new ServerRpcMessage
            {
                netId          = NetId,
                componentIndex = ComponentIndex,
                replyId        = id,
                // type+func so Inventory.RpcUse != Equipment.RpcUse
                functionHash = RemoteCallHelper.GetMethodHash(invokeClass, cmdName),
                // segment to avoid reader allocations
                payload = writer.ToArraySegment()
            };

            Client.Send(message, channelId);

            return(task);
        }
示例#4
0
 private void OnServerRpcMessage(INetworkPlayer player, ServerRpcMessage msg)
 {
     OnServerRpc(player, msg.netId, msg.componentIndex, msg.functionIndex, msg.payload, default);
 }