mirror of
https://github.com/liyunfan1223/azerothcore-wotlk.git
synced 2026-08-08 15:58:04 +00:00
feat(core): implement 31-bit safe petition_id for improved database integrity (#22774)
This commit is contained in:
@@ -0,0 +1,14 @@
|
|||||||
|
-- Add petition_id column to petition table
|
||||||
|
ALTER TABLE `petition` ADD COLUMN `petition_id` INT UNSIGNED NOT NULL DEFAULT 0 AFTER `petitionguid`;
|
||||||
|
-- Populate petition_id based on petitionguid
|
||||||
|
UPDATE `petition` SET `petition_id` = CASE WHEN `petitionguid` <= 2147483647 THEN `petitionguid` ELSE `petitionguid` - 2147483648 END WHERE `petition_id` = 0;
|
||||||
|
-- Add index on petition_id
|
||||||
|
ALTER TABLE `petition` ADD INDEX `idx_petition_id` (`petition_id`);
|
||||||
|
-- Add petition_id column to petition_sign table
|
||||||
|
ALTER TABLE `petition_sign` ADD COLUMN `petition_id` INT UNSIGNED NOT NULL DEFAULT 0 AFTER `petitionguid`;
|
||||||
|
-- Populate petition_id in petition_sign from petition table
|
||||||
|
UPDATE `petition_sign` AS `ps` JOIN `petition` AS `p` ON `p`.`petitionguid` = `ps`.`petitionguid` SET `ps`.`petition_id` = `p`.`petition_id` WHERE `ps`.`petition_id` = 0;
|
||||||
|
-- Add index on petition_id and playerguid in petition_sign
|
||||||
|
ALTER TABLE `petition_sign` ADD INDEX `idx_petition_id_player` (`petition_id`, `playerguid`);
|
||||||
|
-- Update enchantments in item_instance with petition_id prefix
|
||||||
|
UPDATE `item_instance` AS `ii` JOIN `petition` AS `p` ON `p`.`petitionguid` = `ii`.`guid` SET `ii`.`enchantments` = CONCAT(`p`.`petition_id`, SUBSTRING(`ii`.`enchantments`, LOCATE(' ', `ii`.`enchantments`))) WHERE `ii`.`enchantments` IS NOT NULL AND `ii`.`enchantments` <> '';
|
||||||
@@ -353,8 +353,8 @@ void CharacterDatabaseConnection::DoPrepareStatements()
|
|||||||
PrepareStatement(CHAR_UPD_REM_AT_LOGIN_FLAG, "UPDATE characters set at_login = at_login & ~ ? WHERE guid = ?", CONNECTION_ASYNC);
|
PrepareStatement(CHAR_UPD_REM_AT_LOGIN_FLAG, "UPDATE characters set at_login = at_login & ~ ? WHERE guid = ?", CONNECTION_ASYNC);
|
||||||
PrepareStatement(CHAR_UPD_ALL_AT_LOGIN_FLAGS, "UPDATE characters SET at_login = at_login | ?", CONNECTION_ASYNC);
|
PrepareStatement(CHAR_UPD_ALL_AT_LOGIN_FLAGS, "UPDATE characters SET at_login = at_login | ?", CONNECTION_ASYNC);
|
||||||
PrepareStatement(CHAR_INS_BUG_REPORT, "INSERT INTO bugreport (type, content) VALUES(?, ?)", CONNECTION_ASYNC);
|
PrepareStatement(CHAR_INS_BUG_REPORT, "INSERT INTO bugreport (type, content) VALUES(?, ?)", CONNECTION_ASYNC);
|
||||||
PrepareStatement(CHAR_UPD_PETITION_NAME, "UPDATE petition SET name = ? WHERE petitionguid = ?", CONNECTION_ASYNC);
|
PrepareStatement(CHAR_UPD_PETITION_NAME, "UPDATE petition SET name = ? WHERE petition_id = ?", CONNECTION_ASYNC);
|
||||||
PrepareStatement(CHAR_INS_PETITION_SIGNATURE, "INSERT INTO petition_sign (ownerguid, petitionguid, playerguid, player_account) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
|
PrepareStatement(CHAR_INS_PETITION_SIGNATURE, "INSERT INTO petition_sign (ownerguid, petition_id, playerguid, player_account) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
|
||||||
PrepareStatement(CHAR_UPD_ACCOUNT_ONLINE, "UPDATE characters SET online = 0 WHERE account = ?", CONNECTION_ASYNC);
|
PrepareStatement(CHAR_UPD_ACCOUNT_ONLINE, "UPDATE characters SET online = 0 WHERE account = ?", CONNECTION_ASYNC);
|
||||||
PrepareStatement(CHAR_INS_GROUP, "INSERT INTO `groups` (guid, leaderGuid, lootMethod, looterGuid, lootThreshold, icon1, icon2, icon3, icon4, icon5, icon6, icon7, icon8, groupType, difficulty, raidDifficulty, masterLooterGuid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
|
PrepareStatement(CHAR_INS_GROUP, "INSERT INTO `groups` (guid, leaderGuid, lootMethod, looterGuid, lootThreshold, icon1, icon2, icon3, icon4, icon5, icon6, icon7, icon8, groupType, difficulty, raidDifficulty, masterLooterGuid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
|
||||||
PrepareStatement(CHAR_REP_GROUP_MEMBER, "REPLACE INTO group_member (guid, memberGuid, memberFlags, subgroup, roles) VALUES(?, ?, ?, ?, ?)", CONNECTION_ASYNC);
|
PrepareStatement(CHAR_REP_GROUP_MEMBER, "REPLACE INTO group_member (guid, memberGuid, memberFlags, subgroup, roles) VALUES(?, ?, ?, ?, ?)", CONNECTION_ASYNC);
|
||||||
@@ -456,9 +456,9 @@ void CharacterDatabaseConnection::DoPrepareStatements()
|
|||||||
PrepareStatement(CHAR_INS_CHAR_GIFT, "INSERT INTO character_gifts (guid, item_guid, entry, flags) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
|
PrepareStatement(CHAR_INS_CHAR_GIFT, "INSERT INTO character_gifts (guid, item_guid, entry, flags) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
|
||||||
PrepareStatement(CHAR_DEL_INSTANCE_BY_INSTANCE, "DELETE FROM instance WHERE id = ?", CONNECTION_ASYNC);
|
PrepareStatement(CHAR_DEL_INSTANCE_BY_INSTANCE, "DELETE FROM instance WHERE id = ?", CONNECTION_ASYNC);
|
||||||
PrepareStatement(CHAR_DEL_MAIL_ITEM_BY_ID, "DELETE FROM mail_items WHERE mail_id = ?", CONNECTION_ASYNC);
|
PrepareStatement(CHAR_DEL_MAIL_ITEM_BY_ID, "DELETE FROM mail_items WHERE mail_id = ?", CONNECTION_ASYNC);
|
||||||
PrepareStatement(CHAR_INS_PETITION, "INSERT INTO petition (ownerguid, petitionguid, name, type) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
|
PrepareStatement(CHAR_INS_PETITION, "INSERT INTO petition (petition_id, ownerguid, petitionguid, name, type) VALUES (?, ?, ?, ?, ?)", CONNECTION_ASYNC);
|
||||||
PrepareStatement(CHAR_DEL_PETITION_BY_GUID, "DELETE FROM petition WHERE petitionguid = ?", CONNECTION_ASYNC);
|
PrepareStatement(CHAR_DEL_PETITION_BY_ID, "DELETE FROM petition WHERE petition_id = ?", CONNECTION_ASYNC);
|
||||||
PrepareStatement(CHAR_DEL_PETITION_SIGNATURE_BY_GUID, "DELETE FROM petition_sign WHERE petitionguid = ?", CONNECTION_ASYNC);
|
PrepareStatement(CHAR_DEL_PETITION_SIGNATURE_BY_ID, "DELETE FROM petition_sign WHERE petition_id = ?", CONNECTION_ASYNC);
|
||||||
PrepareStatement(CHAR_DEL_CHAR_DECLINED_NAME, "DELETE FROM character_declinedname WHERE guid = ?", CONNECTION_ASYNC);
|
PrepareStatement(CHAR_DEL_CHAR_DECLINED_NAME, "DELETE FROM character_declinedname WHERE guid = ?", CONNECTION_ASYNC);
|
||||||
PrepareStatement(CHAR_INS_CHAR_DECLINED_NAME, "INSERT INTO character_declinedname (guid, genitive, dative, accusative, instrumental, prepositional) VALUES (?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
|
PrepareStatement(CHAR_INS_CHAR_DECLINED_NAME, "INSERT INTO character_declinedname (guid, genitive, dative, accusative, instrumental, prepositional) VALUES (?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
|
||||||
PrepareStatement(CHAR_UPD_CHAR_RACE, "UPDATE characters SET race = ? WHERE guid = ?", CONNECTION_ASYNC);
|
PrepareStatement(CHAR_UPD_CHAR_RACE, "UPDATE characters SET race = ? WHERE guid = ?", CONNECTION_ASYNC);
|
||||||
|
|||||||
@@ -381,8 +381,8 @@ enum CharacterDatabaseStatements : uint32
|
|||||||
CHAR_DEL_INSTANCE_BY_INSTANCE,
|
CHAR_DEL_INSTANCE_BY_INSTANCE,
|
||||||
CHAR_DEL_MAIL_ITEM_BY_ID,
|
CHAR_DEL_MAIL_ITEM_BY_ID,
|
||||||
CHAR_INS_PETITION,
|
CHAR_INS_PETITION,
|
||||||
CHAR_DEL_PETITION_BY_GUID,
|
CHAR_DEL_PETITION_BY_ID,
|
||||||
CHAR_DEL_PETITION_SIGNATURE_BY_GUID,
|
CHAR_DEL_PETITION_SIGNATURE_BY_ID,
|
||||||
CHAR_DEL_CHAR_DECLINED_NAME,
|
CHAR_DEL_CHAR_DECLINED_NAME,
|
||||||
CHAR_INS_CHAR_DECLINED_NAME,
|
CHAR_INS_CHAR_DECLINED_NAME,
|
||||||
CHAR_UPD_CHAR_RACE,
|
CHAR_UPD_CHAR_RACE,
|
||||||
|
|||||||
@@ -183,7 +183,9 @@ void WorldSession::HandlePetitionBuyOpcode(WorldPacket& recvData)
|
|||||||
if (!charter)
|
if (!charter)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
charter->SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1, charter->GetGUID().GetCounter());
|
// Use a 31-bit safe petition id instead of the raw item guid
|
||||||
|
uint32 petitionId = sPetitionMgr->GeneratePetitionId();
|
||||||
|
charter->SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1, petitionId);
|
||||||
// ITEM_FIELD_ENCHANTMENT_1_1 is guild/arenateam id
|
// ITEM_FIELD_ENCHANTMENT_1_1 is guild/arenateam id
|
||||||
// ITEM_FIELD_ENCHANTMENT_1_1+1 is current signatures count (showed on item)
|
// ITEM_FIELD_ENCHANTMENT_1_1+1 is current signatures count (showed on item)
|
||||||
charter->SetState(ITEM_CHANGED, _player);
|
charter->SetState(ITEM_CHANGED, _player);
|
||||||
@@ -211,16 +213,18 @@ void WorldSession::HandlePetitionBuyOpcode(WorldPacket& recvData)
|
|||||||
// xinef: petition pointer is invalid from now on
|
// xinef: petition pointer is invalid from now on
|
||||||
|
|
||||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_PETITION);
|
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_PETITION);
|
||||||
stmt->SetData(0, _player->GetGUID().GetCounter());
|
// petition_id, ownerguid, petitionguid(item guid), name, type
|
||||||
stmt->SetData(1, charter->GetGUID().GetCounter());
|
stmt->SetData(0, petitionId);
|
||||||
stmt->SetData(2, name);
|
stmt->SetData(1, _player->GetGUID().GetCounter());
|
||||||
stmt->SetData(3, uint8(type));
|
stmt->SetData(2, charter->GetGUID().GetCounter());
|
||||||
|
stmt->SetData(3, name);
|
||||||
|
stmt->SetData(4, uint8(type));
|
||||||
trans->Append(stmt);
|
trans->Append(stmt);
|
||||||
|
|
||||||
CharacterDatabase.CommitTransaction(trans);
|
CharacterDatabase.CommitTransaction(trans);
|
||||||
|
|
||||||
// xinef: fill petition store
|
// xinef: fill petition store (include petitionId)
|
||||||
sPetitionMgr->AddPetition(charter->GetGUID(), _player->GetGUID(), name, uint8(type));
|
sPetitionMgr->AddPetition(charter->GetGUID(), _player->GetGUID(), name, uint8(type), petitionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldSession::HandlePetitionShowSignOpcode(WorldPacket& recvData)
|
void WorldSession::HandlePetitionShowSignOpcode(WorldPacket& recvData)
|
||||||
@@ -249,7 +253,7 @@ void WorldSession::HandlePetitionShowSignOpcode(WorldPacket& recvData)
|
|||||||
WorldPacket data(SMSG_PETITION_SHOW_SIGNATURES, (8 + 8 + 4 + 1 + signs * 12));
|
WorldPacket data(SMSG_PETITION_SHOW_SIGNATURES, (8 + 8 + 4 + 1 + signs * 12));
|
||||||
data << petitionguid; // petition guid
|
data << petitionguid; // petition guid
|
||||||
data << _player->GetGUID(); // owner guid
|
data << _player->GetGUID(); // owner guid
|
||||||
data << uint32(petitionguid.GetCounter()); // guild guid
|
data << uint32(petition->petitionId); // guild/team id (31-bit safe)
|
||||||
data << uint8(signs); // sign's count
|
data << uint8(signs); // sign's count
|
||||||
|
|
||||||
if (signs)
|
if (signs)
|
||||||
@@ -286,7 +290,7 @@ void WorldSession::SendPetitionQueryOpcode(ObjectGuid petitionguid)
|
|||||||
|
|
||||||
uint8 type = petition->petitionType;
|
uint8 type = petition->petitionType;
|
||||||
WorldPacket data(SMSG_PETITION_QUERY_RESPONSE, (4 + 8 + petition->petitionName.size() + 1 + 1 + 4 * 12 + 2 + 10));
|
WorldPacket data(SMSG_PETITION_QUERY_RESPONSE, (4 + 8 + petition->petitionName.size() + 1 + 1 + 4 * 12 + 2 + 10));
|
||||||
data << uint32(petitionguid.GetCounter()); // guild/team guid (in Trinity always same as petition low guid
|
data << uint32(petition->petitionId); // guild/team id (was item low guid)
|
||||||
data << petition->ownerGuid; // charter owner guid
|
data << petition->ownerGuid; // charter owner guid
|
||||||
data << petition->petitionName; // name (guild/arena team)
|
data << petition->petitionName; // name (guild/arena team)
|
||||||
data << uint8(0); // some string
|
data << uint8(0); // some string
|
||||||
@@ -373,7 +377,7 @@ void WorldSession::HandlePetitionRenameOpcode(WorldPacket& recvData)
|
|||||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_PETITION_NAME);
|
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_PETITION_NAME);
|
||||||
|
|
||||||
stmt->SetData(0, newName);
|
stmt->SetData(0, newName);
|
||||||
stmt->SetData(1, petitionGuid.GetCounter());
|
stmt->SetData(1, petition->petitionId);
|
||||||
|
|
||||||
CharacterDatabase.Execute(stmt);
|
CharacterDatabase.Execute(stmt);
|
||||||
|
|
||||||
@@ -497,7 +501,7 @@ void WorldSession::HandlePetitionSignOpcode(WorldPacket& recvData)
|
|||||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_PETITION_SIGNATURE);
|
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_PETITION_SIGNATURE);
|
||||||
|
|
||||||
stmt->SetData(0, petition->ownerGuid.GetCounter());
|
stmt->SetData(0, petition->ownerGuid.GetCounter());
|
||||||
stmt->SetData(1, petitionGuid.GetCounter());
|
stmt->SetData(1, petition->petitionId);
|
||||||
stmt->SetData(2, playerGuid.GetCounter());
|
stmt->SetData(2, playerGuid.GetCounter());
|
||||||
stmt->SetData(3, GetAccountId());
|
stmt->SetData(3, GetAccountId());
|
||||||
|
|
||||||
@@ -625,7 +629,7 @@ void WorldSession::HandleOfferPetitionOpcode(WorldPacket& recvData)
|
|||||||
WorldPacket data(SMSG_PETITION_SHOW_SIGNATURES, (8 + 8 + 4 + signs + signs * 12));
|
WorldPacket data(SMSG_PETITION_SHOW_SIGNATURES, (8 + 8 + 4 + signs + signs * 12));
|
||||||
data << petitionguid; // petition guid
|
data << petitionguid; // petition guid
|
||||||
data << _player->GetGUID(); // owner guid
|
data << _player->GetGUID(); // owner guid
|
||||||
data << uint32(petitionguid.GetCounter()); // guild guid
|
data << uint32(petition->petitionId); // guild/team id (31-bit safe)
|
||||||
data << uint8(signs); // sign's count
|
data << uint8(signs); // sign's count
|
||||||
|
|
||||||
if (signs)
|
if (signs)
|
||||||
@@ -790,12 +794,12 @@ void WorldSession::HandleTurnInPetitionOpcode(WorldPacket& recvData)
|
|||||||
|
|
||||||
CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
|
CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
|
||||||
|
|
||||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PETITION_BY_GUID);
|
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PETITION_BY_ID);
|
||||||
stmt->SetData(0, petitionGuid.GetCounter());
|
stmt->SetData(0, petition->petitionId);
|
||||||
trans->Append(stmt);
|
trans->Append(stmt);
|
||||||
|
|
||||||
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PETITION_SIGNATURE_BY_GUID);
|
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PETITION_SIGNATURE_BY_ID);
|
||||||
stmt->SetData(0, petitionGuid.GetCounter());
|
stmt->SetData(0, petition->petitionId);
|
||||||
trans->Append(stmt);
|
trans->Append(stmt);
|
||||||
|
|
||||||
CharacterDatabase.CommitTransaction(trans);
|
CharacterDatabase.CommitTransaction(trans);
|
||||||
|
|||||||
@@ -41,8 +41,9 @@ void PetitionMgr::LoadPetitions()
|
|||||||
{
|
{
|
||||||
uint32 oldMSTime = getMSTime();
|
uint32 oldMSTime = getMSTime();
|
||||||
PetitionStore.clear();
|
PetitionStore.clear();
|
||||||
|
PetitionIdToItemGuid.clear();
|
||||||
|
|
||||||
QueryResult result = CharacterDatabase.Query("SELECT ownerguid, petitionguid, name, type FROM petition");
|
QueryResult result = CharacterDatabase.Query("SELECT ownerguid, petitionguid, name, type, petition_id FROM petition");
|
||||||
if (!result)
|
if (!result)
|
||||||
{
|
{
|
||||||
LOG_WARN("server.loading", ">> Loaded 0 Petitions!");
|
LOG_WARN("server.loading", ">> Loaded 0 Petitions!");
|
||||||
@@ -51,13 +52,24 @@ void PetitionMgr::LoadPetitions()
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32 count = 0;
|
uint32 count = 0;
|
||||||
|
uint32 maxId = 0;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
Field* fields = result->Fetch();
|
Field* fields = result->Fetch();
|
||||||
AddPetition(ObjectGuid::Create<HighGuid::Item>(fields[1].Get<uint32>()), ObjectGuid::Create<HighGuid::Player>(fields[0].Get<uint32>()), fields[2].Get<std::string>(), fields[3].Get<uint8>());
|
uint32 itemLow = fields[1].Get<uint32>();
|
||||||
|
uint32 petitionId = fields[4].Get<uint32>();
|
||||||
|
ObjectGuid itemGuid = ObjectGuid::Create<HighGuid::Item>(itemLow);
|
||||||
|
ObjectGuid ownerGuid = ObjectGuid::Create<HighGuid::Player>(fields[0].Get<uint32>());
|
||||||
|
AddPetition(itemGuid, ownerGuid, fields[2].Get<std::string>(), fields[3].Get<uint8>(), petitionId);
|
||||||
|
PetitionIdToItemGuid[petitionId] = itemGuid;
|
||||||
|
if (petitionId > maxId)
|
||||||
|
maxId = petitionId;
|
||||||
++count;
|
++count;
|
||||||
} while (result->NextRow());
|
} while (result->NextRow());
|
||||||
|
|
||||||
|
// initialize next id (keep within 31-bit safe range)
|
||||||
|
_nextPetitionId = std::min<uint32>(std::max<uint32>(maxId + 1, 1), 0x7FFFFFFFu);
|
||||||
|
|
||||||
LOG_INFO("server.loading", ">> Loaded {} Petitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
|
LOG_INFO("server.loading", ">> Loaded {} Petitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
|
||||||
LOG_INFO("server.loading", " ");
|
LOG_INFO("server.loading", " ");
|
||||||
}
|
}
|
||||||
@@ -67,7 +79,7 @@ void PetitionMgr::LoadSignatures()
|
|||||||
uint32 oldMSTime = getMSTime();
|
uint32 oldMSTime = getMSTime();
|
||||||
SignatureStore.clear();
|
SignatureStore.clear();
|
||||||
|
|
||||||
QueryResult result = CharacterDatabase.Query("SELECT petitionguid, playerguid, player_account FROM petition_sign");
|
QueryResult result = CharacterDatabase.Query("SELECT petition_id, playerguid, player_account FROM petition_sign");
|
||||||
if (!result)
|
if (!result)
|
||||||
{
|
{
|
||||||
LOG_WARN("server.loading", ">> Loaded 0 Petition signs!");
|
LOG_WARN("server.loading", ">> Loaded 0 Petition signs!");
|
||||||
@@ -79,7 +91,11 @@ void PetitionMgr::LoadSignatures()
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
Field* fields = result->Fetch();
|
Field* fields = result->Fetch();
|
||||||
AddSignature(ObjectGuid::Create<HighGuid::Item>(fields[0].Get<uint32>()), fields[2].Get<uint32>(), ObjectGuid::Create<HighGuid::Player>(fields[1].Get<uint32>()));
|
uint32 petitionId = fields[0].Get<uint32>();
|
||||||
|
auto it = PetitionIdToItemGuid.find(petitionId);
|
||||||
|
if (it == PetitionIdToItemGuid.end())
|
||||||
|
continue; // orphan signature, skip
|
||||||
|
AddSignature(it->second, fields[2].Get<uint32>(), ObjectGuid::Create<HighGuid::Player>(fields[1].Get<uint32>()));
|
||||||
++count;
|
++count;
|
||||||
} while (result->NextRow());
|
} while (result->NextRow());
|
||||||
|
|
||||||
@@ -87,10 +103,11 @@ void PetitionMgr::LoadSignatures()
|
|||||||
LOG_INFO("server.loading", " ");
|
LOG_INFO("server.loading", " ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void PetitionMgr::AddPetition(ObjectGuid petitionGUID, ObjectGuid ownerGuid, std::string const& name, uint8 type)
|
void PetitionMgr::AddPetition(ObjectGuid petitionGUID, ObjectGuid ownerGuid, std::string const& name, uint8 type, uint32 petitionId)
|
||||||
{
|
{
|
||||||
Petition& p = PetitionStore[petitionGUID];
|
Petition& p = PetitionStore[petitionGUID];
|
||||||
p.petitionGuid = petitionGUID;
|
p.petitionGuid = petitionGUID;
|
||||||
|
p.petitionId = petitionId;
|
||||||
p.ownerGuid = ownerGuid;
|
p.ownerGuid = ownerGuid;
|
||||||
p.petitionName = name;
|
p.petitionName = name;
|
||||||
p.petitionType = type;
|
p.petitionType = type;
|
||||||
@@ -102,7 +119,12 @@ void PetitionMgr::AddPetition(ObjectGuid petitionGUID, ObjectGuid ownerGuid, std
|
|||||||
|
|
||||||
void PetitionMgr::RemovePetition(ObjectGuid petitionGUID)
|
void PetitionMgr::RemovePetition(ObjectGuid petitionGUID)
|
||||||
{
|
{
|
||||||
PetitionStore.erase(petitionGUID);
|
auto it = PetitionStore.find(petitionGUID);
|
||||||
|
if (it != PetitionStore.end())
|
||||||
|
{
|
||||||
|
PetitionIdToItemGuid.erase(it->second.petitionId);
|
||||||
|
PetitionStore.erase(it);
|
||||||
|
}
|
||||||
|
|
||||||
// remove signatures
|
// remove signatures
|
||||||
SignatureStore.erase(petitionGUID);
|
SignatureStore.erase(petitionGUID);
|
||||||
@@ -143,6 +165,15 @@ Petition const* PetitionMgr::GetPetition(ObjectGuid petitionGUID) const
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Petition const* PetitionMgr::GetPetitionById(uint32 petitionId) const
|
||||||
|
{
|
||||||
|
auto it = PetitionIdToItemGuid.find(petitionId);
|
||||||
|
if (it == PetitionIdToItemGuid.end())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return GetPetition(it->second);
|
||||||
|
}
|
||||||
|
|
||||||
Petition const* PetitionMgr::GetPetitionByOwnerWithType(ObjectGuid ownerGuid, uint8 type) const
|
Petition const* PetitionMgr::GetPetitionByOwnerWithType(ObjectGuid ownerGuid, uint8 type) const
|
||||||
{
|
{
|
||||||
for (PetitionContainer::const_iterator itr = PetitionStore.begin(); itr != PetitionStore.end(); ++itr)
|
for (PetitionContainer::const_iterator itr = PetitionStore.begin(); itr != PetitionStore.end(); ++itr)
|
||||||
@@ -189,3 +220,37 @@ void PetitionMgr::RemoveSignaturesByPlayerAndType(ObjectGuid playerGuid, uint8 t
|
|||||||
itr->second.signatureMap.erase(signItr);
|
itr->second.signatureMap.erase(signItr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32 PetitionMgr::GeneratePetitionId()
|
||||||
|
{
|
||||||
|
// ensure 31-bit range and avoid collisions with already loaded petitions
|
||||||
|
if (_nextPetitionId == 0 || _nextPetitionId >= 0x7FFFFFFF)
|
||||||
|
_nextPetitionId = 1;
|
||||||
|
|
||||||
|
// find first free id
|
||||||
|
while (PetitionIdToItemGuid.count(_nextPetitionId))
|
||||||
|
{
|
||||||
|
++_nextPetitionId;
|
||||||
|
if (_nextPetitionId >= 0x7FFFFFFF)
|
||||||
|
_nextPetitionId = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 id = _nextPetitionId++;
|
||||||
|
if (_nextPetitionId >= 0x7FFFFFFF)
|
||||||
|
_nextPetitionId = 1;
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 PetitionMgr::GetPetitionIdByItemGuid(ObjectGuid petitionItemGuid) const
|
||||||
|
{
|
||||||
|
Petition const* p = GetPetition(petitionItemGuid);
|
||||||
|
return p ? p->petitionId : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjectGuid PetitionMgr::GetItemGuidByPetitionId(uint32 petitionId) const
|
||||||
|
{
|
||||||
|
auto it = PetitionIdToItemGuid.find(petitionId);
|
||||||
|
if (it == PetitionIdToItemGuid.end())
|
||||||
|
return ObjectGuid::Empty;
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
#include "ObjectGuid.h"
|
#include "ObjectGuid.h"
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#define CHARTER_DISPLAY_ID 16161
|
#define CHARTER_DISPLAY_ID 16161
|
||||||
@@ -37,14 +38,21 @@ typedef std::map<ObjectGuid, uint32> SignatureMap;
|
|||||||
|
|
||||||
struct Petition
|
struct Petition
|
||||||
{
|
{
|
||||||
|
// Item GUID of the charter item (used to find the item in inventory)
|
||||||
ObjectGuid petitionGuid;
|
ObjectGuid petitionGuid;
|
||||||
|
// New 31-bit safe petition identifier used in packets/DB relations
|
||||||
|
uint32 petitionId;
|
||||||
|
// Owner character GUID
|
||||||
ObjectGuid ownerGuid;
|
ObjectGuid ownerGuid;
|
||||||
|
// Petition type (guild / arena)
|
||||||
uint8 petitionType;
|
uint8 petitionType;
|
||||||
|
// Name associated with the petition (guild/arena name)
|
||||||
std::string petitionName;
|
std::string petitionName;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Signatures
|
struct Signatures
|
||||||
{
|
{
|
||||||
|
// Keep keying by item-guid for backward compatibility in code paths
|
||||||
ObjectGuid petitionGuid;
|
ObjectGuid petitionGuid;
|
||||||
SignatureMap signatureMap;
|
SignatureMap signatureMap;
|
||||||
};
|
};
|
||||||
@@ -65,10 +73,11 @@ public:
|
|||||||
void LoadSignatures();
|
void LoadSignatures();
|
||||||
|
|
||||||
// Petitions
|
// Petitions
|
||||||
void AddPetition(ObjectGuid petitionGUID, ObjectGuid ownerGuid, std::string const& name, uint8 type);
|
void AddPetition(ObjectGuid petitionGUID, ObjectGuid ownerGuid, std::string const& name, uint8 type, uint32 petitionId);
|
||||||
void RemovePetition(ObjectGuid petitionGUID);
|
void RemovePetition(ObjectGuid petitionGUID);
|
||||||
void RemovePetitionByOwnerAndType(ObjectGuid ownerGuid, uint8 type);
|
void RemovePetitionByOwnerAndType(ObjectGuid ownerGuid, uint8 type);
|
||||||
Petition const* GetPetition(ObjectGuid petitionGUID) const;
|
Petition const* GetPetition(ObjectGuid petitionGUID) const;
|
||||||
|
Petition const* GetPetitionById(uint32 petitionId) const;
|
||||||
Petition const* GetPetitionByOwnerWithType(ObjectGuid ownerGuid, uint8 type) const;
|
Petition const* GetPetitionByOwnerWithType(ObjectGuid ownerGuid, uint8 type) const;
|
||||||
PetitionContainer* GetPetitionStore() { return &PetitionStore; }
|
PetitionContainer* GetPetitionStore() { return &PetitionStore; }
|
||||||
|
|
||||||
@@ -79,9 +88,17 @@ public:
|
|||||||
Signatures const* GetSignature(ObjectGuid petitionGUID) const;
|
Signatures const* GetSignature(ObjectGuid petitionGUID) const;
|
||||||
SignatureContainer* GetSignatureStore() { return &SignatureStore; }
|
SignatureContainer* GetSignatureStore() { return &SignatureStore; }
|
||||||
|
|
||||||
|
uint32 GeneratePetitionId();
|
||||||
|
uint32 GetPetitionIdByItemGuid(ObjectGuid petitionItemGuid) const;
|
||||||
|
ObjectGuid GetItemGuidByPetitionId(uint32 petitionId) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
PetitionContainer PetitionStore;
|
PetitionContainer PetitionStore;
|
||||||
SignatureContainer SignatureStore;
|
SignatureContainer SignatureStore;
|
||||||
|
// Mapping id -> item-guid to support DB-id lookups
|
||||||
|
std::unordered_map<uint32, ObjectGuid> PetitionIdToItemGuid;
|
||||||
|
// Next petition id (kept < 2^31)
|
||||||
|
uint32 _nextPetitionId = 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define sPetitionMgr PetitionMgr::instance()
|
#define sPetitionMgr PetitionMgr::instance()
|
||||||
|
|||||||
Reference in New Issue
Block a user