From e3e5d14d52da6ab6005f28acca6492ff805fe6a0 Mon Sep 17 00:00:00 2001 From: Shauren Date: Tue, 26 Feb 2013 16:57:11 +0100 Subject: Core/Quests: Updated quest flags and implemented QUEST_FLAGS_NO_MONEY_FROM_XP - experience reward from quests using this flag is not converted into money at max level. --- src/server/game/Entities/Player/Player.cpp | 4 +-- src/server/game/Globals/ObjectMgr.cpp | 4 +-- src/server/game/Handlers/QuestHandler.cpp | 2 +- src/server/game/Quests/QuestDef.cpp | 8 ++++++ src/server/game/Quests/QuestDef.h | 44 +++++++++++++++--------------- 5 files changed, 35 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index a8a500c093a..467604960ed 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -15067,7 +15067,7 @@ void Player::CompleteQuest(uint32 quest_id) if (Quest const* qInfo = sObjectMgr->GetQuestTemplate(quest_id)) { - if (qInfo->HasFlag(QUEST_FLAGS_AUTO_REWARDED)) + if (qInfo->HasFlag(QUEST_FLAGS_TRACKING)) RewardQuest(qInfo, 0, this, false); else SendQuestComplete(quest_id); @@ -21361,7 +21361,7 @@ void Player::UpdatePvPState(bool onlyFFA) else // in friendly area { if (IsPvP() && !HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP) && pvpInfo.endTimer == 0) - pvpInfo.endTimer = time(0); // start toggle-off + pvpInfo.endTimer = time(NULL); // start toggle-off } } diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 3b71d11757c..c82ea46f0f7 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -3813,14 +3813,14 @@ void ObjectMgr::LoadQuests() } } - if (qinfo->Flags & QUEST_FLAGS_AUTO_REWARDED) + if (qinfo->Flags & QUEST_FLAGS_TRACKING) { // at auto-reward can be rewarded only RewardChoiceItemId[0] for (int j = 1; j < QUEST_REWARD_CHOICES_COUNT; ++j ) { if (uint32 id = qinfo->RewardChoiceItemId[j]) { - sLog->outError(LOG_FILTER_SQL, "Quest %u has `RewardChoiceItemId%d` = %u but item from `RewardChoiceItemId%d` can't be rewarded with quest flag QUEST_FLAGS_AUTO_REWARDED.", + sLog->outError(LOG_FILTER_SQL, "Quest %u has `RewardChoiceItemId%d` = %u but item from `RewardChoiceItemId%d` can't be rewarded with quest flag QUEST_FLAGS_TRACKING.", qinfo->GetQuestId(), j+1, id, j+1); // no changes, quest ignore this data } diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp index 4e5dbb306fa..b9301347afb 100644 --- a/src/server/game/Handlers/QuestHandler.cpp +++ b/src/server/game/Handlers/QuestHandler.cpp @@ -425,7 +425,7 @@ void WorldSession::HandleQuestLogRemoveQuest(WorldPacket& recvData) if (!_player->TakeQuestSourceItem(questId, true)) return; // can't un-equip some items, reject quest cancel - if (const Quest *quest = sObjectMgr->GetQuestTemplate(questId)) + if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId)) { if (quest->HasFlag(QUEST_TRINITY_FLAGS_TIMED)) _player->RemoveTimedQuest(questId); diff --git a/src/server/game/Quests/QuestDef.cpp b/src/server/game/Quests/QuestDef.cpp index 8bc628b853d..3fefa812489 100644 --- a/src/server/game/Quests/QuestDef.cpp +++ b/src/server/game/Quests/QuestDef.cpp @@ -207,6 +207,14 @@ int32 Quest::GetRewOrReqMoney() const return int32(RewardOrRequiredMoney * sWorld->getRate(RATE_DROP_MONEY)); } +uint32 Quest::GetRewMoneyMaxLevel() const +{ + if (HasFlag(QUEST_FLAGS_NO_MONEY_FROM_XP)) + return 0; + + return RewardMoneyMaxLevel; +} + bool Quest::IsAutoAccept() const { return sWorld->getBoolConfig(CONFIG_QUEST_IGNORE_AUTO_ACCEPT) ? false : (Flags & QUEST_FLAGS_AUTO_ACCEPT); diff --git a/src/server/game/Quests/QuestDef.h b/src/server/game/Quests/QuestDef.h index 9073c5d1441..a447f4a8f52 100644 --- a/src/server/game/Quests/QuestDef.h +++ b/src/server/game/Quests/QuestDef.h @@ -124,27 +124,27 @@ enum __QuestGiverStatus enum QuestFlags { // Flags used at server and sent to client - QUEST_FLAGS_NONE = 0x00000000, - QUEST_FLAGS_STAY_ALIVE = 0x00000001, // Not used currently - QUEST_FLAGS_PARTY_ACCEPT = 0x00000002, // Not used currently. If player in party, all players that can accept this quest will receive confirmation box to accept quest CMSG_QUEST_CONFIRM_ACCEPT/SMSG_QUEST_CONFIRM_ACCEPT - QUEST_FLAGS_EXPLORATION = 0x00000004, // Not used currently - QUEST_FLAGS_SHARABLE = 0x00000008, // Can be shared: Player::CanShareQuest() - //QUEST_FLAGS_NONE2 = 0x00000010, // Not used currently - QUEST_FLAGS_EPIC = 0x00000020, // Not used currently: Unsure of content - QUEST_FLAGS_RAID = 0x00000040, // Not used currently - QUEST_FLAGS_TBC = 0x00000080, // Not used currently: Available if TBC expansion enabled only - QUEST_FLAGS_DELIVER_MORE = 0x00000100, // Not used currently: _DELIVER_MORE Quest needs more than normal _q-item_ drops from mobs - QUEST_FLAGS_HIDDEN_REWARDS = 0x00000200, // Items and money rewarded only sent in SMSG_QUESTGIVER_OFFER_REWARD (not in SMSG_QUESTGIVER_QUEST_DETAILS or in client quest log(SMSG_QUEST_QUERY_RESPONSE)) - QUEST_FLAGS_AUTO_REWARDED = 0x00000400, // These quests are automatically rewarded on quest complete and they will never appear in quest log client side. - QUEST_FLAGS_TBC_RACES = 0x00000800, // Not used currently: Blood elf/Draenei starting zone quests - QUEST_FLAGS_DAILY = 0x00001000, // Used to know quest is Daily one - QUEST_FLAGS_REPEATABLE = 0x00002000, // Used on repeatable quests (3.0.0+) - QUEST_FLAGS_UNAVAILABLE = 0x00004000, // Used on quests that are not generically available - QUEST_FLAGS_WEEKLY = 0x00008000, - QUEST_FLAGS_AUTOCOMPLETE = 0x00010000, // auto complete - QUEST_FLAGS_SPECIAL_ITEM = 0x00020000, // has something to do with RequiredItemId and SourceItemId - QUEST_FLAGS_OBJ_TEXT = 0x00040000, // use Objective text as Complete text - QUEST_FLAGS_AUTO_ACCEPT = 0x00080000, // The client recognizes this flag as auto-accept. However, NONE of the current quests (3.3.5a) have this flag. Maybe blizz used to use it, or will use it in the future. + QUEST_FLAGS_NONE = 0x00000000, + QUEST_FLAGS_STAY_ALIVE = 0x00000001, // Not used currently + QUEST_FLAGS_PARTY_ACCEPT = 0x00000002, // Not used currently. If player in party, all players that can accept this quest will receive confirmation box to accept quest CMSG_QUEST_CONFIRM_ACCEPT/SMSG_QUEST_CONFIRM_ACCEPT + QUEST_FLAGS_EXPLORATION = 0x00000004, // Not used currently + QUEST_FLAGS_SHARABLE = 0x00000008, // Can be shared: Player::CanShareQuest() + QUEST_FLAGS_HAS_CONDITION = 0x00000010, // Not used currently + QUEST_FLAGS_HIDE_REWARD_POI = 0x00000020, // Not used currently: Unsure of content + QUEST_FLAGS_RAID = 0x00000040, // Not used currently + QUEST_FLAGS_TBC = 0x00000080, // Not used currently: Available if TBC expansion enabled only + QUEST_FLAGS_NO_MONEY_FROM_XP = 0x00000100, // Not used currently: Experience is not converted to gold at max level + QUEST_FLAGS_HIDDEN_REWARDS = 0x00000200, // Items and money rewarded only sent in SMSG_QUESTGIVER_OFFER_REWARD (not in SMSG_QUESTGIVER_QUEST_DETAILS or in client quest log(SMSG_QUEST_QUERY_RESPONSE)) + QUEST_FLAGS_TRACKING = 0x00000400, // These quests are automatically rewarded on quest complete and they will never appear in quest log client side. + QUEST_FLAGS_DEPRECATE_REPUTATION = 0x00000800, // Not used currently + QUEST_FLAGS_DAILY = 0x00001000, // Used to know quest is Daily one + QUEST_FLAGS_FLAGS_PVP = 0x00002000, // Having this quest in log forces PvP flag + QUEST_FLAGS_UNAVAILABLE = 0x00004000, // Used on quests that are not generically available + QUEST_FLAGS_WEEKLY = 0x00008000, + QUEST_FLAGS_AUTOCOMPLETE = 0x00010000, // auto complete + QUEST_FLAGS_DISPLAY_ITEM_IN_TRACKER = 0x00020000, // Displays usable item in quest tracker + QUEST_FLAGS_OBJ_TEXT = 0x00040000, // use Objective text as Complete text + QUEST_FLAGS_AUTO_ACCEPT = 0x00080000, // The client recognizes this flag as auto-accept. However, NONE of the current quests (3.3.5a) have this flag. Maybe blizz used to use it, or will use it in the future. // Trinity flags for set SpecialFlags in DB if required but used only at server QUEST_TRINITY_FLAGS_REPEATABLE = 0x00100000, // Set by 1 in SpecialFlags from DB @@ -234,7 +234,7 @@ class Quest int32 GetRewOrReqMoney() const; uint32 GetRewHonorAddition() const { return RewardHonor; } float GetRewHonorMultiplier() const { return RewardHonorMultiplier; } - uint32 GetRewMoneyMaxLevel() const { return RewardMoneyMaxLevel; } // use in XP calculation at client + uint32 GetRewMoneyMaxLevel() const; // use in XP calculation at client uint32 GetRewSpell() const { return RewardSpell; } int32 GetRewSpellCast() const { return RewardSpellCast; } uint32 GetRewMailTemplateId() const { return RewardMailTemplateId; } -- cgit v1.2.3 From af4ac778d7f47e4ab20c042009cb8bbd9c41d94b Mon Sep 17 00:00:00 2001 From: Shauren Date: Tue, 26 Feb 2013 17:14:13 +0100 Subject: Core/Quests: Implemented quest flag forcing the player to be flagged for PvP as long as the quest is in his log. --- src/server/game/Entities/Player/Player.cpp | 71 +++++++++++++++++++++------- src/server/game/Entities/Player/Player.h | 13 +++-- src/server/game/Handlers/MiscHandler.cpp | 6 +-- src/server/game/Handlers/MovementHandler.cpp | 4 +- src/server/game/Handlers/QuestHandler.cpp | 6 +++ src/server/game/Handlers/TaxiHandler.cpp | 2 +- src/server/game/Spells/SpellEffects.cpp | 6 +++ src/server/scripts/Commands/cs_quest.cpp | 6 +++ 8 files changed, 85 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 467604960ed..8647d9d6f5e 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -7417,17 +7417,17 @@ void Player::UpdateArea(uint32 newArea) m_areaUpdateId = newArea; AreaTableEntry const* area = GetAreaEntryByAreaID(newArea); - pvpInfo.inFFAPvPArea = area && (area->flags & AREA_FLAG_ARENA); + pvpInfo.IsInFFAPvPArea = area && (area->flags & AREA_FLAG_ARENA); UpdatePvPState(true); UpdateAreaDependentAuras(newArea); // previously this was in UpdateZone (but after UpdateArea) so nothing will break - pvpInfo.inNoPvPArea = false; + pvpInfo.IsInNoPvPArea = false; if (area && area->IsSanctuary()) // in sanctuary { SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY); - pvpInfo.inNoPvPArea = true; + pvpInfo.IsInNoPvPArea = true; CombatStopWithPets(); } else @@ -7482,29 +7482,32 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea) switch (zone->team) { case AREATEAM_ALLY: - pvpInfo.inHostileArea = GetTeam() != ALLIANCE && (sWorld->IsPvPRealm() || zone->flags & AREA_FLAG_CAPITAL); + pvpInfo.IsInHostileArea = GetTeam() != ALLIANCE && (sWorld->IsPvPRealm() || zone->flags & AREA_FLAG_CAPITAL); break; case AREATEAM_HORDE: - pvpInfo.inHostileArea = GetTeam() != HORDE && (sWorld->IsPvPRealm() || zone->flags & AREA_FLAG_CAPITAL); + pvpInfo.IsInHostileArea = GetTeam() != HORDE && (sWorld->IsPvPRealm() || zone->flags & AREA_FLAG_CAPITAL); break; case AREATEAM_NONE: // overwrite for battlegrounds, maybe batter some zone flags but current known not 100% fit to this - pvpInfo.inHostileArea = sWorld->IsPvPRealm() || InBattleground() || zone->flags & AREA_FLAG_WINTERGRASP; + pvpInfo.IsInHostileArea = sWorld->IsPvPRealm() || InBattleground() || zone->flags & AREA_FLAG_WINTERGRASP; break; default: // 6 in fact - pvpInfo.inHostileArea = false; + pvpInfo.IsInHostileArea = false; break; } + // Treat players having a quest flagging for PvP as always in hostile area + pvpInfo.IsHostile = pvpInfo.IsInHostileArea || HasPvPForcingQuest(); + if (zone->flags & AREA_FLAG_CAPITAL) // Is in a capital city { - if (!pvpInfo.inHostileArea || zone->IsSanctuary()) + if (!pvpInfo.IsHostile || zone->IsSanctuary()) { SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING); SetRestType(REST_TYPE_IN_CITY); InnEnter(time(0), GetMapId(), 0, 0, 0); } - pvpInfo.inNoPvPArea = true; + pvpInfo.IsInNoPvPArea = true; } else { @@ -15046,6 +15049,12 @@ void Player::AddQuest(Quest const* quest, Object* questGiver) else questStatusData.Timer = 0; + if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP)) + { + pvpInfo.IsHostile = true; + UpdatePvPState(); + } + SetQuestSlot(log_slot, quest_id, qtime); m_QuestStatusSave[quest_id] = true; @@ -15242,6 +15251,12 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver, UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT); UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST, quest->GetQuestId()); + if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP)) + { + pvpInfo.IsHostile = pvpInfo.IsInHostileArea || HasPvPForcingQuest(); + UpdatePvPState(); + } + //lets remove flag for delayed teleports SetCanDelayTeleport(false); } @@ -16555,6 +16570,25 @@ void Player::SendQuestUpdateAddPlayer(Quest const* quest, uint16 old_count, uint SetQuestSlotCounter(log_slot, QUEST_PVP_KILL_SLOT, GetQuestSlotCounter(log_slot, QUEST_PVP_KILL_SLOT) + add_count); } +bool Player::HasPvPForcingQuest() const +{ + for (uint8 i = 0; i < MAX_QUEST_LOG_SIZE; ++i) + { + uint32 questId = GetQuestSlotQuestId(i); + if (questId == 0) + continue; + + Quest const* quest = sObjectMgr->GetQuestTemplate(questId); + if (!quest) + continue; + + if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP)) + return true; + } + + return false; +} + /*********************************************************/ /*** LOAD SYSTEM ***/ /*********************************************************/ @@ -19887,7 +19921,8 @@ void Player::UpdatePvPFlag(time_t currTime) { if (!IsPvP()) return; - if (pvpInfo.endTimer == 0 || currTime < (pvpInfo.endTimer + 300) || pvpInfo.inHostileArea) + + if (!pvpInfo.EndTimer || currTime < (pvpInfo.EndTimer + 300) || pvpInfo.IsHostile) return; UpdatePvP(false); @@ -21333,8 +21368,8 @@ void Player::UpdatePvPState(bool onlyFFA) { // TODO: should we always synchronize UNIT_FIELD_BYTES_2, 1 of controller and controlled? // no, we shouldn't, those are checked for affecting player by client - if (!pvpInfo.inNoPvPArea && !isGameMaster() - && (pvpInfo.inFFAPvPArea || sWorld->IsFFAPvPRealm())) + if (!pvpInfo.IsInNoPvPArea && !isGameMaster() + && (pvpInfo.IsInFFAPvPArea || sWorld->IsFFAPvPRealm())) { if (!HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP)) { @@ -21353,15 +21388,15 @@ void Player::UpdatePvPState(bool onlyFFA) if (onlyFFA) return; - if (pvpInfo.inHostileArea) // in hostile area + if (pvpInfo.IsHostile) // in hostile area { - if (!IsPvP() || pvpInfo.endTimer != 0) + if (!IsPvP() || pvpInfo.EndTimer) UpdatePvP(true, true); } else // in friendly area { - if (IsPvP() && !HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP) && pvpInfo.endTimer == 0) - pvpInfo.endTimer = time(NULL); // start toggle-off + if (IsPvP() && !HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP) && !pvpInfo.EndTimer) + pvpInfo.EndTimer = time(NULL); // start toggle-off } } @@ -21370,11 +21405,11 @@ void Player::UpdatePvP(bool state, bool override) if (!state || override) { SetPvP(state); - pvpInfo.endTimer = 0; + pvpInfo.EndTimer = 0; } else { - pvpInfo.endTimer = time(NULL); + pvpInfo.EndTimer = time(NULL); SetPvP(state); } } diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 362b6aca631..a2086f0b68a 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -270,12 +270,13 @@ struct PlayerInfo struct PvPInfo { - PvPInfo() : inHostileArea(false), inNoPvPArea(false), inFFAPvPArea(false), endTimer(0) {} + PvPInfo() : IsHostile(false), IsInHostileArea(false), IsInNoPvPArea(false), IsInFFAPvPArea(false), EndTimer(0) {} - bool inHostileArea; - bool inNoPvPArea; - bool inFFAPvPArea; - time_t endTimer; + bool IsHostile; + bool IsInHostileArea; ///> Marks if player is in an area which forces PvP flag + bool IsInNoPvPArea; ///> Marks if player is in a sanctuary or friendly capital city + bool IsInFFAPvPArea; ///> Marks if player is in an FFAPvP area (such as Gurubashi Arena) + time_t EndTimer; ///> Time when player unflags himself for PvP (flag removed after 5 minutes) }; struct DuelInfo @@ -1500,6 +1501,8 @@ class Player : public Unit, public GridObject void AddTimedQuest(uint32 quest_id) { m_timedquests.insert(quest_id); } void RemoveTimedQuest(uint32 quest_id) { m_timedquests.erase(quest_id); } + bool HasPvPForcingQuest() const; + /*********************************************************/ /*** LOAD SYSTEM ***/ /*********************************************************/ diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index 3864acb8f88..2a4f4a15037 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -475,13 +475,13 @@ void WorldSession::HandleTogglePvP(WorldPacket& recvData) if (GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP)) { - if (!GetPlayer()->IsPvP() || GetPlayer()->pvpInfo.endTimer != 0) + if (!GetPlayer()->IsPvP() || GetPlayer()->pvpInfo.EndTimer) GetPlayer()->UpdatePvP(true, true); } else { - if (!GetPlayer()->pvpInfo.inHostileArea && GetPlayer()->IsPvP()) - GetPlayer()->pvpInfo.endTimer = time(NULL); // start toggle-off + if (!GetPlayer()->pvpInfo.IsHostile && GetPlayer()->IsPvP()) + GetPlayer()->pvpInfo.EndTimer = time(NULL); // start toggle-off } //if (OutdoorPvP* pvp = _player->GetOutdoorPvP()) diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp index 3308c7bee24..5b023fa160c 100644 --- a/src/server/game/Handlers/MovementHandler.cpp +++ b/src/server/game/Handlers/MovementHandler.cpp @@ -174,7 +174,7 @@ void WorldSession::HandleMoveWorldportAckOpcode() GetPlayer()->UpdateZone(newzone, newarea); // honorless target - if (GetPlayer()->pvpInfo.inHostileArea) + if (GetPlayer()->pvpInfo.IsHostile) GetPlayer()->CastSpell(GetPlayer(), 2479, true); // in friendly area @@ -224,7 +224,7 @@ void WorldSession::HandleMoveTeleportAck(WorldPacket& recvData) if (old_zone != newzone) { // honorless target - if (plMover->pvpInfo.inHostileArea) + if (plMover->pvpInfo.IsHostile) plMover->CastSpell(plMover, 2479, true); // in friendly area diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp index b9301347afb..2724a523667 100644 --- a/src/server/game/Handlers/QuestHandler.cpp +++ b/src/server/game/Handlers/QuestHandler.cpp @@ -429,6 +429,12 @@ void WorldSession::HandleQuestLogRemoveQuest(WorldPacket& recvData) { if (quest->HasFlag(QUEST_TRINITY_FLAGS_TIMED)) _player->RemoveTimedQuest(questId); + + if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP)) + { + _player->pvpInfo.IsHostile = _player->pvpInfo.IsInHostileArea || _player->HasPvPForcingQuest(); + _player->UpdatePvPState(); + } } _player->TakeQuestSourceItem(questId, true); // remove quest src item from player diff --git a/src/server/game/Handlers/TaxiHandler.cpp b/src/server/game/Handlers/TaxiHandler.cpp index b7155e552c7..53334cffd18 100644 --- a/src/server/game/Handlers/TaxiHandler.cpp +++ b/src/server/game/Handlers/TaxiHandler.cpp @@ -269,7 +269,7 @@ void WorldSession::HandleMoveSplineDoneOpcode(WorldPacket& recvData) GetPlayer()->CleanupAfterTaxiFlight(); GetPlayer()->SetFallInformation(0, GetPlayer()->GetPositionZ()); - if (GetPlayer()->pvpInfo.inHostileArea) + if (GetPlayer()->pvpInfo.IsHostile) GetPlayer()->CastSpell(GetPlayer(), 2479, true); } diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 9d3ec6630e5..2aa8b6daed8 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -5041,6 +5041,12 @@ void Spell::EffectQuestClear(SpellEffIndex effIndex) // we ignore unequippable quest items in this case, it's still be equipped player->TakeQuestSourceItem(logQuest, false); + + if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP)) + { + player->pvpInfo.IsHostile = player->pvpInfo.IsInHostileArea || player->HasPvPForcingQuest(); + player->UpdatePvPState(); + } } } diff --git a/src/server/scripts/Commands/cs_quest.cpp b/src/server/scripts/Commands/cs_quest.cpp index e10cf883518..e0d67b55989 100644 --- a/src/server/scripts/Commands/cs_quest.cpp +++ b/src/server/scripts/Commands/cs_quest.cpp @@ -138,6 +138,12 @@ public: // we ignore unequippable quest items in this case, its' still be equipped player->TakeQuestSourceItem(logQuest, false); + + if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP)) + { + player->pvpInfo.IsHostile = player->pvpInfo.IsInHostileArea || player->HasPvPForcingQuest(); + player->UpdatePvPState(); + } } } -- cgit v1.2.3 From 3b1410e798662c6f259f3d42d8718cb2d2f181e1 Mon Sep 17 00:00:00 2001 From: Nay Date: Tue, 26 Feb 2013 20:42:34 +0000 Subject: Core/Player: Rename PLAYER_FLAGS_UNK19 to PLAYER_FLAGS_UBER --- src/server/game/Entities/Player/Player.h | 2 +- src/server/game/Entities/Unit/Unit.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index a2086f0b68a..174a5ac531d 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -394,7 +394,7 @@ enum PlayerFlags PLAYER_FLAGS_UNK16 = 0x00010000, // pre-3.0.3 PLAYER_FLAGS_SANCTUARY flag for player entered sanctuary PLAYER_FLAGS_TAXI_BENCHMARK = 0x00020000, // taxi benchmark mode (on/off) (2.0.1) PLAYER_FLAGS_PVP_TIMER = 0x00040000, // 3.0.2, pvp timer active (after you disable pvp manually) - PLAYER_FLAGS_UNK19 = 0x00080000, + PLAYER_FLAGS_UBER = 0x00080000, PLAYER_FLAGS_UNK20 = 0x00100000, PLAYER_FLAGS_UNK21 = 0x00200000, PLAYER_FLAGS_COMMENTATOR2 = 0x00400000, diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 00f771b1f54..508f4b602de 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -11665,7 +11665,7 @@ bool Unit::_IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell, Wo if (Player const* playerAttacker = ToPlayer()) { - if (playerAttacker->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_UNK19)) + if (playerAttacker->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_UBER)) return false; } // check flags -- cgit v1.2.3 From 6ccad9adc4a7a895444d5456e9cebdd655435b8b Mon Sep 17 00:00:00 2001 From: Shauren Date: Tue, 26 Feb 2013 22:20:15 +0100 Subject: Scripts/Blackwing Lair: Fixed crash happening with Shadows of Ebonroc --- .../scripts/EasternKingdoms/BlackwingLair/boss_ebonroc.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_ebonroc.cpp b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_ebonroc.cpp index a9b41b719f7..d1670171d67 100644 --- a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_ebonroc.cpp +++ b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_ebonroc.cpp @@ -74,32 +74,32 @@ public: //Shadowflame Timer if (ShadowFlame_Timer <= diff) { - DoCast(me->getVictim(), SPELL_SHADOWFLAME); + DoCastVictim(SPELL_SHADOWFLAME); ShadowFlame_Timer = urand(12000, 15000); } else ShadowFlame_Timer -= diff; //Thrash Timer if (Thrash_Timer <= diff) { - DoCast(me->getVictim(), SPELL_THRASH); + DoCastVictim(SPELL_THRASH); Thrash_Timer = urand(10000, 15000); } else Thrash_Timer -= diff; //Wing Buffet Timer if (WingBuffet_Timer <= diff) { - DoCast(me->getVictim(), SPELL_WINGBUFFET); + DoCastVictim(SPELL_WINGBUFFET); WingBuffet_Timer = 25000; } else WingBuffet_Timer -= diff; //Shadow of Ebonroc Timer if (ShadowOfEbonroc_Timer <= diff) { - DoCast(me->getVictim(), SPELL_SHADOWOFEBONROC); + DoCastVictim(SPELL_SHADOWOFEBONROC); ShadowOfEbonroc_Timer = urand(25000, 350000); } else ShadowOfEbonroc_Timer -= diff; - if (me->getVictim()->HasAura(SPELL_SHADOWOFEBONROC)) + if (me->getVictim() && me->getVictim()->HasAura(SPELL_SHADOWOFEBONROC)) { if (Heal_Timer <= diff) { -- cgit v1.2.3 From 00c58f25d7180790bd8e70ef57c4788d45e165d0 Mon Sep 17 00:00:00 2001 From: Spp Date: Tue, 26 Feb 2013 22:35:55 +0100 Subject: Core/RBAC: Force loadPermissions before checking session permissions if the storage is null (someone created a session but forgot to call to LoadPermissions) --- src/server/game/Server/WorldSession.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 1e36f342712..8bf92d95248 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -1189,5 +1189,8 @@ RBACData* WorldSession::GetRBACData() bool WorldSession::HasPermission(uint32 permission) { + if (!_RBACData) + LoadPermissions(); + return _RBACData->HasPermission(permission); } -- cgit v1.2.3 From 4ea31ce8862cbc1bc4b9c35bc2ff677cbb6c4a16 Mon Sep 17 00:00:00 2001 From: Nay Date: Tue, 26 Feb 2013 23:49:21 +0000 Subject: Core&SQL: Fix typos (RBAC and equips related) --- sql/base/auth_database.sql | 245 +------------------------ sql/updates/auth/2013_02_25_00_auth_misc.sql | 2 +- sql/updates/auth/2013_02_25_11_auth_misc.sql | 4 +- sql/updates/auth/2013_02_25_14_auth_misc.sql | 2 +- src/server/game/Entities/Creature/Creature.cpp | 4 +- src/server/game/Handlers/MiscHandler.cpp | 2 +- 6 files changed, 13 insertions(+), 246 deletions(-) (limited to 'src') diff --git a/sql/base/auth_database.sql b/sql/base/auth_database.sql index 2ecc6483a26..f50a050bf9c 100644 --- a/sql/base/auth_database.sql +++ b/sql/base/auth_database.sql @@ -265,106 +265,7 @@ CREATE TABLE `rbac_group_roles` ( LOCK TABLES `rbac_group_roles` WRITE; /*!40000 ALTER TABLE `rbac_group_roles` DISABLE KEYS */; -INSERT INTO `rbac_group_roles` VALUES -(1, 1), -(2, 2), -(3, 3), -(4, 4), -(2, 5), -(1, 6), -(1, 7), -(2, 8), -(3, 8), -(4, 8), -(2, 9), -(3, 9), -(4, 9), -(2, 10), -(3, 10), -(4, 10), -(2, 11), -(3, 11), -(4, 11), -(2, 12), -(3, 12), -(4, 12), -(2, 13), -(3, 13), -(4, 13), -(2, 14), -(3, 14), -(4, 14), -(2, 15), -(3, 15), -(4, 15), -(2, 16), -(3, 16), -(4, 16), -(2, 17), -(3, 17), -(4, 17), -(4, 18), -(1, 19), -(2, 19), -(3, 19), -(4, 19), -(2, 20), -(3, 20), -(4, 20), -(2, 21), -(3, 21), -(4, 21), -(2, 22), -(3, 22), -(4, 22), -(4, 23), -(2, 24), -(3, 24), -(4, 24), -(2, 25), -(3, 25), -(4, 25), -(2, 26), -(3, 26), -(4, 26), -(2, 27), -(3, 27), -(4, 27), -(1, 28), -(2, 28), -(3, 28), -(4, 28), -(2, 29), -(3, 29), -(4, 29), -(1, 30), -(2, 30), -(3, 30), -(4, 30), -(2, 31), -(3, 31), -(4, 31), -(2, 32), -(3, 32), -(4, 32), -(2, 33), -(3, 33), -(4, 33), -(2, 34), -(3, 34), -(4, 34), -(2, 35), -(3, 35), -(4, 35), -(2, 36), -(3, 36), -(4, 36), -(2, 37), -(3, 37), -(4, 37), -(2, 38), -(3, 38), -(4, 38); +INSERT INTO `rbac_group_roles` VALUES (1,1),(2,2),(3,3),(4,4),(2,5),(1,6),(1,7),(2,8),(3,8),(4,8),(2,9),(3,9),(4,9),(2,10),(3,10),(4,10),(2,11),(3,11),(4,11),(2,12),(3,12),(4,12),(2,13),(3,13),(4,13),(2,14),(3,14),(4,14),(2,15),(3,15),(4,15),(2,16),(3,16),(4,16),(2,17),(3,17),(4,17),(4,18),(1,19),(2,19),(3,19),(4,19),(2,20),(3,20),(4,20),(2,21),(3,21),(4,21),(2,22),(3,22),(4,22),(4,23),(2,24),(3,24),(4,24),(2,25),(3,25),(4,25),(2,26),(3,26),(4,26),(2,27),(3,27),(4,27),(1,28),(2,28),(3,28),(4,28),(2,29),(3,29),(4,29),(1,30),(2,30),(3,30),(4,30),(2,31),(3,31),(4,31),(2,32),(3,32),(4,32),(2,33),(3,33),(4,33),(2,34),(3,34),(4,34),(2,35),(3,35),(4,35),(2,36),(3,36),(4,36),(2,37),(3,37),(4,37),(2,38),(3,38),(4,38); /*!40000 ALTER TABLE `rbac_group_roles` ENABLE KEYS */; UNLOCK TABLES; @@ -388,11 +289,7 @@ CREATE TABLE `rbac_groups` ( LOCK TABLES `rbac_groups` WRITE; /*!40000 ALTER TABLE `rbac_groups` DISABLE KEYS */; -INSERT INTO `rbac_groups` VALUES -(1,'Player'), -(2,'Moderator'), -(3,'GameMaster'), -(4,'Administrator'); +INSERT INTO `rbac_groups` VALUES (1,'Player'),(2,'Moderator'),(3,'GameMaster'),(4,'Administrator'); /*!40000 ALTER TABLE `rbac_groups` ENABLE KEYS */; UNLOCK TABLES; @@ -416,53 +313,7 @@ CREATE TABLE `rbac_permissions` ( LOCK TABLES `rbac_permissions` WRITE; /*!40000 ALTER TABLE `rbac_permissions` DISABLE KEYS */; -INSERT INTO `rbac_permissions` VALUES -(1, 'Instant logout'), -(2, 'Skip Queue'), -(3, 'Join Normal Battleground'), -(4, 'Join Random Battleground'), -(5, 'Join Arenas'), -(6, 'Join Dungeon Finder'), -(7, 'Player Commands (Temporal till commands moved to rbac)'), -(8, 'Moderator Commands (Temporal till commands moved to rbac)'), -(9, 'GameMaster Commands (Temporal till commands moved to rbac)'), -(10, 'Administrator Commands (Temporal till commands moved to rbac)'), -(11, 'Log GM trades'), -(13, 'Skip Instance required bosses check'), -(14, 'Skip character creation team mask check'), -(15, 'Skip character creation class mask check'), -(16, 'Skip character creation race mask check'), -(17, 'Skip character creation reserved name check'), -(18, 'Skip character creation heroic min level check'), -(19, 'Skip needed requirements to use channel check'), -(20, 'Skip disable map check'), -(21, 'Skip reset talents when used more than allowed check'), -(22, 'Skip spam chat check'), -(23, 'Skip over-speed ping check'), -(24, 'Two side faction characters on the same account'), -(25, 'Allow say chat between factions'), -(26, 'Allow channel chat between factions'), -(27, 'Two side mail interaction'), -(28, 'See two side who list'), -(29, 'Add friends of other faction'), -(30, 'Save character without delay with .save command'), -(31, 'Use params with .unstuck command'), -(32, 'Can be assigned tickets with .assign ticket command'), -(33, 'Notify if a command was not found'), -(34, 'Check if should appear in list using .gm ingame command'), -(35, 'See all security levels with who command'), -(36, 'Filter whispers'), -(37, 'Use staff badge in chat'), -(38, 'Resurrect with full Health Points'), -(39, 'Restore saved gm setting states'), -(40, 'Allows to add a gm to friend list'), -(41, 'Use Config option START_GM_LEVEL to assign new character level'), -(42, 'Allows to use CMSG_WORLD_TELEPORT opcode'), -(43, 'Allows to use CMSG_WHOIS opcode'), -(44, 'Receive global GM messages/texts'), -(45, 'Join channels without announce'), -(46, 'Change channel settings without being channel moderator'), -(47, 'Enables lower security than target check'); +INSERT INTO `rbac_permissions` VALUES (1,'Instant logout'),(2,'Skip Queue'),(3,'Join Normal Battleground'),(4,'Join Random Battleground'),(5,'Join Arenas'),(6,'Join Dungeon Finder'),(7,'Player Commands (Temporal till commands moved to rbac)'),(8,'Moderator Commands (Temporal till commands moved to rbac)'),(9,'GameMaster Commands (Temporal till commands moved to rbac)'),(10,'Administrator Commands (Temporal till commands moved to rbac)'),(11,'Log GM trades'),(13,'Skip Instance required bosses check'),(14,'Skip character creation team mask check'),(15,'Skip character creation class mask check'),(16,'Skip character creation race mask check'),(17,'Skip character creation reserved name check'),(18,'Skip character creation heroic min level check'),(19,'Skip needed requirements to use channel check'),(20,'Skip disable map check'),(21,'Skip reset talents when used more than allowed check'),(22,'Skip spam chat check'),(23,'Skip over-speed ping check'),(24,'Two side faction characters on the same account'),(25,'Allow say chat between factions'),(26,'Allow channel chat between factions'),(27,'Two side mail interaction'),(28,'See two side who list'),(29,'Add friends of other faction'),(30,'Save character without delay with .save command'),(31,'Use params with .unstuck command'),(32,'Can be assigned tickets with .assign ticket command'),(33,'Notify if a command was not found'),(34,'Check if should appear in list using .gm ingame command'),(35,'See all security levels with who command'),(36,'Filter whispers'),(37,'Use staff badge in chat'),(38,'Resurrect with full Health Points'),(39,'Restore saved gm setting states'),(40,'Allows to add a gm to friend list'),(41,'Use Config option START_GM_LEVEL to assign new character level'),(42,'Allows to use CMSG_WORLD_TELEPORT opcode'),(43,'Allows to use CMSG_WHOIS opcode'),(44,'Receive global GM messages/texts'),(45,'Join channels without announce'),(46,'Change channel settings without being channel moderator'),(47,'Enables lower security than target check'); /*!40000 ALTER TABLE `rbac_permissions` ENABLE KEYS */; UNLOCK TABLES; @@ -489,53 +340,7 @@ CREATE TABLE `rbac_role_permissions` ( LOCK TABLES `rbac_role_permissions` WRITE; /*!40000 ALTER TABLE `rbac_role_permissions` DISABLE KEYS */; -INSERT INTO `rbac_role_permissions` VALUES -(5, 1), -(5, 2), -(6, 3), -(6, 4), -(6, 5), -(7, 6), -(1, 7), -(2, 8), -(3, 9), -(4, 10), -(8, 11), -(9, 13), -(33, 14), -(33, 15), -(33, 16), -(33, 17), -(33, 18), -(27, 19), -(22, 20), -(23, 21), -(24, 22), -(17, 23), -(34, 24), -(28, 25), -(30, 26), -(19, 27), -(35, 28), -(36, 29), -(11, 30), -(12, 31), -(10, 32), -(20, 33), -(14, 34), -(37, 35), -(29, 36), -(15, 37), -(13, 38), -(25, 39), -(38, 40), -(26, 41), -(18, 42), -(18, 43), -(16, 44), -(31, 45), -(32, 46), -(21, 47); +INSERT INTO `rbac_role_permissions` VALUES (5,1),(5,2),(6,3),(6,4),(6,5),(7,6),(1,7),(2,8),(3,9),(4,10),(8,11),(9,13),(33,14),(33,15),(33,16),(33,17),(33,18),(27,19),(22,20),(23,21),(24,22),(17,23),(34,24),(28,25),(30,26),(19,27),(35,28),(36,29),(11,30),(12,31),(10,32),(20,33),(14,34),(37,35),(29,36),(15,37),(13,38),(25,39),(38,40),(26,41),(18,42),(18,43),(16,44),(31,45),(32,46),(21,47); /*!40000 ALTER TABLE `rbac_role_permissions` ENABLE KEYS */; UNLOCK TABLES; @@ -559,45 +364,7 @@ CREATE TABLE `rbac_roles` ( LOCK TABLES `rbac_roles` WRITE; /*!40000 ALTER TABLE `rbac_roles` DISABLE KEYS */; -INSERT INTO `rbac_roles` VALUES -(1, 'Player Commands'), -(2, 'Moderator Commands'), -(3, 'GameMaster Commands'), -(4, 'Administrator Commands'), -(5, 'Quick Login/Logout'), -(6, 'Use Battleground/Arenas'), -(7, 'Use Dungeon Finder'), -(8, 'Log GM trades'), -(9, 'Skip Instance required bosses check'), -(10, 'Ticket management'), -(11, 'Instant .save'), -(12, 'Allow params with .unstuck'), -(13, 'Full HP after resurrect'), -(14, 'Appear in GM ingame list'), -(15, 'Use staff badge in chat'), -(16, 'Receive global GM messages/texts'), -(17, 'Skip over-speed ping check'), -(18, 'Allows Admin Opcodes'), -(19, 'Two side mail interaction'), -(20, 'Notify if a command was not found'), -(21, 'Enables lower security than target check'), -(22, 'Skip disable map check'), -(23, 'Skip reset talents when used more than allowed check'), -(24, 'Skip spam chat check'), -(25, 'Restore saved gm setting states'), -(26, 'Use Config option START_GM_LEVEL to assign new character level'), -(27, 'Skips needed requirements to use channel check'), -(28, 'Allow say chat between factions'), -(29, 'Filter whispers'), -(30, 'Allow channel chat between factions'), -(31, 'Join channels without announce'), -(32, 'Change channel settings without being channel moderator'), -(33, 'Skip character creation checks'), -(34, 'Two side faction characters on the same account'), -(35, 'See two side who list'), -(36, 'Add friends of other faction'), -(37, 'See all security levels with who command'), -(38, 'Allows to add a gm to friend list'); +INSERT INTO `rbac_roles` VALUES (1,'Player Commands'),(2,'Moderator Commands'),(3,'GameMaster Commands'),(4,'Administrator Commands'),(5,'Quick Login/Logout'),(6,'Use Battleground/Arenas'),(7,'Use Dungeon Finder'),(8,'Log GM trades'),(9,'Skip Instance required bosses check'),(10,'Ticket management'),(11,'Instant .save'),(12,'Allow params with .unstuck'),(13,'Full HP after resurrect'),(14,'Appear in GM ingame list'),(15,'Use staff badge in chat'),(16,'Receive global GM messages/texts'),(17,'Skip over-speed ping check'),(18,'Allows Admin Opcodes'),(19,'Two side mail interaction'),(20,'Notify if a command was not found'),(21,'Enables lower security than target check'),(22,'Skip disable map check'),(23,'Skip reset talents when used more than allowed check'),(24,'Skip spam chat check'),(25,'Restore saved gm setting states'),(26,'Use Config option START_GM_LEVEL to assign new character level'),(27,'Skip needed requirements to use channel check'),(28,'Allow say chat between factions'),(29,'Filter whispers'),(30,'Allow channel chat between factions'),(31,'Join channels without announce'),(32,'Change channel settings without being channel moderator'),(33,'Skip character creation checks'),(34,'Two side faction characters on the same account'),(35,'See two side who list'),(36,'Add friends of other faction'),(37,'See all security levels with who command'),(38,'Allows to add a gm to friend list'); /*!40000 ALTER TABLE `rbac_roles` ENABLE KEYS */; UNLOCK TABLES; @@ -722,4 +489,4 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2013-02-04 16:07:23 +-- Dump completed on 2013-02-26 23:48:17 diff --git a/sql/updates/auth/2013_02_25_00_auth_misc.sql b/sql/updates/auth/2013_02_25_00_auth_misc.sql index 3cce3c0d5ce..8769060ba9d 100644 --- a/sql/updates/auth/2013_02_25_00_auth_misc.sql +++ b/sql/updates/auth/2013_02_25_00_auth_misc.sql @@ -1,5 +1,5 @@ ALTER TABLE `rbac_roles` MODIFY COLUMN `name` varchar(100) NOT NULL COMMENT 'Role name'; -ALTER TABLE `rbac_roles` MODIFY COLUMN `name` varchar(100) NOT NULL COMMENT 'Group name'; +ALTER TABLE `rbac_groups` MODIFY COLUMN `name` varchar(100) NOT NULL COMMENT 'Group name'; -- Add new permission DELETE FROM `rbac_permissions` WHERE `id` = 11; diff --git a/sql/updates/auth/2013_02_25_11_auth_misc.sql b/sql/updates/auth/2013_02_25_11_auth_misc.sql index 90c19526b06..b5f9767ca7b 100644 --- a/sql/updates/auth/2013_02_25_11_auth_misc.sql +++ b/sql/updates/auth/2013_02_25_11_auth_misc.sql @@ -1,14 +1,14 @@ -- Add new permissions DELETE FROM `rbac_permissions` WHERE `id` IN (19, 25, 36); INSERT INTO `rbac_permissions` (`id`, `name`) VALUES -(19, 'Skips needed requirements to use channel check'), +(19, 'Skip needed requirements to use channel check'), (25, 'Allow say chat between factions'), (36, 'Filter whispers'); -- Add new role DELETE FROM `rbac_roles` WHERE `id` IN (27, 28, 29); INSERT INTO `rbac_roles` (`id`, `name`) VALUES -(27, 'Skips needed requirements to use channel check'), +(27, 'Skip needed requirements to use channel check'), (28, 'Allow say chat between factions'), (29, 'Filter whispers'); diff --git a/sql/updates/auth/2013_02_25_14_auth_misc.sql b/sql/updates/auth/2013_02_25_14_auth_misc.sql index f88280feae7..59189304342 100644 --- a/sql/updates/auth/2013_02_25_14_auth_misc.sql +++ b/sql/updates/auth/2013_02_25_14_auth_misc.sql @@ -7,7 +7,7 @@ INSERT INTO `rbac_permissions` (`id`, `name`) VALUES (40, 'Allows to add a gm to friend list'); -- Add new role -DELETE FROM `rbac_roles` WHERE `id` IN (33, 34); +DELETE FROM `rbac_roles` WHERE `id` IN (35, 36, 37, 38); INSERT INTO `rbac_roles` (`id`, `name`) VALUES (35, 'See two side who list'), (36, 'Add friends of other faction'), diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 39534c1c2bf..4d549b3b046 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -322,8 +322,8 @@ bool Creature::InitEntry(uint32 Entry, uint32 /*team*/, const CreatureData* data SetByteValue(UNIT_FIELD_BYTES_0, 2, minfo->gender); // Load creature equipment - if (!data || data->equipmentId == 0) // use default from the template - LoadEquipment(GetOriginalEquipmentId()); + if (!data || data->equipmentId == 0) + LoadEquipment(); // use default equipment (if available) else if (data && data->equipmentId != 0) // override, 0 means no equipment { m_originalEquipmentId = data->equipmentId; diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index 2a4f4a15037..3cd937216b8 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -1259,7 +1259,7 @@ void WorldSession::HandleWhoisOpcode(WorldPacket& recvData) std::string charname; recvData >> charname; - if (HasPermission(RBAC_PERM_OPCODE_WHOIS)) + if (!HasPermission(RBAC_PERM_OPCODE_WHOIS)) { SendNotification(LANG_YOU_NOT_HAVE_PERMISSION); return; -- cgit v1.2.3 From 480c6cf4dd8965627aa7bc6e903558f2fa5c3ea6 Mon Sep 17 00:00:00 2001 From: Spp Date: Wed, 27 Feb 2013 03:29:11 +0100 Subject: Core/RBAC: Add .reload rbac command and prevent possible crash if rbac_permissions has wrong data --- sql/updates/world/2013_02_27_00_world_command.sql | 3 + src/server/game/Accounts/AccountMgr.cpp | 61 +++++--- src/server/game/Accounts/AccountMgr.h | 1 + src/server/game/Accounts/RBAC.cpp | 162 +++++++++++++++++++++- src/server/game/Accounts/RBAC.h | 8 +- src/server/game/Server/WorldSession.cpp | 20 ++- src/server/game/Server/WorldSession.h | 1 + src/server/game/World/World.cpp | 8 ++ src/server/game/World/World.h | 3 + src/server/scripts/Commands/cs_reload.cpp | 11 ++ src/server/shared/Logging/Appender.cpp | 2 + src/server/shared/Logging/Appender.h | 3 +- src/server/worldserver/worldserver.conf.dist | 1 + 13 files changed, 255 insertions(+), 29 deletions(-) create mode 100644 sql/updates/world/2013_02_27_00_world_command.sql (limited to 'src') diff --git a/sql/updates/world/2013_02_27_00_world_command.sql b/sql/updates/world/2013_02_27_00_world_command.sql new file mode 100644 index 00000000000..a83e7ec3c04 --- /dev/null +++ b/sql/updates/world/2013_02_27_00_world_command.sql @@ -0,0 +1,3 @@ +DELETE FROM `command` WHERE `name` = 'reload rbac'; +INSERT INTO `command` (`name`,`security`,`help`) VALUES +('reload rbac',3,'Syntax: .reload rbac\nReload rbac system.'); diff --git a/src/server/game/Accounts/AccountMgr.cpp b/src/server/game/Accounts/AccountMgr.cpp index 7172efaac0e..83f1252e1f1 100644 --- a/src/server/game/Accounts/AccountMgr.cpp +++ b/src/server/game/Accounts/AccountMgr.cpp @@ -31,14 +31,7 @@ AccountMgr::AccountMgr() AccountMgr::~AccountMgr() { - for (RBACPermissionsContainer::iterator itr = _permissions.begin(); itr != _permissions.end(); ++itr) - delete itr->second; - - for (RBACRolesContainer::iterator itr = _roles.begin(); itr != _roles.end(); ++itr) - delete itr->second; - - for (RBACGroupsContainer::iterator itr = _groups.begin(); itr != _groups.end(); ++itr) - delete itr->second; + ClearRBAC(); } AccountOpResult AccountMgr::CreateAccount(std::string username, std::string password) @@ -337,11 +330,15 @@ bool AccountMgr::IsConsoleAccount(uint32 gmlevel) void AccountMgr::LoadRBAC() { + ClearRBAC(); + + sLog->outInfo(LOG_FILTER_RBAC, "AccountMgr::LoadRBAC"); uint32 oldMSTime = getMSTime(); uint32 count1 = 0; uint32 count2 = 0; uint32 count3 = 0; + sLog->outDebug(LOG_FILTER_RBAC, "AccountMgr::LoadRBAC: Loading permissions"); QueryResult result = LoginDatabase.Query("SELECT id, name FROM rbac_permissions"); if (!result) { @@ -358,6 +355,7 @@ void AccountMgr::LoadRBAC() } while (result->NextRow()); + sLog->outDebug(LOG_FILTER_RBAC, "AccountMgr::LoadRBAC: Loading roles"); result = LoginDatabase.Query("SELECT id, name FROM rbac_roles"); if (!result) { @@ -374,6 +372,7 @@ void AccountMgr::LoadRBAC() } while (result->NextRow()); + sLog->outDebug(LOG_FILTER_RBAC, "AccountMgr::LoadRBAC: Loading role permissions"); result = LoginDatabase.Query("SELECT roleId, permissionId FROM rbac_role_permissions"); if (!result) { @@ -390,6 +389,7 @@ void AccountMgr::LoadRBAC() } while (result->NextRow()); + sLog->outDebug(LOG_FILTER_RBAC, "AccountMgr::LoadRBAC: Loading groups"); result = LoginDatabase.Query("SELECT id, name FROM rbac_groups"); if (!result) { @@ -406,6 +406,7 @@ void AccountMgr::LoadRBAC() } while (result->NextRow()); + sLog->outDebug(LOG_FILTER_RBAC, "AccountMgr::LoadRBAC: Loading group roles"); result = LoginDatabase.Query("SELECT groupId, roleId FROM rbac_group_roles"); if (!result) { @@ -422,6 +423,7 @@ void AccountMgr::LoadRBAC() } while (result->NextRow()); + sLog->outDebug(LOG_FILTER_RBAC, "AccountMgr::LoadRBAC: Loading security level groups"); result = LoginDatabase.Query("SELECT secId, groupId FROM rbac_security_level_groups ORDER by secId ASC"); if (!result) { @@ -445,6 +447,7 @@ void AccountMgr::LoadRBAC() sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u permission definitions, %u role definitions and %u group definitions in %u ms", count1, count2, count3, GetMSTimeDiffToNow(oldMSTime)); + sLog->outDebug(LOG_FILTER_RBAC, "AccountMgr::LoadRBAC: Loading default groups"); // Load default groups to be added to any RBAC Object. std::string defaultGroups = ConfigMgr::GetStringDefault("RBAC.DefaultGroups", ""); Tokenizer tokens(defaultGroups, ','); @@ -518,42 +521,68 @@ void AccountMgr::UpdateAccountAccess(RBACData* rbac, uint32 accountId, uint8 sec } } -RBACGroup const* AccountMgr::GetRBACGroup(uint32 group) const +RBACGroup const* AccountMgr::GetRBACGroup(uint32 groupId) const { - RBACGroupsContainer::const_iterator it = _groups.find(group); + sLog->outTrace(LOG_FILTER_RBAC, "AccountMgr::GetRBACGroup: groupId: %u", groupId); + RBACGroupsContainer::const_iterator it = _groups.find(groupId); if (it != _groups.end()) return it->second; return NULL; } -RBACRole const* AccountMgr::GetRBACRole(uint32 role) const +RBACRole const* AccountMgr::GetRBACRole(uint32 roleId) const { - RBACRolesContainer::const_iterator it = _roles.find(role); + sLog->outTrace(LOG_FILTER_RBAC, "AccountMgr::GetRBACRole: roleId: %u", roleId); + RBACRolesContainer::const_iterator it = _roles.find(roleId); if (it != _roles.end()) return it->second; return NULL; } -RBACPermission const* AccountMgr::GetRBACPermission(uint32 permission) const +RBACPermission const* AccountMgr::GetRBACPermission(uint32 permissionId) const { - RBACPermissionsContainer::const_iterator it = _permissions.find(permission); + sLog->outTrace(LOG_FILTER_RBAC, "AccountMgr::GetRBACPermission: roleId: %u", permissionId); + RBACPermissionsContainer::const_iterator it = _permissions.find(permissionId); if (it != _permissions.end()) return it->second; return NULL; } -bool AccountMgr::HasPermission(uint32 accountId, uint32 permission, uint32 realmId) +bool AccountMgr::HasPermission(uint32 accountId, uint32 permissionId, uint32 realmId) { if (!accountId) + { + sLog->outError(LOG_FILTER_RBAC, "AccountMgr::HasPermission: Wrong accountId 0"); return false; + } RBACData* rbac = new RBACData(accountId, "", realmId); rbac->LoadFromDB(); - bool hasPermission = rbac->HasPermission(permission); + bool hasPermission = rbac->HasPermission(permissionId); delete rbac; + sLog->outDebug(LOG_FILTER_RBAC, "AccountMgr::HasPermission [AccountId: %u, PermissionId: %u, realmId: %d]: %u", + accountId, permissionId, realmId, hasPermission); return hasPermission; } + +void AccountMgr::ClearRBAC() +{ + for (RBACPermissionsContainer::iterator itr = _permissions.begin(); itr != _permissions.end(); ++itr) + delete itr->second; + + for (RBACRolesContainer::iterator itr = _roles.begin(); itr != _roles.end(); ++itr) + delete itr->second; + + for (RBACGroupsContainer::iterator itr = _groups.begin(); itr != _groups.end(); ++itr) + delete itr->second; + + _permissions.clear(); + _roles.clear(); + _groups.clear(); + _defaultGroups.clear(); + _defaultSecGroups.clear(); +} diff --git a/src/server/game/Accounts/AccountMgr.h b/src/server/game/Accounts/AccountMgr.h index 28373456994..16b4355585a 100644 --- a/src/server/game/Accounts/AccountMgr.h +++ b/src/server/game/Accounts/AccountMgr.h @@ -82,6 +82,7 @@ class AccountMgr RBACGroupContainer const& GetRBACDefaultGroups() const { return _defaultGroups; } private: + void ClearRBAC(); RBACPermissionsContainer _permissions; RBACRolesContainer _roles; RBACGroupsContainer _groups; diff --git a/src/server/game/Accounts/RBAC.cpp b/src/server/game/Accounts/RBAC.cpp index 121c9faae76..d26d557e2f4 100644 --- a/src/server/game/Accounts/RBAC.cpp +++ b/src/server/game/Accounts/RBAC.cpp @@ -19,21 +19,67 @@ #include "AccountMgr.h" #include "DatabaseEnv.h" +void RBACRole::GrantPermission(uint32 permissionId) +{ + if (permissionId < RBAC_PERM_MAX) + { + sLog->outTrace(LOG_FILTER_RBAC, "RBACRole::GrantPermission (Role %u, Permission %u). Ok", GetId(), permissionId); + _perms.set(permissionId); + } + else + sLog->outError(LOG_FILTER_RBAC, "RBACRole::GrantPermission (Role %u, Permission %u). Permission not lower than %u", + GetId(), permissionId, RBAC_PERM_MAX); +} + +void RBACRole::RevokePermission(uint32 permissionId) +{ + if (permissionId < RBAC_PERM_MAX) + { + sLog->outTrace(LOG_FILTER_RBAC, "RBACRole::RevokePermission (Role %u, Permission %u). Ok", GetId(), permissionId); + _perms.reset(permissionId); + } + else + sLog->outError(LOG_FILTER_RBAC, "RBACRole::RevokePermission (Role %u, Permission %u). Permission not lower than %u", + GetId(), permissionId, RBAC_PERM_MAX); +} + +void RBACGroup::GrantRole(uint32 roleId) +{ + sLog->outTrace(LOG_FILTER_RBAC, "RBACRole::GrantPermission (Role %u, Permission %u). Ok", GetId(), roleId); + _roles.insert(roleId); +} + +void RBACGroup::RevokeRole(uint32 roleId) +{ + sLog->outTrace(LOG_FILTER_RBAC, "RBACRole::GrantPermission (Role %u, Permission %u). Ok", GetId(), roleId); + _roles.erase(roleId); +} + RBACCommandResult RBACData::AddGroup(uint32 groupId, int32 realmId /* = 0 */) { // Check if group Id exists RBACGroup const* group = sAccountMgr->GetRBACGroup(groupId); if (!group) + { + sLog->outTrace(LOG_FILTER_RBAC, "RBACData::AddGroup [Id: %u Name: %s] (Group %u, RealmId %d). Group does not exists", + GetId(), GetName().c_str(), groupId, realmId); return RBAC_ID_DOES_NOT_EXISTS; + } // Already added? std::pair::iterator, bool> ret = _groups.insert(groupId); if (!ret.second) + { + sLog->outTrace(LOG_FILTER_RBAC, "RBACData::AddGroup [Id: %u Name: %s] (Group %u, RealmId %d). Group Already added", + GetId(), GetName().c_str(), groupId, realmId); return RBAC_CANT_ADD_ALREADY_ADDED; + } // Do not save to db when loading data from DB (realmId = 0) if (realmId) { + sLog->outTrace(LOG_FILTER_RBAC, "RBACData::AddGroup [Id: %u Name: %s] (Group %u, RealmId %d). Added and DB updated", + GetId(), GetName().c_str(), groupId, realmId); PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_RBAC_ACCOUNT_GROUP); stmt->setUInt32(0, GetId()); stmt->setUInt32(1, groupId); @@ -42,6 +88,9 @@ RBACCommandResult RBACData::AddGroup(uint32 groupId, int32 realmId /* = 0 */) CalculateNewPermissions(); } + else + sLog->outTrace(LOG_FILTER_RBAC, "RBACData::AddGroup [Id: %u Name: %s] (Group %u, RealmId %d). Added", + GetId(), GetName().c_str(), groupId, realmId); return RBAC_OK; } @@ -50,11 +99,17 @@ RBACCommandResult RBACData::RemoveGroup(uint32 groupId, int32 realmId /* = 0 */) { // could remove it? if (!_groups.erase(groupId)) + { + sLog->outTrace(LOG_FILTER_RBAC, "RBACData::RemoveGroup [Id: %u Name: %s] (Group %u, RealmId %d). Group not in list", + GetId(), GetName().c_str(), groupId, realmId); return RBAC_CANT_REVOKE_NOT_IN_LIST; + } // Do not save to db when loading data from DB (realmId = 0) if (realmId) { + sLog->outTrace(LOG_FILTER_RBAC, "RBACData::RemoveGroup [Id: %u Name: %s] (Group %u, RealmId %d). Removed and DB updated", + GetId(), GetName().c_str(), groupId, realmId); PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_RBAC_ACCOUNT_GROUP); stmt->setUInt32(0, GetId()); stmt->setUInt32(1, groupId); @@ -63,6 +118,9 @@ RBACCommandResult RBACData::RemoveGroup(uint32 groupId, int32 realmId /* = 0 */) CalculateNewPermissions(); } + else + sLog->outTrace(LOG_FILTER_RBAC, "RBACData::RemoveGroup [Id: %u Name: %s] (Group %u, RealmId %d). Removed", + GetId(), GetName().c_str(), groupId, realmId); return RBAC_OK; } @@ -72,23 +130,40 @@ RBACCommandResult RBACData::GrantRole(uint32 roleId, int32 realmId /* = 0*/) // Check if role Id exists RBACRole const* role = sAccountMgr->GetRBACRole(roleId); if (!role) + { + sLog->outTrace(LOG_FILTER_RBAC, "RBACData::GrantRole [Id: %u Name: %s] (Role %u, RealmId %d). Role does not exists", + GetId(), GetName().c_str(), roleId, realmId); return RBAC_ID_DOES_NOT_EXISTS; + } // Check if already added in denied list if (_deniedRoles.find(roleId) != _deniedRoles.end()) + { + sLog->outTrace(LOG_FILTER_RBAC, "RBACData::GrantRole [Id: %u Name: %s] (Role %u, RealmId %d). Role in deny list", + GetId(), GetName().c_str(), roleId, realmId); return RBAC_IN_DENIED_LIST; + } // Already added? std::pair::iterator, bool> ret = _grantedRoles.insert(roleId); if (!ret.second) + { + sLog->outTrace(LOG_FILTER_RBAC, "RBACData::GrantRole [Id: %u Name: %s] (Role %u, RealmId %d). Role already granted", + GetId(), GetName().c_str(), roleId, realmId); return RBAC_CANT_ADD_ALREADY_ADDED; + } // Do not save to db when loading data from DB (realmId = 0) if (realmId) { + sLog->outTrace(LOG_FILTER_RBAC, "RBACData::GrantRole [Id: %u Name: %s] (Role %u, RealmId %d). Ok and DB updated", + GetId(), GetName().c_str(), roleId, realmId); SaveRole(roleId, true, realmId); CalculateNewPermissions(); } + else + sLog->outTrace(LOG_FILTER_RBAC, "RBACData::GrantRole [Id: %u Name: %s] (Role %u, RealmId %d). Ok", + GetId(), GetName().c_str(), roleId, realmId); return RBAC_OK; } @@ -98,23 +173,40 @@ RBACCommandResult RBACData::DenyRole(uint32 roleId, int32 realmId /* = 0*/) // Check if role Id exists RBACRole const* role = sAccountMgr->GetRBACRole(roleId); if (!role) + { + sLog->outTrace(LOG_FILTER_RBAC, "RBACData::DenyRole [Id: %u Name: %s] (Role %u, RealmId %d). Role does not exists", + GetId(), GetName().c_str(), roleId, realmId); return RBAC_ID_DOES_NOT_EXISTS; + } // Check if already added in granted list if (_grantedRoles.find(roleId) != _grantedRoles.end()) + { + sLog->outTrace(LOG_FILTER_RBAC, "RBACData::DenyRole [Id: %u Name: %s] (Role %u, RealmId %d). Role in grant list", + GetId(), GetName().c_str(), roleId, realmId); return RBAC_IN_GRANTED_LIST; + } // Already added? std::pair::iterator, bool> ret = _deniedRoles.insert(roleId); if (!ret.second) + { + sLog->outTrace(LOG_FILTER_RBAC, "RBACData::DenyRole [Id: %u Name: %s] (Role %u, RealmId %d). Role already denied", + GetId(), GetName().c_str(), roleId, realmId); return RBAC_CANT_ADD_ALREADY_ADDED; + } // Do not save to db when loading data from DB (realmId = 0) if (realmId) { + sLog->outTrace(LOG_FILTER_RBAC, "RBACData::DenyRole [Id: %u Name: %s] (Role %u, RealmId %d). Ok and DB updated", + GetId(), GetName().c_str(), roleId, realmId); SaveRole(roleId, false, realmId); CalculateNewPermissions(); } + else + sLog->outTrace(LOG_FILTER_RBAC, "RBACData::DenyRole [Id: %u Name: %s] (Role %u, RealmId %d). Ok", + GetId(), GetName().c_str(), roleId, realmId); return RBAC_OK; } @@ -135,11 +227,17 @@ RBACCommandResult RBACData::RevokeRole(uint32 roleId, int32 realmId /* = 0*/) // could remove it? if (!revoked) + { + sLog->outTrace(LOG_FILTER_RBAC, "RBACData::RevokeRole [Id: %u Name: %s] (Role %u, RealmId %d). Not granted or revoked", + GetId(), GetName().c_str(), roleId, realmId); return RBAC_CANT_REVOKE_NOT_IN_LIST; + } // Do not save to db when loading data from DB (realmId = 0) if (realmId) { + sLog->outTrace(LOG_FILTER_RBAC, "RBACData::RevokeRole [Id: %u Name: %s] (Role %u, RealmId %d). Ok and DB updated", + GetId(), GetName().c_str(), roleId, realmId); PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_RBAC_ACCOUNT_ROLE); stmt->setUInt32(0, GetId()); stmt->setUInt32(1, roleId); @@ -148,6 +246,9 @@ RBACCommandResult RBACData::RevokeRole(uint32 roleId, int32 realmId /* = 0*/) CalculateNewPermissions(); } + else + sLog->outTrace(LOG_FILTER_RBAC, "RBACData::RevokeRole [Id: %u Name: %s] (Role %u, RealmId %d). Ok", + GetId(), GetName().c_str(), roleId, realmId); return RBAC_OK; } @@ -157,24 +258,41 @@ RBACCommandResult RBACData::GrantPermission(uint32 permissionId, int32 realmId / // Check if permission Id exists RBACPermission const* perm = sAccountMgr->GetRBACPermission(permissionId); if (!perm) + { + sLog->outTrace(LOG_FILTER_RBAC, "RBACData::GrantPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Permission does not exists", + GetId(), GetName().c_str(), permissionId, realmId); return RBAC_ID_DOES_NOT_EXISTS; + } // Check if already added in denied list if (_deniedPerms.test(permissionId)) + { + sLog->outTrace(LOG_FILTER_RBAC, "RBACData::GrantPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Permission in deny list", + GetId(), GetName().c_str(), permissionId, realmId); return RBAC_IN_DENIED_LIST; + } // Already added? if (_grantedPerms.test(permissionId)) + { + sLog->outTrace(LOG_FILTER_RBAC, "RBACData::GrantPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Permission already granted", + GetId(), GetName().c_str(), permissionId, realmId); return RBAC_CANT_ADD_ALREADY_ADDED; + } _grantedPerms.set(permissionId); // Do not save to db when loading data from DB (realmId = 0) if (realmId) { + sLog->outTrace(LOG_FILTER_RBAC, "RBACData::GrantPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Ok and DB updated", + GetId(), GetName().c_str(), permissionId, realmId); SavePermission(permissionId, true, realmId); CalculateNewPermissions(); } + else + sLog->outTrace(LOG_FILTER_RBAC, "RBACData::GrantPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Ok", + GetId(), GetName().c_str(), permissionId, realmId); return RBAC_OK; } @@ -184,24 +302,41 @@ RBACCommandResult RBACData::DenyPermission(uint32 permissionId, int32 realmId /* // Check if permission Id exists RBACPermission const* perm = sAccountMgr->GetRBACPermission(permissionId); if (!perm) + { + sLog->outTrace(LOG_FILTER_RBAC, "RBACData::DenyPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Permission does not exists", + GetId(), GetName().c_str(), permissionId, realmId); return RBAC_ID_DOES_NOT_EXISTS; + } // Check if already added in granted list if (_grantedPerms.test(permissionId)) + { + sLog->outTrace(LOG_FILTER_RBAC, "RBACData::DenyPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Permission in grant list", + GetId(), GetName().c_str(), permissionId, realmId); return RBAC_IN_GRANTED_LIST; + } // Already added? if (_deniedPerms.test(permissionId)) + { + sLog->outTrace(LOG_FILTER_RBAC, "RBACData::DenyPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Permission already denied", + GetId(), GetName().c_str(), permissionId, realmId); return RBAC_CANT_ADD_ALREADY_ADDED; + } _deniedPerms.set(permissionId); // Do not save to db when loading data from DB (realmId = 0) if (realmId) { + sLog->outTrace(LOG_FILTER_RBAC, "RBACData::DenyPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Ok and DB updated", + GetId(), GetName().c_str(), permissionId, realmId); SavePermission(permissionId, false, realmId); CalculateNewPermissions(); } + else + sLog->outTrace(LOG_FILTER_RBAC, "RBACData::DenyPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Ok", + GetId(), GetName().c_str(), permissionId, realmId); return RBAC_OK; } @@ -216,32 +351,44 @@ void RBACData::SavePermission(uint32 permission, bool granted, int32 realmId) LoginDatabase.Execute(stmt); } -RBACCommandResult RBACData::RevokePermission(uint32 permission, int32 realmId /* = 0*/) +RBACCommandResult RBACData::RevokePermission(uint32 permissionId, int32 realmId /* = 0*/) { // Check if it's present in any list - if (!_grantedPerms.test(permission) && !_deniedPerms.test(permission)) + if (!_grantedPerms.test(permissionId) && !_deniedPerms.test(permissionId)) + { + sLog->outTrace(LOG_FILTER_RBAC, "RBACData::RevokePermission [Id: %u Name: %s] (Permission %u, RealmId %d). Not granted or revoked", + GetId(), GetName().c_str(), permissionId, realmId); return RBAC_CANT_REVOKE_NOT_IN_LIST; + } - _grantedPerms.reset(permission); - _deniedPerms.reset(permission); + _grantedPerms.reset(permissionId); + _deniedPerms.reset(permissionId); // Do not save to db when loading data from DB (realmId = 0) if (realmId) { + sLog->outTrace(LOG_FILTER_RBAC, "RBACData::RevokePermission [Id: %u Name: %s] (Permission %u, RealmId %d). Ok and DB updated", + GetId(), GetName().c_str(), permissionId, realmId); PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_RBAC_ACCOUNT_PERMISSION); stmt->setUInt32(0, GetId()); - stmt->setUInt32(1, permission); + stmt->setUInt32(1, permissionId); stmt->setInt32(2, realmId); LoginDatabase.Execute(stmt); CalculateNewPermissions(); } + else + sLog->outTrace(LOG_FILTER_RBAC, "RBACData::RevokePermission [Id: %u Name: %s] (Permission %u, RealmId %d). Ok", + GetId(), GetName().c_str(), permissionId, realmId); return RBAC_OK; } void RBACData::LoadFromDB() { + sLog->outInfo(LOG_FILTER_RBAC, "RBACData::LoadFromDB [Id: %u Name: %s]", GetId(), GetName().c_str()); + sLog->outDebug(LOG_FILTER_RBAC, "RBACData::LoadFromDB [Id: %u Name: %s]: Loading groups", GetId(), GetName().c_str()); + // Load account group that affect current realm PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_RBAC_ACCOUNT_GROUPS); stmt->setUInt32(0, GetId()); @@ -258,6 +405,7 @@ void RBACData::LoadFromDB() while (result->NextRow()); } + sLog->outDebug(LOG_FILTER_RBAC, "RBACData::LoadFromDB [Id: %u Name: %s]: Loading roles", GetId(), GetName().c_str()); // Load account roles (granted and denied) that affect current realm stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_RBAC_ACCOUNT_ROLES); stmt->setUInt32(0, GetId()); @@ -277,6 +425,7 @@ void RBACData::LoadFromDB() while (result->NextRow()); } + sLog->outDebug(LOG_FILTER_RBAC, "RBACData::LoadFromDB [Id: %u Name: %s]: Loading permissions", GetId(), GetName().c_str()); // Load account permissions (granted and denied) that affect current realm stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_RBAC_ACCOUNT_PERMISSIONS); stmt->setUInt32(0, GetId()); @@ -296,11 +445,13 @@ void RBACData::LoadFromDB() while (result->NextRow()); } + sLog->outDebug(LOG_FILTER_RBAC, "RBACData::LoadFromDB [Id: %u Name: %s]: Adding default groups", GetId(), GetName().c_str()); // Add default groups RBACGroupContainer const& groups = sAccountMgr->GetRBACDefaultGroups(); for (RBACGroupContainer::const_iterator itr = groups.begin(); itr != groups.end(); ++itr) AddGroup(*itr); + sLog->outDebug(LOG_FILTER_RBAC, "RBACData::LoadFromDB [Id: %u Name: %s]: Calculating global permissions", GetId(), GetName().c_str()); // Force calculation of permissions, it wasn't performed at load time // while adding groups, roles and permissions CalculateNewPermissions(); @@ -308,6 +459,7 @@ void RBACData::LoadFromDB() void RBACData::CalculateNewPermissions() { + sLog->outTrace(LOG_FILTER_RBAC, "RBACData::LoadFromDB [Id: %u Name: %s]: Calculating global permissions", GetId(), GetName().c_str()); // Get the list of directly granted roles RBACRoleContainer tempGrantedRoles = GetGrantedRoles(); diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h index 0bd193d3841..779b0ece021 100644 --- a/src/server/game/Accounts/RBAC.h +++ b/src/server/game/Accounts/RBAC.h @@ -146,9 +146,9 @@ class RBACRole: public RBACObject /// Gets the Permissions assigned to this role RBACPermissionContainer const& GetPermissions() const { return _perms; } /// Grants a Permission (Adds) - void GrantPermission(uint32 id) { _perms.set(id); } + void GrantPermission(uint32 id); /// Revokes a Permission (Removes) - void RevokePermission(uint32 id) { _perms.reset(id); } + void RevokePermission(uint32 id); private: RBACPermissionContainer _perms; ///> Set of permissions @@ -164,9 +164,9 @@ class RBACGroup: public RBACObject /// Gets the Roles assigned to this group RBACRoleContainer const& GetRoles() const { return _roles; } /// Grants a Role (Adds) - void GrantRole(uint32 role) { _roles.insert(role); } + void GrantRole(uint32 role); /// Revokes a Role (Removes) - void RevokeRole(uint32 role) { _roles.erase(role); } + void RevokeRole(uint32 role); private: RBACRoleContainer _roles; ///> Set of Roles diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 8bf92d95248..8ebb85d8084 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -1175,11 +1175,13 @@ void WorldSession::LoadPermissions() { uint32 id = GetAccountId(); std::string name; - int32 realmId = ConfigMgr::GetIntDefault("RealmID", 0); AccountMgr::GetName(id, name); - _RBACData = new RBACData(id, name, realmId); + _RBACData = new RBACData(id, name, realmID); _RBACData->LoadFromDB(); + + sLog->outDebug(LOG_FILTER_RBAC, "WorldSession::LoadPermissions [AccountId: %u, Name: %s, realmId: %d]", + id, name.c_str(), realmID); } RBACData* WorldSession::GetRBACData() @@ -1192,5 +1194,17 @@ bool WorldSession::HasPermission(uint32 permission) if (!_RBACData) LoadPermissions(); - return _RBACData->HasPermission(permission); + bool hasPermission = _RBACData->HasPermission(permission); + sLog->outDebug(LOG_FILTER_RBAC, "WorldSession::HasPermission [AccountId: %u, Name: %s, realmId: %d]", + _RBACData->GetId(), _RBACData->GetName().c_str(), realmID); + + return hasPermission; +} + +void WorldSession::InvalidateRBACData() +{ + sLog->outDebug(LOG_FILTER_RBAC, "WorldSession::InvalidateRBACData [AccountId: %u, Name: %s, realmId: %d]", + _RBACData->GetId(), _RBACData->GetName().c_str(), realmID); + delete _RBACData; + _RBACData = NULL; } diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 20fa7d9335d..b714cd71e6d 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -220,6 +220,7 @@ class WorldSession RBACData* GetRBACData(); bool HasPermission(uint32 permissionId); void LoadPermissions(); + void InvalidateRBACData(); // Used to force LoadPermissions at next HasPermission check AccountTypes GetSecurity() const { return _security; } uint32 GetAccountId() const { return _accountId; } diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 955f3b7b99f..bcd69ec70ed 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -3122,3 +3122,11 @@ CharacterNameData const* World::GetCharacterNameData(uint32 guid) const else return NULL; } + +void World::ReloadRBAC() +{ + sLog->outInfo(LOG_FILTER_RBAC, "World::ReloadRBAC()"); + for (SessionMap::const_iterator itr = m_sessions.begin(); itr != m_sessions.end(); ++itr) + if (WorldSession* session = itr->second) + session->InvalidateRBACData(); +} diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index 612078f17bf..154e9972218 100644 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -739,6 +739,9 @@ class World uint32 GetCleaningFlags() const { return m_CleaningFlags; } void SetCleaningFlags(uint32 flags) { m_CleaningFlags = flags; } void ResetEventSeasonalQuests(uint16 event_id); + + void ReloadRBAC(); + protected: void _UpdateGameTime(); // callback for UpdateRealmCharacters diff --git a/src/server/scripts/Commands/cs_reload.cpp b/src/server/scripts/Commands/cs_reload.cpp index 3f15c3fe6b7..7aee1139868 100644 --- a/src/server/scripts/Commands/cs_reload.cpp +++ b/src/server/scripts/Commands/cs_reload.cpp @@ -22,6 +22,7 @@ Comment: All reload related commands Category: commandscripts EndScriptData */ +#include "AccountMgr.h" #include "AchievementMgr.h" #include "AuctionHouseMgr.h" #include "Chat.h" @@ -128,6 +129,7 @@ public: { "prospecting_loot_template", SEC_ADMINISTRATOR, true, &HandleReloadLootTemplatesProspectingCommand, "", NULL }, { "quest_poi", SEC_ADMINISTRATOR, true, &HandleReloadQuestPOICommand, "", NULL }, { "quest_template", SEC_ADMINISTRATOR, true, &HandleReloadQuestTemplateCommand, "", NULL }, + { "rbac", SEC_ADMINISTRATOR, true, &HandleReloadRBACCommand, "", NULL }, { "reference_loot_template", SEC_ADMINISTRATOR, true, &HandleReloadLootTemplatesReferenceCommand, "", NULL }, { "reserved_name", SEC_ADMINISTRATOR, true, &HandleReloadReservedNameCommand, "", NULL }, { "reputation_reward_rate", SEC_ADMINISTRATOR, true, &HandleReloadReputationRewardRateCommand, "", NULL }, @@ -1242,6 +1244,15 @@ public: handler->SendGlobalGMSysMessage("Vehicle template accessories reloaded."); return true; } + + static bool HandleReloadRBACCommand(ChatHandler* handler, const char* /*args*/) + { + sLog->outInfo(LOG_FILTER_GENERAL, "Reloading RBAC tables..."); + sAccountMgr->LoadRBAC(); + sWorld->ReloadRBAC(); + handler->SendGlobalGMSysMessage("RBAC data reloaded."); + return true; + } }; void AddSC_reload_commandscript() diff --git a/src/server/shared/Logging/Appender.cpp b/src/server/shared/Logging/Appender.cpp index 1d215e1212e..efb141d1060 100644 --- a/src/server/shared/Logging/Appender.cpp +++ b/src/server/shared/Logging/Appender.cpp @@ -216,6 +216,8 @@ char const* Appender::getLogFilterTypeString(LogFilterType type) return "OPCODE"; case LOG_FILTER_SOAP: return "SOAP"; + case LOG_FILTER_RBAC: + return "RBAC"; default: break; } diff --git a/src/server/shared/Logging/Appender.h b/src/server/shared/Logging/Appender.h index 08628948b90..e11bc40c42f 100644 --- a/src/server/shared/Logging/Appender.h +++ b/src/server/shared/Logging/Appender.h @@ -67,7 +67,8 @@ enum LogFilterType LOG_FILTER_BATTLEFIELD = 39, LOG_FILTER_SERVER_LOADING = 40, LOG_FILTER_OPCODES = 41, - LOG_FILTER_SOAP = 42 + LOG_FILTER_SOAP = 42, + LOG_FILTER_RBAC = 43 }; const uint8 MaxLogFilter = 43; diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index 069c027d139..7c8aff9ce3a 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -2789,6 +2789,7 @@ Appenders=Console Server GM DBErrors Char RA Warden Chat # 40 - Server Loading # 41 - Opcodes (just id and name sent / received) # 42 - SOAP +# 43 - RBAC (Role Based Access Control) # # LogLevel # 0 - (Disabled) -- cgit v1.2.3