Fixes instances with infinite duration (#7547)
* Fixes #6230 and fixes #7472. * Resolves an issue where instances that have infinite TimeLimit or IdleTimeOut would instantly become destroyed. * Fixes an issue where do_final_instance() could end up on an invalid iterator value resulting in memleaks/crashes on map server closure. * Add missing constructor parameters. Thanks to @secretdataz, @Lemongrass3110, and @mazvi!
This commit is contained in:
@@ -93,13 +93,15 @@ uint64 InstanceDatabase::parseBodyNode(const ryml::NodeRef& node) {
|
||||
if (!this->asInt64(node, "TimeLimit", limit))
|
||||
return 0;
|
||||
|
||||
if (limit == 0) // Infinite duration
|
||||
limit = INT64_MAX;
|
||||
|
||||
instance->limit = limit;
|
||||
|
||||
// Infinite duration
|
||||
instance->infinite_limit = (limit == 0);
|
||||
} else {
|
||||
if (!exists)
|
||||
if (!exists) {
|
||||
instance->limit = 3600;
|
||||
instance->infinite_limit = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (this->nodeExists(node, "IdleTimeOut")) {
|
||||
@@ -108,13 +110,15 @@ uint64 InstanceDatabase::parseBodyNode(const ryml::NodeRef& node) {
|
||||
if (!this->asInt64(node, "IdleTimeOut", idle))
|
||||
return 0;
|
||||
|
||||
if (idle == 0) // Infinite duration
|
||||
idle = INT64_MAX;
|
||||
|
||||
instance->timeout = idle;
|
||||
|
||||
// Infinite duration
|
||||
instance->infinite_timeout = (idle == 0);
|
||||
} else {
|
||||
if (!exists)
|
||||
if (!exists) {
|
||||
instance->timeout = 300;
|
||||
instance->infinite_timeout = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (this->nodeExists(node, "NoNpc")) {
|
||||
@@ -404,6 +408,10 @@ bool instance_startkeeptimer(std::shared_ptr<s_instance_data> idata, int instanc
|
||||
if (!db)
|
||||
return false;
|
||||
|
||||
// Infinite duration instance
|
||||
if (db->infinite_limit)
|
||||
return true;
|
||||
|
||||
// Add timer
|
||||
idata->keep_limit = time(nullptr) + db->limit;
|
||||
idata->keep_timer = add_timer(gettick() + db->limit * 1000, instance_delete_timer, instance_id, 0);
|
||||
@@ -451,6 +459,10 @@ bool instance_startidletimer(std::shared_ptr<s_instance_data> idata, int instanc
|
||||
if (!db)
|
||||
return false;
|
||||
|
||||
// Infinite idle duration instance
|
||||
if (db->infinite_timeout)
|
||||
return true;
|
||||
|
||||
// Add the timer
|
||||
idata->idle_limit = time(nullptr) + db->timeout;
|
||||
idata->idle_timer = add_timer(gettick() + db->timeout * 1000, instance_delete_timer, instance_id, 0);
|
||||
@@ -1294,6 +1306,7 @@ void do_init_instance(void) {
|
||||
* Finalizes the instances and instance database
|
||||
*/
|
||||
void do_final_instance(void) {
|
||||
for (const auto &it : instances)
|
||||
instance_destroy(it.first);
|
||||
// Since instance_destroy() modifies the unordered_map, make sure iteration always restarts.
|
||||
for (auto it = instances.begin(); it != instances.end(); it = instances.begin())
|
||||
instance_destroy(it->first);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user