cocos2d-x+lua 开发之lua代码热更新专题1

*大概步骤:
1、Lua脚本目录设置,如把脚本目录文件夹命名LuaScript
2、需要实现一个下载实现以及更新等待的更新场景
3、更新完成后delete Lua虚拟机,然后重新require lua文件,然后进入游戏

详细说明:
一般来说,我们打APK包或者ipa包的时候,会把游戏的资源打进包里面(apk 包一般把资源放到assets目录下assets/LuaScript )我们叫做包资源;我们从我们的资源服务器更新下来的资源叫做更新资源,一般我们在android的SD卡或者是data新创建目录来存放更新的资源 如:xgame/LuaScript , xgame/Image xgame/Music)

现在我们要做的就是要在appdategate 里面设置LUA文件搜索路径,优先搜索下载目录,程序启动时设置lua的搜索路径:1、设置lua优先搜索路径为上述说的 android SD 卡xgame路径下的LuaScript文件夹;2、再搜索api或者apk里面事先打包进去的LuaScirpt文件夹。

void initLua()
{

CCLuaEngine* pEngine = CCLuaEngine::defaultEngine();
CCScriptEngineManager::sharedManager()->setScriptEngine(pEngine);

//library cache path
//分平台实现不同平台下的library目录路径的获取
std::string cachePath = kt_library_path() + "/Caches/";

//app、apk path
std::string bundleLuaPath = CCFileUtils::sharedFileUtils()->fullPathFromRelativePath(LUA_DIR_NAME);

std::string cacheLuaPath = cachePath + "LuaScript";
std::string cacheXMLPath = cachePath + "XML";

//check
std::string oldVersion = CCUserDefault::sharedUserDefault()->getStringForKey("AppVersion");
//分平台实现了getVersion方法以获取不同平台下的bundle 版本号
std::string newVersion = KTChannel_Help::sharedInstance()->getVersion();

if (oldVersion.empty()) {
    CCUserDefault::sharedUserDefault()->setStringForKey("AppVersion", newVersion);
    CCUserDefault::sharedUserDefault()->flush();
    kt_remove_dir(cacheLuaPath.c_str());
    kt_remove_dir(cacheXMLPath.c_str());
}
else {
    if (kt_compareVersion(oldVersion, newVersion)) {
        //newVersion > oldVersion
        CCUserDefault::sharedUserDefault()->setStringForKey("AppVersion", newVersion);
        CCUserDefault::sharedUserDefault()->flush();
        kt_remove_dir(cacheLuaPath.c_str());
        kt_remove_dir(cacheXMLPath.c_str());
    }
    else {
    }
}

pEngine->addSearchPath(cacheLuaPath.c_str(), bundleLuaPath.c_str());

std::string tempPath = cacheLuaPath + "/version.lua";

if (kt_isFileExist(tempPath.c_str())) {
    luaFilePathPrefix = cacheLuaPath + "/";
}
else {
    luaFilePathPrefix = bundleLuaPath + "/";
}

}

void setLuaSearchPath(std::string firstPath, std::string secondPath)
{
CCLuaEngine* pEngine = CCLuaEngine::defaultEngine();
pEngine->addSearchPath(firstPath.c_str(), secondPath.c_str());
}

//修改了一下引擎里面的搜索路劲代码
void CCLuaEngine::addSearchPath(const char* path1, const char* path2)
{
lua_getglobal(m_state, “package”);/* stack: package */
lua_getfield(m_state, -1, “path”);/* get package.path, stack: package path */
const char* cur_path = lua_tostring(m_state, -1);
lua_pop(m_state, 1);/* stack: package */
lua_pushfstring(m_state, “%s;%s/?.lua;%s/?.lua”, cur_path, path1, path2);/* stack: package newpath */
lua_setfield(m_state, -2, “path”);/* package.path = newpath, stack: package */
lua_pop(m_state, 1);/* stack: - */
}

获取游戏在userdefault.xml里面存储的版本号AppVersion,若此值为空,那么用户第一次下载次游戏,此时为了安全起见删除Caches里面的Luascript文件夹。
若此值非空,则和程序包的bundle版本号比较BundleVersion, 若AppVersion 大于BundleVersion,则不用处理,
若AppVersion小于BundleVersion则需要删除xgame下的LuaScript文件夹来保证本地版本的最新.
此处这样做的目的是为了解决用户在1.0版本时热更新过Lua,之后用户在商店里更新了2.0版本的游戏包(只会更新.app Library等其余三个目录不会变),此时2.0版本里面的lua版本号可能低于
本地lua版本号,虽然游戏版本号比较新但是游戏包中事先打包的lua版本号比较旧。

c.设定了搜索路径后,我们需要读取本地该渠道的lua的版本号来对比服务端的该渠道(例如appstore)lua版本号,以此来决定是否需要下载更新包,需要的话就下载加密的zip包到本地解压到Caches里来覆盖之前的Luascript,当然我们程序里面的所有lua文件都是RSA加密的,放心吧!

猜你喜欢

转载自blog.csdn.net/u014043213/article/details/65935308