* speeded up mpq data extraction a LOT.
* added extraction of maps, depending on the data found in Map.dbc.
This commit is contained in:
parent
54a37a3ff9
commit
95353eb132
@ -44,6 +44,6 @@ uint32 MPQFile::GetFileSize(char *fn)
|
|||||||
void MPQFile::Close(void)
|
void MPQFile::Close(void)
|
||||||
{
|
{
|
||||||
if(_isopen)
|
if(_isopen)
|
||||||
SFileCloseArchive(_mpq);
|
FreeMPQArchive((TMPQArchive*&)_mpq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -7,32 +7,8 @@
|
|||||||
#define DATADIR "Data"
|
#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
|
// TODO: check which files are needed and which are not + recheck for correct ordering
|
||||||
std::string dir = "Data/";
|
std::string dir = "Data/";
|
||||||
std::string ext = ".MPQ";
|
std::string ext = ".MPQ";
|
||||||
@ -63,30 +39,49 @@ bool MPQHelper::AssignArchive(char *archive)
|
|||||||
_patches.push_front(buf);
|
_patches.push_front(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
_archive = archive;
|
for(std::list<std::string>::iterator it=_patches.begin(); it != _patches.end(); it++)
|
||||||
return FileExists(dir+archive+ext);
|
{
|
||||||
|
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 MPQHelper::ExtractFile(char* fn)
|
||||||
{
|
{
|
||||||
ByteBuffer bb;
|
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());
|
MPQFile *mpq = *i;
|
||||||
if(mpq.IsOpen() && mpq.HasFile(fn) && mpq.GetFileSize(fn) > 0)
|
if(mpq->IsOpen() && mpq->HasFile(fn) && mpq->GetFileSize(fn) > 0)
|
||||||
{
|
{
|
||||||
printf("MPQE: Using %s from %s\n",fn,i->c_str());
|
// printf("MPQE: Using %s from %s\n",fn,i->c_str());
|
||||||
bb = mpq.ReadFile(fn);
|
bb = mpq->ReadFile(fn);
|
||||||
return bb;
|
return bb;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MPQFile arch(_archive.c_str());
|
return bb; // will be empty if returned here
|
||||||
if(arch.IsOpen() && arch.HasFile(fn))
|
}
|
||||||
|
|
||||||
|
bool MPQHelper::FileExists(char *fn)
|
||||||
{
|
{
|
||||||
printf("MPQE: Using %s from %s\n",fn,_archive.c_str());
|
for(std::list<MPQFile*>::iterator i = _files.begin(); i != _files.end(); i++)
|
||||||
bb = arch.ReadFile(fn);
|
{
|
||||||
|
if((*i)->IsOpen() && (*i)->HasFile(fn) && (*i)->GetFileSize(fn) > 0)
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return bb;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -3,15 +3,18 @@
|
|||||||
|
|
||||||
#define MAX_PATCH_NUMBER 9
|
#define MAX_PATCH_NUMBER 9
|
||||||
|
|
||||||
|
class MPQFile;
|
||||||
|
|
||||||
class MPQHelper
|
class MPQHelper
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MPQHelper();
|
MPQHelper(char*);
|
||||||
bool AssignArchive(char*);
|
~MPQHelper();
|
||||||
ByteBuffer ExtractFile(char*);
|
ByteBuffer ExtractFile(char*);
|
||||||
|
bool FileExists(char*);
|
||||||
private:
|
private:
|
||||||
std::list<std::string> _patches; // patch.mpq - patch-9.mpq
|
std::list<MPQFile*> _files;
|
||||||
std::string _archive;
|
std::list<std::string> _patches;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -7,6 +7,8 @@
|
|||||||
#include "DBCFieldData.h"
|
#include "DBCFieldData.h"
|
||||||
#include "Locale.h"
|
#include "Locale.h"
|
||||||
|
|
||||||
|
std::vector<std::string> mapNames;
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
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"))
|
if(FileExists(std::string("Data/")+GetLocale()+"/locale-"+GetLocale()+".MPQ"))
|
||||||
{
|
{
|
||||||
printf("Locale seems valid, starting conversion...\n");
|
printf("Locale seems valid, starting conversion...\n");
|
||||||
|
CreateDir("stuffextract");
|
||||||
|
CreateDir("stuffextract/data");
|
||||||
ConvertDBC();
|
ConvertDBC();
|
||||||
|
ExtractMaps();
|
||||||
//...
|
//...
|
||||||
printf("\n -- finished, press enter to exit --\n");
|
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
|
SCPStorageMap EmoteDataStorage,RaceDataStorage,SoundDataStorage,MapDataStorage,AreaDataStorage; // will store the converted data from dbc files
|
||||||
DBCFile EmotesText,EmotesTextData,EmotesTextSound,ChrRaces,SoundEntries,Map,AreaTable;
|
DBCFile EmotesText,EmotesTextData,EmotesTextSound,ChrRaces,SoundEntries,Map,AreaTable;
|
||||||
printf("Opening DBC archive...\n");
|
printf("Opening DBC archive...\n");
|
||||||
MPQHelper mpq;
|
MPQHelper mpq("dbc");
|
||||||
if(!mpq.AssignArchive("dbc"))
|
|
||||||
{
|
|
||||||
printf("ConvertDBC: Could not open 'Data/dbc.MPQ'\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
printf("Opening DBC files...\n");
|
printf("Opening DBC files...\n");
|
||||||
EmotesText.openmem(mpq.ExtractFile("DBFilesClient\\EmotesText.dbc"));
|
EmotesText.openmem(mpq.ExtractFile("DBFilesClient\\EmotesText.dbc"));
|
||||||
EmotesTextData.openmem(mpq.ExtractFile("DBFilesClient\\EmotesTextData.dbc"));
|
EmotesTextData.openmem(mpq.ExtractFile("DBFilesClient\\EmotesTextData.dbc"));
|
||||||
@ -172,6 +173,7 @@ bool ConvertDBC(void)
|
|||||||
printf("map info..");
|
printf("map info..");
|
||||||
for(DBCFile::Iterator it = Map.begin(); it != Map.end(); ++it)
|
for(DBCFile::Iterator it = Map.begin(); it != Map.end(); ++it)
|
||||||
{
|
{
|
||||||
|
mapNames.push_back(it->getString(MAP_NAME_GENERAL));
|
||||||
uint32 id = it->getUInt(MAP_ID);
|
uint32 id = it->getUInt(MAP_ID);
|
||||||
for(uint32 field=MAP_ID; field < MAP_END; field++)
|
for(uint32 field=MAP_ID; field < MAP_END; field++)
|
||||||
{
|
{
|
||||||
@ -204,8 +206,7 @@ bool ConvertDBC(void)
|
|||||||
//...
|
//...
|
||||||
printf("DONE!\n");
|
printf("DONE!\n");
|
||||||
//...
|
//...
|
||||||
CreateDir("stuffextract");
|
|
||||||
CreateDir("stuffextract/data");
|
|
||||||
CreateDir("stuffextract/data/scp");
|
CreateDir("stuffextract/data/scp");
|
||||||
|
|
||||||
printf("Writing SCP files:\n");
|
printf("Writing SCP files:\n");
|
||||||
@ -222,3 +223,49 @@ bool ConvertDBC(void)
|
|||||||
|
|
||||||
return true;
|
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);
|
||||||
|
}
|
||||||
|
|||||||
@ -8,12 +8,14 @@
|
|||||||
#define MAPS_VERSION ((uint32)0)
|
#define MAPS_VERSION ((uint32)0)
|
||||||
#define OUTDIR "stuffextract"
|
#define OUTDIR "stuffextract"
|
||||||
#define SCPDIR OUTDIR "/data/scp"
|
#define SCPDIR OUTDIR "/data/scp"
|
||||||
|
#define MAPSDIR OUTDIR "/data/maps"
|
||||||
|
|
||||||
typedef std::map< uint32,std::list<std::string> > SCPStorageMap;
|
typedef std::map< uint32,std::list<std::string> > SCPStorageMap;
|
||||||
|
|
||||||
int main(int argc, char *argv[]);
|
int main(int argc, char *argv[]);
|
||||||
void OutSCP(char*, SCPStorageMap&);
|
void OutSCP(char*, SCPStorageMap&);
|
||||||
bool ConvertDBC(void);
|
bool ConvertDBC(void);
|
||||||
|
void ExtractMaps(void);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
Loading…
x
Reference in New Issue
Block a user