[9170] Impleament DBCs build check at server startup.

* Extractor now include in extarcted DBC dir data file with build info.
* Mangosd use this data for check at startup for main DBC dir and DBC local subdirs intergrity.
* Also updates DBC checks for raw data.

NOTE: You need reextract DBC data by _new_ extractor for correct work mangosd.
This commit is contained in:
VladimirMangos 2010-01-13 11:33:22 +03:00
parent 10de01c6f7
commit 83bd854030
4 changed files with 158 additions and 14 deletions

View file

@ -166,6 +166,43 @@ void HandleArgs(int argc, char * arg[])
}
}
uint32 ReadBuild(int locale)
{
// include build info file also
std::string filename = std::string("component.wow-")+langs[locale]+".txt";
//printf("Read %s file... ", filename.c_str());
MPQFile m(filename.c_str());
if(m.isEof())
{
printf("Fatal error: Not found %s file!\n", filename.c_str());
exit(1);
}
std::string text = m.getPointer();
m.close();
size_t pos = text.find("version=\"");
size_t pos1 = pos + strlen("version=\"");
size_t pos2 = text.find("\"",pos1);
if (pos == text.npos || pos2 == text.npos || pos1 >= pos2)
{
printf("Fatal error: Invalid %s file format!\n", filename.c_str());
exit(1);
}
std::string build_str = text.substr(pos1,pos2-pos1);
int build = atoi(build_str.c_str());
if (build <= 0)
{
printf("Fatal error: Invalid %s file format!\n", filename.c_str());
exit(1);
}
return build;
}
uint32 ReadMapDBC()
{
printf("Read Map.dbc file... ");
@ -920,6 +957,14 @@ void ExtractDBCFiles(int locale, bool basicLocale)
CreateDir(path);
}
// extract Build info file
{
string mpq_name = std::string("component.wow-") + langs[locale] + ".txt";
string filename = path + mpq_name;
ExtractFile(mpq_name.c_str(), filename);
}
// extract DBCs
int count = 0;
for (set<string>::iterator iter = dbcfiles.begin(); iter != dbcfiles.end(); ++iter)
@ -978,6 +1023,7 @@ int main(int argc, char * arg[])
HandleArgs(argc, arg);
int FirstLocale = -1;
uint32 build = 0;
for (int i = 0; i < LANG_COUNT; i++)
{
@ -993,6 +1039,8 @@ int main(int argc, char * arg[])
if((CONF_extract & EXTRACT_DBC) == 0)
{
FirstLocale = i;
build = ReadBuild(FirstLocale);
printf("Detected client build: %u\n", build);
break;
}
@ -1000,6 +1048,8 @@ int main(int argc, char * arg[])
if(FirstLocale < 0)
{
FirstLocale = i;
build = ReadBuild(FirstLocale);
printf("Detected client build: %u\n", build);
ExtractDBCFiles(i, true);
}
else

Binary file not shown.

View file

@ -178,6 +178,55 @@ std::string AcceptableClientBuildsListStr()
return data.str();
}
static bool ReadDBCBuildFileText(const std::string& dbc_path, char const* localeName, std::string& text)
{
std::string filename = dbc_path + "component.wow-" + localeName + ".txt";
if(FILE* file = fopen(filename.c_str(),"rb"))
{
char buf[100];
fread(buf,1,100-1,file);
fclose(file);
text = &buf[0];
fclose(file);
return true;
}
else
return false;
}
static uint32 ReadDBCBuild(const std::string& dbc_path, char const* localeName = NULL)
{
std::string text;
if (!localeName)
{
for(LocaleNameStr* itr = &fullLocaleNameList[0]; itr->name; ++itr)
if (ReadDBCBuildFileText(dbc_path,itr->name,text))
break;
}
else
ReadDBCBuildFileText(dbc_path,localeName,text);
if (text.empty())
return 0;
size_t pos = text.find("version=\"");
size_t pos1 = pos + strlen("version=\"");
size_t pos2 = text.find("\"",pos1);
if (pos == text.npos || pos2 == text.npos || pos1 >= pos2)
return 0;
std::string build_str = text.substr(pos1,pos2-pos1);
int build = atoi(build_str.c_str());
if (build <= 0)
return 0;
return build;
}
static bool LoadDBC_assert_print(uint32 fsize,uint32 rsize, const std::string& filename)
{
sLog.outError("ERROR: Size of '%s' setted by format string (%u) not equal size of C++ structure (%u).",filename.c_str(),fsize,rsize);
@ -186,8 +235,18 @@ static bool LoadDBC_assert_print(uint32 fsize,uint32 rsize, const std::string& f
return false;
}
struct LocalData
{
explicit LocalData(uint32 build) : main_build(build), availableDbcLocales(0xFFFFFFFF),checkedDbcLocaleBuilds(0) {}
uint32 main_build;
// bitmasks for index of fullLocaleNameList
uint32 availableDbcLocales;
uint32 checkedDbcLocaleBuilds;
};
template<class T>
inline void LoadDBC(uint32& availableDbcLocales,barGoLink& bar, StoreProblemList& errlist, DBCStorage<T>& storage, const std::string& dbc_path, const std::string& filename)
inline void LoadDBC(LocalData& localeData,barGoLink& bar, StoreProblemList& errlist, DBCStorage<T>& storage, const std::string& dbc_path, const std::string& filename)
{
// compatibility format and C++ structure sizes
assert(DBCFileLoader::GetFormatRecordSize(storage.GetFormat()) == sizeof(T) || LoadDBC_assert_print(DBCFileLoader::GetFormatRecordSize(storage.GetFormat()),sizeof(T),filename));
@ -198,12 +257,36 @@ inline void LoadDBC(uint32& availableDbcLocales,barGoLink& bar, StoreProblemList
bar.step();
for(uint8 i = 0; fullLocaleNameList[i].name; ++i)
{
if(!(availableDbcLocales & (1 << i)))
if (!(localeData.availableDbcLocales & (1 << i)))
continue;
std::string dbc_dir_loc = dbc_path + fullLocaleNameList[i].name + "/";
if (!(localeData.checkedDbcLocaleBuilds & (1 << i)))
{
localeData.checkedDbcLocaleBuilds |= (1<<i);// mark as checked for speedup next checks
uint32 build_loc = ReadDBCBuild(dbc_dir_loc,fullLocaleNameList[i].name);
if(localeData.main_build != build_loc)
{
localeData.availableDbcLocales &= ~(1<<i); // mark as not available for speedup next checks
// exist but wrong build
if (build_loc)
{
std::string dbc_filename_loc = dbc_path + fullLocaleNameList[i].name + "/" + filename;
char buf[200];
snprintf(buf,200," (exist, but DBC locale subdir %s have DBCs for build %u instead expected build %u, it and other DBC from subdir skipped)",fullLocaleNameList[i].name,build_loc,localeData.main_build);
errlist.push_back(dbc_filename_loc + buf);
}
continue;
}
}
std::string dbc_filename_loc = dbc_path + fullLocaleNameList[i].name + "/" + filename;
if(!storage.LoadStringsFrom(dbc_filename_loc.c_str()))
availableDbcLocales &= ~(1<<i); // mark as not available for speedup next checks
localeData.availableDbcLocales &= ~(1<<i); // mark as not available for speedup next checks
}
}
else
@ -226,14 +309,25 @@ void LoadDBCStores(const std::string& dataPath)
{
std::string dbcPath = dataPath+"dbc/";
uint32 build = ReadDBCBuild(dbcPath);
// Check the expected DBC version
if (!IsAcceptableClientBuild(build))
{
if (build)
sLog.outError("Found DBC files for build %u but mangosd expected DBC for one from builds: %s Please extract correct DBC files.", build, AcceptableClientBuildsListStr().c_str());
else
sLog.outError("Incorrect DataDir value in mangosd.conf or not found build info (outdated DBC files). Required one from builds: %s Please extract correct DBC files.",AcceptableClientBuildsListStr().c_str());
exit(1);
}
const uint32 DBCFilesCount = 82;
barGoLink bar( DBCFilesCount );
StoreProblemList bad_dbc_files;
// bitmask for index of fullLocaleNameList
uint32 availableDbcLocales = 0xFFFFFFFF;
LocalData availableDbcLocales(build);
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAreaStore, dbcPath,"AreaTable.dbc");
@ -524,15 +618,15 @@ void LoadDBCStores(const std::string& dataPath)
}
// Check loaded DBC files proper version
if( !sSpellStore.LookupEntry(66530) || // last added spell in 3.1.3
!sMapStore.LookupEntry(624) || // last map added in 3.1.3
!sGemPropertiesStore.LookupEntry(1609) || // last gem property added in 3.1.3
!sItemExtendedCostStore.LookupEntry(2671) || // last item extended cost added in 3.1.3
!sCharTitlesStore.LookupEntry(166) || // last char title added in 3.1.3
!sAreaStore.LookupEntry(2905) || // last area (areaflag) added in 3.1.3
!sItemStore.LookupEntry(46894) ) // last client known item added in 3.1.3
if( !sSpellStore.LookupEntry(73190) || // last added spell in 3.3.0a
!sMapStore.LookupEntry(718) || // last map added in 3.3.0a
!sGemPropertiesStore.LookupEntry(1629) || // last gem property added in 3.3.0a
!sItemExtendedCostStore.LookupEntry(2935) || // last item extended cost added in 3.3.0a
!sCharTitlesStore.LookupEntry(177) || // last char title added in 3.3.0a
!sAreaStore.LookupEntry(3460) || // last area (areaflag) added in 3.3.0a
!sItemStore.LookupEntry(52062) ) // last client known item added in 3.3.0a
{
sLog.outError("\nYou have _outdated_ DBC files. Please re-extract DBC files for one from client build: %s",AcceptableClientBuildsListStr().c_str());
sLog.outError("\nYou have mixed version DBC files. Please re-extract DBC files for one from client build: %s",AcceptableClientBuildsListStr().c_str());
exit(1);
}

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "9169"
#define REVISION_NR "9170"
#endif // __REVISION_NR_H__