@xmobitea/gn-typescript-client 2.6.13-tsc → 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 (400) hide show
  1. package/AGENTS.md +37 -0
  2. package/README.MD +420 -1
  3. package/dist/gearn.js.client.js +71354 -0
  4. package/dist/gearn.js.client.min.js +2 -0
  5. package/dist/gearn.js.client.min.js.LICENSE.txt +14 -0
  6. package/dist/index.d.ts +30 -0
  7. package/dist/index.js +58386 -339
  8. package/dist/runtime/GNNetwork.d.ts +687 -3
  9. package/dist/runtime/GNNetworkAuthenticateApi.d.ts +327 -0
  10. package/dist/runtime/GNNetworkCharacterPlayerApi.d.ts +1026 -0
  11. package/dist/runtime/GNNetworkCloudScriptApi.d.ts +141 -0
  12. package/dist/runtime/GNNetworkContentApi.d.ts +243 -0
  13. package/dist/runtime/GNNetworkDashboardApi.d.ts +221 -0
  14. package/dist/runtime/GNNetworkGamePlayerApi.d.ts +1033 -0
  15. package/dist/runtime/GNNetworkGroupApi.d.ts +783 -0
  16. package/dist/runtime/GNNetworkInventoryApi.d.ts +673 -0
  17. package/dist/runtime/GNNetworkMasterPlayerApi.d.ts +1614 -6
  18. package/dist/runtime/GNNetworkMultiplayerApi.d.ts +234 -0
  19. package/dist/runtime/GNNetworkStoreInventoryApi.d.ts +309 -0
  20. package/dist/runtime/common/Action0.d.ts +30 -0
  21. package/dist/runtime/common/Action1.d.ts +32 -0
  22. package/dist/runtime/common/Action2.d.ts +21 -0
  23. package/dist/runtime/common/Action3.d.ts +16 -0
  24. package/dist/runtime/common/Action4.d.ts +17 -0
  25. package/dist/runtime/common/GNData.d.ts +368 -0
  26. package/dist/runtime/config/GNServerSettings.d.ts +442 -12
  27. package/dist/runtime/constant/Commands.d.ts +80 -0
  28. package/dist/runtime/constant/EventCode.d.ts +48 -0
  29. package/dist/runtime/constant/OperationCode.d.ts +74 -1
  30. package/dist/runtime/constant/ReturnCode.d.ts +72 -0
  31. package/dist/runtime/constant/enumType/ExecuteResponseStatus.d.ts +31 -0
  32. package/dist/runtime/constant/enumType/FriendStatus.d.ts +39 -0
  33. package/dist/runtime/constant/enumType/GoogleLoginType.d.ts +23 -0
  34. package/dist/runtime/constant/enumType/GroupStatus.d.ts +32 -0
  35. package/dist/runtime/constant/enumType/InvalidMemberType.d.ts +75 -0
  36. package/dist/runtime/constant/enumType/ItemType.d.ts +23 -0
  37. package/dist/runtime/constant/enumType/MatchStatus.d.ts +30 -0
  38. package/dist/runtime/constant/enumType/MatchmakingMemberStatus.d.ts +24 -0
  39. package/dist/runtime/constant/enumType/MatchmakingTicketStatus.d.ts +34 -0
  40. package/dist/runtime/constant/enumType/OwnerType.d.ts +40 -0
  41. package/dist/runtime/constant/enumType/PermissionDataItem.d.ts +22 -0
  42. package/dist/runtime/constant/enumType/PushPlatformType.d.ts +18 -0
  43. package/dist/runtime/constant/enumType/RequestRole.d.ts +32 -0
  44. package/dist/runtime/constant/enumType/RequestType.d.ts +70 -0
  45. package/dist/runtime/constant/enumType/StoreItemType.d.ts +21 -0
  46. package/dist/runtime/constant/enumType/StoreReceiveType.d.ts +30 -0
  47. package/dist/runtime/constant/errorCode/ErrorCode.d.ts +190 -8
  48. package/dist/runtime/constant/parameterCode/ParameterCode.d.ts +35 -5
  49. package/dist/runtime/entity/DataMember.d.ts +338 -0
  50. package/dist/runtime/entity/GNMetadata.d.ts +101 -0
  51. package/dist/runtime/entity/InvalidMember.d.ts +28 -0
  52. package/dist/runtime/entity/OperationEvent.d.ts +49 -0
  53. package/dist/runtime/entity/OperationRequest.d.ts +108 -0
  54. package/dist/runtime/entity/OperationResponse.d.ts +110 -0
  55. package/dist/runtime/entity/models/AuthenticateModels.d.ts +115 -0
  56. package/dist/runtime/entity/models/AuthenticateRequestModels.d.ts +131 -0
  57. package/dist/runtime/entity/models/AuthenticateResponseModels.d.ts +131 -0
  58. package/dist/runtime/entity/models/CharacterPlayerModels.d.ts +625 -1
  59. package/dist/runtime/entity/models/CharacterPlayerRequestModels.d.ts +972 -0
  60. package/dist/runtime/entity/models/CharacterPlayerResponseModels.d.ts +332 -0
  61. package/dist/runtime/entity/models/CloudScriptModels.d.ts +109 -0
  62. package/dist/runtime/entity/models/CloudScriptRequestModels.d.ts +107 -0
  63. package/dist/runtime/entity/models/CloudScriptResponseModels.d.ts +46 -0
  64. package/dist/runtime/entity/models/ContentModels.d.ts +124 -0
  65. package/dist/runtime/entity/models/ContentRequestModels.d.ts +152 -0
  66. package/dist/runtime/entity/models/ContentResponseModels.d.ts +58 -0
  67. package/dist/runtime/entity/models/DashboardModels.d.ts +371 -8
  68. package/dist/runtime/entity/models/DashboardRequestModels.d.ts +172 -0
  69. package/dist/runtime/entity/models/DashboardResponseModels.d.ts +170 -0
  70. package/dist/runtime/entity/models/GamePlayerModels.d.ts +644 -1
  71. package/dist/runtime/entity/models/GamePlayerRequestModels.d.ts +959 -0
  72. package/dist/runtime/entity/models/GamePlayerResponseModels.d.ts +333 -1
  73. package/dist/runtime/entity/models/GenericModels.d.ts +94 -0
  74. package/dist/runtime/entity/models/GroupModels.d.ts +484 -2
  75. package/dist/runtime/entity/models/GroupRequestModels.d.ts +737 -0
  76. package/dist/runtime/entity/models/GroupResponseModels.d.ts +254 -0
  77. package/dist/runtime/entity/models/InventoryModels.d.ts +415 -0
  78. package/dist/runtime/entity/models/InventoryRequestModels.d.ts +629 -0
  79. package/dist/runtime/entity/models/InventoryResponseModels.d.ts +218 -0
  80. package/dist/runtime/entity/models/MasterPlayerModels.d.ts +1065 -3
  81. package/dist/runtime/entity/models/MasterPlayerRequestModels.d.ts +1560 -6
  82. package/dist/runtime/entity/models/MasterPlayerResponseModels.d.ts +532 -1
  83. package/dist/runtime/entity/models/MultiplayerModels.d.ts +199 -0
  84. package/dist/runtime/entity/models/MultiplayerRequestModels.d.ts +196 -0
  85. package/dist/runtime/entity/models/MultiplayerResponseModels.d.ts +74 -0
  86. package/dist/runtime/entity/models/StoreInventoryModels.d.ts +262 -0
  87. package/dist/runtime/entity/models/StoreInventoryRequestModels.d.ts +268 -0
  88. package/dist/runtime/entity/models/StoreInventoryResponseModels.d.ts +98 -0
  89. package/dist/runtime/entity/request/CustomOperationRequest.d.ts +99 -0
  90. package/dist/runtime/entity/response/CustomOperationResponse.d.ts +118 -0
  91. package/dist/runtime/entity/response/GetAuthInfoResponse.d.ts +53 -0
  92. package/dist/runtime/entity/response/HealthCheckResponse.d.ts +56 -0
  93. package/dist/runtime/entity/response/UploadFileResponse.d.ts +19 -0
  94. package/dist/runtime/helper/CodeHelper.d.ts +122 -0
  95. package/dist/runtime/helper/ConverterService.d.ts +74 -0
  96. package/dist/runtime/helper/EnumUtility.d.ts +63 -0
  97. package/dist/runtime/helper/GNSupport.d.ts +64 -4
  98. package/dist/runtime/helper/GNUtils.d.ts +54 -0
  99. package/dist/runtime/helper/MessagePackConverterService.d.ts +48 -0
  100. package/dist/runtime/helper/OperationHelper.d.ts +51 -0
  101. package/dist/runtime/helper/StorageService.d.ts +48 -8
  102. package/dist/runtime/logger/GNDebug.d.ts +117 -0
  103. package/dist/runtime/networking/AuthenticateStatus.d.ts +64 -0
  104. package/dist/runtime/networking/IPeer.d.ts +83 -0
  105. package/dist/runtime/networking/NetworkingPeer.d.ts +256 -1
  106. package/dist/runtime/networking/OperationPending.d.ts +112 -0
  107. package/dist/runtime/networking/PeerBase.d.ts +231 -0
  108. package/dist/runtime/networking/handler/IServerEventHandler.d.ts +84 -0
  109. package/dist/runtime/networking/handler/OnCharacterPlayerFriendUpdateEventHandler.d.ts +69 -0
  110. package/dist/runtime/networking/handler/OnCharacterPlayerGroupUpdateEventHandler.d.ts +49 -0
  111. package/dist/runtime/networking/handler/OnGamePlayerFriendUpdateEventHandler.d.ts +50 -0
  112. package/dist/runtime/networking/handler/OnGamePlayerGroupUpdateEventHandler.d.ts +41 -0
  113. package/dist/runtime/networking/handler/OnGroupMemberUpdateEventHandler.d.ts +47 -0
  114. package/dist/runtime/networking/handler/OnGroupMessageUpdateEventHandler.d.ts +46 -0
  115. package/dist/runtime/networking/http/HttpPeer.d.ts +173 -0
  116. package/dist/runtime/networking/http/NetworkingHttpPeerBase.d.ts +87 -0
  117. package/dist/runtime/networking/http/NetworkingPeerAxiosRequest.d.ts +113 -0
  118. package/dist/runtime/networking/socket/NetworkingPeerSocketIOClient.d.ts +145 -0
  119. package/dist/runtime/networking/socket/NetworkingSocketPeerBase.d.ts +198 -0
  120. package/dist/runtime/networking/socket/SocketPeer.d.ts +155 -0
  121. package/dist/runtime/typescript/ServiceUpdate.d.ts +46 -0
  122. package/docs/AI_CHEATSHEET.md +211 -0
  123. package/docs/COOKBOOK.md +912 -0
  124. package/docs/RULES.md +307 -0
  125. package/docs/ai-manifest.json +725 -0
  126. package/docs/guides/AUTHENTICATE.md +246 -0
  127. package/docs/guides/CHARACTER_PLAYER.md +439 -0
  128. package/docs/guides/CLOUDSCRIPT.md +335 -0
  129. package/docs/guides/COCOS_CREATOR_INTEGRATION.md +150 -0
  130. package/docs/guides/CONTENT.md +291 -0
  131. package/docs/guides/DASHBOARD.md +262 -0
  132. package/docs/guides/GAME_PLAYER.md +473 -0
  133. package/docs/guides/GROUP.md +412 -0
  134. package/docs/guides/INVENTORY.md +375 -0
  135. package/docs/guides/MASTER_PLAYER.md +458 -0
  136. package/docs/guides/MULTIPLAYER.md +303 -0
  137. package/docs/guides/STORE_INVENTORY.md +313 -0
  138. package/docs/llms-full.txt +43 -0
  139. package/docs/reference/API_AUTHENTICATE.md +75 -0
  140. package/docs/reference/API_CHARACTER_PLAYER.md +226 -0
  141. package/docs/reference/API_CLOUDSCRIPT.md +82 -0
  142. package/docs/reference/API_CONTENT.md +88 -0
  143. package/docs/reference/API_DASHBOARD.md +82 -0
  144. package/docs/reference/API_GAME_PLAYER.md +223 -0
  145. package/docs/reference/API_GROUP.md +187 -0
  146. package/docs/reference/API_INDEX.md +57 -0
  147. package/docs/reference/API_INVENTORY.md +169 -0
  148. package/docs/reference/API_MASTER_PLAYER.md +323 -0
  149. package/docs/reference/API_MULTIPLAYER.md +97 -0
  150. package/docs/reference/API_STORE_INVENTORY.md +109 -0
  151. package/docs/reference/CONFIG.md +107 -0
  152. package/docs/reference/DTO_INDEX.md +2543 -0
  153. package/docs/reference/ENUMS.md +433 -0
  154. package/docs/reference/ERROR_HANDLING.md +159 -0
  155. package/docs/reference/EVENTS.md +188 -0
  156. package/docs/reference/PERMISSION_RULES.md +55 -0
  157. package/docs/reference/dto/AUTHENTICATE.md +619 -0
  158. package/docs/reference/dto/CHARACTER_PLAYER.md +3686 -0
  159. package/docs/reference/dto/CLOUDSCRIPT.md +400 -0
  160. package/docs/reference/dto/CONTENT.md +548 -0
  161. package/docs/reference/dto/DASHBOARD.md +1980 -0
  162. package/docs/reference/dto/GAME_PLAYER.md +3631 -0
  163. package/docs/reference/dto/GENERIC.md +151 -0
  164. package/docs/reference/dto/GROUP.md +2842 -0
  165. package/docs/reference/dto/INVENTORY.md +2385 -0
  166. package/docs/reference/dto/MASTER_PLAYER.md +6024 -0
  167. package/docs/reference/dto/MULTIPLAYER.md +850 -0
  168. package/docs/reference/dto/STORE_INVENTORY.md +1262 -0
  169. package/llms.txt +47 -0
  170. package/package.json +11 -2
  171. package/GNServerSettings.debug.json +0 -21
  172. package/dist/runtime/GNNetwork.js +0 -273
  173. package/dist/runtime/GNNetworkAuthenticateApi.js +0 -122
  174. package/dist/runtime/GNNetworkCharacterPlayerApi.js +0 -968
  175. package/dist/runtime/GNNetworkCloudScriptApi.js +0 -104
  176. package/dist/runtime/GNNetworkContentApi.js +0 -140
  177. package/dist/runtime/GNNetworkDashboardApi.js +0 -170
  178. package/dist/runtime/GNNetworkGamePlayerApi.js +0 -950
  179. package/dist/runtime/GNNetworkGroupApi.js +0 -734
  180. package/dist/runtime/GNNetworkInventoryApi.js +0 -626
  181. package/dist/runtime/GNNetworkMasterPlayerApi.js +0 -1550
  182. package/dist/runtime/GNNetworkMultiplayerApi.js +0 -194
  183. package/dist/runtime/GNNetworkStoreInventoryApi.js +0 -266
  184. package/dist/runtime/common/Action0.js +0 -1
  185. package/dist/runtime/common/Action1.js +0 -1
  186. package/dist/runtime/common/Action2.js +0 -1
  187. package/dist/runtime/common/Action3.js +0 -1
  188. package/dist/runtime/common/Action4.js +0 -1
  189. package/dist/runtime/common/GNData.js +0 -209
  190. package/dist/runtime/config/GNServerSettings.js +0 -156
  191. package/dist/runtime/constant/Commands.js +0 -20
  192. package/dist/runtime/constant/EventCode.js +0 -8
  193. package/dist/runtime/constant/OperationCode.js +0 -221
  194. package/dist/runtime/constant/ReturnCode.js +0 -14
  195. package/dist/runtime/constant/enumType/ExecuteResponseStatus.js +0 -8
  196. package/dist/runtime/constant/enumType/FriendStatus.js +0 -7
  197. package/dist/runtime/constant/enumType/GoogleLoginType.js +0 -5
  198. package/dist/runtime/constant/enumType/GroupStatus.js +0 -7
  199. package/dist/runtime/constant/enumType/InvalidMemberType.js +0 -18
  200. package/dist/runtime/constant/enumType/ItemType.js +0 -5
  201. package/dist/runtime/constant/enumType/MatchmakingMemberStatus.js +0 -6
  202. package/dist/runtime/constant/enumType/MatchmakingTicketStatus.js +0 -8
  203. package/dist/runtime/constant/enumType/OwnerType.js +0 -9
  204. package/dist/runtime/constant/enumType/PermissionDataItem.js +0 -5
  205. package/dist/runtime/constant/enumType/PushPlatformType.js +0 -5
  206. package/dist/runtime/constant/enumType/RequestRole.js +0 -6
  207. package/dist/runtime/constant/enumType/RequestType.js +0 -15
  208. package/dist/runtime/constant/enumType/StoreItemType.js +0 -5
  209. package/dist/runtime/constant/enumType/StoreReceiveType.js +0 -8
  210. package/dist/runtime/constant/errorCode/ErrorCode.js +0 -52
  211. package/dist/runtime/constant/parameterCode/ParameterCode.js +0 -617
  212. package/dist/runtime/entity/DataMember.js +0 -208
  213. package/dist/runtime/entity/GNMetadata.js +0 -11
  214. package/dist/runtime/entity/InvalidMember.js +0 -1
  215. package/dist/runtime/entity/OperationEvent.js +0 -24
  216. package/dist/runtime/entity/OperationRequest.js +0 -42
  217. package/dist/runtime/entity/OperationResponse.js +0 -73
  218. package/dist/runtime/entity/models/AuthenticateModels.js +0 -426
  219. package/dist/runtime/entity/models/AuthenticateRequestModels.js +0 -188
  220. package/dist/runtime/entity/models/AuthenticateResponseModels.js +0 -131
  221. package/dist/runtime/entity/models/CharacterPlayerModels.js +0 -1433
  222. package/dist/runtime/entity/models/CharacterPlayerRequestModels.js +0 -1386
  223. package/dist/runtime/entity/models/CharacterPlayerResponseModels.js +0 -376
  224. package/dist/runtime/entity/models/CloudScriptModels.js +0 -197
  225. package/dist/runtime/entity/models/CloudScriptRequestModels.js +0 -138
  226. package/dist/runtime/entity/models/CloudScriptResponseModels.js +0 -40
  227. package/dist/runtime/entity/models/ContentModels.js +0 -203
  228. package/dist/runtime/entity/models/ContentRequestModels.js +0 -190
  229. package/dist/runtime/entity/models/ContentResponseModels.js +0 -54
  230. package/dist/runtime/entity/models/DashboardModels.js +0 -3002
  231. package/dist/runtime/entity/models/DashboardRequestModels.js +0 -268
  232. package/dist/runtime/entity/models/DashboardResponseModels.js +0 -187
  233. package/dist/runtime/entity/models/GamePlayerModels.js +0 -1591
  234. package/dist/runtime/entity/models/GamePlayerRequestModels.js +0 -1360
  235. package/dist/runtime/entity/models/GamePlayerResponseModels.js +0 -369
  236. package/dist/runtime/entity/models/GenericModels.js +0 -177
  237. package/dist/runtime/entity/models/GroupModels.js +0 -1135
  238. package/dist/runtime/entity/models/GroupRequestModels.js +0 -1048
  239. package/dist/runtime/entity/models/GroupResponseModels.js +0 -285
  240. package/dist/runtime/entity/models/InventoryModels.js +0 -915
  241. package/dist/runtime/entity/models/InventoryRequestModels.js +0 -892
  242. package/dist/runtime/entity/models/InventoryResponseModels.js +0 -243
  243. package/dist/runtime/entity/models/MasterPlayerModels.js +0 -2573
  244. package/dist/runtime/entity/models/MasterPlayerRequestModels.js +0 -2228
  245. package/dist/runtime/entity/models/MasterPlayerResponseModels.js +0 -607
  246. package/dist/runtime/entity/models/MultiplayerModels.js +0 -404
  247. package/dist/runtime/entity/models/MultiplayerRequestModels.js +0 -268
  248. package/dist/runtime/entity/models/MultiplayerResponseModels.js +0 -75
  249. package/dist/runtime/entity/models/StoreInventoryModels.js +0 -797
  250. package/dist/runtime/entity/models/StoreInventoryRequestModels.js +0 -372
  251. package/dist/runtime/entity/models/StoreInventoryResponseModels.js +0 -103
  252. package/dist/runtime/entity/request/CustomOperationRequest.js +0 -24
  253. package/dist/runtime/entity/response/CustomOperationResponse.js +0 -29
  254. package/dist/runtime/entity/response/GetAuthInfoResponse.js +0 -2
  255. package/dist/runtime/entity/response/HealthCheckResponse.js +0 -2
  256. package/dist/runtime/entity/response/UploadFileResponse.js +0 -2
  257. package/dist/runtime/helper/CodeHelper.js +0 -63
  258. package/dist/runtime/helper/ConverterService.js +0 -275
  259. package/dist/runtime/helper/EnumUtility.js +0 -33
  260. package/dist/runtime/helper/GNSupport.js +0 -47
  261. package/dist/runtime/helper/GNUtils.js +0 -72
  262. package/dist/runtime/helper/MessagePackConverterService.js +0 -9
  263. package/dist/runtime/helper/OperationHelper.js +0 -24
  264. package/dist/runtime/helper/StorageService.js +0 -62
  265. package/dist/runtime/logger/GNDebug.js +0 -29
  266. package/dist/runtime/networking/AuthenticateStatus.js +0 -14
  267. package/dist/runtime/networking/IPeer.js +0 -1
  268. package/dist/runtime/networking/NetworkingPeer.js +0 -210
  269. package/dist/runtime/networking/OperationPending.js +0 -53
  270. package/dist/runtime/networking/PeerBase.js +0 -161
  271. package/dist/runtime/networking/handler/IServerEventHandler.js +0 -13
  272. package/dist/runtime/networking/handler/OnCharacterPlayerFriendUpdateEventHandler.js +0 -39
  273. package/dist/runtime/networking/handler/OnCharacterPlayerGroupUpdateEventHandler.js +0 -39
  274. package/dist/runtime/networking/handler/OnGamePlayerFriendUpdateEventHandler.js +0 -39
  275. package/dist/runtime/networking/handler/OnGamePlayerGroupUpdateEventHandler.js +0 -39
  276. package/dist/runtime/networking/handler/OnGroupMemberUpdateEventHandler.js +0 -35
  277. package/dist/runtime/networking/handler/OnGroupMessageUpdateEventHandler.js +0 -43
  278. package/dist/runtime/networking/http/HttpPeer.js +0 -123
  279. package/dist/runtime/networking/http/NetworkingHttpPeerBase.js +0 -9
  280. package/dist/runtime/networking/http/NetworkingPeerAxiosRequest.js +0 -179
  281. package/dist/runtime/networking/socket/NetworkingPeerSocketIOClient.js +0 -130
  282. package/dist/runtime/networking/socket/NetworkingSocketPeerBase.js +0 -165
  283. package/dist/runtime/networking/socket/SocketPeer.js +0 -115
  284. package/dist/runtime/typescript/ServiceUpdate.js +0 -22
  285. package/docs/COCOS_CREATOR_INTEGRATION.md +0 -116
  286. package/examples/cocos-creator/GearNExample.ts.txt +0 -176
  287. package/srcSwift/Package.swift +0 -32
  288. package/srcSwift/Sources/GearN/runtime/GNNetwork.swift +0 -530
  289. package/srcSwift/Sources/GearN/runtime/GNNetworkAuthenticateApi.swift +0 -178
  290. package/srcSwift/Sources/GearN/runtime/GNNetworkCharacterPlayerApi.swift +0 -1162
  291. package/srcSwift/Sources/GearN/runtime/GNNetworkCloudScriptApi.swift +0 -154
  292. package/srcSwift/Sources/GearN/runtime/GNNetworkContentApi.swift +0 -208
  293. package/srcSwift/Sources/GearN/runtime/GNNetworkDashboardApi.swift +0 -240
  294. package/srcSwift/Sources/GearN/runtime/GNNetworkGamePlayerApi.swift +0 -1369
  295. package/srcSwift/Sources/GearN/runtime/GNNetworkGroupApi.swift +0 -1100
  296. package/srcSwift/Sources/GearN/runtime/GNNetworkInventoryApi.swift +0 -937
  297. package/srcSwift/Sources/GearN/runtime/GNNetworkMasterPlayerApi.swift +0 -2323
  298. package/srcSwift/Sources/GearN/runtime/GNNetworkMultiplayerApi.swift +0 -298
  299. package/srcSwift/Sources/GearN/runtime/GNNetworkStoreInventoryApi.swift +0 -397
  300. package/srcSwift/Sources/GearN/runtime/common/Action0.swift +0 -3
  301. package/srcSwift/Sources/GearN/runtime/common/Action1.swift +0 -3
  302. package/srcSwift/Sources/GearN/runtime/common/Action2.swift +0 -3
  303. package/srcSwift/Sources/GearN/runtime/common/Action3.swift +0 -3
  304. package/srcSwift/Sources/GearN/runtime/common/Action4.swift +0 -3
  305. package/srcSwift/Sources/GearN/runtime/common/GNArray.swift +0 -204
  306. package/srcSwift/Sources/GearN/runtime/common/GNData.swift +0 -108
  307. package/srcSwift/Sources/GearN/runtime/common/GNHashtable.swift +0 -200
  308. package/srcSwift/Sources/GearN/runtime/config/GNServerSettings.swift +0 -95
  309. package/srcSwift/Sources/GearN/runtime/constant/Commands.swift +0 -28
  310. package/srcSwift/Sources/GearN/runtime/constant/EventCode.swift +0 -10
  311. package/srcSwift/Sources/GearN/runtime/constant/OperationCode.swift +0 -252
  312. package/srcSwift/Sources/GearN/runtime/constant/ReturnCode.swift +0 -19
  313. package/srcSwift/Sources/GearN/runtime/constant/enumType/ExecuteResponseStatus.swift +0 -9
  314. package/srcSwift/Sources/GearN/runtime/constant/enumType/FriendStatus.swift +0 -8
  315. package/srcSwift/Sources/GearN/runtime/constant/enumType/GoogleLoginType.swift +0 -6
  316. package/srcSwift/Sources/GearN/runtime/constant/enumType/GroupStatus.swift +0 -8
  317. package/srcSwift/Sources/GearN/runtime/constant/enumType/InvalidMemberType.swift +0 -19
  318. package/srcSwift/Sources/GearN/runtime/constant/enumType/ItemType.swift +0 -6
  319. package/srcSwift/Sources/GearN/runtime/constant/enumType/MatchmakingMemberStatus.swift +0 -7
  320. package/srcSwift/Sources/GearN/runtime/constant/enumType/MatchmakingTicketStatus.swift +0 -9
  321. package/srcSwift/Sources/GearN/runtime/constant/enumType/OwnerType.swift +0 -10
  322. package/srcSwift/Sources/GearN/runtime/constant/enumType/PermissionDataItem.swift +0 -6
  323. package/srcSwift/Sources/GearN/runtime/constant/enumType/PushPlatformType.swift +0 -6
  324. package/srcSwift/Sources/GearN/runtime/constant/enumType/RequestRole.swift +0 -7
  325. package/srcSwift/Sources/GearN/runtime/constant/enumType/RequestType.swift +0 -16
  326. package/srcSwift/Sources/GearN/runtime/constant/enumType/StoreItemType.swift +0 -6
  327. package/srcSwift/Sources/GearN/runtime/constant/enumType/StoreReceiveType.swift +0 -9
  328. package/srcSwift/Sources/GearN/runtime/constant/errorCode/ErrorCode.swift +0 -58
  329. package/srcSwift/Sources/GearN/runtime/constant/parameterCode/ParameterCode.swift +0 -672
  330. package/srcSwift/Sources/GearN/runtime/entity/DataMember.swift +0 -196
  331. package/srcSwift/Sources/GearN/runtime/entity/GNMetadata.swift +0 -9
  332. package/srcSwift/Sources/GearN/runtime/entity/InvalidMember.swift +0 -11
  333. package/srcSwift/Sources/GearN/runtime/entity/OperationEvent.swift +0 -38
  334. package/srcSwift/Sources/GearN/runtime/entity/OperationHelper.swift +0 -28
  335. package/srcSwift/Sources/GearN/runtime/entity/OperationRequest.swift +0 -62
  336. package/srcSwift/Sources/GearN/runtime/entity/OperationResponse.swift +0 -98
  337. package/srcSwift/Sources/GearN/runtime/entity/models/AuthenticateModels.swift +0 -351
  338. package/srcSwift/Sources/GearN/runtime/entity/models/AuthenticateRequestModels.swift +0 -81
  339. package/srcSwift/Sources/GearN/runtime/entity/models/AuthenticateResponseModels.swift +0 -108
  340. package/srcSwift/Sources/GearN/runtime/entity/models/CharacterPlayerModels.swift +0 -1045
  341. package/srcSwift/Sources/GearN/runtime/entity/models/CharacterPlayerRequestModels.swift +0 -821
  342. package/srcSwift/Sources/GearN/runtime/entity/models/CharacterPlayerResponseModels.swift +0 -588
  343. package/srcSwift/Sources/GearN/runtime/entity/models/CloudScriptModels.swift +0 -187
  344. package/srcSwift/Sources/GearN/runtime/entity/models/CloudScriptRequestModels.swift +0 -84
  345. package/srcSwift/Sources/GearN/runtime/entity/models/CloudScriptResponseModels.swift +0 -59
  346. package/srcSwift/Sources/GearN/runtime/entity/models/ContentModels.swift +0 -195
  347. package/srcSwift/Sources/GearN/runtime/entity/models/ContentRequestModels.swift +0 -116
  348. package/srcSwift/Sources/GearN/runtime/entity/models/ContentResponseModels.swift +0 -81
  349. package/srcSwift/Sources/GearN/runtime/entity/models/DashboardModels.swift +0 -426
  350. package/srcSwift/Sources/GearN/runtime/entity/models/DashboardRequestModels.swift +0 -160
  351. package/srcSwift/Sources/GearN/runtime/entity/models/DashboardResponseModels.swift +0 -82
  352. package/srcSwift/Sources/GearN/runtime/entity/models/GamePlayerModels.swift +0 -1334
  353. package/srcSwift/Sources/GearN/runtime/entity/models/GamePlayerRequestModels.swift +0 -643
  354. package/srcSwift/Sources/GearN/runtime/entity/models/GamePlayerResponseModels.swift +0 -213
  355. package/srcSwift/Sources/GearN/runtime/entity/models/GenericModels.swift +0 -171
  356. package/srcSwift/Sources/GearN/runtime/entity/models/GroupModels.swift +0 -850
  357. package/srcSwift/Sources/GearN/runtime/entity/models/GroupRequestModels.swift +0 -485
  358. package/srcSwift/Sources/GearN/runtime/entity/models/GroupResponseModels.swift +0 -165
  359. package/srcSwift/Sources/GearN/runtime/entity/models/InventoryModels.swift +0 -679
  360. package/srcSwift/Sources/GearN/runtime/entity/models/InventoryRequestModels.swift +0 -413
  361. package/srcSwift/Sources/GearN/runtime/entity/models/InventoryResponseModels.swift +0 -141
  362. package/srcSwift/Sources/GearN/runtime/entity/models/MasterPlayerModels.swift +0 -378
  363. package/srcSwift/Sources/GearN/runtime/entity/models/MasterPlayerRequestModels.swift +0 -147
  364. package/srcSwift/Sources/GearN/runtime/entity/models/MasterPlayerResponseModels.swift +0 -318
  365. package/srcSwift/Sources/GearN/runtime/entity/models/MultiplayerModels.swift +0 -319
  366. package/srcSwift/Sources/GearN/runtime/entity/models/MultiplayerRequestModels.swift +0 -125
  367. package/srcSwift/Sources/GearN/runtime/entity/models/MultiplayerResponseModels.swift +0 -45
  368. package/srcSwift/Sources/GearN/runtime/entity/models/StoreInventoryModels.swift +0 -633
  369. package/srcSwift/Sources/GearN/runtime/entity/models/StoreInventoryRequestModels.swift +0 -173
  370. package/srcSwift/Sources/GearN/runtime/entity/models/StoreInventoryResponseModels.swift +0 -61
  371. package/srcSwift/Sources/GearN/runtime/entity/request/CustomOperationRequest.swift +0 -42
  372. package/srcSwift/Sources/GearN/runtime/entity/response/CustomOperationResponse.swift +0 -49
  373. package/srcSwift/Sources/GearN/runtime/entity/response/GetAuthInfoResponse.swift +0 -43
  374. package/srcSwift/Sources/GearN/runtime/entity/response/HealthCheckResponse.swift +0 -86
  375. package/srcSwift/Sources/GearN/runtime/entity/response/UploadFileResponse.swift +0 -15
  376. package/srcSwift/Sources/GearN/runtime/helper/CodeHelper.swift +0 -107
  377. package/srcSwift/Sources/GearN/runtime/helper/ConverterService.swift +0 -98
  378. package/srcSwift/Sources/GearN/runtime/helper/EnumUtility.swift +0 -34
  379. package/srcSwift/Sources/GearN/runtime/helper/GNSupport.swift +0 -41
  380. package/srcSwift/Sources/GearN/runtime/helper/GNUtils.swift +0 -66
  381. package/srcSwift/Sources/GearN/runtime/helper/MessagePackConverterService.swift +0 -21
  382. package/srcSwift/Sources/GearN/runtime/helper/StorageService.swift +0 -29
  383. package/srcSwift/Sources/GearN/runtime/logger/GNDebug.swift +0 -33
  384. package/srcSwift/Sources/GearN/runtime/networking/AuthenticateStatus.swift +0 -24
  385. package/srcSwift/Sources/GearN/runtime/networking/IPeer.swift +0 -8
  386. package/srcSwift/Sources/GearN/runtime/networking/NetworkingPeer.swift +0 -368
  387. package/srcSwift/Sources/GearN/runtime/networking/OperationPending.swift +0 -81
  388. package/srcSwift/Sources/GearN/runtime/networking/PeerBase.swift +0 -228
  389. package/srcSwift/Sources/GearN/runtime/networking/handler/IServerEventHandler.swift +0 -20
  390. package/srcSwift/Sources/GearN/runtime/networking/http/HttpPeer.swift +0 -226
  391. package/srcSwift/Sources/GearN/runtime/networking/http/HttpTypes.swift +0 -24
  392. package/srcSwift/Sources/GearN/runtime/networking/http/NetworkingHttpPeerBase.swift +0 -13
  393. package/srcSwift/Sources/GearN/runtime/networking/http/NetworkingPeerUrlSession.swift +0 -125
  394. package/srcSwift/Sources/GearN/runtime/networking/request/NetRequest.swift +0 -19
  395. package/srcSwift/Sources/GearN/runtime/networking/response/NetResponse.swift +0 -13
  396. package/srcSwift/Sources/GearN/runtime/networking/socket/NetworkingPeerSocketIOClient.swift +0 -244
  397. package/srcSwift/Sources/GearN/runtime/networking/socket/NetworkingSocketPeerBase.swift +0 -59
  398. package/srcSwift/Sources/GearN/runtime/networking/socket/SocketPeer.swift +0 -136
  399. package/tsconfig-build.cocos.json +0 -31
  400. 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 |