From 1459de81e0be2048d1e873b37bbed016dd0bdd61 Mon Sep 17 00:00:00 2001 From: Chaplain Date: Fri, 25 Jan 2013 23:40:22 +0300 Subject: Core/Spells: rename wrong spell attribute *SPELL_ATTR0_BREAKABLE_BY_DAMAGE -> SPELL_ATTR0_HEARTBEAT_RESIST_CHECK --- src/server/game/AI/CoreAI/UnitAI.cpp | 3 +-- src/server/game/Entities/Unit/Unit.cpp | 2 +- src/server/game/Miscellaneous/SharedDefines.h | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/server/game/AI/CoreAI/UnitAI.cpp b/src/server/game/AI/CoreAI/UnitAI.cpp index 09ba2cc19b1..f7d5852e5a3 100644 --- a/src/server/game/AI/CoreAI/UnitAI.cpp +++ b/src/server/game/AI/CoreAI/UnitAI.cpp @@ -148,8 +148,7 @@ void UnitAI::DoCast(uint32 spellId) float range = spellInfo->GetMaxRange(false); DefaultTargetSelector targetSelector(me, range, playerOnly, -(int32)spellId); - if (!(spellInfo->Attributes & SPELL_ATTR0_BREAKABLE_BY_DAMAGE) - && !(spellInfo->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_VICTIM) + if (!(spellInfo->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_VICTIM) && targetSelector(me->getVictim())) target = me->getVictim(); else diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 948b88d4702..b8a64fda53e 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -515,7 +515,7 @@ bool Unit::HasBreakableByDamageAuraType(AuraType type, uint32 excludeAura) const AuraEffectList const& auras = GetAuraEffectsByType(type); for (AuraEffectList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) if ((!excludeAura || excludeAura != (*itr)->GetSpellInfo()->Id) && //Avoid self interrupt of channeled Crowd Control spells like Seduction - ((*itr)->GetSpellInfo()->Attributes & SPELL_ATTR0_BREAKABLE_BY_DAMAGE || (*itr)->GetSpellInfo()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_TAKE_DAMAGE)) + ((*itr)->GetSpellInfo()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_TAKE_DAMAGE)) return true; return false; } diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index 3d8ad37c92d..6f25f50ed50 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -297,7 +297,7 @@ enum SpellAttr0 SPELL_ATTR0_CASTABLE_WHILE_SITTING = 0x08000000, // 27 castable while sitting SPELL_ATTR0_CANT_USED_IN_COMBAT = 0x10000000, // 28 Cannot be used in combat SPELL_ATTR0_UNAFFECTED_BY_INVULNERABILITY = 0x20000000, // 29 unaffected by invulnerability (hmm possible not...) - SPELL_ATTR0_BREAKABLE_BY_DAMAGE = 0x40000000, // 30 + SPELL_ATTR0_HEARTBEAT_RESIST_CHECK = 0x40000000, // 30 random chance the effect will end TODO: implement core support SPELL_ATTR0_CANT_CANCEL = 0x80000000 // 31 positive aura can't be canceled }; -- cgit v1.2.3 From 4657cb896f12fe94d6c1e553144b8d1468ca5564 Mon Sep 17 00:00:00 2001 From: ille Date: Wed, 20 Feb 2013 20:41:48 +0100 Subject: Core/Conditions: add missing break Core/Units: use attackers MeleeDamageSchoolMask to calculate benefit/mod for auras with SPELL_AURA_MOD_DAMAGE_TAKEN/SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN in Unit::MeleeDamageBonusTaken() thx bonitas for pointing --- src/server/game/Conditions/ConditionMgr.cpp | 1 + src/server/game/Entities/Unit/Unit.cpp | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index a5494f689fb..96cb8b7ee25 100644 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -431,6 +431,7 @@ uint32 Condition::GetSearcherTypeMaskForCondition() default: break; } + break; case CONDITION_TYPE_MASK: if (ConditionValue1 & TYPEMASK_UNIT) mask |= GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_PLAYER; diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index fa7ef5189fb..d75eb46ea8d 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -11193,7 +11193,7 @@ uint32 Unit::MeleeDamageBonusTaken(Unit* attacker, uint32 pdamage, WeaponAttackT // ..taken AuraEffectList const& mDamageTaken = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_TAKEN); for (AuraEffectList::const_iterator i = mDamageTaken.begin(); i != mDamageTaken.end(); ++i) - if ((*i)->GetMiscValue() & GetMeleeDamageSchoolMask()) + if ((*i)->GetMiscValue() & attacker->GetMeleeDamageSchoolMask()) TakenFlatBenefit += (*i)->GetAmount(); if (attType != RANGED_ATTACK) @@ -11205,7 +11205,7 @@ uint32 Unit::MeleeDamageBonusTaken(Unit* attacker, uint32 pdamage, WeaponAttackT float TakenTotalMod = 1.0f; // ..taken - TakenTotalMod *= GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, GetMeleeDamageSchoolMask()); + TakenTotalMod *= GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, attacker->GetMeleeDamageSchoolMask()); // .. taken pct (special attacks) if (spellProto) -- cgit v1.2.3 From ba549ddc30fd09f7591f0619a59cee1cd9e20574 Mon Sep 17 00:00:00 2001 From: horn Date: Sat, 23 Feb 2013 01:50:52 +0100 Subject: Core/Summons: Implement summon groups system to be able to summon multiple NPCs at once without need of hardcoding the positions. Almost all hardcoded positions can now be moved to DB. Thx to @Shauren for his help. --- .../2013_02_24_00_world_creature_summon_groups.sql | 16 ++++ .../game/Entities/Creature/TemporarySummon.h | 16 ++++ src/server/game/Entities/Object/Object.cpp | 37 ++++++++++ src/server/game/Entities/Object/Object.h | 1 + src/server/game/Globals/ObjectMgr.cpp | 86 ++++++++++++++++++++++ src/server/game/Globals/ObjectMgr.h | 42 +++++++++++ src/server/game/Maps/Map.h | 1 + src/server/game/World/World.cpp | 3 + 8 files changed, 202 insertions(+) create mode 100644 sql/updates/world/2013_02_24_00_world_creature_summon_groups.sql (limited to 'src') diff --git a/sql/updates/world/2013_02_24_00_world_creature_summon_groups.sql b/sql/updates/world/2013_02_24_00_world_creature_summon_groups.sql new file mode 100644 index 00000000000..409f79bb2aa --- /dev/null +++ b/sql/updates/world/2013_02_24_00_world_creature_summon_groups.sql @@ -0,0 +1,16 @@ +DROP TABLE IF EXISTS `creature_summon_groups`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `creature_summon_groups` ( + `summonerId` mediumint(8) unsigned NOT NULL DEFAULT '0', + `summonerType` tinyint(3) unsigned NOT NULL DEFAULT '0', + `groupId` tinyint(3) unsigned NOT NULL DEFAULT '0', + `entry` mediumint(8) unsigned NOT NULL DEFAULT '0', + `position_x` float NOT NULL DEFAULT '0', + `position_y` float NOT NULL DEFAULT '0', + `position_z` float NOT NULL DEFAULT '0', + `orientation` float NOT NULL DEFAULT '0', + `summonType` tinyint(3) unsigned NOT NULL DEFAULT '0', + `summonTime` int(10) unsigned NOT NULL DEFAULT '0' +) ENGINE=MyISAM DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; diff --git a/src/server/game/Entities/Creature/TemporarySummon.h b/src/server/game/Entities/Creature/TemporarySummon.h index a96d9ab33d0..dc3347c5b4f 100644 --- a/src/server/game/Entities/Creature/TemporarySummon.h +++ b/src/server/game/Entities/Creature/TemporarySummon.h @@ -21,6 +21,22 @@ #include "Creature.h" +enum SummonerType +{ + SUMMONER_TYPE_CREATURE = 0, + SUMMONER_TYPE_GAMEOBJECT = 1, + SUMMONER_TYPE_MAP = 2 +}; + +/// Stores data for temp summons +struct TempSummonData +{ + uint32 entry; ///< Entry of summoned creature + Position pos; ///< Position, where should be creature spawned + TempSummonType type; ///< Summon type, see TempSummonType for available types + uint32 time; ///< Despawn time, usable only with certain temp summon types +}; + class TempSummon : public Creature { public: diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 893d4c1ea69..79bf656c318 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -2315,6 +2315,24 @@ TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropert return summon; } +/** +* Summons group of creatures. +* +* @param group Id of group to summon. +* @param list List to store pointers to summoned creatures. +*/ + +void Map::SummonCreatureGroup(uint8 group, std::list& list) +{ + std::vector const* data = sObjectMgr->GetSummonGroup(GetId(), SUMMONER_TYPE_MAP, group); + if (!data) + return; + + for (std::vector::const_iterator itr = data->begin(); itr != data->end(); ++itr) + if (TempSummon* summon = SummonCreature(itr->entry, itr->pos, NULL, itr->time)) + list.push_back(summon); +} + void WorldObject::SetZoneScript() { if (Map* map = FindMap()) @@ -2394,6 +2412,25 @@ Creature* WorldObject::SummonTrigger(float x, float y, float z, float ang, uint3 return summon; } +/** +* Summons group of creatures. Should be called only by instances of Creature and GameObject classes. +* +* @param group Id of group to summon. +* @param list List to store pointers to summoned creatures. +*/ +void WorldObject::SummonCreatureGroup(uint8 group, std::list& list) +{ + ASSERT((GetTypeId() == TYPEID_GAMEOBJECT || GetTypeId() == TYPEID_UNIT) && "Only GOs and creatures can summon npc groups!"); + + std::vector const* data = sObjectMgr->GetSummonGroup(GetEntry(), GetTypeId() == TYPEID_GAMEOBJECT ? SUMMONER_TYPE_GAMEOBJECT : SUMMONER_TYPE_CREATURE, group); + if (!data) + return; + + for (std::vector::const_iterator itr = data->begin(); itr != data->end(); ++itr) + if (TempSummon* summon = SummonCreature(itr->entry, itr->pos, itr->type, itr->time)) + list.push_back(summon); +} + Creature* WorldObject::FindNearestCreature(uint32 entry, float range, bool alive) const { Creature* creature = NULL; diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index ae3d545b7d7..ae788621368 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -793,6 +793,7 @@ class WorldObject : public Object, public WorldLocation } GameObject* SummonGameObject(uint32 entry, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 respawnTime); Creature* SummonTrigger(float x, float y, float z, float ang, uint32 dur, CreatureAI* (*GetAI)(Creature*) = NULL); + void SummonCreatureGroup(uint8 group, std::list& list); Creature* FindNearestCreature(uint32 entry, float range, bool alive = true) const; GameObject* FindNearestGameObject(uint32 entry, float range) const; diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 0e657c5ea9e..222331c48f8 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -1421,6 +1421,92 @@ bool ObjectMgr::SetCreatureLinkedRespawn(uint32 guidLow, uint32 linkedGuidLow) return true; } +void ObjectMgr::LoadTempSummons() +{ + uint32 oldMSTime = getMSTime(); + + // 0 1 2 3 4 5 6 7 8 9 + QueryResult result = WorldDatabase.Query("SELECT summonerId, summonerType, groupId, entry, position_x, position_y, position_z, orientation, summonType, summonTime FROM creature_summon_groups"); + + if (!result) + { + sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 temp summons. DB table `creature_summon_groups` is empty."); + return; + } + + uint32 count = 0; + do + { + Field* fields = result->Fetch(); + + uint32 summonerId = fields[0].GetUInt32(); + SummonerType summonerType = SummonerType(fields[1].GetUInt8()); + uint8 group = fields[2].GetUInt8(); + + switch (summonerType) + { + case SUMMONER_TYPE_CREATURE: + if (!GetCreatureTemplate(summonerId)) + { + sLog->outError(LOG_FILTER_SQL, "Table `creature_summon_groups` has summoner with non existing entry %u for creature summoner type, skipped.", summonerId); + continue; + } + break; + case SUMMONER_TYPE_GAMEOBJECT: + if (!GetGameObjectTemplate(summonerId)) + { + sLog->outError(LOG_FILTER_SQL, "Table `creature_summon_groups` has summoner with non existing entry %u for gameobject summoner type, skipped.", summonerId); + continue; + } + break; + case SUMMONER_TYPE_MAP: + if (!sMapStore.LookupEntry(summonerId)) + { + sLog->outError(LOG_FILTER_SQL, "Table `creature_summon_groups` has summoner with non existing entry %u for map summoner type, skipped.", summonerId); + continue; + } + break; + default: + sLog->outError(LOG_FILTER_SQL, "Table `creature_summon_groups` has unhandled summoner type %u for summoner %u, skipped.", summonerType, summonerId); + continue; + } + + TempSummonData data; + data.entry = fields[3].GetUInt32(); + + if (!GetCreatureTemplate(data.entry)) + { + sLog->outError(LOG_FILTER_SQL, "Table `creature_summon_groups` has creature in group [Summoner ID: %u, Summoner Type: %u, Group ID: %u] with non existing creature entry %u, skipped.", summonerId, summonerType, group, data.entry); + continue; + } + + float posX = fields[4].GetFloat(); + float posY = fields[5].GetFloat(); + float posZ = fields[6].GetFloat(); + float orientation = fields[7].GetFloat(); + + data.pos.Relocate(posX, posY, posZ, orientation); + + data.type = TempSummonType(fields[8].GetUInt8()); + + if (data.type > TEMPSUMMON_MANUAL_DESPAWN) + { + sLog->outError(LOG_FILTER_SQL, "Table `creature_summon_groups` has unhandled temp summon type %u in group [Summoner ID: %u, Summoner Type: %u, Group ID: %u] for creature entry %u, skipped.", data.type, summonerId, summonerType, group, data.entry); + continue; + } + + data.time = fields[9].GetUInt32(); + + TempSummonGroupKey key(summonerId, summonerType, group); + _tempSummonDataStore[key].push_back(data); + + ++count; + + } while (result->NextRow()); + + sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u temp summons in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); +} + void ObjectMgr::LoadCreatures() { uint32 oldMSTime = getMSTime(); diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 88496fa9d6e..12df01fc350 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -25,6 +25,7 @@ #include "Creature.h" #include "DynamicObject.h" #include "GameObject.h" +#include "TemporarySummon.h" #include "Corpse.h" #include "QuestDef.h" #include "ItemPrototype.h" @@ -416,9 +417,29 @@ struct TrinityStringLocale StringVector Content; }; +/// Key for storing temp summon data in TempSummonDataContainer +struct TempSummonGroupKey +{ + TempSummonGroupKey(uint32 summonerEntry, SummonerType summonerType, uint8 group) + : _summonerEntry(summonerEntry), _summonerType(summonerType), _summonGroup(group) + { + } + + bool operator<(TempSummonGroupKey const& rhs) const + { + return memcmp(this, &rhs, sizeof(TempSummonGroupKey)) < 0; + } + +private: + uint32 _summonerEntry; ///< Summoner's entry + SummonerType _summonerType; ///< Summoner's type, see SummonerType for available types + uint8 _summonGroup; ///< Summon's group id +}; + typedef std::map LinkedRespawnContainer; typedef UNORDERED_MAP CreatureDataContainer; typedef UNORDERED_MAP GameObjectDataContainer; +typedef std::map > TempSummonDataContainer; typedef UNORDERED_MAP CreatureLocaleContainer; typedef UNORDERED_MAP GameObjectLocaleContainer; typedef UNORDERED_MAP ItemLocaleContainer; @@ -876,6 +897,7 @@ class ObjectMgr void LoadCreatureTemplates(); void LoadCreatureTemplateAddons(); void CheckCreatureTemplate(CreatureTemplate const* cInfo); + void LoadTempSummons(); void LoadCreatures(); void LoadLinkedRespawn(); bool SetCreatureLinkedRespawn(uint32 guid, uint32 linkedGuid); @@ -981,6 +1003,24 @@ class ObjectMgr return _mapObjectGuidsStore[MAKE_PAIR32(mapid, spawnMode)][cell_id]; } + /** + * Gets temp summon data for all creatures of specified group. + * + * @param summonerId Summoner's entry. + * @param summonerType Summoner's type, see SummonerType for available types. + * @param group Id of required group. + * + * @return null if group was not found, otherwise reference to the creature group data + */ + std::vector const* GetSummonGroup(uint32 summonerId, SummonerType summonerType, uint8 group) const + { + TempSummonDataContainer::const_iterator itr = _tempSummonDataStore.find(TempSummonGroupKey(summonerId, summonerType, group)); + if (itr != _tempSummonDataStore.end()) + return &itr->second; + + return NULL; + } + CreatureData const* GetCreatureData(uint32 guid) const { CreatureDataContainer::const_iterator itr = _creatureDataStore.find(guid); @@ -1294,6 +1334,8 @@ class ObjectMgr GameObjectDataContainer _gameObjectDataStore; GameObjectLocaleContainer _gameObjectLocaleStore; GameObjectTemplateContainer _gameObjectTemplateStore; + /// Stores temp summon data grouped by summoner's entry, summoner's type and group id + TempSummonDataContainer _tempSummonDataStore; ItemTemplateContainer _itemTemplateStore; ItemLocaleContainer _itemLocaleStore; diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index 6bf7edf3a2f..cc47f053827 100644 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -435,6 +435,7 @@ class Map : public GridRefManager void UpdateIteratorBack(Player* player); TempSummon* SummonCreature(uint32 entry, Position const& pos, SummonPropertiesEntry const* properties = NULL, uint32 duration = 0, Unit* summoner = NULL, uint32 spellId = 0, uint32 vehId = 0); + void SummonCreatureGroup(uint8 group, std::list& list); Creature* GetCreature(uint64 guid); GameObject* GetGameObject(uint64 guid); DynamicObject* GetDynamicObject(uint64 guid); diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 29ecdbb033e..ad2cc7699b2 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1432,6 +1432,9 @@ void World::SetInitialWorldSettings() sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading Creature Data..."); sObjectMgr->LoadCreatures(); + sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading Temporary Summon Data..."); + sObjectMgr->LoadTempSummons(); // must be after LoadCreatureTemplates() and LoadGameObjectTemplates() + sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading pet levelup spells..."); sSpellMgr->LoadPetLevelupSpellMap(); -- cgit v1.2.3 From cf58f5a0755aba577fee604cc88e5929428b9784 Mon Sep 17 00:00:00 2001 From: Nay Date: Sun, 24 Feb 2013 16:54:02 +0000 Subject: Core: Fix a comment in LoadConfigSettings Closes #9292 --- src/server/game/World/World.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index ad2cc7699b2..32ee21a7ca2 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1223,7 +1223,7 @@ void World::LoadConfigSettings(bool reload) m_bool_configs[CONFIG_PDUMP_NO_OVERWRITE] = ConfigMgr::GetBoolDefault("PlayerDump.DisallowOverwrite", true); m_bool_configs[CONFIG_UI_QUESTLEVELS_IN_DIALOGS] = ConfigMgr::GetBoolDefault("UI.ShowQuestLevelsInDialogs", false); - // call ScriptMgr if we're reloading the configuration + // Wintergrasp battlefield m_bool_configs[CONFIG_WINTERGRASP_ENABLE] = ConfigMgr::GetBoolDefault("Wintergrasp.Enable", false); m_int_configs[CONFIG_WINTERGRASP_PLR_MAX] = ConfigMgr::GetIntDefault("Wintergrasp.PlayerMax", 100); m_int_configs[CONFIG_WINTERGRASP_PLR_MIN] = ConfigMgr::GetIntDefault("Wintergrasp.PlayerMin", 0); @@ -1232,6 +1232,7 @@ void World::LoadConfigSettings(bool reload) m_int_configs[CONFIG_WINTERGRASP_NOBATTLETIME] = ConfigMgr::GetIntDefault("Wintergrasp.NoBattleTimer", 150); m_int_configs[CONFIG_WINTERGRASP_RESTART_AFTER_CRASH] = ConfigMgr::GetIntDefault("Wintergrasp.CrashRestartTimer", 10); + // call ScriptMgr if we're reloading the configuration if (reload) sScriptMgr->OnConfigLoad(reload); } -- cgit v1.2.3 From cb99c1d16aef4f4fc000aff7aaa3f63fadf4e9ef Mon Sep 17 00:00:00 2001 From: Gacko Date: Sun, 24 Feb 2013 19:29:06 +0100 Subject: Script/Quest: The Lonesome Watcher (12877) Closes: #9185 See: http://www.youtube.com/watch?v=ylZRMu9CIMw --- .../2013_02_24_01_world_areatrigger_scripts.sql | 3 + .../world/2013_02_24_02_world_smart_scripts.sql | 7 +++ .../world/2013_02_24_03_world_waypoint_data.sql | 11 ++++ .../2013_02_24_04_world_creature_template.sql | 2 + src/server/scripts/World/areatrigger_scripts.cpp | 64 ++++++++++++++++++++++ 5 files changed, 87 insertions(+) create mode 100644 sql/updates/world/2013_02_24_01_world_areatrigger_scripts.sql create mode 100644 sql/updates/world/2013_02_24_02_world_smart_scripts.sql create mode 100644 sql/updates/world/2013_02_24_03_world_waypoint_data.sql create mode 100644 sql/updates/world/2013_02_24_04_world_creature_template.sql (limited to 'src') diff --git a/sql/updates/world/2013_02_24_01_world_areatrigger_scripts.sql b/sql/updates/world/2013_02_24_01_world_areatrigger_scripts.sql new file mode 100644 index 00000000000..2aebe1d2edd --- /dev/null +++ b/sql/updates/world/2013_02_24_01_world_areatrigger_scripts.sql @@ -0,0 +1,3 @@ +DELETE FROM `areatrigger_scripts` WHERE `entry`=5173; +INSERT INTO `areatrigger_scripts`(`entry`,`ScriptName`) VALUE +(5173,'at_frostgrips_hollow'); diff --git a/sql/updates/world/2013_02_24_02_world_smart_scripts.sql b/sql/updates/world/2013_02_24_02_world_smart_scripts.sql new file mode 100644 index 00000000000..7b41c82b6fa --- /dev/null +++ b/sql/updates/world/2013_02_24_02_world_smart_scripts.sql @@ -0,0 +1,7 @@ +DELETE FROM `smart_scripts` WHERE `entryorguid`=29861 AND `source_type`=0; +INSERT INTO `smart_scripts`(`entryorguid`,`source_type`,`event_type`,`action_type`,`action_param1`,`action_param2`,`target_type`,`comment`) VALUES +(29861,0,54,80,2986100,2,1,'Stormforged Eradictor - Just summoned - Call timed actionlist 2986100'); + +DELETE FROM `smart_scripts` WHERE `entryorguid`=2986100 AND `source_type`=9; +INSERT INTO `smart_scripts`(`entryorguid`,`source_type`,`id`,`event_param1`,`event_param2`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`target_type`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUE +(2986100,9,0,10000,10000,12,29729,4,10000,8,6972.13,14.24,805.79,3.349,'Stormforged Eradictor - Timed actionlist - Summon Frostborn Axemaster'); diff --git a/sql/updates/world/2013_02_24_03_world_waypoint_data.sql b/sql/updates/world/2013_02_24_03_world_waypoint_data.sql new file mode 100644 index 00000000000..e97f0758304 --- /dev/null +++ b/sql/updates/world/2013_02_24_03_world_waypoint_data.sql @@ -0,0 +1,11 @@ +DELETE FROM `waypoint_data` WHERE `id`=2986200; +INSERT INTO `waypoint_data`(`id`,`point`,`position_x`,`position_y`,`position_z`) VALUES +(2986200,0,6963.95,45.65,818.71), +(2986200,1,6965.09,39.67,820.15), +(2986200,2,6963.56,21.14,805.79); + +DELETE FROM `waypoint_data` WHERE `id`=2986100; +INSERT INTO `waypoint_data`(`id`,`point`,`position_x`,`position_y`,`position_z`) VALUES +(2986100,0,6983.18,7.150,806.33), +(2986100,1,6975.37,16.73,804.98), +(2986100,2,6967.15,13.27,806.56); diff --git a/sql/updates/world/2013_02_24_04_world_creature_template.sql b/sql/updates/world/2013_02_24_04_world_creature_template.sql new file mode 100644 index 00000000000..c9acc0d2a1a --- /dev/null +++ b/sql/updates/world/2013_02_24_04_world_creature_template.sql @@ -0,0 +1,2 @@ +UPDATE `creature_template` SET `faction_A`=1954,`faction_H`=1954,`AIName`='SmartAI' WHERE `entry`=29861; +UPDATE `creature_template` SET `faction_A`=1954,`faction_H`=1954 WHERE `entry`=29862; diff --git a/src/server/scripts/World/areatrigger_scripts.cpp b/src/server/scripts/World/areatrigger_scripts.cpp index c031c4a3b4d..83fac35b1b6 100644 --- a/src/server/scripts/World/areatrigger_scripts.cpp +++ b/src/server/scripts/World/areatrigger_scripts.cpp @@ -425,6 +425,69 @@ class AreaTrigger_at_area_52_entrance : public AreaTriggerScript std::map _triggerTimes; }; +/*###### + ## at_frostgrips_hollow + ######*/ + +enum FrostgripsHollow +{ + QUEST_THE_LONESOME_WATCHER = 12877, + + NPC_STORMFORGED_MONITOR = 29862, + NPC_STORMFORGED_ERADICTOR = 29861, + + TYPE_WAYPOINT = 0, + DATA_START = 0 +}; + +Position const stormforgedMonitorPosition = {6963.95f, 45.65f, 818.71f, 4.948f}; +Position const stormforgedEradictorPosition = {6983.18f, 7.15f, 806.33f, 2.228f}; + +class AreaTrigger_at_frostgrips_hollow : public AreaTriggerScript +{ +public: + AreaTrigger_at_frostgrips_hollow() : AreaTriggerScript("at_frostgrips_hollow") + { + stormforgedMonitorGUID = 0; + stormforgedEradictorGUID = 0; + } + + bool OnTrigger(Player* player, AreaTriggerEntry const* /* trigger */) + { + if (player->GetQuestStatus(QUEST_THE_LONESOME_WATCHER) != QUEST_STATUS_INCOMPLETE) + return false; + + Creature* stormforgedMonitor = Creature::GetCreature(*player, stormforgedMonitorGUID); + if (stormforgedMonitor) + return false; + + Creature* stormforgedEradictor = Creature::GetCreature(*player, stormforgedEradictorGUID); + if (stormforgedEradictor) + return false; + + if ((stormforgedMonitor = player->SummonCreature(NPC_STORMFORGED_MONITOR, stormforgedMonitorPosition, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000))) + { + stormforgedMonitorGUID = stormforgedMonitor->GetGUID(); + stormforgedMonitor->SetWalk(false); + /// The npc would search an alternative way to get to the last waypoint without this unit state. + stormforgedMonitor->AddUnitState(UNIT_STATE_IGNORE_PATHFINDING); + stormforgedMonitor->GetMotionMaster()->MovePath(NPC_STORMFORGED_MONITOR * 100, false); + } + + if ((stormforgedEradictor = player->SummonCreature(NPC_STORMFORGED_ERADICTOR, stormforgedEradictorPosition, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000))) + { + stormforgedEradictorGUID = stormforgedEradictor->GetGUID(); + stormforgedEradictor->GetMotionMaster()->MovePath(NPC_STORMFORGED_ERADICTOR * 100, false); + } + + return true; + } + +private: + uint64 stormforgedMonitorGUID; + uint64 stormforgedEradictorGUID; +}; + void AddSC_areatrigger_scripts() { new AreaTrigger_at_coilfang_waterfall(); @@ -436,4 +499,5 @@ void AddSC_areatrigger_scripts() new AreaTrigger_at_nats_landing(); new AreaTrigger_at_brewfest(); new AreaTrigger_at_area_52_entrance(); + new AreaTrigger_at_frostgrips_hollow(); } -- cgit v1.2.3 From 1049d02e5fe3a2c5179196b4e53fd7dd20daf682 Mon Sep 17 00:00:00 2001 From: Shocker Date: Mon, 25 Feb 2013 04:55:53 +0200 Subject: Core/Spells: Define SPELL_ATTR6_PRINT_SPELLNAME (Can't think of a better name/description) --- src/server/game/Miscellaneous/SharedDefines.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index a2d1cdd83dd..6d58dfbf27d 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -489,7 +489,7 @@ enum SpellAttr6 SPELL_ATTR6_UNK3 = 0x00000008, // 3 SPELL_ATTR6_UNK4 = 0x00000010, // 4 SPELL_ATTR6_UNK5 = 0x00000020, // 5 - SPELL_ATTR6_UNK6 = 0x00000040, // 6 + SPELL_ATTR6_PRINT_SPELLNAME = 0x00000040, // 6 when activated, spell name is shown at the center of the screen: (client-side attribute) SPELL_ATTR6_UNK7 = 0x00000080, // 7 SPELL_ATTR6_CANT_TARGET_CROWD_CONTROLLED = 0x00000100, // 8 SPELL_ATTR6_UNK9 = 0x00000200, // 9 -- cgit v1.2.3 From 20e913efa685695a721e44931b4f939e6bfe7733 Mon Sep 17 00:00:00 2001 From: Shocker Date: Mon, 25 Feb 2013 05:38:34 +0200 Subject: Core/Spells: Implement TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT to allow ignoring equipped item requirements on triggered casting --- src/server/game/Entities/Unit/Unit.h | 1 + src/server/game/Spells/Spell.cpp | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 62facf6a69e..b549802c91c 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -398,6 +398,7 @@ enum TriggerCastFlags TRIGGERED_IGNORE_CASTER_AURAS = 0x00010000, //! Will ignore caster aura restrictions or requirements TRIGGERED_DISALLOW_PROC_EVENTS = 0x00020000, //! Disallows proc events from triggered spell (default) TRIGGERED_DONT_REPORT_CAST_ERROR = 0x00040000, //! Will return SPELL_FAILED_DONT_REPORT in CheckCast functions + TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT = 0x00080000, //! Will ignore equipped item requirements TRIGGERED_FULL_MASK = 0xFFFFFFFF }; diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 53bcd6bd077..ae1389c5f11 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -5942,8 +5942,9 @@ SpellCastResult Spell::CheckItems() // if not item target then required item must be equipped else { - if (m_caster->GetTypeId() == TYPEID_PLAYER && !m_caster->ToPlayer()->HasItemFitToSpellRequirements(m_spellInfo)) - return SPELL_FAILED_EQUIPPED_ITEM_CLASS; + if (!(_triggeredCastFlags & TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT)) + if (m_caster->GetTypeId() == TYPEID_PLAYER && !m_caster->ToPlayer()->HasItemFitToSpellRequirements(m_spellInfo)) + return SPELL_FAILED_EQUIPPED_ITEM_CLASS; } // check spell focus object @@ -6325,7 +6326,7 @@ SpellCastResult Spell::CheckItems() } // check weapon presence in slots for main/offhand weapons - if (m_spellInfo->EquippedItemClass >=0) + if (!(_triggeredCastFlags & TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT) && m_spellInfo->EquippedItemClass >=0) { // main hand weapon required if (m_spellInfo->AttributesEx3 & SPELL_ATTR3_MAIN_HAND) -- cgit v1.2.3 From 15343d9bb074823e9b631cef873b7ba93663fad2 Mon Sep 17 00:00:00 2001 From: Spp Date: Mon, 25 Feb 2013 10:47:50 +0100 Subject: Core/RBAC: Remove unnecessary header includes from other header files --- src/server/game/Accounts/AccountMgr.cpp | 13 +++++++ src/server/game/Accounts/AccountMgr.h | 1 + src/server/game/AuctionHouse/AuctionHouseMgr.cpp | 47 ++++++++++++------------ src/server/game/DungeonFinding/LFGMgr.cpp | 1 + src/server/game/Server/WorldSession.cpp | 1 + src/server/game/Server/WorldSession.h | 2 +- src/server/scripts/Commands/cs_rbac.cpp | 4 +- src/server/worldserver/TCSoap/TCSoap.cpp | 3 ++ src/server/worldserver/TCSoap/TCSoap.h | 10 +---- 9 files changed, 47 insertions(+), 35 deletions(-) (limited to 'src') diff --git a/src/server/game/Accounts/AccountMgr.cpp b/src/server/game/Accounts/AccountMgr.cpp index 596f7f5ceb9..7172efaac0e 100644 --- a/src/server/game/Accounts/AccountMgr.cpp +++ b/src/server/game/Accounts/AccountMgr.cpp @@ -544,3 +544,16 @@ RBACPermission const* AccountMgr::GetRBACPermission(uint32 permission) const return NULL; } + +bool AccountMgr::HasPermission(uint32 accountId, uint32 permission, uint32 realmId) +{ + if (!accountId) + return false; + + RBACData* rbac = new RBACData(accountId, "", realmId); + rbac->LoadFromDB(); + bool hasPermission = rbac->HasPermission(permission); + delete rbac; + + return hasPermission; +} diff --git a/src/server/game/Accounts/AccountMgr.h b/src/server/game/Accounts/AccountMgr.h index 2c07172723d..28373456994 100644 --- a/src/server/game/Accounts/AccountMgr.h +++ b/src/server/game/Accounts/AccountMgr.h @@ -67,6 +67,7 @@ class AccountMgr static bool IsGMAccount(uint32 gmlevel); static bool IsAdminAccount(uint32 gmlevel); static bool IsConsoleAccount(uint32 gmlevel); + static bool HasPermission(uint32 accountId, uint32 permission, uint32 realmId); void UpdateAccountAccess(RBACData* rbac, uint32 accountId, uint8 securityLevel, int32 realmId); diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp index 71c44408f72..20f73eeff69 100644 --- a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp +++ b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp @@ -93,46 +93,45 @@ void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry* auction, SQLTransaction& if (!pItem) return; - uint32 bidder_accId = 0; - uint64 bidder_guid = MAKE_NEW_GUID(auction->bidder, 0, HIGHGUID_PLAYER); - Player* bidder = ObjectAccessor::FindPlayer(bidder_guid); + uint32 bidderAccId = 0; + uint64 bidderGuid = MAKE_NEW_GUID(auction->bidder, 0, HIGHGUID_PLAYER); + Player* bidder = ObjectAccessor::FindPlayer(bidderGuid); // data for gm.log if (sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) { - uint32 bidder_security = 0; - std::string bidder_name; + std::string bidderName; + bool logGmTrade = false; + if (bidder) { - bidder_accId = bidder->GetSession()->GetAccountId(); - bidder_security = bidder->GetSession()->GetSecurity(); - bidder_name = bidder->GetName(); + bidderAccId = bidder->GetSession()->GetAccountId(); + bidderName = bidder->GetName(); + logGmTrade = !AccountMgr::IsPlayerAccount(bidder->GetSession()->GetAccountId()); } else { - bidder_accId = sObjectMgr->GetPlayerAccountIdByGUID(bidder_guid); - bidder_security = AccountMgr::GetSecurity(bidder_accId, realmID); + bidderAccId = sObjectMgr->GetPlayerAccountIdByGUID(bidderGuid); + logGmTrade = !AccountMgr::IsPlayerAccount(AccountMgr::GetSecurity(bidderAccId, realmID)); - if (!AccountMgr::IsPlayerAccount(bidder_security)) // not do redundant DB requests - { - if (!sObjectMgr->GetPlayerNameByGUID(bidder_guid, bidder_name)) - bidder_name = sObjectMgr->GetTrinityStringForDBCLocale(LANG_UNKNOWN); - } + if (logGmTrade && !sObjectMgr->GetPlayerNameByGUID(bidderGuid, bidderName)) + bidderName = sObjectMgr->GetTrinityStringForDBCLocale(LANG_UNKNOWN); } - if (!AccountMgr::IsPlayerAccount(bidder_security)) + + if (logGmTrade) { - std::string owner_name; - if (!sObjectMgr->GetPlayerNameByGUID(auction->owner, owner_name)) - owner_name = sObjectMgr->GetTrinityStringForDBCLocale(LANG_UNKNOWN); + std::string ownerName; + if (!sObjectMgr->GetPlayerNameByGUID(auction->owner, ownerName)) + ownerName = sObjectMgr->GetTrinityStringForDBCLocale(LANG_UNKNOWN); - uint32 owner_accid = sObjectMgr->GetPlayerAccountIdByGUID(auction->owner); + uint32 ownerAccId = sObjectMgr->GetPlayerAccountIdByGUID(auction->owner); - sLog->outCommand(bidder_accId, "GM %s (Account: %u) won item in auction: %s (Entry: %u Count: %u) and pay money: %u. Original owner %s (Account: %u)", - bidder_name.c_str(), bidder_accId, pItem->GetTemplate()->Name1.c_str(), pItem->GetEntry(), pItem->GetCount(), auction->bid, owner_name.c_str(), owner_accid); + sLog->outCommand(bidderAccId, "GM %s (Account: %u) won item in auction: %s (Entry: %u Count: %u) and pay money: %u. Original owner %s (Account: %u)", + bidderName.c_str(), bidderAccId, pItem->GetTemplate()->Name1.c_str(), pItem->GetEntry(), pItem->GetCount(), auction->bid, ownerName.c_str(), ownerAccId); } } // receiver exist - if (bidder || bidder_accId) + if (bidder || bidderAccId) { // set owner to bidder (to prevent delete item with sender char deleting) // owner in `data` will set at mail receive and item extracting @@ -143,7 +142,7 @@ void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry* auction, SQLTransaction& if (bidder) { - bidder->GetSession()->SendAuctionBidderNotification(auction->GetHouseId(), auction->Id, bidder_guid, 0, 0, auction->itemEntry); + bidder->GetSession()->SendAuctionBidderNotification(auction->GetHouseId(), auction->Id, bidderGuid, 0, 0, auction->itemEntry); // FIXME: for offline player need also bidder->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WON_AUCTIONS, 1); } diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index 9bb65b63557..ce18c227656 100644 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -29,6 +29,7 @@ #include "LFGQueue.h" #include "Group.h" #include "Player.h" +#include "RBAC.h" #include "GroupMgr.h" #include "GameEventMgr.h" #include "WorldSession.h" diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 610047dac2f..1e36f342712 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -24,6 +24,7 @@ #include "Config.h" #include "Common.h" #include "DatabaseEnv.h" +#include "AccountMgr.h" #include "Log.h" #include "Opcodes.h" #include "WorldPacket.h" diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 42242e93742..20fa7d9335d 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -24,7 +24,6 @@ #define __WORLDSESSION_H #include "Common.h" -#include "AccountMgr.h" #include "SharedDefines.h" #include "AddonMgr.h" #include "DatabaseEnv.h" @@ -40,6 +39,7 @@ class LoginQueryHolder; class Object; class Player; class Quest; +class RBACData; class SpellCastTargets; class Unit; class Warden; diff --git a/src/server/scripts/Commands/cs_rbac.cpp b/src/server/scripts/Commands/cs_rbac.cpp index 092aabb0045..604218c2e68 100644 --- a/src/server/scripts/Commands/cs_rbac.cpp +++ b/src/server/scripts/Commands/cs_rbac.cpp @@ -22,7 +22,7 @@ Comment: All role based access control related commands (including account relat Category: commandscripts EndScriptData */ -#include "RBAC.h" +#include "AccountMgr.h" #include "Config.h" #include "Chat.h" #include "Language.h" @@ -188,7 +188,7 @@ public: if (!rdata) { - data->rbac = new RBACData(accountId, accountName, ConfigMgr::GetIntDefault("RealmID", 0)); + data->rbac = new RBACData(accountId, accountName, realmID); data->rbac->LoadFromDB(); data->needDelete = true; } diff --git a/src/server/worldserver/TCSoap/TCSoap.cpp b/src/server/worldserver/TCSoap/TCSoap.cpp index 7d460da4f83..dd82c6ce0c7 100644 --- a/src/server/worldserver/TCSoap/TCSoap.cpp +++ b/src/server/worldserver/TCSoap/TCSoap.cpp @@ -18,6 +18,9 @@ #include "TCSoap.h" #include "soapH.h" #include "soapStub.h" +#include "World.h" +#include "AccountMgr.h" +#include "Log.h" void TCSoapRunnable::run() { diff --git a/src/server/worldserver/TCSoap/TCSoap.h b/src/server/worldserver/TCSoap/TCSoap.h index ccdc7b1f89f..b786ee94e81 100644 --- a/src/server/worldserver/TCSoap/TCSoap.h +++ b/src/server/worldserver/TCSoap/TCSoap.h @@ -18,17 +18,11 @@ #ifndef _TCSOAP_H #define _TCSOAP_H -#include "Common.h" -#include "World.h" -#include "AccountMgr.h" -#include "Log.h" - -#include "soapH.h" -#include "soapStub.h" -#include "stdsoap2.h" +#include "Define.h" #include #include +#include class TCSoapRunnable: public ACE_Based::Runnable { -- cgit v1.2.3 From 8810fcb575a3362703421c1d2f900faa2ab57fd6 Mon Sep 17 00:00:00 2001 From: Spp Date: Mon, 25 Feb 2013 11:40:51 +0100 Subject: Core/RBAC: Add new Permission "Log gm trade". Config option still active, but will affect only to users with that permission granted --- sql/updates/auth/2013_02_25_00_auth_misc.sql | 14 ++++++++++++++ src/server/game/Accounts/RBAC.h | 1 + src/server/game/AuctionHouse/AuctionHouseMgr.cpp | 4 ++-- src/server/game/Guilds/Guild.cpp | 7 +++++-- src/server/game/Handlers/MailHandler.cpp | 7 ++++--- src/server/game/Handlers/TradeHandler.cpp | 11 ++++++----- src/server/game/Spells/SpellEffects.cpp | 6 +++--- 7 files changed, 35 insertions(+), 15 deletions(-) create mode 100644 sql/updates/auth/2013_02_25_00_auth_misc.sql (limited to 'src') diff --git a/sql/updates/auth/2013_02_25_00_auth_misc.sql b/sql/updates/auth/2013_02_25_00_auth_misc.sql new file mode 100644 index 00000000000..fbbf47f1a23 --- /dev/null +++ b/sql/updates/auth/2013_02_25_00_auth_misc.sql @@ -0,0 +1,14 @@ +-- Add new permission +INSERT INTO `rbac_permissions` (`id`, `name`) VALUES (11, 'Log GM trades'); + +-- Add new role +INSERT INTO `rbac_roles` (`id`, `name`) VALUES (8, 'Log GM trades'); + +-- Add the permission to the role +INSERT INTO `rbac_role_permissions` (`roleId`, `permissionId`) VALUES (8, 11); + +-- Add it to all GM+ groups +INSERT INTO `rbac_group_roles` (`groupId`, `roleId`) VALUES +(2, 8), +(3, 8), +(4, 8); diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h index f6e494e7b70..82b9d74f711 100644 --- a/src/server/game/Accounts/RBAC.h +++ b/src/server/game/Accounts/RBAC.h @@ -58,6 +58,7 @@ enum RBACPermissions RBAC_PERM_MODERATOR_COMMANDS, RBAC_PERM_GAMEMASTER_COMMANDS, RBAC_PERM_ADMINISTRATOR_COMMANDS, + RBAC_PERM_LOG_GM_TRADE, RBAC_PERM_MAX }; diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp index 20f73eeff69..586a42c9f7e 100644 --- a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp +++ b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp @@ -106,12 +106,12 @@ void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry* auction, SQLTransaction& { bidderAccId = bidder->GetSession()->GetAccountId(); bidderName = bidder->GetName(); - logGmTrade = !AccountMgr::IsPlayerAccount(bidder->GetSession()->GetAccountId()); + logGmTrade = bidder->GetSession()->HasPermission(RBAC_PERM_LOG_GM_TRADE); } else { bidderAccId = sObjectMgr->GetPlayerAccountIdByGUID(bidderGuid); - logGmTrade = !AccountMgr::IsPlayerAccount(AccountMgr::GetSecurity(bidderAccId, realmID)); + logGmTrade = AccountMgr::HasPermission(bidderAccId, RBAC_PERM_LOG_GM_TRADE, realmID); if (logGmTrade && !sObjectMgr->GetPlayerNameByGUID(bidderGuid, bidderName)) bidderName = sObjectMgr->GetTrinityStringForDBCLocale(LANG_UNKNOWN); diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp index c424e5d3ffe..a1ab1b22b08 100644 --- a/src/server/game/Guilds/Guild.cpp +++ b/src/server/game/Guilds/Guild.cpp @@ -983,12 +983,15 @@ void Guild::BankMoveItemData::LogBankEvent(SQLTransaction& trans, MoveItemData* void Guild::BankMoveItemData::LogAction(MoveItemData* pFrom) const { MoveItemData::LogAction(pFrom); - if (!pFrom->IsBank() && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE) && !AccountMgr::IsPlayerAccount(m_pPlayer->GetSession()->GetSecurity())) // TODO: move to scripts + if (!pFrom->IsBank() && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE) && + m_pPlayer->GetSession()->HasPermission(RBAC_PERM_LOG_GM_TRADE)) + { sLog->outCommand(m_pPlayer->GetSession()->GetAccountId(), "GM %s (Account: %u) deposit item: %s (Entry: %d Count: %u) to guild bank (Guild ID: %u)", m_pPlayer->GetName().c_str(), m_pPlayer->GetSession()->GetAccountId(), pFrom->GetItem()->GetTemplate()->Name1.c_str(), pFrom->GetItem()->GetEntry(), pFrom->GetItem()->GetCount(), m_pGuild->GetId()); + } } Item* Guild::BankMoveItemData::_StoreItem(SQLTransaction& trans, BankTab* pTab, Item* pItem, ItemPosCount& pos, bool clone) const @@ -1729,7 +1732,7 @@ void Guild::HandleMemberDepositMoney(WorldSession* session, uint32 amount) std::string aux = ByteArrayToHexStr(reinterpret_cast(&amount), 8, true); _BroadcastEvent(GE_BANK_MONEY_CHANGED, 0, aux.c_str()); - if (!AccountMgr::IsPlayerAccount(player->GetSession()->GetSecurity()) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) + if (player->GetSession()->HasPermission(RBAC_PERM_LOG_GM_TRADE) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) { sLog->outCommand(player->GetSession()->GetAccountId(), "GM %s (Account: %u) deposit money (Amount: %u) to guild bank (Guild ID %u)", diff --git a/src/server/game/Handlers/MailHandler.cpp b/src/server/game/Handlers/MailHandler.cpp index 14b6df23061..787cd93576c 100644 --- a/src/server/game/Handlers/MailHandler.cpp +++ b/src/server/game/Handlers/MailHandler.cpp @@ -256,12 +256,13 @@ void WorldSession::HandleSendMail(WorldPacket& recvData) if (items_count > 0 || money > 0) { + bool log = sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE) && HasPermission(RBAC_PERM_LOG_GM_TRADE); if (items_count > 0) { for (uint8 i = 0; i < items_count; ++i) { Item* item = items[i]; - if (!AccountMgr::IsPlayerAccount(GetSecurity()) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) + if (log) { sLog->outCommand(GetAccountId(), "GM %s (Account: %u) mail item: %s (Entry: %u Count: %u) to player: %s (Account: %u)", GetPlayerName().c_str(), GetAccountId(), item->GetTemplate()->Name1.c_str(), item->GetEntry(), item->GetCount(), receiver.c_str(), rc_account); @@ -281,7 +282,7 @@ void WorldSession::HandleSendMail(WorldPacket& recvData) needItemDelay = player->GetSession()->GetAccountId() != rc_account; } - if (money > 0 && !AccountMgr::IsPlayerAccount(GetSecurity()) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) + if (log && money > 0) { sLog->outCommand(GetAccountId(), "GM %s (Account: %u) mail money: %u to player: %s (Account: %u)", GetPlayerName().c_str(), GetAccountId(), money, receiver.c_str(), rc_account); @@ -462,7 +463,7 @@ void WorldSession::HandleMailTakeItem(WorldPacket& recvData) uint32 sender_accId = 0; - if (!AccountMgr::IsPlayerAccount(GetSecurity()) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) + if (HasPermission(RBAC_PERM_LOG_GM_TRADE) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) { std::string sender_name; if (receive) diff --git a/src/server/game/Handlers/TradeHandler.cpp b/src/server/game/Handlers/TradeHandler.cpp index bb31b5c1dc8..63ab6d27701 100644 --- a/src/server/game/Handlers/TradeHandler.cpp +++ b/src/server/game/Handlers/TradeHandler.cpp @@ -152,7 +152,7 @@ void WorldSession::moveItems(Item* myItems[], Item* hisItems[]) { // logging sLog->outDebug(LOG_FILTER_NETWORKIO, "partner storing: %u", myItems[i]->GetGUIDLow()); - if (!AccountMgr::IsPlayerAccount(_player->GetSession()->GetSecurity()) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) + if (HasPermission(RBAC_PERM_LOG_GM_TRADE) && sWorld->getBoolConfig(CONFIG_GM_LOG_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(), @@ -170,7 +170,7 @@ void WorldSession::moveItems(Item* myItems[], Item* hisItems[]) { // logging sLog->outDebug(LOG_FILTER_NETWORKIO, "player storing: %u", hisItems[i]->GetGUIDLow()); - if (!AccountMgr::IsPlayerAccount(trader->GetSession()->GetSecurity()) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) + if (HasPermission(RBAC_PERM_LOG_GM_TRADE) && sWorld->getBoolConfig(CONFIG_GM_LOG_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(), @@ -473,16 +473,17 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/) moveItems(myItems, hisItems); // logging money - if (sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) + if (HasPermission(RBAC_PERM_LOG_GM_TRADE) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) { - if (!AccountMgr::IsPlayerAccount(_player->GetSession()->GetSecurity()) && my_trade->GetMoney() > 0) + if (my_trade->GetMoney() > 0) { sLog->outCommand(_player->GetSession()->GetAccountId(), "GM %s (Account: %u) give money (Amount: %u) to player: %s (Account: %u)", _player->GetName().c_str(), _player->GetSession()->GetAccountId(), my_trade->GetMoney(), trader->GetName().c_str(), trader->GetSession()->GetAccountId()); } - if (!AccountMgr::IsPlayerAccount(trader->GetSession()->GetSecurity()) && his_trade->GetMoney() > 0) + + if (his_trade->GetMoney() > 0) { sLog->outCommand(trader->GetSession()->GetAccountId(), "GM %s (Account: %u) give money (Amount: %u) to player: %s (Account: %u)", trader->GetName().c_str(), trader->GetSession()->GetAccountId(), diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index f5504f8b7c1..9d3ec6630e5 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -2763,7 +2763,7 @@ void Spell::EffectEnchantItemPerm(SpellEffIndex effIndex) if (!item_owner) return; - if (item_owner != p_caster && !AccountMgr::IsPlayerAccount(p_caster->GetSession()->GetSecurity()) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) + if (item_owner != p_caster && p_caster->GetSession()->HasPermission(RBAC_PERM_LOG_GM_TRADE) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) { sLog->outCommand(p_caster->GetSession()->GetAccountId(), "GM %s (Account: %u) enchanting(perm): %s (Entry: %d) for player: %s (Account: %u)", p_caster->GetName().c_str(), p_caster->GetSession()->GetAccountId(), @@ -2828,7 +2828,7 @@ void Spell::EffectEnchantItemPrismatic(SpellEffIndex effIndex) if (!item_owner) return; - if (item_owner != p_caster && !AccountMgr::IsPlayerAccount(p_caster->GetSession()->GetSecurity()) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) + if (item_owner != p_caster && p_caster->GetSession()->HasPermission(RBAC_PERM_LOG_GM_TRADE) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) { sLog->outCommand(p_caster->GetSession()->GetAccountId(), "GM %s (Account: %u) enchanting(perm): %s (Entry: %d) for player: %s (Account: %u)", p_caster->GetName().c_str(), p_caster->GetSession()->GetAccountId(), @@ -2962,7 +2962,7 @@ void Spell::EffectEnchantItemTmp(SpellEffIndex effIndex) if (!item_owner) return; - if (item_owner != p_caster && !AccountMgr::IsPlayerAccount(p_caster->GetSession()->GetSecurity()) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) + if (item_owner != p_caster && p_caster->GetSession()->HasPermission(RBAC_PERM_LOG_GM_TRADE) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) { sLog->outCommand(p_caster->GetSession()->GetAccountId(), "GM %s (Account: %u) enchanting(temp): %s (Entry: %d) for player: %s (Account: %u)", p_caster->GetName().c_str(), p_caster->GetSession()->GetAccountId(), -- cgit v1.2.3 From 1638092f18c0fd13e4e092a5d6eb23becfb8ae23 Mon Sep 17 00:00:00 2001 From: Spp Date: Mon, 25 Feb 2013 11:50:13 +0100 Subject: Core/RBAC: Create 'Skip instance required bosses check' permission --- sql/updates/auth/2013_02_25_01_auth_misc.sql | 14 ++++++++++++++ src/server/game/Accounts/RBAC.h | 1 + .../IcecrownCitadel/instance_icecrown_citadel.cpp | 2 +- 3 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 sql/updates/auth/2013_02_25_01_auth_misc.sql (limited to 'src') diff --git a/sql/updates/auth/2013_02_25_01_auth_misc.sql b/sql/updates/auth/2013_02_25_01_auth_misc.sql new file mode 100644 index 00000000000..0cd63bf2062 --- /dev/null +++ b/sql/updates/auth/2013_02_25_01_auth_misc.sql @@ -0,0 +1,14 @@ +-- Add new permission +INSERT INTO `rbac_permissions` (`id`, `name`) VALUES (13, 'Skip Instance required bosses check'); + +-- Add new role +INSERT INTO `rbac_roles` (`id`, `name`) VALUES (9, 'Skip Instance required bosses check'); + +-- Add the permission to the role +INSERT INTO `rbac_role_permissions` (`roleId`, `permissionId`) VALUES (9, 13); + +-- Add it to all GM+ groups +INSERT INTO `rbac_group_roles` (`groupId`, `roleId`) VALUES +(2, 9), +(3, 9), +(4, 9); diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h index 82b9d74f711..27cfb8058d5 100644 --- a/src/server/game/Accounts/RBAC.h +++ b/src/server/game/Accounts/RBAC.h @@ -59,6 +59,7 @@ enum RBACPermissions RBAC_PERM_GAMEMASTER_COMMANDS, RBAC_PERM_ADMINISTRATOR_COMMANDS, RBAC_PERM_LOG_GM_TRADE, + RBAC_PERM_SKIP_CHECK_INSTANCE_REQUIRED_BOSSES = 13, RBAC_PERM_MAX }; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp index 593d9586156..db4ab2f32d2 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp @@ -954,7 +954,7 @@ class instance_icecrown_citadel : public InstanceMapScript bool CheckRequiredBosses(uint32 bossId, Player const* player = NULL) const { - if (player && AccountMgr::IsGMAccount(player->GetSession()->GetSecurity())) + if (player && player->GetSession()->HasPermission(RBAC_PERM_SKIP_CHECK_INSTANCE_REQUIRED_BOSSES)) return true; switch (bossId) -- cgit v1.2.3 From e6087b5563916cf21a949652ce62e1439d7f1b78 Mon Sep 17 00:00:00 2001 From: Spp Date: Mon, 25 Feb 2013 12:10:16 +0100 Subject: Core/RBAC: Create new permission 'Be assigned ticket' --- sql/updates/auth/2013_02_25_02_auth_misc.sql | 14 ++++++++++++++ src/server/game/Accounts/RBAC.h | 23 ++++++++++++----------- src/server/scripts/Commands/cs_ticket.cpp | 12 +++++------- 3 files changed, 31 insertions(+), 18 deletions(-) create mode 100644 sql/updates/auth/2013_02_25_02_auth_misc.sql (limited to 'src') diff --git a/sql/updates/auth/2013_02_25_02_auth_misc.sql b/sql/updates/auth/2013_02_25_02_auth_misc.sql new file mode 100644 index 00000000000..5695d308cf4 --- /dev/null +++ b/sql/updates/auth/2013_02_25_02_auth_misc.sql @@ -0,0 +1,14 @@ +-- Add new permission +INSERT INTO `rbac_permissions` (`id`, `name`) VALUES (32, 'Can be assigned tickets with .assign ticket command'); + +-- Add new role +INSERT INTO `rbac_roles` (`id`, `name`) VALUES (10, 'Ticket management'); + +-- Add the permission to the role +INSERT INTO `rbac_role_permissions` (`roleId`, `permissionId`) VALUES (10, 32); + +-- Add it to all GM+ groups +INSERT INTO `rbac_group_roles` (`groupId`, `roleId`) VALUES +(2, 10), +(3, 10), +(4, 10); diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h index 27cfb8058d5..6c605d9a108 100644 --- a/src/server/game/Accounts/RBAC.h +++ b/src/server/game/Accounts/RBAC.h @@ -48,18 +48,19 @@ enum RBACPermissions { - RBAC_PERM_INSTANT_LOGOUT = 1, - RBAC_PERM_SKIP_QUEUE, - RBAC_PERM_JOIN_NORMAL_BG, - RBAC_PERM_JOIN_RANDOM_BG, - RBAC_PERM_JOIN_ARENAS, - RBAC_PERM_JOIN_DUNGEON_FINDER, - RBAC_PERM_PLAYER_COMMANDS, - RBAC_PERM_MODERATOR_COMMANDS, - RBAC_PERM_GAMEMASTER_COMMANDS, - RBAC_PERM_ADMINISTRATOR_COMMANDS, - RBAC_PERM_LOG_GM_TRADE, + RBAC_PERM_INSTANT_LOGOUT = 1, + RBAC_PERM_SKIP_QUEUE = 2, + RBAC_PERM_JOIN_NORMAL_BG = 3, + RBAC_PERM_JOIN_RANDOM_BG = 4, + RBAC_PERM_JOIN_ARENAS = 5, + RBAC_PERM_JOIN_DUNGEON_FINDER = 6, + RBAC_PERM_PLAYER_COMMANDS = 7, + RBAC_PERM_MODERATOR_COMMANDS = 8, + RBAC_PERM_GAMEMASTER_COMMANDS = 9, + RBAC_PERM_ADMINISTRATOR_COMMANDS = 10, + RBAC_PERM_LOG_GM_TRADE = 11, RBAC_PERM_SKIP_CHECK_INSTANCE_REQUIRED_BOSSES = 13, + RBAC_PERM_COMMANDS_BE_ASSIGNED_TICKET = 32, RBAC_PERM_MAX }; diff --git a/src/server/scripts/Commands/cs_ticket.cpp b/src/server/scripts/Commands/cs_ticket.cpp index aee01f47581..958eb1709d5 100644 --- a/src/server/scripts/Commands/cs_ticket.cpp +++ b/src/server/scripts/Commands/cs_ticket.cpp @@ -95,18 +95,16 @@ public: return true; } - // Get target information - uint64 targetGuid = sObjectMgr->GetPlayerGUIDByName(target.c_str()); - uint64 targetAccountId = sObjectMgr->GetPlayerAccountIdByGUID(targetGuid); - uint32 targetGmLevel = AccountMgr::GetSecurity(targetAccountId, realmID); - + uint32 accountId = AccountMgr::GetId(target); // Target must exist and have administrative rights - if (!targetGuid || AccountMgr::IsPlayerAccount(targetGmLevel)) + if (!AccountMgr::HasPermission(accountId, RBAC_PERM_COMMANDS_BE_ASSIGNED_TICKET, realmID)) { handler->SendSysMessage(LANG_COMMAND_TICKETASSIGNERROR_A); return true; } + uint64 targetGuid = sObjectMgr->GetPlayerGUIDByName(target); + // If already assigned, leave if (ticket->IsAssignedTo(targetGuid)) { @@ -125,7 +123,7 @@ public: // Assign ticket SQLTransaction trans = SQLTransaction(NULL); - ticket->SetAssignedTo(targetGuid, AccountMgr::IsAdminAccount(targetGmLevel)); + ticket->SetAssignedTo(targetGuid, AccountMgr::IsAdminAccount(AccountMgr::GetSecurity(accountId, realmID))); ticket->SaveToDB(trans); sTicketMgr->UpdateLastChange(); -- cgit v1.2.3 From cb0456fedcc555097ec55c5c6df79422515aff85 Mon Sep 17 00:00:00 2001 From: Spp Date: Mon, 25 Feb 2013 12:23:02 +0100 Subject: Core/RBAC: Create new permissions 'Instant .save', 'Allow params with .unstuck', 'Full HP after resurrect' --- sql/updates/auth/2013_02_25_03_auth_misc.sql | 32 ++++++++++++++++++++++++++++ src/server/game/Accounts/RBAC.h | 3 +++ src/server/scripts/Commands/cs_misc.cpp | 8 +++---- 3 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 sql/updates/auth/2013_02_25_03_auth_misc.sql (limited to 'src') diff --git a/sql/updates/auth/2013_02_25_03_auth_misc.sql b/sql/updates/auth/2013_02_25_03_auth_misc.sql new file mode 100644 index 00000000000..cf843b9769d --- /dev/null +++ b/sql/updates/auth/2013_02_25_03_auth_misc.sql @@ -0,0 +1,32 @@ +-- Add new permissions +DELETE FROM `rbac_permissions` WHERE `id` IN (30, 31, 38); +INSERT INTO `rbac_permissions` (`id`, `name`) VALUES +(30, 'Save character without delay with .save command'), +(31, 'Use params with .unstuck command'), +(38, 'Resurrect with full Health Points'); + +-- Add new role +DELETE FROM `rbac_roles` WHERE `id` IN (11, 12, 13); +INSERT INTO `rbac_roles` (`id`, `name`) VALUES +(11, 'Instant .save'), +(12, 'Allow params with .unstuck'), +(13, 'Full HP after resurrect'); + +-- Add the permission to the role +DELETE FROM `rbac_role_permissions` WHERE `roleId` IN (11, 12, 13); +INSERT INTO `rbac_role_permissions` (`roleId`, `permissionId`) VALUES +(11, 30), +(12, 31), +(13, 38); + +-- Add it to all GM+ groups +INSERT INTO `rbac_group_roles` (`groupId`, `roleId`) VALUES +(2, 11), +(3, 11), +(4, 11), +(2, 12), +(3, 12), +(4, 12), +(2, 13), +(3, 13), +(4, 13); diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h index 6c605d9a108..1c2cd9dd27a 100644 --- a/src/server/game/Accounts/RBAC.h +++ b/src/server/game/Accounts/RBAC.h @@ -60,7 +60,10 @@ enum RBACPermissions RBAC_PERM_ADMINISTRATOR_COMMANDS = 10, RBAC_PERM_LOG_GM_TRADE = 11, RBAC_PERM_SKIP_CHECK_INSTANCE_REQUIRED_BOSSES = 13, + RBAC_PERM_COMMANDS_SAVE_WITHOUT_DELAY = 30, + RBAC_PERM_COMMANDS_USE_UNSTUCK_WITH_ARGS = 31, RBAC_PERM_COMMANDS_BE_ASSIGNED_TICKET = 32, + RBAC_PERM_RESURRECT_WITH_FULL_HPS = 38, RBAC_PERM_MAX }; diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index cacefea7b85..4cdc1e0d9ce 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -678,7 +678,7 @@ public: if (target) { - target->ResurrectPlayer(!AccountMgr::IsPlayerAccount(target->GetSession()->GetSecurity()) ? 1.0f : 0.5f); + target->ResurrectPlayer(target->GetSession()->HasPermission(RBAC_PERM_RESURRECT_WITH_FULL_HPS) ? 1.0f : 0.5f); target->SpawnCorpseBones(); target->SaveToDB(); } @@ -881,7 +881,7 @@ public: Player* player = handler->GetSession()->GetPlayer(); // save GM account without delay and output message - if (!AccountMgr::IsPlayerAccount(handler->GetSession()->GetSecurity())) + if (handler->GetSession()->HasPermission(RBAC_PERM_COMMANDS_SAVE_WITHOUT_DELAY)) { if (Player* target = handler->getSelectedPlayer()) target->SaveToDB(); @@ -938,8 +938,8 @@ public: static bool HandleUnstuckCommand(ChatHandler* handler, char const* args) { - //No args required for players - if (handler->GetSession() && AccountMgr::IsPlayerAccount(handler->GetSession()->GetSecurity())) + // No args required for players + if (handler->GetSession() && !handler->GetSession()->HasPermission(RBAC_PERM_COMMANDS_USE_UNSTUCK_WITH_ARGS)) { // 7355: "Stuck" if (Player* player = handler->GetSession()->GetPlayer()) -- cgit v1.2.3 From 367d3ccc4f4ce3977475e398b812d98dec8cc5f0 Mon Sep 17 00:00:00 2001 From: Spp Date: Mon, 25 Feb 2013 12:36:20 +0100 Subject: Core/RBAC: Create new permissions 'Use staff badge in chat' and 'Check if should appear in .gm ingame command' --- sql/updates/auth/2013_02_25_04_auth_misc.sql | 27 ++++++++++++++++ src/server/game/Accounts/RBAC.h | 2 ++ src/server/scripts/Commands/cs_gm.cpp | 46 +++++++++++++++------------- 3 files changed, 54 insertions(+), 21 deletions(-) create mode 100644 sql/updates/auth/2013_02_25_04_auth_misc.sql (limited to 'src') diff --git a/sql/updates/auth/2013_02_25_04_auth_misc.sql b/sql/updates/auth/2013_02_25_04_auth_misc.sql new file mode 100644 index 00000000000..accacbb19d8 --- /dev/null +++ b/sql/updates/auth/2013_02_25_04_auth_misc.sql @@ -0,0 +1,27 @@ +-- Add new permissions +DELETE FROM `rbac_permissions` WHERE `id` IN (34, 37); +INSERT INTO `rbac_permissions` (`id`, `name`) VALUES +(34, 'Check if shoul appear in list using .gm ingame command'), +(37, 'Use staff badge in chat'); + +-- Add new role +DELETE FROM `rbac_roles` WHERE `id` IN (14, 15); +INSERT INTO `rbac_roles` (`id`, `name`) VALUES +(14, 'Appear in GM ingame list'), +(15, 'Use staff badge in chat'); + +-- Add the permission to the role +DELETE FROM `rbac_role_permissions` WHERE `roleId` IN (14, 15); +INSERT INTO `rbac_role_permissions` (`roleId`, `permissionId`) VALUES +(14, 34), +(15, 37); + +-- Add it to all GM+ groups +DELETE FROM `rbac_role_permissions` WHERE `roleId` IN (14, 15); +INSERT INTO `rbac_group_roles` (`groupId`, `roleId`) VALUES +(2, 14), +(3, 14), +(4, 14), +(2, 15), +(3, 15), +(4, 15); diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h index 1c2cd9dd27a..80a493febe0 100644 --- a/src/server/game/Accounts/RBAC.h +++ b/src/server/game/Accounts/RBAC.h @@ -63,6 +63,8 @@ enum RBACPermissions RBAC_PERM_COMMANDS_SAVE_WITHOUT_DELAY = 30, RBAC_PERM_COMMANDS_USE_UNSTUCK_WITH_ARGS = 31, RBAC_PERM_COMMANDS_BE_ASSIGNED_TICKET = 32, + RBAC_PERM_COMMANDS_APPEAR_IN_GM_LIST = 34, + RBAC_PERM_CHAT_USE_STAFF_BADGE = 37, RBAC_PERM_RESURRECT_WITH_FULL_HPS = 38, RBAC_PERM_MAX }; diff --git a/src/server/scripts/Commands/cs_gm.cpp b/src/server/scripts/Commands/cs_gm.cpp index 932bb562f11..168a5ec60b8 100644 --- a/src/server/scripts/Commands/cs_gm.cpp +++ b/src/server/scripts/Commands/cs_gm.cpp @@ -59,30 +59,32 @@ public: // Enables or disables hiding of the staff badge static bool HandleGMChatCommand(ChatHandler* handler, char const* args) { - if (!*args) + if (WorldSession* session = handler->GetSession()) { - WorldSession* session = handler->GetSession(); - if (!AccountMgr::IsPlayerAccount(session->GetSecurity()) && session->GetPlayer()->isGMChat()) - session->SendNotification(LANG_GM_CHAT_ON); - else - session->SendNotification(LANG_GM_CHAT_OFF); - return true; - } + if (!*args) + { + if (session->HasPermission(RBAC_PERM_CHAT_USE_STAFF_BADGE) && session->GetPlayer()->isGMChat()) + session->SendNotification(LANG_GM_CHAT_ON); + else + session->SendNotification(LANG_GM_CHAT_OFF); + return true; + } - std::string param = (char*)args; + std::string param = (char*)args; - if (param == "on") - { - handler->GetSession()->GetPlayer()->SetGMChat(true); - handler->GetSession()->SendNotification(LANG_GM_CHAT_ON); - return true; - } + if (param == "on") + { + session->GetPlayer()->SetGMChat(true); + session->SendNotification(LANG_GM_CHAT_ON); + return true; + } - if (param == "off") - { - handler->GetSession()->GetPlayer()->SetGMChat(false); - handler->GetSession()->SendNotification(LANG_GM_CHAT_OFF); - return true; + if (param == "off") + { + session->GetPlayer()->SetGMChat(false); + session->SendNotification(LANG_GM_CHAT_OFF); + return true; + } } handler->SendSysMessage(LANG_USE_BOL); @@ -126,7 +128,9 @@ public: for (HashMapHolder::MapType::const_iterator itr = m.begin(); itr != m.end(); ++itr) { AccountTypes itrSec = itr->second->GetSession()->GetSecurity(); - if ((itr->second->isGameMaster() || (!AccountMgr::IsPlayerAccount(itrSec) && itrSec <= AccountTypes(sWorld->getIntConfig(CONFIG_GM_LEVEL_IN_GM_LIST)))) && + if ((itr->second->isGameMaster() || + (itr->second->GetSession()->HasPermission(RBAC_PERM_COMMANDS_APPEAR_IN_GM_LIST) && + itrSec <= AccountTypes(sWorld->getIntConfig(CONFIG_GM_LEVEL_IN_GM_LIST)))) && (!handler->GetSession() || itr->second->IsVisibleGloballyFor(handler->GetSession()->GetPlayer()))) { if (first) -- cgit v1.2.3 From 54f7cc326f9aaf986a2fc1e20c2b03c95e020977 Mon Sep 17 00:00:00 2001 From: Spp Date: Mon, 25 Feb 2013 12:45:10 +0100 Subject: Core/RBAC: Create new permission 'Receive global GM messages/texts' --- sql/updates/auth/2013_02_25_04_auth_misc.sql | 2 +- sql/updates/auth/2013_02_25_05_auth_misc.sql | 18 ++++++++++++++ src/server/game/Accounts/RBAC.h | 1 + src/server/game/World/World.cpp | 37 +++++++++++++++++----------- 4 files changed, 42 insertions(+), 16 deletions(-) create mode 100644 sql/updates/auth/2013_02_25_05_auth_misc.sql (limited to 'src') diff --git a/sql/updates/auth/2013_02_25_04_auth_misc.sql b/sql/updates/auth/2013_02_25_04_auth_misc.sql index accacbb19d8..faaee3582ea 100644 --- a/sql/updates/auth/2013_02_25_04_auth_misc.sql +++ b/sql/updates/auth/2013_02_25_04_auth_misc.sql @@ -1,7 +1,7 @@ -- Add new permissions DELETE FROM `rbac_permissions` WHERE `id` IN (34, 37); INSERT INTO `rbac_permissions` (`id`, `name`) VALUES -(34, 'Check if shoul appear in list using .gm ingame command'), +(34, 'Check if should appear in list using .gm ingame command'), (37, 'Use staff badge in chat'); -- Add new role diff --git a/sql/updates/auth/2013_02_25_05_auth_misc.sql b/sql/updates/auth/2013_02_25_05_auth_misc.sql new file mode 100644 index 00000000000..e3ee3f00572 --- /dev/null +++ b/sql/updates/auth/2013_02_25_05_auth_misc.sql @@ -0,0 +1,18 @@ +-- Add new permission +DELETE FROM `rbac_permissions` WHERE `id` = 44; +INSERT INTO `rbac_permissions` (`id`, `name`) VALUES (44, 'Receive global GM messages/texts'); + +-- Add new role +DELETE FROM `rbac_roles` WHERE `id` = 16; +INSERT INTO `rbac_roles` (`id`, `name`) VALUES (16, 'Receive global GM messages/texts'); + +-- Add the permission to the role +DELETE FROM `rbac_role_permissions` WHERE `roleId` = 16; +INSERT INTO `rbac_role_permissions` (`roleId`, `permissionId`) VALUES (16, 44); + +-- Add it to all GM+ groups +DELETE FROM `rbac_group_roles` WHERE `roleId` = 16; +INSERT INTO `rbac_group_roles` (`groupId`, `roleId`) VALUES +(2, 16), +(3, 16), +(4, 16); diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h index 80a493febe0..0bc2f65a053 100644 --- a/src/server/game/Accounts/RBAC.h +++ b/src/server/game/Accounts/RBAC.h @@ -66,6 +66,7 @@ enum RBACPermissions RBAC_PERM_COMMANDS_APPEAR_IN_GM_LIST = 34, RBAC_PERM_CHAT_USE_STAFF_BADGE = 37, RBAC_PERM_RESURRECT_WITH_FULL_HPS = 38, + RBAC_PERM_RECEIVE_GLOBAL_GM_TEXTMESSAGE = 44, RBAC_PERM_MAX }; diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 32ee21a7ca2..955f3b7b99f 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -2118,18 +2118,21 @@ void World::SendGlobalMessage(WorldPacket* packet, WorldSession* self, uint32 te /// Send a packet to all GMs (except self if mentioned) void World::SendGlobalGMMessage(WorldPacket* packet, WorldSession* self, uint32 team) { - SessionMap::iterator itr; - for (itr = m_sessions.begin(); itr != m_sessions.end(); ++itr) + for (SessionMap::const_iterator itr = m_sessions.begin(); itr != m_sessions.end(); ++itr) { - if (itr->second && - itr->second->GetPlayer() && - itr->second->GetPlayer()->IsInWorld() && - itr->second != self && - !AccountMgr::IsPlayerAccount(itr->second->GetSecurity()) && - (team == 0 || itr->second->GetPlayer()->GetTeam() == team)) - { - itr->second->SendPacket(packet); - } + // 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)) + continue; + + // Player should be in world + Player* player = session->GetPlayer(); + if (!player || !player->IsInWorld()) + continue; + + // Send only to same team, if team is given + if (!team || player->GetTeam() == team) + session->SendPacket(packet); } } @@ -2217,15 +2220,19 @@ void World::SendGMText(int32 string_id, ...) Trinity::WorldWorldTextBuilder wt_builder(string_id, &ap); Trinity::LocalizedPacketListDo wt_do(wt_builder); - for (SessionMap::iterator itr = m_sessions.begin(); itr != m_sessions.end(); ++itr) + for (SessionMap::const_iterator itr = m_sessions.begin(); itr != m_sessions.end(); ++itr) { - if (!itr->second || !itr->second->GetPlayer() || !itr->second->GetPlayer()->IsInWorld()) + // Session should have permissions to receive global gm messages + WorldSession* session = itr->second; + if (!session || !session->HasPermission(RBAC_PERM_RECEIVE_GLOBAL_GM_TEXTMESSAGE)) continue; - if (AccountMgr::IsPlayerAccount(itr->second->GetSecurity())) + // Player should be in world + Player* player = session->GetPlayer(); + if (!player || !player->IsInWorld()) continue; - wt_do(itr->second->GetPlayer()); + wt_do(player); } va_end(ap); -- cgit v1.2.3 From e99dd159152dcb8093134f025e29901b17cb98a8 Mon Sep 17 00:00:00 2001 From: Spp Date: Mon, 25 Feb 2013 12:50:50 +0100 Subject: Core/RBAC: Create new permission 'Skip over-speed ping check' --- sql/updates/auth/2013_02_25_06_auth_misc.sql | 18 ++++++++++++++++++ src/server/game/Accounts/RBAC.h | 1 + src/server/game/Server/WorldSocket.cpp | 2 +- 3 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 sql/updates/auth/2013_02_25_06_auth_misc.sql (limited to 'src') diff --git a/sql/updates/auth/2013_02_25_06_auth_misc.sql b/sql/updates/auth/2013_02_25_06_auth_misc.sql new file mode 100644 index 00000000000..92eae3d782d --- /dev/null +++ b/sql/updates/auth/2013_02_25_06_auth_misc.sql @@ -0,0 +1,18 @@ +-- Add new permission +DELETE FROM `rbac_permissions` WHERE `id` = 23; +INSERT INTO `rbac_permissions` (`id`, `name`) VALUES (23, 'Skip over-speed ping check'); + +-- Add new role +DELETE FROM `rbac_roles` WHERE `id` = 17; +INSERT INTO `rbac_roles` (`id`, `name`) VALUES (17, 'Skip over-speed ping check'); + +-- Add the permission to the role +DELETE FROM `rbac_role_permissions` WHERE `roleId` = 17; +INSERT INTO `rbac_role_permissions` (`roleId`, `permissionId`) VALUES (17, 23); + +-- Add it to all GM+ groups +DELETE FROM `rbac_group_roles` WHERE `roleId` = 17; +INSERT INTO `rbac_group_roles` (`groupId`, `roleId`) VALUES +(2, 17), +(3, 17), +(4, 17); diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h index 0bc2f65a053..d0cf1e0e95b 100644 --- a/src/server/game/Accounts/RBAC.h +++ b/src/server/game/Accounts/RBAC.h @@ -60,6 +60,7 @@ enum RBACPermissions RBAC_PERM_ADMINISTRATOR_COMMANDS = 10, RBAC_PERM_LOG_GM_TRADE = 11, RBAC_PERM_SKIP_CHECK_INSTANCE_REQUIRED_BOSSES = 13, + RBAC_PERM_SKIP_CHECK_OVERSPEED_PING = 23, RBAC_PERM_COMMANDS_SAVE_WITHOUT_DELAY = 30, RBAC_PERM_COMMANDS_USE_UNSTUCK_WITH_ARGS = 31, RBAC_PERM_COMMANDS_BE_ASSIGNED_TICKET = 32, diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp index de5dd1dd98b..128175d785b 100644 --- a/src/server/game/Server/WorldSocket.cpp +++ b/src/server/game/Server/WorldSocket.cpp @@ -980,7 +980,7 @@ int WorldSocket::HandlePing (WorldPacket& recvPacket) { ACE_GUARD_RETURN (LockType, Guard, m_SessionLock, -1); - if (m_Session && AccountMgr::IsPlayerAccount(m_Session->GetSecurity())) + if (m_Session && !m_Session->HasPermission(RBAC_PERM_SKIP_CHECK_OVERSPEED_PING)) { sLog->outError(LOG_FILTER_NETWORKIO, "WorldSocket::HandlePing: %s kicked for over-speed pings (address: %s)", m_Session->GetPlayerInfo().c_str(), GetRemoteAddress().c_str()); -- cgit v1.2.3 From ea2e6052b2edc730d27e13e62b83f276d2dc1687 Mon Sep 17 00:00:00 2001 From: Spp Date: Mon, 25 Feb 2013 12:55:37 +0100 Subject: Core/RBAC: Create new permissions 'Allow to use CMSG_WORLD_TELEPORT opcode' and 'Allow to use CMSG_WHOIS opcode' --- sql/updates/auth/2013_02_25_07_auth_misc.sql | 21 +++++++++++++++++++++ src/server/game/Accounts/RBAC.h | 2 ++ src/server/game/Handlers/MiscHandler.cpp | 4 ++-- 3 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 sql/updates/auth/2013_02_25_07_auth_misc.sql (limited to 'src') diff --git a/sql/updates/auth/2013_02_25_07_auth_misc.sql b/sql/updates/auth/2013_02_25_07_auth_misc.sql new file mode 100644 index 00000000000..2416f08280c --- /dev/null +++ b/sql/updates/auth/2013_02_25_07_auth_misc.sql @@ -0,0 +1,21 @@ +-- Add new permissions +DELETE FROM `rbac_permissions` WHERE `id` IN (42, 43); +INSERT INTO `rbac_permissions` (`id`, `name`) VALUES +(42, 'Allows to use CMSG_WORLD_TELEPORT opcode'), +(43, 'Allows to use CMSG_WHOIS opcode'); + +-- Add new role +DELETE FROM `rbac_roles` WHERE `id` = 18; +INSERT INTO `rbac_roles` (`id`, `name`) VALUES +(18, 'Allows Admin Opcodes'); + +-- Add the permission to the role +DELETE FROM `rbac_role_permissions` WHERE `roleId` = 18; +INSERT INTO `rbac_role_permissions` (`roleId`, `permissionId`) VALUES +(18, 42), +(18, 43); + +-- Add it to all GM+ groups +DELETE FROM `rbac_role_permissions` WHERE `roleId` = 18; +INSERT INTO `rbac_group_roles` (`groupId`, `roleId`) VALUES +(4, 18); diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h index d0cf1e0e95b..60dea9cc11a 100644 --- a/src/server/game/Accounts/RBAC.h +++ b/src/server/game/Accounts/RBAC.h @@ -67,6 +67,8 @@ enum RBACPermissions RBAC_PERM_COMMANDS_APPEAR_IN_GM_LIST = 34, RBAC_PERM_CHAT_USE_STAFF_BADGE = 37, RBAC_PERM_RESURRECT_WITH_FULL_HPS = 38, + RBAC_PERM_OPCODE_WORLD_TELEPORT = 42, + RBAC_PERM_OPCODE_WHOIS = 43, RBAC_PERM_RECEIVE_GLOBAL_GM_TEXTMESSAGE = 44, RBAC_PERM_MAX }; diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index 14bff05a412..45cf1d17450 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -1248,7 +1248,7 @@ void WorldSession::HandleWorldTeleportOpcode(WorldPacket& recvData) sLog->outDebug(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 (AccountMgr::IsAdminAccount(GetSecurity())) + if (HasPermission(RBAC_PERM_OPCODE_WORLD_TELEPORT)) GetPlayer()->TeleportTo(mapid, PositionX, PositionY, PositionZ, Orientation); else SendNotification(LANG_YOU_NOT_HAVE_PERMISSION); @@ -1260,7 +1260,7 @@ void WorldSession::HandleWhoisOpcode(WorldPacket& recvData) std::string charname; recvData >> charname; - if (!AccountMgr::IsAdminAccount(GetSecurity())) + if (HasPermission(RBAC_PERM_OPCODE_WHOIS)) { SendNotification(LANG_YOU_NOT_HAVE_PERMISSION); return; -- cgit v1.2.3 From d14cb26e6e608902e10f6935ec3de86962e32738 Mon Sep 17 00:00:00 2001 From: Spp Date: Mon, 25 Feb 2013 13:32:31 +0100 Subject: Core/RBAC: Create new permission 'Two side mail interaction'. In order to send/receive mails from other faction, config option should be enabled and both sender and receiver should have the permission --- sql/updates/auth/2013_02_25_08_auth_misc.sql | 19 ++++ src/server/game/Accounts/RBAC.h | 1 + src/server/game/Handlers/MailHandler.cpp | 131 ++++++++++++++------------- 3 files changed, 87 insertions(+), 64 deletions(-) create mode 100644 sql/updates/auth/2013_02_25_08_auth_misc.sql (limited to 'src') diff --git a/sql/updates/auth/2013_02_25_08_auth_misc.sql b/sql/updates/auth/2013_02_25_08_auth_misc.sql new file mode 100644 index 00000000000..35b12b1eddb --- /dev/null +++ b/sql/updates/auth/2013_02_25_08_auth_misc.sql @@ -0,0 +1,19 @@ +-- Add new permission +DELETE FROM `rbac_permissions` WHERE `id` = 27; +INSERT INTO `rbac_permissions` (`id`, `name`) VALUES (27, 'Send mail to other faction'); + +-- Add new role +DELETE FROM `rbac_roles` WHERE `id` = 19; +INSERT INTO `rbac_roles` (`id`, `name`) VALUES (19, 'Send mail to other faction'); + +-- Add the permission to the role +DELETE FROM `rbac_role_permissions` WHERE `roleId` = 19; +INSERT INTO `rbac_role_permissions` (`roleId`, `permissionId`) VALUES (19, 27); + +-- Add it to all GM+ groups +DELETE FROM `rbac_group_roles` WHERE `roleId` = 19; +INSERT INTO `rbac_group_roles` (`groupId`, `roleId`) VALUES +(1, 19), +(2, 19), +(3, 19), +(4, 19); diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h index 60dea9cc11a..e8ea9a33134 100644 --- a/src/server/game/Accounts/RBAC.h +++ b/src/server/game/Accounts/RBAC.h @@ -61,6 +61,7 @@ enum RBACPermissions RBAC_PERM_LOG_GM_TRADE = 11, RBAC_PERM_SKIP_CHECK_INSTANCE_REQUIRED_BOSSES = 13, RBAC_PERM_SKIP_CHECK_OVERSPEED_PING = 23, + RBAC_PERM_TWO_SIDE_INTERACTION_MAIL = 27, RBAC_PERM_COMMANDS_SAVE_WITHOUT_DELAY = 30, RBAC_PERM_COMMANDS_USE_UNSTUCK_WITH_ARGS = 31, RBAC_PERM_COMMANDS_BE_ASSIGNED_TICKET = 32, diff --git a/src/server/game/Handlers/MailHandler.cpp b/src/server/game/Handlers/MailHandler.cpp index 787cd93576c..3cdd3d854a1 100644 --- a/src/server/game/Handlers/MailHandler.cpp +++ b/src/server/game/Handlers/MailHandler.cpp @@ -32,23 +32,16 @@ void WorldSession::HandleSendMail(WorldPacket& recvData) { uint64 mailbox, unk3; - std::string receiver, subject, body; + std::string receiverName, subject, body; uint32 unk1, unk2, money, COD; uint8 unk4; - recvData >> mailbox; - recvData >> receiver; - - recvData >> subject; - - recvData >> body; - - recvData >> unk1; // stationery? - recvData >> unk2; // 0x00000000 - uint8 items_count; - recvData >> items_count; // attached items count + recvData >> mailbox >> receiverName >> subject >> body + >> unk1 // stationery? + >> unk2 // 0x00000000 + >> items_count; // attached items count - if (items_count > MAX_MAIL_ITEMS) // client limit + if (items_count > MAX_MAIL_ITEMS) // client limit { GetPlayer()->SendMailResult(0, MAIL_SEND, MAIL_ERR_TOO_MANY_ATTACHMENTS); recvData.rfinish(); // set to end to avoid warnings spam @@ -72,7 +65,7 @@ void WorldSession::HandleSendMail(WorldPacket& recvData) if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX)) return; - if (receiver.empty()) + if (receiverName.empty()) return; Player* player = _player; @@ -83,21 +76,26 @@ void WorldSession::HandleSendMail(WorldPacket& recvData) return; } - uint64 rc = 0; - if (normalizePlayerName(receiver)) - rc = sObjectMgr->GetPlayerGUIDByName(receiver); + uint64 receiverGuid = 0; + if (normalizePlayerName(receiverName)) + receiverGuid = sObjectMgr->GetPlayerGUIDByName(receiverName); - if (!rc) + if (!receiverGuid) { - sLog->outInfo(LOG_FILTER_NETWORKIO, "Player %u is sending mail to %s (GUID: not existed!) with subject %s and body %s includes %u items, %u copper and %u COD copper with unk1 = %u, unk2 = %u", - player->GetGUIDLow(), receiver.c_str(), subject.c_str(), body.c_str(), items_count, money, COD, unk1, unk2); + sLog->outInfo(LOG_FILTER_NETWORKIO, "Player %u is sending mail to %s (GUID: not existed!) with subject %s " + "and body %s includes %u items, %u copper and %u COD copper with unk1 = %u, unk2 = %u", + player->GetGUIDLow(), receiverName.c_str(), subject.c_str(), body.c_str(), + items_count, money, COD, unk1, unk2); player->SendMailResult(0, MAIL_SEND, MAIL_ERR_RECIPIENT_NOT_FOUND); return; } - sLog->outInfo(LOG_FILTER_NETWORKIO, "Player %u is sending mail to %s (GUID: %u) with subject %s and body %s includes %u items, %u copper and %u COD copper with unk1 = %u, unk2 = %u", player->GetGUIDLow(), receiver.c_str(), GUID_LOPART(rc), subject.c_str(), body.c_str(), items_count, money, COD, unk1, unk2); + sLog->outInfo(LOG_FILTER_NETWORKIO, "Player %u is sending mail to %s (GUID: %u) with subject %s and body %s " + "includes %u items, %u copper and %u COD copper with unk1 = %u, unk2 = %u", + player->GetGUIDLow(), receiverName.c_str(), GUID_LOPART(receiverGuid), subject.c_str(), + body.c_str(), items_count, money, COD, unk1, unk2); - if (player->GetGUID() == rc) + if (player->GetGUID() == receiverGuid) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_CANNOT_SEND_TO_SELF); return; @@ -113,58 +111,62 @@ void WorldSession::HandleSendMail(WorldPacket& recvData) return; } - Player* receive = ObjectAccessor::FindPlayer(rc); + Player* receiver = ObjectAccessor::FindPlayer(receiverGuid); - uint32 rc_team = 0; - uint8 mails_count = 0; //do not allow to send to one player more than 100 mails - uint8 receiveLevel = 0; + uint32 receiverTeam = 0; + uint8 mailsCount = 0; //do not allow to send to one player more than 100 mails + uint8 receiverLevel = 0; + uint32 receiverAccountId = 0; + bool canReceiveMailFromOtherFaction = false; - if (receive) + if (receiver) { - rc_team = receive->GetTeam(); - mails_count = receive->GetMailSize(); - receiveLevel = receive->getLevel(); + receiverTeam = receiver->GetTeam(); + mailsCount = receiver->GetMailSize(); + receiverLevel = receiver->getLevel(); + receiverAccountId = receiver->GetSession()->GetAccountId(); + canReceiveMailFromOtherFaction = receiver->GetSession()->HasPermission(RBAC_PERM_TWO_SIDE_INTERACTION_MAIL); } else { - rc_team = sObjectMgr->GetPlayerTeamByGUID(rc); + receiverTeam = sObjectMgr->GetPlayerTeamByGUID(receiverGuid); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAIL_COUNT); - - stmt->setUInt32(0, GUID_LOPART(rc)); + stmt->setUInt32(0, GUID_LOPART(receiverGuid)); PreparedQueryResult result = CharacterDatabase.Query(stmt); - if (result) { Field* fields = result->Fetch(); - mails_count = fields[0].GetUInt64(); + mailsCount = fields[0].GetUInt64(); } stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_LEVEL); - - stmt->setUInt32(0, GUID_LOPART(rc)); + stmt->setUInt32(0, GUID_LOPART(receiverGuid)); result = CharacterDatabase.Query(stmt); - if (result) { Field* fields = result->Fetch(); - receiveLevel = fields[0].GetUInt8(); + receiverLevel = fields[0].GetUInt8(); } + + receiverAccountId = sObjectMgr->GetPlayerAccountIdByGUID(receiverGuid); + canReceiveMailFromOtherFaction = AccountMgr::HasPermission(receiverAccountId, RBAC_PERM_TWO_SIDE_INTERACTION_MAIL, realmID); } - //do not allow to have more than 100 mails in mailbox.. mails count is in opcode uint8!!! - so max can be 255.. - if (mails_count > 100) + + // do not allow to have more than 100 mails in mailbox.. mails count is in opcode uint8!!! - so max can be 255.. + if (mailsCount > 100) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_RECIPIENT_CAP_REACHED); return; } + // test the receiver's Faction... or all items are account bound bool accountBound = items_count ? true : false; for (uint8 i = 0; i < items_count; ++i) { - Item* item = player->GetItemByGuid(itemGUIDs[i]); - if (item) + if (Item* item = player->GetItemByGuid(itemGUIDs[i])) { ItemTemplate const* itemProto = item->GetTemplate(); if (!itemProto || !(itemProto->Flags & ITEM_PROTO_FLAG_BIND_TO_ACCOUNT)) @@ -175,22 +177,21 @@ void WorldSession::HandleSendMail(WorldPacket& recvData) } } - if (!accountBound && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_MAIL) && player->GetTeam() != rc_team && AccountMgr::IsPlayerAccount(GetSecurity())) + if (!accountBound && player->GetTeam() != receiverTeam && // Sender and reciver are from different faction + (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_MAIL) || // Config not enabled + !HasPermission(RBAC_PERM_TWO_SIDE_INTERACTION_MAIL) || // Sender cant mail interact with the other faction + !canReceiveMailFromOtherFaction)) // Receiver cant mail interact with the other faction { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_NOT_YOUR_TEAM); return; } - if (receiveLevel < sWorld->getIntConfig(CONFIG_MAIL_LEVEL_REQ)) + if (receiverLevel < sWorld->getIntConfig(CONFIG_MAIL_LEVEL_REQ)) { SendNotification(GetTrinityString(LANG_MAIL_RECEIVER_REQ), sWorld->getIntConfig(CONFIG_MAIL_LEVEL_REQ)); return; } - uint32 rc_account = receive - ? receive->GetSession()->GetAccountId() - : sObjectMgr->GetPlayerAccountIdByGUID(rc); - Item* items[MAX_MAIL_ITEMS]; for (uint8 i = 0; i < items_count; ++i) @@ -216,7 +217,7 @@ void WorldSession::HandleSendMail(WorldPacket& recvData) return; } - if (item->IsBoundAccountWide() && item->IsSoulBound() && player->GetSession()->GetAccountId() != rc_account) + if (item->IsBoundAccountWide() && item->IsSoulBound() && player->GetSession()->GetAccountId() != receiverAccountId) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_ARTEFACTS_ONLY_FOR_OWN_CHARACTERS); return; @@ -264,28 +265,30 @@ void WorldSession::HandleSendMail(WorldPacket& recvData) Item* item = items[i]; if (log) { - sLog->outCommand(GetAccountId(), "GM %s (Account: %u) mail item: %s (Entry: %u Count: %u) to player: %s (Account: %u)", - GetPlayerName().c_str(), GetAccountId(), item->GetTemplate()->Name1.c_str(), item->GetEntry(), item->GetCount(), receiver.c_str(), rc_account); + sLog->outCommand(GetAccountId(), "GM %s (Account: %u) mail item: %s (Entry: %u Count: %u) " + "to player: %s (Account: %u)", GetPlayerName().c_str(), GetAccountId(), + item->GetTemplate()->Name1.c_str(), item->GetEntry(), item->GetCount(), + receiverName.c_str(), receiverAccountId); } item->SetNotRefundable(GetPlayer()); // makes the item no longer refundable player->MoveItemFromInventory(items[i]->GetBagSlot(), item->GetSlot(), true); item->DeleteFromInventoryDB(trans); // deletes item from character's inventory - item->SetOwnerGUID(rc); + item->SetOwnerGUID(receiverGuid); item->SaveToDB(trans); // recursive and not have transaction guard into self, item not in inventory and can be save standalone draft.AddItem(item); } // if item send to character at another account, then apply item delivery delay - needItemDelay = player->GetSession()->GetAccountId() != rc_account; + needItemDelay = player->GetSession()->GetAccountId() != receiverAccountId; } if (log && money > 0) { sLog->outCommand(GetAccountId(), "GM %s (Account: %u) mail money: %u to player: %s (Account: %u)", - GetPlayerName().c_str(), GetAccountId(), money, receiver.c_str(), rc_account); + GetPlayerName().c_str(), GetAccountId(), money, receiverName.c_str(), receiverAccountId); } } @@ -296,7 +299,7 @@ void WorldSession::HandleSendMail(WorldPacket& recvData) draft .AddMoney(money) .AddCOD(COD) - .SendMailTo(trans, MailReceiver(receive, GUID_LOPART(rc)), MailSender(player), body.empty() ? MAIL_CHECK_MASK_COPIED : MAIL_CHECK_MASK_HAS_BODY, deliver_delay); + .SendMailTo(trans, MailReceiver(receiver, GUID_LOPART(receiverGuid)), MailSender(player), body.empty() ? MAIL_CHECK_MASK_COPIED : MAIL_CHECK_MASK_HAS_BODY, deliver_delay); player->SaveInventoryAndGoldToDB(trans); CharacterDatabase.CommitTransaction(trans); @@ -459,17 +462,17 @@ void WorldSession::HandleMailTakeItem(WorldPacket& recvData) if (m->COD > 0) //if there is COD, take COD money from player and send them to sender by mail { uint64 sender_guid = MAKE_NEW_GUID(m->sender, 0, HIGHGUID_PLAYER); - Player* receive = ObjectAccessor::FindPlayer(sender_guid); + Player* receiver = ObjectAccessor::FindPlayer(sender_guid); uint32 sender_accId = 0; if (HasPermission(RBAC_PERM_LOG_GM_TRADE) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) { std::string sender_name; - if (receive) + if (receiver) { - sender_accId = receive->GetSession()->GetAccountId(); - sender_name = receive->GetName(); + sender_accId = receiver->GetSession()->GetAccountId(); + sender_name = receiver->GetName(); } else { @@ -479,18 +482,18 @@ void WorldSession::HandleMailTakeItem(WorldPacket& recvData) if (!sObjectMgr->GetPlayerNameByGUID(sender_guid, sender_name)) sender_name = sObjectMgr->GetTrinityStringForDBCLocale(LANG_UNKNOWN); } - sLog->outCommand(GetAccountId(), "GM %s (Account: %u) receive mail item: %s (Entry: %u Count: %u) and send COD money: %u to player: %s (Account: %u)", + sLog->outCommand(GetAccountId(), "GM %s (Account: %u) receiver mail item: %s (Entry: %u Count: %u) and send COD money: %u to player: %s (Account: %u)", GetPlayerName().c_str(), GetAccountId(), it->GetTemplate()->Name1.c_str(), it->GetEntry(), it->GetCount(), m->COD, sender_name.c_str(), sender_accId); } - else if (!receive) + else if (!receiver) sender_accId = sObjectMgr->GetPlayerAccountIdByGUID(sender_guid); // check player existence - if (receive || sender_accId) + if (receiver || sender_accId) { MailDraft(m->subject, "") .AddMoney(m->COD) - .SendMailTo(trans, MailReceiver(receive, m->sender), MailSender(MAIL_NORMAL, m->receiver), MAIL_CHECK_MASK_COD_PAYMENT); + .SendMailTo(trans, MailReceiver(receiver, m->sender), MailSender(MAIL_NORMAL, m->receiver), MAIL_CHECK_MASK_COD_PAYMENT); } player->ModifyMoney(-int32(m->COD)); -- cgit v1.2.3 From fc78c48495661dc1e8393c637028971c8126a680 Mon Sep 17 00:00:00 2001 From: Spp Date: Mon, 25 Feb 2013 13:40:56 +0100 Subject: Core/RBAC: Create new permissions 'Notify if a command was not found' and 'Enables lower security than target check' --- sql/updates/auth/2013_02_25_08_auth_misc.sql | 4 +-- sql/updates/auth/2013_02_25_09_auth_misc.sql | 27 ++++++++++++++++ src/server/game/Accounts/RBAC.h | 48 +++++++++++++++------------- src/server/game/Chat/Chat.cpp | 5 +-- 4 files changed, 57 insertions(+), 27 deletions(-) create mode 100644 sql/updates/auth/2013_02_25_09_auth_misc.sql (limited to 'src') diff --git a/sql/updates/auth/2013_02_25_08_auth_misc.sql b/sql/updates/auth/2013_02_25_08_auth_misc.sql index 35b12b1eddb..244b1848d0c 100644 --- a/sql/updates/auth/2013_02_25_08_auth_misc.sql +++ b/sql/updates/auth/2013_02_25_08_auth_misc.sql @@ -1,10 +1,10 @@ -- Add new permission DELETE FROM `rbac_permissions` WHERE `id` = 27; -INSERT INTO `rbac_permissions` (`id`, `name`) VALUES (27, 'Send mail to other faction'); +INSERT INTO `rbac_permissions` (`id`, `name`) VALUES (27, 'Two side mail interaction'); -- Add new role DELETE FROM `rbac_roles` WHERE `id` = 19; -INSERT INTO `rbac_roles` (`id`, `name`) VALUES (19, 'Send mail to other faction'); +INSERT INTO `rbac_roles` (`id`, `name`) VALUES (19, 'Two side mail interaction'); -- Add the permission to the role DELETE FROM `rbac_role_permissions` WHERE `roleId` = 19; diff --git a/sql/updates/auth/2013_02_25_09_auth_misc.sql b/sql/updates/auth/2013_02_25_09_auth_misc.sql new file mode 100644 index 00000000000..f2affe05b70 --- /dev/null +++ b/sql/updates/auth/2013_02_25_09_auth_misc.sql @@ -0,0 +1,27 @@ +-- Add new permissions +DELETE FROM `rbac_permissions` WHERE `id` IN (33, 47); +INSERT INTO `rbac_permissions` (`id`, `name`) VALUES +(33, 'Notify if a command was not found'), +(47, 'Enables lower security than target check'); + +-- Add new role +DELETE FROM `rbac_roles` WHERE `id` IN (20, 21); +INSERT INTO `rbac_roles` (`id`, `name`) VALUES +(20, 'Notify if a command was not found'), +(21, 'Enables lower security than target check'); + +-- Add the permission to the role +DELETE FROM `rbac_role_permissions` WHERE `roleId` IN (20, 21); +INSERT INTO `rbac_role_permissions` (`roleId`, `permissionId`) VALUES +(20, 33), +(21, 47); + +-- Add it to all GM+ groups +DELETE FROM `rbac_role_permissions` WHERE `roleId` IN (20, 21); +INSERT INTO `rbac_group_roles` (`groupId`, `roleId`) VALUES +(2, 20), +(3, 20), +(4, 20), +(2, 21), +(3, 21), +(4, 21); diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h index e8ea9a33134..8113f7cf1fb 100644 --- a/src/server/game/Accounts/RBAC.h +++ b/src/server/game/Accounts/RBAC.h @@ -48,29 +48,31 @@ enum RBACPermissions { - RBAC_PERM_INSTANT_LOGOUT = 1, - RBAC_PERM_SKIP_QUEUE = 2, - RBAC_PERM_JOIN_NORMAL_BG = 3, - RBAC_PERM_JOIN_RANDOM_BG = 4, - RBAC_PERM_JOIN_ARENAS = 5, - RBAC_PERM_JOIN_DUNGEON_FINDER = 6, - RBAC_PERM_PLAYER_COMMANDS = 7, - RBAC_PERM_MODERATOR_COMMANDS = 8, - RBAC_PERM_GAMEMASTER_COMMANDS = 9, - RBAC_PERM_ADMINISTRATOR_COMMANDS = 10, - RBAC_PERM_LOG_GM_TRADE = 11, - RBAC_PERM_SKIP_CHECK_INSTANCE_REQUIRED_BOSSES = 13, - RBAC_PERM_SKIP_CHECK_OVERSPEED_PING = 23, - RBAC_PERM_TWO_SIDE_INTERACTION_MAIL = 27, - RBAC_PERM_COMMANDS_SAVE_WITHOUT_DELAY = 30, - RBAC_PERM_COMMANDS_USE_UNSTUCK_WITH_ARGS = 31, - RBAC_PERM_COMMANDS_BE_ASSIGNED_TICKET = 32, - RBAC_PERM_COMMANDS_APPEAR_IN_GM_LIST = 34, - RBAC_PERM_CHAT_USE_STAFF_BADGE = 37, - RBAC_PERM_RESURRECT_WITH_FULL_HPS = 38, - RBAC_PERM_OPCODE_WORLD_TELEPORT = 42, - RBAC_PERM_OPCODE_WHOIS = 43, - RBAC_PERM_RECEIVE_GLOBAL_GM_TEXTMESSAGE = 44, + RBAC_PERM_INSTANT_LOGOUT = 1, + RBAC_PERM_SKIP_QUEUE = 2, + RBAC_PERM_JOIN_NORMAL_BG = 3, + RBAC_PERM_JOIN_RANDOM_BG = 4, + RBAC_PERM_JOIN_ARENAS = 5, + RBAC_PERM_JOIN_DUNGEON_FINDER = 6, + RBAC_PERM_PLAYER_COMMANDS = 7, + RBAC_PERM_MODERATOR_COMMANDS = 8, + RBAC_PERM_GAMEMASTER_COMMANDS = 9, + RBAC_PERM_ADMINISTRATOR_COMMANDS = 10, + RBAC_PERM_LOG_GM_TRADE = 11, + RBAC_PERM_SKIP_CHECK_INSTANCE_REQUIRED_BOSSES = 13, + RBAC_PERM_SKIP_CHECK_OVERSPEED_PING = 23, + RBAC_PERM_TWO_SIDE_INTERACTION_MAIL = 27, + RBAC_PERM_COMMANDS_SAVE_WITHOUT_DELAY = 30, + RBAC_PERM_COMMANDS_USE_UNSTUCK_WITH_ARGS = 31, + RBAC_PERM_COMMANDS_BE_ASSIGNED_TICKET = 32, + RBAC_PERM_COMMANDS_NOTIFY_COMMAND_NOT_FOUND_ERROR = 33, + RBAC_PERM_COMMANDS_APPEAR_IN_GM_LIST = 34, + RBAC_PERM_CHAT_USE_STAFF_BADGE = 37, + RBAC_PERM_RESURRECT_WITH_FULL_HPS = 38, + RBAC_PERM_OPCODE_WORLD_TELEPORT = 42, + RBAC_PERM_OPCODE_WHOIS = 43, + RBAC_PERM_RECEIVE_GLOBAL_GM_TEXTMESSAGE = 44, + RBAC_PERM_CHECK_FOR_LOWER_SECURITY = 47, RBAC_PERM_MAX }; diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp index 3cae9d0f83a..7c92af2d67f 100644 --- a/src/server/game/Chat/Chat.cpp +++ b/src/server/game/Chat/Chat.cpp @@ -175,7 +175,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 (!AccountMgr::IsPlayerAccount(m_session->GetSecurity()) && !strong && !sWorld->getBoolConfig(CONFIG_GM_LOWER_SECURITY)) + if (m_session->HasPermission(RBAC_PERM_CHECK_FOR_LOWER_SECURITY) && !strong && !sWorld->getBoolConfig(CONFIG_GM_LOWER_SECURITY)) return false; if (target) @@ -361,6 +361,7 @@ bool ChatHandler::ExecuteCommandInTable(ChatCommand* table, const char* text, co // table[i].Name == "" is special case: send original command to handler if ((table[i].Handler)(this, table[i].Name[0] != '\0' ? text : oldtext)) { + // FIXME: When Command system is moved to RBAC this check must be changed if (!AccountMgr::IsPlayerAccount(table[i].SecurityLevel)) { // chat case @@ -476,7 +477,7 @@ bool ChatHandler::ParseCommands(char const* text) if (!ExecuteCommandInTable(getCommandTable(), text, fullcmd)) { - if (m_session && AccountMgr::IsPlayerAccount(m_session->GetSecurity())) + if (m_session && !m_session->HasPermission(RBAC_PERM_COMMANDS_NOTIFY_COMMAND_NOT_FOUND_ERROR)) return false; SendSysMessage(LANG_NO_CMD); -- cgit v1.2.3 From 9bd697066b4f2f3e46d44f57457cfba8961f6316 Mon Sep 17 00:00:00 2001 From: Spp Date: Mon, 25 Feb 2013 14:01:51 +0100 Subject: Core/RBAC: Add new permissions 'Skip disable map check', 'Skip reset talents when used more than allowed check', 'Skip spam chat check', 'Restore saved gm setting states', 'Use Config option START_GM_LEVEL to assign new character level' --- sql/updates/auth/2013_02_25_10_auth_misc.sql | 43 ++++++++++++++++++++++++++++ src/server/game/Accounts/RBAC.h | 5 ++++ src/server/game/Entities/Player/Player.cpp | 10 +++---- 3 files changed, 53 insertions(+), 5 deletions(-) create mode 100644 sql/updates/auth/2013_02_25_10_auth_misc.sql (limited to 'src') diff --git a/sql/updates/auth/2013_02_25_10_auth_misc.sql b/sql/updates/auth/2013_02_25_10_auth_misc.sql new file mode 100644 index 00000000000..4255bdac8ba --- /dev/null +++ b/sql/updates/auth/2013_02_25_10_auth_misc.sql @@ -0,0 +1,43 @@ +-- Add new permissions +DELETE FROM `rbac_permissions` WHERE `id` IN (20, 21, 22, 39, 41); +INSERT INTO `rbac_permissions` (`id`, `name`) VALUES +(20, 'Skip disable map check'), +(21, 'Skip reset talents when used more than allowed check'), +(22, 'Skip spam chat check'), +(39, 'Restore saved gm setting states'), +(41, 'Use Config option START_GM_LEVEL to assign new character level'); + +-- Add new role +DELETE FROM `rbac_roles` WHERE `id` IN (22, 23, 24, 25, 26); +INSERT INTO `rbac_roles` (`id`, `name`) VALUES +(22, 'Skip disable map check'), +(23, 'Skip reset talents when used more than allowed check'), +(24, 'Skip spam chat check'), +(25, 'Restore saved gm setting states'), +(26, 'Use Config option START_GM_LEVEL to assign new character level'); + +-- Add the permission to the role +DELETE FROM `rbac_role_permissions` WHERE `roleId` IN (22, 23, 24, 25, 26); +INSERT INTO `rbac_role_permissions` (`roleId`, `permissionId`) VALUES +(22, 20), +(23, 21), +(24, 22), +(25, 39), +(26, 41); + +-- Add it to all GM+ groups +DELETE FROM `rbac_role_permissions` WHERE `roleId` IN (22, 23, 24, 25, 26); +INSERT INTO `rbac_group_roles` (`groupId`, `roleId`) VALUES +(2, 22), +(3, 22), +(4, 22), +(4, 23), +(2, 24), +(3, 24), +(4, 24), +(2, 25), +(3, 25), +(4, 25), +(2, 26), +(3, 26), +(4, 26); diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h index 8113f7cf1fb..72fe5eceb8b 100644 --- a/src/server/game/Accounts/RBAC.h +++ b/src/server/game/Accounts/RBAC.h @@ -60,6 +60,9 @@ enum RBACPermissions RBAC_PERM_ADMINISTRATOR_COMMANDS = 10, RBAC_PERM_LOG_GM_TRADE = 11, RBAC_PERM_SKIP_CHECK_INSTANCE_REQUIRED_BOSSES = 13, + RBAC_PERM_SKIP_CHECK_DISABLE_MAP = 20, + RBAC_PERM_SKIP_CHECK_MORE_TALENTS_THAN_ALLOWED = 21, + RBAC_PERM_SKIP_CHECK_CHAT_SPAM = 22, RBAC_PERM_SKIP_CHECK_OVERSPEED_PING = 23, RBAC_PERM_TWO_SIDE_INTERACTION_MAIL = 27, RBAC_PERM_COMMANDS_SAVE_WITHOUT_DELAY = 30, @@ -69,6 +72,8 @@ enum RBACPermissions RBAC_PERM_COMMANDS_APPEAR_IN_GM_LIST = 34, RBAC_PERM_CHAT_USE_STAFF_BADGE = 37, RBAC_PERM_RESURRECT_WITH_FULL_HPS = 38, + RBAC_PERM_RESTORE_SAVED_GM_STATE = 39, + RBAC_PERM_USE_START_GM_LEVEL = 41, RBAC_PERM_OPCODE_WORLD_TELEPORT = 42, RBAC_PERM_OPCODE_WHOIS = 43, RBAC_PERM_RECEIVE_GLOBAL_GM_TEXTMESSAGE = 44, diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index c7c88ae0bbe..fda6a656226 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -1018,7 +1018,7 @@ bool Player::Create(uint32 guidlow, CharacterCreateInfo* createInfo) ? sWorld->getIntConfig(CONFIG_START_PLAYER_LEVEL) : sWorld->getIntConfig(CONFIG_START_HEROIC_PLAYER_LEVEL); - if (!AccountMgr::IsPlayerAccount(GetSession()->GetSecurity())) + if (m_session->HasPermission(RBAC_PERM_USE_START_GM_LEVEL)) { uint32 gm_level = sWorld->getIntConfig(CONFIG_START_GM_LEVEL); if (gm_level > start_level) @@ -2069,7 +2069,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati return false; } - if (AccountMgr::IsPlayerAccount(GetSession()->GetSecurity()) && DisableMgr::IsDisabledFor(DISABLE_TYPE_MAP, mapid, this)) + if (!GetSession()->HasPermission(RBAC_PERM_SKIP_CHECK_DISABLE_MAP) && DisableMgr::IsDisabledFor(DISABLE_TYPE_MAP, mapid, this)) { sLog->outError(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); @@ -3120,7 +3120,7 @@ void Player::InitTalentForLevel() // if used more that have then reset if (m_usedTalentCount > talentPointsForLevel) { - if (!AccountMgr::IsAdminAccount(GetSession()->GetSecurity())) + if (!GetSession()->HasPermission(RBAC_PERM_SKIP_CHECK_MORE_TALENTS_THAN_ALLOWED)) resetTalents(true); else SetFreeTalentPoints(0); @@ -17309,7 +17309,7 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder) outDebugValues(); // GM state - if (!AccountMgr::IsPlayerAccount(GetSession()->GetSecurity())) + if (GetSession()->HasPermission(RBAC_PERM_RESTORE_SAVED_GM_STATE)) { switch (sWorld->getIntConfig(CONFIG_GM_LOGIN_STATE)) { @@ -19628,7 +19628,7 @@ void Player::outDebugValues() const void Player::UpdateSpeakTime() { // ignore chat spam protection for GMs in any mode - if (!AccountMgr::IsPlayerAccount(GetSession()->GetSecurity())) + if (!GetSession()->HasPermission(RBAC_PERM_SKIP_CHECK_CHAT_SPAM)) return; time_t current = time (NULL); -- cgit v1.2.3 From 18562a43bafc43cee910114c8e869c8e1e8c361d Mon Sep 17 00:00:00 2001 From: Spp Date: Mon, 25 Feb 2013 14:19:37 +0100 Subject: Core/RBAC: Create new permissions 'Skips needed requirements to use channel check', 'Filter whispers', 'Allow say chat between factions'. Last one needs config option to be enabled and both sender and receiver to have the permission --- sql/updates/auth/2013_02_25_11_auth_misc.sql | 34 ++++++++++++++++++++++++++++ src/server/game/Accounts/RBAC.h | 3 +++ src/server/game/Entities/Player/Player.cpp | 2 +- src/server/game/Handlers/ChatHandler.cpp | 24 +++++++++++--------- 4 files changed, 51 insertions(+), 12 deletions(-) create mode 100644 sql/updates/auth/2013_02_25_11_auth_misc.sql (limited to 'src') diff --git a/sql/updates/auth/2013_02_25_11_auth_misc.sql b/sql/updates/auth/2013_02_25_11_auth_misc.sql new file mode 100644 index 00000000000..9c2897394e5 --- /dev/null +++ b/sql/updates/auth/2013_02_25_11_auth_misc.sql @@ -0,0 +1,34 @@ +-- Add new permissions +DELETE FROM `rbac_permissions` WHERE `id` IN (19, 25, 36); +INSERT INTO `rbac_permissions` (`id`, `name`) VALUES +(19, 'Skips needed requirements to use channel check'), +(25, 'Allow say chat between factions'), +(36, 'Filter whispers'); + +-- Add new role +DELETE FROM `rbac_roles` WHERE `id` IN (27, 28, 29); +INSERT INTO `rbac_roles` (`id`, `name`) VALUES +(27, 'Skips needed requirements to use channel check'), +(28, 'Allow say chat between factions'), +(29, 'Filter whispers'); + +-- Add the permission to the role +DELETE FROM `rbac_role_permissions` WHERE `roleId` IN (27, 28, 29); +INSERT INTO `rbac_role_permissions` (`roleId`, `permissionId`) VALUES +(27, 19), +(28, 25), +(29, 36); + +-- Add it to all GM+ groups +DELETE FROM `rbac_role_permissions` WHERE `roleId` IN (27, 28, 29); +INSERT INTO `rbac_group_roles` (`groupId`, `roleId`) VALUES +(2, 27), +(3, 27), +(4, 27), +(1, 28), +(2, 28), +(3, 28), +(4, 28), +(2, 29), +(3, 29), +(4, 29); diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h index 72fe5eceb8b..568c72303a4 100644 --- a/src/server/game/Accounts/RBAC.h +++ b/src/server/game/Accounts/RBAC.h @@ -60,16 +60,19 @@ enum RBACPermissions RBAC_PERM_ADMINISTRATOR_COMMANDS = 10, RBAC_PERM_LOG_GM_TRADE = 11, RBAC_PERM_SKIP_CHECK_INSTANCE_REQUIRED_BOSSES = 13, + RBAC_PERM_SKIP_CHECK_CHAT_CHANNEL_REQ = 19, RBAC_PERM_SKIP_CHECK_DISABLE_MAP = 20, RBAC_PERM_SKIP_CHECK_MORE_TALENTS_THAN_ALLOWED = 21, RBAC_PERM_SKIP_CHECK_CHAT_SPAM = 22, RBAC_PERM_SKIP_CHECK_OVERSPEED_PING = 23, + RBAC_PERM_TWO_SIDE_INTERACTION_CHAT = 25, RBAC_PERM_TWO_SIDE_INTERACTION_MAIL = 27, RBAC_PERM_COMMANDS_SAVE_WITHOUT_DELAY = 30, RBAC_PERM_COMMANDS_USE_UNSTUCK_WITH_ARGS = 31, RBAC_PERM_COMMANDS_BE_ASSIGNED_TICKET = 32, RBAC_PERM_COMMANDS_NOTIFY_COMMAND_NOT_FOUND_ERROR = 33, RBAC_PERM_COMMANDS_APPEAR_IN_GM_LIST = 34, + RBAC_PERM_CAN_FILTER_WHISPERS = 36, RBAC_PERM_CHAT_USE_STAFF_BADGE = 37, RBAC_PERM_RESURRECT_WITH_FULL_HPS = 38, RBAC_PERM_RESTORE_SAVED_GM_STATE = 39, diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index fda6a656226..f24b35ef83c 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -668,7 +668,7 @@ Player::Player(WorldSession* session): Unit(true) //m_pad = 0; // players always accept - if (AccountMgr::IsPlayerAccount(GetSession()->GetSecurity())) + if (!GetSession()->HasPermission(RBAC_PERM_CAN_FILTER_WHISPERS)) SetAcceptWhispers(true); m_curSelection = 0; diff --git a/src/server/game/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp index d04d365504d..efb3a3b6d7c 100644 --- a/src/server/game/Handlers/ChatHandler.cpp +++ b/src/server/game/Handlers/ChatHandler.cpp @@ -273,20 +273,22 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) } Player* receiver = sObjectAccessor->FindPlayerByName(to); - bool senderIsPlayer = AccountMgr::IsPlayerAccount(GetSecurity()); - bool receiverIsPlayer = AccountMgr::IsPlayerAccount(receiver ? receiver->GetSession()->GetSecurity() : SEC_PLAYER); - if (!receiver || (senderIsPlayer && !receiverIsPlayer && !receiver->isAcceptWhispers() && !receiver->IsInWhisperWhiteList(sender->GetGUID()))) + if (!receiver || (!HasPermission(RBAC_PERM_CAN_FILTER_WHISPERS) && + receiver->GetSession()->HasPermission(RBAC_PERM_CAN_FILTER_WHISPERS) && + !receiver->isAcceptWhispers() && !receiver->IsInWhisperWhiteList(sender->GetGUID()))) { SendPlayerNotFoundNotice(to); return; } - if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT) && senderIsPlayer && receiverIsPlayer) - if (GetPlayer()->GetTeam() != receiver->GetTeam()) - { - SendWrongFactionNotice(); - return; - } + if (GetPlayer()->GetTeam() != receiver->GetTeam() && + (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT) || + !HasPermission(RBAC_PERM_TWO_SIDE_INTERACTION_CHAT) || + !receiver->GetSession()->HasPermission(RBAC_PERM_TWO_SIDE_INTERACTION_CHAT))) + { + SendWrongFactionNotice(); + return; + } if (GetPlayer()->HasAura(1852) && !receiver->isGameMaster()) { @@ -295,7 +297,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 - if (!senderIsPlayer && !sender->isAcceptWhispers() && !sender->IsInWhisperWhiteList(receiver->GetGUID())) + if (HasPermission(RBAC_PERM_CAN_FILTER_WHISPERS) && !sender->isAcceptWhispers() && !sender->IsInWhisperWhiteList(receiver->GetGUID())) sender->AddWhisperWhiteList(receiver->GetGUID()); GetPlayer()->Whisper(msg, lang, receiver->GetGUID()); @@ -420,7 +422,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) } break; case CHAT_MSG_CHANNEL: { - if (AccountMgr::IsPlayerAccount(GetSecurity())) + if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHAT_CHANNEL_REQ)) { if (_player->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_CHANNEL_LEVEL_REQ)) { -- cgit v1.2.3 From f67330e2ad348e39068a22fa072825d682b825c9 Mon Sep 17 00:00:00 2001 From: Spp Date: Mon, 25 Feb 2013 14:37:13 +0100 Subject: Core/RBAC: Create new permissions 'Allow channel chat between factions', 'Join channels without announce' (both need config option enabled and permission set) and 'Change channel settings without being channel moderator' --- sql/updates/auth/2013_02_25_12_auth_misc.sql | 34 +++++++++++++++++++++++ src/server/game/Accounts/RBAC.h | 3 ++ src/server/game/Chat/Channels/Channel.cpp | 41 ++++++++++++++-------------- 3 files changed, 58 insertions(+), 20 deletions(-) create mode 100644 sql/updates/auth/2013_02_25_12_auth_misc.sql (limited to 'src') diff --git a/sql/updates/auth/2013_02_25_12_auth_misc.sql b/sql/updates/auth/2013_02_25_12_auth_misc.sql new file mode 100644 index 00000000000..9d2f01a917d --- /dev/null +++ b/sql/updates/auth/2013_02_25_12_auth_misc.sql @@ -0,0 +1,34 @@ +-- Add new permissions +DELETE FROM `rbac_permissions` WHERE `id` IN (26, 46, 46); +INSERT INTO `rbac_permissions` (`id`, `name`) VALUES +(26, 'Allow channel chat between factions'), +(46, 'Join channels without announce'), +(46, 'Change channel settings without being channel moderator'); + +-- Add new role +DELETE FROM `rbac_roles` WHERE `id` IN (30, 31, 32); +INSERT INTO `rbac_roles` (`id`, `name`) VALUES +(30, 'Allow channel chat between factions'), +(31, 'Join channels without announce'), +(32, 'Change channel settings without being channel moderator'); + +-- Add the permission to the role +DELETE FROM `rbac_role_permissions` WHERE `roleId` IN (30, 31, 32); +INSERT INTO `rbac_role_permissions` (`roleId`, `permissionId`) VALUES +(30, 26), +(31, 46), +(32, 4645); + +-- Add it to all GM+ groups +DELETE FROM `rbac_role_permissions` WHERE `roleId` IN (30, 31, 32); +INSERT INTO `rbac_group_roles` (`groupId`, `roleId`) VALUES +(1, 30), +(2, 30), +(3, 30), +(4, 30), +(2, 31), +(3, 31), +(4, 31), +(2, 32), +(3, 32), +(4, 32); diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h index 568c72303a4..f20734a1994 100644 --- a/src/server/game/Accounts/RBAC.h +++ b/src/server/game/Accounts/RBAC.h @@ -66,6 +66,7 @@ enum RBACPermissions RBAC_PERM_SKIP_CHECK_CHAT_SPAM = 22, RBAC_PERM_SKIP_CHECK_OVERSPEED_PING = 23, RBAC_PERM_TWO_SIDE_INTERACTION_CHAT = 25, + RBAC_PERM_TWO_SIDE_INTERACTION_CHANNEL = 26, RBAC_PERM_TWO_SIDE_INTERACTION_MAIL = 27, RBAC_PERM_COMMANDS_SAVE_WITHOUT_DELAY = 30, RBAC_PERM_COMMANDS_USE_UNSTUCK_WITH_ARGS = 31, @@ -80,6 +81,8 @@ enum RBACPermissions RBAC_PERM_OPCODE_WORLD_TELEPORT = 42, RBAC_PERM_OPCODE_WHOIS = 43, RBAC_PERM_RECEIVE_GLOBAL_GM_TEXTMESSAGE = 44, + RBAC_PERM_SILENTLY_JOIN_CHANNEL = 45, + RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR = 46, RBAC_PERM_CHECK_FOR_LOWER_SECURITY = 47, RBAC_PERM_MAX }; diff --git a/src/server/game/Chat/Channels/Channel.cpp b/src/server/game/Chat/Channels/Channel.cpp index 9e7a63c9093..50ac4f66dec 100644 --- a/src/server/game/Chat/Channels/Channel.cpp +++ b/src/server/game/Chat/Channels/Channel.cpp @@ -180,7 +180,7 @@ void Channel::JoinChannel(Player* player, std::string const& pass) if (HasFlag(CHANNEL_FLAG_LFG) && sWorld->getBoolConfig(CONFIG_RESTRICTED_LFG_CHANNEL) && - AccountMgr::IsPlayerAccount(player->GetSession()->GetSecurity()) && + AccountMgr::IsPlayerAccount(player->GetSession()->GetSecurity()) && //FIXME: Move to RBAC player->GetGroup()) { WorldPacket data; @@ -191,8 +191,8 @@ void Channel::JoinChannel(Player* player, std::string const& pass) player->JoinedChannel(this); - if (_announce && (!AccountMgr::IsGMAccount(player->GetSession()->GetSecurity()) || - !sWorld->getBoolConfig(CONFIG_SILENTLY_GM_JOIN_TO_CHANNEL))) + if (_announce && (!sWorld->getBoolConfig(CONFIG_SILENTLY_GM_JOIN_TO_CHANNEL) || + !player->GetSession()->HasPermission(RBAC_PERM_SILENTLY_JOIN_CHANNEL))) { WorldPacket data; MakeJoined(&data, guid); @@ -252,8 +252,9 @@ void Channel::LeaveChannel(Player* player, bool send) bool changeowner = playersStore[guid].IsOwner(); playersStore.erase(guid); - if (_announce && (!AccountMgr::IsGMAccount(player->GetSession()->GetSecurity()) || - !sWorld->getBoolConfig(CONFIG_SILENTLY_GM_JOIN_TO_CHANNEL))) + + if (_announce && (!sWorld->getBoolConfig(CONFIG_SILENTLY_GM_JOIN_TO_CHANNEL) || + !player->GetSession()->HasPermission(RBAC_PERM_SILENTLY_JOIN_CHANNEL))) { WorldPacket data; MakeLeft(&data, guid); @@ -279,7 +280,6 @@ void Channel::LeaveChannel(Player* player, bool send) void Channel::KickOrBan(Player const* player, std::string const& badname, bool ban) { - AccountTypes sec = player->GetSession()->GetSecurity(); uint64 good = player->GetGUID(); if (!IsOn(good)) @@ -290,7 +290,7 @@ void Channel::KickOrBan(Player const* player, std::string const& badname, bool b return; } - if (!playersStore[good].IsModerator() && !AccountMgr::IsGMAccount(sec)) + if (!playersStore[good].IsModerator() && !player->GetSession()->HasPermission(RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR)) { WorldPacket data; MakeNotModerator(&data); @@ -310,7 +310,7 @@ void Channel::KickOrBan(Player const* player, std::string const& badname, bool b bool changeowner = _ownerGUID == victim; - if (!AccountMgr::IsGMAccount(sec) && changeowner && good != _ownerGUID) + if (!player->GetSession()->HasPermission(RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR) && changeowner && good != _ownerGUID) { WorldPacket data; MakeNotOwner(&data); @@ -318,7 +318,7 @@ void Channel::KickOrBan(Player const* player, std::string const& badname, bool b return; } - bool notify = !(AccountMgr::IsGMAccount(sec) && sWorld->getBoolConfig(CONFIG_SILENTLY_GM_JOIN_TO_CHANNEL)); + bool notify = !sWorld->getBoolConfig(CONFIG_SILENTLY_GM_JOIN_TO_CHANNEL) || !player->GetSession()->HasPermission(RBAC_PERM_SILENTLY_JOIN_CHANNEL); if (ban && !IsBanned(victim)) { @@ -404,7 +404,7 @@ void Channel::Password(Player const* player, std::string const& pass) return; } - if (!playersStore[guid].IsModerator() && !AccountMgr::IsGMAccount(player->GetSession()->GetSecurity())) + if (!playersStore[guid].IsModerator() && !player->GetSession()->HasPermission(RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR)) { WorldPacket data; MakeNotModerator(&data); @@ -424,7 +424,6 @@ void Channel::Password(Player const* player, std::string const& pass) void Channel::SetMode(Player const* player, std::string const& p2n, bool mod, bool set) { uint64 guid = player->GetGUID(); - uint32 sec = player->GetSession()->GetSecurity(); if (!IsOn(guid)) { @@ -434,7 +433,7 @@ void Channel::SetMode(Player const* player, std::string const& p2n, bool mod, bo return; } - if (!playersStore[guid].IsModerator() && !AccountMgr::IsGMAccount(sec)) + if (!playersStore[guid].IsModerator() && !player->GetSession()->HasPermission(RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR)) { WorldPacket data; MakeNotModerator(&data); @@ -449,10 +448,11 @@ void Channel::SetMode(Player const* player, std::string const& p2n, bool mod, bo uint64 victim = newp ? newp->GetGUID() : 0; if (!victim || !IsOn(victim) || + (player->GetTeam() != newp->GetTeam() && (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL) || + !player->GetSession()->HasPermission(RBAC_PERM_TWO_SIDE_INTERACTION_CHANNEL) || + !newp->GetSession()->HasPermission(RBAC_PERM_TWO_SIDE_INTERACTION_CHANNEL)))) // allow make moderator from another team only if both is GMs // at this moment this only way to show channel post for GM from another team - ((!AccountMgr::IsGMAccount(sec) || !AccountMgr::IsGMAccount(newp->GetSession()->GetSecurity())) && - player->GetTeam() != newp->GetTeam() && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL))) { WorldPacket data; MakePlayerNotFound(&data, p2n); @@ -477,7 +477,6 @@ void Channel::SetMode(Player const* player, std::string const& p2n, bool mod, bo void Channel::SetOwner(Player const* player, std::string const& newname) { uint64 guid = player->GetGUID(); - uint32 sec = player->GetSession()->GetSecurity(); if (!IsOn(guid)) { @@ -487,7 +486,7 @@ void Channel::SetOwner(Player const* player, std::string const& newname) return; } - if (!AccountMgr::IsGMAccount(sec) && guid != _ownerGUID) + if (!player->GetSession()->HasPermission(RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR) && guid != _ownerGUID) { WorldPacket data; MakeNotOwner(&data); @@ -570,7 +569,6 @@ void Channel::List(Player const* player) void Channel::Announce(Player const* player) { uint64 guid = player->GetGUID(); - uint32 sec = player->GetSession()->GetSecurity(); if (!IsOn(guid)) { @@ -580,7 +578,7 @@ void Channel::Announce(Player const* player) return; } - if (!playersStore[guid].IsModerator() && !AccountMgr::IsGMAccount(sec)) + if (!playersStore[guid].IsModerator() && !player->GetSession()->HasPermission(RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR)) { WorldPacket data; MakeNotModerator(&data); @@ -605,6 +603,10 @@ void Channel::Say(uint64 guid, std::string const& what, uint32 lang) if (what.empty()) return; + uint8 chatTag = 0; + if (Player* player = ObjectAccessor::FindPlayer(guid)) + chatTag = player->GetChatTag(); + if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL)) lang = LANG_UNIVERSAL; @@ -633,8 +635,7 @@ void Channel::Say(uint64 guid, std::string const& what, uint32 lang) data << uint64(guid); data << uint32(what.size() + 1); data << what; - Player* player = ObjectAccessor::FindPlayer(guid); - data << uint8(player ? player->GetChatTag() : 0); + data << uint8(chatTag); SendToAll(&data, !playersStore[guid].IsModerator() ? guid : false); } -- cgit v1.2.3 From 019770dddba453095b09545002000bc44a8d645a Mon Sep 17 00:00:00 2001 From: Spp Date: Mon, 25 Feb 2013 15:28:41 +0100 Subject: Core/RBAC: Create new permissions related to character creation - 'Skips character creation team mask check' - 'Skips character creation class mask check' - 'Skips character creation race mask check' - 'Skips character creation reserved name check' - 'Skips character creation heroic min level check' - 'Creation of two side faction characters in same account' (Affected by global config option) --- sql/updates/auth/2013_02_25_12_auth_misc.sql | 8 +-- sql/updates/auth/2013_02_25_13_auth_misc.sql | 36 ++++++++++++ src/server/game/Accounts/RBAC.h | 78 ++++++++++++++------------ src/server/game/Entities/Player/Player.cpp | 3 +- src/server/game/Handlers/CharacterHandler.cpp | 81 +++++++++++++++------------ 5 files changed, 130 insertions(+), 76 deletions(-) create mode 100644 sql/updates/auth/2013_02_25_13_auth_misc.sql (limited to 'src') diff --git a/sql/updates/auth/2013_02_25_12_auth_misc.sql b/sql/updates/auth/2013_02_25_12_auth_misc.sql index 9d2f01a917d..2b394dc9bcb 100644 --- a/sql/updates/auth/2013_02_25_12_auth_misc.sql +++ b/sql/updates/auth/2013_02_25_12_auth_misc.sql @@ -1,8 +1,8 @@ -- Add new permissions -DELETE FROM `rbac_permissions` WHERE `id` IN (26, 46, 46); +DELETE FROM `rbac_permissions` WHERE `id` IN (26, 45, 46); INSERT INTO `rbac_permissions` (`id`, `name`) VALUES (26, 'Allow channel chat between factions'), -(46, 'Join channels without announce'), +(45, 'Join channels without announce'), (46, 'Change channel settings without being channel moderator'); -- Add new role @@ -16,8 +16,8 @@ INSERT INTO `rbac_roles` (`id`, `name`) VALUES DELETE FROM `rbac_role_permissions` WHERE `roleId` IN (30, 31, 32); INSERT INTO `rbac_role_permissions` (`roleId`, `permissionId`) VALUES (30, 26), -(31, 46), -(32, 4645); +(31, 45), +(32, 46); -- Add it to all GM+ groups DELETE FROM `rbac_role_permissions` WHERE `roleId` IN (30, 31, 32); diff --git a/sql/updates/auth/2013_02_25_13_auth_misc.sql b/sql/updates/auth/2013_02_25_13_auth_misc.sql new file mode 100644 index 00000000000..82247ecd07d --- /dev/null +++ b/sql/updates/auth/2013_02_25_13_auth_misc.sql @@ -0,0 +1,36 @@ +-- Add new permissions +DELETE FROM `rbac_permissions` WHERE `id` IN (14, 15, 16, 17, 18, 24); +INSERT INTO `rbac_permissions` (`id`, `name`) VALUES +(14, 'Skips character creation team mask check'), +(15, 'Skips character creation class mask check'), +(16, 'Skips character creation race mask check'), +(17, 'Skips character creation reserved name check'), +(18, 'Skips character creation heroic min level check'), +(24, 'Creation of two side faction characters in same account'); + +-- Add new role +DELETE FROM `rbac_roles` WHERE `id` IN (33, 34); +INSERT INTO `rbac_roles` (`id`, `name`) VALUES +(33, 'Skips character creation checks'), +(34, 'Creation of two side faction characters in same account'); + +-- Add the permission to the role +DELETE FROM `rbac_role_permissions` WHERE `roleId` IN (33, 34); +INSERT INTO `rbac_role_permissions` (`roleId`, `permissionId`) VALUES +(33, 14), +(33, 15), +(33, 16), +(33, 17), +(33, 18), +(34, 24); + +-- Add it to all groups +DELETE FROM `rbac_role_permissions` WHERE `roleId` IN (33, 34); +INSERT INTO `rbac_group_roles` (`groupId`, `roleId`) VALUES +(2, 33), +(3, 33), +(4, 33), +(2, 34), +(3, 34), +(4, 34); + diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h index f20734a1994..eb9220a317a 100644 --- a/src/server/game/Accounts/RBAC.h +++ b/src/server/game/Accounts/RBAC.h @@ -48,42 +48,48 @@ enum RBACPermissions { - RBAC_PERM_INSTANT_LOGOUT = 1, - RBAC_PERM_SKIP_QUEUE = 2, - RBAC_PERM_JOIN_NORMAL_BG = 3, - RBAC_PERM_JOIN_RANDOM_BG = 4, - RBAC_PERM_JOIN_ARENAS = 5, - RBAC_PERM_JOIN_DUNGEON_FINDER = 6, - RBAC_PERM_PLAYER_COMMANDS = 7, - RBAC_PERM_MODERATOR_COMMANDS = 8, - RBAC_PERM_GAMEMASTER_COMMANDS = 9, - RBAC_PERM_ADMINISTRATOR_COMMANDS = 10, - RBAC_PERM_LOG_GM_TRADE = 11, - RBAC_PERM_SKIP_CHECK_INSTANCE_REQUIRED_BOSSES = 13, - RBAC_PERM_SKIP_CHECK_CHAT_CHANNEL_REQ = 19, - RBAC_PERM_SKIP_CHECK_DISABLE_MAP = 20, - RBAC_PERM_SKIP_CHECK_MORE_TALENTS_THAN_ALLOWED = 21, - RBAC_PERM_SKIP_CHECK_CHAT_SPAM = 22, - RBAC_PERM_SKIP_CHECK_OVERSPEED_PING = 23, - RBAC_PERM_TWO_SIDE_INTERACTION_CHAT = 25, - RBAC_PERM_TWO_SIDE_INTERACTION_CHANNEL = 26, - RBAC_PERM_TWO_SIDE_INTERACTION_MAIL = 27, - RBAC_PERM_COMMANDS_SAVE_WITHOUT_DELAY = 30, - RBAC_PERM_COMMANDS_USE_UNSTUCK_WITH_ARGS = 31, - RBAC_PERM_COMMANDS_BE_ASSIGNED_TICKET = 32, - RBAC_PERM_COMMANDS_NOTIFY_COMMAND_NOT_FOUND_ERROR = 33, - RBAC_PERM_COMMANDS_APPEAR_IN_GM_LIST = 34, - RBAC_PERM_CAN_FILTER_WHISPERS = 36, - RBAC_PERM_CHAT_USE_STAFF_BADGE = 37, - RBAC_PERM_RESURRECT_WITH_FULL_HPS = 38, - RBAC_PERM_RESTORE_SAVED_GM_STATE = 39, - RBAC_PERM_USE_START_GM_LEVEL = 41, - RBAC_PERM_OPCODE_WORLD_TELEPORT = 42, - RBAC_PERM_OPCODE_WHOIS = 43, - RBAC_PERM_RECEIVE_GLOBAL_GM_TEXTMESSAGE = 44, - RBAC_PERM_SILENTLY_JOIN_CHANNEL = 45, - RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR = 46, - RBAC_PERM_CHECK_FOR_LOWER_SECURITY = 47, + RBAC_PERM_INSTANT_LOGOUT = 1, + RBAC_PERM_SKIP_QUEUE = 2, + RBAC_PERM_JOIN_NORMAL_BG = 3, + RBAC_PERM_JOIN_RANDOM_BG = 4, + RBAC_PERM_JOIN_ARENAS = 5, + RBAC_PERM_JOIN_DUNGEON_FINDER = 6, + RBAC_PERM_PLAYER_COMMANDS = 7, + RBAC_PERM_MODERATOR_COMMANDS = 8, + RBAC_PERM_GAMEMASTER_COMMANDS = 9, + RBAC_PERM_ADMINISTRATOR_COMMANDS = 10, + RBAC_PERM_LOG_GM_TRADE = 11, + RBAC_PERM_SKIP_CHECK_INSTANCE_REQUIRED_BOSSES = 13, + RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_TEAMMASK = 14, + RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_CLASSMASK = 15, + RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RACEMASK = 16, + RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME = 17, + RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_HEROIC_CHARACTER = 18, + RBAC_PERM_SKIP_CHECK_CHAT_CHANNEL_REQ = 19, + RBAC_PERM_SKIP_CHECK_DISABLE_MAP = 20, + RBAC_PERM_SKIP_CHECK_MORE_TALENTS_THAN_ALLOWED = 21, + RBAC_PERM_SKIP_CHECK_CHAT_SPAM = 22, + RBAC_PERM_SKIP_CHECK_OVERSPEED_PING = 23, + RBAC_PERM_TWO_SIDE_CHARACTER_CREATION = 24, + RBAC_PERM_TWO_SIDE_INTERACTION_CHAT = 25, + RBAC_PERM_TWO_SIDE_INTERACTION_CHANNEL = 26, + RBAC_PERM_TWO_SIDE_INTERACTION_MAIL = 27, + RBAC_PERM_COMMANDS_SAVE_WITHOUT_DELAY = 30, + RBAC_PERM_COMMANDS_USE_UNSTUCK_WITH_ARGS = 31, + RBAC_PERM_COMMANDS_BE_ASSIGNED_TICKET = 32, + RBAC_PERM_COMMANDS_NOTIFY_COMMAND_NOT_FOUND_ERROR = 33, + RBAC_PERM_COMMANDS_APPEAR_IN_GM_LIST = 34, + RBAC_PERM_CAN_FILTER_WHISPERS = 36, + RBAC_PERM_CHAT_USE_STAFF_BADGE = 37, + RBAC_PERM_RESURRECT_WITH_FULL_HPS = 38, + RBAC_PERM_RESTORE_SAVED_GM_STATE = 39, + RBAC_PERM_USE_START_GM_LEVEL = 41, + RBAC_PERM_OPCODE_WORLD_TELEPORT = 42, + RBAC_PERM_OPCODE_WHOIS = 43, + RBAC_PERM_RECEIVE_GLOBAL_GM_TEXTMESSAGE = 44, + RBAC_PERM_SILENTLY_JOIN_CHANNEL = 45, + RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR = 46, + RBAC_PERM_CHECK_FOR_LOWER_SECURITY = 47, RBAC_PERM_MAX }; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index f24b35ef83c..a8a500c093a 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -16774,7 +16774,8 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder) // check name limitations if (ObjectMgr::CheckPlayerName(m_name) != CHAR_NAME_SUCCESS || - (AccountMgr::IsPlayerAccount(GetSession()->GetSecurity()) && sObjectMgr->IsReservedName(m_name))) + (!GetSession()->HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME) && + sObjectMgr->IsReservedName(m_name))) { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG); stmt->setUInt16(0, uint16(AT_LOGIN_RENAME)); diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index b12893ff65f..eb5326e8094 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -274,7 +274,7 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData) WorldPacket data(SMSG_CHAR_CREATE, 1); // returned with diff.values in all cases - if (AccountMgr::IsPlayerAccount(GetSecurity())) + if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_TEAMMASK)) { if (uint32 mask = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_DISABLED)) { @@ -283,13 +283,17 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData) uint32 team = Player::TeamForRace(race_); switch (team) { - case ALLIANCE: disabled = mask & (1 << 0); break; - case HORDE: disabled = mask & (1 << 1); break; + case ALLIANCE: + disabled = mask & (1 << 0); + break; + case HORDE: + disabled = mask & (1 << 1); + break; } if (disabled) { - data << (uint8)CHAR_CREATE_DISABLED; + data << uint8(CHAR_CREATE_DISABLED); SendPacket(&data); return; } @@ -299,7 +303,7 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData) ChrClassesEntry const* classEntry = sChrClassesStore.LookupEntry(class_); if (!classEntry) { - data << (uint8)CHAR_CREATE_FAILED; + data << uint8(CHAR_CREATE_FAILED); SendPacket(&data); sLog->outError(LOG_FILTER_NETWORKIO, "Class (%u) not found in DBC while creating new char for account (ID: %u): wrong DBC files or cheater?", class_, GetAccountId()); return; @@ -308,7 +312,7 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData) ChrRacesEntry const* raceEntry = sChrRacesStore.LookupEntry(race_); if (!raceEntry) { - data << (uint8)CHAR_CREATE_FAILED; + data << uint8(CHAR_CREATE_FAILED); SendPacket(&data); sLog->outError(LOG_FILTER_NETWORKIO, "Race (%u) not found in DBC while creating new char for account (ID: %u): wrong DBC files or cheater?", race_, GetAccountId()); return; @@ -317,7 +321,7 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData) // prevent character creating Expansion race without Expansion account if (raceEntry->expansion > Expansion()) { - data << (uint8)CHAR_CREATE_EXPANSION; + data << uint8(CHAR_CREATE_EXPANSION); sLog->outError(LOG_FILTER_NETWORKIO, "Expansion %u account:[%d] tried to Create character with expansion %u race (%u)", Expansion(), GetAccountId(), raceEntry->expansion, race_); SendPacket(&data); return; @@ -326,13 +330,13 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData) // prevent character creating Expansion class without Expansion account if (classEntry->expansion > Expansion()) { - data << (uint8)CHAR_CREATE_EXPANSION_CLASS; + data << uint8(CHAR_CREATE_EXPANSION_CLASS); sLog->outError(LOG_FILTER_NETWORKIO, "Expansion %u account:[%d] tried to Create character with expansion %u class (%u)", Expansion(), GetAccountId(), classEntry->expansion, class_); SendPacket(&data); return; } - if (AccountMgr::IsPlayerAccount(GetSecurity())) + if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RACEMASK)) { uint32 raceMaskDisabled = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_DISABLED_RACEMASK); if ((1 << (race_ - 1)) & raceMaskDisabled) @@ -341,7 +345,10 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData) SendPacket(&data); return; } + } + if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_CLASSMASK)) + { uint32 classMaskDisabled = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_DISABLED_CLASSMASK); if ((1 << (class_ - 1)) & classMaskDisabled) { @@ -354,7 +361,7 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData) // prevent character creating with invalid name if (!normalizePlayerName(name)) { - data << (uint8)CHAR_NAME_NO_NAME; + data << uint8(CHAR_NAME_NO_NAME); SendPacket(&data); sLog->outError(LOG_FILTER_NETWORKIO, "Account:[%d] but tried to Create character with empty [name] ", GetAccountId()); return; @@ -369,29 +376,32 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData) return; } - if (AccountMgr::IsPlayerAccount(GetSecurity()) && sObjectMgr->IsReservedName(name)) + if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME) && sObjectMgr->IsReservedName(name)) { - data << (uint8)CHAR_NAME_RESERVED; + data << uint8(CHAR_NAME_RESERVED); SendPacket(&data); return; } - // speedup check for heroic class disabled case - uint32 heroic_free_slots = sWorld->getIntConfig(CONFIG_HEROIC_CHARACTERS_PER_REALM); - if (heroic_free_slots == 0 && AccountMgr::IsPlayerAccount(GetSecurity()) && class_ == CLASS_DEATH_KNIGHT) + if (class_ == CLASS_DEATH_KNIGHT && !HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_HEROIC_CHARACTER)) { - data << (uint8)CHAR_CREATE_UNIQUE_CLASS_LIMIT; - SendPacket(&data); - return; - } + // speedup check for heroic class disabled case + uint32 heroic_free_slots = sWorld->getIntConfig(CONFIG_HEROIC_CHARACTERS_PER_REALM); + if (heroic_free_slots == 0) + { + data << uint8(CHAR_CREATE_UNIQUE_CLASS_LIMIT); + SendPacket(&data); + return; + } - // speedup check for heroic class disabled case - uint32 req_level_for_heroic = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_MIN_LEVEL_FOR_HEROIC_CHARACTER); - if (AccountMgr::IsPlayerAccount(GetSecurity()) && class_ == CLASS_DEATH_KNIGHT && req_level_for_heroic > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL)) - { - data << (uint8)CHAR_CREATE_LEVEL_REQUIREMENT; - SendPacket(&data); - return; + // speedup check for heroic class disabled case + uint32 req_level_for_heroic = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_MIN_LEVEL_FOR_HEROIC_CHARACTER); + if (req_level_for_heroic > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL)) + { + data << uint8(CHAR_CREATE_LEVEL_REQUIREMENT); + SendPacket(&data); + return; + } } delete _charCreateCallback.GetParam(); // Delete existing if any, to make the callback chain reset to stage 0 @@ -482,7 +492,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte } } - bool allowTwoSideAccounts = !sWorld->IsPvPRealm() || sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_ACCOUNTS) || !AccountMgr::IsPlayerAccount(GetSecurity()); + bool allowTwoSideAccounts = !sWorld->IsPvPRealm() || sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_ACCOUNTS) || HasPermission(RBAC_PERM_TWO_SIDE_CHARACTER_CREATION); uint32 skipCinematics = sWorld->getIntConfig(CONFIG_SKIP_CINEMATICS); _charCreateCallback.FreeResult(); @@ -506,8 +516,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() || sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_ACCOUNTS) || !AccountMgr::IsPlayerAccount(GetSecurity()); + bool allowTwoSideAccounts = !sWorld->IsPvPRealm() || sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_ACCOUNTS) || HasPermission(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); if (result) { @@ -517,7 +528,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte Field* field = result->Fetch(); uint8 accRace = field[1].GetUInt8(); - if (AccountMgr::IsPlayerAccount(GetSecurity()) && createInfo->Class == CLASS_DEATH_KNIGHT) + if (checkHeroicReqs) { uint8 accClass = field[2].GetUInt8(); if (accClass == CLASS_DEATH_KNIGHT) @@ -576,7 +587,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte if (!haveSameRace) haveSameRace = createInfo->Race == accRace; - if (AccountMgr::IsPlayerAccount(GetSecurity()) && createInfo->Class == CLASS_DEATH_KNIGHT) + if (checkHeroicReqs) { uint8 acc_class = field[2].GetUInt8(); if (acc_class == CLASS_DEATH_KNIGHT) @@ -605,7 +616,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte } } - if (AccountMgr::IsPlayerAccount(GetSecurity()) && createInfo->Class == CLASS_DEATH_KNIGHT && !hasHeroicReqLevel) + if (checkHeroicReqs && !hasHeroicReqLevel) { WorldPacket data(SMSG_CHAR_CREATE, 1); data << uint8(CHAR_CREATE_LEVEL_REQUIREMENT); @@ -1122,7 +1133,7 @@ void WorldSession::HandleCharRenameOpcode(WorldPacket& recvData) } // check name limitations - if (AccountMgr::IsPlayerAccount(GetSecurity()) && sObjectMgr->IsReservedName(newName)) + if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME) && sObjectMgr->IsReservedName(newName)) { WorldPacket data(SMSG_CHAR_RENAME, 1); data << uint8(CHAR_NAME_RESERVED); @@ -1444,7 +1455,7 @@ void WorldSession::HandleCharCustomize(WorldPacket& recvData) } // check name limitations - if (AccountMgr::IsPlayerAccount(GetSecurity()) && sObjectMgr->IsReservedName(newName)) + if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME) && sObjectMgr->IsReservedName(newName)) { WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1); data << uint8(CHAR_NAME_RESERVED); @@ -1690,7 +1701,7 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData) return; } - if (AccountMgr::IsPlayerAccount(GetSecurity())) + if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RACEMASK)) { uint32 raceMaskDisabled = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_DISABLED_RACEMASK); if ((1 << (race - 1)) & raceMaskDisabled) @@ -1721,7 +1732,7 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData) } // check name limitations - if (AccountMgr::IsPlayerAccount(GetSecurity()) && sObjectMgr->IsReservedName(newname)) + if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME) && sObjectMgr->IsReservedName(newname)) { WorldPacket data(SMSG_CHAR_FACTION_CHANGE, 1); data << uint8(CHAR_NAME_RESERVED); -- cgit v1.2.3 From fb9893a190a76d964b3b833d4f80e2a01c3cbf65 Mon Sep 17 00:00:00 2001 From: Spp Date: Mon, 25 Feb 2013 15:37:20 +0100 Subject: Add missing change related to permission 'Two side interaction channel' --- src/server/game/Chat/Channels/Channel.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/game/Chat/Channels/Channel.cpp b/src/server/game/Chat/Channels/Channel.cpp index 50ac4f66dec..ce155bc6bad 100644 --- a/src/server/game/Chat/Channels/Channel.cpp +++ b/src/server/game/Chat/Channels/Channel.cpp @@ -607,6 +607,7 @@ void Channel::Say(uint64 guid, std::string const& what, uint32 lang) if (Player* player = ObjectAccessor::FindPlayer(guid)) chatTag = player->GetChatTag(); + // TODO: Add proper RBAC check if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL)) lang = LANG_UNIVERSAL; @@ -669,7 +670,9 @@ void Channel::Invite(Player const* player, std::string const& newname) return; } - if (newp->GetTeam() != player->GetTeam() && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL)) + if (newp->GetTeam() != player->GetTeam() && (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL) || + !player->GetSession()->HasPermission(RBAC_PERM_TWO_SIDE_INTERACTION_CHANNEL) || + !newp->GetSession()->HasPermission(RBAC_PERM_TWO_SIDE_INTERACTION_CHANNEL))) { WorldPacket data; MakeInviteWrongFaction(&data); -- cgit v1.2.3 From 0c2402df955091f73898713c45c3f02cd8c25adf Mon Sep 17 00:00:00 2001 From: Spp Date: Mon, 25 Feb 2013 15:47:12 +0100 Subject: Core/RBAC: Create new permissions 'See two side who list', 'Add friends of other faction', 'See all levels with who command' and 'Allows to add a gm to friend list' --- sql/updates/auth/2013_02_25_14_auth_misc.sql | 39 +++++++++++++++ src/server/game/Accounts/RBAC.h | 5 ++ src/server/game/Chat/Channels/Channel.cpp | 4 +- src/server/game/Entities/Player/SocialMgr.cpp | 71 ++++++++++++++------------- src/server/game/Handlers/MiscHandler.cpp | 45 +++++++++-------- 5 files changed, 107 insertions(+), 57 deletions(-) create mode 100644 sql/updates/auth/2013_02_25_14_auth_misc.sql (limited to 'src') diff --git a/sql/updates/auth/2013_02_25_14_auth_misc.sql b/sql/updates/auth/2013_02_25_14_auth_misc.sql new file mode 100644 index 00000000000..c02b600b12f --- /dev/null +++ b/sql/updates/auth/2013_02_25_14_auth_misc.sql @@ -0,0 +1,39 @@ +-- Add new permissions +DELETE FROM `rbac_permissions` WHERE `id` IN (28, 29, 35, 40); +INSERT INTO `rbac_permissions` (`id`, `name`) VALUES +(28, 'See two side who list'), +(29, 'Add friends of other faction'), +(35, 'See all security levels with who command'), +(40, 'Allows to add a gm to friend list'); + +-- Add new role +DELETE FROM `rbac_roles` WHERE `id` IN (33, 34); +INSERT INTO `rbac_roles` (`id`, `name`) VALUES +(35, 'See two side who list'), +(36, 'Add friends of other faction'), +(37, 'See all security levels with who command'), +(38, 'Allows to add a gm to friend list'); + +-- Add the permission to the role +DELETE FROM `rbac_role_permissions` WHERE `roleId` IN (35, 36, 37, 38); +INSERT INTO `rbac_role_permissions` (`roleId`, `permissionId`) VALUES +(35, 28), +(36, 29), +(37, 35), +(38, 40); + +-- Add it to all groups +DELETE FROM `rbac_role_permissions` WHERE `roleId` IN (35, 36, 37, 38); +INSERT INTO `rbac_group_roles` (`groupId`, `roleId`) VALUES +(2, 35), +(3, 35), +(4, 35), +(2, 36), +(3, 36), +(4, 36), +(2, 37), +(3, 37), +(4, 37), +(2, 38), +(3, 38), +(4, 38); diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h index eb9220a317a..0bd193d3841 100644 --- a/src/server/game/Accounts/RBAC.h +++ b/src/server/game/Accounts/RBAC.h @@ -59,6 +59,7 @@ enum RBACPermissions RBAC_PERM_GAMEMASTER_COMMANDS = 9, RBAC_PERM_ADMINISTRATOR_COMMANDS = 10, RBAC_PERM_LOG_GM_TRADE = 11, + // Free = 12 RBAC_PERM_SKIP_CHECK_INSTANCE_REQUIRED_BOSSES = 13, RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_TEAMMASK = 14, RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_CLASSMASK = 15, @@ -74,15 +75,19 @@ enum RBACPermissions RBAC_PERM_TWO_SIDE_INTERACTION_CHAT = 25, RBAC_PERM_TWO_SIDE_INTERACTION_CHANNEL = 26, RBAC_PERM_TWO_SIDE_INTERACTION_MAIL = 27, + RBAC_PERM_TWO_SIDE_WHO_LIST = 28, + RBAC_PERM_TWO_SIDE_ADD_FRIEND = 29, RBAC_PERM_COMMANDS_SAVE_WITHOUT_DELAY = 30, RBAC_PERM_COMMANDS_USE_UNSTUCK_WITH_ARGS = 31, RBAC_PERM_COMMANDS_BE_ASSIGNED_TICKET = 32, RBAC_PERM_COMMANDS_NOTIFY_COMMAND_NOT_FOUND_ERROR = 33, RBAC_PERM_COMMANDS_APPEAR_IN_GM_LIST = 34, + RBAC_PERM_WHO_SEE_ALL_SEC_LEVELS = 35, RBAC_PERM_CAN_FILTER_WHISPERS = 36, RBAC_PERM_CHAT_USE_STAFF_BADGE = 37, RBAC_PERM_RESURRECT_WITH_FULL_HPS = 38, RBAC_PERM_RESTORE_SAVED_GM_STATE = 39, + RBAC_PERM_ALLOW_GM_FRIEND = 40, RBAC_PERM_USE_START_GM_LEVEL = 41, RBAC_PERM_OPCODE_WORLD_TELEPORT = 42, RBAC_PERM_OPCODE_WHOIS = 43, diff --git a/src/server/game/Chat/Channels/Channel.cpp b/src/server/game/Chat/Channels/Channel.cpp index ce155bc6bad..86d03859bc7 100644 --- a/src/server/game/Chat/Channels/Channel.cpp +++ b/src/server/game/Chat/Channels/Channel.cpp @@ -552,7 +552,9 @@ void Channel::List(Player const* player) // PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters // MODERATOR, GAME MASTER, ADMINISTRATOR can see all - if (member && (!AccountMgr::IsPlayerAccount(player->GetSession()->GetSecurity()) || member->GetSession()->GetSecurity() <= AccountTypes(gmLevelInWhoList)) && + if (member && + (player->GetSession()->HasPermission(RBAC_PERM_WHO_SEE_ALL_SEC_LEVELS) || + member->GetSession()->GetSecurity() <= AccountTypes(gmLevelInWhoList)) && member->IsVisibleGloballyFor(player)) { data << uint64(i->first); diff --git a/src/server/game/Entities/Player/SocialMgr.cpp b/src/server/game/Entities/Player/SocialMgr.cpp index e5bbac59e00..7a2b36e23bf 100644 --- a/src/server/game/Entities/Player/SocialMgr.cpp +++ b/src/server/game/Entities/Player/SocialMgr.cpp @@ -216,34 +216,38 @@ void SocialMgr::GetFriendInfo(Player* player, uint32 friendGUID, FriendInfo &fri friendInfo.Level = 0; friendInfo.Class = 0; - Player* pFriend = ObjectAccessor::FindPlayer(friendGUID); - if (!pFriend) + Player* target = ObjectAccessor::FindPlayer(friendGUID); + if (!target) return; - uint32 team = player->GetTeam(); - AccountTypes security = player->GetSession()->GetSecurity(); - bool allowTwoSideWhoList = sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_WHO_LIST); - AccountTypes gmLevelInWhoList = AccountTypes(sWorld->getIntConfig(CONFIG_GM_LEVEL_IN_WHO_LIST)); - PlayerSocialMap::iterator itr = player->GetSocial()->m_playerSocialMap.find(friendGUID); if (itr != player->GetSocial()->m_playerSocialMap.end()) friendInfo.Note = itr->second.Note; // PLAYER see his team only and PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters // MODERATOR, GAME MASTER, ADMINISTRATOR can see all - if (pFriend && - (!AccountMgr::IsPlayerAccount(security) || - ((pFriend->GetTeam() == team || allowTwoSideWhoList) && (pFriend->GetSession()->GetSecurity() <= gmLevelInWhoList))) && - pFriend->IsVisibleGloballyFor(player)) + + if (!player->GetSession()->HasPermission(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() && + !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_WHO_LIST) && !player->GetSession()->HasPermission(RBAC_PERM_TWO_SIDE_WHO_LIST)) + return; + + if (target->IsVisibleGloballyFor(player)) { - friendInfo.Status = FRIEND_STATUS_ONLINE; - if (pFriend->isAFK()) - friendInfo.Status = FRIEND_STATUS_AFK; - if (pFriend->isDND()) + if (target->isDND()) friendInfo.Status = FRIEND_STATUS_DND; - friendInfo.Area = pFriend->GetZoneId(); - friendInfo.Level = pFriend->getLevel(); - friendInfo.Class = pFriend->getClass(); + else if (target->isAFK()) + friendInfo.Status = FRIEND_STATUS_AFK; + else + friendInfo.Status = FRIEND_STATUS_ONLINE; + + friendInfo.Area = target->GetZoneId(); + friendInfo.Level = target->getLevel(); + friendInfo.Class = target->getClass(); } } @@ -295,28 +299,29 @@ void SocialMgr::BroadcastToFriendListers(Player* player, WorldPacket* packet) if (!player) return; - uint32 team = player->GetTeam(); - AccountTypes security = player->GetSession()->GetSecurity(); - uint32 guid = player->GetGUIDLow(); - AccountTypes gmLevelInWhoList = AccountTypes(sWorld->getIntConfig(CONFIG_GM_LEVEL_IN_WHO_LIST)); - bool allowTwoSideWhoList = sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_WHO_LIST); - for (SocialMap::const_iterator itr = m_socialMap.begin(); itr != m_socialMap.end(); ++itr) { - PlayerSocialMap::const_iterator itr2 = itr->second.m_playerSocialMap.find(guid); + PlayerSocialMap::const_iterator itr2 = itr->second.m_playerSocialMap.find(player->GetGUID()); if (itr2 != itr->second.m_playerSocialMap.end() && (itr2->second.Flags & SOCIAL_FLAG_FRIEND)) { - Player* pFriend = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER)); + Player* target = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER)); + if (!target || !target->IsInWorld()) + continue; + + if (!target->GetSession()->HasPermission(RBAC_PERM_WHO_SEE_ALL_SEC_LEVELS) && + player->GetSession()->GetSecurity() > AccountTypes(sWorld->getIntConfig(CONFIG_GM_LEVEL_IN_WHO_LIST))) + continue; + + // player can see member of other team only if CONFIG_ALLOW_TWO_SIDE_WHO_LIST + if (target->GetTeam() != player->GetTeam() && + !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_WHO_LIST) && + !target->GetSession()->HasPermission(RBAC_PERM_TWO_SIDE_WHO_LIST)) + continue; // PLAYER see his team only and PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters // MODERATOR, GAME MASTER, ADMINISTRATOR can see all - if (pFriend && pFriend->IsInWorld() && - (!AccountMgr::IsPlayerAccount(pFriend->GetSession()->GetSecurity()) || - ((pFriend->GetTeam() == team || allowTwoSideWhoList) && security <= gmLevelInWhoList)) && - player->IsVisibleGloballyFor(pFriend)) - { - pFriend->GetSession()->SendPacket(packet); - } + if (player->IsVisibleGloballyFor(target)) + target->GetSession()->SendPacket(packet); } } } diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index 45cf1d17450..3864acb8f88 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -241,7 +241,7 @@ void WorldSession::HandleWhoOpcode(WorldPacket& recvData) level_max = STRONG_MAX_LEVEL; uint32 team = _player->GetTeam(); - uint32 security = GetSecurity(); + bool allowTwoSideWhoList = sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_WHO_LIST); uint32 gmLevelInWhoList = sWorld->getIntConfig(CONFIG_GM_LEVEL_IN_WHO_LIST); uint32 displaycount = 0; @@ -254,42 +254,40 @@ void WorldSession::HandleWhoOpcode(WorldPacket& recvData) HashMapHolder::MapType const& m = sObjectAccessor->GetPlayers(); for (HashMapHolder::MapType::const_iterator itr = m.begin(); itr != m.end(); ++itr) { - if (AccountMgr::IsPlayerAccount(security)) - { - // player can see member of other team only if CONFIG_ALLOW_TWO_SIDE_WHO_LIST - if (itr->second->GetTeam() != team && !allowTwoSideWhoList) - continue; + Player* target = itr->second; + // player can see member of other team only if CONFIG_ALLOW_TWO_SIDE_WHO_LIST + if (target->GetTeam() != team && !allowTwoSideWhoList && !HasPermission(RBAC_PERM_TWO_SIDE_WHO_LIST)) + continue; - // player can see MODERATOR, GAME MASTER, ADMINISTRATOR only if CONFIG_GM_IN_WHO_LIST - if ((itr->second->GetSession()->GetSecurity() > AccountTypes(gmLevelInWhoList))) - 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)) + continue; - //do not process players which are not in world - if (!(itr->second->IsInWorld())) + // do not process players which are not in world + if (!target->IsInWorld()) continue; // check if target is globally visible for player - if (!(itr->second->IsVisibleGloballyFor(_player))) + if (!target->IsVisibleGloballyFor(_player)) continue; // check if target's level is in level range - uint8 lvl = itr->second->getLevel(); + uint8 lvl = target->getLevel(); if (lvl < level_min || lvl > level_max) continue; // check if class matches classmask - uint32 class_ = itr->second->getClass(); + uint8 class_ = target->getClass(); if (!(classmask & (1 << class_))) continue; // check if race matches racemask - uint32 race = itr->second->getRace(); + uint32 race = target->getRace(); if (!(racemask & (1 << race))) continue; - uint32 pzoneid = itr->second->GetZoneId(); - uint8 gender = itr->second->getGender(); + uint32 pzoneid = target->GetZoneId(); + uint8 gender = target->getGender(); bool z_show = true; for (uint32 i = 0; i < zones_count; ++i) @@ -305,7 +303,7 @@ void WorldSession::HandleWhoOpcode(WorldPacket& recvData) if (!z_show) continue; - std::string pname = itr->second->GetName(); + std::string pname = target->GetName(); std::wstring wpname; if (!Utf8toWStr(pname, wpname)) continue; @@ -314,7 +312,7 @@ void WorldSession::HandleWhoOpcode(WorldPacket& recvData) if (!(wplayer_name.empty() || wpname.find(wplayer_name) != std::wstring::npos)) continue; - std::string gname = sGuildMgr->GetGuildNameById(itr->second->GetGuildId()); + std::string gname = sGuildMgr->GetGuildNameById(target->GetGuildId()); std::wstring wgname; if (!Utf8toWStr(gname, wgname)) continue; @@ -324,7 +322,7 @@ void WorldSession::HandleWhoOpcode(WorldPacket& recvData) continue; std::string aname; - if (AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(itr->second->GetZoneId())) + if (AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(pzoneid)) aname = areaEntry->area_name[GetSessionDbcLocale()]; bool s_show = true; @@ -575,13 +573,14 @@ void WorldSession::HandleAddFriendOpcodeCallBack(PreparedQueryResult result, std team = Player::TeamForRace(fields[1].GetUInt8()); friendAccountId = fields[2].GetUInt32(); - if (!AccountMgr::IsPlayerAccount(GetSecurity()) || sWorld->getBoolConfig(CONFIG_ALLOW_GM_FRIEND) || AccountMgr::IsPlayerAccount(AccountMgr::GetSecurity(friendAccountId, realmID))) + if (HasPermission(RBAC_PERM_ALLOW_GM_FRIEND) || sWorld->getBoolConfig(CONFIG_ALLOW_GM_FRIEND) || + AccountMgr::IsPlayerAccount(AccountMgr::GetSecurity(friendAccountId, realmID))) { if (friendGuid) { if (friendGuid == GetPlayer()->GetGUID()) friendResult = FRIEND_SELF; - else if (GetPlayer()->GetTeam() != team && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_ADD_FRIEND) && AccountMgr::IsPlayerAccount(GetSecurity())) + else if (GetPlayer()->GetTeam() != team && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_ADD_FRIEND) && !HasPermission(RBAC_PERM_TWO_SIDE_ADD_FRIEND)) friendResult = FRIEND_ENEMY; else if (GetPlayer()->GetSocial()->HasFriend(GUID_LOPART(friendGuid))) friendResult = FRIEND_ALREADY; -- cgit v1.2.3 From d47b95cc0a09c7fd5c10b6e2a7bb9d33d7f11db1 Mon Sep 17 00:00:00 2001 From: Spp Date: Mon, 25 Feb 2013 15:51:48 +0100 Subject: Missing change related to permission 'Change channel settings' --- src/server/game/Chat/Channels/Channel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/game/Chat/Channels/Channel.cpp b/src/server/game/Chat/Channels/Channel.cpp index 86d03859bc7..5f6bc8b7865 100644 --- a/src/server/game/Chat/Channels/Channel.cpp +++ b/src/server/game/Chat/Channels/Channel.cpp @@ -363,7 +363,7 @@ void Channel::UnBan(Player const* player, std::string const& badname) return; } - if (!playersStore[good].IsModerator() && !AccountMgr::IsGMAccount(sec)) + if (!playersStore[good].IsModerator() && !player->GetSession()->HasPermission(RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR)) { WorldPacket data; MakeNotModerator(&data); -- cgit v1.2.3 From ffdf54b0827620f18d71f45aebc72d0817b0e7b6 Mon Sep 17 00:00:00 2001 From: Spp Date: Mon, 25 Feb 2013 15:59:16 +0100 Subject: Core/RBAC: Remove couple of harcoded checks for GM level and use Permission 'Log gm trade' --- src/server/game/Handlers/AuctionHouseHandler.cpp | 4 ++-- src/server/game/Handlers/TradeHandler.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/server/game/Handlers/AuctionHouseHandler.cpp b/src/server/game/Handlers/AuctionHouseHandler.cpp index 6fc88f441bb..22070d4c2c2 100644 --- a/src/server/game/Handlers/AuctionHouseHandler.cpp +++ b/src/server/game/Handlers/AuctionHouseHandler.cpp @@ -245,7 +245,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[i]) { - if (GetSecurity() > SEC_PLAYER && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) + if (HasPermission(RBAC_PERM_LOG_GM_TRADE) && sWorld->getBoolConfig(CONFIG_GM_LOG_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()); @@ -291,7 +291,7 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData) return; } - if (GetSecurity() > SEC_PLAYER && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) + if (HasPermission(RBAC_PERM_LOG_GM_TRADE) && sWorld->getBoolConfig(CONFIG_GM_LOG_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/TradeHandler.cpp b/src/server/game/Handlers/TradeHandler.cpp index 63ab6d27701..7fbb68b70f8 100644 --- a/src/server/game/Handlers/TradeHandler.cpp +++ b/src/server/game/Handlers/TradeHandler.cpp @@ -170,7 +170,7 @@ void WorldSession::moveItems(Item* myItems[], Item* hisItems[]) { // logging sLog->outDebug(LOG_FILTER_NETWORKIO, "player storing: %u", hisItems[i]->GetGUIDLow()); - if (HasPermission(RBAC_PERM_LOG_GM_TRADE) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) + if (HasPermission(RBAC_PERM_LOG_GM_TRADE) && sWorld->getBoolConfig(CONFIG_GM_LOG_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(), -- cgit v1.2.3