Core/RBAC: Create new permission 'Two side mail interaction'. In order to send/receive mails from other faction, config option should be enabled and both sender and receiver should have the permission

This commit is contained in:
Spp
2013-02-25 15:48:18 +01:00
parent ea2e6052b2
commit d14cb26e6e
3 changed files with 87 additions and 64 deletions
@@ -0,0 +1,19 @@
-- Add new permission
DELETE FROM `rbac_permissions` WHERE `id` = 27;
INSERT INTO `rbac_permissions` (`id`, `name`) VALUES (27, 'Send mail to other faction');
-- Add new role
DELETE FROM `rbac_roles` WHERE `id` = 19;
INSERT INTO `rbac_roles` (`id`, `name`) VALUES (19, 'Send mail to other faction');
-- Add the permission to the role
DELETE FROM `rbac_role_permissions` WHERE `roleId` = 19;
INSERT INTO `rbac_role_permissions` (`roleId`, `permissionId`) VALUES (19, 27);
-- Add it to all GM+ groups
DELETE FROM `rbac_group_roles` WHERE `roleId` = 19;
INSERT INTO `rbac_group_roles` (`groupId`, `roleId`) VALUES
(1, 19),
(2, 19),
(3, 19),
(4, 19);
+1
View File
@@ -61,6 +61,7 @@ enum RBACPermissions
RBAC_PERM_LOG_GM_TRADE = 11,
RBAC_PERM_SKIP_CHECK_INSTANCE_REQUIRED_BOSSES = 13,
RBAC_PERM_SKIP_CHECK_OVERSPEED_PING = 23,
RBAC_PERM_TWO_SIDE_INTERACTION_MAIL = 27,
RBAC_PERM_COMMANDS_SAVE_WITHOUT_DELAY = 30,
RBAC_PERM_COMMANDS_USE_UNSTUCK_WITH_ARGS = 31,
RBAC_PERM_COMMANDS_BE_ASSIGNED_TICKET = 32,
+67 -64
View File
@@ -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;
@@ -264,28 +265,30 @@ void WorldSession::HandleSendMail(WorldPacket& recvData)
Item* item = items[i];
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 (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);
}
}
@@ -296,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);
@@ -459,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 (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
{
@@ -479,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));