* fixed extractor: works now with 2.0.x ONLY!

* extractor asks for locale now and creates needed directories itself.
* deleted obsoelete files
This commit is contained in:
False.Genesis 2007-05-02 13:00:44 +00:00
parent 0b36ae85da
commit 6fbcb3cea9
14 changed files with 190 additions and 90 deletions

View File

@ -90,7 +90,7 @@
PreprocessorDefinitions="WIN32" PreprocessorDefinitions="WIN32"
StringPooling="TRUE" StringPooling="TRUE"
ExceptionHandling="FALSE" ExceptionHandling="FALSE"
RuntimeLibrary="4" RuntimeLibrary="0"
BufferSecurityCheck="FALSE" BufferSecurityCheck="FALSE"
EnableFunctionLevelLinking="FALSE" EnableFunctionLevelLinking="FALSE"
EnableEnhancedInstructionSet="0" EnableEnhancedInstructionSet="0"

View File

@ -135,10 +135,10 @@ std::deque<std::string> GetFileList(std::string path)
return files; return files;
} }
bool FileExists(char *fn) bool FileExists(std::string fn)
{ {
std::fstream f; std::fstream f;
f.open(fn,std::ios_base::in); f.open(fn.c_str(),std::ios_base::in);
if (f.is_open()) if (f.is_open())
{ {
f.close(); f.close();
@ -147,4 +147,17 @@ bool FileExists(char *fn)
return false; return false;
} }
bool CreateDir(const char *dir)
{
bool result;
# ifdef _WIN32
result = ::CreateDirectory(dir,NULL);
# else
// NOT tested for Linux!! whats the return value on success?
// TODO: fix me!
result = mkdir(dir);
#endif
return result;
}

View File

@ -16,6 +16,7 @@ std::string getDateString(void);
uint64 toInt(std::string); uint64 toInt(std::string);
std::string toHexDump(uint8* array,uint32 size,bool spaces=true); std::string toHexDump(uint8* array,uint32 size,bool spaces=true);
std::deque<std::string> GetFileList(std::string); std::deque<std::string> GetFileList(std::string);
bool FileExists(char*); bool FileExists(std::string);
bool CreateDir(const char*);
#endif #endif

View File

@ -163,6 +163,12 @@
<File <File
RelativePath=".\stuffextract\dbcfile.h"> RelativePath=".\stuffextract\dbcfile.h">
</File> </File>
<File
RelativePath=".\stuffextract\Locale.cpp">
</File>
<File
RelativePath=".\stuffextract\Locale.h">
</File>
<File <File
RelativePath=".\stuffextract\MPQFile.cpp"> RelativePath=".\stuffextract\MPQFile.cpp">
</File> </File>

View File

@ -1,8 +1,6 @@
#ifndef DBCFIELDDATA_H #ifndef DBCFIELDDATA_H
#define DBCFIELDDATA_H #define DBCFIELDDATA_H
// NOTE: fields checked for 1.12.2 deDE
// defines fields numbers in EmotesText.dbc // defines fields numbers in EmotesText.dbc
// unk fields are always 0, EMOTESTEXT_EMOTE_STRING is string and the rest is uint32. // unk fields are always 0, EMOTESTEXT_EMOTE_STRING is string and the rest is uint32.
enum EmotesTextEnum enum EmotesTextEnum
@ -56,7 +54,15 @@ static const char *EmotesTextFieldNames[] =
enum EmotesTextDataEnum enum EmotesTextDataEnum
{ {
EMOTESTEXTDATA_TEXTID = 0, EMOTESTEXTDATA_TEXTID = 0,
EMOTESTEXTDATA_STRING = 4 EMOTESTEXTDATA_STRING1,
EMOTESTEXTDATA_STRING2,
EMOTESTEXTDATA_STRING3,
EMOTESTEXTDATA_STRING4,
EMOTESTEXTDATA_STRING5,
EMOTESTEXTDATA_STRING6,
EMOTESTEXTDATA_STRING7,
EMOTESTEXTDATA_STRING8,
EMOTESTEXTDATA_UNK,
// rest of the fields is 0 always // rest of the fields is 0 always
}; };
@ -129,30 +135,29 @@ enum ChrRacesEnum
CHRRACES_NAME_SHORT, // 2 chars name abbrev (Hu,Or,Tr, etc) CHRRACES_NAME_SHORT, // 2 chars name abbrev (Hu,Or,Tr, etc)
CHRRACES_UNK_4, CHRRACES_UNK_4,
CHRRACES_FACTION, // 1=Alliance, 7=Horde CHRRACES_FACTION, // 1=Alliance, 7=Horde
CHRRACES_UNK_5, CHRRACES_UNK_5, // always 7?
CHRRACES_UNK_6, CHRRACES_UNK_6, // SpellID? was always 836 in 1.12.x, since 2.0.x its 15007
CHRRACES_UNK_7, CHRRACES_UNK_7,
CHRRACES_UNK_8,
CHRRACES_UNK_9,
CHRRACES_UNK_10,
CHRRACES_NAME_GENERAL, // always the english(?) name (without spaces). used in texture names etc. CHRRACES_NAME_GENERAL, // always the english(?) name (without spaces). used in texture names etc.
CHRRACES_UNK_9,
// the following 8 fields contain either 0 or the race name, depending on the locale.
CHRRACES_NAME1, // english
CHRRACES_NAME2, // <need info here>
CHRRACES_NAME3, // <need info here>
CHRRACES_NAME4, // german
CHRRACES_NAME5, // <need info here>
CHRRACES_NAME6, // <need info here>
CHRRACES_NAME7, // <need info here>
CHRRACES_NAME8, // <need info here>
CHRRACES_UNK_10,
CHRRACES_UNK_11, CHRRACES_UNK_11,
CHRRACES_UNK_12,
CHRRACES_UNK_13,
CHRRACES_UNK_14,
CHRRACES_NAME_LOCAL, // localized(?) name (spanish,german or whatever)
CHRRACES_UNK_15,
CHRRACES_UNK_16,
CHRRACES_UNK_17,
CHRRACES_UNK_18,
CHRRACES_UNK_19, CHRRACES_UNK_19,
CHRRACES_UNK_20, CHRRACES_UNK_20,
CHRRACES_TRAITS, // string that defines the face decorations on char create
CHRRACES_UNK_21, CHRRACES_UNK_21,
CHARRACES_END CHARRACES_END
}; };
static const char *ChrRacesFormat = "ixxxiisxixxxxxxsxxxxsxxxxxxsx"; static const char *ChrRacesFormat = "ixxxiisxixxxsxssssssssxxxxx";
static const char *ChrRacesFieldNames[] = static const char *ChrRacesFieldNames[] =
{ {
@ -168,23 +173,21 @@ static const char *ChrRacesFieldNames[] =
"", "",
"", "",
"", "",
"",
"",
"",
"name_general", "name_general",
"", "",
"", "name",
"", "name",
"", "name",
"name",
"name",
"name",
"name",
"name", "name",
"", "",
"", "",
"", "",
"", "",
"", "",
"",
"traits",
"",
"" ""
}; };

