diff options
| author | Shauren <shauren.trinity@gmail.com> | 2020-07-01 00:34:51 +0200 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2020-07-01 00:34:51 +0200 |
| commit | 4499f203a3ee9d6567b2af9011ee9e4378de0eab (patch) | |
| tree | e2a2b2f58794edaa41886bc3ffb201a4f8c66361 /src/server/game | |
| parent | 587bf750f74245f0f7bb3b88dc599738eacb0226 (diff) | |
Core/DataStores: Fixed sending localized hotfixes and improved db2 loading error messages
Diffstat (limited to 'src/server/game')
| -rw-r--r-- | src/server/game/DataStores/DB2Stores.cpp | 148 | ||||
| -rw-r--r-- | src/server/game/DataStores/DB2Stores.h | 2 | ||||
| -rw-r--r-- | src/server/game/Maps/TransportMgr.h | 2 | ||||
| -rw-r--r-- | src/server/game/World/World.cpp | 8 |
4 files changed, 95 insertions, 65 deletions
diff --git a/src/server/game/DataStores/DB2Stores.cpp b/src/server/game/DataStores/DB2Stores.cpp index 85caeccd077..e37196cc3de 100644 --- a/src/server/game/DataStores/DB2Stores.cpp +++ b/src/server/game/DataStores/DB2Stores.cpp @@ -27,7 +27,9 @@ #include "Regex.h" #include "Timer.h" #include "Util.h" +#include <boost/filesystem/operations.hpp> #include <array> +#include <bitset> #include <numeric> #include <sstream> #include <cctype> @@ -438,7 +440,7 @@ namespace template<typename T> constexpr std::size_t GetCppRecordSize(DB2Storage<T> const&) { return sizeof(T); } -void LoadDB2(uint32& availableDb2Locales, std::vector<std::string>& errlist, StorageMap& stores, DB2StorageBase* storage, std::string const& db2Path, +void LoadDB2(std::bitset<TOTAL_LOCALES>& availableDb2Locales, std::vector<std::string>& errlist, StorageMap& stores, DB2StorageBase* storage, std::string const& db2Path, LocaleConstant defaultLocale, std::size_t cppRecordSize) { // validate structure @@ -472,42 +474,53 @@ void LoadDB2(uint32& availableDb2Locales, std::vector<std::string>& errlist, Sto storage->GetFileName().c_str(), loadInfo->Meta->GetRecordSize(), cppRecordSize); } - if (storage->Load(db2Path + localeNames[defaultLocale] + '/', defaultLocale)) + try { - storage->LoadFromDB(); - // LoadFromDB() always loads strings into enUS locale, other locales are expected to have data in corresponding _locale tables - // so we need to make additional call to load that data in case said locale is set as default by worldserver.conf (and we do not want to load all this data from .db2 file again) - if (defaultLocale != LOCALE_enUS) - storage->LoadStringsFromDB(defaultLocale); - - for (LocaleConstant i = LOCALE_enUS; i < TOTAL_LOCALES; i = LocaleConstant(i + 1)) + storage->Load(db2Path + localeNames[defaultLocale] + '/', defaultLocale); + } + catch (std::system_error const& e) + { + if (e.code() == std::errc::no_such_file_or_directory) { - if (defaultLocale == i || i == LOCALE_none) - continue; - - if (availableDb2Locales & (1 << i)) - if (!storage->LoadStringsFrom((db2Path + localeNames[i] + '/'), i)) - availableDb2Locales &= ~(1 << i); // mark as not available for speedup next checks - - storage->LoadStringsFromDB(i); + errlist.push_back(Trinity::StringFormat("File %s does not exist", db2Path + localeNames[defaultLocale] + '/' + storage->GetFileName())); } + else + throw; } - else + catch (std::exception const& e) { - // sort problematic db2 to (1) non compatible and (2) nonexistent - if (FILE* f = fopen((db2Path + localeNames[defaultLocale] + '/' + storage->GetFileName()).c_str(), "rb")) + errlist.emplace_back(e.what()); + return; + } + + // load additional data and enUS strings from db + storage->LoadFromDB(); + + for (LocaleConstant i = LOCALE_enUS; i < TOTAL_LOCALES; i = LocaleConstant(i + 1)) + { + if (defaultLocale == i || !availableDb2Locales[i]) + continue; + + try { - std::ostringstream stream; - stream << storage->GetFileName() << " exists, and has " << storage->GetFieldCount() << " field(s) (expected " << loadInfo->Meta->FieldCount - << "). Extracted file might be from wrong client version."; - std::string buf = stream.str(); - errlist.push_back(buf); - fclose(f); + storage->LoadStringsFrom((db2Path + localeNames[i] + '/'), i); + } + catch (std::system_error const& e) + { + if (e.code() != std::errc::no_such_file_or_directory) + throw; + + // locale db2 files are optional, do not error if nothing is found + } + catch (std::exception const& e) + { + errlist.emplace_back(e.what()); } - else - errlist.push_back(storage->GetFileName()); } + for (LocaleConstant i = LOCALE_koKR; i < TOTAL_LOCALES; i = LocaleConstant(i + 1)) + storage->LoadStringsFromDB(i); + stores[storage->GetTableHash()] = storage; } @@ -517,16 +530,32 @@ DB2Manager& DB2Manager::Instance() return instance; } -void DB2Manager::LoadStores(std::string const& dataPath, LocaleConstant defaultLocale) +uint32 DB2Manager::LoadStores(std::string const& dataPath, LocaleConstant defaultLocale) { uint32 oldMSTime = getMSTime(); std::string db2Path = dataPath + "dbc/"; - std::vector<std::string> bad_db2_files; - uint32 availableDb2Locales = 0xFF; + std::vector<std::string> loadErrors; + std::bitset<TOTAL_LOCALES> availableDb2Locales = [&]() + { + std::bitset<TOTAL_LOCALES> foundLocales; + boost::filesystem::directory_iterator db2PathItr(db2Path), end; + while (db2PathItr != end) + { + LocaleConstant locale = GetLocaleByName(db2PathItr->path().filename().string()); + if (IsValidLocale(locale)) + foundLocales[locale] = true; -#define LOAD_DB2(store) LoadDB2(availableDb2Locales, bad_db2_files, _stores, &store, db2Path, defaultLocale, GetCppRecordSize(store)) + ++db2PathItr; + } + return foundLocales; + }(); + + if (!availableDb2Locales[defaultLocale]) + return 0; + +#define LOAD_DB2(store) LoadDB2(availableDb2Locales, loadErrors, _stores, &store, db2Path, defaultLocale, GetCppRecordSize(store)) LOAD_DB2(sAchievementStore); LOAD_DB2(sAnimationDataStore); @@ -783,6 +812,30 @@ void DB2Manager::LoadStores(std::string const& dataPath, LocaleConstant defaultL #undef LOAD_DB2 + // error checks + if (!loadErrors.empty()) + { + sLog->SetSynchronous(); // server will shut down after this, so set sync logging to prevent messages from getting lost + + for (std::string const& error : loadErrors) + TC_LOG_ERROR("misc", "%s", error.c_str()); + + return 0; + } + + // Check loaded DB2 files proper version + if (!sAreaTableStore.LookupEntry(13227) || // last area added in 8.3.0 (34769) + !sCharTitlesStore.LookupEntry(672) || // last char title added in 8.3.0 (34769) + !sGemPropertiesStore.LookupEntry(3802) || // last gem property added in 8.3.0 (34769) + !sItemStore.LookupEntry(175264) || // last item added in 8.3.0 (34769) + !sItemExtendedCostStore.LookupEntry(6716) || // last item extended cost added in 8.3.0 (34769) + !sMapStore.LookupEntry(2292) || // last map added in 8.3.0 (34769) + !sSpellNameStore.LookupEntry(319960)) // last spell added in 8.3.0 (34769) + { + TC_LOG_ERROR("misc", "You have _outdated_ DB2 files. Please extract correct versions from current using client."); + exit(1); + } + for (AreaGroupMemberEntry const* areaGroupMember : sAreaGroupMemberStore) _areaGroupMembers[areaGroupMember->AreaGroupID].push_back(areaGroupMember->AreaID); @@ -1322,36 +1375,9 @@ void DB2Manager::LoadStores(std::string const& dataPath, LocaleConstant defaultL } } - // error checks - if (bad_db2_files.size() == _stores.size()) - { - TC_LOG_ERROR("misc", "\nIncorrect DataDir value in worldserver.conf or ALL required *.db2 files (" SZFMTD ") not found by path: %sdbc/%s/", _stores.size(), dataPath.c_str(), localeNames[defaultLocale]); - exit(1); - } - else if (!bad_db2_files.empty()) - { - std::string str; - for (auto const& bad_db2_file : bad_db2_files) - str += bad_db2_file + "\n"; - - TC_LOG_ERROR("misc", "\nSome required *.db2 files (" SZFMTD " from " SZFMTD ") not found or not compatible:\n%s", bad_db2_files.size(), _stores.size(), str.c_str()); - exit(1); - } - - // Check loaded DB2 files proper version - if (!sAreaTableStore.LookupEntry(10521) || // last area added in 8.1.5 (30706) - !sCharTitlesStore.LookupEntry(649) || // last char title added in 8.1.5 (30706) - !sGemPropertiesStore.LookupEntry(3746) || // last gem property added in 8.1.5 (30706) - !sItemStore.LookupEntry(168279) || // last item added in 8.1.5 (30706) - !sItemExtendedCostStore.LookupEntry(6545) || // last item extended cost added in 8.1.5 (30706) - !sMapStore.LookupEntry(2178) || // last map added in 8.1.5 (30706) - !sSpellNameStore.LookupEntry(296952)) // last spell added in 8.1.5 (30706) - { - TC_LOG_ERROR("misc", "You have _outdated_ DB2 files. Please extract correct versions from current using client."); - exit(1); - } - TC_LOG_INFO("server.loading", ">> Initialized " SZFMTD " DB2 data stores in %u ms", _stores.size(), GetMSTimeDiffToNow(oldMSTime)); + + return availableDb2Locales.to_ulong(); } DB2StorageBase const* DB2Manager::GetStorage(uint32 type) const diff --git a/src/server/game/DataStores/DB2Stores.h b/src/server/game/DataStores/DB2Stores.h index d33ba31ceac..95ac7eabf14 100644 --- a/src/server/game/DataStores/DB2Stores.h +++ b/src/server/game/DataStores/DB2Stores.h @@ -275,7 +275,7 @@ public: static DB2Manager& Instance(); - void LoadStores(std::string const& dataPath, LocaleConstant defaultLocale); + uint32 LoadStores(std::string const& dataPath, LocaleConstant defaultLocale); DB2StorageBase const* GetStorage(uint32 type) const; void LoadHotfixData(); diff --git a/src/server/game/Maps/TransportMgr.h b/src/server/game/Maps/TransportMgr.h index 49f1b2b0083..0005eed85a7 100644 --- a/src/server/game/Maps/TransportMgr.h +++ b/src/server/game/Maps/TransportMgr.h @@ -102,8 +102,6 @@ typedef std::map<uint32, TransportAnimation> TransportAnimationContainer; class TC_GAME_API TransportMgr { - friend void DB2Manager::LoadStores(std::string const&, LocaleConstant); - public: static TransportMgr* instance(); diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 4567492bba0..3aa3fcde40b 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1571,7 +1571,13 @@ void World::SetInitialWorldSettings() TC_LOG_INFO("server.loading", "Initialize data stores..."); ///- Load DB2s - sDB2Manager.LoadStores(m_dataPath, m_defaultDbcLocale); + m_availableDbcLocaleMask = sDB2Manager.LoadStores(m_dataPath, m_defaultDbcLocale); + if (!(m_availableDbcLocaleMask & (1 << m_defaultDbcLocale))) + { + TC_LOG_FATAL("server.loading", "Unable to load db2 files for %s locale specified in DBC.Locale config!", localeNames[m_defaultDbcLocale]); + exit(1); + } + TC_LOG_INFO("misc", "Loading hotfix blobs..."); sDB2Manager.LoadHotfixBlob(); TC_LOG_INFO("misc", "Loading hotfix info..."); |
