Core/Entities: ObjectGuid improvements

* Support creation of all guid types
* Change ToString to output client compatible text (fixes calendar and auction mails)
* Fix saving and loading item soulbound trade allowed traders
* constexpr EnumClassFlag
This commit is contained in:
Shauren
2020-04-12 17:50:33 +02:00
parent 3b6e5a87d8
commit 676eb6d77f
11 changed files with 576 additions and 342 deletions

View File

@@ -26,51 +26,56 @@ class EnumClassFlag
static_assert(std::is_enum<T>::value, "EnumClassFlag must be used only with enums");
public:
/*implicit*/ EnumClassFlag(T value) : _value(value) { }
/*implicit*/ constexpr EnumClassFlag(T value) : _value(value) { }
EnumClassFlag& operator&=(EnumClassFlag right)
constexpr EnumClassFlag& operator&=(EnumClassFlag right)
{
_value = static_cast<T>(static_cast<std::underlying_type_t<T>>(_value) & static_cast<std::underlying_type_t<T>>(right._value));
return *this;
}
friend EnumClassFlag operator&(EnumClassFlag left, EnumClassFlag right)
constexpr friend EnumClassFlag operator&(EnumClassFlag left, EnumClassFlag right)
{
return left &= right;
}
EnumClassFlag& operator|=(EnumClassFlag right)
constexpr EnumClassFlag& operator|=(EnumClassFlag right)
{
_value = static_cast<T>(static_cast<std::underlying_type_t<T>>(_value) | static_cast<std::underlying_type_t<T>>(right._value));
return *this;
}
friend EnumClassFlag operator|(EnumClassFlag left, EnumClassFlag right)
constexpr friend EnumClassFlag operator|(EnumClassFlag left, EnumClassFlag right)
{
return left |= right;
}
EnumClassFlag operator~() const
constexpr EnumClassFlag operator~() const
{
return static_cast<T>(~static_cast<std::underlying_type_t<T>>(_value));
}
void RemoveFlag(EnumClassFlag flag)
constexpr void RemoveFlag(EnumClassFlag flag)
{
_value = static_cast<T>(static_cast<std::underlying_type_t<T>>(_value) & ~static_cast<std::underlying_type_t<T>>(flag._value));
}
bool HasFlag(T flag) const
constexpr bool HasFlag(T flag) const
{
return (static_cast<std::underlying_type_t<T>>(_value) & static_cast<std::underlying_type_t<T>>(flag)) != 0;
}
operator T() const
constexpr bool HasAllFlags(T flags) const
{
return (static_cast<std::underlying_type_t<T>>(_value) & static_cast<std::underlying_type_t<T>>(flags)) == static_cast<std::underlying_type_t<T>>(flags);
}
constexpr operator T() const
{
return _value;
}
std::underlying_type_t<T> AsUnderlyingType() const
constexpr std::underlying_type_t<T> AsUnderlyingType() const
{
return static_cast<std::underlying_type_t<T>>(_value);
}

View File

