[9571] Create and use ObjectGuidGenerator/IdGenerator template classes.

* This is let finally hide guid structure in ObjectGuid.h/.cpp code.
* Shared related code.

NOTE: while switch to use new clasess one more problem has been detected
with not-safe code in .pdump work for future per-map multi-threading.
It's need rewrited before will possible safe use in like case.
For current single world thread case it's safe.
This commit is contained in:
VladimirMangos 2010-03-11 15:50:45 +03:00
parent 873b2cab99
commit c4f3578226
8 changed files with 206 additions and 234 deletions

View file

@ -205,8 +205,7 @@ Map::Map(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode, Map* _par
i_id(id), i_InstanceId(InstanceId), m_unloadTimer(0), i_id(id), i_InstanceId(InstanceId), m_unloadTimer(0),
m_VisibleDistance(DEFAULT_VISIBILITY_DISTANCE), m_VisibleDistance(DEFAULT_VISIBILITY_DISTANCE),
m_activeNonPlayersIter(m_activeNonPlayers.end()), m_activeNonPlayersIter(m_activeNonPlayers.end()),
i_gridExpiry(expiry), m_parentMap(_parent ? _parent : this), i_gridExpiry(expiry), m_parentMap(_parent ? _parent : this)
m_hiDynObjectGuid(1), m_hiPetGuid(1), m_hiVehicleGuid(1)
{ {
for(unsigned int idx=0; idx < MAX_NUMBER_OF_GRIDS; ++idx) for(unsigned int idx=0; idx < MAX_NUMBER_OF_GRIDS; ++idx)
{ {
@ -3592,26 +3591,11 @@ uint32 Map::GenerateLocalLowGuid(HighGuid guidhigh)
switch(guidhigh) switch(guidhigh)
{ {
case HIGHGUID_DYNAMICOBJECT: case HIGHGUID_DYNAMICOBJECT:
if (m_hiDynObjectGuid >= 0xFFFFFFFE) return m_DynObjectGuids.Generate();
{
sLog.outError("DynamicObject guid overflow!! Can't continue, shutting down server. ");
World::StopNow(ERROR_EXIT_CODE);
}
return m_hiDynObjectGuid++;
case HIGHGUID_PET: case HIGHGUID_PET:
if(m_hiPetGuid>=0x00FFFFFE) return m_PetGuids.Generate();
{
sLog.outError("Pet guid overflow!! Can't continue, shutting down server. ");
World::StopNow(ERROR_EXIT_CODE);
}
return m_hiPetGuid++;
case HIGHGUID_VEHICLE: case HIGHGUID_VEHICLE:
if(m_hiVehicleGuid>=0x00FFFFFF) return m_VehicleGuids.Generate();
{
sLog.outError("Vehicle guid overflow!! Can't continue, shutting down server. ");
World::StopNow(ERROR_EXIT_CODE);
}
return m_hiVehicleGuid++;
default: default:
ASSERT(0); ASSERT(0);
} }

View file

@ -495,9 +495,9 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
std::multimap<time_t, ScriptAction> m_scriptSchedule; std::multimap<time_t, ScriptAction> m_scriptSchedule;
// Map local low guid counters // Map local low guid counters
uint32 m_hiDynObjectGuid; ObjectGuidGenerator<HIGHGUID_DYNAMICOBJECT> m_DynObjectGuids;
uint32 m_hiPetGuid; ObjectGuidGenerator<HIGHGUID_PET> m_PetGuids;
uint32 m_hiVehicleGuid; ObjectGuidGenerator<HIGHGUID_VEHICLE> m_VehicleGuids;
// Type specific code for add/remove to/from grid // Type specific code for add/remove to/from grid
template<class T> template<class T>

View file

@ -17,22 +17,25 @@
*/ */
#include "ObjectGuid.h" #include "ObjectGuid.h"
#include "World.h"
#include <sstream> #include <sstream>
char const* ObjectGuid::GetTypeName() const char const* ObjectGuid::GetTypeName(HighGuid high)
{ {
switch(GetHigh()) switch(high)
{ {
case HIGHGUID_ITEM: return "item"; case HIGHGUID_ITEM: return "Item";
case HIGHGUID_PLAYER: return !IsEmpty() ? "player" : "none"; case HIGHGUID_PLAYER: return "Player";
case HIGHGUID_GAMEOBJECT: return "gameobject"; case HIGHGUID_GAMEOBJECT: return "Gameobject";
case HIGHGUID_TRANSPORT: return "transport"; case HIGHGUID_TRANSPORT: return "Transport";
case HIGHGUID_UNIT: return "creature"; case HIGHGUID_UNIT: return "Creature";
case HIGHGUID_PET: return "pet"; case HIGHGUID_PET: return "Pet";
case HIGHGUID_VEHICLE: return "vehicle"; case HIGHGUID_VEHICLE: return "Vehicle";
case HIGHGUID_DYNAMICOBJECT:return "dynobject"; case HIGHGUID_DYNAMICOBJECT:return "DynObject";
case HIGHGUID_CORPSE: return "corpse"; case HIGHGUID_CORPSE: return "Corpse";
case HIGHGUID_MO_TRANSPORT: return "mo_transport"; case HIGHGUID_MO_TRANSPORT: return "MoTransport";
default: default:
return "<unknown>"; return "<unknown>";
} }
@ -48,6 +51,17 @@ std::string ObjectGuid::GetString() const
return str.str(); return str.str();
} }
template<HighGuid high>
uint32 ObjectGuidGenerator<high>::Generate()
{
if (m_nextGuid >= ObjectGuid::GetMaxCounter(high)-1)
{
sLog.outError("%s guid overflow!! Can't continue, shutting down server. ",ObjectGuid::GetTypeName(high));
World::StopNow(ERROR_EXIT_CODE);
}
return m_nextGuid++;
}
ByteBuffer& operator<< (ByteBuffer& buf, ObjectGuid const& guid) ByteBuffer& operator<< (ByteBuffer& buf, ObjectGuid const& guid)
{ {
buf << uint64(guid.GetRawValue()); buf << uint64(guid.GetRawValue());
@ -71,3 +85,13 @@ ByteBuffer &operator>>(ByteBuffer& buf, PackedGuidReader const& guid)
guid.m_guidPtr->Set(buf.readPackGUID()); guid.m_guidPtr->Set(buf.readPackGUID());
return buf; return buf;
} }
template uint32 ObjectGuidGenerator<HIGHGUID_ITEM>::Generate();
template uint32 ObjectGuidGenerator<HIGHGUID_PLAYER>::Generate();
template uint32 ObjectGuidGenerator<HIGHGUID_GAMEOBJECT>::Generate();
template uint32 ObjectGuidGenerator<HIGHGUID_TRANSPORT>::Generate();
template uint32 ObjectGuidGenerator<HIGHGUID_UNIT>::Generate();
template uint32 ObjectGuidGenerator<HIGHGUID_PET>::Generate();
template uint32 ObjectGuidGenerator<HIGHGUID_VEHICLE>::Generate();
template uint32 ObjectGuidGenerator<HIGHGUID_DYNAMICOBJECT>::Generate();
template uint32 ObjectGuidGenerator<HIGHGUID_CORPSE>::Generate();

View file

@ -136,6 +136,8 @@ class ObjectGuid
// Possible removed in future for more strict control type conversions // Possible removed in future for more strict control type conversions
void operator= (uint64 const& guid) { m_guid = guid; } void operator= (uint64 const& guid) { m_guid = guid; }
PackedGuid WriteAsPacked() const;
public: // accessors public: // accessors
uint64 const& GetRawValue() const { return m_guid; } uint64 const& GetRawValue() const { return m_guid; }
HighGuid GetHigh() const { return HighGuid((m_guid >> 48) & 0x0000FFFF); } HighGuid GetHigh() const { return HighGuid((m_guid >> 48) & 0x0000FFFF); }
@ -147,6 +149,15 @@ class ObjectGuid
: uint32(m_guid & UI64LIT(0x00000000FFFFFFFF)); : uint32(m_guid & UI64LIT(0x00000000FFFFFFFF));
} }
static uint32 GetMaxCounter(HighGuid high)
{
return HasEntry(high)
? uint32(0x00FFFFFF)
: uint32(0xFFFFFFFF);
}
uint32 GetMaxCounter() const { return GetMaxCounter(GetHigh()); }
bool IsEmpty() const { return m_guid == 0; } bool IsEmpty() const { return m_guid == 0; }
bool IsCreature() const { return GetHigh() == HIGHGUID_UNIT; } bool IsCreature() const { return GetHigh() == HIGHGUID_UNIT; }
bool IsPet() const { return GetHigh() == HIGHGUID_PET; } bool IsPet() const { return GetHigh() == HIGHGUID_PET; }
@ -161,9 +172,9 @@ class ObjectGuid
bool IsTransport() const { return GetHigh() == HIGHGUID_TRANSPORT; } bool IsTransport() const { return GetHigh() == HIGHGUID_TRANSPORT; }
bool IsMOTransport() const { return GetHigh() == HIGHGUID_MO_TRANSPORT; } bool IsMOTransport() const { return GetHigh() == HIGHGUID_MO_TRANSPORT; }
TypeID GetTypeId() static TypeID GetTypeId(HighGuid high)
{ {
switch(GetHigh()) switch(high)
{ {
case HIGHGUID_ITEM: return TYPEID_ITEM; case HIGHGUID_ITEM: return TYPEID_ITEM;
//case HIGHGUID_CONTAINER: return TYPEID_CONTAINER; HIGHGUID_CONTAINER==HIGHGUID_ITEM currently //case HIGHGUID_CONTAINER: return TYPEID_CONTAINER; HIGHGUID_CONTAINER==HIGHGUID_ITEM currently
@ -180,14 +191,17 @@ class ObjectGuid
} }
} }
PackedGuid WriteAsPacked() const; TypeID GetTypeId() const { return GetTypeId(GetHigh()); }
public: // accessors - for debug public: // accessors - for debug
char const* GetTypeName() const; static char const* GetTypeName(HighGuid high);
char const* GetTypeName() const { return !IsEmpty() ? GetTypeName(GetHigh()) : "None"; }
std::string GetString() const; std::string GetString() const;
private: // internal functions private: // internal functions
bool HasEntry() const static bool HasEntry(HighGuid high)
{ {
switch(GetHigh()) switch(high)
{ {
case HIGHGUID_ITEM: case HIGHGUID_ITEM:
case HIGHGUID_PLAYER: case HIGHGUID_PLAYER:
@ -205,6 +219,8 @@ class ObjectGuid
} }
} }
bool HasEntry() const { return HasEntry(GetHigh()); }
private: // fields private: // fields
uint64 m_guid; uint64 m_guid;
}; };
@ -229,6 +245,23 @@ class PackedGuid
ByteBuffer m_packedGuid; ByteBuffer m_packedGuid;
}; };
template<HighGuid high>
class ObjectGuidGenerator
{
public: // constructors
explicit ObjectGuidGenerator(uint32 start = 1) : m_nextGuid(start) {}
public: // modifiers
void Set(uint32 val) { m_nextGuid = val; }
uint32 Generate();
public: // accessors
uint32 GetNextAfterMaxUsed() const { return m_nextGuid; }
private: // fields
uint32 m_nextGuid;
};
ByteBuffer& operator<< (ByteBuffer& buf, ObjectGuid const& guid); ByteBuffer& operator<< (ByteBuffer& buf, ObjectGuid const& guid);
ByteBuffer& operator>> (ByteBuffer& buf, ObjectGuid& guid); ByteBuffer& operator>> (ByteBuffer& buf, ObjectGuid& guid);

