363 | | void WorldSession::SendGMTicketGetTicket(uint32 status, char const* text) |
364 | | { |
365 | | int len = text ? strlen(text) : 0; |
366 | | WorldPacket data( SMSG_GMTICKET_GETTICKET, (4+len+1+4+2+4+4) ); |
367 | | data << uint32(status); // standard 0x0A, 0x06 if text present |
368 | | if(status == 6) |
369 | | { |
370 | | data << text; // ticket text |
371 | | data << uint8(0x7); // ticket category |
372 | | data << float(0); // time from ticket creation? |
373 | | data << float(0); // const |
374 | | data << float(0); // const |
375 | | data << uint8(0); // const |
376 | | data << uint8(0); // const |
377 | | } |
378 | | SendPacket( &data ); |
379 | | } |
380 | | |
381 | | void WorldSession::HandleGMTicketGetTicketOpcode( WorldPacket & /*recv_data*/ ) |
382 | | { |
383 | | WorldPacket data( SMSG_QUERY_TIME_RESPONSE, 4+4 ); |
384 | | data << (uint32)time(NULL); |
385 | | data << (uint32)0; |
386 | | SendPacket( &data ); |
387 | | |
388 | | uint64 guid; |
389 | | Field *fields; |
390 | | guid = GetPlayer()->GetGUID(); |
391 | | |
392 | | QueryResult *result = CharacterDatabase.PQuery("SELECT COUNT(ticket_id) FROM character_ticket WHERE guid = '%u'", GUID_LOPART(guid)); |
393 | | |
394 | | if (result) |
395 | | { |
396 | | int cnt; |
397 | | fields = result->Fetch(); |
398 | | cnt = fields[0].GetUInt32(); |
399 | | delete result; |
400 | | |
401 | | if ( cnt > 0 ) |
402 | | { |
403 | | QueryResult *result2 = CharacterDatabase.PQuery("SELECT ticket_text FROM character_ticket WHERE guid = '%u'", GUID_LOPART(guid)); |
404 | | if(result2) |
405 | | { |
406 | | Field *fields2 = result2->Fetch(); |
407 | | SendGMTicketGetTicket(0x06,fields2[0].GetString()); |
408 | | delete result2; |
409 | | } |
410 | | } |
411 | | else |
412 | | SendGMTicketGetTicket(0x0A,0); |
413 | | } |
414 | | } |
415 | | |
416 | | void WorldSession::HandleGMTicketUpdateTextOpcode( WorldPacket & recv_data ) |
417 | | { |
418 | | CHECK_PACKET_SIZE(recv_data,1); |
419 | | |
420 | | std::string ticketText; |
421 | | recv_data >> ticketText; |
422 | | |
423 | | CharacterDatabase.escape_string(ticketText); |
424 | | CharacterDatabase.PExecute("UPDATE character_ticket SET ticket_text = '%s' WHERE guid = '%u'", ticketText.c_str(), _player->GetGUIDLow()); |
425 | | } |
426 | | |
427 | | void WorldSession::HandleGMTicketDeleteOpcode( WorldPacket & /*recv_data*/ ) |
428 | | { |
429 | | uint32 guid = GetPlayer()->GetGUIDLow(); |
430 | | |
431 | | CharacterDatabase.PExecute("DELETE FROM character_ticket WHERE guid = '%u' LIMIT 1",guid); |
432 | | |
433 | | WorldPacket data( SMSG_GMTICKET_DELETETICKET, 4 ); |
434 | | data << uint32(9); |
435 | | SendPacket( &data ); |
436 | | |
437 | | SendGMTicketGetTicket(0x0A, 0); |
438 | | } |
439 | | |
440 | | void WorldSession::HandleGMTicketCreateOpcode( WorldPacket & recv_data ) |
441 | | { |
442 | | CHECK_PACKET_SIZE(recv_data, 4*4+1+2*4); |
443 | | |
444 | | uint32 map; |
445 | | float x, y, z; |
446 | | std::string ticketText = ""; |
447 | | uint32 unk1, unk2; |
448 | | |
449 | | recv_data >> map >> x >> y >> z; // last check 2.4.3 |
450 | | recv_data >> ticketText; |
451 | | |
452 | | // recheck |
453 | | CHECK_PACKET_SIZE(recv_data,4*4+(ticketText.size()+1)+2*4); |
454 | | |
455 | | recv_data >> unk1 >> unk2; |
456 | | // note: the packet might contain more data, but the exact structure of that is unknown |
457 | | |
458 | | sLog.outDebug("TicketCreate: map %u, x %f, y %f, z %f, text %s, unk1 %u, unk2 %u", map, x, y, z, ticketText.c_str(), unk1, unk2); |
459 | | |
460 | | CharacterDatabase.escape_string(ticketText); |
461 | | |
462 | | QueryResult *result = CharacterDatabase.PQuery("SELECT COUNT(*) FROM character_ticket WHERE guid = '%u'", _player->GetGUIDLow()); |
463 | | |
464 | | if (result) |
465 | | { |
466 | | int cnt; |
467 | | Field *fields = result->Fetch(); |
468 | | cnt = fields[0].GetUInt32(); |
469 | | delete result; |
470 | | |
471 | | if ( cnt > 0 ) |
472 | | { |
473 | | WorldPacket data( SMSG_GMTICKET_CREATE, 4 ); |
474 | | data << uint32(1); |
475 | | SendPacket( &data ); |
476 | | } |
477 | | else |
478 | | { |
479 | | CharacterDatabase.PExecute("INSERT INTO character_ticket (guid,ticket_text) VALUES ('%u', '%s')", _player->GetGUIDLow(), ticketText.c_str()); |
480 | | |
481 | | WorldPacket data( SMSG_QUERY_TIME_RESPONSE, 4+4 ); |
482 | | data << (uint32)time(NULL); |
483 | | data << (uint32)0; |
484 | | SendPacket( &data ); |
485 | | |
486 | | data.Initialize( SMSG_GMTICKET_CREATE, 4 ); |
487 | | data << uint32(2); |
488 | | SendPacket( &data ); |
489 | | DEBUG_LOG("update the ticket\n"); |
490 | | |
491 | | //TODO: Guard player map |
492 | | HashMapHolder<Player>::MapType &m = ObjectAccessor::Instance().GetPlayers(); |
493 | | for(HashMapHolder<Player>::MapType::iterator itr = m.begin(); itr != m.end(); ++itr) |
494 | | { |
495 | | if(itr->second->GetSession()->GetSecurity() >= SEC_GAMEMASTER && itr->second->isAcceptTickets()) |
496 | | ChatHandler(itr->second).PSendSysMessage(LANG_COMMAND_TICKETNEW,GetPlayer()->GetName()); |
497 | | } |
498 | | } |
499 | | } |
500 | | } |
501 | | |
502 | | void WorldSession::HandleGMTicketSystemStatusOpcode( WorldPacket & /*recv_data*/ ) |
503 | | { |
504 | | WorldPacket data( SMSG_GMTICKET_SYSTEMSTATUS,4 ); |
505 | | data << uint32(1); // we can also disable ticket system by sending 0 value |
506 | | |
507 | | SendPacket( &data ); |
508 | | } |
509 | | |
510 | | void WorldSession::HandleGMSurveySubmit( WorldPacket & recv_data) |
511 | | { |
512 | | // GM survey is shown after SMSG_GM_TICKET_STATUS_UPDATE with status = 3 |
513 | | CHECK_PACKET_SIZE(recv_data,4+4); |
514 | | uint32 x; |
515 | | recv_data >> x; // answer range? (6 = 0-5?) |
516 | | sLog.outDebug("SURVEY: X = %u", x); |
517 | | |
518 | | uint8 result[10]; |
519 | | memset(result, 0, sizeof(result)); |
520 | | for( int i = 0; i < 10; ++i) |
521 | | { |
522 | | CHECK_PACKET_SIZE(recv_data,recv_data.rpos()+4); |
523 | | uint32 questionID; |
524 | | recv_data >> questionID; // GMSurveyQuestions.dbc |
525 | | if (!questionID) |
526 | | break; |
527 | | |
528 | | CHECK_PACKET_SIZE(recv_data,recv_data.rpos()+1+1); |
529 | | uint8 value; |
530 | | std::string unk_text; |
531 | | recv_data >> value; // answer |
532 | | recv_data >> unk_text; // always empty? |
533 | | |
534 | | result[i] = value; |
535 | | sLog.outDebug("SURVEY: ID %u, value %u, text %s", questionID, value, unk_text.c_str()); |
536 | | } |
537 | | |
538 | | CHECK_PACKET_SIZE(recv_data,recv_data.rpos()+1); |
539 | | std::string comment; |
540 | | recv_data >> comment; // addional comment |
541 | | sLog.outDebug("SURVEY: comment %s", comment.c_str()); |
542 | | |
543 | | // TODO: chart this data in some way |
544 | | } |
545 | | |