@xmobitea/gn-typescript-client 2.6.12 → 2.6.13

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 (127) hide show
  1. package/dist/gearn.js.client.js +183 -57
  2. package/dist/gearn.js.client.min.js +1 -1
  3. package/dist/index.d.ts +2 -2
  4. package/dist/index.js +183 -57
  5. package/dist/runtime/GNNetwork.d.ts +1 -1
  6. package/dist/runtime/helper/GNSupport.d.ts +20 -0
  7. package/dist/runtime/{entity → helper}/OperationHelper.d.ts +1 -1
  8. package/dist/runtime/helper/StorageService.d.ts +18 -0
  9. package/dist/runtime/networking/NetworkingPeer.d.ts +1 -1
  10. package/dist/runtime/typescript/ServiceUpdate.d.ts +2 -0
  11. package/docs/COCOS_CREATOR_INTEGRATION.md +116 -0
  12. package/examples/cocos-creator/GearNExample.ts.txt +176 -0
  13. package/package.json +3 -2
  14. package/srcSwift/Package.swift +32 -0
  15. package/srcSwift/Sources/GearN/runtime/GNNetwork.swift +530 -0
  16. package/srcSwift/Sources/GearN/runtime/GNNetworkAuthenticateApi.swift +178 -0
  17. package/srcSwift/Sources/GearN/runtime/GNNetworkCharacterPlayerApi.swift +1162 -0
  18. package/srcSwift/Sources/GearN/runtime/GNNetworkCloudScriptApi.swift +154 -0
  19. package/srcSwift/Sources/GearN/runtime/GNNetworkContentApi.swift +208 -0
  20. package/srcSwift/Sources/GearN/runtime/GNNetworkDashboardApi.swift +240 -0
  21. package/srcSwift/Sources/GearN/runtime/GNNetworkGamePlayerApi.swift +1369 -0
  22. package/srcSwift/Sources/GearN/runtime/GNNetworkGroupApi.swift +1100 -0
  23. package/srcSwift/Sources/GearN/runtime/GNNetworkInventoryApi.swift +937 -0
  24. package/srcSwift/Sources/GearN/runtime/GNNetworkMasterPlayerApi.swift +2323 -0
  25. package/srcSwift/Sources/GearN/runtime/GNNetworkMultiplayerApi.swift +298 -0
  26. package/srcSwift/Sources/GearN/runtime/GNNetworkStoreInventoryApi.swift +397 -0
  27. package/srcSwift/Sources/GearN/runtime/common/Action0.swift +3 -0
  28. package/srcSwift/Sources/GearN/runtime/common/Action1.swift +3 -0
  29. package/srcSwift/Sources/GearN/runtime/common/Action2.swift +3 -0
  30. package/srcSwift/Sources/GearN/runtime/common/Action3.swift +3 -0
  31. package/srcSwift/Sources/GearN/runtime/common/Action4.swift +3 -0
  32. package/srcSwift/Sources/GearN/runtime/common/GNArray.swift +204 -0
  33. package/srcSwift/Sources/GearN/runtime/common/GNData.swift +108 -0
  34. package/srcSwift/Sources/GearN/runtime/common/GNHashtable.swift +200 -0
  35. package/srcSwift/Sources/GearN/runtime/config/GNServerSettings.swift +95 -0
  36. package/srcSwift/Sources/GearN/runtime/constant/Commands.swift +28 -0
  37. package/srcSwift/Sources/GearN/runtime/constant/EventCode.swift +10 -0
  38. package/srcSwift/Sources/GearN/runtime/constant/OperationCode.swift +252 -0
  39. package/srcSwift/Sources/GearN/runtime/constant/ReturnCode.swift +19 -0
  40. package/srcSwift/Sources/GearN/runtime/constant/enumType/ExecuteResponseStatus.swift +9 -0
  41. package/srcSwift/Sources/GearN/runtime/constant/enumType/FriendStatus.swift +8 -0
  42. package/srcSwift/Sources/GearN/runtime/constant/enumType/GoogleLoginType.swift +6 -0
  43. package/srcSwift/Sources/GearN/runtime/constant/enumType/GroupStatus.swift +8 -0
  44. package/srcSwift/Sources/GearN/runtime/constant/enumType/InvalidMemberType.swift +19 -0
  45. package/srcSwift/Sources/GearN/runtime/constant/enumType/ItemType.swift +6 -0
  46. package/srcSwift/Sources/GearN/runtime/constant/enumType/MatchmakingMemberStatus.swift +7 -0
  47. package/srcSwift/Sources/GearN/runtime/constant/enumType/MatchmakingTicketStatus.swift +9 -0
  48. package/srcSwift/Sources/GearN/runtime/constant/enumType/OwnerType.swift +10 -0
  49. package/srcSwift/Sources/GearN/runtime/constant/enumType/PermissionDataItem.swift +6 -0
  50. package/srcSwift/Sources/GearN/runtime/constant/enumType/PushPlatformType.swift +6 -0
  51. package/srcSwift/Sources/GearN/runtime/constant/enumType/RequestRole.swift +7 -0
  52. package/srcSwift/Sources/GearN/runtime/constant/enumType/RequestType.swift +16 -0
  53. package/srcSwift/Sources/GearN/runtime/constant/enumType/StoreItemType.swift +6 -0
  54. package/srcSwift/Sources/GearN/runtime/constant/enumType/StoreReceiveType.swift +9 -0
  55. package/srcSwift/Sources/GearN/runtime/constant/errorCode/ErrorCode.swift +58 -0
  56. package/srcSwift/Sources/GearN/runtime/constant/parameterCode/ParameterCode.swift +672 -0
  57. package/srcSwift/Sources/GearN/runtime/entity/DataMember.swift +196 -0
  58. package/srcSwift/Sources/GearN/runtime/entity/GNMetadata.swift +9 -0
  59. package/srcSwift/Sources/GearN/runtime/entity/InvalidMember.swift +11 -0
  60. package/srcSwift/Sources/GearN/runtime/entity/OperationEvent.swift +38 -0
  61. package/srcSwift/Sources/GearN/runtime/entity/OperationHelper.swift +28 -0
  62. package/srcSwift/Sources/GearN/runtime/entity/OperationRequest.swift +62 -0
  63. package/srcSwift/Sources/GearN/runtime/entity/OperationResponse.swift +98 -0
  64. package/srcSwift/Sources/GearN/runtime/entity/models/AuthenticateModels.swift +351 -0
  65. package/srcSwift/Sources/GearN/runtime/entity/models/AuthenticateRequestModels.swift +81 -0
  66. package/srcSwift/Sources/GearN/runtime/entity/models/AuthenticateResponseModels.swift +108 -0
  67. package/srcSwift/Sources/GearN/runtime/entity/models/CharacterPlayerModels.swift +1045 -0
  68. package/srcSwift/Sources/GearN/runtime/entity/models/CharacterPlayerRequestModels.swift +821 -0
  69. package/srcSwift/Sources/GearN/runtime/entity/models/CharacterPlayerResponseModels.swift +588 -0
  70. package/srcSwift/Sources/GearN/runtime/entity/models/CloudScriptModels.swift +187 -0
  71. package/srcSwift/Sources/GearN/runtime/entity/models/CloudScriptRequestModels.swift +84 -0
  72. package/srcSwift/Sources/GearN/runtime/entity/models/CloudScriptResponseModels.swift +59 -0
  73. package/srcSwift/Sources/GearN/runtime/entity/models/ContentModels.swift +195 -0
  74. package/srcSwift/Sources/GearN/runtime/entity/models/ContentRequestModels.swift +116 -0
  75. package/srcSwift/Sources/GearN/runtime/entity/models/ContentResponseModels.swift +81 -0
  76. package/srcSwift/Sources/GearN/runtime/entity/models/DashboardModels.swift +426 -0
  77. package/srcSwift/Sources/GearN/runtime/entity/models/DashboardRequestModels.swift +160 -0
  78. package/srcSwift/Sources/GearN/runtime/entity/models/DashboardResponseModels.swift +82 -0
  79. package/srcSwift/Sources/GearN/runtime/entity/models/GamePlayerModels.swift +1334 -0
  80. package/srcSwift/Sources/GearN/runtime/entity/models/GamePlayerRequestModels.swift +643 -0
  81. package/srcSwift/Sources/GearN/runtime/entity/models/GamePlayerResponseModels.swift +213 -0
  82. package/srcSwift/Sources/GearN/runtime/entity/models/GenericModels.swift +171 -0
  83. package/srcSwift/Sources/GearN/runtime/entity/models/GroupModels.swift +850 -0
  84. package/srcSwift/Sources/GearN/runtime/entity/models/GroupRequestModels.swift +485 -0
  85. package/srcSwift/Sources/GearN/runtime/entity/models/GroupResponseModels.swift +165 -0
  86. package/srcSwift/Sources/GearN/runtime/entity/models/InventoryModels.swift +679 -0
  87. package/srcSwift/Sources/GearN/runtime/entity/models/InventoryRequestModels.swift +413 -0
  88. package/srcSwift/Sources/GearN/runtime/entity/models/InventoryResponseModels.swift +141 -0
  89. package/srcSwift/Sources/GearN/runtime/entity/models/MasterPlayerModels.swift +378 -0
  90. package/srcSwift/Sources/GearN/runtime/entity/models/MasterPlayerRequestModels.swift +147 -0
  91. package/srcSwift/Sources/GearN/runtime/entity/models/MasterPlayerResponseModels.swift +318 -0
  92. package/srcSwift/Sources/GearN/runtime/entity/models/MultiplayerModels.swift +319 -0
  93. package/srcSwift/Sources/GearN/runtime/entity/models/MultiplayerRequestModels.swift +125 -0
  94. package/srcSwift/Sources/GearN/runtime/entity/models/MultiplayerResponseModels.swift +45 -0
  95. package/srcSwift/Sources/GearN/runtime/entity/models/StoreInventoryModels.swift +633 -0
  96. package/srcSwift/Sources/GearN/runtime/entity/models/StoreInventoryRequestModels.swift +173 -0
  97. package/srcSwift/Sources/GearN/runtime/entity/models/StoreInventoryResponseModels.swift +61 -0
  98. package/srcSwift/Sources/GearN/runtime/entity/request/CustomOperationRequest.swift +42 -0
  99. package/srcSwift/Sources/GearN/runtime/entity/response/CustomOperationResponse.swift +49 -0
  100. package/srcSwift/Sources/GearN/runtime/entity/response/GetAuthInfoResponse.swift +43 -0
  101. package/srcSwift/Sources/GearN/runtime/entity/response/HealthCheckResponse.swift +86 -0
  102. package/srcSwift/Sources/GearN/runtime/entity/response/UploadFileResponse.swift +15 -0
  103. package/srcSwift/Sources/GearN/runtime/helper/CodeHelper.swift +107 -0
  104. package/srcSwift/Sources/GearN/runtime/helper/ConverterService.swift +98 -0
  105. package/srcSwift/Sources/GearN/runtime/helper/EnumUtility.swift +34 -0
  106. package/srcSwift/Sources/GearN/runtime/helper/GNSupport.swift +41 -0
  107. package/srcSwift/Sources/GearN/runtime/helper/GNUtils.swift +66 -0
  108. package/srcSwift/Sources/GearN/runtime/helper/MessagePackConverterService.swift +21 -0
  109. package/srcSwift/Sources/GearN/runtime/helper/StorageService.swift +29 -0
  110. package/srcSwift/Sources/GearN/runtime/logger/GNDebug.swift +33 -0
  111. package/srcSwift/Sources/GearN/runtime/networking/AuthenticateStatus.swift +24 -0
  112. package/srcSwift/Sources/GearN/runtime/networking/IPeer.swift +8 -0
  113. package/srcSwift/Sources/GearN/runtime/networking/NetworkingPeer.swift +368 -0
  114. package/srcSwift/Sources/GearN/runtime/networking/OperationPending.swift +81 -0
  115. package/srcSwift/Sources/GearN/runtime/networking/PeerBase.swift +228 -0
  116. package/srcSwift/Sources/GearN/runtime/networking/handler/IServerEventHandler.swift +20 -0
  117. package/srcSwift/Sources/GearN/runtime/networking/http/HttpPeer.swift +226 -0
  118. package/srcSwift/Sources/GearN/runtime/networking/http/HttpTypes.swift +24 -0
  119. package/srcSwift/Sources/GearN/runtime/networking/http/NetworkingHttpPeerBase.swift +13 -0
  120. package/srcSwift/Sources/GearN/runtime/networking/http/NetworkingPeerUrlSession.swift +125 -0
  121. package/srcSwift/Sources/GearN/runtime/networking/request/NetRequest.swift +19 -0
  122. package/srcSwift/Sources/GearN/runtime/networking/response/NetResponse.swift +13 -0
  123. package/srcSwift/Sources/GearN/runtime/networking/socket/NetworkingPeerSocketIOClient.swift +244 -0
  124. package/srcSwift/Sources/GearN/runtime/networking/socket/NetworkingSocketPeerBase.swift +59 -0
  125. package/srcSwift/Sources/GearN/runtime/networking/socket/SocketPeer.swift +136 -0
  126. package/tsconfig-build.cocos.json +31 -0
  127. package/webpack.config.cocos.mjs +78 -0
