3

如何将应用程序的多个资源(图像、声音、脚本、xml 等)组合到一个/多个二进制文件中,以保护它们免受用户手的伤害?典型的步骤是什么(组织、加载、加密等)?

这在游戏开发中尤其常见,但是很多游戏框架和引擎都没有提供简单的方法来做到这一点,也没有描述通用的方法。我一直想学习如何去做,但我不知道从哪里开始。谁能指出我正确的方向?

4

5 回答 5

3

有很多方法可以做到这一点。m_pGladiator 有一些好主意,尤其是在序列化方面。我想发表一些其他意见。

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

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

  1. 音频包文件可能包含游戏的所有音频。您可能只需要为菜单或界面屏幕加载某些类型的音频,并为关卡加载不同的音频集。这可能属于上述第一类。
  2. 属于第二类的类型可能是一个级别的所有模型/纹理/等。您基本上希望在加载时将此文件的全部内容加载到游戏中,因为您(可能)会在玩家玩该级别或部分时需要它的所有内容。

我们构建的许多包文件属于第二类。我们基本上将关卡内容打包,然后用 zlib 之类的东西压缩它们。当我们在游戏时加载其中一个时,我们会读取少量文件,将读取的内容解压缩到内存缓冲区中,然后重复直到整个文件被读入内存。我们读入的缓冲区相对较小,而最终目标缓冲区大到足以容纳我们需要的最大的未压缩数据集。这种方法很棘手,但同样,它节省了 RAM,这是一个有趣的开始工作的练习,而且你感觉非常好和温暖,因为你是系统资源的好管家。一旦packfile完全解压到它的destinatino缓冲区中,我们在缓冲区上运行最后一次以修复指针位置等。此方法仅在您将包文件写为游戏知道的结构时才有效。换句话说,我们的打包文件编写工具与游戏代码共享结构(或类)。我们基本上是在写出和压缩数据结构的精确表示。

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

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

希望这会有所帮助。

于 2008-10-16T14:17:52.430 回答
2

像 Java 一样:将它全部打包在一个 zip 中,并使用类似文件系统的 API 直接从那里读取。

于 2008-10-15T18:44:49.427 回答
0

简短的回答:是的。

在 Mac OS 6、7、8 中,有大量 API 专门用于执行此任务。如果您有兴趣,请查找“资源管理器”。编辑:ROOT物理分析包也是如此。

并不是说我现在知道一个好的工具。您希望它在什么平台上运行?


编辑添加:我离开的所有两三个工具都具有相似的结构:

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

实现你自己的并不难,但我会寻找一个好的现有的,首先满足你的需求。

于 2008-10-15T18:43:08.947 回答
0

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

  1. 首先阅读有关序列化对象的信息。当您从文件(图形、声音或其他)加载资源时,它会存储在内存中的某个对象实例中。一个游戏通常使用几十个图形和声音对象。您必须制作一个工具,将它们全部加载并存储在内存中的集合中。然后将这些集合序列化成一个二进制文件,你就拥有了那里的所有资源。

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

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

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

当然,您可以通过将不同级别的资源存储在不同的二进制文件中来使其更全面,等等 - 有很多变体,具体取决于您想要什么。您也可以先压缩,然后加密,或对这些步骤进行其他组合。

于 2008-10-15T18:48:36.847 回答
0

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

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

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

于 2011-03-16T00:27:24.213 回答