您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

156 行
6.8 KiB

using System;
using System.Collections;
using BossRoom.Scripts.Shared.Net.UnityServices.Auth;
using Unity.Multiplayer.Samples.BossRoom.ApplicationLifecycle.Messages;
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 UnityEngine;
using UnityEngine.SceneManagement;
using VContainer;
using VContainer.Unity;
namespace Unity.Multiplayer.Samples.BossRoom.Shared
{
/// <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;
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);
//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);
//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.RegisterInstance(new NetworkedMessageChannel<LifeStateChangedEventMessage>()).AsImplementedInterfaces();
builder.RegisterInstance(new NetworkedMessageChannel<ConnectionEventMessage>()).AsImplementedInterfaces();
#if UNITY_EDITOR || DEVELOPMENT_BUILD
builder.RegisterInstance(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();
}
#if UNITY_EDITOR && UNITY_SERVER
void OnGUI()
{
var styleToUse = GUI.skin.label;
styleToUse.fontSize = 50;
styleToUse.alignment = TextAnchor.LowerLeft;
var textToDisplay = "Dedicated Server Running";
var textWidth = styleToUse.fontSize * textToDisplay.Length;
GUI.Label(new Rect(10, 10, textWidth, styleToUse.fontSize * 2), textToDisplay, styleToUse);
}
#endif
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;
if (DedicatedServerUtilities.IsServerBuildTarget)
{
// skip main menu and start IP server directly
SceneManager.LoadScene(SceneNames.DedicatedServerLobbyManagement);
}
else
{
SceneManager.LoadScene(SceneNames.StartupClient, LoadSceneMode.Additive);
SceneManager.LoadScene(SceneNames.MainMenu);
}
}
protected override void OnDestroy()
{
m_Subscriptions?.Dispose();
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()
{
var canQuit = 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
}
}
}