[Respawns] Convert Respawn Times to Repositories (#3949)

* [Respawns] Convert Respawn Times to Repositories

- Convert `respawn_times` based methods to repositories.

* Missed some.

* Comments
This commit is contained in:
Alex King 2024-01-12 23:38:31 -05:00 committed by GitHub
parent 818f833d04
commit 71f78b757e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 108 additions and 94 deletions

View File

@ -16,6 +16,7 @@
#include "../../strings.h"
#include <ctime>
class BaseRespawnTimesRepository {
public:
struct RespawnTimes {

View File

@ -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

View File

@ -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<Spawn2*> 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);
}

View File

@ -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<Spawn2*> &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",
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<Spawn2*> &spa
spawn2_list.Insert(new_spawn);
}
LogInfo("Loaded [{}] spawn2 entries", Strings::Commify(results.RowCount()));
LogInfo("Loaded [{}] spawn2 entries", Strings::Commify(l.size()));
NPC::SpawnZoneController();

View File

@ -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 <time.h>
@ -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<Spawn2 *> iterator(spawn2_list);
iterator.Reset();
std::vector<std::string> 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()

View File

@ -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 <ctime>
#include <iostream>
@ -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<int32_t>(spawn2_id),
.start = static_cast<int32_t>(current_time),
.duration = static_cast<int32_t>(time_left),
.instance_id = static_cast<int16_t>(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);
return RespawnTimesRepository::GetTimeRemaining(*this, spawn2_id, instance_id, tv.tv_sec);
}
void ZoneDatabase::UpdateSpawn2Status(uint32 id, uint8 new_status, uint32 instance_id)

View File

@ -528,8 +528,8 @@ public:
bool LoadSpawnGroupsByID(int spawn_group_id, SpawnGroupList* spawn_group_list);
bool PopulateZoneSpawnList(uint32 zoneid, LinkedList<Spawn2*> &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 */