aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/AI/CreatureAIImpl.h30
-rw-r--r--src/server/game/Accounts/AccountMgr.cpp217
-rw-r--r--src/server/game/Accounts/AccountMgr.h27
-rw-r--r--src/server/game/Accounts/RBAC.cpp336
-rw-r--r--src/server/game/Accounts/RBAC.h410
-rw-r--r--src/server/game/Chat/Chat.cpp25
-rw-r--r--src/server/game/DungeonFinding/LFG.cpp108
-rw-r--r--src/server/game/DungeonFinding/LFG.h9
-rw-r--r--src/server/game/DungeonFinding/LFGGroupData.cpp5
-rw-r--r--src/server/game/DungeonFinding/LFGGroupData.h5
-rw-r--r--src/server/game/DungeonFinding/LFGMgr.cpp171
-rw-r--r--src/server/game/DungeonFinding/LFGMgr.h173
-rw-r--r--src/server/game/DungeonFinding/LFGPlayerData.cpp5
-rw-r--r--src/server/game/DungeonFinding/LFGPlayerData.h5
-rw-r--r--src/server/game/DungeonFinding/LFGQueue.cpp11
-rw-r--r--src/server/game/DungeonFinding/LFGQueue.h5
-rw-r--r--src/server/game/DungeonFinding/LFGScripts.cpp23
-rw-r--r--src/server/game/DungeonFinding/LFGScripts.h6
-rw-r--r--src/server/game/Entities/Player/Player.cpp51
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp2
-rw-r--r--src/server/game/Groups/Group.cpp2
-rw-r--r--src/server/game/Handlers/LFGHandler.cpp125
-rw-r--r--src/server/game/Handlers/MiscHandler.cpp2
-rw-r--r--src/server/game/Maps/Map.cpp8
-rw-r--r--src/server/game/Miscellaneous/Language.h35
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp5
-rw-r--r--src/server/game/Scripting/ScriptLoader.cpp2
-rw-r--r--src/server/game/Scripting/ScriptMgr.cpp2
-rw-r--r--src/server/game/Scripting/ScriptMgr.h3
-rw-r--r--src/server/game/Server/WorldSession.cpp29
-rw-r--r--src/server/game/Server/WorldSession.h29
-rw-r--r--src/server/game/Server/WorldSocket.cpp3
-rw-r--r--src/server/game/World/World.cpp7
-rw-r--r--src/server/scripts/Commands/CMakeLists.txt1
-rw-r--r--src/server/scripts/Commands/cs_account.cpp34
-rw-r--r--src/server/scripts/Commands/cs_lfg.cpp10
-rw-r--r--src/server/scripts/Commands/cs_misc.cpp72
-rw-r--r--src/server/scripts/Commands/cs_rbac.cpp780
-rw-r--r--src/server/scripts/Spells/spell_generic.cpp63
-rw-r--r--src/server/shared/Database/Implementation/LoginDatabase.cpp21
-rw-r--r--src/server/shared/Database/Implementation/LoginDatabase.h11
-rw-r--r--src/server/worldserver/worldserver.conf.dist20
42 files changed, 2408 insertions, 480 deletions
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