pkg文件--一种简单的游戏资源打包格式
.pkg文件的格式
[四字节] 固定的内容, 值不重要
[四字节] 文件数目(unsigned int)
[四字节] 文件名表 的偏移(unsigned int)
[四字节] 文件名表 的长度(字节数)(unsigned int)
……
中间一堆 各个文件的内容, 文件内容使用zlib压缩过
……
直到
文件名表:
[两字节] 文件名长度
[文件名长度那么多字节] 文件名
[四字节] 固定的内容,值不重要
[四字节] 文件原长度
[四字节] 文件偏移
[四字节] 文件压缩后的长度
[两字节] 又一个文件名的长度
…
例程:
打包 PKGEncode.py
用法 python PKGEncode.py dirname pathname.pkg
# -*- coding: utf-8 -*-
import zlib, glob, os, sys, structfilelist = []class FileVisitor:def __init__(self, startDir=os.curdir):self.startDir = startDirdef run(self):for dirname, subdirnames, filenames in os.walk(self.startDir, True):for filename in filenames:self.visit_file(os.path.join(dirname, filename))def visit_file(self, pathname):filelist.append({'filename':pathname, 'size':0, 'zlib_size':0, 'offset':0, 'relative_filename': pathname.replace(os.path.normpath(self.startDir)+os.sep, '')})#print filelist[-1]['relative_filename']
if __name__ == "__main__":if len(sys.argv[1]) < 3:print 'few parameter'else:source_dirname = sys.argv[1]out_filename = sys.argv[2]FileVisitor(source_dirname).run()total = len(filelist)fp = file(out_filename + '~', 'wb')fp.write('\x64\x00\x00\x00')fp.write(struct.pack('I', len(filelist)))fp.write(struct.pack('I', 0))fp.write(struct.pack('I', 0))offset = 16for index in range(total):item = filelist[index]item['offset'] = offsetinfile = file(item['filename'], 'rb')text = infile.read()infile.close()item['size'] = len(text)text = zlib.compress(text)item['zlib_size'] = len(text)fp.write(text)offset += item['zlib_size']print u'已压缩文件 %d/%d' % (index+1, total)filename_table_offset = offsetfor index in range(total):item = filelist[index]fp.write(struct.pack('H', len(item['relative_filename'])))fp.write(item['relative_filename'])fp.write('\x01\x00\x00\x00')fp.write(struct.pack('I', item['offset']))fp.write(struct.pack('I', item['size']))fp.write(struct.pack('I', item['zlib_size']))offset += 2 + len(item['relative_filename']) + 16print u'已输出路径 %d/%d' % (index+1, total)filename_table_len = offset - filename_table_offsetfp.close()fp = file(out_filename + '~', 'rb')ret = file(out_filename, 'wb')fp.read(16)ret.write('\x64\x00\x00\x00')ret.write(struct.pack('I', len(filelist)))ret.write(struct.pack('I', filename_table_offset))ret.write(struct.pack('I', filename_table_len))copy_bytes = 16total_bytes = offsetwhile True:text = fp.read(2**20)ret.write(text)copy_bytes += len(text)print u'最后的拷贝 %d%%' % (copy_bytes*100.0/total_bytes)if not text:breakfp.close()ret.close()os.remove(out_filename + '~')
解包 PKGDecode.py
用法 python PKGDecode.py pathname.pkg dirname
# -*- coding: utf-8 -*-import sys, os, struct, zlibif __name__ == "__main__":if len(sys.argv) < 3:print 'few argument'else:pkgfilename = sys.argv[1]outdirname = sys.argv[2]pkgfile = file(pkgfilename, 'rb')pkgfile.read(4)filenums, = struct.unpack('I', pkgfile.read(4))filename_table_offset, = struct.unpack('I', pkgfile.read(4))filename_table_len, = struct.unpack('I', pkgfile.read(4))pkgfile.seek(filename_table_offset)for index in range(filenums):name_len, = struct.unpack('H', pkgfile.read(2))name = pkgfile.read(name_len)pkgfile.read(4)offset, = struct.unpack('I', pkgfile.read(4))size, = struct.unpack('I', pkgfile.read(4))zlib_size, = struct.unpack('I', pkgfile.read(4))current_pos = pkgfile.tell()pkgfile.seek(offset)text = pkgfile.read(zlib_size)text = zlib.decompress(text)pkgfile.seek(current_pos)outfilename = os.path.join(outdirname, os.path.join(os.path.splitext(os.path.basename(pkgfilename))[0], name))print u'进度 [%d/%d]: ' %(index+1, filenums), os.path.join(os.path.splitext(os.path.basename(pkgfilename))[0], name)if not os.path.exists(os.path.dirname(outfilename)):os.makedirs(os.path.dirname(outfilename))file(outfilename, 'wb').write(text)
感谢python各种库的方便
这两个程序也可以作为自己的压缩解压工具
pkg文件--一种简单的游戏资源打包格式相关推荐
- C3游戏引擎资源打包格式支持(APK不释放资源的问题)
http://www.9miao.com/thread-16828-1-1.html C3游戏引擎支持wdf和tpd两种资源打包格式. Wdf是一种C3游戏资源打包格式,不做数据压缩和加密,适合png ...
- 6.pixi.js编写的塔防游戏(类似保卫萝卜)-游戏资源打包逻辑
游戏说明 一个用pixi.js编写的h5塔防游戏,可以用electron打包为exe,支持移动端,也可以用webview控件打包为app在移动端使用 环境说明 cnpm@6.2.0 npm@6.14. ...
- 一款游戏资源解包工具的开发始末
来自 <http://www.jybase.net/ruanjianpojie/20120311795_5.html> 时间:2012-03-11 21:59来源:未知 整理:寂涯网络 点 ...
- 通用型游戏资源提取工具介绍
先感慨一下,这是篇2007年的帖子啊!!13年了! 游戏资源包括了游戏的图片.文字.音乐.动画和其他数据资源.虽然很多游戏的资源都是开放的或者采用通用格式压缩的,但也不少游戏是经特殊格式打包过了,要想 ...
- 通用型游戏资源提取工具介绍收藏
游戏资源包括了游戏的图片.文字.音乐.动画和其他数据资源.虽然很多游戏的资源都是开放的或者采用通用格式压缩的,但也不少游戏是经特殊格式打包过了,要想得到这些资源可以寻找专用的资源提取工具.但并非所有游 ...
- 【转贴】通用型游戏资源提取工具介绍 (推荐)
游戏资源包括了游戏的图片.文字.音乐.动画和其他数据资源.虽然很多游戏的资源都是开放的或者采用通用格式压缩的,但也不少游戏是经特殊格式打包过了,要想得到这些资源可以寻找专用的资源提取工具.但并非所有游 ...
- 如何转换图片的格式?分享五种简单好用的转换方法
图片的格式怎么进行转换呢?在数字时代,我们经常需要使用电子设备来处理和共享各种图片.然而,不同的设备和应用程序支持不同的图片格式,这可能会导致一些不便和问题.因此,我们需要将图片的格式进行转换,以便在 ...
- Webp格式图片怎么转JPG?教你几种简单好用的转换方法
Wepb格式的图片怎么转换成JPG格式呢?WebP是一种新型的图像格式,但是它目前仍然不被所有的浏览器和设备支持.大多数设备和浏览器都支持JPG格式,因此将WebP格式的图片转换成JPG格式可以确保图 ...
- 利用文件摘要简化游戏资源的引用管理
资源的引用管理是个有趣的话题,最近我在代码里实践了一种做法,可以在某些方面简化资源的管理,完成之后简单记录在这里.这篇文章先介绍传统的各种方式,然后简单说明一下,这个实践在传统方式的基础上做了哪些改善 ...
最新文章
- linux 进程 地址空间 内存分布 简介
- 06python 之基本数据类型
- 错误处理:RuntimeError: [enforce fail at ..\caffe2\serialize\inline_container.cc:145] . PytorchStreamRead
- 鸟哥的Linux私房菜(服务器)- 第六章、 Linux 网络侦错
- 双表联查mysql_MySQL的双表多表联查
- FreeModbus TCP传输
- 搜索宝典:搜索资料的三重境界【帮助高级篇】
- 用js实现千位分隔符
- vue 侦听器侦听对象属性_SQL Server始终处于侦听器状态
- 郭宏志的android无线点餐系统,Android无线点餐系统--含代码.doc
- wireless-tools源码分析-iwlist
- 快解析:用友T+异地访问解决方案
- imperva数据库脱敏-server2008
- IBM Jdk环境启动jboss,出现如下错误:SunX509 KeyManagerFactory not available
- php评论表情包怎么引入,WordPress中添加自定义评论表情包的方法
- Gitee项目分享——学之思开源考试系统
- C++ bit field 位域/位段
- Matlab中用Simulink快速画Bode图及 .m 文件画Bode图
- 古魂魂之刃2电脑版用逍遥模拟器电脑上玩手机账号数据互通
- Ubuntu下Ruby的下载和编译源码安装
热门文章
- java写一个查询详情接口_旅游景点api 景区详细信息查询服务
- 阅信短信平台走进网上书店
- 下载:Bejeweled 3(宝石迷阵3)简体中文版
- Dell R740服务器设置磁盘直通,不做RAID虚拟磁盘阵列
- python成绩统计_用Python操作Excel,实现班级成绩的统计
- zego实现简单的web端推拉流
- MongoDB 自学笔记(入门级教程)
- matlab改变figure大小,Matlab Figure 调整大小、字号、线宽
- 关于3D可视化平台!
- 生物医药实验室安全知识202203第七次作业答案(2022.11.11)