DataRePort_launcher.lua 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851
  1. local DataRePort = class("DataRePort")
  2. local cjson = require("cjson")
  3. local sha1 = require( "sha1/init" )
  4. local slspb = nil
  5. if LuaBridgeCtl:Inst() and LuaBridgeCtl:Inst():GetModulesSwitch( 20 ) == 1 then
  6. slspb = require( "slslogpb" )
  7. end
  8. local baseURL = "https://api.tj.996sdk.com" -- init的地址 只针对PC --"测试:https://mapi-test.tj.996sdk.com"
  9. local initAPI = "/api/v1/app/sdkRule"
  10. local ststokenAPI = "/api/v1/app/stsToken"
  11. local aliyunLogAPI = "/logstores/direct-log/shards/lb" -- aliyun上报地址, 数据是protobuf
  12. local appid = nil
  13. local secretKey = nil
  14. local channelid = nil
  15. local pbFileName = ""
  16. --------------------------
  17. local ReportModlistURL = "https://log.tj.996sdk.com" -- 区服列表异常上报地址
  18. local ReportModlistAPI = "/v1/apm"
  19. local ReportModlistAPPID = "nbGzEntGO3QR"
  20. local ReportModlistAPPKey = "Zlcg5DarX6n37RiNMuHWjaT3quzpoYdR"
  21. --检测modeInfoURL合法性
  22. local mode_info_check = "https://user-sdkv2.dhsf.xqhuyu.com" -- "https://user-sdkv2.dhsf.xqhuyu.com" --pre "https://user-sdkv2-pre.dhsf.xqhuyu.com" --test "https://user-sdkv2-test.ppp996.hqyxkj.cn"
  23. local mode_info_interface = "/api/user/checkHost"
  24. local tableMerge = function(dest, src)
  25. for k, v in pairs(src) do
  26. dest[k] = v
  27. end
  28. end
  29. local function encodeBase64(source_str)
  30. local b64chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
  31. local s64 = ''
  32. local str = source_str
  33. while #str > 0 do
  34. local bytes_num = 0
  35. local buf = 0
  36. for byte_cnt=1,3 do
  37. buf = (buf * 256)
  38. if #str > 0 then
  39. buf = buf + string.byte(str, 1, 1)
  40. str = string.sub(str, 2)
  41. bytes_num = bytes_num + 1
  42. end
  43. end
  44. for group_cnt=1,(bytes_num+1) do
  45. local b64char = math.fmod(math.floor(buf/262144), 64) + 1
  46. s64 = s64 .. string.sub(b64chars, b64char, b64char)
  47. buf = buf * 64
  48. end
  49. for fill_cnt=1,(3-bytes_num) do
  50. s64 = s64 .. '='
  51. end
  52. end
  53. return s64
  54. end
  55. local HTTPRequestPost = function(url, callback, data, header, responseType)
  56. local httpRequest = cc.XMLHttpRequest:new()
  57. httpRequest.responseType = cc.XMLHTTPREQUEST_RESPONSE_JSON
  58. httpRequest.timeout = 100000 -- 10 s
  59. httpRequest:open("POST", url)
  60. if header then
  61. for k, v in pairs(header) do
  62. httpRequest:setRequestHeader(k, v)
  63. end
  64. end
  65. if callback then
  66. local function HttpResponseCB()
  67. local code = httpRequest.status
  68. local success = code >= 200 and code < 300
  69. local response = httpRequest.response
  70. -- release_print("Http Request Code:" .. tostring(code))
  71. -- release_print("收到消息数据:", response)
  72. callback(success, response, code)
  73. end
  74. if not header or not header["Content-type"] then
  75. httpRequest:setRequestHeader("Content-type", "application/json")
  76. end
  77. httpRequest:registerScriptHandler(HttpResponseCB)
  78. end
  79. httpRequest:send(data)
  80. end
  81. local calc996SDKSignSuffix = function(originData,secret_key,apiURL,dataStr)
  82. table.sort(originData, function(a, b)
  83. return a.key < b.key
  84. end)
  85. -- 拼接
  86. local origin = "POST" .. "\n"
  87. if apiURL and string.len(origin) > 0 then
  88. origin = origin .. apiURL .. "\n"
  89. end
  90. for i, v in ipairs(originData) do
  91. if v and v.key and v.value and string.len(v.key) > 0 and string.len(v.value) > 0 then
  92. origin = origin .. string.format("%s=%s", v.key, v.value)
  93. if i < #originData then
  94. origin = origin .. "\n"
  95. end
  96. end
  97. end
  98. if dataStr and string.len(dataStr) > 0 then
  99. origin = origin .. "\n" .. dataStr
  100. end
  101. origin = origin .. "\n" .. "key=" .. secret_key
  102. local md5Str = get_str_MD5(origin)
  103. return md5Str
  104. end
  105. local calcAliYunSuffix = function(originData, url, md5Str, dateStr, secret_key)
  106. -- -- ascii排序
  107. table.sort(originData, function(a, b)
  108. return a.key < b.key
  109. end)
  110. -- 拼接
  111. local origin = ""
  112. for i, v in ipairs(originData) do
  113. if v and v.key and v.value and string.len(v.key) > 0 and string.len(v.value) > 0 then
  114. origin = origin .. string.format("%s:%s", v.key, v.value)
  115. origin = origin .. "\n"
  116. end
  117. end
  118. origin = string.sub(origin, 1, string.len(origin)-1)
  119. -- URL编码
  120. local signStr = "POST\n" .. md5Str .. "\n" .. "application/x-protobuf\n" .. dateStr .. "\n" .. origin .. "\n".. url
  121. -- HMAC-SHA1
  122. local sign = sha1.hmac_binary(secret_key, signStr)
  123. -- Base64
  124. sign = encodeBase64(sign)
  125. return sign
  126. end
  127. local simpleEncryKey = {50,30,20,43}
  128. local stringToByteSimpleEncry = function(str)
  129. local bytes={}
  130. for i=1,string.len(str) do
  131. table.insert(bytes,string.byte(string.sub(str,i,i)))
  132. end
  133. local newBytes = {}
  134. local i = 1
  135. for k,v in ipairs(bytes) do
  136. newBytes[k] = v+simpleEncryKey[i]
  137. if i > #simpleEncryKey then
  138. i = 1
  139. end
  140. end
  141. return cjson.encode(newBytes)
  142. end
  143. local stringToByteSimpleDecry = function(byteStr)
  144. local bytes = cjson.decode(byteStr)
  145. local newBytes = {}
  146. local i = 1
  147. local str = ""
  148. for k,v in ipairs(bytes) do
  149. newBytes[k] = v-simpleEncryKey[i]
  150. if i > #simpleEncryKey then
  151. i = 1
  152. end
  153. end
  154. local str = string.char(unpack(newBytes))
  155. return str
  156. end
  157. local GetMacID = function()
  158. local userData = UserData:new("data_report")
  159. local deviceID = userData:getStringForKey( "id" )
  160. local newDeviceID = getDeviceID and getDeviceID() or nil
  161. if not deviceID or deviceID == "" then
  162. deviceID = newDeviceID or (getMac and getMac()) or nil
  163. if not deviceID or deviceID == "" then
  164. local uuid = function()
  165. local seed={'e','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}
  166. local tb={}
  167. for i=1,32 do
  168. table.insert(tb,seed[math.random(1,16)])
  169. end
  170. local sid=table.concat(tb)
  171. return string.format('%s-%s-%s-%s-%s',
  172. string.sub(sid,1,8),
  173. string.sub(sid,9,12),
  174. string.sub(sid,13,16),
  175. string.sub(sid,17,20),
  176. string.sub(sid,21,32)
  177. )
  178. end
  179. deviceID = uuid()
  180. end
  181. userData:setStringForKey( "id", stringToByteSimpleEncry( deviceID ) )
  182. else
  183. deviceID = stringToByteSimpleDecry(deviceID)
  184. end
  185. -- 重新保存 使用最新的
  186. if newDeviceID and deviceID and newDeviceID ~= deviceID then
  187. deviceID = newDeviceID
  188. userData:setStringForKey( "id", stringToByteSimpleEncry( deviceID ) )
  189. end
  190. return deviceID
  191. end
  192. -- 获取系统版本
  193. local function getWindownVersion()
  194. if getWindowsVersion then
  195. local windowVersion = getWindowsVersion()
  196. local versions = string.split(windowVersion,"_")
  197. local majorVer = tonumber(versions[1])
  198. local minorVer = tonumber(versions[2])
  199. local buildNum = tonumber(versions[3])
  200. if majorVer >= 10 then
  201. if buildNum >= 22000 then
  202. return "Win11"
  203. end
  204. return "Win10"
  205. elseif majorVer >= 6 then
  206. if minorVer >= 3 then
  207. return "Win8.1"
  208. elseif minorVer >= 2 then
  209. return "Win8"
  210. elseif minorVer >= 1 then
  211. return "Win7"
  212. end
  213. elseif majorVer >= 5 then
  214. return "WinXP"
  215. end
  216. end
  217. return "windows"
  218. end
  219. function DataRePort:ctor()
  220. self._reportURL = nil --上报地址 通过aliyun获取
  221. self._isCanRePort = false --是否能上报
  222. self._infoData = {} --数据上报的固定数据
  223. self._stsToken = {} --ststoken数据
  224. self._initFinish = false
  225. self._LuaBridgeCtl = nil
  226. self._token_timeout = -1 --token失效时间
  227. self._isCubeReport = false --是否c++上报
  228. end
  229. function DataRePort:Init()
  230. if self._initFinish then
  231. return
  232. end
  233. self._initFinish = true
  234. local isMac = global.L_GameEnvManager:GetEnvDataByKey("platform") == "mac"
  235. if not (cc.PLATFORM_OS_WINDOWS == global.Platform or isMac) then
  236. return
  237. end
  238. appid = global.L_GameEnvManager:GetEnvDataByKey("sdkAppid")
  239. if not appid then
  240. return
  241. end
  242. secretKey = global.L_GameEnvManager:GetEnvDataByKey("sdkAppkey")
  243. if not secretKey then
  244. return
  245. end
  246. channelid = global.L_GameEnvManager:GetEnvDataByKey("sdkChannel")
  247. if not channelid then
  248. return
  249. end
  250. if not self._LuaBridgeCtl then
  251. self._LuaBridgeCtl = LuaBridgeCtl:Inst()
  252. end
  253. if self._LuaBridgeCtl and self._LuaBridgeCtl:GetModulesSwitch(22) == 1 then
  254. self._isCubeReport = true
  255. end
  256. if self._isCubeReport then
  257. return
  258. end
  259. if not self._LuaBridgeCtl or self._LuaBridgeCtl:GetModulesSwitch( 17 ) ~= 1 then
  260. appid = nil
  261. return
  262. end
  263. pbFileName = string.format("%s%s",cc.FileUtils:getInstance():getDefaultResourceRootPath(),"cache/mod_launcher/stab/scripts/pb_message/DataRePort.pb")
  264. if not cc.FileUtils:getInstance():isFileExist(pbFileName) then
  265. pbFileName = string.format("%s%s",cc.FileUtils:getInstance():getDefaultResourceRootPath(),"mod_launcher/stab/scripts/pb_message/DataRePort.pb")
  266. end
  267. local isMac = global.L_GameEnvManager:GetEnvDataByKey("platform") == "mac"
  268. local type = isMac and "mac" or "pc"
  269. local macID = isMac and (global.L_GameEnvManager:GetEnvDataByKey("macAddress") or "") or (GetMacID() or "")
  270. local width = isMac and (global.L_GameEnvManager:GetEnvDataByKey("displayWidth") or 1136) or (getWindowWidth and getWindowWidth() or 1136)
  271. local height = isMac and (global.L_GameEnvManager:GetEnvDataByKey("displayHeight") or 1136) or (getWindowHeight and getWindowHeight() or 640)
  272. local model = isMac and (global.L_GameEnvManager:GetEnvDataByKey("model") or "") or "pc"
  273. local osVersion = isMac and (global.L_GameEnvManager:GetEnvDataByKey("osVersion") or "") or (getWindownVersion() or "")
  274. self._infoData = {
  275. ["device"] = {
  276. type = type,
  277. id = macID,
  278. width = width,
  279. height = height,
  280. model = model,
  281. os = osVersion
  282. },
  283. appid = appid,
  284. channel = channelid or "",
  285. sdk_ver = "1.0.0",
  286. app_ver = isMac and (global.L_GameEnvManager:GetEnvDataByKey("app_ver") or "") or (global.L_GameEnvManager:GetAPKVersionName() or ""),
  287. net_type = "UNKNOWN",
  288. }
  289. self.isDeviceLoginFinish = false
  290. end
  291. --
  292. function DataRePort:UpDeviceLogin(subMod)
  293. if not appid or not secretKey or not channelid then
  294. return
  295. end
  296. self:UpdateSelectModule(subMod)
  297. if self.isDeviceLoginFinish then
  298. return
  299. end
  300. self.isDeviceLoginFinish = true
  301. -- 初始化 c++ 上报
  302. if self._isCubeReport then
  303. local isTest = false
  304. local data = {
  305. appid = appid,
  306. secretKey = secretKey,
  307. channel = channelid,
  308. boxid = self._infoData.boxid,
  309. isDev = isTest
  310. }
  311. global.L_NativeBridgeManager:GN_InitClientCube(data)
  312. return
  313. end
  314. -- init sdk
  315. local data = {
  316. ["appid"] = appid
  317. }
  318. local jsonStr = cjson.encode(data)
  319. local timeMS = os.time()
  320. local nonce = string.format("%s%09d", timeMS, math.random(1, 999999999))
  321. local originData = {
  322. {key="x-996sdk-appid", value = appid},
  323. {key="x-996sdk-timestamp", value = ""..timeMS},
  324. {key="x-996sdk-nonce", value = nonce},
  325. {key="x-996sdk-algo", value = "MD5"},
  326. }
  327. local headerData = {
  328. ["x-996sdk-appid"] = appid,
  329. ["x-996sdk-timestamp"] = ""..timeMS,
  330. ["x-996sdk-nonce"] = nonce,
  331. ["x-996sdk-algo"] = "MD5",
  332. ["x-996sdk-sign"] = calc996SDKSignSuffix(originData,secretKey,initAPI,jsonStr)
  333. }
  334. -- 上报地址走配置
  335. if subMod then
  336. local modGameEnv = subMod:GetGameEnv()
  337. local reportDataURL = modGameEnv:GetCustomDataByKey("reportDataURL")
  338. if reportDataURL and string.len(reportDataURL) > 0 then
  339. baseURL = reportDataURL
  340. end
  341. end
  342. HTTPRequestPost(baseURL..initAPI, function(success, response, code)
  343. local json = cjson.decode(response)
  344. if json.code == 200 then
  345. self._stsToken = json.data and json.data.sts_token or {}
  346. if self._stsToken.project and self._stsToken.project ~= "" and self._stsToken.endpoint and self._stsToken.endpoint ~= "" then
  347. self._reportURL = self._stsToken.project .. "." .. self._stsToken.endpoint
  348. local pattern="(%d+)-(%d+)-(%d+)(%u)(%d+):(%d+):(%d+)(%u)"
  349. local year,month,day,T,hour,min,sec,Z=self._stsToken.Expiration:match(pattern)
  350. self._token_timeout = os.time({day=day*1, month=month*1, year=year*1, hour=hour*1, min=min*1, sec=sec*1})
  351. -- app 启动
  352. local timeStamp = os.time()
  353. local dataParam = {
  354. event={time=timeStamp,name = "device_login",type = "track"}
  355. }
  356. self:SendRePortData(dataParam)
  357. end
  358. end
  359. end,jsonStr,headerData)
  360. end
  361. -- c++上报传过来的设备数据
  362. function DataRePort:SetDeviceInfo( data )
  363. local boxid = self._infoData and self._infoData.boxid
  364. if data and type(data) == "table" and next(data) then
  365. data.boxid = boxid
  366. else
  367. data = {}
  368. end
  369. self._infoData = data
  370. end
  371. -- 读取设备数据
  372. function DataRePort:GetDeviceInfo()
  373. return self._infoData or {}
  374. end
  375. -- 打开聚合
  376. function DataRePort:OpenJuheMode()
  377. -- body
  378. local juheRoleUrl = global.L_GameEnvManager:GetEnvDataByKey("juheSdkRoleUrl")
  379. local juhePayURL = global.L_GameEnvManager:GetEnvDataByKey("juheSdkPayUrl")
  380. local jsonData = {
  381. juheRoleUrl = juheRoleUrl,
  382. juhePayURL = juhePayURL
  383. }
  384. global.L_NativeBridgeManager:GN_OpenJuheMode(jsonData)
  385. end
  386. -- 发送登录事件
  387. function DataRePort:SendLoginEvent( data )
  388. local dataParam = {
  389. event={time=timeStamp,name = "device_login",type = "track"}
  390. }
  391. self:SendRePortData(dataParam)
  392. end
  393. function DataRePort:UpdateAliYunSTSToken( callbackFunc,callbackData )
  394. local initSDKApi = "/api/v1/app/sdkRule"
  395. local data = {
  396. ["module"] = "apm",
  397. }
  398. tableMerge(data,self._infoData or {})
  399. local jsonStr = cjson.encode(data)
  400. local timeMS = os.time()
  401. local nonce = string.format("%s%09d", timeMS, math.random(1, 999999999))
  402. local originData = {
  403. {key="x-996sdk-appid", value = appid},
  404. {key="x-996sdk-timestamp", value = ""..timeMS},
  405. {key="x-996sdk-nonce", value = nonce},
  406. {key="x-996sdk-algo", value = "MD5"},
  407. }
  408. local headerData = {
  409. ["x-996sdk-appid"] = appid,
  410. ["x-996sdk-timestamp"] = ""..timeMS,
  411. ["x-996sdk-nonce"] = nonce,
  412. ["x-996sdk-algo"] = "MD5",
  413. ["x-996sdk-sign"] = calc996SDKSignSuffix(originData,secretKey,ststokenAPI,jsonStr)
  414. }
  415. self._token_timeout = -1
  416. HTTPRequestPost(baseURL..ststokenAPI, function(success, response, code)
  417. local json = cjson.decode( response )
  418. if json.code == 200 then
  419. local jsonData = json.data or {}
  420. self._stsToken = jsonData or {}
  421. if jsonData.project and jsonData.project ~= "" and jsonData.endpoint and jsonData.endpoint ~= "" then
  422. self._reportURL = jsonData.project .. "." .. jsonData.endpoint
  423. local pattern="(%d+)-(%d+)-(%d+)(%u)(%d+):(%d+):(%d+)(%u)"
  424. local year,month,day,T,hour,min,sec,Z=self._stsToken.Expiration:match(pattern)
  425. self._token_timeout = os.time({day=day*1, month=month*1, year=year*1, hour=hour*1, min=min*1, sec=sec*1})
  426. if callbackFunc then
  427. callbackFunc(callbackData)
  428. end
  429. end
  430. end
  431. end,jsonStr,headerData)
  432. end
  433. function DataRePort:GetLogGroupPortData(data,timeStamp)
  434. local LogGroup = nil
  435. if self._LuaBridgeCtl and self._LuaBridgeCtl:GetModulesSwitch( 20 ) == 1 then
  436. if data and type(data) == "table" and next(data) then
  437. -- info data
  438. tableMerge(data, self._infoData or {})
  439. LogGroup = {LogTags={}, Topic = "", Source = "",Logs={}}
  440. local Log = {Time = timeStamp or os.time(), Contents = {}}
  441. for k,v in pairs( data ) do
  442. local vStr = ""
  443. if type(v) == "table" then
  444. vStr = cjson.encode(v)
  445. else
  446. vStr = v
  447. end
  448. table.insert(Log.Contents, {
  449. Key = tostring(k),
  450. Value = vStr
  451. })
  452. end
  453. LogGroup.Logs[1] = Log
  454. end
  455. else
  456. if data and type(data) == "table" and next(data) then
  457. -- info data
  458. tableMerge(data, self._infoData or {})
  459. LogGroup = {Logs={{Time = timeStamp or os.time(), Contents = {}}},LogTags={}}
  460. for k,v in pairs( data ) do
  461. local vStr = ""
  462. if type(v) == "table" then
  463. vStr = cjson.encode(v)
  464. else
  465. vStr = v
  466. end
  467. table.insert(LogGroup.Logs[1].Contents,{
  468. Key = tostring(k), Value = vStr
  469. })
  470. end
  471. end
  472. end
  473. return LogGroup
  474. end
  475. function DataRePort:SendRePortData( data )
  476. -- 试玩不上报任何数据
  477. local shiwan = global.L_GameEnvManager:GetEnvDataByKey("shiwan")
  478. if shiwan and tonumber(shiwan) == 1 then
  479. return
  480. end
  481. local isMac = global.L_GameEnvManager:GetEnvDataByKey("platform") == "mac"
  482. if not (cc.PLATFORM_OS_WINDOWS == global.Platform or isMac) then
  483. if data and data.event then
  484. data.game_event = data.event
  485. data.event = nil
  486. end
  487. if data and data.properities then
  488. data.game_properities = data.properities
  489. data.properities = nil
  490. end
  491. global.L_NativeBridgeManager:GN_customRePortData(data)
  492. return
  493. end
  494. -- c++ 上报
  495. if self._isCubeReport then
  496. self:SendCubeRePortData( data )
  497. return
  498. end
  499. if self._token_timeout < 0 then
  500. return true
  501. end
  502. local function getTimeUTC() --UTC时间
  503. local utcTime = os.time(os.date("!*t", now))
  504. return utcTime
  505. end
  506. local psSend = function( sData )
  507. local LogGroup = self:GetLogGroupPortData( sData )
  508. self:RePortDataContent(LogGroup)
  509. end
  510. if getTimeUTC() >= self._token_timeout then
  511. self:UpdateAliYunSTSToken(psSend,data)
  512. return
  513. end
  514. psSend(data)
  515. end
  516. -- 上报 c++接口
  517. function DataRePort:SendCubeRePortData( data )
  518. local eventName = data and data.event and data.event.name or ""
  519. local uid = data and data.user and data.user.id or ""
  520. local properties = data and data.properities or {}
  521. global.L_NativeBridgeManager:GN_SendLogGroupCube({
  522. event = eventName,
  523. user = uid,
  524. properties = cjson.encode(properties)
  525. })
  526. end
  527. function DataRePort:RePortDataContent(dataContent,pbMessageName,pbName )
  528. if not self._reportURL then --上报地址没有
  529. return
  530. end
  531. if type(dataContent) ~= "table" or not next(dataContent) then
  532. return
  533. end
  534. local pbContent = nil
  535. if self._LuaBridgeCtl and self._LuaBridgeCtl:GetModulesSwitch( 20 ) == 1 then
  536. local encodeLogPb = function(data)
  537. local ok, resultOrErrMsg = pcall(function()
  538. return slspb.GetLogGroupPBBytes(data)
  539. end)
  540. if not ok then
  541. release_print(resultOrErrMsg);
  542. return nil
  543. end
  544. return resultOrErrMsg
  545. end
  546. pbContent = encodeLogPb(dataContent)
  547. else
  548. pbName = pbName or pbFileName
  549. if not global.L_ProtoBuf:registerPB(pbName) then
  550. return
  551. end
  552. pbContent = global.L_ProtoBuf:encodePB(pbMessageName or "LogGroup", dataContent)
  553. end
  554. if not pbContent then
  555. return
  556. end
  557. local pbSize = string.len(pbContent)
  558. local originData = {
  559. {key="x-log-apiversion", value = "0.6.0"},
  560. {key="x-log-bodyrawsize", value = pbSize},
  561. {key="x-log-signaturemethod", value = "hmac-sha1"},
  562. {key="x-acs-security-token", value = self._stsToken.SecurityToken or ""},
  563. }
  564. local md5Str = string.upper(get_str_MD5(pbContent))
  565. local dateStr = os.date("!%a, %d %b %Y %X GMT", os.time())
  566. local signStrt = calcAliYunSuffix(originData, aliyunLogAPI, md5Str, dateStr, self._stsToken.AccessKeySecret)
  567. local headerData = {
  568. ["Content-Length"] = pbSize,
  569. ["Content-type"] = "application/x-protobuf",
  570. ["x-log-bodyrawsize"] = pbSize,
  571. ["Content-MD5"] = md5Str,
  572. ["Date"] = dateStr,
  573. ["x-log-apiversion"] = "0.6.0",
  574. ["x-log-signaturemethod"] = "hmac-sha1",
  575. ["Authorization"] = "LOG " .. (self._stsToken.AccessKeyId or "") .. ":" .. signStrt,
  576. ["x-acs-security-token"] = self._stsToken.SecurityToken or "",
  577. }
  578. -- 上报
  579. local url = "https://" .. self._reportURL .. aliyunLogAPI
  580. HTTPRequestPost(url,function(success, response, code)
  581. if success then
  582. release_print("***********============success")
  583. else
  584. release_print("***********============fail")
  585. end
  586. end,pbContent,headerData)
  587. end
  588. -- 上报区服列表访问失败信息至服务器
  589. function DataRePort:ReportErrorModlistURL(errorType, errorCode, errorMsg, errorURL, httpCode)
  590. local deviceT = {
  591. [cc.PLATFORM_OS_WINDOWS] = "pc",
  592. [cc.PLATFORM_OS_ANDROID] = "android",
  593. [cc.PLATFORM_OS_IPHONE] = "ios",
  594. [cc.PLATFORM_OS_IPAD] = "ios",
  595. [cc.PLATFORM_OS_HARMONY] = "ohos",
  596. }
  597. -- -1:未识别 0:wifi 1:2g 2:3g 3:4g
  598. local netTypeT = {
  599. [-1] = "UNKNOWN",
  600. [0] = "WIFI",
  601. [1] = "2G",
  602. [2] = "3G",
  603. [3] = "4G",
  604. }
  605. local requestBody = {
  606. ["device"] =
  607. {
  608. type = deviceT[global.Platform] or "pc",
  609. width = global.Director:getVisibleSize().width,
  610. height = global.Director:getVisibleSize().height,
  611. model = "empty",
  612. os = "empty",
  613. net_type= netTypeT[global.L_GameEnvManager:GetNetType()] or "UNKNOWN",
  614. },
  615. appid = ReportModlistAPPID,
  616. channel = global.L_GameEnvManager:GetEnvDataByKey("sdkChannel") or "",
  617. sdk_ver = "1.0.0",
  618. app_ver = global.L_GameEnvManager:GetAPKVersionName() or "",
  619. ["event_type"] = "http_request",
  620. ["event_content"] =
  621. {
  622. ["extend"] = cjson.encode({
  623. ["content"] = errorType,
  624. ["code"] = errorCode,
  625. ["msg"] = errorMsg,
  626. }),
  627. ["url"] = errorURL,
  628. ["status_code"] = httpCode,
  629. }
  630. }
  631. local requestHeader = {
  632. ["x-996sdk-algo"] = "MD5",
  633. ["x-996sdk-appid"] = ReportModlistAPPID,
  634. ["x-996sdk-nonce"] = string.format("%09d", math.random(1, 999999999)) .. string.format("%09d", math.random(1, 999999999)),
  635. ["x-996sdk-timestamp"] = "" .. os.time(),
  636. }
  637. -- 计算签名
  638. local signHeader = {}
  639. for k, v in pairs(requestHeader) do
  640. table.insert(signHeader, {key = k, value = v})
  641. end
  642. requestHeader["x-996sdk-sign"] = calc996SDKSignSuffix(signHeader, ReportModlistAPPKey, ReportModlistAPI, cjson.encode(requestBody))
  643. requestHeader["user-agent"] = "lua-http-client/1.0"
  644. -- post to server
  645. local function postCB(success, response, code)
  646. print("ReportErrorModlistURL", success, response, code)
  647. end
  648. local postURL = ReportModlistURL .. ReportModlistAPI
  649. local postData = cjson.encode(requestBody)
  650. local postHeader = requestHeader
  651. HTTPRequestPost(postURL, postCB, postData, postHeader)
  652. print("--------------- post URL")
  653. print(postURL)
  654. print(postData)
  655. print(cjson.encode(postHeader))
  656. print("---------------")
  657. end
  658. function DataRePort:RequestModeInfoCheck(subMod)
  659. if global.isDebugMode or global.isGMMode then
  660. return nil
  661. end
  662. if not subMod then
  663. return nil
  664. end
  665. local modGameEnv = subMod:GetGameEnv()
  666. local ModeInfoCheckDoamin = modGameEnv:GetCustomDataByKey("ModeInfoCheckDoamin")
  667. if ModeInfoCheckDoamin and string.len(ModeInfoCheckDoamin) > 0 then
  668. mode_info_check = ModeInfoCheckDoamin
  669. end
  670. local checkURLs = global.L_GameEnvManager:GetEnvDataByKey("modlist") or ""
  671. local planBURL = global.L_GameEnvManager:GetEnvDataByKey("modlistPlanB")
  672. if planBURL and string.len(planBURL) > 0 then
  673. checkURLs = checkURLs .. "," .. planBURL
  674. end
  675. local url = string.format("%s%s?type=%s&host=%s", mode_info_check, mode_info_interface, "c2", checkURLs)
  676. HTTPRequest(url, function( success, response )
  677. -- body
  678. if not success then
  679. PerformWithDelayGlobal(function()
  680. self:RequestModeInfoCheck(subMod)
  681. end, 5 * 60)
  682. end
  683. success = true
  684. if response and string.len(response) > 0 then
  685. local jsonData = cjson.decode(response)
  686. if jsonData and jsonData.data == 0 then
  687. success = false
  688. end
  689. end
  690. releasePrint("======CHECK: ", response or "")
  691. if not success then
  692. local function callback(bType, custom)
  693. if bType == 1 then
  694. if global.isWindows then
  695. global.Director:endToLua()
  696. else
  697. global.L_NativeBridgeManager:GN_accountLogout()
  698. global.L_GameEnvManager:RestartGame()
  699. end
  700. end
  701. end
  702. local data = {}
  703. data.str = "渠道获取失败,请联系客服"
  704. data.btnDesc = { "退出" }
  705. data.callback = callback
  706. global.L_CommonTipsManager:OpenLayer(data)
  707. if not global.L_CommonTipsManager._layer then
  708. global.Facade:sendNotification(global.NoticeTable.Layer_CommonTips_Open, data)
  709. end
  710. end
  711. end)
  712. end
  713. function DataRePort:UpdateSelectModule(subMod)
  714. if not appid or not secretKey or not channelid then
  715. return
  716. end
  717. if global.L_GameEnvManager:GetEnvDataByKey("isBoxLogin") == 1 then
  718. local boxBoxGameID = subMod:GetOperID() or ""
  719. local boxChannelID = global.L_GameEnvManager:GetChannelID() or ""
  720. local platformId = subMod:GetPlatformID()
  721. if platformId and string.len( tostring(platformId) ) > 0 then
  722. boxChannelID = tostring(platformId)
  723. end
  724. local oldBoxid = self._infoData.boxid
  725. self._infoData.boxid= boxBoxGameID .. ":" .. boxChannelID
  726. if self.isDeviceLoginFinish and oldBoxid ~= self._infoData.boxid then
  727. if self._isCubeReport then
  728. local data = {
  729. appid = appid,
  730. secretKey = secretKey,
  731. channel = channelid,
  732. boxid = self._infoData.boxid,
  733. }
  734. global.L_NativeBridgeManager:GN_UpdateDeviceInfo(data)
  735. return
  736. end
  737. self:SendLoginEvent()
  738. end
  739. end
  740. end
  741. return DataRePort