aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/updates/auth/2013_02_25_00_auth_misc.sql18
-rw-r--r--sql/updates/auth/2013_02_25_01_auth_misc.sql18
-rw-r--r--sql/updates/auth/2013_02_25_02_auth_misc.sql18
-rw-r--r--sql/updates/auth/2013_02_25_03_auth_misc.sql33
-rw-r--r--sql/updates/auth/2013_02_25_04_auth_misc.sql27
-rw-r--r--sql/updates/auth/2013_02_25_05_auth_misc.sql18
-rw-r--r--sql/updates/auth/2013_02_25_06_auth_misc.sql18
-rw-r--r--sql/updates/auth/2013_02_25_07_auth_misc.sql21
-rw-r--r--sql/updates/auth/2013_02_25_08_auth_misc.sql19
-rw-r--r--sql/updates/auth/2013_02_25_09_auth_misc.sql27
-rw-r--r--sql/updates/auth/2013_02_25_10_auth_misc.sql43
-rw-r--r--sql/updates/auth/2013_02_25_11_auth_misc.sql34
-rw-r--r--sql/updates/auth/2013_02_25_12_auth_misc.sql34
-rw-r--r--sql/updates/auth/2013_02_25_13_auth_misc.sql36
-rw-r--r--sql/updates/auth/2013_02_25_14_auth_misc.sql39
-rw-r--r--sql/updates/world/2013_02_23_00_world_gameobject.sql1
-rw-r--r--sql/updates/world/2013_02_23_01_world_areatrigger_teleport.sql3
-rw-r--r--sql/updates/world/2013_02_24_00_world_creature_summon_groups.sql16
-rw-r--r--sql/updates/world/2013_02_24_01_world_areatrigger_scripts.sql3
-rw-r--r--sql/updates/world/2013_02_24_02_world_smart_scripts.sql7
-rw-r--r--sql/updates/world/2013_02_24_03_world_waypoint_data.sql11
-rw-r--r--sql/updates/world/2013_02_24_04_world_creature_template.sql2
-rw-r--r--src/server/game/Accounts/AccountMgr.cpp29
-rw-r--r--src/server/game/Accounts/AccountMgr.h2
-rw-r--r--src/server/game/Accounts/RBAC.h57
-rw-r--r--src/server/game/AuctionHouse/AuctionHouseMgr.cpp47
-rw-r--r--src/server/game/Calendar/CalendarMgr.cpp87
-rw-r--r--src/server/game/Calendar/CalendarMgr.h16
-rw-r--r--src/server/game/Chat/Channels/Channel.cpp52
-rw-r--r--src/server/game/Chat/Chat.cpp5
-rw-r--r--src/server/game/DungeonFinding/LFGMgr.cpp1
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp6
-rw-r--r--src/server/game/Entities/Creature/TemporarySummon.h16
-rw-r--r--src/server/game/Entities/Object/Object.cpp37
-rw-r--r--src/server/game/Entities/Object/Object.h1
-rw-r--r--src/server/game/Entities/Player/Player.cpp15
-rw-r--r--src/server/game/Entities/Player/SocialMgr.cpp71
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp11
-rw-r--r--src/server/game/Entities/Unit/Unit.h1
-rwxr-xr-xsrc/server/game/Entities/Vehicle/Vehicle.cpp66
-rw-r--r--src/server/game/Entities/Vehicle/Vehicle.h48
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp86
-rw-r--r--src/server/game/Globals/ObjectMgr.h42
-rw-r--r--src/server/game/Guilds/Guild.cpp7
-rw-r--r--src/server/game/Handlers/AuctionHouseHandler.cpp4
-rw-r--r--src/server/game/Handlers/CalendarHandler.cpp8
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp81
-rw-r--r--src/server/game/Handlers/ChatHandler.cpp24
-rw-r--r--src/server/game/Handlers/MailHandler.cpp138
-rw-r--r--src/server/game/Handlers/MiscHandler.cpp78
-rw-r--r--src/server/game/Handlers/TradeHandler.cpp11
-rw-r--r--src/server/game/Maps/Map.h1
-rw-r--r--src/server/game/Miscellaneous/SharedDefines.h2
-rw-r--r--src/server/game/Server/WorldSession.cpp40
-rw-r--r--src/server/game/Server/WorldSession.h4
-rw-r--r--src/server/game/Server/WorldSocket.cpp2
-rw-r--r--src/server/game/Spells/Spell.cpp7
-rw-r--r--src/server/game/Spells/SpellEffects.cpp6
-rw-r--r--src/server/game/World/World.cpp43
-rw-r--r--src/server/scripts/Commands/cs_gm.cpp46
-rw-r--r--src/server/scripts/Commands/cs_misc.cpp8
-rw-r--r--src/server/scripts/Commands/cs_rbac.cpp4
-rw-r--r--src/server/scripts/Commands/cs_ticket.cpp12
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp2
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp2
-rw-r--r--src/server/scripts/World/areatrigger_scripts.cpp64
-rw-r--r--src/server/shared/Logging/Log.cpp3
-rw-r--r--src/server/worldserver/TCSoap/TCSoap.cpp3
-rw-r--r--src/server/worldserver/TCSoap/TCSoap.h10
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
{