zoukankan      html  css  js  c++  java
  • jxqy1 unpack

    Mignet/Jx: jx (github.com)

    debug模式需要添加c++

    ....EngineInclude;%(AdditionalIncludeDirectories)

    // PackSingle.cpp : Defines the entry point for the console application.
    //
    
    #include <windows.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <io.h>
    #include <direct.h>
    #include <sstream>
    //首先是处理SPR文件的代码
    
    //SPR头文件的定义,为了实现可移植的目标
    
    
    #include "ZPackFile.h"
    typedef struct {
        BYTE    Comment[4];    // 注释文字(SPR)
        WORD    Width;        // 图片宽度
        WORD    Height;        // 图片高度
        WORD    CenterX;    // 重心的水平位移
        WORD    CenterY;    // 重心的垂直位移
        WORD    Frames;        // 总帧数
        WORD    Colors;        // 颜色数
        WORD    Directions;    // 方向数
        WORD    Interval;    // 每帧间隔(以游戏帧为单位)
        WORD    Reserved[6];// 保留字段(到以后使用)
    } SPRHEAD;
    
    typedef struct
    {
        DWORD    Offset;        // 每一帧的偏移
        DWORD    Length;        // 每一帧的长度
    } SPROFFS;
    
    
    //重新定义
    #define FRAME_SIZE            800 * 1024            //800K以上的SPR文件使用分帧的压缩
    int root_length = 0;
    
    #define MAX_FILE                    2004800            //最多20万个文件
    
    index_info index_list[MAX_FILE];
    char *temp_buffer[MAX_FILE * sizeof(index_info)];
    int file_count;                                        //当前文件的数量
    
    unsigned long offset;                                //当前偏移量
    #define COMPRESS_BUF_SIZE    10240000
    char compress_buffer[COMPRESS_BUF_SIZE];            //10M的压缩缓冲区,存放所有的帧,一次写
    
    #include <ucl/ucl.h>
    bool bCheck = false;
    #include <conio.h>
    
    //增加一个文件到数据文件中,返回偏移量
    bool addFile(FILE *output, const char *file_name) {
        char full_name[MAX_PATH];
        getcwd(full_name, MAX_PATH);
        strcat(full_name, "\");
        strcat(full_name, file_name);
        char *ptr = full_name;
        while(*ptr) {
            if(*ptr >= 'A' && *ptr <= 'Z') *ptr += 'a' - 'A';
            ptr++;
        }
    
        unsigned long id = hash(full_name + root_length);//0x12345678
        char *to = (char*)malloc(strlen(full_name) - root_length - 13);
        strncpy(to, full_name + root_length+10, strlen(full_name)- root_length -14);
        to[strlen(full_name) - root_length - 14] = '';
    
        id = std::stoul(to, nullptr, 0);
        int index;
        for(index = 0; index < file_count; index++) {
            if(id < index_list[index].id) {
                memmove(temp_buffer, (char *)&index_list[index], (file_count - index) * sizeof(index_info));
                memmove((char *)&index_list[index + 1], temp_buffer, (file_count - index) * sizeof(index_info));
                break;
            }
            else if(id == index_list[index].id) {
                printf("error %s has the same id %d
    ", full_name + root_length, id);
    
                if(!bCheck) exit(0);
                else getch();
            }
        }
        file_count++;
        if(bCheck) {
            printf("check %s ok
    ", full_name + root_length);
            return true;
        }
    
        ZMapFile map(file_name);
        int compress_size = 0;
    
        unsigned long compress_type = TYPE_UCL;                //使用UCL压缩
    
        bool bSPR = false;                                    //是否为SPR文件
        const char *ext = file_name + strlen(file_name) - 3;
        if(*ext == 's' && *(ext + 1) == 'p' && *(ext + 2) == 'r') bSPR = true;
    
        int r;
        unsigned int size = 0;
        map.map();
        if(map.m_Ptr) {
    
            index_list[index].id = id;
            index_list[index].offset = offset;
            index_list[index].size = map.m_Size;
    
            ptr = compress_buffer;
            if(!bSPR || map.m_Size < FRAME_SIZE) {
                if(compress_type == TYPE_UCL) {
                    r = ucl_nrv2b_99_compress((BYTE *)map.m_Ptr, map.m_Size, (BYTE *)ptr, (unsigned int *)&index_list[index].compress_size, NULL, 5, NULL, NULL);
                }
                else if(compress_type == TYPE_BZIP2) {
    //                index_list[index].compress_size = COMPRESS_BUF_SIZE;
    //                r = BZ2_bzBuffToBuffCompress(ptr, (unsigned int *)&index_list[index].compress_size, map.m_Ptr, map.m_Size, 9, 0, 30);
                }
                if(r) return false;
                fwrite(compress_buffer, 1, index_list[index].compress_size, output);
                offset += index_list[index].compress_size;
                printf("%s [%d]->[%d]
    ", full_name + root_length, map.m_Size, index_list[index].compress_size);
                index_list[index].compress_size |= (compress_type << 24);
            }
            else {                                //每帧独立压缩
                SPRHEAD *head;
                head = (SPRHEAD *)map.m_Ptr;
                memmove(ptr, head, sizeof(SPRHEAD) + head->Colors * 3);            //前面的数据不压缩
                ptr += sizeof(SPRHEAD) + head->Colors * 3;
                frame_info *compress_frame_info = (frame_info *)ptr;                    //压缩后每一帧的数据
                ptr += head->Frames * sizeof(SPROFFS);
        
                SPROFFS *frame_info = (SPROFFS *)(map.m_Ptr + sizeof(SPRHEAD) + head->Colors * 3);        //原来每一帧的数据
                char *frame_data = (char *)frame_info + head->Frames * sizeof(SPROFFS);
                int frame_index;
    
                int frame_offset = 0;
                for(frame_index = 0; frame_index < head->Frames; frame_index++) {
    //压缩每一帧的内容
                    if(frame_info[frame_index].Length >= 256) {                //小于256字节的不压缩
                        if(compress_type == TYPE_UCL) {
                            r = ucl_nrv2b_99_compress((BYTE *)frame_data + frame_info[frame_index].Offset, frame_info[frame_index].Length, (BYTE *)ptr, &size, NULL, 10, NULL, NULL);
                        }
                        else if(compress_type == TYPE_BZIP2) {
    //                        size = COMPRESS_BUF_SIZE;
    //                        r = BZ2_bzBuffToBuffCompress(ptr, &size, frame_data + frame_info[frame_index].Offset, frame_info[frame_index].Length, 9, 0, 30);
                        }
                        if(r) return false;
                        compress_frame_info[frame_index].size = frame_info[frame_index].Length;        //记录原来的大小
                    }
                    else {
                        size = frame_info[frame_index].Length;
                        memmove(ptr, (BYTE *)frame_data + frame_info[frame_index].Offset, size);
                        compress_frame_info[frame_index].size = -(long)frame_info[frame_index].Length;        //记录原来的大小
                    }
                    compress_size += size;
                    compress_frame_info[frame_index].compress_size = size;
                    frame_offset += size;
                    ptr += size;        
                }
                fwrite(compress_buffer, 1, ptr - compress_buffer, output);
                offset += ptr - compress_buffer;
                printf("[frame] %s old size = %d, compressed size = %d
    ", full_name + root_length, map.m_Size, compress_size);
                index_list[index].compress_size = (ptr - compress_buffer) | ((compress_type | TYPE_FRAME) << 24);
            }
        }
        return true;
    }
    
    void addDirectory(FILE *output, const char *rootDir, const char *subDir = NULL) {
        char            szRealDir[MAX_PATH];
        if(subDir) sprintf(szRealDir, "%s\%s", rootDir, subDir);
        else {
            strcpy(szRealDir, rootDir);
            root_length = strlen(rootDir);
            while(rootDir[root_length] != '\') root_length--;
        }
        if(chdir(szRealDir)) return;
        _finddata_t FindData;
        long dir = _findfirst("*.*", &FindData);
        while(dir != -1) {
            if(strcmp(FindData.name, ".") == 0 || strcmp(FindData.name, "..") == 0)    {
                if(_findnext(dir, &FindData)) break;
                continue;
            }
            if(FindData.attrib & _A_SUBDIR)
            {
                addDirectory(output, szRealDir, FindData.name);
            }
            else
            {    
                if(!addFile(output, FindData.name)) return;
            }
            if(_findnext(dir, &FindData)) break;
        } 
        _findclose(dir);
        chdir(rootDir);
    }
    
    bool pack(const char *dir, const char *pack_name = 0) {
        char name_buffer[MAX_PATH];
        file_count = 0;
        offset = 0;
        if(!pack_name) {
            strcpy(name_buffer, dir);
            strcat(name_buffer, ".pak");
            pack_name = name_buffer;
        }
        FILE * output = NULL;
        z_pack_header header;
        if(!bCheck) {
            output = fopen(pack_name, "wb");
            memset(&header, 0, sizeof(header));
            fwrite(&header, 1, sizeof(header), output);
            offset += sizeof(header);
        }
    
        char aAddDir[MAX_PATH];
        strcpy(aAddDir, dir);
        strcat(aAddDir, "\Font");
        addDirectory(output, aAddDir);                    //压缩指定目录
        strcpy(aAddDir, dir);
        strcat(aAddDir, "\Maps");
        addDirectory(output, aAddDir);                    //压缩指定目录
        strcpy(aAddDir, dir);
        strcat(aAddDir, "\settings");
        addDirectory(output, aAddDir);                    //压缩指定目录
        strcpy(aAddDir, dir);
        strcat(aAddDir, "\script");
        addDirectory(output, aAddDir);                    //压缩指定目录
        strcpy(aAddDir, dir);
        strcat(aAddDir, "\Spr");
        addDirectory(output, aAddDir);                    //压缩指定目录
        strcpy(aAddDir, dir);
        strcat(aAddDir, "\Sound");
        addDirectory(output, aAddDir);                    //压缩指定目录
        strcpy(aAddDir, dir);
        strcat(aAddDir, "\Ui");
        addDirectory(output, aAddDir);                    //压缩指定目录
        strcpy(aAddDir, dir);
        strcat(aAddDir, "\游戏资源");
        addDirectory(output, aAddDir);                    //压缩指定目录
    
        if(!bCheck) {
            memset(&header, 0, sizeof(header));
            memcpy(header.signature, "PACK", 4);
            header.index_offset = offset;
            header.data_offset = sizeof(header);
            header.count = file_count;
            int result = fwrite(&index_list[0], 1, file_count * sizeof(index_info), output);
            fseek(output, 0, SEEK_SET);
            fwrite(&header, 1, sizeof(header), output);
            fclose(output);
        }
        return true;
    }
    
    int main(int argc, char **argv) {
    
        if(argc < 2) {
            printf("usage: packSingle [pack directory] [pack file name] [/c]
    without [pack file name], the pack file name will be the same of directory name
    /c to check the same id
    ");
            return 0;
        }
    
        if (ucl_init() != UCL_E_OK) return 0;
    
        if(argc > 2) {
            if(!stricmp(argv[2], "/c")) {
                bCheck = true;
                pack(argv[1]);
            }
            else {
                if(argc > 3) {
                    if(!stricmp(argv[3], "/c")) bCheck = true;
                }
                pack(argv[1], argv[2]);
            }
        }
        else pack(argv[1]);
    
        return 0;
    }
    //首先是处理SPR文件的代码
    
    //SPR头文件的定义,为了实现可移植的目标
    #include <windows.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <io.h>
    #include <direct.h>
    #include <IOSTREAM>
    #include <conio.h>
    #include "ZPackFile.h"
    #include "SavePack.h"
    #include <sstream>
    
    using namespace std;
    #define MAX_FILE                    2004800            //最多20万个文件
    
    index_info index_list[MAX_FILE];
    char temp_buffer[MAX_FILE * sizeof(index_info)];
    
    void IndexNT2Normal(index_info_nt* IndexNT, index_info* aIndex)
    {
        aIndex->id = IndexNT->id;
        aIndex->offset = IndexNT->offset;
        aIndex->size = IndexNT->size;
        aIndex->compress_size = IndexNT->compress_size;
        return;
    }
    bool PackExp(char* baseFile, char* addFile, char* nowFile, char* saveFile)
    {
        //打开四个文件
        ZCache baseCache(65536 * 1024);
        ZPackFileNT basePack(baseFile, &baseCache);
        cout<<"Open Base Pack "<<baseFile<<" Successfully.";
        cout<<"Base Pack File Count:"<<basePack.getFileCount()<<endl;
    
        ZCache addCache(65536 * 1024);
        ZPackFileNT addPack(addFile, &addCache);
        if(addFile)
        {
            cout<<"Open Add Pack "<<addFile<<" Successfully.";
            cout<<"Add Pack File Count:"<<addPack.getFileCount()<<endl;
        }
        else
        {
            cout<<"No Add Pack File"<<endl;
        }
        
        ZCache nowCache(65536 * 1024);
        ZPackFileNT nowPack(nowFile, &nowCache);
        cout<<"Open Latest Pack "<<nowFile<<" Successfully.";
        cout<<"Latest Pack File Count:"<<nowPack.getFileCount()<<endl;
    
        CSavePack SavePack;
        if(SavePack.open(saveFile, index_list))
            cout<<"Open Save Pack "<<saveFile<<" Successfully."<<endl;
        else
        {
            cout<<"Error Save Pack "<<saveFile<<" ."<<endl;
            getch();
            exit(1);
        }
        //cout<<"Press any key to continue..."<<endl;
        //getch();
        
        int i;
        for(i=0;i<nowPack.getFileCount();++i)
        {
            index_info_nt* IndexInfoNow = nowPack.IndexData(i);
            
            if(addFile)    //如果addFile里面有这个文件
            {                                    //就跟addFile的这个文件比较时间
                int addPackIndex = addPack.getNodeIndex(IndexInfoNow->id);
                if(addPackIndex != -1)
                {
                    index_info_nt* IndexInfoAdd=addPack.IndexData(i);
                    if(CompareFileTime(&IndexInfoNow->UpdateTime,&IndexInfoAdd->UpdateTime) != 1)
                    {//如果时间与原来的文件一样的话就跳过
                        cout<<"ID:"<<IndexInfoNow->id<<" Skip."<<endl;
                        continue;
                    }
                }
            }
            index_info aIndex;
            IndexNT2Normal(IndexInfoNow,&aIndex);
            char* aData = nowPack.getOrigData(IndexInfoNow->id);
            SavePack.AddData(aData, &aIndex, temp_buffer);
            int fileSize = IndexInfoNow->compress_size & 0x00FFFFFF;
            cout<<"Add Data From File:["<<nowFile<<"] ID:"<<IndexInfoNow->id
                    <<" Size:"<<fileSize<<endl;
        }
        if(SavePack.Close())
            cout<<"File "<<saveFile<< " Saved."<<endl;
        else
            cout<<"Error Save File "<<saveFile<< " ."<<endl;
    
        return true;
    }
    
    int main(int argc, char **argv)
    {
    
        if(argc < 5) {
            if (argc >= 1) {
                char* basePackFile = argv[1];
                cout << "Press any key to begin test..." << endl;
                getch();
                ZCache aaCache(65536 * 1024);
                ZPackFile aaPack(basePackFile, &aaCache);
                int i;
                const z_pack_header* header = aaPack.GetHeader();
                cout << "Pack File Count:" << aaPack.getFileCount() << endl;
    
                getch();
    
                for (i = 0; i < header->count; ++i)
                {
                    index_info* IndexInfo = aaPack.IndexData(i);
                    int fileSize = IndexInfo->compress_size & 0x00FFFFFF;
                    cout << "[" << i << "]||id:"
                        << IndexInfo->id << "||offset:"
                        << IndexInfo->offset << "||compress_size:"
                        << IndexInfo->compress_size << "||size:"
                        << IndexInfo->size << "||fileSize:"
                        << fileSize << "||";
    
                    char* aa = aaPack.getData(IndexInfo->id);//getOrigData
                    char* bb = aaPack.getOrigData(IndexInfo->id);//getOrigData
                    if (aa == bb) {
                        cout << "getData == getOrigData" << endl;
                    }
                    if (aa) {
                        FILE *infile;
                        //cout << bb << endl;
                        if (*bb=='S' && (*bb+1) == 'P'&& (*bb+2) == 'R') {
                            cout << "SPR Ready?" << endl;
                        }
                        else {
                            cout << "Other Ready?" << endl;
                        }
    
                        getch();
                        //SPR
                        if (*bb == 'S' && (*bb + 1) == 'P' && (*bb + 2) == 'R') {
                            infile = fopen((std::to_string(IndexInfo->id) + ".spr").c_str(), "wb");//用fopen函数打开文件
                            if (!infile) {
                                printf("open infile failed....
    ");
                                continue;
                            }
                            fwrite(aa, sizeof(char), strlen(aa), infile);//写入内容
                            if (fclose(infile)) {
                                printf("write infile failed....
    ");
                            };
                        }
                        else {
                            infile = fopen((std::to_string(IndexInfo->id)+".lua").c_str(), "w");//用fopen函数打开文件
                            if (!infile) {
                                printf("open infile failed....
    ");
                                continue;
                            }
    
                            fprintf(infile, "%s", aa);
                            //fwrite(&aa, 1, count, infile);//写入内容
                            //fputs(aa, infile);
                            if (fclose(infile)) {
                                printf("write infile failed....
    ");
                            };
                        }
                        
                        //cout << aa << endl;
                        cout << "OK" << endl;
                        //getch();
                    }
                    else
                    {
                        cout << "Error" << endl;
                        getch();
                    }
                }
                getch();
                return 0;
    
            }
            printf("usage: PackExp [base pack file] [previous version pack file] [present version pack file] [output pack file].
    ");
            return 0;
        }
    
        if (ucl_init() != UCL_E_OK) return 0;
    
        //argv[1] ----- f:\temp\PackBase.pac
        //argv[2] ----- f:\temp\PackUpdate1.pac
        //argv[3] ----- f:\temp\PackUpdate2.pac
        //argv[4] ----- f:\temp\Update1-2.pak
    
        //生成从版本a到版本b的升级包
        char* basePackFile = argv[1];        //版本0的文件(原始版本)
        char* addPackFile = argv[2];        //版本a的文件
        char* nowPackFile = argv[3];        //版本b的文件
        char* outputPackFile = argv[4];        //导出的文件
        if (strcmp(addPackFile,"none") == 0) addPackFile =NULL;
        PackExp(basePackFile,addPackFile,nowPackFile,outputPackFile);
    
        if(argc == 5)return 0;
        
        cout<<"Press any key to begin test..."<<endl;
        getch();
        ZCache aaCache(65536 * 1024);
        ZPackFile aaPack(outputPackFile, &aaCache);
        int i;
        const z_pack_header* header = aaPack.GetHeader();
        cout<<"Pack File Count:"<<aaPack.getFileCount()<<endl; 
    
        getch();
        
        for(i=0;i<header->count;++i)
        {
            index_info* IndexInfo=aaPack.IndexData(i);
            int fileSize = IndexInfo->compress_size & 0x00FFFFFF;
            cout<<"["<<i<<"]||"
                <<IndexInfo->id<<"||"
                <<IndexInfo->offset<<"||"
                <<IndexInfo->size<<"||"
                <<fileSize<<"||";
            char* aa = aaPack.getOrigData(IndexInfo->id);
            if(aa)
                cout<<"OK"<<endl;
            else
            {
                cout<<"Error"<<endl;
                getch();
            }
        }
        getch();
        return 0;
    }
  • 相关阅读:
    Ubuntu下libpcap安装
    chrome浏览器如何保存pdf
    C++文件操作
    Word2010制作饭店活动宣传单
    PPT2010制作翻牌动画
    PPT2010制作清明上河图动画
    PPT2010制作充电动画
    Java中Jar包调用命令行运行编译
    Java带包结构调用命令行运行编译
    Word2010制作简单个人简历
  • 原文地址:https://www.cnblogs.com/mignet/p/14190181.html
Copyright © 2011-2022 走看看