TrinityCore
Loading...
Searching...
No Matches
cs_debug.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: debug_commandscript
20%Complete: 100
21Comment: All debug related commands
22Category: commandscripts
23EndScriptData */
24
25#include "ScriptMgr.h"
26#include "Bag.h"
27#include "BattlefieldMgr.h"
28#include "BattlegroundMgr.h"
29#include "CellImpl.h"
30#include "Channel.h"
31#include "ChannelPackets.h"
32#include "Chat.h"
33#include "ChatCommand.h"
34#include "ChatPackets.h"
35#include "Conversation.h"
36#include "CreatureAI.h"
37#include "DB2Stores.h"
38#include "GameTime.h"
39#include "GridNotifiersImpl.h"
40#include "InstanceScript.h"
41#include "Language.h"
42#include "LFG.h"
43#include "Log.h"
44#include "M2Stores.h"
45#include "MapManager.h"
46#include "MovementPackets.h"
47#include "ObjectAccessor.h"
48#include "ObjectMgr.h"
49#include "PhasingHandler.h"
50#include "PoolMgr.h"
51#include "RBAC.h"
52#include "SpellMgr.h"
53#include "SpellPackets.h"
54#include "Transport.h"
55#include "World.h"
56#include "WorldSession.h"
57#include "WorldStateMgr.h"
58#include <fstream>
59#include <limits>
60#include <map>
61#include <set>
62#include <sstream>
63
64using namespace Trinity::ChatCommands;
65
67{
68public:
69 debug_commandscript() : CommandScript("debug_commandscript") { }
70
71 std::span<ChatCommandBuilder const> GetCommands() const override
72 {
73 static ChatCommandTable debugPlayCommandTable =
74 {
80 };
81 static ChatCommandTable debugSendCommandTable =
82 {
85 { "chatmessage", HandleDebugSendChatMsgCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No },
95 };
96 static ChatCommandTable debugCommandTable =
97 {
99 { "threatinfo", HandleDebugThreatInfoCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No },
102 { "arena", HandleDebugArenaCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::Yes },
104 { "getitemstate", HandleDebugGetItemStateCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No },
105 { "lootrecipient", HandleDebugGetLootRecipientCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No },
106 { "play", debugPlayCommandTable },
107 { "send", debugSendCommandTable },
108 { "setaurastate", HandleDebugSetAuraStateCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No },
109 { "spawnvehicle", HandleDebugSpawnVehicleCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No },
110 { "entervehicle", HandleDebugEnterVehicleCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No },
112 { "itemexpire", HandleDebugItemExpireCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No },
113 { "areatriggers", HandleDebugAreaTriggersCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No },
115 { "moveflags", HandleDebugMoveflagsCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No },
116 { "transport", HandleDebugTransportCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No },
117 { "loadcells", HandleDebugLoadCellsCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::Yes },
119 { "boundary", HandleDebugBoundaryCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No },
120 { "raidreset", HandleDebugRaidResetCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No },
121 { "neargraveyard", HandleDebugNearGraveyard, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No },
122 { "instancespawn", HandleDebugInstanceSpawns, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No },
123 { "conversation", HandleDebugConversationCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No },
124 { "modifiertree", HandleDebugModifierTreeCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No },
125 { "wsexpression", HandleDebugWSExpressionCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No },
126 { "playercondition", HandleDebugPlayerConditionCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No },
127 { "pvp warmode", HandleDebugWarModeBalanceCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::Yes },
129 { "asan memoryleak", HandleDebugMemoryLeak, rbac::RBAC_PERM_COMMAND_DEBUG, Console::Yes },
130 { "asan outofbounds", HandleDebugOutOfBounds, rbac::RBAC_PERM_COMMAND_DEBUG, Console::Yes },
131 { "guidlimits", HandleDebugGuidLimitsCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::Yes },
132 { "objectcount", HandleDebugObjectCountCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::Yes },
133 { "questreset", HandleDebugQuestResetCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::Yes },
134 { "personalclone", HandleDebugBecomePersonalClone, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }
135 };
136 static ChatCommandTable commandTable =
137 {
138 { "debug", debugCommandTable },
139 { "wpgps", HandleWPGPSCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No },
140 };
141 return commandTable;
142 }
143
144 static bool TryExtractTeamId(std::string const &args, TeamId &outFaction)
145 {
146 if ("a" == args || "alliance" == args)
147 outFaction = TEAM_ALLIANCE;
148 else if ("h" == args || "horde" == args)
149 outFaction = TEAM_HORDE;
150 else if ("n" == args || "neutral" == args)
151 outFaction = TEAM_NEUTRAL;
152 else
153 return false;
154
155 return true;
156 }
157
158 static bool HandleDebugWarModeBalanceCommand(ChatHandler* handler, Variant<uint32, EXACT_SEQUENCE("alliance"), EXACT_SEQUENCE("horde"), EXACT_SEQUENCE("neutral"), EXACT_SEQUENCE("off")> command, Optional<int32> rewardValue)
159 {
160 // USAGE: .debug pvp fb <alliance|horde|neutral|off> [pct]
161 // neutral Sets faction balance off.
162 // alliance Set faction balance to alliance.
163 // horde Set faction balance to horde.
164 // off Reset the faction balance and use the calculated value of it
165 switch (command.index())
166 {
167 case 0: // workaround for Variant of only ExactSequences not being supported
169 handler->SetSentErrorMessage(true);
170 return false;
171 case 1:
172 sWorld->SetForcedWarModeFactionBalanceState(TEAM_ALLIANCE, rewardValue.value_or(0));
173 break;
174 case 2:
175 sWorld->SetForcedWarModeFactionBalanceState(TEAM_HORDE, rewardValue.value_or(0));
176 break;
177 case 3:
178 sWorld->SetForcedWarModeFactionBalanceState(TEAM_NEUTRAL);
179 break;
180 case 4:
181 sWorld->DisableForcedWarModeFactionBalanceState();
182 break;
183 }
184
185 return true;
186 }
187
188 // cinematicId - ID from CinematicSequences.dbc
189 static bool HandleDebugPlayCinematicCommand(ChatHandler* handler, uint32 cinematicId)
190 {
191 CinematicSequencesEntry const* cineSeq = sCinematicSequencesStore.LookupEntry(cinematicId);
192 if (!cineSeq)
193 {
194 handler->PSendSysMessage(LANG_CINEMATIC_NOT_EXIST, cinematicId);
195 handler->SetSentErrorMessage(true);
196 return false;
197 }
198
199 // Dump camera locations
200 if (std::vector<FlyByCamera> const* flyByCameras = GetFlyByCameras(cineSeq->Camera[0]))
201 {
202 handler->PSendSysMessage("Waypoints for sequence %u, camera %u", cinematicId, cineSeq->Camera[0]);
203 uint32 count = 1;
204 for (FlyByCamera const& cam : *flyByCameras)
205 {
206 handler->PSendSysMessage("%02u - %7ums [%s (%f degrees)]", count, cam.timeStamp, cam.locations.ToString().c_str(), cam.locations.GetOrientation() * (180 / M_PI));
207 ++count;
208 }
209 handler->PSendSysMessage(SZFMTD " waypoints dumped", flyByCameras->size());
210 }
211
212 handler->GetPlayer()->SendCinematicStart(cinematicId);
213 return true;
214 }
215
216 // movieId - ID from Movie.dbc
217 static bool HandleDebugPlayMovieCommand(ChatHandler* handler, uint32 movieId)
218 {
219
220 if (!sMovieStore.LookupEntry(movieId))
221 {
222 handler->PSendSysMessage(LANG_MOVIE_NOT_EXIST, movieId);
223 handler->SetSentErrorMessage(true);
224 return false;
225 }
226
227 handler->GetPlayer()->SendMovieStart(movieId);
228 return true;
229 }
230
231 // soundId - ID from SoundKit.db2
232 static bool HandleDebugPlaySoundCommand(ChatHandler* handler, uint32 soundId, Optional<uint32> broadcastTextId)
233 {
234 if (!sSoundKitStore.LookupEntry(soundId))
235 {
236 handler->PSendSysMessage(LANG_SOUND_NOT_EXIST, soundId);
237 handler->SetSentErrorMessage(true);
238 return false;
239 }
240
241 Player* player = handler->GetPlayer();
242
243 Unit* unit = handler->getSelectedUnit();
244 if (!unit)
245 {
247 handler->SetSentErrorMessage(true);
248 return false;
249 }
250
251 if (player->GetTarget().IsEmpty())
252 unit->PlayDistanceSound(soundId, player);
253 else
254 unit->PlayDirectSound(soundId, player, broadcastTextId.value_or(0));
255
256 handler->PSendSysMessage(LANG_YOU_HEAR_SOUND, soundId);
257 return true;
258 }
259
260 // musicId - ID from SoundEntries.dbc
261 static bool HandleDebugPlayMusicCommand(ChatHandler* handler, uint32 musicId)
262 {
263 if (!sSoundKitStore.LookupEntry(musicId))
264 {
265 handler->PSendSysMessage(LANG_SOUND_NOT_EXIST, musicId);
266 handler->SetSentErrorMessage(true);
267 return false;
268 }
269
270 Player* player = handler->GetPlayer();
271
272 player->PlayDirectMusic(musicId, player);
273
274 handler->PSendSysMessage(LANG_YOU_HEAR_SOUND, musicId);
275 return true;
276 }
277
278 static bool HandleDebugPlayObjectSoundCommand(ChatHandler* handler, int32 soundKitId, Optional<int32> broadcastTextId)
279 {
280 if (!sSoundKitStore.LookupEntry(soundKitId))
281 {
282 handler->PSendSysMessage(LANG_SOUND_NOT_EXIST, soundKitId);
283 handler->SetSentErrorMessage(true);
284 return false;
285 }
286
287 Player* player = handler->GetPlayer();
288
289 player->PlayObjectSound(soundKitId, player->GetGUID(), player, broadcastTextId.has_value() ? *broadcastTextId : 0);
290
291 handler->PSendSysMessage(LANG_YOU_HEAR_SOUND, soundKitId);
292 return true;
293 }
294
296 {
298 castFailed.CastID = ObjectGuid::Empty;
299 castFailed.SpellID = 133;
300 castFailed.Reason = result;
301 castFailed.FailedArg1 = failArg1.value_or(-1);
302 castFailed.FailedArg2 = failArg2.value_or(-1);
303 handler->GetSession()->SendPacket(castFailed.Write());
304
305 return true;
306 }
307
309 {
310 Player* player = handler->GetPlayer();
311 player->SendPlayerChoice(player->GetGUID(), choiceId);
312 return true;
313 }
314
316 {
317 handler->GetPlayer()->SendEquipError(error, nullptr, nullptr);
318 return true;
319 }
320
322 {
323 handler->GetPlayer()->SendSellError(error, nullptr, ObjectGuid::Empty);
324 return true;
325 }
326
328 {
329 handler->GetPlayer()->SendBuyError(error, nullptr, 0, 0);
330 return true;
331 }
332
334 {
335 Unit* unit = handler->getSelectedUnit();
336 Player* player = nullptr;
337 if (!unit || (unit->GetTypeId() != TYPEID_PLAYER))
338 player = handler->GetPlayer();
339 else
340 player = unit->ToPlayer();
341
342 if (!unit)
343 unit = player;
344
345 std::ifstream ifs("opcode.txt");
346 if (ifs.fail())
347 return false;
348
349 // remove comments from file
350 std::stringstream parsedStream;
351 while (!ifs.eof())
352 {
353 char commentToken[2] = {};
354 ifs.get(commentToken[0]);
355 if (ifs.eof())
356 break;
357 if (commentToken[0] == '/')
358 {
359 ifs.get(commentToken[1]);
360 if (!ifs.eof())
361 {
362 // /* comment
363 if (commentToken[1] == '*')
364 {
365 while (!ifs.eof())
366 {
367 ifs.get(commentToken[0]);
368 if (ifs.eof())
369 break;
370 if (commentToken[0] == '*')
371 {
372 ifs.get(commentToken[1]);
373 if (ifs.eof())
374 break;
375 if (commentToken[1] == '/')
376 break;
377 else
378 ifs.putback(commentToken[1]);
379 }
380 }
381 continue;
382 }
383 // line comment
384 else if (commentToken[1] == '/')
385 {
386 std::string str;
387 std::getline(ifs, str);
388 if (ifs.eof())
389 break;
390 continue;
391 }
392 // regular data
393 else
394 ifs.putback(commentToken[1]);
395 }
396 }
397 parsedStream.put(commentToken[0]);
398 }
399 ifs.close();
400
401 uint32 opcode = 0;
402 parsedStream >> opcode;
403
404 if (!opcode)
405 return false;
406
407 WorldPacket data(OpcodeServer(opcode), 0);
408
409 while (!parsedStream.eof() && !parsedStream.fail())
410 {
411 std::string type;
412 parsedStream >> type;
413
414 if (type.empty())
415 break;
416
417 if (type == "uint8")
418 {
419 if (parsedStream.eof())
420 return false;
421 uint16 val1 = 0;
422 parsedStream >> val1;
423 if (parsedStream.fail())
424 return false;
425 data << uint8(val1);
426 }
427 else if (type == "uint16")
428 {
429 if (parsedStream.eof())
430 return false;
431 uint16 val2 = 0;
432 parsedStream >> val2;
433 if (parsedStream.fail())
434 return false;
435 data << val2;
436 }
437 else if (type == "uint32")
438 {
439 if (parsedStream.eof())
440 return false;
441 uint32 val3 = 0;
442 parsedStream >> val3;
443 if (parsedStream.fail())
444 return false;
445 data << val3;
446 }
447 else if (type == "uint64")
448 {
449 if (parsedStream.eof())
450 return false;
451 uint64 val4 = 0;
452 parsedStream >> val4;
453 if (parsedStream.fail())
454 return false;
455 data << val4;
456 }
457 else if (type == "float")
458 {
459 if (parsedStream.eof())
460 return false;
461 float val5 = 0.0f;
462 parsedStream >> val5;
463 if (parsedStream.fail())
464 return false;
465 data << val5;
466 }
467 else if (type == "string")
468 {
469 std::string val6;
470 parsedStream >> val6;
471 // empty string is allowed so no need to check eof/fail here
472 data << val6;
473 }
474 else if (type == "goguid")
475 {
476 GameObject* obj = handler->GetNearbyGameObject();
477 if (!obj)
478 {
480 handler->SetSentErrorMessage(true);
481 return false;
482 }
483 data << obj->GetGUID();
484 }
485 else if (type == "myguid")
486 {
487 data << player->GetGUID();
488 }
489 else if (type == "itsguid")
490 {
491 data << unit->GetGUID();
492 }
493 else if (type == "itspos")
494 {
495 data << unit->GetPositionX();
496 data << unit->GetPositionY();
497 data << unit->GetPositionZ();
498 }
499 else if (type == "mypos")
500 {
501 data << player->GetPositionX();
502 data << player->GetPositionY();
503 data << player->GetPositionZ();
504 }
505 else
506 {
507 TC_LOG_ERROR("misc", "Sending opcode that has unknown type '{}'", type);
508 break;
509 }
510 }
511 TC_LOG_DEBUG("network", "Sending opcode {}", data.GetOpcode());
512 data.hexlike();
513 player->GetSession()->SendPacket(&data, true);
514 handler->PSendSysMessage(LANG_COMMAND_OPCODESENT, data.GetOpcode(), unit->GetName().c_str());
515 return true;
516 }
517
518 static bool HandleDebugUpdateWorldStateCommand(ChatHandler const* handler, int32 variable, int32 value)
519 {
520 WorldStateMgr::SetValue(variable, value, false, handler->GetPlayer()->GetMap());
521 return true;
522 }
523
525 {
526 Player* player = handler->GetPlayer();
527 if (!player->isDebugAreaTriggers)
528 {
530 player->isDebugAreaTriggers = true;
531 }
532 else
533 {
535 player->isDebugAreaTriggers = false;
536 }
537 player->UpdateObjectVisibility();
538 return true;
539 }
540
542 {
544 channelNotify.Type = type;
545 channelNotify._Channel = "test";
546 handler->GetSession()->SendPacket(channelNotify.Write());
547 return true;
548 }
549
551 {
553 packet.Initialize(type, LANG_UNIVERSAL, handler->GetPlayer(), handler->GetPlayer(), "testtest", 0, "chan");
554 handler->GetSession()->SendPacket(packet.Write());
555 return true;
556 }
557
559 {
560 handler->GetSession()->GetPlayer()->SendPushToPartyResponse(handler->GetPlayer(), msg);
561 return true;
562 }
563
565 {
566 Creature* target = handler->getSelectedCreature();
567 if (!target)
568 return false;
569
570 handler->PSendSysMessage("Loot recipients for creature %s (%s, SpawnID " UI64FMTD ") are:",
571 target->GetName().c_str(), target->GetGUID().ToString().c_str(), target->GetSpawnId());
572
573 for (ObjectGuid tapperGuid : target->GetTapList())
574 {
575 Player* tapper = ObjectAccessor::GetPlayer(*target, tapperGuid);
576 handler->PSendSysMessage("* %s", tapper ? tapper->GetName().c_str() : "offline");
577 }
578
579 return true;
580 }
581
583 {
584 handler->GetPlayer()->SendCanTakeQuestResponse(msg);
585 return true;
586 }
587
588 static bool HandleDebugGetItemStateCommand(ChatHandler* handler, std::string itemState)
589 {
591 bool listQueue = false;
592 bool checkAll = false;
593
594 if (itemState == "unchanged")
595 state = ITEM_UNCHANGED;
596 else if (itemState == "changed")
597 state = ITEM_CHANGED;
598 else if (itemState == "new")
599 state = ITEM_NEW;
600 else if (itemState == "removed")
601 state = ITEM_REMOVED;
602 else if (itemState == "queue")
603 listQueue = true;
604 else if (itemState == "check_all")
605 checkAll = true;
606 else
607 return false;
608
609 Player* player = handler->getSelectedPlayer();
610 if (!player)
611 player = handler->GetPlayer();
612
613 if (!listQueue && !checkAll)
614 {
615 itemState = "The player has the following " + itemState + " items: ";
616 handler->SendSysMessage(itemState.c_str());
617 for (uint8 i = PLAYER_SLOT_START; i < PLAYER_SLOT_END; ++i)
618 {
619 if (i >= BUYBACK_SLOT_START && i < BUYBACK_SLOT_END)
620 continue;
621
622 if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, i))
623 {
624 if (Bag* bag = item->ToBag())
625 {
626 for (uint8 j = 0; j < bag->GetBagSize(); ++j)
627 if (Item* item2 = bag->GetItemByPos(j))
628 if (item2->GetState() == state)
629 handler->PSendSysMessage("bag: 255 slot: %d %s owner: %s", item2->GetSlot(), item2->GetGUID().ToString().c_str(), item2->GetOwnerGUID().ToString().c_str());
630 }
631 else if (item->GetState() == state)
632 handler->PSendSysMessage("bag: 255 slot: %d %s owner: %s", item->GetSlot(), item->GetGUID().ToString().c_str(), item->GetOwnerGUID().ToString().c_str());
633 }
634 }
635 }
636
637 if (listQueue)
638 {
639 std::vector<Item*>& updateQueue = player->GetItemUpdateQueue();
640 for (size_t i = 0; i < updateQueue.size(); ++i)
641 {
642 Item* item = updateQueue[i];
643 if (!item)
644 continue;
645
646 Bag* container = item->GetContainer();
647 uint8 bagSlot = container ? container->GetSlot() : uint8(INVENTORY_SLOT_BAG_0);
648
649 std::string st;
650 switch (item->GetState())
651 {
652 case ITEM_UNCHANGED:
653 st = "unchanged";
654 break;
655 case ITEM_CHANGED:
656 st = "changed";
657 break;
658 case ITEM_NEW:
659 st = "new";
660 break;
661 case ITEM_REMOVED:
662 st = "removed";
663 break;
664 }
665
666 handler->PSendSysMessage("bag: %d slot: %d %s - state: %s", bagSlot, item->GetSlot(), item->GetGUID().ToString().c_str(), st.c_str());
667 }
668 if (updateQueue.empty())
669 handler->PSendSysMessage("The player's updatequeue is empty");
670 }
671
672 if (checkAll)
673 {
674 bool error = false;
675 std::vector<Item*>& updateQueue = player->GetItemUpdateQueue();
676 for (uint8 i = PLAYER_SLOT_START; i < PLAYER_SLOT_END; ++i)
677 {
678 if (i >= BUYBACK_SLOT_START && i < BUYBACK_SLOT_END)
679 continue;
680
681 Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, i);
682 if (!item)
683 continue;
684
685 if (item->GetSlot() != i)
686 {
687 handler->PSendSysMessage("Item with slot %d and %s has an incorrect slot value: %d", i, item->GetGUID().ToString().c_str(), item->GetSlot());
688 error = true;
689 continue;
690 }
691
692 if (item->GetOwnerGUID() != player->GetGUID())
693 {
694 handler->PSendSysMessage("The item with slot %d %s does have non-matching owner guid %s and %s!", item->GetSlot(), item->GetGUID().ToString().c_str(), item->GetOwnerGUID().ToString().c_str(), player->GetGUID().ToString().c_str());
695 error = true;
696 continue;
697 }
698
699 if (Bag* container = item->GetContainer())
700 {
701 handler->PSendSysMessage("The item with slot %d %s has a container (slot: %d, %s) but shouldn't!", item->GetSlot(), item->GetGUID().ToString().c_str(), container->GetSlot(), container->GetGUID().ToString().c_str());
702 error = true;
703 continue;
704 }
705
706 if (item->IsInUpdateQueue())
707 {
708 uint16 qp = item->GetQueuePos();
709 if (qp > updateQueue.size())
710 {
711 handler->PSendSysMessage("The item with slot %d and %s has its queuepos (%d) larger than the update queue size! ", item->GetSlot(), item->GetGUID().ToString().c_str(), qp);
712 error = true;
713 continue;
714 }
715
716 if (updateQueue[qp] == nullptr)
717 {
718 handler->PSendSysMessage("The item with slot %d and %s has its queuepos (%d) pointing to NULL in the queue!", item->GetSlot(), item->GetGUID().ToString().c_str(), qp);
719 error = true;
720 continue;
721 }
722
723 if (updateQueue[qp] != item)
724 {
725 handler->PSendSysMessage("The item with slot %d and %s has a queuepos (%d) that points to another item in the queue (bag: %d, slot: %d, %s)", item->GetSlot(), item->GetGUID().ToString().c_str(), qp, updateQueue[qp]->GetBagSlot(), updateQueue[qp]->GetSlot(), updateQueue[qp]->GetGUID().ToString().c_str());
726 error = true;
727 continue;
728 }
729 }
730 else if (item->GetState() != ITEM_UNCHANGED)
731 {
732 handler->PSendSysMessage("The item with slot %d and %s is not in queue but should be (state: %d)!", item->GetSlot(), item->GetGUID().ToString().c_str(), item->GetState());
733 error = true;
734 continue;
735 }
736
737 if (Bag* bag = item->ToBag())
738 {
739 for (uint8 j = 0; j < bag->GetBagSize(); ++j)
740 {
741 Item* item2 = bag->GetItemByPos(j);
742 if (!item2)
743 continue;
744
745 if (item2->GetSlot() != j)
746 {
747 handler->PSendSysMessage("The item in bag %d and slot %d (%s) has an incorrect slot value: %d", bag->GetSlot(), j, item2->GetGUID().ToString().c_str(), item2->GetSlot());
748 error = true;
749 continue;
750 }
751
752 if (item2->GetOwnerGUID() != player->GetGUID())
753 {
754 handler->PSendSysMessage("The item in bag %d at slot %d and %s, the owner (%s) and the player (%s) don't match!", bag->GetSlot(), item2->GetSlot(), item2->GetGUID().ToString().c_str(), item2->GetOwnerGUID().ToString().c_str(), player->GetGUID().ToString().c_str());
755 error = true;
756 continue;
757 }
758
759 Bag* container = item2->GetContainer();
760 if (!container)
761 {
762 handler->PSendSysMessage("The item in bag %d at slot %d %s has no container!", bag->GetSlot(), item2->GetSlot(), item2->GetGUID().ToString().c_str());
763 error = true;
764 continue;
765 }
766
767 if (container != bag)
768 {
769 handler->PSendSysMessage("The item in bag %d at slot %d %s has a different container(slot %d %s)!", bag->GetSlot(), item2->GetSlot(), item2->GetGUID().ToString().c_str(), container->GetSlot(), container->GetGUID().ToString().c_str());
770 error = true;
771 continue;
772 }
773
774 if (item2->IsInUpdateQueue())
775 {
776 uint16 qp = item2->GetQueuePos();
777 if (qp > updateQueue.size())
778 {
779 handler->PSendSysMessage("The item in bag %d at slot %d having %s has a queuepos (%d) larger than the update queue size! ", bag->GetSlot(), item2->GetSlot(), item2->GetGUID().ToString().c_str(), qp);
780 error = true;
781 continue;
782 }
783
784 if (updateQueue[qp] == nullptr)
785 {
786 handler->PSendSysMessage("The item in bag %d at slot %d having %s has a queuepos (%d) that points to NULL in the queue!", bag->GetSlot(), item2->GetSlot(), item2->GetGUID().ToString().c_str(), qp);
787 error = true;
788 continue;
789 }
790
791 if (updateQueue[qp] != item2)
792 {
793 handler->PSendSysMessage("The item in bag %d at slot %d having %s has a queuepos (%d) that points to another item in the queue (bag: %d, slot: %d, %s)", bag->GetSlot(), item2->GetSlot(), item2->GetGUID().ToString().c_str(), qp, updateQueue[qp]->GetBagSlot(), updateQueue[qp]->GetSlot(), updateQueue[qp]->GetGUID().ToString().c_str());
794 error = true;
795 continue;
796 }
797 }
798 else if (item2->GetState() != ITEM_UNCHANGED)
799 {
800 handler->PSendSysMessage("The item in bag %d at slot %d having %s is not in queue but should be (state: %d)!", bag->GetSlot(), item2->GetSlot(), item2->GetGUID().ToString().c_str(), item2->GetState());
801 error = true;
802 continue;
803 }
804 }
805 }
806 }
807
808 for (size_t i = 0; i < updateQueue.size(); ++i)
809 {
810 Item* item = updateQueue[i];
811 if (!item)
812 continue;
813
814 if (item->GetOwnerGUID() != player->GetGUID())
815 {
816 handler->PSendSysMessage("queue(%zu): For the item %s, the owner (%s) and the player (%s) don't match!", i, item->GetGUID().ToString().c_str(), item->GetOwnerGUID().ToString().c_str(), player->GetGUID().ToString().c_str());
817 error = true;
818 continue;
819 }
820
821 if (item->GetQueuePos() != i)
822 {
823 handler->PSendSysMessage("queue(%zu): For the item %s, the queuepos doesn't match it's position in the queue!", i, item->GetGUID().ToString().c_str());
824 error = true;
825 continue;
826 }
827
828 if (item->GetState() == ITEM_REMOVED)
829 continue;
830
831 Item* test = player->GetItemByPos(item->GetBagSlot(), item->GetSlot());
832
833 if (test == nullptr)
834 {
835 handler->PSendSysMessage("queue(%zu): The bag(%d) and slot(%d) values for %s are incorrect, the player doesn't have any item at that position!", i, item->GetBagSlot(), item->GetSlot(), item->GetGUID().ToString().c_str());
836 error = true;
837 continue;
838 }
839
840 if (test != item)
841 {
842 handler->PSendSysMessage("queue(%zu): The bag(%d) and slot(%d) values for the %s are incorrect, %s is there instead!", i, item->GetBagSlot(), item->GetSlot(), item->GetGUID().ToString().c_str(), test->GetGUID().ToString().c_str());
843 error = true;
844 continue;
845 }
846 }
847 if (!error)
848 handler->SendSysMessage("All OK!");
849 }
850
851 return true;
852 }
853
855 {
856 sBattlegroundMgr->ToggleTesting();
857 return true;
858 }
859
860 static bool HandleDebugArenaCommand(ChatHandler* handler, uint32 battlemasterListId)
861 {
862 bool successful = sBattlegroundMgr->ToggleArenaTesting(battlemasterListId);
863 if (!successful)
864 {
865 handler->PSendSysMessage("BattlemasterListId %u does not exist or is not an arena.", battlemasterListId);
866 handler->SetSentErrorMessage(true);
867 return true;
868 }
869
870 if (!battlemasterListId || !handler || !handler->GetSession())
871 return true;
872
874 return true;
875 }
876
878 {
879 Unit* target = handler->getSelectedUnit();
880 if (!target)
881 target = handler->GetPlayer();
882
883 ThreatManager& mgr = target->GetThreatManager();
884 if (!target->IsAlive())
885 {
886 handler->PSendSysMessage("%s (%s) is not alive.%s", target->GetName().c_str(), target->GetGUID().ToString().c_str(), target->IsEngaged() ? " (It is, however, engaged. Huh?)" : "");
887 return true;
888 }
889
890 uint32 count = 0;
891 auto const& threatenedByMe = target->GetThreatManager().GetThreatenedByMeList();
892 if (threatenedByMe.empty())
893 handler->PSendSysMessage("%s (%s) does not threaten any units.", target->GetName().c_str(), target->GetGUID().ToString().c_str());
894 else
895 {
896 handler->PSendSysMessage("List of units threatened by %s (%s)", target->GetName().c_str(), target->GetGUID().ToString().c_str());
897 for (auto const& pair : threatenedByMe)
898 {
899 Unit* unit = pair.second->GetOwner();
900 handler->PSendSysMessage(" %u. %s (%s, SpawnID " UI64FMTD ") - threat %f", ++count, unit->GetName().c_str(), unit->GetGUID().ToString().c_str(), unit->GetTypeId() == TYPEID_UNIT ? unit->ToCreature()->GetSpawnId() : 0, pair.second->GetThreat());
901 }
902 handler->SendSysMessage("End of threatened-by-me list.");
903 }
904
905 if (mgr.CanHaveThreatList())
906 {
907 if (!mgr.IsThreatListEmpty(true))
908 {
909 if (target->IsEngaged())
910 handler->PSendSysMessage("Threat list of %s (%s, SpawnID " UI64FMTD "):", target->GetName().c_str(), target->GetGUID().ToString().c_str(), target->GetTypeId() == TYPEID_UNIT ? target->ToCreature()->GetSpawnId() : 0);
911 else
912 handler->PSendSysMessage("%s (%s, SpawnID " UI64FMTD ") is not engaged, but still has a threat list? Well, here it is:", target->GetName().c_str(), target->GetGUID().ToString().c_str(), target->GetTypeId() == TYPEID_UNIT ? target->ToCreature()->GetSpawnId() : 0);
913
914 count = 0;
915 Unit* fixateVictim = mgr.GetFixateTarget();
916 for (ThreatReference const* ref : mgr.GetSortedThreatList())
917 {
918 Unit* unit = ref->GetVictim();
919 char const* onlineStr;
920 switch (ref->GetOnlineState())
921 {
923 onlineStr = " [SUPPRESSED]";
924 break;
926 onlineStr = " [OFFLINE]";
927 break;
928 default:
929 onlineStr = "";
930 }
931 char const* tauntStr;
932 if (unit == fixateVictim)
933 tauntStr = " [FIXATE]";
934 else
935 switch (ref->GetTauntState())
936 {
938 tauntStr = " [TAUNT]";
939 break;
941 tauntStr = " [DETAUNT]";
942 break;
943 default:
944 tauntStr = "";
945 }
946 handler->PSendSysMessage(" %u. %s (%s) - threat %f%s%s", ++count, unit->GetName().c_str(), unit->GetGUID().ToString().c_str(), ref->GetThreat(), tauntStr, onlineStr);
947 }
948 handler->SendSysMessage("End of threat list.");
949 }
950 else if (!target->IsEngaged())
951 handler->PSendSysMessage("%s (%s, SpawnID " UI64FMTD ") is not currently engaged.", target->GetName().c_str(), target->GetGUID().ToString().c_str(), target->GetTypeId() == TYPEID_UNIT ? target->ToCreature()->GetSpawnId() : 0);
952 else
953 handler->PSendSysMessage("%s (%s, SpawnID " UI64FMTD ") seems to be engaged, but does not have a threat list??", target->GetName().c_str(), target->GetGUID().ToString().c_str(), target->GetTypeId() == TYPEID_UNIT ? target->ToCreature()->GetSpawnId() : 0);
954 }
955 else if (target->IsEngaged())
956 handler->PSendSysMessage("%s (%s) is currently engaged. (This unit cannot have a threat list.)", target->GetName().c_str(), target->GetGUID().ToString().c_str());
957 else
958 handler->PSendSysMessage("%s (%s) is not currently engaged. (This unit cannot have a threat list.)", target->GetName().c_str(), target->GetGUID().ToString().c_str());
959 return true;
960 }
961
963 {
964 Unit* target = handler->getSelectedUnit();
965 if (!target)
966 {
968 handler->SetSentErrorMessage(true);
969 return false;
970 }
971
972 handler->PSendSysMessage("Threat info for %s (%s):", target->GetName().c_str(), target->GetGUID().ToString().c_str());
973
974 ThreatManager const& mgr = target->GetThreatManager();
975
976 // _singleSchoolModifiers
977 {
978 auto& mods = mgr._singleSchoolModifiers;
979 handler->SendSysMessage(" - Single-school threat modifiers:");
980 handler->PSendSysMessage(" |-- Physical: %.2f%%", mods[SPELL_SCHOOL_NORMAL] * 100.0f);
981 handler->PSendSysMessage(" |-- Holy : %.2f%%", mods[SPELL_SCHOOL_HOLY] * 100.0f);
982 handler->PSendSysMessage(" |-- Fire : %.2f%%", mods[SPELL_SCHOOL_FIRE] * 100.0f);
983 handler->PSendSysMessage(" |-- Nature : %.2f%%", mods[SPELL_SCHOOL_NATURE] * 100.0f);
984 handler->PSendSysMessage(" |-- Frost : %.2f%%", mods[SPELL_SCHOOL_FROST] * 100.0f);
985 handler->PSendSysMessage(" |-- Shadow : %.2f%%", mods[SPELL_SCHOOL_SHADOW] * 100.0f);
986 handler->PSendSysMessage(" |-- Arcane : %.2f%%", mods[SPELL_SCHOOL_ARCANE] * 100.0f);
987 }
988
989 // _multiSchoolModifiers
990 {
991 auto& mods = mgr._multiSchoolModifiers;
992 handler->PSendSysMessage("- Multi-school threat modifiers (%zu entries):", mods.size());
993 for (auto const& pair : mods)
994 handler->PSendSysMessage(" |-- Mask 0x%x: %.2f%%", uint32(pair.first), pair.second);
995 }
996
997 // _redirectInfo
998 {
999 auto const& redirectInfo = mgr._redirectInfo;
1000 if (redirectInfo.empty())
1001 handler->SendSysMessage(" - No redirects being applied");
1002 else
1003 {
1004 handler->PSendSysMessage(" - %02zu redirects being applied:", redirectInfo.size());
1005 for (auto const& pair : redirectInfo)
1006 {
1007 Unit* unit = ObjectAccessor::GetUnit(*target, pair.first);
1008 handler->PSendSysMessage(" |-- % 2.1f%% to %s", pair.second, unit ? unit->GetName().c_str() : pair.first.ToString().c_str());
1009 }
1010 }
1011 }
1012
1013 // _redirectRegistry
1014 {
1015 auto const& redirectRegistry = mgr._redirectRegistry;
1016 if (redirectRegistry.empty())
1017 handler->SendSysMessage(" - No redirects are registered");
1018 else
1019 {
1020 handler->PSendSysMessage(" - %02zu spells may have redirects registered", redirectRegistry.size());
1021 for (auto const& outerPair : redirectRegistry) // (spellId, (guid, pct))
1022 {
1023 SpellInfo const* const spell = sSpellMgr->GetSpellInfo(outerPair.first, DIFFICULTY_NONE);
1024 handler->PSendSysMessage(" |-- #%06u %s (%zu entries):", outerPair.first, spell ? (*spell->SpellName)[sWorld->GetDefaultDbcLocale()] : "<unknown>", outerPair.second.size());
1025 for (auto const& innerPair : outerPair.second) // (guid, pct)
1026 {
1027 Unit* unit = ObjectAccessor::GetUnit(*target, innerPair.first);
1028 handler->PSendSysMessage(" |-- % 2.1f%% to %s", innerPair.second, unit ? unit->GetName().c_str() : innerPair.first.ToString().c_str());
1029 }
1030 }
1031 }
1032 }
1033
1034 return true;
1035 }
1036
1038 {
1039 Unit* target = handler->getSelectedUnit();
1040 if (!target)
1041 target = handler->GetPlayer();
1042
1043 handler->PSendSysMessage("Combat refs: (Combat state: %d | Manager state: %d)", target->IsInCombat(), target->GetCombatManager().HasCombat());
1044 for (auto const& ref : target->GetCombatManager().GetPvPCombatRefs())
1045 {
1046 Unit* unit = ref.second->GetOther(target);
1047 handler->PSendSysMessage("[PvP] %s (SpawnID %u)", unit->GetName().c_str(), unit->GetTypeId() == TYPEID_UNIT ? unit->ToCreature()->GetSpawnId() : 0);
1048 }
1049 for (auto const& ref : target->GetCombatManager().GetPvECombatRefs())
1050 {
1051 Unit* unit = ref.second->GetOther(target);
1052 handler->PSendSysMessage("[PvE] %s (SpawnID %u)", unit->GetName().c_str(), unit->GetTypeId() == TYPEID_UNIT ? unit->ToCreature()->GetSpawnId() : 0);
1053 }
1054 return true;
1055 }
1056
1058 {
1059 Unit* target = handler->getSelectedUnit();
1060 if (!target || !target->IsVehicle())
1061 return false;
1062
1063 if (!seatId)
1064 seatId = -1;
1065
1066 if (!entry)
1067 handler->GetPlayer()->EnterVehicle(target, *seatId);
1068 else
1069 {
1070 Creature* passenger = nullptr;
1071 Trinity::AllCreaturesOfEntryInRange check(handler->GetPlayer(), entry, 20.0f);
1073 Cell::VisitAllObjects(handler->GetPlayer(), searcher, 30.0f);
1074 if (!passenger || passenger == target)
1075 return false;
1076 passenger->EnterVehicle(target, *seatId);
1077 }
1078
1079 handler->PSendSysMessage("Unit %u entered vehicle %hhd", entry, *seatId);
1080 return true;
1081 }
1082
1084 {
1085 float x, y, z, o = handler->GetPlayer()->GetOrientation();
1086 handler->GetPlayer()->GetClosePoint(x, y, z, handler->GetPlayer()->GetCombatReach());
1087
1088 if (!id)
1089 return handler->GetPlayer()->SummonCreature(entry, x, y, z, o) != nullptr;
1090
1091 CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(entry);
1092
1093 if (!ci)
1094 return false;
1095
1096 VehicleEntry const* ve = sVehicleStore.LookupEntry(*id);
1097
1098 if (!ve)
1099 return false;
1100
1101 Map* map = handler->GetPlayer()->GetMap();
1102 Position pos = { x, y, z, o };
1103
1104 Creature* v = Creature::CreateCreature(entry, map, pos, *id);
1105 if (!v)
1106 return false;
1107
1109
1110 map->AddToMap(v);
1111
1112 return true;
1113 }
1114
1116 {
1117 std::ostringstream ss;
1118 while (ss.str().size() < 128000)
1119 ss << "This is a dummy string to push the packet's size beyond 128000 bytes. ";
1120 handler->SendSysMessage(ss.str().c_str());
1121 return true;
1122 }
1123
1125 {
1126 PhaseShift phaseShift;
1127
1128 if (phaseId)
1129 phaseShift.AddPhase(*phaseId, PhaseFlags::None, nullptr);
1130
1131 if (visibleMapId)
1132 phaseShift.AddVisibleMapId(*visibleMapId, nullptr);
1133
1134 if (uiMapPhaseId)
1135 phaseShift.AddUiMapPhaseId(*uiMapPhaseId);
1136
1137 PhasingHandler::SendToPlayer(handler->GetSession()->GetPlayer(), phaseShift);
1138 return true;
1139 }
1140
1142 {
1143 Item* i = handler->GetPlayer()->GetItemByGuid(ObjectGuid::Create<HighGuid::Item>(guid));
1144
1145 if (!i)
1146 return false;
1147
1148 handler->GetPlayer()->DestroyItem(i->GetBagSlot(), i->GetSlot(), true);
1149 sScriptMgr->OnItemExpire(handler->GetPlayer(), i->GetTemplate());
1150
1151 return true;
1152 }
1153
1154 // Play emote animation
1155 static bool HandleDebugAnimCommand(ChatHandler* handler, Emote emote)
1156 {
1157 if (Unit* unit = handler->getSelectedUnit())
1158 unit->HandleEmoteCommand(emote);
1159
1160 handler->PSendSysMessage("Playing emote %s", EnumUtils::ToConstant(emote));
1161
1162 return true;
1163 }
1164
1166 {
1167 if (Unit* unit = handler->getSelectedUnit())
1168 {
1169 Player* player = handler->GetPlayer();
1170 handler->PSendSysMessage("Checking LoS %s -> %s:", player->GetName().c_str(), unit->GetName().c_str());
1171 handler->PSendSysMessage(" VMAP LoS: %s", player->IsWithinLOSInMap(unit, LINEOFSIGHT_CHECK_VMAP) ? "clear" : "obstructed");
1172 handler->PSendSysMessage(" GObj LoS: %s", player->IsWithinLOSInMap(unit, LINEOFSIGHT_CHECK_GOBJECT) ? "clear" : "obstructed");
1173 handler->PSendSysMessage("%s is %sin line of sight of %s.", unit->GetName().c_str(), (player->IsWithinLOSInMap(unit) ? "" : "not "), player->GetName().c_str());
1174 return true;
1175 }
1176 return false;
1177 }
1178
1180 {
1181 Unit* unit = handler->getSelectedUnit();
1182 if (!unit)
1183 {
1185 handler->SetSentErrorMessage(true);
1186 return false;
1187 }
1188
1189 if (!state)
1190 {
1191 // reset all states
1192 for (AuraStateType s : EnumUtils::Iterate<AuraStateType>())
1193 unit->ModifyAuraState(s, false);
1194 return true;
1195 }
1196
1197 unit->ModifyAuraState(*state, apply);
1198 return true;
1199 }
1200
1201 static bool HandleDebugMoveflagsCommand(ChatHandler* handler, Optional<uint32> moveFlags, Optional<uint32> moveFlagsExtra, Optional<uint32> moveFlagsExtra2)
1202 {
1203 Unit* target = handler->getSelectedUnit();
1204 if (!target)
1205 target = handler->GetPlayer();
1206
1207 if (!moveFlags)
1208 {
1211 }
1212 else
1213 {
1214 target->SetUnitMovementFlags(*moveFlags);
1215
1216 if (moveFlagsExtra)
1217 target->SetExtraUnitMovementFlags(*moveFlagsExtra);
1218
1219 if (moveFlagsExtra2)
1220 target->SetExtraUnitMovementFlags2(*moveFlagsExtra2);
1221
1222 if (target->GetTypeId() != TYPEID_PLAYER)
1223 target->DestroyForNearbyPlayers(); // Force new SMSG_UPDATE_OBJECT:CreateObject
1224 else
1225 {
1227 moveUpdate.Status = &target->m_movementInfo;
1228 target->SendMessageToSet(moveUpdate.Write(), true);
1229 }
1230
1232 }
1233
1234 return true;
1235 }
1236
1237 static bool HandleWPGPSCommand(ChatHandler* handler)
1238 {
1239 Player* player = handler->GetPlayer();
1240
1241 TC_LOG_INFO("sql.dev", "(@PATH, XX, {:.3f}, {:.3f}, {:.5f}, {:.5f}, 0, 0, 0, 100, 0),", player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetOrientation());
1242
1243 handler->PSendSysMessage("Waypoint SQL written to SQL Developer log");
1244 return true;
1245 }
1246
1247 static bool HandleDebugTransportCommand(ChatHandler* handler, std::string operation)
1248 {
1249 Transport* transport = dynamic_cast<Transport*>(handler->GetPlayer()->GetTransport());
1250 if (!transport)
1251 return false;
1252
1253 bool start = false;
1254 if (StringEqualI(operation, "stop"))
1255 transport->EnableMovement(false);
1256 else if (StringEqualI(operation, "start"))
1257 {
1258 transport->EnableMovement(true);
1259 start = true;
1260 }
1261 else
1262 {
1263 Position pos = transport->GetPosition();
1264 handler->PSendSysMessage("Transport %s is %s", transport->GetName().c_str(), transport->GetGoState() == GO_STATE_READY ? "stopped" : "moving");
1265 handler->PSendSysMessage("Transport position: %s", pos.ToString().c_str());
1266 return true;
1267 }
1268
1269 handler->PSendSysMessage("Transport %s %s", transport->GetName().c_str(), start ? "started" : "stopped");
1270 return true;
1271 }
1272
1274 {
1275 if (mapId)
1276 {
1277 sMapMgr->DoForAllMapsWithMapId(*mapId, [&](Map* map)
1278 {
1279 HandleDebugLoadCellsCommandHelper(handler, map, tileX, tileY);
1280 });
1281 return true;
1282 }
1283
1284 if (Player* player = handler->GetPlayer())
1285 {
1286 // Fallback to player's map if no map has been specified
1287 return HandleDebugLoadCellsCommandHelper(handler, player->GetMap(), tileX, tileY);
1288 }
1289
1290 return false;
1291 }
1292
1294 {
1295 if (!map)
1296 return false;
1297
1298 // Load 1 single tile if specified, otherwise load the whole map
1299 if (tileX && tileY)
1300 {
1301 handler->PSendSysMessage("Loading cell (mapId: %u tile: %u, %u). Current GameObjects " SZFMTD ", Creatures " SZFMTD,
1302 map->GetId(), *tileX, *tileY, map->GetObjectsStore().Size<GameObject>(), map->GetObjectsStore().Size<Creature>());
1303
1304 // Some unit convertions to go from TileXY to GridXY to WorldXY
1305 float x = ((float(64 - 1 - *tileX) - 0.5f - CENTER_GRID_ID) * SIZE_OF_GRIDS) + (CENTER_GRID_OFFSET * 2);
1306 float y = ((float(64 - 1 - *tileY) - 0.5f - CENTER_GRID_ID) * SIZE_OF_GRIDS) + (CENTER_GRID_OFFSET * 2);
1307 map->LoadGrid(x, y);
1308
1309 handler->PSendSysMessage("Cell loaded (mapId: %u tile: %u, %u) After load - GameObject " SZFMTD ", Creatures " SZFMTD,
1310 map->GetId(), *tileX, *tileY, map->GetObjectsStore().Size<GameObject>(), map->GetObjectsStore().Size<Creature>());
1311 }
1312 else
1313 {
1314 handler->PSendSysMessage("Loading all cells (mapId: %u). Current GameObjects " SZFMTD ", Creatures " SZFMTD, map->GetId(), map->GetObjectsStore().Size<GameObject>(), map->GetObjectsStore().Size<Creature>());
1315
1316 map->LoadAllCells();
1317
1318 handler->PSendSysMessage("Cells loaded (mapId: %u) After load - GameObject " SZFMTD ", Creatures " SZFMTD, map->GetId(), map->GetObjectsStore().Size<GameObject>(), map->GetObjectsStore().Size<Creature>());
1319 }
1320
1321 return true;
1322 }
1323
1324 static bool HandleDebugBoundaryCommand(ChatHandler* handler, Optional<EXACT_SEQUENCE("fill")> fill, Optional<uint32> durationArg)
1325 {
1326 Player* player = handler->GetPlayer();
1327 if (!player)
1328 return false;
1329 Creature* target = handler->getSelectedCreature();
1330 if (!target || !target->IsAIEnabled())
1331 return false;
1332
1333 Seconds duration = durationArg ? Seconds(*durationArg) : 0s;
1334 if (duration <= 0s || duration >= 30min) // arbitrary upper limit
1335 duration = 3min;
1336
1337 int32 errMsg = target->AI()->VisualizeBoundary(duration, player, fill.has_value());
1338 if (errMsg > 0)
1339 handler->PSendSysMessage(errMsg);
1340
1341 return true;
1342 }
1343
1345 {
1346 Unit* target = handler->getSelectedUnit();
1347
1348 if (!target)
1349 {
1351 handler->SetSentErrorMessage(true);
1352 return false;
1353 }
1354
1355 if (target->GetDBPhase() > 0)
1356 handler->PSendSysMessage("Target creature's PhaseId in DB: %d", target->GetDBPhase());
1357 else if (target->GetDBPhase() < 0)
1358 handler->PSendSysMessage("Target creature's PhaseGroup in DB: %d", abs(target->GetDBPhase()));
1359
1360 PhasingHandler::PrintToChat(handler, target);
1361 return true;
1362 }
1363
1364 static bool HandleDebugRaidResetCommand(ChatHandler* handler, uint32 mapId, Optional<uint32> difficulty)
1365 {
1366 MapEntry const* mEntry = sMapStore.LookupEntry(mapId);
1367 if (!mEntry)
1368 {
1369 handler->PSendSysMessage("Invalid map specified.");
1370 return true;
1371 }
1372 if (!mEntry->IsDungeon())
1373 {
1374 handler->PSendSysMessage("'%s' is not a dungeon map.", mEntry->MapName[handler->GetSessionDbcLocale()]);
1375 return true;
1376 }
1377 if (difficulty && !sDifficultyStore.HasRecord(*difficulty))
1378 {
1379 handler->PSendSysMessage("Invalid difficulty %d.", *difficulty);
1380 return false;
1381 }
1382 if (difficulty && !sDB2Manager.GetMapDifficultyData(mEntry->ID, Difficulty(*difficulty)))
1383 {
1384 handler->PSendSysMessage("Difficulty %d is not valid for '%s'.", *difficulty, mEntry->MapName[handler->GetSessionDbcLocale()]);
1385 return true;
1386 }
1387
1388 return true;
1389 }
1390
1391 static bool HandleDebugQuestResetCommand(ChatHandler* handler, std::string arg)
1392 {
1393 if (!Utf8ToUpperOnlyLatin(arg))
1394 return false;
1395
1396 bool daily = false, weekly = false, monthly = false;
1397 if (arg == "ALL")
1398 daily = weekly = monthly = true;
1399 else if (arg == "DAILY")
1400 daily = true;
1401 else if (arg == "WEEKLY")
1402 weekly = true;
1403 else if (arg == "MONTHLY")
1404 monthly = true;
1405 else
1406 return false;
1407
1408 if (daily)
1409 {
1410 sWorld->DailyReset();
1411 handler->PSendSysMessage("Daily quests have been reset. Next scheduled reset: %s", TimeToHumanReadable(sWorld->GetPersistentWorldVariable(World::NextDailyQuestResetTimeVarId)).c_str());
1412 }
1413 if (weekly)
1414 {
1415 sWorld->ResetWeeklyQuests();
1416 handler->PSendSysMessage("Weekly quests have been reset. Next scheduled reset: %s", TimeToHumanReadable(sWorld->GetPersistentWorldVariable(World::NextWeeklyQuestResetTimeVarId)).c_str());
1417 }
1418 if (monthly)
1419 {
1420 sWorld->ResetMonthlyQuests();
1421 handler->PSendSysMessage("Monthly quests have been reset. Next scheduled reset: %s", TimeToHumanReadable(sWorld->GetPersistentWorldVariable(World::NextMonthlyQuestResetTimeVarId)).c_str());
1422 }
1423
1424 return true;
1425 }
1426
1427 static bool HandleDebugNearGraveyard(ChatHandler* handler, Optional<EXACT_SEQUENCE("linked")> linked)
1428 {
1429 Player* player = handler->GetPlayer();
1430 WorldSafeLocsEntry const* nearestLoc = nullptr;
1431
1432 if (linked)
1433 {
1434
1435 if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(player->GetMap(), player->GetZoneId()))
1436 nearestLoc = bf->GetClosestGraveyard(player);
1437 else
1438 nearestLoc = sObjectMgr->GetClosestGraveyard(*player, player->GetTeam(), player);
1439 }
1440 else
1441 {
1442 float x = player->GetPositionX();
1443 float y = player->GetPositionY();
1444 float z = player->GetPositionZ();
1445 float distNearest = std::numeric_limits<float>::max();
1446
1447 for (auto&& kvp : sObjectMgr->GetWorldSafeLocs())
1448 {
1449 if (kvp.second.Loc.GetMapId() == player->GetMapId())
1450 {
1451 float dist = (kvp.second.Loc.GetPositionX() - x) * (kvp.second.Loc.GetPositionX() - x)
1452 + (kvp.second.Loc.GetPositionY() - y) * (kvp.second.Loc.GetPositionY() - y)
1453 + (kvp.second.Loc.GetPositionZ() - z) * (kvp.second.Loc.GetPositionZ() - z);
1454 if (dist < distNearest)
1455 {
1456 distNearest = dist;
1457 nearestLoc = &kvp.second;
1458 }
1459 }
1460 }
1461 }
1462
1463 if (nearestLoc)
1464 handler->PSendSysMessage(LANG_COMMAND_NEARGRAVEYARD, nearestLoc->ID, nearestLoc->Loc.GetPositionX(), nearestLoc->Loc.GetPositionY(), nearestLoc->Loc.GetPositionZ());
1465 else
1467
1468 return true;
1469 }
1470
1471 static bool HandleDebugInstanceSpawns(ChatHandler* handler, Variant<uint32, EXACT_SEQUENCE("explain")> optArg)
1472 {
1473 Player const* const player = handler->GetPlayer();
1474 if (!player)
1475 return false;
1476
1477 bool explain = false;
1478 uint32 groupID = 0;
1479 if (optArg.holds_alternative<uint32>())
1480 groupID = optArg.get<uint32>();
1481 else
1482 explain = true;
1483
1484 if (groupID && !sObjectMgr->GetSpawnGroupData(groupID))
1485 {
1486 handler->PSendSysMessage("There is no spawn group with ID %u.", groupID);
1487 handler->SetSentErrorMessage(true);
1488 return false;
1489 }
1490
1491 Map const* const map = player->GetMap();
1492 char const* const mapName = map->GetMapName();
1493 InstanceScript const* const instance = player->GetInstanceScript();
1494 if (!instance)
1495 {
1496 handler->PSendSysMessage("%s has no instance script.", mapName);
1497 handler->SetSentErrorMessage(true);
1498 return false;
1499 }
1500 if (!instance->_instanceSpawnGroups || instance->_instanceSpawnGroups->empty())
1501 {
1502 handler->PSendSysMessage("%s's instance script does not manage any spawn groups.", mapName);
1503 handler->SetSentErrorMessage(true);
1504 return false;
1505 }
1506 auto const& spawnGroups = *instance->_instanceSpawnGroups;
1507 std::map<uint32, std::set<std::tuple<bool, uint8, uint8>>> store;
1508 for (InstanceSpawnGroupInfo const& info : spawnGroups)
1509 {
1510 if (groupID && info.SpawnGroupId != groupID)
1511 continue;
1512
1513 bool isSpawn;
1515 isSpawn = false;
1516 else if (info.Flags & InstanceSpawnGroupInfo::FLAG_ACTIVATE_SPAWN)
1517 isSpawn = true;
1518 else
1519 continue;
1520
1521 store[info.SpawnGroupId].emplace(isSpawn, info.BossStateId, info.BossStates);
1522 }
1523
1524 if (groupID && store.find(groupID) == store.end())
1525 {
1526 handler->PSendSysMessage("%s's instance script does not manage group '%s'.", mapName, sObjectMgr->GetSpawnGroupData(groupID)->name.c_str());
1527 handler->SetSentErrorMessage(true);
1528 return false;
1529 }
1530
1531 if (!groupID)
1532 handler->PSendSysMessage("Spawn groups managed by %s (%u):", mapName, map->GetId());
1533
1534 for (auto const& pair : store)
1535 {
1536 SpawnGroupTemplateData const* groupData = sObjectMgr->GetSpawnGroupData(pair.first);
1537 ASSERT(groupData); // checked by objectmgr on load
1538 if (explain)
1539 {
1540 handler->PSendSysMessage(" |-- '%s' (%u)", groupData->name.c_str(), pair.first);
1541 bool isBlocked = false, isSpawned = false;
1542 for (auto const& tuple : pair.second)
1543 {
1544 bool const isSpawn = std::get<0>(tuple);
1545 uint8 const bossStateId = std::get<1>(tuple);
1546 EncounterState const actualState = instance->GetBossState(bossStateId);
1547 if (std::get<2>(tuple) & (1 << actualState))
1548 {
1549 if (isSpawn)
1550 {
1551 isSpawned = true;
1552 if (isBlocked)
1553 handler->PSendSysMessage(" | |-- '%s' would be allowed to spawn by boss state %u being %s, but this is overruled", groupData->name.c_str(), bossStateId, InstanceScript::GetBossStateName(actualState));
1554 else
1555 handler->PSendSysMessage(" | |-- '%s' is allowed to spawn because boss state %u is %s.", groupData->name.c_str(), bossStateId, InstanceScript::GetBossStateName(bossStateId));
1556 }
1557 else
1558 {
1559 isBlocked = true;
1560 handler->PSendSysMessage(" | |-- '%s' is blocked from spawning because boss state %u is %s.", groupData->name.c_str(), bossStateId, InstanceScript::GetBossStateName(bossStateId));
1561 }
1562 }
1563 else
1564 handler->PSendSysMessage(" | |-- '%s' could've been %s if boss state %u matched mask 0x%02x; but it is %s -> 0x%02x, which does not match.",
1565 groupData->name.c_str(), isSpawn ? "allowed to spawn" : "blocked from spawning", bossStateId, std::get<2>(tuple), InstanceScript::GetBossStateName(actualState), (1 << actualState));
1566 }
1567 if (isBlocked)
1568 handler->PSendSysMessage(" | |=> '%s' is not active due to a blocking rule being matched", groupData->name.c_str());
1569 else if (isSpawned)
1570 handler->PSendSysMessage(" | |=> '%s' is active due to a spawn rule being matched", groupData->name.c_str());
1571 else
1572 handler->PSendSysMessage(" | |=> '%s' is not active due to none of its rules being matched", groupData->name.c_str());
1573 }
1574 else
1575 handler->PSendSysMessage(" - '%s' (%u) is %sactive", groupData->name.c_str(), pair.first, map->IsSpawnGroupActive(pair.first) ? "" : "not ");
1576 }
1577 return true;
1578 }
1579
1580 static bool HandleDebugConversationCommand(ChatHandler* handler, uint32 conversationEntry)
1581 {
1582 Player* target = handler->getSelectedPlayerOrSelf();
1583
1584 if (!target)
1585 {
1587 handler->SetSentErrorMessage(true);
1588 return false;
1589 }
1590
1591 return Conversation::CreateConversation(conversationEntry, target, *target, target->GetGUID()) != nullptr;
1592 }
1593
1594 static bool HandleDebugModifierTreeCommand(ChatHandler* handler, uint32 modifierTreeId)
1595 {
1596 Player* target = handler->getSelectedPlayerOrSelf();
1597
1598 if (!target)
1599 {
1601 handler->SetSentErrorMessage(true);
1602 return false;
1603 }
1604
1605 if (target->ModifierTreeSatisfied(modifierTreeId))
1606 handler->PSendSysMessage("ModifierTree %u met", modifierTreeId);
1607 else
1608 handler->PSendSysMessage("ModifierTree %u not met", modifierTreeId);
1609
1610 return true;
1611 }
1612
1613 static bool HandleDebugWSExpressionCommand(ChatHandler* handler, uint32 expressionId)
1614 {
1615 Player* target = handler->getSelectedPlayerOrSelf();
1616
1617 if (!target)
1618 {
1620 handler->SetSentErrorMessage(true);
1621 return false;
1622 }
1623
1624 WorldStateExpressionEntry const* wsExpressionEntry = sWorldStateExpressionStore.LookupEntry(expressionId);
1625 if (!wsExpressionEntry)
1626 return false;
1627
1628 if (ConditionMgr::IsMeetingWorldStateExpression(target->GetMap(), wsExpressionEntry))
1629 handler->PSendSysMessage("WorldStateExpression %u met", expressionId);
1630 else
1631 handler->PSendSysMessage("WorldStateExpression %u not met", expressionId);
1632
1633 return true;
1634 }
1635
1636 static bool HandleDebugPlayerConditionCommand(ChatHandler* handler, uint32 playerConditionId)
1637 {
1638 Player* target = handler->getSelectedPlayerOrSelf();
1639
1640 if (!target)
1641 {
1643 handler->SetSentErrorMessage(true);
1644 return false;
1645 }
1646
1647 if (ConditionMgr::IsPlayerMeetingCondition(target, playerConditionId))
1648 handler->PSendSysMessage("PlayerCondition %u met", playerConditionId);
1649 else
1650 handler->PSendSysMessage("PlayerCondition %u not met", playerConditionId);
1651
1652 return true;
1653 }
1654
1655 static bool HandleDebugOutOfBounds([[maybe_unused]] ChatHandler* handler)
1656 {
1657#ifdef ASAN
1658 uint8 stack_array[10] = {};
1659 int size = 10;
1660
1661 handler->PSendSysMessage("Triggered an array out of bounds read at address %p, value %u", static_cast<void*>(stack_array + size), stack_array[size]);
1662#endif
1663 return true;
1664 }
1665
1666 static bool HandleDebugMemoryLeak([[maybe_unused]] ChatHandler* handler)
1667 {
1668#ifdef ASAN
1669 uint8* leak = new uint8();
1670 handler->PSendSysMessage("Leaked 1 uint8 object at address %p", static_cast<void*>(leak));
1671#endif
1672 return true;
1673 }
1674
1676 {
1677 if (mapId)
1678 {
1679 sMapMgr->DoForAllMapsWithMapId(mapId.value(),
1680 [handler](Map* map) -> void
1681 {
1682 HandleDebugGuidLimitsMap(handler, map);
1683 }
1684 );
1685 }
1686 else
1687 {
1688 sMapMgr->DoForAllMaps(
1689 [handler](Map* map) -> void
1690 {
1691 HandleDebugGuidLimitsMap(handler, map);
1692 }
1693 );
1694 }
1695
1696 handler->PSendSysMessage("Guid Warn Level: %u", sWorld->getIntConfig(CONFIG_RESPAWN_GUIDWARNLEVEL));
1697 handler->PSendSysMessage("Guid Alert Level: %u", sWorld->getIntConfig(CONFIG_RESPAWN_GUIDALERTLEVEL));
1698 return true;
1699 }
1700
1701 static void HandleDebugGuidLimitsMap(ChatHandler* handler, Map* map)
1702 {
1703 handler->PSendSysMessage("Map Id: %u Name: '%s' Instance Id: %u Highest Guid Creature: " UI64FMTD " GameObject: " UI64FMTD,
1705 }
1706
1708 {
1709 if (mapId)
1710 {
1711 sMapMgr->DoForAllMapsWithMapId(mapId.value(),
1712 [handler](Map* map) -> void
1713 {
1714 HandleDebugObjectCountMap(handler, map);
1715 }
1716 );
1717 }
1718 else
1719 {
1720 sMapMgr->DoForAllMaps(
1721 [handler](Map* map) -> void
1722 {
1723 HandleDebugObjectCountMap(handler, map);
1724 }
1725 );
1726 }
1727
1728 return true;
1729 }
1730
1732 {
1733 public:
1734 void Visit(std::unordered_map<ObjectGuid, Creature*> const& creatureMap)
1735 {
1736 for (auto const& [_, creature] : creatureMap)
1737 ++creatureCountsById[creature->GetEntry()];
1738 }
1739
1740 template<class T>
1741 static void Visit(std::unordered_map<ObjectGuid, T*> const&) { }
1742
1743 std::vector<std::pair<uint32, uint32>> GetTopCreatureCount(std::size_t count) const
1744 {
1745 count = std::min(count, creatureCountsById.size());
1746 std::vector<std::pair<uint32, uint32>> result;
1747 if (!count)
1748 return result;
1749
1750 result.reserve(count + 1);
1751
1752 for (auto const& [creatureId, creatureCount] : creatureCountsById)
1753 {
1754 if (result.size() >= count && result.back().second > creatureCount)
1755 continue;
1756
1757 auto where = std::ranges::lower_bound(result, creatureCount, std::ranges::greater(), Trinity::TupleElement<1>);
1758 result.emplace(where, creatureId, creatureCount);
1759 if (result.size() > count)
1760 result.pop_back();
1761 }
1762
1763 return result;
1764 }
1765
1766 private:
1767 std::unordered_map<uint32, uint32> creatureCountsById;
1768 };
1769
1770 static void HandleDebugObjectCountMap(ChatHandler* handler, Map* map)
1771 {
1772 handler->PSendSysMessage("Map Id: %u Name: '%s' Instance Id: %u Creatures: " UI64FMTD " GameObjects: " UI64FMTD " SetActive Objects: " UI64FMTD,
1773 map->GetId(), map->GetMapName(), map->GetInstanceId(),
1777
1778 CreatureCountWorker worker;
1780 visitor.Visit(map->GetObjectsStore());
1781
1782 handler->PSendSysMessage("Top Creatures count:");
1783
1784 for (auto const& [creatureId, count] : worker.GetTopCreatureCount(5))
1785 handler->PSendSysMessage("Entry: %u Count: %u", creatureId, count);
1786 }
1787
1789 {
1790 Creature* selection = handler->getSelectedCreature();
1791 if (!selection)
1792 return false;
1793
1794 Player* player = handler->GetSession()->GetPlayer();
1795 selection->SummonPersonalClone(player->GetPosition(), TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, player);
1796 return true;
1797 }
1798
1800 {
1801 handler->SendSysMessage("This command does nothing right now. Edit your local core (cs_debug.cpp) to make it do whatever you need for testing.");
1802 return true;
1803 }
1804};
1805
1807{
1808 new debug_commandscript();
1809}
#define sBattlefieldMgr
#define sBattlegroundMgr
ChatNotify
Definition Channel.h:40
#define EXACT_SEQUENCE(str)
#define M_PI
Definition Common.h:118
DB2Storage< DifficultyEntry > sDifficultyStore("Difficulty.db2", &DifficultyLoadInfo::Instance)
DB2Storage< MapEntry > sMapStore("Map.db2", &MapLoadInfo::Instance)
DB2Storage< WorldStateExpressionEntry > sWorldStateExpressionStore("WorldStateExpression.db2", &WorldStateExpressionLoadInfo::Instance)
DB2Storage< MovieEntry > sMovieStore("Movie.db2", &MovieLoadInfo::Instance)
DB2Storage< SoundKitEntry > sSoundKitStore("SoundKit.db2", &SoundKitLoadInfo::Instance)
DB2Storage< VehicleEntry > sVehicleStore("Vehicle.db2", &VehicleLoadInfo::Instance)
DB2Storage< CinematicSequencesEntry > sCinematicSequencesStore("CinematicSequences.db2", &CinematicSequencesLoadInfo::Instance)
#define sDB2Manager
Definition DB2Stores.h:569
Difficulty
Definition DBCEnums.h:932
@ DIFFICULTY_NONE
Definition DBCEnums.h:933
#define UI64FMTD
Definition Define.h:138
uint8_t uint8
Definition Define.h:156
int32_t int32
Definition Define.h:150
uint64_t uint64
Definition Define.h:153
uint16_t uint16
Definition Define.h:155
uint32_t uint32
Definition Define.h:154
#define SZFMTD
Definition Define.h:144
std::chrono::seconds Seconds
Seconds shorthand typedef.
Definition Duration.h:28
#define ASSERT
Definition Errors.h:80
#define SIZE_OF_GRIDS
Definition GridDefines.h:40
#define CENTER_GRID_ID
Definition GridDefines.h:41
#define CENTER_GRID_OFFSET
Definition GridDefines.h:43
EncounterState
InventoryResult
Definition ItemDefines.h:25
BuyResult
SellResult
ItemUpdateState
Definition Item.h:45
@ ITEM_CHANGED
Definition Item.h:47
@ ITEM_REMOVED
Definition Item.h:49
@ ITEM_NEW
Definition Item.h:48
@ ITEM_UNCHANGED
Definition Item.h:46
@ LANG_SELECT_CREATURE
Definition Language.h:32
@ LANG_COMMAND_OBJNOTFOUND
Definition Language.h:324
@ LANG_DEBUG_AREATRIGGER_ON
Definition Language.h:980
@ LANG_CINEMATIC_NOT_EXIST
Definition Language.h:978
@ LANG_MOVEFLAGS_GET
Definition Language.h:919
@ LANG_COMMAND_OPCODESENT
Definition Language.h:544
@ LANG_COMMAND_NEARGRAVEYARD
Definition Language.h:114
@ LANG_YOU_HEAR_SOUND
Definition Language.h:198
@ LANG_MOVEFLAGS_SET
Definition Language.h:920
@ LANG_SELECT_CHAR_OR_CREATURE
Definition Language.h:31
@ LANG_MOVIE_NOT_EXIST
Definition Language.h:979
@ LANG_PLAYER_NOT_FOUND
Definition Language.h:570
@ LANG_SOUND_NOT_EXIST
Definition Language.h:212
@ LANG_BAD_VALUE
Definition Language.h:149
@ LANG_COMMAND_NEARGRAVEYARD_NOTFOUND
Definition Language.h:115
@ LANG_DEBUG_AREATRIGGER_OFF
Definition Language.h:981
#define TC_LOG_DEBUG(filterType__, message__,...)
Definition Log.h:181
#define TC_LOG_ERROR(filterType__, message__,...)
Definition Log.h:190
#define TC_LOG_INFO(filterType__, message__,...)
Definition Log.h:184
std::vector< FlyByCamera > const * GetFlyByCameras(uint32 cinematicCameraId)
Definition M2Stores.cpp:266
#define sMapMgr
Definition MapManager.h:186
@ TEMPSUMMON_MANUAL_DESPAWN
@ TYPEID_UNIT
Definition ObjectGuid.h:43
@ TYPEID_PLAYER
Definition ObjectGuid.h:44
#define sObjectMgr
Definition ObjectMgr.h:1885
OpcodeServer
Definition Opcodes.h:1085
std::optional< T > Optional
Optional helper class to wrap optional values within.
Definition Optional.h:25
@ BUYBACK_SLOT_END
Definition Player.h:799
@ BUYBACK_SLOT_START
Definition Player.h:798
#define INVENTORY_SLOT_BAG_0
Definition Player.h:723
@ PLAYER_SLOT_START
Definition Player.h:715
@ PLAYER_SLOT_END
Definition Player.h:717
QuestFailedReason
Definition QuestDef.h:59
QuestPushReason
Definition QuestDef.h:78
Role Based Access Control related classes definition.
#define sScriptMgr
Definition ScriptMgr.h:1449
@ LANG_UNIVERSAL
@ TEAM_NEUTRAL
@ TEAM_ALLIANCE
@ TEAM_HORDE
@ LINEOFSIGHT_CHECK_VMAP
@ LINEOFSIGHT_CHECK_GOBJECT
SpellCastResult
AuraStateType
@ SPELL_SCHOOL_SHADOW
@ SPELL_SCHOOL_NORMAL
@ SPELL_SCHOOL_NATURE
@ SPELL_SCHOOL_FROST
@ SPELL_SCHOOL_ARCANE
@ SPELL_SCHOOL_FIRE
@ SPELL_SCHOOL_HOLY
ChatMsg
@ GO_STATE_READY
#define sSpellMgr
Definition SpellMgr.h:812
TC_COMMON_API bool StringEqualI(std::string_view str1, std::string_view str2)
Definition Util.cpp:849
bool Utf8ToUpperOnlyLatin(std::string &utf8String)
Definition Util.cpp:752
std::string TimeToHumanReadable(time_t t)
Definition Util.cpp:267
Definition Bag.h:27
ObjectGuid const & GetGUID() const
Definition BaseEntity.h:163
TypeID GetTypeId() const
Definition BaseEntity.h:166
static void QueuePlayerForArena(Player const *player, uint8 teamSize, uint8 roles)
void hexlike() const
Player * getSelectedPlayerOrSelf()
Definition Chat.cpp:248
Unit * getSelectedUnit()
Definition Chat.cpp:216
Player * getSelectedPlayer()
Definition Chat.cpp:204
WorldSession * GetSession()
Definition Chat.h:42
virtual LocaleConstant GetSessionDbcLocale() const
Definition Chat.cpp:593
Creature * getSelectedCreature()
Definition Chat.cpp:240
void SetSentErrorMessage(bool val)
Definition Chat.h:127
Player * GetPlayer() const
Definition Chat.cpp:37
void PSendSysMessage(char const *fmt, Args &&... args)
Definition Chat.h:62
virtual void SendSysMessage(std::string_view str, bool escapeCharacters=false)
Definition Chat.cpp:111
GameObject * GetNearbyGameObject()
Definition Chat.cpp:378
bool HasCombat() const
std::unordered_map< ObjectGuid, PvPCombatReference * > const & GetPvPCombatRefs() const
std::unordered_map< ObjectGuid, CombatReference * > const & GetPvECombatRefs() const
static bool IsMeetingWorldStateExpression(Map const *map, WorldStateExpressionEntry const *expression)
static bool IsPlayerMeetingCondition(Player const *player, uint32 conditionId)
static Conversation * CreateConversation(uint32 conversationEntry, Unit *creator, Position const &pos, ObjectGuid privateObjectOwner, SpellInfo const *spellInfo=nullptr, bool autoStart=true)
int32 VisualizeBoundary(Seconds duration, Unit *owner=nullptr, bool fill=false) const
static Creature * CreateCreature(uint32 entry, Map *map, Position const &pos, uint32 vehId=0)
GuidUnorderedSet const & GetTapList() const
Definition Creature.h:304
ObjectGuid::LowType GetSpawnId() const
Definition Creature.h:110
CreatureAI * AI() const
Definition Creature.h:228
static char const * ToConstant(Enum value)
Definition SmartEnum.h:121
GOState GetGoState() const
Definition GameObject.h:284
static char const * GetBossStateName(uint8 state)
EncounterState GetBossState(uint32 id) const
std::vector< InstanceSpawnGroupInfo > const *const _instanceSpawnGroups
Definition Item.h:179
uint8 GetSlot() const
Definition Item.h:290
Bag * GetContainer()
Definition Item.h:291
Bag * ToBag()
Definition Item.h:251
ItemTemplate const * GetTemplate() const
Definition Item.cpp:1233
ItemUpdateState GetState() const
Definition Item.h:333
uint16 GetQueuePos() const
Definition Item.h:336
ObjectGuid GetOwnerGUID() const
Definition Item.h:197
uint8 GetBagSlot() const
Definition Item.cpp:1331
bool IsInUpdateQueue() const
Definition Item.h:335
Definition Map.h:225
MapStoredObjectTypesContainer & GetObjectsStore()
Definition Map.h:458
void LoadGrid(float x, float y)
Definition Map.cpp:372
bool AddToMap(T *)
Definition Map.cpp:517
ObjectGuid::LowType GetMaxLowGuid()
Definition Map.h:565
bool IsSpawnGroupActive(uint32 groupId) const
Definition Map.cpp:2476
uint32 GetId() const
Definition Map.cpp:3257
char const * GetMapName() const
Definition Map.cpp:1844
uint32 GetInstanceId() const
Definition Map.h:350
void LoadAllCells()
Definition Map.cpp:114
size_t GetActiveNonPlayersCount() const
Definition Map.h:581
static ObjectGuid const Empty
Definition ObjectGuid.h:314
bool IsEmpty() const
Definition ObjectGuid.h:362
std::string ToString() const
uint64 LowType
Definition ObjectGuid.h:321
Player * ToPlayer()
Definition Object.h:126
Creature * ToCreature()
Definition Object.h:121
bool AddVisibleMapId(uint32 visibleMapId, TerrainSwapInfo const *visibleMapInfo, int32 references=1)
bool AddUiMapPhaseId(uint32 uiMapPhaseId, int32 references=1)
bool AddPhase(uint32 phaseId, PhaseFlags flags, std::vector< Condition > const *areaConditions, int32 references=1)
static void PrintToChat(ChatHandler *chat, WorldObject const *target)
static void InheritPhaseShift(WorldObject *target, WorldObject const *source)
static void SendToPlayer(Player const *player, PhaseShift const &phaseShift)
void SendMovieStart(uint32 movieId)
Definition Player.cpp:6297
void SendEquipError(InventoryResult msg, Item const *item1=nullptr, Item const *item2=nullptr, uint32 itemId=0) const
Definition Player.cpp:13130
void SendPlayerChoice(ObjectGuid sender, int32 choiceId)
Definition Player.cpp:30184
void SendSellError(SellResult msg, Creature *creature, ObjectGuid guid) const
Definition Player.cpp:13187
WorldSession * GetSession() const
Definition Player.h:2272
Item * GetItemByPos(uint16 pos) const
Definition Player.cpp:9630
bool ModifierTreeSatisfied(uint32 modifierTreeId) const
Definition Player.cpp:27610
void DestroyItem(uint8 bag, uint8 slot, bool update)
Definition Player.cpp:12121
void SendBuyError(BuyResult msg, Creature *creature, uint32 item, uint32 param) const
Definition Player.cpp:13178
void SendCinematicStart(uint32 CinematicSequenceId) const
Definition Player.cpp:6288
void SendCanTakeQuestResponse(QuestFailedReason reason, bool sendErrorMessage=true, std::string reasonText="") const
Definition Player.cpp:17378
std::vector< Item * > & GetItemUpdateQueue()
Definition Player.h:1485
void SendPushToPartyResponse(Player const *player, QuestPushReason reason, Quest const *quest=nullptr) const
Definition Player.cpp:17410
void UpdateObjectVisibility(bool forced=true) override
Definition Player.cpp:24822
Item * GetItemByGuid(ObjectGuid guid) const
Definition Player.cpp:9614
bool isDebugAreaTriggers
Definition Player.h:2865
Team GetTeam() const
Definition Player.h:2423
LocalizedString const * SpellName
Definition SpellInfo.h:409
std::array< float, MAX_SPELL_SCHOOL > _singleSchoolModifiers
auto const & GetThreatenedByMeList() const
bool IsThreatListEmpty(bool includeOffline=false) const
static bool CanHaveThreatList(Unit const *who)
std::unordered_map< uint32, std::unordered_map< ObjectGuid, float > > _redirectRegistry
Trinity::IteratorPair< ThreatListIterator, std::nullptr_t > GetSortedThreatList() const
std::unordered_map< std::underlying_type< SpellSchoolMask >::type, float > _multiSchoolModifiers
Unit * GetFixateTarget() const
std::vector< std::pair< ObjectGuid, float > > _redirectInfo
void EnableMovement(bool enabled)
void Visit(TypeContainer &c)
Definition Unit.h:635
void EnterVehicle(Unit *base, int8 seatId=-1)
Definition Unit.cpp:12749
void SetExtraUnitMovementFlags2(uint32 f)
Definition Unit.h:1748
bool IsVehicle() const
Definition Unit.h:754
uint32 GetUnitMovementFlags() const
Definition Unit.h:1735
ThreatManager & GetThreatManager()
Definition Unit.h:1078
void SetUnitMovementFlags(uint32 f)
Definition Unit.h:1736
bool IsAlive() const
Definition Unit.h:1185
float GetCombatReach() const override
Definition Unit.h:705
void ModifyAuraState(AuraStateType flag, bool apply)
Definition Unit.cpp:6079
bool IsAIEnabled() const
Definition Unit.h:666
Unit * GetVictim() const
Definition Unit.h:726
uint32 GetExtraUnitMovementFlags() const
Definition Unit.h:1741
CombatManager & GetCombatManager()
Definition Unit.h:1038
void SetExtraUnitMovementFlags(uint32 f)
Definition Unit.h:1742
virtual bool IsEngaged() const
Definition Unit.h:1034
ObjectGuid GetTarget() const
Definition Unit.h:1831
bool IsInCombat() const
Definition Unit.h:1058
constexpr uint32 GetMapId() const
Definition Position.h:216
TempSummon * SummonPersonalClone(Position const &pos, TempSummonType despawnType=TEMPSUMMON_MANUAL_DESPAWN, Milliseconds despawnTime=0s, uint32 vehId=0, uint32 spellId=0, Player *privateObjectOwner=nullptr)
Definition Object.cpp:1421
void PlayDirectSound(uint32 soundId, Player const *target=nullptr, uint32 broadcastTextId=0) const
Definition Object.cpp:2938
virtual void SendMessageToSet(WorldPacket const *data, bool self) const
Definition Object.cpp:1094
Map * GetMap() const
Definition Object.h:411
InstanceScript * GetInstanceScript() const
Definition Object.cpp:396
void GetClosePoint(float &x, float &y, float &z, float size, float distance2d=0, float relAngle=0) const
Definition Object.cpp:2749
void PlayDirectMusic(uint32 musicId, Player const *target=nullptr) const
Definition Object.cpp:2946
TempSummon * SummonCreature(uint32 entry, Position const &pos, TempSummonType despawnType=TEMPSUMMON_MANUAL_DESPAWN, Milliseconds despawnTime=0s, uint32 vehId=0, uint32 spellId=0, ObjectGuid privateObjectOwner=ObjectGuid::Empty)
Definition Object.cpp:1398
Unit * GetOwner() const
Definition Object.cpp:1598
TransportBase * GetTransport() const
Definition Object.h:537
void PlayDistanceSound(uint32 soundId, Player const *target=nullptr) const
Definition Object.cpp:2922
std::string const & GetName() const
Definition Object.h:342
bool IsWithinLOSInMap(WorldObject const *obj, LineOfSightChecks checks=LINEOFSIGHT_ALL_CHECKS, VMAP::ModelIgnoreFlags ignoreFlags=VMAP::ModelIgnoreFlags::Nothing) const
Definition Object.cpp:535
void DestroyForNearbyPlayers()
Definition Object.cpp:3037
uint32 GetZoneId() const
Definition Object.h:332
MovementInfo m_movementInfo
Definition Object.h:548
void PlayObjectSound(int32 soundKitId, ObjectGuid targetObject, Player const *target=nullptr, int32 broadcastTextId=0) const
Definition Object.cpp:2954
int32 GetDBPhase() const
Definition Object.h:327
uint32 GetOpcode() const
Definition WorldPacket.h:83
std::string _Channel
Channel Name.
WorldPacket const * Write() override
void Initialize(ChatMsg chatType, Language language, WorldObject const *sender, WorldObject const *receiver, std::string_view message, uint32 achievementId=0, std::string_view channelName="", LocaleConstant locale=DEFAULT_LOCALE, std::string_view addonPrefix="")
WorldPacket const * Write() override
WorldPacket const * Write() override
WorldPacket const * Write() override
Player * GetPlayer() const
void SendPacket(WorldPacket const *packet, bool forced=false)
Send a packet to the client.
static PersistentWorldVariable const NextMonthlyQuestResetTimeVarId
Definition World.h:127
static PersistentWorldVariable const NextDailyQuestResetTimeVarId
Definition World.h:128
static PersistentWorldVariable const NextWeeklyQuestResetTimeVarId
Definition World.h:123
static void Visit(std::unordered_map< ObjectGuid, T * > const &)
std::vector< std::pair< uint32, uint32 > > GetTopCreatureCount(std::size_t count) const
std::unordered_map< uint32, uint32 > creatureCountsById
void Visit(std::unordered_map< ObjectGuid, Creature * > const &creatureMap)
static bool HandleDebugThreatListCommand(ChatHandler *handler)
Definition cs_debug.cpp:877
static bool HandleDebugGetItemStateCommand(ChatHandler *handler, std::string itemState)
Definition cs_debug.cpp:588
static bool HandleDebugSendLargePacketCommand(ChatHandler *handler)
std::span< ChatCommandBuilder const > GetCommands() const override
Definition cs_debug.cpp:71
static void HandleDebugGuidLimitsMap(ChatHandler *handler, Map *map)
static bool HandleDebugPlayerConditionCommand(ChatHandler *handler, uint32 playerConditionId)
static bool HandleDebugModifierTreeCommand(ChatHandler *handler, uint32 modifierTreeId)
static bool HandleDebugRaidResetCommand(ChatHandler *handler, uint32 mapId, Optional< uint32 > difficulty)
static bool HandleDebugSendChatMsgCommand(ChatHandler *handler, ChatMsg type)
Definition cs_debug.cpp:550
static bool HandleDebugLoadCellsCommandHelper(ChatHandler *handler, Map *map, Optional< uint32 > tileX, Optional< uint32 > tileY)
static bool HandleDebugAreaTriggersCommand(ChatHandler *handler)
Definition cs_debug.cpp:524
static bool HandleDebugSendSellErrorCommand(ChatHandler *handler, SellResult error)
Definition cs_debug.cpp:321
static bool HandleDebugSendSpellFailCommand(ChatHandler *handler, SpellCastResult result, Optional< int32 > failArg1, Optional< int32 > failArg2)
Definition cs_debug.cpp:295
static bool HandleDebugTransportCommand(ChatHandler *handler, std::string operation)
static bool HandleDebugGetLootRecipientCommand(ChatHandler *handler)
Definition cs_debug.cpp:564
static bool HandleDebugLoSCommand(ChatHandler *handler)
static bool HandleDebugPlayMovieCommand(ChatHandler *handler, uint32 movieId)
Definition cs_debug.cpp:217
static bool HandleWPGPSCommand(ChatHandler *handler)
static bool HandleDebugOutOfBounds(ChatHandler *handler)
static bool HandleDebugSendOpcodeCommand(ChatHandler *handler)
Definition cs_debug.cpp:333
static bool HandleDebugDummyCommand(ChatHandler *handler)
static bool HandleDebugSendEquipErrorCommand(ChatHandler *handler, InventoryResult error)
Definition cs_debug.cpp:315
static bool HandleDebugThreatInfoCommand(ChatHandler *handler)
Definition cs_debug.cpp:962
static bool HandleDebugSpawnVehicleCommand(ChatHandler *handler, uint32 entry, Optional< uint32 > id)
static bool HandleDebugPlayMusicCommand(ChatHandler *handler, uint32 musicId)
Definition cs_debug.cpp:261
static bool HandleDebugWSExpressionCommand(ChatHandler *handler, uint32 expressionId)
static bool HandleDebugBattlegroundCommand(ChatHandler *)
Definition cs_debug.cpp:854
static bool HandleDebugSendBuyErrorCommand(ChatHandler *handler, BuyResult error)
Definition cs_debug.cpp:327
static bool TryExtractTeamId(std::string const &args, TeamId &outFaction)
Definition cs_debug.cpp:144
static bool HandleDebugPhaseCommand(ChatHandler *handler)
static bool HandleDebugWarModeBalanceCommand(ChatHandler *handler, Variant< uint32, EXACT_SEQUENCE("alliance"), EXACT_SEQUENCE("horde"), EXACT_SEQUENCE("neutral"), EXACT_SEQUENCE("off")> command, Optional< int32 > rewardValue)
Definition cs_debug.cpp:158
static bool HandleDebugObjectCountCommand(ChatHandler *handler, Optional< uint32 > mapId)
static bool HandleDebugSendChannelNotifyCommand(ChatHandler *handler, ChatNotify type)
Definition cs_debug.cpp:541
static bool HandleDebugSendQuestPartyMsgCommand(ChatHandler *handler, QuestPushReason msg)
Definition cs_debug.cpp:558
static bool HandleDebugGuidLimitsCommand(ChatHandler *handler, Optional< uint32 > mapId)
static bool HandleDebugCombatListCommand(ChatHandler *handler)
static bool HandleDebugLoadCellsCommand(ChatHandler *handler, Optional< uint32 > mapId, Optional< uint32 > tileX, Optional< uint32 > tileY)
static bool HandleDebugEnterVehicleCommand(ChatHandler *handler, uint32 entry, Optional< int8 > seatId)
static bool HandleDebugSendPlayerChoiceCommand(ChatHandler *handler, int32 choiceId)
Definition cs_debug.cpp:308
static bool HandleDebugMemoryLeak(ChatHandler *handler)
static bool HandleDebugItemExpireCommand(ChatHandler *handler, ObjectGuid::LowType guid)
static bool HandleDebugSendQuestInvalidMsgCommand(ChatHandler *handler, QuestFailedReason msg)
Definition cs_debug.cpp:582
static bool HandleDebugQuestResetCommand(ChatHandler *handler, std::string arg)
static bool HandleDebugPlayCinematicCommand(ChatHandler *handler, uint32 cinematicId)
Definition cs_debug.cpp:189
static bool HandleDebugPlayObjectSoundCommand(ChatHandler *handler, int32 soundKitId, Optional< int32 > broadcastTextId)
Definition cs_debug.cpp:278
static void HandleDebugObjectCountMap(ChatHandler *handler, Map *map)
static bool HandleDebugInstanceSpawns(ChatHandler *handler, Variant< uint32, EXACT_SEQUENCE("explain")> optArg)
static bool HandleDebugNearGraveyard(ChatHandler *handler, Optional< EXACT_SEQUENCE("linked")> linked)
static bool HandleDebugMoveflagsCommand(ChatHandler *handler, Optional< uint32 > moveFlags, Optional< uint32 > moveFlagsExtra, Optional< uint32 > moveFlagsExtra2)
static bool HandleDebugConversationCommand(ChatHandler *handler, uint32 conversationEntry)
static bool HandleDebugAnimCommand(ChatHandler *handler, Emote emote)
static bool HandleDebugBecomePersonalClone(ChatHandler *handler)
static bool HandleDebugSendSetPhaseShiftCommand(ChatHandler *handler, Optional< uint32 > phaseId, Optional< uint32 > visibleMapId, Optional< uint32 > uiMapPhaseId)
static bool HandleDebugUpdateWorldStateCommand(ChatHandler const *handler, int32 variable, int32 value)
Definition cs_debug.cpp:518
static bool HandleDebugArenaCommand(ChatHandler *handler, uint32 battlemasterListId)
Definition cs_debug.cpp:860
static bool HandleDebugBoundaryCommand(ChatHandler *handler, Optional< EXACT_SEQUENCE("fill")> fill, Optional< uint32 > durationArg)
static bool HandleDebugSetAuraStateCommand(ChatHandler *handler, Optional< AuraStateType > state, bool apply)
static bool HandleDebugPlaySoundCommand(ChatHandler *handler, uint32 soundId, Optional< uint32 > broadcastTextId)
Definition cs_debug.cpp:232
void AddSC_debug_commandscript()
#define sWorld
Definition World.h:916
@ CONFIG_RESPAWN_GUIDALERTLEVEL
Definition World.h:421
@ CONFIG_RESPAWN_GUIDWARNLEVEL
Definition World.h:420
TC_GAME_API Unit * GetUnit(WorldObject const &, ObjectGuid const &guid)
TC_GAME_API Player * GetPlayer(Map const *, ObjectGuid const &guid)
ChatCommandBuilder const [] ChatCommandTable
Definition ChatCommand.h:49
TC_GAME_API void SetValue(int32 worldStateId, int32 value, bool hidden, Map *map)
@ PLAYER_ROLE_DAMAGE
Definition LFG.h:43
@ RBAC_PERM_COMMAND_DEBUG
Definition RBAC.h:214
static void VisitAllObjects(WorldObject const *obj, T &visitor, float radius, bool dont_load=true)
Definition CellImpl.h:203
std::array< uint16, 8 > Camera
LocalizedString MapName
bool IsDungeon() const
constexpr float GetPositionX() const
Definition Position.h:87
constexpr float GetPositionY() const
Definition Position.h:88
std::string ToString() const
Definition Position.cpp:202
constexpr void GetPosition(float &x, float &y) const
Definition Position.h:92
constexpr float GetOrientation() const
Definition Position.h:90
constexpr float GetPositionZ() const
Definition Position.h:89
std::size_t Size() const
WorldLocation Loc
Definition ObjectMgr.h:836