plain framework 1 pak插件说明(资源压缩加密)

在互联网的发展中,资源的整理一般成了发布软件应用的迫在眉睫的一件事情,不经打包的资源往往容易暴露而且众多的文件使得拷贝等待时间变长。在这种情况下,一种应用便诞生了,其起源是源自压缩软件,这便是我们今天要介绍的打包插件。

resources package

  1、魔兽世界

  2、天龙八部

\

  3、剑侠情缘三

  4、笑傲江湖

5、刀剑2OL

PAK SOURCE

PAK SIMPLE TUTORIALS

  图例

  pak 数据包简介

  1. 解释
    pak数据包一般用在资源打包加密上,也就是把许多文件塞入一个文件内并压缩与加密, 一般用于游戏资源和配置的打包发布,例如魔兽世界经典的mpq资源包。

  2. 分类

    • 普通数据包,这类数据包一般用在对应用的数据读取直接使用
    • 补丁数据包,这类数据包一般用在对应用的数据包需要更新时使用
  3. 基本结构

    文件标记 | 包头数据 | 文件数据 | 文件数据 ... (最基本的结构)
    文件标记 | 包头数据 | HASHKEY TABLE | BLOCK TABLE | 列表信息文件数据 | 属性信息文件数据 | 文件数据 ... (pak结构)

  4. 包头数据结构

    包头数据为固定的一个结构体,它存放了一些最基本的pak包的信息,如版本信息、文件大小、文件的类型等等。

  5. 文件数据结构 文件块位置数据 | 文件块数据 ...

  6. HASHKEY TABLE

    顾名思义,它的存放了文件的名称,用来定位文件块数据的索引。

  7. BLOCK TABLE

    文件块数据数组,通过文件块数据索引可以获得对应文件块数据的数据存储位置(pak文件)、压缩后的大小、未压缩的大小、状态标记。

  8. 列表信息文件数据

    不管是普通包还是补丁数据包都有该文件,并放在第一个文件位置,即紧跟在BLOCK TABLE之后, 主要存放了有关文件名的数据。

  9. 属性信息文件数据

    不管是普通包还是补丁数据包都有该文件,并放在第二个文件位置,紧跟在列表信息文件之后, 存放了文件的版本、标记、crc32数据、时间数据、md5数据。

  10. 文件块数据及位置 文件块数据位置是一位存放文件块数据位置的数组,文件块数据为文件数据的基本单位, 在pak中一个文件块数据的基本大小为4096字节即4K。

  11. 关于普通和补丁包的区别

    两者在大小上有明显的区别,因为普通包会将文件列表信息数据保持足够的大,所以会将该文件数据分配为一个大小为2M的空间, 而补丁文件则根据文件有多少则记多少的原则。

PAK SIMPLE

  code.

复制代码
#include "pak/interface.h"
#include "pak/file.h"
#include "pak/util.h"
#include "main.h"

