TrinityCore
cs_send.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "ScriptMgr.h"
19#include "Chat.h"
20#include "ChatCommand.h"
21#include "DatabaseEnv.h"
22#include "Item.h"
23#include "Language.h"
24#include "Mail.h"
25#include "ObjectMgr.h"
26#include "Player.h"
27#include "RBAC.h"
28#include "WorldSession.h"
29
30#if TRINITY_COMPILER == TRINITY_COMPILER_GNU
31#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
32#endif
33
34using namespace Trinity::ChatCommands;
35
37{
38public:
39 send_commandscript() : CommandScript("send_commandscript") { }
40
42 {
43 static ChatCommandTable sendCommandTable =
44 {
49 };
50
51 static ChatCommandTable commandTable =
52 {
53 { "send", sendCommandTable },
54 };
55 return commandTable;
56 }
57
58 // Send mail by command
59 static bool HandleSendMailCommand(ChatHandler* handler, char const* args)
60 {
61 // format: name "subject text" "mail text"
62 Player* target;
63 ObjectGuid targetGuid;
64 std::string targetName;
65 if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName))
66 return false;
67
68 char* tail1 = strtok(nullptr, "");
69 if (!tail1)
70 return false;
71
72 char const* msgSubject = handler->extractQuotedArg(tail1);
73 if (!msgSubject)
74 return false;
75
76 char* tail2 = strtok(nullptr, "");
77 if (!tail2)
78 return false;
79
80 char const* msgText = handler->extractQuotedArg(tail2);
81 if (!msgText)
82 return false;
83
84 // msgSubject, msgText isn't NUL after prev. check
85 std::string subject = msgSubject;
86 std::string text = msgText;
87
88 // from console, use non-existing sender
90
92 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
93 MailDraft(subject, text)
94 .SendMailTo(trans, MailReceiver(target, targetGuid.GetCounter()), sender);
95
96 CharacterDatabase.CommitTransaction(trans);
97
98 std::string nameLink = handler->playerLink(targetName);
99 handler->PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str());
100 return true;
101 }
102
103 // Send items by mail
104 static bool HandleSendItemsCommand(ChatHandler* handler, char const* args)
105 {
106 // format: name "subject text" "mail text" item1[:count1] item2[:count2] ... item12[:count12]
107 Player* receiver;
108 ObjectGuid receiverGuid;
109 std::string receiverName;
110 if (!handler->extractPlayerTarget((char*)args, &receiver, &receiverGuid, &receiverName))
111 return false;
112
113 char* tail1 = strtok(nullptr, "");
114 if (!tail1)
115 return false;
116
117 char const* msgSubject = handler->extractQuotedArg(tail1);
118 if (!msgSubject)
119 return false;
120
121 char* tail2 = strtok(nullptr, "");
122 if (!tail2)
123 return false;
124
125 char const* msgText = handler->extractQuotedArg(tail2);
126 if (!msgText)
127 return false;
128
129 // msgSubject, msgText isn't NUL after prev. check
130 std::string subject = msgSubject;
131 std::string text = msgText;
132
133 // extract items
134 typedef std::pair<uint32, uint32> ItemPair;
135 typedef std::list< ItemPair > ItemPairs;
136 ItemPairs items;
137
138 // get all tail string
139 char* tail = strtok(nullptr, "");
140
141 // get from tail next item str
142 while (char* itemStr = strtok(tail, " "))
143 {
144 // and get new tail
145 tail = strtok(nullptr, "");
146
147 // parse item str
148 char const* itemIdStr = strtok(itemStr, ":");
149 char const* itemCountStr = strtok(nullptr, " ");
150
151 Optional<uint32> itemId = Trinity::StringTo<uint32>(itemIdStr);
152 if (!itemId)
153 return false;
154
155 ItemTemplate const* item_proto = sObjectMgr->GetItemTemplate(*itemId);
156 if (!item_proto)
157 {
159 handler->SetSentErrorMessage(true);
160 return false;
161 }
162
163 uint32 itemCount = itemCountStr ? atoi(itemCountStr) : 1;
164 if (itemCount < 1 || (item_proto->GetMaxCount() > 0 && itemCount > uint32(item_proto->GetMaxCount())))
165 {
166 handler->PSendSysMessage(LANG_COMMAND_INVALID_ITEM_COUNT, itemCount, *itemId);
167 handler->SetSentErrorMessage(true);
168 return false;
169 }
170
171 while (itemCount > item_proto->GetMaxStackSize())
172 {
173 items.push_back(ItemPair(*itemId, item_proto->GetMaxStackSize()));
174 itemCount -= item_proto->GetMaxStackSize();
175 }
176
177 items.push_back(ItemPair(*itemId, itemCount));
178
179 if (items.size() > MAX_MAIL_ITEMS)
180 {
182 handler->SetSentErrorMessage(true);
183 return false;
184 }
185 }
186
187 // from console show nonexisting sender
189
190 // fill mail
191 MailDraft draft(subject, text);
192
193 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
194
195 for (ItemPairs::const_iterator itr = items.begin(); itr != items.end(); ++itr)
196 {
197 if (Item* item = Item::CreateItem(itr->first, itr->second, ItemContext::NONE, handler->GetSession() ? handler->GetSession()->GetPlayer() : nullptr))
198 {
199 item->SaveToDB(trans); // Save to prevent being lost at next mail load. If send fails, the item will be deleted.
200 draft.AddItem(item);
201 }
202 }
203
204 draft.SendMailTo(trans, MailReceiver(receiver, receiverGuid.GetCounter()), sender);
205 CharacterDatabase.CommitTransaction(trans);
206
207 std::string nameLink = handler->playerLink(receiverName);
208 handler->PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str());
209 return true;
210 }
212 static bool HandleSendMoneyCommand(ChatHandler* handler, PlayerIdentifier const& receiver, QuotedString const& subject, QuotedString const& text, int64 money)
213 {
215
216 // from console show nonexisting sender
218
219 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
220
221 MailDraft(subject, text)
222 .AddMoney(money)
223 .SendMailTo(trans, MailReceiver(receiver.GetConnectedPlayer(), receiver.GetGUID().GetCounter()), sender);
224
225 CharacterDatabase.CommitTransaction(trans);
226
227 std::string nameLink = handler->playerLink(receiver.GetName());
228 handler->PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str());
229 return true;
230 }
232 static bool HandleSendMessageCommand(ChatHandler* handler, char const* args)
233 {
235 Player* player;
236 if (!handler->extractPlayerTarget((char*)args, &player))
237 return false;
238
239 char* msgStr = strtok(nullptr, "");
240 if (!msgStr)
241 return false;
242
244 if (player->GetSession()->isLogingOut())
245 {
247 handler->SetSentErrorMessage(true);
248 return false;
249 }
250
252 player->GetSession()->SendNotification("%s", msgStr);
253 player->GetSession()->SendNotification("|cffff0000[Message from administrator]:|r");
254
255 // Confirmation message
256 std::string nameLink = handler->GetNameLink(player);
257 handler->PSendSysMessage(LANG_SENDMESSAGE, nameLink.c_str(), msgStr);
258
259 return true;
260 }
261};
262
264{
265 new send_commandscript();
266}
SQLTransaction< CharacterDatabaseConnection > CharacterDatabaseTransaction
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
Definition: DatabaseEnv.cpp:21
int64_t int64
Definition: Define.h:137
#define UI64LIT(N)
Definition: Define.h:127
uint32_t uint32
Definition: Define.h:142
@ LANG_COMMAND_INVALID_ITEM_COUNT
Definition: Language.h:84
@ LANG_COMMAND_MAIL_ITEMS_LIMIT
Definition: Language.h:85
@ LANG_MAIL_SENT
Definition: Language.h:211
@ LANG_SENDMESSAGE
Definition: Language.h:875
@ LANG_PLAYER_NOT_FOUND
Definition: Language.h:567
@ LANG_COMMAND_ITEMIDINVALID
Definition: Language.h:495
#define MAX_MAIL_ITEMS
Definition: Mail.h:35
@ MAIL_STATIONERY_GM
Definition: Mail.h:65
@ MAIL_NORMAL
Definition: Mail.h:39
#define sObjectMgr
Definition: ObjectMgr.h:1946
std::optional< T > Optional
Optional helper class to wrap optional values within.
Definition: Optional.h:25
Role Based Access Control related classes definition.
std::string playerLink(std::string const &name) const
Definition: Chat.cpp:602
char * extractQuotedArg(char *args)
Definition: Chat.cpp:546
WorldSession * GetSession()
Definition: Chat.h:42
virtual std::string GetNameLink() const
Definition: Chat.cpp:58
void PSendSysMessage(const char *fmt, Args &&... args)
Definition: Chat.h:57
void SetSentErrorMessage(bool val)
Definition: Chat.h:114
virtual void SendSysMessage(std::string_view str, bool escapeCharacters=false)
Definition: Chat.cpp:113
bool extractPlayerTarget(char *args, Player **player, ObjectGuid *player_guid=nullptr, std::string *player_name=nullptr)
Definition: Chat.cpp:489
Definition: Item.h:170
static Item * CreateItem(uint32 itemEntry, uint32 count, ItemContext context, Player const *player=nullptr, bool addDefaultBonuses=true)
Definition: Item.cpp:1625
void SendMailTo(CharacterDatabaseTransaction trans, MailReceiver const &receiver, MailSender const &sender, MailCheckMask checked=MAIL_CHECK_MASK_NONE, uint32 deliver_delay=0)
Definition: Mail.cpp:192
MailDraft & AddItem(Item *item)
Definition: Mail.cpp:99
MailDraft & AddMoney(uint64 money)
Definition: Mail.h:145
LowType GetCounter() const
Definition: ObjectGuid.h:293
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:159
WorldSession * GetSession() const
Definition: Player.h:2101
void SendNotification(char const *format,...) ATTR_PRINTF(2
bool isLogingOut() const
Is the user engaged in a log out process?
Player * GetPlayer() const
ChatCommandTable GetCommands() const override
Definition: cs_send.cpp:41
static bool HandleSendItemsCommand(ChatHandler *handler, char const *args)
Definition: cs_send.cpp:104
static bool HandleSendMailCommand(ChatHandler *handler, char const *args)
Definition: cs_send.cpp:59
static bool HandleSendMoneyCommand(ChatHandler *handler, PlayerIdentifier const &receiver, QuotedString const &subject, QuotedString const &text, int64 money)
Send money by mail.
Definition: cs_send.cpp:212
static bool HandleSendMessageCommand(ChatHandler *handler, char const *args)
Send a message to a player in game.
Definition: cs_send.cpp:232
void AddSC_send_commandscript()
Definition: cs_send.cpp:263
std::vector< ChatCommandBuilder > ChatCommandTable
Definition: ChatCommand.h:49
@ RBAC_PERM_COMMAND_SEND_MESSAGE
Definition: RBAC.h:358
@ RBAC_PERM_COMMAND_SEND_MAIL
Definition: RBAC.h:357
@ RBAC_PERM_COMMAND_SEND_MONEY
Definition: RBAC.h:359
@ RBAC_PERM_COMMAND_SEND_ITEMS
Definition: RBAC.h:356
uint32 GetMaxStackSize() const
Definition: ItemTemplate.h:847
uint32 GetMaxCount() const
Definition: ItemTemplate.h:796
std::string const & GetName() const