summaryrefslogtreecommitdiff
path: root/src/map/npc.c
diff options
context:
space:
mode:
authorHaru <haru@dotalux.com>2020-02-09 23:37:09 +0100
committerGitHub <noreply@github.com>2020-02-09 23:37:09 +0100
commite164b55dbb908c0006f0ca4e2e74e9995f318d57 (patch)
tree49e7c955b2444d2489df6544c7fa38012acd8de0 /src/map/npc.c
parent23537d239343a856f638307c341c9e1d2fa34330 (diff)
parentac0b5bd55203e5f968e751ee3c4a71e521290f09 (diff)
downloadhercules-e164b55dbb908c0006f0ca4e2e74e9995f318d57.tar.gz
hercules-e164b55dbb908c0006f0ca4e2e74e9995f318d57.tar.bz2
hercules-e164b55dbb908c0006f0ca4e2e74e9995f318d57.tar.xz
hercules-e164b55dbb908c0006f0ca4e2e74e9995f318d57.zip
Merge pull request #2627 from Kenpachi2k13/issue#2073
Change NPC ID validation in npc_scriptcont()
Diffstat (limited to 'src/map/npc.c')
-rw-r--r--src/map/npc.c67
1 files changed, 41 insertions, 26 deletions
diff --git a/src/map/npc.c b/src/map/npc.c
index d369aca82..e66888a74 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -1335,53 +1335,68 @@ static int npc_click(struct map_session_data *sd, struct npc_data *nd)
return 0;
}
-/*==========================================
+/**
+ * Validates a character's script related data and (re-)runs the script if validation was successful.
*
- *------------------------------------------*/
+ * Is called when:
+ * - The Next/Close button was clicked.
+ * - A menu option was selected.
+ * - A value was entered by input() script command.
+ * - A progress bar has reached 100%.
+ * - The character timed out because of idling.
+ *
+ * @param sd The character's session data.
+ * @param id The NPC ID.
+ * @param closing Whether the script is closing, or not.
+ * @return 0 on success, otherwise 1.
+ *
+**/
static int npc_scriptcont(struct map_session_data *sd, int id, bool closing)
{
- struct block_list *target = map->id2bl(id);
nullpo_retr(1, sd);
- if( id != sd->npc_id ){
- struct npc_data *nd_sd = map->id2nd(sd->npc_id);
- struct npc_data *nd = BL_CAST(BL_NPC, target);
- ShowDebug("npc_scriptcont: %s (sd->npc_id=%d) is not %s (id=%d).\n",
- nd_sd?(char*)nd_sd->name:"'Unknown NPC'", (int)sd->npc_id,
- nd?(char*)nd->name:"'Unknown NPC'", (int)id);
- return 1;
+ struct block_list *target = map->id2bl(id);
+
+#ifdef SECURE_NPCTIMEOUT
+ if (sd->npc_idle_timer != INVALID_TIMER) { /// Not yet timed out.
+#endif
+ if (id != sd->npc_id) {
+ struct npc_data *nd_sd = map->id2nd(sd->npc_id);
+ struct npc_data *nd = BL_CAST(BL_NPC, target);
+
+ ShowDebug("npc_scriptcont: %s (sd->npc_id=%d) is not %s (id=%d).\n",
+ (nd_sd != NULL) ? nd_sd->name : "'Unknown NPC'", sd->npc_id,
+ (nd != NULL) ? nd->name : "'Unknown NPC'", id);
+
+ return 1;
+ }
+#ifdef SECURE_NPCTIMEOUT
}
+#endif
- if (id != npc->fake_nd->bl.id) { // Not item script
+ if (id != npc->fake_nd->bl.id) { /// Not an item script.
if (sd->state.npc_unloaded != 0) {
sd->state.npc_unloaded = 0;
- } else if ((npc->checknear(sd,target)) == NULL) {
- ShowWarning("npc_scriptcont: failed npc->checknear test.\n");
+ } else if (npc->checknear(sd, target) == NULL) {
+ ShowWarning("npc_scriptcont: Failed npc->checknear test.\n");
return 1;
}
}
- /**
- * For the Secure NPC Timeout option (check config/Secure.h) [RR]
- **/
+
#ifdef SECURE_NPCTIMEOUT
- /**
- * Update the last NPC iteration
- **/
- sd->npc_idle_tick = timer->gettick();
+ sd->npc_idle_tick = timer->gettick(); /// Update the last NPC iteration.
#endif
- /**
- * WPE can get to this point with a progressbar; we deny it.
- **/
- if( sd->progressbar.npc_id && DIFF_TICK(sd->progressbar.timeout,timer->gettick()) > 0 )
+ /// WPE can get to this point with a progressbar; we deny it.
+ if (sd->progressbar.npc_id != 0 && DIFF_TICK(sd->progressbar.timeout, timer->gettick()) > 0)
return 1;
- if( !sd->st ) {
+ if (sd->st == NULL) {
sd->npc_id = 0;
return 1;
}
- if( closing && sd->st->state == CLOSE )
+ if (closing && sd->st->state == CLOSE)
sd->st->state = END;
script->run_main(sd->st);