TrinityCore
Loading...
Searching...
No Matches
cs_ticket.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/* ScriptData
19Name: ticket_commandscript
20%Complete: 100
21Comment: All ticket related commands
22Category: commandscripts
23EndScriptData */
24
25#include "ScriptMgr.h"
26#include "AccountMgr.h"
27#include "CharacterCache.h"
28#include "Chat.h"
29#include "Language.h"
30#include "ObjectAccessor.h"
31#include "ObjectMgr.h"
32#include "Opcodes.h"
33#include "Player.h"
34#include "Realm.h"
35#include "TicketMgr.h"
36#include "World.h"
37#include "WorldSession.h"
38
39#if TRINITY_COMPILER == TRINITY_COMPILER_GNU
40#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
41#endif
42
44{
45public:
46 ticket_commandscript() : CommandScript("ticket_commandscript") { }
47
48 std::vector<ChatCommand> GetCommands() const override
49 {
50 static std::vector<ChatCommand> ticketResponseCommandTable =
51 {
54 };
55 static std::vector<ChatCommand> ticketCommandTable =
56 {
68 { "response", rbac::RBAC_PERM_COMMAND_TICKET_RESPONSE, true, nullptr, "", ticketResponseCommandTable },
73 };
74 static std::vector<ChatCommand> commandTable =
75 {
76 { "ticket", rbac::RBAC_PERM_COMMAND_TICKET, false, nullptr, "", ticketCommandTable },
77 };
78 return commandTable;
79 }
80
81 static bool HandleGMTicketAssignToCommand(ChatHandler* handler, char const* args)
82 {
83 if (!*args)
84 return false;
85
86 char* ticketIdStr = strtok((char*)args, " ");
87 uint32 ticketId = atoi(ticketIdStr);
88
89 char* targetStr = strtok(nullptr, " ");
90 if (!targetStr)
91 return false;
92
93 std::string target(targetStr);
94 if (!normalizePlayerName(target))
95 return false;
96
97 GmTicket* ticket = sTicketMgr->GetTicket(ticketId);
98 if (!ticket || ticket->IsClosed())
99 {
101 return true;
102 }
103
104 ObjectGuid targetGuid = sCharacterCache->GetCharacterGuidByName(target);
105 uint32 accountId = sCharacterCache->GetCharacterAccountIdByGuid(targetGuid);
106 // Target must exist and have administrative rights
108 {
110 return true;
111 }
112
113 // If already assigned, leave
114 if (ticket->IsAssignedTo(targetGuid))
115 {
117 return true;
118 }
119
120 // If assigned to different player other than current, leave
122 Player* player = handler->GetSession() ? handler->GetSession()->GetPlayer() : nullptr;
123 if (player && ticket->IsAssignedNotTo(player->GetGUID()))
124 {
125 handler->PSendSysMessage(LANG_COMMAND_TICKETALREADYASSIGNED, ticket->GetId(), target.c_str());
126 return true;
127 }
128
129 // Assign ticket
132 ticket->SaveToDB(trans);
133 sTicketMgr->UpdateLastChange();
134
135 std::string msg = ticket->FormatMessageString(*handler, nullptr, target.c_str(), nullptr, nullptr, nullptr);
136 handler->SendGlobalGMSysMessage(msg.c_str());
137 return true;
138 }
139
140 static bool HandleGMTicketCloseByIdCommand(ChatHandler* handler, char const* args)
141 {
142 if (!*args)
143 return false;
144
145 uint32 ticketId = atoi(args);
146 GmTicket* ticket = sTicketMgr->GetTicket(ticketId);
147 if (!ticket || ticket->IsClosed() || ticket->IsCompleted())
148 {
150 return true;
151 }
152
153 // Ticket should be assigned to the player who tries to close it.
154 // Console can override though
155 Player* player = handler->GetSession() ? handler->GetSession()->GetPlayer() : nullptr;
156 if (player && ticket->IsAssignedNotTo(player->GetGUID()))
157 {
159 return true;
160 }
161
162 sTicketMgr->ResolveAndCloseTicket(ticket->GetId(), Object::GetGUID(player));
163 sTicketMgr->UpdateLastChange();
164
165 std::string msg = ticket->FormatMessageString(*handler, player ? player->GetName().c_str() : "Console", nullptr, nullptr, nullptr, nullptr);
166 handler->SendGlobalGMSysMessage(msg.c_str());
167
168 // Inform player, who submitted this ticket, that it is closed
169 if (Player* submitter = ticket->GetPlayer())
170 {
173 submitter->SendDirectMessage(&data);
174 }
175 return true;
176 }
177
178 static bool HandleGMTicketCommentCommand(ChatHandler* handler, char const* args)
179 {
180 if (!*args)
181 return false;
182
183 char* ticketIdStr = strtok((char*)args, " ");
184 uint32 ticketId = atoi(ticketIdStr);
185
186 char* comment = strtok(nullptr, "\n");
187 if (!comment)
188 return false;
189
190 GmTicket* ticket = sTicketMgr->GetTicket(ticketId);
191 if (!ticket || ticket->IsClosed())
192 {
194 return true;
195 }
196
197 // Cannot comment ticket assigned to someone else
199 Player* player = handler->GetSession() ? handler->GetSession()->GetPlayer() : nullptr;
200 if (player && ticket->IsAssignedNotTo(player->GetGUID()))
201 {
203 return true;
204 }
205
207 ticket->SetComment(comment);
208 ticket->SaveToDB(trans);
209 sTicketMgr->UpdateLastChange();
210
211 std::string msg = [&] {
212 std::string const assignedName = ticket->GetAssignedToName();
213 return ticket->FormatMessageString(*handler, nullptr,
214 assignedName.empty() ? nullptr : assignedName.c_str(), nullptr, nullptr, nullptr);
215 }();
216
217 msg += handler->PGetParseString(LANG_COMMAND_TICKETLISTADDCOMMENT, player ? player->GetName().c_str() : "Console", comment);
218 handler->SendGlobalGMSysMessage(msg.c_str());
219
220 return true;
221 }
222
223 static bool HandleGMTicketListClosedCommand(ChatHandler* handler, char const* /*args*/)
224 {
225 sTicketMgr->ShowClosedList(*handler);
226 return true;
227 }
228
229 static bool HandleGMTicketCompleteCommand(ChatHandler* handler, char const* args)
230 {
231 if (!*args)
232 return false;
233
234 char* ticketIdStr = strtok((char*)args, " ");
235 uint32 ticketId = atoi(ticketIdStr);
236
237 GmTicket* ticket = sTicketMgr->GetTicket(ticketId);
238 if (!ticket || ticket->IsClosed() || ticket->IsCompleted())
239 {
241 return true;
242 }
243
244 char* response = strtok(nullptr, "\n");
245 if (response)
246 {
247 // Cannot add response to ticket, assigned to someone else
249 Player* player = handler->GetSession() ? handler->GetSession()->GetPlayer() : nullptr;
250 if (player && ticket->IsAssignedNotTo(player->GetGUID()))
251 {
253 return true;
254 }
255
256 ticket->AppendResponse(response);
257 }
258
259 if (Player* player = ticket->GetPlayer())
260 ticket->SendResponse(player->GetSession());
261
262 Player* gm = handler->GetSession() ? handler->GetSession()->GetPlayer() : nullptr;
263
265 ticket->SetResolvedBy(Object::GetGUID(gm));
266 ticket->SetCompleted();
267 ticket->SaveToDB(trans);
268
269 std::string msg = ticket->FormatMessageString(*handler, nullptr, nullptr,
270 nullptr, nullptr, handler->GetSession() ? handler->GetSession()->GetPlayer()->GetName().c_str() : "Console");
271 handler->SendGlobalGMSysMessage(msg.c_str());
272 sTicketMgr->UpdateLastChange();
273 return true;
274 }
275
276 static bool HandleGMTicketDeleteByIdCommand(ChatHandler* handler, char const* args)
277 {
278 if (!*args)
279 return false;
280
281 uint32 ticketId = atoi(args);
282 GmTicket* ticket = sTicketMgr->GetTicket(ticketId);
283 if (!ticket)
284 {
286 return true;
287 }
288
289 if (!ticket->IsClosed())
290 {
292 return true;
293 }
294
295 std::string msg = ticket->FormatMessageString(*handler, nullptr, nullptr, nullptr, handler->GetSession() ? handler->GetSession()->GetPlayer()->GetName().c_str() : "Console", nullptr);
296 handler->SendGlobalGMSysMessage(msg.c_str());
297
298 if (Player* player = ticket->GetPlayer())
299 {
300 // Force abandon ticket
303 player->SendDirectMessage(&data);
304 }
305
306 sTicketMgr->RemoveTicket(ticket->GetId());
307 sTicketMgr->UpdateLastChange();
308
309 return true;
310 }
311
312 static bool HandleGMTicketEscalateCommand(ChatHandler* handler, char const* args)
313 {
314 if (!*args)
315 return false;
316
317 uint32 ticketId = atoi(args);
318 GmTicket* ticket = sTicketMgr->GetTicket(ticketId);
319 if (!ticket || ticket->IsClosed() || ticket->IsCompleted() || ticket->GetEscalatedStatus() != TICKET_UNASSIGNED)
320 {
322 return true;
323 }
324
326
327 if (Player* player = ticket->GetPlayer())
328 sTicketMgr->SendTicket(player->GetSession(), ticket);
329
330 sTicketMgr->UpdateLastChange();
331 return true;
332 }
333
334 static bool HandleGMTicketListEscalatedCommand(ChatHandler* handler, char const* /*args*/)
335 {
336 sTicketMgr->ShowEscalatedList(*handler);
337 return true;
338 }
339
340 static bool HandleGMTicketListCommand(ChatHandler* handler, char const* /*args*/)
341 {
342 sTicketMgr->ShowList(*handler, false);
343 return true;
344 }
345
346 static bool HandleGMTicketListOnlineCommand(ChatHandler* handler, char const* /*args*/)
347 {
348 sTicketMgr->ShowList(*handler, true);
349 return true;
350 }
351
352 static bool HandleGMTicketResetCommand(ChatHandler* handler, char const* /*args*/)
353 {
354 if (sTicketMgr->GetOpenTicketCount())
355 {
357 return true;
358 }
359 else
360 {
361 sTicketMgr->ResetTickets();
363 }
364
365 return true;
366 }
367
368 static bool HandleToggleGMTicketSystem(ChatHandler* handler, char const* /*args*/)
369 {
370 bool status = !sTicketMgr->GetStatus();
371 sTicketMgr->SetStatus(status);
373 return true;
374 }
375
376 static bool HandleGMTicketUnAssignCommand(ChatHandler* handler, char const* args)
377 {
378 if (!*args)
379 return false;
380
381 uint32 ticketId = atoi(args);
382 GmTicket* ticket = sTicketMgr->GetTicket(ticketId);
383 if (!ticket || ticket->IsClosed())
384 {
386 return true;
387 }
388 // Ticket must be assigned
389 if (!ticket->IsAssigned())
390 {
392 return true;
393 }
394
395 // Get security level of player, whom this ticket is assigned to
396 uint32 security = SEC_PLAYER;
397 Player* assignedPlayer = ticket->GetAssignedPlayer();
398 if (assignedPlayer)
399 security = assignedPlayer->GetSession()->GetSecurity();
400 else
401 {
402 ObjectGuid guid = ticket->GetAssignedToGUID();
403 uint32 accountId = sCharacterCache->GetCharacterAccountIdByGuid(guid);
404 security = AccountMgr::GetSecurity(accountId, realm.Id.Realm);
405 }
406
407 // Check security
409 uint32 mySecurity = handler->GetSession() ? handler->GetSession()->GetSecurity() : SEC_CONSOLE;
410 if (security > mySecurity)
411 {
413 return true;
414 }
415
416 std::string assignedTo = ticket->GetAssignedToName(); // copy assignedto name because we need it after the ticket has been unnassigned
418 ticket->SetUnassigned();
419 ticket->SaveToDB(trans);
420 sTicketMgr->UpdateLastChange();
421
422 std::string msg = ticket->FormatMessageString(*handler, nullptr, assignedTo.c_str(),
423 handler->GetSession() ? handler->GetSession()->GetPlayer()->GetName().c_str() : "Console", nullptr, nullptr);
424 handler->SendGlobalGMSysMessage(msg.c_str());
425
426 return true;
427 }
428
429 static bool HandleGMTicketGetByIdCommand(ChatHandler* handler, char const* args)
430 {
431 if (!*args)
432 return false;
433
434 uint32 ticketId = atoi(args);
435 GmTicket* ticket = sTicketMgr->GetTicket(ticketId);
436 if (!ticket || ticket->IsClosed() || ticket->IsCompleted())
437 {
439 return true;
440 }
441
443 ticket->SetViewed();
444 ticket->SaveToDB(trans);
445
446 handler->SendSysMessage(ticket->FormatMessageString(*handler, true).c_str());
447 return true;
448 }
449
450 static bool HandleGMTicketGetByNameCommand(ChatHandler* handler, char const* args)
451 {
452 if (!*args)
453 return false;
454
455 std::string name(args);
456 if (!normalizePlayerName(name))
457 return false;
458
459 // Detect target's GUID
460 ObjectGuid guid;
461 if (Player* player = ObjectAccessor::FindPlayerByName(name))
462 guid = player->GetGUID();
463 else
464 guid = sCharacterCache->GetCharacterGuidByName(name);
465
466 // Target must exist
467 if (guid.IsEmpty())
468 {
470 return true;
471 }
472
473 // Ticket must exist
474 GmTicket* ticket = sTicketMgr->GetTicketByPlayer(guid);
475 if (!ticket)
476 {
478 return true;
479 }
480
482 ticket->SetViewed();
483 ticket->SaveToDB(trans);
484
485 handler->SendSysMessage(ticket->FormatMessageString(*handler, true).c_str());
486 return true;
487 }
488
489 static bool _HandleGMTicketResponseAppendCommand(char const* args, bool newLine, ChatHandler* handler)
490 {
491 if (!*args)
492 return false;
493
494 char* ticketIdStr = strtok((char*)args, " ");
495 uint32 ticketId = atoi(ticketIdStr);
496
497 char* response = strtok(nullptr, "\n");
498 if (!response)
499 return false;
500
501 GmTicket* ticket = sTicketMgr->GetTicket(ticketId);
502 if (!ticket || ticket->IsClosed())
503 {
505 return true;
506 }
507
508 // Cannot add response to ticket, assigned to someone else
510 Player* player = handler->GetSession() ? handler->GetSession()->GetPlayer() : nullptr;
511 if (player && ticket->IsAssignedNotTo(player->GetGUID()))
512 {
514 return true;
515 }
516
518 ticket->AppendResponse(response);
519 if (newLine)
520 ticket->AppendResponse("\n");
521 ticket->SaveToDB(trans);
522
523 return true;
524 }
525
526 static bool HandleGMTicketResponseAppendCommand(ChatHandler* handler, char const* args)
527 {
528 return _HandleGMTicketResponseAppendCommand(args, false, handler);
529 }
530
531 static bool HandleGMTicketResponseAppendLnCommand(ChatHandler* handler, char const* args)
532 {
533 return _HandleGMTicketResponseAppendCommand(args, true, handler);
534 }
535};
536
#define sCharacterCache
@ SEC_PLAYER
Definition Common.h:40
@ SEC_CONSOLE
Definition Common.h:44
SQLTransaction< CharacterDatabaseConnection > CharacterDatabaseTransaction
uint32_t uint32
Definition Define.h:133
@ LANG_COMMAND_TICKETRESET
Definition Language.h:1053
@ LANG_COMMAND_TICKETALREADYASSIGNED
Definition Language.h:1032
@ LANG_ALLOW_TICKETS
Definition Language.h:910
@ LANG_COMMAND_TICKETUNASSIGNSECURITY
Definition Language.h:1040
@ LANG_COMMAND_TICKETCANNOTCLOSE
Definition Language.h:1041
@ LANG_COMMAND_TICKETCLOSEFIRST
Definition Language.h:1031
@ LANG_COMMAND_TICKETNOTASSIGNED
Definition Language.h:1039
@ LANG_DISALLOW_TICKETS
Definition Language.h:911
@ LANG_COMMAND_TICKETASSIGNERROR_B
Definition Language.h:1038
@ LANG_COMMAND_TICKETPENDING
Definition Language.h:1052
@ LANG_COMMAND_TICKETLISTADDCOMMENT
Definition Language.h:1049
@ LANG_NO_PLAYERS_FOUND
Definition Language.h:385
@ LANG_COMMAND_TICKETASSIGNERROR_A
Definition Language.h:1037
@ LANG_COMMAND_TICKETNOTEXIST
Definition Language.h:1030
bool normalizePlayerName(std::string &name)
#define sTicketMgr
Definition TicketMgr.h:248
@ TICKET_IN_ESCALATION_QUEUE
Definition TicketMgr.h:62
@ TICKET_UNASSIGNED
Definition TicketMgr.h:60
@ GMTICKET_RESPONSE_TICKET_DELETED
Definition TicketMgr.h:50
static uint32 GetSecurity(uint32 accountId, int32 realmId)
static bool HasPermission(uint32 accountId, uint32 permission, uint32 realmId)
static bool IsAdminAccount(uint32 gmlevel)
void SendGlobalGMSysMessage(const char *str)
Definition Chat.cpp:135
static std::string PGetParseString(std::string_view fmt, Args &&... args)
Definition Chat.h:81
WorldSession * GetSession()
Definition Chat.h:46
void PSendSysMessage(char const *fmt, Args &&... args)
Definition Chat.h:69
virtual void SendSysMessage(std::string_view str, bool escapeCharacters=false)
Definition Chat.cpp:101
ObjectGuid GetAssignedToGUID() const
Definition TicketMgr.h:109
bool IsAssignedTo(ObjectGuid guid) const
Definition TicketMgr.h:101
bool IsAssigned() const
Definition TicketMgr.h:100
void SetViewed()
Definition TicketMgr.h:128
void SetUnassigned()
bool IsClosed() const
Definition TicketMgr.h:97
Player * GetPlayer() const
Definition TicketMgr.cpp:54
void SetResolvedBy(ObjectGuid value)
Definition TicketMgr.h:124
void SaveToDB(CharacterDatabaseTransaction trans) const
Definition TicketMgr.cpp:91
void SetAssignedTo(ObjectGuid guid, bool isAdmin)
Definition TicketMgr.h:115
void AppendResponse(std::string const &response)
Definition TicketMgr.h:133
bool IsCompleted() const
Definition TicketMgr.h:98
void SetCompleted()
Definition TicketMgr.h:125
void SetComment(std::string const &comment)
Definition TicketMgr.h:127
uint32 GetId() const
Definition TicketMgr.h:104
void SendResponse(WorldSession *session) const
std::string FormatMessageString(ChatHandler &handler, bool detailed=false) const
bool IsAssignedNotTo(ObjectGuid guid) const
Definition TicketMgr.h:102
std::string GetAssignedToName() const
Player * GetAssignedPlayer() const
Definition TicketMgr.cpp:59
GMTicketEscalationStatus GetEscalatedStatus() const
Definition TicketMgr.h:112
void SetEscalatedStatus(GMTicketEscalationStatus escalatedStatus)
Definition TicketMgr.h:114
bool IsEmpty() const
Definition ObjectGuid.h:172
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:78
ObjectGuid GetGUID() const
Definition Object.h:79
WorldSession * GetSession() const
Definition Player.h:1719
std::string const & GetName() const
Definition Object.h:382
AccountTypes GetSecurity() const
Player * GetPlayer() const
static bool HandleGMTicketResponseAppendLnCommand(ChatHandler *handler, char const *args)
static bool HandleGMTicketListOnlineCommand(ChatHandler *handler, char const *)
static bool HandleGMTicketResetCommand(ChatHandler *handler, char const *)
static bool HandleGMTicketGetByNameCommand(ChatHandler *handler, char const *args)
static bool HandleGMTicketCompleteCommand(ChatHandler *handler, char const *args)
static bool HandleGMTicketListCommand(ChatHandler *handler, char const *)
std::vector< ChatCommand > GetCommands() const override
Definition cs_ticket.cpp:48
static bool HandleGMTicketDeleteByIdCommand(ChatHandler *handler, char const *args)
static bool HandleGMTicketResponseAppendCommand(ChatHandler *handler, char const *args)
static bool HandleGMTicketEscalateCommand(ChatHandler *handler, char const *args)
static bool HandleGMTicketAssignToCommand(ChatHandler *handler, char const *args)
Definition cs_ticket.cpp:81
static bool HandleGMTicketCloseByIdCommand(ChatHandler *handler, char const *args)
static bool HandleGMTicketListClosedCommand(ChatHandler *handler, char const *)
static bool HandleToggleGMTicketSystem(ChatHandler *handler, char const *)
static bool HandleGMTicketGetByIdCommand(ChatHandler *handler, char const *args)
static bool HandleGMTicketUnAssignCommand(ChatHandler *handler, char const *args)
static bool HandleGMTicketCommentCommand(ChatHandler *handler, char const *args)
static bool _HandleGMTicketResponseAppendCommand(char const *args, bool newLine, ChatHandler *handler)
static bool HandleGMTicketListEscalatedCommand(ChatHandler *handler, char const *)
void AddSC_ticket_commandscript()
@ SMSG_GMTICKET_DELETETICKET
Definition Opcodes.h:565
Realm realm
Definition World.cpp:3605
TC_GAME_API Player * FindPlayerByName(std::string_view name)
@ RBAC_PERM_COMMANDS_BE_ASSIGNED_TICKET
Definition RBAC.h:85
@ RBAC_PERM_COMMAND_TICKET_ESCALATEDLIST
Definition RBAC.h:620
@ RBAC_PERM_COMMAND_TICKET_ONLINELIST
Definition RBAC.h:622
@ RBAC_PERM_COMMAND_TICKET_RESPONSE_APPENDLN
Definition RBAC.h:626
@ RBAC_PERM_COMMAND_TICKET_RESPONSE_APPEND
Definition RBAC.h:625
@ RBAC_PERM_COMMAND_TICKET_RESPONSE
Definition RBAC.h:624
@ RBAC_PERM_COMMAND_TICKET_COMMENT
Definition RBAC.h:616
@ RBAC_PERM_COMMAND_TICKET_LIST
Definition RBAC.h:621
@ RBAC_PERM_COMMAND_TICKET_TOGGLESYSTEM
Definition RBAC.h:627
@ RBAC_PERM_COMMAND_TICKET_CLOSEDLIST
Definition RBAC.h:615
@ RBAC_PERM_COMMAND_TICKET_UNASSIGN
Definition RBAC.h:628
@ RBAC_PERM_COMMAND_TICKET_DELETE
Definition RBAC.h:618
@ RBAC_PERM_COMMAND_TICKET_ESCALATE
Definition RBAC.h:619
@ RBAC_PERM_COMMAND_TICKET
Definition RBAC.h:612
@ RBAC_PERM_COMMAND_TICKET_COMPLETE
Definition RBAC.h:617
@ RBAC_PERM_COMMAND_TICKET_RESET
Definition RBAC.h:623
@ RBAC_PERM_COMMAND_TICKET_VIEWNAME
Definition RBAC.h:630
@ RBAC_PERM_COMMAND_TICKET_VIEWID
Definition RBAC.h:629
@ RBAC_PERM_COMMAND_TICKET_ASSIGN
Definition RBAC.h:613
@ RBAC_PERM_COMMAND_TICKET_CLOSE
Definition RBAC.h:614
uint32 Realm
Definition Realm.h:44
RealmHandle Id
Definition Realm.h:67