@xmobitea/gn-typescript-client 2.6.13 → 2.6.14

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 (286) hide show
  1. package/AGENTS.md +37 -0
  2. package/README.MD +420 -1
  3. package/dist/gearn.js.client.js +25056 -1056
  4. package/dist/gearn.js.client.min.js +1 -1
  5. package/dist/index.d.ts +30 -0
  6. package/dist/index.js +24236 -212
  7. package/dist/runtime/GNNetwork.d.ts +687 -3
  8. package/dist/runtime/GNNetworkAuthenticateApi.d.ts +327 -0
  9. package/dist/runtime/GNNetworkCharacterPlayerApi.d.ts +1026 -0
  10. package/dist/runtime/GNNetworkCloudScriptApi.d.ts +141 -0
  11. package/dist/runtime/GNNetworkContentApi.d.ts +243 -0
  12. package/dist/runtime/GNNetworkDashboardApi.d.ts +221 -0
  13. package/dist/runtime/GNNetworkGamePlayerApi.d.ts +1033 -0
  14. package/dist/runtime/GNNetworkGroupApi.d.ts +783 -0
  15. package/dist/runtime/GNNetworkInventoryApi.d.ts +673 -0
  16. package/dist/runtime/GNNetworkMasterPlayerApi.d.ts +1614 -6
  17. package/dist/runtime/GNNetworkMultiplayerApi.d.ts +234 -0
  18. package/dist/runtime/GNNetworkStoreInventoryApi.d.ts +309 -0
  19. package/dist/runtime/common/Action0.d.ts +30 -0
  20. package/dist/runtime/common/Action1.d.ts +32 -0
  21. package/dist/runtime/common/Action2.d.ts +21 -0
  22. package/dist/runtime/common/Action3.d.ts +16 -0
  23. package/dist/runtime/common/Action4.d.ts +17 -0
  24. package/dist/runtime/common/GNData.d.ts +368 -0
  25. package/dist/runtime/config/GNServerSettings.d.ts +442 -12
  26. package/dist/runtime/constant/Commands.d.ts +80 -0
  27. package/dist/runtime/constant/EventCode.d.ts +48 -0
  28. package/dist/runtime/constant/OperationCode.d.ts +74 -1
  29. package/dist/runtime/constant/ReturnCode.d.ts +72 -0
  30. package/dist/runtime/constant/enumType/ExecuteResponseStatus.d.ts +31 -0
  31. package/dist/runtime/constant/enumType/FriendStatus.d.ts +39 -0
  32. package/dist/runtime/constant/enumType/GoogleLoginType.d.ts +23 -0
  33. package/dist/runtime/constant/enumType/GroupStatus.d.ts +32 -0
  34. package/dist/runtime/constant/enumType/InvalidMemberType.d.ts +75 -0
  35. package/dist/runtime/constant/enumType/ItemType.d.ts +23 -0
  36. package/dist/runtime/constant/enumType/MatchStatus.d.ts +30 -0
  37. package/dist/runtime/constant/enumType/MatchmakingMemberStatus.d.ts +24 -0
  38. package/dist/runtime/constant/enumType/MatchmakingTicketStatus.d.ts +34 -0
  39. package/dist/runtime/constant/enumType/OwnerType.d.ts +40 -0
  40. package/dist/runtime/constant/enumType/PermissionDataItem.d.ts +22 -0
  41. package/dist/runtime/constant/enumType/PushPlatformType.d.ts +18 -0
  42. package/dist/runtime/constant/enumType/RequestRole.d.ts +32 -0
  43. package/dist/runtime/constant/enumType/RequestType.d.ts +70 -0
  44. package/dist/runtime/constant/enumType/StoreItemType.d.ts +21 -0
  45. package/dist/runtime/constant/enumType/StoreReceiveType.d.ts +30 -0
  46. package/dist/runtime/constant/errorCode/ErrorCode.d.ts +190 -8
  47. package/dist/runtime/constant/parameterCode/ParameterCode.d.ts +35 -5
  48. package/dist/runtime/entity/DataMember.d.ts +338 -0
  49. package/dist/runtime/entity/GNMetadata.d.ts +101 -0
  50. package/dist/runtime/entity/InvalidMember.d.ts +28 -0
  51. package/dist/runtime/entity/OperationEvent.d.ts +49 -0
  52. package/dist/runtime/entity/OperationRequest.d.ts +108 -0
  53. package/dist/runtime/entity/OperationResponse.d.ts +110 -0
  54. package/dist/runtime/entity/models/AuthenticateModels.d.ts +115 -0
  55. package/dist/runtime/entity/models/AuthenticateRequestModels.d.ts +131 -0
  56. package/dist/runtime/entity/models/AuthenticateResponseModels.d.ts +131 -0
  57. package/dist/runtime/entity/models/CharacterPlayerModels.d.ts +625 -1
  58. package/dist/runtime/entity/models/CharacterPlayerRequestModels.d.ts +972 -0
  59. package/dist/runtime/entity/models/CharacterPlayerResponseModels.d.ts +332 -0
  60. package/dist/runtime/entity/models/CloudScriptModels.d.ts +109 -0
  61. package/dist/runtime/entity/models/CloudScriptRequestModels.d.ts +107 -0
  62. package/dist/runtime/entity/models/CloudScriptResponseModels.d.ts +46 -0
  63. package/dist/runtime/entity/models/ContentModels.d.ts +124 -0
  64. package/dist/runtime/entity/models/ContentRequestModels.d.ts +152 -0
  65. package/dist/runtime/entity/models/ContentResponseModels.d.ts +58 -0
  66. package/dist/runtime/entity/models/DashboardModels.d.ts +371 -8
  67. package/dist/runtime/entity/models/DashboardRequestModels.d.ts +172 -0
  68. package/dist/runtime/entity/models/DashboardResponseModels.d.ts +170 -0
  69. package/dist/runtime/entity/models/GamePlayerModels.d.ts +644 -1
  70. package/dist/runtime/entity/models/GamePlayerRequestModels.d.ts +959 -0
  71. package/dist/runtime/entity/models/GamePlayerResponseModels.d.ts +333 -1
  72. package/dist/runtime/entity/models/GenericModels.d.ts +94 -0
  73. package/dist/runtime/entity/models/GroupModels.d.ts +484 -2
  74. package/dist/runtime/entity/models/GroupRequestModels.d.ts +737 -0
  75. package/dist/runtime/entity/models/GroupResponseModels.d.ts +254 -0
  76. package/dist/runtime/entity/models/InventoryModels.d.ts +415 -0
  77. package/dist/runtime/entity/models/InventoryRequestModels.d.ts +629 -0
  78. package/dist/runtime/entity/models/InventoryResponseModels.d.ts +218 -0
  79. package/dist/runtime/entity/models/MasterPlayerModels.d.ts +1065 -3
  80. package/dist/runtime/entity/models/MasterPlayerRequestModels.d.ts +1560 -6
  81. package/dist/runtime/entity/models/MasterPlayerResponseModels.d.ts +532 -1
  82. package/dist/runtime/entity/models/MultiplayerModels.d.ts +199 -0
  83. package/dist/runtime/entity/models/MultiplayerRequestModels.d.ts +196 -0
  84. package/dist/runtime/entity/models/MultiplayerResponseModels.d.ts +74 -0
  85. package/dist/runtime/entity/models/StoreInventoryModels.d.ts +262 -0
  86. package/dist/runtime/entity/models/StoreInventoryRequestModels.d.ts +268 -0
  87. package/dist/runtime/entity/models/StoreInventoryResponseModels.d.ts +98 -0
  88. package/dist/runtime/entity/request/CustomOperationRequest.d.ts +99 -0
  89. package/dist/runtime/entity/response/CustomOperationResponse.d.ts +118 -0
  90. package/dist/runtime/entity/response/GetAuthInfoResponse.d.ts +53 -0
  91. package/dist/runtime/entity/response/HealthCheckResponse.d.ts +56 -0
  92. package/dist/runtime/entity/response/UploadFileResponse.d.ts +19 -0
  93. package/dist/runtime/helper/CodeHelper.d.ts +122 -0
  94. package/dist/runtime/helper/ConverterService.d.ts +74 -0
  95. package/dist/runtime/helper/EnumUtility.d.ts +63 -0
  96. package/dist/runtime/helper/GNSupport.d.ts +64 -4
  97. package/dist/runtime/helper/GNUtils.d.ts +54 -0
  98. package/dist/runtime/helper/MessagePackConverterService.d.ts +48 -0
  99. package/dist/runtime/helper/OperationHelper.d.ts +51 -0
  100. package/dist/runtime/helper/StorageService.d.ts +48 -8
  101. package/dist/runtime/logger/GNDebug.d.ts +117 -0
  102. package/dist/runtime/networking/AuthenticateStatus.d.ts +64 -0
  103. package/dist/runtime/networking/IPeer.d.ts +83 -0
  104. package/dist/runtime/networking/NetworkingPeer.d.ts +256 -1
  105. package/dist/runtime/networking/OperationPending.d.ts +112 -0
  106. package/dist/runtime/networking/PeerBase.d.ts +231 -0
  107. package/dist/runtime/networking/handler/IServerEventHandler.d.ts +84 -0
  108. package/dist/runtime/networking/handler/OnCharacterPlayerFriendUpdateEventHandler.d.ts +69 -0
  109. package/dist/runtime/networking/handler/OnCharacterPlayerGroupUpdateEventHandler.d.ts +49 -0
  110. package/dist/runtime/networking/handler/OnGamePlayerFriendUpdateEventHandler.d.ts +50 -0
  111. package/dist/runtime/networking/handler/OnGamePlayerGroupUpdateEventHandler.d.ts +41 -0
  112. package/dist/runtime/networking/handler/OnGroupMemberUpdateEventHandler.d.ts +47 -0
  113. package/dist/runtime/networking/handler/OnGroupMessageUpdateEventHandler.d.ts +46 -0
  114. package/dist/runtime/networking/http/HttpPeer.d.ts +173 -0
  115. package/dist/runtime/networking/http/NetworkingHttpPeerBase.d.ts +87 -0
  116. package/dist/runtime/networking/http/NetworkingPeerAxiosRequest.d.ts +113 -0
  117. package/dist/runtime/networking/socket/NetworkingPeerSocketIOClient.d.ts +145 -0
  118. package/dist/runtime/networking/socket/NetworkingSocketPeerBase.d.ts +198 -0
  119. package/dist/runtime/networking/socket/SocketPeer.d.ts +155 -0
  120. package/dist/runtime/typescript/ServiceUpdate.d.ts +46 -0
  121. package/docs/AI_CHEATSHEET.md +211 -0
  122. package/docs/COOKBOOK.md +912 -0
  123. package/docs/RULES.md +307 -0
  124. package/docs/ai-manifest.json +725 -0
  125. package/docs/guides/AUTHENTICATE.md +246 -0
  126. package/docs/guides/CHARACTER_PLAYER.md +439 -0
  127. package/docs/guides/CLOUDSCRIPT.md +335 -0
  128. package/docs/guides/COCOS_CREATOR_INTEGRATION.md +150 -0
  129. package/docs/guides/CONTENT.md +291 -0
  130. package/docs/guides/DASHBOARD.md +262 -0
  131. package/docs/guides/GAME_PLAYER.md +473 -0
  132. package/docs/guides/GROUP.md +412 -0
  133. package/docs/guides/INVENTORY.md +375 -0
  134. package/docs/guides/MASTER_PLAYER.md +458 -0
  135. package/docs/guides/MULTIPLAYER.md +303 -0
  136. package/docs/guides/STORE_INVENTORY.md +313 -0
  137. package/docs/llms-full.txt +43 -0
  138. package/docs/reference/API_AUTHENTICATE.md +75 -0
  139. package/docs/reference/API_CHARACTER_PLAYER.md +226 -0
  140. package/docs/reference/API_CLOUDSCRIPT.md +82 -0
  141. package/docs/reference/API_CONTENT.md +88 -0
  142. package/docs/reference/API_DASHBOARD.md +82 -0
  143. package/docs/reference/API_GAME_PLAYER.md +223 -0
  144. package/docs/reference/API_GROUP.md +187 -0
  145. package/docs/reference/API_INDEX.md +57 -0
  146. package/docs/reference/API_INVENTORY.md +169 -0
  147. package/docs/reference/API_MASTER_PLAYER.md +323 -0
  148. package/docs/reference/API_MULTIPLAYER.md +97 -0
  149. package/docs/reference/API_STORE_INVENTORY.md +109 -0
  150. package/docs/reference/CONFIG.md +107 -0
  151. package/docs/reference/DTO_INDEX.md +2543 -0
  152. package/docs/reference/ENUMS.md +433 -0
  153. package/docs/reference/ERROR_HANDLING.md +159 -0
  154. package/docs/reference/EVENTS.md +188 -0
  155. package/docs/reference/PERMISSION_RULES.md +55 -0
  156. package/docs/reference/dto/AUTHENTICATE.md +619 -0
  157. package/docs/reference/dto/CHARACTER_PLAYER.md +3686 -0
  158. package/docs/reference/dto/CLOUDSCRIPT.md +400 -0
  159. package/docs/reference/dto/CONTENT.md +548 -0
  160. package/docs/reference/dto/DASHBOARD.md +1980 -0
  161. package/docs/reference/dto/GAME_PLAYER.md +3631 -0
  162. package/docs/reference/dto/GENERIC.md +151 -0
  163. package/docs/reference/dto/GROUP.md +2842 -0
  164. package/docs/reference/dto/INVENTORY.md +2385 -0
  165. package/docs/reference/dto/MASTER_PLAYER.md +6024 -0
  166. package/docs/reference/dto/MULTIPLAYER.md +850 -0
  167. package/docs/reference/dto/STORE_INVENTORY.md +1262 -0
  168. package/llms.txt +47 -0
  169. package/package.json +12 -3
  170. package/GNServerSettings.debug.json +0 -21
  171. package/docs/COCOS_CREATOR_INTEGRATION.md +0 -116
  172. package/examples/cocos-creator/GearNExample.ts.txt +0 -176
  173. package/srcSwift/Package.swift +0 -32
  174. package/srcSwift/Sources/GearN/runtime/GNNetwork.swift +0 -530
  175. package/srcSwift/Sources/GearN/runtime/GNNetworkAuthenticateApi.swift +0 -178
  176. package/srcSwift/Sources/GearN/runtime/GNNetworkCharacterPlayerApi.swift +0 -1162
  177. package/srcSwift/Sources/GearN/runtime/GNNetworkCloudScriptApi.swift +0 -154
  178. package/srcSwift/Sources/GearN/runtime/GNNetworkContentApi.swift +0 -208
  179. package/srcSwift/Sources/GearN/runtime/GNNetworkDashboardApi.swift +0 -240
  180. package/srcSwift/Sources/GearN/runtime/GNNetworkGamePlayerApi.swift +0 -1369
  181. package/srcSwift/Sources/GearN/runtime/GNNetworkGroupApi.swift +0 -1100
  182. package/srcSwift/Sources/GearN/runtime/GNNetworkInventoryApi.swift +0 -937
  183. package/srcSwift/Sources/GearN/runtime/GNNetworkMasterPlayerApi.swift +0 -2323
  184. package/srcSwift/Sources/GearN/runtime/GNNetworkMultiplayerApi.swift +0 -298
  185. package/srcSwift/Sources/GearN/runtime/GNNetworkStoreInventoryApi.swift +0 -397
  186. package/srcSwift/Sources/GearN/runtime/common/Action0.swift +0 -3
  187. package/srcSwift/Sources/GearN/runtime/common/Action1.swift +0 -3
  188. package/srcSwift/Sources/GearN/runtime/common/Action2.swift +0 -3
  189. package/srcSwift/Sources/GearN/runtime/common/Action3.swift +0 -3
  190. package/srcSwift/Sources/GearN/runtime/common/Action4.swift +0 -3
  191. package/srcSwift/Sources/GearN/runtime/common/GNArray.swift +0 -204
  192. package/srcSwift/Sources/GearN/runtime/common/GNData.swift +0 -108
  193. package/srcSwift/Sources/GearN/runtime/common/GNHashtable.swift +0 -200
  194. package/srcSwift/Sources/GearN/runtime/config/GNServerSettings.swift +0 -95
  195. package/srcSwift/Sources/GearN/runtime/constant/Commands.swift +0 -28
  196. package/srcSwift/Sources/GearN/runtime/constant/EventCode.swift +0 -10
  197. package/srcSwift/Sources/GearN/runtime/constant/OperationCode.swift +0 -252
  198. package/srcSwift/Sources/GearN/runtime/constant/ReturnCode.swift +0 -19
  199. package/srcSwift/Sources/GearN/runtime/constant/enumType/ExecuteResponseStatus.swift +0 -9
  200. package/srcSwift/Sources/GearN/runtime/constant/enumType/FriendStatus.swift +0 -8
  201. package/srcSwift/Sources/GearN/runtime/constant/enumType/GoogleLoginType.swift +0 -6
  202. package/srcSwift/Sources/GearN/runtime/constant/enumType/GroupStatus.swift +0 -8
  203. package/srcSwift/Sources/GearN/runtime/constant/enumType/InvalidMemberType.swift +0 -19
  204. package/srcSwift/Sources/GearN/runtime/constant/enumType/ItemType.swift +0 -6
  205. package/srcSwift/Sources/GearN/runtime/constant/enumType/MatchmakingMemberStatus.swift +0 -7
  206. package/srcSwift/Sources/GearN/runtime/constant/enumType/MatchmakingTicketStatus.swift +0 -9
  207. package/srcSwift/Sources/GearN/runtime/constant/enumType/OwnerType.swift +0 -10
  208. package/srcSwift/Sources/GearN/runtime/constant/enumType/PermissionDataItem.swift +0 -6
  209. package/srcSwift/Sources/GearN/runtime/constant/enumType/PushPlatformType.swift +0 -6
  210. package/srcSwift/Sources/GearN/runtime/constant/enumType/RequestRole.swift +0 -7
  211. package/srcSwift/Sources/GearN/runtime/constant/enumType/RequestType.swift +0 -16
  212. package/srcSwift/Sources/GearN/runtime/constant/enumType/StoreItemType.swift +0 -6
  213. package/srcSwift/Sources/GearN/runtime/constant/enumType/StoreReceiveType.swift +0 -9
  214. package/srcSwift/Sources/GearN/runtime/constant/errorCode/ErrorCode.swift +0 -58
  215. package/srcSwift/Sources/GearN/runtime/constant/parameterCode/ParameterCode.swift +0 -672
  216. package/srcSwift/Sources/GearN/runtime/entity/DataMember.swift +0 -196
  217. package/srcSwift/Sources/GearN/runtime/entity/GNMetadata.swift +0 -9
  218. package/srcSwift/Sources/GearN/runtime/entity/InvalidMember.swift +0 -11
  219. package/srcSwift/Sources/GearN/runtime/entity/OperationEvent.swift +0 -38
  220. package/srcSwift/Sources/GearN/runtime/entity/OperationHelper.swift +0 -28
  221. package/srcSwift/Sources/GearN/runtime/entity/OperationRequest.swift +0 -62
  222. package/srcSwift/Sources/GearN/runtime/entity/OperationResponse.swift +0 -98
  223. package/srcSwift/Sources/GearN/runtime/entity/models/AuthenticateModels.swift +0 -351
  224. package/srcSwift/Sources/GearN/runtime/entity/models/AuthenticateRequestModels.swift +0 -81
  225. package/srcSwift/Sources/GearN/runtime/entity/models/AuthenticateResponseModels.swift +0 -108
  226. package/srcSwift/Sources/GearN/runtime/entity/models/CharacterPlayerModels.swift +0 -1045
  227. package/srcSwift/Sources/GearN/runtime/entity/models/CharacterPlayerRequestModels.swift +0 -821
  228. package/srcSwift/Sources/GearN/runtime/entity/models/CharacterPlayerResponseModels.swift +0 -588
  229. package/srcSwift/Sources/GearN/runtime/entity/models/CloudScriptModels.swift +0 -187
  230. package/srcSwift/Sources/GearN/runtime/entity/models/CloudScriptRequestModels.swift +0 -84
  231. package/srcSwift/Sources/GearN/runtime/entity/models/CloudScriptResponseModels.swift +0 -59
  232. package/srcSwift/Sources/GearN/runtime/entity/models/ContentModels.swift +0 -195
  233. package/srcSwift/Sources/GearN/runtime/entity/models/ContentRequestModels.swift +0 -116
  234. package/srcSwift/Sources/GearN/runtime/entity/models/ContentResponseModels.swift +0 -81
  235. package/srcSwift/Sources/GearN/runtime/entity/models/DashboardModels.swift +0 -426
  236. package/srcSwift/Sources/GearN/runtime/entity/models/DashboardRequestModels.swift +0 -160
  237. package/srcSwift/Sources/GearN/runtime/entity/models/DashboardResponseModels.swift +0 -82
  238. package/srcSwift/Sources/GearN/runtime/entity/models/GamePlayerModels.swift +0 -1334
  239. package/srcSwift/Sources/GearN/runtime/entity/models/GamePlayerRequestModels.swift +0 -643
  240. package/srcSwift/Sources/GearN/runtime/entity/models/GamePlayerResponseModels.swift +0 -213
  241. package/srcSwift/Sources/GearN/runtime/entity/models/GenericModels.swift +0 -171
  242. package/srcSwift/Sources/GearN/runtime/entity/models/GroupModels.swift +0 -850
  243. package/srcSwift/Sources/GearN/runtime/entity/models/GroupRequestModels.swift +0 -485
  244. package/srcSwift/Sources/GearN/runtime/entity/models/GroupResponseModels.swift +0 -165
  245. package/srcSwift/Sources/GearN/runtime/entity/models/InventoryModels.swift +0 -679
  246. package/srcSwift/Sources/GearN/runtime/entity/models/InventoryRequestModels.swift +0 -413
  247. package/srcSwift/Sources/GearN/runtime/entity/models/InventoryResponseModels.swift +0 -141
  248. package/srcSwift/Sources/GearN/runtime/entity/models/MasterPlayerModels.swift +0 -378
  249. package/srcSwift/Sources/GearN/runtime/entity/models/MasterPlayerRequestModels.swift +0 -147
  250. package/srcSwift/Sources/GearN/runtime/entity/models/MasterPlayerResponseModels.swift +0 -318
  251. package/srcSwift/Sources/GearN/runtime/entity/models/MultiplayerModels.swift +0 -319
  252. package/srcSwift/Sources/GearN/runtime/entity/models/MultiplayerRequestModels.swift +0 -125
  253. package/srcSwift/Sources/GearN/runtime/entity/models/MultiplayerResponseModels.swift +0 -45
  254. package/srcSwift/Sources/GearN/runtime/entity/models/StoreInventoryModels.swift +0 -633
  255. package/srcSwift/Sources/GearN/runtime/entity/models/StoreInventoryRequestModels.swift +0 -173
  256. package/srcSwift/Sources/GearN/runtime/entity/models/StoreInventoryResponseModels.swift +0 -61
  257. package/srcSwift/Sources/GearN/runtime/entity/request/CustomOperationRequest.swift +0 -42
  258. package/srcSwift/Sources/GearN/runtime/entity/response/CustomOperationResponse.swift +0 -49
  259. package/srcSwift/Sources/GearN/runtime/entity/response/GetAuthInfoResponse.swift +0 -43
  260. package/srcSwift/Sources/GearN/runtime/entity/response/HealthCheckResponse.swift +0 -86
  261. package/srcSwift/Sources/GearN/runtime/entity/response/UploadFileResponse.swift +0 -15
  262. package/srcSwift/Sources/GearN/runtime/helper/CodeHelper.swift +0 -107
  263. package/srcSwift/Sources/GearN/runtime/helper/ConverterService.swift +0 -98
  264. package/srcSwift/Sources/GearN/runtime/helper/EnumUtility.swift +0 -34
  265. package/srcSwift/Sources/GearN/runtime/helper/GNSupport.swift +0 -41
  266. package/srcSwift/Sources/GearN/runtime/helper/GNUtils.swift +0 -66
  267. package/srcSwift/Sources/GearN/runtime/helper/MessagePackConverterService.swift +0 -21
  268. package/srcSwift/Sources/GearN/runtime/helper/StorageService.swift +0 -29
  269. package/srcSwift/Sources/GearN/runtime/logger/GNDebug.swift +0 -33
  270. package/srcSwift/Sources/GearN/runtime/networking/AuthenticateStatus.swift +0 -24
  271. package/srcSwift/Sources/GearN/runtime/networking/IPeer.swift +0 -8
  272. package/srcSwift/Sources/GearN/runtime/networking/NetworkingPeer.swift +0 -368
  273. package/srcSwift/Sources/GearN/runtime/networking/OperationPending.swift +0 -81
  274. package/srcSwift/Sources/GearN/runtime/networking/PeerBase.swift +0 -228
  275. package/srcSwift/Sources/GearN/runtime/networking/handler/IServerEventHandler.swift +0 -20
  276. package/srcSwift/Sources/GearN/runtime/networking/http/HttpPeer.swift +0 -226
  277. package/srcSwift/Sources/GearN/runtime/networking/http/HttpTypes.swift +0 -24
  278. package/srcSwift/Sources/GearN/runtime/networking/http/NetworkingHttpPeerBase.swift +0 -13
  279. package/srcSwift/Sources/GearN/runtime/networking/http/NetworkingPeerUrlSession.swift +0 -125
  280. package/srcSwift/Sources/GearN/runtime/networking/request/NetRequest.swift +0 -19
  281. package/srcSwift/Sources/GearN/runtime/networking/response/NetResponse.swift +0 -13
  282. package/srcSwift/Sources/GearN/runtime/networking/socket/NetworkingPeerSocketIOClient.swift +0 -244
  283. package/srcSwift/Sources/GearN/runtime/networking/socket/NetworkingSocketPeerBase.swift +0 -59
  284. package/srcSwift/Sources/GearN/runtime/networking/socket/SocketPeer.swift +0 -136
  285. package/tsconfig-build.cocos.json +0 -31
  286. package/webpack.config.cocos.mjs +0 -78
