mirror of
https://github.com/mangosfour/server.git
synced 2025-12-12 19:37:03 +00:00
[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:
parent
10de01c6f7
commit
83bd854030
4 changed files with 158 additions and 14 deletions
|
|
@ -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.
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef __REVISION_NR_H__
|
||||
#define __REVISION_NR_H__
|
||||
#define REVISION_NR "9169"
|
||||
#define REVISION_NR "9170"
|
||||
#endif // __REVISION_NR_H__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue