|
- require("preload.PluginPatcher")
-
- --[[
- 更新流程
- 1、获取服务器信息
- 2、更新资源
- 4.1 如果无需更新,则跳过此步骤
- 4.2 下载差分包并解压
- 3、如果是android,先检查APK更新。
- 2.1 如果无需更新,则跳过此步骤
- 2.2 下载差分包
- 2.3 合并新的APK
- 2.4 安装新的APK
- 4、检查强更版本号。
- 3.1 如果无需更新,则跳过此步骤
- 3.2 如果需要更新,则弹出更新提示
- 5、检查文件完整性
- 6、完成更新
- 6.1 如果本次没有更新资源,则完成更新
- 6.2 如果本次有更新内容,则提示玩家重启游戏。否则直接进入游戏
- --]]
-
- local AutoUpdater = {};
- AutoUpdater.__index = AutoUpdater;
-
- local writablePath = cc.FileUtils:getInstance():getWritablePath()
- local updateConfirmSize = 5 * 1024 * 1024
- local tempDir = os.date("%Y%m%d%H%M", os.time());
- local tempFile="tempFile.zip"
-
- local zipFileDir = writablePath .. tempDir .. '/'
- local zipFilePath = zipFileDir .. tempFile;
-
- -- 创建新对象
- function AutoUpdater:new(...)
- local instance = {};
- setmetatable(instance , AutoUpdater);
- instance:ctor(...);
- return instance;
- end
-
- function AutoUpdater:ctor(romSetting, mainScene, onFinsishCallback)
-
- -- 保存全局配置
- self.romSetting = romSetting
- self.onFinsishCallback = onFinsishCallback
-
- self.Packages={}
-
- self.OldFiles={}
- self.NewFiles={}
-
- -- 渲染视图
- self.View = require("preload.AutoUpdate.AutoUpdaterView"):new(self, mainScene)
-
- -- 是否提示过APK更新
- self.isShowApkPatch = false;
-
- --是否清理过文件
- self.IsCleanFile = false
-
- --是否更新过程出现问题
- self.IsError=false
-
- -- 是否更新了资源
- self.isUpdateRes = false;
-
- -- 标记本次更新是否已经成功获取到配置信息了
- self.isGetServerConfigSuccessed = false
- end
-
- function AutoUpdater:doNext()
- logD("AutoUpdater:doNext()");
- if #self.execQueue > 0 then
- local execFunc = self.execQueue[1]
- table.remove(self.execQueue, 1)
- if execFunc then
- execFunc()
- end
- else
- self:onUpdateFinished()
- end
- end
-
- function AutoUpdater:startUpdate()
- logD("AutoUpdater:startUpdate()");
-
- self.execQueue = {}
- table.insert(self.execQueue, handler(self, self.getServerConfigs))
- table.insert(self.execQueue, handler(self, self.updateRes))
- table.insert(self.execQueue, handler(self, self.updateApk))
- table.insert(self.execQueue, handler(self, self.updateForce ))
- table.insert(self.execQueue, handler(self, self.checkFilesExist))
-
- self:doNext()
- end
-
- function AutoUpdater:getServerConfigs()
- logD("AutoUpdater:getServerConfigs()");
-
- self.isGetServerConfigSuccessed = false
- local function onEndGetServerConfig(isSuccessed)
- logD("AutoUpdater:onEndGetServerConfig(), isSuccessed = ", tostring(isSuccessed));
- if isSuccessed then
- if not self.isGetServerConfigSuccessed then
- self.isGetServerConfigSuccessed = true
- self:doNext()
- else
- logD("AutoUpdater:getServerConfigs(), 重复收到服务器的配置数据,本次不处理");
- end
- else
- self:dispatchEvent("error", "初始化失败,请更换网络后重试")
- end
- end
-
- if isIOSPlatform() then
- checkNetWorkPermission(function()
- getServerConfigs(onEndGetServerConfig, true)
- end)
- else
- getServerConfigs(onEndGetServerConfig, true)
- end
- end
-
- -- 更新资源
- function AutoUpdater:updateRes()
- logD("AutoUpdater:updateStart() 检查资源更新")
- if PhpSetting.update.url=="" or PhpSetting.update.md5=="" then
- local ver = loadVersion()
- if tonumber(ver) ~= tonumber(PhpSetting.update.ver) and not self.IsCleanFile then
- logD("AutoUpdater:updateStart() 找不到版本,开始清理数据")
- self:ClearDatingCache()
-
- self:startUpdate()
- self.IsCleanFile = true
- else
- logD("AutoUpdater:updateStart() 版本一致,无需更新")
- self:doNext()
- end
- return
- end
-
- -- 有文件需要更新
- logD("AutoUpdater:updateStart() 有文件需要更新")
- self.isUpdateRes = true;
-
- self.DownloadedFileSize=tonumber(PhpSetting.update.size)
-
- local function onFinishDownZip()
- logD("AutoUpdater:onFinishDownZip(), 下载差分包完成");
- local md5=cc.FileUtils:getInstance():md5File(zipFilePath)
- if md5~=PhpSetting.update.md5 then
- logD("AutoUpdater:onFinishDownZip(), 校验差分包失败, update.md5 = " .. PhpSetting.update.md5 );
- logD("AutoUpdater:onFinishDownZip(), 校验差分包失败, md5 = " .. md5 );
- os.remove(zipFilePath)
- self:dispatchEvent("error",PLN.FILE_CHECKSUM_FAILED)
- return
- end
-
- self:dispatchEvent("zip",{text=PLN.UPDATING_RES,percent=1})
-
- runDelayWithTime(function()
- local isZipSuccessed=cc.FileUtils:getInstance():decompress(zipFilePath)
- os.remove(zipFilePath)
-
- logD("AutoUpdater:onFinishDownZip(), 解压差分包完成" );
-
- if isZipSuccessed then
- local move_result = move_dir(zipFileDir, writablePath);
- if move_result then
- logD("AutoUpdater:onFinishDownZip() need restart");
- local function OnClickOk()
- cc.Application:getInstance():restart()
- end
- local tipsMessage = "更新完成,点击确认重启游戏"
- showTipsView(tipsMessage, OnClickOk, nil)
- else
- self:dispatchEvent("error",PLN.FILE_MOVE_FAILED)
- end
- else
- self:dispatchEvent("error",PLN.FILE_UNCOMPRESS_FAILED)
- end
-
- remove_dir(zipFileDir)
- end,0.01)
- end
-
- local function onState( state, msg )
- logD("AutoUpdater:updateRes() onState() :", state, msg)
- if state=="progress" then
- local percent = msg--self.DownloadedFileSize*msg / self.DownloadedFileSize;
- self:dispatchEvent("downloadFile" , {text = string.format(PLN.DOWNLOADING_FILE , self.DownloadedFileSize*percent / 1024 / 1024 , self.DownloadedFileSize / 1024 / 1024 , percent * 100) , percent = percent});
- elseif state=="successed" then
- local percent = 1
- self:dispatchEvent("downloadFile" , {text = string.format(PLN.DOWNLOADING_FILE , self.DownloadedFileSize*percent / 1024 / 1024 , self.DownloadedFileSize / 1024 / 1024 , percent * 100) , percent = percent});
-
- runDelayWithTime(function()
- onFinishDownZip()
- end,0.01)
- else
- self:dispatchEvent("error",PLN.DOWNLOAD_FILE_FAILED)
- end
- end
-
- if not cc.FileUtils:getInstance():isDirectoryExist(zipFileDir) then
- if not cc.FileUtils:getInstance():createDirectory(zipFileDir) then
- logD("AutoUpdater:updateStart() createDirectory failed :" .. zipFileDir)
- end
- end
-
- downloadFileByUrls2(PhpSetting.update.url, onState, zipFilePath)
- end
-
- -- 更新APK
- function AutoUpdater:updateApk()
-
- if self.isShowApkPatch then
- self:doNext()
- return
- end
- self.isShowApkPatch = true;
-
- logD("AutoUpdater:updateApk()")
- if isAndroidPlatform() and PhpSetting.apkupdate and PhpSetting.apkupdate.url ~= nil and PhpSetting.apkupdate.url ~= "" then
-
- local function installNewApk(apk_file)
- logD("AutoUpdater:installNewApk() apk_file = ", apk_file)
- patcherInstallApk(apk_file);
- end
-
- local function mergePatchToApk(patchFilePath)
- logD("AutoUpdater:mergePatchToApk() patchFilePath = ", patchFilePath)
-
- self:dispatchEvent("info","正在生成新的安装包")
-
- local patch_file = patchFilePath;
- local patch_md5 = PhpSetting.apkupdate.md5;
- local apk_file = writablePath .. PhpSetting.apkupdate.ver .. ".apk";
- local apk_md5 = PhpSetting.apkupdate.apkmd5
-
- local result = patcherMakeApk(patch_file, patch_md5, apk_file, apk_md5);
- logD("AutoUpdater:mergePatchToApk() result = ", result)
-
- if result then
- installNewApk(apk_file);
- else
- self:doNext()
- end
- end
-
- local function downloadPatch ()
- local totalSize = tonumber(PhpSetting.apkupdate.size)
- local currentSize = 0;
- self:dispatchProgress(currentSize, totalSize);
-
- local patchFilePath = writablePath .. PhpSetting.apkupdate.ver .. ".patch";
- logD("AutoUpdater:downloadPatch() patchFilePath = ", patchFilePath)
-
- local function onState( state, msg )
- logD("AutoUpdater:downloadPatch() onState() :", state, msg)
- if state=="progress" then
- local percent = msg
- currentSize = totalSize * percent;
- self:dispatchProgress(currentSize, totalSize);
- elseif state=="successed" then
- local percent = 1
- currentSize = totalSize
- self:dispatchProgress(currentSize, totalSize);
-
- runDelayWithTime(function()
- mergePatchToApk(patchFilePath)
- end,0.01)
- else
- self:dispatchEvent("error",PLN.DOWNLOAD_FILE_FAILED)
- -- 如果下载失败就直接进入下一步,检测强制更新
- self:checkUpdate();
- end
- end
-
- logD("AutoUpdater:downloadPatch() url = ", PhpSetting.apkupdate.url)
- downloadFileByUrls2(PhpSetting.apkupdate.url, onState, patchFilePath)
- end
-
- local function onClickOk()
- downloadPatch();
- end
-
- local function onClickCancel()
- self:doNext()
- end
-
- -- 提示信息
- local content = PhpSetting.apkupdate.content;
- if content == nil or content == "" then
- content = "发现有新的安装包可以使用,是否下载新的安装包?"
- end
-
- -- 是否可以取消更新
- if PhpSetting.apkupdate.update_type == 2 then
- onClickCancel = nil
- end
-
- -- 点击确定后是否关闭界面
- local closeWhenOk = true;
-
- require("preload.AutoUpdate.UpdateTipsView"):new(content, onClickOk, onClickCancel, closeWhenOk)
- return
- else
- self:doNext()
- end
- end
-
- -- 检查强更版本
- function AutoUpdater:updateForce()
- if PhpSetting and PhpSetting.force then
- -- 检查强制更新
- if tonumber(PhpSetting.force.isForce) > 0 then
- local title = "发现新版本"
- local content = PhpSetting.force.tips or ""
- local url = PhpSetting.force.url
- if not url or url == "" then
- url = self.romSetting.downloadUrl
- end
- if not url or url == "" then
- url = "https://www.baidu.com"
- end
- local function onClick(ret)
- logD("AutoUpdater:updateForce() onClick, url = ", tostring(url))
- if PluginDevice then
- PluginDevice:callVoid("openUrl", url)
- else
- logD("AutoUpdater:updateForce() PluginDevice is nil")
- end
- end
- require("preload.AutoUpdate.UpdateTipsView"):new(content, onClick )
- return
- end
- -- 检查提示更新
- if tonumber(PhpSetting.force.isTips) > 0 then
- local title = "发现新版本"
- local content = PhpSetting.force.tips or ""
- local url = PhpSetting.force.url
- if not url or url == "" then
- url = self.romSetting.downloadUrl
- end
- if not url or url == "" then
- url = "https://www.baidu.com"
- end
- local function onClickOk(ret)
- logD("AutoUpdater:updateForce() onClickOk, url = ", tostring(url))
- if PluginDevice then
- PluginDevice:callVoid("openUrl", url)
- else
- logD("AutoUpdater:updateForce() PluginDevice is nil")
- end
- end
- local function onClickCancel(ret)
- logD("AutoUpdater:updateForce() onClickCancel")
- self:doNext()
- end
-
- require("preload.AutoUpdate.UpdateTipsView"):new(content,onClickOk, onClickCancel)
- return
- end
- end
-
- self:doNext()
- end
-
- -- 检查文件是否完整
- function AutoUpdater:checkFilesExist()
- local files_list_file = self.romSetting.Platform .. "/files.txt"
- local ret, missing_files_list = checkFilesExist(files_list_file)
- if ret then
- logD("AutoUpdater:checkFilesExist(), 校验完成,未发现文件缺失");
- self:doNext();
- else
- logD("AutoUpdater:checkFilesExist(), 校验完成,发现有文件丢失");
- local function OnClickOk()
- self:ClearDatingCache()
- cc.Application:getInstance():restart()
- end
- local tipsMessage = "发现有文件丢失,点击确定开始修复"
- showTipsView(tipsMessage, OnClickOk, nil)
- end
- end
-
- -- 更新完成
- function AutoUpdater:onUpdateFinished()
- logD("AutoUpdater:onUpdateFinished()");
- self:dispatchEvent("finish", "更新完成!")
-
- if self.isUpdateRes then
- logD("AutoUpdater:onUpdateFinished() need restart");
- local function OnClickOk()
- cc.Application:getInstance():restart()
- end
- local tipsMessage = "更新完成,点击确认重启游戏"
- showTipsView(tipsMessage, OnClickOk, nil)
- else
- logD("AutoUpdater:onUpdateFinished() not need restart");
- if self.onFinsishCallback then
- self.onFinsishCallback()
- end
- self.View:onExit();
- end
- end
-
- -- 通知界面显示当前进度
- function AutoUpdater:dispatchProgress(currentSize, totalSize)
- local percent = currentSize / totalSize
- self:dispatchEvent("downloadFile" , {text = string.format(PLN.DOWNLOADING_FILE , currentSize / 1024 / 1024 , totalSize / 1024 / 1024 , percent * 100) , percent = percent});
- end
-
- -- 派发一个更新事件给外部侦听者
- function AutoUpdater:dispatchEvent(eventName , eventValue)
- logD("AutoUpdater:dispatchEvent()" , eventName , eventValue);
-
- --[[
- if eventName == "error" then
- self.IsError=true
- uploadErrorLogs("AutoUpdaterError");
- end
- --]]
-
- self.View:showProgress(eventName , eventValue);
-
- if eventName == "error" then
- local function OnClickOk()
- cc.Application:getInstance():restart()
- end
- -- 上报更新错误
- uploadLogs(GAME_ERROR_TYPE.UPDATEFAILED)
- -- 提示更新失败
- local tipsMessage = "出错了,点击确定重新开始更新"
- showTipsView(tipsMessage, OnClickOk, nil)
- end
- end
-
- -- 清理大厅的缓存文件
- function AutoUpdater:ClearDatingCache()
- logD("AutoUpdater:ClearDatingCache() 清理大厅的缓存文件")
-
- local corePath = writablePath.."core/"
- local datingRomFiles = writablePath..self.romSetting.Platform.."/romFiles/"
- local datingPreload = writablePath..self.romSetting.Platform.."/preload/"
- local datingScript = writablePath..self.romSetting.Platform.."/luaScript/"
- local datingRes = writablePath..self.romSetting.Platform.."/res/"
-
- cc.FileUtils:getInstance():removeDirectory(corePath)
- cc.FileUtils:getInstance():removeDirectory(datingRomFiles)
- cc.FileUtils:getInstance():removeDirectory(datingPreload)
- cc.FileUtils:getInstance():removeDirectory(datingScript)
- cc.FileUtils:getInstance():removeDirectory(datingRes)
-
- local filesListPath = writablePath..self.romSetting.Platform.."/files.txt"
- os.remove(filesListPath)
-
- cc.FileUtils:getInstance():purgeCachedEntries()
-
- --logD("删除UserConfig.xml")
- --os.remove(writablePath .. "UserConfig.xml")
- end
-
-
- return AutoUpdater;
|