Esempio n. 1
0
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::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;
}
Esempio n. 3
0
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;
}