com.taptap.sdk.cloudsave 4.10.1-beta.1 → 4.10.2

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.
Files changed (64) hide show
  1. package/Mobile/Editor/NativeDependencies.xml +14 -14
  2. package/Mobile/Editor/NativeDependencies.xml.meta +2 -2
  3. package/Mobile/Editor/TapCloudSaveMobileProcessBuild.cs +20 -20
  4. package/Mobile/Editor/TapCloudSaveMobileProcessBuild.cs.meta +11 -11
  5. package/Mobile/Editor/TapSDK.CloudSave.Mobile.Editor.asmdef +16 -16
  6. package/Mobile/Editor/TapSDK.CloudSave.Mobile.Editor.asmdef.meta +7 -7
  7. package/Mobile/Editor.meta +8 -8
  8. package/Mobile/Runtime/TapCloudSaveBridge.cs +589 -589
  9. package/Mobile/Runtime/TapCloudSaveBridge.cs.meta +11 -11
  10. package/Mobile/Runtime/TapSDK.CloudSave.Mobile.Runtime.asmdef +19 -19
  11. package/Mobile/Runtime/TapSDK.CloudSave.Mobile.Runtime.asmdef.meta +7 -7
  12. package/Mobile/Runtime.meta +8 -8
  13. package/Mobile.meta +8 -8
  14. package/Runtime/Internal/ITapCloudSaveBridge.cs +24 -24
  15. package/Runtime/Internal/ITapCloudSaveBridge.cs.meta +11 -11
  16. package/Runtime/Internal/TapCloudSaveInitTask.cs +19 -19
  17. package/Runtime/Internal/TapCloudSaveInitTask.cs.meta +11 -11
  18. package/Runtime/Internal/TapTapCloudSaveInternal.cs +51 -51
  19. package/Runtime/Internal/TapTapCloudSaveInternal.cs.meta +11 -11
  20. package/Runtime/Internal.meta +8 -8
  21. package/Runtime/Public/ArchiveData.cs +33 -33
  22. package/Runtime/Public/ArchiveData.cs.meta +2 -2
  23. package/Runtime/Public/ITapCloudSaveCallback.cs +8 -8
  24. package/Runtime/Public/ITapCloudSaveCallback.cs.meta +2 -2
  25. package/Runtime/Public/ITapCloudSaveRequestCallback.cs +14 -14
  26. package/Runtime/Public/ITapCloudSaveRequestCallback.cs.meta +2 -2
  27. package/Runtime/Public/TapCloudSaveRequestCallbackAdapter.cs +34 -34
  28. package/Runtime/Public/TapCloudSaveRequestCallbackAdapter.cs.meta +2 -2
  29. package/Runtime/Public/TapTapCloudSave.cs +39 -39
  30. package/Runtime/Public/TapTapCloudSave.cs.meta +11 -11
  31. package/Runtime/Public.meta +8 -8
  32. package/Runtime/TapSDK.CloudSave.Runtime.asmdef +14 -14
  33. package/Runtime/TapSDK.CloudSave.Runtime.asmdef.meta +7 -7
  34. package/Runtime.meta +8 -8
  35. package/Standalone/Editor/TapCloudSaveStandaloneProcessBuild.cs +26 -26
  36. package/Standalone/Editor/TapCloudSaveStandaloneProcessBuild.cs.meta +11 -11
  37. package/Standalone/Editor/TapSDK.CloudSave.Standalone.Editor.asmdef +16 -16
  38. package/Standalone/Editor/TapSDK.CloudSave.Standalone.Editor.asmdef.meta +7 -7
  39. package/Standalone/Editor.meta +8 -8
  40. package/Standalone/Plugins/x86_64/cloudsave_sdk.dll +0 -0
  41. package/Standalone/Plugins/x86_64/cloudsave_sdk.dll.meta +80 -80
  42. package/Standalone/Plugins/x86_64.meta +8 -8
  43. package/Standalone/Plugins.meta +8 -8
  44. package/Standalone/Runtime/Internal/TapCloudSaveArchiveListResponse.cs +11 -11
  45. package/Standalone/Runtime/Internal/TapCloudSaveArchiveListResponse.cs.meta +11 -11
  46. package/Standalone/Runtime/Internal/TapCloudSaveBaseResponse.cs +29 -29
  47. package/Standalone/Runtime/Internal/TapCloudSaveBaseResponse.cs.meta +11 -11
  48. package/Standalone/Runtime/Internal/TapCloudSaveTracker.cs +101 -101
  49. package/Standalone/Runtime/Internal/TapCloudSaveTracker.cs.meta +11 -11
  50. package/Standalone/Runtime/Internal/TapCloudSaveWrapper.cs +583 -561
  51. package/Standalone/Runtime/Internal/TapCloudSaveWrapper.cs.meta +11 -11
  52. package/Standalone/Runtime/Internal.meta +8 -8
  53. package/Standalone/Runtime/TapCloudSaveResultCode.cs +9 -9
  54. package/Standalone/Runtime/TapCloudSaveResultCode.cs.meta +11 -11
  55. package/Standalone/Runtime/TapCloudSaveStandalone.cs +712 -712
  56. package/Standalone/Runtime/TapCloudSaveStandalone.cs.meta +11 -11
  57. package/Standalone/Runtime.meta +8 -8
  58. package/Standalone/TapSDK.CloudSave.Standalone.Runtime.asmdef +21 -21
  59. package/Standalone/TapSDK.CloudSave.Standalone.Runtime.asmdef.meta +7 -7
  60. package/Standalone.meta +8 -8
  61. package/link.xml +3 -3
  62. package/link.xml.meta +7 -7
  63. package/package.json +11 -11
  64. package/package.json.meta +7 -7
