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:
@@ -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);
|
||||
@@ -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,
|
||||
|
||||
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user