You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
157 lines
6.3 KiB
C#
157 lines
6.3 KiB
C#
2 weeks ago
|
using System;
|
||
|
using System.Collections;
|
||
|
using Unity.BossRoom.ApplicationLifecycle.Messages;
|
||
|
using Unity.BossRoom.ConnectionManagement;
|
||
|
using Unity.BossRoom.Gameplay.GameState;
|
||
|
using Unity.BossRoom.Gameplay.Messages;
|
||
|
using Unity.BossRoom.Infrastructure;
|
||
|
using Unity.BossRoom.UnityServices;
|
||
|
using Unity.BossRoom.UnityServices.Auth;
|
||
|
using Unity.BossRoom.UnityServices.Lobbies;
|
||
|
using Unity.BossRoom.Utils;
|
||
|
using Unity.Netcode;
|
||
|
using UnityEngine;
|
||
|
using UnityEngine.SceneManagement;
|
||
|
using VContainer;
|
||
|
using VContainer.Unity;
|
||
|
|
||
|
namespace Unity.BossRoom.ApplicationLifecycle
|
||
|
{
|
||
|
/// <summary>
|
||
|
/// An entry point to the application, where we bind all the common dependencies to the root DI scope.
|
||
|
/// </summary>
|
||
|
public class ApplicationController : LifetimeScope
|
||
|
{
|
||
|
[SerializeField]
|
||
|
UpdateRunner m_UpdateRunner;
|
||
|
[SerializeField]
|
||
|
ConnectionManager m_ConnectionManager;
|
||
|
[SerializeField]
|
||
|
NetworkManager m_NetworkManager;
|
||
|
|
||
|
LocalLobby m_LocalLobby;
|
||
|
LobbyServiceFacade m_LobbyServiceFacade;
|
||
|
|
||
|
IDisposable m_Subscriptions;
|
||
|
|
||
|
protected override void Configure(IContainerBuilder builder)
|
||
|
{
|
||
|
base.Configure(builder);
|
||
|
builder.RegisterComponent(m_UpdateRunner);
|
||
|
builder.RegisterComponent(m_ConnectionManager);
|
||
|
builder.RegisterComponent(m_NetworkManager);
|
||
|
|
||
|
//the following singletons represent the local representations of the lobby that we're in and the user that we are
|
||
|
//they can persist longer than the lifetime of the UI in MainMenu where we set up the lobby that we create or join
|
||
|
builder.Register<LocalLobbyUser>(Lifetime.Singleton);
|
||
|
builder.Register<LocalLobby>(Lifetime.Singleton);
|
||
|
|
||
|
builder.Register<ProfileManager>(Lifetime.Singleton);
|
||
|
|
||
|
builder.Register<PersistentGameState>(Lifetime.Singleton);
|
||
|
|
||
|
//these message channels are essential and persist for the lifetime of the lobby and relay services
|
||
|
// Registering as instance to prevent code stripping on iOS
|
||
|
builder.RegisterInstance(new MessageChannel<QuitApplicationMessage>()).AsImplementedInterfaces();
|
||
|
builder.RegisterInstance(new MessageChannel<UnityServiceErrorMessage>()).AsImplementedInterfaces();
|
||
|
builder.RegisterInstance(new MessageChannel<ConnectStatus>()).AsImplementedInterfaces();
|
||
|
builder.RegisterInstance(new MessageChannel<DoorStateChangedEventMessage>()).AsImplementedInterfaces();
|
||
|
|
||
|
//these message channels are essential and persist for the lifetime of the lobby and relay services
|
||
|
//they are networked so that the clients can subscribe to those messages that are published by the server
|
||
|
builder.RegisterComponent(new NetworkedMessageChannel<LifeStateChangedEventMessage>()).AsImplementedInterfaces();
|
||
|
builder.RegisterComponent(new NetworkedMessageChannel<ConnectionEventMessage>()).AsImplementedInterfaces();
|
||
|
#if UNITY_EDITOR || DEVELOPMENT_BUILD
|
||
|
builder.RegisterComponent(new NetworkedMessageChannel<CheatUsedMessage>()).AsImplementedInterfaces();
|
||
|
#endif
|
||
|
|
||
|
//this message channel is essential and persists for the lifetime of the lobby and relay services
|
||
|
builder.RegisterInstance(new MessageChannel<ReconnectMessage>()).AsImplementedInterfaces();
|
||
|
|
||
|
//buffered message channels hold the latest received message in buffer and pass to any new subscribers
|
||
|
builder.RegisterInstance(new BufferedMessageChannel<LobbyListFetchedMessage>()).AsImplementedInterfaces();
|
||
|
|
||
|
//all the lobby service stuff, bound here so that it persists through scene loads
|
||
|
builder.Register<AuthenticationServiceFacade>(Lifetime.Singleton); //a manager entity that allows us to do anonymous authentication with unity services
|
||
|
|
||
|
//LobbyServiceFacade is registered as entrypoint because it wants a callback after container is built to do it's initialization
|
||
|
builder.RegisterEntryPoint<LobbyServiceFacade>(Lifetime.Singleton).AsSelf();
|
||
|
}
|
||
|
|
||
|
private void Start()
|
||
|
{
|
||
|
m_LocalLobby = Container.Resolve<LocalLobby>();
|
||
|
m_LobbyServiceFacade = Container.Resolve<LobbyServiceFacade>();
|
||
|
|
||
|
var quitApplicationSub = Container.Resolve<ISubscriber<QuitApplicationMessage>>();
|
||
|
|
||
|
var subHandles = new DisposableGroup();
|
||
|
subHandles.Add(quitApplicationSub.Subscribe(QuitGame));
|
||
|
m_Subscriptions = subHandles;
|
||
|
|
||
|
Application.wantsToQuit += OnWantToQuit;
|
||
|
DontDestroyOnLoad(gameObject);
|
||
|
DontDestroyOnLoad(m_UpdateRunner.gameObject);
|
||
|
Application.targetFrameRate = 120;
|
||
|
SceneManager.LoadScene("MainMenu");
|
||
|
}
|
||
|
|
||
|
protected override void OnDestroy()
|
||
|
{
|
||
|
if (m_Subscriptions != null)
|
||
|
{
|
||
|
m_Subscriptions.Dispose();
|
||
|
}
|
||
|
|
||
|
if (m_LobbyServiceFacade != null)
|
||
|
{
|
||
|
m_LobbyServiceFacade.EndTracking();
|
||
|
}
|
||
|
|
||
|
base.OnDestroy();
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// In builds, if we are in a lobby and try to send a Leave request on application quit, it won't go through if we're quitting on the same frame.
|
||
|
/// So, we need to delay just briefly to let the request happen (though we don't need to wait for the result).
|
||
|
/// </summary>
|
||
|
private IEnumerator LeaveBeforeQuit()
|
||
|
{
|
||
|
// 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()
|
||
|
{
|
||
|
Application.wantsToQuit -= OnWantToQuit;
|
||
|
|
||
|
var canQuit = m_LocalLobby != null && string.IsNullOrEmpty(m_LocalLobby.LobbyID);
|
||
|
if (!canQuit)
|
||
|
{
|
||
|
StartCoroutine(LeaveBeforeQuit());
|
||
|
}
|
||
|
|
||
|
return canQuit;
|
||
|
}
|
||
|
|
||
|
private void QuitGame(QuitApplicationMessage msg)
|
||
|
{
|
||
|
#if UNITY_EDITOR
|
||
|
UnityEditor.EditorApplication.isPlaying = false;
|
||
|
#else
|
||
|
Application.Quit();
|
||
|
#endif
|
||
|
}
|
||
|
}
|
||
|
}
|