* speeded up mpq data extraction a LOT.

* added extraction of maps, depending on the data found in Map.dbc.
This commit is contained in:
False.Genesis 2007-05-07 18:46:26 +00:00
parent 54a37a3ff9
commit 95353eb132
5 changed files with 123 additions and 76 deletions

View File

@ -44,6 +44,6 @@ uint32 MPQFile::GetFileSize(char *fn)
void MPQFile::Close(void)
{
if(_isopen)
SFileCloseArchive(_mpq);
FreeMPQArchive((TMPQArchive*&)_mpq);
}

View File

@ -7,32 +7,8 @@
#define DATADIR "Data"
MPQHelper::MPQHelper()
MPQHelper::MPQHelper(char *archive)
{
}
// supply without ".mpq" !!
bool MPQHelper::AssignArchive(char *archive)
{
// 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<MAX_PATCH_NUMBER; i++)
{
char buf[20];
sprintf(buf,DATADIR"/patch-%u.MPQ",i);
if(FileExists(buf))
_patches.push_front(buf);
}
// 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";
@ -63,30 +39,49 @@ bool MPQHelper::AssignArchive(char *archive)
_patches.push_front(buf);
}
_archive = archive;
return FileExists(dir+archive+ext);
for(std::list<std::string>::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));
}
MPQHelper::~MPQHelper()
{
for(std::list<MPQFile*>::iterator it=_files.begin(); it != _files.end(); it++)
{
(*it)->Close();
delete *it;
}
}
ByteBuffer MPQHelper::ExtractFile(char* fn)
{
ByteBuffer bb;
for(std::list<std::string>::iterator i = _patches.begin(); i != _patches.end(); i++)
for(std::list<MPQFile*>::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)
{
printf("MPQE: Using %s from %s\n",fn,_archive.c_str());
bb = arch.ReadFile(fn);
for(std::list<MPQFile*>::iterator i = _files.begin(); i != _files.end(); i++)
{
if((*i)->IsOpen() && (*i)->HasFile(fn) && (*i)->GetFileSize(fn) > 0)
return true;
}
return bb;
return false;
}

View File

@ -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<std::string> _patches; // patch.mpq - patch-9.mpq
std::string _archive;
std::list<MPQFile*> _files;
std::list<std::string> _patches;
};
#endif

View File

@ -7,6 +7,8 @@
#include "DBCFieldData.h"
#include "Locale.h"
std::vector<std::string> 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");
@ -222,3 +223,49 @@ bool ConvertDBC(void)
return true;
}
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);
}

View File

@ -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<std::string> > SCPStorageMap;
int main(int argc, char *argv[]);
void OutSCP(char*, SCPStorageMap&);
bool ConvertDBC(void);
void ExtractMaps(void);
#endif