374 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C#
		
	
	
			
		
		
	
	
			374 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C#
		
	
	
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.0";
 | 
						|
        public const string Tag = "[Guru]";
 | 
						|
        public const string ServicesConfigKey = "guru_services";
 | 
						|
        
 | 
						|
        private static GuruSDK _instance;
 | 
						|
        /// <summary>
 | 
						|
        /// 单利引用
 | 
						|
        /// </summary>
 | 
						|
        public static GuruSDK Instance
 | 
						|
        {
 | 
						|
            get
 | 
						|
            {
 | 
						|
                if(null == _instance)
 | 
						|
                {
 | 
						|
                    _instance = CreateInstance();
 | 
						|
                }
 | 
						|
                return _instance;
 | 
						|
            }
 | 
						|
            
 | 
						|
        }
 | 
						|
 | 
						|
        private GuruSDKInitConfig _initConfig;
 | 
						|
        private Action<bool> _onCompleteCallback;
 | 
						|
 | 
						|
        private static GuruSDKModel _model;
 | 
						|
 | 
						|
        internal static GuruSDKInitConfig InitConfig => Instance._initConfig;
 | 
						|
        internal static GuruSDKModel Model => GuruSDKModel.Instance;
 | 
						|
        private static GuruServicesConfig _appServicesConfig;
 | 
						|
        
 | 
						|
        /// <summary>
 | 
						|
        /// Debug Mode
 | 
						|
        /// </summary>
 | 
						|
        public static bool IsDebugMode
 | 
						|
        {
 | 
						|
            get
 | 
						|
            {
 | 
						|
#if UNITY_EDITOR || DEBUG
 | 
						|
                return true;
 | 
						|
#endif
 | 
						|
                return false;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// 初始化成功标志位
 | 
						|
        /// </summary>
 | 
						|
        public static bool IsInitialSuccess { get; private set; } = false;
 | 
						|
 | 
						|
        #region 初始化
 | 
						|
        
 | 
						|
        private static GuruSDK CreateInstance()
 | 
						|
        {
 | 
						|
            var go = new GameObject(nameof(GuruSDK));
 | 
						|
            DontDestroyOnLoad(go);
 | 
						|
            _instance = go.AddComponent<GuruSDK>();
 | 
						|
            return _instance;
 | 
						|
        }
 | 
						|
 | 
						|
        public static GuruSDKInitConfig BuildConfig(
 | 
						|
            bool useCustomConsent = false, 
 | 
						|
            bool autoLoadAds = true, 
 | 
						|
            bool iapEnabled = true, 
 | 
						|
            bool autoRecordFinishedLevels = true, 
 | 
						|
            bool showDebugLog = false,
 | 
						|
            Dictionary<string, object> defaultRemoteData = null,
 | 
						|
            byte[] googleKeys = null,
 | 
						|
            byte[] appleRootCerts = null)
 | 
						|
        {
 | 
						|
            var config = GuruSDKInitConfig.Build(useCustomConsent, autoLoadAds, iapEnabled, 
 | 
						|
                autoRecordFinishedLevels, showDebugLog, defaultRemoteData, googleKeys, appleRootCerts);
 | 
						|
            return config;
 | 
						|
        }
 | 
						|
 | 
						|
        public static void Init(Action<bool> onComplete)
 | 
						|
        {
 | 
						|
            Init(GuruSDKInitConfig.Build(), onComplete);
 | 
						|
        }
 | 
						|
        
 | 
						|
        public static void Init(GuruSDKInitConfig config, Action<bool> onComplete)
 | 
						|
        {
 | 
						|
            LogI($"---- Guru SDK init ----\n{config.ToString()}");
 | 
						|
            Instance.StartWithConfig(config, onComplete);
 | 
						|
        }
 | 
						|
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// 启动SDK
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="config"></param>
 | 
						|
        /// <param name="onComplete"></param>
 | 
						|
        private void StartWithConfig(GuruSDKInitConfig config, Action<bool> onComplete)
 | 
						|
        {
 | 
						|
            Model.PropBLevel.OnValueChanged += OnBLevelChanged;
 | 
						|
            Model.PropBPlay.OnValueChanged += OnBPlayChanged;
 | 
						|
            
 | 
						|
            _initConfig = config;
 | 
						|
            _onCompleteCallback = onComplete;
 | 
						|
            IsInitialSuccess = false;
 | 
						|
            
 | 
						|
            //--- 之后的逻辑放在 Start 方法内 ---
 | 
						|
        }
 | 
						|
 | 
						|
        void Start()
 | 
						|
        {
 | 
						|
            //---- Init All tools ----
 | 
						|
            // Loom.StartUp();
 | 
						|
            
 | 
						|
            //---------- Start Firebase ------------
 | 
						|
            FirebaseUtil.InitFirebase(OnFirebaseReady);
 | 
						|
            // FirebaseUtil.OnFetchRemoteSuccess+= OnFetchRemoteCallback;
 | 
						|
            //---------- Start Facebook ------------
 | 
						|
            FBService.Instance.StartService();
 | 
						|
        }
 | 
						|
        
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// 开始各种组件初始化
 | 
						|
        /// </summary>
 | 
						|
        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);
 | 
						|
        }
 | 
						|
        
 | 
						|
        /// <summary>
 | 
						|
        /// 注入云控参数基础数据
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="dict"></param>
 | 
						|
        /// <returns></returns>
 | 
						|
        private Dictionary<string, object> BuildDefaultRemoteData(Dictionary<string, object> dict)
 | 
						|
        {
 | 
						|
            if (dict == null) dict = new Dictionary<string, object>(3);
 | 
						|
            
 | 
						|
            // 注入默认的 Services 配置值
 | 
						|
            string json = Model.LoadDefaltServicesConfigJson(); 
 | 
						|
            if (!string.IsNullOrEmpty(json)) dict[ServicesConfigKey] = json;
 | 
						|
       
 | 
						|
            return dict;
 | 
						|
        }
 | 
						|
        
 | 
						|
        /// <summary>
 | 
						|
        /// 拉取云控参数完成
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="success"></param>
 | 
						|
        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 guruSettings = GuruSettings.Instance;
 | 
						|
            
 | 
						|
            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.tch020_val > 0)
 | 
						|
                {
 | 
						|
                    Analytics.EnableTch02Event = true;
 | 
						|
                    Analytics.SetTch02TargetValue(_appServicesConfig.app_settings.tch020_val);
 | 
						|
                }
 | 
						|
            }
 | 
						|
            
 | 
						|
            // AdjustService.StartService();
 | 
						|
            
 | 
						|
            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<GuruServicesConfig>(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 ?? "";
 | 
						|
 | 
						|
        #endregion
 | 
						|
        
 | 
						|
        #region Misc
 | 
						|
        
 | 
						|
        /// <summary>
 | 
						|
        /// 打开页面
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="url"></param>
 | 
						|
        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 生命周期
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// 暂停时处理
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="paused"></param>
 | 
						|
        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 延迟处理
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// 启动协程
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="enumerator"></param>
 | 
						|
        /// <returns></returns>
 | 
						|
        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);
 | 
						|
        }
 | 
						|
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// 延时执行
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="seconds"></param>
 | 
						|
        /// <param name="callback"></param>
 | 
						|
        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
 | 
						|
        
 | 
						|
    }
 | 
						|
} |