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. --- sql/updates/auth/2013_xx_xx_00_auth_account.sql | 3 +++ sql/updates/world/2013_xx_xx_00_world_trinity_string.sql | 4 ++++ 2 files changed, 7 insertions(+) create mode 100644 sql/updates/auth/2013_xx_xx_00_auth_account.sql create mode 100644 sql/updates/world/2013_xx_xx_00_world_trinity_string.sql (limited to 'sql/updates') diff --git a/sql/updates/auth/2013_xx_xx_00_auth_account.sql b/sql/updates/auth/2013_xx_xx_00_auth_account.sql new file mode 100644 index 00000000000..fa893915716 --- /dev/null +++ b/sql/updates/auth/2013_xx_xx_00_auth_account.sql @@ -0,0 +1,3 @@ +ALTER TABLE `account` + ADD COLUMN `mutereason` VARCHAR(255) NOT NULL DEFAULT '' AFTER `mutetime`, + ADD COLUMN `muteby` VARCHAR(50) NOT NULL DEFAULT '' AFTER `mutereason`; \ No newline at end of file diff --git a/sql/updates/world/2013_xx_xx_00_world_trinity_string.sql b/sql/updates/world/2013_xx_xx_00_world_trinity_string.sql new file mode 100644 index 00000000000..5c531a0895d --- /dev/null +++ b/sql/updates/world/2013_xx_xx_00_world_trinity_string.sql @@ -0,0 +1,4 @@ +DELETE FROM `trinity_string` WHERE entry IN (300,550); +INSERT INTO `trinity_string` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES +('300','Your chat has been disabled for %u minutes. By: %s ,Reason: %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +('550','Mute time remaining: %s, By: %s, Reason: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); \ No newline at end of file -- cgit v1.2.3 From 83e3bf6d6d76156f36f3eaec28ef2244f9826fdf Mon Sep 17 00:00:00 2001 From: Bezo Date: Thu, 31 Jan 2013 00:30:29 +0200 Subject: Remove \ No newline at end of file --- sql/updates/auth/2013_xx_xx_00_auth_account.sql | 2 +- sql/updates/world/2013_xx_xx_00_world_trinity_string.sql | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'sql/updates') diff --git a/sql/updates/auth/2013_xx_xx_00_auth_account.sql b/sql/updates/auth/2013_xx_xx_00_auth_account.sql index fa893915716..9af73d41ee3 100644 --- a/sql/updates/auth/2013_xx_xx_00_auth_account.sql +++ b/sql/updates/auth/2013_xx_xx_00_auth_account.sql @@ -1,3 +1,3 @@ ALTER TABLE `account` ADD COLUMN `mutereason` VARCHAR(255) NOT NULL DEFAULT '' AFTER `mutetime`, - ADD COLUMN `muteby` VARCHAR(50) NOT NULL DEFAULT '' AFTER `mutereason`; \ No newline at end of file + ADD COLUMN `muteby` VARCHAR(50) NOT NULL DEFAULT '' AFTER `mutereason`; diff --git a/sql/updates/world/2013_xx_xx_00_world_trinity_string.sql b/sql/updates/world/2013_xx_xx_00_world_trinity_string.sql index 5c531a0895d..0a4ec437b28 100644 --- a/sql/updates/world/2013_xx_xx_00_world_trinity_string.sql +++ b/sql/updates/world/2013_xx_xx_00_world_trinity_string.sql @@ -1,4 +1,4 @@ DELETE FROM `trinity_string` WHERE entry IN (300,550); INSERT INTO `trinity_string` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES ('300','Your chat has been disabled for %u minutes. By: %s ,Reason: %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), -('550','Mute time remaining: %s, By: %s, Reason: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); \ No newline at end of file +('550','Mute time remaining: %s, By: %s, Reason: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); -- cgit v1.2.3 From 0fbfe675ec659ee51e3514948e80d40c18a1746e Mon Sep 17 00:00:00 2001 From: w1sht0l1v3 Date: Mon, 4 Feb 2013 01:26:45 +0200 Subject: DB/Misc: Add full script for Something Stinks (A:24655 H:24536) Rename an sql file. --- .../world/2013_02_03_00_world_lfg_entrances.sql | 1 + .../world/2013_02_03_world_lfg_entrances.sql | 1 - sql/updates/world/2013_02_04_00_world_misc.sql | 60 ++++++++++++++++++++++ 3 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 sql/updates/world/2013_02_03_00_world_lfg_entrances.sql delete mode 100644 sql/updates/world/2013_02_03_world_lfg_entrances.sql create mode 100644 sql/updates/world/2013_02_04_00_world_misc.sql (limited to 'sql/updates') diff --git a/sql/updates/world/2013_02_03_00_world_lfg_entrances.sql b/sql/updates/world/2013_02_03_00_world_lfg_entrances.sql new file mode 100644 index 00000000000..e308c001d29 --- /dev/null +++ b/sql/updates/world/2013_02_03_00_world_lfg_entrances.sql @@ -0,0 +1 @@ +ALTER TABLE `lfg_entrances` CHARACTER SET utf8 COLLATE utf8_general_ci, ENGINE MyISAM; diff --git a/sql/updates/world/2013_02_03_world_lfg_entrances.sql b/sql/updates/world/2013_02_03_world_lfg_entrances.sql deleted file mode 100644 index e308c001d29..00000000000 --- a/sql/updates/world/2013_02_03_world_lfg_entrances.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE `lfg_entrances` CHARACTER SET utf8 COLLATE utf8_general_ci, ENGINE MyISAM; diff --git a/sql/updates/world/2013_02_04_00_world_misc.sql b/sql/updates/world/2013_02_04_00_world_misc.sql new file mode 100644 index 00000000000..ff8021653ab --- /dev/null +++ b/sql/updates/world/2013_02_04_00_world_misc.sql @@ -0,0 +1,60 @@ +-- Something Stinks (A:24655 H:24536) +SET @GUID := 85637; -- set by TDB (need 10)(85637,85638,85639,85640,85641,85642,85643,85644,85645,85646,43498,43502,45075,45099) +SET @EVENT := 8; -- Love is in the Air + +SET @BUNNY := 38288; -- Love Guard Perfume Bunny +SET @GUARD_SW := 68; -- Stormwind City Guard +SET @PATROOLER_SW := 1976; -- Stormwind City Patroller +SET @GUARD_ORG := 3296; -- Orgrimmar Grunt +SET @ELITE_ORG := 14304; -- Kor'kron Elite + +SET @SPELL_PULSE := 71520; -- Heavily Perfumed Pulse +SET @SPELL_BUFF := 71507; -- Heavily Perfumed +SET @SPELL_ANALYSIS := 70192; -- Fragrant Air Analysis + + +DELETE FROM `creature` WHERE `id`=@BUNNY; +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,@BUNNY,0,1,1,0,0,-8825.604,629.3108,94.1137,0,300,0,0,1,0,0,0,0,0), -- sw trade district +(@GUID+1,@BUNNY,0,1,1,0,0,-8988.889,849.4149,105.9425,0,300,0,0,1,0,0,0,0,0), -- sw mage quarter +(@GUID+2,@BUNNY,0,1,1,0,0,-8737.654,1051.887,90.8816,0,300,0,0,1,0,0,0,0,0), -- sw the park +(@GUID+3,@BUNNY,0,1,1,0,0,-8625.038,780.0799,96.73399,0,300,0,0,1,0,0,0,0,0), -- sw cathedral square +(@GUID+4,@BUNNY,0,1,1,0,0,-8433.189,607.2205,95.13025,0,300,0,0,1,0,0,0,0,0), -- sw dwarven district +(@GUID+5,@BUNNY,0,1,1,0,0,-8486.955,390.5139,108.4689,0,300,0,0,1,0,0,0,0,0), -- sw stormwind keep +(@GUID+6,@BUNNY,0,1,1,0,0,-8676.724,444.5052,99.73087,0,300,0,0,1,0,0,0,0,0), -- sw old town +-- +(@GUID+7,@BUNNY,1,1,1,0,0,1573.92,-4397.11,16.00813,0,300,0,0,1,0,0,0,0,0), -- org valley of strength +(@GUID+8,@BUNNY,1,1,1,0,0,1893.24,-4507.31,24.94853,0,300,0,0,1,0,0,0,0,0), -- org the drag +(@GUID+9,@BUNNY,1,1,1,0,0,2015.27,-4687.4,28.61023,0,300,0,0,1,0,0,0,0,0); -- org valley of honor + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry`=@SPELL_PULSE; +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=17 AND `SourceEntry`=@SPELL_BUFF; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`SourceId`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionTarget`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`NegativeCondition`,`ErrorType`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES +(13,1,@SPELL_PULSE,0,0,31,0,3,@GUARD_SW,0,0,0,0,'',"Heavily Perfumed Pulse target Stormwind City Guard"), +(13,1,@SPELL_PULSE,0,1,31,0,3,@PATROOLER_SW,0,0,0,0,'',"Heavily Perfumed Pulse target Stormwind City Patroller"), +(13,1,@SPELL_PULSE,0,2,31,0,3,@GUARD_ORG,0,0,0,0,'',"Heavily Perfumed Pulse target Orgrimmar Grunt"), +(13,1,@SPELL_PULSE,0,3,31,0,3,@ELITE_ORG,0,0,0,0,'',"Heavily Perfumed Pulse target Kor'kron Elite"), +(17,0,@SPELL_BUFF,0,0,1,0,@SPELL_BUFF,0,0,1,0,0,'',"Apply Heavily Perfumed only when missing"); + +UPDATE `creature_template` SET `AIName`='SmartAI',`InhabitType`=4,`flags_extra`=`flags_extra`|128 WHERE `entry`=@BUNNY; +DELETE FROM `smart_scripts` WHERE `entryorguid`=@BUNNY 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 +(@BUNNY,0,0,0,60,0,100,0,0,0,600000,600000,11,@SPELL_PULSE,0,0,0,0,0,1,0,0,0,0,0,0,0,"On update(each 10 min) - Cast - Self"); + +-- ussing this because dummy effect #1 of spell 70192 is to remove the buff +DELETE FROM `spell_linked_spell` WHERE `spell_trigger`=@SPELL_ANALYSIS; +INSERT INTO `spell_linked_spell` (`spell_trigger`,`spell_effect`,`type`,`comment`) VALUES +(@SPELL_ANALYSIS,-@SPELL_BUFF,1,'Remove Heavily Perfumed on Fragrant Air Analysis hit'); + +DELETE FROM `game_event_creature` WHERE `eventEntry`=@EVENT AND `guid` BETWEEN @GUID+0 AND @GUID+9; +INSERT INTO `game_event_creature` (`eventEntry`,`guid`) VALUES +(@EVENT,@GUID+0), +(@EVENT,@GUID+1), +(@EVENT,@GUID+2), +(@EVENT,@GUID+3), +(@EVENT,@GUID+4), +(@EVENT,@GUID+5), +(@EVENT,@GUID+6), +(@EVENT,@GUID+7), +(@EVENT,@GUID+8), +(@EVENT,@GUID+9); -- cgit v1.2.3 From e0fca3454e55f1689b669f0ecf385a2556a898a8 Mon Sep 17 00:00:00 2001 From: Kinzcool Date: Sun, 3 Feb 2013 18:50:42 -0500 Subject: DB/Creature Text: Corrected some texts & type fails -- more to come; Soon (TM) --- .../world/2013_02_04_01_world_creature_text.sql | 165 +++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 sql/updates/world/2013_02_04_01_world_creature_text.sql (limited to 'sql/updates') diff --git a/sql/updates/world/2013_02_04_01_world_creature_text.sql b/sql/updates/world/2013_02_04_01_world_creature_text.sql new file mode 100644 index 00000000000..c52aa380c49 --- /dev/null +++ b/sql/updates/world/2013_02_04_01_world_creature_text.sql @@ -0,0 +1,165 @@ +-- Ragnaros +UPDATE `creature_text` SET `text`='TOO SOON! YOU HAVE AWAKENED ME TOO SOON, EXECUTUS! WHAT IS THE MEANING OF THIS INTRUSION???' WHERE `entry`=11502 AND `groupid`=1; +UPDATE `creature_text` SET `text`='FOOL! YOU ALLOWED THESE INSECTS TO RUN RAMPANT THROUGH THE HALLOWED CORE? AND NOW YOU LEAD THEM TO MY VERY LAIR? YOU HAVE FAILED ME, EXECUTUS! JUSTICE SHALL BE MET, INDEED!' WHERE `entry`=11502 AND `groupid`=3; +UPDATE `creature_text` SET `text`='NOW FOR YOU, INSECTS! BOLDLY, YOU SOUGHT THE POWER OF RAGNAROS. NOW YOU SHALL SEE IT FIRSTHAND!' WHERE `entry`=11502 AND `groupid`=4; +UPDATE `creature_text` SET `text`='DIE, INSECT!' WHERE `entry`=11502 AND `groupid`=9; + +-- Core Rager +UPDATE `creature_text` SET `text`='%s refuses to die while its master is endangered!' WHERE `entry`=11672 AND `groupid`=0; + +-- Morridune +UPDATE `creature_text` SET `text`='Aku''mai is dead! At last, I can leave this wretched place.' WHERE `entry`=6729 AND `groupid`=0; +UPDATE `creature_text` SET `text`='Speak with me to hear my tale.' WHERE `entry`=6729 AND `groupid`=1; + +-- Amnennar the Coldbringer +UPDATE `creature_text` SET `text`='You''ll never leave this place alive.' WHERE `entry`=7358 AND `groupid`=0; +UPDATE `creature_text` SET `text`='Come, spirits - attend your master!' WHERE `entry`=7358 AND `groupid`=2; +UPDATE `creature_text` SET `text`='Too easy.', `type`=12 WHERE `entry`=7358 AND `groupid`=4; + +-- Weegli Blastfuse +UPDATE `creature_text` SET `text`='Oh no! Here they come!' WHERE `entry`=7607 AND `groupid`=0; +UPDATE `creature_text` SET `text`='Ok, here I go!' WHERE `entry`=7607 AND `groupid`=1; + +-- The Prophet Skeram +UPDATE `creature_text` SET `text`='Are you so eager to die? I will be happy to accommodate you...' WHERE `entry`=15263 AND `groupid`=0 AND `id`=0; +UPDATE `creature_text` SET `text`='You only delay the inevitable!' WHERE `entry`=15263 AND `groupid`=3; + +-- Ossirian the Unscarred +UPDATE `creature_text` SET `text`='Sands of the desert, rise and block out the sun!' WHERE `entry`=15339 AND `groupid`=2; + +-- General Rajaxx +UPDATE `creature_text` SET `text`='Warriors, Captains, continue the fight! ' WHERE `entry`=15341 AND `groupid`=9; +UPDATE `creature_text` SET `text`='Breathe your last!' WHERE `entry`=15341 AND `groupid`=11; + +-- Buru the Gorger +UPDATE `creature_text` SET `text`='%s sets eyes on $n!' WHERE `entry`=15370 AND `groupid`=0; + +-- Spectral Stable Hand +UPDATE `creature_text` SET `type`=12 WHERE `entry`=15551 AND `groupid`=0 AND `id`=0; +UPDATE `creature_text` SET `text`='What will become of--' WHERE `entry`=15551 AND `groupid`=0 AND `id`=1; + +-- Medivh +UPDATE `creature_text` SET `text`='The time has come! Gul''dan, order your warlocks to double their efforts! Moments from now the gateway will open and your Horde will be released upon this ripe, unsuspecting world!' WHERE `entry`=15608 AND `groupid`=0; +UPDATE `creature_text` SET `text`='Champions! My shield grows weak!' WHERE `entry`=15608 AND `groupid`=2; +UPDATE `creature_text` SET `text`='No! Damn this feeble, mortal coil!' WHERE `entry`=15608 AND `groupid`=5; +UPDATE `creature_text` SET `text`='I am grateful for your aid, champions. Now, Gul''dan''s Horde will sweep across this world like a locust swarm, and all my designs, all my carefully-laid plans will at last fall into place.' WHERE `entry`=15608 AND `groupid`=6; +UPDATE `creature_text` SET `text`='Orcs of the Horde! This portal is the gateway to your new destiny! Azeroth lies before you, ripe for the taking!' WHERE `entry`=15608 AND `groupid`=7; + +-- Moroes +UPDATE `creature_text` SET `text`='Hm, unannounced visitors. Preparations must be made...' WHERE `entry`=15687 AND `groupid`=0; +UPDATE `creature_text` SET `text`='How terribly clumsy of me.' WHERE `entry`=15687 AND `groupid`=3; + +-- Terestian Illhoof +UPDATE `creature_text` SET `text`='Your blood will anoint my circle!' WHERE `entry`=15688 AND `groupid`=0 AND `id`=0; +UPDATE `creature_text` SET `text`='My life is yours, oh great one...' WHERE `entry`=15688 AND `groupid`=1; +UPDATE `creature_text` SET `text`='Ah, you''re just in time. The rituals are about to begin!' WHERE `entry`=15688 AND `groupid`=2; +UPDATE `creature_text` SET `text`='Please accept this humble offering, oh great one...' WHERE `entry`=15688 AND `groupid`=3 AND `id`=0; +UPDATE `creature_text` SET `text`='Let this sacrifice serve as testament to my fealty.' WHERE `entry`=15688 AND `groupid`=3 AND `id`=1; +UPDATE `creature_text` SET `text`='Come, you dwellers in the dark! Rally to my call!' WHERE `entry`=15688 AND `groupid`=4 AND `id`=0; +UPDATE `creature_text` SET `text`='Gather, my pets... there is plenty for all!' WHERE `entry`=15688 AND `groupid`=4 AND `id`=1; + +-- Prince Malchezaar +UPDATE `creature_text` SET `text`='How can you hope to stand against such overwhelming power?' WHERE `entry`=15690 AND `groupid`=5; +UPDATE `creature_text` SET `text`='I refuse to concede defeat! I am a prince of the Eredar! I... am...' WHERE `entry`=15690 AND `groupid`=8; + +-- The Curator +UPDATE `creature_text` SET `text`='This Curator is equipped for gallery protection.' WHERE `entry`=15691 AND `groupid`=1 AND `id`=1; +UPDATE `creature_text` SET `text`='Curator is no longer operation-a-l.' WHERE `entry`=15691 AND `groupid`=5; + +-- Thaddius +UPDATE `creature_text` SET `text`='You are too late!! I... must... obey!!' WHERE `entry`=15928 AND `groupid`=0; +UPDATE `creature_text` SET `text`='Kill...' WHERE `entry`=15928 AND `groupid`=1 AND `id`=0; +UPDATE `creature_text` SET `text`='Eat... your... bones...' WHERE `entry`=15928 AND `groupid`=1 AND `id`=1; +UPDATE `creature_text` SET `text`='Break... you!!' WHERE `entry`=15928 AND `groupid`=1 AND `id`=2; +UPDATE `creature_text` SET `text`='You... die now!!' WHERE `entry`=15928 AND `groupid`=2; +UPDATE `creature_text` SET `text`='Now you feel pain...' WHERE `entry`=15928 AND `groupid`=3; + +-- Feugen +UPDATE `creature_text` SET `text`='Feugen make master happy.' WHERE `entry`=15930 AND `groupid`=1; + +-- Grand Widow Faerlina +UPDATE `creature_text` SET `text`='Your old lives, your mortal desires mean nothing... you are acolytes of the master now, and you will serve the cause without question! The greatest glory is to die in the master''s service!' WHERE `entry`=15953 AND `groupid`=0; +UPDATE `creature_text` SET `text`='The master will avenge me!!' WHERE `entry`=15953 AND `groupid`=3; + +-- Anub'Rekhan +UPDATE `creature_text` SET `text`='Yes, run! It makes the blood pump faster!' WHERE `entry`=15956 AND `groupid`=0 AND `id`=2; +UPDATE `creature_text` SET `text`='I hear little hearts beating. Yes... beating faster now... soon the beating will stop.' WHERE `entry`=15956 AND `groupid`=1 AND `id`=1; +UPDATE `creature_text` SET `text`='Which one shall I eat first? So difficult to choose. They all smell so delicious...' WHERE `entry`=15956 AND `groupid`=1 AND `id`=3; +UPDATE `creature_text` SET `text`='Closer now. Tasty morsels. I''ve been too long without food, without blood to drink.' WHERE `entry`=15956 AND `groupid`=1 AND `id`=4; +UPDATE `creature_text` SET `text`='Shhh... it will all be over soon.' WHERE `entry`=15956 AND `groupid`=2; + +-- Kel'Thuzad +UPDATE `creature_text` SET `text`='Your forces are nearly marshaled to strike back against your enemies, my liege.' WHERE `entry`=15990 AND `groupid`=0; +UPDATE `creature_text` SET `text`='Yes, master. The time of their ultimate demise draws close.... What is this?' WHERE `entry`=15990 AND `groupid`=2; +UPDATE `creature_text` SET `text`='As you command, master!' WHERE `entry`=15990 AND `groupid`=4; +UPDATE `creature_text` SET `text`='Fools! You think yourselves triumphant? You have only taken one step closer to the abyss!' WHERE `entry`=15990 AND `groupid`=6 AND `id`=1; +UPDATE `creature_text` SET `text`='%s cackles maniacally.', `type`=16 WHERE `entry`=15990 AND `groupid`=8 AND `id`=1; +UPDATE `creature_text` SET `text`='Agghhhh! Do... not... rejoice! Your victory is a hollow one, for I shall return with powers beyond your imagining!' WHERE `entry`=15990 AND `groupid`=9; +UPDATE `creature_text` SET `text`='Your soul is bound to me, now!' WHERE `entry`=15990 AND `groupid`=10 AND `id`=0; +UPDATE `creature_text` SET `text`='Master, I require aid!' WHERE `entry`=15990 AND `groupid`=12; +UPDATE `creature_text` SET `text`='Minions, servants, soldiers of the cold dark! Obey the call of Kel''Thuzad!' WHERE `entry`=15990 AND `groupid`=14; + +-- Patchwerk +UPDATE `creature_text` SET `text`='Kel''thuzad make Patchwerk his avatar of war!' WHERE `entry`=16028 AND `groupid`=0 AND `id`=1; +UPDATE `creature_text` SET `text`='What... happen to-' WHERE `entry`=16028 AND `groupid`=2; +UPDATE `creature_text` SET `text`='%s goes into a frenzy!', `type`=41 WHERE `entry`=16028 AND `groupid`=4; + +-- Spectral Servant +UPDATE `creature_text` SET `type`=12 WHERE `entry`=16407 AND `groupid`=0 AND `id`=0; + +-- Maiden of Virtue +UPDATE `creature_text` SET `text`='Your behavior will not be tolerated.' WHERE `entry`=16457 AND `groupid`=0; + +-- Shade of Aran +UPDATE `creature_text` SET `text`='Please, no more! My son... he''s gone mad!' WHERE `entry`=16524 AND `groupid`=0 AND `id`=0; +UPDATE `creature_text` SET `text`='I''ll show you: this beaten dog still has some teeth!' WHERE `entry`=16524 AND `groupid`=1 AND `id`=0; +UPDATE `creature_text` SET `text`='Burn, you hellish fiends!' WHERE `entry`=16524 AND `groupid`=1 AND `id`=1; +UPDATE `creature_text` SET `text`='Yes, yes my son is quite powerful... but I have powers of my own!' WHERE `entry`=16524 AND `groupid`=3 AND `id`=0; +UPDATE `creature_text` SET `text`='I''m not finished yet! No, I have a few more tricks up my sleeve...', `type`=12 WHERE `entry`=16524 AND `groupid`=5; +UPDATE `creature_text` SET `text`='At last the nightmare is over...' WHERE `entry`=16524 AND `groupid`=8; + +-- Martik Tor'seldori +UPDATE `creature_text` SET `text`='Brothers and sisters, I have been to the promised land. I have tasted in the sublime energy. I have felt bliss - bliss so engrossing and all encompassing that I was left wondering if I had stumbled upon the dreams of gods.' WHERE `entry`=16577 AND `groupid`=0; + +-- Grand Warlock Nethekurse +UPDATE `creature_text` SET `text`='You can have that one, I no longer need him!' WHERE `entry`=16807 AND `groupid`=1 AND `id`=0; +UPDATE `creature_text` SET `text`='Yes, beat him mercilessly! His skull is as thick as an ogre''s!' WHERE `entry`=16807 AND `groupid`=1 AND `id`=1; +UPDATE `creature_text` SET `text`='Don''t waste your time on that one, he''s weak!' WHERE `entry`=16807 AND `groupid`=1 AND `id`=2; +UPDATE `creature_text` SET `text`='One pitiful wretch down. Go on, take another one!' WHERE `entry`=16807 AND `groupid`=2 AND `id`=0; +UPDATE `creature_text` SET `text`='Ah, what a waste... next!' WHERE `entry`=16807 AND `groupid`=2 AND `id`=1; +UPDATE `creature_text` SET `text`='Thank you for saving me the trouble. Now it''s my turn to have some fun!' WHERE `entry`=16807 AND `groupid`=2 AND `id`=3; +UPDATE `creature_text` SET `text`='Beg for your pitiful life!' WHERE `entry`=16807 AND `groupid`=3 AND `id`=0; +UPDATE `creature_text` SET `text`='Run, coward, run! ' WHERE `entry`=16807 AND `groupid`=3 AND `id`=1; -- Blizz fail. +UPDATE `creature_text` SET `text`='Your pain amuses me!' WHERE `entry`=16807 AND `groupid`=3 AND `id`=2; +UPDATE `creature_text` SET `text`='I''m already bored!' WHERE `entry`=16807 AND `groupid`=4 AND `id`=0; +UPDATE `creature_text` SET `text`='Come on, show me a real fight!' WHERE `entry`=16807 AND `groupid`=4 AND `id`=1; +UPDATE `creature_text` SET `text`='I had more fun torturing the peons!' WHERE `entry`=16807 AND `groupid`=4 AND `id`=2; +UPDATE `creature_text` SET `text`='You lose.' WHERE `entry`=16807 AND `groupid`=5 AND `id`=0; +UPDATE `creature_text` SET `text`='Oh, just die!' WHERE `entry`=16807 AND `groupid`=5 AND `id`=1; +UPDATE `creature_text` SET `text`='What... a shame.' WHERE `entry`=16807 AND `groupid`=6; + +-- Warchief Kargath Bladefist +UPDATE `creature_text` SET `text`='Ours is the TRUE Horde! The only Horde!' WHERE `entry`=16808 AND `groupid`=0 AND `id`=0; +UPDATE `creature_text` SET `text`='I am called Bladefist for a reason. As you will see.' WHERE `entry`=16808 AND `groupid`=0 AND `id`=2; +UPDATE `creature_text` SET `text`='I am the ONLY warchief!' WHERE `entry`=16808 AND `groupid`=1 AND `id`=1; +UPDATE `creature_text` SET `text`='The true Horde... will prevail.' WHERE `entry`=16808 AND `groupid`=2; + +-- Barnes +UPDATE `creature_text` SET `text`='Welcome ladies and gentlemen, to this evening''s presentation!' WHERE `entry`=16812 AND `groupid`=0; +UPDATE `creature_text` SET `text`='Tonight we plumb the depths of the human soul as we join a lost, lonely girl trying desperately--with the help of her loyal companions--to find her way home!' WHERE `entry`=16812 AND `groupid`=1; +UPDATE `creature_text` SET `text`='But she is pursued... by a wicked, malevolent crone!' WHERE `entry`=16812 AND `groupid`=2; +UPDATE `creature_text` SET `text`='Will she survive? Will she prevail? Only time will tell. And now... on with the show!' WHERE `entry`=16812 AND `groupid`=3; +UPDATE `creature_text` SET `text`='Good evening ladies and gentlemen, welcome to this evening''s presentation!' WHERE `entry`=16812 AND `groupid`=4; +UPDATE `creature_text` SET `text`='Tonight, things are not what they seem... for tonight your eyes may not be trusted!' WHERE `entry`=16812 AND `groupid`=5; +UPDATE `creature_text` SET `text`='Take for instance this quiet elderly woman waiting for a visit from her granddaughter... surely there is nothing to fear from this sweet, gray-haired old lady!' WHERE `entry`=16812 AND `groupid`=6; +UPDATE `creature_text` SET `text`='But don''t let me pull the wool over your eyes! See for yourself what lies beneath those covers! And now... on with the show!' WHERE `entry`=16812 AND `groupid`=7; +UPDATE `creature_text` SET `text`='Welcome ladies and gentlemen, to this evening''s presentation!' WHERE `entry`=16812 AND `groupid`=8; +UPDATE `creature_text` SET `text`='Tonight... we explore a tale of forbidden love!' WHERE `entry`=16812 AND `groupid`=9; +UPDATE `creature_text` SET `text`='But beware, for not all love stories end happily, as you may find out. Sometimes, love pricks like a thorn!' WHERE `entry`=16812 AND `groupid`=10; +UPDATE `creature_text` SET `text`='But don''t take it from me; see for yourself what tragedy lies ahead when the paths of star crossed lovers meet! And now... on with the show!' WHERE `entry`=16812 AND `groupid`=11; + +-- Shadow Council Enforcer +UPDATE `creature_text` SET `text`='Gul''dan speaks the truth! We should return at once to tell our brothers of the news! Retreat back through the portal!', `type`=14 WHERE `entry`=17023 AND `groupid`=0; + +-- Nightbane +UPDATE `creature_text` SET `text`='%s takes a deep breath.', `type`=41 WHERE `entry`=17225 AND `groupid`=4; -- 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 'sql/updates') 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 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 'sql/updates') 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 'sql/updates') 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 30e1516387809e2ce255c36c182dc4774997acf5 Mon Sep 17 00:00:00 2001 From: Gacko Date: Mon, 4 Feb 2013 16:43:12 +0100 Subject: Rename sql files of 760d62e934f8289cdd9950c04a4dbf588eddd742 --- sql/updates/auth/2013_02_04_01_auth_account.sql | 3 +++ sql/updates/auth/2013_xx_xx_00_auth_account.sql | 3 --- sql/updates/world/2013_02_04_04_world_trinity_string.sql | 4 ++++ sql/updates/world/2013_xx_xx_00_world_trinity_string.sql | 4 ---- 4 files changed, 7 insertions(+), 7 deletions(-) create mode 100644 sql/updates/auth/2013_02_04_01_auth_account.sql delete mode 100644 sql/updates/auth/2013_xx_xx_00_auth_account.sql create mode 100644 sql/updates/world/2013_02_04_04_world_trinity_string.sql delete mode 100644 sql/updates/world/2013_xx_xx_00_world_trinity_string.sql (limited to 'sql/updates') diff --git a/sql/updates/auth/2013_02_04_01_auth_account.sql b/sql/updates/auth/2013_02_04_01_auth_account.sql new file mode 100644 index 00000000000..9af73d41ee3 --- /dev/null +++ b/sql/updates/auth/2013_02_04_01_auth_account.sql @@ -0,0 +1,3 @@ +ALTER TABLE `account` + ADD COLUMN `mutereason` VARCHAR(255) NOT NULL DEFAULT '' AFTER `mutetime`, + ADD COLUMN `muteby` VARCHAR(50) NOT NULL DEFAULT '' AFTER `mutereason`; diff --git a/sql/updates/auth/2013_xx_xx_00_auth_account.sql b/sql/updates/auth/2013_xx_xx_00_auth_account.sql deleted file mode 100644 index 9af73d41ee3..00000000000 --- a/sql/updates/auth/2013_xx_xx_00_auth_account.sql +++ /dev/null @@ -1,3 +0,0 @@ -ALTER TABLE `account` - ADD COLUMN `mutereason` VARCHAR(255) NOT NULL DEFAULT '' AFTER `mutetime`, - ADD COLUMN `muteby` VARCHAR(50) NOT NULL DEFAULT '' AFTER `mutereason`; diff --git a/sql/updates/world/2013_02_04_04_world_trinity_string.sql b/sql/updates/world/2013_02_04_04_world_trinity_string.sql new file mode 100644 index 00000000000..0a4ec437b28 --- /dev/null +++ b/sql/updates/world/2013_02_04_04_world_trinity_string.sql @@ -0,0 +1,4 @@ +DELETE FROM `trinity_string` WHERE entry IN (300,550); +INSERT INTO `trinity_string` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES +('300','Your chat has been disabled for %u minutes. By: %s ,Reason: %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +('550','Mute time remaining: %s, By: %s, Reason: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); diff --git a/sql/updates/world/2013_xx_xx_00_world_trinity_string.sql b/sql/updates/world/2013_xx_xx_00_world_trinity_string.sql deleted file mode 100644 index 0a4ec437b28..00000000000 --- a/sql/updates/world/2013_xx_xx_00_world_trinity_string.sql +++ /dev/null @@ -1,4 +0,0 @@ -DELETE FROM `trinity_string` WHERE entry IN (300,550); -INSERT INTO `trinity_string` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES -('300','Your chat has been disabled for %u minutes. By: %s ,Reason: %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), -('550','Mute time remaining: %s, By: %s, Reason: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); -- 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 'sql/updates') 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 From fb7a544d842c1c3dcdf24c1f82b192d8ca20d18c Mon Sep 17 00:00:00 2001 From: Spp Date: Mon, 4 Feb 2013 17:04:40 +0100 Subject: Correction to previous commit (Use proper way to delete from spell_script_names) --- sql/updates/world/2013_02_04_05_world_spell_script_names.sql | 2 +- src/server/game/DungeonFinding/LFGScripts.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'sql/updates') 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 index 055e4b1d77d..4dd5ee52583 100644 --- 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 @@ -1 +1 @@ -DELETE FROM `spell_script_names` WHERE `spell_id`=72221; +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_gen_luck_of_the_draw'; diff --git a/src/server/game/DungeonFinding/LFGScripts.cpp b/src/server/game/DungeonFinding/LFGScripts.cpp index 46a4ed4a134..a4716de9524 100644 --- a/src/server/game/DungeonFinding/LFGScripts.cpp +++ b/src/server/game/DungeonFinding/LFGScripts.cpp @@ -102,7 +102,7 @@ void LFGPlayerScript::OnMapChanged(Player* player) 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)) + else player->RemoveAurasDueToSpell(LFG_SPELL_LUCK_OF_THE_DRAW); } -- cgit v1.2.3 From 8f6e9dc85ccda388bc5ced1921cd4e30cb5fe2e0 Mon Sep 17 00:00:00 2001 From: Nay Date: Mon, 4 Feb 2013 20:25:18 +0000 Subject: DB/Commands: Fix RBAC commands (remove an extra dot) --- sql/updates/world/2013_02_04_06_world_command.sql | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 sql/updates/world/2013_02_04_06_world_command.sql (limited to 'sql/updates') diff --git a/sql/updates/world/2013_02_04_06_world_command.sql b/sql/updates/world/2013_02_04_06_world_command.sql new file mode 100644 index 00000000000..fb36c512c4a --- /dev/null +++ b/sql/updates/world/2013_02_04_06_world_command.sql @@ -0,0 +1,15 @@ +UPDATE `command` SET `name` = 'rbac account' WHERE `name` LIKE '.rbac account'; +UPDATE `command` SET `name` = 'rbac account group' WHERE `name` LIKE '.rbac account group'; +UPDATE `command` SET `name` = 'rbac account group add' WHERE `name` LIKE '.rbac account group add'; +UPDATE `command` SET `name` = 'rbac account group remove' WHERE `name` LIKE '.rbac account group remove'; +UPDATE `command` SET `name` = 'rbac account permission' WHERE `name` LIKE '.rbac account permission'; +UPDATE `command` SET `name` = 'rbac account permission deny' WHERE `name` LIKE '.rbac account permission deny'; +UPDATE `command` SET `name` = 'rbac account permission grant' WHERE `name` LIKE '.rbac account permission grant'; +UPDATE `command` SET `name` = 'rbac account permission revoke' WHERE `name` LIKE '.rbac account permission revoke'; +UPDATE `command` SET `name` = 'rbac account role' WHERE `name` LIKE '.rbac account role'; +UPDATE `command` SET `name` = 'rbac account role deny' WHERE `name` LIKE '.rbac account role deny'; +UPDATE `command` SET `name` = 'rbac account role grant' WHERE `name` LIKE '.rbac account role grant'; +UPDATE `command` SET `name` = 'rbac account role revoke' WHERE `name` LIKE '.rbac account role revoke'; +UPDATE `command` SET `name` = 'rbac list groups' WHERE `name` LIKE '.rbac list groups'; +UPDATE `command` SET `name` = 'rbac list permissions' WHERE `name` LIKE '.rbac list permissions'; +UPDATE `command` SET `name` = 'rbac list roles' WHERE `name` LIKE '.rbac list roles'; -- cgit v1.2.3