Skip to content
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

fix: replace null-coalescencing and null-conditional operators [MTT-7125] #867

Merged
merged 10 commits into from
Sep 6, 2023
14 changes: 11 additions & 3 deletions Assets/Scripts/ApplicationLifecycle/ApplicationController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,16 @@ private void Start()

protected override void OnDestroy()
{
m_Subscriptions?.Dispose();
m_LobbyServiceFacade?.EndTracking();
if (m_Subscriptions != null)
{
m_Subscriptions.Dispose();
}

if (m_LobbyServiceFacade != null)
{
m_LobbyServiceFacade.EndTracking();
}

base.OnDestroy();
}

Expand Down Expand Up @@ -127,7 +135,7 @@ private bool OnWantToQuit()
{
Application.wantsToQuit -= OnWantToQuit;

var canQuit = string.IsNullOrEmpty(m_LocalLobby?.LobbyID);
var canQuit = m_LocalLobby != null && string.IsNullOrEmpty(m_LocalLobby.LobbyID);
if (!canQuit)
{
StartCoroutine(LeaveBeforeQuit());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,19 @@ public override void Exit()

public override void OnClientConnected(ulong clientId)
{
m_ConnectionEventPublisher.Publish(new ConnectionEventMessage() { ConnectStatus = ConnectStatus.Success, PlayerName = SessionManager<SessionPlayerData>.Instance.GetPlayerData(clientId)?.PlayerName });
var playerData = SessionManager<SessionPlayerData>.Instance.GetPlayerData(clientId);
if (playerData != null)
{
m_ConnectionEventPublisher.Publish(new ConnectionEventMessage() { ConnectStatus = ConnectStatus.Success, PlayerName = playerData.Value.PlayerName });
}
else
{
// This should not happen since player data is assigned during connection approval
Debug.LogError($"No player data associated with client {clientId}");
var reason = JsonUtility.ToJson(ConnectStatus.GenericDisconnect);
m_ConnectionManager.NetworkManager.DisconnectClient(clientId, reason);
}

}

public override void OnClientDisconnect(ulong clientId)
Expand Down
11 changes: 9 additions & 2 deletions Assets/Scripts/Gameplay/GameState/ServerBossRoomState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,15 +88,22 @@ void OnNetworkSpawn()

void OnNetworkDespawn()
{
m_LifeStateChangedEventMessageSubscriber?.Unsubscribe(OnLifeStateChangedEventMessage);
if (m_LifeStateChangedEventMessageSubscriber != null)
{
m_LifeStateChangedEventMessageSubscriber.Unsubscribe(OnLifeStateChangedEventMessage);
}

NetworkManager.Singleton.OnClientDisconnectCallback -= OnClientDisconnect;
NetworkManager.Singleton.SceneManager.OnLoadEventCompleted -= OnLoadEventCompleted;
NetworkManager.Singleton.SceneManager.OnSynchronizeComplete -= OnSynchronizeComplete;
}

protected override void OnDestroy()
{
m_LifeStateChangedEventMessageSubscriber?.Unsubscribe(OnLifeStateChangedEventMessage);
if (m_LifeStateChangedEventMessageSubscriber != null)
{
m_LifeStateChangedEventMessageSubscriber.Unsubscribe(OnLifeStateChangedEventMessage);
}

if (m_NetcodeHooks)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,10 @@ public bool IsMoving()
/// </summary>
public void CancelMove()
{
m_NavPath?.Clear();
if (m_NavPath != null)
{
m_NavPath.Clear();
}
m_MovementState = MovementState.Idle;
}

Expand Down
5 changes: 4 additions & 1 deletion Assets/Scripts/Gameplay/GameplayObjects/SwitchedDoor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,10 @@ void OnDoorStateChanged(bool wasDoorOpen, bool isDoorOpen)
if (IsClient)
{
m_PhysicsObject.SetActive(!isDoorOpen);
m_Publisher?.Publish(new DoorStateChangedEventMessage() { IsDoorOpen = isDoorOpen });
if (m_Publisher != null)
{
m_Publisher.Publish(new DoorStateChangedEventMessage() { IsDoorOpen = isDoorOpen });
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ void Awake()

void OnDestroy()
{
m_Subscriptions?.Dispose();
if (m_Subscriptions != null)
{
m_Subscriptions.Dispose();
}
}

void OnConnectStatus(ConnectStatus status)
Expand Down
5 changes: 4 additions & 1 deletion Assets/Scripts/Gameplay/UI/IPConnectionWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ void Awake()

void OnDestroy()
{
m_ConnectStatusSubscriber?.Unsubscribe(OnConnectStatusMessage);
if (m_ConnectStatusSubscriber != null)
{
m_ConnectStatusSubscriber.Unsubscribe(OnConnectStatusMessage);
}
}

void OnConnectStatusMessage(ConnectStatus connectStatus)
Expand Down
5 changes: 4 additions & 1 deletion Assets/Scripts/Gameplay/UI/IPUIMediator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,10 @@ void Start()

void OnDestroy()
{
m_ConnectStatusSubscriber?.Unsubscribe(OnConnectStatusMessage);
if (m_ConnectStatusSubscriber != null)
{
m_ConnectStatusSubscriber.Unsubscribe(OnConnectStatusMessage);
}
}

void OnConnectStatusMessage(ConnectStatus connectStatus)
Expand Down
7 changes: 5 additions & 2 deletions Assets/Scripts/Gameplay/UI/Lobby/LobbyJoiningUI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,16 @@ void OnDisable()
{
if (m_UpdateRunner != null)
{
m_UpdateRunner?.Unsubscribe(PeriodicRefresh);
m_UpdateRunner.Unsubscribe(PeriodicRefresh);
}
}

void OnDestroy()
{
m_LocalLobbiesRefreshedSub?.Unsubscribe(UpdateUI);
if (m_LocalLobbiesRefreshedSub != null)
{
m_LocalLobbiesRefreshedSub.Unsubscribe(UpdateUI);
}
}

[Inject]
Expand Down
5 changes: 4 additions & 1 deletion Assets/Scripts/Gameplay/UI/Lobby/LobbyUIMediator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,10 @@ void OnConnectStatus(ConnectStatus status)

void OnDestroy()
{
m_ConnectStatusSubscriber?.Unsubscribe(OnConnectStatus);
if (m_ConnectStatusSubscriber != null)
{
m_ConnectStatusSubscriber.Unsubscribe(OnConnectStatus);
}
}

//Lobby and Relay calls done from UI
Expand Down
5 changes: 4 additions & 1 deletion Assets/Scripts/Gameplay/UI/UIMessageFeed.cs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,10 @@ UIMessageSlot GetAvailableSlot()

void OnDestroy()
{
m_Subscriptions?.Dispose();
if (m_Subscriptions != null)
{
m_Subscriptions.Dispose();
}
}

}
Expand Down
5 changes: 4 additions & 1 deletion Assets/Scripts/Gameplay/UI/UnityServicesUIHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,10 @@ void HandleLobbyError(UnityServiceErrorMessage error)

void OnDestroy()
{
m_ServiceErrorSubscription?.Unsubscribe(ServiceErrorHandler);
if (m_ServiceErrorSubscription != null)
{
m_ServiceErrorSubscription.Unsubscribe(ServiceErrorHandler);
}
}
}
}
5 changes: 4 additions & 1 deletion Assets/Scripts/Infrastructure/PubSub/MessageChannel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,10 @@ public virtual void Publish(T message)

foreach (var messageHandler in m_MessageHandlers)
{
messageHandler?.Invoke(message);
if (messageHandler != null)
{
messageHandler.Invoke(message);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public InitializationOptions GenerateAuthenticationOptions(string profile)
}
catch (Exception e)
{
var reason = $"{e.Message} ({e.InnerException?.Message})";
var reason = e.InnerException == null ? e.Message : $"{e.Message} ({e.InnerException.Message})";
m_UnityServiceErrorMessagePublisher.Publish(new UnityServiceErrorMessage("Authentication Error", reason, UnityServiceErrorMessage.Service.Authentication, e));
throw;
}
Expand All @@ -46,7 +46,7 @@ public async Task InitializeAndSignInAsync(InitializationOptions initializationO
}
catch (Exception e)
{
var reason = $"{e.Message} ({e.InnerException?.Message})";
var reason = e.InnerException == null ? e.Message : $"{e.Message} ({e.InnerException.Message})";
m_UnityServiceErrorMessagePublisher.Publish(new UnityServiceErrorMessage("Authentication Error", reason, UnityServiceErrorMessage.Service.Authentication, e));
throw;
}
Expand All @@ -67,7 +67,7 @@ public async Task SwitchProfileAndReSignInAsync(string profile)
}
catch (Exception e)
{
var reason = $"{e.Message} ({e.InnerException?.Message})";
var reason = e.InnerException == null ? e.Message : $"{e.Message} ({e.InnerException.Message})";
m_UnityServiceErrorMessagePublisher.Publish(new UnityServiceErrorMessage("Authentication Error", reason, UnityServiceErrorMessage.Service.Authentication, e));
throw;
}
Expand All @@ -87,7 +87,7 @@ public async Task<bool> EnsurePlayerIsAuthorized()
}
catch (AuthenticationException e)
{
var reason = $"{e.Message} ({e.InnerException?.Message})";
var reason = e.InnerException == null ? e.Message : $"{e.Message} ({e.InnerException.Message})";
m_UnityServiceErrorMessagePublisher.Publish(new UnityServiceErrorMessage("Authentication Error", reason, UnityServiceErrorMessage.Service.Authentication, e));

//not rethrowing for authentication exceptions - any failure to authenticate is considered "handled failure"
Expand All @@ -96,7 +96,7 @@ public async Task<bool> EnsurePlayerIsAuthorized()
catch (Exception e)
{
//all other exceptions should still bubble up as unhandled ones
var reason = $"{e.Message} ({e.InnerException?.Message})";
var reason = e.InnerException == null ? e.Message : $"{e.Message} ({e.InnerException.Message})";
m_UnityServiceErrorMessagePublisher.Publish(new UnityServiceErrorMessage("Authentication Error", reason, UnityServiceErrorMessage.Service.Authentication, e));
throw;
}
Expand Down
18 changes: 14 additions & 4 deletions Assets/Scripts/UnityServices/Lobbies/LobbyServiceFacade.cs
Original file line number Diff line number Diff line change
Expand Up @@ -228,8 +228,14 @@ public void EndTracking()
void ResetLobby()
{
CurrentUnityLobby = null;
m_LocalUser.ResetState();
m_LocalLobby?.Reset(m_LocalUser);
if (m_LocalUser != null)
{
m_LocalUser.ResetState();
}
LPLafontaineB marked this conversation as resolved.
Show resolved Hide resolved
if (m_LocalLobby != null)
{
m_LocalLobby.Reset(m_LocalUser);
}
RikuTheFuffs marked this conversation as resolved.
Show resolved Hide resolved

// no need to disconnect Netcode, it should already be handled by Netcode's callback to disconnect
}
Expand Down Expand Up @@ -471,7 +477,11 @@ public async Task UpdateLobbyDataAndUnlockAsync()

var localData = m_LocalLobby.GetDataForUnityServices();

var dataCurr = CurrentUnityLobby.Data ?? new Dictionary<string, DataObject>();
var dataCurr = CurrentUnityLobby.Data;
if (dataCurr == null)
{
dataCurr = new Dictionary<string, DataObject>();
}

foreach (var dataNew in localData)
{
Expand Down Expand Up @@ -533,7 +543,7 @@ void DoLobbyHeartbeat(float dt)

void PublishError(LobbyServiceException e)
{
var reason = $"{e.Message} ({e.InnerException?.Message})"; // Lobby error type, then HTTP error type.
var reason = e.InnerException == null ? e.Message : $"{e.Message} ({e.InnerException.Message})"; // Lobby error type, then HTTP error type.
m_UnityServiceErrorMessagePub.Publish(new UnityServiceErrorMessage("Lobby Error", reason, UnityServiceErrorMessage.Service.Lobby, e));
}
}
Expand Down
2 changes: 1 addition & 1 deletion Assets/Scripts/UnityServices/Lobbies/LocalLobby.cs
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ public void ApplyRemoteData(Lobby lobby)
var incomingData = new LocalLobbyUser
{
IsHost = lobby.HostId.Equals(player.Id),
DisplayName = player.Data?.ContainsKey("DisplayName") == true ? player.Data["DisplayName"].Value : default,
DisplayName = player.Data != null && player.Data.ContainsKey("DisplayName") ? player.Data["DisplayName"].Value : default,
ID = player.Id
};

Expand Down
6 changes: 5 additions & 1 deletion Assets/Scripts/Utils/NetworkSimulatorUIMediator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,11 @@ void OnScenarioChanged(int optionIndex)
break;
}
m_NetworkSimulator.Scenario = scenario;
m_NetworkSimulator.Scenario?.Start(m_NetworkSimulator);
if (m_NetworkSimulator.Scenario != null)
{
m_NetworkSimulator.Scenario.Start(m_NetworkSimulator);
}

UpdateScenarioButton();
}

