diff options
54 files changed, 3313 insertions, 512 deletions
diff --git a/sql/base/auth_database.sql b/sql/base/auth_database.sql index fe1e68070d5..14c5d2e8a92 100644 --- a/sql/base/auth_database.sql +++ b/sql/base/auth_database.sql @@ -1,8 +1,8 @@ --- MySQL dump 10.13 Distrib 5.5.21, for Win64 (x86) +-- MySQL dump 10.13 Distrib 5.6.9-rc, for Win64 (x86_64) -- -- Host: localhost Database: auth_4x -- ------------------------------------------------------ --- Server version 5.5.21 +-- Server version 5.6.9-rc /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -38,6 +38,8 @@ CREATE TABLE `account` ( `online` tinyint(3) unsigned NOT NULL DEFAULT '0', `expansion` tinyint(3) unsigned NOT NULL DEFAULT '3', `mutetime` bigint(20) NOT NULL DEFAULT '0', + `mutereason` varchar(255) NOT NULL DEFAULT '', + `muteby` varchar(50) NOT NULL DEFAULT '', `locale` tinyint(3) unsigned NOT NULL DEFAULT '0', `os` varchar(3) NOT NULL DEFAULT '', `recruiter` int(10) unsigned NOT NULL DEFAULT '0', @@ -158,6 +160,241 @@ LOCK TABLES `logs` WRITE; UNLOCK TABLES; -- +-- Table structure for table `rbac_account_groups` +-- + +DROP TABLE IF EXISTS `rbac_account_groups`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `rbac_account_groups` ( + `accountId` int(10) unsigned NOT NULL COMMENT 'Account id', + `groupId` int(10) unsigned NOT NULL COMMENT 'Group id', + `realmId` int(11) NOT NULL DEFAULT '-1' COMMENT 'Realm Id, -1 means all', + PRIMARY KEY (`accountId`,`groupId`,`realmId`), + KEY `fk__rbac_account_groups__rbac_groups` (`groupId`), + CONSTRAINT `fk__rbac_account_groups__account` FOREIGN KEY (`accountId`) REFERENCES `account` (`id`) ON DELETE CASCADE, + CONSTRAINT `fk__rbac_account_groups__rbac_groups` FOREIGN KEY (`groupId`) REFERENCES `rbac_groups` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Account-Group relation'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `rbac_account_groups` +-- + +LOCK TABLES `rbac_account_groups` WRITE; +/*!40000 ALTER TABLE `rbac_account_groups` DISABLE KEYS */; +/*!40000 ALTER TABLE `rbac_account_groups` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `rbac_account_permissions` +-- + +DROP TABLE IF EXISTS `rbac_account_permissions`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `rbac_account_permissions` ( + `accountId` int(10) unsigned NOT NULL COMMENT 'Account id', + `permissionId` int(10) unsigned NOT NULL COMMENT 'Permission id', + `granted` tinyint(1) NOT NULL DEFAULT '1' COMMENT 'Granted = 1, Denied = 0', + `realmId` int(11) NOT NULL DEFAULT '-1' COMMENT 'Realm Id, -1 means all', + PRIMARY KEY (`accountId`,`permissionId`,`realmId`), + KEY `fk__rbac_account_roles__rbac_permissions` (`permissionId`), + CONSTRAINT `fk__rbac_account_permissions__account` FOREIGN KEY (`accountId`) REFERENCES `account` (`id`) ON DELETE CASCADE, + CONSTRAINT `fk__rbac_account_roles__rbac_permissions` FOREIGN KEY (`permissionId`) REFERENCES `rbac_permissions` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Account-Permission relation'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `rbac_account_permissions` +-- + +LOCK TABLES `rbac_account_permissions` WRITE; +/*!40000 ALTER TABLE `rbac_account_permissions` DISABLE KEYS */; +/*!40000 ALTER TABLE `rbac_account_permissions` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `rbac_account_roles` +-- + +DROP TABLE IF EXISTS `rbac_account_roles`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `rbac_account_roles` ( + `accountId` int(10) unsigned NOT NULL COMMENT 'Account id', + `roleId` int(10) unsigned NOT NULL COMMENT 'Role id', + `granted` tinyint(1) NOT NULL DEFAULT '1' COMMENT 'Granted = 1, Denied = 0', + `realmId` int(11) NOT NULL DEFAULT '-1' COMMENT 'Realm Id, -1 means all', + PRIMARY KEY (`accountId`,`roleId`,`realmId`), + KEY `fk__rbac_account_roles__rbac_roles` (`roleId`), + CONSTRAINT `fk__rbac_account_roles__account` FOREIGN KEY (`accountId`) REFERENCES `account` (`id`) ON DELETE CASCADE, + CONSTRAINT `fk__rbac_account_roles__rbac_roles` FOREIGN KEY (`roleId`) REFERENCES `rbac_roles` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Account-Role relation'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `rbac_account_roles` +-- + +LOCK TABLES `rbac_account_roles` WRITE; +/*!40000 ALTER TABLE `rbac_account_roles` DISABLE KEYS */; +/*!40000 ALTER TABLE `rbac_account_roles` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `rbac_group_roles` +-- + +DROP TABLE IF EXISTS `rbac_group_roles`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `rbac_group_roles` ( + `groupId` int(10) unsigned NOT NULL COMMENT 'group id', + `roleId` int(10) unsigned NOT NULL COMMENT 'Role id', + PRIMARY KEY (`groupId`,`roleId`), + KEY `fk__rbac_group_roles__rbac_roles` (`roleId`), + CONSTRAINT `fk__rbac_group_roles__rbac_roles` FOREIGN KEY (`roleId`) REFERENCES `rbac_roles` (`id`) ON DELETE CASCADE, + CONSTRAINT `fk__rbac_group_roles__rbac_groups` FOREIGN KEY (`groupId`) REFERENCES `rbac_groups` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Group Role relation'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `rbac_group_roles` +-- + +LOCK TABLES `rbac_group_roles` WRITE; +/*!40000 ALTER TABLE `rbac_group_roles` DISABLE KEYS */; +INSERT INTO `rbac_group_roles` VALUES (1,1),(2,2),(3,3),(4,4),(2,5),(1,6),(1,7); +/*!40000 ALTER TABLE `rbac_group_roles` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `rbac_groups` +-- + +DROP TABLE IF EXISTS `rbac_groups`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `rbac_groups` ( + `id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Group id', + `name` varchar(50) NOT NULL COMMENT 'Group name', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Group List'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `rbac_groups` +-- + +LOCK TABLES `rbac_groups` WRITE; +/*!40000 ALTER TABLE `rbac_groups` DISABLE KEYS */; +INSERT INTO `rbac_groups` VALUES (1,'Player'),(2,'Moderator'),(3,'GameMaster'),(4,'Administrator'); +/*!40000 ALTER TABLE `rbac_groups` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `rbac_permissions` +-- + +DROP TABLE IF EXISTS `rbac_permissions`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `rbac_permissions` ( + `id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Permission id', + `name` varchar(100) NOT NULL COMMENT 'Permission name', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Permission List'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `rbac_permissions` +-- + +LOCK TABLES `rbac_permissions` WRITE; +/*!40000 ALTER TABLE `rbac_permissions` DISABLE KEYS */; +INSERT INTO `rbac_permissions` VALUES (1,'Instant logout'),(2,'Skip Queue'),(3,'Join Normal Battleground'),(4,'Join Random Battleground'),(5,'Join Arenas'),(6,'Join Dungeon Finder'),(7,'Player Commands (Temporal till commands moved to rbac)'),(8,'Moderator Commands (Temporal till commands moved to rbac)'),(9,'GameMaster Commands (Temporal till commands moved to rbac)'),(10,'Administrator Commands (Temporal till commands moved to rbac)'); +/*!40000 ALTER TABLE `rbac_permissions` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `rbac_role_permissions` +-- + +DROP TABLE IF EXISTS `rbac_role_permissions`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `rbac_role_permissions` ( + `roleId` int(10) unsigned NOT NULL COMMENT 'Role id', + `permissionId` int(10) unsigned NOT NULL COMMENT 'Permission id', + PRIMARY KEY (`roleId`,`permissionId`), + KEY `fk__role_permissions__rbac_permissions` (`permissionId`), + CONSTRAINT `fk__role_permissions__rbac_roles` FOREIGN KEY (`roleId`) REFERENCES `rbac_roles` (`id`) ON DELETE CASCADE, + CONSTRAINT `fk__role_permissions__rbac_permissions` FOREIGN KEY (`permissionId`) REFERENCES `rbac_permissions` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Role Permission relation'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `rbac_role_permissions` +-- + +LOCK TABLES `rbac_role_permissions` WRITE; +/*!40000 ALTER TABLE `rbac_role_permissions` DISABLE KEYS */; +INSERT INTO `rbac_role_permissions` VALUES (5,1),(5,2),(6,3),(6,4),(6,5),(7,6),(1,7),(2,8),(3,9),(4,10); +/*!40000 ALTER TABLE `rbac_role_permissions` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `rbac_roles` +-- + +DROP TABLE IF EXISTS `rbac_roles`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `rbac_roles` ( + `id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Role id', + `name` varchar(50) NOT NULL COMMENT 'Role name', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Roles List'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `rbac_roles` +-- + +LOCK TABLES `rbac_roles` WRITE; +/*!40000 ALTER TABLE `rbac_roles` DISABLE KEYS */; +INSERT INTO `rbac_roles` VALUES (1,'Player Commands'),(2,'Moderator Commands'),(3,'GameMaster Commands'),(4,'Administrator Commands'),(5,'Quick Login/Logout'),(6,'Use Battleground/Arenas'),(7,'Use Dungeon Finder'); +/*!40000 ALTER TABLE `rbac_roles` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `rbac_security_level_groups` +-- + +DROP TABLE IF EXISTS `rbac_security_level_groups`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `rbac_security_level_groups` ( + `secId` int(10) unsigned NOT NULL COMMENT 'Security Level id', + `groupId` int(10) unsigned NOT NULL COMMENT 'group id', + PRIMARY KEY (`secId`,`groupId`), + KEY `fk__rbac_security_level_groups__rbac_groups` (`groupId`), + CONSTRAINT `fk__rbac_security_level_groups__rbac_groups` FOREIGN KEY (`groupId`) REFERENCES `rbac_groups` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Default groups to assign when an account is set gm level'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `rbac_security_level_groups` +-- + +LOCK TABLES `rbac_security_level_groups` WRITE; +/*!40000 ALTER TABLE `rbac_security_level_groups` DISABLE KEYS */; +INSERT INTO `rbac_security_level_groups` VALUES (0,1),(1,1),(2,1),(3,1),(1,2),(2,2),(3,2),(2,3),(3,3),(3,4); +/*!40000 ALTER TABLE `rbac_security_level_groups` ENABLE KEYS */; +UNLOCK TABLES; + +-- -- Table structure for table `realmcharacters` -- @@ -252,4 +489,8 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; +<<<<<<< HEAD -- Dump completed on 2012-08-08 19:01:34 +======= +-- Dump completed on 2013-02-04 16:07:23 +>>>>>>> 8f6e9dc85ccda388bc5ced1921cd4e30cb5fe2e0 diff --git a/sql/base/characters_database.sql b/sql/base/characters_database.sql index 165ae3aff78..0f828b08c50 100644 --- a/sql/base/characters_database.sql +++ b/sql/base/characters_database.sql @@ -1,8 +1,8 @@ --- MySQL dump 10.13 Distrib 5.5.21, for Win64 (x86) +-- MySQL dump 10.13 Distrib 5.6.9-rc, for Win64 (x86_64) -- -- Host: localhost Database: characters_4x -- ------------------------------------------------------ --- Server version 5.5.21 +-- Server version 5.6.9-rc /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -244,7 +244,7 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `calendar_events`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; -CREATE TABLE IF NOT EXISTS `calendar_events` ( +CREATE TABLE `calendar_events` ( `id` bigint(20) unsigned NOT NULL DEFAULT '0', `creator` int(10) unsigned NOT NULL DEFAULT '0', `title` varchar(255) NOT NULL DEFAULT '', @@ -259,13 +259,22 @@ CREATE TABLE IF NOT EXISTS `calendar_events` ( /*!40101 SET character_set_client = @saved_cs_client */; -- +-- Dumping data for table `calendar_events` +-- + +LOCK TABLES `calendar_events` WRITE; +/*!40000 ALTER TABLE `calendar_events` DISABLE KEYS */; +/*!40000 ALTER TABLE `calendar_events` ENABLE KEYS */; +UNLOCK TABLES; + +-- -- Table structure for table `calendar_invites` -- DROP TABLE IF EXISTS `calendar_invites`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; -CREATE TABLE IF NOT EXISTS `calendar_invites` ( +CREATE TABLE `calendar_invites` ( `id` bigint(20) unsigned NOT NULL DEFAULT '0', `event` bigint(20) unsigned NOT NULL DEFAULT '0', `invitee` int(10) unsigned NOT NULL DEFAULT '0', @@ -279,6 +288,15 @@ CREATE TABLE IF NOT EXISTS `calendar_invites` ( /*!40101 SET character_set_client = @saved_cs_client */; -- +-- Dumping data for table `calendar_invites` +-- + +LOCK TABLES `calendar_invites` WRITE; +/*!40000 ALTER TABLE `calendar_invites` DISABLE KEYS */; +/*!40000 ALTER TABLE `calendar_invites` ENABLE KEYS */; +UNLOCK TABLES; + +-- -- Table structure for table `channels` -- @@ -950,6 +968,30 @@ LOCK TABLES `character_queststatus_daily` WRITE; UNLOCK TABLES; -- +-- Table structure for table `character_queststatus_monthly` +-- + +DROP TABLE IF EXISTS `character_queststatus_monthly`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `character_queststatus_monthly` ( + `guid` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Global Unique Identifier', + `quest` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Quest Identifier', + PRIMARY KEY (`guid`,`quest`), + KEY `idx_guid` (`guid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Player System'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `character_queststatus_monthly` +-- + +LOCK TABLES `character_queststatus_monthly` WRITE; +/*!40000 ALTER TABLE `character_queststatus_monthly` DISABLE KEYS */; +/*!40000 ALTER TABLE `character_queststatus_monthly` ENABLE KEYS */; +UNLOCK TABLES; + +-- -- Table structure for table `character_queststatus_rewarded` -- @@ -998,30 +1040,6 @@ LOCK TABLES `character_queststatus_seasonal` WRITE; UNLOCK TABLES; -- --- Table structure for table `character_queststatus_monthly` --- - -DROP TABLE IF EXISTS `character_queststatus_monthly`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `character_queststatus_monthly` ( - `guid` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Global Unique Identifier', - `quest` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Quest Identifier', - PRIMARY KEY (`guid`,`quest`), - KEY `idx_guid` (`guid`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Player System'; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `character_queststatus_monthly` --- - -LOCK TABLES `character_queststatus_monthly` WRITE; -/*!40000 ALTER TABLE `character_queststatus_monthly` DISABLE KEYS */; -/*!40000 ALTER TABLE `character_queststatus_monthly` ENABLE KEYS */; -UNLOCK TABLES; - --- -- Table structure for table `character_queststatus_weekly` -- @@ -2009,7 +2027,7 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `guild_member_withdraw`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; -CREATE TABLE IF NOT EXISTS `guild_member_withdraw` ( +CREATE TABLE `guild_member_withdraw` ( `guid` int(10) unsigned NOT NULL, `tab0` int(10) unsigned NOT NULL DEFAULT '0', `tab1` int(10) unsigned NOT NULL DEFAULT '0', @@ -2205,6 +2223,15 @@ CREATE TABLE `item_loot_items` ( /*!40101 SET character_set_client = @saved_cs_client */; -- +-- Dumping data for table `item_loot_items` +-- + +LOCK TABLES `item_loot_items` WRITE; +/*!40000 ALTER TABLE `item_loot_items` DISABLE KEYS */; +/*!40000 ALTER TABLE `item_loot_items` ENABLE KEYS */; +UNLOCK TABLES; + +-- -- Table structure for table `item_loot_money` -- @@ -2218,6 +2245,15 @@ CREATE TABLE `item_loot_money` ( /*!40101 SET character_set_client = @saved_cs_client */; -- +-- Dumping data for table `item_loot_money` +-- + +LOCK TABLES `item_loot_money` WRITE; +/*!40000 ALTER TABLE `item_loot_money` DISABLE KEYS */; +/*!40000 ALTER TABLE `item_loot_money` ENABLE KEYS */; +UNLOCK TABLES; + +-- -- Table structure for table `item_refund_instance` -- @@ -2621,4 +2657,4 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2012-09-10 11:54:51 +-- Dump completed on 2013-02-04 16:22:06 diff --git a/sql/updates/auth/2013_02_04_00_auth_misc.sql b/sql/updates/auth/2013_02_04_00_auth_misc.sql new file mode 100644 index 00000000000..815df637be0 --- /dev/null +++ b/sql/updates/auth/2013_02_04_00_auth_misc.sql @@ -0,0 +1,176 @@ +-- Delete bad data from the DB before adding foreign keys +DELETE FROM `account_access` WHERE `id` NOT IN (SELECT `id` FROM `account`); + +-- Need them first in case of re-execute due to foreign keys +DROP TABLE IF EXISTS `rbac_account_permissions`; +DROP TABLE IF EXISTS `rbac_account_roles`; +DROP TABLE IF EXISTS `rbac_account_groups`; +DROP TABLE IF EXISTS `rbac_role_permissions`; +DROP TABLE IF EXISTS `rbac_group_roles`; +DROP TABLE IF EXISTS `rbac_security_level_groups`; +DROP TABLE IF EXISTS `rbac_permissions`; +DROP TABLE IF EXISTS `rbac_roles`; +DROP TABLE IF EXISTS `rbac_groups`; + +CREATE TABLE IF NOT EXISTS `rbac_groups` ( + `id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Group id', + `name` varchar(50) NOT NULL COMMENT 'Group name', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Group List'; + +CREATE TABLE IF NOT EXISTS `rbac_roles` ( + `id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Role id', + `name` varchar(50) NOT NULL COMMENT 'Role name', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Roles List'; + +CREATE TABLE IF NOT EXISTS `rbac_permissions` ( + `id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Permission id', + `name` varchar(100) NOT NULL COMMENT 'Permission name', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Permission List'; + +CREATE TABLE IF NOT EXISTS `rbac_group_roles` ( + `groupId` int(10) unsigned NOT NULL COMMENT 'group id', + `roleId` int(10) unsigned NOT NULL COMMENT 'Role id', + PRIMARY KEY (`groupId`, `roleId`), + CONSTRAINT `fk__rbac_group_roles__rbac_roles` + FOREIGN KEY (`roleId`) REFERENCES `rbac_roles`(`id`) + ON DELETE CASCADE ON UPDATE RESTRICT, + CONSTRAINT `fk__rbac_group_roles__rbac_groups` + FOREIGN KEY (`groupId`) REFERENCES `rbac_groups`(`id`) + ON DELETE CASCADE ON UPDATE RESTRICT +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Group Role relation'; + +CREATE TABLE IF NOT EXISTS `rbac_role_permissions` ( + `roleId` int(10) unsigned NOT NULL COMMENT 'Role id', + `permissionId` int(10) unsigned NOT NULL COMMENT 'Permission id', + PRIMARY KEY (`roleId`, `permissionId`), + CONSTRAINT `fk__role_permissions__rbac_roles` + FOREIGN KEY (`roleId`) REFERENCES `rbac_roles`(`id`) + ON DELETE CASCADE ON UPDATE RESTRICT, + CONSTRAINT `fk__role_permissions__rbac_permissions` + FOREIGN KEY (`permissionId`) REFERENCES `rbac_permissions`(`id`) + ON DELETE CASCADE ON UPDATE RESTRICT +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Role Permission relation'; + +CREATE TABLE IF NOT EXISTS `rbac_security_level_groups` ( + `secId` int(10) unsigned NOT NULL COMMENT 'Security Level id', + `groupId` int(10) unsigned NOT NULL COMMENT 'group id', + PRIMARY KEY (`secId`, `groupId`), + CONSTRAINT `fk__rbac_security_level_groups__rbac_groups` + FOREIGN KEY (`groupId`) REFERENCES `rbac_groups`(`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Default groups to assign when an account is set gm level'; + +CREATE TABLE IF NOT EXISTS `rbac_account_groups` ( + `accountId` int(10) unsigned NOT NULL COMMENT 'Account id', + `groupId` int(10) unsigned NOT NULL COMMENT 'Group id', + `realmId` int(11) NOT NULL DEFAULT '-1' COMMENT 'Realm Id, -1 means all', + PRIMARY KEY (`accountId`, `groupId`, `realmId`), + CONSTRAINT `fk__rbac_account_groups__account` + FOREIGN KEY (`accountId`) REFERENCES `account`(`id`) + ON DELETE CASCADE ON UPDATE RESTRICT, + CONSTRAINT `fk__rbac_account_groups__rbac_groups` + FOREIGN KEY (`groupId`) REFERENCES `rbac_groups`(`id`) + ON DELETE CASCADE ON UPDATE RESTRICT +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Account-Group relation'; + +CREATE TABLE IF NOT EXISTS `rbac_account_roles` ( + `accountId` int(10) unsigned NOT NULL COMMENT 'Account id', + `roleId` int(10) unsigned NOT NULL COMMENT 'Role id', + `granted` tinyint(1) NOT NULL default 1 COMMENT 'Granted = 1, Denied = 0', + `realmId` int(11) NOT NULL DEFAULT '-1' COMMENT 'Realm Id, -1 means all', + PRIMARY KEY (`accountId`, `roleId`, `realmId`), + CONSTRAINT `fk__rbac_account_roles__account` + FOREIGN KEY (`accountId`) REFERENCES `account`(`id`) + ON DELETE CASCADE ON UPDATE RESTRICT, + CONSTRAINT `fk__rbac_account_roles__rbac_roles` + FOREIGN KEY (`roleId`) REFERENCES `rbac_roles`(`id`) + ON DELETE CASCADE ON UPDATE RESTRICT +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Account-Role relation'; + +CREATE TABLE IF NOT EXISTS `rbac_account_permissions` ( + `accountId` int(10) unsigned NOT NULL COMMENT 'Account id', + `permissionId` int(10) unsigned NOT NULL COMMENT 'Permission id', + `granted` tinyint(1) NOT NULL default 1 COMMENT 'Granted = 1, Denied = 0', + `realmId` int(11) NOT NULL DEFAULT '-1' COMMENT 'Realm Id, -1 means all', + PRIMARY KEY (`accountId`, `permissionId`, `realmId`), + CONSTRAINT `fk__rbac_account_permissions__account` + FOREIGN KEY (`accountId`) REFERENCES `account`(`id`) + ON DELETE CASCADE ON UPDATE RESTRICT, + CONSTRAINT `fk__rbac_account_roles__rbac_permissions` + FOREIGN KEY (`permissionId`) REFERENCES `rbac_permissions`(`id`) + ON DELETE CASCADE ON UPDATE RESTRICT +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Account-Permission relation'; + +DELETE FROM `rbac_permissions` WHERE `id` BETWEEN 1 AND 10; +INSERT INTO `rbac_permissions` (`id`, `name`) VALUES +(1, 'Instant logout'), +(2, 'Skip Queue'), +(3, 'Join Normal Battleground'), +(4, 'Join Random Battleground'), +(5, 'Join Arenas'), +(6, 'Join Dungeon Finder'), +(7, 'Player Commands (Temporal till commands moved to rbac)'), +(8, 'Moderator Commands (Temporal till commands moved to rbac)'), +(9, 'GameMaster Commands (Temporal till commands moved to rbac)'), +(10, 'Administrator Commands (Temporal till commands moved to rbac)'); + +DELETE FROM `rbac_roles` WHERE `id` BETWEEN 1 AND 7; +INSERT INTO `rbac_roles` (`id`, `name`) VALUES +(1, 'Player Commands'), +(2, 'Moderator Commands'), +(3, 'GameMaster Commands'), +(4, 'Administrator Commands'), +(5, 'Quick Login/Logout'), +(6, 'Use Battleground/Arenas'), +(7, 'Use Dungeon Finder'); + +DELETE FROM `rbac_groups` WHERE `id` BETWEEN 1 AND 4; +INSERT INTO `rbac_groups` (`id`, `name`) VALUES +(1, 'Player'), +(2, 'Moderator'), +(3, 'GameMaster'), +(4, 'Administrator'); + +DELETE FROM `rbac_role_permissions` WHERE `roleId` BETWEEN 1 AND 7; +INSERT INTO `rbac_role_permissions` (`roleId`, `permissionId`) VALUES +(5, 1), +(5, 2), +(6, 3), +(6, 4), +(6, 5), +(7, 6), +(1, 7), +(2, 8), +(3, 9), +(4, 10); + +DELETE FROM `rbac_group_roles` WHERE `groupId` BETWEEN 1 AND 4; +INSERT INTO `rbac_group_roles` (`groupId`, `roleId`) VALUES +(1, 1), +(1, 6), +(1, 7), +(2, 2), +(2, 5), +(3, 3), +(4, 4); + +TRUNCATE `rbac_account_groups`; +INSERT INTO `rbac_account_groups` (`accountId`, `groupId`, `realmId`) SELECT `id`, 1, -1 FROM `account`; -- Add Player group to all accounts +INSERT INTO `rbac_account_groups` (`accountId`, `groupId`, `realmId`) SELECT `id`, 2, `RealmID` FROM `account_access` WHERE `gmlevel` > 0; -- Add Moderator group to all Moderator or higher GM level +INSERT INTO `rbac_account_groups` (`accountId`, `groupId`, `realmId`) SELECT `id`, 3, `RealmID` FROM `account_access` WHERE `gmlevel` > 1; -- Add GameMaster group to all GameMasters or higher GM level +INSERT INTO `rbac_account_groups` (`accountId`, `groupId`, `realmId`) SELECT `id`, 4, `RealmID` FROM `account_access` WHERE `gmlevel` > 2; -- Add Administrator group to all Administrators + +TRUNCATE `rbac_security_level_groups`; +INSERT INTO `rbac_security_level_groups` (`secId`, `groupId`) VALUES +(0, 1), +(1, 1), +(1, 2), +(2, 1), +(2, 2), +(2, 3), +(3, 1), +(3, 2), +(3, 3), +(3, 4); diff --git a/sql/updates/auth/2013_02_04_01_auth_account.sql b/sql/updates/auth/2013_02_04_01_auth_account.sql new file mode 100644 index 00000000000..9af73d41ee3 --- /dev/null +++ b/sql/updates/auth/2013_02_04_01_auth_account.sql @@ -0,0 +1,3 @@ +ALTER TABLE `account` + ADD COLUMN `mutereason` VARCHAR(255) NOT NULL DEFAULT '' AFTER `mutetime`, + ADD COLUMN `muteby` VARCHAR(50) NOT NULL DEFAULT '' AFTER `mutereason`; diff --git a/sql/updates/world/2013_02_03_world_lfg_entrances.sql b/sql/updates/world/2013_02_03_00_world_lfg_entrances.sql index e308c001d29..e308c001d29 100644 --- a/sql/updates/world/2013_02_03_world_lfg_entrances.sql +++ b/sql/updates/world/2013_02_03_00_world_lfg_entrances.sql diff --git a/sql/updates/world/2013_02_04_00_world_misc.sql b/sql/updates/world/2013_02_04_00_world_misc.sql new file mode 100644 index 00000000000..ff8021653ab --- /dev/null +++ b/sql/updates/world/2013_02_04_00_world_misc.sql @@ -0,0 +1,60 @@ +-- Something Stinks (A:24655 H:24536) +SET @GUID := 85637; -- set by TDB (need 10)(85637,85638,85639,85640,85641,85642,85643,85644,85645,85646,43498,43502,45075,45099) +SET @EVENT := 8; -- Love is in the Air + +SET @BUNNY := 38288; -- Love Guard Perfume Bunny +SET @GUARD_SW := 68; -- Stormwind City Guard +SET @PATROOLER_SW := 1976; -- Stormwind City Patroller +SET @GUARD_ORG := 3296; -- Orgrimmar Grunt +SET @ELITE_ORG := 14304; -- Kor'kron Elite + +SET @SPELL_PULSE := 71520; -- Heavily Perfumed Pulse +SET @SPELL_BUFF := 71507; -- Heavily Perfumed +SET @SPELL_ANALYSIS := 70192; -- Fragrant Air Analysis + + +DELETE FROM `creature` WHERE `id`=@BUNNY; +INSERT INTO `creature` (`guid`,`id`,`map`,`spawnMask`,`phaseMask`,`modelid`,`equipment_id`,`position_x`,`position_y`,`position_z`,`orientation`,`spawntimesecs`,`spawndist`,`currentwaypoint`,`curhealth`,`curmana`,`MovementType`,`npcflag`,`unit_flags`,`dynamicflags`) VALUES +(@GUID+0,@BUNNY,0,1,1,0,0,-8825.604,629.3108,94.1137,0,300,0,0,1,0,0,0,0,0), -- sw trade district +(@GUID+1,@BUNNY,0,1,1,0,0,-8988.889,849.4149,105.9425,0,300,0,0,1,0,0,0,0,0), -- sw mage quarter +(@GUID+2,@BUNNY,0,1,1,0,0,-8737.654,1051.887,90.8816,0,300,0,0,1,0,0,0,0,0), -- sw the park +(@GUID+3,@BUNNY,0,1,1,0,0,-8625.038,780.0799,96.73399,0,300,0,0,1,0,0,0,0,0), -- sw cathedral square +(@GUID+4,@BUNNY,0,1,1,0,0,-8433.189,607.2205,95.13025,0,300,0,0,1,0,0,0,0,0), -- sw dwarven district +(@GUID+5,@BUNNY,0,1,1,0,0,-8486.955,390.5139,108.4689,0,300,0,0,1,0,0,0,0,0), -- sw stormwind keep +(@GUID+6,@BUNNY,0,1,1,0,0,-8676.724,444.5052,99.73087,0,300,0,0,1,0,0,0,0,0), -- sw old town +-- +(@GUID+7,@BUNNY,1,1,1,0,0,1573.92,-4397.11,16.00813,0,300,0,0,1,0,0,0,0,0), -- org valley of strength +(@GUID+8,@BUNNY,1,1,1,0,0,1893.24,-4507.31,24.94853,0,300,0,0,1,0,0,0,0,0), -- org the drag +(@GUID+9,@BUNNY,1,1,1,0,0,2015.27,-4687.4,28.61023,0,300,0,0,1,0,0,0,0,0); -- org valley of honor + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry`=@SPELL_PULSE; +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=17 AND `SourceEntry`=@SPELL_BUFF; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`SourceId`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionTarget`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`NegativeCondition`,`ErrorType`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES +(13,1,@SPELL_PULSE,0,0,31,0,3,@GUARD_SW,0,0,0,0,'',"Heavily Perfumed Pulse target Stormwind City Guard"), +(13,1,@SPELL_PULSE,0,1,31,0,3,@PATROOLER_SW,0,0,0,0,'',"Heavily Perfumed Pulse target Stormwind City Patroller"), +(13,1,@SPELL_PULSE,0,2,31,0,3,@GUARD_ORG,0,0,0,0,'',"Heavily Perfumed Pulse target Orgrimmar Grunt"), +(13,1,@SPELL_PULSE,0,3,31,0,3,@ELITE_ORG,0,0,0,0,'',"Heavily Perfumed Pulse target Kor'kron Elite"), +(17,0,@SPELL_BUFF,0,0,1,0,@SPELL_BUFF,0,0,1,0,0,'',"Apply Heavily Perfumed only when missing"); + +UPDATE `creature_template` SET `AIName`='SmartAI',`InhabitType`=4,`flags_extra`=`flags_extra`|128 WHERE `entry`=@BUNNY; +DELETE FROM `smart_scripts` WHERE `entryorguid`=@BUNNY AND `source_type`=0; +INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(@BUNNY,0,0,0,60,0,100,0,0,0,600000,600000,11,@SPELL_PULSE,0,0,0,0,0,1,0,0,0,0,0,0,0,"On update(each 10 min) - Cast - Self"); + +-- ussing this because dummy effect #1 of spell 70192 is to remove the buff +DELETE FROM `spell_linked_spell` WHERE `spell_trigger`=@SPELL_ANALYSIS; +INSERT INTO `spell_linked_spell` (`spell_trigger`,`spell_effect`,`type`,`comment`) VALUES +(@SPELL_ANALYSIS,-@SPELL_BUFF,1,'Remove Heavily Perfumed on Fragrant Air Analysis hit'); + +DELETE FROM `game_event_creature` WHERE `eventEntry`=@EVENT AND `guid` BETWEEN @GUID+0 AND @GUID+9; +INSERT INTO `game_event_creature` (`eventEntry`,`guid`) VALUES +(@EVENT,@GUID+0), +(@EVENT,@GUID+1), +(@EVENT,@GUID+2), +(@EVENT,@GUID+3), +(@EVENT,@GUID+4), +(@EVENT,@GUID+5), +(@EVENT,@GUID+6), +(@EVENT,@GUID+7), +(@EVENT,@GUID+8), +(@EVENT,@GUID+9); diff --git a/sql/updates/world/2013_02_04_01_world_creature_text.sql b/sql/updates/world/2013_02_04_01_world_creature_text.sql new file mode 100644 index 00000000000..c52aa380c49 --- /dev/null +++ b/sql/updates/world/2013_02_04_01_world_creature_text.sql @@ -0,0 +1,165 @@ +-- Ragnaros +UPDATE `creature_text` SET `text`='TOO SOON! YOU HAVE AWAKENED ME TOO SOON, EXECUTUS! WHAT IS THE MEANING OF THIS INTRUSION???' WHERE `entry`=11502 AND `groupid`=1; +UPDATE `creature_text` SET `text`='FOOL! YOU ALLOWED THESE INSECTS TO RUN RAMPANT THROUGH THE HALLOWED CORE? AND NOW YOU LEAD THEM TO MY VERY LAIR? YOU HAVE FAILED ME, EXECUTUS! JUSTICE SHALL BE MET, INDEED!' WHERE `entry`=11502 AND `groupid`=3; +UPDATE `creature_text` SET `text`='NOW FOR YOU, INSECTS! BOLDLY, YOU SOUGHT THE POWER OF RAGNAROS. NOW YOU SHALL SEE IT FIRSTHAND!' WHERE `entry`=11502 AND `groupid`=4; +UPDATE `creature_text` SET `text`='DIE, INSECT!' WHERE `entry`=11502 AND `groupid`=9; + +-- Core Rager +UPDATE `creature_text` SET `text`='%s refuses to die while its master is endangered!' WHERE `entry`=11672 AND `groupid`=0; + +-- Morridune +UPDATE `creature_text` SET `text`='Aku''mai is dead! At last, I can leave this wretched place.' WHERE `entry`=6729 AND `groupid`=0; +UPDATE `creature_text` SET `text`='Speak with me to hear my tale.' WHERE `entry`=6729 AND `groupid`=1; + +-- Amnennar the Coldbringer +UPDATE `creature_text` SET `text`='You''ll never leave this place alive.' WHERE `entry`=7358 AND `groupid`=0; +UPDATE `creature_text` SET `text`='Come, spirits - attend your master!' WHERE `entry`=7358 AND `groupid`=2; +UPDATE `creature_text` SET `text`='Too easy.', `type`=12 WHERE `entry`=7358 AND `groupid`=4; + +-- Weegli Blastfuse +UPDATE `creature_text` SET `text`='Oh no! Here they come!' WHERE `entry`=7607 AND `groupid`=0; +UPDATE `creature_text` SET `text`='Ok, here I go!' WHERE `entry`=7607 AND `groupid`=1; + +-- The Prophet Skeram +UPDATE `creature_text` SET `text`='Are you so eager to die? I will be happy to accommodate you...' WHERE `entry`=15263 AND `groupid`=0 AND `id`=0; +UPDATE `creature_text` SET `text`='You only delay the inevitable!' WHERE `entry`=15263 AND `groupid`=3; + +-- Ossirian the Unscarred +UPDATE `creature_text` SET `text`='Sands of the desert, rise and block out the sun!' WHERE `entry`=15339 AND `groupid`=2; + +-- General Rajaxx +UPDATE `creature_text` SET `text`='Warriors, Captains, continue the fight! ' WHERE `entry`=15341 AND `groupid`=9; +UPDATE `creature_text` SET `text`='Breathe your last!' WHERE `entry`=15341 AND `groupid`=11; + +-- Buru the Gorger +UPDATE `creature_text` SET `text`='%s sets eyes on $n!' WHERE `entry`=15370 AND `groupid`=0; + +-- Spectral Stable Hand +UPDATE `creature_text` SET `type`=12 WHERE `entry`=15551 AND `groupid`=0 AND `id`=0; +UPDATE `creature_text` SET `text`='What will become of--' WHERE `entry`=15551 AND `groupid`=0 AND `id`=1; + +-- Medivh +UPDATE `creature_text` SET `text`='The time has come! Gul''dan, order your warlocks to double their efforts! Moments from now the gateway will open and your Horde will be released upon this ripe, unsuspecting world!' WHERE `entry`=15608 AND `groupid`=0; +UPDATE `creature_text` SET `text`='Champions! My shield grows weak!' WHERE `entry`=15608 AND `groupid`=2; +UPDATE `creature_text` SET `text`='No! Damn this feeble, mortal coil!' WHERE `entry`=15608 AND `groupid`=5; +UPDATE `creature_text` SET `text`='I am grateful for your aid, champions. Now, Gul''dan''s Horde will sweep across this world like a locust swarm, and all my designs, all my carefully-laid plans will at last fall into place.' WHERE `entry`=15608 AND `groupid`=6; +UPDATE `creature_text` SET `text`='Orcs of the Horde! This portal is the gateway to your new destiny! Azeroth lies before you, ripe for the taking!' WHERE `entry`=15608 AND `groupid`=7; + +-- Moroes <Tower Steward> +UPDATE `creature_text` SET `text`='Hm, unannounced visitors. Preparations must be made...' WHERE `entry`=15687 AND `groupid`=0; +UPDATE `creature_text` SET `text`='How terribly clumsy of me.' WHERE `entry`=15687 AND `groupid`=3; + +-- Terestian Illhoof +UPDATE `creature_text` SET `text`='Your blood will anoint my circle!' WHERE `entry`=15688 AND `groupid`=0 AND `id`=0; +UPDATE `creature_text` SET `text`='My life is yours, oh great one...' WHERE `entry`=15688 AND `groupid`=1; +UPDATE `creature_text` SET `text`='Ah, you''re just in time. The rituals are about to begin!' WHERE `entry`=15688 AND `groupid`=2; +UPDATE `creature_text` SET `text`='Please accept this humble offering, oh great one...' WHERE `entry`=15688 AND `groupid`=3 AND `id`=0; +UPDATE `creature_text` SET `text`='Let this sacrifice serve as testament to my fealty.' WHERE `entry`=15688 AND `groupid`=3 AND `id`=1; +UPDATE `creature_text` SET `text`='Come, you dwellers in the dark! Rally to my call!' WHERE `entry`=15688 AND `groupid`=4 AND `id`=0; +UPDATE `creature_text` SET `text`='Gather, my pets... there is plenty for all!' WHERE `entry`=15688 AND `groupid`=4 AND `id`=1; + +-- Prince Malchezaar +UPDATE `creature_text` SET `text`='How can you hope to stand against such overwhelming power?' WHERE `entry`=15690 AND `groupid`=5; +UPDATE `creature_text` SET `text`='I refuse to concede defeat! I am a prince of the Eredar! I... am...' WHERE `entry`=15690 AND `groupid`=8; + +-- The Curator +UPDATE `creature_text` SET `text`='This Curator is equipped for gallery protection.' WHERE `entry`=15691 AND `groupid`=1 AND `id`=1; +UPDATE `creature_text` SET `text`='Curator is no longer operation-a-l.' WHERE `entry`=15691 AND `groupid`=5; + +-- Thaddius +UPDATE `creature_text` SET `text`='You are too late!! I... must... obey!!' WHERE `entry`=15928 AND `groupid`=0; +UPDATE `creature_text` SET `text`='Kill...' WHERE `entry`=15928 AND `groupid`=1 AND `id`=0; +UPDATE `creature_text` SET `text`='Eat... your... bones...' WHERE `entry`=15928 AND `groupid`=1 AND `id`=1; +UPDATE `creature_text` SET `text`='Break... you!!' WHERE `entry`=15928 AND `groupid`=1 AND `id`=2; +UPDATE `creature_text` SET `text`='You... die now!!' WHERE `entry`=15928 AND `groupid`=2; +UPDATE `creature_text` SET `text`='Now you feel pain...' WHERE `entry`=15928 AND `groupid`=3; + +-- Feugen +UPDATE `creature_text` SET `text`='Feugen make master happy.' WHERE `entry`=15930 AND `groupid`=1; + +-- Grand Widow Faerlina +UPDATE `creature_text` SET `text`='Your old lives, your mortal desires mean nothing... you are acolytes of the master now, and you will serve the cause without question! The greatest glory is to die in the master''s service!' WHERE `entry`=15953 AND `groupid`=0; +UPDATE `creature_text` SET `text`='The master will avenge me!!' WHERE `entry`=15953 AND `groupid`=3; + +-- Anub'Rekhan +UPDATE `creature_text` SET `text`='Yes, run! It makes the blood pump faster!' WHERE `entry`=15956 AND `groupid`=0 AND `id`=2; +UPDATE `creature_text` SET `text`='I hear little hearts beating. Yes... beating faster now... soon the beating will stop.' WHERE `entry`=15956 AND `groupid`=1 AND `id`=1; +UPDATE `creature_text` SET `text`='Which one shall I eat first? So difficult to choose. They all smell so delicious...' WHERE `entry`=15956 AND `groupid`=1 AND `id`=3; +UPDATE `creature_text` SET `text`='Closer now. Tasty morsels. I''ve been too long without food, without blood to drink.' WHERE `entry`=15956 AND `groupid`=1 AND `id`=4; +UPDATE `creature_text` SET `text`='Shhh... it will all be over soon.' WHERE `entry`=15956 AND `groupid`=2; + +-- Kel'Thuzad +UPDATE `creature_text` SET `text`='Your forces are nearly marshaled to strike back against your enemies, my liege.' WHERE `entry`=15990 AND `groupid`=0; +UPDATE `creature_text` SET `text`='Yes, master. The time of their ultimate demise draws close.... What is this?' WHERE `entry`=15990 AND `groupid`=2; +UPDATE `creature_text` SET `text`='As you command, master!' WHERE `entry`=15990 AND `groupid`=4; +UPDATE `creature_text` SET `text`='Fools! You think yourselves triumphant? You have only taken one step closer to the abyss!' WHERE `entry`=15990 AND `groupid`=6 AND `id`=1; +UPDATE `creature_text` SET `text`='%s cackles maniacally.', `type`=16 WHERE `entry`=15990 AND `groupid`=8 AND `id`=1; +UPDATE `creature_text` SET `text`='Agghhhh! Do... not... rejoice! Your victory is a hollow one, for I shall return with powers beyond your imagining!' WHERE `entry`=15990 AND `groupid`=9; +UPDATE `creature_text` SET `text`='Your soul is bound to me, now!' WHERE `entry`=15990 AND `groupid`=10 AND `id`=0; +UPDATE `creature_text` SET `text`='Master, I require aid!' WHERE `entry`=15990 AND `groupid`=12; +UPDATE `creature_text` SET `text`='Minions, servants, soldiers of the cold dark! Obey the call of Kel''Thuzad!' WHERE `entry`=15990 AND `groupid`=14; + +-- Patchwerk +UPDATE `creature_text` SET `text`='Kel''thuzad make Patchwerk his avatar of war!' WHERE `entry`=16028 AND `groupid`=0 AND `id`=1; +UPDATE `creature_text` SET `text`='What... happen to-' WHERE `entry`=16028 AND `groupid`=2; +UPDATE `creature_text` SET `text`='%s goes into a frenzy!', `type`=41 WHERE `entry`=16028 AND `groupid`=4; + +-- Spectral Servant +UPDATE `creature_text` SET `type`=12 WHERE `entry`=16407 AND `groupid`=0 AND `id`=0; + +-- Maiden of Virtue +UPDATE `creature_text` SET `text`='Your behavior will not be tolerated.' WHERE `entry`=16457 AND `groupid`=0; + +-- Shade of Aran +UPDATE `creature_text` SET `text`='Please, no more! My son... he''s gone mad!' WHERE `entry`=16524 AND `groupid`=0 AND `id`=0; +UPDATE `creature_text` SET `text`='I''ll show you: this beaten dog still has some teeth!' WHERE `entry`=16524 AND `groupid`=1 AND `id`=0; +UPDATE `creature_text` SET `text`='Burn, you hellish fiends!' WHERE `entry`=16524 AND `groupid`=1 AND `id`=1; +UPDATE `creature_text` SET `text`='Yes, yes my son is quite powerful... but I have powers of my own!' WHERE `entry`=16524 AND `groupid`=3 AND `id`=0; +UPDATE `creature_text` SET `text`='I''m not finished yet! No, I have a few more tricks up my sleeve...', `type`=12 WHERE `entry`=16524 AND `groupid`=5; +UPDATE `creature_text` SET `text`='At last the nightmare is over...' WHERE `entry`=16524 AND `groupid`=8; + +-- Martik Tor'seldori +UPDATE `creature_text` SET `text`='Brothers and sisters, I have been to the promised land. I have tasted in the sublime energy. I have felt bliss - bliss so engrossing and all encompassing that I was left wondering if I had stumbled upon the dreams of gods.' WHERE `entry`=16577 AND `groupid`=0; + +-- Grand Warlock Nethekurse +UPDATE `creature_text` SET `text`='You can have that one, I no longer need him!' WHERE `entry`=16807 AND `groupid`=1 AND `id`=0; +UPDATE `creature_text` SET `text`='Yes, beat him mercilessly! His skull is as thick as an ogre''s!' WHERE `entry`=16807 AND `groupid`=1 AND `id`=1; +UPDATE `creature_text` SET `text`='Don''t waste your time on that one, he''s weak!' WHERE `entry`=16807 AND `groupid`=1 AND `id`=2; +UPDATE `creature_text` SET `text`='One pitiful wretch down. Go on, take another one!' WHERE `entry`=16807 AND `groupid`=2 AND `id`=0; +UPDATE `creature_text` SET `text`='Ah, what a waste... next!' WHERE `entry`=16807 AND `groupid`=2 AND `id`=1; +UPDATE `creature_text` SET `text`='Thank you for saving me the trouble. Now it''s my turn to have some fun!' WHERE `entry`=16807 AND `groupid`=2 AND `id`=3; +UPDATE `creature_text` SET `text`='Beg for your pitiful life!' WHERE `entry`=16807 AND `groupid`=3 AND `id`=0; +UPDATE `creature_text` SET `text`='Run, coward, run! ' WHERE `entry`=16807 AND `groupid`=3 AND `id`=1; -- Blizz fail. +UPDATE `creature_text` SET `text`='Your pain amuses me!' WHERE `entry`=16807 AND `groupid`=3 AND `id`=2; +UPDATE `creature_text` SET `text`='I''m already bored!' WHERE `entry`=16807 AND `groupid`=4 AND `id`=0; +UPDATE `creature_text` SET `text`='Come on, show me a real fight!' WHERE `entry`=16807 AND `groupid`=4 AND `id`=1; +UPDATE `creature_text` SET `text`='I had more fun torturing the peons!' WHERE `entry`=16807 AND `groupid`=4 AND `id`=2; +UPDATE `creature_text` SET `text`='You lose.' WHERE `entry`=16807 AND `groupid`=5 AND `id`=0; +UPDATE `creature_text` SET `text`='Oh, just die!' WHERE `entry`=16807 AND `groupid`=5 AND `id`=1; +UPDATE `creature_text` SET `text`='What... a shame.' WHERE `entry`=16807 AND `groupid`=6; + +-- Warchief Kargath Bladefist +UPDATE `creature_text` SET `text`='Ours is the TRUE Horde! The only Horde!' WHERE `entry`=16808 AND `groupid`=0 AND `id`=0; +UPDATE `creature_text` SET `text`='I am called Bladefist for a reason. As you will see.' WHERE `entry`=16808 AND `groupid`=0 AND `id`=2; +UPDATE `creature_text` SET `text`='I am the ONLY warchief!' WHERE `entry`=16808 AND `groupid`=1 AND `id`=1; +UPDATE `creature_text` SET `text`='The true Horde... will prevail.' WHERE `entry`=16808 AND `groupid`=2; + +-- Barnes <The Stage Manager> +UPDATE `creature_text` SET `text`='Welcome ladies and gentlemen, to this evening''s presentation!' WHERE `entry`=16812 AND `groupid`=0; +UPDATE `creature_text` SET `text`='Tonight we plumb the depths of the human soul as we join a lost, lonely girl trying desperately--with the help of her loyal companions--to find her way home!' WHERE `entry`=16812 AND `groupid`=1; +UPDATE `creature_text` SET `text`='But she is pursued... by a wicked, malevolent crone!' WHERE `entry`=16812 AND `groupid`=2; +UPDATE `creature_text` SET `text`='Will she survive? Will she prevail? Only time will tell. And now... on with the show!' WHERE `entry`=16812 AND `groupid`=3; +UPDATE `creature_text` SET `text`='Good evening ladies and gentlemen, welcome to this evening''s presentation!' WHERE `entry`=16812 AND `groupid`=4; +UPDATE `creature_text` SET `text`='Tonight, things are not what they seem... for tonight your eyes may not be trusted!' WHERE `entry`=16812 AND `groupid`=5; +UPDATE `creature_text` SET `text`='Take for instance this quiet elderly woman waiting for a visit from her granddaughter... surely there is nothing to fear from this sweet, gray-haired old lady!' WHERE `entry`=16812 AND `groupid`=6; +UPDATE `creature_text` SET `text`='But don''t let me pull the wool over your eyes! See for yourself what lies beneath those covers! And now... on with the show!' WHERE `entry`=16812 AND `groupid`=7; +UPDATE `creature_text` SET `text`='Welcome ladies and gentlemen, to this evening''s presentation!' WHERE `entry`=16812 AND `groupid`=8; +UPDATE `creature_text` SET `text`='Tonight... we explore a tale of forbidden love!' WHERE `entry`=16812 AND `groupid`=9; +UPDATE `creature_text` SET `text`='But beware, for not all love stories end happily, as you may find out. Sometimes, love pricks like a thorn!' WHERE `entry`=16812 AND `groupid`=10; +UPDATE `creature_text` SET `text`='But don''t take it from me; see for yourself what tragedy lies ahead when the paths of star crossed lovers meet! And now... on with the show!' WHERE `entry`=16812 AND `groupid`=11; + +-- Shadow Council Enforcer +UPDATE `creature_text` SET `text`='Gul''dan speaks the truth! We should return at once to tell our brothers of the news! Retreat back through the portal!', `type`=14 WHERE `entry`=17023 AND `groupid`=0; + +-- Nightbane +UPDATE `creature_text` SET `text`='%s takes a deep breath.', `type`=41 WHERE `entry`=17225 AND `groupid`=4; diff --git a/sql/updates/world/2013_02_04_02_world_misc.sql b/sql/updates/world/2013_02_04_02_world_misc.sql new file mode 100644 index 00000000000..300d0e31bcb --- /dev/null +++ b/sql/updates/world/2013_02_04_02_world_misc.sql @@ -0,0 +1,119 @@ +-- Pilfering Perfume (A:24656 H:24541) + +SET @QUEST_A := 24656; +SET @QUEST_H := 24541; + +SET @SNIP := 38066; -- Inspector Snip Snagglebolt +SET @SNAP := 37172; -- Detective Snap Snagglebolt +SET @MENUID := 10976; + +SET @TRIGGER_SW_OUT := 5703; -- outside +SET @TRIGGER_SW_IN := 5704; -- inside +SET @TRIGGER_ORG_OUT := 5705; -- outside +SET @TRIGGER_ORG_IN := 5706; -- inside + +SET @SPELL_UNIFORM := 71450; -- Crown Parcel Service Uniform +SET @SPELL_CONTRABAND := 71459; -- Crown Chemical Co. Contraband + +SET @SPELL_CREDIT_A := 71522; -- Crown Chemical Co. Supplies +SET @SPELL_CREDIT_H := 71539; -- Crown Chemical Co. Supplies + +SET @GUID := 48571; -- set by TDB,need 3 (48571,48572,48573) +SET @EVENT := 8; -- Love is in the Air +SET @NPC_GUARD := 37671; -- Crown Supply Guard + +-- missing npcs on horde side +DELETE FROM `creature` WHERE `id`=@NPC_GUARD; +INSERT INTO `creature` (`guid`,`id`,`map`,`spawnMask`,`phaseMask`,`modelid`,`equipment_id`,`position_x`,`position_y`,`position_z`,`orientation`,`spawntimesecs`,`spawndist`,`currentwaypoint`,`curhealth`,`curmana`,`MovementType`,`npcflag`,`unit_flags`,`dynamicflags`) VALUES +(@GUID+0,@NPC_GUARD,1,1,1,0,0,1391.2,-4486.23,31.4544,3.3355,300,0,0,42,0,0,0,0,0), +(@GUID+1,@NPC_GUARD,1,1,1,0,0,1392.66,-4481.87,31.3782,1.97284,300,0,0,42,0,0,0,0,0), +(@GUID+2,@NPC_GUARD,1,1,1,0,0,1393.92,-4489.57,31.4737,4.93701,300,0,0,42,0,0,0,0,0); + +DELETE FROM `game_event_creature` WHERE `eventEntry`=@EVENT AND `guid` BETWEEN @GUID+0 AND @GUID+2; +INSERT INTO `game_event_creature` (`eventEntry`,`guid`) VALUES +(@EVENT,@GUID+0), +(@EVENT,@GUID+1), +(@EVENT,@GUID+2); + +-- removing a wrong spawn +DELETE FROM `creature` WHERE `guid`=40507; +DELETE FROM `game_event_creature` WHERE `guid`=40507; + +-- deleting wrong previous spawns and reusing some guids to spawn proper ones +DELETE FROM `gameobject` WHERE `guid` IN (24416,24417,24418,24419,24420,24421,24422,24423,24433,24434,24435,24436,24437,24438,24439,24440,24441); +INSERT INTO `gameobject` (`guid`,`id`,`map`,`spawnMask`,`phaseMask`,`position_x`,`position_y`,`position_z`,`orientation`,`rotation0`,`rotation1`,`rotation2`,`rotation3`,`spawntimesecs`,`animprogress`,`state`) VALUES +(24416,181015,1,1,1,1392.938,-4485.202,31.41421,0,0,0,0,1,120,255,1), +(24417,201778,1,1,1,1393.677,-4486.033,32.67227,0,0,0,0,1,120,255,1), +(24418,201752,1,1,1,1394.184,-4484.108,31.24833,4.32842,0,0,0,1,120,255,1), +(24419,201778,1,1,1,1394.26,-4484.368,32.50796,5.148723,0,0,0,1,120,255,1), +(24420,201752,1,1,1,1393.319,-4486.797,31.42903,4.101525,0,0,0,1,120,255,1), +(24421,201752,1,1,1,1394.401,-4485.688,31.35416,5.916668,0,0,0,1,120,255,1), +(24422,201752,1,1,1,1394.042,-4488.397,31.4775,4.32842,0,0,0,1,120,255,1), +(24423,201752,1,1,1,1396.476,-4482.715,32.14788,4.32842,0,0,0,1,120,255,1), +(24433,181015,1,1,1,1395.002,-4487.113,31.37537,3.874631,0,0,0,1,120,255,1), +(24434,181015,1,1,1,1396.632,-4482.505,30.87226,5.166176,0,0,0,1,120,255,1), +(24435,201752,1,1,1,1395.813,-4486.439,32.56021,1.710422,0,0,0,1,120,255,1), +(24436,201752,1,1,1,1396.595,-4486.056,31.15484,4.32842,0,0,0,1,120,255,1), +(24437,201752,1,1,1,1397.377,-4488.021,33.71862,0.157079,0,0,0,1,120,255,1), +(24438,181015,1,1,1,1397.51,-4487.901,32.46279,3.68265,0,0,0,1,120,255,1), +(24439,201752,1,1,1,1397.571,-4487.939,31.21067,3.33359,0,0,0,1,120,255,1); +-- these guids will remain free +DELETE FROM `game_event_gameobject` WHERE `eventEntry`=@EVENT AND `guid` IN (24440,24441); + +-- Snip & Snap sai +UPDATE `creature_template` SET `npcflag`=`npcflag`|1|2,`gossip_menu_id`=@MENUID,`AIName`='SmartAI' WHERE `entry` IN (@SNIP,@SNAP); +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (@SNIP,@SNAP) AND `source_type`=0; +INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(@SNIP,0,0,0,19,0,100,0,@QUEST_A,0,0,0,11,@SPELL_UNIFORM,0,0,0,0,0,7,0,0,0,0,0,0,0,'Snip - On quest accept - Spellcast'), +(@SNIP,0,1,2,62,0,100,0,@MENUID,0,0,0,72,0,0,0,0,0,0,7,0,0,0,0,0,0,0,'Snip - On gossip option select - Close gossip'), +(@SNIP,0,2,0,61,0,100,0,0,0,0,0,11,@SPELL_UNIFORM,0,0,0,0,0,7,0,0,0,0,0,0,0,'Snip - On gossip option accept - Spellcast'), +-- +(@SNAP,0,0,0,19,0,100,0,@QUEST_H,0,0,0,11,@SPELL_UNIFORM,0,0,0,0,0,7,0,0,0,0,0,0,0,'Snap - On quest accept - Spellcast'), +(@SNAP,0,1,2,62,0,100,0,@MENUID,0,0,0,72,0,0,0,0,0,0,7,0,0,0,0,0,0,0,'Snap - On gossip option select - Close gossip'), +(@SNAP,0,2,0,61,0,100,0,0,0,0,0,11,@SPELL_UNIFORM,0,0,0,0,0,7,0,0,0,0,0,0,0,'Snap - On gossip option accept - Spellcast'); + +DELETE FROM `areatrigger_involvedrelation` WHERE `id` IN (@TRIGGER_SW_OUT,@TRIGGER_SW_IN,@TRIGGER_ORG_OUT,@TRIGGER_ORG_IN); +INSERT INTO `areatrigger_involvedrelation` (`id`,`quest`) VALUES +(@TRIGGER_SW_OUT,@QUEST_A), +(@TRIGGER_SW_IN,@QUEST_A), +-- +(@TRIGGER_ORG_OUT,@QUEST_H), +(@TRIGGER_ORG_IN,@QUEST_H); + +DELETE FROM `areatrigger_scripts` WHERE `entry` IN (@TRIGGER_SW_OUT,@TRIGGER_SW_IN,@TRIGGER_ORG_OUT,@TRIGGER_ORG_IN); +INSERT INTO `areatrigger_scripts` (`entry`,`ScriptName`) VALUES +(@TRIGGER_SW_OUT,'SmartTrigger'), +(@TRIGGER_SW_IN,'SmartTrigger'), +-- +(@TRIGGER_ORG_OUT,'SmartTrigger'), +(@TRIGGER_ORG_IN,'SmartTrigger'); + +-- usig invoker cast because normal cast doesn't want to work(LoS issue,i think) +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (@TRIGGER_SW_OUT,@TRIGGER_SW_IN,@TRIGGER_ORG_OUT,@TRIGGER_ORG_IN) AND `source_type`=2; +INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(@TRIGGER_SW_OUT,2,0,0,46,0,100,0,@TRIGGER_SW_OUT,0,0,0,85,@SPELL_CONTRABAND,0,0,0,0,0,7,0,0,0,0,0,0,0,"On Trigger - Cast - Invoker"), +(@TRIGGER_SW_IN,2,0,0,46,0,100,0,@TRIGGER_SW_IN,0,0,0,85,@SPELL_CREDIT_A,0,0,0,0,0,7,0,0,0,0,0,0,0,"On Trigger - Cast - Invoker"), +-- +(@TRIGGER_ORG_OUT,2,0,0,46,0,100,0,@TRIGGER_ORG_OUT,0,0,0,85,@SPELL_CONTRABAND,0,0,0,0,0,7,0,0,0,0,0,0,0,"On Trigger - Cast - Invoker"), +(@TRIGGER_ORG_IN,2,0,0,46,0,100,0,@TRIGGER_ORG_IN,0,0,0,85,@SPELL_CREDIT_H,0,0,0,0,0,7,0,0,0,0,0,0,0,"On Trigger - Cast - Invoker"); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=22 AND `SourceEntry` IN (@TRIGGER_SW_OUT,@TRIGGER_SW_IN,@TRIGGER_ORG_OUT,@TRIGGER_ORG_IN); +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=@MENUID; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`SourceId`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionTarget`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`NegativeCondition`,`ErrorType`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES +(22,1,@TRIGGER_SW_OUT,2,0,1,0,@SPELL_UNIFORM,0,0,0,0,0,'','execute sai only if player has aura'), +(22,1,@TRIGGER_SW_IN,2,0,1,0,@SPELL_CONTRABAND,0,0,0,0,0,'','execute sai only if player has aura'), +(15,@MENUID,0,0,0,9,0,@QUEST_A,0,0,0,0,0,'','show gossip option only if player has quest taken'), +-- +(22,1,@TRIGGER_ORG_OUT,2,0,1,0,@SPELL_UNIFORM,0,0,0,0,0,'','execute sai only if player has aura'), +(22,1,@TRIGGER_ORG_IN,2,0,1,0,@SPELL_CONTRABAND,0,0,0,0,0,'','execute sai only if player has aura'), +(15,@MENUID,0,0,1,9,0,@QUEST_H,0,0,0,0,0,'','show gossip option only if player has quest taken'); + +DELETE FROM `spell_linked_spell` WHERE `spell_trigger` IN (@SPELL_CREDIT_A,@SPELL_CREDIT_H,-@SPELL_UNIFORM); +INSERT INTO `spell_linked_spell` (`spell_trigger`,`spell_effect`,`type`,`comment`) VALUES +(@SPELL_CREDIT_A,-@SPELL_UNIFORM,1,'Remove Crown Parcel Service Uniform on Crown Chemical Co. Supplies hit'), +(@SPELL_CREDIT_H,-@SPELL_UNIFORM,1,'Remove Crown Parcel Service Uniform on Crown Chemical Co. Supplies hit'), +(-@SPELL_UNIFORM,-@SPELL_CONTRABAND,0,'Remove Crown Chemical Co. Contraband when Crown Parcel Service Uniform is removed'); + +DELETE FROM `spell_script_names` WHERE `spell_id`=@SPELL_UNIFORM; +INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES +(@SPELL_UNIFORM,'spell_gen_aura_service_uniform'); diff --git a/sql/updates/world/2013_02_04_03_world_misc.sql b/sql/updates/world/2013_02_04_03_world_misc.sql new file mode 100644 index 00000000000..a609d411b6e --- /dev/null +++ b/sql/updates/world/2013_02_04_03_world_misc.sql @@ -0,0 +1,53 @@ +DELETE FROM `trinity_string` WHERE `entry` BETWEEN 63 AND 95; +INSERT INTO trinity_string (entry, content_default) VALUES +(63, "Wrong parameter id: %u, does not exist"), +(64, "Wrong parameter realmId: %d"), +(65, "Couldn't add group %u (%s) realmId %d. Account %u (%s) already has that group"), +(66, "Couldn't remove group %u (%s) realmId %d. Account %u (%s) does not have that group"), +(67, "Added group %u (%s) realmId %d to account %u (%s)"), +(68, "Removed group %u (%s) realmId %d from account %u (%s)"), +(69, "Account %u (%s) groups:"), +(70, "Empty List"), +(71, "- %u (%s)"), +(72, "Couldn't grant role %u (%s) realmId %d. Account %u (%s) already has that role"), +(73, "Couldn't grant role %u (%s) realmId %d. Account %u (%s) has that role in deny list"), +(74, "Granted role %u (%s) realmId %d to account %u (%s)"), +(75, "Couldn't deny role %u (%s) realmId %d. Account %u (%s) already has that role"), +(76, "Couldn't deny role %u (%s) realmId %d. Account %u (%s) has that role in deny list"), +(77, "Denied role %u (%s) realmId %d to account %u (%s)"), +(78, "Denied role %u (%s) realmId %d to account %u (%s)"), +(79, "Couldn't revoke role %u (%s) realmId %d. Account %u (%s) does not have that role"), +(80, "Account %u (%s) granted roles:"), +(81, "Account %u (%s) denied roles:"), +(82, "Couldn't grant permission %u (%s) realmId %d. Account %u (%s) already has that permission"), +(83, "Couldn't grant permission %u (%s) realmId %d. Account %u (%s) has that permission in deny list"), +(84, "Granted permission %u (%s) realmId %d to account %u (%s)"), +(85, "Couldn't deny permission %u (%s) realmId %d. Account %u (%s) already has that permission"), +(86, "Couldn't deny permission %u (%s) realmId %d. Account %u (%s) has that permission in deny list"), +(87, "Denied permission %u (%s) realmId %d to account %u (%s)"), +(88, "Revoked permission %u (%s) realmId %d to account %u (%s)"), +(89, "Couldn't revoke permission %u (%s) realmId %d. Account %u (%s) does not have that permission"), +(90, "Account %u (%s) granted permissions:"), +(91, "Account %u (%s) denied permissions:"), +(92, "Account %u (%s) global permissions:"), +(93, "Groups:"), +(94, "Roles:"), +(95, "Permissions:"); + +DELETE FROM `command` WHERE `name` LIKE '.rbac%'; +INSERT INTO `command` (`name`, `security`, `help`) VALUES +('.rbac account', 3, 'Syntax: .rbac account [$account]\n\nView permissions of selected player or given account\nNote: Only those that affect current realm\n\nNote: Shows real permissions after checking group and roles'), +('.rbac account group', 3, 'Syntax: .rbac account group [$account]\n\nView groups of selected player or given account\nNote: Only those that affect current realm'), +('.rbac account group add', 3, 'Syntax: .rbac account group add [$account] #id [#realmId]\n\nAdd a group to selected player or given account.\n\n#reamID may be -1 for all realms.'), +('.rbac account group remove', 3, 'Syntax: .rbac account group remove [$account] #id\n\nRemove a group from selected player or given account.'), +('.rbac account role', 3, 'Syntax: .rbac account role [$account]\n\nView roles of selected player or given account\nNote: Only those that affect current realm\nNote: Only those directly granted or denied, does not include inherited roles from groups'), +('.rbac account role grant', 3, 'Syntax: .rbac account role grant [$account] #id [#realmId]\n\nGrant a role to selected player or given account.\n\n#reamID may be -1 for all realms.'), +('.rbac account role deny', 3, 'Syntax: .rbac account role deny [$account] #id [#realmId]\n\nDeny a role to selected player or given account.\n\n#reamID may be -1 for all realms.'), +('.rbac account role revoke', 3, 'Syntax: .rbac account role revoke [$account] #id\n\nRemove a role from an account\n\nNote: Removes the role from granted or denied roles'), +('.rbac account permission', 3, 'Syntax: .rbac account permission [$account]\n\nView permissions of selected player or given account\nNote: Only those that affect current realm\nNote: Only those directly granted or denied, does not include inherited permissions from roles'), +('.rbac account permission grant', 3, 'Syntax: .rbac account permission grant [$account] #id [#realmId]\n\nGrant a permission to selected player or given account.\n\n#reamID may be -1 for all realms.'), +('.rbac account permission deny', 3, 'Syntax: .rbac account permission deny [$account] #id [#realmId]\n\nDeny a permission to selected player or given account.\n\n#reamID may be -1 for all realms.'), +('.rbac account permission revoke', 3, 'Syntax: .rbac account permission revoke [$account] #id\n\nRemove a permission from an account\n\nNote: Removes the permission from granted or denied permissions'), +('.rbac list groups', 3, 'Syntax: .rbac list groups [$id]\n\nView list of all groups. If $id is given will show group info and his inherited roles.'), +('.rbac list roles', 3, 'Syntax: .rbac list roles [$id]\n\nView list of all roles. If $id is given will show role info and his inherited permissions.'), +('.rbac list permissions', 3, 'Syntax: .rbac list permissions [$id]\n\nView list of all permissions. If $id is given will show only info for that permission.'); diff --git a/sql/updates/world/2013_02_04_04_world_trinity_string.sql b/sql/updates/world/2013_02_04_04_world_trinity_string.sql new file mode 100644 index 00000000000..0a4ec437b28 --- /dev/null +++ b/sql/updates/world/2013_02_04_04_world_trinity_string.sql @@ -0,0 +1,4 @@ +DELETE FROM `trinity_string` WHERE entry IN (300,550); +INSERT INTO `trinity_string` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES +('300','Your chat has been disabled for %u minutes. By: %s ,Reason: %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +('550','Mute time remaining: %s, By: %s, Reason: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); diff --git a/sql/updates/world/2013_02_04_05_world_spell_script_names.sql b/sql/updates/world/2013_02_04_05_world_spell_script_names.sql new file mode 100644 index 00000000000..4dd5ee52583 --- /dev/null +++ b/sql/updates/world/2013_02_04_05_world_spell_script_names.sql @@ -0,0 +1 @@ +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_gen_luck_of_the_draw'; diff --git a/sql/updates/world/2013_02_04_06_world_command.sql b/sql/updates/world/2013_02_04_06_world_command.sql new file mode 100644 index 00000000000..fb36c512c4a --- /dev/null +++ b/sql/updates/world/2013_02_04_06_world_command.sql @@ -0,0 +1,15 @@ +UPDATE `command` SET `name` = 'rbac account' WHERE `name` LIKE '.rbac account'; +UPDATE `command` SET `name` = 'rbac account group' WHERE `name` LIKE '.rbac account group'; +UPDATE `command` SET `name` = 'rbac account group add' WHERE `name` LIKE '.rbac account group add'; +UPDATE `command` SET `name` = 'rbac account group remove' WHERE `name` LIKE '.rbac account group remove'; +UPDATE `command` SET `name` = 'rbac account permission' WHERE `name` LIKE '.rbac account permission'; +UPDATE `command` SET `name` = 'rbac account permission deny' WHERE `name` LIKE '.rbac account permission deny'; +UPDATE `command` SET `name` = 'rbac account permission grant' WHERE `name` LIKE '.rbac account permission grant'; +UPDATE `command` SET `name` = 'rbac account permission revoke' WHERE `name` LIKE '.rbac account permission revoke'; +UPDATE `command` SET `name` = 'rbac account role' WHERE `name` LIKE '.rbac account role'; +UPDATE `command` SET `name` = 'rbac account role deny' WHERE `name` LIKE '.rbac account role deny'; +UPDATE `command` SET `name` = 'rbac account role grant' WHERE `name` LIKE '.rbac account role grant'; +UPDATE `command` SET `name` = 'rbac account role revoke' WHERE `name` LIKE '.rbac account role revoke'; +UPDATE `command` SET `name` = 'rbac list groups' WHERE `name` LIKE '.rbac list groups'; +UPDATE `command` SET `name` = 'rbac list permissions' WHERE `name` LIKE '.rbac list permissions'; +UPDATE `command` SET `name` = 'rbac list roles' WHERE `name` LIKE '.rbac list roles'; diff --git a/src/server/game/AI/CreatureAIImpl.h b/src/server/game/AI/CreatureAIImpl.h index 7121a031ec2..6c5cb5622b3 100644 --- a/src/server/game/AI/CreatureAIImpl.h +++ b/src/server/game/AI/CreatureAIImpl.h @@ -314,10 +314,10 @@ const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, c class EventMap { /** - * Internal storage type. + * Internal storage type. * Key: Time as uint32 when the event should occur. - * Value: The event data as uint32. - * + * Value: The event data as uint32. + * * Structure of event data: * - Bit 0 - 15: Event Id. * - Bit 16 - 23: Group @@ -454,7 +454,7 @@ class EventMap { if (Empty()) return; - + uint32 eventId = _eventMap.begin()->second; _eventMap.erase(_eventMap.begin()); ScheduleEvent(eventId, time); @@ -480,7 +480,7 @@ class EventMap while (!Empty()) { EventStore::iterator itr = _eventMap.begin(); - + if (itr->first > _time) return 0; else if (_phase && (itr->second & 0xFF000000) && !((itr->second >> 24) & _phase)) @@ -492,7 +492,7 @@ class EventMap return eventId; } } - + return 0; } @@ -506,7 +506,7 @@ class EventMap while (!Empty()) { EventStore::iterator itr = _eventMap.begin(); - + if (itr->first > _time) return 0; else if (_phase && (itr->second & 0xFF000000) && !(itr->second & (_phase << 24))) @@ -514,7 +514,7 @@ class EventMap else return (itr->second & 0x0000FFFF); } - + return 0; } @@ -538,7 +538,7 @@ class EventMap { if (!group || group > 8 || Empty()) return; - + EventStore delayed; for (EventStore::iterator itr = _eventMap.begin(); itr != _eventMap.end();) @@ -551,7 +551,7 @@ class EventMap else ++itr; } - + _eventMap.insert(delayed.begin(), delayed.end()); } @@ -578,7 +578,7 @@ class EventMap * @name CancelEventGroup * @brief Cancel events belonging to specified group. * @param group Group to cancel. - */ + */ void CancelEventGroup(uint32 group) { if (!group || group > 8 || Empty()) @@ -610,7 +610,7 @@ class EventMap return 0; } - + /** * @name GetNextEventTime * @return Time of next event. @@ -636,14 +636,14 @@ class EventMap * @name _time * @brief Internal timer. * - * This does not represent the real date/time value. + * This does not represent the real date/time value. * It's more like a stopwatch: It can run, it can be stopped, * it can be resetted and so on. Events occur when this timer * has reached their time value. Its value is changed in the * Update method. */ uint32 _time; - + /** * @name _phase * @brief Phase mask of the event map. @@ -653,7 +653,7 @@ class EventMap * AddPhase. RemovePhase deactives a phase. */ uint8 _phase; - + /** * @name _eventMap * @brief Internal event storage map. Contains the scheduled events. diff --git a/src/server/game/Accounts/AccountMgr.cpp b/src/server/game/Accounts/AccountMgr.cpp index 3c3eded1f68..ce382342de8 100644 --- a/src/server/game/Accounts/AccountMgr.cpp +++ b/src/server/game/Accounts/AccountMgr.cpp @@ -17,6 +17,7 @@ */ #include "AccountMgr.h" +#include "Config.h" #include "DatabaseEnv.h" #include "ObjectAccessor.h" #include "Player.h" @@ -26,6 +27,7 @@ AccountMgr::AccountMgr() { + } AccountOpResult AccountMgr::CreateAccount(std::string username, std::string password) @@ -44,12 +46,22 @@ AccountOpResult AccountMgr::CreateAccount(std::string username, std::string pass stmt->setString(0, username); stmt->setString(1, CalculateShaPassHash(username, password)); - LoginDatabase.Execute(stmt); + LoginDatabase.DirectExecute(stmt); // Enforce saving, otherwise AddGroup can fail stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_REALM_CHARACTERS_INIT); LoginDatabase.Execute(stmt); + // Add default rbac groups for that security level + RBACData* rbac = new RBACData(GetId(username), username, -1); + // No need to Load From DB, as it's new data + + RBACGroupContainer const& groupsToAdd = _defaultGroups[0]; // 0: Default sec level + for (RBACGroupContainer::const_iterator it = groupsToAdd.begin(); it != groupsToAdd.end(); ++it) + rbac->AddGroup(*it, -1); + + delete rbac; + return AOR_OK; // everything's fine } @@ -303,3 +315,206 @@ bool AccountMgr::IsConsoleAccount(uint32 gmlevel) { return gmlevel == SEC_CONSOLE; } + +void AccountMgr::LoadRBAC() +{ + uint32 oldMSTime = getMSTime(); + uint32 count1 = 0; + uint32 count2 = 0; + uint32 count3 = 0; + + QueryResult result = LoginDatabase.Query("SELECT id, name FROM rbac_permissions"); + if (!result) + { + sLog->outInfo(LOG_FILTER_SQL, ">> Loaded 0 account permission definitions. DB table `rbac_permissions` is empty."); + return; + } + + do + { + Field* field = result->Fetch(); + uint32 id = field[0].GetUInt32(); + _permissions[id] = new RBACPermission(id, field[1].GetString()); + ++count1; + } + while (result->NextRow()); + + result = LoginDatabase.Query("SELECT id, name FROM rbac_roles"); + if (!result) + { + sLog->outInfo(LOG_FILTER_SQL, ">> Loaded 0 account role definitions. DB table `rbac_roles` is empty."); + return; + } + + do + { + Field* field = result->Fetch(); + uint32 id = field[0].GetUInt32(); + _roles[id] = new RBACRole(id, field[1].GetString()); + ++count2; + } + while (result->NextRow()); + + result = LoginDatabase.Query("SELECT roleId, permissionId FROM rbac_role_permissions"); + if (!result) + { + sLog->outInfo(LOG_FILTER_SQL, ">> Loaded 0 account role-permission definitions. DB table `rbac_role_permissions` is empty."); + return; + } + + do + { + Field* field = result->Fetch(); + uint32 id = field[0].GetUInt32(); + RBACRole* role = _roles[id]; + role->GrantPermission(field[1].GetUInt32()); + } + while (result->NextRow()); + + result = LoginDatabase.Query("SELECT id, name FROM rbac_groups"); + if (!result) + { + sLog->outInfo(LOG_FILTER_SQL, ">> Loaded 0 account group definitions. DB table `rbac_groups` is empty."); + return; + } + + do + { + Field* field = result->Fetch(); + uint32 id = field[0].GetUInt32(); + _groups[id] = new RBACGroup(id, field[1].GetString()); + ++count3; + } + while (result->NextRow()); + + result = LoginDatabase.Query("SELECT groupId, roleId FROM rbac_group_roles"); + if (!result) + { + sLog->outInfo(LOG_FILTER_SQL, ">> Loaded 0 account group-role definitions. DB table `rbac_group_roles` is empty."); + return; + } + + do + { + Field* field = result->Fetch(); + uint32 id = field[0].GetUInt32(); + RBACGroup* group = _groups[id]; + group->GrantRole(field[1].GetUInt32()); + } + while (result->NextRow()); + + result = LoginDatabase.Query("SELECT secId, groupId FROM rbac_security_level_groups ORDER by secId ASC"); + if (!result) + { + sLog->outInfo(LOG_FILTER_SQL, ">> Loaded 0 account default groups for security levels definitions. DB table `rbac_security_level_groups` is empty."); + return; + } + + uint8 lastSecId = 255; + RBACGroupContainer* groups = NULL; + do + { + Field* field = result->Fetch(); + uint8 secId = field[0].GetUInt8(); + + if (lastSecId != secId) + groups = &_defaultGroups[secId]; + + groups->insert(field[1].GetUInt32()); + } + while (result->NextRow()); + + sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u permission definitions, %u role definitions and %u group definitions in %u ms", count1, count2, count3, GetMSTimeDiffToNow(oldMSTime)); +} + +void AccountMgr::UpdateAccountAccess(RBACData* rbac, uint32 accountId, uint8 securityLevel, int32 realmId) +{ + int32 serverRealmId = realmId != -1 ? realmId : ConfigMgr::GetIntDefault("RealmID", 0); + bool needDelete = false; + if (!rbac) + { + needDelete = true; + rbac = new RBACData(accountId, "", serverRealmId); + rbac->LoadFromDB(); + } + + // Get max security level and realm (checking current realm and -1) + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_ACCESS_BY_ID); + stmt->setUInt32(0, accountId); + stmt->setInt32(1, serverRealmId); + PreparedQueryResult result = LoginDatabase.Query(stmt); + if (result) + { + do + { + Field* field = result->Fetch(); + uint8 secLevel = field[0].GetUInt8(); + int32 realmId = field[1].GetUInt32(); + + RBACGroupContainer const& groupsToRemove = _defaultGroups[secLevel]; + for (RBACGroupContainer::const_iterator it = groupsToRemove.begin(); it != groupsToRemove.end(); ++it) + rbac->RemoveGroup(*it, realmId); + } + while (result->NextRow()); + } + + // Add new groups depending on the new security Level + RBACGroupContainer const& groupsToAdd = _defaultGroups[securityLevel]; + for (RBACGroupContainer::const_iterator it = groupsToAdd.begin(); it != groupsToAdd.end(); ++it) + rbac->AddGroup(*it, realmId); + + if (needDelete) + delete rbac; + + // Delete old security level from DB + if (realmId == -1) + { + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_ACCOUNT_ACCESS); + stmt->setUInt32(0, accountId); + LoginDatabase.Execute(stmt); + } + else + { + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_ACCOUNT_ACCESS_BY_REALM); + stmt->setUInt32(0, accountId); + stmt->setUInt32(1, realmId); + LoginDatabase.Execute(stmt); + } + + // Add new security level + if (securityLevel) + { + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_ACCOUNT_ACCESS); + stmt->setUInt32(0, accountId); + stmt->setUInt8(1, securityLevel); + stmt->setInt32(2, realmId); + LoginDatabase.Execute(stmt); + } +} + +RBACGroup const* AccountMgr::GetRBACGroup(uint32 group) const +{ + RBACGroupsContainer::const_iterator it = _groups.find(group); + if (it != _groups.end()) + return it->second; + + return NULL; +} + +RBACRole const* AccountMgr::GetRBACRole(uint32 role) const +{ + RBACRolesContainer::const_iterator it = _roles.find(role); + if (it != _roles.end()) + return it->second; + + return NULL; +} + +RBACPermission const* AccountMgr::GetRBACPermission(uint32 permission) const +{ + RBACPermissionsContainer::const_iterator it = _permissions.find(permission); + if (it != _permissions.end()) + return it->second; + + return NULL; +} diff --git a/src/server/game/Accounts/AccountMgr.h b/src/server/game/Accounts/AccountMgr.h index c8de5688e73..90c533ca5fa 100644 --- a/src/server/game/Accounts/AccountMgr.h +++ b/src/server/game/Accounts/AccountMgr.h @@ -19,8 +19,7 @@ #ifndef _ACCMGR_H #define _ACCMGR_H -#include "Define.h" -#include <string> +#include "RBAC.h" #include <ace/Singleton.h> enum AccountOpResult @@ -35,6 +34,11 @@ enum AccountOpResult #define MAX_ACCOUNT_STR 16 +typedef std::map<uint32, RBACPermission*> RBACPermissionsContainer; +typedef std::map<uint32, RBACRole*> RBACRolesContainer; +typedef std::map<uint32, RBACGroup*> RBACGroupsContainer; +typedef std::map<uint32, RBACGroupContainer> RBACDefaultSecurityGroupContainer; + class AccountMgr { friend class ACE_Singleton<AccountMgr, ACE_Null_Mutex>; @@ -43,7 +47,7 @@ class AccountMgr AccountMgr(); public: - static AccountOpResult CreateAccount(std::string username, std::string password); + AccountOpResult CreateAccount(std::string username, std::string password); static AccountOpResult DeleteAccount(uint32 accountId); static AccountOpResult ChangeUsername(uint32 accountId, std::string newUsername, std::string newPassword); static AccountOpResult ChangePassword(uint32 accountId, std::string newPassword); @@ -62,6 +66,23 @@ class AccountMgr static bool IsGMAccount(uint32 gmlevel); static bool IsAdminAccount(uint32 gmlevel); static bool IsConsoleAccount(uint32 gmlevel); + + void UpdateAccountAccess(RBACData* rbac, uint32 accountId, uint8 securityLevel, int32 realmId); + + void LoadRBAC(); + RBACGroup const* GetRBACGroup(uint32 group) const; + RBACRole const* GetRBACRole(uint32 role) const; + RBACPermission const* GetRBACPermission(uint32 permission) const; + + RBACGroupsContainer const& GetRBACGroupList() const { return _groups; } + RBACRolesContainer const& GetRBACRoleList() const { return _roles; } + RBACPermissionsContainer const& GetRBACPermissionList() const { return _permissions; } + + private: + RBACPermissionsContainer _permissions; + RBACRolesContainer _roles; + RBACGroupsContainer _groups; + RBACDefaultSecurityGroupContainer _defaultGroups; }; #define sAccountMgr ACE_Singleton<AccountMgr, ACE_Null_Mutex>::instance() diff --git a/src/server/game/Accounts/RBAC.cpp b/src/server/game/Accounts/RBAC.cpp new file mode 100644 index 00000000000..4a069df05cd --- /dev/null +++ b/src/server/game/Accounts/RBAC.cpp @@ -0,0 +1,336 @@ +/*
+ * Copyright (C) 2008-2013 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "RBAC.h"
+#include "AccountMgr.h"
+#include "DatabaseEnv.h"
+
+RBACCommandResult RBACData::AddGroup(uint32 groupId, int32 realmId /* = 0 */)
+{
+ // Check if group Id exists
+ RBACGroup const* group = sAccountMgr->GetRBACGroup(groupId);
+ if (!group)
+ return RBAC_ID_DOES_NOT_EXISTS;
+
+ // Already added?
+ std::pair<std::set<uint32>::iterator, bool> ret = _groups.insert(groupId);
+ if (!ret.second)
+ return RBAC_CANT_ADD_ALREADY_ADDED;
+
+ // Do not save to db when loading data from DB (realmId = 0)
+ if (realmId)
+ {
+ PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_RBAC_ACCOUNT_GROUP);
+ stmt->setUInt32(0, GetId());
+ stmt->setUInt32(1, groupId);
+ stmt->setInt32(2, realmId);
+ LoginDatabase.Execute(stmt);
+
+ CalculateNewPermissions();
+ }
+
+ return RBAC_OK;
+}
+
+RBACCommandResult RBACData::RemoveGroup(uint32 groupId, int32 realmId /* = 0 */)
+{
+ // could remove it?
+ if (!_groups.erase(groupId))
+ return RBAC_CANT_REVOKE_NOT_IN_LIST;
+
+ // Do not save to db when loading data from DB (realmId = 0)
+ if (realmId)
+ {
+ PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_RBAC_ACCOUNT_GROUP);
+ stmt->setUInt32(0, GetId());
+ stmt->setUInt32(1, groupId);
+ stmt->setInt32(2, realmId);
+ LoginDatabase.Execute(stmt);
+
+ CalculateNewPermissions();
+ }
+
+ return RBAC_OK;
+}
+
+RBACCommandResult RBACData::GrantRole(uint32 roleId, int32 realmId /* = 0*/)
+{
+ // Check if role Id exists
+ RBACRole const* role = sAccountMgr->GetRBACRole(roleId);
+ if (!role)
+ return RBAC_ID_DOES_NOT_EXISTS;
+
+ // Check if already added in denied list
+ if (_deniedRoles.find(roleId) != _deniedRoles.end())
+ return RBAC_IN_DENIED_LIST;
+
+ // Already added?
+ std::pair<std::set<uint32>::iterator, bool> ret = _grantedRoles.insert(roleId);
+ if (!ret.second)
+ return RBAC_CANT_ADD_ALREADY_ADDED;
+
+ // Do not save to db when loading data from DB (realmId = 0)
+ if (realmId)
+ {
+ SaveRole(roleId, true, realmId);
+ CalculateNewPermissions();
+ }
+
+ return RBAC_OK;
+}
+
+RBACCommandResult RBACData::DenyRole(uint32 roleId, int32 realmId /* = 0*/)
+{
+ // Check if role Id exists
+ RBACRole const* role = sAccountMgr->GetRBACRole(roleId);
+ if (!role)
+ return RBAC_ID_DOES_NOT_EXISTS;
+
+ // Check if already added in granted list
+ if (_grantedRoles.find(roleId) != _grantedRoles.end())
+ return RBAC_IN_GRANTED_LIST;
+
+ // Already added?
+ std::pair<std::set<uint32>::iterator, bool> ret = _deniedRoles.insert(roleId);
+ if (!ret.second)
+ return RBAC_CANT_ADD_ALREADY_ADDED;
+
+ // Do not save to db when loading data from DB (realmId = 0)
+ if (realmId)
+ {
+ SaveRole(roleId, false, realmId);
+ CalculateNewPermissions();
+ }
+
+ return RBAC_OK;
+}
+
+void RBACData::SaveRole(uint32 roleId, bool granted, int32 realmId)
+{
+ PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_RBAC_ACCOUNT_ROLE);
+ stmt->setUInt32(0, GetId());
+ stmt->setUInt32(1, roleId);
+ stmt->setBool(2, granted);
+ stmt->setInt32(3, realmId);
+ LoginDatabase.Execute(stmt);
+}
+
+RBACCommandResult RBACData::RevokeRole(uint32 roleId, int32 realmId /* = 0*/)
+{
+ uint8 revoked = _grantedRoles.erase(roleId) + _deniedRoles.erase(roleId);
+
+ // could remove it?
+ if (!revoked)
+ return RBAC_CANT_REVOKE_NOT_IN_LIST;
+
+ // Do not save to db when loading data from DB (realmId = 0)
+ if (realmId)
+ {
+ PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_RBAC_ACCOUNT_ROLE);
+ stmt->setUInt32(0, GetId());
+ stmt->setUInt32(1, roleId);
+ stmt->setInt32(2, realmId);
+ LoginDatabase.Execute(stmt);
+
+ CalculateNewPermissions();
+ }
+
+ return RBAC_OK;
+}
+
+RBACCommandResult RBACData::GrantPermission(uint32 permissionId, int32 realmId /* = 0*/)
+{
+ // Check if permission Id exists
+ RBACPermission const* perm = sAccountMgr->GetRBACPermission(permissionId);
+ if (!perm)
+ return RBAC_ID_DOES_NOT_EXISTS;
+
+ // Check if already added in denied list
+ if (_deniedPerms.test(permissionId))
+ return RBAC_IN_DENIED_LIST;
+
+ // Already added?
+ if (_grantedPerms.test(permissionId))
+ return RBAC_CANT_ADD_ALREADY_ADDED;
+
+ _grantedPerms.set(permissionId);
+
+ // Do not save to db when loading data from DB (realmId = 0)
+ if (realmId)
+ {
+ SavePermission(permissionId, true, realmId);
+ CalculateNewPermissions();
+ }
+
+ return RBAC_OK;
+}
+
+RBACCommandResult RBACData::DenyPermission(uint32 permissionId, int32 realmId /* = 0*/)
+{
+ // Check if permission Id exists
+ RBACPermission const* perm = sAccountMgr->GetRBACPermission(permissionId);
+ if (!perm)
+ return RBAC_ID_DOES_NOT_EXISTS;
+
+ // Check if already added in granted list
+ if (_grantedPerms.test(permissionId))
+ return RBAC_IN_GRANTED_LIST;
+
+ // Already added?
+ if (_deniedPerms.test(permissionId))
+ return RBAC_CANT_ADD_ALREADY_ADDED;
+
+ _deniedPerms.set(permissionId);
+
+ // Do not save to db when loading data from DB (realmId = 0)
+ if (realmId)
+ {
+ SavePermission(permissionId, false, realmId);
+ CalculateNewPermissions();
+ }
+
+ return RBAC_OK;
+}
+
+void RBACData::SavePermission(uint32 permission, bool granted, int32 realmId)
+{
+ PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_RBAC_ACCOUNT_PERMISSION);
+ stmt->setUInt32(0, GetId());
+ stmt->setUInt32(1, permission);
+ stmt->setBool(2, granted);
+ stmt->setInt32(3, realmId);
+ LoginDatabase.Execute(stmt);
+}
+
+RBACCommandResult RBACData::RevokePermission(uint32 permission, int32 realmId /* = 0*/)
+{
+ // Check if it's present in any list
+ if (!_grantedPerms.test(permission) && !_deniedPerms.test(permission))
+ return RBAC_CANT_REVOKE_NOT_IN_LIST;
+
+ _grantedPerms.reset(permission);
+ _deniedPerms.reset(permission);
+
+ // Do not save to db when loading data from DB (realmId = 0)
+ if (realmId)
+ {
+ PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_RBAC_ACCOUNT_PERMISSION);
+ stmt->setUInt32(0, GetId());
+ stmt->setUInt32(1, permission);
+ stmt->setInt32(2, realmId);
+ LoginDatabase.Execute(stmt);
+
+ CalculateNewPermissions();
+ }
+
+ return RBAC_OK;
+}
+
+void RBACData::LoadFromDB()
+{
+ // Load account group that affect current realm
+ PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_RBAC_ACCOUNT_GROUPS);
+ stmt->setUInt32(0, GetId());
+ stmt->setInt32(1, GetRealmId());
+ PreparedQueryResult result = LoginDatabase.Query(stmt);
+
+ if (result)
+ {
+ do
+ {
+ Field* fields = result->Fetch();
+ AddGroup(fields[0].GetUInt32());
+ }
+ while (result->NextRow());
+ }
+
+ // Load account roles (granted and denied) that affect current realm
+ stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_RBAC_ACCOUNT_ROLES);
+ stmt->setUInt32(0, GetId());
+ stmt->setInt32(1, GetRealmId());
+ result = LoginDatabase.Query(stmt);
+
+ if (result)
+ {
+ do
+ {
+ Field* fields = result->Fetch();
+ if (fields[1].GetBool())
+ GrantRole(fields[0].GetUInt32());
+ else
+ DenyRole(fields[0].GetUInt32());
+ }
+ while (result->NextRow());
+ }
+
+ // Load account permissions (granted and denied) that affect current realm
+ stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_RBAC_ACCOUNT_PERMISSIONS);
+ stmt->setUInt32(0, GetId());
+ stmt->setInt32(1, GetRealmId());
+
+ result = LoginDatabase.Query(stmt);
+ if (result)
+ {
+ do
+ {
+ Field* fields = result->Fetch();
+ if (fields[1].GetBool())
+ GrantPermission(fields[0].GetUInt32());
+ else
+ DenyPermission(fields[0].GetUInt32());
+ }
+ while (result->NextRow());
+ }
+
+ // Force calculation of permissions, it wasn't performed at load time
+ // while adding groups, roles and permissions
+ CalculateNewPermissions();
+}
+
+void RBACData::CalculateNewPermissions()
+{
+ // Get the list of directly granted roles
+ RBACRoleContainer tempGrantedRoles = GetGrantedRoles();
+
+ // Add those roles inherited from groups
+ for (RBACGroupContainer::const_iterator itGroup = _groups.begin(); itGroup != _groups.end(); ++itGroup)
+ {
+ RBACGroup const* group = sAccountMgr->GetRBACGroup(*itGroup);
+ if (!group) // Should never happen due to foreign keys in DB
+ continue;
+
+ RBACRoleContainer const& roles = group->GetRoles();
+ for (RBACRoleContainer::const_iterator it = roles.begin(); it != roles.end(); ++it)
+ tempGrantedRoles.insert(*it);
+ }
+
+ // Get the list of granted permissions
+ _globalPerms = GetGrantedPermissions();
+
+ // Add those permissions inherited from roles granted
+ for (RBACRoleContainer::const_iterator it = tempGrantedRoles.begin(); it != tempGrantedRoles.end(); ++it)
+ if (RBACRole const* role = sAccountMgr->GetRBACRole(*it))
+ _globalPerms |= role->GetPermissions();
+
+ // Remove denied permissions from the list
+ _globalPerms &= ~GetDeniedPermissions();
+
+ // Remove those permissions inherited from denied roles
+ for (RBACRoleContainer::const_iterator it = _deniedRoles.begin(); it != _deniedRoles.end(); ++it)
+ if (RBACRole const* role = sAccountMgr->GetRBACRole(*it))
+ _globalPerms &= ~role->GetPermissions();
+}
diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h new file mode 100644 index 00000000000..5420df29d17 --- /dev/null +++ b/src/server/game/Accounts/RBAC.h @@ -0,0 +1,410 @@ +/*
+ * Copyright (C) 2008-2013 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+* @file RBAC.h
+* @brief Role Based Access Control related classes definition
+*
+* This file contains all the classes and enums used to implement
+* Role Based Access Control
+*
+* RBAC Rules:
+* - Pemission: Defines an autorization to perform certain operation.
+* - Role: Set of permissions.
+* - Group: Set of roles.
+* - An Account can have multiple groups, roles and permissions.
+* - Account Groups can only be granted or revoked
+* - Account Roles and Permissions can be granted, denied or revoked
+* - Grant: Assignment of the object (role/permission) and allow it
+* - Deny: Assignment of the object (role/permission) and deny it
+* - Revoke: Removal of the object (role/permission) no matter if it was granted or denied
+* - Global Permissions are computed as:
+* Group Grants + Role Grants + User Grans - Role Grants - User Grants
+* - Groups, Roles and Permissions can be assigned by realm
+*/
+
+#ifndef _RBAC_H
+#define _RBAC_H
+
+#include "Define.h"
+#include <string>
+#include <bitset>
+#include <set>
+#include <map>
+
+enum RBACPermissions
+{
+ RBAC_PERM_INSTANT_LOGOUT = 1,
+ RBAC_PERM_SKIP_QUEUE,
+ RBAC_PERM_JOIN_NORMAL_BG,
+ RBAC_PERM_JOIN_RANDOM_BG,
+ RBAC_PERM_JOIN_ARENAS,
+ RBAC_PERM_JOIN_DUNGEON_FINDER,
+ RBAC_PERM_PLAYER_COMMANDS,
+ RBAC_PERM_MODERATOR_COMMANDS,
+ RBAC_PERM_GAMEMASTER_COMMANDS,
+ RBAC_PERM_ADMINISTRATOR_COMMANDS,
+ RBAC_PERM_MAX
+};
+
+enum RBACCommandResult
+{
+ RBAC_OK,
+ RBAC_CANT_ADD_ALREADY_ADDED,
+ RBAC_CANT_REVOKE_NOT_IN_LIST,
+ RBAC_IN_GRANTED_LIST,
+ RBAC_IN_DENIED_LIST,
+ RBAC_ID_DOES_NOT_EXISTS
+};
+
+typedef std::bitset<RBAC_PERM_MAX> RBACPermissionContainer;
+typedef std::set<uint32> RBACRoleContainer;
+typedef std::set<uint32> RBACGroupContainer;
+
+class RBACObject
+{
+ public:
+ RBACObject(uint32 id = 0, std::string const& name = ""):
+ _id(id), _name(name) { }
+
+ /// Gets the Name of the Object
+ std::string const& GetName() const { return _name; }
+ /// Gets the Id of the Object
+ uint32 GetId() const { return _id; }
+
+ private:
+ uint32 _id; ///> id of the object
+ std::string _name; ///> name of the object
+};
+
+/// Permission: Defines an autorization to perform certain operation
+class RBACPermission: public RBACObject
+{
+ public:
+ RBACPermission(uint32 id = 0, std::string const& name = ""):
+ RBACObject(id, name) { }
+};
+
+/// Set of Permissions
+class RBACRole: public RBACObject
+{
+ public:
+ RBACRole(uint32 id = 0, std::string const& name = ""):
+ RBACObject(id, name) { }
+
+ /// Gets the Permissions assigned to this role
+ RBACPermissionContainer const& GetPermissions() const { return _perms; }
+ /// Grants a Permission (Adds)
+ void GrantPermission(uint32 id) { _perms.set(id); }
+ /// Revokes a Permission (Removes)
+ void RevokePermission(uint32 id) { _perms.reset(id); }
+
+ private:
+ RBACPermissionContainer _perms; ///> Set of permissions
+};
+
+/// Set of Roles
+class RBACGroup: public RBACObject
+{
+ public:
+ RBACGroup(uint32 id = 0, std::string const& name = ""):
+ RBACObject(id, name) { }
+
+ /// Gets the Roles assigned to this group
+ RBACRoleContainer const& GetRoles() const { return _roles; }
+ /// Grants a Role (Adds)
+ void GrantRole(uint32 role) { _roles.insert(role); }
+ /// Revokes a Role (Removes)
+ void RevokeRole(uint32 role) { _roles.erase(role); }
+
+ private:
+ RBACRoleContainer _roles; ///> Set of Roles
+};
+
+/*
+ * @name RBACData
+ * @brief Contains all needed information about the acccount
+ *
+ * This class contains all the data needed to calculate the account permissions.
+ * RBACDAta is formed by group permissions and user permissions through:
+ * - Granted Groups, which contains roles, which contains permissions: Set of granted permissions
+ * - Granted Roles, which contains permissions: Set of granted permissions
+ * - Denied Roles, which contains permissions: Set of denied permissions
+ * - Granted Permissions
+ * - Denied Permissions
+ *
+ * Calculation of current Permissions: Granted permissions - Denied permissions
+ * - Granted permissions: through groups, through roles and directly assigned
+ * - Denied permissions: through roles and directly assigned
+ */
+class RBACData: public RBACObject
+{
+ public:
+ RBACData(uint32 id, std::string const& name, int32 realmId):
+ RBACObject(id, name), _realmId(realmId) { }
+
+ /**
+ * @name HasPermission
+ * @brief Checks if certain action is allowed
+ *
+ * Checks if certain action can be performed.
+ *
+ * @return grant or deny action
+ *
+ * Example Usage:
+ * @code
+ * bool Player::CanJoinArena(Battleground* bg)
+ * {
+ * return bg->isArena() && HasPermission(RBAC_PERM_JOIN_ARENA);
+ * }
+ * @endcode
+ */
+ bool HasPermission(uint32 permission) { return _globalPerms.test(permission); }
+
+ // Functions enabled to be used by command system
+ /// Returns all the granted permissions (after computation)
+ RBACPermissionContainer const& GetPermissions() const { return _globalPerms; }
+ /// Returns all the granted permissions
+ RBACPermissionContainer const& GetGrantedPermissions() const { return _grantedPerms; }
+ /// Returns all the denied permissions
+ RBACPermissionContainer const& GetDeniedPermissions() const { return _deniedPerms; }
+ /// Returns all the granted roles
+ RBACRoleContainer const& GetGrantedRoles() const { return _grantedRoles; }
+ /// Returns all the denied roles
+ RBACRoleContainer const& GetDeniedRoles() const { return _deniedRoles; }
+ /// Returns all the granted groups
+ RBACGroupContainer const& GetGroups() const { return _groups; }
+
+ /**
+ * @name AddGroup
+ * @brief Adds new group
+ *
+ * Add a new group to the account. If realm is 0 or the group can not be added
+ * No save to db action will be performed.
+ *
+ * Fails if group Id does not exists or group already present
+ *
+ * @param groupId group to be added
+ * @param realmId realm affected
+ *
+ * @return Success or failure (with reason) to add the group
+ *
+ * Example Usage:
+ * @code
+ * // previously defined "RBACData* rbac" with proper initialization
+ * uint32 groupId = 2;
+ * if (rbac->AddGroup(groupId) == RBAC_OK)
+ * sLog->outDebug(LOG_FILTER_PLAYER, "Group %u succesfully added", groupId);
+ * @endcode
+ */
+ RBACCommandResult AddGroup(uint32 groupId, int32 realmId = 0);
+
+ /**
+ * @name RemoveGroup
+ * @brief Removes a group
+ *
+ * Removes a group from the account. If realm is 0 or the group can not be removed
+ * No save to db action will be performed. Any delete operation will always affect
+ * "all realms (-1)" in addition to the realm specified
+ *
+ * Fails if group not present
+ *
+ * @param groupId group to be removed
+ * @param realmId realm affected
+ *
+ * @return Success or failure (with reason) to remove the group
+ *
+ * Example Usage:
+ * // previously defined "RBACData* rbac" with proper initialization
+ * uint32 groupId = 2;
+ * if (rbac->RemoveGroup(groupId) == RBAC_OK)
+ * sLog->outDebug(LOG_FILTER_PLAYER, "Group %u succesfully removed", groupId);
+ * @endcode
+ */
+ RBACCommandResult RemoveGroup(uint32 groupId, int32 realmId = 0);
+
+ /**
+ * @name GrantRole
+ * @brief Grants a role
+ *
+ * Grants a role to the account. If realm is 0 or the role can not be added
+ * No save to db action will be performed.
+ *
+ * Fails if role Id does not exists or role already granted or denied
+ *
+ * @param roleId role to be granted
+ * @param realmId realm affected
+ *
+ * @return Success or failure (with reason) to grant the role
+ *
+ * Example Usage:
+ * // previously defined "RBACData* rbac" with proper initialization
+ * uint32 roleId = 2;
+ * if (rbac->GrantRole(roleId) == RBAC_IN_DENIED_LIST)
+ * sLog->outDebug(LOG_FILTER_PLAYER, "Failed to grant role %u, already denied", roleId);
+ * @endcode
+ */
+ RBACCommandResult GrantRole(uint32 roleId, int32 realmId = 0);
+
+ /**
+ * @name DenyRole
+ * @brief Denies a role
+ *
+ * Denied a role to the account. If realm is 0 or the role can not be added
+ * No save to db action will be performed.
+ *
+ * Fails if role Id does not exists or role already granted or denied
+ *
+ * @param roleId role to be denied
+ * @param realmId realm affected
+ *
+ * @return Success or failure (with reason) to deny the role
+ *
+ * Example Usage:
+ * // previously defined "RBACData* rbac" with proper initialization
+ * uint32 roleId = 2;
+ * if (rbac->DenyRole(roleId) == RBAC_ID_DOES_NOT_EXISTS)
+ * sLog->outDebug(LOG_FILTER_PLAYER, "Role Id %u does not exists", roleId);
+ * @endcode
+ */
+ RBACCommandResult DenyRole(uint32 roleId, int32 realmId = 0);
+
+ /**
+ * @name RevokeRole
+ * @brief Removes a role
+ *
+ * Removes a role from the account. If realm is 0 or the role can not be removed
+ * No save to db action will be performed. Any delete operation will always affect
+ * "all realms (-1)" in addition to the realm specified
+ *
+ * Fails if role not present
+ *
+ * @param roleId role to be removed
+ * @param realmId realm affected
+ *
+ * @return Success or failure (with reason) to remove the role
+ *
+ * Example Usage:
+ * // previously defined "RBACData* rbac" with proper initialization
+ * uint32 roleId = 2;
+ * if (rbac->RevokeRole(roleId) == RBAC_OK)
+ * sLog->outDebug(LOG_FILTER_PLAYER, "Role %u succesfully removed", roleId);
+ * @endcode
+ */
+ RBACCommandResult RevokeRole(uint32 roleId, int32 realmId = 0);
+
+ /**
+ * @name GrantRole
+ * @brief Grants a permission
+ *
+ * Grants a permission to the account. If realm is 0 or the permission can not be added
+ * No save to db action will be performed.
+ *
+ * Fails if permission Id does not exists or permission already granted or denied
+ *
+ * @param permissionId permission to be granted
+ * @param realmId realm affected
+ *
+ * @return Success or failure (with reason) to grant the permission
+ *
+ * Example Usage:
+ * // previously defined "RBACData* rbac" with proper initialization
+ * uint32 permissionId = 2;
+ * if (rbac->GrantRole(permissionId) == RBAC_IN_DENIED_LIST)
+ * sLog->outDebug(LOG_FILTER_PLAYER, "Failed to grant permission %u, already denied", permissionId);
+ * @endcode
+ */
+ RBACCommandResult GrantPermission(uint32 permissionId, int32 realmId = 0);
+
+ /**
+ * @name DenyPermission
+ * @brief Denies a permission
+ *
+ * Denied a permission to the account. If realm is 0 or the permission can not be added
+ * No save to db action will be performed.
+ *
+ * Fails if permission Id does not exists or permission already granted or denied
+ *
+ * @param permissionId permission to be denied
+ * @param realmId realm affected
+ *
+ * @return Success or failure (with reason) to deny the permission
+ *
+ * Example Usage:
+ * // previously defined "RBACData* rbac" with proper initialization
+ * uint32 permissionId = 2;
+ * if (rbac->DenyRole(permissionId) == RBAC_ID_DOES_NOT_EXISTS)
+ * sLog->outDebug(LOG_FILTER_PLAYER, "Role Id %u does not exists", permissionId);
+ * @endcode
+ */
+ RBACCommandResult DenyPermission(uint32 permissionId, int32 realmId = 0);
+
+ /**
+ * @name RevokePermission
+ * @brief Removes a permission
+ *
+ * Removes a permission from the account. If realm is 0 or the permission can not be removed
+ * No save to db action will be performed. Any delete operation will always affect
+ * "all realms (-1)" in addition to the realm specified
+ *
+ * Fails if permission not present
+ *
+ * @param permissionId permission to be removed
+ * @param realmId realm affected
+ *
+ * @return Success or failure (with reason) to remove the permission
+ *
+ * Example Usage:
+ * // previously defined "RBACData* rbac" with proper initialization
+ * uint32 permissionId = 2;
+ * if (rbac->RevokeRole(permissionId) == RBAC_OK)
+ * sLog->outDebug(LOG_FILTER_PLAYER, "Permission %u succesfully removed", permissionId);
+ * @endcode
+ */
+ RBACCommandResult RevokePermission(uint32 permissionId, int32 realmId = 0);
+
+ /// Loads all permissions, groups and roles assigned to current account
+ void LoadFromDB();
+ private:
+ /// Saves a role to DB, Granted or Denied
+ void SaveRole(uint32 role, bool granted, int32 realm);
+ /// Saves a permission to DB, Granted or Denied
+ void SavePermission(uint32 role, bool granted, int32 realm);
+
+ /**
+ * @name CalculateNewPermissions
+ * @brief Calculates new permissions
+ *
+ * Calculates new permissions after some change in groups, roles or permissions.
+ * The calculation is done Granted - Denied:
+ * - Granted permissions: through groups, through roles and directly assigned
+ * - Denied permissions: through roles and directly assigned
+ */
+ void CalculateNewPermissions();
+
+ int32 GetRealmId() { return _realmId; }
+
+ int32 _realmId; ///> RealmId Affected
+ RBACGroupContainer _groups; ///> Granted groups
+ RBACRoleContainer _grantedRoles; ///> Granted roles
+ RBACRoleContainer _deniedRoles; ///> Denied roles
+ RBACPermissionContainer _grantedPerms; ///> Granted permissions
+ RBACPermissionContainer _deniedPerms; ///> Denied permissions
+ RBACPermissionContainer _globalPerms; ///> Calculated permissions
+};
+
+#endif
diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp index 1cbea4df7ed..0befbbfc7fb 100644 --- a/src/server/game/Chat/Chat.cpp +++ b/src/server/game/Chat/Chat.cpp @@ -122,8 +122,27 @@ const char *ChatHandler::GetTrinityString(int32 entry) const bool ChatHandler::isAvailable(ChatCommand const& cmd) const { - // check security level only for simple command (without child commands) - return m_session->GetSecurity() >= AccountTypes(cmd.SecurityLevel); + uint32 permission = 0; + + ///@Workaround:: Fast adaptation to RBAC system till all commands are moved to permissions + switch (AccountTypes(cmd.SecurityLevel)) + { + case SEC_ADMINISTRATOR: + permission = RBAC_PERM_ADMINISTRATOR_COMMANDS; + break; + case SEC_GAMEMASTER: + permission = RBAC_PERM_GAMEMASTER_COMMANDS; + break; + case SEC_MODERATOR: + permission = RBAC_PERM_MODERATOR_COMMANDS; + break; + case SEC_PLAYER: + default: + permission = RBAC_PERM_PLAYER_COMMANDS; + break; + } + + return m_session->HasPermission(permission); } bool ChatHandler::HasLowerSecurity(Player* target, uint64 guid, bool strong) @@ -431,7 +450,7 @@ bool ChatHandler::ParseCommands(char const* text) std::string fullcmd = text; - if (m_session && AccountMgr::IsPlayerAccount(m_session->GetSecurity()) && !sWorld->getBoolConfig(CONFIG_ALLOW_PLAYER_COMMANDS)) + if (m_session && !m_session->HasPermission(RBAC_PERM_PLAYER_COMMANDS)) return false; /// chat case (.command or !command format) diff --git a/src/server/game/DungeonFinding/LFG.cpp b/src/server/game/DungeonFinding/LFG.cpp new file mode 100644 index 00000000000..ce16ad5533e --- /dev/null +++ b/src/server/game/DungeonFinding/LFG.cpp @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2008-2013 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "LFG.h" +#include "Language.h" +#include "ObjectMgr.h" + +namespace lfg +{ + +std::string ConcatenateDungeons(LfgDungeonSet const& dungeons) +{ + std::string dungeonstr = ""; + if (!dungeons.empty()) + { + std::ostringstream o; + LfgDungeonSet::const_iterator it = dungeons.begin(); + o << (*it); + for (++it; it != dungeons.end(); ++it) + o << ", " << uint32(*it); + dungeonstr = o.str(); + } + return dungeonstr; +} + +std::string GetRolesString(uint8 roles) +{ + std::string rolesstr = ""; + + if (roles & PLAYER_ROLE_TANK) + rolesstr.append(sObjectMgr->GetTrinityStringForDBCLocale(LANG_LFG_ROLE_TANK)); + + if (roles & PLAYER_ROLE_HEALER) + { + if (!rolesstr.empty()) + rolesstr.append(", "); + rolesstr.append(sObjectMgr->GetTrinityStringForDBCLocale(LANG_LFG_ROLE_HEALER)); + } + + if (roles & PLAYER_ROLE_DAMAGE) + { + if (!rolesstr.empty()) + rolesstr.append(", "); + rolesstr.append(sObjectMgr->GetTrinityStringForDBCLocale(LANG_LFG_ROLE_DAMAGE)); + } + + if (roles & PLAYER_ROLE_LEADER) + { + if (!rolesstr.empty()) + rolesstr.append(", "); + rolesstr.append(sObjectMgr->GetTrinityStringForDBCLocale(LANG_LFG_ROLE_LEADER)); + } + + if (rolesstr.empty()) + rolesstr.append(sObjectMgr->GetTrinityStringForDBCLocale(LANG_LFG_ROLE_NONE)); + + return rolesstr; +} + +std::string GetStateString(LfgState state) +{ + int32 entry = LANG_LFG_ERROR; + switch (state) + { + case LFG_STATE_NONE: + entry = LANG_LFG_STATE_NONE; + break; + case LFG_STATE_ROLECHECK: + entry = LANG_LFG_STATE_ROLECHECK; + break; + case LFG_STATE_QUEUED: + entry = LANG_LFG_STATE_QUEUED; + break; + case LFG_STATE_PROPOSAL: + entry = LANG_LFG_STATE_PROPOSAL; + break; + case LFG_STATE_DUNGEON: + entry = LANG_LFG_STATE_DUNGEON; + break; + case LFG_STATE_BOOT: + entry = LANG_LFG_STATE_BOOT; + break; + case LFG_STATE_FINISHED_DUNGEON: + entry = LANG_LFG_STATE_FINISHED_DUNGEON; + break; + case LFG_STATE_RAIDBROWSER: + entry = LANG_LFG_STATE_RAIDBROWSER; + break; + } + + return std::string(sObjectMgr->GetTrinityStringForDBCLocale(entry)); +} + +} // namespace lfg diff --git a/src/server/game/DungeonFinding/LFG.h b/src/server/game/DungeonFinding/LFG.h index ebbcfb1d71a..541e4d6bd43 100644 --- a/src/server/game/DungeonFinding/LFG.h +++ b/src/server/game/DungeonFinding/LFG.h @@ -20,6 +20,9 @@ #include "Common.h" +namespace lfg +{ + enum LFGEnum { LFG_TANKS_NEEDED = 1, @@ -99,4 +102,10 @@ typedef std::list<uint64> LfgGuidList; typedef std::map<uint64, uint8> LfgRolesMap; typedef std::map<uint64, uint64> LfgGroupsMap; +std::string ConcatenateDungeons(LfgDungeonSet const& dungeons); +std::string GetRolesString(uint8 roles); +std::string GetStateString(LfgState state); + +} // namespace lfg + #endif diff --git a/src/server/game/DungeonFinding/LFGGroupData.cpp b/src/server/game/DungeonFinding/LFGGroupData.cpp index 427225bf323..f711514e26d 100644 --- a/src/server/game/DungeonFinding/LFGGroupData.cpp +++ b/src/server/game/DungeonFinding/LFGGroupData.cpp @@ -18,6 +18,9 @@ #include "LFG.h" #include "LFGGroupData.h" +namespace lfg +{ + LfgGroupData::LfgGroupData(): m_State(LFG_STATE_NONE), m_OldState(LFG_STATE_NONE), m_Leader(0), m_Dungeon(0), m_KicksLeft(LFG_GROUP_MAX_KICKS) { } @@ -122,3 +125,5 @@ uint8 LfgGroupData::GetKicksLeft() const { return m_KicksLeft; } + +} // namespace lfg diff --git a/src/server/game/DungeonFinding/LFGGroupData.h b/src/server/game/DungeonFinding/LFGGroupData.h index 2ad020d3bc1..47e562c37aa 100644 --- a/src/server/game/DungeonFinding/LFGGroupData.h +++ b/src/server/game/DungeonFinding/LFGGroupData.h @@ -20,6 +20,9 @@ #include "LFG.h" +namespace lfg +{ + enum LfgGroupEnum { LFG_GROUP_MAX_KICKS = 3, @@ -75,4 +78,6 @@ class LfgGroupData uint8 m_KicksLeft; ///< Number of kicks left }; +} // namespace lfg + #endif diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index 0f23925cc2b..9bb65b63557 100644 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -33,6 +33,9 @@ #include "GameEventMgr.h" #include "WorldSession.h" +namespace lfg +{ + LFGMgr::LFGMgr(): m_QueueTimer(0), m_lfgProposalId(1), m_options(sWorld->getIntConfig(CONFIG_LFG_OPTIONSMASK)) { @@ -95,89 +98,6 @@ void LFGMgr::_SaveToDB(uint64 guid, uint32 db_guid) CharacterDatabase.Execute(stmt); } -std::string LFGMgr::ConcatenateDungeons(LfgDungeonSet const& dungeons) -{ - std::string dungeonstr = ""; - if (!dungeons.empty()) - { - std::ostringstream o; - LfgDungeonSet::const_iterator it = dungeons.begin(); - o << (*it); - for (++it; it != dungeons.end(); ++it) - o << ", " << uint32(*it); - dungeonstr = o.str(); - } - return dungeonstr; -} - -std::string LFGMgr::GetRolesString(uint8 roles) -{ - std::string rolesstr = ""; - - if (roles & PLAYER_ROLE_TANK) - rolesstr.append(sObjectMgr->GetTrinityStringForDBCLocale(LANG_LFG_ROLE_TANK)); - - if (roles & PLAYER_ROLE_HEALER) - { - if (!rolesstr.empty()) - rolesstr.append(", "); - rolesstr.append(sObjectMgr->GetTrinityStringForDBCLocale(LANG_LFG_ROLE_HEALER)); - } - - if (roles & PLAYER_ROLE_DAMAGE) - { - if (!rolesstr.empty()) - rolesstr.append(", "); - rolesstr.append(sObjectMgr->GetTrinityStringForDBCLocale(LANG_LFG_ROLE_DAMAGE)); - } - - if (roles & PLAYER_ROLE_LEADER) - { - if (!rolesstr.empty()) - rolesstr.append(", "); - rolesstr.append(sObjectMgr->GetTrinityStringForDBCLocale(LANG_LFG_ROLE_LEADER)); - } - - if (rolesstr.empty()) - rolesstr.append(sObjectMgr->GetTrinityStringForDBCLocale(LANG_LFG_ROLE_NONE)); - - return rolesstr; -} - -std::string LFGMgr::GetStateString(LfgState state) -{ - int32 entry = LANG_LFG_ERROR; - switch (state) - { - case LFG_STATE_NONE: - entry = LANG_LFG_STATE_NONE; - break; - case LFG_STATE_ROLECHECK: - entry = LANG_LFG_STATE_ROLECHECK; - break; - case LFG_STATE_QUEUED: - entry = LANG_LFG_STATE_QUEUED; - break; - case LFG_STATE_PROPOSAL: - entry = LANG_LFG_STATE_PROPOSAL; - break; - case LFG_STATE_DUNGEON: - entry = LANG_LFG_STATE_DUNGEON; - break; - case LFG_STATE_BOOT: - entry = LANG_LFG_STATE_BOOT; - break; - case LFG_STATE_FINISHED_DUNGEON: - entry = LANG_LFG_STATE_FINISHED_DUNGEON; - break; - case LFG_STATE_RAIDBROWSER: - entry = LANG_LFG_STATE_RAIDBROWSER; - break; - } - - return std::string(sObjectMgr->GetTrinityStringForDBCLocale(entry)); -} - /// Load rewards for completing dungeons void LFGMgr::LoadRewards() { @@ -207,7 +127,7 @@ void LFGMgr::LoadRewards() uint32 firstQuestId = fields[2].GetUInt32(); uint32 otherQuestId = fields[3].GetUInt32(); - if (!GetLFGDungeon(dungeonId)) + if (!GetLFGDungeonEntry(dungeonId)) { sLog->outError(LOG_FILTER_SQL, "Dungeon %u specified in table `lfg_dungeon_rewards` does not exist!", dungeonId); continue; @@ -248,11 +168,6 @@ LFGDungeonData const* LFGMgr::GetLFGDungeon(uint32 id) return NULL; } -LFGDungeonContainer & LFGMgr::GetLFGDungeonMap() -{ - return LfgDungeonStore; -} - void LFGMgr::LoadLFGDungeons(bool reload /* = false */) { uint32 oldMSTime = getMSTime(); @@ -464,6 +379,7 @@ void LFGMgr::InitializeLockedDungeons(Player* player, uint8 level /* = 0 */) uint8 expansion = player->GetSession()->Expansion(); LfgDungeonSet const& dungeons = GetDungeonsByRandom(0); LfgLockMap lock; + bool denyJoin = !player->GetSession()->HasPermission(RBAC_PERM_JOIN_DUNGEON_FINDER); for (LfgDungeonSet::const_iterator it = dungeons.begin(); it != dungeons.end(); ++it) { @@ -472,7 +388,9 @@ void LFGMgr::InitializeLockedDungeons(Player* player, uint8 level /* = 0 */) continue; uint32 lockData = 0; - if (dungeon->expansion > expansion) + if (denyJoin) + lockData = LFG_LOCKSTATUS_RAID_LOCKED; + else if (dungeon->expansion > expansion) lockData = LFG_LOCKSTATUS_INSUFFICIENT_EXPANSION; else if (DisableMgr::IsDisabledFor(DISABLE_TYPE_MAP, dungeon->map, player)) lockData = LFG_LOCKSTATUS_RAID_LOCKED; @@ -554,7 +472,9 @@ void LFGMgr::JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons, const } // Check player or group member restrictions - if (player->InBattleground() || player->InArena() || player->InBattlegroundQueue()) + if (!player->GetSession()->HasPermission(RBAC_PERM_JOIN_DUNGEON_FINDER)) + joinData.result = LFG_JOIN_NOT_MEET_REQS; + else if (player->InBattleground() || player->InArena() || player->InBattlegroundQueue()) joinData.result = LFG_JOIN_USING_BG_SYSTEM; else if (player->HasAura(LFG_SPELL_DUNGEON_DESERTER)) joinData.result = LFG_JOIN_DESERTER; @@ -573,6 +493,8 @@ void LFGMgr::JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons, const { if (Player* plrg = itr->getSource()) { + if (!plrg->GetSession()->HasPermission(RBAC_PERM_JOIN_DUNGEON_FINDER)) + joinData.result = LFG_JOIN_PARTY_NOT_MEET_REQS; if (plrg->HasAura(LFG_SPELL_DUNGEON_DESERTER)) joinData.result = LFG_JOIN_PARTY_DESERTER; else if (plrg->HasAura(LFG_SPELL_DUNGEON_COOLDOWN)) @@ -1163,7 +1085,6 @@ void LFGMgr::UpdateProposal(uint32 proposalId, uint64 guid, bool accept) break; } - teleportStore.push_back(pguid); SetState(pguid, LFG_STATE_DUNGEON); } @@ -1398,10 +1319,7 @@ void LFGMgr::TeleportPlayer(Player* player, bool out, bool fromOpcode /*= false* sLog->outDebug(LOG_FILTER_LFG, "TeleportPlayer: Player %s is being teleported out. Current Map %u - Expected Map %u", player->GetName().c_str(), player->GetMapId(), uint32(dungeon->map)); if (player->GetMapId() == uint32(dungeon->map)) - { - player->RemoveAurasDueToSpell(LFG_SPELL_LUCK_OF_THE_DRAW); player->TeleportToBGEntryPoint(); - } return; } @@ -1675,16 +1593,6 @@ const std::string& LFGMgr::GetComment(uint64 guid) return PlayersStore[guid].GetComment(); } -bool LFGMgr::IsTeleported(uint64 pguid) -{ - if (std::find(teleportStore.begin(), teleportStore.end(), pguid) != teleportStore.end()) - { - teleportStore.remove(pguid); - return true; - } - return false; -} - LfgDungeonSet const& LFGMgr::GetSelectedDungeons(uint64 guid) { sLog->outTrace(LOG_FILTER_LFG, "LFGMgr::GetSelectedDungeons: [" UI64FMTD "]", guid); @@ -2039,3 +1947,56 @@ void LFGMgr::SetupGroupMember(uint64 guid, uint64 gguid) SetGroup(guid, gguid); AddPlayerToGroup(gguid, guid); } + +bool LFGMgr::selectedRandomLfgDungeon(uint64 guid) +{ + if (GetState(guid) != LFG_STATE_NONE) + { + LfgDungeonSet const& dungeons = GetSelectedDungeons(guid); + if (!dungeons.empty()) + { + LFGDungeonData const* dungeon = GetLFGDungeon(*dungeons.begin()); + if (dungeon && (dungeon->type == LFG_TYPE_RANDOM || dungeon->seasonal)) + return true; + } + } + + return false; +} + +bool LFGMgr::inLfgDungeonMap(uint64 guid, uint32 map, Difficulty difficulty) +{ + if (!IS_GROUP_GUID(guid)) + guid = GetGroup(guid); + + if (uint32 dungeonId = GetDungeon(guid, true)) + if (LFGDungeonData const* dungeon = GetLFGDungeon(dungeonId)) + if (uint32(dungeon->map) == map && dungeon->difficulty == difficulty) + return true; + + return false; +} + +uint32 LFGMgr::GetLFGDungeonEntry(uint32 id) +{ + if (id) + if (LFGDungeonData const* dungeon = GetLFGDungeon(id)) + return dungeon->Entry(); + + return 0; +} + +LfgDungeonSet LFGMgr::GetRandomAndSeasonalDungeons(uint8 level, uint8 expansion) +{ + LfgDungeonSet randomDungeons; + for (lfg::LFGDungeonContainer::const_iterator itr = LfgDungeonStore.begin(); itr != LfgDungeonStore.end(); ++itr) + { + lfg::LFGDungeonData const& dungeon = itr->second; + if ((dungeon.type == lfg::LFG_TYPE_RANDOM || (dungeon.seasonal && sLFGMgr->IsSeasonActive(dungeon.id))) + && dungeon.expansion <= expansion && dungeon.minlevel <= level && level <= dungeon.maxlevel) + randomDungeons.insert(dungeon.Entry()); + } + return randomDungeons; +} + +} // namespace lfg diff --git a/src/server/game/DungeonFinding/LFGMgr.h b/src/server/game/DungeonFinding/LFGMgr.h index 6f6e770a5bd..0795e6e22d5 100644 --- a/src/server/game/DungeonFinding/LFGMgr.h +++ b/src/server/game/DungeonFinding/LFGMgr.h @@ -30,6 +30,9 @@ class Group; class Player; class Quest; +namespace lfg +{ + enum LfgOptions { LFG_OPTION_ENABLE_DUNGEON_FINDER = 0x01, @@ -296,91 +299,123 @@ class LFGMgr ~LFGMgr(); public: + // Functions used outside lfg namespace void Update(uint32 diff); - // Reward - void LoadRewards(); + // World.cpp + /// Finish the dungeon for the given group. All check are performed using internal lfg data void FinishDungeon(uint64 gguid, uint32 dungeonId); - LfgReward const* GetRandomDungeonReward(uint32 dungeon, uint8 level); - - // Queue - void JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons, std::string const& comment); - void LeaveLfg(uint64 guid); - - // Role Check - void UpdateRoleCheck(uint64 gguid, uint64 guid = 0, uint8 roles = PLAYER_ROLE_NONE); - - // Group Matching - static bool CheckGroupRoles(LfgRolesMap &groles, bool removeLeaderFlag = true); - void GetCompatibleDungeons(LfgDungeonSet& dungeons, LfgGuidSet const& players, LfgLockPartyMap& lockMap); - - // Proposals - uint32 AddProposal(LfgProposal& proposal); - void UpdateProposal(uint32 proposalId, uint64 guid, bool accept); + /// Loads rewards for random dungeons + void LoadRewards(); + /// Loads dungeons from dbc and adds teleport coords + void LoadLFGDungeons(bool reload = false); - // Teleportation - void TeleportPlayer(Player* player, bool out, bool fromOpcode = false); + // Multiple files + /// Check if given guid applied for random dungeon + bool selectedRandomLfgDungeon(uint64 guid); + /// Check if given guid applied for given map and difficulty. Used to know + bool inLfgDungeonMap(uint64 guid, uint32 map, Difficulty difficulty); + /// Get selected dungeons + LfgDungeonSet const& GetSelectedDungeons(uint64 guid); + /// Get current lfg state + LfgState GetState(uint64 guid); + /// Get current dungeon + uint32 GetDungeon(uint64 guid, bool asId = true); + /// Get the map id of the current dungeon + uint32 GetDungeonMapId(uint64 guid); + /// Get kicks left in current group + uint8 GetKicksLeft(uint64 gguid); + /// Load Lfg group info from DB + void _LoadFromDB(Field* fields, uint64 guid); + /// Initializes player data after loading group data from DB + void SetupGroupMember(uint64 guid, uint64 gguid); + /// Return Lfg dungeon entry for given dungeon id + uint32 GetLFGDungeonEntry(uint32 id); - // Vote kick - void InitBoot(uint64 gguid, uint64 kguid, uint64 vguid, std::string const& reason); - void UpdateBoot(uint64 guid, bool accept); + // cs_lfg + /// Get current player roles + uint8 GetRoles(uint64 guid); + /// Get current player comment (used for LFR) + std::string const& GetComment(uint64 gguid); + /// Gets current lfg options + uint32 GetOptions(); + /// Sets new lfg options + void SetOptions(uint32 options); + /// Checks if given lfg option is enabled + bool isOptionEnabled(uint32 option); + /// Clears queue - Only for internal testing + void Clean(); + /// Dumps the state of the queue - Only for internal testing + std::string DumpQueueInfo(bool full = false); + // LFGScripts + /// Get leader of the group (using internal data) + uint64 GetLeader(uint64 guid); + /// Initializes locked dungeons for given player (called at login or level change) void InitializeLockedDungeons(Player* player, uint8 level = 0); - - void SetRoles(uint64 guid, uint8 roles); - void SetComment(uint64 guid, std::string const& comment); + /// Sets player team void SetTeam(uint64 guid, uint8 team); + /// Sets player group void SetGroup(uint64 guid, uint64 group); + /// Gets player group + uint64 GetGroup(uint64 guid); + /// Sets the leader of the group void SetLeader(uint64 gguid, uint64 leader); - void SetState(uint64 guid, LfgState state); - - void _LoadFromDB(Field* fields, uint64 guid); - void _SaveToDB(uint64 guid, uint32 db_guid); - - void RemovePlayerData(uint64 guid); + /// Removes saved group data void RemoveGroupData(uint64 guid); + /// Removes a player from a group uint8 RemovePlayerFromGroup(uint64 gguid, uint64 guid); + /// Adds player to group void AddPlayerToGroup(uint64 gguid, uint64 guid); + // LFGHandler + /// Get locked dungeons LfgLockMap const& GetLockedDungeons(uint64 guid); - LfgDungeonSet const& GetSelectedDungeons(uint64 guid); - uint32 GetDungeon(uint64 guid, bool asId = true); - uint32 GetDungeonMapId(uint64 guid); - LfgState GetState(uint64 guid); + /// Returns current lfg status + LfgUpdateData GetLfgStatus(uint64 guid); + /// Checks if Seasonal dungeon is active + bool IsSeasonActive(uint32 dungeonId); + /// Gets the random dungeon reward corresponding to given dungeon and player level + LfgReward const* GetRandomDungeonReward(uint32 dungeon, uint8 level); + /// Returns all random and seasonal dungeons for given level and expansion + LfgDungeonSet GetRandomAndSeasonalDungeons(uint8 level, uint8 expansion); + /// Teleport a player to/from selected dungeon + void TeleportPlayer(Player* player, bool out, bool fromOpcode = false); + /// Inits new proposal to boot a player + void InitBoot(uint64 gguid, uint64 kguid, uint64 vguid, std::string const& reason); + /// Updates player boot proposal with new player answer + void UpdateBoot(uint64 guid, bool accept); + /// Updates proposal to join dungeon with player answer + void UpdateProposal(uint32 proposalId, uint64 guid, bool accept); + /// Updates the role check with player answer + void UpdateRoleCheck(uint64 gguid, uint64 guid = 0, uint8 roles = PLAYER_ROLE_NONE); + /// Sets player lfg roles + void SetRoles(uint64 guid, uint8 roles); + /// Sets player lfr comment + void SetComment(uint64 guid, std::string const& comment); + /// Join Lfg with selected roles, dungeons and comment + void JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons, std::string const& comment); + /// Leaves lfg + void LeaveLfg(uint64 guid); + + // LfgQueue + /// Get last lfg state (NONE, DUNGEON or FINISHED_DUNGEON) LfgState GetOldState(uint64 guid); - uint8 GetKicksLeft(uint64 gguid); - uint64 GetLeader(uint64 guid); + /// Check if given group guid is lfg bool IsLfgGroup(uint64 guid); - uint8 GetRoles(uint64 guid); - std::string const& GetComment(uint64 gguid); - LfgGuidSet const& GetPlayers(uint64 guid); + /// Gets the player count of given group uint8 GetPlayerCount(uint64 guid); - - bool IsTeleported(uint64 guid); - + /// Add a new Proposal + uint32 AddProposal(LfgProposal& proposal); + /// Checks if all players are queued bool AllQueued(LfgGuidList const& check); - void Clean(); - + /// Checks if given roles match, modifies given roles map with new roles + static bool CheckGroupRoles(LfgRolesMap &groles, bool removeLeaderFlag = true); + /// Checks if given players are ignoring each other static bool HasIgnore(uint64 guid1, uint64 guid2); + /// Sends queue status to player static void SendLfgQueueStatus(uint64 guid, LfgQueueStatusData const& data); - bool isOptionEnabled(uint32 option); - uint32 GetOptions(); - void SetOptions(uint32 options); - LfgUpdateData GetLfgStatus(uint64 guid); - bool IsSeasonActive(uint32 dungeonId); - - std::string DumpQueueInfo(bool full = false); - static std::string ConcatenateDungeons(LfgDungeonSet const& dungeons); - static std::string GetRolesString(uint8 roles); - static std::string GetStateString(LfgState state); - - void LoadLFGDungeons(bool reload = false); - LFGDungeonData const* GetLFGDungeon(uint32 id); - LFGDungeonContainer& GetLFGDungeonMap(); - void SetupGroupMember(uint64 guid, uint64 gguid); - uint64 GetGroup(uint64 guid); - private: uint8 GetTeam(uint64 guid); void RestoreState(uint64 guid, char const* debugMsg); @@ -389,6 +424,11 @@ class LFGMgr void SetSelectedDungeons(uint64 guid, LfgDungeonSet const& dungeons); void SetLockedDungeons(uint64 guid, LfgLockMap const& lock); void DecreaseKicksLeft(uint64 guid); + void SetState(uint64 guid, LfgState state); + void RemovePlayerData(uint64 guid); + void GetCompatibleDungeons(LfgDungeonSet& dungeons, LfgGuidSet const& players, LfgLockPartyMap& lockMap); + void _SaveToDB(uint64 guid, uint32 db_guid); + LFGDungeonData const* GetLFGDungeon(uint32 id); // Proposals void RemoveProposal(LfgProposalContainer::iterator itProposal, LfgUpdateType type); @@ -407,6 +447,8 @@ class LFGMgr void SendLfgUpdatePlayer(uint64 guid, LfgUpdateData const& data); void SendLfgUpdateProposal(uint64 guid, LfgProposal const& proposal); + LfgGuidSet const& GetPlayers(uint64 guid); + // General variables uint32 m_QueueTimer; ///< used to check interval of update uint32 m_lfgProposalId; ///< used as internal counter for proposals @@ -423,8 +465,9 @@ class LFGMgr LfgPlayerBootContainer BootsStore; ///< Current player kicks LfgPlayerDataContainer PlayersStore; ///< Player data LfgGroupDataContainer GroupsStore; ///< Group data - LfgGuidList teleportStore; ///< Players being teleported }; -#define sLFGMgr ACE_Singleton<LFGMgr, ACE_Null_Mutex>::instance() +} // namespace lfg + +#define sLFGMgr ACE_Singleton<lfg::LFGMgr, ACE_Null_Mutex>::instance() #endif diff --git a/src/server/game/DungeonFinding/LFGPlayerData.cpp b/src/server/game/DungeonFinding/LFGPlayerData.cpp index 410076f7e75..e8ef430bc1f 100644 --- a/src/server/game/DungeonFinding/LFGPlayerData.cpp +++ b/src/server/game/DungeonFinding/LFGPlayerData.cpp @@ -17,6 +17,9 @@ #include "LFGPlayerData.h" +namespace lfg +{ + LfgPlayerData::LfgPlayerData(): m_State(LFG_STATE_NONE), m_OldState(LFG_STATE_NONE), m_Team(0), m_Group(0), m_Roles(0), m_Comment("") {} @@ -122,3 +125,5 @@ LfgDungeonSet const& LfgPlayerData::GetSelectedDungeons() const { return m_SelectedDungeons; } + +} // namespace lfg diff --git a/src/server/game/DungeonFinding/LFGPlayerData.h b/src/server/game/DungeonFinding/LFGPlayerData.h index 055924fd364..a425ce77bad 100644 --- a/src/server/game/DungeonFinding/LFGPlayerData.h +++ b/src/server/game/DungeonFinding/LFGPlayerData.h @@ -20,6 +20,9 @@ #include "LFG.h" +namespace lfg +{ + /** Stores all lfg data needed about the player. */ @@ -68,4 +71,6 @@ class LfgPlayerData LfgDungeonSet m_SelectedDungeons; ///< Selected Dungeons when joined LFG }; +} // namespace lfg + #endif diff --git a/src/server/game/DungeonFinding/LFGQueue.cpp b/src/server/game/DungeonFinding/LFGQueue.cpp index f1d2dbb313d..6a98fccecdc 100644 --- a/src/server/game/DungeonFinding/LFGQueue.cpp +++ b/src/server/game/DungeonFinding/LFGQueue.cpp @@ -27,6 +27,9 @@ #include "World.h" #include "GroupMgr.h" +namespace lfg +{ + /** Given a list of guids returns the concatenation using | as delimiter @@ -431,7 +434,7 @@ LfgCompatibility LFGQueue::CheckCompatibility(LfgGuidList check) { std::ostringstream o; for (LfgRolesMap::const_iterator it = debugRoles.begin(); it != debugRoles.end(); ++it) - o << ", " << it->first << ": " << sLFGMgr->GetRolesString(it->second); + o << ", " << it->first << ": " << GetRolesString(it->second); sLog->outDebug(LOG_FILTER_LFG, "LFGQueue::CheckCompatibility: (%s) Roles not compatible%s", strGuids.c_str(), o.str().c_str()); SetCompatibles(strGuids, LFG_INCOMPATIBLES_NO_ROLES); @@ -441,12 +444,12 @@ LfgCompatibility LFGQueue::CheckCompatibility(LfgGuidList check) LfgGuidList::iterator itguid = check.begin(); proposalDungeons = QueueDataStore[*itguid].dungeons; std::ostringstream o; - o << ", " << *itguid << ": (" << sLFGMgr->ConcatenateDungeons(proposalDungeons) << ")"; + o << ", " << *itguid << ": (" << ConcatenateDungeons(proposalDungeons) << ")"; for (++itguid; itguid != check.end(); ++itguid) { LfgDungeonSet temporal; LfgDungeonSet &dungeons = QueueDataStore[*itguid].dungeons; - o << ", " << *itguid << ": (" << sLFGMgr->ConcatenateDungeons(dungeons) << ")"; + o << ", " << *itguid << ": (" << ConcatenateDungeons(dungeons) << ")"; std::set_intersection(proposalDungeons.begin(), proposalDungeons.end(), dungeons.begin(), dungeons.end(), std::inserter(temporal, temporal.begin())); proposalDungeons = temporal; } @@ -671,3 +674,5 @@ void LFGQueue::UpdateBestCompatibleInQueue(LfgQueueDataContainer::iterator itrQu --queueData.dps; } } + +} // namespace lfg diff --git a/src/server/game/DungeonFinding/LFGQueue.h b/src/server/game/DungeonFinding/LFGQueue.h index acb78d2c0f2..db7e7bbf318 100644 --- a/src/server/game/DungeonFinding/LFGQueue.h +++ b/src/server/game/DungeonFinding/LFGQueue.h @@ -20,6 +20,9 @@ #include "LFG.h" +namespace lfg +{ + enum LfgCompatibility { LFG_COMPATIBILITY_PENDING, @@ -140,4 +143,6 @@ class LFGQueue LfgGuidList newToQueueStore; ///< New groups to add to queue }; +} // namespace lfg + #endif diff --git a/src/server/game/DungeonFinding/LFGScripts.cpp b/src/server/game/DungeonFinding/LFGScripts.cpp index 568b61eef2f..a4716de9524 100644 --- a/src/server/game/DungeonFinding/LFGScripts.cpp +++ b/src/server/game/DungeonFinding/LFGScripts.cpp @@ -29,6 +29,9 @@ #include "ObjectAccessor.h" #include "WorldSession.h" +namespace lfg +{ + LFGPlayerScript::LFGPlayerScript() : PlayerScript("LFGPlayerScript") { } @@ -85,6 +88,24 @@ void LFGPlayerScript::OnBindToInstance(Player* player, Difficulty difficulty, ui sLFGMgr->InitializeLockedDungeons(player); } +void LFGPlayerScript::OnMapChanged(Player* player) +{ + Map const* map = player->GetMap(); + + if (sLFGMgr->inLfgDungeonMap(player->GetGUID(), map->GetId(), map->GetDifficulty())) + { + Group* group = player->GetGroup(); + for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) + if (Player* member = itr->getSource()) + player->GetSession()->SendNameQueryOpcode(member->GetGUID()); + + if (sLFGMgr->selectedRandomLfgDungeon(player->GetGUID())) + player->CastSpell(player, LFG_SPELL_LUCK_OF_THE_DRAW, true); + } + else + player->RemoveAurasDueToSpell(LFG_SPELL_LUCK_OF_THE_DRAW); +} + LFGGroupScript::LFGGroupScript() : GroupScript("LFGGroupScript") { } @@ -208,3 +229,5 @@ void LFGGroupScript::OnInviteMember(Group* group, uint64 guid) if (leader && !gguid) sLFGMgr->LeaveLfg(leader); } + +} // namespace lfg diff --git a/src/server/game/DungeonFinding/LFGScripts.h b/src/server/game/DungeonFinding/LFGScripts.h index 227543e1899..bb1900cad93 100644 --- a/src/server/game/DungeonFinding/LFGScripts.h +++ b/src/server/game/DungeonFinding/LFGScripts.h @@ -26,6 +26,9 @@ class Player; class Group; +namespace lfg +{ + class LFGPlayerScript : public PlayerScript { public: @@ -36,6 +39,7 @@ class LFGPlayerScript : public PlayerScript void OnLogout(Player* player); void OnLogin(Player* player); void OnBindToInstance(Player* player, Difficulty difficulty, uint32 mapId, bool permanent); + void OnMapChanged(Player* player); }; class LFGGroupScript : public GroupScript @@ -50,3 +54,5 @@ class LFGGroupScript : public GroupScript void OnChangeLeader(Group* group, uint64 newLeaderGuid, uint64 oldLeaderGuid); void OnInviteMember(Group* group, uint64 guid); }; + +} // namespace lfg diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 93ae1fbd963..fdcfee354e2 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -7735,13 +7735,7 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea) // group update if (Group* group = GetGroup()) - { SetGroupUpdateFlag(GROUP_UPDATE_FULL); - if (GetSession() && group->isLFGGroup() && sLFGMgr->IsTeleported(GetGUID())) - for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) - if (Player* member = itr->getSource()) - GetSession()->SendNameQueryOpcode(member->GetGUID()); - } m_zoneUpdateId = newZone; m_zoneUpdateTimer = ZONE_UPDATE_INTERVAL; @@ -11769,22 +11763,12 @@ InventoryResult Player::CanUseItem(ItemTemplate const* proto) const InventoryResult Player::CanRollForItemInLFG(ItemTemplate const* proto, WorldObject const* lootedObject) const { - LfgDungeonSet const& dungeons = sLFGMgr->GetSelectedDungeons(GetGUID()); - if (dungeons.empty()) - return EQUIP_ERR_OK; // not using LFG - if (!GetGroup() || !GetGroup()->isLFGGroup()) return EQUIP_ERR_OK; // not in LFG group // check if looted object is inside the lfg dungeon - bool lootedObjectInDungeon = false; Map const* map = lootedObject->GetMap(); - if (uint32 dungeonId = sLFGMgr->GetDungeon(GetGroup()->GetGUID(), true)) - if (LFGDungeonData const* dungeon = sLFGMgr->GetLFGDungeon(dungeonId)) - if (uint32(dungeon->map) == map->GetId() && dungeon->difficulty == map->GetDifficulty()) - lootedObjectInDungeon = true; - - if (!lootedObjectInDungeon) + if (!sLFGMgr->inLfgDungeonMap(GetGroup()->GetGUID(), map->GetId(), map->GetDifficulty())) return EQUIP_ERR_OK; if (!proto) @@ -22167,12 +22151,21 @@ void Player::LeaveBattleground(bool teleportToEntryPoint) } } -bool Player::CanJoinToBattleground(Battleground const* /*bg*/) const +bool Player::CanJoinToBattleground(Battleground const* bg) const { // check Deserter debuff if (HasAura(26013)) return false; + if (bg->isArena() && !GetSession()->HasPermission(RBAC_PERM_JOIN_ARENAS)) + return false; + + if (bg->IsRandom() && !GetSession()->HasPermission(RBAC_PERM_JOIN_RANDOM_BG)) + return false; + + if (!GetSession()->HasPermission(RBAC_PERM_JOIN_NORMAL_BG)) + return false; + return true; } @@ -23839,14 +23832,14 @@ PartyResult Player::CanUninviteFromGroup() const if (!sLFGMgr->GetKicksLeft(gguid)) return ERR_PARTY_LFG_BOOT_LIMIT; - LfgState state = sLFGMgr->GetState(gguid); - if (state == LFG_STATE_BOOT) + lfg::LfgState state = sLFGMgr->GetState(gguid); + if (state == lfg::LFG_STATE_BOOT) return ERR_PARTY_LFG_BOOT_IN_PROGRESS; - if (grp->GetMembersCount() <= LFG_GROUP_KICK_VOTES_NEEDED) + if (grp->GetMembersCount() <= lfg::LFG_GROUP_KICK_VOTES_NEEDED) return ERR_PARTY_LFG_BOOT_TOO_FEW_PLAYERS; - if (state == LFG_STATE_FINISHED_DUNGEON) + if (state == lfg::LFG_STATE_FINISHED_DUNGEON) return ERR_PARTY_LFG_BOOT_DUNGEON_COMPLETE; if (grp->isRollLootActive()) @@ -23876,21 +23869,17 @@ PartyResult Player::CanUninviteFromGroup() const bool Player::isUsingLfg() { - return sLFGMgr->GetState(GetGUID()) != LFG_STATE_NONE; + return sLFGMgr->GetState(GetGUID()) != lfg::LFG_STATE_NONE; } bool Player::inRandomLfgDungeon() { - if (isUsingLfg()) + if (sLFGMgr->selectedRandomLfgDungeon(GetGUID())) { - const LfgDungeonSet& dungeons = sLFGMgr->GetSelectedDungeons(GetGUID()); - if (!dungeons.empty()) - { - LFGDungeonData const* dungeon = sLFGMgr->GetLFGDungeon(*dungeons.begin()); - if (dungeon && (dungeon->type == LFG_TYPE_RANDOM || dungeon->seasonal)) - return true; - } + Map const* map = GetMap(); + return sLFGMgr->inLfgDungeonMap(GetGUID(), map->GetId(), map->GetDifficulty()); } + return false; } diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index acbdfa6a4a2..640eef5d651 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -4945,7 +4945,7 @@ void ObjectMgr::LoadInstanceEncounters() continue; } - if (lastEncounterDungeon && !sLFGMgr->GetLFGDungeon(lastEncounterDungeon)) + if (lastEncounterDungeon && !sLFGMgr->GetLFGDungeonEntry(lastEncounterDungeon)) { sLog->outError(LOG_FILTER_SQL, "Table `instance_encounters` has an encounter %u (%s) marked as final for invalid dungeon id %u, skipped!", entry, dungeonEncounter->encounterName, lastEncounterDungeon); continue; diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index acc15efcbed..031a8ee96e7 100644 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -1529,7 +1529,7 @@ void Group::SendUpdateToPlayer(uint64 playerGUID, MemberSlot* slot) data << uint8(slot->roles); if (isLFGGroup()) { - data << uint8(sLFGMgr->GetState(m_guid) == LFG_STATE_FINISHED_DUNGEON ? 2 : 0); // FIXME - Dungeon save status? 2 = done + data << uint8(sLFGMgr->GetState(m_guid) == lfg::LFG_STATE_FINISHED_DUNGEON ? 2 : 0); // FIXME - Dungeon save status? 2 = done data << uint32(sLFGMgr->GetDungeon(m_guid)); data << uint8(0); // 4.x new } diff --git a/src/server/game/Handlers/LFGHandler.cpp b/src/server/game/Handlers/LFGHandler.cpp index 07ade9456b1..c2ff0d4b8e0 100644 --- a/src/server/game/Handlers/LFGHandler.cpp +++ b/src/server/game/Handlers/LFGHandler.cpp @@ -23,10 +23,10 @@ #include "WorldPacket.h" #include "WorldSession.h" -void BuildPlayerLockDungeonBlock(WorldPacket& data, LfgLockMap const& lock) +void BuildPlayerLockDungeonBlock(WorldPacket& data, lfg::LfgLockMap const& lock) { data << uint32(lock.size()); // Size of lock dungeons - for (LfgLockMap::const_iterator it = lock.begin(); it != lock.end(); ++it) + for (lfg::LfgLockMap::const_iterator it = lock.begin(); it != lock.end(); ++it) { data << uint32(it->first); // Dungeon entry (id + type) data << uint32(it->second); // Lock status @@ -35,10 +35,10 @@ void BuildPlayerLockDungeonBlock(WorldPacket& data, LfgLockMap const& lock) } } -void BuildPartyLockDungeonBlock(WorldPacket& data, const LfgLockPartyMap& lockMap) +void BuildPartyLockDungeonBlock(WorldPacket& data, lfg::LfgLockPartyMap const& lockMap) { data << uint8(lockMap.size()); - for (LfgLockPartyMap::const_iterator it = lockMap.begin(); it != lockMap.end(); ++it) + for (lfg::LfgLockPartyMap::const_iterator it = lockMap.begin(); it != lockMap.end(); ++it) { data << uint64(it->first); // Player guid BuildPlayerLockDungeonBlock(data, it->second); @@ -47,7 +47,7 @@ void BuildPartyLockDungeonBlock(WorldPacket& data, const LfgLockPartyMap& lockMa void WorldSession::HandleLfgJoinOpcode(WorldPacket& recvData) { - if (!sLFGMgr->isOptionEnabled(LFG_OPTION_ENABLE_DUNGEON_FINDER | LFG_OPTION_ENABLE_RAID_BROWSER) || + if (!sLFGMgr->isOptionEnabled(lfg::LFG_OPTION_ENABLE_DUNGEON_FINDER | lfg::LFG_OPTION_ENABLE_RAID_BROWSER) || (GetPlayer()->GetGroup() && GetPlayer()->GetGroup()->GetLeaderGUID() != GetPlayer()->GetGUID() && (GetPlayer()->GetGroup()->GetMembersCount() == MAXGROUPSIZE || !GetPlayer()->GetGroup()->isLFGGroup()))) { @@ -68,7 +68,7 @@ void WorldSession::HandleLfgJoinOpcode(WorldPacket& recvData) return; } - LfgDungeonSet newDungeons; + lfg::LfgDungeonSet newDungeons; for (int8 i = 0; i < numDungeons; ++i) { uint32 dungeon; @@ -169,21 +169,12 @@ void WorldSession::HandleLfgPlayerLockInfoRequestOpcode(WorldPacket& /*recvData* GetPlayerInfo().c_str()); // Get Random dungeons that can be done at a certain level and expansion - LfgDungeonSet randomDungeons; uint8 level = GetPlayer()->getLevel(); - uint8 expansion = GetPlayer()->GetSession()->Expansion(); - - LFGDungeonContainer& LfgDungeons = sLFGMgr->GetLFGDungeonMap(); - for (LFGDungeonContainer::const_iterator itr = LfgDungeons.begin(); itr != LfgDungeons.end(); ++itr) - { - LFGDungeonData const& dungeon = itr->second; - if ((dungeon.type == LFG_TYPE_RANDOM || (dungeon.seasonal && sLFGMgr->IsSeasonActive(dungeon.id))) - && dungeon.expansion <= expansion && dungeon.minlevel <= level && level <= dungeon.maxlevel) - randomDungeons.insert(dungeon.Entry()); - } + lfg::LfgDungeonSet const& randomDungeons = + sLFGMgr->GetRandomAndSeasonalDungeons(level, GetPlayer()->GetSession()->Expansion()); // Get player locked Dungeons - LfgLockMap const& lock = sLFGMgr->GetLockedDungeons(guid); + lfg::LfgLockMap const& lock = sLFGMgr->GetLockedDungeons(guid); uint32 rsize = uint32(randomDungeons.size()); uint32 lsize = uint32(lock.size()); @@ -191,10 +182,10 @@ void WorldSession::HandleLfgPlayerLockInfoRequestOpcode(WorldPacket& /*recvData* WorldPacket data(SMSG_LFG_PLAYER_INFO, 1 + rsize * (4 + 1 + 4 + 4 + 4 + 4 + 1 + 4 + 4 + 4) + 4 + lsize * (1 + 4 + 4 + 4 + 4 + 1 + 4 + 4 + 4)); data << uint8(randomDungeons.size()); // Random Dungeon count - for (LfgDungeonSet::const_iterator it = randomDungeons.begin(); it != randomDungeons.end(); ++it) + for (lfg::LfgDungeonSet::const_iterator it = randomDungeons.begin(); it != randomDungeons.end(); ++it) { data << uint32(*it); // Dungeon Entry (id + type) - LfgReward const* reward = sLFGMgr->GetRandomDungeonReward(*it, level); + lfg::LfgReward const* reward = sLFGMgr->GetRandomDungeonReward(*it, level); Quest const* quest = NULL; bool done = false; if (reward) @@ -252,7 +243,7 @@ void WorldSession::HandleLfgPartyLockInfoRequestOpcode(WorldPacket& /*recvData* return; // Get the locked dungeons of the other party members - LfgLockPartyMap lockMap; + lfg::LfgLockPartyMap lockMap; for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* plrg = itr->getSource(); @@ -267,7 +258,7 @@ void WorldSession::HandleLfgPartyLockInfoRequestOpcode(WorldPacket& /*recvData* } uint32 size = 0; - for (LfgLockPartyMap::const_iterator it = lockMap.begin(); it != lockMap.end(); ++it) + for (lfg::LfgLockPartyMap::const_iterator it = lockMap.begin(); it != lockMap.end(); ++it) size += 8 + 4 + uint32(it->second.size()) * (4 + 4 + 4 + 4); sLog->outDebug(LOG_FILTER_LFG, "SMSG_LFG_PARTY_INFO %s", GetPlayerInfo().c_str()); @@ -299,7 +290,7 @@ void WorldSession::HandleLfgGetStatus(WorldPacket& /*recvData*/) sLog->outDebug(LOG_FILTER_LFG, "CMSG_LFG_GET_STATUS %s", GetPlayerInfo().c_str()); uint64 guid = GetPlayer()->GetGUID(); - LfgUpdateData updateData = sLFGMgr->GetLfgStatus(guid); + lfg::LfgUpdateData updateData = sLFGMgr->GetLfgStatus(guid); if (GetPlayer()->GetGroup()) { @@ -315,19 +306,19 @@ void WorldSession::HandleLfgGetStatus(WorldPacket& /*recvData*/) } } -void WorldSession::SendLfgUpdatePlayer(LfgUpdateData const& updateData) +void WorldSession::SendLfgUpdatePlayer(lfg::LfgUpdateData const& updateData) { bool queued = false; uint8 size = uint8(updateData.dungeons.size()); switch (updateData.updateType) { - case LFG_UPDATETYPE_JOIN_QUEUE: - case LFG_UPDATETYPE_ADDED_TO_QUEUE: + case lfg::LFG_UPDATETYPE_JOIN_QUEUE: + case lfg::LFG_UPDATETYPE_ADDED_TO_QUEUE: queued = true; break; - case LFG_UPDATETYPE_UPDATE_STATUS: - queued = updateData.state == LFG_STATE_QUEUED; + case lfg::LFG_UPDATETYPE_UPDATE_STATUS: + queued = updateData.state == lfg::LFG_STATE_QUEUED; break; default: break; @@ -345,14 +336,14 @@ void WorldSession::SendLfgUpdatePlayer(LfgUpdateData const& updateData) data << uint8(0); // unk - Always 0 data << uint8(size); - for (LfgDungeonSet::const_iterator it = updateData.dungeons.begin(); it != updateData.dungeons.end(); ++it) + for (lfg::LfgDungeonSet::const_iterator it = updateData.dungeons.begin(); it != updateData.dungeons.end(); ++it) data << uint32(*it); data << updateData.comment; } SendPacket(&data); } -void WorldSession::SendLfgUpdateParty(const LfgUpdateData& updateData) +void WorldSession::SendLfgUpdateParty(const lfg::LfgUpdateData& updateData) { bool join = false; bool queued = false; @@ -360,15 +351,15 @@ void WorldSession::SendLfgUpdateParty(const LfgUpdateData& updateData) switch (updateData.updateType) { - case LFG_UPDATETYPE_ADDED_TO_QUEUE: // Rolecheck Success + case lfg::LFG_UPDATETYPE_ADDED_TO_QUEUE: // Rolecheck Success queued = true; // no break on purpose - case LFG_UPDATETYPE_PROPOSAL_BEGIN: + case lfg::LFG_UPDATETYPE_PROPOSAL_BEGIN: join = true; break; - case LFG_UPDATETYPE_UPDATE_STATUS: - join = updateData.state != LFG_STATE_ROLECHECK && updateData.state != LFG_STATE_NONE; - queued = updateData.state == LFG_STATE_QUEUED; + case lfg::LFG_UPDATETYPE_UPDATE_STATUS: + join = updateData.state != lfg::LFG_STATE_ROLECHECK && updateData.state != lfg::LFG_STATE_NONE; + queued = updateData.state == lfg::LFG_STATE_QUEUED; break; default: break; @@ -389,7 +380,7 @@ void WorldSession::SendLfgUpdateParty(const LfgUpdateData& updateData) data << uint8(0); // unk - Always 0 data << uint8(size); - for (LfgDungeonSet::const_iterator it = updateData.dungeons.begin(); it != updateData.dungeons.end(); ++it) + for (lfg::LfgDungeonSet::const_iterator it = updateData.dungeons.begin(); it != updateData.dungeons.end(); ++it) data << uint32(*it); data << updateData.comment; } @@ -408,9 +399,9 @@ void WorldSession::SendLfgRoleChosen(uint64 guid, uint8 roles) SendPacket(&data); } -void WorldSession::SendLfgRoleCheckUpdate(const LfgRoleCheck& roleCheck) +void WorldSession::SendLfgRoleCheckUpdate(lfg::LfgRoleCheck const& roleCheck) { - LfgDungeonSet dungeons; + lfg::LfgDungeonSet dungeons; if (roleCheck.rDungeonId) dungeons.insert(roleCheck.rDungeonId); else @@ -420,16 +411,11 @@ void WorldSession::SendLfgRoleCheckUpdate(const LfgRoleCheck& roleCheck) WorldPacket data(SMSG_LFG_ROLE_CHECK_UPDATE, 4 + 1 + 1 + dungeons.size() * 4 + 1 + roleCheck.roles.size() * (8 + 1 + 4 + 1)); data << uint32(roleCheck.state); // Check result - data << uint8(roleCheck.state == LFG_ROLECHECK_INITIALITING); + data << uint8(roleCheck.state == lfg::LFG_ROLECHECK_INITIALITING); data << uint8(dungeons.size()); // Number of dungeons if (!dungeons.empty()) - { - for (LfgDungeonSet::iterator it = dungeons.begin(); it != dungeons.end(); ++it) - { - LFGDungeonData const* dungeon = sLFGMgr->GetLFGDungeon(*it); - data << uint32(dungeon ? dungeon->Entry() : 0); // Dungeon - } - } + for (lfg::LfgDungeonSet::iterator it = dungeons.begin(); it != dungeons.end(); ++it) + data << uint32(sLFGMgr->GetLFGDungeonEntry(*it)); // Dungeon data << uint8(roleCheck.roles.size()); // Players in group if (!roleCheck.roles.empty()) @@ -443,7 +429,7 @@ void WorldSession::SendLfgRoleCheckUpdate(const LfgRoleCheck& roleCheck) Player* player = ObjectAccessor::FindPlayer(guid); data << uint8(player ? player->getLevel() : 0); // Level - for (LfgRolesMap::const_iterator it = roleCheck.roles.begin(); it != roleCheck.roles.end(); ++it) + for (lfg::LfgRolesMap::const_iterator it = roleCheck.roles.begin(); it != roleCheck.roles.end(); ++it) { if (it->first == roleCheck.leader) continue; @@ -460,10 +446,10 @@ void WorldSession::SendLfgRoleCheckUpdate(const LfgRoleCheck& roleCheck) SendPacket(&data); } -void WorldSession::SendLfgJoinResult(LfgJoinResultData const& joinData) +void WorldSession::SendLfgJoinResult(lfg::LfgJoinResultData const& joinData) { uint32 size = 0; - for (LfgLockPartyMap::const_iterator it = joinData.lockmap.begin(); it != joinData.lockmap.end(); ++it) + for (lfg::LfgLockPartyMap::const_iterator it = joinData.lockmap.begin(); it != joinData.lockmap.end(); ++it) size += 8 + 4 + uint32(it->second.size()) * (4 + 4 + 4 + 4); sLog->outDebug(LOG_FILTER_LFG, "SMSG_LFG_JOIN_RESULT %s checkResult: %u checkValue: %u", @@ -477,7 +463,7 @@ void WorldSession::SendLfgJoinResult(LfgJoinResultData const& joinData) SendPacket(&data); } -void WorldSession::SendLfgQueueStatus(LfgQueueStatusData const& queueData) +void WorldSession::SendLfgQueueStatus(lfg::LfgQueueStatusData const& queueData) { sLog->outDebug(LOG_FILTER_LFG, "SMSG_LFG_QUEUE_STATUS %s dungeon: %u, waitTime: %d, " "avgWaitTime: %d, waitTimeTanks: %d, waitTimeHealer: %d, waitTimeDps: %d, " @@ -500,7 +486,7 @@ void WorldSession::SendLfgQueueStatus(LfgQueueStatusData const& queueData) SendPacket(&data); } -void WorldSession::SendLfgPlayerReward(LfgPlayerRewardData const& rewardData) +void WorldSession::SendLfgPlayerReward(lfg::LfgPlayerRewardData const& rewardData) { if (!rewardData.rdungeonEntry || !rewardData.sdungeonEntry || !rewardData.quest) return; @@ -534,43 +520,43 @@ void WorldSession::SendLfgPlayerReward(LfgPlayerRewardData const& rewardData) SendPacket(&data); } -void WorldSession::SendLfgBootProposalUpdate(LfgPlayerBoot const& boot) +void WorldSession::SendLfgBootProposalUpdate(lfg::LfgPlayerBoot const& boot) { uint64 guid = GetPlayer()->GetGUID(); - LfgAnswer playerVote = boot.votes.find(guid)->second; + lfg::LfgAnswer playerVote = boot.votes.find(guid)->second; uint8 votesNum = 0; uint8 agreeNum = 0; uint32 secsleft = uint8((boot.cancelTime - time(NULL)) / 1000); - for (LfgAnswerContainer::const_iterator it = boot.votes.begin(); it != boot.votes.end(); ++it) + for (lfg::LfgAnswerContainer::const_iterator it = boot.votes.begin(); it != boot.votes.end(); ++it) { - if (it->second != LFG_ANSWER_PENDING) + if (it->second != lfg::LFG_ANSWER_PENDING) { ++votesNum; - if (it->second == LFG_ANSWER_AGREE) + if (it->second == lfg::LFG_ANSWER_AGREE) ++agreeNum; } } sLog->outDebug(LOG_FILTER_LFG, "SMSG_LFG_BOOT_PROPOSAL_UPDATE %s inProgress: %u - " "didVote: %u - agree: %u - victim: %u votes: %u - agrees: %u - left: %u - " "needed: %u - reason %s", - GetPlayerInfo().c_str(), uint8(boot.inProgress), uint8(playerVote != LFG_ANSWER_PENDING), - uint8(playerVote == LFG_ANSWER_AGREE), GUID_LOPART(boot.victim), votesNum, agreeNum, - secsleft, LFG_GROUP_KICK_VOTES_NEEDED, boot.reason.c_str()); + GetPlayerInfo().c_str(), uint8(boot.inProgress), uint8(playerVote != lfg::LFG_ANSWER_PENDING), + uint8(playerVote == lfg::LFG_ANSWER_AGREE), GUID_LOPART(boot.victim), votesNum, agreeNum, + secsleft, lfg::LFG_GROUP_KICK_VOTES_NEEDED, boot.reason.c_str()); WorldPacket data(SMSG_LFG_BOOT_PROPOSAL_UPDATE, 1 + 1 + 1 + 1 + 8 + 4 + 4 + 4 + 4 + boot.reason.length()); data << uint8(boot.inProgress); // Vote in progress - data << uint8(playerVote != LFG_ANSWER_PENDING); // Did Vote - data << uint8(playerVote == LFG_ANSWER_AGREE); // Agree + data << uint8(playerVote != lfg::LFG_ANSWER_PENDING); // Did Vote + data << uint8(playerVote == lfg::LFG_ANSWER_AGREE); // Agree data << uint8(0); // Unknown 4.2.2 data << uint64(boot.victim); // Victim GUID data << uint32(votesNum); // Total Votes data << uint32(agreeNum); // Agree Count data << uint32(secsleft); // Time Left - data << uint32(LFG_GROUP_KICK_VOTES_NEEDED); // Needed Votes + data << uint32(lfg::LFG_GROUP_KICK_VOTES_NEEDED); // Needed Votes data << boot.reason.c_str(); // Kick reason SendPacket(&data); } -void WorldSession::SendLfgUpdateProposal(LfgProposal const& proposal) +void WorldSession::SendLfgUpdateProposal(lfg::LfgProposal const& proposal) { uint64 guid = GetPlayer()->GetGUID(); uint64 gguid = proposal.players.find(guid)->second.group; @@ -583,13 +569,12 @@ void WorldSession::SendLfgUpdateProposal(LfgProposal const& proposal) // show random dungeon if player selected random dungeon and it's not lfg group if (!silent) { - LfgDungeonSet const& playerDungeons = sLFGMgr->GetSelectedDungeons(guid); + lfg::LfgDungeonSet const& playerDungeons = sLFGMgr->GetSelectedDungeons(guid); if (playerDungeons.find(proposal.dungeonId) == playerDungeons.end()) dungeonEntry = (*playerDungeons.begin()); } - if (LFGDungeonData const* dungeon = sLFGMgr->GetLFGDungeon(dungeonEntry)) - dungeonEntry = dungeon->Entry(); + dungeonEntry = sLFGMgr->GetLFGDungeonEntry(dungeonEntry); WorldPacket data(SMSG_LFG_PROPOSAL_UPDATE, 4 + 1 + 4 + 4 + 1 + 1 + proposal.players.size() * (4 + 1 + 1 + 1 + 1 +1)); data << uint32(dungeonEntry); // Dungeon @@ -599,9 +584,9 @@ void WorldSession::SendLfgUpdateProposal(LfgProposal const& proposal) data << uint8(silent); // Show proposal window data << uint8(proposal.players.size()); // Group size - for (LfgProposalPlayerContainer::const_iterator it = proposal.players.begin(); it != proposal.players.end(); ++it) + for (lfg::LfgProposalPlayerContainer::const_iterator it = proposal.players.begin(); it != proposal.players.end(); ++it) { - LfgProposalPlayer const& player = it->second; + lfg::LfgProposalPlayer const& player = it->second; data << uint32(player.role); // Role data << uint8(it->first == guid); // Self player if (!player.group) // Player not it a group @@ -614,8 +599,8 @@ void WorldSession::SendLfgUpdateProposal(LfgProposal const& proposal) data << uint8(player.group == proposal.group); // In dungeon (silent) data << uint8(player.group == gguid); // Same Group than player } - data << uint8(player.accept != LFG_ANSWER_PENDING);// Answered - data << uint8(player.accept == LFG_ANSWER_AGREE); // Accepted + data << uint8(player.accept != lfg::LFG_ANSWER_PENDING);// Answered + data << uint8(player.accept == lfg::LFG_ANSWER_AGREE); // Accepted } SendPacket(&data); } diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index a748b6ebad7..e08a7a30699 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -396,7 +396,7 @@ void WorldSession::HandleLogoutRequestOpcode(WorldPacket& /*recvData*/) //instant logout in taverns/cities or on taxi or for admins, gm's, mod's if its enabled in worldserver.conf if (GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING) || GetPlayer()->isInFlight() || - GetSecurity() >= AccountTypes(sWorld->getIntConfig(CONFIG_INSTANT_LOGOUT))) + HasPermission(RBAC_PERM_INSTANT_LOGOUT)) { WorldPacket data(SMSG_LOGOUT_RESPONSE, 1+4); data << uint32(reason); diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index e811a25f730..30ed39932ae 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -26,7 +26,6 @@ #include "GridStates.h" #include "Group.h" #include "InstanceScript.h" -#include "LFGMgr.h" #include "MapInstanced.h" #include "MapManager.h" #include "ObjectAccessor.h" @@ -2485,13 +2484,6 @@ bool InstanceMap::AddPlayerToMap(Player* player) ASSERT(playerBind->save == mapSave); } } - - if (group && group->isLFGGroup()) - if (uint32 dungeonId = sLFGMgr->GetDungeon(group->GetGUID(), true)) - if (LFGDungeonData const* dungeon = sLFGMgr->GetLFGDungeon(dungeonId)) - if (LFGDungeonData const* randomDungeon = sLFGMgr->GetLFGDungeon(*(sLFGMgr->GetSelectedDungeons(player->GetGUID()).begin()))) - if (uint32(dungeon->map) == GetId() && dungeon->difficulty == GetDifficulty() && randomDungeon->type == LFG_TYPE_RANDOM) - player->CastSpell(player, LFG_SPELL_LUCK_OF_THE_DRAW, true); } // for normal instances cancel the reset schedule when the diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h index 036d25acc61..03884ae003e 100644 --- a/src/server/game/Miscellaneous/Language.h +++ b/src/server/game/Miscellaneous/Language.h @@ -86,7 +86,40 @@ enum TrinityStrings LANG_CONNECTED_PLAYERS = 60, LANG_ACCOUNT_ADDON = 61, LANG_IMPROPER_VALUE = 62, - // Room for more level 0 63-99 not used + LANG_RBAC_WRONG_PARAMETER_ID = 63, + LANG_RBAC_WRONG_PARAMETER_REALM = 64, + LANG_RBAC_GROUP_IN_LIST = 65, + LANG_RBAC_GROUP_NOT_IN_LIST = 66, + LANG_RBAC_GROUP_ADDED = 67, + LANG_RBAC_GROUP_REMOVED = 68, + LANG_RBAC_GROUP_LIST_HEADER = 69, + LANG_RBAC_LIST_EMPTY = 70, + LANG_RBAC_LIST_ELEMENT = 71, + LANG_RBAC_ROLE_GRANTED_IN_LIST = 72, + LANG_RBAC_ROLE_GRANTED_IN_DENIED_LIST = 73, + LANG_RBAC_ROLE_GRANTED = 74, + LANG_RBAC_ROLE_DENIED_IN_LIST = 75, + LANG_RBAC_ROLE_DENIED_IN_GRANTED_LIST = 76, + LANG_RBAC_ROLE_DENIED = 77, + LANG_RBAC_ROLE_REVOKED = 78, + LANG_RBAC_ROLE_REVOKED_NOT_IN_LIST = 79, + LANG_RBAC_ROLE_LIST_HEADER_GRANTED = 80, + LANG_RBAC_ROLE_LIST_HEADER_DENIED = 81, + LANG_RBAC_PERM_GRANTED_IN_LIST = 82, + LANG_RBAC_PERM_GRANTED_IN_DENIED_LIST = 83, + LANG_RBAC_PERM_GRANTED = 84, + LANG_RBAC_PERM_DENIED_IN_LIST = 85, + LANG_RBAC_PERM_DENIED_IN_GRANTED_LIST = 86, + LANG_RBAC_PERM_DENIED = 87, + LANG_RBAC_PERM_REVOKED = 88, + LANG_RBAC_PERM_REVOKED_NOT_IN_LIST = 89, + LANG_RBAC_PERM_LIST_HEADER_GRANTED = 90, + LANG_RBAC_PERM_LIST_HEADER_DENIED = 91, + LANG_RBAC_PERM_LIST_GLOBAL = 92, + LANG_RBAC_LIST_GROUPS_HEADER = 93, + LANG_RBAC_LIST_ROLES_HEADER = 94, + LANG_RBAC_LIST_PERMISSIONS_HEADER = 95, + // Room for more level 0 96-99 not used // level 1 chat LANG_GLOBAL_NOTIFY = 100, diff --git a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp index 06b2315f294..1f5503948c8 100755 --- a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp @@ -128,8 +128,6 @@ void EffectMovementGenerator::Finalize(Unit* unit) if (unit->GetTypeId() != TYPEID_UNIT) return; - if (unit->ToCreature()->AI()) - unit->ToCreature()->AI()->MovementInform(EFFECT_MOTION_TYPE, m_Id); // Need restore previous movement since we have no proper states system if (unit->isAlive() && !unit->HasUnitState(UNIT_STATE_CONFUSED | UNIT_STATE_FLEEING)) { @@ -138,4 +136,7 @@ void EffectMovementGenerator::Finalize(Unit* unit) else unit->GetMotionMaster()->Initialize(); } + + if (unit->ToCreature()->AI()) + unit->ToCreature()->AI()->MovementInform(EFFECT_MOTION_TYPE, m_Id); } diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp index 5b31d4a6950..245ca7fd41d 100644 --- a/src/server/game/Scripting/ScriptLoader.cpp +++ b/src/server/game/Scripting/ScriptLoader.cpp @@ -70,6 +70,7 @@ void AddSC_mmaps_commandscript(); void AddSC_modify_commandscript(); void AddSC_npc_commandscript(); void AddSC_quest_commandscript(); +void AddSC_rbac_commandscript(); void AddSC_reload_commandscript(); void AddSC_reset_commandscript(); void AddSC_server_commandscript(); @@ -700,6 +701,7 @@ void AddCommandScripts() AddSC_modify_commandscript(); AddSC_npc_commandscript(); AddSC_quest_commandscript(); + AddSC_rbac_commandscript(); AddSC_reload_commandscript(); AddSC_reset_commandscript(); AddSC_server_commandscript(); diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp index bdbfa46ba5d..5a973395c68 100644 --- a/src/server/game/Scripting/ScriptMgr.cpp +++ b/src/server/game/Scripting/ScriptMgr.cpp @@ -580,6 +580,8 @@ void ScriptMgr::OnPlayerEnterMap(Map* map, Player* player) ASSERT(map); ASSERT(player); + FOREACH_SCRIPT(PlayerScript)->OnMapChanged(player); + SCR_MAP_BGN(WorldMapScript, map, itr, end, entry, IsWorldMap); itr->second->OnPlayerEnter(map, player); SCR_MAP_END; diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h index 92b5e8299e1..e9d040200e4 100644 --- a/src/server/game/Scripting/ScriptMgr.h +++ b/src/server/game/Scripting/ScriptMgr.h @@ -753,6 +753,9 @@ class PlayerScript : public UnitScript // Called when a player switches to a new zone virtual void OnUpdateZone(Player* /*player*/, uint32 /*newZone*/, uint32 /*newArea*/) { } + + // Called when a player changes to a new map (after moving to new map) + virtual void OnMapChanged(Player* /*player*/) { } }; class GuildScript : public ScriptObject diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 97ac6c0440e..d12128b11c1 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -22,6 +22,7 @@ #include "WorldSocket.h" // must be first to make ACE happy with ACE includes in it #include <zlib.h> +#include "Config.h" #include "Common.h" #include "DatabaseEnv.h" #include "Log.h" @@ -119,7 +120,8 @@ WorldSession::WorldSession(uint32 id, WorldSocket* sock, AccountTypes sec, uint8 _filterAddonMessages(false), recruiterId(recruiter), isRecruiter(isARecruiter), - timeLastWhoCommand(0) + timeLastWhoCommand(0), + _RBACData(NULL) { if (sock) { @@ -160,8 +162,8 @@ WorldSession::~WorldSession() m_Socket = NULL; } - if (_warden) - delete _warden; + delete _warden; + delete _RBACData; ///- empty incoming packet queue WorldPacket* packet = NULL; @@ -1152,3 +1154,24 @@ void WorldSession::InitWarden(BigNumber* k, std::string const& os) // _warden->Init(this, k); } } + +void WorldSession::LoadPermissions() +{ + uint32 id = GetAccountId(); + std::string name; + int32 realmId = ConfigMgr::GetIntDefault("RealmID", 0); + AccountMgr::GetName(id, name); + + _RBACData = new RBACData(id, name, realmId); + _RBACData->LoadFromDB(); +} + +RBACData* WorldSession::GetRBACData() +{ + return _RBACData; +} + +bool WorldSession::HasPermission(uint32 permission) +{ + return _RBACData->HasPermission(permission); +} diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index d2ef4c4eea5..419de3a466e 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -24,6 +24,7 @@ #define __WORLDSESSION_H #include "Common.h" +#include "AccountMgr.h" #include "SharedDefines.h" #include "AddonMgr.h" #include "DatabaseEnv.h" @@ -49,15 +50,18 @@ struct AreaTableEntry; struct AuctionEntry; struct DeclinedName; struct ItemTemplate; +struct MovementInfo; + +namespace lfg +{ struct LfgJoinResultData; -struct LfgLockStatus; struct LfgPlayerBoot; struct LfgProposal; struct LfgQueueStatusData; struct LfgPlayerRewardData; struct LfgRoleCheck; struct LfgUpdateData; -struct MovementInfo; +} enum AccountDataType { @@ -218,6 +222,10 @@ class WorldSession void SendAuthResponse(uint8 code, bool queued, uint32 queuePos = 0); void SendClientCacheVersion(uint32 version); + RBACData* GetRBACData(); + bool HasPermission(uint32 permissionId); + void LoadPermissions(); + AccountTypes GetSecurity() const { return _security; } uint32 GetAccountId() const { return _accountId; } Player* GetPlayer() const { return _player; } @@ -811,16 +819,16 @@ class WorldSession void HandleLfrLeaveOpcode(WorldPacket& recvData); void HandleLfgGetStatus(WorldPacket& recvData); - void SendLfgUpdatePlayer(LfgUpdateData const& updateData); - void SendLfgUpdateParty(LfgUpdateData const& updateData); + void SendLfgUpdatePlayer(lfg::LfgUpdateData const& updateData); + void SendLfgUpdateParty(lfg::LfgUpdateData const& updateData); void SendLfgRoleChosen(uint64 guid, uint8 roles); - void SendLfgRoleCheckUpdate(LfgRoleCheck const& pRoleCheck); + void SendLfgRoleCheckUpdate(lfg::LfgRoleCheck const& pRoleCheck); void SendLfgLfrList(bool update); - void SendLfgJoinResult(LfgJoinResultData const& joinData); - void SendLfgQueueStatus(LfgQueueStatusData const& queueData); - void SendLfgPlayerReward(LfgPlayerRewardData const& lfgPlayerRewardData); - void SendLfgBootProposalUpdate(LfgPlayerBoot const& boot); - void SendLfgUpdateProposal(LfgProposal const& proposal); + void SendLfgJoinResult(lfg::LfgJoinResultData const& joinData); + void SendLfgQueueStatus(lfg::LfgQueueStatusData const& queueData); + void SendLfgPlayerReward(lfg::LfgPlayerRewardData const& lfgPlayerRewardData); + void SendLfgBootProposalUpdate(lfg::LfgPlayerBoot const& boot); + void SendLfgUpdateProposal(lfg::LfgProposal const& proposal); void SendLfgDisabled(); void SendLfgOfferContinue(uint32 dungeonEntry); void SendLfgTeleportError(uint8 err); @@ -1009,6 +1017,7 @@ class WorldSession ACE_Based::LockedQueue<WorldPacket*, ACE_Thread_Mutex> _recvQueue; time_t timeLastWhoCommand; z_stream_s* _compressionStream; + RBACData* _RBACData; }; #endif /// @} diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp index 9e3c47caea2..753864c2b70 100644 --- a/src/server/game/Server/WorldSocket.cpp +++ b/src/server/game/Server/WorldSocket.cpp @@ -886,7 +886,7 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket) { mutetime = time(NULL) + llabs(mutetime); - PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_MUTE_TIME); + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_MUTE_TIME_LOGIN); stmt->setInt64(0, mutetime); stmt->setUInt32(1, id); @@ -1002,6 +1002,7 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket) m_Session->LoadGlobalAccountData(); m_Session->LoadTutorialsData(); m_Session->ReadAddonsInfo(addonsData); + m_Session->LoadPermissions(); // Initialize Warden system only if it is enabled by config if (sWorld->getBoolConfig(CONFIG_WARDEN_ENABLED)) diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 38637cdde29..3bba06a021f 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -269,7 +269,7 @@ void World::AddSession_(WorldSession* s) if (decrease_session) --Sessions; - if (pLimit > 0 && Sessions >= pLimit && AccountMgr::IsPlayerAccount(s->GetSecurity()) && !HasRecentlyDisconnected(s)) + if (pLimit > 0 && Sessions >= pLimit && !s->HasPermission(RBAC_PERM_SKIP_QUEUE) && !HasRecentlyDisconnected(s)) { AddQueuedPlayer(s); UpdateMaxSessionCounters(); @@ -587,7 +587,6 @@ void World::LoadConfigSettings(bool reload) m_int_configs[CONFIG_TICKET_LEVEL_REQ] = ConfigMgr::GetIntDefault("LevelReq.Ticket", 1); m_int_configs[CONFIG_AUCTION_LEVEL_REQ] = ConfigMgr::GetIntDefault("LevelReq.Auction", 1); m_int_configs[CONFIG_MAIL_LEVEL_REQ] = ConfigMgr::GetIntDefault("LevelReq.Mail", 1); - m_bool_configs[CONFIG_ALLOW_PLAYER_COMMANDS] = ConfigMgr::GetBoolDefault("AllowPlayerCommands", 1); m_bool_configs[CONFIG_PRESERVE_CUSTOM_CHANNELS] = ConfigMgr::GetBoolDefault("PreserveCustomChannels", false); m_int_configs[CONFIG_PRESERVE_CUSTOM_CHANNEL_DURATION] = ConfigMgr::GetIntDefault("PreserveCustomChannelDuration", 14); m_bool_configs[CONFIG_GRID_UNLOAD] = ConfigMgr::GetBoolDefault("GridUnload", true); @@ -1081,8 +1080,6 @@ void World::LoadConfigSettings(bool reload) sLog->outError(LOG_FILTER_SERVER_LOADING, "ClientCacheVersion can't be negative %d, ignored.", clientCacheId); } - m_int_configs[CONFIG_INSTANT_LOGOUT] = ConfigMgr::GetIntDefault("InstantLogout", SEC_MODERATOR); - m_int_configs[CONFIG_GUILD_NEWS_LOG_COUNT] = ConfigMgr::GetIntDefault("Guild.NewsLogRecordsCount", GUILD_NEWSLOG_MAX_RECORDS); if (m_int_configs[CONFIG_GUILD_NEWS_LOG_COUNT] > GUILD_NEWSLOG_MAX_RECORDS) m_int_configs[CONFIG_GUILD_NEWS_LOG_COUNT] = GUILD_NEWSLOG_MAX_RECORDS; @@ -1382,6 +1379,8 @@ void World::SetInitialWorldSettings() sObjectMgr->SetDBCLocaleIndex(GetDefaultDbcLocale()); // Get once for all the locale index of DBC language (console/broadcasts) sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Localization strings loaded in %u ms", GetMSTimeDiffToNow(oldMSTime)); + sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading Account Roles and Permissions..."); + sAccountMgr->LoadRBAC(); sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading Page Texts..."); sObjectMgr->LoadPageTexts(); diff --git a/src/server/scripts/Commands/CMakeLists.txt b/src/server/scripts/Commands/CMakeLists.txt index 7b9e2444952..83e97b2c80d 100644 --- a/src/server/scripts/Commands/CMakeLists.txt +++ b/src/server/scripts/Commands/CMakeLists.txt @@ -35,6 +35,7 @@ set(scripts_STAT_SRCS Commands/cs_modify.cpp Commands/cs_npc.cpp Commands/cs_quest.cpp + Commands/cs_rbac.cpp Commands/cs_reload.cpp Commands/cs_reset.cpp Commands/cs_tele.cpp diff --git a/src/server/scripts/Commands/cs_account.cpp b/src/server/scripts/Commands/cs_account.cpp index 3a20a03bb4a..4dc44bbfc58 100644 --- a/src/server/scripts/Commands/cs_account.cpp +++ b/src/server/scripts/Commands/cs_account.cpp @@ -106,7 +106,7 @@ public: if (!accountName || !password) return false; - AccountOpResult result = AccountMgr::CreateAccount(std::string(accountName), std::string(password)); + AccountOpResult result = sAccountMgr->CreateAccount(std::string(accountName), std::string(password)); switch (result) { case AOR_OK: @@ -503,36 +503,8 @@ public: return false; } - // If gmRealmID is -1, delete all values for the account id, else, insert values for the specific realmID - PreparedStatement* stmt; - - if (gmRealmID == -1) - { - stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_ACCOUNT_ACCESS); - - stmt->setUInt32(0, targetAccountId); - } - else - { - stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_ACCOUNT_ACCESS_BY_REALM); - - stmt->setUInt32(0, targetAccountId); - stmt->setUInt32(1, realmID); - } - - LoginDatabase.Execute(stmt); - - if (gm != 0) - { - stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_ACCOUNT_ACCESS); - - stmt->setUInt32(0, targetAccountId); - stmt->setUInt8(1, uint8(gm)); - stmt->setInt32(2, gmRealmID); - - LoginDatabase.Execute(stmt); - } - + RBACData* rbac = isAccountNameGiven ? NULL : handler->getSelectedPlayer()->GetSession()->GetRBACData(); + sAccountMgr->UpdateAccountAccess(rbac, targetAccountId, uint8(gm), gmRealmID); handler->PSendSysMessage(LANG_YOU_CHANGE_SECURITY, targetAccountName.c_str(), gm); return true; diff --git a/src/server/scripts/Commands/cs_lfg.cpp b/src/server/scripts/Commands/cs_lfg.cpp index 7f39a8fc024..aa9d9308bcd 100644 --- a/src/server/scripts/Commands/cs_lfg.cpp +++ b/src/server/scripts/Commands/cs_lfg.cpp @@ -28,12 +28,12 @@ void GetPlayerInfo(ChatHandler* handler, Player* player) return; uint64 guid = player->GetGUID(); - LfgDungeonSet dungeons = sLFGMgr->GetSelectedDungeons(guid); + lfg::LfgDungeonSet dungeons = sLFGMgr->GetSelectedDungeons(guid); - std::string const& state = sLFGMgr->GetStateString(sLFGMgr->GetState(guid)); + std::string const& state = lfg::GetStateString(sLFGMgr->GetState(guid)); handler->PSendSysMessage(LANG_LFG_PLAYER_INFO, player->GetName().c_str(), - state.c_str(), uint8(dungeons.size()), sLFGMgr->ConcatenateDungeons(dungeons).c_str(), - sLFGMgr->GetRolesString(sLFGMgr->GetRoles(guid)).c_str(), sLFGMgr->GetComment(guid).c_str()); + state.c_str(), uint8(dungeons.size()), lfg::ConcatenateDungeons(dungeons).c_str(), + lfg::GetRolesString(sLFGMgr->GetRoles(guid)).c_str(), sLFGMgr->GetComment(guid).c_str()); } class lfg_commandscript : public CommandScript @@ -87,7 +87,7 @@ public: } uint64 guid = grp->GetGUID(); - std::string const& state = sLFGMgr->GetStateString(sLFGMgr->GetState(guid)); + std::string const& state = lfg::GetStateString(sLFGMgr->GetState(guid)); handler->PSendSysMessage(LANG_LFG_GROUP_INFO, grp->isLFGGroup(), state.c_str(), sLFGMgr->GetDungeon(guid)); diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index 989a9b540f5..3acfe9c14ba 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -1549,6 +1549,8 @@ public: std::string userName = handler->GetTrinityString(LANG_ERROR); std::string eMail = handler->GetTrinityString(LANG_ERROR); + std::string muteReason = ""; + std::string muteBy = ""; std::string lastIp = handler->GetTrinityString(LANG_ERROR); uint32 security = 0; std::string lastLogin = handler->GetTrinityString(LANG_ERROR); @@ -1565,6 +1567,8 @@ public: security = fields[1].GetUInt8(); eMail = fields[2].GetString(); muteTime = fields[5].GetUInt64(); + muteReason = fields[6].GetString(); + muteBy = fields[7].GetString(); if (eMail.empty()) eMail = "-"; @@ -1626,7 +1630,7 @@ public: } if (muteTime > 0) - handler->PSendSysMessage(LANG_PINFO_MUTE, secsToTimeString(muteTime - time(NULL), true).c_str()); + handler->PSendSysMessage(LANG_PINFO_MUTE, secsToTimeString(muteTime - time(NULL), true).c_str(), muteBy.c_str(), muteReason.c_str()); if (banTime >= 0) handler->PSendSysMessage(LANG_PINFO_BAN, banTime > 0 ? secsToTimeString(banTime - time(NULL), true).c_str() : "permanently", bannedby.c_str(), banreason.c_str()); @@ -1824,6 +1828,11 @@ public: return false; PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_MUTE_TIME); + std::string muteBy = ""; + if (handler->GetSession()) + muteBy = handler->GetSession()->GetPlayerName(); + else + muteBy = "Console"; if (target) { @@ -1831,7 +1840,7 @@ public: int64 muteTime = time(NULL) + notSpeakTime * MINUTE; target->GetSession()->m_muteTime = muteTime; stmt->setInt64(0, muteTime); - ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOUR_CHAT_DISABLED, notSpeakTime, muteReasonStr.c_str()); + ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOUR_CHAT_DISABLED, notSpeakTime, muteBy.c_str(), muteReasonStr.c_str()); } else { @@ -1840,7 +1849,9 @@ public: stmt->setInt64(0, muteTime); } - stmt->setUInt32(1, accountId); + stmt->setString(1, muteReasonStr.c_str()); + stmt->setString(2, muteBy.c_str()); + stmt->setUInt32(3, accountId); LoginDatabase.Execute(stmt); std::string nameLink = handler->playerLink(targetName); @@ -1883,7 +1894,9 @@ public: PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_MUTE_TIME); stmt->setInt64(0, 0); - stmt->setUInt32(1, accountId); + stmt->setString(1, ""); + stmt->setString(2, ""); + stmt->setUInt32(3, accountId); LoginDatabase.Execute(stmt); if (target) @@ -2832,41 +2845,40 @@ public: { handler->PSendSysMessage(LANG_GROUP_TYPE, (groupTarget->isRaidGroup() ? "raid" : "party")); Group::MemberSlotList const& members = groupTarget->GetMemberSlots(); - Group::MemberSlotList::const_iterator itr; - for (itr = members.begin(); itr != members.end(); ++itr) + for (Group::MemberSlotList::const_iterator itr = members.begin(); itr != members.end(); ++itr) { - std::ostringstream flags, roles; - if ((*itr).flags & MEMBER_FLAG_ASSISTANT) - flags << "Assistant "; - if ((*itr).flags & MEMBER_FLAG_MAINTANK) - flags << "MainTank "; - if ((*itr).flags & MEMBER_FLAG_MAINASSIST) - flags << "MainAssist "; - - if ((*itr).roles & PLAYER_ROLE_LEADER) - roles << "Leader "; - if ((*itr).roles & PLAYER_ROLE_TANK) - roles << "Tank "; - if ((*itr).roles & PLAYER_ROLE_HEALER) - roles << "Healer "; - if ((*itr).roles & PLAYER_ROLE_DAMAGE) - roles << "Damage "; + Group::MemberSlot const& slot = *itr; + + std::string flags; + if (slot.flags & MEMBER_FLAG_ASSISTANT) + flags = "Assistant"; + + if (slot.flags & MEMBER_FLAG_MAINTANK) + { + if (!flags.empty()) + flags.append(", "); + flags.append("MainTank"); + } + + if (slot.flags & MEMBER_FLAG_MAINASSIST) + { + if (!flags.empty()) + flags.append(", "); + flags.append("MainAssist"); + } + + if (flags.empty()) + flags = "None"; Player* p = ObjectAccessor::FindPlayer((*itr).guid); const char* onlineState = (p && p->IsInWorld()) ? "online" : "offline"; - std::string flagsStr = (flags.str().empty()) ? "None" : flags.str(); - std::string rolesStr = (roles.str().empty()) ? "None" : roles.str(); - - handler->PSendSysMessage(LANG_GROUP_PLAYER_NAME_GUID, (*itr).name.c_str(), onlineState, GUID_LOPART((*itr).guid), flagsStr.c_str(), rolesStr.c_str()); + handler->PSendSysMessage(LANG_GROUP_PLAYER_NAME_GUID, slot.name.c_str(), onlineState, + GUID_LOPART(slot.guid), flags.c_str(), lfg::GetRolesString(slot.roles).c_str()); } - return true; } else - { handler->PSendSysMessage(LANG_GROUP_NOT_IN_GROUP, nameTarget.c_str()); - return true; - } return true; } diff --git a/src/server/scripts/Commands/cs_rbac.cpp b/src/server/scripts/Commands/cs_rbac.cpp new file mode 100644 index 00000000000..fb21def4c02 --- /dev/null +++ b/src/server/scripts/Commands/cs_rbac.cpp @@ -0,0 +1,780 @@ +/*
+ * Copyright (C) 2008-2013 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* ScriptData
+Name: rbac_commandscript
+%Complete: 100
+Comment: All role based access control related commands (including account related)
+Category: commandscripts
+EndScriptData */
+
+#include "RBAC.h"
+#include "Config.h"
+#include "Chat.h"
+#include "Language.h"
+#include "Player.h"
+#include "ScriptMgr.h"
+
+struct RBACCommandData
+{
+ RBACCommandData(): id(0), realmId(0), rbac(NULL), needDelete(false) { }
+ uint32 id;
+ int32 realmId;
+ RBACData* rbac;
+ bool needDelete;
+};
+
+class rbac_commandscript : public CommandScript
+{
+public:
+ rbac_commandscript() : CommandScript("rbac_commandscript") { }
+
+ ChatCommand* GetCommands() const
+ {
+ static ChatCommand rbacGroupsCommandTable[] =
+ {
+ { "add", SEC_ADMINISTRATOR, true, &HandleRBACGroupAddCommand, "", NULL },
+ { "remove", SEC_ADMINISTRATOR, true, &HandleRBACGroupRemoveCommand, "", NULL },
+ { "", SEC_ADMINISTRATOR, true, &HandleRBACGroupListCommand, "", NULL },
+ { NULL, SEC_ADMINISTRATOR, false, NULL, "", NULL }
+ };
+
+ static ChatCommand rbacRolesCommandTable[] =
+ {
+ { "grant", SEC_ADMINISTRATOR, true, &HandleRBACRoleGrantCommand, "", NULL },
+ { "deny", SEC_ADMINISTRATOR, true, &HandleRBACRoleDenyCommand, "", NULL },
+ { "revoke", SEC_ADMINISTRATOR, true, &HandleRBACRoleRevokeCommand, "", NULL },
+ { "", SEC_ADMINISTRATOR, true, &HandleRBACRoleListCommand, "", NULL },
+ { NULL, SEC_ADMINISTRATOR, false, NULL, "", NULL }
+ };
+
+ static ChatCommand rbacPermsCommandTable[] =
+ {
+ { "grant", SEC_ADMINISTRATOR, true, &HandleRBACPermGrantCommand, "", NULL },
+ { "deny", SEC_ADMINISTRATOR, true, &HandleRBACPermDenyCommand, "", NULL },
+ { "revoke", SEC_ADMINISTRATOR, true, &HandleRBACPermRevokeCommand, "", NULL },
+ { "", SEC_ADMINISTRATOR, true, &HandleRBACPermListCommand, "", NULL },
+ { NULL, SEC_ADMINISTRATOR, false, NULL, "", NULL }
+ };
+
+ static ChatCommand rbacListCommandTable[] =
+ {
+ { "groups", SEC_ADMINISTRATOR, true, &HandleRBACListGroupsCommand, "", NULL },
+ { "roles", SEC_ADMINISTRATOR, true, &HandleRBACListRolesCommand, "", NULL },
+ { "permissions", SEC_ADMINISTRATOR, true, &HandleRBACListPermissionsCommand, "", NULL },
+ { NULL, SEC_ADMINISTRATOR, false, NULL, "", NULL }
+ };
+
+ static ChatCommand rbacAccountCommandTable[] =
+ {
+ { "group", SEC_ADMINISTRATOR, true, NULL, "", rbacGroupsCommandTable },
+ { "role", SEC_ADMINISTRATOR, true, NULL, "", rbacRolesCommandTable },
+ { "permission", SEC_ADMINISTRATOR, true, NULL, "", rbacPermsCommandTable },
+ { "", SEC_ADMINISTRATOR, true, &HandleRBACAccountPermissionCommand, "", NULL },
+ { NULL, SEC_ADMINISTRATOR, false, NULL, "", NULL }
+ };
+
+ static ChatCommand rbacCommandTable[] =
+ {
+ { "account", SEC_ADMINISTRATOR, true, NULL, "", rbacAccountCommandTable },
+ { "list", SEC_ADMINISTRATOR, true, NULL, "", rbacListCommandTable },
+ { NULL, SEC_ADMINISTRATOR, false, NULL, "", NULL }
+ };
+
+ static ChatCommand commandTable[] =
+ {
+ { "rbac", SEC_ADMINISTRATOR, true, NULL, "", rbacCommandTable },
+ { NULL, SEC_ADMINISTRATOR, false, NULL, "", NULL }
+ };
+
+ return commandTable;
+ }
+
+ static RBACCommandData* ReadParams(ChatHandler* handler, char const* args, bool checkParams = true)
+ {
+ if (!args)
+ return NULL;
+
+ char* param1 = strtok((char*)args, " ");
+ char* param2 = strtok(NULL, " ");
+ char* param3 = strtok(NULL, " ");
+
+ int32 realmId = -1;
+ uint32 accountId = 0;
+ std::string accountName;
+ uint32 id = 0;
+ RBACCommandData* data = NULL;
+ RBACData* rdata = NULL;
+ bool useSelectedPlayer = false;
+
+ if (checkParams)
+ {
+ if (!param3)
+ {
+ if (param2)
+ realmId = atoi(param2);
+
+ if (param1)
+ id = atoi(param1);
+
+ useSelectedPlayer = true;
+ }
+ else
+ {
+ id = atoi(param2);
+ realmId = atoi(param3);
+ }
+
+ if (!id)
+ {
+ handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, id);
+ handler->SetSentErrorMessage(true);
+ return NULL;
+ }
+
+ if (realmId < -1 || !realmId)
+ {
+ handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_REALM, realmId);
+ handler->SetSentErrorMessage(true);
+ return NULL;
+ }
+ }
+ else if (!param1)
+ useSelectedPlayer = true;
+
+ if (useSelectedPlayer)
+ {
+ Player* player = handler->getSelectedPlayer();
+ if (!player)
+ return NULL;
+
+ rdata = player->GetSession()->GetRBACData();
+ accountId = rdata->GetId();
+ AccountMgr::GetName(accountId, accountName);
+ }
+ else
+ {
+ accountName = param1;
+
+ if (AccountMgr::normalizeString(accountName))
+ accountId = AccountMgr::GetId(accountName);
+
+ if (!accountId)
+ {
+ handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str());
+ handler->SetSentErrorMessage(true);
+ return NULL;
+ }
+ }
+
+ if (checkParams && handler->HasLowerSecurityAccount(NULL, accountId, true))
+ return NULL;
+
+ data = new RBACCommandData();
+
+ if (!rdata)
+ {
+ data->rbac = new RBACData(accountId, accountName, ConfigMgr::GetIntDefault("RealmID", 0));
+ data->rbac->LoadFromDB();
+ data->needDelete = true;
+ }
+ else
+ data->rbac = rdata;
+
+ data->id = id;
+ data->realmId = realmId;
+ return data;
+ }
+
+ static bool HandleRBACGroupAddCommand(ChatHandler* handler, char const* args)
+ {
+ RBACCommandData* command = ReadParams(handler, args);
+
+ if (!command)
+ {
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ RBACCommandResult result = command->rbac->AddGroup(command->id, command->realmId);
+ RBACGroup const* group = sAccountMgr->GetRBACGroup(command->id);
+
+ switch (result)
+ {
+ case RBAC_CANT_ADD_ALREADY_ADDED:
+ handler->PSendSysMessage(LANG_RBAC_GROUP_IN_LIST, command->id, group->GetName().c_str(),
+ command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str());
+ break;
+ case RBAC_OK:
+ handler->PSendSysMessage(LANG_RBAC_GROUP_ADDED, command->id, group->GetName().c_str(),
+ command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str());
+ break;
+ case RBAC_ID_DOES_NOT_EXISTS:
+ handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, command->id);
+ break;
+ default:
+ break;
+ }
+
+ if (command->needDelete)
+ delete command;
+
+ return true;
+ }
+
+ static bool HandleRBACGroupRemoveCommand(ChatHandler* handler, char const* args)
+ {
+ RBACCommandData* command = ReadParams(handler, args);
+
+ if (!command)
+ {
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ RBACCommandResult result = command->rbac->RemoveGroup(command->id, command->realmId);
+ RBACGroup const* group = sAccountMgr->GetRBACGroup(command->id);
+
+ switch (result)
+ {
+ case RBAC_CANT_REVOKE_NOT_IN_LIST:
+ handler->PSendSysMessage(LANG_RBAC_GROUP_NOT_IN_LIST, command->id, group->GetName().c_str(),
+ command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str());
+ break;
+ case RBAC_OK:
+ handler->PSendSysMessage(LANG_RBAC_GROUP_REMOVED, command->id, group->GetName().c_str(),
+ command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str());
+ break;
+ case RBAC_ID_DOES_NOT_EXISTS:
+ handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, command->id);
+ break;
+ default:
+ break;
+ }
+
+ if (command->needDelete)
+ delete command;
+
+ return true;
+ }
+
+ static bool HandleRBACGroupListCommand(ChatHandler* handler, char const* args)
+ {
+ RBACCommandData* command = ReadParams(handler, args, false);
+
+ if (!command)
+ {
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ handler->PSendSysMessage(LANG_RBAC_GROUP_LIST_HEADER, command->rbac->GetId(), command->rbac->GetName().c_str());
+ RBACGroupContainer const& groups = command->rbac->GetGroups();
+ if (groups.empty())
+ handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_EMPTY));
+ else
+ {
+ for (RBACGroupContainer::const_iterator it = groups.begin(); it != groups.end(); ++it)
+ {
+ RBACGroup const* group = sAccountMgr->GetRBACGroup(*it);
+ handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, group->GetId(), group->GetName().c_str());
+ }
+ }
+
+ if (command->needDelete)
+ delete command;
+
+ return true;
+ }
+
+ static bool HandleRBACRoleGrantCommand(ChatHandler* handler, char const* args)
+ {
+ RBACCommandData* command = ReadParams(handler, args);
+
+ if (!command)
+ {
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ RBACCommandResult result = command->rbac->GrantRole(command->id, command->realmId);
+ RBACRole const* role = sAccountMgr->GetRBACRole(command->id);
+
+ switch (result)
+ {
+ case RBAC_CANT_ADD_ALREADY_ADDED:
+ handler->PSendSysMessage(LANG_RBAC_ROLE_GRANTED_IN_LIST, command->id, role->GetName().c_str(),
+ command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str());
+ break;
+ case RBAC_IN_DENIED_LIST:
+ handler->PSendSysMessage(LANG_RBAC_ROLE_GRANTED_IN_DENIED_LIST, command->id, role->GetName().c_str(),
+ command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str());
+ break;
+ case RBAC_OK:
+ handler->PSendSysMessage(LANG_RBAC_ROLE_GRANTED, command->id, role->GetName().c_str(),
+ command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str());
+ break;
+ case RBAC_ID_DOES_NOT_EXISTS:
+ handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, command->id);
+ break;
+ default:
+ break;
+ }
+
+ if (command->needDelete)
+ delete command;
+
+ return true;
+ }
+
+ static bool HandleRBACRoleDenyCommand(ChatHandler* handler, char const* args)
+ {
+ RBACCommandData* command = ReadParams(handler, args);
+
+ if (!command)
+ {
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ RBACCommandResult result = command->rbac->DenyRole(command->id, command->realmId);
+ RBACRole const* role = sAccountMgr->GetRBACRole(command->id);
+
+ switch (result)
+ {
+ case RBAC_CANT_ADD_ALREADY_ADDED:
+ handler->PSendSysMessage(LANG_RBAC_ROLE_DENIED_IN_LIST, command->id, role->GetName().c_str(),
+ command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str());
+ break;
+ case RBAC_IN_GRANTED_LIST:
+ handler->PSendSysMessage(LANG_RBAC_ROLE_DENIED_IN_GRANTED_LIST, command->id, role->GetName().c_str(),
+ command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str());
+ break;
+ case RBAC_OK:
+ handler->PSendSysMessage(LANG_RBAC_ROLE_DENIED, command->id, role->GetName().c_str(),
+ command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str());
+ break;
+ case RBAC_ID_DOES_NOT_EXISTS:
+ handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, command->id);
+ break;
+ default:
+ break;
+ }
+
+ if (command->needDelete)
+ delete command;
+
+ return true;
+ }
+
+ static bool HandleRBACRoleRevokeCommand(ChatHandler* handler, char const* args)
+ {
+ RBACCommandData* command = ReadParams(handler, args);
+
+ if (!command)
+ {
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ RBACCommandResult result = command->rbac->RevokeRole(command->id, command->realmId);
+ RBACRole const* role = sAccountMgr->GetRBACRole(command->id);
+
+ switch (result)
+ {
+ case RBAC_CANT_REVOKE_NOT_IN_LIST:
+ handler->PSendSysMessage(LANG_RBAC_ROLE_REVOKED_NOT_IN_LIST, command->id, role->GetName().c_str(),
+ command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str());
+ break;
+ case RBAC_OK:
+ handler->PSendSysMessage(LANG_RBAC_ROLE_REVOKED, command->id, role->GetName().c_str(),
+ command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str());
+ break;
+ case RBAC_ID_DOES_NOT_EXISTS:
+ handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, command->id);
+ break;
+ default:
+ break;
+ }
+
+ if (command->needDelete)
+ delete command;
+
+ return true;
+ }
+
+ static bool HandleRBACRoleListCommand(ChatHandler* handler, char const* args)
+ {
+ RBACCommandData* command = ReadParams(handler, args, false);
+
+ if (!command)
+ {
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ handler->PSendSysMessage(LANG_RBAC_ROLE_LIST_HEADER_GRANTED, command->rbac->GetId(), command->rbac->GetName().c_str());
+ RBACGroupContainer const& granted = command->rbac->GetGrantedRoles();
+ if (granted.empty())
+ handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_EMPTY));
+ else
+ {
+ for (RBACRoleContainer::const_iterator it = granted.begin(); it != granted.end(); ++it)
+ {
+ RBACRole const* role = sAccountMgr->GetRBACRole(*it);
+ handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, role->GetId(), role->GetName().c_str());
+ }
+ }
+
+ handler->PSendSysMessage(LANG_RBAC_ROLE_LIST_HEADER_DENIED, command->rbac->GetId(), command->rbac->GetName().c_str());
+ RBACGroupContainer const& denied = command->rbac->GetDeniedRoles();
+ if (denied.empty())
+ handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_EMPTY));
+ else
+ {
+ for (RBACRoleContainer::const_iterator it = denied.begin(); it != denied.end(); ++it)
+ {
+ RBACRole const* role = sAccountMgr->GetRBACRole(*it);
+ handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, role->GetId(), role->GetName().c_str());
+ }
+ }
+
+ if (command->needDelete)
+ delete command;
+
+ return true;
+ }
+
+ static bool HandleRBACPermGrantCommand(ChatHandler* handler, char const* args)
+ {
+ RBACCommandData* command = ReadParams(handler, args);
+
+ if (!command)
+ {
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ RBACCommandResult result = command->rbac->GrantPermission(command->id, command->realmId);
+ RBACPermission const* permission = sAccountMgr->GetRBACPermission(command->id);
+
+ switch (result)
+ {
+ case RBAC_CANT_ADD_ALREADY_ADDED:
+ handler->PSendSysMessage(LANG_RBAC_PERM_GRANTED_IN_LIST, command->id, permission->GetName().c_str(),
+ command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str());
+ break;
+ case RBAC_IN_DENIED_LIST:
+ handler->PSendSysMessage(LANG_RBAC_PERM_GRANTED_IN_DENIED_LIST, command->id, permission->GetName().c_str(),
+ command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str());
+ break;
+ case RBAC_OK:
+ handler->PSendSysMessage(LANG_RBAC_PERM_GRANTED, command->id, permission->GetName().c_str(),
+ command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str());
+ break;
+ case RBAC_ID_DOES_NOT_EXISTS:
+ handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, command->id);
+ break;
+ default:
+ break;
+ }
+
+ if (command->needDelete)
+ delete command;
+
+ return true;
+ }
+
+ static bool HandleRBACPermDenyCommand(ChatHandler* handler, char const* args)
+ {
+ RBACCommandData* command = ReadParams(handler, args);
+
+ if (!command)
+ {
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ RBACCommandResult result = command->rbac->DenyPermission(command->id, command->realmId);
+ RBACPermission const* permission = sAccountMgr->GetRBACPermission(command->id);
+
+ switch (result)
+ {
+ case RBAC_CANT_ADD_ALREADY_ADDED:
+ handler->PSendSysMessage(LANG_RBAC_PERM_DENIED_IN_LIST, command->id, permission->GetName().c_str(),
+ command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str());
+ break;
+ case RBAC_IN_GRANTED_LIST:
+ handler->PSendSysMessage(LANG_RBAC_PERM_DENIED_IN_GRANTED_LIST, command->id, permission->GetName().c_str(),
+ command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str());
+ break;
+ case RBAC_OK:
+ handler->PSendSysMessage(LANG_RBAC_PERM_DENIED, command->id, permission->GetName().c_str(),
+ command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str());
+ break;
+ case RBAC_ID_DOES_NOT_EXISTS:
+ handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, command->id);
+ break;
+ default:
+ break;
+ }
+
+ if (command->needDelete)
+ delete command;
+
+ return true;
+ }
+
+ static bool HandleRBACPermRevokeCommand(ChatHandler* handler, char const* args)
+ {
+ RBACCommandData* command = ReadParams(handler, args);
+
+ if (!command)
+ {
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ RBACCommandResult result = command->rbac->RevokePermission(command->id, command->realmId);
+ RBACPermission const* permission = sAccountMgr->GetRBACPermission(command->id);
+
+ switch (result)
+ {
+ case RBAC_CANT_REVOKE_NOT_IN_LIST:
+ handler->PSendSysMessage(LANG_RBAC_PERM_REVOKED_NOT_IN_LIST, command->id, permission->GetName().c_str(),
+ command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str());
+ break;
+ case RBAC_OK:
+ handler->PSendSysMessage(LANG_RBAC_PERM_REVOKED, command->id, permission->GetName().c_str(),
+ command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str());
+ break;
+ case RBAC_ID_DOES_NOT_EXISTS:
+ handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, command->id);
+ break;
+ default:
+ break;
+ }
+
+ if (command->needDelete)
+ delete command;
+
+ return true;
+ }
+
+ static bool HandleRBACPermListCommand(ChatHandler* handler, char const* args)
+ {
+ RBACCommandData* command = ReadParams(handler, args, false);
+
+ if (!command)
+ {
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ handler->PSendSysMessage(LANG_RBAC_PERM_LIST_HEADER_GRANTED, command->rbac->GetId(), command->rbac->GetName().c_str());
+ RBACPermissionContainer const& granted = command->rbac->GetGrantedPermissions();
+ if (!granted.any())
+ handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_EMPTY));
+ else
+ {
+ for (uint32 i = 0; i < RBAC_PERM_MAX; ++i)
+ if (granted.test(i))
+ {
+ RBACPermission const* permission = sAccountMgr->GetRBACPermission(i);
+ handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, permission->GetId(), permission->GetName().c_str());
+ }
+ }
+
+ handler->PSendSysMessage(LANG_RBAC_PERM_LIST_HEADER_DENIED, command->rbac->GetId(), command->rbac->GetName().c_str());
+ RBACPermissionContainer const& denied = command->rbac->GetDeniedPermissions();
+ if (!denied.any())
+ handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_EMPTY));
+ else
+ {
+ for (uint32 i = 0; i < RBAC_PERM_MAX; ++i)
+ if (denied.test(i))
+ {
+ RBACPermission const* permission = sAccountMgr->GetRBACPermission(i);
+ handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, permission->GetId(), permission->GetName().c_str());
+ }
+ }
+
+ if (command->needDelete)
+ delete command;
+
+ return true;
+ }
+
+ static bool HandleRBACAccountPermissionCommand(ChatHandler* handler, char const* args)
+ {
+ RBACCommandData* command = ReadParams(handler, args, false);
+
+ if (!command)
+ {
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ handler->PSendSysMessage(LANG_RBAC_PERM_LIST_GLOBAL, command->rbac->GetId(), command->rbac->GetName().c_str());
+ RBACPermissionContainer const& permissions = command->rbac->GetPermissions();
+ if (!permissions.any())
+ handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_EMPTY));
+ else
+ {
+ for (uint32 i = 0; i < RBAC_PERM_MAX; ++i)
+ if (permissions.test(i))
+ {
+ RBACPermission const* permission = sAccountMgr->GetRBACPermission(i);
+ handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, permission->GetId(), permission->GetName().c_str());
+ }
+ }
+
+ if (command->needDelete)
+ delete command;
+
+ return true;
+ }
+
+ static bool HandleRBACListGroupsCommand(ChatHandler* handler, char const* args)
+ {
+ uint32 id = 0;
+ if (char* param1 = strtok((char*)args, " "))
+ id = atoi(param1);
+
+ if (!id)
+ {
+ RBACGroupsContainer const& groups = sAccountMgr->GetRBACGroupList();
+ handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_GROUPS_HEADER));
+ for (RBACGroupsContainer::const_iterator it = groups.begin(); it != groups.end(); ++it)
+ {
+ RBACGroup const* group = it->second;
+ handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, group->GetId(), group->GetName().c_str());
+ }
+ }
+ else
+ {
+ RBACGroup const* group = sAccountMgr->GetRBACGroup(id);
+ if (!group)
+ {
+ handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, id);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_GROUPS_HEADER));
+ handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, group->GetId(), group->GetName().c_str());
+ handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_ROLES_HEADER));
+ RBACRoleContainer const& roles = group->GetRoles();
+ if (roles.empty())
+ handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_EMPTY));
+ else
+ {
+ for (RBACRoleContainer::const_iterator it = roles.begin(); it != roles.end(); ++it)
+ {
+ RBACRole const* role = sAccountMgr->GetRBACRole(*it);
+ handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, role->GetId(), role->GetName().c_str());
+ }
+ }
+ }
+
+ return true;
+ }
+
+ static bool HandleRBACListRolesCommand(ChatHandler* handler, char const* args)
+ {
+ uint32 id = 0;
+ if (char* param1 = strtok((char*)args, " "))
+ id = atoi(param1);
+
+ if (!id)
+ {
+ RBACRolesContainer const& roles = sAccountMgr->GetRBACRoleList();
+ handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_ROLES_HEADER));
+ for (RBACRolesContainer::const_iterator it = roles.begin(); it != roles.end(); ++it)
+ {
+ RBACRole const* role = it->second;
+ handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, role->GetId(), role->GetName().c_str());
+ }
+ }
+ else
+ {
+ RBACRole const* role = sAccountMgr->GetRBACRole(id);
+ if (!role)
+ {
+ handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, id);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_ROLES_HEADER));
+ handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, role->GetId(), role->GetName().c_str());
+ handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_PERMISSIONS_HEADER));
+ RBACPermissionContainer const& permissions = role->GetPermissions();
+ if (!permissions.any())
+ handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_EMPTY));
+ else
+ {
+ for (uint32 i = 0; i < RBAC_PERM_MAX; ++i)
+ if (permissions.test(i))
+ {
+ RBACPermission const* permission = sAccountMgr->GetRBACPermission(i);
+ handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, permission->GetId(), permission->GetName().c_str());
+ }
+ }
+ }
+
+ return true;
+ }
+
+ static bool HandleRBACListPermissionsCommand(ChatHandler* handler, char const* args)
+ {
+ uint32 id = 0;
+ if (char* param1 = strtok((char*)args, " "))
+ id = atoi(param1);
+
+ if (!id)
+ {
+ RBACPermissionsContainer const& permissions = sAccountMgr->GetRBACPermissionList();
+ handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_PERMISSIONS_HEADER));
+ for (RBACPermissionsContainer::const_iterator it = permissions.begin(); it != permissions.end(); ++it)
+ {
+ RBACPermission const* permission = it->second;
+ handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, permission->GetId(), permission->GetName().c_str());
+ }
+ }
+ else
+ {
+ RBACPermission const* permission = sAccountMgr->GetRBACPermission(id);
+ if (!permission)
+ {
+ handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, id);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_PERMISSIONS_HEADER));
+ handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, permission->GetId(), permission->GetName().c_str());
+ }
+
+ return true;
+ }
+};
+
+void AddSC_rbac_commandscript()
+{
+ new rbac_commandscript();
+}
diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index acaf7f08f36..74334f192f4 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -1652,68 +1652,6 @@ class spell_gen_oracle_wolvar_reputation : public SpellScriptLoader } }; -class spell_gen_luck_of_the_draw : public SpellScriptLoader -{ - public: - spell_gen_luck_of_the_draw() : SpellScriptLoader("spell_gen_luck_of_the_draw") { } - - class spell_gen_luck_of_the_draw_AuraScript : public AuraScript - { - PrepareAuraScript(spell_gen_luck_of_the_draw_AuraScript); - - bool Load() - { - return GetUnitOwner()->GetTypeId() == TYPEID_PLAYER; - } - - // cheap hax to make it have update calls - void CalcPeriodic(AuraEffect const* /*effect*/, bool& isPeriodic, int32& amplitude) - { - isPeriodic = true; - amplitude = 5 * IN_MILLISECONDS; - } - - void Update(AuraEffect* /*effect*/) - { - if (Player* owner = GetUnitOwner()->ToPlayer()) - { - const LfgDungeonSet dungeons = sLFGMgr->GetSelectedDungeons(owner->GetGUID()); - LfgDungeonSet::const_iterator itr = dungeons.begin(); - - if (itr == dungeons.end()) - { - Remove(AURA_REMOVE_BY_DEFAULT); - return; - } - - - LFGDungeonData const* randomDungeon = sLFGMgr->GetLFGDungeon(*itr); - if (Group* group = owner->GetGroup()) - if (Map const* map = owner->GetMap()) - if (group->isLFGGroup()) - if (uint32 dungeonId = sLFGMgr->GetDungeon(group->GetGUID(), true)) - if (LFGDungeonData const* dungeon = sLFGMgr->GetLFGDungeon(dungeonId)) - if (uint32(dungeon->map) == map->GetId() && dungeon->difficulty == map->GetDifficulty()) - if (randomDungeon && randomDungeon->type == LFG_TYPE_RANDOM) - return; // in correct dungeon - - Remove(AURA_REMOVE_BY_DEFAULT); - } - } - - void Register() - { - DoEffectCalcPeriodic += AuraEffectCalcPeriodicFn(spell_gen_luck_of_the_draw_AuraScript::CalcPeriodic, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE); - OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(spell_gen_luck_of_the_draw_AuraScript::Update, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE); - } - }; - - AuraScript* GetAuraScript() const - { - return new spell_gen_luck_of_the_draw_AuraScript(); - } -}; - enum DummyTrigger { SPELL_PERSISTANT_SHIELD_TRIGGERED = 26470, @@ -3681,7 +3619,6 @@ void AddSC_generic_spell_scripts() new spell_gen_launch(); new spell_gen_vehicle_scaling(); new spell_gen_oracle_wolvar_reputation(); - new spell_gen_luck_of_the_draw(); new spell_gen_dummy_trigger(); new spell_gen_spirit_healer_res(); new spell_gen_gadgetzan_transporter_backfire(); diff --git a/src/server/shared/Database/Implementation/LoginDatabase.cpp b/src/server/shared/Database/Implementation/LoginDatabase.cpp index 227680b2d6b..bbb51cfbde6 100644 --- a/src/server/shared/Database/Implementation/LoginDatabase.cpp +++ b/src/server/shared/Database/Implementation/LoginDatabase.cpp @@ -55,14 +55,15 @@ void LoginDatabaseConnection::DoPrepareStatements() PrepareStatement(LOGIN_DEL_REALM_CHARACTERS, "DELETE FROM realmcharacters WHERE acctid = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_INS_REALM_CHARACTERS, "INSERT INTO realmcharacters (numchars, acctid, realmid) VALUES (?, ?, ?)", CONNECTION_ASYNC); PrepareStatement(LOGIN_SEL_SUM_REALM_CHARACTERS, "SELECT SUM(numchars) FROM realmcharacters WHERE acctid = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_INS_ACCOUNT, "INSERT INTO account(username, sha_pass_hash, joindate) VALUES(?, ?, NOW())", CONNECTION_ASYNC); + PrepareStatement(LOGIN_INS_ACCOUNT, "INSERT INTO account(username, sha_pass_hash, joindate) VALUES(?, ?, NOW())", CONNECTION_SYNCH); PrepareStatement(LOGIN_INS_REALM_CHARACTERS_INIT, "INSERT INTO realmcharacters (realmid, acctid, numchars) SELECT realmlist.id, account.id, 0 FROM realmlist, account LEFT JOIN realmcharacters ON acctid=account.id WHERE acctid IS NULL", CONNECTION_ASYNC); PrepareStatement(LOGIN_UPD_EXPANSION, "UPDATE account SET expansion = ? WHERE id = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_UPD_ACCOUNT_LOCK, "UPDATE account SET locked = ? WHERE id = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_INS_LOG, "INSERT INTO logs (time, realm, type, level, string) VALUES (?, ?, ?, ?, ?)", CONNECTION_ASYNC); PrepareStatement(LOGIN_UPD_USERNAME, "UPDATE account SET v = 0, s = 0, username = ?, sha_pass_hash = ? WHERE id = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_UPD_PASSWORD, "UPDATE account SET v = 0, s = 0, sha_pass_hash = ? WHERE id = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_UPD_MUTE_TIME, "UPDATE account SET mutetime = ? WHERE id = ?", CONNECTION_ASYNC); + PrepareStatement(LOGIN_UPD_MUTE_TIME, "UPDATE account SET mutetime = ? , mutereason = ? , muteby = ? WHERE id = ?", CONNECTION_ASYNC); + PrepareStatement(LOGIN_UPD_MUTE_TIME_LOGIN, "UPDATE account SET mutetime = ? WHERE id = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_UPD_LAST_IP, "UPDATE account SET last_ip = ? WHERE username = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_UPD_ACCOUNT_ONLINE, "UPDATE account SET online = 1 WHERE id = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_UPD_UPTIME_PLAYERS, "UPDATE uptime SET uptime = ?, maxplayers = ? WHERE realmid = ? AND starttime = ?", CONNECTION_ASYNC); @@ -76,7 +77,7 @@ void LoginDatabaseConnection::DoPrepareStatements() PrepareStatement(LOGIN_GET_USERNAME_BY_ID, "SELECT username FROM account WHERE id = ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_CHECK_PASSWORD, "SELECT 1 FROM account WHERE id = ? AND sha_pass_hash = ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_CHECK_PASSWORD_BY_NAME, "SELECT 1 FROM account WHERE username = ? AND sha_pass_hash = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_PINFO, "SELECT a.username, aa.gmlevel, a.email, a.last_ip, DATE_FORMAT(a.last_login, '%Y-%m-%d %T'), a.mutetime FROM account a LEFT JOIN account_access aa ON (a.id = aa.id AND (aa.RealmID = ? OR aa.RealmID = -1)) WHERE a.id = ?", CONNECTION_SYNCH); + PrepareStatement(LOGIN_SEL_PINFO, "SELECT a.username, aa.gmlevel, a.email, a.last_ip, DATE_FORMAT(a.last_login, '%Y-%m-%d %T'), a.mutetime, a.mutereason, a.muteby FROM account a LEFT JOIN account_access aa ON (a.id = aa.id AND (aa.RealmID = ? OR aa.RealmID = -1)) WHERE a.id = ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_PINFO_BANS, "SELECT unbandate, bandate = unbandate, bannedby, banreason FROM account_banned WHERE id = ? AND active ORDER BY bandate ASC LIMIT 1", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_GM_ACCOUNTS, "SELECT a.username, aa.gmlevel FROM account a, account_access aa WHERE a.id=aa.id AND aa.gmlevel >= ? AND (aa.realmid = -1 OR aa.realmid = ?)", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_ACCOUNT_INFO, "SELECT a.username, a.last_ip, aa.gmlevel, a.expansion FROM account a LEFT JOIN account_access aa ON (a.id = aa.id) WHERE a.id = ?", CONNECTION_SYNCH); @@ -87,4 +88,18 @@ void LoginDatabaseConnection::DoPrepareStatements() PrepareStatement(LOGIN_SEL_ACCOUNT_WHOIS, "SELECT username, email, last_ip FROM account WHERE id = ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_REALMLIST_SECURITY_LEVEL, "SELECT allowedSecurityLevel from realmlist WHERE id = ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_DEL_ACCOUNT, "DELETE FROM account WHERE id = ?", CONNECTION_ASYNC); + + PrepareStatement(LOGIN_SEL_ACCOUNT_ACCESS_BY_ID, "SELECT gmlevel, RealmID FROM account_access WHERE id = ? and (RealmID = ? OR RealmID = -1) ORDER BY gmlevel desc", CONNECTION_SYNCH); + + PrepareStatement(LOGIN_SEL_RBAC_ACCOUNT_GROUPS, "SELECT groupId FROM rbac_account_groups WHERE accountId = ? AND (realmId = ? OR realmId = -1) GROUP BY groupId", CONNECTION_SYNCH); + PrepareStatement(LOGIN_INS_RBAC_ACCOUNT_GROUP, "INSERT INTO rbac_account_groups (accountId, groupId, realmId) VALUES (?, ?, ?)", CONNECTION_ASYNC); + PrepareStatement(LOGIN_DEL_RBAC_ACCOUNT_GROUP, "DELETE FROM rbac_account_groups WHERE accountId = ? AND groupId = ? AND (realmId = ? OR realmId = -1)", CONNECTION_ASYNC); + + PrepareStatement(LOGIN_SEL_RBAC_ACCOUNT_ROLES, "SELECT roleId, granted FROM rbac_account_roles WHERE accountId = ? AND (realmId = ? OR realmId = -1) ORDER BY roleId, realmId", CONNECTION_SYNCH); + PrepareStatement(LOGIN_INS_RBAC_ACCOUNT_ROLE, "INSERT INTO rbac_account_roles (accountId, roleId, granted, realmId) VALUES (?, ?, ?, ?) ON DUPLICATE KEY UPDATE granted = VALUES(granted)", CONNECTION_ASYNC); + PrepareStatement(LOGIN_DEL_RBAC_ACCOUNT_ROLE, "DELETE FROM rbac_account_roles WHERE accountId = ? AND roleId = ? AND (realmId = ? OR realmId = -1)", CONNECTION_ASYNC); + + PrepareStatement(LOGIN_SEL_RBAC_ACCOUNT_PERMISSIONS, "SELECT permissionId, granted FROM rbac_account_permissions WHERE accountId = ? AND (realmId = ? OR realmId = -1) ORDER BY permissionId, realmId", CONNECTION_SYNCH); + PrepareStatement(LOGIN_INS_RBAC_ACCOUNT_PERMISSION, "INSERT INTO rbac_account_permissions (accountId, permissionId, granted, realmId) VALUES (?, ?, ?, ?) ON DUPLICATE KEY UPDATE granted = VALUES(granted)", CONNECTION_ASYNC); + PrepareStatement(LOGIN_DEL_RBAC_ACCOUNT_PERMISSION, "DELETE FROM rbac_account_permissions WHERE accountId = ? AND permissionId = ? AND (realmId = ? OR realmId = -1)", CONNECTION_ASYNC); } diff --git a/src/server/shared/Database/Implementation/LoginDatabase.h b/src/server/shared/Database/Implementation/LoginDatabase.h index 798016d553d..939cc4b4790 100644 --- a/src/server/shared/Database/Implementation/LoginDatabase.h +++ b/src/server/shared/Database/Implementation/LoginDatabase.h @@ -83,6 +83,7 @@ enum LoginDatabaseStatements LOGIN_UPD_USERNAME, LOGIN_UPD_PASSWORD, LOGIN_UPD_MUTE_TIME, + LOGIN_UPD_MUTE_TIME_LOGIN, LOGIN_UPD_LAST_IP, LOGIN_UPD_ACCOUNT_ONLINE, LOGIN_UPD_UPTIME_PLAYERS, @@ -108,6 +109,16 @@ enum LoginDatabaseStatements LOGIN_SEL_REALMLIST_SECURITY_LEVEL, LOGIN_DEL_ACCOUNT, + LOGIN_SEL_ACCOUNT_ACCESS_BY_ID, + LOGIN_SEL_RBAC_ACCOUNT_GROUPS, + LOGIN_INS_RBAC_ACCOUNT_GROUP, + LOGIN_DEL_RBAC_ACCOUNT_GROUP, + LOGIN_SEL_RBAC_ACCOUNT_ROLES, + LOGIN_INS_RBAC_ACCOUNT_ROLE, + LOGIN_DEL_RBAC_ACCOUNT_ROLE, + LOGIN_SEL_RBAC_ACCOUNT_PERMISSIONS, + LOGIN_INS_RBAC_ACCOUNT_PERMISSION, + LOGIN_DEL_RBAC_ACCOUNT_PERMISSION, MAX_LOGINDATABASE_STATEMENTS }; diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index 40bd2a443f6..0fc26eae9cd 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -787,18 +787,6 @@ RecruitAFriend.MaxLevel = 80 RecruitAFriend.MaxDifference = 4 # -# InstantLogout -# Description: Required security level for instantly logging out everywhere. -# Does not work while in combat, dueling or falling. -# Default: 1 - (Enabled, Mods/GMs/Admins) -# 0 - (Enabled, Everyone) -# 2 - (Enabled, GMs/Admins) -# 3 - (Enabled, Admins) -# 4 - (Disabled) - -InstantLogout = 1 - -# # DisableWaterBreath # Description: Required security level for water breathing. # Default: 4 - (Disabled) @@ -1542,14 +1530,6 @@ ChatLevelReq.Whisper = 1 ChatLevelReq.Say = 1 # -# AllowPlayerCommands -# Description: Allow players to use commands. -# Default: 1 - (Enabled) -# 0 - (Disabled) - -AllowPlayerCommands = 1 - -# # PreserveCustomChannels # Description: Store custom chat channel settings like password, automatic ownership handout # or ban list in the database. Needs to be enabled to save custom |
