public void Fire <T>(string name, T arg, RpcTarget rpcTarget)
        {
            Debug.Log($"Fire message {name}, photonView {_photonView.ViewID} with data {typeof(T).Name}: {arg.ToString()}");
            switch (arg)
            {
            case bool _:
            case short _:
            case int _:
            case long _:
            case float _:
            case double _:
            case string _:
            case object[] _:
            case Hashtable _:
            case Dictionary <Object, Object> _:
            case Vector2 _:
            case Vector3 _:
            case Quaternion _:
            case Player _:
            case int[] _:
                PhotonView.RPC(nameof(ReceivedMessage), rpcTarget, name, arg);
                return;

            default:
                Debug.LogError($"Fire {name}, photonView {_photonView.ViewID} arg: {arg} not supported");
                break;
            }
        }
        /// <summary>
        /// Rpc Function. You can call any function marked with FduRPC attribute,which is DEFINED in the classes derived from FduObserverBase or other monobehaviors belong to  the gameobject.
        /// Notice that you can only use it on MasterNode.
        /// </summary>
        /// <param name="view">the view instance which will execute the rpc</param>
        /// <param name="methodName">name of the rpc mehthod</param>
        /// <param name="target">rpc target</param>
        /// <param name="paras">rpc parameters</param>
        public object RPC(FduClusterView view, string methodName, RpcTarget target, params object[] paras)
        {
            if (!inited)
            {
                Debug.LogWarning("[FduRpc]Rpc Manager is not set up yet. Ignore this operation"); return(null);
            }
            if (view == null || methodName == null)
            {
                Debug.LogError("[FduRpc]Cluster view or method name can not be null!"); return(null);
            }
            ;

            if (ClusterHelper.Instance.Client != null)
            {
                return(null);
            }

            FduRPCEvent e = new FduRPCEvent();

            e.setUpViewId(view.ViewId, methodName);
            e.setUpParameters(paras);
            _rpcEventList.Add(e);

            if (target == RpcTarget.All)
            {
                return(executeRpc(e.getRpcData()));
            }
            else
            {
                return(null);
            }
        }
Exemple #3
0
 public RpcInvokeMessage(string methodName, ulong entityId, RpcTarget target, params object[] arguments)
 {
     this.methodName = methodName;
     this.entityId   = entityId;
     this.target     = target;
     this.arguments  = arguments;
 }
 public void ExecuteActions(Actions actions, Actions currentActions, RpcTarget targets)
 {
     this.executeActions = actions;
     this.currentActions = currentActions;
     this.targets        = targets;
     photonView.RPC(ARPC, targets);
     Debug.Log("ExecuteActions " + actions + " / " + targets);
 }
        void DoRPC()
        {
            // get the photon proxy for Photon RPC access
            GameObject go = GameObject.Find("PlayMaker Photon Proxy");

            if (go == null)
            {
                return;
            }


            if (remoteEvent != null && remoteEvent.IsGlobal == false)
            {
                return;
            }

            RpcTarget _photonTargets = getPhotonTargets();

            // get the proxy component
            PlayMakerPhotonProxy _proxy = go.GetComponent <PlayMakerPhotonProxy>();

            if (_proxy == null)
            {
                Debug.LogWarning("PlayMakerPhotonProxy is missing");
                return;
            }

            if (eventTarget.target == FsmEventTarget.EventTarget.BroadcastAll)
            {
                if (data.Length > 0)
                {
                    //_proxy.PhotonRpcFsmBroadcastEventWithData(_photonTargets,remoteEvent.Name,data);
                }
                else
                {
                    _proxy.PhotonRpcBroacastFsmEvent(rpcTarget, remoteEvent.Name);
                }
            }
            else
            {
                PlayMakerPhotonGameObjectProxy _goProxy = Owner.GetComponent <PlayMakerPhotonGameObjectProxy>();
                if (_proxy == null)
                {
                    Debug.LogWarning("PlayMakerPhotonProxy is missing");
                    return;
                }

                if (data.Length > 0)
                {
                    _goProxy.PhotonRpcSendFsmEventWithData(_photonTargets, remoteEvent.Name, data);
                }
                else
                {
                    _goProxy.PhotonRpcSendFsmEvent(rpcTarget, remoteEvent.Name);
                }
            }
        }
        void DoREC()
        {
            // get the photon proxy for Photon RPC access
            GameObject go = GameObject.Find("PlayMaker Photon Proxy");

            if (go == null)
            {
                return;
            }


            if (string.IsNullOrEmpty(remoteEvent.Value))
            {
                return;
            }

            RpcTarget _photonTargets = GetPhotonTargets();

            // get the proxy component
            PlayMakerPhotonProxy _proxy = go.GetComponent <PlayMakerPhotonProxy>();

            if (_proxy == null)
            {
                Debug.LogWarning("PlayMakerPhotonProxy is missing");
                return;
            }

            if (eventTarget.target == FsmEventTarget.EventTarget.BroadcastAll)
            {
                if (!stringData.IsNone && stringData.Value != "")
                {
                    _proxy.PhotonRpcBroacastFsmEventWithString(_photonTargets, remoteEvent.Value, stringData.Value);
                }
                else
                {
                    _proxy.PhotonRpcBroacastFsmEvent(rpcTarget, remoteEvent.Value);
                }
            }
            else
            {
                PlayMakerPhotonGameObjectProxy _goProxy = Owner.GetComponent <PlayMakerPhotonGameObjectProxy>();
                if (_proxy == null)
                {
                    Debug.LogWarning("PlayMakerPhotonProxy is missing");
                    return;
                }

                if (!stringData.IsNone && stringData.Value != "")
                {
                    _goProxy.PhotonRpcSendFsmEventWithString(_photonTargets, remoteEvent.Value, stringData.Value);
                }
                else
                {
                    _goProxy.PhotonRpcSendFsmEvent(rpcTarget, remoteEvent.Value);
                }
            }
        }
