Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
PetitionsHandler.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 "ArenaTeam.h"
7#include "ArenaTeamMgr.h"
8#include "Common.h"
9#include "GossipDef.h"
10#include "Guild.h"
11#include "GuildMgr.h"
12#include "Language.h"
13#include "Log.h"
14#include "ObjectMgr.h"
15#include "Opcodes.h"
16#include "SocialMgr.h"
17#include "World.h"
18#include "WorldPacket.h"
19#include "WorldSession.h"
20
21#define CHARTER_DISPLAY_ID 16161
22
23constexpr uint32 GUILD_CHARTER = 5863;
24constexpr uint64 GUILD_CHARTER_COST = 1000;
26
28{
29 SF_LOG_DEBUG("network", "Received opcode CMSG_PETITION_BUY");
30
31 ObjectGuid npcGuid;
32 uint8 nameLen;
33 std::string name;
34
35 recvData.ReadGuidMask(npcGuid, 5, 2, 3);
36 nameLen = recvData.ReadBits(7);
37 recvData.ReadGuidMask(npcGuid, 4, 1, 7, 0, 6);
38
39 name = recvData.ReadString(nameLen);
40 recvData.ReadGuidBytes(npcGuid, 1, 7, 4, 6, 0, 5, 2, 3);
41
42 SF_LOG_DEBUG("network", "Petitioner with GUID %u tried sell petition: name %s", GUID_LOPART(npcGuid), name.c_str());
43
44 // prevent cheating
46 if (!creature)
47 {
48 SF_LOG_DEBUG("network", "WORLD: HandlePetitionBuyOpcode - Unit (GUID: %u) not found or you can't interact with him.", GUID_LOPART(npcGuid));
49 return;
50 }
51
52 // remove fake death
53 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
55
56 // if tabard designer, then trying to buy a guild charter.
57 // do not let if already in guild.
58 if (_player->GetGuildId())
59 return;
60
61 if (sGuildMgr->GetGuildByName(name))
62 {
64 return;
65 }
66
67 if (sObjectMgr->IsReservedName(name) || !ObjectMgr::IsValidCharterName(name))
68 {
70 return;
71 }
72
73 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(GUILD_CHARTER);
74 if (!pProto)
75 {
77 return;
78 }
79
80 if (!_player->HasEnoughMoney(uint64(GUILD_CHARTER_COST)))
81 { //player hasn't got enough money
83 return;
84 }
85
86 ItemPosCountVec dest;
87 InventoryResult msg = _player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, GUILD_CHARTER, pProto->BuyCount);
88 if (msg != EQUIP_ERR_OK)
89 {
90 _player->SendEquipError(msg, NULL, NULL, GUILD_CHARTER);
91 return;
92 }
93
94 _player->ModifyMoney(-(int32)GUILD_CHARTER_COST);
95 Item* charter = _player->StoreNewItem(dest, GUILD_CHARTER, true);
96 if (!charter)
97 return;
98
100 // ITEM_FIELD_ENCHANTMENT is guild/arenateam id
101 // ITEM_FIELD_ENCHANTMENT+1 is current signatures count (showed on item)
102 charter->SetState(ITEM_CHANGED, _player);
103 _player->SendNewItem(charter, 1, true, false);
104
105 // a petition is invalid, if both the owner and the type matches
106 // we checked above, if this player is in an arenateam, so this must be
107 // datacorruption
109 stmt->setUInt32(0, _player->GetGUIDLow());
111 PreparedQueryResult result = CharacterDatabase.Query(stmt);
112
113 std::ostringstream ssInvalidPetitionGUIDs;
114
115 if (result)
116 {
117 do
118 {
119 Field* fields = result->Fetch();
120 ssInvalidPetitionGUIDs << '\'' << fields[0].GetUInt32() << "', ";
121 } while (result->NextRow());
122 }
123
124 // delete petitions with the same guid as this one
125 ssInvalidPetitionGUIDs << '\'' << charter->GetGUIDLow() << '\'';
126
127 SF_LOG_DEBUG("network", "Invalid petition GUIDs: %s", ssInvalidPetitionGUIDs.str().c_str());
128 CharacterDatabase.EscapeString(name);
129 SQLTransaction trans = CharacterDatabase.BeginTransaction();
130 trans->PAppend("DELETE FROM petition WHERE petitionguid IN (%s)", ssInvalidPetitionGUIDs.str().c_str());
131 trans->PAppend("DELETE FROM petition_sign WHERE petitionguid IN (%s)", ssInvalidPetitionGUIDs.str().c_str());
132
133 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_PETITION);
134 stmt->setUInt32(0, _player->GetGUIDLow());
135 stmt->setUInt32(1, charter->GetGUIDLow());
136 stmt->setString(2, name);
138 trans->Append(stmt);
139
140 CharacterDatabase.CommitTransaction(trans);
141}
142
144{
145 SF_LOG_DEBUG("network", "Received opcode CMSG_PETITION_SHOW_SIGNATURES");
146
147 uint8 playerCount = 0;
148 ObjectGuid petitionGuid;
149
150 recvData.ReadGuidMask(petitionGuid, 3, 7, 2, 4, 5, 6, 0, 1);
151 recvData.ReadGuidBytes(petitionGuid, 2, 4, 5, 7, 1, 0, 3, 6);
152
153 // solve (possible) some strange compile problems with explicit use GUID_LOPART(petitionguid) at some GCC versions (wrong code optimization in compiler?)
154 uint32 petitionGuidLow = GUID_LOPART(petitionGuid);
155
156 // if guild petition and has guild => error, return;
157 if (_player->GetGuildId())
158 return;
159
161
162 stmt->setUInt32(0, petitionGuidLow);
163
164 PreparedQueryResult result = CharacterDatabase.Query(stmt);
165
166 // result == NULL also correct in case no sign yet
167 if (result)
168 playerCount = uint8(result->GetRowCount());
169
170 SF_LOG_DEBUG("network", "CMSG_PETITION_SHOW_SIGNATURES petition entry: '%u'", petitionGuidLow);
171
172 ObjectGuid playerGuid = _player->GetGUID();
173 ObjectGuid* playerGuids = new ObjectGuid[playerCount];
174
175 for (uint8 i = 0; i < playerCount; ++i)
176 {
177 Field* fields2 = result->Fetch();
178 uint32 lowGuid = fields2[0].GetUInt32();
179 playerGuids[i] = MAKE_NEW_GUID(lowGuid, 0, HIGHGUID_PLAYER);
180 result->NextRow();
181 }
182
183 WorldPacket data(SMSG_PETITION_SHOW_SIGNATURES, (8 + 8 + 3 + (playerCount * (8 + 4)) + 4));
184 data.WriteGuidMask(playerGuid, 1);
185 data.WriteGuidMask(petitionGuid, 3);
186 data.WriteGuidMask(playerGuid, 3);
187 data.WriteGuidMask(petitionGuid, 4, 0);
188 data.WriteGuidMask(playerGuid, 7, 5);
189 data.WriteGuidMask(petitionGuid, 1, 5, 7);
190 data.WriteGuidMask(playerGuid, 0, 6);
191 data.WriteGuidMask(petitionGuid, 6);
192 data.WriteGuidMask(playerGuid, 2, 4);
193
194 data.WriteBits(playerCount, 21);
195
196 for (int i = 0; i < playerCount; i++)
197 {
198 data.WriteGuidMask(playerGuids[i], 2, 0, 4, 7, 5, 1, 6, 3);
199 }
200 data.WriteGuidMask(petitionGuid, 2);
201 data.FlushBits();
202
203 for (int i = 0; i < playerCount; i++)
204 {
205 data.WriteGuidBytes(playerGuids[i], 6, 0, 1, 3, 2, 5, 7, 4);
206 data << uint32(1); // Choice ??? Blizzard also stores declined players ???
207 }
208
209 data.WriteGuidBytes(petitionGuid, 6, 5, 4);
210 data.WriteGuidBytes(playerGuid, 4);
211 data.WriteGuidBytes(petitionGuid, 1);
212 data << uint32(petitionGuidLow); // guildID
213 data.WriteGuidBytes(petitionGuid, 2, 3, 7);
214 data.WriteGuidBytes(playerGuid, 5, 6, 3, 7, 1, 0);
215 data.WriteGuidBytes(petitionGuid, 0);
216 data.WriteGuidBytes(playerGuid, 2);
217 delete[] playerGuids;
218 SendPacket(&data);
219}
220
222{
223 SF_LOG_DEBUG("network", "Received opcode CMSG_PETITION_QUERY"); // ok
224
225 uint32 guildguid;
226 ObjectGuid petitionGuid;
227
228 recvData >> guildguid; // in Skyfire always same as GUID_LOPART(petitionguid)
229
230 recvData.ReadGuidMask(petitionGuid, 2, 3, 1, 0, 4, 7, 6, 5);
231 recvData.ReadGuidBytes(petitionGuid, 0, 4, 7, 5, 1, 6, 3, 2);
232
233 SF_LOG_DEBUG("network", "CMSG_PETITION_QUERY Petition GUID %u Guild GUID %u", GUID_LOPART(petitionGuid), guildguid);
234
235 SendPetitionQueryOpcode(petitionGuid);
236}
237
239{
240 ObjectGuid ownerGuid = 0;
241 uint32 type;
242 std::string name = "NO_NAME_FOR_GUID";
243
244 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION);
245
246 stmt->setUInt32(0, GUID_LOPART(petitionGuid));
247
248 PreparedQueryResult result = CharacterDatabase.Query(stmt);
249
250 if (result)
251 {
252 Field* fields = result->Fetch();
253 ownerGuid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER);
254 name = fields[1].GetString();
255 type = fields[2].GetUInt8();
256 }
257 else
258 {
259 SF_LOG_DEBUG("network", "CMSG_PETITION_QUERY failed for petition (GUID: %u)", GUID_LOPART(petitionGuid));
260 return;
261 }
262
263 WorldPacket data(SMSG_PETITION_QUERY_RESPONSE, (8 + 2 + 1 + name.size() + (13 * 4) + 2));
264 data << uint32(GUID_LOPART(petitionGuid)); // guild/team guid (in Skyfire always same as GUID_LOPART(petition guid)
265 data.WriteBit(1); // hasData;
266
267 for (int i = 0; i < 10; i++)
268 data.WriteBits(0, 6); // Unk strings;
269
270 data.WriteGuidMask(ownerGuid, 2, 4);
271 data.WriteBits(0, 12);
272 data.WriteGuidMask(ownerGuid, 0, 7, 3, 6, 5);
273 data.WriteBits(name.size(), 7); //NameLen
274 data.WriteGuidMask(ownerGuid, 1);
275
276 data.FlushBits();
277
278 data.WriteGuidBytes(ownerGuid, 5);
279 data << uint32(0);
280 data.WriteString(name);
281 data << uint32(0);
282 data.WriteGuidBytes(ownerGuid, 4);
283 data << uint32(type); // Type - 4 guild
284 data.WriteGuidBytes(ownerGuid, 6);
285 data << uint32(0);
286 data << uint32(sWorld->getIntConfig(WorldIntConfigs::CONFIG_MIN_PETITION_SIGNS)); // Required sign count
287 data.WriteGuidBytes(ownerGuid, 1, 7, 0);
288 data << uint32(0);
289 data << uint32(0);
290 data.WriteGuidBytes(ownerGuid, 2);
291 data << uint32(time(NULL) + YEAR); // Deadline
292 data << uint16(0);
293 data << uint32(0);
294 data.WriteGuidBytes(ownerGuid, 3);
295 data << uint32(0);
296 data << uint32(0);
297 data << uint32(0);
298 data << uint32(0);
299
300 SendPacket(&data);
301}
302
304{
305 SF_LOG_DEBUG("network", "Received opcode CMSG_PETITION_RENAME");
306
307 ObjectGuid petitionGuid;
308 uint32 type;
309 uint8 nameLen;
310 std::string newName;
311
312 nameLen = recvData.ReadBits(7);
313 recvData.ReadGuidMask(petitionGuid, 7, 4, 6, 2, 0, 5, 3, 1);
314 recvData.ReadGuidBytes(petitionGuid, 4, 1, 7);
315 newName = recvData.ReadString(nameLen);
316 recvData.ReadGuidBytes(petitionGuid, 0, 3, 2, 6, 5);
317
318 Item* item = _player->GetItemByGuid(petitionGuid);
319 if (!item)
320 return;
321
322 if (sGuildMgr->GetGuildByName(newName))
323 {
325 return;
326 }
327 if (sObjectMgr->IsReservedName(newName) || !ObjectMgr::IsValidCharterName(newName))
328 {
330 return;
331 }
332
333 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_PETITION_NAME);
334
335 stmt->setString(0, newName);
336 stmt->setUInt32(1, GUID_LOPART(petitionGuid));
337
338 CharacterDatabase.Execute(stmt);
339
340 SF_LOG_DEBUG("network", "Petition (GUID: %u) renamed to '%s'", GUID_LOPART(petitionGuid), newName.c_str());
341
342 WorldPacket data(SMSG_PETITION_RENAME_RESULT, (9 + 1 + newName.size()));
343 data.WriteBits(newName.length(), 7);
344 data.WriteGuidMask(petitionGuid, 0, 3, 4, 2, 6, 5, 7, 1);
345 data.FlushBits();
346 data.WriteGuidBytes(petitionGuid, 4, 3, 6, 0, 5, 2, 1, 7);
347 data.WriteString(newName);
348 SendPacket(&data);
349}
350
352{
353 SF_LOG_DEBUG("network", "Received opcode CMSG_PETITION_SIGN"); // ok
354
355 Field* fields;
356 ObjectGuid petitionGuid;
357
358 recvData.read_skip<uint8>();
359 recvData.ReadGuidMask(petitionGuid, 4, 2, 0, 1, 5, 3, 6, 7);
360 recvData.ReadGuidBytes(petitionGuid, 6, 1, 7, 2, 5, 3, 0, 4);
361
363
364 stmt->setUInt32(0, GUID_LOPART(petitionGuid));
365 stmt->setUInt32(1, GUID_LOPART(petitionGuid));
366
367 PreparedQueryResult result = CharacterDatabase.Query(stmt);
368
369 if (!result)
370 {
371 SF_LOG_ERROR("network", "Petition %u is not found for player %u %s", GUID_LOPART(petitionGuid), GetPlayer()->GetGUIDLow(), GetPlayer()->GetName().c_str());
372 return;
373 }
374
375 fields = result->Fetch();
376 uint64 ownerGuid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER);
377 uint64 signs = fields[1].GetUInt64();
378 uint8 type = fields[2].GetUInt8();
379
380 uint32 playerGuid = _player->GetGUIDLow();
381 if (GUID_LOPART(ownerGuid) == playerGuid)
382 return;
383
384 // not let enemies sign guild charter
385 if (!sWorld->GetBoolConfig(WorldBoolConfigs::CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && GetPlayer()->GetTeam() != sObjectMgr->GetPlayerTeamByGUID(ownerGuid))
386 {
388 return;
389 }
390
391 if (_player->GetGuildId())
392 {
394 return;
395 }
396 if (_player->GetGuildIdInvited())
397 {
399 return;
400 }
401
402 if (++signs > type) // client signs maximum
403 return;
404
405 // Client doesn't allow to sign petition two times by one character, but not check sign by another character from same account
406 // not allow sign another player from already sign player account
407 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION_SIG_BY_ACCOUNT);
408
409 stmt->setUInt32(0, GetAccountId());
410 stmt->setUInt32(1, GUID_LOPART(petitionGuid));
411
412 result = CharacterDatabase.Query(stmt);
413
414 if (result)
415 {
416 // close at signer side
418 return;
419 }
420
421 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_PETITION_SIGNATURE);
422
423 stmt->setUInt32(0, GUID_LOPART(ownerGuid));
424 stmt->setUInt32(1, GUID_LOPART(petitionGuid));
425 stmt->setUInt32(2, playerGuid);
426 stmt->setUInt32(3, GetAccountId());
427
428 CharacterDatabase.Execute(stmt);
429
430 SF_LOG_DEBUG("network", "PETITION SIGN: GUID %u by player: %s (GUID: %u Account: %u)", GUID_LOPART(petitionGuid), _player->GetName().c_str(), playerGuid, GetAccountId());
431
432 // close at signer side
433 SendPetitionSignResults(petitionGuid, _player->GetGUID(), PETITION_SIGN_OK);
434
435 // update signs count on charter, required testing...
436 //Item* item = _player->GetItemByGuid(petitionguid));
437 //if (item)
438 // item->SetUInt32Value(ITEM_FIELD_ENCHANTMENT+1, signs);
439
440 // update for owner if online
441 if (Player* owner = ObjectAccessor::FindPlayer(ownerGuid))
442 owner->GetSession()->SendPetitionSignResults(petitionGuid, _player->GetGUID(), PETITION_SIGN_OK);
443}
444
446{
447 SF_LOG_DEBUG("network", "Received opcode MSG_PETITION_DECLINE"); // ok
448
449 ObjectGuid petitionGuid;
450 uint64 ownerGuid;
451
452 recvData.ReadGuidMask(petitionGuid, 5, 6, 4, 3, 1, 7, 0, 2);
453 recvData.ReadGuidBytes(petitionGuid, 6, 2, 1, 5, 0, 7, 4, 3);
454
455 SF_LOG_DEBUG("network", "Petition %u declined by %u", GUID_LOPART(petitionGuid), _player->GetGUIDLow());
456
458
459 stmt->setUInt32(0, GUID_LOPART(petitionGuid));
460
461 PreparedQueryResult result = CharacterDatabase.Query(stmt);
462
463 if (!result)
464 return;
465
466 Field* fields = result->Fetch();
467 ownerGuid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER);
468
469 Player* owner = ObjectAccessor::FindPlayer(ownerGuid);
470 if (owner) // petition owner online
471 owner->GetSession()->SendPetitionSignResults(petitionGuid, _player->GetGUID(), PETITION_SIGN_OK);
472}
473
475{
476 SF_LOG_DEBUG("network", "Received opcode CMSG_OFFER_PETITION"); // ok
477
478 uint8 playerCount = 0;
479 ObjectGuid petitionGuid, playerGuid;
480 uint32 type;
481 Player* player;
482
483 recvData.read_skip<uint32>();
484 recvData.ReadGuidMask(playerGuid, 4, 1);
485 recvData.ReadGuidMask(petitionGuid, 2);
486 recvData.ReadGuidMask(playerGuid, 6);
487 recvData.ReadGuidMask(petitionGuid, 1);
488 recvData.ReadGuidMask(playerGuid, 2);
489 recvData.ReadGuidMask(petitionGuid, 4);
490 recvData.ReadGuidMask(playerGuid, 3, 7);
491 recvData.ReadGuidMask(petitionGuid, 0, 6);
492 recvData.ReadGuidMask(playerGuid, 5, 0);
493 recvData.ReadGuidMask(petitionGuid, 3, 5, 7);
494
495 recvData.ReadGuidBytes(playerGuid, 7);
496 recvData.ReadGuidBytes(petitionGuid, 1, 4, 2);
497 recvData.ReadGuidBytes(playerGuid, 6);
498 recvData.ReadGuidBytes(petitionGuid, 3, 0, 5);
499 recvData.ReadGuidBytes(playerGuid, 0, 2, 5, 3, 4);
500 recvData.ReadGuidBytes(petitionGuid, 7);
501 recvData.ReadGuidBytes(playerGuid, 1);
502 recvData.ReadGuidBytes(petitionGuid, 6);
503
504 player = ObjectAccessor::FindPlayer(playerGuid);
505 if (!player)
506 return;
507
508 if (!sWorld->GetBoolConfig(WorldBoolConfigs::CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && GetPlayer()->GetTeam() != player->GetTeam())
509 {
511 return;
512 }
513
514 if (player->GetGuildId())
515 {
517 return;
518 }
519
520 if (player->GetGuildIdInvited())
521 {
523 return;
524 }
525
527
528 stmt->setUInt32(0, GUID_LOPART(petitionGuid));
529
530 PreparedQueryResult result = CharacterDatabase.Query(stmt);
531
532 // result == NULL also correct charter without signs
533 if (result)
534 playerCount = uint8(result->GetRowCount());
535
536 ObjectGuid* playerGuids = new ObjectGuid[playerCount];
537
538 for (uint8 i = 0; i < playerCount; ++i)
539 {
540 Field* fields2 = result->Fetch();
541 uint32 lowGuid = fields2[0].GetUInt32();
542 playerGuids[i] = MAKE_NEW_GUID(lowGuid, 0, HIGHGUID_PLAYER);
543 result->NextRow();
544 }
545
546 WorldPacket data(SMSG_PETITION_SHOW_SIGNATURES, (8 + 8 + 3 + (playerCount * (8 + 4)) + 4));
547 data.WriteGuidMask(playerGuid, 1);
548 data.WriteGuidMask(petitionGuid, 3);
549 data.WriteGuidMask(playerGuid, 3);
550 data.WriteGuidMask(petitionGuid, 4, 0);
551 data.WriteGuidMask(playerGuid, 7, 5);
552 data.WriteGuidMask(petitionGuid, 1, 5, 7);
553 data.WriteGuidMask(playerGuid, 0, 6);
554 data.WriteGuidMask(petitionGuid, 6);
555 data.WriteGuidMask(playerGuid, 2, 4);
556
557 data.WriteBits(playerCount, 21);
558
559 for (int i = 0; i < playerCount; i++)
560 {
561 data.WriteGuidMask(playerGuids[i], 2, 0, 4, 7, 5, 1, 6, 3);
562 }
563 data.WriteGuidMask(petitionGuid, 2);
564 data.FlushBits();
565
566 for (int i = 0; i < playerCount; i++)
567 {
568 data.WriteGuidBytes(playerGuids[i], 6, 0, 1, 3, 2, 5, 7, 4);
569 data << uint32(1); // Choice ??? Blizzard also stores declined players ???
570 }
571
572 data.WriteGuidBytes(petitionGuid, 6, 5, 4);
573 data.WriteGuidBytes(playerGuid, 4);
574 data.WriteGuidBytes(petitionGuid, 1);
575 data << uint32(GUID_LOPART(petitionGuid)); // guildID
576 data.WriteGuidBytes(petitionGuid, 2, 3, 7);
577 data.WriteGuidBytes(playerGuid, 5, 6, 3, 7, 1, 0);
578 data.WriteGuidBytes(petitionGuid, 0);
579 data.WriteGuidBytes(playerGuid, 2);
580 delete[] playerGuids;
581 SendPacket(&data);
582 player->GetSession()->SendPacket(&data);
583}
584
586{
587 SF_LOG_DEBUG("network", "Received opcode CMSG_TURN_IN_PETITION");
588
589 // Get petition guid from packet
590 WorldPacket data;
591 ObjectGuid petitionGuid;
592
593 recvData.ReadGuidMask(petitionGuid, 1, 2, 3, 0, 5, 7, 4, 6);
594 recvData.ReadGuidBytes(petitionGuid, 2, 1, 4, 6, 0, 7, 5, 3);
595
596 // Check if player really has the required petition charter
597 Item* item = _player->GetItemByGuid(petitionGuid);
598 if (!item)
599 return;
600
601 SF_LOG_DEBUG("network", "Petition %u turned in by %u", GUID_LOPART(petitionGuid), _player->GetGUIDLow());
602
603 // Get petition data from db
604 uint32 ownerguidlo;
605 uint32 type;
606 std::string name;
607
608 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION);
609 stmt->setUInt32(0, GUID_LOPART(petitionGuid));
610 PreparedQueryResult result = CharacterDatabase.Query(stmt);
611
612 if (result)
613 {
614 Field* fields = result->Fetch();
615 ownerguidlo = fields[0].GetUInt32();
616 name = fields[1].GetString();
617 type = fields[2].GetUInt8();
618 }
619 else
620 {
621 SF_LOG_ERROR("network", "Player %s (guid: %u) tried to turn in petition (guid: %u) that is not present in the database", _player->GetName().c_str(), _player->GetGUIDLow(), GUID_LOPART(petitionGuid));
622 return;
623 }
624
625 // Only the petition owner can turn in the petition
626 if (_player->GetGUIDLow() != ownerguidlo)
627 return;
628
629 // Petition type (guild/arena) specific checks
630 // Check if player is already in a guild
631 if (_player->GetGuildId())
632 {
635 data.FlushBits();
636 _player->GetSession()->SendPacket(&data);
637 return;
638 }
639
640 // Check if guild name is already taken
641 if (sGuildMgr->GetGuildByName(name))
642 {
644 return;
645 }
646
647 // Get petition signatures from db
648 uint8 signatures;
649
650 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION_SIGNATURE);
651 stmt->setUInt32(0, GUID_LOPART(petitionGuid));
652 result = CharacterDatabase.Query(stmt);
653
654 if (result)
655 signatures = uint8(result->GetRowCount());
656 else
657 signatures = 0;
658
659 uint32 requiredSignatures = sWorld->getIntConfig(WorldIntConfigs::CONFIG_MIN_PETITION_SIGNS);
660
661 // Notify player if signatures are missing
662 if (signatures < requiredSignatures)
663 {
666 data.FlushBits();
667 SendPacket(&data);
668 return;
669 }
670
671 // Proceed with guild/arena team creation
672
673 // Delete charter item
674 _player->DestroyItem(item->GetBagSlot(), item->GetSlot(), true);
675
676 // Create guild
677 Guild* guild = new Guild;
678
679 if (!guild->Create(_player, name))
680 {
681 delete guild;
682 return;
683 }
684
685 // Register guild and add guild master
686 sGuildMgr->AddGuild(guild);
687
689
690 // Add members from signatures
691 for (uint8 i = 0; i < signatures; ++i)
692 {
693 Field* fields = result->Fetch();
694 guild->AddMember(MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER));
695 result->NextRow();
696 }
697
698 SQLTransaction trans = CharacterDatabase.BeginTransaction();
699
700 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PETITION_BY_GUID);
701 stmt->setUInt32(0, GUID_LOPART(petitionGuid));
702 trans->Append(stmt);
703
704 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PETITION_SIGNATURE_BY_GUID);
705 stmt->setUInt32(0, GUID_LOPART(petitionGuid));
706 trans->Append(stmt);
707
708 CharacterDatabase.CommitTransaction(trans);
709
710 // created
711 SF_LOG_DEBUG("network", "TURN IN PETITION GUID %u", GUID_LOPART(petitionGuid));
712
715 data.FlushBits();
716 SendPacket(&data);
717}
718
720{
721 SF_LOG_DEBUG("network", "Received CMSG_PETITION_SHOWLIST");
722
723 ObjectGuid guid;
724
725 recvData.ReadGuidMask(guid, 1, 7, 2, 5, 4, 0, 3, 6);
726 recvData.ReadGuidBytes(guid, 6, 3, 2, 4, 1, 7, 5, 0);
727
729 if (!unit)
730 {
731 SF_LOG_DEBUG("network", "WORLD: HandlePetitionerShowListOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)));
732 return;
733 }
734
736}
737
739{
741 if (!creature)
742 {
743 SF_LOG_DEBUG("network", "WORLD: HandlePetitionShowListOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)));
744 return;
745 }
746
747 ObjectGuid npcGuid = guid;
748
750 data.WriteGuidMask(npcGuid, 3, 5, 7, 6, 1, 0, 2, 4);
751 data.WriteGuidMask(npcGuid, 6, 0, 1);
752
753 data << uint32(GUILD_CHARTER_COST); // Petition Cost
754 data.WriteGuidBytes(npcGuid, 4, 3, 5, 2, 7);
755
756 SendPacket(&data);
757 SF_LOG_DEBUG("network", "Sent SMSG_PETITION_SHOWLIST");
758}
759
761{
763 data.WriteGuidMask(playerGuid, 2, 0);
764 data.WriteGuidMask(petitionGuid, 0);
765 data.WriteGuidMask(playerGuid, 1);
766 data.WriteGuidMask(petitionGuid, 5, 2, 4);
767 data.WriteGuidMask(playerGuid, 6);
768 data.WriteGuidMask(petitionGuid, 1, 6);
769 data.WriteGuidMask(playerGuid, 4);
770 data.WriteGuidMask(petitionGuid, 3);
771 data.WriteGuidMask(playerGuid, 5, 3);
772 data.WriteGuidMask(petitionGuid, 7);
773 data.WriteGuidMask(playerGuid, 7);
774
775 data.WriteBits(result, 4);
776 data.FlushBits();
777
778 data.WriteGuidBytes(petitionGuid, 0, 5);
779 data.WriteGuidBytes(playerGuid, 3, 0);
780 data.WriteGuidBytes(petitionGuid, 3);
781 data.WriteGuidBytes(playerGuid, 2, 6, 4, 1);
782 data.WriteGuidBytes(petitionGuid, 6, 7);
783 data.WriteGuidBytes(playerGuid, 7);
784 data.WriteGuidBytes(petitionGuid, 2, 1);
785 data.WriteGuidBytes(playerGuid, 5);
786 data.WriteGuidBytes(petitionGuid, 4);
787 SendPacket(&data);
788}
@ CHAR_INS_PETITION_SIGNATURE
@ CHAR_DEL_PETITION_BY_GUID
@ CHAR_SEL_PETITION_OWNER_BY_GUID
@ CHAR_UPD_PETITION_NAME
@ CHAR_SEL_PETITION_BY_OWNER
@ CHAR_SEL_PETITION_SIG_BY_ACCOUNT
@ CHAR_SEL_PETITION
@ CHAR_SEL_PETITION_SIGNATURE
@ CHAR_SEL_PETITION_SIGNATURES
@ CHAR_INS_PETITION
@ CHAR_DEL_PETITION_SIGNATURE_BY_GUID
@ YEAR
Definition Common.h:124
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::uint16_t uint16
Definition Define.h:78
@ GUILD_COMMAND_INVITE
Definition Guild.h:81
@ GUILD_COMMAND_CREATE
Definition Guild.h:80
@ ERR_ALREADY_IN_GUILD_S
Definition Guild.h:103
@ ERR_GUILD_COMMAND_SUCCESS
Definition Guild.h:100
@ ERR_GUILD_NOT_ALLIED
Definition Guild.h:113
@ ERR_GUILD_NAME_EXISTS_S
Definition Guild.h:107
@ ERR_ALREADY_INVITED_TO_GUILD_S
Definition Guild.h:105
@ ERR_GUILD_NAME_INVALID
Definition Guild.h:106
@ PETITION_SIGN_ALREADY_SIGNED
Definition Guild.h:176
@ PETITION_SIGN_OK
Definition Guild.h:175
@ PETITION_TURN_NEED_MORE_SIGNATURES
Definition Guild.h:168
@ PETITION_TURN_ALREADY_IN_GUILD
Definition Guild.h:167
@ PETITION_TURN_OK
Definition Guild.h:166
#define sGuildMgr
Definition GuildMgr.h:53
@ BUY_ERR_NOT_ENOUGHT_MONEY
Definition Item.h:128
@ BUY_ERR_CANT_FIND_ITEM
Definition Item.h:126
InventoryResult
Definition Item.h:27
@ EQUIP_ERR_OK
Definition Item.h:28
@ ITEM_CHANGED
Definition Item.h:192
#define SF_LOG_DEBUG(filterType__,...)
Definition Log.h:134
#define SF_LOG_ERROR(filterType__,...)
Definition Log.h:143
uint32 GUID_LOPART(uint64 x)
@ HIGHGUID_PLAYER
uint64 MAKE_NEW_GUID(uint32 l, uint32 e, uint32 h)
#define sObjectMgr
Definition ObjectMgr.h:1617
constexpr uint64 GUILD_CHARTER_COST
constexpr uint8 GUILD_CHARTER_TYPE
constexpr uint32 GUILD_CHARTER
std::vector< ItemPosCount > ItemPosCountVec
Definition Player.h:777
Skyfire::AutoPtr< PreparedResultSet, Skyfire::Mutex > PreparedQueryResult
Definition QueryResult.h:94
@ SPELL_AURA_FEIGN_DEATH
Skyfire::AutoPtr< Transaction, Skyfire::Mutex > SQLTransaction
Definition Transaction.h:42
@ UNIT_NPC_FLAG_PETITIONER
Definition Unit.h:705
@ NULL_BAG
Definition Unit.h:336
@ NULL_SLOT
Definition Unit.h:337
@ UNIT_STATE_DIED
Definition Unit.h:512
@ ITEM_FIELD_ENCHANTMENT
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
void WriteGuidMask(const ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:248
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
std::string ReadString(size_t length)
Definition ByteBuffer.h:565
void ReadGuidMask(ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:240
void WriteBits(T value, size_t bits)
Definition ByteBuffer.h:192
void FlushBits()
Definition ByteBuffer.h:154
Definition Field.h:16
uint8 GetUInt8() const
Definition Field.h:26
std::string GetString() const
Definition Field.h:228
uint64 GetUInt64() const
Definition Field.h:141
uint32 GetUInt32() const
Definition Field.h:105
Definition Guild.h:324
bool Create(Player *pLeader, std::string const &name)
Definition Guild.cpp:1178
static void SendCommandResult(WorldSession *session, GuildCommandType type, GuildCommandError errCode, std::string const &param="")
Definition Guild.cpp:87
bool AddMember(uint64 guid, uint8 rankId=GUILD_RANK_NONE)
Definition Guild.cpp:2828
Definition Item.h:202
uint8 GetSlot() const
Definition Item.h:265
void SetState(ItemUpdateState state, Player *forplayer=NULL)
Definition Item.cpp:667
uint8 GetBagSlot() const
Definition Item.cpp:734
static Player * FindPlayer(uint64)
ObjectGuid GetObjectGUID() const
Definition Object.h:123
uint32 GetGUIDLow() const
Definition Object.h:120
void SetUInt32Value(uint16 index, uint32 value)
Definition Object.cpp:1038
static bool IsValidCharterName(std::string const &name)
uint32 GetTeam() const
Definition Player.h:2527
uint32 GetGuildId() const
Definition Player.h:2291
WorldSession * GetSession() const
Definition Player.h:2417
int GetGuildIdInvited() const
Definition Player.h:2298
Creature * GetNPCIfCanInteractWith(uint64 guid, uint32 npcflagmask)
Definition Player.cpp:2836
void setString(const uint8 index, const std::string &value)
void setUInt32(const uint8 index, const uint32 value)
void setUInt8(const uint8 index, const uint8 value)
void RemoveAurasByType(AuraType auraType, uint64 casterGUID=0, Aura *except=NULL, bool negative=true, bool positive=true)
void Initialize(Opcodes opcode, size_t newres=200)
Definition WorldPacket.h:31
void HandlePetitionShowListOpcode(WorldPacket &recvPacket)
void HandleTurnInPetitionOpcode(WorldPacket &recvData)
void SendPetitionSignResults(ObjectGuid petitionGuid, ObjectGuid playerGuid, uint8 result)
void HandlePetitionShowSignOpcode(WorldPacket &recvData)
Player * GetPlayer() const
void HandlePetitionBuyOpcode(WorldPacket &recvData)
void SendPacket(WorldPacket const *packet, bool forced=false)
Send a packet to the client.
uint32 GetAccountId() const
void HandlePetitionQueryOpcode(WorldPacket &recvData)
Player * _player
void SendPetitionShowList(uint64 guid)
void HandlePetitionRenameOpcode(WorldPacket &recvData)
void SendPetitionQueryOpcode(uint64 petitionguid)
void HandleOfferPetitionOpcode(WorldPacket &recvData)
void HandlePetitionDeclineOpcode(WorldPacket &recvData)
void HandlePetitionSignOpcode(WorldPacket &recvData)
CharacterDatabaseWorkerPool CharacterDatabase
Accessor to the character database.
Definition Main.cpp:41
@ SMSG_PETITION_SHOWLIST
Definition Opcodes.h:849
@ SMSG_PETITION_SHOW_SIGNATURES
Definition Opcodes.h:850
@ SMSG_PETITION_QUERY_RESPONSE
Definition Opcodes.h:847
@ SMSG_TURN_IN_PETITION_RESULTS
Definition Opcodes.h:1041
@ SMSG_PETITION_SIGN_RESULTS
Definition Opcodes.h:851
@ SMSG_PETITION_RENAME_RESULT
Definition Opcodes.h:848
#define sWorld
Definition World.h:910
@ CONFIG_MIN_PETITION_SIGNS
Definition World.h:245
@ CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD
Definition World.h:99