From 4befcf747fa0c6eb22c6c1dcc31c5f55486dcf91 Mon Sep 17 00:00:00 2001 From: Aleos Date: Sat, 11 Aug 2018 16:13:24 -0400 Subject: [PATCH] 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! --- src/config/secure.hpp | 12 ++++++------ src/map/npc.cpp | 7 ++++--- src/map/npc.hpp | 2 +- src/map/pc.cpp | 7 +++++-- src/map/script.cpp | 4 ++-- 5 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/config/secure.hpp b/src/config/secure.hpp index 97dd678484..0b00f5341c 100644 --- a/src/config/secure.hpp +++ b/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 diff --git a/src/map/npc.cpp b/src/map/npc.cpp index 6b904c0765..e5a274e0f0 100644 --- a/src/map/npc.cpp +++ b/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; } diff --git a/src/map/npc.hpp b/src/map/npc.hpp index ca79159d1a..c93469ed89 100644 --- a/src/map/npc.hpp +++ b/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) diff --git a/src/map/pc.cpp b/src/map/pc.cpp index 14ad45065b..7e9e822543 100755 --- a/src/map/pc.cpp +++ b/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; diff --git a/src/map/script.cpp b/src/map/script.cpp index d17b43ad8b..f388618ec7 100644 --- a/src/map/script.cpp +++ b/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 }