@@ -1,590 +1,590 @@
1
- using System.Collections.Generic;
2
- using TapSDK.Core;
3
- using System;
4
- using System.Threading.Tasks;
5
- using Newtonsoft.Json;
6
- using TapSDK.CloudSave.Internal;
7
- using TapSDK.Core.Internal.Log;
8
-
9
- namespace TapSDK.CloudSave.Mobile
10
- {
11
- public class ErrorResponse
12
- {
13
- [JsonProperty("errorCode")] public int ErrorCode { get; set; }
14
- [JsonProperty("errorMessage")] public string ErrorMessage { get; set; }
15
- }
16
-
17
- public class TapCloudSaveBridge : ITapCloudSaveBridge
18
- {
19
- public static string TAP_CLOUDSAVE_SERVICE = "BridgeCloudSaveService";
20
-
21
- public static string TDS_CLOUDSAVE_SERVICE_CLZ = "com.taptap.sdk.cloudsave.unity.BridgeCloudSaveService";
22
-
23
- public static string TDS_CLOUDSAVE_SERVICE_IMPL = "com.taptap.sdk.cloudsave.unity.BridgeCloudSaveServiceImpl";
24
-
25
- // 全局callback管理
26
- private readonly List<ITapCloudSaveCallback> callbacks = new List<ITapCloudSaveCallback>();
27
- private bool hasRegisteredNativeCallback = false;
28
-
29
- public TapCloudSaveBridge()
30
- {
31
- EngineBridge.GetInstance().Register(TDS_CLOUDSAVE_SERVICE_CLZ, TDS_CLOUDSAVE_SERVICE_IMPL);
32
- }
33
-
34
- public void Init(TapTapSdkOptions options)
35
- {
36
- // 原生由原生内部实现
37
- }
38
-
39
- public void RegisterCloudSaveCallback(ITapCloudSaveCallback callback)
40
- {
41
- TapLog.Log("[TapCloudSaveBridge] RegisterCloudSaveCallback called with global callback management");
42
-
43
- if (callback != null)
44
- {
45
- // 添加到全局callback列表
46
- if (!callbacks.Contains(callback))
47
- {
48
- callbacks.Add(callback);
49
- TapLog.Log($"[TapCloudSaveBridge] Added callback. Total callbacks: {callbacks.Count}");
50
- }
51
- else
52
- {
53
- TapLog.Log("[TapCloudSaveBridge] Callback already registered");
54
- }
55
-
56
- // 初始化注册原生callback(只注册一次)
57
- InitRegisterNativeCallback();
58
- }
59
- }
60
-
61
- public void UnregisterCloudSaveCallback(ITapCloudSaveCallback callback)
62
- {
63
- TapLog.Log("[TapCloudSaveBridge] UnregisterCloudSaveCallback called");
64
-
65
- if (callback != null)
66
- {
67
- if (callbacks.Contains(callback))
68
- {
69
- callbacks.Remove(callback);
70
- TapLog.Log($"[TapCloudSaveBridge] Removed callback. Remaining callbacks: {callbacks.Count}");
71
-
72
- // 当没有callback时,取消注册原生callback
73
- if (callbacks.Count == 0 && hasRegisteredNativeCallback)
74
- {
75
- var command = new Command.Builder()
76
- .Service(TAP_CLOUDSAVE_SERVICE)
77
- .Method("unregisterCloudSaveCallback")
78
- .Callback(false)
79
- .OnceTime(false);
80
- EngineBridge.GetInstance().CallHandler(command.CommandBuilder());
81
- hasRegisteredNativeCallback = false;
82
- TapLog.Log("[TapCloudSaveBridge] Unregistered native callback");
83
- }
84
- }
85
- else
86
- {
87
- TapLog.Log("[TapCloudSaveBridge] Callback not found");
88
- }
89
- }
90
- }
91
-
92
- private void InitRegisterNativeCallback()
93
- {
94
- if (hasRegisteredNativeCallback)
95
- {
96
- return;
97
- }
98
- hasRegisteredNativeCallback = true;
99
-
100
- var command = new Command.Builder()
101
- .Service(TAP_CLOUDSAVE_SERVICE)
102
- .Method("registerCloudSaveCallback")
103
- .Callback(true)
104
- .OnceTime(false);
105
-
106
- EngineBridge.GetInstance().CallHandler(command.CommandBuilder(), (response) =>
107
- {
108
- TapLog.Log($"[TapCloudSaveBridge] Native callback received: code={response.code}, content={response.content}");
109
-
110
- if (callbacks.Count == 0) return;
111
-
112
- try
113
- {
114
- int resultCode = -1;
115
-
116
- // 修复:始终尝试解析content中的resultCode,不要因为response.code失败就跳过
117
- // iOS端会在TapSDKResult.content中传递真实的错误码(如300001 NEED_LOGIN)
118
- if (!string.IsNullOrEmpty(response.content))
119
- {
120
- try
121
- {
122
- var result = JsonConvert.DeserializeObject<TapEngineBridgeResult>(response.content);
123
- if (result != null && !string.IsNullOrEmpty(result.content))
124
- {
125
- // 尝试解析为字典(iOS格式:{"resultCode": 300001})
126
- try
127
- {
128
- var dataDict = JsonConvert.DeserializeObject<Dictionary<string, object>>(result.content);
129
- if (dataDict != null && dataDict.ContainsKey("resultCode"))
130
- {
131
- resultCode = SafeDictionary.GetValue<int>(dataDict, "resultCode", -1);
132
- TapLog.Log($"[TapCloudSaveBridge] Parsed resultCode from dictionary: {resultCode}");
133
- }
134
- else
135
- {
136
- // 尝试直接解析为int(兼容旧格式)
137
- resultCode = JsonConvert.DeserializeObject<int>(result.content);
138
- TapLog.Log($"[TapCloudSaveBridge] Parsed resultCode directly: {resultCode}");
139
- }
140
- }
141
- catch
142
- {
143
- // 如果无法解析为字典,尝试直接解析为int
144
- resultCode = JsonConvert.DeserializeObject<int>(result.content);
145
- TapLog.Log($"[TapCloudSaveBridge] Parsed resultCode as int: {resultCode}");
146
- }
147
- }
148
- }
149
- catch (Exception parseEx)
150
- {
151
- TapLog.Error($"[TapCloudSaveBridge] Failed to parse TapEngineBridgeResult: {parseEx.Message}, using -1");
152
- resultCode = -1;
153
- }
154
- }
155
- else
156
- {
157
- TapLog.Error("[TapCloudSaveBridge] Response content is null or empty, using -1");
158
- }
159
-
160
- TapLog.Log($"[TapCloudSaveBridge] Final resultCode: {resultCode}");
161
-
162
- // 通知所有已注册的callback
163
- foreach (var callback in callbacks)
164
- {
165
- try
166
- {
167
- callback?.OnResult(resultCode);
168
- }
169
- catch (Exception e)
170
- {
171
- TapLog.Log($"[TapCloudSaveBridge] Error in callback execution: {e.Message}");
172
- }
173
- }
174
- }
175
- catch (Exception e)
176
- {
177
- TapLog.Log($"[TapCloudSaveBridge] Error processing native callback: {e.Message}");
178
-
179
- // 即使解析错误,也要通知所有callback
180
- foreach (var callback in callbacks)
181
- {
182
- try
183
- {
184
- callback?.OnResult(-1);
185
- }
186
- catch (Exception callbackException)
187
- {
188
- TapLog.Log($"[TapCloudSaveBridge] Error in callback execution during error handling: {callbackException.Message}");
189
- }
190
- }
191
- }
192
- });
193
-
194
- TapLog.Log("[TapCloudSaveBridge] Initialized native callback registration");
195
- }
196
-
197
- public Task<ArchiveData> CreateArchive(ArchiveMetadata metadata, string archiveFilePath, string archiveCoverPath)
198
- {
199
- TapLog.Log("[TapCloudSaveBridge] CreateArchive called with Task<ArchiveData> return type (NEW API)");
200
- var taskSource = new TaskCompletionSource<ArchiveData>();
201
- EngineBridge.GetInstance().CallHandler(new Command.Builder()
202
- .Service(TAP_CLOUDSAVE_SERVICE)
203
- .Method("createArchive")
204
- .Args("archiveMetadata", JsonConvert.SerializeObject(metadata))
205
- .Args("archiveFilePath", archiveFilePath)
206
- .Args("archiveCoverPath", archiveCoverPath)
207
- .Callback(true)
208
- .OnceTime(true)
209
- .CommandBuilder(),
210
- response =>
211
- {
212
- try
213
- {
214
- if (response.code != Result.RESULT_SUCCESS || string.IsNullOrEmpty(response.content))
215
- {
216
- taskSource.TrySetException(new TapException(-1, "Failed to create archive: code="+response.code + " content="+response.content));
217
- return;
218
- }
219
-
220
- var result = JsonConvert.DeserializeObject<TapEngineBridgeResult>(response.content);
221
- if (result != null && result.code == TapEngineBridgeResult.RESULT_SUCCESS)
222
- {
223
- var archive = JsonConvert.DeserializeObject<ArchiveData>(result.content);
224
- if (archive != null)
225
- {
226
- taskSource.TrySetResult(archive);
227
- }
228
- else
229
- {
230
- taskSource.TrySetException(new TapException(-1, "json convert failed: content="+result.content));
231
- }
232
- }
233
- else
234
- {
235
- try
236
- {
237
- var errorResponse = JsonConvert.DeserializeObject<ErrorResponse>(result.content);
238
- if (errorResponse != null)
239
- {
240
- taskSource.TrySetException(new TapException(errorResponse.ErrorCode, errorResponse.ErrorMessage));
241
- }
242
- else
243
- {
244
- taskSource.TrySetException(new TapException(-1, "Failed to create archive: content="+response.content));
245
- }
246
- }
247
- catch (Exception e)
248
- {
249
- taskSource.TrySetException(new TapException(-1, "Failed to create archive: content="+response.content));
250
- }
251
- }
252
- }
253
- catch (Exception e)
254
- {
255
- taskSource.TrySetException(new TapException(-1, "Failed to create archive: error=" + e.Message + ", content=" + response.content));
256
- }
257
- });
258
- return taskSource.Task;
259
- }
260
-
261
- public Task<ArchiveData> UpdateArchive(string archiveUuid, ArchiveMetadata metadata, string archiveFilePath, string archiveCoverPath)
262
- {
263
- TapLog.Log("[TapCloudSaveBridge] UpdateArchive called with Task<ArchiveData> return type (NEW API)");
264
- var taskSource = new TaskCompletionSource<ArchiveData>();
265
- EngineBridge.GetInstance().CallHandler(new Command.Builder()
266
- .Service(TAP_CLOUDSAVE_SERVICE)
267
- .Method("updateArchive")
268
- .Args("archiveUUIDForUpdate", archiveUuid)
269
- .Args("archiveMetadataForUpdate", JsonConvert.SerializeObject(metadata))
270
- .Args("archiveFilePathForUpdate", archiveFilePath)
271
- .Args("archiveCoverPathForUpdate", archiveCoverPath)
272
- .Callback(true)
273
- .OnceTime(true)
274
- .CommandBuilder(), (response) =>
275
- {
276
- try
277
- {
278
- if (response.code != Result.RESULT_SUCCESS || string.IsNullOrEmpty(response.content))
279
- {
280
- taskSource.TrySetException(new TapException(-1, "Failed to update archive: code="+response.code + " content="+response.content));
281
- return;
282
- }
283
-
284
- var result = JsonConvert.DeserializeObject<TapEngineBridgeResult>(response.content);
285
- if (result != null && result.code == TapEngineBridgeResult.RESULT_SUCCESS)
286
- {
287
- var archive = JsonConvert.DeserializeObject<ArchiveData>(result.content);
288
- if (archive != null)
289
- {
290
- taskSource.TrySetResult(archive);
291
- }
292
- else
293
- {
294
- taskSource.TrySetException(new TapException(-1, "json convert failed: content="+result.content));
295
- }
296
- }
297
- else
298
- {
299
- try
300
- {
301
- var errorResponse = JsonConvert.DeserializeObject<ErrorResponse>(result.content);
302
- if (errorResponse != null)
303
- {
304
- taskSource.TrySetException(new TapException(errorResponse.ErrorCode, errorResponse.ErrorMessage));
305
- }
306
- else
307
- {
308
- taskSource.TrySetException(new TapException(-1, "Failed to update archive: content="+response.content));
309
- }
310
- }
311
- catch (Exception e)
312
- {
313
- taskSource.TrySetException(new TapException(-1, "Failed to update archive: content="+response.content));
314
- }
315
- }
316
- }
317
- catch (Exception e)
318
- {
319
- taskSource.TrySetException(new TapException(-1, "Failed to update archive: error=" + e.Message + ", content=" + response.content));
320
- }
321
- });
322
- return taskSource.Task;
323
- }
324
-
325
- public Task<ArchiveData> DeleteArchive(string archiveUuid)
326
- {
327
- TapLog.Log("[TapCloudSaveBridge] DeleteArchive called with Task<ArchiveData> return type (NEW API)");
328
- var taskSource = new TaskCompletionSource<ArchiveData>();
329
- EngineBridge.GetInstance().CallHandler(new Command.Builder()
330
- .Service(TAP_CLOUDSAVE_SERVICE)
331
- .Method("deleteArchive")
332
- .Args("archiveUUID", archiveUuid)
333
- .Callback(true)
334
- .OnceTime(true)
335
- .CommandBuilder(), (response) =>
336
- {
337
- try
338
- {
339
- if (response.code != Result.RESULT_SUCCESS || string.IsNullOrEmpty(response.content))
340
- {
341
- taskSource.TrySetException(new TapException(-1, "Failed to delete archive: code="+response.code + " content="+response.content));
342
- return;
343
- }
344
-
345
- var result = JsonConvert.DeserializeObject<TapEngineBridgeResult>(response.content);
346
- if (result != null && result.code == TapEngineBridgeResult.RESULT_SUCCESS)
347
- {
348
- var archive = JsonConvert.DeserializeObject<ArchiveData>(result.content);
349
- if (archive != null)
350
- {
351
- taskSource.TrySetResult(archive);
352
- }
353
- else
354
- {
355
- taskSource.TrySetException(new TapException(-1, "json convert failed: content="+result.content));
356
- }
357
- }
358
- else
359
- {
360
- try
361
- {
362
- var errorResponse = JsonConvert.DeserializeObject<ErrorResponse>(result.content);
363
- if (errorResponse != null)
364
- {
365
- taskSource.TrySetException(new TapException(errorResponse.ErrorCode, errorResponse.ErrorMessage));
366
- }
367
- else
368
- {
369
- taskSource.TrySetException(new TapException(-1, "Failed to delete archive: content="+response.content));
370
- }
371
- }
372
- catch (Exception e)
373
- {
374
- taskSource.TrySetException(new TapException(-1, "Failed to delete archive: content="+response.content));
375
- }
376
- }
377
- }
378
- catch (Exception e)
379
- {
380
- taskSource.TrySetException(new TapException(-1, "Failed to delete archive: error=" + e.Message + ", content=" + response.content));
381
- }
382
- });
383
- return taskSource.Task;
384
- }
385
-
386
- public Task<List<ArchiveData>> GetArchiveList()
387
- {
388
- TapLog.Log("[TapCloudSaveBridge] 🚀 GetArchiveList called - Starting archive list request");
389
- TapLog.Log($"[TapCloudSaveBridge] 📋 Service: {TAP_CLOUDSAVE_SERVICE}, Method: getArchiveList");
390
-
391
- var taskSource = new TaskCompletionSource<List<ArchiveData>>();
392
- var command = new Command.Builder()
393
- .Service(TAP_CLOUDSAVE_SERVICE)
394
- .Method("getArchiveList")
395
- .Callback(true)
396
- .OnceTime(true)
397
- .CommandBuilder();
398
-
399
- TapLog.Log($"[TapCloudSaveBridge] 📤 Sending command to iOS: {command.ToJSON()}");
400
-
401
- EngineBridge.GetInstance().CallHandler(command, (response) =>
402
- {
403
- TapLog.Log($"[TapCloudSaveBridge] 📥 Received response from iOS - Code: {response.code}, Content length: {response.content?.Length ?? 0}");
404
-
405
- try
406
- {
407
- if (response.code != Result.RESULT_SUCCESS || string.IsNullOrEmpty(response.content))
408
- {
409
- TapLog.Log($"[TapCloudSaveBridge] ❌ Response failed - Code: {response.code}, Content: {response.content}");
410
- taskSource.TrySetException(new TapException(-1, "Failed to get archive list: code="+response.code + " content="+response.content));
411
- return;
412
- }
413
-
414
- TapLog.Log($"[TapCloudSaveBridge] 🔍 Parsing response content: {response.content.Substring(0, Math.Min(200, response.content.Length))}...");
415
-
416
- var result = JsonConvert.DeserializeObject<TapEngineBridgeResult>(response.content);
417
- if (result != null && result.code == TapEngineBridgeResult.RESULT_SUCCESS)
418
- {
419
- TapLog.Log($"[TapCloudSaveBridge] ✅ Bridge result successful, parsing archive list content: {result.content?.Substring(0, Math.Min(100, result.content?.Length ?? 0))}...");
420
-
421
- var archiveList = JsonConvert.DeserializeObject<List<ArchiveData>>(result.content);
422
- if (archiveList != null)
423
- {
424
- TapLog.Log($"[TapCloudSaveBridge] 🎉 Successfully parsed {archiveList.Count} archives, completing task");
425
- taskSource.TrySetResult(archiveList);
426
- }
427
- else
428
- {
429
- TapLog.Log($"[TapCloudSaveBridge] ❌ Failed to deserialize archive list from content: {result.content}");
430
- taskSource.TrySetException(new TapException(-1, "json convert failed: content="+result.content));
431
- }
432
- }
433
- else
434
- {
435
- TapLog.Log($"[TapCloudSaveBridge] ❌ Bridge result failed - Code: {result?.code}, Content: {result?.content}");
436
- try
437
- {
438
- var errorResponse = JsonConvert.DeserializeObject<ErrorResponse>(result.content);
439
- if (errorResponse != null)
440
- {
441
- TapLog.Log($"[TapCloudSaveBridge] 📋 Parsed error response - Code: {errorResponse.ErrorCode}, Message: {errorResponse.ErrorMessage}");
442
- taskSource.TrySetException(new TapException(errorResponse.ErrorCode, errorResponse.ErrorMessage));
443
- }
444
- else
445
- {
446
- TapLog.Log("[TapCloudSaveBridge] ❌ Failed to parse error response, raw content: " + response.content);
447
- taskSource.TrySetException(new TapException(-1, "Failed to get archive list: content="+response.content));
448
- }
449
- }
450
- catch (Exception e)
451
- {
452
- TapLog.Log($"[TapCloudSaveBridge] ❌ Exception while parsing error response: {e.Message}");
453
- taskSource.TrySetException(new TapException(-1, "Failed to get archive list: content="+response.content));
454
- }
455
- }
456
- }
457
- catch (Exception e)
458
- {
459
- TapLog.Log($"[TapCloudSaveBridge] ❌ Top-level exception while processing response: {e.Message}");
460
- taskSource.TrySetException(new TapException(-1, "Failed to get archive list: error=" + e.Message + ", content=" + response.content));
461
- }
462
- });
463
- return taskSource.Task;
464
- }
465
-
466
- public Task<byte[]> GetArchiveData(string archiveUuid, string archiveFileId)
467
- {
468
- TapLog.Log("[TapCloudSaveBridge] GetArchiveData called with Task<byte[]> return type (NEW API)");
469
- var taskSource = new TaskCompletionSource<byte[]>();
470
- EngineBridge.GetInstance().CallHandler(new Command.Builder()
471
- .Service(TAP_CLOUDSAVE_SERVICE)
472
- .Method("getArchiveData")
473
- .Args("archiveUUID", archiveUuid)
474
- .Args("archiveFileID", archiveFileId)
475
- .Callback(true)
476
- .OnceTime(true)
477
- .CommandBuilder(), (response) =>
478
- {
479
- try
480
- {
481
- if (response.code != Result.RESULT_SUCCESS || string.IsNullOrEmpty(response.content))
482
- {
483
- taskSource.TrySetException(new TapException(-1, "Failed to get archive data: code=" + response.code + " content="+response.content));
484
- return;
485
- }
486
-
487
- var result = JsonConvert.DeserializeObject<TapEngineBridgeResult>(response.content);
488
- if (result != null && result.code == TapEngineBridgeResult.RESULT_SUCCESS)
489
- {
490
- var archiveData = Convert.FromBase64String(result.content);
491
- if (archiveData != null)
492
- {
493
- taskSource.TrySetResult(archiveData);
494
- }
495
- else
496
- {
497
- taskSource.TrySetException(new TapException(-1, "json convert failed: content="+result.content));
498
- }
499
- }
500
- else
501
- {
502
- try
503
- {
504
- var errorResponse = JsonConvert.DeserializeObject<ErrorResponse>(result.content);
505
- if (errorResponse != null)
506
- {
507
- taskSource.TrySetException(new TapException(errorResponse.ErrorCode, errorResponse.ErrorMessage));
508
- }
509
- else
510
- {
511
- taskSource.TrySetException(new TapException(-1, "Failed to get archive data: content="+response.content));
512
- }
513
- }
514
- catch (Exception e)
515
- {
516
- taskSource.TrySetException(new TapException(-1, "Failed to get archive data: content="+response.content));
517
- }
518
- }
519
- }
520
- catch (Exception e)
521
- {
522
- taskSource.TrySetException(new TapException(-1, "Failed to get archive data: error=" + e.Message + ", content=" + response.content));
523
- }
524
- });
525
- return taskSource.Task;
526
- }
527
-
528
- public Task<byte[]> GetArchiveCover(string archiveUuid, string archiveFileId)
529
- {
530
- TapLog.Log("[TapCloudSaveBridge] GetArchiveCover called with Task<byte[]> return type (NEW API)");
531
- var taskSource = new TaskCompletionSource<byte[]>();
532
- EngineBridge.GetInstance().CallHandler(new Command.Builder()
533
- .Service(TAP_CLOUDSAVE_SERVICE)
534
- .Method("getArchiveCover")
535
- .Args("archiveUUIDForCover", archiveUuid)
536
- .Args("archiveFileIDForCover", archiveFileId)
537
- .Callback(true)
538
- .OnceTime(true)
539
- .CommandBuilder(), (response) =>
540
- {
541
- try
542
- {
543
- if (response.code != Result.RESULT_SUCCESS || string.IsNullOrEmpty(response.content))
544
- {
545
- taskSource.TrySetException(new TapException(-1, "Failed to get archive cover: code="+response.code + " content="+response.content));
546
- return;
547
- }
548
-
549
- var result = JsonConvert.DeserializeObject<TapEngineBridgeResult>(response.content);
550
- if (result != null && result.code == TapEngineBridgeResult.RESULT_SUCCESS)
551
- {
552
- var coverData = Convert.FromBase64String(result.content);
553
- if (coverData != null)
554
- {
555
- taskSource.TrySetResult(coverData);
556
- }
557
- else
558
- {
559
- taskSource.TrySetException(new TapException(-1, "json convert failed: content="+result.content));
560
- }
561
- }
562
- else
563
- {
564
- try
565
- {
566
- var errorResponse = JsonConvert.DeserializeObject<ErrorResponse>(result.content);
567
- if (errorResponse != null)
568
- {
569
- taskSource.TrySetException(new TapException(errorResponse.ErrorCode, errorResponse.ErrorMessage));
570
- }
571
- else
572
- {
573
- taskSource.TrySetException(new TapException(-1, "Failed to get archive cover: content="+response.content));
574
- }
575
- }
576
- catch (Exception e)
577
- {
578
- taskSource.TrySetException(new TapException(-1, "Failed to get archive cover: content="+response.content));
579
- }
580
- }
581
- }
582
- catch (Exception e)
583
- {
584
- taskSource.TrySetException(new TapException(-1, "Failed to get archive cover: error=" + e.Message + ", content=" + response.content));
585
- }
586
- });
587
- return taskSource.Task;
588
- }
589
- }
1
+ using System.Collections.Generic;
2
+ using TapSDK.Core;
3
+ using System;
4
+ using System.Threading.Tasks;
5
+ using Newtonsoft.Json;
6
+ using TapSDK.CloudSave.Internal;
7
+ using TapSDK.Core.Internal.Log;
8
+
9
+ namespace TapSDK.CloudSave.Mobile
10
+ {
11
+ public class ErrorResponse
12
+ {
13
+ [JsonProperty("errorCode")] public int ErrorCode { get; set; }
14
+ [JsonProperty("errorMessage")] public string ErrorMessage { get; set; }
15
+ }
16
+
17
+ public class TapCloudSaveBridge : ITapCloudSaveBridge
18
+ {
19
+ public static string TAP_CLOUDSAVE_SERVICE = "BridgeCloudSaveService";
20
+
21
+ public static string TDS_CLOUDSAVE_SERVICE_CLZ = "com.taptap.sdk.cloudsave.unity.BridgeCloudSaveService";
22
+
23
+ public static string TDS_CLOUDSAVE_SERVICE_IMPL = "com.taptap.sdk.cloudsave.unity.BridgeCloudSaveServiceImpl";
24
+
25
+ // 全局callback管理
26
+ private readonly List<ITapCloudSaveCallback> callbacks = new List<ITapCloudSaveCallback>();
27
+ private bool hasRegisteredNativeCallback = false;
28
+
29
+ public TapCloudSaveBridge()
30
+ {
31
+ EngineBridge.GetInstance().Register(TDS_CLOUDSAVE_SERVICE_CLZ, TDS_CLOUDSAVE_SERVICE_IMPL);
32
+ }
33
+
34
+ public void Init(TapTapSdkOptions options)
35
+ {
36
+ // 原生由原生内部实现
37
+ }
38
+
39
+ public void RegisterCloudSaveCallback(ITapCloudSaveCallback callback)
40
+ {
41
+ TapLog.Log("[TapCloudSaveBridge] RegisterCloudSaveCallback called with global callback management");
42
+
43
+ if (callback != null)
44
+ {
45
+ // 添加到全局callback列表
46
+ if (!callbacks.Contains(callback))
47
+ {
48
+ callbacks.Add(callback);
49
+ TapLog.Log($"[TapCloudSaveBridge] Added callback. Total callbacks: {callbacks.Count}");
50
+ }
51
+ else
52
+ {
53
+ TapLog.Log("[TapCloudSaveBridge] Callback already registered");
54
+ }
55
+
56
+ // 初始化注册原生callback(只注册一次)
57
+ InitRegisterNativeCallback();
58
+ }
59
+ }
60
+
61
+ public void UnregisterCloudSaveCallback(ITapCloudSaveCallback callback)
62
+ {
63
+ TapLog.Log("[TapCloudSaveBridge] UnregisterCloudSaveCallback called");
64
+
65
+ if (callback != null)
66
+ {
67
+ if (callbacks.Contains(callback))
68
+ {
69
+ callbacks.Remove(callback);
70
+ TapLog.Log($"[TapCloudSaveBridge] Removed callback. Remaining callbacks: {callbacks.Count}");
71
+
72
+ // 当没有callback时,取消注册原生callback
73
+ if (callbacks.Count == 0 && hasRegisteredNativeCallback)
74
+ {
75
+ var command = new Command.Builder()
76
+ .Service(TAP_CLOUDSAVE_SERVICE)
77
+ .Method("unregisterCloudSaveCallback")
78
+ .Callback(false)
79
+ .OnceTime(false);
80
+ EngineBridge.GetInstance().CallHandler(command.CommandBuilder());
81
+ hasRegisteredNativeCallback = false;
82
+ TapLog.Log("[TapCloudSaveBridge] Unregistered native callback");
83
+ }
84
+ }
85
+ else
86
+ {
87
+ TapLog.Log("[TapCloudSaveBridge] Callback not found");
88
+ }
89
+ }
90
+ }
91
+
92
+ private void InitRegisterNativeCallback()
93
+ {
94
+ if (hasRegisteredNativeCallback)
95
+ {
96
+ return;
97
+ }
98
+ hasRegisteredNativeCallback = true;
99
+
100
+ var command = new Command.Builder()
101
+ .Service(TAP_CLOUDSAVE_SERVICE)
102
+ .Method("registerCloudSaveCallback")
103
+ .Callback(true)
104
+ .OnceTime(false);
105
+
106
+ EngineBridge.GetInstance().CallHandler(command.CommandBuilder(), (response) =>
107
+ {
108
+ TapLog.Log($"[TapCloudSaveBridge] Native callback received: code={response.code}, content={response.content}");
109
+
110
+ if (callbacks.Count == 0) return;
111
+
112
+ try
113
+ {
114
+ int resultCode = -1;
115
+
116
+ // 修复:始终尝试解析content中的resultCode,不要因为response.code失败就跳过
117
+ // iOS端会在TapSDKResult.content中传递真实的错误码(如300001 NEED_LOGIN)
118
+ if (!string.IsNullOrEmpty(response.content))
119
+ {
120
+ try
121
+ {
122
+ var result = JsonConvert.DeserializeObject<TapEngineBridgeResult>(response.content);
123
+ if (result != null && !string.IsNullOrEmpty(result.content))
124
+ {
125
+ // 尝试解析为字典(iOS格式:{"resultCode": 300001})
126
+ try
127
+ {
128
+ var dataDict = JsonConvert.DeserializeObject<Dictionary<string, object>>(result.content);
129
+ if (dataDict != null && dataDict.ContainsKey("resultCode"))
130
+ {
131
+ resultCode = SafeDictionary.GetValue<int>(dataDict, "resultCode", -1);
132
+ TapLog.Log($"[TapCloudSaveBridge] Parsed resultCode from dictionary: {resultCode}");
133
+ }
134
+ else
135
+ {
136
+ // 尝试直接解析为int(兼容旧格式)
137
+ resultCode = JsonConvert.DeserializeObject<int>(result.content);
138
+ TapLog.Log($"[TapCloudSaveBridge] Parsed resultCode directly: {resultCode}");
139
+ }
140
+ }
141
+ catch
142
+ {
143
+ // 如果无法解析为字典,尝试直接解析为int
144
+ resultCode = JsonConvert.DeserializeObject<int>(result.content);
145
+ TapLog.Log($"[TapCloudSaveBridge] Parsed resultCode as int: {resultCode}");
146
+ }
147
+ }
148
+ }
149
+ catch (Exception parseEx)
150
+ {
151
+ TapLog.Error($"[TapCloudSaveBridge] Failed to parse TapEngineBridgeResult: {parseEx.Message}, using -1");
152
+ resultCode = -1;
153
+ }
154
+ }
155
+ else
156
+ {
157
+ TapLog.Error("[TapCloudSaveBridge] Response content is null or empty, using -1");
158
+ }
159
+
160
+ TapLog.Log($"[TapCloudSaveBridge] Final resultCode: {resultCode}");
161
+
162
+ // 通知所有已注册的callback
163
+ foreach (var callback in callbacks)
164
+ {
165
+ try
166
+ {
167
+ callback?.OnResult(resultCode);
168
+ }
169
+ catch (Exception e)
170
+ {
171
+ TapLog.Log($"[TapCloudSaveBridge] Error in callback execution: {e.Message}");
172
+ }
173
+ }
174
+ }
175
+ catch (Exception e)
176
+ {
177
+ TapLog.Log($"[TapCloudSaveBridge] Error processing native callback: {e.Message}");
178
+
179
+ // 即使解析错误,也要通知所有callback
180
+ foreach (var callback in callbacks)
181
+ {
182
+ try
183
+ {
184
+ callback?.OnResult(-1);
185
+ }
186
+ catch (Exception callbackException)
187
+ {
188
+ TapLog.Log($"[TapCloudSaveBridge] Error in callback execution during error handling: {callbackException.Message}");
189
+ }
190
+ }
191
+ }
192
+ });
193
+
194
+ TapLog.Log("[TapCloudSaveBridge] Initialized native callback registration");
195
+ }
196
+
197
+ public Task<ArchiveData> CreateArchive(ArchiveMetadata metadata, string archiveFilePath, string archiveCoverPath)
198
+ {
199
+ TapLog.Log("[TapCloudSaveBridge] CreateArchive called with Task<ArchiveData> return type (NEW API)");
200
+ var taskSource = new TaskCompletionSource<ArchiveData>();
201
+ EngineBridge.GetInstance().CallHandler(new Command.Builder()
202
+ .Service(TAP_CLOUDSAVE_SERVICE)
203
+ .Method("createArchive")
204
+ .Args("archiveMetadata", JsonConvert.SerializeObject(metadata))
205
+ .Args("archiveFilePath", archiveFilePath)
206
+ .Args("archiveCoverPath", archiveCoverPath)
207
+ .Callback(true)
208
+ .OnceTime(true)
209
+ .CommandBuilder(),
210
+ response =>
211
+ {
212
+ try
213
+ {
214
+ if (response.code != Result.RESULT_SUCCESS || string.IsNullOrEmpty(response.content))
215
+ {
216
+ taskSource.TrySetException(new TapException(-1, "Failed to create archive: code="+response.code + " content="+response.content));
217
+ return;
218
+ }
219
+
220
+ var result = JsonConvert.DeserializeObject<TapEngineBridgeResult>(response.content);
221
+ if (result != null && result.code == TapEngineBridgeResult.RESULT_SUCCESS)
222
+ {
223
+ var archive = JsonConvert.DeserializeObject<ArchiveData>(result.content);
224
+ if (archive != null)
225
+ {
226
+ taskSource.TrySetResult(archive);
227
+ }
228
+ else
229
+ {
230
+ taskSource.TrySetException(new TapException(-1, "json convert failed: content="+result.content));
231
+ }
232
+ }
233
+ else
234
+ {
235
+ try
236
+ {
237
+ var errorResponse = JsonConvert.DeserializeObject<ErrorResponse>(result.content);
238
+ if (errorResponse != null)
239
+ {
240
+ taskSource.TrySetException(new TapException(errorResponse.ErrorCode, errorResponse.ErrorMessage));
241
+ }
242
+ else
243
+ {
244
+ taskSource.TrySetException(new TapException(-1, "Failed to create archive: content="+response.content));
245
+ }
246
+ }
247
+ catch (Exception e)
248
+ {
249
+ taskSource.TrySetException(new TapException(-1, "Failed to create archive: content="+response.content));
250
+ }
251
+ }
252
+ }
253
+ catch (Exception e)
254
+ {
255
+ taskSource.TrySetException(new TapException(-1, "Failed to create archive: error=" + e.Message + ", content=" + response.content));
256
+ }
257
+ });
258
+ return taskSource.Task;
259
+ }
260
+
261
+ public Task<ArchiveData> UpdateArchive(string archiveUuid, ArchiveMetadata metadata, string archiveFilePath, string archiveCoverPath)
262
+ {
263
+ TapLog.Log("[TapCloudSaveBridge] UpdateArchive called with Task<ArchiveData> return type (NEW API)");
264
+ var taskSource = new TaskCompletionSource<ArchiveData>();
265
+ EngineBridge.GetInstance().CallHandler(new Command.Builder()
266
+ .Service(TAP_CLOUDSAVE_SERVICE)
267
+ .Method("updateArchive")
268
+ .Args("archiveUUIDForUpdate", archiveUuid)
269
+ .Args("archiveMetadataForUpdate", JsonConvert.SerializeObject(metadata))
270
+ .Args("archiveFilePathForUpdate", archiveFilePath)
271
+ .Args("archiveCoverPathForUpdate", archiveCoverPath)
272
+ .Callback(true)
273
+ .OnceTime(true)
274
+ .CommandBuilder(), (response) =>
275
+ {
276
+ try
277
+ {
278
+ if (response.code != Result.RESULT_SUCCESS || string.IsNullOrEmpty(response.content))
279
+ {
280
+ taskSource.TrySetException(new TapException(-1, "Failed to update archive: code="+response.code + " content="+response.content));
281
+ return;
282
+ }
283
+
284
+ var result = JsonConvert.DeserializeObject<TapEngineBridgeResult>(response.content);
285
+ if (result != null && result.code == TapEngineBridgeResult.RESULT_SUCCESS)
286
+ {
287
+ var archive = JsonConvert.DeserializeObject<ArchiveData>(result.content);
288
+ if (archive != null)
289
+ {
290
+ taskSource.TrySetResult(archive);
291
+ }
292
+ else
293
+ {
294
+ taskSource.TrySetException(new TapException(-1, "json convert failed: content="+result.content));
295
+ }
296
+ }
297
+ else
298
+ {
299
+ try
300
+ {
301
+ var errorResponse = JsonConvert.DeserializeObject<ErrorResponse>(result.content);
302
+ if (errorResponse != null)
303
+ {
304
+ taskSource.TrySetException(new TapException(errorResponse.ErrorCode, errorResponse.ErrorMessage));
305
+ }
306
+ else
307
+ {
308
+ taskSource.TrySetException(new TapException(-1, "Failed to update archive: content="+response.content));
309
+ }
310
+ }
311
+ catch (Exception e)
312
+ {
313
+ taskSource.TrySetException(new TapException(-1, "Failed to update archive: content="+response.content));
314
+ }
315
+ }
316
+ }
317
+ catch (Exception e)
318
+ {
319
+ taskSource.TrySetException(new TapException(-1, "Failed to update archive: error=" + e.Message + ", content=" + response.content));
320
+ }
321
+ });
322
+ return taskSource.Task;
323
+ }
324
+
325
+ public Task<ArchiveData> DeleteArchive(string archiveUuid)
326
+ {
327
+ TapLog.Log("[TapCloudSaveBridge] DeleteArchive called with Task<ArchiveData> return type (NEW API)");
328
+ var taskSource = new TaskCompletionSource<ArchiveData>();
329
+ EngineBridge.GetInstance().CallHandler(new Command.Builder()
330
+ .Service(TAP_CLOUDSAVE_SERVICE)
331
+ .Method("deleteArchive")
332
+ .Args("archiveUUID", archiveUuid)
333
+ .Callback(true)
334
+ .OnceTime(true)
335
+ .CommandBuilder(), (response) =>
336
+ {
337
+ try
338
+ {
339
+ if (response.code != Result.RESULT_SUCCESS || string.IsNullOrEmpty(response.content))
340
+ {
341
+ taskSource.TrySetException(new TapException(-1, "Failed to delete archive: code="+response.code + " content="+response.content));
342
+ return;
343
+ }
344
+
345
+ var result = JsonConvert.DeserializeObject<TapEngineBridgeResult>(response.content);
346
+ if (result != null && result.code == TapEngineBridgeResult.RESULT_SUCCESS)
347
+ {
348
+ var archive = JsonConvert.DeserializeObject<ArchiveData>(result.content);
349
+ if (archive != null)
350
+ {
351
+ taskSource.TrySetResult(archive);
352
+ }
353
+ else
354
+ {
355
+ taskSource.TrySetException(new TapException(-1, "json convert failed: content="+result.content));
356
+ }
357
+ }
358
+ else
359
+ {
360
+ try
361
+ {
362
+ var errorResponse = JsonConvert.DeserializeObject<ErrorResponse>(result.content);
363
+ if (errorResponse != null)
364
+ {
365
+ taskSource.TrySetException(new TapException(errorResponse.ErrorCode, errorResponse.ErrorMessage));
366
+ }
367
+ else
368
+ {
369
+ taskSource.TrySetException(new TapException(-1, "Failed to delete archive: content="+response.content));
370
+ }
371
+ }
372
+ catch (Exception e)
373
+ {
374
+ taskSource.TrySetException(new TapException(-1, "Failed to delete archive: content="+response.content));
375
+ }
376
+ }
377
+ }
378
+ catch (Exception e)
379
+ {
380
+ taskSource.TrySetException(new TapException(-1, "Failed to delete archive: error=" + e.Message + ", content=" + response.content));
381
+ }
382
+ });
383
+ return taskSource.Task;
384
+ }
385
+
386
+ public Task<List<ArchiveData>> GetArchiveList()
387
+ {
388
+ TapLog.Log("[TapCloudSaveBridge] 🚀 GetArchiveList called - Starting archive list request");
389
+ TapLog.Log($"[TapCloudSaveBridge] 📋 Service: {TAP_CLOUDSAVE_SERVICE}, Method: getArchiveList");
390
+
391
+ var taskSource = new TaskCompletionSource<List<ArchiveData>>();
392
+ var command = new Command.Builder()
393
+ .Service(TAP_CLOUDSAVE_SERVICE)
394
+ .Method("getArchiveList")
395
+ .Callback(true)
396
+ .OnceTime(true)
397
+ .CommandBuilder();
398
+
399
+ TapLog.Log($"[TapCloudSaveBridge] 📤 Sending command to iOS: {command.ToJSON()}");
400
+
401
+ EngineBridge.GetInstance().CallHandler(command, (response) =>
402
+ {
403
+ TapLog.Log($"[TapCloudSaveBridge] 📥 Received response from iOS - Code: {response.code}, Content length: {response.content?.Length ?? 0}");
404
+
405
+ try
406
+ {
407
+ if (response.code != Result.RESULT_SUCCESS || string.IsNullOrEmpty(response.content))
408
+ {
409
+ TapLog.Log($"[TapCloudSaveBridge] ❌ Response failed - Code: {response.code}, Content: {response.content}");
410
+ taskSource.TrySetException(new TapException(-1, "Failed to get archive list: code="+response.code + " content="+response.content));
411
+ return;
412
+ }
413
+
414
+ TapLog.Log($"[TapCloudSaveBridge] 🔍 Parsing response content: {response.content.Substring(0, Math.Min(200, response.content.Length))}...");
415
+
416
+ var result = JsonConvert.DeserializeObject<TapEngineBridgeResult>(response.content);
417
+ if (result != null && result.code == TapEngineBridgeResult.RESULT_SUCCESS)
418
+ {
419
+ TapLog.Log($"[TapCloudSaveBridge] ✅ Bridge result successful, parsing archive list content: {result.content?.Substring(0, Math.Min(100, result.content?.Length ?? 0))}...");
420
+
421
+ var archiveList = JsonConvert.DeserializeObject<List<ArchiveData>>(result.content);
422
+ if (archiveList != null)
423
+ {
424
+ TapLog.Log($"[TapCloudSaveBridge] 🎉 Successfully parsed {archiveList.Count} archives, completing task");
425
+ taskSource.TrySetResult(archiveList);
426
+ }
427
+ else
428
+ {
429
+ TapLog.Log($"[TapCloudSaveBridge] ❌ Failed to deserialize archive list from content: {result.content}");
430
+ taskSource.TrySetException(new TapException(-1, "json convert failed: content="+result.content));
431
+ }
432
+ }
433
+ else
434
+ {
435
+ TapLog.Log($"[TapCloudSaveBridge] ❌ Bridge result failed - Code: {result?.code}, Content: {result?.content}");
436
+ try
437
+ {
438
+ var errorResponse = JsonConvert.DeserializeObject<ErrorResponse>(result.content);
439
+ if (errorResponse != null)
440
+ {
441
+ TapLog.Log($"[TapCloudSaveBridge] 📋 Parsed error response - Code: {errorResponse.ErrorCode}, Message: {errorResponse.ErrorMessage}");
442
+ taskSource.TrySetException(new TapException(errorResponse.ErrorCode, errorResponse.ErrorMessage));
443
+ }
444
+ else
445
+ {
446
+ TapLog.Log("[TapCloudSaveBridge] ❌ Failed to parse error response, raw content: " + response.content);
447
+ taskSource.TrySetException(new TapException(-1, "Failed to get archive list: content="+response.content));
448
+ }
449
+ }
450
+ catch (Exception e)
451
+ {
452
+ TapLog.Log($"[TapCloudSaveBridge] ❌ Exception while parsing error response: {e.Message}");
453
+ taskSource.TrySetException(new TapException(-1, "Failed to get archive list: content="+response.content));
454
+ }
455
+ }
456
+ }
457
+ catch (Exception e)
458
+ {
459
+ TapLog.Log($"[TapCloudSaveBridge] ❌ Top-level exception while processing response: {e.Message}");
460
+ taskSource.TrySetException(new TapException(-1, "Failed to get archive list: error=" + e.Message + ", content=" + response.content));
461
+ }
462
+ });
463
+ return taskSource.Task;
464
+ }
465
+
466
+ public Task<byte[]> GetArchiveData(string archiveUuid, string archiveFileId)
467
+ {
468
+ TapLog.Log("[TapCloudSaveBridge] GetArchiveData called with Task<byte[]> return type (NEW API)");
469
+ var taskSource = new TaskCompletionSource<byte[]>();
470
+ EngineBridge.GetInstance().CallHandler(new Command.Builder()
471
+ .Service(TAP_CLOUDSAVE_SERVICE)
472
+ .Method("getArchiveData")
473
+ .Args("archiveUUID", archiveUuid)
474
+ .Args("archiveFileID", archiveFileId)
475
+ .Callback(true)
476
+ .OnceTime(true)
477
+ .CommandBuilder(), (response) =>
478
+ {
479
+ try
480
+ {
481
+ if (response.code != Result.RESULT_SUCCESS || string.IsNullOrEmpty(response.content))
482
+ {
483
+ taskSource.TrySetException(new TapException(-1, "Failed to get archive data: code=" + response.code + " content="+response.content));
484
+ return;
485
+ }
486
+
487
+ var result = JsonConvert.DeserializeObject<TapEngineBridgeResult>(response.content);
488
+ if (result != null && result.code == TapEngineBridgeResult.RESULT_SUCCESS)
489
+ {
490
+ var archiveData = Convert.FromBase64String(result.content);
491
+ if (archiveData != null)
492
+ {
493
+ taskSource.TrySetResult(archiveData);
494
+ }
495
+ else
496
+ {
497
+ taskSource.TrySetException(new TapException(-1, "json convert failed: content="+result.content));
498
+ }
499
+ }
500
+ else
501
+ {
502
+ try
503
+ {
504
+ var errorResponse = JsonConvert.DeserializeObject<ErrorResponse>(result.content);
505
+ if (errorResponse != null)
506
+ {
507
+ taskSource.TrySetException(new TapException(errorResponse.ErrorCode, errorResponse.ErrorMessage));
508
+ }
509
+ else
510
+ {
511
+ taskSource.TrySetException(new TapException(-1, "Failed to get archive data: content="+response.content));
512
+ }
513
+ }
514
+ catch (Exception e)
515
+ {
516
+ taskSource.TrySetException(new TapException(-1, "Failed to get archive data: content="+response.content));
517
+ }
518
+ }
519
+ }
520
+ catch (Exception e)
521
+ {
522
+ taskSource.TrySetException(new TapException(-1, "Failed to get archive data: error=" + e.Message + ", content=" + response.content));
523
+ }
524
+ });
525
+ return taskSource.Task;
526
+ }
527
+
528
+ public Task<byte[]> GetArchiveCover(string archiveUuid, string archiveFileId)
529
+ {
530
+ TapLog.Log("[TapCloudSaveBridge] GetArchiveCover called with Task<byte[]> return type (NEW API)");
531
+ var taskSource = new TaskCompletionSource<byte[]>();
532
+ EngineBridge.GetInstance().CallHandler(new Command.Builder()
533
+ .Service(TAP_CLOUDSAVE_SERVICE)
534
+ .Method("getArchiveCover")
535
+ .Args("archiveUUIDForCover", archiveUuid)
536
+ .Args("archiveFileIDForCover", archiveFileId)
537
+ .Callback(true)
538
+ .OnceTime(true)
539
+ .CommandBuilder(), (response) =>
540
+ {
541
+ try
542
+ {
543
+ if (response.code != Result.RESULT_SUCCESS || string.IsNullOrEmpty(response.content))
544
+ {
545
+ taskSource.TrySetException(new TapException(-1, "Failed to get archive cover: code="+response.code + " content="+response.content));
546
+ return;
547
+ }
548
+
549
+ var result = JsonConvert.DeserializeObject<TapEngineBridgeResult>(response.content);
550
+ if (result != null && result.code == TapEngineBridgeResult.RESULT_SUCCESS)
551
+ {
552
+ var coverData = Convert.FromBase64String(result.content);
553
+ if (coverData != null)
554
+ {
555
+ taskSource.TrySetResult(coverData);
556
+ }
557
+ else
558
+ {
559
+ taskSource.TrySetException(new TapException(-1, "json convert failed: content="+result.content));
560
+ }
561
+ }
562
+ else
563
+ {
564
+ try
565
+ {
566
+ var errorResponse = JsonConvert.DeserializeObject<ErrorResponse>(result.content);
567
+ if (errorResponse != null)
568
+ {
569
+ taskSource.TrySetException(new TapException(errorResponse.ErrorCode, errorResponse.ErrorMessage));
570
+ }
571
+ else
572
+ {
573
+ taskSource.TrySetException(new TapException(-1, "Failed to get archive cover: content="+response.content));
574
+ }
575
+ }
576
+ catch (Exception e)
577
+ {
578
+ taskSource.TrySetException(new TapException(-1, "Failed to get archive cover: content="+response.content));
579
+ }
580
+ }
581
+ }
582
+ catch (Exception e)
583
+ {
584
+ taskSource.TrySetException(new TapException(-1, "Failed to get archive cover: error=" + e.Message + ", content=" + response.content));
585
+ }
586
+ });
587
+ return taskSource.Task;
588
+ }
589
+ }
590
590
  }