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

476 lines
14 KiB

  1. --[[
  2. 管理所有子游戏的版本信息,更新状态,及更新子游戏
  3. 负责下载所有子游戏的游戏图标,并将图标时间记录下来
  4. 从SubGameVersionManager获取子游戏最新的版本信息
  5. 从本地文件中获取子游戏当前的版本信息
  6. 判断子游戏是否需要更新
  7. 提供子游戏更新的接口
  8. 子游戏列表及当前版本号存本地文件,
  9. subGameList =
  10. {
  11. [gameId] = "1022",
  12. [gameId] = "1022",
  13. }
  14. --]]
  15. local SubGameVersionManager = class("SubGameVersionManager")
  16. function SubGameVersionManager:ctor()
  17. cc.GameObject.extend(self)
  18. self:addComponent(require("luaScript.cc.components.behavior.EventProtocol"):new()):exportMethods()
  19. -- 是否测试下载
  20. self.isTestUpdate = false
  21. -- 子游戏列表
  22. self.subGameList = {}
  23. -- 本地记录的文件信息
  24. self.GameVersionsKey = "GameVersions";
  25. self.GameVersions = {}
  26. -- self.GameVersions[3] = 10000;
  27. -- self.GameVersions[6] = 1000;
  28. --基础包
  29. --self.GameVersions[1001] = -1;
  30. --self.GameVersions[1002] = -1;
  31. --self.GameVersions[1003] = -1;
  32. -- 从本地读取已经安装的子游戏列表
  33. -- 以及每个子游戏的当前版本号
  34. self:loadVersionsFromFile()
  35. --处理一下基础包的版本号
  36. self.GameVersions[1001] = self.GameVersions[1001]==1000 and -1 or self.GameVersions[1001]
  37. self.GameVersions[1002] = self.GameVersions[1002]==1000 and -1 or self.GameVersions[1002]
  38. self.GameVersions[1003] = self.GameVersions[1003]==1000 and -1 or self.GameVersions[1003]
  39. -- self.GameVersions[3] = self.GameVersions[3]==10000 and -1 or self.GameVersions[3]
  40. -- 子游戏下载器
  41. self.updaterList = {}
  42. --排序
  43. self.info = {};
  44. -- self:loadFromFile();
  45. end
  46. -- 获取子游戏的版本
  47. -- 如果指定的游戏没有安装,则返回-1
  48. function SubGameVersionManager:getSubGameVersionNum(gameId)
  49. gameId = tonumber(gameId)
  50. if self.GameVersions[gameId] then
  51. return self.GameVersions[gameId]
  52. else
  53. return -1
  54. end
  55. end
  56. -- 从本地读取游戏版本信息
  57. function SubGameVersionManager:loadVersionsFromFile()
  58. local locString = loadUserInfo(self.GameVersionsKey)
  59. if not locString or locString == "" then
  60. return
  61. end
  62. logD("SubGameVersionManager:loadVersionsFromFile() locString = ", locString)
  63. local locData = json.decode(locString)
  64. if locData then
  65. for k,v in pairs(locData) do
  66. self.GameVersions[tonumber(k)] = tonumber(v)
  67. end
  68. else
  69. logD("SubGameVersionManager:loadVersionsFromFile() locString:"..locString)
  70. end
  71. end
  72. -- 将游戏版本信息写入到本地
  73. function SubGameVersionManager:saveVersionsToFile()
  74. local locString = json.encode(self.GameVersions)
  75. logD("SubGameVersionManager:saveVersionsToFile() locString = ", locString)
  76. saveUserInfo(self.GameVersionsKey, locString)
  77. end
  78. -- 保存子游戏的资源版本号
  79. function SubGameVersionManager:saveSubGameVersion(gameId, newVersion)
  80. if not self.GameVersions then
  81. self.GameVersions = {}
  82. end
  83. self.GameVersions[tonumber(gameId)] = newVersion
  84. self:saveVersionsToFile()
  85. end
  86. -- 子游戏是否已安装
  87. function SubGameVersionManager:isInstaller(gameId)
  88. gameId = tonumber(gameId)
  89. -- WIN32且未开启测试,则默认已安装
  90. if isWin32Platform() and self.isTestUpdate == false then
  91. return true
  92. end
  93. if (gameId and self.GameVersions and self.GameVersions[gameId]) then
  94. return true
  95. else
  96. return false
  97. end
  98. end
  99. -- 子游戏是否需要更新
  100. function SubGameVersionManager:isNeedUpdate(gameId)
  101. logD("SubGameVersionManager:isNeedUpdate()", gameId)
  102. -- WIN32且未开启测试,则默认不需要更新
  103. if isWin32Platform() and self.isTestUpdate == false then
  104. return false
  105. end
  106. -- 检查该游戏的基础包
  107. local subGameConfig = getSubGameConfig(gameId)
  108. if subGameConfig and subGameConfig.fremworkId then
  109. if self:isNeedUpdate(subGameConfig.fremworkId) then
  110. return true
  111. end
  112. end
  113. local verLocal = self:getSubGameVersionNum(gameId)
  114. local verServer = app.serverConfigs:getSubGameVersionNum(gameId)
  115. logD(string.format("SubGameVersionManager:isNeedUpdate() gameId = %s, verLocal = %s, verServer = %s", gameId, verLocal, verServer))
  116. -- 如果本地没有安装,肯定是需要更新的
  117. if tonumber(verLocal) == -1 then
  118. logD(string.format("SubGameVersionManager:isNeedUpdate() gameId = %s, verLocal = %s", gameId, verLocal))
  119. return true
  120. end
  121. -- 无需更新的情况
  122. if tonumber(verServer) == 0 or tonumber(verLocal) == tonumber(verServer) then
  123. logD("SubGameVersionManager:isNeedUpdate() 无需更新")
  124. return false
  125. end
  126. -- 正常更新
  127. if tonumber(verLocal) < tonumber(verServer) then
  128. logD("SubGameVersionManager:isNeedUpdate() 正常更新")
  129. return true
  130. end
  131. -- 版本回退
  132. if tonumber(verLocal) > tonumber(verServer) then
  133. logD("SubGameVersionManager:isNeedUpdate() 版本回退")
  134. local writablePath = cc.FileUtils:getInstance():getWritablePath()
  135. local rootName = nil
  136. local subGameConfig = getSubGameConfig(gameId)
  137. if subGameConfig then
  138. rootName = subGameConfig.rootName
  139. elseif FRAMEWORK_DIR[gameId] then
  140. rootName = FRAMEWORK_DIR[gameId]
  141. end
  142. logD("SubGameVersionManager:isNeedUpdate() rootName = ", tostring(rootName))
  143. if rootName then
  144. local subGameResPath = writablePath .. RomSetting.Platform .. "/" .. rootName .. "/"
  145. logD("SubGameVersionManager:isNeedUpdate() subGameResPath = ", subGameResPath)
  146. cc.FileUtils:getInstance():removeDirectory(subGameResPath)
  147. cc.FileUtils:getInstance():purgeCachedEntries()
  148. self:saveSubGameVersion(gameId, nil)
  149. end
  150. return true
  151. end
  152. -- 能走到这里来肯定是有问题的
  153. error("SubGameVersionManager:isNeedUpdate()")
  154. return false
  155. end
  156. -- 判断某个游戏是否正在更新中
  157. function SubGameVersionManager:isUpdating(gameId)
  158. return self.updaterList[tonumber(gameId)] ~= nil
  159. end
  160. ---
  161. -- 获取更新任务,包含子游戏及子游戏依赖的框架,可能有多重嵌套依赖
  162. -- @param {number} gameId 子游戏id
  163. -- @return {table} 下载任务 {{gameId = 123, isUpdated = false}, {...}}
  164. --
  165. --
  166. function SubGameVersionManager:getSubGameUpdateTasks (gameId)
  167. if not gameId then
  168. logE("SubGameVersionManager:getSubGameUpdateTasks", "参数gameId不能为空!")
  169. return 0
  170. end
  171. local gameVersionInfo = app.serverConfigs:getSubGameVersionInfo(gameId)
  172. if not gameVersionInfo then
  173. -- 子游戏配置信息不存在,返回0,不下载
  174. return 0
  175. end
  176. local updateTasks = {
  177. {gameId = gameId, isUpdated = false},
  178. }
  179. local subGameConfig=getSubGameConfig(gameId)
  180. while (subGameConfig and subGameConfig.fremworkId and subGameConfig.fremworkId > 0) do
  181. local isNeedUpdate = self:isNeedUpdate(subGameConfig.fremworkId)
  182. if isNeedUpdate then
  183. table.insert(updateTasks, 1, {gameId = subGameConfig.fremworkId, isUpdated = false})
  184. end
  185. subGameConfig = getSubGameConfig(subGameConfig.fremworkId)
  186. end
  187. return updateTasks;
  188. end
  189. ---
  190. -- 更新子游戏
  191. -- @param gameId 子游戏id
  192. -- @param percentCallback 百分比回调函数
  193. -- @param finishCallBack 下载完成回调函数
  194. -- @return
  195. --
  196. function SubGameVersionManager:updateSubGame(gameId, percentCallback, finishCallBack)
  197. logD("SubGameVersionManager:updateSubGame()", gameId)
  198. local gameVersionInfo = app.serverConfigs:getSubGameVersionInfo(gameId)
  199. if not gameVersionInfo then
  200. -- 如果游戏配置不存在,直接返回
  201. logD("游戏配置不存在,不进行更新操作!")
  202. if finishCallBack then
  203. finishCallBack();
  204. end
  205. return
  206. end
  207. self.subGameUpdateTasks = self:getSubGameUpdateTasks(gameId) -- 需要更新的任务
  208. self.subGameTaskCount = table.nums(self.subGameUpdateTasks) -- 需要更新的任务总数
  209. self.curSubGameUpdateIndex = 1 -- 当前第几个任务
  210. if self.subGameTaskCount == 0 then
  211. logD("SubGameVersionManager:updateSubGame", "没有可更新的子游戏")
  212. return
  213. end
  214. -- 开始执行子游戏更新
  215. logD("SubGameVersionManager:updateSubGame", "开始执行子游戏更新", table.tostring(self.subGameUpdateTasks))
  216. self:startUpdateSubGame(percentCallback, finishCallBack)
  217. end
  218. ---
  219. -- 开始执行子游戏更新
  220. -- @param percentCallback 百分比回调函数
  221. -- @param finishCallBack 下载完成回调函数
  222. -- @return
  223. --
  224. function SubGameVersionManager:startUpdateSubGame(percentCallback, finishCallBack)
  225. logD("SubGameVersionManager:startUpdateSubGame()")
  226. if table.nums(self.subGameUpdateTasks) == 0 then
  227. logD("SubGameVersionManager:startUpdateSubGame", "所有子游戏下载完成!")
  228. -- 所有任务下载完成,强制显示100%
  229. if percentCallback then
  230. percentCallback(100)
  231. end
  232. -- 所有任务下载完成,执行下载完成回调
  233. if finishCallBack then
  234. finishCallBack()
  235. end
  236. return
  237. end
  238. local task = table.remove(self.subGameUpdateTasks, 1)
  239. logD("SubGameVersionManager:startUpdateSubGame", "开始下载子游戏,gameId:", task.gameId)
  240. if self:isNeedUpdate(task.gameId) then
  241. self:updateGame(task.gameId, function (num)
  242. -- 更新下载进度,多个任务下载时,根据当前任务索引,加上之前的下载进度
  243. percentCallback((self.curSubGameUpdateIndex - 1) / self.subGameTaskCount * 100 + num / self.subGameTaskCount)
  244. end, function ()
  245. self.curSubGameUpdateIndex = self.curSubGameUpdateIndex + 1
  246. self:startUpdateSubGame(percentCallback, finishCallBack)
  247. end)
  248. else
  249. self:startUpdateSubGame(percentCallback, finishCallBack);
  250. end
  251. end
  252. function SubGameVersionManager:updateGame(gameId, percentCallback, finishCallBack)
  253. logD("SubGameVersionManager:updateGame", "curSubGameUpdateIndex", self.curSubGameUpdateIndex)
  254. logD("SubGameVersionManager:updateGame()", gameId)
  255. local gameVersionInfo = app.serverConfigs:getSubGameVersionInfo(gameId)
  256. gameVersionInfo.gameId = gameId
  257. --框架ID添加
  258. if gameId > 1000 then
  259. gameVersionInfo.show = false
  260. end
  261. dump(gameVersionInfo)
  262. local function onFinishCallback(newVersion)
  263. logD("SubGameVersionManager:updateSubGame() onFinishCallback()", gameId, newVersion)
  264. -- 修改数据
  265. self:saveSubGameVersion(gameId, newVersion)
  266. --上报游戏版本
  267. app.php:requestReportGameVer(gameId, newVersion)
  268. -- 删除下载器
  269. self.updaterList[gameId] = nil
  270. -- 触发回调
  271. if finishCallBack then
  272. logD("SubGameVersionManager:updateSubGame() onFinishCallback() call finishCallBack")
  273. finishCallBack(newVersion)
  274. else
  275. logD("SubGameVersionManager:updateSubGame() onFinishCallback() finishCallBack is nil")
  276. end
  277. end
  278. local updater = import("luaScript.SubGame.SubGameUpdater"):new(gameVersionInfo, percentCallback, onFinishCallback)
  279. if updater then
  280. -- 保存下载器
  281. self.updaterList[gameId] = updater
  282. -- 开始下载
  283. updater:start();
  284. end
  285. end
  286. -- 更换回调函数
  287. function SubGameVersionManager:updateCallback(gameId, percentCallback, finishCallBack)
  288. local updater = self.updaterList[gameId]
  289. if updater then
  290. local function onFinishCallback(newVersion)
  291. logD("SubGameVersionManager:updateCallback() onFinishCallback()", gameId, newVersion)
  292. -- 修改数据
  293. self:saveSubGameVersion(gameId, newVersion)
  294. -- 删除下载器
  295. self.updaterList[gameId] = nil
  296. -- 触发回调
  297. if finishCallBack then
  298. logD("SubGameVersionManager:updateCallback() onFinishCallback() call finishCallBack")
  299. finishCallBack(newVersion)
  300. else
  301. logD("SubGameVersionManager:updateCallback() onFinishCallback() finishCallBack is nil")
  302. end
  303. end
  304. updater:updateCallback(percentCallback, onFinishCallback)
  305. end
  306. end
  307. -- 获取已安装的游戏列表
  308. function SubGameVersionManager:getGameListInstalled()
  309. local listIds
  310. -- 这里不能遍历服务器配置中的列表
  311. -- 因为如果某个子游戏隐藏了,机器人开的房间要能进去
  312. for k,v in pairs(GAME_IDS) do
  313. if self:isInstaller(v) then
  314. if not listIds then
  315. listIds = tostring(v)
  316. else
  317. listIds = listIds .. "," .. tostring(v)
  318. end
  319. end
  320. end
  321. return listIds;
  322. end
  323. -- local fileName = "gameUserTime.data"
  324. -- function SubGameVersionManager:loadFromFile()
  325. -- local jsonString = loadStringFromFile(fileName)
  326. -- if jsonString then
  327. -- self.info = json.decode(jsonString) or {}
  328. -- end
  329. -- end
  330. -- -- 保存信息到本地文件
  331. -- function SubGameVersionManager:saveToFile(gameId)
  332. -- local time = os.time()
  333. -- self.info[tostring(gameId)] = time
  334. -- local jsonString = json.encode(self.info)
  335. -- saveStringToFile(jsonString, fileName)
  336. -- end
  337. function SubGameVersionManager:clearGame(gameId, endCallback)
  338. local rootName = nil
  339. local gameConfig = getSubGameConfig(gameId)
  340. if gameConfig and gameConfig.rootName then
  341. rootName = gameConfig.rootName
  342. end
  343. if FRAMEWORK_DIR[gameId] then
  344. rootName = FRAMEWORK_DIR[gameId]
  345. end
  346. if rootName then
  347. local writablePath = cc.FileUtils:getInstance():getWritablePath()
  348. if gameConfig and gameConfig.resDirs then
  349. for k,v in pairs(gameConfig.resDirs) do
  350. local dir = writablePath..app.config.RomSetting.Platform.."/"..v.."/";
  351. logD("SubGameVersionManager:clearGame() removeDirectory, dir = ", dir);
  352. cc.FileUtils:getInstance():removeDirectory(dir)
  353. end
  354. else
  355. local dir = writablePath..app.config.RomSetting.Platform.."/"..rootName.."/";
  356. logD("SubGameVersionManager:clearGame() removeDirectory, dir = ", dir);
  357. cc.FileUtils:getInstance():removeDirectory(dir)
  358. end
  359. self.GameVersions[gameId]=nil
  360. self:saveVersionsToFile()
  361. end
  362. app.serverConfigs:requestGetSubGameVersions(endCallback)
  363. end
  364. function SubGameVersionManager:checkSubGameFiles(gameId)
  365. logD("SubGameVersionManager:checkSubGameFiles() gameId = " .. gameId);
  366. if isWin32Platform() then
  367. return true
  368. end
  369. local rootName = nil
  370. local gameConfig = getSubGameConfig(gameId)
  371. if gameConfig and gameConfig.rootName then
  372. rootName = gameConfig.rootName
  373. end
  374. if FRAMEWORK_DIR[gameId] then
  375. rootName = FRAMEWORK_DIR[gameId]
  376. end
  377. if not rootName then
  378. return true, gameId, {}
  379. end
  380. local writablePath = cc.FileUtils:getInstance():getWritablePath()
  381. local filesfile = app.config.RomSetting.Platform .. "/" .. rootName .. "/" .. "files.txt";
  382. logD("SubGameVersionManager:checkSubGameFiles() filesfile = ", filesfile);
  383. local result, missingfiles = checkFilesExist(filesfile)
  384. return result, gameId, missingfiles;
  385. end
  386. -- 检查子游戏文件的完整性
  387. function SubGameVersionManager:checkGameFiles(gameId)
  388. logD("SubGameVersionManager:checkGameFiles() gameId = ", gameId);
  389. local result, subGameId, missingfiles = self:checkSubGameFiles(gameId)
  390. if not result then
  391. return result, subGameId, missingfiles
  392. end
  393. local gameConfig = getSubGameConfig(gameId)
  394. if gameConfig and gameConfig.fremworkId then
  395. logD("SubGameVersionManager:checkGameFiles() fremworkId = ", gameConfig.fremworkId);
  396. local result, subGameId, missingfiles = self:checkSubGameFiles(gameConfig.fremworkId)
  397. if not result then
  398. return result, subGameId, missingfiles
  399. end
  400. end
  401. return true, gameId, {};
  402. end
  403. return SubGameVersionManager