From 760d62e934f8289cdd9950c04a4dbf588eddd742 Mon Sep 17 00:00:00 2001 From: Bezo Date: Wed, 30 Jan 2013 13:09:41 +0200 Subject: Add Mute reason and mute by to the db so you can get this info from the db with the pinfo command when player get muted. old LOGIN_UPD_MUTE_TIME change to LOGIN_UPD_MUTE_TIME_LOGIN due the use of it when character login to world. --- src/server/scripts/Commands/cs_misc.cpp | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'src/server/scripts') diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index 367591080d2..973d466bab5 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -1550,6 +1550,8 @@ public: std::string userName = handler->GetTrinityString(LANG_ERROR); std::string eMail = handler->GetTrinityString(LANG_ERROR); + std::string muteReason = ""; + std::string muteBy = ""; std::string lastIp = handler->GetTrinityString(LANG_ERROR); uint32 security = 0; std::string lastLogin = handler->GetTrinityString(LANG_ERROR); @@ -1566,6 +1568,8 @@ public: security = fields[1].GetUInt8(); eMail = fields[2].GetString(); muteTime = fields[5].GetUInt64(); + muteReason = fields[6].GetString(); + muteBy = fields[7].GetString(); if (eMail.empty()) eMail = "-"; @@ -1627,7 +1631,7 @@ public: } if (muteTime > 0) - handler->PSendSysMessage(LANG_PINFO_MUTE, secsToTimeString(muteTime - time(NULL), true).c_str()); + handler->PSendSysMessage(LANG_PINFO_MUTE, secsToTimeString(muteTime - time(NULL), true).c_str(), muteBy.c_str(), muteReason.c_str()); if (banTime >= 0) handler->PSendSysMessage(LANG_PINFO_BAN, banTime > 0 ? secsToTimeString(banTime - time(NULL), true).c_str() : "permanently", bannedby.c_str(), banreason.c_str()); @@ -1826,6 +1830,11 @@ public: return false; PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_MUTE_TIME); + std::string muteBy = ""; + if (handler->GetSession()) + muteBy = handler->GetSession()->GetPlayerName(); + else + muteBy = "Console"; if (target) { @@ -1833,7 +1842,7 @@ public: int64 muteTime = time(NULL) + notSpeakTime * MINUTE; target->GetSession()->m_muteTime = muteTime; stmt->setInt64(0, muteTime); - ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOUR_CHAT_DISABLED, notSpeakTime, muteReasonStr.c_str()); + ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOUR_CHAT_DISABLED, notSpeakTime, muteBy.c_str(), muteReasonStr.c_str()); } else { @@ -1842,7 +1851,9 @@ public: stmt->setInt64(0, muteTime); } - stmt->setUInt32(1, accountId); + stmt->setString(1, muteReasonStr.c_str()); + stmt->setString(2, muteBy.c_str()); + stmt->setUInt32(3, accountId); LoginDatabase.Execute(stmt); std::string nameLink = handler->playerLink(targetName); @@ -1885,7 +1896,9 @@ public: PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_MUTE_TIME); stmt->setInt64(0, 0); - stmt->setUInt32(1, accountId); + stmt->setString(1, ""); + stmt->setString(2, ""); + stmt->setUInt32(3, accountId); LoginDatabase.Execute(stmt); if (target) -- cgit v1.2.3 From ffb4c63fe303111c1694e89dcb19419226974fcd Mon Sep 17 00:00:00 2001 From: w1sht0l1v3 Date: Mon, 4 Feb 2013 05:22:09 +0200 Subject: DB/Misc: Add full script for Pilfering Perfume (A:24656 H:24541) Closes #5205 --- sql/updates/world/2013_02_04_02_world_misc.sql | 119 +++++++++++++++++++++++++ src/server/scripts/Spells/spell_generic.cpp | 58 ++++++++++++ 2 files changed, 177 insertions(+) create mode 100644 sql/updates/world/2013_02_04_02_world_misc.sql (limited to 'src/server/scripts') diff --git a/sql/updates/world/2013_02_04_02_world_misc.sql b/sql/updates/world/2013_02_04_02_world_misc.sql new file mode 100644 index 00000000000..300d0e31bcb --- /dev/null +++ b/sql/updates/world/2013_02_04_02_world_misc.sql @@ -0,0 +1,119 @@ +-- Pilfering Perfume (A:24656 H:24541) + +SET @QUEST_A := 24656; +SET @QUEST_H := 24541; + +SET @SNIP := 38066; -- Inspector Snip Snagglebolt +SET @SNAP := 37172; -- Detective Snap Snagglebolt +SET @MENUID := 10976; + +SET @TRIGGER_SW_OUT := 5703; -- outside +SET @TRIGGER_SW_IN := 5704; -- inside +SET @TRIGGER_ORG_OUT := 5705; -- outside +SET @TRIGGER_ORG_IN := 5706; -- inside + +SET @SPELL_UNIFORM := 71450; -- Crown Parcel Service Uniform +SET @SPELL_CONTRABAND := 71459; -- Crown Chemical Co. Contraband + +SET @SPELL_CREDIT_A := 71522; -- Crown Chemical Co. Supplies +SET @SPELL_CREDIT_H := 71539; -- Crown Chemical Co. Supplies + +SET @GUID := 48571; -- set by TDB,need 3 (48571,48572,48573) +SET @EVENT := 8; -- Love is in the Air +SET @NPC_GUARD := 37671; -- Crown Supply Guard + +-- missing npcs on horde side +DELETE FROM `creature` WHERE `id`=@NPC_GUARD; +INSERT INTO `creature` (`guid`,`id`,`map`,`spawnMask`,`phaseMask`,`modelid`,`equipment_id`,`position_x`,`position_y`,`position_z`,`orientation`,`spawntimesecs`,`spawndist`,`currentwaypoint`,`curhealth`,`curmana`,`MovementType`,`npcflag`,`unit_flags`,`dynamicflags`) VALUES +(@GUID+0,@NPC_GUARD,1,1,1,0,0,1391.2,-4486.23,31.4544,3.3355,300,0,0,42,0,0,0,0,0), +(@GUID+1,@NPC_GUARD,1,1,1,0,0,1392.66,-4481.87,31.3782,1.97284,300,0,0,42,0,0,0,0,0), +(@GUID+2,@NPC_GUARD,1,1,1,0,0,1393.92,-4489.57,31.4737,4.93701,300,0,0,42,0,0,0,0,0); + +DELETE FROM `game_event_creature` WHERE `eventEntry`=@EVENT AND `guid` BETWEEN @GUID+0 AND @GUID+2; +INSERT INTO `game_event_creature` (`eventEntry`,`guid`) VALUES +(@EVENT,@GUID+0), +(@EVENT,@GUID+1), +(@EVENT,@GUID+2); + +-- removing a wrong spawn +DELETE FROM `creature` WHERE `guid`=40507; +DELETE FROM `game_event_creature` WHERE `guid`=40507; + +-- deleting wrong previous spawns and reusing some guids to spawn proper ones +DELETE FROM `gameobject` WHERE `guid` IN (24416,24417,24418,24419,24420,24421,24422,24423,24433,24434,24435,24436,24437,24438,24439,24440,24441); +INSERT INTO `gameobject` (`guid`,`id`,`map`,`spawnMask`,`phaseMask`,`position_x`,`position_y`,`position_z`,`orientation`,`rotation0`,`rotation1`,`rotation2`,`rotation3`,`spawntimesecs`,`animprogress`,`state`) VALUES +(24416,181015,1,1,1,1392.938,-4485.202,31.41421,0,0,0,0,1,120,255,1), +(24417,201778,1,1,1,1393.677,-4486.033,32.67227,0,0,0,0,1,120,255,1), +(24418,201752,1,1,1,1394.184,-4484.108,31.24833,4.32842,0,0,0,1,120,255,1), +(24419,201778,1,1,1,1394.26,-4484.368,32.50796,5.148723,0,0,0,1,120,255,1), +(24420,201752,1,1,1,1393.319,-4486.797,31.42903,4.101525,0,0,0,1,120,255,1), +(24421,201752,1,1,1,1394.401,-4485.688,31.35416,5.916668,0,0,0,1,120,255,1), +(24422,201752,1,1,1,1394.042,-4488.397,31.4775,4.32842,0,0,0,1,120,255,1), +(24423,201752,1,1,1,1396.476,-4482.715,32.14788,4.32842,0,0,0,1,120,255,1), +(24433,181015,1,1,1,1395.002,-4487.113,31.37537,3.874631,0,0,0,1,120,255,1), +(24434,181015,1,1,1,1396.632,-4482.505,30.87226,5.166176,0,0,0,1,120,255,1), +(24435,201752,1,1,1,1395.813,-4486.439,32.56021,1.710422,0,0,0,1,120,255,1), +(24436,201752,1,1,1,1396.595,-4486.056,31.15484,4.32842,0,0,0,1,120,255,1), +(24437,201752,1,1,1,1397.377,-4488.021,33.71862,0.157079,0,0,0,1,120,255,1), +(24438,181015,1,1,1,1397.51,-4487.901,32.46279,3.68265,0,0,0,1,120,255,1), +(24439,201752,1,1,1,1397.571,-4487.939,31.21067,3.33359,0,0,0,1,120,255,1); +-- these guids will remain free +DELETE FROM `game_event_gameobject` WHERE `eventEntry`=@EVENT AND `guid` IN (24440,24441); + +-- Snip & Snap sai +UPDATE `creature_template` SET `npcflag`=`npcflag`|1|2,`gossip_menu_id`=@MENUID,`AIName`='SmartAI' WHERE `entry` IN (@SNIP,@SNAP); +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (@SNIP,@SNAP) AND `source_type`=0; +INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(@SNIP,0,0,0,19,0,100,0,@QUEST_A,0,0,0,11,@SPELL_UNIFORM,0,0,0,0,0,7,0,0,0,0,0,0,0,'Snip - On quest accept - Spellcast'), +(@SNIP,0,1,2,62,0,100,0,@MENUID,0,0,0,72,0,0,0,0,0,0,7,0,0,0,0,0,0,0,'Snip - On gossip option select - Close gossip'), +(@SNIP,0,2,0,61,0,100,0,0,0,0,0,11,@SPELL_UNIFORM,0,0,0,0,0,7,0,0,0,0,0,0,0,'Snip - On gossip option accept - Spellcast'), +-- +(@SNAP,0,0,0,19,0,100,0,@QUEST_H,0,0,0,11,@SPELL_UNIFORM,0,0,0,0,0,7,0,0,0,0,0,0,0,'Snap - On quest accept - Spellcast'), +(@SNAP,0,1,2,62,0,100,0,@MENUID,0,0,0,72,0,0,0,0,0,0,7,0,0,0,0,0,0,0,'Snap - On gossip option select - Close gossip'), +(@SNAP,0,2,0,61,0,100,0,0,0,0,0,11,@SPELL_UNIFORM,0,0,0,0,0,7,0,0,0,0,0,0,0,'Snap - On gossip option accept - Spellcast'); + +DELETE FROM `areatrigger_involvedrelation` WHERE `id` IN (@TRIGGER_SW_OUT,@TRIGGER_SW_IN,@TRIGGER_ORG_OUT,@TRIGGER_ORG_IN); +INSERT INTO `areatrigger_involvedrelation` (`id`,`quest`) VALUES +(@TRIGGER_SW_OUT,@QUEST_A), +(@TRIGGER_SW_IN,@QUEST_A), +-- +(@TRIGGER_ORG_OUT,@QUEST_H), +(@TRIGGER_ORG_IN,@QUEST_H); + +DELETE FROM `areatrigger_scripts` WHERE `entry` IN (@TRIGGER_SW_OUT,@TRIGGER_SW_IN,@TRIGGER_ORG_OUT,@TRIGGER_ORG_IN); +INSERT INTO `areatrigger_scripts` (`entry`,`ScriptName`) VALUES +(@TRIGGER_SW_OUT,'SmartTrigger'), +(@TRIGGER_SW_IN,'SmartTrigger'), +-- +(@TRIGGER_ORG_OUT,'SmartTrigger'), +(@TRIGGER_ORG_IN,'SmartTrigger'); + +-- usig invoker cast because normal cast doesn't want to work(LoS issue,i think) +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (@TRIGGER_SW_OUT,@TRIGGER_SW_IN,@TRIGGER_ORG_OUT,@TRIGGER_ORG_IN) AND `source_type`=2; +INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(@TRIGGER_SW_OUT,2,0,0,46,0,100,0,@TRIGGER_SW_OUT,0,0,0,85,@SPELL_CONTRABAND,0,0,0,0,0,7,0,0,0,0,0,0,0,"On Trigger - Cast - Invoker"), +(@TRIGGER_SW_IN,2,0,0,46,0,100,0,@TRIGGER_SW_IN,0,0,0,85,@SPELL_CREDIT_A,0,0,0,0,0,7,0,0,0,0,0,0,0,"On Trigger - Cast - Invoker"), +-- +(@TRIGGER_ORG_OUT,2,0,0,46,0,100,0,@TRIGGER_ORG_OUT,0,0,0,85,@SPELL_CONTRABAND,0,0,0,0,0,7,0,0,0,0,0,0,0,"On Trigger - Cast - Invoker"), +(@TRIGGER_ORG_IN,2,0,0,46,0,100,0,@TRIGGER_ORG_IN,0,0,0,85,@SPELL_CREDIT_H,0,0,0,0,0,7,0,0,0,0,0,0,0,"On Trigger - Cast - Invoker"); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=22 AND `SourceEntry` IN (@TRIGGER_SW_OUT,@TRIGGER_SW_IN,@TRIGGER_ORG_OUT,@TRIGGER_ORG_IN); +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=@MENUID; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`SourceId`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionTarget`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`NegativeCondition`,`ErrorType`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES +(22,1,@TRIGGER_SW_OUT,2,0,1,0,@SPELL_UNIFORM,0,0,0,0,0,'','execute sai only if player has aura'), +(22,1,@TRIGGER_SW_IN,2,0,1,0,@SPELL_CONTRABAND,0,0,0,0,0,'','execute sai only if player has aura'), +(15,@MENUID,0,0,0,9,0,@QUEST_A,0,0,0,0,0,'','show gossip option only if player has quest taken'), +-- +(22,1,@TRIGGER_ORG_OUT,2,0,1,0,@SPELL_UNIFORM,0,0,0,0,0,'','execute sai only if player has aura'), +(22,1,@TRIGGER_ORG_IN,2,0,1,0,@SPELL_CONTRABAND,0,0,0,0,0,'','execute sai only if player has aura'), +(15,@MENUID,0,0,1,9,0,@QUEST_H,0,0,0,0,0,'','show gossip option only if player has quest taken'); + +DELETE FROM `spell_linked_spell` WHERE `spell_trigger` IN (@SPELL_CREDIT_A,@SPELL_CREDIT_H,-@SPELL_UNIFORM); +INSERT INTO `spell_linked_spell` (`spell_trigger`,`spell_effect`,`type`,`comment`) VALUES +(@SPELL_CREDIT_A,-@SPELL_UNIFORM,1,'Remove Crown Parcel Service Uniform on Crown Chemical Co. Supplies hit'), +(@SPELL_CREDIT_H,-@SPELL_UNIFORM,1,'Remove Crown Parcel Service Uniform on Crown Chemical Co. Supplies hit'), +(-@SPELL_UNIFORM,-@SPELL_CONTRABAND,0,'Remove Crown Chemical Co. Contraband when Crown Parcel Service Uniform is removed'); + +DELETE FROM `spell_script_names` WHERE `spell_id`=@SPELL_UNIFORM; +INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES +(@SPELL_UNIFORM,'spell_gen_aura_service_uniform'); diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index 05fad623114..e7befff87a3 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -3518,6 +3518,63 @@ class spell_gen_replenishment : public SpellScriptLoader } }; +enum ServiceUniform +{ + SPELL_SERVICE_UNIFORM = 71450, + + MODEL_GOBLIN_MALE = 31002, + MODEL_GOBLIN_FEMALE = 31003, +}; + +class spell_gen_aura_service_uniform : public SpellScriptLoader +{ + public: + spell_gen_aura_service_uniform() : SpellScriptLoader("spell_gen_aura_service_uniform") { } + + class spell_gen_aura_service_uniform_AuraScript : public AuraScript + { + PrepareAuraScript(spell_gen_aura_service_uniform_AuraScript); + + bool Validate(SpellInfo const* /*spell*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_SERVICE_UNIFORM)) + return false; + return true; + } + + void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + // Apply model goblin + Unit* target = GetTarget(); + if (target->GetTypeId() == TYPEID_PLAYER) + { + if (target->getGender() == GENDER_MALE) + target->SetDisplayId(MODEL_GOBLIN_MALE); + else + target->SetDisplayId(MODEL_GOBLIN_FEMALE); + } + } + + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* target = GetTarget(); + if (target->GetTypeId() == TYPEID_PLAYER) + target->RestoreDisplayId(); + } + + void Register() + { + AfterEffectApply += AuraEffectRemoveFn(spell_gen_aura_service_uniform_AuraScript::OnApply, EFFECT_0, SPELL_AURA_TRANSFORM, AURA_EFFECT_HANDLE_REAL); + AfterEffectRemove += AuraEffectRemoveFn(spell_gen_aura_service_uniform_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_TRANSFORM, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_gen_aura_service_uniform_AuraScript(); + } +}; + void AddSC_generic_spell_scripts() { new spell_gen_absorb0_hitlimit1(); @@ -3597,4 +3654,5 @@ void AddSC_generic_spell_scripts() new spell_gen_bonked(); new spell_gen_gift_of_naaru(); new spell_gen_replenishment(); + new spell_gen_aura_service_uniform(); } -- cgit v1.2.3 From f753c989f25e1f3bbb8c667ffd0028a0c0aa389d Mon Sep 17 00:00:00 2001 From: Spp Date: Mon, 4 Feb 2013 04:08:51 +0100 Subject: Core/Dungeon Finder: Simplify Spell Luck of the draw code Core/Dungeon Finder: Partial recode of "group list" using existing Lfg functions --- src/server/game/DungeonFinding/LFGMgr.cpp | 26 ++++++++++++++ src/server/game/DungeonFinding/LFGMgr.h | 3 ++ src/server/game/Maps/Map.cpp | 6 +--- src/server/scripts/Commands/cs_misc.cpp | 53 ++++++++++++++--------------- src/server/scripts/Spells/spell_generic.cpp | 46 ++++++++++++------------- 5 files changed, 78 insertions(+), 56 deletions(-) (limited to 'src/server/scripts') diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index 0f23925cc2b..4c6a8b92e0b 100644 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -2039,3 +2039,29 @@ void LFGMgr::SetupGroupMember(uint64 guid, uint64 gguid) SetGroup(guid, gguid); AddPlayerToGroup(gguid, guid); } + +bool LFGMgr::inRandomLfgDungeon(uint64 guid) +{ + if (GetState(guid) != LFG_STATE_NONE) + { + LfgDungeonSet const& dungeons = GetSelectedDungeons(guid); + if (!dungeons.empty()) + { + LFGDungeonData const* dungeon = GetLFGDungeon(*dungeons.begin()); + if (dungeon && (dungeon->type == LFG_TYPE_RANDOM || dungeon->seasonal)) + return true; + } + } + + return false; +} + +bool LFGMgr::inLfgDungeonMap(uint64 guid, uint32 map, Difficulty difficulty) +{ + if (uint32 dungeonId = GetDungeon(guid, true)) + if (LFGDungeonData const* dungeon = GetLFGDungeon(dungeonId)) + if (uint32(dungeon->map) == map && dungeon->difficulty == difficulty) + return true; + + return false; +} diff --git a/src/server/game/DungeonFinding/LFGMgr.h b/src/server/game/DungeonFinding/LFGMgr.h index 74c7ca9e3d3..5b26cf9854c 100644 --- a/src/server/game/DungeonFinding/LFGMgr.h +++ b/src/server/game/DungeonFinding/LFGMgr.h @@ -381,6 +381,9 @@ class LFGMgr void SetupGroupMember(uint64 guid, uint64 gguid); uint64 GetGroup(uint64 guid); + bool inRandomLfgDungeon(uint64 guid); + bool inLfgDungeonMap(uint64 guid, uint32 map, Difficulty difficulty); + private: uint8 GetTeam(uint64 guid); void RestoreState(uint64 guid, char const* debugMsg); diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 184450ef8d6..6358acfb97d 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -2486,11 +2486,7 @@ bool InstanceMap::AddPlayerToMap(Player* player) } if (group && group->isLFGGroup()) - if (uint32 dungeonId = sLFGMgr->GetDungeon(group->GetGUID(), true)) - if (LFGDungeonData const* dungeon = sLFGMgr->GetLFGDungeon(dungeonId)) - if (LFGDungeonData const* randomDungeon = sLFGMgr->GetLFGDungeon(*(sLFGMgr->GetSelectedDungeons(player->GetGUID()).begin()))) - if (uint32(dungeon->map) == GetId() && dungeon->difficulty == GetDifficulty() && randomDungeon->type == LFG_TYPE_RANDOM) - player->CastSpell(player, LFG_SPELL_LUCK_OF_THE_DRAW, true); + player->CastSpell(player, LFG_SPELL_LUCK_OF_THE_DRAW, true); } // for normal instances cancel the reset schedule when the diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index ce9d5088317..08140772db9 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -33,7 +33,7 @@ #include "ace/INET_Addr.h" #include "Player.h" #include "Pet.h" -#include "LFG.h" +#include "LFGMgr.h" #include "GroupMgr.h" class misc_commandscript : public CommandScript @@ -2834,41 +2834,40 @@ public: { handler->PSendSysMessage(LANG_GROUP_TYPE, (groupTarget->isRaidGroup() ? "raid" : "party")); Group::MemberSlotList const& members = groupTarget->GetMemberSlots(); - Group::MemberSlotList::const_iterator itr; - for (itr = members.begin(); itr != members.end(); ++itr) + for (Group::MemberSlotList::const_iterator itr = members.begin(); itr != members.end(); ++itr) { - std::ostringstream flags, roles; - if ((*itr).flags & MEMBER_FLAG_ASSISTANT) - flags << "Assistant "; - if ((*itr).flags & MEMBER_FLAG_MAINTANK) - flags << "MainTank "; - if ((*itr).flags & MEMBER_FLAG_MAINASSIST) - flags << "MainAssist "; - - if ((*itr).roles & PLAYER_ROLE_LEADER) - roles << "Leader "; - if ((*itr).roles & PLAYER_ROLE_TANK) - roles << "Tank "; - if ((*itr).roles & PLAYER_ROLE_HEALER) - roles << "Healer "; - if ((*itr).roles & PLAYER_ROLE_DAMAGE) - roles << "Damage "; + Group::MemberSlot const& slot = *itr; + + std::string flags; + if (slot.flags & MEMBER_FLAG_ASSISTANT) + flags = "Assistant"; + + if (slot.flags & MEMBER_FLAG_MAINTANK) + { + if (!flags.empty()) + flags.append(", "); + flags.append("MainTank"); + } + + if (slot.flags & MEMBER_FLAG_MAINASSIST) + { + if (!flags.empty()) + flags.append(", "); + flags.append("MainAssist"); + } + + if (flags.empty()) + flags = "None"; Player* p = ObjectAccessor::FindPlayer((*itr).guid); const char* onlineState = (p && p->IsInWorld()) ? "online" : "offline"; - std::string flagsStr = (flags.str().empty()) ? "None" : flags.str(); - std::string rolesStr = (roles.str().empty()) ? "None" : roles.str(); - - handler->PSendSysMessage(LANG_GROUP_PLAYER_NAME_GUID, (*itr).name.c_str(), onlineState, GUID_LOPART((*itr).guid), flagsStr.c_str(), rolesStr.c_str()); + handler->PSendSysMessage(LANG_GROUP_PLAYER_NAME_GUID, slot.name.c_str(), onlineState, + GUID_LOPART(slot.guid), flags.c_str(), LFGMgr::GetRolesString(slot.roles).c_str()); } - return true; } else - { handler->PSendSysMessage(LANG_GROUP_NOT_IN_GROUP, nameTarget.c_str()); - return true; - } return true; } diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index e7befff87a3..54ca3efd6d5 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -1715,10 +1715,29 @@ class spell_gen_luck_of_the_draw : public SpellScriptLoader class spell_gen_luck_of_the_draw_AuraScript : public AuraScript { PrepareAuraScript(spell_gen_luck_of_the_draw_AuraScript); + Map const* map; + Difficulty difficulty; bool Load() { - return GetUnitOwner()->GetTypeId() == TYPEID_PLAYER; + Player* owner = GetUnitOwner()->ToPlayer(); + if (!owner) + return false; + + Group* group = owner->GetGroup(); + if (!group || group->isLFGGroup()) + return false; + + if (!sLFGMgr->inRandomLfgDungeon(owner->GetGUID())) + return false; + + map = owner->GetMap(); + difficulty = owner->GetMap()->GetDifficulty(); + + if (!sLFGMgr->inLfgDungeonMap(owner->GetGUID(), map->GetId(), difficulty)) + return false; + + return true; } // cheap hax to make it have update calls @@ -1730,30 +1749,9 @@ class spell_gen_luck_of_the_draw : public SpellScriptLoader void Update(AuraEffect* /*effect*/) { - if (Player* owner = GetUnitOwner()->ToPlayer()) - { - const LfgDungeonSet dungeons = sLFGMgr->GetSelectedDungeons(owner->GetGUID()); - LfgDungeonSet::const_iterator itr = dungeons.begin(); - - if (itr == dungeons.end()) - { - Remove(AURA_REMOVE_BY_DEFAULT); - return; - } - - - LFGDungeonData const* randomDungeon = sLFGMgr->GetLFGDungeon(*itr); - if (Group* group = owner->GetGroup()) - if (Map const* map = owner->GetMap()) - if (group->isLFGGroup()) - if (uint32 dungeonId = sLFGMgr->GetDungeon(group->GetGUID(), true)) - if (LFGDungeonData const* dungeon = sLFGMgr->GetLFGDungeon(dungeonId)) - if (uint32(dungeon->map) == map->GetId() && dungeon->difficulty == map->GetDifficulty()) - if (randomDungeon && randomDungeon->type == LFG_TYPE_RANDOM) - return; // in correct dungeon - + Map const* currentMap = GetUnitOwner()->ToPlayer()->GetMap(); + if (currentMap != map || currentMap->GetDifficulty() != difficulty) Remove(AURA_REMOVE_BY_DEFAULT); - } } void Register() -- cgit v1.2.3 From 9bdfc877748501066a6fce91b9d5f774eab5ac77 Mon Sep 17 00:00:00 2001 From: Spp Date: Mon, 4 Feb 2013 04:43:18 +0100 Subject: Core/Dungeon Finder: Use lfg namespace to encapsulate all LFG classes, structs and enums --- src/server/game/DungeonFinding/LFG.cpp | 91 ++++++++++++++++++ src/server/game/DungeonFinding/LFG.h | 9 ++ src/server/game/DungeonFinding/LFGGroupData.cpp | 5 + src/server/game/DungeonFinding/LFGGroupData.h | 5 + src/server/game/DungeonFinding/LFGMgr.cpp | 88 +---------------- src/server/game/DungeonFinding/LFGMgr.h | 10 +- src/server/game/DungeonFinding/LFGPlayerData.cpp | 5 + src/server/game/DungeonFinding/LFGPlayerData.h | 5 + src/server/game/DungeonFinding/LFGQueue.cpp | 11 ++- src/server/game/DungeonFinding/LFGQueue.h | 5 + src/server/game/DungeonFinding/LFGScripts.cpp | 5 + src/server/game/DungeonFinding/LFGScripts.h | 5 + src/server/game/Entities/Player/Player.cpp | 29 ++---- src/server/game/Groups/Group.cpp | 2 +- src/server/game/Handlers/LFGHandler.cpp | 116 +++++++++++------------ src/server/game/Maps/Map.cpp | 2 +- src/server/game/Server/WorldSession.h | 23 +++-- src/server/scripts/Commands/cs_lfg.cpp | 10 +- src/server/scripts/Commands/cs_misc.cpp | 4 +- 19 files changed, 242 insertions(+), 188 deletions(-) create mode 100644 src/server/game/DungeonFinding/LFG.cpp (limited to 'src/server/scripts') diff --git a/src/server/game/DungeonFinding/LFG.cpp b/src/server/game/DungeonFinding/LFG.cpp new file mode 100644 index 00000000000..e146899841f --- /dev/null +++ b/src/server/game/DungeonFinding/LFG.cpp @@ -0,0 +1,91 @@ +#include "LFG.h" +#include "Language.h" +#include "ObjectMgr.h" + +namespace lfg +{ + +std::string ConcatenateDungeons(LfgDungeonSet const& dungeons) +{ + std::string dungeonstr = ""; + if (!dungeons.empty()) + { + std::ostringstream o; + LfgDungeonSet::const_iterator it = dungeons.begin(); + o << (*it); + for (++it; it != dungeons.end(); ++it) + o << ", " << uint32(*it); + dungeonstr = o.str(); + } + return dungeonstr; +} + +std::string GetRolesString(uint8 roles) +{ + std::string rolesstr = ""; + + if (roles & PLAYER_ROLE_TANK) + rolesstr.append(sObjectMgr->GetTrinityStringForDBCLocale(LANG_LFG_ROLE_TANK)); + + if (roles & PLAYER_ROLE_HEALER) + { + if (!rolesstr.empty()) + rolesstr.append(", "); + rolesstr.append(sObjectMgr->GetTrinityStringForDBCLocale(LANG_LFG_ROLE_HEALER)); + } + + if (roles & PLAYER_ROLE_DAMAGE) + { + if (!rolesstr.empty()) + rolesstr.append(", "); + rolesstr.append(sObjectMgr->GetTrinityStringForDBCLocale(LANG_LFG_ROLE_DAMAGE)); + } + + if (roles & PLAYER_ROLE_LEADER) + { + if (!rolesstr.empty()) + rolesstr.append(", "); + rolesstr.append(sObjectMgr->GetTrinityStringForDBCLocale(LANG_LFG_ROLE_LEADER)); + } + + if (rolesstr.empty()) + rolesstr.append(sObjectMgr->GetTrinityStringForDBCLocale(LANG_LFG_ROLE_NONE)); + + return rolesstr; +} + +std::string GetStateString(LfgState state) +{ + int32 entry = LANG_LFG_ERROR; + switch (state) + { + case LFG_STATE_NONE: + entry = LANG_LFG_STATE_NONE; + break; + case LFG_STATE_ROLECHECK: + entry = LANG_LFG_STATE_ROLECHECK; + break; + case LFG_STATE_QUEUED: + entry = LANG_LFG_STATE_QUEUED; + break; + case LFG_STATE_PROPOSAL: + entry = LANG_LFG_STATE_PROPOSAL; + break; + case LFG_STATE_DUNGEON: + entry = LANG_LFG_STATE_DUNGEON; + break; + case LFG_STATE_BOOT: + entry = LANG_LFG_STATE_BOOT; + break; + case LFG_STATE_FINISHED_DUNGEON: + entry = LANG_LFG_STATE_FINISHED_DUNGEON; + break; + case LFG_STATE_RAIDBROWSER: + entry = LANG_LFG_STATE_RAIDBROWSER; + break; + } + + return std::string(sObjectMgr->GetTrinityStringForDBCLocale(entry)); +} + +} // namespace lfg diff --git a/src/server/game/DungeonFinding/LFG.h b/src/server/game/DungeonFinding/LFG.h index ebbcfb1d71a..541e4d6bd43 100644 --- a/src/server/game/DungeonFinding/LFG.h +++ b/src/server/game/DungeonFinding/LFG.h @@ -20,6 +20,9 @@ #include "Common.h" +namespace lfg +{ + enum LFGEnum { LFG_TANKS_NEEDED = 1, @@ -99,4 +102,10 @@ typedef std::list LfgGuidList; typedef std::map LfgRolesMap; typedef std::map LfgGroupsMap; +std::string ConcatenateDungeons(LfgDungeonSet const& dungeons); +std::string GetRolesString(uint8 roles); +std::string GetStateString(LfgState state); + +} // namespace lfg + #endif diff --git a/src/server/game/DungeonFinding/LFGGroupData.cpp b/src/server/game/DungeonFinding/LFGGroupData.cpp index 427225bf323..f711514e26d 100644 --- a/src/server/game/DungeonFinding/LFGGroupData.cpp +++ b/src/server/game/DungeonFinding/LFGGroupData.cpp @@ -18,6 +18,9 @@ #include "LFG.h" #include "LFGGroupData.h" +namespace lfg +{ + LfgGroupData::LfgGroupData(): m_State(LFG_STATE_NONE), m_OldState(LFG_STATE_NONE), m_Leader(0), m_Dungeon(0), m_KicksLeft(LFG_GROUP_MAX_KICKS) { } @@ -122,3 +125,5 @@ uint8 LfgGroupData::GetKicksLeft() const { return m_KicksLeft; } + +} // namespace lfg diff --git a/src/server/game/DungeonFinding/LFGGroupData.h b/src/server/game/DungeonFinding/LFGGroupData.h index 2ad020d3bc1..47e562c37aa 100644 --- a/src/server/game/DungeonFinding/LFGGroupData.h +++ b/src/server/game/DungeonFinding/LFGGroupData.h @@ -20,6 +20,9 @@ #include "LFG.h" +namespace lfg +{ + enum LfgGroupEnum { LFG_GROUP_MAX_KICKS = 3, @@ -75,4 +78,6 @@ class LfgGroupData uint8 m_KicksLeft; ///< Number of kicks left }; +} // namespace lfg + #endif diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index 4c6a8b92e0b..05a15b9cb6a 100644 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -33,6 +33,9 @@ #include "GameEventMgr.h" #include "WorldSession.h" +namespace lfg +{ + LFGMgr::LFGMgr(): m_QueueTimer(0), m_lfgProposalId(1), m_options(sWorld->getIntConfig(CONFIG_LFG_OPTIONSMASK)) { @@ -95,89 +98,6 @@ void LFGMgr::_SaveToDB(uint64 guid, uint32 db_guid) CharacterDatabase.Execute(stmt); } -std::string LFGMgr::ConcatenateDungeons(LfgDungeonSet const& dungeons) -{ - std::string dungeonstr = ""; - if (!dungeons.empty()) - { - std::ostringstream o; - LfgDungeonSet::const_iterator it = dungeons.begin(); - o << (*it); - for (++it; it != dungeons.end(); ++it) - o << ", " << uint32(*it); - dungeonstr = o.str(); - } - return dungeonstr; -} - -std::string LFGMgr::GetRolesString(uint8 roles) -{ - std::string rolesstr = ""; - - if (roles & PLAYER_ROLE_TANK) - rolesstr.append(sObjectMgr->GetTrinityStringForDBCLocale(LANG_LFG_ROLE_TANK)); - - if (roles & PLAYER_ROLE_HEALER) - { - if (!rolesstr.empty()) - rolesstr.append(", "); - rolesstr.append(sObjectMgr->GetTrinityStringForDBCLocale(LANG_LFG_ROLE_HEALER)); - } - - if (roles & PLAYER_ROLE_DAMAGE) - { - if (!rolesstr.empty()) - rolesstr.append(", "); - rolesstr.append(sObjectMgr->GetTrinityStringForDBCLocale(LANG_LFG_ROLE_DAMAGE)); - } - - if (roles & PLAYER_ROLE_LEADER) - { - if (!rolesstr.empty()) - rolesstr.append(", "); - rolesstr.append(sObjectMgr->GetTrinityStringForDBCLocale(LANG_LFG_ROLE_LEADER)); - } - - if (rolesstr.empty()) - rolesstr.append(sObjectMgr->GetTrinityStringForDBCLocale(LANG_LFG_ROLE_NONE)); - - return rolesstr; -} - -std::string LFGMgr::GetStateString(LfgState state) -{ - int32 entry = LANG_LFG_ERROR; - switch (state) - { - case LFG_STATE_NONE: - entry = LANG_LFG_STATE_NONE; - break; - case LFG_STATE_ROLECHECK: - entry = LANG_LFG_STATE_ROLECHECK; - break; - case LFG_STATE_QUEUED: - entry = LANG_LFG_STATE_QUEUED; - break; - case LFG_STATE_PROPOSAL: - entry = LANG_LFG_STATE_PROPOSAL; - break; - case LFG_STATE_DUNGEON: - entry = LANG_LFG_STATE_DUNGEON; - break; - case LFG_STATE_BOOT: - entry = LANG_LFG_STATE_BOOT; - break; - case LFG_STATE_FINISHED_DUNGEON: - entry = LANG_LFG_STATE_FINISHED_DUNGEON; - break; - case LFG_STATE_RAIDBROWSER: - entry = LANG_LFG_STATE_RAIDBROWSER; - break; - } - - return std::string(sObjectMgr->GetTrinityStringForDBCLocale(entry)); -} - /// Load rewards for completing dungeons void LFGMgr::LoadRewards() { @@ -2065,3 +1985,5 @@ bool LFGMgr::inLfgDungeonMap(uint64 guid, uint32 map, Difficulty difficulty) return false; } + +} // namespace lfg diff --git a/src/server/game/DungeonFinding/LFGMgr.h b/src/server/game/DungeonFinding/LFGMgr.h index 5b26cf9854c..20116caaaf3 100644 --- a/src/server/game/DungeonFinding/LFGMgr.h +++ b/src/server/game/DungeonFinding/LFGMgr.h @@ -30,6 +30,9 @@ class Group; class Player; class Quest; +namespace lfg +{ + enum LfgOptions { LFG_OPTION_ENABLE_DUNGEON_FINDER = 0x01, @@ -371,9 +374,6 @@ class LFGMgr bool IsSeasonActive(uint32 dungeonId); std::string DumpQueueInfo(bool full = false); - static std::string ConcatenateDungeons(LfgDungeonSet const& dungeons); - static std::string GetRolesString(uint8 roles); - static std::string GetStateString(LfgState state); void LoadLFGDungeons(bool reload = false); LFGDungeonData const* GetLFGDungeon(uint32 id); @@ -429,5 +429,7 @@ class LFGMgr LfgGuidList teleportStore; ///< Players being teleported }; -#define sLFGMgr ACE_Singleton::instance() +} // namespace lfg + +#define sLFGMgr ACE_Singleton::instance() #endif diff --git a/src/server/game/DungeonFinding/LFGPlayerData.cpp b/src/server/game/DungeonFinding/LFGPlayerData.cpp index 410076f7e75..e8ef430bc1f 100644 --- a/src/server/game/DungeonFinding/LFGPlayerData.cpp +++ b/src/server/game/DungeonFinding/LFGPlayerData.cpp @@ -17,6 +17,9 @@ #include "LFGPlayerData.h" +namespace lfg +{ + LfgPlayerData::LfgPlayerData(): m_State(LFG_STATE_NONE), m_OldState(LFG_STATE_NONE), m_Team(0), m_Group(0), m_Roles(0), m_Comment("") {} @@ -122,3 +125,5 @@ LfgDungeonSet const& LfgPlayerData::GetSelectedDungeons() const { return m_SelectedDungeons; } + +} // namespace lfg diff --git a/src/server/game/DungeonFinding/LFGPlayerData.h b/src/server/game/DungeonFinding/LFGPlayerData.h index 055924fd364..a425ce77bad 100644 --- a/src/server/game/DungeonFinding/LFGPlayerData.h +++ b/src/server/game/DungeonFinding/LFGPlayerData.h @@ -20,6 +20,9 @@ #include "LFG.h" +namespace lfg +{ + /** Stores all lfg data needed about the player. */ @@ -68,4 +71,6 @@ class LfgPlayerData LfgDungeonSet m_SelectedDungeons; ///< Selected Dungeons when joined LFG }; +} // namespace lfg + #endif diff --git a/src/server/game/DungeonFinding/LFGQueue.cpp b/src/server/game/DungeonFinding/LFGQueue.cpp index f1d2dbb313d..6a98fccecdc 100644 --- a/src/server/game/DungeonFinding/LFGQueue.cpp +++ b/src/server/game/DungeonFinding/LFGQueue.cpp @@ -27,6 +27,9 @@ #include "World.h" #include "GroupMgr.h" +namespace lfg +{ + /** Given a list of guids returns the concatenation using | as delimiter @@ -431,7 +434,7 @@ LfgCompatibility LFGQueue::CheckCompatibility(LfgGuidList check) { std::ostringstream o; for (LfgRolesMap::const_iterator it = debugRoles.begin(); it != debugRoles.end(); ++it) - o << ", " << it->first << ": " << sLFGMgr->GetRolesString(it->second); + o << ", " << it->first << ": " << GetRolesString(it->second); sLog->outDebug(LOG_FILTER_LFG, "LFGQueue::CheckCompatibility: (%s) Roles not compatible%s", strGuids.c_str(), o.str().c_str()); SetCompatibles(strGuids, LFG_INCOMPATIBLES_NO_ROLES); @@ -441,12 +444,12 @@ LfgCompatibility LFGQueue::CheckCompatibility(LfgGuidList check) LfgGuidList::iterator itguid = check.begin(); proposalDungeons = QueueDataStore[*itguid].dungeons; std::ostringstream o; - o << ", " << *itguid << ": (" << sLFGMgr->ConcatenateDungeons(proposalDungeons) << ")"; + o << ", " << *itguid << ": (" << ConcatenateDungeons(proposalDungeons) << ")"; for (++itguid; itguid != check.end(); ++itguid) { LfgDungeonSet temporal; LfgDungeonSet &dungeons = QueueDataStore[*itguid].dungeons; - o << ", " << *itguid << ": (" << sLFGMgr->ConcatenateDungeons(dungeons) << ")"; + o << ", " << *itguid << ": (" << ConcatenateDungeons(dungeons) << ")"; std::set_intersection(proposalDungeons.begin(), proposalDungeons.end(), dungeons.begin(), dungeons.end(), std::inserter(temporal, temporal.begin())); proposalDungeons = temporal; } @@ -671,3 +674,5 @@ void LFGQueue::UpdateBestCompatibleInQueue(LfgQueueDataContainer::iterator itrQu --queueData.dps; } } + +} // namespace lfg diff --git a/src/server/game/DungeonFinding/LFGQueue.h b/src/server/game/DungeonFinding/LFGQueue.h index acb78d2c0f2..db7e7bbf318 100644 --- a/src/server/game/DungeonFinding/LFGQueue.h +++ b/src/server/game/DungeonFinding/LFGQueue.h @@ -20,6 +20,9 @@ #include "LFG.h" +namespace lfg +{ + enum LfgCompatibility { LFG_COMPATIBILITY_PENDING, @@ -140,4 +143,6 @@ class LFGQueue LfgGuidList newToQueueStore; ///< New groups to add to queue }; +} // namespace lfg + #endif diff --git a/src/server/game/DungeonFinding/LFGScripts.cpp b/src/server/game/DungeonFinding/LFGScripts.cpp index 568b61eef2f..ac95d289397 100644 --- a/src/server/game/DungeonFinding/LFGScripts.cpp +++ b/src/server/game/DungeonFinding/LFGScripts.cpp @@ -29,6 +29,9 @@ #include "ObjectAccessor.h" #include "WorldSession.h" +namespace lfg +{ + LFGPlayerScript::LFGPlayerScript() : PlayerScript("LFGPlayerScript") { } @@ -208,3 +211,5 @@ void LFGGroupScript::OnInviteMember(Group* group, uint64 guid) if (leader && !gguid) sLFGMgr->LeaveLfg(leader); } + +} // namespace lfg diff --git a/src/server/game/DungeonFinding/LFGScripts.h b/src/server/game/DungeonFinding/LFGScripts.h index 227543e1899..e9c6b1499d1 100644 --- a/src/server/game/DungeonFinding/LFGScripts.h +++ b/src/server/game/DungeonFinding/LFGScripts.h @@ -26,6 +26,9 @@ class Player; class Group; +namespace lfg +{ + class LFGPlayerScript : public PlayerScript { public: @@ -50,3 +53,5 @@ class LFGGroupScript : public GroupScript void OnChangeLeader(Group* group, uint64 newLeaderGuid, uint64 oldLeaderGuid); void OnInviteMember(Group* group, uint64 guid); }; + +} // namespace lfg diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 59f9e1e3efb..9c398bd88fb 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -11913,7 +11913,7 @@ InventoryResult Player::CanUseItem(ItemTemplate const* proto) const InventoryResult Player::CanRollForItemInLFG(ItemTemplate const* proto, WorldObject const* lootedObject) const { - LfgDungeonSet const& dungeons = sLFGMgr->GetSelectedDungeons(GetGUID()); + lfg::LfgDungeonSet const& dungeons = sLFGMgr->GetSelectedDungeons(GetGUID()); if (dungeons.empty()) return EQUIP_ERR_OK; // not using LFG @@ -11923,10 +11923,7 @@ InventoryResult Player::CanRollForItemInLFG(ItemTemplate const* proto, WorldObje // check if looted object is inside the lfg dungeon bool lootedObjectInDungeon = false; Map const* map = lootedObject->GetMap(); - if (uint32 dungeonId = sLFGMgr->GetDungeon(GetGroup()->GetGUID(), true)) - if (LFGDungeonData const* dungeon = sLFGMgr->GetLFGDungeon(dungeonId)) - if (uint32(dungeon->map) == map->GetId() && dungeon->difficulty == map->GetDifficulty()) - lootedObjectInDungeon = true; + lootedObjectInDungeon = sLFGMgr->inLfgDungeonMap(GetGroup()->GetGUID(), map->GetId(), map->GetDifficulty()); if (!lootedObjectInDungeon) return EQUIP_ERR_OK; @@ -23426,14 +23423,14 @@ PartyResult Player::CanUninviteFromGroup() const if (!sLFGMgr->GetKicksLeft(gguid)) return ERR_PARTY_LFG_BOOT_LIMIT; - LfgState state = sLFGMgr->GetState(gguid); - if (state == LFG_STATE_BOOT) + lfg::LfgState state = sLFGMgr->GetState(gguid); + if (state == lfg::LFG_STATE_BOOT) return ERR_PARTY_LFG_BOOT_IN_PROGRESS; - if (grp->GetMembersCount() <= LFG_GROUP_KICK_VOTES_NEEDED) + if (grp->GetMembersCount() <= lfg::LFG_GROUP_KICK_VOTES_NEEDED) return ERR_PARTY_LFG_BOOT_TOO_FEW_PLAYERS; - if (state == LFG_STATE_FINISHED_DUNGEON) + if (state == lfg::LFG_STATE_FINISHED_DUNGEON) return ERR_PARTY_LFG_BOOT_DUNGEON_COMPLETE; if (grp->isRollLootActive()) @@ -23463,22 +23460,12 @@ PartyResult Player::CanUninviteFromGroup() const bool Player::isUsingLfg() { - return sLFGMgr->GetState(GetGUID()) != LFG_STATE_NONE; + return sLFGMgr->GetState(GetGUID()) != lfg::LFG_STATE_NONE; } bool Player::inRandomLfgDungeon() { - if (isUsingLfg()) - { - const LfgDungeonSet& dungeons = sLFGMgr->GetSelectedDungeons(GetGUID()); - if (!dungeons.empty()) - { - LFGDungeonData const* dungeon = sLFGMgr->GetLFGDungeon(*dungeons.begin()); - if (dungeon && (dungeon->type == LFG_TYPE_RANDOM || dungeon->seasonal)) - return true; - } - } - return false; + return sLFGMgr->inRandomLfgDungeon(GetGUID()); } void Player::SetBattlegroundOrBattlefieldRaid(Group* group, int8 subgroup) diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index 711e07ef941..eb2d33c63a0 100644 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -1496,7 +1496,7 @@ void Group::SendUpdateToPlayer(uint64 playerGUID, MemberSlot* slot) data << uint8(slot->roles); if (isLFGGroup()) { - data << uint8(sLFGMgr->GetState(m_guid) == LFG_STATE_FINISHED_DUNGEON ? 2 : 0); // FIXME - Dungeon save status? 2 = done + data << uint8(sLFGMgr->GetState(m_guid) == lfg::LFG_STATE_FINISHED_DUNGEON ? 2 : 0); // FIXME - Dungeon save status? 2 = done data << uint32(sLFGMgr->GetDungeon(m_guid)); } diff --git a/src/server/game/Handlers/LFGHandler.cpp b/src/server/game/Handlers/LFGHandler.cpp index 0654ae326f9..60fc63694ee 100644 --- a/src/server/game/Handlers/LFGHandler.cpp +++ b/src/server/game/Handlers/LFGHandler.cpp @@ -23,20 +23,20 @@ #include "WorldPacket.h" #include "WorldSession.h" -void BuildPlayerLockDungeonBlock(WorldPacket& data, LfgLockMap const& lock) +void BuildPlayerLockDungeonBlock(WorldPacket& data, lfg::LfgLockMap const& lock) { data << uint32(lock.size()); // Size of lock dungeons - for (LfgLockMap::const_iterator it = lock.begin(); it != lock.end(); ++it) + for (lfg::LfgLockMap::const_iterator it = lock.begin(); it != lock.end(); ++it) { data << uint32(it->first); // Dungeon entry (id + type) data << uint32(it->second); // Lock status } } -void BuildPartyLockDungeonBlock(WorldPacket& data, const LfgLockPartyMap& lockMap) +void BuildPartyLockDungeonBlock(WorldPacket& data, lfg::LfgLockPartyMap const& lockMap) { data << uint8(lockMap.size()); - for (LfgLockPartyMap::const_iterator it = lockMap.begin(); it != lockMap.end(); ++it) + for (lfg::LfgLockPartyMap::const_iterator it = lockMap.begin(); it != lockMap.end(); ++it) { data << uint64(it->first); // Player guid BuildPlayerLockDungeonBlock(data, it->second); @@ -45,7 +45,7 @@ void BuildPartyLockDungeonBlock(WorldPacket& data, const LfgLockPartyMap& lockMa void WorldSession::HandleLfgJoinOpcode(WorldPacket& recvData) { - if (!sLFGMgr->isOptionEnabled(LFG_OPTION_ENABLE_DUNGEON_FINDER | LFG_OPTION_ENABLE_RAID_BROWSER) || + if (!sLFGMgr->isOptionEnabled(lfg::LFG_OPTION_ENABLE_DUNGEON_FINDER | lfg::LFG_OPTION_ENABLE_RAID_BROWSER) || (GetPlayer()->GetGroup() && GetPlayer()->GetGroup()->GetLeaderGUID() != GetPlayer()->GetGUID() && (GetPlayer()->GetGroup()->GetMembersCount() == MAXGROUPSIZE || !GetPlayer()->GetGroup()->isLFGGroup()))) { @@ -66,7 +66,7 @@ void WorldSession::HandleLfgJoinOpcode(WorldPacket& recvData) return; } - LfgDungeonSet newDungeons; + lfg::LfgDungeonSet newDungeons; for (int8 i = 0; i < numDungeons; ++i) { uint32 dungeon; @@ -167,21 +167,21 @@ void WorldSession::HandleLfgPlayerLockInfoRequestOpcode(WorldPacket& /*recvData* GetPlayerInfo().c_str()); // Get Random dungeons that can be done at a certain level and expansion - LfgDungeonSet randomDungeons; + lfg::LfgDungeonSet randomDungeons; uint8 level = GetPlayer()->getLevel(); uint8 expansion = GetPlayer()->GetSession()->Expansion(); - LFGDungeonContainer& LfgDungeons = sLFGMgr->GetLFGDungeonMap(); - for (LFGDungeonContainer::const_iterator itr = LfgDungeons.begin(); itr != LfgDungeons.end(); ++itr) + lfg::LFGDungeonContainer& LfgDungeons = sLFGMgr->GetLFGDungeonMap(); + for (lfg::LFGDungeonContainer::const_iterator itr = LfgDungeons.begin(); itr != LfgDungeons.end(); ++itr) { - LFGDungeonData const& dungeon = itr->second; - if ((dungeon.type == LFG_TYPE_RANDOM || (dungeon.seasonal && sLFGMgr->IsSeasonActive(dungeon.id))) + lfg::LFGDungeonData const& dungeon = itr->second; + if ((dungeon.type == lfg::LFG_TYPE_RANDOM || (dungeon.seasonal && sLFGMgr->IsSeasonActive(dungeon.id))) && dungeon.expansion <= expansion && dungeon.minlevel <= level && level <= dungeon.maxlevel) randomDungeons.insert(dungeon.Entry()); } // Get player locked Dungeons - LfgLockMap const& lock = sLFGMgr->GetLockedDungeons(guid); + lfg::LfgLockMap const& lock = sLFGMgr->GetLockedDungeons(guid); uint32 rsize = uint32(randomDungeons.size()); uint32 lsize = uint32(lock.size()); @@ -189,10 +189,10 @@ void WorldSession::HandleLfgPlayerLockInfoRequestOpcode(WorldPacket& /*recvData* WorldPacket data(SMSG_LFG_PLAYER_INFO, 1 + rsize * (4 + 1 + 4 + 4 + 4 + 4 + 1 + 4 + 4 + 4) + 4 + lsize * (1 + 4 + 4 + 4 + 4 + 1 + 4 + 4 + 4)); data << uint8(randomDungeons.size()); // Random Dungeon count - for (LfgDungeonSet::const_iterator it = randomDungeons.begin(); it != randomDungeons.end(); ++it) + for (lfg::LfgDungeonSet::const_iterator it = randomDungeons.begin(); it != randomDungeons.end(); ++it) { data << uint32(*it); // Dungeon Entry (id + type) - LfgReward const* reward = sLFGMgr->GetRandomDungeonReward(*it, level); + lfg::LfgReward const* reward = sLFGMgr->GetRandomDungeonReward(*it, level); Quest const* quest = NULL; bool done = false; if (reward) @@ -250,7 +250,7 @@ void WorldSession::HandleLfgPartyLockInfoRequestOpcode(WorldPacket& /*recvData* return; // Get the locked dungeons of the other party members - LfgLockPartyMap lockMap; + lfg::LfgLockPartyMap lockMap; for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* plrg = itr->getSource(); @@ -265,7 +265,7 @@ void WorldSession::HandleLfgPartyLockInfoRequestOpcode(WorldPacket& /*recvData* } uint32 size = 0; - for (LfgLockPartyMap::const_iterator it = lockMap.begin(); it != lockMap.end(); ++it) + for (lfg::LfgLockPartyMap::const_iterator it = lockMap.begin(); it != lockMap.end(); ++it) size += 8 + 4 + uint32(it->second.size()) * (4 + 4); sLog->outDebug(LOG_FILTER_LFG, "SMSG_LFG_PARTY_INFO %s", GetPlayerInfo().c_str()); @@ -297,7 +297,7 @@ void WorldSession::HandleLfgGetStatus(WorldPacket& /*recvData*/) sLog->outDebug(LOG_FILTER_LFG, "CMSG_LFG_GET_STATUS %s", GetPlayerInfo().c_str()); uint64 guid = GetPlayer()->GetGUID(); - LfgUpdateData updateData = sLFGMgr->GetLfgStatus(guid); + lfg::LfgUpdateData updateData = sLFGMgr->GetLfgStatus(guid); if (GetPlayer()->GetGroup()) { @@ -313,19 +313,19 @@ void WorldSession::HandleLfgGetStatus(WorldPacket& /*recvData*/) } } -void WorldSession::SendLfgUpdatePlayer(LfgUpdateData const& updateData) +void WorldSession::SendLfgUpdatePlayer(lfg::LfgUpdateData const& updateData) { bool queued = false; uint8 size = uint8(updateData.dungeons.size()); switch (updateData.updateType) { - case LFG_UPDATETYPE_JOIN_QUEUE: - case LFG_UPDATETYPE_ADDED_TO_QUEUE: + case lfg::LFG_UPDATETYPE_JOIN_QUEUE: + case lfg::LFG_UPDATETYPE_ADDED_TO_QUEUE: queued = true; break; - case LFG_UPDATETYPE_UPDATE_STATUS: - queued = updateData.state == LFG_STATE_QUEUED; + case lfg::LFG_UPDATETYPE_UPDATE_STATUS: + queued = updateData.state == lfg::LFG_STATE_QUEUED; break; default: break; @@ -343,14 +343,14 @@ void WorldSession::SendLfgUpdatePlayer(LfgUpdateData const& updateData) data << uint8(0); // unk - Always 0 data << uint8(size); - for (LfgDungeonSet::const_iterator it = updateData.dungeons.begin(); it != updateData.dungeons.end(); ++it) + for (lfg::LfgDungeonSet::const_iterator it = updateData.dungeons.begin(); it != updateData.dungeons.end(); ++it) data << uint32(*it); data << updateData.comment; } SendPacket(&data); } -void WorldSession::SendLfgUpdateParty(const LfgUpdateData& updateData) +void WorldSession::SendLfgUpdateParty(const lfg::LfgUpdateData& updateData) { bool join = false; bool queued = false; @@ -358,15 +358,15 @@ void WorldSession::SendLfgUpdateParty(const LfgUpdateData& updateData) switch (updateData.updateType) { - case LFG_UPDATETYPE_ADDED_TO_QUEUE: // Rolecheck Success + case lfg::LFG_UPDATETYPE_ADDED_TO_QUEUE: // Rolecheck Success queued = true; // no break on purpose - case LFG_UPDATETYPE_PROPOSAL_BEGIN: + case lfg::LFG_UPDATETYPE_PROPOSAL_BEGIN: join = true; break; - case LFG_UPDATETYPE_UPDATE_STATUS: - join = updateData.state != LFG_STATE_ROLECHECK && updateData.state != LFG_STATE_NONE; - queued = updateData.state == LFG_STATE_QUEUED; + case lfg::LFG_UPDATETYPE_UPDATE_STATUS: + join = updateData.state != lfg::LFG_STATE_ROLECHECK && updateData.state != lfg::LFG_STATE_NONE; + queued = updateData.state == lfg::LFG_STATE_QUEUED; break; default: break; @@ -387,7 +387,7 @@ void WorldSession::SendLfgUpdateParty(const LfgUpdateData& updateData) data << uint8(0); // unk - Always 0 data << uint8(size); - for (LfgDungeonSet::const_iterator it = updateData.dungeons.begin(); it != updateData.dungeons.end(); ++it) + for (lfg::LfgDungeonSet::const_iterator it = updateData.dungeons.begin(); it != updateData.dungeons.end(); ++it) data << uint32(*it); data << updateData.comment; } @@ -406,9 +406,9 @@ void WorldSession::SendLfgRoleChosen(uint64 guid, uint8 roles) SendPacket(&data); } -void WorldSession::SendLfgRoleCheckUpdate(const LfgRoleCheck& roleCheck) +void WorldSession::SendLfgRoleCheckUpdate(lfg::LfgRoleCheck const& roleCheck) { - LfgDungeonSet dungeons; + lfg::LfgDungeonSet dungeons; if (roleCheck.rDungeonId) dungeons.insert(roleCheck.rDungeonId); else @@ -418,13 +418,13 @@ void WorldSession::SendLfgRoleCheckUpdate(const LfgRoleCheck& roleCheck) WorldPacket data(SMSG_LFG_ROLE_CHECK_UPDATE, 4 + 1 + 1 + dungeons.size() * 4 + 1 + roleCheck.roles.size() * (8 + 1 + 4 + 1)); data << uint32(roleCheck.state); // Check result - data << uint8(roleCheck.state == LFG_ROLECHECK_INITIALITING); + data << uint8(roleCheck.state == lfg::LFG_ROLECHECK_INITIALITING); data << uint8(dungeons.size()); // Number of dungeons if (!dungeons.empty()) { - for (LfgDungeonSet::iterator it = dungeons.begin(); it != dungeons.end(); ++it) + for (lfg::LfgDungeonSet::iterator it = dungeons.begin(); it != dungeons.end(); ++it) { - LFGDungeonData const* dungeon = sLFGMgr->GetLFGDungeon(*it); + lfg::LFGDungeonData const* dungeon = sLFGMgr->GetLFGDungeon(*it); data << uint32(dungeon ? dungeon->Entry() : 0); // Dungeon } } @@ -441,7 +441,7 @@ void WorldSession::SendLfgRoleCheckUpdate(const LfgRoleCheck& roleCheck) Player* player = ObjectAccessor::FindPlayer(guid); data << uint8(player ? player->getLevel() : 0); // Level - for (LfgRolesMap::const_iterator it = roleCheck.roles.begin(); it != roleCheck.roles.end(); ++it) + for (lfg::LfgRolesMap::const_iterator it = roleCheck.roles.begin(); it != roleCheck.roles.end(); ++it) { if (it->first == roleCheck.leader) continue; @@ -458,10 +458,10 @@ void WorldSession::SendLfgRoleCheckUpdate(const LfgRoleCheck& roleCheck) SendPacket(&data); } -void WorldSession::SendLfgJoinResult(LfgJoinResultData const& joinData) +void WorldSession::SendLfgJoinResult(lfg::LfgJoinResultData const& joinData) { uint32 size = 0; - for (LfgLockPartyMap::const_iterator it = joinData.lockmap.begin(); it != joinData.lockmap.end(); ++it) + for (lfg::LfgLockPartyMap::const_iterator it = joinData.lockmap.begin(); it != joinData.lockmap.end(); ++it) size += 8 + 4 + uint32(it->second.size()) * (4 + 4); sLog->outDebug(LOG_FILTER_LFG, "SMSG_LFG_JOIN_RESULT %s checkResult: %u checkValue: %u", @@ -475,7 +475,7 @@ void WorldSession::SendLfgJoinResult(LfgJoinResultData const& joinData) SendPacket(&data); } -void WorldSession::SendLfgQueueStatus(LfgQueueStatusData const& queueData) +void WorldSession::SendLfgQueueStatus(lfg::LfgQueueStatusData const& queueData) { sLog->outDebug(LOG_FILTER_LFG, "SMSG_LFG_QUEUE_STATUS %s dungeon: %u, waitTime: %d, " "avgWaitTime: %d, waitTimeTanks: %d, waitTimeHealer: %d, waitTimeDps: %d, " @@ -498,7 +498,7 @@ void WorldSession::SendLfgQueueStatus(LfgQueueStatusData const& queueData) SendPacket(&data); } -void WorldSession::SendLfgPlayerReward(LfgPlayerRewardData const& rewardData) +void WorldSession::SendLfgPlayerReward(lfg::LfgPlayerRewardData const& rewardData) { if (!rewardData.rdungeonEntry || !rewardData.sdungeonEntry || !rewardData.quest) return; @@ -532,42 +532,42 @@ void WorldSession::SendLfgPlayerReward(LfgPlayerRewardData const& rewardData) SendPacket(&data); } -void WorldSession::SendLfgBootProposalUpdate(LfgPlayerBoot const& boot) +void WorldSession::SendLfgBootProposalUpdate(lfg::LfgPlayerBoot const& boot) { uint64 guid = GetPlayer()->GetGUID(); - LfgAnswer playerVote = boot.votes.find(guid)->second; + lfg::LfgAnswer playerVote = boot.votes.find(guid)->second; uint8 votesNum = 0; uint8 agreeNum = 0; uint32 secsleft = uint8((boot.cancelTime - time(NULL)) / 1000); - for (LfgAnswerContainer::const_iterator it = boot.votes.begin(); it != boot.votes.end(); ++it) + for (lfg::LfgAnswerContainer::const_iterator it = boot.votes.begin(); it != boot.votes.end(); ++it) { - if (it->second != LFG_ANSWER_PENDING) + if (it->second != lfg::LFG_ANSWER_PENDING) { ++votesNum; - if (it->second == LFG_ANSWER_AGREE) + if (it->second == lfg::LFG_ANSWER_AGREE) ++agreeNum; } } sLog->outDebug(LOG_FILTER_LFG, "SMSG_LFG_BOOT_PROPOSAL_UPDATE %s inProgress: %u - " "didVote: %u - agree: %u - victim: %u votes: %u - agrees: %u - left: %u - " "needed: %u - reason %s", - GetPlayerInfo().c_str(), uint8(boot.inProgress), uint8(playerVote != LFG_ANSWER_PENDING), - uint8(playerVote == LFG_ANSWER_AGREE), GUID_LOPART(boot.victim), votesNum, agreeNum, - secsleft, LFG_GROUP_KICK_VOTES_NEEDED, boot.reason.c_str()); + GetPlayerInfo().c_str(), uint8(boot.inProgress), uint8(playerVote != lfg::LFG_ANSWER_PENDING), + uint8(playerVote == lfg::LFG_ANSWER_AGREE), GUID_LOPART(boot.victim), votesNum, agreeNum, + secsleft, lfg::LFG_GROUP_KICK_VOTES_NEEDED, boot.reason.c_str()); WorldPacket data(SMSG_LFG_BOOT_PROPOSAL_UPDATE, 1 + 1 + 1 + 8 + 4 + 4 + 4 + 4 + boot.reason.length()); data << uint8(boot.inProgress); // Vote in progress - data << uint8(playerVote != LFG_ANSWER_PENDING); // Did Vote - data << uint8(playerVote == LFG_ANSWER_AGREE); // Agree + data << uint8(playerVote != lfg::LFG_ANSWER_PENDING); // Did Vote + data << uint8(playerVote == lfg::LFG_ANSWER_AGREE); // Agree data << uint64(boot.victim); // Victim GUID data << uint32(votesNum); // Total Votes data << uint32(agreeNum); // Agree Count data << uint32(secsleft); // Time Left - data << uint32(LFG_GROUP_KICK_VOTES_NEEDED); // Needed Votes + data << uint32(lfg::LFG_GROUP_KICK_VOTES_NEEDED); // Needed Votes data << boot.reason.c_str(); // Kick reason SendPacket(&data); } -void WorldSession::SendLfgUpdateProposal(LfgProposal const& proposal) +void WorldSession::SendLfgUpdateProposal(lfg::LfgProposal const& proposal) { uint64 guid = GetPlayer()->GetGUID(); uint64 gguid = proposal.players.find(guid)->second.group; @@ -580,12 +580,12 @@ void WorldSession::SendLfgUpdateProposal(LfgProposal const& proposal) // show random dungeon if player selected random dungeon and it's not lfg group if (!silent) { - LfgDungeonSet const& playerDungeons = sLFGMgr->GetSelectedDungeons(guid); + lfg::LfgDungeonSet const& playerDungeons = sLFGMgr->GetSelectedDungeons(guid); if (playerDungeons.find(proposal.dungeonId) == playerDungeons.end()) dungeonEntry = (*playerDungeons.begin()); } - if (LFGDungeonData const* dungeon = sLFGMgr->GetLFGDungeon(dungeonEntry)) + if (lfg::LFGDungeonData const* dungeon = sLFGMgr->GetLFGDungeon(dungeonEntry)) dungeonEntry = dungeon->Entry(); WorldPacket data(SMSG_LFG_PROPOSAL_UPDATE, 4 + 1 + 4 + 4 + 1 + 1 + proposal.players.size() * (4 + 1 + 1 + 1 + 1 +1)); @@ -596,9 +596,9 @@ void WorldSession::SendLfgUpdateProposal(LfgProposal const& proposal) data << uint8(silent); // Show proposal window data << uint8(proposal.players.size()); // Group size - for (LfgProposalPlayerContainer::const_iterator it = proposal.players.begin(); it != proposal.players.end(); ++it) + for (lfg::LfgProposalPlayerContainer::const_iterator it = proposal.players.begin(); it != proposal.players.end(); ++it) { - LfgProposalPlayer const& player = it->second; + lfg::LfgProposalPlayer const& player = it->second; data << uint32(player.role); // Role data << uint8(it->first == guid); // Self player if (!player.group) // Player not it a group @@ -611,8 +611,8 @@ void WorldSession::SendLfgUpdateProposal(LfgProposal const& proposal) data << uint8(player.group == proposal.group); // In dungeon (silent) data << uint8(player.group == gguid); // Same Group than player } - data << uint8(player.accept != LFG_ANSWER_PENDING);// Answered - data << uint8(player.accept == LFG_ANSWER_AGREE); // Accepted + data << uint8(player.accept != lfg::LFG_ANSWER_PENDING);// Answered + data << uint8(player.accept == lfg::LFG_ANSWER_AGREE); // Accepted } SendPacket(&data); } diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 6358acfb97d..288592d1029 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -2486,7 +2486,7 @@ bool InstanceMap::AddPlayerToMap(Player* player) } if (group && group->isLFGGroup()) - player->CastSpell(player, LFG_SPELL_LUCK_OF_THE_DRAW, true); + player->CastSpell(player, lfg::LFG_SPELL_LUCK_OF_THE_DRAW, true); } // for normal instances cancel the reset schedule when the diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index abe048279db..11bb7a36f5a 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -48,15 +48,18 @@ struct AreaTableEntry; struct AuctionEntry; struct DeclinedName; struct ItemTemplate; +struct MovementInfo; + +namespace lfg +{ struct LfgJoinResultData; -struct LfgLockStatus; struct LfgPlayerBoot; struct LfgProposal; struct LfgQueueStatusData; struct LfgPlayerRewardData; struct LfgRoleCheck; struct LfgUpdateData; -struct MovementInfo; +} enum AccountDataType { @@ -782,16 +785,16 @@ class WorldSession void HandleLfrLeaveOpcode(WorldPacket& recvData); void HandleLfgGetStatus(WorldPacket& recvData); - void SendLfgUpdatePlayer(LfgUpdateData const& updateData); - void SendLfgUpdateParty(LfgUpdateData const& updateData); + void SendLfgUpdatePlayer(lfg::LfgUpdateData const& updateData); + void SendLfgUpdateParty(lfg::LfgUpdateData const& updateData); void SendLfgRoleChosen(uint64 guid, uint8 roles); - void SendLfgRoleCheckUpdate(LfgRoleCheck const& pRoleCheck); + void SendLfgRoleCheckUpdate(lfg::LfgRoleCheck const& pRoleCheck); void SendLfgLfrList(bool update); - void SendLfgJoinResult(LfgJoinResultData const& joinData); - void SendLfgQueueStatus(LfgQueueStatusData const& queueData); - void SendLfgPlayerReward(LfgPlayerRewardData const& lfgPlayerRewardData); - void SendLfgBootProposalUpdate(LfgPlayerBoot const& boot); - void SendLfgUpdateProposal(LfgProposal const& proposal); + void SendLfgJoinResult(lfg::LfgJoinResultData const& joinData); + void SendLfgQueueStatus(lfg::LfgQueueStatusData const& queueData); + void SendLfgPlayerReward(lfg::LfgPlayerRewardData const& lfgPlayerRewardData); + void SendLfgBootProposalUpdate(lfg::LfgPlayerBoot const& boot); + void SendLfgUpdateProposal(lfg::LfgProposal const& proposal); void SendLfgDisabled(); void SendLfgOfferContinue(uint32 dungeonEntry); void SendLfgTeleportError(uint8 err); diff --git a/src/server/scripts/Commands/cs_lfg.cpp b/src/server/scripts/Commands/cs_lfg.cpp index 7f39a8fc024..aa9d9308bcd 100644 --- a/src/server/scripts/Commands/cs_lfg.cpp +++ b/src/server/scripts/Commands/cs_lfg.cpp @@ -28,12 +28,12 @@ void GetPlayerInfo(ChatHandler* handler, Player* player) return; uint64 guid = player->GetGUID(); - LfgDungeonSet dungeons = sLFGMgr->GetSelectedDungeons(guid); + lfg::LfgDungeonSet dungeons = sLFGMgr->GetSelectedDungeons(guid); - std::string const& state = sLFGMgr->GetStateString(sLFGMgr->GetState(guid)); + std::string const& state = lfg::GetStateString(sLFGMgr->GetState(guid)); handler->PSendSysMessage(LANG_LFG_PLAYER_INFO, player->GetName().c_str(), - state.c_str(), uint8(dungeons.size()), sLFGMgr->ConcatenateDungeons(dungeons).c_str(), - sLFGMgr->GetRolesString(sLFGMgr->GetRoles(guid)).c_str(), sLFGMgr->GetComment(guid).c_str()); + state.c_str(), uint8(dungeons.size()), lfg::ConcatenateDungeons(dungeons).c_str(), + lfg::GetRolesString(sLFGMgr->GetRoles(guid)).c_str(), sLFGMgr->GetComment(guid).c_str()); } class lfg_commandscript : public CommandScript @@ -87,7 +87,7 @@ public: } uint64 guid = grp->GetGUID(); - std::string const& state = sLFGMgr->GetStateString(sLFGMgr->GetState(guid)); + std::string const& state = lfg::GetStateString(sLFGMgr->GetState(guid)); handler->PSendSysMessage(LANG_LFG_GROUP_INFO, grp->isLFGGroup(), state.c_str(), sLFGMgr->GetDungeon(guid)); diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index 08140772db9..cc1b62ea99d 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -33,7 +33,7 @@ #include "ace/INET_Addr.h" #include "Player.h" #include "Pet.h" -#include "LFGMgr.h" +#include "LFG.h" #include "GroupMgr.h" class misc_commandscript : public CommandScript @@ -2863,7 +2863,7 @@ public: const char* onlineState = (p && p->IsInWorld()) ? "online" : "offline"; handler->PSendSysMessage(LANG_GROUP_PLAYER_NAME_GUID, slot.name.c_str(), onlineState, - GUID_LOPART(slot.guid), flags.c_str(), LFGMgr::GetRolesString(slot.roles).c_str()); + GUID_LOPART(slot.guid), flags.c_str(), lfg::GetRolesString(slot.roles).c_str()); } } else -- cgit v1.2.3 From f743424f630af8c8b940bcc3a8ed08512708540c Mon Sep 17 00:00:00 2001 From: Spp Date: Mon, 4 Feb 2013 05:50:52 +0100 Subject: Core/Dungeon Finder: Corrections to previous commit - player::inRandomLfgDungeon was supposed to return if current player map and difficulty are the ones player applied for --- src/server/game/DungeonFinding/LFG.cpp | 17 +++++++++++++++++ src/server/game/DungeonFinding/LFGMgr.cpp | 5 ++++- src/server/game/DungeonFinding/LFGMgr.h | 2 +- src/server/game/Entities/Player/Player.cpp | 8 +++++++- src/server/scripts/Spells/spell_generic.cpp | 2 +- 5 files changed, 30 insertions(+), 4 deletions(-) (limited to 'src/server/scripts') diff --git a/src/server/game/DungeonFinding/LFG.cpp b/src/server/game/DungeonFinding/LFG.cpp index e146899841f..ce16ad5533e 100644 --- a/src/server/game/DungeonFinding/LFG.cpp +++ b/src/server/game/DungeonFinding/LFG.cpp @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + #include "LFG.h" #include "Language.h" #include "ObjectMgr.h" diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index 05a15b9cb6a..3e8cc7d4aa9 100644 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -1960,7 +1960,7 @@ void LFGMgr::SetupGroupMember(uint64 guid, uint64 gguid) AddPlayerToGroup(gguid, guid); } -bool LFGMgr::inRandomLfgDungeon(uint64 guid) +bool LFGMgr::selectedRandomLfgDungeon(uint64 guid) { if (GetState(guid) != LFG_STATE_NONE) { @@ -1978,6 +1978,9 @@ bool LFGMgr::inRandomLfgDungeon(uint64 guid) bool LFGMgr::inLfgDungeonMap(uint64 guid, uint32 map, Difficulty difficulty) { + if (!IS_GROUP_GUID(guid)) + guid = GetGroup(guid); + if (uint32 dungeonId = GetDungeon(guid, true)) if (LFGDungeonData const* dungeon = GetLFGDungeon(dungeonId)) if (uint32(dungeon->map) == map && dungeon->difficulty == difficulty) diff --git a/src/server/game/DungeonFinding/LFGMgr.h b/src/server/game/DungeonFinding/LFGMgr.h index 20116caaaf3..43ae128174f 100644 --- a/src/server/game/DungeonFinding/LFGMgr.h +++ b/src/server/game/DungeonFinding/LFGMgr.h @@ -381,7 +381,7 @@ class LFGMgr void SetupGroupMember(uint64 guid, uint64 gguid); uint64 GetGroup(uint64 guid); - bool inRandomLfgDungeon(uint64 guid); + bool selectedRandomLfgDungeon(uint64 guid); bool inLfgDungeonMap(uint64 guid, uint32 map, Difficulty difficulty); private: diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 9c398bd88fb..72ddd0b8595 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -23465,7 +23465,13 @@ bool Player::isUsingLfg() bool Player::inRandomLfgDungeon() { - return sLFGMgr->inRandomLfgDungeon(GetGUID()); + if (sLFGMgr->selectedRandomLfgDungeon(GetGUID())) + { + Map const* map = GetMap(); + return sLFGMgr->inLfgDungeonMap(GetGUID(), map->GetId(), map->GetDifficulty()); + } + + return false; } void Player::SetBattlegroundOrBattlefieldRaid(Group* group, int8 subgroup) diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index 54ca3efd6d5..61f4a81bc73 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -1728,7 +1728,7 @@ class spell_gen_luck_of_the_draw : public SpellScriptLoader if (!group || group->isLFGGroup()) return false; - if (!sLFGMgr->inRandomLfgDungeon(owner->GetGUID())) + if (!sLFGMgr->selectedRandomLfgDungeon(owner->GetGUID())) return false; map = owner->GetMap(); -- cgit v1.2.3 From ec5d16db8a688a2b6262333e5f1e927e2c1f639a Mon Sep 17 00:00:00 2001 From: Spp Date: Mon, 4 Feb 2013 06:43:03 +0100 Subject: Core/Dungeon Finder: Declare some functions private as those are not used outside LFGMgr. Also do not expose LFGDungeonData outside LFGMgr --- src/server/game/DungeonFinding/LFGMgr.cpp | 31 ++++-- src/server/game/DungeonFinding/LFGMgr.h | 167 +++++++++++++++++----------- src/server/game/Entities/Player/Player.cpp | 2 +- src/server/game/Globals/ObjectMgr.cpp | 2 +- src/server/game/Handlers/LFGHandler.cpp | 23 +--- src/server/scripts/Spells/spell_generic.cpp | 2 +- 6 files changed, 135 insertions(+), 92 deletions(-) (limited to 'src/server/scripts') diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index 3e8cc7d4aa9..d9d4a897eed 100644 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -127,7 +127,7 @@ void LFGMgr::LoadRewards() uint32 firstQuestId = fields[2].GetUInt32(); uint32 otherQuestId = fields[3].GetUInt32(); - if (!GetLFGDungeon(dungeonId)) + if (!GetLFGDungeonEntry(dungeonId)) { sLog->outError(LOG_FILTER_SQL, "Dungeon %u specified in table `lfg_dungeon_rewards` does not exist!", dungeonId); continue; @@ -168,11 +168,6 @@ LFGDungeonData const* LFGMgr::GetLFGDungeon(uint32 id) return NULL; } -LFGDungeonContainer & LFGMgr::GetLFGDungeonMap() -{ - return LfgDungeonStore; -} - void LFGMgr::LoadLFGDungeons(bool reload /* = false */) { uint32 oldMSTime = getMSTime(); @@ -1595,7 +1590,7 @@ const std::string& LFGMgr::GetComment(uint64 guid) return PlayersStore[guid].GetComment(); } -bool LFGMgr::IsTeleported(uint64 pguid) +bool LFGMgr::hasPendingTeleport(uint64 pguid) { if (std::find(teleportStore.begin(), teleportStore.end(), pguid) != teleportStore.end()) { @@ -1989,4 +1984,26 @@ bool LFGMgr::inLfgDungeonMap(uint64 guid, uint32 map, Difficulty difficulty) return false; } +uint32 LFGMgr::GetLFGDungeonEntry(uint32 id) +{ + if (id) + if (LFGDungeonData const* dungeon = GetLFGDungeon(id)) + return dungeon->Entry(); + + return 0; +} + +LfgDungeonSet LFGMgr::GetRandomAndSeasonalDungeons(uint8 level, uint8 expansion) +{ + LfgDungeonSet randomDungeons; + for (lfg::LFGDungeonContainer::const_iterator itr = LfgDungeonStore.begin(); itr != LfgDungeonStore.end(); ++itr) + { + lfg::LFGDungeonData const& dungeon = itr->second; + if ((dungeon.type == lfg::LFG_TYPE_RANDOM || (dungeon.seasonal && sLFGMgr->IsSeasonActive(dungeon.id))) + && dungeon.expansion <= expansion && dungeon.minlevel <= level && level <= dungeon.maxlevel) + randomDungeons.insert(dungeon.Entry()); + } + return randomDungeons; +} + } // namespace lfg diff --git a/src/server/game/DungeonFinding/LFGMgr.h b/src/server/game/DungeonFinding/LFGMgr.h index 43ae128174f..da7980647bb 100644 --- a/src/server/game/DungeonFinding/LFGMgr.h +++ b/src/server/game/DungeonFinding/LFGMgr.h @@ -299,91 +299,125 @@ class LFGMgr ~LFGMgr(); public: + // Functions used outside lfg namespace void Update(uint32 diff); - // Reward - void LoadRewards(); + // World.cpp + /// Finish the dungeon for the given group. All check are performed using internal lfg data void FinishDungeon(uint64 gguid, uint32 dungeonId); - LfgReward const* GetRandomDungeonReward(uint32 dungeon, uint8 level); - - // Queue - void JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons, std::string const& comment); - void LeaveLfg(uint64 guid); - - // Role Check - void UpdateRoleCheck(uint64 gguid, uint64 guid = 0, uint8 roles = PLAYER_ROLE_NONE); - - // Group Matching - static bool CheckGroupRoles(LfgRolesMap &groles, bool removeLeaderFlag = true); - void GetCompatibleDungeons(LfgDungeonSet& dungeons, LfgGuidSet const& players, LfgLockPartyMap& lockMap); - - // Proposals - uint32 AddProposal(LfgProposal& proposal); - void UpdateProposal(uint32 proposalId, uint64 guid, bool accept); + /// Loads rewards for random dungeons + void LoadRewards(); + /// Loads dungeons from dbc and adds teleport coords + void LoadLFGDungeons(bool reload = false); - // Teleportation - void TeleportPlayer(Player* player, bool out, bool fromOpcode = false); + // Multiple files + /// Check if given guid applied for random dungeon + bool selectedRandomLfgDungeon(uint64 guid); + /// Check if given guid applied for given map and difficulty. Used to know + bool inLfgDungeonMap(uint64 guid, uint32 map, Difficulty difficulty); + /// Get selected dungeons + LfgDungeonSet const& GetSelectedDungeons(uint64 guid); + /// Get current lfg state + LfgState GetState(uint64 guid); + /// Get current dungeon + uint32 GetDungeon(uint64 guid, bool asId = true); + /// Get the map id of the current dungeon + uint32 GetDungeonMapId(uint64 guid); + /// Get kicks left in current group + uint8 GetKicksLeft(uint64 gguid); + /// Load Lfg group info from DB + void _LoadFromDB(Field* fields, uint64 guid); + /// Initializes player data after loading group data from DB + void SetupGroupMember(uint64 guid, uint64 gguid); + /// Player has pending teleport action + bool hasPendingTeleport(uint64 guid); + /// Return Lfg dungeon entry for given dungeon id + uint32 GetLFGDungeonEntry(uint32 id); - // Vote kick - void InitBoot(uint64 gguid, uint64 kguid, uint64 vguid, std::string const& reason); - void UpdateBoot(uint64 guid, bool accept); + // cs_lfg + /// Get current player roles + uint8 GetRoles(uint64 guid); + /// Get current player comment (used for LFR) + std::string const& GetComment(uint64 gguid); + /// Gets current lfg options + uint32 GetOptions(); // cs_lfg + /// Sets new lfg options + void SetOptions(uint32 options); + /// Checks if given lfg option is enabled + bool isOptionEnabled(uint32 option); + /// Clears queue - Only for internal testing + void Clean(); + /// Dumps the state of the queue - Only for internal testing + std::string DumpQueueInfo(bool full = false); + // LFGScripts + /// Get leader of the group (using internal data) + uint64 GetLeader(uint64 guid); + /// Initializes locked dungeons for given player (called at login or level change) void InitializeLockedDungeons(Player* player, uint8 level = 0); - - void SetRoles(uint64 guid, uint8 roles); - void SetComment(uint64 guid, std::string const& comment); + /// Inits new proposal to boot a player + void InitBoot(uint64 gguid, uint64 kguid, uint64 vguid, std::string const& reason); + /// Sets player team void SetTeam(uint64 guid, uint8 team); + /// Sets player group void SetGroup(uint64 guid, uint64 group); + /// Gets player group + uint64 GetGroup(uint64 guid); + /// Sets the leader of the group void SetLeader(uint64 gguid, uint64 leader); - void SetState(uint64 guid, LfgState state); - - void _LoadFromDB(Field* fields, uint64 guid); - void _SaveToDB(uint64 guid, uint32 db_guid); - - void RemovePlayerData(uint64 guid); + /// Removes saved group data void RemoveGroupData(uint64 guid); + /// Removes a player from a group uint8 RemovePlayerFromGroup(uint64 gguid, uint64 guid); + /// Adds player to group void AddPlayerToGroup(uint64 gguid, uint64 guid); + // LFGHandler + /// Get locked dungeons LfgLockMap const& GetLockedDungeons(uint64 guid); - LfgDungeonSet const& GetSelectedDungeons(uint64 guid); - uint32 GetDungeon(uint64 guid, bool asId = true); - uint32 GetDungeonMapId(uint64 guid); - LfgState GetState(uint64 guid); + /// Returns current lfg status + LfgUpdateData GetLfgStatus(uint64 guid); + /// Checks if Seasonal dungeon is active + bool IsSeasonActive(uint32 dungeonId); + /// Gets the random dungeon reward corresponding to given dungeon and player level + LfgReward const* GetRandomDungeonReward(uint32 dungeon, uint8 level); + /// Returns all random and seasonal dungeons for given level and expansion + LfgDungeonSet GetRandomAndSeasonalDungeons(uint8 level, uint8 expansion); + /// Teleport a player to/from selected dungeon + void TeleportPlayer(Player* player, bool out, bool fromOpcode = false); + /// Updates player boot proposal with new player answer + void UpdateBoot(uint64 guid, bool accept); + /// Updates proposal to join dungeon with player answer + void UpdateProposal(uint32 proposalId, uint64 guid, bool accept); + /// Updates the role check with player answer + void UpdateRoleCheck(uint64 gguid, uint64 guid = 0, uint8 roles = PLAYER_ROLE_NONE); + /// Sets player lfg roles + void SetRoles(uint64 guid, uint8 roles); + /// Sets player lfr comment + void SetComment(uint64 guid, std::string const& comment); + /// Join Lfg with selected roles, dungeons and comment + void JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons, std::string const& comment); + /// Leaves lfg + void LeaveLfg(uint64 guid); + + // LfgQueue + /// Get last lfg state (NONE, DUNGEON or FINISHED_DUNGEON) LfgState GetOldState(uint64 guid); - uint8 GetKicksLeft(uint64 gguid); - uint64 GetLeader(uint64 guid); + /// Check if given group guid is lfg bool IsLfgGroup(uint64 guid); - uint8 GetRoles(uint64 guid); - std::string const& GetComment(uint64 gguid); - LfgGuidSet const& GetPlayers(uint64 guid); + /// Gets the player count of given group uint8 GetPlayerCount(uint64 guid); - - bool IsTeleported(uint64 guid); - + /// Add a new Proposal + uint32 AddProposal(LfgProposal& proposal); + /// Checks if all players are queued bool AllQueued(LfgGuidList const& check); - void Clean(); - + /// Checks if given roles match, modifies given roles map with new roles + static bool CheckGroupRoles(LfgRolesMap &groles, bool removeLeaderFlag = true); + /// Checks if given players are ignoring each other static bool HasIgnore(uint64 guid1, uint64 guid2); + /// Sends queue status to player static void SendLfgQueueStatus(uint64 guid, LfgQueueStatusData const& data); - bool isOptionEnabled(uint32 option); - uint32 GetOptions(); - void SetOptions(uint32 options); - LfgUpdateData GetLfgStatus(uint64 guid); - bool IsSeasonActive(uint32 dungeonId); - - std::string DumpQueueInfo(bool full = false); - - void LoadLFGDungeons(bool reload = false); - LFGDungeonData const* GetLFGDungeon(uint32 id); - LFGDungeonContainer& GetLFGDungeonMap(); - void SetupGroupMember(uint64 guid, uint64 gguid); - uint64 GetGroup(uint64 guid); - - bool selectedRandomLfgDungeon(uint64 guid); - bool inLfgDungeonMap(uint64 guid, uint32 map, Difficulty difficulty); - private: uint8 GetTeam(uint64 guid); void RestoreState(uint64 guid, char const* debugMsg); @@ -392,6 +426,11 @@ class LFGMgr void SetSelectedDungeons(uint64 guid, LfgDungeonSet const& dungeons); void SetLockedDungeons(uint64 guid, LfgLockMap const& lock); void DecreaseKicksLeft(uint64 guid); + void SetState(uint64 guid, LfgState state); + void RemovePlayerData(uint64 guid); + void GetCompatibleDungeons(LfgDungeonSet& dungeons, LfgGuidSet const& players, LfgLockPartyMap& lockMap); + void _SaveToDB(uint64 guid, uint32 db_guid); + LFGDungeonData const* GetLFGDungeon(uint32 id); // Proposals void RemoveProposal(LfgProposalContainer::iterator itProposal, LfgUpdateType type); @@ -410,6 +449,8 @@ class LFGMgr void SendLfgUpdatePlayer(uint64 guid, LfgUpdateData const& data); void SendLfgUpdateProposal(uint64 guid, LfgProposal const& proposal); + LfgGuidSet const& GetPlayers(uint64 guid); + // General variables uint32 m_QueueTimer; ///< used to check interval of update uint32 m_lfgProposalId; ///< used as internal counter for proposals diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 72ddd0b8595..a4356f55340 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -7446,7 +7446,7 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea) if (Group* group = GetGroup()) { SetGroupUpdateFlag(GROUP_UPDATE_FULL); - if (GetSession() && group->isLFGGroup() && sLFGMgr->IsTeleported(GetGUID())) + if (GetSession() && group->isLFGGroup() && sLFGMgr->hasPendingTeleport(GetGUID())) { for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) { diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index a3a5c865a48..1dd824759c9 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -5010,7 +5010,7 @@ void ObjectMgr::LoadInstanceEncounters() continue; } - if (lastEncounterDungeon && !sLFGMgr->GetLFGDungeon(lastEncounterDungeon)) + if (lastEncounterDungeon && !sLFGMgr->GetLFGDungeonEntry(lastEncounterDungeon)) { sLog->outError(LOG_FILTER_SQL, "Table `instance_encounters` has an encounter %u (%s) marked as final for invalid dungeon id %u, skipped!", entry, dungeonEncounter->encounterName[0], lastEncounterDungeon); continue; diff --git a/src/server/game/Handlers/LFGHandler.cpp b/src/server/game/Handlers/LFGHandler.cpp index 60fc63694ee..619e9b68b51 100644 --- a/src/server/game/Handlers/LFGHandler.cpp +++ b/src/server/game/Handlers/LFGHandler.cpp @@ -167,18 +167,9 @@ void WorldSession::HandleLfgPlayerLockInfoRequestOpcode(WorldPacket& /*recvData* GetPlayerInfo().c_str()); // Get Random dungeons that can be done at a certain level and expansion - lfg::LfgDungeonSet randomDungeons; uint8 level = GetPlayer()->getLevel(); - uint8 expansion = GetPlayer()->GetSession()->Expansion(); - - lfg::LFGDungeonContainer& LfgDungeons = sLFGMgr->GetLFGDungeonMap(); - for (lfg::LFGDungeonContainer::const_iterator itr = LfgDungeons.begin(); itr != LfgDungeons.end(); ++itr) - { - lfg::LFGDungeonData const& dungeon = itr->second; - if ((dungeon.type == lfg::LFG_TYPE_RANDOM || (dungeon.seasonal && sLFGMgr->IsSeasonActive(dungeon.id))) - && dungeon.expansion <= expansion && dungeon.minlevel <= level && level <= dungeon.maxlevel) - randomDungeons.insert(dungeon.Entry()); - } + lfg::LfgDungeonSet const& randomDungeons = + sLFGMgr->GetRandomAndSeasonalDungeons(level, GetPlayer()->GetSession()->Expansion()); // Get player locked Dungeons lfg::LfgLockMap const& lock = sLFGMgr->GetLockedDungeons(guid); @@ -421,13 +412,8 @@ void WorldSession::SendLfgRoleCheckUpdate(lfg::LfgRoleCheck const& roleCheck) data << uint8(roleCheck.state == lfg::LFG_ROLECHECK_INITIALITING); data << uint8(dungeons.size()); // Number of dungeons if (!dungeons.empty()) - { for (lfg::LfgDungeonSet::iterator it = dungeons.begin(); it != dungeons.end(); ++it) - { - lfg::LFGDungeonData const* dungeon = sLFGMgr->GetLFGDungeon(*it); - data << uint32(dungeon ? dungeon->Entry() : 0); // Dungeon - } - } + data << uint32(sLFGMgr->GetLFGDungeonEntry(*it)); // Dungeon data << uint8(roleCheck.roles.size()); // Players in group if (!roleCheck.roles.empty()) @@ -585,8 +571,7 @@ void WorldSession::SendLfgUpdateProposal(lfg::LfgProposal const& proposal) dungeonEntry = (*playerDungeons.begin()); } - if (lfg::LFGDungeonData const* dungeon = sLFGMgr->GetLFGDungeon(dungeonEntry)) - dungeonEntry = dungeon->Entry(); + dungeonEntry = sLFGMgr->GetLFGDungeonEntry(dungeonEntry); WorldPacket data(SMSG_LFG_PROPOSAL_UPDATE, 4 + 1 + 4 + 4 + 1 + 1 + proposal.players.size() * (4 + 1 + 1 + 1 + 1 +1)); data << uint32(dungeonEntry); // Dungeon diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index 61f4a81bc73..39992e94c21 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -1725,7 +1725,7 @@ class spell_gen_luck_of_the_draw : public SpellScriptLoader return false; Group* group = owner->GetGroup(); - if (!group || group->isLFGGroup()) + if (!group || !group->isLFGGroup()) return false; if (!sLFGMgr->selectedRandomLfgDungeon(owner->GetGUID())) -- cgit v1.2.3 From b980aff83e214bab60f141c879c2a392789a4d16 Mon Sep 17 00:00:00 2001 From: Spp Date: Mon, 4 Feb 2013 08:21:25 +0100 Subject: Core: Implement Role based Access Control - This system will give more control of actions an account can perform. System defines: - Permissions to perform some action - Roles: a set of permissions that have some relation - Groups: a set of roles that have some relation Operations: - Grant: Assign and allow - Deny: Assign and do not allow - Revoke: Remove Precedence to know if something can be done: Grant, Deny. That means, if you are granted some action by a role but you have denied the permission, the action can not be done. Some Rules: - Groups can only have roles - Roles can only have permissions - An account can be assigned granted and denied roles. Permissions inherited from roles are granted if roles is granted and denied if roles is denied - An account can be assigned granted and denied permissions - An account can have multiple groups, roles and permissions - An account can not have same role granted and denied at same time - An acconnt can not have same permission granted and denied at same time - Id 0 can not be used to define a group, role or permission Added some permissions as a sample of use (Instant Logout, Skip Queue, Join BGs, Join DF) and some permissions as a workaround to commands till command system is modified to use RBAC --- sql/updates/auth/2013_02_04_00_auth_misc.sql | 173 ++++++++++++++++ sql/updates/world/2013_02_04_03_world_misc.sql | 53 +++++ src/server/game/AI/CreatureAIImpl.h | 30 +-- src/server/game/Accounts/AccountMgr.cpp | 217 ++++++++++++++++++++- src/server/game/Accounts/AccountMgr.h | 27 ++- src/server/game/Chat/Chat.cpp | 25 ++- src/server/game/DungeonFinding/LFGMgr.cpp | 11 +- src/server/game/DungeonFinding/LFGMgr.h | 2 +- src/server/game/Entities/Player/Player.cpp | 11 +- src/server/game/Handlers/MiscHandler.cpp | 2 +- src/server/game/Miscellaneous/Language.h | 35 +++- src/server/game/Scripting/ScriptLoader.cpp | 2 + src/server/game/Server/WorldSession.cpp | 29 ++- src/server/game/Server/WorldSession.h | 6 + src/server/game/Server/WorldSocket.cpp | 1 + src/server/game/World/World.cpp | 7 +- src/server/scripts/Commands/CMakeLists.txt | 1 + src/server/scripts/Commands/cs_account.cpp | 34 +--- .../Database/Implementation/LoginDatabase.cpp | 16 +- .../shared/Database/Implementation/LoginDatabase.h | 10 + src/server/worldserver/worldserver.conf.dist | 20 -- 21 files changed, 625 insertions(+), 87 deletions(-) create mode 100644 sql/updates/auth/2013_02_04_00_auth_misc.sql create mode 100644 sql/updates/world/2013_02_04_03_world_misc.sql (limited to 'src/server/scripts') diff --git a/sql/updates/auth/2013_02_04_00_auth_misc.sql b/sql/updates/auth/2013_02_04_00_auth_misc.sql new file mode 100644 index 00000000000..573b58ac156 --- /dev/null +++ b/sql/updates/auth/2013_02_04_00_auth_misc.sql @@ -0,0 +1,173 @@ +-- Need them first in case of re-execute due to foreign keys +DROP TABLE IF EXISTS `rbac_account_permissions`; +DROP TABLE IF EXISTS `rbac_account_roles`; +DROP TABLE IF EXISTS `rbac_account_groups`; +DROP TABLE IF EXISTS `rbac_role_permissions`; +DROP TABLE IF EXISTS `rbac_group_roles`; +DROP TABLE IF EXISTS `rbac_permissions`; +DROP TABLE IF EXISTS `rbac_roles`; +DROP TABLE IF EXISTS `rbac_groups`; +DROP TABLE IF EXISTS `rbac_security_level_groups`; + +CREATE TABLE IF NOT EXISTS `rbac_groups` ( + `id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Group id', + `name` varchar(50) NOT NULL COMMENT 'Group name', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Group List'; + +CREATE TABLE IF NOT EXISTS `rbac_roles` ( + `id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Role id', + `name` varchar(50) NOT NULL COMMENT 'Role name', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Roles List'; + +CREATE TABLE IF NOT EXISTS `rbac_permissions` ( + `id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Permission id', + `name` varchar(100) NOT NULL COMMENT 'Permission name', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Permission List'; + +CREATE TABLE IF NOT EXISTS `rbac_group_roles` ( + `groupId` int(10) unsigned NOT NULL COMMENT 'group id', + `roleId` int(10) unsigned NOT NULL COMMENT 'Role id', + PRIMARY KEY (`groupId`, `roleId`), + CONSTRAINT `fk__rbac_group_roles__rbac_roles` + FOREIGN KEY (`roleId`) REFERENCES `rbac_roles`(`id`) + ON DELETE CASCADE ON UPDATE RESTRICT, + CONSTRAINT `fk__rbac_group_roles__rbac_groups` + FOREIGN KEY (`groupId`) REFERENCES `rbac_groups`(`id`) + ON DELETE CASCADE ON UPDATE RESTRICT +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Group Role relation'; + +CREATE TABLE IF NOT EXISTS `rbac_role_permissions` ( + `roleId` int(10) unsigned NOT NULL COMMENT 'Role id', + `permissionId` int(10) unsigned NOT NULL COMMENT 'Permission id', + PRIMARY KEY (`roleId`, `permissionId`), + CONSTRAINT `fk__role_permissions__rbac_roles` + FOREIGN KEY (`roleId`) REFERENCES `rbac_roles`(`id`) + ON DELETE CASCADE ON UPDATE RESTRICT, + CONSTRAINT `fk__role_permissions__rbac_permissions` + FOREIGN KEY (`permissionId`) REFERENCES `rbac_permissions`(`id`) + ON DELETE CASCADE ON UPDATE RESTRICT +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Role Permission relation'; + +CREATE TABLE IF NOT EXISTS `rbac_security_level_groups` ( + `secId` int(10) unsigned NOT NULL COMMENT 'Security Level id', + `groupId` int(10) unsigned NOT NULL COMMENT 'group id', + PRIMARY KEY (`secId`, `groupId`), + CONSTRAINT `fk__rbac_security_level_groups__rbac_groups` + FOREIGN KEY (`groupId`) REFERENCES `rbac_groups`(`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Default groups to assign when an account is set gm level'; + +CREATE TABLE IF NOT EXISTS `rbac_account_groups` ( + `accountId` int(10) unsigned NOT NULL COMMENT 'Account id', + `groupId` int(10) unsigned NOT NULL COMMENT 'Group id', + `realmId` int(11) NOT NULL DEFAULT '-1' COMMENT 'Realm Id, -1 means all', + PRIMARY KEY (`accountId`, `groupId`, `realmId`), + CONSTRAINT `fk__rbac_account_groups__account` + FOREIGN KEY (`accountId`) REFERENCES `account`(`id`) + ON DELETE CASCADE ON UPDATE RESTRICT, + CONSTRAINT `fk__rbac_account_groups__rbac_groups` + FOREIGN KEY (`groupId`) REFERENCES `rbac_groups`(`id`) + ON DELETE CASCADE ON UPDATE RESTRICT +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Account-Group relation'; + +CREATE TABLE IF NOT EXISTS `rbac_account_roles` ( + `accountId` int(10) unsigned NOT NULL COMMENT 'Account id', + `roleId` int(10) unsigned NOT NULL COMMENT 'Role id', + `granted` tinyint(1) NOT NULL default 1 COMMENT 'Granted = 1, Denied = 0', + `realmId` int(11) NOT NULL DEFAULT '-1' COMMENT 'Realm Id, -1 means all', + PRIMARY KEY (`accountId`, `roleId`, `realmId`), + CONSTRAINT `fk__rbac_account_roles__account` + FOREIGN KEY (`accountId`) REFERENCES `account`(`id`) + ON DELETE CASCADE ON UPDATE RESTRICT, + CONSTRAINT `fk__rbac_account_roles__rbac_roles` + FOREIGN KEY (`roleId`) REFERENCES `rbac_roles`(`id`) + ON DELETE CASCADE ON UPDATE RESTRICT +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Account-Role relation'; + +CREATE TABLE IF NOT EXISTS `rbac_account_permissions` ( + `accountId` int(10) unsigned NOT NULL COMMENT 'Account id', + `permissionId` int(10) unsigned NOT NULL COMMENT 'Permission id', + `granted` tinyint(1) NOT NULL default 1 COMMENT 'Granted = 1, Denied = 0', + `realmId` int(11) NOT NULL DEFAULT '-1' COMMENT 'Realm Id, -1 means all', + PRIMARY KEY (`accountId`, `permissionId`, `realmId`), + CONSTRAINT `fk__rbac_account_permissions__account` + FOREIGN KEY (`accountId`) REFERENCES `account`(`id`) + ON DELETE CASCADE ON UPDATE RESTRICT, + CONSTRAINT `fk__rbac_account_roles__rbac_permissions` + FOREIGN KEY (`permissionId`) REFERENCES `rbac_permissions`(`id`) + ON DELETE CASCADE ON UPDATE RESTRICT +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Account-Permission relation'; + +DELETE FROM `rbac_permissions` WHERE `id` BETWEEN 1 AND 10; +INSERT INTO `rbac_permissions` (`id`, `name`) VALUES +(1, 'Instant logout'), +(2, 'Skip Queue'), +(3, 'Join Normal Battleground'), +(4, 'Join Random Battleground'), +(5, 'Join Arenas'), +(6, 'Join Dungeon Finder'), +(7, 'Player Commands (Temporal till commands moved to rbac)'), +(8, 'Moderator Commands (Temporal till commands moved to rbac)'), +(9, 'GameMaster Commands (Temporal till commands moved to rbac)'), +(10, 'Administrator Commands (Temporal till commands moved to rbac)'); + +DELETE FROM `rbac_roles` WHERE `id` BETWEEN 1 AND 7; +INSERT INTO `rbac_roles` (`id`, `name`) VALUES +(1, 'Player Commands'), +(2, 'Moderator Commands'), +(3, 'GameMaster Commands'), +(4, 'Administrator Commands'), +(5, 'Quick Login/Logout'), +(6, 'Use Battleground/Arenas'), +(7, 'Use Dungeon Finder'); + +DELETE FROM `rbac_groups` WHERE `id` BETWEEN 1 AND 4; +INSERT INTO `rbac_groups` (`id`, `name`) VALUES +(1, 'Player'), +(2, 'Moderator'), +(3, 'GameMaster'), +(4, 'Administrator'); + +DELETE FROM `rbac_role_permissions` WHERE `roleId` BETWEEN 1 AND 7; +INSERT INTO `rbac_role_permissions` (`roleId`, `permissionId`) VALUES +(5, 1), +(5, 2), +(6, 3), +(6, 4), +(6, 5), +(7, 6), +(1, 7), +(2, 8), +(3, 9), +(4, 10); + +DELETE FROM `rbac_group_roles` WHERE `groupId` BETWEEN 1 AND 4; +INSERT INTO `rbac_group_roles` (`groupId`, `roleId`) VALUES +(1, 1), +(1, 6), +(1, 7), +(2, 2), +(2, 5), +(3, 3), +(4, 4); + +TRUNCATE `rbac_account_groups`; +INSERT INTO `rbac_account_groups` (`accountId`, `groupId`, `realmId`) SELECT `id`, 1, -1 FROM `account`; -- Add Player group to all accounts +INSERT INTO `rbac_account_groups` (`accountId`, `groupId`, `realmId`) SELECT `id`, 2, `RealmID` FROM `account_access` WHERE `gmlevel` > 0; -- Add Moderator group to all Moderator or higher GM level +INSERT INTO `rbac_account_groups` (`accountId`, `groupId`, `realmId`) SELECT `id`, 3, `RealmID` FROM `account_access` WHERE `gmlevel` > 1; -- Add GameMaster group to all GameMasters or higher GM level +INSERT INTO `rbac_account_groups` (`accountId`, `groupId`, `realmId`) SELECT `id`, 4, `RealmID` FROM `account_access` WHERE `gmlevel` > 2; -- Add Administrator group to all Administrators + +TRUNCATE `rbac_security_level_groups`; +INSERT INTO `rbac_security_level_groups` (`secId`, `groupId`) VALUES +(0, 1), +(1, 1), +(1, 2), +(2, 1), +(2, 2), +(2, 3), +(3, 1), +(3, 2), +(3, 3), +(3, 4); diff --git a/sql/updates/world/2013_02_04_03_world_misc.sql b/sql/updates/world/2013_02_04_03_world_misc.sql new file mode 100644 index 00000000000..a609d411b6e --- /dev/null +++ b/sql/updates/world/2013_02_04_03_world_misc.sql @@ -0,0 +1,53 @@ +DELETE FROM `trinity_string` WHERE `entry` BETWEEN 63 AND 95; +INSERT INTO trinity_string (entry, content_default) VALUES +(63, "Wrong parameter id: %u, does not exist"), +(64, "Wrong parameter realmId: %d"), +(65, "Couldn't add group %u (%s) realmId %d. Account %u (%s) already has that group"), +(66, "Couldn't remove group %u (%s) realmId %d. Account %u (%s) does not have that group"), +(67, "Added group %u (%s) realmId %d to account %u (%s)"), +(68, "Removed group %u (%s) realmId %d from account %u (%s)"), +(69, "Account %u (%s) groups:"), +(70, "Empty List"), +(71, "- %u (%s)"), +(72, "Couldn't grant role %u (%s) realmId %d. Account %u (%s) already has that role"), +(73, "Couldn't grant role %u (%s) realmId %d. Account %u (%s) has that role in deny list"), +(74, "Granted role %u (%s) realmId %d to account %u (%s)"), +(75, "Couldn't deny role %u (%s) realmId %d. Account %u (%s) already has that role"), +(76, "Couldn't deny role %u (%s) realmId %d. Account %u (%s) has that role in deny list"), +(77, "Denied role %u (%s) realmId %d to account %u (%s)"), +(78, "Denied role %u (%s) realmId %d to account %u (%s)"), +(79, "Couldn't revoke role %u (%s) realmId %d. Account %u (%s) does not have that role"), +(80, "Account %u (%s) granted roles:"), +(81, "Account %u (%s) denied roles:"), +(82, "Couldn't grant permission %u (%s) realmId %d. Account %u (%s) already has that permission"), +(83, "Couldn't grant permission %u (%s) realmId %d. Account %u (%s) has that permission in deny list"), +(84, "Granted permission %u (%s) realmId %d to account %u (%s)"), +(85, "Couldn't deny permission %u (%s) realmId %d. Account %u (%s) already has that permission"), +(86, "Couldn't deny permission %u (%s) realmId %d. Account %u (%s) has that permission in deny list"), +(87, "Denied permission %u (%s) realmId %d to account %u (%s)"), +(88, "Revoked permission %u (%s) realmId %d to account %u (%s)"), +(89, "Couldn't revoke permission %u (%s) realmId %d. Account %u (%s) does not have that permission"), +(90, "Account %u (%s) granted permissions:"), +(91, "Account %u (%s) denied permissions:"), +(92, "Account %u (%s) global permissions:"), +(93, "Groups:"), +(94, "Roles:"), +(95, "Permissions:"); + +DELETE FROM `command` WHERE `name` LIKE '.rbac%'; +INSERT INTO `command` (`name`, `security`, `help`) VALUES +('.rbac account', 3, 'Syntax: .rbac account [$account]\n\nView permissions of selected player or given account\nNote: Only those that affect current realm\n\nNote: Shows real permissions after checking group and roles'), +('.rbac account group', 3, 'Syntax: .rbac account group [$account]\n\nView groups of selected player or given account\nNote: Only those that affect current realm'), +('.rbac account group add', 3, 'Syntax: .rbac account group add [$account] #id [#realmId]\n\nAdd a group to selected player or given account.\n\n#reamID may be -1 for all realms.'), +('.rbac account group remove', 3, 'Syntax: .rbac account group remove [$account] #id\n\nRemove a group from selected player or given account.'), +('.rbac account role', 3, 'Syntax: .rbac account role [$account]\n\nView roles of selected player or given account\nNote: Only those that affect current realm\nNote: Only those directly granted or denied, does not include inherited roles from groups'), +('.rbac account role grant', 3, 'Syntax: .rbac account role grant [$account] #id [#realmId]\n\nGrant a role to selected player or given account.\n\n#reamID may be -1 for all realms.'), +('.rbac account role deny', 3, 'Syntax: .rbac account role deny [$account] #id [#realmId]\n\nDeny a role to selected player or given account.\n\n#reamID may be -1 for all realms.'), +('.rbac account role revoke', 3, 'Syntax: .rbac account role revoke [$account] #id\n\nRemove a role from an account\n\nNote: Removes the role from granted or denied roles'), +('.rbac account permission', 3, 'Syntax: .rbac account permission [$account]\n\nView permissions of selected player or given account\nNote: Only those that affect current realm\nNote: Only those directly granted or denied, does not include inherited permissions from roles'), +('.rbac account permission grant', 3, 'Syntax: .rbac account permission grant [$account] #id [#realmId]\n\nGrant a permission to selected player or given account.\n\n#reamID may be -1 for all realms.'), +('.rbac account permission deny', 3, 'Syntax: .rbac account permission deny [$account] #id [#realmId]\n\nDeny a permission to selected player or given account.\n\n#reamID may be -1 for all realms.'), +('.rbac account permission revoke', 3, 'Syntax: .rbac account permission revoke [$account] #id\n\nRemove a permission from an account\n\nNote: Removes the permission from granted or denied permissions'), +('.rbac list groups', 3, 'Syntax: .rbac list groups [$id]\n\nView list of all groups. If $id is given will show group info and his inherited roles.'), +('.rbac list roles', 3, 'Syntax: .rbac list roles [$id]\n\nView list of all roles. If $id is given will show role info and his inherited permissions.'), +('.rbac list permissions', 3, 'Syntax: .rbac list permissions [$id]\n\nView list of all permissions. If $id is given will show only info for that permission.'); diff --git a/src/server/game/AI/CreatureAIImpl.h b/src/server/game/AI/CreatureAIImpl.h index 7121a031ec2..6c5cb5622b3 100644 --- a/src/server/game/AI/CreatureAIImpl.h +++ b/src/server/game/AI/CreatureAIImpl.h @@ -314,10 +314,10 @@ const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, c class EventMap { /** - * Internal storage type. + * Internal storage type. * Key: Time as uint32 when the event should occur. - * Value: The event data as uint32. - * + * Value: The event data as uint32. + * * Structure of event data: * - Bit 0 - 15: Event Id. * - Bit 16 - 23: Group @@ -454,7 +454,7 @@ class EventMap { if (Empty()) return; - + uint32 eventId = _eventMap.begin()->second; _eventMap.erase(_eventMap.begin()); ScheduleEvent(eventId, time); @@ -480,7 +480,7 @@ class EventMap while (!Empty()) { EventStore::iterator itr = _eventMap.begin(); - + if (itr->first > _time) return 0; else if (_phase && (itr->second & 0xFF000000) && !((itr->second >> 24) & _phase)) @@ -492,7 +492,7 @@ class EventMap return eventId; } } - + return 0; } @@ -506,7 +506,7 @@ class EventMap while (!Empty()) { EventStore::iterator itr = _eventMap.begin(); - + if (itr->first > _time) return 0; else if (_phase && (itr->second & 0xFF000000) && !(itr->second & (_phase << 24))) @@ -514,7 +514,7 @@ class EventMap else return (itr->second & 0x0000FFFF); } - + return 0; } @@ -538,7 +538,7 @@ class EventMap { if (!group || group > 8 || Empty()) return; - + EventStore delayed; for (EventStore::iterator itr = _eventMap.begin(); itr != _eventMap.end();) @@ -551,7 +551,7 @@ class EventMap else ++itr; } - + _eventMap.insert(delayed.begin(), delayed.end()); } @@ -578,7 +578,7 @@ class EventMap * @name CancelEventGroup * @brief Cancel events belonging to specified group. * @param group Group to cancel. - */ + */ void CancelEventGroup(uint32 group) { if (!group || group > 8 || Empty()) @@ -610,7 +610,7 @@ class EventMap return 0; } - + /** * @name GetNextEventTime * @return Time of next event. @@ -636,14 +636,14 @@ class EventMap * @name _time * @brief Internal timer. * - * This does not represent the real date/time value. + * This does not represent the real date/time value. * It's more like a stopwatch: It can run, it can be stopped, * it can be resetted and so on. Events occur when this timer * has reached their time value. Its value is changed in the * Update method. */ uint32 _time; - + /** * @name _phase * @brief Phase mask of the event map. @@ -653,7 +653,7 @@ class EventMap * AddPhase. RemovePhase deactives a phase. */ uint8 _phase; - + /** * @name _eventMap * @brief Internal event storage map. Contains the scheduled events. diff --git a/src/server/game/Accounts/AccountMgr.cpp b/src/server/game/Accounts/AccountMgr.cpp index 3c3eded1f68..ce382342de8 100644 --- a/src/server/game/Accounts/AccountMgr.cpp +++ b/src/server/game/Accounts/AccountMgr.cpp @@ -17,6 +17,7 @@ */ #include "AccountMgr.h" +#include "Config.h" #include "DatabaseEnv.h" #include "ObjectAccessor.h" #include "Player.h" @@ -26,6 +27,7 @@ AccountMgr::AccountMgr() { + } AccountOpResult AccountMgr::CreateAccount(std::string username, std::string password) @@ -44,12 +46,22 @@ AccountOpResult AccountMgr::CreateAccount(std::string username, std::string pass stmt->setString(0, username); stmt->setString(1, CalculateShaPassHash(username, password)); - LoginDatabase.Execute(stmt); + LoginDatabase.DirectExecute(stmt); // Enforce saving, otherwise AddGroup can fail stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_REALM_CHARACTERS_INIT); LoginDatabase.Execute(stmt); + // Add default rbac groups for that security level + RBACData* rbac = new RBACData(GetId(username), username, -1); + // No need to Load From DB, as it's new data + + RBACGroupContainer const& groupsToAdd = _defaultGroups[0]; // 0: Default sec level + for (RBACGroupContainer::const_iterator it = groupsToAdd.begin(); it != groupsToAdd.end(); ++it) + rbac->AddGroup(*it, -1); + + delete rbac; + return AOR_OK; // everything's fine } @@ -303,3 +315,206 @@ bool AccountMgr::IsConsoleAccount(uint32 gmlevel) { return gmlevel == SEC_CONSOLE; } + +void AccountMgr::LoadRBAC() +{ + uint32 oldMSTime = getMSTime(); + uint32 count1 = 0; + uint32 count2 = 0; + uint32 count3 = 0; + + QueryResult result = LoginDatabase.Query("SELECT id, name FROM rbac_permissions"); + if (!result) + { + sLog->outInfo(LOG_FILTER_SQL, ">> Loaded 0 account permission definitions. DB table `rbac_permissions` is empty."); + return; + } + + do + { + Field* field = result->Fetch(); + uint32 id = field[0].GetUInt32(); + _permissions[id] = new RBACPermission(id, field[1].GetString()); + ++count1; + } + while (result->NextRow()); + + result = LoginDatabase.Query("SELECT id, name FROM rbac_roles"); + if (!result) + { + sLog->outInfo(LOG_FILTER_SQL, ">> Loaded 0 account role definitions. DB table `rbac_roles` is empty."); + return; + } + + do + { + Field* field = result->Fetch(); + uint32 id = field[0].GetUInt32(); + _roles[id] = new RBACRole(id, field[1].GetString()); + ++count2; + } + while (result->NextRow()); + + result = LoginDatabase.Query("SELECT roleId, permissionId FROM rbac_role_permissions"); + if (!result) + { + sLog->outInfo(LOG_FILTER_SQL, ">> Loaded 0 account role-permission definitions. DB table `rbac_role_permissions` is empty."); + return; + } + + do + { + Field* field = result->Fetch(); + uint32 id = field[0].GetUInt32(); + RBACRole* role = _roles[id]; + role->GrantPermission(field[1].GetUInt32()); + } + while (result->NextRow()); + + result = LoginDatabase.Query("SELECT id, name FROM rbac_groups"); + if (!result) + { + sLog->outInfo(LOG_FILTER_SQL, ">> Loaded 0 account group definitions. DB table `rbac_groups` is empty."); + return; + } + + do + { + Field* field = result->Fetch(); + uint32 id = field[0].GetUInt32(); + _groups[id] = new RBACGroup(id, field[1].GetString()); + ++count3; + } + while (result->NextRow()); + + result = LoginDatabase.Query("SELECT groupId, roleId FROM rbac_group_roles"); + if (!result) + { + sLog->outInfo(LOG_FILTER_SQL, ">> Loaded 0 account group-role definitions. DB table `rbac_group_roles` is empty."); + return; + } + + do + { + Field* field = result->Fetch(); + uint32 id = field[0].GetUInt32(); + RBACGroup* group = _groups[id]; + group->GrantRole(field[1].GetUInt32()); + } + while (result->NextRow()); + + result = LoginDatabase.Query("SELECT secId, groupId FROM rbac_security_level_groups ORDER by secId ASC"); + if (!result) + { + sLog->outInfo(LOG_FILTER_SQL, ">> Loaded 0 account default groups for security levels definitions. DB table `rbac_security_level_groups` is empty."); + return; + } + + uint8 lastSecId = 255; + RBACGroupContainer* groups = NULL; + do + { + Field* field = result->Fetch(); + uint8 secId = field[0].GetUInt8(); + + if (lastSecId != secId) + groups = &_defaultGroups[secId]; + + groups->insert(field[1].GetUInt32()); + } + while (result->NextRow()); + + sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u permission definitions, %u role definitions and %u group definitions in %u ms", count1, count2, count3, GetMSTimeDiffToNow(oldMSTime)); +} + +void AccountMgr::UpdateAccountAccess(RBACData* rbac, uint32 accountId, uint8 securityLevel, int32 realmId) +{ + int32 serverRealmId = realmId != -1 ? realmId : ConfigMgr::GetIntDefault("RealmID", 0); + bool needDelete = false; + if (!rbac) + { + needDelete = true; + rbac = new RBACData(accountId, "", serverRealmId); + rbac->LoadFromDB(); + } + + // Get max security level and realm (checking current realm and -1) + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_ACCESS_BY_ID); + stmt->setUInt32(0, accountId); + stmt->setInt32(1, serverRealmId); + PreparedQueryResult result = LoginDatabase.Query(stmt); + if (result) + { + do + { + Field* field = result->Fetch(); + uint8 secLevel = field[0].GetUInt8(); + int32 realmId = field[1].GetUInt32(); + + RBACGroupContainer const& groupsToRemove = _defaultGroups[secLevel]; + for (RBACGroupContainer::const_iterator it = groupsToRemove.begin(); it != groupsToRemove.end(); ++it) + rbac->RemoveGroup(*it, realmId); + } + while (result->NextRow()); + } + + // Add new groups depending on the new security Level + RBACGroupContainer const& groupsToAdd = _defaultGroups[securityLevel]; + for (RBACGroupContainer::const_iterator it = groupsToAdd.begin(); it != groupsToAdd.end(); ++it) + rbac->AddGroup(*it, realmId); + + if (needDelete) + delete rbac; + + // Delete old security level from DB + if (realmId == -1) + { + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_ACCOUNT_ACCESS); + stmt->setUInt32(0, accountId); + LoginDatabase.Execute(stmt); + } + else + { + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_ACCOUNT_ACCESS_BY_REALM); + stmt->setUInt32(0, accountId); + stmt->setUInt32(1, realmId); + LoginDatabase.Execute(stmt); + } + + // Add new security level + if (securityLevel) + { + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_ACCOUNT_ACCESS); + stmt->setUInt32(0, accountId); + stmt->setUInt8(1, securityLevel); + stmt->setInt32(2, realmId); + LoginDatabase.Execute(stmt); + } +} + +RBACGroup const* AccountMgr::GetRBACGroup(uint32 group) const +{ + RBACGroupsContainer::const_iterator it = _groups.find(group); + if (it != _groups.end()) + return it->second; + + return NULL; +} + +RBACRole const* AccountMgr::GetRBACRole(uint32 role) const +{ + RBACRolesContainer::const_iterator it = _roles.find(role); + if (it != _roles.end()) + return it->second; + + return NULL; +} + +RBACPermission const* AccountMgr::GetRBACPermission(uint32 permission) const +{ + RBACPermissionsContainer::const_iterator it = _permissions.find(permission); + if (it != _permissions.end()) + return it->second; + + return NULL; +} diff --git a/src/server/game/Accounts/AccountMgr.h b/src/server/game/Accounts/AccountMgr.h index c8de5688e73..90c533ca5fa 100644 --- a/src/server/game/Accounts/AccountMgr.h +++ b/src/server/game/Accounts/AccountMgr.h @@ -19,8 +19,7 @@ #ifndef _ACCMGR_H #define _ACCMGR_H -#include "Define.h" -#include +#include "RBAC.h" #include enum AccountOpResult @@ -35,6 +34,11 @@ enum AccountOpResult #define MAX_ACCOUNT_STR 16 +typedef std::map RBACPermissionsContainer; +typedef std::map RBACRolesContainer; +typedef std::map RBACGroupsContainer; +typedef std::map RBACDefaultSecurityGroupContainer; + class AccountMgr { friend class ACE_Singleton; @@ -43,7 +47,7 @@ class AccountMgr AccountMgr(); public: - static AccountOpResult CreateAccount(std::string username, std::string password); + AccountOpResult CreateAccount(std::string username, std::string password); static AccountOpResult DeleteAccount(uint32 accountId); static AccountOpResult ChangeUsername(uint32 accountId, std::string newUsername, std::string newPassword); static AccountOpResult ChangePassword(uint32 accountId, std::string newPassword); @@ -62,6 +66,23 @@ class AccountMgr static bool IsGMAccount(uint32 gmlevel); static bool IsAdminAccount(uint32 gmlevel); static bool IsConsoleAccount(uint32 gmlevel); + + void UpdateAccountAccess(RBACData* rbac, uint32 accountId, uint8 securityLevel, int32 realmId); + + void LoadRBAC(); + RBACGroup const* GetRBACGroup(uint32 group) const; + RBACRole const* GetRBACRole(uint32 role) const; + RBACPermission const* GetRBACPermission(uint32 permission) const; + + RBACGroupsContainer const& GetRBACGroupList() const { return _groups; } + RBACRolesContainer const& GetRBACRoleList() const { return _roles; } + RBACPermissionsContainer const& GetRBACPermissionList() const { return _permissions; } + + private: + RBACPermissionsContainer _permissions; + RBACRolesContainer _roles; + RBACGroupsContainer _groups; + RBACDefaultSecurityGroupContainer _defaultGroups; }; #define sAccountMgr ACE_Singleton::instance() diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp index 0bf7c8591e3..b8f80fb36ac 100644 --- a/src/server/game/Chat/Chat.cpp +++ b/src/server/game/Chat/Chat.cpp @@ -122,8 +122,27 @@ const char *ChatHandler::GetTrinityString(int32 entry) const bool ChatHandler::isAvailable(ChatCommand const& cmd) const { - // check security level only for simple command (without child commands) - return m_session->GetSecurity() >= AccountTypes(cmd.SecurityLevel); + uint32 permission = 0; + + ///@Workaround:: Fast adaptation to RBAC system till all commands are moved to permissions + switch (AccountTypes(cmd.SecurityLevel)) + { + case SEC_ADMINISTRATOR: + permission = RBAC_PERM_ADMINISTRATOR_COMMANDS; + break; + case SEC_GAMEMASTER: + permission = RBAC_PERM_GAMEMASTER_COMMANDS; + break; + case SEC_MODERATOR: + permission = RBAC_PERM_MODERATOR_COMMANDS; + break; + case SEC_PLAYER: + default: + permission = RBAC_PERM_PLAYER_COMMANDS; + break; + } + + return m_session->HasPermission(permission); } bool ChatHandler::HasLowerSecurity(Player* target, uint64 guid, bool strong) @@ -431,7 +450,7 @@ bool ChatHandler::ParseCommands(char const* text) std::string fullcmd = text; - if (m_session && AccountMgr::IsPlayerAccount(m_session->GetSecurity()) && !sWorld->getBoolConfig(CONFIG_ALLOW_PLAYER_COMMANDS)) + if (m_session && !m_session->HasPermission(RBAC_PERM_PLAYER_COMMANDS)) return false; /// chat case (.command or !command format) diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index d9d4a897eed..e18a103e21c 100644 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -379,6 +379,7 @@ void LFGMgr::InitializeLockedDungeons(Player* player, uint8 level /* = 0 */) uint8 expansion = player->GetSession()->Expansion(); LfgDungeonSet const& dungeons = GetDungeonsByRandom(0); LfgLockMap lock; + bool denyJoin = !player->GetSession()->HasPermission(RBAC_PERM_JOIN_DUNGEON_FINDER); for (LfgDungeonSet::const_iterator it = dungeons.begin(); it != dungeons.end(); ++it) { @@ -387,7 +388,9 @@ void LFGMgr::InitializeLockedDungeons(Player* player, uint8 level /* = 0 */) continue; uint32 lockData = 0; - if (dungeon->expansion > expansion) + if (denyJoin) + lockData = LFG_LOCKSTATUS_RAID_LOCKED; + else if (dungeon->expansion > expansion) lockData = LFG_LOCKSTATUS_INSUFFICIENT_EXPANSION; else if (DisableMgr::IsDisabledFor(DISABLE_TYPE_MAP, dungeon->map, player)) lockData = LFG_LOCKSTATUS_RAID_LOCKED; @@ -469,7 +472,9 @@ void LFGMgr::JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons, const } // Check player or group member restrictions - if (player->InBattleground() || player->InArena() || player->InBattlegroundQueue()) + if (!player->GetSession()->HasPermission(RBAC_PERM_JOIN_DUNGEON_FINDER)) + joinData.result = LFG_JOIN_NOT_MEET_REQS; + else if (player->InBattleground() || player->InArena() || player->InBattlegroundQueue()) joinData.result = LFG_JOIN_USING_BG_SYSTEM; else if (player->HasAura(LFG_SPELL_DUNGEON_DESERTER)) joinData.result = LFG_JOIN_DESERTER; @@ -488,6 +493,8 @@ void LFGMgr::JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons, const { if (Player* plrg = itr->getSource()) { + if (!plrg->GetSession()->HasPermission(RBAC_PERM_JOIN_DUNGEON_FINDER)) + joinData.result = LFG_JOIN_PARTY_NOT_MEET_REQS; if (plrg->HasAura(LFG_SPELL_DUNGEON_DESERTER)) joinData.result = LFG_JOIN_PARTY_DESERTER; else if (plrg->HasAura(LFG_SPELL_DUNGEON_COOLDOWN)) diff --git a/src/server/game/DungeonFinding/LFGMgr.h b/src/server/game/DungeonFinding/LFGMgr.h index da7980647bb..07c4281f86f 100644 --- a/src/server/game/DungeonFinding/LFGMgr.h +++ b/src/server/game/DungeonFinding/LFGMgr.h @@ -343,7 +343,7 @@ class LFGMgr uint32 GetOptions(); // cs_lfg /// Sets new lfg options void SetOptions(uint32 options); - /// Checks if given lfg option is enabled + /// Checks if given lfg option is enabled bool isOptionEnabled(uint32 option); /// Clears queue - Only for internal testing void Clean(); diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index a4356f55340..dc98facc5ab 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -21757,12 +21757,21 @@ void Player::LeaveBattleground(bool teleportToEntryPoint) } } -bool Player::CanJoinToBattleground(Battleground const* /*bg*/) const +bool Player::CanJoinToBattleground(Battleground const* bg) const { // check Deserter debuff if (HasAura(26013)) return false; + if (bg->isArena() && !GetSession()->HasPermission(RBAC_PERM_JOIN_ARENAS)) + return false; + + if (bg->IsRandom() && !GetSession()->HasPermission(RBAC_PERM_JOIN_RANDOM_BG)) + return false; + + if (!GetSession()->HasPermission(RBAC_PERM_JOIN_NORMAL_BG)) + return false; + return true; } diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index aa4c9f35085..6272f42ec8c 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -396,7 +396,7 @@ void WorldSession::HandleLogoutRequestOpcode(WorldPacket& /*recvData*/) //instant logout in taverns/cities or on taxi or for admins, gm's, mod's if its enabled in worldserver.conf if (GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING) || GetPlayer()->isInFlight() || - GetSecurity() >= AccountTypes(sWorld->getIntConfig(CONFIG_INSTANT_LOGOUT))) + HasPermission(RBAC_PERM_INSTANT_LOGOUT)) { WorldPacket data(SMSG_LOGOUT_RESPONSE, 1+4); data << uint8(0); diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h index e13cc86747c..5868b60b722 100644 --- a/src/server/game/Miscellaneous/Language.h +++ b/src/server/game/Miscellaneous/Language.h @@ -86,7 +86,40 @@ enum TrinityStrings LANG_CONNECTED_PLAYERS = 60, LANG_ACCOUNT_ADDON = 61, LANG_IMPROPER_VALUE = 62, - // Room for more level 0 63-99 not used + LANG_RBAC_WRONG_PARAMETER_ID = 63, + LANG_RBAC_WRONG_PARAMETER_REALM = 64, + LANG_RBAC_GROUP_IN_LIST = 65, + LANG_RBAC_GROUP_NOT_IN_LIST = 66, + LANG_RBAC_GROUP_ADDED = 67, + LANG_RBAC_GROUP_REMOVED = 68, + LANG_RBAC_GROUP_LIST_HEADER = 69, + LANG_RBAC_LIST_EMPTY = 70, + LANG_RBAC_LIST_ELEMENT = 71, + LANG_RBAC_ROLE_GRANTED_IN_LIST = 72, + LANG_RBAC_ROLE_GRANTED_IN_DENIED_LIST = 73, + LANG_RBAC_ROLE_GRANTED = 74, + LANG_RBAC_ROLE_DENIED_IN_LIST = 75, + LANG_RBAC_ROLE_DENIED_IN_GRANTED_LIST = 76, + LANG_RBAC_ROLE_DENIED = 77, + LANG_RBAC_ROLE_REVOKED = 78, + LANG_RBAC_ROLE_REVOKED_NOT_IN_LIST = 79, + LANG_RBAC_ROLE_LIST_HEADER_GRANTED = 80, + LANG_RBAC_ROLE_LIST_HEADER_DENIED = 81, + LANG_RBAC_PERM_GRANTED_IN_LIST = 82, + LANG_RBAC_PERM_GRANTED_IN_DENIED_LIST = 83, + LANG_RBAC_PERM_GRANTED = 84, + LANG_RBAC_PERM_DENIED_IN_LIST = 85, + LANG_RBAC_PERM_DENIED_IN_GRANTED_LIST = 86, + LANG_RBAC_PERM_DENIED = 87, + LANG_RBAC_PERM_REVOKED = 88, + LANG_RBAC_PERM_REVOKED_NOT_IN_LIST = 89, + LANG_RBAC_PERM_LIST_HEADER_GRANTED = 90, + LANG_RBAC_PERM_LIST_HEADER_DENIED = 91, + LANG_RBAC_PERM_LIST_GLOBAL = 92, + LANG_RBAC_LIST_GROUPS_HEADER = 93, + LANG_RBAC_LIST_ROLES_HEADER = 94, + LANG_RBAC_LIST_PERMISSIONS_HEADER = 95, + // Room for more level 0 96-99 not used // level 1 chat LANG_GLOBAL_NOTIFY = 100, diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp index efd45188d42..afc153a5000 100644 --- a/src/server/game/Scripting/ScriptLoader.cpp +++ b/src/server/game/Scripting/ScriptLoader.cpp @@ -70,6 +70,7 @@ void AddSC_mmaps_commandscript(); void AddSC_modify_commandscript(); void AddSC_npc_commandscript(); void AddSC_quest_commandscript(); +void AddSC_rbac_commandscript(); void AddSC_reload_commandscript(); void AddSC_reset_commandscript(); void AddSC_server_commandscript(); @@ -700,6 +701,7 @@ void AddCommandScripts() AddSC_modify_commandscript(); AddSC_npc_commandscript(); AddSC_quest_commandscript(); + AddSC_rbac_commandscript(); AddSC_reload_commandscript(); AddSC_reset_commandscript(); AddSC_server_commandscript(); diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 6c689319bc7..522dc95105d 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -21,6 +21,7 @@ */ #include "WorldSocket.h" // must be first to make ACE happy with ACE includes in it +#include "Config.h" #include "Common.h" #include "DatabaseEnv.h" #include "Log.h" @@ -115,7 +116,8 @@ WorldSession::WorldSession(uint32 id, WorldSocket* sock, AccountTypes sec, uint8 m_TutorialsChanged(false), recruiterId(recruiter), isRecruiter(isARecruiter), - timeLastWhoCommand(0) + timeLastWhoCommand(0), + _RBACData(NULL) { if (sock) { @@ -143,8 +145,8 @@ WorldSession::~WorldSession() m_Socket = NULL; } - if (_warden) - delete _warden; + delete _warden; + delete _RBACData; ///- empty incoming packet queue WorldPacket* packet = NULL; @@ -1200,3 +1202,24 @@ void WorldSession::InitWarden(BigNumber* k, std::string const& os) // _warden->Init(this, k); } } + +void WorldSession::LoadPermissions() +{ + uint32 id = GetAccountId(); + std::string name; + int32 realmId = ConfigMgr::GetIntDefault("RealmID", 0); + AccountMgr::GetName(id, name); + + _RBACData = new RBACData(id, name, realmId); + _RBACData->LoadFromDB(); +} + +RBACData* WorldSession::GetRBACData() +{ + return _RBACData; +} + +bool WorldSession::HasPermission(uint32 permission) +{ + return _RBACData->HasPermission(permission); +} diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 11bb7a36f5a..d6877b8a18a 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -24,6 +24,7 @@ #define __WORLDSESSION_H #include "Common.h" +#include "AccountMgr.h" #include "SharedDefines.h" #include "AddonMgr.h" #include "DatabaseEnv.h" @@ -216,6 +217,10 @@ class WorldSession void SendAuthResponse(uint8 code, bool shortForm, uint32 queuePos = 0); void SendClientCacheVersion(uint32 version); + RBACData* GetRBACData(); + bool HasPermission(uint32 permissionId); + void LoadPermissions(); + AccountTypes GetSecurity() const { return _security; } uint32 GetAccountId() const { return _accountId; } Player* GetPlayer() const { return _player; } @@ -954,6 +959,7 @@ class WorldSession bool isRecruiter; ACE_Based::LockedQueue _recvQueue; time_t timeLastWhoCommand; + RBACData* _RBACData; }; #endif /// @} diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp index c80d25be139..c77cad70186 100644 --- a/src/server/game/Server/WorldSocket.cpp +++ b/src/server/game/Server/WorldSocket.cpp @@ -953,6 +953,7 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket) m_Session->LoadGlobalAccountData(); m_Session->LoadTutorialsData(); m_Session->ReadAddonsInfo(recvPacket); + m_Session->LoadPermissions(); // Initialize Warden system only if it is enabled by config if (sWorld->getBoolConfig(CONFIG_WARDEN_ENABLED)) diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index f28b9548e5f..d02ba402c53 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -267,7 +267,7 @@ void World::AddSession_(WorldSession* s) if (decrease_session) --Sessions; - if (pLimit > 0 && Sessions >= pLimit && AccountMgr::IsPlayerAccount(s->GetSecurity()) && !HasRecentlyDisconnected(s)) + if (pLimit > 0 && Sessions >= pLimit && !s->HasPermission(RBAC_PERM_SKIP_QUEUE) && !HasRecentlyDisconnected(s)) { AddQueuedPlayer(s); UpdateMaxSessionCounters(); @@ -585,7 +585,6 @@ void World::LoadConfigSettings(bool reload) m_int_configs[CONFIG_TICKET_LEVEL_REQ] = ConfigMgr::GetIntDefault("LevelReq.Ticket", 1); m_int_configs[CONFIG_AUCTION_LEVEL_REQ] = ConfigMgr::GetIntDefault("LevelReq.Auction", 1); m_int_configs[CONFIG_MAIL_LEVEL_REQ] = ConfigMgr::GetIntDefault("LevelReq.Mail", 1); - m_bool_configs[CONFIG_ALLOW_PLAYER_COMMANDS] = ConfigMgr::GetBoolDefault("AllowPlayerCommands", 1); m_bool_configs[CONFIG_PRESERVE_CUSTOM_CHANNELS] = ConfigMgr::GetBoolDefault("PreserveCustomChannels", false); m_int_configs[CONFIG_PRESERVE_CUSTOM_CHANNEL_DURATION] = ConfigMgr::GetIntDefault("PreserveCustomChannelDuration", 14); m_bool_configs[CONFIG_GRID_UNLOAD] = ConfigMgr::GetBoolDefault("GridUnload", true); @@ -1059,8 +1058,6 @@ void World::LoadConfigSettings(bool reload) sLog->outError(LOG_FILTER_SERVER_LOADING, "ClientCacheVersion can't be negative %d, ignored.", clientCacheId); } - m_int_configs[CONFIG_INSTANT_LOGOUT] = ConfigMgr::GetIntDefault("InstantLogout", SEC_MODERATOR); - m_int_configs[CONFIG_GUILD_EVENT_LOG_COUNT] = ConfigMgr::GetIntDefault("Guild.EventLogRecordsCount", GUILD_EVENTLOG_MAX_RECORDS); if (m_int_configs[CONFIG_GUILD_EVENT_LOG_COUNT] > GUILD_EVENTLOG_MAX_RECORDS) m_int_configs[CONFIG_GUILD_EVENT_LOG_COUNT] = GUILD_EVENTLOG_MAX_RECORDS; @@ -1348,6 +1345,8 @@ void World::SetInitialWorldSettings() sObjectMgr->SetDBCLocaleIndex(GetDefaultDbcLocale()); // Get once for all the locale index of DBC language (console/broadcasts) sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Localization strings loaded in %u ms", GetMSTimeDiffToNow(oldMSTime)); + sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading Account Roles and Permissions..."); + sAccountMgr->LoadRBAC(); sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading Page Texts..."); sObjectMgr->LoadPageTexts(); diff --git a/src/server/scripts/Commands/CMakeLists.txt b/src/server/scripts/Commands/CMakeLists.txt index 7b9e2444952..83e97b2c80d 100644 --- a/src/server/scripts/Commands/CMakeLists.txt +++ b/src/server/scripts/Commands/CMakeLists.txt @@ -35,6 +35,7 @@ set(scripts_STAT_SRCS Commands/cs_modify.cpp Commands/cs_npc.cpp Commands/cs_quest.cpp + Commands/cs_rbac.cpp Commands/cs_reload.cpp Commands/cs_reset.cpp Commands/cs_tele.cpp diff --git a/src/server/scripts/Commands/cs_account.cpp b/src/server/scripts/Commands/cs_account.cpp index 3a20a03bb4a..4dc44bbfc58 100644 --- a/src/server/scripts/Commands/cs_account.cpp +++ b/src/server/scripts/Commands/cs_account.cpp @@ -106,7 +106,7 @@ public: if (!accountName || !password) return false; - AccountOpResult result = AccountMgr::CreateAccount(std::string(accountName), std::string(password)); + AccountOpResult result = sAccountMgr->CreateAccount(std::string(accountName), std::string(password)); switch (result) { case AOR_OK: @@ -503,36 +503,8 @@ public: return false; } - // If gmRealmID is -1, delete all values for the account id, else, insert values for the specific realmID - PreparedStatement* stmt; - - if (gmRealmID == -1) - { - stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_ACCOUNT_ACCESS); - - stmt->setUInt32(0, targetAccountId); - } - else - { - stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_ACCOUNT_ACCESS_BY_REALM); - - stmt->setUInt32(0, targetAccountId); - stmt->setUInt32(1, realmID); - } - - LoginDatabase.Execute(stmt); - - if (gm != 0) - { - stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_ACCOUNT_ACCESS); - - stmt->setUInt32(0, targetAccountId); - stmt->setUInt8(1, uint8(gm)); - stmt->setInt32(2, gmRealmID); - - LoginDatabase.Execute(stmt); - } - + RBACData* rbac = isAccountNameGiven ? NULL : handler->getSelectedPlayer()->GetSession()->GetRBACData(); + sAccountMgr->UpdateAccountAccess(rbac, targetAccountId, uint8(gm), gmRealmID); handler->PSendSysMessage(LANG_YOU_CHANGE_SECURITY, targetAccountName.c_str(), gm); return true; diff --git a/src/server/shared/Database/Implementation/LoginDatabase.cpp b/src/server/shared/Database/Implementation/LoginDatabase.cpp index 227680b2d6b..210e2b3ac60 100644 --- a/src/server/shared/Database/Implementation/LoginDatabase.cpp +++ b/src/server/shared/Database/Implementation/LoginDatabase.cpp @@ -55,7 +55,7 @@ void LoginDatabaseConnection::DoPrepareStatements() PrepareStatement(LOGIN_DEL_REALM_CHARACTERS, "DELETE FROM realmcharacters WHERE acctid = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_INS_REALM_CHARACTERS, "INSERT INTO realmcharacters (numchars, acctid, realmid) VALUES (?, ?, ?)", CONNECTION_ASYNC); PrepareStatement(LOGIN_SEL_SUM_REALM_CHARACTERS, "SELECT SUM(numchars) FROM realmcharacters WHERE acctid = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_INS_ACCOUNT, "INSERT INTO account(username, sha_pass_hash, joindate) VALUES(?, ?, NOW())", CONNECTION_ASYNC); + PrepareStatement(LOGIN_INS_ACCOUNT, "INSERT INTO account(username, sha_pass_hash, joindate) VALUES(?, ?, NOW())", CONNECTION_SYNCH); PrepareStatement(LOGIN_INS_REALM_CHARACTERS_INIT, "INSERT INTO realmcharacters (realmid, acctid, numchars) SELECT realmlist.id, account.id, 0 FROM realmlist, account LEFT JOIN realmcharacters ON acctid=account.id WHERE acctid IS NULL", CONNECTION_ASYNC); PrepareStatement(LOGIN_UPD_EXPANSION, "UPDATE account SET expansion = ? WHERE id = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_UPD_ACCOUNT_LOCK, "UPDATE account SET locked = ? WHERE id = ?", CONNECTION_ASYNC); @@ -87,4 +87,18 @@ void LoginDatabaseConnection::DoPrepareStatements() PrepareStatement(LOGIN_SEL_ACCOUNT_WHOIS, "SELECT username, email, last_ip FROM account WHERE id = ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_REALMLIST_SECURITY_LEVEL, "SELECT allowedSecurityLevel from realmlist WHERE id = ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_DEL_ACCOUNT, "DELETE FROM account WHERE id = ?", CONNECTION_ASYNC); + + PrepareStatement(LOGIN_SEL_ACCOUNT_ACCESS_BY_ID, "SELECT gmlevel, RealmID FROM account_access WHERE id = ? and (RealmID = ? OR RealmID = -1) ORDER BY gmlevel desc", CONNECTION_SYNCH); + + PrepareStatement(LOGIN_SEL_RBAC_ACCOUNT_GROUPS, "SELECT groupId FROM rbac_account_groups WHERE accountId = ? AND (realmId = ? OR realmId = -1) GROUP BY groupId", CONNECTION_SYNCH); + PrepareStatement(LOGIN_INS_RBAC_ACCOUNT_GROUP, "INSERT INTO rbac_account_groups (accountId, groupId, realmId) VALUES (?, ?, ?)", CONNECTION_ASYNC); + PrepareStatement(LOGIN_DEL_RBAC_ACCOUNT_GROUP, "DELETE FROM rbac_account_groups WHERE accountId = ? AND groupId = ? AND (realmId = ? OR realmId = -1)", CONNECTION_ASYNC); + + PrepareStatement(LOGIN_SEL_RBAC_ACCOUNT_ROLES, "SELECT roleId, granted FROM rbac_account_roles WHERE accountId = ? AND (realmId = ? OR realmId = -1) ORDER BY roleId, realmId", CONNECTION_SYNCH); + PrepareStatement(LOGIN_INS_RBAC_ACCOUNT_ROLE, "INSERT INTO rbac_account_roles (accountId, roleId, granted, realmId) VALUES (?, ?, ?, ?) ON DUPLICATE KEY UPDATE granted = VALUES(granted)", CONNECTION_ASYNC); + PrepareStatement(LOGIN_DEL_RBAC_ACCOUNT_ROLE, "DELETE FROM rbac_account_roles WHERE accountId = ? AND roleId = ? AND (realmId = ? OR realmId = -1)", CONNECTION_ASYNC); + + PrepareStatement(LOGIN_SEL_RBAC_ACCOUNT_PERMISSIONS, "SELECT permissionId, granted FROM rbac_account_permissions WHERE accountId = ? AND (realmId = ? OR realmId = -1) ORDER BY permissionId, realmId", CONNECTION_SYNCH); + PrepareStatement(LOGIN_INS_RBAC_ACCOUNT_PERMISSION, "INSERT INTO rbac_account_permissions (accountId, permissionId, granted, realmId) VALUES (?, ?, ?, ?) ON DUPLICATE KEY UPDATE granted = VALUES(granted)", CONNECTION_ASYNC); + PrepareStatement(LOGIN_DEL_RBAC_ACCOUNT_PERMISSION, "DELETE FROM rbac_account_permissions WHERE accountId = ? AND permissionId = ? AND (realmId = ? OR realmId = -1)", CONNECTION_ASYNC); } diff --git a/src/server/shared/Database/Implementation/LoginDatabase.h b/src/server/shared/Database/Implementation/LoginDatabase.h index 798016d553d..211706b26b8 100644 --- a/src/server/shared/Database/Implementation/LoginDatabase.h +++ b/src/server/shared/Database/Implementation/LoginDatabase.h @@ -108,6 +108,16 @@ enum LoginDatabaseStatements LOGIN_SEL_REALMLIST_SECURITY_LEVEL, LOGIN_DEL_ACCOUNT, + LOGIN_SEL_ACCOUNT_ACCESS_BY_ID, + LOGIN_SEL_RBAC_ACCOUNT_GROUPS, + LOGIN_INS_RBAC_ACCOUNT_GROUP, + LOGIN_DEL_RBAC_ACCOUNT_GROUP, + LOGIN_SEL_RBAC_ACCOUNT_ROLES, + LOGIN_INS_RBAC_ACCOUNT_ROLE, + LOGIN_DEL_RBAC_ACCOUNT_ROLE, + LOGIN_SEL_RBAC_ACCOUNT_PERMISSIONS, + LOGIN_INS_RBAC_ACCOUNT_PERMISSION, + LOGIN_DEL_RBAC_ACCOUNT_PERMISSION, MAX_LOGINDATABASE_STATEMENTS }; diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index 641fe1ebb62..f6a09667dda 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -813,18 +813,6 @@ RecruitAFriend.MaxLevel = 60 RecruitAFriend.MaxDifference = 4 -# -# InstantLogout -# Description: Required security level for instantly logging out everywhere. -# Does not work while in combat, dueling or falling. -# Default: 1 - (Enabled, Mods/GMs/Admins) -# 0 - (Enabled, Everyone) -# 2 - (Enabled, GMs/Admins) -# 3 - (Enabled, Admins) -# 4 - (Disabled) - -InstantLogout = 1 - # # DisableWaterBreath # Description: Required security level for water breathing. @@ -1567,14 +1555,6 @@ ChatLevelReq.Whisper = 1 ChatLevelReq.Say = 1 -# -# AllowPlayerCommands -# Description: Allow players to use commands. -# Default: 1 - (Enabled) -# 0 - (Disabled) - -AllowPlayerCommands = 1 - # # PreserveCustomChannels # Description: Store custom chat channel settings like password, automatic ownership handout -- cgit v1.2.3 From 683de1d62484d1c9c5396a7c41507f03116509aa Mon Sep 17 00:00:00 2001 From: Spp Date: Mon, 4 Feb 2013 09:39:01 +0100 Subject: Core/RBAC: Add SQL to remove bad data from account_access, otherwise other sqls will fail due to use of FOREIGN KEYS - Also add missing files from previous commit --- sql/updates/auth/2013_02_04_00_auth_misc.sql | 5 +- src/server/game/Accounts/RBAC.cpp | 334 ++++++++++++ src/server/game/Accounts/RBAC.h | 410 ++++++++++++++ src/server/scripts/Commands/cs_rbac.cpp | 780 +++++++++++++++++++++++++++ 4 files changed, 1528 insertions(+), 1 deletion(-) create mode 100644 src/server/game/Accounts/RBAC.cpp create mode 100644 src/server/game/Accounts/RBAC.h create mode 100644 src/server/scripts/Commands/cs_rbac.cpp (limited to 'src/server/scripts') diff --git a/sql/updates/auth/2013_02_04_00_auth_misc.sql b/sql/updates/auth/2013_02_04_00_auth_misc.sql index 573b58ac156..815df637be0 100644 --- a/sql/updates/auth/2013_02_04_00_auth_misc.sql +++ b/sql/updates/auth/2013_02_04_00_auth_misc.sql @@ -1,13 +1,16 @@ +-- Delete bad data from the DB before adding foreign keys +DELETE FROM `account_access` WHERE `id` NOT IN (SELECT `id` FROM `account`); + -- Need them first in case of re-execute due to foreign keys DROP TABLE IF EXISTS `rbac_account_permissions`; DROP TABLE IF EXISTS `rbac_account_roles`; DROP TABLE IF EXISTS `rbac_account_groups`; DROP TABLE IF EXISTS `rbac_role_permissions`; DROP TABLE IF EXISTS `rbac_group_roles`; +DROP TABLE IF EXISTS `rbac_security_level_groups`; DROP TABLE IF EXISTS `rbac_permissions`; DROP TABLE IF EXISTS `rbac_roles`; DROP TABLE IF EXISTS `rbac_groups`; -DROP TABLE IF EXISTS `rbac_security_level_groups`; CREATE TABLE IF NOT EXISTS `rbac_groups` ( `id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Group id', diff --git a/src/server/game/Accounts/RBAC.cpp b/src/server/game/Accounts/RBAC.cpp new file mode 100644 index 00000000000..0b08e277fb2 --- /dev/null +++ b/src/server/game/Accounts/RBAC.cpp @@ -0,0 +1,334 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "RBAC.h" + +RBACCommandResult RBACData::AddGroup(uint32 groupId, int32 realmId /* = 0 */) +{ + // Check if group Id exists + RBACGroup const* group = sAccountMgr->GetRBACGroup(groupId); + if (!group) + return RBAC_ID_DOES_NOT_EXISTS; + + // Already added? + std::pair::iterator, bool> ret = _groups.insert(groupId); + if (!ret.second) + return RBAC_CANT_ADD_ALREADY_ADDED; + + // Do not save to db when loading data from DB (realmId = 0) + if (realmId) + { + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_RBAC_ACCOUNT_GROUP); + stmt->setUInt32(0, GetId()); + stmt->setUInt32(1, groupId); + stmt->setInt32(2, realmId); + LoginDatabase.Execute(stmt); + + CalculateNewPermissions(); + } + + return RBAC_OK; +} + +RBACCommandResult RBACData::RemoveGroup(uint32 groupId, int32 realmId /* = 0 */) +{ + // could remove it? + if (!_groups.erase(groupId)) + return RBAC_CANT_REVOKE_NOT_IN_LIST; + + // Do not save to db when loading data from DB (realmId = 0) + if (realmId) + { + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_RBAC_ACCOUNT_GROUP); + stmt->setUInt32(0, GetId()); + stmt->setUInt32(1, groupId); + stmt->setInt32(2, realmId); + LoginDatabase.Execute(stmt); + + CalculateNewPermissions(); + } + + return RBAC_OK; +} + +RBACCommandResult RBACData::GrantRole(uint32 roleId, int32 realmId /* = 0*/) +{ + // Check if role Id exists + RBACRole const* role = sAccountMgr->GetRBACRole(roleId); + if (!role) + return RBAC_ID_DOES_NOT_EXISTS; + + // Check if already added in denied list + if (_deniedRoles.find(roleId) != _deniedRoles.end()) + return RBAC_IN_DENIED_LIST; + + // Already added? + std::pair::iterator, bool> ret = _grantedRoles.insert(roleId); + if (!ret.second) + return RBAC_CANT_ADD_ALREADY_ADDED; + + // Do not save to db when loading data from DB (realmId = 0) + if (realmId) + { + SaveRole(roleId, true, realmId); + CalculateNewPermissions(); + } + + return RBAC_OK; +} + +RBACCommandResult RBACData::DenyRole(uint32 roleId, int32 realmId /* = 0*/) +{ + // Check if role Id exists + RBACRole const* role = sAccountMgr->GetRBACRole(roleId); + if (!role) + return RBAC_ID_DOES_NOT_EXISTS; + + // Check if already added in granted list + if (_grantedRoles.find(roleId) != _grantedRoles.end()) + return RBAC_IN_GRANTED_LIST; + + // Already added? + std::pair::iterator, bool> ret = _deniedRoles.insert(roleId); + if (!ret.second) + return RBAC_CANT_ADD_ALREADY_ADDED; + + // Do not save to db when loading data from DB (realmId = 0) + if (realmId) + { + SaveRole(roleId, false, realmId); + CalculateNewPermissions(); + } + + return RBAC_OK; +} + +void RBACData::SaveRole(uint32 roleId, bool granted, int32 realmId) +{ + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_RBAC_ACCOUNT_ROLE); + stmt->setUInt32(0, GetId()); + stmt->setUInt32(1, roleId); + stmt->setBool(2, granted); + stmt->setInt32(3, realmId); + LoginDatabase.Execute(stmt); +} + +RBACCommandResult RBACData::RevokeRole(uint32 roleId, int32 realmId /* = 0*/) +{ + uint8 revoked = _grantedRoles.erase(roleId) + _deniedRoles.erase(roleId); + + // could remove it? + if (!revoked) + return RBAC_CANT_REVOKE_NOT_IN_LIST; + + // Do not save to db when loading data from DB (realmId = 0) + if (realmId) + { + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_RBAC_ACCOUNT_ROLE); + stmt->setUInt32(0, GetId()); + stmt->setUInt32(1, roleId); + stmt->setInt32(2, realmId); + LoginDatabase.Execute(stmt); + + CalculateNewPermissions(); + } + + return RBAC_OK; +} + +RBACCommandResult RBACData::GrantPermission(uint32 permissionId, int32 realmId /* = 0*/) +{ + // Check if permission Id exists + RBACPermission const* perm = sAccountMgr->GetRBACPermission(permissionId); + if (!perm) + return RBAC_ID_DOES_NOT_EXISTS; + + // Check if already added in denied list + if (_deniedPerms.test(permissionId)) + return RBAC_IN_DENIED_LIST; + + // Already added? + if (_grantedPerms.test(permissionId)) + return RBAC_CANT_ADD_ALREADY_ADDED; + + _grantedPerms.set(permissionId); + + // Do not save to db when loading data from DB (realmId = 0) + if (realmId) + { + SavePermission(permissionId, true, realmId); + CalculateNewPermissions(); + } + + return RBAC_OK; +} + +RBACCommandResult RBACData::DenyPermission(uint32 permissionId, int32 realmId /* = 0*/) +{ + // Check if permission Id exists + RBACPermission const* perm = sAccountMgr->GetRBACPermission(permissionId); + if (!perm) + return RBAC_ID_DOES_NOT_EXISTS; + + // Check if already added in granted list + if (_grantedPerms.test(permissionId)) + return RBAC_IN_GRANTED_LIST; + + // Already added? + if (_deniedPerms.test(permissionId)) + return RBAC_CANT_ADD_ALREADY_ADDED; + + _deniedPerms.set(permissionId); + + // Do not save to db when loading data from DB (realmId = 0) + if (realmId) + { + SavePermission(permissionId, false, realmId); + CalculateNewPermissions(); + } + + return RBAC_OK; +} + +void RBACData::SavePermission(uint32 permission, bool granted, int32 realmId) +{ + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_RBAC_ACCOUNT_PERMISSION); + stmt->setUInt32(0, GetId()); + stmt->setUInt32(1, permission); + stmt->setBool(2, granted); + stmt->setInt32(3, realmId); + LoginDatabase.Execute(stmt); +} + +RBACCommandResult RBACData::RevokePermission(uint32 permission, int32 realmId /* = 0*/) +{ + // Check if it's present in any list + if (!_grantedPerms.test(permission) && !_deniedPerms.test(permission)) + return RBAC_CANT_REVOKE_NOT_IN_LIST; + + _grantedPerms.reset(permission); + _deniedPerms.reset(permission); + + // Do not save to db when loading data from DB (realmId = 0) + if (realmId) + { + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_RBAC_ACCOUNT_PERMISSION); + stmt->setUInt32(0, GetId()); + stmt->setUInt32(1, permission); + stmt->setInt32(2, realmId); + LoginDatabase.Execute(stmt); + + CalculateNewPermissions(); + } + + return RBAC_OK; +} + +void RBACData::LoadFromDB() +{ + // Load account group that affect current realm + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_RBAC_ACCOUNT_GROUPS); + stmt->setUInt32(0, GetId()); + stmt->setInt32(1, GetRealmId()); + PreparedQueryResult result = LoginDatabase.Query(stmt); + + if (result) + { + do + { + Field* fields = result->Fetch(); + AddGroup(fields[0].GetUInt32()); + } + while (result->NextRow()); + } + + // Load account roles (granted and denied) that affect current realm + stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_RBAC_ACCOUNT_ROLES); + stmt->setUInt32(0, GetId()); + stmt->setInt32(1, GetRealmId()); + result = LoginDatabase.Query(stmt); + + if (result) + { + do + { + Field* fields = result->Fetch(); + if (fields[1].GetBool()) + GrantRole(fields[0].GetUInt32()); + else + DenyRole(fields[0].GetUInt32()); + } + while (result->NextRow()); + } + + // Load account permissions (granted and denied) that affect current realm + stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_RBAC_ACCOUNT_PERMISSIONS); + stmt->setUInt32(0, GetId()); + stmt->setInt32(1, GetRealmId()); + + result = LoginDatabase.Query(stmt); + if (result) + { + do + { + Field* fields = result->Fetch(); + if (fields[1].GetBool()) + GrantPermission(fields[0].GetUInt32()); + else + DenyPermission(fields[0].GetUInt32()); + } + while (result->NextRow()); + } + + // Force calculation of permissions, it wasn't performed at load time + // while adding groups, roles and permissions + CalculateNewPermissions(); +} + +void RBACData::CalculateNewPermissions() +{ + // Get the list of directly granted roles + RBACRoleContainer tempGrantedRoles = GetGrantedRoles(); + + // Add those roles inherited from groups + for (RBACGroupContainer::const_iterator itGroup = _groups.begin(); itGroup != _groups.end(); ++itGroup) + { + RBACGroup const* group = sAccountMgr->GetRBACGroup(*itGroup); + if (!group) // Should never happen due to foreign keys in DB + continue; + + RBACRoleContainer const& roles = group->GetRoles(); + for (RBACRoleContainer::const_iterator it = roles.begin(); it != roles.end(); ++it) + tempGrantedRoles.insert(*it); + } + + // Get the list of granted permissions + _globalPerms = GetGrantedPermissions(); + + // Add those permissions inherited from roles granted + for (RBACRoleContainer::const_iterator it = tempGrantedRoles.begin(); it != tempGrantedRoles.end(); ++it) + if (RBACRole const* role = sAccountMgr->GetRBACRole(*it)) + _globalPerms |= role->GetPermissions(); + + // Remove denied permissions from the list + _globalPerms &= ~GetDeniedPermissions(); + + // Remove those permissions inherited from denied roles + for (RBACRoleContainer::const_iterator it = _deniedRoles.begin(); it != _deniedRoles.end(); ++it) + if (RBACRole const* role = sAccountMgr->GetRBACRole(*it)) + _globalPerms &= ~role->GetPermissions(); +} diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h new file mode 100644 index 00000000000..5420df29d17 --- /dev/null +++ b/src/server/game/Accounts/RBAC.h @@ -0,0 +1,410 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +/** +* @file RBAC.h +* @brief Role Based Access Control related classes definition +* +* This file contains all the classes and enums used to implement +* Role Based Access Control +* +* RBAC Rules: +* - Pemission: Defines an autorization to perform certain operation. +* - Role: Set of permissions. +* - Group: Set of roles. +* - An Account can have multiple groups, roles and permissions. +* - Account Groups can only be granted or revoked +* - Account Roles and Permissions can be granted, denied or revoked +* - Grant: Assignment of the object (role/permission) and allow it +* - Deny: Assignment of the object (role/permission) and deny it +* - Revoke: Removal of the object (role/permission) no matter if it was granted or denied +* - Global Permissions are computed as: +* Group Grants + Role Grants + User Grans - Role Grants - User Grants +* - Groups, Roles and Permissions can be assigned by realm +*/ + +#ifndef _RBAC_H +#define _RBAC_H + +#include "Define.h" +#include +#include +#include +#include + +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_MAX +}; + +enum RBACCommandResult +{ + RBAC_OK, + RBAC_CANT_ADD_ALREADY_ADDED, + RBAC_CANT_REVOKE_NOT_IN_LIST, + RBAC_IN_GRANTED_LIST, + RBAC_IN_DENIED_LIST, + RBAC_ID_DOES_NOT_EXISTS +}; + +typedef std::bitset RBACPermissionContainer; +typedef std::set RBACRoleContainer; +typedef std::set RBACGroupContainer; + +class RBACObject +{ + public: + RBACObject(uint32 id = 0, std::string const& name = ""): + _id(id), _name(name) { } + + /// Gets the Name of the Object + std::string const& GetName() const { return _name; } + /// Gets the Id of the Object + uint32 GetId() const { return _id; } + + private: + uint32 _id; ///> id of the object + std::string _name; ///> name of the object +}; + +/// Permission: Defines an autorization to perform certain operation +class RBACPermission: public RBACObject +{ + public: + RBACPermission(uint32 id = 0, std::string const& name = ""): + RBACObject(id, name) { } +}; + +/// Set of Permissions +class RBACRole: public RBACObject +{ + public: + RBACRole(uint32 id = 0, std::string const& name = ""): + RBACObject(id, name) { } + + /// Gets the Permissions assigned to this role + RBACPermissionContainer const& GetPermissions() const { return _perms; } + /// Grants a Permission (Adds) + void GrantPermission(uint32 id) { _perms.set(id); } + /// Revokes a Permission (Removes) + void RevokePermission(uint32 id) { _perms.reset(id); } + + private: + RBACPermissionContainer _perms; ///> Set of permissions +}; + +/// Set of Roles +class RBACGroup: public RBACObject +{ + public: + RBACGroup(uint32 id = 0, std::string const& name = ""): + RBACObject(id, name) { } + + /// Gets the Roles assigned to this group + RBACRoleContainer const& GetRoles() const { return _roles; } + /// Grants a Role (Adds) + void GrantRole(uint32 role) { _roles.insert(role); } + /// Revokes a Role (Removes) + void RevokeRole(uint32 role) { _roles.erase(role); } + + private: + RBACRoleContainer _roles; ///> Set of Roles +}; + +/* + * @name RBACData + * @brief Contains all needed information about the acccount + * + * This class contains all the data needed to calculate the account permissions. + * RBACDAta is formed by group permissions and user permissions through: + * - Granted Groups, which contains roles, which contains permissions: Set of granted permissions + * - Granted Roles, which contains permissions: Set of granted permissions + * - Denied Roles, which contains permissions: Set of denied permissions + * - Granted Permissions + * - Denied Permissions + * + * Calculation of current Permissions: Granted permissions - Denied permissions + * - Granted permissions: through groups, through roles and directly assigned + * - Denied permissions: through roles and directly assigned + */ +class RBACData: public RBACObject +{ + public: + RBACData(uint32 id, std::string const& name, int32 realmId): + RBACObject(id, name), _realmId(realmId) { } + + /** + * @name HasPermission + * @brief Checks if certain action is allowed + * + * Checks if certain action can be performed. + * + * @return grant or deny action + * + * Example Usage: + * @code + * bool Player::CanJoinArena(Battleground* bg) + * { + * return bg->isArena() && HasPermission(RBAC_PERM_JOIN_ARENA); + * } + * @endcode + */ + bool HasPermission(uint32 permission) { return _globalPerms.test(permission); } + + // Functions enabled to be used by command system + /// Returns all the granted permissions (after computation) + RBACPermissionContainer const& GetPermissions() const { return _globalPerms; } + /// Returns all the granted permissions + RBACPermissionContainer const& GetGrantedPermissions() const { return _grantedPerms; } + /// Returns all the denied permissions + RBACPermissionContainer const& GetDeniedPermissions() const { return _deniedPerms; } + /// Returns all the granted roles + RBACRoleContainer const& GetGrantedRoles() const { return _grantedRoles; } + /// Returns all the denied roles + RBACRoleContainer const& GetDeniedRoles() const { return _deniedRoles; } + /// Returns all the granted groups + RBACGroupContainer const& GetGroups() const { return _groups; } + + /** + * @name AddGroup + * @brief Adds new group + * + * Add a new group to the account. If realm is 0 or the group can not be added + * No save to db action will be performed. + * + * Fails if group Id does not exists or group already present + * + * @param groupId group to be added + * @param realmId realm affected + * + * @return Success or failure (with reason) to add the group + * + * Example Usage: + * @code + * // previously defined "RBACData* rbac" with proper initialization + * uint32 groupId = 2; + * if (rbac->AddGroup(groupId) == RBAC_OK) + * sLog->outDebug(LOG_FILTER_PLAYER, "Group %u succesfully added", groupId); + * @endcode + */ + RBACCommandResult AddGroup(uint32 groupId, int32 realmId = 0); + + /** + * @name RemoveGroup + * @brief Removes a group + * + * Removes a group from the account. If realm is 0 or the group can not be removed + * No save to db action will be performed. Any delete operation will always affect + * "all realms (-1)" in addition to the realm specified + * + * Fails if group not present + * + * @param groupId group to be removed + * @param realmId realm affected + * + * @return Success or failure (with reason) to remove the group + * + * Example Usage: + * // previously defined "RBACData* rbac" with proper initialization + * uint32 groupId = 2; + * if (rbac->RemoveGroup(groupId) == RBAC_OK) + * sLog->outDebug(LOG_FILTER_PLAYER, "Group %u succesfully removed", groupId); + * @endcode + */ + RBACCommandResult RemoveGroup(uint32 groupId, int32 realmId = 0); + + /** + * @name GrantRole + * @brief Grants a role + * + * Grants a role to the account. If realm is 0 or the role can not be added + * No save to db action will be performed. + * + * Fails if role Id does not exists or role already granted or denied + * + * @param roleId role to be granted + * @param realmId realm affected + * + * @return Success or failure (with reason) to grant the role + * + * Example Usage: + * // previously defined "RBACData* rbac" with proper initialization + * uint32 roleId = 2; + * if (rbac->GrantRole(roleId) == RBAC_IN_DENIED_LIST) + * sLog->outDebug(LOG_FILTER_PLAYER, "Failed to grant role %u, already denied", roleId); + * @endcode + */ + RBACCommandResult GrantRole(uint32 roleId, int32 realmId = 0); + + /** + * @name DenyRole + * @brief Denies a role + * + * Denied a role to the account. If realm is 0 or the role can not be added + * No save to db action will be performed. + * + * Fails if role Id does not exists or role already granted or denied + * + * @param roleId role to be denied + * @param realmId realm affected + * + * @return Success or failure (with reason) to deny the role + * + * Example Usage: + * // previously defined "RBACData* rbac" with proper initialization + * uint32 roleId = 2; + * if (rbac->DenyRole(roleId) == RBAC_ID_DOES_NOT_EXISTS) + * sLog->outDebug(LOG_FILTER_PLAYER, "Role Id %u does not exists", roleId); + * @endcode + */ + RBACCommandResult DenyRole(uint32 roleId, int32 realmId = 0); + + /** + * @name RevokeRole + * @brief Removes a role + * + * Removes a role from the account. If realm is 0 or the role can not be removed + * No save to db action will be performed. Any delete operation will always affect + * "all realms (-1)" in addition to the realm specified + * + * Fails if role not present + * + * @param roleId role to be removed + * @param realmId realm affected + * + * @return Success or failure (with reason) to remove the role + * + * Example Usage: + * // previously defined "RBACData* rbac" with proper initialization + * uint32 roleId = 2; + * if (rbac->RevokeRole(roleId) == RBAC_OK) + * sLog->outDebug(LOG_FILTER_PLAYER, "Role %u succesfully removed", roleId); + * @endcode + */ + RBACCommandResult RevokeRole(uint32 roleId, int32 realmId = 0); + + /** + * @name GrantRole + * @brief Grants a permission + * + * Grants a permission to the account. If realm is 0 or the permission can not be added + * No save to db action will be performed. + * + * Fails if permission Id does not exists or permission already granted or denied + * + * @param permissionId permission to be granted + * @param realmId realm affected + * + * @return Success or failure (with reason) to grant the permission + * + * Example Usage: + * // previously defined "RBACData* rbac" with proper initialization + * uint32 permissionId = 2; + * if (rbac->GrantRole(permissionId) == RBAC_IN_DENIED_LIST) + * sLog->outDebug(LOG_FILTER_PLAYER, "Failed to grant permission %u, already denied", permissionId); + * @endcode + */ + RBACCommandResult GrantPermission(uint32 permissionId, int32 realmId = 0); + + /** + * @name DenyPermission + * @brief Denies a permission + * + * Denied a permission to the account. If realm is 0 or the permission can not be added + * No save to db action will be performed. + * + * Fails if permission Id does not exists or permission already granted or denied + * + * @param permissionId permission to be denied + * @param realmId realm affected + * + * @return Success or failure (with reason) to deny the permission + * + * Example Usage: + * // previously defined "RBACData* rbac" with proper initialization + * uint32 permissionId = 2; + * if (rbac->DenyRole(permissionId) == RBAC_ID_DOES_NOT_EXISTS) + * sLog->outDebug(LOG_FILTER_PLAYER, "Role Id %u does not exists", permissionId); + * @endcode + */ + RBACCommandResult DenyPermission(uint32 permissionId, int32 realmId = 0); + + /** + * @name RevokePermission + * @brief Removes a permission + * + * Removes a permission from the account. If realm is 0 or the permission can not be removed + * No save to db action will be performed. Any delete operation will always affect + * "all realms (-1)" in addition to the realm specified + * + * Fails if permission not present + * + * @param permissionId permission to be removed + * @param realmId realm affected + * + * @return Success or failure (with reason) to remove the permission + * + * Example Usage: + * // previously defined "RBACData* rbac" with proper initialization + * uint32 permissionId = 2; + * if (rbac->RevokeRole(permissionId) == RBAC_OK) + * sLog->outDebug(LOG_FILTER_PLAYER, "Permission %u succesfully removed", permissionId); + * @endcode + */ + RBACCommandResult RevokePermission(uint32 permissionId, int32 realmId = 0); + + /// Loads all permissions, groups and roles assigned to current account + void LoadFromDB(); + private: + /// Saves a role to DB, Granted or Denied + void SaveRole(uint32 role, bool granted, int32 realm); + /// Saves a permission to DB, Granted or Denied + void SavePermission(uint32 role, bool granted, int32 realm); + + /** + * @name CalculateNewPermissions + * @brief Calculates new permissions + * + * Calculates new permissions after some change in groups, roles or permissions. + * The calculation is done Granted - Denied: + * - Granted permissions: through groups, through roles and directly assigned + * - Denied permissions: through roles and directly assigned + */ + void CalculateNewPermissions(); + + int32 GetRealmId() { return _realmId; } + + int32 _realmId; ///> RealmId Affected + RBACGroupContainer _groups; ///> Granted groups + RBACRoleContainer _grantedRoles; ///> Granted roles + RBACRoleContainer _deniedRoles; ///> Denied roles + RBACPermissionContainer _grantedPerms; ///> Granted permissions + RBACPermissionContainer _deniedPerms; ///> Denied permissions + RBACPermissionContainer _globalPerms; ///> Calculated permissions +}; + +#endif diff --git a/src/server/scripts/Commands/cs_rbac.cpp b/src/server/scripts/Commands/cs_rbac.cpp new file mode 100644 index 00000000000..fb21def4c02 --- /dev/null +++ b/src/server/scripts/Commands/cs_rbac.cpp @@ -0,0 +1,780 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +/* ScriptData +Name: rbac_commandscript +%Complete: 100 +Comment: All role based access control related commands (including account related) +Category: commandscripts +EndScriptData */ + +#include "RBAC.h" +#include "Config.h" +#include "Chat.h" +#include "Language.h" +#include "Player.h" +#include "ScriptMgr.h" + +struct RBACCommandData +{ + RBACCommandData(): id(0), realmId(0), rbac(NULL), needDelete(false) { } + uint32 id; + int32 realmId; + RBACData* rbac; + bool needDelete; +}; + +class rbac_commandscript : public CommandScript +{ +public: + rbac_commandscript() : CommandScript("rbac_commandscript") { } + + ChatCommand* GetCommands() const + { + static ChatCommand rbacGroupsCommandTable[] = + { + { "add", SEC_ADMINISTRATOR, true, &HandleRBACGroupAddCommand, "", NULL }, + { "remove", SEC_ADMINISTRATOR, true, &HandleRBACGroupRemoveCommand, "", NULL }, + { "", SEC_ADMINISTRATOR, true, &HandleRBACGroupListCommand, "", NULL }, + { NULL, SEC_ADMINISTRATOR, false, NULL, "", NULL } + }; + + static ChatCommand rbacRolesCommandTable[] = + { + { "grant", SEC_ADMINISTRATOR, true, &HandleRBACRoleGrantCommand, "", NULL }, + { "deny", SEC_ADMINISTRATOR, true, &HandleRBACRoleDenyCommand, "", NULL }, + { "revoke", SEC_ADMINISTRATOR, true, &HandleRBACRoleRevokeCommand, "", NULL }, + { "", SEC_ADMINISTRATOR, true, &HandleRBACRoleListCommand, "", NULL }, + { NULL, SEC_ADMINISTRATOR, false, NULL, "", NULL } + }; + + static ChatCommand rbacPermsCommandTable[] = + { + { "grant", SEC_ADMINISTRATOR, true, &HandleRBACPermGrantCommand, "", NULL }, + { "deny", SEC_ADMINISTRATOR, true, &HandleRBACPermDenyCommand, "", NULL }, + { "revoke", SEC_ADMINISTRATOR, true, &HandleRBACPermRevokeCommand, "", NULL }, + { "", SEC_ADMINISTRATOR, true, &HandleRBACPermListCommand, "", NULL }, + { NULL, SEC_ADMINISTRATOR, false, NULL, "", NULL } + }; + + static ChatCommand rbacListCommandTable[] = + { + { "groups", SEC_ADMINISTRATOR, true, &HandleRBACListGroupsCommand, "", NULL }, + { "roles", SEC_ADMINISTRATOR, true, &HandleRBACListRolesCommand, "", NULL }, + { "permissions", SEC_ADMINISTRATOR, true, &HandleRBACListPermissionsCommand, "", NULL }, + { NULL, SEC_ADMINISTRATOR, false, NULL, "", NULL } + }; + + static ChatCommand rbacAccountCommandTable[] = + { + { "group", SEC_ADMINISTRATOR, true, NULL, "", rbacGroupsCommandTable }, + { "role", SEC_ADMINISTRATOR, true, NULL, "", rbacRolesCommandTable }, + { "permission", SEC_ADMINISTRATOR, true, NULL, "", rbacPermsCommandTable }, + { "", SEC_ADMINISTRATOR, true, &HandleRBACAccountPermissionCommand, "", NULL }, + { NULL, SEC_ADMINISTRATOR, false, NULL, "", NULL } + }; + + static ChatCommand rbacCommandTable[] = + { + { "account", SEC_ADMINISTRATOR, true, NULL, "", rbacAccountCommandTable }, + { "list", SEC_ADMINISTRATOR, true, NULL, "", rbacListCommandTable }, + { NULL, SEC_ADMINISTRATOR, false, NULL, "", NULL } + }; + + static ChatCommand commandTable[] = + { + { "rbac", SEC_ADMINISTRATOR, true, NULL, "", rbacCommandTable }, + { NULL, SEC_ADMINISTRATOR, false, NULL, "", NULL } + }; + + return commandTable; + } + + static RBACCommandData* ReadParams(ChatHandler* handler, char const* args, bool checkParams = true) + { + if (!args) + return NULL; + + char* param1 = strtok((char*)args, " "); + char* param2 = strtok(NULL, " "); + char* param3 = strtok(NULL, " "); + + int32 realmId = -1; + uint32 accountId = 0; + std::string accountName; + uint32 id = 0; + RBACCommandData* data = NULL; + RBACData* rdata = NULL; + bool useSelectedPlayer = false; + + if (checkParams) + { + if (!param3) + { + if (param2) + realmId = atoi(param2); + + if (param1) + id = atoi(param1); + + useSelectedPlayer = true; + } + else + { + id = atoi(param2); + realmId = atoi(param3); + } + + if (!id) + { + handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, id); + handler->SetSentErrorMessage(true); + return NULL; + } + + if (realmId < -1 || !realmId) + { + handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_REALM, realmId); + handler->SetSentErrorMessage(true); + return NULL; + } + } + else if (!param1) + useSelectedPlayer = true; + + if (useSelectedPlayer) + { + Player* player = handler->getSelectedPlayer(); + if (!player) + return NULL; + + rdata = player->GetSession()->GetRBACData(); + accountId = rdata->GetId(); + AccountMgr::GetName(accountId, accountName); + } + else + { + accountName = param1; + + if (AccountMgr::normalizeString(accountName)) + accountId = AccountMgr::GetId(accountName); + + if (!accountId) + { + handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str()); + handler->SetSentErrorMessage(true); + return NULL; + } + } + + if (checkParams && handler->HasLowerSecurityAccount(NULL, accountId, true)) + return NULL; + + data = new RBACCommandData(); + + if (!rdata) + { + data->rbac = new RBACData(accountId, accountName, ConfigMgr::GetIntDefault("RealmID", 0)); + data->rbac->LoadFromDB(); + data->needDelete = true; + } + else + data->rbac = rdata; + + data->id = id; + data->realmId = realmId; + return data; + } + + static bool HandleRBACGroupAddCommand(ChatHandler* handler, char const* args) + { + RBACCommandData* command = ReadParams(handler, args); + + if (!command) + { + handler->SetSentErrorMessage(true); + return false; + } + + RBACCommandResult result = command->rbac->AddGroup(command->id, command->realmId); + RBACGroup const* group = sAccountMgr->GetRBACGroup(command->id); + + switch (result) + { + case RBAC_CANT_ADD_ALREADY_ADDED: + handler->PSendSysMessage(LANG_RBAC_GROUP_IN_LIST, command->id, group->GetName().c_str(), + command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str()); + break; + case RBAC_OK: + handler->PSendSysMessage(LANG_RBAC_GROUP_ADDED, command->id, group->GetName().c_str(), + command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str()); + break; + case RBAC_ID_DOES_NOT_EXISTS: + handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, command->id); + break; + default: + break; + } + + if (command->needDelete) + delete command; + + return true; + } + + static bool HandleRBACGroupRemoveCommand(ChatHandler* handler, char const* args) + { + RBACCommandData* command = ReadParams(handler, args); + + if (!command) + { + handler->SetSentErrorMessage(true); + return false; + } + + RBACCommandResult result = command->rbac->RemoveGroup(command->id, command->realmId); + RBACGroup const* group = sAccountMgr->GetRBACGroup(command->id); + + switch (result) + { + case RBAC_CANT_REVOKE_NOT_IN_LIST: + handler->PSendSysMessage(LANG_RBAC_GROUP_NOT_IN_LIST, command->id, group->GetName().c_str(), + command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str()); + break; + case RBAC_OK: + handler->PSendSysMessage(LANG_RBAC_GROUP_REMOVED, command->id, group->GetName().c_str(), + command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str()); + break; + case RBAC_ID_DOES_NOT_EXISTS: + handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, command->id); + break; + default: + break; + } + + if (command->needDelete) + delete command; + + return true; + } + + static bool HandleRBACGroupListCommand(ChatHandler* handler, char const* args) + { + RBACCommandData* command = ReadParams(handler, args, false); + + if (!command) + { + handler->SetSentErrorMessage(true); + return false; + } + + handler->PSendSysMessage(LANG_RBAC_GROUP_LIST_HEADER, command->rbac->GetId(), command->rbac->GetName().c_str()); + RBACGroupContainer const& groups = command->rbac->GetGroups(); + if (groups.empty()) + handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_EMPTY)); + else + { + for (RBACGroupContainer::const_iterator it = groups.begin(); it != groups.end(); ++it) + { + RBACGroup const* group = sAccountMgr->GetRBACGroup(*it); + handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, group->GetId(), group->GetName().c_str()); + } + } + + if (command->needDelete) + delete command; + + return true; + } + + static bool HandleRBACRoleGrantCommand(ChatHandler* handler, char const* args) + { + RBACCommandData* command = ReadParams(handler, args); + + if (!command) + { + handler->SetSentErrorMessage(true); + return false; + } + + RBACCommandResult result = command->rbac->GrantRole(command->id, command->realmId); + RBACRole const* role = sAccountMgr->GetRBACRole(command->id); + + switch (result) + { + case RBAC_CANT_ADD_ALREADY_ADDED: + handler->PSendSysMessage(LANG_RBAC_ROLE_GRANTED_IN_LIST, command->id, role->GetName().c_str(), + command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str()); + break; + case RBAC_IN_DENIED_LIST: + handler->PSendSysMessage(LANG_RBAC_ROLE_GRANTED_IN_DENIED_LIST, command->id, role->GetName().c_str(), + command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str()); + break; + case RBAC_OK: + handler->PSendSysMessage(LANG_RBAC_ROLE_GRANTED, command->id, role->GetName().c_str(), + command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str()); + break; + case RBAC_ID_DOES_NOT_EXISTS: + handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, command->id); + break; + default: + break; + } + + if (command->needDelete) + delete command; + + return true; + } + + static bool HandleRBACRoleDenyCommand(ChatHandler* handler, char const* args) + { + RBACCommandData* command = ReadParams(handler, args); + + if (!command) + { + handler->SetSentErrorMessage(true); + return false; + } + + RBACCommandResult result = command->rbac->DenyRole(command->id, command->realmId); + RBACRole const* role = sAccountMgr->GetRBACRole(command->id); + + switch (result) + { + case RBAC_CANT_ADD_ALREADY_ADDED: + handler->PSendSysMessage(LANG_RBAC_ROLE_DENIED_IN_LIST, command->id, role->GetName().c_str(), + command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str()); + break; + case RBAC_IN_GRANTED_LIST: + handler->PSendSysMessage(LANG_RBAC_ROLE_DENIED_IN_GRANTED_LIST, command->id, role->GetName().c_str(), + command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str()); + break; + case RBAC_OK: + handler->PSendSysMessage(LANG_RBAC_ROLE_DENIED, command->id, role->GetName().c_str(), + command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str()); + break; + case RBAC_ID_DOES_NOT_EXISTS: + handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, command->id); + break; + default: + break; + } + + if (command->needDelete) + delete command; + + return true; + } + + static bool HandleRBACRoleRevokeCommand(ChatHandler* handler, char const* args) + { + RBACCommandData* command = ReadParams(handler, args); + + if (!command) + { + handler->SetSentErrorMessage(true); + return false; + } + + RBACCommandResult result = command->rbac->RevokeRole(command->id, command->realmId); + RBACRole const* role = sAccountMgr->GetRBACRole(command->id); + + switch (result) + { + case RBAC_CANT_REVOKE_NOT_IN_LIST: + handler->PSendSysMessage(LANG_RBAC_ROLE_REVOKED_NOT_IN_LIST, command->id, role->GetName().c_str(), + command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str()); + break; + case RBAC_OK: + handler->PSendSysMessage(LANG_RBAC_ROLE_REVOKED, command->id, role->GetName().c_str(), + command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str()); + break; + case RBAC_ID_DOES_NOT_EXISTS: + handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, command->id); + break; + default: + break; + } + + if (command->needDelete) + delete command; + + return true; + } + + static bool HandleRBACRoleListCommand(ChatHandler* handler, char const* args) + { + RBACCommandData* command = ReadParams(handler, args, false); + + if (!command) + { + handler->SetSentErrorMessage(true); + return false; + } + + handler->PSendSysMessage(LANG_RBAC_ROLE_LIST_HEADER_GRANTED, command->rbac->GetId(), command->rbac->GetName().c_str()); + RBACGroupContainer const& granted = command->rbac->GetGrantedRoles(); + if (granted.empty()) + handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_EMPTY)); + else + { + for (RBACRoleContainer::const_iterator it = granted.begin(); it != granted.end(); ++it) + { + RBACRole const* role = sAccountMgr->GetRBACRole(*it); + handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, role->GetId(), role->GetName().c_str()); + } + } + + handler->PSendSysMessage(LANG_RBAC_ROLE_LIST_HEADER_DENIED, command->rbac->GetId(), command->rbac->GetName().c_str()); + RBACGroupContainer const& denied = command->rbac->GetDeniedRoles(); + if (denied.empty()) + handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_EMPTY)); + else + { + for (RBACRoleContainer::const_iterator it = denied.begin(); it != denied.end(); ++it) + { + RBACRole const* role = sAccountMgr->GetRBACRole(*it); + handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, role->GetId(), role->GetName().c_str()); + } + } + + if (command->needDelete) + delete command; + + return true; + } + + static bool HandleRBACPermGrantCommand(ChatHandler* handler, char const* args) + { + RBACCommandData* command = ReadParams(handler, args); + + if (!command) + { + handler->SetSentErrorMessage(true); + return false; + } + + RBACCommandResult result = command->rbac->GrantPermission(command->id, command->realmId); + RBACPermission const* permission = sAccountMgr->GetRBACPermission(command->id); + + switch (result) + { + case RBAC_CANT_ADD_ALREADY_ADDED: + handler->PSendSysMessage(LANG_RBAC_PERM_GRANTED_IN_LIST, command->id, permission->GetName().c_str(), + command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str()); + break; + case RBAC_IN_DENIED_LIST: + handler->PSendSysMessage(LANG_RBAC_PERM_GRANTED_IN_DENIED_LIST, command->id, permission->GetName().c_str(), + command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str()); + break; + case RBAC_OK: + handler->PSendSysMessage(LANG_RBAC_PERM_GRANTED, command->id, permission->GetName().c_str(), + command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str()); + break; + case RBAC_ID_DOES_NOT_EXISTS: + handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, command->id); + break; + default: + break; + } + + if (command->needDelete) + delete command; + + return true; + } + + static bool HandleRBACPermDenyCommand(ChatHandler* handler, char const* args) + { + RBACCommandData* command = ReadParams(handler, args); + + if (!command) + { + handler->SetSentErrorMessage(true); + return false; + } + + RBACCommandResult result = command->rbac->DenyPermission(command->id, command->realmId); + RBACPermission const* permission = sAccountMgr->GetRBACPermission(command->id); + + switch (result) + { + case RBAC_CANT_ADD_ALREADY_ADDED: + handler->PSendSysMessage(LANG_RBAC_PERM_DENIED_IN_LIST, command->id, permission->GetName().c_str(), + command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str()); + break; + case RBAC_IN_GRANTED_LIST: + handler->PSendSysMessage(LANG_RBAC_PERM_DENIED_IN_GRANTED_LIST, command->id, permission->GetName().c_str(), + command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str()); + break; + case RBAC_OK: + handler->PSendSysMessage(LANG_RBAC_PERM_DENIED, command->id, permission->GetName().c_str(), + command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str()); + break; + case RBAC_ID_DOES_NOT_EXISTS: + handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, command->id); + break; + default: + break; + } + + if (command->needDelete) + delete command; + + return true; + } + + static bool HandleRBACPermRevokeCommand(ChatHandler* handler, char const* args) + { + RBACCommandData* command = ReadParams(handler, args); + + if (!command) + { + handler->SetSentErrorMessage(true); + return false; + } + + RBACCommandResult result = command->rbac->RevokePermission(command->id, command->realmId); + RBACPermission const* permission = sAccountMgr->GetRBACPermission(command->id); + + switch (result) + { + case RBAC_CANT_REVOKE_NOT_IN_LIST: + handler->PSendSysMessage(LANG_RBAC_PERM_REVOKED_NOT_IN_LIST, command->id, permission->GetName().c_str(), + command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str()); + break; + case RBAC_OK: + handler->PSendSysMessage(LANG_RBAC_PERM_REVOKED, command->id, permission->GetName().c_str(), + command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str()); + break; + case RBAC_ID_DOES_NOT_EXISTS: + handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, command->id); + break; + default: + break; + } + + if (command->needDelete) + delete command; + + return true; + } + + static bool HandleRBACPermListCommand(ChatHandler* handler, char const* args) + { + RBACCommandData* command = ReadParams(handler, args, false); + + if (!command) + { + handler->SetSentErrorMessage(true); + return false; + } + + handler->PSendSysMessage(LANG_RBAC_PERM_LIST_HEADER_GRANTED, command->rbac->GetId(), command->rbac->GetName().c_str()); + RBACPermissionContainer const& granted = command->rbac->GetGrantedPermissions(); + if (!granted.any()) + handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_EMPTY)); + else + { + for (uint32 i = 0; i < RBAC_PERM_MAX; ++i) + if (granted.test(i)) + { + RBACPermission const* permission = sAccountMgr->GetRBACPermission(i); + handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, permission->GetId(), permission->GetName().c_str()); + } + } + + handler->PSendSysMessage(LANG_RBAC_PERM_LIST_HEADER_DENIED, command->rbac->GetId(), command->rbac->GetName().c_str()); + RBACPermissionContainer const& denied = command->rbac->GetDeniedPermissions(); + if (!denied.any()) + handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_EMPTY)); + else + { + for (uint32 i = 0; i < RBAC_PERM_MAX; ++i) + if (denied.test(i)) + { + RBACPermission const* permission = sAccountMgr->GetRBACPermission(i); + handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, permission->GetId(), permission->GetName().c_str()); + } + } + + if (command->needDelete) + delete command; + + return true; + } + + static bool HandleRBACAccountPermissionCommand(ChatHandler* handler, char const* args) + { + RBACCommandData* command = ReadParams(handler, args, false); + + if (!command) + { + handler->SetSentErrorMessage(true); + return false; + } + + handler->PSendSysMessage(LANG_RBAC_PERM_LIST_GLOBAL, command->rbac->GetId(), command->rbac->GetName().c_str()); + RBACPermissionContainer const& permissions = command->rbac->GetPermissions(); + if (!permissions.any()) + handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_EMPTY)); + else + { + for (uint32 i = 0; i < RBAC_PERM_MAX; ++i) + if (permissions.test(i)) + { + RBACPermission const* permission = sAccountMgr->GetRBACPermission(i); + handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, permission->GetId(), permission->GetName().c_str()); + } + } + + if (command->needDelete) + delete command; + + return true; + } + + static bool HandleRBACListGroupsCommand(ChatHandler* handler, char const* args) + { + uint32 id = 0; + if (char* param1 = strtok((char*)args, " ")) + id = atoi(param1); + + if (!id) + { + RBACGroupsContainer const& groups = sAccountMgr->GetRBACGroupList(); + handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_GROUPS_HEADER)); + for (RBACGroupsContainer::const_iterator it = groups.begin(); it != groups.end(); ++it) + { + RBACGroup const* group = it->second; + handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, group->GetId(), group->GetName().c_str()); + } + } + else + { + RBACGroup const* group = sAccountMgr->GetRBACGroup(id); + if (!group) + { + handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, id); + handler->SetSentErrorMessage(true); + return false; + } + + handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_GROUPS_HEADER)); + handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, group->GetId(), group->GetName().c_str()); + handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_ROLES_HEADER)); + RBACRoleContainer const& roles = group->GetRoles(); + if (roles.empty()) + handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_EMPTY)); + else + { + for (RBACRoleContainer::const_iterator it = roles.begin(); it != roles.end(); ++it) + { + RBACRole const* role = sAccountMgr->GetRBACRole(*it); + handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, role->GetId(), role->GetName().c_str()); + } + } + } + + return true; + } + + static bool HandleRBACListRolesCommand(ChatHandler* handler, char const* args) + { + uint32 id = 0; + if (char* param1 = strtok((char*)args, " ")) + id = atoi(param1); + + if (!id) + { + RBACRolesContainer const& roles = sAccountMgr->GetRBACRoleList(); + handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_ROLES_HEADER)); + for (RBACRolesContainer::const_iterator it = roles.begin(); it != roles.end(); ++it) + { + RBACRole const* role = it->second; + handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, role->GetId(), role->GetName().c_str()); + } + } + else + { + RBACRole const* role = sAccountMgr->GetRBACRole(id); + if (!role) + { + handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, id); + handler->SetSentErrorMessage(true); + return false; + } + + handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_ROLES_HEADER)); + handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, role->GetId(), role->GetName().c_str()); + handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_PERMISSIONS_HEADER)); + RBACPermissionContainer const& permissions = role->GetPermissions(); + if (!permissions.any()) + handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_EMPTY)); + else + { + for (uint32 i = 0; i < RBAC_PERM_MAX; ++i) + if (permissions.test(i)) + { + RBACPermission const* permission = sAccountMgr->GetRBACPermission(i); + handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, permission->GetId(), permission->GetName().c_str()); + } + } + } + + return true; + } + + static bool HandleRBACListPermissionsCommand(ChatHandler* handler, char const* args) + { + uint32 id = 0; + if (char* param1 = strtok((char*)args, " ")) + id = atoi(param1); + + if (!id) + { + RBACPermissionsContainer const& permissions = sAccountMgr->GetRBACPermissionList(); + handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_PERMISSIONS_HEADER)); + for (RBACPermissionsContainer::const_iterator it = permissions.begin(); it != permissions.end(); ++it) + { + RBACPermission const* permission = it->second; + handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, permission->GetId(), permission->GetName().c_str()); + } + } + else + { + RBACPermission const* permission = sAccountMgr->GetRBACPermission(id); + if (!permission) + { + handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, id); + handler->SetSentErrorMessage(true); + return false; + } + + handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_PERMISSIONS_HEADER)); + handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, permission->GetId(), permission->GetName().c_str()); + } + + return true; + } +}; + +void AddSC_rbac_commandscript() +{ + new rbac_commandscript(); +} -- cgit v1.2.3 From 61979f85918ed7acda19075d3a3201ad15bbcaea Mon Sep 17 00:00:00 2001 From: Spp Date: Mon, 4 Feb 2013 16:52:43 +0100 Subject: Scripts/Player: Add OnMapChanged to PlayerScripts (after map changed) Core/Dungeon Finder: Use OnMapChanged script to cast/remove Luck of the draw - Also move code to force party update to LfgPlayerScript - Remove some obsolete Lfg code after recent commits --- .../2013_02_04_05_world_spell_script_names.sql | 1 + src/server/game/DungeonFinding/LFGMgr.cpp | 14 ----- src/server/game/DungeonFinding/LFGMgr.h | 9 ++-- src/server/game/DungeonFinding/LFGScripts.cpp | 18 +++++++ src/server/game/DungeonFinding/LFGScripts.h | 1 + src/server/game/Entities/Player/Player.cpp | 19 +------ src/server/game/Maps/Map.cpp | 4 -- src/server/game/Scripting/ScriptMgr.cpp | 2 + src/server/game/Scripting/ScriptMgr.h | 3 ++ src/server/scripts/Spells/spell_generic.cpp | 61 ---------------------- 10 files changed, 29 insertions(+), 103 deletions(-) create mode 100644 sql/updates/world/2013_02_04_05_world_spell_script_names.sql (limited to 'src/server/scripts') diff --git a/sql/updates/world/2013_02_04_05_world_spell_script_names.sql b/sql/updates/world/2013_02_04_05_world_spell_script_names.sql new file mode 100644 index 00000000000..055e4b1d77d --- /dev/null +++ b/sql/updates/world/2013_02_04_05_world_spell_script_names.sql @@ -0,0 +1 @@ +DELETE FROM `spell_script_names` WHERE `spell_id`=72221; diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index e18a103e21c..9bb65b63557 100644 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -1085,7 +1085,6 @@ void LFGMgr::UpdateProposal(uint32 proposalId, uint64 guid, bool accept) break; } - teleportStore.push_back(pguid); SetState(pguid, LFG_STATE_DUNGEON); } @@ -1320,10 +1319,7 @@ void LFGMgr::TeleportPlayer(Player* player, bool out, bool fromOpcode /*= false* sLog->outDebug(LOG_FILTER_LFG, "TeleportPlayer: Player %s is being teleported out. Current Map %u - Expected Map %u", player->GetName().c_str(), player->GetMapId(), uint32(dungeon->map)); if (player->GetMapId() == uint32(dungeon->map)) - { - player->RemoveAurasDueToSpell(LFG_SPELL_LUCK_OF_THE_DRAW); player->TeleportToBGEntryPoint(); - } return; } @@ -1597,16 +1593,6 @@ const std::string& LFGMgr::GetComment(uint64 guid) return PlayersStore[guid].GetComment(); } -bool LFGMgr::hasPendingTeleport(uint64 pguid) -{ - if (std::find(teleportStore.begin(), teleportStore.end(), pguid) != teleportStore.end()) - { - teleportStore.remove(pguid); - return true; - } - return false; -} - LfgDungeonSet const& LFGMgr::GetSelectedDungeons(uint64 guid) { sLog->outTrace(LOG_FILTER_LFG, "LFGMgr::GetSelectedDungeons: [" UI64FMTD "]", guid); diff --git a/src/server/game/DungeonFinding/LFGMgr.h b/src/server/game/DungeonFinding/LFGMgr.h index 07c4281f86f..96fedb65547 100644 --- a/src/server/game/DungeonFinding/LFGMgr.h +++ b/src/server/game/DungeonFinding/LFGMgr.h @@ -329,8 +329,6 @@ class LFGMgr void _LoadFromDB(Field* fields, uint64 guid); /// Initializes player data after loading group data from DB void SetupGroupMember(uint64 guid, uint64 gguid); - /// Player has pending teleport action - bool hasPendingTeleport(uint64 guid); /// Return Lfg dungeon entry for given dungeon id uint32 GetLFGDungeonEntry(uint32 id); @@ -340,7 +338,7 @@ class LFGMgr /// Get current player comment (used for LFR) std::string const& GetComment(uint64 gguid); /// Gets current lfg options - uint32 GetOptions(); // cs_lfg + uint32 GetOptions(); /// Sets new lfg options void SetOptions(uint32 options); /// Checks if given lfg option is enabled @@ -355,8 +353,6 @@ class LFGMgr uint64 GetLeader(uint64 guid); /// Initializes locked dungeons for given player (called at login or level change) void InitializeLockedDungeons(Player* player, uint8 level = 0); - /// Inits new proposal to boot a player - void InitBoot(uint64 gguid, uint64 kguid, uint64 vguid, std::string const& reason); /// Sets player team void SetTeam(uint64 guid, uint8 team); /// Sets player group @@ -385,6 +381,8 @@ class LFGMgr LfgDungeonSet GetRandomAndSeasonalDungeons(uint8 level, uint8 expansion); /// Teleport a player to/from selected dungeon void TeleportPlayer(Player* player, bool out, bool fromOpcode = false); + /// Inits new proposal to boot a player + void InitBoot(uint64 gguid, uint64 kguid, uint64 vguid, std::string const& reason); /// Updates player boot proposal with new player answer void UpdateBoot(uint64 guid, bool accept); /// Updates proposal to join dungeon with player answer @@ -467,7 +465,6 @@ class LFGMgr LfgPlayerBootContainer BootsStore; ///< Current player kicks LfgPlayerDataContainer PlayersStore; ///< Player data LfgGroupDataContainer GroupsStore; ///< Group data - LfgGuidList teleportStore; ///< Players being teleported }; } // namespace lfg diff --git a/src/server/game/DungeonFinding/LFGScripts.cpp b/src/server/game/DungeonFinding/LFGScripts.cpp index ac95d289397..46a4ed4a134 100644 --- a/src/server/game/DungeonFinding/LFGScripts.cpp +++ b/src/server/game/DungeonFinding/LFGScripts.cpp @@ -88,6 +88,24 @@ void LFGPlayerScript::OnBindToInstance(Player* player, Difficulty difficulty, ui sLFGMgr->InitializeLockedDungeons(player); } +void LFGPlayerScript::OnMapChanged(Player* player) +{ + Map const* map = player->GetMap(); + + if (sLFGMgr->inLfgDungeonMap(player->GetGUID(), map->GetId(), map->GetDifficulty())) + { + Group* group = player->GetGroup(); + for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) + if (Player* member = itr->getSource()) + player->GetSession()->SendNameQueryOpcode(member->GetGUID()); + + if (sLFGMgr->selectedRandomLfgDungeon(player->GetGUID())) + player->CastSpell(player, LFG_SPELL_LUCK_OF_THE_DRAW, true); + } + else // if (player->HasAura(lfg:LFG_SPELL_LUCK_OF_THE_DRAW)) + player->RemoveAurasDueToSpell(LFG_SPELL_LUCK_OF_THE_DRAW); +} + LFGGroupScript::LFGGroupScript() : GroupScript("LFGGroupScript") { } diff --git a/src/server/game/DungeonFinding/LFGScripts.h b/src/server/game/DungeonFinding/LFGScripts.h index e9c6b1499d1..bb1900cad93 100644 --- a/src/server/game/DungeonFinding/LFGScripts.h +++ b/src/server/game/DungeonFinding/LFGScripts.h @@ -39,6 +39,7 @@ class LFGPlayerScript : public PlayerScript void OnLogout(Player* player); void OnLogin(Player* player); void OnBindToInstance(Player* player, Difficulty difficulty, uint32 mapId, bool permanent); + void OnMapChanged(Player* player); }; class LFGGroupScript : public GroupScript diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index dc98facc5ab..18b2a837b5a 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -7444,17 +7444,7 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea) // group update if (Group* group = GetGroup()) - { SetGroupUpdateFlag(GROUP_UPDATE_FULL); - if (GetSession() && group->isLFGGroup() && sLFGMgr->hasPendingTeleport(GetGUID())) - { - for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) - { - if (Player* member = itr->getSource()) - GetSession()->SendNameQueryOpcode(member->GetGUID()); - } - } - } m_zoneUpdateId = newZone; m_zoneUpdateTimer = ZONE_UPDATE_INTERVAL; @@ -11913,19 +11903,12 @@ InventoryResult Player::CanUseItem(ItemTemplate const* proto) const InventoryResult Player::CanRollForItemInLFG(ItemTemplate const* proto, WorldObject const* lootedObject) const { - lfg::LfgDungeonSet const& dungeons = sLFGMgr->GetSelectedDungeons(GetGUID()); - if (dungeons.empty()) - return EQUIP_ERR_OK; // not using LFG - if (!GetGroup() || !GetGroup()->isLFGGroup()) return EQUIP_ERR_OK; // not in LFG group // check if looted object is inside the lfg dungeon - bool lootedObjectInDungeon = false; Map const* map = lootedObject->GetMap(); - lootedObjectInDungeon = sLFGMgr->inLfgDungeonMap(GetGroup()->GetGUID(), map->GetId(), map->GetDifficulty()); - - if (!lootedObjectInDungeon) + if (!sLFGMgr->inLfgDungeonMap(GetGroup()->GetGUID(), map->GetId(), map->GetDifficulty())) return EQUIP_ERR_OK; if (!proto) diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 288592d1029..7fe516a1eb4 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -26,7 +26,6 @@ #include "GridStates.h" #include "Group.h" #include "InstanceScript.h" -#include "LFGMgr.h" #include "MapInstanced.h" #include "MapManager.h" #include "ObjectAccessor.h" @@ -2484,9 +2483,6 @@ bool InstanceMap::AddPlayerToMap(Player* player) ASSERT(playerBind->save == mapSave); } } - - if (group && group->isLFGGroup()) - player->CastSpell(player, lfg::LFG_SPELL_LUCK_OF_THE_DRAW, true); } // for normal instances cancel the reset schedule when the diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp index cae8ea9d2d5..8321b88962f 100644 --- a/src/server/game/Scripting/ScriptMgr.cpp +++ b/src/server/game/Scripting/ScriptMgr.cpp @@ -580,6 +580,8 @@ void ScriptMgr::OnPlayerEnterMap(Map* map, Player* player) ASSERT(map); ASSERT(player); + FOREACH_SCRIPT(PlayerScript)->OnMapChanged(player); + SCR_MAP_BGN(WorldMapScript, map, itr, end, entry, IsWorldMap); itr->second->OnPlayerEnter(map, player); SCR_MAP_END; diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h index 7f140cfffe0..b13c2da7f6c 100644 --- a/src/server/game/Scripting/ScriptMgr.h +++ b/src/server/game/Scripting/ScriptMgr.h @@ -754,6 +754,9 @@ class PlayerScript : public UnitScript // Called when a player switches to a new zone virtual void OnUpdateZone(Player* /*player*/, uint32 /*newZone*/, uint32 /*newArea*/) { } + + // Called when a player changes to a new map (after moving to new map) + virtual void OnMapChanged(Player* /*player*/) { } }; class GuildScript : public ScriptObject diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index 39992e94c21..edda9750709 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -1707,66 +1707,6 @@ class spell_gen_damage_reduction_aura : public SpellScriptLoader } }; -class spell_gen_luck_of_the_draw : public SpellScriptLoader -{ - public: - spell_gen_luck_of_the_draw() : SpellScriptLoader("spell_gen_luck_of_the_draw") { } - - class spell_gen_luck_of_the_draw_AuraScript : public AuraScript - { - PrepareAuraScript(spell_gen_luck_of_the_draw_AuraScript); - Map const* map; - Difficulty difficulty; - - bool Load() - { - Player* owner = GetUnitOwner()->ToPlayer(); - if (!owner) - return false; - - Group* group = owner->GetGroup(); - if (!group || !group->isLFGGroup()) - return false; - - if (!sLFGMgr->selectedRandomLfgDungeon(owner->GetGUID())) - return false; - - map = owner->GetMap(); - difficulty = owner->GetMap()->GetDifficulty(); - - if (!sLFGMgr->inLfgDungeonMap(owner->GetGUID(), map->GetId(), difficulty)) - return false; - - return true; - } - - // cheap hax to make it have update calls - void CalcPeriodic(AuraEffect const* /*effect*/, bool& isPeriodic, int32& amplitude) - { - isPeriodic = true; - amplitude = 5 * IN_MILLISECONDS; - } - - void Update(AuraEffect* /*effect*/) - { - Map const* currentMap = GetUnitOwner()->ToPlayer()->GetMap(); - if (currentMap != map || currentMap->GetDifficulty() != difficulty) - Remove(AURA_REMOVE_BY_DEFAULT); - } - - void Register() - { - DoEffectCalcPeriodic += AuraEffectCalcPeriodicFn(spell_gen_luck_of_the_draw_AuraScript::CalcPeriodic, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE); - OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(spell_gen_luck_of_the_draw_AuraScript::Update, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE); - } - }; - - AuraScript* GetAuraScript() const - { - return new spell_gen_luck_of_the_draw_AuraScript(); - } -}; - enum DummyTrigger { SPELL_PERSISTANT_SHIELD_TRIGGERED = 26470, @@ -3608,7 +3548,6 @@ void AddSC_generic_spell_scripts() new spell_gen_vehicle_scaling(); new spell_gen_oracle_wolvar_reputation(); new spell_gen_damage_reduction_aura(); - new spell_gen_luck_of_the_draw(); new spell_gen_dummy_trigger(); new spell_gen_spirit_healer_res(); new spell_gen_gadgetzan_transporter_backfire(); -- cgit v1.2.3