Skip to content

cherrypick fix: null refs when quitting (#563) #572

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 16 additions & 5 deletions Assets/BossRoom/Scripts/Shared/ApplicationController.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
using System;
using System.Collections;
using BossRoom.Scripts.Shared.Net.UnityServices.Auth;
using Unity.Multiplayer.Samples.BossRoom.Client;
using Unity.Multiplayer.Samples.BossRoom.Server;
using Unity.Multiplayer.Samples.BossRoom.Shared.Infrastructure;
using Unity.Multiplayer.Samples.BossRoom.Shared.Net.UnityServices.Infrastructure;
using Unity.Multiplayer.Samples.BossRoom.Shared.Net.UnityServices.Lobbies;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.SceneManagement;

Expand Down Expand Up @@ -77,7 +77,7 @@ private void Start()

private void OnDestroy()
{
m_LobbyServiceFacade.ForceLeaveLobbyAttempt();
m_LobbyServiceFacade.EndTracking();
DIScope.RootScope.Dispose();
}

Expand All @@ -87,21 +87,32 @@ private void OnDestroy()
/// </summary>
private IEnumerator LeaveBeforeQuit()
{
m_LobbyServiceFacade.ForceLeaveLobbyAttempt();
// We want to quit anyways, so if anything happens while trying to leave the Lobby, log the exception then carry on
try
{
m_LobbyServiceFacade.EndTracking();
}
catch (Exception e)
{
Debug.LogError(e.Message);
}
yield return null;
Application.Quit();
}

private bool OnWantToQuit()
{
var canQuit = string.IsNullOrEmpty(m_LocalLobby?.LobbyID);
StartCoroutine(LeaveBeforeQuit());
if (canQuit)
{
StartCoroutine(LeaveBeforeQuit());
}
return canQuit;
}

public void LeaveSession()
{
m_LobbyServiceFacade.ForceLeaveLobbyAttempt();
m_LobbyServiceFacade.EndTracking();

// first disconnect then return to menu
var gameNetPortal = GameNetPortal.Instance;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,20 +87,18 @@ public void DeleteLobbyAsync(string lobbyId, Action onComplete, Action onFailed)
RunTask(task, onComplete, onFailed);
}

public Task JoinLobbyAsync_ByCode(string requesterUasId, string lobbyCode, Dictionary<string, PlayerDataObject> localUserData, Action<Lobby> onComplete, Action onFailed)
public void JoinLobbyAsync_ByCode(string requesterUasId, string lobbyCode, Dictionary<string, PlayerDataObject> localUserData, Action<Lobby> onComplete, Action onFailed)
{
JoinLobbyByCodeOptions joinOptions = new JoinLobbyByCodeOptions { Player = new Player(id: requesterUasId, data: localUserData) };
var task = Lobbies.Instance.JoinLobbyByCodeAsync(lobbyCode, joinOptions);
RunTask(task, onComplete, onFailed);
return task;
}

public Task JoinLobbyAsync_ById(string requesterUasId, string lobbyId, Dictionary<string, PlayerDataObject> localUserData, Action<Lobby> onComplete, Action onFailed)
public void JoinLobbyAsync_ById(string requesterUasId, string lobbyId, Dictionary<string, PlayerDataObject> localUserData, Action<Lobby> onComplete, Action onFailed)
{
JoinLobbyByIdOptions joinOptions = new JoinLobbyByIdOptions { Player = new Player(id: requesterUasId, data: localUserData) };
var task = Lobbies.Instance.JoinLobbyByIdAsync(lobbyId, joinOptions);
RunTask(task, onComplete, onFailed);
return task;
}

public void QuickJoinLobbyAsync(string requesterUasId, Dictionary<string, PlayerDataObject> localUserData, Action<Lobby> onComplete, Action onFailed)
Expand All @@ -115,11 +113,10 @@ public void QuickJoinLobbyAsync(string requesterUasId, Dictionary<string, Player
RunTask(task, onComplete, onFailed);
}

public Task LeaveLobbyAsync(string requesterUasId, string lobbyId, Action onComplete, Action onFailed)
public void LeaveLobbyAsync(string requesterUasId, string lobbyId, Action onComplete, Action onFailed)
{
var task = Lobbies.Instance.RemovePlayerAsync(lobbyId, requesterUasId);
RunTask(task, onComplete, onFailed);
return task;
}

public void QueryAllLobbiesAsync(Action<QueryResponse> onComplete, Action onFailed)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,16 +92,15 @@ public void BeginTracking()
}
}

