chore: cleanup objectIdManager overloading and classes (#1391)

* objectIdManager fixes

* Remove debug log
This commit is contained in:
David Markowitz 2024-01-05 04:31:22 -08:00 committed by GitHub
parent 66ac5a1b7a
commit 870b56fe02
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 166 additions and 236 deletions

View File

@ -2,7 +2,7 @@
#include "RakNetTypes.h" #include "RakNetTypes.h"
#include "Game.h" #include "Game.h"
#include "User.h" #include "User.h"
#include "../dWorldServer/ObjectIDManager.h" #include "ObjectIDManager.h"
#include "Character.h" #include "Character.h"
#include "GeneralUtils.h" #include "GeneralUtils.h"
#include "dServer.h" #include "dServer.h"
@ -89,7 +89,7 @@ Entity* EntityManager::CreateEntity(EntityInfo info, User* user, Entity* parentE
// Entities with no ID already set, often spawned entities, we'll generate a new sequencial ID // Entities with no ID already set, often spawned entities, we'll generate a new sequencial ID
if (info.id == 0) { if (info.id == 0) {
id = ObjectIDManager::Instance()->GenerateObjectID(); id = ObjectIDManager::GenerateObjectID();
} }
// Entities with an ID already set, often level entities, we'll use that ID as a base // Entities with an ID already set, often level entities, we'll use that ID as a base

View File

@ -2,7 +2,7 @@
#include "EntityManager.h" #include "EntityManager.h"
#include "GameMessages.h" #include "GameMessages.h"
#include "InventoryComponent.h" #include "InventoryComponent.h"
#include "../dWorldServer/ObjectIDManager.h" #include "ObjectIDManager.h"
#include "Game.h" #include "Game.h"
#include "Logger.h" #include "Logger.h"
#include "Item.h" #include "Item.h"
@ -273,7 +273,7 @@ void TradingManager::CancelTrade(LWOOBJID tradeId) {
} }
Trade* TradingManager::NewTrade(LWOOBJID participantA, LWOOBJID participantB) { Trade* TradingManager::NewTrade(LWOOBJID participantA, LWOOBJID participantB) {
const LWOOBJID tradeId = ObjectIDManager::Instance()->GenerateObjectID(); const LWOOBJID tradeId = ObjectIDManager::GenerateObjectID();
auto* trade = new Trade(tradeId, participantA, participantB); auto* trade = new Trade(tradeId, participantA, participantB);

View File

@ -12,7 +12,7 @@
#include "Character.h" #include "Character.h"
#include <BitStream.h> #include <BitStream.h>
#include "PacketUtils.h" #include "PacketUtils.h"
#include "../dWorldServer/ObjectIDManager.h" #include "ObjectIDManager.h"
#include "Logger.h" #include "Logger.h"
#include "GeneralUtils.h" #include "GeneralUtils.h"
#include "ZoneInstanceManager.h" #include "ZoneInstanceManager.h"
@ -263,7 +263,7 @@ void UserManager::CreateCharacter(const SystemAddress& sysAddr, Packet* packet)
} }
//Now that the name is ok, we can get an objectID from Master: //Now that the name is ok, we can get an objectID from Master:
ObjectIDManager::Instance()->RequestPersistentID([=, this](uint32_t objectID) { ObjectIDManager::RequestPersistentID([=, this](uint32_t objectID) {
if (Database::Get()->GetCharacterInfo(objectID)) { if (Database::Get()->GetCharacterInfo(objectID)) {
LOG("Character object id unavailable, check object_id_tracker!"); LOG("Character object id unavailable, check object_id_tracker!");
WorldPackets::SendCharacterCreationResponse(sysAddr, eCharacterCreationResponse::OBJECT_ID_UNAVAILABLE); WorldPackets::SendCharacterCreationResponse(sysAddr, eCharacterCreationResponse::OBJECT_ID_UNAVAILABLE);

View File

@ -5,7 +5,7 @@
#include "Game.h" #include "Game.h"
#include "Logger.h" #include "Logger.h"
#include "SkillComponent.h" #include "SkillComponent.h"
#include "../dWorldServer/ObjectIDManager.h" #include "ObjectIDManager.h"
#include "eObjectBits.h" #include "eObjectBits.h"
void ProjectileAttackBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { void ProjectileAttackBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
@ -106,7 +106,7 @@ void ProjectileAttackBehavior::Calculate(BehaviorContext* context, RakNet::BitSt
const auto maxTime = this->m_maxDistance / this->m_projectileSpeed; const auto maxTime = this->m_maxDistance / this->m_projectileSpeed;
for (auto i = 0u; i < this->m_projectileCount; ++i) { for (auto i = 0u; i < this->m_projectileCount; ++i) {
auto id = static_cast<LWOOBJID>(ObjectIDManager::Instance()->GenerateObjectID()); auto id = static_cast<LWOOBJID>(ObjectIDManager::GenerateObjectID());
GeneralUtils::SetBit(id, eObjectBits::SPAWNED); GeneralUtils::SetBit(id, eObjectBits::SPAWNED);

View File

@ -7,7 +7,7 @@
#include "Game.h" #include "Game.h"
#include "Logger.h" #include "Logger.h"
#include "CDClientManager.h" #include "CDClientManager.h"
#include "../dWorldServer/ObjectIDManager.h" #include "ObjectIDManager.h"
#include "MissionComponent.h" #include "MissionComponent.h"
#include "GameMessages.h" #include "GameMessages.h"
#include "SkillComponent.h" #include "SkillComponent.h"
@ -68,7 +68,7 @@ InventoryComponent::InventoryComponent(Entity* parent, tinyxml2::XMLDocument* do
continue; continue;
} }
const LWOOBJID id = ObjectIDManager::Instance()->GenerateObjectID(); const LWOOBJID id = ObjectIDManager::GenerateObjectID();
const auto& info = Inventory::FindItemComponent(item.itemid); const auto& info = Inventory::FindItemComponent(item.itemid);
@ -86,7 +86,7 @@ InventoryComponent::InventoryComponent(Entity* parent, tinyxml2::XMLDocument* do
const auto proxyLOT = static_cast<LOT>(std::stoi(proxyLotAsString)); const auto proxyLOT = static_cast<LOT>(std::stoi(proxyLotAsString));
const auto& proxyInfo = Inventory::FindItemComponent(proxyLOT); const auto& proxyInfo = Inventory::FindItemComponent(proxyLOT);
const LWOOBJID proxyId = ObjectIDManager::Instance()->GenerateObjectID(); const LWOOBJID proxyId = ObjectIDManager::GenerateObjectID();
// Use item.count since we equip item.count number of the item this is a requested proxy of // Use item.count since we equip item.count number of the item this is a requested proxy of
UpdateSlot(proxyInfo.equipLocation, { proxyId, proxyLOT, item.count, slot++ }); UpdateSlot(proxyInfo.equipLocation, { proxyId, proxyLOT, item.count, slot++ });
@ -1341,7 +1341,7 @@ void InventoryComponent::SetNPCItems(const std::vector<LOT>& items) {
auto slot = 0u; auto slot = 0u;
for (const auto& item : items) { for (const auto& item : items) {
const LWOOBJID id = ObjectIDManager::Instance()->GenerateObjectID(); const LWOOBJID id = ObjectIDManager::GenerateObjectID();
const auto& info = Inventory::FindItemComponent(item); const auto& info = Inventory::FindItemComponent(item);

View File

@ -13,7 +13,7 @@
#include "DestroyableComponent.h" #include "DestroyableComponent.h"
#include "dpWorld.h" #include "dpWorld.h"
#include "PetDigServer.h" #include "PetDigServer.h"
#include "../dWorldServer/ObjectIDManager.h" #include "ObjectIDManager.h"
#include "eUnequippableActiveType.h" #include "eUnequippableActiveType.h"
#include "eTerminateType.h" #include "eTerminateType.h"
#include "ePetTamingNotifyType.h" #include "ePetTamingNotifyType.h"
@ -562,7 +562,7 @@ void PetComponent::NotifyTamingBuildSuccess(NiPoint3 position) {
return; return;
} }
LWOOBJID petSubKey = ObjectIDManager::Instance()->GenerateRandomObjectID(); LWOOBJID petSubKey = ObjectIDManager::GenerateRandomObjectID();
GeneralUtils::SetBit(petSubKey, eObjectBits::CHARACTER); GeneralUtils::SetBit(petSubKey, eObjectBits::CHARACTER);
GeneralUtils::SetBit(petSubKey, eObjectBits::PERSISTENT); GeneralUtils::SetBit(petSubKey, eObjectBits::PERSISTENT);

View File

@ -13,7 +13,7 @@
#include "Game.h" #include "Game.h"
#include "Item.h" #include "Item.h"
#include "Database.h" #include "Database.h"
#include "../dWorldServer/ObjectIDManager.h" #include "ObjectIDManager.h"
#include "Player.h" #include "Player.h"
#include "RocketLaunchpadControlComponent.h" #include "RocketLaunchpadControlComponent.h"
#include "PropertyEntranceComponent.h" #include "PropertyEntranceComponent.h"
@ -334,7 +334,7 @@ void PropertyManagementComponent::UpdateModelPosition(const LWOOBJID id, const N
node->position = position; node->position = position;
node->rotation = rotation; node->rotation = rotation;
ObjectIDManager::Instance()->RequestPersistentID([this, node, modelLOT, entity, position, rotation, originalRotation](uint32_t persistentId) { ObjectIDManager::RequestPersistentID([this, node, modelLOT, entity, position, rotation, originalRotation](uint32_t persistentId) {
SpawnerInfo info{}; SpawnerInfo info{};
info.templateID = modelLOT; info.templateID = modelLOT;

View File

@ -14,7 +14,7 @@
#include "EntityManager.h" #include "EntityManager.h"
#include "Database.h" #include "Database.h"
#include "dServer.h" #include "dServer.h"
#include "../dWorldServer/ObjectIDManager.h" #include "ObjectIDManager.h"
#include "CppScripts.h" #include "CppScripts.h"
#include "UserManager.h" #include "UserManager.h"
#include "ZoneInstanceManager.h" #include "ZoneInstanceManager.h"
@ -1045,7 +1045,7 @@ void GameMessages::SendDropClientLoot(Entity* entity, const LWOOBJID& sourceID,
LWOOBJID owner = entity->GetObjectID(); LWOOBJID owner = entity->GetObjectID();
if (item != LOT_NULL && item != 0) { if (item != LOT_NULL && item != 0) {
lootID = ObjectIDManager::Instance()->GenerateObjectID(); lootID = ObjectIDManager::GenerateObjectID();
Loot::Info info; Loot::Info info;
info.id = lootID; info.id = lootID;
@ -2565,12 +2565,12 @@ void GameMessages::HandleBBBSaveRequest(RakNet::BitStream* inStream, Entity* ent
//But we don't want the server to go unresponsive, because then the client would disconnect. //But we don't want the server to go unresponsive, because then the client would disconnect.
//We need to get a new ID for our model first: //We need to get a new ID for our model first:
ObjectIDManager::Instance()->RequestPersistentID([=](uint32_t newID) { ObjectIDManager::RequestPersistentID([=](uint32_t newID) {
LWOOBJID newIDL = newID; LWOOBJID newIDL = newID;
GeneralUtils::SetBit(newIDL, eObjectBits::CHARACTER); GeneralUtils::SetBit(newIDL, eObjectBits::CHARACTER);
GeneralUtils::SetBit(newIDL, eObjectBits::PERSISTENT); GeneralUtils::SetBit(newIDL, eObjectBits::PERSISTENT);
uint32_t blueprintIDSmall = ObjectIDManager::Instance()->GenerateRandomObjectID(); uint32_t blueprintIDSmall = ObjectIDManager::GenerateRandomObjectID();
LWOOBJID blueprintID = blueprintIDSmall; LWOOBJID blueprintID = blueprintIDSmall;
GeneralUtils::SetBit(blueprintID, eObjectBits::CHARACTER); GeneralUtils::SetBit(blueprintID, eObjectBits::CHARACTER);
GeneralUtils::SetBit(blueprintID, eObjectBits::PERSISTENT); GeneralUtils::SetBit(blueprintID, eObjectBits::PERSISTENT);
@ -5565,7 +5565,7 @@ void GameMessages::HandleModularBuildFinish(RakNet::BitStream* inStream, Entity*
} }
} }
ObjectIDManager::Instance()->RequestPersistentID([=](uint32_t newId) { ObjectIDManager::RequestPersistentID([=](uint32_t newId) {
LOG("Build finished"); LOG("Build finished");
GameMessages::SendFinishArrangingWithItem(character, entity->GetObjectID()); // kick them from modular build GameMessages::SendFinishArrangingWithItem(character, entity->GetObjectID()); // kick them from modular build
GameMessages::SendModularBuildEnd(character); // i dont know if this does anything but DLUv2 did it GameMessages::SendModularBuildEnd(character); // i dont know if this does anything but DLUv2 did it

View File

@ -2,7 +2,7 @@
#include <sstream> #include <sstream>
#include "../dWorldServer/ObjectIDManager.h" #include "ObjectIDManager.h"
#include "GeneralUtils.h" #include "GeneralUtils.h"
#include "GameMessages.h" #include "GameMessages.h"
#include "Entity.h" #include "Entity.h"

View File

@ -5,7 +5,7 @@
#include "Game.h" #include "Game.h"
#include "GameMessages.h" #include "GameMessages.h"
#include "ModelComponent.h" #include "ModelComponent.h"
#include "../../dWorldServer/ObjectIDManager.h" #include "ObjectIDManager.h"
#include "Logger.h" #include "Logger.h"
#include "BehaviorStates.h" #include "BehaviorStates.h"
#include "AssetManager.h" #include "AssetManager.h"
@ -31,7 +31,7 @@
#include "UpdateStripUiMessage.h" #include "UpdateStripUiMessage.h"
void ControlBehaviors::RequestUpdatedID(ControlBehaviorContext& context) { void ControlBehaviors::RequestUpdatedID(ControlBehaviorContext& context) {
ObjectIDManager::Instance()->RequestPersistentID( ObjectIDManager::RequestPersistentID(
[context](uint32_t persistentId) { [context](uint32_t persistentId) {
if (!context) { if (!context) {
LOG("Model to update behavior ID for is null. Cannot update ID."); LOG("Model to update behavior ID for is null. Cannot update ID.");

View File

@ -3,6 +3,7 @@ set(DGAME_DUTILITIES_SOURCES "BrickDatabase.cpp"
"GUID.cpp" "GUID.cpp"
"Loot.cpp" "Loot.cpp"
"Mail.cpp" "Mail.cpp"
"ObjectIDManager.cpp"
"Preconditions.cpp" "Preconditions.cpp"
"SlashCommandHandler.cpp" "SlashCommandHandler.cpp"
"VanityUtilities.cpp") "VanityUtilities.cpp")

View File

@ -0,0 +1,51 @@
#include "ObjectIDManager.h"
// Custom Classes
#include "MasterPackets.h"
#include "Database.h"
#include "Logger.h"
#include "Game.h"
//! The persistent ID request
struct PersistentIDRequest {
PersistentIDRequest(const uint64_t& requestID, const std::function<void(uint32_t)>& callback) : requestID(requestID), callback(callback) {}
uint64_t requestID;
std::function<void(uint32_t)> callback;
};
namespace {
std::vector<PersistentIDRequest> Requests; //!< All outstanding persistent ID requests
uint64_t CurrentRequestID = 0; //!< The current request ID
uint32_t CurrentObjectID = uint32_t(1152921508165007067); //!< The current object ID
std::uniform_int_distribution<int> Uni(10000000, INT32_MAX);
};
//! Requests a persistent ID
void ObjectIDManager::RequestPersistentID(const std::function<void(uint32_t)> callback) {
const auto& request = Requests.emplace_back(++CurrentRequestID, callback);
MasterPackets::SendPersistentIDRequest(Game::server, request.requestID);
}
//! Handles a persistent ID response
void ObjectIDManager::HandleRequestPersistentIDResponse(const uint64_t requestID, const uint32_t persistentID) {
auto it = std::find_if(Requests.begin(), Requests.end(), [requestID](const PersistentIDRequest& request) {
return request.requestID == requestID;
});
if (it == Requests.end()) return;
it->callback(persistentID);
Requests.erase(it);
}
//! Handles cases where we have to get a unique object ID synchronously
uint32_t ObjectIDManager::GenerateRandomObjectID() {
return Uni(Game::randomEngine);
}
//! Generates an object ID server-sided (used for regular entities like smashables)
uint32_t ObjectIDManager::GenerateObjectID() {
return ++CurrentObjectID;
}

View File

@ -0,0 +1,40 @@
#pragma once
// C++
#include <functional>
#include <vector>
#include <stdint.h>
/*!
\file ObjectIDManager.h
\brief A manager for handling object ID generation
*/
//! The Object ID Manager
namespace ObjectIDManager {
//! Requests a persistent ID
/*!
\param callback The callback function
*/
void RequestPersistentID(const std::function<void(uint32_t)> callback);
//! Handles a persistent ID response
/*!
\param requestID The request ID
\param persistentID The persistent ID
*/
void HandleRequestPersistentIDResponse(const uint64_t requestID, const uint32_t persistentID);
//! Generates an object ID server-sided
/*!
\return A generated object ID
*/
uint32_t GenerateObjectID();
//! Generates a random object ID server-sided
/*!
\return A generated object ID
*/
uint32_t GenerateRandomObjectID();
};

View File

@ -17,7 +17,7 @@
#include "EntityInfo.h" #include "EntityInfo.h"
#include "Spawner.h" #include "Spawner.h"
#include "dZoneManager.h" #include "dZoneManager.h"
#include "../dWorldServer/ObjectIDManager.h" #include "ObjectIDManager.h"
#include "Level.h" #include "Level.h"
#include <fstream> #include <fstream>
@ -182,7 +182,7 @@ LWOOBJID VanityUtilities::SpawnSpawner(LOT lot, const NiPoint3& position, const
obj.lot = lot; obj.lot = lot;
// guratantee we have no collisions // guratantee we have no collisions
do { do {
obj.id = ObjectIDManager::Instance()->GenerateObjectID(); obj.id = ObjectIDManager::GenerateObjectID();
} while(Game::zoneManager->GetSpawner(obj.id)); } while(Game::zoneManager->GetSpawner(obj.id));
obj.position = position; obj.position = position;
obj.rotation = rotation; obj.rotation = rotation;

View File

@ -1,6 +1,6 @@
set(DMASTERSERVER_SOURCES set(DMASTERSERVER_SOURCES
"InstanceManager.cpp" "InstanceManager.cpp"
"ObjectIDManager.cpp" "PersistentIDManager.cpp"
"Start.cpp" "Start.cpp"
) )

View File

@ -35,7 +35,7 @@
#include "Game.h" #include "Game.h"
#include "InstanceManager.h" #include "InstanceManager.h"
#include "MasterPackets.h" #include "MasterPackets.h"
#include "ObjectIDManager.h" #include "PersistentIDManager.h"
#include "PacketUtils.h" #include "PacketUtils.h"
#include "FdbToSqlite.h" #include "FdbToSqlite.h"
#include "BitStreamUtils.h" #include "BitStreamUtils.h"
@ -134,7 +134,7 @@ int main(int argc, char** argv) {
if (!resServerPathExists) { if (!resServerPathExists) {
LOG("%s does not exist, creating it.", (resServerPath).c_str()); LOG("%s does not exist, creating it.", (resServerPath).c_str());
if(!std::filesystem::create_directories(resServerPath)){ if (!std::filesystem::create_directories(resServerPath)) {
LOG("Failed to create %s", (resServerPath).string().c_str()); LOG("Failed to create %s", (resServerPath).string().c_str());
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -257,8 +257,8 @@ int main(int argc, char** argv) {
//Create account //Create account
try { try {
Database::Get()->InsertNewAccount(username, std::string(hash, BCRYPT_HASHSIZE)); Database::Get()->InsertNewAccount(username, std::string(hash, BCRYPT_HASHSIZE));
} catch(sql::SQLException& e) { } catch (sql::SQLException& e) {
LOG("A SQL error occurred!:\n %s", e.what()); LOG("A SQL error occurred!:\n %s", e.what());
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -288,7 +288,7 @@ int main(int argc, char** argv) {
Database::Get()->SetMasterIp(master_server_ip, Game::server->GetPort()); Database::Get()->SetMasterIp(master_server_ip, Game::server->GetPort());
//Create additional objects here: //Create additional objects here:
ObjectIDManager::Instance()->Initialize(Game::logger); PersistentIDManager::Initialize();
Game::im = new InstanceManager(Game::logger, Game::server->GetIP()); Game::im = new InstanceManager(Game::logger, Game::server->GetIP());
//Depending on the config, start up servers: //Depending on the config, start up servers:
@ -464,7 +464,7 @@ void HandlePacket(Packet* packet) {
uint64_t requestID = 0; uint64_t requestID = 0;
inStream.Read(requestID); inStream.Read(requestID);
uint32_t objID = ObjectIDManager::Instance()->GeneratePersistentID(); uint32_t objID = PersistentIDManager::GeneratePersistentID();
MasterPackets::SendPersistentIDResponse(Game::server, packet->systemAddress, requestID, objID); MasterPackets::SendPersistentIDResponse(Game::server, packet->systemAddress, requestID, objID);
break; break;
} }
@ -822,11 +822,8 @@ int ShutdownSequence(int32_t signal) {
LOG("Triggered master shutdown"); LOG("Triggered master shutdown");
} }
auto* objIdManager = ObjectIDManager::TryInstance(); PersistentIDManager::SaveToDatabase();
if (objIdManager) { LOG("Saved ObjectIDTracker to DB");
objIdManager->SaveToDatabase();
LOG("Saved ObjectIDTracker to DB");
}
// A server might not be finished spinning up yet, remove all of those here. // A server might not be finished spinning up yet, remove all of those here.
for (auto* instance : Game::im->GetInstances()) { for (auto* instance : Game::im->GetInstances()) {

View File

@ -1,47 +0,0 @@
#pragma once
// C++
#include <cstdint>
class Logger;
/*!
\file ObjectIDManager.hpp
\brief A manager that handles requests for object IDs
*/
//! The Object ID Manager
class ObjectIDManager {
private:
Logger* mLogger;
static ObjectIDManager* m_Address; //!< The singleton instance
uint32_t currentPersistentID; //!< The highest current persistent ID in use
public:
//! Return the singleton if it is initialized
static ObjectIDManager* TryInstance() {
return m_Address;
}
//! The singleton method
static ObjectIDManager* Instance() {
if (m_Address == nullptr) {
m_Address = new ObjectIDManager;
}
return m_Address;
}
//! Initializes the manager
void Initialize(Logger* logger);
//! Generates a new persistent ID
/*!
\return The new persistent ID
*/
uint32_t GeneratePersistentID();
void SaveToDatabase();
};

View File

@ -1,48 +1,45 @@
#include "ObjectIDManager.h" #include "PersistentIDManager.h"
// Custom Classes // Custom Classes
#include "Database.h" #include "Database.h"
#include "Logger.h" #include "Logger.h"
#include "Game.h" #include "Game.h"
// Static Variables namespace {
ObjectIDManager* ObjectIDManager::m_Address = nullptr; uint32_t CurrentPersistentID = 1; //!< The highest current persistent ID in use
};
//! Initializes the manager //! Initializes the manager
void ObjectIDManager::Initialize(Logger* logger) { void PersistentIDManager::Initialize() {
this->mLogger = logger;
this->currentPersistentID = 1;
try { try {
auto lastObjectId = Database::Get()->GetCurrentPersistentId(); auto lastObjectId = Database::Get()->GetCurrentPersistentId();
if (!lastObjectId) { if (!lastObjectId) {
Database::Get()->InsertDefaultPersistentId(); Database::Get()->InsertDefaultPersistentId();
return;
} else { } else {
this->currentPersistentID = lastObjectId.value(); CurrentPersistentID = lastObjectId.value();
} }
if (this->currentPersistentID <= 0) { if (CurrentPersistentID <= 0) {
LOG("Invalid persistent object ID in database. Aborting to prevent bad id generation."); LOG("Invalid persistent object ID in database. Aborting to prevent bad id generation.");
throw std::runtime_error("Invalid persistent object ID in database. Aborting to prevent bad id generation."); throw std::runtime_error("Invalid persistent object ID in database. Aborting to prevent bad id generation.");
} }
} catch (sql::SQLException& e) { } catch (sql::SQLException& e) {
LOG("Unable to fetch max persistent object ID in use. This will cause issues. Aborting to prevent collisions."); LOG("Unable to fetch max persistent object ID in use. This will cause issues. Aborting to prevent collisions.");
LOG("SQL error: %s", e.what()); LOG("SQL error: %s", e.what());
throw; throw e;
} }
} }
//! Generates a new persistent ID //! Generates a new persistent ID
uint32_t ObjectIDManager::GeneratePersistentID() { uint32_t PersistentIDManager::GeneratePersistentID() {
uint32_t toReturn = ++this->currentPersistentID; uint32_t toReturn = ++CurrentPersistentID;
SaveToDatabase(); SaveToDatabase();
return toReturn; return toReturn;
} }
void ObjectIDManager::SaveToDatabase() { void PersistentIDManager::SaveToDatabase() {
Database::Get()->UpdatePersistentId(this->currentPersistentID); Database::Get()->UpdatePersistentId(CurrentPersistentID);
} }

View File

@ -0,0 +1,23 @@
#pragma once
// C++
#include <cstdint>
/*!
\file PersistentIDManager.h
\brief A manager that handles requests for object IDs
*/
//! The Object ID Manager
namespace PersistentIDManager {
//! Initializes the manager
void Initialize();
//! Generates a new persistent ID
/*!
\return The new persistent ID
*/
uint32_t GeneratePersistentID();
void SaveToDatabase();
};

View File

@ -9,7 +9,7 @@
#include "CharacterComponent.h" #include "CharacterComponent.h"
#include "SimplePhysicsComponent.h" #include "SimplePhysicsComponent.h"
#include "MovementAIComponent.h" #include "MovementAIComponent.h"
#include "../dWorldServer/ObjectIDManager.h" #include "ObjectIDManager.h"
#include "MissionComponent.h" #include "MissionComponent.h"
#include "Loot.h" #include "Loot.h"
#include "InventoryComponent.h" #include "InventoryComponent.h"

View File

@ -1,5 +1,4 @@
set(DWORLDSERVER_SOURCES set(DWORLDSERVER_SOURCES
"ObjectIDManager.cpp"
"PerformanceManager.cpp" "PerformanceManager.cpp"
) )

View File

@ -1,55 +0,0 @@
#include "ObjectIDManager.h"
// Custom Classes
#include "MasterPackets.h"
#include "Database.h"
#include "Logger.h"
#include "Game.h"
// Static Variables
ObjectIDManager* ObjectIDManager::m_Address = nullptr;
static std::uniform_int_distribution<int> uni(10000000, INT32_MAX);
//! Initializes the manager
void ObjectIDManager::Initialize(void) {
//this->currentRequestID = 0;
this->currentObjectID = uint32_t(1152921508165007067); //Initial value for this server's objectIDs
}
//! Requests a persistent ID
void ObjectIDManager::RequestPersistentID(std::function<void(uint32_t)> callback) {
PersistentIDRequest* request = new PersistentIDRequest();
request->requestID = ++this->currentRequestID;
request->callback = callback;
this->requests.push_back(request);
MasterPackets::SendPersistentIDRequest(Game::server, request->requestID);
}
//! Handles a persistent ID response
void ObjectIDManager::HandleRequestPersistentIDResponse(uint64_t requestID, uint32_t persistentID) {
for (uint32_t i = 0; i < this->requests.size(); ++i) {
if (this->requests[i]->requestID == requestID) {
// Call the callback function
this->requests[i]->callback(persistentID);
// Then delete the request
delete this->requests[i];
this->requests.erase(this->requests.begin() + i);
return;
}
}
}
//! Handles cases where we have to get a unique object ID synchronously
uint32_t ObjectIDManager::GenerateRandomObjectID() {
return uni(Game::randomEngine);
}
//! Generates an object ID server-sided (used for regular entities like smashables)
uint32_t ObjectIDManager::GenerateObjectID(void) {
return ++this->currentObjectID;
}

View File

@ -1,75 +0,0 @@
#pragma once
// C++
#include <functional>
#include <vector>
#include <stdint.h>
/*!
\file ObjectIDManager.hpp
\brief A manager for handling object ID generation
*/
//! The persistent ID request
struct PersistentIDRequest {
uint64_t requestID;
std::function<void(uint32_t)> callback;
};
//! The Object ID Manager
class ObjectIDManager {
private:
static ObjectIDManager* m_Address; //!< The singleton instance
std::vector<PersistentIDRequest*> requests; //!< All outstanding persistent ID requests
uint64_t currentRequestID; //!< The current request ID
uint32_t currentObjectID; //!< The current object ID
public:
//! The singleton instance
static ObjectIDManager* Instance() {
if (m_Address == 0) {
m_Address = new ObjectIDManager;
}
return m_Address;
}
//! Initializes the manager
void Initialize(void);
//! Requests a persistent ID
/*!
\param callback The callback function
*/
void RequestPersistentID(std::function<void(uint32_t)> callback);
//! Handles a persistent ID response
/*!
\param requestID The request ID
\param persistentID The persistent ID
*/
void HandleRequestPersistentIDResponse(uint64_t requestID, uint32_t persistentID);
//! Generates an object ID server-sided
/*!
\return A generated object ID
*/
uint32_t GenerateObjectID(void);
//! Generates a random object ID server-sided
/*!
\return A generated object ID
*/
static uint32_t GenerateRandomObjectID();
//! Generates a persistent object ID server-sided
/*!
\return A generated object ID
*/
uint32_t GeneratePersistentObjectID(void);
};

View File

@ -208,7 +208,6 @@ int main(int argc, char** argv) {
masterPort = masterInfo->port; masterPort = masterInfo->port;
} }
ObjectIDManager::Instance()->Initialize();
UserManager::Instance()->Initialize(); UserManager::Instance()->Initialize();
bool dontGenerateDCF = false; bool dontGenerateDCF = false;
@ -736,7 +735,7 @@ void HandlePacket(Packet* packet) {
case eMasterMessageType::REQUEST_PERSISTENT_ID_RESPONSE: { case eMasterMessageType::REQUEST_PERSISTENT_ID_RESPONSE: {
uint64_t requestID = PacketUtils::ReadU64(8, packet); uint64_t requestID = PacketUtils::ReadU64(8, packet);
uint32_t objectID = PacketUtils::ReadU32(16, packet); uint32_t objectID = PacketUtils::ReadU32(16, packet);
ObjectIDManager::Instance()->HandleRequestPersistentIDResponse(requestID, objectID); ObjectIDManager::HandleRequestPersistentIDResponse(requestID, objectID);
break; break;
} }

View File

@ -15,7 +15,7 @@
#include "CDZoneTableTable.h" #include "CDZoneTableTable.h"
#include "AssetManager.h" #include "AssetManager.h"
#include "../dWorldServer/ObjectIDManager.h" #include "ObjectIDManager.h"
void dZoneManager::Initialize(const LWOZONEID& zoneID) { void dZoneManager::Initialize(const LWOZONEID& zoneID) {
LOG("Preparing zone: %i/%i/%i", zoneID.GetMapID(), zoneID.GetInstanceID(), zoneID.GetCloneID()); LOG("Preparing zone: %i/%i/%i", zoneID.GetMapID(), zoneID.GetInstanceID(), zoneID.GetCloneID());
@ -112,7 +112,7 @@ LWOOBJID dZoneManager::MakeSpawner(SpawnerInfo info) {
auto objectId = info.spawnerID; auto objectId = info.spawnerID;
if (objectId == LWOOBJID_EMPTY) { if (objectId == LWOOBJID_EMPTY) {
objectId = ObjectIDManager::Instance()->GenerateObjectID(); objectId = ObjectIDManager::GenerateObjectID();
GeneralUtils::SetBit(objectId, eObjectBits::CLIENT); GeneralUtils::SetBit(objectId, eObjectBits::CLIENT);
info.spawnerID = objectId; info.spawnerID = objectId;