x2Fusion

Untitled

Dec 30th, 2022
1,706
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 63.37 KB | None | 0 0
  1. xyd = xyd or {}
  2. xyd.db = xyd.db or {}
  3. local socket = require("socket")
  4. local gettime = socket.gettime
  5. local json = require("cjson")
  6. local string_find = string.find
  7. local Application = UnityEngine.Application
  8. local PlayerPrefs = UnityEngine.PlayerPrefs
  9. local SetString = PlayerPrefs.SetString
  10. local GetString = PlayerPrefs.GetString
  11. local SetInt = PlayerPrefs.SetInt
  12. local GetInt = PlayerPrefs.GetInt
  13. local HasKey = PlayerPrefs.HasKey
  14. local Save = PlayerPrefs.Save
  15. local DeleteKey = PlayerPrefs.DeleteKey
  16. local LoadSceneMode = UnityEngine.SceneManagement.LoadSceneMode
  17. local ANDROID_FILE = "Android"
  18. local VERSION_FILE = "version.json"
  19. local VERSION_FILE_32 = "version_32.json"
  20. local SAVE_VERSION = "__version__"
  21. local SAVE_TMP_VERSION = "__tmp__version__"
  22. local TMP_RES_PATH = "__tmp__res__"
  23. local SAVE_FAILED_URL_TYPE = "__save_failed_url_type_%s_%s__"
  24. local SAVE_ERROR_VERSION = "__error_version__"
  25. local SAVE_CHANGE_ROUTE = "__save_change_route__"
  26. local OS_ANDROID = 1
  27. local OS_IOS = 2
  28. local ADD_COUNTER = 0
  29. local DOWNLOAD_THREADS_NUM = 8
  30. local LAZY_LUA_DOWNLOAD_PREFIX = XYDDef.LazyLuaDownloadPrefix
  31. local LAZY_LZ4_DOWNLOAD_PREFIX = XYDDef.LazyLz4DownloadPrefix
  32. local LAZY_WEB_DOWNLOAD_PREFIX = XYDDef.LazyWebDownloadPrefix
  33. local BACK_UPDATE_WEB_DOWNLOAD_PREFIX = "__back_update_web_download__"
  34. local STANDBY_URL_EFFECT_TIME = 86400
  35.  
  36. local function isPkgVersionUp(versionB)
  37.     local versionA = UnityEngine.Application.version
  38.  
  39.     return XYDUtils.CompVersion(versionA, versionB) > 0
  40. end
  41.  
  42. local function is3rdPkg()
  43.     local pkgName = XYDDef.PkgName
  44.  
  45.     return pkgName == "com.yottagames.tgmafia"
  46. end
  47.  
  48. local function xpcall2(func, ...)
  49.     xpcall(func, function (err)
  50.         print(err)
  51.     end, ...)
  52. end
  53.  
  54. local GM_CHAT_ENABLED = isPkgVersionUp("1.1.18")
  55. local CDN_URLS_ENABLED = isPkgVersionUp("1.1.105")
  56. local THIRD_AUTO_UPDATE = isPkgVersionUp("1.1.105") and is3rdPkg()
  57. local GM_CHAT_PLAYER_ID_ENABLED = isPkgVersionUp("1.1.195")
  58. local UrlUsageType = {
  59.     CDN = "cdn",
  60.     GATE = "gate",
  61.     BACKEND = "backend"
  62. }
  63. local UrlType = {
  64.     AKAMAI = 2,
  65.     GCP = 3,
  66.     NORMAL = 1
  67. }
  68. local BACKEND_URLS = {
  69.     [UrlType.NORMAL] = "http://mafia2back.yottagames.com",
  70.     [UrlType.AKAMAI] = "https://mafia2back-aka.yottagames.com",
  71.     [UrlType.GCP] = "https://mafia2back-gc.yottagames.com"
  72. }
  73. local GATE_URLS = {
  74.     [UrlType.NORMAL] = "mafia2gate.yottagames.com",
  75.     [UrlType.AKAMAI] = "mafia2gate-aka.yottagames.com",
  76.     [UrlType.GCP] = "mafia2gate-gc.yottagames.com"
  77. }
  78. local CDN_URLS = {
  79.     [UrlType.NORMAL] = "http://mafia2cdn.yottagames.com",
  80.     [UrlType.AKAMAI] = "https://yottacdn.akamaized.net/mafia2ycdn",
  81.     [UrlType.GCP] = "https://mafia2cdn-gc.yottagames.com"
  82. }
  83. local URLS = {
  84.     [UrlUsageType.BACKEND] = BACKEND_URLS,
  85.     [UrlUsageType.CDN] = CDN_URLS,
  86.     [UrlUsageType.GATE] = GATE_URLS
  87. }
  88. xyd.package2Language = {
  89.     ["com.yottagames.gameofmafia"] = {
  90.         en_us = 1,
  91.         zh_tw = 1
  92.     },
  93.     ["com.yottagames.tgmafia"] = {
  94.         en_us = 1,
  95.         zh_tw = 1
  96.     },
  97.     ["com.yottagames.gameofmafiatest"] = {
  98.         en_us = 1,
  99.         zh_tw = 1
  100.     },
  101.     ["com.yottagames.gameofmafiatr"] = {
  102.         en_us = 1
  103.     },
  104.     ["com.yottagames.gameofmafiajp"] = {
  105.         en_us = 1,
  106.         ja_jp = 1,
  107.         zh_tw = 1
  108.     },
  109.     ["com.yottagames.gameofmafiakr"] = {
  110.         en_us = 1,
  111.         ko_kr = 1
  112.     }
  113. }
  114. xyd.package2LineID = {
  115.     ["com.yottagames.gameofmafiatr"] = "TheGrandMafia",
  116.     ["com.yottagames.gameofmafia"] = "TheGrandMafia",
  117.     ["com.yottagames.gameofmafiajp"] = "TheGrandMafia",
  118.     ["com.yottagames.gameofmafiatest"] = "TheGrandMafia",
  119.     ["com.yottagames.tgmafia"] = "TheGrandMafia",
  120.     ["com.yottagames.gameofmafiakr"] = "TheGrandMafia"
  121. }
  122.  
  123. if GetInt("__IS__UPDATING__", 0) <= 0 then
  124.     require("base.functions")
  125.     require("app.xinyoudi")
  126. end
  127.  
  128. local sqlite3 = require("sqlite3")
  129. local DownloadInfo = class("DownloadInfo")
  130.  
  131. function DownloadInfo:ctor()
  132. end
  133.  
  134. function DownloadInfo:createTable()
  135.     self.db:exec([[
  136.         CREATE TABLE IF NOT EXISTS downloadinfo (
  137.             path TEXT NOT NULL PRIMARY KEY,
  138.             version TEXT NOT NULL,
  139.             size INT NOT NULL DEFAULT 0,
  140.             downloadedSize INT NOT NULL DEFAULT 0
  141.         );
  142.     ]])
  143. end
  144.  
  145. function DownloadInfo:openDB(dbName)
  146.     if self.dbName ~= dbName and self.db then
  147.         self:close()
  148.     end
  149.  
  150.     if self.db == nil or not self.db:isopen() then
  151.         self.dbName = dbName
  152.         local dbfile = XYDDef.DatabasePath .. dbName
  153.         self.db = sqlite3.open(dbfile)
  154.  
  155.         if self.db == nil then
  156.             os.remove(dbfile)
  157.  
  158.             self.db = sqlite3.open(dbfile)
  159.         end
  160.  
  161.         self.db:exec("            PRAGMA synchronous=OFF;\n            PRAGMA temp_store = 2;\n        ")
  162.         self:createTable()
  163.     end
  164. end
  165.  
  166. function DownloadInfo:getAll()
  167.     local stmt = self.db:prepare("SELECT * FROM downloadinfo")
  168.     local downloads = {}
  169.  
  170.     for row in stmt:nrows() do
  171.         local path = row.path
  172.         downloads[path] = row
  173.     end
  174.  
  175.     stmt:finalize()
  176.  
  177.     return downloads
  178. end
  179.  
  180. function DownloadInfo:add(downloadInfo)
  181.     if downloadInfo == nil then
  182.         return
  183.     end
  184.  
  185.     local db = self.db
  186.  
  187.     if self.addStmt == nil then
  188.         self.addStmt = db:prepare("            INSERT OR REPLACE INTO downloadinfo (path, version, size, downloadedSize) VALUES (?, ?, ?, ?)\n        ")
  189.     end
  190.  
  191.     local stmt = self.addStmt
  192.  
  193.     stmt:bind_values(downloadInfo.path, downloadInfo.version, downloadInfo.size, downloadInfo.downloadedSize)
  194.  
  195.     local res = stmt:step()
  196.  
  197.     if db:errcode() ~= 101 then
  198.         print(db:errcode())
  199.         print(db:errmsg())
  200.     end
  201.  
  202.     stmt:reset()
  203. end
  204.  
  205. function DownloadInfo:begin()
  206.     self.db:exec("        BEGIN;\n    ")
  207.  
  208.     self.inTransaction = true
  209. end
  210.  
  211. function DownloadInfo:commit()
  212.     if not self.inTransaction then
  213.         return
  214.     end
  215.  
  216.     self.db:exec("        COMMIT;\n    ")
  217.  
  218.     self.inTransaction = false
  219. end
  220.  
  221. function DownloadInfo:truncate()
  222.     self.db:exec("        DROP TABLE downloadinfo;\n    ")
  223.     self:createTable()
  224. end
  225.  
  226. function DownloadInfo:close()
  227.     if self.addStmt ~= nil then
  228.         self.addStmt:finalize()
  229.  
  230.         self.addStmt = nil
  231.     end
  232.  
  233.     if self.db and self.db:isopen() then
  234.         self.db:close()
  235.     end
  236.  
  237.     self.db = nil
  238. end
  239.  
  240. local LocalMd5Info = class("LocalMd5Info")
  241.  
  242. function LocalMd5Info:ctor()
  243. end
  244.  
  245. function LocalMd5Info:createTable()
  246.     self.db:exec([[
  247.         CREATE TABLE IF NOT EXISTS res_md5 (
  248.             path TEXT NOT NULL,
  249.             md5 TEXT NOT NULL,
  250.             PRIMARY KEY (path)
  251.         );
  252.     ]])
  253. end
  254.  
  255. function LocalMd5Info:openDB(dbName)
  256.     if self.dbName ~= dbName and self.db then
  257.         self:close()
  258.     end
  259.  
  260.     if self.db == nil or not self.db:isopen() then
  261.         self.dbName = dbName
  262.         local dbfile = XYDDef.DatabasePath .. dbName
  263.         self.db = sqlite3.open(dbfile)
  264.  
  265.         if self.db == nil then
  266.             os.remove(dbfile)
  267.  
  268.             self.db = sqlite3.open(dbfile)
  269.         end
  270.  
  271.         self.db:exec("            PRAGMA synchronous=OFF;\n            PRAGMA temp_store = 2;\n        ")
  272.         self:createTable()
  273.     end
  274. end
  275.  
  276. function LocalMd5Info:getAllLocalMd5s()
  277.     local result = {}
  278.  
  279.     local function func()
  280.         local stmt = self.db:prepare("            SELECT * FROM res_md5\n        ")
  281.         local count = 0
  282.  
  283.         for row in stmt:nrows() do
  284.             result[row.path] = row.md5
  285.             count = count + 1
  286.         end
  287.  
  288.         stmt:finalize()
  289.     end
  290.  
  291.     xpcall2(func)
  292.  
  293.     return result
  294. end
  295.  
  296. function LocalMd5Info:removeLocalMd5(path)
  297.     local function func()
  298.         local stmt = self.db:prepare("            DELETE FROM res_md5 WHERE path = ?\n        ")
  299.  
  300.         stmt:bind_values(path)
  301.         stmt:step()
  302.  
  303.         if self.db:errcode() ~= 101 then
  304.             print(self.db:errcode())
  305.             print(self.db:errmsg())
  306.         end
  307.  
  308.         stmt:reset()
  309.     end
  310.  
  311.     xpcall2(func)
  312. end
  313.  
  314. function LocalMd5Info:setLocalMd5(path, md5)
  315.     local function func()
  316.         local stmt = self.db:prepare("            INSERT OR REPLACE INTO res_md5 (path, md5) VALUES (?, ?)\n        ")
  317.  
  318.         stmt:bind_values(path, md5)
  319.         stmt:step()
  320.  
  321.         if self.db:errcode() ~= 101 then
  322.             print(self.db:errcode())
  323.             print(self.db:errmsg())
  324.         end
  325.  
  326.         stmt:reset()
  327.     end
  328.  
  329.     xpcall2(func)
  330. end
  331.  
  332. function LocalMd5Info:getLocalMd5(path)
  333.     local r = nil
  334.  
  335.     local function func()
  336.         local stmt = self.db:prepare("            SELECT md5 FROM res_md5 WHERE path = ?\n        ")
  337.  
  338.         stmt:bind_values(path)
  339.  
  340.         for row in stmt:nrows() do
  341.             r = row.md5
  342.  
  343.             break
  344.         end
  345.  
  346.         stmt:finalize()
  347.     end
  348.  
  349.     xpcall2(func)
  350.  
  351.     return r
  352. end
  353.  
  354. function LocalMd5Info:close()
  355.     if self.db and self.db:isopen() then
  356.         self.db:close()
  357.     end
  358.  
  359.     self.db = nil
  360. end
  361.  
  362. local UpdateController = {
  363.     run = function (self)
  364.         xyd.isLoadingFinish = false
  365.         self.urls_ = {}
  366.         self.urlTypes_ = {}
  367.         self.urlFailedTimes_ = {}
  368.         self.urlUsageSucceed_ = {}
  369.         self.usedUrlTypes_ = {}
  370.  
  371.         self:initVersion()
  372.         self:initLastAccountInfo()
  373.  
  374.         if UNITY_ANDROID or UNITY_IOS then
  375.             self:waitShowAutoRepairWindow("UpdateController:run")
  376.         end
  377.  
  378.         self:initRecommendedUrlTypes()
  379.         self:initTranslation()
  380.  
  381.         if xyd.db.downloadInfo == nil then
  382.             xyd.db.downloadInfo = DownloadInfo.new()
  383.             xyd.db.backDownloadInfo = DownloadInfo.new()
  384.  
  385.             print("xyd.db.backDownloadInfo is nil?:", xyd.db.backDownloadInfo == nil)
  386.         end
  387.  
  388.         if xyd.db.localMd5Info == nil then
  389.             xyd.db.localMd5Info = LocalMd5Info.new()
  390.  
  391.             xyd.db.localMd5Info:openDB("local_md5.db")
  392.         end
  393.  
  394.         if UNITY_ANDROID or UNITY_IOS then
  395.             self:checkUpdate()
  396.         else
  397.             xyd.isLoadingFinish = true
  398.             xyd.res_version = "1.0.657"
  399.             xyd.backendurl = "mafia2back.xunmenginc.com:80"
  400.  
  401.             self:startGame(false)
  402.         end
  403.     end,
  404.     initVersion = function (self)
  405.         if not self.packageVersion_ or self.packageVersion_ == "" then
  406.             self.packageVersion_ = UnityEngine.Application.version
  407.         end
  408.  
  409.         if not self.savedVersion_ or self.savedVersion_ == "" then
  410.             self.savedVersion_ = GetString(SAVE_VERSION, "")
  411.         end
  412.  
  413.         if self.savedVersion_ ~= "" and not FileUtils.IsResInData(VERSION_FILE) then
  414.             self.savedVersion_ = ""
  415.  
  416.             SetString(SAVE_VERSION, "")
  417.             FileUtils.DeleteResDirectory("src")
  418.             FileUtils.DeleteResDirectory("sdkchat")
  419.         end
  420.  
  421.         if not self.resourceVersion_ or self.resourceVersion_ == "" then
  422.             if self.savedVersion_ and self.savedVersion_ ~= "" then
  423.                 self.resourceVersion_ = self.savedVersion_
  424.             else
  425.                 self.resourceVersion_ = self.packageVersion_
  426.             end
  427.  
  428.             xyd.res_version = self.resourceVersion_
  429.         end
  430.     end,
  431.     roundNum = function (self, value)
  432.         value = tonumber(value) or 0
  433.  
  434.         return math.floor(value + 0.5)
  435.     end,
  436.     checkUpdate = function (self)
  437.         self:logGameLoginEvent("checkUpdate, will check version", 101)
  438.         UIManager.SetLoadingProgress(0.3, 0.05, false)
  439.         UIManager.SetLoadingVersion(self:getResourceVersion())
  440.         self:retrieveVersionInfo()
  441.     end,
  442.     clearTmpVersionFiles = function (self, tmp)
  443.         DeleteKey(SAVE_TMP_VERSION)
  444.         Save()
  445.         FileUtils.DeleteFileDirectory(TMP_RES_PATH)
  446.     end,
  447.     retrieveVersionInfo = function (self)
  448.         local os_id = OS_ANDROID
  449.         local device_id = XYDSDK.Instance:GetDeviceID()
  450.  
  451.         if UNITY_ANDROID then
  452.             os_id = OS_ANDROID
  453.         elseif UNITY_IOS then
  454.             os_id = OS_IOS
  455.         end
  456.  
  457.         print("retrieveVersionInfo:", os_id, device_id)
  458.  
  459.         self.backendRequestUrl_ = self:getBackendRequestUrl()
  460.         local params = {
  461.             mid = 2,
  462.             test_id = 1,
  463.             os_id = os_id,
  464.             device_id = device_id,
  465.             app_v = self:getPackageVersion(),
  466.             res_v = self:getResourceVersion(),
  467.             bundle_id = XYDDef.PkgName
  468.         }
  469.  
  470.         if UNITY_2020 then
  471.             params.test_id = 2
  472.             params.u_v = 2020
  473.         end
  474.  
  475.         local backendRequestUrl = self.backendRequestUrl_
  476.  
  477.         self:webRequest(self.backendRequestUrl_, params, function (response, success, httpCode)
  478.             if backendRequestUrl == self.backendRequestUrl_ then
  479.                 if success then
  480.                     local payload = response.payload
  481.                     local errorCode = payload.error_code
  482.  
  483.                     if errorCode ~= nil then
  484.                         print("error_code: " .. errorCode)
  485.                         self:recordUrlFailed(UrlUsageType.BACKEND)
  486.                         self:onWebRequestCheckVersionError(httpCode, response)
  487.                     else
  488.                         self:clearUrlFailed(UrlUsageType.BACKEND)
  489.                         self:onWebRequestCheckVersionSuccess(response)
  490.                     end
  491.                 else
  492.                     self:recordUrlFailed(UrlUsageType.BACKEND)
  493.                     self:onWebRequestCheckVersionError(httpCode, response)
  494.                 end
  495.             end
  496.         end)
  497.     end,
  498.     onWebRequestCheckVersionSuccess = function (self, response)
  499.         local payload = response.payload
  500.         local serverVersion = payload.curr_version
  501.         local minPkgVersion = payload.min_version
  502.         local minHotVersion = payload.min_hot_version or "0.1.68"
  503.         self.serverVersion_ = serverVersion
  504.         self.isMaintenance_ = payload.is_maintenance
  505.  
  506.         self:logGameLoginEvent("checkUpdate, get server version", 102)
  507.         print("backendurl", payload.backendurl)
  508.  
  509.         xyd.backendurl = payload.backendurl
  510.         self.updateTitle_ = payload.title or ""
  511.         self.updateContent_ = payload.content or ""
  512.         local versionUrl = self:getServerVersionUrl(serverVersion)
  513.         local currentVersion = self:getResourceVersion()
  514.         local pkgVersion = self:getPackageVersion()
  515.  
  516.         print("currentVersion: " .. currentVersion .. ",  serverVersion: " .. serverVersion .. ", pkgVersion: " .. pkgVersion .. ", minPkgVersion: " .. minPkgVersion .. ", minHotVersion: " .. minHotVersion .. ", versionUrl: " .. versionUrl)
  517.  
  518.         xyd.os_id = tonumber(payload.os_id)
  519.         xyd.test_id = tonumber(payload.test_id)
  520.  
  521.         if self.savedVersion_ == "" then
  522.             self:setPackageLazyDownloadInfos()
  523.             self:setResourceVersion(pkgVersion)
  524.         else
  525.             self:setLocalLazyDownloadInfos()
  526.         end
  527.  
  528.         self:waitShowAutoRepairWindow("UpdateController:onWebRequestCheckVersionSuccess")
  529.  
  530.         if XYDUtils.CompVersion(currentVersion, serverVersion) >= 0 then
  531.             self:onCheckVersionComplete(false)
  532.         elseif XYDUtils.CompVersion(minPkgVersion, pkgVersion) > 0 then
  533.             if THIRD_AUTO_UPDATE then
  534.                 UIManager.ShowConfirmAlert(__("FRIEND_TIP"), __("NEED_UPDATE_PACKAGE"), __("OK"), false, function ()
  535.                     XYDSDK.Instance:UpdateAppBySDK()
  536.                 end)
  537.             else
  538.                 UIManager.ShowConfirmAlert(__("FRIEND_TIP"), __("NEED_GO_APPSTORE"), __("OK"), false, function ()
  539.                     Application.OpenURL(xyd.pkgUpdateURL)
  540.                 end)
  541.             end
  542.         else
  543.             local tmpVersion = self:getTmpVersion()
  544.             local tmpVersionPath = self:getTmpFilePath(VERSION_FILE)
  545.             local isTmpVersionExist = FileUtils.IsFileInData(tmpVersionPath)
  546.  
  547.             if XYDUtils.CompVersion(tmpVersion, currentVersion) > 0 and isTmpVersionExist then
  548.                 self:copyTmpVersionFiles()
  549.             elseif XYDUtils.CompVersion(currentVersion, minHotVersion) >= 0 then
  550.                 local errorVersion = self:getErrorVersion()
  551.  
  552.                 if XYDUtils.CompVersion(serverVersion, errorVersion) ~= 0 then
  553.                     SetString(SAVE_ERROR_VERSION, "")
  554.                     Save()
  555.  
  556.                     xyd.needBackUpdate = true
  557.                     xyd.backUpdateParams = {
  558.                         curr_version = serverVersion,
  559.                         min_version = minPkgVersion
  560.                     }
  561.                 end
  562.  
  563.                 self:onCheckVersionComplete(false)
  564.             else
  565.                 self:waitShowAutoRepairWindow("UpdateController:forceDownloadVersionFile")
  566.                 self:forceDownloadVersionFile()
  567.             end
  568.         end
  569.     end,
  570.     getServerVersionUrl = function (self, serverVersion)
  571.         local versionUrl = ""
  572.  
  573.         if UNITY_2020 then
  574.             if UNITY_IOS then
  575.                 if jit.arch == "arm" then
  576.                     versionUrl = XYDUtils.CdnUrl() .. "version_ios" .. serverVersion .. "_32_2020.json"
  577.                 else
  578.                     versionUrl = XYDUtils.CdnUrl() .. "version_ios" .. serverVersion .. "_2020.json"
  579.                 end
  580.             elseif UNITY_ANDROID then
  581.                 if jit.arch == "arm" then
  582.                     versionUrl = XYDUtils.CdnUrl() .. "version_android" .. serverVersion .. "_32_2020.json"
  583.                 else
  584.                     versionUrl = XYDUtils.CdnUrl() .. "version_android" .. serverVersion .. "_2020.json"
  585.                 end
  586.             end
  587.         elseif UNITY_IOS then
  588.             if jit.arch == "arm" then
  589.                 versionUrl = XYDUtils.CdnUrl() .. "version_ios" .. serverVersion .. "_32.json"
  590.             else
  591.                 versionUrl = XYDUtils.CdnUrl() .. "version_ios" .. serverVersion .. ".json"
  592.             end
  593.         elseif UNITY_ANDROID then
  594.             if jit.arch == "arm" then
  595.                 versionUrl = XYDUtils.CdnUrl() .. "version_android" .. serverVersion .. "_32.json"
  596.             else
  597.                 versionUrl = XYDUtils.CdnUrl() .. "version_android" .. serverVersion .. ".json"
  598.             end
  599.         end
  600.  
  601.         return versionUrl
  602.     end,
  603.     setCurrentVersionInfos = function (self, versionInfos)
  604.         if self.currentVersionInfos_ == nil then
  605.             self.currentVersionInfos_ = versionInfos
  606.             self.allLocalMd5s_ = xyd.db.localMd5Info:getAllLocalMd5s()
  607.         elseif self.currentVersionInfos_ ~= versionInfos then
  608.             self.currentVersionInfos_ = versionInfos
  609.             local usedMd5s = {}
  610.             local path, md5 = nil
  611.  
  612.             for _, versionInfo in ipairs(versionInfos.resources) do
  613.                 path = versionInfo.path
  614.                 md5 = self.allLocalMd5s_[path]
  615.  
  616.                 if md5 then
  617.                     usedMd5s[path] = md5
  618.                     self.allLocalMd5s_[path] = nil
  619.                 end
  620.             end
  621.  
  622.             local unusedMd5s = self.allLocalMd5s_
  623.             self.allLocalMd5s_ = usedMd5s
  624.  
  625.             for path, md5 in pairs(unusedMd5s) do
  626.                 xyd.db.localMd5Info:removeLocalMd5(path)
  627.             end
  628.         end
  629.     end,
  630.     getCurrentVersionInfos = function (self)
  631.         if not self.currentVersionInfos_ and FileUtils.IsResInData(VERSION_FILE) then
  632.             local str = FileUtils.ReadResStringInData(VERSION_FILE)
  633.             local status, versionInfos = pcall(json.decode, str)
  634.  
  635.             if status then
  636.                 self:setCurrentVersionInfos(versionInfos)
  637.             end
  638.         end
  639.  
  640.         return self.currentVersionInfos_
  641.     end,
  642.     getTmpVersion = function (self)
  643.         return GetString(SAVE_TMP_VERSION, "")
  644.     end,
  645.     getTmpFilePath = function (self, path)
  646.         return TMP_RES_PATH .. "/" .. path
  647.     end,
  648.     setTmpVersion = function (self, version, versionStr)
  649.         FileUtils.WriteFile(self:getTmpFilePath(VERSION_FILE), versionStr)
  650.         SetString(SAVE_TMP_VERSION, version)
  651.         Save()
  652.     end,
  653.     copyTmpVersionFiles = function (self, serverVersionInfos, updateVersionInfos)
  654.         local afterForceDownload = serverVersionInfos ~= nil
  655.         local tmpVersion = self:getTmpVersion()
  656.         local tmpVersionPath = self:getTmpFilePath(VERSION_FILE)
  657.  
  658.         if not serverVersionInfos and not updateVersionInfos then
  659.             local jsonStr = FileUtils.ReadFileStringInData(tmpVersionPath)
  660.             serverVersionInfos = json.decode(jsonStr)
  661.             updateVersionInfos = self:getUpdateVersionInfos(serverVersionInfos)
  662.         end
  663.  
  664.         SetInt("__IS__UPDATING__", 1)
  665.         Save()
  666.         self:updateTmpRes(updateVersionInfos, function ()
  667.             FileUtils.CopyFile2Res(tmpVersionPath, VERSION_FILE)
  668.             self:setCurrentVersionInfos(serverVersionInfos)
  669.             self:setResourceVersion(tmpVersion)
  670.             self:clearTmpVersionFiles()
  671.             UIManager.SetLoadingVersion(tmpVersion)
  672.             SetInt("__IS__UPDATING__", 0)
  673.             Save()
  674.             self:onCheckVersionComplete(true)
  675.         end, afterForceDownload)
  676.     end,
  677.     getUpdateVersionInfos = function (self, newVersionInfos)
  678.         local currentVersionInfos = self:getCurrentVersionInfos()
  679.         local updateVersionInfos = {}
  680.         local currentVersionTable = {}
  681.         local path, md5, type, downloadInfo = nil
  682.  
  683.         for _, versionInfo in pairs(currentVersionInfos.resources) do
  684.             path = versionInfo.path
  685.             md5 = versionInfo.md5
  686.             currentVersionTable[path .. md5] = versionInfo
  687.         end
  688.  
  689.         local newVersion = newVersionInfos.version
  690.  
  691.         for _, versionInfo in pairs(newVersionInfos.resources) do
  692.             path = versionInfo.path
  693.             type = versionInfo.type
  694.             md5 = versionInfo.md5
  695.  
  696.             if currentVersionTable[path .. md5] == nil then
  697.                 downloadInfo = {
  698.                     path = path,
  699.                     type = type,
  700.                     md5 = md5,
  701.                     res = versionInfo.res,
  702.                     size = versionInfo.size,
  703.                     version = newVersion
  704.                 }
  705.  
  706.                 if type == 1 or type == 2 or type == 3 then
  707.                     table.insert(updateVersionInfos, downloadInfo)
  708.                 elseif type == 4 then
  709.                     if HasKey(BACK_UPDATE_WEB_DOWNLOAD_PREFIX .. path) then
  710.                         table.insert(updateVersionInfos, downloadInfo)
  711.                     else
  712.                         SetString(LAZY_WEB_DOWNLOAD_PREFIX .. path, json.encode(downloadInfo))
  713.                     end
  714.                 end
  715.             end
  716.         end
  717.  
  718.         Save()
  719.  
  720.         return updateVersionInfos
  721.     end,
  722.     setLocalLazyDownloadInfos = function (self)
  723.         local currentVersionInfos = self:getCurrentVersionInfos()
  724.  
  725.         if not currentVersionInfos then
  726.             print("=======checkLocalLazyDownloadInfos==json=====failed=====")
  727.  
  728.             return
  729.         end
  730.  
  731.         local time1 = gettime()
  732.         local path, type, md5, downloadInfo = nil
  733.         local version = currentVersionInfos.version
  734.  
  735.         for _, versionInfo in pairs(currentVersionInfos.resources) do
  736.             path = versionInfo.path
  737.             type = versionInfo.type
  738.             md5 = versionInfo.md5
  739.  
  740.             if type == 4 then
  741.                 if not HasKey(LAZY_WEB_DOWNLOAD_PREFIX .. path) and not FileUtils.IsResInData(path) then
  742.                     downloadInfo = {
  743.                         path = path,
  744.                         type = type,
  745.                         md5 = md5,
  746.                         res = versionInfo.res,
  747.                         size = versionInfo.size,
  748.                         version = version
  749.                     }
  750.  
  751.                     SetString(LAZY_WEB_DOWNLOAD_PREFIX .. path, json.encode(downloadInfo))
  752.                 end
  753.             elseif type == 3 and not HasKey(LAZY_WEB_DOWNLOAD_PREFIX .. path) and not FileUtils.IsResInData(path) and not FileUtils.IsResInApp(path) then
  754.                 downloadInfo = {
  755.                     path = path,
  756.                     type = type,
  757.                     md5 = md5,
  758.                     res = versionInfo.res,
  759.                     size = versionInfo.size,
  760.                     version = version
  761.                 }
  762.  
  763.                 SetString(LAZY_WEB_DOWNLOAD_PREFIX .. path, json.encode(downloadInfo))
  764.             end
  765.         end
  766.  
  767.         local time2 = gettime()
  768.  
  769.         print("set local lazy time", time2 - time1)
  770.     end,
  771.     setPackageLazyDownloadInfos = function (self)
  772.         local fileName = jit.arch == "arm" and VERSION_FILE_32 or VERSION_FILE
  773.  
  774.         if not FileUtils.IsResInApp(fileName) then
  775.             print("error no version file in app!!")
  776.  
  777.             return
  778.         end
  779.  
  780.         local currentVersionStr = FileUtils.ReadResStringInApp(fileName)
  781.  
  782.         FileUtils.WriteRes(VERSION_FILE, currentVersionStr)
  783.  
  784.         local currentVersionInfos = json.decode(currentVersionStr)
  785.  
  786.         self:setCurrentVersionInfos(currentVersionInfos)
  787.  
  788.         local time1 = gettime()
  789.         local path, type, md5, downloadInfo = nil
  790.         local version = currentVersionInfos.version
  791.  
  792.         for _, versionInfo in pairs(currentVersionInfos.resources) do
  793.             path = versionInfo.path
  794.             type = versionInfo.type
  795.             md5 = versionInfo.md5
  796.  
  797.             if type == 2 or type == 3 or type == 4 then
  798.                 downloadInfo = {
  799.                     path = path,
  800.                     type = type,
  801.                     md5 = md5,
  802.                     res = versionInfo.res,
  803.                     size = versionInfo.size,
  804.                     version = version
  805.                 }
  806.  
  807.                 if type == 2 then
  808.                     if not FileUtils.IsResInApp(path) then
  809.                         SetString(LAZY_LUA_DOWNLOAD_PREFIX .. path, json.encode(downloadInfo))
  810.                     end
  811.                 elseif type == 3 then
  812.                     if not FileUtils.IsResInApp(path) then
  813.                         SetString(LAZY_WEB_DOWNLOAD_PREFIX .. path, json.encode(downloadInfo))
  814.                     end
  815.                 elseif type == 4 then
  816.                     SetString(LAZY_WEB_DOWNLOAD_PREFIX .. path, json.encode(downloadInfo))
  817.                 end
  818.             end
  819.         end
  820.  
  821.         local time2 = gettime()
  822.  
  823.         print("set package lazy time", time2 - time1)
  824.     end,
  825.     onLanguageLoaded = function (self, restart, reloadLang)
  826.         if self.isMaintenance_ == 1 then
  827.             if self.updateTitle_ == "" or self.updateContent_ == "" then
  828.                 UIManager.ShowConfirmAlert(__("FRIEND_TIP"), __("SERVER_MAINTENANCE"), __("OK"), false, function ()
  829.                     XYDUtils.QuitGame()
  830.                 end)
  831.             else
  832.                 self:showAnnounce(function ()
  833.                     XYDUtils.QuitGame()
  834.                 end)
  835.             end
  836.         elseif restart then
  837.             self:restartGame()
  838.         else
  839.             self:logGameLoginEvent("checkUpdate, start preload", 105)
  840.  
  841.             local time1 = gettime()
  842.  
  843.             print("start preloadAbs")
  844.             ResManager.PreloadABsAsync(function (success, obj)
  845.                 xyd.isLoadingFinish = true
  846.  
  847.                 self:logGameLoginEvent("checkUpdate, finish preload", 106)
  848.  
  849.                 local time2 = gettime()
  850.  
  851.                 print("finish preloadAbs", time2 - time1)
  852.  
  853.                 if xyd.isLoginInfoReceived then
  854.                     xyd.EventDispatcher.inner():dispatchEvent({
  855.                         name = xyd.event.GAME_START
  856.                     })
  857.                 end
  858.             end)
  859.             self:startGame(reloadLang)
  860.         end
  861.     end,
  862.     onCheckVersionComplete = function (self, needRestart)
  863.         local pkgName = XYDDef.PkgName
  864.         local languages = xyd.package2Language[pkgName]
  865.         local languageKey = LAZY_LUA_DOWNLOAD_PREFIX .. "src/data/tables/translation_" .. xyd.lang .. ".lua"
  866.  
  867.         if not languages[xyd.lang] and HasKey(languageKey) then
  868.             local updateVersions = {}
  869.             local languageVersionStr = GetString(languageKey, "")
  870.  
  871.             if languageVersionStr ~= "" then
  872.                 local downloadInfo = json.decode(languageVersionStr)
  873.  
  874.                 table.insert(updateVersions, downloadInfo)
  875.             end
  876.  
  877.             self:logGameLoginEvent("checkUpdate, start download translation", 103)
  878.             self:downloadTranslation(updateVersions, function ()
  879.                 self:logGameLoginEvent("checkUpdate, translation downloaded", 104)
  880.                 self:onLanguageLoaded(needRestart, true)
  881.             end)
  882.         else
  883.             self:onLanguageLoaded(needRestart, false)
  884.         end
  885.     end,
  886.     forceDownloadVersionFile = function (self)
  887.         local versionUrl = self:getServerVersionUrl(self.serverVersion_)
  888.  
  889.         print("versionUrl:", versionUrl)
  890.         ResManager.DownloadString(versionUrl, function (status, response)
  891.             if status == DownloadStatus.Success then
  892.                 self:clearUrlFailed(UrlUsageType.CDN)
  893.                 SetInt("__IS__UPDATING__", 1)
  894.                 Save()
  895.  
  896.                 local serverVersionInfos = json.decode(response)
  897.                 local updateVersionInfos = self:getUpdateVersionInfos(serverVersionInfos)
  898.  
  899.                 self:updateRes(updateVersionInfos, __("UPDATING"), function ()
  900.                     self:setTmpVersion(self.serverVersion_, response)
  901.                     SetInt("__IS__UPDATING__", 0)
  902.                     Save()
  903.                     self:copyTmpVersionFiles(serverVersionInfos, updateVersionInfos)
  904.                 end, true)
  905.  
  906.                 return
  907.             end
  908.  
  909.             if status == DownloadStatus.Failed then
  910.                 self:recordUrlFailed(UrlUsageType.CDN)
  911.  
  912.                 local failedTimes = self:getUrlFailedTimes(UrlUsageType.CDN) + 1
  913.  
  914.                 print("===Update Error===: download version json failed(e:002) -- url:" .. versionUrl .. " failedTimes:" .. failedTimes)
  915.  
  916.                 failedTimes = self:setUrlFailedTimes(UrlUsageType.CDN, failedTimes)
  917.  
  918.                 local function callbackTodo()
  919.                     self:forceDownloadVersionFile()
  920.                 end
  921.  
  922.                 if failedTimes >= 2 then
  923.                     self:showAutoRepairWindow({
  924.                         strErrorCode = "(e:002)",
  925.                         urlUsageType = "cdn",
  926.                         callbackTodo = callbackTodo
  927.                     })
  928.                 else
  929.                     callbackTodo()
  930.                 end
  931.             end
  932.         end)
  933.     end,
  934.     getUrlFailedTimes = function (self, urlUsageType)
  935.         return self.urlFailedTimes_[urlUsageType] or 0
  936.     end,
  937.     setUrlFailedTimes = function (self, urlUsageType, failedTimes)
  938.         self.urlFailedTimes_[urlUsageType] = failedTimes
  939.  
  940.         if failedTimes >= 2 then
  941.             if not self.urlUsageSucceed_[urlUsageType] then
  942.                 if urlUsageType ~= UrlUsageType.CDN or CDN_URLS_ENABLED then
  943.                     local currentUrlType = self:getUrlType(urlUsageType)
  944.                     local urlType = self:getRecommendedUrlType(urlUsageType)
  945.  
  946.                     if currentUrlType ~= urlType then
  947.                         self:setUrlType(urlUsageType, urlType)
  948.  
  949.                         self.urlFailedTimes_[urlUsageType] = 0
  950.  
  951.                         print("change url:", urlUsageType, currentUrlType, urlType)
  952.                     end
  953.                 end
  954.             else
  955.                 print("this url usage type was succeed, can not change", self.urlUsageSucceed_[urlUsageType])
  956.             end
  957.         end
  958.  
  959.         return self.urlFailedTimes_[urlUsageType]
  960.     end,
  961.     recordUrlFailed = function (self, urlUsageType)
  962.         local urlType = self:getUrlType(urlUsageType)
  963.         local failedTime = os.time()
  964.  
  965.         SetInt(string.format(SAVE_FAILED_URL_TYPE, urlUsageType, urlType), failedTime)
  966.         print("recordUrlFailed", urlUsageType, urlType)
  967.     end,
  968.     clearUrlFailed = function (self, urlUsageType)
  969.         local succeedUrlType = self:getUrlType(urlUsageType)
  970.  
  971.         self:setUrlFailedTimes(urlUsageType, 0)
  972.  
  973.         if not self.urlUsageSucceed_[urlUsageType] or self.urlUsageSucceed_[urlUsageType] ~= succeedUrlType then
  974.             self.urlUsageSucceed_[urlUsageType] = succeedUrlType
  975.  
  976.             SetInt(string.format(SAVE_FAILED_URL_TYPE, urlUsageType, succeedUrlType), 0)
  977.             print("clearUrlFailed", urlUsageType, succeedUrlType)
  978.         end
  979.     end,
  980.     getFailedUrlType = function (self, urlUsageType, urlType)
  981.         return GetInt(string.format(SAVE_FAILED_URL_TYPE, urlUsageType, urlType), 0)
  982.     end,
  983.     initRecommendedUrlTypes = function (self)
  984.         local setUsage = {}
  985.         local savedRoute = GetInt(SAVE_CHANGE_ROUTE, 0)
  986.  
  987.         if savedRoute <= 0 or savedRoute >= 4 then
  988.             savedRoute = 1
  989.         end
  990.  
  991.         local currentTime = os.time()
  992.         local defaultType = UrlType.NORMAL
  993.  
  994.         for _, usage in pairs(UrlUsageType) do
  995.             local num = self:getFailedUrlType(usage, defaultType)
  996.  
  997.             if num <= 0 or STANDBY_URL_EFFECT_TIME <= currentTime - num then
  998.                 print("init default url", usage, defaultType)
  999.                 self:setUrlType(usage, defaultType)
  1000.  
  1001.                 setUsage[usage] = true
  1002.             end
  1003.         end
  1004.  
  1005.         for _, usage in pairs(UrlUsageType) do
  1006.             if not setUsage[usage] then
  1007.                 local num = self:getFailedUrlType(usage, savedRoute)
  1008.  
  1009.                 if num <= 0 then
  1010.                     print("init saved url", usage, savedRoute)
  1011.                     self:setUrlType(usage, savedRoute)
  1012.  
  1013.                     setUsage[usage] = true
  1014.                 end
  1015.             end
  1016.         end
  1017.  
  1018.         for _, usage in pairs(UrlUsageType) do
  1019.             if not setUsage[usage] then
  1020.                 local targetType = UrlType.NORMAL
  1021.  
  1022.                 for urlType = UrlType.AKAMAI, UrlType.GCP do
  1023.                     local num = self:getFailedUrlType(usage, urlType)
  1024.  
  1025.                     if num <= 0 then
  1026.                         targetType = urlType
  1027.  
  1028.                         break
  1029.                     end
  1030.                 end
  1031.  
  1032.                 print("init url", usage, targetType)
  1033.                 self:setUrlType(usage, targetType)
  1034.             end
  1035.         end
  1036.     end,
  1037.     getRecommendedUrlType = function (self, urlUsageType)
  1038.         local urls = URLS[urlUsageType]
  1039.  
  1040.         for urlType, url in pairs(urls) do
  1041.             local num = self:getFailedUrlType(urlUsageType, urlType)
  1042.  
  1043.             if num <= 0 then
  1044.                 return urlType
  1045.             end
  1046.         end
  1047.  
  1048.         local usedUrlTypes = self.usedUrlTypes_[urlUsageType] or {}
  1049.  
  1050.         for urlType, url in pairs(urls) do
  1051.             if not usedUrlTypes[urlType] then
  1052.                 return urlType
  1053.             end
  1054.         end
  1055.  
  1056.         return self:getUrlType(urlUsageType) or UrlType.NORMAL
  1057.     end,
  1058.     onWebRequestCheckVersionError = function (self, httpCode, response)
  1059.         self:delayWaitShowAutoRepairWindow()
  1060.         self:logGameLoginEvent("checkUpdate, get server version, " .. self.backendRequestUrl_, 107)
  1061.  
  1062.         local failedTimes = self:getUrlFailedTimes(UrlUsageType.BACKEND) + 1
  1063.  
  1064.         print("===Update Error===: check version failed(e:001), failed times: " .. failedTimes .. ", url: " .. self.backendRequestUrl_)
  1065.  
  1066.         failedTimes = self:setUrlFailedTimes(UrlUsageType.BACKEND, failedTimes)
  1067.  
  1068.         local function callbackTodo()
  1069.             self:retrieveVersionInfo()
  1070.         end
  1071.  
  1072.         if failedTimes >= 2 then
  1073.             self:reportMessageToBackupPlatform("001", httpCode, response.payload, self.backendRequestUrl_)
  1074.             self:showAutoRepairWindow({
  1075.                 strErrorCode = "(e:001)",
  1076.                 urlUsageType = "backend",
  1077.                 callbackTodo = callbackTodo
  1078.             })
  1079.         else
  1080.             callbackTodo()
  1081.         end
  1082.     end,
  1083.     waitShowAutoRepairWindow = function (self, event, time)
  1084.         self.waitShowAutoRepairWindowEvent_ = event
  1085.         self.waitShowAutoRepairWindowTime_ = time or 30
  1086.  
  1087.         XYDCo.StopWait("WaitShowAutoRepair")
  1088.         XYDCo.WaitForTime(self.waitShowAutoRepairWindowTime_, function ()
  1089.             local windows = {
  1090.                 "ui_alert",
  1091.                 "ui_account_banned",
  1092.                 "ui_update_announce",
  1093.                 "ui_auto_repair",
  1094.                 "ui_auto_repair_res",
  1095.                 "ui_chat_sdk_window"
  1096.             }
  1097.  
  1098.             for _, window in ipairs(windows) do
  1099.                 if UIManager.IsOpen(window) then
  1100.                     print("wait show auto repair:", window .. " window is open")
  1101.  
  1102.                     return
  1103.                 end
  1104.             end
  1105.  
  1106.             print("wait show auto repair event:", self.waitShowAutoRepairWindowEvent_)
  1107.  
  1108.             local params = {
  1109.                 strErrorCode = "(e:009)",
  1110.                 urlUsageType = "backend",
  1111.                 callbackTodo = function ()
  1112.                     print("wait show auto repair error!!")
  1113.                 end
  1114.             }
  1115.  
  1116.             self:showAutoRepairWindow(params)
  1117.  
  1118.             self.waitShowAutoRepairWindowEvent_ = nil
  1119.             self.waitShowAutoRepairWindowTime_ = nil
  1120.         end, "WaitShowAutoRepair")
  1121.     end,
  1122.     delayWaitShowAutoRepairWindow = function (self)
  1123.         if self.waitShowAutoRepairWindowEvent_ and self.waitShowAutoRepairWindowTime_ then
  1124.             self:waitShowAutoRepairWindow(self.waitShowAutoRepairWindowEvent_, self.waitShowAutoRepairWindowTime_)
  1125.         end
  1126.     end,
  1127.     stopWaitShowAutoRepairWindow = function (self, event)
  1128.         print("stop wait show auto repair event:", event)
  1129.         XYDCo.StopWait("WaitShowAutoRepair")
  1130.     end,
  1131.     showAutoRepairWindow = function (self, params)
  1132.         params = params or {}
  1133.         local callbackTodo = params.callbackTodo
  1134.         local strErrorCode = params.strErrorCode
  1135.         local globalPlayerID = params.globalPlayerID
  1136.         local urlUsageType = params.urlUsageType
  1137.         local urls = params.urls
  1138.         local gameLoginEvents = params.gameLoginEvents or {}
  1139.  
  1140.         UIManager.ShowAlert(__("FRIEND_TIP"), __("NOT_CONNECTED") .. strErrorCode, __("RETRY"), __("AUTO_REPAIR"), false, function (yes)
  1141.             if yes then
  1142.                 self:tryLogGameLoginEvent(gameLoginEvents[1])
  1143.                 callbackTodo(yes)
  1144.             else
  1145.                 self:tryLogGameLoginEvent(gameLoginEvents[2])
  1146.  
  1147.                 local title = __("AUTO_REPAIR")
  1148.                 local tip = __("AUTO_REPAIR_TIP")
  1149.  
  1150.                 if urls == nil then
  1151.                     if urlUsageType ~= nil then
  1152.                         urls = URLS[urlUsageType] or {}
  1153.                     else
  1154.                         urls = {}
  1155.                     end
  1156.                 end
  1157.  
  1158.                 local strUrls = json.encode({
  1159.                     inGame = false,
  1160.                     urls = urls
  1161.                 })
  1162.                 local strPlayerID = "-1"
  1163.  
  1164.                 if globalPlayerID and globalPlayerID > 0 then
  1165.                     strPlayerID = tostring(globalPlayerID)
  1166.                 elseif self.lastPlayerID_ and self.lastPlayerID_ > 0 then
  1167.                     strPlayerID = tostring(self.lastPlayerID_)
  1168.                 end
  1169.  
  1170.                 local logPath = XYDDef.DataPath .. "/Logs"
  1171.  
  1172.                 print("show auto repair: urls", strUrls)
  1173.                 UIManager.ShowAutoRepair(title, tip, strUrls, false, strPlayerID, logPath, true, function (strResult)
  1174.                     print("auto repair result", strResult)
  1175.  
  1176.                     local isE009 = strErrorCode == "(e:009)"
  1177.  
  1178.                     if self.lastPlayerID_ > 0 then
  1179.                         self:tryLogGameLoginEvent(gameLoginEvents[3])
  1180.  
  1181.                         local info = {
  1182.                             player_name = __("LOGIN_NICK_NAME"),
  1183.                             player_id = __("LOGIN_PLAYER_ID"),
  1184.                             kingdom_id = __("LOGIN_CITY"),
  1185.                             player_level = __("LOGIN_PLAYER_LEVEL"),
  1186.                             castle_level = __("LOGIN_CASTLE_LEVEL"),
  1187.                             player_name_v = self.lastPlayerName_,
  1188.                             player_id_v = self.lastPlayerID_,
  1189.                             kingdom_id_v = self.lastKingdomID_,
  1190.                             player_level_v = self.lastPlayerLevel_,
  1191.                             castle_level_v = self.lastCastleLevel_,
  1192.                             message = __("AUTO_REPAIR_RES_MSG1"),
  1193.                             message2 = __("AUTO_REPAIR_RES_MSG2"),
  1194.                             message3 = __("LOGIN_OFFICIAL_LINE", self:getLineID()),
  1195.                             yes_text = isE009 and __("AUTO_REPAIR_REVERT") or __("OK"),
  1196.                             no_text = __("GM_CONTACT_ENTRANCE")
  1197.                         }
  1198.  
  1199.                         local function callbackCopy(str)
  1200.                             if str == "link" then
  1201.                                 if xyd.lang == "en_us" then
  1202.                                     Application.OpenURL("https://discord.gg/wx5KbpF")
  1203.                                 elseif xyd.lang == "pt_pt" then
  1204.                                     Application.OpenURL("https://wa.me/message/KHYHKQ5NRSHRL1")
  1205.                                 end
  1206.                             else
  1207.                                 self:setClipboard(self:getLineID())
  1208.                                 UIManager.ShowTip(__("COPY_SUCCESS"))
  1209.                             end
  1210.                         end
  1211.  
  1212.                         local function callbackTodo2()
  1213.                             self:tryLogGameLoginEvent(gameLoginEvents[4])
  1214.  
  1215.                             if isE009 then
  1216.                                 self:clearErrorVersion()
  1217.                             else
  1218.                                 callbackTodo()
  1219.                             end
  1220.                         end
  1221.  
  1222.                         if GM_CHAT_ENABLED then
  1223.                             local function callbackSetGmChat()
  1224.                                 if GM_CHAT_PLAYER_ID_ENABLED then
  1225.                                     UIManager.SetGmChat(strErrorCode, tostring(self.originLastPlayerID_), self.lastPlayerName_, strPlayerID)
  1226.                                 else
  1227.                                     UIManager.SetGmChat(strErrorCode)
  1228.                                 end
  1229.                             end
  1230.  
  1231.                             UIManager.ShowAutoRepairRes(__("AUTO_REPAIR"), json.encode(info), callbackTodo2, callbackSetGmChat, callbackCopy)
  1232.                         else
  1233.                             UIManager.ShowAutoRepairRes(__("AUTO_REPAIR"), json.encode(info), callbackTodo2, callbackCopy)
  1234.                         end
  1235.                     else
  1236.                         self:tryLogGameLoginEvent(gameLoginEvents[5])
  1237.  
  1238.                         local deviceID = XYDSDK.Instance:GetDeviceID()
  1239.  
  1240.                         print("device id:", deviceID)
  1241.  
  1242.                         local title = __("AUTO_REPAIR")
  1243.                         local msg = __("AUTO_REPAIR_RES") .. "\n" .. __("LOGIN_OFFICIAL_LINE", self:getLineID()) .. "\n" .. "Device ID:" .. deviceID
  1244.  
  1245.                         if isE009 then
  1246.                             UIManager.ShowAlert(title, msg, __("AUTO_REPAIR_REVERT"), __("OK"), false, function (yes)
  1247.                                 self:tryLogGameLoginEvent(gameLoginEvents[6])
  1248.  
  1249.                                 if yes then
  1250.                                     self:clearErrorVersion()
  1251.                                 else
  1252.                                     callbackTodo()
  1253.                                 end
  1254.                             end)
  1255.                         else
  1256.                             UIManager.ShowConfirmAlert(title, msg, __("OK"), false, function ()
  1257.                                 self:tryLogGameLoginEvent(gameLoginEvents[6])
  1258.                                 callbackTodo()
  1259.                             end)
  1260.                         end
  1261.                     end
  1262.                 end, function ()
  1263.                     self:tryLogGameLoginEvent(gameLoginEvents[7])
  1264.                     callbackTodo()
  1265.                 end)
  1266.             end
  1267.         end)
  1268.     end,
  1269.     initLastAccountInfo = function (self)
  1270.         self.lastPlayerID_ = GetInt("__player_id_key__", -1)
  1271.         self.lastPlayerName_ = GetString("__player_name_key__", "")
  1272.         self.lastPlayerLevel_ = GetInt("__player_level_key__", 1)
  1273.         self.lastKingdomID_ = GetInt("__kingdom_id_key__", 1)
  1274.         self.lastCastleLevel_ = GetInt("__castle_level_key__", 1)
  1275.  
  1276.         if self.lastPlayerID_ > 0 then
  1277.             self.originLastPlayerID_ = self.lastPlayerID_
  1278.             self.lastPlayerID_ = self:encryptPlayerID(self.lastPlayerID_)
  1279.         end
  1280.     end,
  1281.     encryptPlayerID = function (self, num1)
  1282.         local num2 = 66666666666.0
  1283.         local num3 = 0
  1284.         local digit = 0
  1285.  
  1286.         while num1 > 0 or num2 > 0 do
  1287.             local t1 = num1 % 2
  1288.             local t2 = num2 % 2
  1289.             local t3 = t1 ~= t2 and 1 or 0
  1290.             num3 = num3 + t3 * math.pow(2, digit)
  1291.             digit = digit + 1
  1292.             num1 = math.floor(num1 / 2)
  1293.             num2 = math.floor(num2 / 2)
  1294.         end
  1295.  
  1296.         return num3
  1297.     end,
  1298.     getLineID = function (self)
  1299.         local res = "TheGrandMafia"
  1300.         local pkgName = XYDDef.PkgName
  1301.  
  1302.         if pkgName == "com.yottagames.gameofmafia" or pkgName == "com.yottagames.tgmafia" or pkgName == "com.yottagames.gameofmafiatest" or pkgName == "com.yottagames.gameofmafiatr" or pkgName == "com.yottagames.gameofmafiajp" or pkgName == "com.yottagames.gameofmafiakr" then
  1303.             if xyd.lang == "zh_tw" then
  1304.                 res = "@grandmafiatw"
  1305.             elseif xyd.lang == "fr_fr" then
  1306.                 res = "@grandmafiafr"
  1307.             elseif xyd.lang == "de_de" then
  1308.                 res = "@grandmafiade"
  1309.             elseif xyd.lang == "ru_ru" then
  1310.                 res = "thegrandmafia"
  1311.             elseif xyd.lang == "es_es" then
  1312.                 res = "grandmafiaes"
  1313.             elseif xyd.lang == "tr_tr" then
  1314.                 res = "grandmafiatr"
  1315.             elseif xyd.lang == "ja_jp" then
  1316.                 res = "@grandmafiajp"
  1317.             elseif xyd.lang == "it_it" then
  1318.                 res = "grandmafiait"
  1319.             elseif xyd.lang == "pt_pt" then
  1320.                 res = "Secretária Nat"
  1321.             elseif xyd.lang == "ar_ae" then
  1322.                 res = "@grandmafiaar"
  1323.             elseif xyd.lang == "ko_kr" then
  1324.                 res = "더 그랜드 마피아"
  1325.             else
  1326.                 res = xyd.package2LineID[pkgName]
  1327.             end
  1328.         else
  1329.             res = xyd.package2LineID[pkgName]
  1330.         end
  1331.  
  1332.         return res or "TheGrandMafia"
  1333.     end,
  1334.     setUrlType = function (self, urlUsageType, urlType)
  1335.         if urlUsageType == UrlUsageType.CDN then
  1336.             if CDN_URLS_ENABLED then
  1337.                 self.urlTypes_[urlUsageType] = urlType
  1338.                 self.urls_[urlUsageType] = URLS[urlUsageType][urlType]
  1339.  
  1340.                 XYDUtils.SetCdnUrl(self:getCdnResUrl())
  1341.                 self:addUsedUrlType(urlUsageType, urlType)
  1342.             else
  1343.                 self.urlTypes_[urlUsageType] = UrlType.NORMAL
  1344.                 self.urls_[urlUsageType] = UrlType.NORMAL
  1345.  
  1346.                 self:addUsedUrlType(urlUsageType, urlType)
  1347.             end
  1348.         else
  1349.             self.urlTypes_[urlUsageType] = urlType
  1350.             self.urls_[urlUsageType] = URLS[urlUsageType][urlType]
  1351.  
  1352.             self:addUsedUrlType(urlUsageType, urlType)
  1353.         end
  1354.     end,
  1355.     addUsedUrlType = function (self, urlUsageType, urlType)
  1356.         self.usedUrlTypes_[urlUsageType] = self.usedUrlTypes_[urlUsageType] or {}
  1357.         self.usedUrlTypes_[urlUsageType][urlType] = true
  1358.     end,
  1359.     getUrlType = function (self, urlUsageType)
  1360.         return self.urlTypes_[urlUsageType]
  1361.     end,
  1362.     getBackendUrl = function (self)
  1363.         return self.urls_[UrlUsageType.BACKEND]
  1364.     end,
  1365.     getGateUrl = function (self)
  1366.         return self.urls_[UrlUsageType.GATE]
  1367.     end,
  1368.     getCdnUrl = function (self)
  1369.         return self.urls_[UrlUsageType.CDN]
  1370.     end,
  1371.     getCdnResUrl = function (self)
  1372.         return self:getCdnUrl() .. "/res/"
  1373.     end,
  1374.     isCheckServer = function (self)
  1375.         if xyd.backendurl == "mafia2backreview.xunmenginc.com" or xyd.backendurl == "mafia2backreview.yottagames.com" then
  1376.             return true
  1377.         end
  1378.  
  1379.         return false
  1380.     end,
  1381.     getBackendRequestUrl = function (self)
  1382.         if self:isCheckServer() or UNITY_EDITOR then
  1383.             return "http://" .. xyd.backendurl .. "/api/v1"
  1384.         end
  1385.  
  1386.         return self:getBackendUrl() .. "/api/v1"
  1387.     end,
  1388.     webRequest = function (self, url, params, callback)
  1389.         local function complete(response, success)
  1390.             if callback ~= nil then
  1391.                 callback(response or {}, success)
  1392.             end
  1393.         end
  1394.  
  1395.         local payload = json.encode(params or {})
  1396.         local request = HttpRequest.Request(url, "POST")
  1397.  
  1398.         request:AddField("payload", payload)
  1399.         print(string.format("Request web %s, post data %s", url, payload))
  1400.         request:SetTimeout(10)
  1401.         request:AddCallback(function (response)
  1402.             if not response.IsSuccess then
  1403.                 local state = response.ReqState
  1404.                 local status = response.StatusCode
  1405.  
  1406.                 print("webRequest not success:", state, status)
  1407.                 complete({}, false)
  1408.  
  1409.                 return
  1410.             end
  1411.  
  1412.             local code = response.StatusCode
  1413.             local text = response.DataAsText
  1414.  
  1415.             print(string.format("Received from web code(%d) -- %s", code, text))
  1416.  
  1417.             if code ~= 200 and code ~= 400 then
  1418.                 complete({}, false, code)
  1419.  
  1420.                 return
  1421.             end
  1422.  
  1423.             local ok, result = pcall(json.decode, text)
  1424.  
  1425.             if ok and type(result) == "table" then
  1426.                 complete(result, true, code)
  1427.             else
  1428.                 complete({}, false, code)
  1429.             end
  1430.         end)
  1431.         request:Send()
  1432.     end,
  1433.     clearDownloadInfos = function (self)
  1434.         self.downloadInfos_ = nil
  1435.  
  1436.         xyd.db.downloadInfo:commit()
  1437.         xyd.db.downloadInfo:truncate()
  1438.         xyd.db.downloadInfo:close()
  1439.     end,
  1440.     saveDownloadInfo = function (self, downloadInfo)
  1441.         if ADD_COUNTER % 10 == 0 then
  1442.             xyd.db.downloadInfo:commit()
  1443.             xyd.db.downloadInfo:begin()
  1444.         end
  1445.  
  1446.         ADD_COUNTER = ADD_COUNTER + 1
  1447.  
  1448.         xyd.db.downloadInfo:add(downloadInfo)
  1449.     end,
  1450.     isDownloadFinished = function (self, downloadInfo)
  1451.         return downloadInfo ~= nil and downloadInfo.downloadedSize == downloadInfo.size
  1452.     end,
  1453.     isDownloaded = function (self, downloadInfo, versionInfo)
  1454.         return downloadInfo ~= nil and versionInfo ~= nil and downloadInfo.version == versionInfo.version and downloadInfo.size == versionInfo.size
  1455.     end,
  1456.     recoverDownloadProgress = function (self, versionInfos)
  1457.         if self.downloadInfos_ == nil then
  1458.             xyd.db.downloadInfo:openDB("download.db")
  1459.  
  1460.             self.downloadInfos_ = xyd.db.downloadInfo:getAll()
  1461.         end
  1462.  
  1463.         local totalBytes = 0
  1464.         local totalDownloadBytes = 0
  1465.         local path, size, downloadInfo = nil
  1466.  
  1467.         for _, versionInfo in ipairs(versionInfos) do
  1468.             path = versionInfo.path
  1469.             size = versionInfo.size
  1470.             totalBytes = totalBytes + size
  1471.             downloadInfo = self.downloadInfos_[path]
  1472.  
  1473.             if self:isDownloaded(downloadInfo, versionInfo) then
  1474.                 totalDownloadBytes = totalDownloadBytes + (downloadInfo.downloadedSize or 0)
  1475.             end
  1476.         end
  1477.  
  1478.         return totalDownloadBytes, totalBytes
  1479.     end,
  1480.     getDownloadInfo = function (self, versionInfo)
  1481.         local path = versionInfo.path
  1482.         local downloadInfo = self.downloadInfos_[path]
  1483.  
  1484.         if downloadInfo == nil or not self:isDownloaded(downloadInfo, versionInfo) then
  1485.             downloadInfo = downloadInfo or {}
  1486.             downloadInfo.version = versionInfo.version
  1487.             downloadInfo.size = versionInfo.size
  1488.             downloadInfo.path = versionInfo.path
  1489.             downloadInfo.downloadedSize = 0
  1490.         end
  1491.  
  1492.         return downloadInfo
  1493.     end,
  1494.     downloadVersion = function (self, downloadInfo, versionInfo, callback, isTmpPath)
  1495.         local path = downloadInfo.path
  1496.         local md5 = versionInfo.md5
  1497.         local res = versionInfo.res
  1498.  
  1499.         if isTmpPath then
  1500.             ResManager.DownloadFile(XYDUtils.CdnUrl() .. res .. "." .. md5, md5, path, self:getTmpFilePath(path), function (status)
  1501.                 if status == DownloadStatus.Success then
  1502.                     downloadInfo.downloadedSize = versionInfo.size
  1503.  
  1504.                     self:saveDownloadInfo(downloadInfo)
  1505.                 end
  1506.  
  1507.                 callback(status)
  1508.             end, function (status, progress)
  1509.                 callback(status, progress)
  1510.             end)
  1511.         else
  1512.             ResManager.DownloadRes(XYDUtils.CdnUrl() .. res .. "." .. md5, md5, path, path, function (status)
  1513.                 if status == DownloadStatus.Success then
  1514.                     self:finishLazyDownload(versionInfo.type, path, md5)
  1515.  
  1516.                     downloadInfo.downloadedSize = versionInfo.size
  1517.  
  1518.                     self:saveDownloadInfo(downloadInfo)
  1519.                 end
  1520.  
  1521.                 callback(status)
  1522.             end, function (status, progress)
  1523.                 callback(status, progress)
  1524.             end)
  1525.         end
  1526.     end,
  1527.     getLocalMd5 = function (self, path)
  1528.         return self.allLocalMd5s_[path]
  1529.     end,
  1530.     finishLazyDownload = function (self, type, path, md5)
  1531.         self.allLocalMd5s_[path] = md5
  1532.  
  1533.         xyd.db.localMd5Info:setLocalMd5(path, md5)
  1534.  
  1535.         if type == 2 then
  1536.             DeleteKey(LAZY_LUA_DOWNLOAD_PREFIX .. path)
  1537.         elseif type == 3 then
  1538.             DeleteKey(LAZY_WEB_DOWNLOAD_PREFIX .. path)
  1539.         elseif type == 4 then
  1540.             DeleteKey(LAZY_WEB_DOWNLOAD_PREFIX .. path)
  1541.         end
  1542.     end,
  1543.     downloadTranslation = function (self, versionInfos, callback)
  1544.         self:updateRes(versionInfos, __("LOADING"), callback)
  1545.     end,
  1546.     updateRes = function (self, versionInfos, desc, callback, isTmpPath)
  1547.         if #versionInfos <= 0 then
  1548.             return callback()
  1549.         end
  1550.  
  1551.         local totalDownloadBytes, totalBytes = self:recoverDownloadProgress(versionInfos)
  1552.  
  1553.         local function complete()
  1554.             self:clearDownloadInfos()
  1555.  
  1556.             if isTmpPath then
  1557.                 XYDCo.WaitForFrame(1, function ()
  1558.                     callback()
  1559.                 end, nil)
  1560.             else
  1561.                 XYDCo.WaitForFrame(60, function ()
  1562.                     UIManager.SetLoadingProgress(0, false)
  1563.                     UIManager.SetLoadingProgress("")
  1564.                     callback()
  1565.                 end, nil)
  1566.             end
  1567.         end
  1568.  
  1569.         local gindex = 0
  1570.         local complete_count = 0
  1571.         local totalPercent = 1
  1572.         local targetPercent = 0.6
  1573.  
  1574.         if isTmpPath then
  1575.             totalPercent = 0.8
  1576.             targetPercent = 0.4
  1577.         end
  1578.  
  1579.         local function download(index)
  1580.             if index > #versionInfos then
  1581.                 complete_count = complete_count + 1
  1582.  
  1583.                 if DOWNLOAD_THREADS_NUM <= complete_count then
  1584.                     UIManager.SetLoadingProgress(totalPercent, 0.6, false)
  1585.                     UIManager.SetLoadingProgress(desc .. " " .. self:roundNum(totalPercent * 100) .. "%")
  1586.  
  1587.                     return complete()
  1588.                 end
  1589.  
  1590.                 return
  1591.             end
  1592.  
  1593.             local versionInfo = versionInfos[index]
  1594.             local downloadInfo = self:getDownloadInfo(versionInfo)
  1595.             local progress = totalDownloadBytes / totalBytes * targetPercent + 0.4
  1596.  
  1597.             UIManager.SetLoadingProgress(progress, 0.4, false)
  1598.             UIManager.SetLoadingProgress(desc .. " " .. self:roundNum(progress * 100) .. "%")
  1599.  
  1600.             if self:isDownloadFinished(downloadInfo) then
  1601.                 gindex = gindex + 1
  1602.  
  1603.                 return download(gindex)
  1604.             end
  1605.  
  1606.             local tmpDownloadBytes = 0
  1607.  
  1608.             self:downloadVersion(downloadInfo, versionInfo, function (status, progress)
  1609.                 if status == DownloadStatus.Success then
  1610.                     totalDownloadBytes = totalDownloadBytes - tmpDownloadBytes
  1611.                     totalDownloadBytes = totalDownloadBytes + versionInfo.size
  1612.                     local progress2 = totalDownloadBytes / totalBytes * targetPercent + 0.4
  1613.  
  1614.                     UIManager.SetLoadingProgress(progress2, 0.4, false)
  1615.                     UIManager.SetLoadingProgress(desc .. " " .. self:roundNum(progress2 * 100) .. "%")
  1616.  
  1617.                     gindex = gindex + 1
  1618.  
  1619.                     download(gindex)
  1620.                     self:delayWaitShowAutoRepairWindow()
  1621.                     self:clearUrlFailed(UrlUsageType.CDN)
  1622.                 elseif status == DownloadStatus.Progress then
  1623.                     totalDownloadBytes = totalDownloadBytes - tmpDownloadBytes
  1624.                     tmpDownloadBytes = versionInfo.size * progress
  1625.                     totalDownloadBytes = totalDownloadBytes + tmpDownloadBytes
  1626.                     local progress2 = totalDownloadBytes / totalBytes * targetPercent + 0.4
  1627.  
  1628.                     UIManager.SetLoadingProgress(progress2, 0.4, false)
  1629.                     UIManager.SetLoadingProgress(desc .. " " .. self:roundNum(progress2 * 100) .. "%")
  1630.                 elseif status == DownloadStatus.Failed then
  1631.                     self:recordUrlFailed(UrlUsageType.CDN)
  1632.  
  1633.                     local function onDownloadFailed()
  1634.                         totalDownloadBytes = totalDownloadBytes - tmpDownloadBytes
  1635.  
  1636.                         download(index)
  1637.                     end
  1638.  
  1639.                     local failedTimes = self:getUrlFailedTimes(UrlUsageType.CDN) + 1
  1640.  
  1641.                     print("===Update Error===: download resource failed(e:003) -- version:" .. versionInfo.version .. ", res:" .. versionInfo.res .. "." .. versionInfo.md5 .. " url:" .. XYDUtils.CdnUrl() .. " failedTimes:" .. failedTimes)
  1642.  
  1643.                     failedTimes = self:setUrlFailedTimes(UrlUsageType.CDN, failedTimes)
  1644.  
  1645.                     if failedTimes >= 2 then
  1646.                         self:reportMessageToBackupPlatform("003", "", "", XYDUtils.CdnUrl())
  1647.                         self:showAutoRepairWindow({
  1648.                             strErrorCode = "(e:003)",
  1649.                             urlUsageType = "cdn",
  1650.                             callbackTodo = onDownloadFailed
  1651.                         })
  1652.                     else
  1653.                         onDownloadFailed()
  1654.                     end
  1655.                 end
  1656.             end, isTmpPath)
  1657.         end
  1658.  
  1659.         for i = 1, DOWNLOAD_THREADS_NUM do
  1660.             gindex = gindex + 1
  1661.  
  1662.             download(gindex)
  1663.         end
  1664.     end,
  1665.     updateTmpRes = function (self, versionInfos, callback, afterForceDownload)
  1666.         local desc = afterForceDownload and __("UPDATING") or __("LOADING")
  1667.  
  1668.         if #versionInfos <= 0 then
  1669.             return callback()
  1670.         end
  1671.  
  1672.         local function complete()
  1673.             XYDCo.WaitForFrame(60, function ()
  1674.                 UIManager.SetLoadingProgress(0, false)
  1675.                 UIManager.SetLoadingProgress("")
  1676.                 callback()
  1677.             end, nil)
  1678.         end
  1679.  
  1680.         local function copyFile(index)
  1681.             if index > #versionInfos then
  1682.                 UIManager.SetLoadingProgress(1, 0.6, false)
  1683.                 UIManager.SetLoadingProgress(desc .. " 100%")
  1684.  
  1685.                 return complete()
  1686.             end
  1687.  
  1688.             local progress = nil
  1689.  
  1690.             if afterForceDownload then
  1691.                 progress = index / #versionInfos * 0.2 + 0.8
  1692.             else
  1693.                 progress = index / #versionInfos * 0.6 + 0.4
  1694.             end
  1695.  
  1696.             UIManager.SetLoadingProgress(progress, 0.4, false)
  1697.             UIManager.SetLoadingProgress(desc .. " " .. self:roundNum(progress * 100) .. "%")
  1698.  
  1699.             local versionInfo = versionInfos[index]
  1700.             local type = versionInfo.type
  1701.             local path = versionInfo.path
  1702.             local md5 = versionInfo.md5
  1703.  
  1704.             FileUtils.CopyFile2Res(self:getTmpFilePath(path), path)
  1705.  
  1706.             if type == 4 then
  1707.                 DeleteKey(BACK_UPDATE_WEB_DOWNLOAD_PREFIX .. path)
  1708.             end
  1709.  
  1710.             self:finishLazyDownload(type, path, md5)
  1711.  
  1712.             if index % 10 == 0 then
  1713.                 XYDCo.WaitForEndOfFrame(function ()
  1714.                     copyFile(index + 1)
  1715.                 end, "")
  1716.             else
  1717.                 copyFile(index + 1)
  1718.             end
  1719.         end
  1720.  
  1721.         copyFile(1)
  1722.     end,
  1723.     initTranslation = function (self)
  1724.         if not __ then
  1725.             local infos = {}
  1726.             local data = require("data.tables.translation_" .. xyd.lang)
  1727.  
  1728.             for _, row in ipairs(data.rows) do
  1729.                 local key = row[1]
  1730.                 local value = string.gsub(row[2], "|", "\n")
  1731.                 local ordinals = {}
  1732.  
  1733.                 for num in value:gmatch("{(%d+)}") do
  1734.                     table.insert(ordinals, tonumber(num))
  1735.                 end
  1736.  
  1737.                 infos[key] = {
  1738.                     format = value:gsub("{%d+}", "%%s"),
  1739.                     ordinals = ordinals
  1740.                 }
  1741.             end
  1742.  
  1743.             function __(name, ...)
  1744.                 name = tostring(name)
  1745.                 local info = infos[name]
  1746.  
  1747.                 if info == nil then
  1748.                     return name
  1749.                 end
  1750.  
  1751.                 local inargs = {
  1752.                     ...
  1753.                 }
  1754.                 local args = {}
  1755.  
  1756.                 for _, index in ipairs(info.ordinals) do
  1757.                     table.insert(args, inargs[index] or "")
  1758.                 end
  1759.  
  1760.                 return string.format(info.format, unpack(args))
  1761.             end
  1762.         end
  1763.  
  1764.         local playerID = GetInt("__player_id_key__", -1)
  1765.         local allianceCalendarStr = GetString("__alliance_calendar__" .. playerID, "")
  1766.         local savedAllianceCalendarInfos = {}
  1767.         local extraLoadingStr = GetString("__extra_loading_tip__" .. playerID, "")
  1768.         local savedExtraLoadingInfos = {}
  1769.         local allInfos = {}
  1770.         local loadingMessage1, loadingMessage2 = nil
  1771.         local leftInfos = {}
  1772.         local infoWeight = 0
  1773.         local saveInfo1, saveInfo2 = nil
  1774.  
  1775.         if allianceCalendarStr ~= "" or extraLoadingStr ~= "" then
  1776.             savedAllianceCalendarInfos = allianceCalendarStr ~= "" and json.decode(allianceCalendarStr) or {}
  1777.             savedExtraLoadingInfos = extraLoadingStr ~= "" and json.decode(extraLoadingStr) or {}
  1778.  
  1779.             for _, info in ipairs(savedExtraLoadingInfos) do
  1780.                 local newInfo = {
  1781.                     id = info.id,
  1782.                     time = info.time,
  1783.                     showed = info.showed,
  1784.                     weight = info.weight,
  1785.                     trans = info.trans,
  1786.                     transParams = info.transParams,
  1787.                     source = info,
  1788.                     saveTable = savedExtraLoadingInfos,
  1789.                     saveKey = "__extra_loading_tip__" .. playerID
  1790.                 }
  1791.  
  1792.                 table.insert(allInfos, newInfo)
  1793.             end
  1794.  
  1795.             for _, info in ipairs(savedAllianceCalendarInfos) do
  1796.                 local newInfo = {
  1797.                     id = info.id,
  1798.                     time = info.time,
  1799.                     showed = info.showed,
  1800.                     weight = info.weight,
  1801.                     trans = info.trans,
  1802.                     transParams = info.transParams,
  1803.                     source = info,
  1804.                     saveTable = savedAllianceCalendarInfos,
  1805.                     saveKey = "__alliance_calendar__" .. playerID
  1806.                 }
  1807.  
  1808.                 table.insert(allInfos, newInfo)
  1809.             end
  1810.  
  1811.             local osTime = os.time()
  1812.             local osDate = os.date("*t", osTime)
  1813.             local maxOsTime = os.time({
  1814.                 hour = 0,
  1815.                 min = 0,
  1816.                 sec = 0,
  1817.                 year = osDate.year,
  1818.                 month = osDate.month,
  1819.                 day = osDate.day + 2
  1820.             })
  1821.  
  1822.             for _, info in ipairs(allInfos) do
  1823.                 if info.id and info.time and osTime < info.time and info.time < maxOsTime then
  1824.                     local infoDate = os.date("*t", info.time)
  1825.                     local transKey = nil
  1826.                     local trans = info.trans or {}
  1827.  
  1828.                     if infoDate.day == osDate.day then
  1829.                         transKey = trans[1] or ""
  1830.                     else
  1831.                         transKey = trans[2] or ""
  1832.                     end
  1833.  
  1834.                     local transParams = info.transParams or {}
  1835.                     local transParams2 = {}
  1836.  
  1837.                     for i, transParam in ipairs(transParams) do
  1838.                         transParams2[i] = __(transParam)
  1839.                     end
  1840.  
  1841.                     local lang = __(transKey, unpack(transParams2))
  1842.                     local showed = nil
  1843.  
  1844.                     if info.showed == 0 then
  1845.                         if not loadingMessage1 then
  1846.                             loadingMessage1 = lang
  1847.                             info.source.showed = 1
  1848.                             saveInfo1 = info
  1849.                             showed = true
  1850.                         elseif not loadingMessage2 then
  1851.                             loadingMessage2 = lang
  1852.                             saveInfo2 = info
  1853.                             showed = true
  1854.                         end
  1855.                     end
  1856.  
  1857.                     if not showed and info.showed == 1 then
  1858.                         local weight = info.weight or 0
  1859.                         local messageInfo = {
  1860.                             lang = lang,
  1861.                             weight = weight
  1862.                         }
  1863.                         infoWeight = infoWeight + weight
  1864.  
  1865.                         table.insert(leftInfos, messageInfo)
  1866.                     end
  1867.                 end
  1868.             end
  1869.         end
  1870.  
  1871.         local prompts = {
  1872.             {
  1873.                 index = 1,
  1874.                 lv_limit = 10,
  1875.                 lang = __("LOADING_PROMPT1")
  1876.             },
  1877.             {
  1878.                 index = 2,
  1879.                 lv_limit = 1,
  1880.                 lang = __("LOADING_PROMPT2")
  1881.             },
  1882.             {
  1883.                 index = 3,
  1884.                 lv_limit = 1,
  1885.                 lang = __("LOADING_PROMPT3")
  1886.             },
  1887.             {
  1888.                 index = 4,
  1889.                 lv_limit = 3,
  1890.                 lang = __("LOADING_PROMPT4")
  1891.             },
  1892.             {
  1893.                 index = 5,
  1894.                 lv_limit = 3,
  1895.                 lang = __("LOADING_PROMPT5")
  1896.             },
  1897.             {
  1898.                 index = 6,
  1899.                 lv_limit = 1,
  1900.                 lang = __("LOADING_PROMPT6")
  1901.             },
  1902.             {
  1903.                 index = 7,
  1904.                 lv_limit = 3,
  1905.                 lang = __("LOADING_PROMPT7")
  1906.             },
  1907.             {
  1908.                 index = 8,
  1909.                 lv_limit = 10,
  1910.                 lang = __("LOADING_PROMPT8")
  1911.             },
  1912.             {
  1913.                 index = 9,
  1914.                 lv_limit = 3,
  1915.                 lang = __("LOADING_PROMPT9")
  1916.             },
  1917.             {
  1918.                 index = 10,
  1919.                 lv_limit = 3,
  1920.                 lang = __("LOADING_PROMPT10")
  1921.             },
  1922.             {
  1923.                 index = 11,
  1924.                 lv_limit = 3,
  1925.                 lang = __("LOADING_PROMPT11")
  1926.             },
  1927.             {
  1928.                 index = 12,
  1929.                 lv_limit = 10,
  1930.                 lang = __("LOADING_PROMPT12")
  1931.             },
  1932.             {
  1933.                 index = 13,
  1934.                 lv_limit = 10,
  1935.                 lang = __("LOADING_PROMPT13")
  1936.             },
  1937.             {
  1938.                 index = 14,
  1939.                 lv_limit = 1,
  1940.                 lang = __("LOADING_PROMPT14")
  1941.             },
  1942.             {
  1943.                 index = 15,
  1944.                 lv_limit = 10,
  1945.                 lang = __("LOADING_PROMPT15")
  1946.             },
  1947.             {
  1948.                 index = 16,
  1949.                 lv_limit = 1,
  1950.                 lang = __("LOADING_PROMPT16")
  1951.             },
  1952.             {
  1953.                 index = 17,
  1954.                 lv_limit = 3,
  1955.                 lang = __("LOADING_PROMPT17")
  1956.             },
  1957.             {
  1958.                 index = 18,
  1959.                 lv_limit = 10,
  1960.                 lang = __("LOADING_PROMPT18")
  1961.             },
  1962.             {
  1963.                 index = 19,
  1964.                 lv_limit = 10,
  1965.                 lang = __("LOADING_PROMPT19")
  1966.             },
  1967.             {
  1968.                 index = 20,
  1969.                 lv_limit = 10,
  1970.                 lang = __("LOADING_PROMPT20")
  1971.             },
  1972.             {
  1973.                 index = 21,
  1974.                 lv_limit = 3,
  1975.                 lang = __("LOADING_PROMPT21")
  1976.             },
  1977.             {
  1978.                 index = 22,
  1979.                 lv_limit = 1,
  1980.                 lang = __("LOADING_PROMPT22")
  1981.             },
  1982.             {
  1983.                 index = 23,
  1984.                 lv_limit = 1,
  1985.                 lang = __("LOADING_PROMPT23")
  1986.             },
  1987.             {
  1988.                 index = 24,
  1989.                 lv_limit = 1,
  1990.                 lang = __("LOADING_PROMPT24")
  1991.             },
  1992.             {
  1993.                 index = 25,
  1994.                 lv_limit = 1,
  1995.                 lang = __("LOADING_PROMPT25")
  1996.             },
  1997.             {
  1998.                 index = 26,
  1999.                 lv_limit = 1,
  2000.                 lang = __("LOADING_PROMPT26")
  2001.             },
  2002.             {
  2003.                 index = 27,
  2004.                 lv_limit = 1,
  2005.                 lang = __("LOADING_PROMPT27")
  2006.             },
  2007.             {
  2008.                 index = 28,
  2009.                 lv_limit = 1,
  2010.                 lang = __("LOADING_PROMPT28")
  2011.             },
  2012.             {
  2013.                 index = 29,
  2014.                 lv_limit = 1,
  2015.                 lang = __("LOADING_PROMPT29")
  2016.             },
  2017.             {
  2018.                 index = 30,
  2019.                 lv_limit = 1,
  2020.                 lang = __("LOADING_PROMPT30")
  2021.             },
  2022.             {
  2023.                 index = 31,
  2024.                 lv_limit = 1,
  2025.                 lang = __("LOADING_PROMPT31")
  2026.             },
  2027.             {
  2028.                 index = 32,
  2029.                 lv_limit = 1,
  2030.                 lang = __("LOADING_PROMPT32")
  2031.             },
  2032.             {
  2033.                 index = 33,
  2034.                 lv_limit = 1,
  2035.                 lang = __("LOADING_PROMPT33")
  2036.             },
  2037.             {
  2038.                 index = 34,
  2039.                 lv_limit = 1,
  2040.                 lang = __("LOADING_PROMPT34")
  2041.             },
  2042.             {
  2043.                 index = 35,
  2044.                 lv_limit = 1,
  2045.                 lang = __("LOADING_PROMPT35")
  2046.             },
  2047.             {
  2048.                 index = 36,
  2049.                 lv_limit = 1,
  2050.                 lang = __("LOADING_PROMPT36")
  2051.             },
  2052.             {
  2053.                 index = 37,
  2054.                 lv_limit = 1,
  2055.                 lang = __("LOADING_PROMPT37")
  2056.             },
  2057.             {
  2058.                 index = 38,
  2059.                 lv_limit = 1,
  2060.                 lang = __("LOADING_PROMPT38")
  2061.             },
  2062.             {
  2063.                 index = 39,
  2064.                 lv_limit = 1,
  2065.                 lang = __("LOADING_PROMPT39")
  2066.             },
  2067.             {
  2068.                 index = 40,
  2069.                 lv_limit = 1,
  2070.                 lang = __("LOADING_PROMPT40")
  2071.             },
  2072.             {
  2073.                 index = 41,
  2074.                 lv_limit = 1,
  2075.                 lang = __("LOADING_PROMPT41")
  2076.             },
  2077.             {
  2078.                 index = 42,
  2079.                 lv_limit = 1,
  2080.                 lang = __("LOADING_PROMPT42")
  2081.             },
  2082.             {
  2083.                 index = 43,
  2084.                 lv_limit = 1,
  2085.                 lang = __("LOADING_PROMPT43")
  2086.             },
  2087.             {
  2088.                 index = 44,
  2089.                 lv_limit = 1,
  2090.                 lang = __("LOADING_PROMPT44")
  2091.             },
  2092.             {
  2093.                 index = 45,
  2094.                 lv_limit = 1,
  2095.                 lang = __("LOADING_PROMPT45")
  2096.             },
  2097.             {
  2098.                 index = 46,
  2099.                 lv_limit = 1,
  2100.                 lang = __("LOADING_PROMPT46")
  2101.             },
  2102.             {
  2103.                 index = 47,
  2104.                 lv_limit = 1,
  2105.                 lang = __("LOADING_PROMPT47")
  2106.             },
  2107.             {
  2108.                 index = 48,
  2109.                 lv_limit = 1,
  2110.                 lang = __("LOADING_PROMPT48")
  2111.             },
  2112.             {
  2113.                 index = 49,
  2114.                 lv_limit = 1,
  2115.                 lang = __("LOADING_PROMPT49")
  2116.             }
  2117.         }
  2118.  
  2119.         math.randomseed(os.time())
  2120.  
  2121.         local castleLevel = GetInt("__castle_level_key__", 1)
  2122.  
  2123.         if castleLevel <= 0 then
  2124.             castleLevel = 1
  2125.         end
  2126.  
  2127.         local canPicks = {}
  2128.         local lastPicks = {}
  2129.         local device_id = XYDUtils.GetDeviceID2Int()
  2130.         local isNew = device_id % 2 == 1
  2131.  
  2132.         for _, tmp in ipairs(prompts) do
  2133.             if isNew then
  2134.                 if tmp.index >= 22 and tmp.lv_limit <= castleLevel then
  2135.                     table.insert(canPicks, tmp)
  2136.                 end
  2137.             elseif tmp.index <= 21 and tmp.lv_limit <= castleLevel then
  2138.                 table.insert(canPicks, tmp)
  2139.             end
  2140.         end
  2141.  
  2142.         if loadingMessage1 then
  2143.             UIManager.SetLoadingMessage(loadingMessage1)
  2144.  
  2145.             local savedStr = json.encode(saveInfo1.saveTable)
  2146.  
  2147.             SetString(saveInfo1.saveKey, savedStr)
  2148.  
  2149.             loadingMessage1 = nil
  2150.             saveInfo1 = nil
  2151.         else
  2152.             local rd = math.random(1, #canPicks + infoWeight)
  2153.  
  2154.             if rd <= #canPicks then
  2155.                 UIManager.SetLoadingMessage(canPicks[rd].lang)
  2156.             else
  2157.                 local deltaRd = rd - #canPicks
  2158.                 local weights = 0
  2159.  
  2160.                 for _, allianceCalendarShowed in ipairs(leftInfos) do
  2161.                     local weight = allianceCalendarShowed.weight or 0
  2162.                     weights = weights + weight
  2163.  
  2164.                     if deltaRd <= weights then
  2165.                         local lang = allianceCalendarShowed.lang or ""
  2166.  
  2167.                         UIManager.SetLoadingMessage(lang)
  2168.  
  2169.                         break
  2170.                     end
  2171.                 end
  2172.             end
  2173.         end
  2174.  
  2175.         xyd.promptTimer = Timer.New(function ()
  2176.             if loadingMessage2 then
  2177.                 UIManager.SetLoadingMessage(loadingMessage2)
  2178.  
  2179.                 saveInfo2.source.showed = 1
  2180.                 local savedStr = json.encode(saveInfo2.saveTable)
  2181.  
  2182.                 SetString(saveInfo2.saveKey, savedStr)
  2183.  
  2184.                 loadingMessage2 = nil
  2185.                 saveInfo2 = nil
  2186.             else
  2187.                 local rd2 = math.random(1, #canPicks + infoWeight)
  2188.  
  2189.                 if rd2 <= #canPicks then
  2190.                     UIManager.SetLoadingMessage(canPicks[rd2].lang)
  2191.                 else
  2192.                     local deltaRd = rd2 - #canPicks
  2193.                     local weights = 0
  2194.  
  2195.                     for _, allianceCalendarShowed in ipairs(leftInfos) do
  2196.                         local weight = allianceCalendarShowed.weight or 0
  2197.                         weights = weights + weight
  2198.  
  2199.                         if deltaRd <= weights then
  2200.                             local lang = allianceCalendarShowed.lang or ""
  2201.  
  2202.                             UIManager.SetLoadingMessage(lang)
  2203.  
  2204.                             break
  2205.                         end
  2206.                     end
  2207.                 end
  2208.             end
  2209.         end, 5, -1, false)
  2210.  
  2211.         xyd.promptTimer:Start()
  2212.     end,
  2213.     showAnnounce = function (self, callback)
  2214.         local message = self.updateTitle_ .. "\n\n"
  2215.  
  2216.         for _, content in ipairs(self.updateContent_) do
  2217.             message = message .. content .. "\n"
  2218.         end
  2219.  
  2220.         UIManager.ShowUpdateAnnounce(__("UPDATE_ANNOUNCE"), message, "Textures/Banner_web/update_banner", __("CONFIRM_EXIT"), callback)
  2221.     end,
  2222.     getResourceVersion = function (self)
  2223.         return self.resourceVersion_
  2224.     end,
  2225.     getPackageVersion = function (self)
  2226.         return self.packageVersion_
  2227.     end,
  2228.     setResourceVersion = function (self, version)
  2229.         SetString(SAVE_VERSION, version)
  2230.         Save()
  2231.  
  2232.         self.savedVersion_ = version
  2233.         self.resourceVersion_ = version
  2234.         xyd.res_version = version
  2235.     end,
  2236.     getErrorVersion = function (self)
  2237.         return GetString(SAVE_ERROR_VERSION)
  2238.     end,
  2239.     setClipboard = function (self, str)
  2240.         UniClipBoard.SetText(str)
  2241.     end,
  2242.     startGame = function (self, reloadLang)
  2243.         UIManager.SetLoadingProgress(0.9, 1, false)
  2244.         self:cleanUp()
  2245.         self:stopWaitShowAutoRepairWindow("UpdateController:startGame")
  2246.         print("=-=-=-=-=-=-=-=-=-=start loadScene-=-=-=-=-=-=-=-=-=-=-=")
  2247.         SceneUtils.LoadScene("GuiScene", LoadSceneMode.Additive, function (scene, mode)
  2248.             print("=-=-=-=-=-=-=-=-=-=complete loadScene-=-=-=-=-=-=-=-=-=-=-=")
  2249.  
  2250.             if scene.name == "GuiScene" then
  2251.                 if UNITY_2020 then
  2252.                     XYDUtils.SetChildCameraActive("LNgui", false)
  2253.                 end
  2254.  
  2255.                 require("app.Game").new():run(reloadLang)
  2256.             end
  2257.         end)
  2258.     end,
  2259.     restartGame = function (self)
  2260.         XYDApp.NeedRestart = true
  2261.     end,
  2262.     cleanUp = function (self)
  2263.         package.loaded["data.tables.translation_" .. xyd.lang] = nil
  2264.         package.loaded.UpdateController = nil
  2265.     end
  2266. }
  2267. local tryTimesOfCode = {}
  2268.  
  2269. function UpdateController:reportMessageToBackupPlatform(eCode, responseCode, responseBody, url)
  2270.     if UNITY_ANDROID and XYDUtils.CompVersion(Application.version, "1.0.913") > 0 then
  2271.         tryTimesOfCode[eCode] = (tryTimesOfCode[eCode] or 0) + 1
  2272.  
  2273.         if tryTimesOfCode[eCode] == 3 then
  2274.             XYDSDK.Instance:ReportMessageToBackupPlatform(json.encode({
  2275.                 e = eCode,
  2276.                 response_code = responseCode,
  2277.                 response_body = responseBody
  2278.             }), url)
  2279.         end
  2280.     end
  2281. end
  2282.  
  2283. function UpdateController:logGameLoginEvent(desc, stageId)
  2284.     if UNITY_ANDROID and XYDUtils.CompVersion(Application.version, "1.0.913") > 0 and XYDUtils.IsFirstStart then
  2285.         XYDUtils.LogGameLoginEvent(desc, stageId, Application.version)
  2286.     end
  2287. end
  2288.  
  2289. function UpdateController:tryLogGameLoginEvent(event)
  2290.     if event then
  2291.         self:logGameLoginEvent(event.desc, event.stageId)
  2292.     end
  2293. end
  2294.  
  2295. function UpdateController:clearErrorVersion(inGame)
  2296.     local pkgVersion = self:getPackageVersion()
  2297.     local resVersion = self:getResourceVersion()
  2298.  
  2299.     if XYDUtils.CompVersion(pkgVersion, resVersion) >= 0 then
  2300.         return false
  2301.     end
  2302.  
  2303.     local fileName = jit.arch == "arm" and VERSION_FILE_32 or VERSION_FILE
  2304.  
  2305.     if not FileUtils.IsResInApp(fileName) then
  2306.         print("error no version file in app!!")
  2307.  
  2308.         return false
  2309.     end
  2310.  
  2311.     local pkgVersionStr = FileUtils.ReadResStringInApp(fileName)
  2312.     local pkgVersionInfos = json.decode(pkgVersionStr)
  2313.     local map = {}
  2314.     local currentVersionInfos = self:getCurrentVersionInfos()
  2315.  
  2316.     for _, versionInfo in pairs(currentVersionInfos.resources) do
  2317.         map[versionInfo.path] = versionInfo.md5
  2318.     end
  2319.  
  2320.     local path, type, md5, currentVersionMd5, downloadInfo = nil
  2321.  
  2322.     for _, versionInfo in pairs(pkgVersionInfos.resources) do
  2323.         type = versionInfo.type
  2324.         path = versionInfo.path
  2325.         md5 = versionInfo.md5
  2326.  
  2327.         if type == 3 or type == 4 then
  2328.             currentVersionMd5 = map[path]
  2329.  
  2330.             if currentVersionMd5 and currentVersionMd5 ~= md5 then
  2331.                 if FileUtils.IsResInData(path) then
  2332.                     FileUtils.DeleteRes(path)
  2333.                 end
  2334.  
  2335.                 DeleteKey(LAZY_WEB_DOWNLOAD_PREFIX .. path)
  2336.  
  2337.                 if type == 4 then
  2338.                     downloadInfo = {
  2339.                         path = path,
  2340.                         type = type,
  2341.                         md5 = md5,
  2342.                         res = versionInfo.res,
  2343.                         size = versionInfo.size,
  2344.                         version = pkgVersion
  2345.                     }
  2346.  
  2347.                     SetString(LAZY_WEB_DOWNLOAD_PREFIX .. path, json.encode(downloadInfo))
  2348.                 end
  2349.             end
  2350.         elseif type == 2 and not FileUtils.IsResInApp(path) then
  2351.             downloadInfo = {
  2352.                 path = path,
  2353.                 type = type,
  2354.                 md5 = md5,
  2355.                 res = versionInfo.res,
  2356.                 size = versionInfo.size,
  2357.                 version = pkgVersion
  2358.             }
  2359.  
  2360.             SetString(LAZY_LUA_DOWNLOAD_PREFIX .. path, json.encode(downloadInfo))
  2361.         end
  2362.     end
  2363.  
  2364.     FileUtils.DeleteRes(ANDROID_FILE)
  2365.     FileUtils.DeleteRes(VERSION_FILE)
  2366.     FileUtils.DeleteResDirectory("src")
  2367.     FileUtils.DeleteResDirectory("sdkchat")
  2368.     FileUtils.WriteRes(VERSION_FILE, pkgVersionStr)
  2369.     SetString(SAVE_VERSION, pkgVersion)
  2370.     SetString(SAVE_ERROR_VERSION, resVersion)
  2371.     Save()
  2372.  
  2373.     if not inGame then
  2374.         self:restartGame()
  2375.     end
  2376.  
  2377.     return true
  2378. end
  2379.  
  2380. return UpdateController
Advertisement
Add Comment
Please, Sign In to add comment