Code: Select all
<?php
/*
* Concept DDS GEO Header Remover Source Release
* Coming Soon PHP GEL GEM FILE EXTRACTOR
* No License, Make this as your own
*/
$filename = "./item/07_bro_1.dds"; //file to read
$contents = file_get_contents($filename); //read as string
//echo strlen($contents); //Count no. of strings
echo substr($contents,3,strlen($contents)); //Removed GEO / DDS Header
$modS = substr($contents,3,strlen($contents)); // Same but is placed inside a variable
$file = fopen("./converted/test.tga","wb"); //Write to new name inside an exisiting folder
fwrite($file,$modS,filesize($filename)); //Write File
?>
Thanks to spintz for showing the source of the extractor. If your having a hard time to compile spintz's source then use this source instead.
GNU C++ compiler compatible, (Windows only, because of CreateDirectory and windows.h)
Code: Select all
#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 = "C:\\Program Files\\Level Up Games\\Rohan Online CBT\\Client\\res\\bitmaps.gel";
// Set this to the .GEM file that matches the .GEL file you want to extract
std::string srcGem = "C:\\Program Files\\Level Up Games\\Rohan Online CBT\\Client\\res\\bitmaps.gem";
// This is the path where all the files will be extracted to
std::string destPath = "C:\\Users\\Loki\\Downloads\\Modder\\bitmaps\\";
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;
}
I think this can be done by using string manipulation in php, because c++ reads the stream the same way as php but in different method.