com.beanbag.tiktokminigames 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/DefaultTemplate/backgroundlandscape.png +0 -0
- package/DefaultTemplate/backgroundlandscape.png.meta +159 -0
- package/DefaultTemplate/backgroundportrait.png +0 -0
- package/DefaultTemplate/backgroundportrait.png.meta +159 -0
- package/DefaultTemplate/game.js +151 -0
- package/DefaultTemplate/game.js.meta +7 -0
- package/DefaultTemplate/images/unity_logo.png +0 -0
- package/DefaultTemplate/images/unity_logo.png.meta +159 -0
- package/DefaultTemplate/images.meta +8 -0
- package/DefaultTemplate/plugin-config.js +23 -0
- package/DefaultTemplate/plugin-config.js.meta +7 -0
- package/DefaultTemplate/plugin.js +1 -0
- package/DefaultTemplate/plugin.js.meta +7 -0
- package/DefaultTemplate/unity-namespace.js +11 -0
- package/DefaultTemplate/unity-namespace.js.meta +7 -0
- package/DefaultTemplate/webgl-wasm-split.js +17 -0
- package/DefaultTemplate/webgl-wasm-split.js.meta +7 -0
- package/DefaultTemplate.meta +8 -0
- package/Editor/Extras/Integration/DouYinMiniGameSettings.cs +30 -0
- package/Editor/Extras/Integration/DouYinMiniGameSettings.cs.meta +11 -0
- package/Editor/Extras/Integration/DouYinMiniGameSettingsEditor.cs +354 -0
- package/Editor/Extras/Integration/DouYinMiniGameSettingsEditor.cs.meta +3 -0
- package/Editor/Extras/Integration/DouYinSubplatformInterface.cs +153 -0
- package/Editor/Extras/Integration/DouYinSubplatformInterface.cs.meta +3 -0
- package/Editor/Extras/Integration.meta +8 -0
- package/Editor/Extras/Providers/TTMiniGameSupportProvider.cs +148 -0
- package/Editor/Extras/Providers/TTMiniGameSupportProvider.cs.meta +3 -0
- package/Editor/Extras/Providers.meta +3 -0
- package/Editor/Extras/TTEditorSupportProviderRegister.cs +15 -0
- package/Editor/Extras/TTEditorSupportProviderRegister.cs.meta +3 -0
- package/Editor/Extras.meta +3 -0
- package/Editor/ttsdk_tools.dll +0 -0
- package/Editor/ttsdk_tools.dll.meta +33 -0
- package/Editor/ttsdk_tools.pdb +0 -0
- package/Editor/ttsdk_tools.pdb.meta +7 -0
- package/Editor.meta +8 -0
- package/LitJson/TTLitJson.dll +0 -0
- package/LitJson/TTLitJson.dll.meta +33 -0
- package/LitJson/TTLitJson.pdb +0 -0
- package/LitJson/TTLitJson.pdb.meta +7 -0
- package/LitJson.meta +8 -0
- package/TTSDK/ttsdk.dll +0 -0
- package/TTSDK/ttsdk.dll.meta +33 -0
- package/TTSDK/ttsdk.pdb +0 -0
- package/TTSDK/ttsdk.pdb.meta +7 -0
- package/TTSDK.meta +8 -0
- package/WebGL/AssetBundle/DownloadHandlerTTAssetBundle.cs +85 -0
- package/WebGL/AssetBundle/DownloadHandlerTTAssetBundle.cs.meta +3 -0
- package/WebGL/AssetBundle/TTAssetBundle.cs +72 -0
- package/WebGL/AssetBundle/TTAssetBundle.cs.meta +3 -0
- package/WebGL/AssetBundle/TTAssetBundleExtensions.cs +25 -0
- package/WebGL/AssetBundle/TTAssetBundleExtensions.cs.meta +3 -0
- package/WebGL/AssetBundle/TTAssetBundleProviders.cs.txt +1301 -0
- package/WebGL/AssetBundle/TTAssetBundleProviders.cs.txt.meta +3 -0
- package/WebGL/AssetBundle/TTAssetBundleRequest.cs +96 -0
- package/WebGL/AssetBundle/TTAssetBundleRequest.cs.meta +3 -0
- package/WebGL/AssetBundle.meta +8 -0
- package/WebGL/Compatibility/UnityCacheCompatibility.cs +49 -0
- package/WebGL/Compatibility/UnityCacheCompatibility.cs.meta +3 -0
- package/WebGL/Compatibility/UnityWebRequestCompatibility.cs +18 -0
- package/WebGL/Compatibility/UnityWebRequestCompatibility.cs.meta +3 -0
- package/WebGL/Compatibility.meta +3 -0
- package/WebGL/FileSystem/TTFileSystemManager.cs +460 -0
- package/WebGL/FileSystem/TTFileSystemManager.cs.meta +11 -0
- package/WebGL/FileSystem/TTFileSystemManagerDefault.cs +1039 -0
- package/WebGL/FileSystem/TTFileSystemManagerDefault.cs.meta +11 -0
- package/WebGL/FileSystem/TTFileSystemManagerWebGL.cs +1278 -0
- package/WebGL/FileSystem/TTFileSystemManagerWebGL.cs.meta +11 -0
- package/WebGL/FileSystem.meta +3 -0
- package/WebGL/Input/Input.cs +230 -0
- package/WebGL/Input/Input.cs.meta +3 -0
- package/WebGL/Input/TTPCInputHandler.cs +199 -0
- package/WebGL/Input/TTPCInputHandler.cs.meta +3 -0
- package/WebGL/Input.meta +3 -0
- package/WebGL/Network/TTUDPSocketHandler.cs +130 -0
- package/WebGL/Network/TTUDPSocketHandler.cs.meta +11 -0
- package/WebGL/Network.meta +3 -0
- package/WebGL/TTAssetBundle.jslib +33 -0
- package/WebGL/TTAssetBundle.jslib.meta +32 -0
- package/WebGL/TTCallbackHandler.cs +139 -0
- package/WebGL/TTCallbackHandler.cs.meta +3 -0
- package/WebGL/TTModel.cs +582 -0
- package/WebGL/TTModel.cs.meta +11 -0
- package/WebGL/TTSDK.jslib +592 -0
- package/WebGL/TTSDK.jslib.meta +32 -0
- package/WebGL/TTSDKType.cs +10 -0
- package/WebGL/TTSDKType.cs.meta +3 -0
- package/WebGL/TTStorageManager.cs +155 -0
- package/WebGL/TTStorageManager.cs.meta +11 -0
- package/WebGL/TTUNBridge.jslib +117 -0
- package/WebGL/TTUNBridge.jslib.meta +32 -0
- package/WebGL/TTVersionAttribute.cs +21 -0
- package/WebGL/TTVersionAttribute.cs.meta +11 -0
- package/WebGL/TTWebGL.asmdef +18 -0
- package/WebGL/TTWebGL.asmdef.meta +7 -0
- package/WebGL/TTWebGLInterface.cs +63 -0
- package/WebGL/TTWebGLInterface.cs.meta +11 -0
- package/WebGL.meta +8 -0
- package/package.json +13 -0
- package/package.json.meta +7 -0
|
@@ -0,0 +1,1301 @@
|
|
|
1
|
+
#if UNITY_2022_1_OR_NEWER
|
|
2
|
+
#define UNLOAD_BUNDLE_ASYNC
|
|
3
|
+
#endif
|
|
4
|
+
|
|
5
|
+
using System;
|
|
6
|
+
using System.Collections.Generic;
|
|
7
|
+
using System.ComponentModel;
|
|
8
|
+
using System.IO;
|
|
9
|
+
using System.Threading;
|
|
10
|
+
using UnityEngine.Networking;
|
|
11
|
+
using UnityEngine.ResourceManagement.AsyncOperations;
|
|
12
|
+
using UnityEngine.ResourceManagement.Exceptions;
|
|
13
|
+
using UnityEngine.ResourceManagement.ResourceLocations;
|
|
14
|
+
using UnityEngine.ResourceManagement.Util;
|
|
15
|
+
using TTSDK;
|
|
16
|
+
|
|
17
|
+
namespace UnityEngine.ResourceManagement
|
|
18
|
+
{
|
|
19
|
+
internal class TTWebRequestQueueOperation
|
|
20
|
+
{
|
|
21
|
+
private bool m_Completed = false;
|
|
22
|
+
public UnityWebRequestAsyncOperation Result;
|
|
23
|
+
public Action<UnityWebRequestAsyncOperation> OnComplete;
|
|
24
|
+
public bool IsDone
|
|
25
|
+
{
|
|
26
|
+
get { return m_Completed || Result != null; }
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
internal UnityWebRequest m_WebRequest;
|
|
30
|
+
|
|
31
|
+
public UnityWebRequest WebRequest
|
|
32
|
+
{
|
|
33
|
+
get { return m_WebRequest; }
|
|
34
|
+
internal set { m_WebRequest = value; }
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
public TTWebRequestQueueOperation(UnityWebRequest request)
|
|
38
|
+
{
|
|
39
|
+
m_WebRequest = request;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
internal void Complete(UnityWebRequestAsyncOperation asyncOp)
|
|
43
|
+
{
|
|
44
|
+
m_Completed = true;
|
|
45
|
+
Result = asyncOp;
|
|
46
|
+
OnComplete?.Invoke(Result);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
internal static class WebRequestQueue
|
|
52
|
+
{
|
|
53
|
+
internal static int s_MaxRequest = 512;
|
|
54
|
+
internal static Queue<TTWebRequestQueueOperation> s_QueuedOperations = new Queue<TTWebRequestQueueOperation>();
|
|
55
|
+
internal static List<UnityWebRequestAsyncOperation> s_ActiveRequests = new List<UnityWebRequestAsyncOperation>();
|
|
56
|
+
|
|
57
|
+
public static void SetMaxConcurrentRequests(int maxRequests)
|
|
58
|
+
{
|
|
59
|
+
if (maxRequests < 1)
|
|
60
|
+
throw new ArgumentException("MaxRequests must be 1 or greater.", "maxRequests");
|
|
61
|
+
s_MaxRequest = maxRequests;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
public static TTWebRequestQueueOperation QueueRequest(UnityWebRequest request)
|
|
65
|
+
{
|
|
66
|
+
TTWebRequestQueueOperation queueOperation = new TTWebRequestQueueOperation(request);
|
|
67
|
+
if (s_ActiveRequests.Count < s_MaxRequest)
|
|
68
|
+
BeginWebRequest(queueOperation);
|
|
69
|
+
else
|
|
70
|
+
s_QueuedOperations.Enqueue(queueOperation);
|
|
71
|
+
|
|
72
|
+
return queueOperation;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
internal static void WaitForRequestToBeActive(TTWebRequestQueueOperation request, int millisecondsTimeout)
|
|
76
|
+
{
|
|
77
|
+
var completedRequests = new List<UnityWebRequestAsyncOperation>();
|
|
78
|
+
while (s_QueuedOperations.Contains(request))
|
|
79
|
+
{
|
|
80
|
+
completedRequests.Clear();
|
|
81
|
+
foreach (UnityWebRequestAsyncOperation webRequestAsyncOp in s_ActiveRequests)
|
|
82
|
+
{
|
|
83
|
+
if (TTUnityWebRequestUtilities.IsAssetBundleDownloaded(webRequestAsyncOp))
|
|
84
|
+
completedRequests.Add(webRequestAsyncOp);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
foreach (UnityWebRequestAsyncOperation webRequestAsyncOp in completedRequests)
|
|
88
|
+
{
|
|
89
|
+
bool requestIsActive = s_QueuedOperations.Peek() == request;
|
|
90
|
+
webRequestAsyncOp.completed -= OnWebAsyncOpComplete;
|
|
91
|
+
OnWebAsyncOpComplete(webRequestAsyncOp);
|
|
92
|
+
if (requestIsActive)
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
Thread.Sleep(millisecondsTimeout);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
internal static void DequeueRequest(UnityWebRequestAsyncOperation operation)
|
|
101
|
+
{
|
|
102
|
+
operation.completed -= OnWebAsyncOpComplete;
|
|
103
|
+
OnWebAsyncOpComplete(operation);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
private static void OnWebAsyncOpComplete(AsyncOperation operation)
|
|
107
|
+
{
|
|
108
|
+
OnWebAsyncOpComplete(operation as UnityWebRequestAsyncOperation);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
private static void OnWebAsyncOpComplete(UnityWebRequestAsyncOperation operation)
|
|
112
|
+
{
|
|
113
|
+
if (s_ActiveRequests.Remove(operation) && s_QueuedOperations.Count > 0)
|
|
114
|
+
{
|
|
115
|
+
var nextQueuedOperation = s_QueuedOperations.Dequeue();
|
|
116
|
+
BeginWebRequest(nextQueuedOperation);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
static void BeginWebRequest(TTWebRequestQueueOperation queueOperation)
|
|
121
|
+
{
|
|
122
|
+
var request = queueOperation.m_WebRequest;
|
|
123
|
+
UnityWebRequestAsyncOperation webRequestAsyncOp = null;
|
|
124
|
+
try
|
|
125
|
+
{
|
|
126
|
+
webRequestAsyncOp = request.SendWebRequest();
|
|
127
|
+
if (webRequestAsyncOp != null)
|
|
128
|
+
{
|
|
129
|
+
s_ActiveRequests.Add(webRequestAsyncOp);
|
|
130
|
+
|
|
131
|
+
if (webRequestAsyncOp.isDone)
|
|
132
|
+
OnWebAsyncOpComplete(webRequestAsyncOp);
|
|
133
|
+
else
|
|
134
|
+
webRequestAsyncOp.completed += OnWebAsyncOpComplete;
|
|
135
|
+
}
|
|
136
|
+
else
|
|
137
|
+
{
|
|
138
|
+
OnWebAsyncOpComplete(null);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
catch (Exception e)
|
|
142
|
+
{
|
|
143
|
+
Debug.LogError(e.Message);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
queueOperation.Complete(webRequestAsyncOp);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
namespace UnityEngine.ResourceManagement.Util
|
|
152
|
+
{
|
|
153
|
+
[Flags]
|
|
154
|
+
internal enum BundleSource
|
|
155
|
+
{
|
|
156
|
+
None = 0,
|
|
157
|
+
Local = 1,
|
|
158
|
+
Cache = 2,
|
|
159
|
+
Download = 4,
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
namespace UnityEngine.ResourceManagement.ResourceProviders
|
|
164
|
+
{
|
|
165
|
+
|
|
166
|
+
[DisplayName("Assets from TTBundles Provider")]
|
|
167
|
+
public class TTBundledAssetProvider : ResourceProviderBase
|
|
168
|
+
{
|
|
169
|
+
internal class InternalOp
|
|
170
|
+
{
|
|
171
|
+
AssetBundle m_AssetBundle;
|
|
172
|
+
AssetBundleRequest m_PreloadRequest;
|
|
173
|
+
AssetBundleRequest m_RequestOperation;
|
|
174
|
+
object m_Result;
|
|
175
|
+
ProvideHandle m_ProvideHandle;
|
|
176
|
+
string subObjectName = null;
|
|
177
|
+
|
|
178
|
+
internal static T LoadBundleFromDependecies<T>(IList<object> results) where T : class, IAssetBundleResource
|
|
179
|
+
{
|
|
180
|
+
if (results == null || results.Count == 0)
|
|
181
|
+
return default(T);
|
|
182
|
+
|
|
183
|
+
IAssetBundleResource bundle = null;
|
|
184
|
+
bool firstBundleWrapper = true;
|
|
185
|
+
for (int i = 0; i < results.Count; i++)
|
|
186
|
+
{
|
|
187
|
+
var abWrapper = results[i] as IAssetBundleResource;
|
|
188
|
+
if (abWrapper != null)
|
|
189
|
+
{
|
|
190
|
+
//only use the first asset bundle, even if it is invalid
|
|
191
|
+
abWrapper.GetAssetBundle();
|
|
192
|
+
if (firstBundleWrapper)
|
|
193
|
+
bundle = abWrapper;
|
|
194
|
+
firstBundleWrapper = false;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return bundle as T;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
public void Start(ProvideHandle provideHandle)
|
|
202
|
+
{
|
|
203
|
+
provideHandle.SetProgressCallback(ProgressCallback);
|
|
204
|
+
provideHandle.SetWaitForCompletionCallback(WaitForCompletionHandler);
|
|
205
|
+
subObjectName = null;
|
|
206
|
+
m_ProvideHandle = provideHandle;
|
|
207
|
+
m_RequestOperation = null;
|
|
208
|
+
List<object> deps = new List<object>();
|
|
209
|
+
m_ProvideHandle.GetDependencies(deps);
|
|
210
|
+
var bundleResource = LoadBundleFromDependecies<IAssetBundleResource>(deps);
|
|
211
|
+
if (bundleResource == null)
|
|
212
|
+
{
|
|
213
|
+
m_ProvideHandle.Complete<AssetBundle>(null, false, new Exception("Unable to load dependent bundle from location " + m_ProvideHandle.Location));
|
|
214
|
+
}
|
|
215
|
+
else
|
|
216
|
+
{
|
|
217
|
+
m_AssetBundle = bundleResource.GetAssetBundle();
|
|
218
|
+
if (m_AssetBundle == null)
|
|
219
|
+
{
|
|
220
|
+
m_ProvideHandle.Complete<AssetBundle>(null, false, new Exception("Unable to load dependent bundle from location " + m_ProvideHandle.Location));
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
var assetBundleResource = bundleResource as TTAssetBundleResource;
|
|
225
|
+
if (assetBundleResource != null)
|
|
226
|
+
m_PreloadRequest = assetBundleResource.GetAssetPreloadRequest();
|
|
227
|
+
if (m_PreloadRequest == null || m_PreloadRequest.isDone)
|
|
228
|
+
BeginAssetLoad();
|
|
229
|
+
else
|
|
230
|
+
m_PreloadRequest.completed += operation => BeginAssetLoad();
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
private void BeginAssetLoad()
|
|
235
|
+
{
|
|
236
|
+
if (m_AssetBundle == null)
|
|
237
|
+
{
|
|
238
|
+
m_ProvideHandle.Complete<AssetBundle>(null, false, new Exception("Unable to load dependent bundle from location " + m_ProvideHandle.Location));
|
|
239
|
+
}
|
|
240
|
+
else
|
|
241
|
+
{
|
|
242
|
+
var assetPath = m_ProvideHandle.ResourceManager.TransformInternalId(m_ProvideHandle.Location);
|
|
243
|
+
if (m_ProvideHandle.Type.IsArray)
|
|
244
|
+
{
|
|
245
|
+
#if !UNITY_2021_1_OR_NEWER
|
|
246
|
+
if (AsyncOperationHandle.IsWaitingForCompletion)
|
|
247
|
+
{
|
|
248
|
+
GetArrayResult(m_AssetBundle.LoadAssetWithSubAssets(assetPath, m_ProvideHandle.Type.GetElementType()));
|
|
249
|
+
CompleteOperation();
|
|
250
|
+
}
|
|
251
|
+
else
|
|
252
|
+
#endif
|
|
253
|
+
m_RequestOperation = m_AssetBundle.LoadAssetWithSubAssetsAsync(assetPath, m_ProvideHandle.Type.GetElementType());
|
|
254
|
+
}
|
|
255
|
+
else if (m_ProvideHandle.Type.IsGenericType && typeof(IList<>) == m_ProvideHandle.Type.GetGenericTypeDefinition())
|
|
256
|
+
{
|
|
257
|
+
#if !UNITY_2021_1_OR_NEWER
|
|
258
|
+
if (AsyncOperationHandle.IsWaitingForCompletion)
|
|
259
|
+
{
|
|
260
|
+
GetListResult(m_AssetBundle.LoadAssetWithSubAssets(assetPath, m_ProvideHandle.Type.GetGenericArguments()[0]));
|
|
261
|
+
CompleteOperation();
|
|
262
|
+
}
|
|
263
|
+
else
|
|
264
|
+
#endif
|
|
265
|
+
m_RequestOperation = m_AssetBundle.LoadAssetWithSubAssetsAsync(assetPath, m_ProvideHandle.Type.GetGenericArguments()[0]);
|
|
266
|
+
}
|
|
267
|
+
else
|
|
268
|
+
{
|
|
269
|
+
if (ExtractKeyAndSubKey(assetPath, out string mainPath, out string subKey))
|
|
270
|
+
{
|
|
271
|
+
subObjectName = subKey;
|
|
272
|
+
#if !UNITY_2021_1_OR_NEWER
|
|
273
|
+
if (AsyncOperationHandle.IsWaitingForCompletion)
|
|
274
|
+
{
|
|
275
|
+
GetAssetSubObjectResult(m_AssetBundle.LoadAssetWithSubAssets(mainPath, m_ProvideHandle.Type));
|
|
276
|
+
CompleteOperation();
|
|
277
|
+
}
|
|
278
|
+
else
|
|
279
|
+
#endif
|
|
280
|
+
m_RequestOperation = m_AssetBundle.LoadAssetWithSubAssetsAsync(mainPath, m_ProvideHandle.Type);
|
|
281
|
+
}
|
|
282
|
+
else
|
|
283
|
+
{
|
|
284
|
+
#if !UNITY_2021_1_OR_NEWER
|
|
285
|
+
if (AsyncOperationHandle.IsWaitingForCompletion)
|
|
286
|
+
{
|
|
287
|
+
GetAssetResult(m_AssetBundle.LoadAsset(assetPath, m_ProvideHandle.Type));
|
|
288
|
+
CompleteOperation();
|
|
289
|
+
}
|
|
290
|
+
else
|
|
291
|
+
#endif
|
|
292
|
+
m_RequestOperation = m_AssetBundle.LoadAssetAsync(assetPath, m_ProvideHandle.Type);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
if (m_RequestOperation != null)
|
|
297
|
+
{
|
|
298
|
+
if (m_RequestOperation.isDone)
|
|
299
|
+
ActionComplete(m_RequestOperation);
|
|
300
|
+
else
|
|
301
|
+
{
|
|
302
|
+
#if ENABLE_ADDRESSABLE_PROFILER
|
|
303
|
+
if (UnityEngine.Profiling.Profiler.enabled && m_ProvideHandle.IsValid)
|
|
304
|
+
Profiling.ProfilerRuntime.AddAssetOperation(m_ProvideHandle, Profiling.ContentStatus.Loading);
|
|
305
|
+
#endif
|
|
306
|
+
m_RequestOperation.completed += ActionComplete;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
private bool WaitForCompletionHandler()
|
|
313
|
+
{
|
|
314
|
+
if (m_PreloadRequest != null && !m_PreloadRequest.isDone)
|
|
315
|
+
return m_PreloadRequest.asset == null;
|
|
316
|
+
if (m_Result != null)
|
|
317
|
+
return true;
|
|
318
|
+
if (m_RequestOperation == null)
|
|
319
|
+
return false;
|
|
320
|
+
if (m_RequestOperation.isDone)
|
|
321
|
+
return true;
|
|
322
|
+
return m_RequestOperation.asset != null;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
private void ActionComplete(AsyncOperation obj)
|
|
326
|
+
{
|
|
327
|
+
if (m_RequestOperation != null)
|
|
328
|
+
{
|
|
329
|
+
if (m_ProvideHandle.Type.IsArray)
|
|
330
|
+
GetArrayResult(m_RequestOperation.allAssets);
|
|
331
|
+
else if (m_ProvideHandle.Type.IsGenericType && typeof(IList<>) == m_ProvideHandle.Type.GetGenericTypeDefinition())
|
|
332
|
+
GetListResult(m_RequestOperation.allAssets);
|
|
333
|
+
else if (string.IsNullOrEmpty(subObjectName))
|
|
334
|
+
GetAssetResult(m_RequestOperation.asset);
|
|
335
|
+
else
|
|
336
|
+
GetAssetSubObjectResult(m_RequestOperation.allAssets);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
CompleteOperation();
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
private void GetArrayResult(Object[] allAssets)
|
|
343
|
+
{
|
|
344
|
+
m_Result = ResourceManagerConfig.CreateArrayResult(m_ProvideHandle.Type, allAssets);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
private void GetListResult(Object[] allAssets)
|
|
348
|
+
{
|
|
349
|
+
m_Result = ResourceManagerConfig.CreateListResult(m_ProvideHandle.Type, allAssets);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
private void GetAssetResult(Object asset)
|
|
353
|
+
{
|
|
354
|
+
m_Result = (asset != null && m_ProvideHandle.Type.IsAssignableFrom(asset.GetType())) ? asset : null;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
private void GetAssetSubObjectResult(Object[] allAssets)
|
|
358
|
+
{
|
|
359
|
+
foreach (var o in allAssets)
|
|
360
|
+
{
|
|
361
|
+
if (o.name == subObjectName)
|
|
362
|
+
{
|
|
363
|
+
if (m_ProvideHandle.Type.IsAssignableFrom(o.GetType()))
|
|
364
|
+
{
|
|
365
|
+
m_Result = o;
|
|
366
|
+
break;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
void CompleteOperation()
|
|
373
|
+
{
|
|
374
|
+
#if ENABLE_ADDRESSABLE_PROFILER
|
|
375
|
+
if (UnityEngine.Profiling.Profiler.enabled && m_Result != null && m_ProvideHandle.IsValid)
|
|
376
|
+
Profiling.ProfilerRuntime.AddAssetOperation(m_ProvideHandle, Profiling.ContentStatus.Active);
|
|
377
|
+
#endif
|
|
378
|
+
|
|
379
|
+
Exception e = m_Result == null
|
|
380
|
+
? new Exception($"Unable to load asset of type {m_ProvideHandle.Type} from location {m_ProvideHandle.Location}.")
|
|
381
|
+
: null;
|
|
382
|
+
m_ProvideHandle.Complete(m_Result, m_Result != null, e);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
public float ProgressCallback()
|
|
386
|
+
{
|
|
387
|
+
return m_RequestOperation != null ? m_RequestOperation.progress : 0.0f;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
/// <summary>
|
|
391
|
+
/// Extracts main and subobject keys if properly formatted
|
|
392
|
+
/// </summary>
|
|
393
|
+
/// <param name="keyObj">The key as an object.</param>
|
|
394
|
+
/// <param name="mainKey">The key of the main asset. This will be set to null if a sub key is not found.</param>
|
|
395
|
+
/// <param name="subKey">The key of the sub object. This will be set to null if not found.</param>
|
|
396
|
+
/// <returns></returns>
|
|
397
|
+
internal static bool ExtractKeyAndSubKey(object keyObj, out string mainKey, out string subKey)
|
|
398
|
+
{
|
|
399
|
+
var key = keyObj as string;
|
|
400
|
+
if (key != null)
|
|
401
|
+
{
|
|
402
|
+
var i = key.IndexOf('[');
|
|
403
|
+
if (i > 0)
|
|
404
|
+
{
|
|
405
|
+
var j = key.LastIndexOf(']');
|
|
406
|
+
if (j > i)
|
|
407
|
+
{
|
|
408
|
+
mainKey = key.Substring(0, i);
|
|
409
|
+
subKey = key.Substring(i + 1, j - (i + 1));
|
|
410
|
+
return true;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
mainKey = null;
|
|
415
|
+
subKey = null;
|
|
416
|
+
return false;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
public override void Provide(ProvideHandle provideHandle)
|
|
421
|
+
{
|
|
422
|
+
new InternalOp().Start(provideHandle);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
public class TTAssetBundleResource : IAssetBundleResource, IUpdateReceiver
|
|
427
|
+
{
|
|
428
|
+
public enum LoadType
|
|
429
|
+
{
|
|
430
|
+
None,
|
|
431
|
+
Local,
|
|
432
|
+
Web
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
AssetBundle m_AssetBundle;
|
|
436
|
+
DownloadHandlerTTAssetBundle m_downloadHandler;
|
|
437
|
+
AsyncOperation m_RequestOperation;
|
|
438
|
+
internal TTWebRequestQueueOperation m_WebRequestQueueOperation;
|
|
439
|
+
internal ProvideHandle m_ProvideHandle;
|
|
440
|
+
internal AssetBundleRequestOptions m_Options;
|
|
441
|
+
|
|
442
|
+
[NonSerialized]
|
|
443
|
+
bool m_RequestCompletedCallbackCalled = false;
|
|
444
|
+
|
|
445
|
+
int m_Retries;
|
|
446
|
+
BundleSource m_Source = BundleSource.None;
|
|
447
|
+
long m_BytesToDownload;
|
|
448
|
+
long m_DownloadedBytes;
|
|
449
|
+
bool m_Completed = false;
|
|
450
|
+
#if UNLOAD_BUNDLE_ASYNC
|
|
451
|
+
AssetBundleUnloadOperation m_UnloadOperation;
|
|
452
|
+
#endif
|
|
453
|
+
const int k_WaitForWebRequestMainThreadSleep = 1;
|
|
454
|
+
string m_TransformedInternalId;
|
|
455
|
+
AssetBundleRequest m_PreloadRequest;
|
|
456
|
+
bool m_PreloadCompleted = false;
|
|
457
|
+
ulong m_LastDownloadedByteCount = 0;
|
|
458
|
+
float m_TimeoutTimer = 0;
|
|
459
|
+
int m_TimeoutOverFrames = 0;
|
|
460
|
+
|
|
461
|
+
private bool HasTimedOut => m_TimeoutTimer >= m_Options.Timeout && m_TimeoutOverFrames > 5;
|
|
462
|
+
|
|
463
|
+
internal long BytesToDownload
|
|
464
|
+
{
|
|
465
|
+
get
|
|
466
|
+
{
|
|
467
|
+
if (m_BytesToDownload == -1)
|
|
468
|
+
{
|
|
469
|
+
if (m_Options != null)
|
|
470
|
+
m_BytesToDownload = m_Options.ComputeSize(m_ProvideHandle.Location, m_ProvideHandle.ResourceManager);
|
|
471
|
+
else
|
|
472
|
+
m_BytesToDownload = 0;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
return m_BytesToDownload;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
internal UnityWebRequest CreateWebRequest(IResourceLocation loc)
|
|
480
|
+
{
|
|
481
|
+
var url = m_ProvideHandle.ResourceManager.TransformInternalId(loc);
|
|
482
|
+
return CreateWebRequest(url);
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
internal UnityWebRequest CreateWebRequest(string url)
|
|
486
|
+
{
|
|
487
|
+
string sanitizedUrl = Uri.UnescapeDataString(url);
|
|
488
|
+
|
|
489
|
+
#if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN
|
|
490
|
+
Uri uri = new Uri(sanitizedUrl.Replace(" ", "%20"));
|
|
491
|
+
#else
|
|
492
|
+
Uri uri = new Uri(Uri.EscapeUriString(sanitizedUrl));
|
|
493
|
+
#endif
|
|
494
|
+
|
|
495
|
+
if (m_Options == null)
|
|
496
|
+
{
|
|
497
|
+
m_Source = BundleSource.Download;
|
|
498
|
+
#if ENABLE_ADDRESSABLE_PROFILER
|
|
499
|
+
AddBundleToProfiler(Profiling.ContentStatus.Downloading, m_Source);
|
|
500
|
+
#endif
|
|
501
|
+
return TTAssetBundle.GetAssetBundle(url);
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
UnityWebRequest webRequest;
|
|
505
|
+
if (!string.IsNullOrEmpty(m_Options.Hash))
|
|
506
|
+
{
|
|
507
|
+
CachedAssetBundle cachedBundle = new CachedAssetBundle(m_Options.BundleName, Hash128.Parse(m_Options.Hash));
|
|
508
|
+
#if ENABLE_CACHING
|
|
509
|
+
bool cached = Caching.IsVersionCached(cachedBundle);
|
|
510
|
+
m_Source = cached ? BundleSource.Cache : BundleSource.Download;
|
|
511
|
+
if (m_Options.UseCrcForCachedBundle || m_Source == BundleSource.Download)
|
|
512
|
+
webRequest = UnityWebRequestAssetBundle.GetAssetBundle(uri, cachedBundle, m_Options.Crc);
|
|
513
|
+
else
|
|
514
|
+
webRequest = UnityWebRequestAssetBundle.GetAssetBundle(uri, cachedBundle);
|
|
515
|
+
#else
|
|
516
|
+
webRequest = UnityWebRequestAssetBundle.GetAssetBundle(uri, cachedBundle, m_Options.Crc);
|
|
517
|
+
#endif
|
|
518
|
+
}
|
|
519
|
+
else
|
|
520
|
+
{
|
|
521
|
+
m_Source = BundleSource.Download;
|
|
522
|
+
webRequest = TTAssetBundle.GetAssetBundle(url, m_Options.Crc);
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
if (m_Options.RedirectLimit > 0)
|
|
526
|
+
webRequest.redirectLimit = m_Options.RedirectLimit;
|
|
527
|
+
if (m_ProvideHandle.ResourceManager.CertificateHandlerInstance != null)
|
|
528
|
+
{
|
|
529
|
+
webRequest.certificateHandler = m_ProvideHandle.ResourceManager.CertificateHandlerInstance;
|
|
530
|
+
webRequest.disposeCertificateHandlerOnDispose = false;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
m_ProvideHandle.ResourceManager.WebRequestOverride?.Invoke(webRequest);
|
|
534
|
+
return webRequest;
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
public AssetBundleRequest GetAssetPreloadRequest()
|
|
538
|
+
{
|
|
539
|
+
if (m_PreloadCompleted || GetAssetBundle() == null)
|
|
540
|
+
return null;
|
|
541
|
+
|
|
542
|
+
if (m_Options.AssetLoadMode == AssetLoadMode.AllPackedAssetsAndDependencies)
|
|
543
|
+
{
|
|
544
|
+
#if !UNITY_2021_1_OR_NEWER
|
|
545
|
+
if (AsyncOperationHandle.IsWaitingForCompletion)
|
|
546
|
+
{
|
|
547
|
+
m_AssetBundle.LoadAllAssets();
|
|
548
|
+
m_PreloadCompleted = true;
|
|
549
|
+
return null;
|
|
550
|
+
}
|
|
551
|
+
#endif
|
|
552
|
+
if (m_PreloadRequest == null)
|
|
553
|
+
{
|
|
554
|
+
m_PreloadRequest = m_AssetBundle.LoadAllAssetsAsync();
|
|
555
|
+
m_PreloadRequest.completed += operation => m_PreloadCompleted = true;
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
return m_PreloadRequest;
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
return null;
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
float PercentComplete()
|
|
565
|
+
{
|
|
566
|
+
return m_RequestOperation != null ? m_RequestOperation.progress : 0.0f;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
DownloadStatus GetDownloadStatus()
|
|
570
|
+
{
|
|
571
|
+
if (m_Options == null)
|
|
572
|
+
return default;
|
|
573
|
+
var status = new DownloadStatus() {TotalBytes = BytesToDownload, IsDone = PercentComplete() >= 1f};
|
|
574
|
+
if (BytesToDownload > 0)
|
|
575
|
+
{
|
|
576
|
+
if (m_WebRequestQueueOperation != null && string.IsNullOrEmpty(m_WebRequestQueueOperation.m_WebRequest.error))
|
|
577
|
+
m_DownloadedBytes = (long)(m_WebRequestQueueOperation.m_WebRequest.downloadedBytes);
|
|
578
|
+
else if (m_RequestOperation != null && m_RequestOperation is UnityWebRequestAsyncOperation operation && string.IsNullOrEmpty(operation.webRequest.error))
|
|
579
|
+
m_DownloadedBytes = (long)operation.webRequest.downloadedBytes;
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
status.DownloadedBytes = m_DownloadedBytes;
|
|
583
|
+
return status;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
public AssetBundle GetAssetBundle()
|
|
587
|
+
{
|
|
588
|
+
if (m_AssetBundle == null)
|
|
589
|
+
{
|
|
590
|
+
if (m_downloadHandler != null)
|
|
591
|
+
{
|
|
592
|
+
m_AssetBundle = m_downloadHandler.assetBundle;
|
|
593
|
+
m_downloadHandler.Dispose();
|
|
594
|
+
m_downloadHandler = null;
|
|
595
|
+
} else if (m_RequestOperation is TTAssetBundleRequest r)
|
|
596
|
+
{
|
|
597
|
+
m_AssetBundle = r.assetBundle;
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
return m_AssetBundle;
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
#if ENABLE_ADDRESSABLE_PROFILER
|
|
605
|
+
private void AddBundleToProfiler(Profiling.ContentStatus status, BundleSource source)
|
|
606
|
+
{
|
|
607
|
+
if (!Profiler.enabled)
|
|
608
|
+
return;
|
|
609
|
+
|
|
610
|
+
if (status == Profiling.ContentStatus.Active && m_AssetBundle == null)
|
|
611
|
+
Profiling.ProfilerRuntime.BundleReleased(m_Options.BundleName);
|
|
612
|
+
else
|
|
613
|
+
Profiling.ProfilerRuntime.AddBundleOperation(m_ProvideHandle, m_Options, status, source);
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
private void RemoveBundleFromProfiler()
|
|
617
|
+
{
|
|
618
|
+
if (m_Options == null)
|
|
619
|
+
return;
|
|
620
|
+
Profiling.ProfilerRuntime.BundleReleased(m_Options.BundleName);
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
#endif
|
|
624
|
+
|
|
625
|
+
#if UNLOAD_BUNDLE_ASYNC
|
|
626
|
+
void OnUnloadOperationComplete(AsyncOperation op)
|
|
627
|
+
{
|
|
628
|
+
m_UnloadOperation = null;
|
|
629
|
+
BeginOperation();
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
#endif
|
|
633
|
+
|
|
634
|
+
#if UNLOAD_BUNDLE_ASYNC
|
|
635
|
+
public void Start(ProvideHandle provideHandle, AssetBundleUnloadOperation unloadOp)
|
|
636
|
+
#else
|
|
637
|
+
public void Start(ProvideHandle provideHandle)
|
|
638
|
+
#endif
|
|
639
|
+
{
|
|
640
|
+
m_Retries = 0;
|
|
641
|
+
m_AssetBundle = null;
|
|
642
|
+
m_RequestOperation = null;
|
|
643
|
+
m_ProvideHandle = provideHandle;
|
|
644
|
+
m_Options = m_ProvideHandle.Location.Data as AssetBundleRequestOptions;
|
|
645
|
+
m_BytesToDownload = -1;
|
|
646
|
+
m_ProvideHandle.SetProgressCallback(PercentComplete);
|
|
647
|
+
m_ProvideHandle.SetDownloadProgressCallbacks(GetDownloadStatus);
|
|
648
|
+
m_ProvideHandle.SetWaitForCompletionCallback(WaitForCompletionHandler);
|
|
649
|
+
#if UNLOAD_BUNDLE_ASYNC
|
|
650
|
+
m_UnloadOperation = unloadOp;
|
|
651
|
+
if (m_UnloadOperation != null && !m_UnloadOperation.isDone)
|
|
652
|
+
m_UnloadOperation.completed += OnUnloadOperationComplete;
|
|
653
|
+
else
|
|
654
|
+
#endif
|
|
655
|
+
BeginOperation();
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
private bool WaitForCompletionHandler()
|
|
659
|
+
{
|
|
660
|
+
#if UNLOAD_BUNDLE_ASYNC
|
|
661
|
+
if (m_UnloadOperation != null && !m_UnloadOperation.isDone)
|
|
662
|
+
{
|
|
663
|
+
m_UnloadOperation.completed -= OnUnloadOperationComplete;
|
|
664
|
+
m_UnloadOperation.WaitForCompletion();
|
|
665
|
+
m_UnloadOperation = null;
|
|
666
|
+
BeginOperation();
|
|
667
|
+
}
|
|
668
|
+
#endif
|
|
669
|
+
|
|
670
|
+
if (m_RequestOperation == null)
|
|
671
|
+
{
|
|
672
|
+
if (m_WebRequestQueueOperation == null)
|
|
673
|
+
return false;
|
|
674
|
+
else
|
|
675
|
+
WebRequestQueue.WaitForRequestToBeActive(m_WebRequestQueueOperation, k_WaitForWebRequestMainThreadSleep);
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
if (m_RequestOperation is UnityWebRequestAsyncOperation op)
|
|
679
|
+
{
|
|
680
|
+
while (!TTUnityWebRequestUtilities.IsAssetBundleDownloaded(op))
|
|
681
|
+
Thread.Sleep(k_WaitForWebRequestMainThreadSleep);
|
|
682
|
+
#if ENABLE_ASYNC_ASSETBUNDLE_UWR
|
|
683
|
+
if (m_Source == BundleSource.Cache)
|
|
684
|
+
{
|
|
685
|
+
var downloadHandler = (DownloadHandlerTTAssetBundle)op?.webRequest?.downloadHandler;
|
|
686
|
+
if (downloadHandler.autoLoadAssetBundle)
|
|
687
|
+
m_AssetBundle = downloadHandler.assetBundle;
|
|
688
|
+
}
|
|
689
|
+
#endif
|
|
690
|
+
WebRequestQueue.DequeueRequest(op);
|
|
691
|
+
|
|
692
|
+
if (!m_RequestCompletedCallbackCalled)
|
|
693
|
+
{
|
|
694
|
+
m_RequestOperation.completed -= WebRequestOperationCompleted;
|
|
695
|
+
WebRequestOperationCompleted(m_RequestOperation);
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
if (!m_Completed && m_Source == BundleSource.Local)
|
|
700
|
+
{
|
|
701
|
+
if (!m_RequestCompletedCallbackCalled)
|
|
702
|
+
{
|
|
703
|
+
m_RequestOperation.completed -= LocalRequestOperationCompleted;
|
|
704
|
+
LocalRequestOperationCompleted(m_RequestOperation);
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
if (!m_Completed && m_RequestOperation.isDone)
|
|
709
|
+
{
|
|
710
|
+
m_ProvideHandle.Complete(this, m_AssetBundle != null, null);
|
|
711
|
+
m_Completed = true;
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
return m_Completed;
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
void AddCallbackInvokeIfDone(AsyncOperation operation, Action<AsyncOperation> callback)
|
|
718
|
+
{
|
|
719
|
+
if (operation.isDone)
|
|
720
|
+
callback(operation);
|
|
721
|
+
else
|
|
722
|
+
operation.completed += callback;
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
public static void GetLoadInfo(ProvideHandle handle, out LoadType loadType, out string path)
|
|
726
|
+
{
|
|
727
|
+
GetLoadInfo(handle.Location, handle.ResourceManager, out loadType, out path);
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
internal static void GetLoadInfo(IResourceLocation location, ResourceManager resourceManager, out LoadType loadType, out string path)
|
|
731
|
+
{
|
|
732
|
+
var options = location?.Data as AssetBundleRequestOptions;
|
|
733
|
+
if (options == null)
|
|
734
|
+
{
|
|
735
|
+
loadType = LoadType.None;
|
|
736
|
+
path = null;
|
|
737
|
+
return;
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
path = resourceManager.TransformInternalId(location);
|
|
741
|
+
if (Application.platform == RuntimePlatform.Android && path.StartsWith("jar:", StringComparison.Ordinal))
|
|
742
|
+
loadType = options.UseUnityWebRequestForLocalBundles ? LoadType.Web : LoadType.Local;
|
|
743
|
+
else if (ResourceManagerConfig.ShouldPathUseWebRequest(path))
|
|
744
|
+
loadType = LoadType.Web;
|
|
745
|
+
else if (options.UseUnityWebRequestForLocalBundles)
|
|
746
|
+
{
|
|
747
|
+
path = "file:///" + Path.GetFullPath(path);
|
|
748
|
+
loadType = LoadType.Web;
|
|
749
|
+
}
|
|
750
|
+
else
|
|
751
|
+
loadType = LoadType.Local;
|
|
752
|
+
|
|
753
|
+
if (loadType == LoadType.Web)
|
|
754
|
+
path = path.Replace('\\', '/');
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
private void BeginOperation()
|
|
758
|
+
{
|
|
759
|
+
m_DownloadedBytes = 0;
|
|
760
|
+
m_RequestCompletedCallbackCalled = false;
|
|
761
|
+
GetLoadInfo(m_ProvideHandle, out LoadType loadType, out m_TransformedInternalId);
|
|
762
|
+
|
|
763
|
+
if (loadType == LoadType.Local)
|
|
764
|
+
{
|
|
765
|
+
LoadLocalBundle();
|
|
766
|
+
return;
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
if (loadType == LoadType.Web)
|
|
770
|
+
{
|
|
771
|
+
m_WebRequestQueueOperation = EnqueueWebRequest(m_TransformedInternalId);
|
|
772
|
+
AddBeginWebRequestHandler(m_WebRequestQueueOperation);
|
|
773
|
+
return;
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
m_Source = BundleSource.None;
|
|
777
|
+
m_RequestOperation = null;
|
|
778
|
+
m_ProvideHandle.Complete<TTAssetBundleResource>(null, false,
|
|
779
|
+
new RemoteProviderException(string.Format("Invalid path in AssetBundleProvider: '{0}'.", m_TransformedInternalId), m_ProvideHandle.Location));
|
|
780
|
+
m_Completed = true;
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
private void LoadLocalBundle()
|
|
784
|
+
{
|
|
785
|
+
m_Source = BundleSource.Local;
|
|
786
|
+
#if !UNITY_2021_1_OR_NEWER
|
|
787
|
+
if (AsyncOperationHandle.IsWaitingForCompletion)
|
|
788
|
+
CompleteBundleLoad(AssetBundle.LoadFromFile(m_TransformedInternalId, m_Options == null ? 0 : m_Options.Crc));
|
|
789
|
+
else
|
|
790
|
+
#endif
|
|
791
|
+
{
|
|
792
|
+
m_RequestOperation = AssetBundle.LoadFromFileAsync(m_TransformedInternalId, m_Options == null ? 0 : m_Options.Crc);
|
|
793
|
+
#if ENABLE_ADDRESSABLE_PROFILER
|
|
794
|
+
AddBundleToProfiler(Profiling.ContentStatus.Loading, m_Source);
|
|
795
|
+
#endif
|
|
796
|
+
AddCallbackInvokeIfDone(m_RequestOperation, LocalRequestOperationCompleted);
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
internal TTWebRequestQueueOperation EnqueueWebRequest(string internalId)
|
|
801
|
+
{
|
|
802
|
+
var req = CreateWebRequest(internalId);
|
|
803
|
+
#if ENABLE_ASYNC_ASSETBUNDLE_UWR
|
|
804
|
+
((DownloadHandlerAssetBundle)req.downloadHandler).autoLoadAssetBundle = true;
|
|
805
|
+
#endif
|
|
806
|
+
req.disposeDownloadHandlerOnDispose = false;
|
|
807
|
+
|
|
808
|
+
return WebRequestQueue.QueueRequest(req);
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
internal void AddBeginWebRequestHandler(TTWebRequestQueueOperation webRequestQueueOperation)
|
|
812
|
+
{
|
|
813
|
+
if (webRequestQueueOperation.IsDone)
|
|
814
|
+
{
|
|
815
|
+
BeginWebRequestOperation(webRequestQueueOperation.Result);
|
|
816
|
+
}
|
|
817
|
+
else
|
|
818
|
+
{
|
|
819
|
+
#if ENABLE_ADDRESSABLE_PROFILER
|
|
820
|
+
AddBundleToProfiler(Profiling.ContentStatus.Queue, m_Source);
|
|
821
|
+
#endif
|
|
822
|
+
webRequestQueueOperation.OnComplete += asyncOp => BeginWebRequestOperation(asyncOp);
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
private void BeginWebRequestOperation(AsyncOperation asyncOp)
|
|
827
|
+
{
|
|
828
|
+
m_TimeoutTimer = 0;
|
|
829
|
+
m_TimeoutOverFrames = 0;
|
|
830
|
+
m_LastDownloadedByteCount = 0;
|
|
831
|
+
m_RequestOperation = asyncOp;
|
|
832
|
+
if (m_RequestOperation == null || m_RequestOperation.isDone)
|
|
833
|
+
WebRequestOperationCompleted(m_RequestOperation);
|
|
834
|
+
else
|
|
835
|
+
{
|
|
836
|
+
if (m_Options.Timeout > 0)
|
|
837
|
+
m_ProvideHandle.ResourceManager.AddUpdateReceiver(this);
|
|
838
|
+
#if ENABLE_ADDRESSABLE_PROFILER
|
|
839
|
+
AddBundleToProfiler(m_Source == BundleSource.Cache ? Profiling.ContentStatus.Loading : Profiling.ContentStatus.Downloading, m_Source);
|
|
840
|
+
#endif
|
|
841
|
+
m_RequestOperation.completed += WebRequestOperationCompleted;
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
public void Update(float unscaledDeltaTime)
|
|
846
|
+
{
|
|
847
|
+
if (m_RequestOperation != null && m_RequestOperation is UnityWebRequestAsyncOperation operation && !operation.isDone)
|
|
848
|
+
{
|
|
849
|
+
if (m_LastDownloadedByteCount != operation.webRequest.downloadedBytes)
|
|
850
|
+
{
|
|
851
|
+
m_TimeoutTimer = 0;
|
|
852
|
+
m_TimeoutOverFrames = 0;
|
|
853
|
+
m_LastDownloadedByteCount = operation.webRequest.downloadedBytes;
|
|
854
|
+
}
|
|
855
|
+
else
|
|
856
|
+
{
|
|
857
|
+
m_TimeoutTimer += unscaledDeltaTime;
|
|
858
|
+
if (HasTimedOut)
|
|
859
|
+
operation.webRequest.Abort();
|
|
860
|
+
m_TimeoutOverFrames++;
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
private void LocalRequestOperationCompleted(AsyncOperation op)
|
|
866
|
+
{
|
|
867
|
+
if (m_RequestCompletedCallbackCalled)
|
|
868
|
+
{
|
|
869
|
+
return;
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
m_RequestCompletedCallbackCalled = true;
|
|
873
|
+
CompleteBundleLoad((op as TTAssetBundleRequest).assetBundle);
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
private void CompleteBundleLoad(AssetBundle bundle)
|
|
877
|
+
{
|
|
878
|
+
m_AssetBundle = bundle;
|
|
879
|
+
#if ENABLE_ADDRESSABLE_PROFILER
|
|
880
|
+
AddBundleToProfiler(Profiling.ContentStatus.Active, m_Source);
|
|
881
|
+
#endif
|
|
882
|
+
if (m_AssetBundle != null)
|
|
883
|
+
m_ProvideHandle.Complete(this, true, null);
|
|
884
|
+
else
|
|
885
|
+
m_ProvideHandle.Complete<TTAssetBundleResource>(null, false,
|
|
886
|
+
new RemoteProviderException(string.Format("Invalid path in AssetBundleProvider: '{0}'.", m_TransformedInternalId), m_ProvideHandle.Location));
|
|
887
|
+
m_Completed = true;
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
private void WebRequestOperationCompleted(AsyncOperation op)
|
|
891
|
+
{
|
|
892
|
+
if (m_RequestCompletedCallbackCalled)
|
|
893
|
+
return;
|
|
894
|
+
|
|
895
|
+
m_RequestCompletedCallbackCalled = true;
|
|
896
|
+
|
|
897
|
+
if (m_Options.Timeout > 0)
|
|
898
|
+
m_ProvideHandle.ResourceManager.RemoveUpdateReciever(this);
|
|
899
|
+
|
|
900
|
+
UnityWebRequestAsyncOperation remoteReq = op as UnityWebRequestAsyncOperation;
|
|
901
|
+
var webReq = remoteReq?.webRequest;
|
|
902
|
+
var downloadHandler = webReq?.downloadHandler as DownloadHandlerTTAssetBundle;
|
|
903
|
+
TTUnityWebRequestResult uwrResult = null;
|
|
904
|
+
if (webReq != null && !TTUnityWebRequestUtilities.RequestHasErrors(webReq, out uwrResult))
|
|
905
|
+
{
|
|
906
|
+
if (!m_Completed)
|
|
907
|
+
{
|
|
908
|
+
#if ENABLE_ADDRESSABLE_PROFILER
|
|
909
|
+
AddBundleToProfiler(Profiling.ContentStatus.Active, m_Source);
|
|
910
|
+
#endif
|
|
911
|
+
m_AssetBundle = downloadHandler.assetBundle;
|
|
912
|
+
downloadHandler.Dispose();
|
|
913
|
+
downloadHandler = null;
|
|
914
|
+
m_ProvideHandle.Complete(this, true, null);
|
|
915
|
+
m_Completed = true;
|
|
916
|
+
}
|
|
917
|
+
#if ENABLE_CACHING
|
|
918
|
+
if (!string.IsNullOrEmpty(m_Options.Hash) && m_Options.ClearOtherCachedVersionsWhenLoaded)
|
|
919
|
+
Caching.ClearOtherCachedVersions(m_Options.BundleName, Hash128.Parse(m_Options.Hash));
|
|
920
|
+
#endif
|
|
921
|
+
}
|
|
922
|
+
else
|
|
923
|
+
{
|
|
924
|
+
if (HasTimedOut)
|
|
925
|
+
uwrResult.Error = "Request timeout";
|
|
926
|
+
webReq = m_WebRequestQueueOperation.m_WebRequest;
|
|
927
|
+
if (uwrResult == null)
|
|
928
|
+
uwrResult = new TTUnityWebRequestResult(m_WebRequestQueueOperation.m_WebRequest);
|
|
929
|
+
|
|
930
|
+
downloadHandler = webReq.downloadHandler as DownloadHandlerTTAssetBundle;
|
|
931
|
+
downloadHandler.Dispose();
|
|
932
|
+
downloadHandler = null;
|
|
933
|
+
bool forcedRetry = false;
|
|
934
|
+
string message = $"Web request failed, retrying ({m_Retries}/{m_Options.RetryCount})...\n{uwrResult}";
|
|
935
|
+
#if ENABLE_CACHING
|
|
936
|
+
if (!string.IsNullOrEmpty(m_Options.Hash))
|
|
937
|
+
{
|
|
938
|
+
#if ENABLE_ADDRESSABLE_PROFILER
|
|
939
|
+
if (m_Source == BundleSource.Cache)
|
|
940
|
+
#endif
|
|
941
|
+
{
|
|
942
|
+
message = $"Web request failed to load from cache. The cached AssetBundle will be cleared from the cache and re-downloaded. Retrying...\n{uwrResult}";
|
|
943
|
+
Caching.ClearCachedVersion(m_Options.BundleName, Hash128.Parse(m_Options.Hash));
|
|
944
|
+
if (m_Retries == 0 && uwrResult.ShouldRetryDownloadError())
|
|
945
|
+
{
|
|
946
|
+
Debug.LogFormat(message);
|
|
947
|
+
BeginOperation();
|
|
948
|
+
m_Retries++;
|
|
949
|
+
forcedRetry = true;
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
#endif
|
|
954
|
+
if (!forcedRetry)
|
|
955
|
+
{
|
|
956
|
+
if (m_Retries < m_Options.RetryCount && uwrResult.ShouldRetryDownloadError())
|
|
957
|
+
{
|
|
958
|
+
m_Retries++;
|
|
959
|
+
Debug.LogFormat(message);
|
|
960
|
+
BeginOperation();
|
|
961
|
+
}
|
|
962
|
+
else
|
|
963
|
+
{
|
|
964
|
+
var exception = new TTRemoteProviderException($"Unable to load asset bundle from : {webReq.url}", m_ProvideHandle.Location, uwrResult);
|
|
965
|
+
m_ProvideHandle.Complete<TTAssetBundleResource>(null, false, exception);
|
|
966
|
+
m_Completed = true;
|
|
967
|
+
#if ENABLE_ADDRESSABLE_PROFILER
|
|
968
|
+
RemoveBundleFromProfiler();
|
|
969
|
+
#endif
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
webReq.Dispose();
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
#if UNLOAD_BUNDLE_ASYNC
|
|
978
|
+
public bool Unload(out AssetBundleUnloadOperation unloadOp)
|
|
979
|
+
#else
|
|
980
|
+
public void Unload()
|
|
981
|
+
#endif
|
|
982
|
+
{
|
|
983
|
+
#if UNLOAD_BUNDLE_ASYNC
|
|
984
|
+
unloadOp = null;
|
|
985
|
+
if (m_AssetBundle != null)
|
|
986
|
+
{
|
|
987
|
+
unloadOp = m_AssetBundle.UnloadAsync(true);
|
|
988
|
+
m_AssetBundle = null;
|
|
989
|
+
}
|
|
990
|
+
#else
|
|
991
|
+
if (m_AssetBundle != null)
|
|
992
|
+
{
|
|
993
|
+
m_AssetBundle.TTUnload(true);
|
|
994
|
+
m_AssetBundle = null;
|
|
995
|
+
}
|
|
996
|
+
#endif
|
|
997
|
+
m_RequestOperation = null;
|
|
998
|
+
#if ENABLE_ADDRESSABLE_PROFILER
|
|
999
|
+
RemoveBundleFromProfiler();
|
|
1000
|
+
#endif
|
|
1001
|
+
#if UNLOAD_BUNDLE_ASYNC
|
|
1002
|
+
return unloadOp != null;
|
|
1003
|
+
#endif
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
[DisplayName("TTAssetBundle Provider")]
|
|
1008
|
+
public class TTAssetBundleProvider : ResourceProviderBase
|
|
1009
|
+
{
|
|
1010
|
+
#if UNLOAD_BUNDLE_ASYNC
|
|
1011
|
+
internal static Dictionary<string, AssetBundleUnloadOperation> m_UnloadingBundles = new Dictionary<string, AssetBundleUnloadOperation>();
|
|
1012
|
+
|
|
1013
|
+
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
|
|
1014
|
+
private static void Init()
|
|
1015
|
+
{
|
|
1016
|
+
m_UnloadingBundles = new Dictionary<string, AssetBundleUnloadOperation>();
|
|
1017
|
+
}
|
|
1018
|
+
|
|
1019
|
+
protected internal static Dictionary<string, AssetBundleUnloadOperation> UnloadingBundles
|
|
1020
|
+
{
|
|
1021
|
+
get { return m_UnloadingBundles; }
|
|
1022
|
+
internal set { m_UnloadingBundles = value; }
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
internal static int UnloadingAssetBundleCount => m_UnloadingBundles.Count;
|
|
1026
|
+
internal static int AssetBundleCount => AssetBundle.GetAllLoadedAssetBundles().Count() - UnloadingAssetBundleCount;
|
|
1027
|
+
internal static void WaitForAllUnloadingBundlesToComplete()
|
|
1028
|
+
{
|
|
1029
|
+
if (UnloadingAssetBundleCount > 0)
|
|
1030
|
+
{
|
|
1031
|
+
var bundles = m_UnloadingBundles.Values.ToArray();
|
|
1032
|
+
foreach (var b in bundles)
|
|
1033
|
+
b.WaitForCompletion();
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
#else
|
|
1038
|
+
internal static void WaitForAllUnloadingBundlesToComplete()
|
|
1039
|
+
{
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1042
|
+
#endif
|
|
1043
|
+
|
|
1044
|
+
public override void Provide(ProvideHandle providerInterface)
|
|
1045
|
+
{
|
|
1046
|
+
#if UNLOAD_BUNDLE_ASYNC
|
|
1047
|
+
if (m_UnloadingBundles.TryGetValue(providerInterface.Location.InternalId, out var unloadOp))
|
|
1048
|
+
{
|
|
1049
|
+
if (unloadOp.isDone)
|
|
1050
|
+
unloadOp = null;
|
|
1051
|
+
}
|
|
1052
|
+
new TTAssetBundleResource().Start(providerInterface, unloadOp);
|
|
1053
|
+
#else
|
|
1054
|
+
new TTAssetBundleResource().Start(providerInterface);
|
|
1055
|
+
#endif
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
public override Type GetDefaultType(IResourceLocation location)
|
|
1059
|
+
{
|
|
1060
|
+
return typeof(IAssetBundleResource);
|
|
1061
|
+
}
|
|
1062
|
+
|
|
1063
|
+
public override void Release(IResourceLocation location, object asset)
|
|
1064
|
+
{
|
|
1065
|
+
if (location == null)
|
|
1066
|
+
throw new ArgumentNullException("location");
|
|
1067
|
+
if (asset == null)
|
|
1068
|
+
{
|
|
1069
|
+
Debug.LogWarningFormat("Releasing null asset bundle from location {0}. This is an indication that the bundle failed to load.", location);
|
|
1070
|
+
return;
|
|
1071
|
+
}
|
|
1072
|
+
|
|
1073
|
+
var bundle = asset as TTAssetBundleResource;
|
|
1074
|
+
if (bundle != null)
|
|
1075
|
+
{
|
|
1076
|
+
#if UNLOAD_BUNDLE_ASYNC
|
|
1077
|
+
if (bundle.Unload(out var unloadOp))
|
|
1078
|
+
{
|
|
1079
|
+
m_UnloadingBundles.Add(location.InternalId, unloadOp);
|
|
1080
|
+
unloadOp.completed += op => m_UnloadingBundles.Remove(location.InternalId);
|
|
1081
|
+
}
|
|
1082
|
+
#else
|
|
1083
|
+
bundle.Unload();
|
|
1084
|
+
#endif
|
|
1085
|
+
return;
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
|
|
1092
|
+
namespace UnityEngine.ResourceManagement.Exceptions
|
|
1093
|
+
{
|
|
1094
|
+
/// <summary>
|
|
1095
|
+
/// Class representing an error occured during an operation that remotely fetch data.
|
|
1096
|
+
/// </summary>
|
|
1097
|
+
public class TTRemoteProviderException : ProviderException
|
|
1098
|
+
{
|
|
1099
|
+
/// <summary>
|
|
1100
|
+
/// Creates a new instance of <see cref="ProviderException"/>.
|
|
1101
|
+
/// </summary>
|
|
1102
|
+
/// <param name="message">A message describing the error.</param>
|
|
1103
|
+
/// <param name="location">The resource location that the operation was trying to provide.</param>
|
|
1104
|
+
/// <param name="uwrResult">The result of the unity web request, if any.</param>
|
|
1105
|
+
/// <param name="innerException">The exception that caused the error, if any.</param>
|
|
1106
|
+
public TTRemoteProviderException(string message, IResourceLocation location = null,
|
|
1107
|
+
TTUnityWebRequestResult uwrResult = null, Exception innerException = null)
|
|
1108
|
+
: base(message, location, innerException)
|
|
1109
|
+
{
|
|
1110
|
+
WebRequestResult = uwrResult;
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1113
|
+
///<inheritdoc/>
|
|
1114
|
+
public override string Message => this.ToString();
|
|
1115
|
+
|
|
1116
|
+
/// <summary>
|
|
1117
|
+
/// The result of the unity web request, if any.
|
|
1118
|
+
/// </summary>
|
|
1119
|
+
public TTUnityWebRequestResult WebRequestResult { get; }
|
|
1120
|
+
|
|
1121
|
+
/// <summary>Provides a new string object describing the exception.</summary>
|
|
1122
|
+
/// <returns>A newly allocated managed string.</returns>
|
|
1123
|
+
public override string ToString()
|
|
1124
|
+
{
|
|
1125
|
+
if (WebRequestResult != null)
|
|
1126
|
+
return
|
|
1127
|
+
$"{GetType().Name} : {base.Message}\nUnityWebRequest result : {WebRequestResult}\n{InnerException}";
|
|
1128
|
+
else
|
|
1129
|
+
return base.ToString();
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
}
|
|
1133
|
+
|
|
1134
|
+
namespace UnityEngine.ResourceManagement.Util
|
|
1135
|
+
{
|
|
1136
|
+
internal class TTUnityWebRequestUtilities
|
|
1137
|
+
{
|
|
1138
|
+
public static bool RequestHasErrors(UnityWebRequest webReq, out TTUnityWebRequestResult result)
|
|
1139
|
+
{
|
|
1140
|
+
result = null;
|
|
1141
|
+
if (webReq == null || !webReq.isDone)
|
|
1142
|
+
return false;
|
|
1143
|
+
|
|
1144
|
+
#if UNITY_2020_1_OR_NEWER
|
|
1145
|
+
switch (webReq.result)
|
|
1146
|
+
{
|
|
1147
|
+
case UnityWebRequest.Result.InProgress:
|
|
1148
|
+
case UnityWebRequest.Result.Success:
|
|
1149
|
+
return false;
|
|
1150
|
+
case UnityWebRequest.Result.ConnectionError:
|
|
1151
|
+
case UnityWebRequest.Result.ProtocolError:
|
|
1152
|
+
case UnityWebRequest.Result.DataProcessingError:
|
|
1153
|
+
result = new TTUnityWebRequestResult(webReq);
|
|
1154
|
+
return true;
|
|
1155
|
+
default:
|
|
1156
|
+
throw new NotImplementedException($"Cannot determine whether UnityWebRequest succeeded or not from result : {webReq.result}");
|
|
1157
|
+
}
|
|
1158
|
+
#else
|
|
1159
|
+
var isError = webReq.isHttpError || webReq.isNetworkError;
|
|
1160
|
+
if (isError)
|
|
1161
|
+
result = new UnityWebRequestResult(webReq);
|
|
1162
|
+
|
|
1163
|
+
return isError;
|
|
1164
|
+
#endif
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
internal static bool IsAssetBundleDownloaded(UnityWebRequestAsyncOperation op)
|
|
1168
|
+
{
|
|
1169
|
+
#if ENABLE_ASYNC_ASSETBUNDLE_UWR
|
|
1170
|
+
var handler = (DownloadHandlerAssetBundle)op.webRequest.downloadHandler;
|
|
1171
|
+
if (handler != null && handler.autoLoadAssetBundle)
|
|
1172
|
+
return handler.isDownloadComplete;
|
|
1173
|
+
#endif
|
|
1174
|
+
return op.isDone;
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
|
|
1178
|
+
/// <summary>
|
|
1179
|
+
/// Container class for the result of a unity web request.
|
|
1180
|
+
/// </summary>
|
|
1181
|
+
public class TTUnityWebRequestResult
|
|
1182
|
+
{
|
|
1183
|
+
/// <summary>
|
|
1184
|
+
/// Creates a new instance of <see cref="UnityWebRequestResult"/>.
|
|
1185
|
+
/// </summary>
|
|
1186
|
+
/// <param name="request">The unity web request.</param>
|
|
1187
|
+
public TTUnityWebRequestResult(UnityWebRequest request)
|
|
1188
|
+
{
|
|
1189
|
+
string error = request.error;
|
|
1190
|
+
#if UNITY_2020_1_OR_NEWER
|
|
1191
|
+
if (request.result == UnityWebRequest.Result.DataProcessingError && request.downloadHandler != null)
|
|
1192
|
+
{
|
|
1193
|
+
error = $"{error} : {request.downloadHandler.error}";
|
|
1194
|
+
}
|
|
1195
|
+
|
|
1196
|
+
Result = request.result;
|
|
1197
|
+
#endif
|
|
1198
|
+
Error = error;
|
|
1199
|
+
ResponseCode = request.responseCode;
|
|
1200
|
+
Method = request.method;
|
|
1201
|
+
Url = request.url;
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1204
|
+
/// <summary>Provides a new string object describing the result.</summary>
|
|
1205
|
+
/// <returns>A newly allocated managed string.</returns>
|
|
1206
|
+
public override string ToString()
|
|
1207
|
+
{
|
|
1208
|
+
var sb = new System.Text.StringBuilder();
|
|
1209
|
+
|
|
1210
|
+
#if UNITY_2020_1_OR_NEWER
|
|
1211
|
+
sb.AppendLine($"{Result} : {Error}");
|
|
1212
|
+
#else
|
|
1213
|
+
if (!string.IsNullOrEmpty(Error))
|
|
1214
|
+
sb.AppendLine(Error);
|
|
1215
|
+
#endif
|
|
1216
|
+
if (ResponseCode > 0)
|
|
1217
|
+
sb.AppendLine($"ResponseCode : {ResponseCode}, Method : {Method}");
|
|
1218
|
+
sb.AppendLine($"url : {Url}");
|
|
1219
|
+
|
|
1220
|
+
return sb.ToString();
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1223
|
+
/// <summary>
|
|
1224
|
+
/// A string explaining the error that occured.
|
|
1225
|
+
/// </summary>
|
|
1226
|
+
public string Error { get; internal set; }
|
|
1227
|
+
|
|
1228
|
+
/// <summary>
|
|
1229
|
+
/// The numeric HTTP response code returned by the server, if any.
|
|
1230
|
+
/// See <a href="https://docs.unity3d.com/ScriptReference/Networking.UnityWebRequest-responseCode.html">documentation</a> for more details.
|
|
1231
|
+
/// </summary>
|
|
1232
|
+
public long ResponseCode { get; }
|
|
1233
|
+
|
|
1234
|
+
#if UNITY_2020_1_OR_NEWER
|
|
1235
|
+
/// <summary>
|
|
1236
|
+
/// The outcome of the request.
|
|
1237
|
+
/// </summary>
|
|
1238
|
+
public UnityWebRequest.Result Result { get; }
|
|
1239
|
+
#endif
|
|
1240
|
+
/// <summary>
|
|
1241
|
+
/// The HTTP verb used by this UnityWebRequest, such as GET or POST.
|
|
1242
|
+
/// </summary>
|
|
1243
|
+
public string Method { get; }
|
|
1244
|
+
|
|
1245
|
+
/// <summary>
|
|
1246
|
+
/// The target url of the request.
|
|
1247
|
+
/// </summary>
|
|
1248
|
+
public string Url { get; }
|
|
1249
|
+
|
|
1250
|
+
internal bool ShouldRetryDownloadError()
|
|
1251
|
+
{
|
|
1252
|
+
if (string.IsNullOrEmpty(Error))
|
|
1253
|
+
return true;
|
|
1254
|
+
|
|
1255
|
+
if (Error == "Request aborted" ||
|
|
1256
|
+
Error == "Unable to write data" ||
|
|
1257
|
+
Error == "Malformed URL" ||
|
|
1258
|
+
Error == "Out of memory" ||
|
|
1259
|
+
Error == "Encountered invalid redirect (missing Location header?)" ||
|
|
1260
|
+
Error == "Cannot modify request at this time" ||
|
|
1261
|
+
Error == "Unsupported Protocol" ||
|
|
1262
|
+
Error == "Destination host has an erroneous SSL certificate" ||
|
|
1263
|
+
Error == "Unable to load SSL Cipher for verification" ||
|
|
1264
|
+
Error == "SSL CA certificate error" ||
|
|
1265
|
+
Error == "Unrecognized content-encoding" ||
|
|
1266
|
+
Error == "Request already transmitted" ||
|
|
1267
|
+
Error == "Invalid HTTP Method" ||
|
|
1268
|
+
Error == "Header name contains invalid characters" ||
|
|
1269
|
+
Error == "Header value contains invalid characters" ||
|
|
1270
|
+
Error == "Cannot override system-specified headers"
|
|
1271
|
+
)
|
|
1272
|
+
return false;
|
|
1273
|
+
|
|
1274
|
+
/* Errors that can be retried:
|
|
1275
|
+
"Unknown Error":
|
|
1276
|
+
"No Internet Connection"
|
|
1277
|
+
"Backend Initialization Error":
|
|
1278
|
+
"Cannot resolve proxy":
|
|
1279
|
+
"Cannot resolve destination host":
|
|
1280
|
+
"Cannot connect to destination host":
|
|
1281
|
+
"Access denied":
|
|
1282
|
+
"Generic/unknown HTTP error":
|
|
1283
|
+
"Unable to read data":
|
|
1284
|
+
"Request timeout":
|
|
1285
|
+
"Error during HTTP POST transmission":
|
|
1286
|
+
"Unable to complete SSL connection":
|
|
1287
|
+
"Redirect limit exceeded":
|
|
1288
|
+
"Received no data in response":
|
|
1289
|
+
"Destination host does not support SSL":
|
|
1290
|
+
"Failed to transmit data":
|
|
1291
|
+
"Failed to receive data":
|
|
1292
|
+
"Login failed":
|
|
1293
|
+
"SSL shutdown failed":
|
|
1294
|
+
"Redirect limit is invalid":
|
|
1295
|
+
"Not implemented":
|
|
1296
|
+
"Data Processing Error, see Download Handler error":
|
|
1297
|
+
*/
|
|
1298
|
+
return true;
|
|
1299
|
+
}
|
|
1300
|
+
}
|
|
1301
|
+
}
|