Exemple #7
0
        /// <summary>
        /// Function typically called from the action "PhotonViewRpcBroadcasFsmEvent" that use RPC to send information about the event to broadcast
        /// </summary>
        /// <param name='target'>
        /// Photon Target.
        /// </param>
        /// <param name='globalEventName'>
        /// Global Fsm event name to broadcast using the photon target rule.
        /// </param>
        public void PhotonRpcBroadcastFsmEvent(RpcTarget target, string globalEventName)
        {
            if (LogMessageInfo)
            {
                Debug.Log("RPC to send global Fsm Event:" + globalEventName + " to target:" + target, this);
            }

            this.photonView.RPC("rpc", target, globalEventName);// method name used to be too long : "RPC_PhotonRpcBroadcastFsmEvent"
        }
Exemple #8
0
        /// <summary>
        /// Function typically called from the action "PhotonViewRpcBroadcasFsmEvent" that use RPC to send information about the event to broadcast
        /// </summary>
        /// <param name='target'>
        /// Photon Target.
        /// </param>
        /// <param name='globalEventName'>
        /// Global Fsm event name to broadcast using the photon target rule.
        /// </param>
        /// <param name='stringData'>
        /// String data to pass with this event. WARNING: this is not supposed to be (nor efficient) a way to synchronize data. This is simply to comply with
        /// the ability for FsmEvent to include data.
        /// </param>
        public void PhotonRpcBroadcastFsmEventWithString(RpcTarget target, string globalEventName, string stringData)
        {
            if (LogMessageInfo)
            {
                Debug.Log("RPC to send string:" + stringData + "  with global Fsm Event:" + globalEventName + " to target:" + target);
            }

            photonView.RPC("rpc_s", target, globalEventName, stringData);// method name used to be too long :  "RPC_FsmPhotonRpcBroadcastFsmEventWithString"
        }
