diff options
Diffstat (limited to 'src')
26 files changed, 389 insertions, 101 deletions
diff --git a/src/server/game/Accounts/AccountMgr.cpp b/src/server/game/Accounts/AccountMgr.cpp index 7172efaac0e..83f1252e1f1 100644 --- a/src/server/game/Accounts/AccountMgr.cpp +++ b/src/server/game/Accounts/AccountMgr.cpp @@ -31,14 +31,7 @@ AccountMgr::AccountMgr() AccountMgr::~AccountMgr() { - for (RBACPermissionsContainer::iterator itr = _permissions.begin(); itr != _permissions.end(); ++itr) - delete itr->second; - - for (RBACRolesContainer::iterator itr = _roles.begin(); itr != _roles.end(); ++itr) - delete itr->second; - - for (RBACGroupsContainer::iterator itr = _groups.begin(); itr != _groups.end(); ++itr) - delete itr->second; + ClearRBAC(); } AccountOpResult AccountMgr::CreateAccount(std::string username, std::string password) @@ -337,11 +330,15 @@ bool AccountMgr::IsConsoleAccount(uint32 gmlevel) void AccountMgr::LoadRBAC() { + ClearRBAC(); + + sLog->outInfo(LOG_FILTER_RBAC, "AccountMgr::LoadRBAC"); uint32 oldMSTime = getMSTime(); uint32 count1 = 0; uint32 count2 = 0; uint32 count3 = 0; + sLog->outDebug(LOG_FILTER_RBAC, "AccountMgr::LoadRBAC: Loading permissions"); QueryResult result = LoginDatabase.Query("SELECT id, name FROM rbac_permissions"); if (!result) { @@ -358,6 +355,7 @@ void AccountMgr::LoadRBAC() } while (result->NextRow()); + sLog->outDebug(LOG_FILTER_RBAC, "AccountMgr::LoadRBAC: Loading roles"); result = LoginDatabase.Query("SELECT id, name FROM rbac_roles"); if (!result) { @@ -374,6 +372,7 @@ void AccountMgr::LoadRBAC() } while (result->NextRow()); + sLog->outDebug(LOG_FILTER_RBAC, "AccountMgr::LoadRBAC: Loading role permissions"); result = LoginDatabase.Query("SELECT roleId, permissionId FROM rbac_role_permissions"); if (!result) { @@ -390,6 +389,7 @@ void AccountMgr::LoadRBAC() } while (result->NextRow()); + sLog->outDebug(LOG_FILTER_RBAC, "AccountMgr::LoadRBAC: Loading groups"); result = LoginDatabase.Query("SELECT id, name FROM rbac_groups"); if (!result) { @@ -406,6 +406,7 @@ void AccountMgr::LoadRBAC() } while (result->NextRow()); + sLog->outDebug(LOG_FILTER_RBAC, "AccountMgr::LoadRBAC: Loading group roles"); result = LoginDatabase.Query("SELECT groupId, roleId FROM rbac_group_roles"); if (!result) { @@ -422,6 +423,7 @@ void AccountMgr::LoadRBAC() } while (result->NextRow()); + sLog->outDebug(LOG_FILTER_RBAC, "AccountMgr::LoadRBAC: Loading security level groups"); result = LoginDatabase.Query("SELECT secId, groupId FROM rbac_security_level_groups ORDER by secId ASC"); if (!result) { @@ -445,6 +447,7 @@ void AccountMgr::LoadRBAC() 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)); + sLog->outDebug(LOG_FILTER_RBAC, "AccountMgr::LoadRBAC: Loading default groups"); // Load default groups to be added to any RBAC Object. std::string defaultGroups = ConfigMgr::GetStringDefault("RBAC.DefaultGroups", ""); Tokenizer tokens(defaultGroups, ','); @@ -518,42 +521,68 @@ void AccountMgr::UpdateAccountAccess(RBACData* rbac, uint32 accountId, uint8 sec } } -RBACGroup const* AccountMgr::GetRBACGroup(uint32 group) const +RBACGroup const* AccountMgr::GetRBACGroup(uint32 groupId) const { - RBACGroupsContainer::const_iterator it = _groups.find(group); + sLog->outTrace(LOG_FILTER_RBAC, "AccountMgr::GetRBACGroup: groupId: %u", groupId); + RBACGroupsContainer::const_iterator it = _groups.find(groupId); if (it != _groups.end()) return it->second; return NULL; } -RBACRole const* AccountMgr::GetRBACRole(uint32 role) const +RBACRole const* AccountMgr::GetRBACRole(uint32 roleId) const { - RBACRolesContainer::const_iterator it = _roles.find(role); + sLog->outTrace(LOG_FILTER_RBAC, "AccountMgr::GetRBACRole: roleId: %u", roleId); + RBACRolesContainer::const_iterator it = _roles.find(roleId); if (it != _roles.end()) return it->second; return NULL; } -RBACPermission const* AccountMgr::GetRBACPermission(uint32 permission) const +RBACPermission const* AccountMgr::GetRBACPermission(uint32 permissionId) const { - RBACPermissionsContainer::const_iterator it = _permissions.find(permission); + sLog->outTrace(LOG_FILTER_RBAC, "AccountMgr::GetRBACPermission: roleId: %u", permissionId); + RBACPermissionsContainer::const_iterator it = _permissions.find(permissionId); if (it != _permissions.end()) return it->second; return NULL; } -bool AccountMgr::HasPermission(uint32 accountId, uint32 permission, uint32 realmId) +bool AccountMgr::HasPermission(uint32 accountId, uint32 permissionId, uint32 realmId) { if (!accountId) + { + sLog->outError(LOG_FILTER_RBAC, "AccountMgr::HasPermission: Wrong accountId 0"); return false; + } RBACData* rbac = new RBACData(accountId, "", realmId); rbac->LoadFromDB(); - bool hasPermission = rbac->HasPermission(permission); + bool hasPermission = rbac->HasPermission(permissionId); delete rbac; + sLog->outDebug(LOG_FILTER_RBAC, "AccountMgr::HasPermission [AccountId: %u, PermissionId: %u, realmId: %d]: %u", + accountId, permissionId, realmId, hasPermission); return hasPermission; } + +void AccountMgr::ClearRBAC() +{ + for (RBACPermissionsContainer::iterator itr = _permissions.begin(); itr != _permissions.end(); ++itr) + delete itr->second; + + for (RBACRolesContainer::iterator itr = _roles.begin(); itr != _roles.end(); ++itr) + delete itr->second; + + for (RBACGroupsContainer::iterator itr = _groups.begin(); itr != _groups.end(); ++itr) + delete itr->second; + + _permissions.clear(); + _roles.clear(); + _groups.clear(); + _defaultGroups.clear(); + _defaultSecGroups.clear(); +} diff --git a/src/server/game/Accounts/AccountMgr.h b/src/server/game/Accounts/AccountMgr.h index 28373456994..16b4355585a 100644 --- a/src/server/game/Accounts/AccountMgr.h +++ b/src/server/game/Accounts/AccountMgr.h @@ -82,6 +82,7 @@ class AccountMgr RBACGroupContainer const& GetRBACDefaultGroups() const { return _defaultGroups; } private: + void ClearRBAC(); RBACPermissionsContainer _permissions; RBACRolesContainer _roles; RBACGroupsContainer _groups; diff --git a/src/server/game/Accounts/RBAC.cpp b/src/server/game/Accounts/RBAC.cpp index 121c9faae76..d26d557e2f4 100644 --- a/src/server/game/Accounts/RBAC.cpp +++ b/src/server/game/Accounts/RBAC.cpp @@ -19,21 +19,67 @@ #include "AccountMgr.h"
#include "DatabaseEnv.h"
+void RBACRole::GrantPermission(uint32 permissionId)
+{
+ if (permissionId < RBAC_PERM_MAX)
+ {
+ sLog->outTrace(LOG_FILTER_RBAC, "RBACRole::GrantPermission (Role %u, Permission %u). Ok", GetId(), permissionId);
+ _perms.set(permissionId);
+ }
+ else
+ sLog->outError(LOG_FILTER_RBAC, "RBACRole::GrantPermission (Role %u, Permission %u). Permission not lower than %u",
+ GetId(), permissionId, RBAC_PERM_MAX);
+}
+
+void RBACRole::RevokePermission(uint32 permissionId)
+{
+ if (permissionId < RBAC_PERM_MAX)
+ {
+ sLog->outTrace(LOG_FILTER_RBAC, "RBACRole::RevokePermission (Role %u, Permission %u). Ok", GetId(), permissionId);
+ _perms.reset(permissionId);
+ }
+ else
+ sLog->outError(LOG_FILTER_RBAC, "RBACRole::RevokePermission (Role %u, Permission %u). Permission not lower than %u",
+ GetId(), permissionId, RBAC_PERM_MAX);
+}
+
+void RBACGroup::GrantRole(uint32 roleId)
+{
+ sLog->outTrace(LOG_FILTER_RBAC, "RBACRole::GrantPermission (Role %u, Permission %u). Ok", GetId(), roleId);
+ _roles.insert(roleId);
+}
+
+void RBACGroup::RevokeRole(uint32 roleId)
+{
+ sLog->outTrace(LOG_FILTER_RBAC, "RBACRole::GrantPermission (Role %u, Permission %u). Ok", GetId(), roleId);
+ _roles.erase(roleId);
+}
+
RBACCommandResult RBACData::AddGroup(uint32 groupId, int32 realmId /* = 0 */)
{
// Check if group Id exists
RBACGroup const* group = sAccountMgr->GetRBACGroup(groupId);
if (!group)
+ {
+ sLog->outTrace(LOG_FILTER_RBAC, "RBACData::AddGroup [Id: %u Name: %s] (Group %u, RealmId %d). Group does not exists",
+ GetId(), GetName().c_str(), groupId, realmId);
return RBAC_ID_DOES_NOT_EXISTS;
+ }
// Already added?
std::pair<std::set<uint32>::iterator, bool> ret = _groups.insert(groupId);
if (!ret.second)
+ {
+ sLog->outTrace(LOG_FILTER_RBAC, "RBACData::AddGroup [Id: %u Name: %s] (Group %u, RealmId %d). Group Already added",
+ GetId(), GetName().c_str(), groupId, realmId);
return RBAC_CANT_ADD_ALREADY_ADDED;
+ }
// Do not save to db when loading data from DB (realmId = 0)
if (realmId)
{
+ sLog->outTrace(LOG_FILTER_RBAC, "RBACData::AddGroup [Id: %u Name: %s] (Group %u, RealmId %d). Added and DB updated",
+ GetId(), GetName().c_str(), groupId, realmId);
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_RBAC_ACCOUNT_GROUP);
stmt->setUInt32(0, GetId());
stmt->setUInt32(1, groupId);
@@ -42,6 +88,9 @@ RBACCommandResult RBACData::AddGroup(uint32 groupId, int32 realmId /* = 0 */) CalculateNewPermissions();
}
+ else
+ sLog->outTrace(LOG_FILTER_RBAC, "RBACData::AddGroup [Id: %u Name: %s] (Group %u, RealmId %d). Added",
+ GetId(), GetName().c_str(), groupId, realmId);
return RBAC_OK;
}
@@ -50,11 +99,17 @@ RBACCommandResult RBACData::RemoveGroup(uint32 groupId, int32 realmId /* = 0 */) {
// could remove it?
if (!_groups.erase(groupId))
+ {
+ sLog->outTrace(LOG_FILTER_RBAC, "RBACData::RemoveGroup [Id: %u Name: %s] (Group %u, RealmId %d). Group not in list",
+ GetId(), GetName().c_str(), groupId, realmId);
return RBAC_CANT_REVOKE_NOT_IN_LIST;
+ }
// Do not save to db when loading data from DB (realmId = 0)
if (realmId)
{
+ sLog->outTrace(LOG_FILTER_RBAC, "RBACData::RemoveGroup [Id: %u Name: %s] (Group %u, RealmId %d). Removed and DB updated",
+ GetId(), GetName().c_str(), groupId, realmId);
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_RBAC_ACCOUNT_GROUP);
stmt->setUInt32(0, GetId());
stmt->setUInt32(1, groupId);
@@ -63,6 +118,9 @@ RBACCommandResult RBACData::RemoveGroup(uint32 groupId, int32 realmId /* = 0 */) CalculateNewPermissions();
}
+ else
+ sLog->outTrace(LOG_FILTER_RBAC, "RBACData::RemoveGroup [Id: %u Name: %s] (Group %u, RealmId %d). Removed",
+ GetId(), GetName().c_str(), groupId, realmId);
return RBAC_OK;
}
@@ -72,23 +130,40 @@ RBACCommandResult RBACData::GrantRole(uint32 roleId, int32 realmId /* = 0*/) // Check if role Id exists
RBACRole const* role = sAccountMgr->GetRBACRole(roleId);
if (!role)
+ {
+ sLog->outTrace(LOG_FILTER_RBAC, "RBACData::GrantRole [Id: %u Name: %s] (Role %u, RealmId %d). Role does not exists",
+ GetId(), GetName().c_str(), roleId, realmId);
return RBAC_ID_DOES_NOT_EXISTS;
+ }
// Check if already added in denied list
if (_deniedRoles.find(roleId) != _deniedRoles.end())
+ {
+ sLog->outTrace(LOG_FILTER_RBAC, "RBACData::GrantRole [Id: %u Name: %s] (Role %u, RealmId %d). Role in deny list",
+ GetId(), GetName().c_str(), roleId, realmId);
return RBAC_IN_DENIED_LIST;
+ }
// Already added?
std::pair<std::set<uint32>::iterator, bool> ret = _grantedRoles.insert(roleId);
if (!ret.second)
+ {
+ sLog->outTrace(LOG_FILTER_RBAC, "RBACData::GrantRole [Id: %u Name: %s] (Role %u, RealmId %d). Role already granted",
+ GetId(), GetName().c_str(), roleId, realmId);
return RBAC_CANT_ADD_ALREADY_ADDED;
+ }
// Do not save to db when loading data from DB (realmId = 0)
if (realmId)
{
+ sLog->outTrace(LOG_FILTER_RBAC, "RBACData::GrantRole [Id: %u Name: %s] (Role %u, RealmId %d). Ok and DB updated",
+ GetId(), GetName().c_str(), roleId, realmId);
SaveRole(roleId, true, realmId);
CalculateNewPermissions();
}
+ else
+ sLog->outTrace(LOG_FILTER_RBAC, "RBACData::GrantRole [Id: %u Name: %s] (Role %u, RealmId %d). Ok",
+ GetId(), GetName().c_str(), roleId, realmId);
return RBAC_OK;
}
@@ -98,23 +173,40 @@ RBACCommandResult RBACData::DenyRole(uint32 roleId, int32 realmId /* = 0*/) // Check if role Id exists
RBACRole const* role = sAccountMgr->GetRBACRole(roleId);
if (!role)
+ {
+ sLog->outTrace(LOG_FILTER_RBAC, "RBACData::DenyRole [Id: %u Name: %s] (Role %u, RealmId %d). Role does not exists",
+ GetId(), GetName().c_str(), roleId, realmId);
return RBAC_ID_DOES_NOT_EXISTS;
+ }
// Check if already added in granted list
if (_grantedRoles.find(roleId) != _grantedRoles.end())
+ {
+ sLog->outTrace(LOG_FILTER_RBAC, "RBACData::DenyRole [Id: %u Name: %s] (Role %u, RealmId %d). Role in grant list",
+ GetId(), GetName().c_str(), roleId, realmId);
return RBAC_IN_GRANTED_LIST;
+ }
// Already added?
std::pair<std::set<uint32>::iterator, bool> ret = _deniedRoles.insert(roleId);
if (!ret.second)
+ {
+ sLog->outTrace(LOG_FILTER_RBAC, "RBACData::DenyRole [Id: %u Name: %s] (Role %u, RealmId %d). Role already denied",
+ GetId(), GetName().c_str(), roleId, realmId);
return RBAC_CANT_ADD_ALREADY_ADDED;
+ }
// Do not save to db when loading data from DB (realmId = 0)
if (realmId)
{
+ sLog->outTrace(LOG_FILTER_RBAC, "RBACData::DenyRole [Id: %u Name: %s] (Role %u, RealmId %d). Ok and DB updated",
+ GetId(), GetName().c_str(), roleId, realmId);
SaveRole(roleId, false, realmId);
CalculateNewPermissions();
}
+ else
+ sLog->outTrace(LOG_FILTER_RBAC, "RBACData::DenyRole [Id: %u Name: %s] (Role %u, RealmId %d). Ok",
+ GetId(), GetName().c_str(), roleId, realmId);
return RBAC_OK;
}
@@ -135,11 +227,17 @@ RBACCommandResult RBACData::RevokeRole(uint32 roleId, int32 realmId /* = 0*/) // could remove it?
if (!revoked)
+ {
+ sLog->outTrace(LOG_FILTER_RBAC, "RBACData::RevokeRole [Id: %u Name: %s] (Role %u, RealmId %d). Not granted or revoked",
+ GetId(), GetName().c_str(), roleId, realmId);
return RBAC_CANT_REVOKE_NOT_IN_LIST;
+ }
// Do not save to db when loading data from DB (realmId = 0)
if (realmId)
{
+ sLog->outTrace(LOG_FILTER_RBAC, "RBACData::RevokeRole [Id: %u Name: %s] (Role %u, RealmId %d). Ok and DB updated",
+ GetId(), GetName().c_str(), roleId, realmId);
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_RBAC_ACCOUNT_ROLE);
stmt->setUInt32(0, GetId());
stmt->setUInt32(1, roleId);
@@ -148,6 +246,9 @@ RBACCommandResult RBACData::RevokeRole(uint32 roleId, int32 realmId /* = 0*/) CalculateNewPermissions();
}
+ else
+ sLog->outTrace(LOG_FILTER_RBAC, "RBACData::RevokeRole [Id: %u Name: %s] (Role %u, RealmId %d). Ok",
+ GetId(), GetName().c_str(), roleId, realmId);
return RBAC_OK;
}
@@ -157,24 +258,41 @@ RBACCommandResult RBACData::GrantPermission(uint32 permissionId, int32 realmId / // Check if permission Id exists
RBACPermission const* perm = sAccountMgr->GetRBACPermission(permissionId);
if (!perm)
+ {
+ sLog->outTrace(LOG_FILTER_RBAC, "RBACData::GrantPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Permission does not exists",
+ GetId(), GetName().c_str(), permissionId, realmId);
return RBAC_ID_DOES_NOT_EXISTS;
+ }
// Check if already added in denied list
if (_deniedPerms.test(permissionId))
+ {
+ sLog->outTrace(LOG_FILTER_RBAC, "RBACData::GrantPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Permission in deny list",
+ GetId(), GetName().c_str(), permissionId, realmId);
return RBAC_IN_DENIED_LIST;
+ }
// Already added?
if (_grantedPerms.test(permissionId))
+ {
+ sLog->outTrace(LOG_FILTER_RBAC, "RBACData::GrantPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Permission already granted",
+ GetId(), GetName().c_str(), permissionId, realmId);
return RBAC_CANT_ADD_ALREADY_ADDED;
+ }
_grantedPerms.set(permissionId);
// Do not save to db when loading data from DB (realmId = 0)
if (realmId)
{
+ sLog->outTrace(LOG_FILTER_RBAC, "RBACData::GrantPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Ok and DB updated",
+ GetId(), GetName().c_str(), permissionId, realmId);
SavePermission(permissionId, true, realmId);
CalculateNewPermissions();
}
+ else
+ sLog->outTrace(LOG_FILTER_RBAC, "RBACData::GrantPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Ok",
+ GetId(), GetName().c_str(), permissionId, realmId);
return RBAC_OK;
}
@@ -184,24 +302,41 @@ RBACCommandResult RBACData::DenyPermission(uint32 permissionId, int32 realmId /* // Check if permission Id exists
RBACPermission const* perm = sAccountMgr->GetRBACPermission(permissionId);
if (!perm)
+ {
+ sLog->outTrace(LOG_FILTER_RBAC, "RBACData::DenyPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Permission does not exists",
+ GetId(), GetName().c_str(), permissionId, realmId);
return RBAC_ID_DOES_NOT_EXISTS;
+ }
// Check if already added in granted list
if (_grantedPerms.test(permissionId))
+ {
+ sLog->outTrace(LOG_FILTER_RBAC, "RBACData::DenyPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Permission in grant list",
+ GetId(), GetName().c_str(), permissionId, realmId);
return RBAC_IN_GRANTED_LIST;
+ }
// Already added?
if (_deniedPerms.test(permissionId))
+ {
+ sLog->outTrace(LOG_FILTER_RBAC, "RBACData::DenyPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Permission already denied",
+ GetId(), GetName().c_str(), permissionId, realmId);
return RBAC_CANT_ADD_ALREADY_ADDED;
+ }
_deniedPerms.set(permissionId);
// Do not save to db when loading data from DB (realmId = 0)
if (realmId)
{
+ sLog->outTrace(LOG_FILTER_RBAC, "RBACData::DenyPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Ok and DB updated",
+ GetId(), GetName().c_str(), permissionId, realmId);
SavePermission(permissionId, false, realmId);
CalculateNewPermissions();
}
+ else
+ sLog->outTrace(LOG_FILTER_RBAC, "RBACData::DenyPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Ok",
+ GetId(), GetName().c_str(), permissionId, realmId);
return RBAC_OK;
}
@@ -216,32 +351,44 @@ void RBACData::SavePermission(uint32 permission, bool granted, int32 realmId) LoginDatabase.Execute(stmt);
}
-RBACCommandResult RBACData::RevokePermission(uint32 permission, int32 realmId /* = 0*/)
+RBACCommandResult RBACData::RevokePermission(uint32 permissionId, int32 realmId /* = 0*/)
{
// Check if it's present in any list
- if (!_grantedPerms.test(permission) && !_deniedPerms.test(permission))
+ if (!_grantedPerms.test(permissionId) && !_deniedPerms.test(permissionId))
+ {
+ sLog->outTrace(LOG_FILTER_RBAC, "RBACData::RevokePermission [Id: %u Name: %s] (Permission %u, RealmId %d). Not granted or revoked",
+ GetId(), GetName().c_str(), permissionId, realmId);
return RBAC_CANT_REVOKE_NOT_IN_LIST;
+ }
- _grantedPerms.reset(permission);
- _deniedPerms.reset(permission);
+ _grantedPerms.reset(permissionId);
+ _deniedPerms.reset(permissionId);
// Do not save to db when loading data from DB (realmId = 0)
if (realmId)
{
+ sLog->outTrace(LOG_FILTER_RBAC, "RBACData::RevokePermission [Id: %u Name: %s] (Permission %u, RealmId %d). Ok and DB updated",
+ GetId(), GetName().c_str(), permissionId, realmId);
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_RBAC_ACCOUNT_PERMISSION);
stmt->setUInt32(0, GetId());
- stmt->setUInt32(1, permission);
+ stmt->setUInt32(1, permissionId);
stmt->setInt32(2, realmId);
LoginDatabase.Execute(stmt);
CalculateNewPermissions();
}
+ else
+ sLog->outTrace(LOG_FILTER_RBAC, "RBACData::RevokePermission [Id: %u Name: %s] (Permission %u, RealmId %d). Ok",
+ GetId(), GetName().c_str(), permissionId, realmId);
return RBAC_OK;
}
void RBACData::LoadFromDB()
{
+ sLog->outInfo(LOG_FILTER_RBAC, "RBACData::LoadFromDB [Id: %u Name: %s]", GetId(), GetName().c_str());
+ sLog->outDebug(LOG_FILTER_RBAC, "RBACData::LoadFromDB [Id: %u Name: %s]: Loading groups", GetId(), GetName().c_str());
+
// Load account group that affect current realm
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_RBAC_ACCOUNT_GROUPS);
stmt->setUInt32(0, GetId());
@@ -258,6 +405,7 @@ void RBACData::LoadFromDB() while (result->NextRow());
}
+ sLog->outDebug(LOG_FILTER_RBAC, "RBACData::LoadFromDB [Id: %u Name: %s]: Loading roles", GetId(), GetName().c_str());
// Load account roles (granted and denied) that affect current realm
stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_RBAC_ACCOUNT_ROLES);
stmt->setUInt32(0, GetId());
@@ -277,6 +425,7 @@ void RBACData::LoadFromDB() while (result->NextRow());
}
+ sLog->outDebug(LOG_FILTER_RBAC, "RBACData::LoadFromDB [Id: %u Name: %s]: Loading permissions", GetId(), GetName().c_str());
// Load account permissions (granted and denied) that affect current realm
stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_RBAC_ACCOUNT_PERMISSIONS);
stmt->setUInt32(0, GetId());
@@ -296,11 +445,13 @@ void RBACData::LoadFromDB() while (result->NextRow());
}
+ sLog->outDebug(LOG_FILTER_RBAC, "RBACData::LoadFromDB [Id: %u Name: %s]: Adding default groups", GetId(), GetName().c_str());
// Add default groups
RBACGroupContainer const& groups = sAccountMgr->GetRBACDefaultGroups();
for (RBACGroupContainer::const_iterator itr = groups.begin(); itr != groups.end(); ++itr)
AddGroup(*itr);
+ sLog->outDebug(LOG_FILTER_RBAC, "RBACData::LoadFromDB [Id: %u Name: %s]: Calculating global permissions", GetId(), GetName().c_str());
// Force calculation of permissions, it wasn't performed at load time
// while adding groups, roles and permissions
CalculateNewPermissions();
@@ -308,6 +459,7 @@ void RBACData::LoadFromDB() void RBACData::CalculateNewPermissions()
{
+ sLog->outTrace(LOG_FILTER_RBAC, "RBACData::LoadFromDB [Id: %u Name: %s]: Calculating global permissions", GetId(), GetName().c_str());
// Get the list of directly granted roles
RBACRoleContainer tempGrantedRoles = GetGrantedRoles();
diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h index 0bd193d3841..779b0ece021 100644 --- a/src/server/game/Accounts/RBAC.h +++ b/src/server/game/Accounts/RBAC.h @@ -146,9 +146,9 @@ class RBACRole: public RBACObject /// Gets the Permissions assigned to this role
RBACPermissionContainer const& GetPermissions() const { return _perms; }
/// Grants a Permission (Adds)
- void GrantPermission(uint32 id) { _perms.set(id); }
+ void GrantPermission(uint32 id);
/// Revokes a Permission (Removes)
- void RevokePermission(uint32 id) { _perms.reset(id); }
+ void RevokePermission(uint32 id);
private:
RBACPermissionContainer _perms; ///> Set of permissions
@@ -164,9 +164,9 @@ class RBACGroup: public RBACObject /// Gets the Roles assigned to this group
RBACRoleContainer const& GetRoles() const { return _roles; }
/// Grants a Role (Adds)
- void GrantRole(uint32 role) { _roles.insert(role); }
+ void GrantRole(uint32 role);
/// Revokes a Role (Removes)
- void RevokeRole(uint32 role) { _roles.erase(role); }
+ void RevokeRole(uint32 role);
private:
RBACRoleContainer _roles; ///> Set of Roles
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index da9780a9793..99d796bbb84 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -322,8 +322,8 @@ bool Creature::InitEntry(uint32 Entry, uint32 /*team*/, const CreatureData* data SetByteValue(UNIT_FIELD_BYTES_0, 2, minfo->gender); // Load creature equipment - if (!data || data->equipmentId == 0) // use default from the template - LoadEquipment(GetOriginalEquipmentId()); + if (!data || data->equipmentId == 0) + LoadEquipment(); // use default equipment (if available) else if (data && data->equipmentId != 0) // override, 0 means no equipment { m_originalEquipmentId = data->equipmentId; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index e207c2535d0..948bb240026 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -7705,17 +7705,17 @@ void Player::UpdateArea(uint32 newArea) phaseMgr.AddUpdateFlag(PHASE_UPDATE_FLAG_AREA_UPDATE); AreaTableEntry const* area = GetAreaEntryByAreaID(newArea); - pvpInfo.inFFAPvPArea = area && (area->flags & AREA_FLAG_ARENA); + pvpInfo.IsInFFAPvPArea = area && (area->flags & AREA_FLAG_ARENA); UpdatePvPState(true); UpdateAreaDependentAuras(newArea); // previously this was in UpdateZone (but after UpdateArea) so nothing will break - pvpInfo.inNoPvPArea = false; + pvpInfo.IsInNoPvPArea = false; if (area && area->IsSanctuary()) // in sanctuary { SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY); - pvpInfo.inNoPvPArea = true; + pvpInfo.IsInNoPvPArea = true; CombatStopWithPets(); } else @@ -7774,29 +7774,32 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea) switch (zone->team) { case AREATEAM_ALLY: - pvpInfo.inHostileArea = GetTeam() != ALLIANCE && (sWorld->IsPvPRealm() || zone->flags & AREA_FLAG_CAPITAL); + pvpInfo.IsInHostileArea = GetTeam() != ALLIANCE && (sWorld->IsPvPRealm() || zone->flags & AREA_FLAG_CAPITAL); break; case AREATEAM_HORDE: - pvpInfo.inHostileArea = GetTeam() != HORDE && (sWorld->IsPvPRealm() || zone->flags & AREA_FLAG_CAPITAL); + pvpInfo.IsInHostileArea = GetTeam() != HORDE && (sWorld->IsPvPRealm() || zone->flags & AREA_FLAG_CAPITAL); break; case AREATEAM_NONE: // overwrite for battlegrounds, maybe batter some zone flags but current known not 100% fit to this - pvpInfo.inHostileArea = sWorld->IsPvPRealm() || InBattleground() || zone->flags & AREA_FLAG_WINTERGRASP; + pvpInfo.IsInHostileArea = sWorld->IsPvPRealm() || InBattleground() || zone->flags & AREA_FLAG_WINTERGRASP; break; default: // 6 in fact - pvpInfo.inHostileArea = false; + pvpInfo.IsInHostileArea = false; break; } + // Treat players having a quest flagging for PvP as always in hostile area + pvpInfo.IsHostile = pvpInfo.IsInHostileArea || HasPvPForcingQuest(); + if (zone->flags & AREA_FLAG_CAPITAL) // Is in a capital city { - if (!pvpInfo.inHostileArea || zone->IsSanctuary()) + if (!pvpInfo.IsHostile || zone->IsSanctuary()) { SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING); SetRestType(REST_TYPE_IN_CITY); InnEnter(time(0), GetMapId(), 0, 0, 0); } - pvpInfo.inNoPvPArea = true; + pvpInfo.IsInNoPvPArea = true; } else { @@ -15060,6 +15063,12 @@ void Player::AddQuest(Quest const* quest, Object* questGiver) else questStatusData.Timer = 0; + if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP)) + { + pvpInfo.IsHostile = true; + UpdatePvPState(); + } + SetQuestSlot(log_slot, quest_id, qtime); m_QuestStatusSave[quest_id] = true; @@ -15081,7 +15090,7 @@ void Player::CompleteQuest(uint32 quest_id) if (Quest const* qInfo = sObjectMgr->GetQuestTemplate(quest_id)) { - if (qInfo->HasFlag(QUEST_FLAGS_AUTO_REWARDED)) + if (qInfo->HasFlag(QUEST_FLAGS_TRACKING)) RewardQuest(qInfo, 0, this, false); else SendQuestComplete(qInfo); @@ -15256,6 +15265,12 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver, UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT); UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST, quest->GetQuestId()); + if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP)) + { + pvpInfo.IsHostile = pvpInfo.IsInHostileArea || HasPvPForcingQuest(); + UpdatePvPState(); + } + //lets remove flag for delayed teleports SetCanDelayTeleport(false); } @@ -16587,6 +16602,25 @@ void Player::SendQuestUpdateAddPlayer(Quest const* quest, uint16 old_count, uint SetQuestSlotCounter(log_slot, QUEST_PVP_KILL_SLOT, GetQuestSlotCounter(log_slot, QUEST_PVP_KILL_SLOT) + add_count); } +bool Player::HasPvPForcingQuest() const +{ + for (uint8 i = 0; i < MAX_QUEST_LOG_SIZE; ++i) + { + uint32 questId = GetQuestSlotQuestId(i); + if (questId == 0) + continue; + + Quest const* quest = sObjectMgr->GetQuestTemplate(questId); + if (!quest) + continue; + + if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP)) + return true; + } + + return false; +} + /*********************************************************/ /*** LOAD SYSTEM ***/ /*********************************************************/ @@ -20130,7 +20164,8 @@ void Player::UpdatePvPFlag(time_t currTime) { if (!IsPvP()) return; - if (pvpInfo.endTimer == 0 || currTime < (pvpInfo.endTimer + 300) || pvpInfo.inHostileArea) + + if (!pvpInfo.EndTimer || currTime < (pvpInfo.EndTimer + 300) || pvpInfo.IsHostile) return; UpdatePvP(false); @@ -21745,8 +21780,8 @@ void Player::UpdatePvPState(bool onlyFFA) { // TODO: should we always synchronize UNIT_FIELD_BYTES_2, 1 of controller and controlled? // no, we shouldn't, those are checked for affecting player by client - if (!pvpInfo.inNoPvPArea && !isGameMaster() - && (pvpInfo.inFFAPvPArea || sWorld->IsFFAPvPRealm())) + if (!pvpInfo.IsInNoPvPArea && !isGameMaster() + && (pvpInfo.IsInFFAPvPArea || sWorld->IsFFAPvPRealm())) { if (!HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP)) { @@ -21765,15 +21800,15 @@ void Player::UpdatePvPState(bool onlyFFA) if (onlyFFA) return; - if (pvpInfo.inHostileArea) // in hostile area + if (pvpInfo.IsHostile) // in hostile area { - if (!IsPvP() || pvpInfo.endTimer != 0) + if (!IsPvP() || pvpInfo.EndTimer) UpdatePvP(true, true); } else // in friendly area { - if (IsPvP() && !HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP) && pvpInfo.endTimer == 0) - pvpInfo.endTimer = time(0); // start toggle-off + if (IsPvP() && !HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP) && !pvpInfo.EndTimer) + pvpInfo.EndTimer = time(NULL); // start toggle-off } } @@ -21782,11 +21817,11 @@ void Player::UpdatePvP(bool state, bool override) if (!state || override) { SetPvP(state); - pvpInfo.endTimer = 0; + pvpInfo.EndTimer = 0; } else { - pvpInfo.endTimer = time(NULL); + pvpInfo.EndTimer = time(NULL); SetPvP(state); } } diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 920e0357bc5..6295db693d6 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -403,12 +403,13 @@ struct PlayerInfo struct PvPInfo { - PvPInfo() : inHostileArea(false), inNoPvPArea(false), inFFAPvPArea(false), endTimer(0) {} + PvPInfo() : IsHostile(false), IsInHostileArea(false), IsInNoPvPArea(false), IsInFFAPvPArea(false), EndTimer(0) {} - bool inHostileArea; - bool inNoPvPArea; - bool inFFAPvPArea; - time_t endTimer; + bool IsHostile; + bool IsInHostileArea; ///> Marks if player is in an area which forces PvP flag + bool IsInNoPvPArea; ///> Marks if player is in a sanctuary or friendly capital city + bool IsInFFAPvPArea; ///> Marks if player is in an FFAPvP area (such as Gurubashi Arena) + time_t EndTimer; ///> Time when player unflags himself for PvP (flag removed after 5 minutes) }; struct DuelInfo @@ -518,7 +519,7 @@ enum PlayerFlags PLAYER_FLAGS_UNK16 = 0x00010000, // pre-3.0.3 PLAYER_FLAGS_SANCTUARY flag for player entered sanctuary PLAYER_FLAGS_TAXI_BENCHMARK = 0x00020000, // taxi benchmark mode (on/off) (2.0.1) PLAYER_FLAGS_PVP_TIMER = 0x00040000, // 3.0.2, pvp timer active (after you disable pvp manually) - PLAYER_FLAGS_UNK19 = 0x00080000, + PLAYER_FLAGS_UBER = 0x00080000, PLAYER_FLAGS_UNK20 = 0x00100000, PLAYER_FLAGS_UNK21 = 0x00200000, PLAYER_FLAGS_COMMENTATOR2 = 0x00400000, @@ -1684,6 +1685,8 @@ class Player : public Unit, public GridObject<Player> return count; } + bool HasPvPForcingQuest() const; + /*********************************************************/ /*** LOAD SYSTEM ***/ /*********************************************************/ diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 50b88f3dd27..491b469841c 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -10533,7 +10533,7 @@ bool Unit::_IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell, Wo if (Player const* playerAttacker = ToPlayer()) { - if (playerAttacker->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_UNK19)) + if (playerAttacker->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_UBER)) return false; } // check flags diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 46fec55b820..a29227462ea 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -3643,14 +3643,14 @@ void ObjectMgr::LoadQuests() } } - if (qinfo->Flags & QUEST_FLAGS_AUTO_REWARDED) + if (qinfo->Flags & QUEST_FLAGS_TRACKING) { // at auto-reward can be rewarded only RewardChoiceItemId[0] for (int j = 1; j < QUEST_REWARD_CHOICES_COUNT; ++j ) { if (uint32 id = qinfo->RewardChoiceItemId[j]) { - sLog->outError(LOG_FILTER_SQL, "Quest %u has `RewardChoiceItemId%d` = %u but item from `RewardChoiceItemId%d` can't be rewarded with quest flag QUEST_FLAGS_AUTO_REWARDED.", + sLog->outError(LOG_FILTER_SQL, "Quest %u has `RewardChoiceItemId%d` = %u but item from `RewardChoiceItemId%d` can't be rewarded with quest flag QUEST_FLAGS_TRACKING.", qinfo->GetQuestId(), j+1, id, j+1); // no changes, quest ignore this data } diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index 808e86e15c7..b7b5330921f 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -468,13 +468,13 @@ void WorldSession::HandleTogglePvP(WorldPacket& recvData) if (GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP)) { - if (!GetPlayer()->IsPvP() || GetPlayer()->pvpInfo.endTimer != 0) + if (!GetPlayer()->IsPvP() || GetPlayer()->pvpInfo.EndTimer) GetPlayer()->UpdatePvP(true, true); } else { - if (!GetPlayer()->pvpInfo.inHostileArea && GetPlayer()->IsPvP()) - GetPlayer()->pvpInfo.endTimer = time(NULL); // start toggle-off + if (!GetPlayer()->pvpInfo.IsHostile && GetPlayer()->IsPvP()) + GetPlayer()->pvpInfo.EndTimer = time(NULL); // start toggle-off } //if (OutdoorPvP* pvp = _player->GetOutdoorPvP()) @@ -1321,7 +1321,7 @@ void WorldSession::HandleWhoisOpcode(WorldPacket& recvData) std::string charname; recvData >> charname; - if (HasPermission(RBAC_PERM_OPCODE_WHOIS)) + if (!HasPermission(RBAC_PERM_OPCODE_WHOIS)) { SendNotification(LANG_YOU_NOT_HAVE_PERMISSION); return; diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp index b2971abaeba..dfb2af66833 100644 --- a/src/server/game/Handlers/MovementHandler.cpp +++ b/src/server/game/Handlers/MovementHandler.cpp @@ -174,7 +174,7 @@ void WorldSession::HandleMoveWorldportAckOpcode() GetPlayer()->UpdateZone(newzone, newarea); // honorless target - if (GetPlayer()->pvpInfo.inHostileArea) + if (GetPlayer()->pvpInfo.IsHostile) GetPlayer()->CastSpell(GetPlayer(), 2479, true); // in friendly area @@ -241,7 +241,7 @@ void WorldSession::HandleMoveTeleportAck(WorldPacket& recvPacket) if (old_zone != newzone) { // honorless target - if (plMover->pvpInfo.inHostileArea) + if (plMover->pvpInfo.IsHostile) plMover->CastSpell(plMover, 2479, true); // in friendly area diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp index 78800f77098..76b4ec64380 100644 --- a/src/server/game/Handlers/QuestHandler.cpp +++ b/src/server/game/Handlers/QuestHandler.cpp @@ -438,10 +438,16 @@ void WorldSession::HandleQuestLogRemoveQuest(WorldPacket& recvData) if (!_player->TakeQuestSourceItem(questId, true)) return; // can't un-equip some items, reject quest cancel - if (const Quest *quest = sObjectMgr->GetQuestTemplate(questId)) + if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId)) { if (quest->HasSpecialFlag(QUEST_SPECIAL_FLAGS_TIMED)) _player->RemoveTimedQuest(questId); + + if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP)) + { + _player->pvpInfo.IsHostile = _player->pvpInfo.IsInHostileArea || _player->HasPvPForcingQuest(); + _player->UpdatePvPState(); + } } _player->TakeQuestSourceItem(questId, true); // remove quest src item from player diff --git a/src/server/game/Handlers/TaxiHandler.cpp b/src/server/game/Handlers/TaxiHandler.cpp index 252debb7f63..23b8537e369 100644 --- a/src/server/game/Handlers/TaxiHandler.cpp +++ b/src/server/game/Handlers/TaxiHandler.cpp @@ -266,7 +266,7 @@ void WorldSession::HandleMoveSplineDoneOpcode(WorldPacket& recvData) GetPlayer()->CleanupAfterTaxiFlight(); GetPlayer()->SetFallInformation(0, GetPlayer()->GetPositionZ()); - if (GetPlayer()->pvpInfo.inHostileArea) + if (GetPlayer()->pvpInfo.IsHostile) GetPlayer()->CastSpell(GetPlayer(), 2479, true); } diff --git a/src/server/game/Quests/QuestDef.cpp b/src/server/game/Quests/QuestDef.cpp index b44377e98a8..8d4f3b42e72 100644 --- a/src/server/game/Quests/QuestDef.cpp +++ b/src/server/game/Quests/QuestDef.cpp @@ -316,6 +316,14 @@ void Quest::BuildExtraQuestInfo(WorldPacket& data, Player* player) const data << uint32(GetRewardSkillPoints()); } +uint32 Quest::GetRewMoneyMaxLevel() const +{ + if (HasFlag(QUEST_FLAGS_NO_MONEY_FROM_XP)) + return 0; + + return RewardMoneyMaxLevel; +} + bool Quest::IsAutoAccept() const { return sWorld->getBoolConfig(CONFIG_QUEST_IGNORE_AUTO_ACCEPT) ? false : (Flags & QUEST_FLAGS_AUTO_ACCEPT); diff --git a/src/server/game/Quests/QuestDef.h b/src/server/game/Quests/QuestDef.h index 28e81bfe551..34c0a1fd9d8 100644 --- a/src/server/game/Quests/QuestDef.h +++ b/src/server/game/Quests/QuestDef.h @@ -127,34 +127,32 @@ enum __QuestGiverStatus enum QuestFlags { - // Flags used at server and sent to client - QUEST_FLAGS_NONE = 0x00000000, - QUEST_FLAGS_STAY_ALIVE = 0x00000001, // Not used currently - QUEST_FLAGS_PARTY_ACCEPT = 0x00000002, // Not used currently. If player in party, all players that can accept this quest will receive confirmation box to accept quest CMSG_QUEST_CONFIRM_ACCEPT/SMSG_QUEST_CONFIRM_ACCEPT - QUEST_FLAGS_EXPLORATION = 0x00000004, // Not used currently - QUEST_FLAGS_SHARABLE = 0x00000008, // Can be shared: Player::CanShareQuest() - //QUEST_FLAGS_NONE2 = 0x00000010, // Not used currently - QUEST_FLAGS_EPIC = 0x00000020, // Not used currently: Unsure of content - QUEST_FLAGS_RAID = 0x00000040, // Not used currently - QUEST_FLAGS_TBC = 0x00000080, // Not used currently: Available if TBC expansion enabled only - QUEST_FLAGS_DELIVER_MORE = 0x00000100, // Not used currently: _DELIVER_MORE Quest needs more than normal _q-item_ drops from mobs - QUEST_FLAGS_HIDDEN_REWARDS = 0x00000200, // Items and money rewarded only sent in SMSG_QUESTGIVER_OFFER_REWARD (not in SMSG_QUESTGIVER_QUEST_DETAILS or in client quest log(SMSG_QUEST_QUERY_RESPONSE)) - QUEST_FLAGS_AUTO_REWARDED = 0x00000400, // These quests are automatically rewarded on quest complete and they will never appear in quest log client side. - QUEST_FLAGS_TBC_RACES = 0x00000800, // Not used currently: Blood elf/Draenei starting zone quests - QUEST_FLAGS_DAILY = 0x00001000, // Used to know quest is Daily one - QUEST_FLAGS_REPEATABLE = 0x00002000, // Used on repeatable quests (3.0.0+) - QUEST_FLAGS_UNAVAILABLE = 0x00004000, // Used on quests that are not generically available - QUEST_FLAGS_WEEKLY = 0x00008000, - QUEST_FLAGS_AUTOCOMPLETE = 0x00010000, // auto complete - QUEST_FLAGS_SPECIAL_ITEM = 0x00020000, // has something to do with RequiredItemId and SourceItemId - QUEST_FLAGS_OBJ_TEXT = 0x00040000, // use Objective text as Complete text - QUEST_FLAGS_AUTO_ACCEPT = 0x00080000, // The client recognizes this flag as auto-accept. However, NONE of the current quests (3.3.5a) have this flag. Maybe blizz used to use it, or will use it in the future. - QUEST_FLAGS_AUTO_SUBMIT = 0x00100000, // Quests with this flag player submit automatically by special button in player gui - QUEST_FLAGS_AUTO_TAKE = 0x00200000, // Automatically suggestion of accepting quest. Not from npc. - //QUEST_FLAGS_UNK2 = 0x00400000, - //QUEST_FLAGS_UNK3 = 0x00800000, // Found in quest 14069 - //QUEST_FLAGS_UNK4 = 0x01000000, - + QUEST_FLAGS_NONE = 0x00000000, + QUEST_FLAGS_STAY_ALIVE = 0x00000001, // Not used currently + QUEST_FLAGS_PARTY_ACCEPT = 0x00000002, // Not used currently. If player in party, all players that can accept this quest will receive confirmation box to accept quest CMSG_QUEST_CONFIRM_ACCEPT/SMSG_QUEST_CONFIRM_ACCEPT + QUEST_FLAGS_EXPLORATION = 0x00000004, // Not used currently + QUEST_FLAGS_SHARABLE = 0x00000008, // Can be shared: Player::CanShareQuest() + QUEST_FLAGS_HAS_CONDITION = 0x00000010, // Not used currently + QUEST_FLAGS_HIDE_REWARD_POI = 0x00000020, // Not used currently: Unsure of content + QUEST_FLAGS_RAID = 0x00000040, // Not used currently + QUEST_FLAGS_TBC = 0x00000080, // Not used currently: Available if TBC expansion enabled only + QUEST_FLAGS_NO_MONEY_FROM_XP = 0x00000100, // Not used currently: Experience is not converted to gold at max level + QUEST_FLAGS_HIDDEN_REWARDS = 0x00000200, // Items and money rewarded only sent in SMSG_QUESTGIVER_OFFER_REWARD (not in SMSG_QUESTGIVER_QUEST_DETAILS or in client quest log(SMSG_QUEST_QUERY_RESPONSE)) + QUEST_FLAGS_TRACKING = 0x00000400, // These quests are automatically rewarded on quest complete and they will never appear in quest log client side. + QUEST_FLAGS_DEPRECATE_REPUTATION = 0x00000800, // Not used currently + QUEST_FLAGS_DAILY = 0x00001000, // Used to know quest is Daily one + QUEST_FLAGS_FLAGS_PVP = 0x00002000, // Having this quest in log forces PvP flag + QUEST_FLAGS_UNAVAILABLE = 0x00004000, // Used on quests that are not generically available + QUEST_FLAGS_WEEKLY = 0x00008000, + QUEST_FLAGS_AUTOCOMPLETE = 0x00010000, // auto complete + QUEST_FLAGS_DISPLAY_ITEM_IN_TRACKER = 0x00020000, // Displays usable item in quest tracker + QUEST_FLAGS_OBJ_TEXT = 0x00040000, // use Objective text as Complete text + QUEST_FLAGS_AUTO_ACCEPT = 0x00080000, // The client recognizes this flag as auto-accept. However, NONE of the current quests (3.3.5a) have this flag. Maybe blizz used to use it, or will use it in the future. + QUEST_FLAGS_AUTO_SUBMIT = 0x00100000, // Quests with this flag player submit automatically by special button in player gui + QUEST_FLAGS_AUTO_TAKE = 0x00200000, // Automatically suggestion of accepting quest. Not from npc. + //QUEST_FLAGS_UNK2 = 0x00400000, + //QUEST_FLAGS_UNK3 = 0x00800000, // Found in quest 14069 + //QUEST_FLAGS_UNK4 = 0x01000000, // ... 4.x added flags up to 0x80000000 - all unknown for now }; @@ -261,7 +259,7 @@ class Quest int32 GetRewOrReqMoney() const; uint32 GetRewHonorAddition() const { return RewardHonor; } float GetRewHonorMultiplier() const { return RewardHonorMultiplier; } - uint32 GetRewMoneyMaxLevel() const { return RewardMoneyMaxLevel; } // use in XP calculation at client + uint32 GetRewMoneyMaxLevel() const; // use in XP calculation at client uint32 GetRewSpell() const { return RewardSpell; } int32 GetRewSpellCast() const { return RewardSpellCast; } uint32 GetRewMailTemplateId() const { return RewardMailTemplateId; } diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index dd186c498a9..9efad4664aa 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -1127,11 +1127,13 @@ 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 = new RBACData(id, name, realmID); _RBACData->LoadFromDB(); + + sLog->outDebug(LOG_FILTER_RBAC, "WorldSession::LoadPermissions [AccountId: %u, Name: %s, realmId: %d]", + id, name.c_str(), realmID); } RBACData* WorldSession::GetRBACData() @@ -1141,5 +1143,20 @@ RBACData* WorldSession::GetRBACData() bool WorldSession::HasPermission(uint32 permission) { - return _RBACData->HasPermission(permission); + if (!_RBACData) + LoadPermissions(); + + bool hasPermission = _RBACData->HasPermission(permission); + sLog->outDebug(LOG_FILTER_RBAC, "WorldSession::HasPermission [AccountId: %u, Name: %s, realmId: %d]", + _RBACData->GetId(), _RBACData->GetName().c_str(), realmID); + + return hasPermission; +} + +void WorldSession::InvalidateRBACData() +{ + sLog->outDebug(LOG_FILTER_RBAC, "WorldSession::InvalidateRBACData [AccountId: %u, Name: %s, realmId: %d]", + _RBACData->GetId(), _RBACData->GetName().c_str(), realmID); + delete _RBACData; + _RBACData = NULL; } diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 24917b368fc..c4a918c227a 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -225,6 +225,7 @@ class WorldSession RBACData* GetRBACData(); bool HasPermission(uint32 permissionId); void LoadPermissions(); + void InvalidateRBACData(); // Used to force LoadPermissions at next HasPermission check AccountTypes GetSecurity() const { return _security; } uint32 GetAccountId() const { return _accountId; } diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index fc2da0d199c..c4dc26507f3 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -4754,6 +4754,12 @@ void Spell::EffectQuestClear(SpellEffIndex effIndex) // we ignore unequippable quest items in this case, it's still be equipped player->TakeQuestSourceItem(logQuest, false); + + if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP)) + { + player->pvpInfo.IsHostile = player->pvpInfo.IsInHostileArea || player->HasPvPForcingQuest(); + player->UpdatePvPState(); + } } } diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 93c336c811c..8624dda37a7 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -3245,3 +3245,11 @@ void World::UpdatePhaseDefinitions() if (itr->second && itr->second->GetPlayer() && itr->second->GetPlayer()->IsInWorld()) itr->second->GetPlayer()->GetPhaseMgr().NotifyStoresReloaded(); } + +void World::ReloadRBAC() +{ + sLog->outInfo(LOG_FILTER_RBAC, "World::ReloadRBAC()"); + for (SessionMap::const_iterator itr = m_sessions.begin(); itr != m_sessions.end(); ++itr) + if (WorldSession* session = itr->second) + session->InvalidateRBACData(); +} diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index e65eaf73983..5c728d34a2b 100644 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -761,6 +761,8 @@ class World void ResetEventSeasonalQuests(uint16 event_id); void UpdatePhaseDefinitions(); + void ReloadRBAC(); + protected: void _UpdateGameTime(); // callback for UpdateRealmCharacters diff --git a/src/server/scripts/Commands/cs_quest.cpp b/src/server/scripts/Commands/cs_quest.cpp index e10cf883518..e0d67b55989 100644 --- a/src/server/scripts/Commands/cs_quest.cpp +++ b/src/server/scripts/Commands/cs_quest.cpp @@ -138,6 +138,12 @@ public: // we ignore unequippable quest items in this case, its' still be equipped player->TakeQuestSourceItem(logQuest, false); + + if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP)) + { + player->pvpInfo.IsHostile = player->pvpInfo.IsInHostileArea || player->HasPvPForcingQuest(); + player->UpdatePvPState(); + } } } diff --git a/src/server/scripts/Commands/cs_reload.cpp b/src/server/scripts/Commands/cs_reload.cpp index ef1af6c544f..76045a249be 100644 --- a/src/server/scripts/Commands/cs_reload.cpp +++ b/src/server/scripts/Commands/cs_reload.cpp @@ -22,6 +22,7 @@ Comment: All reload related commands Category: commandscripts EndScriptData */ +#include "AccountMgr.h" #include "AchievementMgr.h" #include "AuctionHouseMgr.h" #include "Chat.h" @@ -123,6 +124,7 @@ public: { "prospecting_loot_template", SEC_ADMINISTRATOR, true, &HandleReloadLootTemplatesProspectingCommand, "", NULL }, { "quest_poi", SEC_ADMINISTRATOR, true, &HandleReloadQuestPOICommand, "", NULL }, { "quest_template", SEC_ADMINISTRATOR, true, &HandleReloadQuestTemplateCommand, "", NULL }, + { "rbac", SEC_ADMINISTRATOR, true, &HandleReloadRBACCommand, "", NULL }, { "reference_loot_template", SEC_ADMINISTRATOR, true, &HandleReloadLootTemplatesReferenceCommand, "", NULL }, { "reserved_name", SEC_ADMINISTRATOR, true, &HandleReloadReservedNameCommand, "", NULL }, { "reputation_reward_rate", SEC_ADMINISTRATOR, true, &HandleReloadReputationRewardRateCommand, "", NULL }, @@ -1197,6 +1199,7 @@ public: return true; } + static bool HandleReloadPhaseDefinitionsCommand(ChatHandler* handler, const char* /*args*/) { sLog->outInfo(LOG_FILTER_GENERAL, "Reloading phase_definitions table..."); @@ -1205,6 +1208,15 @@ public: handler->SendGlobalGMSysMessage("Phase Definitions reloaded."); return true; } + + static bool HandleReloadRBACCommand(ChatHandler* handler, const char* /*args*/) + { + sLog->outInfo(LOG_FILTER_GENERAL, "Reloading RBAC tables..."); + sAccountMgr->LoadRBAC(); + sWorld->ReloadRBAC(); + handler->SendGlobalGMSysMessage("RBAC data reloaded."); + return true; + } }; void AddSC_reload_commandscript() diff --git a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_ebonroc.cpp b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_ebonroc.cpp index a9b41b719f7..d1670171d67 100644 --- a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_ebonroc.cpp +++ b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_ebonroc.cpp @@ -74,32 +74,32 @@ public: //Shadowflame Timer if (ShadowFlame_Timer <= diff) { - DoCast(me->getVictim(), SPELL_SHADOWFLAME); + DoCastVictim(SPELL_SHADOWFLAME); ShadowFlame_Timer = urand(12000, 15000); } else ShadowFlame_Timer -= diff; //Thrash Timer if (Thrash_Timer <= diff) { - DoCast(me->getVictim(), SPELL_THRASH); + DoCastVictim(SPELL_THRASH); Thrash_Timer = urand(10000, 15000); } else Thrash_Timer -= diff; //Wing Buffet Timer if (WingBuffet_Timer <= diff) { - DoCast(me->getVictim(), SPELL_WINGBUFFET); + DoCastVictim(SPELL_WINGBUFFET); WingBuffet_Timer = 25000; } else WingBuffet_Timer -= diff; //Shadow of Ebonroc Timer if (ShadowOfEbonroc_Timer <= diff) { - DoCast(me->getVictim(), SPELL_SHADOWOFEBONROC); + DoCastVictim(SPELL_SHADOWOFEBONROC); ShadowOfEbonroc_Timer = urand(25000, 350000); } else ShadowOfEbonroc_Timer -= diff; - if (me->getVictim()->HasAura(SPELL_SHADOWOFEBONROC)) + if (me->getVictim() && me->getVictim()->HasAura(SPELL_SHADOWOFEBONROC)) { if (Heal_Timer <= diff) { diff --git a/src/server/shared/Logging/Appender.cpp b/src/server/shared/Logging/Appender.cpp index 1d215e1212e..efb141d1060 100644 --- a/src/server/shared/Logging/Appender.cpp +++ b/src/server/shared/Logging/Appender.cpp @@ -216,6 +216,8 @@ char const* Appender::getLogFilterTypeString(LogFilterType type) return "OPCODE"; case LOG_FILTER_SOAP: return "SOAP"; + case LOG_FILTER_RBAC: + return "RBAC"; default: break; } diff --git a/src/server/shared/Logging/Appender.h b/src/server/shared/Logging/Appender.h index 08628948b90..e11bc40c42f 100644 --- a/src/server/shared/Logging/Appender.h +++ b/src/server/shared/Logging/Appender.h @@ -67,7 +67,8 @@ enum LogFilterType LOG_FILTER_BATTLEFIELD = 39, LOG_FILTER_SERVER_LOADING = 40, LOG_FILTER_OPCODES = 41, - LOG_FILTER_SOAP = 42 + LOG_FILTER_SOAP = 42, + LOG_FILTER_RBAC = 43 }; const uint8 MaxLogFilter = 43; diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index 96ad754a007..56d22355f09 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -2757,6 +2757,7 @@ Appenders=Console Server GM DBErrors Char RA Warden Chat # 40 - Server Loading # 41 - Opcodes (just id and name sent / received) # 42 - SOAP +# 43 - RBAC (Role Based Access Control) # # LogLevel # 0 - (Disabled) |