taochangchun hace 1 mes
commit
ffc6b34bfc
Se han modificado 5 ficheros con 372 adiciones y 0 borrados
  1. 8 0
      Editor.meta
  2. 106 0
      Editor/Prepare.cs
  3. 11 0
      Editor/Prepare.cs.meta
  4. 236 0
      HotfixManager.cs
  5. 11 0
      HotfixManager.cs.meta

+ 8 - 0
Editor.meta

@@ -0,0 +1,8 @@
1
+fileFormatVersion: 2
2
+guid: 419d8cf2d3a8aec41bc2c5148e782adc
3
+folderAsset: yes
4
+DefaultImporter:
5
+  externalObjects: {}
6
+  userData: 
7
+  assetBundleName: 
8
+  assetBundleVariant: 

+ 106 - 0
Editor/Prepare.cs

@@ -0,0 +1,106 @@
1
+using TFramework;
2
+using System.Collections;
3
+using System.Collections.Generic;
4
+using UnityEngine;
5
+using UnityEditor;
6
+using UnityEditor.PackageManager;
7
+using UnityEditor.PackageManager.Requests;
8
+
9
+public class Prepare
10
+{
11
+    private const string PACKAGENAME = "com.code-philosophy.hybridclr";
12
+    private const string PACKAGEGITPATH = "https://github.com/focus-creative-games/hybridclr_unity.git";
13
+    static ListRequest _listRequest;
14
+
15
+    [InitializeOnLoadMethod]
16
+    public static void InitEnv()
17
+    {
18
+        if (CheckInstall()) return;
19
+        _listRequest = Client.List();
20
+        EditorApplication.update += Update;
21
+    }
22
+
23
+    public static bool CheckEnv()
24
+    {
25
+        bool isHaveEnv = false;
26
+        foreach (var info in _listRequest.Result)
27
+        {
28
+            if(info.name==PACKAGENAME)
29
+            {
30
+                isHaveEnv = true;
31
+                break;
32
+            }
33
+        }
34
+        return isHaveEnv;
35
+    }
36
+
37
+    public static bool CheckInstall()
38
+    {
39
+#if HybridCLR
40
+        return new HybridCLR.Editor.Installer.InstallerController().HasInstalledHybridCLR();
41
+#else
42
+        return false;
43
+#endif
44
+    }
45
+
46
+    private static void Update()
47
+    {
48
+        if (_listRequest.IsCompleted)
49
+        {
50
+            if (_listRequest.Status == StatusCode.Success)
51
+            {
52
+                if (!CheckEnv())
53
+                {
54
+                    if (EditorUtility.DisplayDialog("环境检查提示", "当前不存在热更环境,是否导入环境?", "马上导入", "稍后再说"))
55
+                    {
56
+                        AddRequest addRequest = Client.Add(PACKAGEGITPATH);
57
+                        while (!addRequest.IsCompleted)
58
+                        {
59
+                            if (addRequest.Status == StatusCode.InProgress)
60
+                                Debug.Log(addRequest.Status);
61
+                            else
62
+                            {
63
+                                Debug.LogError($"安装热更环境【{PACKAGENAME}】出错");
64
+                                break;
65
+                            }
66
+                        }
67
+                        if (addRequest.IsCompleted)
68
+                        {
69
+                            if (addRequest.Status >= StatusCode.Failure)
70
+                                Debug.LogError(addRequest.Error.message);
71
+                        }
72
+                    }
73
+                }
74
+                else if(!IsAddSymbols())
75
+                {
76
+                    AddDefineSymbols("HybridCLR");
77
+                }
78
+                else if (!CheckInstall())
79
+                {
80
+                    EditorApplication.ExecuteMenuItem("HybridCLR/Installer...");
81
+                }
82
+            }
83
+            else if (_listRequest.Status >= StatusCode.Failure)
84
+                Debug.Log(_listRequest.Error.message);
85
+            EditorApplication.update -= Update;
86
+        }
87
+    }
88
+
89
+    public static void AddDefineSymbols(string symbol)
90
+    {
91
+        BuildTargetGroup buildTargetGroup = EditorUserBuildSettings.selectedBuildTargetGroup;
92
+        string symbols = PlayerSettings.GetScriptingDefineSymbolsForGroup(buildTargetGroup);
93
+        if (symbols.Split(';').Contains(symbol)) return;
94
+        symbols = string.IsNullOrEmpty(symbols) ? symbol : symbols += $";{symbol}";
95
+        PlayerSettings.SetScriptingDefineSymbolsForGroup(buildTargetGroup, symbols);
96
+    }
97
+
98
+    public static bool IsAddSymbols()
99
+    {
100
+#if HybridCLR
101
+        return true;
102
+#else
103
+        return false;
104
+#endif
105
+    }
106
+}

+ 11 - 0
Editor/Prepare.cs.meta

