Implement .reset mail command + Increase max bags slots to 36 (#102)

Default behaviour :
       -------------------
        - delete checked mails (even if its is GM stationery and if it contains items in it, but not deleted COD)

       Options :
       ---------
        - cod : delete only cod mail (even if it is unchecked)
            TODO -> to improve => return cod to sender instead of delete
        - gm : delete only GM stationery emails (even if it is unchecked)
        - all : delete all mails (even if it is unchecked)
        - from XXXX : delete all mails from specific sender in the slected player mailbox, name or guid
          TODO  -> to improve, if unchecked return letter to sender to inform it was not read and purged by GM for tech. reason.

        TODO : future => handle reset mail for Offline char ?
This commit is contained in:
Elmsroth 2020-06-17 08:50:54 +02:00 committed by GitHub
parent ef98577af2
commit 0f53874d1f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 1017 additions and 796 deletions

View File

@ -25,6 +25,7 @@
#include "Chat.h"
#include "Language.h"
#include "World.h"
#include "Mail.h"
/**********************************************************************
CommandTable : commandTable
@ -531,3 +532,200 @@ bool ChatHandler::HandleResetItemsCommand(char* args)
return true;
}
int GetResetMailBitMask(char* args)
{
int optionBitMask = RESET_MAIL_COMMAND_FLAG_OPTION_NONE;
if (args == NULL)
{
return optionBitMask;
}
if (strncmp(args, RESET_MAIL_COMMAND_ARG_OPTION_COD, strlen(args)) == 0)
{
optionBitMask |= RESET_MAIL_COMMAND_FLAG_OPTION_COD;
return optionBitMask;
}
if (strncmp(args, RESET_MAIL_COMMAND_ARG_OPTION_GM, strlen(args)) == 0)
{
optionBitMask |= RESET_MAIL_COMMAND_FLAG_OPTION_GM;
return optionBitMask;
}
//Specific case for "from XXX"
if (strncmp(args, RESET_MAIL_COMMAND_ARG_OPTION_FROM, strlen(RESET_MAIL_COMMAND_ARG_OPTION_FROM)) == 0)
{
optionBitMask |= RESET_MAIL_COMMAND_FLAG_OPTION_FROM;
return optionBitMask;
}
if (strncmp(args, RESET_MAIL_COMMAND_ARG_OPTION_ALL, strlen(args)) == 0)
{
optionBitMask |= RESET_MAIL_COMMAND_FLAG_OPTION_ALL;
return optionBitMask;
}
return optionBitMask;
}
/*
HandleResetMailCommand
Default behaviour :
-------------------
- delete checked mails (even if its is GM stationery and if it contains items in it, but not deleted COD)
Options :
---------
- cod : delete only cod mail (even if it is unchecked)
TODO -> to improve => return cod to sender instead of delete
- gm : delete only GM stationery emails (even if it is unchecked)
- all : delete all mails (even if it is unchecked)
- from XXXX : delete all mails from specific sender in the slected player mailbox, name or guid
TODO -> to improve, if unchecked return letter to sender to inform it was not read and purged by GM for tech. reason.
TODO : future => handle reset mail for Offline char ?
*/
bool ChatHandler::HandleResetMailCommand(char* args)
{
char* firstArg = ExtractArg(&args);
int optionBitMask = GetResetMailBitMask(firstArg);
// Get Select player Or if no selection, use Current player
Player* player = getSelectedPlayer();
if (!player)
{
player = m_session->GetPlayer();
}
uint8 totalDeletedMailCount = 0;
uint8 deletedGMMailCount = 0;
uint8 deletedCODMailCount = 0;
uint8 deletedFromMailCount = 0;
// Special chack if amil delete "from"
// in order to retrieve player
uint32 senderGuid = -1;
std::string from_sender_name;
if (optionBitMask & RESET_MAIL_COMMAND_FLAG_OPTION_FROM)
{
// Check if arg after "from" is player guid or playerName and if so check guid
// Extract Uint32 from remaining arg text
uint32 playerGuid = 0;
Player* sender;
ObjectGuid from_sender_guid;
if (!ExtractPlayerTarget(&args, &sender, &from_sender_guid, &from_sender_name))
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
return false;
}
senderGuid = from_sender_guid;
}
for (PlayerMails::iterator itr = player->GetMailBegin(); itr != player->GetMailEnd(); ++itr)
{
// Flag the mail as "deleted"
Mail* m = (*itr);
bool deleteMail = false;
// DO not use the swith because it begins at 1
if (optionBitMask == RESET_MAIL_COMMAND_FLAG_OPTION_NONE)
{
if (m->checked && !m->COD && m->state != MAIL_STATE_DELETED)
{
deleteMail = true;
}
}
BITMASK_AND_SWITCH(optionBitMask)
{
case RESET_MAIL_COMMAND_FLAG_OPTION_COD:
{
if (m->COD && m->state != MAIL_STATE_DELETED)
{
deleteMail = true;
++deletedCODMailCount;
}
break;
}
case RESET_MAIL_COMMAND_FLAG_OPTION_GM:
{
if (m->stationery == MAIL_STATIONERY_GM && m->state != MAIL_STATE_DELETED)
{
deleteMail = true;
++deletedGMMailCount;
}
break;
}
case RESET_MAIL_COMMAND_FLAG_OPTION_FROM:
{
if (senderGuid != -1 && (m->sender == senderGuid) && m->state != MAIL_STATE_DELETED)
{
deleteMail = true;
++deletedFromMailCount;
}
break;
}
}
if (deleteMail)
{
m->checked = m->checked | MAIL_CHECK_MASK_READ ;
m->state = MAIL_STATE_DELETED;
player->SendMailResult(m->messageID, MAIL_DELETED, MAIL_OK);
++totalDeletedMailCount;
}
}
if (totalDeletedMailCount > 0)
{
player->m_mailsUpdated = true;
}
// Notification
Player * gm = m_session->GetPlayer();
BITMASK_AND_SWITCH(optionBitMask)
{
case RESET_MAIL_COMMAND_FLAG_OPTION_NONE:
{
// Nothing specific to display
break;
}
case RESET_MAIL_COMMAND_FLAG_OPTION_COD:
{
PSendSysMessage(LANG_COMMAND_RESET_MAIL_COD, deletedCODMailCount, player->GetName());
break;
}
case RESET_MAIL_COMMAND_FLAG_OPTION_GM:
{
PSendSysMessage(LANG_COMMAND_RESET_MAIL_GM, deletedGMMailCount, player->GetName());
break;
}
case RESET_MAIL_COMMAND_FLAG_OPTION_FROM:
{
PSendSysMessage(LANG_COMMAND_RESET_MAIL_FROM, deletedFromMailCount, from_sender_name.c_str(), player->GetName());
break;
}
}
if (gm != player)
{
ChatHandler(player).PSendSysMessage(LANG_COMMAND_RESET_MAIL_PLAYER_NOTIF, m_session->GetPlayer()->GetName(), totalDeletedMailCount);
}
PSendSysMessage(LANG_COMMAND_RESET_MAIL_RECAP, totalDeletedMailCount, player->GetName());
return true;
}

