From 89b019ffeb5414f51922796a9174ffbfc4def13e Mon Sep 17 00:00:00 2001 From: Shauren Date: Mon, 26 Dec 2022 10:53:47 +0100 Subject: [PATCH] Core/WorldStates: Move custom worldstates to separate table and move saving worldstate values to WorldStateMgr --- sql/base/characters_database.sql | 65 ++++++--- .../4.3.4/2022_12_26_00_characters.sql | 32 ++++ .../Implementation/CharacterDatabase.cpp | 4 +- .../Implementation/CharacterDatabase.h | 4 +- src/server/game/Conditions/ConditionMgr.cpp | 2 +- src/server/game/Miscellaneous/SharedDefines.h | 14 +- .../game/Tools/CharacterDatabaseCleaner.cpp | 9 +- src/server/game/World/World.cpp | 138 ++++++++---------- src/server/game/World/World.h | 21 ++- .../game/World/WorldStates/WorldStateMgr.cpp | 64 +++++++- .../game/World/WorldStates/WorldStateMgr.h | 2 + .../scripts/Battlefield/BattlefieldTB.cpp | 48 ++---- .../scripts/Battlefield/BattlefieldTB.h | 4 - .../scripts/Battlefield/BattlefieldWG.cpp | 98 +++---------- .../scripts/Battlefield/BattlefieldWG.h | 13 -- 15 files changed, 260 insertions(+), 258 deletions(-) create mode 100644 sql/updates/characters/4.3.4/2022_12_26_00_characters.sql diff --git a/sql/base/characters_database.sql b/sql/base/characters_database.sql index 5b1e46fc17..1440c8ed78 100644 --- a/sql/base/characters_database.sql +++ b/sql/base/characters_database.sql @@ -3060,6 +3060,7 @@ INSERT INTO `updates` VALUES ('2022_09_01_00_characters.sql','E3C0DA9995BA71ED5A267294470CD03DC51862DD','RELEASED','2022-09-01 14:51:33',0), ('2022_09_03_00_characters.sql','50429D68E6EBD1149CDA14A9EA642BC06A1FAE3D','RELEASED','2022-09-03 11:03:06',0), ('2022_12_24_00_characters.sql','D3F04078C0846BCF7C8330AC20C39B8C3AEE7002','RELEASED','2022-12-24 23:52:52',0), +('2022_12_26_00_characters.sql','74EDF8E4AC31419144E4535A295DB8B189CFAF95','RELEASED','2022-12-26 10:51:39',0), ('custom_2017_12_21_00_characters.sql','2D5B3830D47E4BC717EC468E18E477A32B9A21BF','ARCHIVED','2019-11-06 00:17:44',0), ('custom_2018_01_07_00_characters.sql','7437B6243B3CB6FA08F6A37BB39E38930B0DCFD3','ARCHIVED','2019-11-06 00:17:44',0), ('custom_2018_03_18_00_characters.sql','8D1E81A7272F643687C67443C270D17255A9AA84','ARCHIVED','2019-11-06 00:17:44',0), @@ -3124,35 +3125,59 @@ LOCK TABLES `warden_action` WRITE; UNLOCK TABLES; -- --- Table structure for table `worldstates` +-- Table structure for table `world_state_value` -- -DROP TABLE IF EXISTS `worldstates`; +DROP TABLE IF EXISTS `world_state_value`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; -CREATE TABLE `worldstates` ( - `entry` int unsigned NOT NULL DEFAULT '0', - `value` int unsigned NOT NULL DEFAULT '0', - `comment` tinytext COLLATE utf8mb4_unicode_ci, - PRIMARY KEY (`entry`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Variable Saves'; +CREATE TABLE `world_state_value` ( + `Id` int NOT NULL, + `Value` int NOT NULL, + PRIMARY KEY (`Id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- --- Dumping data for table `worldstates` +-- Dumping data for table `world_state_value` -- -LOCK TABLES `worldstates` WRITE; -/*!40000 ALTER TABLE `worldstates` DISABLE KEYS */; -INSERT INTO `worldstates` VALUES -(20001,0,'NextArenaPointDistributionTime'), -(20002,0,'NextWeeklyQuestResetTime'), -(20003,0,'NextBGRandomDailyResetTime'), -(20004,0,'cleaning_flags'), -(20006,0,'NextGuildDailyResetTime'), -(20007,0,'NextMonthlyQuestResetTime'), -(20008,0,'NextDailyQuestResetTime'); -/*!40000 ALTER TABLE `worldstates` ENABLE KEYS */; +LOCK TABLES `world_state_value` WRITE; +/*!40000 ALTER TABLE `world_state_value` DISABLE KEYS */; +/*!40000 ALTER TABLE `world_state_value` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `world_variable` +-- + +DROP TABLE IF EXISTS `world_variable`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `world_variable` ( + `ID` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, + `Value` int NOT NULL DEFAULT '0', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `world_variable` +-- + +LOCK TABLES `world_variable` WRITE; +/*!40000 ALTER TABLE `world_variable` DISABLE KEYS */; +INSERT INTO `world_variable` VALUES +('NextCurrencyResetTime',0), +('NextWeeklyQuestResetTime',0), +('NextBGRandomDailyResetTime',0), +('PersistentCharacterCleanFlags',0), +('NextGuildDailyResetTime',0), +('NextMonthlyQuestResetTime',0), +('NextDailyQuestResetTime',0), +('NextOldCalendarEventDeletionTime',0), +('NextGuildWeeklyResetTime',0); +/*!40000 ALTER TABLE `world_variable` ENABLE KEYS */; UNLOCK TABLES; -- diff --git a/sql/updates/characters/4.3.4/2022_12_26_00_characters.sql b/sql/updates/characters/4.3.4/2022_12_26_00_characters.sql new file mode 100644 index 0000000000..734ecae701 --- /dev/null +++ b/sql/updates/characters/4.3.4/2022_12_26_00_characters.sql @@ -0,0 +1,32 @@ +-- +-- Table structure for table `world_state_value` +-- +DROP TABLE IF EXISTS `world_state_value`; +CREATE TABLE `world_state_value` ( + `Id` int NOT NULL, + `Value` int NOT NULL, + PRIMARY KEY (`Id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +-- +-- Table structure for table `world_state_value` +-- +DROP TABLE IF EXISTS `world_variable`; +CREATE TABLE `world_variable` ( + `ID` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, + `Value` int NOT NULL DEFAULT '0', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +INSERT INTO `world_state_value` SELECT `entry`, `value` FROM `worldstates` WHERE `entry` NOT BETWEEN 20001 AND 20009 AND `entry` <> 20050; + +INSERT INTO `world_variable` SELECT 'NextCurrencyResetTime', ws.`value` FROM `worldstates` ws WHERE ws.entry = 20001; +INSERT INTO `world_variable` SELECT 'NextWeeklyQuestResetTime', ws.`value` FROM `worldstates` ws WHERE ws.entry = 20002; +INSERT INTO `world_variable` SELECT 'NextBGRandomDailyResetTime', ws.`value` FROM `worldstates` ws WHERE ws.entry = 20003; +INSERT INTO `world_variable` SELECT 'PersistentCharacterCleanFlags', ws.`value` FROM `worldstates` ws WHERE ws.entry = 20004; +INSERT INTO `world_variable` SELECT 'NextGuildDailyResetTime', ws.`value` FROM `worldstates` ws WHERE ws.entry = 20006; +INSERT INTO `world_variable` SELECT 'NextMonthlyQuestResetTime', ws.`value` FROM `worldstates` ws WHERE ws.entry = 20007; +INSERT INTO `world_variable` SELECT 'NextDailyQuestResetTime', ws.`value` FROM `worldstates` ws WHERE ws.entry = 20008; +INSERT INTO `world_variable` SELECT 'NextOldCalendarEventDeletionTime', ws.`value` FROM `worldstates` ws WHERE ws.entry = 20009; +INSERT INTO `world_variable` SELECT 'NextGuildWeeklyResetTime', ws.`value` FROM `worldstates` ws WHERE ws.entry = 20050; + +DROP TABLE `worldstates`; diff --git a/src/server/database/Database/Implementation/CharacterDatabase.cpp b/src/server/database/Database/Implementation/CharacterDatabase.cpp index 3e56ae5ee9..6c4606b1b3 100644 --- a/src/server/database/Database/Implementation/CharacterDatabase.cpp +++ b/src/server/database/Database/Implementation/CharacterDatabase.cpp @@ -432,8 +432,8 @@ void CharacterDatabaseConnection::DoPrepareStatements() PrepareStatement(CHAR_UPD_GLOBAL_INSTANCE_RESETTIME, "UPDATE instance_reset SET resettime = ? WHERE mapid = ? AND difficulty = ?", CONNECTION_BOTH); PrepareStatement(CHAR_UPD_CHAR_ONLINE, "UPDATE characters SET online = 1 WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_UPD_CHAR_NAME_AT_LOGIN, "UPDATE characters set name = ?, at_login = ? WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_WORLDSTATE, "UPDATE worldstates SET value = ? WHERE entry = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_WORLDSTATE, "INSERT INTO worldstates (entry, value) VALUES (?, ?)", CONNECTION_ASYNC); + PrepareStatement(CHAR_REP_WORLD_STATE, "REPLACE INTO world_state_value (Id, Value) VALUES (?, ?)", CONNECTION_ASYNC); + PrepareStatement(CHAR_REP_WORLD_VARIABLE, "REPLACE INTO world_variable (Id, Value) VALUES (?, ?)", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_CHAR_INSTANCE_BY_INSTANCE_GUID, "DELETE FROM character_instance WHERE guid = ? AND instance = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_UPD_CHAR_INSTANCE, "UPDATE character_instance SET instance = ?, permanent = ?, extendState = ? WHERE guid = ? AND instance = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_INS_CHAR_INSTANCE, "INSERT INTO character_instance (guid, instance, permanent, extendState) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC); diff --git a/src/server/database/Database/Implementation/CharacterDatabase.h b/src/server/database/Database/Implementation/CharacterDatabase.h index 8585fa1370..db746cf3a5 100644 --- a/src/server/database/Database/Implementation/CharacterDatabase.h +++ b/src/server/database/Database/Implementation/CharacterDatabase.h @@ -356,8 +356,8 @@ enum CharacterDatabaseStatements : uint32 CHAR_UPD_GLOBAL_INSTANCE_RESETTIME, CHAR_UPD_CHAR_ONLINE, CHAR_UPD_CHAR_NAME_AT_LOGIN, - CHAR_UPD_WORLDSTATE, - CHAR_INS_WORLDSTATE, + CHAR_REP_WORLD_STATE, + CHAR_REP_WORLD_VARIABLE, CHAR_DEL_CHAR_INSTANCE_BY_INSTANCE_GUID, CHAR_UPD_CHAR_INSTANCE, CHAR_INS_CHAR_INSTANCE, diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index acb67adca8..b6c5d3f4bd 100644 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -2295,7 +2295,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) const } case CONDITION_WORLD_STATE: { - if (!sWorld->getWorldState(cond->ConditionValue1)) + if (!sWorldStateMgr->GetWorldStateTemplate(cond->ConditionValue1)) { TC_LOG_ERROR("sql.sql", "%s has non existing world state in value1 (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index ee6f1885db..174206c1c2 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -4446,19 +4446,7 @@ enum WorldState : uint32 WS_BATTLEFIELD_TB_EAST_INTACT_ALLIANCE = 5446, WS_BATTLEFIELD_TB_EAST_DAMAGED_ALLIANCE = 5447, WS_BATTLEFIELD_TB_EAST_INTACT_NEUTRAL = 5451, - WS_BATTLEFIELD_TB_EAST_DAMAGED_NEUTRAL = 5452, - - - WS_ARENA_DISTRIBUTION_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 - // Cata specific custom worldstates - WS_GUILD_WEEKLY_RESET_TIME = 20050, // Next guild week reset time - WS_CURRENCY_RESET_TIME = 20051, // Custom worldstate + WS_BATTLEFIELD_TB_EAST_DAMAGED_NEUTRAL = 5452 }; enum class PursuingType : uint8 diff --git a/src/server/game/Tools/CharacterDatabaseCleaner.cpp b/src/server/game/Tools/CharacterDatabaseCleaner.cpp index b55e33bd51..2e065a37b0 100644 --- a/src/server/game/Tools/CharacterDatabaseCleaner.cpp +++ b/src/server/game/Tools/CharacterDatabaseCleaner.cpp @@ -34,12 +34,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) @@ -60,7 +55,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 a90173bc05..cef66d6663 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -109,6 +109,22 @@ TC_GAME_API int32 World::m_visibility_notify_periodOnContinents = DEFAULT_VISIBI TC_GAME_API int32 World::m_visibility_notify_periodInInstances = DEFAULT_VISIBILITY_NOTIFY_PERIOD; TC_GAME_API int32 World::m_visibility_notify_periodInBGArenas = 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() { @@ -2132,11 +2148,11 @@ void World::SetInitialWorldSettings() TC_LOG_INFO("server.loading", "Loading Creature Formations..."); sFormationMgr->LoadCreatureFormations(); - TC_LOG_INFO("server.loading", "Loading World States..."); // must be loaded before battleground, outdoor PvP and conditions - LoadWorldStates(); - 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 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); @@ -3260,9 +3276,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) @@ -3299,7 +3315,7 @@ void World::ResetDailyQuestsAndRewards() 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."); } @@ -3345,7 +3361,7 @@ void World::ResetWeeklyQuestsAndRewards() 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."); } @@ -3381,7 +3397,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."); } @@ -3399,7 +3415,7 @@ void World::CheckQuestResetTimes() void World::InitRandomBGResetTime() { - time_t bgtime = uint64(sWorld->getWorldState(WS_BG_DAILY_RESET_TIME)); + time_t bgtime = sWorld->GetPersistentWorldVariable(NextBGRandomDailyResetTimeVarId); if (!bgtime) m_NextRandomBGReset = GameTime::GetGameTime(); // game time not yet init @@ -3422,12 +3438,12 @@ void World::InitRandomBGResetTime() m_NextRandomBGReset = bgtime < curTime ? nextDayResetTime - DAY : nextDayResetTime; if (!bgtime) - sWorld->setWorldState(WS_BG_DAILY_RESET_TIME, uint64(m_NextRandomBGReset)); + sWorld->SetPersistentWorldVariable(NextBGRandomDailyResetTimeVarId, uint32(m_NextRandomBGReset)); } void World::InitGuildResetTime() { - time_t gtime = uint64(getWorldState(WS_GUILD_DAILY_RESET_TIME)); + time_t gtime = GetPersistentWorldVariable(NextGuildDailyResetTimeVarId); if (!gtime) m_NextGuildReset = GameTime::GetGameTime(); // game time not yet init @@ -3450,12 +3466,12 @@ void World::InitGuildResetTime() m_NextGuildReset = gtime < curTime ? nextDayResetTime - DAY : nextDayResetTime; if (!gtime) - sWorld->setWorldState(WS_GUILD_DAILY_RESET_TIME, uint64(m_NextGuildReset)); + sWorld->SetPersistentWorldVariable(NextGuildDailyResetTimeVarId, uint32(m_NextGuildReset)); } void World::InitCurrencyResetTime() { - time_t currencytime = uint64(sWorld->getWorldState(WS_CURRENCY_RESET_TIME)); + time_t currencytime = sWorld->GetPersistentWorldVariable(NextCurrencyResetTimeVarId); if (!currencytime) m_NextCurrencyReset = GameTime::GetGameTime(); // game time not yet init @@ -3479,7 +3495,7 @@ void World::InitCurrencyResetTime() m_NextCurrencyReset = currencytime < curTime ? nextWeekResetTime - getIntConfig(CONFIG_CURRENCY_RESET_INTERVAL) * DAY : nextWeekResetTime; if (!currencytime) - sWorld->setWorldState(WS_CURRENCY_RESET_TIME, uint64(m_NextCurrencyReset)); + sWorld->SetPersistentWorldVariable(NextCurrencyResetTimeVarId, uint32(m_NextCurrencyReset)); } void World::ResetCurrencyWeekCap() @@ -3491,7 +3507,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, uint64(m_NextCurrencyReset)); + sWorld->SetPersistentWorldVariable(NextCurrencyResetTimeVarId, uint32(m_NextCurrencyReset)); } void World::LoadDBAllowedSecurityLevel() @@ -3539,18 +3555,18 @@ void World::ResetRandomBG() itr->second->GetPlayer()->SetRandomWinner(false); m_NextRandomBGReset = time_t(m_NextRandomBGReset + DAY); - sWorld->setWorldState(WS_BG_DAILY_RESET_TIME, uint64(m_NextRandomBGReset)); + sWorld->SetPersistentWorldVariable(NextBGRandomDailyResetTimeVarId, uint32(m_NextRandomBGReset)); } void World::PerformDailyGuildActions() { m_NextGuildReset = time_t(m_NextGuildReset + DAY); - sWorld->setWorldState(WS_GUILD_DAILY_RESET_TIME, uint64(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); sGuildMgr->ClearExpiredGuildNews(); @@ -3589,32 +3605,6 @@ void World::UpdateAreaDependentAuras() } } -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); @@ -3625,38 +3615,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, uint64 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); - - stmt->setUInt32(0, uint32(value)); - stmt->setUInt32(1, index); - - CharacterDatabase.Execute(stmt); - } - else - { - CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_WORLDSTATE); - - stmt->setUInt32(0, index); - stmt->setUInt32(1, uint32(value)); - - CharacterDatabase.Execute(stmt); - } - m_worldstates[index] = value; + return 0; } -uint64 World::getWorldState(uint32 index) const +void World::SetPersistentWorldVariable(PersistentWorldVariable const& var, int32 value) { - WorldStatesMap::const_iterator it = m_worldstates.find(index); - return it != m_worldstates.end() ? it->second : 0; + m_worldVariables[var.Id] = value; + + CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_WORLD_VARIABLE); + stmt->setString(0, var.Id); + stmt->setInt32(1, value); + CharacterDatabase.Execute(stmt); +} + +void World::LoadPersistentWorldVariables() +{ + uint32 oldMSTime = getMSTime(); + + 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()); + } + + TC_LOG_INFO("server.loading", ">> Loaded " SZFMTD " world variables in %u ms", m_worldVariables.size(), GetMSTimeDiffToNow(oldMSTime)); } void World::ProcessQueryCallbacks() diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index 0d43877776..c947d21fe7 100644 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -552,6 +552,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 { @@ -744,9 +746,19 @@ class TC_GAME_API World return index < INT_CONFIG_VALUE_COUNT ? m_int_configs[index] : 0; } - void setWorldState(uint32 index, uint64 value); - uint64 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; @@ -848,8 +860,7 @@ class TC_GAME_API World uint32 m_int_configs[INT_CONFIG_VALUE_COUNT]; bool m_bool_configs[BOOL_CONFIG_VALUE_COUNT]; float m_float_configs[FLOAT_CONFIG_VALUE_COUNT]; - typedef std::map WorldStatesMap; - WorldStatesMap m_worldstates; + std::unordered_map 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 b220ae1b30..5b668ce942 100644 --- a/src/server/game/World/WorldStates/WorldStateMgr.cpp +++ b/src/server/game/World/WorldStates/WorldStateMgr.cpp @@ -58,14 +58,14 @@ void WorldStateMgr::LoadFromDB() uint32 mapId = atoul(*itr); if (!mapId) { - TC_LOG_ERROR("sql.sql", "Table `world_state` contains a world state %u with non-integer MapID (%s), map ignored", + TC_LOG_ERROR("sql.sql", "Table `world_state` contains a world state %d with non-integer MapID (%s), map ignored", id, *itr); 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; } @@ -75,7 +75,7 @@ void WorldStateMgr::LoadFromDB() if (i > 0 && worldState.MapIds.empty()) { - TC_LOG_ERROR("sql.sql", "Table `world_state` contains a world state %u with nonempty MapIDs but no valid map id was found, ignored", + TC_LOG_ERROR("sql.sql", "Table `world_state` contains a world state %d with nonempty MapIDs but no valid map id was found, ignored", id); continue; } @@ -89,7 +89,7 @@ void WorldStateMgr::LoadFromDB() uint32 areaId = atoul(*itr); if (!areaId) { - TC_LOG_ERROR("sql.sql", "Table `world_state` contains a world state %u with non-integer AreaID, area ignored", + TC_LOG_ERROR("sql.sql", "Table `world_state` contains a world state %d with non-integer AreaID, area ignored", id); 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,7 +114,7 @@ void WorldStateMgr::LoadFromDB() if (i > 0 && worldState.AreaIds.empty()) { - TC_LOG_ERROR("sql.sql", "Table `world_state` contains a world state %u with nonempty AreaIDs but no valid area id was found, ignored", + TC_LOG_ERROR("sql.sql", "Table `world_state` contains a world state %d with nonempty AreaIDs but no valid area id was found, ignored", id); continue; } @@ -138,6 +138,39 @@ 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 +225,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 d17cdb4031..17a3f7920e 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; diff --git a/src/server/scripts/Battlefield/BattlefieldTB.cpp b/src/server/scripts/Battlefield/BattlefieldTB.cpp index 694927f528..a13cc535bb 100644 --- a/src/server/scripts/Battlefield/BattlefieldTB.cpp +++ b/src/server/scripts/Battlefield/BattlefieldTB.cpp @@ -296,36 +296,35 @@ bool BattlefieldTB::SetupBattlefield() m_Data32.resize(BATTLEFIELD_TB_DATA_MAX); - m_saveTimer = 5 * MINUTE * IN_MILLISECONDS; - updatedNPCAndObjects = true; m_updateObjectsTimer = 0; // Was there a battle going on or time isn't set yet? Then use m_RestartAfterCrash - if (sWorld->getWorldState(WS_BATTLEFIELD_TB_STATE_BATTLE) == 1 || sWorld->getWorldState(WS_BATTLEFIELD_TB_TIME_NEXT_BATTLE) == 0) - sWorld->setWorldState(WS_BATTLEFIELD_TB_TIME_NEXT_BATTLE, m_RestartAfterCrash); + if (sWorldStateMgr->GetValue(WS_BATTLEFIELD_TB_STATE_BATTLE, m_Map) == 1 || sWorldStateMgr->GetValue(WS_BATTLEFIELD_TB_TIME_NEXT_BATTLE, m_Map) < GameTime::GetGameTime()) + { + sWorldStateMgr->SetValueAndSaveInDb(WS_BATTLEFIELD_TB_STATE_BATTLE, 0, false, m_Map); + sWorldStateMgr->SetValue(WS_BATTLEFIELD_TB_TIME_NEXT_BATTLE, GameTime::GetGameTime() + m_RestartAfterCrash / IN_MILLISECONDS, false, m_Map); + } // Set timer - m_Timer = sWorld->getWorldState(WS_BATTLEFIELD_TB_TIME_NEXT_BATTLE); + m_Timer = sWorldStateMgr->GetValue(WS_BATTLEFIELD_TB_TIME_NEXT_BATTLE, m_Map) - GameTime::GetGameTime(); // Defending team isn't set yet? Choose randomly. - if (sWorld->getWorldState(WS_BATTLEFIELD_TB_FACTION_CONTROLLING) == 0) - sWorld->setWorldState(WS_BATTLEFIELD_TB_FACTION_CONTROLLING, uint32(urand(1, 2))); + if (sWorldStateMgr->GetValue(WS_BATTLEFIELD_TB_FACTION_CONTROLLING, m_Map) == 0) + sWorldStateMgr->SetValue(WS_BATTLEFIELD_TB_FACTION_CONTROLLING, uint32(urand(1, 2)), false, m_Map); // Set defender team - SetDefenderTeam(TeamId(sWorld->getWorldState(WS_BATTLEFIELD_TB_FACTION_CONTROLLING) - 1)); + SetDefenderTeam(TeamId(sWorldStateMgr->GetValue(WS_BATTLEFIELD_TB_FACTION_CONTROLLING, m_Map) - 1)); sWorldStateMgr->SetValue(WS_BATTLEFIELD_TB_TIME_NEXT_BATTLE_SHOW, 1, false, m_Map); - sWorldStateMgr->SetValue(WS_BATTLEFIELD_TB_TIME_NEXT_BATTLE, GameTime::GetGameTime() + m_Timer / IN_MILLISECONDS, false, m_Map); + sWorldStateMgr->SetValueAndSaveInDb(WS_BATTLEFIELD_TB_TIME_NEXT_BATTLE, GameTime::GetGameTime() + m_Timer / IN_MILLISECONDS, false, m_Map); - sWorldStateMgr->SetValue(WS_BATTLEFIELD_TB_FACTION_CONTROLLING, GetDefenderTeam() + 1, false, m_Map); + sWorldStateMgr->SetValueAndSaveInDb(WS_BATTLEFIELD_TB_FACTION_CONTROLLING, GetDefenderTeam() + 1, false, m_Map); sWorldStateMgr->SetValue(WS_BATTLEFIELD_TB_ALLIANCE_CONTROLS_SHOW, GetDefenderTeam() == TEAM_ALLIANCE ? 1 : 0, false, m_Map); sWorldStateMgr->SetValue(WS_BATTLEFIELD_TB_HORDE_CONTROLS_SHOW, GetDefenderTeam() == TEAM_HORDE ? 1 : 0, false, m_Map); sWorldStateMgr->SetValue(WS_BATTLEFIELD_TB_KEEP_ALLIANCE, GetDefenderTeam() == TEAM_ALLIANCE ? 1 : 0, false, m_Map); sWorldStateMgr->SetValue(WS_BATTLEFIELD_TB_KEEP_HORDE, GetDefenderTeam() == TEAM_HORDE ? 1 : 0, false, m_Map); - SaveWorldStateValues(); - // Create capture points for (uint8 i = 0; i < TB_BASE_COUNT; i++) { @@ -411,14 +410,6 @@ bool BattlefieldTB::Update(uint32 diff) m_updateObjectsTimer -= diff; } - if (m_saveTimer <= diff) - { - SaveWorldStateValues(); - m_saveTimer = 60 * IN_MILLISECONDS; - } - else - m_saveTimer -= diff; - return m_return; } @@ -462,13 +453,6 @@ void BattlefieldTB::RemoveAurasFromPlayer(Player* player) player->RemoveAurasDueToSpell(SPELL_TB_SPIRITUAL_IMMUNITY); } -void BattlefieldTB::SaveWorldStateValues() -{ - sWorld->setWorldState(WS_BATTLEFIELD_TB_FACTION_CONTROLLING, uint32(GetDefenderTeam())); - sWorld->setWorldState(WS_BATTLEFIELD_TB_STATE_BATTLE, uint32(IsWarTime() ? 1 : 0)); - sWorld->setWorldState(WS_BATTLEFIELD_TB_TIME_NEXT_BATTLE, uint32(!IsWarTime() ? m_Timer : 0)); -} - void BattlefieldTB::OnStartGrouping() { UpdateNPCsAndGameObjects(); @@ -495,7 +479,7 @@ void BattlefieldTB::OnBattleStart() sWorldStateMgr->SetValue(WS_BATTLEFIELD_TB_TIME_BATTLE_END, GameTime::GetGameTime() + m_Timer / IN_MILLISECONDS, false, m_Map); sWorldStateMgr->SetValue(WS_BATTLEFIELD_TB_TIME_NEXT_BATTLE_SHOW, 0, false, m_Map); - sWorldStateMgr->SetValue(WS_BATTLEFIELD_TB_TIME_NEXT_BATTLE, 0, false, m_Map); + sWorldStateMgr->SetValueAndSaveInDb(WS_BATTLEFIELD_TB_TIME_NEXT_BATTLE, 0, false, m_Map); sWorldStateMgr->SetValue(WS_BATTLEFIELD_TB_ALLIANCE_ATTACKING_SHOW, GetAttackerTeam() == TEAM_ALLIANCE ? 1 : 0, false, m_Map); sWorldStateMgr->SetValue(WS_BATTLEFIELD_TB_HORDE_ATTACKING_SHOW, GetAttackerTeam() == TEAM_HORDE ? 1 : 0, false, m_Map); @@ -510,7 +494,7 @@ void BattlefieldTB::OnBattleStart() sWorldStateMgr->SetValue(WS_BATTLEFIELD_TB_TOWERS_DESTROYED, 0, false, m_Map); sWorldStateMgr->SetValue(WS_BATTLEFIELD_TB_STATE_PREPARATIONS, 0, false, m_Map); - sWorldStateMgr->SetValue(WS_BATTLEFIELD_TB_STATE_BATTLE, 1, false, m_Map); + sWorldStateMgr->SetValueAndSaveInDb(WS_BATTLEFIELD_TB_STATE_BATTLE, 1, false, m_Map); // Towers/spires for (uint8 i = 0; i < TB_TOWERS_COUNT; i++) @@ -561,12 +545,12 @@ void BattlefieldTB::OnBattleEnd(bool endByTimer) sWorldStateMgr->SetValue(WS_BATTLEFIELD_TB_TIME_BATTLE_END, 0, false, m_Map); sWorldStateMgr->SetValue(WS_BATTLEFIELD_TB_TIME_NEXT_BATTLE_SHOW, 1, false, m_Map); - sWorldStateMgr->SetValue(WS_BATTLEFIELD_TB_TIME_NEXT_BATTLE, GameTime::GetGameTime() + m_NoWarBattleTime / IN_MILLISECONDS, false, m_Map); + sWorldStateMgr->SetValueAndSaveInDb(WS_BATTLEFIELD_TB_TIME_NEXT_BATTLE, GameTime::GetGameTime() + m_NoWarBattleTime / IN_MILLISECONDS, false, m_Map); sWorldStateMgr->SetValue(WS_BATTLEFIELD_TB_ALLIANCE_ATTACKING_SHOW, 0, false, m_Map); sWorldStateMgr->SetValue(WS_BATTLEFIELD_TB_HORDE_ATTACKING_SHOW, 0, false, m_Map); - sWorldStateMgr->SetValue(WS_BATTLEFIELD_TB_FACTION_CONTROLLING, GetDefenderTeam() + 1, false, m_Map); + sWorldStateMgr->SetValueAndSaveInDb(WS_BATTLEFIELD_TB_FACTION_CONTROLLING, GetDefenderTeam() + 1, false, m_Map); sWorldStateMgr->SetValue(WS_BATTLEFIELD_TB_ALLIANCE_CONTROLS_SHOW, GetDefenderTeam() == TEAM_ALLIANCE ? 1 : 0, false, m_Map); sWorldStateMgr->SetValue(WS_BATTLEFIELD_TB_HORDE_CONTROLS_SHOW, GetDefenderTeam() == TEAM_HORDE ? 1 : 0, false, m_Map); sWorldStateMgr->SetValue(WS_BATTLEFIELD_TB_KEEP_ALLIANCE, GetDefenderTeam() == TEAM_ALLIANCE ? 1 : 0, false, m_Map); @@ -574,7 +558,7 @@ void BattlefieldTB::OnBattleEnd(bool endByTimer) sWorldStateMgr->SetValue(WS_BATTLEFIELD_TB_BUILDINGS_CAPTURED_SHOW, 0, false, m_Map); - sWorldStateMgr->SetValue(WS_BATTLEFIELD_TB_STATE_BATTLE, 0, false, m_Map); + sWorldStateMgr->SetValueAndSaveInDb(WS_BATTLEFIELD_TB_STATE_BATTLE, 0, false, m_Map); } void BattlefieldTB::UpdateNPCsAndGameObjects() diff --git a/src/server/scripts/Battlefield/BattlefieldTB.h b/src/server/scripts/Battlefield/BattlefieldTB.h index 693da1a718..79ae6c986c 100644 --- a/src/server/scripts/Battlefield/BattlefieldTB.h +++ b/src/server/scripts/Battlefield/BattlefieldTB.h @@ -372,8 +372,6 @@ class BattlefieldTB : public Battlefield bool SetupBattlefield() override; - void SaveWorldStateValues(); - void HandleKill(Player* killer, Unit* victim) override; //void OnUnitDeath(Unit* unit) override; void PromotePlayer(Player* killer); @@ -395,8 +393,6 @@ class BattlefieldTB : public Battlefield bool warnedTwoMinutes; bool warnedOneMinute; - uint32 m_saveTimer; - bool updatedNPCAndObjects; uint32 m_updateObjectsTimer; diff --git a/src/server/scripts/Battlefield/BattlefieldWG.cpp b/src/server/scripts/Battlefield/BattlefieldWG.cpp index 7189b142dc..54e05f31a6 100644 --- a/src/server/scripts/Battlefield/BattlefieldWG.cpp +++ b/src/server/scripts/Battlefield/BattlefieldWG.cpp @@ -439,45 +439,30 @@ bool BattlefieldWG::SetupBattlefield() m_Data32.resize(BATTLEFIELD_WG_DATA_MAX); - m_saveTimer = 60000; - // Init Graveyards SetGraveyardNumber(BATTLEFIELD_WG_GRAVEYARD_MAX); // Load from db - if (sWorld->getWorldState(WS_BATTLEFIELD_WG_SHOW_TIME_NEXT_BATTLE) == 0 - && sWorld->getWorldState(WS_BATTLEFIELD_WG_DEFENDER) == 0 - && sWorld->getWorldState(ClockWorldState[0]) == 0) + if (sWorldStateMgr->GetValue(WS_BATTLEFIELD_WG_SHOW_TIME_NEXT_BATTLE, m_Map) == 0 + && sWorldStateMgr->GetValue(ClockWorldState[0], m_Map) < GameTime::GetGameTime()) { - sWorld->setWorldState(WS_BATTLEFIELD_WG_SHOW_TIME_NEXT_BATTLE, 0); - sWorld->setWorldState(WS_BATTLEFIELD_WG_DEFENDER, urand(0, 1)); - sWorld->setWorldState(ClockWorldState[0], m_NoWarBattleTime); + sWorldStateMgr->SetValueAndSaveInDb(WS_BATTLEFIELD_WG_SHOW_TIME_NEXT_BATTLE, 0, false, m_Map); + sWorldStateMgr->SetValueAndSaveInDb(WS_BATTLEFIELD_WG_DEFENDER, urand(0, 1), false, m_Map); + sWorldStateMgr->SetValueAndSaveInDb(ClockWorldState[0], GameTime::GetGameTime() + m_NoWarBattleTime / IN_MILLISECONDS, false, m_Map); } - m_isActive = sWorld->getWorldState(WS_BATTLEFIELD_WG_SHOW_TIME_NEXT_BATTLE) == 0; - m_DefenderTeam = TeamId(sWorld->getWorldState(WS_BATTLEFIELD_WG_DEFENDER)); + m_isActive = sWorldStateMgr->GetValue(WS_BATTLEFIELD_WG_SHOW_TIME_NEXT_BATTLE, m_Map) == 0; + m_DefenderTeam = TeamId(sWorldStateMgr->GetValue(WS_BATTLEFIELD_WG_DEFENDER, m_Map)); - m_Timer = sWorld->getWorldState(ClockWorldState[0]); + m_Timer = sWorldStateMgr->GetValue(ClockWorldState[0], m_Map) - GameTime::GetGameTime(); if (m_isActive) { m_isActive = false; m_Timer = m_RestartAfterCrash; } - auto loadSavedWorldState = [&](int32 id) - { - sWorldStateMgr->SetValue(id, sWorld->getWorldState(id), false, m_Map); - }; - - loadSavedWorldState(WS_BATTLEFIELD_WG_SHOW_TIME_NEXT_BATTLE); - loadSavedWorldState(WS_BATTLEFIELD_WG_DEFENDER); sWorldStateMgr->SetValue(WS_BATTLEFIELD_WG_ATTACKER, GetAttackerTeam(), false, m_Map); - sWorldStateMgr->SetValue(ClockWorldState[0], GameTime::GetGameTime() + m_Timer / IN_MILLISECONDS, false, m_Map); sWorldStateMgr->SetValue(ClockWorldState[1], GameTime::GetGameTime() + m_Timer / IN_MILLISECONDS, false, m_Map); - loadSavedWorldState(WS_BATTLEFIELD_WG_ATTACKED_A); - loadSavedWorldState(WS_BATTLEFIELD_WG_DEFENDED_A); - loadSavedWorldState(WS_BATTLEFIELD_WG_ATTACKED_H); - loadSavedWorldState(WS_BATTLEFIELD_WG_DEFENDED_H); for (uint8 i = 0; i < BATTLEFIELD_WG_GRAVEYARD_MAX; i++) { @@ -554,31 +539,6 @@ bool BattlefieldWG::SetupBattlefield() return true; } -bool BattlefieldWG::Update(uint32 diff) -{ - bool m_return = Battlefield::Update(diff); - if (m_saveTimer <= diff) - { - auto saveWorldState = [&](int32 id) - { - sWorld->setWorldState(id, sWorldStateMgr->GetValue(id, m_Map)); - }; - - sWorld->setWorldState(WS_BATTLEFIELD_WG_SHOW_TIME_NEXT_BATTLE, !m_isActive); - sWorld->setWorldState(WS_BATTLEFIELD_WG_DEFENDER, m_DefenderTeam); - sWorld->setWorldState(ClockWorldState[0], m_Timer); - saveWorldState(WS_BATTLEFIELD_WG_ATTACKED_A); - saveWorldState(WS_BATTLEFIELD_WG_DEFENDED_A); - saveWorldState(WS_BATTLEFIELD_WG_ATTACKED_H); - saveWorldState(WS_BATTLEFIELD_WG_DEFENDED_H); - m_saveTimer = 60 * IN_MILLISECONDS; - } - else - m_saveTimer -= diff; - - return m_return; -} - void BattlefieldWG::OnBattleStart() { // Spawn titan relic @@ -594,10 +554,10 @@ void BattlefieldWG::OnBattleStart() TC_LOG_ERROR("bg.battlefield", "WG: Failed to spawn titan relic."); sWorldStateMgr->SetValue(WS_BATTLEFIELD_WG_ATTACKER, GetAttackerTeam(), false, m_Map); - sWorldStateMgr->SetValue(WS_BATTLEFIELD_WG_DEFENDER, GetDefenderTeam(), false, m_Map); - sWorldStateMgr->SetValue(WS_BATTLEFIELD_WG_SHOW_TIME_NEXT_BATTLE, 0, false, m_Map); + sWorldStateMgr->SetValueAndSaveInDb(WS_BATTLEFIELD_WG_DEFENDER, GetDefenderTeam(), false, m_Map); + sWorldStateMgr->SetValueAndSaveInDb(WS_BATTLEFIELD_WG_SHOW_TIME_NEXT_BATTLE, 0, false, m_Map); sWorldStateMgr->SetValue(WS_BATTLEFIELD_WG_SHOW_TIME_BATTLE_END, 1, false, m_Map); - sWorldStateMgr->SetValue(ClockWorldState[0], GameTime::GetGameTime() + m_Timer / IN_MILLISECONDS, false, m_Map); + sWorldStateMgr->SetValueAndSaveInDb(ClockWorldState[0], GameTime::GetGameTime() + m_Timer / IN_MILLISECONDS, false, m_Map); // Update tower visibility and update faction for (auto itr = CanonList.begin(); itr != CanonList.end(); ++itr) @@ -685,11 +645,11 @@ void BattlefieldWG::OnBattleEnd(bool endByTimer) else worldStateId = GetDefenderTeam() == TEAM_HORDE ? WS_BATTLEFIELD_WG_ATTACKED_H : WS_BATTLEFIELD_WG_ATTACKED_A; - sWorldStateMgr->SetValue(worldStateId, sWorldStateMgr->GetValue(worldStateId, m_Map) + 1, false, m_Map); + sWorldStateMgr->SetValueAndSaveInDb(worldStateId, sWorldStateMgr->GetValue(worldStateId, m_Map) + 1, false, m_Map); } - sWorldStateMgr->SetValue(WS_BATTLEFIELD_WG_SHOW_TIME_NEXT_BATTLE, 1, false, m_Map); - sWorldStateMgr->SetValue(WS_BATTLEFIELD_WG_SHOW_TIME_BATTLE_END, 0, false, m_Map); + sWorldStateMgr->SetValueAndSaveInDb(WS_BATTLEFIELD_WG_DEFENDER, GetDefenderTeam(), false, m_Map); + sWorldStateMgr->SetValueAndSaveInDb(WS_BATTLEFIELD_WG_SHOW_TIME_NEXT_BATTLE, 1, false, m_Map); sWorldStateMgr->SetValue(ClockWorldState[1], GameTime::GetGameTime() + m_Timer / IN_MILLISECONDS, false, m_Map); // Remove turret @@ -717,13 +677,6 @@ void BattlefieldWG::OnBattleEnd(bool endByTimer) if (GameObject* portal = GetGameObject(*itr)) portal->SetRespawnTime(RESPAWN_ONE_DAY); - // Saving data - for (BfWGGameObjectBuilding* building : BuildingsInZone) - building->Save(); - - for (WintergraspWorkshop* workshop : Workshops) - workshop->Save(); - for (auto itr = m_PlayersInWar[GetDefenderTeam()].begin(); itr != m_PlayersInWar[GetDefenderTeam()].end(); ++itr) { if (Player* player = ObjectAccessor::FindPlayer(*itr)) @@ -1411,7 +1364,7 @@ void BfWGGameObjectBuilding::Rebuild() // Update worldstate _state = WintergraspGameObjectState(BATTLEFIELD_WG_OBJECTSTATE_ALLIANCE_INTACT - (_teamControl * 3)); - sWorldStateMgr->SetValue(_worldState, _state, false, _wg->GetMap()); + sWorldStateMgr->SetValueAndSaveInDb(_worldState, _state, false, _wg->GetMap()); } UpdateCreatureAndGo(); build->SetFaction(WintergraspFaction[_teamControl]); @@ -1422,7 +1375,7 @@ void BfWGGameObjectBuilding::Damaged() { // Update worldstate _state = WintergraspGameObjectState(BATTLEFIELD_WG_OBJECTSTATE_ALLIANCE_DAMAGE - (_teamControl * 3)); - sWorldStateMgr->SetValue(_worldState, _state, false, _wg->GetMap()); + sWorldStateMgr->SetValueAndSaveInDb(_worldState, _state, false, _wg->GetMap()); // Send warning message if (_staticTowerInfo) @@ -1446,7 +1399,7 @@ void BfWGGameObjectBuilding::Destroyed() { // Update worldstate _state = WintergraspGameObjectState(BATTLEFIELD_WG_OBJECTSTATE_ALLIANCE_DESTROY - (_teamControl * 3)); - sWorldStateMgr->SetValue(_worldState, _state, false, _wg->GetMap()); + sWorldStateMgr->SetValueAndSaveInDb(_worldState, _state, false, _wg->GetMap()); // Warn players if (_staticTowerInfo) @@ -1500,8 +1453,7 @@ void BfWGGameObjectBuilding::Init(GameObject* go) break; } - _state = WintergraspGameObjectState(sWorld->getWorldState(_worldState)); - sWorldStateMgr->SetValue(_worldState, _state, false, _wg->GetMap()); + _state = WintergraspGameObjectState(sWorldStateMgr->GetValue(_worldState, _wg->GetMap())); switch (_state) { case BATTLEFIELD_WG_OBJECTSTATE_NEUTRAL_INTACT: @@ -1719,11 +1671,6 @@ void BfWGGameObjectBuilding::UpdateTurretAttack(bool disable) } } -void BfWGGameObjectBuilding::Save() -{ - sWorld->setWorldState(_worldState, _state); -} - WintergraspWorkshop::WintergraspWorkshop(BattlefieldWG* wg, uint8 type) { ASSERT(wg && type < WG_MAX_WORKSHOP); @@ -1754,7 +1701,7 @@ void WintergraspWorkshop::GiveControlTo(TeamId teamId, bool init /*= false*/) { // Updating worldstate _state = BATTLEFIELD_WG_OBJECTSTATE_ALLIANCE_INTACT; - sWorldStateMgr->SetValue(_staticInfo->WorldStateId, _state, false, _wg->GetMap()); + sWorldStateMgr->SetValueAndSaveInDb(_staticInfo->WorldStateId, _state, false, _wg->GetMap()); // Warning message if (!init) @@ -1772,7 +1719,7 @@ void WintergraspWorkshop::GiveControlTo(TeamId teamId, bool init /*= false*/) { // Update worldstate _state = BATTLEFIELD_WG_OBJECTSTATE_HORDE_INTACT; - sWorldStateMgr->SetValue(_staticInfo->WorldStateId, _state, false, _wg->GetMap()); + sWorldStateMgr->SetValueAndSaveInDb(_staticInfo->WorldStateId, _state, false, _wg->GetMap()); // Warning message if (!init) @@ -1799,11 +1746,6 @@ void WintergraspWorkshop::UpdateGraveyardAndWorkshop() GiveControlTo(_wg->GetDefenderTeam(), true); } -void WintergraspWorkshop::Save() -{ - sWorld->setWorldState(_staticInfo->WorldStateId, _state); -} - class Battlefield_wintergrasp : public BattlefieldScript { public: diff --git a/src/server/scripts/Battlefield/BattlefieldWG.h b/src/server/scripts/Battlefield/BattlefieldWG.h index 9fb966546e..4f2b816dbe 100644 --- a/src/server/scripts/Battlefield/BattlefieldWG.h +++ b/src/server/scripts/Battlefield/BattlefieldWG.h @@ -266,14 +266,6 @@ class BattlefieldWG : public Battlefield */ void OnPlayerEnterZone(Player* player) override; - /** - * \brief Called for update battlefield data - * - Save battle timer in database every minutes - * - Update imunity aura from graveyard - * \param diff : time elapsed since the last call (in ms) - */ - bool Update(uint32 diff) override; - /** * \brief Called when a creature is created * - Update vehicle count @@ -362,7 +354,6 @@ class BattlefieldWG : public Battlefield TeamId m_tenacityTeam; uint32 m_tenacityStack; - uint32 m_saveTimer; ObjectGuid m_titansRelicGUID; }; @@ -539,8 +530,6 @@ public: void UpdateCreatureAndGo(); void UpdateTurretAttack(bool disable); - - void Save(); }; // Structure for the 6 workshop @@ -564,8 +553,6 @@ public: void GiveControlTo(TeamId teamId, bool init = false); void UpdateGraveyardAndWorkshop(); - - void Save(); }; #endif