resources data-protection

resources - Combinando recursos en un solo archivo binario



data-protection (5)

¿Cómo se combinan varios recursos para una aplicación (imágenes, sonidos, secuencias de comandos, xmls, etc.) en un archivo binario único / múltiple para que estén protegidos de las manos del usuario? ¿Cuáles son los pasos típicos (organización, carga, encriptación, etc.)?

Esto es particularmente común en el desarrollo de juegos, sin embargo, muchos de los frameworks y motores de juegos no ofrecen una manera fácil de hacerlo, ni describen un enfoque general. He querido aprender a hacerlo, pero no sé por dónde empezar. ¿Alguien podría señalarme en la dirección correcta?


Hay muchas formas de hacer esto. m_pGladiator tiene algunas buenas ideas, especialmente con la seralización. Me gustaría hacer algunos otros comentarios.

Primero, si va a empaquetar una gran cantidad de recursos en un solo archivo (llamo a estos paquetes), entonces creo que debería trabajar para evitar cargar todo el archivo y luego desestacionalizarlo de la memoria. La simple razón es que es más memoria. Eso no es realmente un problema en las PC, supongo, pero es una buena práctica, y es esencial cuando se trabaja en la consola. Si bien no (actualmente) serializamos objetos como m_pGladiator ha sugerido, nos estamos moviendo hacia eso.

Hay dos tipos de paquetes que puede tener. Uno sería un archivo en el que desea un acceso arbitrario a los contenidos de los archivos. Un segundo tipo puede ser una colección de archivos donde necesita todos esos archivos al cargar un nivel. Un ejemplo básico podría ser:

  1. Un archivo de audio puede contener todo el audio de tu juego. Es posible que solo necesite cargar ciertos tipos de audio para los menús o pantallas de interfaz y diferentes conjuntos de audio para los niveles. Esto podría caer en la primera categoría de arriba.
  2. Un tipo que pertenece a la segunda categoría podría ser todos los modelos / texturas / etc. para un nivel. Básicamente, desea cargar todo el contenido de este archivo en el juego en el momento de la carga, ya que (probablemente) necesitará todos sus contenidos mientras un jugador esté jugando en ese nivel o sección.

muchos de los packfiles que construimos entran en la segunda categoría. Básicamente empaquetamos los contenidos de nivel y luego los comprimimos con algo como zlib. Cuando cargamos uno de estos en el momento del juego, leemos una pequeña cantidad del archivo, descomprimimos lo que hemos leído en un búfer de memoria y luego repetimos hasta que el archivo completo se haya leído en la memoria. El buffer que leemos es relativamente pequeño, mientras que el buffer de destino final es lo suficientemente grande como para contener el mayor conjunto de datos sin comprimir que necesitamos. Este método es complicado, pero, de nuevo, ahorra en RAM, es un ejercicio interesante para trabajar, y te sientes todo bien y abrigado porque eres un buen administrador de los recursos del sistema. una vez que el archivo de paquete ha sido completamente descomprimido en su buffer de destinatino, ejecutamos un pase final en el búfer para arreglar las ubicaciones del puntero, etc. Este método solo funciona cuando usted escribe su archivo de paquete como estructuras que el juego conoce. En otras palabras, nuestras herramientas de escritura de paquete de archivos comparten struct (o classses) con el código del juego. Básicamente estamos escribiendo y comprimiendo representaciones exactas de estructuras de datos.

Si simplemente desea reducir el número de archivos que está enviando e instalando en un equipo de usuarios, puede hacer algo como el primer tipo de archivo de paquete que describo. Tal vez tengas miles de texturas y simplemente quieras reducir la cantidad de archivos que tienes que cerrar y empaquetar. Puede escribir una pequeña utilidad que básicamente leerá los archivos que desea empaquetar juntos y luego escribirá un encabezado que contiene los archivos y sus compensaciones en el archivo de paquete, y luego podrá escribir los contenidos del archivo, uno a la vez, uno después del otro, en su gran archivo binario. En el momento del juego, simplemente puede cargar el encabezado de este archivo de paquete y almacenar los nombres de archivo y las compensaciones en un hash. Cuando necesite leer un archivo, puede actualizar el nombre del archivo y ver si existe en su archivo de paquete, y si es así, puede leer los contenidos directamente desde el archivo de paquete buscando el desplazamiento y luego leyendo desde esa ubicación en el archivo de paquete. De nuevo, este método es básicamente una forma de agrupar datos sin tener en cuenta el cifrado, etc. Simplemente es un método de organización.

Pero una vez más, quiero enfatizar que si vas a ir por una ruta como I o m_pGladiator, trabajaría duro para no tener que extraer todo el archivo en la memoria RAM y luego deserializar a otra ubicación en la memoria RAM. Eso es un desperdicio de recursos (que quizás tengas en abundancia). Diría que puede hacer esto para que funcione y, una vez que esté funcionando, puede trabajar en un método que solo lea parte del archivo a la vez y luego descomprima en el búfer de destino. Sin embargo, debe usar un esquema de compsición que funcionará así. zlib y lzw ambos lo hacen (creo). No estoy seguro acerca de un algoritmo MD5.

Espero que esto ayude



Personalmente, nunca usé las herramientas ya disponibles para hacer eso. Si quieres evitar que tu juego sea pirateado fácilmente, entonces debes desarrollar tu propio motor de manipulación de recursos.

  1. Antes que nada, lee sobre la serialización de objetos . Cuando carga un recurso del archivo (gráfico, sonido o lo que sea), se almacena en alguna instancia de objeto en la memoria. Un juego generalmente usa docenas de objetos gráficos y de sonido. Tienes que hacer una herramienta, que los cargue todos y los almacene en colecciones en la memoria. A continuación, serialice esas colecciones en un archivo binario y tendrá todos los recursos allí.

  2. Entonces puede usar, por ejemplo, MD5 o cualquier otro algoritmo de encriptación para encriptar este archivo.

  3. Además, puede usar zlib u otra biblioteca de compresión para hacer que este gran archivo binario sea un poco más pequeño.

  4. En el juego, debes cargar el archivo binario encriptado y descomprimirlo. Luego descifrarlo. Luego deserialice las colecciones de objetos y vuelva a tener todos los recursos en la memoria.

Por supuesto, puede hacer que esto sea más completo almacenando en diferentes archivos binarios los recursos para diferentes niveles, etc. - hay muchas variantes, dependiendo de lo que desee. También puedes primero comprimir, luego encriptar o hacer otras combinaciones de los pasos.


Respuesta corta: sí

En Mac OS 6,7,8 había una API sustancial dedicada a esta tarea exacta. Busque el "Administrador de recursos" si está interesado. Editar: Lo mismo ocurre con el paquete de análisis de física ROOT .

No es que yo sepa de una buena herramienta en este momento. ¿En qué plataforma (s) quieres que funcione?

Editado para agregar: Todas las dos o tres herramientas de este tipo que estoy lejos comparten una estructura similar:

  • El archivo comienza con un encabezado e índice
  • Hay una serie de bloques, algunos de los cuales pueden tener sus propios encabezados e indicios, algunos de los cuales son hojas
  • Cada hoja es una serialización simple de los datos que se almacenarán.
  • El archivo completo (o, a veces, bloques individuales) puede estar comprimido.

No es terriblemente difícil implementar el tuyo, pero buscaría uno bueno que satisfaga tus necesidades primero.


hacer como Java: empacar todo en un zip, y utilizar una API similar a un sistema de archivos para leer directamente desde allí.