int gbupdate_lua_loader(lua_State * L) { static const std::string FILE_EXT = ".lua"; std::string filename(luaL_checkstring(L, 1)); Data chunk; size_t pos = filename.rfind(FILE_EXT); if (pos == filename.length() - FILE_EXT.length()) { filename = filename.substr(0, pos); } pos = filename.find_first_of("."); while (pos != std::string::npos) { filename.replace(pos, 1, "/"); pos = filename.find_first_of("."); } do { GBUpdateInfo * pInfo = GBUpdate::getInstance()->getUpdateInfo(StringUtils::format("src/%s%s", filename.c_str(), FILE_EXT.c_str())); if (!pInfo) break; if (FILE()->isFileExist(pInfo->location)) { chunk = FILE()->getDataFromFile(pInfo->location); break; } } while (false); if (chunk.getBytes()) { LuaStack* stack = LuaEngine::getInstance()->getLuaStack(); stack->luaLoadBuffer(L, (char*)chunk.getBytes(), (int)chunk.getSize(), filename.c_str()); chunk.clear(); } else { CCLOG("can not get file data of %s", filename.c_str()); return 0; } return 1; }
int LuaStack::luaLoadChunksFromZIP(lua_State *L) { if (lua_gettop(L) < 1) { CCLOG("luaLoadChunksFromZIP() - invalid arguments"); return 0; } const char *zipFilename = lua_tostring(L, -1); lua_settop(L, 0); FileUtils *utils = FileUtils::getInstance(); std::string zipFilePath = utils->fullPathForFilename(zipFilename); LuaStack *stack = this; do { ssize_t size = 0; void *buffer = nullptr; unsigned char *zipFileData = utils->getFileData(zipFilePath.c_str(), "rb", &size); ZipFile *zip = nullptr; bool isXXTEA = stack && stack->_xxteaEnabled && zipFileData; for (int i = 0; isXXTEA && i < stack->_xxteaSignLen && i < size; ++i) { isXXTEA = zipFileData[i] == stack->_xxteaSign[i]; } if (isXXTEA) { // decrypt XXTEA xxtea_long len = 0; buffer = xxtea_decrypt(zipFileData + stack->_xxteaSignLen, (xxtea_long)size - (xxtea_long)stack->_xxteaSignLen, (unsigned char*)stack->_xxteaKey, (xxtea_long)stack->_xxteaKeyLen, &len); free(zipFileData); zipFileData = nullptr; zip = ZipFile::createWithBuffer(buffer, len); } else { if (zipFileData) { zip = ZipFile::createWithBuffer(zipFileData, size); } } if (zip) { CCLOG("lua_loadChunksFromZIP() - load zip file: %s%s", zipFilePath.c_str(), isXXTEA ? "*" : ""); lua_getglobal(L, "package"); lua_getfield(L, -1, "preload"); int count = 0; std::string filename = zip->getFirstFilename(); while (filename.length()) { ssize_t bufferSize = 0; unsigned char *zbuffer = zip->getFileData(filename.c_str(), &bufferSize); if (bufferSize) { // remove extension std::size_t found = filename.rfind(".lua"); if (found != std::string::npos) { filename.erase(found); } // replace path seperator '/' '\' to '.' for (int i=0; i<filename.size(); i++) { if (filename[i] == '/' || filename[i] == '\\') { filename[i] = '.'; } } CCLOG("[luaLoadChunksFromZIP] add %s to preload", filename.c_str()); if (stack->luaLoadBuffer(L, (char*)zbuffer, (int)bufferSize, filename.c_str()) == 0) { lua_setfield(L, -2, filename.c_str()); ++count; } free(zbuffer); } filename = zip->getNextFilename(); } CCLOG("lua_loadChunksFromZIP() - loaded chunks count: %d", count); lua_pop(L, 2); lua_pushboolean(L, 1); delete zip; } else { CCLOG("lua_loadChunksFromZIP() - not found or invalid zip file: %s", zipFilePath.c_str()); lua_pushboolean(L, 0); } if (zipFileData) { free(zipFileData); } if (buffer) { free(buffer); } } while (0); return 1; }
int cocos2dx_lua_loader(lua_State *L) { static const std::string BYTECODE_FILE_EXT = ".luac"; static const std::string NOT_BYTECODE_FILE_EXT = ".lua"; std::string filename(luaL_checkstring(L, 1)); size_t pos = filename.rfind(BYTECODE_FILE_EXT); if (pos != std::string::npos) { filename = filename.substr(0, pos); } else { pos = filename.rfind(NOT_BYTECODE_FILE_EXT); if (pos == filename.length() - NOT_BYTECODE_FILE_EXT.length()) { filename = filename.substr(0, pos); } } pos = filename.find_first_of("."); while (pos != std::string::npos) { filename.replace(pos, 1, "/"); pos = filename.find_first_of("."); } // search file in package.path unsigned char* chunk = nullptr; ssize_t chunkSize = 0; std::string chunkName; FileUtils* utils = FileUtils::getInstance(); lua_getglobal(L, "package"); lua_getfield(L, -1, "path"); std::string searchpath(lua_tostring(L, -1)); lua_pop(L, 1); size_t begin = 0; size_t next = searchpath.find_first_of(";", 0); do { if (next == std::string::npos) next = searchpath.length(); std::string prefix = searchpath.substr(begin, next); if (prefix[0] == '.' && prefix[1] == '/') { prefix = prefix.substr(2); } /// LZU /// Change loading to support path like './?/init.lua' /* pos = prefix.find("?.lua"); chunkName = prefix.substr(0, pos) + filename + BYTECODE_FILE_EXT; */ pos = prefix.find("?"); prefix = prefix.substr(0,pos) + filename + prefix.substr(pos+1); pos = prefix.find(".lua"); chunkName = prefix.substr(0,pos) + BYTECODE_FILE_EXT; /// END LZU if (utils->isFileExist(chunkName)) { chunk = utils->getFileData(chunkName.c_str(), "rb", &chunkSize); break; } else { /// LZU chunkName = prefix.substr(0,pos) + NOT_BYTECODE_FILE_EXT; // chunkName = prefix.substr(0, pos) + filename + NOT_BYTECODE_FILE_EXT; /// END LZU if (utils->isFileExist(chunkName)) { chunk = utils->getFileData(chunkName.c_str(), "rb", &chunkSize); break; } } begin = next + 1; next = searchpath.find_first_of(";", begin); } while (begin < (int)searchpath.length()); if (chunk) { LuaStack* stack = LuaEngine::getInstance()->getLuaStack(); stack->luaLoadBuffer(L, (char*)chunk, (int)chunkSize, chunkName.c_str()); free(chunk); } else { CCLOG("can not get file data of %s", chunkName.c_str()); return 0; } return 1; }
int LuaStack::luaLoadChunksFromZIP(lua_State *L) { if (lua_gettop(L) < 1) { CCLOG("luaLoadChunksFromZIP() - invalid arguments"); return 0; } const char *zipFilename = lua_tostring(L, -1); lua_settop(L, 0); FileUtils *utils = FileUtils::getInstance(); std::string zipFilePath = utils->fullPathForFilename(zipFilename); LuaStack *stack = this; do { void *buffer = nullptr; ZipFile *zip = nullptr; Data zipFileData(utils->getDataFromFile(zipFilePath)); unsigned char* bytes = zipFileData.getBytes(); ssize_t size = zipFileData.getSize(); bool isXXTEA = stack && stack->_xxteaEnabled && size >= stack->_xxteaSignLen && memcmp(stack->_xxteaSign, bytes, stack->_xxteaSignLen) == 0; if (isXXTEA) { // decrypt XXTEA xxtea_long len = 0; buffer = xxtea_decrypt(bytes + stack->_xxteaSignLen, (xxtea_long)size - (xxtea_long)stack->_xxteaSignLen, (unsigned char*)stack->_xxteaKey, (xxtea_long)stack->_xxteaKeyLen, &len); zip = ZipFile::createWithBuffer(buffer, len); } else { if (size > 0) { zip = ZipFile::createWithBuffer(bytes, (unsigned long)size); } } if (zip) { CCLOG("lua_loadChunksFromZIP() - load zip file: %s%s", zipFilePath.c_str(), isXXTEA ? "*" : ""); lua_getglobal(L, "package"); lua_getfield(L, -1, "preload"); int count = 0; std::string filename = zip->getFirstFilename(); while (filename.length()) { ssize_t bufferSize = 0; unsigned char *zbuffer = zip->getFileData(filename.c_str(), &bufferSize); if (bufferSize) { // remove .lua or .luac extension size_t pos = filename.find_last_of('.'); if (pos != std::string::npos) { std::string suffix = filename.substr(pos, filename.length()); if (suffix == NOT_BYTECODE_FILE_EXT || suffix == BYTECODE_FILE_EXT) { filename.erase(pos); } } // replace path separator '/' '\' to '.' for (int i=0; i<filename.size(); i++) { if (filename[i] == '/' || filename[i] == '\\') { filename[i] = '.'; } } CCLOG("[luaLoadChunksFromZIP] add %s to preload", filename.c_str()); if (stack->luaLoadBuffer(L, (char*)zbuffer, (int)bufferSize, filename.c_str()) == 0) { lua_setfield(L, -2, filename.c_str()); ++count; } free(zbuffer); } filename = zip->getNextFilename(); } CCLOG("lua_loadChunksFromZIP() - loaded chunks count: %d", count); lua_pop(L, 2); lua_pushboolean(L, 1); delete zip; } else { CCLOG("lua_loadChunksFromZIP() - not found or invalid zip file: %s", zipFilePath.c_str()); lua_pushboolean(L, 0); } if (buffer) { free(buffer); } } while (0); return 1; }
int LuaStack::lua_loadChunksFromZIP(lua_State *L) { if (lua_gettop(L) < 1) { CCLOG("lua_loadChunksFromZIP() - invalid arguments"); return 0; } const char *zipFilename = lua_tostring(L, -1); lua_settop(L, 0); FileUtils *utils = FileUtils::getInstance(); std::string zipFilePath = utils->fullPathForFilename(zipFilename); LuaStack *stack = curStack; do { ssize_t size = 0; void *buffer = NULL; unsigned char *zipFileData = utils->getFileData(zipFilePath.c_str(), "rb", &size); ZipFile *zip = NULL; bool isXXTEA = stack && stack->_xxteaEnabled && zipFileData; for (int i = 0; isXXTEA && i < stack->_xxteaSignLen && i < size; ++i) { isXXTEA = zipFileData[i] == stack->_xxteaSign[i]; } if (isXXTEA) { // decrypt XXTEA xxtea_long len = 0; buffer = xxtea_decrypt(zipFileData + stack->_xxteaSignLen, (xxtea_long)size - (xxtea_long)stack->_xxteaSignLen, (unsigned char*)stack->_xxteaKey, (xxtea_long)stack->_xxteaKeyLen, &len); delete []zipFileData; zipFileData = NULL; zip = ZipFile::createWithBuffer(buffer, len); } else { if (zipFileData) { zip = ZipFile::createWithBuffer(zipFileData, size); } } if (zip) { CCLOG("lua_loadChunksFromZIP() - load zip file: %s%s", zipFilePath.c_str(), isXXTEA ? "*" : ""); lua_getglobal(L, "package"); lua_getfield(L, -1, "preload"); int count = 0; std::string filename = zip->getFirstFilename(); while (filename.length()) { ssize_t bufferSize = 0; unsigned char *zbuffer = zip->getFileData(filename.c_str(), &bufferSize); if (bufferSize) { if (stack->luaLoadBuffer(L, (char*)zbuffer, (int)bufferSize, filename.c_str()) == 0) { lua_setfield(L, -2, filename.c_str()); ++count; } delete []zbuffer; } filename = zip->getNextFilename(); } CCLOG("lua_loadChunksFromZIP() - loaded chunks count: %d", count); lua_pop(L, 2); lua_pushboolean(L, 1); delete zip; } else { CCLOG("lua_loadChunksFromZIP() - not found or invalid zip file: %s", zipFilePath.c_str()); lua_pushboolean(L, 0); } if (zipFileData) { delete []zipFileData; } if (buffer) { free(buffer); } } while (0); return 1; }