将资源组合到单个二进制文件中

时间:2008-10-15 18:33:20

标签: resources data-protection

如何将应用程序的多个资源(图像,声音,脚本,xml等)组合成单个/多个二进制文件,以便它们不受用户的影响?什么是典型的步骤(组织,加载,加密等......)?

这在游戏开发中尤为常见,但很多游戏框架和引擎并没有提供一种简单的方法来实现这一点,也没有描述一般的方法。我一直想学习如何去做,但我不知道从哪里开始。有人能指出我正确的方向吗?

5 个答案:

答案 0 :(得分:3)

有很多方法可以做到这一点。 m_pGladiator有一些很好的想法,特别是对于seralization。我想提出一些其他意见。

首先,如果你打算将一堆资源打包到一个文件中(我称之为这些打包文件),那么我认为你应该努力避免加载整个文件,然后将该文件解包到内存中。原因很简单,它的内存更多。我认为这在PC上确实不是问题,但这是一个很好的做法,在操作控制台时这是必不可少的。虽然我们没有(当前)像m_pGladiator建议的那样序列化对象,但我们正朝着这个方向发展。

您可能拥有两种类型的packfiles。一个是您希望任意访问文件内容的文件。第二种类型可能是文件集合,在加载级别时,您需要所有这些文件。一个基本的例子可能是:

  1. 音频包文件可能包含游戏的所有音频。您可能只需要为菜单或界面屏幕加载某些类型的音频,为级别加载不同的音频组。这可能属于他上面的第一类。
  2. 属于第二类的类型可能是某个级别的所有模型/纹理/等。你基本上想要在加载时将这个文件的全部内容加载到游戏中,因为当玩家正在玩那个级别或部分时你(可能)需要所有内容。
  3. 我们构建的许多packfiles属于第二类。我们基本上打包了级别内容,然后用zlib之类的东西压缩它们。当我们在游戏时加载其中一个时,我们读取少量文件,将我们读入的内容解压缩到内存缓冲区中,然后重复直到将完整文件读入内存。我们读入的缓冲区相对较小,而最终目标缓冲区足够大,可以容纳我们需要的最大的未压缩数据集。这种方法很棘手,但同样,它可以节省RAM,这是一项有趣的工作,让你感觉内心温暖,因为你是一个很好的管理系统资源。一旦packfile完全解压缩到它的destinatino缓冲区,我们在缓冲区上运行最后一次传递来修复指针位置等。这个方法只有在你将packfile写成游戏知道的结构时才有效。换句话说,我们的packfile编写工具与游戏代码共享结构(或类)。我们基本上是在写出并压缩数据结构的精确表示。

    如果您只是想减少要在用户计算机上发送和安装的文件数量,可以使用我描述的第一种packfile。也许你有1000个纹理,只是想减少你必须压缩和打包的文件数量。您可以编写一个小实用程序,它基本上会读取您要打包在一起的文件,然后在packfile中编写包含文件及其偏移量的标题,然后您可以一次编写一个文件的内容,一个在另一个之后,在你的大型二进制文件中。在游戏时,您只需加载此packfile的标头,并将文件名和偏移量存储在哈希中。当您需要读取文件时,可以散列文件名并查看它是否存在于packfile中,如果存在,您可以直接从packfile中读取内容,方法是查找偏移量,然后从packfile中的该位置读取。同样,这种方法基本上是一种将数据打包在一起而不考虑加密等的方法。它只是一种组织方法。

    但是,我再次强调,如果你要像我或m_pGladiator建议的路线,我会努力不必将整个文件拉入RAM,然后反序列化到RAM中的另一个位置。这是浪费资源(你可能有很多)。我会说你可以这样做让它工作,然后一旦它工作,你可以处理一个只读取文件的一部分,然后解压缩到目标缓冲区的方法。你必须使用一个类似于此的comprseion方案。 zlib和lzw都做(我相信)。我不确定MD5算法。

    希望这会有所帮助。

答案 1 :(得分:2)

像Java一样:将所有内容打包成zip,并使用类似文件系统的API直接从那里读取。

答案 2 :(得分:0)

简答:是的。

在Mac OS 6,7,8中,有一个专门针对这个确切任务的API。如果您有兴趣,请查找“资源管理器”。编辑:ROOT物理分析包也是如此。

现在不是我知道一个好工具。您希望它在哪些平台上工作?


编辑添加:我所遗弃的所有这两种或三种工具都有类似的结构:

  • 文件以标题和索引
  • 开头
  • 有一系列的块,其中一些可能有自己的标题和标记,其中一些是叶子
  • 每个叶子都是要存储的数据的简单序列化。
  • 可以压缩整个文件(或者有时是单个块)。

实现自己的并不是非常困难,但我会寻找一个能够满足您需求的现有产品。

答案 3 :(得分:0)

就个人而言,我从未使用过已有的工具来做到这一点。如果你想防止你的游戏被轻易入侵,那么你必须开发自己的资源操作引擎。

  1. 首先阅读serializing objects。从文件(图形,声音或其他)加载资源时,它将存储在内存中的某个对象实例中。游戏通常使用数十种图形和声音对象。您必须创建一个工具,将它们全部加载并将它们存储在内存中的集合中。然后将这些集合序列化为二进制文件,并在那里拥有所有资源。

  2. 然后您可以使用例如MD5或任何其他加密算法来加密此文件。

  3. 此外,您可以使用zlib或其他压缩库将这个大二进制文件缩小一点。

  4. 在游戏中,您应该加载加密的二进制文件并将其解压缩。然后解密它。然后反序列化对象集合,并将所有资源重新存储在内存中。

  5. 当然,你可以通过在不同的二进制文件中存储不同级别的资源等来使这更加全面 - 根据你的需要,有很多变种。您也可以先压缩,然后加密,或者进行其他步骤组合。

答案 4 :(得分:0)

对于像我这样的未来人士,如果想知道同一主题,请查看以下两个链接:

http://www.sfml-dev.org/wiki/en/tutorials/formatdat

http://archive.gamedev.net/reference/programming/features/pak/