@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.
- package/dist/gearn.js.client.js +183 -57
- package/dist/gearn.js.client.min.js +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +183 -57
- package/dist/runtime/GNNetwork.d.ts +1 -1
- package/dist/runtime/helper/GNSupport.d.ts +20 -0
- package/dist/runtime/{entity → helper}/OperationHelper.d.ts +1 -1
- package/dist/runtime/helper/StorageService.d.ts +18 -0
- package/dist/runtime/networking/NetworkingPeer.d.ts +1 -1
- package/dist/runtime/typescript/ServiceUpdate.d.ts +2 -0
- package/docs/COCOS_CREATOR_INTEGRATION.md +116 -0
- package/examples/cocos-creator/GearNExample.ts.txt +176 -0
- package/package.json +3 -2
- package/srcSwift/Package.swift +32 -0
- package/srcSwift/Sources/GearN/runtime/GNNetwork.swift +530 -0
- package/srcSwift/Sources/GearN/runtime/GNNetworkAuthenticateApi.swift +178 -0
- package/srcSwift/Sources/GearN/runtime/GNNetworkCharacterPlayerApi.swift +1162 -0
- package/srcSwift/Sources/GearN/runtime/GNNetworkCloudScriptApi.swift +154 -0
- package/srcSwift/Sources/GearN/runtime/GNNetworkContentApi.swift +208 -0
- package/srcSwift/Sources/GearN/runtime/GNNetworkDashboardApi.swift +240 -0
- package/srcSwift/Sources/GearN/runtime/GNNetworkGamePlayerApi.swift +1369 -0
- package/srcSwift/Sources/GearN/runtime/GNNetworkGroupApi.swift +1100 -0
- package/srcSwift/Sources/GearN/runtime/GNNetworkInventoryApi.swift +937 -0
- package/srcSwift/Sources/GearN/runtime/GNNetworkMasterPlayerApi.swift +2323 -0
- package/srcSwift/Sources/GearN/runtime/GNNetworkMultiplayerApi.swift +298 -0
- package/srcSwift/Sources/GearN/runtime/GNNetworkStoreInventoryApi.swift +397 -0
- package/srcSwift/Sources/GearN/runtime/common/Action0.swift +3 -0
- package/srcSwift/Sources/GearN/runtime/common/Action1.swift +3 -0
- package/srcSwift/Sources/GearN/runtime/common/Action2.swift +3 -0
- package/srcSwift/Sources/GearN/runtime/common/Action3.swift +3 -0
- package/srcSwift/Sources/GearN/runtime/common/Action4.swift +3 -0
- package/srcSwift/Sources/GearN/runtime/common/GNArray.swift +204 -0
- package/srcSwift/Sources/GearN/runtime/common/GNData.swift +108 -0
- package/srcSwift/Sources/GearN/runtime/common/GNHashtable.swift +200 -0
- package/srcSwift/Sources/GearN/runtime/config/GNServerSettings.swift +95 -0
- package/srcSwift/Sources/GearN/runtime/constant/Commands.swift +28 -0
- package/srcSwift/Sources/GearN/runtime/constant/EventCode.swift +10 -0
- package/srcSwift/Sources/GearN/runtime/constant/OperationCode.swift +252 -0
- package/srcSwift/Sources/GearN/runtime/constant/ReturnCode.swift +19 -0
- package/srcSwift/Sources/GearN/runtime/constant/enumType/ExecuteResponseStatus.swift +9 -0
- package/srcSwift/Sources/GearN/runtime/constant/enumType/FriendStatus.swift +8 -0
- package/srcSwift/Sources/GearN/runtime/constant/enumType/GoogleLoginType.swift +6 -0
- package/srcSwift/Sources/GearN/runtime/constant/enumType/GroupStatus.swift +8 -0
- package/srcSwift/Sources/GearN/runtime/constant/enumType/InvalidMemberType.swift +19 -0
- package/srcSwift/Sources/GearN/runtime/constant/enumType/ItemType.swift +6 -0
- package/srcSwift/Sources/GearN/runtime/constant/enumType/MatchmakingMemberStatus.swift +7 -0
- package/srcSwift/Sources/GearN/runtime/constant/enumType/MatchmakingTicketStatus.swift +9 -0
- package/srcSwift/Sources/GearN/runtime/constant/enumType/OwnerType.swift +10 -0
- package/srcSwift/Sources/GearN/runtime/constant/enumType/PermissionDataItem.swift +6 -0
- package/srcSwift/Sources/GearN/runtime/constant/enumType/PushPlatformType.swift +6 -0
- package/srcSwift/Sources/GearN/runtime/constant/enumType/RequestRole.swift +7 -0
- package/srcSwift/Sources/GearN/runtime/constant/enumType/RequestType.swift +16 -0
- package/srcSwift/Sources/GearN/runtime/constant/enumType/StoreItemType.swift +6 -0
- package/srcSwift/Sources/GearN/runtime/constant/enumType/StoreReceiveType.swift +9 -0
- package/srcSwift/Sources/GearN/runtime/constant/errorCode/ErrorCode.swift +58 -0
- package/srcSwift/Sources/GearN/runtime/constant/parameterCode/ParameterCode.swift +672 -0
- package/srcSwift/Sources/GearN/runtime/entity/DataMember.swift +196 -0
- package/srcSwift/Sources/GearN/runtime/entity/GNMetadata.swift +9 -0
- package/srcSwift/Sources/GearN/runtime/entity/InvalidMember.swift +11 -0
- package/srcSwift/Sources/GearN/runtime/entity/OperationEvent.swift +38 -0
- package/srcSwift/Sources/GearN/runtime/entity/OperationHelper.swift +28 -0
- package/srcSwift/Sources/GearN/runtime/entity/OperationRequest.swift +62 -0
- package/srcSwift/Sources/GearN/runtime/entity/OperationResponse.swift +98 -0
- package/srcSwift/Sources/GearN/runtime/entity/models/AuthenticateModels.swift +351 -0
- package/srcSwift/Sources/GearN/runtime/entity/models/AuthenticateRequestModels.swift +81 -0
- package/srcSwift/Sources/GearN/runtime/entity/models/AuthenticateResponseModels.swift +108 -0
- package/srcSwift/Sources/GearN/runtime/entity/models/CharacterPlayerModels.swift +1045 -0
- package/srcSwift/Sources/GearN/runtime/entity/models/CharacterPlayerRequestModels.swift +821 -0
- package/srcSwift/Sources/GearN/runtime/entity/models/CharacterPlayerResponseModels.swift +588 -0
- package/srcSwift/Sources/GearN/runtime/entity/models/CloudScriptModels.swift +187 -0
- package/srcSwift/Sources/GearN/runtime/entity/models/CloudScriptRequestModels.swift +84 -0
- package/srcSwift/Sources/GearN/runtime/entity/models/CloudScriptResponseModels.swift +59 -0
- package/srcSwift/Sources/GearN/runtime/entity/models/ContentModels.swift +195 -0
- package/srcSwift/Sources/GearN/runtime/entity/models/ContentRequestModels.swift +116 -0
- package/srcSwift/Sources/GearN/runtime/entity/models/ContentResponseModels.swift +81 -0
- package/srcSwift/Sources/GearN/runtime/entity/models/DashboardModels.swift +426 -0
- package/srcSwift/Sources/GearN/runtime/entity/models/DashboardRequestModels.swift +160 -0
- package/srcSwift/Sources/GearN/runtime/entity/models/DashboardResponseModels.swift +82 -0
- package/srcSwift/Sources/GearN/runtime/entity/models/GamePlayerModels.swift +1334 -0
- package/srcSwift/Sources/GearN/runtime/entity/models/GamePlayerRequestModels.swift +643 -0
- package/srcSwift/Sources/GearN/runtime/entity/models/GamePlayerResponseModels.swift +213 -0
- package/srcSwift/Sources/GearN/runtime/entity/models/GenericModels.swift +171 -0
- package/srcSwift/Sources/GearN/runtime/entity/models/GroupModels.swift +850 -0
- package/srcSwift/Sources/GearN/runtime/entity/models/GroupRequestModels.swift +485 -0
- package/srcSwift/Sources/GearN/runtime/entity/models/GroupResponseModels.swift +165 -0
- package/srcSwift/Sources/GearN/runtime/entity/models/InventoryModels.swift +679 -0
- package/srcSwift/Sources/GearN/runtime/entity/models/InventoryRequestModels.swift +413 -0
- package/srcSwift/Sources/GearN/runtime/entity/models/InventoryResponseModels.swift +141 -0
- package/srcSwift/Sources/GearN/runtime/entity/models/MasterPlayerModels.swift +378 -0
- package/srcSwift/Sources/GearN/runtime/entity/models/MasterPlayerRequestModels.swift +147 -0
- package/srcSwift/Sources/GearN/runtime/entity/models/MasterPlayerResponseModels.swift +318 -0
- package/srcSwift/Sources/GearN/runtime/entity/models/MultiplayerModels.swift +319 -0
- package/srcSwift/Sources/GearN/runtime/entity/models/MultiplayerRequestModels.swift +125 -0
- package/srcSwift/Sources/GearN/runtime/entity/models/MultiplayerResponseModels.swift +45 -0
- package/srcSwift/Sources/GearN/runtime/entity/models/StoreInventoryModels.swift +633 -0
- package/srcSwift/Sources/GearN/runtime/entity/models/StoreInventoryRequestModels.swift +173 -0
- package/srcSwift/Sources/GearN/runtime/entity/models/StoreInventoryResponseModels.swift +61 -0
- package/srcSwift/Sources/GearN/runtime/entity/request/CustomOperationRequest.swift +42 -0
- package/srcSwift/Sources/GearN/runtime/entity/response/CustomOperationResponse.swift +49 -0
- package/srcSwift/Sources/GearN/runtime/entity/response/GetAuthInfoResponse.swift +43 -0
- package/srcSwift/Sources/GearN/runtime/entity/response/HealthCheckResponse.swift +86 -0
- package/srcSwift/Sources/GearN/runtime/entity/response/UploadFileResponse.swift +15 -0
- package/srcSwift/Sources/GearN/runtime/helper/CodeHelper.swift +107 -0
- package/srcSwift/Sources/GearN/runtime/helper/ConverterService.swift +98 -0
- package/srcSwift/Sources/GearN/runtime/helper/EnumUtility.swift +34 -0
- package/srcSwift/Sources/GearN/runtime/helper/GNSupport.swift +41 -0
- package/srcSwift/Sources/GearN/runtime/helper/GNUtils.swift +66 -0
- package/srcSwift/Sources/GearN/runtime/helper/MessagePackConverterService.swift +21 -0
- package/srcSwift/Sources/GearN/runtime/helper/StorageService.swift +29 -0
- package/srcSwift/Sources/GearN/runtime/logger/GNDebug.swift +33 -0
- package/srcSwift/Sources/GearN/runtime/networking/AuthenticateStatus.swift +24 -0
- package/srcSwift/Sources/GearN/runtime/networking/IPeer.swift +8 -0
- package/srcSwift/Sources/GearN/runtime/networking/NetworkingPeer.swift +368 -0
- package/srcSwift/Sources/GearN/runtime/networking/OperationPending.swift +81 -0
- package/srcSwift/Sources/GearN/runtime/networking/PeerBase.swift +228 -0
- package/srcSwift/Sources/GearN/runtime/networking/handler/IServerEventHandler.swift +20 -0
- package/srcSwift/Sources/GearN/runtime/networking/http/HttpPeer.swift +226 -0
- package/srcSwift/Sources/GearN/runtime/networking/http/HttpTypes.swift +24 -0
- package/srcSwift/Sources/GearN/runtime/networking/http/NetworkingHttpPeerBase.swift +13 -0
- package/srcSwift/Sources/GearN/runtime/networking/http/NetworkingPeerUrlSession.swift +125 -0
- package/srcSwift/Sources/GearN/runtime/networking/request/NetRequest.swift +19 -0
- package/srcSwift/Sources/GearN/runtime/networking/response/NetResponse.swift +13 -0
- package/srcSwift/Sources/GearN/runtime/networking/socket/NetworkingPeerSocketIOClient.swift +244 -0
- package/srcSwift/Sources/GearN/runtime/networking/socket/NetworkingSocketPeerBase.swift +59 -0
- package/srcSwift/Sources/GearN/runtime/networking/socket/SocketPeer.swift +136 -0
- package/tsconfig-build.cocos.json +31 -0
- 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
|
+
}
|