Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
CharacterHandler.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 "AccountMgr.h"
7#include "ArenaTeam.h"
8#include "ArenaTeamMgr.h"
9#include "Battleground.h"
10#include "CalendarMgr.h"
11#include "CharacterBoost.h"
12#include "Chat.h"
13#include "Common.h"
14#include "Creature.h"
15#include "DatabaseEnv.h"
16#include "DBCStores.h"
17#include "Group.h"
18#include "Guild.h"
19#include "GuildMgr.h"
20#include "Language.h"
21#include "LFGMgr.h"
22#include "Log.h"
23#include "Map.h"
24#include "ObjectAccessor.h"
25#include "ObjectMgr.h"
26#include "Opcodes.h"
27#include "Pet.h"
28#include "Player.h"
29#include "PlayerDump.h"
30#include "RBAC.h"
31#include "ReputationMgr.h"
32#include "ScriptMgr.h"
33#include "SharedDefines.h"
34#include "SocialMgr.h"
35#include "SpellInfo.h"
36#include "SpellMgr.h"
37#include "SystemConfig.h"
38#include "UpdateMask.h"
39#include "Util.h"
40#include "World.h"
41#include "WorldPacket.h"
42#include "WorldSession.h"
43
45{
46private:
49public:
51 : m_accountId(accountId), m_guid(guid) { }
52 uint64 GetGuid() const { return m_guid; }
53 uint32 GetAccountId() const { return m_accountId; }
54 bool Initialize();
55};
56
58{
60
61 bool res = true;
62 uint32 lowGuid = GUID_LOPART(m_guid);
63
64 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER);
65 stmt->setUInt32(0, lowGuid);
67
68 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GROUP_MEMBER);
69 stmt->setUInt32(0, lowGuid);
71
72 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_INSTANCE);
73 stmt->setUInt32(0, lowGuid);
75
76 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_AURAS);
77 stmt->setUInt32(0, lowGuid);
79
80 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_SPELL);
81 stmt->setUInt32(0, lowGuid);
83
84 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_QUESTSTATUS);
85 stmt->setUInt32(0, lowGuid);
87
89 stmt->setUInt32(0, lowGuid);
91
92 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_DAILYQUESTSTATUS);
93 stmt->setUInt32(0, lowGuid);
95
97 stmt->setUInt32(0, lowGuid);
99
100 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_MONTHLYQUESTSTATUS);
101 stmt->setUInt32(0, lowGuid);
103
105 stmt->setUInt32(0, lowGuid);
107
108 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_REPUTATION);
109 stmt->setUInt32(0, lowGuid);
111
112 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_INVENTORY);
113 stmt->setUInt32(0, lowGuid);
115
116 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_VOID_STORAGE);
117 stmt->setUInt32(0, lowGuid);
119
120 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_ACTIONS);
121 stmt->setUInt32(0, lowGuid);
123
124 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_MAILCOUNT);
125 stmt->setUInt32(0, lowGuid);
126 stmt->setUInt64(1, uint64(time(NULL)));
128
129 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_MAILDATE);
130 stmt->setUInt32(0, lowGuid);
132
133 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_SOCIALLIST);
134 stmt->setUInt32(0, lowGuid);
136
137 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_HOMEBIND);
138 stmt->setUInt32(0, lowGuid);
140
141 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_SPELLCOOLDOWNS);
142 stmt->setUInt32(0, lowGuid);
144
146 {
147 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_DECLINEDNAMES);
148 stmt->setUInt32(0, lowGuid);
150 }
151
152 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUILD_MEMBER);
153 stmt->setUInt32(0, lowGuid);
155
156 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_ACHIEVEMENTS);
157 stmt->setUInt32(0, lowGuid);
159
160 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_CRITERIAPROGRESS);
161 stmt->setUInt32(0, lowGuid);
163
164 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_EQUIPMENTSETS);
165 stmt->setUInt32(0, lowGuid);
167
168 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_CUF_PROFILES);
169 stmt->setUInt32(0, lowGuid);
171
172 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_BGDATA);
173 stmt->setUInt32(0, lowGuid);
175
176 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_GLYPHS);
177 stmt->setUInt32(0, lowGuid);
179
180 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_TALENTS);
181 stmt->setUInt32(0, lowGuid);
183
184 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PLAYER_ACCOUNT_DATA);
185 stmt->setUInt32(0, lowGuid);
187
188 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_SKILLS);
189 stmt->setUInt32(0, lowGuid);
191
192 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_RANDOMBG);
193 stmt->setUInt32(0, lowGuid);
195
196 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_BANNED);
197 stmt->setUInt32(0, lowGuid);
199
200 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_QUESTSTATUSREW);
201 stmt->setUInt32(0, lowGuid);
203
204 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_ACCOUNT_INSTANCELOCKTIMES);
205 stmt->setUInt32(0, m_accountId);
207
208 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PLAYER_CURRENCY);
209 stmt->setUInt32(0, lowGuid);
211
212 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_ACCOUNT_BATTLE_PETS);
213 stmt->setUInt32(0, m_accountId);
215
216 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_ACCOUNT_BATTLE_PET_SLOTS);
217 stmt->setUInt32(0, m_accountId);
219
220 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_RESEARCH_DIGSITES);
221 stmt->setUInt32(0, lowGuid);
223
224 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_RESEARCH_HISTORY);
225 stmt->setUInt32(0, lowGuid);
227
228 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_RESEARCH_PROJECTS);
229 stmt->setUInt32(0, lowGuid);
231
232 return res;
233}
234
235namespace
236{
237 struct StarterHunterPetTemplate
238 {
240 uint32 CreatedBySpell;
241 };
242
243 bool GetStarterHunterPetTemplate(PlayerInfo const* info, StarterHunterPetTemplate& starterPet)
244 {
245 if (!info)
246 return false;
247
248 for (uint32 spellId : info->spell_cast)
249 {
250 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
251 if (!spellInfo)
252 continue;
253
254 for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
255 {
256 SpellEffectInfo const& effect = spellInfo->Effects[effIndex];
257 if (effect.Effect != SPELL_EFFECT_CREATE_TAMED_PET || effect.MiscValue <= 0)
258 continue;
259
260 starterPet.CreatureEntry = uint32(effect.MiscValue);
261 starterPet.CreatedBySpell = spellId;
262 return true;
263 }
264 }
265
266 return false;
267 }
268
269 char const* GetDefaultPetActionBarData()
270 {
271 return "7 2 7 1 7 4 1 0 1 0 1 0 1 0 6 2 6 3 6 0";
272 }
273
274 bool SeedStarterHunterPetRecord(Player* player, PlayerInfo const* info)
275 {
276 if (!player || player->getClass() != CLASS_HUNTER)
277 return false;
278
279 StarterHunterPetTemplate starterPet = { };
280 if (!GetStarterHunterPetTemplate(info, starterPet))
281 return false;
282
283 CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(starterPet.CreatureEntry);
284 if (!creatureInfo || !creatureInfo->IsTameable(player->CanTameExoticPets()))
285 return false;
286
287 uint32 displayId = creatureInfo->GetFirstValidModelId();
288 if (!displayId)
289 return false;
290
291 std::string petName;
292 if (CreatureFamilyEntry const* family = sCreatureFamilyStore.LookupEntry(creatureInfo->family))
293 {
294 if (family->Name)
295 petName = family->Name;
296 }
297
298 if (petName.empty())
299 {
300 petName = creatureInfo->Name;
301 }
302
303 if (petName.size() > 21)
304 petName.resize(21);
305
306 CharacterDatabase.EscapeString(petName);
307
308 uint32 const petNumber = sObjectMgr->GeneratePetNumber();
309 std::ostringstream ss;
310 ss << "INSERT INTO character_pet "
311 << "(id, entry, owner, modelid, CreatedBySpell, PetType, level, exp, Reactstate, name, renamed, active, slot, curhealth, curmana, savetime, abdata, PetSpecId) VALUES ("
312 << petNumber << ','
313 << starterPet.CreatureEntry << ','
314 << player->GetGUIDLow() << ','
315 << displayId << ','
316 << starterPet.CreatedBySpell << ','
317 << static_cast<uint32>(PetType::HUNTER_PET) << ','
318 << uint32(player->getLevel()) << ','
319 << "0,"
320 << uint32(REACT_DEFENSIVE) << ",'"
321 << petName << "',"
322 << "0,"
323 << "1,"
324 << uint32(PET_SAVE_AS_CURRENT) << ','
325 << "4294967295,"
326 << "0,"
327 << uint32(time(NULL)) << ",'"
328 << GetDefaultPetActionBarData() << "',"
329 << "0)";
330
331 std::string sql = ss.str();
332 CharacterDatabase.DirectExecute(sql.c_str());
333
334 SF_LOG_INFO("entities.pet", "Seeded starter hunter pet entry %u for player %s (GUID: %u) from spell %u.",
335 starterPet.CreatureEntry, player->GetName().c_str(), player->GetGUIDLow(), starterPet.CreatedBySpell);
336 return true;
337 }
338
339 bool CreateStarterHunterPet(Player* player, PlayerInfo const* info)
340 {
341 if (!player || !info || player->getClass() != CLASS_HUNTER || player->GetPet())
342 return false;
343
344 StarterHunterPetTemplate starterPet = { };
345 if (!GetStarterHunterPetTemplate(info, starterPet))
346 return false;
347
348 Pet* pet = player->CreateTamedPetFrom(starterPet.CreatureEntry, starterPet.CreatedBySpell);
349 if (!pet)
350 return false;
351
352 float x, y, z;
353 player->GetClosePoint(x, y, z, pet->GetObjectSize(), PET_FOLLOW_DIST, pet->GetFollowAngle());
354 pet->Relocate(x, y, z, player->GetOrientation());
355
356 if (!pet->IsPositionValid())
357 {
358 delete pet;
359 return false;
360 }
361
362 pet->GetMap()->AddToMap(pet->ToCreature());
363 player->SetMinion(pet, true);
364 pet->InitTalentForLevel();
366 player->PetSpellInitialize();
367
368 SF_LOG_INFO("entities.pet", "Created starter hunter pet entry %u for player %s (GUID: %u) from spell %u.",
369 pet->GetEntry(), player->GetName().c_str(), player->GetGUIDLow(), starterPet.CreatedBySpell);
370 return true;
371 }
372}
373
374namespace
375{
376struct CharacterGuidRequest
377{
378 ObjectGuid guid;
379};
380
381struct PlayerLoginRequest
382{
383 ObjectGuid guid;
384 float unk;
385};
386
387struct LoadScreenRequest
388{
389 uint32 mapId;
390 bool unk;
391};
392
393struct UInt32Request
394{
395 uint32 value;
396};
397
398struct UInt8Request
399{
400 uint8 value;
401};
402
403struct FactionInactiveRequest
404{
405 uint32 factionIndex;
406 uint8 status;
407};
408
409struct CharacterRenameRequest
410{
411 ObjectGuid guid;
412 std::string newName;
413};
414
415struct DeclinedNamesRequest
416{
417 ObjectGuid guid;
418 DeclinedName declinedName;
419};
420
421struct AlterAppearanceRequest
422{
423 uint32 hair;
424 uint32 color;
425 uint32 facialHair;
426 uint32 skinColor;
427};
428
429struct CharacterCustomizeRequest
430{
431 ObjectGuid guid;
432 std::string newName;
433 uint8 gender;
434 uint8 skin;
435 uint8 face;
436 uint8 hairStyle;
437 uint8 hairColor;
438 uint8 facialHair;
439};
440
441struct RandomizeCharNameRequest
442{
443 uint8 gender;
444 uint8 race;
445};
446
447struct EquipmentSetSaveIndexRequest
448{
449 uint32 index;
450};
451
452struct EquipmentSetSaveHeaderRequest
453{
454 ObjectGuid setGuid;
455 ObjectGuid itemGuid[EQUIPMENT_SLOT_END];
456 uint8 iconNameLen;
457 uint8 setNameLen;
458};
459
460struct EquipmentSetSaveTailRequest
461{
462 ObjectGuid setGuid;
463 std::string iconName;
464 std::string name;
465};
466
467struct EquipmentSetUseRequest
468{
470 uint8 srcslot[EQUIPMENT_SLOT_END];
471 ObjectGuid itemGuid[EQUIPMENT_SLOT_END];
472 uint8 inventoryItemCounter;
473};
474
475struct CharFactionOrRaceChangeRequest
476{
477 ObjectGuid guid;
478 std::string newName;
479 uint8 gender;
480 uint8 skin;
481 uint8 face;
482 uint8 hairStyle;
483 uint8 hairColor;
484 uint8 facialHair;
485 uint8 race;
486 bool isFactionChange;
487};
488
489struct ReorderCharacterEntry
490{
491 ObjectGuid guid;
492 uint8 position;
493};
494
495struct ReorderCharactersRequest
496{
497 std::vector<ReorderCharacterEntry> characters;
498};
499
500CharacterGuidRequest ReadCharacterDeleteRequest(WorldPacket& recvData)
501{
502 CharacterGuidRequest request;
503 recvData.ReadGuidMask(request.guid, 1, 3, 2, 7, 4, 6, 0, 5);
504 recvData.ReadGuidBytes(request.guid, 7, 1, 6, 0, 3, 4, 2, 5);
505 return request;
506}
507
508PlayerLoginRequest ReadPlayerLoginRequest(WorldPacket& recvData)
509{
510 PlayerLoginRequest request;
511 recvData >> request.unk;
512 recvData.ReadGuidMask(request.guid, 1, 4, 7, 3, 2, 6, 5, 0);
513 recvData.ReadGuidBytes(request.guid, 5, 1, 0, 6, 2, 4, 7, 3);
514 return request;
515}
516
517LoadScreenRequest ReadLoadScreenRequest(WorldPacket& recvPacket)
518{
519 LoadScreenRequest request;
520 recvPacket >> request.mapId;
521 request.unk = recvPacket.ReadBit();
522 return request;
523}
524
525UInt32Request ReadUInt32Request(WorldPacket& recvData)
526{
527 UInt32Request request;
528 recvData >> request.value;
529 return request;
530}
531
532UInt8Request ReadUInt8Request(WorldPacket& recvData)
533{
534 UInt8Request request;
535 recvData >> request.value;
536 return request;
537}
538
539FactionInactiveRequest ReadFactionInactiveRequest(WorldPacket& recvData)
540{
541 FactionInactiveRequest request;
542 recvData >> request.factionIndex >> request.status;
543 return request;
544}
545
546void ReadToggleDisplayRequest(WorldPacket& recvData)
547{
548 recvData.read_skip<uint8>(); // unknown, bool?
549}
550
551CharacterRenameRequest ReadCharacterRenameRequest(WorldPacket& recvData)
552{
553 CharacterRenameRequest request;
554 recvData.ReadGuidMask(request.guid, 6, 3, 0);
555 uint32 nameLen = recvData.ReadBits(6); // Name size
556 recvData.ReadGuidMask(request.guid, 1, 5, 7, 2, 4);
557 recvData.ReadGuidBytes(request.guid, 1, 6, 5);
558 request.newName = recvData.ReadString(nameLen); // New Name
559 recvData.ReadGuidBytes(request.guid, 2, 4, 3, 7, 0);
560 return request;
561}
562
563DeclinedNamesRequest ReadDeclinedNamesRequest(WorldPacket& recvData)
564{
565 DeclinedNamesRequest request;
566
567 recvData.ReadGuidMask(request.guid, 0, 2, 1, 7, 5, 6, 4, 3);
568 for (uint32 i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
569 request.declinedName.nameLength[i] = recvData.ReadBits(7);
570
571 recvData.FlushBits();
572
573 for (uint32 i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
574 request.declinedName.name[i] = recvData.ReadString(request.declinedName.nameLength[i]);
575
576 recvData.ReadGuidBytes(request.guid, 0, 7, 3, 6, 4, 2, 1, 5);
577 return request;
578}
579
580AlterAppearanceRequest ReadAlterAppearanceRequest(WorldPacket& recvData)
581{
582 AlterAppearanceRequest request;
583 recvData >> request.skinColor >> request.color >> request.hair >> request.facialHair;
584 return request;
585}
586
587CharacterCustomizeRequest ReadCharacterCustomizeRequest(WorldPacket& recvData)
588{
589 CharacterCustomizeRequest request;
590 recvData >> request.hairStyle >> request.gender >> request.skin >> request.face >> request.hairColor >> request.facialHair;
591
592 recvData.ReadGuidMask(request.guid, 2, 6, 1, 0, 7, 5);
593 uint32 nameLen = recvData.ReadBits(6); // Name size
594 recvData.ReadGuidMask(request.guid, 4, 3);
595 recvData.ReadGuidBytes(request.guid, 4);
596 request.newName = recvData.ReadString(nameLen); // New Name
597 recvData.ReadGuidBytes(request.guid, 0, 2, 6, 5, 3, 1, 7);
598
599 return request;
600}
601
602CharacterGuidRequest ReadEquipmentSetDeleteRequest(WorldPacket& recvData)
603{
604 CharacterGuidRequest request;
605
606 request.guid[4] = recvData.ReadBit();
607 request.guid[2] = recvData.ReadBit();
608 request.guid[6] = recvData.ReadBit();
609 request.guid[0] = recvData.ReadBit();
610 request.guid[5] = recvData.ReadBit();
611 request.guid[1] = recvData.ReadBit();
612 request.guid[7] = recvData.ReadBit();
613 request.guid[3] = recvData.ReadBit();
614
615 recvData.ReadByteSeq(request.guid[2]);
616 recvData.ReadByteSeq(request.guid[0]);
617 recvData.ReadByteSeq(request.guid[1]);
618 recvData.ReadByteSeq(request.guid[6]);
619 recvData.ReadByteSeq(request.guid[3]);
620 recvData.ReadByteSeq(request.guid[4]);
621 recvData.ReadByteSeq(request.guid[5]);
622 recvData.ReadByteSeq(request.guid[7]);
623
624 return request;
625}
626
627RandomizeCharNameRequest ReadRandomizeCharNameRequest(WorldPacket& recvData)
628{
629 RandomizeCharNameRequest request;
630 recvData >> request.gender;
631 recvData >> request.race;
632 return request;
633}
634
635EquipmentSetSaveIndexRequest ReadEquipmentSetSaveIndexRequest(WorldPacket& recvData)
636{
637 EquipmentSetSaveIndexRequest request;
638 recvData >> request.index;
639 return request;
640}
641
642EquipmentSetSaveHeaderRequest ReadEquipmentSetSaveHeaderRequest(WorldPacket& recvData)
643{
644 EquipmentSetSaveHeaderRequest request;
645
646 for (uint32 i = 0; i < EQUIPMENT_SLOT_END; ++i)
647 {
648 request.itemGuid[i][5] = recvData.ReadBit();
649 request.itemGuid[i][0] = recvData.ReadBit();
650 request.itemGuid[i][1] = recvData.ReadBit();
651 request.itemGuid[i][4] = recvData.ReadBit();
652 request.itemGuid[i][6] = recvData.ReadBit();
653 request.itemGuid[i][3] = recvData.ReadBit();
654 request.itemGuid[i][7] = recvData.ReadBit();
655 request.itemGuid[i][2] = recvData.ReadBit();
656 }
657
658 request.setGuid[7] = recvData.ReadBit();
659 request.setGuid[1] = recvData.ReadBit();
660 request.setGuid[5] = recvData.ReadBit();
661 request.setGuid[2] = recvData.ReadBit();
662 request.setGuid[3] = recvData.ReadBit();
663 request.setGuid[0] = recvData.ReadBit();
664
665 request.setNameLen = recvData.ReadBits(8);
666 request.setGuid[6] = recvData.ReadBit();
667 request.iconNameLen = recvData.ReadBits(8);
668
669 request.setGuid[4] = recvData.ReadBit();
670
671 bool pair = recvData.ReadBit();
672 if (pair)
673 request.iconNameLen++;
674
675 recvData.ReadByteSeq(request.setGuid[4]);
676 recvData.ReadByteSeq(request.setGuid[0]);
677
678 return request;
679}
680
681void ReadEquipmentSetSaveItemGuidBytes(WorldPacket& recvData, ObjectGuid& itemGuid)
682{
683 recvData.ReadByteSeq(itemGuid[1]);
684 recvData.ReadByteSeq(itemGuid[0]);
685 recvData.ReadByteSeq(itemGuid[7]);
686 recvData.ReadByteSeq(itemGuid[3]);
687 recvData.ReadByteSeq(itemGuid[6]);
688 recvData.ReadByteSeq(itemGuid[2]);
689 recvData.ReadByteSeq(itemGuid[4]);
690 recvData.ReadByteSeq(itemGuid[5]);
691}
692
693EquipmentSetSaveTailRequest ReadEquipmentSetSaveTailRequest(WorldPacket& recvData, EquipmentSetSaveHeaderRequest const& header)
694{
695 EquipmentSetSaveTailRequest request;
696 request.setGuid = header.setGuid;
697 request.iconName = recvData.ReadString(header.iconNameLen);
698
699 recvData.ReadByteSeq(request.setGuid[7]);
700 recvData.ReadByteSeq(request.setGuid[2]);
701
702 request.name = recvData.ReadString(header.setNameLen);
703
704 recvData.ReadByteSeq(request.setGuid[6]);
705 recvData.ReadByteSeq(request.setGuid[1]);
706 recvData.ReadByteSeq(request.setGuid[5]);
707 recvData.ReadByteSeq(request.setGuid[3]);
708
709 return request;
710}
711
712EquipmentSetUseRequest ReadEquipmentSetUseRequest(WorldPacket& recvData)
713{
714 EquipmentSetUseRequest request;
715
716 for (uint8 i = 0; i < EQUIPMENT_SLOT_END; ++i)
717 recvData >> request.srcslot[i] >> request.srcbag[i];
718
719 for (uint32 i = 0; i < EQUIPMENT_SLOT_END; ++i)
720 recvData.ReadGuidMask(request.itemGuid[i], 3, 1, 7, 4, 5, 6, 0, 2);
721
722 request.inventoryItemCounter = recvData.ReadBits(2);
723
724 for (uint8 i = 0; i < request.inventoryItemCounter; i++)
725 {
726 recvData.ReadBit(); // Container Slot
727 recvData.ReadBit(); // Slot
728 }
729
730 return request;
731}
732
733void ReadEquipmentSetUseItemGuidBytes(WorldPacket& recvData, ObjectGuid& itemGuid)
734{
735 recvData.ReadGuidBytes(itemGuid, 4, 7, 0, 3, 2, 5, 1, 6);
736}
737
738CharFactionOrRaceChangeRequest ReadCharFactionOrRaceChangeRequest(WorldPacket& recvData)
739{
740 CharFactionOrRaceChangeRequest request;
741 request.skin = 0;
742 request.face = 0;
743 request.hairStyle = 0;
744 request.hairColor = 0;
745 request.facialHair = 0;
746
747 recvData >> request.gender;
748 recvData >> request.race;
749 request.guid[3] = recvData.ReadBit();
750 request.guid[2] = recvData.ReadBit();
751 bool hasSkinColor = recvData.ReadBit();
752 bool hasFace = recvData.ReadBit();
753 request.guid[6] = recvData.ReadBit();
754 uint32 nameLength = recvData.ReadBits(6);
755 bool hasFacialHair = recvData.ReadBit();
756 bool hasHairStyle = recvData.ReadBit();
757 request.guid[4] = recvData.ReadBit();
758 request.guid[1] = recvData.ReadBit();
759 request.guid[0] = recvData.ReadBit();
760 request.guid[5] = recvData.ReadBit();
761 bool hasHairColor = recvData.ReadBit();
762 request.isFactionChange = recvData.ReadBit();
763 request.guid[7] = recvData.ReadBit();
764
765 recvData.ReadGuidBytes(request.guid, 2, 1, 4, 5, 0);
766 request.newName = recvData.ReadString(nameLength);
767 recvData.ReadGuidBytes(request.guid, 6, 3, 7);
768
769 if (hasHairColor)
770 recvData >> request.hairColor;
771 if (hasHairStyle)
772 recvData >> request.hairStyle;
773 if (hasSkinColor)
774 recvData >> request.skin;
775 if (hasFace)
776 recvData >> request.face;
777 if (hasFacialHair)
778 recvData >> request.facialHair;
779
780 return request;
781}
782
783ReorderCharactersRequest ReadReorderCharactersRequest(WorldPacket& recvData)
784{
785 ReorderCharactersRequest request;
786 request.characters.resize(recvData.ReadBits(9));
787
788 for (uint8 i = 0; i < request.characters.size(); ++i)
789 {
790 request.characters[i].guid[4] = recvData.ReadBit();
791 request.characters[i].guid[2] = recvData.ReadBit();
792 request.characters[i].guid[7] = recvData.ReadBit();
793 request.characters[i].guid[6] = recvData.ReadBit();
794 request.characters[i].guid[0] = recvData.ReadBit();
795 request.characters[i].guid[5] = recvData.ReadBit();
796 request.characters[i].guid[3] = recvData.ReadBit();
797 request.characters[i].guid[1] = recvData.ReadBit();
798 }
799
800 return request;
801}
802
803void ReadReorderCharacterEntryTail(WorldPacket& recvData, ReorderCharacterEntry& character)
804{
805 recvData.ReadByteSeq(character.guid[1]);
806 recvData.ReadByteSeq(character.guid[2]);
807 recvData.ReadByteSeq(character.guid[7]);
808 recvData.ReadByteSeq(character.guid[5]);
809 recvData.ReadByteSeq(character.guid[4]);
810 recvData.ReadByteSeq(character.guid[0]);
811 recvData.ReadByteSeq(character.guid[3]);
812 recvData.ReadByteSeq(character.guid[6]);
813 recvData >> character.position;
814}
815}
816
818{
819 uint32 charCount = 0;
820 ByteBuffer bitBuffer;
821 ByteBuffer dataBuffer;
822
823 // Sended before SMSG_ENUM_CHARACTERS_RESULT
824 // must be procceded before BuildEnumData, because of unsetting bosted character guid
825 if (m_charBooster->GetCurrentAction() == CHARACTER_BOOST_APPLIED)
826 m_charBooster->HandleCharacterBoost();
827
828 if (result)
829 {
830 _legitCharacters.clear();
831
832 charCount = uint32(result->GetRowCount());
833 bitBuffer.reserve(24 * charCount / 8);
834 dataBuffer.reserve(charCount * 381);
835
836 bitBuffer.WriteBits(0, 21); // factionChangeRestrictions - raceId / mask loop
837 bitBuffer.WriteBits(charCount, 16);
838
839 do
840 {
841 uint32 guidLow = (*result)[0].GetUInt32();
842
843 SF_LOG_INFO("network", "Loading char guid %u from account %u.", guidLow, GetAccountId());
844
845 Player::BuildEnumData(result, &dataBuffer, &bitBuffer, m_charBooster->IsBoosting(guidLow));
846
847 // Do not allow banned characters to log in
848 if (!(*result)[20].GetUInt32())
849 _legitCharacters.insert(guidLow);
850
851 if (!sWorld->HasCharacterNameData(guidLow)) // This can happen if characters are inserted into the database manually. Core hasn't loaded name data yet.
852 sWorld->AddCharacterNameData(guidLow, (*result)[1].GetString(), (*result)[4].GetUInt8(), (*result)[2].GetUInt8(), (*result)[3].GetUInt8(), (*result)[7].GetUInt8(), (*result)[11].GetUInt32());
853 } while (result->NextRow());
854
855 bitBuffer.WriteBit(1); // Sucess
856 bitBuffer.FlushBits();
857 }
858 else
859 {
860 bitBuffer.WriteBits(0, 21);
861 bitBuffer.WriteBits(0, 16);
862 bitBuffer.WriteBit(1); // Success
863 bitBuffer.FlushBits();
864 }
865
866 WorldPacket data(SMSG_ENUM_CHARACTERS_RESULT, 7 + bitBuffer.size() + dataBuffer.size());
867
868 data.append(bitBuffer);
869
870 if (charCount)
871 data.append(dataBuffer);
872
873 SendPacket(&data);
874
875 // Sended after SMSG_ENUM_CHARACTERS_RESULT
876 if (m_charBooster->GetCurrentAction() == CHARACTER_BOOST_ITEMS)
877 m_charBooster->HandleCharacterBoost();
878}
879
880
882{
883 // remove expired bans
884 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_EXPIRED_BANS);
885 CharacterDatabase.Execute(stmt);
886
888
890 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_ENUM_DECLINED_NAME);
891 else
892 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_ENUM);
893
894 stmt->setUInt32(0, GetAccountId());
895 stmt->setUInt32(1, GetVirtualRealmID());
896
897 _charEnumCallback = CharacterDatabase.AsyncQuery(stmt);
898}
899
901{
902 uint8 hairStyle, face, facialHair, hairColor, race_, class_, skin, gender, outfitId;
903
904 recvData >> outfitId >> hairStyle >> class_ >> skin;
905 recvData >> face >> race_ >> facialHair >> gender >> hairColor;
906
907 uint32 nameLength = recvData.ReadBits(6);
908 uint8 unk = recvData.ReadBit();
909 std::string name = recvData.ReadString(nameLength);
910
911 if (unk)
912 recvData.read_skip<uint32>();
913
914 WorldPacket data(SMSG_CHAR_CREATE, 1); // returned with diff.values in all cases
915
917 {
919 {
920 bool disabled = false;
921
922 uint32 team = Player::TeamForRace(race_);
923 switch (team)
924 {
925 case ALLIANCE:
926 disabled = mask & (1 << 0);
927 break;
928 case HORDE:
929 disabled = mask & (1 << 1);
930 break;
931 }
932
933 if (disabled)
934 {
936 SendPacket(&data);
937 return;
938 }
939 }
940 }
941
942 ChrClassesEntry const* classEntry = sChrClassesStore.LookupEntry(class_);
943 if (!classEntry)
944 {
946 SendPacket(&data);
947 SF_LOG_ERROR("network", "Class (%u) not found in DBC while creating new char for account (ID: %u): wrong DBC files or cheater?", class_, GetAccountId());
948 return;
949 }
950
951 ChrRacesEntry const* raceEntry = sChrRacesStore.LookupEntry(race_);
952 if (!raceEntry)
953 {
955 SendPacket(&data);
956 SF_LOG_ERROR("network", "Race (%u) not found in DBC while creating new char for account (ID: %u): wrong DBC files or cheater?", race_, GetAccountId());
957 return;
958 }
959 /*
960 // prevent character creating Expansion race without Expansion account
961 if (raceEntry->expansion > Expansion())
962 {
963 data << uint8(CHAR_CREATE_EXPANSION);
964 SF_LOG_ERROR("network", "Expansion %u account:[%d] tried to Create character with expansion %u race (%u)", Expansion(), GetAccountId(), raceEntry->expansion, race_);
965 SendPacket(&data);
966 return;
967 }
968
969 // prevent character creating Expansion class without Expansion account
970 if (classEntry->expansion > Expansion())
971 {
972 data << uint8(CHAR_CREATE_EXPANSION_CLASS);
973 SF_LOG_ERROR("network", "Expansion %u account:[%d] tried to Create character with expansion %u class (%u)", Expansion(), GetAccountId(), classEntry->expansion, class_);
974 SendPacket(&data);
975 return;
976 }*/
977
979 {
981 if ((1 << (race_ - 1)) & raceMaskDisabled)
982 {
984 SendPacket(&data);
985 return;
986 }
987 }
988
990 {
992 if ((1 << (class_ - 1)) & classMaskDisabled)
993 {
995 SendPacket(&data);
996 return;
997 }
998 }
999
1000 // prevent character creating with invalid name
1001 if (!normalizePlayerName(name))
1002 {
1004 SendPacket(&data);
1005 SF_LOG_ERROR("network", "Account:[%d] but tried to Create character with empty [name] ", GetAccountId());
1006 return;
1007 }
1008
1009 // check name limitations
1010 ResponseCodes res = ObjectMgr::CheckPlayerName(name, true);
1012 {
1013 data << uint8(res);
1014 SendPacket(&data);
1015 return;
1016 }
1017
1019 {
1021 SendPacket(&data);
1022 return;
1023 }
1024
1026 {
1027 // speedup check for heroic class disabled case
1028 uint32 heroic_free_slots = sWorld->getIntConfig(WorldIntConfigs::CONFIG_HEROIC_CHARACTERS_PER_REALM);
1029 if (heroic_free_slots == 0)
1030 {
1032 SendPacket(&data);
1033 return;
1034 }
1035
1036 // speedup check for heroic class disabled case
1038 if (req_level_for_heroic > sWorld->getIntConfig(WorldIntConfigs::CONFIG_MAX_PLAYER_LEVEL))
1039 {
1041 SendPacket(&data);
1042 return;
1043 }
1044 }
1045
1046 delete _charCreateCallback.GetParam(); // Delete existing if any, to make the callback chain reset to stage 0
1047 _charCreateCallback.SetParam(new CharacterCreateInfo(name, race_, class_, gender, skin, face, hairStyle, hairColor, facialHair, outfitId, recvData));
1048 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHECK_NAME);
1049 stmt->setString(0, name);
1050 _charCreateCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt));
1051}
1052
1054{
1059 switch (_charCreateCallback.GetStage())
1060 {
1061 case 0:
1062 {
1063 if (result)
1064 {
1067 SendPacket(&data);
1068 delete createInfo;
1069 _charCreateCallback.Reset();
1070 return;
1071 }
1072
1073 ASSERT(_charCreateCallback.GetParam() == createInfo);
1074
1076 stmt->setUInt32(0, GetAccountId());
1077
1078 _charCreateCallback.FreeResult();
1079 _charCreateCallback.SetFutureResult(LoginDatabase.AsyncQuery(stmt));
1080 _charCreateCallback.NextStage();
1081 }
1082 break;
1083 case 1:
1084 {
1085 uint16 acctCharCount = 0;
1086 if (result)
1087 {
1088 Field* fields = result->Fetch();
1089 // SELECT SUM(x) is MYSQL_TYPE_NEWDECIMAL - needs to be read as string
1090 const char* ch = fields[0].GetCString();
1091 if (ch)
1092 acctCharCount = atoi(ch);
1093 }
1094
1095 if (acctCharCount >= sWorld->getIntConfig(WorldIntConfigs::CONFIG_CHARACTERS_PER_ACCOUNT))
1096 {
1099 SendPacket(&data);
1100 delete createInfo;
1101 _charCreateCallback.Reset();
1102 return;
1103 }
1104
1105
1106 ASSERT(_charCreateCallback.GetParam() == createInfo);
1107
1108 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_SUM_CHARS);
1109 stmt->setUInt32(0, GetAccountId());
1110
1111 _charCreateCallback.FreeResult();
1112 _charCreateCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt));
1113 _charCreateCallback.NextStage();
1114 }
1115 break;
1116 case 2:
1117 {
1118 if (result)
1119 {
1120 Field* fields = result->Fetch();
1121 createInfo->CharCount = uint8(fields[0].GetUInt64()); // SQL's COUNT() returns uint64 but it will always be less than uint8.Max
1122
1123 if (createInfo->CharCount >= sWorld->getIntConfig(WorldIntConfigs::CONFIG_CHARACTERS_PER_REALM))
1124 {
1127 SendPacket(&data);
1128 delete createInfo;
1129 _charCreateCallback.Reset();
1130 return;
1131 }
1132 }
1133
1134 bool allowTwoSideAccounts = !sWorld->IsPvPRealm() || HasPermission(rbac::RBAC_PERM_TWO_SIDE_CHARACTER_CREATION);
1135 uint32 skipCinematics = sWorld->getIntConfig(WorldIntConfigs::CONFIG_SKIP_CINEMATICS);
1136
1137 _charCreateCallback.FreeResult();
1138
1139 if (!allowTwoSideAccounts || skipCinematics == 1 || createInfo->Class == CLASS_DEATH_KNIGHT)
1140 {
1142 stmt->setUInt32(0, GetAccountId());
1143 stmt->setUInt32(1, (skipCinematics == 1 || createInfo->Class == CLASS_DEATH_KNIGHT) ? 10 : 1);
1144 _charCreateCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt));
1145 _charCreateCallback.NextStage();
1146 return;
1147 }
1148
1149 _charCreateCallback.NextStage();
1150 HandleCharCreateCallback(PreparedQueryResult(NULL), createInfo); // Will jump to case 3
1151 }
1152 break;
1153 case 3:
1154 {
1155 bool haveSameRace = false;
1157 bool hasHeroicReqLevel = (heroicReqLevel == 0);
1158 bool allowTwoSideAccounts = !sWorld->IsPvPRealm() || HasPermission(rbac::RBAC_PERM_TWO_SIDE_CHARACTER_CREATION);
1159 uint32 skipCinematics = sWorld->getIntConfig(WorldIntConfigs::CONFIG_SKIP_CINEMATICS);
1161
1162 if (result)
1163 {
1164 uint32 team = Player::TeamForRace(createInfo->Race);
1165 uint32 freeHeroicSlots = sWorld->getIntConfig(WorldIntConfigs::CONFIG_HEROIC_CHARACTERS_PER_REALM);
1166
1167 Field* field = result->Fetch();
1168 uint8 accRace = field[1].GetUInt8();
1169
1170 if (checkHeroicReqs)
1171 {
1172 uint8 accClass = field[2].GetUInt8();
1173 if (accClass == CLASS_DEATH_KNIGHT)
1174 {
1175 if (freeHeroicSlots > 0)
1176 --freeHeroicSlots;
1177
1178 if (freeHeroicSlots == 0)
1179 {
1182 SendPacket(&data);
1183 delete createInfo;
1184 _charCreateCallback.Reset();
1185 return;
1186 }
1187 }
1188
1189 if (!hasHeroicReqLevel)
1190 {
1191 uint8 accLevel = field[0].GetUInt8();
1192 if (accLevel >= heroicReqLevel)
1193 hasHeroicReqLevel = true;
1194 }
1195 }
1196
1197 // need to check team only for first character
1199 if (!allowTwoSideAccounts)
1200 {
1201 uint32 accTeam = 0;
1202 if (accRace > 0)
1203 accTeam = Player::TeamForRace(accRace);
1204
1205 if (accTeam != team)
1206 {
1209 SendPacket(&data);
1210 delete createInfo;
1211 _charCreateCallback.Reset();
1212 return;
1213 }
1214 }
1215
1216 // search same race for cinematic or same class if need
1218 while ((skipCinematics == 1 && !haveSameRace) || createInfo->Class == CLASS_DEATH_KNIGHT)
1219 {
1220 if (!result->NextRow())
1221 break;
1222
1223 field = result->Fetch();
1224 accRace = field[1].GetUInt8();
1225
1226 if (!haveSameRace)
1227 haveSameRace = createInfo->Race == accRace;
1228
1229 if (checkHeroicReqs)
1230 {
1231 uint8 acc_class = field[2].GetUInt8();
1232 if (acc_class == CLASS_DEATH_KNIGHT)
1233 {
1234 if (freeHeroicSlots > 0)
1235 --freeHeroicSlots;
1236
1237 if (freeHeroicSlots == 0)
1238 {
1241 SendPacket(&data);
1242 delete createInfo;
1243 _charCreateCallback.Reset();
1244 return;
1245 }
1246 }
1247
1248 if (!hasHeroicReqLevel)
1249 {
1250 uint8 acc_level = field[0].GetUInt8();
1251 if (acc_level >= heroicReqLevel)
1252 hasHeroicReqLevel = true;
1253 }
1254 }
1255 }
1256 }
1257
1258 if (checkHeroicReqs && !hasHeroicReqLevel)
1259 {
1262 SendPacket(&data);
1263 delete createInfo;
1264 _charCreateCallback.Reset();
1265 return;
1266 }
1267
1268 if (createInfo->Data.rpos() < createInfo->Data.wpos())
1269 {
1270 uint8 unk;
1271 createInfo->Data >> unk;
1272 SF_LOG_DEBUG("network", "Character creation %s (account %u) has unhandled tail data: [%u]", createInfo->Name.c_str(), GetAccountId(), unk);
1273 }
1274
1275 Player newChar(this);
1276 newChar.GetMotionMaster()->Initialize();
1277 if (!newChar.Create(sObjectMgr->GenerateLowGuid(HIGHGUID_PLAYER), createInfo))
1278 {
1279 // Player not create (race/class/etc problem?)
1280 newChar.CleanupsBeforeDelete();
1281
1284 SendPacket(&data);
1285 delete createInfo;
1286 _charCreateCallback.Reset();
1287 return;
1288 }
1289
1290 if ((haveSameRace && skipCinematics == 1) || skipCinematics == 2)
1291 newChar.setCinematic(1); // not show intro
1292
1293 newChar.SetAtLoginFlag(AT_LOGIN_FIRST); // First login
1294
1295 // Player created, save it now
1296 newChar.SaveToDB(true);
1297 if (PlayerInfo const* info = sObjectMgr->GetPlayerInfo(newChar.getRace(), newChar.getClass()))
1298 SeedStarterHunterPetRecord(&newChar, info);
1299
1300 createInfo->CharCount += 1;
1301
1302 SQLTransaction trans = LoginDatabase.BeginTransaction();
1303
1305 stmt->setUInt32(0, GetAccountId());
1306 stmt->setUInt32(1, GetVirtualRealmID());
1307 trans->Append(stmt);
1308
1309 stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_REALM_CHARACTERS);
1310 stmt->setUInt32(0, createInfo->CharCount);
1311 stmt->setUInt32(1, GetAccountId());
1312 stmt->setUInt32(2, GetVirtualRealmID());
1313 trans->Append(stmt);
1314
1315 LoginDatabase.CommitTransaction(trans);
1316
1319 SendPacket(&data);
1320
1321 std::string IP_str = GetRemoteAddress();
1322 SF_LOG_INFO("entities.player.character", "Account: %d (IP: %s) Create Character:[%s] (GUID: %u)", GetAccountId(), IP_str.c_str(), createInfo->Name.c_str(), newChar.GetGUIDLow());
1323 sScriptMgr->OnPlayerCreate(&newChar);
1324 sWorld->AddCharacterNameData(newChar.GetGUIDLow(), newChar.GetName(), newChar.getGender(), newChar.getRace(), newChar.getClass(), newChar.getLevel(), newChar.getVirtualRealm());
1325
1326 newChar.CleanupsBeforeDelete();
1327 delete createInfo;
1328 _charCreateCallback.Reset();
1329 }
1330 break;
1331 }
1332}
1333
1335{
1336 CharacterGuidRequest request = ReadCharacterDeleteRequest(recvData);
1337 ObjectGuid guid = request.guid;
1338
1339 SF_LOG_DEBUG("network", "Character (Guid: %u) deleted", GUID_LOPART(guid));
1340
1341 // can't delete loaded character
1343 return;
1344
1345 uint32 accountId = 0;
1346 uint8 level = 0;
1347 std::string name;
1348
1349 // is guild leader
1350 if (sGuildMgr->GetGuildByLeader(guid))
1351 {
1354 SendPacket(&data);
1355 return;
1356 }
1357
1359 stmt->setUInt32(0, GUID_LOPART(guid));
1360
1361 if (PreparedQueryResult result = CharacterDatabase.Query(stmt))
1362 {
1363 Field* fields = result->Fetch();
1364 accountId = fields[0].GetUInt32();
1365 name = fields[1].GetString();
1366 level = fields[2].GetUInt8();
1367 }
1368
1369 // prevent deleting other players' characters using cheating tools
1370 if (accountId != GetAccountId())
1371 return;
1372
1373 std::string IP_str = GetRemoteAddress();
1374 SF_LOG_INFO("entities.player.character", "Account: %d, IP: %s deleted character: %s, GUID: %u, Level: %u", accountId, IP_str.c_str(), name.c_str(), GUID_LOPART(guid), level);
1375 sScriptMgr->OnPlayerDelete(guid);
1376
1377 if (sLog->ShouldLog("entities.player.dump", LogLevel::LOG_LEVEL_INFO)) // optimize GetPlayerDump call
1378 {
1379 std::string dump;
1380 if (PlayerDumpWriter().GetDump(GUID_LOPART(guid), dump))
1381 sLog->outCharDump(dump.c_str(), accountId, GUID_LOPART(guid), name.c_str());
1382 }
1383
1384 //sGuildFinderMgr->RemoveAllMembershipRequestsFromPlayer(guid);
1385 sCalendarMgr->RemoveAllPlayerEventsAndInvites(guid);
1386 Player::DeleteFromDB(guid, accountId);
1387
1390 SendPacket(&data);
1391}
1392
1394{
1395 if (PlayerLoading() || GetPlayer() != NULL)
1396 {
1397 SF_LOG_ERROR("network", "Player tries to login again, AccountId = %d", GetAccountId());
1399 return;
1400 }
1401
1402 m_playerLoading = true;
1403 SF_LOG_DEBUG("network", "WORLD: Recvd Player Logon Message");
1404
1405 PlayerLoginRequest request = ReadPlayerLoginRequest(recvData);
1406 ObjectGuid playerGuid = request.guid;
1407
1408 //WorldObject* player = ObjectAccessor::GetWorldObject(*GetPlayer(), playerGuid);
1409 SF_LOG_DEBUG("network", "Character (Guid: %u) logging in", GUID_LOPART(playerGuid));
1410
1411 if (!IsLegitCharacterForAccount(GUID_LOPART(playerGuid)))
1412 {
1413 SF_LOG_ERROR("network", "Account (%u) can't login with that character (%u).", GetAccountId(), GUID_LOPART(playerGuid));
1415 m_playerLoading = false;
1416 return;
1417 }
1418
1419 LoginQueryHolder* holder = new LoginQueryHolder(GetAccountId(), playerGuid);
1420 if (!holder->Initialize())
1421 {
1422 delete holder; // delete all unprocessed queries
1424 m_playerLoading = false;
1425 return;
1426 }
1427
1428 _charLoginCallback = CharacterDatabase.DelayQueryHolder((SQLQueryHolder*)holder);
1429}
1430
1432{
1433 SF_LOG_INFO("general", "WORLD: Recvd CMSG_LOADING_SCREEN_NOTIFY");
1434 LoadScreenRequest request = ReadLoadScreenRequest(recvPacket);
1435 uint32 mapID = request.mapId;
1436
1437 // TODO: Do something with this packet
1438}
1439
1441{
1442 uint64 playerGuid = holder->GetGuid();
1443
1444 Player* pCurrChar = new Player(this);
1445 // for send server info and strings (config)
1446 ChatHandler chH = ChatHandler(pCurrChar->GetSession());
1447
1448 // "GetAccountId() == db stored account id" checked in LoadFromDB (prevent login not own character using cheating tools)
1449 if (!pCurrChar->LoadFromDB(GUID_LOPART(playerGuid), holder))
1450 {
1451 SetPlayer(NULL);
1453 delete pCurrChar; // delete it manually
1454 delete holder; // delete all unprocessed queries
1455 m_playerLoading = false;
1456 return;
1457 }
1458
1459 pCurrChar->GetMotionMaster()->Initialize();
1460 pCurrChar->SendDungeonDifficulty();
1461
1462 WorldPacket data(SMSG_LOGIN_VERIFY_WORLD, 4 + 4 + 4 + 4 + 4);
1463 data << pCurrChar->GetPositionX();
1464 data << pCurrChar->GetOrientation();
1465 data << pCurrChar->GetPositionY();
1466 data << pCurrChar->GetMapId();
1467 data << pCurrChar->GetPositionZ();
1468 SendPacket(&data);
1469
1470 // load player specific part before send times
1473
1474 bool feedbackSystem = sWorld->GetBoolConfig(WorldBoolConfigs::CONFIG_TICKETS_FEEDBACK_SYSTEM_ENABLED);
1475 bool excessiveWarning = false;
1476
1477 data.Initialize(SMSG_FEATURE_SYSTEM_STATUS, 4 + 4 + 4 + 1 + 4 + 2 + 4 + 4 + 4 + 4 + 4 + 4 + 4);
1478 data << uint32(0); // Scroll of Resurrection per day?
1479 data << uint32(0); // Scroll of Resurrection current
1480 data << uint32(0);
1481 data << uint8(2);
1482 data << uint32(0);
1483
1484 data.WriteBit(0);
1485 data.WriteBit(1); // ingame shop status (0 - "The Shop is temporarily unavailable.")
1486 data.WriteBit(0);
1487 data.WriteBit(0); // Recruit a Friend button
1488 data.WriteBit(0); // server supports voice chat
1489 data.WriteBit(1); // show ingame shop icon
1490 data.WriteBit(0); // Scroll of Resurrection button
1491 data.WriteBit(excessiveWarning); // excessive play time warning
1492 data.WriteBit(0); // ingame shop parental control (1 - "Feature has been disabled by Parental Controls.")
1493 data.WriteBit(feedbackSystem); // feedback system (bug, suggestion and report systems)
1494 data.FlushBits();
1495
1496 if (excessiveWarning)
1497 {
1498 data << uint32(0); // excessive play time warning after period(in seconds)
1499 data << uint32(0);
1500 data << uint32(0);
1501 }
1502
1503 if (feedbackSystem)
1504 {
1505 data << uint32(0);
1506 data << uint32(1);
1507 data << uint32(10);
1508 data << uint32(60000);
1509 }
1510
1511 SendPacket(&data);
1512
1513 // Send MOTD
1514 {
1515 data.Initialize(SMSG_MOTD, 50); // new in 2.0.1
1516 data.WriteBits(0, 4);
1517
1518 uint32 linecount = 0;
1519 std::string str_motd = sWorld->GetMotd();
1520 std::string::size_type pos, nextpos;
1521 ByteBuffer stringBuffer;
1522
1523 pos = 0;
1524 while ((nextpos = str_motd.find('@', pos)) != std::string::npos)
1525 {
1526 if (nextpos != pos)
1527 {
1528 std::string string = str_motd.substr(pos, nextpos - pos);
1529 data.WriteBits(strlen(string.c_str()), 7);
1530 stringBuffer.WriteString(string);
1531 ++linecount;
1532 }
1533 pos = nextpos + 1;
1534 }
1535
1536 if (pos < str_motd.length())
1537 {
1538 std::string string = str_motd.substr(pos);
1539 data.WriteBits(strlen(string.c_str()), 7);
1540 stringBuffer.WriteString(string);
1541 ++linecount;
1542 }
1543
1544
1545 data.PutBits(0, linecount, 4);
1546 data.FlushBits();
1547 data.append(stringBuffer);
1548
1549 SendPacket(&data);
1550 SF_LOG_DEBUG("network", "WORLD: Sent motd (SMSG_MOTD)");
1551
1552 // send server info
1553 if (sWorld->getIntConfig(WorldIntConfigs::CONFIG_ENABLE_SINFO_LOGIN) == 1)
1554 {
1555 chH.PSendSysMessage("Open Source Emulation https://www.projectskyfire.org");
1556 chH.PSendSysMessage("www.github.com/ProjectSkyfire/SkyFire_548");
1557 chH.PSendSysMessage("revision: %s", SKYFIRE_VER_PRODUCTVERSION_STR);
1558 }
1559
1560 SF_LOG_DEBUG("network", "WORLD: Sent server info");
1561 }
1562
1563 data.Initialize(SMSG_PVP_SEASON, 4 + 4);
1564 data << uint32(sWorld->getIntConfig(WorldIntConfigs::CONFIG_ARENA_SEASON_ID) - 1); // Old season
1565 data << uint32(sWorld->getIntConfig(WorldIntConfigs::CONFIG_ARENA_SEASON_ID)); // Current season
1566 SendPacket(&data);
1567
1568 //QueryResult* result = CharacterDatabase.PQuery("SELECT guildid, rank FROM guild_member WHERE guid = '%u'", pCurrChar->GetGUIDLow());
1570 {
1571 Field* fields = resultGuild->Fetch();
1572 pCurrChar->SetInGuild(fields[0].GetUInt32());
1573 pCurrChar->SetRank(fields[1].GetUInt8());
1574 if (Guild* guild = sGuildMgr->GetGuildById(pCurrChar->GetGuildId()))
1575 pCurrChar->SetGuildLevel(guild->GetLevel());
1576 }
1577 else if (pCurrChar->GetGuildId()) // clear guild related fields in case wrong data about non existed membership
1578 {
1579 pCurrChar->SetInGuild(0);
1580 pCurrChar->SetRank(0);
1581 pCurrChar->SetGuildLevel(0);
1582 }
1583
1585
1586 HotfixData const& hotfix = sObjectMgr->GetHotfixData();
1587
1589 data.WriteBits(hotfix.size(), 20);
1590 data.FlushBits();
1591
1592 for (uint32 i = 0; i < hotfix.size(); ++i)
1593 {
1594 data << uint32(hotfix[i].Timestamp);
1595 data << uint32(hotfix[i].Entry);
1596 data << uint32(hotfix[i].Type);
1597 }
1598
1599 SendPacket(&data);
1600
1602
1603 //Show cinematic at the first time that player login
1604 if (!pCurrChar->getCinematic())
1605 {
1606 pCurrChar->setCinematic(1);
1607
1608 if (ChrClassesEntry const* cEntry = sChrClassesStore.LookupEntry(pCurrChar->getClass()))
1609 {
1610 if (cEntry->CinematicSequence)
1611 pCurrChar->SendCinematicStart(cEntry->CinematicSequence);
1612 else if (ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(pCurrChar->getRace()))
1613 pCurrChar->SendCinematicStart(rEntry->CinematicSequence);
1614
1615 // send new char string if not empty
1616 if (!sWorld->GetNewCharString().empty())
1617 chH.PSendSysMessage("%s", sWorld->GetNewCharString().c_str());
1618 }
1619 }
1620
1621 if (!pCurrChar->GetMap()->AddPlayerToMap(pCurrChar) || !pCurrChar->CheckInstanceLoginValid())
1622 {
1623 AreaTriggerStruct const* at = sObjectMgr->GetGoBackTrigger(pCurrChar->GetMapId());
1624 if (at)
1625 pCurrChar->TeleportTo(at->target_mapId, at->target_X, at->target_Y, at->target_Z, pCurrChar->GetOrientation());
1626 else
1627 pCurrChar->TeleportTo(pCurrChar->m_homebindMapId, pCurrChar->m_homebindX, pCurrChar->m_homebindY, pCurrChar->m_homebindZ, pCurrChar->GetOrientation());
1628 }
1629
1630 sObjectAccessor->AddObject(pCurrChar);
1631 //SF_LOG_DEBUG("Player %s added to Map.", pCurrChar->GetName().c_str());
1632
1633 if (pCurrChar->GetGuildId() != 0)
1634 {
1635 if (Guild* guild = sGuildMgr->GetGuildById(pCurrChar->GetGuildId()))
1636 guild->SendLoginInfo(this);
1637 else
1638 {
1639 // remove wrong guild data
1640 SF_LOG_ERROR("general", "Player %s (GUID: %u) marked as member of not existing guild (id: %u), removing guild membership for player.", pCurrChar->GetName().c_str(), pCurrChar->GetGUIDLow(), pCurrChar->GetGuildId());
1641 pCurrChar->SetInGuild(0);
1642 }
1643 }
1644
1646
1647 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_ONLINE);
1648 stmt->setUInt32(0, pCurrChar->GetGUIDLow());
1649 CharacterDatabase.Execute(stmt);
1650
1651 stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_ACCOUNT_ONLINE);
1652 stmt->setUInt32(0, GetAccountId());
1653 LoginDatabase.Execute(stmt);
1654
1655 pCurrChar->SetInGameTime(getMSTime());
1656
1657 // announce group about member online (must be after add to player list to receive announce to self)
1658 if (Group* group = pCurrChar->GetGroup())
1659 {
1660 //pCurrChar->groupInfo.group->SendInit(this); // useless
1661 group->SendUpdate();
1662 group->ResetMaxEnchantingLevel();
1663 }
1664
1665 // friend status
1666 sSocialMgr->SendFriendStatus(pCurrChar, FRIEND_ONLINE, pCurrChar->GetGUIDLow(), true);
1667
1668 // Place character in world (and load zone) before some object loading
1669 pCurrChar->LoadCorpse();
1670
1671 // setting Ghost+speed if dead
1672 if (pCurrChar->m_deathState != DeathState::ALIVE)
1673 {
1674 // not blizz like, we must correctly save and load player instead...
1675 if (pCurrChar->getRace() == RACE_NIGHTELF)
1676 pCurrChar->CastSpell(pCurrChar, 20584, true, 0);// auras SPELL_AURA_INCREASE_SPEED(+speed in wisp form), SPELL_AURA_INCREASE_SWIM_SPEED(+swim speed in wisp form), SPELL_AURA_TRANSFORM (to wisp form)
1677 pCurrChar->CastSpell(pCurrChar, 8326, true, 0); // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?)
1678
1679 pCurrChar->SetWaterWalking(true);
1680 }
1681
1682 pCurrChar->ContinueTaxiFlight();
1683
1684 // reset for all pets before pet loading
1687
1688 // Load pet if any (if player not alive and in taxi flight or another then pet will remember as temporary unsummoned)
1689 pCurrChar->LoadPet();
1690
1691 // Set FFA PvP for non GM in non-rest mode
1692 if (sWorld->IsFFAPvPRealm() && !pCurrChar->IsGameMaster() && !pCurrChar->HasFlag(PLAYER_FIELD_PLAYER_FLAGS, PLAYER_FLAGS_RESTING))
1694
1696 pCurrChar->SetContestedPvP();
1697
1698 // Apply at_login requests
1699 if (pCurrChar->HasAtLoginFlag(AT_LOGIN_RESET_SPELLS))
1700 {
1701 pCurrChar->resetSpells();
1703 }
1704
1705 if (pCurrChar->HasAtLoginFlag(AT_LOGIN_RESET_TALENTS))
1706 {
1707 pCurrChar->ResetTalents(true);
1708 pCurrChar->SendTalentsInfoData(); // original talents send already in to SendInitialPacketsBeforeAddToMap, resend reset state
1710 }
1711
1712 bool const firstLogin = pCurrChar->HasAtLoginFlag(AT_LOGIN_FIRST);
1713 if (firstLogin)
1714 {
1716
1717 if (PlayerInfo const* info = sObjectMgr->GetPlayerInfo(pCurrChar->getRace(), pCurrChar->getClass()))
1718 {
1719 StarterHunterPetTemplate starterPet = { };
1720 bool const hasStarterHunterPet = pCurrChar->getClass() == CLASS_HUNTER && pCurrChar->GetPet() &&
1721 GetStarterHunterPetTemplate(info, starterPet);
1722
1723 for (uint32 spellId : info->spell_cast)
1724 {
1725 if (hasStarterHunterPet && spellId == starterPet.CreatedBySpell)
1726 continue;
1727
1728 pCurrChar->CastSpell(pCurrChar, spellId, true);
1729 }
1730
1731 if (pCurrChar->getClass() == CLASS_HUNTER)
1732 {
1733 if (Pet* pet = pCurrChar->GetPet())
1734 {
1736 }
1737 else
1738 {
1739 pCurrChar->LoadPet();
1740 if (!pCurrChar->GetPet())
1741 {
1742 Pet* storedPet = new Pet(pCurrChar);
1743 if (!storedPet->LoadPetFromDB(pCurrChar))
1744 delete storedPet;
1745 }
1746
1747 if (!pCurrChar->GetPet())
1748 CreateStarterHunterPet(pCurrChar, info);
1749 }
1750 }
1751 }
1752 }
1753
1754 // show time before shutdown if shutdown planned.
1755 if (sWorld->IsShuttingDown())
1756 sWorld->ShutdownMsg(true, pCurrChar);
1757
1759 pCurrChar->SetTaxiCheater(true);
1760
1761 if (pCurrChar->IsGameMaster())
1763
1764 std::string IP_str = GetRemoteAddress();
1765 SF_LOG_INFO("entities.player.character", "Account: %d (IP: %s) Login Character:[%s] (GUID: %u) Level: %d",
1766 GetAccountId(), IP_str.c_str(), pCurrChar->GetName().c_str(), pCurrChar->GetGUIDLow(), pCurrChar->getLevel());
1767
1768 if (!pCurrChar->IsStandState() && !pCurrChar->HasUnitState(UNIT_STATE_STUNNED))
1770
1771 m_playerLoading = false;
1772
1773 if (pCurrChar->getClass() == CLASS_MONK)
1774 pCurrChar->CastSpell(pCurrChar, 103985, true); //Stance of White Tiger
1775
1776 sScriptMgr->OnPlayerLogin(pCurrChar, firstLogin);
1777 delete holder;
1778}
1780{
1781 SF_LOG_DEBUG("network", "WORLD: Received CMSG_SET_LFG_BONUS_FACTION_ID");
1782 UInt32Request request = ReadUInt32Request(recvData);
1783 uint32 FactionID = request.value;
1785}
1786
1788{
1789 SF_LOG_DEBUG("network", "WORLD: Received CMSG_SET_FACTION_ATWAR");
1790
1791 UInt8Request request = ReadUInt8Request(recvData);
1792 uint8 FactionIndexID = request.value;
1793
1794 GetPlayer()->GetReputationMgr().SetAtWar(FactionIndexID);
1795}
1796
1798{
1799 SF_LOG_DEBUG("network", "WORLD: Received CMSG_SET_FACTION_NOTATWAR");
1800
1801 UInt8Request request = ReadUInt8Request(recvData);
1802 uint8 FactionIndexID = request.value;
1803
1804 GetPlayer()->GetReputationMgr().SetNotAtWar(FactionIndexID);
1805}
1806
1807//I think this function is never used :/ I dunno, but i guess this opcode not exists
1809{
1810 SF_LOG_ERROR("network", "WORLD SESSION: HandleSetFactionCheat, not expected call, please report.");
1812}
1813
1815{
1816 UInt32Request request = ReadUInt32Request(recvData);
1817 uint32 data = request.value;
1818
1819 uint8 index = uint8(data / 32);
1820 if (index >= MAX_ACCOUNT_TUTORIAL_VALUES)
1821 return;
1822
1823 uint32 value = (data % 32);
1824
1825 uint32 flag = GetTutorialInt(index);
1826 flag |= (1 << value);
1827 SetTutorialInt(index, flag);
1828}
1829
1831{
1832 for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i)
1833 SetTutorialInt(i, 0xFFFFFFFF);
1834}
1835
1837{
1838 for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i)
1839 SetTutorialInt(i, 0x00000000);
1840}
1841
1843{
1844 SF_LOG_DEBUG("network", "WORLD: Received CMSG_SET_WATCHED_FACTION");
1845 UInt32Request request = ReadUInt32Request(recvData);
1846 uint32 fact = request.value;
1848}
1849
1851{
1852 SF_LOG_DEBUG("network", "WORLD: Received CMSG_SET_FACTION_INACTIVE");
1853 FactionInactiveRequest request = ReadFactionInactiveRequest(recvData);
1854 uint32 FactionIndex = request.factionIndex;
1855 uint8 Status = request.status;
1856
1857 _player->GetReputationMgr().SetInactive(FactionIndex, Status);
1858}
1859
1861{
1862 SF_LOG_DEBUG("network", "WORLD: Received CMSG_REQUEST_FORCED_REACTIONS");
1863
1864 _player->GetReputationMgr().SendForceReactions();
1865}
1866
1868{
1869 SF_LOG_DEBUG("network", "CMSG_SHOWING_HELM for %s", _player->GetName().c_str());
1870 ReadToggleDisplayRequest(recvData);
1872}
1873
1875{
1876 SF_LOG_DEBUG("network", "CMSG_SHOWING_CLOAK for %s", _player->GetName().c_str());
1877 ReadToggleDisplayRequest(recvData);
1879}
1880
1882{
1883 CharacterRenameRequest request = ReadCharacterRenameRequest(recvData);
1884 ObjectGuid guid = request.guid;
1885 std::string newName = request.newName;
1886
1887 // prevent character rename to invalid name
1888 if (!normalizePlayerName(newName))
1889 {
1892 SendPacket(&data);
1893 return;
1894 }
1895
1896 ResponseCodes result = ObjectMgr::CheckPlayerName(newName, true);
1898 {
1899 WorldPacket data(SMSG_CHAR_RENAME, 1 + 8 + (newName.size() + 1));
1900 data << uint8(result);
1901 data.WriteGuidMask(guid, 6, 3, 4, 2, 0, 1, 7, 5);
1902 data.WriteGuidBytes(guid, 5, 0, 4, 2, 1, 3, 6, 7);
1903 data << newName;
1904 SendPacket(&data);
1905 return;
1906 }
1907
1908 // check name limitations
1910 {
1913 SendPacket(&data);
1914 return;
1915 }
1916
1917 // Ensure that the character belongs to the current account, that rename at login is enabled
1918 // and that there is no character with the desired new name
1919 _charRenameCallback.SetParam(newName);
1920
1921 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_FREE_NAME);
1922
1923 stmt->setUInt32(0, GUID_LOPART(guid));
1924 stmt->setUInt32(1, GetAccountId());
1925 stmt->setUInt16(2, AT_LOGIN_RENAME);
1926 stmt->setUInt16(3, AT_LOGIN_RENAME);
1927 stmt->setString(4, newName);
1928
1929 _charRenameCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt));
1930}
1931
1933{
1934 if (!result)
1935 {
1938 SendPacket(&data);
1939 return;
1940 }
1941
1942 Field* fields = result->Fetch();
1943
1944 uint32 guidLow = fields[0].GetUInt32();
1945 std::string oldName = fields[1].GetString();
1946
1947 uint64 guid = MAKE_NEW_GUID(guidLow, 0, HIGHGUID_PLAYER);
1948
1949 // Update name and at_login flag in the db
1950 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_NAME);
1951
1952 stmt->setString(0, newName);
1953 stmt->setUInt16(1, AT_LOGIN_RENAME);
1954 stmt->setUInt32(2, guidLow);
1955
1956 CharacterDatabase.Execute(stmt);
1957
1958 // Removed declined name from db
1959 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_DECLINED_NAME);
1960
1961 stmt->setUInt32(0, guidLow);
1962
1963 CharacterDatabase.Execute(stmt);
1964
1965 SF_LOG_INFO("entities.player.character", "Account: %d (IP: %s) Character:[%s] (guid:%u) Changed name to: %s", GetAccountId(), GetRemoteAddress().c_str(), oldName.c_str(), guidLow, newName.c_str());
1966
1967 WorldPacket data(SMSG_CHAR_RENAME, 1 + 8 + (newName.size() + 1));
1969 data << uint64(guid);
1970 data << newName;
1971 SendPacket(&data);
1972
1973 sWorld->UpdateCharacterNameData(guidLow, newName);
1974}
1975
1977{
1978 DeclinedNamesRequest request = ReadDeclinedNamesRequest(recvData);
1979 ObjectGuid guid = request.guid;
1980 DeclinedName declinedname = request.declinedName;
1981
1982 // not accept declined names for unsupported languages
1983 std::string name;
1984 if (!sObjectMgr->GetPlayerNameByGUID(guid, name))
1985 {
1987 data.WriteBit(1);
1988 data.WriteGuidMask(guid, 2, 0, 3, 1, 4, 6, 5, 7);
1989 data.FlushBits();
1990 data.WriteGuidBytes(guid, 2, 7, 1, 0, 4, 3, 6, 5);
1991 data << uint32(1);
1992 SendPacket(&data);
1993 return;
1994 }
1995
1996 std::wstring wname;
1997 if (!Utf8toWStr(name, wname))
1998 {
2000 data.WriteBit(1);
2001 data.WriteGuidMask(guid, 2, 0, 3, 1, 4, 6, 5, 7);
2002 data.FlushBits();
2003 data.WriteGuidBytes(guid, 2, 7, 1, 0, 4, 3, 6, 5);
2004 data << uint32(1);
2005 SendPacket(&data);
2006 return;
2007 }
2008
2009 if (!isCyrillicCharacter(wname[0])) // name already stored as only single alphabet using
2010 {
2012 data.WriteBit(1);
2013 data.WriteGuidMask(guid, 2, 0, 3, 1, 4, 6, 5, 7);
2014 data.FlushBits();
2015 data.WriteGuidBytes(guid, 2, 7, 1, 0, 4, 3, 6, 5);
2016 data << uint32(1);
2017 SendPacket(&data);
2018 return;
2019 }
2020
2021 for (int i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
2022 {
2023 if (!normalizePlayerName(declinedname.name[i]))
2024 {
2026 data.WriteBit(1);
2027 data.WriteGuidMask(guid, 2, 0, 3, 1, 4, 6, 5, 7);
2028 data.FlushBits();
2029 data.WriteGuidBytes(guid, 2, 7, 1, 0, 4, 3, 6, 5);
2030 data << uint32(1);
2031 SendPacket(&data);
2032 return;
2033 }
2034 }
2035
2036 if (!ObjectMgr::CheckDeclinedNames(wname, declinedname))
2037 {
2039 data.WriteBit(1);
2040 data.WriteGuidMask(guid, 2, 0, 3, 1, 4, 6, 5, 7);
2041 data.FlushBits();
2042 data.WriteGuidBytes(guid, 2, 7, 1, 0, 4, 3, 6, 5);
2043 data << uint32(1);
2044 SendPacket(&data);
2045 return;
2046 }
2047
2048 for (int i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
2049 CharacterDatabase.EscapeString(declinedname.name[i]);
2050
2051 SQLTransaction trans = CharacterDatabase.BeginTransaction();
2052
2054 stmt->setUInt32(0, GUID_LOPART(guid));
2055 trans->Append(stmt);
2056
2057 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_DECLINED_NAME);
2058 stmt->setUInt32(0, GUID_LOPART(guid));
2059
2060 for (uint8 i = 0; i < 5; i++)
2061 stmt->setString(i + 1, declinedname.name[i]);
2062
2063 trans->Append(stmt);
2064
2065 CharacterDatabase.CommitTransaction(trans);
2066
2068 data.WriteBit(0);
2069 data.WriteGuidMask(guid, 2, 0, 3, 1, 4, 6, 5, 7);
2070 data.FlushBits();
2071 data.WriteGuidBytes(guid, 2, 7, 1, 0, 4, 3, 6, 5);
2072 data << uint32(0); // OK
2073 SendPacket(&data);
2074}
2075
2076
2078{
2079 SF_LOG_DEBUG("network", "CMSG_ALTER_APPEARANCE");
2080
2081 AlterAppearanceRequest request = ReadAlterAppearanceRequest(recvData);
2082 uint32 Hair = request.hair;
2083 uint32 Color = request.color;
2084 uint32 FacialHair = request.facialHair;
2085 uint32 SkinColor = request.skinColor;
2086
2087 BarberShopStyleEntry const* bs_hair = sBarberShopStyleStore.LookupEntry(Hair);
2088
2089 if (!bs_hair || bs_hair->type != 0 || bs_hair->race != _player->getRace() || bs_hair->gender != _player->getGender())
2090 return;
2091
2092 BarberShopStyleEntry const* bs_facialHair = sBarberShopStyleStore.LookupEntry(FacialHair);
2093
2094 if (!bs_facialHair || bs_facialHair->type != 2 || bs_facialHair->race != _player->getRace() || bs_facialHair->gender != _player->getGender())
2095 return;
2096
2097 BarberShopStyleEntry const* bs_skinColor = sBarberShopStyleStore.LookupEntry(SkinColor);
2098
2099 if (bs_skinColor && (bs_skinColor->type != 3 || bs_skinColor->race != _player->getRace() || bs_skinColor->gender != _player->getGender()))
2100 return;
2101
2102 GameObject* go = _player->FindNearestGameObjectOfType(GAMEOBJECT_TYPE_BARBER_CHAIR, 5.0f);
2103 if (!go)
2104 {
2106 return;
2107 }
2108
2110 {
2112 return;
2113 }
2114
2115 uint32 cost = _player->GetBarberShopCost(bs_hair->hair_id, Color, bs_facialHair->hair_id, bs_skinColor);
2116 if (!_player->HasEnoughMoney((uint64)cost))
2117 {
2119 return;
2120 }
2121
2123
2124 _player->ModifyMoney(-int64(cost)); // it isn't free
2125 _player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_AT_BARBER, cost);
2126
2127 _player->SetByteValue(PLAYER_FIELD_HAIR_COLOR_ID, 2, uint8(bs_hair->hair_id));
2128 _player->SetByteValue(PLAYER_FIELD_HAIR_COLOR_ID, 3, uint8(Color));
2129 _player->SetByteValue(PLAYER_FIELD_REST_STATE, 0, uint8(bs_facialHair->hair_id));
2130 if (bs_skinColor)
2131 _player->SetByteValue(PLAYER_FIELD_HAIR_COLOR_ID, 0, uint8(bs_skinColor->hair_id));
2132
2133 _player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP, 1);
2134
2135 _player->SetStandState(0); // stand up
2136}
2137
2139{
2141 data << uint32(result);
2142 SendPacket(&data);
2143}
2144
2146{
2147 CharacterCustomizeRequest request = ReadCharacterCustomizeRequest(recvData);
2148 ObjectGuid guid = request.guid;
2149 std::string newName = request.newName;
2150 uint8 gender = request.gender;
2151 uint8 skin = request.skin;
2152 uint8 face = request.face;
2153 uint8 hairStyle = request.hairStyle;
2154 uint8 hairColor = request.hairColor;
2155 uint8 facialHair = request.facialHair;
2156
2158 {
2159 SF_LOG_ERROR("network", "Account %u, IP: %s tried to customise character %u, but it does not belong to their account!",
2160 GetAccountId(), GetRemoteAddress().c_str(), GUID_LOPART(guid));
2161 recvData.rfinish();
2162 KickPlayer();
2163 return;
2164 }
2165
2167 stmt->setUInt32(0, GUID_LOPART(guid));
2168 PreparedQueryResult result = CharacterDatabase.Query(stmt);
2169
2170 if (!result)
2171 {
2174 SendPacket(&data);
2175 return;
2176 }
2177
2178 Field* fields = result->Fetch();
2179 uint32 at_loginFlags = fields[0].GetUInt16();
2180
2181 if (!(at_loginFlags & AT_LOGIN_CUSTOMIZE))
2182 {
2185 SendPacket(&data);
2186 return;
2187 }
2188
2189 // prevent character rename to invalid name
2190 if (!normalizePlayerName(newName))
2191 {
2194 SendPacket(&data);
2195 return;
2196 }
2197
2198 ResponseCodes res = ObjectMgr::CheckPlayerName(newName, true);
2200 {
2202 data << uint8(res);
2203 SendPacket(&data);
2204 return;
2205 }
2206
2207 // check name limitations
2209 {
2212 SendPacket(&data);
2213 return;
2214 }
2215
2216 // character with this name already exist
2217 if (uint64 newguid = sObjectMgr->GetPlayerGUIDByName(newName))
2218 {
2219 if (newguid != guid)
2220 {
2223 SendPacket(&data);
2224 return;
2225 }
2226 }
2227
2228 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_NAME);
2229 stmt->setUInt32(0, GUID_LOPART(guid));
2230 result = CharacterDatabase.Query(stmt);
2231
2232 if (result)
2233 {
2234 std::string oldname = result->Fetch()[0].GetString();
2235 SF_LOG_INFO("entities.player.character", "Account: %d (IP: %s), Character[%s] (guid:%u) Customized to: %s", GetAccountId(), GetRemoteAddress().c_str(), oldname.c_str(), GUID_LOPART(guid), newName.c_str());
2236 }
2237
2238 Player::Customize(guid, gender, skin, face, hairStyle, hairColor, facialHair);
2239
2240 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_NAME_AT_LOGIN);
2241
2242 stmt->setString(0, newName);
2244 stmt->setUInt32(2, GUID_LOPART(guid));
2245
2246 CharacterDatabase.Execute(stmt);
2247
2248 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_DECLINED_NAME);
2249
2250 stmt->setUInt32(0, GUID_LOPART(guid));
2251
2252 CharacterDatabase.Execute(stmt);
2253
2254 sWorld->UpdateCharacterNameData(GUID_LOPART(guid), newName, gender);
2255
2256 WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1 + 8 + (newName.size() + 1) + 6);
2257 data.WriteGuidMask(guid, 0, 7, 3, 2, 6, 5, 1, 4);
2258 data.WriteGuidBytes(guid, 1);
2260 data << uint8(facialHair);
2261 data << uint8(skin);
2262 data << uint8(gender);
2263 data << uint8(hairStyle);
2264 data << uint8(face);
2265 data << uint8(hairColor);
2266 data.WriteGuidBytes(guid, 7, 3, 5, 2, 6, 0, 4);
2267 data << newName;
2268 SendPacket(&data);
2269}
2270
2272{
2273 SF_LOG_DEBUG("network", "CMSG_EQUIPMENT_SET_SAVE");
2274
2275 EquipmentSetSaveIndexRequest indexRequest = ReadEquipmentSetSaveIndexRequest(recvData);
2276 uint32 index = indexRequest.index;
2277 EquipmentSet eqSet;
2278
2279 if (index >= MAX_EQUIPMENT_SET_INDEX) // client set slots amount
2280 return;
2281
2282 EquipmentSetSaveHeaderRequest request = ReadEquipmentSetSaveHeaderRequest(recvData);
2283
2284 for (uint32 i = 0; i < EQUIPMENT_SLOT_END; ++i)
2285 {
2286 ReadEquipmentSetSaveItemGuidBytes(recvData, request.itemGuid[i]);
2287
2288 // equipment manager sends "1" (as raw GUID) for slots set to "ignore" (don't touch slot at equip set)
2289 if (request.itemGuid[i] == 1)
2290 {
2291 // ignored slots saved as bit mask because we have no free special values for Items[i]
2292 eqSet.IgnoreMask |= 1 << i;
2293 continue;
2294 }
2295
2296 Item* item = _player->GetItemByPos(INVENTORY_SLOT_BAG_0, i);
2297
2298 if (!item && request.itemGuid[i]) // cheating check 1
2299 return;
2300
2301 if (item && item->GetGUID() != request.itemGuid[i]) // cheating check 2
2302 return;
2303
2304 eqSet.Items[i] = GUID_LOPART(request.itemGuid[i]);
2305 }
2306
2307 EquipmentSetSaveTailRequest tail = ReadEquipmentSetSaveTailRequest(recvData, request);
2308 eqSet.Guid = tail.setGuid;
2309 eqSet.Name = tail.name;
2310 eqSet.IconName = tail.iconName;
2312
2313 _player->SetEquipmentSet(index, eqSet);
2314}
2315
2317{
2318 SF_LOG_DEBUG("network", "CMSG_EQUIPMENT_SET_DELETE");
2319
2320 CharacterGuidRequest request = ReadEquipmentSetDeleteRequest(recvData);
2321 ObjectGuid setGuid = request.guid;
2322
2323 _player->DeleteEquipmentSet(setGuid);
2324}
2325
2327{
2328 SF_LOG_DEBUG("network", "CMSG_EQUIPMENT_SET_USE");
2329
2330 EquipmentSetUseRequest request = ReadEquipmentSetUseRequest(recvData);
2332
2333 for (uint32 i = 0; i < EQUIPMENT_SLOT_END; ++i)
2334 {
2335 ReadEquipmentSetUseItemGuidBytes(recvData, request.itemGuid[i]);
2336
2337 if (i < uint32(startSlot))
2338 continue;
2339
2340 // check if item slot is set to "ignored" (raw value == 1), must not be unequipped then
2341 if (request.itemGuid[i] == 1)
2342 continue;
2343
2344 Item* item = _player->GetItemByGuid(request.itemGuid[i]);
2345
2346 uint16 dstpos = i | (INVENTORY_SLOT_BAG_0 << 8);
2347
2348 if (!item)
2349 {
2350 Item* uItem = _player->GetItemByPos(INVENTORY_SLOT_BAG_0, i);
2351 if (!uItem)
2352 continue;
2353
2354 ItemPosCountVec sDest;
2355 InventoryResult msg = _player->CanStoreItem(NULL_BAG, NULL_SLOT, sDest, uItem, false);
2356 if (msg == EQUIP_ERR_OK)
2357 {
2358 _player->RemoveItem(INVENTORY_SLOT_BAG_0, i, true);
2359 _player->StoreItem(sDest, uItem, true);
2360 }
2361 else
2362 _player->SendEquipError(msg, uItem, NULL);
2363
2364 continue;
2365 }
2366
2367 if (item->GetPos() == dstpos)
2368 continue;
2369
2370 _player->SwapItem(item->GetPos(), dstpos);
2371 }
2372
2373 recvData.rfinish(); //Container Slot and Slot not used.
2374
2375 uint8 Reason = 0;
2377 data << uint8(Reason); // 4 - equipment swap failed - inventory is full
2378
2379 SendPacket(&data);
2380}
2381
2383{
2384 CharFactionOrRaceChangeRequest request = ReadCharFactionOrRaceChangeRequest(recvData);
2385 ObjectGuid guid = request.guid;
2386 std::string newname = request.newName;
2387 uint8 gender = request.gender;
2388 uint8 skin = request.skin;
2389 uint8 face = request.face;
2390 uint8 hairStyle = request.hairStyle;
2391 uint8 hairColor = request.hairColor;
2392 uint8 facialHair = request.facialHair;
2393 uint8 race = request.race;
2394 bool isFactionChange = request.isFactionChange;
2395
2397 {
2398 SF_LOG_ERROR("network", "Account %u, IP: %s tried to factionchange character %u, but it does not belong to their account!",
2399 GetAccountId(), GetRemoteAddress().c_str(), GUID_LOPART(guid));
2400 KickPlayer();
2401 return;
2402 }
2403
2404 uint32 lowGuid = GUID_LOPART(guid);
2405
2406 // get the players old (at this moment current) race
2407 CharacterNameData const* nameData = sWorld->GetCharacterNameData(lowGuid);
2408 if (!nameData)
2409 {
2412 SendPacket(&data);
2413 return;
2414 }
2415
2416 uint8 oldRace = nameData->m_race;
2417 uint8 playerClass = nameData->m_class;
2418 uint8 level = nameData->m_level;
2419
2421 stmt->setUInt32(0, lowGuid);
2422 PreparedQueryResult result = CharacterDatabase.Query(stmt);
2423
2424 if (!result)
2425 {
2428 SendPacket(&data);
2429 return;
2430 }
2431
2432 Field* fields = result->Fetch();
2433 uint32 at_loginFlags = fields[0].GetUInt16();
2434 char const* knownTitlesStr = fields[1].GetCString();
2435 uint32 used_loginFlag = isFactionChange ? AT_LOGIN_CHANGE_FACTION : AT_LOGIN_CHANGE_RACE;
2436
2437 if (!sObjectMgr->GetPlayerInfo(race, playerClass))
2438 {
2441 SendPacket(&data);
2442 return;
2443 }
2444
2445 if (!(at_loginFlags & used_loginFlag))
2446 {
2449 SendPacket(&data);
2450 return;
2451 }
2452
2454 {
2456 if ((1 << (race - 1)) & raceMaskDisabled)
2457 {
2460 SendPacket(&data);
2461 return;
2462 }
2463 }
2464
2465 // prevent character rename to invalid name
2466 if (!normalizePlayerName(newname))
2467 {
2470 SendPacket(&data);
2471 return;
2472 }
2473
2474 ResponseCodes res = ObjectMgr::CheckPlayerName(newname, true);
2476 {
2478 data << uint8(res);
2479 SendPacket(&data);
2480 return;
2481 }
2482
2483 // check name limitations
2485 {
2488 SendPacket(&data);
2489 return;
2490 }
2491
2492 // character with this name already exist
2493 if (uint64 newguid = sObjectMgr->GetPlayerGUIDByName(newname))
2494 {
2495 if (newguid != guid)
2496 {
2499 SendPacket(&data);
2500 return;
2501 }
2502 }
2503
2504 CharacterDatabase.EscapeString(newname);
2505 Player::Customize(guid, gender, skin, face, hairStyle, hairColor, facialHair);
2506 SQLTransaction trans = CharacterDatabase.BeginTransaction();
2507
2508 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_FACTION_OR_RACE);
2509 stmt->setString(0, newname);
2510 stmt->setUInt8(1, race);
2511 stmt->setUInt16(2, used_loginFlag);
2512 stmt->setUInt32(3, lowGuid);
2513 trans->Append(stmt);
2514
2515 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_DECLINED_NAME);
2516 stmt->setUInt32(0, lowGuid);
2517 trans->Append(stmt);
2518
2519 sWorld->UpdateCharacterNameData(GUID_LOPART(guid), newname, gender, race);
2520
2521 if (oldRace != race)
2522 {
2523 TeamId team = TEAM_ALLIANCE;
2524
2525 // Search each faction is targeted
2526 switch (race)
2527 {
2528 case RACE_ORC:
2529 case RACE_TAUREN:
2530 case RACE_UNDEAD_PLAYER:
2531 case RACE_TROLL:
2532 case RACE_BLOODELF:
2533 case RACE_GOBLIN:
2534 team = TEAM_HORDE;
2535 break;
2536 default:
2537 break;
2538 }
2539
2540 // Switch Languages
2541 // delete all languages first
2542 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_SKILL_LANGUAGES);
2543 stmt->setUInt32(0, lowGuid);
2544 trans->Append(stmt);
2545
2546 // Now add them back
2547 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_SKILL_LANGUAGE);
2548 stmt->setUInt32(0, lowGuid);
2549
2550 // Faction specific languages
2551 if (team == TEAM_HORDE)
2552 stmt->setUInt16(1, 109);
2553 else
2554 stmt->setUInt16(1, 98);
2555
2556 trans->Append(stmt);
2557
2558 // Race specific languages
2559 if (race != RACE_ORC && race != RACE_HUMAN)
2560 {
2561 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_SKILL_LANGUAGE);
2562 stmt->setUInt32(0, lowGuid);
2563
2564 switch (race)
2565 {
2566 case RACE_DWARF:
2567 stmt->setUInt16(1, 111);
2568 break;
2569 case RACE_DRAENEI:
2570 stmt->setUInt16(1, 759);
2571 break;
2572 case RACE_GNOME:
2573 stmt->setUInt16(1, 313);
2574 break;
2575 case RACE_NIGHTELF:
2576 stmt->setUInt16(1, 113);
2577 break;
2578 case RACE_WORGEN:
2579 stmt->setUInt16(1, 791);
2580 break;
2581 case RACE_UNDEAD_PLAYER:
2582 stmt->setUInt16(1, 673);
2583 break;
2584 case RACE_TAUREN:
2585 stmt->setUInt16(1, 115);
2586 break;
2587 case RACE_TROLL:
2588 stmt->setUInt16(1, 315);
2589 break;
2590 case RACE_BLOODELF:
2591 stmt->setUInt16(1, 137);
2592 break;
2593 case RACE_GOBLIN:
2594 stmt->setUInt16(1, 792);
2595 break;
2597 stmt->setUInt16(1, 905);
2598 break;
2599 }
2600
2601 trans->Append(stmt);
2602 }
2603
2604 if (isFactionChange)
2605 {
2606 // Delete all Flypaths
2607 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_TAXI_PATH);
2608 stmt->setUInt32(0, lowGuid);
2609 trans->Append(stmt);
2610
2611 if (level > 7)
2612 {
2613 // Update Taxi path
2614 // this doesn't seem to be 100% blizzlike... but it can't really be helped.
2615 std::ostringstream taximaskstream;
2616 uint32 numFullTaximasks = level / 7;
2617 if (numFullTaximasks > 11)
2618 numFullTaximasks = 11;
2619 if (team == TEAM_ALLIANCE)
2620 {
2621 if (playerClass != CLASS_DEATH_KNIGHT)
2622 {
2623 for (uint8 i = 0; i < numFullTaximasks; ++i)
2624 taximaskstream << uint32(sAllianceTaxiNodesMask[i]) << ' ';
2625 }
2626 else
2627 {
2628 for (uint8 i = 0; i < numFullTaximasks; ++i)
2629 taximaskstream << uint32(sAllianceTaxiNodesMask[i] | sDeathKnightTaxiNodesMask[i]) << ' ';
2630 }
2631 }
2632 else
2633 {
2634 if (playerClass != CLASS_DEATH_KNIGHT)
2635 {
2636 for (uint8 i = 0; i < numFullTaximasks; ++i)
2637 taximaskstream << uint32(sHordeTaxiNodesMask[i]) << ' ';
2638 }
2639 else
2640 {
2641 for (uint8 i = 0; i < numFullTaximasks; ++i)
2642 taximaskstream << uint32(sHordeTaxiNodesMask[i] | sDeathKnightTaxiNodesMask[i]) << ' ';
2643 }
2644 }
2645
2646 uint32 numEmptyTaximasks = 11 - numFullTaximasks;
2647 for (uint8 i = 0; i < numEmptyTaximasks; ++i)
2648 taximaskstream << "0 ";
2649 taximaskstream << '0';
2650 std::string taximask = taximaskstream.str();
2651
2652 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_TAXIMASK);
2653 stmt->setString(0, taximask);
2654 stmt->setUInt32(1, lowGuid);
2655 trans->Append(stmt);
2656 }
2657
2659 {
2660 // Reset guild
2661 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUILD_MEMBER);
2662
2663 stmt->setUInt32(0, lowGuid);
2664
2665 result = CharacterDatabase.Query(stmt);
2666 if (result)
2667 if (Guild* guild = sGuildMgr->GetGuildById((result->Fetch()[0]).GetUInt32()))
2668 guild->DeleteMember(MAKE_NEW_GUID(lowGuid, 0, HIGHGUID_PLAYER));
2669 }
2670
2672 {
2673 // Delete Friend List
2674 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_SOCIAL_BY_GUID);
2675 stmt->setUInt32(0, lowGuid);
2676 trans->Append(stmt);
2677
2678 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_SOCIAL_BY_FRIEND);
2679 stmt->setUInt32(0, lowGuid);
2680 trans->Append(stmt);
2681 }
2682
2683 // Reset homebind and position
2684 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PLAYER_HOMEBIND);
2685 stmt->setUInt32(0, lowGuid);
2686 trans->Append(stmt);
2687
2688 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_PLAYER_HOMEBIND);
2689 stmt->setUInt32(0, lowGuid);
2690 if (team == TEAM_ALLIANCE)
2691 {
2692 stmt->setUInt16(1, 0);
2693 stmt->setUInt16(2, 1519);
2694 stmt->setFloat(3, -8867.68f);
2695 stmt->setFloat(4, 673.373f);
2696 stmt->setFloat(5, 97.9034f);
2697 Player::SavePositionInDB(0, -8867.68f, 673.373f, 97.9034f, 0.0f, 1519, lowGuid);
2698 }
2699 else
2700 {
2701 stmt->setUInt16(1, 1);
2702 stmt->setUInt16(2, 1637);
2703 stmt->setFloat(3, 1633.33f);
2704 stmt->setFloat(4, -4439.11f);
2705 stmt->setFloat(5, 15.7588f);
2706 Player::SavePositionInDB(1, 1633.33f, -4439.11f, 15.7588f, 0.0f, 1637, lowGuid);
2707 }
2708 trans->Append(stmt);
2709
2710 // Achievement conversion
2711 for (std::map<uint32, uint32>::const_iterator it = sObjectMgr->FactionChangeAchievements.begin(); it != sObjectMgr->FactionChangeAchievements.end(); ++it)
2712 {
2713 uint32 achiev_alliance = it->first;
2714 uint32 achiev_horde = it->second;
2715
2717 stmt->setUInt16(0, uint16(team == TEAM_ALLIANCE ? achiev_alliance : achiev_horde));
2718 stmt->setUInt32(1, lowGuid);
2719 trans->Append(stmt);
2720
2721 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_ACHIEVEMENT);
2722 stmt->setUInt16(0, uint16(team == TEAM_ALLIANCE ? achiev_alliance : achiev_horde));
2723 stmt->setUInt16(1, uint16(team == TEAM_ALLIANCE ? achiev_horde : achiev_alliance));
2724 stmt->setUInt32(2, lowGuid);
2725 trans->Append(stmt);
2726 }
2727
2728 // Item conversion
2729 for (std::map<uint32, uint32>::const_iterator it = sObjectMgr->FactionChangeItems.begin(); it != sObjectMgr->FactionChangeItems.end(); ++it)
2730 {
2731 uint32 item_alliance = it->first;
2732 uint32 item_horde = it->second;
2733
2734 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_INVENTORY_FACTION_CHANGE);
2735 stmt->setUInt32(0, (team == TEAM_ALLIANCE ? item_alliance : item_horde));
2736 stmt->setUInt32(1, (team == TEAM_ALLIANCE ? item_horde : item_alliance));
2737 stmt->setUInt32(2, guid);
2738 trans->Append(stmt);
2739 }
2740
2741 // Delete all current quests
2742 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_QUESTSTATUS);
2743 stmt->setUInt32(0, GUID_LOPART(guid));
2744 trans->Append(stmt);
2745
2746 // Quest conversion
2747 for (std::map<uint32, uint32>::const_iterator it = sObjectMgr->FactionChangeQuests.begin(); it != sObjectMgr->FactionChangeQuests.end(); ++it)
2748 {
2749 uint32 quest_alliance = it->first;
2750 uint32 quest_horde = it->second;
2751
2753 stmt->setUInt32(0, lowGuid);
2754 stmt->setUInt32(1, (team == TEAM_ALLIANCE ? quest_alliance : quest_horde));
2755 trans->Append(stmt);
2756
2758 stmt->setUInt32(0, (team == TEAM_ALLIANCE ? quest_alliance : quest_horde));
2759 stmt->setUInt32(1, (team == TEAM_ALLIANCE ? quest_horde : quest_alliance));
2760 stmt->setUInt32(2, lowGuid);
2761 trans->Append(stmt);
2762 }
2763
2764 // Mark all rewarded quests as "active" (will count for completed quests achievements)
2766 stmt->setUInt32(0, lowGuid);
2767 trans->Append(stmt);
2768
2769 // Disable all old-faction specific quests
2770 {
2771 ObjectMgr::QuestMap const& questTemplates = sObjectMgr->GetQuestTemplates();
2772 for (ObjectMgr::QuestMap::const_iterator iter = questTemplates.begin(); iter != questTemplates.end(); ++iter)
2773 {
2774 Quest const* quest = iter->second;
2775 uint32 newRaceMask = (team == TEAM_ALLIANCE) ? RACEMASK_ALLIANCE : RACEMASK_HORDE;
2776 if (!(quest->GetRequiredRaces() & newRaceMask))
2777 {
2779 stmt->setUInt32(0, lowGuid);
2780 stmt->setUInt32(1, quest->GetQuestId());
2781 trans->Append(stmt);
2782 }
2783 }
2784 }
2785
2786 // Spell conversion
2787 for (std::map<uint32, uint32>::const_iterator it = sObjectMgr->FactionChangeSpells.begin(); it != sObjectMgr->FactionChangeSpells.end(); ++it)
2788 {
2789 uint32 spell_alliance = it->first;
2790 uint32 spell_horde = it->second;
2791
2792 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_SPELL_BY_SPELL);
2793 stmt->setUInt32(0, (team == TEAM_ALLIANCE ? spell_alliance : spell_horde));
2794 stmt->setUInt32(1, lowGuid);
2795 trans->Append(stmt);
2796
2797 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_SPELL_FACTION_CHANGE);
2798 stmt->setUInt32(0, (team == TEAM_ALLIANCE ? spell_alliance : spell_horde));
2799 stmt->setUInt32(1, (team == TEAM_ALLIANCE ? spell_horde : spell_alliance));
2800 stmt->setUInt32(2, lowGuid);
2801 trans->Append(stmt);
2802 }
2803
2804 // Reputation conversion
2805 for (std::map<uint32, uint32>::const_iterator it = sObjectMgr->FactionChangeReputation.begin(); it != sObjectMgr->FactionChangeReputation.end(); ++it)
2806 {
2807 uint32 reputation_alliance = it->first;
2808 uint32 reputation_horde = it->second;
2809 uint32 newReputation = (team == TEAM_ALLIANCE) ? reputation_alliance : reputation_horde;
2810 uint32 oldReputation = (team == TEAM_ALLIANCE) ? reputation_horde : reputation_alliance;
2811
2812 // select old standing set in db
2813 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_REP_BY_FACTION);
2814 stmt->setUInt32(0, oldReputation);
2815 stmt->setUInt32(1, lowGuid);
2816 result = CharacterDatabase.Query(stmt);
2817
2818 if (!result)
2819 {
2822 SendPacket(&data);
2823 return;
2824 }
2825
2826 fields = result->Fetch();
2827 int32 oldDBRep = fields[0].GetInt32();
2828 FactionEntry const* factionEntry = sFactionStore.LookupEntry(oldReputation);
2829
2830 // old base reputation
2831 int32 oldBaseRep = sObjectMgr->GetBaseReputationOf(factionEntry, oldRace, playerClass);
2832
2833 // new base reputation
2834 int32 newBaseRep = sObjectMgr->GetBaseReputationOf(sFactionStore.LookupEntry(newReputation), race, playerClass);
2835
2836 // final reputation shouldnt change
2837 int32 FinalRep = oldDBRep + oldBaseRep;
2838 int32 newDBRep = FinalRep - newBaseRep;
2839
2840 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_REP_BY_FACTION);
2841 stmt->setUInt32(0, newReputation);
2842 stmt->setUInt32(1, lowGuid);
2843 trans->Append(stmt);
2844
2845 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_REP_FACTION_CHANGE);
2846 stmt->setUInt16(0, uint16(newReputation));
2847 stmt->setInt32(1, newDBRep);
2848 stmt->setUInt16(2, uint16(oldReputation));
2849 stmt->setUInt32(3, lowGuid);
2850 trans->Append(stmt);
2851 }
2852
2853 // Title conversion
2854 if (knownTitlesStr)
2855 {
2856 const uint32 ktcount = KNOWN_TITLES_SIZE * 2;
2857 uint32 knownTitles[ktcount];
2858 Tokenizer tokens(knownTitlesStr, ' ', ktcount);
2859
2860 if (tokens.size() != ktcount)
2861 return;
2862
2863 for (uint32 index = 0; index < ktcount; ++index)
2864 knownTitles[index] = atol(tokens[index]);
2865
2866 for (std::map<uint32, uint32>::const_iterator it = sObjectMgr->FactionChangeTitles.begin(); it != sObjectMgr->FactionChangeTitles.end(); ++it)
2867 {
2868 uint32 title_alliance = it->first;
2869 uint32 title_horde = it->second;
2870
2871 CharTitlesEntry const* atitleInfo = sCharTitlesStore.LookupEntry(title_alliance);
2872 CharTitlesEntry const* htitleInfo = sCharTitlesStore.LookupEntry(title_horde);
2873 // new team
2874 if (team == TEAM_ALLIANCE)
2875 {
2876 uint32 bitIndex = htitleInfo->bit_index;
2877 uint32 index = bitIndex / 32;
2878 uint32 old_flag = 1 << (bitIndex % 32);
2879 uint32 new_flag = 1 << (atitleInfo->bit_index % 32);
2880 if (knownTitles[index] & old_flag)
2881 {
2882 knownTitles[index] &= ~old_flag;
2883 // use index of the new title
2884 knownTitles[atitleInfo->bit_index / 32] |= new_flag;
2885 }
2886 }
2887 else
2888 {
2889 uint32 bitIndex = atitleInfo->bit_index;
2890 uint32 index = bitIndex / 32;
2891 uint32 old_flag = 1 << (bitIndex % 32);
2892 uint32 new_flag = 1 << (htitleInfo->bit_index % 32);
2893 if (knownTitles[index] & old_flag)
2894 {
2895 knownTitles[index] &= ~old_flag;
2896 // use index of the new title
2897 knownTitles[htitleInfo->bit_index / 32] |= new_flag;
2898 }
2899 }
2900
2901 std::ostringstream ss;
2902 for (uint32 index = 0; index < ktcount; ++index)
2903 ss << knownTitles[index] << ' ';
2904
2905 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_TITLES_FACTION_CHANGE);
2906 stmt->setString(0, ss.str().c_str());
2907 stmt->setUInt32(1, lowGuid);
2908 trans->Append(stmt);
2909
2910 // unset any currently chosen title
2911 stmt = CharacterDatabase.GetPreparedStatement(CHAR_RES_CHAR_TITLES_FACTION_CHANGE);
2912 stmt->setUInt32(0, lowGuid);
2913 trans->Append(stmt);
2914 }
2915 }
2916 }
2917 }
2918
2919 CharacterDatabase.CommitTransaction(trans);
2920
2921 std::string IP_str = GetRemoteAddress();
2922 SF_LOG_DEBUG("entities.player", "%s (IP: %s) changed race from %u to %u", GetPlayerInfo().c_str(), IP_str.c_str(), oldRace, race);
2923
2924 WorldPacket data(SMSG_CHAR_FACTION_CHANGE, 1 + 8 + (newname.size() + 1) + 1 + 1 + 1 + 1 + 1 + 1 + 1);
2926 data << uint64(guid);
2927 data << newname;
2928 data << uint8(gender);
2929 data << uint8(skin);
2930 data << uint8(face);
2931 data << uint8(hairStyle);
2932 data << uint8(hairColor);
2933 data << uint8(facialHair);
2934 data << uint8(race);
2935 SendPacket(&data);
2936}
2937
2939{
2940 RandomizeCharNameRequest request = ReadRandomizeCharNameRequest(recvData);
2941 uint8 gender = request.gender;
2942 uint8 race = request.race;
2943
2944 if (!Player::IsValidRace(race))
2945 {
2946 SF_LOG_ERROR("general", "Invalid race (%u) sent by accountId: %u", race, GetAccountId());
2947 return;
2948 }
2949
2950 if (!Player::IsValidGender(gender))
2951 {
2952 SF_LOG_ERROR("general", "Invalid gender (%u) sent by accountId: %u", gender, GetAccountId());
2953 return;
2954 }
2955
2956 std::string const* name = GetRandomCharacterName(race, gender);
2957 WorldPacket data(SMSG_RANDOMIZE_CHAR_NAME, 1 + name->size());
2958 data.WriteBit(0); // unk
2959 data.WriteBits(name->size(), 6);
2960 data.FlushBits();
2961 data.WriteString(*name);
2962 SendPacket(&data);
2963}
2964
2966{
2967 ReorderCharactersRequest request = ReadReorderCharactersRequest(recvData);
2968
2969 SQLTransaction trans = CharacterDatabase.BeginTransaction();
2970 for (uint8 i = 0; i < request.characters.size(); ++i)
2971 {
2972 ReadReorderCharacterEntryTail(recvData, request.characters[i]);
2973
2974 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_LIST_SLOT);
2975 stmt->setUInt8(0, request.characters[i].position);
2976 stmt->setUInt32(1, GUID_LOPART(request.characters[i].guid));
2977 trans->Append(stmt);
2978 }
2979
2980 CharacterDatabase.CommitTransaction(trans);
2981}
2982
2984{
2985 // Only players that has not yet gained any experience can use this
2986 if (_player->GetUInt32Value(PLAYER_FIELD_XP))
2987 return;
2988
2989 if (ChrClassesEntry const* classEntry = sChrClassesStore.LookupEntry(_player->getClass()))
2990 {
2991 if (classEntry->CinematicSequence)
2992 _player->SendCinematicStart(classEntry->CinematicSequence);
2993 else if (ChrRacesEntry const* raceEntry = sChrRacesStore.LookupEntry(_player->getRace()))
2994 _player->SendCinematicStart(raceEntry->CinematicSequence);
2995 }
2996}
@ LOG_LEVEL_INFO
Definition Appender.h:20
#define sCalendarMgr
@ CHAR_SEL_CHARACTER_ACTIONS
@ CHAR_SEL_CHARACTER_DAILYQUESTSTATUS
@ CHAR_DEL_CHAR_SOCIAL_BY_FRIEND
@ CHAR_UPD_CHAR_INVENTORY_FACTION_CHANGE
@ CHAR_SEL_CHECK_NAME
@ CHAR_SEL_CHARACTER_AT_LOGIN
@ CHAR_UPD_CHAR_ONLINE
@ CHAR_DEL_CHAR_QUESTSTATUS_REWARDED_BY_QUEST
@ CHAR_SEL_CHARACTER
@ CHAR_SEL_PLAYER_CURRENCY
@ CHAR_SEL_CHARACTER_QUESTSTATUSREW
@ CHAR_SEL_PLAYER_ACCOUNT_DATA
@ CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_FACTION_CHANGE
@ CHAR_DEL_DECLINED_NAME
@ CHAR_DEL_CHAR_SKILL_LANGUAGES
@ CHAR_SEL_CHARACTER_AURAS
@ CHAR_SEL_ACCOUNT_INSTANCELOCKTIMES
@ CHAR_UPD_CHAR_ACHIEVEMENT
@ CHAR_SEL_ACCOUNT_BATTLE_PET_SLOTS
@ CHAR_DEL_CHAR_DECLINED_NAME
@ CHAR_SEL_CHAR_VOID_STORAGE
@ CHAR_INS_PLAYER_HOMEBIND
@ CHAR_INS_CHAR_SKILL_LANGUAGE
@ CHAR_SEL_CHARACTER_BGDATA
@ CHAR_SEL_CHARACTER_SOCIALLIST
@ CHAR_UPD_CHAR_SPELL_FACTION_CHANGE
@ CHAR_UPD_CHAR_TAXI_PATH
@ CHAR_UPD_CHAR_TAXIMASK
@ CHAR_DEL_PLAYER_HOMEBIND
@ CHAR_SEL_CHAR_REP_BY_FACTION
@ CHAR_SEL_CHARACTER_HOMEBIND
@ CHAR_SEL_FREE_NAME
@ CHAR_SEL_ENUM
@ CHAR_SEL_SUM_CHARS
@ CHAR_SEL_GROUP_MEMBER
@ CHAR_UPD_CHAR_LIST_SLOT
@ CHAR_DEL_CHAR_SPELL_BY_SPELL
@ CHAR_SEL_CHAR_CREATE_INFO
@ CHAR_SEL_CHARACTER_INVENTORY
@ CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_ACTIVE_BY_QUEST
@ CHAR_SEL_CHARACTER_INSTANCE
@ CHAR_SEL_CHARACTER_DATA_BY_GUID
@ CHAR_SEL_CHARACTER_QUESTSTATUS
@ CHAR_DEL_CHAR_ACHIEVEMENT_BY_ACHIEVEMENT
@ CHAR_SEL_CHARACTER_TALENTS
@ CHAR_SEL_CHARACTER_WEEKLYQUESTSTATUS
@ CHAR_SEL_CHAR_CUF_PROFILES
@ CHAR_SEL_CHARACTER_CRITERIAPROGRESS
@ CHAR_SEL_CHARACTER_MAILCOUNT
@ CHAR_SEL_CHARACTER_GLYPHS
@ CHAR_SEL_CHARACTER_REPUTATION
@ CHAR_DEL_CHAR_QUESTSTATUS
@ CHAR_SEL_CHARACTER_SPELL
@ CHAR_UPD_CHAR_REP_FACTION_CHANGE
@ CHAR_SEL_ACCOUNT_BATTLE_PETS
@ CHAR_SEL_CHARACTER_RANDOMBG
@ CHAR_SEL_CHARACTER_EQUIPMENTSETS
@ CHAR_SEL_CHARACTER_SKILLS
@ CHAR_SEL_CHARACTER_MAILDATE
@ CHAR_UPD_CHAR_TITLES_FACTION_CHANGE
@ CHAR_DEL_CHAR_REP_BY_FACTION
@ CHAR_SEL_CHAR_RESEARCH_DIGSITES
@ CHAR_SEL_CHARACTER_QUEST_OBJECTIVE_STATUS
@ CHAR_SEL_ENUM_DECLINED_NAME
@ CHAR_SEL_CHARACTER_SPELLCOOLDOWNS
@ CHAR_RES_CHAR_TITLES_FACTION_CHANGE
@ CHAR_SEL_CHARACTER_MONTHLYQUESTSTATUS
@ CHAR_SEL_CHAR_RESEARCH_HISTORY
@ CHAR_SEL_CHAR_AT_LOGIN_TITLES
@ CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_ACTIVE
@ CHAR_DEL_CHAR_SOCIAL_BY_GUID
@ CHAR_SEL_CHARACTER_ACHIEVEMENTS
@ CHAR_UPD_NAME
@ CHAR_DEL_EXPIRED_BANS
@ CHAR_SEL_CHAR_RESEARCH_PROJECTS
@ CHAR_SEL_CHARACTER_SEASONALQUESTSTATUS
@ CHAR_SEL_GUILD_MEMBER
@ CHAR_SEL_CHARACTER_DECLINEDNAMES
@ CHAR_UPD_CHAR_NAME_AT_LOGIN
@ CHAR_INS_CHAR_DECLINED_NAME
@ CHAR_SEL_CHARACTER_BANNED
@ CHAR_SEL_CHARACTER_NAME
@ CHAR_UPD_FACTION_OR_RACE
#define MAX_ACCOUNT_TUTORIAL_VALUES
Definition Common.h:157
@ ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP
Definition DBCEnums.h:213
@ ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_AT_BARBER
Definition DBCEnums.h:228
DBCStorage< CharTitlesEntry > sCharTitlesStore(CharTitlesEntryfmt)
DBCStorage< FactionEntry > sFactionStore(FactionEntryfmt)
TaxiMask sAllianceTaxiNodesMask
const std::string * GetRandomCharacterName(uint8 race, uint8 gender)
DBCStorage< BarberShopStyleEntry > sBarberShopStyleStore(BarberShopStyleEntryfmt)
DBCStorage< ChrRacesEntry > sChrRacesStore(ChrRacesEntryfmt)
TaxiMask sDeathKnightTaxiNodesMask
DBCStorage< CreatureFamilyEntry > sCreatureFamilyStore(CreatureFamilyfmt)
DBCStorage< ChrClassesEntry > sChrClassesStore(ChrClassesEntryfmt)
TaxiMask sHordeTaxiNodesMask
#define MAX_SPELL_EFFECTS
std::int32_t int32
Definition Define.h:73
std::uint8_t uint8
Definition Define.h:79
std::uint32_t uint32
Definition Define.h:77
std::uint64_t uint64
Definition Define.h:76
std::int64_t int64
Definition Define.h:72
std::uint16_t uint16
Definition Define.h:78
#define ASSERT
Definition Errors.h:29
#define sGuildMgr
Definition GuildMgr.h:53
InventoryResult
Definition Item.h:27
@ EQUIP_ERR_OK
Definition Item.h:28
@ LANG_RESET_SPELLS
Definition Language.h:216
@ LANG_RESET_TALENTS
Definition Language.h:217
@ LANG_GM_ON
Definition Language.h:339
#define SF_LOG_DEBUG(filterType__,...)
Definition Log.h:134
#define SF_LOG_ERROR(filterType__,...)
Definition Log.h:143
#define SF_LOG_INFO(filterType__,...)
Definition Log.h:137
#define sLog
Definition Log.h:106
@ LOGIN_INS_REALM_CHARACTERS
@ LOGIN_SEL_SUM_REALM_CHARACTERS
@ LOGIN_UPD_ACCOUNT_ONLINE
@ LOGIN_DEL_REALM_CHARACTERS_BY_REALM
#define sObjectAccessor
uint32 GUID_LOPART(uint64 x)
@ HIGHGUID_PLAYER
uint64 MAKE_NEW_GUID(uint32 l, uint32 e, uint32 h)
bool normalizePlayerName(std::string &name)
std::vector< HotfixInfo > HotfixData
Definition ObjectMgr.h:665
#define sObjectMgr
Definition ObjectMgr.h:1617
@ PET_SAVE_AS_CURRENT
Definition PetDefines.h:22
#define PET_FOLLOW_DIST
Definition PetDefines.h:57
@ HUNTER_PET
Definition PetDefines.h:12
std::vector< ItemPosCount > ItemPosCountVec
Definition Player.h:777
#define KNOWN_TITLES_SIZE
Definition Player.h:571
@ PLAYER_FLAGS_HIDE_CLOAK
Definition Player.h:548
@ PLAYER_FLAGS_CONTESTED_PVP
Definition Player.h:545
@ PLAYER_FLAGS_RESTING
Definition Player.h:542
@ PLAYER_FLAGS_HIDE_HELM
Definition Player.h:547
#define MAX_EQUIPMENT_SET_INDEX
Definition Player.h:766
EquipmentSlots
Definition Player.h:687
@ EQUIPMENT_SLOT_MAINHAND
Definition Player.h:704
@ EQUIPMENT_SLOT_END
Definition Player.h:708
@ EQUIPMENT_SLOT_START
Definition Player.h:688
@ AT_LOGIN_RESET_TALENTS
Definition Player.h:619
@ AT_LOGIN_RESET_SPELLS
Definition Player.h:618
@ AT_LOGIN_RESET_PET_TALENTS
Definition Player.h:621
@ AT_LOGIN_FIRST
Definition Player.h:622
@ AT_LOGIN_CUSTOMIZE
Definition Player.h:620
@ AT_LOGIN_RENAME
Definition Player.h:617
@ AT_LOGIN_CHANGE_RACE
Definition Player.h:624
@ AT_LOGIN_CHANGE_FACTION
Definition Player.h:623
#define INVENTORY_SLOT_BAG_0
Definition Player.h:684
@ PLAYER_LOGIN_QUERY_LOAD_SPELL_COOLDOWNS
Definition Player.h:883
@ PLAYER_LOGIN_QUERY_LOAD_CURRENCY
Definition Player.h:903
@ PLAYER_LOGIN_QUERY_LOAD_RESEARCH_HISTORY
Definition Player.h:909
@ PLAYER_LOGIN_QUERY_LOAD_GLYPHS
Definition Player.h:891
@ PLAYER_LOGIN_QUERY_LOAD_DECLINED_NAMES
Definition Player.h:884
@ PLAYER_LOGIN_QUERY_LOAD_QUEST_STATUS_REW
Definition Player.h:898
@ MAX_PLAYER_LOGIN_QUERY
Definition Player.h:911
@ PLAYER_LOGIN_QUERY_LOAD_DAILY_QUEST_STATUS
Definition Player.h:875
@ PLAYER_LOGIN_QUERY_LOAD_INSTANCE_LOCK_TIMES
Definition Player.h:899
@ PLAYER_LOGIN_QUERY_LOAD_SEASONAL_QUEST_STATUS
Definition Player.h:900
@ PLAYER_LOGIN_QUERY_LOAD_SOCIAL_LIST
Definition Player.h:881
@ PLAYER_LOGIN_QUERY_LOAD_ACTIONS
Definition Player.h:878
@ PLAYER_LOGIN_QUERY_LOAD_SKILLS
Definition Player.h:894
@ PLAYER_LOGIN_QUERY_LOAD_BG_DATA
Definition Player.h:890
@ PLAYER_LOGIN_QUERY_LOAD_ACCOUNT_DATA
Definition Player.h:893
@ PLAYER_LOGIN_QUERY_LOAD_MAIL_DATE
Definition Player.h:880
@ PLAYER_LOGIN_QUERY_LOAD_VOID_STORAGE
Definition Player.h:902
@ PLAYER_LOGIN_QUERY_LOAD_INVENTORY
Definition Player.h:877
@ PLAYER_LOGIN_QUERY_LOAD_REPUTATION
Definition Player.h:876
@ PLAYER_LOGIN_QUERY_LOAD_RESEARCH_PROJECTS
Definition Player.h:910
@ PLAYER_LOGIN_QUERY_LOAD_MAIL_COUNT
Definition Player.h:879
@ PLAYER_LOGIN_QUERY_LOAD_FROM
Definition Player.h:869
@ PLAYER_LOGIN_QUERY_LOAD_QUEST_STATUS
Definition Player.h:874
@ PLAYER_LOGIN_QUERY_LOAD_BATTLE_PET_SLOTS
Definition Player.h:906
@ PLAYER_LOGIN_QUERY_LOAD_BATTLE_PETS
Definition Player.h:905
@ PLAYER_LOGIN_QUERY_LOAD_RESEARCH_DIGSITES
Definition Player.h:908
@ PLAYER_LOGIN_QUERY_LOAD_WEEKLY_QUEST_STATUS
Definition Player.h:895
@ PLAYER_LOGIN_QUERY_LOAD_MONTHLY_QUEST_STATUS
Definition Player.h:901
@ PLAYER_LOGIN_QUERY_LOAD_GUILD
Definition Player.h:885
@ PLAYER_LOGIN_QUERY_LOAD_EQUIPMENT_SETS
Definition Player.h:889
@ PLAYER_LOGIN_QUERY_LOAD_AURAS
Definition Player.h:872
@ PLAYER_LOGIN_QUERY_LOAD_TALENTS
Definition Player.h:892
@ PLAYER_LOGIN_QUERY_LOAD_BANNED
Definition Player.h:897
@ PLAYER_LOGIN_QUERY_LOAD_QUEST_OBJECTIVE_STATUS
Definition Player.h:907
@ PLAYER_LOGIN_QUERY_LOAD_GROUP
Definition Player.h:870
@ PLAYER_LOGIN_QUERY_LOAD_CRITERIA_PROGRESS
Definition Player.h:888
@ PLAYER_LOGIN_QUERY_LOAD_HOME_BIND
Definition Player.h:882
@ PLAYER_LOGIN_QUERY_LOAD_SPELLS
Definition Player.h:873
@ PLAYER_LOGIN_QUERY_LOAD_BOUND_INSTANCES
Definition Player.h:871
@ PLAYER_LOGIN_QUERY_LOAD_CUF_PROFILES
Definition Player.h:904
@ PLAYER_LOGIN_QUERY_LOAD_RANDOM_BG
Definition Player.h:896
@ PLAYER_LOGIN_QUERY_LOAD_ACHIEVEMENTS
Definition Player.h:887
Skyfire::AutoPtr< PreparedResultSet, Skyfire::Mutex > PreparedQueryResult
Definition QueryResult.h:94
Role Based Access Control related classes definition.
uint8 FactionIndex
#define sScriptMgr
Definition ScriptMgr.h:764
@ GAMEOBJECT_TYPE_BARBER_CHAIR
@ SPELL_EFFECT_CREATE_TAMED_PET
ResponseCodes
@ CHAR_DELETE_FAILED_GUILD_LEADER
@ CHAR_CREATE_PVP_TEAMS_VIOLATION
TeamId
@ TEAM_ALLIANCE
@ TEAM_HORDE
@ CLASS_HUNTER
@ CLASS_MONK
@ CLASS_DEATH_KNIGHT
@ CHARACTER_BOOST_APPLIED
@ CHARACTER_BOOST_ITEMS
@ ALLIANCE
@ HORDE
#define RACEMASK_HORDE
@ RACE_TROLL
@ RACE_UNDEAD_PLAYER
@ RACE_PANDAREN_NEUTRAL
@ RACE_ORC
@ RACE_DRAENEI
@ RACE_NIGHTELF
@ RACE_BLOODELF
@ RACE_DWARF
@ RACE_GNOME
@ RACE_GOBLIN
@ RACE_HUMAN
@ RACE_WORGEN
@ RACE_TAUREN
#define RACEMASK_ALLIANCE
#define sSocialMgr
Definition SocialMgr.h:134
@ FRIEND_ONLINE
Definition SocialMgr.h:59
#define sSpellMgr
Definition SpellMgr.h:744
uint32 getMSTime()
Definition Timer.h:12
Skyfire::AutoPtr< Transaction, Skyfire::Mutex > SQLTransaction
Definition Transaction.h:42
@ ALIVE
Definition Unit.h:503
@ UNIT_STAND_STATE_SIT_LOW_CHAIR
Definition Unit.h:166
@ UNIT_STAND_STATE_STAND
Definition Unit.h:162
#define MAX_DECLINED_NAME_CASES
Definition Unit.h:1098
@ NULL_BAG
Definition Unit.h:336
@ NULL_SLOT
Definition Unit.h:337
@ UNIT_BYTE2_FLAG_FFA_PVP
Definition Unit.h:257
@ UNIT_STATE_STUNNED
Definition Unit.h:515
@ REACT_DEFENSIVE
Definition Unit.h:1157
@ UNIT_FIELD_SHAPESHIFT_FORM
@ PLAYER_FIELD_LFG_BONUS_FACTION_ID
@ PLAYER_FIELD_XP
@ PLAYER_FIELD_HAIR_COLOR_ID
@ PLAYER_FIELD_WATCHED_FACTION_INDEX
@ PLAYER_FIELD_PLAYER_FLAGS
@ PLAYER_FIELD_REST_STATE
bool Utf8toWStr(char const *utf8str, size_t csize, wchar_t *wstr, size_t &wsize)
Definition Util.cpp:305
bool isCyrillicCharacter(wchar_t wchar)
Definition Util.h:172
void WriteGuidBytes(const ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:264
bool WriteBit(uint32 bit)
Definition ByteBuffer.h:164
void read_skip()
Definition ByteBuffer.h:502
size_t rpos() const
Definition ByteBuffer.h:470
void WriteGuidMask(const ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:248
void reserve(size_t ressize)
Definition ByteBuffer.h:619
void WriteString(std::string const &str)
Definition ByteBuffer.h:578
uint32 ReadBits(size_t bits)
Definition ByteBuffer.h:198
void ReadGuidBytes(ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:256
void ReadByteSeq(uint8 &b)
Definition ByteBuffer.h:215
void append(T value)
Definition ByteBuffer.h:147
void rfinish()
Definition ByteBuffer.h:478
std::string ReadString(size_t length)
Definition ByteBuffer.h:565
void PutBits(size_t pos, T value, uint32 bitCount)
Definition ByteBuffer.h:283
size_t wpos() const
Definition ByteBuffer.h:483
void ReadGuidMask(ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:240
void WriteBits(T value, size_t bits)
Definition ByteBuffer.h:192
size_t size() const
Definition ByteBuffer.h:609
void FlushBits()
Definition ByteBuffer.h:154
bool ReadBit()
Definition ByteBuffer.h:180
std::string Name
User specified variables.
uint8 CharCount
Server side data.
void PSendSysMessage(const char *format,...) ATTR_PRINTF(2
Definition Chat.cpp:221
Definition Field.h:16
uint8 GetUInt8() const
Definition Field.h:26
std::string GetString() const
Definition Field.h:228
uint16 GetUInt16() const
Definition Field.h:69
char const * GetCString() const
Definition Field.h:213
uint32 GetUInt32() const
Definition Field.h:105
int32 GetInt32() const
Definition Field.h:123
GameObjectTemplate const * GetGOInfo() const
Definition GameObject.h:643
Definition Group.h:147
Definition Guild.h:324
Definition Item.h:202
uint16 GetPos() const
Definition Item.h:269
uint64 GetGuid() const
uint32 GetAccountId() const
LoginQueryHolder(uint32 accountId, uint64 guid)
bool AddToMap(T *)
Definition Map.cpp:504
virtual bool AddPlayerToMap(Player *)
Definition Map.cpp:460
float GetFollowAngle() const OVERRIDE
static Player * FindPlayer(uint64)
uint64 GetGUID() const
Definition Object.h:119
uint32 GetGUIDLow() const
Definition Object.h:120
uint32 GetEntry() const
Definition Object.h:125
Creature * ToCreature()
Definition Object.h:207
bool HasFlag(uint16 index, uint32 flag) const
Definition Object.cpp:1309
void SetUInt32Value(uint16 index, uint32 value)
Definition Object.cpp:1038
void SetByteFlag(uint16 index, uint8 offset, uint8 newFlag)
Definition Object.cpp:1322
static bool CheckDeclinedNames(const std::wstring &w_ownname, DeclinedName const &names)
static ResponseCodes CheckPlayerName(std::string const &name, bool create=false)
UNORDERED_MAP< uint32, Quest * > QuestMap
Definition ObjectMgr.h:722
Definition Pet.h:28
void InitTalentForLevel()
Definition Pet.cpp:1828
void SavePetToDB(PetSaveMode mode)
Definition Pet.cpp:365
bool LoadPetFromDB(Player *owner, uint32 petentry=0, uint32 petnumber=0, bool current=false)
Definition Pet.cpp:91
static void resetTalentsForAllPetsOf(Player *owner, Pet *online_pet=NULL)
Definition Pet.cpp:1752
void SendInitialPacketsAfterAddToMap()
Definition Player.cpp:18646
void RemoveAtLoginFlag(AtLoginFlags flags, bool persist=false)
Definition Player.cpp:21581
void SetInGuild(uint32 guildId)
Definition Player.cpp:8009
void SendCinematicStart(uint32 CinematicSequenceId)
Definition Player.cpp:6960
static bool BuildEnumData(PreparedQueryResult result, ByteBuffer *dataBuffer, ByteBuffer *bitBuffer, bool boosted=false)
Definition Player.cpp:1860
float m_homebindZ
Definition Player.h:2851
uint32 GetGuildId() const
Definition Player.h:2291
uint32 m_homebindMapId
Definition Player.h:2847
bool CanTameExoticPets() const
Definition Player.h:2624
void SendDungeonDifficulty()
Definition Player.cpp:15489
bool Create(uint32 guidlow, CharacterCreateInfo *createInfo)
Definition Player.cpp:815
void CleanupsBeforeDelete(bool finalCleanup=true) override
Definition Player.cpp:802
void SendTalentsInfoData()
Definition Player.cpp:21306
void PetSpellInitialize()
Definition Player.cpp:15884
void ContinueTaxiFlight()
Definition Player.cpp:16756
void SendInitialPacketsBeforeAddToMap()
Definition Player.cpp:18521
void LoadCorpse()
Definition Player.cpp:13061
Pet * GetPet() const
Definition Player.cpp:15640
static void SavePositionInDB(uint32 mapid, float x, float y, float z, float o, uint32 zone, uint64 guid)
Definition Player.cpp:15406
void SetAtLoginFlag(AtLoginFlags f)
Definition Player.h:2880
WorldSession * GetSession() const
Definition Player.h:2417
bool ResetTalents(bool noCost=false, bool resetTalents=true, bool resetSpecialization=true)
Definition Player.cpp:4497
static uint32 TeamForRace(uint8 race)
Definition Player.cpp:7072
static void Customize(uint64 guid, uint8 gender, uint8 skin, uint8 face, uint8 hairStyle, uint8 hairColor, uint8 facialHair)
Definition Player.cpp:15432
float m_homebindY
Definition Player.h:2850
Group * GetGroup()
Definition Player.h:2972
bool LoadFromDB(uint32 guid, SQLQueryHolder *holder)
Definition Player.cpp:12180
bool IsGameMaster() const
Definition Player.h:1369
void LoadPet()
Definition Player.cpp:13494
uint8 getCinematic() const
Definition Player.h:2217
bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options=0)
Definition Player.cpp:2090
static void DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmChars=true, bool deleteFinally=false)
Definition Player.cpp:4775
void SetRank(uint8 rankId)
Definition Player.h:2271
void SaveToDB(bool create=false)
Definition Player.cpp:14300
static bool IsValidGender(uint8 Gender)
Definition Player.h:1898
bool HasAtLoginFlag(AtLoginFlags f) const
Definition Player.h:2876
static bool IsValidRace(uint8 Race)
Definition Player.h:1906
void SetGuildLevel(uint32 level)
Definition Player.h:2279
void SetTaxiCheater(bool on)
Definition Player.h:1386
void SetInGameTime(uint32 time)
Definition Player.h:1851
void setCinematic(uint8 cine)
Definition Player.h:2218
bool CheckInstanceLoginValid()
Definition Player.cpp:14198
ReputationMgr & GetReputationMgr()
Definition Player.h:2555
float m_homebindX
Definition Player.h:2849
void resetSpells(bool myClassOnly=false)
Definition Player.cpp:18782
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 setUInt64(const uint8 index, const uint64 value)
void setUInt32(const uint8 index, const uint32 value)
void setUInt8(const uint8 index, const uint8 value)
void setInt32(const uint8 index, const int32 value)
uint32 GetRequiredRaces() const
Definition QuestDef.h:278
uint32 GetQuestId() const
Definition QuestDef.h:270
void SetAtWar(FactionIndex FactionIndexID)
void SetNotAtWar(FactionIndex FactionIndexID)
void SetSize(size_t size)
PreparedQueryResult GetPreparedResult(size_t index)
bool bool SetPreparedQuery(size_t index, PreparedStatement *stmt)
SpellEffectInfo Effects[MAX_SPELL_EFFECTS]
Definition SpellInfo.h:255
size_type size() const
Definition Util.h:46
void SetMinion(Minion *minion, bool apply)
Definition Unit.cpp:2432
uint8 getGender() const
Definition Unit.h:1551
uint32 getVirtualRealm() const
Definition Unit.h:1555
void SetContestedPvP(Player *attackedPlayer=NULL)
void CastSpell(SpellCastTargets const &targets, SpellInfo const *spellInfo, CustomSpellValues const *value, TriggerCastFlags triggerFlags=TRIGGERED_NONE, Item *castItem=NULL, AuraEffect const *triggeredByAura=NULL, uint64 originalCaster=0)
Pet * CreateTamedPetFrom(Creature *creatureTarget, uint32 spell_id=0)
Definition Unit.cpp:6255
MotionMaster * GetMotionMaster()
Definition Unit.h:2605
uint8 getClass() const
Definition Unit.h:1543
DeathState m_deathState
Definition Unit.h:2883
bool IsStandState() const
Definition Unit.cpp:5896
bool HasUnitState(const uint32 f) const
Definition Unit.h:1485
uint8 getLevel() const
Definition Unit.h:1528
void SetStandState(uint8 state)
Definition Unit.cpp:5902
bool SetWaterWalking(bool enable, bool packetOnly=false)
Definition Unit.cpp:9245
uint8 getRace() const
Definition Unit.h:1535
uint32 GetMapId() const
Definition Object.h:546
Map * GetMap() const
Definition Object.h:740
std::string const & GetName() const
Definition Object.h:664
void GetClosePoint(float &x, float &y, float &z, float size, float distance2d=0, float angle=0) const
Definition Object.cpp:3070
float GetObjectSize() const
Definition Object.cpp:3100
void Initialize(Opcodes opcode, size_t newres=200)
Definition WorldPacket.h:31
QueryCallback< PreparedQueryResult, CharacterCreateInfo *, true > _charCreateCallback
void SetPlayer(Player *player)
void HandleCharCustomize(WorldPacket &recvData)
void KickPlayer()
Kick a player out of the World.
void HandleEquipmentSetUse(WorldPacket &recvData)
void HandlePlayerLoginOpcode(WorldPacket &recvPacket)
void HandleAlterAppearance(WorldPacket &recvData)
void HandleShowingHelmOpcode(WorldPacket &recvData)
void HandleSetFactionAtWar(WorldPacket &recvData)
void HandleCharEnumOpcode(WorldPacket &recvPacket)
void HandleSetLfgBonusFactionID(WorldPacket &recvData)
void SendNotification(const char *format,...) ATTR_PRINTF(2
void HandleCharFactionOrRaceChange(WorldPacket &recvData)
void HandleSetWatchedFactionOpcode(WorldPacket &recvData)
void HandleSetFactionNotAtWar(WorldPacket &recvData)
void HandleSetFactionInactiveOpcode(WorldPacket &recvData)
void HandlePlayerLogin(LoginQueryHolder *holder)
void LoadAccountData(PreparedQueryResult result, uint32 mask)
void HandleCharCreateCallback(PreparedQueryResult result, CharacterCreateInfo *createInfo)
void HandleLoadScreenOpcode(WorldPacket &recvPacket)
void HandleRandomizeCharNameOpcode(WorldPacket &recvData)
void HandleTutorialFlag(WorldPacket &recvData)
std::string GetPlayerInfo() const
void HandleSetFactionCheat(WorldPacket &recvData)
Player * GetPlayer() const
bool PlayerLoading() const
PreparedQueryResultFuture _charEnumCallback
void HandleChangePlayerNameOpcodeCallBack(PreparedQueryResult result, std::string const &newName)
void HandleEquipmentSetDelete(WorldPacket &recvData)
void HandleOpeningCinematic(WorldPacket &recvData)
QueryCallback< PreparedQueryResult, std::string > _charRenameCallback
void HandleShowingCloakOpcode(WorldPacket &recvData)
void SendBarberShopResult(BarberShopResult result)
uint32 GetVirtualRealmID() const
QueryResultHolderFuture _charLoginCallback
void HandleCharDeleteOpcode(WorldPacket &recvPacket)
void HandleReorderCharacters(WorldPacket &recvData)
void HandleCharEnum(PreparedQueryResult result)
std::set< uint32 > _legitCharacters
bool HasPermission(uint32 permissionId)
void SendTimezoneInformation()
void SendPacket(WorldPacket const *packet, bool forced=false)
Send a packet to the client.
uint32 GetAccountId() const
Player * _player
void HandleRequestForcedReactionsOpcode(WorldPacket &recvData)
uint32 GetTutorialInt(uint8 index) const
CharacterBooster * m_charBooster
void HandleCharCreateOpcode(WorldPacket &recvPacket)
std::string const & GetRemoteAddress()
void HandleEquipmentSetSave(WorldPacket &recvData)
void HandleSetPlayerDeclinedNames(WorldPacket &recvData)
void SendAccountDataTimes(uint32 mask)
void HandleTutorialReset(WorldPacket &recvData)
bool IsLegitCharacterForAccount(uint32 lowGUID)
void HandleCharRenameOpcode(WorldPacket &recvData)
void SetTutorialInt(uint8 index, uint32 value)
void SendCharacterLoginFailed(ResponseCodes reason)
void HandleTutorialClear(WorldPacket &recvData)
CharacterDatabaseWorkerPool CharacterDatabase
Accessor to the character database.
Definition Main.cpp:41
#define PER_CHARACTER_CACHE_MASK
BarberShopResult
@ SMSG_USE_EQUIPMENT_SET_RESULT
Definition Opcodes.h:1059
@ SMSG_CHAR_RENAME
Definition Opcodes.h:609
@ SMSG_PVP_SEASON
Definition Opcodes.h:894
@ SMSG_CHAR_CREATE
Definition Opcodes.h:605
@ SMSG_CHAR_FACTION_CHANGE
Definition Opcodes.h:608
@ SMSG_SET_PLAYER_DECLINED_NAMES_RESULT
Definition Opcodes.h:960
@ SMSG_RANDOMIZE_CHAR_NAME
Definition Opcodes.h:925
@ SMSG_MOTD
Definition Opcodes.h:785
@ SMSG_HOTFIX_NOTIFY_BLOB
Definition Opcodes.h:718
@ SMSG_LOGIN_VERIFY_WORLD
Definition Opcodes.h:761
@ SMSG_BARBER_SHOP_RESULT
Definition Opcodes.h:535
@ SMSG_CHAR_DELETE
Definition Opcodes.h:607
@ SMSG_CHAR_CUSTOMIZE
Definition Opcodes.h:606
@ SMSG_ENUM_CHARACTERS_RESULT
Definition Opcodes.h:650
@ SMSG_FEATURE_SYSTEM_STATUS
Definition Opcodes.h:654
#define sWorld
Definition World.h:910
@ CONFIG_CHARACTERS_PER_ACCOUNT
Definition World.h:219
@ CONFIG_CHARACTER_CREATING_MIN_LEVEL_FOR_HEROIC_CHARACTER
Definition World.h:222
@ CONFIG_CHARACTER_CREATING_DISABLED_RACEMASK
Definition World.h:217
@ CONFIG_CHARACTER_CREATING_DISABLED_CLASSMASK
Definition World.h:218
@ CONFIG_CHARACTERS_PER_REALM
Definition World.h:220
@ CONFIG_SKIP_CINEMATICS
Definition World.h:223
@ CONFIG_CHARACTER_CREATING_DISABLED
Definition World.h:216
@ CONFIG_MAX_PLAYER_LEVEL
Definition World.h:224
@ CONFIG_ARENA_SEASON_ID
Definition World.h:298
@ CONFIG_HEROIC_CHARACTERS_PER_REALM
Definition World.h:221
@ CONFIG_ENABLE_SINFO_LOGIN
Definition World.h:309
@ CONFIG_TICKETS_FEEDBACK_SYSTEM_ENABLED
Definition World.h:168
@ CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD
Definition World.h:99
@ CONFIG_ALL_TAXI_PATHS
Definition World.h:102
@ CONFIG_DECLINED_NAMES_USED
Definition World.h:124
@ RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_TEAMMASK
Definition RBAC.h:54
@ RBAC_PERM_TWO_SIDE_CHARACTER_CREATION
Definition RBAC.h:64
@ RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME
Definition RBAC.h:57
@ RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RACEMASK
Definition RBAC.h:56
@ RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_CLASSMASK
Definition RBAC.h:55
@ RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_HEROIC_CHARACTER
Definition RBAC.h:58
@ RBAC_PERM_TWO_SIDE_ADD_FRIEND
Definition RBAC.h:69
LoginDatabaseWorkerPool LoginDatabase
Definition Main.cpp:54
uint32 type
uint32 race
uint32 gender
uint32 hair_id
uint32 bit_index
uint32 GetFirstValidModelId() const
Definition Creature.cpp:92
std::string Name
Definition Creature.h:71
bool IsTameable(bool canTameExotic) const
Definition Creature.h:153
uint32 nameLength[MAX_DECLINED_NAME_CASES]
Definition Unit.h:1103
std::string name[MAX_DECLINED_NAME_CASES]
Definition Unit.h:1102
std::string Name
Definition Player.h:759
std::string IconName
Definition Player.h:760
EquipmentSetUpdateState state
Definition Player.h:763
uint32 Items[EQUIPMENT_SLOT_END]
Definition Player.h:762
uint64 Guid
Definition Player.h:758
uint32 IgnoreMask
Definition Player.h:761
struct GameObjectTemplate::@046065176235271051340241126110345143267101032070::@114312050106372302366137106154036240136321221160 barberChair
PlayerCreateInfoSpells spell_cast
Definition Player.h:435
float GetPositionZ() const
Definition Object.h:330
float GetOrientation() const
Definition Object.h:331
bool IsPositionValid() const
Definition Object.cpp:2049
float GetPositionX() const
Definition Object.h:328
float GetPositionY() const
Definition Object.h:329
void Relocate(float x, float y)
Definition Object.h:302
const uint32 CreatureEntry[3]