mirror of
https://github.com/araxiaonline/TrinityCore.git
synced 2026-06-17 21:50:50 -04:00
Core/Objects: Make guid generators atomic
(cherry picked from commit 6c925ed40c)
This commit is contained in:
@@ -14,11 +14,12 @@
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __TRINITY_CHANNELMGR_H
|
||||
#define __TRINITY_CHANNELMGR_H
|
||||
#ifndef TRINITYCORE_CHANNEL_MGR_H
|
||||
#define TRINITYCORE_CHANNEL_MGR_H
|
||||
|
||||
#include "Define.h"
|
||||
#include "ObjectGuid.h"
|
||||
#include "ObjectGuidSequenceGenerator.h"
|
||||
#include "SharedDefines.h"
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
@@ -19,10 +19,9 @@
|
||||
#include "ByteBuffer.h"
|
||||
#include "Errors.h"
|
||||
#include "Hash.h"
|
||||
#include "Log.h"
|
||||
#include "RealmList.h"
|
||||
#include "StringFormat.h"
|
||||
#include "Util.h"
|
||||
#include "World.h"
|
||||
#include <charconv>
|
||||
|
||||
static_assert(sizeof(ObjectGuid) == sizeof(uint64) * 2, "ObjectGuid must be exactly 16 bytes");
|
||||
@@ -31,9 +30,12 @@ namespace
|
||||
{
|
||||
struct ObjectGuidInfo
|
||||
{
|
||||
std::string Names[AsUnderlyingType(HighGuid::Count)];
|
||||
fmt::appender(*ClientFormatFunction[AsUnderlyingType(HighGuid::Count)])(fmt::format_context& ctx, std::string const& typeName, ObjectGuid const& guid);
|
||||
ObjectGuid(*ClientParseFunction[AsUnderlyingType(HighGuid::Count)])(HighGuid type, std::string_view guidString);
|
||||
using FormatFunction = fmt::appender(fmt::format_context& ctx, std::string_view typeName, ObjectGuid const& guid);
|
||||
using ParseFunction = ObjectGuid(HighGuid type, std::string_view guidString);
|
||||
|
||||
std::string_view Names[AsUnderlyingType(HighGuid::Count)];
|
||||
std::array<FormatFunction*, AsUnderlyingType(HighGuid::Count)> ClientFormatFunction;
|
||||
std::array<ParseFunction*, AsUnderlyingType(HighGuid::Count)> ClientParseFunction;
|
||||
|
||||
static std::string Format(ObjectGuid const& guid)
|
||||
{
|
||||
@@ -72,9 +74,9 @@ namespace
|
||||
static constexpr inline FormatBase dec{ 10 };
|
||||
static constexpr inline FormatBase hex{ 16 };
|
||||
|
||||
static fmt::appender AppendTypeName(fmt::format_context& ctx, std::string const& type)
|
||||
static fmt::appender AppendTypeName(fmt::format_context& ctx, std::string_view type)
|
||||
{
|
||||
return std::copy(type.begin(), type.end(), ctx.out());
|
||||
return std::ranges::copy(type, ctx.out()).out;
|
||||
}
|
||||
|
||||
template <FormatPadding Width, FormatBase Base>
|
||||
@@ -90,19 +92,19 @@ namespace
|
||||
if constexpr (Width != 0)
|
||||
{
|
||||
if (std::ptrdiff_t written = std::distance(buf.data(), end); written < Width)
|
||||
std::fill_n(ctx.out(), Width - written, '0');
|
||||
std::ranges::fill_n(ctx.out(), Width - written, '0');
|
||||
}
|
||||
|
||||
if constexpr (Base > 10)
|
||||
return std::transform(buf.data(), end, ctx.out(), charToUpper);
|
||||
return std::ranges::transform(buf.data(), end, ctx.out(), charToUpper).out;
|
||||
else
|
||||
return std::copy(buf.data(), end, ctx.out());
|
||||
return std::ranges::copy(buf.data(), end, ctx.out()).out;
|
||||
}
|
||||
|
||||
static fmt::appender AppendComponent(fmt::format_context& ctx, std::string_view component)
|
||||
{
|
||||
*ctx.out() = '-';
|
||||
return std::copy(component.begin(), component.end(), ctx.out());
|
||||
return std::ranges::copy(component, ctx.out()).out;
|
||||
}
|
||||
|
||||
template <FormatBase Base, typename T>
|
||||
@@ -126,9 +128,9 @@ namespace
|
||||
|
||||
static bool ParseDone(std::string_view const& sv) { return sv.empty(); }
|
||||
|
||||
static fmt::appender FormatNull(fmt::format_context& ctx, std::string const& /*typeName*/, ObjectGuid const& /*guid*/)
|
||||
static fmt::appender FormatNull(fmt::format_context& ctx, std::string_view /*typeName*/, ObjectGuid const& /*guid*/)
|
||||
{
|
||||
return std::fill_n(ctx.out(), 16, '0');
|
||||
return std::ranges::fill_n(ctx.out(), 16, '0');
|
||||
}
|
||||
|
||||
static ObjectGuid ParseNull(HighGuid, std::string_view)
|
||||
@@ -136,80 +138,56 @@ namespace
|
||||
return ObjectGuid::Empty;
|
||||
}
|
||||
|
||||
static fmt::appender FormatUniq(fmt::format_context& ctx, std::string const& typeName, ObjectGuid const& guid)
|
||||
static constexpr std::array<std::string_view, 20> UniqNames =
|
||||
{
|
||||
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",
|
||||
nullptr,
|
||||
"WOWGUID_PENDING_PERMANENT_CHARACTER_ASSIGNMENT"
|
||||
};
|
||||
"",
|
||||
"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",
|
||||
"",
|
||||
"WOWGUID_FAKE_MODERATOR",
|
||||
"",
|
||||
"",
|
||||
"WOWGUID_UNIQUE_ACCOUNT_OBJ_INITIALIZATION",
|
||||
"",
|
||||
"WOWGUID_PENDING_PERMANENT_CHARACTER_ASSIGNMENT"
|
||||
};
|
||||
|
||||
static fmt::appender FormatUniq(fmt::format_context& ctx, std::string_view typeName, ObjectGuid const& guid)
|
||||
{
|
||||
ObjectGuid::LowType id = guid.GetCounter();
|
||||
if (id >= std::size(uniqNames) || !uniqNames[id])
|
||||
if (id >= UniqNames.size() || UniqNames[id].empty())
|
||||
id = 3;
|
||||
|
||||
ctx.advance_to(AppendTypeName(ctx, typeName));
|
||||
ctx.advance_to(AppendComponent(ctx, uniqNames[id]));
|
||||
ctx.advance_to(AppendComponent(ctx, UniqNames[id]));
|
||||
return ctx.out();
|
||||
}
|
||||
|
||||
static ObjectGuid ParseUniq(HighGuid /*type*/, std::string_view guidString)
|
||||
{
|
||||
constexpr char const* uniqNames[] =
|
||||
for (std::size_t id = 0; id < UniqNames.size(); ++id)
|
||||
{
|
||||
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",
|
||||
nullptr,
|
||||
"WOWGUID_PENDING_PERMANENT_CHARACTER_ASSIGNMENT"
|
||||
};
|
||||
|
||||
for (std::size_t id = 0; id < std::size(uniqNames); ++id)
|
||||
{
|
||||
if (!uniqNames[id])
|
||||
if (UniqNames[id].empty())
|
||||
continue;
|
||||
|
||||
if (guidString == uniqNames[id])
|
||||
if (guidString == UniqNames[id])
|
||||
return ObjectGuidFactory::CreateUniq(id);
|
||||
}
|
||||
|
||||
return ObjectGuid::FromStringFailed;
|
||||
}
|
||||
|
||||
static fmt::appender FormatPlayer(fmt::format_context& ctx, std::string const& typeName, ObjectGuid const& guid)
|
||||
static fmt::appender FormatPlayer(fmt::format_context& ctx, std::string_view typeName, ObjectGuid const& guid)
|
||||
{
|
||||
ctx.advance_to(AppendTypeName(ctx, typeName));
|
||||
ctx.advance_to(AppendComponent<no_padding, dec>(ctx, guid.GetRealmId()));
|
||||
@@ -230,7 +208,7 @@ namespace
|
||||
return ObjectGuidFactory::CreatePlayer(realmId, dbId);
|
||||
}
|
||||
|
||||
static fmt::appender FormatItem(fmt::format_context& ctx, std::string const& typeName, ObjectGuid const& guid)
|
||||
static fmt::appender FormatItem(fmt::format_context& ctx, std::string_view typeName, ObjectGuid const& guid)
|
||||
{
|
||||
ctx.advance_to(AppendTypeName(ctx, typeName));
|
||||
ctx.advance_to(AppendComponent<no_padding, dec>(ctx, guid.GetRealmId()));
|
||||
@@ -254,7 +232,7 @@ namespace
|
||||
return ObjectGuidFactory::CreateItem(realmId, dbId);
|
||||
}
|
||||
|
||||
static fmt::appender FormatWorldObject(fmt::format_context& ctx, std::string const& typeName, ObjectGuid const& guid)
|
||||
static fmt::appender FormatWorldObject(fmt::format_context& ctx, std::string_view typeName, ObjectGuid const& guid)
|
||||
{
|
||||
ctx.advance_to(AppendTypeName(ctx, typeName));
|
||||
ctx.advance_to(AppendComponent<no_padding, dec>(ctx, guid.GetSubType()));
|
||||
@@ -287,7 +265,7 @@ namespace
|
||||
return ObjectGuidFactory::CreateWorldObject(type, subType, realmId, mapId, serverId, id, counter);
|
||||
}
|
||||
|
||||
static fmt::appender FormatTransport(fmt::format_context& ctx, std::string const& typeName, ObjectGuid const& guid)
|
||||
static fmt::appender FormatTransport(fmt::format_context& ctx, std::string_view typeName, ObjectGuid const& guid)
|
||||
{
|
||||
ctx.advance_to(AppendTypeName(ctx, typeName));
|
||||
ctx.advance_to(AppendComponent<no_padding, dec>(ctx, guid.GetEntry()));
|
||||
@@ -308,7 +286,7 @@ namespace
|
||||
return ObjectGuidFactory::CreateTransport(type, counter);
|
||||
}
|
||||
|
||||
static fmt::appender FormatClientActor(fmt::format_context& ctx, std::string const& typeName, ObjectGuid const& guid)
|
||||
static fmt::appender FormatClientActor(fmt::format_context& ctx, std::string_view typeName, ObjectGuid const& guid)
|
||||
{
|
||||
ctx.advance_to(AppendTypeName(ctx, typeName));
|
||||
ctx.advance_to(AppendComponent<no_padding, dec>(ctx, guid.GetRealmId()));
|
||||
@@ -332,7 +310,7 @@ namespace
|
||||
return ObjectGuidFactory::CreateClientActor(ownerType, ownerId, counter);
|
||||
}
|
||||
|
||||
static fmt::appender FormatChatChannel(fmt::format_context& ctx, std::string const& typeName, ObjectGuid const& guid)
|
||||
static fmt::appender FormatChatChannel(fmt::format_context& ctx, std::string_view typeName, ObjectGuid const& guid)
|
||||
{
|
||||
uint32 builtIn = (guid.GetRawValue(1) >> 25) & 0x1;
|
||||
uint32 trade = (guid.GetRawValue(1) >> 24) & 0x1;
|
||||
@@ -370,7 +348,7 @@ namespace
|
||||
return ObjectGuidFactory::CreateChatChannel(realmId, builtIn != 0, trade != 0, zoneId, factionGroupMask, id);
|
||||
}
|
||||
|
||||
static fmt::appender FormatGlobal(fmt::format_context& ctx, std::string const& typeName, ObjectGuid const& guid)
|
||||
static fmt::appender FormatGlobal(fmt::format_context& ctx, std::string_view typeName, ObjectGuid const& guid)
|
||||
{
|
||||
ctx.advance_to(AppendTypeName(ctx, typeName));
|
||||
ctx.advance_to(AppendComponent<no_padding, dec>(ctx, guid.GetRawValue(1) & 0x3FFFFFFFFFFFFFF));
|
||||
@@ -391,7 +369,7 @@ namespace
|
||||
return ObjectGuidFactory::CreateGlobal(type, dbIdHigh, dbIdLow);
|
||||
}
|
||||
|
||||
static fmt::appender FormatGuild(fmt::format_context& ctx, std::string const& typeName, ObjectGuid const& guid)
|
||||
static fmt::appender FormatGuild(fmt::format_context& ctx, std::string_view typeName, ObjectGuid const& guid)
|
||||
{
|
||||
ctx.advance_to(AppendTypeName(ctx, typeName));
|
||||
ctx.advance_to(AppendComponent<no_padding, dec>(ctx, guid.GetRealmId()));
|
||||
@@ -412,7 +390,7 @@ namespace
|
||||
return ObjectGuidFactory::CreateGuild(type, realmId, dbId);
|
||||
}
|
||||
|
||||
static fmt::appender FormatMobileSession(fmt::format_context& ctx, std::string const& typeName, ObjectGuid const& guid)
|
||||
static fmt::appender FormatMobileSession(fmt::format_context& ctx, std::string_view typeName, ObjectGuid const& guid)
|
||||
{
|
||||
ctx.advance_to(AppendTypeName(ctx, typeName));
|
||||
ctx.advance_to(AppendComponent<no_padding, dec>(ctx, guid.GetRealmId()));
|
||||
@@ -436,7 +414,7 @@ namespace
|
||||
return ObjectGuidFactory::CreateMobileSession(realmId, arg1, counter);
|
||||
}
|
||||
|
||||
static fmt::appender FormatWebObj(fmt::format_context& ctx, std::string const& typeName, ObjectGuid const& guid)
|
||||
static fmt::appender FormatWebObj(fmt::format_context& ctx, std::string_view typeName, ObjectGuid const& guid)
|
||||
{
|
||||
ctx.advance_to(AppendTypeName(ctx, typeName));
|
||||
ctx.advance_to(AppendComponent<no_padding, dec>(ctx, guid.GetRealmId()));
|
||||
@@ -463,7 +441,7 @@ namespace
|
||||
return ObjectGuidFactory::CreateWebObj(realmId, arg1, arg2, counter);
|
||||
}
|
||||
|
||||
static fmt::appender FormatLFGObject(fmt::format_context& ctx, std::string const& typeName, ObjectGuid const& guid)
|
||||
static fmt::appender FormatLFGObject(fmt::format_context& ctx, std::string_view typeName, ObjectGuid const& guid)
|
||||
{
|
||||
ctx.advance_to(AppendTypeName(ctx, typeName));
|
||||
ctx.advance_to(AppendComponent<no_padding, dec>(ctx, guid.GetRawValue(1) >> 54 & 0xF));
|
||||
@@ -499,7 +477,7 @@ namespace
|
||||
return ObjectGuidFactory::CreateLFGObject(arg1, arg2, arg3, arg4, arg5 != 0, arg6, counter);
|
||||
}
|
||||
|
||||
static fmt::appender FormatLFGList(fmt::format_context& ctx, std::string const& typeName, ObjectGuid const& guid)
|
||||
static fmt::appender FormatLFGList(fmt::format_context& ctx, std::string_view typeName, ObjectGuid const& guid)
|
||||
{
|
||||
ctx.advance_to(AppendTypeName(ctx, typeName));
|
||||
ctx.advance_to(AppendComponent<no_padding, dec>(ctx, guid.GetRawValue(1) >> 54 & 0xF));
|
||||
@@ -520,7 +498,7 @@ namespace
|
||||
return ObjectGuidFactory::CreateLFGList(arg1, counter);
|
||||
}
|
||||
|
||||
static fmt::appender FormatClient(fmt::format_context& ctx, std::string const& typeName, ObjectGuid const& guid)
|
||||
static fmt::appender FormatClient(fmt::format_context& ctx, std::string_view typeName, ObjectGuid const& guid)
|
||||
{
|
||||
ctx.advance_to(AppendTypeName(ctx, typeName));
|
||||
ctx.advance_to(AppendComponent<no_padding, dec>(ctx, guid.GetRealmId()));
|
||||
@@ -544,7 +522,7 @@ namespace
|
||||
return ObjectGuidFactory::CreateClient(type, realmId, arg1, counter);
|
||||
}
|
||||
|
||||
static fmt::appender FormatClubFinder(fmt::format_context& ctx, std::string const& typeName, ObjectGuid const& guid)
|
||||
static fmt::appender FormatClubFinder(fmt::format_context& ctx, std::string_view typeName, ObjectGuid const& guid)
|
||||
{
|
||||
uint32 type = uint32(guid.GetRawValue(1) >> 33) & 0xFF;
|
||||
uint32 clubFinderId = uint32(guid.GetRawValue(1)) & 0xFFFFFFFF;
|
||||
@@ -600,7 +578,7 @@ namespace
|
||||
return ObjectGuidFactory::CreateClubFinder(realmId, type, clubFinderId, dbId);
|
||||
}
|
||||
|
||||
static fmt::appender FormatToolsClient(fmt::format_context& ctx, std::string const& typeName, ObjectGuid const& guid)
|
||||
static fmt::appender FormatToolsClient(fmt::format_context& ctx, std::string_view typeName, ObjectGuid const& guid)
|
||||
{
|
||||
ctx.advance_to(AppendTypeName(ctx, typeName));
|
||||
ctx.advance_to(AppendComponent<no_padding, dec>(ctx, guid.GetMapId()));
|
||||
@@ -624,7 +602,7 @@ namespace
|
||||
return ObjectGuidFactory::CreateToolsClient(mapId, serverId, counter);
|
||||
}
|
||||
|
||||
static fmt::appender FormatWorldLayer(fmt::format_context& ctx, std::string const& typeName, ObjectGuid const& guid)
|
||||
static fmt::appender FormatWorldLayer(fmt::format_context& ctx, std::string_view typeName, ObjectGuid const& guid)
|
||||
{
|
||||
ctx.advance_to(AppendTypeName(ctx, typeName));
|
||||
ctx.advance_to(AppendComponent<padding<0>, hex>(ctx, guid.GetRawValue(1) >> 10 & 0xFFFFFFFF));
|
||||
@@ -651,7 +629,7 @@ namespace
|
||||
return ObjectGuidFactory::CreateWorldLayer(arg1, arg2, arg3, arg4);
|
||||
}
|
||||
|
||||
static fmt::appender FormatLMMLobby(fmt::format_context& ctx, std::string const& typeName, ObjectGuid const& guid)
|
||||
static fmt::appender FormatLMMLobby(fmt::format_context& ctx, std::string_view typeName, ObjectGuid const& guid)
|
||||
{
|
||||
ctx.advance_to(AppendTypeName(ctx, typeName));
|
||||
ctx.advance_to(AppendComponent<no_padding, dec>(ctx, guid.GetRealmId()));
|
||||
@@ -687,10 +665,12 @@ namespace
|
||||
ObjectGuidInfo::ObjectGuidInfo()
|
||||
{
|
||||
#define SET_GUID_INFO(type, format, parse) \
|
||||
Names[AsUnderlyingType(HighGuid::type)] = #type;\
|
||||
Names[AsUnderlyingType(HighGuid::type)] = #type ## sv;\
|
||||
ClientFormatFunction[AsUnderlyingType(HighGuid::type)] = &ObjectGuidInfo::format;\
|
||||
ClientParseFunction[AsUnderlyingType(HighGuid::type)] = &ObjectGuidInfo::parse
|
||||
|
||||
using namespace std::string_view_literals;
|
||||
|
||||
SET_GUID_INFO(Null, FormatNull, ParseNull);
|
||||
SET_GUID_INFO(Uniq, FormatUniq, ParseUniq);
|
||||
SET_GUID_INFO(Player, FormatPlayer, ParsePlayer);
|
||||
@@ -1008,28 +988,3 @@ ByteBuffer& operator>>(ByteBuffer& buf, ObjectGuid& guid)
|
||||
buf.ReadPackedUInt64(highMask, guid._data[1]);
|
||||
return buf;
|
||||
}
|
||||
|
||||
ObjectGuid::LowType ObjectGuidGenerator::Generate()
|
||||
{
|
||||
if (_nextGuid >= ObjectGuid::GetMaxCounter(_high) - 1)
|
||||
HandleCounterOverflow();
|
||||
|
||||
if (_high == HighGuid::Creature || _high == HighGuid::Vehicle || _high == HighGuid::GameObject || _high == HighGuid::Transport)
|
||||
CheckGuidTrigger();
|
||||
|
||||
return _nextGuid++;
|
||||
}
|
||||
|
||||
void ObjectGuidGenerator::HandleCounterOverflow()
|
||||
{
|
||||
TC_LOG_ERROR("misc", "{} guid overflow!! Can't continue, shutting down server. ", ObjectGuid::GetTypeName(_high));
|
||||
World::StopNow(ERROR_EXIT_CODE);
|
||||
}
|
||||
|
||||
void ObjectGuidGenerator::CheckGuidTrigger()
|
||||
{
|
||||
if (!sWorld->IsGuidAlert() && _nextGuid > sWorld->getIntConfig(CONFIG_RESPAWN_GUIDALERTLEVEL))
|
||||
sWorld->TriggerGuidAlert();
|
||||
else if (!sWorld->IsGuidWarning() && _nextGuid > sWorld->getIntConfig(CONFIG_RESPAWN_GUIDWARNLEVEL))
|
||||
sWorld->TriggerGuidWarning();
|
||||
}
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef ObjectGuid_h__
|
||||
#define ObjectGuid_h__
|
||||
#ifndef TRINITYCORE_OBJECT_GUID_H
|
||||
#define TRINITYCORE_OBJECT_GUID_H
|
||||
|
||||
#include "Define.h"
|
||||
#include "EnumFlag.h"
|
||||
@@ -394,23 +394,6 @@ using GuidList = std::list<ObjectGuid>;
|
||||
using GuidVector = std::vector<ObjectGuid>;
|
||||
using GuidUnorderedSet = std::unordered_set<ObjectGuid>;
|
||||
|
||||
class TC_GAME_API ObjectGuidGenerator
|
||||
{
|
||||
public:
|
||||
explicit ObjectGuidGenerator(HighGuid high, ObjectGuid::LowType start = UI64LIT(1)) : _high(high), _nextGuid(start) { }
|
||||
~ObjectGuidGenerator() = default;
|
||||
|
||||
void Set(ObjectGuid::LowType val) { _nextGuid = val; }
|
||||
ObjectGuid::LowType Generate();
|
||||
ObjectGuid::LowType GetNextAfterMaxUsed() const { return _nextGuid; }
|
||||
|
||||
protected:
|
||||
void HandleCounterOverflow();
|
||||
void CheckGuidTrigger();
|
||||
HighGuid _high;
|
||||
ObjectGuid::LowType _nextGuid;
|
||||
};
|
||||
|
||||
TC_GAME_API ByteBuffer& operator<<(ByteBuffer& buf, ObjectGuid const& guid);
|
||||
TC_GAME_API ByteBuffer& operator>>(ByteBuffer& buf, ObjectGuid& guid);
|
||||
|
||||
@@ -515,4 +498,4 @@ namespace Trinity
|
||||
}
|
||||
}
|
||||
|
||||
#endif // ObjectGuid_h__
|
||||
#endif // TRINITYCORE_OBJECT_GUID_H
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ObjectGuidSequenceGenerator.h"
|
||||
#include "Log.h"
|
||||
#include "World.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
void HandleCounterOverflow(HighGuid high)
|
||||
{
|
||||
TC_LOG_ERROR("misc", "{} guid overflow!! Can't continue, shutting down server. ", ObjectGuid::GetTypeName(high));
|
||||
World::StopNow(ERROR_EXIT_CODE);
|
||||
}
|
||||
|
||||
void CheckGuidTrigger(ObjectGuid::LowType newCounter)
|
||||
{
|
||||
World* world = sWorld;
|
||||
if (!world->IsGuidAlert() && newCounter > world->getIntConfig(CONFIG_RESPAWN_GUIDALERTLEVEL))
|
||||
world->TriggerGuidAlert();
|
||||
else if (!world->IsGuidWarning() && newCounter > world->getIntConfig(CONFIG_RESPAWN_GUIDWARNLEVEL))
|
||||
world->TriggerGuidWarning();
|
||||
}
|
||||
|
||||
ObjectGuid::LowType CheckGeneratedGuidValue(HighGuid high, ObjectGuid::LowType newCounter)
|
||||
{
|
||||
if (newCounter >= ObjectGuid::GetMaxCounter(high) - 1)
|
||||
HandleCounterOverflow(high);
|
||||
|
||||
if (high == HighGuid::Creature || high == HighGuid::Vehicle || high == HighGuid::GameObject || high == HighGuid::Transport)
|
||||
CheckGuidTrigger(newCounter);
|
||||
|
||||
return newCounter;
|
||||
}
|
||||
}
|
||||
|
||||
ObjectGuid::LowType ObjectGuidGenerator::Generate()
|
||||
{
|
||||
return CheckGeneratedGuidValue(_high, _nextGuid++);
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TRINITYCORE_OBJECT_GUID_SEQUENCE_GENERATOR_H
|
||||
#define TRINITYCORE_OBJECT_GUID_SEQUENCE_GENERATOR_H
|
||||
|
||||
#include "ObjectGuid.h"
|
||||
#include <atomic>
|
||||
|
||||
class ObjectGuidGenerator
|
||||
{
|
||||
public:
|
||||
explicit ObjectGuidGenerator(HighGuid high, ObjectGuid::LowType start = UI64LIT(1)) : _nextGuid(start), _high(high) { }
|
||||
|
||||
void Set(ObjectGuid::LowType val) { _nextGuid = val; }
|
||||
ObjectGuid::LowType Generate();
|
||||
ObjectGuid::LowType GetNextAfterMaxUsed() const { return _nextGuid; }
|
||||
|
||||
private:
|
||||
std::atomic<ObjectGuid::LowType> _nextGuid;
|
||||
HighGuid _high;
|
||||
};
|
||||
|
||||
#endif // TRINITYCORE_OBJECT_GUID_SEQUENCE_GENERATOR_H
|
||||
@@ -7188,11 +7188,7 @@ void ObjectMgr::SetHighestGuids()
|
||||
|
||||
ObjectGuidGenerator& ObjectMgr::GetGuidSequenceGenerator(HighGuid high)
|
||||
{
|
||||
auto itr = _guidGenerators.find(high);
|
||||
if (itr == _guidGenerators.end())
|
||||
itr = _guidGenerators.insert(std::make_pair(high, std::make_unique<ObjectGuidGenerator>(high))).first;
|
||||
|
||||
return *itr->second;
|
||||
return _guidGenerators.try_emplace(high, high).first->second;
|
||||
}
|
||||
|
||||
uint32 ObjectMgr::GenerateAuctionID()
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "NPCHandler.h"
|
||||
#include "ObjectDefines.h"
|
||||
#include "ObjectGuid.h"
|
||||
#include "ObjectGuidSequenceGenerator.h"
|
||||
#include "Position.h"
|
||||
#include "QuestDef.h"
|
||||
#include "RaceMask.h"
|
||||
@@ -1776,7 +1777,7 @@ class TC_GAME_API ObjectMgr
|
||||
// first free low guid for selected guid type
|
||||
ObjectGuidGenerator& GetGuidSequenceGenerator(HighGuid high);
|
||||
|
||||
std::map<HighGuid, std::unique_ptr<ObjectGuidGenerator>> _guidGenerators;
|
||||
std::map<HighGuid, ObjectGuidGenerator> _guidGenerators;
|
||||
QuestContainer _questTemplates;
|
||||
std::vector<Quest const*> _questTemplatesAutoPush;
|
||||
QuestObjectivesByIdContainer _questObjectives;
|
||||
|
||||
@@ -2518,11 +2518,7 @@ void Map::UpdateSpawnGroupConditions()
|
||||
|
||||
ObjectGuidGenerator& Map::GetGuidSequenceGenerator(HighGuid high)
|
||||
{
|
||||
auto itr = _guidGenerators.find(high);
|
||||
if (itr == _guidGenerators.end())
|
||||
itr = _guidGenerators.insert(std::make_pair(high, std::make_unique<ObjectGuidGenerator>(high))).first;
|
||||
|
||||
return *itr->second;
|
||||
return _guidGenerators.try_emplace(high, high).first->second;
|
||||
}
|
||||
|
||||
void Map::AddFarSpellCallback(FarSpellCallback&& callback)
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "MapRefManager.h"
|
||||
#include "MPSCQueue.h"
|
||||
#include "ObjectGuid.h"
|
||||
#include "ObjectGuidSequenceGenerator.h"
|
||||
#include "PersonalPhaseTracker.h"
|
||||
#include "SharedDefines.h"
|
||||
#include "SpawnData.h"
|
||||
@@ -826,7 +827,7 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
|
||||
|
||||
ObjectGuidGenerator& GetGuidSequenceGenerator(HighGuid high);
|
||||
|
||||
std::map<HighGuid, std::unique_ptr<ObjectGuidGenerator>> _guidGenerators;
|
||||
std::map<HighGuid, ObjectGuidGenerator> _guidGenerators;
|
||||
std::unique_ptr<SpawnedPoolData> _poolData;
|
||||
MapStoredObjectTypesContainer _objectsStore;
|
||||
CreatureBySpawnIdContainer _creatureBySpawnIdStore;
|
||||
|
||||
Reference in New Issue
Block a user