public Task EndTracking()
public void EndTracking()
{
var task = Task.CompletedTask;
if (CurrentUnityLobby != null)
{
CurrentUnityLobby = null;

if (!string.IsNullOrEmpty(m_LocalLobby?.LobbyID))
{
task = LeaveLobbyAsync(m_LocalLobby?.LobbyID, null, null);
LeaveLobbyAsync(m_LocalLobby?.LobbyID, null, null);
}

m_LocalUser.ResetState();
Expand All @@ -115,7 +114,6 @@ public Task EndTracking()
m_HeartbeatTime = 0;
m_JoinedLobbyContentHeartbeat.EndTracking();
}
return task;
}

void UpdateLobby(float unused)
Expand All @@ -138,7 +136,7 @@ void OnSuccess(Lobby lobby)
}
}
m_UnityServiceErrorMessagePub.Publish(new UnityServiceErrorMessage("Host left the lobby","Disconnecting.", UnityServiceErrorMessage.Service.Lobby));
ForceLeaveLobbyAttempt();
EndTracking();
// no need to disconnect Netcode, it should already be handled by Netcode's callback to disconnect
}
}
Expand Down Expand Up @@ -169,24 +167,24 @@ public void CreateLobbyAsync(string lobbyName, int maxPlayers, bool isPrivate, O
/// <summary>
/// Attempt to join an existing lobby. Will try to join via code, if code is null - will try to join via ID.
/// </summary>
public Task JoinLobbyAsync(string lobbyId, string lobbyCode, Action<Lobby> onSuccess, Action onFailure)
public void JoinLobbyAsync(string lobbyId, string lobbyCode, Action<Lobby> onSuccess, Action onFailure)
{
if (!m_RateLimitJoin.CanCall ||
(lobbyId == null && lobbyCode == null))
{
onFailure?.Invoke();
UnityEngine.Debug.LogWarning("Join Lobby hit the rate limit.");
return Task.CompletedTask;
return;
}
m_RateLimitJoin.PutOnCooldown();

if (!string.IsNullOrEmpty(lobbyCode))
{
return m_LobbyApiInterface.JoinLobbyAsync_ByCode(AuthenticationService.Instance.PlayerId, lobbyCode, m_LocalUser.GetDataForUnityServices(), onSuccess, onFailure);
m_LobbyApiInterface.JoinLobbyAsync_ByCode(AuthenticationService.Instance.PlayerId, lobbyCode, m_LocalUser.GetDataForUnityServices(), onSuccess, onFailure);
}
else
{
return m_LobbyApiInterface.JoinLobbyAsync_ById(AuthenticationService.Instance.PlayerId, lobbyId, m_LocalUser.GetDataForUnityServices(), onSuccess, onFailure);
m_LobbyApiInterface.JoinLobbyAsync_ById(AuthenticationService.Instance.PlayerId, lobbyId, m_LocalUser.GetDataForUnityServices(), onSuccess, onFailure);
}
}

Expand Down Expand Up @@ -243,10 +241,10 @@ void RetrieveLobbyAsync(string lobbyId, Action<Lobby> onSuccess, Action onFailur
/// <summary>
/// Attempt to leave a lobby, and then delete it if no players remain.
/// </summary>
public Task LeaveLobbyAsync(string lobbyId, Action onSuccess, Action onFailure)
public void LeaveLobbyAsync(string lobbyId, Action onSuccess, Action onFailure)
{
string uasId = AuthenticationService.Instance.PlayerId;
return m_LobbyApiInterface.LeaveLobbyAsync(uasId, lobbyId, onSuccess, onFailure);
m_LobbyApiInterface.LeaveLobbyAsync(uasId, lobbyId, onSuccess, onFailure);
}

public void RemovePlayerFromLobbyAsync(string uasId, string lobbyId, Action onSuccess, Action onFailure)
Expand Down Expand Up @@ -406,10 +404,5 @@ public void DoLobbyHeartbeat(float dt)
m_LobbyApiInterface.HeartbeatPlayerAsync(CurrentUnityLobby.Id);
}
}

public void ForceLeaveLobbyAttempt()
{
EndTracking();
}
}
}