From e671397fb25182e67d191c32f1272a4727322807 Mon Sep 17 00:00:00 2001 From: shennetsind Date: Tue, 16 Apr 2013 00:48:09 -0300 Subject: Fixed Bug #1721 SECURE_NPCTIMEOUT now possesses 3 settings (to mimic official ones) NPC_SECURE_TIMEOUT_INPUT NPC_SECURE_TIMEOUT_MENU NPC_SECURE_TIMEOUT_NEXT http://hercules.ws/board/tracker/issue-1721-npc-window-timeout/ Signed-off-by: shennetsind --- src/config/const.h | 10 ++++++++-- src/config/secure.h | 24 ++++++++++++++++++++---- src/map/battle.c | 4 ++-- src/map/clif.c | 4 ++-- src/map/npc.c | 18 +++++++++++++++--- src/map/npc.h | 2 +- src/map/pc.c | 3 ++- src/map/pc.h | 10 +++++++++- src/map/script.c | 25 ++++++++++++++++++++++--- 9 files changed, 81 insertions(+), 19 deletions(-) diff --git a/src/config/const.h b/src/config/const.h index abc36b05f..825824c62 100644 --- a/src/config/const.h +++ b/src/config/const.h @@ -19,8 +19,14 @@ #if SECURE_NPCTIMEOUT_INTERVAL <= 0 #error SECURE_NPCTIMEOUT_INTERVAL should be at least 1 (1s) #endif -#if SECURE_NPCTIMEOUT < 0 - #error SECURE_NPCTIMEOUT cannot be lower than 0 +#if NPC_SECURE_TIMEOUT_INPUT < 0 + #error NPC_SECURE_TIMEOUT_INPUT cannot be lower than 0 +#endif +#if NPC_SECURE_TIMEOUT_MENU < 0 + #error NPC_SECURE_TIMEOUT_MENU cannot be lower than 0 +#endif +#if NPC_SECURE_TIMEOUT_NEXT < 0 + #error NPC_SECURE_TIMEOUT_NEXT cannot be lower than 0 #endif /** diff --git a/src/config/secure.h b/src/config/secure.h index 70ee0437a..7f16ba55a 100644 --- a/src/config/secure.h +++ b/src/config/secure.h @@ -17,11 +17,27 @@ * Optional NPC Dialog Timer * When enabled all npcs dialog will 'timeout' if user is on idle for longer than the amount of seconds allowed * - On 'timeout' the npc dialog window changes its next/menu to a 'close' button - * @values - * - ? : Desired idle time in seconds (e.g. 10) - * - 0 : Disabled + * Uncomment to enable **/ -#define SECURE_NPCTIMEOUT 0 +//#define SECURE_NPCTIMEOUT + +/** + * number of seconds to 'timeout' if the user is on idle for longer than the value allowed after a 'input' field is displayed. + * default: 180 + **/ +#define NPC_SECURE_TIMEOUT_INPUT 180 + +/** + * number of seconds to 'timeout' if the user is on idle for longer than the value allowed after a 'menu' is displayed. + * default: 60 + **/ +#define NPC_SECURE_TIMEOUT_MENU 60 + +/** + * number of seconds to 'timeout' if the user is on idle for longer than the value allowed after a 'next' button is displayed. + * default: 60 + **/ +#define NPC_SECURE_TIMEOUT_NEXT 60 /** * (Secure) Optional NPC Dialog Timer diff --git a/src/map/battle.c b/src/map/battle.c index ac386f890..ad4c7fc7d 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -5940,10 +5940,10 @@ void Hercules_report(char* date, char *time_c) { config |= C_RENEWAL_ASPD; #endif -/* not a ifdef because SECURE_NPCTIMEOUT is always defined, but either as 0 or higher */ -#if SECURE_NPCTIMEOUT +#ifdef SECURE_NPCTIMEOUT config |= C_SECURE_NPCTIMEOUT; #endif + /* non-define part */ if( db_use_sqldbs ) config |= C_SQL_DBS; diff --git a/src/map/clif.c b/src/map/clif.c index 57b14b1de..d851b4435 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -11255,13 +11255,13 @@ void clif_parse_NpcSelectMenu(int fd,struct map_session_data *sd) uint8 select = RFIFOB(fd,6); if( (select > sd->npc_menu && select != 0xff) || select == 0 ) { -#if SECURE_NPCTIMEOUT +#ifdef SECURE_NPCTIMEOUT if( sd->npc_idle_timer != INVALID_TIMER ) { #endif TBL_NPC* nd = map_id2nd(npc_id); ShowWarning("Invalid menu selection on npc %d:'%s' - got %d, valid range is [%d..%d] (player AID:%d, CID:%d, name:'%s')!\n", npc_id, (nd)?nd->name:"invalid npc id", select, 1, sd->npc_menu, sd->bl.id, sd->status.char_id, sd->status.name); clif->GM_kick(NULL,sd); -#if SECURE_NPCTIMEOUT +#ifdef SECURE_NPCTIMEOUT } #endif return; diff --git a/src/map/npc.c b/src/map/npc.c index 5cca94a87..a3340de78 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -240,17 +240,29 @@ struct npc_data* npc_name2id(const char* name) /** * For the Secure NPC Timeout option (check config/Secure.h) [RR] **/ -#if SECURE_NPCTIMEOUT +#ifdef SECURE_NPCTIMEOUT /** * Timer to check for idle time and timeout the dialog if necessary **/ int npc_rr_secure_timeout_timer(int tid, unsigned int tick, int id, intptr_t data) { struct map_session_data* sd = NULL; + unsigned int timeout = NPC_SECURE_TIMEOUT_NEXT; if( (sd = map_id2sd(id)) == NULL || !sd->npc_id ) { if( sd ) sd->npc_idle_timer = INVALID_TIMER; return 0;//Not logged in anymore OR no longer attached to a npc } - if( DIFF_TICK(tick,sd->npc_idle_tick) > (SECURE_NPCTIMEOUT*1000) ) { + + switch( sd->npc_idle_type ) { + case NPCT_INPUT: + timeout = NPC_SECURE_TIMEOUT_INPUT; + break; + case NPCT_MENU: + timeout = NPC_SECURE_TIMEOUT_MENU; + break; + //case NPCT_WAIT: var starts with this value + } + + if( DIFF_TICK(tick,sd->npc_idle_tick) > (timeout*1000) ) { /** * If we still have the NPC script attached, tell it to stop. **/ @@ -1240,7 +1252,7 @@ int npc_scriptcont(struct map_session_data* sd, int id, bool closing) /** * For the Secure NPC Timeout option (check config/Secure.h) [RR] **/ -#if SECURE_NPCTIMEOUT +#ifdef SECURE_NPCTIMEOUT /** * Update the last NPC iteration **/ diff --git a/src/map/npc.h b/src/map/npc.h index 229363191..8800b4e5b 100644 --- a/src/map/npc.h +++ b/src/map/npc.h @@ -179,7 +179,7 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, uns /** * For the Secure NPC Timeout option (check config/Secure.h) [RR] **/ -#if SECURE_NPCTIMEOUT +#ifdef SECURE_NPCTIMEOUT int npc_rr_secure_timeout_timer(int tid, unsigned int tick, int id, intptr_t data); #endif diff --git a/src/map/pc.c b/src/map/pc.c index bb577a8fc..52619bbea 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -968,12 +968,13 @@ bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_tim /** * For the Secure NPC Timeout option (check config/Secure.h) [RR] **/ -#if SECURE_NPCTIMEOUT +#ifdef SECURE_NPCTIMEOUT /** * Initialize to defaults/expected **/ sd->npc_idle_timer = INVALID_TIMER; sd->npc_idle_tick = tick; + sd->npc_idle_type = NPCT_INPUT; #endif sd->canuseitem_tick = tick; diff --git a/src/map/pc.h b/src/map/pc.h index 5ccfdaee8..05090ad9e 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -109,6 +109,12 @@ struct s_autobonus { unsigned short pos; }; +enum npc_timeout_type { + NPCT_INPUT = 0, + NPCT_MENU = 1, + NPCT_WAIT = 2, +}; + struct map_session_data { struct block_list bl; struct unit_data ud; @@ -467,7 +473,7 @@ struct map_session_data { /** * For the Secure NPC Timeout option (check config/Secure.h) [RR] **/ -#if SECURE_NPCTIMEOUT +#ifdef SECURE_NPCTIMEOUT /** * ID of the timer * @info @@ -481,6 +487,8 @@ struct map_session_data { * - It is updated on every NPC iteration as mentioned above **/ unsigned int npc_idle_tick; + /* */ + enum npc_timeout_type npc_idle_type; #endif struct { diff --git a/src/map/script.c b/src/map/script.c index 648a8940f..2cb9e8cfc 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -50,6 +50,7 @@ #include "script.h" #include "quest.h" #include "elemental.h" +#include "../config/core.h" #include #include @@ -3603,7 +3604,7 @@ static void script_detach_state(struct script_state* st, bool dequeue_event) /** * For the Secure NPC Timeout option (check config/Secure.h) [RR] **/ -#if SECURE_NPCTIMEOUT +#ifdef SECURE_NPCTIMEOUT /** * We're done with this NPC session, so we cancel the timer (if existent) and move on **/ @@ -3649,7 +3650,7 @@ static void script_attach_state(struct script_state* st) /** * For the Secure NPC Timeout option (check config/Secure.h) [RR] **/ -#if SECURE_NPCTIMEOUT +#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_tick = gettick(); @@ -4376,7 +4377,9 @@ BUILDIN_FUNC(next) sd = script_rid2sd(st); if( sd == NULL ) return 0; - +#ifdef SECURE_NPCTIMEOUT + sd->npc_idle_type = NPCT_WAIT; +#endif st->state = STOP; clif->scriptnext(sd, st->oid); return 0; @@ -4478,6 +4481,10 @@ BUILDIN_FUNC(menu) if( sd == NULL ) return 0; +#ifdef SECURE_NPCTIMEOUT + sd->npc_idle_type = NPCT_MENU; +#endif + // TODO detect multiple scripts waiting for input at the same time, and what to do when that happens if( sd->state.menu_or_input == 0 ) { @@ -4603,6 +4610,10 @@ BUILDIN_FUNC(select) if( sd == NULL ) return 0; +#ifdef SECURE_NPCTIMEOUT + sd->npc_idle_type = NPCT_MENU; +#endif + if( sd->state.menu_or_input == 0 ) { struct StringBuf buf; @@ -4678,6 +4689,10 @@ BUILDIN_FUNC(prompt) if( sd == NULL ) return 0; +#ifdef SECURE_NPCTIMEOUT + sd->npc_idle_type = NPCT_MENU; +#endif + if( sd->state.menu_or_input == 0 ) { struct StringBuf buf; @@ -5417,6 +5432,10 @@ BUILDIN_FUNC(input) min = (script_hasdata(st,3) ? script_getnum(st,3) : script_config.input_min_value); max = (script_hasdata(st,4) ? script_getnum(st,4) : script_config.input_max_value); +#ifdef SECURE_NPCTIMEOUT + sd->npc_idle_type = NPCT_WAIT; +#endif + if( !sd->state.menu_or_input ) { // first invocation, display npc input box sd->state.menu_or_input = 1; -- cgit v1.2.3-60-g2f50