int32_t main(int32_t argc, char * argv[]) {
  uint64_t result = 0;
  pak::archive_t *archive = pak::archivecreate("test.pak", 
                                               result, 
                                               0x10000, 
                                               PAK_TYPE_PATCH);
  if (NULL == archive) return -1;
  pak::fileadd(archive, 
               "files\\filelist.txt", 
               "files\\filelist.txt",
               PAK_FILE_ENCRYPTED | PAK_FILE_COMPRESS, 
               0, 
               pak::kFileTypeData);
  pak::fileadd(archive, 
               "files\\filelist.txt", 
               "files\\filelist.txt",
               PAK_FILE_ENCRYPTED | PAK_FILE_COMPRESS | PAK_FILE_REPLACEEXISTING, 
               0, 
               pak::kFileTypeData);
  ERRORPRINTF("pak::fileadd end 1.file");
  pak::fileadd(archive, 
               "files\\global.txt", 
               "2.file",
               PAK_FILE_ENCRYPTED | PAK_FILE_COMPRESS, 
               0, 
               pak::kFileTypeData);
  ERRORPRINTF("pak::fileadd end 2.file");
  pak::archive_t *clonearchive = archive->createclone(result);
  pak::file_t *file = pak::fileopen(clonearchive, "files\\filelist.txt", result);
  DEBUGPRINTF("result: %d", result);
  if (!file) return -1;
  char *buffer = new char[1024 * 1024];
  if (!buffer) return -1;
  memset(buffer, 0, 1024 * 1024);
  uint64_t readed, size;
  size = pak::filesize(file);
  ERRORPRINTF("size: %d", size);
  pak::fileread(file, buffer, size, &readed);
  DEBUGPRINTF("buffer: %s, readed: %d", buffer, readed);
  pak::fileeof(file);
  pak::fileclose(file);
  archive->destoryclone(clonearchive);
  pak::archiveclose(archive);
  DEBUGPRINTF("1 archiveclose");
  memset(buffer, 0, 1024 * 1024);
  archive = pak::archiveopen("test.pak", result, true);
  DEBUGPRINTF("result: %d", result);
  if (!archive) return -1;
  DEBUGPRINTF("archive not NULL");
  file = pak::fileopen(archive, "files\\filelist.txt", result);
  if (!file) return -1;
  pak::fileread(file, buffer, size, &readed);
  DEBUGPRINTF("1 buffer: %s, readed: %d", buffer, readed);
  pak::fileeof(file);
  pak::fileclose(file);
  pak::fileadd(archive,
               "files\\task.txt",
               "2.file",
               PAK_FILE_ENCRYPTED | PAK_FILE_COMPRESS | PAK_FILE_REPLACEEXISTING,
               0,
               pak::kFileTypeData);
  file = pak::fileopen(archive, "2.file", result);
  if (!file) return -1;
  size = pak::filesize(file);
  pak::fileread(file, buffer, size, &readed);
  DEBUGPRINTF("1 buffer: %s, readed: %d", buffer, readed);
  pak::fileeof(file);
  pak::fileclose(file);
  pak::archiveclose(archive);
  archive = pak::archiveopen("test.pak", result, true);
  DEBUGPRINTF("result: %d", result);
  if (!archive) return -1;
  DEBUGPRINTF("archive not NULL");
  file = pak::fileopen(archive, "2.file", result);
  if (!file) return -1;
  size = pak::filesize(file);
  pak::fileread(file, buffer, size, &readed);
  DEBUGPRINTF("1 buffer: %s, readed: %d", buffer, readed);
  pak::fileclose(file);
  pak::fileeof(file);
  pak::archiveclose(archive);
#if __WINDOWS__
  system("pause");
#endif
  return 0;
}
复制代码

  result.

  1. windows

 

  2. linux

 

源码说明

  特别说明这部分源码来自与经典的魔兽世界mpq包算法以及KPM衍生而来,为了尊重原作者在源码中保留了大部分的英文注释。源码如代码中作者的注释一样还有一些奇怪和不足的地方,这些不足大家可以自行找相应的办法临时修复,如果你找到了彻底解决的方法而不吝啬可以联系我。鉴于这部分代码比较旧,在不触犯代码著作的前提下,改写了大部分的结构,同时支持多平台使用,不用担心64/32位使用产生的问题。

 成员招募(长期有效)

  如果你也对开源知识比较感兴趣,如果也对网络应用或者网络游戏感兴趣,如果你也对该框架感兴趣,你可以加入我们的QQ群(348477824)。

  欢迎大家进群相互交流学习,同时也欢迎各位朋友对该框架供出自己的一份心力。

作者:viticm  出处: http://www.cnblogs.com/lianyue/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。如果觉得还有帮助的话,可以点一下右下角的 【推荐】,希望能够持续的为大家带来好的技术文章!想跟我一起进步么?那就 【关注】我吧。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值