From 71f78b757e15b0bc7a6f947eb05a11114ecc2e08 Mon Sep 17 00:00:00 2001 From: Alex King <89047260+Kinglykrab@users.noreply.github.com> Date: Fri, 12 Jan 2024 23:38:31 -0500 Subject: [PATCH] [Respawns] Convert Respawn Times to Repositories (#3949) * [Respawns] Convert Respawn Times to Repositories - Convert `respawn_times` based methods to repositories. * Missed some. * Comments --- .../base/base_respawn_times_repository.h | 1 + .../repositories/respawn_times_repository.h | 32 +++++++++ zone/questmgr.cpp | 32 +++++---- zone/spawn2.cpp | 39 +++++----- zone/zone.cpp | 23 ++++-- zone/zonedb.cpp | 71 ++++++------------- zone/zonedb.h | 4 +- 7 files changed, 108 insertions(+), 94 deletions(-) diff --git a/common/repositories/base/base_respawn_times_repository.h b/common/repositories/base/base_respawn_times_repository.h index 6e8f4206a..fac8ed10f 100644 --- a/common/repositories/base/base_respawn_times_repository.h +++ b/common/repositories/base/base_respawn_times_repository.h @@ -16,6 +16,7 @@ #include "../../strings.h" #include + class BaseRespawnTimesRepository { public: struct RespawnTimes { diff --git a/common/repositories/respawn_times_repository.h b/common/repositories/respawn_times_repository.h index a4d7179b6..5eada10f7 100644 --- a/common/repositories/respawn_times_repository.h +++ b/common/repositories/respawn_times_repository.h @@ -44,7 +44,39 @@ public: */ // Custom extended repository methods here + static void ClearExpiredRespawnTimers(Database& db) + { + db.QueryDatabase( + fmt::format( + "DELETE FROM `{}` WHERE (`start` + `duration`) < UNIX_TIMESTAMP(NOW())", + TableName() + ) + ); + } + static uint32 GetTimeRemaining(Database& db, uint32 spawn2_id, uint16 instance_id, time_t time_seconds) + { + const auto& l = RespawnTimesRepository::GetWhere( + db, + fmt::format( + "`id` = {} AND `instance_id` = {}", + spawn2_id, + instance_id + ) + ); + + if (l.empty()) { + return 0; + } + + auto r = l.front(); + + if ((r.start + r.duration) <= time_seconds) { + return 0; + } + + return ((r.start + r.duration) - time_seconds); + } }; #endif //EQEMU_RESPAWN_TIMES_REPOSITORY_H diff --git a/zone/questmgr.cpp b/zone/questmgr.cpp index b3796d464..287aef2c4 100644 --- a/zone/questmgr.cpp +++ b/zone/questmgr.cpp @@ -3090,35 +3090,39 @@ void QuestManager::removeitem(uint32 item_id, uint32 quantity) { initiator->RemoveItem(item_id, quantity); } -void QuestManager::UpdateSpawnTimer(uint32 id, uint32 newTime) +void QuestManager::UpdateSpawnTimer(uint32 spawn2_id, uint32 new_time) { bool found = false; - database.UpdateRespawnTime(id, 0, (newTime/1000)); + database.UpdateRespawnTime(spawn2_id, 0, (new_time / 1000)); + LinkedListIterator iterator(zone->spawn2_list); + iterator.Reset(); - while (iterator.MoreElements()) - { - if(iterator.GetData()->GetID() == id) - { - if(!iterator.GetData()->NPCPointerValid()) - { - iterator.GetData()->SetTimer(newTime); + + while (iterator.MoreElements()) { + if (iterator.GetData()->GetID() == spawn2_id) { + if (!iterator.GetData()->NPCPointerValid()) { + iterator.GetData()->SetTimer(new_time); } + found = true; break; } + iterator.Advance(); } - if(!found) - { + if (!found) { //Spawn wasn't in this zone... //Tell the other zones to update their spawn time for this spawn point auto pack = new ServerPacket(ServerOP_UpdateSpawn, sizeof(UpdateSpawnTimer_Struct)); - UpdateSpawnTimer_Struct *ust = (UpdateSpawnTimer_Struct*) pack->pBuffer; - ust->id = id; - ust->duration = newTime; + + auto ust = (UpdateSpawnTimer_Struct*) pack->pBuffer; + + ust->id = spawn2_id; + ust->duration = new_time; + worldserver.SendPacket(pack); safe_delete(pack); } diff --git a/zone/spawn2.cpp b/zone/spawn2.cpp index 7985cf42a..7fab55b94 100644 --- a/zone/spawn2.cpp +++ b/zone/spawn2.cpp @@ -29,6 +29,7 @@ #include "../common/repositories/criteria/content_filter_criteria.h" #include "../common/repositories/spawn2_repository.h" #include "../common/repositories/spawn2_disabled_repository.h" +#include "../common/repositories/respawn_times_repository.h" extern EntityList entity_list; extern Zone* zone; @@ -442,32 +443,26 @@ bool ZoneDatabase::PopulateZoneSpawnList(uint32 zoneid, LinkedList &spa /* Bulk Load NPC Types Data into the cache */ content_db.LoadNPCTypesData(0, true); - std::string spawn_query = StringFormat( - "SELECT " - "respawn_times.id, " - "respawn_times.`start`, " - "respawn_times.duration " - "FROM " - "respawn_times " - "WHERE instance_id = %u", - zone->GetInstanceID() + const auto& l = RespawnTimesRepository::GetWhere( + *this, + fmt::format( + "`instance_id` = {}", + zone->GetInstanceID() + ) ); - auto results = database.QueryDatabase(spawn_query); - for (auto row = results.begin(); row != results.end(); ++row) { - uint32 start_duration = Strings::ToInt(row[1]) > 0 ? Strings::ToInt(row[1]) : 0; - uint32 end_duration = Strings::ToInt(row[2]) > 0 ? Strings::ToInt(row[2]) : 0; - /* Our current time was expired */ - if ((start_duration + end_duration) <= tv.tv_sec) { - spawn_times[Strings::ToInt(row[0])] = 0; - } - /* We still have time left on this timer */ - else { - spawn_times[Strings::ToInt(row[0])] = ((start_duration + end_duration) - tv.tv_sec) * 1000; + for (const auto& e : l) { + int start = e.start > 0 ? e.start : 0; + int duration = e.duration > 0 ? e.duration : 0; + + if ((start + duration) <= tv.tv_sec) { // Our current time was expired + spawn_times[e.id] = 0; + } else { // We still have time left on this timer + spawn_times[e.id] = ((start + duration) - tv.tv_sec) * 1000; } } - LogInfo("Loaded [{}] respawn timer(s)", Strings::Commify(results.RowCount())); + LogInfo("Loaded [{}] respawn timer(s)", Strings::Commify(l.size())); const char *zone_name = ZoneName(zoneid); @@ -537,7 +532,7 @@ bool ZoneDatabase::PopulateZoneSpawnList(uint32 zoneid, LinkedList &spa spawn2_list.Insert(new_spawn); } - LogInfo("Loaded [{}] spawn2 entries", Strings::Commify(results.RowCount())); + LogInfo("Loaded [{}] spawn2 entries", Strings::Commify(l.size())); NPC::SpawnZoneController(); diff --git a/zone/zone.cpp b/zone/zone.cpp index e81e89881..219a98805 100644 --- a/zone/zone.cpp +++ b/zone/zone.cpp @@ -61,6 +61,7 @@ #include "../common/repositories/level_exp_mods_repository.h" #include "../common/repositories/ldon_trap_entries_repository.h" #include "../common/repositories/ldon_trap_templates_repository.h" +#include "../common/repositories/respawn_times_repository.h" #include "../common/serverinfo.h" #include @@ -1167,7 +1168,7 @@ bool Zone::Init(bool is_static) { LogError("Loading World Objects failed. continuing"); } - database.QueryDatabase("DELETE FROM `respawn_times` WHERE (`start` + `duration`) < UNIX_TIMESTAMP(NOW())"); + RespawnTimesRepository::ClearExpiredRespawnTimers(database); LoadZoneDoors(); LoadZoneBlockedSpells(); @@ -2642,17 +2643,25 @@ void Zone::ReloadWorld(uint8 global_repop) void Zone::ClearSpawnTimers() { LinkedListIterator iterator(spawn2_list); + iterator.Reset(); + + std::vector respawn_ids; + while (iterator.MoreElements()) { - auto query = fmt::format( - "DELETE FROM respawn_times WHERE id = {} AND instance_id = {}", - iterator.GetData()->GetID(), - GetInstanceID() - ); - auto results = database.QueryDatabase(query); + respawn_ids.emplace_back(std::to_string(iterator.GetData()->GetID())); iterator.Advance(); } + + RespawnTimesRepository::DeleteWhere( + database, + fmt::format( + "`instance_id` = {} AND `id` IN ({})", + GetInstanceID(), + Strings::Implode(", ", respawn_ids) + ) + ); } void Zone::LoadTickItems() diff --git a/zone/zonedb.cpp b/zone/zonedb.cpp index f36a4115b..0e8c2098c 100755 --- a/zone/zonedb.cpp +++ b/zone/zonedb.cpp @@ -37,6 +37,7 @@ #include "../common/repositories/character_alt_currency_repository.h" #include "../common/repositories/character_item_recast_repository.h" #include "../common/repositories/account_repository.h" +#include "../common/repositories/respawn_times_repository.h" #include #include @@ -119,7 +120,6 @@ bool ZoneDatabase::SaveZoneCFG(uint32 zoneid, uint16 instance_version, NewZone_S void ZoneDatabase::UpdateRespawnTime(uint32 spawn2_id, uint16 instance_id, uint32 time_left) { - timeval tv; gettimeofday(&tv, nullptr); uint32 current_time = tv.tv_sec; @@ -128,63 +128,36 @@ void ZoneDatabase::UpdateRespawnTime(uint32 spawn2_id, uint16 instance_id, uint3 otherwise we update with a REPLACE INTO */ - if(time_left == 0) { - std::string query = StringFormat("DELETE FROM `respawn_times` WHERE `id` = %u AND `instance_id` = %u", spawn2_id, instance_id); - QueryDatabase(query); + if (!time_left) { + RespawnTimesRepository::DeleteWhere( + *this, + fmt::format( + "`id` = {} AND `instance_id` = {}", + spawn2_id, + instance_id + ) + ); return; } - std::string query = StringFormat( - "REPLACE INTO `respawn_times` " - "(id, " - "start, " - "duration, " - "instance_id) " - "VALUES " - "(%u, " - "%u, " - "%u, " - "%u)", - spawn2_id, - current_time, - time_left, - instance_id + RespawnTimesRepository::ReplaceOne( + *this, + RespawnTimesRepository::RespawnTimes{ + .id = static_cast(spawn2_id), + .start = static_cast(current_time), + .duration = static_cast(time_left), + .instance_id = static_cast(instance_id) + } ); - QueryDatabase(query); - - return; } //Gets the respawn time left in the database for the current spawn id -uint32 ZoneDatabase::GetSpawnTimeLeft(uint32 id, uint16 instance_id) +uint32 ZoneDatabase::GetSpawnTimeLeft(uint32 spawn2_id, uint16 instance_id) { - std::string query = StringFormat("SELECT start, duration FROM respawn_times " - "WHERE id = %lu AND instance_id = %lu", - (unsigned long)id, (unsigned long)zone->GetInstanceID()); - auto results = QueryDatabase(query); - if (!results.Success()) { - return 0; - } - - if (results.RowCount() != 1) - return 0; - - auto& row = results.begin(); - - timeval tv; - gettimeofday(&tv, nullptr); - uint32 resStart = Strings::ToInt(row[0]); - uint32 resDuration = Strings::ToInt(row[1]); - - //compare our values to current time - if((resStart + resDuration) <= tv.tv_sec) { - //our current time was expired - return 0; - } - - //we still have time left on this timer - return ((resStart + resDuration) - tv.tv_sec); + timeval tv; + gettimeofday(&tv, nullptr); + return RespawnTimesRepository::GetTimeRemaining(*this, spawn2_id, instance_id, tv.tv_sec); } void ZoneDatabase::UpdateSpawn2Status(uint32 id, uint8 new_status, uint32 instance_id) diff --git a/zone/zonedb.h b/zone/zonedb.h index bf0746c03..aa8330c5c 100644 --- a/zone/zonedb.h +++ b/zone/zonedb.h @@ -528,8 +528,8 @@ public: bool LoadSpawnGroupsByID(int spawn_group_id, SpawnGroupList* spawn_group_list); bool PopulateZoneSpawnList(uint32 zoneid, LinkedList &spawn2_list, int16 version); bool CreateSpawn2(Client *c, uint32 spawngroup, const char* zone, const glm::vec4& position, uint32 respawn, uint32 variance, uint16 condition, int16 cond_value); - void UpdateRespawnTime(uint32 id, uint16 instance_id,uint32 timeleft); - uint32 GetSpawnTimeLeft(uint32 id, uint16 instance_id); + void UpdateRespawnTime(uint32 spawn2_id, uint16 instance_id,uint32 timeleft); + uint32 GetSpawnTimeLeft(uint32 spawn2_id, uint16 instance_id); void UpdateSpawn2Status(uint32 id, uint8 new_status, uint32 instance_id); /* Grids/Paths */