@@ -0,0 +1,81 @@
1
+ import Foundation
2
+
3
+ public class OperationPending {
4
+ private var operationRequest: OperationRequest
5
+ private var requestType: RequestType
6
+ private var role: RequestRole
7
+ private var authToken: String
8
+ private var secretKey: String
9
+ private var gameId: String
10
+ private var customTags: GNHashtable?
11
+ private var onOperationResponse: Action1<OperationResponse>?
12
+ private var timeout: Double
13
+
14
+ private var firstSend: Double = 0
15
+ private var secondsSend: Double = 0
16
+
17
+ public init(requestType: RequestType, role: RequestRole, operationRequest: OperationRequest, onOperationResponse: Action1<OperationResponse>?, authToken: String, secretKey: String, customTags: GNHashtable?, gameId: String) {
18
+ self.operationRequest = operationRequest
19
+ self.onOperationResponse = onOperationResponse
20
+
21
+ self.timeout = Date().timeIntervalSince1970 + Double(OperationRequest.defaultTimeOut)
22
+ self.firstSend = 0
23
+ self.secondsSend = 0
24
+
25
+ self.requestType = requestType
26
+ self.role = role
27
+ self.authToken = authToken
28
+ self.secretKey = secretKey
29
+ self.gameId = gameId
30
+ self.customTags = customTags
31
+ }
32
+
33
+ public func getRequestType() -> RequestType {
34
+ return self.requestType
35
+ }
36
+
37
+ public func getRole() -> RequestRole {
38
+ return self.role
39
+ }
40
+
41
+ public func getAuthToken() -> String {
42
+ return self.authToken
43
+ }
44
+
45
+ public func getSecretKey() -> String {
46
+ return self.secretKey
47
+ }
48
+
49
+ public func getGameId() -> String {
50
+ return self.gameId
51
+ }
52
+
53
+ public func getCustomTags() -> GNHashtable? {
54
+ return self.customTags
55
+ }
56
+
57
+ public func onSend() {
58
+ self.firstSend = Date().timeIntervalSince1970
59
+ self.timeout = self.firstSend + Double(self.operationRequest.getTimeout())
60
+ }
61
+
62
+ public func onRecv() {
63
+ self.secondsSend = Date().timeIntervalSince1970
64
+ }
65
+
66
+ public func getExecuteTimerInMs() -> Double {
67
+ return (self.secondsSend - self.firstSend)
68
+ }
69
+
70
+ public func isTimeout() -> Bool {
71
+ return self.timeout < Date().timeIntervalSince1970
72
+ }
73
+
74
+ public func getOperationRequest() -> OperationRequest {
75
+ return self.operationRequest
76
+ }
77
+
78
+ public func getCallback() -> Action1<OperationResponse>? {
79
+ return self.onOperationResponse
80
+ }
81
+ }
@@ -0,0 +1,228 @@
1
+ import Foundation
2
+
3
+ public class PeerBase: IPeer {
4
+ internal var operationPendingQueue: [OperationPending] = []
5
+ internal var operationWaitingResponseDict: [Int: OperationPending] = [:]
6
+
7
+ private static var requestId: Int = 0
8
+
9
+ private var perMsgTimer: Double = 0
10
+ private var nextSendMsgTimer: Double = 0
11
+ private var checkTimeoutOperationPending: Double = 0
12
+
13
+ public var ping: Double = -1
14
+ private var pingLst: [Double] = []
15
+
16
+ internal var isUse: Bool = false
17
+
18
+ protected func getSendRate() -> Double {
19
+ return (1000 / self.perMsgTimer)
20
+ }
21
+
22
+ protected func setSendRate(sendRate: Int) {
23
+ self.perMsgTimer = 1000 / Double(sendRate) / 1000
24
+ }
25
+
26
+ public init() {
27
+ // Swift classes need init
28
+ }
29
+
30
+ public func initPeer() {
31
+ self.operationWaitingResponseDict = [:]
32
+ self.operationPendingQueue = []
33
+ self.pingLst = []
34
+
35
+ self.initSendRate()
36
+ self.initGNSocketObject()
37
+ }
38
+
39
+ private func initSendRate() {
40
+ if let gnServerSettings = GNNetwork.getGNServerSettings() {
41
+ self.setSendRate(sendRate: gnServerSettings.getSendRate())
42
+ } else {
43
+ // Fatal error or log? TS throws error
44
+ fatalError("Null GN Server Settings, please find it now")
45
+ }
46
+ }
47
+
48
+ // Abstract method workarounds
49
+ open func initGNSocketObject() {
50
+ fatalError("Must be implemented by subclass")
51
+ }
52
+
53
+ public func enqueue(requestType: RequestType, role: RequestRole, operationRequest: OperationRequest, onOperationResponse: Action1<OperationResponse>?, authToken: String?, secretKey: String?, customTags: GNHashtable?, gameId: String?) {
54
+ if !self.isUse {
55
+ GNDebug.logError("[GearN] Server Settings dont setup to use this to send operation request.")
56
+ return
57
+ }
58
+
59
+ // Unwrap logic for optionals to match TS defaults or expectations
60
+ let auth = authToken ?? ""
61
+ let secret = secretKey ?? ""
62
+ let game = gameId ?? ""
63
+
64
+ if operationRequest.getRequestId() != -1 {
65
+ PeerBase.requestId += 1
66
+ let _ = operationRequest.setRequestId(requestId: PeerBase.requestId)
67
+ }
68
+
69
+ let operationPending = OperationPending(requestType: requestType, role: role, operationRequest: operationRequest, onOperationResponse: onOperationResponse, authToken: auth, secretKey: secret, customTags: customTags, gameId: game)
70
+ self.operationPendingQueue.append(operationPending)
71
+
72
+ self.onEnqueue(operationPending: operationPending)
73
+ }
74
+
75
+ open func onEnqueue(operationPending: OperationPending) {
76
+ fatalError("Must be implemented by subclass")
77
+ }
78
+
79
+ public func isUsing() -> Bool {
80
+ return self.isUse
81
+ }
82
+
83
+ public func service() {
84
+ if !self.isUse { return }
85
+
86
+ let nowSecond = Date().timeIntervalSince1970
87
+ if self.checkTimeoutOperationPending < nowSecond {
88
+ self.checkTimeoutOperationPending = nowSecond + 0.1
89
+
90
+ if !self.operationWaitingResponseDict.isEmpty {
91
+ var gnHashtableLst: [GNHashtable] = []
92
+
93
+ for (operationPendingKey, operationPending) in self.operationWaitingResponseDict {
94
+ if operationPending.isTimeout() {
95
+ let gnHashtable = GNHashtable()
96
+
97
+ gnHashtable.add(k: ParameterCode.ReturnCode, value: ReturnCode.OperationTimeout)
98
+ gnHashtable.add(k: ParameterCode.Parameters, value: nil)
99
+ gnHashtable.add(k: ParameterCode.ResponseId, value: operationPending.getOperationRequest().getRequestId())
100
+
101
+ gnHashtableLst.append(gnHashtable)
102
+ }
103
+ }
104
+
105
+ if !gnHashtableLst.isEmpty {
106
+ gnHashtableLst.forEach { gnHashtable in
107
+ self.onResponseHandler(obj: gnHashtable)
108
+ }
109
+ }
110
+ }
111
+ }
112
+
113
+ if self.nextSendMsgTimer < nowSecond {
114
+ if !self.operationPendingQueue.isEmpty {
115
+ self.nextSendMsgTimer = nowSecond + self.perMsgTimer
116
+
117
+ let operationPending = self.operationPendingQueue.removeFirst()
118
+
119
+ self.send(operationPending: operationPending)
120
+ }
121
+ }
122
+ }
123
+
124
+ internal func onResponseHandler(obj: GNHashtable) {
125
+ guard let responseId = obj.getNumber(ParameterCode.ResponseId) else { return }
126
+
127
+ // TS key is number, Dictionary Int
128
+ let key = Int(responseId)
129
+
130
+ if let operationPending = self.operationWaitingResponseDict[key] {
131
+ operationPending.onRecv()
132
+
133
+ self.operationWaitingResponseDict.removeValue(forKey: key)
134
+
135
+ let returnCode = Int(obj.getNumber(ParameterCode.ReturnCode) ?? Double(ReturnCode.UnknownError))
136
+
137
+ let parameters = obj.getGNHashtable(ParameterCode.Parameters) ?? GNHashtable()
138
+ let debugMessage = obj.getString(ParameterCode.DebugMessage) ?? ""
139
+ let invalidRequestParameterArray = obj.getGNArray(ParameterCode.InvalidRequestParameters)
140
+
141
+ let operationRequest = operationPending.getOperationRequest()
142
+ let operationResponse = OperationResponse(operationCode: operationRequest.getOperationCode(), responseId: operationRequest.getRequestId())
143
+
144
+ let _ = operationResponse.setReturnCode(returnCode: returnCode)
145
+ let _ = operationResponse.setDebugMessage(debugMessage: debugMessage)
146
+ let _ = operationResponse.setParameters(parameters: parameters)
147
+
148
+ if let invalidRequestParameterArray = invalidRequestParameterArray {
149
+ var invalidMembers: [InvalidMember] = []
150
+ for i in 0..<invalidRequestParameterArray.count() {
151
+ if let arrChild = invalidRequestParameterArray.getGNArray(i) {
152
+ let code = arrChild.getString(0) ?? ""
153
+ let typeInt = Int(arrChild.getNumber(1) ?? 0)
154
+ let type = InvalidMemberType(rawValue: typeInt) ?? .UnknownError
155
+ invalidMembers.append(InvalidMember(code: code, invalidMemberType: type))
156
+ }
157
+ }
158
+ let _ = operationResponse.setInvalidMembers(invalidMembers: invalidMembers)
159
+ }
160
+
161
+ if !operationResponse.hasError() {
162
+ self.addPing(value: operationPending.getExecuteTimerInMs())
163
+
164
+ // Update auth/userId/ts in GNNetwork/Storage
165
+ if parameters.containsKey(ParameterCode.AuthToken) {
166
+ if let authToken = parameters.getString(ParameterCode.AuthToken) {
167
+ GNNetwork.getAuthenticateStatus().setAuthToken(authToken: authToken)
168
+ StorageService.set(key: GNNetwork.AUTH_TOKEN_KEY, value: authToken)
169
+ }
170
+ }
171
+
172
+ if parameters.containsKey(ParameterCode.UserId) {
173
+ if let userId = parameters.getString(ParameterCode.UserId) {
174
+ GNNetwork.getAuthenticateStatus().setUserId(userId: userId)
175
+ StorageService.set(key: GNNetwork.USER_ID_KEY, value: userId)
176
+ }
177
+ }
178
+
179
+ if parameters.containsKey(ParameterCode.Ts) {
180
+ // TS: GNNetwork.peer.setServerTimeMilliseconds(...)
181
+ // Accessing GNNetwork.peer might be circular but Swift allows.
182
+ // Assuming GNNetwork has static peer access
183
+ let ts = parameters.getNumber(ParameterCode.Ts) ?? Double(Date().timeIntervalSince1970 * 1000)
184
+ GNNetwork.getPeer().setServerTimeMilliseconds(currentServerMilliseconds: ts)
185
+ }
186
+ }
187
+
188
+ GNDebug.log("[GN RECV] " + operationResponse.toString())
189
+
190
+ if let callback = operationPending.getCallback() {
191
+ callback(operationResponse)
192
+ }
193
+ } else {
194
+ GNDebug.logError("[GearN] OnResponseHandler, unavailable request id \(obj)")
195
+ }
196
+ }
197
+
198
+ internal func send(operationPending: OperationPending) {
199
+ operationPending.onSend()
200
+
201
+ let operationRequest = operationPending.getOperationRequest()
202
+
203
+ if operationRequest.getRequestId() != -1 {
204
+ if operationPending.getCallback() != nil {
205
+ self.operationWaitingResponseDict[operationRequest.getRequestId()] = operationPending
206
+ }
207
+ }
208
+ }
209
+
210
+ func addPing(value: Double) {
211
+ if self.pingLst.count > 10 {
212
+ self.pingLst.removeFirst()
213
+ }
214
+ self.pingLst.append(value / 2)
215
+
216
+ if !self.pingLst.isEmpty {
217
+ var total: Double = 0
218
+ for v in self.pingLst {
219
+ total += v
220
+ }
221
+
222
+ let average = total / Double(self.pingLst.count)
223
+ self.ping = (average * 1000)
224
+ } else {
225
+ self.ping = -1
226
+ }
227
+ }
228
+ }
@@ -0,0 +1,20 @@
1
+ import Foundation
2
+
3
+ public protocol IServerEventHandler {
4
+ init()
5
+ func getEventCode() -> String
6
+ func handle(operationEvent: OperationEvent)
7
+ }
8
+
9
+ public class ServerEventHandlerRegistry {
10
+ private static var implementations: [IServerEventHandler.Type] = []
11
+
12
+ public static func getImplementations() -> [IServerEventHandler.Type] {
13
+ return implementations
14
+ }
15
+
16
+ public static func registerEvent<T: IServerEventHandler>(ctor: T.Type) -> T.Type {
17
+ implementations.append(ctor)
18
+ return ctor
19
+ }
20
+ }
@@ -0,0 +1,226 @@
1
+ import Foundation
2
+
3
+ public class HttpPeer: PeerBase {
4
+ private var networkingHttpPeerBase: NetworkingHttpPeerBase!
5
+
6
+ private static let JSON_CHAR_KNOWN: Character = "{"
7
+
8
+ // Static API Strings
9
+ internal static let API_JSON: String = "api/json"
10
+ internal static let API_MSG_PACK: String = "api/msgpack"
11
+ internal static let UPLOAD_FILE: String = "upload/file"
12
+
13
+ // MARK: - GET Request for utility endpoints
14
+ public func getRequest(subUri: String, onResponse: @escaping (HttpAppResponse) -> Void) {
15
+ guard let settings = GNNetwork.getGNServerSettings() else {
16
+ let response = HttpAppResponse()
17
+ response.error = "No server settings"
18
+ onResponse(response)
19
+ return
20
+ }
21
+
22
+ let url = "\(settings.getHttpUrl())/\(subUri)"
23
+
24
+ sendRawRequest(url: url, method: "GET", body: nil) { data, response, error in
25
+ let httpResponse = HttpAppResponse()
26
+
27
+ if let error = error {
28
+ httpResponse.error = error.localizedDescription
29
+ } else if let httpUrlResponse = response as? HTTPURLResponse {
30
+ httpResponse.statusCode = httpUrlResponse.statusCode
31
+ if let data = data {
32
+ httpResponse.data = data
33
+ httpResponse.text = String(data: data, encoding: .utf8)
34
+ }
35
+ }
36
+
37
+ onResponse(httpResponse)
38
+ }
39
+ }
40
+
41
+ // MARK: - Upload File
42
+ public func uploadFile(fileId: String, content: Data, filename: String, mimetype: String, onResponse: @escaping (HttpAppResponse) -> Void) {
43
+ guard let settings = GNNetwork.getGNServerSettings() else {
44
+ let response = HttpAppResponse()
45
+ response.error = "No server settings"
46
+ onResponse(response)
47
+ return
48
+ }
49
+
50
+ let url = "\(settings.getHttpUrl())/\(HttpPeer.UPLOAD_FILE)"
51
+ let boundary = UUID().uuidString
52
+
53
+ var body = Data()
54
+
55
+ // Add file id field
56
+ body.append("--\(boundary)\r\n".data(using: .utf8)!)
57
+ body.append("Content-Disposition: form-data; name=\"fileId\"\r\n\r\n".data(using: .utf8)!)
58
+ body.append("\(fileId)\r\n".data(using: .utf8)!)
59
+
60
+ // Add file content
61
+ body.append("--\(boundary)\r\n".data(using: .utf8)!)
62
+ body.append("Content-Disposition: form-data; name=\"file\"; filename=\"\(filename)\"\r\n".data(using: .utf8)!)
63
+ body.append("Content-Type: \(mimetype)\r\n\r\n".data(using: .utf8)!)
64
+ body.append(content)
65
+ body.append("\r\n".data(using: .utf8)!)
66
+ body.append("--\(boundary)--\r\n".data(using: .utf8)!)
67
+
68
+ var headers: [String: String] = [:]
69
+ headers["Content-Type"] = "multipart/form-data; boundary=\(boundary)"
70
+
71
+ if let authStatus = GNNetwork.getAuthenticateStatus() {
72
+ headers["Authorization"] = "Bearer \(authStatus.getAuthToken())"
73
+ }
74
+
75
+ sendRawRequest(url: url, method: "POST", headers: headers, body: body) { data, response, error in
76
+ let httpResponse = HttpAppResponse()
77
+
78
+ if let error = error {
79
+ httpResponse.error = error.localizedDescription
80
+ } else if let httpUrlResponse = response as? HTTPURLResponse {
81
+ httpResponse.statusCode = httpUrlResponse.statusCode
82
+ if let data = data {
83
+ httpResponse.data = data
84
+ httpResponse.text = String(data: data, encoding: .utf8)
85
+ }
86
+ }
87
+
88
+ onResponse(httpResponse)
89
+ }
90
+ }
91
+
92
+
93
+ public override func initGNSocketObject() {
94
+ guard let gnServerSettings = GNNetwork.getGNServerSettings() else {
95
+ fatalError("Where is GN Server Settings")
96
+ }
97
+
98
+ self.isUse = gnServerSettings.isUseHttp()
99
+
100
+ self.networkingHttpPeerBase = NetworkingPeerUrlSession()
101
+
102
+ let httpUrl = gnServerSettings.getHttpUrl()
103
+ let userAgent = "GN-swift-" + GNNetwork.getPlatform() + "@" + GNNetwork.getClientSdkVersion()
104
+
105
+ self.networkingHttpPeerBase.initPeer(httpUrl: httpUrl, userAgent: userAgent)
106
+ self.networkingHttpPeerBase.setUseReverseProxy(useReverseProxy: gnServerSettings.getUseReverseProxy())
107
+ }
108
+
109
+ public override func send(operationPending: OperationPending) {
110
+ guard let gnServerSettings = GNNetwork.getGNServerSettings() else { return }
111
+
112
+ let operationRequest = operationPending.getOperationRequest()
113
+
114
+ if operationRequest.getTimeout() == OperationRequest.defaultTimeOut {
115
+ let _ = operationRequest.setTimeout(timeout: gnServerSettings.getDefaultTimeoutInSeconds())
116
+ }
117
+
118
+ super.send(operationPending: operationPending)
119
+
120
+ GNDebug.log("[GN Http SEND] " + operationRequest.toString())
121
+
122
+ let authToken = operationPending.getAuthToken()
123
+ let secretKey = operationPending.getSecretKey()
124
+ let gameId = operationPending.getGameId()
125
+ let customTags = operationPending.getCustomTags()
126
+
127
+ var postType = gnServerSettings.getMessageType() == MessageType.Json ? PostType.Json : PostType.MsgPack
128
+
129
+ // Assume Swift supports MsgPack effectively if lib present, otherwise fallback or error
130
+ // Unlike JS, Swift strictly compiled so we adhere to settings. If MsgPack not impl, HttpPeerUrlSession handles it.
131
+
132
+ let subUri = (postType == .Json ? HttpPeer.API_JSON : HttpPeer.API_MSG_PACK) + "/" + CodeHelper.getRequestTypeName(operationPending.getRequestType().rawValue) + "/" + CodeHelper.getRequestRoleName(operationPending.getRole().rawValue) + "/" + operationRequest.getOperationCode()
133
+
134
+ self.networkingHttpPeerBase.postRequest(subUri: subUri, param: operationRequest.getParameters() ?? GNHashtable(), postType: postType, onHttpAppResponse: { [weak self] httpAppResponse in
135
+ self?.onSendOperationRequestResponse(operationPending: operationPending, httpAppResponse: httpAppResponse)
136
+ }, timeout: operationRequest.getTimeout(), authToken: authToken, secretKey: secretKey, customTags: customTags, gameId: gameId)
137
+ }
138
+
139
+ public override func onEnqueue(operationPending: OperationPending) {
140
+ GNDebug.log("[GN Http ENQUEUE] " + operationPending.getOperationRequest().toString())
141
+ }
142
+
143
+ private func onSendOperationRequestResponse(operationPending: OperationPending, httpAppResponse: HttpAppResponse) {
144
+ let operationRequest = operationPending.getOperationRequest()
145
+ let obj = GNHashtable()
146
+
147
+ if !httpAppResponse.hasError() {
148
+ if httpAppResponse.statusCode == 200 {
149
+ var gnHashtable: GNHashtable? = nil
150
+
151
+ if let text = httpAppResponse.text, !text.isEmpty {
152
+ if text.first == HttpPeer.JSON_CHAR_KNOWN {
153
+ // Parse JSON
154
+ if let data = text.data(using: .utf8),
155
+ let json = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
156
+ gnHashtable = GNHashtable()
157
+ // Simple populate, assuming GNHashtable can ingest dictionary
158
+ // Or builder pattern
159
+ // Quick hack:
160
+ for (k, v) in json {
161
+ gnHashtable!.add(k: k, value: v)
162
+ }
163
+ }
164
+ }
165
+ }
166
+
167
+ // If msgpack
168
+ if gnHashtable == nil {
169
+ if let data = httpAppResponse.data {
170
+ // MsgPack deserialize
171
+ // Placeholder
172
+ }
173
+ }
174
+
175
+ if let table = gnHashtable {
176
+ obj.add(k: ParameterCode.ReturnCode, value: table.getNumber(ParameterCode.ReturnCode))
177
+ obj.add(k: ParameterCode.Parameters, value: table.getGNHashtable(ParameterCode.Parameters))
178
+ obj.add(k: ParameterCode.InvalidRequestParameters, value: table.getGNArray(ParameterCode.InvalidRequestParameters))
179
+ obj.add(k: ParameterCode.DebugMessage, value: table.getString(ParameterCode.DebugMessage))
180
+ obj.add(k: ParameterCode.ResponseId, value: operationRequest.getRequestId())
181
+
182
+ self.onResponseHandler(obj: obj)
183
+ return
184
+ }
185
+ }
186
+ }
187
+
188
+ obj.add(k: ParameterCode.ReturnCode, value: ReturnCode.UnknownError)
189
+ obj.add(k: ParameterCode.DebugMessage, value: httpAppResponse.error ?? "Unknown Error")
190
+ obj.add(k: ParameterCode.ResponseId, value: operationRequest.getRequestId())
191
+
192
+ self.onResponseHandler(obj: obj)
193
+ }
194
+
195
+ // MARK: - Raw Request Method
196
+ public func sendRawRequest(
197
+ url: String,
198
+ method: String,
199
+ headers: [String: String]? = nil,
200
+ body: Data?,
201
+ completion: @escaping (Data?, URLResponse?, Error?) -> Void
202
+ ) {
203
+ guard let requestUrl = URL(string: url) else {
204
+ completion(nil, nil, NSError(domain: "HttpPeer", code: -1, userInfo: [NSLocalizedDescriptionKey: "Invalid URL"]))
205
+ return
206
+ }
207
+
208
+ var request = URLRequest(url: requestUrl)
209
+ request.httpMethod = method
210
+ request.httpBody = body
211
+
212
+ if let headers = headers {
213
+ for (key, value) in headers {
214
+ request.setValue(value, forHTTPHeaderField: key)
215
+ }
216
+ }
217
+
218
+ let task = URLSession.shared.dataTask(with: request) { data, response, error in
219
+ DispatchQueue.main.async {
220
+ completion(data, response, error)
221
+ }
222
+ }
223
+ task.resume()
224
+ }
225
+ }
226
+
@@ -0,0 +1,24 @@
1
+ import Foundation
2
+
3
+ public class HttpAppResponse {
4
+ public var statusCode: Int = 0
5
+ public var error: String?
6
+ public var data: Data?
7
+ public var text: String?
8
+
9
+ public func hasError() -> Bool {
10
+ return self.error != nil
11
+ }
12
+
13
+ public func toString() -> String {
14
+ var answer = " StatusCode: \(self.statusCode)"
15
+ if let err = self.error { answer += ", Error: \(err)" }
16
+ if let txt = self.text { answer += ", Text: \(txt)" }
17
+ return answer
18
+ }
19
+ }
20
+
21
+ public enum PostType: Int {
22
+ case Json = 0
23
+ case MsgPack = 1
24
+ }
@@ -0,0 +1,13 @@
1
+ import Foundation
2
+
3
+ public protocol NetworkingHttpPeerBase {
4
+ func initPeer(httpUrl: String, userAgent: String)
5
+
6
+ func setUseReverseProxy(useReverseProxy: Bool)
7
+
8
+ func getRequest(subUri: String, onHttpAppResponse: @escaping Action1<HttpAppResponse>, timeout: Int, authToken: String, secretKey: String, gameId: String)
9
+
10
+ func postRequest(subUri: String, param: GNHashtable, postType: PostType, onHttpAppResponse: @escaping Action1<HttpAppResponse>, timeout: Int, authToken: String, secretKey: String, customTags: GNHashtable?, gameId: String)
11
+
12
+ func postRequestUpload(subUri: String, content: Data, filename: String, mimetype: String, onHttpAppResponse: @escaping Action1<HttpAppResponse>, timeout: Int)
13
+ }