int CCLuaStack::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); CCFileUtils *utils = CCFileUtils::sharedFileUtils(); string zipFilePath = utils->fullPathForFilename(zipFilename); zipFilename = NULL; CCLuaStack *stack = CCLuaStack::stack(L); do { unsigned long size = 0; void *buffer = NULL; unsigned char *zipFileData = utils->getFileData(zipFilePath.c_str(), "rb", &size); CCZipFile *zip = NULL; bool isXXTEA = stack && stack->m_xxteaEnabled && zipFileData; for (unsigned int i = 0; isXXTEA && i < stack->m_xxteaSignLen && i < size; ++i) { isXXTEA = zipFileData[i] == stack->m_xxteaSign[i]; } if (isXXTEA) { // decrypt XXTEA xxtea_long len = 0; buffer = xxtea_decrypt(zipFileData + stack->m_xxteaSignLen, (xxtea_long)size - (xxtea_long)stack->m_xxteaSignLen, (unsigned char*)stack->m_xxteaKey, (xxtea_long)stack->m_xxteaKeyLen, &len); delete []zipFileData; zipFileData = NULL; zip = CCZipFile::createWithBuffer(buffer, len); } else { if (zipFileData) { zip = CCZipFile::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; string filename = zip->getFirstFilename(); while (filename.length()) { unsigned long bufferSize = 0; unsigned char *buffer = zip->getFileData(filename.c_str(), &bufferSize); if (bufferSize) { if (lua_loadbuffer(L, (char*)buffer, (int)bufferSize, filename.c_str()) == 0) { lua_setfield(L, -2, filename.c_str()); ++count; } delete []buffer; } filename = zip->getNextFilename(); } CCLOG("lua_loadChunksFromZIP() - loaded chunks count: %d", count); lua_pop(L, 2); lua_pushboolean(L, 1); } 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; }
int CCLuaStack::loadChunksFromZip(lua_State *L) { const char *zipFilename = lua_tostring(L, -1); CCFileUtils *utils = CCFileUtils::sharedFileUtils(); string zipFilePath = utils->fullPathForFilename(zipFilename); lua_pop(L, 1); zipFilename = NULL; do { #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) string tmpFilePath = utils->getWriteablePath().append("cc_load_chunks.tmp"); unsigned long size = 0; unsigned char *buffer = utils->getFileData(zipFilePath.c_str(), "rb", &size); bool success = false; do { if (size == 0 || !buffer) { CCLOG("CCLoadChunksFromZip() - read source file %s failure", zipFilePath.c_str()); break; } FILE *tmp = fopen(tmpFilePath.c_str(), "wb"); if (!tmp) { CCLOG("CCLoadChunksFromZip() - create tmp file %s failure", tmpFilePath.c_str()); break; } success = fwrite(buffer, 1, size, tmp) > 0; fclose(tmp); if (success) { zipFilePath = tmpFilePath; CCLOG("CCLoadChunksFromZip() - copy zip file to %s ok", tmpFilePath.c_str()); } } while (0); if (buffer) { delete []buffer; } if (!success) { lua_pushboolean(L, 0); break; } #endif CCZipFile *zip = CCZipFile::create(zipFilePath.c_str()); if (zip) { CCLOG("CCLoadChunksFromZip() - load zip file: %s", zipFilePath.c_str()); lua_getglobal(L, "package"); lua_getfield(L, -1, "preload"); CCLOG("CCLoadChunksFromZip() - began"); int count = 0; string filename = zip->getFirstFilename(); while (filename.length()) { unsigned long bufferSize = 0; unsigned char *buffer = zip->getFileData(filename.c_str(), &bufferSize); if (bufferSize) { luaL_loadbuffer(L, (char*)buffer, bufferSize, filename.c_str()); lua_pushcclosure(L, &cc_lua_require, 1); lua_setfield(L, -2, filename.c_str()); delete []buffer; ++count; // CCLOG("CCLoadChunksFromZip() - chunk %s", filename.c_str()); } filename = zip->getNextFilename(); } CCLOG("CCLoadChunksFromZip() - ended, chunks count %d", count); lua_pop(L, 2); lua_pushboolean(L, 1); } else { CCLOG("CCLoadChunksFromZip() - not found zip file: %s", zipFilePath.c_str()); lua_pushboolean(L, 0); } #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) unlink(tmpFilePath.c_str()); #endif } while (0); return 1; }