Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
TicketHandler.cpp
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
6#include "Common.h"
7#include "Chat.h"
8#include "Language.h"
9#include "ObjectMgr.h"
10#include "Opcodes.h"
11#include "Player.h"
12#include "TicketMgr.h"
13#include "Util.h"
14#include "World.h"
15#include "WorldPacket.h"
16#include "WorldSession.h"
17#include "zlib.h"
18#include <unordered_set>
19
21{
22 // Don't accept tickets if the ticket queue is disabled. (Ticket UI is greyed out but not fully dependable)
23 if (sTicketMgr->GetGmTicketSystemStatus() == GMTICKET_QUEUE_STATUS_DISABLED)
24 return;
25
26 if (GetPlayer()->getLevel() < sWorld->getIntConfig(WorldIntConfigs::CONFIG_TICKET_LEVEL_REQ))
27 {
29 return;
30 }
31
33 GmTicket* ticket = sTicketMgr->GetGmTicketByPlayerGuid(GetPlayer()->GetGUID());
34
35 if (ticket && ticket->IsCompleted())
36 sTicketMgr->CloseTicket<GmTicket>(ticket->GetTicketId(), GetPlayer()->GetGUID());;
37
38 // Player must not have ticket
39 if (!ticket || ticket->IsClosed())
40 {
41 uint32 count, mapId, decompressedSize;
42 G3D::Vector3 Position;
43 uint8 textCount, messageLen;
44 std::list<uint32> times;
45 std::string chatLog, message;
46 bool haveTicket, needResponse;
47
48 ticket = new GmTicket(GetPlayer());
49
50 recvData >> mapId;
51 recvData >> Position.z;
52 recvData >> Position.y;
53 recvData.read_skip<uint8>(); // flags!?
54 recvData >> Position.x;
55 recvData >> count;
56
57 if (count > 0)
58 {
59 recvData >> textCount;
60 for (uint32 i = 0; i < textCount; i++)
61 {
62 uint32 time;
63 recvData >> time;
64 times.push_back(time);
65 }
66
67 recvData >> decompressedSize;
68
69 if (count && decompressedSize && decompressedSize < 0xFFFF)
70 {
71 uint32 pos = recvData.rpos();
72 ByteBuffer tailPacket;
73 tailPacket.resize(decompressedSize);
74
75 uLongf realSize = decompressedSize;
76 if (uncompress(tailPacket.contents(), &realSize, recvData.contents() + pos, recvData.size() - pos) == Z_OK)
77 tailPacket >> chatLog;
78
79 else
80 {
81 SF_LOG_ERROR("network", "CMSG_GM_TICKET_CREATE possibly corrupt. Uncompression failed.");
82 recvData.rfinish();
83 delete ticket;
84 return;
85 }
86 }
87 }
88
89 recvData.FlushBits();
90 needResponse = recvData.ReadBit();
91 haveTicket = recvData.ReadBit();
92 messageLen = recvData.ReadBits(11);
93 message = recvData.ReadString(messageLen);
94
95 if (!ChatHandler(this).isValidChatMessage(message.c_str()))
96 return;
97
98 ticket->SetChatLog(times, chatLog);
99 ticket->SetMessage(message);
100 ticket->SetPosition(mapId, Position);
101 ticket->SetGmAction(needResponse, haveTicket);
102
103 sTicketMgr->AddTicket(ticket);
104 sTicketMgr->UpdateLastChange();
105
106 sWorld->SendGMText(LANG_COMMAND_TICKETNEW, GetPlayer()->GetName().c_str(), ticket->GetTicketId());
107
109 }
110
111 sTicketMgr->SendGmTicketUpdate(SMSG_GM_TICKET_UPDATE, response, GetPlayer());
112}
113
115{
116 std::string message;
117 uint8 messageLen = 0;
118
119 if (!ChatHandler(this).isValidChatMessage(message.c_str()))
120 return;
121
122 messageLen = recvData.ReadBits(11);
123 message = recvData.ReadString(messageLen);
124
126 if (GmTicket* ticket = sTicketMgr->GetGmTicketByPlayerGuid(GetPlayer()->GetGUID()))
127 {
128 SQLTransaction trans = SQLTransaction(NULL);
129 ticket->SetMessage(message);
130 ticket->SaveToDB(trans);
131
132 sWorld->SendGMText(LANG_COMMAND_TICKETUPDATED, GetPlayer()->GetName().c_str(), ticket->GetTicketId());
133
135 }
136
137 sTicketMgr->SendGmTicketUpdate(SMSG_GM_TICKET_UPDATE, response, GetPlayer());
138}
139
141{
142 if (GmTicket* ticket = sTicketMgr->GetGmTicketByPlayerGuid(GetPlayer()->GetGUID()))
143 {
145
146 sWorld->SendGMText(LANG_COMMAND_TICKETPLAYERABANDON, GetPlayer()->GetName().c_str(), ticket->GetTicketId());
147
148 sTicketMgr->CloseTicket<GmTicket>(ticket->GetTicketId(), GetPlayer()->GetGUID());
149 sTicketMgr->SendGmTicket(this, NULL);
150 }
151}
152
154{
156
157 if (GmTicket* ticket = sTicketMgr->GetGmTicketByPlayerGuid(GetPlayer()->GetGUID()))
158 {
159 if (ticket->IsCompleted())
160 sTicketMgr->SendGmResponsee(this, ticket);
161 else
162 sTicketMgr->SendGmTicket(this, ticket);
163 }
164 else
165 sTicketMgr->SendGmTicket(this, NULL);
166}
167
169{
170 // Note: This only disables the ticket UI at client side and is not fully reliable
171 // are we sure this is a uint32? Should ask Zor
174 SendPacket(&data);
175}
176
178{
179 time_t UpdateTime = 0, OldestTicketTime = time(NULL);
181 data.WriteBits(0, 20);
182 data.FlushBits();
183 data.AppendPackedTime(UpdateTime);
184 data.AppendPackedTime(OldestTicketTime);
185 SendPacket(&data);
186}
187
189{
190 uint32 nextSurveyID = sTicketMgr->GetNextSurveyID();
191 // just put the survey into the database
192 uint32 mainSurvey; // GMSurveyCurrentSurvey.dbc, column 1 (all 9) ref to GMSurveySurveys.dbc
193 recvData >> mainSurvey;
194
195 std::unordered_set<uint32> surveyIds;
196 SQLTransaction trans = CharacterDatabase.BeginTransaction();
197
198 // 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,
199 for (uint8 i = 0; i < 15; i++)
200 {
201 uint32 subSurveyId; // ref to i'th GMSurveySurveys.dbc field (all fields in that dbc point to fields in GMSurveyQuestions.dbc)
202 recvData >> subSurveyId;
203 if (!subSurveyId)
204 break;
205
206 uint8 rank; // probably some sort of ref to GMSurveyAnswers.dbc
207 recvData >> rank;
208 std::string comment; // comment ("Usage: GMSurveyAnswerSubmit(question, rank, comment)")
209 recvData >> comment;
210
211 // make sure the same sub survey is not added to DB twice
212 if (!surveyIds.insert(subSurveyId).second)
213 continue;
214
215 if (!ChatHandler(this).isValidChatMessage(comment.c_str()))
216 return;
217
218 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GM_SUBSURVEY);
219 stmt->setUInt32(0, nextSurveyID);
220 stmt->setUInt32(1, subSurveyId);
221 stmt->setUInt32(2, rank);
222 stmt->setString(3, comment);
223 trans->Append(stmt);
224 }
225
226 std::string comment; // just a guess
227 recvData >> comment;
228
229 if (!ChatHandler(this).isValidChatMessage(comment.c_str()))
230 return;
231
232 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GM_SURVEY);
233 stmt->setUInt32(0, GUID_LOPART(GetPlayer()->GetGUID()));
234 stmt->setUInt32(1, nextSurveyID);
235 stmt->setUInt32(2, mainSurvey);
236 stmt->setString(3, comment);
237
238 trans->Append(stmt);
239
240 CharacterDatabase.CommitTransaction(trans);
241}
242
244{
245 // just put the lag report into the database...
246 // can't think of anything else to do with it
247 uint32 lagType, mapId;
248 recvData >> lagType;
249 recvData >> mapId;
250 float x, y, z;
251 recvData >> x;
252 recvData >> y;
253 recvData >> z;
254
255 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_LAG_REPORT);
256 stmt->setUInt32(0, GUID_LOPART(GetPlayer()->GetGUID()));
257 stmt->setUInt8(1, lagType);
258 stmt->setUInt16(2, mapId);
259 stmt->setFloat(3, x);
260 stmt->setFloat(4, y);
261 stmt->setFloat(5, z);
262 stmt->setUInt32(6, GetLatency());
263 stmt->setUInt32(7, time(NULL));
264 CharacterDatabase.Execute(stmt);
265}
266
268{
269 if (GmTicket* ticket = sTicketMgr->GetGmTicketByPlayerGuid(GetPlayer()->GetGUID()))
270 {
271 uint8 getSurvey = 0;
273 getSurvey = 1;
274
276 data.WriteBit(getSurvey);
277 data.FlushBits();
278 SendPacket(&data);
279
282 SendPacket(&data2);
283
284 sTicketMgr->CloseTicket<GmTicket>(ticket->GetTicketId(), GetPlayer()->GetGUID());
285 sTicketMgr->SendGmTicket(this, NULL);
286 }
287}
288
290{
291 if (!sTicketMgr->GetFeedBackSystemStatus())
292 return;
293
294 if (GetPlayer()->getLevel() < sWorld->getIntConfig(WorldIntConfigs::CONFIG_TICKET_LEVEL_REQ))
295 {
297 return;
298 }
299
300 if (BugTicket* ticket = new BugTicket(GetPlayer(), recvPacket))
301 sTicketMgr->AddTicket(ticket);
302}
303
305{
306 if (!sTicketMgr->GetFeedBackSystemStatus())
307 return;
308
309 if (GetPlayer()->getLevel() < sWorld->getIntConfig(WorldIntConfigs::CONFIG_TICKET_LEVEL_REQ))
310 {
312 return;
313 }
314
315 if (SuggestTicket* ticket = new SuggestTicket(GetPlayer(), recvPacket))
316 sTicketMgr->AddTicket(ticket);
317}
@ CHAR_INS_GM_SURVEY
@ CHAR_INS_LAG_REPORT
@ CHAR_INS_GM_SUBSURVEY
std::uint8_t uint8
Definition Define.h:79
std::uint32_t uint32
Definition Define.h:77
@ LANG_TICKET_REQ
Definition Language.h:1114
@ LANG_COMMAND_TICKETPLAYERABANDON
Definition Language.h:1037
@ LANG_COMMAND_TICKETNEW
Definition Language.h:1035
@ LANG_COMMAND_TICKETUPDATED
Definition Language.h:1036
#define SF_LOG_ERROR(filterType__,...)
Definition Log.h:143
uint32 GUID_LOPART(uint64 x)
@ GMTICKET_QUEUE_STATUS_ENABLED
Definition TicketInfo.h:17
@ GMTICKET_QUEUE_STATUS_DISABLED
Definition TicketInfo.h:16
GMTicketResponse
Definition TicketInfo.h:27
@ GMTICKET_RESPONSE_CREATE_SUCCESS
Definition TicketInfo.h:29
@ GMTICKET_RESPONSE_TICKET_DELETED
Definition TicketInfo.h:33
@ GMTICKET_RESPONSE_CREATE_ERROR
Definition TicketInfo.h:30
@ GMTICKET_RESPONSE_UPDATE_SUCCESS
Definition TicketInfo.h:31
@ GMTICKET_RESPONSE_UPDATE_ERROR
Definition TicketInfo.h:32
#define sTicketMgr
Definition TicketMgr.h:117
Skyfire::AutoPtr< Transaction, Skyfire::Mutex > SQLTransaction
Definition Transaction.h:42
double rand_chance(void)
Definition Util.cpp:55
bool WriteBit(uint32 bit)
Definition ByteBuffer.h:164
void read_skip()
Definition ByteBuffer.h:502
size_t rpos() const
Definition ByteBuffer.h:470
uint32 ReadBits(size_t bits)
Definition ByteBuffer.h:198
void resize(size_t newsize)
Definition ByteBuffer.h:612
void rfinish()
Definition ByteBuffer.h:478
std::string ReadString(size_t length)
Definition ByteBuffer.h:565
void WriteBits(T value, size_t bits)
Definition ByteBuffer.h:192
void AppendPackedTime(time_t time)
Definition ByteBuffer.h:700
size_t size() const
Definition ByteBuffer.h:609
void FlushBits()
Definition ByteBuffer.h:154
uint8 * contents()
Definition ByteBuffer.h:605
bool ReadBit()
Definition ByteBuffer.h:180
void SetGmAction(bool needResponse, bool haveTicket)
void SetMessage(std::string const &message)
bool IsCompleted() const
Definition TicketInfo.h:138
void SetChatLog(std::list< uint32 > time, std::string const &log)
void setFloat(const uint8 index, const float value)
void setString(const uint8 index, const std::string &value)
void setUInt16(const uint8 index, const uint16 value)
void setUInt32(const uint8 index, const uint32 value)
void setUInt8(const uint8 index, const uint8 value)
uint32 GetTicketId() const
Definition TicketInfo.h:85
void SetPosition(uint32 MapID, G3D::Vector3 pos)
bool IsClosed() const
Definition TicketInfo.h:75
void HandleGMTicketCreateOpcode(WorldPacket &recvPacket)
const char * GetSkyFireString(int32 entry) const
void HandleGMTicketGetTicketOpcode(WorldPacket &recvPacket)
void HandleGMSurveySubmit(WorldPacket &recvPacket)
void SendNotification(const char *format,...) ATTR_PRINTF(2
void HandleGMTicketUpdateOpcode(WorldPacket &recvPacket)
void HandleGMTicketCaseStatusOpcode(WorldPacket &recvPacket)
Player * GetPlayer() const
void HandleGMResponseResolve(WorldPacket &recvPacket)
void HandleSubmitBugOpcode(WorldPacket &recvPacket)
void HandleReportLag(WorldPacket &recvPacket)
void SendPacket(WorldPacket const *packet, bool forced=false)
Send a packet to the client.
uint32 GetLatency() const
void SendQueryTimeResponse()
void HandleGMTicketDeleteOpcode(WorldPacket &recvPacket)
void HandleGMTicketSystemStatusOpcode(WorldPacket &recvPacket)
void HandleSubmitSuggestOpcode(WorldPacket &recvPacket)
CharacterDatabaseWorkerPool CharacterDatabase
Accessor to the character database.
Definition Main.cpp:41
@ SMSG_GM_TICKET_CASE_STATUS
Definition Opcodes.h:662
@ SMSG_GM_TICKET_SYSTEM_STATUS
Definition Opcodes.h:666
@ SMSG_GM_TICKET_RESOLVE_RESPONSE
Definition Opcodes.h:664
@ SMSG_GM_TICKET_UPDATE
Definition Opcodes.h:667
#define sWorld
Definition World.h:910
@ CONFIG_TICKET_LEVEL_REQ
Definition World.h:281
@ CONFIG_CHANCE_OF_GM_SURVEY
Definition World.h:189