View File

@ -0,0 +1,13 @@
#include "Locale.h"
char *my_locale;
void SetLocale(char *loc)
{
my_locale = loc;
}
char *GetLocale(void)
{
return my_locale;
}

View File

@ -0,0 +1,7 @@
#ifndef STUFFEXTRACT_LOCALE_H
#define STUFFEXTRACT_LOCALE_H
char *GetLocale(void);
void SetLocale(char*);
#endif

View File

@ -7,6 +7,11 @@ MPQFile::MPQFile(const char *fn)
_isopen = SFileOpenArchive(fn,0,0,&_mpq); _isopen = SFileOpenArchive(fn,0,0,&_mpq);
} }
MPQFile::~MPQFile()
{
Close();
}
bool MPQFile::HasFile(char *fn) bool MPQFile::HasFile(char *fn)
{ {
return SFileHasFile(_mpq,fn); return SFileHasFile(_mpq,fn);
@ -22,6 +27,7 @@ ByteBuffer MPQFile::ReadFile(char *fn)
uint32 size = SFileGetFileSize(fh); uint32 size = SFileGetFileSize(fh);
bb.resize(size); bb.resize(size);
SFileReadFile(fh, (void*)bb.contents(), size, NULL, NULL); SFileReadFile(fh, (void*)bb.contents(), size, NULL, NULL);
SFileCloseFile(fh);
return bb; return bb;
} }
@ -34,3 +40,10 @@ uint32 MPQFile::GetFileSize(char *fn)
SFileCloseFile(fh); SFileCloseFile(fh);
return size; return size;
} }
void MPQFile::Close(void)
{
if(_isopen)
SFileCloseArchive(_mpq);
}

