diff options
| author | Shauren <shauren.trinity@gmail.com> | 2022-07-14 22:32:21 +0200 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2022-07-14 22:32:21 +0200 |
| commit | e487d78ba7b37c35ede36c554169d26afeac88b0 (patch) | |
| tree | 0591c19887f048d6fb3f070eaecb396086f04389 /src/server/game | |
| parent | f4951f9031cf2c015474c80f5fb0172f19b31acb (diff) | |
Core/WorldStates: Move custom worldstates to separate table and move saving worldstate values to WorldStateMgr
Diffstat (limited to 'src/server/game')
| -rw-r--r-- | src/server/game/Miscellaneous/SharedDefines.h | 10 | ||||
| -rw-r--r-- | src/server/game/Tools/CharacterDatabaseCleaner.cpp | 9 | ||||
| -rw-r--r-- | src/server/game/World/World.cpp | 158 | ||||
| -rw-r--r-- | src/server/game/World/World.h | 21 | ||||
| -rw-r--r-- | src/server/game/World/WorldStates/WorldStateMgr.cpp | 65 | ||||
| -rw-r--r-- | src/server/game/World/WorldStates/WorldStateMgr.h | 2 |
6 files changed, 145 insertions, 120 deletions
diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index 8a638e638fc..d5ae045904b 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -7838,16 +7838,6 @@ enum WorldState : uint32 WS_WAR_MODE_HORDE_BUFF_VALUE = 17042, WS_WAR_MODE_ALLIANCE_BUFF_VALUE = 17043, - - WS_CURRENCY_RESET_TIME = 20001, // Next arena distribution time - WS_WEEKLY_QUEST_RESET_TIME = 20002, // Next weekly quest reset time - WS_BG_DAILY_RESET_TIME = 20003, // Next daily BG reset time - WS_CLEANING_FLAGS = 20004, // Cleaning Flags - WS_GUILD_DAILY_RESET_TIME = 20006, // Next guild cap reset time - WS_MONTHLY_QUEST_RESET_TIME = 20007, // Next monthly quest reset time - WS_DAILY_QUEST_RESET_TIME = 20008, // Next daily quest reset time - WS_DAILY_CALENDAR_DELETION_OLD_EVENTS_TIME = 20009, // Next daily calendar deletions of old events time - WS_GUILD_WEEKLY_RESET_TIME = 20050, // Next guild week reset time }; #endif diff --git a/src/server/game/Tools/CharacterDatabaseCleaner.cpp b/src/server/game/Tools/CharacterDatabaseCleaner.cpp index 4f67878885e..06956f865f3 100644 --- a/src/server/game/Tools/CharacterDatabaseCleaner.cpp +++ b/src/server/game/Tools/CharacterDatabaseCleaner.cpp @@ -36,12 +36,7 @@ void CharacterDatabaseCleaner::CleanDatabase() uint32 oldMSTime = getMSTime(); - // check flags which clean ups are necessary - QueryResult result = CharacterDatabase.PQuery("SELECT value FROM worldstates WHERE entry = %d", WS_CLEANING_FLAGS); - if (!result) - return; - - uint32 flags = (*result)[0].GetUInt32(); + uint32 flags = sWorld->GetPersistentWorldVariable(World::CharacterDatabaseCleaningFlagsVarId); // clean up if (flags & CLEANING_FLAG_ACHIEVEMENT_PROGRESS) @@ -62,7 +57,7 @@ void CharacterDatabaseCleaner::CleanDatabase() // NOTE: In order to have persistentFlags be set in worldstates for the next cleanup, // you need to define them at least once in worldstates. flags &= sWorld->getIntConfig(CONFIG_PERSISTENT_CHARACTER_CLEAN_FLAGS); - CharacterDatabase.DirectPExecute("UPDATE worldstates SET value = %u WHERE entry = %d", flags, WS_CLEANING_FLAGS); + sWorld->SetPersistentWorldVariable(World::CharacterDatabaseCleaningFlagsVarId, flags); sWorld->SetCleaningFlags(flags); diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index b762853b02a..502afce812b 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -119,6 +119,21 @@ TC_GAME_API int32 World::m_visibility_notify_periodInInstances = DEFAULT_VISIBI TC_GAME_API int32 World::m_visibility_notify_periodInBG = DEFAULT_VISIBILITY_NOTIFY_PERIOD; TC_GAME_API int32 World::m_visibility_notify_periodInArenas = DEFAULT_VISIBILITY_NOTIFY_PERIOD; +struct PersistentWorldVariable +{ + std::string Id; +}; + +PersistentWorldVariable const World::NextCurrencyResetTimeVarId{ "NextCurrencyResetTime" }; +PersistentWorldVariable const World::NextWeeklyQuestResetTimeVarId{ "NextWeeklyQuestResetTime" }; +PersistentWorldVariable const World::NextBGRandomDailyResetTimeVarId{ "NextBGRandomDailyResetTime" }; +PersistentWorldVariable const World::CharacterDatabaseCleaningFlagsVarId{ "PersistentCharacterCleanFlags" }; +PersistentWorldVariable const World::NextGuildDailyResetTimeVarId{ "NextGuildDailyResetTime" }; +PersistentWorldVariable const World::NextMonthlyQuestResetTimeVarId{ "NextMonthlyQuestResetTime" }; +PersistentWorldVariable const World::NextDailyQuestResetTimeVarId{ "NextDailyQuestResetTime" }; +PersistentWorldVariable const World::NextOldCalendarEventDeletionTimeVarId{ "NextOldCalendarEventDeletionTime" }; +PersistentWorldVariable const World::NextGuildWeeklyResetTimeVarId{ "NextGuildWeeklyResetTime" }; + /// World constructor World::World() { @@ -145,6 +160,7 @@ World::World() mail_timer = 0; mail_timer_expires = 0; + blackmarket_timer = 0; m_isClosed = false; @@ -2246,16 +2262,13 @@ void World::SetInitialWorldSettings() sFormationMgr->LoadCreatureFormations(); TC_LOG_INFO("server.loading", "Loading World State templates..."); - sWorldStateMgr->LoadFromDB(); + sWorldStateMgr->LoadFromDB(); // must be loaded before battleground, outdoor PvP and conditions - TC_LOG_INFO("server.loading", "Loading World States..."); // must be loaded before battleground, outdoor PvP and conditions - LoadWorldStates(); + TC_LOG_INFO("server.loading", "Loading Persistend World Variables..."); + LoadPersistentWorldVariables(); sWorldStateMgr->SetValue(WS_CURRENT_PVP_SEASON_ID, getBoolConfig(CONFIG_ARENA_SEASON_IN_PROGRESS) ? getIntConfig(CONFIG_ARENA_SEASON_ID) : 0, false, nullptr); sWorldStateMgr->SetValue(WS_PREVIOUS_PVP_SEASON_ID, getIntConfig(CONFIG_ARENA_SEASON_ID) - getBoolConfig(CONFIG_ARENA_SEASON_IN_PROGRESS), false, nullptr); - // TODO: this is temporary until custom world states are purged from old world state saved values - sWorldStateMgr->SetValue(WS_WAR_MODE_HORDE_BUFF_VALUE, getWorldState(WS_WAR_MODE_HORDE_BUFF_VALUE), false, nullptr); - sWorldStateMgr->SetValue(WS_WAR_MODE_ALLIANCE_BUFF_VALUE, getWorldState(WS_WAR_MODE_ALLIANCE_BUFF_VALUE), false, nullptr); sObjectMgr->LoadPhases(); @@ -2374,8 +2387,6 @@ void World::SetInitialWorldSettings() m_timers[WUPDATE_BLACKMARKET].SetInterval(10 * IN_MILLISECONDS); - blackmarket_timer = 0; - m_timers[WUPDATE_CHECK_FILECHANGES].SetInterval(500); m_timers[WUPDATE_WHO_LIST].SetInterval(5 * IN_MILLISECONDS); // update who list cache every 5 seconds @@ -2503,12 +2514,8 @@ void World::SetInitialWorldSettings() void World::SetForcedWarModeFactionBalanceState(TeamId team, int32 reward) { - sWorldStateMgr->SetValue(WS_WAR_MODE_HORDE_BUFF_VALUE, 10 + (team == TEAM_ALLIANCE ? reward : 0), false, nullptr); - sWorldStateMgr->SetValue(WS_WAR_MODE_ALLIANCE_BUFF_VALUE, 10 + (team == TEAM_HORDE ? reward : 0), false, nullptr); - - // save to db - setWorldState(WS_WAR_MODE_HORDE_BUFF_VALUE, sWorldStateMgr->GetValue(WS_WAR_MODE_HORDE_BUFF_VALUE, nullptr)); - setWorldState(WS_WAR_MODE_ALLIANCE_BUFF_VALUE, sWorldStateMgr->GetValue(WS_WAR_MODE_ALLIANCE_BUFF_VALUE, nullptr)); + sWorldStateMgr->SetValueAndSaveInDb(WS_WAR_MODE_HORDE_BUFF_VALUE, 10 + (team == TEAM_ALLIANCE ? reward : 0), false, nullptr); + sWorldStateMgr->SetValueAndSaveInDb(WS_WAR_MODE_ALLIANCE_BUFF_VALUE, 10 + (team == TEAM_HORDE ? reward : 0), false, nullptr); } void World::DisableForcedWarModeFactionBalanceState() @@ -3484,9 +3491,9 @@ void World::_UpdateRealmCharCount(PreparedQueryResult resultCharCount) void World::InitQuestResetTimes() { - m_NextDailyQuestReset = sWorld->getWorldState(WS_DAILY_QUEST_RESET_TIME); - m_NextWeeklyQuestReset = sWorld->getWorldState(WS_WEEKLY_QUEST_RESET_TIME); - m_NextMonthlyQuestReset = sWorld->getWorldState(WS_MONTHLY_QUEST_RESET_TIME); + m_NextDailyQuestReset = sWorld->GetPersistentWorldVariable(NextDailyQuestResetTimeVarId); + m_NextWeeklyQuestReset = sWorld->GetPersistentWorldVariable(NextWeeklyQuestResetTimeVarId); + m_NextMonthlyQuestReset = sWorld->GetPersistentWorldVariable(NextMonthlyQuestResetTimeVarId); } static time_t GetNextDailyResetTime(time_t t) @@ -3518,7 +3525,7 @@ void World::DailyReset() ASSERT(now < next); m_NextDailyQuestReset = next; - sWorld->setWorldState(WS_DAILY_QUEST_RESET_TIME, uint64(next)); + sWorld->SetPersistentWorldVariable(NextDailyQuestResetTimeVarId, uint64(next)); TC_LOG_INFO("misc", "Daily quests for all characters have been reset."); } @@ -3557,7 +3564,7 @@ void World::ResetWeeklyQuests() ASSERT(now < next); m_NextWeeklyQuestReset = next; - sWorld->setWorldState(WS_WEEKLY_QUEST_RESET_TIME, uint64(next)); + sWorld->SetPersistentWorldVariable(NextWeeklyQuestResetTimeVarId, uint64(next)); TC_LOG_INFO("misc", "Weekly quests for all characters have been reset."); } @@ -3593,7 +3600,7 @@ void World::ResetMonthlyQuests() ASSERT(now < next); m_NextMonthlyQuestReset = next; - sWorld->setWorldState(WS_MONTHLY_QUEST_RESET_TIME, uint64(next)); + sWorld->SetPersistentWorldVariable(NextMonthlyQuestResetTimeVarId, uint64(next)); TC_LOG_INFO("misc", "Monthly quests for all characters have been reset."); } @@ -3611,7 +3618,7 @@ void World::CheckScheduledResetTimes() void World::InitRandomBGResetTime() { - time_t bgtime = sWorld->getWorldState(WS_BG_DAILY_RESET_TIME); + time_t bgtime = sWorld->GetPersistentWorldVariable(NextBGRandomDailyResetTimeVarId); if (!bgtime) m_NextRandomBGReset = GameTime::GetGameTime(); // game time not yet init @@ -3634,14 +3641,14 @@ void World::InitRandomBGResetTime() m_NextRandomBGReset = bgtime < curTime ? nextDayResetTime - DAY : nextDayResetTime; if (!bgtime) - sWorld->setWorldState(WS_BG_DAILY_RESET_TIME, uint32(m_NextRandomBGReset)); + sWorld->SetPersistentWorldVariable(NextBGRandomDailyResetTimeVarId, uint32(m_NextRandomBGReset)); } void World::InitCalendarOldEventsDeletionTime() { time_t now = GameTime::GetGameTime(); time_t nextDeletionTime = GetLocalHourTimestamp(now, getIntConfig(CONFIG_CALENDAR_DELETE_OLD_EVENTS_HOUR)); - time_t currentDeletionTime = getWorldState(WS_DAILY_CALENDAR_DELETION_OLD_EVENTS_TIME); + time_t currentDeletionTime = GetPersistentWorldVariable(NextOldCalendarEventDeletionTimeVarId); // If the reset time saved in the worldstate is before now it means the server was offline when the reset was supposed to occur. // In this case we set the reset time in the past and next world update will do the reset and schedule next one in the future. @@ -3651,12 +3658,12 @@ void World::InitCalendarOldEventsDeletionTime() m_NextCalendarOldEventsDeletionTime = nextDeletionTime; if (!currentDeletionTime) - sWorld->setWorldState(WS_DAILY_CALENDAR_DELETION_OLD_EVENTS_TIME, uint64(m_NextCalendarOldEventsDeletionTime)); + sWorld->SetPersistentWorldVariable(NextOldCalendarEventDeletionTimeVarId, uint64(m_NextCalendarOldEventsDeletionTime)); } void World::InitGuildResetTime() { - time_t gtime = getWorldState(WS_GUILD_DAILY_RESET_TIME); + time_t gtime = GetPersistentWorldVariable(NextGuildDailyResetTimeVarId); if (!gtime) m_NextGuildReset = GameTime::GetGameTime(); // game time not yet init @@ -3679,12 +3686,12 @@ void World::InitGuildResetTime() m_NextGuildReset = gtime < curTime ? nextDayResetTime - DAY : nextDayResetTime; if (!gtime) - sWorld->setWorldState(WS_GUILD_DAILY_RESET_TIME, uint32(m_NextGuildReset)); + sWorld->SetPersistentWorldVariable(NextGuildDailyResetTimeVarId, uint32(m_NextGuildReset)); } void World::InitCurrencyResetTime() { - time_t currencytime = sWorld->getWorldState(WS_CURRENCY_RESET_TIME); + time_t currencytime = sWorld->GetPersistentWorldVariable(NextCurrencyResetTimeVarId); if (!currencytime) m_NextCurrencyReset = GameTime::GetGameTime(); // game time not yet init @@ -3709,7 +3716,7 @@ void World::InitCurrencyResetTime() m_NextCurrencyReset = currencytime < curTime ? nextWeekResetTime - getIntConfig(CONFIG_CURRENCY_RESET_INTERVAL) * DAY : nextWeekResetTime; if (!currencytime) - sWorld->setWorldState(WS_CURRENCY_RESET_TIME, uint32(m_NextCurrencyReset)); + sWorld->SetPersistentWorldVariable(NextCurrencyResetTimeVarId, uint32(m_NextCurrencyReset)); } void World::ResetCurrencyWeekCap() @@ -3721,7 +3728,7 @@ void World::ResetCurrencyWeekCap() itr->second->GetPlayer()->ResetCurrencyWeekCap(); m_NextCurrencyReset = time_t(m_NextCurrencyReset + DAY * getIntConfig(CONFIG_CURRENCY_RESET_INTERVAL)); - sWorld->setWorldState(WS_CURRENCY_RESET_TIME, uint32(m_NextCurrencyReset)); + sWorld->SetPersistentWorldVariable(NextCurrencyResetTimeVarId, uint32(m_NextCurrencyReset)); } void World::ResetEventSeasonalQuests(uint16 event_id, time_t eventStartTime) @@ -3750,7 +3757,7 @@ void World::ResetRandomBG() itr->second->GetPlayer()->SetRandomWinner(false); m_NextRandomBGReset = time_t(m_NextRandomBGReset + DAY); - sWorld->setWorldState(WS_BG_DAILY_RESET_TIME, uint32(m_NextRandomBGReset)); + sWorld->SetPersistentWorldVariable(NextBGRandomDailyResetTimeVarId, uint32(m_NextRandomBGReset)); } void World::CalendarDeleteOldEvents() @@ -3758,19 +3765,19 @@ void World::CalendarDeleteOldEvents() TC_LOG_INFO("misc", "Calendar deletion of old events."); m_NextCalendarOldEventsDeletionTime = time_t(m_NextCalendarOldEventsDeletionTime + DAY); - sWorld->setWorldState(WS_DAILY_CALENDAR_DELETION_OLD_EVENTS_TIME, uint64(m_NextCalendarOldEventsDeletionTime)); + sWorld->SetPersistentWorldVariable(NextOldCalendarEventDeletionTimeVarId, uint64(m_NextCalendarOldEventsDeletionTime)); sCalendarMgr->DeleteOldEvents(); } void World::ResetGuildCap() { m_NextGuildReset = time_t(m_NextGuildReset + DAY); - sWorld->setWorldState(WS_GUILD_DAILY_RESET_TIME, uint32(m_NextGuildReset)); - uint32 week = getWorldState(WS_GUILD_WEEKLY_RESET_TIME); + sWorld->SetPersistentWorldVariable(NextGuildDailyResetTimeVarId, uint32(m_NextGuildReset)); + uint32 week = GetPersistentWorldVariable(NextGuildWeeklyResetTimeVarId); week = week < 7 ? week + 1 : 1; TC_LOG_INFO("misc", "Guild Daily Cap reset. Week: %u", week == 1); - sWorld->setWorldState(WS_GUILD_WEEKLY_RESET_TIME, week); + sWorld->SetPersistentWorldVariable(NextGuildWeeklyResetTimeVarId, week); sGuildMgr->ResetTimes(week == 1); } @@ -3815,33 +3822,6 @@ bool World::IsBattlePetJournalLockAcquired(ObjectGuid battlenetAccountGuid) return false; } -void World::LoadWorldStates() -{ - uint32 oldMSTime = getMSTime(); - - QueryResult result = CharacterDatabase.Query("SELECT entry, value FROM worldstates"); - - if (!result) - { - TC_LOG_INFO("server.loading", ">> Loaded 0 world states. DB table `worldstates` is empty!"); - - return; - } - - uint32 count = 0; - - do - { - Field* fields = result->Fetch(); - m_worldstates[fields[0].GetUInt32()] = fields[1].GetUInt32(); - ++count; - } - while (result->NextRow()); - - TC_LOG_INFO("server.loading", ">> Loaded %u world states in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); - -} - bool World::IsPvPRealm() const { return (getIntConfig(CONFIG_GAME_TYPE) == REALM_TYPE_PVP || getIntConfig(CONFIG_GAME_TYPE) == REALM_TYPE_RPPVP || getIntConfig(CONFIG_GAME_TYPE) == REALM_TYPE_FFA_PVP); @@ -3852,38 +3832,38 @@ bool World::IsFFAPvPRealm() const return getIntConfig(CONFIG_GAME_TYPE) == REALM_TYPE_FFA_PVP; } -// Setting a worldstate will save it to DB -void World::setWorldState(uint32 index, uint32 value) +int32 World::GetPersistentWorldVariable(PersistentWorldVariable const& var) const { - WorldStatesMap::const_iterator it = m_worldstates.find(index); - if (it != m_worldstates.end()) - { - if (it->second == value) - return; + if (int32 const* value = Trinity::Containers::MapGetValuePtr(m_worldVariables, var.Id)) + return *value; - CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_WORLDSTATE); + return 0; +} - stmt->setUInt32(0, uint32(value)); - stmt->setUInt32(1, index); +void World::SetPersistentWorldVariable(PersistentWorldVariable const& var, int32 value) +{ + m_worldVariables[var.Id] = value; - CharacterDatabase.Execute(stmt); - } - else - { - CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_WORLDSTATE); + CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_WORLD_VARIABLE); + stmt->setStringView(0, var.Id); + stmt->setInt32(1, value); + CharacterDatabase.Execute(stmt); +} - stmt->setUInt32(0, index); - stmt->setUInt32(1, uint32(value)); +void World::LoadPersistentWorldVariables() +{ + uint32 oldMSTime = getMSTime(); - CharacterDatabase.Execute(stmt); + if (QueryResult result = CharacterDatabase.Query("SELECT ID, Value FROM world_variable")) + { + do + { + Field* fields = result->Fetch(); + m_worldVariables[fields[0].GetString()] = fields[1].GetInt32(); + } while (result->NextRow()); } - m_worldstates[index] = value; -} -uint32 World::getWorldState(uint32 index) const -{ - WorldStatesMap::const_iterator it = m_worldstates.find(index); - return it != m_worldstates.end() ? it->second : 0; + TC_LOG_INFO("server.loading", ">> Loaded " SZFMTD " world variables in %u ms", m_worldVariables.size(), GetMSTimeDiffToNow(oldMSTime)); } void World::ProcessQueryCallbacks() @@ -3956,12 +3936,8 @@ void World::UpdateWarModeRewardValues() outnumberedFactionReward = 5; } - sWorldStateMgr->SetValue(WS_WAR_MODE_HORDE_BUFF_VALUE, 10 + (dominantFaction == TEAM_ALLIANCE ? outnumberedFactionReward : 0), false, nullptr); - sWorldStateMgr->SetValue(WS_WAR_MODE_ALLIANCE_BUFF_VALUE, 10 + (dominantFaction == TEAM_HORDE ? outnumberedFactionReward : 0), false, nullptr); - - // save to db - setWorldState(WS_WAR_MODE_HORDE_BUFF_VALUE, sWorldStateMgr->GetValue(WS_WAR_MODE_HORDE_BUFF_VALUE, nullptr)); - setWorldState(WS_WAR_MODE_ALLIANCE_BUFF_VALUE, sWorldStateMgr->GetValue(WS_WAR_MODE_ALLIANCE_BUFF_VALUE, nullptr)); + sWorldStateMgr->SetValueAndSaveInDb(WS_WAR_MODE_HORDE_BUFF_VALUE, 10 + (dominantFaction == TEAM_ALLIANCE ? outnumberedFactionReward : 0), false, nullptr); + sWorldStateMgr->SetValueAndSaveInDb(WS_WAR_MODE_ALLIANCE_BUFF_VALUE, 10 + (dominantFaction == TEAM_HORDE ? outnumberedFactionReward : 0), false, nullptr); } Realm realm; diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index 214e9cbd6c0..044990acecd 100644 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -561,6 +561,8 @@ enum RealmZone REALM_ZONE_CN5_8 = 37 // basic-Latin at create, any at login }; +struct PersistentWorldVariable; + /// Storage class for commands issued for delayed execution struct TC_GAME_API CliCommandHolder { @@ -746,9 +748,19 @@ class TC_GAME_API World return index < INT64_CONFIT_VALUE_COUNT ? m_int64_configs[index] : 0; } - void setWorldState(uint32 index, uint32 value); - uint32 getWorldState(uint32 index) const; - void LoadWorldStates(); + static PersistentWorldVariable const NextCurrencyResetTimeVarId; // Next arena distribution time + static PersistentWorldVariable const NextWeeklyQuestResetTimeVarId; // Next weekly quest reset time + static PersistentWorldVariable const NextBGRandomDailyResetTimeVarId; // Next daily BG reset time + static PersistentWorldVariable const CharacterDatabaseCleaningFlagsVarId; // Cleaning Flags + static PersistentWorldVariable const NextGuildDailyResetTimeVarId; // Next guild cap reset time + static PersistentWorldVariable const NextMonthlyQuestResetTimeVarId; // Next monthly quest reset time + static PersistentWorldVariable const NextDailyQuestResetTimeVarId; // Next daily quest reset time + static PersistentWorldVariable const NextOldCalendarEventDeletionTimeVarId; // Next daily calendar deletions of old events time + static PersistentWorldVariable const NextGuildWeeklyResetTimeVarId; // Next guild week reset time + + int32 GetPersistentWorldVariable(PersistentWorldVariable const& var) const; + void SetPersistentWorldVariable(PersistentWorldVariable const& var, int32 value); + void LoadPersistentWorldVariables(); /// Are we on a "Player versus Player" server? bool IsPvPRealm() const; @@ -862,8 +874,7 @@ class TC_GAME_API World uint64 m_int64_configs[INT64_CONFIT_VALUE_COUNT]; bool m_bool_configs[BOOL_CONFIG_VALUE_COUNT]; float m_float_configs[FLOAT_CONFIG_VALUE_COUNT]; - typedef std::map<uint32, uint32> WorldStatesMap; - WorldStatesMap m_worldstates; + std::unordered_map<std::string, int32> m_worldVariables; uint32 m_playerLimit; AccountTypes m_allowedSecurityLevel; LocaleConstant m_defaultDbcLocale; // from config for one from loaded DBC locales diff --git a/src/server/game/World/WorldStates/WorldStateMgr.cpp b/src/server/game/World/WorldStates/WorldStateMgr.cpp index a09e9e82977..f753d0e0bc4 100644 --- a/src/server/game/World/WorldStates/WorldStateMgr.cpp +++ b/src/server/game/World/WorldStates/WorldStateMgr.cpp @@ -59,14 +59,14 @@ void WorldStateMgr::LoadFromDB() Optional<uint32> mapId = Trinity::StringTo<uint32>(mapIdToken); if (!mapId) { - TC_LOG_ERROR("sql.sql", "Table `world_state` contains a world state %u with non-integer MapID (" STRING_VIEW_FMT "), map ignored", + TC_LOG_ERROR("sql.sql", "Table `world_state` contains a world state %d with non-integer MapID (" STRING_VIEW_FMT "), map ignored", id, STRING_VIEW_FMT_ARG(mapIdToken)); continue; } if (!sMapStore.LookupEntry(*mapId)) { - TC_LOG_ERROR("sql.sql", "Table `world_state` contains a world state %u with invalid MapID (%u), map ignored", + TC_LOG_ERROR("sql.sql", "Table `world_state` contains a world state %d with invalid MapID (%u), map ignored", id, *mapId); continue; } @@ -76,7 +76,7 @@ void WorldStateMgr::LoadFromDB() if (!mapIds.empty() && worldState.MapIds.empty()) { - TC_LOG_ERROR("sql.sql", "Table `world_state` contains a world state %u with nonempty MapIDs (" STRING_VIEW_FMT ") but no valid map id was found, ignored", + TC_LOG_ERROR("sql.sql", "Table `world_state` contains a world state %d with nonempty MapIDs (" STRING_VIEW_FMT ") but no valid map id was found, ignored", id, STRING_VIEW_FMT_ARG(mapIds)); continue; } @@ -97,14 +97,14 @@ void WorldStateMgr::LoadFromDB() AreaTableEntry const* areaTableEntry = sAreaTableStore.LookupEntry(*areaId); if (!areaTableEntry) { - TC_LOG_ERROR("sql.sql", "Table `world_state` contains a world state %u with invalid AreaID (%u), area ignored", + TC_LOG_ERROR("sql.sql", "Table `world_state` contains a world state %d with invalid AreaID (%u), area ignored", id, *areaId); continue; } if (worldState.MapIds.find(areaTableEntry->ContinentID) == worldState.MapIds.end()) { - TC_LOG_ERROR("sql.sql", "Table `world_state` contains a world state %u with AreaID (%u) not on any of required maps, area ignored", + TC_LOG_ERROR("sql.sql", "Table `world_state` contains a world state %d with AreaID (%u) not on any of required maps, area ignored", id, *areaId); continue; } @@ -114,14 +114,14 @@ void WorldStateMgr::LoadFromDB() if (!areaIds.empty() && worldState.AreaIds.empty()) { - TC_LOG_ERROR("sql.sql", "Table `world_state` contains a world state %u with nonempty AreaIDs (" STRING_VIEW_FMT ") but no valid area id was found, ignored", + TC_LOG_ERROR("sql.sql", "Table `world_state` contains a world state %d with nonempty AreaIDs (" STRING_VIEW_FMT ") but no valid area id was found, ignored", id, STRING_VIEW_FMT_ARG(areaIds)); continue; } } else if (!areaIds.empty()) { - TC_LOG_ERROR("sql.sql", "Table `world_state` contains a world state %u with nonempty AreaIDs (" STRING_VIEW_FMT ") but is a realm wide world state, area requirement ignored", + TC_LOG_ERROR("sql.sql", "Table `world_state` contains a world state %d with nonempty AreaIDs (" STRING_VIEW_FMT ") but is a realm wide world state, area requirement ignored", id, STRING_VIEW_FMT_ARG(areaIds)); } @@ -138,6 +138,40 @@ void WorldStateMgr::LoadFromDB() } while (result->NextRow()); TC_LOG_INFO("server.loading", ">> Loaded " SZFMTD " world state templates %u ms", _worldStateTemplates.size(), GetMSTimeDiffToNow(oldMSTime)); + + oldMSTime = getMSTime(); + + result = CharacterDatabase.Query("SELECT Id, Value FROM world_state_value"); + uint32 savedValueCount = 0; + if (result) + { + do + { + Field* fields = result->Fetch(); + int32 worldStateId = fields[0].GetInt32(); + WorldStateTemplate* worldState = Trinity::Containers::MapGetValuePtr(_worldStateTemplates, worldStateId); + if (!worldState) + { + TC_LOG_ERROR("sql.sql", "Table `world_state_value` contains a value for unknown world state %d, ignored", worldStateId); + continue; + } + + int32 value = fields[1].GetInt32(); + + if (!worldState->MapIds.empty()) + { + for (uint32 mapId : worldState->MapIds) + _worldStatesByMap[mapId][worldStateId] = value; + } + else + _realmWorldStateValues[worldStateId] = value; + + ++savedValueCount; + } + while (result->NextRow()); + } + + TC_LOG_INFO("server.loading", ">> Loaded %u saved world state values %u ms", savedValueCount, GetMSTimeDiffToNow(oldMSTime)); } WorldStateTemplate const* WorldStateMgr::GetWorldStateTemplate(int32 worldStateId) const @@ -192,6 +226,23 @@ void WorldStateMgr::SetValue(int32 worldStateId, int32 value, bool hidden, Map* map->SetWorldStateValue(worldStateId, value, hidden); } +void WorldStateMgr::SaveValueInDb(int32 worldStateId, int32 value) +{ + if (!GetWorldStateTemplate(worldStateId)) + return; + + CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_WORLD_VARIABLE); + stmt->setInt32(0, worldStateId); + stmt->setInt32(1, value); + CharacterDatabase.Execute(stmt); +} + +void WorldStateMgr::SetValueAndSaveInDb(int32 worldStateId, int32 value, bool hidden, Map* map) +{ + SetValue(worldStateId, value, hidden, map); + SaveValueInDb(worldStateId, value); +} + WorldStateValueContainer WorldStateMgr::GetInitialWorldStatesForMap(Map const* map) const { WorldStateValueContainer initialValues; diff --git a/src/server/game/World/WorldStates/WorldStateMgr.h b/src/server/game/World/WorldStates/WorldStateMgr.h index d17cdb40310..17a3f7920ee 100644 --- a/src/server/game/World/WorldStates/WorldStateMgr.h +++ b/src/server/game/World/WorldStates/WorldStateMgr.h @@ -39,6 +39,8 @@ public: int32 GetValue(int32 worldStateId, Map const* map) const; void SetValue(int32 worldStateId, int32 value, bool hidden, Map* map); + void SaveValueInDb(int32 worldStateId, int32 value); + void SetValueAndSaveInDb(int32 worldStateId, int32 value, bool hidden, Map* map); WorldStateValueContainer GetInitialWorldStatesForMap(Map const* map) const; |
