mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-02-01 10:03:47 +00:00
feat(core): implement 31-bit safe petition_id for improved database integrity (#22774)
This commit is contained in:
@@ -41,8 +41,9 @@ void PetitionMgr::LoadPetitions()
|
||||
{
|
||||
uint32 oldMSTime = getMSTime();
|
||||
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)
|
||||
{
|
||||
LOG_WARN("server.loading", ">> Loaded 0 Petitions!");
|
||||
@@ -51,13 +52,24 @@ void PetitionMgr::LoadPetitions()
|
||||
}
|
||||
|
||||
uint32 count = 0;
|
||||
uint32 maxId = 0;
|
||||
do
|
||||
{
|
||||
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;
|
||||
} 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", " ");
|
||||
}
|
||||
@@ -67,7 +79,7 @@ void PetitionMgr::LoadSignatures()
|
||||
uint32 oldMSTime = getMSTime();
|
||||
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)
|
||||
{
|
||||
LOG_WARN("server.loading", ">> Loaded 0 Petition signs!");
|
||||
@@ -79,7 +91,11 @@ void PetitionMgr::LoadSignatures()
|
||||
do
|
||||
{
|
||||
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;
|
||||
} while (result->NextRow());
|
||||
|
||||
@@ -87,10 +103,11 @@ void PetitionMgr::LoadSignatures()
|
||||
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];
|
||||
p.petitionGuid = petitionGUID;
|
||||
p.petitionId = petitionId;
|
||||
p.ownerGuid = ownerGuid;
|
||||
p.petitionName = name;
|
||||
p.petitionType = type;
|
||||
@@ -102,7 +119,12 @@ void PetitionMgr::AddPetition(ObjectGuid petitionGUID, ObjectGuid ownerGuid, std
|
||||
|
||||
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
|
||||
SignatureStore.erase(petitionGUID);
|
||||
@@ -143,6 +165,15 @@ Petition const* PetitionMgr::GetPetition(ObjectGuid petitionGUID) const
|
||||
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
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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 <unordered_map>
|
||||
#include <map>
|
||||
|
||||
#define CHARTER_DISPLAY_ID 16161
|
||||
@@ -37,14 +38,21 @@ typedef std::map<ObjectGuid, uint32> SignatureMap;
|
||||
|
||||
struct Petition
|
||||
{
|
||||
// Item GUID of the charter item (used to find the item in inventory)
|
||||
ObjectGuid petitionGuid;
|
||||
// New 31-bit safe petition identifier used in packets/DB relations
|
||||
uint32 petitionId;
|
||||
// Owner character GUID
|
||||
ObjectGuid ownerGuid;
|
||||
// Petition type (guild / arena)
|
||||
uint8 petitionType;
|
||||
// Name associated with the petition (guild/arena name)
|
||||
std::string petitionName;
|
||||
};
|
||||
|
||||
struct Signatures
|
||||
{
|
||||
// Keep keying by item-guid for backward compatibility in code paths
|
||||
ObjectGuid petitionGuid;
|
||||
SignatureMap signatureMap;
|
||||
};
|
||||
@@ -65,10 +73,11 @@ public:
|
||||
void LoadSignatures();
|
||||
|
||||
// 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 RemovePetitionByOwnerAndType(ObjectGuid ownerGuid, uint8 type);
|
||||
Petition const* GetPetition(ObjectGuid petitionGUID) const;
|
||||
Petition const* GetPetitionById(uint32 petitionId) const;
|
||||
Petition const* GetPetitionByOwnerWithType(ObjectGuid ownerGuid, uint8 type) const;
|
||||
PetitionContainer* GetPetitionStore() { return &PetitionStore; }
|
||||
|
||||
@@ -79,9 +88,17 @@ public:
|
||||
Signatures const* GetSignature(ObjectGuid petitionGUID) const;
|
||||
SignatureContainer* GetSignatureStore() { return &SignatureStore; }
|
||||
|
||||
uint32 GeneratePetitionId();
|
||||
uint32 GetPetitionIdByItemGuid(ObjectGuid petitionItemGuid) const;
|
||||
ObjectGuid GetItemGuidByPetitionId(uint32 petitionId) const;
|
||||
|
||||
protected:
|
||||
PetitionContainer PetitionStore;
|
||||
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()
|
||||
|
||||
Reference in New Issue
Block a user