123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237 |
- using TFramework;
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using System;
- using UnityEngine.Networking;
- #if HybridCLR
- using HybridCLR;
- #endif
- namespace TModule.Runtime {
- public class HotfixManager : MonoBehaviour
- {
- public bool m_isEnableHotfix = true;
- public string m_resServerUrl;
- public string m_updateHandle;
- public string m_versionFileName;
- /// <summary>
- ///本地资源存放路径
- /// </summary>
- public string LocalResFilePath { get; private set; }
- /// <summary>
- /// 本地版本文件存放路径
- /// </summary>
- private string _loaclVersionPath;
- /// <summary>
- /// 待下载资源列表
- /// </summary>
- private List<VersionDataEntity> _NeedDownloadResList = new List<VersionDataEntity>();
- /// <summary>
- /// 本地资源列表
- /// </summary>
- private List<VersionDataEntity> _LocalResList = new List<VersionDataEntity>();
- /// <summary>
- /// 检查版本文件进行事件
- /// </summary>
- private Action<float> OnCheckVersion;
- /// <summary>
- /// 版本文件检查完成事件
- /// </summary>
- private Action<float> OnCheckVersionOver;
- /// <summary>
- /// 版本文件检查出错事件
- /// </summary>
- private Action<string> OnCheckVersionError;
- /// <summary>
- /// 检查进度
- /// </summary>
- private float _checkProgress;
- /// <summary>
- /// 超时时间
- /// </summary>
- public const int DOWNLOADTIMEOUT = 5;
- public float TotalSize
- {
- get
- {
- float szie = 0;
- _NeedDownloadResList.ForEach(p => szie += (float)p.m_size);
- return szie;
- }
- }
- void Start()
- {
- if (m_isEnableHotfix)
- {
- }
- }
- /// <summary>
- /// 检查版本文件
- /// </summary>
- public void InitCheckVersion(Action<float> checkVersion, Action<float> checkVersionOver, Action<string> checkVersionError = null)
- {
- if (string.IsNullOrEmpty(AssetConfig.ResUrl))
- {
- Log.Error("未指定资源服务器地址");
- return;
- }
- OnCheckVersion = checkVersion;
- OnCheckVersionOver = checkVersionOver;
- OnCheckVersionError = checkVersionError;
- _checkProgress = 0;
- string strVersionPath = AssetConfig.ResUrl + m_versionFileName;
- StartCoroutine(DowloadVersion(strVersionPath));
- }
- /// <summary>
- /// 对比版本文件
- /// </summary>
- /// <param name="arg0"></param>
- private void OnInitVersionCallBack(List<VersionDataEntity> arg0)
- {
- _loaclVersionPath = LocalResFilePath + m_versionFileName;
- if (FileOperations.FileExists(_loaclVersionPath))
- {
- List<VersionDataEntity> clienData = FileOperations.ReadJsonData<List<VersionDataEntity>>(_loaclVersionPath);
- foreach (var item in arg0)
- {
- _checkProgress += 1.0f / arg0.Count / 2;
- _checkProgress = _checkProgress >= 1 ? 1 : _checkProgress;
- OnCheckVersion?.Invoke(_checkProgress);
- VersionDataEntity dataEntity = clienData.Find(p => p.m_fullName == item.m_fullName);
- //已有资源
- if (dataEntity != null)
- {
- //对比MD5
- if (dataEntity.m_md5 != item.m_md5)
- _NeedDownloadResList.Add(item);
- }
- else
- _NeedDownloadResList.Add(item);//新资源
- }
- }
- else
- arg0.ForEach(p =>
- {
- _NeedDownloadResList.Add(p);
- _checkProgress += 1.0f / arg0.Count / 2;
- _checkProgress = _checkProgress >= 1 ? 1 : _checkProgress;
- OnCheckVersion?.Invoke(_checkProgress);
- });
- if (_NeedDownloadResList.Count > 0)
- OnCheckVersionOver?.Invoke(TotalSize);
- else
- OnCheckVersionOver?.Invoke(0);
- }
- /// <summary>
- /// 下载版本文件
- /// </summary>
- /// <param name="url"></param>
- /// <param name="OnDownLoadOver"></param>
- /// <returns></returns>
- private IEnumerator DowloadVersion(string url)
- {
- UnityWebRequest www = UnityWebRequest.Get(url);
- www.timeout = DOWNLOADTIMEOUT;
- yield return www.SendWebRequest();
- while (!www.isDone)
- {
- _checkProgress = www.downloadProgress / 2;
- OnCheckVersion?.Invoke(_checkProgress);
- }
- if (www.result != UnityWebRequest.Result.ProtocolError && www.result != UnityWebRequest.Result.ConnectionError)
- {
- string content = www.downloadHandler.text;
- _checkProgress = 0.5f;
- OnInitVersionCallBack(content.JsonStrToObject<List<VersionDataEntity>>());
- Debug.Log(content);
- }
- else
- {
- Debug.Log("下载失败:" + www.error);
- OnCheckVersionError?.Invoke(www.error);
- }
- }
- /// <summary>
- /// 保存版本文件
- /// </summary>
- private void SaveLoaclVersion() => FileOperations.WriteJsonData(_LocalResList, _loaclVersionPath);
- /// <summary>
- /// 更新版本文件
- /// </summary>
- /// <param name="entity"></param>
- public void ModifyLocaData(VersionDataEntity entity)
- {
- if (_LocalResList == null) return;
- bool isExists = false;
- for (int i = 0; i < _LocalResList.Count; i++)
- {
- if (_LocalResList[i].m_fullName.Equals(entity.m_fullName, StringComparison.CurrentCultureIgnoreCase))
- {
- _LocalResList[i].m_md5 = entity.m_md5;
- _LocalResList[i].m_fullName = entity.m_fullName;
- _LocalResList[i].m_size = entity.m_size;
- isExists = true;
- break;
- }
- }
- if (!isExists)
- {
- _LocalResList.Add(entity);
- }
- SaveLoaclVersion();
- }
- private static void LoadMetadataForAOTAssemblies()
- {
- List<string> aotMetaAssemblyFiles = new List<string>()
- {
- "mscorlib.dll",
- "System.dll",
- "System.Core.dll",
- };
- /// 注意,补充元数据是给AOT dll补充元数据,而不是给热更新dll补充元数据。
- /// 热更新dll不缺元数据,不需要补充,如果调用LoadMetadataForAOTAssembly会返回错误
- ///
- #if HybridCLR
- HomologousImageMode mode = HomologousImageMode.SuperSet;
- foreach (var aotDllName in aotMetaAssemblyFiles)
- {
- byte[] dllBytes = FileOperations.SafeReadAllBytes(AssetConfig.AssetBundleRootPath + aotDllName + ".bytes");
- // 加载assembly对应的dll,会自动为它hook。一旦aot泛型函数的native函数不存在,用解释器版本代码
- LoadImageErrorCode err = RuntimeApi.LoadMetadataForAOTAssembly(dllBytes, mode);
- Debug.Log($"LoadMetadataForAOTAssembly:{aotDllName}. mode:{mode} ret:{err}");
- }
- #else
- Log.Error("当前非热更环境!请先安装HybridCLR");
- #endif
- }
- }
- }
|