TapCloudSaveBridge.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453
  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. namespace TapSDK.CloudSave.Mobile
  9. {
  10. public class ErrorResponse
  11. {
  12. [JsonProperty("errorCode")] public int ErrorCode { get; set; }
  13. [JsonProperty("errorMessage")] public string ErrorMessage { get; set; }
  14. }
  15. public class TapCloudSaveBridge : ITapCloudSaveBridge
  16. {
  17. public static string TAP_CLOUDSAVE_SERVICE = "BridgeCloudSaveService";
  18. public static string TDS_CLOUDSAVE_SERVICE_CLZ = "com.taptap.sdk.cloudsave.unity.BridgeCloudSaveService";
  19. public static string TDS_CLOUDSAVE_SERVICE_IMPL = "com.taptap.sdk.cloudsave.unity.BridgeCloudSaveServiceImpl";
  20. public TapCloudSaveBridge()
  21. {
  22. EngineBridge.GetInstance().Register(TDS_CLOUDSAVE_SERVICE_CLZ, TDS_CLOUDSAVE_SERVICE_IMPL);
  23. }
  24. public void Init(TapTapSdkOptions options)
  25. {
  26. // 原生由原生内部实现
  27. }
  28. public void RegisterCloudSaveCallback(ITapCloudSaveCallback callback)
  29. {
  30. TapLog.Log("[TapCloudSaveBridge] RegisterCloudSaveCallback called (UNCHANGED callback pattern)");
  31. EngineBridge.GetInstance().CallHandler(new Command.Builder()
  32. .Service(TAP_CLOUDSAVE_SERVICE)
  33. .Method("registerCloudSaveCallback")
  34. .Callback(true)
  35. .OnceTime(true)
  36. .CommandBuilder(), (response) =>
  37. {
  38. if (callback == null) return;
  39. try
  40. {
  41. if (response.code != Result.RESULT_SUCCESS || string.IsNullOrEmpty(response.content))
  42. {
  43. callback.OnResult(-1);
  44. return;
  45. }
  46. var result = JsonConvert.DeserializeObject<TapEngineBridgeResult>(response.content);
  47. if (result != null && result.code == TapEngineBridgeResult.RESULT_SUCCESS)
  48. {
  49. var resultCode = JsonConvert.DeserializeObject<int>(result.content);
  50. if (resultCode != null)
  51. {
  52. callback.OnResult(resultCode);
  53. }
  54. else
  55. {
  56. callback.OnResult(-1);
  57. }
  58. }
  59. else
  60. {
  61. callback.OnResult(-1);
  62. }
  63. }
  64. catch (Exception e)
  65. {
  66. callback.OnResult(-1);
  67. }
  68. });
  69. }
  70. public Task<ArchiveData> CreateArchive(ArchiveMetadata metadata, string archiveFilePath, string archiveCoverPath)
  71. {
  72. TapLog.Log("[TapCloudSaveBridge] CreateArchive called with Task<ArchiveData> return type (NEW API)");
  73. var taskSource = new TaskCompletionSource<ArchiveData>();
  74. EngineBridge.GetInstance().CallHandler(new Command.Builder()
  75. .Service(TAP_CLOUDSAVE_SERVICE)
  76. .Method("createArchive")
  77. .Args("archiveMetadata", JsonConvert.SerializeObject(metadata))
  78. .Args("archiveFilePath", archiveFilePath)
  79. .Args("archiveCoverPath", archiveCoverPath)
  80. .Callback(true)
  81. .OnceTime(true)
  82. .CommandBuilder(),
  83. response =>
  84. {
  85. try
  86. {
  87. if (response.code != Result.RESULT_SUCCESS || string.IsNullOrEmpty(response.content))
  88. {
  89. taskSource.TrySetException(new TapException(-1, "Failed to create archive: code="+response.code + " content="+response.content));
  90. return;
  91. }
  92. var result = JsonConvert.DeserializeObject<TapEngineBridgeResult>(response.content);
  93. if (result != null && result.code == TapEngineBridgeResult.RESULT_SUCCESS)
  94. {
  95. var archive = JsonConvert.DeserializeObject<ArchiveData>(result.content);
  96. if (archive != null)
  97. {
  98. taskSource.TrySetResult(archive);
  99. }
  100. else
  101. {
  102. taskSource.TrySetException(new TapException(-1, "json convert failed: content="+result.content));
  103. }
  104. }
  105. else
  106. {
  107. try
  108. {
  109. var errorResponse = JsonConvert.DeserializeObject<ErrorResponse>(result.content);
  110. if (errorResponse != null)
  111. {
  112. taskSource.TrySetException(new TapException(errorResponse.ErrorCode, errorResponse.ErrorMessage));
  113. }
  114. else
  115. {
  116. taskSource.TrySetException(new TapException(-1, "Failed to create archive: content="+response.content));
  117. }
  118. }
  119. catch (Exception e)
  120. {
  121. taskSource.TrySetException(new TapException(-1, "Failed to create archive: content="+response.content));
  122. }
  123. }
  124. }
  125. catch (Exception e)
  126. {
  127. taskSource.TrySetException(new TapException(-1, "Failed to create archive: error=" + e.Message + ", content=" + response.content));
  128. }
  129. });
  130. return taskSource.Task;
  131. }
  132. public Task<ArchiveData> UpdateArchive(string archiveUuid, ArchiveMetadata metadata, string archiveFilePath, string archiveCoverPath)
  133. {
  134. TapLog.Log("[TapCloudSaveBridge] UpdateArchive called with Task<ArchiveData> return type (NEW API)");
  135. var taskSource = new TaskCompletionSource<ArchiveData>();
  136. EngineBridge.GetInstance().CallHandler(new Command.Builder()
  137. .Service(TAP_CLOUDSAVE_SERVICE)
  138. .Method("updateArchive")
  139. .Args("archiveUUIDForUpdate", archiveUuid)
  140. .Args("archiveMetadataForUpdate", JsonConvert.SerializeObject(metadata))
  141. .Args("archiveFilePathForUpdate", archiveFilePath)
  142. .Args("archiveCoverPathForUpdate", archiveCoverPath)
  143. .Callback(true)
  144. .OnceTime(true)
  145. .CommandBuilder(), (response) =>
  146. {
  147. try
  148. {
  149. if (response.code != Result.RESULT_SUCCESS || string.IsNullOrEmpty(response.content))
  150. {
  151. taskSource.TrySetException(new TapException(-1, "Failed to update archive: code="+response.code + " content="+response.content));
  152. return;
  153. }
  154. var result = JsonConvert.DeserializeObject<TapEngineBridgeResult>(response.content);
  155. if (result != null && result.code == TapEngineBridgeResult.RESULT_SUCCESS)
  156. {
  157. var archive = JsonConvert.DeserializeObject<ArchiveData>(result.content);
  158. if (archive != null)
  159. {
  160. taskSource.TrySetResult(archive);
  161. }
  162. else
  163. {
  164. taskSource.TrySetException(new TapException(-1, "json convert failed: content="+result.content));
  165. }
  166. }
  167. else
  168. {
  169. try
  170. {
  171. var errorResponse = JsonConvert.DeserializeObject<ErrorResponse>(result.content);
  172. if (errorResponse != null)
  173. {
  174. taskSource.TrySetException(new TapException(errorResponse.ErrorCode, errorResponse.ErrorMessage));
  175. }
  176. else
  177. {
  178. taskSource.TrySetException(new TapException(-1, "Failed to update archive: content="+response.content));
  179. }
  180. }
  181. catch (Exception e)
  182. {
  183. taskSource.TrySetException(new TapException(-1, "Failed to update archive: content="+response.content));
  184. }
  185. }
  186. }
  187. catch (Exception e)
  188. {
  189. taskSource.TrySetException(new TapException(-1, "Failed to update archive: error=" + e.Message + ", content=" + response.content));
  190. }
  191. });
  192. return taskSource.Task;
  193. }
  194. public Task<ArchiveData> DeleteArchive(string archiveUuid)
  195. {
  196. TapLog.Log("[TapCloudSaveBridge] DeleteArchive called with Task<ArchiveData> return type (NEW API)");
  197. var taskSource = new TaskCompletionSource<ArchiveData>();
  198. EngineBridge.GetInstance().CallHandler(new Command.Builder()
  199. .Service(TAP_CLOUDSAVE_SERVICE)
  200. .Method("deleteArchive")
  201. .Args("archiveUUID", archiveUuid)
  202. .Callback(true)
  203. .OnceTime(true)
  204. .CommandBuilder(), (response) =>
  205. {
  206. try
  207. {
  208. if (response.code != Result.RESULT_SUCCESS || string.IsNullOrEmpty(response.content))
  209. {
  210. taskSource.TrySetException(new TapException(-1, "Failed to delete archive: code="+response.code + " content="+response.content));
  211. return;
  212. }
  213. var result = JsonConvert.DeserializeObject<TapEngineBridgeResult>(response.content);
  214. if (result != null && result.code == TapEngineBridgeResult.RESULT_SUCCESS)
  215. {
  216. var archive = JsonConvert.DeserializeObject<ArchiveData>(result.content);
  217. if (archive != null)
  218. {
  219. taskSource.TrySetResult(archive);
  220. }
  221. else
  222. {
  223. taskSource.TrySetException(new TapException(-1, "json convert failed: content="+result.content));
  224. }
  225. }
  226. else
  227. {
  228. try
  229. {
  230. var errorResponse = JsonConvert.DeserializeObject<ErrorResponse>(result.content);
  231. if (errorResponse != null)
  232. {
  233. taskSource.TrySetException(new TapException(errorResponse.ErrorCode, errorResponse.ErrorMessage));
  234. }
  235. else
  236. {
  237. taskSource.TrySetException(new TapException(-1, "Failed to delete archive: content="+response.content));
  238. }
  239. }
  240. catch (Exception e)
  241. {
  242. taskSource.TrySetException(new TapException(-1, "Failed to delete archive: content="+response.content));
  243. }
  244. }
  245. }
  246. catch (Exception e)
  247. {
  248. taskSource.TrySetException(new TapException(-1, "Failed to delete archive: error=" + e.Message + ", content=" + response.content));
  249. }
  250. });
  251. return taskSource.Task;
  252. }
  253. public Task<List<ArchiveData>> GetArchiveList()
  254. {
  255. TapLog.Log("[TapCloudSaveBridge] GetArchiveList called with Task<List<ArchiveData>> return type (NEW API)");
  256. var taskSource = new TaskCompletionSource<List<ArchiveData>>();
  257. EngineBridge.GetInstance().CallHandler(new Command.Builder()
  258. .Service(TAP_CLOUDSAVE_SERVICE)
  259. .Method("getArchiveList")
  260. .Callback(true)
  261. .OnceTime(true)
  262. .CommandBuilder(), (response) =>
  263. {
  264. try
  265. {
  266. if (response.code != Result.RESULT_SUCCESS || string.IsNullOrEmpty(response.content))
  267. {
  268. taskSource.TrySetException(new TapException(-1, "Failed to get archive list: code="+response.code + " content="+response.content));
  269. return;
  270. }
  271. var result = JsonConvert.DeserializeObject<TapEngineBridgeResult>(response.content);
  272. if (result != null && result.code == TapEngineBridgeResult.RESULT_SUCCESS)
  273. {
  274. var archiveList = JsonConvert.DeserializeObject<List<ArchiveData>>(result.content);
  275. if (archiveList != null)
  276. {
  277. taskSource.TrySetResult(archiveList);
  278. }
  279. else
  280. {
  281. taskSource.TrySetException(new TapException(-1, "json convert failed: content="+result.content));
  282. }
  283. }
  284. else
  285. {
  286. try
  287. {
  288. var errorResponse = JsonConvert.DeserializeObject<ErrorResponse>(result.content);
  289. if (errorResponse != null)
  290. {
  291. taskSource.TrySetException(new TapException(errorResponse.ErrorCode, errorResponse.ErrorMessage));
  292. }
  293. else
  294. {
  295. taskSource.TrySetException(new TapException(-1, "Failed to get archive list: content="+response.content));
  296. }
  297. }
  298. catch (Exception e)
  299. {
  300. taskSource.TrySetException(new TapException(-1, "Failed to get archive list: content="+response.content));
  301. }
  302. }
  303. }
  304. catch (Exception e)
  305. {
  306. taskSource.TrySetException(new TapException(-1, "Failed to get archive list: error=" + e.Message + ", content=" + response.content));
  307. }
  308. });
  309. return taskSource.Task;
  310. }
  311. public Task<byte[]> GetArchiveData(string archiveUuid, string archiveFileId)
  312. {
  313. TapLog.Log("[TapCloudSaveBridge] GetArchiveData called with Task<byte[]> return type (NEW API)");
  314. var taskSource = new TaskCompletionSource<byte[]>();
  315. EngineBridge.GetInstance().CallHandler(new Command.Builder()
  316. .Service(TAP_CLOUDSAVE_SERVICE)
  317. .Method("getArchiveData")
  318. .Args("archiveUUID", archiveUuid)
  319. .Args("archiveFileID", archiveFileId)
  320. .Callback(true)
  321. .OnceTime(true)
  322. .CommandBuilder(), (response) =>
  323. {
  324. try
  325. {
  326. if (response.code != Result.RESULT_SUCCESS || string.IsNullOrEmpty(response.content))
  327. {
  328. taskSource.TrySetException(new TapException(-1, "Failed to get archive data: code=" + response.code + " content="+response.content));
  329. return;
  330. }
  331. var result = JsonConvert.DeserializeObject<TapEngineBridgeResult>(response.content);
  332. if (result != null && result.code == TapEngineBridgeResult.RESULT_SUCCESS)
  333. {
  334. var archiveData = Convert.FromBase64String(result.content);
  335. if (archiveData != null)
  336. {
  337. taskSource.TrySetResult(archiveData);
  338. }
  339. else
  340. {
  341. taskSource.TrySetException(new TapException(-1, "json convert failed: content="+result.content));
  342. }
  343. }
  344. else
  345. {
  346. try
  347. {
  348. var errorResponse = JsonConvert.DeserializeObject<ErrorResponse>(result.content);
  349. if (errorResponse != null)
  350. {
  351. taskSource.TrySetException(new TapException(errorResponse.ErrorCode, errorResponse.ErrorMessage));
  352. }
  353. else
  354. {
  355. taskSource.TrySetException(new TapException(-1, "Failed to get archive data: content="+response.content));
  356. }
  357. }
  358. catch (Exception e)
  359. {
  360. taskSource.TrySetException(new TapException(-1, "Failed to get archive data: content="+response.content));
  361. }
  362. }
  363. }
  364. catch (Exception e)
  365. {
  366. taskSource.TrySetException(new TapException(-1, "Failed to get archive data: error=" + e.Message + ", content=" + response.content));
  367. }
  368. });
  369. return taskSource.Task;
  370. }
  371. public Task<byte[]> GetArchiveCover(string archiveUuid, string archiveFileId)
  372. {
  373. TapLog.Log("[TapCloudSaveBridge] GetArchiveCover called with Task<byte[]> return type (NEW API)");
  374. var taskSource = new TaskCompletionSource<byte[]>();
  375. EngineBridge.GetInstance().CallHandler(new Command.Builder()
  376. .Service(TAP_CLOUDSAVE_SERVICE)
  377. .Method("getArchiveCover")
  378. .Args("archiveUUIDForCover", archiveUuid)
  379. .Args("archiveFileIDForCover", archiveFileId)
  380. .Callback(true)
  381. .OnceTime(true)
  382. .CommandBuilder(), (response) =>
  383. {
  384. try
  385. {
  386. if (response.code != Result.RESULT_SUCCESS || string.IsNullOrEmpty(response.content))
  387. {
  388. taskSource.TrySetException(new TapException(-1, "Failed to get archive cover: code="+response.code + " content="+response.content));
  389. return;
  390. }
  391. var result = JsonConvert.DeserializeObject<TapEngineBridgeResult>(response.content);
  392. if (result != null && result.code == TapEngineBridgeResult.RESULT_SUCCESS)
  393. {
  394. var coverData = Convert.FromBase64String(result.content);
  395. if (coverData != null)
  396. {
  397. taskSource.TrySetResult(coverData);
  398. }
  399. else
  400. {
  401. taskSource.TrySetException(new TapException(-1, "json convert failed: content="+result.content));
  402. }
  403. }
  404. else
  405. {
  406. try
  407. {
  408. var errorResponse = JsonConvert.DeserializeObject<ErrorResponse>(result.content);
  409. if (errorResponse != null)
  410. {
  411. taskSource.TrySetException(new TapException(errorResponse.ErrorCode, errorResponse.ErrorMessage));
  412. }
  413. else
  414. {
  415. taskSource.TrySetException(new TapException(-1, "Failed to get archive cover: content="+response.content));
  416. }
  417. }
  418. catch (Exception e)
  419. {
  420. taskSource.TrySetException(new TapException(-1, "Failed to get archive cover: content="+response.content));
  421. }
  422. }
  423. }
  424. catch (Exception e)
  425. {
  426. taskSource.TrySetException(new TapException(-1, "Failed to get archive cover: error=" + e.Message + ", content=" + response.content));
  427. }
  428. });
  429. return taskSource.Task;
  430. }
  431. }
  432. }