TrinityCore
Loading...
Searching...
No Matches
TicketHandler.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 "WorldSession.h"
19#include "Common.h"
20#include "DatabaseEnv.h"
21#include "GameTime.h"
22#include "Language.h"
23#include "Log.h"
24#include "ObjectMgr.h"
25#include "Opcodes.h"
26#include "Player.h"
27#include "Random.h"
28#include "TicketMgr.h"
29#include "Util.h"
30#include "World.h"
31#include "WorldPacket.h"
32#include <zlib.h>
33
35{
36 // Don't accept tickets if the ticket queue is disabled. (Ticket UI is greyed out but not fully dependable)
38 return;
39
40 if (GetPlayer()->GetLevel() < sWorld->getIntConfig(CONFIG_TICKET_LEVEL_REQ))
41 {
43 return;
44 }
45
47 GmTicket* ticket = sTicketMgr->GetTicketByPlayer(GetPlayer()->GetGUID());
48
49 if (ticket && ticket->IsCompleted())
50 sTicketMgr->CloseTicket(ticket->GetId(), GetPlayer()->GetGUID());
51
52 // Player must not have ticket
53 if (!ticket || ticket->IsClosed())
54 {
55 uint32 mapId;
56 float x, y, z;
57 std::string message;
58 uint32 needResponse;
59 bool needMoreHelp;
60 uint32 count;
61 std::list<uint32> times;
62 uint32 decompressedSize;
63 std::string chatLog;
64
65 recvData >> mapId;
66 recvData >> x >> y >> z;
67 recvData >> message;
68
70 return;
71
72 recvData >> needResponse;
73 recvData >> needMoreHelp;
74
75 recvData >> count;
76
77 for (uint32 i = 0; i < count; i++)
78 {
79 uint32 time;
80 recvData >> time;
81 times.push_back(time);
82 }
83
84 recvData >> decompressedSize;
85
86 if (count && decompressedSize && decompressedSize < 0xFFFF)
87 {
88 uint32 pos = recvData.rpos();
89 ByteBuffer dest;
90 dest.resize(decompressedSize);
91
92 uLongf realSize = decompressedSize;
93 if (uncompress(dest.contents(), &realSize, recvData.contents() + pos, recvData.size() - pos) == Z_OK)
94 {
95 dest >> chatLog;
96 }
97 else
98 {
99 TC_LOG_ERROR("network", "CMSG_GMTICKET_CREATE possibly corrupt. Uncompression failed.");
100 recvData.rfinish();
101 return;
102 }
103
104 recvData.rfinish(); // Will still have compressed data in buffer.
105 }
106
107 if (!chatLog.empty() && !ValidateHyperlinksAndMaybeKick(chatLog))
108 return;
109
110 ticket = new GmTicket(GetPlayer());
111 ticket->SetPosition(mapId, x, y, z);
112 ticket->SetMessage(message);
113 ticket->SetGmAction(needResponse, needMoreHelp);
114 if (!chatLog.empty())
115 ticket->SetChatLog(times, chatLog);
116
117 sTicketMgr->AddTicket(ticket);
118 sTicketMgr->UpdateLastChange();
119
120 sWorld->SendGMText(LANG_COMMAND_TICKETNEW, GetPlayer()->GetName().c_str(), ticket->GetId());
121
123 }
124
126 data << uint32(response);
127 SendPacket(&data);
128}
129
131{
132 std::string message;
133 recvData >> message;
134
135 if (!ValidateHyperlinksAndMaybeKick(message))
136 return;
137
139 if (GmTicket* ticket = sTicketMgr->GetTicketByPlayer(GetPlayer()->GetGUID()))
140 {
142 ticket->SetMessage(message);
143 ticket->SaveToDB(trans);
144
145 sWorld->SendGMText(LANG_COMMAND_TICKETUPDATED, GetPlayer()->GetName().c_str(), ticket->GetId());
146
148 }
149
151 data << uint32(response);
152 SendPacket(&data);
153}
154
156{
157 if (GmTicket* ticket = sTicketMgr->GetTicketByPlayer(GetPlayer()->GetGUID()))
158 {
161 SendPacket(&data);
162
163 sWorld->SendGMText(LANG_COMMAND_TICKETPLAYERABANDON, GetPlayer()->GetName().c_str(), ticket->GetId());
164
165 sTicketMgr->CloseTicket(ticket->GetId(), GetPlayer()->GetGUID());
166 sTicketMgr->SendTicket(this, nullptr);
167 }
168}
169
171{
173
174 if (GmTicket* ticket = sTicketMgr->GetTicketByPlayer(GetPlayer()->GetGUID()))
175 {
176 if (ticket->IsCompleted())
177 ticket->SendResponse(this);
178 else
179 sTicketMgr->SendTicket(this, ticket);
180 }
181 else
182 sTicketMgr->SendTicket(this, nullptr);
183}
184
186{
187 // Note: This only disables the ticket UI at client side and is not fully reliable
188 // are we sure this is a uint32? Should ask Zor
191 SendPacket(&data);
192}
193
195{
196 uint32 nextSurveyID = sTicketMgr->GetNextSurveyID();
197 // just put the survey into the database
198 uint32 mainSurvey; // GMSurveyCurrentSurvey.dbc, column 1 (all 9) ref to GMSurveySurveys.dbc
199 recvData >> mainSurvey;
200
201 std::unordered_set<uint32> surveyIds;
202 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
203 // sub_survey1, r1, comment1, sub_survey2, r2, comment2, sub_survey3, r3, comment3, sub_survey4, r4, comment4, sub_survey5, r5, comment5, sub_survey6, r6, comment6, sub_survey7, r7, comment7, sub_survey8, r8, comment8, sub_survey9, r9, comment9, sub_survey10, r10, comment10,
204 for (uint8 i = 0; i < 10; i++)
205 {
206 uint32 subSurveyId; // ref to i'th GMSurveySurveys.dbc field (all fields in that dbc point to fields in GMSurveyQuestions.dbc)
207 recvData >> subSurveyId;
208 if (!subSurveyId)
209 break;
210
211 uint8 rank; // probably some sort of ref to GMSurveyAnswers.dbc
212 recvData >> rank;
213 std::string comment; // comment ("Usage: GMSurveyAnswerSubmit(question, rank, comment)")
214 recvData >> comment;
215
216 // make sure the same sub survey is not added to DB twice
217 if (!surveyIds.insert(subSurveyId).second)
218 continue;
219
220 if (!ValidateHyperlinksAndMaybeKick(comment))
221 return;
222
224 stmt->setUInt32(0, nextSurveyID);
225 stmt->setUInt32(1, subSurveyId);
226 stmt->setUInt32(2, rank);
227 stmt->setString(3, comment);
228 trans->Append(stmt);
229 }
230
231 std::string comment; // just a guess
232 recvData >> comment;
233
234 if (!ValidateHyperlinksAndMaybeKick(comment))
235 return;
236
238 stmt->setUInt32(0, GetPlayer()->GetGUID().GetCounter());
239 stmt->setUInt32(1, nextSurveyID);
240 stmt->setUInt32(2, mainSurvey);
241 stmt->setString(3, comment);
242
243 trans->Append(stmt);
244
245 CharacterDatabase.CommitTransaction(trans);
246}
247
249{
250 // just put the lag report into the database...
251 // can't think of anything else to do with it
252 uint32 lagType, mapId;
253 recvData >> lagType;
254 recvData >> mapId;
255 float x, y, z;
256 recvData >> x;
257 recvData >> y;
258 recvData >> z;
259
261 stmt->setUInt32(0, GetPlayer()->GetGUID().GetCounter());
262 stmt->setUInt8 (1, lagType);
263 stmt->setUInt16(2, mapId);
264 stmt->setFloat (3, x);
265 stmt->setFloat (4, y);
266 stmt->setFloat (5, z);
267 stmt->setUInt32(6, GetLatency());
269 CharacterDatabase.Execute(stmt);
270}
271
273{
274 // empty packet
275 if (GmTicket* ticket = sTicketMgr->GetTicketByPlayer(GetPlayer()->GetGUID()))
276 {
277 uint8 getSurvey = 0;
278 if (roll_chance_f(sWorld->getFloatConfig(CONFIG_CHANCE_OF_GM_SURVEY)))
279 getSurvey = 1;
280
282 data << uint8(getSurvey);
283 SendPacket(&data);
284
287 SendPacket(&data2);
288
289 sTicketMgr->CloseTicket(ticket->GetId(), GetPlayer()->GetGUID());
290 sTicketMgr->SendTicket(this, nullptr);
291 }
292}
@ CHAR_INS_GM_SURVEY
@ CHAR_INS_LAG_REPORT
@ CHAR_INS_GM_SUBSURVEY
SQLTransaction< CharacterDatabaseConnection > CharacterDatabaseTransaction
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
uint8_t uint8
Definition Define.h:135
uint32_t uint32
Definition Define.h:133
@ LANG_TICKET_REQ
Definition Language.h:1165
@ LANG_COMMAND_TICKETPLAYERABANDON
Definition Language.h:1027
@ LANG_COMMAND_TICKETNEW
Definition Language.h:1025
@ LANG_COMMAND_TICKETUPDATED
Definition Language.h:1026
#define TC_LOG_ERROR(filterType__,...)
Definition Log.h:165
bool roll_chance_f(float chance)
Definition Random.h:53
#define sTicketMgr
Definition TicketMgr.h:248
@ GMTICKET_QUEUE_STATUS_ENABLED
Definition TicketMgr.h:34
@ GMTICKET_QUEUE_STATUS_DISABLED
Definition TicketMgr.h:33
GMTicketResponse
Definition TicketMgr.h:44
@ GMTICKET_RESPONSE_CREATE_ERROR
Definition TicketMgr.h:47
@ GMTICKET_RESPONSE_CREATE_SUCCESS
Definition TicketMgr.h:46
@ GMTICKET_RESPONSE_TICKET_DELETED
Definition TicketMgr.h:50
@ GMTICKET_RESPONSE_UPDATE_SUCCESS
Definition TicketMgr.h:48
@ GMTICKET_RESPONSE_UPDATE_ERROR
Definition TicketMgr.h:49
size_t rpos() const
Definition ByteBuffer.h:308
void resize(size_t newsize)
Definition ByteBuffer.h:412
void rfinish()
Definition ByteBuffer.h:316
size_t size() const
Definition ByteBuffer.h:409
uint8 * contents()
Definition ByteBuffer.h:395
bool IsClosed() const
Definition TicketMgr.h:97
void SetPosition(uint32 mapId, float x, float y, float z)
void SetMessage(std::string const &message)
void SetGmAction(uint32 needResponse, bool needMoreHelp)
bool IsCompleted() const
Definition TicketMgr.h:98
uint32 GetId() const
Definition TicketMgr.h:104
void SetChatLog(std::list< uint32 > time, std::string const &log)
void setUInt16(uint8 index, uint16 value)
void setUInt32(uint8 index, uint32 value)
void setFloat(uint8 index, float value)
void setUInt8(uint8 index, uint8 value)
void setString(uint8 index, std::string const &value)
void HandleGMTicketCreateOpcode(WorldPacket &recvPacket)
char const * GetTrinityString(uint32 entry) const
void HandleGMTicketGetTicketOpcode(WorldPacket &recvPacket)
void HandleGMSurveySubmit(WorldPacket &recvPacket)
void SendPacket(WorldPacket const *packet)
Send a packet to the client.
void SendNotification(const char *format,...) ATTR_PRINTF(2
void HandleGMTicketUpdateOpcode(WorldPacket &recvPacket)
Player * GetPlayer() const
void HandleGMResponseResolve(WorldPacket &recvPacket)
void HandleReportLag(WorldPacket &recvPacket)
uint32 GetLatency() const
void SendQueryTimeResponse()
void HandleGMTicketDeleteOpcode(WorldPacket &recvPacket)
void HandleGMTicketSystemStatusOpcode(WorldPacket &recvPacket)
bool ValidateHyperlinksAndMaybeKick(std::string const &str)
@ SMSG_GMRESPONSE_STATUS_UPDATE
Definition Opcodes.h:1294
@ SMSG_GMTICKET_SYSTEMSTATUS
Definition Opcodes.h:568
@ SMSG_GMTICKET_DELETETICKET
Definition Opcodes.h:565
@ SMSG_GMTICKET_UPDATETEXT
Definition Opcodes.h:549
@ SMSG_GMTICKET_CREATE
Definition Opcodes.h:547
#define sWorld
Definition World.h:900
@ CONFIG_TICKET_LEVEL_REQ
Definition World.h:302
@ CONFIG_CHANCE_OF_GM_SURVEY
Definition World.h:195
time_t GetGameTime()
Definition GameTime.cpp:42