Selaa lähdekoodia

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!
Aleos 2 vuotta sitten
vanhempi
commit
73811d10a4
2 muutettua tiedostoa jossa 41 lisäystä ja 41 poistoa
  1. 38 38
      src/map/instance.cpp
  2. 3 3
      src/map/instance.hpp

+ 38 - 38
src/map/instance.cpp

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

+ 3 - 3
src/map/instance.hpp

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