diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index a959d9093..9a824722e 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -44,6 +44,7 @@ SET(common_sources md5.cpp memory_buffer.cpp memory_mapped_file.cpp + metric_manager.cpp misc.cpp misc_functions.cpp mutex.cpp @@ -173,6 +174,8 @@ SET(common_headers md5.h memory_buffer.h memory_mapped_file.h + metric_event.h + metric_manager.h misc.h misc_functions.h mutex.h diff --git a/common/metric_event.h b/common/metric_event.h new file mode 100644 index 000000000..9487ab27b --- /dev/null +++ b/common/metric_event.h @@ -0,0 +1,65 @@ +/* EQEMu: Everquest Server Emulator + + Copyright (C) 2001-2020 EQEMu Development Team (http://eqemulator.net) + + 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; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY except by those people which sell it, which + are required to give you total support for your newly bought product; + 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, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef METRIC_EVENT_H +#define METRIC_EVENT_H + +#include "types.h" + +namespace EQEmu +{ + class MetricEvent { + public: + + enum class EventType { + eventNone, + eventNpcStatsMonitor + }; + + MetricEvent() { + + m_finalized = false; + m_expired = false; + m_event_id = 0; + } + + virtual EventType GetEventType() const = 0; + + virtual void Process() = 0; + virtual void Flush() = 0; + + virtual void Finalize() { m_finalized = true; } // invoke MetricEvent::Finalize() inside of derived class function if not handled locally + bool IsFinalized() const { return m_finalized; } + + virtual void Expire() { m_finalized = true; m_expired = true; } // invoke MetricEvent::Expire() inside of derived class function if not handled locally + bool IsExpired() const { return m_expired; } + + void SetEventId(int value) { if (m_event_id == 0) { m_event_id = value; } } + int GetEventId() const { return m_event_id; } + + private: + + bool m_finalized; + bool m_expired; + int m_event_id; + }; + +} // EQEmu + +#endif // METRIC_EVENT_H diff --git a/common/metric_manager.cpp b/common/metric_manager.cpp new file mode 100644 index 000000000..9144ba606 --- /dev/null +++ b/common/metric_manager.cpp @@ -0,0 +1,112 @@ +/* EQEMu: Everquest Server Emulator + + Copyright (C) 2001-2020 EQEMu Development Team (http://eqemulator.net) + + 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; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY except by those people which sell it, which + are required to give you total support for your newly bought product; + 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, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "metric_manager.h" +#include "metric_event.h" + +EQEmu::MetricManager::MetricManager() { + + m_current_event_id = 0; +} + +void EQEmu::MetricManager::Process() { + + for (std::list::iterator iter = m_event_list.begin(); iter != m_event_list.end(); ) { + + if ((*iter)->IsExpired()) { + + iter = m_event_list.erase(iter); + continue; + } + + (*iter)->Process(); + ++iter; + } +} + +int EQEmu::MetricManager::RegisterEvent(MetricEvent* event_object) { + + if (event_object == nullptr) { + return 0; + } + + event_object->SetEventId(get_next_event_id()); + m_event_list.push_back(event_object); + + return event_object->GetEventId(); +} + +void EQEmu::MetricManager::FlushAll() { + + for (auto iter : m_event_list) { + iter->Flush(); + } +} + +void EQEmu::MetricManager::FlushById(int event_id) { + + for (auto iter : m_event_list) { + if (iter->GetEventId() == event_id) { + + iter->Flush(); + break; + } + } +} + +void EQEmu::MetricManager::FinalizeAll() { + + for (auto iter : m_event_list) { + iter->Finalize(); + } +} + +void EQEmu::MetricManager::FinalizeById(int event_id) { + + for (auto iter : m_event_list) { + if (iter->GetEventId() == event_id) { + + iter->Finalize(); + break; + } + } +} + +void EQEmu::MetricManager::ExpireAll() { + + for (auto iter : m_event_list) { + iter->Expire(); + } +} + +void EQEmu::MetricManager::ExpireById(int event_id) { + + for (auto iter : m_event_list) { + if (iter->GetEventId() == event_id) { + + iter->Expire(); + break; + } + } +} + +int EQEmu::MetricManager::get_next_event_id() { + + return ++m_current_event_id; +} diff --git a/common/metric_manager.h b/common/metric_manager.h new file mode 100644 index 000000000..4e67b0fe0 --- /dev/null +++ b/common/metric_manager.h @@ -0,0 +1,58 @@ +/* EQEMu: Everquest Server Emulator + + Copyright (C) 2001-2020 EQEMu Development Team (http://eqemulator.net) + + 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; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY except by those people which sell it, which + are required to give you total support for your newly bought product; + 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, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef METRIC_MANAGER_H +#define METRIC_MANAGER_H + +#include + +namespace EQEmu +{ + class MetricEvent; + + class MetricManager { + public: + + MetricManager(); + + void Process(); + + int RegisterEvent(MetricEvent*); + + void FlushAll(); + void FlushById(int); + + void FinalizeAll(); + void FinalizeById(int); + + void ExpireAll(); + void ExpireById(int); + + private: + + int get_next_event_id(); + + int m_current_event_id; + + std::list m_event_list; + }; + +} // EQEmu + +#endif // METRIC_MANAGER_H diff --git a/zone/CMakeLists.txt b/zone/CMakeLists.txt index f75e963f9..f162d6cb9 100644 --- a/zone/CMakeLists.txt +++ b/zone/CMakeLists.txt @@ -82,6 +82,7 @@ SET(zone_sources main.cpp map.cpp merc.cpp + metric_event_types.cpp mob.cpp mob_ai.cpp mob_appearance.cpp diff --git a/zone/entity.cpp b/zone/entity.cpp index 3d926e651..b49c1a97c 100644 --- a/zone/entity.cpp +++ b/zone/entity.cpp @@ -65,6 +65,8 @@ Entity::Entity() id = 0; initial_id = 0; spawn_timestamp = time(nullptr); + + m_metric_event = nullptr; } Entity::~Entity() diff --git a/zone/entity.h b/zone/entity.h index a296ca794..b0371295f 100644 --- a/zone/entity.h +++ b/zone/entity.h @@ -26,6 +26,7 @@ #include "../common/servertalk.h" #include "../common/bodytypes.h" #include "../common/eq_constants.h" +#include "../common/metric_event.h" #include "position.h" #include "zonedump.h" @@ -121,6 +122,9 @@ public: const Bot* CastToBot() const; #endif + EQEmu::MetricEvent* GetMetricEvent() { return m_metric_event; } + bool SetMetricEvent(EQEmu::MetricEvent* metric_event) { if (!m_metric_event) { m_metric_event = metric_event; return true; } else { return false; } } + protected: friend class EntityList; inline virtual void SetID(uint16 set_id) { @@ -135,6 +139,8 @@ private: uint16 id; uint16 initial_id; time_t spawn_timestamp; + + EQEmu::MetricEvent* m_metric_event; }; class EntityList diff --git a/zone/main.cpp b/zone/main.cpp index 6d3eee96c..2c7832044 100644 --- a/zone/main.cpp +++ b/zone/main.cpp @@ -42,6 +42,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "../common/eqemu_exception.h" #include "../common/spdat.h" #include "../common/eqemu_logsys.h" +#include "../common/metric_manager.h" #include "api_service.h" #include "zone_config.h" @@ -111,6 +112,7 @@ const SPDat_Spell_Struct* spells; int32 SPDAT_RECORDS = -1; const ZoneConfig *Config; double frame_time = 0.0; +EQEmu::MetricManager metrics; void Shutdown(); void UpdateWindowTitle(char* iNewTitle); @@ -537,6 +539,7 @@ int main(int argc, char** argv) { quest_manager.Process(); } + metrics.Process(); } } diff --git a/zone/metric_event_types.cpp b/zone/metric_event_types.cpp new file mode 100644 index 000000000..5e371de18 --- /dev/null +++ b/zone/metric_event_types.cpp @@ -0,0 +1,35 @@ +/* EQEMu: Everquest Server Emulator + + Copyright (C) 2001-2020 EQEMu Development Team (http://eqemulator.net) + + 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; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY except by those people which sell it, which + are required to give you total support for your newly bought product; + 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, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "../common/metric_event.h" +#include "npc.h" + +class NPC::EventNpcStatsMonitor : EQEmu::MetricEvent { +public: + + virtual EventType GetEventType() const { return EventType::eventNpcStatsMonitor; } + + virtual void Process() {} + + virtual void Flush() {} + + virtual void Finalize() { MetricEvent::Finalize(); } + + virtual void Expire() { MetricEvent::Expire(); } +}; diff --git a/zone/npc.cpp b/zone/npc.cpp index ed5f37bb5..95f214ab8 100644 --- a/zone/npc.cpp +++ b/zone/npc.cpp @@ -448,6 +448,18 @@ uint32 NPC::GetRoamboxMinDelay() const NPC::~NPC() { + auto metric_event = GetMetricEvent(); + if (metric_event) { + + switch (metric_event->GetEventType()) { + case EQEmu::MetricEvent::EventType::eventNpcStatsMonitor: + metric_event->Finalize(); + SetMetricEvent(nullptr); + default: + break; + } + } + AI_Stop(); if(proximity != nullptr) { @@ -3195,4 +3207,4 @@ void NPC::AIYellForHelp(Mob *sender, Mob *attacker) } } -} \ No newline at end of file +} diff --git a/zone/npc.h b/zone/npc.h index 84ab8b4ef..c35c6940c 100644 --- a/zone/npc.h +++ b/zone/npc.h @@ -103,6 +103,8 @@ namespace EQEmu class NPC : public Mob { public: + class EventNpcStatsMonitor; + static NPC* SpawnNPC(const char* spawncommand, const glm::vec4& position, Client* client = nullptr); static bool SpawnZoneController(); static int8 GetAILevel(bool iForceReRead = false);