Fixes an issue with instance timer display (#6988)

* Fixes #6835.
* Follow up to ac7292c.
* Instance packet updates were ignored if instances had infinite duration or timeouts.
* Infinite duration or timeout instances now store the cap as INT64_MAX instead of 0.
* Converts the TimeLimit and IdleTimeOut storage types from uint32 to int64 to allow longer 'infinite' duration instances.
Thanks to @samers1 and @Atemo!
This commit is contained in:
Aleos 2022-06-16 10:49:41 -04:00 committed by GitHub
parent fbbd0d0a8e
commit 73811d10a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 41 additions and 41 deletions

View File

@ -88,11 +88,14 @@ uint64 InstanceDatabase::parseBodyNode(const ryml::NodeRef& node) {
}
if (this->nodeExists(node, "TimeLimit")) {
uint32 limit;
int64 limit;
if (!this->asUInt32(node, "TimeLimit", limit))
if (!this->asInt64(node, "TimeLimit", limit))
return 0;
if (limit == 0) // Infinite duration
limit = INT64_MAX;
instance->limit = limit;
} else {
if (!exists)
@ -100,11 +103,14 @@ uint64 InstanceDatabase::parseBodyNode(const ryml::NodeRef& node) {
}
if (this->nodeExists(node, "IdleTimeOut")) {
uint32 idle;
int64 idle;
if (!this->asUInt32(node, "IdleTimeOut", idle))
if (!this->asInt64(node, "IdleTimeOut", idle))
return 0;
if (idle == 0) // Infinite duration
idle = INT64_MAX;
instance->timeout = idle;
} else {
if (!exists)
@ -359,7 +365,7 @@ static TIMER_FUNC(instance_subscription_timer){
bool instance_startkeeptimer(std::shared_ptr<s_instance_data> idata, int instance_id)
{
// No timer
if (!idata || idata->keep_timer != INVALID_TIMER || idata->keep_limit == 0)
if (!idata || idata->keep_timer != INVALID_TIMER)
return false;
std::shared_ptr<s_instance_db> db = instance_db.find(idata->id);
@ -368,7 +374,7 @@ bool instance_startkeeptimer(std::shared_ptr<s_instance_data> idata, int instanc
return false;
// Add timer
idata->keep_limit = static_cast<unsigned int>(time(nullptr)) + db->limit;
idata->keep_limit = time(nullptr) + db->limit;
idata->keep_timer = add_timer(gettick() + db->limit * 1000, instance_delete_timer, instance_id, 0);
switch(idata->mode) {
@ -376,19 +382,19 @@ bool instance_startkeeptimer(std::shared_ptr<s_instance_data> idata, int instanc
break;
case IM_CHAR:
if (map_charid2sd(idata->owner_id)) // Notify player of the added instance timer
clif_instance_status(instance_id, idata->keep_limit, idata->idle_limit);
clif_instance_status(instance_id, static_cast<uint32>(idata->keep_limit), static_cast<uint32>(idata->idle_limit));
break;
case IM_PARTY:
if (party_search(idata->owner_id)) // Notify party of the added instance timer
clif_instance_status(instance_id, idata->keep_limit, idata->idle_limit);
clif_instance_status(instance_id, static_cast<uint32>(idata->keep_limit), static_cast<uint32>(idata->idle_limit));
break;
case IM_GUILD:
if (guild_search(idata->owner_id)) // Notify guild of the added instance timer
clif_instance_status(instance_id, idata->keep_limit, idata->idle_limit);
clif_instance_status(instance_id, static_cast<uint32>(idata->keep_limit), static_cast<uint32>(idata->idle_limit));
break;
case IM_CLAN:
if (clan_search(idata->owner_id)) // Notify clan of the added instance timer
clif_instance_status(instance_id, idata->keep_limit, idata->idle_limit);
clif_instance_status(instance_id, static_cast<uint32>(idata->keep_limit), static_cast<uint32>(idata->idle_limit));
break;
default:
return false;
@ -415,7 +421,7 @@ bool instance_startidletimer(std::shared_ptr<s_instance_data> idata, int instanc
return false;
// Add the timer
idata->idle_limit = static_cast<unsigned int>(time(nullptr)) + db->timeout;
idata->idle_limit = time(nullptr) + db->timeout;
idata->idle_timer = add_timer(gettick() + db->timeout * 1000, instance_delete_timer, instance_id, 0);
switch(idata->mode) {
@ -423,19 +429,19 @@ bool instance_startidletimer(std::shared_ptr<s_instance_data> idata, int instanc
break;
case IM_CHAR:
if (map_charid2sd(idata->owner_id)) // Notify player of added instance timer
clif_instance_status(instance_id, idata->keep_limit, idata->idle_limit);
clif_instance_status(instance_id, static_cast<uint32>(idata->keep_limit), static_cast<uint32>(idata->idle_limit));
break;
case IM_PARTY:
if (party_search(idata->owner_id)) // Notify party of added instance timer
clif_instance_status(instance_id, idata->keep_limit, idata->idle_limit);
clif_instance_status(instance_id, static_cast<uint32>(idata->keep_limit), static_cast<uint32>(idata->idle_limit));
break;
case IM_GUILD:
if (guild_search(idata->owner_id)) // Notify guild of added instance timer
clif_instance_status(instance_id, idata->keep_limit, idata->idle_limit);
clif_instance_status(instance_id, static_cast<uint32>(idata->keep_limit), static_cast<uint32>(idata->idle_limit));
break;
case IM_CLAN:
if (clan_search(idata->owner_id)) // Notify clan of added instance timer
clif_instance_status(instance_id, idata->keep_limit, idata->idle_limit);
clif_instance_status(instance_id, static_cast<uint32>(idata->keep_limit), static_cast<uint32>(idata->idle_limit));
break;
default:
return false;
@ -457,6 +463,7 @@ bool instance_stopidletimer(std::shared_ptr<s_instance_data> idata, int instance
return false;
// Delete the timer - Party has returned or instance is destroyed
idata->idle_limit = 0;
delete_timer(idata->idle_timer, instance_delete_timer);
idata->idle_timer = INVALID_TIMER;
@ -465,19 +472,19 @@ bool instance_stopidletimer(std::shared_ptr<s_instance_data> idata, int instance
break;
case IM_CHAR:
if (map_charid2sd(idata->owner_id)) // Notify the player
clif_instance_changestatus(instance_id, IN_NOTIFY, 0);
clif_instance_changestatus(instance_id, IN_NOTIFY, static_cast<uint32>(idata->idle_limit));
break;
case IM_PARTY:
if (party_search(idata->owner_id)) // Notify the party
clif_instance_changestatus(instance_id, IN_NOTIFY, 0);
clif_instance_changestatus(instance_id, IN_NOTIFY, static_cast<uint32>(idata->idle_limit));
break;
case IM_GUILD:
if (guild_search(idata->owner_id)) // Notify the guild
clif_instance_changestatus(instance_id, IN_NOTIFY, 0);
clif_instance_changestatus(instance_id, IN_NOTIFY, static_cast<uint32>(idata->idle_limit));
break;
case IM_CLAN:
if (clan_search(idata->owner_id)) // Notify the clan
clif_instance_changestatus(instance_id, IN_NOTIFY, 0);
clif_instance_changestatus(instance_id, IN_NOTIFY, static_cast<uint32>(idata->idle_limit));
break;
default:
return false;
@ -677,15 +684,8 @@ int instance_addmap(int instance_id) {
// Set to busy, update timers
idata->state = INSTANCE_BUSY;
if (db->timeout > 0) {
idata->idle_limit = static_cast<unsigned int>(time(nullptr)) + db->timeout;
idata->idle_timer = add_timer(gettick() + db->timeout * 1000, instance_delete_timer, instance_id, 0);
}
if (db->limit > 0) {
//This will allow the instance to get a time in 'instance_startkeeptimer'
idata->keep_limit = 1;
}
idata->idle_limit = time(nullptr) + db->timeout;
idata->idle_timer = add_timer(gettick() + db->timeout * 1000, instance_delete_timer, instance_id, 0);
idata->nomapflag = db->nomapflag;
idata->nonpc = db->nonpc;
@ -724,19 +724,19 @@ int instance_addmap(int instance_id) {
break;
case IM_CHAR:
if (map_charid2sd(idata->owner_id)) // Inform player of the created instance
clif_instance_status(instance_id, idata->keep_limit, idata->idle_limit);
clif_instance_status(instance_id, static_cast<uint32>(idata->keep_limit), static_cast<uint32>(idata->idle_limit));
break;
case IM_PARTY:
if (party_search(idata->owner_id)) // Inform party members of the created instance
clif_instance_status(instance_id, idata->keep_limit, idata->idle_limit);
clif_instance_status(instance_id, static_cast<uint32>(idata->keep_limit), static_cast<uint32>(idata->idle_limit));
break;
case IM_GUILD:
if (guild_search(idata->owner_id)) // Inform guild members of the created instance
clif_instance_status(instance_id, idata->keep_limit, idata->idle_limit);
clif_instance_status(instance_id, static_cast<uint32>(idata->keep_limit), static_cast<uint32>(idata->idle_limit));
break;
case IM_CLAN:
if (clan_search(idata->owner_id)) // Inform clan members of the created instance
clif_instance_status(instance_id, idata->keep_limit, idata->idle_limit);
clif_instance_status(instance_id, static_cast<uint32>(idata->keep_limit), static_cast<uint32>(idata->idle_limit));
break;
default:
return 0;
@ -934,7 +934,7 @@ bool instance_destroy(int instance_id)
}
}
} else {
unsigned int now = static_cast<unsigned int>(time(nullptr));
int64 now = time(nullptr);
if(idata->keep_limit && idata->keep_limit <= now)
type = IN_DESTROY_LIVE_TIMEOUT;
@ -1117,7 +1117,7 @@ bool instance_reqinfo(struct map_session_data *sd, int instance_id)
} else if (idata->state == INSTANCE_BUSY) { // Give info on the instance if busy
int map_instance_id = map_getmapdata(sd->bl.m)->instance_id;
if (map_instance_id == 0 || map_instance_id == instance_id) {
clif_instance_status(instance_id, idata->keep_limit, idata->idle_limit);
clif_instance_status(instance_id, static_cast<uint32>(idata->keep_limit), static_cast<uint32>(idata->idle_limit));
sd->instance_mode = idata->mode;
}
}
@ -1134,7 +1134,7 @@ bool instance_addusers(int instance_id)
{
std::shared_ptr<s_instance_data> idata = util::umap_find(instances, instance_id);
if(!idata || idata->state != INSTANCE_BUSY || idata->idle_limit == 0)
if(!idata || idata->state != INSTANCE_BUSY)
return false;
// Stop the idle timer if we had one
@ -1155,7 +1155,7 @@ bool instance_delusers(int instance_id)
{
std::shared_ptr<s_instance_data> idata = util::umap_find(instances, instance_id);
if(!idata || idata->state != INSTANCE_BUSY || idata->idle_limit == 0)
if(!idata || idata->state != INSTANCE_BUSY)
return false;
int users = 0;
@ -1190,8 +1190,8 @@ void do_reload_instance(void)
// Create new keep timer
std::shared_ptr<s_instance_db> db = instance_db.find(idata->id);
if (db && db->limit > 0)
idata->keep_limit = static_cast<unsigned int>(time(nullptr)) + db->limit;
if (db)
idata->keep_limit = time(nullptr) + db->limit;
}
}

View File

@ -63,9 +63,9 @@ struct s_instance_data {
e_instance_state state; ///< State of instance
e_instance_mode mode; ///< Mode of instance
int owner_id; ///< Owner ID of instance
unsigned int keep_limit; ///< Life time of instance
int64 keep_limit; ///< Life time of instance
int keep_timer; ///< Life time ID
unsigned int idle_limit; ///< Idle time of instance
int64 idle_limit; ///< Idle time of instance
int idle_timer; ///< Idle timer ID
bool nonpc;
bool nomapflag;
@ -89,7 +89,7 @@ struct s_instance_data {
struct s_instance_db {
int id; ///< Instance DB ID
std::string name; ///< Instance name
uint32 limit, ///< Duration limit
int64 limit, ///< Duration limit
timeout; ///< Timeout limit
bool nonpc;
bool nomapflag;