/// <summary> /// Method which is called when class is contructed, and deletes references to other user's controllers /// </summary> private void Start() { if (PV.IsMine) { //subscribe the mouse senstivity method to settings update event GameEvents.current.onSettingsUpdate += updateMouse; //Equip the first item available EquipItem(0); //Remove the material entry in the hashmap if there is one if (customProperties.ContainsKey("app")) { customProperties.Remove("app"); } //Determine the material that a player should be rendered as if (PhotonNetwork.IsMasterClient) { customProperties.Add("app", 1); PhotonNetwork.LocalPlayer.SetCustomProperties(customProperties); } else { customProperties.Add("app", 2); PhotonNetwork.LocalPlayer.SetCustomProperties(customProperties); } } else { //destroy cameras and rigidbodies if they are not assigned to the local user Destroy(GetComponentInChildren <Camera>().gameObject); Destroy(rb); } }
// 封装复用方法,给自己分配一个序号 // RoomInfo 里的公共变量string "1234567" 来保存序号 public void GetFlag() { ExitGames.Client.Photon.Hashtable roomProperties = thisRoom.CustomProperties; if (!roomProperties.ContainsKey("RedCount")) { roomProperties.Add("RedCount", 1); flag = 0; roomProperties.Add("RedIds", "123"); playerId = 0; } else if ((int)roomProperties["RedCount"] == maxPlayerOneSide) { if (!roomProperties.ContainsKey("BlueCount")) { roomProperties.Add("BlueCount", 1); flag = Flag.Blue; roomProperties.Add("BlueIds", "567"); playerId = 4; } else { roomProperties["BlueCount"] = (int)roomProperties["BlueCount"] + 1; flag = Flag.Red; playerId = ((string)roomProperties["BlueIds"])[0] - '0'; roomProperties["BlueIds"] = ((string)roomProperties["BlueIds"]).Substring(1); } } else { roomProperties["RedCount"] = (int)roomProperties["RedCount"] + 1; playerId = ((string)roomProperties["RedIds"])[0] - '0'; roomProperties["RedIds"] = ((string)roomProperties["RedIds"]).Substring(1); } thisRoom.SetCustomProperties(roomProperties); }
public override void OnPlayerPropertiesUpdate(Player targetPlayer, Hashtable changedProps) { if (changedProps.ContainsKey(PoringPrototype.PLAYER_LIVES)) { // CheckEndOfGame(); return; } if (!PhotonNetwork.IsMasterClient) { return; } if (changedProps.ContainsKey(PoringPrototype.PLAYER_LOADED_LEVEL)) { if (CheckAllPlayerLoadedLevel()) { Hashtable props = new Hashtable { { CountdownTimer.CountdownStartTime, (float)PhotonNetwork.Time } }; PhotonNetwork.CurrentRoom.SetCustomProperties(props); } } }
public override void OnPhotonPlayerPropertiesChanged(object[] playerAndUpdatedProps) { PhotonPlayer m_photonPlayer = (PhotonPlayer)playerAndUpdatedProps[0]; Hashtable m_changedPropertie = (Hashtable)playerAndUpdatedProps[1]; if (m_changedPropertie.ContainsKey(PunPlayerScores.PlayerScoreProp)) { int m_score = (int)m_changedPropertie[PunPlayerScores.PlayerScoreProp]; if (m_photonPlayer.ID == m_pView.OwnerActorNr) { ChangeColor(m_score); } } if (m_changedPropertie.ContainsKey(PunPlayerScores.PlayerWeaponID)) { int w_Id = (int)m_changedPropertie[PunPlayerScores.PlayerWeaponID]; if (m_photonPlayer.ID == m_pView.OwnerActorNr) { GetComponent <PhotonView>().RPC("GetWeaponek", PhotonTargets.AllBuffered, w_Id); //GetWeaponek(w_Id); } } }
public override void OnRoomPropertiesUpdate(Hashtable propertiesThatChanged) { if (propertiesThatChanged.ContainsKey("Tile")) { GameObject go = PhotonNetwork.CurrentRoom.GetTileData(); Tile tile = go.GetComponent <Tile>(); Vector2 targetPos = new Vector2(); bool isChange = false; foreach (Transform tf in this.transform) { if (tf.gameObject.GetComponent <Tile>().Pos == tile.Pos) { targetPos = tf.gameObject.GetComponent <Tile>().Pos; Destroy(tf.gameObject); isChange = true; } } go.transform.SetParent(this.transform); if (isChange) { go.transform.SetSiblingIndex((int)targetPos.y * GetComponent <GridLayoutGroup>().constraintCount + (int)targetPos.x); } } if (propertiesThatChanged.ContainsKey("Worker")) { GameObject go = PhotonNetwork.CurrentRoom.GetWorker(); Worker worker = go.GetComponent <Worker>(); go.transform.SetParent(this.transform.GetChild((int)worker.Pos.y * GetComponent <GridLayoutGroup>().constraintCount + (int)worker.Pos.x)); go.transform.localPosition = new Vector3(0, 0, 0); if (PhotonNetwork.CurrentRoom.GetTurnPlayer() == PhotonNetwork.LocalPlayer) { GameObject.Find("BuildingAbilityListViewer").GetComponent <BuildingAbilityListViewer>().Show(worker.GetAroundBuildings()); } } }
public override void OnPlayerPropertiesUpdate(Player targetPlayer, Hashtable changedProps) { if (changedProps.ContainsKey(GameConstants.PLAYER_LIVES)) { CheckEndOfGame(); Debug.Log("Properties contains PLAYER_LIVES"); return; } if (!PhotonNetwork.IsMasterClient) { return; } //Will only be run by master client only at this point int startTimestamp; bool startTimeIsSet = CountdownTimer.TryGetStartTime(out startTimestamp); if (changedProps.ContainsKey(GameConstants.PLAYER_HAS_LOADED_LEVEL)) { if (CheckAllPlayerHasLoaded()) { if (!startTimeIsSet) { CountdownTimer.SetStartTime(); } } else { //Waiting for player Debug.Log("Not all player is loaded! waiting for players..."); } } }
void SetupPlayerProps() { Hashtable PlayerCustomProps = PhotonNetwork.LocalPlayer.CustomProperties; if (PlayerCustomProps.ContainsKey("CharacterName")) { playerProps.CharacterType = (string)PlayerCustomProps["CharacterName"]; } else { playerProps.CharacterType = "Ruso"; } if (PlayerCustomProps.ContainsKey("Team")) { int PropsTeam = (int)PlayerCustomProps["Team"]; playerProps.Team = PropsTeam >= 0 && PropsTeam < TeamSpawnUnit.Length ? (int)PlayerCustomProps["Team"] : 0; } else { playerProps.Team = 0; } if (PlayerCustomProps.ContainsKey("Alive")) { playerProps.Alive = (bool)PlayerCustomProps["Alive"]; } else { playerProps.Alive = false; } }
public void OnRoomPropertiesUpdate(ExitGames.Client.Photon.Hashtable propertiesThatChanged) { if (propertiesThatChanged.ContainsKey(PropertiesKeys.Team1Score) || propertiesThatChanged.ContainsKey(PropertiesKeys.Team2Score)) { CheckScore(); } }
public override void OnPlayerPropertiesUpdate(Player targetPlayer, Hashtable changedProps) { if (changedProps.ContainsKey(InspiritVRQuizGame.PLAYER_LIVES)) { CheckEndOfGame(); return; } if (!PhotonNetwork.IsMasterClient) { return; } // if there was no countdown yet, the master client (this one) waits until everyone loaded the level and sets a timer start int startTimestamp; bool startTimeIsSet = CountdownTimerController.TryGetStartTime(out startTimestamp); if (changedProps.ContainsKey(InspiritVRQuizGame.PLAYER_LOADED_LEVEL)) { if (CheckAllPlayerLoadedLevel()) { if (!startTimeIsSet) { CountdownTimerController.SetStartTime(); } } else { // not all players loaded yet. wait: infoText.text = "Waiting for other players..."; } } }
public override void OnRoomPropertiesUpdate(Hashtable propertiesThatChanged) { if (propertiesThatChanged.ContainsKey(GnG.EAT_ENERGY)) { int energy = (int)propertiesThatChanged[GnG.EAT_ENERGY]; m_CurrentEnergyCount = energy; m_Slider.value = (float)energy / GnG.MAX_ENERGY_COUNT; if (m_CurrentEnergyCount >= GnG.MAX_ENERGY_COUNT) { m_RevivalDoor.SetActive(true); } foreach (Player p in PhotonNetwork.PlayerList) { Debug.Log(p.NickName + " : " + p.GetScore().ToString()); } } if (propertiesThatChanged.ContainsKey(GnG.REVIVAL_GHOST_COUNT)) { int revGhost = (int)propertiesThatChanged[GnG.REVIVAL_GHOST_COUNT]; if (revGhost >= PhotonNetwork.CurrentRoom.PlayerCount - 1) { EndGame(GnG.TeamType.Ghost); } } }
public void OnPhotonCustomRoomPropertiesChanged(Hashtable propertiesThatChanged) { if (propertiesThatChanged.ContainsKey("player1trail") == true) { if (PlayerNo != 1) { trailListJson = propertiesThatChanged["player1trail"].ToString(); TrailList = ConvertStringToIntList(trailListJson); ownedListJson = propertiesThatChanged["player1owned"].ToString(); OwnedList = ConvertStringToIntList(ownedListJson); Player.SyncTrail(); Player.SyncFill(); //if(TrailList.Contains(Player.lastReachedGroundPiece.indexInGrid)) } } if (propertiesThatChanged.ContainsKey("player2trail") == true) { if (PlayerNo != 2) { trailListJson = propertiesThatChanged["player2trail"].ToString(); TrailList = ConvertStringToIntList(trailListJson); ownedListJson = propertiesThatChanged["player2owned"].ToString(); OwnedList = ConvertStringToIntList(ownedListJson); Player.SyncTrail(); Player.SyncFill(); } } }
public void OnPhotonCustomRoomPropertiesChanged(Hashtable propertiesThatChanged) { if (propertiesThatChanged.ContainsKey("DeckTotal")) { GetComponent <TextMeshProUGUI>().text = "Deck: " + this.Total; //Debug.Log("Deck Count: " + this.Total); } if (propertiesThatChanged.ContainsKey("DeckAttack")) { Debug.Log("Creating deck..."); Create(); } if (propertiesThatChanged.ContainsKey("DeckInteract")) { // Player is done interacting if (propertiesThatChanged["DeckInteract"].Equals("")) { Debug.Log("Deck is free."); } else { Debug.Log(propertiesThatChanged["DeckInteract"].ToString() + " using deck."); } } }
public override void OnPlayerPropertiesUpdate(Player targetPlayer, Hashtable changedProps) { if (PhotonNetwork.IsMasterClient) { if (changedProps.ContainsKey(KeyStrings.SceneLoaded)) { SetupTurnOrder(); } // don't do this ever again (will otherwise again and see ready on phasechange etc) if (changedProps.ContainsKey(KeyStrings.ZoneMap) && !zoneMapsDone) { bool everyoneReady = true; foreach (Player player in PhotonNetwork.CurrentRoom.Players.Values) { if (player.CustomProperties[KeyStrings.ZoneMap] == null) // if any player is not ready { everyoneReady = false; break; } } if (everyoneReady) { zoneMapsDone = true; SetupGameState(); } } } }
public void OnPhotonCustomRoomPropertiesChanged(Hashtable propertiesThatChanged) { if (propertiesThatChanged.ContainsKey("TurnCount")) { isTimeEnded = false; turnCountUI.text = "Turn: " + Turn.ToString(); Debug.Log("Turn: " + Turn); } if (propertiesThatChanged.ContainsKey("TurnPlayer")) { turnPlayerUI.text = "Current Turn: " + this.CurrentPlayer; } if (propertiesThatChanged.ContainsKey("EndMove")) { if ((bool)propertiesThatChanged["EndMove"]) { isTimeEnded = true; Debug.Log(this.CurrentPlayer + " ended their turn."); if (PhotonNetwork.isMasterClient) { StartCoroutine(WaitToStartNextTurn()); } } } }
public void OnPhotonCustomRoomPropertiesChanged(ExitGames.Client.Photon.Hashtable propertiesThatChanged) { if (propertiesThatChanged.ContainsKey("startTime") && propertiesThatChanged.ContainsKey("duration")) { storedStartTime = (int)propertiesThatChanged["startTime"]; storedDuration = (int)propertiesThatChanged["duration"]; } }
/// <summary> /// Local player property to send to the target player (often Player2) /// </summary> public void SendPlayerProperty(string propName, object value) { if (playerData.ContainsKey(propName)) { playerData[propName] = value; } else { playerData.Add(propName, value); } }
void OnPhotonCustomRoomPropertiesChanged(PhotonHashTable propertiesThatChanged) { if (propertiesThatChanged.ContainsKey("Round")) { round = (int)room.customProperties ["Round"]; } if (propertiesThatChanged.ContainsKey("C1")) { UpdateStats(); } }
// when the room properties change, the text values next to the sliders are told to update so both players have synchronised values public override void OnRoomPropertiesUpdate(ExitGames.Client.Photon.Hashtable propertiesThatChanged) { if (propertiesThatChanged.ContainsKey("sliderValue")) { text.text = propertiesThatChanged["sliderValue"].ToString(); } if (propertiesThatChanged.ContainsKey("sliderValueDiff")) { textDiff.text = propertiesThatChanged["sliderValueDiff"].ToString(); } }
//*********************Call Backs *******************// public override void OnRoomPropertiesUpdate(Hashtable propertiesThatChanged) { if (propertiesThatChanged.ContainsKey(Constants.INITIALIZING_CARDS)) { Debug.Log("Intializing cards"); if (!PhotonNetwork.IsMasterClient) { Dictionary <string, List <byte> > reply = (Dictionary <string, List <byte> >)propertiesThatChanged[Constants.INITIALIZING_CARDS]; if (reply.ContainsKey(localPlayer.PlayerId)) { leastCountManager.AddCardValuesToPlayer(localPlayer.PlayerId, reply[localPlayer.PlayerId]); leastCountManager.AddCardValuesToPlayer(remotePlayer.PlayerId, reply[remotePlayer.PlayerId]); leastCountManager.SetPoolOfCards(reply["poolOfCards"]); leastCountManager.AddCardToDroppedCards(reply[Constants.INITIALIZING_DROPPEDCARD][0]); intializing = true; gameState = GameState.GameStarted; GameFlow(); } } } if (propertiesThatChanged.ContainsKey(Constants.GAME_STATE_CHANGED)) { int state = (int)propertiesThatChanged[Constants.GAME_STATE_CHANGED]; if (!PhotonNetwork.IsMasterClient) { CheckPlayersBooks(); ShowAndHidePlayersDisplayingCards(); } } if (propertiesThatChanged.ContainsKey(Constants.PLAYER_MOVE)) { PlayerMove move = (PlayerMove)propertiesThatChanged[Constants.PLAYER_MOVE]; int justPlayed = move.CurrentActorNumber; byte replyDroppedCards = move.droppedCards; byte drawnCard = move.drawnCard; string drawn = move.drawnFromDeckOrDropped; int currentPlayerId = move.NextActorNumber; if (justPlayed != PhotonNetwork.LocalPlayer.ActorNumber) { MoveAnimations(replyDroppedCards, 0, drawnCard); } if (currentPlayerId == PhotonNetwork.LocalPlayer.ActorNumber) { currentTurnPlayer = localPlayer; gameState = GameState.TurnSelectingDroppingCard; GameFlow(); } //Animation } }
public void OnRoomPropertiesUpdate(Hastable propertiesThatChanged) { if (propertiesThatChanged.ContainsKey(PropertiesKeys.Team1Score)) { int t1 = PhotonNetwork.CurrentRoom.GetRoomScore(Team.Team1); UI.Team1ScoreText.text = t1.ToString(); } else if (propertiesThatChanged.ContainsKey(PropertiesKeys.Team2Score)) { int t2 = PhotonNetwork.CurrentRoom.GetRoomScore(Team.Team2); UI.Team2ScoreText.text = t2.ToString(); } }
/// <summary>Reads the "custom content" Hashtable that is sent as color update.</summary> /// <returns>Hashtable for event "color" to update others</returns> public void ReadEvColor(Hashtable evContent) { if (evContent.ContainsKey((byte)1)) { this.Color = (int)evContent[(byte)1]; } else if (evContent.ContainsKey("1")) { // js client event support (those can't send with byte-keys) this.Color = System.Convert.ToInt32(evContent["1"]); } this.LastUpdateTimestamp = GameLogic.Timestamp; }
public override void OnPlayerPropertiesUpdate(Player targetPlayer, Hashtable changedProps) { if (!PV.IsMine && targetPlayer == PV.Owner) { if (changedProps.ContainsKey("itemIndex")) { EquipItem((int)changedProps["itemIndex"]); } if (changedProps.ContainsKey("firedGun")) { //BulletFlash((int)changedProps["firedGun"]); } } }
public override void OnPhotonCustomRoomPropertiesChanged(ExitGames.Client.Photon.Hashtable propertiesThatChanged) { if (propertiesThatChanged.ContainsKey(TimeToStartProp)) { this.temp = (double)propertiesThatChanged[TimeToStartProp]; Debug.Log("Got StartTime: " + this.temp); } if (propertiesThatChanged.ContainsKey(TimeToBornSoldier)) { this.timeToBornSoldier = (double)propertiesThatChanged[TimeToBornSoldier]; Debug.Log("enemyBornTime: " + this.timeToBornSoldier); } }
void Awake() { PhotonNetwork.LocalPlayer.AddScore(SScore_); if (!Sc.ContainsKey("score_")) { Sc.Add("score_", score_); } if (!Sc.ContainsKey("Score_")) { Sc.Add("Score_", score_); } PhotonNetwork.LocalPlayer.SetCustomProperties(Sc, null); }
public override void OnRoomPropertiesUpdate(Hashtable roomSettings) { if (!PhotonNetwork.IsMasterClient) { if (roomSettings.ContainsKey("mapLat") && roomSettings.ContainsKey("mapLong")) { Vector2d latLong = new Vector2d( (double)roomSettings["mapLat"], (double)roomSettings["mapLong"] ); _map.Initialize(latLong, _map.AbsoluteZoom); } } }
public override void OnRoomPropertiesUpdate(Hashtable propertiesThatChanged) { base.OnRoomPropertiesUpdate(propertiesThatChanged); if (propertiesThatChanged.ContainsKey("complete")) { PopupManagement.Instance.Add("PopupScore"); } if (propertiesThatChanged.ContainsKey("score")) { _labelScore.text = "" + propertiesThatChanged["score"]; } }
public override void OnPlayerPropertiesUpdate(Player targetPlayer, Hashtable changedProps) { if (changedProps.ContainsKey("killer")) { //this is for updating local data from others SomeoneGotAKill((int)changedProps["killer"]); } if (changedProps.ContainsKey("killer")) { int killer = (int)changedProps["killer"]; bool scoreExists = false; for (int i = 0; i < players.Count; i++) { if (players[i] == killer) { scoreExists = true; scores[i]++; } } if (!scoreExists) { players.Add(killer); scores.Add(1); } for (int i = 0; i < scores.Count; i++) { if (scores[i] > highestScore) { highestScore = scores[i]; } } for (int i = 0; i < scores.Count; i++) { if (scores[i] == highestScore) { IDofHighestScore = players[i]; } } CheckForWinner(); } }
public override void OnPhotonCustomRoomPropertiesChanged(Hashtable propertiesThatChanged) { if (propertiesThatChanged.ContainsKey(PlayerRoomIndexing.RoomPlayerIndexedProp)) { RefreshData(); } }
public override void OnPlayerPropertiesUpdate(Player target, Hashtable changedProps) { base.OnPlayerPropertiesUpdate(target, changedProps); if (target.ActorNumber == PhotonNetwork.LocalPlayer.ActorNumber && changedProps.ContainsKey("seat") && (int)changedProps["seat"] != 0) { foreach (Player player in PhotonNetwork.PlayerList) { UpdatePlayerGui(player); } for (int i = 1; i <= 5; i++) { Button button = Seats.transform.GetChild(ComputeSlot(i)).gameObject.GetComponent <Button>(); button.onClick.RemoveAllListeners(); int localIndex = i; button.onClick.AddListener(() => { ChangeSeatOnClick(localIndex); }); } } else if (PhotonNetwork.LocalPlayer.CustomProperties.ContainsKey("seat") && (int)PhotonNetwork.LocalPlayer.CustomProperties["seat"] != 0) { UpdatePlayerGui(target); } else { } }
public void Update() { if (NetwordLauncher.mapSelect != 0 && MapID == 0 && PhotonNetwork.IsMasterClient) { o = NetwordLauncher.mapSelect - 1; transform.GetChild(o).gameObject.SetActive(true); if (!lookMap.ContainsKey("map")) { lookMap.Add("map", o); PhotonNetwork.LocalPlayer.SetCustomProperties(lookMap, null); } else { lookMap.Remove("map"); lookMap.Add("map", o); PhotonNetwork.LocalPlayer.SetCustomProperties(lookMap, null); } //for (int i = 0; i < transform.childCount; i++) //{ // transform.GetChild(i).gameObject.SetActive(false); //} } if (!PhotonNetwork.IsMasterClient) { foreach (Player player in PhotonNetwork.PlayerList) { if (player.IsMasterClient) { o = (int)player.CustomProperties["map"]; } } transform.GetChild(o).gameObject.SetActive(true); } }
private Hashtable GetActorPropertiesForActorNr(Hashtable actorProperties, int actorNr) { if (actorProperties.ContainsKey(actorNr)) { return (Hashtable)actorProperties[actorNr]; } return actorProperties; }
/// <summary> /// reads incoming messages created by "OnSerialize" /// </summary> private bool DeltaCompressionRead(PhotonView view, Hashtable data) { if (data.ContainsKey((byte)1)) { // we have a full list of data (cause key 1 is used), so return "we have uncompressed all" return true; } // Compression was applied as data[(byte)2] exists (this is the data with some fields being compressed to null) // now we also need a previous "full" list of values to restore values that are null in this msg if (view.lastOnSerializeDataReceived == null) { return false; // We dont have a full match yet, we cannot work with missing values: skip this message } object[] compressedContents = data[(byte)2] as object[]; if (compressedContents == null) { // despite expectation, there is no compressed data in this msg. shouldn't happen. just a null check return false; } int[] indexesThatAreChangedToNull = data[(byte)3] as int[]; if (indexesThatAreChangedToNull == null) { indexesThatAreChangedToNull = new int[0]; } object[] lastReceivedData = view.lastOnSerializeDataReceived; for (int index = 0; index < compressedContents.Length; index++) { if (compressedContents[index] == null && !indexesThatAreChangedToNull.Contains(index)) { // we replace null values in this received msg unless a index is in the "changed to null" list object lastValue = lastReceivedData[index]; compressedContents[index] = lastValue; } } data[(byte)1] = compressedContents; // compressedContents are now uncompressed... return true; }
internal GameObject DoInstantiate(Hashtable evData, PhotonPlayer photonPlayer, GameObject resourceGameObject) { // some values always present: string prefabName = (string)evData[(byte)0]; int serverTime = (int)evData[(byte)6]; int instantiationId = (int)evData[(byte)7]; Vector3 position; if (evData.ContainsKey((byte)1)) { position = (Vector3)evData[(byte)1]; } else { position = Vector3.zero; } Quaternion rotation = Quaternion.identity; if (evData.ContainsKey((byte)2)) { rotation = (Quaternion)evData[(byte)2]; } int group = 0; if (evData.ContainsKey((byte)3)) { group = (int)evData[(byte)3]; } short objLevelPrefix = 0; if (evData.ContainsKey((byte)8)) { objLevelPrefix = (short)evData[(byte)8]; } int[] viewsIDs; if (evData.ContainsKey((byte)4)) { viewsIDs = (int[])evData[(byte)4]; } else { viewsIDs = new int[1] { instantiationId }; } object[] incomingInstantiationData; if (evData.ContainsKey((byte)5)) { incomingInstantiationData = (object[])evData[(byte)5]; } else { incomingInstantiationData = null; } // SetReceiving filtering if (group != 0 && !this.allowedReceivingGroups.Contains(group)) { return null; // Ignore group } // load prefab, if it wasn't loaded before (calling methods might do this) if (resourceGameObject == null) { if (!NetworkingPeer.UsePrefabCache || !NetworkingPeer.PrefabCache.TryGetValue(prefabName, out resourceGameObject)) { resourceGameObject = (GameObject)Resources.Load(prefabName, typeof(GameObject)); if (NetworkingPeer.UsePrefabCache) { NetworkingPeer.PrefabCache.Add(prefabName, resourceGameObject); } } if (resourceGameObject == null) { Debug.LogError("PhotonNetwork error: Could not Instantiate the prefab [" + prefabName + "]. Please verify you have this gameobject in a Resources folder."); return null; } } // now modify the loaded "blueprint" object before it becomes a part of the scene (by instantiating it) PhotonView[] resourcePVs = resourceGameObject.GetPhotonViewsInChildren(); if (resourcePVs.Length != viewsIDs.Length) { throw new Exception("Error in Instantiation! The resource's PhotonView count is not the same as in incoming data."); } for (int i = 0; i < viewsIDs.Length; i++) { // NOTE instantiating the loaded resource will keep the viewID but would not copy instantiation data, so it's set below // so we only set the viewID and instantiationId now. the instantiationData can be fetched resourcePVs[i].viewID = viewsIDs[i]; resourcePVs[i].prefix = objLevelPrefix; resourcePVs[i].instantiationId = instantiationId; } this.StoreInstantiationData(instantiationId, incomingInstantiationData); // load the resource and set it's values before instantiating it: GameObject go = (GameObject)GameObject.Instantiate(resourceGameObject, position, rotation); for (int i = 0; i < viewsIDs.Length; i++) { // NOTE instantiating the loaded resource will keep the viewID but would not copy instantiation data, so it's set below // so we only set the viewID and instantiationId now. the instantiationData can be fetched resourcePVs[i].viewID = 0; resourcePVs[i].prefix = -1; resourcePVs[i].prefixBackup = -1; resourcePVs[i].instantiationId = -1; } this.RemoveInstantiationData(instantiationId); // Send OnPhotonInstantiate callback to newly created GO. // GO will be enabled when instantiated from Prefab and it does not matter if the script is enabled or disabled. go.SendMessage(PhotonNetworkingMessage.OnPhotonInstantiate.ToString(), new PhotonMessageInfo(photonPlayer, serverTime, null), SendMessageOptions.DontRequireReceiver); return go; }
// PHOTONVIEW/RPC related /// <summary> /// Executes a received RPC event /// </summary> public void ExecuteRPC(Hashtable rpcData, PhotonPlayer sender) { if (rpcData == null || !rpcData.ContainsKey((byte)0)) { Debug.LogError("Malformed RPC; this should never occur. Content: " + SupportClass.DictionaryToString(rpcData)); return; } // ts: updated with "flat" event data int netViewID = (int)rpcData[(byte)0]; // LIMITS PHOTONVIEWS&PLAYERS int otherSidePrefix = 0; // by default, the prefix is 0 (and this is not being sent) if (rpcData.ContainsKey((byte)1)) { otherSidePrefix = (short)rpcData[(byte)1]; } string inMethodName; if (rpcData.ContainsKey((byte)5)) { int rpcIndex = (byte)rpcData[(byte)5]; // LIMITS RPC COUNT if (rpcIndex > PhotonNetwork.PhotonServerSettings.RpcList.Count - 1) { Debug.LogError("Could not find RPC with index: " + rpcIndex + ". Going to ignore! Check PhotonServerSettings.RpcList"); return; } else { inMethodName = PhotonNetwork.PhotonServerSettings.RpcList[rpcIndex]; } } else { inMethodName = (string)rpcData[(byte)3]; } object[] inMethodParameters = null; if (rpcData.ContainsKey((byte)4)) { inMethodParameters = (object[])rpcData[(byte)4]; } if (inMethodParameters == null) { inMethodParameters = new object[0]; } PhotonView photonNetview = this.GetPhotonView(netViewID); if (photonNetview == null) { int viewOwnerId = netViewID/PhotonNetwork.MAX_VIEW_IDS; bool owningPv = (viewOwnerId == this.mLocalActor.ID); bool ownerSent = (viewOwnerId == sender.ID); if (owningPv) { Debug.LogWarning("Received RPC \"" + inMethodName + "\" for viewID " + netViewID + " but this PhotonView does not exist! View was/is ours." + (ownerSent ? " Owner called." : " Remote called.") + " By: " + sender.ID); } else { Debug.LogWarning("Received RPC \"" + inMethodName + "\" for viewID " + netViewID + " but this PhotonView does not exist! Was remote PV." + (ownerSent ? " Owner called." : " Remote called.") + " By: " + sender.ID + " Maybe GO was destroyed but RPC not cleaned up."); } return; } if (photonNetview.prefix != otherSidePrefix) { Debug.LogError( "Received RPC \"" + inMethodName + "\" on viewID " + netViewID + " with a prefix of " + otherSidePrefix + ", our prefix is " + photonNetview.prefix + ". The RPC has been ignored."); return; } // Get method name if (inMethodName == string.Empty) { Debug.LogError("Malformed RPC; this should never occur. Content: " + SupportClass.DictionaryToString(rpcData)); return; } if (PhotonNetwork.logLevel >= PhotonLogLevel.Full) Debug.Log("Received RPC: " + inMethodName); // SetReceiving filtering if (photonNetview.group != 0 && !allowedReceivingGroups.Contains(photonNetview.group)) { return; // Ignore group } Type[] argTypes = new Type[0]; if (inMethodParameters.Length > 0) { argTypes = new Type[inMethodParameters.Length]; int i = 0; for (int index = 0; index < inMethodParameters.Length; index++) { object objX = inMethodParameters[index]; if (objX == null) { argTypes[i] = null; } else { argTypes[i] = objX.GetType(); } i++; } } int receivers = 0; int foundMethods = 0; MonoBehaviour[] mbComponents = photonNetview.GetComponents<MonoBehaviour>(); // NOTE: we could possibly also cache MonoBehaviours per view?! for (int componentsIndex = 0; componentsIndex < mbComponents.Length; componentsIndex++) { MonoBehaviour monob = mbComponents[componentsIndex]; if (monob == null) { Debug.LogError("ERROR You have missing MonoBehaviours on your gameobjects!"); continue; } Type type = monob.GetType(); // Get [RPC] methods from cache List<MethodInfo> cachedRPCMethods = null; if (this.monoRPCMethodsCache.ContainsKey(type)) { cachedRPCMethods = this.monoRPCMethodsCache[type]; } if (cachedRPCMethods == null) { List<MethodInfo> entries = SupportClass.GetMethods(type, typeof(RPC)); this.monoRPCMethodsCache[type] = entries; cachedRPCMethods = entries; } if (cachedRPCMethods == null) { continue; } // Check cache for valid methodname+arguments for (int index = 0; index < cachedRPCMethods.Count; index++) { MethodInfo mInfo = cachedRPCMethods[index]; if (mInfo.Name == inMethodName) { foundMethods++; ParameterInfo[] pArray = mInfo.GetParameters(); if (pArray.Length == argTypes.Length) { // Normal, PhotonNetworkMessage left out if (this.CheckTypeMatch(pArray, argTypes)) { receivers++; object result = mInfo.Invoke((object)monob, inMethodParameters); if (mInfo.ReturnType == typeof(IEnumerator)) { monob.StartCoroutine((IEnumerator)result); } } } else if ((pArray.Length - 1) == argTypes.Length) { // Check for PhotonNetworkMessage being the last if (this.CheckTypeMatch(pArray, argTypes)) { if (pArray[pArray.Length - 1].ParameterType == typeof(PhotonMessageInfo)) { receivers++; int sendTime = (int)rpcData[(byte)2]; object[] deParamsWithInfo = new object[inMethodParameters.Length + 1]; inMethodParameters.CopyTo(deParamsWithInfo, 0); deParamsWithInfo[deParamsWithInfo.Length - 1] = new PhotonMessageInfo(sender, sendTime, photonNetview); object result = mInfo.Invoke((object)monob, deParamsWithInfo); if (mInfo.ReturnType == typeof(IEnumerator)) { monob.StartCoroutine((IEnumerator)result); } } } } else if (pArray.Length == 1 && pArray[0].ParameterType.IsArray) { receivers++; object result = mInfo.Invoke((object)monob, new object[] { inMethodParameters }); if (mInfo.ReturnType == typeof(IEnumerator)) { monob.StartCoroutine((IEnumerator)result); } } } } } // Error handling if (receivers != 1) { string argsString = string.Empty; for (int index = 0; index < argTypes.Length; index++) { Type ty = argTypes[index]; if (argsString != string.Empty) { argsString += ", "; } if (ty == null) { argsString += "null"; } else { argsString += ty.Name; } } if (receivers == 0) { if (foundMethods == 0) { Debug.LogError("PhotonView with ID " + netViewID + " has no method \"" + inMethodName + "\" marked with the [RPC](C#) or @RPC(JS) property! Args: " + argsString); } else { Debug.LogError("PhotonView with ID " + netViewID + " has no method \"" + inMethodName + "\" that takes " + argTypes.Length + " argument(s): " + argsString); } } else { Debug.LogError("PhotonView with ID " + netViewID + " has " + receivers + " methods \"" + inMethodName + "\" that takes " + argTypes.Length + " argument(s): " + argsString + ". Should be just one?"); } } }
/// <summary> /// Caches custom properties for this player. /// </summary> internal void InternalCacheProperties(Hashtable properties) { if (properties == null || properties.Count == 0 || this.customProperties.Equals(properties)) { return; } if (properties.ContainsKey(ActorProperties.PlayerName)) { this.nameField = (string)properties[ActorProperties.PlayerName]; } if (properties.ContainsKey(ActorProperties.IsInactive)) { // TODO: implement isinactive } this.customProperties.MergeStringKeys(properties); this.customProperties.StripKeysWithNullValues(); }
/// <summary>Reads the "custom content" Hashtable that is sent as color update.</summary> /// <returns>Hashtable for event "color" to update others</returns> public void ReadEvColor(Hashtable evContent) { if (evContent.ContainsKey((byte)1)) { this.Color = (int)evContent[(byte)1]; } else if (evContent.ContainsKey("1")) { // js client event support (those can't send with byte-keys) this.Color = System.Convert.ToInt32(evContent["1"]); } this.LastUpdateTimestamp = GameLogic.Timestamp; }
/// <summary>Reads the "custom content" Hashtable that is sent as position update.</summary> /// <returns>Hashtable for event "move" to update others</returns> public void ReadEvMove(Hashtable evContent) { if (evContent.ContainsKey((byte)1)) { byte[] posArray = (byte[])evContent[(byte)1]; this.PosX = posArray[0]; this.PosY = posArray[1]; } else if (evContent.ContainsKey("1")) { // js client event support (those can't send with byte-keys) var posArray = (object[])evContent["1"]; // NOTE: this is subject to change while we update the serialization in JS/Server this.PosX = System.Convert.ToByte(posArray[0]); this.PosY = System.Convert.ToByte(posArray[1]); } this.LastUpdateTimestamp = GameLogic.Timestamp; }
/// <summary>Caches properties for new Players or when updates of remote players are received. Use SetCustomProperties() for a synced update.</summary> /// <remarks> /// This only updates the CustomProperties and doesn't send them to the server. /// Mostly used when creating new remote players, where the server sends their properties. /// </remarks> public virtual void CacheProperties(Hashtable properties) { if (properties == null || properties.Count == 0 || this.CustomProperties.Equals(properties)) { return; } if (properties.ContainsKey(ActorProperties.PlayerName)) { string nameInServersProperties = (string)properties[ActorProperties.PlayerName]; if (nameInServersProperties != null) { if (this.IsLocal) { // the local playername is different than in the properties coming from the server // so the local nickName was changed and the server is outdated -> update server // update property instead of using the outdated nickName coming from server if (!nameInServersProperties.Equals(this.nickName)) { this.SetPlayerNameProperty(); } } else { this.NickName = nameInServersProperties; } } } if (properties.ContainsKey(ActorProperties.IsInactive)) { this.IsInactive = (bool)properties[ActorProperties.IsInactive]; //TURNBASED new well-known propery for players } this.CustomProperties.MergeStringKeys(properties); }
/// <summary> /// Caches custom properties for this player. /// </summary> internal void InternalCacheProperties(Hashtable properties) { if (properties == null || properties.Count == 0 || this.customProperties.Equals(properties)) { return; } if (properties.ContainsKey(ActorProperties.PlayerName)) { this.nameField = (string)properties[ActorProperties.PlayerName]; } if (properties.ContainsKey(ActorProperties.UserId)) { this.userId = (string)properties[ActorProperties.UserId]; } if (properties.ContainsKey(ActorProperties.IsInactive)) { this.isInactive = (bool)properties[ActorProperties.IsInactive]; //TURNBASED new well-known propery for players } this.customProperties.MergeStringKeys(properties); this.customProperties.StripKeysWithNullValues(); }
internal GameObject DoInstantiate(Hashtable evData, PhotonPlayer photonPlayer, GameObject resourceGameObject) { // some values always present: string prefabName = (string)evData[(byte)0]; int serverTime = (int)evData[(byte)6]; int instantiationId = (int)evData[(byte)7]; Vector3 position; if (evData.ContainsKey((byte)1)) { position = (Vector3)evData[(byte)1]; } else { position = Vector3.zero; } Quaternion rotation = Quaternion.identity; if (evData.ContainsKey((byte)2)) { rotation = (Quaternion)evData[(byte)2]; } int group = 0; if (evData.ContainsKey((byte)3)) { group = (int)evData[(byte)3]; } short objLevelPrefix = 0; if (evData.ContainsKey((byte)8)) { objLevelPrefix = (short)evData[(byte)8]; } int[] viewsIDs; if (evData.ContainsKey((byte)4)) { viewsIDs = (int[])evData[(byte)4]; } else { viewsIDs = new int[1] { instantiationId }; } object[] incomingInstantiationData; if (evData.ContainsKey((byte)5)) { incomingInstantiationData = (object[])evData[(byte)5]; } else { incomingInstantiationData = null; } // SetReceiving filtering if (group != 0 && !this.allowedReceivingGroups.Contains(group)) { return null; // Ignore group } // load prefab, if it wasn't loaded before (calling methods might do this) if (resourceGameObject == null) { if (!NetworkingPeer.UsePrefabCache || !NetworkingPeer.PrefabCache.TryGetValue(prefabName, out resourceGameObject)) { resourceGameObject = (GameObject)Resources.Load(prefabName, typeof(GameObject)); if (NetworkingPeer.UsePrefabCache) { NetworkingPeer.PrefabCache.Add(prefabName, resourceGameObject); } } if (resourceGameObject == null) { Debug.LogError("PhotonNetwork error: Could not Instantiate the prefab [" + prefabName + "]. Please verify you have this gameobject in a Resources folder."); return null; } } // now modify the loaded "blueprint" object before it becomes a part of the scene (by instantiating it) PhotonView[] resourcePVs = resourceGameObject.GetPhotonViewsInChildren(); if (resourcePVs.Length != viewsIDs.Length) { throw new Exception("Error in Instantiation! The resource's PhotonView count is not the same as in incoming data."); } for (int i = 0; i < viewsIDs.Length; i++) { // NOTE instantiating the loaded resource will keep the viewID but would not copy instantiation data, so it's set below // so we only set the viewID and instantiationId now. the instantiationData can be fetched resourcePVs[i].viewID = viewsIDs[i]; resourcePVs[i].prefix = objLevelPrefix; resourcePVs[i].instantiationId = instantiationId; } this.StoreInstantiationData(instantiationId, incomingInstantiationData); // load the resource and set it's values before instantiating it: GameObject go = (GameObject)GameObject.Instantiate(resourceGameObject, position, rotation); for (int i = 0; i < viewsIDs.Length; i++) { // NOTE instantiating the loaded resource will keep the viewID but would not copy instantiation data, so it's set below // so we only set the viewID and instantiationId now. the instantiationData can be fetched resourcePVs[i].viewID = 0; resourcePVs[i].prefix = -1; resourcePVs[i].prefixBackup = -1; resourcePVs[i].instantiationId = -1; } this.RemoveInstantiationData(instantiationId); //TODO: remove this debug check if (this.instantiatedObjects.ContainsKey(instantiationId)) { GameObject knownGo = this.instantiatedObjects[instantiationId]; string pvaInfo = ""; PhotonView[] pva; if (knownGo != null) { pva = knownGo.GetPhotonViewsInChildren(); foreach (PhotonView view in pva) { if (view == null) continue; pvaInfo += view.ToString() + ", "; } } Debug.LogError(string.Format("DoInstantiate re-defines a GameObject. Destroying old entry! New: '{0}' (instantiationID: {1}) Old: {3}. PhotonViews on old: {4}. instantiatedObjects.Count: {2}. PhotonNetwork.lastUsedViewSubId: {5} PhotonNetwork.lastUsedViewSubIdStatic: {6} this.photonViewList.Count {7}.)", go, instantiationId, this.instantiatedObjects.Count, knownGo, pvaInfo, PhotonNetwork.lastUsedViewSubId, PhotonNetwork.lastUsedViewSubIdStatic, this.photonViewList.Count)); //this.instantiatedObjects.Remove(instantiationId); // TODO: check if simple remove is ok in all cases. Maybe better Destroy!? this.RemoveInstantiatedGO(knownGo, true); } this.instantiatedObjects.Add(instantiationId, go); //TODO check if instantiatedObjects is (still) needed // Send mono event // TOD move this callback and script-caching into a method! there should be one already... object[] messageInfoParam = new object[1]; messageInfoParam[0] = new PhotonMessageInfo(photonPlayer, serverTime, null); MonoBehaviour[] monos = go.GetComponentsInChildren<MonoBehaviour>(); for (int index = 0; index < monos.Length; index++) { MonoBehaviour mono = monos[index]; MethodInfo methodI; if (NetworkingPeer.GetMethod(mono, PhotonNetworkingMessage.OnPhotonInstantiate.ToString(), out methodI)) { object result = methodI.Invoke((object)mono, messageInfoParam); if (methodI.ReturnType == typeof(System.Collections.IEnumerator)) { mono.StartCoroutine((IEnumerator)result); } } } return go; }