View File

@ -10,10 +10,12 @@ class MPQFile
{ {
public: public:
MPQFile(const char*); MPQFile(const char*);
~MPQFile();
inline bool IsOpen(void) { return _isopen; } inline bool IsOpen(void) { return _isopen; }
ByteBuffer ReadFile(char*); ByteBuffer ReadFile(char*);
uint32 GetFileSize(char*); uint32 GetFileSize(char*);
bool HasFile(char*); bool HasFile(char*);
void Close(void);
private: private:
HANDLE _mpq; HANDLE _mpq;

View File

@ -1,28 +1,70 @@
#include <vector>
#include "common.h" #include "common.h"
#include "MPQHelper.h" #include "MPQHelper.h"
#include "MPQFile.h" #include "MPQFile.h"
#include "Locale.h"
#define DATADIR "Data"
MPQHelper::MPQHelper() MPQHelper::MPQHelper()
{ {
} }
bool MPQHelper::AssignArchive(char *fn) // 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. // first, check which patch files are avalible.
// store patches in reversed order, that patch-9.mpq is checked first, and patch.mpq checked last // store patches in reversed order, that patch-9.mpq is checked first, and patch.mpq checked last
if(FileExists("Data/patch.MPQ")) if(FileExists(DATADIR"/patch.MPQ"))
_patches.push_front("Data/patch.MPQ"); _patches.push_front("Data/patch.MPQ");
for(uint32 i=1; i<MAX_PATCH_NUMBER; i++) for(uint32 i=1; i<MAX_PATCH_NUMBER; i++)
{ {
char buf[20]; char buf[20];
sprintf(buf,"patch-%u.MPQ",i); sprintf(buf,DATADIR"/patch-%u.MPQ",i);
if(FileExists(buf)) if(FileExists(buf))
_patches.push_front(buf); _patches.push_front(buf);
} }
// then assign the original archive name // then assign the original archive name
_archive = fn; _archive = archive;
return FileExists(fn); 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 MPQHelper::ExtractFile(char* fn)
@ -31,7 +73,7 @@ ByteBuffer MPQHelper::ExtractFile(char* fn)
for(std::list<std::string>::iterator i = _patches.begin(); i != _patches.end(); i++) for(std::list<std::string>::iterator i = _patches.begin(); i != _patches.end(); i++)
{ {
MPQFile mpq((*i).c_str()); MPQFile mpq((*i).c_str());
if(mpq.IsOpen() && mpq.HasFile(fn)) 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);

View File

@ -5,15 +5,31 @@
#include "dbcfile.h" #include "dbcfile.h"
#include "StuffExtract.h" #include "StuffExtract.h"
#include "DBCFieldData.h" #include "DBCFieldData.h"
#include "Locale.h"
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
printf("StuffExtract [version %u]\n",SE_VERSION); char input[200];
printf("StuffExtract [version %u]\n\n",SE_VERSION);
printf("Enter your locale (enUS, enGB, deDE, ...): ");
fgets(input,sizeof(input),stdin);
char loc[5];
memcpy(loc,input,4); loc[4]=0;
SetLocale(loc);
if(FileExists(std::string("Data/")+GetLocale()+"/locale-"+GetLocale()+".MPQ"))
{
printf("Locale seems valid, starting conversion...\n");
ConvertDBC(); ConvertDBC();
//...
printf("\n -- finished, press enter to exit --\n");
}
else
{
printf("ERROR: Invalid locale! Press Enter to exit...\n");
}
fgets(input,sizeof(input),stdin);
printf("\n -- finished --\n");
char crap[200];
fgets(crap,sizeof(crap),stdin);
//while(true); //while(true);
return 0; return 0;
@ -54,7 +70,6 @@ void OutSCP(char *fn, SCPStorageMap& scp)
} }
} }
bool ConvertDBC(void) bool ConvertDBC(void)
{ {
std::map<uint8,std::string> racemap; // needed to extract other dbc files correctly std::map<uint8,std::string> racemap; // needed to extract other dbc files correctly
@ -62,7 +77,7 @@ bool ConvertDBC(void)
DBCFile EmotesText,EmotesTextData,EmotesTextSound,ChrRaces,SoundEntries; DBCFile EmotesText,EmotesTextData,EmotesTextSound,ChrRaces,SoundEntries;
printf("Opening DBC archive...\n"); printf("Opening DBC archive...\n");
MPQHelper mpq; MPQHelper mpq;
if(!mpq.AssignArchive("Data/dbc.MPQ")) if(!mpq.AssignArchive("dbc"))
{ {
printf("ConvertDBC: Could not open 'Data/dbc.MPQ'\n"); printf("ConvertDBC: Could not open 'Data/dbc.MPQ'\n");
return false; return false;
@ -86,6 +101,7 @@ bool ConvertDBC(void)
if(strlen(ChrRacesFieldNames[field])) if(strlen(ChrRacesFieldNames[field]))
{ {
std::string value = AutoGetDataString(it,ChrRacesFormat,field); std::string value = AutoGetDataString(it,ChrRacesFormat,field);
if(!value.empty())
RaceDataStorage[id].push_back(std::string(ChrRacesFieldNames[field]).append("=").append(value)); RaceDataStorage[id].push_back(std::string(ChrRacesFieldNames[field]).append("=").append(value));
} }
} }
@ -109,11 +125,17 @@ bool ConvertDBC(void)
if(textid == (*it).getInt(field)) if(textid == (*it).getInt(field))
{ {
fname = EmotesTextFieldNames[field]; fname = EmotesTextFieldNames[field];
EmoteDataStorage[em].push_back( fname + "=" + (*ix).getString(EMOTESTEXTDATA_STRING) ); for(uint8 stringpos=EMOTESTEXTDATA_STRING1; stringpos<=EMOTESTEXTDATA_STRING8; stringpos++) // we have 8 locales, so...
{
if((*ix).getInt(stringpos)) // find out which field is used, 0 if not used
{
EmoteDataStorage[em].push_back( fname + "=" + (*ix).getString(stringpos) );
break;
}
}
break; break;
} }
} }
} }
} }
for(DBCFile::Iterator is = EmotesTextSound.begin(); is != EmotesTextSound.end(); ++is) for(DBCFile::Iterator is = EmotesTextSound.begin(); is != EmotesTextSound.end(); ++is)
@ -148,6 +170,9 @@ bool ConvertDBC(void)
//... //...
printf("DONE!\n"); printf("DONE!\n");
//... //...
CreateDir("stuffextract");
CreateDir("stuffextract/scp");
printf("Writing SCP files:\n"); printf("Writing SCP files:\n");
printf("emote.."); OutSCP(SCPDIR "/emote.scp",EmoteDataStorage); printf("emote.."); OutSCP(SCPDIR "/emote.scp",EmoteDataStorage);
printf("race.."); OutSCP(SCPDIR "/race.scp",RaceDataStorage); printf("race.."); OutSCP(SCPDIR "/race.scp",RaceDataStorage);
@ -155,9 +180,8 @@ bool ConvertDBC(void)
//... //...
printf("DONE!\n"); printf("DONE!\n");
// wait for all container destructors to finish
printf("DBC files converted, cleaning up...\n");
return true; return true;
} }

View File

@ -59,6 +59,11 @@ bool DBCFile::open()
bool DBCFile::openmem(ByteBuffer bb) bool DBCFile::openmem(ByteBuffer bb)
{ {
if(bb.size() < 4+4+4+4+4)
{
printf("DBCFile::openmem(): ByteBuffer too small!");
return false;
}
uint32 hdr; uint32 hdr;
bb >> hdr; bb >> hdr;

View File

@ -1,25 +0,0 @@
#Coders:
False.Genesis (project starter)
Mini
#Testers:
=========
Project-Eden crew: Leito, Michel [Milk Addict], ©haos, Orochi, SoulReaper
#Special thanks to:
===================
©haos for the neat icon and many hours that passed by while discussing
about PseuWoW related stuff.
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
Want to be named here? Then do something for the Project!

View File

@ -1,4 +0,0 @@
realm login:
- use the correct IP in CLIENT_LOGON_CHALLENGE, and not 127.0.0.1
- use correct timezone, maybe settable via conf file later on
- define the crc_hash as it should be