/// <summary> /// Joins a random room that matches the filter. Will callback: OnJoinedRoom or OnJoinRandomFailed. /// </summary> /// <remarks> /// Used for random matchmaking. You can join any room or one with specific properties defined in opJoinRandomRoomParams. /// /// This operation fails if no rooms are fitting or available (all full, closed, in another lobby or not visible). /// It may also fail when actually joining the room which was found. Rooms may close, become full or empty anytime. /// /// This method can only be called while the client is connected to a Master Server so you should /// implement the callback OnConnectedToMaster. /// Check the return value to make sure the operation will be called on the server. /// Note: There will be no callbacks if this method returned false. /// /// More about PUN matchmaking: /// https://doc.photonengine.com/en-us/pun/v2/lobby-and-matchmaking/matchmaking-and-lobby /// </remarks> /// <param name="expectedCustomRoomProperties">Filters for rooms that match these custom properties (string keys and values). To ignore, pass null.</param> /// <param name="expectedMaxPlayers">Filters for a particular maxplayer setting. Use 0 to accept any maxPlayer value.</param> /// <param name="matchingType">Selects one of the available matchmaking algorithms. See MatchmakingMode enum for options.</param> /// <param name="typedLobby">The lobby in which you want to lookup a room. Pass null, to use the default lobby. This does not join that lobby and neither sets the lobby property.</param> /// <param name="sqlLobbyFilter">A filter-string for SQL-typed lobbies.</param> /// <param name="expectedUsers">Optional list of users (by UserId) who are expected to join this game and who you want to block a slot for.</param> /// <returns>If the operation got queued and will be sent.</returns> public static async UniTask JoinRandomRoomAsync( Hashtable expectedCustomRoomProperties, byte expectedMaxPlayers, MatchmakingMode matchingType, TypedLobby typedLobby, string sqlLobbyFilter, string[] expectedUsers = null, CancellationToken token = default) { var task = UniTask.WhenAny( Pun2TaskCallback.OnJoinedRoomAsync().AsAsyncUnitUniTask(), Pun2TaskCallback.OnJoinRandomFailedAsync()); var valid = PhotonNetwork.JoinRandomRoom( expectedCustomRoomProperties, expectedMaxPlayers, matchingType, typedLobby, sqlLobbyFilter, expectedUsers); if (!valid) { throw new InvalidRoomOperationException("It is not ready to join a room."); } var(winIndex, _, (returnCode, message)) = await task.WithCancellation(token); if (winIndex == 0) { return; } throw new FailedToJoinRoomException(returnCode, message); }
/// <summary> /// Creates a new room. Will callback: OnCreatedRoom and OnJoinedRoom or OnCreateRoomFailed. /// </summary> /// <remarks> /// When successful, this calls the callbacks OnCreatedRoom and OnJoinedRoom (the latter, cause you join as first player). /// In all error cases, OnCreateRoomFailed gets called. /// /// Creating a room will fail if the room name is already in use or when the RoomOptions clashing /// with one another. Check the EnterRoomParams reference for the various room creation options. /// /// If you don't want to create a unique room-name, pass null or "" as name and the server will assign a roomName (a GUID as string). /// /// This method can only be called while the client is connected to a Master Server so you should /// implement the callback OnConnectedToMaster. /// Check the return value to make sure the operation will be called on the server. /// Note: There will be no callbacks if this method returned false. /// /// More about PUN matchmaking: /// https://doc.photonengine.com/en-us/pun/v2/lobby-and-matchmaking/matchmaking-and-lobby /// </remarks> /// <param name="roomName">Unique name of the room to create. Pass null or "" to make the server generate a name.</param> /// <param name="roomOptions">Common options for the room like MaxPlayers, initial custom room properties and similar. See RoomOptions type..</param> /// <param name="typedLobby">If null, the room is automatically created in the currently used lobby (which is "default" when you didn't join one explicitly).</param> /// <param name="expectedUsers">Optional list of users (by UserId) who are expected to join this game and who you want to block a slot for.</param> public static async UniTask CreateRoomAsync( string roomName, RoomOptions roomOptions = null, TypedLobby typedLobby = null, string[] expectedUsers = null, CancellationToken token = default) { var task = UniTask.WhenAny( Pun2TaskCallback.OnJoinedRoomAsync().AsAsyncUnitUniTask(), Pun2TaskCallback.OnCreateRoomFailedAsync()); var valid = PhotonNetwork.CreateRoom(roomName, roomOptions, typedLobby, expectedUsers); if (!valid) { throw new InvalidRoomOperationException("It is not ready to create a room."); } var(winIndex, _, (returnCode, message)) = await task.WithCancellation(token); if (winIndex == 0) { return; } throw new FailedToCreateRoomException(returnCode, message); }
/// <summary>When the client lost connection during gameplay, this method attempts to reconnect and rejoin the room.</summary> /// <remarks> /// This method re-connects directly to the game server which was hosting the room PUN was in before. /// If the room was shut down in the meantime, PUN will call OnJoinRoomFailed and return this client to the Master Server. /// /// Check the return value, if this client will attempt a reconnect and rejoin (if the conditions are met). /// If ReconnectAndRejoin returns false, you can still attempt a Reconnect and Rejoin. /// /// Similar to PhotonNetwork.RejoinRoom, this requires you to use unique IDs per player (the UserID). /// /// Rejoining room will not send any player properties. Instead client will receive up-to-date ones from server. /// If you want to set new player properties, do it once rejoined. /// </remarks> /// <returns>False, if there is no known room or game server to return to. Then, this client does not attempt the ReconnectAndRejoin.</returns> public static async UniTask ReconnectAndRejoinAsync(CancellationToken token) { var task = UniTask.WhenAny( Pun2TaskCallback.OnJoinedRoomAsync().AsAsyncUnitUniTask(), Pun2TaskCallback.OnJoinRoomFailedAsync()); var valid = PhotonNetwork.ReconnectAndRejoin(); if (!valid) { throw new InvalidRoomOperationException("It is not ready to join a room."); } var(winIndex, _, (returnCode, message)) = await task.WithCancellation(token); if (winIndex == 0) { return; } throw new FailedToJoinRoomException(returnCode, message); }
/// <summary> /// Rejoins a room by roomName (using the userID internally to return). Will callback: OnJoinedRoom or OnJoinRoomFailed. /// </summary> /// <remarks> /// After losing connection, you might be able to return to a room and continue playing, /// if the client is reconnecting fast enough. Use Reconnect() and this method. /// Cache the room name you're in and use RejoinRoom(roomname) to return to a game. /// /// Note: To be able to Rejoin any room, you need to use UserIDs! /// You also need to set RoomOptions.PlayerTtl. /// /// <b>Important: Instantiate() and use of RPCs is not yet supported.</b> /// The ownership rules of PhotonViews prevent a seamless return to a game, if you use PhotonViews. /// Use Custom Properties and RaiseEvent with event caching instead. /// /// Common use case: Press the Lock Button on a iOS device and you get disconnected immediately. /// /// Rejoining room will not send any player properties. Instead client will receive up-to-date ones from server. /// If you want to set new player properties, do it once rejoined. public static async UniTask RejoinRoomAsync(string roomName, CancellationToken token = default) { var task = UniTask.WhenAny( Pun2TaskCallback.OnJoinedRoomAsync().AsAsyncUnitUniTask(), Pun2TaskCallback.OnJoinRoomFailedAsync()); var valid = PhotonNetwork.RejoinRoom(roomName); if (!valid) { throw new InvalidRoomOperationException("It is not ready to join a room."); } var(winIndex, _, (returnCode, message)) = await task.AttachExternalCancellation(token); if (winIndex == 0) { return; } throw new FailedToJoinRoomException(returnCode, message); }
/// <summary> /// Joins a specific room by name and creates it on demand. Will callback: OnJoinedRoom or OnJoinRoomFailed. /// </summary> /// <remarks> /// Useful when players make up a room name to meet in: /// All involved clients call the same method and whoever is first, also creates the room. /// /// When successful, the client will enter the specified room. /// The client which creates the room, will callback both OnCreatedRoom and OnJoinedRoom. /// Clients that join an existing room will only callback OnJoinedRoom. /// In all error cases, OnJoinRoomFailed gets called. /// /// Joining a room will fail, if the room is full, closed or when the user /// already is present in the room (checked by userId). /// /// To return to a room, use OpRejoinRoom. /// /// This method can only be called while the client is connected to a Master Server so you should /// implement the callback OnConnectedToMaster. /// Check the return value to make sure the operation will be called on the server. /// Note: There will be no callbacks if this method returned false. /// /// /// If you set room properties in roomOptions, they get ignored when the room is existing already. /// This avoids changing the room properties by late joining players. /// /// You can define an array of expectedUsers, to block player slots in the room for these users. /// The corresponding feature in Photon is called "Slot Reservation" and can be found in the doc pages. /// /// /// More about PUN matchmaking: /// https://doc.photonengine.com/en-us/pun/v2/lobby-and-matchmaking/matchmaking-and-lobby /// </remarks> /// <param name="roomName">Name of the room to join. Must be non null.</param> /// <param name="roomOptions">Options for the room, in case it does not exist yet. Else these values are ignored.</param> /// <param name="typedLobby">Lobby you want a new room to be listed in. Ignored if the room was existing and got joined.</param> /// <param name="expectedUsers">Optional list of users (by UserId) who are expected to join this game and who you want to block a slot for.</param> /// <returns>True will be returned when you are the first user.</returns>> public static async UniTask <bool> JoinOrCreateRoomAsync( string roomName, RoomOptions roomOptions, TypedLobby typedLobby, string[] expectedUsers = null, CancellationToken token = default) { var createdRoomTask = Pun2TaskCallback.OnCreatedRoomAsync().GetAwaiter(); var task = UniTask.WhenAny( Pun2TaskCallback.OnJoinedRoomAsync().AsAsyncUnitUniTask(), Pun2TaskCallback.OnCreateRoomFailedAsync(), Pun2TaskCallback.OnJoinRoomFailedAsync()); var valid = PhotonNetwork.JoinOrCreateRoom(roomName, roomOptions, typedLobby, expectedUsers); if (!valid) { throw new InvalidRoomOperationException("It is not ready to join a room."); } var(winIndex, _, (createFailedCode, createFailedMessage), (joinFailedCode, joinFailedMessage)) = await task.WithCancellation(token); if (winIndex == 0) { return(createdRoomTask.IsCompleted); } if (winIndex == 1) { throw new FailedToCreateRoomException(createFailedCode, createFailedMessage); } else { throw new FailedToJoinRoomException(createFailedCode, createFailedMessage); } }