You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1258 lines
33 KiB

  1. local lfs = lfs or require("lfs")
  2. local writablePath = cc.FileUtils:getInstance():getWritablePath();
  3. local targetPlatform = cc.Application:getInstance():getTargetPlatform()
  4. RomSetting = loadRomSettingScript();
  5. PhpSetting = {}
  6. -- 将废弃
  7. function log(...)
  8. print(...)
  9. end
  10. -- 打印一般信息,开发时查看数据用
  11. function logI(...)
  12. if target_platform ~= 0 then
  13. return
  14. end
  15. print(...)
  16. end
  17. -- 打印较重要的调试信息
  18. function logD(...)
  19. print(...)
  20. end
  21. -- 打印错误信息
  22. function logE(...)
  23. print(...)
  24. end
  25. -- 将废弃
  26. function printDebug(...)
  27. print(...)
  28. end
  29. function handler(target, method)
  30. assert(method);
  31. return function(...)
  32. return method(target, ...)
  33. end
  34. end
  35. -- 从本地读取审核状态
  36. function loadIsReview()
  37. local appPackageName = tostring(getAppPackageName())
  38. local appVersionName = tostring(getAppVersionName())
  39. logD("loadIsReview() appVersionName = ", appVersionName)
  40. logD("loadIsReview() appPackageName = ", appPackageName)
  41. if appPackageName == "com.dangdang.chuannan" and appVersionName == "3.0.0" then
  42. return false
  43. end
  44. if appPackageName == "com.cdhklu.yoihtts" and appVersionName == "1.0.3" then
  45. return false
  46. end
  47. local isReview = false
  48. -- 如果是配置了小游戏,则默认审核,否则默认非审核
  49. if RomSetting and RomSetting.IosReviewType and RomSetting.IosReviewType ~= 1 then
  50. isReview = cc.UserDefault:getInstance():getBoolForKey("isReview", true);
  51. else
  52. isReview = cc.UserDefault:getInstance():getBoolForKey("isReview", false);
  53. end
  54. logD("loadIsReview() isReview = ", tostring(isReview))
  55. return isReview;
  56. end
  57. -- 保存审核状态到本地
  58. function saveIsReview(isReview)
  59. logD("saveIsReview() isReview = ", tostring(isReview))
  60. cc.UserDefault:getInstance():setBoolForKey("isReview", isReview);
  61. end
  62. -- 是否开发模式
  63. function isDevMode()
  64. return RomSetting.isDevMode == true;
  65. end
  66. function isDebug()
  67. return isDevMode();
  68. end
  69. -- 是否软著版本
  70. function isRuanZhu()
  71. return (RomSetting.isRuanZhu == true)
  72. end
  73. function getAppId()
  74. if RomSetting.AppId then
  75. return RomSetting.AppId;
  76. else
  77. return 0;
  78. end
  79. end
  80. function getChannelId()
  81. if RomSetting.ChannelId then
  82. return RomSetting.ChannelId;
  83. else
  84. return 100;
  85. end
  86. end
  87. -- 是否是Android操作系统
  88. function isAndroidPlatform()
  89. local targetPlatform = cc.Application:getInstance():getTargetPlatform();
  90. -- Android版本
  91. if targetPlatform == 3 then
  92. return true;
  93. else
  94. return false;
  95. end
  96. end
  97. -- 是否是苹果操作系统
  98. function isIOSPlatform()
  99. local targetPlatform = cc.Application:getInstance():getTargetPlatform();
  100. -- 苹果版本
  101. if (targetPlatform == 4 or targetPlatform == 5) then
  102. return true;
  103. else
  104. return false;
  105. end
  106. end
  107. function isWin32Platform()
  108. local targetPlatform = cc.Application:getInstance():getTargetPlatform();
  109. if (targetPlatform == 0) then
  110. return true;
  111. else
  112. return false;
  113. end
  114. end
  115. -- 是否是正在审核的版本
  116. function isReviewVersion()
  117. logD("PreloadTools::isReviewVersion()")
  118. if RomSetting and RomSetting.isReviewVersion == true then
  119. return true
  120. end
  121. local isReview = loadIsReview()
  122. logD("PreloadTools::isReviewVersion() isReview = ", tostring(isReview))
  123. return isReview
  124. end
  125. -- 是否是苹果正在审核的版本
  126. function isIOSReviewVersion()
  127. return isIOSPlatform() and isReviewVersion()
  128. end
  129. -- 是否正在使用小游戏审核
  130. function isReviewWithMiniGame()
  131. if isReviewVersion() then
  132. return tonumber(RomSetting.IosReviewType) ~= 1
  133. else
  134. return false
  135. end
  136. end
  137. -- 是否使用竖屏提交苹果审核
  138. function isReviewByPortrait()
  139. if isReviewVersion() then
  140. return tonumber(RomSetting.IosReviewType) == 3
  141. else
  142. return false
  143. end
  144. end
  145. function getMiniGameConfig()
  146. if RomSetting and RomSetting.IosReviewType == 3 and RomSetting.MiniGameId ~= nil then
  147. local configs = require("preload.MiniGameConfigs")
  148. if configs then
  149. return configs[RomSetting.MiniGameId]
  150. end
  151. end
  152. return nil
  153. end
  154. function getMiniGameMainViewScript()
  155. local miniGameConfig = getMiniGameConfig()
  156. if miniGameConfig then
  157. return miniGameConfig.MainViewScript
  158. else
  159. return nil
  160. end
  161. end
  162. function getMiniGameAutoUpdateViewUI()
  163. local miniGameConfig = getMiniGameConfig()
  164. if miniGameConfig then
  165. return miniGameConfig.AutoUpdateViewUI
  166. else
  167. return nil
  168. end
  169. end
  170. function loadVersionFromLua()
  171. local versionInfo = require("romFiles.version");
  172. if versionInfo then
  173. return versionInfo.ResourceVersion
  174. else
  175. return nil
  176. end
  177. end
  178. function loadVersionFromJson()
  179. local fileName = "romFiles/version.json";
  180. local fileString = cc.FileUtils:getInstance():getStringFromFile(fileName)
  181. return fileString or "1000"
  182. end
  183. function loadVersion()
  184. local resversionLua = loadVersionFromLua()
  185. local resVersionJson = loadVersionFromJson()
  186. local resVersion = resversionLua or resVersionJson
  187. return resVersion
  188. end
  189. -- 所有子UI都根据名字保存到这里
  190. function getUIItems(ui)
  191. local items = {}
  192. local function onNode(node)
  193. local name = node:getName();
  194. if type(name) == "string" then
  195. items[name] = node;
  196. end
  197. local desc = node:getDescription();
  198. if desc == "Button" then
  199. node:setClickSoundFile("");
  200. end
  201. return true;
  202. end
  203. -- 遍历所有子节点,把子UI取出来统一放在Items里
  204. ui:visitNode(onNode);
  205. return items;
  206. end
  207. loadUIText = nil
  208. tipLoadUIBg = nil
  209. -- 载入UI文件,并返回UI的根节点
  210. function loadUI(fileName)
  211. logD("loadUI() ", fileName)
  212. if false and isWin32Platform() then
  213. local info = debug.traceback()
  214. local list = string.split(info,"\"")
  215. local nameList = string.split(list[4],".")
  216. local tt = {}
  217. for k,v in ipairs(nameList) do
  218. if v ~= "" then
  219. table.insert(tt,v)
  220. end
  221. end
  222. local fList = string.split(fileName,"/")
  223. fList = string.split(fList[#fList],".");
  224. local seq = cc.Sequence:create(cc.FadeIn:create(0.5),cc.DelayTime:create(3.0),cc.FadeOut:create(0.1))
  225. local function createLabel()
  226. tipLoadUIBg = cc.ImageView:create()
  227. tipLoadUIBg:loadTexture("res/ui/zy_tongyong/tongyong_loading_bg.png")
  228. tipLoadUIBg:setAutoSize(false)
  229. tipLoadUIBg:setSize(cc.size(1280,100))
  230. app.dialogLayout:addChild(tipLoadUIBg,99999)
  231. tipLoadUIBg:setPosition(cc.p(getWinSize().width/2,50))
  232. app.dialogLayout.tipLoadUIBg = tipLoadUIBg
  233. tipLoadUIBg:setVisible(false)
  234. loadUIText = cc.Text:create();
  235. local ttfConfig = {}
  236. ttfConfig.fontFilePath = "res/default/msyh.ttc"
  237. ttfConfig.fontSize = 35
  238. ttfConfig.glyphs = cc.GLYPHCOLLECTION_DYNAMIC
  239. ttfConfig.customGlyphs = nil
  240. ttfConfig.distanceFieldEnabled = false
  241. ttfConfig.outlineSize = 2
  242. ttfConfig.effectColor = cc.c4b(255,255,255,255)
  243. ttfConfig.texColor = cc.c4b(255,39,240,255)
  244. loadUIText:setFontConfig(ttfConfig);
  245. tipLoadUIBg:addChild(loadUIText)
  246. loadUIText:setPosition(cc.p(tipLoadUIBg:getSize().width/2,tipLoadUIBg:getSize().height/2))
  247. tipLoadUIBg:runAction(seq)
  248. end
  249. if fileName ~= "res/ui/ui_common/ModelDialog.ui" and fileName ~= "res/ui/ui_tongyong/texttips.ui"
  250. then
  251. if app.dialogLayout and not app.dialogLayout.tipLoadUIBg or tolua.isnull(tipLoadUIBg)then
  252. createLabel()
  253. elseif app.dialogLayout and app.dialogLayout.tipLoadUIBg then
  254. if not tolua.isnull(tipLoadUIBg) then
  255. if fileName ~= "res/ui/ui_tongyong/duanxinchonglian.ui" then
  256. loadUIText:setText("所用UI:"..fList[1] .." 类名:".. tostring(tt[#tt]));
  257. tipLoadUIBg:stopAllActions()
  258. tipLoadUIBg:setOpacity(0)
  259. tipLoadUIBg:runAction(seq)
  260. tipLoadUIBg:setVisible(true)
  261. end
  262. end
  263. end
  264. end
  265. end
  266. local ui = cc.StreamObject:loadFromFile(fileName);
  267. ui.Items = getUIItems(ui);
  268. ui:setCollectAnimationClip(false);
  269. return ui;
  270. end
  271. -- 获得一个文件在可写文件目录中的位置
  272. function getWritableFullName(fileName)
  273. return writablePath .. fileName;
  274. end
  275. -- 可写文件目录中的文件是否存在
  276. function isWritableFileExist(fileName)
  277. return cc.FileSystem:fileExists(writablePath .. fileName);
  278. end
  279. -- 从可写文件目录读取一个文件的原始数据
  280. function getWritableFileData(fileName)
  281. local targetPath = writablePath .. fileName;
  282. local f = io.open(targetPath , "rb");
  283. if f then
  284. local data = f:read("*a");
  285. f:close();
  286. return data;
  287. else
  288. return nil;
  289. end
  290. end
  291. -- ROM中的文件是否存在
  292. function isRomFileExist(fileName)
  293. local isExist = cc.FileSystem:fileExists(fileName);
  294. return isExist;
  295. end
  296. -- 从ROM读取原始文件数据
  297. function getRomFileData(fileName)
  298. return cc.FileSystem:readData(fileName);
  299. end
  300. -- 判断某个文件是否存在
  301. function isFileExist(fileName)
  302. return isWritableFileExist(fileName) or isRomFileExist(fileName);
  303. end
  304. function isLuaFuleExist(fileName)
  305. return cc.FileUtils:getInstance():isFileExist( fileName .. ".luac") or cc.FileUtils:getInstance():isFileExist( fileName .. ".lua")
  306. end
  307. -- 获取文件内容
  308. function getFileData(fileName)
  309. if isWritableFileExist(fileName) then
  310. return getWritableFileData(fileName)
  311. elseif isRomFileExist(fileName) then
  312. return getRomFileData(fileName)
  313. else
  314. return nil
  315. end
  316. end
  317. -- 把一个字符串分割成数组
  318. function split(szFullString, szSeparator)
  319. local nFindStartIndex = 1
  320. local nSplitIndex = 1
  321. local nSplitArray = {}
  322. while true do
  323. local nFindLastIndex, endIndex= string.find(szFullString, szSeparator, nFindStartIndex)
  324. if not nFindLastIndex then
  325. nSplitArray[nSplitIndex] = string.sub(szFullString, nFindStartIndex, string.len(szFullString))
  326. break
  327. end
  328. nSplitArray[nSplitIndex] = string.sub(szFullString, nFindStartIndex, nFindLastIndex - 1)
  329. nFindStartIndex = endIndex + 1;
  330. nSplitIndex = nSplitIndex + 1
  331. end
  332. return nSplitArray
  333. end
  334. function table_nums(t)
  335. local count = 0
  336. for k, v in pairs(t) do
  337. count = count + 1
  338. end
  339. return count
  340. end
  341. local function sortFunc(a,b)
  342. local numA = tonumber(a)
  343. local numB = tonumber(b)
  344. if numA ~= nil and numB ~= nil then
  345. return numA < numB
  346. else
  347. return a < b
  348. end
  349. end
  350. -- 根据Key排序 :从小到大
  351. function pairsByKeys (t)
  352. local a = {}
  353. for n in pairs(t) do table.insert(a, n) end
  354. table.sort(a, sortFunc)
  355. local i = 0 -- iterator variable
  356. local iter = function () -- iterator function
  357. i = i + 1
  358. if a[i] == nil then
  359. return nil
  360. else
  361. return a[i], t[a[i]]
  362. end
  363. end
  364. return iter
  365. end
  366. local function sortFuncEx(a,b)
  367. local numA = tonumber(a)
  368. local numB = tonumber(b)
  369. if numA ~= nil and numB ~= nil then
  370. return numA > numB
  371. else
  372. return a > b
  373. end
  374. end
  375. -- 根据Key排序(从大到小)
  376. function pairsByKeysEx (t)
  377. local a = {}
  378. for n in pairs(t) do table.insert(a, n) end
  379. table.sort(a, sortFuncEx)
  380. local i = 0 -- iterator variable
  381. local iter = function () -- iterator function
  382. i = i + 1
  383. if a[i] == nil then
  384. return nil
  385. else
  386. return a[i], t[a[i]]
  387. end
  388. end
  389. return iter
  390. end
  391. -- 将 path 中的 str_old 替换为 str_new
  392. -- IOS 的路径中包含'-'符号,使用 string.gsub 进行替换会失败
  393. -- 所有手动写一个替换的接口,用于转换路径
  394. function replace_path(path, str_old, str_new)
  395. local len_old = string.len(str_old)
  396. local len_new = string.len(str_new)
  397. local file = string.sub(path,len_old + 1,-1)
  398. local path_new = str_new .. file
  399. return path_new;
  400. end
  401. -- 删除目录以及目录下的所有文件
  402. function remove_dir(path)
  403. for file in lfs.dir(path) do
  404. if file ~= "." and file ~= ".." then
  405. local f = path..'/'..file
  406. local attr = lfs.attributes (f)
  407. assert (type(attr) == "table")
  408. if attr.mode == "directory" then
  409. if remove_dir(f) == false then
  410. return false;
  411. end
  412. else
  413. os.remove(f);
  414. end
  415. end
  416. end
  417. lfs.rmdir(path)
  418. return true;
  419. end
  420. -- 遍历dir中的所有文件,rev表示是否遍历子目录,fun回调文件名
  421. function for_dir (path, fun)
  422. for file in lfs.dir(path) do
  423. if file ~= "." and file ~= ".." then
  424. local f = path..'/'..file
  425. -- logD(f)
  426. local attr = lfs.attributes (f)
  427. assert (type(attr) == "table")
  428. if attr.mode == "directory" then
  429. if for_dir (f,fun) == false then
  430. return false;
  431. end
  432. else
  433. -- logD(file)
  434. if fun(f, file, path) == false then
  435. return false;
  436. end
  437. end
  438. end
  439. end
  440. return true;
  441. end
  442. function move_file(file_source, file_target)
  443. --logD("PreloadTools::move_file() file_source = " .. tostring(file_source))
  444. --logD("PreloadTools::move_file() file_target = " .. tostring(file_target))
  445. if not cc.FileUtils:getInstance():isFileExist(file_source) then
  446. logD("PreloadTools::move_file() file_source is not exist : " .. tostring(file_source))
  447. return false
  448. end
  449. -- 删除旧的文件
  450. if cc.FileUtils:getInstance():isFileExist(file_target) then
  451. logD("PreloadTools::move_file() remove old file : " .. tostring(file_target))
  452. os.remove(file_target);
  453. end
  454. -- 替换成新的文件
  455. local ret1, ret2= os.rename(file_source, file_target)
  456. if not ret1 then
  457. logD("PreloadTools::move_file() move file failed, ret2 = " .. tostring(ret2) .. ", source = " .. file_source .. ", target = " .. file_target)
  458. return false;
  459. end
  460. return true;
  461. end
  462. -- 移动目录下的所有文件到指定目录
  463. function move_dir(path_source, path_target)
  464. logD("PreloadTools::move_dir() path_source = " .. tostring(path_source))
  465. logD("PreloadTools::move_dir() path_target = " .. tostring(path_target))
  466. if not path_source or not path_target then
  467. return false
  468. end
  469. if not cc.FileUtils:getInstance():isDirectoryExist(path_target) then
  470. if not cc.FileUtils:getInstance():createDirectory(path_target) then
  471. logD("PreloadTools::move_dir() createDirectory failed " .. path_target)
  472. return false
  473. end
  474. end
  475. local ret = true;
  476. local version_files = {}
  477. for_dir(path_source, function(fullpath, file, dir)
  478. --logD("PreloadTools::move_dir() for_dir: " .. fullpath)
  479. local dirNew = replace_path(dir, path_source, path_target)
  480. local fullpathNew = replace_path(fullpath, path_source, path_target)
  481. --logD("PreloadTools::move_dir() for_dir: dirNew = " .. dirNew)
  482. --logD("PreloadTools::move_dir() for_dir: fullpathNew = " .. fullpathNew)
  483. if not cc.FileUtils:getInstance():isDirectoryExist(dirNew) then
  484. --logD("PreloadTools::move_dir() create directory : " .. tostring(dirNew))
  485. if not cc.FileUtils:getInstance():createDirectory(dirNew) then
  486. logD("PreloadTools::move_dir() create directory failed :" .. dirNew)
  487. ret = false;
  488. end
  489. end
  490. -- 版本文件最后处理
  491. if file == "version.json" then
  492. table.insert(version_files, {fullpath = fullpath, fullpathNew = fullpathNew})
  493. return
  494. end
  495. -- 移动文件
  496. if not move_file(fullpath, fullpathNew) then
  497. ret = false
  498. end
  499. --logD("PreloadTools::move_dir() move file successed, source = " .. fullpath .. ", target = " .. fullpathNew)
  500. end)
  501. logD("PreloadTools::move_dir() ret = " .. tostring(ret))
  502. -- 移动文件成功之后,最后才移动版本文件
  503. if ret then
  504. if #version_files > 0 then
  505. for _,v in pairs(version_files) do
  506. --logI("PreloadTools::move_dir() move file, source = " .. v.fullpath .. ", target = " .. v.fullpathNew)
  507. if not move_file(v.fullpath, v.fullpathNew) then
  508. logD("PreloadTools::move_dir() move file failed, source = " .. v.fullpath .. ", target = " .. v.fullpathNew)
  509. end
  510. end
  511. end
  512. end
  513. logD("PreloadTools::move_dir() finished")
  514. return ret;
  515. end
  516. -- 在下一帧执行一次函数func
  517. function runInNextFrame(func , ...)
  518. local id
  519. local arg = {...}
  520. local function exec()
  521. cc.Director:getInstance():getScheduler():unscheduleScriptEntry(id);
  522. func(unpack(arg));
  523. end
  524. id = cc.Director:getInstance():getScheduler():scheduleScriptFunc(exec, 0, false)
  525. end
  526. function runDelayWithTime(func, mtime)
  527. local id
  528. local function exec()
  529. cc.Director:getInstance():getScheduler():unscheduleScriptEntry(id);
  530. func();
  531. end
  532. id = cc.Director:getInstance():getScheduler():scheduleScriptFunc(exec, tonumber(mtime), false)
  533. return id
  534. end
  535. function isIpV6Format(ip)
  536. local ret = string.find(ip, "%:")
  537. return ret ~= nil
  538. end
  539. function getHostByUrl(url)
  540. logD("getHostByUrl()", url)
  541. local isHost = false;
  542. local isHttps = false
  543. local withHead = string.find(url, "https")
  544. if withHead and withHead > 0 then
  545. isHttps = true
  546. end
  547. local withHead = string.find(url, "http")
  548. if withHead and withHead > 0 then
  549. url = string.gsub(url, "http://", "");
  550. url = string.gsub(url, "https://", "");
  551. end
  552. local arr1 = split(url, "/")
  553. local host = ""
  554. if arr1 and #arr1 > 0 then
  555. host = arr1[1]
  556. end
  557. local arr2 = split(host, "%.")
  558. if arr2 and #arr2 > 0 then
  559. local num = tonumber(arr2[1])
  560. if num == nil then
  561. isHost = true
  562. end
  563. end
  564. logD("getHostByUrl()", isHost, host)
  565. return isHost, host ,isHttps;
  566. end
  567. -- callback = function(host, ip)
  568. function getHostAndIpByUrl(url, callback)
  569. logD("getHostAndIpByUrl()", url)
  570. local function doCallback(host, ip)
  571. logD("getHostAndIpByUrl() doCallback()", host, ip)
  572. if callback then
  573. callback(host, ip)
  574. end
  575. end
  576. local isHost, host ,isHttps = getHostByUrl(url)
  577. -- 如果不包含域名,则返回空
  578. if not isHost then
  579. doCallback();
  580. return;
  581. end
  582. if PluginHttpDns and targetPlatform >= 3 and targetPlatform <= 5 then
  583. local function onHttpDnsResponse(strResult)
  584. logD("onHttpDnsResponse() strResult = ", tostring(strResult));
  585. -- 解析结果
  586. local jsonResult = json.decode(tostring(strResult))
  587. if not jsonResult then
  588. logD("onHttpDnsResponse() jsonResult is nil")
  589. return doCallback();
  590. end
  591. -- 检查错误码
  592. local code = tonumber(jsonResult.code)
  593. if code ~= 8001 then
  594. return doCallback();
  595. end
  596. logD("onHttpDnsResponse() message = ", tostring(jsonResult.message))
  597. -- 解析内容
  598. local jsonMessage = json.decode(jsonResult.message)
  599. if not jsonMessage then
  600. logD("onHttpDnsResponse() jsonMessage is nil")
  601. return doCallback();
  602. end
  603. if type(jsonMessage) == "table" then
  604. for k,v in pairs(jsonMessage) do
  605. logD(k,v)
  606. end
  607. local ip = jsonMessage[1]
  608. return doCallback(host, ip);
  609. else
  610. logD("type of jsonMessage is ",type(jsonMessage));
  611. return doCallback();
  612. end
  613. end
  614. local params =
  615. {
  616. host = isHttps and "https://"..host or "http://"..host,
  617. callback = onHttpDnsResponse
  618. }
  619. PluginHttpDns:callVoid("getIpByHostWithNormal", params);
  620. else
  621. doCallback();
  622. end
  623. end
  624. -- callback = function(url, headers)
  625. function converUrlToIp(url, callback)
  626. logD("converUrlToIp() url = ", url)
  627. local function doCallback(urlNew, header)
  628. logD("converUrlToIp() doCallback() ", urlNew)
  629. if callback then
  630. callback( urlNew or url, header)
  631. end
  632. end
  633. -- 微信头像不使用HTTPDNS
  634. local strWeiXin = "thirdwx.qlogo.cn"
  635. local ret = string.find(url, strWeiXin)
  636. if ret then
  637. logD("converUrlToIp() return by thirdwx.qlogo.cn");
  638. return doCallback();
  639. end
  640. -- 如果明确指示不使用HTTPDNS
  641. if RomSetting.withoutHttpDns then
  642. logD("converUrlToIp() return by withoutHttpDns");
  643. return doCallback();
  644. end
  645. -- 查询这个url中的host和Ip,并进行处理
  646. getHostAndIpByUrl(url, function(host, ip)
  647. if host and ip then
  648. local isIpV6 = isIpV6Format(ip)
  649. if isIpV6 then
  650. ip = "[" .. ip .. "]"
  651. end
  652. local urlNew = string.gsub(url, host, ip);
  653. local header = {
  654. Host = host,
  655. }
  656. doCallback(urlNew, header)
  657. else
  658. doCallback()
  659. end
  660. end)
  661. end
  662. -- 递交一个http post请求,通过callback返回
  663. -- handlerCallback: 返回 post 的句柄
  664. function httpPost(url , postTable , callback, handlerCallback)
  665. --logD("httpPost() url = ", url)
  666. converUrlToIp(url, function(urlNew, header)
  667. -- -- 添加md5验证 begin
  668. -- if postTable.action ~= "system.init" then
  669. local key_table = {}
  670. --取出所有的键
  671. for key,_ in pairs(postTable) do
  672. table.insert(key_table,key)
  673. end
  674. --对所有键进行排序
  675. local str = ""
  676. table.sort(key_table)
  677. for _,key in pairs(key_table) do
  678. if _ == #key_table then
  679. local Md5key = "s#z7*wk^z(m2u%er@vgf8h&ds#)|sg";
  680. str = str..""..key.."="..postTable[key].."&".."key="..Md5key
  681. else
  682. str = str..""..key.."="..postTable[key].."&"
  683. end
  684. end
  685. print("输出"..str)
  686. local signtoken = md5.sumhexa( str )
  687. local signtokenLower = string.lower(signtoken);
  688. print("输出signtoken小写"..signtokenLower)
  689. postTable.signtoken = signtokenLower
  690. -- end
  691. -- 添加md5验证 end
  692. header = header or {}
  693. header["Expect"] = ""
  694. logD("httpPost() url = ", url)
  695. logD("httpPost() urlNew = ", urlNew)
  696. if table and table.tostring then
  697. logD("httpPost() header = ", table.tostring(header))
  698. logD("httpPost() postTable = ", table.tostring(postTable))
  699. else
  700. for k,v in pairs(header) do
  701. logD(string.format("httpPost() header: %s = %s ", k, v))
  702. end
  703. for k,v in pairs(postTable) do
  704. logD(string.format("httpPost() postTable: %s = %s ", k, v))
  705. end
  706. end
  707. local taskId = cc.CURLManager:getInstance():createPostTask(urlNew , header, postTable , callback)
  708. if handlerCallback then
  709. handlerCallback(taskId)
  710. end
  711. end)
  712. end
  713. --- 递交一个带自定义头的post请求
  714. function httpPostWithHeader(url, header, postFields, callback)
  715. return cc.CURLManager:getInstance():createPostTask(url , header, postFields , callback)
  716. end
  717. function closeHttpPost(id)
  718. if id then
  719. cc.CURLManager:getInstance():cancelTask(id);
  720. end
  721. end
  722. -- 创建下载任务,如果下载失败,就用ip地址下载
  723. function downloadFileByUrls(urls , onUpdate , priority , startPos , dataSize)
  724. urls = split(urls , ",");
  725. priority = priority or 0;
  726. startPos = startPos or 0;
  727. dataSize = dataSize or 0;
  728. local index = 1;
  729. local function createTask(url,onUpdateFirst)
  730. converUrlToIp(url, function(urlNew, header)
  731. cc.CURLManager:getInstance():createHeaderTask(urlNew ,header, onUpdateFirst , priority , startPos , dataSize);
  732. end)
  733. end
  734. local function onUpdateFirst(status , data)
  735. -- 解析域名失败
  736. if status == "failed" and urls[index + 1] ~= nil then
  737. logD("使用首选地址下载文件失败" , urls[index] , onUpdateFirst , priority , startPos , dataSize);
  738. index = index + 1;
  739. logD("使用备用地址开始下载文件" , urls[index] , onUpdateFirst , priority , startPos , dataSize);
  740. createTask(urls[index],onUpdateFirst)
  741. else
  742. onUpdate(status , data);
  743. end
  744. end
  745. logD("创建下载任务" , urls[index] , onUpdateFirst , priority , startPos , dataSize);
  746. createTask(urls[index],onUpdateFirst)
  747. end
  748. function downloadFileByUrls2(urls , onUpdate , fileName , dataSize)
  749. urls = split(urls , ",");
  750. fileName = fileName or "";
  751. dataSize = dataSize or 0;
  752. local index = 1;
  753. local function createTask(url,onUpdateFirst)
  754. converUrlToIp(url, function(urlNew, header)
  755. cc.CurlFileTaskManager:getInstance():createHeaderTask(urlNew , header , onUpdateFirst , fileName , dataSize);
  756. end)
  757. end
  758. local function onUpdateFirst(status , data)
  759. -- 下载失败
  760. if status == "failed" and urls[index + 1] ~= nil then
  761. logD("使用首选地址下载文件失败" , urls[index] , onUpdateFirst , fileName , dataSize);
  762. index = index + 1;
  763. logD("使用备用地址开始下载文件" , urls[index] , onUpdateFirst , fileName , dataSize);
  764. createTask(urls[index] , onUpdateFirst)
  765. else
  766. onUpdate(status , data);
  767. end
  768. end
  769. logD("创建下载任务" , urls[index] , onUpdateFirst , fileName , dataSize);
  770. createTask(urls[index] , onUpdateFirst)
  771. end
  772. function saveStringToFile(strText, fileName)
  773. if not fileName or fileName == "" then
  774. return
  775. end
  776. local targetPath = writablePath .. fileName;
  777. local f , err = io.open(targetPath , "wb");
  778. if f then
  779. f:write(strText or "");
  780. f:close();
  781. return true;
  782. else
  783. return false , err;
  784. end
  785. end
  786. function loadStringFromFile(fileName)
  787. if not fileName or fileName == "" then
  788. return ""
  789. end
  790. local strText = getWritableFileData(fileName);
  791. return strText;
  792. end
  793. function saveUserId(userId)
  794. cc.UserDefault:getInstance():setStringForKey("UserId", userId);
  795. end
  796. function loadUserId()
  797. local userId = cc.UserDefault:getInstance():getStringForKey("UserId");
  798. return userId or "";
  799. end
  800. -- 显示错误界面
  801. function showErrorView(errorString, onClickOk)
  802. local view = require("preload.AutoUpdate.ErrorView"):new(errorString, onClickOk);
  803. local director = cc.Director:getInstance();
  804. local mainScene = director:getRunningScene()
  805. mainScene:addChild(view.ui);
  806. end
  807. -- 显示一个提示界面
  808. function showTipsView(tipsMessage, onOkCallback, onCancelCallback)
  809. local view = require("preload.AutoUpdate.TipsView"):new(tipsMessage, onOkCallback, onCancelCallback);
  810. local director = cc.Director:getInstance();
  811. local mainScene = director:getRunningScene()
  812. mainScene:addChild(view.ui);
  813. end
  814. -- 获取唯一字符串
  815. function guid()
  816. local seed = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}
  817. local tb = {}
  818. for i = 1,32 do
  819. table.insert(tb, seed[math.random(1,16)])
  820. end
  821. local sid = table.concat(tb)
  822. return sid
  823. end
  824. function guid16()
  825. local seed = {'0','1','2','3','4','5','6','7','8','9'}
  826. local tb = {}
  827. for i = 1,16 do
  828. table.insert(tb, seed[math.random(1,10)])
  829. end
  830. local sid = table.concat(tb)
  831. return sid
  832. end
  833. -- 检查文件列表中的文件是否都存在
  834. --[[
  835. files_list_file : 记录文件列表的文件
  836. files_list =
  837. {
  838. [filename] = md5_value,
  839. [filename] = md5_value,
  840. [filename] = md5_value,
  841. [filename] = md5_value,
  842. },
  843. 如果文件完整,return true, nil
  844. 如果文件缺失, return false, missing_file_list
  845. --]]
  846. function checkFilesExist(files_list_file)
  847. logD("PreloadTools::checkFilesExist(), files_list_file = ", tostring(files_list_file))
  848. -- 文件是否存在
  849. local isExist = isFileExist(files_list_file)
  850. if not isExist then
  851. logE("PreloadTools::checkFilesExist() files_list_file is not exist");
  852. return false, {}
  853. end
  854. -- 读取文件内容
  855. local filestring = getFileData(files_list_file)
  856. if not filestring or filestring == "" then
  857. logE("PreloadTools::checkFilesExist() filestring is nil or empty");
  858. return false, {}
  859. end
  860. -- 解密文件内容
  861. local jsonString = base64.decode(filestring)
  862. if not jsonString or jsonString == "" then
  863. logE("PreloadTools::checkFilesExist() jsonString is nil or empty");
  864. return false, {};
  865. end
  866. -- 转 json object
  867. local jsonData = json.decode(jsonString);
  868. if not jsonData then
  869. logE("PreloadTools::checkFilesExist() jsonData is nil");
  870. return false, {};
  871. end
  872. -- 打印文件列表
  873. --[[
  874. for k,v in pairs(jsonData) do
  875. logD(v, " : ", k)
  876. end
  877. --]]
  878. local ret = true
  879. local missing_file_list = {}
  880. for fileName,v in pairs(jsonData) do
  881. -- 之前的文件列表中,文件名是以"/"开头的,这会让C++认为这是一个完整路径
  882. local firstChar = string.sub(fileName, 1, 1)
  883. if firstChar == "/" then
  884. fileName = string.sub(fileName, 2)
  885. end
  886. local isExist = isFileExist(fileName)
  887. --logD(string.format("checkFilesExist(), ret = %s, fileName = %s", tostring(isExist), tostring(fileName)));
  888. if not isExist then
  889. ret = false
  890. missing_file_list[fileName] = v
  891. end
  892. end
  893. logD("checkFilesExist(), ret = ", tostring(ret))
  894. for fileName,v in pairs(missing_file_list) do
  895. logD(string.format("checkFilesExist(), ret = false, fileName = %s", tostring(fileName)));
  896. end
  897. return ret, missing_file_list
  898. end
  899. local g_phpUrl=nil
  900. local g_phpUrlIdx = 0
  901. local g_phpUrlList = {}
  902. -- 设置当前使用成功的phpUrl
  903. local function setGlobalPhpUrl(url)
  904. logD("setGlobalPhpUrl() ", url)
  905. g_phpUrl = url
  906. end
  907. function getGlobalPhpUrl()
  908. return g_phpUrl or RomSetting.phpUrl
  909. end
  910. -- 保存最后一次使用成功的 phpUrl
  911. local function saveLastPhpUrl(url)
  912. logD("saveLastPhpUrl() ", url)
  913. cc.UserDefault:getInstance():setStringForKey("lastPhpUrl", url or "")
  914. end
  915. -- 读取最后一次使用成功的 phpUrl
  916. local function loadLastPhpUrl()
  917. local lastPhpUrl = cc.UserDefault:getInstance():getStringForKey("lastPhpUrl", "")
  918. logD("loadLastPhpUrl() ", lastPhpUrl)
  919. return lastPhpUrl
  920. end
  921. function initGlobalPhpUrlList()
  922. --local isReview = cc.UserDefault:getInstance():getBoolForKey("isReview", true);
  923. -- 加载上次成功的phpUrl
  924. local lastPhpUrl = loadLastPhpUrl()
  925. -- if lastPhpUrl and lastPhpUrl ~= "" then
  926. -- table.insert(g_phpUrlList, lastPhpUrl)
  927. -- end
  928. -- 按顺序加载配置中的phpUrl
  929. if RomSetting.phpUrl then
  930. table.insert(g_phpUrlList, RomSetting.phpUrl)
  931. end
  932. if RomSetting.phpUrl_1 then
  933. table.insert(g_phpUrlList, RomSetting.phpUrl_1)
  934. end
  935. if RomSetting.phpUrl_2 then
  936. table.insert(g_phpUrlList, RomSetting.phpUrl_2)
  937. end
  938. if RomSetting.phpUrl_3 then
  939. table.insert(g_phpUrlList, RomSetting.phpUrl_3)
  940. end
  941. for k,v in pairs(g_phpUrlList) do
  942. logD("initGlobalPhpUrlList", tostring(v))
  943. end
  944. end
  945. initGlobalPhpUrlList()
  946. -- callback : function(true/false)
  947. -- useNextUrl :是否使用下一个url
  948. function getServerConfigs(callback, useNextUrl)
  949. logD("getServerConfigs(), useNextUrl = ", tostring(useNextUrl))
  950. local function doCallback(isSuccessed)
  951. if callback then
  952. callback(isSuccessed)
  953. end
  954. end
  955. -- 获取当前要使用的phpUrl
  956. if useNextUrl then
  957. g_phpUrlIdx = g_phpUrlIdx + 1
  958. end
  959. local curPhpUrl = g_phpUrlList[g_phpUrlIdx]
  960. if not curPhpUrl then
  961. logE("getServerConfigs() curPhpUrl is nil")
  962. doCallback(false)
  963. return;
  964. end
  965. logD("getServerConfigs(), curPhpUrl = ", curPhpUrl)
  966. local uid = loadUserId();
  967. local apkver = tostring(getAppVersion());
  968. local resver = loadVersion();
  969. local params =
  970. {
  971. appid = tostring(RomSetting.AppId),
  972. apkType = tonumber(RomSetting.ChannelId),
  973. uid = uid;
  974. apkver = apkver,
  975. vername = apkver,
  976. resver = resver,
  977. isnew = 1,
  978. }
  979. for k,v in pairs(params) do
  980. logD("getServerConfigs() params: " .. tostring(k) .. " = " .. tostring(v))
  981. end
  982. local PasswordKey = "s#z7*wk^z(m2u%er@vgf8h&ds#)|sg";
  983. local RandomString = guid16();
  984. local strParams1 = json.encode(params)
  985. logD("params:",strParams1);
  986. local strParams2 = base64.encode(md5.crypt(strParams1, PasswordKey, RandomString))
  987. local tt =
  988. {
  989. action = "system.init",
  990. p = strParams2,
  991. }
  992. isResponse = false
  993. local function onHttpResponse(status, response)
  994. logD("getServerConfigs:onHttpResponse()", tostring(status), tostring(response))
  995. -- 标记为收到回复了,不需要关系回复的数据是否正确
  996. isResponse = true
  997. if status ~= "successed" then
  998. logE("getServerConfigs:onHttpResponse() status not successed")
  999. getServerConfigs(callback, true)
  1000. return
  1001. end
  1002. local jsonData = json.decode(response)
  1003. if not jsonData then
  1004. logE("getServerConfigs:onHttpResponse() jsonData is nil")
  1005. getServerConfigs(callback, true)
  1006. return
  1007. end
  1008. if jsonData.code ~= 200 then
  1009. logE("getServerConfigs:onHttpResponse() jsonData.code == ", jsonData.code)
  1010. if jsonData.code == -105 then
  1011. -- 停服公告
  1012. showTipsView("系统维护中,请稍后重试!", function()
  1013. cc.Application:getInstance():shutdown();
  1014. end)
  1015. else
  1016. getServerConfigs(callback, true)
  1017. end
  1018. return
  1019. end
  1020. if not jsonData.result then
  1021. logE("getServerConfigs:onHttpResponse() jsonData.result is nil")
  1022. getServerConfigs(callback, true)
  1023. return;
  1024. end
  1025. local strResult = md5.decrypt(base64.decode(jsonData.result), PasswordKey);
  1026. logD("getServerConfigs:onHttpResponse() strResult = ", strResult)
  1027. local jsonResult = json.decode(strResult);
  1028. if not jsonResult or type(jsonResult) ~= "table" then
  1029. logE("getServerConfigs:onHttpResponse() jsonResult is not valid")
  1030. getServerConfigs(callback, true)
  1031. return
  1032. end
  1033. -- 记录当前可用的phpUrl
  1034. saveLastPhpUrl(curPhpUrl)
  1035. setGlobalPhpUrl(curPhpUrl)
  1036. -- 保存服务器配置信息
  1037. for k,v in pairs(jsonResult) do
  1038. PhpSetting[k] = v
  1039. end
  1040. --PhpSetting.gameServer = "47.107.98.44:9240"
  1041. -- 保存服务器下发的审核状态
  1042. -- 如果本地是审核状态,而现在服务器下发时非审核状态,则保存状态后重启
  1043. local curReviewStatus = isReviewVersion()
  1044. local newReviewStatus = tonumber(PhpSetting.isAudit) == 1
  1045. if curReviewStatus ~= newReviewStatus then
  1046. saveIsReview(newReviewStatus)
  1047. logD("getServerConfigs:onHttpResponse() RomSetting.ChannelId = " .. tostring(RomSetting.ChannelId))
  1048. logD("getServerConfigs:onHttpResponse() RomSetting.IosReviewType = " .. tostring(RomSetting.IosReviewType))
  1049. if RomSetting.IosReviewType and RomSetting.IosReviewType ~= 1 then
  1050. logD("getServerConfigs:onHttpResponse() 审核版本转非审核版本")
  1051. showTipsView("点击确定退出游戏,再次启动游戏即可", function()
  1052. cc.Application:getInstance():shutdown();
  1053. end)
  1054. return;
  1055. end
  1056. end
  1057. -- 如果服务器要求上传日志,则立刻上传
  1058. if jsonResult.upload_log ~= nil and jsonResult.upload_log ~= "" then
  1059. logD("getServerConfigs::onHttpResponse() upload_log = ", upload_log);
  1060. if logFileManager then
  1061. logD("getServerConfigs::onHttpResponse() request upload");
  1062. logFileManager:uploadFilesByDay(tostring(jsonResult.upload_log))
  1063. end
  1064. end
  1065. doCallback(true)
  1066. end
  1067. --[[
  1068. 存在一种情况,HttpDns初始化的时间比较长,可能达到15甚至20s.
  1069. HttpDns返回结果的时候,脚本已经在使用ip连接了。
  1070. 然后HttpDns的回调又会触发host连接。
  1071. 这样就有了两个连接,且都是有效的。
  1072. 导致后面更新出现一些重复的流程而产生问题
  1073. --]]
  1074. logD("getServerConfigs() 打印0")
  1075. local taskId;
  1076. local function onCreatePostCallback(id)
  1077. taskId = id;
  1078. runDelayWithTime(function()
  1079. logD("getServerConfigs() 打印1")
  1080. if not isResponse then --没有数据回来 默认超时
  1081. logD("getServerConfigs() 打印2")
  1082. -- 取消之前的连接
  1083. if taskId then
  1084. logD("getServerConfigs() 打印3")
  1085. cc.CURLManager:getInstance():cancelTask(taskId)
  1086. end
  1087. -- 换一个地址来尝试
  1088. getServerConfigs(callback, true)
  1089. end
  1090. end, 5)
  1091. end
  1092. httpPost(curPhpUrl, tt, onHttpResponse, onCreatePostCallback);
  1093. end