MultiVersionData_launcher.lua 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. local MultiVersionData = {
  2. _mult_init = true
  3. }
  4. local cjson = require("cjson")
  5. local Array = require("lockbox.util.array")
  6. local Stream = require("lockbox.util.stream")
  7. local CBCMode = require("lockbox.cipher.mode.cbc")
  8. local Base64 = require("lockbox.util.base64")
  9. local ZeroPadding = require("lockbox.padding.zero")
  10. local AES256Cipher = require("lockbox.cipher.aes256")
  11. local aes256key = "0CodEiBIMeE8MTjZ/gpAnm2xUJi0DG5WelYBn+mdm6U=" -- 测试: "TdC9aSnhWZRWV+Gg38BPFQVRAqxdvvS73GwzAU2YE9w=" 准生产/正式: "0CodEiBIMeE8MTjZ/gpAnm2xUJi0DG5WelYBn+mdm6U="
  12. local baseURL = "https://api.tj.996sdk.com" -- 测试: "https://api-test.tj.996sdk.com" 准生产/正式: "https://api.tj.996sdk.com"
  13. local multiVersion = "/api/v1/app/getConfig"
  14. local multiVersionKey = "Zlcg5DarX6n37RiNMuHWjaT3quzpoYdR" -- 测试:"027fa120e1c2e7a3d9e2258bd9069093" 准生产/正式: "Zlcg5DarX6n37RiNMuHWjaT3quzpoYdR"
  15. local multiVerionAppID = "nbGzEntGO3QR" -- 测试 "GzE1B0ytgA2z" 准生产/正式: "nbGzEntGO3QR"
  16. local function encodeBase64(source_str)
  17. local b64chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
  18. local s64 = ''
  19. local str = source_str
  20. while #str > 0 do
  21. local bytes_num = 0
  22. local buf = 0
  23. for byte_cnt=1,3 do
  24. buf = (buf * 256)
  25. if #str > 0 then
  26. buf = buf + string.byte(str, 1, 1)
  27. str = string.sub(str, 2)
  28. bytes_num = bytes_num + 1
  29. end
  30. end
  31. for group_cnt=1,(bytes_num+1) do
  32. local b64char = math.fmod(math.floor(buf/262144), 64) + 1
  33. s64 = s64 .. string.sub(b64chars, b64char, b64char)
  34. buf = buf * 64
  35. end
  36. for fill_cnt=1,(3-bytes_num) do
  37. s64 = s64 .. '='
  38. end
  39. end
  40. return s64
  41. end
  42. local HTTPRequestPost = function(url, callback, data, header, responseType)
  43. local httpRequest = cc.XMLHttpRequest:new()
  44. httpRequest.responseType = cc.XMLHTTPREQUEST_RESPONSE_JSON
  45. httpRequest.timeout = 100000 -- 10 s
  46. httpRequest:open("POST", url)
  47. if header then
  48. for k, v in pairs(header) do
  49. httpRequest:setRequestHeader(k, v)
  50. end
  51. end
  52. if callback then
  53. local function HttpResponseCB()
  54. local code = httpRequest.status
  55. local success = code >= 200 and code < 300
  56. local response = httpRequest.response
  57. -- release_print("Http Request Code:" .. tostring(code))
  58. -- release_print("收到消息数据:", response)
  59. callback(success, response, code)
  60. end
  61. if not header or not header["Content-type"] then
  62. httpRequest:setRequestHeader("Content-type", "application/json")
  63. end
  64. httpRequest:registerScriptHandler(HttpResponseCB)
  65. end
  66. httpRequest:send(data)
  67. end
  68. local calc996SDKSignSuffix = function(originData,secret_key,apiURL,dataStr)
  69. table.sort(originData, function(a, b)
  70. return a.key < b.key
  71. end)
  72. -- 拼接
  73. local origin = "POST" .. "\n"
  74. if apiURL and string.len(origin) > 0 then
  75. origin = origin .. apiURL .. "\n"
  76. end
  77. for i, v in ipairs(originData) do
  78. if v and v.key and v.value and string.len(v.key) > 0 and string.len(v.value) > 0 then
  79. origin = origin .. string.format("%s=%s", v.key, v.value)
  80. if i < #originData then
  81. origin = origin .. "\n"
  82. end
  83. end
  84. end
  85. if dataStr and string.len(dataStr) > 0 then
  86. origin = origin .. "\n" .. dataStr
  87. end
  88. origin = origin .. "\n" .. "key=" .. secret_key
  89. local md5Str = get_str_MD5(origin)
  90. return md5Str
  91. end
  92. local calcAliYunSuffix = function(originData, url, md5Str, dateStr, secret_key)
  93. -- -- ascii排序
  94. table.sort(originData, function(a, b)
  95. return a.key < b.key
  96. end)
  97. -- 拼接
  98. local origin = ""
  99. for i, v in ipairs(originData) do
  100. if v and v.key and v.value and string.len(v.key) > 0 and string.len(v.value) > 0 then
  101. origin = origin .. string.format("%s:%s", v.key, v.value)
  102. origin = origin .. "\n"
  103. end
  104. end
  105. origin = string.sub(origin, 1, string.len(origin)-1)
  106. -- URL编码
  107. local signStr = "POST\n" .. md5Str .. "\n" .. "application/x-protobuf\n" .. dateStr .. "\n" .. origin .. "\n".. url
  108. -- HMAC-SHA1
  109. local sign = sha1.hmac_binary(secret_key, signStr)
  110. -- Base64
  111. sign = encodeBase64(sign)
  112. return sign
  113. end
  114. local Aes256Decode = function (params)
  115. local decipher = CBCMode.Decipher()
  116. .setKey(Array.fromString(aes256key))
  117. .setBlockCipher(AES256Cipher)
  118. .setPadding(ZeroPadding);
  119. local decodeBytes = decipher
  120. .init()
  121. .update(Stream.fromString("gamesdk996start1"))
  122. .update(Base64.toStream(params))
  123. .finish()
  124. .asBytes();
  125. return string.match(Array.toString(decodeBytes), "%b{}")
  126. end
  127. function MultiVersionData:ctor()
  128. self._mult_channelid = nil
  129. end
  130. function MultiVersionData:initMultiVersCustomConfig()
  131. -- body
  132. local multiVersURL = global.L_GameEnvManager:GetModlistCustomDataByKey("multiVersURL")
  133. local multiVersVersion = global.L_GameEnvManager:GetModlistCustomDataByKey("multiVersVersion")
  134. if multiVersURL and string.len(multiVersURL) > 0 then
  135. baseURL = multiVersURL
  136. end
  137. if multiVersVersion and tonumber(multiVersVersion) == 2 then
  138. aes256key = "TdC9aSnhWZRWV+Gg38BPFQVRAqxdvvS73GwzAU2YE9w="
  139. multiVersionKey = "027fa120e1c2e7a3d9e2258bd9069093"
  140. multiVerionAppID = "GzE1B0ytgA2z"
  141. end
  142. end
  143. function MultiVersionData:GetNewAppData(subMod)
  144. if self._mult_init then
  145. -- 读取配置
  146. self._mult_init = false
  147. self:initMultiVersCustomConfig()
  148. end
  149. if cc.PLATFORM_OS_WINDOWS == global.Platform then
  150. return false
  151. end
  152. if not subMod then
  153. return false
  154. end
  155. local gameLists = global.L_ModuleManager:GetAllGameID() or {}
  156. if #gameLists < 2 then
  157. return false
  158. end
  159. local platformID = subMod.GetPlatformID and subMod:GetPlatformID() or ""
  160. if platformID == "" then
  161. return false
  162. end
  163. if self._mult_platformID == platformID then
  164. return false
  165. end
  166. self._mult_platformID = platformID
  167. local gameid = subMod:GetOperID()
  168. if not gameid then
  169. return false
  170. end
  171. local requestBody = {
  172. game_id = tostring(gameid)
  173. }
  174. local requestHeader = {
  175. ["x-996sdk-algo"] = "MD5",
  176. ["x-996sdk-appid"] = multiVerionAppID,
  177. ["x-996sdk-nonce"] = string.format("%09d", math.random(1, 999999999)) .. string.format("%09d", math.random(1, 999999999)),
  178. ["x-996sdk-timestamp"] = "" .. os.time(),
  179. }
  180. -- 计算签名
  181. local signHeader = {}
  182. for k, v in pairs(requestHeader) do
  183. table.insert(signHeader, {key = k, value = v})
  184. end
  185. requestHeader["x-996sdk-sign"] = calc996SDKSignSuffix(signHeader, multiVersionKey, multiVersion, cjson.encode(requestBody))
  186. requestHeader["user-agent"] = "lua-http-client/1.0"
  187. -- post to server
  188. local function postCB(success, response, code)
  189. if not success then
  190. release_print("--------multi verSion http error: ", code)
  191. return
  192. end
  193. release_print("---------multi verSion response: ", response)
  194. -- 获取数据
  195. local json = cjson.decode(response)
  196. if not json then
  197. return
  198. end
  199. if json.code ~= 200 then
  200. return
  201. end
  202. if not json.data then
  203. return
  204. end
  205. local aesDecode = Aes256Decode(json.data)
  206. if not aesDecode or aesDecode == "" then
  207. release_print("--------multi verSion aesDecode is null")
  208. return
  209. end
  210. local cjsonData = cjson.decode(aesDecode)
  211. if not cjsonData then
  212. return
  213. end
  214. local appid = cjsonData.appid
  215. if not appid or string.len(appid) == 0 then
  216. release_print("----------multi verSion appid is null")
  217. return
  218. end
  219. local appkey = cjsonData.appkey
  220. if not appkey or string.len(appkey) == 0 then
  221. release_print("----------multi verSion appkey is null")
  222. return
  223. end
  224. local sdk_app_id = cjsonData.sdk_app_id
  225. if not sdk_app_id or string.len(sdk_app_id) == 0 then
  226. release_print("----------multi verSion sdk_app_id is null")
  227. return
  228. end
  229. local sdk_app_key = cjsonData.sdk_app_key
  230. if not sdk_app_key or string.len(sdk_app_key) == 0 then
  231. release_print("----------multi verSion sdk_app_key is null")
  232. return
  233. end
  234. local appsign = cjsonData.appsign
  235. if not appsign or string.len(appsign) == 0 then
  236. release_print("----------multi verSion appsign is null")
  237. return
  238. end
  239. local channelid = global.L_GameEnvManager:GetChannelID() or ""
  240. -- 通知java
  241. local jsonData = {
  242. appId = sdk_app_id,
  243. appKey = sdk_app_key,
  244. loginAppId = appid,
  245. loginSignKey = appkey,
  246. loginChannel = appid,
  247. sdkSign = appsign,
  248. gameId = gameid,
  249. }
  250. global.L_NativeBridgeManager:GN_SDKinit(jsonData)
  251. end
  252. local postURL = baseURL .. multiVersion
  253. local postData = cjson.encode(requestBody)
  254. local postHeader = requestHeader
  255. HTTPRequestPost(postURL, postCB, postData, postHeader)
  256. release_print("--------------- post URL: ", postURL)
  257. release_print("--------------- post body: ", postData)
  258. release_print("--------------- post header: ", cjson.encode(postHeader))
  259. release_print("---------------")
  260. end
  261. return MultiVersionData