hot_UpdateModel - woodelf-treetop/rcwiki GitHub Wiki

热更模块

我们热更中主要的用到的脚本共四个:
GameManager.cs 进入游戏的主脚本,热更的控制逻辑,依赖于以下三个脚本
ThreadManager.cs 下载的逻辑
HotUpdateView.cs 界面显示的逻辑
CheckNetState.cs 热更过程中网络检测的逻辑

大致思路

以下都是默认开启bundle模式和热更模式

游戏启动后,从GameManager的Init()方法进入解压协成逻辑

private IEnumerator Init()
{
    //做一些数据初始化
    ...
        yield return StartCoroutine(CheckExtractResource()); //释放资源,并触发后续流程
    ...
}
IEnumerator CheckExtractResource()
{
    //这一块的主要逻辑是先拿到本地包体里面的Version文件读取数据,然后再查找包体外的地方有没有Version文件。
    //一、如果没有,则直接进行解压逻辑,解压后开启热更检测流程。
    //二、如果有,进行大版本号的对比,不匹配需要覆盖解压,匹配的话开启热更检测流程。
	...
}
		

热更检测开启

这里对 suspension.txt 文件的code值进行说明

0:正常进入 1:白名单可热更(热更大版本),非白名单(热更小版本)。正常能进游戏。————白名单热更下一版本的内容 2:白名单可热更,可进游戏。非白名单不能热更,不能进游戏(显示停服)。————都热更大版本,只有白名单能进游戏

   public IEnumerator CheckNeedUpdate()
   {
       /*
   
		一、由于有白名单的功能,所以我们需要先对【suspension.txt】和【whiteList.txt】两个文件进行解析,通过白名单和suspension里的开服配置id双重判断来确定当前玩家是:无法进入游戏、正常进入游戏、进入热更版本。这三种情况。
		二、这里下载【云端的clientVersion.txt】文件和【本地的clientVersion.txt】文件进行热更版本号的对比。详细代码已在下面代码块中给出。
   		三、下载file列表,进行热更检测。
   	*/
           
   }
private static int CheckUpdateVersion(IList<string> serverVersionData)
{
    //云端热更版本号大于本地时(checkNeedUpdate = 2),直接执行热更检测
    //云端热更版本号等于本地时(checkNeedUpdate = 1),判断是否应该要分包检测
    //云端热更版本号小于本地时(checkNeedUpdate = 0),不执行热更检测,也不执行分包检测            
    var checkNeedUpdate = 1;
    var completeVersion = serverVersionData[0].Replace("@", "");
    var gameVersion = int.Parse(GetStringBetweenChar(completeVersion, '.', 4, 3));
    var fileData = Util.DataPath + "clientVersion.txt";
    if (!File.Exists(fileData)) return checkNeedUpdate;
    var files = File.ReadAllLines(fileData);
    var updateVersion = files[0].Replace("@", "");
    var appConstGameVersion = int.Parse(GetStringBetweenChar(updateVersion, '.', 4, 3));
    if (gameVersion > appConstGameVersion)
    {
        checkNeedUpdate = 2;
    }
    else if (gameVersion == appConstGameVersion)
    {
        checkNeedUpdate = 1;
    }
    else
    {
        checkNeedUpdate = 0;
    }
    return checkNeedUpdate;
}

热更检测说明:这里是将云端和本地的files文件分别解析,存储为 key:资源路径 value:MD5的字典。
分包需要下载的资源也会写入到云端的字典里,然后两者先判断路径。路径不一样直接添加到热更字典里。路径一样,再判断MD5,MD5不一样添加到热更字典里。

开启热更

我们的热更就是通过 ThreadManager.cs 这个脚本实现的,用的是WebClient

我们用到了WebClient的两个回调。
client.DownloadProgressChanged += ProgressChanged; //下载进度回调
client.DownloadFileCompleted += NetFileCompleted;  //下载完成并写入后的回调
NetFileCompleted这个回调很有用,我们可以确保一个资源下载完成并且成功存储在了本地,才进行files文件的回写。可以避免写入没保存完成的资源。

具体操作如下图:

​ 每下载完一条写回本地的目的是:在热更的途中中断了下载,那么下次再热更的时候就会除去之前已经下载过的资源文件。

其他说明

GameManager整理过一次,在看的时候可以结合代码标记来看。

ThreadManager

​ 开始热更之后,会根据差异项数据下载每一条资源。每条资源下来的开始会将资源数据添加到线程下载事件,也就是利用ThreadManager.AddUpdateEvent方法添加到_updateEvents队列数据中。之后交给ThreadManager自己去执行队列下载。

HotUpdateView

HotUpdateView.cs里面基本都是和界面数据显示有关的,大部分是提供给外部调用的弹窗接口,以及界面底部显示的文字说明。另外在Update函数里有一个资源加载进度条,这段期间是指:热更完成之后↔调用Game.lua的OnInitOK之前。
1.ResourceManager.cs里完成预加载资源(0.4)。
2.接着调回GameManager.cs里的OnResourceInitOver()函数,完成AssetBundle初始化读取路径(0.7)
3.走到GameManager.cs里的OnXAssetInitOk(),做lua层的资源加载和初始化。(1.0)

CheckNetState

这个脚本主要处理下载过程中的网络状态,会根据不同状态提示玩家做哪些操作。 本地网络的判断基于Application.internetReachability这个属性,通过三种枚举值来判断:
NetworkReachability.NotReachable 无网络链接
NetworkReachability.ReachableViaLocalAreaNetwork WIFI状态下
NetworkReachability.ReachableViaCarrierDataNetwork 3G/4G状态

需要注意的地方

不能直接将方法名传进来 如:StopCoroutine(func)
这样是不行的,start的时候每次会创建一个新的Coroutine
所以我们在手动stop的时候需要结束 start返回的Coroutine

⚠️ **GitHub.com Fallback** ⚠️