View File

@ -18065,7 +18065,7 @@ void Player::SaveToDB()
if (m_mailsUpdated) // save mails only when needed
{
_SaveMail();
SaveMail();
}
_SaveBGData();
@ -18394,14 +18394,14 @@ void Player::_SaveHonorCP()
tempList.clear();
}
void Player::_SaveMail()
void Player::SaveMail()
{
static SqlStatementID updateMail ;
static SqlStatementID deleteMailItems ;
static SqlStatementID deleteItem ;
static SqlStatementID deleteItemText;
static SqlStatementID deleteMain ;
static SqlStatementID deleteMail ;
static SqlStatementID deleteItems ;
for (PlayerMails::iterator itr = m_mail.begin(); itr != m_mail.end(); ++itr)
@ -18450,7 +18450,7 @@ void Player::_SaveMail()
stmt.PExecute(m->itemTextId);
}
SqlStatement stmt = CharacterDatabase.CreateStatement(deleteMain, "DELETE FROM `mail` WHERE `id` = ?");
SqlStatement stmt = CharacterDatabase.CreateStatement(deleteMail, "DELETE FROM `mail` WHERE `id` = ?");
stmt.PExecute(m->messageID);
stmt = CharacterDatabase.CreateStatement(deleteItems, "DELETE FROM `mail_items` WHERE `mail_id` = ?");

View File

@ -2393,7 +2393,7 @@ class Player : public Unit
void SetBotDeathTimer() { m_deathTimer = 0; }
//PlayerTalentMap& GetTalentMap(uint8 spec) { return m_talents[spec]; }
#endif
void SaveMail();
protected:
uint32 m_contestedPvPTimer;
@ -2453,7 +2453,7 @@ class Player : public Unit
void _SaveAuras();
void _SaveInventory();
void _SaveHonorCP();
void _SaveMail();
void _SaveQuestStatus();
void _SaveSkills();
void _SaveSpells();

View File

@ -1047,6 +1047,12 @@ enum MangosStrings
LANG_COMMAND_RESET_ITEMS_ALL = 1527,
LANG_COMMAND_RESET_ITEMS_ALLBAGS = 1528,
LANG_COMMAND_RESET_MAIL_COD = 1529,
LANG_COMMAND_RESET_MAIL_GM = 1530,
LANG_COMMAND_RESET_MAIL_FROM = 1531,
LANG_COMMAND_RESET_MAIL_PLAYER_NOTIF = 1532,
LANG_COMMAND_RESET_MAIL_RECAP = 1533,
// Room for more Level 2 1522-1599 not used
// Outdoor PvP

View File

@ -574,6 +574,7 @@ ChatCommand* ChatHandler::getCommandTable()
{ "stats", SEC_ADMINISTRATOR, true, &ChatHandler::HandleResetStatsCommand, "", NULL },
{ "talents", SEC_ADMINISTRATOR, true, &ChatHandler::HandleResetTalentsCommand, "", NULL },
{ "items", SEC_ADMINISTRATOR, false, &ChatHandler::HandleResetItemsCommand, "", NULL },
{ "mail", SEC_ADMINISTRATOR, false, &ChatHandler::HandleResetMailCommand, "", NULL },
{ "all", SEC_ADMINISTRATOR, true, &ChatHandler::HandleResetAllCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};

File diff suppressed because it is too large Load Diff

View File

@ -513,7 +513,7 @@ void WorldSession::HandleMailTakeItem(WorldPacket& recv_data)
CharacterDatabase.BeginTransaction();
pl->SaveInventoryAndGoldToDB();
pl->_SaveMail();
pl->SaveMail();
CharacterDatabase.CommitTransaction();
pl->SendMailResult(mailId, MAIL_ITEM_TAKEN, MAIL_OK, 0, itemId, count);
@ -557,7 +557,7 @@ void WorldSession::HandleMailTakeMoney(WorldPacket& recv_data)
// save money and mail to prevent cheating
CharacterDatabase.BeginTransaction();
pl->SaveGoldToDB();
pl->_SaveMail();
pl->SaveMail();
CharacterDatabase.CommitTransaction();
}