diff options
61 files changed, 1103 insertions, 310 deletions
diff --git a/sql/updates/auth/2013_02_25_00_auth_misc.sql b/sql/updates/auth/2013_02_25_00_auth_misc.sql new file mode 100644 index 00000000000..5531252037a --- /dev/null +++ b/sql/updates/auth/2013_02_25_00_auth_misc.sql @@ -0,0 +1,18 @@ +-- Add new permission +DELETE FROM `rbac_permissions` WHERE `id` = 11; +INSERT INTO `rbac_permissions` (`id`, `name`) VALUES (11, 'Log GM trades'); + +-- Add new role +DELETE FROM `rbac_roles` WHERE `id` = 8; +INSERT INTO `rbac_roles` (`id`, `name`) VALUES (8, 'Log GM trades'); + +-- Add the permission to the role +DELETE FROM `rbac_role_permissions` WHERE `roleId` = 8; +INSERT INTO `rbac_role_permissions` (`roleId`, `permissionId`) VALUES (8, 11); + +-- Add it to all GM+ groups +DELETE FROM `rbac_group_roles` WHERE `roleId` = 8; +INSERT INTO `rbac_group_roles` (`groupId`, `roleId`) VALUES +(2, 8), +(3, 8), +(4, 8); diff --git a/sql/updates/auth/2013_02_25_01_auth_misc.sql b/sql/updates/auth/2013_02_25_01_auth_misc.sql new file mode 100644 index 00000000000..f5cb6c01d19 --- /dev/null +++ b/sql/updates/auth/2013_02_25_01_auth_misc.sql @@ -0,0 +1,18 @@ +-- Add new permission +DELETE FROM `rbac_permissions` WHERE `id` = 13; +INSERT INTO `rbac_permissions` (`id`, `name`) VALUES (13, 'Skip Instance required bosses check'); + +-- Add new role +DELETE FROM `rbac_roles` WHERE `id` = 9; +INSERT INTO `rbac_roles` (`id`, `name`) VALUES (9, 'Skip Instance required bosses check'); + +-- Add the permission to the role +DELETE FROM `rbac_role_permissions` WHERE `roleId` = 9; +INSERT INTO `rbac_role_permissions` (`roleId`, `permissionId`) VALUES (9, 13); + +-- Add it to all GM+ groups +DELETE FROM `rbac_group_roles` WHERE `roleId` = 9; +INSERT INTO `rbac_group_roles` (`groupId`, `roleId`) VALUES +(2, 9), +(3, 9), +(4, 9); diff --git a/sql/updates/auth/2013_02_25_02_auth_misc.sql b/sql/updates/auth/2013_02_25_02_auth_misc.sql new file mode 100644 index 00000000000..11e235c91d9 --- /dev/null +++ b/sql/updates/auth/2013_02_25_02_auth_misc.sql @@ -0,0 +1,18 @@ +-- Add new permission +DELETE FROM `rbac_permissions` WHERE `id` = 32; +INSERT INTO `rbac_permissions` (`id`, `name`) VALUES (32, 'Can be assigned tickets with .assign ticket command'); + +-- Add new role +DELETE FROM `rbac_roles` WHERE `id` = 10; +INSERT INTO `rbac_roles` (`id`, `name`) VALUES (10, 'Ticket management'); + +-- Add the permission to the role +DELETE FROM `rbac_role_permissions` WHERE `roleId` = 10; +INSERT INTO `rbac_role_permissions` (`roleId`, `permissionId`) VALUES (10, 32); + +-- Add it to all GM+ groups +DELETE FROM `rbac_group_roles` WHERE `roleId` = 10; +INSERT INTO `rbac_group_roles` (`groupId`, `roleId`) VALUES +(2, 10), +(3, 10), +(4, 10); diff --git a/sql/updates/auth/2013_02_25_03_auth_misc.sql b/sql/updates/auth/2013_02_25_03_auth_misc.sql new file mode 100644 index 00000000000..ab2c6e0692c --- /dev/null +++ b/sql/updates/auth/2013_02_25_03_auth_misc.sql @@ -0,0 +1,33 @@ +-- Add new permissions +DELETE FROM `rbac_permissions` WHERE `id` IN (30, 31, 38); +INSERT INTO `rbac_permissions` (`id`, `name`) VALUES +(30, 'Save character without delay with .save command'), +(31, 'Use params with .unstuck command'), +(38, 'Resurrect with full Health Points'); + +-- Add new role +DELETE FROM `rbac_roles` WHERE `id` IN (11, 12, 13); +INSERT INTO `rbac_roles` (`id`, `name`) VALUES +(11, 'Instant .save'), +(12, 'Allow params with .unstuck'), +(13, 'Full HP after resurrect'); + +-- Add the permission to the role +DELETE FROM `rbac_role_permissions` WHERE `roleId` IN (11, 12, 13); +INSERT INTO `rbac_role_permissions` (`roleId`, `permissionId`) VALUES +(11, 30), +(12, 31), +(13, 38); + +-- Add it to all GM+ groups +DELETE FROM `rbac_role_permissions` WHERE `roleId` IN (11, 12, 13); +INSERT INTO `rbac_group_roles` (`groupId`, `roleId`) VALUES +(2, 11), +(3, 11), +(4, 11), +(2, 12), +(3, 12), +(4, 12), +(2, 13), +(3, 13), +(4, 13); diff --git a/sql/updates/auth/2013_02_25_04_auth_misc.sql b/sql/updates/auth/2013_02_25_04_auth_misc.sql new file mode 100644 index 00000000000..faaee3582ea --- /dev/null +++ b/sql/updates/auth/2013_02_25_04_auth_misc.sql @@ -0,0 +1,27 @@ +-- Add new permissions +DELETE FROM `rbac_permissions` WHERE `id` IN (34, 37); +INSERT INTO `rbac_permissions` (`id`, `name`) VALUES +(34, 'Check if should appear in list using .gm ingame command'), +(37, 'Use staff badge in chat'); + +-- Add new role +DELETE FROM `rbac_roles` WHERE `id` IN (14, 15); +INSERT INTO `rbac_roles` (`id`, `name`) VALUES +(14, 'Appear in GM ingame list'), +(15, 'Use staff badge in chat'); + +-- Add the permission to the role +DELETE FROM `rbac_role_permissions` WHERE `roleId` IN (14, 15); +INSERT INTO `rbac_role_permissions` (`roleId`, `permissionId`) VALUES +(14, 34), +(15, 37); + +-- Add it to all GM+ groups +DELETE FROM `rbac_role_permissions` WHERE `roleId` IN (14, 15); +INSERT INTO `rbac_group_roles` (`groupId`, `roleId`) VALUES +(2, 14), +(3, 14), +(4, 14), +(2, 15), +(3, 15), +(4, 15); diff --git a/sql/updates/auth/2013_02_25_05_auth_misc.sql b/sql/updates/auth/2013_02_25_05_auth_misc.sql new file mode 100644 index 00000000000..e3ee3f00572 --- /dev/null +++ b/sql/updates/auth/2013_02_25_05_auth_misc.sql @@ -0,0 +1,18 @@ +-- Add new permission +DELETE FROM `rbac_permissions` WHERE `id` = 44; +INSERT INTO `rbac_permissions` (`id`, `name`) VALUES (44, 'Receive global GM messages/texts'); + +-- Add new role +DELETE FROM `rbac_roles` WHERE `id` = 16; +INSERT INTO `rbac_roles` (`id`, `name`) VALUES (16, 'Receive global GM messages/texts'); + +-- Add the permission to the role +DELETE FROM `rbac_role_permissions` WHERE `roleId` = 16; +INSERT INTO `rbac_role_permissions` (`roleId`, `permissionId`) VALUES (16, 44); + +-- Add it to all GM+ groups +DELETE FROM `rbac_group_roles` WHERE `roleId` = 16; +INSERT INTO `rbac_group_roles` (`groupId`, `roleId`) VALUES +(2, 16), +(3, 16), +(4, 16); diff --git a/sql/updates/auth/2013_02_25_06_auth_misc.sql b/sql/updates/auth/2013_02_25_06_auth_misc.sql new file mode 100644 index 00000000000..92eae3d782d --- /dev/null +++ b/sql/updates/auth/2013_02_25_06_auth_misc.sql @@ -0,0 +1,18 @@ +-- Add new permission +DELETE FROM `rbac_permissions` WHERE `id` = 23; +INSERT INTO `rbac_permissions` (`id`, `name`) VALUES (23, 'Skip over-speed ping check'); + +-- Add new role +DELETE FROM `rbac_roles` WHERE `id` = 17; +INSERT INTO `rbac_roles` (`id`, `name`) VALUES (17, 'Skip over-speed ping check'); + +-- Add the permission to the role +DELETE FROM `rbac_role_permissions` WHERE `roleId` = 17; +INSERT INTO `rbac_role_permissions` (`roleId`, `permissionId`) VALUES (17, 23); + +-- Add it to all GM+ groups +DELETE FROM `rbac_group_roles` WHERE `roleId` = 17; +INSERT INTO `rbac_group_roles` (`groupId`, `roleId`) VALUES +(2, 17), +(3, 17), +(4, 17); diff --git a/sql/updates/auth/2013_02_25_07_auth_misc.sql b/sql/updates/auth/2013_02_25_07_auth_misc.sql new file mode 100644 index 00000000000..2416f08280c --- /dev/null +++ b/sql/updates/auth/2013_02_25_07_auth_misc.sql @@ -0,0 +1,21 @@ +-- Add new permissions +DELETE FROM `rbac_permissions` WHERE `id` IN (42, 43); +INSERT INTO `rbac_permissions` (`id`, `name`) VALUES +(42, 'Allows to use CMSG_WORLD_TELEPORT opcode'), +(43, 'Allows to use CMSG_WHOIS opcode'); + +-- Add new role +DELETE FROM `rbac_roles` WHERE `id` = 18; +INSERT INTO `rbac_roles` (`id`, `name`) VALUES +(18, 'Allows Admin Opcodes'); + +-- Add the permission to the role +DELETE FROM `rbac_role_permissions` WHERE `roleId` = 18; +INSERT INTO `rbac_role_permissions` (`roleId`, `permissionId`) VALUES +(18, 42), +(18, 43); + +-- Add it to all GM+ groups +DELETE FROM `rbac_role_permissions` WHERE `roleId` = 18; +INSERT INTO `rbac_group_roles` (`groupId`, `roleId`) VALUES +(4, 18); diff --git a/sql/updates/auth/2013_02_25_08_auth_misc.sql b/sql/updates/auth/2013_02_25_08_auth_misc.sql new file mode 100644 index 00000000000..244b1848d0c --- /dev/null +++ b/sql/updates/auth/2013_02_25_08_auth_misc.sql @@ -0,0 +1,19 @@ +-- Add new permission +DELETE FROM `rbac_permissions` WHERE `id` = 27; +INSERT INTO `rbac_permissions` (`id`, `name`) VALUES (27, 'Two side mail interaction'); + +-- Add new role +DELETE FROM `rbac_roles` WHERE `id` = 19; +INSERT INTO `rbac_roles` (`id`, `name`) VALUES (19, 'Two side mail interaction'); + +-- Add the permission to the role +DELETE FROM `rbac_role_permissions` WHERE `roleId` = 19; +INSERT INTO `rbac_role_permissions` (`roleId`, `permissionId`) VALUES (19, 27); + +-- Add it to all GM+ groups +DELETE FROM `rbac_group_roles` WHERE `roleId` = 19; +INSERT INTO `rbac_group_roles` (`groupId`, `roleId`) VALUES +(1, 19), +(2, 19), +(3, 19), +(4, 19); diff --git a/sql/updates/auth/2013_02_25_09_auth_misc.sql b/sql/updates/auth/2013_02_25_09_auth_misc.sql new file mode 100644 index 00000000000..f2affe05b70 --- /dev/null +++ b/sql/updates/auth/2013_02_25_09_auth_misc.sql @@ -0,0 +1,27 @@ +-- Add new permissions +DELETE FROM `rbac_permissions` WHERE `id` IN (33, 47); +INSERT INTO `rbac_permissions` (`id`, `name`) VALUES +(33, 'Notify if a command was not found'), +(47, 'Enables lower security than target check'); + +-- Add new role +DELETE FROM `rbac_roles` WHERE `id` IN (20, 21); +INSERT INTO `rbac_roles` (`id`, `name`) VALUES +(20, 'Notify if a command was not found'), +(21, 'Enables lower security than target check'); + +-- Add the permission to the role +DELETE FROM `rbac_role_permissions` WHERE `roleId` IN (20, 21); +INSERT INTO `rbac_role_permissions` (`roleId`, `permissionId`) VALUES +(20, 33), +(21, 47); + +-- Add it to all GM+ groups +DELETE FROM `rbac_role_permissions` WHERE `roleId` IN (20, 21); +INSERT INTO `rbac_group_roles` (`groupId`, `roleId`) VALUES +(2, 20), +(3, 20), +(4, 20), +(2, 21), +(3, 21), +(4, 21); diff --git a/sql/updates/auth/2013_02_25_10_auth_misc.sql b/sql/updates/auth/2013_02_25_10_auth_misc.sql new file mode 100644 index 00000000000..4255bdac8ba --- /dev/null +++ b/sql/updates/auth/2013_02_25_10_auth_misc.sql @@ -0,0 +1,43 @@ +-- Add new permissions +DELETE FROM `rbac_permissions` WHERE `id` IN (20, 21, 22, 39, 41); +INSERT INTO `rbac_permissions` (`id`, `name`) VALUES +(20, 'Skip disable map check'), +(21, 'Skip reset talents when used more than allowed check'), +(22, 'Skip spam chat check'), +(39, 'Restore saved gm setting states'), +(41, 'Use Config option START_GM_LEVEL to assign new character level'); + +-- Add new role +DELETE FROM `rbac_roles` WHERE `id` IN (22, 23, 24, 25, 26); +INSERT INTO `rbac_roles` (`id`, `name`) VALUES +(22, 'Skip disable map check'), +(23, 'Skip reset talents when used more than allowed check'), +(24, 'Skip spam chat check'), +(25, 'Restore saved gm setting states'), +(26, 'Use Config option START_GM_LEVEL to assign new character level'); + +-- Add the permission to the role +DELETE FROM `rbac_role_permissions` WHERE `roleId` IN (22, 23, 24, 25, 26); +INSERT INTO `rbac_role_permissions` (`roleId`, `permissionId`) VALUES +(22, 20), +(23, 21), +(24, 22), +(25, 39), +(26, 41); + +-- Add it to all GM+ groups +DELETE FROM `rbac_role_permissions` WHERE `roleId` IN (22, 23, 24, 25, 26); +INSERT INTO `rbac_group_roles` (`groupId`, `roleId`) VALUES +(2, 22), +(3, 22), +(4, 22), +(4, 23), +(2, 24), +(3, 24), +(4, 24), +(2, 25), +(3, 25), +(4, 25), +(2, 26), +(3, 26), +(4, 26); diff --git a/sql/updates/auth/2013_02_25_11_auth_misc.sql b/sql/updates/auth/2013_02_25_11_auth_misc.sql new file mode 100644 index 00000000000..9c2897394e5 --- /dev/null +++ b/sql/updates/auth/2013_02_25_11_auth_misc.sql @@ -0,0 +1,34 @@ +-- Add new permissions +DELETE FROM `rbac_permissions` WHERE `id` IN (19, 25, 36); +INSERT INTO `rbac_permissions` (`id`, `name`) VALUES +(19, 'Skips needed requirements to use channel check'), +(25, 'Allow say chat between factions'), +(36, 'Filter whispers'); + +-- Add new role +DELETE FROM `rbac_roles` WHERE `id` IN (27, 28, 29); +INSERT INTO `rbac_roles` (`id`, `name`) VALUES +(27, 'Skips needed requirements to use channel check'), +(28, 'Allow say chat between factions'), +(29, 'Filter whispers'); + +-- Add the permission to the role +DELETE FROM `rbac_role_permissions` WHERE `roleId` IN (27, 28, 29); +INSERT INTO `rbac_role_permissions` (`roleId`, `permissionId`) VALUES +(27, 19), +(28, 25), +(29, 36); + +-- Add it to all GM+ groups +DELETE FROM `rbac_role_permissions` WHERE `roleId` IN (27, 28, 29); +INSERT INTO `rbac_group_roles` (`groupId`, `roleId`) VALUES +(2, 27), +(3, 27), +(4, 27), +(1, 28), +(2, 28), +(3, 28), +(4, 28), +(2, 29), +(3, 29), +(4, 29); diff --git a/sql/updates/auth/2013_02_25_12_auth_misc.sql b/sql/updates/auth/2013_02_25_12_auth_misc.sql new file mode 100644 index 00000000000..2b394dc9bcb --- /dev/null +++ b/sql/updates/auth/2013_02_25_12_auth_misc.sql @@ -0,0 +1,34 @@ +-- Add new permissions +DELETE FROM `rbac_permissions` WHERE `id` IN (26, 45, 46); +INSERT INTO `rbac_permissions` (`id`, `name`) VALUES +(26, 'Allow channel chat between factions'), +(45, 'Join channels without announce'), +(46, 'Change channel settings without being channel moderator'); + +-- Add new role +DELETE FROM `rbac_roles` WHERE `id` IN (30, 31, 32); +INSERT INTO `rbac_roles` (`id`, `name`) VALUES +(30, 'Allow channel chat between factions'), +(31, 'Join channels without announce'), +(32, 'Change channel settings without being channel moderator'); + +-- Add the permission to the role +DELETE FROM `rbac_role_permissions` WHERE `roleId` IN (30, 31, 32); +INSERT INTO `rbac_role_permissions` (`roleId`, `permissionId`) VALUES +(30, 26), +(31, 45), +(32, 46); + +-- Add it to all GM+ groups +DELETE FROM `rbac_role_permissions` WHERE `roleId` IN (30, 31, 32); +INSERT INTO `rbac_group_roles` (`groupId`, `roleId`) VALUES +(1, 30), +(2, 30), +(3, 30), +(4, 30), +(2, 31), +(3, 31), +(4, 31), +(2, 32), +(3, 32), +(4, 32); diff --git a/sql/updates/auth/2013_02_25_13_auth_misc.sql b/sql/updates/auth/2013_02_25_13_auth_misc.sql new file mode 100644 index 00000000000..82247ecd07d --- /dev/null +++ b/sql/updates/auth/2013_02_25_13_auth_misc.sql @@ -0,0 +1,36 @@ +-- Add new permissions +DELETE FROM `rbac_permissions` WHERE `id` IN (14, 15, 16, 17, 18, 24); +INSERT INTO `rbac_permissions` (`id`, `name`) VALUES +(14, 'Skips character creation team mask check'), +(15, 'Skips character creation class mask check'), +(16, 'Skips character creation race mask check'), +(17, 'Skips character creation reserved name check'), +(18, 'Skips character creation heroic min level check'), +(24, 'Creation of two side faction characters in same account'); + +-- Add new role +DELETE FROM `rbac_roles` WHERE `id` IN (33, 34); +INSERT INTO `rbac_roles` (`id`, `name`) VALUES +(33, 'Skips character creation checks'), +(34, 'Creation of two side faction characters in same account'); + +-- Add the permission to the role +DELETE FROM `rbac_role_permissions` WHERE `roleId` IN (33, 34); +INSERT INTO `rbac_role_permissions` (`roleId`, `permissionId`) VALUES +(33, 14), +(33, 15), +(33, 16), +(33, 17), +(33, 18), +(34, 24); + +-- Add it to all groups +DELETE FROM `rbac_role_permissions` WHERE `roleId` IN (33, 34); +INSERT INTO `rbac_group_roles` (`groupId`, `roleId`) VALUES +(2, 33), +(3, 33), +(4, 33), +(2, 34), +(3, 34), +(4, 34); + diff --git a/sql/updates/auth/2013_02_25_14_auth_misc.sql b/sql/updates/auth/2013_02_25_14_auth_misc.sql new file mode 100644 index 00000000000..c02b600b12f --- /dev/null +++ b/sql/updates/auth/2013_02_25_14_auth_misc.sql @@ -0,0 +1,39 @@ +-- Add new permissions +DELETE FROM `rbac_permissions` WHERE `id` IN (28, 29, 35, 40); +INSERT INTO `rbac_permissions` (`id`, `name`) VALUES +(28, 'See two side who list'), +(29, 'Add friends of other faction'), +(35, 'See all security levels with who command'), +(40, 'Allows to add a gm to friend list'); + +-- Add new role +DELETE FROM `rbac_roles` WHERE `id` IN (33, 34); +INSERT INTO `rbac_roles` (`id`, `name`) VALUES +(35, 'See two side who list'), +(36, 'Add friends of other faction'), +(37, 'See all security levels with who command'), +(38, 'Allows to add a gm to friend list'); + +-- Add the permission to the role +DELETE FROM `rbac_role_permissions` WHERE `roleId` IN (35, 36, 37, 38); +INSERT INTO `rbac_role_permissions` (`roleId`, `permissionId`) VALUES +(35, 28), +(36, 29), +(37, 35), +(38, 40); + +-- Add it to all groups +DELETE FROM `rbac_role_permissions` WHERE `roleId` IN (35, 36, 37, 38); +INSERT INTO `rbac_group_roles` (`groupId`, `roleId`) VALUES +(2, 35), +(3, 35), +(4, 35), +(2, 36), +(3, 36), +(4, 36), +(2, 37), +(3, 37), +(4, 37), +(2, 38), +(3, 38), +(4, 38); diff --git a/sql/updates/world/2013_02_24_00_world_creature_summon_groups.sql b/sql/updates/world/2013_02_24_00_world_creature_summon_groups.sql new file mode 100644 index 00000000000..409f79bb2aa --- /dev/null +++ b/sql/updates/world/2013_02_24_00_world_creature_summon_groups.sql @@ -0,0 +1,16 @@ +DROP TABLE IF EXISTS `creature_summon_groups`; +/*!40101 SET @saved_cs_client     = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `creature_summon_groups` ( +  `summonerId` mediumint(8) unsigned NOT NULL DEFAULT '0', +  `summonerType` tinyint(3) unsigned NOT NULL DEFAULT '0', +  `groupId` tinyint(3) unsigned NOT NULL DEFAULT '0', +  `entry` mediumint(8) unsigned NOT NULL DEFAULT '0', +  `position_x` float NOT NULL DEFAULT '0', +  `position_y` float NOT NULL DEFAULT '0', +  `position_z` float NOT NULL DEFAULT '0', +  `orientation` float NOT NULL DEFAULT '0', +  `summonType` tinyint(3) unsigned NOT NULL DEFAULT '0', +  `summonTime` int(10) unsigned NOT NULL DEFAULT '0' +) ENGINE=MyISAM DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; diff --git a/sql/updates/world/2013_02_24_01_world_areatrigger_scripts.sql b/sql/updates/world/2013_02_24_01_world_areatrigger_scripts.sql new file mode 100644 index 00000000000..2aebe1d2edd --- /dev/null +++ b/sql/updates/world/2013_02_24_01_world_areatrigger_scripts.sql @@ -0,0 +1,3 @@ +DELETE FROM `areatrigger_scripts` WHERE `entry`=5173; +INSERT INTO `areatrigger_scripts`(`entry`,`ScriptName`) VALUE +(5173,'at_frostgrips_hollow'); diff --git a/sql/updates/world/2013_02_24_02_world_smart_scripts.sql b/sql/updates/world/2013_02_24_02_world_smart_scripts.sql new file mode 100644 index 00000000000..7b41c82b6fa --- /dev/null +++ b/sql/updates/world/2013_02_24_02_world_smart_scripts.sql @@ -0,0 +1,7 @@ +DELETE FROM `smart_scripts` WHERE `entryorguid`=29861 AND `source_type`=0; +INSERT INTO `smart_scripts`(`entryorguid`,`source_type`,`event_type`,`action_type`,`action_param1`,`action_param2`,`target_type`,`comment`) VALUES +(29861,0,54,80,2986100,2,1,'Stormforged Eradictor - Just summoned - Call timed actionlist 2986100'); + +DELETE FROM `smart_scripts` WHERE `entryorguid`=2986100 AND `source_type`=9; +INSERT INTO `smart_scripts`(`entryorguid`,`source_type`,`id`,`event_param1`,`event_param2`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`target_type`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUE +(2986100,9,0,10000,10000,12,29729,4,10000,8,6972.13,14.24,805.79,3.349,'Stormforged Eradictor - Timed actionlist - Summon Frostborn Axemaster'); diff --git a/sql/updates/world/2013_02_24_03_world_waypoint_data.sql b/sql/updates/world/2013_02_24_03_world_waypoint_data.sql new file mode 100644 index 00000000000..e97f0758304 --- /dev/null +++ b/sql/updates/world/2013_02_24_03_world_waypoint_data.sql @@ -0,0 +1,11 @@ +DELETE FROM `waypoint_data` WHERE `id`=2986200; +INSERT INTO `waypoint_data`(`id`,`point`,`position_x`,`position_y`,`position_z`) VALUES +(2986200,0,6963.95,45.65,818.71), +(2986200,1,6965.09,39.67,820.15), +(2986200,2,6963.56,21.14,805.79); + +DELETE FROM `waypoint_data` WHERE `id`=2986100; +INSERT INTO `waypoint_data`(`id`,`point`,`position_x`,`position_y`,`position_z`) VALUES +(2986100,0,6983.18,7.150,806.33), +(2986100,1,6975.37,16.73,804.98), +(2986100,2,6967.15,13.27,806.56); diff --git a/sql/updates/world/2013_02_24_04_world_creature_template.sql b/sql/updates/world/2013_02_24_04_world_creature_template.sql new file mode 100644 index 00000000000..c9acc0d2a1a --- /dev/null +++ b/sql/updates/world/2013_02_24_04_world_creature_template.sql @@ -0,0 +1,2 @@ +UPDATE `creature_template` SET `faction_A`=1954,`faction_H`=1954,`AIName`='SmartAI' WHERE `entry`=29861; +UPDATE `creature_template` SET `faction_A`=1954,`faction_H`=1954 WHERE `entry`=29862; diff --git a/src/server/game/AI/CoreAI/UnitAI.cpp b/src/server/game/AI/CoreAI/UnitAI.cpp index 7f0d387c2f1..e0e9e68315d 100644 --- a/src/server/game/AI/CoreAI/UnitAI.cpp +++ b/src/server/game/AI/CoreAI/UnitAI.cpp @@ -146,8 +146,7 @@ void UnitAI::DoCast(uint32 spellId)              float range = spellInfo->GetMaxRange(false);              DefaultTargetSelector targetSelector(me, range, playerOnly, -(int32)spellId); -            if (!(spellInfo->Attributes & SPELL_ATTR0_BREAKABLE_BY_DAMAGE) -                && !(spellInfo->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_VICTIM) +            if (!(spellInfo->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_VICTIM)                  && targetSelector(me->getVictim()))                  target = me->getVictim();              else diff --git a/src/server/game/Accounts/AccountMgr.cpp b/src/server/game/Accounts/AccountMgr.cpp index 596f7f5ceb9..7172efaac0e 100644 --- a/src/server/game/Accounts/AccountMgr.cpp +++ b/src/server/game/Accounts/AccountMgr.cpp @@ -544,3 +544,16 @@ RBACPermission const* AccountMgr::GetRBACPermission(uint32 permission) const      return NULL;  } + +bool AccountMgr::HasPermission(uint32 accountId, uint32 permission, uint32 realmId) +{ +    if (!accountId) +        return false; + +    RBACData* rbac = new RBACData(accountId, "", realmId); +    rbac->LoadFromDB(); +    bool hasPermission = rbac->HasPermission(permission); +    delete rbac; + +    return hasPermission; +} diff --git a/src/server/game/Accounts/AccountMgr.h b/src/server/game/Accounts/AccountMgr.h index 2c07172723d..28373456994 100644 --- a/src/server/game/Accounts/AccountMgr.h +++ b/src/server/game/Accounts/AccountMgr.h @@ -67,6 +67,7 @@ class AccountMgr          static bool IsGMAccount(uint32 gmlevel);          static bool IsAdminAccount(uint32 gmlevel);          static bool IsConsoleAccount(uint32 gmlevel); +        static bool HasPermission(uint32 accountId, uint32 permission, uint32 realmId);          void UpdateAccountAccess(RBACData* rbac, uint32 accountId, uint8 securityLevel, int32 realmId); diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h index f6e494e7b70..0bd193d3841 100644 --- a/src/server/game/Accounts/RBAC.h +++ b/src/server/game/Accounts/RBAC.h @@ -48,16 +48,53 @@  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_INSTANT_LOGOUT                                 = 1,
 +    RBAC_PERM_SKIP_QUEUE                                     = 2,
 +    RBAC_PERM_JOIN_NORMAL_BG                                 = 3,
 +    RBAC_PERM_JOIN_RANDOM_BG                                 = 4,
 +    RBAC_PERM_JOIN_ARENAS                                    = 5,
 +    RBAC_PERM_JOIN_DUNGEON_FINDER                            = 6,
 +    RBAC_PERM_PLAYER_COMMANDS                                = 7,
 +    RBAC_PERM_MODERATOR_COMMANDS                             = 8,
 +    RBAC_PERM_GAMEMASTER_COMMANDS                            = 9,
 +    RBAC_PERM_ADMINISTRATOR_COMMANDS                         = 10,
 +    RBAC_PERM_LOG_GM_TRADE                                   = 11,
 +    // Free = 12
 +    RBAC_PERM_SKIP_CHECK_INSTANCE_REQUIRED_BOSSES            = 13,
 +    RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_TEAMMASK         = 14,
 +    RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_CLASSMASK        = 15,
 +    RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RACEMASK         = 16,
 +    RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME     = 17,
 +    RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_HEROIC_CHARACTER = 18,
 +    RBAC_PERM_SKIP_CHECK_CHAT_CHANNEL_REQ                    = 19,
 +    RBAC_PERM_SKIP_CHECK_DISABLE_MAP                         = 20,
 +    RBAC_PERM_SKIP_CHECK_MORE_TALENTS_THAN_ALLOWED           = 21,
 +    RBAC_PERM_SKIP_CHECK_CHAT_SPAM                           = 22,
 +    RBAC_PERM_SKIP_CHECK_OVERSPEED_PING                      = 23,
 +    RBAC_PERM_TWO_SIDE_CHARACTER_CREATION                    = 24,
 +    RBAC_PERM_TWO_SIDE_INTERACTION_CHAT                      = 25,
 +    RBAC_PERM_TWO_SIDE_INTERACTION_CHANNEL                   = 26,
 +    RBAC_PERM_TWO_SIDE_INTERACTION_MAIL                      = 27,
 +    RBAC_PERM_TWO_SIDE_WHO_LIST                              = 28,
 +    RBAC_PERM_TWO_SIDE_ADD_FRIEND                            = 29,
 +    RBAC_PERM_COMMANDS_SAVE_WITHOUT_DELAY                    = 30,
 +    RBAC_PERM_COMMANDS_USE_UNSTUCK_WITH_ARGS                 = 31,
 +    RBAC_PERM_COMMANDS_BE_ASSIGNED_TICKET                    = 32,
 +    RBAC_PERM_COMMANDS_NOTIFY_COMMAND_NOT_FOUND_ERROR        = 33,
 +    RBAC_PERM_COMMANDS_APPEAR_IN_GM_LIST                     = 34,
 +    RBAC_PERM_WHO_SEE_ALL_SEC_LEVELS                         = 35,
 +    RBAC_PERM_CAN_FILTER_WHISPERS                            = 36,
 +    RBAC_PERM_CHAT_USE_STAFF_BADGE                           = 37,
 +    RBAC_PERM_RESURRECT_WITH_FULL_HPS                        = 38,
 +    RBAC_PERM_RESTORE_SAVED_GM_STATE                         = 39,
 +    RBAC_PERM_ALLOW_GM_FRIEND                                = 40,
 +    RBAC_PERM_USE_START_GM_LEVEL                             = 41,
 +    RBAC_PERM_OPCODE_WORLD_TELEPORT                          = 42,
 +    RBAC_PERM_OPCODE_WHOIS                                   = 43,
 +    RBAC_PERM_RECEIVE_GLOBAL_GM_TEXTMESSAGE                  = 44,
 +    RBAC_PERM_SILENTLY_JOIN_CHANNEL                          = 45,
 +    RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR                   = 46,
 +    RBAC_PERM_CHECK_FOR_LOWER_SECURITY                       = 47,
      RBAC_PERM_MAX
  };
 diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp index 67bc094797f..906ce520bd1 100644 --- a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp +++ b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp @@ -93,46 +93,45 @@ void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry* auction, SQLTransaction&      if (!pItem)          return; -    uint32 bidder_accId = 0; -    uint64 bidder_guid = MAKE_NEW_GUID(auction->bidder, 0, HIGHGUID_PLAYER); -    Player* bidder = ObjectAccessor::FindPlayer(bidder_guid); +    uint32 bidderAccId = 0; +    uint64 bidderGuid = MAKE_NEW_GUID(auction->bidder, 0, HIGHGUID_PLAYER); +    Player* bidder = ObjectAccessor::FindPlayer(bidderGuid);      // data for gm.log      if (sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE))      { -        uint32 bidder_security = 0; -        std::string bidder_name; +        std::string bidderName; +        bool logGmTrade = false; +          if (bidder)          { -            bidder_accId = bidder->GetSession()->GetAccountId(); -            bidder_security = bidder->GetSession()->GetSecurity(); -            bidder_name = bidder->GetName(); +            bidderAccId = bidder->GetSession()->GetAccountId(); +            bidderName = bidder->GetName(); +            logGmTrade = bidder->GetSession()->HasPermission(RBAC_PERM_LOG_GM_TRADE);          }          else          { -            bidder_accId = sObjectMgr->GetPlayerAccountIdByGUID(bidder_guid); -            bidder_security = AccountMgr::GetSecurity(bidder_accId, realmID); +            bidderAccId = sObjectMgr->GetPlayerAccountIdByGUID(bidderGuid); +            logGmTrade = AccountMgr::HasPermission(bidderAccId, RBAC_PERM_LOG_GM_TRADE, realmID); -            if (!AccountMgr::IsPlayerAccount(bidder_security)) // not do redundant DB requests -            { -                if (!sObjectMgr->GetPlayerNameByGUID(bidder_guid, bidder_name)) -                    bidder_name = sObjectMgr->GetTrinityStringForDBCLocale(LANG_UNKNOWN); -            } +            if (logGmTrade && !sObjectMgr->GetPlayerNameByGUID(bidderGuid, bidderName)) +                bidderName = sObjectMgr->GetTrinityStringForDBCLocale(LANG_UNKNOWN);          } -        if (!AccountMgr::IsPlayerAccount(bidder_security)) + +        if (logGmTrade)          { -            std::string owner_name; -            if (!sObjectMgr->GetPlayerNameByGUID(auction->owner, owner_name)) -                owner_name = sObjectMgr->GetTrinityStringForDBCLocale(LANG_UNKNOWN); +            std::string ownerName; +            if (!sObjectMgr->GetPlayerNameByGUID(auction->owner, ownerName)) +                ownerName = sObjectMgr->GetTrinityStringForDBCLocale(LANG_UNKNOWN); -            uint32 owner_accid = sObjectMgr->GetPlayerAccountIdByGUID(auction->owner); +            uint32 ownerAccId = sObjectMgr->GetPlayerAccountIdByGUID(auction->owner); -            sLog->outCommand(bidder_accId, "GM %s (Account: %u) won item in auction: %s (Entry: %u Count: %u) and pay money: %u. Original owner %s (Account: %u)", -                bidder_name.c_str(), bidder_accId, pItem->GetTemplate()->Name1.c_str(), pItem->GetEntry(), pItem->GetCount(), auction->bid, owner_name.c_str(), owner_accid); +            sLog->outCommand(bidderAccId, "GM %s (Account: %u) won item in auction: %s (Entry: %u Count: %u) and pay money: %u. Original owner %s (Account: %u)", +                bidderName.c_str(), bidderAccId, pItem->GetTemplate()->Name1.c_str(), pItem->GetEntry(), pItem->GetCount(), auction->bid, ownerName.c_str(), ownerAccId);          }      }      // receiver exist -    if (bidder || bidder_accId) +    if (bidder || bidderAccId)      {          // set owner to bidder (to prevent delete item with sender char deleting)          // owner in `data` will set at mail receive and item extracting @@ -143,7 +142,7 @@ void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry* auction, SQLTransaction&          if (bidder)          { -            bidder->GetSession()->SendAuctionBidderNotification(auction->GetHouseId(), auction->Id, bidder_guid, 0, 0, auction->itemEntry); +            bidder->GetSession()->SendAuctionBidderNotification(auction->GetHouseId(), auction->Id, bidderGuid, 0, 0, auction->itemEntry);              // FIXME: for offline player need also              bidder->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WON_AUCTIONS, 1);          } diff --git a/src/server/game/Chat/Channels/Channel.cpp b/src/server/game/Chat/Channels/Channel.cpp index 9e7a63c9093..5f6bc8b7865 100644 --- a/src/server/game/Chat/Channels/Channel.cpp +++ b/src/server/game/Chat/Channels/Channel.cpp @@ -180,7 +180,7 @@ void Channel::JoinChannel(Player* player, std::string const& pass)      if (HasFlag(CHANNEL_FLAG_LFG) &&          sWorld->getBoolConfig(CONFIG_RESTRICTED_LFG_CHANNEL) && -        AccountMgr::IsPlayerAccount(player->GetSession()->GetSecurity()) && +        AccountMgr::IsPlayerAccount(player->GetSession()->GetSecurity()) && //FIXME: Move to RBAC          player->GetGroup())      {          WorldPacket data; @@ -191,8 +191,8 @@ void Channel::JoinChannel(Player* player, std::string const& pass)      player->JoinedChannel(this); -    if (_announce && (!AccountMgr::IsGMAccount(player->GetSession()->GetSecurity()) || -                       !sWorld->getBoolConfig(CONFIG_SILENTLY_GM_JOIN_TO_CHANNEL))) +    if (_announce && (!sWorld->getBoolConfig(CONFIG_SILENTLY_GM_JOIN_TO_CHANNEL) || +            !player->GetSession()->HasPermission(RBAC_PERM_SILENTLY_JOIN_CHANNEL)))      {          WorldPacket data;          MakeJoined(&data, guid); @@ -252,8 +252,9 @@ void Channel::LeaveChannel(Player* player, bool send)      bool changeowner = playersStore[guid].IsOwner();      playersStore.erase(guid); -    if (_announce && (!AccountMgr::IsGMAccount(player->GetSession()->GetSecurity()) || -                       !sWorld->getBoolConfig(CONFIG_SILENTLY_GM_JOIN_TO_CHANNEL))) + +    if (_announce && (!sWorld->getBoolConfig(CONFIG_SILENTLY_GM_JOIN_TO_CHANNEL) || +            !player->GetSession()->HasPermission(RBAC_PERM_SILENTLY_JOIN_CHANNEL)))      {          WorldPacket data;          MakeLeft(&data, guid); @@ -279,7 +280,6 @@ void Channel::LeaveChannel(Player* player, bool send)  void Channel::KickOrBan(Player const* player, std::string const& badname, bool ban)  { -    AccountTypes sec = player->GetSession()->GetSecurity();      uint64 good = player->GetGUID();      if (!IsOn(good)) @@ -290,7 +290,7 @@ void Channel::KickOrBan(Player const* player, std::string const& badname, bool b          return;      } -    if (!playersStore[good].IsModerator() && !AccountMgr::IsGMAccount(sec)) +    if (!playersStore[good].IsModerator() && !player->GetSession()->HasPermission(RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR))      {          WorldPacket data;          MakeNotModerator(&data); @@ -310,7 +310,7 @@ void Channel::KickOrBan(Player const* player, std::string const& badname, bool b      bool changeowner = _ownerGUID == victim; -    if (!AccountMgr::IsGMAccount(sec) && changeowner && good != _ownerGUID) +    if (!player->GetSession()->HasPermission(RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR) && changeowner && good != _ownerGUID)      {          WorldPacket data;          MakeNotOwner(&data); @@ -318,7 +318,7 @@ void Channel::KickOrBan(Player const* player, std::string const& badname, bool b          return;      } -    bool notify = !(AccountMgr::IsGMAccount(sec) && sWorld->getBoolConfig(CONFIG_SILENTLY_GM_JOIN_TO_CHANNEL)); +    bool notify = !sWorld->getBoolConfig(CONFIG_SILENTLY_GM_JOIN_TO_CHANNEL) || !player->GetSession()->HasPermission(RBAC_PERM_SILENTLY_JOIN_CHANNEL);      if (ban && !IsBanned(victim))      { @@ -363,7 +363,7 @@ void Channel::UnBan(Player const* player, std::string const& badname)          return;      } -    if (!playersStore[good].IsModerator() && !AccountMgr::IsGMAccount(sec)) +    if (!playersStore[good].IsModerator() && !player->GetSession()->HasPermission(RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR))      {          WorldPacket data;          MakeNotModerator(&data); @@ -404,7 +404,7 @@ void Channel::Password(Player const* player, std::string const& pass)          return;      } -    if (!playersStore[guid].IsModerator() && !AccountMgr::IsGMAccount(player->GetSession()->GetSecurity())) +    if (!playersStore[guid].IsModerator() && !player->GetSession()->HasPermission(RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR))      {          WorldPacket data;          MakeNotModerator(&data); @@ -424,7 +424,6 @@ void Channel::Password(Player const* player, std::string const& pass)  void Channel::SetMode(Player const* player, std::string const& p2n, bool mod, bool set)  {      uint64 guid = player->GetGUID(); -    uint32 sec = player->GetSession()->GetSecurity();      if (!IsOn(guid))      { @@ -434,7 +433,7 @@ void Channel::SetMode(Player const* player, std::string const& p2n, bool mod, bo          return;      } -    if (!playersStore[guid].IsModerator() && !AccountMgr::IsGMAccount(sec)) +    if (!playersStore[guid].IsModerator() && !player->GetSession()->HasPermission(RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR))      {          WorldPacket data;          MakeNotModerator(&data); @@ -449,10 +448,11 @@ void Channel::SetMode(Player const* player, std::string const& p2n, bool mod, bo      uint64 victim = newp ? newp->GetGUID() : 0;      if (!victim || !IsOn(victim) || +        (player->GetTeam() != newp->GetTeam() && (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL) || +        !player->GetSession()->HasPermission(RBAC_PERM_TWO_SIDE_INTERACTION_CHANNEL) || +        !newp->GetSession()->HasPermission(RBAC_PERM_TWO_SIDE_INTERACTION_CHANNEL))))          // allow make moderator from another team only if both is GMs          // at this moment this only way to show channel post for GM from another team -        ((!AccountMgr::IsGMAccount(sec) || !AccountMgr::IsGMAccount(newp->GetSession()->GetSecurity())) && -         player->GetTeam() != newp->GetTeam() && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL)))      {          WorldPacket data;          MakePlayerNotFound(&data, p2n); @@ -477,7 +477,6 @@ void Channel::SetMode(Player const* player, std::string const& p2n, bool mod, bo  void Channel::SetOwner(Player const* player, std::string const& newname)  {      uint64 guid = player->GetGUID(); -    uint32 sec = player->GetSession()->GetSecurity();      if (!IsOn(guid))      { @@ -487,7 +486,7 @@ void Channel::SetOwner(Player const* player, std::string const& newname)          return;      } -    if (!AccountMgr::IsGMAccount(sec) && guid != _ownerGUID) +    if (!player->GetSession()->HasPermission(RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR) && guid != _ownerGUID)      {          WorldPacket data;          MakeNotOwner(&data); @@ -553,7 +552,9 @@ void Channel::List(Player const* player)          // PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters          // MODERATOR, GAME MASTER, ADMINISTRATOR can see all -        if (member && (!AccountMgr::IsPlayerAccount(player->GetSession()->GetSecurity()) || member->GetSession()->GetSecurity() <= AccountTypes(gmLevelInWhoList)) && +        if (member && +            (player->GetSession()->HasPermission(RBAC_PERM_WHO_SEE_ALL_SEC_LEVELS) || +             member->GetSession()->GetSecurity() <= AccountTypes(gmLevelInWhoList)) &&              member->IsVisibleGloballyFor(player))          {              data << uint64(i->first); @@ -570,7 +571,6 @@ void Channel::List(Player const* player)  void Channel::Announce(Player const* player)  {      uint64 guid = player->GetGUID(); -    uint32 sec = player->GetSession()->GetSecurity();      if (!IsOn(guid))      { @@ -580,7 +580,7 @@ void Channel::Announce(Player const* player)          return;      } -    if (!playersStore[guid].IsModerator() && !AccountMgr::IsGMAccount(sec)) +    if (!playersStore[guid].IsModerator() && !player->GetSession()->HasPermission(RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR))      {          WorldPacket data;          MakeNotModerator(&data); @@ -605,6 +605,11 @@ void Channel::Say(uint64 guid, std::string const& what, uint32 lang)      if (what.empty())          return; +    uint8 chatTag = 0; +    if (Player* player = ObjectAccessor::FindPlayer(guid)) +        chatTag = player->GetChatTag(); + +    // TODO: Add proper RBAC check      if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL))          lang = LANG_UNIVERSAL; @@ -633,8 +638,7 @@ void Channel::Say(uint64 guid, std::string const& what, uint32 lang)      data << uint64(guid);      data << uint32(what.size() + 1);      data << what; -    Player* player = ObjectAccessor::FindPlayer(guid); -    data << uint8(player ? player->GetChatTag() : 0); +    data << uint8(chatTag);      SendToAll(&data, !playersStore[guid].IsModerator() ? guid : false);  } @@ -668,7 +672,9 @@ void Channel::Invite(Player const* player, std::string const& newname)          return;      } -    if (newp->GetTeam() != player->GetTeam() && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL)) +    if (newp->GetTeam() != player->GetTeam() && (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL) || +        !player->GetSession()->HasPermission(RBAC_PERM_TWO_SIDE_INTERACTION_CHANNEL) || +        !newp->GetSession()->HasPermission(RBAC_PERM_TWO_SIDE_INTERACTION_CHANNEL)))      {          WorldPacket data;          MakeInviteWrongFaction(&data); diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp index 12a98126dbf..62a148eae03 100644 --- a/src/server/game/Chat/Chat.cpp +++ b/src/server/game/Chat/Chat.cpp @@ -175,7 +175,7 @@ bool ChatHandler::HasLowerSecurityAccount(WorldSession* target, uint32 target_ac          return false;      // ignore only for non-players for non strong checks (when allow apply command at least to same sec level) -    if (!AccountMgr::IsPlayerAccount(m_session->GetSecurity()) && !strong && !sWorld->getBoolConfig(CONFIG_GM_LOWER_SECURITY)) +    if (m_session->HasPermission(RBAC_PERM_CHECK_FOR_LOWER_SECURITY) && !strong && !sWorld->getBoolConfig(CONFIG_GM_LOWER_SECURITY))          return false;      if (target) @@ -361,6 +361,7 @@ bool ChatHandler::ExecuteCommandInTable(ChatCommand* table, const char* text, co          // table[i].Name == "" is special case: send original command to handler          if ((table[i].Handler)(this, table[i].Name[0] != '\0' ? text : oldtext))          { +            // FIXME: When Command system is moved to RBAC this check must be changed              if (!AccountMgr::IsPlayerAccount(table[i].SecurityLevel))              {                  // chat case @@ -476,7 +477,7 @@ bool ChatHandler::ParseCommands(char const* text)      if (!ExecuteCommandInTable(getCommandTable(), text, fullcmd))      { -        if (m_session && AccountMgr::IsPlayerAccount(m_session->GetSecurity())) +        if (m_session && !m_session->HasPermission(RBAC_PERM_COMMANDS_NOTIFY_COMMAND_NOT_FOUND_ERROR))              return false;          SendSysMessage(LANG_NO_CMD); diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index bc1fd27e093..01d675a35c1 100644 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -431,6 +431,7 @@ uint32 Condition::GetSearcherTypeMaskForCondition()                  default:                      break;              } +            break;          case CONDITION_TYPE_MASK:              if (ConditionValue1 & TYPEMASK_UNIT)                  mask |= GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_PLAYER; diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index 9bb65b63557..ce18c227656 100644 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -29,6 +29,7 @@  #include "LFGQueue.h"  #include "Group.h"  #include "Player.h" +#include "RBAC.h"  #include "GroupMgr.h"  #include "GameEventMgr.h"  #include "WorldSession.h" diff --git a/src/server/game/Entities/Creature/TemporarySummon.h b/src/server/game/Entities/Creature/TemporarySummon.h index a96d9ab33d0..dc3347c5b4f 100644 --- a/src/server/game/Entities/Creature/TemporarySummon.h +++ b/src/server/game/Entities/Creature/TemporarySummon.h @@ -21,6 +21,22 @@  #include "Creature.h" +enum SummonerType +{ +    SUMMONER_TYPE_CREATURE      = 0, +    SUMMONER_TYPE_GAMEOBJECT    = 1, +    SUMMONER_TYPE_MAP           = 2 +}; + +/// Stores data for temp summons +struct TempSummonData +{ +    uint32 entry;        ///< Entry of summoned creature +    Position pos;        ///< Position, where should be creature spawned +    TempSummonType type; ///< Summon type, see TempSummonType for available types +    uint32 time;         ///< Despawn time, usable only with certain temp summon types +}; +  class TempSummon : public Creature  {      public: diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index cb497d11d4f..1851847f408 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -2463,6 +2463,24 @@ TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropert      return summon;  } +/** +* Summons group of creatures. +* +* @param group Id of group to summon. +* @param list  List to store pointers to summoned creatures. +*/ + +void Map::SummonCreatureGroup(uint8 group, std::list<TempSummon*>& list) +{ +    std::vector<TempSummonData> const* data = sObjectMgr->GetSummonGroup(GetId(), SUMMONER_TYPE_MAP, group); +    if (!data) +        return; + +    for (std::vector<TempSummonData>::const_iterator itr = data->begin(); itr != data->end(); ++itr) +        if (TempSummon* summon = SummonCreature(itr->entry, itr->pos, NULL, itr->time)) +            list.push_back(summon); +} +  void WorldObject::SetZoneScript()  {      if (Map* map = FindMap()) @@ -2542,6 +2560,25 @@ Creature* WorldObject::SummonTrigger(float x, float y, float z, float ang, uint3      return summon;  } +/** +* Summons group of creatures. Should be called only by instances of Creature and GameObject classes. +* +* @param group Id of group to summon. +* @param list  List to store pointers to summoned creatures. +*/ +void WorldObject::SummonCreatureGroup(uint8 group, std::list<TempSummon*>& list) +{ +    ASSERT((GetTypeId() == TYPEID_GAMEOBJECT || GetTypeId() == TYPEID_UNIT) && "Only GOs and creatures can summon npc groups!"); + +    std::vector<TempSummonData> const* data = sObjectMgr->GetSummonGroup(GetEntry(), GetTypeId() == TYPEID_GAMEOBJECT ? SUMMONER_TYPE_GAMEOBJECT : SUMMONER_TYPE_CREATURE, group); +    if (!data) +        return; + +    for (std::vector<TempSummonData>::const_iterator itr = data->begin(); itr != data->end(); ++itr) +        if (TempSummon* summon = SummonCreature(itr->entry, itr->pos, itr->type, itr->time)) +            list.push_back(summon); +} +  Creature* WorldObject::FindNearestCreature(uint32 entry, float range, bool alive) const  {      Creature* creature = NULL; diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index 8b61b6ec2c8..0f34c5df4b9 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -872,6 +872,7 @@ class WorldObject : public Object, public WorldLocation          }          GameObject* SummonGameObject(uint32 entry, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 respawnTime);          Creature*   SummonTrigger(float x, float y, float z, float ang, uint32 dur, CreatureAI* (*GetAI)(Creature*) = NULL); +        void SummonCreatureGroup(uint8 group, std::list<TempSummon*>& list);          Creature*   FindNearestCreature(uint32 entry, float range, bool alive = true) const;          GameObject* FindNearestGameObject(uint32 entry, float range) const; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index d72b906e6a5..e207c2535d0 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -671,7 +671,7 @@ Player::Player(WorldSession* session): Unit(true), phaseMgr(this)      //m_pad = 0;      // players always accept -    if (AccountMgr::IsPlayerAccount(GetSession()->GetSecurity())) +    if (!GetSession()->HasPermission(RBAC_PERM_CAN_FILTER_WHISPERS))          SetAcceptWhispers(true);      m_curSelection = 0; @@ -1013,7 +1013,7 @@ bool Player::Create(uint32 guidlow, CharacterCreateInfo* createInfo)          ? sWorld->getIntConfig(CONFIG_START_PLAYER_LEVEL)          : sWorld->getIntConfig(CONFIG_START_HEROIC_PLAYER_LEVEL); -    if (!AccountMgr::IsPlayerAccount(GetSession()->GetSecurity())) +    if (m_session->HasPermission(RBAC_PERM_USE_START_GM_LEVEL))      {          uint32 gm_level = sWorld->getIntConfig(CONFIG_START_GM_LEVEL);          if (gm_level > start_level) @@ -2072,7 +2072,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati          return false;      } -    if (AccountMgr::IsPlayerAccount(GetSession()->GetSecurity()) && DisableMgr::IsDisabledFor(DISABLE_TYPE_MAP, mapid, this)) +    if (!GetSession()->HasPermission(RBAC_PERM_SKIP_CHECK_DISABLE_MAP) && DisableMgr::IsDisabledFor(DISABLE_TYPE_MAP, mapid, this))      {          sLog->outError(LOG_FILTER_MAPS, "Player (GUID: %u, name: %s) tried to enter a forbidden map %u", GetGUIDLow(), GetName().c_str(), mapid);          SendTransferAborted(mapid, TRANSFER_ABORT_MAP_NOT_ALLOWED); @@ -3176,7 +3176,7 @@ void Player::InitTalentForLevel()          // if used more that have then reset          if (GetUsedTalentCount() > talentPointsForLevel)          { -            if (!AccountMgr::IsAdminAccount(GetSession()->GetSecurity())) +            if (!GetSession()->HasPermission(RBAC_PERM_SKIP_CHECK_MORE_TALENTS_THAN_ALLOWED))                  ResetTalents(true);              else                  SetFreeTalentPoints(0); @@ -16808,7 +16808,8 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder)      // check name limitations      if (ObjectMgr::CheckPlayerName(m_name) != CHAR_NAME_SUCCESS || -        (AccountMgr::IsPlayerAccount(GetSession()->GetSecurity()) && sObjectMgr->IsReservedName(m_name))) +        (!GetSession()->HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME) && +         sObjectMgr->IsReservedName(m_name)))      {          PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG);          stmt->setUInt16(0, uint16(AT_LOGIN_RENAME)); @@ -17366,7 +17367,7 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder)      outDebugValues();      // GM state -    if (!AccountMgr::IsPlayerAccount(GetSession()->GetSecurity())) +    if (GetSession()->HasPermission(RBAC_PERM_RESTORE_SAVED_GM_STATE))      {          switch (sWorld->getIntConfig(CONFIG_GM_LOGIN_STATE))          { @@ -19871,7 +19872,7 @@ void Player::outDebugValues() const  void Player::UpdateSpeakTime()  {      // ignore chat spam protection for GMs in any mode -    if (!AccountMgr::IsPlayerAccount(GetSession()->GetSecurity())) +    if (!GetSession()->HasPermission(RBAC_PERM_SKIP_CHECK_CHAT_SPAM))          return;      time_t current = time (NULL); diff --git a/src/server/game/Entities/Player/SocialMgr.cpp b/src/server/game/Entities/Player/SocialMgr.cpp index db91fb90936..ec8e6672508 100644 --- a/src/server/game/Entities/Player/SocialMgr.cpp +++ b/src/server/game/Entities/Player/SocialMgr.cpp @@ -217,34 +217,38 @@ void SocialMgr::GetFriendInfo(Player* player, uint32 friendGUID, FriendInfo &fri      friendInfo.Level = 0;      friendInfo.Class = 0; -    Player* pFriend = ObjectAccessor::FindPlayer(friendGUID); -    if (!pFriend) +    Player* target = ObjectAccessor::FindPlayer(friendGUID); +    if (!target)          return; -    uint32 team = player->GetTeam(); -    AccountTypes security = player->GetSession()->GetSecurity(); -    bool allowTwoSideWhoList = sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_WHO_LIST); -    AccountTypes gmLevelInWhoList = AccountTypes(sWorld->getIntConfig(CONFIG_GM_LEVEL_IN_WHO_LIST)); -      PlayerSocialMap::iterator itr = player->GetSocial()->m_playerSocialMap.find(friendGUID);      if (itr != player->GetSocial()->m_playerSocialMap.end())          friendInfo.Note = itr->second.Note;      // PLAYER see his team only and PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters      // MODERATOR, GAME MASTER, ADMINISTRATOR can see all -    if (pFriend && -        (!AccountMgr::IsPlayerAccount(security) || -        ((pFriend->GetTeam() == team || allowTwoSideWhoList) && (pFriend->GetSession()->GetSecurity() <= gmLevelInWhoList))) && -        pFriend->IsVisibleGloballyFor(player)) + +    if (!player->GetSession()->HasPermission(RBAC_PERM_WHO_SEE_ALL_SEC_LEVELS) && +        target->GetSession()->GetSecurity() > AccountTypes(sWorld->getIntConfig(CONFIG_GM_LEVEL_IN_WHO_LIST))) +        return; + +    // player can see member of other team only if CONFIG_ALLOW_TWO_SIDE_WHO_LIST +    if (target->GetTeam() != player->GetTeam() && +        !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_WHO_LIST) && !player->GetSession()->HasPermission(RBAC_PERM_TWO_SIDE_WHO_LIST)) +        return; + +    if (target->IsVisibleGloballyFor(player))      { -        friendInfo.Status = FRIEND_STATUS_ONLINE; -        if (pFriend->isAFK()) -            friendInfo.Status = FRIEND_STATUS_AFK; -        if (pFriend->isDND()) +        if (target->isDND())              friendInfo.Status = FRIEND_STATUS_DND; -        friendInfo.Area = pFriend->GetZoneId(); -        friendInfo.Level = pFriend->getLevel(); -        friendInfo.Class = pFriend->getClass(); +        else if (target->isAFK()) +            friendInfo.Status = FRIEND_STATUS_AFK; +        else +            friendInfo.Status = FRIEND_STATUS_ONLINE; + +        friendInfo.Area = target->GetZoneId(); +        friendInfo.Level = target->getLevel(); +        friendInfo.Class = target->getClass();      }  } @@ -296,28 +300,29 @@ void SocialMgr::BroadcastToFriendListers(Player* player, WorldPacket* packet)      if (!player)          return; -    uint32 team = player->GetTeam(); -    AccountTypes security = player->GetSession()->GetSecurity(); -    uint32 guid = player->GetGUIDLow(); -    AccountTypes gmLevelInWhoList = AccountTypes(sWorld->getIntConfig(CONFIG_GM_LEVEL_IN_WHO_LIST)); -    bool allowTwoSideWhoList = sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_WHO_LIST); -      for (SocialMap::const_iterator itr = m_socialMap.begin(); itr != m_socialMap.end(); ++itr)      { -        PlayerSocialMap::const_iterator itr2 = itr->second.m_playerSocialMap.find(guid); +        PlayerSocialMap::const_iterator itr2 = itr->second.m_playerSocialMap.find(player->GetGUID());          if (itr2 != itr->second.m_playerSocialMap.end() && (itr2->second.Flags & SOCIAL_FLAG_FRIEND))          { -            Player* pFriend = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER)); +            Player* target = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER)); +            if (!target || !target->IsInWorld()) +                continue; + +            if (!target->GetSession()->HasPermission(RBAC_PERM_WHO_SEE_ALL_SEC_LEVELS) && +                player->GetSession()->GetSecurity() > AccountTypes(sWorld->getIntConfig(CONFIG_GM_LEVEL_IN_WHO_LIST))) +                continue; + +            // player can see member of other team only if CONFIG_ALLOW_TWO_SIDE_WHO_LIST +            if (target->GetTeam() != player->GetTeam() && +                !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_WHO_LIST) && +                !target->GetSession()->HasPermission(RBAC_PERM_TWO_SIDE_WHO_LIST)) +                continue;              // PLAYER see his team only and PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters              // MODERATOR, GAME MASTER, ADMINISTRATOR can see all -            if (pFriend && pFriend->IsInWorld() && -                (!AccountMgr::IsPlayerAccount(pFriend->GetSession()->GetSecurity()) || -                ((pFriend->GetTeam() == team || allowTwoSideWhoList) && security <= gmLevelInWhoList)) && -                player->IsVisibleGloballyFor(pFriend)) -            { -                pFriend->GetSession()->SendPacket(packet); -            } +            if (player->IsVisibleGloballyFor(target)) +                target->GetSession()->SendPacket(packet);          }      }  } diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 040cd6a19f8..50b88f3dd27 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -524,7 +524,7 @@ bool Unit::HasBreakableByDamageAuraType(AuraType type, uint32 excludeAura) const      AuraEffectList const& auras = GetAuraEffectsByType(type);      for (AuraEffectList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)          if ((!excludeAura || excludeAura != (*itr)->GetSpellInfo()->Id) && //Avoid self interrupt of channeled Crowd Control spells like Seduction -            ((*itr)->GetSpellInfo()->Attributes & SPELL_ATTR0_BREAKABLE_BY_DAMAGE || (*itr)->GetSpellInfo()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_TAKE_DAMAGE)) +            ((*itr)->GetSpellInfo()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_TAKE_DAMAGE))              return true;      return false;  } @@ -10013,7 +10013,7 @@ uint32 Unit::MeleeDamageBonusTaken(Unit* attacker, uint32 pdamage, WeaponAttackT      // ..taken      AuraEffectList const& mDamageTaken = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_TAKEN);      for (AuraEffectList::const_iterator i = mDamageTaken.begin(); i != mDamageTaken.end(); ++i) -        if ((*i)->GetMiscValue() & GetMeleeDamageSchoolMask()) +        if ((*i)->GetMiscValue() & attacker->GetMeleeDamageSchoolMask())              TakenFlatBenefit += (*i)->GetAmount();      if (attType != RANGED_ATTACK) @@ -10025,7 +10025,7 @@ uint32 Unit::MeleeDamageBonusTaken(Unit* attacker, uint32 pdamage, WeaponAttackT      float TakenTotalMod = 1.0f;      // ..taken -    TakenTotalMod *= GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, GetMeleeDamageSchoolMask()); +    TakenTotalMod *= GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, attacker->GetMeleeDamageSchoolMask());      // .. taken pct (special attacks)      if (spellProto) diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index f9a0ca80f90..c2fd3494c79 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -398,6 +398,7 @@ enum TriggerCastFlags      TRIGGERED_IGNORE_CASTER_AURAS                   = 0x00010000,   //! Will ignore caster aura restrictions or requirements      TRIGGERED_DISALLOW_PROC_EVENTS                  = 0x00020000,   //! Disallows proc events from triggered spell (default)      TRIGGERED_DONT_REPORT_CAST_ERROR                = 0x00040000,   //! Will return SPELL_FAILED_DONT_REPORT in CheckCast functions +    TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT      = 0x00080000,   //! Will ignore equipped item requirements      TRIGGERED_FULL_MASK                             = 0xFFFFFFFF  }; diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 399087d1c0a..265b981639f 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -1446,6 +1446,92 @@ bool ObjectMgr::SetCreatureLinkedRespawn(uint32 guidLow, uint32 linkedGuidLow)      return true;  } +void ObjectMgr::LoadTempSummons() +{ +    uint32 oldMSTime = getMSTime(); + +    //                                               0           1             2        3      4           5           6           7            8           9 +    QueryResult result = WorldDatabase.Query("SELECT summonerId, summonerType, groupId, entry, position_x, position_y, position_z, orientation, summonType, summonTime FROM creature_summon_groups"); + +    if (!result) +    { +        sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 temp summons. DB table `creature_summon_groups` is empty."); +        return; +    } + +    uint32 count = 0; +    do +    { +        Field* fields = result->Fetch(); + +        uint32 summonerId               = fields[0].GetUInt32(); +        SummonerType summonerType       = SummonerType(fields[1].GetUInt8()); +        uint8 group                     = fields[2].GetUInt8(); + +        switch (summonerType) +        { +            case SUMMONER_TYPE_CREATURE: +                if (!GetCreatureTemplate(summonerId)) +                { +                    sLog->outError(LOG_FILTER_SQL, "Table `creature_summon_groups` has summoner with non existing entry %u for creature summoner type, skipped.", summonerId); +                    continue; +                } +                break; +            case SUMMONER_TYPE_GAMEOBJECT: +                if (!GetGameObjectTemplate(summonerId)) +                { +                    sLog->outError(LOG_FILTER_SQL, "Table `creature_summon_groups` has summoner with non existing entry %u for gameobject summoner type, skipped.", summonerId); +                    continue; +                } +                break; +            case SUMMONER_TYPE_MAP: +                if (!sMapStore.LookupEntry(summonerId)) +                { +                    sLog->outError(LOG_FILTER_SQL, "Table `creature_summon_groups` has summoner with non existing entry %u for map summoner type, skipped.", summonerId); +                    continue; +                } +                break; +            default: +                sLog->outError(LOG_FILTER_SQL, "Table `creature_summon_groups` has unhandled summoner type %u for summoner %u, skipped.", summonerType, summonerId); +                continue; +        } + +        TempSummonData data; +        data.entry                      = fields[3].GetUInt32(); + +        if (!GetCreatureTemplate(data.entry)) +        { +            sLog->outError(LOG_FILTER_SQL, "Table `creature_summon_groups` has creature in group [Summoner ID: %u, Summoner Type: %u, Group ID: %u] with non existing creature entry %u, skipped.", summonerId, summonerType, group, data.entry); +            continue; +        } + +        float posX                      = fields[4].GetFloat(); +        float posY                      = fields[5].GetFloat(); +        float posZ                      = fields[6].GetFloat(); +        float orientation               = fields[7].GetFloat(); + +        data.pos.Relocate(posX, posY, posZ, orientation); + +        data.type                       = TempSummonType(fields[8].GetUInt8()); + +        if (data.type > TEMPSUMMON_MANUAL_DESPAWN) +        { +            sLog->outError(LOG_FILTER_SQL, "Table `creature_summon_groups` has unhandled temp summon type %u in group [Summoner ID: %u, Summoner Type: %u, Group ID: %u] for creature entry %u, skipped.", data.type, summonerId, summonerType, group, data.entry); +            continue; +        } + +        data.time                       = fields[9].GetUInt32(); + +        TempSummonGroupKey key(summonerId, summonerType, group); +        _tempSummonDataStore[key].push_back(data); + +        ++count; + +    } while (result->NextRow()); + +    sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u temp summons in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); +} +  void ObjectMgr::LoadCreatures()  {      uint32 oldMSTime = getMSTime(); diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index d0963a224b7..9502bb343e0 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -25,6 +25,7 @@  #include "Creature.h"  #include "DynamicObject.h"  #include "GameObject.h" +#include "TemporarySummon.h"  #include "Corpse.h"  #include "QuestDef.h"  #include "ItemPrototype.h" @@ -416,9 +417,29 @@ struct TrinityStringLocale      StringVector Content;  }; +/// Key for storing temp summon data in TempSummonDataContainer +struct TempSummonGroupKey +{ +    TempSummonGroupKey(uint32 summonerEntry, SummonerType summonerType, uint8 group) +        : _summonerEntry(summonerEntry), _summonerType(summonerType), _summonGroup(group) +    { +    } +    +    bool operator<(TempSummonGroupKey const& rhs) const +    { +        return memcmp(this, &rhs, sizeof(TempSummonGroupKey)) < 0; +    } + +private: +    uint32 _summonerEntry;      ///< Summoner's entry +    SummonerType _summonerType; ///< Summoner's type, see SummonerType for available types +    uint8 _summonGroup;         ///< Summon's group id +}; +  typedef std::map<uint64, uint64> LinkedRespawnContainer;  typedef UNORDERED_MAP<uint32, CreatureData> CreatureDataContainer;  typedef UNORDERED_MAP<uint32, GameObjectData> GameObjectDataContainer; +typedef std::map<TempSummonGroupKey, std::vector<TempSummonData> > TempSummonDataContainer;  typedef UNORDERED_MAP<uint32, CreatureLocale> CreatureLocaleContainer;  typedef UNORDERED_MAP<uint32, GameObjectLocale> GameObjectLocaleContainer;  typedef UNORDERED_MAP<uint32, ItemLocale> ItemLocaleContainer; @@ -872,6 +893,7 @@ class ObjectMgr          void LoadCreatureTemplates();          void LoadCreatureTemplateAddons();          void CheckCreatureTemplate(CreatureTemplate const* cInfo); +        void LoadTempSummons();          void LoadCreatures();          void LoadLinkedRespawn();          bool SetCreatureLinkedRespawn(uint32 guid, uint32 linkedGuid); @@ -984,6 +1006,24 @@ class ObjectMgr              return _mapObjectGuidsStore[MAKE_PAIR32(mapid, spawnMode)][cell_id];          } +        /** +         * Gets temp summon data for all creatures of specified group. +         * +         * @param summonerId   Summoner's entry. +         * @param summonerType Summoner's type, see SummonerType for available types. +         * @param group        Id of required group. +         * +         * @return null if group was not found, otherwise reference to the creature group data +         */ +        std::vector<TempSummonData> const* GetSummonGroup(uint32 summonerId, SummonerType summonerType, uint8 group) const +        { +            TempSummonDataContainer::const_iterator itr = _tempSummonDataStore.find(TempSummonGroupKey(summonerId, summonerType, group)); +            if (itr != _tempSummonDataStore.end()) +                return &itr->second; +                    +            return NULL; +        } +          CreatureData const* GetCreatureData(uint32 guid) const          {              CreatureDataContainer::const_iterator itr = _creatureDataStore.find(guid); @@ -1313,6 +1353,8 @@ class ObjectMgr          GameObjectDataContainer _gameObjectDataStore;          GameObjectLocaleContainer _gameObjectLocaleStore;          GameObjectTemplateContainer _gameObjectTemplateStore; +        /// Stores temp summon data grouped by summoner's entry, summoner's type and group id +        TempSummonDataContainer _tempSummonDataStore;          ItemTemplateContainer _itemTemplateStore;          ItemLocaleContainer _itemLocaleStore; diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp index b112888d1b3..705bdfd8589 100644 --- a/src/server/game/Guilds/Guild.cpp +++ b/src/server/game/Guilds/Guild.cpp @@ -1019,12 +1019,15 @@ void Guild::BankMoveItemData::LogBankEvent(SQLTransaction& trans, MoveItemData*  void Guild::BankMoveItemData::LogAction(MoveItemData* pFrom) const  {      MoveItemData::LogAction(pFrom); -    if (!pFrom->IsBank() && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE) && !AccountMgr::IsPlayerAccount(m_pPlayer->GetSession()->GetSecurity()))       // TODO: move to scripts +    if (!pFrom->IsBank() && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE) && +        m_pPlayer->GetSession()->HasPermission(RBAC_PERM_LOG_GM_TRADE)) +    {          sLog->outCommand(m_pPlayer->GetSession()->GetAccountId(),              "GM %s (Account: %u) deposit item: %s (Entry: %d Count: %u) to guild bank (Guild ID: %u)",              m_pPlayer->GetName().c_str(), m_pPlayer->GetSession()->GetAccountId(),              pFrom->GetItem()->GetTemplate()->Name1.c_str(), pFrom->GetItem()->GetEntry(), pFrom->GetItem()->GetCount(),              m_pGuild->GetId()); +    }  }  Item* Guild::BankMoveItemData::_StoreItem(SQLTransaction& trans, BankTab* pTab, Item* pItem, ItemPosCount& pos, bool clone) const @@ -2009,7 +2012,7 @@ void Guild::HandleMemberDepositMoney(WorldSession* session, uint64 amount, bool      std::string aux = ByteArrayToHexStr(reinterpret_cast<uint8*>(&amount), 8, true);      _BroadcastEvent(GE_BANK_MONEY_CHANGED, 0, aux.c_str()); -    if (!AccountMgr::IsPlayerAccount(player->GetSession()->GetSecurity()) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) +    if (player->GetSession()->HasPermission(RBAC_PERM_LOG_GM_TRADE) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE))      {          sLog->outCommand(player->GetSession()->GetAccountId(),              "GM %s (Account: %u) deposit money (Amount: " UI64FMTD ") to guild bank (Guild ID %u)", diff --git a/src/server/game/Handlers/AuctionHouseHandler.cpp b/src/server/game/Handlers/AuctionHouseHandler.cpp index 17551df2181..59a1bcf6c33 100644 --- a/src/server/game/Handlers/AuctionHouseHandler.cpp +++ b/src/server/game/Handlers/AuctionHouseHandler.cpp @@ -269,7 +269,7 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData)          // Required stack size of auction matches to current item stack size, just move item to auctionhouse          if (itemsCount == 1 && item->GetCount() == count[i])          { -            if (GetSecurity() > SEC_PLAYER && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) +            if (HasPermission(RBAC_PERM_LOG_GM_TRADE) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE))              {                  sLog->outCommand(GetAccountId(), "GM %s (Account: %u) create auction: %s (Entry: %u Count: %u)",                      GetPlayerName().c_str(), GetAccountId(), item->GetTemplate()->Name1.c_str(), item->GetEntry(), item->GetCount()); @@ -318,7 +318,7 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData)                  return;              } -            if (GetSecurity() > SEC_PLAYER && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) +            if (HasPermission(RBAC_PERM_LOG_GM_TRADE) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE))              {                  sLog->outCommand(GetAccountId(), "GM %s (Account: %u) create auction: %s (Entry: %u Count: %u)",                      GetPlayerName().c_str(), GetAccountId(), newItem->GetTemplate()->Name1.c_str(), newItem->GetEntry(), newItem->GetCount()); diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index 5dfba797448..a647a9098e0 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -299,7 +299,7 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData)      WorldPacket data(SMSG_CHAR_CREATE, 1);                  // returned with diff.values in all cases -    if (AccountMgr::IsPlayerAccount(GetSecurity())) +    if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_TEAMMASK))      {          if (uint32 mask = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_DISABLED))          { @@ -308,13 +308,17 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData)              uint32 team = Player::TeamForRace(race_);              switch (team)              { -                case ALLIANCE: disabled = mask & (1 << 0); break; -                case HORDE:    disabled = mask & (1 << 1); break; +                case ALLIANCE: +                    disabled = mask & (1 << 0); +                    break; +                case HORDE: +                    disabled = mask & (1 << 1); +                    break;              }              if (disabled)              { -                data << (uint8)CHAR_CREATE_DISABLED; +                data << uint8(CHAR_CREATE_DISABLED);                  SendPacket(&data);                  return;              } @@ -324,7 +328,7 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData)      ChrClassesEntry const* classEntry = sChrClassesStore.LookupEntry(class_);      if (!classEntry)      { -        data << (uint8)CHAR_CREATE_FAILED; +        data << uint8(CHAR_CREATE_FAILED);          SendPacket(&data);          sLog->outError(LOG_FILTER_NETWORKIO, "Class (%u) not found in DBC while creating new char for account (ID: %u): wrong DBC files or cheater?", class_, GetAccountId());          return; @@ -333,7 +337,7 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData)      ChrRacesEntry const* raceEntry = sChrRacesStore.LookupEntry(race_);      if (!raceEntry)      { -        data << (uint8)CHAR_CREATE_FAILED; +        data << uint8(CHAR_CREATE_FAILED);          SendPacket(&data);          sLog->outError(LOG_FILTER_NETWORKIO, "Race (%u) not found in DBC while creating new char for account (ID: %u): wrong DBC files or cheater?", race_, GetAccountId());          return; @@ -342,7 +346,7 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData)      // prevent character creating Expansion race without Expansion account      if (raceEntry->expansion > Expansion())      { -        data << (uint8)CHAR_CREATE_EXPANSION; +        data << uint8(CHAR_CREATE_EXPANSION);          sLog->outError(LOG_FILTER_NETWORKIO, "Expansion %u account:[%d] tried to Create character with expansion %u race (%u)", Expansion(), GetAccountId(), raceEntry->expansion, race_);          SendPacket(&data);          return; @@ -351,13 +355,13 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData)      // prevent character creating Expansion class without Expansion account      if (classEntry->expansion > Expansion())      { -        data << (uint8)CHAR_CREATE_EXPANSION_CLASS; +        data << uint8(CHAR_CREATE_EXPANSION_CLASS);          sLog->outError(LOG_FILTER_NETWORKIO, "Expansion %u account:[%d] tried to Create character with expansion %u class (%u)", Expansion(), GetAccountId(), classEntry->expansion, class_);          SendPacket(&data);          return;      } -    if (AccountMgr::IsPlayerAccount(GetSecurity())) +    if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RACEMASK))      {          uint32 raceMaskDisabled = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_DISABLED_RACEMASK);          if ((1 << (race_ - 1)) & raceMaskDisabled) @@ -366,7 +370,10 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData)              SendPacket(&data);              return;          } +    } +    if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_CLASSMASK)) +    {          uint32 classMaskDisabled = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_DISABLED_CLASSMASK);          if ((1 << (class_ - 1)) & classMaskDisabled)          { @@ -379,7 +386,7 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData)      // prevent character creating with invalid name      if (!normalizePlayerName(name))      { -        data << (uint8)CHAR_NAME_NO_NAME; +        data << uint8(CHAR_NAME_NO_NAME);          SendPacket(&data);          sLog->outError(LOG_FILTER_NETWORKIO, "Account:[%d] but tried to Create character with empty [name] ", GetAccountId());          return; @@ -394,29 +401,32 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData)          return;      } -    if (AccountMgr::IsPlayerAccount(GetSecurity()) && sObjectMgr->IsReservedName(name)) +    if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME) && sObjectMgr->IsReservedName(name))      { -        data << (uint8)CHAR_NAME_RESERVED; +        data << uint8(CHAR_NAME_RESERVED);          SendPacket(&data);          return;      } -    // speedup check for heroic class disabled case -    uint32 heroic_free_slots = sWorld->getIntConfig(CONFIG_HEROIC_CHARACTERS_PER_REALM); -    if (heroic_free_slots == 0 && AccountMgr::IsPlayerAccount(GetSecurity()) && class_ == CLASS_DEATH_KNIGHT) +    if (class_ == CLASS_DEATH_KNIGHT && !HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_HEROIC_CHARACTER))      { -        data << (uint8)CHAR_CREATE_UNIQUE_CLASS_LIMIT; -        SendPacket(&data); -        return; -    } +        // speedup check for heroic class disabled case +        uint32 heroic_free_slots = sWorld->getIntConfig(CONFIG_HEROIC_CHARACTERS_PER_REALM); +        if (heroic_free_slots == 0) +        { +            data << uint8(CHAR_CREATE_UNIQUE_CLASS_LIMIT); +            SendPacket(&data); +            return; +        } -    // speedup check for heroic class disabled case -    uint32 req_level_for_heroic = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_MIN_LEVEL_FOR_HEROIC_CHARACTER); -    if (AccountMgr::IsPlayerAccount(GetSecurity()) && class_ == CLASS_DEATH_KNIGHT && req_level_for_heroic > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL)) -    { -        data << (uint8)CHAR_CREATE_LEVEL_REQUIREMENT; -        SendPacket(&data); -        return; +        // speedup check for heroic class disabled case +        uint32 req_level_for_heroic = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_MIN_LEVEL_FOR_HEROIC_CHARACTER); +        if (req_level_for_heroic > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL)) +        { +            data << uint8(CHAR_CREATE_LEVEL_REQUIREMENT); +            SendPacket(&data); +            return; +        }      }      delete _charCreateCallback.GetParam();  // Delete existing if any, to make the callback chain reset to stage 0 @@ -507,7 +517,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte                  }              } -            bool allowTwoSideAccounts = !sWorld->IsPvPRealm() || sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_ACCOUNTS) || !AccountMgr::IsPlayerAccount(GetSecurity()); +            bool allowTwoSideAccounts = !sWorld->IsPvPRealm() || sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_ACCOUNTS) || HasPermission(RBAC_PERM_TWO_SIDE_CHARACTER_CREATION);              uint32 skipCinematics = sWorld->getIntConfig(CONFIG_SKIP_CINEMATICS);              _charCreateCallback.FreeResult(); @@ -531,8 +541,9 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte              bool haveSameRace = false;              uint32 heroicReqLevel = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_MIN_LEVEL_FOR_HEROIC_CHARACTER);              bool hasHeroicReqLevel = (heroicReqLevel == 0); -            bool allowTwoSideAccounts = !sWorld->IsPvPRealm() || sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_ACCOUNTS) || !AccountMgr::IsPlayerAccount(GetSecurity()); +            bool allowTwoSideAccounts = !sWorld->IsPvPRealm() || sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_ACCOUNTS) || HasPermission(RBAC_PERM_TWO_SIDE_CHARACTER_CREATION);              uint32 skipCinematics = sWorld->getIntConfig(CONFIG_SKIP_CINEMATICS); +            bool checkHeroicReqs = createInfo->Class == CLASS_DEATH_KNIGHT && !HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_HEROIC_CHARACTER);              if (result)              { @@ -542,7 +553,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte                  Field* field = result->Fetch();                  uint8 accRace  = field[1].GetUInt8(); -                if (AccountMgr::IsPlayerAccount(GetSecurity()) && createInfo->Class == CLASS_DEATH_KNIGHT) +                if (checkHeroicReqs)                  {                      uint8 accClass = field[2].GetUInt8();                      if (accClass == CLASS_DEATH_KNIGHT) @@ -601,7 +612,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte                      if (!haveSameRace)                          haveSameRace = createInfo->Race == accRace; -                    if (AccountMgr::IsPlayerAccount(GetSecurity()) && createInfo->Class == CLASS_DEATH_KNIGHT) +                    if (checkHeroicReqs)                      {                          uint8 acc_class = field[2].GetUInt8();                          if (acc_class == CLASS_DEATH_KNIGHT) @@ -630,7 +641,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte                  }              } -            if (AccountMgr::IsPlayerAccount(GetSecurity()) && createInfo->Class == CLASS_DEATH_KNIGHT && !hasHeroicReqLevel) +            if (checkHeroicReqs && !hasHeroicReqLevel)              {                  WorldPacket data(SMSG_CHAR_CREATE, 1);                  data << uint8(CHAR_CREATE_LEVEL_REQUIREMENT); @@ -1211,7 +1222,7 @@ void WorldSession::HandleCharRenameOpcode(WorldPacket& recvData)      }      // check name limitations -    if (AccountMgr::IsPlayerAccount(GetSecurity()) && sObjectMgr->IsReservedName(newName)) +    if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME) && sObjectMgr->IsReservedName(newName))      {          WorldPacket data(SMSG_CHAR_RENAME, 1);          data << uint8(CHAR_NAME_RESERVED); @@ -1531,7 +1542,7 @@ void WorldSession::HandleCharCustomize(WorldPacket& recvData)      }      // check name limitations -    if (AccountMgr::IsPlayerAccount(GetSecurity()) && sObjectMgr->IsReservedName(newName)) +    if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME) && sObjectMgr->IsReservedName(newName))      {          WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1);          data << uint8(CHAR_NAME_RESERVED); @@ -1777,7 +1788,7 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)          return;      } -    if (AccountMgr::IsPlayerAccount(GetSecurity())) +    if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RACEMASK))      {          uint32 raceMaskDisabled = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_DISABLED_RACEMASK);          if ((1 << (race - 1)) & raceMaskDisabled) @@ -1808,7 +1819,7 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)      }      // check name limitations -    if (AccountMgr::IsPlayerAccount(GetSecurity()) && sObjectMgr->IsReservedName(newname)) +    if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME) && sObjectMgr->IsReservedName(newname))      {          WorldPacket data(SMSG_CHAR_FACTION_CHANGE, 1);          data << uint8(CHAR_NAME_RESERVED); diff --git a/src/server/game/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp index eef049fdb66..40547463323 100644 --- a/src/server/game/Handlers/ChatHandler.cpp +++ b/src/server/game/Handlers/ChatHandler.cpp @@ -327,20 +327,22 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)              }              Player* receiver = sObjectAccessor->FindPlayerByName(to); -            bool senderIsPlayer = AccountMgr::IsPlayerAccount(GetSecurity()); -            bool receiverIsPlayer = AccountMgr::IsPlayerAccount(receiver ? receiver->GetSession()->GetSecurity() : SEC_PLAYER); -            if (!receiver || (senderIsPlayer && !receiverIsPlayer && !receiver->isAcceptWhispers() && !receiver->IsInWhisperWhiteList(sender->GetGUID()))) +            if (!receiver || (!HasPermission(RBAC_PERM_CAN_FILTER_WHISPERS) && +                receiver->GetSession()->HasPermission(RBAC_PERM_CAN_FILTER_WHISPERS) && +                !receiver->isAcceptWhispers() && !receiver->IsInWhisperWhiteList(sender->GetGUID())))              {                  SendPlayerNotFoundNotice(to);                  return;              } -            if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT) && senderIsPlayer && receiverIsPlayer) -                if (GetPlayer()->GetTeam() != receiver->GetTeam()) -                { -                    SendWrongFactionNotice(); -                    return; -                } +            if (GetPlayer()->GetTeam() != receiver->GetTeam() && +                (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT) || +                !HasPermission(RBAC_PERM_TWO_SIDE_INTERACTION_CHAT) || +                !receiver->GetSession()->HasPermission(RBAC_PERM_TWO_SIDE_INTERACTION_CHAT))) +            { +                SendWrongFactionNotice(); +                return; +            }              if (GetPlayer()->HasAura(1852) && !receiver->isGameMaster())              { @@ -349,7 +351,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)              }              // If player is a Gamemaster and doesn't accept whisper, we auto-whitelist every player that the Gamemaster is talking to -            if (!senderIsPlayer && !sender->isAcceptWhispers() && !sender->IsInWhisperWhiteList(receiver->GetGUID())) +            if (HasPermission(RBAC_PERM_CAN_FILTER_WHISPERS) && !sender->isAcceptWhispers() && !sender->IsInWhisperWhiteList(receiver->GetGUID()))                  sender->AddWhisperWhiteList(receiver->GetGUID());              GetPlayer()->Whisper(msg, lang, receiver->GetGUID()); @@ -452,7 +454,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)          } break;          case CHAT_MSG_CHANNEL:          { -            if (AccountMgr::IsPlayerAccount(GetSecurity())) +            if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHAT_CHANNEL_REQ))              {                  if (_player->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_CHANNEL_LEVEL_REQ))                  { diff --git a/src/server/game/Handlers/MailHandler.cpp b/src/server/game/Handlers/MailHandler.cpp index 48f11c596d2..b1f42f92a6d 100644 --- a/src/server/game/Handlers/MailHandler.cpp +++ b/src/server/game/Handlers/MailHandler.cpp @@ -33,7 +33,7 @@ void WorldSession::HandleSendMail(WorldPacket& recvData)  {      ObjectGuid mailbox;      uint64 money, COD; -    std::string receiver, subject, body; +    std::string receiverName, subject, body;      uint32 bodyLength, subjectLength, receiverLength;      uint32 unk1, unk2; @@ -46,7 +46,7 @@ void WorldSession::HandleSendMail(WorldPacket& recvData)      uint8 items_count = recvData.ReadBits(5);              // attached items count -    if (items_count > MAX_MAIL_ITEMS)                       // client limit +    if (items_count > MAX_MAIL_ITEMS)                      // client limit      {          GetPlayer()->SendMailResult(0, MAIL_SEND, MAIL_ERR_TOO_MANY_ATTACHMENTS);          recvData.rfinish();                   // set to end to avoid warnings spam @@ -99,7 +99,7 @@ void WorldSession::HandleSendMail(WorldPacket& recvData)      recvData.ReadByteSeq(mailbox[5]);      subject = recvData.ReadString(subjectLength); -    receiver = recvData.ReadString(receiverLength); +    receiverName = recvData.ReadString(receiverLength);      recvData.ReadByteSeq(mailbox[2]);      recvData.ReadByteSeq(mailbox[0]); @@ -113,7 +113,7 @@ void WorldSession::HandleSendMail(WorldPacket& recvData)      if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX))          return; -    if (receiver.empty()) +    if (receiverName.empty())          return;      Player* player = _player; @@ -124,21 +124,26 @@ void WorldSession::HandleSendMail(WorldPacket& recvData)          return;      } -    uint64 rc = 0; -    if (normalizePlayerName(receiver)) -        rc = sObjectMgr->GetPlayerGUIDByName(receiver); +    uint64 receiverGuid = 0; +    if (normalizePlayerName(receiverName)) +        receiverGuid = sObjectMgr->GetPlayerGUIDByName(receiverName); -    if (!rc) +    if (!receiverGuid)      { -        sLog->outInfo(LOG_FILTER_NETWORKIO, "Player %u is sending mail to %s (GUID: not existed!) with subject %s and body %s includes %u items, " UI64FMTD " copper and " UI64FMTD " COD copper with unk1 = %u, unk2 = %u", -            player->GetGUIDLow(), receiver.c_str(), subject.c_str(), body.c_str(), items_count, money, COD, unk1, unk2); +        sLog->outInfo(LOG_FILTER_NETWORKIO, "Player %u is sending mail to %s (GUID: not existed!) with subject %s " +            "and body %s includes %u items, " UI64FMTD " copper and " UI64FMTD " COD copper with unk1 = %u, unk2 = %u", +            player->GetGUIDLow(), receiverName.c_str(), subject.c_str(), body.c_str(), +            items_count, money, COD, unk1, unk2);          player->SendMailResult(0, MAIL_SEND, MAIL_ERR_RECIPIENT_NOT_FOUND);          return;      } -    sLog->outInfo(LOG_FILTER_NETWORKIO, "Player %u is sending mail to %s (GUID: %u) with subject %s and body %s includes %u items, " UI64FMTD " copper and " UI64FMTD " COD copper with unk1 = %u, unk2 = %u", player->GetGUIDLow(), receiver.c_str(), GUID_LOPART(rc), subject.c_str(), body.c_str(), items_count, money, COD, unk1, unk2); +    sLog->outInfo(LOG_FILTER_NETWORKIO, "Player %u is sending mail to %s (GUID: %u) with subject %s and body %s " +        "includes %u items, " UI64FMTD " copper and " UI64FMTD " COD copper with unk1 = %u, unk2 = %u", +        player->GetGUIDLow(), receiverName.c_str(), GUID_LOPART(receiverGuid), subject.c_str(), +        body.c_str(), items_count, money, COD, unk1, unk2); -    if (player->GetGUID() == rc) +    if (player->GetGUID() == receiverGuid)      {          player->SendMailResult(0, MAIL_SEND, MAIL_ERR_CANNOT_SEND_TO_SELF);          return; @@ -154,58 +159,62 @@ void WorldSession::HandleSendMail(WorldPacket& recvData)          return;      } -    Player* receive = ObjectAccessor::FindPlayer(rc); +    Player* receiver = ObjectAccessor::FindPlayer(receiverGuid); -    uint32 rc_team = 0; -    uint8 mails_count = 0;                                  //do not allow to send to one player more than 100 mails -    uint8 receiveLevel = 0; +    uint32 receiverTeam = 0; +    uint8 mailsCount = 0;                                  //do not allow to send to one player more than 100 mails +    uint8 receiverLevel = 0; +    uint32 receiverAccountId = 0; +    bool canReceiveMailFromOtherFaction = false; -    if (receive) +    if (receiver)      { -        rc_team = receive->GetTeam(); -        mails_count = receive->GetMailSize(); -        receiveLevel = receive->getLevel(); +        receiverTeam = receiver->GetTeam(); +        mailsCount = receiver->GetMailSize(); +        receiverLevel = receiver->getLevel(); +        receiverAccountId = receiver->GetSession()->GetAccountId(); +        canReceiveMailFromOtherFaction = receiver->GetSession()->HasPermission(RBAC_PERM_TWO_SIDE_INTERACTION_MAIL);      }      else      { -        rc_team = sObjectMgr->GetPlayerTeamByGUID(rc); +        receiverTeam = sObjectMgr->GetPlayerTeamByGUID(receiverGuid);          PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAIL_COUNT); - -        stmt->setUInt32(0, GUID_LOPART(rc)); +        stmt->setUInt32(0, GUID_LOPART(receiverGuid));          PreparedQueryResult result = CharacterDatabase.Query(stmt); -          if (result)          {              Field* fields = result->Fetch(); -            mails_count = fields[0].GetUInt64(); +            mailsCount = fields[0].GetUInt64();          }          stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_LEVEL); - -        stmt->setUInt32(0, GUID_LOPART(rc)); +        stmt->setUInt32(0, GUID_LOPART(receiverGuid));          result = CharacterDatabase.Query(stmt); -          if (result)          {              Field* fields = result->Fetch(); -            receiveLevel = fields[0].GetUInt8(); +            receiverLevel = fields[0].GetUInt8();          } + +        receiverAccountId = sObjectMgr->GetPlayerAccountIdByGUID(receiverGuid); +        canReceiveMailFromOtherFaction = AccountMgr::HasPermission(receiverAccountId, RBAC_PERM_TWO_SIDE_INTERACTION_MAIL, realmID);      } -    //do not allow to have more than 100 mails in mailbox.. mails count is in opcode uint8!!! - so max can be 255.. -    if (mails_count > 100) + +    // do not allow to have more than 100 mails in mailbox.. mails count is in opcode uint8!!! - so max can be 255.. +    if (mailsCount > 100)      {          player->SendMailResult(0, MAIL_SEND, MAIL_ERR_RECIPIENT_CAP_REACHED);          return;      } +      // test the receiver's Faction... or all items are account bound      bool accountBound = items_count ? true : false;      for (uint8 i = 0; i < items_count; ++i)      { -        Item* item = player->GetItemByGuid(itemGUIDs[i]); -        if (item) +        if (Item* item = player->GetItemByGuid(itemGUIDs[i]))          {              ItemTemplate const* itemProto = item->GetTemplate();              if (!itemProto || !(itemProto->Flags & ITEM_PROTO_FLAG_BIND_TO_ACCOUNT)) @@ -216,22 +225,21 @@ void WorldSession::HandleSendMail(WorldPacket& recvData)          }      } -    if (!accountBound && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_MAIL) && player->GetTeam() != rc_team && AccountMgr::IsPlayerAccount(GetSecurity())) +    if (!accountBound && player->GetTeam() != receiverTeam &&              // Sender and reciver are from different faction +        (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_MAIL) || // Config not enabled +        !HasPermission(RBAC_PERM_TWO_SIDE_INTERACTION_MAIL) ||             // Sender cant mail interact with the other faction +        !canReceiveMailFromOtherFaction))                                  // Receiver cant mail interact with the other faction      {          player->SendMailResult(0, MAIL_SEND, MAIL_ERR_NOT_YOUR_TEAM);          return;      } -    if (receiveLevel < sWorld->getIntConfig(CONFIG_MAIL_LEVEL_REQ)) +    if (receiverLevel < sWorld->getIntConfig(CONFIG_MAIL_LEVEL_REQ))      {          SendNotification(GetTrinityString(LANG_MAIL_RECEIVER_REQ), sWorld->getIntConfig(CONFIG_MAIL_LEVEL_REQ));          return;      } -    uint32 rc_account = receive -        ? receive->GetSession()->GetAccountId() -        : sObjectMgr->GetPlayerAccountIdByGUID(rc); -      Item* items[MAX_MAIL_ITEMS];      for (uint8 i = 0; i < items_count; ++i) @@ -257,7 +265,7 @@ void WorldSession::HandleSendMail(WorldPacket& recvData)              return;          } -        if (item->IsBoundAccountWide() && item->IsSoulBound() && player->GetSession()->GetAccountId() != rc_account) +        if (item->IsBoundAccountWide() && item->IsSoulBound() && player->GetSession()->GetAccountId() != receiverAccountId)          {              player->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_NOT_SAME_ACCOUNT);              return; @@ -297,35 +305,38 @@ void WorldSession::HandleSendMail(WorldPacket& recvData)      if (items_count > 0 || money > 0)      { +        bool log = sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE) && HasPermission(RBAC_PERM_LOG_GM_TRADE);          if (items_count > 0)          {              for (uint8 i = 0; i < items_count; ++i)              {                  Item* item = items[i]; -                if (!AccountMgr::IsPlayerAccount(GetSecurity()) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) +                if (log)                  { -                    sLog->outCommand(GetAccountId(), "GM %s (Account: %u) mail item: %s (Entry: %u Count: %u) to player: %s (Account: %u)", -                        GetPlayerName().c_str(), GetAccountId(), item->GetTemplate()->Name1.c_str(), item->GetEntry(), item->GetCount(), receiver.c_str(), rc_account); +                    sLog->outCommand(GetAccountId(), "GM %s (Account: %u) mail item: %s (Entry: %u Count: %u) " +                        "to player: %s (Account: %u)", GetPlayerName().c_str(), GetAccountId(), +                        item->GetTemplate()->Name1.c_str(), item->GetEntry(), item->GetCount(), +                        receiverName.c_str(), receiverAccountId);                  }                  item->SetNotRefundable(GetPlayer()); // makes the item no longer refundable                  player->MoveItemFromInventory(items[i]->GetBagSlot(), item->GetSlot(), true);                  item->DeleteFromInventoryDB(trans);     // deletes item from character's inventory -                item->SetOwnerGUID(rc); +                item->SetOwnerGUID(receiverGuid);                  item->SaveToDB(trans);                  // recursive and not have transaction guard into self, item not in inventory and can be save standalone                  draft.AddItem(item);              }              // if item send to character at another account, then apply item delivery delay -            needItemDelay = player->GetSession()->GetAccountId() != rc_account; +            needItemDelay = player->GetSession()->GetAccountId() != receiverAccountId;          } -        if (money > 0 && !AccountMgr::IsPlayerAccount(GetSecurity()) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) +        if (log && money > 0)          {              sLog->outCommand(GetAccountId(), "GM %s (Account: %u) mail money: " UI64FMTD " to player: %s (Account: %u)", -                GetPlayerName().c_str(), GetAccountId(), money, receiver.c_str(), rc_account); +                GetPlayerName().c_str(), GetAccountId(), money, receiverName.c_str(), receiverAccountId);          }      } @@ -336,7 +347,7 @@ void WorldSession::HandleSendMail(WorldPacket& recvData)      draft          .AddMoney(money)          .AddCOD(COD) -        .SendMailTo(trans, MailReceiver(receive, GUID_LOPART(rc)), MailSender(player), body.empty() ? MAIL_CHECK_MASK_COPIED : MAIL_CHECK_MASK_HAS_BODY, deliver_delay); +        .SendMailTo(trans, MailReceiver(receiver, GUID_LOPART(receiverGuid)), MailSender(player), body.empty() ? MAIL_CHECK_MASK_COPIED : MAIL_CHECK_MASK_HAS_BODY, deliver_delay);      player->SaveInventoryAndGoldToDB(trans);      CharacterDatabase.CommitTransaction(trans); @@ -492,17 +503,17 @@ void WorldSession::HandleMailTakeItem(WorldPacket& recvData)          if (m->COD > 0)                                     //if there is COD, take COD money from player and send them to sender by mail          {              uint64 sender_guid = MAKE_NEW_GUID(m->sender, 0, HIGHGUID_PLAYER); -            Player* receive = ObjectAccessor::FindPlayer(sender_guid); +            Player* receiver = ObjectAccessor::FindPlayer(sender_guid);              uint32 sender_accId = 0; -            if (!AccountMgr::IsPlayerAccount(GetSecurity()) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) +            if (HasPermission(RBAC_PERM_LOG_GM_TRADE) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE))              {                  std::string sender_name; -                if (receive) +                if (receiver)                  { -                    sender_accId = receive->GetSession()->GetAccountId(); -                    sender_name = receive->GetName(); +                    sender_accId = receiver->GetSession()->GetAccountId(); +                    sender_name = receiver->GetName();                  }                  else                  { @@ -512,18 +523,18 @@ void WorldSession::HandleMailTakeItem(WorldPacket& recvData)                      if (!sObjectMgr->GetPlayerNameByGUID(sender_guid, sender_name))                          sender_name = sObjectMgr->GetTrinityStringForDBCLocale(LANG_UNKNOWN);                  } -                sLog->outCommand(GetAccountId(), "GM %s (Account: %u) receive mail item: %s (Entry: %u Count: %u) and send COD money: " UI64FMTD " to player: %s (Account: %u)", +                sLog->outCommand(GetAccountId(), "GM %s (Account: %u) receiver mail item: %s (Entry: %u Count: %u) and send COD money: " UI64FMTD " to player: %s (Account: %u)",                      GetPlayerName().c_str(), GetAccountId(), it->GetTemplate()->Name1.c_str(), it->GetEntry(), it->GetCount(), m->COD, sender_name.c_str(), sender_accId);              } -            else if (!receive) +            else if (!receiver)                  sender_accId = sObjectMgr->GetPlayerAccountIdByGUID(sender_guid);              // check player existence -            if (receive || sender_accId) +            if (receiver || sender_accId)              {                  MailDraft(m->subject, "")                      .AddMoney(m->COD) -                    .SendMailTo(trans, MailReceiver(receive, m->sender), MailSender(MAIL_NORMAL, m->receiver), MAIL_CHECK_MASK_COD_PAYMENT); +                    .SendMailTo(trans, MailReceiver(receiver, m->sender), MailSender(MAIL_NORMAL, m->receiver), MAIL_CHECK_MASK_COD_PAYMENT);              }              player->ModifyMoney(-int32(m->COD)); diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index a2768319150..808e86e15c7 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -241,7 +241,7 @@ void WorldSession::HandleWhoOpcode(WorldPacket& recvData)          level_max = STRONG_MAX_LEVEL;      uint32 team = _player->GetTeam(); -    uint32 security = GetSecurity(); +      bool allowTwoSideWhoList = sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_WHO_LIST);      uint32 gmLevelInWhoList  = sWorld->getIntConfig(CONFIG_GM_LEVEL_IN_WHO_LIST);      uint32 displaycount = 0; @@ -254,42 +254,40 @@ void WorldSession::HandleWhoOpcode(WorldPacket& recvData)      HashMapHolder<Player>::MapType const& m = sObjectAccessor->GetPlayers();      for (HashMapHolder<Player>::MapType::const_iterator itr = m.begin(); itr != m.end(); ++itr)      { -        if (AccountMgr::IsPlayerAccount(security)) -        { -            // player can see member of other team only if CONFIG_ALLOW_TWO_SIDE_WHO_LIST -            if (itr->second->GetTeam() != team && !allowTwoSideWhoList) -                continue; +        Player* target = itr->second; +        // player can see member of other team only if CONFIG_ALLOW_TWO_SIDE_WHO_LIST +        if (target->GetTeam() != team && !allowTwoSideWhoList && !HasPermission(RBAC_PERM_TWO_SIDE_WHO_LIST)) +            continue; -            // player can see MODERATOR, GAME MASTER, ADMINISTRATOR only if CONFIG_GM_IN_WHO_LIST -            if ((itr->second->GetSession()->GetSecurity() > AccountTypes(gmLevelInWhoList))) -                continue; -        } +        // player can see MODERATOR, GAME MASTER, ADMINISTRATOR only if CONFIG_GM_IN_WHO_LIST +        if (!HasPermission(RBAC_PERM_WHO_SEE_ALL_SEC_LEVELS) && target->GetSession()->GetSecurity() > AccountTypes(gmLevelInWhoList)) +            continue; -        //do not process players which are not in world -        if (!(itr->second->IsInWorld())) +        // do not process players which are not in world +        if (!target->IsInWorld())              continue;          // check if target is globally visible for player -        if (!(itr->second->IsVisibleGloballyFor(_player))) +        if (!target->IsVisibleGloballyFor(_player))              continue;          // check if target's level is in level range -        uint8 lvl = itr->second->getLevel(); +        uint8 lvl = target->getLevel();          if (lvl < level_min || lvl > level_max)              continue;          // check if class matches classmask -        uint32 class_ = itr->second->getClass(); +        uint8 class_ = target->getClass();          if (!(classmask & (1 << class_)))              continue;          // check if race matches racemask -        uint32 race = itr->second->getRace(); +        uint32 race = target->getRace();          if (!(racemask & (1 << race)))              continue; -        uint32 pzoneid = itr->second->GetZoneId(); -        uint8 gender = itr->second->getGender(); +        uint32 pzoneid = target->GetZoneId(); +        uint8 gender = target->getGender();          bool z_show = true;          for (uint32 i = 0; i < zones_count; ++i) @@ -305,7 +303,7 @@ void WorldSession::HandleWhoOpcode(WorldPacket& recvData)          if (!z_show)              continue; -        std::string pname = itr->second->GetName(); +        std::string pname = target->GetName();          std::wstring wpname;          if (!Utf8toWStr(pname, wpname))              continue; @@ -314,7 +312,7 @@ void WorldSession::HandleWhoOpcode(WorldPacket& recvData)          if (!(wplayer_name.empty() || wpname.find(wplayer_name) != std::wstring::npos))              continue; -        std::string gname = sGuildMgr->GetGuildNameById(itr->second->GetGuildId()); +        std::string gname = sGuildMgr->GetGuildNameById(target->GetGuildId());          std::wstring wgname;          if (!Utf8toWStr(gname, wgname))              continue; @@ -324,7 +322,7 @@ void WorldSession::HandleWhoOpcode(WorldPacket& recvData)              continue;          std::string aname; -        if (AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(itr->second->GetZoneId())) +        if (AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(pzoneid))              aname = areaEntry->area_name[GetSessionDbcLocale()];          bool s_show = true; @@ -574,13 +572,14 @@ void WorldSession::HandleAddFriendOpcodeCallBack(PreparedQueryResult result, std          team = Player::TeamForRace(fields[1].GetUInt8());          friendAccountId = fields[2].GetUInt32(); -        if (!AccountMgr::IsPlayerAccount(GetSecurity()) || sWorld->getBoolConfig(CONFIG_ALLOW_GM_FRIEND) || AccountMgr::IsPlayerAccount(AccountMgr::GetSecurity(friendAccountId, realmID))) +        if (HasPermission(RBAC_PERM_ALLOW_GM_FRIEND) || sWorld->getBoolConfig(CONFIG_ALLOW_GM_FRIEND) || +            AccountMgr::IsPlayerAccount(AccountMgr::GetSecurity(friendAccountId, realmID)))          {              if (friendGuid)              {                  if (friendGuid == GetPlayer()->GetGUID())                      friendResult = FRIEND_SELF; -                else if (GetPlayer()->GetTeam() != team && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_ADD_FRIEND) && AccountMgr::IsPlayerAccount(GetSecurity())) +                else if (GetPlayer()->GetTeam() != team && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_ADD_FRIEND) && !HasPermission(RBAC_PERM_TWO_SIDE_ADD_FRIEND))                      friendResult = FRIEND_ENEMY;                  else if (GetPlayer()->GetSocial()->HasFriend(GUID_LOPART(friendGuid)))                      friendResult = FRIEND_ALREADY; @@ -1310,7 +1309,7 @@ void WorldSession::HandleWorldTeleportOpcode(WorldPacket& recvData)      sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_WORLD_TELEPORT: Player = %s, Time = %u, map = %u, x = %f, y = %f, z = %f, o = %f",          GetPlayer()->GetName().c_str(), time, mapid, PositionX, PositionY, PositionZ, Orientation); -    if (AccountMgr::IsAdminAccount(GetSecurity())) +    if (HasPermission(RBAC_PERM_OPCODE_WORLD_TELEPORT))          GetPlayer()->TeleportTo(mapid, PositionX, PositionY, PositionZ, Orientation);      else          SendNotification(LANG_YOU_NOT_HAVE_PERMISSION); @@ -1322,7 +1321,7 @@ void WorldSession::HandleWhoisOpcode(WorldPacket& recvData)      std::string charname;      recvData >> charname; -    if (!AccountMgr::IsAdminAccount(GetSecurity())) +    if (HasPermission(RBAC_PERM_OPCODE_WHOIS))      {          SendNotification(LANG_YOU_NOT_HAVE_PERMISSION);          return; diff --git a/src/server/game/Handlers/TradeHandler.cpp b/src/server/game/Handlers/TradeHandler.cpp index b25f0a301a9..49bc70dcde3 100644 --- a/src/server/game/Handlers/TradeHandler.cpp +++ b/src/server/game/Handlers/TradeHandler.cpp @@ -213,7 +213,7 @@ void WorldSession::moveItems(Item* myItems[], Item* hisItems[])              {                  // logging                  sLog->outDebug(LOG_FILTER_NETWORKIO, "partner storing: %u", myItems[i]->GetGUIDLow()); -                if (!AccountMgr::IsPlayerAccount(_player->GetSession()->GetSecurity()) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) +                if (HasPermission(RBAC_PERM_LOG_GM_TRADE) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE))                  {                      sLog->outCommand(_player->GetSession()->GetAccountId(), "GM %s (Account: %u) trade: %s (Entry: %d Count: %u) to player: %s (Account: %u)",                          _player->GetName().c_str(), _player->GetSession()->GetAccountId(), @@ -231,7 +231,7 @@ void WorldSession::moveItems(Item* myItems[], Item* hisItems[])              {                  // logging                  sLog->outDebug(LOG_FILTER_NETWORKIO, "player storing: %u", hisItems[i]->GetGUIDLow()); -                if (!AccountMgr::IsPlayerAccount(trader->GetSession()->GetSecurity()) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) +                if (HasPermission(RBAC_PERM_LOG_GM_TRADE) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE))                  {                      sLog->outCommand(trader->GetSession()->GetAccountId(), "GM %s (Account: %u) trade: %s (Entry: %d Count: %u) to player: %s (Account: %u)",                          trader->GetName().c_str(), trader->GetSession()->GetAccountId(), @@ -534,16 +534,17 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/)          moveItems(myItems, hisItems);          // logging money -        if (sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) +        if (HasPermission(RBAC_PERM_LOG_GM_TRADE) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE))          { -            if (!AccountMgr::IsPlayerAccount(_player->GetSession()->GetSecurity()) && my_trade->GetMoney() > 0) +            if (my_trade->GetMoney() > 0)              {                  sLog->outCommand(_player->GetSession()->GetAccountId(), "GM %s (Account: %u) give money (Amount: " UI64FMTD ") to player: %s (Account: %u)",                      _player->GetName().c_str(), _player->GetSession()->GetAccountId(),                      my_trade->GetMoney(),                      trader->GetName().c_str(), trader->GetSession()->GetAccountId());              } -            if (!AccountMgr::IsPlayerAccount(trader->GetSession()->GetSecurity()) && his_trade->GetMoney() > 0) + +            if (his_trade->GetMoney() > 0)              {                  sLog->outCommand(trader->GetSession()->GetAccountId(), "GM %s (Account: %u) give money (Amount: " UI64FMTD ") to player: %s (Account: %u)",                      trader->GetName().c_str(), trader->GetSession()->GetAccountId(), diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index cbc17901d02..d3f7ac7bbf1 100644 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -435,6 +435,7 @@ class Map : public GridRefManager<NGridType>          void UpdateIteratorBack(Player* player);          TempSummon* SummonCreature(uint32 entry, Position const& pos, SummonPropertiesEntry const* properties = NULL, uint32 duration = 0, Unit* summoner = NULL, uint32 spellId = 0, uint32 vehId = 0); +        void SummonCreatureGroup(uint8 group, std::list<TempSummon*>& list);          Creature* GetCreature(uint64 guid);          GameObject* GetGameObject(uint64 guid);          DynamicObject* GetDynamicObject(uint64 guid); diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index 514a59894b0..035e658bd69 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -307,7 +307,7 @@ enum SpellAttr0      SPELL_ATTR0_CASTABLE_WHILE_SITTING           = 0x08000000, // 27 castable while sitting      SPELL_ATTR0_CANT_USED_IN_COMBAT              = 0x10000000, // 28 Cannot be used in combat      SPELL_ATTR0_UNAFFECTED_BY_INVULNERABILITY    = 0x20000000, // 29 unaffected by invulnerability (hmm possible not...) -    SPELL_ATTR0_BREAKABLE_BY_DAMAGE              = 0x40000000, // 30 +    SPELL_ATTR0_HEARTBEAT_RESIST_CHECK           = 0x40000000, // 30 random chance the effect will end TODO: implement core support      SPELL_ATTR0_CANT_CANCEL                      = 0x80000000  // 31 positive aura can't be canceled  }; @@ -499,7 +499,7 @@ enum SpellAttr6      SPELL_ATTR6_UNK3                             = 0x00000008, //  3      SPELL_ATTR6_UNK4                             = 0x00000010, //  4      SPELL_ATTR6_UNK5                             = 0x00000020, //  5 -    SPELL_ATTR6_UNK6                             = 0x00000040, //  6 +    SPELL_ATTR6_PRINT_SPELLNAME                  = 0x00000040, //  6 when activated, spell name is shown at the center of the screen: <Spell name> (client-side attribute)      SPELL_ATTR6_UNK7                             = 0x00000080, //  7      SPELL_ATTR6_CANT_TARGET_CROWD_CONTROLLED     = 0x00000100, //  8      SPELL_ATTR6_UNK9                             = 0x00000200, //  9 diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 1819b829404..dd186c498a9 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -25,6 +25,7 @@  #include "Config.h"  #include "Common.h"  #include "DatabaseEnv.h" +#include "AccountMgr.h"  #include "Log.h"  #include "Opcodes.h"  #include "WorldPacket.h" diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 96b766fdf74..24917b368fc 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -24,7 +24,6 @@  #define __WORLDSESSION_H  #include "Common.h" -#include "AccountMgr.h"  #include "SharedDefines.h"  #include "AddonMgr.h"  #include "DatabaseEnv.h" @@ -41,6 +40,7 @@ class LoginQueryHolder;  class Object;  class Player;  class Quest; +class RBACData;  class SpellCastTargets;  class Unit;  class Warden; diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp index 7c263a62b19..f6b43c79199 100644 --- a/src/server/game/Server/WorldSocket.cpp +++ b/src/server/game/Server/WorldSocket.cpp @@ -1046,7 +1046,7 @@ int WorldSocket::HandlePing (WorldPacket& recvPacket)              {                  ACE_GUARD_RETURN (LockType, Guard, m_SessionLock, -1); -                if (m_Session && AccountMgr::IsPlayerAccount(m_Session->GetSecurity())) +                if (m_Session && !m_Session->HasPermission(RBAC_PERM_SKIP_CHECK_OVERSPEED_PING))                  {                      sLog->outError(LOG_FILTER_NETWORKIO, "WorldSocket::HandlePing: %s kicked for over-speed pings (address: %s)",                          m_Session->GetPlayerInfo().c_str(), GetRemoteAddress().c_str()); diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 4c465df7c35..57b316a3141 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -6015,8 +6015,9 @@ SpellCastResult Spell::CheckItems()      // if not item target then required item must be equipped      else      { -        if (m_caster->GetTypeId() == TYPEID_PLAYER && !m_caster->ToPlayer()->HasItemFitToSpellRequirements(m_spellInfo)) -            return SPELL_FAILED_EQUIPPED_ITEM_CLASS; +        if (!(_triggeredCastFlags & TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT)) +            if (m_caster->GetTypeId() == TYPEID_PLAYER && !m_caster->ToPlayer()->HasItemFitToSpellRequirements(m_spellInfo)) +                return SPELL_FAILED_EQUIPPED_ITEM_CLASS;      }      // check spell focus object @@ -6340,7 +6341,7 @@ SpellCastResult Spell::CheckItems()      }      // check weapon presence in slots for main/offhand weapons -    if (m_spellInfo->EquippedItemClass >=0) +    if (!(_triggeredCastFlags & TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT) && m_spellInfo->EquippedItemClass >=0)      {          // main hand weapon required          if (m_spellInfo->AttributesEx3 & SPELL_ATTR3_MAIN_HAND) diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 86d8f55c0ae..fc2da0d199c 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -2593,7 +2593,7 @@ void Spell::EffectEnchantItemPerm(SpellEffIndex effIndex)          if (!item_owner)              return; -        if (item_owner != p_caster && !AccountMgr::IsPlayerAccount(p_caster->GetSession()->GetSecurity()) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) +        if (item_owner != p_caster && p_caster->GetSession()->HasPermission(RBAC_PERM_LOG_GM_TRADE) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE))          {              sLog->outCommand(p_caster->GetSession()->GetAccountId(), "GM %s (Account: %u) enchanting(perm): %s (Entry: %d) for player: %s (Account: %u)",                  p_caster->GetName().c_str(), p_caster->GetSession()->GetAccountId(), @@ -2658,7 +2658,7 @@ void Spell::EffectEnchantItemPrismatic(SpellEffIndex effIndex)      if (!item_owner)          return; -    if (item_owner != p_caster && !AccountMgr::IsPlayerAccount(p_caster->GetSession()->GetSecurity()) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) +    if (item_owner != p_caster && p_caster->GetSession()->HasPermission(RBAC_PERM_LOG_GM_TRADE) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE))      {          sLog->outCommand(p_caster->GetSession()->GetAccountId(), "GM %s (Account: %u) enchanting(perm): %s (Entry: %d) for player: %s (Account: %u)",              p_caster->GetName().c_str(), p_caster->GetSession()->GetAccountId(), @@ -2740,7 +2740,7 @@ void Spell::EffectEnchantItemTmp(SpellEffIndex effIndex)      if (!item_owner)          return; -    if (item_owner != p_caster && !AccountMgr::IsPlayerAccount(p_caster->GetSession()->GetSecurity()) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) +    if (item_owner != p_caster && p_caster->GetSession()->HasPermission(RBAC_PERM_LOG_GM_TRADE) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE))      {          sLog->outCommand(p_caster->GetSession()->GetAccountId(), "GM %s (Account: %u) enchanting(temp): %s (Entry: %d) for player: %s (Account: %u)",              p_caster->GetName().c_str(), p_caster->GetSession()->GetAccountId(), diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 1a7f4b8c2a9..93c336c811c 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1257,7 +1257,7 @@ void World::LoadConfigSettings(bool reload)      m_bool_configs[CONFIG_PDUMP_NO_OVERWRITE] = ConfigMgr::GetBoolDefault("PlayerDump.DisallowOverwrite", true);      m_bool_configs[CONFIG_UI_QUESTLEVELS_IN_DIALOGS] = ConfigMgr::GetBoolDefault("UI.ShowQuestLevelsInDialogs", false); -    // call ScriptMgr if we're reloading the configuration +    // Wintergrasp battlefield      m_bool_configs[CONFIG_WINTERGRASP_ENABLE] = ConfigMgr::GetBoolDefault("Wintergrasp.Enable", false);      m_int_configs[CONFIG_WINTERGRASP_PLR_MAX] = ConfigMgr::GetIntDefault("Wintergrasp.PlayerMax", 100);      m_int_configs[CONFIG_WINTERGRASP_PLR_MIN] = ConfigMgr::GetIntDefault("Wintergrasp.PlayerMin", 0); @@ -1266,6 +1266,7 @@ void World::LoadConfigSettings(bool reload)      m_int_configs[CONFIG_WINTERGRASP_NOBATTLETIME] = ConfigMgr::GetIntDefault("Wintergrasp.NoBattleTimer", 150);      m_int_configs[CONFIG_WINTERGRASP_RESTART_AFTER_CRASH] = ConfigMgr::GetIntDefault("Wintergrasp.CrashRestartTimer", 10); +    // call ScriptMgr if we're reloading the configuration      if (reload)          sScriptMgr->OnConfigLoad(reload);  } @@ -1472,6 +1473,9 @@ void World::SetInitialWorldSettings()      sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading Creature Data...");      sObjectMgr->LoadCreatures(); +    sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading Temporary Summon Data..."); +    sObjectMgr->LoadTempSummons();                               // must be after LoadCreatureTemplates() and LoadGameObjectTemplates() +      sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading pet levelup spells...");      sSpellMgr->LoadPetLevelupSpellMap(); @@ -2181,18 +2185,21 @@ void World::SendGlobalMessage(WorldPacket* packet, WorldSession* self, uint32 te  /// Send a packet to all GMs (except self if mentioned)  void World::SendGlobalGMMessage(WorldPacket* packet, WorldSession* self, uint32 team)  { -    SessionMap::iterator itr; -    for (itr = m_sessions.begin(); itr != m_sessions.end(); ++itr) +    for (SessionMap::const_iterator itr = m_sessions.begin(); itr != m_sessions.end(); ++itr)      { -        if (itr->second && -            itr->second->GetPlayer() && -            itr->second->GetPlayer()->IsInWorld() && -            itr->second != self && -            !AccountMgr::IsPlayerAccount(itr->second->GetSecurity()) && -            (team == 0 || itr->second->GetPlayer()->GetTeam() == team)) -        { -            itr->second->SendPacket(packet); -        } +        // check if session and can receive global GM Messages and its not self +        WorldSession* session = itr->second; +        if (!session || session == self || !session->HasPermission(RBAC_PERM_RECEIVE_GLOBAL_GM_TEXTMESSAGE)) +            continue; + +        // Player should be in world +        Player* player = session->GetPlayer(); +        if (!player || !player->IsInWorld()) +            continue; + +        // Send only to same team, if team is given +        if (!team || player->GetTeam() == team) +            session->SendPacket(packet);      }  } @@ -2280,15 +2287,19 @@ void World::SendGMText(int32 string_id, ...)      Trinity::WorldWorldTextBuilder wt_builder(string_id, &ap);      Trinity::LocalizedPacketListDo<Trinity::WorldWorldTextBuilder> wt_do(wt_builder); -    for (SessionMap::iterator itr = m_sessions.begin(); itr != m_sessions.end(); ++itr) +    for (SessionMap::const_iterator itr = m_sessions.begin(); itr != m_sessions.end(); ++itr)      { -        if (!itr->second || !itr->second->GetPlayer() || !itr->second->GetPlayer()->IsInWorld()) +        // Session should have permissions to receive global gm messages +        WorldSession* session = itr->second; +        if (!session || !session->HasPermission(RBAC_PERM_RECEIVE_GLOBAL_GM_TEXTMESSAGE))              continue; -        if (AccountMgr::IsPlayerAccount(itr->second->GetSecurity())) +        // Player should be in world +        Player* player = session->GetPlayer(); +        if (!player || !player->IsInWorld())              continue; -        wt_do(itr->second->GetPlayer()); +        wt_do(player);      }      va_end(ap); diff --git a/src/server/scripts/Commands/cs_gm.cpp b/src/server/scripts/Commands/cs_gm.cpp index c2939666452..a99957a07c0 100644 --- a/src/server/scripts/Commands/cs_gm.cpp +++ b/src/server/scripts/Commands/cs_gm.cpp @@ -59,30 +59,32 @@ public:      // Enables or disables hiding of the staff badge      static bool HandleGMChatCommand(ChatHandler* handler, char const* args)      { -        if (!*args) +        if (WorldSession* session = handler->GetSession())          { -            WorldSession* session = handler->GetSession(); -            if (!AccountMgr::IsPlayerAccount(session->GetSecurity()) && session->GetPlayer()->isGMChat()) -                session->SendNotification(LANG_GM_CHAT_ON); -            else -                session->SendNotification(LANG_GM_CHAT_OFF); -            return true; -        } +            if (!*args) +            { +                if (session->HasPermission(RBAC_PERM_CHAT_USE_STAFF_BADGE) && session->GetPlayer()->isGMChat()) +                    session->SendNotification(LANG_GM_CHAT_ON); +                else +                    session->SendNotification(LANG_GM_CHAT_OFF); +                return true; +            } -        std::string param = (char*)args; +            std::string param = (char*)args; -        if (param == "on") -        { -            handler->GetSession()->GetPlayer()->SetGMChat(true); -            handler->GetSession()->SendNotification(LANG_GM_CHAT_ON); -            return true; -        } +            if (param == "on") +            { +                session->GetPlayer()->SetGMChat(true); +                session->SendNotification(LANG_GM_CHAT_ON); +                return true; +            } -        if (param == "off") -        { -            handler->GetSession()->GetPlayer()->SetGMChat(false); -            handler->GetSession()->SendNotification(LANG_GM_CHAT_OFF); -            return true; +            if (param == "off") +            { +                session->GetPlayer()->SetGMChat(false); +                session->SendNotification(LANG_GM_CHAT_OFF); +                return true; +            }          }          handler->SendSysMessage(LANG_USE_BOL); @@ -123,7 +125,9 @@ public:          for (HashMapHolder<Player>::MapType::const_iterator itr = m.begin(); itr != m.end(); ++itr)          {              AccountTypes itrSec = itr->second->GetSession()->GetSecurity(); -            if ((itr->second->isGameMaster() || (!AccountMgr::IsPlayerAccount(itrSec) && itrSec <= AccountTypes(sWorld->getIntConfig(CONFIG_GM_LEVEL_IN_GM_LIST)))) && +            if ((itr->second->isGameMaster() || +                (itr->second->GetSession()->HasPermission(RBAC_PERM_COMMANDS_APPEAR_IN_GM_LIST) && +                 itrSec <= AccountTypes(sWorld->getIntConfig(CONFIG_GM_LEVEL_IN_GM_LIST)))) &&                  (!handler->GetSession() || itr->second->IsVisibleGloballyFor(handler->GetSession()->GetPlayer())))              {                  if (first) diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index 3acfe9c14ba..e695a171255 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -677,7 +677,7 @@ public:          if (target)          { -            target->ResurrectPlayer(!AccountMgr::IsPlayerAccount(target->GetSession()->GetSecurity()) ? 1.0f : 0.5f); +            target->ResurrectPlayer(target->GetSession()->HasPermission(RBAC_PERM_RESURRECT_WITH_FULL_HPS) ? 1.0f : 0.5f);              target->SpawnCorpseBones();              target->SaveToDB();          } @@ -880,7 +880,7 @@ public:          Player* player = handler->GetSession()->GetPlayer();          // save GM account without delay and output message -        if (!AccountMgr::IsPlayerAccount(handler->GetSession()->GetSecurity())) +        if (handler->GetSession()->HasPermission(RBAC_PERM_COMMANDS_SAVE_WITHOUT_DELAY))          {              if (Player* target = handler->getSelectedPlayer())                  target->SaveToDB(); @@ -937,8 +937,8 @@ public:      static bool HandleUnstuckCommand(ChatHandler* handler, char const* args)      { -        //No args required for players -        if (handler->GetSession() && AccountMgr::IsPlayerAccount(handler->GetSession()->GetSecurity())) +        // No args required for players +        if (handler->GetSession() && !handler->GetSession()->HasPermission(RBAC_PERM_COMMANDS_USE_UNSTUCK_WITH_ARGS))          {              // 7355: "Stuck"              if (Player* player = handler->GetSession()->GetPlayer()) diff --git a/src/server/scripts/Commands/cs_rbac.cpp b/src/server/scripts/Commands/cs_rbac.cpp index 092aabb0045..604218c2e68 100644 --- a/src/server/scripts/Commands/cs_rbac.cpp +++ b/src/server/scripts/Commands/cs_rbac.cpp @@ -22,7 +22,7 @@ Comment: All role based access control related commands (including account relat  Category: commandscripts
  EndScriptData */
 -#include "RBAC.h"
 +#include "AccountMgr.h"
  #include "Config.h"
  #include "Chat.h"
  #include "Language.h"
 @@ -188,7 +188,7 @@ public:          if (!rdata)
          {
 -            data->rbac = new RBACData(accountId, accountName, ConfigMgr::GetIntDefault("RealmID", 0));
 +            data->rbac = new RBACData(accountId, accountName, realmID);
              data->rbac->LoadFromDB();
              data->needDelete = true;
          }
 diff --git a/src/server/scripts/Commands/cs_ticket.cpp b/src/server/scripts/Commands/cs_ticket.cpp index aee01f47581..958eb1709d5 100644 --- a/src/server/scripts/Commands/cs_ticket.cpp +++ b/src/server/scripts/Commands/cs_ticket.cpp @@ -95,18 +95,16 @@ public:              return true;          } -        // Get target information -        uint64 targetGuid = sObjectMgr->GetPlayerGUIDByName(target.c_str()); -        uint64 targetAccountId = sObjectMgr->GetPlayerAccountIdByGUID(targetGuid); -        uint32 targetGmLevel = AccountMgr::GetSecurity(targetAccountId, realmID); - +        uint32 accountId = AccountMgr::GetId(target);          // Target must exist and have administrative rights -        if (!targetGuid || AccountMgr::IsPlayerAccount(targetGmLevel)) +        if (!AccountMgr::HasPermission(accountId, RBAC_PERM_COMMANDS_BE_ASSIGNED_TICKET, realmID))          {              handler->SendSysMessage(LANG_COMMAND_TICKETASSIGNERROR_A);              return true;          } +        uint64 targetGuid = sObjectMgr->GetPlayerGUIDByName(target); +          // If already assigned, leave          if (ticket->IsAssignedTo(targetGuid))          { @@ -125,7 +123,7 @@ public:          // Assign ticket          SQLTransaction trans = SQLTransaction(NULL); -        ticket->SetAssignedTo(targetGuid, AccountMgr::IsAdminAccount(targetGmLevel)); +        ticket->SetAssignedTo(targetGuid, AccountMgr::IsAdminAccount(AccountMgr::GetSecurity(accountId, realmID)));          ticket->SaveToDB(trans);          sTicketMgr->UpdateLastChange(); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp index 593d9586156..db4ab2f32d2 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp @@ -954,7 +954,7 @@ class instance_icecrown_citadel : public InstanceMapScript              bool CheckRequiredBosses(uint32 bossId, Player const* player = NULL) const              { -                if (player && AccountMgr::IsGMAccount(player->GetSession()->GetSecurity())) +                if (player && player->GetSession()->HasPermission(RBAC_PERM_SKIP_CHECK_INSTANCE_REQUIRED_BOSSES))                      return true;                  switch (bossId) diff --git a/src/server/scripts/World/areatrigger_scripts.cpp b/src/server/scripts/World/areatrigger_scripts.cpp index c031c4a3b4d..83fac35b1b6 100644 --- a/src/server/scripts/World/areatrigger_scripts.cpp +++ b/src/server/scripts/World/areatrigger_scripts.cpp @@ -425,6 +425,69 @@ class AreaTrigger_at_area_52_entrance : public AreaTriggerScript          std::map<uint32, time_t> _triggerTimes;  }; +/*###### + ## at_frostgrips_hollow + ######*/ + +enum FrostgripsHollow +{ +    QUEST_THE_LONESOME_WATCHER      = 12877, +     +    NPC_STORMFORGED_MONITOR         = 29862, +    NPC_STORMFORGED_ERADICTOR       = 29861, +     +    TYPE_WAYPOINT                   = 0, +    DATA_START                      = 0 +}; + +Position const stormforgedMonitorPosition = {6963.95f, 45.65f, 818.71f, 4.948f}; +Position const stormforgedEradictorPosition = {6983.18f, 7.15f, 806.33f, 2.228f}; + +class AreaTrigger_at_frostgrips_hollow : public AreaTriggerScript +{ +public: +    AreaTrigger_at_frostgrips_hollow() : AreaTriggerScript("at_frostgrips_hollow") +    { +        stormforgedMonitorGUID = 0; +        stormforgedEradictorGUID = 0; +    } + +    bool OnTrigger(Player* player, AreaTriggerEntry const* /* trigger */) +    { +        if (player->GetQuestStatus(QUEST_THE_LONESOME_WATCHER) != QUEST_STATUS_INCOMPLETE) +            return false; + +        Creature* stormforgedMonitor = Creature::GetCreature(*player, stormforgedMonitorGUID); +        if (stormforgedMonitor) +            return false; +         +        Creature* stormforgedEradictor = Creature::GetCreature(*player, stormforgedEradictorGUID); +        if (stormforgedEradictor) +            return false; +         +        if ((stormforgedMonitor = player->SummonCreature(NPC_STORMFORGED_MONITOR, stormforgedMonitorPosition, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000))) +        { +            stormforgedMonitorGUID = stormforgedMonitor->GetGUID(); +            stormforgedMonitor->SetWalk(false); +            /// The npc would search an alternative way to get to the last waypoint without this unit state. +            stormforgedMonitor->AddUnitState(UNIT_STATE_IGNORE_PATHFINDING); +            stormforgedMonitor->GetMotionMaster()->MovePath(NPC_STORMFORGED_MONITOR * 100, false); +        } + +        if ((stormforgedEradictor = player->SummonCreature(NPC_STORMFORGED_ERADICTOR, stormforgedEradictorPosition, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000))) +        { +            stormforgedEradictorGUID = stormforgedEradictor->GetGUID(); +            stormforgedEradictor->GetMotionMaster()->MovePath(NPC_STORMFORGED_ERADICTOR * 100, false); +        } +         +        return true; +    } + +private: +    uint64 stormforgedMonitorGUID; +    uint64 stormforgedEradictorGUID; +}; +  void AddSC_areatrigger_scripts()  {      new AreaTrigger_at_coilfang_waterfall(); @@ -436,4 +499,5 @@ void AddSC_areatrigger_scripts()      new AreaTrigger_at_nats_landing();      new AreaTrigger_at_brewfest();      new AreaTrigger_at_area_52_entrance(); +    new AreaTrigger_at_frostgrips_hollow();  } diff --git a/src/server/worldserver/TCSoap/TCSoap.cpp b/src/server/worldserver/TCSoap/TCSoap.cpp index 7d460da4f83..dd82c6ce0c7 100644 --- a/src/server/worldserver/TCSoap/TCSoap.cpp +++ b/src/server/worldserver/TCSoap/TCSoap.cpp @@ -18,6 +18,9 @@  #include "TCSoap.h"  #include "soapH.h"  #include "soapStub.h" +#include "World.h" +#include "AccountMgr.h" +#include "Log.h"  void TCSoapRunnable::run()  { diff --git a/src/server/worldserver/TCSoap/TCSoap.h b/src/server/worldserver/TCSoap/TCSoap.h index ccdc7b1f89f..b786ee94e81 100644 --- a/src/server/worldserver/TCSoap/TCSoap.h +++ b/src/server/worldserver/TCSoap/TCSoap.h @@ -18,17 +18,11 @@  #ifndef _TCSOAP_H  #define _TCSOAP_H -#include "Common.h" -#include "World.h" -#include "AccountMgr.h" -#include "Log.h" - -#include "soapH.h" -#include "soapStub.h" -#include "stdsoap2.h" +#include "Define.h"  #include <ace/Semaphore.h>  #include <ace/Task.h> +#include <Threading.h>  class TCSoapRunnable: public ACE_Based::Runnable  {  | 
