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); }
/// <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); } }
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); }
private void OnServerRpcMessage(INetworkPlayer player, ServerRpcMessage msg) { OnServerRpc(player, msg.netId, msg.componentIndex, msg.functionIndex, msg.payload, default); }