View file

@ -45,6 +45,8 @@
#include "WaypointManager.h" #include "WaypointManager.h"
#include "GossipDef.h" #include "GossipDef.h"
#include <limits>
INSTANTIATE_SINGLETON_1(ObjectMgr); INSTANTIATE_SINGLETON_1(ObjectMgr);
ScriptMapMap sQuestEndScripts; ScriptMapMap sQuestEndScripts;
@ -128,22 +130,30 @@ bool SpellClickInfo::IsFitToRequirements(Player const* player) const
return true; return true;
} }
ObjectMgr::ObjectMgr() template<typename T>
T IdGenerator<T>::Generate()
{ {
m_hiCharGuid = 1; if (m_nextGuid >= std::numeric_limits<T>::max()-1)
m_hiCreatureGuid = 1; {
m_hiItemGuid = 1; sLog.outError("%s guid overflow!! Can't continue, shutting down server. ",m_name);
m_hiGoGuid = 1; World::StopNow(ERROR_EXIT_CODE);
m_hiCorpseGuid = 1; }
m_hiPetNumber = 1; return m_nextGuid++;
m_ItemTextId = 1; }
m_mailid = 1;
m_equipmentSetGuid = 1;
m_guildId = 1;
m_arenaTeamId = 1;
m_auctionid = 1;
m_groupId = 1;
template uint32 IdGenerator<uint32>::Generate();
template uint64 IdGenerator<uint64>::Generate();
ObjectMgr::ObjectMgr() :
m_ArenaTeamIds("Arena team ids"),
m_AuctionIds("Auction ids"),
m_EquipmentSetIds("Equipment set ids"),
m_GuildIds("Guild ids"),
m_ItemTextIds("Item text ids"),
m_MailIds("Mail ids"),
m_PetNumbers("Pet numbers"),
m_GroupIds("Group ids")
{
// Only zero condition left, others will be added while loading DB tables // Only zero condition left, others will be added while loading DB tables
mConditions.resize(1); mConditions.resize(1);
} }
@ -5658,7 +5668,7 @@ void ObjectMgr::PackGroupIds()
bar.step(); bar.step();
} }
m_groupId = groupId; m_GroupIds.Set(groupId);
sLog.outString( ">> Group Ids remapped, next group id is %u", groupId ); sLog.outString( ">> Group Ids remapped, next group id is %u", groupId );
sLog.outString(); sLog.outString();
@ -5669,164 +5679,94 @@ void ObjectMgr::SetHighestGuids()
QueryResult *result = CharacterDatabase.Query( "SELECT MAX(guid) FROM characters" ); QueryResult *result = CharacterDatabase.Query( "SELECT MAX(guid) FROM characters" );
if( result ) if( result )
{ {
m_hiCharGuid = (*result)[0].GetUInt32()+1; m_CharGuids.Set((*result)[0].GetUInt32()+1);
delete result; delete result;
} }
result = WorldDatabase.Query( "SELECT MAX(guid) FROM creature" ); result = WorldDatabase.Query( "SELECT MAX(guid) FROM creature" );
if( result ) if( result )
{ {
m_hiCreatureGuid = (*result)[0].GetUInt32()+1; m_CreatureGuids.Set((*result)[0].GetUInt32()+1);
delete result; delete result;
} }
result = CharacterDatabase.Query( "SELECT MAX(guid) FROM item_instance" ); result = CharacterDatabase.Query( "SELECT MAX(guid) FROM item_instance" );
if( result ) if( result )
{ {
m_hiItemGuid = (*result)[0].GetUInt32()+1; m_ItemGuids.Set((*result)[0].GetUInt32()+1);
delete result; delete result;
} }
// Cleanup other tables from not existed guids (>=m_hiItemGuid) // Cleanup other tables from not existed guids (>=m_hiItemGuid)
CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE item >= '%u'", m_hiItemGuid); CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE item >= '%u'", m_ItemGuids.GetNextAfterMaxUsed());
CharacterDatabase.PExecute("DELETE FROM mail_items WHERE item_guid >= '%u'", m_hiItemGuid); CharacterDatabase.PExecute("DELETE FROM mail_items WHERE item_guid >= '%u'", m_ItemGuids.GetNextAfterMaxUsed());
CharacterDatabase.PExecute("DELETE FROM auctionhouse WHERE itemguid >= '%u'", m_hiItemGuid); CharacterDatabase.PExecute("DELETE FROM auctionhouse WHERE itemguid >= '%u'", m_ItemGuids.GetNextAfterMaxUsed());
CharacterDatabase.PExecute("DELETE FROM guild_bank_item WHERE item_guid >= '%u'", m_hiItemGuid); CharacterDatabase.PExecute("DELETE FROM guild_bank_item WHERE item_guid >= '%u'", m_ItemGuids.GetNextAfterMaxUsed());
result = WorldDatabase.Query("SELECT MAX(guid) FROM gameobject" ); result = WorldDatabase.Query("SELECT MAX(guid) FROM gameobject" );
if( result ) if( result )
{ {
m_hiGoGuid = (*result)[0].GetUInt32()+1; m_GameobjectGuids.Set((*result)[0].GetUInt32()+1);
delete result; delete result;
} }
result = CharacterDatabase.Query("SELECT MAX(id) FROM auctionhouse" ); result = CharacterDatabase.Query("SELECT MAX(id) FROM auctionhouse" );
if( result ) if( result )
{ {
m_auctionid = (*result)[0].GetUInt32()+1; m_AuctionIds.Set((*result)[0].GetUInt32()+1);
delete result; delete result;
} }
result = CharacterDatabase.Query( "SELECT MAX(id) FROM mail" ); result = CharacterDatabase.Query( "SELECT MAX(id) FROM mail" );
if( result ) if( result )
{ {
m_mailid = (*result)[0].GetUInt32()+1; m_MailIds.Set((*result)[0].GetUInt32()+1);
delete result; delete result;
} }
result = CharacterDatabase.Query( "SELECT MAX(id) FROM item_text" ); result = CharacterDatabase.Query( "SELECT MAX(id) FROM item_text" );
if( result ) if( result )
{ {
m_ItemTextId = (*result)[0].GetUInt32()+1; m_ItemTextIds.Set((*result)[0].GetUInt32()+1);
delete result; delete result;
} }
result = CharacterDatabase.Query( "SELECT MAX(guid) FROM corpse" ); result = CharacterDatabase.Query( "SELECT MAX(guid) FROM corpse" );
if( result ) if( result )
{ {
m_hiCorpseGuid = (*result)[0].GetUInt32()+1; m_CorpseGuids.Set((*result)[0].GetUInt32()+1);
delete result; delete result;
} }
result = CharacterDatabase.Query("SELECT MAX(arenateamid) FROM arena_team"); result = CharacterDatabase.Query("SELECT MAX(arenateamid) FROM arena_team");
if (result) if (result)
{ {
m_arenaTeamId = (*result)[0].GetUInt32()+1; m_ArenaTeamIds.Set((*result)[0].GetUInt32()+1);
delete result; delete result;
} }
result = CharacterDatabase.Query("SELECT MAX(setguid) FROM character_equipmentsets"); result = CharacterDatabase.Query("SELECT MAX(setguid) FROM character_equipmentsets");
if (result) if (result)
{ {
m_equipmentSetGuid = (*result)[0].GetUInt64()+1; m_EquipmentSetIds.Set((*result)[0].GetUInt64()+1);
delete result; delete result;
} }
result = CharacterDatabase.Query( "SELECT MAX(guildid) FROM guild" ); result = CharacterDatabase.Query( "SELECT MAX(guildid) FROM guild" );
if (result) if (result)
{ {
m_guildId = (*result)[0].GetUInt32()+1; m_GuildIds.Set((*result)[0].GetUInt32()+1);
delete result; delete result;
} }
result = CharacterDatabase.Query( "SELECT MAX(groupId) FROM groups" ); result = CharacterDatabase.Query( "SELECT MAX(groupId) FROM groups" );
if (result) if (result)
{ {
m_groupId = (*result)[0].GetUInt32()+1; m_GroupIds.Set((*result)[0].GetUInt32()+1);
delete result; delete result;
} }
} }
uint32 ObjectMgr::GenerateArenaTeamId()
{
if(m_arenaTeamId>=0xFFFFFFFE)
{
sLog.outError("Arena team ids overflow!! Can't continue, shutting down server. ");
World::StopNow(ERROR_EXIT_CODE);
}
return m_arenaTeamId++;
}
uint32 ObjectMgr::GenerateAuctionID()
{
if(m_auctionid>=0xFFFFFFFE)
{
sLog.outError("Auctions ids overflow!! Can't continue, shutting down server. ");
World::StopNow(ERROR_EXIT_CODE);
}
return m_auctionid++;
}
uint64 ObjectMgr::GenerateEquipmentSetGuid()
{
if(m_equipmentSetGuid>=0xFFFFFFFFFFFFFFFEll)
{
sLog.outError("EquipmentSet guid overflow!! Can't continue, shutting down server. ");
World::StopNow(ERROR_EXIT_CODE);
}
return m_equipmentSetGuid++;
}
uint32 ObjectMgr::GenerateGuildId()
{
if(m_guildId>=0xFFFFFFFE)
{
sLog.outError("Guild ids overflow!! Can't continue, shutting down server. ");
World::StopNow(ERROR_EXIT_CODE);
}
return m_guildId++;
}
uint32 ObjectMgr::GenerateGroupId()
{
if(m_groupId>=0xFFFFFFFE)
{
sLog.outError("Group ids overflow!! Can't continue, shutting down server. ");
World::StopNow(ERROR_EXIT_CODE);
}
return m_groupId++;
}
uint32 ObjectMgr::GenerateMailID()
{
if(m_mailid>=0xFFFFFFFE)
{
sLog.outError("Mail ids overflow!! Can't continue, shutting down server. ");
World::StopNow(ERROR_EXIT_CODE);
}
return m_mailid++;
}
uint32 ObjectMgr::GenerateItemTextID()
{
if(m_ItemTextId>=0xFFFFFFFE)
{
sLog.outError("Item text ids overflow!! Can't continue, shutting down server. ");
World::StopNow(ERROR_EXIT_CODE);
}
return m_ItemTextId++;
}
uint32 ObjectMgr::CreateItemText(std::string text) uint32 ObjectMgr::CreateItemText(std::string text)
{ {
uint32 newItemTextId = GenerateItemTextID(); uint32 newItemTextId = GenerateItemTextID();
@ -5846,40 +5786,15 @@ uint32 ObjectMgr::GenerateLowGuid(HighGuid guidhigh)
switch(guidhigh) switch(guidhigh)
{ {
case HIGHGUID_ITEM: case HIGHGUID_ITEM:
if(m_hiItemGuid>=0xFFFFFFFE) return m_ItemGuids.Generate();
{
sLog.outError("Item guid overflow!! Can't continue, shutting down server. ");
World::StopNow(ERROR_EXIT_CODE);
}
return m_hiItemGuid++;
case HIGHGUID_UNIT: case HIGHGUID_UNIT:
if(m_hiCreatureGuid>=0x00FFFFFE) return m_CreatureGuids.Generate();
{
sLog.outError("Creature guid overflow!! Can't continue, shutting down server. ");
World::StopNow(ERROR_EXIT_CODE);
}
return m_hiCreatureGuid++;
case HIGHGUID_PLAYER: case HIGHGUID_PLAYER:
if(m_hiCharGuid>=0xFFFFFFFE) return m_CharGuids.Generate();
{
sLog.outError("Players guid overflow!! Can't continue, shutting down server. ");
World::StopNow(ERROR_EXIT_CODE);
}
return m_hiCharGuid++;
case HIGHGUID_GAMEOBJECT: case HIGHGUID_GAMEOBJECT:
if(m_hiGoGuid>=0x00FFFFFE) return m_GameobjectGuids.Generate();
{
sLog.outError("Gameobject guid overflow!! Can't continue, shutting down server. ");
World::StopNow(ERROR_EXIT_CODE);
}
return m_hiGoGuid++;
case HIGHGUID_CORPSE: case HIGHGUID_CORPSE:
if(m_hiCorpseGuid>=0xFFFFFFFE) return m_CorpseGuids.Generate();
{
sLog.outError("Corpse guid overflow!! Can't continue, shutting down server. ");
World::StopNow(ERROR_EXIT_CODE);
}
return m_hiCorpseGuid++;
default: default:
ASSERT(0); ASSERT(0);
} }
@ -6291,7 +6206,7 @@ void ObjectMgr::LoadPetNumber()
if(result) if(result)
{ {
Field *fields = result->Fetch(); Field *fields = result->Fetch();
m_hiPetNumber = fields[0].GetUInt32()+1; m_PetNumbers.Set(fields[0].GetUInt32()+1);
delete result; delete result;
} }
@ -6299,7 +6214,7 @@ void ObjectMgr::LoadPetNumber()
bar.step(); bar.step();
sLog.outString(); sLog.outString();
sLog.outString( ">> Loaded the max pet number: %d", m_hiPetNumber-1); sLog.outString( ">> Loaded the max pet number: %d", m_PetNumbers.GetNextAfterMaxUsed()-1);
} }
std::string ObjectMgr::GeneratePetName(uint32 entry) std::string ObjectMgr::GeneratePetName(uint32 entry)
@ -6319,11 +6234,6 @@ std::string ObjectMgr::GeneratePetName(uint32 entry)
return *(list0.begin()+urand(0, list0.size()-1)) + *(list1.begin()+urand(0, list1.size()-1)); return *(list0.begin()+urand(0, list0.size()-1)) + *(list1.begin()+urand(0, list1.size()-1));
} }
uint32 ObjectMgr::GeneratePetNumber()
{
return ++m_hiPetNumber;
}
void ObjectMgr::LoadCorpses() void ObjectMgr::LoadCorpses()
{ {
uint32 count = 0; uint32 count = 0;

View file

@ -372,6 +372,24 @@ MANGOS_DLL_SPEC LanguageDesc const* GetLanguageDescByID(uint32 lang);
class PlayerDumpReader; class PlayerDumpReader;
template<typename T>
class IdGenerator
{
public: // constructors
explicit IdGenerator(char const* _name) : m_name(_name), m_nextGuid(1) {}
public: // modifiers
void Set(T val) { m_nextGuid = val; }
T Generate();
public: // accessors
T GetNextAfterMaxUsed() const { return m_nextGuid; }
private: // fields
char const* m_name;
T m_nextGuid;
};
class ObjectMgr class ObjectMgr
{ {
friend class PlayerDumpReader; friend class PlayerDumpReader;
@ -653,14 +671,14 @@ class ObjectMgr
void SetHighestGuids(); void SetHighestGuids();
uint32 GenerateLowGuid(HighGuid guidhigh); uint32 GenerateLowGuid(HighGuid guidhigh);
uint32 GenerateArenaTeamId(); uint32 GenerateArenaTeamId() { return m_ArenaTeamIds.Generate(); }
uint32 GenerateAuctionID(); uint32 GenerateAuctionID() { return m_AuctionIds.Generate(); }
uint64 GenerateEquipmentSetGuid(); uint64 GenerateEquipmentSetGuid() { return m_EquipmentSetIds.Generate(); }
uint32 GenerateGuildId(); uint32 GenerateGuildId() { return m_GuildIds.Generate(); }
uint32 GenerateGroupId(); uint32 GenerateGroupId() { return m_GroupIds.Generate(); }
uint32 GenerateItemTextID(); uint32 GenerateItemTextID() { return m_ItemGuids.Generate(); }
uint32 GenerateMailID(); uint32 GenerateMailID() { return m_MailIds.Generate(); }
uint32 GeneratePetNumber(); uint32 GeneratePetNumber() { return m_PetNumbers.Generate(); }
uint32 CreateItemText(std::string text); uint32 CreateItemText(std::string text);
void AddItemText(uint32 itemTextId, std::string text) { mItemTexts[itemTextId] = text; } void AddItemText(uint32 itemTextId, std::string text) { mItemTexts[itemTextId] = text; }
@ -889,21 +907,21 @@ class ObjectMgr
protected: protected:
// first free id for selected id type // first free id for selected id type
uint32 m_arenaTeamId; IdGenerator<uint32> m_ArenaTeamIds;
uint32 m_auctionid; IdGenerator<uint32> m_AuctionIds;
uint64 m_equipmentSetGuid; IdGenerator<uint64> m_EquipmentSetIds;
uint32 m_guildId; IdGenerator<uint32> m_GuildIds;
uint32 m_ItemTextId; IdGenerator<uint32> m_ItemTextIds;
uint32 m_mailid; IdGenerator<uint32> m_MailIds;
uint32 m_hiPetNumber; IdGenerator<uint32> m_PetNumbers;
uint32 m_groupId; IdGenerator<uint32> m_GroupIds;
// first free low guid for selected guid type // first free low guid for selected guid type
uint32 m_hiCharGuid; ObjectGuidGenerator<HIGHGUID_PLAYER> m_CharGuids;
uint32 m_hiCreatureGuid; ObjectGuidGenerator<HIGHGUID_UNIT> m_CreatureGuids;
uint32 m_hiItemGuid; ObjectGuidGenerator<HIGHGUID_ITEM> m_ItemGuids;
uint32 m_hiGoGuid; ObjectGuidGenerator<HIGHGUID_GAMEOBJECT> m_GameobjectGuids;
uint32 m_hiCorpseGuid; ObjectGuidGenerator<HIGHGUID_CORPSE> m_CorpseGuids;
QuestMap mQuestTemplates; QuestMap mQuestTemplates;

View file

@ -416,18 +416,18 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s
// make sure the same guid doesn't already exist and is safe to use // make sure the same guid doesn't already exist and is safe to use
bool incHighest = true; bool incHighest = true;
if (guid != 0 && guid < sObjectMgr.m_hiCharGuid) if (guid != 0 && guid < sObjectMgr.m_CharGuids.GetNextAfterMaxUsed())
{ {
result = CharacterDatabase.PQuery("SELECT * FROM characters WHERE guid = '%d'", guid); result = CharacterDatabase.PQuery("SELECT * FROM characters WHERE guid = '%d'", guid);
if (result) if (result)
{ {
guid = sObjectMgr.m_hiCharGuid; // use first free if exists guid = sObjectMgr.m_CharGuids.GetNextAfterMaxUsed();
delete result; delete result;
} }
else incHighest = false; else incHighest = false;
} }
else else
guid = sObjectMgr.m_hiCharGuid; guid = sObjectMgr.m_CharGuids.GetNextAfterMaxUsed();
// normalize the name if specified and check if it exists // normalize the name if specified and check if it exists
if (!normalizePlayerName(name)) if (!normalizePlayerName(name))
@ -536,7 +536,7 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s
if(!changetoknth(vals, OBJECT_FIELD_GUID+1, newguid)) if(!changetoknth(vals, OBJECT_FIELD_GUID+1, newguid))
ROLLBACK(DUMP_FILE_BROKEN); ROLLBACK(DUMP_FILE_BROKEN);
for(uint16 field = PLAYER_FIELD_INV_SLOT_HEAD; field < PLAYER_FARSIGHT; field++) for(uint16 field = PLAYER_FIELD_INV_SLOT_HEAD; field < PLAYER_FARSIGHT; field++)
if(!changetokGuid(vals, field+1, items, sObjectMgr.m_hiItemGuid, true)) if (!changetokGuid(vals, field+1, items, sObjectMgr.m_ItemGuids.GetNextAfterMaxUsed(), true))
ROLLBACK(DUMP_FILE_BROKEN); ROLLBACK(DUMP_FILE_BROKEN);
if(!changenth(line, 3, vals.c_str())) if(!changenth(line, 3, vals.c_str()))
ROLLBACK(DUMP_FILE_BROKEN); ROLLBACK(DUMP_FILE_BROKEN);
@ -566,25 +566,25 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s
ROLLBACK(DUMP_FILE_BROKEN); ROLLBACK(DUMP_FILE_BROKEN);
// bag, item // bag, item
if(!changeGuid(line, 2, items, sObjectMgr.m_hiItemGuid, true)) if (!changeGuid(line, 2, items, sObjectMgr.m_ItemGuids.GetNextAfterMaxUsed(), true))
ROLLBACK(DUMP_FILE_BROKEN); ROLLBACK(DUMP_FILE_BROKEN);
if(!changeGuid(line, 4, items, sObjectMgr.m_hiItemGuid)) if (!changeGuid(line, 4, items, sObjectMgr.m_ItemGuids.GetNextAfterMaxUsed()))
ROLLBACK(DUMP_FILE_BROKEN); ROLLBACK(DUMP_FILE_BROKEN);
break; break;
} }
case DTT_ITEM: // item_instance t. case DTT_ITEM: // item_instance t.
{ {
// item, owner, data field:item, owner guid // item, owner, data field:item, owner guid
if(!changeGuid(line, 1, items, sObjectMgr.m_hiItemGuid)) if (!changeGuid(line, 1, items, sObjectMgr.m_ItemGuids.GetNextAfterMaxUsed()))
ROLLBACK(DUMP_FILE_BROKEN); ROLLBACK(DUMP_FILE_BROKEN);
if (!changenth(line, 2, newguid)) if (!changenth(line, 2, newguid))
ROLLBACK(DUMP_FILE_BROKEN); ROLLBACK(DUMP_FILE_BROKEN);
std::string vals = getnth(line,3); std::string vals = getnth(line,3);
if(!changetokGuid(vals, OBJECT_FIELD_GUID+1, items, sObjectMgr.m_hiItemGuid)) if (!changetokGuid(vals, OBJECT_FIELD_GUID+1, items, sObjectMgr.m_ItemGuids.GetNextAfterMaxUsed()))
ROLLBACK(DUMP_FILE_BROKEN); ROLLBACK(DUMP_FILE_BROKEN);
if (!changetoknth(vals, ITEM_FIELD_OWNER+1, newguid)) if (!changetoknth(vals, ITEM_FIELD_OWNER+1, newguid))
ROLLBACK(DUMP_FILE_BROKEN); ROLLBACK(DUMP_FILE_BROKEN);
if(!changetokGuid(vals, ITEM_FIELD_ITEM_TEXT_ID+1, itemTexts, sObjectMgr.m_ItemTextId,true)) if (!changetokGuid(vals, ITEM_FIELD_ITEM_TEXT_ID+1, itemTexts, sObjectMgr.m_ItemTextIds.GetNextAfterMaxUsed(), true))
ROLLBACK(DUMP_FILE_BROKEN); ROLLBACK(DUMP_FILE_BROKEN);
if (!changenth(line, 3, vals.c_str())) if (!changenth(line, 3, vals.c_str()))
ROLLBACK(DUMP_FILE_BROKEN); ROLLBACK(DUMP_FILE_BROKEN);
@ -595,7 +595,7 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s
// guid,item_guid, // guid,item_guid,
if (!changenth(line, 1, newguid)) if (!changenth(line, 1, newguid))
ROLLBACK(DUMP_FILE_BROKEN); ROLLBACK(DUMP_FILE_BROKEN);
if(!changeGuid(line, 2, items, sObjectMgr.m_hiItemGuid)) if (!changeGuid(line, 2, items, sObjectMgr.m_ItemGuids.GetNextAfterMaxUsed()))
ROLLBACK(DUMP_FILE_BROKEN); ROLLBACK(DUMP_FILE_BROKEN);
break; break;
} }
@ -603,7 +603,9 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s
{ {
//store a map of old pet id to new inserted pet id for use by type 5 tables //store a map of old pet id to new inserted pet id for use by type 5 tables
snprintf(currpetid, 20, "%s", getnth(line, 1).c_str()); snprintf(currpetid, 20, "%s", getnth(line, 1).c_str());
if(strlen(lastpetid)==0) snprintf(lastpetid, 20, "%s", currpetid); if (strlen(lastpetid)==0)
snprintf(lastpetid, 20, "%s", currpetid);
if (strcmp(lastpetid,currpetid)!=0) if (strcmp(lastpetid,currpetid)!=0)
{ {
snprintf(newpetid, 20, "%d", sObjectMgr.GeneratePetNumber()); snprintf(newpetid, 20, "%d", sObjectMgr.GeneratePetNumber());
@ -644,20 +646,20 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s
case DTT_MAIL: // mail case DTT_MAIL: // mail
{ {
// id,messageType,stationery,mailtemplate,sender,receiver,subject,itemText // id,messageType,stationery,mailtemplate,sender,receiver,subject,itemText
if(!changeGuid(line, 1, mails, sObjectMgr.m_mailid)) if (!changeGuid(line, 1, mails, sObjectMgr.m_MailIds.GetNextAfterMaxUsed()))
ROLLBACK(DUMP_FILE_BROKEN); ROLLBACK(DUMP_FILE_BROKEN);
if (!changenth(line, 6, newguid)) if (!changenth(line, 6, newguid))
ROLLBACK(DUMP_FILE_BROKEN); ROLLBACK(DUMP_FILE_BROKEN);
if(!changeGuid(line, 8, itemTexts, sObjectMgr.m_ItemTextId)) if (!changeGuid(line, 8, itemTexts, sObjectMgr.m_ItemTextIds.GetNextAfterMaxUsed()))
ROLLBACK(DUMP_FILE_BROKEN); ROLLBACK(DUMP_FILE_BROKEN);
break; break;
} }
case DTT_MAIL_ITEM: // mail_items case DTT_MAIL_ITEM: // mail_items
{ {
// mail_id,item_guid,item_template,receiver // mail_id,item_guid,item_template,receiver
if(!changeGuid(line, 1, mails, sObjectMgr.m_mailid)) if (!changeGuid(line, 1, mails, sObjectMgr.m_MailIds.GetNextAfterMaxUsed()))
ROLLBACK(DUMP_FILE_BROKEN); ROLLBACK(DUMP_FILE_BROKEN);
if(!changeGuid(line, 2, items, sObjectMgr.m_hiItemGuid)) if (!changeGuid(line, 2, items, sObjectMgr.m_ItemGuids.GetNextAfterMaxUsed()))
ROLLBACK(DUMP_FILE_BROKEN); ROLLBACK(DUMP_FILE_BROKEN);
if (!changenth(line, 4, newguid)) if (!changenth(line, 4, newguid))
ROLLBACK(DUMP_FILE_BROKEN); ROLLBACK(DUMP_FILE_BROKEN);
@ -666,7 +668,7 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s
case DTT_ITEM_TEXT: // item_text case DTT_ITEM_TEXT: // item_text
{ {
// id // id
if(!changeGuid(line, 1, itemTexts, sObjectMgr.m_ItemTextId)) if (!changeGuid(line, 1, itemTexts, sObjectMgr.m_ItemTextIds.GetNextAfterMaxUsed()))
ROLLBACK(DUMP_FILE_BROKEN); ROLLBACK(DUMP_FILE_BROKEN);
// add it to cache // add it to cache
@ -686,12 +688,13 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s
CharacterDatabase.CommitTransaction(); CharacterDatabase.CommitTransaction();
sObjectMgr.m_hiItemGuid += items.size(); //FIXME: current code with post-updating guids not safe for future per-map threads
sObjectMgr.m_mailid += mails.size(); sObjectMgr.m_ItemGuids.Set(sObjectMgr.m_ItemGuids.GetNextAfterMaxUsed() + items.size());
sObjectMgr.m_ItemTextId += itemTexts.size(); sObjectMgr.m_MailIds.Set(sObjectMgr.m_MailIds.GetNextAfterMaxUsed() + mails.size());
sObjectMgr.m_ItemTextIds.Set(sObjectMgr.m_ItemTextIds.GetNextAfterMaxUsed() + itemTexts.size());
if(incHighest) if(incHighest)
++sObjectMgr.m_hiCharGuid; sObjectMgr.m_CharGuids.Set(sObjectMgr.m_CharGuids.GetNextAfterMaxUsed()+1);
fclose(fin); fclose(fin);

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__ #ifndef __REVISION_NR_H__
#define __REVISION_NR_H__ #define __REVISION_NR_H__
#define REVISION_NR "9570" #define REVISION_NR "9571"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__