diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Achievements/AchievementMgr.cpp | 14 | ||||
-rw-r--r-- | src/server/game/Achievements/AchievementMgr.h | 2 | ||||
-rw-r--r-- | src/server/game/BattleGrounds/BattleGroundMgr.cpp | 5 | ||||
-rw-r--r-- | src/server/game/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/server/game/Chat/Chat.cpp | 4 | ||||
-rw-r--r-- | src/server/game/Chat/Chat.h | 5 | ||||
-rw-r--r-- | src/server/game/Chat/Commands/Level3.cpp | 112 | ||||
-rw-r--r-- | src/server/game/Conditions/DisableMgr.cpp | 254 | ||||
-rw-r--r-- | src/server/game/Conditions/DisableMgr.h | 56 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 29 | ||||
-rw-r--r-- | src/server/game/Globals/ObjectMgr.cpp | 51 | ||||
-rw-r--r-- | src/server/game/Globals/ObjectMgr.h | 9 | ||||
-rw-r--r-- | src/server/game/Server/Protocol/Handlers/BattleGroundHandler.cpp | 13 | ||||
-rw-r--r-- | src/server/game/Spells/Spell.cpp | 30 | ||||
-rw-r--r-- | src/server/game/Spells/SpellMgr.h | 6 | ||||
-rw-r--r-- | src/server/game/World/World.cpp | 24 | ||||
-rw-r--r-- | src/server/game/World/World.h | 3 | ||||
-rw-r--r-- | src/server/worldserver/worldserver.conf.dist | 8 |
18 files changed, 371 insertions, 255 deletions
diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp index bb156c40ca6..c3217a5df02 100644 --- a/src/server/game/Achievements/AchievementMgr.cpp +++ b/src/server/game/Achievements/AchievementMgr.cpp @@ -34,6 +34,7 @@ #include "Player.h" #include "ProgressBar.h" #include "SpellMgr.h" +#include "DisableMgr.h" #include "MapManager.h" #include "BattleGround.h" @@ -107,7 +108,6 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria) { case ACHIEVEMENT_CRITERIA_DATA_TYPE_NONE: case ACHIEVEMENT_CRITERIA_DATA_TYPE_VALUE: - case ACHIEVEMENT_CRITERIA_DATA_TYPE_DISABLED: case ACHIEVEMENT_CRITERIA_DATA_INSTANCE_SCRIPT: return true; case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_CREATURE: @@ -305,8 +305,6 @@ bool AchievementCriteriaData::Meets(uint32 criteria_id, Player const* source, Un if (!target) return false; return target->getGender() == gender.gender; - case ACHIEVEMENT_CRITERIA_DATA_TYPE_DISABLED: - return false; // always fail case ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_DIFFICULTY: return source->GetMap()->GetSpawnMode() == difficulty.difficulty; case ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_PLAYER_COUNT: @@ -715,6 +713,8 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui for (AchievementCriteriaEntryList::const_iterator i = achievementCriteriaList.begin(); i != achievementCriteriaList.end(); ++i) { AchievementCriteriaEntry const *achievementCriteria = (*i); + if (sDisableMgr.IsDisabledFor(DISABLE_TYPE_ACHIEVEMENT_CRITERIA, achievementCriteria->ID, NULL)) + continue; AchievementEntry const *achievement = sAchievementStore.LookupEntry(achievementCriteria->referredAchievement); if (!achievement) @@ -2084,7 +2084,6 @@ void AchievementGlobalMgr::LoadAchievementCriteriaData() } uint32 count = 0; - uint32 disabled_count = 0; barGoLink bar(result->GetRowCount()); do { @@ -2111,9 +2110,6 @@ void AchievementGlobalMgr::LoadAchievementCriteriaData() AchievementCriteriaDataSet& dataSet = m_criteriaDataMap[criteria_id]; dataSet.SetCriteriaId(criteria_id); - if (data.dataType == ACHIEVEMENT_CRITERIA_DATA_TYPE_DISABLED) - ++disabled_count; - // add real data only for not NONE data types if (data.dataType != ACHIEVEMENT_CRITERIA_DATA_TYPE_NONE) dataSet.Add(data); @@ -2193,12 +2189,12 @@ void AchievementGlobalMgr::LoadAchievementCriteriaData() continue; } - if (!GetCriteriaDataSet(criteria)) + if (!GetCriteriaDataSet(criteria) && !sDisableMgr.IsDisabledFor(DISABLE_TYPE_ACHIEVEMENT_CRITERIA, entryId, NULL)) sLog.outErrorDb("Table `achievement_criteria_data` does not have expected data for criteria (Entry: %u Type: %u) for achievement %u.", criteria->ID, criteria->requiredType, criteria->referredAchievement); } sLog.outString(); - sLog.outString(">> Loaded %u additional achievement criteria data (%u disabled).",count,disabled_count); + sLog.outString(">> Loaded %u additional achievement criteria data.",count); } void AchievementGlobalMgr::LoadCompletedAchievements() diff --git a/src/server/game/Achievements/AchievementMgr.h b/src/server/game/Achievements/AchievementMgr.h index 0eedf971c20..3da9b7a6024 100644 --- a/src/server/game/Achievements/AchievementMgr.h +++ b/src/server/game/Achievements/AchievementMgr.h @@ -53,7 +53,7 @@ enum AchievementCriteriaDataType ACHIEVEMENT_CRITERIA_DATA_TYPE_VALUE = 8, // minvalue value provided with achievement update must be not less that limit ACHIEVEMENT_CRITERIA_DATA_TYPE_T_LEVEL = 9, // minlevel minlevel of target ACHIEVEMENT_CRITERIA_DATA_TYPE_T_GENDER = 10,// gender 0=male; 1=female - ACHIEVEMENT_CRITERIA_DATA_TYPE_DISABLED = 11,// used to prevent achievement creteria complete if not all requirement implemented and listed in table + ACHIEVEMENT_CRITERIA_DATA_TYPE_REUSE = 11,// TO BE REUSED ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_DIFFICULTY = 12,// difficulty normal/heroic difficulty for current event map ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_PLAYER_COUNT = 13,// count "with less than %u people in the zone" ACHIEVEMENT_CRITERIA_DATA_TYPE_T_TEAM = 14,// team HORDE(67), ALLIANCE(469) diff --git a/src/server/game/BattleGrounds/BattleGroundMgr.cpp b/src/server/game/BattleGrounds/BattleGroundMgr.cpp index 2450cfe6e24..8cf15984c1e 100644 --- a/src/server/game/BattleGrounds/BattleGroundMgr.cpp +++ b/src/server/game/BattleGrounds/BattleGroundMgr.cpp @@ -48,6 +48,7 @@ #include "ProgressBar.h" #include "SharedDefines.h" #include "Formulas.h" +#include "DisableMgr.h" /*********************************************************/ /*** BATTLEGROUND QUEUE SYSTEM ***/ @@ -1707,7 +1708,7 @@ void BattleGroundMgr::CreateInitialBattleGrounds() uint32 count = 0; // 0 1 2 3 4 5 6 7 8 - QueryResult_AutoPtr result = WorldDatabase.Query("SELECT id, MinPlayersPerTeam,MaxPlayersPerTeam,MinLvl,MaxLvl,AllianceStartLoc,AllianceStartO,HordeStartLoc,HordeStartO FROM battleground_template WHERE disable = 0"); + QueryResult_AutoPtr result = WorldDatabase.Query("SELECT id, MinPlayersPerTeam,MaxPlayersPerTeam,MinLvl,MaxLvl,AllianceStartLoc,AllianceStartO,HordeStartLoc,HordeStartO FROM battleground_template"); if (!result) { @@ -1728,6 +1729,8 @@ void BattleGroundMgr::CreateInitialBattleGrounds() bar.step(); uint32 bgTypeID_ = fields[0].GetUInt32(); + if (sDisableMgr.IsDisabledFor(DISABLE_TYPE_BATTLEGROUND, bgTypeID_, NULL)) + continue; // can be overwrite by values from DB bl = sBattlemasterListStore.LookupEntry(bgTypeID_); diff --git a/src/server/game/CMakeLists.txt b/src/server/game/CMakeLists.txt index 3cb646facbe..b500b686fb9 100644 --- a/src/server/game/CMakeLists.txt +++ b/src/server/game/CMakeLists.txt @@ -63,6 +63,7 @@ set(game_STAT_SRCS Combat/HostileRefManager.cpp Combat/ThreatManager.cpp Conditions/ConditionMgr.cpp + Conditions/DisableMgr.cpp DataStores/DBCStores.cpp DungeonFinding/LFGMgr.cpp Entities/Corpse/Corpse.cpp diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp index f62dee975da..42363124518 100644 --- a/src/server/game/Chat/Chat.cpp +++ b/src/server/game/Chat/Chat.cpp @@ -278,8 +278,6 @@ ChatCommand * ChatHandler::getCommandTable() { "unbind", SEC_ADMINISTRATOR, false, &ChatHandler::HandleInstanceUnbindCommand, "", NULL }, { "stats", SEC_ADMINISTRATOR, true, &ChatHandler::HandleInstanceStatsCommand, "", NULL }, { "savedata", SEC_ADMINISTRATOR, false, &ChatHandler::HandleInstanceSaveDataCommand, "", NULL }, - { "open", SEC_ADMINISTRATOR, true, &ChatHandler::HandleInstanceOpenCommand, "", NULL }, - { "close", SEC_ADMINISTRATOR, true, &ChatHandler::HandleInstanceCloseCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; @@ -466,6 +464,7 @@ ChatCommand * ChatHandler::getCommandTable() { "creature_questrelation", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadCreatureQuestRelationsCommand, "", NULL }, { "creature_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadCreatureTemplateCommand, "", NULL }, //{ "db_script_string", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadDbScriptStringCommand, "", NULL }, + { "disables", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadDisablesCommand, "", NULL }, { "disenchant_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesDisenchantCommand, "", NULL }, { "event_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadEventScriptsCommand, "", NULL }, { "fishing_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesFishingCommand, "", NULL }, @@ -522,7 +521,6 @@ ChatCommand * ChatHandler::getCommandTable() { "spell_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellScriptsCommand, "", NULL }, { "spell_target_position", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellTargetPositionCommand, "", NULL }, { "spell_threats", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellThreatsCommand, "", NULL }, - { "spell_disabled", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellDisabledCommand, "", NULL }, { "spell_group_stack_rules", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellGroupStackRulesCommand, "", NULL }, { "trinity_string", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadTrinityStringCommand, "", NULL }, { "auctions", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAuctionsCommand, "", NULL }, diff --git a/src/server/game/Chat/Chat.h b/src/server/game/Chat/Chat.h index 6b102129c8a..2a653983aa0 100644 --- a/src/server/game/Chat/Chat.h +++ b/src/server/game/Chat/Chat.h @@ -234,9 +234,6 @@ class ChatHandler bool HandleInstanceUnbindCommand(const char* args); bool HandleInstanceStatsCommand(const char* args); bool HandleInstanceSaveDataCommand(const char * args); - bool HandleInstanceOpenCommand(const char * args); - bool HandleInstanceCloseCommand(const char * args); - bool HandleInstanceOpenCloseCommand(const char * args, bool open); bool HandleLearnCommand(const char* args); bool HandleLearnAllCommand(const char* args); @@ -428,7 +425,7 @@ class ChatHandler bool HandleReloadSpellTargetPositionCommand(const char* args); bool HandleReloadSpellThreatsCommand(const char* args); bool HandleReloadSpellPetAurasCommand(const char* args); - bool HandleReloadSpellDisabledCommand(const char* args); + bool HandleReloadDisablesCommand(const char* args); bool HandleReloadSpellGroupStackRulesCommand(const char* args); bool HandleReloadAuctionsCommand(const char* args); bool HandleReloadWpScriptsCommand(const char* args); diff --git a/src/server/game/Chat/Commands/Level3.cpp b/src/server/game/Chat/Commands/Level3.cpp index 3ddf9b84365..40c3aae5705 100644 --- a/src/server/game/Chat/Commands/Level3.cpp +++ b/src/server/game/Chat/Commands/Level3.cpp @@ -56,6 +56,7 @@ #include "SpellAuraEffects.h" #include "DBCEnums.h" #include "ConditionMgr.h" +#include "DisableMgr.h" bool ChatHandler::HandleAHBotOptionsCommand(const char *args) { @@ -661,7 +662,6 @@ bool ChatHandler::HandleReloadAllSpellCommand(const char*) HandleReloadSpellThreatsCommand("a"); HandleReloadSpellGroupStackRulesCommand("a"); HandleReloadSpellPetAurasCommand("a"); - HandleReloadSpellDisabledCommand("a"); return true; } @@ -1463,14 +1463,13 @@ bool ChatHandler::HandleReloadGameTeleCommand(const char* /*arg*/) return true; } -bool ChatHandler::HandleReloadSpellDisabledCommand(const char* /*arg*/) +bool ChatHandler::HandleReloadDisablesCommand(const char* /*arg*/) { - sLog.outString("Re-Loading spell disabled table..."); - - objmgr.LoadSpellDisabledEntrys(); - - SendGlobalGMSysMessage("DB table `spell_disabled` reloaded."); - + sLog.outString("Re-Loading disables table..."); + sDisableMgr.LoadDisables(); + sLog.outString("Checking quest disables..."); + sDisableMgr.CheckQuestDisables(); + SendGlobalGMSysMessage("DB table `disables` reloaded."); return true; } @@ -7051,103 +7050,6 @@ bool ChatHandler::HandleInstanceSaveDataCommand(const char * /*args*/) return true; } -bool ChatHandler::HandleInstanceOpenCommand(const char *args) -{ - return HandleInstanceOpenCloseCommand(args,true); -} - -bool ChatHandler::HandleInstanceCloseCommand(const char *args) -{ - return HandleInstanceOpenCloseCommand(args,false); -} - -bool ChatHandler::HandleInstanceOpenCloseCommand(const char *args,bool open) -{ - char *mapIdStr; - char *instanceModeStr; - extractOptFirstArg((char*)args,&mapIdStr,&instanceModeStr); - if (!mapIdStr || !instanceModeStr) - return false; - - uint32 mapid = atoi(mapIdStr); - - InstanceTemplate const* instance = objmgr.GetInstanceTemplate(mapid); - if (!instance) - { - PSendSysMessage("Invalid map id"); - SetSentErrorMessage(true); - return false; - } - - uint8 status = objmgr.GetAccessRequirement(instance->access_id)->status; - uint8 flag = 0; - - const MapEntry *entry = sMapStore.LookupEntry(mapid); - if (!entry) - return false; - - if (entry->IsDungeon()) - { - if (strcmp(instanceModeStr,"normal")) - flag = DUNGEON_STATUSFLAG_NORMAL; - else if (strcmp(instanceModeStr,"heroic")) - flag = DUNGEON_STATUSFLAG_HEROIC; - else if (strcmp(instanceModeStr,"all")) - flag = DUNGEON_STATUSFLAG_NORMAL & DUNGEON_STATUSFLAG_HEROIC; - else - { - PSendSysMessage("Unrecognized difficulty string"); - SetSentErrorMessage(true); - return false; - } - } - - else if (entry->IsRaid()) - { - if (strcmp(instanceModeStr,"normal")) - flag = RAID_STATUSFLAG_10MAN_NORMAL & RAID_STATUSFLAG_25MAN_NORMAL; - else if (strcmp(instanceModeStr,"heroic")) - flag = RAID_STATUSFLAG_10MAN_HEROIC & RAID_STATUSFLAG_25MAN_HEROIC; - else if (strcmp(instanceModeStr,"10man")) - flag = RAID_STATUSFLAG_10MAN_NORMAL & RAID_STATUSFLAG_10MAN_HEROIC; - else if (strcmp(instanceModeStr,"25man")) - flag = RAID_STATUSFLAG_25MAN_NORMAL & RAID_STATUSFLAG_25MAN_HEROIC; - else if (strcmp(instanceModeStr,"heroic")) - flag = RAID_STATUSFLAG_10MAN_HEROIC & RAID_STATUSFLAG_25MAN_HEROIC; - else if (strcmp(instanceModeStr,"10normal")) - flag = DUNGEON_STATUSFLAG_NORMAL; - else if (strcmp(instanceModeStr,"25normal")) - flag = DUNGEON_STATUSFLAG_HEROIC; - else if (strcmp(instanceModeStr,"10heroic")) - flag = RAID_STATUSFLAG_10MAN_HEROIC; - else if (strcmp(instanceModeStr,"25heroic")) - flag = RAID_STATUSFLAG_25MAN_HEROIC; - else if (strcmp(instanceModeStr,"all")) - flag = RAID_STATUSFLAG_10MAN_NORMAL & RAID_STATUSFLAG_10MAN_HEROIC & RAID_STATUSFLAG_25MAN_NORMAL & RAID_STATUSFLAG_25MAN_HEROIC; - else - { - PSendSysMessage("Unrecognized difficulty string"); - SetSentErrorMessage(true); - return false; - } - } - else - { - PSendSysMessage("Map is not a dungeon/raid"); - SetSentErrorMessage(true); - return false; - } - - if (open) - status |= flag; - else - status &= ~flag; - - WorldDatabase.PExecute("UPDATE access_requirement SET status = '%u' WHERE id = '%u'", status, instance->access_id); - PSendSysMessage("Instance status changed. Don't forget to reload access_requirement table"); - return true; -} - /// Display the list of GMs bool ChatHandler::HandleGMListFullCommand(const char* /*args*/) { diff --git a/src/server/game/Conditions/DisableMgr.cpp b/src/server/game/Conditions/DisableMgr.cpp new file mode 100644 index 00000000000..6fc935c5cb5 --- /dev/null +++ b/src/server/game/Conditions/DisableMgr.cpp @@ -0,0 +1,254 @@ +/* + * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> + * + * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "ProgressBar.h" +#include "SpellMgr.h" +#include "DisableMgr.h" + +DisableMgr::DisableMgr() +{ +} + +DisableMgr::~DisableMgr() +{ + for (DisableMap::iterator itr = m_DisableMap.begin(); itr != m_DisableMap.end(); ++itr) + itr->second.clear(); + m_DisableMap.clear(); +} + +void DisableMgr::LoadDisables() +{ + // reload case + for (DisableMap::iterator itr = m_DisableMap.begin(); itr != m_DisableMap.end(); ++itr) + itr->second.clear(); + m_DisableMap.clear(); + + QueryResult_AutoPtr result = WorldDatabase.Query("SELECT sourceType,entry,flags FROM disables"); + + uint32 total_count = 0; + + if (!result) + { + barGoLink bar(1); + bar.step(); + + sLog.outString(); + sLog.outString(">> Loaded %u disables", total_count); + return; + } + + barGoLink bar(result->GetRowCount()); + + Field* fields; + do + { + bar.step(); + fields = result->Fetch(); + DisableType type = DisableType(fields[0].GetUInt32()); + if (type >= MAX_DISABLE_TYPES) + { + sLog.outErrorDb("Invalid type %u specified in `disables` table, skipped.", type); + continue; + } + uint32 entry = fields[1].GetUInt32(); + uint8 flags = fields[2].GetUInt8(); + switch (type) + { + case DISABLE_TYPE_SPELL: + if (!sSpellStore.LookupEntry(entry)) + { + sLog.outErrorDb("Spell entry %u from `disables` doesn't exist in dbc, skipped.", entry); + continue; + } + if (!flags || flags > 7) + { + sLog.outErrorDb("Disable flags for spell %u are invalid, skipped.", entry); + continue; + } + break; + // checked later + case DISABLE_TYPE_QUEST: + break; + case DISABLE_TYPE_MAP: + { + MapEntry const* mapEntry = sMapStore.LookupEntry(entry); + if (!mapEntry) + { + sLog.outErrorDb("Map entry %u from `disables` doesn't exist in dbc, skipped.", entry); + continue; + } + bool isFlagInvalid = false; + switch (mapEntry->map_type) + { + case MAP_COMMON: + if (flags) + isFlagInvalid = true; + break; + case MAP_INSTANCE: + case MAP_RAID: + if (flags & DUNGEON_STATUSFLAG_HEROIC && !GetMapDifficultyData(entry, DUNGEON_DIFFICULTY_HEROIC)) + isFlagInvalid = true; + else if (flags & RAID_STATUSFLAG_10MAN_HEROIC && !GetMapDifficultyData(entry, RAID_DIFFICULTY_10MAN_HEROIC)) + isFlagInvalid = true; + else if (flags & RAID_STATUSFLAG_25MAN_HEROIC && !GetMapDifficultyData(entry, RAID_DIFFICULTY_25MAN_HEROIC)) + isFlagInvalid = true; + break; + case MAP_BATTLEGROUND: + case MAP_ARENA: + sLog.outErrorDb("Battleground map specified to be disabled in map case, skipped.", entry); + continue; + } + if (isFlagInvalid) + { + sLog.outErrorDb("Disable flags for map %u are invalid, skipped.", entry); + continue; + } + break; + } + case DISABLE_TYPE_BATTLEGROUND: + if (!sBattlemasterListStore.LookupEntry(entry)) + { + sLog.outErrorDb("Battleground entry %u from `disables` doesn't exist in dbc, skipped.", entry); + continue; + } + if (flags) + sLog.outErrorDb("Disable flags specified for battleground %u, useless data.", entry); + break; + case DISABLE_TYPE_ACHIEVEMENT_CRITERIA: + if (!sAchievementCriteriaStore.LookupEntry(entry)) + { + sLog.outErrorDb("Achievement Criteria entry %u from `disables` doesn't exist in dbc, skipped.", entry); + continue; + } + if (flags) + sLog.outErrorDb("Disable flags specified for Achievement Criteria %u, useless data.", entry); + break; + } + m_DisableMap[type].insert(DisableTypeMap::value_type(entry, flags)); + ++total_count; + } while (result->NextRow()); + + sLog.outString(); + sLog.outString(">> Loaded %u disables.", total_count); +} + +void DisableMgr::CheckQuestDisables() +{ + uint32 count = m_DisableMap[DISABLE_TYPE_QUEST].size(); + if (!count) + { + barGoLink bar(1); + bar.step(); + sLog.outString(); + sLog.outString(">> Done."); + return; + } + + barGoLink bar(count); + // check only quests, rest already done at startup + for (DisableTypeMap::iterator itr = m_DisableMap[DISABLE_TYPE_QUEST].begin(); itr != m_DisableMap[DISABLE_TYPE_QUEST].end();) + { + bar.step(); + const uint32 entry = itr->first; + if (!objmgr.GetQuestTemplate(entry)) + { + sLog.outErrorDb("Quest entry %u from `disables` doesn't exist, skipped.", entry); + m_DisableMap[DISABLE_TYPE_QUEST].erase(itr++); + continue; + } + if (itr->second) + sLog.outErrorDb("Disable flags specified for quest %u, useless data.", entry); + ++itr; + } + + sLog.outString(); + sLog.outString(">> Done."); +} + +bool DisableMgr::IsDisabledFor(DisableType type, uint32 entry, Unit const* pUnit) +{ + assert(type < MAX_DISABLE_TYPES); + if (m_DisableMap[type].empty()) + return false; + + DisableTypeMap::iterator itr = m_DisableMap[type].find(entry); + if (itr == m_DisableMap[type].end()) // not disabled + return false; + + switch (type) + { + case DISABLE_TYPE_SPELL: + { + uint8 flags = itr->second; + if (flags & SPELL_DISABLE_PLAYER && pUnit->GetTypeId() == TYPEID_PLAYER) + return true; + else if (pUnit->GetTypeId() == TYPEID_UNIT) + { + if (pUnit->ToCreature()->isPet()) + { + if (flags & SPELL_DISABLE_PET) + return true; + } + else if (flags & SPELL_DISABLE_CREATURE) + return true; + } + return false; + } + case DISABLE_TYPE_MAP: + if (!pUnit) + return true; + if (Player const* pPlayer = pUnit->ToPlayer()) + { + MapEntry const* mapEntry = sMapStore.LookupEntry(entry); + if (mapEntry->IsDungeon()) + { + uint8 disabledModes = itr->second; + switch(mapEntry->IsRaid() ? pPlayer->GetRaidDifficulty() : pPlayer->GetDungeonDifficulty()) + { + case DUNGEON_DIFFICULTY_NORMAL: + return disabledModes & DUNGEON_STATUSFLAG_NORMAL; + case DUNGEON_DIFFICULTY_HEROIC: + return disabledModes & DUNGEON_STATUSFLAG_HEROIC; + case RAID_DIFFICULTY_10MAN_HEROIC: + return disabledModes & RAID_STATUSFLAG_10MAN_HEROIC; + case RAID_DIFFICULTY_25MAN_HEROIC: + return disabledModes & RAID_STATUSFLAG_25MAN_HEROIC; + } + } + else if (mapEntry->map_type == MAP_COMMON) + return true; + } + return false; + case DISABLE_TYPE_QUEST: + if (!pUnit) + return true; + if (Player const* pPlayer = pUnit->ToPlayer()) + if (pPlayer->isGameMaster()) + return false; + return true; + case DISABLE_TYPE_BATTLEGROUND: + case DISABLE_TYPE_ACHIEVEMENT_CRITERIA: + return true; + default: + return false; + } + + return false; +} diff --git a/src/server/game/Conditions/DisableMgr.h b/src/server/game/Conditions/DisableMgr.h new file mode 100644 index 00000000000..4bfacccdfb0 --- /dev/null +++ b/src/server/game/Conditions/DisableMgr.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> + * + * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef TRINITY_DISABLEMGR_H +#define TRINITY_DISABLEMGR_H + +enum DisableType +{ + DISABLE_TYPE_SPELL = 0, + DISABLE_TYPE_QUEST = 1, + DISABLE_TYPE_MAP = 2, + DISABLE_TYPE_BATTLEGROUND = 3, + DISABLE_TYPE_ACHIEVEMENT_CRITERIA = 4 +}; + +#define MAX_DISABLE_TYPES 5 + +typedef std::map<uint32, uint8> DisableTypeMap; // single disables here with optional data +typedef std::map<DisableType, DisableTypeMap> DisableMap; // global disable map by source + +class DisableMgr +{ + friend class ACE_Singleton<DisableMgr, ACE_Null_Mutex>; + DisableMgr(); + + public: + ~DisableMgr(); + + void LoadDisables(); + bool IsDisabledFor(DisableType type, uint32 entry, Unit const* pUnit); + void CheckQuestDisables(); + + protected: + DisableMap m_DisableMap; +}; + +#define sDisableMgr (*ACE_Singleton<DisableMgr, ACE_Null_Mutex>::instance()) + +#endif //TRINITY_DISABLEMGR_H diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 7a63a794456..e1708528585 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -67,6 +67,7 @@ #include "SpellAuras.h" #include "SpellAuraEffects.h" #include "ConditionMgr.h" +#include "DisableMgr.h" #include <cmath> #define ZONE_UPDATE_INTERVAL (1*IN_MILLISECONDS) @@ -1809,7 +1810,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati return false; } - if ((GetSession()->GetSecurity() < SEC_GAMEMASTER) && !sWorld.IsAllowedMap(mapid)) + if ((GetSession()->GetSecurity() < SEC_GAMEMASTER) && sDisableMgr.IsDisabledFor(DISABLE_TYPE_MAP, mapid, NULL)) { sLog.outError("Player %s tried to enter a forbidden map", GetName()); return false; @@ -13972,7 +13973,8 @@ bool Player::CanSeeStartQuest(Quest const *pQuest) if (SatisfyQuestRace(pQuest, false) && SatisfyQuestSkillOrClass(pQuest, false) && SatisfyQuestExclusiveGroup(pQuest, false) && SatisfyQuestReputation(pQuest, false) && SatisfyQuestPreviousQuest(pQuest, false) && SatisfyQuestNextChain(pQuest, false) && - SatisfyQuestPrevChain(pQuest, false) && SatisfyQuestDay(pQuest, false) && SatisfyQuestWeek(pQuest, false)) + SatisfyQuestPrevChain(pQuest, false) && SatisfyQuestDay(pQuest, false) && SatisfyQuestWeek(pQuest, false) && + !sDisableMgr.IsDisabledFor(DISABLE_TYPE_QUEST, pQuest->GetQuestId(), this)) { return getLevel() + sWorld.getConfig(CONFIG_QUEST_HIGH_LEVEL_HIDE_DIFF) >= pQuest->GetMinLevel(); } @@ -13987,7 +13989,8 @@ bool Player::CanTakeQuest(Quest const *pQuest, bool msg) && SatisfyQuestSkillOrClass(pQuest, msg) && SatisfyQuestReputation(pQuest, msg) && SatisfyQuestPreviousQuest(pQuest, msg) && SatisfyQuestTimed(pQuest, msg) && SatisfyQuestNextChain(pQuest, msg) && SatisfyQuestPrevChain(pQuest, msg) - && SatisfyQuestDay(pQuest, msg) && SatisfyQuestWeek(pQuest, msg); + && SatisfyQuestDay(pQuest, msg) && SatisfyQuestWeek(pQuest, msg) + && !sDisableMgr.IsDisabledFor(DISABLE_TYPE_QUEST, pQuest->GetQuestId(), this); } bool Player::CanAddQuest(Quest const *pQuest, bool msg) @@ -17446,25 +17449,7 @@ bool Player::Satisfy(AccessRequirement const *ar, uint32 target_map, bool report if (!mapEntry) return false; - bool closed = false; - - switch(mapEntry->IsRaid() ? GetRaidDifficulty() : GetDungeonDifficulty()) - { - case DUNGEON_DIFFICULTY_NORMAL: - closed = (ar->status & DUNGEON_STATUSFLAG_NORMAL) == 0; - break; - case DUNGEON_DIFFICULTY_HEROIC: - closed = (ar->status & DUNGEON_STATUSFLAG_HEROIC) == 0; - break; - case RAID_DIFFICULTY_10MAN_HEROIC: - closed = (ar->status & RAID_STATUSFLAG_10MAN_HEROIC) == 0; - break; - case RAID_DIFFICULTY_25MAN_HEROIC: - closed = (ar->status & RAID_STATUSFLAG_25MAN_HEROIC) == 0; - break; - } - - if (closed) + if (sDisableMgr.IsDisabledFor(DISABLE_TYPE_MAP, target_map, this)) { GetSession()->SendAreaTriggerMessage(GetSession()->GetTrinityString(LANG_INSTANCE_CLOSED)); return false; diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 71cd4c46b80..b07c9ecc0f5 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -45,6 +45,7 @@ #include "GossipDef.h" #include "Vehicle.h" #include "AchievementMgr.h" +#include "DisableMgr.h" ScriptMapMap sQuestEndScripts; ScriptMapMap sQuestStartScripts; @@ -3701,6 +3702,10 @@ void ObjectMgr::LoadQuests() // Post processing for (QuestMap::iterator iter = mQuestTemplates.begin(); iter != mQuestTemplates.end(); ++iter) { + // skip post-loading checks for disabled quests + if (sDisableMgr.IsDisabledFor(DISABLE_TYPE_QUEST, iter->first, NULL)) + continue; + Quest * qinfo = iter->second; // additional quest integrity checks (GO, creature_template and item_template must be loaded already) @@ -7574,52 +7579,6 @@ const char *ObjectMgr::GetTrinityString(int32 entry, int locale_idx) const return "<error>"; } -void ObjectMgr::LoadSpellDisabledEntrys() -{ - m_DisabledPlayerSpells.clear(); // need for reload case - m_DisabledCreatureSpells.clear(); - m_DisabledPetSpells.clear(); - QueryResult_AutoPtr result = WorldDatabase.Query("SELECT entry, disable_mask FROM spell_disabled"); - - uint32 total_count = 0; - - if (!result) - { - barGoLink bar(1); - bar.step(); - - sLog.outString(); - sLog.outString(">> Loaded %u disabled spells", total_count); - return; - } - - barGoLink bar(result->GetRowCount()); - - Field* fields; - do - { - bar.step(); - fields = result->Fetch(); - uint32 spellid = fields[0].GetUInt32(); - if (!sSpellStore.LookupEntry(spellid)) - { - sLog.outErrorDb("Spell entry %u from `spell_disabled` doesn't exist in dbc, ignoring.",spellid); - continue; - } - uint32 disable_mask = fields[1].GetUInt32(); - if (disable_mask & SPELL_DISABLE_PLAYER) - m_DisabledPlayerSpells.insert(spellid); - if (disable_mask & SPELL_DISABLE_CREATURE) - m_DisabledCreatureSpells.insert(spellid); - if (disable_mask & SPELL_DISABLE_PET) - m_DisabledPetSpells.insert(spellid); - ++total_count; - } while (result->NextRow()); - - sLog.outString(); - sLog.outString(">> Loaded %u disabled spells from `spell_disabled`", total_count); -} - void ObjectMgr::LoadFishingBaseSkillLevel() { mFishingBaseForArea.clear(); // for reload case diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 7b7e0e2bdb9..e02fe438c5c 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -837,11 +837,6 @@ class ObjectMgr static bool CheckDeclinedNames(std::wstring mainpart, DeclinedName const& names); - void LoadSpellDisabledEntrys(); - bool IsPlayerSpellDisabled(uint32 spellid) { return (m_DisabledPlayerSpells.count(spellid) != 0); } - bool IsCreatureSpellDisabled(uint32 spellid) { return (m_DisabledCreatureSpells.count(spellid) != 0); } - bool IsPetSpellDisabled(uint32 spellid) { return (m_DisabledPetSpells.count(spellid) != 0); } - int GetIndexForLocale(LocaleConstant loc); LocaleConstant GetLocaleForIndex(int i); @@ -999,10 +994,6 @@ class ObjectMgr typedef std::set<std::wstring> ReservedNamesMap; ReservedNamesMap m_ReservedNames; - std::set<uint32> m_DisabledPlayerSpells; - std::set<uint32> m_DisabledCreatureSpells; - std::set<uint32> m_DisabledPetSpells; - // GraveYardMap mGraveYardMap; GameTeleMap m_GameTeleMap; diff --git a/src/server/game/Server/Protocol/Handlers/BattleGroundHandler.cpp b/src/server/game/Server/Protocol/Handlers/BattleGroundHandler.cpp index e779f2a8ab1..a50eb813bb5 100644 --- a/src/server/game/Server/Protocol/Handlers/BattleGroundHandler.cpp +++ b/src/server/game/Server/Protocol/Handlers/BattleGroundHandler.cpp @@ -34,6 +34,7 @@ #include "Player.h" #include "Object.h" #include "Opcodes.h" +#include "DisableMgr.h" void WorldSession::HandleBattlemasterHelloOpcode(WorldPacket & recv_data) { @@ -90,6 +91,12 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket & recv_data) return; } + if (sDisableMgr.IsDisabledFor(DISABLE_TYPE_BATTLEGROUND, bgTypeId_, NULL)) + { + ChatHandler(this).PSendSysMessage(LANG_BG_DISABLED); + return; + } + BattleGroundTypeId bgTypeId = BattleGroundTypeId(bgTypeId_); sLog.outDebug("WORLD: Recvd CMSG_BATTLEMASTER_JOIN Message from (GUID: %u TypeId:%u)", GUID_LOPART(guid), GuidHigh2TypeId(GUID_HIPART(guid))); @@ -659,6 +666,12 @@ void WorldSession::HandleBattlemasterJoinArena(WorldPacket & recv_data) return; } + if (sDisableMgr.IsDisabledFor(DISABLE_TYPE_BATTLEGROUND, BATTLEGROUND_AA, NULL)) + { + ChatHandler(this).PSendSysMessage(LANG_ARENA_DISABLED); + return; + } + BattleGroundTypeId bgTypeId = bg->GetTypeID(); BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bgTypeId, arenatype); PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bg->GetMapId(),_player->getLevel()); diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 052c829676b..28248b97c96 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -51,6 +51,7 @@ #include "SpellAuraEffects.h" #include "ScriptMgr.h" #include "ConditionMgr.h" +#include "DisableMgr.h" #define SPELL_CHANNEL_UPDATE_INTERVAL (1 * IN_MILLISECONDS) @@ -2740,31 +2741,12 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect const * triggere finish(false); return; } - if (m_caster->GetTypeId() == TYPEID_PLAYER) - { - if (objmgr.IsPlayerSpellDisabled(m_spellInfo->Id)) - { - SendCastResult(SPELL_FAILED_SPELL_UNAVAILABLE); - finish(false); - return; - } - } - else if (m_caster->GetTypeId() == TYPEID_UNIT && m_caster->ToCreature()->isPet()) - { - if (objmgr.IsPetSpellDisabled(m_spellInfo->Id)) - { - SendCastResult(SPELL_FAILED_SPELL_UNAVAILABLE); - finish(false); - return; - } - } - else + + if (sDisableMgr.IsDisabledFor(DISABLE_TYPE_SPELL, m_spellInfo->Id, m_caster)) { - if (objmgr.IsCreatureSpellDisabled(m_spellInfo->Id)) - { - finish(false); - return; - } + SendCastResult(SPELL_FAILED_SPELL_UNAVAILABLE); + finish(false); + return; } if (m_caster->GetTypeId() == TYPEID_PLAYER) diff --git a/src/server/game/Spells/SpellMgr.h b/src/server/game/Spells/SpellMgr.h index ec0149f3a63..d02efab43b1 100644 --- a/src/server/game/Spells/SpellMgr.h +++ b/src/server/game/Spells/SpellMgr.h @@ -52,9 +52,9 @@ enum SpellCategories enum SpellDisableTypes { - SPELL_DISABLE_PLAYER = 1, - SPELL_DISABLE_CREATURE = 2, - SPELL_DISABLE_PET = 4 + SPELL_DISABLE_PLAYER = 1, + SPELL_DISABLE_CREATURE = 2, + SPELL_DISABLE_PET = 4 }; enum SpellEffectTargetTypes diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 05065140c35..691fd1dce22 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -70,6 +70,7 @@ #include "AddonMgr.h" #include "LFGMgr.h" #include "ConditionMgr.h" +#include "DisableMgr.h" volatile bool World::m_stopEvent = false; uint8 World::m_ExitCode = SHUTDOWN_EXIT_CODE; @@ -1224,20 +1225,6 @@ void World::LoadConfigSettings(bool reload) m_configs[CONFIG_MIN_LOG_UPDATE] = sConfig.GetIntDefault("MinRecordUpdateTimeDiff", 10); m_configs[CONFIG_NUMTHREADS] = sConfig.GetIntDefault("MapUpdate.Threads", 1); - std::string forbiddenmaps = sConfig.GetStringDefault("ForbiddenMaps", ""); - char * forbiddenMaps = new char[forbiddenmaps.length() + 1]; - forbiddenMaps[forbiddenmaps.length()] = 0; - strncpy(forbiddenMaps, forbiddenmaps.c_str(), forbiddenmaps.length()); - const char * delim = ","; - char * token = strtok(forbiddenMaps, delim); - while (token != NULL) - { - int32 mapid = strtol(token, NULL, 10); - m_forbiddenMapIds.insert(mapid); - token = strtok(NULL,delim); - } - delete[] forbiddenMaps; - // chat logging m_configs[CONFIG_CHATLOG_CHANNEL] = sConfig.GetBoolDefault("ChatLogs.Channel", false); m_configs[CONFIG_CHATLOG_WHISPER] = sConfig.GetBoolDefault("ChatLogs.Whisper", false); @@ -1430,9 +1417,15 @@ void World::SetInitialWorldSettings() sLog.outString("Loading Weather Data..."); objmgr.LoadWeatherZoneChances(); + sLog.outString("Loading Disables"); + sDisableMgr.LoadDisables(); // must be before loading quests + sLog.outString("Loading Quests..."); objmgr.LoadQuests(); // must be loaded after DBCs, creature_template, item_template, gameobject tables + sLog.outString("Checking Quest Disables"); + sDisableMgr.CheckQuestDisables(); // must be after loading quests + sLog.outString("Loading Quest POI"); objmgr.LoadQuestPOI(); @@ -1499,9 +1492,6 @@ void World::SetInitialWorldSettings() sLog.outString("Loading Player level dependent mail rewards..."); objmgr.LoadMailLevelRewards(); - sLog.outString("Loading Disabled Spells..."); - objmgr.LoadSpellDisabledEntrys(); - // Loot tables LoadLootTables(); diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index 07d7d3c51db..f3a92108f60 100644 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -637,8 +637,6 @@ class World uint32 DecreaseScheduledScriptCount(size_t count) { return (uint32)(m_scheduledScripts -= count); } bool IsScriptScheduled() const { return m_scheduledScripts > 0; } - bool IsAllowedMap(uint32 mapid) { return m_forbiddenMapIds.count(mapid) == 0 ;} - // for max speed access static float GetMaxVisibleDistanceOnContinents() { return m_MaxVisibleDistanceOnContinents; } static float GetMaxVisibleDistanceInInstances() { return m_MaxVisibleDistanceInInstances; } @@ -739,7 +737,6 @@ class World bool m_allowMovement; std::string m_motd; std::string m_dataPath; - std::set<uint32> m_forbiddenMapIds; // for max speed access static float m_MaxVisibleDistanceOnContinents; diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index d3b0e289711..0f93bef4c06 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -2147,14 +2147,6 @@ Ra.Secure = 1 # Default: 0 = Only 1 Guild Master per guild # 1 = Allow more than one Guild Master # -# ForbiddenMaps -# Map ids that users below SEC_GAMEMASTER cannot enter, -# with delimiter ',' -# Default: "" -# example: "538,90" -# Note that it's HIGHLY DISCOURAGED to forbid starting maps -# (0, 1, 530)! -# # ShowKickInWorld # Determines wether a message is broadcasted to the entire server # when a player gets kicked |