@@ -927,7 +927,7 @@ std::string AuctionEntry::BuildAuctionMailBody(uint64 lowGuid, uint64 bid, uint6
{
std::ostringstream strm;
strm.width(16);
strm << std::right << std::hex << ObjectGuid::Create<HighGuid::Player>(lowGuid); // HIGHGUID_PLAYER always present, even for empty guids
strm << std::right << std::hex << ObjectGuid::Create<HighGuid::Player>(lowGuid).ToString(); // HIGHGUID_PLAYER always present, even for empty guids
strm << std::dec << ':' << bid << ':' << buyout;
strm << ':' << deposit << ':' << cut;
return strm.str();

View File

@@ -410,7 +410,7 @@ uint32 CalendarMgr::GetPlayerNumPending(ObjectGuid guid)
std::string CalendarEvent::BuildCalendarMailSubject(ObjectGuid remover) const
{
std::ostringstream strm;
strm << remover << ':' << _title;
strm << remover.ToString() << ':' << _title;
return strm.str();
}

View File

@@ -90,7 +90,8 @@ Channel::Channel(ObjectGuid const& guid, std::string const& name, uint32 team /*
Tokenizer tokens(bannedList, ' ');
for (auto const& token : tokens)
{
std::string bannedGuidStr(token);
// legacy db content might not have 0x prefix, account for that
std::string bannedGuidStr(memcmp(token, "0x", 2) ? token + 2 : token);
ObjectGuid bannedGuid;
bannedGuid.SetRawValue(uint64(strtoull(bannedGuidStr.substr(0, 16).c_str(), nullptr, 16)), uint64(strtoull(bannedGuidStr.substr(16).c_str(), nullptr, 16)));
if (!bannedGuid.IsEmpty())
@@ -145,7 +146,7 @@ void Channel::UpdateChannelInDB() const
{
std::ostringstream banlist;
for (ObjectGuid const& guid : _bannedStore)
banlist << guid << ' ';
banlist << guid.ToHexString() << ' ';
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHANNEL);
stmt->setBool(0, _announceEnabled);

View File

@@ -180,35 +180,15 @@ void ChannelMgr::SendNotOnChannelNotify(Player const* player, std::string const&
ObjectGuid ChannelMgr::CreateCustomChannelGuid()
{
uint64 high = 0;
high |= uint64(HighGuid::ChatChannel) << 58;
high |= uint64(realm.Id.Realm) << 42;
high |= uint64(_team == ALLIANCE ? 3 : 5) << 4;
ObjectGuid channelGuid;
channelGuid.SetRawValue(high, _guidGenerator.Generate());
return channelGuid;
return ObjectGuid::Create<HighGuid::ChatChannel>(false, false, 0, _team == ALLIANCE ? 3 : 5, _guidGenerator.Generate());
}
ObjectGuid ChannelMgr::CreateBuiltinChannelGuid(uint32 channelId, AreaTableEntry const* zoneEntry /*= nullptr*/) const
{
ChatChannelsEntry const* channelEntry = sChatChannelsStore.AssertEntry(channelId);
uint32 zoneId = zoneEntry ? zoneEntry->ID : 0;
if (channelEntry->Flags & (CHANNEL_DBC_FLAG_GLOBAL | CHANNEL_DBC_FLAG_CITY_ONLY))
zoneId = 0;
uint64 high = 0;
high |= uint64(HighGuid::ChatChannel) << 58;
high |= uint64(realm.Id.Realm) << 42;
high |= uint64(1) << 25; // built-in
if (channelEntry->Flags & CHANNEL_DBC_FLAG_CITY_ONLY2)
high |= uint64(1) << 24; // trade
high |= uint64(zoneId) << 10;
high |= uint64(_team == ALLIANCE ? 3 : 5) << 4;
ObjectGuid channelGuid;
channelGuid.SetRawValue(high, channelId);
return channelGuid;
return ObjectGuid::Create<HighGuid::ChatChannel>(true, (channelEntry->Flags & CHANNEL_DBC_FLAG_CITY_ONLY2) != 0, zoneId, _team == ALLIANCE ? 3 : 5, channelId);
}

View File

@@ -43,9 +43,9 @@ std::string ConcatenateGuids(GuidList const& check)
std::ostringstream o;
GuidSet::const_iterator it = guids.begin();
o << *it;
o << it->ToHexString();
for (++it; it != guids.end(); ++it)
o << '|' << *it;
o << '|' << it->ToHexString();
return o.str();
}
@@ -137,9 +137,7 @@ void LFGQueue::RemoveFromQueue(ObjectGuid guid)
RemoveFromCurrentQueue(guid);
RemoveFromCompatibles(guid);
std::ostringstream o;
o << guid;
std::string sguid = o.str();
std::string sguid = guid.ToHexString();
LfgQueueDataContainer::iterator itDelete = QueueDataStore.end();
for (LfgQueueDataContainer::iterator itr = QueueDataStore.begin(); itr != QueueDataStore.end(); ++itr)
@@ -231,9 +229,7 @@ void LFGQueue::UpdateWaitTimeDps(int32 waitTime, uint32 dungeonId)
*/
void LFGQueue::RemoveFromCompatibles(ObjectGuid guid)
{
std::stringstream out;
out << guid;
std::string strGuid = out.str();
std::string strGuid = guid.ToHexString();
TC_LOG_DEBUG("lfg.queue.data.compatibles.remove", "Removing %s", guid.ToString().c_str());
for (LfgCompatibleContainer::iterator itNext = CompatibleMapStore.begin(); itNext != CompatibleMapStore.end();)
@@ -477,7 +473,7 @@ LfgCompatibility LFGQueue::CheckCompatibility(GuidList check)
{
std::ostringstream o;
for (LfgRolesMap::const_iterator it = debugRoles.begin(); it != debugRoles.end(); ++it)
o << ", " << it->first << ": " << GetRolesString(it->second);
o << ", " << it->first.ToHexString() << ": " << GetRolesString(it->second);
TC_LOG_DEBUG("lfg.queue.match.compatibility.check", "Guids: (%s) Roles not compatible%s", GetDetailedMatchRoles(check).c_str(), o.str().c_str());
SetCompatibles(strGuids, LFG_INCOMPATIBLES_NO_ROLES);
@@ -487,12 +483,12 @@ LfgCompatibility LFGQueue::CheckCompatibility(GuidList check)
GuidList::iterator itguid = check.begin();
proposalDungeons = QueueDataStore[*itguid].dungeons;
std::ostringstream o;
o << ", " << *itguid << ": (" << ConcatenateDungeons(proposalDungeons) << ")";
o << ", " << itguid->ToHexString() << ": (" << ConcatenateDungeons(proposalDungeons) << ")";
for (++itguid; itguid != check.end(); ++itguid)
{
LfgDungeonSet temporal;
LfgDungeonSet& dungeons = QueueDataStore[*itguid].dungeons;
o << ", " << *itguid << ": (" << ConcatenateDungeons(dungeons) << ")";
o << ", " << itguid->ToHexString() << ": (" << ConcatenateDungeons(dungeons) << ")";
std::set_intersection(proposalDungeons.begin(), proposalDungeons.end(), dungeons.begin(), dungeons.end(), std::inserter(temporal, temporal.begin()));
proposalDungeons = temporal;
}
@@ -695,9 +691,7 @@ std::string LFGQueue::DumpCompatibleInfo(bool full /* = false */) const
void LFGQueue::FindBestCompatibleInQueue(LfgQueueDataContainer::iterator itrQueue)
{
TC_LOG_DEBUG("lfg.queue.compatibles.find", "%s", itrQueue->first.ToString().c_str());
std::ostringstream o;
o << itrQueue->first;
std::string sguid = o.str();
std::string sguid = itrQueue->first.ToHexString();
for (LfgCompatibleContainer::const_iterator itr = CompatibleMapStore.begin(); itr != CompatibleMapStore.end(); ++itr)
if (itr->second.compatibility == LFG_COMPATIBLES_WITH_LESS_PLAYERS &&

View File

@@ -17,83 +17,214 @@
#include "ObjectGuid.h"
#include "ByteBuffer.h"
#include "Containers.h"
#include "Errors.h"
#include "Hash.h"
#include "Log.h"
#include "Realm.h"
#include "Util.h"
#include "World.h"
#include <sstream>
#include <iomanip>
static_assert(sizeof(ObjectGuid) == sizeof(uint64) * 2, "ObjectGuid must be exactly 16 bytes");
namespace
{
struct GuidTypeNames
struct ObjectGuidInfo
{
char const* Values[uint32(HighGuid::Count)];
char const* Names[AsUnderlyingType(HighGuid::Count)];
std::string(ObjectGuidInfo::*ClientFormatFunction[AsUnderlyingType(HighGuid::Count)])(char const*, ObjectGuid guid);
GuidTypeNames();
} Names;
std::string Format(ObjectGuid guid)
{
if (guid.GetHigh() >= HighGuid::Count)
return "Uniq-WOWGUID_TO_STRING_FAILED";
GuidTypeNames::GuidTypeNames()
int32 type = AsUnderlyingType(guid.GetHigh());
if (!ClientFormatFunction[type])
return "Uniq-WOWGUID_TO_STRING_FAILED";
return (this->*ClientFormatFunction[type])(Names[type], guid);
}
std::string FormatNull(char const*, ObjectGuid)
{
return "0000000000000000";
}
std::string FormatUniq(char const* typeName, ObjectGuid guid)
{
constexpr char const* uniqNames[] =
{
nullptr,
"WOWGUID_UNIQUE_PROBED_DELETE",
"WOWGUID_UNIQUE_JAM_TEMP",
"WOWGUID_TO_STRING_FAILED",
"WOWGUID_FROM_STRING_FAILED",
"WOWGUID_UNIQUE_SERVER_SELF",
"WOWGUID_UNIQUE_MAGIC_SELF",
"WOWGUID_UNIQUE_MAGIC_PET",
"WOWGUID_UNIQUE_INVALID_TRANSPORT",
"WOWGUID_UNIQUE_AMMO_ID",
"WOWGUID_SPELL_TARGET_TRADE_ITEM",
"WOWGUID_SCRIPT_TARGET_INVALID",
"WOWGUID_SCRIPT_TARGET_NONE",
nullptr,
"WOWGUID_FAKE_MODERATOR",
nullptr,
nullptr,
"WOWGUID_UNIQUE_ACCOUNT_OBJ_INITIALIZATION"
};
ObjectGuid::LowType id = guid.GetCounter();
if (id >= Trinity::Containers::Size(uniqNames))
id = 3;
return Trinity::StringFormat("%s-%s", typeName, uniqNames[id]);
}
std::string FormatPlayer(char const* typeName, ObjectGuid guid)
{
return Trinity::StringFormat("%s-%u-%08llX", typeName, guid.GetRealmId(), guid.GetRawValue(0));
}
std::string FormatItem(char const* typeName, ObjectGuid guid)
{
return Trinity::StringFormat("%s-%u-%u-%016llX", typeName, guid.GetRealmId(), uint32(guid.GetRawValue(1) >> 18) & 0xFFFFFF, guid.GetRawValue(0));
}
std::string FormatWorldObject(char const* typeName, ObjectGuid guid)
{
return Trinity::StringFormat("%s-%u-%u-%u-%u-%u-%010llX", typeName, guid.GetSubType(), guid.GetRealmId(), guid.GetMapId(),
uint32(guid.GetRawValue(0) >> 40) & 0xFFFFFF, guid.GetEntry(), guid.GetCounter());
}
std::string FormatTransport(char const* typeName, ObjectGuid guid)
{
return Trinity::StringFormat("%s-%u-%016llX", typeName, uint32(guid.GetRawValue(1) >> 38) & 0xFFFFF, guid.GetRawValue(0));
}
std::string FormatClientActor(char const* typeName, ObjectGuid guid)
{
return Trinity::StringFormat("%s-%u-%u-%u", typeName, guid.GetRealmId(), uint32(guid.GetRawValue(1) >> 26) & 0xFFFFFF, uint32(guid.GetRawValue(0)));
}
std::string FormatChatChannel(char const* typeName, ObjectGuid guid)
{
uint32 builtIn = (guid.GetRawValue(1) >> 25) & 0x1;
uint32 trade = (guid.GetRawValue(1) >> 24) & 0x1;
uint32 zoneId = (guid.GetRawValue(1) >> 10) & 0x3FFF;
uint32 factionGroupMask = (guid.GetRawValue(1) >> 4) & 0x3F;
return Trinity::StringFormat("%s-%u-%u-%u-%u-%u-%08llX", typeName, guid.GetRealmId(), builtIn, trade, zoneId, factionGroupMask, guid.GetRawValue(0));
}
std::string FormatGlobal(char const* typeName, ObjectGuid guid)
{
return Trinity::StringFormat("%s-%llu-%012llX", typeName, guid.GetRawValue(1) & 0x3FFFFFFFFFFFFFF, guid.GetRawValue(0));
}
std::string FormatGuild(char const* typeName, ObjectGuid guid)
{
return Trinity::StringFormat("%s-%u-%012llX", typeName, guid.GetRealmId(), guid.GetRawValue(0));
}
std::string FormatMobileSession(char const* typeName, ObjectGuid guid)
{
return Trinity::StringFormat("%s-%u-%u-%08llX", typeName, guid.GetRealmId(), uint32(guid.GetRawValue(1) >> 33) & 0x1FF, guid.GetRawValue(0));
}
std::string FormatWebObj(char const* typeName, ObjectGuid guid)
{
return Trinity::StringFormat("%s-%u-%u-%u-%012llX", typeName, guid.GetRealmId(), uint32(guid.GetRawValue(1) >> 37) & 0x1F,
uint32(guid.GetRawValue(1) >> 35) & 0x3, guid.GetRawValue(0));
}
std::string FormatLFGObject(char const* typeName, ObjectGuid guid)
{
return Trinity::StringFormat("%s-%u-%u-%u-%u-%u-%u-%06llX", typeName, uint32(guid.GetRawValue(1) >> 54) & 0xF, uint32(guid.GetRawValue(1) >> 50) & 0xF,
uint32(guid.GetRawValue(1) >> 46) & 0xF, uint32(guid.GetRawValue(1) >> 38) & 0xFF, uint32(guid.GetRawValue(1) >> 37) & 0x1,
uint32(guid.GetRawValue(1) >> 35) & 0x3, guid.GetRawValue(0));
}
std::string FormatLFGList(char const* typeName, ObjectGuid guid)
{
return Trinity::StringFormat("%s-%u-%06llX", typeName, uint32(guid.GetRawValue(1) >> 54) & 0xF, guid.GetRawValue(0));
}
std::string FormatClient(char const* typeName, ObjectGuid guid)
{
return Trinity::StringFormat("%s-%u-%u-%012llX", typeName, guid.GetRealmId(), uint32(guid.GetRawValue(1) >> 10) & 0xFFFFFFFF, guid.GetRawValue(0));
}
std::string FormatClubFinder(char const* typeName, ObjectGuid guid)
{
uint32 type = uint32(guid.GetRawValue(1) >> 33) & 0xFF;
uint32 clubFinderId = uint32(guid.GetRawValue(1)) & 0xFFFFFFFF;
if (type == 1) // guild
return Trinity::StringFormat("%s-%u-%u-%u-%llu", typeName, type, clubFinderId, guid.GetRealmId(), guid.GetRawValue(0) /*guildId*/);
return Trinity::StringFormat("%s-%u-%u-%016llX", typeName, type, clubFinderId, guid.GetRawValue(0) /*clubId*/);
}
ObjectGuidInfo();
} Info;
ObjectGuidInfo::ObjectGuidInfo()
{
#define SET_GUID_NAME(type) Values[uint32(HighGuid::type)] = #type;
#define SET_GUID_INFO(type, format) Names[AsUnderlyingType(HighGuid::type)] = #type; ClientFormatFunction[AsUnderlyingType(HighGuid::type)] = &ObjectGuidInfo::format;
SET_GUID_NAME(Null);
SET_GUID_NAME(Uniq);
SET_GUID_NAME(Player);
SET_GUID_NAME(Item);
SET_GUID_NAME(WorldTransaction);
SET_GUID_NAME(StaticDoor);
SET_GUID_NAME(Transport);
SET_GUID_NAME(Conversation);
SET_GUID_NAME(Creature);
SET_GUID_NAME(Vehicle);
SET_GUID_NAME(Pet);
SET_GUID_NAME(GameObject);
SET_GUID_NAME(DynamicObject);
SET_GUID_NAME(AreaTrigger);
SET_GUID_NAME(Corpse);
SET_GUID_NAME(LootObject);
SET_GUID_NAME(SceneObject);
SET_GUID_NAME(Scenario);
SET_GUID_NAME(AIGroup);
SET_GUID_NAME(DynamicDoor);
SET_GUID_NAME(ClientActor);
SET_GUID_NAME(Vignette);
SET_GUID_NAME(CallForHelp);
SET_GUID_NAME(AIResource);
SET_GUID_NAME(AILock);
SET_GUID_NAME(AILockTicket);
SET_GUID_NAME(ChatChannel);
SET_GUID_NAME(Party);
SET_GUID_NAME(Guild);
SET_GUID_NAME(WowAccount);
SET_GUID_NAME(BNetAccount);
SET_GUID_NAME(GMTask);
SET_GUID_NAME(MobileSession);
SET_GUID_NAME(RaidGroup);
SET_GUID_NAME(Spell);
SET_GUID_NAME(Mail);
SET_GUID_NAME(WebObj);
SET_GUID_NAME(LFGObject);
SET_GUID_NAME(LFGList);
SET_GUID_NAME(UserRouter);
SET_GUID_NAME(PVPQueueGroup);
SET_GUID_NAME(UserClient);
SET_GUID_NAME(PetBattle);
SET_GUID_NAME(UniqUserClient);
SET_GUID_NAME(BattlePet);
SET_GUID_NAME(CommerceObj);
SET_GUID_NAME(ClientSession);
SET_GUID_NAME(Cast);
SET_GUID_NAME(ClientConnection);
SET_GUID_NAME(ClubFinder);
SET_GUID_INFO(Null, FormatNull);
SET_GUID_INFO(Uniq, FormatUniq);
SET_GUID_INFO(Player, FormatPlayer);
SET_GUID_INFO(Item, FormatItem);
SET_GUID_INFO(WorldTransaction, FormatWorldObject);
SET_GUID_INFO(StaticDoor, FormatTransport);
SET_GUID_INFO(Transport, FormatTransport);
SET_GUID_INFO(Conversation, FormatWorldObject);
SET_GUID_INFO(Creature, FormatWorldObject);
SET_GUID_INFO(Vehicle, FormatWorldObject);
SET_GUID_INFO(Pet, FormatWorldObject);
SET_GUID_INFO(GameObject, FormatWorldObject);
SET_GUID_INFO(DynamicObject, FormatWorldObject);
SET_GUID_INFO(AreaTrigger, FormatWorldObject);
SET_GUID_INFO(Corpse, FormatWorldObject);
SET_GUID_INFO(LootObject, FormatWorldObject);
SET_GUID_INFO(SceneObject, FormatWorldObject);
SET_GUID_INFO(Scenario, FormatWorldObject);
SET_GUID_INFO(AIGroup, FormatWorldObject);
SET_GUID_INFO(DynamicDoor, FormatWorldObject);
SET_GUID_INFO(ClientActor, FormatClientActor);
SET_GUID_INFO(Vignette, FormatWorldObject);
SET_GUID_INFO(CallForHelp, FormatWorldObject);
SET_GUID_INFO(AIResource, FormatWorldObject);
SET_GUID_INFO(AILock, FormatWorldObject);
SET_GUID_INFO(AILockTicket, FormatWorldObject);
SET_GUID_INFO(ChatChannel, FormatChatChannel);
SET_GUID_INFO(Party, FormatGlobal);
SET_GUID_INFO(Guild, FormatGuild);
SET_GUID_INFO(WowAccount, FormatGlobal);
SET_GUID_INFO(BNetAccount, FormatGlobal);
SET_GUID_INFO(GMTask, FormatGlobal);
SET_GUID_INFO(MobileSession, FormatMobileSession);
SET_GUID_INFO(RaidGroup, FormatGlobal);
SET_GUID_INFO(Spell, FormatGlobal);
SET_GUID_INFO(Mail, FormatGlobal);
SET_GUID_INFO(WebObj, FormatWebObj);
SET_GUID_INFO(LFGObject, FormatLFGObject);
SET_GUID_INFO(LFGList, FormatLFGList);
SET_GUID_INFO(UserRouter, FormatGlobal);
SET_GUID_INFO(PVPQueueGroup, FormatGlobal);
SET_GUID_INFO(UserClient, FormatGlobal);
SET_GUID_INFO(PetBattle, FormatClient);
SET_GUID_INFO(UniqUserClient, FormatClient);
SET_GUID_INFO(BattlePet, FormatGlobal);
SET_GUID_INFO(CommerceObj, FormatGlobal);
SET_GUID_INFO(ClientSession, FormatClient);
SET_GUID_INFO(Cast, FormatWorldObject);
SET_GUID_INFO(ClientConnection, FormatClient);
SET_GUID_INFO(ClubFinder, FormatClubFinder);
#undef SET_GUID_NAME
#undef SET_GUID_INFO
}
}
char const* ObjectGuid::GetTypeName(HighGuid high)
@@ -101,45 +232,27 @@ char const* ObjectGuid::GetTypeName(HighGuid high)
if (high >= HighGuid::Count)
return "<unknown>";
return Names.Values[uint32(high)];
return Info.Names[uint32(high)];
}
std::string ObjectGuid::ToString() const
{
std::ostringstream str;
str << "GUID Full: 0x" << std::hex << std::uppercase << std::setw(16) << std::setfill('0') << _high << std::setw(16) << _low << std::dec << std::nouppercase;
str << " Type: " << GetTypeName();
if (HasEntry())
str << (IsPet() ? " Pet number: " : " Entry: ") << GetEntry();
return Info.Format(*this);
}
str << " Low: " << GetCounter();
return str.str();
std::string ObjectGuid::ToHexString() const
{
return Trinity::StringFormat("0x%016llX%016llX", _data[1], _data[0]);
}
std::size_t ObjectGuid::GetHash() const
{
std::size_t hashVal = 0;
Trinity::hash_combine(hashVal, _low);
Trinity::hash_combine(hashVal, _high);
Trinity::hash_combine(hashVal, _data[0]);
Trinity::hash_combine(hashVal, _data[1]);
return hashVal;
}
ObjectGuid ObjectGuid::Global(HighGuid type, LowType counter)
{
return ObjectGuid(uint64(uint64(type) << 58), counter);
}
ObjectGuid ObjectGuid::RealmSpecific(HighGuid type, LowType counter)
{
return ObjectGuid(uint64(uint64(type) << 58 | uint64(realm.Id.Realm) << 42), counter);
}
ObjectGuid ObjectGuid::MapSpecific(HighGuid type, uint8 subType, uint16 mapId, uint32 serverId, uint32 entry, LowType counter)
{
return ObjectGuid(uint64((uint64(type) << 58) | (uint64(realm.Id.Realm & 0x1FFF) << 42) | (uint64(mapId & 0x1FFF) << 29) | (uint64(entry & 0x7FFFFF) << 6) | (uint64(subType) & 0x3F)),
uint64((uint64(serverId & 0xFFFFFF) << 40) | (counter & UI64LIT(0xFFFFFFFFFF))));
}
std::vector<uint8> ObjectGuid::GetRawValue() const
{
std::vector<uint8> raw(16);
@@ -153,6 +266,138 @@ void ObjectGuid::SetRawValue(std::vector<uint8> const& guid)
memcpy(this, guid.data(), sizeof(*this));
}
ObjectGuid ObjectGuidFactory::CreateNull()
{
return ObjectGuid();
}
ObjectGuid ObjectGuidFactory::CreateUniq(ObjectGuid::LowType id)
{
return ObjectGuid(uint64(uint64(HighGuid::Uniq) << 58),
id);
}
ObjectGuid ObjectGuidFactory::CreatePlayer(ObjectGuid::LowType dbId)
{
return ObjectGuid(uint64((uint64(HighGuid::Player) << 58)
| (uint64(realm.Id.Realm) << 42)),
dbId);
}
ObjectGuid ObjectGuidFactory::CreateItem(ObjectGuid::LowType dbId)
{
return ObjectGuid(uint64((uint64(HighGuid::Item) << 58)
| (uint64(realm.Id.Realm) << 42)),
dbId);
}
ObjectGuid ObjectGuidFactory::CreateWorldObject(HighGuid type, uint8 subType, uint16 mapId, uint32 serverId, uint32 entry, ObjectGuid::LowType counter)
{
return ObjectGuid(uint64((uint64(type) << 58)
| (uint64(realm.Id.Realm & 0x1FFF) << 42)
| (uint64(mapId & 0x1FFF) << 29)
| (uint64(entry & 0x7FFFFF) << 6)
| (uint64(subType) & 0x3F)),
uint64((uint64(serverId & 0xFFFFFF) << 40)
| (counter & UI64LIT(0xFFFFFFFFFF))));
}
ObjectGuid ObjectGuidFactory::CreateTransport(HighGuid type, uint32 counter)
{
return ObjectGuid(uint64((uint64(type) << 58)
| (uint64(counter) << 38)),
UI64LIT(0));
}
ObjectGuid ObjectGuidFactory::CreateClientActor(uint16 ownerType, uint16 ownerId, uint32 counter)
{
return ObjectGuid(uint64((uint64(HighGuid::ClientActor) << 58)
| (uint64(ownerType & 0x1FFF) << 42)
| (uint64(ownerId & 0xFFFFFF) << 26)),
uint64(counter));
}
ObjectGuid ObjectGuidFactory::CreateChatChannel(bool builtIn, bool trade, uint16 zoneId, uint8 factionGroupMask, ObjectGuid::LowType counter)
{
return ObjectGuid(uint64((uint64(HighGuid::ChatChannel) << 58)
| (uint64(realm.Id.Realm & 0x1FFF) << 42)
| (uint64(builtIn) << 25)
| (uint64(trade) << 24)
| (uint64(zoneId & 0x3FFF) << 10)
| (uint64(factionGroupMask & 0x3F) << 4)),
counter);
}
ObjectGuid ObjectGuidFactory::CreateGlobal(HighGuid type, ObjectGuid::LowType dbIdHigh, ObjectGuid::LowType dbId)
{
return ObjectGuid(uint64((uint64(type) << 58)
| (uint64(dbIdHigh & UI64LIT(0x3FFFFFFFFFFFFFF)))),
dbId);
}
ObjectGuid ObjectGuidFactory::CreateGuild(ObjectGuid::LowType dbId)
{
return ObjectGuid(uint64((uint64(HighGuid::Guild) << 58)
| (uint64(realm.Id.Realm) << 42)),
dbId);
}
ObjectGuid ObjectGuidFactory::CreateMobileSession(uint16 arg1, ObjectGuid::LowType counter)
{
return ObjectGuid(uint64((uint64(HighGuid::MobileSession) << 58)
| (uint64(realm.Id.Realm) << 42)
| (uint64(arg1 & 0x1FF) << 33)),
counter);
}
ObjectGuid ObjectGuidFactory::CreateWebObj(uint8 arg1, uint8 arg2, ObjectGuid::LowType counter)
{
return ObjectGuid(uint64((uint64(HighGuid::WebObj) << 58)
| (uint64(realm.Id.Realm & 0x1FFF) << 42)
| (uint64(arg1 & 0x1F) << 37)
| (uint64(arg2 & 0x3) << 35)),
counter);
}
ObjectGuid ObjectGuidFactory::CreateLFGObject(uint8 arg1, uint8 arg2, uint8 arg3, uint8 arg4, bool arg5, uint8 arg6, ObjectGuid::LowType counter)
{
return ObjectGuid(uint64((uint64(HighGuid::LFGObject) << 58)
| (uint64(arg1 & 0xF) << 54)
| (uint64(arg2 & 0xF) << 50)
| (uint64(arg3 & 0xF) << 46)
| (uint64(arg4 & 0xFF) << 38)
| (uint64(arg5 ? 1 : 0) << 37)
| (uint64(arg6 & 0x3) << 35)),
counter);
}
ObjectGuid ObjectGuidFactory::CreateLFGList(uint8 arg1, ObjectGuid::LowType counter)
{
return ObjectGuid(uint64((uint64(HighGuid::LFGObject) << 58)
| (uint64(arg1 & 0xF) << 54)),
counter);
}
ObjectGuid ObjectGuidFactory::CreateClient(HighGuid type, uint32 arg1, ObjectGuid::LowType counter)
{
return ObjectGuid(uint64((uint64(type) << 58)
| (uint64(realm.Id.Realm & 0x1FFF) << 42)
| (uint64(arg1 & 0xFFFFFFFF) << 10)),
counter);
}
ObjectGuid ObjectGuidFactory::CreateClubFinder(uint8 type, uint32 clubFinderId, ObjectGuid::LowType dbId)
{
return ObjectGuid(uint64((uint64(HighGuid::ClubFinder) << 58)
| (type == 1 ? (uint64(realm.Id.Realm & 0x1FFF) << 42) : UI64LIT(0))
| (uint64(type & 0xFF) << 33)
| (uint64(clubFinderId & 0xFFFFFFFF))),
dbId);
}
ObjectGuid const ObjectGuid::Empty = ObjectGuid();
ObjectGuid const ObjectGuid::TradeItem = ObjectGuid::Create<HighGuid::Uniq>(UI64LIT(10));
ByteBuffer& operator<<(ByteBuffer& buf, ObjectGuid const& guid)
{
uint8 lowMask = 0;
@@ -163,9 +408,9 @@ ByteBuffer& operator<<(ByteBuffer& buf, ObjectGuid const& guid)
buf << uint8(highMask);
uint8 packed[8];
if (size_t packedSize = ByteBuffer::PackUInt64(guid._low, &lowMask, packed))
if (size_t packedSize = ByteBuffer::PackUInt64(guid._data[0], &lowMask, packed))
buf.append(packed, packedSize);
if (size_t packedSize = ByteBuffer::PackUInt64(guid._high, &highMask, packed))
if (size_t packedSize = ByteBuffer::PackUInt64(guid._data[1], &highMask, packed))
buf.append(packed, packedSize);
buf.put(pos, lowMask);
@@ -178,51 +423,64 @@ ByteBuffer& operator>>(ByteBuffer& buf, ObjectGuid& guid)
{
uint8 lowMask, highMask;
buf >> lowMask >> highMask;
buf.ReadPackedUInt64(lowMask, guid._low);
buf.ReadPackedUInt64(highMask, guid._high);
buf.ReadPackedUInt64(lowMask, guid._data[0]);
buf.ReadPackedUInt64(highMask, guid._data[1]);
return buf;
}
std::ostream& operator<<(std::ostream& stream, ObjectGuid const& guid)
{
std::ostringstream tmp;
tmp << std::hex << std::setw(16) << std::setfill('0') << guid._high << std::setw(16) << std::setfill('0') << guid._low;
stream << tmp.str();
return stream;
}
ObjectGuid const ObjectGuid::Empty = ObjectGuid();
ObjectGuid const ObjectGuid::TradeItem = ObjectGuid::Create<HighGuid::Uniq>(uint64(10));
void ObjectGuidGeneratorBase::HandleCounterOverflow(HighGuid high)
{
TC_LOG_ERROR("misc", "%s guid overflow!! Can't continue, shutting down server. ", ObjectGuid::GetTypeName(high));
World::StopNow(ERROR_EXIT_CODE);
}
#define GUID_TRAIT_INSTANTIATE_GUID( HIGH_GUID ) \
template class TC_GAME_API ObjectGuidGenerator< HIGH_GUID >;
GUID_TRAIT_INSTANTIATE_GUID(HighGuid::Player)
GUID_TRAIT_INSTANTIATE_GUID(HighGuid::Item)
GUID_TRAIT_INSTANTIATE_GUID(HighGuid::Transport)
GUID_TRAIT_INSTANTIATE_GUID(HighGuid::Guild)
GUID_TRAIT_INSTANTIATE_GUID(HighGuid::Conversation)
GUID_TRAIT_INSTANTIATE_GUID(HighGuid::Creature)
GUID_TRAIT_INSTANTIATE_GUID(HighGuid::Vehicle)
GUID_TRAIT_INSTANTIATE_GUID(HighGuid::Pet)
GUID_TRAIT_INSTANTIATE_GUID(HighGuid::GameObject)
GUID_TRAIT_INSTANTIATE_GUID(HighGuid::DynamicObject)
GUID_TRAIT_INSTANTIATE_GUID(HighGuid::AreaTrigger)
GUID_TRAIT_INSTANTIATE_GUID(HighGuid::Corpse)
GUID_TRAIT_INSTANTIATE_GUID(HighGuid::LootObject)
GUID_TRAIT_INSTANTIATE_GUID(HighGuid::SceneObject)
GUID_TRAIT_INSTANTIATE_GUID(HighGuid::Scenario)
GUID_TRAIT_INSTANTIATE_GUID(HighGuid::AIGroup)
GUID_TRAIT_INSTANTIATE_GUID(HighGuid::DynamicDoor)
GUID_TRAIT_INSTANTIATE_GUID(HighGuid::Vignette)
GUID_TRAIT_INSTANTIATE_GUID(HighGuid::CallForHelp)
GUID_TRAIT_INSTANTIATE_GUID(HighGuid::AIResource)
GUID_TRAIT_INSTANTIATE_GUID(HighGuid::AILock)
GUID_TRAIT_INSTANTIATE_GUID(HighGuid::AILockTicket)
GUID_TRAIT_INSTANTIATE_GUID(HighGuid::Cast)
template class TC_GAME_API ObjectGuidGenerator<HighGuid::Null>;
template class TC_GAME_API ObjectGuidGenerator<HighGuid::Uniq>;
template class TC_GAME_API ObjectGuidGenerator<HighGuid::Player>;
template class TC_GAME_API ObjectGuidGenerator<HighGuid::Item>;
template class TC_GAME_API ObjectGuidGenerator<HighGuid::WorldTransaction>;
template class TC_GAME_API ObjectGuidGenerator<HighGuid::StaticDoor>;
template class TC_GAME_API ObjectGuidGenerator<HighGuid::Transport>;
template class TC_GAME_API ObjectGuidGenerator<HighGuid::Conversation>;
template class TC_GAME_API ObjectGuidGenerator<HighGuid::Creature>;
template class TC_GAME_API ObjectGuidGenerator<HighGuid::Vehicle>;
template class TC_GAME_API ObjectGuidGenerator<HighGuid::Pet>;
template class TC_GAME_API ObjectGuidGenerator<HighGuid::GameObject>;
template class TC_GAME_API ObjectGuidGenerator<HighGuid::DynamicObject>;
template class TC_GAME_API ObjectGuidGenerator<HighGuid::AreaTrigger>;
template class TC_GAME_API ObjectGuidGenerator<HighGuid::Corpse>;
template class TC_GAME_API ObjectGuidGenerator<HighGuid::LootObject>;
template class TC_GAME_API ObjectGuidGenerator<HighGuid::SceneObject>;
template class TC_GAME_API ObjectGuidGenerator<HighGuid::Scenario>;
template class TC_GAME_API ObjectGuidGenerator<HighGuid::AIGroup>;
template class TC_GAME_API ObjectGuidGenerator<HighGuid::DynamicDoor>;
template class TC_GAME_API ObjectGuidGenerator<HighGuid::ClientActor>;
template class TC_GAME_API ObjectGuidGenerator<HighGuid::Vignette>;
template class TC_GAME_API ObjectGuidGenerator<HighGuid::CallForHelp>;
template class TC_GAME_API ObjectGuidGenerator<HighGuid::AIResource>;
template class TC_GAME_API ObjectGuidGenerator<HighGuid::AILock>;
template class TC_GAME_API ObjectGuidGenerator<HighGuid::AILockTicket>;
template class TC_GAME_API ObjectGuidGenerator<HighGuid::ChatChannel>;
template class TC_GAME_API ObjectGuidGenerator<HighGuid::Party>;
template class TC_GAME_API ObjectGuidGenerator<HighGuid::Guild>;
template class TC_GAME_API ObjectGuidGenerator<HighGuid::WowAccount>;
template class TC_GAME_API ObjectGuidGenerator<HighGuid::BNetAccount>;
template class TC_GAME_API ObjectGuidGenerator<HighGuid::GMTask>;
template class TC_GAME_API ObjectGuidGenerator<HighGuid::MobileSession>;
template class TC_GAME_API ObjectGuidGenerator<HighGuid::RaidGroup>;
template class TC_GAME_API ObjectGuidGenerator<HighGuid::Spell>;
template class TC_GAME_API ObjectGuidGenerator<HighGuid::Mail>;
template class TC_GAME_API ObjectGuidGenerator<HighGuid::WebObj>;
template class TC_GAME_API ObjectGuidGenerator<HighGuid::LFGObject>;
template class TC_GAME_API ObjectGuidGenerator<HighGuid::LFGList>;
template class TC_GAME_API ObjectGuidGenerator<HighGuid::UserRouter>;
template class TC_GAME_API ObjectGuidGenerator<HighGuid::PVPQueueGroup>;
template class TC_GAME_API ObjectGuidGenerator<HighGuid::UserClient>;
template class TC_GAME_API ObjectGuidGenerator<HighGuid::PetBattle>;
template class TC_GAME_API ObjectGuidGenerator<HighGuid::UniqUserClient>;
template class TC_GAME_API ObjectGuidGenerator<HighGuid::BattlePet>;
template class TC_GAME_API ObjectGuidGenerator<HighGuid::CommerceObj>;
template class TC_GAME_API ObjectGuidGenerator<HighGuid::ClientSession>;
template class TC_GAME_API ObjectGuidGenerator<HighGuid::Cast>;
template class TC_GAME_API ObjectGuidGenerator<HighGuid::ClientConnection>;
template class TC_GAME_API ObjectGuidGenerator<HighGuid::ClubFinder>;

View File

@@ -19,6 +19,7 @@
#define ObjectGuid_h__
#include "Define.h"
#include "EnumClassFlag.h"
#include <deque>
#include <functional>
#include <list>
@@ -122,98 +123,128 @@ enum class HighGuid
Count,
};
enum class ObjectGuidSequenceSource
{
None = 0x0,
Global = 0x1,
Realm = 0x2,
Map = 0x4
};
enum class ObjectGuidFormatType
{
Null,
Uniq,
Player,
Item,
WorldObject,
Transport,
ClientActor,
ChatChannel,
Global,
Guild,
MobileSession,
WebObj,
LFGObject,
LFGList,
Client,
ClubFinder,
};
template<HighGuid high>
struct ObjectGuidTraits
{
static bool const Global = false;
static bool const RealmSpecific = false;
static bool const MapSpecific = false;
static constexpr EnumClassFlag<ObjectGuidSequenceSource> SequenceSource = ObjectGuidSequenceSource::None;
using Format = std::integral_constant<ObjectGuidFormatType, ObjectGuidFormatType::Null>;
};
#define GUID_TRAIT_GLOBAL(highguid) \
template<> struct ObjectGuidTraits<highguid> \
#define MAKE_GUID_TRAIT(high, sequence, format) \
template<> struct ObjectGuidTraits<high> \
{ \
static bool const Global = true; \
static bool const RealmSpecific = false; \
static bool const MapSpecific = false; \
};
static constexpr EnumClassFlag<ObjectGuidSequenceSource> SequenceSource = sequence; \
using Format = std::integral_constant<ObjectGuidFormatType, format>; \
}
#define GUID_TRAIT_REALM_SPECIFIC(highguid) \
template<> struct ObjectGuidTraits<highguid> \
{ \
static bool const Global = false; \
static bool const RealmSpecific = true; \
static bool const MapSpecific = false; \
};
#define GUID_TRAIT_MAP_SPECIFIC(highguid) \
template<> struct ObjectGuidTraits<highguid> \
{ \
static bool const Global = false; \
static bool const RealmSpecific = false; \
static bool const MapSpecific = true; \
};
GUID_TRAIT_GLOBAL(HighGuid::Uniq)
GUID_TRAIT_GLOBAL(HighGuid::Party)
GUID_TRAIT_GLOBAL(HighGuid::WowAccount)
GUID_TRAIT_GLOBAL(HighGuid::BNetAccount)
GUID_TRAIT_GLOBAL(HighGuid::GMTask)
GUID_TRAIT_GLOBAL(HighGuid::RaidGroup)
GUID_TRAIT_GLOBAL(HighGuid::Spell)
GUID_TRAIT_GLOBAL(HighGuid::Mail)
GUID_TRAIT_GLOBAL(HighGuid::UserRouter)
GUID_TRAIT_GLOBAL(HighGuid::PVPQueueGroup)
GUID_TRAIT_GLOBAL(HighGuid::UserClient)
GUID_TRAIT_GLOBAL(HighGuid::UniqUserClient)
GUID_TRAIT_GLOBAL(HighGuid::BattlePet)
GUID_TRAIT_GLOBAL(HighGuid::CommerceObj)
GUID_TRAIT_GLOBAL(HighGuid::ClientSession)
GUID_TRAIT_REALM_SPECIFIC(HighGuid::Player)
GUID_TRAIT_REALM_SPECIFIC(HighGuid::Item) // This is not exactly correct, there are 2 more unknown parts in highguid: (high >> 10 & 0xFF), (high >> 18 & 0xFFFFFF)
GUID_TRAIT_REALM_SPECIFIC(HighGuid::ChatChannel)
GUID_TRAIT_REALM_SPECIFIC(HighGuid::Guild)
GUID_TRAIT_MAP_SPECIFIC(HighGuid::WorldTransaction)
GUID_TRAIT_MAP_SPECIFIC(HighGuid::Conversation)
GUID_TRAIT_MAP_SPECIFIC(HighGuid::Creature)
GUID_TRAIT_MAP_SPECIFIC(HighGuid::Vehicle)
GUID_TRAIT_MAP_SPECIFIC(HighGuid::Pet)
GUID_TRAIT_MAP_SPECIFIC(HighGuid::GameObject)
GUID_TRAIT_MAP_SPECIFIC(HighGuid::DynamicObject)
GUID_TRAIT_MAP_SPECIFIC(HighGuid::AreaTrigger)
GUID_TRAIT_MAP_SPECIFIC(HighGuid::Corpse)
GUID_TRAIT_MAP_SPECIFIC(HighGuid::LootObject)
GUID_TRAIT_MAP_SPECIFIC(HighGuid::SceneObject)
GUID_TRAIT_MAP_SPECIFIC(HighGuid::Scenario)
GUID_TRAIT_MAP_SPECIFIC(HighGuid::AIGroup)
GUID_TRAIT_MAP_SPECIFIC(HighGuid::DynamicDoor)
GUID_TRAIT_MAP_SPECIFIC(HighGuid::Vignette)
GUID_TRAIT_MAP_SPECIFIC(HighGuid::CallForHelp)
GUID_TRAIT_MAP_SPECIFIC(HighGuid::AIResource)
GUID_TRAIT_MAP_SPECIFIC(HighGuid::AILock)
GUID_TRAIT_MAP_SPECIFIC(HighGuid::AILockTicket)
GUID_TRAIT_MAP_SPECIFIC(HighGuid::Cast)
// Special case
// Global transports are loaded from `transports` table, RealmSpecific part is used for them.
// after worldserver finishes loading, no more global transports can be created, only the ones existing within instances that never change maps
// here is where MapSpecific comes into play - each map takes over the responsibility to generate transport guids
// on top of this, regular elevators (GAMEOBJECT_TYPE_TRANSPORT) must also use Transport highguid type, otherwise client will reject seeing other players on them
template<>
struct ObjectGuidTraits<HighGuid::Transport>
{
static bool const Global = false;
static bool const RealmSpecific = true;
static bool const MapSpecific = true;
};
MAKE_GUID_TRAIT(HighGuid::Null, ObjectGuidSequenceSource::None, ObjectGuidFormatType::Null);
MAKE_GUID_TRAIT(HighGuid::Uniq, ObjectGuidSequenceSource::None, ObjectGuidFormatType::Uniq);
MAKE_GUID_TRAIT(HighGuid::Player, ObjectGuidSequenceSource::Realm, ObjectGuidFormatType::Player);
MAKE_GUID_TRAIT(HighGuid::Item, ObjectGuidSequenceSource::Realm, ObjectGuidFormatType::Item);
MAKE_GUID_TRAIT(HighGuid::WorldTransaction, ObjectGuidSequenceSource::Map, ObjectGuidFormatType::WorldObject);
MAKE_GUID_TRAIT(HighGuid::StaticDoor, EnumClassFlag<ObjectGuidSequenceSource>{ObjectGuidSequenceSource::Global} | ObjectGuidSequenceSource::Map, ObjectGuidFormatType::Transport);
MAKE_GUID_TRAIT(HighGuid::Transport, EnumClassFlag<ObjectGuidSequenceSource>{ObjectGuidSequenceSource::Global} | ObjectGuidSequenceSource::Map, ObjectGuidFormatType::Transport);
MAKE_GUID_TRAIT(HighGuid::Conversation, ObjectGuidSequenceSource::Map, ObjectGuidFormatType::WorldObject);
MAKE_GUID_TRAIT(HighGuid::Creature, ObjectGuidSequenceSource::Map, ObjectGuidFormatType::WorldObject);
MAKE_GUID_TRAIT(HighGuid::Vehicle, ObjectGuidSequenceSource::Map, ObjectGuidFormatType::WorldObject);
MAKE_GUID_TRAIT(HighGuid::Pet, ObjectGuidSequenceSource::Map, ObjectGuidFormatType::WorldObject);
MAKE_GUID_TRAIT(HighGuid::GameObject, ObjectGuidSequenceSource::Map, ObjectGuidFormatType::WorldObject);
MAKE_GUID_TRAIT(HighGuid::DynamicObject, ObjectGuidSequenceSource::Map, ObjectGuidFormatType::WorldObject);
MAKE_GUID_TRAIT(HighGuid::AreaTrigger, ObjectGuidSequenceSource::Map, ObjectGuidFormatType::WorldObject);
MAKE_GUID_TRAIT(HighGuid::Corpse, ObjectGuidSequenceSource::Map, ObjectGuidFormatType::WorldObject);
MAKE_GUID_TRAIT(HighGuid::LootObject, ObjectGuidSequenceSource::Map, ObjectGuidFormatType::WorldObject);
MAKE_GUID_TRAIT(HighGuid::SceneObject, ObjectGuidSequenceSource::Map, ObjectGuidFormatType::WorldObject);
MAKE_GUID_TRAIT(HighGuid::Scenario, ObjectGuidSequenceSource::Map, ObjectGuidFormatType::WorldObject);
MAKE_GUID_TRAIT(HighGuid::AIGroup, ObjectGuidSequenceSource::Map, ObjectGuidFormatType::WorldObject);
MAKE_GUID_TRAIT(HighGuid::DynamicDoor, ObjectGuidSequenceSource::Map, ObjectGuidFormatType::WorldObject);
MAKE_GUID_TRAIT(HighGuid::ClientActor, ObjectGuidSequenceSource::None, ObjectGuidFormatType::ClientActor);
MAKE_GUID_TRAIT(HighGuid::Vignette, ObjectGuidSequenceSource::Map, ObjectGuidFormatType::WorldObject);
MAKE_GUID_TRAIT(HighGuid::CallForHelp, ObjectGuidSequenceSource::Map, ObjectGuidFormatType::WorldObject);
MAKE_GUID_TRAIT(HighGuid::AIResource, ObjectGuidSequenceSource::Map, ObjectGuidFormatType::WorldObject);
MAKE_GUID_TRAIT(HighGuid::AILock, ObjectGuidSequenceSource::Map, ObjectGuidFormatType::WorldObject);
MAKE_GUID_TRAIT(HighGuid::AILockTicket, ObjectGuidSequenceSource::Map, ObjectGuidFormatType::WorldObject);
MAKE_GUID_TRAIT(HighGuid::ChatChannel, ObjectGuidSequenceSource::Realm, ObjectGuidFormatType::ChatChannel);
MAKE_GUID_TRAIT(HighGuid::Party, ObjectGuidSequenceSource::Global, ObjectGuidFormatType::Global);
MAKE_GUID_TRAIT(HighGuid::Guild, ObjectGuidSequenceSource::Realm, ObjectGuidFormatType::Guild);
MAKE_GUID_TRAIT(HighGuid::WowAccount, ObjectGuidSequenceSource::Global, ObjectGuidFormatType::Global);
MAKE_GUID_TRAIT(HighGuid::BNetAccount, ObjectGuidSequenceSource::Global, ObjectGuidFormatType::Global);
MAKE_GUID_TRAIT(HighGuid::GMTask, ObjectGuidSequenceSource::Global, ObjectGuidFormatType::Global);
MAKE_GUID_TRAIT(HighGuid::MobileSession, ObjectGuidSequenceSource::Realm, ObjectGuidFormatType::MobileSession);
MAKE_GUID_TRAIT(HighGuid::RaidGroup, ObjectGuidSequenceSource::Global, ObjectGuidFormatType::Global);
MAKE_GUID_TRAIT(HighGuid::Spell, ObjectGuidSequenceSource::Global, ObjectGuidFormatType::Global);
MAKE_GUID_TRAIT(HighGuid::Mail, ObjectGuidSequenceSource::Global, ObjectGuidFormatType::Global);
MAKE_GUID_TRAIT(HighGuid::WebObj, ObjectGuidSequenceSource::Realm, ObjectGuidFormatType::WebObj);
MAKE_GUID_TRAIT(HighGuid::LFGObject, ObjectGuidSequenceSource::Global, ObjectGuidFormatType::LFGObject);
MAKE_GUID_TRAIT(HighGuid::LFGList, ObjectGuidSequenceSource::Global, ObjectGuidFormatType::LFGList);
MAKE_GUID_TRAIT(HighGuid::UserRouter, ObjectGuidSequenceSource::Global, ObjectGuidFormatType::Global);
MAKE_GUID_TRAIT(HighGuid::PVPQueueGroup, ObjectGuidSequenceSource::Global, ObjectGuidFormatType::Global);
MAKE_GUID_TRAIT(HighGuid::UserClient, ObjectGuidSequenceSource::Global, ObjectGuidFormatType::Global);
MAKE_GUID_TRAIT(HighGuid::PetBattle, ObjectGuidSequenceSource::Realm, ObjectGuidFormatType::Client);
MAKE_GUID_TRAIT(HighGuid::UniqUserClient, ObjectGuidSequenceSource::Realm, ObjectGuidFormatType::Client);
MAKE_GUID_TRAIT(HighGuid::BattlePet, ObjectGuidSequenceSource::Global, ObjectGuidFormatType::Global);
MAKE_GUID_TRAIT(HighGuid::CommerceObj, ObjectGuidSequenceSource::Global, ObjectGuidFormatType::Global);
MAKE_GUID_TRAIT(HighGuid::ClientSession, ObjectGuidSequenceSource::Realm, ObjectGuidFormatType::Client);
MAKE_GUID_TRAIT(HighGuid::Cast, ObjectGuidSequenceSource::Map, ObjectGuidFormatType::WorldObject);
MAKE_GUID_TRAIT(HighGuid::ClientConnection, ObjectGuidSequenceSource::Realm, ObjectGuidFormatType::Client);
MAKE_GUID_TRAIT(HighGuid::ClubFinder, ObjectGuidSequenceSource::Global, ObjectGuidFormatType::ClubFinder);
class ByteBuffer;
class ObjectGuid;
class ObjectGuidFactory
{
public:
static ObjectGuid CreateNull();
static ObjectGuid CreateUniq(uint64 id);
static ObjectGuid CreatePlayer(uint64 dbId);
static ObjectGuid CreateItem(uint64 dbId);
static ObjectGuid CreateWorldObject(HighGuid type, uint8 subType, uint16 mapId, uint32 serverId, uint32 entry, uint64 counter);
static ObjectGuid CreateTransport(HighGuid type, uint32 counter);
static ObjectGuid CreateClientActor(uint16 ownerType, uint16 ownerId, uint32 counter);
static ObjectGuid CreateChatChannel(bool builtIn, bool trade, uint16 zoneId, uint8 factionGroupMask, uint64 counter);
static ObjectGuid CreateGlobal(HighGuid type, uint64 dbIdHigh, uint64 dbId);
static ObjectGuid CreateGuild(uint64 dbId);
static ObjectGuid CreateMobileSession(uint16 arg1, uint64 counter);
static ObjectGuid CreateWebObj(uint8 arg1, uint8 arg2, uint64 counter);
static ObjectGuid CreateLFGObject(uint8 arg1, uint8 arg2, uint8 arg3, uint8 arg4, bool arg5, uint8 arg6, uint64 counter);
static ObjectGuid CreateLFGList(uint8 arg1, uint64 counter);
static ObjectGuid CreateClient(HighGuid type, uint32 arg1, uint64 counter);
static ObjectGuid CreateClubFinder(uint8 type, uint32 clubFinderId, uint64 dbId);
};
#pragma pack(push, 1)
class TC_GAME_API ObjectGuid
{
friend TC_GAME_API std::ostream& operator<<(std::ostream& stream, ObjectGuid const& guid);
friend class ObjectGuidFactory;
friend TC_GAME_API ByteBuffer& operator<<(ByteBuffer& buf, ObjectGuid const& guid);
friend TC_GAME_API ByteBuffer& operator>>(ByteBuffer& buf, ObjectGuid& guid);
@@ -221,41 +252,31 @@ class TC_GAME_API ObjectGuid
static ObjectGuid const Empty;
static ObjectGuid const TradeItem;
typedef uint64 LowType;
using LowType = uint64;
template<HighGuid type>
static typename std::enable_if<ObjectGuidTraits<type>::Global, ObjectGuid>::type Create(LowType counter) { return Global(type, counter); }
template<HighGuid type>
static typename std::enable_if<ObjectGuidTraits<type>::RealmSpecific, ObjectGuid>::type Create(LowType counter) { return RealmSpecific(type, counter); }
template<HighGuid type>
static typename std::enable_if<ObjectGuidTraits<type>::MapSpecific && type != HighGuid::Transport, ObjectGuid>::type Create(uint16 mapId, uint32 entry, LowType counter) { return MapSpecific(type, 0, mapId, 0, entry, counter); }
template<HighGuid type>
static typename std::enable_if<ObjectGuidTraits<type>::MapSpecific && type != HighGuid::Transport, ObjectGuid>::type Create(uint8 subType, uint16 mapId, uint32 entry, LowType counter) { return MapSpecific(type, subType, mapId, 0, entry, counter); }
ObjectGuid() : _low(0), _high(0) { }
ObjectGuid() { Clear(); }
uint64 GetRawValue(std::size_t i) const { return _data[i]; }
std::vector<uint8> GetRawValue() const;
void SetRawValue(std::vector<uint8> const& guid);
void SetRawValue(uint64 high, uint64 low) { _high = high; _low = low; }
void Clear() { _high = 0; _low = 0; }
void SetRawValue(uint64 high, uint64 low) { _data[0] = low; _data[1] = high; }
void Clear() { std::fill(std::begin(_data), std::end(_data), UI64LIT(0)); }
HighGuid GetHigh() const { return HighGuid((_high >> 58) & 0x3F); }
uint32 GetRealmId() const { return uint32((_high >> 42) & 0x1FFF); }
uint32 GetMapId() const { return uint32((_high >> 29) & 0x1FFF); }
uint32 GetEntry() const { return uint32((_high >> 6) & 0x7FFFFF); }
HighGuid GetHigh() const { return HighGuid((_data[1] >> 58) & 0x3F); }
uint32 GetRealmId() const { return uint32((_data[1] >> 42) & 0xFFFF); }
uint32 GetMapId() const { return uint32((_data[1] >> 29) & 0x1FFF); }
uint32 GetEntry() const { return uint32((_data[1] >> 6) & 0x7FFFFF); }
uint32 GetSubType() const { return uint32(_data[1] & 0x3F); }
LowType GetCounter() const
{
switch (GetHigh())
{
case HighGuid::Transport:
return (_high >> 38) & UI64LIT(0xFFFFF);
return (_data[1] >> 38) & UI64LIT(0xFFFFF);
default:
break;
}
return _low & UI64LIT(0x000000FFFFFFFFFF);
return _data[0] & UI64LIT(0x000000FFFFFFFFFF);
}
static LowType GetMaxCounter(HighGuid high)
@@ -272,7 +293,7 @@ class TC_GAME_API ObjectGuid
LowType GetMaxCounter() const { return GetMaxCounter(GetHigh()); }
bool IsEmpty() const { return _low == 0 && _high == 0; }
bool IsEmpty() const { return _data[0] == 0 && _data[1] == 0; }
bool IsCreature() const { return GetHigh() == HighGuid::Creature; }
bool IsPet() const { return GetHigh() == HighGuid::Pet; }
bool IsVehicle() const { return GetHigh() == HighGuid::Vehicle; }
@@ -294,92 +315,67 @@ class TC_GAME_API ObjectGuid
bool IsConversation() const { return GetHigh() == HighGuid::Conversation; }
bool IsCast() const { return GetHigh() == HighGuid::Cast; }
static TypeID GetTypeId(HighGuid high)
{
switch (high)
{
case HighGuid::Item: return TYPEID_ITEM;
case HighGuid::Creature:
case HighGuid::Pet:
case HighGuid::Vehicle: return TYPEID_UNIT;
case HighGuid::Player: return TYPEID_PLAYER;
case HighGuid::GameObject:
case HighGuid::Transport: return TYPEID_GAMEOBJECT;
case HighGuid::DynamicObject: return TYPEID_DYNAMICOBJECT;
case HighGuid::Corpse: return TYPEID_CORPSE;
case HighGuid::AreaTrigger: return TYPEID_AREATRIGGER;
case HighGuid::SceneObject: return TYPEID_SCENEOBJECT;
case HighGuid::Conversation: return TYPEID_CONVERSATION;
default: return TYPEID_OBJECT;
}
}
TypeID GetTypeId() const { return GetTypeId(GetHigh()); }
bool operator!() const { return IsEmpty(); }
bool operator== (ObjectGuid const& guid) const { return _low == guid._low && _high == guid._high; }
bool operator== (ObjectGuid const& guid) const { return _data[0] == guid._data[0] && _data[1] == guid._data[1]; }
bool operator!= (ObjectGuid const& guid) const { return !(*this == guid); }
bool operator< (ObjectGuid const& guid) const
{
if (_high < guid._high)
if (_data[1] < guid._data[1])
return true;
else if (_high > guid._high)
else if (_data[1] > guid._data[1])
return false;
return _low < guid._low;
return _data[0] < guid._data[0];
}
static char const* GetTypeName(HighGuid high);
char const* GetTypeName() const { return !IsEmpty() ? GetTypeName(GetHigh()) : "None"; }
std::string ToString() const;
std::string ToHexString() const;
std::size_t GetHash() const;
template<HighGuid type> static std::enable_if_t<ObjectGuidTraits<type>::Format::value == ObjectGuidFormatType::Null, ObjectGuid> Create() { return ObjectGuidFactory::CreateNull(); }
template<HighGuid type> static std::enable_if_t<ObjectGuidTraits<type>::Format::value == ObjectGuidFormatType::Uniq, ObjectGuid> Create(ObjectGuid::LowType id) { return ObjectGuidFactory::CreateUniq(id); }
template<HighGuid type> static std::enable_if_t<ObjectGuidTraits<type>::Format::value == ObjectGuidFormatType::Player, ObjectGuid> Create(ObjectGuid::LowType dbId) { return ObjectGuidFactory::CreatePlayer(dbId); }
template<HighGuid type> static std::enable_if_t<ObjectGuidTraits<type>::Format::value == ObjectGuidFormatType::Item, ObjectGuid> Create(ObjectGuid::LowType dbId) { return ObjectGuidFactory::CreateItem(dbId); }
template<HighGuid type> static std::enable_if_t<ObjectGuidTraits<type>::Format::value == ObjectGuidFormatType::WorldObject, ObjectGuid> Create(uint16 mapId, uint32 entry, ObjectGuid::LowType counter) { return ObjectGuidFactory::CreateWorldObject(type, 0, mapId, 0, entry, counter); }
template<HighGuid type> static std::enable_if_t<ObjectGuidTraits<type>::Format::value == ObjectGuidFormatType::WorldObject, ObjectGuid> Create(uint8 subType, uint16 mapId, uint32 entry, ObjectGuid::LowType counter) { return ObjectGuidFactory::CreateWorldObject(type, subType, mapId, 0, entry, counter); }
template<HighGuid type> static std::enable_if_t<ObjectGuidTraits<type>::Format::value == ObjectGuidFormatType::Transport, ObjectGuid> Create(uint32 counter) { return ObjectGuidFactory::CreateTransport(type, counter); }
template<HighGuid type> static std::enable_if_t<ObjectGuidTraits<type>::Format::value == ObjectGuidFormatType::ClientActor, ObjectGuid> Create(uint16 ownerType, uint16 ownerId, uint32 counter) { return ObjectGuidFactory::CreateClientActor(ownerType, ownerId, counter); }
template<HighGuid type> static std::enable_if_t<ObjectGuidTraits<type>::Format::value == ObjectGuidFormatType::ChatChannel, ObjectGuid> Create(bool builtIn, bool trade, uint16 zoneId, uint8 factionGroupMask, ObjectGuid::LowType counter) { return ObjectGuidFactory::CreateChatChannel(builtIn, trade, zoneId, factionGroupMask, counter); }
template<HighGuid type> static std::enable_if_t<ObjectGuidTraits<type>::Format::value == ObjectGuidFormatType::Global, ObjectGuid> Create(ObjectGuid::LowType dbId) { return ObjectGuidFactory::CreateGlobal(type, UI64LIT(0), dbId); }
template<HighGuid type> static std::enable_if_t<ObjectGuidTraits<type>::Format::value == ObjectGuidFormatType::Guild, ObjectGuid> Create(ObjectGuid::LowType dbId) { return ObjectGuidFactory::CreateGuild(dbId); }
template<HighGuid type> static std::enable_if_t<ObjectGuidTraits<type>::Format::value == ObjectGuidFormatType::MobileSession, ObjectGuid> Create(uint16 arg1, ObjectGuid::LowType counter) { return ObjectGuidFactory::CreateMobileSession(arg1, counter); }
template<HighGuid type> static std::enable_if_t<ObjectGuidTraits<type>::Format::value == ObjectGuidFormatType::WebObj, ObjectGuid> Create(uint8 arg1, uint8 arg2, ObjectGuid::LowType counter) { return ObjectGuidFactory::CreateWebObj(arg1, arg2, counter); }
template<HighGuid type> static std::enable_if_t<ObjectGuidTraits<type>::Format::value == ObjectGuidFormatType::LFGObject, ObjectGuid> Create(uint8 arg1, uint8 arg2, uint8 arg3, uint8 arg4, bool arg5, uint8 arg6, ObjectGuid::LowType counter) { return ObjectGuidFactory::CreateLFGObject(arg1, arg2, arg3, arg4, arg5, arg6, counter); }
template<HighGuid type> static std::enable_if_t<ObjectGuidTraits<type>::Format::value == ObjectGuidFormatType::LFGList, ObjectGuid> Create(uint8 arg1, ObjectGuid::LowType counter) { return ObjectGuidFactory::CreateLFGList(arg1, counter); }
template<HighGuid type> static std::enable_if_t<ObjectGuidTraits<type>::Format::value == ObjectGuidFormatType::Client, ObjectGuid> Create(uint32 arg1, ObjectGuid::LowType counter) { return ObjectGuidFactory::CreateClient(type, arg1, counter); }
template<HighGuid type> static std::enable_if_t<ObjectGuidTraits<type>::Format::value == ObjectGuidFormatType::ClubFinder, ObjectGuid> Create(uint8 clubType, uint32 clubFinderId, ObjectGuid::LowType dbId) { return ObjectGuidFactory::CreateClubFinder(clubType, clubFinderId, dbId); }
protected:
static bool HasEntry(HighGuid high)
ObjectGuid(uint64 high, uint64 low)
{
switch (high)
{
case HighGuid::GameObject:
case HighGuid::Creature:
case HighGuid::Pet:
case HighGuid::Vehicle:
default:
return true;
}
_data[0] = low;
_data[1] = high;
}
bool HasEntry() const { return HasEntry(GetHigh()); }
static ObjectGuid Global(HighGuid type, LowType counter);
static ObjectGuid RealmSpecific(HighGuid type, LowType counter);
static ObjectGuid MapSpecific(HighGuid type, uint8 subType, uint16 mapId, uint32 serverId, uint32 entry, LowType counter);
ObjectGuid(uint64 high, uint64 low) : _low(low), _high(high) { }
uint64 _low;
uint64 _high;
uint64 _data[2];
};
template<>
inline typename std::enable_if<ObjectGuidTraits<HighGuid::Transport>::RealmSpecific, ObjectGuid>::type ObjectGuid::Create<HighGuid::Transport>(LowType counter)
{
return ObjectGuid(uint64((uint64(HighGuid::Transport) << 58) | uint64(counter << 38)), UI64LIT(0));
}
#pragma pack(pop)
// Some Shared defines
typedef std::set<ObjectGuid> GuidSet;
typedef std::list<ObjectGuid> GuidList;
typedef std::deque<ObjectGuid> GuidDeque;
typedef std::vector<ObjectGuid> GuidVector;
typedef std::unordered_set<ObjectGuid> GuidUnorderedSet;
using GuidSet = std::set<ObjectGuid>;
using GuidList = std::list<ObjectGuid>;
using GuidDeque = std::deque<ObjectGuid>;
using GuidVector = std::vector<ObjectGuid>;
using GuidUnorderedSet = std::unordered_set<ObjectGuid>;
class TC_GAME_API ObjectGuidGeneratorBase
{
public:
ObjectGuidGeneratorBase(ObjectGuid::LowType start = UI64LIT(1)) : _nextGuid(start) { }
virtual ~ObjectGuidGeneratorBase() { }
virtual ~ObjectGuidGeneratorBase() = default;
virtual void Set(uint64 val) { _nextGuid = val; }
virtual ObjectGuid::LowType Generate() = 0;
@@ -407,8 +403,6 @@ public:
TC_GAME_API ByteBuffer& operator<<(ByteBuffer& buf, ObjectGuid const& guid);
TC_GAME_API ByteBuffer& operator>>(ByteBuffer& buf, ObjectGuid& guid);
TC_GAME_API std::ostream& operator<<(std::ostream& stream, ObjectGuid const& guid);
namespace std
{
template<>

View File

@@ -11994,9 +11994,9 @@ Item* Player::StoreNewItem(ItemPosCountVec const& pos, uint32 itemId, bool updat
// save data
std::ostringstream ss;
GuidSet::const_iterator itr = allowedLooters.begin();
ss << *itr;
ss << itr->GetCounter();
for (++itr; itr != allowedLooters.end(); ++itr)
ss << ' ' << *itr;
ss << ' ' << itr->GetCounter();
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_ITEM_BOP_TRADE);
stmt->setUInt64(0, item->GetGUID().GetCounter());

View File

@@ -1330,7 +1330,9 @@ class TC_GAME_API ObjectMgr
template<HighGuid type>
inline ObjectGuidGeneratorBase& GetGenerator()
{
static_assert(ObjectGuidTraits<type>::Global || ObjectGuidTraits<type>::RealmSpecific, "Only global guid can be generated in ObjectMgr context");
static_assert(ObjectGuidTraits<type>::SequenceSource.HasFlag(ObjectGuidSequenceSource::Global)
|| ObjectGuidTraits<type>::SequenceSource.HasFlag(ObjectGuidSequenceSource::Realm),
"Only global guid can be generated in ObjectMgr context");
return GetGuidSequenceGenerator<type>();
}

View File

@@ -558,7 +558,7 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
template<HighGuid high>
inline ObjectGuid::LowType GenerateLowGuid()
{
static_assert(ObjectGuidTraits<high>::MapSpecific, "Only map specific guid can be generated in Map context");
static_assert(ObjectGuidTraits<high>::SequenceSource.HasFlag(ObjectGuidSequenceSource::Map), "Only map specific guid can be generated in Map context");
return GetGuidSequenceGenerator<high>().Generate();
}