Exemple #9
0
        private void DoAttack()
        {
            float damage = myWeapon.attackDamage;

            if (c > 2)
            {
                damage *= 1.5f;
                c       = 0;
            }

            Ray        ray1 = new Ray(Hand.transform.position, transform.forward);
            RaycastHit hit;

            if (Physics.Raycast(ray1, out hit, myWeapon.attackRange))
            {
                if (hit.collider.CompareTag("Player"))
                {
                    RpcTarget    target      = hit.collider.GetComponent <RpcTarget>();
                    PhotonView   enemyView   = hit.transform.GetComponent <PhotonView>();
                    PlayerHealth enemyHealth = hit.transform.GetComponent <PlayerHealth>();

                    enemyView.RPC("Damage", target, damage);
                    enemyView.RPC("Knockback", target, (Hand.transform.forward * myWeapon.knockback));
                }

                if (hit.collider.CompareTag("Bonus"))
                {
                    PlayerHealth bonusHealth = hit.collider.GetComponent <PlayerHealth>();
                    string       type        = bonusHealth.type;

                    if (bonusHealth.health <= damage)
                    {
                        if (type == "vie")
                        {
                            pH.health += 30f;
                        }

                        if (type == "force")
                        {
                            initDmg *= 2;
                            Invoke("SetDamageNormal", 300);
                        }

                        if (type == "vitesse")
                        {
                            pM.speed *= 1.5f;
                            Invoke("SetSpeedNormal", 30);
                        }

                        Debug.Log("Bonus died !");
                    }

                    bonusHealth.health -= damage;
                }
            }
        }
Exemple #10
0
    public void SetAffectedController(int index, int id, bool capsuleHit, RpcTarget selectedTarget)
    {
        int wasCapsuleHit = 0;

        if (capsuleHit)
        {
            wasCapsuleHit = 1;
        }
        photonView.RPC("RPC_SetAffectedController", selectedTarget, index, id, wasCapsuleHit);
    }
Exemple #11
0
    public void DisableVisibility(int index, int id, bool local, RpcTarget selectedTarget)
    {
        int isLocal = 0;

        if (local)
        {
            isLocal = 1;
        }
        photonView.RPC("RPC_DisableVisibility", selectedTarget, index, id, isLocal);
    }
Exemple #12
0
    public void EnableDisableControllerOutline(int id, bool enableOutline, RpcTarget selectedTarget)
    {
        int enable = 0;

        if (enableOutline)
        {
            enable = 1;
        }
        photonView.RPC("RPC_EnableDisableControllerOutline", selectedTarget, id, enable);
    }
Exemple #13
0
 //not used yet
 public void SendRPCforAllCharacters(string rpc, RpcTarget target, string param)
 {
     // Send the RPC for every character in the room
     GameObject[] players = GameObject.FindGameObjectsWithTag("NetworkPlayer");
     foreach (GameObject player in players)
     {
         NetworkPlayer networkplayer = (NetworkPlayer)player.GetComponent("NetworkPlayer");
         networkplayer.photonView.RPC(rpc, target, param);
     }
 }
 void OnEnable()
 {
     if (broadcastToAllOthers)
     {
         rpcTarget = RpcTarget.Others;
     }
     else
     {
         rpcTarget = RpcTarget.All;
     }
 }
        public override void Reset()
        {
            // JFF: how can I set this silently without a plubic variable? if I set it to private, it doesn't work anymore. maybe I forgot a setting?
            eventTarget        = new FsmEventTarget();
            eventTarget.target = FsmEventTarget.EventTarget.BroadcastAll;

            remoteEvent             = null;
            rpcTarget               = RpcTarget.All;
            photonTargetsFromString = null;
            stringData              = null;
        }
Exemple #16
0
 private void SendMessage(string message, RpcTarget target)
 {
     if (PhotonNetwork.IsConnected)
     {
         SendOnlineMessage(message, target);
     }
     else
     {
         SendOfflineMessage(message);
     }
 }
Exemple #17
0
        public void QueueServerRpc(BitWriter bs, RpcTarget target)
        {
            bs.FlushBits();

            var qrpc = new QueuedRpc()
            {
                bs     = bs,
                target = target
            };

            queuedRpcs.Add(qrpc);
        }
Exemple #18
0
 /// <summary>
 /// Sends the NetStream to the RPC at the supplied target.
 /// </summary>
 /// <param name="target"> Who to send the RPC to. For a client, this should always be Server. </param>
 private void SendSync(RpcTarget target)
 {
     if (target == RpcTarget.None)
     {
         return;
     }
     if (syncMessage == null)
     {
         syncMessage = NetMessage.Create((ushort)ViewCmd.Sync, (uint)Id, 1, false);
     }
     syncMessage.Parameters[0] = syncStream;
     ViewManager.Send(this, syncMessage, target);
 }
