namespace Guru { using UnityEngine; using System; using System.Collections; using System.Collections.Generic; using System.IO; public partial class GuruSDK: MonoBehaviour { public const string Version = "1.0.6"; public const string Tag = "[Guru]"; public const string ServicesConfigKey = "guru_services"; private static GuruSDK _instance; /// /// 单利引用 /// public static GuruSDK Instance { get { if(null == _instance) { _instance = CreateInstance(); } return _instance; } } private GuruSDKInitConfig _initConfig; private Action _onCompleteCallback; private static GuruSDKModel _model; internal static GuruSDKInitConfig InitConfig => Instance._initConfig; internal static GuruSDKModel Model => GuruSDKModel.Instance; private static GuruServicesConfig _appServicesConfig; private static GuruSettings _guruSettings; private static GuruSettings GuruSettings { get { if (_guruSettings == null) _guruSettings = GuruSettings.Instance; return _guruSettings; } } private static bool _isDebugEnabled = false; /// /// Debug Mode /// public static bool IsDebugMode { get { #if UNITY_EDITOR || DEBUG return true; #endif return _isDebugEnabled; } } /// /// 初始化成功标志位 /// public static bool IsInitialSuccess { get; private set; } = false; #region 初始化 private static GuruSDK CreateInstance() { var go = new GameObject(nameof(GuruSDK)); DontDestroyOnLoad(go); _instance = go.AddComponent(); return _instance; } public static GuruSDKInitConfig BuildConfig( bool useCustomConsent = false, bool autoLoadAds = true, bool iapEnabled = true, bool autoRecordFinishedLevels = true, bool debugMode = false, Dictionary defaultRemoteData = null, byte[] googleKeys = null, byte[] appleRootCerts = null) { var config = GuruSDKInitConfig.Build(useCustomConsent, autoLoadAds, iapEnabled, autoRecordFinishedLevels, debugMode, defaultRemoteData, googleKeys, appleRootCerts); return config; } public static void Init(Action onComplete) { Init(GuruSDKInitConfig.Build(), onComplete); } public static void Init(GuruSDKInitConfig config, Action onComplete) { LogI($"---- Guru SDK init ----\n{config.ToString()}"); Instance.StartWithConfig(config, onComplete); } /// /// 启动SDK /// /// /// private void StartWithConfig(GuruSDKInitConfig config, Action onComplete) { Model.PropBLevel.OnValueChanged += OnBLevelChanged; Model.PropBPlay.OnValueChanged += OnBPlayChanged; IsInitialSuccess = false; _initConfig = config; _onCompleteCallback = onComplete; _isDebugEnabled = config.DebugMode; //--- 之后的逻辑放在 Start 方法内 --- } void Start() { //---- Init All tools ---- //---------- Start Firebase ------------ FirebaseUtil.InitFirebase(OnFirebaseReady); // FirebaseUtil.OnFetchRemoteSuccess+= OnFetchRemoteCallback; //---------- Start Facebook ------------ FBService.Instance.StartService(); } /// /// 开始各种组件初始化 /// private void OnFirebaseReady() { IsInitialSuccess = true; if (!InitConfig.UseCustomConsent) { // LogI($"--- #3 Start Consent Flow ---"); StartConsentFlow(); } if(!string.IsNullOrEmpty(IPMConfig.IPM_UID)) SetUID(IPMConfig.IPM_UID); // 开始Remote Manager初始化 RemoteConfigManager.Init(BuildDefaultRemoteData(_initConfig.DefaultRemoteData)); RemoteConfigManager.OnFetchCompleted += OnFetchRemoteCallback; // 根据上次的云控配置来初始化参数 SetupServicesConfig(); _onCompleteCallback?.Invoke(true); } /// /// 注入云控参数基础数据 /// /// /// private Dictionary BuildDefaultRemoteData(Dictionary dict) { if (dict == null) dict = new Dictionary(3); // 注入默认的 Services 配置值 string json = Model.LoadDefaltServicesConfigJson(); if (!string.IsNullOrEmpty(json)) dict[ServicesConfigKey] = json; return dict; } /// /// 拉取云控参数完成 /// /// private void OnFetchRemoteCallback(bool success) { LogI($"--- Remote fetch complete: {success} ---"); ABTestManager.Init(); // 启动AB测试解析器 Callbacks.Remote._onRemoteFetchComplete?.Invoke(success); } #endregion #region App Remote Update private void SetupServicesConfig() { bool useKeywords = true; bool useIAP = true; var services = GetRemoteServicesConfig(); if (services != null) { _appServicesConfig = services; useKeywords = _appServicesConfig.IsKeywordsEnabled(); if (null != GuruSettings) { if(_appServicesConfig.adjust_settings != null) { // 更新 Adjust Tokens GuruSettings.UpdateAdjustTokens(_appServicesConfig.adjust_settings.AndroidToken ,_appServicesConfig.adjust_settings.iOSToken); // 更新 Adjust Events GuruSettings.UpdateAdjustEvents(_appServicesConfig.adjust_settings.events); } } useIAP = _appServicesConfig.IsIAPEnabled(); if (_appServicesConfig.app_settings != null) { if (_appServicesConfig.app_settings.tch020_val > 0) { Analytics.EnableTch02Event = true; Analytics.SetTch02TargetValue(_appServicesConfig.app_settings.tch020_val); } // 更新和升级 GuruSettings 对应的值 GuruSettings.UpdateAppSettings( _appServicesConfig.app_settings.bundle_id, _appServicesConfig.fb_settings.fb_app_id, _appServicesConfig.app_settings.support_email, _appServicesConfig.app_settings.privacy_url, _appServicesConfig.app_settings.terms_url, _appServicesConfig.app_settings.android_store, _appServicesConfig.app_settings.ios_store); } } if(useIAP) { InitIAP(_initConfig.GoogleKeys, _initConfig.AppleRootCerts); // 初始化IAP } if(useKeywords) { KeywordsManager.Install(Model.IsIAPUser, Model.SuccessLevelCount); // 启动Keyword管理器 } } private GuruServicesConfig GetRemoteServicesConfig() { var json = GetRemoteString(ServicesConfigKey); if (!string.IsNullOrEmpty(json)) { return JsonParser.ToObject(json); } return null; } #endregion #region 数据 private void OnBLevelChanged(int blevel) { SetUserBLevel(blevel); } private void OnBPlayChanged(int bplay) { SetUserBPlay(bplay); } public static string UID => _model?.UserId ?? ""; public static string SupportEmail => GuruSettings.SupportEmail ?? ""; public static string StoreUrl { get { string url = ""; #if UNITY_EDITOR url = "https://test@com.guru.ai"; #elif UNITY_ANDROID url = GuruSettings?.AndroidStoreUrl ?? ""; #elif UNITY_IOS url = GuruSettings?.IOSStoreUrl ?? ""; #endif return url; } } #endregion #region Misc /// /// 打开页面 /// /// public static void OpenURL(string url) { GuruWebview.OpenPage(url); } #endregion #region Logging internal static void LogI(object message) { Debug.Log($"{Tag} {message}"); } internal static void LogW(object message) { Debug.LogWarning($"{Tag} {message}"); } internal static void LogE(object message) { Debug.LogError($"{Tag} {message}"); } internal static void LogException(string message) { LogException( new Exception($"{Tag} {message}")); } internal static void LogException(Exception e) { Debug.LogException(e); } #endregion #region 生命周期 /// /// 暂停时处理 /// /// private void OnAppPauseHandler(bool paused) { if(paused) Model.Save(true); // 强制保存数据 Callbacks.App._onAppPaused?.Invoke(paused); } private void OnApplicationPause(bool paused) { OnAppPauseHandler(paused); } private void OnApplicationFocus(bool hasFocus) { OnAppPauseHandler(!hasFocus); } private void OnApplicationQuit() { Model.Save(true); Callbacks.App._onAppQuit?.Invoke(); } #endregion #region 延迟处理 /// /// 启动协程 /// /// /// public static Coroutine DoCoroutine(IEnumerator enumerator) { return Instance != null ? Instance.StartCoroutine(enumerator) : null; } public static void KillCoroutine(Coroutine coroutine) { if(coroutine != null) Instance.StopCoroutine(coroutine); } /// /// 延时执行 /// /// /// public static void Delay(float seconds, Action callback) { DoCoroutine(Instance.OnDelayCall(seconds, callback)); } private IEnumerator OnDelayCall(float delay, Action callback) { if (delay > 0) { yield return new WaitForSeconds(delay); } else { yield return null; } callback?.Invoke(); } #endregion } }