@@ -0,0 +1,912 @@
1
+ # Cookbook
2
+
3
+ 16 scenario end-to-end phổ biến. Mỗi scenario có: problem, prerequisites, APIs used, code snippet, return path handling, pitfall.
4
+
5
+ > Tất cả snippet dùng import từ package name `@xmobitea/gn-typescript-client`. Ví dụ dùng dạng `async/await` (form `*Async()`). Các comment trong snippet là điểm nối vào logic ứng dụng của bạn.
6
+
7
+ ## Index
8
+
9
+ 1. [Init SDK + bootstrap tối thiểu](#scenario-1-init-sdk--bootstrap-tối-thiểu)
10
+ 2. [Login by account + retrieve profile](#scenario-2-login-by-account--retrieve-profile)
11
+ 3. [Refresh token và persist session](#scenario-3-refresh-token-và-persist-session)
12
+ 4. [Login by social (Google/Apple/Facebook)](#scenario-4-login-by-social-googleapplefacebook)
13
+ 5. [Connect socket + handle reconnect](#scenario-5-connect-socket--handle-reconnect)
14
+ 6. [Subscribe friend updates](#scenario-6-subscribe-friend-updates)
15
+ 7. [Subscribe + send group message](#scenario-7-subscribe--send-group-message)
16
+ 8. [Group member lifecycle (join / leave / kick) + realtime update](#scenario-8-group-member-lifecycle-join--leave--kick--realtime-update)
17
+ 9. [Matchmaking ticket flow](#scenario-9-matchmaking-ticket-flow)
18
+ 10. [Inventory: query + grant item (server role)](#scenario-10-inventory-query--grant-item-server-role)
19
+ 11. [Store: list catalog → purchase → validate receipt](#scenario-11-store-list-catalog--purchase--validate-receipt)
20
+ 12. [CloudScript: execute function + customTags](#scenario-12-cloudscript-execute-function--customtags)
21
+ 13. [Override authToken / secret (impersonate, cross-role)](#scenario-13-override-authtoken--secret-impersonate-cross-role)
22
+ 14. [Admin login qua DashboardApi](#scenario-14-admin-login-qua-dashboardapi)
23
+ 15. [Cleanup & shutdown flow](#scenario-15-cleanup--shutdown-flow)
24
+ 16. [Diagnose `OperationNotAllow`](#scenario-16-diagnose-operationnotallow)
25
+
26
+ ---
27
+
28
+ ## Scenario 1: Init SDK + bootstrap tối thiểu
29
+
30
+ **Problem:** Lần đầu khởi chạy ứng dụng — cần init SDK để bất kỳ API nào hoạt động.
31
+
32
+ **Prerequisites:** biết server address/port và `secretKey` backend cấp.
33
+
34
+ **APIs used:** `GNNetwork.init()`, `GNServerSettings`.
35
+
36
+ Code mẫu đầy đủ (có comment từng field): [README § 4](../README.MD#4-khởi-tạo-cơ-bản). Minimal pattern: [AI_CHEATSHEET § 1](AI_CHEATSHEET.md#1-mandatory-pattern-sao-chép--dùng).
37
+
38
+ ### Return paths
39
+
40
+ - `init()` là void và **idempotent** — gọi lần thứ 2 chỉ log warning rồi return.
41
+ - Không có network call ở bước này; lỗi cấu hình thường gặp là gọi `settings.config({...})` thiếu field required trong `GNServerSettingsOptions`.
42
+
43
+ ### Pitfalls
44
+
45
+ - `logType: LogType.All` trong production làm console spam. Dùng `LogType.Error` hoặc `LogType.Off`.
46
+ - Gọi lại `GNNetwork.init()` để đổi settings không có hiệu lực. Setter trên cùng `settings` object sau init chỉ ảnh hưởng một số request mới và không tự reconnect socket.
47
+ - Full anti-patterns: [RULES § 10](RULES.md#10-anti-patterns--pitfalls). Full field schema: [reference/CONFIG.md](reference/CONFIG.md).
48
+
49
+ ---
50
+
51
+ ## Scenario 2: Login by account + retrieve profile
52
+
53
+ **Problem:** User nhập username/password → gọi login → nhận profile + cache auth token để request sau tự động attach.
54
+
55
+ **Prerequisites:** đã `init()`.
56
+
57
+ **APIs used:** [`GNNetwork.authenticate.loginByAccountAsync`](reference/API_AUTHENTICATE.md), [`AuthenticateModels.LoginByAccountRequestData`](reference/dto/AUTHENTICATE.md#loginbyaccountrequestdata), [`AuthenticateModels.InfoRequestParam`](reference/dto/AUTHENTICATE.md#inforequestparam).
58
+
59
+ ### Code
60
+
61
+ ```typescript
62
+ import {
63
+ GNNetwork,
64
+ ReturnCode,
65
+ ErrorCode,
66
+ AuthenticateModels,
67
+ } from "@xmobitea/gn-typescript-client";
68
+
69
+ async function loginWithAccount(username: string, password: string) {
70
+ const infoRequestParam = new AuthenticateModels.InfoRequestParam();
71
+ infoRequestParam.displayName = true;
72
+ infoRequestParam.avatar = true;
73
+ infoRequestParam.playerCurrencies = true;
74
+ infoRequestParam.tsCreate = true;
75
+
76
+ const request = new AuthenticateModels.LoginByAccountRequestData();
77
+ request.username = username;
78
+ request.password = password;
79
+ request.infoRequestParam = infoRequestParam;
80
+
81
+ const res = await GNNetwork.authenticate.loginByAccountAsync(request);
82
+
83
+ if (res.returnCode !== ReturnCode.Ok) {
84
+ console.error("transport error", res.returnCode, res.debugMessage);
85
+ return null;
86
+ }
87
+ if (res.errorCode !== ErrorCode.Ok) {
88
+ console.warn("business error", res.errorCode, res.invalidMembers);
89
+ return null;
90
+ }
91
+
92
+ // AuthenticateApi success auto-caches authToken + userId into AuthenticateStatus/StorageService.
93
+ return res.responseData; // AuthenticateResponseData
94
+ }
95
+ ```
96
+
97
+ ### Return paths
98
+
99
+ - Happy: `ReturnCode.Ok` + `ErrorCode.Ok` → SDK cache `authToken` + `userId`; response có profile fields enabled trong `InfoRequestParam`.
100
+ - `ReturnCode.OperationTimeout` (-1) → retry sau nếu idempotent.
101
+ - `ErrorCode.AccountNotFound` (2) hoặc `ErrorCode.AccountPasswordWrong` → báo user.
102
+ - `ReturnCode.InvalidRequestParameters` với `invalidMembers` → có field request sai format (ví dụ username < 6 chars).
103
+
104
+ ### Pitfalls
105
+
106
+ - Đọc `responseData` trước khi check đủ 2 tầng → có thể dùng payload chưa đáng tin.
107
+ - Set `infoRequestParam.customDatas = true` nhưng không set `customDataKeys` → backend có thể trả TẤT CẢ custom data, tốn bandwidth.
108
+ - `username`/`password` < 6 ký tự → backend reject với `ReturnCode.InvalidRequestParameters` trước khi query DB.
109
+
110
+ ---
111
+
112
+ ## Scenario 3: Refresh token và persist session
113
+
114
+ **Problem:** Token sắp hết hạn (hoặc user mở lại app sau 1 ngày) → refresh để lấy token mới, tránh bắt login lại.
115
+
116
+ **Prerequisites:** đã có `authToken` cache từ lần login trước (stored ở `StorageService`).
117
+
118
+ **APIs used:** [`GNNetwork.authenticate.refreshAuthTokenAsync`](reference/API_AUTHENTICATE.md).
119
+
120
+ ### Code
121
+
122
+ ```typescript
123
+ import { GNNetwork, ReturnCode, ErrorCode, AuthenticateModels } from "@xmobitea/gn-typescript-client";
124
+
125
+ async function ensureValidToken() {
126
+ // refreshAuthToken uses cached auth context — không cần truyền field nào
127
+ const res = await GNNetwork.authenticate.refreshAuthTokenAsync(
128
+ new AuthenticateModels.RefreshAuthTokenRequestData(),
129
+ );
130
+
131
+ if (res.returnCode !== ReturnCode.Ok) return false;
132
+ if (res.errorCode !== ErrorCode.Ok) return false;
133
+
134
+ return true;
135
+ }
136
+
137
+ // On app start:
138
+ if (!(await ensureValidToken())) {
139
+ // redirect về login screen
140
+ }
141
+ ```
142
+
143
+ ### Return paths
144
+
145
+ - Happy → `authToken` mới được SDK cache, session tiếp tục.
146
+ - `ReturnCode.OperationNotAuthorized` hoặc `ErrorCode.VerifyTokenError` → token cũ invalid/expired; cần login lại.
147
+ - `ErrorCode.PlayerBan` → user bị ban; xem `res.responseData.playerBan` (BanItem với tsExpire + reason).
148
+
149
+ ### Pitfalls
150
+
151
+ - Không có `authToken` cache → request gửi đi thiếu auth, reject.
152
+ - Refresh thành công nhưng app vẫn dùng token tự lưu bên ngoài SDK → đồng bộ lại storage riêng của app từ `GNNetwork.getAuthenticateStatus()` nếu có.
153
+
154
+ ---
155
+
156
+ ## Scenario 4: Login by social (Google/Apple/Facebook)
157
+
158
+ **Problem:** User chọn đăng nhập bằng Google (hoặc Apple, Facebook, Game Center, GooglePlayGameService …).
159
+
160
+ **Prerequisites:** đã init; đã có ID token từ social SDK native.
161
+
162
+ **APIs used:** `loginByGoogleAsync`, `loginByAppleAsync`, `loginByFacebookAsync`, `loginByGameCenterAsync`, `loginByGooglePlayGameServiceAsync` — cùng pattern. Xem [API_AUTHENTICATE.md](reference/API_AUTHENTICATE.md).
163
+
164
+ ### Code
165
+
166
+ ```typescript
167
+ import {
168
+ GNNetwork,
169
+ ReturnCode,
170
+ ErrorCode,
171
+ AuthenticateModels,
172
+ GoogleLoginType,
173
+ } from "@xmobitea/gn-typescript-client";
174
+
175
+ async function loginWithGoogle(idToken: string) {
176
+ const infoRequestParam = new AuthenticateModels.InfoRequestParam();
177
+ infoRequestParam.displayName = true;
178
+ infoRequestParam.avatar = true;
179
+
180
+ const request = new AuthenticateModels.LoginByGoogleRequestData();
181
+ request.token = idToken;
182
+ request.type = GoogleLoginType.IdToken;
183
+ request.createPlayerIfNotExists = true;
184
+ request.infoRequestParam = infoRequestParam;
185
+
186
+ const res = await GNNetwork.authenticate.loginByGoogleAsync(request);
187
+
188
+ if (res.returnCode !== ReturnCode.Ok || res.errorCode !== ErrorCode.Ok) return null;
189
+
190
+ // AuthenticateApi success auto-caches authToken + userId.
191
+ if (res.responseData.newlyCreated) console.log("new player created");
192
+ return res.responseData;
193
+ }
194
+ ```
195
+
196
+ ### Return paths
197
+
198
+ - Happy → `authToken` + `newlyCreated` flag cho biết user mới hay đã tồn tại.
199
+ - `ErrorCode.VerifyTokenError` hoặc `ErrorCode.VerifyFailed` → ID token social invalid/expired.
200
+ - `ErrorCode.ExternalLinkedOtherAccount` hoặc `ErrorCode.ExternalLinkedOtherValue` → social id đã liên kết account khác.
201
+
202
+ ### Pitfalls
203
+
204
+ - `createPlayerIfNotExists: false` với social id chưa từng login → `ErrorCode.AccountNotFound`. Set `true` cho flow "login hoặc register" tự động.
205
+ - Apple ID token có lifetime rất ngắn; lấy xong phải call ngay.
206
+
207
+ ---
208
+
209
+ ## Scenario 5: Connect socket + handle reconnect
210
+
211
+ **Problem:** Cần realtime event (group message, friend update, …) — phải connect socket.
212
+
213
+ **Prerequisites:** đã login (có `authToken` cache); `useSocket: true` trong settings.
214
+
215
+ **APIs used:** `GNNetwork.connectSocket`, `GNNetwork.sendRequestAuthSocket`, `GNNetwork.subscriberOnConnectHandler`, `GNNetwork.subscriberOnDisconnectHandler`.
216
+
217
+ ### Code
218
+
219
+ ```typescript
220
+ import { GNNetwork } from "@xmobitea/gn-typescript-client";
221
+
222
+ GNNetwork.subscriberOnConnectHandler(() => {
223
+ console.log("socket connected, sid=", GNNetwork.getSocketSId());
224
+ // SDK auto-auths the socket if an auth token is already cached.
225
+ // Call GNNetwork.sendRequestAuthSocket() manually only when login/token refresh happens after this connect.
226
+ });
227
+
228
+ GNNetwork.subscriberOnDisconnectHandler(() => {
229
+ console.warn("socket disconnected — SDK will auto-reconnect after reconnectDelay ms");
230
+ });
231
+
232
+ GNNetwork.connectSocket(() => {
233
+ // optional one-shot callback on first connect
234
+ });
235
+ ```
236
+
237
+ ### Return paths
238
+
239
+ - Connect thành công → `onConnect` callback fire; `isSocketConnected()` trả `true`.
240
+ - Disconnect do network → SDK tự retry sau `reconnectDelay` (default 5000ms). Mỗi lần reconnect sẽ fire `onConnect` handler lại.
241
+
242
+ ### Pitfalls
243
+
244
+ - Nếu socket connect trước khi login/token refresh, cần gọi `sendRequestAuthSocket()` sau khi token có trong cache để re-auth thủ công.
245
+ - `subscriberOnConnectHandler` gắn MULTIPLE callback, mỗi lần reconnect đều fire tất cả. Dùng `unscriberOnConnectHandler` khi cleanup.
246
+ - `connectSocket()` gọi trước `init()` → crash.
247
+
248
+ ---
249
+
250
+ ## Scenario 6: Subscribe friend updates
251
+
252
+ **Problem:** Hiển thị UI danh sách bạn bè realtime (thêm/xóa/thay đổi status).
253
+
254
+ **Prerequisites:** socket đã connected + authenticated (scenario 5).
255
+
256
+ **APIs used:** [`OnGamePlayerFriendUpdateEventHandler`](reference/EVENTS.md#ongameplayerfriendupdateeventhandler).
257
+
258
+ ### Code
259
+
260
+ ```typescript
261
+ import { OnGamePlayerFriendUpdateEventHandler, FriendStatus } from "@xmobitea/gn-typescript-client";
262
+
263
+ OnGamePlayerFriendUpdateEventHandler.onUpdate = (payload) => {
264
+ // payload.playerFriends: Array<GenericModels.FriendItem>
265
+ for (const f of payload.playerFriends ?? []) {
266
+ switch (f.status) {
267
+ case FriendStatus.Friend: {
268
+ upsertFriendInUI(f);
269
+ break;
270
+ }
271
+ case FriendStatus.WaitingAccept:
272
+ case FriendStatus.SentRequestAndWaitingAccept: {
273
+ showFriendRequest(f);
274
+ break;
275
+ }
276
+ case FriendStatus.NotFriend: {
277
+ removeFriendFromUI(f.friendId);
278
+ break;
279
+ }
280
+ }
281
+ }
282
+ };
283
+
284
+ // Cleanup khi user logout hoặc navigate đi
285
+ function unsubscribe() {
286
+ OnGamePlayerFriendUpdateEventHandler.onUpdate = () => {};
287
+ }
288
+ ```
289
+
290
+ ### Return paths
291
+
292
+ - Event fire mỗi khi friend relation thay đổi — hot path, đừng làm heavy work trong handler.
293
+ - Không có ACK trả về; delivery là at-most-once khi socket up.
294
+
295
+ ### Pitfalls
296
+
297
+ - `onUpdate` là field `static` — gán nhiều component sẽ **ghi đè lẫn nhau**, chỉ handler cuối cùng fire. Dùng wrapper pattern (xem [EVENTS.md](reference/EVENTS.md)) nếu cần fan-out.
298
+ - Khi socket tạm mất kết nối → event trong interval đó KHÔNG được replay. App nên resync bằng `GNNetwork.gamePlayer.getFriendList*` sau reconnect.
299
+
300
+ ---
301
+
302
+ ## Scenario 7: Subscribe + send group message
303
+
304
+ **Problem:** Chat trong group — lắng nghe message đến + gửi message đi.
305
+
306
+ **Prerequisites:** đã login + connect socket + là member của `groupId`.
307
+
308
+ **APIs used:** [`OnGroupMessageUpdateEventHandler`](reference/EVENTS.md#ongroupmessageupdateeventhandler), [`GNNetwork.group.sendGroupMessageAsync`](reference/API_GROUP.md).
309
+
310
+ ### Code
311
+
312
+ ```typescript
313
+ import {
314
+ GNNetwork,
315
+ OnGroupMessageUpdateEventHandler,
316
+ ReturnCode,
317
+ ErrorCode,
318
+ GroupModels,
319
+ } from "@xmobitea/gn-typescript-client";
320
+
321
+ // 1. Subscribe incoming messages
322
+ OnGroupMessageUpdateEventHandler.onUpdate = (payload) => {
323
+ if (payload.groupId !== currentGroupId) return;
324
+ for (const msg of payload.groupMessages ?? []) {
325
+ appendMessageToUI(msg);
326
+ }
327
+ };
328
+
329
+ // 2. Send a new message
330
+ async function sendGroupChat(groupId: string, text: string) {
331
+ const request = new GroupModels.SendGroupMessageRequestData();
332
+ request.senderId = GNNetwork.getAuthenticateStatus().getUserId();
333
+ request.groupId = groupId;
334
+ request.message = text;
335
+
336
+ const res = await GNNetwork.group.sendGroupMessageAsync(request);
337
+
338
+ if (res.returnCode !== ReturnCode.Ok || res.errorCode !== ErrorCode.Ok) {
339
+ console.warn("send failed", res.errorCode, res.debugMessage);
340
+ return false;
341
+ }
342
+ return true;
343
+ }
344
+ ```
345
+
346
+ ### Return paths
347
+
348
+ - Response `sendGroupMessageAsync` trả về nhanh khi server đã nhận — event `OnGroupMessageUpdate` sẽ fire cho TẤT CẢ member trong group (bao gồm sender).
349
+ - `ErrorCode.PlayerNotMember` hoặc `ReturnCode.OperationNotAllow` → user không phải member hoặc secret thiếu permission gửi message.
350
+ - `ErrorCode.GroupNotFound` → `groupId` sai.
351
+
352
+ ### Pitfalls
353
+
354
+ - Optimistic UI: nếu append message ngay sau khi gọi send thành công, và event handler cũng append → duplicate. Dùng messageId server trả về để dedupe.
355
+ - Event `OnGroupMessageUpdate` có thể payload nhiều message cùng lúc (khi backend batch) — luôn lặp `payload.groupMessages`.
356
+
357
+ ---
358
+
359
+ ## Scenario 8: Group member lifecycle (join / leave / kick) + realtime update
360
+
361
+ **Problem:** User join/leave group, và mọi member khác thấy roster update realtime.
362
+
363
+ **Prerequisites:** đã login + connect socket.
364
+
365
+ **APIs used:** `GNNetwork.gamePlayer.joinGroupAsync`, `GNNetwork.gamePlayer.leaveGroupAsync`, `GNNetwork.group.server.removeMemberAsync`, [`OnGroupMemberUpdateEventHandler`](reference/EVENTS.md#ongroupmemberupdateeventhandler).
366
+
367
+ ### Code
368
+
369
+ ```typescript
370
+ import {
371
+ GNNetwork,
372
+ OnGroupMemberUpdateEventHandler,
373
+ ReturnCode,
374
+ ErrorCode,
375
+ GamePlayerModels,
376
+ } from "@xmobitea/gn-typescript-client";
377
+
378
+ OnGroupMemberUpdateEventHandler.onUpdate = (payload) => {
379
+ if (payload.groupId !== currentGroupId) return;
380
+ for (const m of payload.members ?? []) {
381
+ // MemberItem.status is backend-defined; update idempotently and resync roster after reconnect.
382
+ roster.upsert(m);
383
+ }
384
+ };
385
+
386
+ async function join(groupId: string) {
387
+ const request = new GamePlayerModels.JoinGroupRequestData();
388
+ request.groupId = groupId;
389
+
390
+ const res = await GNNetwork.gamePlayer.joinGroupAsync(request);
391
+ if (res.returnCode !== ReturnCode.Ok || res.errorCode !== ErrorCode.Ok) {
392
+ if (res.errorCode === ErrorCode.GroupNotFound) return "group_not_found";
393
+ return "error";
394
+ }
395
+ return "ok";
396
+ }
397
+
398
+ async function leave(groupId: string) {
399
+ const request = new GamePlayerModels.LeaveGroupRequestData();
400
+ request.groupId = groupId;
401
+
402
+ await GNNetwork.gamePlayer.leaveGroupAsync(request);
403
+ }
404
+ ```
405
+
406
+ ### Return paths
407
+
408
+ - Join OK → event `OnGroupMemberUpdate` fire với status `Joined`.
409
+ - `ErrorCode.GroupNotFound`, `ErrorCode.GamePlayerNotFound`, `ErrorCode.PlayerBan`, hoặc `ReturnCode.OperationNotAllow` → xử lý theo context.
410
+
411
+ ### Pitfalls
412
+
413
+ - `removeMember` là method `.server` namespace — chỉ call được nếu có `secretKey` có `permission rules` có `group.removeMember.serverSelfEnable`. Từ client thường expose qua CloudScript.
414
+
415
+ ---
416
+
417
+ ## Scenario 9: Matchmaking ticket flow
418
+
419
+ **Problem:** User bấm "Find match" → enqueue ticket → poll status → vào match khi ghép xong.
420
+
421
+ **Prerequisites:** đã login + connect socket.
422
+
423
+ **APIs used:** `GNNetwork.multiplayer.createMatchmakingTicketAsync`, `getMatchmakingTicketAsync`, `cancelMatchmakingTicketAsync`. Xem [API_MULTIPLAYER.md](reference/API_MULTIPLAYER.md).
424
+
425
+ ### Code
426
+
427
+ ```typescript
428
+ import {
429
+ GNNetwork,
430
+ ReturnCode,
431
+ ErrorCode,
432
+ GNHashtable,
433
+ MultiplayerModels,
434
+ MatchmakingTicketStatus,
435
+ } from "@xmobitea/gn-typescript-client";
436
+
437
+ async function findMatch(queueName: string) {
438
+ const createRequest = new MultiplayerModels.CreateMatchmakingTicketRequestData();
439
+ createRequest.queueName = queueName;
440
+ createRequest.giveUpAfterSeconds = 60;
441
+ createRequest.attribute = GNHashtable.builder().build();
442
+
443
+ const createRes = await GNNetwork.multiplayer.createMatchmakingTicketAsync(createRequest);
444
+ if (createRes.returnCode !== ReturnCode.Ok || createRes.errorCode !== ErrorCode.Ok) {
445
+ return null;
446
+ }
447
+ const ticketId = createRes.responseData.ticketId;
448
+
449
+ // Poll mỗi 2s cho tới khi matched hoặc timeout
450
+ for (let i = 0; i < 30; i++) {
451
+ await new Promise((r) => setTimeout(r, 2000));
452
+ const pollRequest = new MultiplayerModels.GetMatchmakingTicketRequestData();
453
+ pollRequest.ticketId = ticketId;
454
+ pollRequest.returnMember = true;
455
+
456
+ const poll = await GNNetwork.multiplayer.getMatchmakingTicketAsync(pollRequest);
457
+ if (poll.returnCode !== ReturnCode.Ok || poll.errorCode !== ErrorCode.Ok) continue;
458
+
459
+ const ticket = poll.responseData.matchmakingTicket;
460
+ const status = ticket.status;
461
+ if (status === MatchmakingTicketStatus.Matched) {
462
+ return ticket.matchId;
463
+ }
464
+ if (status === MatchmakingTicketStatus.Canceled) {
465
+ return null;
466
+ }
467
+ }
468
+
469
+ // Timeout: cancel ticket để queue không giữ slot
470
+ const cancelRequest = new MultiplayerModels.CancelMatchmakingTicketRequestData();
471
+ cancelRequest.ticketId = ticketId;
472
+
473
+ await GNNetwork.multiplayer.cancelMatchmakingTicketAsync(cancelRequest);
474
+ return null;
475
+ }
476
+ ```
477
+
478
+ ### Return paths
479
+
480
+ - `MatchmakingTicketStatus.Matched` → có `matchId`, chuyển sang scene game.
481
+ - `WaitingForMembers`, `WaitingForMatch`, `WaitingForServer` → tiếp tục poll.
482
+ - `Canceled` → abort.
483
+
484
+ ### Pitfalls
485
+
486
+ - Không cancel khi user hủy → ticket vẫn trong queue, occupy slot tới khi server timeout.
487
+ - Poll interval quá ngắn (<1s) → rate-limit reject.
488
+
489
+ ---
490
+
491
+ ## Scenario 10: Inventory query + grant item (server role)
492
+
493
+ **Problem:** Client xem inventory; backend/CloudScript grant item cho player khác.
494
+
495
+ **Prerequisites:** client login; `secretKey` có `permission rules` là `admin` hoặc `server` cấu hình ở backend/CloudScript.
496
+
497
+ **APIs used:** [`GNNetwork.gamePlayer.getPlayerInventoryAsync`](reference/API_GAME_PLAYER.md) (client), `GNNetwork.gamePlayer.server.createPlayerItemAsync` (server).
498
+
499
+ ### Code
500
+
501
+ ```typescript
502
+ import { GNNetwork, ReturnCode, ErrorCode, GamePlayerModels } from "@xmobitea/gn-typescript-client";
503
+
504
+ // Client: xem inventory của chính mình
505
+ async function loadMyInventory() {
506
+ const request = new GamePlayerModels.GetPlayerInventoryRequestData();
507
+ request.itemCatalogIds = ["weapon"];
508
+
509
+ const res = await GNNetwork.gamePlayer.getPlayerInventoryAsync(request);
510
+ if (res.returnCode !== ReturnCode.Ok || res.errorCode !== ErrorCode.Ok) return [];
511
+ return res.responseData.infoResponseParameters?.playerInventories ?? [];
512
+ }
513
+
514
+ // Server: create/grant 1 sword cho player targetUserId
515
+ async function grantSword(targetUserId: string) {
516
+ const request = new GamePlayerModels.ServerCreatePlayerItemRequestData();
517
+ request.userId = targetUserId;
518
+ request.catalogId = "weapon";
519
+ request.classId = "sword_001";
520
+ request.displayName = "Starter Sword";
521
+ request.amount = 1;
522
+
523
+ const res = await GNNetwork.gamePlayer.server.createPlayerItemAsync(request);
524
+ return res.returnCode === ReturnCode.Ok && res.errorCode === ErrorCode.Ok;
525
+ }
526
+ ```
527
+
528
+ ### Return paths
529
+
530
+ - Client query → không truyền `userId` nên backend resolve inventory của game player đang authenticate.
531
+ - Server grant → nếu `secretKey` sai/thiếu → `ReturnCode.SecretInvalid`; nếu secret hợp lệ nhưng thiếu flag → `ReturnCode.OperationNotAllow`.
532
+
533
+ ### Pitfalls
534
+
535
+ - NÊN gọi `.server` trong backend Node service hoặc CloudScript.
536
+
537
+ ---
538
+
539
+ ## Scenario 11: Store list catalog → purchase → validate receipt
540
+
541
+ **Problem:** User mở shop → chọn item → mua → xác nhận nhận hàng.
542
+
543
+ **Prerequisites:** đã login.
544
+
545
+ **APIs used:** [`GNNetwork.storeInventory.getStoreItemsWithTagAsync`](reference/API_STORE_INVENTORY.md), `buyStoreItemAsync`, `server.validateGooglePlayStoreReceiptAsync` / `server.validateAppleAppStoreReceiptAsync`.
546
+
547
+ ### Code
548
+
549
+ ```typescript
550
+ import { GNNetwork, ReturnCode, ErrorCode, OwnerType, StoreInventoryModels } from "@xmobitea/gn-typescript-client";
551
+
552
+ async function listCatalog() {
553
+ const infoRequestParam = new StoreInventoryModels.InfoRequestParam();
554
+ infoRequestParam.displayName = true;
555
+ infoRequestParam.tags = true;
556
+
557
+ const request = new StoreInventoryModels.GetStoreItemsWithTagRequestData();
558
+ request.key = "visible";
559
+ request.value = "true";
560
+ request.infoRequestParam = infoRequestParam;
561
+ request.skip = 0;
562
+ request.limit = 50;
563
+
564
+ const res = await GNNetwork.storeInventory.getStoreItemsWithTagAsync(request);
565
+ if (res.returnCode !== ReturnCode.Ok || res.errorCode !== ErrorCode.Ok) return [];
566
+ return res.responseData.results ?? [];
567
+ }
568
+
569
+ async function buyItem(storeItemId: string) {
570
+ const request = new StoreInventoryModels.BuyStoreItemRequestData();
571
+ request.storeId = storeItemId;
572
+ request.id = GNNetwork.getAuthenticateStatus().getUserId();
573
+ request.type = OwnerType.GamePlayer;
574
+ request.log = "shop_purchase";
575
+
576
+ const res = await GNNetwork.storeInventory.buyStoreItemAsync(request);
577
+
578
+ if (res.returnCode !== ReturnCode.Ok) return "transport_error";
579
+ switch (res.errorCode) {
580
+ case ErrorCode.Ok:
581
+ return "ok";
582
+ case ErrorCode.NotEnoughCurrency:
583
+ return "not_enough_currency";
584
+ case ErrorCode.StoreItemRemoved:
585
+ case ErrorCode.CanNotBuyThisStoreItem:
586
+ return "not_buyable";
587
+ default:
588
+ return "unhandled_" + res.errorCode;
589
+ }
590
+ }
591
+ ```
592
+
593
+ ### Return paths
594
+
595
+ - `ErrorCode.Ok` → item đã grant vào inventory player; currency đã trừ.
596
+ - `ErrorCode.NotEnoughCurrency` (8) → cần topup.
597
+ - `ErrorCode.StoreItemRemoved` hoặc `ErrorCode.CanNotBuyThisStoreItem` → item không còn mua được ở state hiện tại.
598
+
599
+ ### Pitfalls
600
+
601
+ - In-app purchase (IAP) có receipt native — validate qua method cụ thể theo store, ví dụ `storeInventory.server.validateGooglePlayStoreReceiptAsync` hoặc `validateAppleAppStoreReceiptAsync`, trước khi tin kết quả grant.
602
+
603
+ ---
604
+
605
+ ## Scenario 12: CloudScript execute function + customTags
606
+
607
+ **Problem:** Trigger function server-side custom (ví dụ "claim daily reward") từ client.
608
+
609
+ **Prerequisites:** đã login; CloudScript function đã publish ở backend.
610
+
611
+ **APIs used:** [`GNNetwork.cloudScript.executeFunctionAsync`](reference/API_CLOUDSCRIPT.md).
612
+
613
+ ### Code
614
+
615
+ ```typescript
616
+ import { GNNetwork, ReturnCode, ErrorCode, CloudScriptModels, ExecuteResponseStatus, GNHashtable } from "@xmobitea/gn-typescript-client";
617
+
618
+ async function claimDailyReward() {
619
+ const request = new CloudScriptModels.ExecuteFunctionRequestData();
620
+ request.functionName = "claimDailyReward";
621
+ request.functionParameters = { date: new Date().toISOString().slice(0, 10) };
622
+
623
+ const res = await GNNetwork.cloudScript.executeFunctionAsync(
624
+ request,
625
+ undefined, // overrideAuthToken
626
+ undefined, // overrideSecretKey
627
+ GNHashtable.builder().add("source", "daily_popup").build(), // customTags
628
+ 30, // timeout (seconds)
629
+ );
630
+
631
+ if (res.returnCode !== ReturnCode.Ok || res.errorCode !== ErrorCode.Ok) return null;
632
+
633
+ const exec = res.responseData;
634
+ if (exec.status !== ExecuteResponseStatus.Ok) {
635
+ console.warn("function failed", exec.errorMessage);
636
+ return null;
637
+ }
638
+ return exec.functionResult; // raw payload từ function
639
+ }
640
+ ```
641
+
642
+ ### Return paths
643
+
644
+ - `ExecuteResponseStatus.Ok` → function chạy xong, `functionResult` là value function trả về.
645
+ - `ExecuteResponseStatus.Exception` → function throw; `exec.errorMessage` chứa message.
646
+ - `ExecuteResponseStatus.FunctionNameNotFound` → function chưa publish/export hoặc sai tên.
647
+
648
+ ### Pitfalls
649
+
650
+ - `customTags` là `GNHashtable`; dùng `GNHashtable.builder()` để giữ đúng public type. Giá trị nên là primitive hoặc string; không nhét object lồng.
651
+ - Timeout function mặc định 20s — function nặng (query DB lớn) nên tăng timeout param.
652
+
653
+ ---
654
+
655
+ ## Scenario 13: Override authToken / secret (impersonate, cross-role)
656
+
657
+ **Problem:** Đang ở role admin/server, cần gọi API như một player cụ thể (impersonate) hoặc override secret key của request cụ thể.
658
+
659
+ **APIs used:** mọi method — async form nhận `overrideAuthToken`, `overrideSecretKey` là param thứ 2-3; callback form là param thứ 3-4 vì có `onResponse`.
660
+
661
+ ### Code
662
+
663
+ ```typescript
664
+ import { GNNetwork, ContentModels, MasterPlayerModels } from "@xmobitea/gn-typescript-client";
665
+
666
+ // Impersonate player để query profile của họ
667
+ async function fetchProfileAs(playerAuthToken: string, playerId: string) {
668
+ const infoRequestParam = new MasterPlayerModels.InfoRequestParam();
669
+ infoRequestParam.displayName = true;
670
+ infoRequestParam.avatar = true;
671
+
672
+ const request = new MasterPlayerModels.GetPlayerInformationRequestData();
673
+ request.userId = playerId;
674
+ request.infoRequestParam = infoRequestParam;
675
+
676
+ const res = await GNNetwork.masterPlayer.getPlayerInformationAsync(
677
+ request,
678
+ playerAuthToken, // overrideAuthToken — thay token cache
679
+ undefined, // overrideSecretKey — giữ secret key mặc định của role
680
+ undefined, // customTags
681
+ undefined, // timeout
682
+ );
683
+ return res.responseData;
684
+ }
685
+
686
+ // Dùng secret key khác (ví dụ một game khác cùng backend)
687
+ async function callOtherGame(gameSecret: string) {
688
+ const request = new ContentModels.GetContentDataRequestData();
689
+ request.keys = ["config"];
690
+
691
+ return GNNetwork.content.getContentDataAsync(
692
+ request,
693
+ undefined,
694
+ gameSecret,
695
+ );
696
+ }
697
+ ```
698
+
699
+ ### Return paths
700
+
701
+ - Token override bypass cache; request này KHÔNG update cached token.
702
+ - Secret override bypass `secretKey` mặc định.
703
+
704
+ ### Pitfalls
705
+
706
+ - Override không persist — mỗi request phải truyền lại.
707
+ - Truyền `overrideAuthToken = ""` (rỗng) → request đi KHÔNG CÓ auth header, thường fail với `ReturnCode.OperationNotAuthorized`. Muốn dùng auth cache hiện tại thì truyền `null`/`undefined`.
708
+
709
+ ---
710
+
711
+ ## Scenario 14: Admin login qua DashboardApi
712
+
713
+ **Problem:** Tool dashboard web — cần admin login bằng username/password admin, rồi query game list / analytics.
714
+
715
+ **Prerequisites:** đã init; biết admin username/password backend cấp.
716
+
717
+ **APIs used:** [`GNNetwork.dashboard.loginByAdminAccountAsync`](reference/API_DASHBOARD.md), `getGameListAsync`, `getAnalyticsAsync`, …
718
+
719
+ > **Lưu ý thiết kế:** Dashboard API CHỈ có namespace client (`GNNetwork.dashboard`, không có `.server` / `.admin`). Transport dùng `RequestRole.Client`. Admin context backend resolve TỪ auth token trả về sau `loginByAdminAccount` — token này khác token của player thường.
720
+
721
+ ### Code
722
+
723
+ ```typescript
724
+ import { GNNetwork, ReturnCode, ErrorCode, DashboardModels } from "@xmobitea/gn-typescript-client";
725
+
726
+ async function adminLogin(username: string, password: string) {
727
+ const request = new DashboardModels.LoginByAdminAccountRequestData();
728
+ request.username = username;
729
+ request.password = password;
730
+
731
+ const res = await GNNetwork.dashboard.loginByAdminAccountAsync(request);
732
+ if (res.returnCode !== ReturnCode.Ok || res.errorCode !== ErrorCode.Ok) return false;
733
+
734
+ // Dashboard response carries authToken; SDK caches it for later dashboard calls.
735
+ return true;
736
+ }
737
+
738
+ async function listGames() {
739
+ const res = await GNNetwork.dashboard.getGameListAsync(new DashboardModels.GetGameListRequestData());
740
+ return res.responseData?.games ?? [];
741
+ }
742
+ ```
743
+
744
+ ### Return paths
745
+
746
+ - Happy → admin token được SDK cache; mọi dashboard method sau đó dùng token này.
747
+ - `ErrorCode.AccountNotFound` / `ErrorCode.AccountPasswordWrong` → giống player login.
748
+
749
+ ### Pitfalls
750
+
751
+ - Trộn admin token với player flow → backend reject. Sau admin logout, clear token trước khi login player.
752
+ - Dashboard KHÔNG cần socket — có thể set `useSocket: false` trong settings cho web dashboard.
753
+
754
+ ---
755
+
756
+ ## Scenario 15: Cleanup & shutdown flow
757
+
758
+ **Problem:** User logout hoặc app shutdown — cần close socket + clear auth để session sau không leak state.
759
+
760
+ ### Code
761
+
762
+ ```typescript
763
+ import { GNNetwork, AuthenticateStatus, OnGroupMessageUpdateEventHandler, OnGroupMemberUpdateEventHandler, OnGamePlayerFriendUpdateEventHandler, OnGamePlayerGroupUpdateEventHandler, OnCharacterPlayerFriendUpdateEventHandler, OnCharacterPlayerGroupUpdateEventHandler } from "@xmobitea/gn-typescript-client";
764
+
765
+ function logoutAndCleanup() {
766
+ // 1. Clear all event handler callbacks (chúng là static, không tự gc)
767
+ const noop = () => {};
768
+ OnGroupMessageUpdateEventHandler.onUpdate = noop;
769
+ OnGroupMemberUpdateEventHandler.onUpdate = noop;
770
+ OnGamePlayerFriendUpdateEventHandler.onUpdate = noop;
771
+ OnGamePlayerGroupUpdateEventHandler.onUpdate = noop;
772
+ OnCharacterPlayerFriendUpdateEventHandler.onUpdate = noop;
773
+ OnCharacterPlayerGroupUpdateEventHandler.onUpdate = noop;
774
+
775
+ // 2. Close socket
776
+ GNNetwork.disconnectSocket(() => {
777
+ console.log("socket closed");
778
+ });
779
+
780
+ // 3. Clear auth state
781
+ const empty = new AuthenticateStatus();
782
+ empty.setAuthToken("");
783
+ empty.setUserId("");
784
+ GNNetwork.setNewAuthenticateStatus(empty);
785
+ }
786
+ ```
787
+
788
+ ### Return paths
789
+
790
+ - `disconnectSocket` callback fire khi connection closed. Sau đó socket không auto-reconnect (stop reconnect loop).
791
+ - `setNewAuthenticateStatus` với token rỗng xóa state + localStorage entry.
792
+
793
+ ### Pitfalls
794
+
795
+ - Không clear event handler → new session fire vào callback cũ trỏ tới UI component đã unmount, gây crash.
796
+ - Không đợi `disconnectSocket` callback mà shutdown process ngay → socket có thể không gửi packet `logout` tới server → backend phải đợi timeout để cleanup session.
797
+
798
+ ---
799
+
800
+ ## Scenario 16: Diagnose `OperationNotAllow`
801
+
802
+ **Problem:** Một API call trả `ReturnCode.OperationNotAllow`. Cần xác định root cause và fix.
803
+
804
+ **Prerequisites:** biết method đang gọi, namespace (`client` / `.server` / `.admin`), target user (nếu có), secret key đang dùng.
805
+
806
+ **Key insight:** `OperationNotAllow` **không** phải thiếu secret hoặc operation không tồn tại (đó là `SecretInvalid` và `OperationInvalid`). Đây là: secret hợp lệ, operation tồn tại, nhưng **permission rule** của secret không cho phép operation trong target context. Xem [RULES § 5](RULES.md#5-phân-biệt-3-returncode-dễ-nhầm).
807
+
808
+ ### Decision tree
809
+
810
+ ```
811
+ Gặp returnCode === OperationNotAllow
812
+
813
+ ├─ Bước 1: Xác định route đang gọi
814
+ │ • GNNetwork.<group>.<method>(...) → route = client
815
+ │ • GNNetwork.<group>.server.<method>(...) → route = server
816
+ │ • GNNetwork.<group>.admin.<method>(...) → route = admin
817
+
818
+ ├─ Bước 2: Xác định target (chỉ áp dụng route client)
819
+ │ • Bỏ userId HOẶC userId trùng auth → target = self
820
+ │ • userId khác auth user → target = other-self
821
+ │ • Domain không có ownership (Content,
822
+ │ StoreInventory, Multiplayer, CloudScript) → bỏ qua bước 2
823
+
824
+ ├─ Bước 3: Map route + target → flag cần (RULES § 6.1)
825
+ │ • client + self → selfEnable
826
+ │ • client + other-self → otherSelfEnable
827
+ │ • server → serverSelfEnable
828
+ │ • admin → adminSelfEnable
829
+
830
+ ├─ Bước 4: Check secret active có flag đó cho operation đang gọi không?
831
+ │ → xem dashboard GearN Server hoặc hỏi backend admin
832
+ │ → danh sách operation: reference/PERMISSION_RULES.md + API_<GROUP>.md
833
+
834
+ └─ Bước 5: Nếu không có flag, chọn 1 trong 3 action:
835
+ (a) Dùng secret khác qua GNServerSettings.secretKey (cần restart process)
836
+ (b) Override per-request: truyền overrideSecretKey vào method
837
+ (c) Yêu cầu backend admin bật flag trong GearN Dashboard tương ứng cho secret hiện tại
838
+ ```
839
+
840
+ ### Code
841
+
842
+ ```ts
843
+ import {
844
+ GNNetwork,
845
+ ReturnCode,
846
+ InventoryModels,
847
+ } from "@xmobitea/gn-typescript-client";
848
+
849
+ async function grantItem(userId: string, itemId: string, amount: number) {
850
+ const req = new InventoryModels.SetAmountRequestData();
851
+ req.itemId = itemId;
852
+ req.amount = amount;
853
+
854
+ // Attempt 1: route admin với secret mặc định của app
855
+ let res = await GNNetwork.inventory.admin.setAmountAsync(req);
856
+
857
+ if (res.returnCode === ReturnCode.OperationNotAllow) {
858
+ console.warn("OperationNotAllow on admin route — secret thiếu adminSelfEnable cho inventory.setAmount");
859
+ console.warn("debugMessage:", res.debugMessage);
860
+
861
+ // Attempt 2: fallback override secret admin cho 1 request
862
+ const ADMIN_SECRET = process.env.GEARN_ADMIN_SECRET; // KHÔNG hardcode
863
+ if (ADMIN_SECRET) {
864
+ res = await GNNetwork.inventory.admin.setAmountAsync(
865
+ req,
866
+ undefined, // overrideAuthToken
867
+ ADMIN_SECRET, // overrideSecretKey
868
+ );
869
+ }
870
+ }
871
+
872
+ if (res.returnCode !== ReturnCode.Ok) {
873
+ // Vẫn fail sau fallback → báo ops, KHÔNG retry
874
+ throw new Error(`grant failed: returnCode=${res.returnCode}, debug=${res.debugMessage}`);
875
+ }
876
+ return res.responseData;
877
+ }
878
+ ```
879
+
880
+ ### Return paths
881
+
882
+ - `OperationNotAllow` → **không retry cùng secret**, đó là config fix.
883
+ - Sau fallback `overrideSecretKey` vẫn `OperationNotAllow` → secret admin cũng thiếu flag, phải liên hệ backend admin thêm flag trong GearN Dashboard.
884
+ - Nếu chuyển sang `SecretInvalid` sau fallback → override secret sai format / không khớp game context (khác lỗi, xem [RULES § 5](RULES.md#5-phân-biệt-3-returncode-dễ-nhầm)).
885
+
886
+ ### Pitfalls
887
+
888
+ - **Nhầm `OperationNotAllow` với `SecretInvalid`** → sửa sai hướng, đổi secret vô nghĩa khi rule chưa được bật.
889
+ - **Dùng `.server` / `.admin` từ frontend app để vượt permission** → trust boundary leak, secret bị expose. Route phải match caller thực tế (xem [RULES § 3](RULES.md#3-route--trust-boundary-của-caller)).
890
+ - **Retry tự động khi gặp `OperationNotAllow`** → không bao giờ giải quyết được, chỉ tốn request budget.
891
+ - **Giả định rule `selfEnable` tự bật** → backend admin config per-operation, không default bật tất cả.
892
+ - **Không check self vs other-self khi ở route `client`** → ví dụ gọi `masterPlayer.getPlayerInformationAsync(otherId)` mà nghĩ vẫn là self → sai flag → debug lâu.
893
+
894
+ ### Liên kết
895
+
896
+ - Mapping rule đầy đủ: [RULES § 6.1](RULES.md#61-mapping-route-target--required-flag)
897
+ - Scenario điển hình (5 case): [RULES § 6.3](RULES.md#63-scenario-điển-hình-trigger-operationnotallow)
898
+ - Checklist nhanh: [RULES § 6.4](RULES.md#64-checklist-nhanh-khi-gặp-returncodeoperationnotallow)
899
+ - Danh sách operation per-domain: [reference/PERMISSION_RULES.md](reference/PERMISSION_RULES.md)
900
+
901
+ ---
902
+
903
+ ## Pattern chung xuyên scenarios
904
+
905
+ | Pattern | Khi nào | Tham khảo |
906
+ |---------|---------|-----------|
907
+ | Check `returnCode` → `errorCode` → đọc `responseData` | Mọi `*Async()` | [ERROR_HANDLING.md](reference/ERROR_HANDLING.md) |
908
+ | SDK auto-cache `authToken` / `userId` sau authenticate success | Login/refresh player; dashboard login cache `authToken` | Scenario 2, 3, 4, 14 |
909
+ | Subscribe event handler trước `connectSocket`; chỉ gọi `sendRequestAuthSocket` khi cần re-auth thủ công | Realtime | Scenario 5, 6, 7, 8 |
910
+ | `.server` / `.admin` chỉ ở backend, không bao giờ ở frontend | Mọi cross-role call | Scenario 10, 13 |
911
+ | `customTags` để backend log/route | Khi cần phân loại source | Scenario 12 |
912
+ | Clear event handler + `disconnectSocket` + `setNewAuthenticateStatus(empty)` khi logout | Unload/logout | Scenario 15 |