游戏中的Pak文件解析.docx
- 文档编号:26100180
- 上传时间:2023-06-17
- 格式:DOCX
- 页数:22
- 大小:23.03KB
游戏中的Pak文件解析.docx
《游戏中的Pak文件解析.docx》由会员分享,可在线阅读,更多相关《游戏中的Pak文件解析.docx(22页珍藏版)》请在冰豆网上搜索。
游戏中的Pak文件解析
Pak文件的结构
pak文件就是将多个文件打包为一个单独文件,在这个文件中保存着多个文件的数据,当然还有一些描述文件结构的数据。
所以将“Pak”作为文件的后缀是一种常规的用法,可以自定义其它的文件后缀。
使用Pak方法将程序中要用到的资源(图片、音乐、文本)组合为单一文件是一个安全有效的方法。
由于MIDP对j2me程序大小有限制,所以缩小发布程序就意味着能够提供更多的程序或者内容(如图片、音乐)给用户。
因为zip/jar算法对大文件的压缩率高于对等量的多个小文件的压缩率,所以先把多个小文件按一定结构组合成一个pak文件,再压缩成jar包,有助于减少程序容量。
同时可以在pak文件中对文件数据进行加密,可以保护作者权益。
可以自行设计Pak文件结构,下面是一个参考例子:
同样的可以把Javame平台上的pak文件使用方法修改扩展应用到其他平台上,如Android/OPhone,wm等
PAKFileHeader:
Pak文件的头部
*签名:
6字节char数组*版本号:
32位float*文件table数量:
32位整数*密码行为:
8位字节*密码:
8位字节*文件唯一ID:
10字节char数组*保留位:
32位整数(4字节)
FileTable:
Pak文件中包含文件的列表,在一个Pak文件中一个被包含的文件对应一个FileTable。
*文件名:
30字节char数组*文件大小:
32位整型*文件在pak文件中的位移:
32位整数
ConcatenatedFileData:
按FileTable的顺序连接在一起的文件数据。
*文件数据
四、程序框架:
1。
PakHeader类,定义了Pak文件头。
2。
PakFileTable类,定义Pak文件table。
3。
PakUtil类(J2SE版),具备两个功能:
将多个png图片合成一个Pak文件,并使用简单的加减加密法对其进行加密;从Pak文件中取出png图片,构造byte数组(可以用来构造Image对象)或者写为文件。
PakUtil类(j2me版),具备的功能:
从Pak文件中取出png图片,构造byte数组(可以用来构造Image对象)。
可自行设计实现程序,特别是关键的加密算法
以下为参考代码:
五、PakHeader和PakFileTable类:
PakHeader.java:
packagecn.org.matrix.gmatrix.gameLab.util.pak;/***Pak文件头:
*结构:
*
签名:
6字节char数组* 版本号:
32位float*
文件table数量:
32位整数*
密码行为:
8位字节* 密码:
8位字节*
文件唯一ID:
10字节char数组*
保留位:
32位整数(4字节)*@authorcleverpig**/classPakHeader{
//定义文件唯一ID长度
publicstaticfinalintUNIQUEID_LENGTH=10;
//定义文件签名长度
publicstaticfinalintSIGNATURE_LENGTH=6;
//定义加法运算
publicstaticfinalintADDITION_CIPHERACTION=0;
//定义减法运算
publicstaticfinalintSUBTRACT_CIHOERACTION=1;
//文件签名
privatechar[]signature=newchar[SIGNATURE_LENGTH];
//版本号
privatefloatversion=0f;
//文件table数量
privatelongnumFileTableEntries=0;
//密码使用方法:
在原数据上进行加法还是减法
privatebytecipherAction=ADDITION_CIPHERACTION;
//密码值
privatebytecipherValue=0x00;
//唯一ID
privatechar[]uniqueID=newchar[UNIQUEID_LENGTH];
//保留的4字节
privatelongreserved=0;
publicPakHeader()
/**
*构造方法
*@paramsignature签名
*@paramversion版本
*@paramnumFileTableEntries文件table数量
*@paramcipherAction密码使用方法
*@paramcipherValue密码值
*@paramuniqueID唯一ID
*@paramreserved保留的2字节
*/
publicPakHeader(char[]signature,floatversion,
longnumFileTableEntries,bytecipherAction,
bytecipherValue,char[]uniqueID,longreserved){
for(inti=0;i ; this.version=version; this.cipherAction=cipherAction; this.numFileTableEntries=numFileTableEntries; this.cipherValue=cipherValue; for(inti=0;i this.reserved=reserved; } publicbytegetCipherValue(){ returncipherValue; } publicvoidsetCipherValue(bytecipherValue){ this.cipherValue=cipherValue; } publiclonggetNumFileTableEntries(){ returnnumFileTableEntries; } publicvoidsetNumFileTableEntries(longnumFileTableEntries){ this.numFileTableEntries=numFileTableEntries; } publiclonggetReserved(){ returnreserved; } publicvoidsetReserved(longreserved){ this.reserved=reserved; } publicchar[]getUniqueID(){ returnuniqueID; } publicvoidsetUniqueID(char[]uniqueID){ for(inti=0;i ; } publicfloatgetVersion(){ returnversion; } publicvoidsetVersion(floatversion){ this.version=version; } publicbytegetCipherAction(){ returncipherAction; } publicvoidsetCipherAction(bytecipherAction){ this.cipherAction=cipherAction; } publicchar[]getSignature(){ returnsignature; } publicvoidsetSignature(char[]signature){ for(inti=0;i ; } /** *返回PakHeader的大小 *@return返回PakHeader的大小 */ publicstaticintsize(){ returnSIGNATURE_LENGTH+4+4+1+1+UNIQUEID_LENGTH+4; } publicStringtoString(){ Stringresult=""; result+="t签名: "+newString(this.signature).trim() +"t版本号: "+this.version +"t文件table数量: "+this.numFileTableEntries +"t密码行为: "+this.cipherAction +"t密码: "+this.cipherValue +"t文件唯一ID: "+newString(this.uniqueID).trim() +"t保留位: "+this.reserved; returnresult; }} PakFileTable.java packagecn.org.matrix.gmatrix.gameLab.util.pak;/***Pak文件table类*文件table结构: * 文件名: 30字节char数组* 文件大小: 32位整型* 文件在pak文件中的位移: 32位整数*@authorcleverpig**/classPakFileTable{ publicstaticfinalintFILENAME_LENGTH=30; //文件名 privatechar[]fileName=newchar[FILENAME_LENGTH]; //文件大小 privatelongfileSize=0L; //文件在pak文件中的位移 privatelongoffSet=0L; publicPakFileTable() /** *构造方法 *@paramfileName文件名 *@paramfileSize文件大小 *@paramoffSet文件在Pak文件中的位移 */ publicPakFileTable(char[]fileName, longfileSize,longoffSet){ for(inti=0;i ; this.fileSize=fileSize; this.offSet=offSet; } publicchar[]getFileName(){ returnfileName; } publicvoidsetFileName(char[]fileName){ for(inti=0;i ; } publiclonggetFileSize(){ returnfileSize; } publicvoidsetFileSize(longfileSize){ this.fileSize=fileSize; } publiclonggetOffSet(){ returnoffSet; } publicvoidsetOffSet(longoffSet){ this.offSet=offSet; } /** *返回文件Table的大小 *@return返回文件Table的大小 */ publicstaticintsize(){ returnFILENAME_LENGTH+4+4; } publicStringtoString(){ return"t文件名: "+newString(this.fileName).trim() +"t文件大小: "+this.fileSize +"t文件位移: "+this.offSet; }} 六、PakUtil类(j2se版): PakUtil.java packagecn.org.matrix.gmatrix.gameLab.util.pak;importjava.io.*; importjava.util.Vector; /***Pak工具类*功能: *1.将多个png图片合成一个Pak文件,并使用简单的加减加密法对其进行加密; *2.从Pak文件中取出png图片,构造byte数组(可以用来构造Image对象)或者写为文件*@authorcleverpig**/publicclassPakUtil{ publicPakUtil() /** *返回文件长度 *@paramfilePath文件路径 *@return文件长度 */ privatelonggetFileSize(StringfilePath){ Filefile=newFile(filePath); returnfile.length(); } /** *返回文件名 *@paramfilePath文件路径 *@return文件名 */ privateStringgetFileName(StringfilePath){ Filefile=newFile(filePath); returnfile.getName(); } /** *计算文件位移的起始点 *@return文件位移的起始点 */ privatelongworkOutOffsetStart(PakHeaderheader){ //计算出文件头+文件table的长度 returnPakHeader.size()+header.getNumFileTableEntries()*PakFileTable.size(); } /** *计算文件位移 *@paramfileIndex文件序号 *@paramlastFileOffset上一个文件位移 *@return 文件在pak文件中的位移 */ privatelongworkOutNextOffset(longsourceFileSize,longlastFileOffset){ returnlastFileOffset+sourceFileSize; } /** *生成文件table *@paramsourceFileName源文件名 *@paramsourceFileSize源文件长度 *@paramcurrentFileOffset当前文件位移 *@return生成的PakFileTable对象 */ privatePakFileTablegenerateFileTable(StringsourceFileName, longsourceFileSize,longcurrentFileOffset){ PakFileTableft=newPakFileTable(); ft.setFileName(sourceFileName.toCharArray()); ft.setFileSize(sourceFileSize); ft.setOffSet(currentFileOffset); returnft; } /** *将char字符数组写入到DataOutputStream中 *@paramtoWriteCharArray被写入的char数组 *@paramdosDataOutputStream *@throwsException */ privatevoidwriteCharArray(char[]toWriteCharArray,DataOutputStreamdos)throwsException{ for(inti=0;i } /** *使用文件头中的密码对数据进行加密 *@parambuff被加密的数据 *@parambuffLength数据的长度 *@paramheader文件头 */ privatevoidencryptBuff(byte[]buff,intbuffLength,PakHeaderheader){ for(inti=0;i switch(header.getCipherAction()){ casePakHeader.ADDITION_CIPHERACTION: buff+=header.getCipherValue(); break; casePakHeader.SUBTRACT_CIHOERACTION: buff-=header.getCipherValue(); break; } } } /** *使用文件头中的密码对数据进行解密 *@parambuff被解密的数据 *@parambuffLength数据的长度 *@paramheader文件头 */ privatevoiddecryptBuff(byte[]buff,intbuffLength,PakHeaderheader){ for(inti=0;i switch(header.getCipherAction()){ casePakHeader.ADDITION_CIPHERACTION: buff-=header.getCipherValue(); break; casePakHeader.SUBTRACT_CIHOERACTION: buff+=header.getCipherValue(); break; } } } /** *制作Pak文件 *@paramsourceFilePath源文件路径数组 *@paramdestinateFilePath目的文件路径(Pak文件) *@paramcipherAction密码行为 *@paramcipherValue密码 *@throwsException */ publicvoidmakePakFile(String[]sourceFilePath, StringdestinateFilePath,PakHeaderheader)throwsException{ PakFileTable[]fileTable=newPakFileTable[sourceFilePath.length]; //计算文件位移起始点 longfileOffset=workOutOffsetStart(header); //逐个建立文件table for(inti=0;i StringsourceFileName=getFileName(sourceFilePath); longsourceFileSize=getFileSize(sourceFilePath); PakFileTableft=generateFileTable(sourceFileName,sourceFileSize,fileOffset); //计算下一个文件位移 fileOffset=workOutNextOffset(sourceFileSize,fileOffset); fileTable=ft; } //写入文件头 FilewFile=newFile(destinateFilePath); FileOutputStreamfos=newFileOutputStream(wFile); DataOutputStreamdos=newDataOutputStream(fos); writeCharArray(header.getSignature(),dos); dos.writeFloat(header.getVersion()); dos.writeLong(header.getNumFileTableEntries()); dos.writeByte(header.getCipherAction()); dos.writeByte(header.getCipherValue()); writeCharArray(header.getUniqueID(),dos); dos.writeLong(header.getReserved()); //写入文件table for(inti=0;i //写入文件数据 for(inti=0;i FileftFile=newFile(sourceFilePath);
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 游戏 中的 Pak 文件 解析
![提示](https://static.bdocx.com/images/bang_tan.gif)