diff options
| author | Shauren <shauren.trinity@gmail.com> | 2013-10-07 14:30:37 +0200 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2013-10-07 14:30:37 +0200 |
| commit | fca4a5448ac476b942c330108a76032ae242711e (patch) | |
| tree | 81fe500a02353fa5079532fe53c21a4f3a269b82 /src/server/game | |
| parent | 1b56bd1b6a860c325f3e4e76d94dc367429fbb16 (diff) | |
| parent | c8f525c76e162b5b546c91628a1457f9aef43699 (diff) | |
Merge branch 'master' of github.com:TrinityCore/TrinityCore into 4.3.4
Diffstat (limited to 'src/server/game')
46 files changed, 672 insertions, 1065 deletions
diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp index a56d0f94f2d..57fd7ea2d73 100644 --- a/src/server/game/AI/SmartScripts/SmartAI.cpp +++ b/src/server/game/AI/SmartScripts/SmartAI.cpp @@ -206,7 +206,7 @@ void SmartAI::EndPath(bool fail) mLastWP = NULL; if (mCanRepeatPath) - StartPath(mRun, GetScript()->GetPathId(), mCanRepeatPath); + StartPath(mRun, GetScript()->GetPathId(), true); else GetScript()->SetPathId(0); diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index 70dd9e9d1ee..3823f7ba287 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -411,11 +411,17 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u } } + if (count == 0) + { + delete targets; + break; + } + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) { if (IsUnit(*itr)) { - uint32 emote = temp[urand(0, count)]; + uint32 emote = temp[urand(0, count - 1)]; (*itr)->ToUnit()->HandleEmoteCommand(emote); TC_LOG_DEBUG(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_RANDOM_EMOTE: Creature guidLow %u handle random emote %u", (*itr)->GetGUIDLow(), emote); @@ -835,7 +841,10 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u } } - uint32 phase = temp[urand(0, count)]; + if (count == 0) + break; + + uint32 phase = temp[urand(0, count - 1)]; SetPhase(phase); TC_LOG_DEBUG(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction: SMART_ACTION_RANDOM_PHASE: Creature %u sets event phase to %u", GetBaseObject()->GetGUIDLow(), phase); @@ -933,7 +942,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u break; instance->SetData64(e.action.setInstanceData64.field, targets->front()->GetGUID()); - TC_LOG_DEBUG(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction: SMART_ACTION_SET_INST_DATA64: Field: %u, data: "UI64FMTD, + TC_LOG_DEBUG(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction: SMART_ACTION_SET_INST_DATA64: Field: %u, data: " UI64FMTD, e.action.setInstanceData64.field, targets->front()->GetGUID()); delete targets; @@ -1475,7 +1484,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u } case SMART_ACTION_CREATE_TIMED_EVENT: { - SmartEvent ne; + SmartEvent ne = SmartEvent(); ne.type = (SMART_EVENT)SMART_EVENT_UPDATE; ne.event_chance = e.action.timeEvent.chance; if (!ne.event_chance) ne.event_chance = 100; @@ -1489,11 +1498,11 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u if (!ne.minMaxRepeat.repeatMin && !ne.minMaxRepeat.repeatMax) ne.event_flags |= SMART_EVENT_FLAG_NOT_REPEATABLE; - SmartAction ac; + SmartAction ac = SmartAction(); ac.type = (SMART_ACTION)SMART_ACTION_TRIGGER_TIMED_EVENT; ac.timeEvent.id = e.action.timeEvent.id; - SmartScriptHolder ev; + SmartScriptHolder ev = SmartScriptHolder(); ev.event = ne; ev.event_id = e.action.timeEvent.id; ev.target = e.target; @@ -1576,8 +1585,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u break; } - ObjectList* targets = GetTargets(e, unit); - if (targets) + if (ObjectList* targets = GetTargets(e, unit)) { for (ObjectList::iterator itr = targets->begin(); itr != targets->end(); ++itr) { @@ -1693,7 +1701,10 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u } } - uint32 id = temp[urand(0, count)]; + if (count == 0) + break; + + uint32 id = temp[urand(0, count - 1)]; if (e.GetTargetType() == SMART_TARGET_NONE) { TC_LOG_ERROR(LOG_FILTER_SQL, "SmartScript: Entry %d SourceType %u Event %u Action %u is using TARGET_NONE(0) for Script9 target. Please correct target_type in database.", e.entryOrGuid, e.GetScriptType(), e.GetEventType(), e.GetActionType()); @@ -2539,7 +2550,7 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /* case SMART_TARGET_CLOSEST_ENEMY: { if (me) - if (Unit* target = me->SelectNearestTarget(e.target.closestAttackable.maxDist)) + if (Unit* target = me->SelectNearestTarget(e.target.closestAttackable.maxDist, e.target.closestAttackable.playerOnly)) l->push_back(target); break; @@ -2547,7 +2558,7 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /* case SMART_TARGET_CLOSEST_FRIENDLY: { if (me) - if (Unit* target = DoFindClosestFriendlyInRange(e.target.closestFriendly.maxDist)) + if (Unit* target = DoFindClosestFriendlyInRange(e.target.closestFriendly.maxDist, e.target.closestFriendly.playerOnly)) l->push_back(target); break; @@ -3431,13 +3442,13 @@ void SmartScript::DoFindFriendlyMissingBuff(std::list<Creature*>& list, float ra cell.Visit(p, grid_creature_searcher, *me->GetMap(), *me, range); } -Unit* SmartScript::DoFindClosestFriendlyInRange(float range) +Unit* SmartScript::DoFindClosestFriendlyInRange(float range, bool playerOnly) { if (!me) return NULL; Unit* unit = NULL; - Trinity::AnyFriendlyUnitInObjectRangeCheck u_check(me, me, range); + Trinity::AnyFriendlyUnitInObjectRangeCheck u_check(me, me, range, playerOnly); Trinity::UnitLastSearcher<Trinity::AnyFriendlyUnitInObjectRangeCheck> searcher(me, unit, u_check); me->VisitNearbyObject(range, searcher); return unit; @@ -3451,16 +3462,15 @@ void SmartScript::SetScript9(SmartScriptHolder& e, uint32 entry) return; for (SmartAIEventList::iterator i = mTimedActionList.begin(); i != mTimedActionList.end(); ++i) { - if (i == mTimedActionList.begin()) - { - i->enableTimed = true;//enable processing only for the first action - } - else i->enableTimed = false; + i->enableTimed = i == mTimedActionList.begin();//enable processing only for the first action - if (e.action.timedActionList.timerType == 1) + if (e.action.timedActionList.timerType == 0) + i->event.type = SMART_EVENT_UPDATE_OOC; + else if (e.action.timedActionList.timerType == 1) i->event.type = SMART_EVENT_UPDATE_IC; else if (e.action.timedActionList.timerType > 1) i->event.type = SMART_EVENT_UPDATE; + InitTimer((*i)); } } diff --git a/src/server/game/AI/SmartScripts/SmartScript.h b/src/server/game/AI/SmartScripts/SmartScript.h index b22f2d81b26..b1b9f4d6725 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.h +++ b/src/server/game/AI/SmartScripts/SmartScript.h @@ -89,7 +89,7 @@ class SmartScript Unit* DoSelectLowestHpFriendly(float range, uint32 MinHPDiff); void DoFindFriendlyCC(std::list<Creature*>& _list, float range); void DoFindFriendlyMissingBuff(std::list<Creature*>& list, float range, uint32 spellid); - Unit* DoFindClosestFriendlyInRange(float range); + Unit* DoFindClosestFriendlyInRange(float range, bool playerOnly); void StoreTargetList(ObjectList* targets, uint32 id) { diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index 6f0dd31e11f..fba892767e3 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -410,7 +410,7 @@ enum SMART_ACTION SMART_ACTION_ACTIVATE_GOBJECT = 9, // SMART_ACTION_RANDOM_EMOTE = 10, // EmoteId1, EmoteId2, EmoteId3... SMART_ACTION_CAST = 11, // SpellId, CastFlags - SMART_ACTION_SUMMON_CREATURE = 12, // CreatureID, summonType, duration in ms, storageID, attackInvoker, + SMART_ACTION_SUMMON_CREATURE = 12, // CreatureID, summonType, duration in ms, attackInvoker SMART_ACTION_THREAT_SINGLE_PCT = 13, // Threat% SMART_ACTION_THREAT_ALL_PCT = 14, // Threat% SMART_ACTION_CALL_AREAEXPLOREDOREVENTHAPPENS = 15, // QuestID @@ -584,7 +584,6 @@ struct SmartAction uint32 creature; uint32 type; uint32 duration; - uint32 storageID; uint32 attackInvoker; } summonCreature; @@ -1023,8 +1022,8 @@ enum SMARTAI_TARGETS SMART_TARGET_ACTION_INVOKER_VEHICLE = 22, // Unit's vehicle who caused this Event to occur SMART_TARGET_OWNER_OR_SUMMONER = 23, // Unit's owner or summoner SMART_TARGET_THREAT_LIST = 24, // All units on creature's threat list - SMART_TARGET_CLOSEST_ENEMY = 25, // maxDist - SMART_TARGET_CLOSEST_FRIENDLY = 26, // maxDist + SMART_TARGET_CLOSEST_ENEMY = 25, // maxDist, playerOnly + SMART_TARGET_CLOSEST_FRIENDLY = 26, // maxDist, playerOnly SMART_TARGET_END = 27 }; @@ -1111,11 +1110,13 @@ struct SmartTarget struct { uint32 maxDist; + uint32 playerOnly; } closestAttackable; struct { uint32 maxDist; + uint32 playerOnly; } closestFriendly; struct @@ -1289,7 +1290,7 @@ enum SmartCastFlags struct SmartScriptHolder { SmartScriptHolder() : entryOrGuid(0), source_type(SMART_SCRIPT_TYPE_CREATURE) - , event_id(0), link(0), timer(0), active(false), runOnce(false) + , event_id(0), link(0), event(), action(), target(), timer(0), active(false), runOnce(false) , enableTimed(false) {} int32 entryOrGuid; diff --git a/src/server/game/Accounts/AccountMgr.cpp b/src/server/game/Accounts/AccountMgr.cpp index 819a3b85fe6..6d79c6c77a1 100644 --- a/src/server/game/Accounts/AccountMgr.cpp +++ b/src/server/game/Accounts/AccountMgr.cpp @@ -56,19 +56,8 @@ AccountOpResult AccountMgr::CreateAccount(std::string username, std::string pass LoginDatabase.DirectExecute(stmt); // Enforce saving, otherwise AddGroup can fail stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_REALM_CHARACTERS_INIT); - LoginDatabase.Execute(stmt); - // Add default rbac groups for that security level - RBACData* rbac = new RBACData(GetId(username), username, -1); - // No need to Load From DB, as it's new data - - RBACGroupContainer const& groupsToAdd = _defaultSecGroups[0]; // 0: Default sec level - for (RBACGroupContainer::const_iterator it = groupsToAdd.begin(); it != groupsToAdd.end(); ++it) - rbac->AddGroup(*it, -1); - - delete rbac; - return AOR_OK; // everything's fine } @@ -403,7 +392,7 @@ void AccountMgr::LoadRBAC() { ClearRBAC(); - TC_LOG_INFO(LOG_FILTER_RBAC, "AccountMgr::LoadRBAC"); + TC_LOG_INFO(LOG_FILTER_SERVER_LOADING, "AccountMgr::LoadRBAC"); uint32 oldMSTime = getMSTime(); uint32 count1 = 0; uint32 count2 = 0; @@ -413,7 +402,7 @@ void AccountMgr::LoadRBAC() QueryResult result = LoginDatabase.Query("SELECT id, name FROM rbac_permissions"); if (!result) { - TC_LOG_INFO(LOG_FILTER_SQL, ">> Loaded 0 account permission definitions. DB table `rbac_permissions` is empty."); + TC_LOG_INFO(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 account permission definitions. DB table `rbac_permissions` is empty."); return; } @@ -421,150 +410,75 @@ void AccountMgr::LoadRBAC() { Field* field = result->Fetch(); uint32 id = field[0].GetUInt32(); - _permissions[id] = new RBACPermission(id, field[1].GetString()); + _permissions[id] = new rbac::RBACPermission(id, field[1].GetString()); ++count1; } while (result->NextRow()); - TC_LOG_DEBUG(LOG_FILTER_RBAC, "AccountMgr::LoadRBAC: Loading roles"); - result = LoginDatabase.Query("SELECT id, name FROM rbac_roles"); + TC_LOG_DEBUG(LOG_FILTER_RBAC, "AccountMgr::LoadRBAC: Loading linked permissions"); + result = LoginDatabase.Query("SELECT id, linkedId FROM rbac_linked_permissions ORDER BY id ASC"); if (!result) { - TC_LOG_INFO(LOG_FILTER_SQL, ">> Loaded 0 account role definitions. DB table `rbac_roles` is empty."); + TC_LOG_INFO(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 linked permissions. DB table `rbac_linked_permissions` is empty."); return; } - do - { - Field* field = result->Fetch(); - uint32 id = field[0].GetUInt32(); - _roles[id] = new RBACRole(id, field[1].GetString()); - ++count2; - } - while (result->NextRow()); - - TC_LOG_DEBUG(LOG_FILTER_RBAC, "AccountMgr::LoadRBAC: Loading role permissions"); - result = LoginDatabase.Query("SELECT roleId, permissionId FROM rbac_role_permissions"); - if (!result) - { - TC_LOG_INFO(LOG_FILTER_SQL, ">> Loaded 0 account role-permission definitions. DB table `rbac_role_permissions` is empty."); - return; - } + uint32 permissionId = 0; + rbac::RBACPermission* permission = NULL; do { Field* field = result->Fetch(); - uint32 id = field[0].GetUInt32(); - RBACRole* role = _roles[id]; - role->GrantPermission(field[1].GetUInt32()); - } - while (result->NextRow()); - - TC_LOG_DEBUG(LOG_FILTER_RBAC, "AccountMgr::LoadRBAC: Loading groups"); - result = LoginDatabase.Query("SELECT id, name FROM rbac_groups"); - if (!result) - { - TC_LOG_INFO(LOG_FILTER_SQL, ">> Loaded 0 account group definitions. DB table `rbac_groups` is empty."); - return; - } - - do - { - Field* field = result->Fetch(); - uint32 id = field[0].GetUInt32(); - _groups[id] = new RBACGroup(id, field[1].GetString()); - ++count3; - } - while (result->NextRow()); - - TC_LOG_DEBUG(LOG_FILTER_RBAC, "AccountMgr::LoadRBAC: Loading group roles"); - result = LoginDatabase.Query("SELECT groupId, roleId FROM rbac_group_roles"); - if (!result) - { - TC_LOG_INFO(LOG_FILTER_SQL, ">> Loaded 0 account group-role definitions. DB table `rbac_group_roles` is empty."); - return; - } + uint32 newId = field[0].GetUInt32(); + if (permissionId != newId) + { + permissionId = newId; + permission = _permissions[newId]; + } - do - { - Field* field = result->Fetch(); - uint32 id = field[0].GetUInt32(); - RBACGroup* group = _groups[id]; - group->GrantRole(field[1].GetUInt32()); + uint32 linkedPermissionId = field[1].GetUInt32(); + if (linkedPermissionId == permissionId) + { + TC_LOG_ERROR(LOG_FILTER_SQL, "RBAC Permission %u has itself as linked permission. Ignored", permissionId); + continue; + } + permission->AddLinkedPermission(linkedPermissionId); + ++count2; } while (result->NextRow()); - TC_LOG_DEBUG(LOG_FILTER_RBAC, "AccountMgr::LoadRBAC: Loading security level groups"); - result = LoginDatabase.Query("SELECT secId, groupId FROM rbac_security_level_groups ORDER by secId ASC"); + TC_LOG_DEBUG(LOG_FILTER_RBAC, "AccountMgr::LoadRBAC: Loading default permissions"); + result = LoginDatabase.Query("SELECT secId, permissionId FROM rbac_default_permissions ORDER BY secId ASC"); if (!result) { - TC_LOG_INFO(LOG_FILTER_SQL, ">> Loaded 0 account default groups for security levels definitions. DB table `rbac_security_level_groups` is empty."); + TC_LOG_INFO(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 default permission definitions. DB table `rbac_default_permissions` is empty."); return; } - uint8 lastSecId = 255; - RBACGroupContainer* groups = NULL; + uint8 secId = 255; + rbac::RBACPermissionContainer* permissions = NULL; do { Field* field = result->Fetch(); - uint8 secId = field[0].GetUInt8(); - - if (lastSecId != secId) - groups = &_defaultSecGroups[secId]; - - groups->insert(field[1].GetUInt32()); + uint32 newId = field[0].GetUInt32(); + if (secId != newId) + { + secId = newId; + permissions = &_defaultPermissions[secId]; + } + + permissions->insert(field[1].GetUInt32()); + ++count3; } while (result->NextRow()); - TC_LOG_INFO(LOG_FILTER_SERVER_LOADING, ">> Loaded %u permission definitions, %u role definitions and %u group definitions in %u ms", count1, count2, count3, GetMSTimeDiffToNow(oldMSTime)); - - TC_LOG_DEBUG(LOG_FILTER_RBAC, "AccountMgr::LoadRBAC: Loading default groups"); - // Load default groups to be added to any RBAC Object. - std::string defaultGroups = sConfigMgr->GetStringDefault("RBAC.DefaultGroups", ""); - Tokenizer tokens(defaultGroups, ','); - for (Tokenizer::const_iterator itr = tokens.begin(); itr != tokens.end(); ++itr) - if (uint32 groupId = atoi(*itr)) - _defaultGroups.insert(groupId); + TC_LOG_INFO(LOG_FILTER_SERVER_LOADING, ">> Loaded %u permission definitions, %u linked permissions and %u default permissions in %u ms", count1, count2, count3, GetMSTimeDiffToNow(oldMSTime)); } -void AccountMgr::UpdateAccountAccess(RBACData* rbac, uint32 accountId, uint8 securityLevel, int32 realmId) +void AccountMgr::UpdateAccountAccess(rbac::RBACData* rbac, uint32 accountId, uint8 securityLevel, int32 realmId) { - int32 serverRealmId = realmId != -1 ? realmId : sConfigMgr->GetIntDefault("RealmID", 0); - bool needDelete = false; - if (!rbac) - { - needDelete = true; - rbac = new RBACData(accountId, "", serverRealmId); - rbac->LoadFromDB(); - } - - // Get max security level and realm (checking current realm and -1) - PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_ACCESS_BY_ID); - stmt->setUInt32(0, accountId); - stmt->setInt32(1, serverRealmId); - PreparedQueryResult result = LoginDatabase.Query(stmt); - if (result) - { - do - { - Field* field = result->Fetch(); - uint8 secLevel = field[0].GetUInt8(); - int32 realmId = field[1].GetUInt32(); - - RBACGroupContainer const& groupsToRemove = _defaultSecGroups[secLevel]; - for (RBACGroupContainer::const_iterator it = groupsToRemove.begin(); it != groupsToRemove.end(); ++it) - rbac->RemoveGroup(*it, realmId); - } - while (result->NextRow()); - } - - // Add new groups depending on the new security Level - RBACGroupContainer const& groupsToAdd = _defaultSecGroups[securityLevel]; - for (RBACGroupContainer::const_iterator it = groupsToAdd.begin(); it != groupsToAdd.end(); ++it) - rbac->AddGroup(*it, realmId); - - if (needDelete) - delete rbac; + if (rbac && securityLevel == rbac->GetSecurityLevel()) + rbac->SetSecurityLevel(securityLevel); // Delete old security level from DB if (realmId == -1) @@ -592,30 +506,10 @@ void AccountMgr::UpdateAccountAccess(RBACData* rbac, uint32 accountId, uint8 sec } } -RBACGroup const* AccountMgr::GetRBACGroup(uint32 groupId) const +rbac::RBACPermission const* AccountMgr::GetRBACPermission(uint32 permissionId) const { - TC_LOG_TRACE(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 roleId) const -{ - TC_LOG_TRACE(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 permissionId) const -{ - TC_LOG_TRACE(LOG_FILTER_RBAC, "AccountMgr::GetRBACPermission: roleId: %u", permissionId); - RBACPermissionsContainer::const_iterator it = _permissions.find(permissionId); + TC_LOG_TRACE(LOG_FILTER_RBAC, "AccountMgr::GetRBACPermission: %u", permissionId); + rbac::RBACPermissionsContainer::const_iterator it = _permissions.find(permissionId); if (it != _permissions.end()) return it->second; @@ -630,7 +524,7 @@ bool AccountMgr::HasPermission(uint32 accountId, uint32 permissionId, uint32 rea return false; } - RBACData rbac(accountId, "", realmId); + rbac::RBACData rbac(accountId, "", realmId); rbac.LoadFromDB(); bool hasPermission = rbac.HasPermission(permissionId); @@ -641,18 +535,15 @@ bool AccountMgr::HasPermission(uint32 accountId, uint32 permissionId, uint32 rea 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) + for (rbac::RBACPermissionsContainer::iterator itr = _permissions.begin(); itr != _permissions.end(); ++itr) delete itr->second; _permissions.clear(); - _roles.clear(); - _groups.clear(); - _defaultGroups.clear(); - _defaultSecGroups.clear(); + _defaultPermissions.clear(); +} + +rbac::RBACPermissionContainer const& AccountMgr::GetRBACDefaultPermissions(uint8 secLevel) +{ + TC_LOG_TRACE(LOG_FILTER_RBAC, "AccountMgr::GetRBACDefaultPermissions: secLevel %u - size: %u", secLevel, uint32(_defaultPermissions[secLevel].size())); + return _defaultPermissions[secLevel]; } diff --git a/src/server/game/Accounts/AccountMgr.h b/src/server/game/Accounts/AccountMgr.h index 92c1e2292d0..24bea5c15a9 100644 --- a/src/server/game/Accounts/AccountMgr.h +++ b/src/server/game/Accounts/AccountMgr.h @@ -43,10 +43,11 @@ enum PasswordChangeSecurity #define MAX_ACCOUNT_STR 16 #define MAX_EMAIL_STR 64 -typedef std::map<uint32, RBACPermission*> RBACPermissionsContainer; -typedef std::map<uint32, RBACRole*> RBACRolesContainer; -typedef std::map<uint32, RBACGroup*> RBACGroupsContainer; -typedef std::map<uint32, RBACGroupContainer> RBACDefaultSecurityGroupContainer; +namespace rbac +{ +typedef std::map<uint32, rbac::RBACPermission*> RBACPermissionsContainer; +typedef std::map<uint8, rbac::RBACPermissionContainer> RBACDefaultPermissionsContainer; +} class AccountMgr { @@ -80,25 +81,18 @@ class AccountMgr static bool IsConsoleAccount(uint32 gmlevel); static bool HasPermission(uint32 accountId, uint32 permission, uint32 realmId); - void UpdateAccountAccess(RBACData* rbac, uint32 accountId, uint8 securityLevel, int32 realmId); + void UpdateAccountAccess(rbac::RBACData* rbac, uint32 accountId, uint8 securityLevel, int32 realmId); void LoadRBAC(); - RBACGroup const* GetRBACGroup(uint32 group) const; - RBACRole const* GetRBACRole(uint32 role) const; - RBACPermission const* GetRBACPermission(uint32 permission) const; + rbac::RBACPermission const* GetRBACPermission(uint32 permission) const; - RBACGroupsContainer const& GetRBACGroupList() const { return _groups; } - RBACRolesContainer const& GetRBACRoleList() const { return _roles; } - RBACPermissionsContainer const& GetRBACPermissionList() const { return _permissions; } - RBACGroupContainer const& GetRBACDefaultGroups() const { return _defaultGroups; } + rbac::RBACPermissionsContainer const& GetRBACPermissionList() const { return _permissions; } + rbac::RBACPermissionContainer const& GetRBACDefaultPermissions(uint8 secLevel); private: void ClearRBAC(); - RBACPermissionsContainer _permissions; - RBACRolesContainer _roles; - RBACGroupsContainer _groups; - RBACDefaultSecurityGroupContainer _defaultSecGroups; - RBACGroupContainer _defaultGroups; + rbac::RBACPermissionsContainer _permissions; + rbac::RBACDefaultPermissionsContainer _defaultPermissions; }; #define sAccountMgr ACE_Singleton<AccountMgr, ACE_Null_Mutex>::instance() diff --git a/src/server/game/Accounts/RBAC.cpp b/src/server/game/Accounts/RBAC.cpp index 763b1584431..8cd70721976 100644 --- a/src/server/game/Accounts/RBAC.cpp +++ b/src/server/game/Accounts/RBAC.cpp @@ -20,238 +20,23 @@ #include "DatabaseEnv.h"
#include "Log.h"
-void RBACRole::GrantPermission(uint32 permissionId)
+namespace rbac
{
- if (permissionId < RBAC_PERM_MAX)
- {
- TC_LOG_TRACE(LOG_FILTER_RBAC, "RBACRole::GrantPermission (Role %u, Permission %u). Ok", GetId(), permissionId);
- _perms.set(permissionId);
- }
- else
- TC_LOG_ERROR(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)
- {
- TC_LOG_TRACE(LOG_FILTER_RBAC, "RBACRole::RevokePermission (Role %u, Permission %u). Ok", GetId(), permissionId);
- _perms.reset(permissionId);
- }
- else
- TC_LOG_ERROR(LOG_FILTER_RBAC, "RBACRole::RevokePermission (Role %u, Permission %u). Permission not lower than %u",
- GetId(), permissionId, RBAC_PERM_MAX);
-}
-
-void RBACGroup::GrantRole(uint32 roleId)
-{
- TC_LOG_TRACE(LOG_FILTER_RBAC, "RBACRole::GrantPermission (Role %u, Permission %u). Ok", GetId(), roleId);
- _roles.insert(roleId);
-}
-
-void RBACGroup::RevokeRole(uint32 roleId)
-{
- TC_LOG_TRACE(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)
- {
- TC_LOG_TRACE(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<std::set<uint32>::iterator, bool> ret = _groups.insert(groupId);
- if (!ret.second)
- {
- TC_LOG_TRACE(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)
- {
- TC_LOG_TRACE(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);
- stmt->setInt32(2, realmId);
- LoginDatabase.Execute(stmt);
-
- CalculateNewPermissions();
- }
- else
- TC_LOG_TRACE(LOG_FILTER_RBAC, "RBACData::AddGroup [Id: %u Name: %s] (Group %u, RealmId %d). Added",
- GetId(), GetName().c_str(), groupId, realmId);
-
- return RBAC_OK;
-}
-
-RBACCommandResult RBACData::RemoveGroup(uint32 groupId, int32 realmId /* = 0 */)
-{
- // could remove it?
- if (!_groups.erase(groupId))
- {
- TC_LOG_TRACE(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)
- {
- TC_LOG_TRACE(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);
- stmt->setInt32(2, realmId);
- LoginDatabase.Execute(stmt);
-
- CalculateNewPermissions();
- }
- else
- TC_LOG_TRACE(LOG_FILTER_RBAC, "RBACData::RemoveGroup [Id: %u Name: %s] (Group %u, RealmId %d). Removed",
- GetId(), GetName().c_str(), groupId, realmId);
-
- return RBAC_OK;
-}
-
-RBACCommandResult RBACData::GrantRole(uint32 roleId, int32 realmId /* = 0*/)
-{
- // Check if role Id exists
- RBACRole const* role = sAccountMgr->GetRBACRole(roleId);
- if (!role)
- {
- TC_LOG_TRACE(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())
- {
- TC_LOG_TRACE(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<std::set<uint32>::iterator, bool> ret = _grantedRoles.insert(roleId);
- if (!ret.second)
- {
- TC_LOG_TRACE(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)
- {
- TC_LOG_TRACE(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
- TC_LOG_TRACE(LOG_FILTER_RBAC, "RBACData::GrantRole [Id: %u Name: %s] (Role %u, RealmId %d). Ok",
- GetId(), GetName().c_str(), roleId, realmId);
-
- return RBAC_OK;
-}
-
-RBACCommandResult RBACData::DenyRole(uint32 roleId, int32 realmId /* = 0*/)
-{
- // Check if role Id exists
- RBACRole const* role = sAccountMgr->GetRBACRole(roleId);
- if (!role)
- {
- TC_LOG_TRACE(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())
- {
- TC_LOG_TRACE(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<std::set<uint32>::iterator, bool> ret = _deniedRoles.insert(roleId);
- if (!ret.second)
- {
- TC_LOG_TRACE(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)
- {
- TC_LOG_TRACE(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
- TC_LOG_TRACE(LOG_FILTER_RBAC, "RBACData::DenyRole [Id: %u Name: %s] (Role %u, RealmId %d). Ok",
- GetId(), GetName().c_str(), roleId, realmId);
-
- return RBAC_OK;
-}
-
-void RBACData::SaveRole(uint32 roleId, bool granted, int32 realmId)
-{
- PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_RBAC_ACCOUNT_ROLE);
- stmt->setUInt32(0, GetId());
- stmt->setUInt32(1, roleId);
- stmt->setBool(2, granted);
- stmt->setInt32(3, realmId);
- LoginDatabase.Execute(stmt);
-}
-RBACCommandResult RBACData::RevokeRole(uint32 roleId, int32 realmId /* = 0*/)
+std::string GetDebugPermissionString(RBACPermissionContainer const& perms)
{
- uint8 revoked = _grantedRoles.erase(roleId) + _deniedRoles.erase(roleId);
-
- // could remove it?
- if (!revoked)
- {
- TC_LOG_TRACE(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)
+ std::string str = "";
+ if (!perms.empty())
{
- TC_LOG_TRACE(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);
- stmt->setInt32(2, realmId);
- LoginDatabase.Execute(stmt);
-
- CalculateNewPermissions();
+ std::ostringstream o;
+ RBACPermissionContainer::const_iterator itr = perms.begin();
+ o << (*itr);
+ for (++itr; itr != perms.end(); ++itr)
+ o << ", " << uint32(*itr);
+ str = o.str();
}
- else
- TC_LOG_TRACE(LOG_FILTER_RBAC, "RBACData::RevokeRole [Id: %u Name: %s] (Role %u, RealmId %d). Ok",
- GetId(), GetName().c_str(), roleId, realmId);
- return RBAC_OK;
+ return str;
}
RBACCommandResult RBACData::GrantPermission(uint32 permissionId, int32 realmId /* = 0*/)
@@ -266,7 +51,7 @@ RBACCommandResult RBACData::GrantPermission(uint32 permissionId, int32 realmId / }
// Check if already added in denied list
- if (_deniedPerms.test(permissionId))
+ if (HasDeniedPermission(permissionId))
{
TC_LOG_TRACE(LOG_FILTER_RBAC, "RBACData::GrantPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Permission in deny list",
GetId(), GetName().c_str(), permissionId, realmId);
@@ -274,14 +59,14 @@ RBACCommandResult RBACData::GrantPermission(uint32 permissionId, int32 realmId / }
// Already added?
- if (_grantedPerms.test(permissionId))
+ if (HasGrantedPermission(permissionId))
{
TC_LOG_TRACE(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);
+ AddGrantedPermission(permissionId);
// Do not save to db when loading data from DB (realmId = 0)
if (realmId)
@@ -310,7 +95,7 @@ RBACCommandResult RBACData::DenyPermission(uint32 permissionId, int32 realmId /* }
// Check if already added in granted list
- if (_grantedPerms.test(permissionId))
+ if (HasGrantedPermission(permissionId))
{
TC_LOG_TRACE(LOG_FILTER_RBAC, "RBACData::DenyPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Permission in grant list",
GetId(), GetName().c_str(), permissionId, realmId);
@@ -318,14 +103,14 @@ RBACCommandResult RBACData::DenyPermission(uint32 permissionId, int32 realmId /* }
// Already added?
- if (_deniedPerms.test(permissionId))
+ if (HasDeniedPermission(permissionId))
{
TC_LOG_TRACE(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);
+ AddDeniedPermission(permissionId);
// Do not save to db when loading data from DB (realmId = 0)
if (realmId)
@@ -355,15 +140,15 @@ void RBACData::SavePermission(uint32 permission, bool granted, int32 realmId) RBACCommandResult RBACData::RevokePermission(uint32 permissionId, int32 realmId /* = 0*/)
{
// Check if it's present in any list
- if (!_grantedPerms.test(permissionId) && !_deniedPerms.test(permissionId))
+ if (!HasGrantedPermission(permissionId) && !HasDeniedPermission(permissionId))
{
TC_LOG_TRACE(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(permissionId);
- _deniedPerms.reset(permissionId);
+ RemoveGrantedPermission(permissionId);
+ RemoveDeniedPermission(permissionId);
// Do not save to db when loading data from DB (realmId = 0)
if (realmId)
@@ -387,52 +172,15 @@ RBACCommandResult RBACData::RevokePermission(uint32 permissionId, int32 realmId void RBACData::LoadFromDB()
{
- TC_LOG_INFO(LOG_FILTER_RBAC, "RBACData::LoadFromDB [Id: %u Name: %s]", GetId(), GetName().c_str());
- TC_LOG_DEBUG(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());
- stmt->setInt32(1, GetRealmId());
- PreparedQueryResult result = LoginDatabase.Query(stmt);
-
- if (result)
- {
- do
- {
- Field* fields = result->Fetch();
- AddGroup(fields[0].GetUInt32());
- }
- while (result->NextRow());
- }
-
- TC_LOG_DEBUG(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());
- stmt->setInt32(1, GetRealmId());
- result = LoginDatabase.Query(stmt);
-
- if (result)
- {
- do
- {
- Field* fields = result->Fetch();
- if (fields[1].GetBool())
- GrantRole(fields[0].GetUInt32());
- else
- DenyRole(fields[0].GetUInt32());
- }
- while (result->NextRow());
- }
+ ClearData();
TC_LOG_DEBUG(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);
+ PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_RBAC_ACCOUNT_PERMISSIONS);
stmt->setUInt32(0, GetId());
stmt->setInt32(1, GetRealmId());
- result = LoginDatabase.Query(stmt);
+ PreparedQueryResult result = LoginDatabase.Query(stmt);
if (result)
{
do
@@ -446,49 +194,72 @@ void RBACData::LoadFromDB() while (result->NextRow());
}
- TC_LOG_DEBUG(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);
+ // Add default permissions
+ RBACPermissionContainer const& permissions = sAccountMgr->GetRBACDefaultPermissions(_secLevel);
+ for (RBACPermissionContainer::const_iterator itr = permissions.begin(); itr != permissions.end(); ++itr)
+ GrantPermission(*itr);
- TC_LOG_DEBUG(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
+ // Force calculation of permissions
CalculateNewPermissions();
}
void RBACData::CalculateNewPermissions()
{
- TC_LOG_TRACE(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();
+ TC_LOG_TRACE(LOG_FILTER_RBAC, "RBACData::CalculateNewPermissions [Id: %u Name: %s]", GetId(), GetName().c_str());
+
+ // Get the list of granted permissions
+ _globalPerms = GetGrantedPermissions();
+ ExpandPermissions(_globalPerms);
+ RBACPermissionContainer revoked = GetDeniedPermissions();
+ ExpandPermissions(revoked);
+ RemovePermissions(_globalPerms, revoked);
+}
+
+void RBACData::AddPermissions(RBACPermissionContainer const& permsFrom, RBACPermissionContainer& permsTo)
+{
+ for (RBACPermissionContainer::const_iterator itr = permsFrom.begin(); itr != permsFrom.end(); ++itr)
+ permsTo.insert(*itr);
+}
+
+void RBACData::RemovePermissions(RBACPermissionContainer const& permsFrom, RBACPermissionContainer& permsTo)
+{
+ for (RBACPermissionContainer::const_iterator itr = permsFrom.begin(); itr != permsFrom.end(); ++itr)
+ permsTo.erase(*itr);
+}
- // Add those roles inherited from groups
- for (RBACGroupContainer::const_iterator itGroup = _groups.begin(); itGroup != _groups.end(); ++itGroup)
+void RBACData::ExpandPermissions(RBACPermissionContainer& permissions)
+{
+ RBACPermissionContainer toCheck = permissions;
+ permissions.clear();
+
+ while (!toCheck.empty())
{
- RBACGroup const* group = sAccountMgr->GetRBACGroup(*itGroup);
- if (!group) // Should never happen due to foreign keys in DB
+ // remove the permission from original list
+ uint32 permissionId = *toCheck.begin();
+ toCheck.erase(toCheck.begin());
+
+ RBACPermission const* permission = sAccountMgr->GetRBACPermission(permissionId);
+ if (!permission)
continue;
- RBACRoleContainer const& roles = group->GetRoles();
- for (RBACRoleContainer::const_iterator it = roles.begin(); it != roles.end(); ++it)
- tempGrantedRoles.insert(*it);
- }
+ // insert into the final list (expanded list)
+ permissions.insert(permissionId);
- // Get the list of granted permissions
- _globalPerms = GetGrantedPermissions();
+ // add all linked permissions (that are not already expanded) to the list of permissions to be checked
+ RBACPermissionContainer const& linkedPerms = permission->GetLinkedPermissions();
+ for (RBACPermissionContainer::const_iterator itr = linkedPerms.begin(); itr != linkedPerms.end(); ++itr)
+ if (permissions.find(*itr) == permissions.end())
+ toCheck.insert(*itr);
+ }
- // Add those permissions inherited from roles granted
- for (RBACRoleContainer::const_iterator it = tempGrantedRoles.begin(); it != tempGrantedRoles.end(); ++it)
- if (RBACRole const* role = sAccountMgr->GetRBACRole(*it))
- _globalPerms |= role->GetPermissions();
+ TC_LOG_DEBUG(LOG_FILTER_RBAC, "RBACData::ExpandPermissions: Expanded: %s", GetDebugPermissionString(permissions).c_str());
+}
- // Remove denied permissions from the list
- _globalPerms &= ~GetDeniedPermissions();
+void RBACData::ClearData()
+{
+ _grantedPerms.clear();
+ _deniedPerms.clear();
+ _globalPerms.clear();
+}
- // Remove those permissions inherited from denied roles
- for (RBACRoleContainer::const_iterator it = _deniedRoles.begin(); it != _deniedRoles.end(); ++it)
- if (RBACRole const* role = sAccountMgr->GetRBACRole(*it))
- _globalPerms &= ~role->GetPermissions();
}
diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h index e751cba0fbf..1937fc9ca49 100644 --- a/src/server/game/Accounts/RBAC.h +++ b/src/server/game/Accounts/RBAC.h @@ -42,10 +42,12 @@ #include "Define.h" #include <string> -#include <bitset> #include <set> #include <map> +namespace rbac +{ + enum RBACPermissions { RBAC_PERM_INSTANT_LOGOUT = 1, @@ -98,25 +100,26 @@ enum RBACPermissions RBAC_PERM_COMMANDS_PINFO_CHECK_PERSONAL_DATA = 48, RBAC_PERM_EMAIL_CONFIRM_FOR_PASS_CHANGE = 49, RBAC_PERM_MAY_CHECK_OWN_EMAIL = 50, - // Leave some space for core permissions + // Free space for core permissions (till 149) + // Roles (Permissions with delegated permissions) use 199 and descending RBAC_PERM_COMMAND_RBAC = 200, RBAC_PERM_COMMAND_RBAC_ACC = 201, - RBAC_PERM_COMMAND_RBAC_ACC_GROUP = 202, - RBAC_PERM_COMMAND_RBAC_ACC_GROUP_ADD = 203, - RBAC_PERM_COMMAND_RBAC_ACC_GROUP_DEL = 204, - RBAC_PERM_COMMAND_RBAC_ACC_ROLE = 205, - RBAC_PERM_COMMAND_RBAC_ACC_ROLE_GRANT = 206, - RBAC_PERM_COMMAND_RBAC_ACC_ROLE_DENY = 207, - RBAC_PERM_COMMAND_RBAC_ACC_ROLE_REVOKE = 208, - RBAC_PERM_COMMAND_RBAC_ACC_PERM = 209, - RBAC_PERM_COMMAND_RBAC_ACC_PERM_GRANT = 210, - RBAC_PERM_COMMAND_RBAC_ACC_PERM_DENY = 211, - RBAC_PERM_COMMAND_RBAC_ACC_PERM_REVOKE = 212, - RBAC_PERM_COMMAND_RBAC_LIST = 213, - RBAC_PERM_COMMAND_RBAC_LIST_GROUPS = 214, - RBAC_PERM_COMMAND_RBAC_LIST_ROLES = 215, - RBAC_PERM_COMMAND_RBAC_LIST_PERMS = 216, + RBAC_PERM_COMMAND_RBAC_ACC_PERM_LIST = 202, + RBAC_PERM_COMMAND_RBAC_ACC_PERM_GRANT = 203, + RBAC_PERM_COMMAND_RBAC_ACC_PERM_DENY = 204, + RBAC_PERM_COMMAND_RBAC_ACC_PERM_REVOKE = 205, + RBAC_PERM_COMMAND_RBAC_LIST = 206, + // 207 - reuse + // 208 - reuse + // 209 - reuse + // 210 - reuse + // 211 - reuse + // 212 - reuse + // 213 - reuse + // 214 - reuse + // 215 - reuse + // 216 - reuse RBAC_PERM_COMMAND_ACCOUNT = 217, RBAC_PERM_COMMAND_ACCOUNT_ADDON = 218, RBAC_PERM_COMMAND_ACCOUNT_CREATE = 219, @@ -507,109 +510,109 @@ enum RBACPermissions RBAC_PERM_COMMAND_QUEST_COMPLETE = 604, RBAC_PERM_COMMAND_QUEST_REMOVE = 605, RBAC_PERM_COMMAND_QUEST_REWARD = 606, - RBAC_PERM_COMMANDS_RELOAD = 607, - RBAC_PERM_COMMANDS_RELOAD_ACCESS_REQUIREMENT = 608, - RBAC_PERM_COMMANDS_RELOAD_ACHIEVEMENT_CRITERIA_DATA = 609, - RBAC_PERM_COMMANDS_RELOAD_ACHIEVEMENT_REWARD = 610, - RBAC_PERM_COMMANDS_RELOAD_ALL = 611, - RBAC_PERM_COMMANDS_RELOAD_ALL_ACHIEVEMENT = 612, - RBAC_PERM_COMMANDS_RELOAD_ALL_AREA = 613, - RBAC_PERM_COMMANDS_RELOAD_ALL_EVENTAI = 614, - RBAC_PERM_COMMANDS_RELOAD_ALL_GOSSIP = 615, - RBAC_PERM_COMMANDS_RELOAD_ALL_ITEM = 616, - RBAC_PERM_COMMANDS_RELOAD_ALL_LOCALES = 617, - RBAC_PERM_COMMANDS_RELOAD_ALL_LOOT = 618, - RBAC_PERM_COMMANDS_RELOAD_ALL_NPC = 619, - RBAC_PERM_COMMANDS_RELOAD_ALL_QUEST = 620, - RBAC_PERM_COMMANDS_RELOAD_ALL_SCRIPTS = 621, - RBAC_PERM_COMMANDS_RELOAD_ALL_SPELL = 622, - RBAC_PERM_COMMANDS_RELOAD_AREATRIGGER_INVOLVEDRELATION = 623, - RBAC_PERM_COMMANDS_RELOAD_AREATRIGGER_TAVERN = 624, - RBAC_PERM_COMMANDS_RELOAD_AREATRIGGER_TELEPORT = 625, - RBAC_PERM_COMMANDS_RELOAD_AUCTIONS = 626, - RBAC_PERM_COMMANDS_RELOAD_AUTOBROADCAST = 627, - RBAC_PERM_COMMANDS_RELOAD_COMMAND = 628, - RBAC_PERM_COMMANDS_RELOAD_CONDITIONS = 629, - RBAC_PERM_COMMANDS_RELOAD_CONFIG = 630, - RBAC_PERM_COMMANDS_RELOAD_CREATURE_AI_SCRIPTS = 631, - RBAC_PERM_COMMANDS_RELOAD_CREATURE_AI_TEXTS = 632, - RBAC_PERM_COMMANDS_RELOAD_CREATURE_LINKED_RESPAWN = 633, - RBAC_PERM_COMMANDS_RELOAD_CREATURE_LOOT_TEMPLATE = 634, - RBAC_PERM_COMMANDS_RELOAD_CREATURE_ONKILL_REPUTATION = 635, - RBAC_PERM_COMMANDS_RELOAD_CREATURE_QUESTENDER = 636, - RBAC_PERM_COMMANDS_RELOAD_CREATURE_QUESTSTARTER = 637, - RBAC_PERM_COMMANDS_RELOAD_CREATURE_SUMMON_GROUPS = 638, - RBAC_PERM_COMMANDS_RELOAD_CREATURE_TEMPLATE = 639, - RBAC_PERM_COMMANDS_RELOAD_CREATURE_TEXT = 640, - RBAC_PERM_COMMANDS_RELOAD_DISABLES = 641, - RBAC_PERM_COMMANDS_RELOAD_DISENCHANT_LOOT_TEMPLATE = 642, - RBAC_PERM_COMMANDS_RELOAD_EVENT_SCRIPTS = 643, - RBAC_PERM_COMMANDS_RELOAD_FISHING_LOOT_TEMPLATE = 644, - RBAC_PERM_COMMANDS_RELOAD_GAME_GRAVEYARD_ZONE = 645, - RBAC_PERM_COMMANDS_RELOAD_GAMEOBJECT_QUESTENDER = 646, - RBAC_PERM_COMMANDS_RELOAD_GAMEOBJECT_QUEST_LOOT_TEMPLATE = 647, - RBAC_PERM_COMMANDS_RELOAD_GAMEOBJECT_QUESTSTARTER = 648, - RBAC_PERM_COMMANDS_RELOAD_GAME_TELE = 649, - RBAC_PERM_COMMANDS_RELOAD_GM_TICKETS = 650, - RBAC_PERM_COMMANDS_RELOAD_GOSSIP_MENU = 651, - RBAC_PERM_COMMANDS_RELOAD_GOSSIP_MENU_OPTION = 652, - RBAC_PERM_COMMANDS_RELOAD_ITEM_ENCHANTMENT_TEMPLATE = 653, - RBAC_PERM_COMMANDS_RELOAD_ITEM_LOOT_TEMPLATE = 654, - RBAC_PERM_COMMANDS_RELOAD_ITEM_SET_NAMES = 655, - RBAC_PERM_COMMANDS_RELOAD_LFG_DUNGEON_REWARDS = 656, - RBAC_PERM_COMMANDS_RELOAD_LOCALES_ACHIEVEMENT_REWARD = 657, - RBAC_PERM_COMMANDS_RELOAD_LOCALES_CRETURE = 658, - RBAC_PERM_COMMANDS_RELOAD_LOCALES_CRETURE_TEXT = 659, - RBAC_PERM_COMMANDS_RELOAD_LOCALES_GAMEOBJECT = 660, - RBAC_PERM_COMMANDS_RELOAD_LOCALES_GOSSIP_MENU_OPTION = 661, - RBAC_PERM_COMMANDS_RELOAD_LOCALES_ITEM = 662, - RBAC_PERM_COMMANDS_RELOAD_LOCALES_ITEM_SET_NAME = 663, - RBAC_PERM_COMMANDS_RELOAD_LOCALES_NPC_TEXT = 664, - RBAC_PERM_COMMANDS_RELOAD_LOCALES_PAGE_TEXT = 665, - RBAC_PERM_COMMANDS_RELOAD_LOCALES_POINTS_OF_INTEREST = 666, - RBAC_PERM_COMMANDS_RELOAD_LOCALES_QUEST = 667, - RBAC_PERM_COMMANDS_RELOAD_MAIL_LEVEL_REWARD = 668, - RBAC_PERM_COMMANDS_RELOAD_MAIL_LOOT_TEMPLATE = 669, - RBAC_PERM_COMMANDS_RELOAD_MILLING_LOOT_TEMPLATE = 670, - RBAC_PERM_COMMANDS_RELOAD_NPC_SPELLCLICK_SPELLS = 671, - RBAC_PERM_COMMANDS_RELOAD_NPC_TRAINER = 672, - RBAC_PERM_COMMANDS_RELOAD_NPC_VENDOR = 673, - RBAC_PERM_COMMANDS_RELOAD_PAGE_TEXT = 674, - RBAC_PERM_COMMANDS_RELOAD_PICKPOCKETING_LOOT_TEMPLATE = 675, - RBAC_PERM_COMMANDS_RELOAD_POINTS_OF_INTEREST = 676, - RBAC_PERM_COMMANDS_RELOAD_PROSPECTING_LOOT_TEMPLATE = 677, - RBAC_PERM_COMMANDS_RELOAD_QUEST_POI = 678, - RBAC_PERM_COMMANDS_RELOAD_QUEST_TEMPLATE = 679, - RBAC_PERM_COMMANDS_RELOAD_RBAC = 680, - RBAC_PERM_COMMANDS_RELOAD_REFERENCE_LOOT_TEMPLATE = 681, - RBAC_PERM_COMMANDS_RELOAD_REPUTATION_REWARD_RATE = 682, - RBAC_PERM_COMMANDS_RELOAD_RESERVED_NAME = 683, - RBAC_PERM_COMMANDS_RELOAD_SKILL_DISCOVERY_TEMPLATE = 684, - RBAC_PERM_COMMANDS_RELOAD_SKILL_EXTRA_ITEM_TEMPLATE = 685, - RBAC_PERM_COMMANDS_RELOAD_SKILL_FISHING_BASE_LEVEL = 686, - RBAC_PERM_COMMANDS_RELOAD_SKINNING_LOOT_TEMPLATE = 687, - RBAC_PERM_COMMANDS_RELOAD_SMART_SCRIPTS = 688, - RBAC_PERM_COMMANDS_RELOAD_SPELL_AREA = 689, - RBAC_PERM_COMMANDS_RELOAD_SPELL_BONUS_DATA = 690, - RBAC_PERM_COMMANDS_RELOAD_SPELL_GROUP = 691, - RBAC_PERM_COMMANDS_RELOAD_SPELL_GROUP_STACK_RULES = 692, - RBAC_PERM_COMMANDS_RELOAD_SPELL_LEARN_SPELL = 693, - RBAC_PERM_COMMANDS_RELOAD_SPELL_LINKED_SPELL = 694, - RBAC_PERM_COMMANDS_RELOAD_SPELL_LOOT_TEMPLATE = 695, - RBAC_PERM_COMMANDS_RELOAD_SPELL_PET_AURAS = 696, - RBAC_PERM_COMMANDS_RELOAD_SPELL_PROC = 697, - RBAC_PERM_COMMANDS_RELOAD_SPELL_PROC_EVENT = 698, - RBAC_PERM_COMMANDS_RELOAD_SPELL_REQUIRED = 699, - RBAC_PERM_COMMANDS_RELOAD_SPELL_SCRIPTS = 700, - RBAC_PERM_COMMANDS_RELOAD_SPELL_TARGET_POSITION = 701, - RBAC_PERM_COMMANDS_RELOAD_SPELL_THREATS = 702, - RBAC_PERM_COMMANDS_RELOAD_SPILLOVER_TEMPLATE = 703, - RBAC_PERM_COMMANDS_RELOAD_TRINITY_STRING = 704, - RBAC_PERM_COMMANDS_RELOAD_VEHICLE_ACCESORY = 705, - RBAC_PERM_COMMANDS_RELOAD_VEHICLE_TEMPLATE_ACCESSORY = 706, - RBAC_PERM_COMMANDS_RELOAD_WARDEN_ACTION = 707, - RBAC_PERM_COMMANDS_RELOAD_WAYPOINT_DATA = 708, - RBAC_PERM_COMMANDS_RELOAD_WAYPOINT_SCRIPTS = 709, + RBAC_PERM_COMMAND_RELOAD = 607, + RBAC_PERM_COMMAND_RELOAD_ACCESS_REQUIREMENT = 608, + RBAC_PERM_COMMAND_RELOAD_ACHIEVEMENT_CRITERIA_DATA = 609, + RBAC_PERM_COMMAND_RELOAD_ACHIEVEMENT_REWARD = 610, + RBAC_PERM_COMMAND_RELOAD_ALL = 611, + RBAC_PERM_COMMAND_RELOAD_ALL_ACHIEVEMENT = 612, + RBAC_PERM_COMMAND_RELOAD_ALL_AREA = 613, + RBAC_PERM_COMMAND_RELOAD_ALL_EVENTAI = 614, + RBAC_PERM_COMMAND_RELOAD_ALL_GOSSIP = 615, + RBAC_PERM_COMMAND_RELOAD_ALL_ITEM = 616, + RBAC_PERM_COMMAND_RELOAD_ALL_LOCALES = 617, + RBAC_PERM_COMMAND_RELOAD_ALL_LOOT = 618, + RBAC_PERM_COMMAND_RELOAD_ALL_NPC = 619, + RBAC_PERM_COMMAND_RELOAD_ALL_QUEST = 620, + RBAC_PERM_COMMAND_RELOAD_ALL_SCRIPTS = 621, + RBAC_PERM_COMMAND_RELOAD_ALL_SPELL = 622, + RBAC_PERM_COMMAND_RELOAD_AREATRIGGER_INVOLVEDRELATION = 623, + RBAC_PERM_COMMAND_RELOAD_AREATRIGGER_TAVERN = 624, + RBAC_PERM_COMMAND_RELOAD_AREATRIGGER_TELEPORT = 625, + RBAC_PERM_COMMAND_RELOAD_AUCTIONS = 626, + RBAC_PERM_COMMAND_RELOAD_AUTOBROADCAST = 627, + RBAC_PERM_COMMAND_RELOAD_COMMAND = 628, + RBAC_PERM_COMMAND_RELOAD_CONDITIONS = 629, + RBAC_PERM_COMMAND_RELOAD_CONFIG = 630, + RBAC_PERM_COMMAND_RELOAD_CREATURE_AI_SCRIPTS = 631, + RBAC_PERM_COMMAND_RELOAD_CREATURE_AI_TEXTS = 632, + RBAC_PERM_COMMAND_RELOAD_CREATURE_LINKED_RESPAWN = 633, + RBAC_PERM_COMMAND_RELOAD_CREATURE_LOOT_TEMPLATE = 634, + RBAC_PERM_COMMAND_RELOAD_CREATURE_ONKILL_REPUTATION = 635, + RBAC_PERM_COMMAND_RELOAD_CREATURE_QUESTENDER = 636, + RBAC_PERM_COMMAND_RELOAD_CREATURE_QUESTSTARTER = 637, + RBAC_PERM_COMMAND_RELOAD_CREATURE_SUMMON_GROUPS = 638, + RBAC_PERM_COMMAND_RELOAD_CREATURE_TEMPLATE = 639, + RBAC_PERM_COMMAND_RELOAD_CREATURE_TEXT = 640, + RBAC_PERM_COMMAND_RELOAD_DISABLES = 641, + RBAC_PERM_COMMAND_RELOAD_DISENCHANT_LOOT_TEMPLATE = 642, + RBAC_PERM_COMMAND_RELOAD_EVENT_SCRIPTS = 643, + RBAC_PERM_COMMAND_RELOAD_FISHING_LOOT_TEMPLATE = 644, + RBAC_PERM_COMMAND_RELOAD_GAME_GRAVEYARD_ZONE = 645, + RBAC_PERM_COMMAND_RELOAD_GAMEOBJECT_QUESTENDER = 646, + RBAC_PERM_COMMAND_RELOAD_GAMEOBJECT_QUEST_LOOT_TEMPLATE = 647, + RBAC_PERM_COMMAND_RELOAD_GAMEOBJECT_QUESTSTARTER = 648, + RBAC_PERM_COMMAND_RELOAD_GAME_TELE = 649, + RBAC_PERM_COMMAND_RELOAD_GM_TICKETS = 650, + RBAC_PERM_COMMAND_RELOAD_GOSSIP_MENU = 651, + RBAC_PERM_COMMAND_RELOAD_GOSSIP_MENU_OPTION = 652, + RBAC_PERM_COMMAND_RELOAD_ITEM_ENCHANTMENT_TEMPLATE = 653, + RBAC_PERM_COMMAND_RELOAD_ITEM_LOOT_TEMPLATE = 654, + RBAC_PERM_COMMAND_RELOAD_ITEM_SET_NAMES = 655, + RBAC_PERM_COMMAND_RELOAD_LFG_DUNGEON_REWARDS = 656, + RBAC_PERM_COMMAND_RELOAD_LOCALES_ACHIEVEMENT_REWARD = 657, + RBAC_PERM_COMMAND_RELOAD_LOCALES_CRETURE = 658, + RBAC_PERM_COMMAND_RELOAD_LOCALES_CRETURE_TEXT = 659, + RBAC_PERM_COMMAND_RELOAD_LOCALES_GAMEOBJECT = 660, + RBAC_PERM_COMMAND_RELOAD_LOCALES_GOSSIP_MENU_OPTION = 661, + RBAC_PERM_COMMAND_RELOAD_LOCALES_ITEM = 662, + RBAC_PERM_COMMAND_RELOAD_LOCALES_ITEM_SET_NAME = 663, + RBAC_PERM_COMMAND_RELOAD_LOCALES_NPC_TEXT = 664, + RBAC_PERM_COMMAND_RELOAD_LOCALES_PAGE_TEXT = 665, + RBAC_PERM_COMMAND_RELOAD_LOCALES_POINTS_OF_INTEREST = 666, + RBAC_PERM_COMMAND_RELOAD_LOCALES_QUEST = 667, + RBAC_PERM_COMMAND_RELOAD_MAIL_LEVEL_REWARD = 668, + RBAC_PERM_COMMAND_RELOAD_MAIL_LOOT_TEMPLATE = 669, + RBAC_PERM_COMMAND_RELOAD_MILLING_LOOT_TEMPLATE = 670, + RBAC_PERM_COMMAND_RELOAD_NPC_SPELLCLICK_SPELLS = 671, + RBAC_PERM_COMMAND_RELOAD_NPC_TRAINER = 672, + RBAC_PERM_COMMAND_RELOAD_NPC_VENDOR = 673, + RBAC_PERM_COMMAND_RELOAD_PAGE_TEXT = 674, + RBAC_PERM_COMMAND_RELOAD_PICKPOCKETING_LOOT_TEMPLATE = 675, + RBAC_PERM_COMMAND_RELOAD_POINTS_OF_INTEREST = 676, + RBAC_PERM_COMMAND_RELOAD_PROSPECTING_LOOT_TEMPLATE = 677, + RBAC_PERM_COMMAND_RELOAD_QUEST_POI = 678, + RBAC_PERM_COMMAND_RELOAD_QUEST_TEMPLATE = 679, + RBAC_PERM_COMMAND_RELOAD_RBAC = 680, + RBAC_PERM_COMMAND_RELOAD_REFERENCE_LOOT_TEMPLATE = 681, + RBAC_PERM_COMMAND_RELOAD_REPUTATION_REWARD_RATE = 682, + RBAC_PERM_COMMAND_RELOAD_RESERVED_NAME = 683, + RBAC_PERM_COMMAND_RELOAD_SKILL_DISCOVERY_TEMPLATE = 684, + RBAC_PERM_COMMAND_RELOAD_SKILL_EXTRA_ITEM_TEMPLATE = 685, + RBAC_PERM_COMMAND_RELOAD_SKILL_FISHING_BASE_LEVEL = 686, + RBAC_PERM_COMMAND_RELOAD_SKINNING_LOOT_TEMPLATE = 687, + RBAC_PERM_COMMAND_RELOAD_SMART_SCRIPTS = 688, + RBAC_PERM_COMMAND_RELOAD_SPELL_AREA = 689, + RBAC_PERM_COMMAND_RELOAD_SPELL_BONUS_DATA = 690, + RBAC_PERM_COMMAND_RELOAD_SPELL_GROUP = 691, + RBAC_PERM_COMMAND_RELOAD_SPELL_GROUP_STACK_RULES = 692, + RBAC_PERM_COMMAND_RELOAD_SPELL_LEARN_SPELL = 693, + RBAC_PERM_COMMAND_RELOAD_SPELL_LINKED_SPELL = 694, + RBAC_PERM_COMMAND_RELOAD_SPELL_LOOT_TEMPLATE = 695, + RBAC_PERM_COMMAND_RELOAD_SPELL_PET_AURAS = 696, + RBAC_PERM_COMMAND_RELOAD_SPELL_PROC = 697, + RBAC_PERM_COMMAND_RELOAD_SPELL_PROC_EVENT = 698, + RBAC_PERM_COMMAND_RELOAD_SPELL_REQUIRED = 699, + RBAC_PERM_COMMAND_RELOAD_SPELL_SCRIPTS = 700, + RBAC_PERM_COMMAND_RELOAD_SPELL_TARGET_POSITION = 701, + RBAC_PERM_COMMAND_RELOAD_SPELL_THREATS = 702, + RBAC_PERM_COMMAND_RELOAD_SPILLOVER_TEMPLATE = 703, + RBAC_PERM_COMMAND_RELOAD_TRINITY_STRING = 704, + RBAC_PERM_COMMAND_RELOAD_VEHICLE_ACCESORY = 705, + RBAC_PERM_COMMAND_RELOAD_VEHICLE_TEMPLATE_ACCESSORY = 706, + RBAC_PERM_COMMAND_RELOAD_WARDEN_ACTION = 707, + RBAC_PERM_COMMAND_RELOAD_WAYPOINT_DATA = 708, + RBAC_PERM_COMMAND_RELOAD_WAYPOINT_SCRIPTS = 709, RBAC_PERM_COMMAND_RESET = 710, RBAC_PERM_COMMAND_RESET_ACHIEVEMENTS = 711, RBAC_PERM_COMMAND_RESET_HONOR = 712, @@ -692,93 +695,53 @@ enum RBACCommandResult RBAC_ID_DOES_NOT_EXISTS }; -typedef std::bitset<RBAC_PERM_MAX> RBACPermissionContainer; -typedef std::set<uint32> RBACRoleContainer; -typedef std::set<uint32> RBACGroupContainer; +typedef std::set<uint32> RBACPermissionContainer; -class RBACObject +class RBACPermission { public: - RBACObject(uint32 id = 0, std::string const& name = ""): + RBACPermission(uint32 id = 0, std::string const& name = ""): _id(id), _name(name) { } - virtual ~RBACObject() { } - /// Gets the Name of the Object std::string const& GetName() const { return _name; } /// Gets the Id of the Object uint32 GetId() const { return _id; } + /// Gets the Permissions linked to this permission + RBACPermissionContainer const& GetLinkedPermissions() const { return _perms; } + /// Adds a new linked Permission + void AddLinkedPermission(uint32 id) { _perms.insert(id); } + /// Removes a linked Permission + void RemoveLinkedPermission(uint32 id) { _perms.erase(id); } + private: uint32 _id; ///> id of the object std::string _name; ///> name of the object -}; - -/// Permission: Defines an autorization to perform certain operation -class RBACPermission: public RBACObject -{ - public: - RBACPermission(uint32 id = 0, std::string const& name = ""): - RBACObject(id, name) { } -}; - -/// Set of Permissions -class RBACRole: public RBACObject -{ - public: - RBACRole(uint32 id = 0, std::string const& name = ""): - RBACObject(id, name) { } - - /// Gets the Permissions assigned to this role - RBACPermissionContainer const& GetPermissions() const { return _perms; } - /// Grants a Permission (Adds) - void GrantPermission(uint32 id); - /// Revokes a Permission (Removes) - void RevokePermission(uint32 id); - - private: RBACPermissionContainer _perms; ///> Set of permissions }; -/// Set of Roles -class RBACGroup: public RBACObject -{ - public: - RBACGroup(uint32 id = 0, std::string const& name = ""): - RBACObject(id, name) { } - - /// Gets the Roles assigned to this group - RBACRoleContainer const& GetRoles() const { return _roles; } - /// Grants a Role (Adds) - void GrantRole(uint32 role); - /// Revokes a Role (Removes) - void RevokeRole(uint32 role); - - private: - RBACRoleContainer _roles; ///> Set of Roles -}; - /** * @name RBACData * @brief Contains all needed information about the acccount * * This class contains all the data needed to calculate the account permissions. - * RBACDAta is formed by group permissions and user permissions through: - * - Granted Groups, which contains roles, which contains permissions: Set of granted permissions - * - Granted Roles, which contains permissions: Set of granted permissions - * - Denied Roles, which contains permissions: Set of denied permissions - * - Granted Permissions - * - Denied Permissions + * RBACDAta is formed by granted and denied permissions and all the inherited permissions * * Calculation of current Permissions: Granted permissions - Denied permissions - * - Granted permissions: through groups, through roles and directly assigned - * - Denied permissions: through roles and directly assigned + * - Granted permissions: through linked permissions and directly assigned + * - Denied permissions: through linked permissions and directly assigned */ -class RBACData: public RBACObject +class RBACData { public: - RBACData(uint32 id, std::string const& name, int32 realmId): - RBACObject(id, name), _realmId(realmId) { } + RBACData(uint32 id, std::string const& name, int32 realmId, uint8 secLevel = 255): + _id(id), _name(name), _realmId(realmId), _secLevel(secLevel) { } + + /// Gets the Name of the Object + std::string const& GetName() const { return _name; } + /// Gets the Id of the Object + uint32 GetId() const { return _id; } /** * @name HasPermission @@ -796,7 +759,10 @@ class RBACData: public RBACObject * } * @endcode */ - bool HasPermission(uint32 permission) const { return _globalPerms.test(permission); } + bool HasPermission(uint32 permission) const + { + return _globalPerms.find(permission) != _globalPerms.end(); + } // Functions enabled to be used by command system /// Returns all the granted permissions (after computation) @@ -805,130 +771,6 @@ class RBACData: public RBACObject RBACPermissionContainer const& GetGrantedPermissions() const { return _grantedPerms; } /// Returns all the denied permissions RBACPermissionContainer const& GetDeniedPermissions() const { return _deniedPerms; } - /// Returns all the granted roles - RBACRoleContainer const& GetGrantedRoles() const { return _grantedRoles; } - /// Returns all the denied roles - RBACRoleContainer const& GetDeniedRoles() const { return _deniedRoles; } - /// Returns all the granted groups - RBACGroupContainer const& GetGroups() const { return _groups; } - - /** - * @name AddGroup - * @brief Adds new group - * - * Add a new group to the account. If realm is 0 or the group can not be added - * No save to db action will be performed. - * - * Fails if group Id does not exists or group already present - * - * @param groupId group to be added - * @param realmId realm affected - * - * @return Success or failure (with reason) to add the group - * - * Example Usage: - * @code - * // previously defined "RBACData* rbac" with proper initialization - * uint32 groupId = 2; - * if (rbac->AddGroup(groupId) == RBAC_OK) - * TC_LOG_DEBUG(LOG_FILTER_PLAYER, "Group %u succesfully added", groupId); - * @endcode - */ - RBACCommandResult AddGroup(uint32 groupId, int32 realmId = 0); - - /** - * @name RemoveGroup - * @brief Removes a group - * - * Removes a group from the account. If realm is 0 or the group can not be removed - * No save to db action will be performed. Any delete operation will always affect - * "all realms (-1)" in addition to the realm specified - * - * Fails if group not present - * - * @param groupId group to be removed - * @param realmId realm affected - * - * @return Success or failure (with reason) to remove the group - * - * Example Usage: - * // previously defined "RBACData* rbac" with proper initialization - * uint32 groupId = 2; - * if (rbac->RemoveGroup(groupId) == RBAC_OK) - * TC_LOG_DEBUG(LOG_FILTER_PLAYER, "Group %u succesfully removed", groupId); - * @endcode - */ - RBACCommandResult RemoveGroup(uint32 groupId, int32 realmId = 0); - - /** - * @name GrantRole - * @brief Grants a role - * - * Grants a role to the account. If realm is 0 or the role can not be added - * No save to db action will be performed. - * - * Fails if role Id does not exists or role already granted or denied - * - * @param roleId role to be granted - * @param realmId realm affected - * - * @return Success or failure (with reason) to grant the role - * - * Example Usage: - * // previously defined "RBACData* rbac" with proper initialization - * uint32 roleId = 2; - * if (rbac->GrantRole(roleId) == RBAC_IN_DENIED_LIST) - * TC_LOG_DEBUG(LOG_FILTER_PLAYER, "Failed to grant role %u, already denied", roleId); - * @endcode - */ - RBACCommandResult GrantRole(uint32 roleId, int32 realmId = 0); - - /** - * @name DenyRole - * @brief Denies a role - * - * Denied a role to the account. If realm is 0 or the role can not be added - * No save to db action will be performed. - * - * Fails if role Id does not exists or role already granted or denied - * - * @param roleId role to be denied - * @param realmId realm affected - * - * @return Success or failure (with reason) to deny the role - * - * Example Usage: - * // previously defined "RBACData* rbac" with proper initialization - * uint32 roleId = 2; - * if (rbac->DenyRole(roleId) == RBAC_ID_DOES_NOT_EXISTS) - * TC_LOG_DEBUG(LOG_FILTER_PLAYER, "Role Id %u does not exists", roleId); - * @endcode - */ - RBACCommandResult DenyRole(uint32 roleId, int32 realmId = 0); - - /** - * @name RevokeRole - * @brief Removes a role - * - * Removes a role from the account. If realm is 0 or the role can not be removed - * No save to db action will be performed. Any delete operation will always affect - * "all realms (-1)" in addition to the realm specified - * - * Fails if role not present - * - * @param roleId role to be removed - * @param realmId realm affected - * - * @return Success or failure (with reason) to remove the role - * - * Example Usage: - * // previously defined "RBACData* rbac" with proper initialization - * uint32 roleId = 2; - * if (rbac->RevokeRole(roleId) == RBAC_OK) - * TC_LOG_DEBUG(LOG_FILTER_PLAYER, "Role %u succesfully removed", roleId); - * @endcode - */ - RBACCommandResult RevokeRole(uint32 roleId, int32 realmId = 0); /** * @name GrantRole @@ -1000,34 +842,103 @@ class RBACData: public RBACObject */ RBACCommandResult RevokePermission(uint32 permissionId, int32 realmId = 0); - /// Loads all permissions, groups and roles assigned to current account + /// Loads all permissions assigned to current account void LoadFromDB(); + + /// Sets security level + void SetSecurityLevel(uint8 id) + { + _secLevel = id; + LoadFromDB(); + } + + /// Returns the security level assigned + uint8 GetSecurityLevel() const { return _secLevel; } private: - /// Saves a role to DB, Granted or Denied - void SaveRole(uint32 role, bool granted, int32 realm); /// Saves a permission to DB, Granted or Denied void SavePermission(uint32 role, bool granted, int32 realm); + /// Clears roles, groups and permissions - Used for reload + void ClearData(); /** * @name CalculateNewPermissions * @brief Calculates new permissions * - * Calculates new permissions after some change in groups, roles or permissions. + * Calculates new permissions after some change * The calculation is done Granted - Denied: - * - Granted permissions: through groups, through roles and directly assigned - * - Denied permissions: through roles and directly assigned + * - Granted permissions: through linked permissions and directly assigned + * - Denied permissions: through linked permissions and directly assigned */ void CalculateNewPermissions(); int32 GetRealmId() { return _realmId; } + // Auxiliar private functions - defined to allow to maintain same code even + // if internal structure changes. + + /// Checks if a permission is granted + bool HasGrantedPermission(uint32 permissionId) const + { + return _grantedPerms.find(permissionId) != _grantedPerms.end(); + } + + /// Checks if a permission is denied + bool HasDeniedPermission(uint32 permissionId) const + { + return _deniedPerms.find(permissionId) != _deniedPerms.end(); + } + + /// Adds a new granted permission + void AddGrantedPermission(uint32 permissionId) + { + _grantedPerms.insert(permissionId); + } + + /// Removes a granted permission + void RemoveGrantedPermission(uint32 permissionId) + { + _grantedPerms.erase(permissionId); + } + + /// Adds a new denied permission + void AddDeniedPermission(uint32 permissionId) + { + _deniedPerms.insert(permissionId); + } + + /// Removes a denied permission + void RemoveDeniedPermission(uint32 permissionId) + { + _deniedPerms.erase(permissionId); + } + + /// Adds a list of permissions to another list + void AddPermissions(RBACPermissionContainer const& permsFrom, RBACPermissionContainer& permsTo); + + /// Removes a list of permissions to another list + void RemovePermissions(RBACPermissionContainer const& permsFrom, RBACPermissionContainer& permsTo); + + /** + * @name ExpandPermissions + * @brief Adds the list of linked permissions to the original list + * + * Given a list of permissions, gets all the inherited permissions + * @param permissions The list of permissions to expand + * + * @return new list of permissions containing original permissions and + * all other pemissions that are linked to the original ones + */ + void ExpandPermissions(RBACPermissionContainer& permissions); + + uint32 _id; ///> Account id + std::string _name; ///> Account name int32 _realmId; ///> RealmId Affected - RBACGroupContainer _groups; ///> Granted groups - RBACRoleContainer _grantedRoles; ///> Granted roles - RBACRoleContainer _deniedRoles; ///> Denied roles + uint8 _secLevel; ///> Account SecurityLevel RBACPermissionContainer _grantedPerms; ///> Granted permissions RBACPermissionContainer _deniedPerms; ///> Denied permissions RBACPermissionContainer _globalPerms; ///> Calculated permissions }; +} + #endif diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp index 6186e616928..79d36b694bf 100644 --- a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp +++ b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp @@ -104,12 +104,12 @@ void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry* auction, SQLTransaction& { bidderAccId = bidder->GetSession()->GetAccountId(); bidderName = bidder->GetName(); - logGmTrade = bidder->GetSession()->HasPermission(RBAC_PERM_LOG_GM_TRADE); + logGmTrade = bidder->GetSession()->HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE); } else { bidderAccId = sObjectMgr->GetPlayerAccountIdByGUID(bidderGuid); - logGmTrade = AccountMgr::HasPermission(bidderAccId, RBAC_PERM_LOG_GM_TRADE, realmID); + logGmTrade = AccountMgr::HasPermission(bidderAccId, rbac::RBAC_PERM_LOG_GM_TRADE, realmID); if (logGmTrade && !sObjectMgr->GetPlayerNameByGUID(bidderGuid, bidderName)) bidderName = sObjectMgr->GetTrinityStringForDBCLocale(LANG_UNKNOWN); diff --git a/src/server/game/Chat/Channels/Channel.cpp b/src/server/game/Chat/Channels/Channel.cpp index d8a1413bb63..10af9f4fb1a 100644 --- a/src/server/game/Chat/Channels/Channel.cpp +++ b/src/server/game/Chat/Channels/Channel.cpp @@ -191,7 +191,7 @@ void Channel::JoinChannel(Player* player, std::string const& pass) player->JoinedChannel(this); - if (_announce && !player->GetSession()->HasPermission(RBAC_PERM_SILENTLY_JOIN_CHANNEL)) + if (_announce && !player->GetSession()->HasPermission(rbac::RBAC_PERM_SILENTLY_JOIN_CHANNEL)) { WorldPacket data; MakeJoined(&data, guid); @@ -252,7 +252,7 @@ void Channel::LeaveChannel(Player* player, bool send) playersStore.erase(guid); - if (_announce && !player->GetSession()->HasPermission(RBAC_PERM_SILENTLY_JOIN_CHANNEL)) + if (_announce && !player->GetSession()->HasPermission(rbac::RBAC_PERM_SILENTLY_JOIN_CHANNEL)) { WorldPacket data; MakeLeft(&data, guid); @@ -288,7 +288,7 @@ void Channel::KickOrBan(Player const* player, std::string const& badname, bool b return; } - if (!playersStore[good].IsModerator() && !player->GetSession()->HasPermission(RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR)) + if (!playersStore[good].IsModerator() && !player->GetSession()->HasPermission(rbac::RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR)) { WorldPacket data; MakeNotModerator(&data); @@ -308,7 +308,7 @@ void Channel::KickOrBan(Player const* player, std::string const& badname, bool b bool changeowner = _ownerGUID == victim; - if (!player->GetSession()->HasPermission(RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR) && changeowner && good != _ownerGUID) + if (!player->GetSession()->HasPermission(rbac::RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR) && changeowner && good != _ownerGUID) { WorldPacket data; MakeNotOwner(&data); @@ -321,14 +321,14 @@ void Channel::KickOrBan(Player const* player, std::string const& badname, bool b bannedStore.insert(victim); UpdateChannelInDB(); - if (!player->GetSession()->HasPermission(RBAC_PERM_SILENTLY_JOIN_CHANNEL)) + if (!player->GetSession()->HasPermission(rbac::RBAC_PERM_SILENTLY_JOIN_CHANNEL)) { WorldPacket data; MakePlayerBanned(&data, victim, good); SendToAll(&data); } } - else if (!player->GetSession()->HasPermission(RBAC_PERM_SILENTLY_JOIN_CHANNEL)) + else if (!player->GetSession()->HasPermission(rbac::RBAC_PERM_SILENTLY_JOIN_CHANNEL)) { WorldPacket data; MakePlayerKicked(&data, victim, good); @@ -358,7 +358,7 @@ void Channel::UnBan(Player const* player, std::string const& badname) return; } - if (!playersStore[good].IsModerator() && !player->GetSession()->HasPermission(RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR)) + if (!playersStore[good].IsModerator() && !player->GetSession()->HasPermission(rbac::RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR)) { WorldPacket data; MakeNotModerator(&data); @@ -399,7 +399,7 @@ void Channel::Password(Player const* player, std::string const& pass) return; } - if (!playersStore[guid].IsModerator() && !player->GetSession()->HasPermission(RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR)) + if (!playersStore[guid].IsModerator() && !player->GetSession()->HasPermission(rbac::RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR)) { WorldPacket data; MakeNotModerator(&data); @@ -428,7 +428,7 @@ void Channel::SetMode(Player const* player, std::string const& p2n, bool mod, bo return; } - if (!playersStore[guid].IsModerator() && !player->GetSession()->HasPermission(RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR)) + if (!playersStore[guid].IsModerator() && !player->GetSession()->HasPermission(rbac::RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR)) { WorldPacket data; MakeNotModerator(&data); @@ -444,8 +444,8 @@ void Channel::SetMode(Player const* player, std::string const& p2n, bool mod, bo if (!victim || !IsOn(victim) || (player->GetTeam() != newp->GetTeam() && - (!player->GetSession()->HasPermission(RBAC_PERM_TWO_SIDE_INTERACTION_CHANNEL) || - !newp->GetSession()->HasPermission(RBAC_PERM_TWO_SIDE_INTERACTION_CHANNEL)))) + (!player->GetSession()->HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHANNEL) || + !newp->GetSession()->HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHANNEL)))) { WorldPacket data; MakePlayerNotFound(&data, p2n); @@ -479,7 +479,7 @@ void Channel::SetOwner(Player const* player, std::string const& newname) return; } - if (!player->GetSession()->HasPermission(RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR) && guid != _ownerGUID) + if (!player->GetSession()->HasPermission(rbac::RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR) && guid != _ownerGUID) { WorldPacket data; MakeNotOwner(&data); @@ -492,8 +492,8 @@ void Channel::SetOwner(Player const* player, std::string const& newname) if (!victim || !IsOn(victim) || (player->GetTeam() != newp->GetTeam() && - (!player->GetSession()->HasPermission(RBAC_PERM_TWO_SIDE_INTERACTION_CHANNEL) || - !newp->GetSession()->HasPermission(RBAC_PERM_TWO_SIDE_INTERACTION_CHANNEL)))) + (!player->GetSession()->HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHANNEL) || + !newp->GetSession()->HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHANNEL)))) { WorldPacket data; MakePlayerNotFound(&data, newname); @@ -548,7 +548,7 @@ void Channel::List(Player const* player) // PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters // MODERATOR, GAME MASTER, ADMINISTRATOR can see all if (member && - (player->GetSession()->HasPermission(RBAC_PERM_WHO_SEE_ALL_SEC_LEVELS) || + (player->GetSession()->HasPermission(rbac::RBAC_PERM_WHO_SEE_ALL_SEC_LEVELS) || member->GetSession()->GetSecurity() <= AccountTypes(gmLevelInWhoList)) && member->IsVisibleGloballyFor(player)) { @@ -575,7 +575,7 @@ void Channel::Announce(Player const* player) return; } - if (!playersStore[guid].IsModerator() && !player->GetSession()->HasPermission(RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR)) + if (!playersStore[guid].IsModerator() && !player->GetSession()->HasPermission(rbac::RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR)) { WorldPacket data; MakeNotModerator(&data); @@ -668,8 +668,8 @@ void Channel::Invite(Player const* player, std::string const& newname) } if (newp->GetTeam() != player->GetTeam() && - (!player->GetSession()->HasPermission(RBAC_PERM_TWO_SIDE_INTERACTION_CHANNEL) || - !newp->GetSession()->HasPermission(RBAC_PERM_TWO_SIDE_INTERACTION_CHANNEL))) + (!player->GetSession()->HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHANNEL) || + !newp->GetSession()->HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHANNEL))) { WorldPacket data; MakeInviteWrongFaction(&data); diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp index fdaaac394f4..50eb09a07e6 100644 --- a/src/server/game/Chat/Chat.cpp +++ b/src/server/game/Chat/Chat.cpp @@ -154,7 +154,7 @@ bool ChatHandler::HasLowerSecurityAccount(WorldSession* target, uint32 target_ac return false; // ignore only for non-players for non strong checks (when allow apply command at least to same sec level) - if (m_session->HasPermission(RBAC_PERM_CHECK_FOR_LOWER_SECURITY) && !strong && !sWorld->getBoolConfig(CONFIG_GM_LOWER_SECURITY)) + if (m_session->HasPermission(rbac::RBAC_PERM_CHECK_FOR_LOWER_SECURITY) && !strong && !sWorld->getBoolConfig(CONFIG_GM_LOWER_SECURITY)) return false; if (target) @@ -344,7 +344,7 @@ bool ChatHandler::ExecuteCommandInTable(ChatCommand* table, const char* text, st Player* player = m_session->GetPlayer(); if (!AccountMgr::IsPlayerAccount(m_session->GetSecurity())) { - uint64 guid = player->GetSelection(); + uint64 guid = player->GetTarget(); uint32 areaId = player->GetAreaId(); std::string areaName = "Unknown"; std::string zoneName = "Unknown"; @@ -464,7 +464,7 @@ bool ChatHandler::ParseCommands(char const* text) if (!ExecuteCommandInTable(getCommandTable(), text, fullcmd)) { - if (m_session && !m_session->HasPermission(RBAC_PERM_COMMANDS_NOTIFY_COMMAND_NOT_FOUND_ERROR)) + if (m_session && !m_session->HasPermission(rbac::RBAC_PERM_COMMANDS_NOTIFY_COMMAND_NOT_FOUND_ERROR)) return false; SendSysMessage(LANG_NO_CMD); @@ -726,12 +726,11 @@ Player* ChatHandler::getSelectedPlayer() if (!m_session) return NULL; - uint64 guid = m_session->GetPlayer()->GetSelection(); - - if (guid == 0) + uint64 selected = m_session->GetPlayer()->GetTarget(); + if (!selected) return m_session->GetPlayer(); - return ObjectAccessor::FindPlayer(guid); + return ObjectAccessor::FindPlayer(selected); } Unit* ChatHandler::getSelectedUnit() @@ -739,12 +738,10 @@ Unit* ChatHandler::getSelectedUnit() if (!m_session) return NULL; - uint64 guid = m_session->GetPlayer()->GetSelection(); - - if (guid == 0) - return m_session->GetPlayer(); + if (Unit* selected = m_session->GetPlayer()->GetSelectedUnit()) + return selected; - return ObjectAccessor::GetUnit(*m_session->GetPlayer(), guid); + return m_session->GetPlayer(); } WorldObject* ChatHandler::getSelectedObject() @@ -752,7 +749,7 @@ WorldObject* ChatHandler::getSelectedObject() if (!m_session) return NULL; - uint64 guid = m_session->GetPlayer()->GetSelection(); + uint64 guid = m_session->GetPlayer()->GetTarget(); if (guid == 0) return GetNearbyGameObject(); @@ -765,7 +762,7 @@ Creature* ChatHandler::getSelectedCreature() if (!m_session) return NULL; - return ObjectAccessor::GetCreatureOrPetOrVehicle(*m_session->GetPlayer(), m_session->GetPlayer()->GetSelection()); + return ObjectAccessor::GetCreatureOrPetOrVehicle(*m_session->GetPlayer(), m_session->GetPlayer()->GetTarget()); } char* ChatHandler::extractKeyFromLink(char* text, char const* linkType, char** something1) diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index d29e0800776..2a7f1c534b2 100644 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -379,7 +379,7 @@ void LFGMgr::InitializeLockedDungeons(Player* player, uint8 level /* = 0 */) uint8 expansion = player->GetSession()->Expansion(); LfgDungeonSet const& dungeons = GetDungeonsByRandom(0); LfgLockMap lock; - bool denyJoin = !player->GetSession()->HasPermission(RBAC_PERM_JOIN_DUNGEON_FINDER); + bool denyJoin = !player->GetSession()->HasPermission(rbac::RBAC_PERM_JOIN_DUNGEON_FINDER); for (LfgDungeonSet::const_iterator it = dungeons.begin(); it != dungeons.end(); ++it) { @@ -472,7 +472,7 @@ void LFGMgr::JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons, const } // Check player or group member restrictions - if (!player->GetSession()->HasPermission(RBAC_PERM_JOIN_DUNGEON_FINDER)) + if (!player->GetSession()->HasPermission(rbac::RBAC_PERM_JOIN_DUNGEON_FINDER)) joinData.result = LFG_JOIN_NOT_MEET_REQS; else if (player->InBattleground() || player->InArena() || player->InBattlegroundQueue()) joinData.result = LFG_JOIN_USING_BG_SYSTEM; @@ -493,7 +493,7 @@ void LFGMgr::JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons, const { if (Player* plrg = itr->GetSource()) { - if (!plrg->GetSession()->HasPermission(RBAC_PERM_JOIN_DUNGEON_FINDER)) + if (!plrg->GetSession()->HasPermission(rbac::RBAC_PERM_JOIN_DUNGEON_FINDER)) joinData.result = LFG_JOIN_INTERNAL_ERROR; if (plrg->HasAura(LFG_SPELL_DUNGEON_DESERTER)) joinData.result = LFG_JOIN_PARTY_DESERTER; diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index a5c9a3f8391..5f06cab3b8a 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -165,6 +165,7 @@ m_creatureInfo(NULL), m_creatureData(NULL), m_path_id(0), m_formation(NULL) ResetLootMode(); // restore default loot mode TriggerJustRespawned = false; m_isTempWorldObject = false; + _focusSpell = NULL; } Creature::~Creature() @@ -1716,7 +1717,7 @@ SpellInfo const* Creature::reachWithSpellCure(Unit* victim) } // select nearest hostile unit within the given distance (regardless of threat list). -Unit* Creature::SelectNearestTarget(float dist) const +Unit* Creature::SelectNearestTarget(float dist, bool playerOnly /* = false */) const { CellCoord p(Trinity::ComputeCellCoord(GetPositionX(), GetPositionY())); Cell cell(p); @@ -1728,7 +1729,7 @@ Unit* Creature::SelectNearestTarget(float dist) const if (dist == 0.0f) dist = MAX_VISIBILITY_DISTANCE; - Trinity::NearestHostileUnitCheck u_check(this, dist); + Trinity::NearestHostileUnitCheck u_check(this, dist, playerOnly); Trinity::UnitLastSearcher<Trinity::NearestHostileUnitCheck> searcher(this, target, u_check); TypeContainerVisitor<Trinity::UnitLastSearcher<Trinity::NearestHostileUnitCheck>, WorldTypeMapContainer > world_unit_searcher(searcher); @@ -2538,3 +2539,41 @@ void Creature::SetDisplayId(uint32 modelId) SetFloatValue(UNIT_FIELD_COMBATREACH, minfo->combat_reach * GetObjectScale()); } } + +void Creature::SetTarget(uint64 guid) +{ + if (!_focusSpell) + SetUInt64Value(UNIT_FIELD_TARGET, guid); +} + +void Creature::FocusTarget(Spell const* focusSpell, WorldObject const* target) +{ + // already focused + if (_focusSpell) + return; + + _focusSpell = focusSpell; + SetUInt64Value(UNIT_FIELD_TARGET, target->GetGUID()); + if (focusSpell->GetSpellInfo()->AttributesEx5 & SPELL_ATTR5_DONT_TURN_DURING_CAST) + AddUnitState(UNIT_STATE_ROTATING); + + // Set serverside orientation if needed (needs to be after attribute check) + SetInFront(target); +} + +void Creature::ReleaseFocus(Spell const* focusSpell) +{ + // focused to something else + if (focusSpell != _focusSpell) + return; + + _focusSpell = NULL; + if (Unit* victim = GetVictim()) + SetUInt64Value(UNIT_FIELD_TARGET, victim->GetGUID()); + else + SetUInt64Value(UNIT_FIELD_TARGET, 0); + + if (focusSpell->GetSpellInfo()->AttributesEx5 & SPELL_ATTR5_DONT_TURN_DURING_CAST) + ClearUnitState(UNIT_STATE_ROTATING); +} + diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index 365bb05444e..eb0f006b105 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -598,7 +598,7 @@ class Creature : public Unit, public GridObject<Creature>, public MapCreature void SendAIReaction(AiReaction reactionType); - Unit* SelectNearestTarget(float dist = 0) const; + Unit* SelectNearestTarget(float dist = 0, bool playerOnly = false) const; Unit* SelectNearestTargetInAttackDistance(float dist = 0) const; Player* SelectNearestPlayer(float distance = 0) const; Unit* SelectNearestHostileUnitInAggroRange(bool useLOS = false) const; @@ -692,6 +692,11 @@ class Creature : public Unit, public GridObject<Creature>, public MapCreature bool m_isTempWorldObject; //true when possessed + // Handling caster facing during spellcast + void SetTarget(uint64 guid); + void FocusTarget(Spell const* focusSpell, WorldObject const* target); + void ReleaseFocus(Spell const* focusSpell); + protected: bool CreateFromProto(uint32 guidlow, uint32 Entry, uint32 vehId, uint32 team, const CreatureData* data = NULL); bool InitEntry(uint32 entry, uint32 team=ALLIANCE, const CreatureData* data=NULL); @@ -751,6 +756,8 @@ class Creature : public Unit, public GridObject<Creature>, public MapCreature //Formation var CreatureGroup* m_formation; bool TriggerJustRespawned; + + Spell const* _focusSpell; ///> Locks the target during spell cast for proper facing }; class AssistDelayEvent : public BasicEvent diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index f6e6116f391..3ba02553855 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -1509,7 +1509,7 @@ void GameObject::Use(Unit* user) Player* player = user->ToPlayer(); - Player* targetPlayer = ObjectAccessor::FindPlayer(player->GetSelection()); + Player* targetPlayer = ObjectAccessor::FindPlayer(player->GetTarget()); // accept only use by player from same raid as caster, except caster itself if (!targetPlayer || targetPlayer == player || !targetPlayer->IsInSameRaidWith(player)) diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 0a5eb82a175..976a5dcd005 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -93,7 +93,7 @@ WorldObject::~WorldObject() { if (GetTypeId() == TYPEID_CORPSE) { - TC_LOG_FATAL(LOG_FILTER_GENERAL, "Object::~Object Corpse guid="UI64FMTD", type=%d, entry=%u deleted but still in map!!", + TC_LOG_FATAL(LOG_FILTER_GENERAL, "Object::~Object Corpse guid=" UI64FMTD ", type=%d, entry=%u deleted but still in map!!", GetGUID(), ((Corpse*)this)->GetType(), GetEntry()); ASSERT(false); } @@ -105,7 +105,7 @@ Object::~Object() { if (IsInWorld()) { - TC_LOG_FATAL(LOG_FILTER_GENERAL, "Object::~Object - guid="UI64FMTD", typeid=%d, entry=%u deleted but still in world!!", GetGUID(), GetTypeId(), GetEntry()); + TC_LOG_FATAL(LOG_FILTER_GENERAL, "Object::~Object - guid=" UI64FMTD ", typeid=%d, entry=%u deleted but still in world!!", GetGUID(), GetTypeId(), GetEntry()); if (isType(TYPEMASK_ITEM)) TC_LOG_FATAL(LOG_FILTER_GENERAL, "Item slot %u", ((Item*)this)->GetSlot()); ASSERT(false); @@ -114,7 +114,7 @@ Object::~Object() if (m_objectUpdated) { - TC_LOG_FATAL(LOG_FILTER_GENERAL, "Object::~Object - guid="UI64FMTD", typeid=%d, entry=%u deleted but still in update list!!", GetGUID(), GetTypeId(), GetEntry()); + TC_LOG_FATAL(LOG_FILTER_GENERAL, "Object::~Object - guid=" UI64FMTD ", typeid=%d, entry=%u deleted but still in update list!!", GetGUID(), GetTypeId(), GetEntry()); ASSERT(false); sObjectAccessor->RemoveUpdateObject(this); } diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp index 088098275e9..287fd915c6d 100644 --- a/src/server/game/Entities/Pet/Pet.cpp +++ b/src/server/game/Entities/Pet/Pet.cpp @@ -1690,22 +1690,22 @@ bool Pet::resetTalents() return true; } -void Pet::resetTalentsForAllPetsOf(Player* owner, Pet* online_pet /*= NULL*/) +void Pet::resetTalentsForAllPetsOf(Player* owner, Pet* onlinePet /*= NULL*/) { // not need after this call - if (owner->ToPlayer()->HasAtLoginFlag(AT_LOGIN_RESET_PET_TALENTS)) - owner->ToPlayer()->RemoveAtLoginFlag(AT_LOGIN_RESET_PET_TALENTS, true); + if (owner->HasAtLoginFlag(AT_LOGIN_RESET_PET_TALENTS)) + owner->RemoveAtLoginFlag(AT_LOGIN_RESET_PET_TALENTS, true); // reset for online - if (online_pet) - online_pet->resetTalents(); + if (onlinePet) + onlinePet->resetTalents(); // now need only reset for offline pets (all pets except online case) - uint32 except_petnumber = online_pet ? online_pet->GetCharmInfo()->GetPetNumber() : 0; + uint32 exceptPetNumber = onlinePet ? onlinePet->GetCharmInfo()->GetPetNumber() : 0; PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_PET); stmt->setUInt32(0, owner->GetGUIDLow()); - stmt->setUInt32(1, except_petnumber); + stmt->setUInt32(1, exceptPetNumber); PreparedQueryResult resultPets = CharacterDatabase.Query(stmt); // no offline pets @@ -1714,7 +1714,7 @@ void Pet::resetTalentsForAllPetsOf(Player* owner, Pet* online_pet /*= NULL*/) stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PET_SPELL_LIST); stmt->setUInt32(0, owner->GetGUIDLow()); - stmt->setUInt32(1, except_petnumber); + stmt->setUInt32(1, exceptPetNumber); PreparedQueryResult result = CharacterDatabase.Query(stmt); if (!result) diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 2354db24fb9..eb81c136b43 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -690,10 +690,9 @@ Player::Player(WorldSession* session): Unit(true), phaseMgr(this) //m_pad = 0; // players always accept - if (!GetSession()->HasPermission(RBAC_PERM_CAN_FILTER_WHISPERS)) + if (!GetSession()->HasPermission(rbac::RBAC_PERM_CAN_FILTER_WHISPERS)) SetAcceptWhispers(true); - m_curSelection = 0; m_lootGuid = 0; m_comboTarget = 0; @@ -1033,7 +1032,7 @@ bool Player::Create(uint32 guidlow, CharacterCreateInfo* createInfo) ? sWorld->getIntConfig(CONFIG_START_PLAYER_LEVEL) : sWorld->getIntConfig(CONFIG_START_HEROIC_PLAYER_LEVEL); - if (m_session->HasPermission(RBAC_PERM_USE_START_GM_LEVEL)) + if (m_session->HasPermission(rbac::RBAC_PERM_USE_START_GM_LEVEL)) { uint32 gm_level = sWorld->getIntConfig(CONFIG_START_GM_LEVEL); if (gm_level > start_level) @@ -2113,7 +2112,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati return false; } - if (!GetSession()->HasPermission(RBAC_PERM_SKIP_CHECK_DISABLE_MAP) && DisableMgr::IsDisabledFor(DISABLE_TYPE_MAP, mapid, this)) + if (!GetSession()->HasPermission(rbac::RBAC_PERM_SKIP_CHECK_DISABLE_MAP) && DisableMgr::IsDisabledFor(DISABLE_TYPE_MAP, mapid, this)) { TC_LOG_ERROR(LOG_FILTER_MAPS, "Player (GUID: %u, name: %s) tried to enter a forbidden map %u", GetGUIDLow(), GetName().c_str(), mapid); SendTransferAborted(mapid, TRANSFER_ABORT_MAP_NOT_ALLOWED); @@ -3224,7 +3223,7 @@ void Player::InitTalentForLevel() // if used more that have then reset if (GetUsedTalentCount() > talentPointsForLevel) { - if (!GetSession()->HasPermission(RBAC_PERM_SKIP_CHECK_MORE_TALENTS_THAN_ALLOWED)) + if (!GetSession()->HasPermission(rbac::RBAC_PERM_SKIP_CHECK_MORE_TALENTS_THAN_ALLOWED)) ResetTalents(true); else SetFreeTalentPoints(0); @@ -17084,7 +17083,7 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder) // check name limitations if (ObjectMgr::CheckPlayerName(m_name) != CHAR_NAME_SUCCESS || - (!GetSession()->HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME) && + (!GetSession()->HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME) && sObjectMgr->IsReservedName(m_name))) { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG); @@ -17651,7 +17650,7 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder) outDebugValues(); // GM state - if (GetSession()->HasPermission(RBAC_PERM_RESTORE_SAVED_GM_STATE)) + if (GetSession()->HasPermission(rbac::RBAC_PERM_RESTORE_SAVED_GM_STATE)) { switch (sWorld->getIntConfig(CONFIG_GM_LOGIN_STATE)) { @@ -20172,7 +20171,7 @@ void Player::outDebugValues() const void Player::UpdateSpeakTime() { // ignore chat spam protection for GMs in any mode - if (GetSession()->HasPermission(RBAC_PERM_SKIP_CHECK_CHAT_SPAM)) + if (GetSession()->HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHAT_SPAM)) return; time_t current = time (NULL); @@ -20630,7 +20629,7 @@ void Player::TextEmote(const std::string& text) WorldPacket data(SMSG_MESSAGECHAT, 200); BuildPlayerChat(&data, CHAT_MSG_EMOTE, _text, LANG_UNIVERSAL); - SendMessageToSetInRange(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE), true, !GetSession()->HasPermission(RBAC_PERM_TWO_SIDE_INTERACTION_CHAT)); + SendMessageToSetInRange(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE), true, !GetSession()->HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHAT)); } void Player::WhisperAddon(const std::string& text, const std::string& prefix, Player* receiver) @@ -20799,7 +20798,7 @@ void Player::PossessSpellInitialize() if (!charmInfo) { - TC_LOG_ERROR(LOG_FILTER_PLAYER, "Player::PossessSpellInitialize(): charm ("UI64FMTD") has no charminfo!", charm->GetGUID()); + TC_LOG_ERROR(LOG_FILTER_PLAYER, "Player::PossessSpellInitialize(): charm (" UI64FMTD ") has no charminfo!", charm->GetGUID()); return; } @@ -20911,7 +20910,7 @@ void Player::CharmSpellInitialize() CharmInfo* charmInfo = charm->GetCharmInfo(); if (!charmInfo) { - TC_LOG_ERROR(LOG_FILTER_PLAYER, "Player::CharmSpellInitialize(): the player's charm ("UI64FMTD") has no charminfo!", charm->GetGUID()); + TC_LOG_ERROR(LOG_FILTER_PLAYER, "Player::CharmSpellInitialize(): the player's charm (" UI64FMTD ") has no charminfo!", charm->GetGUID()); return; } @@ -22639,13 +22638,13 @@ bool Player::CanJoinToBattleground(Battleground const* bg) const if (HasAura(26013)) return false; - if (bg->isArena() && !GetSession()->HasPermission(RBAC_PERM_JOIN_ARENAS)) + if (bg->isArena() && !GetSession()->HasPermission(rbac::RBAC_PERM_JOIN_ARENAS)) return false; - if (bg->IsRandom() && !GetSession()->HasPermission(RBAC_PERM_JOIN_RANDOM_BG)) + if (bg->IsRandom() && !GetSession()->HasPermission(rbac::RBAC_PERM_JOIN_RANDOM_BG)) return false; - if (!GetSession()->HasPermission(RBAC_PERM_JOIN_NORMAL_BG)) + if (!GetSession()->HasPermission(rbac::RBAC_PERM_JOIN_NORMAL_BG)) return false; return true; @@ -22997,15 +22996,15 @@ bool Player::IsQuestRewarded(uint32 quest_id) const Unit* Player::GetSelectedUnit() const { - if (m_curSelection) - return ObjectAccessor::GetUnit(*this, m_curSelection); + if (uint64 selectionGUID = GetUInt64Value(UNIT_FIELD_TARGET)) + return ObjectAccessor::GetUnit(*this, selectionGUID); return NULL; } Player* Player::GetSelectedPlayer() const { - if (m_curSelection) - return ObjectAccessor::GetPlayer(*this, m_curSelection); + if (uint64 selectionGUID = GetUInt64Value(UNIT_FIELD_TARGET)) + return ObjectAccessor::GetPlayer(*this, selectionGUID); return NULL; } @@ -26093,7 +26092,7 @@ void Player::SetEquipmentSet(uint32 index, EquipmentSet eqset) if (!found) // something wrong... { - TC_LOG_ERROR(LOG_FILTER_PLAYER, "Player %s tried to save equipment set "UI64FMTD" (index %u), but that equipment set not found!", GetName().c_str(), eqset.Guid, index); + TC_LOG_ERROR(LOG_FILTER_PLAYER, "Player %s tried to save equipment set " UI64FMTD " (index %u), but that equipment set not found!", GetName().c_str(), eqset.Guid, index); return; } } diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index ff81e0cd6e2..4804b4a1da2 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1695,10 +1695,11 @@ class Player : public Unit, public GridObject<Player> size_t GetRewardedQuestCount() const { return m_RewardedQuests.size(); } bool IsQuestRewarded(uint32 quest_id) const; - uint64 GetSelection() const { return m_curSelection; } Unit* GetSelectedUnit() const; Player* GetSelectedPlayer() const; - void SetSelection(uint64 guid) { m_curSelection = guid; SetUInt64Value(UNIT_FIELD_TARGET, guid); } + + void SetTarget(uint64 /*guid*/) OVERRIDE { } /// Used for serverside target changes, does not apply to players + void SetSelection(uint64 guid) { SetUInt64Value(UNIT_FIELD_TARGET, guid); } uint8 GetComboPoints() const { return m_comboPoints; } uint64 GetComboTarget() const { return m_comboTarget; } @@ -2688,7 +2689,6 @@ class Player : public Unit, public GridObject<Player> bool m_itemUpdateQueueBlocked; uint32 m_ExtraFlags; - uint64 m_curSelection; uint64 m_comboTarget; int8 m_comboPoints; diff --git a/src/server/game/Entities/Player/SocialMgr.cpp b/src/server/game/Entities/Player/SocialMgr.cpp index f4ab052aa1d..c257065afa6 100644 --- a/src/server/game/Entities/Player/SocialMgr.cpp +++ b/src/server/game/Entities/Player/SocialMgr.cpp @@ -221,12 +221,12 @@ void SocialMgr::GetFriendInfo(Player* player, uint32 friendGUID, FriendInfo &fri // PLAYER see his team only and PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters // MODERATOR, GAME MASTER, ADMINISTRATOR can see all - if (!player->GetSession()->HasPermission(RBAC_PERM_WHO_SEE_ALL_SEC_LEVELS) && + if (!player->GetSession()->HasPermission(rbac::RBAC_PERM_WHO_SEE_ALL_SEC_LEVELS) && target->GetSession()->GetSecurity() > AccountTypes(sWorld->getIntConfig(CONFIG_GM_LEVEL_IN_WHO_LIST))) return; // player can see member of other team only if CONFIG_ALLOW_TWO_SIDE_WHO_LIST - if (target->GetTeam() != player->GetTeam() && !player->GetSession()->HasPermission(RBAC_PERM_TWO_SIDE_WHO_LIST)) + if (target->GetTeam() != player->GetTeam() && !player->GetSession()->HasPermission(rbac::RBAC_PERM_TWO_SIDE_WHO_LIST)) return; if (target->IsVisibleGloballyFor(player)) @@ -303,10 +303,10 @@ void SocialMgr::BroadcastToFriendListers(Player* player, WorldPacket* packet) continue; WorldSession* session = target->GetSession(); - if (!session->HasPermission(RBAC_PERM_WHO_SEE_ALL_SEC_LEVELS) && player->GetSession()->GetSecurity() > gmSecLevel) + if (!session->HasPermission(rbac::RBAC_PERM_WHO_SEE_ALL_SEC_LEVELS) && player->GetSession()->GetSecurity() > gmSecLevel) continue; - if (target->GetTeam() != player->GetTeam() && !session->HasPermission(RBAC_PERM_TWO_SIDE_WHO_LIST)) + if (target->GetTeam() != player->GetTeam() && !session->HasPermission(rbac::RBAC_PERM_TWO_SIDE_WHO_LIST)) continue; if (player->IsVisibleGloballyFor(target)) diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 57503737043..659543d897d 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -258,7 +258,6 @@ Unit::Unit(bool isWorldObject) : m_serverSideVisibility.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_ALIVE); - _focusSpell = NULL; _lastLiquid = NULL; _isWalkingBeforeCharm = false; } @@ -569,6 +568,9 @@ uint32 Unit::DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDam if (IsAIEnabled) GetAI()->DamageDealt(victim, damage, damagetype); + // Hook for OnDamage Event + sScriptMgr->OnDamage(this, victim, damage); + if (victim->GetTypeId() == TYPEID_PLAYER && this != victim) { // Signal to pets that their owner was attacked @@ -2365,7 +2367,7 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit* victim, SpellInfo const* spellInfo SpellMissInfo Unit::MagicSpellHitResult(Unit* victim, SpellInfo const* spellInfo) { // Can`t miss on dead target (on skinning for example) - if (!victim->IsAlive() && victim->GetTypeId() != TYPEID_PLAYER) + if ((!victim->IsAlive() && victim->GetTypeId() != TYPEID_PLAYER) || spellInfo->AttributesEx3 & SPELL_ATTR3_IGNORE_HIT_RESULT) return SPELL_MISS_NONE; SpellSchoolMask schoolMask = spellInfo->GetSchoolMask(); @@ -2407,16 +2409,11 @@ SpellMissInfo Unit::MagicSpellHitResult(Unit* victim, SpellInfo const* spellInfo if (rand < tmp) return SPELL_MISS_MISS; - // Spells with SPELL_ATTR3_IGNORE_HIT_RESULT will additionally fully ignore - // resist and deflect chances - if (spellInfo->AttributesEx3 & SPELL_ATTR3_IGNORE_HIT_RESULT) - return SPELL_MISS_NONE; - // Chance resist mechanic (select max value from every mechanic spell effect) int32 resist_chance = victim->GetMechanicResistChance(spellInfo) * 100; tmp += resist_chance; - // Roll chance + // Roll chance if (rand < tmp) return SPELL_MISS_RESIST; @@ -5157,18 +5154,19 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere // cast 45429 Arcane Bolt if Exalted by Scryers case 45481: { - if (GetTypeId() != TYPEID_PLAYER) + Player* player = ToPlayer(); + if (!player) return false; // Get Aldor reputation rank - if (ToPlayer()->GetReputationRank(932) == REP_EXALTED) + if (player->GetReputationRank(932) == REP_EXALTED) { target = this; triggered_spell_id = 45479; break; } // Get Scryers reputation rank - if (ToPlayer()->GetReputationRank(934) == REP_EXALTED) + if (player->GetReputationRank(934) == REP_EXALTED) { // triggered at positive/self casts also, current attack target used then if (target && IsFriendlyTo(target)) @@ -5176,8 +5174,7 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere target = GetVictim(); if (!target) { - uint64 selected_guid = ToPlayer()->GetSelection(); - target = ObjectAccessor::GetUnit(*this, selected_guid); + target = player->GetSelectedUnit(); if (!target) return false; } @@ -8116,6 +8113,9 @@ int32 Unit::DealHeal(Unit* victim, uint32 addhealth) if (addhealth) gain = victim->ModifyHealth(int32(addhealth)); + // Hook for OnHeal Event + sScriptMgr->OnHeal(this, victim, gain); + Unit* unit = this; if (GetTypeId() == TYPEID_UNIT && ToCreature()->IsTotem()) @@ -14141,7 +14141,7 @@ void Unit::RemoveCharmedBy(Unit* charmer) if (GetCharmInfo()) GetCharmInfo()->SetPetNumber(0, true); else - TC_LOG_ERROR(LOG_FILTER_UNITS, "Aura::HandleModCharm: target="UI64FMTD" with typeid=%d has a charm aura but no charm info!", GetGUID(), GetTypeId()); + TC_LOG_ERROR(LOG_FILTER_UNITS, "Aura::HandleModCharm: target=" UI64FMTD " with typeid=%d has a charm aura but no charm info!", GetGUID(), GetTypeId()); } } break; @@ -15304,7 +15304,7 @@ void Unit::_ExitVehicle(Position const* exitPosition) if (vehicle->GetBase()->HasUnitTypeMask(UNIT_MASK_MINION) && vehicle->GetBase()->GetTypeId() == TYPEID_UNIT) if (((Minion*)vehicle->GetBase())->GetOwner() == this) - vehicle->GetBase()->ToCreature()->DespawnOrUnsummon(); + vehicle->GetBase()->ToCreature()->DespawnOrUnsummon(1); if (HasUnitTypeMask(UNIT_MASK_ACCESSORY)) { @@ -15812,8 +15812,8 @@ void Unit::StopAttackFaction(uint32 faction_id) void Unit::OutDebugInfo() const { TC_LOG_ERROR(LOG_FILTER_UNITS, "Unit::OutDebugInfo"); - TC_LOG_INFO(LOG_FILTER_UNITS, "GUID "UI64FMTD", entry %u, type %u, name %s", GetGUID(), GetEntry(), (uint32)GetTypeId(), GetName().c_str()); - TC_LOG_INFO(LOG_FILTER_UNITS, "OwnerGUID "UI64FMTD", MinionGUID "UI64FMTD", CharmerGUID "UI64FMTD", CharmedGUID "UI64FMTD, GetOwnerGUID(), GetMinionGUID(), GetCharmerGUID(), GetCharmGUID()); + TC_LOG_INFO(LOG_FILTER_UNITS, "GUID " UI64FMTD ", entry %u, type %u, name %s", GetGUID(), GetEntry(), (uint32)GetTypeId(), GetName().c_str()); + TC_LOG_INFO(LOG_FILTER_UNITS, "OwnerGUID " UI64FMTD ", MinionGUID " UI64FMTD ", CharmerGUID " UI64FMTD ", CharmedGUID "UI64FMTD, GetOwnerGUID(), GetMinionGUID(), GetCharmerGUID(), GetCharmGUID()); TC_LOG_INFO(LOG_FILTER_UNITS, "In world %u, unit type mask %u", (uint32)(IsInWorld() ? 1 : 0), m_unitTypeMask); if (IsInWorld()) TC_LOG_INFO(LOG_FILTER_UNITS, "Mapid %u", GetMapId()); @@ -16197,42 +16197,6 @@ bool Unit::IsSplineEnabled() const return movespline->Initialized() && !movespline->Finalized(); } -void Unit::SetTarget(uint64 guid) -{ - if (!_focusSpell) - SetUInt64Value(UNIT_FIELD_TARGET, guid); -} - -void Unit::FocusTarget(Spell const* focusSpell, WorldObject const* target) -{ - // already focused - if (_focusSpell) - return; - - _focusSpell = focusSpell; - SetUInt64Value(UNIT_FIELD_TARGET, target->GetGUID()); - if (focusSpell->GetSpellInfo()->AttributesEx5 & SPELL_ATTR5_DONT_TURN_DURING_CAST) - AddUnitState(UNIT_STATE_ROTATING); - - // Set serverside orientation if needed (needs to be after attribute check) - SetInFront(target); -} - -void Unit::ReleaseFocus(Spell const* focusSpell) -{ - // focused to something else - if (focusSpell != _focusSpell) - return; - - _focusSpell = NULL; - if (Unit* victim = GetVictim()) - SetUInt64Value(UNIT_FIELD_TARGET, victim->GetGUID()); - else - SetUInt64Value(UNIT_FIELD_TARGET, 0); - - if (focusSpell->GetSpellInfo()->AttributesEx5 & SPELL_ATTR5_DONT_TURN_DURING_CAST) - ClearUnitState(UNIT_STATE_ROTATING); -} void Unit::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target) const { diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 8dc4b49eec3..7cb6ebbee44 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -2134,11 +2134,8 @@ class Unit : public WorldObject TempSummon* ToTempSummon() { if (IsSummon()) return reinterpret_cast<TempSummon*>(this); else return NULL; } TempSummon const* ToTempSummon() const { if (IsSummon()) return reinterpret_cast<TempSummon const*>(this); else return NULL; } - void SetTarget(uint64 guid); - - // Handling caster facing during spellcast - void FocusTarget(Spell const* focusSpell, WorldObject const* target); - void ReleaseFocus(Spell const* focusSpell); + uint64 GetTarget() const { return GetUInt64Value(UNIT_FIELD_TARGET); } + virtual void SetTarget(uint64 /*guid*/) = 0; // Movement info Movement::MoveSpline * movespline; @@ -2267,7 +2264,6 @@ class Unit : public WorldObject bool m_cleanupDone; // lock made to not add stuff after cleanup before delete bool m_duringRemoveFromWorld; // lock made to not add stuff after begining removing from world - Spell const* _focusSpell; ///> Locks the target during spell cast for proper facing bool _isWalkingBeforeCharm; // Are we walking before we were charmed? time_t _lastDamagedTime; // Part of Evade mechanics diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h index 813499e91d7..e6b1bf28608 100644 --- a/src/server/game/Grids/Notifiers/GridNotifiers.h +++ b/src/server/game/Grids/Notifiers/GridNotifiers.h @@ -885,10 +885,10 @@ namespace Trinity class AnyFriendlyUnitInObjectRangeCheck { public: - AnyFriendlyUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range) : i_obj(obj), i_funit(funit), i_range(range) {} + AnyFriendlyUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range, bool playerOnly = false) : i_obj(obj), i_funit(funit), i_range(range), i_playerOnly(playerOnly) {} bool operator()(Unit* u) { - if (u->IsAlive() && i_obj->IsWithinDistInMap(u, i_range) && i_funit->IsFriendlyTo(u)) + if (u->IsAlive() && i_obj->IsWithinDistInMap(u, i_range) && i_funit->IsFriendlyTo(u) && (!i_playerOnly || u->GetTypeId() == TYPEID_PLAYER)) return true; else return false; @@ -897,6 +897,7 @@ namespace Trinity WorldObject const* i_obj; Unit const* i_funit; float i_range; + bool i_playerOnly; }; class AnyGroupedUnitInObjectRangeCheck @@ -1049,7 +1050,7 @@ namespace Trinity class NearestHostileUnitCheck { public: - explicit NearestHostileUnitCheck(Creature const* creature, float dist = 0) : me(creature) + explicit NearestHostileUnitCheck(Creature const* creature, float dist = 0, bool playerOnly = false) : me(creature), i_playerOnly(playerOnly) { m_range = (dist == 0 ? 9999 : dist); } @@ -1061,6 +1062,9 @@ namespace Trinity if (!me->IsValidAttackTarget(u)) return false; + if (i_playerOnly && u->GetTypeId() != TYPEID_PLAYER) + return false; + m_range = me->GetDistance(u); // use found unit range as new range limit for next check return true; } @@ -1068,6 +1072,7 @@ namespace Trinity private: Creature const* me; float m_range; + bool i_playerOnly; NearestHostileUnitCheck(NearestHostileUnitCheck const&); }; diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp index 80d5175123d..97a96d2ecaa 100644 --- a/src/server/game/Guilds/Guild.cpp +++ b/src/server/game/Guilds/Guild.cpp @@ -1019,7 +1019,7 @@ void Guild::BankMoveItemData::LogBankEvent(SQLTransaction& trans, MoveItemData* void Guild::BankMoveItemData::LogAction(MoveItemData* pFrom) const { MoveItemData::LogAction(pFrom); - if (!pFrom->IsBank() && m_pPlayer->GetSession()->HasPermission(RBAC_PERM_LOG_GM_TRADE)) /// @todo Move this to scripts + if (!pFrom->IsBank() && m_pPlayer->GetSession()->HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE)) /// @todo Move this to scripts { sLog->outCommand(m_pPlayer->GetSession()->GetAccountId(), "GM %s (Guid: %u) (Account: %u) deposit item: %s (Entry: %d Count: %u) to guild bank named: %s (Guild ID: %u)", @@ -2062,7 +2062,7 @@ void Guild::HandleMemberDepositMoney(WorldSession* session, uint64 amount, bool std::string aux = ByteArrayToHexStr(reinterpret_cast<uint8*>(&amount), 8, true); _BroadcastEvent(GE_BANK_MONEY_CHANGED, 0, aux.c_str()); - if (player->GetSession()->HasPermission(RBAC_PERM_LOG_GM_TRADE)) + if (player->GetSession()->HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE)) { sLog->outCommand(player->GetSession()->GetAccountId(), "GM %s (Account: %u) deposit money (Amount: " UI64FMTD ") to guild bank (Guild ID %u)", diff --git a/src/server/game/Handlers/AuctionHouseHandler.cpp b/src/server/game/Handlers/AuctionHouseHandler.cpp index 4ebe9a2b90d..7e0ee4fd080 100644 --- a/src/server/game/Handlers/AuctionHouseHandler.cpp +++ b/src/server/game/Handlers/AuctionHouseHandler.cpp @@ -273,7 +273,7 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData) // Required stack size of auction matches to current item stack size, just move item to auctionhouse if (itemsCount == 1 && item->GetCount() == count[0]) { - if (HasPermission(RBAC_PERM_LOG_GM_TRADE)) + if (HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE)) { sLog->outCommand(GetAccountId(), "GM %s (Account: %u) create auction: %s (Entry: %u Count: %u)", GetPlayerName().c_str(), GetAccountId(), item->GetTemplate()->Name1.c_str(), item->GetEntry(), item->GetCount()); @@ -323,7 +323,7 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData) return; } - if (HasPermission(RBAC_PERM_LOG_GM_TRADE)) + if (HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE)) { sLog->outCommand(GetAccountId(), "GM %s (Account: %u) create auction: %s (Entry: %u Count: %u)", GetPlayerName().c_str(), GetAccountId(), newItem->GetTemplate()->Name1.c_str(), newItem->GetEntry(), newItem->GetCount()); diff --git a/src/server/game/Handlers/CalendarHandler.cpp b/src/server/game/Handlers/CalendarHandler.cpp index 3c28a32af93..72a0df34fe7 100644 --- a/src/server/game/Handlers/CalendarHandler.cpp +++ b/src/server/game/Handlers/CalendarHandler.cpp @@ -489,7 +489,7 @@ void WorldSession::HandleCalendarEventRsvp(WorldPacket& recvData) uint32 status; recvData >> eventId >> inviteId >> status; - TC_LOG_DEBUG(LOG_FILTER_NETWORKIO, "CMSG_CALENDAR_EVENT_RSVP [" UI64FMTD"] EventId [" + TC_LOG_DEBUG(LOG_FILTER_NETWORKIO, "CMSG_CALENDAR_EVENT_RSVP [" UI64FMTD "] EventId [" UI64FMTD "], InviteId [" UI64FMTD "], status %u", guid, eventId, inviteId, status); diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index 81bf31dcf3a..126be2978c1 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -304,7 +304,7 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData) WorldPacket data(SMSG_CHAR_CREATE, 1); // returned with diff.values in all cases - if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_TEAMMASK)) + if (!HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_TEAMMASK)) { if (uint32 mask = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_DISABLED)) { @@ -366,7 +366,7 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData) return; } - if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RACEMASK)) + if (!HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RACEMASK)) { uint32 raceMaskDisabled = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_DISABLED_RACEMASK); if ((1 << (race_ - 1)) & raceMaskDisabled) @@ -377,7 +377,7 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData) } } - if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_CLASSMASK)) + if (!HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_CLASSMASK)) { uint32 classMaskDisabled = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_DISABLED_CLASSMASK); if ((1 << (class_ - 1)) & classMaskDisabled) @@ -406,14 +406,14 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData) return; } - if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME) && sObjectMgr->IsReservedName(name)) + if (!HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME) && sObjectMgr->IsReservedName(name)) { data << uint8(CHAR_NAME_RESERVED); SendPacket(&data); return; } - if (class_ == CLASS_DEATH_KNIGHT && !HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_HEROIC_CHARACTER)) + if (class_ == CLASS_DEATH_KNIGHT && !HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_HEROIC_CHARACTER)) { // speedup check for heroic class disabled case uint32 heroic_free_slots = sWorld->getIntConfig(CONFIG_HEROIC_CHARACTERS_PER_REALM); @@ -522,7 +522,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte } } - bool allowTwoSideAccounts = !sWorld->IsPvPRealm() || HasPermission(RBAC_PERM_TWO_SIDE_CHARACTER_CREATION); + bool allowTwoSideAccounts = !sWorld->IsPvPRealm() || HasPermission(rbac::RBAC_PERM_TWO_SIDE_CHARACTER_CREATION); uint32 skipCinematics = sWorld->getIntConfig(CONFIG_SKIP_CINEMATICS); _charCreateCallback.FreeResult(); @@ -546,9 +546,9 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte bool haveSameRace = false; uint32 heroicReqLevel = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_MIN_LEVEL_FOR_HEROIC_CHARACTER); bool hasHeroicReqLevel = (heroicReqLevel == 0); - bool allowTwoSideAccounts = !sWorld->IsPvPRealm() || HasPermission(RBAC_PERM_TWO_SIDE_CHARACTER_CREATION); + bool allowTwoSideAccounts = !sWorld->IsPvPRealm() || HasPermission(rbac::RBAC_PERM_TWO_SIDE_CHARACTER_CREATION); uint32 skipCinematics = sWorld->getIntConfig(CONFIG_SKIP_CINEMATICS); - bool checkHeroicReqs = createInfo->Class == CLASS_DEATH_KNIGHT && !HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_HEROIC_CHARACTER); + bool checkHeroicReqs = createInfo->Class == CLASS_DEATH_KNIGHT && !HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_HEROIC_CHARACTER); if (result) { @@ -1254,7 +1254,7 @@ void WorldSession::HandleCharRenameOpcode(WorldPacket& recvData) } // check name limitations - if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME) && sObjectMgr->IsReservedName(newName)) + if (!HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME) && sObjectMgr->IsReservedName(newName)) { WorldPacket data(SMSG_CHAR_RENAME, 1); data << uint8(CHAR_NAME_RESERVED); @@ -1572,7 +1572,7 @@ void WorldSession::HandleCharCustomize(WorldPacket& recvData) } // check name limitations - if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME) && sObjectMgr->IsReservedName(newName)) + if (!HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME) && sObjectMgr->IsReservedName(newName)) { WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1); data << uint8(CHAR_NAME_RESERVED); @@ -1820,7 +1820,7 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData) return; } - if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RACEMASK)) + if (!HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RACEMASK)) { uint32 raceMaskDisabled = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_DISABLED_RACEMASK); if ((1 << (race - 1)) & raceMaskDisabled) @@ -1851,7 +1851,7 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData) } // check name limitations - if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME) && sObjectMgr->IsReservedName(newname)) + if (!HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME) && sObjectMgr->IsReservedName(newname)) { WorldPacket data(SMSG_CHAR_FACTION_CHANGE, 1); data << uint8(CHAR_NAME_RESERVED); @@ -2035,7 +2035,7 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData) guild->DeleteMember(MAKE_NEW_GUID(lowGuid, 0, HIGHGUID_PLAYER), false, false, true); } - if (!HasPermission(RBAC_PERM_TWO_SIDE_ADD_FRIEND)) + if (!HasPermission(rbac::RBAC_PERM_TWO_SIDE_ADD_FRIEND)) { // Delete Friend List stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_SOCIAL_BY_GUID); diff --git a/src/server/game/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp index 1c5741cbad8..d145c3359e2 100644 --- a/src/server/game/Handlers/ChatHandler.cpp +++ b/src/server/game/Handlers/ChatHandler.cpp @@ -179,7 +179,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) else { // send in universal language in two side iteration allowed mode - if (HasPermission(RBAC_PERM_TWO_SIDE_INTERACTION_CHAT)) + if (HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHAT)) lang = LANG_UNIVERSAL; else { @@ -321,7 +321,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) } Player* receiver = sObjectAccessor->FindPlayerByName(to); - if (!receiver || (!receiver->isAcceptWhispers() && receiver->GetSession()->HasPermission(RBAC_PERM_CAN_FILTER_WHISPERS) && !receiver->IsInWhisperWhiteList(sender->GetGUID()))) + if (!receiver || (!receiver->isAcceptWhispers() && receiver->GetSession()->HasPermission(rbac::RBAC_PERM_CAN_FILTER_WHISPERS) && !receiver->IsInWhisperWhiteList(sender->GetGUID()))) { SendPlayerNotFoundNotice(to); return; @@ -332,7 +332,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) return; } - if (GetPlayer()->GetTeam() != receiver->GetTeam() && !HasPermission(RBAC_PERM_TWO_SIDE_INTERACTION_CHAT) && !receiver->IsInWhisperWhiteList(sender->GetGUID())) + if (GetPlayer()->GetTeam() != receiver->GetTeam() && !HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHAT) && !receiver->IsInWhisperWhiteList(sender->GetGUID())) { SendWrongFactionNotice(); return; @@ -347,7 +347,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) // If player is a Gamemaster and doesn't accept whisper, we auto-whitelist every player that the Gamemaster is talking to // We also do that if a player is under the required level for whispers. if (receiver->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_WHISPER_LEVEL_REQ) || - (HasPermission(RBAC_PERM_CAN_FILTER_WHISPERS) && !sender->isAcceptWhispers() && !sender->IsInWhisperWhiteList(receiver->GetGUID()))) + (HasPermission(rbac::RBAC_PERM_CAN_FILTER_WHISPERS) && !sender->isAcceptWhispers() && !sender->IsInWhisperWhiteList(receiver->GetGUID()))) sender->AddWhisperWhiteList(receiver->GetGUID()); GetPlayer()->Whisper(msg, lang, receiver->GetGUID()); @@ -450,7 +450,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) } break; case CHAT_MSG_CHANNEL: { - if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHAT_CHANNEL_REQ)) + if (!HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHAT_CHANNEL_REQ)) { if (_player->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_CHANNEL_LEVEL_REQ)) { diff --git a/src/server/game/Handlers/MailHandler.cpp b/src/server/game/Handlers/MailHandler.cpp index d493e793edc..4542b264ab1 100644 --- a/src/server/game/Handlers/MailHandler.cpp +++ b/src/server/game/Handlers/MailHandler.cpp @@ -223,7 +223,7 @@ void WorldSession::HandleSendMail(WorldPacket& recvData) } } - if (!accountBound && player->GetTeam() != receiverTeam && !HasPermission(RBAC_PERM_TWO_SIDE_INTERACTION_MAIL)) + if (!accountBound && player->GetTeam() != receiverTeam && !HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_MAIL)) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_NOT_YOUR_TEAM); return; @@ -300,7 +300,7 @@ void WorldSession::HandleSendMail(WorldPacket& recvData) if (items_count > 0 || money > 0) { - bool log = HasPermission(RBAC_PERM_LOG_GM_TRADE); + bool log = HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE); if (items_count > 0) { for (uint8 i = 0; i < items_count; ++i) @@ -507,7 +507,7 @@ void WorldSession::HandleMailTakeItem(WorldPacket& recvData) uint32 sender_accId = 0; - if (HasPermission(RBAC_PERM_LOG_GM_TRADE)) + if (HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE)) { std::string sender_name; if (receiver) diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index dc3679e021f..54448766885 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -256,11 +256,11 @@ void WorldSession::HandleWhoOpcode(WorldPacket& recvData) { Player* target = itr->second; // player can see member of other team only if CONFIG_ALLOW_TWO_SIDE_WHO_LIST - if (target->GetTeam() != team && !HasPermission(RBAC_PERM_TWO_SIDE_WHO_LIST)) + if (target->GetTeam() != team && !HasPermission(rbac::RBAC_PERM_TWO_SIDE_WHO_LIST)) continue; // player can see MODERATOR, GAME MASTER, ADMINISTRATOR only if CONFIG_GM_IN_WHO_LIST - if (!HasPermission(RBAC_PERM_WHO_SEE_ALL_SEC_LEVELS) && target->GetSession()->GetSecurity() > AccountTypes(gmLevelInWhoList)) + if (!HasPermission(rbac::RBAC_PERM_WHO_SEE_ALL_SEC_LEVELS) && target->GetSession()->GetSecurity() > AccountTypes(gmLevelInWhoList)) continue; // do not process players which are not in world @@ -374,7 +374,7 @@ void WorldSession::HandleLogoutRequestOpcode(WorldPacket& /*recvData*/) DoLootRelease(lguid); bool instantLogout = (GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING) && !GetPlayer()->IsInCombat()) || - GetPlayer()->IsInFlight() || HasPermission(RBAC_PERM_INSTANT_LOGOUT); + GetPlayer()->IsInFlight() || HasPermission(rbac::RBAC_PERM_INSTANT_LOGOUT); /// TODO: Possibly add RBAC permission to log out in combat bool canLogoutInCombat = GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING); @@ -572,13 +572,13 @@ void WorldSession::HandleAddFriendOpcodeCallBack(PreparedQueryResult result, std team = Player::TeamForRace(fields[1].GetUInt8()); friendAccountId = fields[2].GetUInt32(); - if (HasPermission(RBAC_PERM_ALLOW_GM_FRIEND) || AccountMgr::IsPlayerAccount(AccountMgr::GetSecurity(friendAccountId, realmID))) + if (HasPermission(rbac::RBAC_PERM_ALLOW_GM_FRIEND) || AccountMgr::IsPlayerAccount(AccountMgr::GetSecurity(friendAccountId, realmID))) { if (friendGuid) { if (friendGuid == GetPlayer()->GetGUID()) friendResult = FRIEND_SELF; - else if (GetPlayer()->GetTeam() != team && !HasPermission(RBAC_PERM_TWO_SIDE_ADD_FRIEND)) + else if (GetPlayer()->GetTeam() != team && !HasPermission(rbac::RBAC_PERM_TWO_SIDE_ADD_FRIEND)) friendResult = FRIEND_ENEMY; else if (GetPlayer()->GetSocial()->HasFriend(GUID_LOPART(friendGuid))) friendResult = FRIEND_ALREADY; @@ -1196,8 +1196,6 @@ void WorldSession::HandleInspectOpcode(WorldPacket& recvData) TC_LOG_DEBUG(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_INSPECT"); - _player->SetSelection(guid); - Player* player = ObjectAccessor::FindPlayer(guid); if (!player) { @@ -1310,7 +1308,7 @@ void WorldSession::HandleWorldTeleportOpcode(WorldPacket& recvData) TC_LOG_DEBUG(LOG_FILTER_NETWORKIO, "CMSG_WORLD_TELEPORT: Player = %s, Time = %u, map = %u, x = %f, y = %f, z = %f, o = %f", GetPlayer()->GetName().c_str(), time, mapid, PositionX, PositionY, PositionZ, Orientation); - if (HasPermission(RBAC_PERM_OPCODE_WORLD_TELEPORT)) + if (HasPermission(rbac::RBAC_PERM_OPCODE_WORLD_TELEPORT)) GetPlayer()->TeleportTo(mapid, PositionX, PositionY, PositionZ, Orientation); else SendNotification(LANG_YOU_NOT_HAVE_PERMISSION); @@ -1322,7 +1320,7 @@ void WorldSession::HandleWhoisOpcode(WorldPacket& recvData) std::string charname; recvData >> charname; - if (!HasPermission(RBAC_PERM_OPCODE_WHOIS)) + if (!HasPermission(rbac::RBAC_PERM_OPCODE_WHOIS)) { SendNotification(LANG_YOU_NOT_HAVE_PERMISSION); return; diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp index cad1ef77daa..540107148fa 100644 --- a/src/server/game/Handlers/MovementHandler.cpp +++ b/src/server/game/Handlers/MovementHandler.cpp @@ -32,7 +32,9 @@ #include "ObjectMgr.h" #include "MovementStructures.h" -void WorldSession::HandleMoveWorldportAckOpcode(WorldPacket& /*recvPacket*/) +#define MOVEMENT_PACKET_TIME_DELAY 0 + +void WorldSession::HandleMoveWorldportAckOpcode(WorldPacket & /*recvData*/) { TC_LOG_DEBUG(LOG_FILTER_NETWORKIO, "WORLD: got MSG_MOVE_WORLDPORT_ACK."); HandleMoveWorldportAckOpcode(); @@ -372,7 +374,14 @@ void WorldSession::HandleMovementOpcodes(WorldPacket& recvPacket) plrMover->SetInWater(!plrMover->IsInWater() || plrMover->GetBaseMap()->IsUnderWater(movementInfo.pos.GetPositionX(), movementInfo.pos.GetPositionY(), movementInfo.pos.GetPositionZ())); } - movementInfo.time = getMSTime(); + uint32 mstime = getMSTime(); + /*----------------------*/ + if(m_clientTimeDelay == 0) + m_clientTimeDelay = mstime - movementInfo.time; + + /* process position-change */ + movementInfo.time = movementInfo.time + m_clientTimeDelay + MOVEMENT_PACKET_TIME_DELAY; + movementInfo.guid = mover->GetGUID(); mover->m_movementInfo = movementInfo; diff --git a/src/server/game/Handlers/QueryHandler.cpp b/src/server/game/Handlers/QueryHandler.cpp index 9ade8032edb..08c7d8bac3e 100644 --- a/src/server/game/Handlers/QueryHandler.cpp +++ b/src/server/game/Handlers/QueryHandler.cpp @@ -273,7 +273,6 @@ void WorldSession::HandleNpcTextQueryOpcode(WorldPacket& recvData) TC_LOG_DEBUG(LOG_FILTER_NETWORKIO, "WORLD: CMSG_NPC_TEXT_QUERY ID '%u'", textID); recvData >> guid; - GetPlayer()->SetSelection(guid); GossipText const* pGossip = sObjectMgr->GetGossipText(textID); diff --git a/src/server/game/Handlers/TradeHandler.cpp b/src/server/game/Handlers/TradeHandler.cpp index b9baf69d615..f04e23dcf92 100644 --- a/src/server/game/Handlers/TradeHandler.cpp +++ b/src/server/game/Handlers/TradeHandler.cpp @@ -213,7 +213,7 @@ void WorldSession::moveItems(Item* myItems[], Item* hisItems[]) { // logging TC_LOG_DEBUG(LOG_FILTER_NETWORKIO, "partner storing: %u", myItems[i]->GetGUIDLow()); - if (HasPermission(RBAC_PERM_LOG_GM_TRADE)) + if (HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE)) { sLog->outCommand(_player->GetSession()->GetAccountId(), "GM %s (Account: %u) trade: %s (Entry: %d Count: %u) to player: %s (Account: %u)", _player->GetName().c_str(), _player->GetSession()->GetAccountId(), @@ -231,7 +231,7 @@ void WorldSession::moveItems(Item* myItems[], Item* hisItems[]) { // logging TC_LOG_DEBUG(LOG_FILTER_NETWORKIO, "player storing: %u", hisItems[i]->GetGUIDLow()); - if (HasPermission(RBAC_PERM_LOG_GM_TRADE)) + if (HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE)) { sLog->outCommand(trader->GetSession()->GetAccountId(), "GM %s (Account: %u) trade: %s (Entry: %d Count: %u) to player: %s (Account: %u)", trader->GetName().c_str(), trader->GetSession()->GetAccountId(), @@ -534,7 +534,7 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/) moveItems(myItems, hisItems); // logging money - if (HasPermission(RBAC_PERM_LOG_GM_TRADE)) + if (HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE)) { if (my_trade->GetMoney() > 0) { diff --git a/src/server/game/Handlers/VehicleHandler.cpp b/src/server/game/Handlers/VehicleHandler.cpp index 7a5d5ef8f48..36ea31d170b 100644 --- a/src/server/game/Handlers/VehicleHandler.cpp +++ b/src/server/game/Handlers/VehicleHandler.cpp @@ -218,7 +218,7 @@ void WorldSession::HandleEjectPassenger(WorldPacket& data) TC_LOG_ERROR(LOG_FILTER_NETWORKIO, "Player %u attempted to eject creature GUID %u from non-ejectable seat.", GetPlayer()->GetGUIDLow(), GUID_LOPART(guid)); } else - TC_LOG_ERROR(LOG_FILTER_NETWORKIO, "HandleEjectPassenger: Player %u tried to eject invalid GUID "UI64FMTD, GetPlayer()->GetGUIDLow(), guid); + TC_LOG_ERROR(LOG_FILTER_NETWORKIO, "HandleEjectPassenger: Player %u tried to eject invalid GUID " UI64FMTD, GetPlayer()->GetGUIDLow(), guid); } void WorldSession::HandleRequestVehicleExit(WorldPacket& /*recvData*/) diff --git a/src/server/game/Instances/InstanceSaveMgr.cpp b/src/server/game/Instances/InstanceSaveMgr.cpp index 6370eda6568..d7ffb70ccfa 100644 --- a/src/server/game/Instances/InstanceSaveMgr.cpp +++ b/src/server/game/Instances/InstanceSaveMgr.cpp @@ -336,7 +336,7 @@ void InstanceSaveManager::LoadResetTimes() InstResetTimeMapDiffType::iterator itr = instResetTime.find(instance); if (itr != instResetTime.end() && itr->second.second != resettime) { - CharacterDatabase.DirectPExecute("UPDATE instance SET resettime = '"UI64FMTD"' WHERE id = '%u'", uint64(resettime), instance); + CharacterDatabase.DirectPExecute("UPDATE instance SET resettime = '" UI64FMTD "' WHERE id = '%u'", uint64(resettime), instance); itr->second.second = resettime; } } @@ -408,7 +408,7 @@ void InstanceSaveManager::LoadResetTimes() // calculate the next reset time t = (t / DAY) * DAY; t += ((today - t) / period + 1) * period + diff; - CharacterDatabase.DirectPExecute("UPDATE instance_reset SET resettime = '"UI64FMTD"' WHERE mapid = '%u' AND difficulty= '%u'", (uint64)t, mapid, difficulty); + CharacterDatabase.DirectPExecute("UPDATE instance_reset SET resettime = '" UI64FMTD "' WHERE mapid = '%u' AND difficulty= '%u'", (uint64)t, mapid, difficulty); } SetResetTimeFor(mapid, difficulty, t); diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 1fd762e7446..4f4f4104b83 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -360,7 +360,7 @@ void Map::EnsureGridLoadedForActiveObject(const Cell &cell, WorldObject* object) // refresh grid state & timer if (grid->GetGridState() != GRID_STATE_ACTIVE) { - TC_LOG_DEBUG(LOG_FILTER_MAPS, "Active object "UI64FMTD" triggers loading of grid [%u, %u] on map %u", object->GetGUID(), cell.GridX(), cell.GridY(), GetId()); + TC_LOG_DEBUG(LOG_FILTER_MAPS, "Active object " UI64FMTD " triggers loading of grid [%u, %u] on map %u", object->GetGUID(), cell.GridX(), cell.GridY(), GetId()); ResetGridExpiry(*grid, 0.1f); grid->SetGridState(GRID_STATE_ACTIVE); } diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h index c30795de475..05b3bab30a1 100644 --- a/src/server/game/Miscellaneous/Language.h +++ b/src/server/game/Miscellaneous/Language.h @@ -88,37 +88,24 @@ enum TrinityStrings LANG_IMPROPER_VALUE = 62, LANG_RBAC_WRONG_PARAMETER_ID = 63, LANG_RBAC_WRONG_PARAMETER_REALM = 64, - LANG_RBAC_GROUP_IN_LIST = 65, - LANG_RBAC_GROUP_NOT_IN_LIST = 66, - LANG_RBAC_GROUP_ADDED = 67, - LANG_RBAC_GROUP_REMOVED = 68, - LANG_RBAC_GROUP_LIST_HEADER = 69, + LANG_RBAC_LIST_HEADER_GRANTED = 65, + LANG_RBAC_LIST_HEADER_DENIED = 66, + LANG_RBAC_LIST_HEADER_BY_SEC_LEVEL = 67, + LANG_RBAC_LIST_PERMISSIONS_HEADER = 68, + LANG_RBAC_LIST_PERMS_LINKED_HEADER = 69, LANG_RBAC_LIST_EMPTY = 70, LANG_RBAC_LIST_ELEMENT = 71, - LANG_RBAC_ROLE_GRANTED_IN_LIST = 72, - LANG_RBAC_ROLE_GRANTED_IN_DENIED_LIST = 73, - LANG_RBAC_ROLE_GRANTED = 74, - LANG_RBAC_ROLE_DENIED_IN_LIST = 75, - LANG_RBAC_ROLE_DENIED_IN_GRANTED_LIST = 76, - LANG_RBAC_ROLE_DENIED = 77, - LANG_RBAC_ROLE_REVOKED = 78, - LANG_RBAC_ROLE_REVOKED_NOT_IN_LIST = 79, - LANG_RBAC_ROLE_LIST_HEADER_GRANTED = 80, - LANG_RBAC_ROLE_LIST_HEADER_DENIED = 81, - LANG_RBAC_PERM_GRANTED_IN_LIST = 82, - LANG_RBAC_PERM_GRANTED_IN_DENIED_LIST = 83, - LANG_RBAC_PERM_GRANTED = 84, - LANG_RBAC_PERM_DENIED_IN_LIST = 85, - LANG_RBAC_PERM_DENIED_IN_GRANTED_LIST = 86, - LANG_RBAC_PERM_DENIED = 87, - LANG_RBAC_PERM_REVOKED = 88, - LANG_RBAC_PERM_REVOKED_NOT_IN_LIST = 89, - LANG_RBAC_PERM_LIST_HEADER_GRANTED = 90, - LANG_RBAC_PERM_LIST_HEADER_DENIED = 91, - LANG_RBAC_PERM_LIST_GLOBAL = 92, - LANG_RBAC_LIST_GROUPS_HEADER = 93, - LANG_RBAC_LIST_ROLES_HEADER = 94, - LANG_RBAC_LIST_PERMISSIONS_HEADER = 95, + LANG_RBAC_PERM_GRANTED_IN_LIST = 72, + LANG_RBAC_PERM_GRANTED_IN_DENIED_LIST = 73, + LANG_RBAC_PERM_GRANTED = 74, + LANG_RBAC_PERM_DENIED_IN_LIST = 75, + LANG_RBAC_PERM_DENIED_IN_GRANTED_LIST = 76, + LANG_RBAC_PERM_DENIED = 77, + LANG_RBAC_PERM_REVOKED = 78, + LANG_RBAC_PERM_REVOKED_NOT_IN_LIST = 79, + // Free 80 - 95 + + LANG_GUILD_RENAME_ALREADY_EXISTS = 96, LANG_GUILD_RENAME_DONE = 97, LANG_RENAME_PLAYER_ALREADY_EXISTS = 98, diff --git a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp index 31da239670b..d71815e90a5 100755 --- a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp @@ -78,7 +78,7 @@ void WaypointMovementGenerator<Creature>::OnArrived(Creature* creature) if (i_path->at(i_currentNode)->event_id && urand(0, 99) < i_path->at(i_currentNode)->event_chance) { - TC_LOG_DEBUG(LOG_FILTER_MAPSCRIPTS, "Creature movement start script %u at point %u for "UI64FMTD".", i_path->at(i_currentNode)->event_id, i_currentNode, creature->GetGUID()); + TC_LOG_DEBUG(LOG_FILTER_MAPSCRIPTS, "Creature movement start script %u at point %u for " UI64FMTD ".", i_path->at(i_currentNode)->event_id, i_currentNode, creature->GetGUID()); creature->GetMap()->ScriptsStart(sWaypointScripts, i_path->at(i_currentNode)->event_id, creature, NULL); } diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp index 65ddb3a8d05..30725acd69c 100644 --- a/src/server/game/Scripting/ScriptMgr.cpp +++ b/src/server/game/Scripting/ScriptMgr.cpp @@ -1363,6 +1363,16 @@ void ScriptMgr::OnGroupDisband(Group* group) } // Unit +void ScriptMgr::OnHeal(Unit* healer, Unit* reciever, uint32 gain) +{ + FOREACH_SCRIPT(UnitScript)->OnHeal(healer, reciever, gain); +} + +void ScriptMgr::OnDamage(Unit* attacker, Unit* victim, uint32 damage) +{ + FOREACH_SCRIPT(UnitScript)->OnDamage(attacker, victim, damage); +} + void ScriptMgr::ModifyPeriodicDamageAurasTick(Unit* target, Unit* attacker, uint32& damage) { FOREACH_SCRIPT(UnitScript)->ModifyPeriodicDamageAurasTick(target, attacker, damage); diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h index 1b8a24daa63..f83fa5a6299 100644 --- a/src/server/game/Scripting/ScriptMgr.h +++ b/src/server/game/Scripting/ScriptMgr.h @@ -395,6 +395,12 @@ class UnitScript : public ScriptObject UnitScript(const char* name, bool addToScripts = true); public: + // Called when a unit deals damage to another unit + virtual void OnHeal(Unit* /*healer*/, Unit* /*reciever*/, uint32 /*gain*/) { } + + // Called when a unit deals damage to another unit + virtual void OnDamage(Unit* /*attacker*/, Unit* /*victim*/, uint32 /*damage*/) { } + // Called when DoT's Tick Damage is being Dealt virtual void ModifyPeriodicDamageAurasTick(Unit* /*target*/, Unit* /*attacker*/, uint32& /*damage*/) { } @@ -1053,6 +1059,8 @@ class ScriptMgr public: /* UnitScript */ + void OnHeal(Unit* healer, Unit* reciever, uint32 gain); + void OnDamage(Unit* attacker, Unit* victim, uint32 damage); void ModifyPeriodicDamageAurasTick(Unit* target, Unit* attacker, uint32& damage); void ModifyMeleeDamage(Unit* target, Unit* attacker, uint32& damage); void ModifySpellDamageTaken(Unit* target, Unit* attacker, int32& damage); diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 275349c83cb..839e7a2f91e 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -118,6 +118,7 @@ WorldSession::WorldSession(uint32 id, WorldSocket* sock, AccountTypes sec, uint8 m_sessionDbcLocale(sWorld->GetAvailableDbcLocale(locale)), m_sessionDbLocaleIndex(locale), m_latency(0), + m_clientTimeDelay(0), m_TutorialsChanged(false), _filterAddonMessages(false), recruiterId(recruiter), @@ -1128,15 +1129,16 @@ void WorldSession::LoadPermissions() uint32 id = GetAccountId(); std::string name; AccountMgr::GetName(id, name); + uint8 secLevel = GetSecurity(); - _RBACData = new RBACData(id, name, realmID); + _RBACData = new rbac::RBACData(id, name, realmID, secLevel); _RBACData->LoadFromDB(); - TC_LOG_DEBUG(LOG_FILTER_RBAC, "WorldSession::LoadPermissions [AccountId: %u, Name: %s, realmId: %d]", - id, name.c_str(), realmID); + TC_LOG_DEBUG(LOG_FILTER_RBAC, "WorldSession::LoadPermissions [AccountId: %u, Name: %s, realmId: %d, secLevel: %u]", + id, name.c_str(), realmID, secLevel); } -RBACData* WorldSession::GetRBACData() +rbac::RBACData* WorldSession::GetRBACData() { return _RBACData; } @@ -1155,7 +1157,7 @@ bool WorldSession::HasPermission(uint32 permission) void WorldSession::InvalidateRBACData() { - TC_LOG_DEBUG(LOG_FILTER_RBAC, "WorldSession::InvalidateRBACData [AccountId: %u, Name: %s, realmId: %d]", + TC_LOG_DEBUG(LOG_FILTER_RBAC, "WorldSession::Invalidaterbac::RBACData [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 871f1df4d05..7b6389698f4 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -41,7 +41,6 @@ class LoginQueryHolder; class Object; class Player; class Quest; -class RBACData; class SpellCastTargets; class Unit; class Warden; @@ -64,6 +63,11 @@ struct LfgRoleCheck; struct LfgUpdateData; } +namespace rbac +{ +class RBACData; +} + enum AccountDataType { GLOBAL_CONFIG_CACHE = 0, // 0x01 g @@ -223,7 +227,7 @@ class WorldSession void SendAuthResponse(uint8 code, bool queued, uint32 queuePos = 0); void SendClientCacheVersion(uint32 version); - RBACData* GetRBACData(); + rbac::RBACData* GetRBACData(); bool HasPermission(uint32 permissionId); void LoadPermissions(); void InvalidateRBACData(); // Used to force LoadPermissions at next HasPermission check @@ -358,6 +362,7 @@ class WorldSession uint32 GetLatency() const { return m_latency; } void SetLatency(uint32 latency) { m_latency = latency; } + void ResetClientTimeDelay() { m_clientTimeDelay = 0; } uint32 getDialogStatus(Player* player, Object* questgiver, uint32 defstatus); time_t m_timeOutTime; @@ -1042,6 +1047,7 @@ class WorldSession LocaleConstant m_sessionDbcLocale; LocaleConstant m_sessionDbLocaleIndex; uint32 m_latency; + uint32 m_clientTimeDelay; AccountData m_accountData[NUM_ACCOUNT_DATA_TYPES]; uint32 m_Tutorials[MAX_ACCOUNT_TUTORIAL_VALUES]; bool m_TutorialsChanged; @@ -1053,7 +1059,7 @@ class WorldSession ACE_Based::LockedQueue<WorldPacket*, ACE_Thread_Mutex> _recvQueue; time_t timeLastWhoCommand; z_stream_s* _compressionStream; - RBACData* _RBACData; + rbac::RBACData* _RBACData; }; #endif /// @} diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp index a1e084bc286..461b7f56dde 100644 --- a/src/server/game/Server/WorldSocket.cpp +++ b/src/server/game/Server/WorldSocket.cpp @@ -1052,7 +1052,7 @@ int WorldSocket::HandlePing (WorldPacket& recvPacket) { ACE_GUARD_RETURN (LockType, Guard, m_SessionLock, -1); - if (m_Session && !m_Session->HasPermission(RBAC_PERM_SKIP_CHECK_OVERSPEED_PING)) + if (m_Session && !m_Session->HasPermission(rbac::RBAC_PERM_SKIP_CHECK_OVERSPEED_PING)) { TC_LOG_ERROR(LOG_FILTER_NETWORKIO, "WorldSocket::HandlePing: %s kicked for over-speed pings (address: %s)", m_Session->GetPlayerInfo().c_str(), GetRemoteAddress().c_str()); @@ -1070,7 +1070,10 @@ int WorldSocket::HandlePing (WorldPacket& recvPacket) ACE_GUARD_RETURN (LockType, Guard, m_SessionLock, -1); if (m_Session) + { m_Session->SetLatency (latency); + m_Session->ResetClientTimeDelay(); + } else { TC_LOG_ERROR(LOG_FILTER_NETWORKIO, "WorldSocket::HandlePing: peer sent CMSG_PING, " diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index fb739ba61c1..18c28f38ba2 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -645,7 +645,7 @@ void Spell::InitExplicitTargets(SpellCastTargets const& targets) if (Player* playerCaster = m_caster->ToPlayer()) { // selection has to be found and to be valid target for the spell - if (Unit* selectedUnit = ObjectAccessor::GetUnit(*m_caster, playerCaster->GetSelection())) + if (Unit* selectedUnit = ObjectAccessor::GetUnit(*m_caster, playerCaster->GetTarget())) if (m_spellInfo->CheckExplicitTarget(m_caster, selectedUnit) == SPELL_CAST_OK) unit = selectedUnit; } @@ -1764,9 +1764,9 @@ void Spell::SelectEffectTypeImplicitTargets(uint8 effIndex) { case SPELL_EFFECT_SUMMON_RAF_FRIEND: case SPELL_EFFECT_SUMMON_PLAYER: - if (m_caster->GetTypeId() == TYPEID_PLAYER && m_caster->ToPlayer()->GetSelection()) + if (m_caster->GetTypeId() == TYPEID_PLAYER && m_caster->GetTarget()) { - WorldObject* target = ObjectAccessor::FindPlayer(m_caster->ToPlayer()->GetSelection()); + WorldObject* target = ObjectAccessor::FindPlayer(m_caster->GetTarget()); CallScriptObjectTargetSelectHandlers(target, SpellEffIndex(effIndex)); @@ -3094,7 +3094,7 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect const* triggered // set target for proper facing if ((m_casttime || m_spellInfo->IsChanneled()) && !(_triggeredCastFlags & TRIGGERED_IGNORE_SET_FACING)) if (m_caster->GetTypeId() == TYPEID_UNIT && m_targets.GetObjectTarget() && m_caster != m_targets.GetObjectTarget()) - m_caster->FocusTarget(this, m_targets.GetObjectTarget()); + m_caster->ToCreature()->FocusTarget(this, m_targets.GetObjectTarget()); if (!(_triggeredCastFlags & TRIGGERED_IGNORE_GCD)) TriggerGlobalCooldown(); @@ -3665,8 +3665,8 @@ void Spell::finish(bool ok) ((Puppet*)charm)->UnSummon(); } - if (m_caster->GetTypeId() == TYPEID_UNIT) - m_caster->ReleaseFocus(this); + if (Creature* creatureCaster = m_caster->ToCreature()) + creatureCaster->ReleaseFocus(this); if (!ok) return; @@ -5376,10 +5376,10 @@ SpellCastResult Spell::CheckCast(bool strict) { if (m_caster->GetTypeId() != TYPEID_PLAYER) return SPELL_FAILED_BAD_TARGETS; - if (!m_caster->ToPlayer()->GetSelection()) + if (!m_caster->GetTarget()) return SPELL_FAILED_BAD_TARGETS; - Player* target = ObjectAccessor::FindPlayer(m_caster->ToPlayer()->GetSelection()); + Player* target = ObjectAccessor::FindPlayer(m_caster->ToPlayer()->GetTarget()); if (!target || m_caster->ToPlayer() == target || (!target->IsInSameRaidWith(m_caster->ToPlayer()) && m_spellInfo->Id != 48955)) // refer-a-friend spell return SPELL_FAILED_BAD_TARGETS; @@ -5411,10 +5411,10 @@ SpellCastResult Spell::CheckCast(bool strict) Player* playerCaster = m_caster->ToPlayer(); // - if (!(playerCaster->GetSelection())) + if (!(playerCaster->GetTarget())) return SPELL_FAILED_BAD_TARGETS; - Player* target = ObjectAccessor::FindPlayer(playerCaster->GetSelection()); + Player* target = playerCaster->GetSelectedPlayer(); if (!target || !(target->GetSession()->GetRecruiterId() == playerCaster->GetSession()->GetAccountId() || target->GetSession()->GetAccountId() == playerCaster->GetSession()->GetRecruiterId())) diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 764fe302069..d951d5c62ef 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -2559,7 +2559,7 @@ void Spell::EffectEnchantItemPerm(SpellEffIndex effIndex) if (!item_owner) return; - if (item_owner != player && player->GetSession()->HasPermission(RBAC_PERM_LOG_GM_TRADE)) + if (item_owner != player && player->GetSession()->HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE)) { sLog->outCommand(player->GetSession()->GetAccountId(), "GM %s (Account: %u) enchanting(perm): %s (Entry: %d) for player: %s (Account: %u)", player->GetName().c_str(), player->GetSession()->GetAccountId(), @@ -2624,7 +2624,7 @@ void Spell::EffectEnchantItemPrismatic(SpellEffIndex effIndex) if (!item_owner) return; - if (item_owner != player && player->GetSession()->HasPermission(RBAC_PERM_LOG_GM_TRADE)) + if (item_owner != player && player->GetSession()->HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE)) { sLog->outCommand(player->GetSession()->GetAccountId(), "GM %s (Account: %u) enchanting(perm): %s (Entry: %d) for player: %s (Account: %u)", player->GetName().c_str(), player->GetSession()->GetAccountId(), @@ -2705,7 +2705,7 @@ void Spell::EffectEnchantItemTmp(SpellEffIndex effIndex) if (!item_owner) return; - if (item_owner != player && player->GetSession()->HasPermission(RBAC_PERM_LOG_GM_TRADE)) + if (item_owner != player && player->GetSession()->HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE)) { sLog->outCommand(player->GetSession()->GetAccountId(), "GM %s (Account: %u) enchanting(temp): %s (Entry: %d) for player: %s (Account: %u)", player->GetName().c_str(), player->GetSession()->GetAccountId(), diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index f297e9a7b75..5f3af640429 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -269,7 +269,7 @@ void World::AddSession_(WorldSession* s) if (decrease_session) --Sessions; - if (pLimit > 0 && Sessions >= pLimit && !s->HasPermission(RBAC_PERM_SKIP_QUEUE) && !HasRecentlyDisconnected(s)) + if (pLimit > 0 && Sessions >= pLimit && !s->HasPermission(rbac::RBAC_PERM_SKIP_QUEUE) && !HasRecentlyDisconnected(s)) { AddQueuedPlayer(s); UpdateMaxSessionCounters(); @@ -2185,7 +2185,7 @@ void World::SendGlobalGMMessage(WorldPacket* packet, WorldSession* self, uint32 { // check if session and can receive global GM Messages and its not self WorldSession* session = itr->second; - if (!session || session == self || !session->HasPermission(RBAC_PERM_RECEIVE_GLOBAL_GM_TEXTMESSAGE)) + if (!session || session == self || !session->HasPermission(rbac::RBAC_PERM_RECEIVE_GLOBAL_GM_TEXTMESSAGE)) continue; // Player should be in world @@ -2287,7 +2287,7 @@ void World::SendGMText(int32 string_id, ...) { // Session should have permissions to receive global gm messages WorldSession* session = itr->second; - if (!session || !session->HasPermission(RBAC_PERM_RECEIVE_GLOBAL_GM_TEXTMESSAGE)) + if (!session || !session->HasPermission(rbac::RBAC_PERM_RECEIVE_GLOBAL_GM_TEXTMESSAGE)) continue; // Player should be in world |
