NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/HotUpdate/GameLauncher.cs

303 lines
10 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using HotUpdate.UI;
using Cysharp.Threading.Tasks;
using PhxhSDK.AOT;
using PhxhSDK.AOT.SimpleLoader;
using PhxhSDK.AOT.VersionUpdate;
using System;
using PhxhSDK.AOT.PreConfig;
using UnityEngine;
using UnityEngine.SceneManagement;
using Assets.PhxhSDK.AOT.BI;
using Obfuz.EncryptionVM;
using Obfuz;
#if PLATFORM_ANDROID || UNITY_EDITOR
using UnityEngine.Android;
#endif
#if SDK_BILIBILI
using PhxhSDK.AOT.Bilibili;
#endif
public class GameLauncher : MonoBehaviour
{
private static bool _isSetUpStaticSecret = false;
/// <summary>
/// 初始化EncryptionService后被混淆的代码才能正常运行
/// 因此尽可能地早地初始化它。
/// </summary>
[ObfuzIgnore]
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)]
private static void _SetUpStaticSecretKey()
{
if (_isSetUpStaticSecret)
{
return;
}
_isSetUpStaticSecret = true;
Debug.Log("[Obfz] SetUpStaticSecret begin");
var loadedAsset = Resources.Load<TextAsset>("us5af47s54fsa1z90sf");
if (loadedAsset == null)
{
Debug.LogError("[Obfz] SetUpStaticSecret failed: could not load static secret asset");
return;
}
EncryptionService<DefaultStaticEncryptionScope>.Encryptor = new GeneratedEncryptionVirtualMachine(loadedAsset.bytes);
Debug.Log("[Obfz] SetUpStaticSecret end");
}
private static void _SetUpDynamicSecret(byte[] bytes)
{
Debug.Log("[Obfz] SetUpDynamicSecret begin");
EncryptionService<DefaultDynamicEncryptionScope>.Encryptor = new GeneratedEncryptionVirtualMachine(bytes);
Debug.Log("[Obfz] SetUpDynamicSecret end");
}
private const string START_SCENE_NAME = "Assets/Scenes/StartScene.unity";
private const string DYNAMIC_SECRET_PATH = "Assets/Config/Obfuz/defaultDynamicSecretKey.bytes";
//最大能容忍的下载卡住时长,一旦超过则重新开始下载
// private const float DOWNLOAD_STUCK_TIME_MAX = 10;
#if USE_HCLR
private HybridCLRHelper _hybridCLRHelper;
#endif
private VersionUpdateHandle _versionUpdateHandle;
private ISimpleLoader _simpleLoader;
private IVersionUpdateUI versionUpdateUI;
public bool enableHotUpdate = true;
private void Awake()
{
_SetUpStaticSecretKey();
#if SDK_BILIBILI
GameObject goBiliBiliSDK = new()
{
name = "BiliBiliSDK"
};
if (!goBiliBiliSDK.TryGetComponent<GSCSdkInterface>(out _))
goBiliBiliSDK.AddComponent<GSCSdkInterface>();
if (!goBiliBiliSDK.TryGetComponent<GSCCallbackListerner>(out _))
goBiliBiliSDK.AddComponent<GSCCallbackListerner>();
DontDestroyOnLoad(goBiliBiliSDK);
#endif
}
private void Start()
{
#if SDK_BILIBILI
GSCSdkInterface.init();
#endif
#if SDK_ADJUST
var YourAppToken = "shw96lfwisqo"; // 替换为你的Adjust App Token
AdjustInitTool.Instance.InitAdjustSDK(YourAppToken);
#endif
#if SDK_FIREBASE
Firebase.Analytics.FirebaseAnalytics.LogEvent("First_open");
#endif
versionUpdateUI = new TempUIHandle();
bool agreement = PlayerPrefs.GetInt("PrivacyAgreement", 0) == 1;
BIToolinAOT.Instance.TrackEventInAOT("app_open", null);
if (!agreement) // 弹隐私弹窗
{
TempUpdateUI.Instance.PrivacyAgreeCallback = () =>
{
TempUpdateUI.Instance.m_ProgressObj.SetActive(true);
Launch();
};
TempUpdateUI.Instance.m_PrivacyDialogObj.SetActive(true);
}
else
{
TempUpdateUI.Instance.m_ProgressObj.SetActive(true);
Launch();
}
}
private async void Launch()
{
#if UNITY_EDITOR
enableHotUpdate = false;
#endif
#if PLATFORM_ANDROID && !SDK_BILIBILI //B站在隐私协议之后才申请权限
if (!Permission.HasUserAuthorizedPermission(Permission.ExternalStorageWrite))
{
Debug.Log("申请权限: " + Permission.ExternalStorageWrite);
Permission.RequestUserPermission(Permission.ExternalStorageWrite);
}
#endif
versionUpdateUI.UpdateProgress(0f);
versionUpdateUI.UpdateProgressText(LocalizeMono.Instance.GetLocalizeText("NetworkConnection")); // 尝试网络连接中...
_versionUpdateHandle = new VersionUpdateHandle(versionUpdateUI);
VersionUpdateInfo versionUpdateInfo = _versionUpdateHandle.GetVersionInfo();
PackDataInst.CreateInst();
UpdateLocalInfo localInfo = PackDataInst.Inst.localInfo;
string acquiring = LocalizeMono.Instance.GetLocalizeText("Acquiring"); // 获取中...
versionUpdateUI.ShowVersion(Application.version, localInfo.workSpace, localInfo.localFullVersion, acquiring, acquiring);
string appID = string.Empty;
string channel = string.Empty;
#if SDK_TALKINGDATA
appID = TalkingDataInitTool.appID;
channel = TalkingDataInitTool.channel;
#endif
BIToolinAOT.Instance.Init(appID, channel);//TalkingData初始化
//TalkingData初始化
#if SDK_TALKINGDATA
#if PLATFORM_ANDROID
if (Permission.HasUserAuthorizedPermission(Permission.ExternalStorageWrite))
{
Debug.Log("已申请权限: " + Permission.ExternalStorageWrite);
BIToolinAOT.Instance.TalkingDataStart();
}
#else
BIToolinAOT.Instance.TalkingDataStart();
#endif
#endif
PlayerPrefs.SetString("BI_Platform", TalkingDataInitTool.channel);
#region 更新AppConfig
bool downloadResult;
do
{
try
{
versionUpdateUI.UpdateProgressText(LocalizeMono.Instance.GetLocalizeText("RequestConfiguration")); // 开始请求APPConfig
BIToolinAOT.Instance.TrackEventInAOT("app_config_request", null);
downloadResult = await PreConfig.instance.DownloadConfig();
versionUpdateUI.UpdateProgressText(LocalizeMono.Instance.GetLocalizeText("RequestConfigurationComplete")); // 请求APPConfig结束
versionUpdateUI.ShowVersion(Application.version, localInfo.workSpace, localInfo.localFullVersion, acquiring, PreConfig.instance.ServerName);
BIToolinAOT.Instance.TrackEventInAOT("app_config_response", new System.Collections.Generic.Dictionary<string, object>(){
{"result", downloadResult? 0 : 1 }
});
}
catch (Exception)
{
downloadResult = false;
}
}
while (!downloadResult && await versionUpdateUI.ShowDialog(LocalizeMono.Instance.GetLocalizeText("Tip"), LocalizeMono.Instance.GetLocalizeText("DownloadConfigErrorRetry"))); // 下载配置文件失败,是否重试?
if (!downloadResult)
TempUpdateUI.Instance.OnClickCancel();
#endregion
if (!PreConfig.instance.isConfigValid)
{
// 配置错误,没有读取到ResUrl
Debug.LogError("配置文件错误");
await versionUpdateUI.ShowDialog(LocalizeMono.Instance.GetLocalizeText("Tip"), LocalizeMono.Instance.GetLocalizeText("ConfigError")); // 配置文件错误
TempUpdateUI.Instance.OnClickCancel();
return;
}
await YooAssetHelper.Init();
_simpleLoader = new SimpleLoader_YooAsset();
Debug.Log($"Launch Game! enableHotUpdate:{enableHotUpdate}");
bool result = await _versionUpdateHandle.CheckUpdate();//这里会打点资源检测更新事件
if (!result)
{
Debug.LogError("更新失败!,无法进入游戏");
return;
}
if (enableHotUpdate)
{
#if USE_HCLR
byte[] dynamicSecret = await _simpleLoader.LoadDllBytes(DYNAMIC_SECRET_PATH);
_SetUpDynamicSecret(dynamicSecret);
await _simpleLoader.UnloadDll(DYNAMIC_SECRET_PATH);
Debug.Log("需要热更新,开始加载程序集");
_hybridCLRHelper = new HybridCLRHelper();
_hybridCLRHelper.SetDllList(AOTGenericReferences.PatchedAOTAssemblyList);
_hybridCLRHelper.RegistLoader(_simpleLoader);
await _hybridCLRHelper.LoadAssemblies();
Debug.Log("加载程序集结束!");
#endif
}
await _simpleLoader.WarmUpShader();
await EnterGame();
}
private async UniTask EnterGame()
{
Debug.Log("开始加载游戏场景");
SimulationProgress(versionUpdateUI.GetCurProgress());
try
{
Scene scene = await _simpleLoader.LoadSceneAsync(START_SCENE_NAME, LoadSceneMode.Additive);
foreach (GameObject go in scene.GetRootGameObjects())
{
if ("EventSystem".Equals(go.name))
{
Destroy(go);
break;
}
}
}
catch (Exception e)
{
Debug.LogError(e);
}
finally
{
await LoadOver();
Debug.Log("加载游戏场景结束");
}
}
private async void SimulationProgress(float startProgress)
{
versionUpdateUI.UpdateProgressText(LocalizeMono.Instance.GetLocalizeText("InitGaming")); // 初始化游戏...
versionUpdateUI.UpdateProgress(startProgress);
float step = (1f - startProgress) * 0.02f;
while (startProgress + step <= 0.99f)
{
await UniTask.Delay(20);
startProgress += step;
versionUpdateUI.UpdateProgress(startProgress);
}
}
private async UniTask LoadOver()
{
while (true)
{
await UniTask.Yield();
// Debug.Log($"校验是否加载完:{IVersionUpdateUI.IsLoadOver}");
if (StartSceneLoadingManager.IsLoadOver)
{
versionUpdateUI.UpdateProgress(1f);
versionUpdateUI.UpdateProgressText(LocalizeMono.Instance.GetLocalizeText("Complete")); // 完成
await UniTask.Delay(200);
versionUpdateUI.CloseAll();
await SceneManager.UnloadSceneAsync(0);
return;
}
}
}
}