aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/AI/CoreAI/UnitAI.cpp3
-rw-r--r--src/server/game/Accounts/AccountMgr.cpp13
-rw-r--r--src/server/game/Accounts/AccountMgr.h1
-rw-r--r--src/server/game/Accounts/RBAC.h57
-rw-r--r--src/server/game/AuctionHouse/AuctionHouseMgr.cpp47
-rw-r--r--src/server/game/Chat/Channels/Channel.cpp53
-rw-r--r--src/server/game/Chat/Chat.cpp5
-rw-r--r--src/server/game/Conditions/ConditionMgr.cpp1
-rw-r--r--src/server/game/DungeonFinding/LFGMgr.cpp1
-rw-r--r--src/server/game/Entities/Creature/TemporarySummon.h1
-rw-r--r--src/server/game/Entities/Pet/Pet.cpp12
-rw-r--r--src/server/game/Entities/Player/Player.cpp15
-rw-r--r--src/server/game/Entities/Player/SocialMgr.cpp71
-rw-r--r--src/server/game/Entities/Unit/StatSystem.cpp14
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp6
-rw-r--r--src/server/game/Entities/Unit/Unit.h1
-rw-r--r--src/server/game/Globals/ObjectMgr.h4
-rw-r--r--src/server/game/Guilds/Guild.cpp7
-rw-r--r--src/server/game/Handlers/AuctionHouseHandler.cpp4
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp81
-rw-r--r--src/server/game/Handlers/ChatHandler.cpp24
-rw-r--r--src/server/game/Handlers/MailHandler.cpp138
-rw-r--r--src/server/game/Handlers/MiscHandler.cpp49
-rw-r--r--src/server/game/Handlers/TradeHandler.cpp11
-rw-r--r--src/server/game/Miscellaneous/SharedDefines.h4
-rw-r--r--src/server/game/Server/WorldSession.cpp1
-rw-r--r--src/server/game/Server/WorldSession.h2
-rw-r--r--src/server/game/Server/WorldSocket.cpp2
-rw-r--r--src/server/game/Spells/Spell.cpp7
-rw-r--r--src/server/game/Spells/SpellEffects.cpp6
-rw-r--r--src/server/game/Spells/SpellInfo.cpp6
-rw-r--r--src/server/game/World/World.cpp37
-rw-r--r--src/server/scripts/Commands/cs_gm.cpp46
-rw-r--r--src/server/scripts/Commands/cs_misc.cpp8
-rw-r--r--src/server/scripts/Commands/cs_rbac.cpp4
-rw-r--r--src/server/scripts/Commands/cs_ticket.cpp12
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp2
-rw-r--r--src/server/scripts/World/areatrigger_scripts.cpp10
-rw-r--r--src/server/shared/Database/DatabaseWorkerPool.h14
-rw-r--r--src/server/worldserver/TCSoap/TCSoap.cpp3
-rw-r--r--src/server/worldserver/TCSoap/TCSoap.h10
41 files changed, 446 insertions, 347 deletions
diff --git a/src/server/game/AI/CoreAI/UnitAI.cpp b/src/server/game/AI/CoreAI/UnitAI.cpp
index 7f0d387c2f1..e0e9e68315d 100644
--- a/src/server/game/AI/CoreAI/UnitAI.cpp
+++ b/src/server/game/AI/CoreAI/UnitAI.cpp
@@ -146,8 +146,7 @@ void UnitAI::DoCast(uint32 spellId)
float range = spellInfo->GetMaxRange(false);
DefaultTargetSelector targetSelector(me, range, playerOnly, -(int32)spellId);
- if (!(spellInfo->Attributes & SPELL_ATTR0_BREAKABLE_BY_DAMAGE)
- && !(spellInfo->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_VICTIM)
+ if (!(spellInfo->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_VICTIM)
&& targetSelector(me->getVictim()))
target = me->getVictim();
else
diff --git a/src/server/game/Accounts/AccountMgr.cpp b/src/server/game/Accounts/AccountMgr.cpp
index 596f7f5ceb9..7172efaac0e 100644
--- a/src/server/game/Accounts/AccountMgr.cpp
+++ b/src/server/game/Accounts/AccountMgr.cpp
@@ -544,3 +544,16 @@ RBACPermission const* AccountMgr::GetRBACPermission(uint32 permission) const
return NULL;
}
+
+bool AccountMgr::HasPermission(uint32 accountId, uint32 permission, uint32 realmId)
+{
+ if (!accountId)
+ return false;
+
+ RBACData* rbac = new RBACData(accountId, "", realmId);
+ rbac->LoadFromDB();
+ bool hasPermission = rbac->HasPermission(permission);
+ delete rbac;
+
+ return hasPermission;
+}
diff --git a/src/server/game/Accounts/AccountMgr.h b/src/server/game/Accounts/AccountMgr.h
index 2c07172723d..28373456994 100644
--- a/src/server/game/Accounts/AccountMgr.h
+++ b/src/server/game/Accounts/AccountMgr.h
@@ -67,6 +67,7 @@ class AccountMgr
static bool IsGMAccount(uint32 gmlevel);
static bool IsAdminAccount(uint32 gmlevel);
static bool IsConsoleAccount(uint32 gmlevel);
+ static bool HasPermission(uint32 accountId, uint32 permission, uint32 realmId);
void UpdateAccountAccess(RBACData* rbac, uint32 accountId, uint8 securityLevel, int32 realmId);
diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h
index f6e494e7b70..0bd193d3841 100644
--- a/src/server/game/Accounts/RBAC.h
+++ b/src/server/game/Accounts/RBAC.h
@@ -48,16 +48,53 @@
enum RBACPermissions
{
- RBAC_PERM_INSTANT_LOGOUT = 1,
- RBAC_PERM_SKIP_QUEUE,
- RBAC_PERM_JOIN_NORMAL_BG,
- RBAC_PERM_JOIN_RANDOM_BG,
- RBAC_PERM_JOIN_ARENAS,
- RBAC_PERM_JOIN_DUNGEON_FINDER,
- RBAC_PERM_PLAYER_COMMANDS,
- RBAC_PERM_MODERATOR_COMMANDS,
- RBAC_PERM_GAMEMASTER_COMMANDS,
- RBAC_PERM_ADMINISTRATOR_COMMANDS,
+ RBAC_PERM_INSTANT_LOGOUT = 1,
+ RBAC_PERM_SKIP_QUEUE = 2,
+ RBAC_PERM_JOIN_NORMAL_BG = 3,
+ RBAC_PERM_JOIN_RANDOM_BG = 4,
+ RBAC_PERM_JOIN_ARENAS = 5,
+ RBAC_PERM_JOIN_DUNGEON_FINDER = 6,
+ RBAC_PERM_PLAYER_COMMANDS = 7,
+ RBAC_PERM_MODERATOR_COMMANDS = 8,
+ RBAC_PERM_GAMEMASTER_COMMANDS = 9,
+ RBAC_PERM_ADMINISTRATOR_COMMANDS = 10,
+ RBAC_PERM_LOG_GM_TRADE = 11,
+ // Free = 12
+ RBAC_PERM_SKIP_CHECK_INSTANCE_REQUIRED_BOSSES = 13,
+ RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_TEAMMASK = 14,
+ RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_CLASSMASK = 15,
+ RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RACEMASK = 16,
+ RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME = 17,
+ RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_HEROIC_CHARACTER = 18,
+ RBAC_PERM_SKIP_CHECK_CHAT_CHANNEL_REQ = 19,
+ RBAC_PERM_SKIP_CHECK_DISABLE_MAP = 20,
+ RBAC_PERM_SKIP_CHECK_MORE_TALENTS_THAN_ALLOWED = 21,
+ RBAC_PERM_SKIP_CHECK_CHAT_SPAM = 22,
+ RBAC_PERM_SKIP_CHECK_OVERSPEED_PING = 23,
+ RBAC_PERM_TWO_SIDE_CHARACTER_CREATION = 24,
+ RBAC_PERM_TWO_SIDE_INTERACTION_CHAT = 25,
+ RBAC_PERM_TWO_SIDE_INTERACTION_CHANNEL = 26,
+ RBAC_PERM_TWO_SIDE_INTERACTION_MAIL = 27,
+ RBAC_PERM_TWO_SIDE_WHO_LIST = 28,
+ RBAC_PERM_TWO_SIDE_ADD_FRIEND = 29,
+ RBAC_PERM_COMMANDS_SAVE_WITHOUT_DELAY = 30,
+ RBAC_PERM_COMMANDS_USE_UNSTUCK_WITH_ARGS = 31,
+ RBAC_PERM_COMMANDS_BE_ASSIGNED_TICKET = 32,
+ RBAC_PERM_COMMANDS_NOTIFY_COMMAND_NOT_FOUND_ERROR = 33,
+ RBAC_PERM_COMMANDS_APPEAR_IN_GM_LIST = 34,
+ RBAC_PERM_WHO_SEE_ALL_SEC_LEVELS = 35,
+ RBAC_PERM_CAN_FILTER_WHISPERS = 36,
+ RBAC_PERM_CHAT_USE_STAFF_BADGE = 37,
+ RBAC_PERM_RESURRECT_WITH_FULL_HPS = 38,
+ RBAC_PERM_RESTORE_SAVED_GM_STATE = 39,
+ RBAC_PERM_ALLOW_GM_FRIEND = 40,
+ RBAC_PERM_USE_START_GM_LEVEL = 41,
+ RBAC_PERM_OPCODE_WORLD_TELEPORT = 42,
+ RBAC_PERM_OPCODE_WHOIS = 43,
+ RBAC_PERM_RECEIVE_GLOBAL_GM_TEXTMESSAGE = 44,
+ RBAC_PERM_SILENTLY_JOIN_CHANNEL = 45,
+ RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR = 46,
+ RBAC_PERM_CHECK_FOR_LOWER_SECURITY = 47,
RBAC_PERM_MAX
};
diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
index 71c44408f72..586a42c9f7e 100644
--- a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
+++ b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
@@ -93,46 +93,45 @@ void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry* auction, SQLTransaction&
if (!pItem)
return;
- uint32 bidder_accId = 0;
- uint64 bidder_guid = MAKE_NEW_GUID(auction->bidder, 0, HIGHGUID_PLAYER);
- Player* bidder = ObjectAccessor::FindPlayer(bidder_guid);
+ uint32 bidderAccId = 0;
+ uint64 bidderGuid = MAKE_NEW_GUID(auction->bidder, 0, HIGHGUID_PLAYER);
+ Player* bidder = ObjectAccessor::FindPlayer(bidderGuid);
// data for gm.log
if (sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE))
{
- uint32 bidder_security = 0;
- std::string bidder_name;
+ std::string bidderName;
+ bool logGmTrade = false;
+
if (bidder)
{
- bidder_accId = bidder->GetSession()->GetAccountId();
- bidder_security = bidder->GetSession()->GetSecurity();
- bidder_name = bidder->GetName();
+ bidderAccId = bidder->GetSession()->GetAccountId();
+ bidderName = bidder->GetName();
+ logGmTrade = bidder->GetSession()->HasPermission(RBAC_PERM_LOG_GM_TRADE);
}
else
{
- bidder_accId = sObjectMgr->GetPlayerAccountIdByGUID(bidder_guid);
- bidder_security = AccountMgr::GetSecurity(bidder_accId, realmID);
+ bidderAccId = sObjectMgr->GetPlayerAccountIdByGUID(bidderGuid);
+ logGmTrade = AccountMgr::HasPermission(bidderAccId, RBAC_PERM_LOG_GM_TRADE, realmID);
- if (!AccountMgr::IsPlayerAccount(bidder_security)) // not do redundant DB requests
- {
- if (!sObjectMgr->GetPlayerNameByGUID(bidder_guid, bidder_name))
- bidder_name = sObjectMgr->GetTrinityStringForDBCLocale(LANG_UNKNOWN);
- }
+ if (logGmTrade && !sObjectMgr->GetPlayerNameByGUID(bidderGuid, bidderName))
+ bidderName = sObjectMgr->GetTrinityStringForDBCLocale(LANG_UNKNOWN);
}
- if (!AccountMgr::IsPlayerAccount(bidder_security))
+
+ if (logGmTrade)
{
- std::string owner_name;
- if (!sObjectMgr->GetPlayerNameByGUID(auction->owner, owner_name))
- owner_name = sObjectMgr->GetTrinityStringForDBCLocale(LANG_UNKNOWN);
+ std::string ownerName;
+ if (!sObjectMgr->GetPlayerNameByGUID(auction->owner, ownerName))
+ ownerName = sObjectMgr->GetTrinityStringForDBCLocale(LANG_UNKNOWN);
- uint32 owner_accid = sObjectMgr->GetPlayerAccountIdByGUID(auction->owner);
+ uint32 ownerAccId = sObjectMgr->GetPlayerAccountIdByGUID(auction->owner);
- sLog->outCommand(bidder_accId, "GM %s (Account: %u) won item in auction: %s (Entry: %u Count: %u) and pay money: %u. Original owner %s (Account: %u)",
- bidder_name.c_str(), bidder_accId, pItem->GetTemplate()->Name1.c_str(), pItem->GetEntry(), pItem->GetCount(), auction->bid, owner_name.c_str(), owner_accid);
+ sLog->outCommand(bidderAccId, "GM %s (Account: %u) won item in auction: %s (Entry: %u Count: %u) and pay money: %u. Original owner %s (Account: %u)",
+ bidderName.c_str(), bidderAccId, pItem->GetTemplate()->Name1.c_str(), pItem->GetEntry(), pItem->GetCount(), auction->bid, ownerName.c_str(), ownerAccId);
}
}
// receiver exist
- if (bidder || bidder_accId)
+ if (bidder || bidderAccId)
{
// set owner to bidder (to prevent delete item with sender char deleting)
// owner in `data` will set at mail receive and item extracting
@@ -143,7 +142,7 @@ void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry* auction, SQLTransaction&
if (bidder)
{
- bidder->GetSession()->SendAuctionBidderNotification(auction->GetHouseId(), auction->Id, bidder_guid, 0, 0, auction->itemEntry);
+ bidder->GetSession()->SendAuctionBidderNotification(auction->GetHouseId(), auction->Id, bidderGuid, 0, 0, auction->itemEntry);
// FIXME: for offline player need also
bidder->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WON_AUCTIONS, 1);
}
diff --git a/src/server/game/Chat/Channels/Channel.cpp b/src/server/game/Chat/Channels/Channel.cpp
index 9e7a63c9093..34c8054256c 100644
--- a/src/server/game/Chat/Channels/Channel.cpp
+++ b/src/server/game/Chat/Channels/Channel.cpp
@@ -180,7 +180,7 @@ void Channel::JoinChannel(Player* player, std::string const& pass)
if (HasFlag(CHANNEL_FLAG_LFG) &&
sWorld->getBoolConfig(CONFIG_RESTRICTED_LFG_CHANNEL) &&
- AccountMgr::IsPlayerAccount(player->GetSession()->GetSecurity()) &&
+ AccountMgr::IsPlayerAccount(player->GetSession()->GetSecurity()) && //FIXME: Move to RBAC
player->GetGroup())
{
WorldPacket data;
@@ -191,8 +191,8 @@ void Channel::JoinChannel(Player* player, std::string const& pass)
player->JoinedChannel(this);
- if (_announce && (!AccountMgr::IsGMAccount(player->GetSession()->GetSecurity()) ||
- !sWorld->getBoolConfig(CONFIG_SILENTLY_GM_JOIN_TO_CHANNEL)))
+ if (_announce && (!sWorld->getBoolConfig(CONFIG_SILENTLY_GM_JOIN_TO_CHANNEL) ||
+ !player->GetSession()->HasPermission(RBAC_PERM_SILENTLY_JOIN_CHANNEL)))
{
WorldPacket data;
MakeJoined(&data, guid);
@@ -252,8 +252,9 @@ void Channel::LeaveChannel(Player* player, bool send)
bool changeowner = playersStore[guid].IsOwner();
playersStore.erase(guid);
- if (_announce && (!AccountMgr::IsGMAccount(player->GetSession()->GetSecurity()) ||
- !sWorld->getBoolConfig(CONFIG_SILENTLY_GM_JOIN_TO_CHANNEL)))
+
+ if (_announce && (!sWorld->getBoolConfig(CONFIG_SILENTLY_GM_JOIN_TO_CHANNEL) ||
+ !player->GetSession()->HasPermission(RBAC_PERM_SILENTLY_JOIN_CHANNEL)))
{
WorldPacket data;
MakeLeft(&data, guid);
@@ -279,7 +280,6 @@ void Channel::LeaveChannel(Player* player, bool send)
void Channel::KickOrBan(Player const* player, std::string const& badname, bool ban)
{
- AccountTypes sec = player->GetSession()->GetSecurity();
uint64 good = player->GetGUID();
if (!IsOn(good))
@@ -290,7 +290,7 @@ void Channel::KickOrBan(Player const* player, std::string const& badname, bool b
return;
}
- if (!playersStore[good].IsModerator() && !AccountMgr::IsGMAccount(sec))
+ if (!playersStore[good].IsModerator() && !player->GetSession()->HasPermission(RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR))
{
WorldPacket data;
MakeNotModerator(&data);
@@ -310,7 +310,7 @@ void Channel::KickOrBan(Player const* player, std::string const& badname, bool b
bool changeowner = _ownerGUID == victim;
- if (!AccountMgr::IsGMAccount(sec) && changeowner && good != _ownerGUID)
+ if (!player->GetSession()->HasPermission(RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR) && changeowner && good != _ownerGUID)
{
WorldPacket data;
MakeNotOwner(&data);
@@ -318,7 +318,7 @@ void Channel::KickOrBan(Player const* player, std::string const& badname, bool b
return;
}
- bool notify = !(AccountMgr::IsGMAccount(sec) && sWorld->getBoolConfig(CONFIG_SILENTLY_GM_JOIN_TO_CHANNEL));
+ bool notify = !sWorld->getBoolConfig(CONFIG_SILENTLY_GM_JOIN_TO_CHANNEL) || !player->GetSession()->HasPermission(RBAC_PERM_SILENTLY_JOIN_CHANNEL);
if (ban && !IsBanned(victim))
{
@@ -352,7 +352,6 @@ void Channel::KickOrBan(Player const* player, std::string const& badname, bool b
void Channel::UnBan(Player const* player, std::string const& badname)
{
- uint32 sec = player->GetSession()->GetSecurity();
uint64 good = player->GetGUID();
if (!IsOn(good))
@@ -363,7 +362,7 @@ void Channel::UnBan(Player const* player, std::string const& badname)
return;
}
- if (!playersStore[good].IsModerator() && !AccountMgr::IsGMAccount(sec))
+ if (!playersStore[good].IsModerator() && !player->GetSession()->HasPermission(RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR))
{
WorldPacket data;
MakeNotModerator(&data);
@@ -404,7 +403,7 @@ void Channel::Password(Player const* player, std::string const& pass)
return;
}
- if (!playersStore[guid].IsModerator() && !AccountMgr::IsGMAccount(player->GetSession()->GetSecurity()))
+ if (!playersStore[guid].IsModerator() && !player->GetSession()->HasPermission(RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR))
{
WorldPacket data;
MakeNotModerator(&data);
@@ -424,7 +423,6 @@ void Channel::Password(Player const* player, std::string const& pass)
void Channel::SetMode(Player const* player, std::string const& p2n, bool mod, bool set)
{
uint64 guid = player->GetGUID();
- uint32 sec = player->GetSession()->GetSecurity();
if (!IsOn(guid))
{
@@ -434,7 +432,7 @@ void Channel::SetMode(Player const* player, std::string const& p2n, bool mod, bo
return;
}
- if (!playersStore[guid].IsModerator() && !AccountMgr::IsGMAccount(sec))
+ if (!playersStore[guid].IsModerator() && !player->GetSession()->HasPermission(RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR))
{
WorldPacket data;
MakeNotModerator(&data);
@@ -449,10 +447,11 @@ void Channel::SetMode(Player const* player, std::string const& p2n, bool mod, bo
uint64 victim = newp ? newp->GetGUID() : 0;
if (!victim || !IsOn(victim) ||
+ (player->GetTeam() != newp->GetTeam() && (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL) ||
+ !player->GetSession()->HasPermission(RBAC_PERM_TWO_SIDE_INTERACTION_CHANNEL) ||
+ !newp->GetSession()->HasPermission(RBAC_PERM_TWO_SIDE_INTERACTION_CHANNEL))))
// allow make moderator from another team only if both is GMs
// at this moment this only way to show channel post for GM from another team
- ((!AccountMgr::IsGMAccount(sec) || !AccountMgr::IsGMAccount(newp->GetSession()->GetSecurity())) &&
- player->GetTeam() != newp->GetTeam() && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL)))
{
WorldPacket data;
MakePlayerNotFound(&data, p2n);
@@ -477,7 +476,6 @@ void Channel::SetMode(Player const* player, std::string const& p2n, bool mod, bo
void Channel::SetOwner(Player const* player, std::string const& newname)
{
uint64 guid = player->GetGUID();
- uint32 sec = player->GetSession()->GetSecurity();
if (!IsOn(guid))
{
@@ -487,7 +485,7 @@ void Channel::SetOwner(Player const* player, std::string const& newname)
return;
}
- if (!AccountMgr::IsGMAccount(sec) && guid != _ownerGUID)
+ if (!player->GetSession()->HasPermission(RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR) && guid != _ownerGUID)
{
WorldPacket data;
MakeNotOwner(&data);
@@ -553,7 +551,9 @@ void Channel::List(Player const* player)
// PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters
// MODERATOR, GAME MASTER, ADMINISTRATOR can see all
- if (member && (!AccountMgr::IsPlayerAccount(player->GetSession()->GetSecurity()) || member->GetSession()->GetSecurity() <= AccountTypes(gmLevelInWhoList)) &&
+ if (member &&
+ (player->GetSession()->HasPermission(RBAC_PERM_WHO_SEE_ALL_SEC_LEVELS) ||
+ member->GetSession()->GetSecurity() <= AccountTypes(gmLevelInWhoList)) &&
member->IsVisibleGloballyFor(player))
{
data << uint64(i->first);
@@ -570,7 +570,6 @@ void Channel::List(Player const* player)
void Channel::Announce(Player const* player)
{
uint64 guid = player->GetGUID();
- uint32 sec = player->GetSession()->GetSecurity();
if (!IsOn(guid))
{
@@ -580,7 +579,7 @@ void Channel::Announce(Player const* player)
return;
}
- if (!playersStore[guid].IsModerator() && !AccountMgr::IsGMAccount(sec))
+ if (!playersStore[guid].IsModerator() && !player->GetSession()->HasPermission(RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR))
{
WorldPacket data;
MakeNotModerator(&data);
@@ -605,6 +604,11 @@ void Channel::Say(uint64 guid, std::string const& what, uint32 lang)
if (what.empty())
return;
+ uint8 chatTag = 0;
+ if (Player* player = ObjectAccessor::FindPlayer(guid))
+ chatTag = player->GetChatTag();
+
+ // TODO: Add proper RBAC check
if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL))
lang = LANG_UNIVERSAL;
@@ -633,8 +637,7 @@ void Channel::Say(uint64 guid, std::string const& what, uint32 lang)
data << uint64(guid);
data << uint32(what.size() + 1);
data << what;
- Player* player = ObjectAccessor::FindPlayer(guid);
- data << uint8(player ? player->GetChatTag() : 0);
+ data << uint8(chatTag);
SendToAll(&data, !playersStore[guid].IsModerator() ? guid : false);
}
@@ -668,7 +671,9 @@ void Channel::Invite(Player const* player, std::string const& newname)
return;
}
- if (newp->GetTeam() != player->GetTeam() && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL))
+ if (newp->GetTeam() != player->GetTeam() && (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL) ||
+ !player->GetSession()->HasPermission(RBAC_PERM_TWO_SIDE_INTERACTION_CHANNEL) ||
+ !newp->GetSession()->HasPermission(RBAC_PERM_TWO_SIDE_INTERACTION_CHANNEL)))
{
WorldPacket data;
MakeInviteWrongFaction(&data);
diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp
index 3cae9d0f83a..7c92af2d67f 100644
--- a/src/server/game/Chat/Chat.cpp
+++ b/src/server/game/Chat/Chat.cpp
@@ -175,7 +175,7 @@ bool ChatHandler::HasLowerSecurityAccount(WorldSession* target, uint32 target_ac
return false;
// ignore only for non-players for non strong checks (when allow apply command at least to same sec level)
- if (!AccountMgr::IsPlayerAccount(m_session->GetSecurity()) && !strong && !sWorld->getBoolConfig(CONFIG_GM_LOWER_SECURITY))
+ if (m_session->HasPermission(RBAC_PERM_CHECK_FOR_LOWER_SECURITY) && !strong && !sWorld->getBoolConfig(CONFIG_GM_LOWER_SECURITY))
return false;
if (target)
@@ -361,6 +361,7 @@ bool ChatHandler::ExecuteCommandInTable(ChatCommand* table, const char* text, co
// table[i].Name == "" is special case: send original command to handler
if ((table[i].Handler)(this, table[i].Name[0] != '\0' ? text : oldtext))
{
+ // FIXME: When Command system is moved to RBAC this check must be changed
if (!AccountMgr::IsPlayerAccount(table[i].SecurityLevel))
{
// chat case
@@ -476,7 +477,7 @@ bool ChatHandler::ParseCommands(char const* text)
if (!ExecuteCommandInTable(getCommandTable(), text, fullcmd))
{
- if (m_session && AccountMgr::IsPlayerAccount(m_session->GetSecurity()))
+ if (m_session && !m_session->HasPermission(RBAC_PERM_COMMANDS_NOTIFY_COMMAND_NOT_FOUND_ERROR))
return false;
SendSysMessage(LANG_NO_CMD);
diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp
index a5494f689fb..96cb8b7ee25 100644
--- a/src/server/game/Conditions/ConditionMgr.cpp
+++ b/src/server/game/Conditions/ConditionMgr.cpp
@@ -431,6 +431,7 @@ uint32 Condition::GetSearcherTypeMaskForCondition()
default:
break;
}
+ break;
case CONDITION_TYPE_MASK:
if (ConditionValue1 & TYPEMASK_UNIT)
mask |= GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_PLAYER;
diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp
index 9bb65b63557..ce18c227656 100644
--- a/src/server/game/DungeonFinding/LFGMgr.cpp
+++ b/src/server/game/DungeonFinding/LFGMgr.cpp
@@ -29,6 +29,7 @@
#include "LFGQueue.h"
#include "Group.h"
#include "Player.h"
+#include "RBAC.h"
#include "GroupMgr.h"
#include "GameEventMgr.h"
#include "WorldSession.h"
diff --git a/src/server/game/Entities/Creature/TemporarySummon.h b/src/server/game/Entities/Creature/TemporarySummon.h
index dc3347c5b4f..a28874c51e7 100644
--- a/src/server/game/Entities/Creature/TemporarySummon.h
+++ b/src/server/game/Entities/Creature/TemporarySummon.h
@@ -72,6 +72,7 @@ class Minion : public TempSummon
float GetFollowAngle() const { return m_followAngle; }
void SetFollowAngle(float angle) { m_followAngle = angle; }
bool IsPetGhoul() const {return GetEntry() == 26125;} // Ghoul may be guardian or pet
+ bool IsSpiritWolf() const {return GetEntry() == 29264;} // Spirit wolf from feral spirits
bool IsGuardianPet() const;
protected:
Unit* const m_owner;
diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp
index d11f6d94734..e4981ee8483 100644
--- a/src/server/game/Entities/Pet/Pet.cpp
+++ b/src/server/game/Entities/Pet/Pet.cpp
@@ -1003,15 +1003,11 @@ bool Guardian::InitStatsForLevel(uint8 petlevel)
if (!pInfo)
SetCreateHealth(30*petlevel);
- float dmg_multiplier = 0.3f;
- if (m_owner->GetAuraEffect(63271, 0)) // Glyph of Feral Spirit
- dmg_multiplier = 0.6f;
+ // wolf attack speed is 1.5s
+ SetAttackTime(BASE_ATTACK, cinfo->baseattacktime);
- SetBonusDamage(int32(m_owner->GetTotalAttackPowerValue(BASE_ATTACK) * dmg_multiplier));
-
- // 14AP == 1dps, wolf's strike speed == 2s so dmg = basedmg + AP / 14 * 2
- SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float((petlevel * 4 - petlevel) + (m_owner->GetTotalAttackPowerValue(BASE_ATTACK) * dmg_multiplier * 2 / 14)));
- SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float((petlevel * 4 + petlevel) + (m_owner->GetTotalAttackPowerValue(BASE_ATTACK) * dmg_multiplier * 2 / 14)));
+ SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float((petlevel * 4 - petlevel)));
+ SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float((petlevel * 4 + petlevel)));
SetModifierValue(UNIT_MOD_ARMOR, BASE_VALUE, float(m_owner->GetArmor()) * 0.35f); // Bonus Armor (35% of player armor)
SetModifierValue(UNIT_MOD_STAT_STAMINA, BASE_VALUE, float(m_owner->GetStat(STAT_STAMINA)) * 0.3f); // Bonus Stamina (30% of player stamina)
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index c7c88ae0bbe..a8a500c093a 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -668,7 +668,7 @@ Player::Player(WorldSession* session): Unit(true)
//m_pad = 0;
// players always accept
- if (AccountMgr::IsPlayerAccount(GetSession()->GetSecurity()))
+ if (!GetSession()->HasPermission(RBAC_PERM_CAN_FILTER_WHISPERS))
SetAcceptWhispers(true);
m_curSelection = 0;
@@ -1018,7 +1018,7 @@ bool Player::Create(uint32 guidlow, CharacterCreateInfo* createInfo)
? sWorld->getIntConfig(CONFIG_START_PLAYER_LEVEL)
: sWorld->getIntConfig(CONFIG_START_HEROIC_PLAYER_LEVEL);
- if (!AccountMgr::IsPlayerAccount(GetSession()->GetSecurity()))
+ if (m_session->HasPermission(RBAC_PERM_USE_START_GM_LEVEL))
{
uint32 gm_level = sWorld->getIntConfig(CONFIG_START_GM_LEVEL);
if (gm_level > start_level)
@@ -2069,7 +2069,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
return false;
}
- if (AccountMgr::IsPlayerAccount(GetSession()->GetSecurity()) && DisableMgr::IsDisabledFor(DISABLE_TYPE_MAP, mapid, this))
+ if (!GetSession()->HasPermission(RBAC_PERM_SKIP_CHECK_DISABLE_MAP) && DisableMgr::IsDisabledFor(DISABLE_TYPE_MAP, mapid, this))
{
sLog->outError(LOG_FILTER_MAPS, "Player (GUID: %u, name: %s) tried to enter a forbidden map %u", GetGUIDLow(), GetName().c_str(), mapid);
SendTransferAborted(mapid, TRANSFER_ABORT_MAP_NOT_ALLOWED);
@@ -3120,7 +3120,7 @@ void Player::InitTalentForLevel()
// if used more that have then reset
if (m_usedTalentCount > talentPointsForLevel)
{
- if (!AccountMgr::IsAdminAccount(GetSession()->GetSecurity()))
+ if (!GetSession()->HasPermission(RBAC_PERM_SKIP_CHECK_MORE_TALENTS_THAN_ALLOWED))
resetTalents(true);
else
SetFreeTalentPoints(0);
@@ -16774,7 +16774,8 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder)
// check name limitations
if (ObjectMgr::CheckPlayerName(m_name) != CHAR_NAME_SUCCESS ||
- (AccountMgr::IsPlayerAccount(GetSession()->GetSecurity()) && sObjectMgr->IsReservedName(m_name)))
+ (!GetSession()->HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME) &&
+ sObjectMgr->IsReservedName(m_name)))
{
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG);
stmt->setUInt16(0, uint16(AT_LOGIN_RENAME));
@@ -17309,7 +17310,7 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder)
outDebugValues();
// GM state
- if (!AccountMgr::IsPlayerAccount(GetSession()->GetSecurity()))
+ if (GetSession()->HasPermission(RBAC_PERM_RESTORE_SAVED_GM_STATE))
{
switch (sWorld->getIntConfig(CONFIG_GM_LOGIN_STATE))
{
@@ -19628,7 +19629,7 @@ void Player::outDebugValues() const
void Player::UpdateSpeakTime()
{
// ignore chat spam protection for GMs in any mode
- if (!AccountMgr::IsPlayerAccount(GetSession()->GetSecurity()))
+ if (!GetSession()->HasPermission(RBAC_PERM_SKIP_CHECK_CHAT_SPAM))
return;
time_t current = time (NULL);
diff --git a/src/server/game/Entities/Player/SocialMgr.cpp b/src/server/game/Entities/Player/SocialMgr.cpp
index e5bbac59e00..7a2b36e23bf 100644
--- a/src/server/game/Entities/Player/SocialMgr.cpp
+++ b/src/server/game/Entities/Player/SocialMgr.cpp
@@ -216,34 +216,38 @@ void SocialMgr::GetFriendInfo(Player* player, uint32 friendGUID, FriendInfo &fri
friendInfo.Level = 0;
friendInfo.Class = 0;
- Player* pFriend = ObjectAccessor::FindPlayer(friendGUID);
- if (!pFriend)
+ Player* target = ObjectAccessor::FindPlayer(friendGUID);
+ if (!target)
return;
- uint32 team = player->GetTeam();
- AccountTypes security = player->GetSession()->GetSecurity();
- bool allowTwoSideWhoList = sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_WHO_LIST);
- AccountTypes gmLevelInWhoList = AccountTypes(sWorld->getIntConfig(CONFIG_GM_LEVEL_IN_WHO_LIST));
-
PlayerSocialMap::iterator itr = player->GetSocial()->m_playerSocialMap.find(friendGUID);
if (itr != player->GetSocial()->m_playerSocialMap.end())
friendInfo.Note = itr->second.Note;
// PLAYER see his team only and PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters
// MODERATOR, GAME MASTER, ADMINISTRATOR can see all
- if (pFriend &&
- (!AccountMgr::IsPlayerAccount(security) ||
- ((pFriend->GetTeam() == team || allowTwoSideWhoList) && (pFriend->GetSession()->GetSecurity() <= gmLevelInWhoList))) &&
- pFriend->IsVisibleGloballyFor(player))
+
+ if (!player->GetSession()->HasPermission(RBAC_PERM_WHO_SEE_ALL_SEC_LEVELS) &&
+ target->GetSession()->GetSecurity() > AccountTypes(sWorld->getIntConfig(CONFIG_GM_LEVEL_IN_WHO_LIST)))
+ return;
+
+ // player can see member of other team only if CONFIG_ALLOW_TWO_SIDE_WHO_LIST
+ if (target->GetTeam() != player->GetTeam() &&
+ !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_WHO_LIST) && !player->GetSession()->HasPermission(RBAC_PERM_TWO_SIDE_WHO_LIST))
+ return;
+
+ if (target->IsVisibleGloballyFor(player))
{
- friendInfo.Status = FRIEND_STATUS_ONLINE;
- if (pFriend->isAFK())
- friendInfo.Status = FRIEND_STATUS_AFK;
- if (pFriend->isDND())
+ if (target->isDND())
friendInfo.Status = FRIEND_STATUS_DND;
- friendInfo.Area = pFriend->GetZoneId();
- friendInfo.Level = pFriend->getLevel();
- friendInfo.Class = pFriend->getClass();
+ else if (target->isAFK())
+ friendInfo.Status = FRIEND_STATUS_AFK;
+ else
+ friendInfo.Status = FRIEND_STATUS_ONLINE;
+
+ friendInfo.Area = target->GetZoneId();
+ friendInfo.Level = target->getLevel();
+ friendInfo.Class = target->getClass();
}
}
@@ -295,28 +299,29 @@ void SocialMgr::BroadcastToFriendListers(Player* player, WorldPacket* packet)
if (!player)
return;
- uint32 team = player->GetTeam();
- AccountTypes security = player->GetSession()->GetSecurity();
- uint32 guid = player->GetGUIDLow();
- AccountTypes gmLevelInWhoList = AccountTypes(sWorld->getIntConfig(CONFIG_GM_LEVEL_IN_WHO_LIST));
- bool allowTwoSideWhoList = sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_WHO_LIST);
-
for (SocialMap::const_iterator itr = m_socialMap.begin(); itr != m_socialMap.end(); ++itr)
{
- PlayerSocialMap::const_iterator itr2 = itr->second.m_playerSocialMap.find(guid);
+ PlayerSocialMap::const_iterator itr2 = itr->second.m_playerSocialMap.find(player->GetGUID());
if (itr2 != itr->second.m_playerSocialMap.end() && (itr2->second.Flags & SOCIAL_FLAG_FRIEND))
{
- Player* pFriend = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER));
+ Player* target = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER));
+ if (!target || !target->IsInWorld())
+ continue;
+
+ if (!target->GetSession()->HasPermission(RBAC_PERM_WHO_SEE_ALL_SEC_LEVELS) &&
+ player->GetSession()->GetSecurity() > AccountTypes(sWorld->getIntConfig(CONFIG_GM_LEVEL_IN_WHO_LIST)))
+ continue;
+
+ // player can see member of other team only if CONFIG_ALLOW_TWO_SIDE_WHO_LIST
+ if (target->GetTeam() != player->GetTeam() &&
+ !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_WHO_LIST) &&
+ !target->GetSession()->HasPermission(RBAC_PERM_TWO_SIDE_WHO_LIST))
+ continue;
// PLAYER see his team only and PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters
// MODERATOR, GAME MASTER, ADMINISTRATOR can see all
- if (pFriend && pFriend->IsInWorld() &&
- (!AccountMgr::IsPlayerAccount(pFriend->GetSession()->GetSecurity()) ||
- ((pFriend->GetTeam() == team || allowTwoSideWhoList) && security <= gmLevelInWhoList)) &&
- player->IsVisibleGloballyFor(pFriend))
- {
- pFriend->GetSession()->SendPacket(packet);
- }
+ if (player->IsVisibleGloballyFor(target))
+ target->GetSession()->SendPacket(packet);
}
}
}
diff --git a/src/server/game/Entities/Unit/StatSystem.cpp b/src/server/game/Entities/Unit/StatSystem.cpp
index 0024d726060..c30fa910f76 100644
--- a/src/server/game/Entities/Unit/StatSystem.cpp
+++ b/src/server/game/Entities/Unit/StatSystem.cpp
@@ -441,6 +441,7 @@ void Player::UpdateAttackPowerAndDamage(bool ranged)
SetFloatValue(index_mult, attPowerMultiplier); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MULTIPLIER field
Pet* pet = GetPet(); //update pet's AP
+ Guardian* guardian = GetGuardianPet();
//automatically update weapon damage after attack power modification
if (ranged)
{
@@ -456,8 +457,11 @@ void Player::UpdateAttackPowerAndDamage(bool ranged)
if (getClass() == CLASS_SHAMAN || getClass() == CLASS_PALADIN) // mental quickness
UpdateSpellDamageAndHealingBonus();
- if (pet && pet->IsPetGhoul()) // At ranged attack change for hunter pet
+ if (pet && pet->IsPetGhoul()) // At melee attack power change for DK pet
pet->UpdateAttackPowerAndDamage();
+
+ if (guardian && guardian->IsSpiritWolf()) // At melee attack power change for Shaman feral spirit
+ guardian->UpdateAttackPowerAndDamage();
}
}
@@ -1305,6 +1309,14 @@ void Guardian::UpdateAttackPowerAndDamage(bool ranged)
bonusAP = owner->GetTotalAttackPowerValue(BASE_ATTACK) * 0.22f;
SetBonusDamage(int32(owner->GetTotalAttackPowerValue(BASE_ATTACK) * 0.1287f));
}
+ else if (IsSpiritWolf()) //wolf benefit from shaman's attack power
+ {
+ float dmg_multiplier = 0.31f;
+ if (m_owner->GetAuraEffect(63271, 0)) // Glyph of Feral Spirit
+ dmg_multiplier = 0.61f;
+ bonusAP = owner->GetTotalAttackPowerValue(BASE_ATTACK) * dmg_multiplier;
+ SetBonusDamage(int32(owner->GetTotalAttackPowerValue(BASE_ATTACK) * dmg_multiplier));
+ }
//demons benefit from warlocks shadow or fire damage
else if (isPet())
{
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index fe4d0b31c80..00f771b1f54 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -515,7 +515,7 @@ bool Unit::HasBreakableByDamageAuraType(AuraType type, uint32 excludeAura) const
AuraEffectList const& auras = GetAuraEffectsByType(type);
for (AuraEffectList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
if ((!excludeAura || excludeAura != (*itr)->GetSpellInfo()->Id) && //Avoid self interrupt of channeled Crowd Control spells like Seduction
- ((*itr)->GetSpellInfo()->Attributes & SPELL_ATTR0_BREAKABLE_BY_DAMAGE || (*itr)->GetSpellInfo()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_TAKE_DAMAGE))
+ ((*itr)->GetSpellInfo()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_TAKE_DAMAGE))
return true;
return false;
}
@@ -11193,7 +11193,7 @@ uint32 Unit::MeleeDamageBonusTaken(Unit* attacker, uint32 pdamage, WeaponAttackT
// ..taken
AuraEffectList const& mDamageTaken = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_TAKEN);
for (AuraEffectList::const_iterator i = mDamageTaken.begin(); i != mDamageTaken.end(); ++i)
- if ((*i)->GetMiscValue() & GetMeleeDamageSchoolMask())
+ if ((*i)->GetMiscValue() & attacker->GetMeleeDamageSchoolMask())
TakenFlatBenefit += (*i)->GetAmount();
if (attType != RANGED_ATTACK)
@@ -11205,7 +11205,7 @@ uint32 Unit::MeleeDamageBonusTaken(Unit* attacker, uint32 pdamage, WeaponAttackT
float TakenTotalMod = 1.0f;
// ..taken
- TakenTotalMod *= GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, GetMeleeDamageSchoolMask());
+ TakenTotalMod *= GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, attacker->GetMeleeDamageSchoolMask());
// .. taken pct (special attacks)
if (spellProto)
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 62facf6a69e..b549802c91c 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -398,6 +398,7 @@ enum TriggerCastFlags
TRIGGERED_IGNORE_CASTER_AURAS = 0x00010000, //! Will ignore caster aura restrictions or requirements
TRIGGERED_DISALLOW_PROC_EVENTS = 0x00020000, //! Disallows proc events from triggered spell (default)
TRIGGERED_DONT_REPORT_CAST_ERROR = 0x00040000, //! Will return SPELL_FAILED_DONT_REPORT in CheckCast functions
+ TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT = 0x00080000, //! Will ignore equipped item requirements
TRIGGERED_FULL_MASK = 0xFFFFFFFF
};
diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h
index 12df01fc350..5b13a4daf0d 100644
--- a/src/server/game/Globals/ObjectMgr.h
+++ b/src/server/game/Globals/ObjectMgr.h
@@ -424,7 +424,7 @@ struct TempSummonGroupKey
: _summonerEntry(summonerEntry), _summonerType(summonerType), _summonGroup(group)
{
}
-
+
bool operator<(TempSummonGroupKey const& rhs) const
{
return memcmp(this, &rhs, sizeof(TempSummonGroupKey)) < 0;
@@ -1017,7 +1017,7 @@ class ObjectMgr
TempSummonDataContainer::const_iterator itr = _tempSummonDataStore.find(TempSummonGroupKey(summonerId, summonerType, group));
if (itr != _tempSummonDataStore.end())
return &itr->second;
-
+
return NULL;
}
diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp
index c424e5d3ffe..a1ab1b22b08 100644
--- a/src/server/game/Guilds/Guild.cpp
+++ b/src/server/game/Guilds/Guild.cpp
@@ -983,12 +983,15 @@ void Guild::BankMoveItemData::LogBankEvent(SQLTransaction& trans, MoveItemData*
void Guild::BankMoveItemData::LogAction(MoveItemData* pFrom) const
{
MoveItemData::LogAction(pFrom);
- if (!pFrom->IsBank() && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE) && !AccountMgr::IsPlayerAccount(m_pPlayer->GetSession()->GetSecurity())) // TODO: move to scripts
+ if (!pFrom->IsBank() && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE) &&
+ m_pPlayer->GetSession()->HasPermission(RBAC_PERM_LOG_GM_TRADE))
+ {
sLog->outCommand(m_pPlayer->GetSession()->GetAccountId(),
"GM %s (Account: %u) deposit item: %s (Entry: %d Count: %u) to guild bank (Guild ID: %u)",
m_pPlayer->GetName().c_str(), m_pPlayer->GetSession()->GetAccountId(),
pFrom->GetItem()->GetTemplate()->Name1.c_str(), pFrom->GetItem()->GetEntry(), pFrom->GetItem()->GetCount(),
m_pGuild->GetId());
+ }
}
Item* Guild::BankMoveItemData::_StoreItem(SQLTransaction& trans, BankTab* pTab, Item* pItem, ItemPosCount& pos, bool clone) const
@@ -1729,7 +1732,7 @@ void Guild::HandleMemberDepositMoney(WorldSession* session, uint32 amount)
std::string aux = ByteArrayToHexStr(reinterpret_cast<uint8*>(&amount), 8, true);
_BroadcastEvent(GE_BANK_MONEY_CHANGED, 0, aux.c_str());
- if (!AccountMgr::IsPlayerAccount(player->GetSession()->GetSecurity()) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE))
+ if (player->GetSession()->HasPermission(RBAC_PERM_LOG_GM_TRADE) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE))
{
sLog->outCommand(player->GetSession()->GetAccountId(),
"GM %s (Account: %u) deposit money (Amount: %u) to guild bank (Guild ID %u)",
diff --git a/src/server/game/Handlers/AuctionHouseHandler.cpp b/src/server/game/Handlers/AuctionHouseHandler.cpp
index 6fc88f441bb..22070d4c2c2 100644
--- a/src/server/game/Handlers/AuctionHouseHandler.cpp
+++ b/src/server/game/Handlers/AuctionHouseHandler.cpp
@@ -245,7 +245,7 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData)
// Required stack size of auction matches to current item stack size, just move item to auctionhouse
if (itemsCount == 1 && item->GetCount() == count[i])
{
- if (GetSecurity() > SEC_PLAYER && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE))
+ if (HasPermission(RBAC_PERM_LOG_GM_TRADE) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE))
{
sLog->outCommand(GetAccountId(), "GM %s (Account: %u) create auction: %s (Entry: %u Count: %u)",
GetPlayerName().c_str(), GetAccountId(), item->GetTemplate()->Name1.c_str(), item->GetEntry(), item->GetCount());
@@ -291,7 +291,7 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData)
return;
}
- if (GetSecurity() > SEC_PLAYER && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE))
+ if (HasPermission(RBAC_PERM_LOG_GM_TRADE) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE))
{
sLog->outCommand(GetAccountId(), "GM %s (Account: %u) create auction: %s (Entry: %u Count: %u)",
GetPlayerName().c_str(), GetAccountId(), newItem->GetTemplate()->Name1.c_str(), newItem->GetEntry(), newItem->GetCount());
diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
index b12893ff65f..eb5326e8094 100644
--- a/src/server/game/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Handlers/CharacterHandler.cpp
@@ -274,7 +274,7 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData)
WorldPacket data(SMSG_CHAR_CREATE, 1); // returned with diff.values in all cases
- if (AccountMgr::IsPlayerAccount(GetSecurity()))
+ if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_TEAMMASK))
{
if (uint32 mask = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_DISABLED))
{
@@ -283,13 +283,17 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData)
uint32 team = Player::TeamForRace(race_);
switch (team)
{
- case ALLIANCE: disabled = mask & (1 << 0); break;
- case HORDE: disabled = mask & (1 << 1); break;
+ case ALLIANCE:
+ disabled = mask & (1 << 0);
+ break;
+ case HORDE:
+ disabled = mask & (1 << 1);
+ break;
}
if (disabled)
{
- data << (uint8)CHAR_CREATE_DISABLED;
+ data << uint8(CHAR_CREATE_DISABLED);
SendPacket(&data);
return;
}
@@ -299,7 +303,7 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData)
ChrClassesEntry const* classEntry = sChrClassesStore.LookupEntry(class_);
if (!classEntry)
{
- data << (uint8)CHAR_CREATE_FAILED;
+ data << uint8(CHAR_CREATE_FAILED);
SendPacket(&data);
sLog->outError(LOG_FILTER_NETWORKIO, "Class (%u) not found in DBC while creating new char for account (ID: %u): wrong DBC files or cheater?", class_, GetAccountId());
return;
@@ -308,7 +312,7 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData)
ChrRacesEntry const* raceEntry = sChrRacesStore.LookupEntry(race_);
if (!raceEntry)
{
- data << (uint8)CHAR_CREATE_FAILED;
+ data << uint8(CHAR_CREATE_FAILED);
SendPacket(&data);
sLog->outError(LOG_FILTER_NETWORKIO, "Race (%u) not found in DBC while creating new char for account (ID: %u): wrong DBC files or cheater?", race_, GetAccountId());
return;
@@ -317,7 +321,7 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData)
// prevent character creating Expansion race without Expansion account
if (raceEntry->expansion > Expansion())
{
- data << (uint8)CHAR_CREATE_EXPANSION;
+ data << uint8(CHAR_CREATE_EXPANSION);
sLog->outError(LOG_FILTER_NETWORKIO, "Expansion %u account:[%d] tried to Create character with expansion %u race (%u)", Expansion(), GetAccountId(), raceEntry->expansion, race_);
SendPacket(&data);
return;
@@ -326,13 +330,13 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData)
// prevent character creating Expansion class without Expansion account
if (classEntry->expansion > Expansion())
{
- data << (uint8)CHAR_CREATE_EXPANSION_CLASS;
+ data << uint8(CHAR_CREATE_EXPANSION_CLASS);
sLog->outError(LOG_FILTER_NETWORKIO, "Expansion %u account:[%d] tried to Create character with expansion %u class (%u)", Expansion(), GetAccountId(), classEntry->expansion, class_);
SendPacket(&data);
return;
}
- if (AccountMgr::IsPlayerAccount(GetSecurity()))
+ if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RACEMASK))
{
uint32 raceMaskDisabled = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_DISABLED_RACEMASK);
if ((1 << (race_ - 1)) & raceMaskDisabled)
@@ -341,7 +345,10 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData)
SendPacket(&data);
return;
}
+ }
+ if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_CLASSMASK))
+ {
uint32 classMaskDisabled = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_DISABLED_CLASSMASK);
if ((1 << (class_ - 1)) & classMaskDisabled)
{
@@ -354,7 +361,7 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData)
// prevent character creating with invalid name
if (!normalizePlayerName(name))
{
- data << (uint8)CHAR_NAME_NO_NAME;
+ data << uint8(CHAR_NAME_NO_NAME);
SendPacket(&data);
sLog->outError(LOG_FILTER_NETWORKIO, "Account:[%d] but tried to Create character with empty [name] ", GetAccountId());
return;
@@ -369,29 +376,32 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData)
return;
}
- if (AccountMgr::IsPlayerAccount(GetSecurity()) && sObjectMgr->IsReservedName(name))
+ if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME) && sObjectMgr->IsReservedName(name))
{
- data << (uint8)CHAR_NAME_RESERVED;
+ data << uint8(CHAR_NAME_RESERVED);
SendPacket(&data);
return;
}
- // speedup check for heroic class disabled case
- uint32 heroic_free_slots = sWorld->getIntConfig(CONFIG_HEROIC_CHARACTERS_PER_REALM);
- if (heroic_free_slots == 0 && AccountMgr::IsPlayerAccount(GetSecurity()) && class_ == CLASS_DEATH_KNIGHT)
+ if (class_ == CLASS_DEATH_KNIGHT && !HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_HEROIC_CHARACTER))
{
- data << (uint8)CHAR_CREATE_UNIQUE_CLASS_LIMIT;
- SendPacket(&data);
- return;
- }
+ // speedup check for heroic class disabled case
+ uint32 heroic_free_slots = sWorld->getIntConfig(CONFIG_HEROIC_CHARACTERS_PER_REALM);
+ if (heroic_free_slots == 0)
+ {
+ data << uint8(CHAR_CREATE_UNIQUE_CLASS_LIMIT);
+ SendPacket(&data);
+ return;
+ }
- // speedup check for heroic class disabled case
- uint32 req_level_for_heroic = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_MIN_LEVEL_FOR_HEROIC_CHARACTER);
- if (AccountMgr::IsPlayerAccount(GetSecurity()) && class_ == CLASS_DEATH_KNIGHT && req_level_for_heroic > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
- {
- data << (uint8)CHAR_CREATE_LEVEL_REQUIREMENT;
- SendPacket(&data);
- return;
+ // speedup check for heroic class disabled case
+ uint32 req_level_for_heroic = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_MIN_LEVEL_FOR_HEROIC_CHARACTER);
+ if (req_level_for_heroic > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
+ {
+ data << uint8(CHAR_CREATE_LEVEL_REQUIREMENT);
+ SendPacket(&data);
+ return;
+ }
}
delete _charCreateCallback.GetParam(); // Delete existing if any, to make the callback chain reset to stage 0
@@ -482,7 +492,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte
}
}
- bool allowTwoSideAccounts = !sWorld->IsPvPRealm() || sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_ACCOUNTS) || !AccountMgr::IsPlayerAccount(GetSecurity());
+ bool allowTwoSideAccounts = !sWorld->IsPvPRealm() || sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_ACCOUNTS) || HasPermission(RBAC_PERM_TWO_SIDE_CHARACTER_CREATION);
uint32 skipCinematics = sWorld->getIntConfig(CONFIG_SKIP_CINEMATICS);
_charCreateCallback.FreeResult();
@@ -506,8 +516,9 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte
bool haveSameRace = false;
uint32 heroicReqLevel = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_MIN_LEVEL_FOR_HEROIC_CHARACTER);
bool hasHeroicReqLevel = (heroicReqLevel == 0);
- bool allowTwoSideAccounts = !sWorld->IsPvPRealm() || sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_ACCOUNTS) || !AccountMgr::IsPlayerAccount(GetSecurity());
+ bool allowTwoSideAccounts = !sWorld->IsPvPRealm() || sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_ACCOUNTS) || HasPermission(RBAC_PERM_TWO_SIDE_CHARACTER_CREATION);
uint32 skipCinematics = sWorld->getIntConfig(CONFIG_SKIP_CINEMATICS);
+ bool checkHeroicReqs = createInfo->Class == CLASS_DEATH_KNIGHT && !HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_HEROIC_CHARACTER);
if (result)
{
@@ -517,7 +528,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte
Field* field = result->Fetch();
uint8 accRace = field[1].GetUInt8();
- if (AccountMgr::IsPlayerAccount(GetSecurity()) && createInfo->Class == CLASS_DEATH_KNIGHT)
+ if (checkHeroicReqs)
{
uint8 accClass = field[2].GetUInt8();
if (accClass == CLASS_DEATH_KNIGHT)
@@ -576,7 +587,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte
if (!haveSameRace)
haveSameRace = createInfo->Race == accRace;
- if (AccountMgr::IsPlayerAccount(GetSecurity()) && createInfo->Class == CLASS_DEATH_KNIGHT)
+ if (checkHeroicReqs)
{
uint8 acc_class = field[2].GetUInt8();
if (acc_class == CLASS_DEATH_KNIGHT)
@@ -605,7 +616,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte
}
}
- if (AccountMgr::IsPlayerAccount(GetSecurity()) && createInfo->Class == CLASS_DEATH_KNIGHT && !hasHeroicReqLevel)
+ if (checkHeroicReqs && !hasHeroicReqLevel)
{
WorldPacket data(SMSG_CHAR_CREATE, 1);
data << uint8(CHAR_CREATE_LEVEL_REQUIREMENT);
@@ -1122,7 +1133,7 @@ void WorldSession::HandleCharRenameOpcode(WorldPacket& recvData)
}
// check name limitations
- if (AccountMgr::IsPlayerAccount(GetSecurity()) && sObjectMgr->IsReservedName(newName))
+ if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME) && sObjectMgr->IsReservedName(newName))
{
WorldPacket data(SMSG_CHAR_RENAME, 1);
data << uint8(CHAR_NAME_RESERVED);
@@ -1444,7 +1455,7 @@ void WorldSession::HandleCharCustomize(WorldPacket& recvData)
}
// check name limitations
- if (AccountMgr::IsPlayerAccount(GetSecurity()) && sObjectMgr->IsReservedName(newName))
+ if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME) && sObjectMgr->IsReservedName(newName))
{
WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1);
data << uint8(CHAR_NAME_RESERVED);
@@ -1690,7 +1701,7 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
return;
}
- if (AccountMgr::IsPlayerAccount(GetSecurity()))
+ if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RACEMASK))
{
uint32 raceMaskDisabled = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_DISABLED_RACEMASK);
if ((1 << (race - 1)) & raceMaskDisabled)
@@ -1721,7 +1732,7 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
}
// check name limitations
- if (AccountMgr::IsPlayerAccount(GetSecurity()) && sObjectMgr->IsReservedName(newname))
+ if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME) && sObjectMgr->IsReservedName(newname))
{
WorldPacket data(SMSG_CHAR_FACTION_CHANGE, 1);
data << uint8(CHAR_NAME_RESERVED);
diff --git a/src/server/game/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp
index d04d365504d..efb3a3b6d7c 100644
--- a/src/server/game/Handlers/ChatHandler.cpp
+++ b/src/server/game/Handlers/ChatHandler.cpp
@@ -273,20 +273,22 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
}
Player* receiver = sObjectAccessor->FindPlayerByName(to);
- bool senderIsPlayer = AccountMgr::IsPlayerAccount(GetSecurity());
- bool receiverIsPlayer = AccountMgr::IsPlayerAccount(receiver ? receiver->GetSession()->GetSecurity() : SEC_PLAYER);
- if (!receiver || (senderIsPlayer && !receiverIsPlayer && !receiver->isAcceptWhispers() && !receiver->IsInWhisperWhiteList(sender->GetGUID())))
+ if (!receiver || (!HasPermission(RBAC_PERM_CAN_FILTER_WHISPERS) &&
+ receiver->GetSession()->HasPermission(RBAC_PERM_CAN_FILTER_WHISPERS) &&
+ !receiver->isAcceptWhispers() && !receiver->IsInWhisperWhiteList(sender->GetGUID())))
{
SendPlayerNotFoundNotice(to);
return;
}
- if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT) && senderIsPlayer && receiverIsPlayer)
- if (GetPlayer()->GetTeam() != receiver->GetTeam())
- {
- SendWrongFactionNotice();
- return;
- }
+ if (GetPlayer()->GetTeam() != receiver->GetTeam() &&
+ (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT) ||
+ !HasPermission(RBAC_PERM_TWO_SIDE_INTERACTION_CHAT) ||
+ !receiver->GetSession()->HasPermission(RBAC_PERM_TWO_SIDE_INTERACTION_CHAT)))
+ {
+ SendWrongFactionNotice();
+ return;
+ }
if (GetPlayer()->HasAura(1852) && !receiver->isGameMaster())
{
@@ -295,7 +297,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
}
// If player is a Gamemaster and doesn't accept whisper, we auto-whitelist every player that the Gamemaster is talking to
- if (!senderIsPlayer && !sender->isAcceptWhispers() && !sender->IsInWhisperWhiteList(receiver->GetGUID()))
+ if (HasPermission(RBAC_PERM_CAN_FILTER_WHISPERS) && !sender->isAcceptWhispers() && !sender->IsInWhisperWhiteList(receiver->GetGUID()))
sender->AddWhisperWhiteList(receiver->GetGUID());
GetPlayer()->Whisper(msg, lang, receiver->GetGUID());
@@ -420,7 +422,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
} break;
case CHAT_MSG_CHANNEL:
{
- if (AccountMgr::IsPlayerAccount(GetSecurity()))
+ if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHAT_CHANNEL_REQ))
{
if (_player->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_CHANNEL_LEVEL_REQ))
{
diff --git a/src/server/game/Handlers/MailHandler.cpp b/src/server/game/Handlers/MailHandler.cpp
index 14b6df23061..f3201401c8d 100644
--- a/src/server/game/Handlers/MailHandler.cpp
+++ b/src/server/game/Handlers/MailHandler.cpp
@@ -32,23 +32,16 @@
void WorldSession::HandleSendMail(WorldPacket& recvData)
{
uint64 mailbox, unk3;
- std::string receiver, subject, body;
+ std::string receiverName, subject, body;
uint32 unk1, unk2, money, COD;
uint8 unk4;
- recvData >> mailbox;
- recvData >> receiver;
-
- recvData >> subject;
-
- recvData >> body;
-
- recvData >> unk1; // stationery?
- recvData >> unk2; // 0x00000000
-
uint8 items_count;
- recvData >> items_count; // attached items count
+ recvData >> mailbox >> receiverName >> subject >> body
+ >> unk1 // stationery?
+ >> unk2 // 0x00000000
+ >> items_count; // attached items count
- if (items_count > MAX_MAIL_ITEMS) // client limit
+ if (items_count > MAX_MAIL_ITEMS) // client limit
{
GetPlayer()->SendMailResult(0, MAIL_SEND, MAIL_ERR_TOO_MANY_ATTACHMENTS);
recvData.rfinish(); // set to end to avoid warnings spam
@@ -72,7 +65,7 @@ void WorldSession::HandleSendMail(WorldPacket& recvData)
if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX))
return;
- if (receiver.empty())
+ if (receiverName.empty())
return;
Player* player = _player;
@@ -83,21 +76,26 @@ void WorldSession::HandleSendMail(WorldPacket& recvData)
return;
}
- uint64 rc = 0;
- if (normalizePlayerName(receiver))
- rc = sObjectMgr->GetPlayerGUIDByName(receiver);
+ uint64 receiverGuid = 0;
+ if (normalizePlayerName(receiverName))
+ receiverGuid = sObjectMgr->GetPlayerGUIDByName(receiverName);
- if (!rc)
+ if (!receiverGuid)
{
- sLog->outInfo(LOG_FILTER_NETWORKIO, "Player %u is sending mail to %s (GUID: not existed!) with subject %s and body %s includes %u items, %u copper and %u COD copper with unk1 = %u, unk2 = %u",
- player->GetGUIDLow(), receiver.c_str(), subject.c_str(), body.c_str(), items_count, money, COD, unk1, unk2);
+ sLog->outInfo(LOG_FILTER_NETWORKIO, "Player %u is sending mail to %s (GUID: not existed!) with subject %s "
+ "and body %s includes %u items, %u copper and %u COD copper with unk1 = %u, unk2 = %u",
+ player->GetGUIDLow(), receiverName.c_str(), subject.c_str(), body.c_str(),
+ items_count, money, COD, unk1, unk2);
player->SendMailResult(0, MAIL_SEND, MAIL_ERR_RECIPIENT_NOT_FOUND);
return;
}
- sLog->outInfo(LOG_FILTER_NETWORKIO, "Player %u is sending mail to %s (GUID: %u) with subject %s and body %s includes %u items, %u copper and %u COD copper with unk1 = %u, unk2 = %u", player->GetGUIDLow(), receiver.c_str(), GUID_LOPART(rc), subject.c_str(), body.c_str(), items_count, money, COD, unk1, unk2);
+ sLog->outInfo(LOG_FILTER_NETWORKIO, "Player %u is sending mail to %s (GUID: %u) with subject %s and body %s "
+ "includes %u items, %u copper and %u COD copper with unk1 = %u, unk2 = %u",
+ player->GetGUIDLow(), receiverName.c_str(), GUID_LOPART(receiverGuid), subject.c_str(),
+ body.c_str(), items_count, money, COD, unk1, unk2);
- if (player->GetGUID() == rc)
+ if (player->GetGUID() == receiverGuid)
{
player->SendMailResult(0, MAIL_SEND, MAIL_ERR_CANNOT_SEND_TO_SELF);
return;
@@ -113,58 +111,62 @@ void WorldSession::HandleSendMail(WorldPacket& recvData)
return;
}
- Player* receive = ObjectAccessor::FindPlayer(rc);
+ Player* receiver = ObjectAccessor::FindPlayer(receiverGuid);
- uint32 rc_team = 0;
- uint8 mails_count = 0; //do not allow to send to one player more than 100 mails
- uint8 receiveLevel = 0;
+ uint32 receiverTeam = 0;
+ uint8 mailsCount = 0; //do not allow to send to one player more than 100 mails
+ uint8 receiverLevel = 0;
+ uint32 receiverAccountId = 0;
+ bool canReceiveMailFromOtherFaction = false;
- if (receive)
+ if (receiver)
{
- rc_team = receive->GetTeam();
- mails_count = receive->GetMailSize();
- receiveLevel = receive->getLevel();
+ receiverTeam = receiver->GetTeam();
+ mailsCount = receiver->GetMailSize();
+ receiverLevel = receiver->getLevel();
+ receiverAccountId = receiver->GetSession()->GetAccountId();
+ canReceiveMailFromOtherFaction = receiver->GetSession()->HasPermission(RBAC_PERM_TWO_SIDE_INTERACTION_MAIL);
}
else
{
- rc_team = sObjectMgr->GetPlayerTeamByGUID(rc);
+ receiverTeam = sObjectMgr->GetPlayerTeamByGUID(receiverGuid);
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAIL_COUNT);
-
- stmt->setUInt32(0, GUID_LOPART(rc));
+ stmt->setUInt32(0, GUID_LOPART(receiverGuid));
PreparedQueryResult result = CharacterDatabase.Query(stmt);
-
if (result)
{
Field* fields = result->Fetch();
- mails_count = fields[0].GetUInt64();
+ mailsCount = fields[0].GetUInt64();
}
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_LEVEL);
-
- stmt->setUInt32(0, GUID_LOPART(rc));
+ stmt->setUInt32(0, GUID_LOPART(receiverGuid));
result = CharacterDatabase.Query(stmt);
-
if (result)
{
Field* fields = result->Fetch();
- receiveLevel = fields[0].GetUInt8();
+ receiverLevel = fields[0].GetUInt8();
}
+
+ receiverAccountId = sObjectMgr->GetPlayerAccountIdByGUID(receiverGuid);
+ canReceiveMailFromOtherFaction = AccountMgr::HasPermission(receiverAccountId, RBAC_PERM_TWO_SIDE_INTERACTION_MAIL, realmID);
}
- //do not allow to have more than 100 mails in mailbox.. mails count is in opcode uint8!!! - so max can be 255..
- if (mails_count > 100)
+
+ // do not allow to have more than 100 mails in mailbox.. mails count is in opcode uint8!!! - so max can be 255..
+ if (mailsCount > 100)
{
player->SendMailResult(0, MAIL_SEND, MAIL_ERR_RECIPIENT_CAP_REACHED);
return;
}
+
// test the receiver's Faction... or all items are account bound
bool accountBound = items_count ? true : false;
for (uint8 i = 0; i < items_count; ++i)
{
- Item* item = player->GetItemByGuid(itemGUIDs[i]);
- if (item)
+ if (Item* item = player->GetItemByGuid(itemGUIDs[i]))
{
ItemTemplate const* itemProto = item->GetTemplate();
if (!itemProto || !(itemProto->Flags & ITEM_PROTO_FLAG_BIND_TO_ACCOUNT))
@@ -175,22 +177,21 @@ void WorldSession::HandleSendMail(WorldPacket& recvData)
}
}
- if (!accountBound && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_MAIL) && player->GetTeam() != rc_team && AccountMgr::IsPlayerAccount(GetSecurity()))
+ if (!accountBound && player->GetTeam() != receiverTeam && // Sender and reciver are from different faction
+ (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_MAIL) || // Config not enabled
+ !HasPermission(RBAC_PERM_TWO_SIDE_INTERACTION_MAIL) || // Sender cant mail interact with the other faction
+ !canReceiveMailFromOtherFaction)) // Receiver cant mail interact with the other faction
{
player->SendMailResult(0, MAIL_SEND, MAIL_ERR_NOT_YOUR_TEAM);
return;
}
- if (receiveLevel < sWorld->getIntConfig(CONFIG_MAIL_LEVEL_REQ))
+ if (receiverLevel < sWorld->getIntConfig(CONFIG_MAIL_LEVEL_REQ))
{
SendNotification(GetTrinityString(LANG_MAIL_RECEIVER_REQ), sWorld->getIntConfig(CONFIG_MAIL_LEVEL_REQ));
return;
}
- uint32 rc_account = receive
- ? receive->GetSession()->GetAccountId()
- : sObjectMgr->GetPlayerAccountIdByGUID(rc);
-
Item* items[MAX_MAIL_ITEMS];
for (uint8 i = 0; i < items_count; ++i)
@@ -216,7 +217,7 @@ void WorldSession::HandleSendMail(WorldPacket& recvData)
return;
}
- if (item->IsBoundAccountWide() && item->IsSoulBound() && player->GetSession()->GetAccountId() != rc_account)
+ if (item->IsBoundAccountWide() && item->IsSoulBound() && player->GetSession()->GetAccountId() != receiverAccountId)
{
player->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_ARTEFACTS_ONLY_FOR_OWN_CHARACTERS);
return;
@@ -256,35 +257,38 @@ void WorldSession::HandleSendMail(WorldPacket& recvData)
if (items_count > 0 || money > 0)
{
+ bool log = sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE) && HasPermission(RBAC_PERM_LOG_GM_TRADE);
if (items_count > 0)
{
for (uint8 i = 0; i < items_count; ++i)
{
Item* item = items[i];
- if (!AccountMgr::IsPlayerAccount(GetSecurity()) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE))
+ if (log)
{
- sLog->outCommand(GetAccountId(), "GM %s (Account: %u) mail item: %s (Entry: %u Count: %u) to player: %s (Account: %u)",
- GetPlayerName().c_str(), GetAccountId(), item->GetTemplate()->Name1.c_str(), item->GetEntry(), item->GetCount(), receiver.c_str(), rc_account);
+ sLog->outCommand(GetAccountId(), "GM %s (Account: %u) mail item: %s (Entry: %u Count: %u) "
+ "to player: %s (Account: %u)", GetPlayerName().c_str(), GetAccountId(),
+ item->GetTemplate()->Name1.c_str(), item->GetEntry(), item->GetCount(),
+ receiverName.c_str(), receiverAccountId);
}
item->SetNotRefundable(GetPlayer()); // makes the item no longer refundable
player->MoveItemFromInventory(items[i]->GetBagSlot(), item->GetSlot(), true);
item->DeleteFromInventoryDB(trans); // deletes item from character's inventory
- item->SetOwnerGUID(rc);
+ item->SetOwnerGUID(receiverGuid);
item->SaveToDB(trans); // recursive and not have transaction guard into self, item not in inventory and can be save standalone
draft.AddItem(item);
}
// if item send to character at another account, then apply item delivery delay
- needItemDelay = player->GetSession()->GetAccountId() != rc_account;
+ needItemDelay = player->GetSession()->GetAccountId() != receiverAccountId;
}
- if (money > 0 && !AccountMgr::IsPlayerAccount(GetSecurity()) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE))
+ if (log && money > 0)
{
sLog->outCommand(GetAccountId(), "GM %s (Account: %u) mail money: %u to player: %s (Account: %u)",
- GetPlayerName().c_str(), GetAccountId(), money, receiver.c_str(), rc_account);
+ GetPlayerName().c_str(), GetAccountId(), money, receiverName.c_str(), receiverAccountId);
}
}
@@ -295,7 +299,7 @@ void WorldSession::HandleSendMail(WorldPacket& recvData)
draft
.AddMoney(money)
.AddCOD(COD)
- .SendMailTo(trans, MailReceiver(receive, GUID_LOPART(rc)), MailSender(player), body.empty() ? MAIL_CHECK_MASK_COPIED : MAIL_CHECK_MASK_HAS_BODY, deliver_delay);
+ .SendMailTo(trans, MailReceiver(receiver, GUID_LOPART(receiverGuid)), MailSender(player), body.empty() ? MAIL_CHECK_MASK_COPIED : MAIL_CHECK_MASK_HAS_BODY, deliver_delay);
player->SaveInventoryAndGoldToDB(trans);
CharacterDatabase.CommitTransaction(trans);
@@ -458,17 +462,17 @@ void WorldSession::HandleMailTakeItem(WorldPacket& recvData)
if (m->COD > 0) //if there is COD, take COD money from player and send them to sender by mail
{
uint64 sender_guid = MAKE_NEW_GUID(m->sender, 0, HIGHGUID_PLAYER);
- Player* receive = ObjectAccessor::FindPlayer(sender_guid);
+ Player* receiver = ObjectAccessor::FindPlayer(sender_guid);
uint32 sender_accId = 0;
- if (!AccountMgr::IsPlayerAccount(GetSecurity()) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE))
+ if (HasPermission(RBAC_PERM_LOG_GM_TRADE) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE))
{
std::string sender_name;
- if (receive)
+ if (receiver)
{
- sender_accId = receive->GetSession()->GetAccountId();
- sender_name = receive->GetName();
+ sender_accId = receiver->GetSession()->GetAccountId();
+ sender_name = receiver->GetName();
}
else
{
@@ -478,18 +482,18 @@ void WorldSession::HandleMailTakeItem(WorldPacket& recvData)
if (!sObjectMgr->GetPlayerNameByGUID(sender_guid, sender_name))
sender_name = sObjectMgr->GetTrinityStringForDBCLocale(LANG_UNKNOWN);
}
- sLog->outCommand(GetAccountId(), "GM %s (Account: %u) receive mail item: %s (Entry: %u Count: %u) and send COD money: %u to player: %s (Account: %u)",
+ sLog->outCommand(GetAccountId(), "GM %s (Account: %u) receiver mail item: %s (Entry: %u Count: %u) and send COD money: %u to player: %s (Account: %u)",
GetPlayerName().c_str(), GetAccountId(), it->GetTemplate()->Name1.c_str(), it->GetEntry(), it->GetCount(), m->COD, sender_name.c_str(), sender_accId);
}
- else if (!receive)
+ else if (!receiver)
sender_accId = sObjectMgr->GetPlayerAccountIdByGUID(sender_guid);
// check player existence
- if (receive || sender_accId)
+ if (receiver || sender_accId)
{
MailDraft(m->subject, "")
.AddMoney(m->COD)
- .SendMailTo(trans, MailReceiver(receive, m->sender), MailSender(MAIL_NORMAL, m->receiver), MAIL_CHECK_MASK_COD_PAYMENT);
+ .SendMailTo(trans, MailReceiver(receiver, m->sender), MailSender(MAIL_NORMAL, m->receiver), MAIL_CHECK_MASK_COD_PAYMENT);
}
player->ModifyMoney(-int32(m->COD));
diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp
index 14bff05a412..3864acb8f88 100644
--- a/src/server/game/Handlers/MiscHandler.cpp
+++ b/src/server/game/Handlers/MiscHandler.cpp
@@ -241,7 +241,7 @@ void WorldSession::HandleWhoOpcode(WorldPacket& recvData)
level_max = STRONG_MAX_LEVEL;
uint32 team = _player->GetTeam();
- uint32 security = GetSecurity();
+
bool allowTwoSideWhoList = sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_WHO_LIST);
uint32 gmLevelInWhoList = sWorld->getIntConfig(CONFIG_GM_LEVEL_IN_WHO_LIST);
uint32 displaycount = 0;
@@ -254,42 +254,40 @@ void WorldSession::HandleWhoOpcode(WorldPacket& recvData)
HashMapHolder<Player>::MapType const& m = sObjectAccessor->GetPlayers();
for (HashMapHolder<Player>::MapType::const_iterator itr = m.begin(); itr != m.end(); ++itr)
{
- if (AccountMgr::IsPlayerAccount(security))
- {
- // player can see member of other team only if CONFIG_ALLOW_TWO_SIDE_WHO_LIST
- if (itr->second->GetTeam() != team && !allowTwoSideWhoList)
- continue;
+ Player* target = itr->second;
+ // player can see member of other team only if CONFIG_ALLOW_TWO_SIDE_WHO_LIST
+ if (target->GetTeam() != team && !allowTwoSideWhoList && !HasPermission(RBAC_PERM_TWO_SIDE_WHO_LIST))
+ continue;
- // player can see MODERATOR, GAME MASTER, ADMINISTRATOR only if CONFIG_GM_IN_WHO_LIST
- if ((itr->second->GetSession()->GetSecurity() > AccountTypes(gmLevelInWhoList)))
- continue;
- }
+ // player can see MODERATOR, GAME MASTER, ADMINISTRATOR only if CONFIG_GM_IN_WHO_LIST
+ if (!HasPermission(RBAC_PERM_WHO_SEE_ALL_SEC_LEVELS) && target->GetSession()->GetSecurity() > AccountTypes(gmLevelInWhoList))
+ continue;
- //do not process players which are not in world
- if (!(itr->second->IsInWorld()))
+ // do not process players which are not in world
+ if (!target->IsInWorld())
continue;
// check if target is globally visible for player
- if (!(itr->second->IsVisibleGloballyFor(_player)))
+ if (!target->IsVisibleGloballyFor(_player))
continue;
// check if target's level is in level range
- uint8 lvl = itr->second->getLevel();
+ uint8 lvl = target->getLevel();
if (lvl < level_min || lvl > level_max)
continue;
// check if class matches classmask
- uint32 class_ = itr->second->getClass();
+ uint8 class_ = target->getClass();
if (!(classmask & (1 << class_)))
continue;
// check if race matches racemask
- uint32 race = itr->second->getRace();
+ uint32 race = target->getRace();
if (!(racemask & (1 << race)))
continue;
- uint32 pzoneid = itr->second->GetZoneId();
- uint8 gender = itr->second->getGender();
+ uint32 pzoneid = target->GetZoneId();
+ uint8 gender = target->getGender();
bool z_show = true;
for (uint32 i = 0; i < zones_count; ++i)
@@ -305,7 +303,7 @@ void WorldSession::HandleWhoOpcode(WorldPacket& recvData)
if (!z_show)
continue;
- std::string pname = itr->second->GetName();
+ std::string pname = target->GetName();
std::wstring wpname;
if (!Utf8toWStr(pname, wpname))
continue;
@@ -314,7 +312,7 @@ void WorldSession::HandleWhoOpcode(WorldPacket& recvData)
if (!(wplayer_name.empty() || wpname.find(wplayer_name) != std::wstring::npos))
continue;
- std::string gname = sGuildMgr->GetGuildNameById(itr->second->GetGuildId());
+ std::string gname = sGuildMgr->GetGuildNameById(target->GetGuildId());
std::wstring wgname;
if (!Utf8toWStr(gname, wgname))
continue;
@@ -324,7 +322,7 @@ void WorldSession::HandleWhoOpcode(WorldPacket& recvData)
continue;
std::string aname;
- if (AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(itr->second->GetZoneId()))
+ if (AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(pzoneid))
aname = areaEntry->area_name[GetSessionDbcLocale()];
bool s_show = true;
@@ -575,13 +573,14 @@ void WorldSession::HandleAddFriendOpcodeCallBack(PreparedQueryResult result, std
team = Player::TeamForRace(fields[1].GetUInt8());
friendAccountId = fields[2].GetUInt32();
- if (!AccountMgr::IsPlayerAccount(GetSecurity()) || sWorld->getBoolConfig(CONFIG_ALLOW_GM_FRIEND) || AccountMgr::IsPlayerAccount(AccountMgr::GetSecurity(friendAccountId, realmID)))
+ if (HasPermission(RBAC_PERM_ALLOW_GM_FRIEND) || sWorld->getBoolConfig(CONFIG_ALLOW_GM_FRIEND) ||
+ AccountMgr::IsPlayerAccount(AccountMgr::GetSecurity(friendAccountId, realmID)))
{
if (friendGuid)
{
if (friendGuid == GetPlayer()->GetGUID())
friendResult = FRIEND_SELF;
- else if (GetPlayer()->GetTeam() != team && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_ADD_FRIEND) && AccountMgr::IsPlayerAccount(GetSecurity()))
+ else if (GetPlayer()->GetTeam() != team && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_ADD_FRIEND) && !HasPermission(RBAC_PERM_TWO_SIDE_ADD_FRIEND))
friendResult = FRIEND_ENEMY;
else if (GetPlayer()->GetSocial()->HasFriend(GUID_LOPART(friendGuid)))
friendResult = FRIEND_ALREADY;
@@ -1248,7 +1247,7 @@ void WorldSession::HandleWorldTeleportOpcode(WorldPacket& recvData)
sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_WORLD_TELEPORT: Player = %s, Time = %u, map = %u, x = %f, y = %f, z = %f, o = %f",
GetPlayer()->GetName().c_str(), time, mapid, PositionX, PositionY, PositionZ, Orientation);
- if (AccountMgr::IsAdminAccount(GetSecurity()))
+ if (HasPermission(RBAC_PERM_OPCODE_WORLD_TELEPORT))
GetPlayer()->TeleportTo(mapid, PositionX, PositionY, PositionZ, Orientation);
else
SendNotification(LANG_YOU_NOT_HAVE_PERMISSION);
@@ -1260,7 +1259,7 @@ void WorldSession::HandleWhoisOpcode(WorldPacket& recvData)
std::string charname;
recvData >> charname;
- if (!AccountMgr::IsAdminAccount(GetSecurity()))
+ if (HasPermission(RBAC_PERM_OPCODE_WHOIS))
{
SendNotification(LANG_YOU_NOT_HAVE_PERMISSION);
return;
diff --git a/src/server/game/Handlers/TradeHandler.cpp b/src/server/game/Handlers/TradeHandler.cpp
index bb31b5c1dc8..7fbb68b70f8 100644
--- a/src/server/game/Handlers/TradeHandler.cpp
+++ b/src/server/game/Handlers/TradeHandler.cpp
@@ -152,7 +152,7 @@ void WorldSession::moveItems(Item* myItems[], Item* hisItems[])
{
// logging
sLog->outDebug(LOG_FILTER_NETWORKIO, "partner storing: %u", myItems[i]->GetGUIDLow());
- if (!AccountMgr::IsPlayerAccount(_player->GetSession()->GetSecurity()) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE))
+ if (HasPermission(RBAC_PERM_LOG_GM_TRADE) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE))
{
sLog->outCommand(_player->GetSession()->GetAccountId(), "GM %s (Account: %u) trade: %s (Entry: %d Count: %u) to player: %s (Account: %u)",
_player->GetName().c_str(), _player->GetSession()->GetAccountId(),
@@ -170,7 +170,7 @@ void WorldSession::moveItems(Item* myItems[], Item* hisItems[])
{
// logging
sLog->outDebug(LOG_FILTER_NETWORKIO, "player storing: %u", hisItems[i]->GetGUIDLow());
- if (!AccountMgr::IsPlayerAccount(trader->GetSession()->GetSecurity()) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE))
+ if (HasPermission(RBAC_PERM_LOG_GM_TRADE) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE))
{
sLog->outCommand(trader->GetSession()->GetAccountId(), "GM %s (Account: %u) trade: %s (Entry: %d Count: %u) to player: %s (Account: %u)",
trader->GetName().c_str(), trader->GetSession()->GetAccountId(),
@@ -473,16 +473,17 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/)
moveItems(myItems, hisItems);
// logging money
- if (sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE))
+ if (HasPermission(RBAC_PERM_LOG_GM_TRADE) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE))
{
- if (!AccountMgr::IsPlayerAccount(_player->GetSession()->GetSecurity()) && my_trade->GetMoney() > 0)
+ if (my_trade->GetMoney() > 0)
{
sLog->outCommand(_player->GetSession()->GetAccountId(), "GM %s (Account: %u) give money (Amount: %u) to player: %s (Account: %u)",
_player->GetName().c_str(), _player->GetSession()->GetAccountId(),
my_trade->GetMoney(),
trader->GetName().c_str(), trader->GetSession()->GetAccountId());
}
- if (!AccountMgr::IsPlayerAccount(trader->GetSession()->GetSecurity()) && his_trade->GetMoney() > 0)
+
+ if (his_trade->GetMoney() > 0)
{
sLog->outCommand(trader->GetSession()->GetAccountId(), "GM %s (Account: %u) give money (Amount: %u) to player: %s (Account: %u)",
trader->GetName().c_str(), trader->GetSession()->GetAccountId(),
diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h
index a2d1cdd83dd..6f60aec4beb 100644
--- a/src/server/game/Miscellaneous/SharedDefines.h
+++ b/src/server/game/Miscellaneous/SharedDefines.h
@@ -297,7 +297,7 @@ enum SpellAttr0
SPELL_ATTR0_CASTABLE_WHILE_SITTING = 0x08000000, // 27 castable while sitting
SPELL_ATTR0_CANT_USED_IN_COMBAT = 0x10000000, // 28 Cannot be used in combat
SPELL_ATTR0_UNAFFECTED_BY_INVULNERABILITY = 0x20000000, // 29 unaffected by invulnerability (hmm possible not...)
- SPELL_ATTR0_BREAKABLE_BY_DAMAGE = 0x40000000, // 30
+ SPELL_ATTR0_HEARTBEAT_RESIST_CHECK = 0x40000000, // 30 random chance the effect will end TODO: implement core support
SPELL_ATTR0_CANT_CANCEL = 0x80000000 // 31 positive aura can't be canceled
};
@@ -489,7 +489,7 @@ enum SpellAttr6
SPELL_ATTR6_UNK3 = 0x00000008, // 3
SPELL_ATTR6_UNK4 = 0x00000010, // 4
SPELL_ATTR6_UNK5 = 0x00000020, // 5
- SPELL_ATTR6_UNK6 = 0x00000040, // 6
+ SPELL_ATTR6_PRINT_SPELLNAME = 0x00000040, // 6 when activated, spell name is shown at the center of the screen: <Spell name> (client-side attribute)
SPELL_ATTR6_UNK7 = 0x00000080, // 7
SPELL_ATTR6_CANT_TARGET_CROWD_CONTROLLED = 0x00000100, // 8
SPELL_ATTR6_UNK9 = 0x00000200, // 9
diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp
index 610047dac2f..1e36f342712 100644
--- a/src/server/game/Server/WorldSession.cpp
+++ b/src/server/game/Server/WorldSession.cpp
@@ -24,6 +24,7 @@
#include "Config.h"
#include "Common.h"
#include "DatabaseEnv.h"
+#include "AccountMgr.h"
#include "Log.h"
#include "Opcodes.h"
#include "WorldPacket.h"
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index 42242e93742..20fa7d9335d 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -24,7 +24,6 @@
#define __WORLDSESSION_H
#include "Common.h"
-#include "AccountMgr.h"
#include "SharedDefines.h"
#include "AddonMgr.h"
#include "DatabaseEnv.h"
@@ -40,6 +39,7 @@ class LoginQueryHolder;
class Object;
class Player;
class Quest;
+class RBACData;
class SpellCastTargets;
class Unit;
class Warden;
diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp
index de5dd1dd98b..128175d785b 100644
--- a/src/server/game/Server/WorldSocket.cpp
+++ b/src/server/game/Server/WorldSocket.cpp
@@ -980,7 +980,7 @@ int WorldSocket::HandlePing (WorldPacket& recvPacket)
{
ACE_GUARD_RETURN (LockType, Guard, m_SessionLock, -1);
- if (m_Session && AccountMgr::IsPlayerAccount(m_Session->GetSecurity()))
+ if (m_Session && !m_Session->HasPermission(RBAC_PERM_SKIP_CHECK_OVERSPEED_PING))
{
sLog->outError(LOG_FILTER_NETWORKIO, "WorldSocket::HandlePing: %s kicked for over-speed pings (address: %s)",
m_Session->GetPlayerInfo().c_str(), GetRemoteAddress().c_str());
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 53bcd6bd077..ae1389c5f11 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -5942,8 +5942,9 @@ SpellCastResult Spell::CheckItems()
// if not item target then required item must be equipped
else
{
- if (m_caster->GetTypeId() == TYPEID_PLAYER && !m_caster->ToPlayer()->HasItemFitToSpellRequirements(m_spellInfo))
- return SPELL_FAILED_EQUIPPED_ITEM_CLASS;
+ if (!(_triggeredCastFlags & TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT))
+ if (m_caster->GetTypeId() == TYPEID_PLAYER && !m_caster->ToPlayer()->HasItemFitToSpellRequirements(m_spellInfo))
+ return SPELL_FAILED_EQUIPPED_ITEM_CLASS;
}
// check spell focus object
@@ -6325,7 +6326,7 @@ SpellCastResult Spell::CheckItems()
}
// check weapon presence in slots for main/offhand weapons
- if (m_spellInfo->EquippedItemClass >=0)
+ if (!(_triggeredCastFlags & TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT) && m_spellInfo->EquippedItemClass >=0)
{
// main hand weapon required
if (m_spellInfo->AttributesEx3 & SPELL_ATTR3_MAIN_HAND)
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index f5504f8b7c1..9d3ec6630e5 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -2763,7 +2763,7 @@ void Spell::EffectEnchantItemPerm(SpellEffIndex effIndex)
if (!item_owner)
return;
- if (item_owner != p_caster && !AccountMgr::IsPlayerAccount(p_caster->GetSession()->GetSecurity()) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE))
+ if (item_owner != p_caster && p_caster->GetSession()->HasPermission(RBAC_PERM_LOG_GM_TRADE) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE))
{
sLog->outCommand(p_caster->GetSession()->GetAccountId(), "GM %s (Account: %u) enchanting(perm): %s (Entry: %d) for player: %s (Account: %u)",
p_caster->GetName().c_str(), p_caster->GetSession()->GetAccountId(),
@@ -2828,7 +2828,7 @@ void Spell::EffectEnchantItemPrismatic(SpellEffIndex effIndex)
if (!item_owner)
return;
- if (item_owner != p_caster && !AccountMgr::IsPlayerAccount(p_caster->GetSession()->GetSecurity()) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE))
+ if (item_owner != p_caster && p_caster->GetSession()->HasPermission(RBAC_PERM_LOG_GM_TRADE) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE))
{
sLog->outCommand(p_caster->GetSession()->GetAccountId(), "GM %s (Account: %u) enchanting(perm): %s (Entry: %d) for player: %s (Account: %u)",
p_caster->GetName().c_str(), p_caster->GetSession()->GetAccountId(),
@@ -2962,7 +2962,7 @@ void Spell::EffectEnchantItemTmp(SpellEffIndex effIndex)
if (!item_owner)
return;
- if (item_owner != p_caster && !AccountMgr::IsPlayerAccount(p_caster->GetSession()->GetSecurity()) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE))
+ if (item_owner != p_caster && p_caster->GetSession()->HasPermission(RBAC_PERM_LOG_GM_TRADE) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE))
{
sLog->outCommand(p_caster->GetSession()->GetAccountId(), "GM %s (Account: %u) enchanting(temp): %s (Entry: %d) for player: %s (Account: %u)",
p_caster->GetName().c_str(), p_caster->GetSession()->GetAccountId(),
diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp
index 9a9369bad28..d2ab1a315e8 100644
--- a/src/server/game/Spells/SpellInfo.cpp
+++ b/src/server/game/Spells/SpellInfo.cpp
@@ -1174,10 +1174,8 @@ bool SpellInfo::IsSingleTarget() const
bool SpellInfo::IsSingleTargetWith(SpellInfo const* spellInfo) const
{
- // TODO - need better check
- // Equal icon and spellfamily
- if (SpellFamilyName == spellInfo->SpellFamilyName &&
- SpellIconID == spellInfo->SpellIconID)
+ // Same spell?
+ if (IsRankOf(spellInfo))
return true;
SpellSpecificType spec = GetSpellSpecific();
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index 32ee21a7ca2..955f3b7b99f 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -2118,18 +2118,21 @@ void World::SendGlobalMessage(WorldPacket* packet, WorldSession* self, uint32 te
/// Send a packet to all GMs (except self if mentioned)
void World::SendGlobalGMMessage(WorldPacket* packet, WorldSession* self, uint32 team)
{
- SessionMap::iterator itr;
- for (itr = m_sessions.begin(); itr != m_sessions.end(); ++itr)
+ for (SessionMap::const_iterator itr = m_sessions.begin(); itr != m_sessions.end(); ++itr)
{
- if (itr->second &&
- itr->second->GetPlayer() &&
- itr->second->GetPlayer()->IsInWorld() &&
- itr->second != self &&
- !AccountMgr::IsPlayerAccount(itr->second->GetSecurity()) &&
- (team == 0 || itr->second->GetPlayer()->GetTeam() == team))
- {
- itr->second->SendPacket(packet);
- }
+ // check if session and can receive global GM Messages and its not self
+ WorldSession* session = itr->second;
+ if (!session || session == self || !session->HasPermission(RBAC_PERM_RECEIVE_GLOBAL_GM_TEXTMESSAGE))
+ continue;
+
+ // Player should be in world
+ Player* player = session->GetPlayer();
+ if (!player || !player->IsInWorld())
+ continue;
+
+ // Send only to same team, if team is given
+ if (!team || player->GetTeam() == team)
+ session->SendPacket(packet);
}
}
@@ -2217,15 +2220,19 @@ void World::SendGMText(int32 string_id, ...)
Trinity::WorldWorldTextBuilder wt_builder(string_id, &ap);
Trinity::LocalizedPacketListDo<Trinity::WorldWorldTextBuilder> wt_do(wt_builder);
- for (SessionMap::iterator itr = m_sessions.begin(); itr != m_sessions.end(); ++itr)
+ for (SessionMap::const_iterator itr = m_sessions.begin(); itr != m_sessions.end(); ++itr)
{
- if (!itr->second || !itr->second->GetPlayer() || !itr->second->GetPlayer()->IsInWorld())
+ // Session should have permissions to receive global gm messages
+ WorldSession* session = itr->second;
+ if (!session || !session->HasPermission(RBAC_PERM_RECEIVE_GLOBAL_GM_TEXTMESSAGE))
continue;
- if (AccountMgr::IsPlayerAccount(itr->second->GetSecurity()))
+ // Player should be in world
+ Player* player = session->GetPlayer();
+ if (!player || !player->IsInWorld())
continue;
- wt_do(itr->second->GetPlayer());
+ wt_do(player);
}
va_end(ap);
diff --git a/src/server/scripts/Commands/cs_gm.cpp b/src/server/scripts/Commands/cs_gm.cpp
index 932bb562f11..168a5ec60b8 100644
--- a/src/server/scripts/Commands/cs_gm.cpp
+++ b/src/server/scripts/Commands/cs_gm.cpp
@@ -59,30 +59,32 @@ public:
// Enables or disables hiding of the staff badge
static bool HandleGMChatCommand(ChatHandler* handler, char const* args)
{
- if (!*args)
+ if (WorldSession* session = handler->GetSession())
{
- WorldSession* session = handler->GetSession();
- if (!AccountMgr::IsPlayerAccount(session->GetSecurity()) && session->GetPlayer()->isGMChat())
- session->SendNotification(LANG_GM_CHAT_ON);
- else
- session->SendNotification(LANG_GM_CHAT_OFF);
- return true;
- }
+ if (!*args)
+ {
+ if (session->HasPermission(RBAC_PERM_CHAT_USE_STAFF_BADGE) && session->GetPlayer()->isGMChat())
+ session->SendNotification(LANG_GM_CHAT_ON);
+ else
+ session->SendNotification(LANG_GM_CHAT_OFF);
+ return true;
+ }
- std::string param = (char*)args;
+ std::string param = (char*)args;
- if (param == "on")
- {
- handler->GetSession()->GetPlayer()->SetGMChat(true);
- handler->GetSession()->SendNotification(LANG_GM_CHAT_ON);
- return true;
- }
+ if (param == "on")
+ {
+ session->GetPlayer()->SetGMChat(true);
+ session->SendNotification(LANG_GM_CHAT_ON);
+ return true;
+ }
- if (param == "off")
- {
- handler->GetSession()->GetPlayer()->SetGMChat(false);
- handler->GetSession()->SendNotification(LANG_GM_CHAT_OFF);
- return true;
+ if (param == "off")
+ {
+ session->GetPlayer()->SetGMChat(false);
+ session->SendNotification(LANG_GM_CHAT_OFF);
+ return true;
+ }
}
handler->SendSysMessage(LANG_USE_BOL);
@@ -126,7 +128,9 @@ public:
for (HashMapHolder<Player>::MapType::const_iterator itr = m.begin(); itr != m.end(); ++itr)
{
AccountTypes itrSec = itr->second->GetSession()->GetSecurity();
- if ((itr->second->isGameMaster() || (!AccountMgr::IsPlayerAccount(itrSec) && itrSec <= AccountTypes(sWorld->getIntConfig(CONFIG_GM_LEVEL_IN_GM_LIST)))) &&
+ if ((itr->second->isGameMaster() ||
+ (itr->second->GetSession()->HasPermission(RBAC_PERM_COMMANDS_APPEAR_IN_GM_LIST) &&
+ itrSec <= AccountTypes(sWorld->getIntConfig(CONFIG_GM_LEVEL_IN_GM_LIST)))) &&
(!handler->GetSession() || itr->second->IsVisibleGloballyFor(handler->GetSession()->GetPlayer())))
{
if (first)
diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp
index cacefea7b85..4cdc1e0d9ce 100644
--- a/src/server/scripts/Commands/cs_misc.cpp
+++ b/src/server/scripts/Commands/cs_misc.cpp
@@ -678,7 +678,7 @@ public:
if (target)
{
- target->ResurrectPlayer(!AccountMgr::IsPlayerAccount(target->GetSession()->GetSecurity()) ? 1.0f : 0.5f);
+ target->ResurrectPlayer(target->GetSession()->HasPermission(RBAC_PERM_RESURRECT_WITH_FULL_HPS) ? 1.0f : 0.5f);
target->SpawnCorpseBones();
target->SaveToDB();
}
@@ -881,7 +881,7 @@ public:
Player* player = handler->GetSession()->GetPlayer();
// save GM account without delay and output message
- if (!AccountMgr::IsPlayerAccount(handler->GetSession()->GetSecurity()))
+ if (handler->GetSession()->HasPermission(RBAC_PERM_COMMANDS_SAVE_WITHOUT_DELAY))
{
if (Player* target = handler->getSelectedPlayer())
target->SaveToDB();
@@ -938,8 +938,8 @@ public:
static bool HandleUnstuckCommand(ChatHandler* handler, char const* args)
{
- //No args required for players
- if (handler->GetSession() && AccountMgr::IsPlayerAccount(handler->GetSession()->GetSecurity()))
+ // No args required for players
+ if (handler->GetSession() && !handler->GetSession()->HasPermission(RBAC_PERM_COMMANDS_USE_UNSTUCK_WITH_ARGS))
{
// 7355: "Stuck"
if (Player* player = handler->GetSession()->GetPlayer())
diff --git a/src/server/scripts/Commands/cs_rbac.cpp b/src/server/scripts/Commands/cs_rbac.cpp
index 092aabb0045..604218c2e68 100644
--- a/src/server/scripts/Commands/cs_rbac.cpp
+++ b/src/server/scripts/Commands/cs_rbac.cpp
@@ -22,7 +22,7 @@ Comment: All role based access control related commands (including account relat
Category: commandscripts
EndScriptData */
-#include "RBAC.h"
+#include "AccountMgr.h"
#include "Config.h"
#include "Chat.h"
#include "Language.h"
@@ -188,7 +188,7 @@ public:
if (!rdata)
{
- data->rbac = new RBACData(accountId, accountName, ConfigMgr::GetIntDefault("RealmID", 0));
+ data->rbac = new RBACData(accountId, accountName, realmID);
data->rbac->LoadFromDB();
data->needDelete = true;
}
diff --git a/src/server/scripts/Commands/cs_ticket.cpp b/src/server/scripts/Commands/cs_ticket.cpp
index aee01f47581..958eb1709d5 100644
--- a/src/server/scripts/Commands/cs_ticket.cpp
+++ b/src/server/scripts/Commands/cs_ticket.cpp
@@ -95,18 +95,16 @@ public:
return true;
}
- // Get target information
- uint64 targetGuid = sObjectMgr->GetPlayerGUIDByName(target.c_str());
- uint64 targetAccountId = sObjectMgr->GetPlayerAccountIdByGUID(targetGuid);
- uint32 targetGmLevel = AccountMgr::GetSecurity(targetAccountId, realmID);
-
+ uint32 accountId = AccountMgr::GetId(target);
// Target must exist and have administrative rights
- if (!targetGuid || AccountMgr::IsPlayerAccount(targetGmLevel))
+ if (!AccountMgr::HasPermission(accountId, RBAC_PERM_COMMANDS_BE_ASSIGNED_TICKET, realmID))
{
handler->SendSysMessage(LANG_COMMAND_TICKETASSIGNERROR_A);
return true;
}
+ uint64 targetGuid = sObjectMgr->GetPlayerGUIDByName(target);
+
// If already assigned, leave
if (ticket->IsAssignedTo(targetGuid))
{
@@ -125,7 +123,7 @@ public:
// Assign ticket
SQLTransaction trans = SQLTransaction(NULL);
- ticket->SetAssignedTo(targetGuid, AccountMgr::IsAdminAccount(targetGmLevel));
+ ticket->SetAssignedTo(targetGuid, AccountMgr::IsAdminAccount(AccountMgr::GetSecurity(accountId, realmID)));
ticket->SaveToDB(trans);
sTicketMgr->UpdateLastChange();
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp
index 593d9586156..db4ab2f32d2 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp
@@ -954,7 +954,7 @@ class instance_icecrown_citadel : public InstanceMapScript
bool CheckRequiredBosses(uint32 bossId, Player const* player = NULL) const
{
- if (player && AccountMgr::IsGMAccount(player->GetSession()->GetSecurity()))
+ if (player && player->GetSession()->HasPermission(RBAC_PERM_SKIP_CHECK_INSTANCE_REQUIRED_BOSSES))
return true;
switch (bossId)
diff --git a/src/server/scripts/World/areatrigger_scripts.cpp b/src/server/scripts/World/areatrigger_scripts.cpp
index 83fac35b1b6..65ebb46c5dd 100644
--- a/src/server/scripts/World/areatrigger_scripts.cpp
+++ b/src/server/scripts/World/areatrigger_scripts.cpp
@@ -432,10 +432,10 @@ class AreaTrigger_at_area_52_entrance : public AreaTriggerScript
enum FrostgripsHollow
{
QUEST_THE_LONESOME_WATCHER = 12877,
-
+
NPC_STORMFORGED_MONITOR = 29862,
NPC_STORMFORGED_ERADICTOR = 29861,
-
+
TYPE_WAYPOINT = 0,
DATA_START = 0
};
@@ -460,11 +460,11 @@ public:
Creature* stormforgedMonitor = Creature::GetCreature(*player, stormforgedMonitorGUID);
if (stormforgedMonitor)
return false;
-
+
Creature* stormforgedEradictor = Creature::GetCreature(*player, stormforgedEradictorGUID);
if (stormforgedEradictor)
return false;
-
+
if ((stormforgedMonitor = player->SummonCreature(NPC_STORMFORGED_MONITOR, stormforgedMonitorPosition, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000)))
{
stormforgedMonitorGUID = stormforgedMonitor->GetGUID();
@@ -479,7 +479,7 @@ public:
stormforgedEradictorGUID = stormforgedEradictor->GetGUID();
stormforgedEradictor->GetMotionMaster()->MovePath(NPC_STORMFORGED_ERADICTOR * 100, false);
}
-
+
return true;
}
diff --git a/src/server/shared/Database/DatabaseWorkerPool.h b/src/server/shared/Database/DatabaseWorkerPool.h
index fa02b1d369a..c43cc8fab82 100644
--- a/src/server/shared/Database/DatabaseWorkerPool.h
+++ b/src/server/shared/Database/DatabaseWorkerPool.h
@@ -222,7 +222,7 @@ class DatabaseWorkerPool
//! Directly executes an SQL query in string format that will block the calling thread until finished.
//! Returns reference counted auto pointer, no need for manual memory management in upper level code.
- QueryResult Query(const char* sql, MySQLConnection* conn = NULL)
+ QueryResult Query(const char* sql, T* conn = NULL)
{
if (!conn)
conn = GetFreeConnection();
@@ -241,7 +241,7 @@ class DatabaseWorkerPool
//! Directly executes an SQL query in string format -with variable args- that will block the calling thread until finished.
//! Returns reference counted auto pointer, no need for manual memory management in upper level code.
- QueryResult PQuery(const char* sql, MySQLConnection* conn, ...)
+ QueryResult PQuery(const char* sql, T* conn, ...)
{
if (!sql)
return QueryResult(NULL);
@@ -380,7 +380,7 @@ class DatabaseWorkerPool
//! were appended to the transaction will be respected during execution.
void DirectCommitTransaction(SQLTransaction& transaction)
{
- MySQLConnection* con = GetFreeConnection();
+ T* con = GetFreeConnection();
if (con->ExecuteTransaction(transaction))
{
con->Unlock(); // OK, operation succesful
@@ -490,17 +490,17 @@ class DatabaseWorkerPool
{
uint8 i = 0;
size_t num_cons = _connectionCount[IDX_SYNCH];
+ T* t = NULL;
//! Block forever until a connection is free
for (;;)
{
- T* t = _connections[IDX_SYNCH][++i % num_cons];
+ t = _connections[IDX_SYNCH][++i % num_cons];
//! Must be matched with t->Unlock() or you will get deadlocks
if (t->LockIfReady())
- return t;
+ break;
}
- //! This will be called when Celine Dion learns to sing
- return NULL;
+ return t;
}
char const* GetDatabaseName() const
diff --git a/src/server/worldserver/TCSoap/TCSoap.cpp b/src/server/worldserver/TCSoap/TCSoap.cpp
index 7d460da4f83..dd82c6ce0c7 100644
--- a/src/server/worldserver/TCSoap/TCSoap.cpp
+++ b/src/server/worldserver/TCSoap/TCSoap.cpp
@@ -18,6 +18,9 @@
#include "TCSoap.h"
#include "soapH.h"
#include "soapStub.h"
+#include "World.h"
+#include "AccountMgr.h"
+#include "Log.h"
void TCSoapRunnable::run()
{
diff --git a/src/server/worldserver/TCSoap/TCSoap.h b/src/server/worldserver/TCSoap/TCSoap.h
index ccdc7b1f89f..b786ee94e81 100644
--- a/src/server/worldserver/TCSoap/TCSoap.h
+++ b/src/server/worldserver/TCSoap/TCSoap.h
@@ -18,17 +18,11 @@
#ifndef _TCSOAP_H
#define _TCSOAP_H
-#include "Common.h"
-#include "World.h"
-#include "AccountMgr.h"
-#include "Log.h"
-
-#include "soapH.h"
-#include "soapStub.h"
-#include "stdsoap2.h"
+#include "Define.h"
#include <ace/Semaphore.h>
#include <ace/Task.h>
+#include <Threading.h>
class TCSoapRunnable: public ACE_Based::Runnable
{