public GameObject ManualBuildSyncToken(InstantiationData dataToSend)
    {
        var go    = PrefabPoolManager.Instance.Instantiate("TransmissionToken", Vector3.zero, Quaternion.identity);//Instantiate(transmissionTokenPrefab);
        var pView = go.GetComponent <PhotonView>();

        if (PhotonNetwork.AllocateViewID(photonView))
        {
            var raiseEventOptions = new RaiseEventOptions
            {
                Receivers     = ReceiverGroup.Others,
                CachingOption = EventCaching.AddToRoomCache
            };

            var sendOptions = new SendOptions {
                Reliability = true
            };

            dataToSend.Add("viewID", photonView.ViewID.ToString());

            PhotonNetwork.RaiseEvent(
                (byte)RaiseEvnetCode.CustomManualInstantiationEventCode,
                dataToSend.ToData(),
                raiseEventOptions,
                sendOptions);

            return(go);
        }

        Debug.LogError("Failed to allocate a ViewId.");
        Destroy(go);
        return(null);
    }
        public void TestInstantiationDataSerialzation()
        {
            var data = new InstantiationData(
                new object[2] {
                SyncTokenType.Player,
                new List <string> {
                    "syncPos", "True", "syncRot", "False"
                }
            });

            Debug.Log($"data:{data.ToString()} {data.Count} {data.ToData().Length}");

            var ty = (SyncTokenType)data.ToData()[0];

            Debug.Log($"data SyncTokenType:{ty}");
            var li = (List <string>)data.ToData()[1];

            Debug.Log($"data List<string>:{li}");
            foreach (var ll in li)
            {
                Debug.Log($"<string>:{ll}");
            }

            var data2 = new InstantiationData(data.ToData());

            Debug.Log($"data2 Objectify:{data2.ToString()} {data2.Count} {data2.ToData().Length}");

            var data3 = InstantiationData.Build(data.ToString());

            data3.Add("k3", "v3");
            Debug.Log($"data3 Stringify:{data3.ToString()} {data3.Count} {data3.ToData().Length}");

            var data4 = InstantiationData.Build(SyncTokenType.Player);

            data4.Add("k1", "v1");
            data4.Add("k2", "v2");
            data4.Add("k3", "v3");
            data4.Add("k4", "v4");
            Debug.Log($"data4 Stringify:{data4.ToString()} {data4.Count} {data4.ToData().Length}");
        }
    public object RequestSyncToken(InstantiationData dataToSend)
    {
        if (!PhotonNetwork.InRoom)
        {
            Debug.LogWarning($"RequestSyncToken NotInRoom");
            return(null);
        }

        GameObject go = null;

        switch (dataToSend.tokenType)
        {
        case SyncTokenType.Player:
            Debug.Log($"PhotonNetwork.Instantiate RequestSyncToken");
            go = PhotonNetwork.Instantiate("Token/TransmissionToken", Vector3.zero, Quaternion.identity, 0, dataToSend.ToData());
            break;

        default:
            if (PhotonNetwork.IsMasterClient)
            {
                go = PhotonNetwork.InstantiateRoomObject("Token/TransmissionToken", Vector3.zero, Quaternion.identity, 0, dataToSend.ToData());
            }
            else
            {
                Debug.LogWarning($"Non MC Cannot InstantiateRoomObject");
            }
            break;
        }

        if (go == null)
        {
            Debug.LogWarning($"Issuing Null GameObject");
        }

        return(go);
    }
    public void RequestRoomObjectManipulation(object data, PhotonMessageInfo info)
    {
        if (!PhotonNetwork.IsMasterClient)
        {
            Debug.LogWarning("[RequestRoomObjectManipulation] Only Master Client can Manipulate RoomObject!");
            return;
        }

        var insData = new InstantiationData(data as object[]);

        //TODO: MC Verify data
        if (insData.tokenType != SyncTokenType.General)
        {
            Debug.LogWarning("[RequestRoomObjectManipulation] Only For Manipulate RoomObject!");
            return;
        }

        if (insData.TryGetValue(InstantiationData.InstantiationKey.objectname, out object objName))
        {
            // Object UUID
            if (!insData.ContainsKey(InstantiationData.InstantiationKey.objectuuid))
            {
                var tokenID = $"ro_{Random.Range(1000, 9999).ToString()}";
                insData[InstantiationData.InstantiationKey.objectuuid.ToString()] = tokenID;
            }

            if (insData.TryGetValue(InstantiationData.InstantiationKey.sceneobject, out object soModification))
            {
                switch ((string)soModification)
                {
                case "create":
                    Debug.LogWarning("[RequestRoomObjectManipulation] Create");
                    itp.RequestSyncToken(insData);
                    break;

                case "destroy":
                    photonView.RPC("RequestLocalObjectManipulation", RpcTarget.Others, insData.ToData() as object);

                    itp.RevokeSyncToken(insData);

                    iosManager.DestroyObject((string)objName, (string)insData["objectuuid"]);

                    Debug.LogWarning($"[RequestRoomObjectManipulation] MC Destroy {insData}");
                    break;
                }
            }
        }
    }
 public void DestroyRoomObject(InstantiationData insData)
 {
     photonView.RPC("RequestRoomObjectManipulation", RpcTarget.MasterClient, insData.ToData() as object);
 }