jxqy1 unpack
debug模式需要添加c++
..\..\Engine\Include;%(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\0) 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] = '\0'; 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\n", full_name + root_length, id); if(!bCheck) exit(0); else getch(); } } file_count++; if(bCheck) { printf("check %s ok\n", 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]\n", 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\n", 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]\nwithout [pack file name], the pack file name will be the same of directory name\n/c to check the same id\n"); 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....\n"); continue; } fwrite(aa, sizeof(char), strlen(aa), infile);//写入内容 if (fclose(infile)) { printf("write infile failed....\n"); }; } else { infile = fopen((std::to_string(IndexInfo->id)+".lua").c_str(), "w");//用fopen函数打开文件 if (!infile) { printf("open infile failed....\n"); continue; } fprintf(infile, "%s", aa); //fwrite(&aa, 1, count, infile);//写入内容 //fputs(aa, infile); if (fclose(infile)) { printf("write infile failed....\n"); }; } //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].\n"); 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; }