/// <summary> /// Se encapsula el metodo RaiseEvent /// </summary> /// <param name="eventosJuego"></param> /// <param name="param"></param> /// <param name="target"></param> public static void LevantarEventos(CodigoEventosJuego eventosJuego, object param, ReceiverGroup target) { RaiseEventOptions raiseEventOptions = new RaiseEventOptions { Receivers = target }; SendOptions sendOptions = new SendOptions { Reliability = true }; PhotonNetwork.RaiseEvent((byte)eventosJuego, param, raiseEventOptions, sendOptions); }
public static void SendChangeLiveEvent(int i) { RaiseEventOptions raiseEventOptions = new RaiseEventOptions { Receivers = ReceiverGroup.Others }; SendOptions sendOptions = new SendOptions { Reliability = true }; PhotonNetwork.RaiseEvent(RemoteEventsNames.LiveChange, i, raiseEventOptions, sendOptions); }
public void SendFriendlyBattleChallenge(BattleType battleType) { byte evCode = (byte)PUNFriendlyBattleEvents.CHALLENGE_SEND; byte[] content = new byte[] { (byte)battleType }; bool reliable = true; RaiseEventOptions options = new RaiseEventOptions(); options.Receivers = ReceiverGroup.All; PhotonNetwork.RaiseEvent(evCode, content, reliable, options); }
private void RaiseEvent(object content, EventCode evCode, ReceiverGroup recGroup) { RaiseEventOptions raiseEventOptions = new RaiseEventOptions { Receivers = recGroup }; SendOptions sendOptions = new SendOptions { Reliability = true }; PhotonNetwork.RaiseEvent((byte)evCode, content, raiseEventOptions, sendOptions); }
/// <summary> /// Send a message to all clients using Photon /// </summary> /// <param name="msgType">Type of message. This specifies /// the type of the payload. This is important in /// networked scenarios, when proper deseriaization into /// the correct type requires knowing what was /// used to serialize the object originally. /// </param> /// <param name="msg">The message to send.</param> public override void MmSendMessageToClient(MmMessage msg) { byte eventCode = (byte)(1); object[] data = msg.Serialize(); RaiseEventOptions raiseEventOptions = new RaiseEventOptions { Receivers = ReceiverGroup.All }; PhotonNetwork.RaiseEvent(eventCode, data, raiseEventOptions, SendOptions.SendReliable); }
void GettingLevel(int tp_int, string tp_string, int id) { string datastring = ""; // WWWForm form = new WWWForm (); // form.AddField ("sql_text_post", "SELECT * FROM level WHERE level_id=" + tp_int + ";"); // form.AddField ("mode_post", tp_string + ""); // WWW data = new WWW ("https://localhost/RPG/GetLevel.php", form); // yield return data; // datastring = data.text; switch (tp_string) { case "common": datastring = data.Levels [tp_int - 1].CommonCount + "|" + data.Levels [tp_int - 1].CommonMobs; break; case "rare": datastring = data.Levels [tp_int - 1].RareCount + "|" + data.Levels [tp_int - 1].RareMobs; break; case "elite": datastring = data.Levels [tp_int - 1].EliteCount + "|" + data.Levels [tp_int - 1].EliteMobs; break; case "legendary": datastring = data.Levels [tp_int - 1].LegendaryCount + "|" + data.Levels [tp_int - 1].LegendaryMobs; break; default: datastring = "Error in Level"; break; } string[] array = datastring.Split("|" [0]); string[] min_max = array [0].Split("-" [0]); int[] MinMax = new int[min_max.Length]; for (int i = 0; i < min_max.Length; i++) { MinMax [i] = int.Parse(min_max [i]); } string[] enemy_characters = array [1].Split("/" [0]); int[] EnemyIDs = new int[enemy_characters.Length]; for (int i = 0; i < enemy_characters.Length; i++) { EnemyIDs [i] = int.Parse(enemy_characters [i]); } RaiseEventOptions opt = new RaiseEventOptions(); opt.TargetActors = ServerStorage.Sv_Storage.B_Storages[id].GroupIds; PhotonNetwork.RaiseEvent(50, "", true, opt); EstimateEnemies(id, MinMax, EnemyIDs); }
public void BumGame() { string[] message = new string[2]; message[0] = PhotonNetwork.NickName; message[1] = "BumGame"; RaiseEventOptions eventOptions = new RaiseEventOptions { Receivers = ReceiverGroup.All }; PhotonNetwork.RaiseEvent(GameOverEventCode, message, eventOptions, SendOptions.SendReliable); }
//Deals 5 cards to every player in the game on game start. //Works recursively with HandlePhotonEvents to ensure players take their cards in order public void DealStartCards() { if (PhotonNetwork.IsMasterClient && view.IsMine && players.Count != 0) { int content = players.Pop().GetComponent <PhotonView>().ViewID; RaiseEventOptions eventOptions = new RaiseEventOptions { Receivers = ReceiverGroup.All }; PhotonNetwork.RaiseEvent(DrawStartCardsEventCode, content, eventOptions, SendOptions.SendReliable); } }
public void SendLoadNextMazeLevelEvent(string levelName) { object[] content = new object[] { levelName }; RaiseEventOptions raiseEventOptions = new RaiseEventOptions { Receivers = ReceiverGroup.All }; PhotonNetwork.RaiseEvent(LoadNextMazeLevelEventCode, content, raiseEventOptions, SendOptions.SendReliable); Logger.Log("SendLoadNextMazeLevelEvent"); }
public void SendOnTradeOffer(string senderNickName, string[] senderBuildingNames, float senderMoney, string receiverNickName, string[] receiverBuildingNames, float receiverMoney) { object[] data = { senderNickName, senderBuildingNames, senderMoney, receiverNickName, receiverBuildingNames, receiverMoney }; RaiseEventOptions raiseOptions = new RaiseEventOptions { Receivers = ReceiverGroup.Others }; SendOptions sendOptions = new SendOptions { Reliability = true }; PhotonNetwork.RaiseEvent((byte)EventsId.TradeOffer, data, raiseOptions, sendOptions); }
public void SendOnMasterStartedGame() { object[] data = {}; RaiseEventOptions raiseOptions = new RaiseEventOptions { Receivers = ReceiverGroup.Others }; SendOptions sendOptions = new SendOptions { Reliability = true }; PhotonNetwork.RaiseEvent((byte)EventsId.MasterStartedGame, data, raiseOptions, sendOptions); }
public void SendOnTradeOfferResponse(bool accepted, string senderNickName, string receiverNickName) { object[] data = { accepted, senderNickName, receiverNickName }; RaiseEventOptions raiseOptions = new RaiseEventOptions { Receivers = ReceiverGroup.Others }; SendOptions sendOptions = new SendOptions { Reliability = true }; PhotonNetwork.RaiseEvent((byte)EventsId.TradeResponse, data, raiseOptions, sendOptions); }
/// <summary> /// Wywyła przez sieć informację służące do synchronizacji /// </summary> /// <param name="syncNumber">Numer synchronizacj. 0 - wysyłamy zapytanie o synchronizację, 1 - odpowiadamy na zapytanie o synchronizację</param> /// <param name="source">Nazwa gracza, który wysyła event</param> /// <param name="target">Nazwa gracza, do którego jest wysyłany event</param> public void SendSyncEvent(int syncNumber, string source, string target, int syncCommand) { object[] data = { syncNumber, source, target, syncCommand }; RaiseEventOptions raiseOptions = new RaiseEventOptions { Receivers = ReceiverGroup.Others }; SendOptions sendOptions = new SendOptions { Reliability = true }; PhotonNetwork.RaiseEvent((byte)EventsId.Sync, data, raiseOptions, sendOptions); }
private void onEndTurn(List <MoveRequest> moveList) { EndTurnRequestEvent endTurnRequest = EndTurnRequestEvent.Create(PhotonNetwork.player.ID, moveList); RaiseEventOptions options = new RaiseEventOptions(); options.Receivers = ReceiverGroup.MasterClient; string requestJson = JsonUtility.ToJson(endTurnRequest); PhotonNetwork.RaiseEvent(NetworkOpCodes.PLAYER_TURN_COMPLETED, requestJson, true, options); }
public void GameEnded(string Team)//모두에게 진팀 보내주기 { byte evcode = 151; object[] datas = new object[] { (string)Team }; RaiseEventOptions op = new RaiseEventOptions { Receivers = ReceiverGroup.All }; PhotonNetwork.RaiseEvent(evcode, datas, true, op); PhotonNetwork.SendOutgoingCommands(); }
void Send(int second) { byte evCode = 0; //事件分組 可用0~200 bool reliable = true; //傳輸事件是否確保正確傳輸給其他人 // RaiseEventOptions options = null; //事件一些選項 例如傳輸的對象,是否快取等。 RaiseEventOptions options = new RaiseEventOptions { Receivers = ReceiverGroup.All }; PhotonNetwork.RaiseEvent(evCode, second, reliable, options);//所有人做傳輸 }
/// <summary> /// Wysyła przez sieć informację o dokonaniu tranzakcji między graczami /// </summary> /// <param name="payerName">Gracz, który przekazywał pieniądze</param> /// <param name="receiverName">Gracz, który otrzymał pieniądze</param> /// <param name="amount">Ilość wymienianych pieniędzy</param> public void SendPayEvent(string payerName, string receiverName, float amount) { object[] data = { payerName, receiverName, amount }; RaiseEventOptions raiseOptions = new RaiseEventOptions { Receivers = ReceiverGroup.All }; SendOptions sendOptions = new SendOptions { Reliability = true }; PhotonNetwork.RaiseEvent((byte)EventsId.Pay, data, raiseOptions, sendOptions); }
/// <summary> /// Wywyła przez sieć informację o ulepszeniu budynku przez gracza /// </summary> /// <param name="playerName">Nazwa gracza, który ulepszył budynek</param> /// <param name="placeId">Numer pola na planszy, które zostało ulepszone</param> public void SendOnPlayerUpgradedBuilding(string playerName, int placeId) { object[] data = { playerName, placeId }; RaiseEventOptions raiseOptions = new RaiseEventOptions { Receivers = ReceiverGroup.All }; SendOptions sendOptions = new SendOptions { Reliability = true }; PhotonNetwork.RaiseEvent((byte)EventsId.PlayerUpgradeBuilding, data, raiseOptions, sendOptions); }
public void RequestCards(int[] request) { Assert.IsTrue(request.Length == 2); RaiseEventOptions options = new RaiseEventOptions { Receivers = ReceiverGroup.MasterClient }; // We pack the requesttype as one of the parameters PhotonNetwork.RaiseEvent(EventCodes.R_BEGIN_TURN_DRAW_CARDS, request, true, options); }
private void SendPING_Myteam(string name, Vector3 pos) // 레이즈이벤트. 핑 프리팹 이름, 월드 좌표, 샌더챔피언 이름, 샌더의 포지션 { byte evCode = MyEventGroup; object[] content = new object[] { name, pos, SenderName, Player.transform.position }; RaiseEventOptions raiseEventOptions = new RaiseEventOptions { CachingOption = EventCaching.DoNotCache, Receivers = ReceiverGroup.All }; PhotonNetwork.RaiseEvent(evCode, content, false, raiseEventOptions); }
public void Press() { byte evCode = 0; // my event 0. could be used as "group units" byte[] content = new byte[] { 1, 2, 5, 10 }; // e.g. selected unity 1,2,5 and 10 bool reliable = true; RaiseEventOptions options = new RaiseEventOptions(); options.Receivers = ReceiverGroup.Others; PhotonNetwork.RaiseEvent(evCode, content, reliable, options); }
private IEnumerator GameStart() { yield return(new WaitForSeconds(1f)); byte startGameEvent = DuelDataManager.Instance.onGameStartEvent; RaiseEventOptions options = new RaiseEventOptions() { Receivers = ReceiverGroup.All }; PhotonNetwork.RaiseEvent(startGameEvent, null, options, SendOptions.SendReliable); }
/// <summary> /// Wysyła event o poruszeniu się gracza /// </summary> /// <param name="playerName">Nazwa gracza</param> /// <param name="fromPlaceIndex">Numer pola, z którego poruszył się gracz</param> /// <param name="toPlaceIndex">Numer pola, na które poruszył się gracz</param> public void SendOnPlayerTeleported(string playerName, int fromPlaceIndex, int toPlaceIndex) { object[] data = { playerName, fromPlaceIndex, toPlaceIndex }; RaiseEventOptions raiseOptions = new RaiseEventOptions { Receivers = ReceiverGroup.All }; SendOptions sendOptions = new SendOptions { Reliability = true }; PhotonNetwork.RaiseEvent((byte)EventsId.PlayerTeleport, data, raiseOptions, sendOptions); }
public void SendOnPlayerMoneyChanged(string playerName) { object[] data = { playerName }; RaiseEventOptions raiseOptions = new RaiseEventOptions { Receivers = ReceiverGroup.All }; SendOptions sendOptions = new SendOptions { Reliability = true }; PhotonNetwork.RaiseEvent((byte)EventsId.PlayerMoneyChanged, data, raiseOptions, sendOptions); }
/// <summary> /// Wysyła event o zmianie gotowości gracza /// </summary> /// <param name="playerName">Nazwa gracza</param> public void SendOnPlayerReady(string playerName, bool ready) { object[] data = { playerName, ready }; RaiseEventOptions raiseOptions = new RaiseEventOptions { Receivers = ReceiverGroup.All }; SendOptions sendOptions = new SendOptions { Reliability = true }; PhotonNetwork.RaiseEvent((byte)EventsId.PlayerReady, data, raiseOptions, sendOptions); }
/// <summary> /// Wysyła przez sieć event zmiany tury /// </summary> /// <param name="previousPlayerName">Nazwa gracza, którego tura właśnie się zakończyła</param> /// <param name="currentPlayerName">Nazwa gracza, którego tura właśnie się zaczyna</param> public void SendOnTurnChanged(string previousPlayerName, string currentPlayerName) { object[] data = { previousPlayerName, currentPlayerName }; RaiseEventOptions raiseOptions = new RaiseEventOptions { Receivers = ReceiverGroup.All }; SendOptions sendOptions = new SendOptions { Reliability = true }; PhotonNetwork.RaiseEvent((byte)EventsId.TurnChange, data, raiseOptions, sendOptions); }
//Informs all other spawnables that this has been despawned, then destroys itself public void Despawn() { Vector2 data = new Vector2(targetLocation.x, targetLocation.y); object content = (object)data; RaiseEventOptions options = new RaiseEventOptions { Receivers = ReceiverGroup.Others }; PhotonNetwork.RaiseEvent((byte)EventCodes.SpawnableDespawned, content, options, SendOptions.SendReliable); Destroy(gameObject); }
/// <summary> /// Wysyła przez sieć informacje o licytacji /// </summary> /// <param name="playerName">Nazwa gracza, który wywołał licytację</param> /// <param name="placeId">Numer pola na planszy, o które toczy się licytacja</param> /// <param name="bidder">Nazwa gracza, który ostatni wylicytował</param> /// <param name="bid">Kwota ostatniej licytacji</param> public void SendOnAuction(string playerName, int placeId, string bidder, float bid, string passPlayerName) { object[] data = { playerName, placeId, bidder, bid, passPlayerName }; RaiseEventOptions raiseOptions = new RaiseEventOptions { Receivers = ReceiverGroup.All }; SendOptions sendOptions = new SendOptions { Reliability = true }; PhotonNetwork.RaiseEvent((byte)EventsId.Auction, data, raiseOptions, sendOptions); }
public void SendUpdateGameModeEvent(GameMode gameMode) { Logger.Log("SendUpdateGameModeEvent with game mode " + gameMode.ToString()); object[] content = new object[] { gameMode.ToString() }; RaiseEventOptions raiseEventOptions = new RaiseEventOptions { Receivers = ReceiverGroup.All }; PhotonNetwork.RaiseEvent(UpdateGameModeEventCode, content, raiseEventOptions, SendOptions.SendReliable); }
/// <summary> /// Wysyła event o zmianie stanu gry w klasie GameplayController /// </summary> /// <param name="previousState">Stan gry przed zmianą</param> /// <param name="newState">Stan gry po zmianie, obecny</param> public void SendOnGameStateChanged(GameState previousState, GameState newState) { object[] data = { previousState, newState }; RaiseEventOptions raiseOptions = new RaiseEventOptions { Receivers = ReceiverGroup.All }; SendOptions sendOptions = new SendOptions { Reliability = true }; PhotonNetwork.RaiseEvent((byte)EventsId.GameStateChange, data, raiseOptions, sendOptions); }
internal void RPC(PhotonView view, string methodName, PhotonPlayer player, params object[] parameters) { if (this.blockSendingGroups.Contains(view.group)) { return; // Block sending on this group } if (view.viewID < 1) //TODO: check why 0 should be illegal { Debug.LogError("Illegal view ID:" + view.viewID + " method: " + methodName + " GO:" + view.gameObject.name); } if (PhotonNetwork.logLevel >= PhotonLogLevel.Full) Debug.Log("Sending RPC \"" + methodName + "\" to player[" + player + "]"); //ts: changed RPCs to a one-level hashtable as described in internal.txt Hashtable rpcEvent = new Hashtable(); rpcEvent[(byte)0] = (int)view.viewID; // LIMITS PHOTONVIEWS&PLAYERS if (view.prefix > 0) { rpcEvent[(byte)1] = (short)view.prefix; } rpcEvent[(byte)2] = this.ServerTimeInMilliSeconds; // send name or shortcut (if available) int shortcut = 0; if (rpcShortcuts.TryGetValue(methodName, out shortcut)) { rpcEvent[(byte)5] = (byte)shortcut; // LIMITS RPC COUNT } else { rpcEvent[(byte)3] = methodName; } if (parameters != null && parameters.Length > 0) { rpcEvent[(byte) 4] = (object[]) parameters; } if (this.mLocalActor == player) { this.ExecuteRPC(rpcEvent, player); } else { RaiseEventOptions options = new RaiseEventOptions() { TargetActors = new int[] { player.ID } }; this.OpRaiseEvent(PunEvent.RPC, rpcEvent, true, options); //int[] targetActors = new int[] { player.ID }; //this.OpRaiseEvent(PunEvent.RPC, rpcEvent, true, 0, targetActors); } }
/// <summary>Cleans server RPCs for PhotonView (without any further checks).</summary> public void OpCleanRpcBuffer(PhotonView view) { Hashtable rpcFilterByViewId = new Hashtable(); rpcFilterByViewId[(byte)0] = view.viewID; RaiseEventOptions options = new RaiseEventOptions() { CachingOption = EventCaching.RemoveFromRoomCache }; this.OpRaiseEvent(PunEvent.RPC, rpcFilterByViewId, true, options); //this.OpRaiseEvent(PunEvent.RPC, rpcFilterByViewId, true, 0, EventCaching.RemoveFromRoomCache, ReceiverGroup.Others); }
public void OpRemoveCompleteCache() { RaiseEventOptions options = new RaiseEventOptions() { CachingOption = EventCaching.RemoveFromRoomCache, Receivers = ReceiverGroup.MasterClient }; this.OpRaiseEvent(0, null, true, options); //this.OpRaiseEvent(0, null, true, 0, EventCaching.RemoveFromRoomCache, ReceiverGroup.MasterClient); // TODO: check who gets this event? }
/// <summary> /// Instead removing RPCs or Instantiates, this removed everything cached by the actor. /// </summary> /// <param name="actorNumber"></param> public void OpRemoveCompleteCacheOfPlayer(int actorNumber) { RaiseEventOptions options = new RaiseEventOptions() { CachingOption = EventCaching.RemoveFromRoomCache, TargetActors = new int[] { actorNumber } }; this.OpRaiseEvent(0, null, true, options); //this.OpRaiseEvent(0, null, true, 0, new int[] { actorNumber }, EventCaching.RemoveFromRoomCache); }
/// <summary> /// Send an event with custom code/type and any content to the other players in the same room. /// </summary> /// <remarks>This override explicitly uses another parameter order to not mix it up with the implementation for Hashtable only.</remarks> /// <param name="eventCode">Identifies this type of event (and the content). Your game's event codes can start with 0.</param> /// <param name="customEventContent">Any serializable datatype (including Hashtable like the other OpRaiseEvent overloads).</param> /// <param name="sendReliable">If this event has to arrive reliably (potentially repeated if it's lost).</param> /// <param name="raiseEventOptions">Contains (slightly) less often used options. If you pass null, the default options will be used.</param> /// <returns>If operation could be enqueued for sending. Sent when calling: Service or SendOutgoingCommands.</returns> public virtual bool OpRaiseEvent(byte eventCode, object customEventContent, bool sendReliable, RaiseEventOptions raiseEventOptions) { Dictionary<byte, object> opParameters = new Dictionary<byte, object>(); opParameters[(byte)LiteOpKey.Code] = (byte)eventCode; if (customEventContent != null) { opParameters[(byte) LiteOpKey.Data] = customEventContent; } if (raiseEventOptions == null) { raiseEventOptions = RaiseEventOptions.Default; } else { if (raiseEventOptions.CachingOption != EventCaching.DoNotCache) { opParameters[(byte) LiteOpKey.Cache] = (byte) raiseEventOptions.CachingOption; } if (raiseEventOptions.Receivers != ReceiverGroup.Others) { opParameters[(byte) LiteOpKey.ReceiverGroup] = (byte) raiseEventOptions.Receivers; } if (raiseEventOptions.InterestGroup != 0) { opParameters[(byte) LiteOpKey.Group] = (byte) raiseEventOptions.InterestGroup; } if (raiseEventOptions.TargetActors != null) { opParameters[(byte) LiteOpKey.ActorList] = raiseEventOptions.TargetActors; } if (raiseEventOptions.ForwardToWebhook) { opParameters[(byte) ParameterCode.EventForward] = true; //TURNBASED } } return this.OpCustom((byte)LiteOpCode.RaiseEvent, opParameters, sendReliable, raiseEventOptions.SequenceChannel, false); }
public override bool OpRaiseEvent(byte eventCode, object customEventContent, bool sendReliable, RaiseEventOptions raiseEventOptions) { if (PhotonNetwork.offlineMode) { return false; } return base.OpRaiseEvent(eventCode, customEventContent, sendReliable, raiseEventOptions); }
/// <summary>Request a client to disconnect (KICK). Only the master client can do this</summary> /// <remarks>Only the target player gets this event. That player will disconnect automatically, which is what the others will notice, too.</remarks> /// <param name="kickPlayer">The PhotonPlayer to kick.</param> public static bool CloseConnection(PhotonPlayer kickPlayer) { if (!VerifyCanUseNetwork()) { return false; } if (!player.isMasterClient) { Debug.LogError("CloseConnection: Only the masterclient can kick another player."); return false; } if (kickPlayer == null) { Debug.LogError("CloseConnection: No such player connected!"); return false; } RaiseEventOptions options = new RaiseEventOptions() { TargetActors = new int[] { kickPlayer.ID } }; return networkingPeer.OpRaiseEvent(PunEvent.CloseConnection, null, true, options); }
/// <summary> /// Removes an instantiation event from the server's cache. Needs id and actorNr of player who instantiated. /// </summary> private void ServerCleanInstantiateAndDestroy(int instantiateId, int creatorId, bool isRuntimeInstantiated) { PhotonView view = GetPhotonView(instantiateId); Hashtable removeFilter = new Hashtable(); removeFilter[(byte)7] = instantiateId; RaiseEventOptions options = new RaiseEventOptions() { CachingOption = EventCaching.RemoveFromRoomCache, TargetActors = new int[] { creatorId } }; this.OpRaiseEvent(PunEvent.Create, removeFilter, true, options); //this.OpRaiseEvent(PunEvent.Instantiation, removeFilter, true, 0, new int[] { actorNr }, EventCaching.RemoveFromRoomCache); Hashtable evData = new Hashtable(); evData[(byte) 0] = (short)view.prefix; evData[(byte)1] = new [] {instantiateId}; options = null; if (!isRuntimeInstantiated) { // if the view got loaded with the scene, the EvDestroy must be cached (there is no Instantiate-msg which we can remove) // reason: joining players will load the obj and have to destroy it (too) options = new RaiseEventOptions(); options.CachingOption = EventCaching.AddToRoomCacheGlobal; Debug.Log("Destroying GO as global. ID: " + instantiateId); } this.OpRaiseEvent(PunEvent.Destroy, evData, true, options); }
/// RPC Hashtable Structure /// (byte)0 -> (int) ViewId (combined from actorNr and actor-unique-id) /// (byte)1 -> (short) prefix (level) /// (byte)2 -> (int) server timestamp /// (byte)3 -> (string) methodname /// (byte)4 -> (object[]) parameters /// (byte)5 -> (byte) method shortcut (alternative to name) /// /// This is sent as event (code: 200) which will contain a sender (origin of this RPC). internal void RPC(PhotonView view, string methodName, PhotonTargets target, params object[] parameters) { if (this.blockSendingGroups.Contains(view.group)) { return; // Block sending on this group } if (view.viewID < 1) { Debug.LogError("Illegal view ID:" + view.viewID + " method: " + methodName + " GO:" + view.gameObject.name); } if (PhotonNetwork.logLevel >= PhotonLogLevel.Full) Debug.Log("Sending RPC \"" + methodName + "\" to " + target); //ts: changed RPCs to a one-level hashtable as described in internal.txt Hashtable rpcEvent = new Hashtable(); rpcEvent[(byte)0] = (int)view.viewID; // LIMITS NETWORKVIEWS&PLAYERS if (view.prefix > 0) { rpcEvent[(byte)1] = (short)view.prefix; } rpcEvent[(byte)2] = this.ServerTimeInMilliSeconds; // send name or shortcut (if available) int shortcut = 0; if (rpcShortcuts.TryGetValue(methodName, out shortcut)) { rpcEvent[(byte)5] = (byte)shortcut; // LIMITS RPC COUNT } else { rpcEvent[(byte)3] = methodName; } if (parameters != null && parameters.Length > 0) { rpcEvent[(byte)4] = (object[])parameters; } // Check scoping if (target == PhotonTargets.All) { RaiseEventOptions options = new RaiseEventOptions() { InterestGroup = (byte)view.group }; this.OpRaiseEvent(PunEvent.RPC, rpcEvent, true, options); //this.OpRaiseEvent(PunEvent.RPC, (byte)view.group, rpcEvent, true, 0); // Execute local this.ExecuteRPC(rpcEvent, this.mLocalActor); } else if (target == PhotonTargets.Others) { RaiseEventOptions options = new RaiseEventOptions() { InterestGroup = (byte)view.group }; this.OpRaiseEvent(PunEvent.RPC, rpcEvent, true, options); } else if (target == PhotonTargets.AllBuffered) { RaiseEventOptions options = new RaiseEventOptions() { CachingOption = EventCaching.AddToRoomCache}; this.OpRaiseEvent(PunEvent.RPC, rpcEvent, true, options); // Execute local this.ExecuteRPC(rpcEvent, this.mLocalActor); } else if (target == PhotonTargets.OthersBuffered) { RaiseEventOptions options = new RaiseEventOptions() { CachingOption = EventCaching.AddToRoomCache }; this.OpRaiseEvent(PunEvent.RPC, rpcEvent, true, options); } else if (target == PhotonTargets.MasterClient) { if (this.mMasterClient == this.mLocalActor) { this.ExecuteRPC(rpcEvent, this.mLocalActor); } else { RaiseEventOptions options = new RaiseEventOptions() { Receivers = ReceiverGroup.MasterClient }; this.OpRaiseEvent(PunEvent.RPC, rpcEvent, true, options); } } else if (target == PhotonTargets.AllViaServer) { RaiseEventOptions options = new RaiseEventOptions() { InterestGroup = (byte)view.group, Receivers = ReceiverGroup.All }; this.OpRaiseEvent(PunEvent.RPC, rpcEvent, true, options); if (PhotonNetwork.offlineMode) { this.ExecuteRPC(rpcEvent, this.mLocalActor); } } else if (target == PhotonTargets.AllBufferedViaServer) { RaiseEventOptions options = new RaiseEventOptions() { InterestGroup = (byte)view.group, Receivers = ReceiverGroup.All, CachingOption = EventCaching.AddToRoomCache }; this.OpRaiseEvent(PunEvent.RPC, rpcEvent, true, options); if (PhotonNetwork.offlineMode) { this.ExecuteRPC(rpcEvent, this.mLocalActor); } } else { Debug.LogError("Unsupported target enum: " + target); } }
// this is called by Update() and in Unity that means it's single threaded. public void RunViewUpdate() { if (!PhotonNetwork.connected || PhotonNetwork.offlineMode) { return; } if (this.mActors == null || #if !PHOTON_DEVELOP this.mActors.Count <= 1 #endif ) { return; // No need to send OnSerialize messages (these are never buffered anyway) } Dictionary<int, Hashtable> dataPerGroupReliable = new Dictionary<int, Hashtable>(); Dictionary<int, Hashtable> dataPerGroupUnreliable = new Dictionary<int, Hashtable>(); /* Format of the data hashtable: * Hasthable dataPergroup* * [(byte)0] = this.ServerTimeInMilliSeconds; * OPTIONAL: [(byte)1] = currentLevelPrefix; * + data */ foreach (KeyValuePair<int, PhotonView> kvp in this.photonViewList) { PhotonView view = kvp.Value; if (view.synchronization != ViewSynchronization.Off) { // Fetch all sending photonViews if (view.isMine) { #if UNITY_2_6_1 || UNITY_2_6 || UNITY_3_0 || UNITY_3_0_0 || UNITY_3_1 || UNITY_3_2 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5 if (!view.gameObject.active) { continue; // Only on actives } #else if (!view.gameObject.activeInHierarchy) { continue; // Only on actives } #endif if (this.blockSendingGroups.Contains(view.group)) { continue; // Block sending on this group } // Run it trough its OnSerialize Hashtable evData = this.OnSerializeWrite(view); if (evData == null) { continue; } if (view.synchronization == ViewSynchronization.ReliableDeltaCompressed || view.mixedModeIsReliable) { if (!evData.ContainsKey((byte)1) && !evData.ContainsKey((byte)2)) { // Everything has been removed by compression, nothing to send } else { if (!dataPerGroupReliable.ContainsKey(view.group)) { dataPerGroupReliable[view.group] = new Hashtable(); dataPerGroupReliable[view.group][(byte)0] = this.ServerTimeInMilliSeconds; if (currentLevelPrefix >= 0) { dataPerGroupReliable[view.group][(byte)1] = this.currentLevelPrefix; } } Hashtable groupHashtable = dataPerGroupReliable[view.group]; groupHashtable.Add((short)groupHashtable.Count, evData); } } else { if (!dataPerGroupUnreliable.ContainsKey(view.group)) { dataPerGroupUnreliable[view.group] = new Hashtable(); dataPerGroupUnreliable[view.group][(byte)0] = this.ServerTimeInMilliSeconds; if (currentLevelPrefix >= 0) { dataPerGroupUnreliable[view.group][(byte)1] = this.currentLevelPrefix; } } Hashtable groupHashtable = dataPerGroupUnreliable[view.group]; groupHashtable.Add((short)groupHashtable.Count, evData); } } else { // Debug.Log(" NO OBS on " + view.name + " " + view.owner); } } else { } } //Send the messages: every group is send in it's own message and unreliable and reliable are split as well RaiseEventOptions options = new RaiseEventOptions(); #if PHOTON_DEVELOP options.Receivers = ReceiverGroup.All; #endif foreach (KeyValuePair<int, Hashtable> kvp in dataPerGroupReliable) { options.InterestGroup = (byte)kvp.Key; this.OpRaiseEvent(PunEvent.SendSerializeReliable, kvp.Value, true, options); //this.OpRaiseEvent(PunEvent.SendSerializeReliable, (byte)kvp.Key, kvp.Value, true, 0); } foreach (KeyValuePair<int, Hashtable> kvp in dataPerGroupUnreliable) { options.InterestGroup = (byte)kvp.Key; this.OpRaiseEvent(PunEvent.SendSerialize, kvp.Value, false, options); //this.OpRaiseEvent(PunEvent.SendSerialize, (byte)kvp.Key, kvp.Value, false, 0); } }
/// RPC Hashtable Structure /// (byte)0 -> (int) ViewId (combined from actorNr and actor-unique-id) /// (byte)1 -> (short) prefix (level) /// (byte)2 -> (int) server timestamp /// (byte)3 -> (string) methodname /// (byte)4 -> (object[]) parameters /// (byte)5 -> (byte) method shortcut (alternative to name) /// /// This is sent as event (code: 200) which will contain a sender (origin of this RPC). internal void RPC(PhotonView view, string methodName, PhotonTargets target, PhotonPlayer player, bool encrypt, params object[] parameters) { if (this.blockSendingGroups.Contains(view.group)) { return; // Block sending on this group } if (view.viewID < 1) { Debug.LogError("Illegal view ID:" + view.viewID + " method: " + methodName + " GO:" + view.gameObject.name); } if (PhotonNetwork.logLevel >= PhotonLogLevel.Full) { Debug.Log("Sending RPC \"" + methodName + "\" to target: " + target + " or player:" + player + "."); } //ts: changed RPCs to a one-level hashtable as described in internal.txt Hashtable rpcEvent = new Hashtable(); rpcEvent[(byte)0] = (int)view.viewID; // LIMITS NETWORKVIEWS&PLAYERS if (view.prefix > 0) { rpcEvent[(byte)1] = (short)view.prefix; } rpcEvent[(byte)2] = PhotonNetwork.ServerTimestamp; // send name or shortcut (if available) int shortcut = 0; if (rpcShortcuts.TryGetValue(methodName, out shortcut)) { rpcEvent[(byte)5] = (byte)shortcut; // LIMITS RPC COUNT } else { rpcEvent[(byte)3] = methodName; } if (parameters != null && parameters.Length > 0) { rpcEvent[(byte)4] = (object[])parameters; } // if sent to target player, this overrides the target if (player != null) { if (this.LocalPlayer.ID == player.ID) { this.ExecuteRpc(rpcEvent, player); } else { RaiseEventOptions options = new RaiseEventOptions() { TargetActors = new int[] { player.ID }, Encrypt = encrypt }; this.OpRaiseEvent(PunEvent.RPC, rpcEvent, true, options); } return; } // send to a specific set of players if (target == PhotonTargets.All) { RaiseEventOptions options = new RaiseEventOptions() { InterestGroup = (byte)view.group, Encrypt = encrypt }; this.OpRaiseEvent(PunEvent.RPC, rpcEvent, true, options); // Execute local this.ExecuteRpc(rpcEvent, this.LocalPlayer); } else if (target == PhotonTargets.Others) { RaiseEventOptions options = new RaiseEventOptions() { InterestGroup = (byte)view.group, Encrypt = encrypt }; this.OpRaiseEvent(PunEvent.RPC, rpcEvent, true, options); } else if (target == PhotonTargets.AllBuffered) { RaiseEventOptions options = new RaiseEventOptions() { CachingOption = EventCaching.AddToRoomCache, Encrypt = encrypt }; this.OpRaiseEvent(PunEvent.RPC, rpcEvent, true, options); // Execute local this.ExecuteRpc(rpcEvent, this.LocalPlayer); } else if (target == PhotonTargets.OthersBuffered) { RaiseEventOptions options = new RaiseEventOptions() { CachingOption = EventCaching.AddToRoomCache, Encrypt = encrypt }; this.OpRaiseEvent(PunEvent.RPC, rpcEvent, true, options); } else if (target == PhotonTargets.MasterClient) { if (this.mMasterClientId == this.LocalPlayer.ID) { this.ExecuteRpc(rpcEvent, this.LocalPlayer); } else { RaiseEventOptions options = new RaiseEventOptions() { Receivers = ReceiverGroup.MasterClient, Encrypt = encrypt }; this.OpRaiseEvent(PunEvent.RPC, rpcEvent, true, options); } } else if (target == PhotonTargets.AllViaServer) { RaiseEventOptions options = new RaiseEventOptions() { InterestGroup = (byte)view.group, Receivers = ReceiverGroup.All, Encrypt = encrypt }; this.OpRaiseEvent(PunEvent.RPC, rpcEvent, true, options); if (PhotonNetwork.offlineMode) { this.ExecuteRpc(rpcEvent, this.LocalPlayer); } } else if (target == PhotonTargets.AllBufferedViaServer) { RaiseEventOptions options = new RaiseEventOptions() { InterestGroup = (byte)view.group, Receivers = ReceiverGroup.All, CachingOption = EventCaching.AddToRoomCache, Encrypt = encrypt }; this.OpRaiseEvent(PunEvent.RPC, rpcEvent, true, options); if (PhotonNetwork.offlineMode) { this.ExecuteRpc(rpcEvent, this.LocalPlayer); } } else { Debug.LogError("Unsupported target enum: " + target); } }
private void OpRemoveFromServerInstantiationsOfPlayer(int actorNr) { // removes all "Instantiation" events of player actorNr. this is not an event for anyone else RaiseEventOptions options = new RaiseEventOptions() { CachingOption = EventCaching.RemoveFromRoomCache, TargetActors = new int[] { actorNr } }; this.OpRaiseEvent(PunEvent.Instantiation, null, true, options); //this.OpRaiseEvent(PunEvent.Instantiation, null, true, 0, new int[] { actorNr }, EventCaching.RemoveFromRoomCache); }
///// <summary> ///// Will remove the view from list of views (by its ID). ///// </summary> //public void RemovePhotonView(PhotonView netView) //{ // if (!Application.isPlaying) // { // this.photonViewList = new Dictionary<int, PhotonView>(); // return; // } // //PhotonView removedView = null; // //this.photonViewList.TryGetValue(netView.viewID, out removedView); // //if (removedView != netView) // //{ // // Debug.LogError("Detected two differing PhotonViews with same viewID: " + netView.viewID); // //} // this.photonViewList.Remove(netView.viewID); // //if (this.DebugOut >= DebugLevel.ALL) // //{ // // this.DebugReturn(DebugLevel.ALL, "Removed PhotonView: " + netView.viewID); // //} //} /// <summary> /// Removes the RPCs of someone else (to be used as master). /// This won't clean any local caches. It just tells the server to forget a player's RPCs and instantiates. /// </summary> /// <param name="actorNumber"></param> public void OpCleanRpcBuffer(int actorNumber) { RaiseEventOptions options = new RaiseEventOptions() { CachingOption = EventCaching.RemoveFromRoomCache, TargetActors = new int[] { actorNumber } }; this.OpRaiseEvent(PunEvent.RPC, null, true, options); //this.OpRaiseEvent(PunEvent.RPC, null, true, 0, new int[] { actorNumber }, EventCaching.RemoveFromRoomCache); }
void LateUpdate() { if (_queuedActions.Count > 0) { Hashtable[] actionsToSend = new Hashtable[_queuedActions.Count]; for (int i=0; i< _queuedActions.Count ; i++) { actionsToSend[i] = _queuedActions[i].Encode(); } RaiseEventOptions options = new RaiseEventOptions(); options.Receivers = ExitGames.Client.Photon.ReceiverGroup.All; PhotonNetwork.RaiseEvent((byte)87, actionsToSend, true, options); _queuedActions.Clear(); } }
/// <summary> /// Removes an instantiation event from the server's cache. Needs id and actorNr of player who instantiated. /// </summary> private void ServerCleanInstantiateAndDestroy(int instantiateId, int actorNr) { Hashtable removeFilter = new Hashtable(); removeFilter[(byte)7] = instantiateId; RaiseEventOptions options = new RaiseEventOptions() { CachingOption = EventCaching.RemoveFromRoomCache, TargetActors = new int[] { actorNr } }; this.OpRaiseEvent(PunEvent.Instantiation, removeFilter, true, options); //this.OpRaiseEvent(PunEvent.Instantiation, removeFilter, true, 0, new int[] { actorNr }, EventCaching.RemoveFromRoomCache); Hashtable evData = new Hashtable(); evData[(byte)0] = instantiateId; this.OpRaiseEvent(PunEvent.Destroy, evData, true, null); }
// this is called by Update() and in Unity that means it's single threaded. public void RunViewUpdate() { if (!PhotonNetwork.connected || PhotonNetwork.offlineMode) { return; } if (this.mActors == null || #if !PHOTON_DEVELOP this.mActors.Count <= 1 #endif ) { return; // No need to send OnSerialize messages (these are never buffered anyway) } //dataPerGroupReliable.Clear(); //dataPerGroupUnreliable.Clear(); /* Format of the data hashtable: * Hasthable dataPergroup* * [(byte)0] = this.ServerTimeInMilliSeconds; * OPTIONAL: [(byte)1] = currentLevelPrefix; * + data */ relevanceCount++; foreach (KeyValuePair<int, PhotonView> kvp in this.photonViewList) { PhotonView view = kvp.Value; if (view.shouldSync && view.isMine && view.HasSpawned) { #if UNITY_2_6_1 || UNITY_2_6 || UNITY_3_0 || UNITY_3_0_0 || UNITY_3_1 || UNITY_3_2 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5 if (!view.gameObject.active) { continue; // Only on actives } #else if (!view.gameObject.activeInHierarchy) { continue; // Only on actives } #endif if (this.blockSendingGroups.Contains(view.group)) { continue; // Block sending on this group } OnSerializeReliableWrite(view, false); OnSerializeUnreliableWrite(view); } } PhotonPlayer[] players = PhotonNetwork.otherPlayers; foreach (KeyValuePair<int, PhotonView> pair in photonViewList) { PhotonView view = pair.Value; foreach (PhotonPlayer player in players) { if (!view.shouldSync || !view.isMine || !view.HasSpawned) continue; if (!view.CheckRelevance(player)) continue; #if UNITY_2_6_1 || UNITY_2_6 || UNITY_3_0 || UNITY_3_0_0 || UNITY_3_1 || UNITY_3_2 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5 if (!view.gameObject.active) { continue; // Only on actives } #else if (!view.gameObject.activeInHierarchy) { continue; // Only on actives } #endif if (this.blockSendingGroups.Contains(view.@group)) { continue; // Block sending on this group } dataPerGroupReliable.Clear(); dataPerGroupUnreliable.Clear(); if (!dataPerGroupReliable.ContainsKey(view.group)) { dataPerGroupReliable[view.group] = new Hashtable(); dataPerGroupReliable[view.group][(byte)0] = this.ServerTimeInMilliSeconds; } Hashtable reliableGroupHashtable = dataPerGroupReliable[view.group]; reliableGroupHashtable.Add((short)reliableGroupHashtable.Count, view.reliableSerializedData); if (!dataPerGroupUnreliable.ContainsKey(view.group)) { dataPerGroupUnreliable[view.group] = new Hashtable(); dataPerGroupUnreliable[view.group][(byte)0] = this.ServerTimeInMilliSeconds; } Hashtable unreliableGroupHashtable = dataPerGroupUnreliable[view.group]; unreliableGroupHashtable.Add((short)unreliableGroupHashtable.Count, view.unreliableSerializedData); //Send the messages: every group is send in it's own message and unreliable and reliable are split as well RaiseEventOptions options = new RaiseEventOptions(); options.TargetActors = new int[] {player.ID}; foreach (KeyValuePair<int, Hashtable> kvp in dataPerGroupReliable) { options.InterestGroup = (byte)kvp.Key; this.OpRaiseEvent(PunEvent.SendSerializeReliable, kvp.Value, true, options); } foreach (KeyValuePair<int, Hashtable> kvp in dataPerGroupUnreliable) { options.InterestGroup = (byte)kvp.Key; this.OpRaiseEvent(PunEvent.SendSerialize, kvp.Value, false, options); } } } }
// this is called by Update() and in Unity that means it's single threaded. public void RunViewUpdate() { if (!PhotonNetwork.connected || PhotonNetwork.offlineMode || this.mActors == null) { return; } // no need to send OnSerialize messages while being alone (these are not buffered anyway) if (this.mActors.Count <= 1) { #if !PHOTON_DEVELOP return; #endif } /* Format of the data hashtable: * Hasthable dataPergroup* * [(byte)0] = PhotonNetwork.ServerTimestamp; * [(byte)1] = currentLevelPrefix; OPTIONAL! * * [(short)10] = data 1 * [(short)11] = data 2 ... */ int countOfUpdatesToSend = 0; foreach (PhotonView view in this.photonViewList.Values) { // a client only sends updates for active, synchronized PhotonViews that are under it's control (isMine) if (view.synchronization == ViewSynchronization.Off || view.isMine == false || view.gameObject.activeInHierarchy == false) { continue; } if (this.blockSendingGroups.Contains(view.group)) { continue; // Block sending on this group } // call the PhotonView's serialize method(s) object[] evData = this.OnSerializeWrite(view); if (evData == null) { continue; } if (view.synchronization == ViewSynchronization.ReliableDeltaCompressed || view.mixedModeIsReliable) { Hashtable groupHashtable = null; bool found = this.dataPerGroupReliable.TryGetValue(view.group, out groupHashtable); if (!found) { groupHashtable = new Hashtable(10); this.dataPerGroupReliable[view.group] = groupHashtable; } groupHashtable.Add((short)(groupHashtable.Count+10), evData); countOfUpdatesToSend++; } else { Hashtable groupHashtable = null; bool found = this.dataPerGroupUnreliable.TryGetValue(view.group, out groupHashtable); if (!found) { groupHashtable = new Hashtable(10); this.dataPerGroupUnreliable[view.group] = groupHashtable; } groupHashtable.Add((short)(groupHashtable.Count+10), evData); countOfUpdatesToSend++; } } // all views serialized // if we didn't produce anything to send, don't do it if (countOfUpdatesToSend == 0) { return; } // we got updates to send. every group is send it's own message and unreliable and reliable are split as well RaiseEventOptions options = new RaiseEventOptions(); #if PHOTON_DEVELOP options.Receivers = ReceiverGroup.All; #endif foreach (int groupId in this.dataPerGroupReliable.Keys) { options.InterestGroup = (byte)groupId; Hashtable groupHashtable = this.dataPerGroupReliable[groupId]; if (groupHashtable.Count == 0) { continue; } groupHashtable[(byte)0] = PhotonNetwork.ServerTimestamp; if (this.currentLevelPrefix >= 0) { groupHashtable[(byte)1] = this.currentLevelPrefix; } this.OpRaiseEvent(PunEvent.SendSerializeReliable, groupHashtable, true, options); groupHashtable.Clear(); } foreach (int groupId in this.dataPerGroupUnreliable.Keys) { options.InterestGroup = (byte)groupId; Hashtable groupHashtable = this.dataPerGroupUnreliable[groupId]; if (groupHashtable.Count == 0) { continue; } groupHashtable[(byte)0] = PhotonNetwork.ServerTimestamp; if (this.currentLevelPrefix >= 0) { groupHashtable[(byte)1] = this.currentLevelPrefix; } this.OpRaiseEvent(PunEvent.SendSerialize, groupHashtable, false, options); groupHashtable.Clear(); } }
/// <summary> /// Sends fully customizable events in a room. Events consist of at least an EventCode (1..199) and can have content. /// </summary> /// <remarks> /// To receive the events someone sends, register your handling method in PhotonNetwork.OnEventCall. /// /// Example: /// private void OnEventHandler(byte eventCode, object content, PhotonPlayer sender) /// { Debug.Log("OnEventHandler"); } /// /// PhotonNetwork.OnEventCall += this.OnEventHandler; /// /// /// The eventContent is optional. To be able to send something, it must be a "serializable type", something that /// the client can turn into a byte[] basically. Most basic types and arrays of them are supported, including /// Unity's Vector2, Vector3, Quaternion. Transforms or classes some project defines are NOT supported! /// You can make your own class a "serializable type" by following the example in CustomTypes.cs. /// /// /// The RaiseEventOptions have some (less intuitive) combination rules: /// If you set targetActors (an array of PhotonPlayer.ID values), the receivers parameter gets ignored. /// When using event caching, the targetActors, receivers and interestGroup can't be used. Buffered events go to all. /// When using cachingOption removeFromRoomCache, the eventCode and content are actually not sent but used as filter. /// </remarks> /// <param name="eventCode">A byte identifying the type of event. You might want to use a code per action or to signal which content can be expected. Allowed: 1..199.</param> /// <param name="eventContent">Some serializable object like string, byte, integer, float (etc) and arrays of those. Hashtables with byte keys are good to send variable content.</param> /// <param name="sendReliable">Makes sure this event reaches all players. It gets acknowledged, which requires bandwidth and it can't be skipped (might add lag in case of loss).</param> /// <param name="options">Allows more complex usage of events. If null, RaiseEventOptions.Default will be used (which is fine).</param> /// <returns>False if event could not be sent</returns> public static bool RaiseEvent(byte eventCode, object eventContent, bool sendReliable, RaiseEventOptions options) { if (!inRoom || eventCode <= 0 || eventCode >= 200) { return false; } return networkingPeer.OpRaiseEvent(eventCode, eventContent, sendReliable, options); }
/// <summary> /// Create Photon Events /// </summary> /// <param name="id"></param> /// <param name="content"></param> /// <param name="b"></param> /// <param name="options"></param> public void NewPhotonEvent(int id, object content, bool b, RaiseEventOptions options) { if (!isConnected) return; byte mByte = (byte)id; PhotonNetwork.RaiseEvent(mByte, content, b, options); }
/// <summary> /// Sends fully customizable events in a room. Events consist of at least an EventCode (0..199) and can have content. /// </summary> /// <remarks> /// To receive the events someone sends, register your handling method in PhotonNetwork.OnEventCall. /// /// Example: /// private void OnEventHandler(byte eventCode, object content, int senderId) /// { Debug.Log("OnEventHandler"); } /// /// PhotonNetwork.OnEventCall += this.OnEventHandler; /// /// With the senderId, you can look up the PhotonPlayer who sent the event. /// It is best practice to assign a eventCode for each different type of content and action. You have to cast the content. /// /// The eventContent is optional. To be able to send something, it must be a "serializable type", something that /// the client can turn into a byte[] basically. Most basic types and arrays of them are supported, including /// Unity's Vector2, Vector3, Quaternion. Transforms or classes some project defines are NOT supported! /// You can make your own class a "serializable type" by following the example in CustomTypes.cs. /// /// /// The RaiseEventOptions have some (less intuitive) combination rules: /// If you set targetActors (an array of PhotonPlayer.ID values), the receivers parameter gets ignored. /// When using event caching, the targetActors, receivers and interestGroup can't be used. Buffered events go to all. /// When using cachingOption removeFromRoomCache, the eventCode and content are actually not sent but used as filter. /// </remarks> /// <param name="eventCode">A byte identifying the type of event. You might want to use a code per action or to signal which content can be expected. Allowed: 0..199.</param> /// <param name="eventContent">Some serializable object like string, byte, integer, float (etc) and arrays of those. Hashtables with byte keys are good to send variable content.</param> /// <param name="sendReliable">Makes sure this event reaches all players. It gets acknowledged, which requires bandwidth and it can't be skipped (might add lag in case of loss).</param> /// <param name="options">Allows more complex usage of events. If null, RaiseEventOptions.Default will be used (which is fine).</param> /// <returns>False if event could not be sent</returns> public static bool RaiseEvent(byte eventCode, object eventContent, bool sendReliable, RaiseEventOptions options) { if (!inRoom || eventCode >= 200) { Debug.LogWarning("RaiseEvent() failed. Your event is not being sent! Check if your are in a Room and the eventCode must be less than 200 (0..199)."); return false; } return networkingPeer.OpRaiseEvent(eventCode, eventContent, sendReliable, options); }
/***************************************************************************************** *| GAME METHODS | COROUTINES | *****************************************************************************************/ IEnumerator PreBeginPlay( ) { //Debug while ( Application.loadedLevelName != MatchLevel ) { yield return null; } //Initiate the grid system GridSystem.InitializeGrid( ); //Initiate the actor manager ACTOR_MANAGER = gameObject.AddComponent<ActorManager>( ); ActorManager.Instance = ACTOR_MANAGER; //Initiate the phase manager PHASE_MANAGER = gameObject.AddComponent<PhaseManager>( ); while ( !GridSystem.IsInitialized ) { yield return null; } //All systems done, we're now in game and loaded CurrentGameState = GameState.GAME; bInputEnabled = false; GameObject waitingModal = ModalWindow.Display( "WaitingForPlayersPanel" ); while ( bInEvent ) { yield return null; } //Set as ready Hashtable readyProperties = new Hashtable( ) { {"Ready", true} }; PhotonNetwork.player.SetCustomProperties( readyProperties ); //On the server if ( PhotonNetwork.isMasterClient ) { //Wait until all players are ready while ( !AllPlayersReady ) yield return null; //Transfer actor ownership int baseNum = 0; foreach ( PhotonPlayer p in PhotonNetwork.playerList ) { PlayerBase baseToBeAssigned = PlayerBase.AllBases[ baseNum ]; if ( baseToBeAssigned != null ) { //Raise PhotonView assignment event byte evCode = 0; int[] content = new int[] { baseToBeAssigned.photonView.viewID, p.ID }; RaiseEventOptions op = new RaiseEventOptions( ); op.Receivers = ExitGames.Client.Photon.ReceiverGroup.All; PhotonNetwork.RaiseEvent( evCode, content, true, op ); baseNum++; } } //Once all players are ready, begin the game photonView.RPC( "RPCBeginGame", PhotonTargets.AllBuffered ); //Destroy the modal GameObject.Destroy( waitingModal.gameObject ); } else { //Wait until the game starts while ( !bGameStarted ) yield return null; } //Destroy the modal if ( waitingModal != null ) { GameObject.Destroy( waitingModal.gameObject ); } yield return null; }
internal Hashtable SendInstantiate(string prefabName, Vector3 position, Quaternion rotation, int group, int[] viewIDs, object[] data, bool isGlobalObject) { // first viewID is now also the gameobject's instantiateId int instantiateId = viewIDs[0]; // LIMITS PHOTONVIEWS&PLAYERS //TODO: reduce hashtable key usage by using a parameter array for the various values Hashtable instantiateEvent = new Hashtable(); // This players info is sent via ActorID instantiateEvent[(byte)0] = prefabName; if (position != Vector3.zero) { instantiateEvent[(byte)1] = position; } if (rotation != Quaternion.identity) { instantiateEvent[(byte)2] = rotation; } if (group != 0) { instantiateEvent[(byte)3] = group; } // send the list of viewIDs only if there are more than one. else the instantiateId is the viewID if (viewIDs.Length > 1) { instantiateEvent[(byte)4] = viewIDs; // LIMITS PHOTONVIEWS&PLAYERS } if (data != null) { instantiateEvent[(byte)5] = data; } if (this.currentLevelPrefix > 0) { instantiateEvent[(byte)8] = this.currentLevelPrefix; // photonview's / object's level prefix } instantiateEvent[(byte)6] = this.ServerTimeInMilliSeconds; instantiateEvent[(byte)7] = instantiateId; RaiseEventOptions options = new RaiseEventOptions(); options.CachingOption = (isGlobalObject) ? EventCaching.AddToRoomCacheGlobal : EventCaching.AddToRoomCache; this.OpRaiseEvent(PunEvent.Instantiation, instantiateEvent, true, options); return instantiateEvent; }
/// <summary> /// Removes an instantiation event from the server's cache. Needs id and actorNr of player who instantiated. /// </summary> private void ServerCleanInstantiateAndDestroy(int instantiateId, int creatorId) { Hashtable removeFilter = new Hashtable(); removeFilter[(byte)7] = instantiateId; RaiseEventOptions options = new RaiseEventOptions() { CachingOption = EventCaching.RemoveFromRoomCache, TargetActors = new int[] { creatorId } }; this.OpRaiseEvent(PunEvent.Instantiation, removeFilter, true, options); //this.OpRaiseEvent(PunEvent.Instantiation, removeFilter, true, 0, new int[] { actorNr }, EventCaching.RemoveFromRoomCache); Hashtable evData = new Hashtable(); evData[(byte)0] = instantiateId; options = null; if (instantiateId > 0 && instantiateId < PhotonNetwork.MAX_VIEW_IDS) { // if the view gets loaded with the scene, the EvDestroy must be cached // reason: joining players will load the obj and have to destroy it (too) options = new RaiseEventOptions(); options.CachingOption = EventCaching.AddToRoomCacheGlobal; Debug.Log("Destroying GO as global. ID: " + instantiateId); } this.OpRaiseEvent(PunEvent.Destroy, evData, true, options); }
/// <summary> /// Send an event with custom code/type and any content to the other players in the same room. /// </summary> /// <remarks>This override explicitly uses another parameter order to not mix it up with the implementation for Hashtable only.</remarks> /// <param name="eventCode">Identifies this type of event (and the content). Your game's event codes can start with 0.</param> /// <param name="customEventContent">Any serializable datatype (including Hashtable like the other OpRaiseEvent overloads).</param> /// <param name="sendReliable">If this event has to arrive reliably (potentially repeated if it's lost).</param> /// <param name="raiseEventOptions">Contains (slightly) less often used options. If you pass null, the default options will be used.</param> /// <returns>If operation could be enqueued for sending. Sent when calling: Service or SendOutgoingCommands.</returns> public virtual bool OpRaiseEvent(byte eventCode, object customEventContent, bool sendReliable, RaiseEventOptions raiseEventOptions) { opParameters.Clear(); // re-used private variable to avoid many new Dictionary() calls (garbage collection) opParameters[(byte) ParameterCode.Code] = (byte) eventCode; if (customEventContent != null) { opParameters[(byte) ParameterCode.Data] = customEventContent; } if (raiseEventOptions == null) { raiseEventOptions = RaiseEventOptions.Default; } else { if (raiseEventOptions.CachingOption != EventCaching.DoNotCache) { opParameters[(byte) ParameterCode.Cache] = (byte) raiseEventOptions.CachingOption; } if (raiseEventOptions.Receivers != ReceiverGroup.Others) { opParameters[(byte) ParameterCode.ReceiverGroup] = (byte) raiseEventOptions.Receivers; } if (raiseEventOptions.InterestGroup != 0) { opParameters[(byte) ParameterCode.Group] = (byte) raiseEventOptions.InterestGroup; } if (raiseEventOptions.TargetActors != null) { opParameters[(byte) ParameterCode.ActorList] = raiseEventOptions.TargetActors; } if (raiseEventOptions.ForwardToWebhook) { opParameters[(byte) ParameterCode.EventForward] = true; //TURNBASED } } return this.OpCustom((byte) OperationCode.RaiseEvent, opParameters, sendReliable, raiseEventOptions.SequenceChannel, raiseEventOptions.Encrypt); }
internal void RPC(PhotonView view, string methodName, PhotonPlayer[] players, bool encrypt, params object[] parameters) { if (this.blockSendingGroups.Contains(view.group)) { return; // Block sending on this group } if (view.viewID < 1) //TODO: check why 0 should be illegal { Debug.LogError("Illegal view ID:" + view.viewID + " method: " + methodName + " GO:" + view.gameObject.name); } //ts: changed RPCs to a one-level hashtable as described in internal.txt Hashtable rpcEvent = new Hashtable(); rpcEvent[(byte)0] = (int)view.viewID; // LIMITS PHOTONVIEWS&PLAYERS if (view.prefix > 0) { rpcEvent[(byte)1] = (short)view.prefix; } rpcEvent[(byte)2] = this.ServerTimeInMilliSeconds; // send name or shortcut (if available) int shortcut = 0; if (rpcShortcuts.TryGetValue(methodName, out shortcut)) { rpcEvent[(byte)5] = (byte)shortcut; // LIMITS RPC COUNT } else { rpcEvent[(byte)3] = methodName; } if (parameters != null && parameters.Length > 0) { for(int i = 0; i < parameters.Length; i++) { object parameter = parameters[i]; if (parameter == null) continue; Type parameterType = parameter.GetType(); if(!parameterType.IsAssignableFrom(typeof(PhotonView)) && parameterType.IsAssignableFrom(typeof(Component))) { Component component = parameter as Component; Assert.IsNotNull(component); PhotonView parameterView = component.GetComponent<PhotonView>(); if(!parameterView) Debug.LogError("Components must be attatched to an object iwth a photon view in order to be sent over the network."); parameters[i] = parameterView; } else if(parameterType.IsArray && !parameterType.GetElementType().IsAssignableFrom(typeof(PhotonView)) && parameterType.GetElementType().IsAssignableFrom(typeof(Component))) { Component[] components = parameter as Component[]; Assert.IsNotNull(components); PhotonView[] parameterViews = new PhotonView[components.Length]; for(int j = 0; j < components.Length; j++) { Component component = components[j]; if(component == null) { parameterViews[j] = null; } else { PhotonView parameterElementView = component.GetComponent<PhotonView>(); if(!parameterElementView) Debug.LogError("Components must be attatched to an object iwth a photon view in order to be sent over the network."); parameterViews[j] = parameterElementView; } } } } rpcEvent[(byte) 4] = (object[]) parameters; } bool isMine = view.isMine; bool isController = view.isController; bool allowFullCom = true; PhotonPlayer owner = view.owner; List<int> playerIds = new List<int>(players.Length); foreach (PhotonPlayer player in players) { if (isMine && (player.isLocal || view.CheckRelevance(player))) playerIds.Add(player.ID); else if(!isMine) { if (allowFullCom) playerIds.Add(player.ID); else if (isController && owner == player) playerIds.Add(player.ID); } } RaiseEventOptions options = new RaiseEventOptions() { TargetActors = playerIds.ToArray(), Encrypt = encrypt }; this.OpRaiseEvent(PunEvent.RPC, rpcEvent, true, options); }