diff --git a/contrib/extractor/System.cpp b/contrib/extractor/System.cpp index 1aa1145d4..11a47baa2 100644 --- a/contrib/extractor/System.cpp +++ b/contrib/extractor/System.cpp @@ -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::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 diff --git a/contrib/extractor/ad.exe b/contrib/extractor/ad.exe index 97a8fde49..105f3819b 100755 Binary files a/contrib/extractor/ad.exe and b/contrib/extractor/ad.exe differ diff --git a/src/game/DBCStores.cpp b/src/game/DBCStores.cpp index 36f0efe2b..ce4d88c3c 100644 --- a/src/game/DBCStores.cpp +++ b/src/game/DBCStores.cpp @@ -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 -inline void LoadDBC(uint32& availableDbcLocales,barGoLink& bar, StoreProblemList& errlist, DBCStorage& storage, const std::string& dbc_path, const std::string& filename) +inline void LoadDBC(LocalData& localeData,barGoLink& bar, StoreProblemList& errlist, DBCStorage& 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<