diff --git a/src/tools/stuffextract/MPQFile.cpp b/src/tools/stuffextract/MPQFile.cpp index a79b653..43c52e8 100644 --- a/src/tools/stuffextract/MPQFile.cpp +++ b/src/tools/stuffextract/MPQFile.cpp @@ -44,6 +44,6 @@ uint32 MPQFile::GetFileSize(char *fn) void MPQFile::Close(void) { if(_isopen) - SFileCloseArchive(_mpq); + FreeMPQArchive((TMPQArchive*&)_mpq); } diff --git a/src/tools/stuffextract/MPQHelper.cpp b/src/tools/stuffextract/MPQHelper.cpp index 0f35f95..1f6cef0 100644 --- a/src/tools/stuffextract/MPQHelper.cpp +++ b/src/tools/stuffextract/MPQHelper.cpp @@ -7,86 +7,81 @@ #define DATADIR "Data" -MPQHelper::MPQHelper() +MPQHelper::MPQHelper(char *archive) { + // TODO: check which files are needed and which are not + recheck for correct ordering + std::string dir = "Data/"; + std::string ext = ".MPQ"; + std::string ldir = dir + GetLocale() + "/"; + + // order goes from last opened to first opened file + // ok maybe this is a bit too much but should work fine :) + _patches.push_front(dir+"common"+ext); + _patches.push_front(dir+"expansion"+ext); + for(uint32 i=1; i<=MAX_PATCH_NUMBER; i++) + { + char buf[200]; + sprintf(buf,"%spatch-%u%s",dir.c_str(),i,ext.c_str()); + _patches.push_front(buf); + } + _patches.push_front(dir+"patch"+ext); + _patches.push_front(ldir+archive+"-"+GetLocale()+ext); + _patches.push_front(ldir+"locale-"+GetLocale()+ext); + _patches.push_front(ldir+"expansion-locale-"+GetLocale()+ext); + _patches.push_front(ldir+"expansion-"+archive+"-"+GetLocale()+ext); + + _patches.push_front(ldir+"patch"+"-"+GetLocale()+ext); + for(uint32 i=1; i<=MAX_PATCH_NUMBER; i++) + { + char buf[200]; + sprintf(buf,"%spatch-%s-%u%s",ldir.c_str(),GetLocale(),i,ext.c_str()); + //if(FileExists(buf)) + _patches.push_front(buf); + } + + for(std::list::iterator it=_patches.begin(); it != _patches.end(); it++) + { + if(::FileExists(*it)) + { + _files.push_back(new MPQFile((*it).c_str())); + } + } + _files.push_back(new MPQFile(archive)); } -// supply without ".mpq" !! -bool MPQHelper::AssignArchive(char *archive) +MPQHelper::~MPQHelper() { - // old code for 1.12.x and below archives order - /* - // first, check which patch files are avalible. - // store patches in reversed order, that patch-9.mpq is checked first, and patch.mpq checked last - if(FileExists(DATADIR"/patch.MPQ")) - _patches.push_front("Data/patch.MPQ"); - for(uint32 i=1; i::iterator it=_files.begin(); it != _files.end(); it++) { - char buf[20]; - sprintf(buf,DATADIR"/patch-%u.MPQ",i); - if(FileExists(buf)) - _patches.push_front(buf); + (*it)->Close(); + delete *it; } - // then assign the original archive name - _archive = archive; - return FileExists(archive); - */ - - // new code for 2.0.x and above - // TODO: check which files are needed and which are not + recheck for correct ordering - std::string dir = "Data/"; - std::string ext = ".MPQ"; - std::string ldir = dir + GetLocale() + "/"; - - // order goes from last opened to first opened file - // ok maybe this is a bit too much but should work fine :) - _patches.push_front(dir+"common"+ext); - _patches.push_front(dir+"expansion"+ext); - for(uint32 i=1; i<=MAX_PATCH_NUMBER; i++) - { - char buf[200]; - sprintf(buf,"%spatch-%u%s",dir.c_str(),i,ext.c_str()); - _patches.push_front(buf); - } - _patches.push_front(dir+"patch"+ext); - _patches.push_front(ldir+archive+"-"+GetLocale()+ext); - _patches.push_front(ldir+"locale-"+GetLocale()+ext); - _patches.push_front(ldir+"expansion-locale-"+GetLocale()+ext); - _patches.push_front(ldir+"expansion-"+archive+"-"+GetLocale()+ext); - - _patches.push_front(ldir+"patch"+"-"+GetLocale()+ext); - for(uint32 i=1; i<=MAX_PATCH_NUMBER; i++) - { - char buf[200]; - sprintf(buf,"%spatch-%s-%u%s",ldir.c_str(),GetLocale(),i,ext.c_str()); - //if(FileExists(buf)) - _patches.push_front(buf); - } - - _archive = archive; - return FileExists(dir+archive+ext); } ByteBuffer MPQHelper::ExtractFile(char* fn) { ByteBuffer bb; - for(std::list::iterator i = _patches.begin(); i != _patches.end(); i++) + for(std::list::iterator i = _files.begin(); i != _files.end(); i++) { - MPQFile mpq((*i).c_str()); - if(mpq.IsOpen() && mpq.HasFile(fn) && mpq.GetFileSize(fn) > 0) + MPQFile *mpq = *i; + if(mpq->IsOpen() && mpq->HasFile(fn) && mpq->GetFileSize(fn) > 0) { - printf("MPQE: Using %s from %s\n",fn,i->c_str()); - bb = mpq.ReadFile(fn); + // printf("MPQE: Using %s from %s\n",fn,i->c_str()); + bb = mpq->ReadFile(fn); return bb; } } - MPQFile arch(_archive.c_str()); - if(arch.IsOpen() && arch.HasFile(fn)) + return bb; // will be empty if returned here +} + +bool MPQHelper::FileExists(char *fn) +{ + for(std::list::iterator i = _files.begin(); i != _files.end(); i++) { - printf("MPQE: Using %s from %s\n",fn,_archive.c_str()); - bb = arch.ReadFile(fn); + if((*i)->IsOpen() && (*i)->HasFile(fn) && (*i)->GetFileSize(fn) > 0) + return true; } - return bb; + return false; } diff --git a/src/tools/stuffextract/MPQHelper.h b/src/tools/stuffextract/MPQHelper.h index bb86221..e6b3155 100644 --- a/src/tools/stuffextract/MPQHelper.h +++ b/src/tools/stuffextract/MPQHelper.h @@ -3,15 +3,18 @@ #define MAX_PATCH_NUMBER 9 +class MPQFile; + class MPQHelper { public: - MPQHelper(); - bool AssignArchive(char*); + MPQHelper(char*); + ~MPQHelper(); ByteBuffer ExtractFile(char*); + bool FileExists(char*); private: - std::list _patches; // patch.mpq - patch-9.mpq - std::string _archive; + std::list _files; + std::list _patches; }; #endif \ No newline at end of file diff --git a/src/tools/stuffextract/StuffExtract.cpp b/src/tools/stuffextract/StuffExtract.cpp index 07ff11b..79c782c 100644 --- a/src/tools/stuffextract/StuffExtract.cpp +++ b/src/tools/stuffextract/StuffExtract.cpp @@ -7,6 +7,8 @@ #include "DBCFieldData.h" #include "Locale.h" +std::vector mapNames; + int main(int argc, char *argv[]) { @@ -20,7 +22,10 @@ int main(int argc, char *argv[]) if(FileExists(std::string("Data/")+GetLocale()+"/locale-"+GetLocale()+".MPQ")) { printf("Locale seems valid, starting conversion...\n"); + CreateDir("stuffextract"); + CreateDir("stuffextract/data"); ConvertDBC(); + ExtractMaps(); //... printf("\n -- finished, press enter to exit --\n"); } @@ -76,12 +81,8 @@ bool ConvertDBC(void) SCPStorageMap EmoteDataStorage,RaceDataStorage,SoundDataStorage,MapDataStorage,AreaDataStorage; // will store the converted data from dbc files DBCFile EmotesText,EmotesTextData,EmotesTextSound,ChrRaces,SoundEntries,Map,AreaTable; printf("Opening DBC archive...\n"); - MPQHelper mpq; - if(!mpq.AssignArchive("dbc")) - { - printf("ConvertDBC: Could not open 'Data/dbc.MPQ'\n"); - return false; - } + MPQHelper mpq("dbc"); + printf("Opening DBC files...\n"); EmotesText.openmem(mpq.ExtractFile("DBFilesClient\\EmotesText.dbc")); EmotesTextData.openmem(mpq.ExtractFile("DBFilesClient\\EmotesTextData.dbc")); @@ -172,6 +173,7 @@ bool ConvertDBC(void) printf("map info.."); for(DBCFile::Iterator it = Map.begin(); it != Map.end(); ++it) { + mapNames.push_back(it->getString(MAP_NAME_GENERAL)); uint32 id = it->getUInt(MAP_ID); for(uint32 field=MAP_ID; field < MAP_END; field++) { @@ -204,8 +206,7 @@ bool ConvertDBC(void) //... printf("DONE!\n"); //... - CreateDir("stuffextract"); - CreateDir("stuffextract/data"); + CreateDir("stuffextract/data/scp"); printf("Writing SCP files:\n"); @@ -221,4 +222,50 @@ bool ConvertDBC(void) printf("DBC files converted, cleaning up...\n"); return true; -} \ No newline at end of file +} + +void ExtractMaps(void) +{ + printf("\nExtracting maps...\n"); + char namebuf[200]; + char outbuf[2000]; + uint32 extr,extrtotal=0; + MPQHelper mpq("terrain"); + CreateDir("stuffextract/data/maps"); + for(uint32 it=0; it < mapNames.size(); it++) + { + extr=0; + for(uint32 x=0; x<64; x++) + { + for(uint32 y=0;y<64; y++) + { + sprintf(namebuf,"World\\Maps\\%s\\%s_%u_%u.adt",mapNames[it].c_str(),mapNames[it].c_str(),x,y); + sprintf(outbuf,MAPSDIR"/%s_%u_%u.adt",mapNames[it].c_str(),x,y); + if(mpq.FileExists(namebuf)) + { + ByteBuffer& bb = mpq.ExtractFile(namebuf); + if(bb.size()) + { + std::fstream fh; + //printf("Extracting map [ %s ]\n",outbuf); + fh.open(outbuf, std::ios_base::out|std::ios_base::binary); + if(!fh.is_open()) + { + printf("\nERROR: Map extraction failed: could not save file %s\n",outbuf); + return; + } + fh.write((char*)bb.contents(),bb.size()); + fh.close(); + extr++; + printf("Map [%u/%u]: %s: %u\r",it+1,mapNames.size(),mapNames[it].c_str(),extr); + } + } + + } + } + extrtotal+=extr; + printf("\n"); + } + + printf("\nDONE - %u maps extracted.\n",extrtotal); +} diff --git a/src/tools/stuffextract/StuffExtract.h b/src/tools/stuffextract/StuffExtract.h index dc92952..5092b09 100644 --- a/src/tools/stuffextract/StuffExtract.h +++ b/src/tools/stuffextract/StuffExtract.h @@ -8,12 +8,14 @@ #define MAPS_VERSION ((uint32)0) #define OUTDIR "stuffextract" #define SCPDIR OUTDIR "/data/scp" +#define MAPSDIR OUTDIR "/data/maps" typedef std::map< uint32,std::list > SCPStorageMap; int main(int argc, char *argv[]); void OutSCP(char*, SCPStorageMap&); bool ConvertDBC(void); +void ExtractMaps(void); #endif \ No newline at end of file