From client 08292012 and this scripts:Quote:
Which one ?
C# moemet
Code:
static void Main(string[] args)
{
string _srcGel = "D:\\NexusRohan\\res\\world.gel";// edit this part
string _srcGem = "D:\\NexusRohan\\res\\world.gem";// edit this part
string _srcDest = "D:\\GelGemExtract\\world\\";// edit this part
using (FileStream fsGel = new FileStream(_srcGel, FileMode.Open, FileAccess.Read))
{
using (BinaryReader brGel = new BinaryReader(fsGel))
{
int m_ID = brGel.ReadInt32();
int m_Version = brGel.ReadInt32();
int m_MaxAllocFileNum = brGel.ReadInt32();
int m_MissingFileSize = brGel.ReadInt32();
int m_Reserved = brGel.ReadInt32();
int m_Reserved1 = brGel.ReadInt32();
int _pos = 0;
while (brGel.BaseStream.Position < brGel.BaseStream.Length )
{
int i1 = brGel.ReadInt32();
int i2 = brGel.ReadInt32();
byte[] filename = brGel.ReadBytes(128);
int i3 = brGel.ReadInt32();
int startOffset = brGel.ReadInt32();
int dataSize = brGel.ReadInt32();
int i6 = brGel.ReadInt32();
using (FileStream fsGem = new FileStream(_srcGem, FileMode.Open, FileAccess.Read))
{
using (BinaryReader brGem = new BinaryReader(fsGem))
{
string _s1 = Encoding.UTF8.GetString(filename);
_s1 = _s1.Substring(0, _s1.IndexOf("\0"));
if (!_s1.EndsWith(".gbf"))
{
int _spos1 = _s1.LastIndexOf("\\");
string _pth = _srcDest + _s1.Substring(0, _spos1);
if (!System.IO.Directory.Exists(_pth))
{
System.IO.Directory.CreateDirectory(_pth);
}
}
string _result = _srcDest + _s1;
brGem.BaseStream.Seek(startOffset, SeekOrigin.Begin);
if (dataSize > 0)
{
using (FileStream fsDest = new FileStream(_result, FileMode.Append, FileAccess.Write))
{
using (BinaryWriter bw = new BinaryWriter(fsDest))
{
bw.Write(brGem.ReadBytes(dataSize));
Console.WriteLine("writing :" + _result + "\n");
}
}
}
}
}
_pos += 1;
}
}
}
}
C++ Xentax
Code:
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <tchar.h>
#include <stdlib.h>
#include <stdio.h>
#include <string>
struct GELHeader
{
int i1;
int i2;
int numberOfElements;
int i4;
int i5;
int i6;
void print()
{
//printf( "i1 = %d\n", i1 );
//printf( "i2 = %d\n", i2 );
printf( "numberOfElements = %d\n", numberOfElements );
//printf( "i4 = %d\n", i4 );
//printf( "i5 = %d\n", i5 );
//printf( "i6 = %d\n", i6 );
printf( "\n" );
}
};
struct GELEntry
{
int i1;
int i2;
char filename[128];
int i3;
int startOffset;
int dataSize;
int i6;
void print()
{
//printf( "i1 = %d\n", i1 );
//printf( "i2 = %d\n", i2 );
printf( "filename = %s\n", filename );
//printf( "i3 = %d\n", i3 );
printf( "startOffset = %d\n", startOffset );
printf( "dataSize = %d\n", dataSize );
//printf( "i6 = %d\n", i6 );
printf( "\n" );
}
};
// Set this to the .GEL file that you want to extract
std::string srcGel = "F:\\Paker\\animation.gel";
// Set this to the .GEM file that matches the .GEL file you want to extract
std::string srcGem = "F:\\Paker\\animation.gem";
// This is the path where all the files will be extracted to
std::string destPath = "F:\\Paker\\Animation\\";
int iiii = 0;
/*
char hextoascii(char a, char b)
{
char hex[5], *stopper;
hex[0] = '0';
hex[1] = 'x';
hex[2] = a;
hex[3] = b;
//hex[4] = '0';
return strtol(hex, &stopper, 16);
}
*/
int main()
{
FILE* gelFP;
gelFP = fopen(srcGel.c_str(), "rb" );
if( gelFP )
{
FILE* gemFP;
gemFP = fopen(srcGem.c_str(), "rb" );
if( gemFP )
{
GELHeader gelHeader;
fread( &gelHeader, sizeof( GELHeader ), 1, gelFP );
//gelHeader.print();
printf("Extracting Files: \n");
for( int i=0; i<gelHeader.numberOfElements; i++ )
{
GELEntry gelEntry;
fread( &gelEntry, sizeof( GELEntry ), 1, gelFP );
//gelEntry.print();
printf( "\b\b\b\b\b\b\b%d", i + 1 );
if( gelEntry.dataSize > 0 )
{
// Create the file
std::string sFilename = gelEntry.filename;
size_t pos = sFilename.find_last_of( "\\" );
std::string path = sFilename.substr( 0, pos + 1 );
std::string filename = sFilename.substr( pos + 1, sFilename.length() - pos );
//printf( "Path = %s\nFile = %s\n", path.c_str(), filename.c_str() );
std::string newPath = destPath;
newPath.append( path );
CreateDirectory( newPath.c_str(), NULL );
// Detect GTX files (DDS files with the header changed and the extension changed
pos = filename.find_last_of( "." );
//printf( "pos = %d\n", pos );
std::string ext = filename.substr( pos + 1, filename.length() - pos - 1 );
//printf( "ext = %s\n", ext.c_str() );
if( ext.find( "gtx" ) != std::string::npos )
{
//printf( "Found GTX file!\n" );
char* data = (char*)malloc( gelEntry.dataSize );
fseek( gemFP, gelEntry.startOffset, 0 );
fread( data, gelEntry.dataSize, 1, gemFP );
printf("%d",gelEntry.startOffset);
if( data[0] == 'G' && data[1] == 'E' && data[2] == 'O' )
{
// Most gtx files are DDS files with the "Magic Word" changed to GEO. We change that here, before
// writing the file
filename.replace( pos + 1, 3, "tga" );
std::string fullPath = newPath;
fullPath.append( "\\" );
fullPath.append( filename );
//data[0] = hextoascii('0','0');
//data[1] = hextoascii('0','0');
//data[2] = hextoascii('0','a');
//data[0] = NULL;
//data[1] = NULL;
//data[2] = NULL;
FILE* outFP;
outFP = fopen(fullPath.c_str(), "wb" );
if( outFP )
{
fwrite( data, gelEntry.dataSize, 1, outFP );
fclose( outFP );
}
}
else if( data[0] == 'D' && data[1] == 'D' && data[2] == 'S' )
{
// Sometimes, DDS files have the proper header in them
filename.replace( pos + 1, 3, "dds" );
std::string fullPath = newPath;
fullPath.append( "\\" );
fullPath.append( filename );
FILE* outFP;
outFP = fopen(fullPath.c_str(), "wb" );
if( outFP )
{
fwrite( data, gelEntry.dataSize, 1, outFP );
fclose( outFP );
}
}
else
{
// Haven't come across this yet, but just in case, we'll know.
printf( "\n" );
printf( "Encountered UNKNOWN GTX file!\n" );
printf( "%c %c %c\n", data[0], data[1], data[2] );
printf( "\n" );
}
free( data );
}
else
{
std::string fullPath = newPath;
fullPath.append( "\\" );
fullPath.append( filename );
FILE* outFP;
outFP = fopen(fullPath.c_str(), "wb" );
if( outFP )
{
void* data = malloc( gelEntry.dataSize );
fseek( gemFP, gelEntry.startOffset, 0 );
fread( data, gelEntry.dataSize, 1, gemFP );
fwrite( data, gelEntry.dataSize, 1, outFP );
free( data );
fclose( outFP );
}
}
}
}
printf( "\n\nProcess Completed\n\n" );
fclose( gemFP );
}
fclose( gelFP );
}
return 0;
}
RoHan Tool from this thread: [Only registered and activated users can see links. Click Here To Register...]
and this quick bms script:
Code:
#quickbms script
#Rohan Gem Extractor
#from chrrox
open FDDE GEM 0
open FDDE GEL 1
get id longlong 1
get files long 1
goto 0x18 1
savepos Tablepos 1
for i = 1 to files
goto Tablepos 1
get FILENUM long 1
get UNKSIZE long 1
getdstring name 0x80 1
get DUMMYSIZE long 1
get offset long 1
get UNK01 long 1
get UNK02 long 1
if i < files
savepos Tablepos 1
savepos temp 1
math temp + 0x8C
goto temp 1
get size long 1
math size - offset
else
get size asize
math size - offset
endif
log name offset size
next i