Npk 文件格式

某游戏的压缩资源格式

涉及两个结构体:

struct st_NpkHeader
{
	int _magic;//    					[_offset + 0]
	int _count;//    					[_offset + 4]	size(count * 28)	
	int _unknonw2;
	int _unknonw3;
	int _bUseTrunkCompressType;
	int _offset;
};
Npk 文件格式_第1张图片


struct st_NpkTrunk
{
    int _trunkHash;
    int _dataOffset;
    int _compressSize;
    int _realSize;
    int _unknown1;
    int _unknonw2;
    int _compressType;
};

Npk 文件格式_第2张图片

 完整代码:

// UnNpk.cpp : 定义控制台应用程序的入口点。
//

#include "./liblz4/lz4.h"
#include "./zlib/zlib.h"
#include "stdafx.h"
#include 
#include 
#include 
struct st_NpkHeader
{
	int _magic;//    					[_offset + 0]
	int _count;//    					[_offset + 4]	size(count * 28)	
	int _unknonw2;
	int _unknonw3;
	int _bUseTrunkCompressType;
	int _offset;
};

struct st_NpkTrunk
{
	int _trunkHash;
	int _dataOffset;
	int _compressSize;
	int _realSize;
	int _unknown1;
	int _unknonw2;
	int _compressType;
};
std::string GetNpkFileName(char *pData, unsigned int maxLen)
{
	std::string name;
	for (int i = 0; i < maxLen; ++i)
	{
		if ((pData[i] >= 'a' && pData[i] <= 'z') 
			|| (pData[i] >= 'A' && pData[i] <= 'Z') )
		{
			name += pData[i];
		}
	}
	return name;
}

int _tmain(int argc, _TCHAR* argv[])
{
	if (argc < 2)
	{
		printf("%s npkFile\n", argv[0]);
		return 0;
	}
	FILE *fp = fopen(argv[1], "rb");
	if (!fp)
	{
		return 0;
	}
	unsigned int nFileLen = 0;
	fseek(fp,0,SEEK_END); //定位到文件末
	nFileLen = ftell(fp); //文件长度 

	fseek(fp,0,SEEK_SET);

	st_NpkHeader npkHeader;
	fread(&npkHeader, sizeof(npkHeader), 1, fp);
	if (npkHeader._magic != 0x4b50584e)
	{
		printf("not npk file\n");
		return 0;
	}
	fseek(fp,0,SEEK_SET);

	st_NpkTrunk* pNpkTrunkList = new st_NpkTrunk[npkHeader._count];
	std::string strDir = "./Dump";
	if (_access(strDir.c_str(), 0) != 0)
	{
		_mkdir(strDir.c_str());
	}
	fseek(fp, npkHeader._offset,SEEK_SET);
	int nRSize = fread(pNpkTrunkList, sizeof(st_NpkTrunk), npkHeader._count, fp);
	for (int i = 0; i < nRSize; ++i)
	{
		fseek(fp, pNpkTrunkList[i]._dataOffset, SEEK_SET);
		char *pSrc = new char[pNpkTrunkList[i]._compressSize];		
		fread(pSrc, pNpkTrunkList[i]._compressSize, 1, fp);
		char *pDst = new char[pNpkTrunkList[i]._realSize];
		if (pNpkTrunkList[i]._compressType == 2)
		{
			LZ4_decompress_safe(pSrc, pDst, pNpkTrunkList[i]._compressSize, pNpkTrunkList[i]._realSize);
		}
		else if (pNpkTrunkList[i]._compressType == 1)
		{
			int realSize = pNpkTrunkList[i]._realSize;
			int nRet = uncompress((Bytef *)pDst, (uLongf*)&realSize, (Bytef *)pSrc, pNpkTrunkList[i]._compressSize);
		}
		else
		{
			memcpy(pDst, pSrc, pNpkTrunkList[i]._realSize);
		}		
		char fileName[126];		
		std::string format = GetNpkFileName(pDst, 5);	
		sprintf_s<126>(fileName, "%s/%x.%s", strDir.c_str(), pNpkTrunkList[i]._trunkHash, format.c_str());
		FILE *fp2 = fopen(fileName, "wb");
		fwrite(pDst, pNpkTrunkList[i]._realSize, 1, fp2);
		fclose(fp2);

		delete[] pSrc;
		delete[] pDst;
	}
	return 0;
}



你可能感兴趣的:(c++)