mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-13 02:11:30 +00:00
[Instances] Add expire_at Column (#4820)
* [Instances] Add `expire_at` Column * expire_at update * Update servertalk.h * Add rule Instances:ExpireOffsetTimeSeconds
This commit is contained in:
parent
b9cfdea76c
commit
92128b98fd
@ -7068,6 +7068,20 @@ ADD COLUMN `expire_at` int(11) UNSIGNED NULL DEFAULT 0 AFTER `duration`;
|
|||||||
UPDATE respawn_times set expire_at = `start` + `duration`; -- backfill existing data
|
UPDATE respawn_times set expire_at = `start` + `duration`; -- backfill existing data
|
||||||
|
|
||||||
CREATE INDEX `idx_expire_at` ON `respawn_times` (`expire_at`);
|
CREATE INDEX `idx_expire_at` ON `respawn_times` (`expire_at`);
|
||||||
|
)",
|
||||||
|
.content_schema_update = false
|
||||||
|
},
|
||||||
|
ManifestEntry{
|
||||||
|
.version = 9321,
|
||||||
|
.description = "2025_03_30_instance_list_add_expire_at.sql",
|
||||||
|
.check = "SHOW COLUMNS FROM `instance_list` LIKE 'expire_at'",
|
||||||
|
.condition = "empty",
|
||||||
|
.match = "",
|
||||||
|
.sql = R"(
|
||||||
|
ALTER TABLE `instance_list`
|
||||||
|
ADD COLUMN `expire_at` bigint(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `duration`;
|
||||||
|
|
||||||
|
CREATE INDEX `idx_expire_at` ON `instance_list` (`expire_at`);
|
||||||
)",
|
)",
|
||||||
.content_schema_update = false
|
.content_schema_update = false
|
||||||
},
|
},
|
||||||
|
|||||||
@ -128,6 +128,7 @@ bool Database::CreateInstance(uint16 instance_id, uint32 zone_id, uint32 version
|
|||||||
e.version = version;
|
e.version = version;
|
||||||
e.start_time = std::time(nullptr);
|
e.start_time = std::time(nullptr);
|
||||||
e.duration = duration;
|
e.duration = duration;
|
||||||
|
e.expire_at = e.start_time + duration;
|
||||||
|
|
||||||
RespawnTimesRepository::ClearInstanceTimers(*this, e.id);
|
RespawnTimesRepository::ClearInstanceTimers(*this, e.id);
|
||||||
InstanceListRepository::ReplaceOne(*this, e);
|
InstanceListRepository::ReplaceOne(*this, e);
|
||||||
@ -560,14 +561,12 @@ void Database::GetCharactersInInstance(uint16 instance_id, std::list<uint32> &ch
|
|||||||
|
|
||||||
void Database::PurgeExpiredInstances()
|
void Database::PurgeExpiredInstances()
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* Delay purging by a day so that we can continue using adjacent free instance id's
|
|
||||||
* from the table without risking the chance we immediately re-allocate a zone that freshly expired but
|
|
||||||
* has not been fully de-allocated
|
|
||||||
*/
|
|
||||||
auto l = InstanceListRepository::GetWhere(
|
auto l = InstanceListRepository::GetWhere(
|
||||||
*this,
|
*this,
|
||||||
"(start_time + duration) <= (UNIX_TIMESTAMP() - 86400) AND never_expires = 0"
|
fmt::format(
|
||||||
|
"expire_at <= (UNIX_TIMESTAMP() - {}) AND never_expires = 0",
|
||||||
|
RuleI(Instances, ExpireOffsetTimeSeconds)
|
||||||
|
)
|
||||||
);
|
);
|
||||||
if (l.empty()) {
|
if (l.empty()) {
|
||||||
return;
|
return;
|
||||||
@ -578,19 +577,19 @@ void Database::PurgeExpiredInstances()
|
|||||||
instance_ids.emplace_back(std::to_string(e.id));
|
instance_ids.emplace_back(std::to_string(e.id));
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto imploded_instance_ids = Strings::Implode(",", instance_ids);
|
const auto ids = Strings::Implode(",", instance_ids);
|
||||||
|
|
||||||
InstanceListRepository::DeleteWhere(*this, fmt::format("id IN ({})", imploded_instance_ids));
|
InstanceListRepository::DeleteWhere(*this, fmt::format("id IN ({})", ids));
|
||||||
InstanceListPlayerRepository::DeleteWhere(*this, fmt::format("id IN ({})", imploded_instance_ids));
|
InstanceListPlayerRepository::DeleteWhere(*this, fmt::format("id IN ({})", ids));
|
||||||
RespawnTimesRepository::DeleteWhere(*this, fmt::format("instance_id IN ({})", imploded_instance_ids));
|
RespawnTimesRepository::DeleteWhere(*this, fmt::format("instance_id IN ({})", ids));
|
||||||
SpawnConditionValuesRepository::DeleteWhere(*this, fmt::format("instance_id IN ({})", imploded_instance_ids));
|
SpawnConditionValuesRepository::DeleteWhere(*this, fmt::format("instance_id IN ({})", ids));
|
||||||
CharacterCorpsesRepository::BuryInstances(*this, imploded_instance_ids);
|
CharacterCorpsesRepository::BuryInstances(*this, ids);
|
||||||
DynamicZoneMembersRepository::DeleteByManyInstances(*this, imploded_instance_ids);
|
DynamicZoneMembersRepository::DeleteByManyInstances(*this, ids);
|
||||||
DynamicZonesRepository::DeleteWhere(*this, fmt::format("instance_id IN ({})", imploded_instance_ids));
|
DynamicZonesRepository::DeleteWhere(*this, fmt::format("instance_id IN ({})", ids));
|
||||||
Spawn2DisabledRepository::DeleteWhere(*this, fmt::format("instance_id IN ({})", imploded_instance_ids));
|
Spawn2DisabledRepository::DeleteWhere(*this, fmt::format("instance_id IN ({})", ids));
|
||||||
DataBucketsRepository::DeleteWhere(*this, fmt::format("instance_id != 0 and instance_id IN ({})", imploded_instance_ids));
|
DataBucketsRepository::DeleteWhere(*this, fmt::format("instance_id != 0 and instance_id IN ({})", ids));
|
||||||
if (RuleB(Zone, StateSavingOnShutdown)) {
|
if (RuleB(Zone, StateSavingOnShutdown)) {
|
||||||
ZoneStateSpawnsRepository::DeleteWhere(*this, fmt::format("`instance_id` IN ({})", imploded_instance_ids));
|
ZoneStateSpawnsRepository::DeleteWhere(*this, fmt::format("`instance_id` IN ({})", ids));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -603,6 +602,7 @@ void Database::SetInstanceDuration(uint16 instance_id, uint32 new_duration)
|
|||||||
|
|
||||||
i.start_time = std::time(nullptr);
|
i.start_time = std::time(nullptr);
|
||||||
i.duration = new_duration;
|
i.duration = new_duration;
|
||||||
|
i.expire_at = i.start_time + i.duration;
|
||||||
|
|
||||||
InstanceListRepository::UpdateOne(*this, i);
|
InstanceListRepository::UpdateOne(*this, i);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -58,6 +58,7 @@ uint32_t DynamicZoneBase::CreateInstance()
|
|||||||
insert_instance.start_time = static_cast<int>(std::chrono::system_clock::to_time_t(m_start_time));
|
insert_instance.start_time = static_cast<int>(std::chrono::system_clock::to_time_t(m_start_time));
|
||||||
insert_instance.duration = static_cast<int>(m_duration.count());
|
insert_instance.duration = static_cast<int>(m_duration.count());
|
||||||
insert_instance.never_expires = m_never_expires;
|
insert_instance.never_expires = m_never_expires;
|
||||||
|
insert_instance.expire_at = insert_instance.start_time + insert_instance.duration;
|
||||||
|
|
||||||
auto instance = InstanceListRepository::InsertOne(GetDatabase(), insert_instance);
|
auto instance = InstanceListRepository::InsertOne(GetDatabase(), insert_instance);
|
||||||
if (instance.id == 0)
|
if (instance.id == 0)
|
||||||
|
|||||||
@ -25,6 +25,7 @@ public:
|
|||||||
uint8_t is_global;
|
uint8_t is_global;
|
||||||
uint32_t start_time;
|
uint32_t start_time;
|
||||||
uint32_t duration;
|
uint32_t duration;
|
||||||
|
uint64_t expire_at;
|
||||||
uint8_t never_expires;
|
uint8_t never_expires;
|
||||||
std::string notes;
|
std::string notes;
|
||||||
};
|
};
|
||||||
@ -43,6 +44,7 @@ public:
|
|||||||
"is_global",
|
"is_global",
|
||||||
"start_time",
|
"start_time",
|
||||||
"duration",
|
"duration",
|
||||||
|
"expire_at",
|
||||||
"never_expires",
|
"never_expires",
|
||||||
"notes",
|
"notes",
|
||||||
};
|
};
|
||||||
@ -57,6 +59,7 @@ public:
|
|||||||
"is_global",
|
"is_global",
|
||||||
"start_time",
|
"start_time",
|
||||||
"duration",
|
"duration",
|
||||||
|
"expire_at",
|
||||||
"never_expires",
|
"never_expires",
|
||||||
"notes",
|
"notes",
|
||||||
};
|
};
|
||||||
@ -105,6 +108,7 @@ public:
|
|||||||
e.is_global = 0;
|
e.is_global = 0;
|
||||||
e.start_time = 0;
|
e.start_time = 0;
|
||||||
e.duration = 0;
|
e.duration = 0;
|
||||||
|
e.expire_at = 0;
|
||||||
e.never_expires = 0;
|
e.never_expires = 0;
|
||||||
e.notes = "";
|
e.notes = "";
|
||||||
|
|
||||||
@ -149,8 +153,9 @@ public:
|
|||||||
e.is_global = row[3] ? static_cast<uint8_t>(strtoul(row[3], nullptr, 10)) : 0;
|
e.is_global = row[3] ? static_cast<uint8_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||||
e.start_time = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
|
e.start_time = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||||
e.duration = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
|
e.duration = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
|
||||||
e.never_expires = row[6] ? static_cast<uint8_t>(strtoul(row[6], nullptr, 10)) : 0;
|
e.expire_at = row[6] ? strtoull(row[6], nullptr, 10) : 0;
|
||||||
e.notes = row[7] ? row[7] : "";
|
e.never_expires = row[7] ? static_cast<uint8_t>(strtoul(row[7], nullptr, 10)) : 0;
|
||||||
|
e.notes = row[8] ? row[8] : "";
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
@ -189,8 +194,9 @@ public:
|
|||||||
v.push_back(columns[3] + " = " + std::to_string(e.is_global));
|
v.push_back(columns[3] + " = " + std::to_string(e.is_global));
|
||||||
v.push_back(columns[4] + " = " + std::to_string(e.start_time));
|
v.push_back(columns[4] + " = " + std::to_string(e.start_time));
|
||||||
v.push_back(columns[5] + " = " + std::to_string(e.duration));
|
v.push_back(columns[5] + " = " + std::to_string(e.duration));
|
||||||
v.push_back(columns[6] + " = " + std::to_string(e.never_expires));
|
v.push_back(columns[6] + " = " + std::to_string(e.expire_at));
|
||||||
v.push_back(columns[7] + " = '" + Strings::Escape(e.notes) + "'");
|
v.push_back(columns[7] + " = " + std::to_string(e.never_expires));
|
||||||
|
v.push_back(columns[8] + " = '" + Strings::Escape(e.notes) + "'");
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@ -218,6 +224,7 @@ public:
|
|||||||
v.push_back(std::to_string(e.is_global));
|
v.push_back(std::to_string(e.is_global));
|
||||||
v.push_back(std::to_string(e.start_time));
|
v.push_back(std::to_string(e.start_time));
|
||||||
v.push_back(std::to_string(e.duration));
|
v.push_back(std::to_string(e.duration));
|
||||||
|
v.push_back(std::to_string(e.expire_at));
|
||||||
v.push_back(std::to_string(e.never_expires));
|
v.push_back(std::to_string(e.never_expires));
|
||||||
v.push_back("'" + Strings::Escape(e.notes) + "'");
|
v.push_back("'" + Strings::Escape(e.notes) + "'");
|
||||||
|
|
||||||
@ -255,6 +262,7 @@ public:
|
|||||||
v.push_back(std::to_string(e.is_global));
|
v.push_back(std::to_string(e.is_global));
|
||||||
v.push_back(std::to_string(e.start_time));
|
v.push_back(std::to_string(e.start_time));
|
||||||
v.push_back(std::to_string(e.duration));
|
v.push_back(std::to_string(e.duration));
|
||||||
|
v.push_back(std::to_string(e.expire_at));
|
||||||
v.push_back(std::to_string(e.never_expires));
|
v.push_back(std::to_string(e.never_expires));
|
||||||
v.push_back("'" + Strings::Escape(e.notes) + "'");
|
v.push_back("'" + Strings::Escape(e.notes) + "'");
|
||||||
|
|
||||||
@ -296,8 +304,9 @@ public:
|
|||||||
e.is_global = row[3] ? static_cast<uint8_t>(strtoul(row[3], nullptr, 10)) : 0;
|
e.is_global = row[3] ? static_cast<uint8_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||||
e.start_time = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
|
e.start_time = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||||
e.duration = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
|
e.duration = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
|
||||||
e.never_expires = row[6] ? static_cast<uint8_t>(strtoul(row[6], nullptr, 10)) : 0;
|
e.expire_at = row[6] ? strtoull(row[6], nullptr, 10) : 0;
|
||||||
e.notes = row[7] ? row[7] : "";
|
e.never_expires = row[7] ? static_cast<uint8_t>(strtoul(row[7], nullptr, 10)) : 0;
|
||||||
|
e.notes = row[8] ? row[8] : "";
|
||||||
|
|
||||||
all_entries.push_back(e);
|
all_entries.push_back(e);
|
||||||
}
|
}
|
||||||
@ -328,8 +337,9 @@ public:
|
|||||||
e.is_global = row[3] ? static_cast<uint8_t>(strtoul(row[3], nullptr, 10)) : 0;
|
e.is_global = row[3] ? static_cast<uint8_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||||
e.start_time = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
|
e.start_time = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||||
e.duration = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
|
e.duration = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
|
||||||
e.never_expires = row[6] ? static_cast<uint8_t>(strtoul(row[6], nullptr, 10)) : 0;
|
e.expire_at = row[6] ? strtoull(row[6], nullptr, 10) : 0;
|
||||||
e.notes = row[7] ? row[7] : "";
|
e.never_expires = row[7] ? static_cast<uint8_t>(strtoul(row[7], nullptr, 10)) : 0;
|
||||||
|
e.notes = row[8] ? row[8] : "";
|
||||||
|
|
||||||
all_entries.push_back(e);
|
all_entries.push_back(e);
|
||||||
}
|
}
|
||||||
@ -410,6 +420,7 @@ public:
|
|||||||
v.push_back(std::to_string(e.is_global));
|
v.push_back(std::to_string(e.is_global));
|
||||||
v.push_back(std::to_string(e.start_time));
|
v.push_back(std::to_string(e.start_time));
|
||||||
v.push_back(std::to_string(e.duration));
|
v.push_back(std::to_string(e.duration));
|
||||||
|
v.push_back(std::to_string(e.expire_at));
|
||||||
v.push_back(std::to_string(e.never_expires));
|
v.push_back(std::to_string(e.never_expires));
|
||||||
v.push_back("'" + Strings::Escape(e.notes) + "'");
|
v.push_back("'" + Strings::Escape(e.notes) + "'");
|
||||||
|
|
||||||
@ -440,6 +451,7 @@ public:
|
|||||||
v.push_back(std::to_string(e.is_global));
|
v.push_back(std::to_string(e.is_global));
|
||||||
v.push_back(std::to_string(e.start_time));
|
v.push_back(std::to_string(e.start_time));
|
||||||
v.push_back(std::to_string(e.duration));
|
v.push_back(std::to_string(e.duration));
|
||||||
|
v.push_back(std::to_string(e.expire_at));
|
||||||
v.push_back(std::to_string(e.never_expires));
|
v.push_back(std::to_string(e.never_expires));
|
||||||
v.push_back("'" + Strings::Escape(e.notes) + "'");
|
v.push_back("'" + Strings::Escape(e.notes) + "'");
|
||||||
|
|
||||||
|
|||||||
@ -7,49 +7,11 @@
|
|||||||
|
|
||||||
class InstanceListRepository: public BaseInstanceListRepository {
|
class InstanceListRepository: public BaseInstanceListRepository {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/**
|
|
||||||
* This file was auto generated and can be modified and extended upon
|
|
||||||
*
|
|
||||||
* Base repository methods are automatically
|
|
||||||
* generated in the "base" version of this repository. The base repository
|
|
||||||
* is immutable and to be left untouched, while methods in this class
|
|
||||||
* are used as extension methods for more specific persistence-layer
|
|
||||||
* accessors or mutators.
|
|
||||||
*
|
|
||||||
* Base Methods (Subject to be expanded upon in time)
|
|
||||||
*
|
|
||||||
* Note: Not all tables are designed appropriately to fit functionality with all base methods
|
|
||||||
*
|
|
||||||
* InsertOne
|
|
||||||
* UpdateOne
|
|
||||||
* DeleteOne
|
|
||||||
* FindOne
|
|
||||||
* GetWhere(std::string where_filter)
|
|
||||||
* DeleteWhere(std::string where_filter)
|
|
||||||
* InsertMany
|
|
||||||
* All
|
|
||||||
*
|
|
||||||
* Example custom methods in a repository
|
|
||||||
*
|
|
||||||
* InstanceListRepository::GetByZoneAndVersion(int zone_id, int zone_version)
|
|
||||||
* InstanceListRepository::GetWhereNeverExpires()
|
|
||||||
* InstanceListRepository::GetWhereXAndY()
|
|
||||||
* InstanceListRepository::DeleteWhereXAndY()
|
|
||||||
*
|
|
||||||
* Most of the above could be covered by base methods, but if you as a developer
|
|
||||||
* find yourself re-using logic for other parts of the code, its best to just make a
|
|
||||||
* method that can be re-used easily elsewhere especially if it can use a base repository
|
|
||||||
* method and encapsulate filters there
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Custom extended repository methods here
|
|
||||||
|
|
||||||
static int UpdateDuration(Database& db, uint16 instance_id, uint32_t new_duration)
|
static int UpdateDuration(Database& db, uint16 instance_id, uint32_t new_duration)
|
||||||
{
|
{
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"UPDATE `{}` SET `duration` = {} WHERE `{}` = {}",
|
"UPDATE `{}` SET `duration` = {}, `expire_at` = (`duration` + `start_time`) WHERE `{}` = {}",
|
||||||
TableName(),
|
TableName(),
|
||||||
new_duration,
|
new_duration,
|
||||||
PrimaryKey(),
|
PrimaryKey(),
|
||||||
@ -65,7 +27,7 @@ public:
|
|||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
SQL(
|
SQL(
|
||||||
SELECT ((start_time + duration) - UNIX_TIMESTAMP()) AS `remaining` FROM `{}`
|
SELECT (`expire_at` - UNIX_TIMESTAMP()) AS `remaining` FROM `{}`
|
||||||
WHERE `id` = {}
|
WHERE `id` = {}
|
||||||
),
|
),
|
||||||
TableName(),
|
TableName(),
|
||||||
|
|||||||
@ -1096,6 +1096,7 @@ RULE_CATEGORY(Instances)
|
|||||||
RULE_INT(Instances, ReservedInstances, 100, "Number of instance IDs which are reserved for globals. This value should not be changed while a server is running")
|
RULE_INT(Instances, ReservedInstances, 100, "Number of instance IDs which are reserved for globals. This value should not be changed while a server is running")
|
||||||
RULE_BOOL(Instances, RecycleInstanceIds, true, "Setting whether free instance IDs should be recycled to prevent them from gradually running out at 32k")
|
RULE_BOOL(Instances, RecycleInstanceIds, true, "Setting whether free instance IDs should be recycled to prevent them from gradually running out at 32k")
|
||||||
RULE_INT(Instances, GuildHallExpirationDays, 90, "Amount of days before a Guild Hall instance expires")
|
RULE_INT(Instances, GuildHallExpirationDays, 90, "Amount of days before a Guild Hall instance expires")
|
||||||
|
RULE_INT(Instances, ExpireOffsetTimeSeconds, 3600, "Amount of seconds to beyond instance expiration time we wait to purge the entry from the database. (Default: 1 Hour)")
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
RULE_CATEGORY(Expedition)
|
RULE_CATEGORY(Expedition)
|
||||||
|
|||||||
@ -42,7 +42,7 @@
|
|||||||
* Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
* Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define CURRENT_BINARY_DATABASE_VERSION 9320
|
#define CURRENT_BINARY_DATABASE_VERSION 9321
|
||||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9054
|
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9054
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -137,8 +137,11 @@ void DynamicZone::SetSecondsRemaining(uint32_t seconds_remaining)
|
|||||||
m_expire_time = now + new_remaining;
|
m_expire_time = now + new_remaining;
|
||||||
m_duration = std::chrono::duration_cast<std::chrono::seconds>(m_expire_time - m_start_time);
|
m_duration = std::chrono::duration_cast<std::chrono::seconds>(m_expire_time - m_start_time);
|
||||||
|
|
||||||
InstanceListRepository::UpdateDuration(database,
|
InstanceListRepository::UpdateDuration(
|
||||||
GetInstanceID(), static_cast<uint32_t>(m_duration.count()));
|
database,
|
||||||
|
GetInstanceID(),
|
||||||
|
static_cast<uint32_t>(m_duration.count())
|
||||||
|
);
|
||||||
|
|
||||||
SendZonesDurationUpdate(); // update zone caches and actual instance's timer
|
SendZonesDurationUpdate(); // update zone caches and actual instance's timer
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3506,6 +3506,7 @@ void QuestManager::UpdateInstanceTimer(uint16 instance_id, uint32 new_duration)
|
|||||||
|
|
||||||
e.duration = new_duration;
|
e.duration = new_duration;
|
||||||
e.start_time = std::time(nullptr);
|
e.start_time = std::time(nullptr);
|
||||||
|
e.expire_at = e.start_time + e.duration;
|
||||||
|
|
||||||
const int updated = InstanceListRepository::UpdateOne(database, e);
|
const int updated = InstanceListRepository::UpdateOne(database, e);
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user