feat(Core/RBAC): Role Based Access Controls (#24641)
Co-authored-by: blinkysc <blinkysc@users.noreply.github.com> Co-authored-by: Spp <spp@jorge.gr> Co-authored-by: Spp <spp@tc.plus> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Andrew <47818697+Nyeriah@users.noreply.github.com>
This commit is contained in:
@@ -24,6 +24,7 @@
|
||||
#include "ObjectMgr.h"
|
||||
#include "Opcodes.h"
|
||||
#include "Player.h"
|
||||
#include "RBAC.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "World.h"
|
||||
#include "WorldPacket.h"
|
||||
@@ -321,6 +322,13 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData)
|
||||
|
||||
SendAuctionCommandResult(AH->Id, AUCTION_SELL_ITEM, ERR_AUCTION_OK);
|
||||
|
||||
if (HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE))
|
||||
{
|
||||
LOG_GM(GetAccountId(), "GM {} (Account: {}) created auction: {} (Item: {} Count: {}) Bid: {} Buyout: {}",
|
||||
_player->GetName(), GetAccountId(), AH->Id,
|
||||
item->GetTemplate()->Name1, item->GetCount(), bid, buyout);
|
||||
}
|
||||
|
||||
GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION, 1);
|
||||
|
||||
LOG_INFO("entities.player.auctionhouse", "AuctionHouse: Account: {} (IP: {}), Player [{}] (GUID: {}) created auction #{}: Item '{}' (Entry: {}) x{}, StartBid: {} copper, Buyout: {} copper, Deposit: {} copper",
|
||||
@@ -388,6 +396,13 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData)
|
||||
|
||||
SendAuctionCommandResult(AH->Id, AUCTION_SELL_ITEM, ERR_AUCTION_OK);
|
||||
|
||||
if (HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE))
|
||||
{
|
||||
LOG_GM(GetAccountId(), "GM {} (Account: {}) created auction: {} (Item: {} Count: {}) Bid: {} Buyout: {}",
|
||||
_player->GetName(), GetAccountId(), AH->Id,
|
||||
newItem->GetTemplate()->Name1, newItem->GetCount(), bid, buyout);
|
||||
}
|
||||
|
||||
GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION, 1);
|
||||
|
||||
LOG_INFO("entities.player.auctionhouse", "AuctionHouse: Account: {} (IP: {}), Player [{}] (GUID: {}) created auction #{}: Item '{}' (Entry: {}) x{}, StartBid: {} copper, Buyout: {} copper, Deposit: {} copper",
|
||||
@@ -501,6 +516,13 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket& recvData)
|
||||
|
||||
SendAuctionCommandResult(auction->Id, AUCTION_PLACE_BID, ERR_AUCTION_OK, 0);
|
||||
|
||||
if (HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE))
|
||||
{
|
||||
LOG_GM(GetAccountId(), "GM {} (Account: {}) bid on auction: {} (Item: {} Count: {}) Bid: {}",
|
||||
player->GetName(), GetAccountId(), auction->Id,
|
||||
auction->item_template, auction->itemCount, price);
|
||||
}
|
||||
|
||||
LOG_INFO("entities.player.auctionhouse", "AuctionHouse: Account: {} (IP: {}), Player [{}] (GUID: {}) placed bid on auction #{}: Item (Entry: {}) x{}, Bid: {} copper, Owner: {} (GUID: {})",
|
||||
GetAccountId(), GetRemoteAddress(), player->GetName(), player->GetGUID().GetCounter(),
|
||||
auction->Id, auction->item_template, auction->itemCount, price, auction->owner.GetCounter(), auction->owner.GetCounter());
|
||||
@@ -528,6 +550,13 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket& recvData)
|
||||
|
||||
SendAuctionCommandResult(auction->Id, AUCTION_PLACE_BID, ERR_AUCTION_OK);
|
||||
|
||||
if (HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE))
|
||||
{
|
||||
LOG_GM(GetAccountId(), "GM {} (Account: {}) bought out auction: {} (Item: {} Count: {}) Buyout: {}",
|
||||
player->GetName(), GetAccountId(), auction->Id,
|
||||
auction->item_template, auction->itemCount, auction->buyout);
|
||||
}
|
||||
|
||||
LOG_INFO("entities.player.auctionhouse", "AuctionHouse: Account: {} (IP: {}), Player [{}] (GUID: {}) bought out auction #{}: Item (Entry: {}) x{}, Buyout: {} copper, Owner: {} (GUID: {})",
|
||||
GetAccountId(), GetRemoteAddress(), player->GetName(), player->GetGUID().GetCounter(),
|
||||
auction->Id, auction->item_template, auction->itemCount, auction->buyout, auction->owner.GetCounter(), auction->owner.GetCounter());
|
||||
|
||||
@@ -161,7 +161,7 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData)
|
||||
{
|
||||
err = ERR_LFG_CANT_USE_BATTLEGROUND;
|
||||
}
|
||||
else if (!_player->CanJoinToBattleground()) // has deserter debuff
|
||||
else if (!_player->CanJoinToBattleground(bg)) // has deserter debuff
|
||||
{
|
||||
err = ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS;
|
||||
}
|
||||
@@ -473,7 +473,7 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket& recvData)
|
||||
if (action == 1 && ginfo.ArenaType == 0)
|
||||
{
|
||||
// can't join with deserter, check it here right before joining to be sure
|
||||
if (!_player->CanJoinToBattleground())
|
||||
if (!_player->CanJoinToBattleground(bg))
|
||||
{
|
||||
WorldPacket data;
|
||||
sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS);
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#include "AccountMgr.h"
|
||||
#include "AreaDefines.h"
|
||||
#include "RBAC.h"
|
||||
#include "ArenaTeamMgr.h"
|
||||
#include "AuctionHouseMgr.h"
|
||||
#include "Battleground.h"
|
||||
@@ -285,7 +286,7 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData)
|
||||
>> createInfo->FacialHair
|
||||
>> createInfo->OutfitId;
|
||||
|
||||
if (AccountMgr::IsPlayerAccount(GetSecurity()))
|
||||
if (!HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_TEAMMASK))
|
||||
{
|
||||
if (uint32 mask = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_DISABLED))
|
||||
{
|
||||
@@ -329,7 +330,7 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData)
|
||||
return;
|
||||
}
|
||||
|
||||
if (AccountMgr::IsPlayerAccount(GetSecurity()))
|
||||
if (!HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RACEMASK))
|
||||
{
|
||||
uint32 raceMaskDisabled = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_DISABLED_RACEMASK);
|
||||
if ((1 << (createInfo->Race - 1)) & raceMaskDisabled)
|
||||
@@ -337,7 +338,10 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData)
|
||||
SendCharCreate(CHAR_CREATE_DISABLED);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_CLASSMASK))
|
||||
{
|
||||
uint32 classMaskDisabled = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_DISABLED_CLASSMASK);
|
||||
if ((1 << (createInfo->Class - 1)) & classMaskDisabled)
|
||||
{
|
||||
@@ -358,13 +362,16 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData)
|
||||
uint8 res = ObjectMgr::CheckPlayerName(createInfo->Name, true);
|
||||
if (res != CHAR_NAME_SUCCESS)
|
||||
{
|
||||
SendCharCreate(ResponseCodes(res));
|
||||
return;
|
||||
if (res != CHAR_NAME_RESERVED || !HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME))
|
||||
{
|
||||
SendCharCreate(ResponseCodes(res));
|
||||
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()) && createInfo->Class == CLASS_DEATH_KNIGHT)
|
||||
if (heroic_free_slots == 0 && !HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_DEATH_KNIGHT) && createInfo->Class == CLASS_DEATH_KNIGHT)
|
||||
{
|
||||
SendCharCreate(CHAR_CREATE_UNIQUE_CLASS_LIMIT);
|
||||
return;
|
||||
@@ -372,7 +379,7 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData)
|
||||
|
||||
// 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()) && createInfo->Class == CLASS_DEATH_KNIGHT && req_level_for_heroic > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
|
||||
if (!HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_DEATH_KNIGHT) && createInfo->Class == CLASS_DEATH_KNIGHT && req_level_for_heroic > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
|
||||
{
|
||||
SendCharCreate(CHAR_CREATE_LEVEL_REQUIREMENT);
|
||||
return;
|
||||
@@ -427,7 +434,7 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData)
|
||||
}
|
||||
}
|
||||
|
||||
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::RBAC_PERM_TWO_SIDE_CHARACTER_CREATION);
|
||||
uint32 skipCinematics = sWorld->getIntConfig(CONFIG_SKIP_CINEMATICS);
|
||||
|
||||
std::function<void(PreparedQueryResult)> finalizeCharacterCreation = [this, createInfo](PreparedQueryResult result)
|
||||
@@ -440,9 +447,9 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData)
|
||||
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::RBAC_PERM_TWO_SIDE_CHARACTER_CREATION);
|
||||
uint32 skipCinematics = sWorld->getIntConfig(CONFIG_SKIP_CINEMATICS);
|
||||
bool checkDeathKnightReqs = AccountMgr::IsPlayerAccount(GetSecurity()) && createInfo->Class == CLASS_DEATH_KNIGHT;
|
||||
bool checkDeathKnightReqs = !HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_DEATH_KNIGHT) && createInfo->Class == CLASS_DEATH_KNIGHT;
|
||||
|
||||
if (result)
|
||||
{
|
||||
@@ -1365,8 +1372,11 @@ void WorldSession::HandleCharRenameOpcode(WorldPacket& recvData)
|
||||
uint8 res = ObjectMgr::CheckPlayerName(renameInfo->Name, true);
|
||||
if (res != CHAR_NAME_SUCCESS)
|
||||
{
|
||||
SendCharRename(ResponseCodes(res), renameInfo.get());
|
||||
return;
|
||||
if (res != CHAR_NAME_RESERVED || !HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME))
|
||||
{
|
||||
SendCharRename(ResponseCodes(res), renameInfo.get());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that the character belongs to the current account, that rename at login is enabled
|
||||
@@ -1705,8 +1715,11 @@ void WorldSession::HandleCharCustomizeCallback(std::shared_ptr<CharacterCustomiz
|
||||
ResponseCodes res = static_cast<ResponseCodes>(ObjectMgr::CheckPlayerName(customizeInfo->Name, true));
|
||||
if (res != CHAR_NAME_SUCCESS)
|
||||
{
|
||||
SendCharCustomize(res, customizeInfo.get());
|
||||
return;
|
||||
if (res != CHAR_NAME_RESERVED || !HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME))
|
||||
{
|
||||
SendCharCustomize(res, customizeInfo.get());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// character with this name already exist
|
||||
@@ -2084,7 +2097,7 @@ void WorldSession::HandleCharFactionOrRaceChangeCallback(std::shared_ptr<Charact
|
||||
return;
|
||||
}
|
||||
|
||||
if (AccountMgr::IsPlayerAccount(GetSecurity()))
|
||||
if (!HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RACEMASK))
|
||||
{
|
||||
uint32 raceMaskDisabled = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_DISABLED_RACEMASK);
|
||||
if ((1 << (factionChangeInfo->Race - 1)) & raceMaskDisabled)
|
||||
@@ -2104,8 +2117,11 @@ void WorldSession::HandleCharFactionOrRaceChangeCallback(std::shared_ptr<Charact
|
||||
ResponseCodes res = static_cast<ResponseCodes>(ObjectMgr::CheckPlayerName(factionChangeInfo->Name, true));
|
||||
if (res != CHAR_NAME_SUCCESS)
|
||||
{
|
||||
SendCharFactionChange(res, factionChangeInfo.get());
|
||||
return;
|
||||
if (res != CHAR_NAME_RESERVED || !HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME))
|
||||
{
|
||||
SendCharFactionChange(res, factionChangeInfo.get());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// character with this name already exist
|
||||
@@ -2321,7 +2337,7 @@ void WorldSession::HandleCharFactionOrRaceChangeCallback(std::shared_ptr<Charact
|
||||
guild->DeleteMember(factionChangeInfo->Guid, false, false, true);
|
||||
}
|
||||
|
||||
if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_ADD_FRIEND))
|
||||
if (!HasPermission(rbac::RBAC_PERM_TWO_SIDE_ADD_FRIEND))
|
||||
{
|
||||
// Delete Friend List
|
||||
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_SOCIAL_BY_GUID);
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#include "AccountMgr.h"
|
||||
#include "CellImpl.h"
|
||||
#include "RBAC.h"
|
||||
#include "ChannelMgr.h"
|
||||
#include "Chat.h"
|
||||
#include "ChatPackets.h"
|
||||
@@ -112,7 +113,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
|
||||
}
|
||||
|
||||
// pussywizard: chatting on most chat types requires 2 hours played to prevent spam/abuse
|
||||
if (AccountMgr::IsPlayerAccount(GetSecurity()))
|
||||
if (!HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHAT_CHANNEL_REQ))
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
@@ -382,8 +383,8 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
|
||||
}
|
||||
|
||||
Player* receiver = ObjectAccessor::FindPlayerByName(to, false);
|
||||
bool senderIsPlayer = AccountMgr::IsPlayerAccount(GetSecurity());
|
||||
bool receiverIsPlayer = AccountMgr::IsPlayerAccount(receiver ? receiver->GetSession()->GetSecurity() : SEC_PLAYER);
|
||||
bool senderIsPlayer = !HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHAT);
|
||||
bool receiverIsPlayer = receiver ? !receiver->GetSession()->HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHAT) : true;
|
||||
|
||||
if (sender->GetLevel() < sWorld->getIntConfig(CONFIG_CHAT_WHISPER_LEVEL_REQ) && receiver != sender && receiver && !receiver->IsGameMaster())
|
||||
{
|
||||
@@ -391,7 +392,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!receiver || (senderIsPlayer && !receiverIsPlayer && !receiver->isAcceptWhispers() && !receiver->IsInWhisperWhiteList(sender->GetGUID())))
|
||||
if (!receiver || (lang != LANG_ADDON && !receiver->isAcceptWhispers() && receiver->GetSession()->HasPermission(rbac::RBAC_PERM_CAN_FILTER_WHISPERS) && !receiver->IsInWhisperWhiteList(sender->GetGUID())))
|
||||
{
|
||||
SendPlayerNotFoundNotice(to);
|
||||
return;
|
||||
@@ -404,7 +405,6 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
|
||||
return;
|
||||
}
|
||||
|
||||
// pussywizard: optimization
|
||||
if (GetPlayer()->HasAura(1852) && !receiver->IsGameMaster())
|
||||
{
|
||||
ChatHandler(this).SendNotification(LANG_GM_SILENCE, GetPlayer()->GetName());
|
||||
@@ -412,7 +412,9 @@ 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()))
|
||||
// We also do that if a player is under the required level for whispers.
|
||||
if (receiver->GetLevel() < sWorld->getIntConfig(CONFIG_CHAT_WHISPER_LEVEL_REQ) ||
|
||||
(HasPermission(rbac::RBAC_PERM_CAN_FILTER_WHISPERS) && !sender->isAcceptWhispers() && !sender->IsInWhisperWhiteList(receiver->GetGUID())))
|
||||
sender->AddWhisperWhiteList(receiver->GetGUID());
|
||||
|
||||
GetPlayer()->Whisper(msg, Language(lang), receiver);
|
||||
@@ -554,7 +556,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
|
||||
break;
|
||||
case CHAT_MSG_CHANNEL:
|
||||
{
|
||||
if (AccountMgr::IsPlayerAccount(GetSecurity()))
|
||||
if (!HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHAT_CHANNEL_REQ))
|
||||
{
|
||||
if (sender->GetLevel() < sWorld->getIntConfig(CONFIG_CHAT_CHANNEL_LEVEL_REQ))
|
||||
{
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#include "AccountMgr.h"
|
||||
#include "Chat.h"
|
||||
#include "RBAC.h"
|
||||
#include "CharacterCache.h"
|
||||
#include "DBCStores.h"
|
||||
#include "DatabaseEnv.h"
|
||||
@@ -38,9 +39,9 @@ bool WorldSession::CanOpenMailBox(ObjectGuid guid)
|
||||
{
|
||||
if (guid == _player->GetGUID())
|
||||
{
|
||||
if (_player->GetSession()->GetSecurity() < SEC_MODERATOR)
|
||||
if (!HasPermission(rbac::RBAC_PERM_COMMAND_MAILBOX))
|
||||
{
|
||||
LOG_ERROR("network.opcode", "{} attempt open mailbox in cheating way.", _player->GetName());
|
||||
LOG_WARN("cheat", "{} attempted to open mailbox by using a cheat.", _player->GetName());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -213,7 +214,7 @@ void WorldSession::HandleSendMail(WorldPacket& recvData)
|
||||
|
||||
uint32 rc_account = receive ? receive->GetSession()->GetAccountId() : sCharacterCache->GetCharacterAccountIdByGuid(receiverGuid);
|
||||
|
||||
if (/*!accountBound*/ GetAccountId() != rc_account && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_MAIL) && player->GetTeamId() != rc_teamId && AccountMgr::IsPlayerAccount(GetSecurity()))
|
||||
if (/*!accountBound*/ GetAccountId() != rc_account && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_MAIL) && player->GetTeamId() != rc_teamId && !HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_MAIL))
|
||||
{
|
||||
player->SendMailResult(0, MAIL_SEND, MAIL_ERR_NOT_YOUR_TEAM);
|
||||
return;
|
||||
@@ -286,6 +287,25 @@ void WorldSession::HandleSendMail(WorldPacket& recvData)
|
||||
|
||||
player->SendMailResult(0, MAIL_SEND, MAIL_OK);
|
||||
|
||||
if (HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE))
|
||||
{
|
||||
if (items_count > 0)
|
||||
{
|
||||
for (uint8 i = 0; i < items_count; ++i)
|
||||
{
|
||||
Item* item = items[i];
|
||||
LOG_GM(GetAccountId(), "GM {} (Account: {}) sent mail to {} (Account: {}) with item: {} (Entry: {} Count: {})",
|
||||
player->GetName(), GetAccountId(), receiver, rc_account,
|
||||
item->GetTemplate()->Name1, item->GetEntry(), item->GetCount());
|
||||
}
|
||||
}
|
||||
if (money > 0)
|
||||
{
|
||||
LOG_GM(GetAccountId(), "GM {} (Account: {}) sent mail to {} (Account: {}) with money: {}",
|
||||
player->GetName(), GetAccountId(), receiver, rc_account, money);
|
||||
}
|
||||
}
|
||||
|
||||
player->ModifyMoney(-int32(reqmoney));
|
||||
player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL, cost);
|
||||
|
||||
@@ -585,6 +605,12 @@ void WorldSession::HandleMailTakeItem(WorldPacket& recvData)
|
||||
it->SetState(ITEM_UNCHANGED); // need to set this state, otherwise item cannot be removed later, if neccessary
|
||||
player->MoveItemToInventory(dest, it, true);
|
||||
|
||||
if (HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE))
|
||||
{
|
||||
LOG_GM(GetAccountId(), "GM {} (Account: {}) took mail item: {} (Entry: {} Count: {}) from mailbox",
|
||||
player->GetName(), GetAccountId(), it->GetTemplate()->Name1, it->GetEntry(), count);
|
||||
}
|
||||
|
||||
player->SaveInventoryAndGoldToDB(trans);
|
||||
player->_SaveMail(trans);
|
||||
CharacterDatabase.CommitTransaction(trans);
|
||||
@@ -620,6 +646,12 @@ void WorldSession::HandleMailTakeMoney(WorldPacket& recvData)
|
||||
return;
|
||||
}
|
||||
|
||||
if (HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE))
|
||||
{
|
||||
LOG_GM(GetAccountId(), "GM {} (Account: {}) took mail money: {} from mailbox",
|
||||
player->GetName(), GetAccountId(), m->money);
|
||||
}
|
||||
|
||||
m->money = 0;
|
||||
m->state = MAIL_STATE_CHANGED;
|
||||
player->m_mailsUpdated = true;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#include "AccountMgr.h"
|
||||
#include "BattlefieldMgr.h"
|
||||
#include "RBAC.h"
|
||||
#include "Battleground.h"
|
||||
#include "BattlegroundMgr.h"
|
||||
#include "CharacterPackets.h"
|
||||
@@ -283,8 +284,6 @@ void WorldSession::HandleWhoOpcode(WorldPacket& recvData)
|
||||
levelMax = STRONG_MAX_LEVEL;
|
||||
|
||||
uint32 team = _player->GetTeamId();
|
||||
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;
|
||||
|
||||
@@ -294,20 +293,13 @@ void WorldSession::HandleWhoOpcode(WorldPacket& recvData)
|
||||
|
||||
for (auto const& target : sWhoListCacheMgr->GetWhoList())
|
||||
{
|
||||
if (AccountMgr::IsPlayerAccount(security))
|
||||
{
|
||||
// player can see member of other team only if CONFIG_ALLOW_TWO_SIDE_WHO_LIST
|
||||
if (target.GetTeamId() != team && !allowTwoSideWhoList)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// player can see member of other team only if CONFIG_ALLOW_TWO_SIDE_WHO_LIST
|
||||
if (target.GetTeamId() != team && !HasPermission(rbac::RBAC_PERM_TWO_SIDE_WHO_LIST))
|
||||
continue;
|
||||
|
||||
// player can see MODERATOR, GAME MASTER, ADMINISTRATOR only if CONFIG_GM_IN_WHO_LIST
|
||||
if (target.GetSecurity() > AccountTypes(gmLevelInWhoList))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// player can see MODERATOR, GAME MASTER, ADMINISTRATOR only if CONFIG_GM_IN_WHO_LIST
|
||||
if (!HasPermission(rbac::RBAC_PERM_WHO_SEE_ALL_SEC_LEVELS) && target.GetSecurity() > AccountTypes(gmLevelInWhoList))
|
||||
continue;
|
||||
|
||||
// check if target is globally visible for player
|
||||
if ((_player->GetGUID() != target.GetGuid() && !target.IsVisible()) &&
|
||||
@@ -429,7 +421,7 @@ void WorldSession::HandleLogoutRequestOpcode(WorldPackets::Character::LogoutRequ
|
||||
if (ObjectGuid lguid = GetPlayer()->GetLootGUID())
|
||||
DoLootRelease(lguid);
|
||||
|
||||
bool instantLogout = ((GetSecurity() >= 0 && uint32(GetSecurity()) >= sWorld->getIntConfig(CONFIG_INSTANT_LOGOUT))
|
||||
bool instantLogout = (HasPermission(rbac::RBAC_PERM_INSTANT_LOGOUT)
|
||||
|| (GetPlayer()->HasPlayerFlag(PLAYER_FLAGS_RESTING) && !GetPlayer()->IsInCombat())) || GetPlayer()->IsInFlight();
|
||||
|
||||
bool preventAfkSanctuaryLogout = sWorld->getIntConfig(CONFIG_AFK_PREVENT_LOGOUT) == 1
|
||||
@@ -1010,7 +1002,7 @@ void WorldSession::HandleInspectOpcode(WorldPacket& recv_data)
|
||||
WorldPacket data(SMSG_INSPECT_TALENT, guid_size + 4 + talent_points);
|
||||
data << player->GetPackGUID();
|
||||
|
||||
if (sWorld->getBoolConfig(CONFIG_TALENTS_INSPECTING) || _player->IsGameMaster())
|
||||
if (sWorld->getBoolConfig(CONFIG_TALENTS_INSPECTING) || _player->CanBeGameMaster())
|
||||
{
|
||||
player->BuildPlayerTalentsInfoData(&data);
|
||||
}
|
||||
@@ -1081,7 +1073,7 @@ void WorldSession::HandleWorldTeleportOpcode(WorldPacket& recv_data)
|
||||
|
||||
LOG_DEBUG("network", "CMSG_WORLD_TELEPORT: Player = {}, Time = {}, map = {}, x = {}, y = {}, z = {}, o = {}", GetPlayer()->GetName(), time, mapid, PositionX, PositionY, PositionZ, Orientation);
|
||||
|
||||
if (AccountMgr::IsAdminAccount(GetSecurity()))
|
||||
if (HasPermission(rbac::RBAC_PERM_OPCODE_WORLD_TELEPORT))
|
||||
GetPlayer()->TeleportTo(mapid, PositionX, PositionY, PositionZ, Orientation);
|
||||
else
|
||||
ChatHandler(this).SendNotification(LANG_PERMISSION_DENIED);
|
||||
@@ -1093,7 +1085,7 @@ void WorldSession::HandleWhoisOpcode(WorldPacket& recv_data)
|
||||
std::string charname;
|
||||
recv_data >> charname;
|
||||
|
||||
if (!AccountMgr::IsAdminAccount(GetSecurity()))
|
||||
if (!HasPermission(rbac::RBAC_PERM_OPCODE_WHOIS))
|
||||
{
|
||||
ChatHandler(this).SendNotification(LANG_PERMISSION_DENIED);
|
||||
return;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#include "AccountMgr.h"
|
||||
#include "Language.h"
|
||||
#include "RBAC.h"
|
||||
#include "Log.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "ObjectMgr.h"
|
||||
@@ -57,13 +58,13 @@ void WorldSession::HandleAddFriendOpcode(WorldPacket& recv_data)
|
||||
TeamId teamId = Player::TeamIdForRace(playerData->Race);
|
||||
FriendsResult friendResult = FRIEND_NOT_FOUND;
|
||||
|
||||
if (!AccountMgr::IsPlayerAccount(GetSecurity()) || sWorld->getBoolConfig(CONFIG_ALLOW_GM_FRIEND)|| AccountMgr::IsPlayerAccount(AccountMgr::GetSecurity(friendAccountId, realm.Id.Realm)))
|
||||
if (HasPermission(rbac::RBAC_PERM_ALLOW_GM_FRIEND) || sWorld->getBoolConfig(CONFIG_ALLOW_GM_FRIEND) || AccountMgr::IsPlayerAccount(AccountMgr::GetSecurity(friendAccountId, realm.Id.Realm)))
|
||||
{
|
||||
if (friendGuid)
|
||||
{
|
||||
if (friendGuid == GetPlayer()->GetGUID())
|
||||
friendResult = FRIEND_SELF;
|
||||
else if (GetPlayer()->GetTeamId() != teamId && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_ADD_FRIEND) && AccountMgr::IsPlayerAccount(GetSecurity()))
|
||||
else if (GetPlayer()->GetTeamId() != teamId && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_ADD_FRIEND) && !HasPermission(rbac::RBAC_PERM_TWO_SIDE_ADD_FRIEND))
|
||||
friendResult = FRIEND_ENEMY;
|
||||
else if (GetPlayer()->GetSocial()->HasFriend(friendGuid))
|
||||
friendResult = FRIEND_ALREADY;
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "ObjectAccessor.h"
|
||||
#include "Opcodes.h"
|
||||
#include "Player.h"
|
||||
#include "RBAC.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "SocialMgr.h"
|
||||
#include "Spell.h"
|
||||
@@ -504,6 +505,35 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/)
|
||||
trader->ModifyMoney(-int32(his_trade->GetMoney()));
|
||||
trader->ModifyMoney(my_trade->GetMoney());
|
||||
|
||||
if (HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE))
|
||||
{
|
||||
for (uint8 i = 0; i < TRADE_SLOT_TRADED_COUNT; ++i)
|
||||
{
|
||||
if (myItems[i])
|
||||
LOG_GM(GetAccountId(), "GM {} (Account: {}) traded item: {} (Entry: {} Count: {}) to {}",
|
||||
_player->GetName(), GetAccountId(),
|
||||
myItems[i]->GetTemplate()->Name1, myItems[i]->GetEntry(), myItems[i]->GetCount(),
|
||||
trader->GetName());
|
||||
}
|
||||
if (my_trade->GetMoney() > 0)
|
||||
LOG_GM(GetAccountId(), "GM {} (Account: {}) traded money: {} to {}",
|
||||
_player->GetName(), GetAccountId(), my_trade->GetMoney(), trader->GetName());
|
||||
}
|
||||
if (trader->GetSession()->HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE))
|
||||
{
|
||||
for (uint8 i = 0; i < TRADE_SLOT_TRADED_COUNT; ++i)
|
||||
{
|
||||
if (hisItems[i])
|
||||
LOG_GM(trader->GetSession()->GetAccountId(), "GM {} (Account: {}) traded item: {} (Entry: {} Count: {}) to {}",
|
||||
trader->GetName(), trader->GetSession()->GetAccountId(),
|
||||
hisItems[i]->GetTemplate()->Name1, hisItems[i]->GetEntry(), hisItems[i]->GetCount(),
|
||||
_player->GetName());
|
||||
}
|
||||
if (his_trade->GetMoney() > 0)
|
||||
LOG_GM(trader->GetSession()->GetAccountId(), "GM {} (Account: {}) traded money: {} to {}",
|
||||
trader->GetName(), trader->GetSession()->GetAccountId(), his_trade->GetMoney(), _player->GetName());
|
||||
}
|
||||
|
||||
// log completed trade
|
||||
LOG_INFO("entities.player.trade", "Trade: Account: {} (IP: {}), Player [{}] ({}) traded with Player [{}] ({}): gave {} copper, received {} copper, gave item(s) [{}], received item(s) [{}]",
|
||||
GetAccountId(), GetRemoteAddress(), _player->GetName(), _player->GetGUID().GetCounter(),
|
||||
@@ -671,7 +701,9 @@ void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_TRADE) && pOther->GetTeamId() != _player->GetTeamId())
|
||||
if (pOther->GetTeamId() != _player->GetTeamId() &&
|
||||
!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_TRADE) &&
|
||||
!GetPlayer()->GetSession()->HasPermission(rbac::RBAC_PERM_ALLOW_TWO_SIDE_TRADE))
|
||||
{
|
||||
info.Status = TRADE_STATUS_WRONG_FACTION;
|
||||
SendTradeStatus(info);
|
||||
|
||||
Reference in New Issue
Block a user