Expand Down
7 changes: 6 additions & 1 deletion Assets/Scripts/Utils/ProfileManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,12 @@ public string Profile
{
get
{
return m_Profile ??= GetProfile();
if (m_Profile == null)
{
m_Profile = GetProfile();
}

return m_Profile;
}
set
{
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Additional documentation and release notes are available at [Multiplayer Documen
### Changed
* Upgraded editor version to 2022.3.7f1 (#855)
* Upgraded Authentication Service package to v2.7.1
* Replaced usages of null-coalescing and null-conditional operators with regular null checks. (#867) These operators can cause issues when used with types inheriting UnityEngine.Object because that type redefines the == operator to define when an object is null. This redefinition applies to regular null checks (if foo == null) but not to those operators, thus this could lead to unexpected behaviour. While those operators were safely used within Boss Room, only with types that were not inheriting UnityEngine.Object, we decided to remove most usages for consistency. This will also help avoid accidental mistakes, such as a user reusing a part of this code, but modifying it so that one of those operators are used with a UnityEngine.Object.
* Upgraded Boss Room to Netcode for GameObjects v1.6.0 (#865)
* A package Version Define has been created for Netcode for GameObjects v.1.5.2 - v1.6.0. Recent refactorings to NetworkManager's shutdown have prevented the ability to invoke CustomMessages when OnClientDisconnected callbacks are invoked during a shutdown as host. This regression has caused one of our runtime tests, namely Unity.BossRoom.Tests.Runtime.ConnectionManagementTests.UnexpectedServerShutdown_ClientsFailToReconnect, to fail and it does not impact gameplay. This is a known issue and will be addressed in a future NGO version.
* Upgraded to Lobby 1.1.0 (#860).
Expand Down
3 changes: 3 additions & 0 deletions Packages/com.unity.multiplayer.samples.coop/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

## [Unreleased] - yyyy-mm-dd

### Changed
* Replaced usages of null-coalescing and null-conditional operators with regular null checks. (#867) These operators can cause issues when used with types inheriting UnityEngine.Object because that type redefines the == operator to define when an object is null. This redefinition applies to regular null checks (if foo == null) but not to those operators, thus this could lead to unexpected behaviour. While those operators were safely used within Boss Room, only with types that were not inheriting UnityEngine.Object, we decided to remove most usages for consistency. This will also help avoid accidental mistakes, such as a user reusing a part of this code, but modifying it so that one of those operators are used with a UnityEngine.Object.

### Fixed
* Clarified fix used to handle clients reconnecting to the server while keeping the same active scene and having additional scenes additively loaded (#864)
* Host loading progress bar is now properly updated on all clients during scene loads (#862)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,14 @@ void Update()

public void SaveSceneSetup()
{
ChildScenesToLoadConfig ??= new List<SceneAsset>();
ChildScenesToLoadConfig.Clear();
if (ChildScenesToLoadConfig == null)
{
ChildScenesToLoadConfig = new List<SceneAsset>();
}
else
{
ChildScenesToLoadConfig.Clear();
}
foreach (var sceneSetup in EditorSceneManager.GetSceneManagerSetup())
{
ChildScenesToLoadConfig.Add(AssetDatabase.LoadAssetAtPath<SceneAsset>(sceneSetup.path));
Expand Down
Loading