/// An abstraction layer between the direct calls into the Lobby API and the outcomes you actually want. E.g. you can request to get a readable list of
/// current lobbies and not need to make the query call directly.
/// </summary>
publicclassLobbyAsyncRequests
publicclassLobbyAsyncRequests:IDisposable
privateconstintk_maxLobbiesToShow=16;// If more are necessary, consider retrieving paginated results or using filters.
publicstaticLobbyAsyncRequestsInstance
{
//Once connected to a lobby, cache the local lobby object so we don't query for it for every lobby operation.
// (This assumes that the player will be actively in just one lobby at a time, though they could passively be in more.)
Lobbym_RemoteLobby;
/// <summary>
/// Store the LobbySubscription so we can unsubscribe later.
/// </summary>
returndata;
}
//TODO Back to Polling i Guess
voidBeginListening(stringlobbyID)
{
m_lobbyEvents=newLobbyEventCallbacks();
voidEndListening()
{
if(m_lobbySubscription==null)
{
Debug.LogError("Can't End listening without first listening to the lobby Callbacks.");
return;
}
m_lobbySubscription.UnsubscribeAsync();
m_RemoteLobby=null;
m_lobbySubscription=null;
/// <summary>
/// Attempt to create a new lobby and then join it.
/// Used for getting the list of all active lobbies, without needing full info for each.
/// </summary>
/// <param name="onListRetrieved">If called with null, retrieval was unsuccessful. Else, this will be given a list of contents to display, as pairs of a lobby code and a display string for that lobby.</param>
if(!ShouldUpdateData(()=>{UpdatePlayerRelayInfoAsync(allocationId,connectionInfo,onComplete);},onComplete,true))// Do retry here since the RelayUtpSetup that called this might be destroyed right after this.
privateconstfloatk_heartbeatPeriod=8;// The heartbeat must be rate-limited to 5 calls per 30 seconds. We'll aim for longer in case periods don't align.
if(!m_isInCooldown)// It's possible that by setting IsInCooldown, something called CanCall immediately, in which case we want to stay on UpdateSlow.
{
Locator.Get.UpdateSlow.Unsubscribe(OnUpdate);// Note that this is after IsInCooldown is set, to prevent an Observer from kicking off CanCall again immediately.
intnumPending=m_pendingOperations.Count;// It's possible a pending operation will re-enqueue itself or new operations, which should wait until the next loop.
for(;numPending>0;numPending--)
m_pendingOperations.Dequeue()?.Invoke();// Note: If this ends up enqueuing many operations, we might need to batch them and/or ensure they don't all execute at once.
boolareAllPlayersConnected=NetworkManager.ConnectedClients.Count>=m_expectedPlayerCount;// The game will begin at this point, or else there's a timeout for booting any unconnected players.
boolareAllPlayersConnected=NetworkManager.Singleton.ConnectedClients.Count>=m_expectedPlayerCount;// The game will begin at this point, or else there's a timeout for booting any unconnected players.
privateNetworkVariable<Vector3>m_position=newNetworkVariable<Vector3>(NetworkVariableReadPermission.Everyone,Vector3.zero);// (Using a NetworkTransform to sync position would also work.)
privateNetworkVariable<Vector3>m_position=newNetworkVariable<Vector3>(Vector3.zero);// (Using a NetworkTransform to sync position would also work.)
privateulongm_localId;
// If the local player cursor spawns before this cursor's owner, the owner's data won't be available yet. This is used to retrieve the data later.
if(m_joinState==(JoinState.Joined|JoinState.Bound)&&this!=null)// this will equal null (i.e. this component has been destroyed) if the host left the lobby during the Relay connection sequence.
privateDictionary<string,PlayerDataObject>m_mockUserData;// This is handled in the LobbyAsyncRequest calls normally, but we need to supply this for the direct Lobby API calls.
yieldreturnnewWaitForSeconds(0.5f);// We need a yield anyway, so wait long enough to probably delete the lobby. There currently (6/22/2021) aren't other tests that would have issues if this took longer.
publicIEnumeratorDoRoundtrip()
{
#region Setup
// Wait a reasonable amount of time for sign-in to complete.
if(!m_didSigninComplete)
yieldreturnnewWaitForSeconds(3);
// Since we're signed in through the same pathway as the actual game, the list of lobbies will include any that have been made in the game itself, so we should account for those.
// If you want to get around this, consider having a secondary project using the same assets with its own credentials.
yieldreturnnewWaitForSeconds(1);// To prevent a possible 429 with the upcoming Query request, in case a previous test had one; Query requests can only occur at a rate of 1 per second.
yieldreturn
newWaitForSeconds(
1);// To prevent a possible 429 with the upcoming Query request, in case a previous test had one; Query requests can only occur at a rate of 1 per second.