Beispiel #1
0
unsigned char *CCZipFile::unZipIfNeed(unsigned char * buffer,uLong insize,uLong& outsize)
{
    //50,4B,03,04
    if(insize>4 && buffer[0]==0x50 && buffer[1]==0x4B && buffer[2]==0x03 && buffer[3]==0x04)
    {
        CCZipFile *zip = createWithBuffer(buffer,insize);
        if(zip)
        {
             std::string name = zip->getFirstFilename();
             uLong newsize=0;
             unsigned char* newbuff = zip->getFileData(name.c_str(), &newsize);
             if(newbuff)
             {
                outsize = newsize;
                return newbuff;
             }
        }
    }
    return NULL;
}
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;
}