Exemple #19
0
 public static void RpcSecure(this MonoBehaviourPun mb, RpcTarget target, Action func)
 {
     if (PunUtils.offlineOrNoRoom)
     {
         if (target == RpcTarget.All)
         {
             func.Invoke();
         }
         return;
     }
     mb.photonView.RpcSecure(func.Method.Name, target, true);
     PunRpcProfiler.AddRpcSent(func.Method.Name);
 }
Exemple #20
0
    /// <summary>
    /// Send data to {target} (based on message type).
    /// If game is not multiplayer the message wont send
    /// and will be handled right away
    /// </summary>
    public void Send(EPhotonMsg pMsgType, params object[] pParams)
    {
        //if(DEBUG_LOG)
        //	Debug.Log("Send " + pMsgType + ", MP: " + isMultiplayer);

        //todo: add timestamp to all messages?
        //eg. neede for setting health


        if (!CanSend(pMsgType))
        {
            if (DEBUG_LOG && !IsLogMsgIgnored(pMsgType))
            {
                Debug.Log(gameObject.name + " - cant send message: " + pMsgType);
            }
            return;
        }

        if (isMultiplayer)
        {
            if (!PhotonNetwork.IsConnected)
            {
                Debug.Log("Not connected - cant send message");
                return;
            }
            if (DEBUG_LOG && !IsLogMsgIgnored(pMsgType))
            {
                Debug.Log("Send " + pMsgType);
            }

            RpcTarget target = GetMsgTarget(pMsgType);
            view.RPC("HandleMsg", target, pMsgType, pParams);
        }
        else
        {
            if (DEBUG_LOG && !IsLogMsgIgnored(pMsgType))
            {
                Debug.Log("SendNotMP " + pMsgType);
            }

            if (debug_notMpMsgDelay > 0)
            {
                DoInTime(() => SendNotMP(pMsgType, pParams), debug_notMpMsgDelay);
            }
            else
            {
                SendNotMP(pMsgType, pParams);
            }
        }
    }
Exemple #21
0
        public static object Rpc(this FduObserverBase ob, string methodName, RpcTarget target, params object[] paras)
        {
            FduClusterView _viewInstance = ob.GetClusterView();

            if (_viewInstance == null)
            {
                Debug.LogError("[FduRPC]This observer is not registed to a cluster view yet. Game object name:" + ob.gameObject.name);
                return(null);
            }
            else
            {
                return(_viewInstance.Rpc(methodName, target, paras));
            }
        }
Exemple #22
0
        /// <summary>
        ///  Returns the connection that matches the supplied target.
        ///  Returns the server for Server or the first controller for Controllers.
        /// </summary>
        internal NetConnection GetTarget(RpcTarget target, NetView view)
        {
            switch (target)
            {
            case RpcTarget.Server:
                return(view.Server);

            case RpcTarget.Controllers:
                return(view.Controllers[0]);
            }

            NetLog.Error("Invalid RpcTarget for GetTarget. Only RpcTarget.Server or RpcTarget.Controllers can be used.");
            return(null);
        }
Exemple #23
0
        /// <summary> Send overload that creates the NetMessage for the RPC. </summary>
        internal void Send(int viewId, bool reliable, string methodName, RpcTarget target, params object[] parameters)
        {
            if (!Socket.Rpc.HasId(methodName))
            {
                NetLog.Error("Send failed: RPC method name has not been assigned an ID.");
                return;
            }
            if (!ViewLookup.ContainsKey(viewId))
            {
                return;
            }
            NetView view       = ViewLookup[viewId];
            var     netMessage = NetMessage.Create(Socket.Rpc.NameToId(methodName), (uint)viewId, parameters, reliable);

            Send(view, netMessage, target);
        }
Exemple #24
0
 public void RPC(string methodName, RpcTarget target, params object[] parameters)
 {
     for (int i = 0; i < parameters.Length; i++)
     {
         MonoBehaviourPun asScript = (parameters[i] as MonoBehaviourPun);
         if (asScript)
         {
             parameters[i] = asScript.photonView.ViewID;
         }
         PhotonView asView = (parameters[i] as PhotonView);
         if (asView)
         {
             parameters[i] = asView.ViewID;
         }
     }
     this.photonView.RPC(methodName, target, parameters);
 }
