123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349 |
- using HybridCLR;
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Reflection;
- using System.Threading.Tasks;
- using UnityEngine;
- using UnityEngine.Networking;
- using LitJson;
- using TMPro;
- using UnityEngine.UI;
- public class LoadDll : MonoBehaviour
- {
- public GameObject EditorGame;
- static LoadDll instance;
- private void Awake()
- {
- instance = this;
- }
- void Start()
- {
- this.transform.SetParent(OpenXRCamera.Instance.head.transform);
- this.transform.localPosition = Vector3.zero;
- this.transform.localEulerAngles = Vector3.zero;
- //PlayerPrefs.DeleteAll();
- #if ISLOCAL
- EditorGame.SetActive(true);
- this.gameObject.SetActive(false);
- #else
- StartCoroutine(DownLoadAssets());
- #endif
- }
- private static Dictionary<string, byte[]> s_assetDatas = new Dictionary<string, byte[]>();
- public static byte[] ReadBytesFromStreamingAssets(string dllName)
- {
- return s_assetDatas[dllName];
- }
- private string GetWebRequestPath(string asset)
- {
- var path = $"{Application.streamingAssetsPath}/{asset}";
- if (!path.Contains("://"))
- {
- path = "file://" + path;
- }
- return path;
- }
- private static List<string> AOTMetaAssemblyFiles { get; } = new List<string>()
- {
- "mscorlib.dll.bytes",
- "System.dll.bytes",
- "System.Core.dll.bytes",
- "UniTask.dll.bytes",
- "Minio.dll.bytes",
- "COSXML.dll.bytes",
- "System.Runtime.CompilerServices.Unsafe.dll.bytes"
- };
- public Text text;
- public Text text2;
- public Slider slider;
- string HotUpdateScripts = "HotUpdateScripts";
- string HotUpdateAssets = "HotUpdateAssets";
- IEnumerator DownLoadAssets()
- {
- text.text = "正在获取网关数据";
- for (int i = 0; i < AOTMetaAssemblyFiles.Count; i++)
- {
- yield return DownLoadLocal(AOTMetaAssemblyFiles[i]);
- }
- slider.gameObject.SetActive(false);
- while (HttpSDKAction.Instance.jsonData==null || HttpSDKAction.Instance.jsonData=="")
- {
- yield return null;
- }
- JsonData data = new JsonData();
- string scUrl = "";
- string artUrl = "";
- try
- {
- data = JsonMapper.ToObject(HttpSDKAction.Instance.jsonData);
- scUrl = data[HotUpdateScripts].ToString();
- artUrl = data[HotUpdateAssets].ToString();
- }
- catch
- {
-
- }
- if(scUrl != "")
- {
- if (!bool.Parse(data["isHotUpdate"].ToString()))
- {
- text.text = "正在下载代码";
- yield return DownLoadAssets(scUrl, HotUpdateScripts, false);
- text.text = "正在下载配置";
- yield return DownLoadAssets(artUrl, HotUpdateAssets, false);
- }
- else if (PlayerPrefs.GetString("HotUpdateVersion") == data["HotUpdateVersion"].ToString())
- {
- text.text = "正在编译代码";
- string filePath = PlayerPrefs.GetString(HotUpdateScripts);
- Task<byte[]> Tb = File.ReadAllBytesAsync(filePath);
- yield return Tb;
- slider.gameObject.SetActive(false);
- Assembly.Load(Tb.Result);
- text.text = "正在解析配置";
- filePath = PlayerPrefs.GetString(HotUpdateAssets);
- Task<byte[]> Tb2 = File.ReadAllBytesAsync(filePath);
- yield return Tb2;
- text.text = "正在解析配置";
- slider.gameObject.SetActive(false);
- AssetBundleCreateRequest acr = AssetBundle.LoadFromMemoryAsync(Tb2.Result);
- while (!acr.isDone)
- {
- text2.text = (acr.progress*100).ToString("F2") + "%";
- slider.value = float.Parse((acr.progress ).ToString("F2"));
- yield return null;
- }
- slider.gameObject.SetActive(true);
- AssetBundleRequest abr = acr.assetBundle.LoadAssetAsync<GameObject>("LocalAsset");
- text.text = "正在加载配置";
- while (!abr.isDone)
- {
- text2.text = (abr.progress * 100).ToString("F2") + "%";
- slider.value = float.Parse((abr.progress ).ToString("F2"));
- yield return null;
- }
- copyGameObject(abr.asset);
- this.gameObject.SetActive(false);
- }
- else
- {
- text.text = "正在下载代码";
- yield return DownLoadAssets(scUrl, HotUpdateScripts);
- text.text = "正在下载配置";
- yield return DownLoadAssets(artUrl, HotUpdateAssets);
- }
- }
- else
- {
- text.text = "正在下载代码";
- yield return DownLoadAssets(scUrl, HotUpdateScripts, false);
- text.text = "正在下载配置";
- yield return DownLoadAssets(artUrl, HotUpdateAssets, false);
- }
- }
- public IEnumerator DownLoadLocal(string name)
- {
- slider.gameObject.SetActive(true);
- UnityWebRequest www = UnityWebRequest.Get(GetWebRequestPath(name));
- www.SendWebRequest();
- while (!www.isDone)
- {
- text2.text = (www.downloadProgress * 100).ToString("F2") + "%";
- slider.value = float.Parse((www.downloadProgress).ToString("F2"));
- yield return null;
- }
- #if UNITY_2020_1_OR_NEWER
- if (www.result != UnityWebRequest.Result.Success)
- {
- Debug.Log(www.error);
- }
- #else
- if (www.isHttpError || www.isNetworkError)
- {
- Debug.Log(www.error);
- }
- #endif
- HomologousImageMode mode = HomologousImageMode.SuperSet;
- LoadImageErrorCode err = RuntimeApi.LoadMetadataForAOTAssembly(www.downloadHandler.data, mode);
- Debug.Log($"LoadMetadataForAOTAssembly:{name}. mode:{mode} ret:{err}");
- }
- public IEnumerator DownLoadAssets(string dllPath,string name,bool isRemote=true)
- {
- slider.gameObject.SetActive(true);
- if(!isRemote)
- {
- dllPath = GetWebRequestPath(name);
- }
- UnityWebRequest www = UnityWebRequest.Get(dllPath);
- www.SendWebRequest();
- while (!www.isDone)
- {
- text2.text = (www.downloadProgress * 100).ToString("F2") + "%";
- slider.value = float.Parse((www.downloadProgress ).ToString("F2"));
- yield return null;
- }
- #if UNITY_2020_1_OR_NEWER
- if (www.result != UnityWebRequest.Result.Success)
- {
- Debug.Log(www.error);
- }
- #else
- if (www.isHttpError || www.isNetworkError)
- {
- Debug.Log(www.error);
- }
- #endif
- else
- {
- if(name == HotUpdateScripts)
- {
- text.text = "正在编译代码";
- slider.gameObject.SetActive(false);
- Assembly.Load(www.downloadHandler.data);
- string fileName = HotUpdateScripts;
- if (!Directory.Exists(Application.persistentDataPath + "/HotUpdate"))
- Directory.CreateDirectory(Application.persistentDataPath + "/HotUpdate" );
- string filePathname = Application.persistentDataPath + "/HotUpdate/" + fileName;
- // if (File.Exists(filePathname))
- // File.Delete(filePathname);
- File.WriteAllBytes(filePathname, www.downloadHandler.data);
- PlayerPrefs.SetString(HotUpdateScripts, filePathname);
- }
- else
- {
- text.text = "正在解析配置";
- slider.gameObject.SetActive(false);
- AssetBundleCreateRequest acr = AssetBundle.LoadFromMemoryAsync(www.downloadHandler.data);
- while (!acr.isDone)
- {
- text2.text = (acr.progress * 100).ToString("F2") + "%";
- slider.value = float.Parse((acr.progress ).ToString("F2"));
- yield return null;
- }
- slider.gameObject.SetActive(true);
- AssetBundleRequest abr = acr.assetBundle.LoadAssetAsync<GameObject>("LocalAsset");
- text.text = "正在加载配置";
- while (!abr.isDone)
- {
- text2.text = (abr.progress * 100).ToString("F2") + "%";
- slider.value = float.Parse((abr.progress ).ToString("F2"));
- yield return null;
- }
- copyGameObject(abr.asset);
- this.gameObject.SetActive(false);
- string fileName = HotUpdateAssets;
- if (!Directory.Exists(Application.persistentDataPath + "/HotUpdate"))
- Directory.CreateDirectory(Application.persistentDataPath + "/HotUpdate");
- string filePathname = Application.persistentDataPath + "/HotUpdate/" + fileName;
- // if (File.Exists(filePathname))
- // File.Delete(filePathname);
- File.WriteAllBytes(filePathname, www.downloadHandler.data);
- PlayerPrefs.SetString(HotUpdateAssets, filePathname);
- }
- }
- }
- void copyGameObject(UnityEngine.Object o)
- {
- Instantiate(o);
- }
- private static Assembly _hotUpdateAss;
- /// <summary>
- /// 为aot assembly加载原始metadata, 这个代码放aot或者热更新都行。
- /// 一旦加载后,如果AOT泛型函数对应native实现不存在,则自动替换为解释模式执行
- /// </summary>
- private static void LoadMetadataForAOTAssemblies()
- {
- /// 注意,补充元数据是给AOT dll补充元数据,而不是给热更新dll补充元数据。
- /// 热更新dll不缺元数据,不需要补充,如果调用LoadMetadataForAOTAssembly会返回错误
- ///
- HomologousImageMode mode = HomologousImageMode.SuperSet;
- foreach (var aotDllName in AOTMetaAssemblyFiles)
- {
- byte[] dllBytes = ReadBytesFromStreamingAssets(aotDllName);
- // 加载assembly对应的dll,会自动为它hook。一旦aot泛型函数的native函数不存在,用解释器版本代码
- LoadImageErrorCode err = RuntimeApi.LoadMetadataForAOTAssembly(dllBytes, mode);
- Debug.Log($"LoadMetadataForAOTAssembly:{aotDllName}. mode:{mode} ret:{err}");
- }
- }
- void StartGame()
- {
- // LoadMetadataForAOTAssemblies();
- /*
- #if !UNITY_EDITOR
- _hotUpdateAss = Assembly.Load(ReadBytesFromStreamingAssets("HotUpdate.dll.bytes"));
- #else
- _hotUpdateAss = System.AppDomain.CurrentDomain.GetAssemblies().First(a => a.GetName().Name == "HotUpdate");
- #endif
- */
- // Type entryType = _hotUpdateAss.GetType("Entry");
- // entryType.GetMethod("Start").Invoke(null, null);
- }
- }
|