Npk 文件格式

某游戏的压缩资源格式

涉及两个结构体:

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;
};


 完整代码:

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

#include "./liblz4/lz4.h"
#include "./zlib/zlib.h"
#include "stdafx.h"
#include <string>
#include <io.h>
#include <direct.h>
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;
}



  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: Python可以使用numpy库来修改npk文件。 首先,需要导入numpy库,可以使用以下代码: import numpy as np 然后,使用np.load()函数加载npk文件,例如: data = np.load('file.npk') 接下来,可以对加载的数据进行修改,例如修改某个元素的值: data[0][0] = 10 或者修改某一行或一列的值: data[1,:] = 20 data[:,2] = 30 完成修改后,可以使用np.save()函数将修改后的数据保存到npk文件中,例如: np.save('file_modified.npk', data) 最后,记得关闭文件: data.close() 总结起来,通过导入numpy库,使用np.load()函数加载npk文件,对加载的数据进行修改,然后使用np.save()函数保存修改后的数据到npk文件中,最后关闭文件,就可以完成对npk文件的修改。 需要注意的是,npk文件包含多个数组,所以在使用索引访问元素时,需要指定具体数组的位置。另外,要确保修改后的数据的维度与原来的数据维度一致,否则可能会引起数据错误。 ### 回答2: Python 可以使用 numpy 库来修改 NPK(Numpy Pickle)文件。 首先,需要导入 numpy 模块和 pickle 模块: ```python import numpy as np import pickle ``` 然后,使用 pickle 模块来加载 NPK 文件的内容: ```python with open('file.npk', 'rb') as file: data = pickle.load(file) ``` 接下来,可以对加载的数据进行修改操作。例如,假设 NPK 文件中存储的是一个 numpy 的数组,可以直接对其中的元素进行修改: ```python data[0] = 10 ``` 修改后的数据可以直接用 pickle 模块再次保存到 NPK 文件中: ```python with open('file.npk', 'wb') as file: pickle.dump(data, file) ``` 完整的代码如下所示: ```python import numpy as np import pickle with open('file.npk', 'rb') as file: data = pickle.load(file) # 对数据进行修改操作,例如:data[0] = 10 with open('file.npk', 'wb') as file: pickle.dump(data, file) ``` 这样,就可以使用 Python 的 numpy 和 pickle 模块来修改 NPK 文件了。 ### 回答3: 要使用Python修改npk文件,首先需要了解npk文件的格式和内容。 npk文件是一个打包文件格式,通常用于游戏资源或软件安装包。它包含了多个文件和文件夹,以及与之相关的元数据。要修改npk文件,可以按照以下步骤进行: 1. 导入相应的Python库,如`zipfile`和`os`,以处理zip压缩和文件操作。 2. 使用`zipfile`库的`ZipFile`函数打开npk文件。例如,可以使用如下代码打开名为`example.npk`的npk文件: ```python import zipfile npk_file = zipfile.ZipFile('example.npk', 'a') ``` 3. 通过`ZipFile`对象,可以使用`extract()`方法提取npk文件中的特定文件,或使用`extractall()`方法将所有文件解压到指定目录。例如,可以使用如下代码将npk文件中的`data.txt`文件提取到当前目录: ```python npk_file.extract('data.txt', './') ``` 4. 若要修改npk文件中的文件内容,可以先将其提取出来,修改后再重新压缩到npk文件中。例如,可以使用以下代码修改`data.txt`文件并重新压缩到npk文件中: ```python # 提取文件 npk_file.extract('data.txt', './') # 修改文件内容 with open('data.txt', 'w') as file: file.write('This is the modified content.') # 将修改后的文件重新压缩到npk文件中 npk_file.write('data.txt') ``` 5. 修改完毕后,记得关闭npk文件: ```python npk_file.close() ``` 以上就是使用Python修改npk文件的基本步骤。根据npk文件的具体内容和格式,可能需要进一步处理其他元数据或修改其他文件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值