Exemple #25
0
        /// <summary>
        /// Replaces the user code with a stub.
        /// Moves the original code to a new method
        /// </summary>
        /// <param name="td">The class containing the method </param>
        /// <param name="md">The method to be stubbed </param>
        /// <param name="ServerRpcAttr">The attribute that made this an RPC</param>
        /// <returns>The method containing the original code</returns>
        /// <remarks>
        /// Generates code like this: (Observers case)
        /// <code>
        /// public void Test (int param)
        /// {
        ///     NetworkWriter writer = new NetworkWriter();
        ///     writer.WritePackedUInt32((uint) param);
        ///     base.SendRpcInternal(typeof(class),"RpcTest", writer, 0);
        /// }
        /// public void UserCode_Test(int param)
        /// {
        ///     // whatever the user did before
        /// }
        /// </code>
        ///
        /// Generates code like this: (Owner/Connection case)
        /// <code>
        /// public void TargetTest(NetworkConnection conn, int param)
        /// {
        ///     NetworkWriter writer = new NetworkWriter();
        ///     writer.WritePackedUInt32((uint)param);
        ///     base.SendTargetRpcInternal(conn, typeof(class), "TargetTest", val);
        /// }
        ///
        /// public void UserCode_TargetTest(NetworkConnection conn, int param)
        /// {
        ///     // whatever the user did before
        /// }
        /// </code>
        /// or if no connection is specified
        ///
        /// <code>
        /// public void TargetTest (int param)
        /// {
        ///     NetworkWriter writer = new NetworkWriter();
        ///     writer.WritePackedUInt32((uint) param);
        ///     base.SendTargetRpcInternal(null, typeof(class), "TargetTest", val);
        /// }
        ///
        /// public void UserCode_TargetTest(int param)
        /// {
        ///     // whatever the user did before
        /// }
        /// </code>
        /// </remarks>
        MethodDefinition GenerateStub(MethodDefinition md, CustomAttribute clientRpcAttr, ValueSerializer[] paramSerializers)
        {
            MethodDefinition rpc = SubstituteMethod(md);

            ILProcessor worker = md.Body.GetILProcessor();

            // if (IsClient)
            // {
            //    call the body
            // }
            CallBody(worker, rpc);

            // NetworkWriter writer = NetworkWriterPool.GetWriter()
            VariableDefinition writer = md.AddLocal <PooledNetworkWriter>();

            worker.Append(worker.Create(OpCodes.Call, () => NetworkWriterPool.GetWriter()));
            worker.Append(worker.Create(OpCodes.Stloc, writer));

            // write all the arguments that the user passed to the Rpc call
            WriteArguments(worker, md, writer, paramSerializers, RemoteCallType.ClientRpc);

            string rpcName = md.Name;

            RpcTarget target       = clientRpcAttr.GetField("target", RpcTarget.Observers);
            int       channel      = clientRpcAttr.GetField("channel", 0);
            bool      excludeOwner = clientRpcAttr.GetField("excludeOwner", false);

            // invoke SendInternal and return
            // this
            worker.Append(worker.Create(OpCodes.Ldarg_0));

            if (target == RpcTarget.Player && HasNetworkPlayerParameter(md))
            {
                worker.Append(worker.Create(OpCodes.Ldarg_1));
            }
            else if (target == RpcTarget.Owner)
            {
                worker.Append(worker.Create(OpCodes.Ldnull));
            }

            worker.Append(worker.Create(OpCodes.Ldtoken, md.DeclaringType.ConvertToGenericIfNeeded()));
            // invokerClass
            worker.Append(worker.Create(OpCodes.Call, () => Type.GetTypeFromHandle(default)));
Exemple #26
0
        void ExecuteAction()
        {
            if (remoteEvent != null && remoteEvent.IsGlobal == false)
            {
                return;
            }

            if (PlayMakerPhotonProxy.Instance == null)
            {
                Debug.LogError("PlayMakerPhotonProxy is missing in the scene");
                return;
            }

            _rpcTargets = (RpcTarget)rpcTargets.Value;

            if (eventTarget.target == FsmEventTarget.EventTarget.BroadcastAll)
            {
                if (!stringData.IsNone && stringData.Value != "")
                {
                    PlayMakerPhotonProxy.Instance.PhotonRpcBroadcastFsmEventWithString(_rpcTargets, remoteEvent.Name, stringData.Value);
                }
                else
                {
                    PlayMakerPhotonProxy.Instance.PhotonRpcBroadcastFsmEvent(_rpcTargets, remoteEvent.Name);
                }
            }
            else
            {
                if (!stringData.IsNone && stringData.Value != "")
                {
                    //		PlayMakerPhotonProxy.Instance.PhotonRpcSendFsmEventWithString(_rpcTargets, remoteEvent.Name,stringData.Value);
                }
                else
                {
                    //		PlayMakerPhotonProxy.Instance.PhotonRpcSendFsmEvent(_rpcTargets,remoteEvent.Name);
                }
            }
        }
Exemple #27
0
        /// <summary>
        /// Generates a skeleton for an RPC
        /// </summary>
        /// <param name="td"></param>
        /// <param name="method"></param>
        /// <param name="cmdCallFunc"></param>
        /// <returns>The newly created skeleton method</returns>
        /// <remarks>
        /// Generates code like this:
        /// <code>
        /// protected static void Skeleton_Test(NetworkBehaviour obj, NetworkReader reader, NetworkConnection senderConnection)
        /// {
        ///     if (!obj.Identity.server.active)
        ///     {
        ///         return;
        ///     }
        ///     ((ShipControl) obj).UserCode_Test(reader.ReadSingle(), (int) reader.ReadPackedUInt32());
        /// }
        /// </code>
        /// </remarks>
        MethodDefinition GenerateSkeleton(MethodDefinition md, MethodDefinition userCodeFunc, CustomAttribute clientRpcAttr, ValueSerializer[] paramSerializers)
        {
            MethodDefinition rpc = md.DeclaringType.AddMethod(
                SkeletonPrefix + md.Name,
                MethodAttributes.Family | MethodAttributes.HideBySig);

            ParameterDefinition readerParameter = rpc.AddParam <NetworkReader>("reader");

            _ = rpc.AddParam <INetworkPlayer>("senderConnection");
            _ = rpc.AddParam <int>("replyId");

            ILProcessor worker = rpc.Body.GetILProcessor();

            worker.Append(worker.Create(OpCodes.Ldarg_0));

            // NetworkConnection parameter is only required for Client.Connection
            RpcTarget target = clientRpcAttr.GetField("target", RpcTarget.Observers);
            bool      hasNetworkConnection = target == RpcTarget.Player && HasNetworkPlayerParameter(md);

            if (hasNetworkConnection)
            {
                // this is called in the skeleton (the client)
                // the client should just get the connection to the server and pass that in
                worker.Append(worker.Create(OpCodes.Ldarg_0));
                worker.Append(worker.Create(OpCodes.Call, (NetworkBehaviour nb) => nb.Client));
                worker.Append(worker.Create(OpCodes.Callvirt, (INetworkClient nb) => nb.Player));
            }

            ReadArguments(md, worker, readerParameter, senderParameter: null, hasNetworkConnection, paramSerializers);

            // invoke actual ServerRpc function
            worker.Append(worker.Create(OpCodes.Callvirt, userCodeFunc));
            worker.Append(worker.Create(OpCodes.Ret));

            return(rpc);
        }
Exemple #28
0
        private void SendRPC <T>(T data, SendTarget sendTargets = SendTarget.ToTarget) where T : MessageData
        {
            data.senderId = UserManager.Instance.userID;
            string requestJsonString = MessageSenderUtil.Encode <T>(data);

            RpcTarget target = RpcTarget.Others;

            switch (sendTargets)
            {
            case SendTarget.ToAll:
                target = RpcTarget.All;
                break;

            case SendTarget.ToOthers:
                target = RpcTarget.Others;
                break;

            default:
                target = RpcTarget.Others;
                break;
            }

            pv?.RPC("RecvRPCData", target, requestJsonString, data.action);
        }
 private void SendMapIndex(int index, RpcTarget receiver)
 {
     photonView.RPC("RPC_UpdateMapIndex", receiver, index);
 }
Exemple #30
0
 /// <summary>
 /// Call a RPC method of this GameObject on remote clients of this room (or on all, inclunding this client).
 /// </summary>
 /// <remarks>
 /// [Remote Procedure Calls](@ref rpcManual) are an essential tool in making multiplayer games with PUN.
 /// It enables you to make every client in a room call a specific method.
 ///
 /// RPC calls can target "All" or the "Others".
 /// Usually, the target "All" gets executed locally immediately after sending the RPC.
 /// The "*ViaServer" options send the RPC to the server and execute it on this client when it's sent back.
 /// Of course, calls are affected by this client's lag and that of remote clients.
 ///
 /// Each call automatically is routed to the same PhotonView (and GameObject) that was used on the
 /// originating client.
 ///
 /// See: [Remote Procedure Calls](@ref rpcManual).
 /// </remarks>
 ///<param name="methodName">The name of a fitting method that was has the RPC attribute.</param>
 ///<param name="target">The group of targets and the way the RPC gets sent.</param>
 ///<param name="encrypt"> </param>
 ///<param name="parameters">The parameters that the RPC method has (must fit this call!).</param>
 public void RpcSecure(string methodName, RpcTarget target, bool encrypt, params object[] parameters)
 {
     PhotonNetwork.RPC(this, methodName, target, encrypt, parameters);
 }
 /// <summary> Sends an RPC to connections that are in-scope for the provided view. </summary>
 internal void Send(NetView view, NetMessage netMessage, RpcTarget target) {
     switch (target) {
         case (RpcTarget.All):
             for (int i = 0; i < Socket.Connections.Count; i++) {
                 var connection = Socket.Connections[i];
                 if (!connection.HasScope) continue;
                 if (view.Group != 0 && !connection.InGroup(view.Group)) continue;
                 if ((netMessage.Reliable && connection.Scope.In(view.Id)) || connection.Scope.In(view.Id, syncFrame) || view.IsController(connection)) connection.Send(netMessage);
             }
             break;
         case (RpcTarget.Controllers):
             foreach (NetConnection controller in view.Controllers) {
                 if (controller == Socket.Self) continue;
                 controller.Send(netMessage);
             }
             break;
         case (RpcTarget.NonControllers):
             for (int i = 0; i < Socket.Connections.Count; i++) {
                 var connection = Socket.Connections[i];
                 if (connection.IsServer || !connection.HasScope) continue;
                 if (view.IsController(connection)) continue;
                 if (view.Group != 0 && !connection.InGroup(view.Group)) continue;
                 if ((netMessage.Reliable && connection.Scope.In(view.Id)) || connection.Scope.In(view.Id, syncFrame)) connection.Send(netMessage);
             }
             break;
         case (RpcTarget.Server):
             if (view.Server != Socket.Self) view.Server.Send(netMessage);
             else NetLog.Warning("Trying to send message to self.");
             break;
         case (RpcTarget.AllInclOutOfScope):
             for (int i = 0; i < Socket.Connections.Count; i++) {
                 var connection = Socket.Connections[i];
                 if (view.Group != 0 && !connection.InGroup(view.Group)) continue;
                 connection.Send(netMessage);
             }
             break;
     }
 }
 /// <summary> Send overload that creates the NetMessage for the RPC. </summary>
 internal void Send(int viewId, bool reliable, string methodName, RpcTarget target, params object[] parameters) {
     if (!Socket.Rpc.HasId(methodName)) {
         NetLog.Error("Send failed: RPC method name has not been assigned an ID.");
         return;
     }
     if (!ViewLookup.ContainsKey(viewId)) return;
     NetView view = ViewLookup[viewId];
     var netMessage = NetMessage.Create(Socket.Rpc.NameToId(methodName), (uint)viewId, parameters, reliable);
     Send(view, netMessage, target);
 }
        /// <summary>
        ///  Returns the connection that matches the supplied target.
        ///  Returns the server for Server or the first controller for Controllers.
        /// </summary>
        internal NetConnection GetTarget(RpcTarget target, NetView view) {
            switch (target) {
                case RpcTarget.Server:
                    return view.Server;
                case RpcTarget.Controllers:
                    return view.Controllers[0];
            }

            NetLog.Error("Invalid RpcTarget for GetTarget. Only RpcTarget.Server or RpcTarget.Controllers can be used.");
            return null;
        }