unsigned char* getFileDataFromZip(const char* zipFile, const char* fileName, ssize_t* size) { if (nullptr == zipFile || nullptr == fileName || nullptr == size) return nullptr; Data zipData = FileUtils::getInstance()->getDataFromFile(zipFile); if (zipData.isNull()) return nullptr; ZipFile * zip = ZipFile::createWithBuffer(zipData.getBytes(), zipData.getSize()); if (nullptr == zip) return nullptr; *size = 0; unsigned char * data = zip->getFileData(fileName, size); delete zip; if (nullptr == data || size <= 0) { *size = 0; free(data); return nullptr; } return data; }
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 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; }