Jelajahi Sumber

Corrected SECURE_NPCTIMEOUT behavior (#3394)

* Fixes #3381 and fixes #3391.
* Properly end NPC sessions when a player times out.
Thanks to @mazvi, @anacondaqq, and @gustavobrigo!
Aleos 6 tahun lalu
induk
melakukan
4befcf747f
5 mengubah file dengan 18 tambahan dan 14 penghapusan
  1. 6 6
      src/config/secure.hpp
  2. 4 3
      src/map/npc.cpp
  3. 1 1
      src/map/npc.hpp
  4. 5 2
      src/map/pc.cpp
  5. 2 2
      src/map/script.cpp

+ 6 - 6
src/config/secure.hpp

@@ -22,20 +22,20 @@
 #define SECURE_NPCTIMEOUT
 
 /**
-+ * Number of seconds after an 'input' field is displayed before invoking an idle timeout.
-+ * Default: 180
+ * Number of seconds after an 'input' field is displayed before invoking an idle timeout.
+ * Default: 180
  **/
 #define NPC_SECURE_TIMEOUT_INPUT 180
 
 /**
-+ * Number of seconds after a 'menu' is displayed before invoking an idle timeout.
-+ * Default: 60
+ * Number of seconds after a 'menu' is displayed before invoking an idle timeout.
+ * Default: 60
  **/
 #define NPC_SECURE_TIMEOUT_MENU 60
 
 /**
-+ * Number of seconds after a 'next' button is displayed before invoking an idle timeout.
-+ * Default: 60
+ * Number of seconds after a 'next' button is displayed before invoking an idle timeout.
+ * Default: 60
  **/
 #define NPC_SECURE_TIMEOUT_NEXT 60
 

+ 4 - 3
src/map/npc.cpp

@@ -266,13 +266,14 @@ struct npc_data* npc_name2id(const char* name)
 	return (struct npc_data *) strdb_get(npcname_db, name);
 }
 /**
- * For the Secure NPC Timeout option (check src/config/secure.hpp) [RR]
+ * For the Secure NPC Timeout option (check src/config/secure.hpp)
+ * @author RR
  **/
 #ifdef SECURE_NPCTIMEOUT
 /**
  * Timer to check for idle time and timeout the dialog if necessary
  **/
-TIMER_FUNC(npc_rr_secure_timeout_timer){
+TIMER_FUNC(npc_secure_timeout_timer){
 	struct map_session_data* sd = NULL;
 	unsigned int timeout = NPC_SECURE_TIMEOUT_NEXT;
 	int cur_tick = gettick(); //ensure we are on last tick
@@ -298,7 +299,7 @@ TIMER_FUNC(npc_rr_secure_timeout_timer){
 	} else if(sd->st && (sd->st->state == END || sd->st->state == CLOSE)){
 		sd->npc_idle_timer = INVALID_TIMER; //stop timer the script is already ending
 	} else { //Create a new instance of ourselves to continue
-		sd->npc_idle_timer = add_timer(cur_tick + (SECURE_NPCTIMEOUT_INTERVAL*1000),npc_rr_secure_timeout_timer,sd->bl.id,0);
+		sd->npc_idle_timer = add_timer(cur_tick + (SECURE_NPCTIMEOUT_INTERVAL*1000),npc_secure_timeout_timer,sd->bl.id,0);
 	}
 	return 0;
 }

+ 1 - 1
src/map/npc.hpp

@@ -1215,7 +1215,7 @@ void npc_market_delfromsql_(const char *exname, unsigned short nameid, bool clea
 #endif
 
 #ifdef SECURE_NPCTIMEOUT
-	TIMER_FUNC(npc_rr_secure_timeout_timer);
+	TIMER_FUNC(npc_secure_timeout_timer);
 #endif
 
 // @commands (script-based)

+ 5 - 2
src/map/pc.cpp

@@ -7723,8 +7723,11 @@ void pc_close_npc(struct map_session_data *sd,int flag)
 #ifdef SECURE_NPCTIMEOUT
 		sd->npc_idle_timer = INVALID_TIMER;
 #endif
-		clif_scriptclose(sd,sd->npc_id);
-		clif_scriptclear(sd,sd->npc_id); // [Ind/Hercules]
+		if (sd->st && sd->st->state == CLOSE) {
+			clif_scriptclose(sd, sd->npc_id);
+			clif_scriptclear(sd, sd->npc_id); // [Ind/Hercules]
+			sd->st->state = END; // Force to end now
+		}
 		if(sd->st && sd->st->state == END ) {// free attached scripts that are waiting
 			script_free_state(sd->st);
 			sd->st = NULL;

+ 2 - 2
src/map/script.cpp

@@ -4177,7 +4177,7 @@ static void script_detach_state(struct script_state* st, bool dequeue_event)
 			 * We're done with this NPC session, so we cancel the timer (if existent) and move on
 			 **/
 			if( sd->npc_idle_timer != INVALID_TIMER ) {
-				delete_timer(sd->npc_idle_timer,npc_rr_secure_timeout_timer);
+				delete_timer(sd->npc_idle_timer,npc_secure_timeout_timer);
 				sd->npc_idle_timer = INVALID_TIMER;
 			}
 #endif
@@ -4217,7 +4217,7 @@ void script_attach_state(struct script_state* st){
 		sd->state.disable_atcommand_on_npc = (!pc_has_permission(sd, PC_PERM_ENABLE_COMMAND));
 #ifdef SECURE_NPCTIMEOUT
 		if( sd->npc_idle_timer == INVALID_TIMER )
-			sd->npc_idle_timer = add_timer(gettick() + (SECURE_NPCTIMEOUT_INTERVAL*1000),npc_rr_secure_timeout_timer,sd->bl.id,0);
+			sd->npc_idle_timer = add_timer(gettick() + (SECURE_NPCTIMEOUT_INTERVAL*1000),npc_secure_timeout_timer,sd->bl.id,0);
 		sd->npc_idle_tick = gettick();
 #endif
 	}