summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2016-09-01 22:02:39 +0300
committerAndrei Karas <akaras@inbox.ru>2016-09-01 22:02:39 +0300
commit211787e349e0249fc032b3b51f8649af613f5ecf (patch)
tree71e67c6b58ecf836f47f836c9625e2bcae2a7db9
parent4f35fa5d10ba0a30157205227f25aed6da67f4e1 (diff)
downloadevol-hercules-211787e349e0249fc032b3b51f8649af613f5ecf.tar.gz
evol-hercules-211787e349e0249fc032b3b51f8649af613f5ecf.tar.bz2
evol-hercules-211787e349e0249fc032b3b51f8649af613f5ecf.tar.xz
evol-hercules-211787e349e0249fc032b3b51f8649af613f5ecf.zip
Add hack for avoid npc_str buffer size limitation.
Now for npc_str used global variable. And it cant be used in any functions except input related buildins.
-rw-r--r--src/emap/clif.c20
-rw-r--r--src/emap/clif.h2
-rw-r--r--src/emap/init.c3
-rw-r--r--src/emap/script_buildins.c92
4 files changed, 105 insertions, 12 deletions
diff --git a/src/emap/clif.c b/src/emap/clif.c
index 63b7cc0..d3bf523 100644
--- a/src/emap/clif.c
+++ b/src/emap/clif.c
@@ -37,6 +37,7 @@
#include "emap/struct/sessionext.h"
extern bool isInit;
+extern char global_npc_str[1001];
static inline void RBUFPOS(const uint8 *p,
unsigned short pos,
@@ -1739,3 +1740,22 @@ void eclif_party_info_post(struct party_data *p,
clif->party_option(p, sd, 2);
}
}
+
+/// NPC text input dialog value (CZ_INPUT_EDITDLGSTR).
+/// 01d5 <packet len>.W <npc id>.L <string>.?B
+void eclif_parse_NpcStringInput(int fd,
+ struct map_session_data* sd)
+{
+ int message_len = RFIFOW(fd, 2) - 8;
+ int npcid = RFIFOL(fd, 4);
+ const char *message = RFIFOP(fd, 8);
+
+ if (message_len <= 0)
+ return; // invalid input
+
+ if (message_len > 1000)
+ message_len = 1000;
+
+ safestrncpy(global_npc_str, message, message_len);
+ npc->scriptcont(sd, npcid, false);
+}
diff --git a/src/emap/clif.h b/src/emap/clif.h
index 4838dc6..1353cc7 100644
--- a/src/emap/clif.h
+++ b/src/emap/clif.h
@@ -103,4 +103,6 @@ void eclif_parse_WalkToXY(int fd,
struct map_session_data *sd) __attribute__((nonnull (2)));
void eclif_party_info_post(struct party_data *p,
struct map_session_data *sd);
+void eclif_parse_NpcStringInput(int fd,
+ struct map_session_data* sd) __attribute__((nonnull (2)));
#endif // EVOL_MAP_CLIF
diff --git a/src/emap/init.c b/src/emap/init.c
index fb95d32..23a2a88 100644
--- a/src/emap/init.c
+++ b/src/emap/init.c
@@ -77,6 +77,7 @@
extern int langScriptId;
extern int mountScriptId;
bool isInit;
+char global_npc_str[1001];
HPExport struct hplugin_info pinfo =
{
@@ -89,6 +90,7 @@ HPExport struct hplugin_info pinfo =
HPExport void plugin_init (void)
{
isInit = false;
+ *global_npc_str = 0;
htreg_init();
skilld_init();
@@ -327,6 +329,7 @@ HPExport void plugin_init (void)
skill->validate_additional_fields = eskill_validate_additional_fields;
clif->useskill = eclif_useskill;
clif->pWalkToXY = eclif_parse_WalkToXY;
+ clif->pNpcStringInput = eclif_parse_NpcStringInput;
pc->jobchange = epc_jobchange;
langScriptId = script->add_str("Lang");
diff --git a/src/emap/script_buildins.c b/src/emap/script_buildins.c
index 2ada5ca..b0cf499 100644
--- a/src/emap/script_buildins.c
+++ b/src/emap/script_buildins.c
@@ -34,6 +34,7 @@
#include "emap/utils/formatutils.h"
extern int mountScriptId;
+extern char global_npc_str[1001];
uint32 MakeDWord(uint16 word0, uint16 word1)
{
@@ -304,8 +305,8 @@ BUILDIN(requestLang)
sd->state.menu_or_input = 0;
int lng = -1;
- if (*sd->npc_str)
- lng = lang_getId(sd->npc_str);
+ if (*global_npc_str)
+ lng = lang_getId(global_npc_str);
script_pushint(st, lng);
st->state = RUN;
}
@@ -333,7 +334,7 @@ BUILDIN(requestItem)
int item = 0;
- if (!*sd->npc_str)
+ if (!*global_npc_str)
{
ShowWarning("npc string not found\n");
script_pushint(st, 0);
@@ -341,7 +342,7 @@ BUILDIN(requestItem)
return false;
}
- if (sscanf (sd->npc_str, "%5d", &item) < 1)
+ if (sscanf (global_npc_str, "%5d", &item) < 1)
{
ShowWarning("input data is not item id\n");
script_pushint(st, 0);
@@ -381,7 +382,7 @@ BUILDIN(requestItems)
sd->state.menu_or_input = 0;
st->state = RUN;
- if (!*sd->npc_str)
+ if (!*global_npc_str)
{
ShowWarning("npc string not found\n");
script_pushstr(st, aStrdup("0,0"));
@@ -389,7 +390,7 @@ BUILDIN(requestItems)
return false;
}
- script_pushstr(st, aStrdup(sd->npc_str));
+ script_pushstr(st, aStrdup(global_npc_str));
}
return true;
}
@@ -418,7 +419,7 @@ BUILDIN(requestItemIndex)
int item = -1;
- if (!*sd->npc_str)
+ if (!*global_npc_str)
{
script_pushint(st, -1);
ShowWarning("npc string not found\n");
@@ -426,7 +427,7 @@ BUILDIN(requestItemIndex)
return false;
}
- if (sscanf (sd->npc_str, "%5d", &item) < 1)
+ if (sscanf (global_npc_str, "%5d", &item) < 1)
{
script_pushint(st, -1);
ShowWarning("input data is not item id\n");
@@ -469,7 +470,7 @@ BUILDIN(requestItemsIndex)
sd->state.menu_or_input = 0;
st->state = RUN;
- if (!*sd->npc_str)
+ if (!*global_npc_str)
{
script_pushstr(st, aStrdup("-1"));
ShowWarning("npc string not found\n");
@@ -477,7 +478,7 @@ BUILDIN(requestItemsIndex)
return false;
}
- script_pushstr(st, aStrdup(sd->npc_str));
+ script_pushstr(st, aStrdup(global_npc_str));
}
return true;
}
@@ -513,7 +514,7 @@ BUILDIN(requestCraft)
sd->state.menu_or_input = 0;
st->state = RUN;
- if (!*sd->npc_str)
+ if (!*global_npc_str)
{
ShowWarning("npc string not found\n");
script->reportsrc(st);
@@ -521,7 +522,7 @@ BUILDIN(requestCraft)
return false;
}
- script_pushstr(st, aStrdup(sd->npc_str));
+ script_pushstr(st, aStrdup(global_npc_str));
}
return true;
}
@@ -2100,3 +2101,70 @@ BUILDIN(toLabel)
script_pushlabel(st, script_getnum(st, 2));
return true;
}
+
+// replace default input with bigger text buffer
+/// Get input from the player.
+/// For numeric inputs the value is capped to the range [min,max]. Returns 1 if
+/// the value was higher than 'max', -1 if lower than 'min' and 0 otherwise.
+/// For string inputs it returns 1 if the string was longer than 'max', -1 is
+/// shorter than 'min' and 0 otherwise.
+///
+/// input(<var>{,<min>{,<max>}}) -> <int>
+BUILDIN(input)
+{
+ struct script_data* data;
+ int64 uid;
+ const char* name;
+ int min;
+ int max;
+ struct map_session_data *sd = script->rid2sd(st);
+ if (sd == NULL)
+ return true;
+
+ data = script_getdata(st, 2);
+ if (!data_isreference(data))
+ {
+ ShowError("script:input: not a variable\n");
+ script->reportdata(data);
+ st->state = END;
+ return false;
+ }
+ uid = reference_getuid(data);
+ name = reference_getname(data);
+ 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;
+ st->state = RERUNLINE;
+ if (is_string_variable(name))
+ clif->scriptinputstr(sd, st->oid);
+ else
+ clif->scriptinput(sd, st->oid);
+ }
+ else
+ {
+ // take received text/value and store it in the designated variable
+ sd->state.menu_or_input = 0;
+ if (is_string_variable(name))
+ {
+ int len = (int)strlen(global_npc_str);
+ script->set_reg(st, sd, uid, name, global_npc_str, script_getref(st,2));
+ script_pushint(st, (len > max ? 1 : len < min ? -1 : 0));
+ }
+ else
+ {
+ int amount = sd->npc_amount;
+ script->set_reg(st, sd, uid, name, (const void *)h64BPTRSIZE(cap_value(amount,min,max)), script_getref(st,2));
+ script_pushint(st, (amount > max ? 1 : amount < min ? -1 : 0));
+ }
+ st->state = RUN;
+ }
+ return true;
+}