diff options
69 files changed, 1290 insertions, 462 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_23_00_world_gameobject.sql b/sql/updates/world/2013_02_23_00_world_gameobject.sql new file mode 100644 index 00000000000..48694505704 --- /dev/null +++ b/sql/updates/world/2013_02_23_00_world_gameobject.sql @@ -0,0 +1 @@ +DELETE FROM `gameobject` WHERE `guid`=61090; diff --git a/sql/updates/world/2013_02_23_01_world_areatrigger_teleport.sql b/sql/updates/world/2013_02_23_01_world_areatrigger_teleport.sql new file mode 100644 index 00000000000..3b34e18a682 --- /dev/null +++ b/sql/updates/world/2013_02_23_01_world_areatrigger_teleport.sql @@ -0,0 +1,3 @@ +DELETE FROM `areatrigger_teleport` WHERE `id`=5148; +INSERT INTO `areatrigger_teleport` (`id`, `target_map`, `target_position_x`, `target_position_y`, `target_position_z`, `target_orientation`, `name`) VALUES +(5148, 1, -8756.6, -4457.02, -200.481, 1.39626, 'CoT Stratholme - Exit Target'); 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/Accounts/AccountMgr.cpp b/src/server/game/Accounts/AccountMgr.cpp index bd560c8266e..7172efaac0e 100644 --- a/src/server/game/Accounts/AccountMgr.cpp +++ b/src/server/game/Accounts/AccountMgr.cpp @@ -1,4 +1,4 @@ - /* +/* * Copyright (C) 2008-2013 TrinityCore <http://www.trinitycore.org/> * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> * @@ -27,7 +27,18 @@ AccountMgr::AccountMgr() { +} + +AccountMgr::~AccountMgr() +{ + for (RBACPermissionsContainer::iterator itr = _permissions.begin(); itr != _permissions.end(); ++itr) + delete itr->second; + + for (RBACRolesContainer::iterator itr = _roles.begin(); itr != _roles.end(); ++itr) + delete itr->second; + for (RBACGroupsContainer::iterator itr = _groups.begin(); itr != _groups.end(); ++itr) + delete itr->second; } AccountOpResult AccountMgr::CreateAccount(std::string username, std::string password) @@ -439,10 +450,7 @@ void AccountMgr::LoadRBAC() Tokenizer tokens(defaultGroups, ','); for (Tokenizer::const_iterator itr = tokens.begin(); itr != tokens.end(); ++itr) if (uint32 groupId = atoi(*itr)) - { - sLog->outError(LOG_FILTER_LFG, "Adding default group %u", groupId); _defaultGroups.insert(groupId); - } } void AccountMgr::UpdateAccountAccess(RBACData* rbac, uint32 accountId, uint8 securityLevel, int32 realmId) @@ -536,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 440e012f1fc..28373456994 100644 --- a/src/server/game/Accounts/AccountMgr.h +++ b/src/server/game/Accounts/AccountMgr.h @@ -45,6 +45,7 @@ class AccountMgr private: AccountMgr(); + ~AccountMgr(); public: AccountOpResult CreateAccount(std::string username, std::string password); @@ -66,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 71c44408f72..586a42c9f7e 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/Calendar/CalendarMgr.cpp b/src/server/game/Calendar/CalendarMgr.cpp index 763e0132c10..5f73ee48380 100644 --- a/src/server/game/Calendar/CalendarMgr.cpp +++ b/src/server/game/Calendar/CalendarMgr.cpp @@ -40,6 +40,12 @@ CalendarMgr::CalendarMgr() CalendarMgr::~CalendarMgr() { + for (CalendarEventStore::iterator itr = _events.begin(); itr != _events.end(); ++itr) + delete *itr; + + for (CalendarEventInviteStore::iterator itr = _invites.begin(); itr != _invites.end(); ++itr) + for (CalendarInviteStore::iterator itr2 = itr->second.begin(); itr2 != itr->second.end(); ++itr2) + delete *itr2; } void CalendarMgr::LoadFromDB() @@ -153,7 +159,7 @@ void CalendarMgr::RemoveEvent(uint64 eventId, uint64 remover) PreparedStatement* stmt; MailDraft mail(calendarEvent->BuildCalendarMailSubject(remover), calendarEvent->BuildCalendarMailBody()); - std::vector<CalendarInvite*>::iterator itr = _invites[eventId].begin(); + CalendarInviteStore::iterator itr = _invites[eventId].begin(); while (itr != _invites[eventId].end()) { stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CALENDAR_INVITE); @@ -187,7 +193,7 @@ void CalendarMgr::RemoveInvite(uint64 inviteId, uint64 eventId, uint64 /*remover if (!calendarEvent) return; - std::vector<CalendarInvite*>::iterator itr = _invites[eventId].begin(); + CalendarInviteStore::iterator itr = _invites[eventId].begin(); for (; itr != _invites[eventId].end(); ++itr) if ((*itr)->GetInviteId() == inviteId) break; @@ -254,8 +260,8 @@ void CalendarMgr::RemoveAllPlayerEventsAndInvites(uint64 guid) if ((*itr)->GetCreatorGUID() == guid) RemoveEvent((*itr)->GetEventId(), 0); // don't send mail if removing a character - std::vector<CalendarInvite*> playerInvites = GetPlayerInvites(guid); - for (std::vector<CalendarInvite*>::const_iterator itr = playerInvites.begin(); itr != playerInvites.end(); ++itr) + CalendarInviteStore playerInvites = GetPlayerInvites(guid); + for (CalendarInviteStore::const_iterator itr = playerInvites.begin(); itr != playerInvites.end(); ++itr) RemoveInvite((*itr)->GetInviteId(), (*itr)->GetEventId(), guid); } @@ -265,14 +271,14 @@ void CalendarMgr::RemovePlayerGuildEventsAndSignups(uint64 guid, uint32 guildId) if ((*itr)->GetCreatorGUID() == guid && ((*itr)->IsGuildEvent() || (*itr)->IsGuildAnnouncement())) RemoveEvent((*itr)->GetEventId(), guid); - std::vector<CalendarInvite*> playerInvites = GetPlayerInvites(guid); - for (std::vector<CalendarInvite*>::const_iterator itr = playerInvites.begin(); itr != playerInvites.end(); ++itr) + CalendarInviteStore playerInvites = GetPlayerInvites(guid); + for (CalendarInviteStore::const_iterator itr = playerInvites.begin(); itr != playerInvites.end(); ++itr) if (CalendarEvent* calendarEvent = GetEvent((*itr)->GetEventId())) if (calendarEvent->IsGuildEvent() && calendarEvent->GetGuildId() == guildId) RemoveInvite((*itr)->GetInviteId(), (*itr)->GetEventId(), guid); } -CalendarEvent* CalendarMgr::GetEvent(uint64 eventId) +CalendarEvent* CalendarMgr::GetEvent(uint64 eventId) const { for (CalendarEventStore::const_iterator itr = _events.begin(); itr != _events.end(); ++itr) if ((*itr)->GetEventId() == eventId) @@ -282,10 +288,10 @@ CalendarEvent* CalendarMgr::GetEvent(uint64 eventId) return NULL; } -CalendarInvite* CalendarMgr::GetInvite(uint64 inviteId) +CalendarInvite* CalendarMgr::GetInvite(uint64 inviteId) const { - for (CalendarInviteStore::const_iterator itr = _invites.begin(); itr != _invites.end(); ++itr) - for (std::vector<CalendarInvite*>::const_iterator itr2 = itr->second.begin(); itr2 != itr->second.end(); ++itr2) + for (CalendarEventInviteStore::const_iterator itr = _invites.begin(); itr != _invites.end(); ++itr) + for (CalendarInviteStore::const_iterator itr2 = itr->second.begin(); itr2 != itr->second.end(); ++itr2) if ((*itr2)->GetInviteId() == inviteId) return *itr2; @@ -305,12 +311,10 @@ uint64 CalendarMgr::GetFreeEventId() { if (_freeEventIds.empty()) return ++_maxEventId; - else - { - uint64 eventId = _freeEventIds.front(); - _freeEventIds.pop_front(); - return eventId; - } + + uint64 eventId = _freeEventIds.front(); + _freeEventIds.pop_front(); + return eventId; } void CalendarMgr::FreeInviteId(uint64 id) @@ -325,20 +329,18 @@ uint64 CalendarMgr::GetFreeInviteId() { if (_freeInviteIds.empty()) return ++_maxInviteId; - else - { - uint64 inviteId = _freeInviteIds.front(); - _freeInviteIds.pop_front(); - return inviteId; - } + + uint64 inviteId = _freeInviteIds.front(); + _freeInviteIds.pop_front(); + return inviteId; } CalendarEventStore CalendarMgr::GetPlayerEvents(uint64 guid) { CalendarEventStore events; - for (CalendarInviteStore::const_iterator itr = _invites.begin(); itr != _invites.end(); ++itr) - for (std::vector<CalendarInvite*>::const_iterator itr2 = itr->second.begin(); itr2 != itr->second.end(); ++itr2) + for (CalendarEventInviteStore::const_iterator itr = _invites.begin(); itr != _invites.end(); ++itr) + for (CalendarInviteStore::const_iterator itr2 = itr->second.begin(); itr2 != itr->second.end(); ++itr2) if ((*itr2)->GetInviteeGUID() == guid) events.insert(GetEvent(itr->first)); @@ -350,17 +352,17 @@ CalendarEventStore CalendarMgr::GetPlayerEvents(uint64 guid) return events; } -std::vector<CalendarInvite*> CalendarMgr::GetEventInvites(uint64 eventId) +CalendarInviteStore const& CalendarMgr::GetEventInvites(uint64 eventId) { return _invites[eventId]; } -std::vector<CalendarInvite*> CalendarMgr::GetPlayerInvites(uint64 guid) +CalendarInviteStore CalendarMgr::GetPlayerInvites(uint64 guid) { - std::vector<CalendarInvite*> invites; + CalendarInviteStore invites; - for (CalendarInviteStore::const_iterator itr = _invites.begin(); itr != _invites.end(); ++itr) - for (std::vector<CalendarInvite*>::const_iterator itr2 = itr->second.begin(); itr2 != itr->second.end(); ++itr2) + for (CalendarEventInviteStore::const_iterator itr = _invites.begin(); itr != _invites.end(); ++itr) + for (CalendarInviteStore::const_iterator itr2 = itr->second.begin(); itr2 != itr->second.end(); ++itr2) if ((*itr2)->GetInviteeGUID() == guid) invites.push_back(*itr2); @@ -369,13 +371,22 @@ std::vector<CalendarInvite*> CalendarMgr::GetPlayerInvites(uint64 guid) uint32 CalendarMgr::GetPlayerNumPending(uint64 guid) { - std::vector<CalendarInvite*> const& invites = GetPlayerInvites(guid); + CalendarInviteStore const& invites = GetPlayerInvites(guid); uint32 pendingNum = 0; - for (std::vector<CalendarInvite*>::const_iterator itr = invites.begin(); itr != invites.end(); ++itr) - // correct? - if ((*itr)->GetStatus() == CALENDAR_STATUS_INVITED || (*itr)->GetStatus() == CALENDAR_STATUS_TENTATIVE || (*itr)->GetStatus() == CALENDAR_STATUS_NOT_SIGNED_UP) - ++pendingNum; + for (CalendarInviteStore::const_iterator itr = invites.begin(); itr != invites.end(); ++itr) + { + switch ((*itr)->GetStatus()) + { + case CALENDAR_STATUS_INVITED: + case CALENDAR_STATUS_TENTATIVE: + case CALENDAR_STATUS_NOT_SIGNED_UP: + ++pendingNum; + break; + default: + break; + } + } return pendingNum; } @@ -531,7 +542,7 @@ void CalendarMgr::SendCalendarEvent(uint64 guid, CalendarEvent const& calendarEv if (!player) return; - std::vector<CalendarInvite*> const& eventInviteeList = _invites[calendarEvent.GetEventId()]; + CalendarInviteStore const& eventInviteeList = _invites[calendarEvent.GetEventId()]; WorldPacket data(SMSG_CALENDAR_SEND_EVENT, 60 + eventInviteeList.size() * 32); data << uint8(sendType); @@ -549,7 +560,7 @@ void CalendarMgr::SendCalendarEvent(uint64 guid, CalendarEvent const& calendarEv data << uint32(calendarEvent.GetGuildId()); data << uint32(eventInviteeList.size()); - for (std::vector<CalendarInvite*>::const_iterator itr = eventInviteeList.begin(); itr != eventInviteeList.end(); ++itr) + for (CalendarInviteStore::const_iterator itr = eventInviteeList.begin(); itr != eventInviteeList.end(); ++itr) { CalendarInvite const* calendarInvite = (*itr); uint64 inviteeGuid = calendarInvite->GetInviteeGUID(); @@ -627,8 +638,8 @@ void CalendarMgr::SendPacketToAllEventRelatives(WorldPacket packet, CalendarEven guild->BroadcastPacket(&packet); // Send packet to all invitees if event is non-guild, in other case only to non-guild invitees (packet was broadcasted for them) - std::vector<CalendarInvite*> invites = _invites[calendarEvent.GetEventId()]; - for (std::vector<CalendarInvite*>::iterator itr = invites.begin(); itr != invites.end(); ++itr) + CalendarInviteStore invites = _invites[calendarEvent.GetEventId()]; + for (CalendarInviteStore::iterator itr = invites.begin(); itr != invites.end(); ++itr) if (Player* player = ObjectAccessor::FindPlayer((*itr)->GetInviteeGUID())) if (!calendarEvent.IsGuildEvent() || (calendarEvent.IsGuildEvent() && player->GetGuildId() != calendarEvent.GetGuildId())) player->SendDirectMessage(&packet); diff --git a/src/server/game/Calendar/CalendarMgr.h b/src/server/game/Calendar/CalendarMgr.h index 3674e707399..d1b3d0a9dd6 100644 --- a/src/server/game/Calendar/CalendarMgr.h +++ b/src/server/game/Calendar/CalendarMgr.h @@ -261,9 +261,9 @@ struct CalendarEvent std::string _title; std::string _description; }; - +typedef std::vector<CalendarInvite*> CalendarInviteStore; typedef std::set<CalendarEvent*> CalendarEventStore; -typedef std::map<uint64 /* eventId */, std::vector<CalendarInvite*> > CalendarInviteStore; +typedef std::map<uint64 /* eventId */, CalendarInviteStore > CalendarEventInviteStore; class CalendarMgr { @@ -274,7 +274,7 @@ class CalendarMgr ~CalendarMgr(); CalendarEventStore _events; - CalendarInviteStore _invites; + CalendarEventInviteStore _invites; std::deque<uint64> _freeEventIds; std::deque<uint64> _freeInviteIds; @@ -284,14 +284,14 @@ class CalendarMgr public: void LoadFromDB(); - CalendarEvent* GetEvent(uint64 eventId); + CalendarEvent* GetEvent(uint64 eventId) const; CalendarEventStore const& GetEvents() const { return _events; } CalendarEventStore GetPlayerEvents(uint64 guid); - CalendarInvite* GetInvite(uint64 inviteId); - CalendarInviteStore const& GetInvites() const { return _invites; } - std::vector<CalendarInvite*> GetEventInvites(uint64 eventId); - std::vector<CalendarInvite*> GetPlayerInvites(uint64 guid); + CalendarInvite* GetInvite(uint64 inviteId) const; + CalendarEventInviteStore const& GetInvites() const { return _invites; } + CalendarInviteStore const& GetEventInvites(uint64 eventId); + CalendarInviteStore GetPlayerInvites(uint64 guid); void FreeEventId(uint64 id); uint64 GetFreeEventId(); 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 3cae9d0f83a..7c92af2d67f 100644 --- a/src/server/game/Chat/Chat.cpp +++ b/src/server/game/Chat/Chat.cpp @@ -175,7 +175,7 @@ bool ChatHandler::HasLowerSecurityAccount(WorldSession* target, uint32 target_ac return false; // ignore only for non-players for non strong checks (when allow apply command at least to same sec level) - if (!AccountMgr::IsPlayerAccount(m_session->GetSecurity()) && !strong && !sWorld->getBoolConfig(CONFIG_GM_LOWER_SECURITY)) + if (m_session->HasPermission(RBAC_PERM_CHECK_FOR_LOWER_SECURITY) && !strong && !sWorld->getBoolConfig(CONFIG_GM_LOWER_SECURITY)) return false; if (target) @@ -361,6 +361,7 @@ bool ChatHandler::ExecuteCommandInTable(ChatCommand* table, const char* text, co // table[i].Name == "" is special case: send original command to handler if ((table[i].Handler)(this, table[i].Name[0] != '\0' ? text : oldtext)) { + // FIXME: When Command system is moved to RBAC this check must be changed if (!AccountMgr::IsPlayerAccount(table[i].SecurityLevel)) { // chat case @@ -476,7 +477,7 @@ bool ChatHandler::ParseCommands(char const* text) if (!ExecuteCommandInTable(getCommandTable(), text, fullcmd)) { - if (m_session && AccountMgr::IsPlayerAccount(m_session->GetSecurity())) + if (m_session && !m_session->HasPermission(RBAC_PERM_COMMANDS_NOTIFY_COMMAND_NOT_FOUND_ERROR)) return false; SendSysMessage(LANG_NO_CMD); 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/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index d2bc7c624b5..39534c1c2bf 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -2112,9 +2112,11 @@ bool Creature::LoadCreaturesAddon(bool reload) SetByteValue(UNIT_FIELD_BYTES_1, 3, uint8((cainfo->bytes1 >> 24) & 0xFF)); //! Suspected correlation between UNIT_FIELD_BYTES_1, offset 3, value 0x2: - //! If no inhabittype_fly (if no MovementFlag_DisableGravity flag found in sniffs) + //! If no inhabittype_fly (if no MovementFlag_DisableGravity or MovementFlag_CanFly flag found in sniffs) + //! Check using InhabitType as movement flags are assigned dynamically + //! basing on whether the creature is in air or not //! Set MovementFlag_Hover. Otherwise do nothing. - if (GetByteValue(UNIT_FIELD_BYTES_1, 3) & UNIT_BYTE1_FLAG_HOVER && !IsLevitating()) + if (GetByteValue(UNIT_FIELD_BYTES_1, 3) & UNIT_BYTE1_FLAG_HOVER && !(GetCreatureTemplate()->InhabitType & INHABIT_AIR)) AddUnitMovementFlag(MOVEMENTFLAG_HOVER); } diff --git a/src/server/game/Entities/Creature/TemporarySummon.h b/src/server/game/Entities/Creature/TemporarySummon.h index a96d9ab33d0..dc3347c5b4f 100644 --- a/src/server/game/Entities/Creature/TemporarySummon.h +++ b/src/server/game/Entities/Creature/TemporarySummon.h @@ -21,6 +21,22 @@ #include "Creature.h" +enum SummonerType +{ + SUMMONER_TYPE_CREATURE = 0, + SUMMONER_TYPE_GAMEOBJECT = 1, + SUMMONER_TYPE_MAP = 2 +}; + +/// Stores data for temp summons +struct TempSummonData +{ + uint32 entry; ///< Entry of summoned creature + Position pos; ///< Position, where should be creature spawned + TempSummonType type; ///< Summon type, see TempSummonType for available types + uint32 time; ///< Despawn time, usable only with certain temp summon types +}; + class TempSummon : public Creature { public: diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 893d4c1ea69..79bf656c318 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -2315,6 +2315,24 @@ TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropert return summon; } +/** +* Summons group of creatures. +* +* @param group Id of group to summon. +* @param list List to store pointers to summoned creatures. +*/ + +void Map::SummonCreatureGroup(uint8 group, std::list<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()) @@ -2394,6 +2412,25 @@ Creature* WorldObject::SummonTrigger(float x, float y, float z, float ang, uint3 return summon; } +/** +* Summons group of creatures. Should be called only by instances of Creature and GameObject classes. +* +* @param group Id of group to summon. +* @param list List to store pointers to summoned creatures. +*/ +void WorldObject::SummonCreatureGroup(uint8 group, std::list<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 ae3d545b7d7..ae788621368 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -793,6 +793,7 @@ class WorldObject : public Object, public WorldLocation } GameObject* SummonGameObject(uint32 entry, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 respawnTime); Creature* SummonTrigger(float x, float y, float z, float ang, uint32 dur, CreatureAI* (*GetAI)(Creature*) = NULL); + void SummonCreatureGroup(uint8 group, std::list<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 c7c88ae0bbe..a8a500c093a 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -668,7 +668,7 @@ Player::Player(WorldSession* session): Unit(true) //m_pad = 0; // players always accept - if (AccountMgr::IsPlayerAccount(GetSession()->GetSecurity())) + if (!GetSession()->HasPermission(RBAC_PERM_CAN_FILTER_WHISPERS)) SetAcceptWhispers(true); m_curSelection = 0; @@ -1018,7 +1018,7 @@ bool Player::Create(uint32 guidlow, CharacterCreateInfo* createInfo) ? sWorld->getIntConfig(CONFIG_START_PLAYER_LEVEL) : sWorld->getIntConfig(CONFIG_START_HEROIC_PLAYER_LEVEL); - if (!AccountMgr::IsPlayerAccount(GetSession()->GetSecurity())) + if (m_session->HasPermission(RBAC_PERM_USE_START_GM_LEVEL)) { uint32 gm_level = sWorld->getIntConfig(CONFIG_START_GM_LEVEL); if (gm_level > start_level) @@ -2069,7 +2069,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati return false; } - if (AccountMgr::IsPlayerAccount(GetSession()->GetSecurity()) && DisableMgr::IsDisabledFor(DISABLE_TYPE_MAP, mapid, this)) + if (!GetSession()->HasPermission(RBAC_PERM_SKIP_CHECK_DISABLE_MAP) && DisableMgr::IsDisabledFor(DISABLE_TYPE_MAP, mapid, this)) { sLog->outError(LOG_FILTER_MAPS, "Player (GUID: %u, name: %s) tried to enter a forbidden map %u", GetGUIDLow(), GetName().c_str(), mapid); SendTransferAborted(mapid, TRANSFER_ABORT_MAP_NOT_ALLOWED); @@ -3120,7 +3120,7 @@ void Player::InitTalentForLevel() // if used more that have then reset if (m_usedTalentCount > talentPointsForLevel) { - if (!AccountMgr::IsAdminAccount(GetSession()->GetSecurity())) + if (!GetSession()->HasPermission(RBAC_PERM_SKIP_CHECK_MORE_TALENTS_THAN_ALLOWED)) resetTalents(true); else SetFreeTalentPoints(0); @@ -16774,7 +16774,8 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder) // check name limitations if (ObjectMgr::CheckPlayerName(m_name) != CHAR_NAME_SUCCESS || - (AccountMgr::IsPlayerAccount(GetSession()->GetSecurity()) && sObjectMgr->IsReservedName(m_name))) + (!GetSession()->HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME) && + sObjectMgr->IsReservedName(m_name))) { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG); stmt->setUInt16(0, uint16(AT_LOGIN_RENAME)); @@ -17309,7 +17310,7 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder) outDebugValues(); // GM state - if (!AccountMgr::IsPlayerAccount(GetSession()->GetSecurity())) + if (GetSession()->HasPermission(RBAC_PERM_RESTORE_SAVED_GM_STATE)) { switch (sWorld->getIntConfig(CONFIG_GM_LOGIN_STATE)) { @@ -19628,7 +19629,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 e5bbac59e00..7a2b36e23bf 100644 --- a/src/server/game/Entities/Player/SocialMgr.cpp +++ b/src/server/game/Entities/Player/SocialMgr.cpp @@ -216,34 +216,38 @@ void SocialMgr::GetFriendInfo(Player* player, uint32 friendGUID, FriendInfo &fri friendInfo.Level = 0; friendInfo.Class = 0; - Player* pFriend = ObjectAccessor::FindPlayer(friendGUID); - if (!pFriend) + Player* target = ObjectAccessor::FindPlayer(friendGUID); + if (!target) return; - uint32 team = player->GetTeam(); - AccountTypes security = player->GetSession()->GetSecurity(); - bool allowTwoSideWhoList = sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_WHO_LIST); - AccountTypes gmLevelInWhoList = AccountTypes(sWorld->getIntConfig(CONFIG_GM_LEVEL_IN_WHO_LIST)); - PlayerSocialMap::iterator itr = player->GetSocial()->m_playerSocialMap.find(friendGUID); if (itr != player->GetSocial()->m_playerSocialMap.end()) friendInfo.Note = itr->second.Note; // PLAYER see his team only and PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters // MODERATOR, GAME MASTER, ADMINISTRATOR can see all - if (pFriend && - (!AccountMgr::IsPlayerAccount(security) || - ((pFriend->GetTeam() == team || allowTwoSideWhoList) && (pFriend->GetSession()->GetSecurity() <= gmLevelInWhoList))) && - pFriend->IsVisibleGloballyFor(player)) + + if (!player->GetSession()->HasPermission(RBAC_PERM_WHO_SEE_ALL_SEC_LEVELS) && + target->GetSession()->GetSecurity() > AccountTypes(sWorld->getIntConfig(CONFIG_GM_LEVEL_IN_WHO_LIST))) + return; + + // player can see member of other team only if CONFIG_ALLOW_TWO_SIDE_WHO_LIST + if (target->GetTeam() != player->GetTeam() && + !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_WHO_LIST) && !player->GetSession()->HasPermission(RBAC_PERM_TWO_SIDE_WHO_LIST)) + return; + + if (target->IsVisibleGloballyFor(player)) { - friendInfo.Status = FRIEND_STATUS_ONLINE; - if (pFriend->isAFK()) - friendInfo.Status = FRIEND_STATUS_AFK; - if (pFriend->isDND()) + if (target->isDND()) friendInfo.Status = FRIEND_STATUS_DND; - friendInfo.Area = pFriend->GetZoneId(); - friendInfo.Level = pFriend->getLevel(); - friendInfo.Class = pFriend->getClass(); + else if (target->isAFK()) + friendInfo.Status = FRIEND_STATUS_AFK; + else + friendInfo.Status = FRIEND_STATUS_ONLINE; + + friendInfo.Area = target->GetZoneId(); + friendInfo.Level = target->getLevel(); + friendInfo.Class = target->getClass(); } } @@ -295,28 +299,29 @@ void SocialMgr::BroadcastToFriendListers(Player* player, WorldPacket* packet) if (!player) return; - uint32 team = player->GetTeam(); - AccountTypes security = player->GetSession()->GetSecurity(); - uint32 guid = player->GetGUIDLow(); - AccountTypes gmLevelInWhoList = AccountTypes(sWorld->getIntConfig(CONFIG_GM_LEVEL_IN_WHO_LIST)); - bool allowTwoSideWhoList = sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_WHO_LIST); - for (SocialMap::const_iterator itr = m_socialMap.begin(); itr != m_socialMap.end(); ++itr) { - PlayerSocialMap::const_iterator itr2 = itr->second.m_playerSocialMap.find(guid); + PlayerSocialMap::const_iterator itr2 = itr->second.m_playerSocialMap.find(player->GetGUID()); if (itr2 != itr->second.m_playerSocialMap.end() && (itr2->second.Flags & SOCIAL_FLAG_FRIEND)) { - Player* pFriend = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER)); + Player* target = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER)); + if (!target || !target->IsInWorld()) + continue; + + if (!target->GetSession()->HasPermission(RBAC_PERM_WHO_SEE_ALL_SEC_LEVELS) && + player->GetSession()->GetSecurity() > AccountTypes(sWorld->getIntConfig(CONFIG_GM_LEVEL_IN_WHO_LIST))) + continue; + + // player can see member of other team only if CONFIG_ALLOW_TWO_SIDE_WHO_LIST + if (target->GetTeam() != player->GetTeam() && + !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_WHO_LIST) && + !target->GetSession()->HasPermission(RBAC_PERM_TWO_SIDE_WHO_LIST)) + continue; // PLAYER see his team only and PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters // MODERATOR, GAME MASTER, ADMINISTRATOR can see all - if (pFriend && pFriend->IsInWorld() && - (!AccountMgr::IsPlayerAccount(pFriend->GetSession()->GetSecurity()) || - ((pFriend->GetTeam() == team || allowTwoSideWhoList) && security <= gmLevelInWhoList)) && - player->IsVisibleGloballyFor(pFriend)) - { - pFriend->GetSession()->SendPacket(packet); - } + if (player->IsVisibleGloballyFor(target)) + target->GetSession()->SendPacket(packet); } } } diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index d75eb46ea8d..a7e065909b6 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -14234,7 +14234,7 @@ void Unit::StopMoving() return; Movement::MoveSplineInit init(this); - init.MoveTo(GetPositionX(), GetPositionY(), GetPositionZMinusOffset()); + init.MoveTo(GetPositionX(), GetPositionY(), GetPositionZMinusOffset(), false); init.SetFacing(GetOrientation()); init.Launch(); } @@ -16605,7 +16605,12 @@ void Unit::ChangeSeat(int8 seatId, bool next) // Todo: the functions below could be consolidated and refactored to take // SeatMap::const_iterator as parameter, to save redundant map lookups. m_vehicle->RemovePassenger(this); - if (!m_vehicle->AddPassenger(this, seatId)) + + // Set m_vehicle to NULL before adding passenger as adding new passengers is handled asynchronously + // and someone may call ExitVehicle again before passenger is added to new seat + Vehicle* veh = m_vehicle; + m_vehicle = NULL; + if (!veh->AddPassenger(this, seatId)) ASSERT(false); } @@ -17107,7 +17112,7 @@ void Unit::SetInFront(Unit const* target) void Unit::SetFacingTo(float ori) { Movement::MoveSplineInit init(this); - init.MoveTo(GetPositionX(), GetPositionY(), GetPositionZMinusOffset()); + init.MoveTo(GetPositionX(), GetPositionY(), GetPositionZMinusOffset(), false); init.SetFacing(ori); init.Launch(); } diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 62facf6a69e..b549802c91c 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -398,6 +398,7 @@ enum TriggerCastFlags TRIGGERED_IGNORE_CASTER_AURAS = 0x00010000, //! Will ignore caster aura restrictions or requirements TRIGGERED_DISALLOW_PROC_EVENTS = 0x00020000, //! Disallows proc events from triggered spell (default) TRIGGERED_DONT_REPORT_CAST_ERROR = 0x00040000, //! Will return SPELL_FAILED_DONT_REPORT in CheckCast functions + TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT = 0x00080000, //! Will ignore equipped item requirements TRIGGERED_FULL_MASK = 0xFFFFFFFF }; diff --git a/src/server/game/Entities/Vehicle/Vehicle.cpp b/src/server/game/Entities/Vehicle/Vehicle.cpp index 8b4516ca47a..f3844d96069 100755 --- a/src/server/game/Entities/Vehicle/Vehicle.cpp +++ b/src/server/game/Entities/Vehicle/Vehicle.cpp @@ -256,7 +256,7 @@ void Vehicle::RemoveAllPassengers() /// Setting to_Abort to true will cause @VehicleJoinEvent::Abort to be executed on next @Unit::UpdateEvents call /// This will properly "reset" the pending join process for the passenger. - while (_pendingJoinEvents.size()) + while (!_pendingJoinEvents.empty()) { VehicleJoinEvent* e = _pendingJoinEvents.front(); e->to_Abort = true; @@ -422,12 +422,12 @@ bool Vehicle::AddPassenger(Unit* unit, int8 seatId) /// @Prevent adding passengers when vehicle is uninstalling. (Bad script in OnUninstall/OnRemovePassenger/PassengerBoarded hook.) if (_status == STATUS_UNINSTALLING) { - sLog->outError(LOG_FILTER_VEHICLES, "Passenger GuidLow: %u, Entry: %u, attempting to board vehicle GuidLow: %u, Entry: %u during uninstall! SeatId: %i", + sLog->outError(LOG_FILTER_VEHICLES, "Passenger GuidLow: %u, Entry: %u, attempting to board vehicle GuidLow: %u, Entry: %u during uninstall! SeatId: %d", unit->GetGUIDLow(), unit->GetEntry(), _me->GetGUIDLow(), _me->GetEntry(), (int32)seatId); return false; } - sLog->outDebug(LOG_FILTER_VEHICLES, "Unit %s scheduling enter vehicle (entry: %u, vehicleId: %u, guid: %u (dbguid: %s) on seat %d", + sLog->outDebug(LOG_FILTER_VEHICLES, "Unit %s scheduling enter vehicle (entry: %u, vehicleId: %u, guid: %u (dbguid: %u) on seat %d", unit->GetName().c_str(), _me->GetEntry(), _vehicleInfo->m_ID, _me->GetGUIDLow(), (_me->GetTypeId() == TYPEID_UNIT ? _me->ToCreature()->GetDBTableGUIDLow() : 0), (int32)seatId); @@ -438,7 +438,6 @@ bool Vehicle::AddPassenger(Unit* unit, int8 seatId) SeatMap::iterator seat; VehicleJoinEvent* e = new VehicleJoinEvent(this, unit); unit->m_Events.AddEvent(e, unit->m_Events.CalculateTime(0)); - _pendingJoinEvents.push_back(e); if (seatId < 0) // no specific seat requirement { @@ -448,22 +447,24 @@ bool Vehicle::AddPassenger(Unit* unit, int8 seatId) if (seat == Seats.end()) // no available seat { - CancelJoinEvent(e); + e->to_Abort = true; return false; } e->Seat = seat; + _pendingJoinEvents.push_back(e); } else { seat = Seats.find(seatId); if (seat == Seats.end()) { - CancelJoinEvent(e); + e->to_Abort = true; return false; } e->Seat = seat; + _pendingJoinEvents.push_back(e); if (seat->second.Passenger) { Unit* passenger = ObjectAccessor::GetUnit(*GetBase(), seat->second.Passenger); @@ -485,7 +486,7 @@ bool Vehicle::AddPassenger(Unit* unit, int8 seatId) * @author Machiavelli * @date 17-2-2013 * - * @param [in,out] unit The passenger to remove.. + * @param [in,out] unit The passenger to remove. */ void Vehicle::RemovePassenger(Unit* unit) @@ -688,21 +689,53 @@ void Vehicle::CalculatePassengerOffset(float& x, float& y, float& z, float& o) } /** - * @fn void Vehicle::CancelJoinEvent(VehicleJoinEvent* e) + * @fn void Vehicle::RemovePendingEvent(VehicleJoinEvent* e) * - * @brief Aborts delayed @VehicleJoinEvent objects. - * Implies that the related unit will not be boarding the vehicle after all. + * @brief Removes @VehicleJoinEvent objects from pending join event store. + * This method only removes it after it's executed or aborted to prevent leaving + * pointers to deleted events. + * + * @author Shauren + * @date 22-2-2013 + * + * @param [in] e The VehicleJoinEvent* to remove from pending event store. + */ + +void Vehicle::RemovePendingEvent(VehicleJoinEvent* e) +{ + for (PendingJoinEventContainer::iterator itr = _pendingJoinEvents.begin(); itr != _pendingJoinEvents.end(); ++itr) + { + if (*itr == e) + { + _pendingJoinEvents.erase(itr); + break; + } + } +} + +/** + * @fn void Vehicle::RemovePendingEventsForSeat(uint8 seatId) + * + * @brief Removes any pending events for given seatId. Executed when a @VehicleJoinEvent::Execute is called * * @author Machiavelli - * @date 17-2-2013 + * @date 23-2-2013 * - * @param [in,out] e The VehicleJoinEvent* to process. + * @param seatId Identifier for the seat. */ -void Vehicle::CancelJoinEvent(VehicleJoinEvent* e) +void Vehicle::RemovePendingEventsForSeat(int8 seatId) { - e->to_Abort = true; - _pendingJoinEvents.pop_back(); + for (PendingJoinEventContainer::iterator itr = _pendingJoinEvents.begin(); itr != _pendingJoinEvents.end();) + { + if ((*itr)->Seat->first == seatId) + { + (*itr)->to_Abort = true; + _pendingJoinEvents.erase(itr++); + } + else + ++itr; + } } /** @@ -725,6 +758,8 @@ bool VehicleJoinEvent::Execute(uint64, uint32) ASSERT(Passenger->IsInWorld()); ASSERT(Target->GetBase()->IsInWorld()); + Target->RemovePendingEventsForSeat(Seat->first); + Passenger->m_vehicle = Target; Seat->second.Passenger = Passenger->GetGUID(); if (Seat->second.SeatInfo->CanEnterOrExit()) @@ -741,6 +776,7 @@ bool VehicleJoinEvent::Execute(uint64, uint32) } Passenger->InterruptNonMeleeSpells(false); + Passenger->RemoveAurasByType(SPELL_AURA_MOUNTED); Player* player = Passenger->ToPlayer(); if (player) diff --git a/src/server/game/Entities/Vehicle/Vehicle.h b/src/server/game/Entities/Vehicle/Vehicle.h index 7ec0df8e533..8b67b82cfa3 100644 --- a/src/server/game/Entities/Vehicle/Vehicle.h +++ b/src/server/game/Entities/Vehicle/Vehicle.h @@ -23,15 +23,23 @@ #include "Object.h" #include "VehicleDefines.h" #include "Unit.h" -#include <deque> +#include <list> struct VehicleEntry; class Unit; -typedef std::set<uint64> GuidSet; class VehicleJoinEvent; +typedef std::set<uint64> GuidSet; + class Vehicle : public TransportBase { + protected: + friend bool Unit::CreateVehicleKit(uint32 id, uint32 creatureEntry); + Vehicle(Unit* unit, VehicleEntry const* vehInfo, uint32 creatureEntry); + + friend void Unit::RemoveVehicleKit(); + ~Vehicle(); + public: void Install(); void Uninstall(); @@ -55,25 +63,18 @@ class Vehicle : public TransportBase void RelocatePassengers(); void RemoveAllPassengers(); void Dismiss(); - void TeleportVehicle(float x, float y, float z, float ang); bool IsVehicleInUse() { return Seats.begin() != Seats.end(); } - void SetLastShootPos(Position const& pos) { m_lastShootPos.Relocate(pos); } - Position GetLastShootPos() { return m_lastShootPos; } + void SetLastShootPos(Position const& pos) { _lastShootPos.Relocate(pos); } + Position GetLastShootPos() { return _lastShootPos; } - SeatMap Seats; ///< The collection of all seats on the vehicle. Including vacant ones. + SeatMap Seats; ///< The collection of all seats on the vehicle. Including vacant ones. VehicleSeatEntry const* GetSeatForPassenger(Unit* passenger); protected: friend class VehicleJoinEvent; - uint32 UsableSeatNum; ///< Number of seats that match VehicleSeatEntry::UsableByPlayer, used for proper display flags - - protected: - friend bool Unit::CreateVehicleKit(uint32 id, uint32 creatureEntry); - Vehicle(Unit* unit, VehicleEntry const* vehInfo, uint32 creatureEntry); - friend void Unit::RemoveVehicleKit(); - ~Vehicle(); + uint32 UsableSeatNum; ///< Number of seats that match VehicleSeatEntry::UsableByPlayer, used for proper display flags private: enum Status @@ -92,15 +93,20 @@ class Vehicle : public TransportBase /// This method transforms supplied global coordinates into local offsets void CalculatePassengerOffset(float& x, float& y, float& z, float& o); - Unit* _me; ///< The underlying unit with the vehicle kit. Can be player or creature. - VehicleEntry const* _vehicleInfo; ///< DBC data for vehicle + void RemovePendingEvent(VehicleJoinEvent* e); + void RemovePendingEventsForSeat(int8 seatId); + + private: + Unit* _me; ///< The underlying unit with the vehicle kit. Can be player or creature. + VehicleEntry const* _vehicleInfo; ///< DBC data for vehicle GuidSet vehiclePlayers; - uint32 _creatureEntry; ///< Can be different than the entry of _me in case of players - Status _status; ///< Internal variable for sanity checks - Position m_lastShootPos; - std::deque<VehicleJoinEvent*> _pendingJoinEvents; ///< Collection of delayed join events for prospective passengers - void CancelJoinEvent(VehicleJoinEvent* e); + uint32 _creatureEntry; ///< Can be different than the entry of _me in case of players + Status _status; ///< Internal variable for sanity checks + Position _lastShootPos; + + typedef std::list<VehicleJoinEvent*> PendingJoinEventContainer; + PendingJoinEventContainer _pendingJoinEvents; ///< Collection of delayed join events for prospective passengers }; class VehicleJoinEvent : public BasicEvent @@ -108,6 +114,7 @@ class VehicleJoinEvent : public BasicEvent friend class Vehicle; protected: VehicleJoinEvent(Vehicle* v, Unit* u) : Target(v), Passenger(u), Seat(Target->Seats.end()) {} + ~VehicleJoinEvent() { Target->RemovePendingEvent(this); } bool Execute(uint64, uint32); void Abort(uint64); @@ -115,4 +122,5 @@ class VehicleJoinEvent : public BasicEvent Unit* Passenger; SeatMap::iterator Seat; }; + #endif diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 0e657c5ea9e..222331c48f8 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -1421,6 +1421,92 @@ bool ObjectMgr::SetCreatureLinkedRespawn(uint32 guidLow, uint32 linkedGuidLow) return true; } +void ObjectMgr::LoadTempSummons() +{ + uint32 oldMSTime = getMSTime(); + + // 0 1 2 3 4 5 6 7 8 9 + QueryResult result = WorldDatabase.Query("SELECT summonerId, summonerType, groupId, entry, position_x, position_y, position_z, orientation, summonType, summonTime FROM creature_summon_groups"); + + if (!result) + { + sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 temp summons. DB table `creature_summon_groups` is empty."); + return; + } + + uint32 count = 0; + do + { + Field* fields = result->Fetch(); + + uint32 summonerId = fields[0].GetUInt32(); + SummonerType summonerType = SummonerType(fields[1].GetUInt8()); + uint8 group = fields[2].GetUInt8(); + + switch (summonerType) + { + case SUMMONER_TYPE_CREATURE: + if (!GetCreatureTemplate(summonerId)) + { + sLog->outError(LOG_FILTER_SQL, "Table `creature_summon_groups` has summoner with non existing entry %u for creature summoner type, skipped.", summonerId); + continue; + } + break; + case SUMMONER_TYPE_GAMEOBJECT: + if (!GetGameObjectTemplate(summonerId)) + { + sLog->outError(LOG_FILTER_SQL, "Table `creature_summon_groups` has summoner with non existing entry %u for gameobject summoner type, skipped.", summonerId); + continue; + } + break; + case SUMMONER_TYPE_MAP: + if (!sMapStore.LookupEntry(summonerId)) + { + sLog->outError(LOG_FILTER_SQL, "Table `creature_summon_groups` has summoner with non existing entry %u for map summoner type, skipped.", summonerId); + continue; + } + break; + default: + sLog->outError(LOG_FILTER_SQL, "Table `creature_summon_groups` has unhandled summoner type %u for summoner %u, skipped.", summonerType, summonerId); + continue; + } + + TempSummonData data; + data.entry = fields[3].GetUInt32(); + + if (!GetCreatureTemplate(data.entry)) + { + sLog->outError(LOG_FILTER_SQL, "Table `creature_summon_groups` has creature in group [Summoner ID: %u, Summoner Type: %u, Group ID: %u] with non existing creature entry %u, skipped.", summonerId, summonerType, group, data.entry); + continue; + } + + float posX = fields[4].GetFloat(); + float posY = fields[5].GetFloat(); + float posZ = fields[6].GetFloat(); + float orientation = fields[7].GetFloat(); + + data.pos.Relocate(posX, posY, posZ, orientation); + + data.type = TempSummonType(fields[8].GetUInt8()); + + if (data.type > TEMPSUMMON_MANUAL_DESPAWN) + { + sLog->outError(LOG_FILTER_SQL, "Table `creature_summon_groups` has unhandled temp summon type %u in group [Summoner ID: %u, Summoner Type: %u, Group ID: %u] for creature entry %u, skipped.", data.type, summonerId, summonerType, group, data.entry); + continue; + } + + data.time = fields[9].GetUInt32(); + + TempSummonGroupKey key(summonerId, summonerType, group); + _tempSummonDataStore[key].push_back(data); + + ++count; + + } while (result->NextRow()); + + sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u temp summons in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); +} + void ObjectMgr::LoadCreatures() { uint32 oldMSTime = getMSTime(); diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 88496fa9d6e..12df01fc350 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -25,6 +25,7 @@ #include "Creature.h" #include "DynamicObject.h" #include "GameObject.h" +#include "TemporarySummon.h" #include "Corpse.h" #include "QuestDef.h" #include "ItemPrototype.h" @@ -416,9 +417,29 @@ struct TrinityStringLocale StringVector Content; }; +/// Key for storing temp summon data in TempSummonDataContainer +struct TempSummonGroupKey +{ + TempSummonGroupKey(uint32 summonerEntry, SummonerType summonerType, uint8 group) + : _summonerEntry(summonerEntry), _summonerType(summonerType), _summonGroup(group) + { + } + + bool operator<(TempSummonGroupKey const& rhs) const + { + return memcmp(this, &rhs, sizeof(TempSummonGroupKey)) < 0; + } + +private: + uint32 _summonerEntry; ///< Summoner's entry + SummonerType _summonerType; ///< Summoner's type, see SummonerType for available types + uint8 _summonGroup; ///< Summon's group id +}; + typedef std::map<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; @@ -876,6 +897,7 @@ class ObjectMgr void LoadCreatureTemplates(); void LoadCreatureTemplateAddons(); void CheckCreatureTemplate(CreatureTemplate const* cInfo); + void LoadTempSummons(); void LoadCreatures(); void LoadLinkedRespawn(); bool SetCreatureLinkedRespawn(uint32 guid, uint32 linkedGuid); @@ -981,6 +1003,24 @@ class ObjectMgr return _mapObjectGuidsStore[MAKE_PAIR32(mapid, spawnMode)][cell_id]; } + /** + * Gets temp summon data for all creatures of specified group. + * + * @param summonerId Summoner's entry. + * @param summonerType Summoner's type, see SummonerType for available types. + * @param group Id of required group. + * + * @return null if group was not found, otherwise reference to the creature group data + */ + std::vector<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); @@ -1294,6 +1334,8 @@ class ObjectMgr GameObjectDataContainer _gameObjectDataStore; GameObjectLocaleContainer _gameObjectLocaleStore; GameObjectTemplateContainer _gameObjectTemplateStore; + /// Stores temp summon data grouped by summoner's entry, summoner's type and group id + TempSummonDataContainer _tempSummonDataStore; ItemTemplateContainer _itemTemplateStore; ItemLocaleContainer _itemLocaleStore; diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp index c424e5d3ffe..a1ab1b22b08 100644 --- a/src/server/game/Guilds/Guild.cpp +++ b/src/server/game/Guilds/Guild.cpp @@ -983,12 +983,15 @@ void Guild::BankMoveItemData::LogBankEvent(SQLTransaction& trans, MoveItemData* void Guild::BankMoveItemData::LogAction(MoveItemData* pFrom) const { MoveItemData::LogAction(pFrom); - if (!pFrom->IsBank() && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE) && !AccountMgr::IsPlayerAccount(m_pPlayer->GetSession()->GetSecurity())) // TODO: move to scripts + if (!pFrom->IsBank() && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE) && + m_pPlayer->GetSession()->HasPermission(RBAC_PERM_LOG_GM_TRADE)) + { sLog->outCommand(m_pPlayer->GetSession()->GetAccountId(), "GM %s (Account: %u) deposit item: %s (Entry: %d Count: %u) to guild bank (Guild ID: %u)", m_pPlayer->GetName().c_str(), m_pPlayer->GetSession()->GetAccountId(), pFrom->GetItem()->GetTemplate()->Name1.c_str(), pFrom->GetItem()->GetEntry(), pFrom->GetItem()->GetCount(), m_pGuild->GetId()); + } } Item* Guild::BankMoveItemData::_StoreItem(SQLTransaction& trans, BankTab* pTab, Item* pItem, ItemPosCount& pos, bool clone) const @@ -1729,7 +1732,7 @@ void Guild::HandleMemberDepositMoney(WorldSession* session, uint32 amount) std::string aux = ByteArrayToHexStr(reinterpret_cast<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: %u) to guild bank (Guild ID %u)", diff --git a/src/server/game/Handlers/AuctionHouseHandler.cpp b/src/server/game/Handlers/AuctionHouseHandler.cpp index 6fc88f441bb..22070d4c2c2 100644 --- a/src/server/game/Handlers/AuctionHouseHandler.cpp +++ b/src/server/game/Handlers/AuctionHouseHandler.cpp @@ -245,7 +245,7 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData) // Required stack size of auction matches to current item stack size, just move item to auctionhouse if (itemsCount == 1 && item->GetCount() == count[i]) { - if (GetSecurity() > SEC_PLAYER && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) + if (HasPermission(RBAC_PERM_LOG_GM_TRADE) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) { sLog->outCommand(GetAccountId(), "GM %s (Account: %u) create auction: %s (Entry: %u Count: %u)", GetPlayerName().c_str(), GetAccountId(), item->GetTemplate()->Name1.c_str(), item->GetEntry(), item->GetCount()); @@ -291,7 +291,7 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData) return; } - if (GetSecurity() > SEC_PLAYER && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) + if (HasPermission(RBAC_PERM_LOG_GM_TRADE) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) { sLog->outCommand(GetAccountId(), "GM %s (Account: %u) create auction: %s (Entry: %u Count: %u)", GetPlayerName().c_str(), GetAccountId(), newItem->GetTemplate()->Name1.c_str(), newItem->GetEntry(), newItem->GetCount()); diff --git a/src/server/game/Handlers/CalendarHandler.cpp b/src/server/game/Handlers/CalendarHandler.cpp index 9dbc4bec199..86f943cf1bf 100644 --- a/src/server/game/Handlers/CalendarHandler.cpp +++ b/src/server/game/Handlers/CalendarHandler.cpp @@ -57,9 +57,9 @@ void WorldSession::HandleCalendarGetCalendar(WorldPacket& /*recvData*/) WorldPacket data(SMSG_CALENDAR_SEND_CALENDAR, 1000); // Average size if no instance - std::vector<CalendarInvite*> invites = sCalendarMgr->GetPlayerInvites(guid); + CalendarInviteStore invites = sCalendarMgr->GetPlayerInvites(guid); data << uint32(invites.size()); - for (std::vector<CalendarInvite*>::const_iterator itr = invites.begin(); itr != invites.end(); ++itr) + for (CalendarInviteStore::const_iterator itr = invites.begin(); itr != invites.end(); ++itr) { data << uint64((*itr)->GetEventId()); data << uint64((*itr)->GetInviteId()); @@ -347,9 +347,9 @@ void WorldSession::HandleCalendarCopyEvent(WorldPacket& recvData) newEvent->SetEventTime(time_t(time)); sCalendarMgr->AddEvent(newEvent, CALENDAR_SENDTYPE_COPY); - std::vector<CalendarInvite*> invites = sCalendarMgr->GetEventInvites(eventId); + CalendarInviteStore invites = sCalendarMgr->GetEventInvites(eventId); - for (std::vector<CalendarInvite*>::const_iterator itr = invites.begin(); itr != invites.end(); ++itr) + for (CalendarInviteStore::const_iterator itr = invites.begin(); itr != invites.end(); ++itr) sCalendarMgr->AddInvite(newEvent, new CalendarInvite(**itr, sCalendarMgr->GetFreeInviteId(), newEvent->GetEventId())); // should we change owner when somebody makes a copy of event owned by another person? diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index b12893ff65f..eb5326e8094 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -274,7 +274,7 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData) WorldPacket data(SMSG_CHAR_CREATE, 1); // returned with diff.values in all cases - if (AccountMgr::IsPlayerAccount(GetSecurity())) + if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_TEAMMASK)) { if (uint32 mask = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_DISABLED)) { @@ -283,13 +283,17 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData) uint32 team = Player::TeamForRace(race_); switch (team) { - case ALLIANCE: disabled = mask & (1 << 0); break; - case HORDE: disabled = mask & (1 << 1); break; + case ALLIANCE: + disabled = mask & (1 << 0); + break; + case HORDE: + disabled = mask & (1 << 1); + break; } if (disabled) { - data << (uint8)CHAR_CREATE_DISABLED; + data << uint8(CHAR_CREATE_DISABLED); SendPacket(&data); return; } @@ -299,7 +303,7 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData) ChrClassesEntry const* classEntry = sChrClassesStore.LookupEntry(class_); if (!classEntry) { - data << (uint8)CHAR_CREATE_FAILED; + data << uint8(CHAR_CREATE_FAILED); SendPacket(&data); sLog->outError(LOG_FILTER_NETWORKIO, "Class (%u) not found in DBC while creating new char for account (ID: %u): wrong DBC files or cheater?", class_, GetAccountId()); return; @@ -308,7 +312,7 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData) ChrRacesEntry const* raceEntry = sChrRacesStore.LookupEntry(race_); if (!raceEntry) { - data << (uint8)CHAR_CREATE_FAILED; + data << uint8(CHAR_CREATE_FAILED); SendPacket(&data); sLog->outError(LOG_FILTER_NETWORKIO, "Race (%u) not found in DBC while creating new char for account (ID: %u): wrong DBC files or cheater?", race_, GetAccountId()); return; @@ -317,7 +321,7 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData) // prevent character creating Expansion race without Expansion account if (raceEntry->expansion > Expansion()) { - data << (uint8)CHAR_CREATE_EXPANSION; + data << uint8(CHAR_CREATE_EXPANSION); sLog->outError(LOG_FILTER_NETWORKIO, "Expansion %u account:[%d] tried to Create character with expansion %u race (%u)", Expansion(), GetAccountId(), raceEntry->expansion, race_); SendPacket(&data); return; @@ -326,13 +330,13 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData) // prevent character creating Expansion class without Expansion account if (classEntry->expansion > Expansion()) { - data << (uint8)CHAR_CREATE_EXPANSION_CLASS; + data << uint8(CHAR_CREATE_EXPANSION_CLASS); sLog->outError(LOG_FILTER_NETWORKIO, "Expansion %u account:[%d] tried to Create character with expansion %u class (%u)", Expansion(), GetAccountId(), classEntry->expansion, class_); SendPacket(&data); return; } - if (AccountMgr::IsPlayerAccount(GetSecurity())) + if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RACEMASK)) { uint32 raceMaskDisabled = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_DISABLED_RACEMASK); if ((1 << (race_ - 1)) & raceMaskDisabled) @@ -341,7 +345,10 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData) SendPacket(&data); return; } + } + if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_CLASSMASK)) + { uint32 classMaskDisabled = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_DISABLED_CLASSMASK); if ((1 << (class_ - 1)) & classMaskDisabled) { @@ -354,7 +361,7 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData) // prevent character creating with invalid name if (!normalizePlayerName(name)) { - data << (uint8)CHAR_NAME_NO_NAME; + data << uint8(CHAR_NAME_NO_NAME); SendPacket(&data); sLog->outError(LOG_FILTER_NETWORKIO, "Account:[%d] but tried to Create character with empty [name] ", GetAccountId()); return; @@ -369,29 +376,32 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData) return; } - if (AccountMgr::IsPlayerAccount(GetSecurity()) && sObjectMgr->IsReservedName(name)) + if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME) && sObjectMgr->IsReservedName(name)) { - data << (uint8)CHAR_NAME_RESERVED; + data << uint8(CHAR_NAME_RESERVED); SendPacket(&data); return; } - // speedup check for heroic class disabled case - uint32 heroic_free_slots = sWorld->getIntConfig(CONFIG_HEROIC_CHARACTERS_PER_REALM); - if (heroic_free_slots == 0 && AccountMgr::IsPlayerAccount(GetSecurity()) && class_ == CLASS_DEATH_KNIGHT) + if (class_ == CLASS_DEATH_KNIGHT && !HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_HEROIC_CHARACTER)) { - data << (uint8)CHAR_CREATE_UNIQUE_CLASS_LIMIT; - SendPacket(&data); - return; - } + // speedup check for heroic class disabled case + uint32 heroic_free_slots = sWorld->getIntConfig(CONFIG_HEROIC_CHARACTERS_PER_REALM); + if (heroic_free_slots == 0) + { + data << uint8(CHAR_CREATE_UNIQUE_CLASS_LIMIT); + SendPacket(&data); + return; + } - // speedup check for heroic class disabled case - uint32 req_level_for_heroic = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_MIN_LEVEL_FOR_HEROIC_CHARACTER); - if (AccountMgr::IsPlayerAccount(GetSecurity()) && class_ == CLASS_DEATH_KNIGHT && req_level_for_heroic > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL)) - { - data << (uint8)CHAR_CREATE_LEVEL_REQUIREMENT; - SendPacket(&data); - return; + // speedup check for heroic class disabled case + uint32 req_level_for_heroic = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_MIN_LEVEL_FOR_HEROIC_CHARACTER); + if (req_level_for_heroic > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL)) + { + data << uint8(CHAR_CREATE_LEVEL_REQUIREMENT); + SendPacket(&data); + return; + } } delete _charCreateCallback.GetParam(); // Delete existing if any, to make the callback chain reset to stage 0 @@ -482,7 +492,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte } } - bool allowTwoSideAccounts = !sWorld->IsPvPRealm() || sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_ACCOUNTS) || !AccountMgr::IsPlayerAccount(GetSecurity()); + bool allowTwoSideAccounts = !sWorld->IsPvPRealm() || sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_ACCOUNTS) || HasPermission(RBAC_PERM_TWO_SIDE_CHARACTER_CREATION); uint32 skipCinematics = sWorld->getIntConfig(CONFIG_SKIP_CINEMATICS); _charCreateCallback.FreeResult(); @@ -506,8 +516,9 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte bool haveSameRace = false; uint32 heroicReqLevel = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_MIN_LEVEL_FOR_HEROIC_CHARACTER); bool hasHeroicReqLevel = (heroicReqLevel == 0); - bool allowTwoSideAccounts = !sWorld->IsPvPRealm() || sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_ACCOUNTS) || !AccountMgr::IsPlayerAccount(GetSecurity()); + bool allowTwoSideAccounts = !sWorld->IsPvPRealm() || sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_ACCOUNTS) || HasPermission(RBAC_PERM_TWO_SIDE_CHARACTER_CREATION); uint32 skipCinematics = sWorld->getIntConfig(CONFIG_SKIP_CINEMATICS); + bool checkHeroicReqs = createInfo->Class == CLASS_DEATH_KNIGHT && !HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_HEROIC_CHARACTER); if (result) { @@ -517,7 +528,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte Field* field = result->Fetch(); uint8 accRace = field[1].GetUInt8(); - if (AccountMgr::IsPlayerAccount(GetSecurity()) && createInfo->Class == CLASS_DEATH_KNIGHT) + if (checkHeroicReqs) { uint8 accClass = field[2].GetUInt8(); if (accClass == CLASS_DEATH_KNIGHT) @@ -576,7 +587,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte if (!haveSameRace) haveSameRace = createInfo->Race == accRace; - if (AccountMgr::IsPlayerAccount(GetSecurity()) && createInfo->Class == CLASS_DEATH_KNIGHT) + if (checkHeroicReqs) { uint8 acc_class = field[2].GetUInt8(); if (acc_class == CLASS_DEATH_KNIGHT) @@ -605,7 +616,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte } } - if (AccountMgr::IsPlayerAccount(GetSecurity()) && createInfo->Class == CLASS_DEATH_KNIGHT && !hasHeroicReqLevel) + if (checkHeroicReqs && !hasHeroicReqLevel) { WorldPacket data(SMSG_CHAR_CREATE, 1); data << uint8(CHAR_CREATE_LEVEL_REQUIREMENT); @@ -1122,7 +1133,7 @@ void WorldSession::HandleCharRenameOpcode(WorldPacket& recvData) } // check name limitations - if (AccountMgr::IsPlayerAccount(GetSecurity()) && sObjectMgr->IsReservedName(newName)) + if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME) && sObjectMgr->IsReservedName(newName)) { WorldPacket data(SMSG_CHAR_RENAME, 1); data << uint8(CHAR_NAME_RESERVED); @@ -1444,7 +1455,7 @@ void WorldSession::HandleCharCustomize(WorldPacket& recvData) } // check name limitations - if (AccountMgr::IsPlayerAccount(GetSecurity()) && sObjectMgr->IsReservedName(newName)) + if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME) && sObjectMgr->IsReservedName(newName)) { WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1); data << uint8(CHAR_NAME_RESERVED); @@ -1690,7 +1701,7 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData) return; } - if (AccountMgr::IsPlayerAccount(GetSecurity())) + if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RACEMASK)) { uint32 raceMaskDisabled = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_DISABLED_RACEMASK); if ((1 << (race - 1)) & raceMaskDisabled) @@ -1721,7 +1732,7 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData) } // check name limitations - if (AccountMgr::IsPlayerAccount(GetSecurity()) && sObjectMgr->IsReservedName(newname)) + if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME) && sObjectMgr->IsReservedName(newname)) { WorldPacket data(SMSG_CHAR_FACTION_CHANGE, 1); data << uint8(CHAR_NAME_RESERVED); diff --git a/src/server/game/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp index d04d365504d..efb3a3b6d7c 100644 --- a/src/server/game/Handlers/ChatHandler.cpp +++ b/src/server/game/Handlers/ChatHandler.cpp @@ -273,20 +273,22 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) } Player* receiver = sObjectAccessor->FindPlayerByName(to); - bool senderIsPlayer = AccountMgr::IsPlayerAccount(GetSecurity()); - bool receiverIsPlayer = AccountMgr::IsPlayerAccount(receiver ? receiver->GetSession()->GetSecurity() : SEC_PLAYER); - if (!receiver || (senderIsPlayer && !receiverIsPlayer && !receiver->isAcceptWhispers() && !receiver->IsInWhisperWhiteList(sender->GetGUID()))) + if (!receiver || (!HasPermission(RBAC_PERM_CAN_FILTER_WHISPERS) && + receiver->GetSession()->HasPermission(RBAC_PERM_CAN_FILTER_WHISPERS) && + !receiver->isAcceptWhispers() && !receiver->IsInWhisperWhiteList(sender->GetGUID()))) { SendPlayerNotFoundNotice(to); return; } - if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT) && senderIsPlayer && receiverIsPlayer) - if (GetPlayer()->GetTeam() != receiver->GetTeam()) - { - SendWrongFactionNotice(); - return; - } + if (GetPlayer()->GetTeam() != receiver->GetTeam() && + (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT) || + !HasPermission(RBAC_PERM_TWO_SIDE_INTERACTION_CHAT) || + !receiver->GetSession()->HasPermission(RBAC_PERM_TWO_SIDE_INTERACTION_CHAT))) + { + SendWrongFactionNotice(); + return; + } if (GetPlayer()->HasAura(1852) && !receiver->isGameMaster()) { @@ -295,7 +297,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) } // If player is a Gamemaster and doesn't accept whisper, we auto-whitelist every player that the Gamemaster is talking to - if (!senderIsPlayer && !sender->isAcceptWhispers() && !sender->IsInWhisperWhiteList(receiver->GetGUID())) + if (HasPermission(RBAC_PERM_CAN_FILTER_WHISPERS) && !sender->isAcceptWhispers() && !sender->IsInWhisperWhiteList(receiver->GetGUID())) sender->AddWhisperWhiteList(receiver->GetGUID()); GetPlayer()->Whisper(msg, lang, receiver->GetGUID()); @@ -420,7 +422,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) } break; case CHAT_MSG_CHANNEL: { - if (AccountMgr::IsPlayerAccount(GetSecurity())) + if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHAT_CHANNEL_REQ)) { if (_player->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_CHANNEL_LEVEL_REQ)) { diff --git a/src/server/game/Handlers/MailHandler.cpp b/src/server/game/Handlers/MailHandler.cpp index 14b6df23061..3cdd3d854a1 100644 --- a/src/server/game/Handlers/MailHandler.cpp +++ b/src/server/game/Handlers/MailHandler.cpp @@ -32,23 +32,16 @@ void WorldSession::HandleSendMail(WorldPacket& recvData) { uint64 mailbox, unk3; - std::string receiver, subject, body; + std::string receiverName, subject, body; uint32 unk1, unk2, money, COD; uint8 unk4; - recvData >> mailbox; - recvData >> receiver; - - recvData >> subject; - - recvData >> body; - - recvData >> unk1; // stationery? - recvData >> unk2; // 0x00000000 - uint8 items_count; - recvData >> items_count; // attached items count + recvData >> mailbox >> receiverName >> subject >> body + >> unk1 // stationery? + >> unk2 // 0x00000000 + >> items_count; // attached items count - if (items_count > MAX_MAIL_ITEMS) // client limit + if (items_count > MAX_MAIL_ITEMS) // client limit { GetPlayer()->SendMailResult(0, MAIL_SEND, MAIL_ERR_TOO_MANY_ATTACHMENTS); recvData.rfinish(); // set to end to avoid warnings spam @@ -72,7 +65,7 @@ void WorldSession::HandleSendMail(WorldPacket& recvData) if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX)) return; - if (receiver.empty()) + if (receiverName.empty()) return; Player* player = _player; @@ -83,21 +76,26 @@ void WorldSession::HandleSendMail(WorldPacket& recvData) return; } - uint64 rc = 0; - if (normalizePlayerName(receiver)) - rc = sObjectMgr->GetPlayerGUIDByName(receiver); + uint64 receiverGuid = 0; + if (normalizePlayerName(receiverName)) + receiverGuid = sObjectMgr->GetPlayerGUIDByName(receiverName); - if (!rc) + if (!receiverGuid) { - sLog->outInfo(LOG_FILTER_NETWORKIO, "Player %u is sending mail to %s (GUID: not existed!) with subject %s and body %s includes %u items, %u copper and %u COD copper with unk1 = %u, unk2 = %u", - player->GetGUIDLow(), receiver.c_str(), subject.c_str(), body.c_str(), items_count, money, COD, unk1, unk2); + sLog->outInfo(LOG_FILTER_NETWORKIO, "Player %u is sending mail to %s (GUID: not existed!) with subject %s " + "and body %s includes %u items, %u copper and %u COD copper with unk1 = %u, unk2 = %u", + player->GetGUIDLow(), receiverName.c_str(), subject.c_str(), body.c_str(), + items_count, money, COD, unk1, unk2); player->SendMailResult(0, MAIL_SEND, MAIL_ERR_RECIPIENT_NOT_FOUND); return; } - sLog->outInfo(LOG_FILTER_NETWORKIO, "Player %u is sending mail to %s (GUID: %u) with subject %s and body %s includes %u items, %u copper and %u COD copper with unk1 = %u, unk2 = %u", player->GetGUIDLow(), receiver.c_str(), GUID_LOPART(rc), subject.c_str(), body.c_str(), items_count, money, COD, unk1, unk2); + sLog->outInfo(LOG_FILTER_NETWORKIO, "Player %u is sending mail to %s (GUID: %u) with subject %s and body %s " + "includes %u items, %u copper and %u COD copper with unk1 = %u, unk2 = %u", + player->GetGUIDLow(), receiverName.c_str(), GUID_LOPART(receiverGuid), subject.c_str(), + body.c_str(), items_count, money, COD, unk1, unk2); - if (player->GetGUID() == rc) + if (player->GetGUID() == receiverGuid) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_CANNOT_SEND_TO_SELF); return; @@ -113,58 +111,62 @@ void WorldSession::HandleSendMail(WorldPacket& recvData) return; } - Player* receive = ObjectAccessor::FindPlayer(rc); + Player* receiver = ObjectAccessor::FindPlayer(receiverGuid); - uint32 rc_team = 0; - uint8 mails_count = 0; //do not allow to send to one player more than 100 mails - uint8 receiveLevel = 0; + uint32 receiverTeam = 0; + uint8 mailsCount = 0; //do not allow to send to one player more than 100 mails + uint8 receiverLevel = 0; + uint32 receiverAccountId = 0; + bool canReceiveMailFromOtherFaction = false; - if (receive) + if (receiver) { - rc_team = receive->GetTeam(); - mails_count = receive->GetMailSize(); - receiveLevel = receive->getLevel(); + receiverTeam = receiver->GetTeam(); + mailsCount = receiver->GetMailSize(); + receiverLevel = receiver->getLevel(); + receiverAccountId = receiver->GetSession()->GetAccountId(); + canReceiveMailFromOtherFaction = receiver->GetSession()->HasPermission(RBAC_PERM_TWO_SIDE_INTERACTION_MAIL); } else { - rc_team = sObjectMgr->GetPlayerTeamByGUID(rc); + receiverTeam = sObjectMgr->GetPlayerTeamByGUID(receiverGuid); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAIL_COUNT); - - stmt->setUInt32(0, GUID_LOPART(rc)); + stmt->setUInt32(0, GUID_LOPART(receiverGuid)); PreparedQueryResult result = CharacterDatabase.Query(stmt); - if (result) { Field* fields = result->Fetch(); - mails_count = fields[0].GetUInt64(); + mailsCount = fields[0].GetUInt64(); } stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_LEVEL); - - stmt->setUInt32(0, GUID_LOPART(rc)); + stmt->setUInt32(0, GUID_LOPART(receiverGuid)); result = CharacterDatabase.Query(stmt); - if (result) { Field* fields = result->Fetch(); - receiveLevel = fields[0].GetUInt8(); + receiverLevel = fields[0].GetUInt8(); } + + receiverAccountId = sObjectMgr->GetPlayerAccountIdByGUID(receiverGuid); + canReceiveMailFromOtherFaction = AccountMgr::HasPermission(receiverAccountId, RBAC_PERM_TWO_SIDE_INTERACTION_MAIL, realmID); } - //do not allow to have more than 100 mails in mailbox.. mails count is in opcode uint8!!! - so max can be 255.. - if (mails_count > 100) + + // do not allow to have more than 100 mails in mailbox.. mails count is in opcode uint8!!! - so max can be 255.. + if (mailsCount > 100) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_RECIPIENT_CAP_REACHED); return; } + // test the receiver's Faction... or all items are account bound bool accountBound = items_count ? true : false; for (uint8 i = 0; i < items_count; ++i) { - Item* item = player->GetItemByGuid(itemGUIDs[i]); - if (item) + if (Item* item = player->GetItemByGuid(itemGUIDs[i])) { ItemTemplate const* itemProto = item->GetTemplate(); if (!itemProto || !(itemProto->Flags & ITEM_PROTO_FLAG_BIND_TO_ACCOUNT)) @@ -175,22 +177,21 @@ void WorldSession::HandleSendMail(WorldPacket& recvData) } } - if (!accountBound && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_MAIL) && player->GetTeam() != rc_team && AccountMgr::IsPlayerAccount(GetSecurity())) + if (!accountBound && player->GetTeam() != receiverTeam && // Sender and reciver are from different faction + (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_MAIL) || // Config not enabled + !HasPermission(RBAC_PERM_TWO_SIDE_INTERACTION_MAIL) || // Sender cant mail interact with the other faction + !canReceiveMailFromOtherFaction)) // Receiver cant mail interact with the other faction { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_NOT_YOUR_TEAM); return; } - if (receiveLevel < sWorld->getIntConfig(CONFIG_MAIL_LEVEL_REQ)) + if (receiverLevel < sWorld->getIntConfig(CONFIG_MAIL_LEVEL_REQ)) { SendNotification(GetTrinityString(LANG_MAIL_RECEIVER_REQ), sWorld->getIntConfig(CONFIG_MAIL_LEVEL_REQ)); return; } - uint32 rc_account = receive - ? receive->GetSession()->GetAccountId() - : sObjectMgr->GetPlayerAccountIdByGUID(rc); - Item* items[MAX_MAIL_ITEMS]; for (uint8 i = 0; i < items_count; ++i) @@ -216,7 +217,7 @@ void WorldSession::HandleSendMail(WorldPacket& recvData) return; } - if (item->IsBoundAccountWide() && item->IsSoulBound() && player->GetSession()->GetAccountId() != rc_account) + if (item->IsBoundAccountWide() && item->IsSoulBound() && player->GetSession()->GetAccountId() != receiverAccountId) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_ARTEFACTS_ONLY_FOR_OWN_CHARACTERS); return; @@ -256,35 +257,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: %u to player: %s (Account: %u)", - GetPlayerName().c_str(), GetAccountId(), money, receiver.c_str(), rc_account); + GetPlayerName().c_str(), GetAccountId(), money, receiverName.c_str(), receiverAccountId); } } @@ -295,7 +299,7 @@ void WorldSession::HandleSendMail(WorldPacket& recvData) draft .AddMoney(money) .AddCOD(COD) - .SendMailTo(trans, MailReceiver(receive, GUID_LOPART(rc)), MailSender(player), body.empty() ? MAIL_CHECK_MASK_COPIED : MAIL_CHECK_MASK_HAS_BODY, deliver_delay); + .SendMailTo(trans, MailReceiver(receiver, GUID_LOPART(receiverGuid)), MailSender(player), body.empty() ? MAIL_CHECK_MASK_COPIED : MAIL_CHECK_MASK_HAS_BODY, deliver_delay); player->SaveInventoryAndGoldToDB(trans); CharacterDatabase.CommitTransaction(trans); @@ -458,17 +462,17 @@ void WorldSession::HandleMailTakeItem(WorldPacket& recvData) if (m->COD > 0) //if there is COD, take COD money from player and send them to sender by mail { uint64 sender_guid = MAKE_NEW_GUID(m->sender, 0, HIGHGUID_PLAYER); - Player* receive = ObjectAccessor::FindPlayer(sender_guid); + Player* receiver = ObjectAccessor::FindPlayer(sender_guid); uint32 sender_accId = 0; - if (!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 { @@ -478,18 +482,18 @@ void WorldSession::HandleMailTakeItem(WorldPacket& recvData) if (!sObjectMgr->GetPlayerNameByGUID(sender_guid, sender_name)) sender_name = sObjectMgr->GetTrinityStringForDBCLocale(LANG_UNKNOWN); } - sLog->outCommand(GetAccountId(), "GM %s (Account: %u) receive mail item: %s (Entry: %u Count: %u) and send COD money: %u to player: %s (Account: %u)", + sLog->outCommand(GetAccountId(), "GM %s (Account: %u) receiver mail item: %s (Entry: %u Count: %u) and send COD money: %u to player: %s (Account: %u)", GetPlayerName().c_str(), GetAccountId(), it->GetTemplate()->Name1.c_str(), it->GetEntry(), it->GetCount(), m->COD, sender_name.c_str(), sender_accId); } - else if (!receive) + else if (!receiver) sender_accId = sObjectMgr->GetPlayerAccountIdByGUID(sender_guid); // check player existence - if (receive || sender_accId) + if (receiver || sender_accId) { MailDraft(m->subject, "") .AddMoney(m->COD) - .SendMailTo(trans, MailReceiver(receive, m->sender), MailSender(MAIL_NORMAL, m->receiver), MAIL_CHECK_MASK_COD_PAYMENT); + .SendMailTo(trans, MailReceiver(receiver, m->sender), MailSender(MAIL_NORMAL, m->receiver), MAIL_CHECK_MASK_COD_PAYMENT); } player->ModifyMoney(-int32(m->COD)); diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index c7299be2853..3864acb8f88 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -241,7 +241,7 @@ void WorldSession::HandleWhoOpcode(WorldPacket& recvData) level_max = STRONG_MAX_LEVEL; uint32 team = _player->GetTeam(); - uint32 security = GetSecurity(); + bool allowTwoSideWhoList = sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_WHO_LIST); uint32 gmLevelInWhoList = sWorld->getIntConfig(CONFIG_GM_LEVEL_IN_WHO_LIST); uint32 displaycount = 0; @@ -254,42 +254,40 @@ void WorldSession::HandleWhoOpcode(WorldPacket& recvData) HashMapHolder<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; @@ -375,33 +373,34 @@ void WorldSession::HandleLogoutRequestOpcode(WorldPacket& /*recvData*/) if (uint64 lguid = GetPlayer()->GetLootGUID()) DoLootRelease(lguid); - uint8 reason = 0; + bool instantLogout = (GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING) && !GetPlayer()->isInCombat()) || + GetPlayer()->isInFlight() || HasPermission(RBAC_PERM_INSTANT_LOGOUT); + + /// TODO: Possibly add RBAC permission to log out in combat + bool canLogoutInCombat = GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING); - if (GetPlayer()->isInCombat()) + uint32 reason = 0; + if (GetPlayer()->isInCombat() && !canLogoutInCombat) reason = 1; else if (GetPlayer()->m_movementInfo.HasMovementFlag(MOVEMENTFLAG_FALLING | MOVEMENTFLAG_FALLING_FAR)) reason = 3; // is jumping or falling else if (GetPlayer()->duel || GetPlayer()->HasAura(9454)) // is dueling or frozen by GM via freeze command reason = 2; // FIXME - Need the correct value + WorldPacket data(SMSG_LOGOUT_RESPONSE, 1+4); + data << uint32(reason); + data << uint8(instantLogout); + SendPacket(&data); + if (reason) { - WorldPacket data(SMSG_LOGOUT_RESPONSE, 1+4); - data << uint8(reason); - data << uint32(0); - SendPacket(&data); LogoutRequest(0); return; } //instant logout in taverns/cities or on taxi or for admins, gm's, mod's if its enabled in worldserver.conf - if (GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING) || GetPlayer()->isInFlight() || - HasPermission(RBAC_PERM_INSTANT_LOGOUT)) + if (instantLogout) { - WorldPacket data(SMSG_LOGOUT_RESPONSE, 1+4); - data << uint8(0); - data << uint32(16777216); - SendPacket(&data); LogoutPlayer(true); return; } @@ -418,10 +417,6 @@ void WorldSession::HandleLogoutRequestOpcode(WorldPacket& /*recvData*/) GetPlayer()->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED); } - WorldPacket data(SMSG_LOGOUT_RESPONSE, 1+4); - data << uint8(0); - data << uint32(0); - SendPacket(&data); LogoutRequest(time(NULL)); } @@ -578,13 +573,14 @@ void WorldSession::HandleAddFriendOpcodeCallBack(PreparedQueryResult result, std team = Player::TeamForRace(fields[1].GetUInt8()); friendAccountId = fields[2].GetUInt32(); - if (!AccountMgr::IsPlayerAccount(GetSecurity()) || sWorld->getBoolConfig(CONFIG_ALLOW_GM_FRIEND) || AccountMgr::IsPlayerAccount(AccountMgr::GetSecurity(friendAccountId, realmID))) + if (HasPermission(RBAC_PERM_ALLOW_GM_FRIEND) || sWorld->getBoolConfig(CONFIG_ALLOW_GM_FRIEND) || + AccountMgr::IsPlayerAccount(AccountMgr::GetSecurity(friendAccountId, realmID))) { if (friendGuid) { if (friendGuid == GetPlayer()->GetGUID()) friendResult = FRIEND_SELF; - else if (GetPlayer()->GetTeam() != team && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_ADD_FRIEND) && AccountMgr::IsPlayerAccount(GetSecurity())) + else if (GetPlayer()->GetTeam() != team && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_ADD_FRIEND) && !HasPermission(RBAC_PERM_TWO_SIDE_ADD_FRIEND)) friendResult = FRIEND_ENEMY; else if (GetPlayer()->GetSocial()->HasFriend(GUID_LOPART(friendGuid))) friendResult = FRIEND_ALREADY; @@ -1251,7 +1247,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); @@ -1263,7 +1259,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 bb31b5c1dc8..7fbb68b70f8 100644 --- a/src/server/game/Handlers/TradeHandler.cpp +++ b/src/server/game/Handlers/TradeHandler.cpp @@ -152,7 +152,7 @@ void WorldSession::moveItems(Item* myItems[], Item* hisItems[]) { // logging sLog->outDebug(LOG_FILTER_NETWORKIO, "partner storing: %u", myItems[i]->GetGUIDLow()); - if (!AccountMgr::IsPlayerAccount(_player->GetSession()->GetSecurity()) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) + if (HasPermission(RBAC_PERM_LOG_GM_TRADE) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) { sLog->outCommand(_player->GetSession()->GetAccountId(), "GM %s (Account: %u) trade: %s (Entry: %d Count: %u) to player: %s (Account: %u)", _player->GetName().c_str(), _player->GetSession()->GetAccountId(), @@ -170,7 +170,7 @@ void WorldSession::moveItems(Item* myItems[], Item* hisItems[]) { // logging sLog->outDebug(LOG_FILTER_NETWORKIO, "player storing: %u", hisItems[i]->GetGUIDLow()); - if (!AccountMgr::IsPlayerAccount(trader->GetSession()->GetSecurity()) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) + if (HasPermission(RBAC_PERM_LOG_GM_TRADE) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) { sLog->outCommand(trader->GetSession()->GetAccountId(), "GM %s (Account: %u) trade: %s (Entry: %d Count: %u) to player: %s (Account: %u)", trader->GetName().c_str(), trader->GetSession()->GetAccountId(), @@ -473,16 +473,17 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/) moveItems(myItems, hisItems); // logging money - if (sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) + if (HasPermission(RBAC_PERM_LOG_GM_TRADE) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) { - if (!AccountMgr::IsPlayerAccount(_player->GetSession()->GetSecurity()) && my_trade->GetMoney() > 0) + if (my_trade->GetMoney() > 0) { sLog->outCommand(_player->GetSession()->GetAccountId(), "GM %s (Account: %u) give money (Amount: %u) to player: %s (Account: %u)", _player->GetName().c_str(), _player->GetSession()->GetAccountId(), my_trade->GetMoney(), trader->GetName().c_str(), trader->GetSession()->GetAccountId()); } - if (!AccountMgr::IsPlayerAccount(trader->GetSession()->GetSecurity()) && his_trade->GetMoney() > 0) + + if (his_trade->GetMoney() > 0) { sLog->outCommand(trader->GetSession()->GetAccountId(), "GM %s (Account: %u) give money (Amount: %u) to player: %s (Account: %u)", trader->GetName().c_str(), trader->GetSession()->GetAccountId(), diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index 6bf7edf3a2f..cc47f053827 100644 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -435,6 +435,7 @@ class Map : public GridRefManager<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 a2d1cdd83dd..6d58dfbf27d 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -489,7 +489,7 @@ enum SpellAttr6 SPELL_ATTR6_UNK3 = 0x00000008, // 3 SPELL_ATTR6_UNK4 = 0x00000010, // 4 SPELL_ATTR6_UNK5 = 0x00000020, // 5 - SPELL_ATTR6_UNK6 = 0x00000040, // 6 + SPELL_ATTR6_PRINT_SPELLNAME = 0x00000040, // 6 when activated, spell name is shown at the center of the screen: <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 522dc95105d..1e36f342712 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -24,6 +24,7 @@ #include "Config.h" #include "Common.h" #include "DatabaseEnv.h" +#include "AccountMgr.h" #include "Log.h" #include "Opcodes.h" #include "WorldPacket.h" @@ -408,14 +409,14 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater) } /// %Log the player out -void WorldSession::LogoutPlayer(bool Save) +void WorldSession::LogoutPlayer(bool save) { // finish pending transfers before starting the logout while (_player && _player->IsBeingTeleportedFar()) HandleMoveWorldportAckOpcode(); m_playerLogout = true; - m_playerSave = Save; + m_playerSave = save; if (_player) { @@ -430,39 +431,6 @@ void WorldSession::LogoutPlayer(bool Save) _player->BuildPlayerRepop(); _player->RepopAtGraveyard(); } - else if (!_player->getAttackers().empty()) - { - // build set of player who attack _player or who have pet attacking of _player - std::set<Player*> aset; - for (Unit::AttackerSet::const_iterator itr = _player->getAttackers().begin(); itr != _player->getAttackers().end(); ++itr) - { - Unit* owner = (*itr)->GetOwner(); // including player controlled case - if (owner && owner->GetTypeId() == TYPEID_PLAYER) - aset.insert(owner->ToPlayer()); - else if ((*itr)->GetTypeId() == TYPEID_PLAYER) - aset.insert((Player*)(*itr)); - } - - // CombatStop() method is removing all attackers from the AttackerSet - // That is why it must be AFTER building current set of attackers - _player->CombatStop(); - _player->getHostileRefManager().setOnlineOfflineState(false); - _player->RemoveAllAurasOnDeath(); - _player->SetPvPDeath(!aset.empty()); - _player->KillPlayer(); - _player->BuildPlayerRepop(); - _player->RepopAtGraveyard(); - - // give honor to all attackers from set like group case - for (std::set<Player*>::const_iterator itr = aset.begin(); itr != aset.end(); ++itr) - (*itr)->RewardHonor(_player, aset.size()); - - // give bg rewards and update counters like kill by first from attackers - // this can't be called for all attackers. - if (!aset.empty()) - if (Battleground* bg = _player->GetBattleground()) - bg->HandleKillPlayer(_player, *aset.begin()); - } else if (_player->HasAuraType(SPELL_AURA_SPIRIT_OF_REDEMPTION)) { // this will kill character by SPELL_AURA_SPIRIT_OF_REDEMPTION @@ -511,7 +479,7 @@ void WorldSession::LogoutPlayer(bool Save) ///- empty buyback items and save the player in the database // some save parts only correctly work in case player present in map/player_lists (pets, etc) - if (Save) + if (save) { uint32 eslot; for (int j = BUYBACK_SLOT_START; j < BUYBACK_SLOT_END; ++j) diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index c1d7f0b00db..20fa7d9335d 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -24,7 +24,6 @@ #define __WORLDSESSION_H #include "Common.h" -#include "AccountMgr.h" #include "SharedDefines.h" #include "AddonMgr.h" #include "DatabaseEnv.h" @@ -40,6 +39,7 @@ class LoginQueryHolder; class Object; class Player; class Quest; +class RBACData; class SpellCastTargets; class Unit; class Warden; @@ -253,7 +253,7 @@ class WorldSession return (_logoutTime > 0 && currTime >= _logoutTime + 20); } - void LogoutPlayer(bool Save); + void LogoutPlayer(bool save); void KickPlayer(); void QueuePacket(WorldPacket* new_packet); diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp index de5dd1dd98b..128175d785b 100644 --- a/src/server/game/Server/WorldSocket.cpp +++ b/src/server/game/Server/WorldSocket.cpp @@ -980,7 +980,7 @@ int WorldSocket::HandlePing (WorldPacket& recvPacket) { ACE_GUARD_RETURN (LockType, Guard, m_SessionLock, -1); - if (m_Session && AccountMgr::IsPlayerAccount(m_Session->GetSecurity())) + if (m_Session && !m_Session->HasPermission(RBAC_PERM_SKIP_CHECK_OVERSPEED_PING)) { sLog->outError(LOG_FILTER_NETWORKIO, "WorldSocket::HandlePing: %s kicked for over-speed pings (address: %s)", m_Session->GetPlayerInfo().c_str(), GetRemoteAddress().c_str()); diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 53bcd6bd077..ae1389c5f11 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -5942,8 +5942,9 @@ SpellCastResult Spell::CheckItems() // if not item target then required item must be equipped else { - if (m_caster->GetTypeId() == TYPEID_PLAYER && !m_caster->ToPlayer()->HasItemFitToSpellRequirements(m_spellInfo)) - return SPELL_FAILED_EQUIPPED_ITEM_CLASS; + if (!(_triggeredCastFlags & TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT)) + if (m_caster->GetTypeId() == TYPEID_PLAYER && !m_caster->ToPlayer()->HasItemFitToSpellRequirements(m_spellInfo)) + return SPELL_FAILED_EQUIPPED_ITEM_CLASS; } // check spell focus object @@ -6325,7 +6326,7 @@ SpellCastResult Spell::CheckItems() } // check weapon presence in slots for main/offhand weapons - if (m_spellInfo->EquippedItemClass >=0) + if (!(_triggeredCastFlags & TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT) && m_spellInfo->EquippedItemClass >=0) { // main hand weapon required if (m_spellInfo->AttributesEx3 & SPELL_ATTR3_MAIN_HAND) diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index f5504f8b7c1..9d3ec6630e5 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -2763,7 +2763,7 @@ void Spell::EffectEnchantItemPerm(SpellEffIndex effIndex) if (!item_owner) return; - if (item_owner != p_caster && !AccountMgr::IsPlayerAccount(p_caster->GetSession()->GetSecurity()) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) + if (item_owner != p_caster && p_caster->GetSession()->HasPermission(RBAC_PERM_LOG_GM_TRADE) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) { sLog->outCommand(p_caster->GetSession()->GetAccountId(), "GM %s (Account: %u) enchanting(perm): %s (Entry: %d) for player: %s (Account: %u)", p_caster->GetName().c_str(), p_caster->GetSession()->GetAccountId(), @@ -2828,7 +2828,7 @@ void Spell::EffectEnchantItemPrismatic(SpellEffIndex effIndex) if (!item_owner) return; - if (item_owner != p_caster && !AccountMgr::IsPlayerAccount(p_caster->GetSession()->GetSecurity()) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) + if (item_owner != p_caster && p_caster->GetSession()->HasPermission(RBAC_PERM_LOG_GM_TRADE) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) { sLog->outCommand(p_caster->GetSession()->GetAccountId(), "GM %s (Account: %u) enchanting(perm): %s (Entry: %d) for player: %s (Account: %u)", p_caster->GetName().c_str(), p_caster->GetSession()->GetAccountId(), @@ -2962,7 +2962,7 @@ void Spell::EffectEnchantItemTmp(SpellEffIndex effIndex) if (!item_owner) return; - if (item_owner != p_caster && !AccountMgr::IsPlayerAccount(p_caster->GetSession()->GetSecurity()) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) + if (item_owner != p_caster && p_caster->GetSession()->HasPermission(RBAC_PERM_LOG_GM_TRADE) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) { sLog->outCommand(p_caster->GetSession()->GetAccountId(), "GM %s (Account: %u) enchanting(temp): %s (Entry: %d) for player: %s (Account: %u)", p_caster->GetName().c_str(), p_caster->GetSession()->GetAccountId(), diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 29ecdbb033e..955f3b7b99f 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1223,7 +1223,7 @@ void World::LoadConfigSettings(bool reload) m_bool_configs[CONFIG_PDUMP_NO_OVERWRITE] = ConfigMgr::GetBoolDefault("PlayerDump.DisallowOverwrite", true); m_bool_configs[CONFIG_UI_QUESTLEVELS_IN_DIALOGS] = ConfigMgr::GetBoolDefault("UI.ShowQuestLevelsInDialogs", false); - // call ScriptMgr if we're reloading the configuration + // Wintergrasp battlefield m_bool_configs[CONFIG_WINTERGRASP_ENABLE] = ConfigMgr::GetBoolDefault("Wintergrasp.Enable", false); m_int_configs[CONFIG_WINTERGRASP_PLR_MAX] = ConfigMgr::GetIntDefault("Wintergrasp.PlayerMax", 100); m_int_configs[CONFIG_WINTERGRASP_PLR_MIN] = ConfigMgr::GetIntDefault("Wintergrasp.PlayerMin", 0); @@ -1232,6 +1232,7 @@ void World::LoadConfigSettings(bool reload) m_int_configs[CONFIG_WINTERGRASP_NOBATTLETIME] = ConfigMgr::GetIntDefault("Wintergrasp.NoBattleTimer", 150); m_int_configs[CONFIG_WINTERGRASP_RESTART_AFTER_CRASH] = ConfigMgr::GetIntDefault("Wintergrasp.CrashRestartTimer", 10); + // call ScriptMgr if we're reloading the configuration if (reload) sScriptMgr->OnConfigLoad(reload); } @@ -1432,6 +1433,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(); @@ -2114,18 +2118,21 @@ void World::SendGlobalMessage(WorldPacket* packet, WorldSession* self, uint32 te /// Send a packet to all GMs (except self if mentioned) void World::SendGlobalGMMessage(WorldPacket* packet, WorldSession* self, uint32 team) { - SessionMap::iterator itr; - for (itr = m_sessions.begin(); itr != m_sessions.end(); ++itr) + for (SessionMap::const_iterator itr = m_sessions.begin(); itr != m_sessions.end(); ++itr) { - if (itr->second && - itr->second->GetPlayer() && - itr->second->GetPlayer()->IsInWorld() && - itr->second != self && - !AccountMgr::IsPlayerAccount(itr->second->GetSecurity()) && - (team == 0 || itr->second->GetPlayer()->GetTeam() == team)) - { - itr->second->SendPacket(packet); - } + // check if session and can receive global GM Messages and its not self + WorldSession* session = itr->second; + if (!session || session == self || !session->HasPermission(RBAC_PERM_RECEIVE_GLOBAL_GM_TEXTMESSAGE)) + continue; + + // Player should be in world + Player* player = session->GetPlayer(); + if (!player || !player->IsInWorld()) + continue; + + // Send only to same team, if team is given + if (!team || player->GetTeam() == team) + session->SendPacket(packet); } } @@ -2213,15 +2220,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 932bb562f11..168a5ec60b8 100644 --- a/src/server/scripts/Commands/cs_gm.cpp +++ b/src/server/scripts/Commands/cs_gm.cpp @@ -59,30 +59,32 @@ public: // Enables or disables hiding of the staff badge static bool HandleGMChatCommand(ChatHandler* handler, char const* args) { - if (!*args) + if (WorldSession* session = handler->GetSession()) { - WorldSession* session = handler->GetSession(); - if (!AccountMgr::IsPlayerAccount(session->GetSecurity()) && session->GetPlayer()->isGMChat()) - session->SendNotification(LANG_GM_CHAT_ON); - else - session->SendNotification(LANG_GM_CHAT_OFF); - return true; - } + if (!*args) + { + if (session->HasPermission(RBAC_PERM_CHAT_USE_STAFF_BADGE) && session->GetPlayer()->isGMChat()) + session->SendNotification(LANG_GM_CHAT_ON); + else + session->SendNotification(LANG_GM_CHAT_OFF); + return true; + } - std::string param = (char*)args; + std::string param = (char*)args; - if (param == "on") - { - handler->GetSession()->GetPlayer()->SetGMChat(true); - handler->GetSession()->SendNotification(LANG_GM_CHAT_ON); - return true; - } + if (param == "on") + { + session->GetPlayer()->SetGMChat(true); + session->SendNotification(LANG_GM_CHAT_ON); + return true; + } - if (param == "off") - { - handler->GetSession()->GetPlayer()->SetGMChat(false); - handler->GetSession()->SendNotification(LANG_GM_CHAT_OFF); - return true; + if (param == "off") + { + session->GetPlayer()->SetGMChat(false); + session->SendNotification(LANG_GM_CHAT_OFF); + return true; + } } handler->SendSysMessage(LANG_USE_BOL); @@ -126,7 +128,9 @@ public: for (HashMapHolder<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 cacefea7b85..4cdc1e0d9ce 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -678,7 +678,7 @@ public: if (target) { - target->ResurrectPlayer(!AccountMgr::IsPlayerAccount(target->GetSession()->GetSecurity()) ? 1.0f : 0.5f); + target->ResurrectPlayer(target->GetSession()->HasPermission(RBAC_PERM_RESURRECT_WITH_FULL_HPS) ? 1.0f : 0.5f); target->SpawnCorpseBones(); target->SaveToDB(); } @@ -881,7 +881,7 @@ public: Player* player = handler->GetSession()->GetPlayer(); // save GM account without delay and output message - if (!AccountMgr::IsPlayerAccount(handler->GetSession()->GetSecurity())) + if (handler->GetSession()->HasPermission(RBAC_PERM_COMMANDS_SAVE_WITHOUT_DELAY)) { if (Player* target = handler->getSelectedPlayer()) target->SaveToDB(); @@ -938,8 +938,8 @@ public: static bool HandleUnstuckCommand(ChatHandler* handler, char const* args) { - //No args required for players - if (handler->GetSession() && AccountMgr::IsPlayerAccount(handler->GetSession()->GetSecurity())) + // No args required for players + if (handler->GetSession() && !handler->GetSession()->HasPermission(RBAC_PERM_COMMANDS_USE_UNSTUCK_WITH_ARGS)) { // 7355: "Stuck" if (Player* player = handler->GetSession()->GetPlayer()) 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/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp index 53fe63195cc..5a5efc36b3c 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp @@ -341,7 +341,7 @@ class boss_algalon_the_observer : public CreatureScript me->GetMotionMaster()->MovePoint(POINT_ALGALON_LAND, AlgalonLandPos); me->SetHomePosition(AlgalonLandPos); Movement::MoveSplineInit init(me); - init.MoveTo(AlgalonLandPos.GetPositionX(), AlgalonLandPos.GetPositionY(), AlgalonLandPos.GetPositionZ()); + init.MoveTo(AlgalonLandPos.GetPositionX(), AlgalonLandPos.GetPositionY(), AlgalonLandPos.GetPositionZ(), false); init.SetOrientationFixed(true); init.Launch(); events.Reset(); 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/shared/Logging/Log.cpp b/src/server/shared/Logging/Log.cpp index 920ce4ce570..f0275f8c6b2 100644 --- a/src/server/shared/Logging/Log.cpp +++ b/src/server/shared/Logging/Log.cpp @@ -286,7 +286,10 @@ void Log::write(LogMessage* msg) if (worker) worker->enqueue(new LogOperation(logger, msg)); else + { logger->write(*msg); + delete msg; + } } std::string Log::GetTimestampStr() 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 { |