using asap.core; using asap.core.common; using game; using Game; using GameCore; using MoreMountains.NiceVibrations; using Newtonsoft.Json.Linq; using System; using System.IO; using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; using TimeManager; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Networking; using UnityEngine.Rendering.Universal; public class SubBoostrap { public static async System.Threading.Tasks.Task RegisterServices(GameObject rootCtxGo) { var container = GContext.container; VibrationController vibrationController = new VibrationController(); vibrationController.Init(); container.RegisterInstance(vibrationController); container.Register().AsSingleton(); using (container.InjectionScope()) { container.Register().AsSingleton(); container.Register().AsSingleton(); container.Register().AsSingleton(); container.Register().AsSingleton(); } /* * _____ ___ ____ ___ *|_ _/ _ \| _ \ / _ \ * | || | | | | | | | | | * | || |_| | |_| | |_| | * |_| \___/|____/ \___/ */ // TODO Refactor all managers #if UNITY_EDITOR UnityEngine.Application.runInBackground = true; GameCore.GameEventMgr.Init(true); #else GameCore.GameEventMgr.Init(); #endif rootCtxGo.AddComponent(); // TODO Replace DataCenter with seprated data class // Create(); // ----------------------------------------- await Awaiters.NextFrame; GameCore.Timer.Create(); //-----------------------TODO-------------------------- Debug.Log("[HotUpateBoostrap] RegisterServices Done"); await Awaiters.NextFrame; } public static async System.Threading.Tasks.Task AfterAssetUpdate(IConfig config, Action progressAction) { #if UNITY_EDITOR var tables = await cfg.Tables.InitEditor(progress => progressAction(0.16f + progress * 0.02f)); #else var tables = await cfg.Tables.Init(progress => progressAction(0.16f + progress * 0.02f)); #endif var container = GContext.container; GContext.container.RegisterInstance(tables); GContext.container.Register().AsSingleton(); GContext.container.Register().AsSingleton(); GContext.container.Register().AsSingleton(); GContext.container.Register().AsSingleton(); GContext.container.Register().AsSingleton(); GContext.container.Register().AsSingleton(); GContext.container.Register().AsSingleton(); GContext.container.RegisterInstance(new AvatarService()); // removed module var settings = new DefaultSettingService(); settings.Init(tables); GContext.container.RegisterInstance(settings); GameCore.LocalizationMgr.Init(); QualityManager.AutoSetQualityLevel(); RootCtx.showFPS = !string.IsNullOrEmpty(config.Get(GConstant.K_FPS, string.Empty)); DebugFunc.Init(); zzwater.URPHelper.RendererFeatureSetActive(false, "FSBlur"); zzwater.URPHelper.RendererFeatureSetActive(false, "FSWave"); await InitVibration(); //#if UNITY_ANDROID //RequestAndriodPermission(); //#endif await Awaiters.NextFrame; await GContext.container.Resolve().Init(); IAdsService adsService = new DevAdsService(); adsService.Init(); GContext.container.RegisterInstance(adsService); Debug.Log("[HotUpateBoostrap] AfterAssetUpdate Done"); } public static async System.Threading.Tasks.Task ShowLoadingScreen(IConfig config, GameObject rootCtxGo) { var fxClick = await Addressables.InstantiateAsync("TopUIFX").Task; if (fxClick != null) { fxClick.name = "TopUIFX"; GameObject.DontDestroyOnLoad(fxClick); } else { Debug.LogError("TopUIFX is null"); } // TODO replace with new UI service await GameCore.UIManager.Init( UITypes.UIRoot, GameCore.ScreenType.PORTRAIT, () => MessageDialog.ShowErrorDialog(-20, "Default Waiting Timeout") ); var uiCam = rootCtxGo.FindChildGameObject("UICamera").GetComponent(); var ui3DCam = rootCtxGo.FindChildGameObject("UI3DCamera").GetComponent(); UIManager.SetUICamera(uiCam, ui3DCam); //Camera.main.SetCamStack(); await LoadingScreen.Show(0.19f); //LoadingScreen.SetVersionInfo($"Ver {Application.version}"); var reVer = VersionTool.FromString(config.Get(GConstant.K_Ver, string.Empty)); Debug.Log($"[SubBoostrap] Saving local version to buildver.txt: {reVer.ToVerString()} (from remote config)"); reVer.Save(); LoadingScreen.SetVersionInfo(reVer.ToVerString()); Debug.Log("[HotUpateBoostrap] ShowLoadingScreen Done"); } private static async Task InitVibration() { var data = await Addressables.LoadAssetAsync("vibrationdata").Task; if (null != data) { var jsonData = JObject.Parse(data.text); if (jsonData.ContainsKey("Soft")) { var soft = jsonData["Soft"]; MMVibrationManager.SoftDuration = soft["duration"].Value(); MMVibrationManager.SoftAmplitude = soft["amplitude"].Value(); } if (jsonData.ContainsKey("Rigid")) { var rigid = jsonData["Rigid"]; MMVibrationManager.RigidDuration = rigid["duration"].Value(); MMVibrationManager.RigidAmplitude = rigid["amplitude"].Value(); } if (jsonData.ContainsKey("Light")) { var light = jsonData["Light"]; MMVibrationManager.LightDuration = light["duration"].Value(); MMVibrationManager.LightAmplitude = light["amplitude"].Value(); } if (jsonData.ContainsKey("Heavy")) { var heavy = jsonData["Heavy"]; MMVibrationManager.LightDuration = heavy["duration"].Value(); MMVibrationManager.LightAmplitude = heavy["amplitude"].Value(); } if (jsonData.ContainsKey("Medium")) { var medium = jsonData["Medium"]; MMVibrationManager.LightDuration = medium["duration"].Value(); MMVibrationManager.LightAmplitude = medium["amplitude"].Value(); } } } //#if UNITY_ANDROID //private static void RequestAndriodPermission() //{ //if(!UnityEngine.Android.Permission.HasUserAuthorizedPermission("android.permission.QUERY_ALL_PACKAGES")) //{ //UnityEngine.Android.Permission.RequestUserPermission("android.permission.QUERY_ALL_PACKAGES"); //} //} //#endif } // public static class CameraExtension // { // public static void SetCamStack(this Camera cam) // { // if (cam != Camera.main) return; // // For URP rendering, add UICamera into main scene camera's stack // // // Camera ui_cam = null; // // if (GameCore.UIManager.Instance != null) // { // ui_cam = GameCore.UIManager.Instance.UICamera; // } // // if (ui_cam != null && cam != ui_cam) // { // var cam_stack = cam.GetUniversalAdditionalCameraData().cameraStack; // // if (!cam_stack.Contains(ui_cam)) // { // cam_stack.Add(ui_cam); // } // } // } // } #if UNITY_EDITOR public class InternalEditorBoost { public static async Task Boost() { UnityEngine.Debug.Log("Editor Internal Boot"); GContext.container.Register().AsSingleton(); await GameCore.UIManager.Init( UITypes.UIRoot, GameCore.ScreenType.PORTRAIT, () => MessageDialog.ShowErrorDialog(-20, "Default Waiting Timeout") ); var ieb = new InternalEditorBoost(); await ieb.LoadConfig(); await ieb.Init(); } private async Task LoadConfig() { var config = GContext.container.Resolve(); // Load Debug Config var debugConfigPath = Path.Combine(Application.persistentDataPath, GConstant.V_Debug_Config_Path); string remoteConfigUrl = null; SimpleJSON.JSONNode debugConfig = null; if (File.Exists(debugConfigPath)) { #if UNITY_EDITOR Debug.Log($"Debug config [{debugConfigPath}] in use"); #endif debugConfig = SimpleJSON.JSON.Parse(File.ReadAllText(debugConfigPath)); if (debugConfig.HasKey(GConstant.K_Static_Res_URL)) { remoteConfigUrl = debugConfig[GConstant.K_Static_Res_URL]; #if UNITY_EDITOR Debug.Log($"Debug Static Res URL => {remoteConfigUrl}"); #endif } } var staticResURL = GConstant.V_Static_Res_URL; if (ChannelManager.IsRustoreStore) staticResURL = GConstant.V_Static_Res_URL_RU; // load remote Config remoteConfigUrl = remoteConfigUrl ?? string.Format(staticResURL, VersionTool.PackVer); var request = UnityWebRequest.Get($"{remoteConfigUrl}/{GConstant.V_Remote_Config_Path}"); await request.SendWebRequest(); if (request.result != UnityWebRequest.Result.Success) throw new Exception($"Load Config Error: {request.error}"); string remoteConfigStr = request.downloadHandler.text; var remoteConfig = SimpleJSON.JSON.Parse(remoteConfigStr); // Merge Configs foreach (var element in remoteConfig) { config.Set(element.Key, element.Value.Value); } if (null != debugConfig) { foreach (var element in debugConfig) { config.Set(element.Key, element.Value.Value); } } // Change Addressable remote location, using custom assetbundle server var customAddressableRemoteURL = config.Get(GConstant.K_Custom_Addressable, string.Empty); var originAddressableRemoteURL = config.Get(GConstant.K_Origin_Addressable, string.Empty); if (!string.IsNullOrEmpty(customAddressableRemoteURL) && !string.IsNullOrEmpty(originAddressableRemoteURL)) { var ctx = (RootCtx)typeof(GContext).GetField("root", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static).GetValue(null); ctx.ChangeAddressableRemoteUrl(customAddressableRemoteURL, originAddressableRemoteURL); } Debug.Log($"[LoadConfig] StaticResURL: {remoteConfigUrl}"); Debug.Log($"[LoadConfig] Custom_Addressable_URL: {config.Get(GConstant.K_Custom_Addressable, "N/A")}"); Debug.Log($"[LoadConfig] Origin_Addressable_URL: {config.Get(GConstant.K_Origin_Addressable, "N/A")}"); // 验证远端资源可访问性 await Addressables.InitializeAsync().Task; var checkHandle = Addressables.LoadResourceLocationsAsync("building101"); await checkHandle.Task; Debug.Log($"[LoadConfig] Resource locations for 'building101': {checkHandle.Result.Count}"); if (checkHandle.Result.Count > 0) { foreach (var loc in checkHandle.Result) { Debug.Log($"[LoadConfig] Resource URL: {loc.InternalId}"); break; } var sizeHandle = Addressables.GetDownloadSizeAsync("building101"); await sizeHandle.Task; Debug.Log($"[LoadConfig] Download size for 'building101': {sizeHandle.Result / (1024f * 1024f):0.00} MB"); Addressables.Release(sizeHandle); } Addressables.Release(checkHandle); } private async Task Init() { var tables = await cfg.Tables.Init(x => { Debug.Log(x); }); GContext.container.RegisterInstance(tables); GContext.container.Register().AsSingleton(); GContext.container.Register().AsSingleton(); GContext.container.Register().AsSingleton(); GContext.container.Register().AsSingleton(); GContext.container.Register().AsSingleton(); GContext.container.Register().AsSingleton(); GContext.container.Register().AsSingleton(); GContext.container.Register().AsSingleton(); using (var scope = GContext.container.InjectionScope()) { // IAdsService 在 AfterAssetUpdate 中手动注册并调用 Init(),此处不再重复注册 GContext.container.Register().AsSingleton(); GContext.container.Register().AsSingleton(); GContext.container.Register().AsSingleton(); // removed module GContext.container.Register().AsSingleton(); GContext.container.Register().AsSingleton(); GContext.container.Register().AsSingleton(); GContext.container.Register().AsSingleton(); // removed module GContext.container.Register().AsSingleton(); } var settings = new DefaultSettingService(); settings.Init(tables); GContext.container.RegisterInstance(settings); GameCore.LocalizationMgr.Init(); await GContext.container.Resolve().Init(); } } #endif