diff options
author | Haru <haru@dotalux.com> | 2014-10-22 20:54:34 +0200 |
---|---|---|
committer | Haru <haru@dotalux.com> | 2014-10-23 18:16:09 +0200 |
commit | 5928d78ba18fafbf4c8b6f4b8d7600df7ccf1d02 (patch) | |
tree | fd96f1710211aae3c5eda01f8ad7d386276eb59f | |
parent | 68d68355ef403dca50e80d8e23bca9dafc745140 (diff) | |
download | hercules-5928d78ba18fafbf4c8b6f4b8d7600df7ccf1d02.tar.gz hercules-5928d78ba18fafbf4c8b6f4b8d7600df7ccf1d02.tar.bz2 hercules-5928d78ba18fafbf4c8b6f4b8d7600df7ccf1d02.tar.xz hercules-5928d78ba18fafbf4c8b6f4b8d7600df7ccf1d02.zip |
Improved bindatcmd handling of spaces in parameters.
- Parameters passed to bindatcmd-invoked labels are now properly
space-delimited.
- This is in order to support strings containing multiple spaces or
containing a trailing space. Previously it was impossible to create a
bindatcmd command that could accept a player name such as
'This name has two spaces' or 'Sir Trailingspace '.
- Added documentation and usage examples, especially wrt space handling.
See doc/script_commands.txt for details.
- NOTE: Your custom atcommand labels may need edits, as we're no longer
trimming multiple sequantial spaces or trailing spaces, in order to
gain more flexibility. It is your care to do that.
- Special thanks to Dastgir, jaBote.
Signed-off-by: Haru <haru@dotalux.com>
-rw-r--r-- | doc/script_commands.txt | 58 | ||||
-rw-r--r-- | src/map/npc.c | 42 |
2 files changed, 75 insertions, 25 deletions
diff --git a/doc/script_commands.txt b/doc/script_commands.txt index 0af9644dd..d0acbf1c8 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -7250,12 +7250,16 @@ when not provided, "group level char" defaults to 99. (1 = log, 0 = no log), default is to not log. The following variables are set upon execution: - .@atcmd_command$ = The name of the @command used. - .@atcmd_parameters$[] = Array containing the given parameters, - starting from an index of 0. - .@atcmd_numparameters = The number of parameters defined. + .@atcmd_command$ = The name of the @command used. + .@atcmd_parameters$[] = Array containing the given parameters, + starting from an index of 0. + .@atcmd_numparameters = The number of parameters defined. -Example: +Parameters are split on spaces. Multiple spaces aren't grouped together, and +will create multiple (empty) arguments. +Any leading spaces before the first parameter will be omitted. + +Usage example: When a user types the command "@test", an angel effect will be shown. @@ -7268,6 +7272,50 @@ OnAtcommand: end; } +Parameter splitting example: + @mycommand + .@atcmd_numparameters -> 0 + .@atcmd_parameters$ -> { } + @mycommand<space><space> + .@atcmd_numparameters -> 0 + .@atcmd_parameters$ -> { } + @mycommand<space>foo + .@atcmd_numparameters -> 1 + .@atcmd_parameters$ -> { "foo" } + @mycommand<space><space>foo + .@atcmd_numparameters -> 1 + .@atcmd_parameters$ -> { "foo" } + @mycommand<space>foo<space>bar + .@atcmd_numparameters -> 2 + .@atcmd_parameters$ -> { "foo", "bar" } + @mycommand<space>foo<space><space>bar + .@atcmd_numparameters -> 3 + .@atcmd_parameters$ -> { "foo", "", "bar" } + @mycommand<space>foo<space> + .@atcmd_numparameters -> 2 + .@atcmd_parameters$ -> { "foo", "" } + @mycommand<space>foo<space><space> + .@atcmd_numparameters -> 3 + .@atcmd_parameters$ -> { "foo", "", "" } + +The called event label needs to take care of joining arguments together, in +case it expects spaces. For example: + +- script atcmd_example -1,{ +OnInit: + bindatcmd "test",strnpcinfo(3)+"::OnAtcommand"; + end; +OnAtcommand: + // This command expects a character name (that may contain spaces) as + // the only parameter. + .@name$ = ""; + for (.@i = 0; .@i < .@atcmd_numparameters; ++.@i) { + .@name$ += (.@i > 0 ? " " : "") + .@atcmd_parameters$[.@i]; + } + dispbottom("The specified name is: '" + .@name$ + "'"); + end; +} + --------------------------------------- *unbindatcmd "command"; diff --git a/src/map/npc.c b/src/map/npc.c index 92b6ff117..7dc0bda60 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -3324,8 +3324,8 @@ int npc_do_atcmd_event(struct map_session_data* sd, const char* command, const c struct event_data* ev = (struct event_data*)strdb_get(npc->ev_db, eventname); struct npc_data *nd; struct script_state *st; - int i = 0, j = 0, k = 0; - char *temp; + int i = 0, nargs = 0; + size_t len; nullpo_ret(sd); @@ -3353,27 +3353,29 @@ int npc_do_atcmd_event(struct map_session_data* sd, const char* command, const c st = script->alloc_state(ev->nd->u.scr.script, ev->pos, sd->bl.id, ev->nd->bl.id); script->setd_sub(st, NULL, ".@atcmd_command$", 0, (void *)command, NULL); - // split atcmd parameters based on spaces - temp = (char*)aMalloc(strlen(message) + 1); - - for( i = 0; i < ( strlen( message ) + 1 ) && k < 127; i ++ ) { - if( message[i] == ' ' || message[i] == '\0' ) { - if( message[ ( i - 1 ) ] == ' ' ) { - continue; // To prevent "@atcmd [space][space]" and .@atcmd_numparameters return 1 without any parameter. - } - temp[k] = '\0'; - k = 0; - if( temp[0] != '\0' ) { - script->setd_sub( st, NULL, ".@atcmd_parameters$", j++, (void *)temp, NULL ); + len = strlen(message); + if (len) { + char *temp, *p; + p = temp = aStrdup(message); + // Sanity check - Skip leading spaces (shouldn't happen) + while (i <= len && temp[i] == ' ') { + p++; + i++; + } + // split atcmd parameters based on spaces + while (i <= len) { + if (temp[i] != ' ' && temp[i] != '\0') { + i++; + continue; } - } else { - temp[k] = message[i]; - k++; + temp[i] = '\0'; + script->setd_sub(st, NULL, ".@atcmd_parameters$", nargs++, (void *)p, NULL); + i++; + p = temp + i; } + aFree(temp); } - - script->setd_sub(st, NULL, ".@atcmd_numparameters", 0, (void *)h64BPTRSIZE(j), NULL); - aFree(temp); + script->setd_sub(st, NULL, ".@atcmd_numparameters", 0, (void *)h64BPTRSIZE(nargs), NULL); script->run_main(st); return 0; |