TREInfo.py
Seamos un poco monotemáticos. Si os poneis a jugar al Star Wars Galaxies una de las primeras cosas que aprendereis será el uso de la tecla Bloq Num, que normalmente está asociada a correr permanentemente, es decir, una pulsación y nuestro personaje correrá, otra y dejará de correr. No quiero decir con esto que seais unos cobardes y salgais corriendo de todos los enfrentamientos (aunque se que todos huimos alguna vez) sino que empezareis a acostumbraros a ir corriendo (o en moto, aerocoche, lo que sea…) de una ciudad a otra del planeta (sí, se que existen los espacio-puertos con lanzaderas entre las ciudades).
Yo, personalmente, me he hartado de correr de un lado para otro, y a pesar de que dejo puesto el "auto-correr" y el "muñecajo" apuntando al waypoint es una pesadez verle subir y bajar montañas sin sentido. Porque por las películas Tantooine podría parecer un desierto más o menos plano, pero los diseñadores debieron pensar que quizá infringieran algúna trademark de Dune y decidieron ponerle montañas, un montón de odiosas y altas montañas.
En Ultima Online (otro juego en linea al que jugue hace un par de años) el mundo era mucho más plano, pero a parte de esto ¡tenía caminos! Es cierto que en los caminos había una gran concentración de PK dispuestos a "ayudarte" con tu mochila, pero más o menos eran itinerarios sencillos y relativamente planos. En Star Wars Galaxies los caminos brillan por su ausencia (o el menos en Tantooine) y no me importaria que existieran a pesar de estar llenos de Moradores de las Arenas.
Así que decidí buscar mapas de Tantooine, ya que en el mapa del juego las alturas no están muy bien representadas (hay diversas tonalidades de marrón, pero no es muy comprensible lo que significan, si es que significan algo). Obviamente a la gente no debe importarle dejar a su personaje corriendo media hora, porque no encontré un mapa como el que a mi me gustaba (sí encontre un buen mapa de Tantooine con todos los lugares "interesantes" marcados y ¡el circuito de Mos Espa!), aunque sí encontré dos buenas páginas sobre Star Wars Galaxies: Allakhazam.com: Star Wars Galaxies y Star Wars Galaxies (SWG) Resource Center. Imprescindibles para el turista espacial.
Y como un Jedi nunca se rinde (bueno, aún no soy un Jedi, ni siquiera los Rebeldes me dejan hacer sus misiones… :() pues aplicamos la filosofía Bricomanía: Hazlo tú mismo. TREInfo.py es el resultado. No obtiene el mapa de alturas (aún) pero quizá a alguien le sea útil.
Si vais al directorio de Star Wars Galaxies hay un montón de archivos .tre, que además son bastante grandes (no pasan de 99,9 MiB, pero hay muchos de esos), asi que es muy probable que fueran una especie de archivos contenedores. En este momento debía haber buscado en Google y habría encontrado RPG Expert - Star Wars Galaxies - Mod Overview y XeNTaX :: View Topic - Star Wars Galaxies TRE file format (lastima que el enlace donde se promete explicación no funcione). Pero claro, no habría sido tan divertido.
Los archivos .tre comienzan siempre con la cadena EERT5000 seguido de el valor 9 ocupando 4 bytes (en little endian). Después hay 6 valores de 4 bytes más.
- El primero es muy grande y normalmente está cerca del final del fichero. Normalmente esto representa el desplazamiento dentro del archivo de una especie de directorio (buscad las especificaciones delos
.pakde Quake si quereis un ejemplo más sencillo con una estructura similar). - Los valores segundo y cuarto eran
2en los primeros archivos que he abierto (luego he descubierto archivos con el valor0), en principio no tenia ni idea de lo que eran, así que los he dejado de lado (cuando he descubierto archivos sin estos doses he comprendido su significado). - Los valores tercero, quinto y sexto eran valores relativamente pequeños, y si tenemos el desplazamiento de un directorio tambien tenemos que tener su longitud o el número de elementos (a veces esto no es asi, si el directorio está al final quizá se omita la longitud y se suponga que el directorio ocupa desde su comienzo hasta el final del archivo, si las entradas del directorio son de una longitud fija no necesitamos ni siquiera el número de elementos). De todas formas en este caso las longitudes son un poco desorientadoras ya que no llegan al final del fichero (mi ignorancia me puede y desconozco la razón).
El siguiente paso es ver que hay en el directorio. Pero a simple vista en el directorio sólo hay basura, números sin sentido ni estructura. Es extraño ya que justo al principio del archivo se podía ver una cabecera de un archivo MP3 toda claríta (empiezan, si tienen etiquetas embebidas, por ID3) y sin cifrar, ¿por qué iba a estar esta parte cifrada? De todas formas he extraido desde el desplazamiento indicado en la cabecera hasta el final del archivo a otro archivo y le he pedido a file que me lo identificara. ¡¿raw data?! ¡¡Arggg!! No perdamos los nervios… Cuáles son los primeros bytes de esa parte, bueno todos comparten al principio la cadena 0x78 0x9c, ahora Googleamos un rato y ¡pluf!, escondido en las entrañas de Google hay una referencia a la librería zlib (entre muchas a archivos del kernel de Linux en los drivers de ISDN ¿?)… por probar no pasa nada. Al descomprir el archivo con zlib (por suerte Python dispone del módulo zlib) vuelven a aparecer números y letras, pero esta vez tienen algo más de sentido que la basura anterior.
En este punto sucede una cosa curiosa, la longitud de los datos descomprimidos es menor que la de los comprimidos, esto puede suceder para algunos tipos de compresión, pero no en cantidades de datos tan grandes. Se me ocurre que puede que no todo el final del archivo sean datos comprimidos y efectivamente si descomprimimos sólo la parte correspondiente a la longitud indicada por el tercer valor de la cabecera obtenemos el mismo resultado. Más curioso aún, justo después de ese trozo aparece de nuevo la cadena 0x78 0x9c asi que pruebo con el quinto valor como longitud y ¡voila! cadenas de texto plano con nombres de directorios y archivos separados por carácteres nulos. Aún queda contenido después de este trozo pero el sexto valor de la cabecera es demasiado grande para ser una longitud y no empieza por la misma cadena que los otros dos (desconozco el significado del sexto valor y si la basura del final de archivo tiene algún significado).
Ahora con la longitud real del primer trozo del final de archivo simplemente lo dividimos entre el número de cadenas existente en el segundo y obtenemos un número exacto que nos indica la longitud de la estructura. En nuestro caso mide 24 bytes que representan lo siguiente:
- Los primeros 4 bytes desconozco el significado. Son números bastante grandes y en orden creciente.
- Los siguientes 8 bytes son el desplazamiento dentro del archivo contenedor del principio del archivo y su longitud.
- Justo después, en los primeros archivos analizados, hay dos conjuntos de 4 bytes todos con el valor 0.
- El último grupo de 4 bytes es también una lista de números crecientes. Su máximo es de un valor parecido a la longitud de la lista de cadenas que hemos descomprimido. Un poco de investigación lleva a pensar que los números representan donde comienzan cada cadena (personalmente no he utilizado esto ya que parecen estar ordenados y en Python las cadenas no tienen por que terminar en el carácter nulo).
Con todos estos datos es fácil realizar un extractor sencillo, pero al empezar a utilizarlo empiezan los problemas, por ejemplo en algunos hotfix la descompresión de las tablas del final del archivo falla. Al abrirlos me doy cuenta de que no estan comprimidas… pero al ver la cabezera también veo que donde había valores 2 ahora hay 0, por lo que esos valores deben indicar si las tablas estan o no comprimidas (más bien parece indicar un cierto tipo de compresión, aunque no he encontrado valores 1).
El segundo problema viene al intentar descomprimir archivos grandes. En ellos los valores a 0 del directorio de archivos no está a 0, sino a 2 (¿a alguien le suena?), el segundo valor es un valor grande pero ligeramente menor que la longitud y sólo es distinto de 0 cuando la columna anterior es distinta de 0. Indica la longitud comprimida del archivo. Esta opción es inteligente ya que los archivos MP3 no están comprimidos dentro del archivo (no serviría de mucho) pero otros sí.
TREinfo.py es funcional en todos los casos comentados, aunque no es muy funcional debido a la brutal compresión. En el momento de descomprir uno de los archivos grandes (100 MiB) se ha comido 11 Gib de mi disco duro, lo que me parece una compresión muy fuerte. Aunque el listado del archivos lo produce (presumiblemente) bien. De todas formar mejor que utiliceis alguno de los dos programas enlazados más arriba, aunque si quereis ejemplos en Python de como utilizar el módulo zlib o el módulo struct (muy interesante para archivos binarios) puede ser interesante su lectura (son menos de 100 lineas en total).
Actualización (2004-09-15): He actualizado el archivo ya que no descomprimia los datos muy bien que digamos. Un problema con las tuplas de Python indexadas en 0 y mi cabeza pensante después de añadirle un elemento nuevo al principio. Me parece muy mal que no me hayais avisado y os estuvieraís carcajeando de mi por ahí.
Ver entradas relacionadas
- No se han encontrado entradas relacionadas


14 de Septiembre de 2004 a las 18:59
Desde cuando, eres miembro del departamente de publicidad de lucas arts? XDXDXD.
15 de Septiembre de 2004 a las 16:31
¿Publicidad? ¿Pero qué publicidad se hace aquí? ¡¡¡Lo que digo que mucha nave espacial y mucha espada laser y no tienen ni un misero camino para los pobres banthas!!!