@@ -0,0 +1,11 @@
1
+fileFormatVersion: 2
2
+guid: 2ab7c6bd68a67f04085ed42f0ae988e5
3
+MonoImporter:
4
+  externalObjects: {}
5
+  serializedVersion: 2
6
+  defaultReferences: []
7
+  executionOrder: 0
8
+  icon: {instanceID: 0}
9
+  userData: 
10
+  assetBundleName: 
11
+  assetBundleVariant: 

+ 236 - 0
HotfixManager.cs

@@ -0,0 +1,236 @@
1
+using TFramework;
2
+using System.Collections;
3
+using System.Collections.Generic;
4
+using UnityEngine;
5
+using System;
6
+using UnityEngine.Networking;
7
+#if HybridCLR
8
+using HybridCLR;
9
+#endif
10
+
11
+namespace TModule.Runtime {
12
+    public class HotfixManager : MonoBehaviour
13
+    {
14
+        public bool m_isEnableHotfix = true;
15
+
16
+        public string m_resServerUrl;
17
+
18
+        public string m_updateHandle;
19
+
20
+        public string m_versionFileName;
21
+
22
+        /// <summary>
23
+        ///本地资源存放路径
24
+        /// </summary>
25
+        public string LocalResFilePath { get; private set; }
26
+
27
+        /// <summary>
28
+        /// 本地版本文件存放路径
29
+        /// </summary>
30
+        private string _loaclVersionPath;
31
+
32
+        /// <summary>
33
+        /// 待下载资源列表
34
+        /// </summary>
35
+        private List<VersionDataEntity> _NeedDownloadResList = new List<VersionDataEntity>();
36
+
37
+        /// <summary>
38
+        /// 本地资源列表
39
+        /// </summary>
40
+        private List<VersionDataEntity> _LocalResList = new List<VersionDataEntity>();
41
+
42
+        /// <summary>
43
+        /// 检查版本文件进行事件
44
+        /// </summary>
45
+        private Action<float> OnCheckVersion;
46
+        /// <summary>
47
+        /// 版本文件检查完成事件
48
+        /// </summary>
49
+        private Action<float> OnCheckVersionOver;
50
+
51
+        /// <summary>
52
+        /// 版本文件检查出错事件
53
+        /// </summary>
54
+        private Action<string> OnCheckVersionError;
55
+        /// <summary>
56
+        /// 检查进度
57
+        /// </summary>
58
+        private float _checkProgress;
59
+
60
+        /// <summary>
61
+        /// 超时时间
62
+        /// </summary>
63
+        public const int DOWNLOADTIMEOUT = 5;
64
+
65
+        public float TotalSize
66
+        {
67
+            get
68
+            {
69
+                float szie = 0;
70
+                _NeedDownloadResList.ForEach(p => szie += (float)p.m_size);
71
+                return szie;
72
+            }
73
+        }
74
+
75
+
76
+        void Start()
77
+        {
78
+            if (m_isEnableHotfix)
79
+            {
80
+
81
+            }
82
+        }
83
+
84
+        /// <summary>
85
+        /// 检查版本文件
86
+        /// </summary>
87
+        public void InitCheckVersion(Action<float> checkVersion, Action<float> checkVersionOver, Action<string> checkVersionError = null)
88
+        {
89
+            if (string.IsNullOrEmpty(AssetConfig.ResUrl))
90
+            {
91
+                Log.Error("未指定资源服务器地址");
92
+                return;
93
+            }
94
+            OnCheckVersion = checkVersion;
95
+            OnCheckVersionOver = checkVersionOver;
96
+            OnCheckVersionError = checkVersionError;
97
+            _checkProgress = 0;
98
+            string strVersionPath = AssetConfig.ResUrl + m_versionFileName;
99
+            StartCoroutine(DowloadVersion(strVersionPath));
100
+        }
101
+
102
+        /// <summary>
103
+        /// 对比版本文件
104
+        /// </summary>
105
+        /// <param name="arg0"></param>
106
+        private void OnInitVersionCallBack(List<VersionDataEntity> arg0)
107
+        {
108
+            _loaclVersionPath = LocalResFilePath + m_versionFileName;
109
+
110
+            if (FileOperations.FileExists(_loaclVersionPath))
111
+            {
112
+                List<VersionDataEntity> clienData = FileOperations.ReadJsonData<List<VersionDataEntity>>(_loaclVersionPath);
113
+
114
+                foreach (var item in arg0)
115
+                {
116
+                    _checkProgress += 1.0f / arg0.Count / 2;
117
+                    _checkProgress = _checkProgress >= 1 ? 1 : _checkProgress;
118
+                    OnCheckVersion?.Invoke(_checkProgress);
119
+                    VersionDataEntity dataEntity = clienData.Find(p => p.m_fullName == item.m_fullName);
120
+                    //已有资源
121
+                    if (dataEntity != null)
122
+                    {
123
+                        //对比MD5
124
+                        if (dataEntity.m_md5 != item.m_md5)
125
+                            _NeedDownloadResList.Add(item);
126
+                    }
127
+                    else
128
+                        _NeedDownloadResList.Add(item);//新资源
129
+                }
130
+            }
131
+            else
132
+                arg0.ForEach(p =>
133
+                {
134
+                    _NeedDownloadResList.Add(p);
135
+                    _checkProgress += 1.0f / arg0.Count / 2;
136
+                    _checkProgress = _checkProgress >= 1 ? 1 : _checkProgress;
137
+                    OnCheckVersion?.Invoke(_checkProgress);
138
+                });
139
+
140
+            if (_NeedDownloadResList.Count > 0)
141
+                OnCheckVersionOver?.Invoke(TotalSize);
142
+            else
143
+                OnCheckVersionOver?.Invoke(0);
144
+        }
145
+
146
+        /// <summary>
147
+        /// 下载版本文件
148
+        /// </summary>
149
+        /// <param name="url"></param>
150
+        /// <param name="OnDownLoadOver"></param>
151
+        /// <returns></returns>
152
+        private IEnumerator DowloadVersion(string url)
153
+        {
154
+            UnityWebRequest www = UnityWebRequest.Get(url);
155
+
156
+            www.timeout = DOWNLOADTIMEOUT;
157
+            yield return www.SendWebRequest();
158
+            while (!www.isDone)
159
+            {
160
+                _checkProgress = www.downloadProgress / 2;
161
+                OnCheckVersion?.Invoke(_checkProgress);
162
+            }
163
+
164
+            if (www.result != UnityWebRequest.Result.ProtocolError && www.result != UnityWebRequest.Result.ConnectionError)
165
+            {
166
+                string content = www.downloadHandler.text;
167
+                _checkProgress = 0.5f;
168
+                OnInitVersionCallBack(content.JsonStrToObject<List<VersionDataEntity>>());
169
+                Debug.Log(content);
170
+            }
171
+            else
172
+            {
173
+                Debug.Log("下载失败:" + www.error);
174
+                OnCheckVersionError?.Invoke(www.error);
175
+            }
176
+        }
177
+
178
+        /// <summary>
179
+        /// 保存版本文件
180
+        /// </summary>
181
+        private void SaveLoaclVersion() => FileOperations.WriteJsonData(_LocalResList, _loaclVersionPath);
182
+
183
+        /// <summary>
184
+        /// 更新版本文件
185
+        /// </summary>
186
+        /// <param name="entity"></param>
187
+        public void ModifyLocaData(VersionDataEntity entity)
188
+        {
189
+            if (_LocalResList == null) return;
190
+            bool isExists = false;
191
+            for (int i = 0; i < _LocalResList.Count; i++)
192
+            {
193
+                if (_LocalResList[i].m_fullName.Equals(entity.m_fullName, StringComparison.CurrentCultureIgnoreCase))
194
+                {
195
+                    _LocalResList[i].m_md5 = entity.m_md5;
196
+                    _LocalResList[i].m_fullName = entity.m_fullName;
197
+                    _LocalResList[i].m_size = entity.m_size;
198
+                    isExists = true;
199
+                    break;
200
+                }
201
+            }
202
+
203
+            if (!isExists)
204
+            {
205
+                _LocalResList.Add(entity);
206
+            }
207
+            SaveLoaclVersion();
208
+        }
209
+
210
+        private static void LoadMetadataForAOTAssemblies()
211
+        {
212
+            List<string> aotMetaAssemblyFiles = new List<string>()
213
+        {
214
+            "mscorlib.dll",
215
+            "System.dll",
216
+            "System.Core.dll",
217
+        };
218
+            /// 注意,补充元数据是给AOT dll补充元数据,而不是给热更新dll补充元数据。
219
+            /// 热更新dll不缺元数据,不需要补充,如果调用LoadMetadataForAOTAssembly会返回错误
220
+            /// 
221
+#if HybridCLR
222
+            HomologousImageMode mode = HomologousImageMode.SuperSet;
223
+            foreach (var aotDllName in aotMetaAssemblyFiles)
224
+            {
225
+                byte[] dllBytes = FileOperations.SafeReadAllBytes(AssetConfig.AssetBundleRootPath + aotDllName + ".bytes");
226
+                // 加载assembly对应的dll,会自动为它hook。一旦aot泛型函数的native函数不存在,用解释器版本代码
227
+                LoadImageErrorCode err = RuntimeApi.LoadMetadataForAOTAssembly(dllBytes, mode);
228
+                Debug.Log($"LoadMetadataForAOTAssembly:{aotDllName}. mode:{mode} ret:{err}");
229
+            }
230
+#else
231
+            Log.Error("当前非热更环境!请先安装HybridCLR");
232
+#endif
233
+        }
234
+    }
235
+}
236
+

+ 11 - 0
HotfixManager.cs.meta

@@ -0,0 +1,11 @@
1
+fileFormatVersion: 2
2
+guid: a649a2c7752e1404e834a53a149e1e64
3
+MonoImporter:
4
+  externalObjects: {}
5
+  serializedVersion: 2
6
+  defaultReferences: []
7
+  executionOrder: 0
8
+  icon: {instanceID: 0}
9
+  userData: 
10
+  assetBundleName: 
11
+  assetBundleVariant: