using System; using System.Collections.Generic; using System.Threading.Tasks; public static class Brisk { private static BriskContext s_context; static Brisk() { Auth = new BriskAuthModule(); Player = new BriskPlayerModule(); Config = new BriskConfigModule(); Announcements = new BriskAnnouncementsModule(); Leaderboard = new BriskLeaderboardModule(); Archive = new BriskArchiveModule(); Space = new BriskSpaceModule(); } public static event Action OnInitialized; public static event Action OnLoggedIn; public static event Action OnLoggedOut; public static event Action OnBlockingError; public static event Action OnAuthExpired; public static BriskAuthModule Auth { get; } public static BriskPlayerModule Player { get; } public static BriskConfigModule Config { get; } public static BriskAnnouncementsModule Announcements { get; } public static BriskLeaderboardModule Leaderboard { get; } public static BriskArchiveModule Archive { get; } public static BriskSpaceModule Space { get; } public static bool IsInitialized => s_context != null; public static bool IsLoggedIn => s_context != null && s_context.Session.HasAccessToken; public static string AccessToken => s_context != null ? s_context.Session.AccessToken : null; public static string PlayerId => s_context != null ? s_context.Session.PlayerId : null; public static BriskIdentity Identity => s_context != null ? s_context.Session.Identity : null; public static BriskOptions Options => s_context != null ? s_context.Options : null; public static BriskBootstrapResult Bootstrap => s_context != null ? s_context.Bootstrap : null; public static async Task InitializeAsync(BriskOptions options) { if (options == null) { throw new ArgumentNullException(nameof(options)); } options.Validate(); var context = new BriskContext(options); s_context = context; try { await BootstrapAsync(context); await RestoreSessionAsync(context); OnInitialized?.Invoke(); } catch { if (context.Bootstrap == null) { s_context = null; } throw; } } public static void Shutdown() { s_context = null; } public static void SetErrorPresenter(IBriskErrorPresenter presenter) { GetRequiredContext().ErrorPresenter = presenter ?? BriskDefaultErrorPresenter.Instance; } public static void SetExitHandler(Action exitHandler) { GetRequiredContext().ExitHandler = exitHandler; } internal static BriskContext GetRequiredContext() { if (s_context == null) { throw new BriskNotInitializedException(); } return s_context; } internal static void NotifyLoggedIn() { OnLoggedIn?.Invoke(); } internal static void NotifyLoggedOut() { OnLoggedOut?.Invoke(); } internal static void NotifyBlockingError(BriskBlockingException exception) { s_context?.ErrorPresenter?.ShowBlockingError(exception); OnBlockingError?.Invoke(exception); } internal static void NotifyAuthExpired(BriskAuthExpiredException exception) { s_context?.ErrorPresenter?.ShowAuthExpired(exception); OnAuthExpired?.Invoke(exception); } private static async Task BootstrapAsync(BriskContext context) { var query = new Dictionary { { "game_key", context.Options.GameKey }, { "client_version", context.Options.ClientVersion }, { "device_id", context.Options.DeviceId } }; var bootstrapData = await context.HttpClient.GetDataAsync("/client/bootstrap", query, false); var bootstrap = BriskModelMapper.ToBootstrapResult(bootstrapData); context.Bootstrap = bootstrap; if (bootstrap.MaintenanceMode) { var message = string.IsNullOrWhiteSpace(bootstrap.MaintenanceMessage) ? "Server is under maintenance." : bootstrap.MaintenanceMessage; var exception = new BriskMaintenanceException(message); NotifyBlockingError(exception); throw exception; } if (BriskVersionComparer.IsLessThan(context.Options.ClientVersion, bootstrap.MinClientVersion)) { var exception = new BriskClientUpdateRequiredException("Client version is lower than the minimum supported version."); NotifyBlockingError(exception); throw exception; } } private static async Task RestoreSessionAsync(BriskContext context) { var storedSession = await context.TokenStore.LoadAsync(); if (storedSession == null || string.IsNullOrWhiteSpace(storedSession.AccessToken)) { return; } context.Session.Update( storedSession.AccessToken, storedSession.ExpiresAt, storedSession.PlayerId, storedSession.ProjectAccountId, storedSession.LoginProvider, storedSession.LoginUserId); if (!context.Options.ValidateSessionOnInitialize) { return; } try { var meData = await context.HttpClient.GetDataAsync("/player/me", null, true); var me = BriskModelMapper.ToPlayerMe(meData); context.Session.Update( storedSession.AccessToken, storedSession.ExpiresAt, me.PlayerId, me.ProjectAccountId, me.LoginProvider, me.LoginUserId); } catch (BriskAuthExpiredException exception) { context.Session.Clear(); await context.TokenStore.ClearAsync(); NotifyAuthExpired(exception); } catch (BriskBlockingException exception) { NotifyBlockingError(exception); throw; } } }