diff options
author | shennetsind <ind@henn.et> | 2014-03-18 15:00:16 -0300 |
---|---|---|
committer | shennetsind <ind@henn.et> | 2014-03-18 15:00:16 -0300 |
commit | 7b71f22331c805a406c57f5a8eff93b464b57018 (patch) | |
tree | ed65b87c241aa123d46ed32f13257d487e3dfe71 /src/map | |
parent | 4cc9d5f91cf6276e28cc02bb75fc4158d28d553b (diff) | |
parent | 21aeb5aa1d5fee9702aba476a94b800c94b29859 (diff) | |
download | hercules-7b71f22331c805a406c57f5a8eff93b464b57018.tar.gz hercules-7b71f22331c805a406c57f5a8eff93b464b57018.tar.bz2 hercules-7b71f22331c805a406c57f5a8eff93b464b57018.tar.xz hercules-7b71f22331c805a406c57f5a8eff93b464b57018.zip |
Merge branch 'master' of https://github.com/HerculesWS/Hercules
Diffstat (limited to 'src/map')
-rw-r--r-- | src/map/atcommand.c | 2 | ||||
-rw-r--r-- | src/map/map.c | 62 | ||||
-rw-r--r-- | src/map/map.h | 2 | ||||
-rw-r--r-- | src/map/script.c | 97 | ||||
-rw-r--r-- | src/map/script.h | 4 |
5 files changed, 150 insertions, 17 deletions
diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 50ec913c4..4c35999d6 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -3666,7 +3666,7 @@ ACMD(reloadscript) { mapit->free(iter); flush_fifos(); - map->reloadnpc(true); // reload config files seeking for npcs + map->reloadnpc(true, NULL, 0); // reload config files seeking for npcs script->reload(); npc->reload(); diff --git a/src/map/map.c b/src/map/map.c index 51b717a16..9e41bdca3 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -3559,8 +3559,8 @@ void map_reloadnpc_sub(char *cfgName) fclose(fp); } -void map_reloadnpc(bool clear) -{ +void map_reloadnpc(bool clear, const char * const *extra_scripts, int extra_scripts_count) { + int i; if (clear) npc->addsrcfile("clear"); // this will clear the current script list @@ -3569,6 +3569,11 @@ void map_reloadnpc(bool clear) #else map->reloadnpc_sub("npc/pre-re/scripts_main.conf"); #endif + + // Append extra scripts + for( i = 0; i < extra_scripts_count; i++ ) { + npc->addsrcfile(extra_scripts[i]); + } } int inter_config_read(char *cfgName) { @@ -5355,7 +5360,10 @@ void map_helpscreen(bool do_exit) ShowInfo(" --grf-path <file> Alternative GRF path configuration.\n"); ShowInfo(" --inter-config <file> Alternative inter-server configuration.\n"); ShowInfo(" --log-config <file> Alternative logging configuration.\n"); - ShowInfo(" --script-check <file> Tests a script for errors, without running the server.\n"); + ShowInfo(" --script-check Doesn't run the server, only tests the\n"); + ShowInfo(" scripts passed through --load-script.\n"); + ShowInfo(" --load-script <file> Loads an additional script (can be repeated).\n"); + ShowInfo(" --load-plugin <name> Loads an additional plugin (can be repeated).\n"); HPM->arg_help();/* display help for commands implemented thru HPM */ if( do_exit ) exit(EXIT_SUCCESS); @@ -5565,8 +5573,9 @@ void map_load_defaults(void) { int do_init(int argc, char *argv[]) { bool minimal = false; - char *scriptcheck = NULL; - int i; + bool scriptcheck = false; + int i, load_extras_count = 0; + char **load_extras = NULL; #ifdef GCOLLECT GC_enable_incremental(); @@ -5579,7 +5588,21 @@ int do_init(int argc, char *argv[]) HPM->load_sub = HPM_map_plugin_load_sub; HPM->symbol_defaults_sub = map_hp_symbols; HPM->grabHPDataSub = HPM_map_grabHPData; - HPM->config_read(); + for( i = 1; i < argc; i++ ) { + const char* arg = argv[i]; + if( strcmp(arg, "--load-plugin") == 0 ) { + if( map->arg_next_value(arg, i, argc, true) ) { + RECREATE(load_extras, char *, ++load_extras_count); + load_extras[load_extras_count-1] = argv[++i]; + } + } + } + HPM->config_read((const char * const *)load_extras, load_extras_count); + if (load_extras) { + aFree(load_extras); + load_extras = NULL; + load_extras_count = 0; + } HPM->event(HPET_PRE_INIT); @@ -5627,8 +5650,15 @@ int do_init(int argc, char *argv[]) } else if( strcmp(arg, "script-check") == 0 ) { map->minimal = true; runflag = CORE_ST_STOP; + scriptcheck = true; + } else if( strcmp(arg, "load-plugin") == 0 ) { if( map->arg_next_value(arg, i, argc, true) ) - scriptcheck = argv[++i]; + i++; + } else if( strcmp(arg, "load-script") == 0 ) { + if( map->arg_next_value(arg, i, argc, true) ) { + RECREATE(load_extras, char *, ++load_extras_count); + load_extras[load_extras_count-1] = argv[++i]; + } } else { ShowError("Unknown option '%s'.\n", argv[i]); exit(EXIT_FAILURE); @@ -5656,7 +5686,7 @@ int do_init(int argc, char *argv[]) map->config_read_sub(map->MAP_CONF_NAME); // loads npcs - map->reloadnpc(false); + map->reloadnpc(false, (const char * const *)load_extras, load_extras_count); chrif->checkdefaultlogin(); @@ -5766,9 +5796,19 @@ int do_init(int argc, char *argv[]) vending->init(minimal); if (scriptcheck) { - if (npc->parsesrcfile(scriptcheck, false) == 0) - exit(EXIT_SUCCESS); - exit(EXIT_FAILURE); + bool failed = load_extras_count > 0 ? false : true; + for (i = 0; i < load_extras_count; i++) { + if (npc->parsesrcfile(load_extras[i], false) != 0) + failed = true; + } + if (failed) + exit(EXIT_FAILURE); + exit(EXIT_SUCCESS); + } + if (load_extras) { + aFree(load_extras); + load_extras = NULL; + load_extras_count = 0; } if( minimal ) { diff --git a/src/map/map.h b/src/map/map.h index 270931689..c1eaeb40d 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -992,7 +992,7 @@ struct map_interface { struct mob_data * (*getmob_boss) (int16 m); struct mob_data * (*id2boss) (int id); // reload config file looking only for npcs - void (*reloadnpc) (bool clear); + void (*reloadnpc) (bool clear, const char * const *extra_scripts, int extra_scripts_count); int (*check_dir) (int s_dir,int t_dir); uint8 (*calc_dir) (struct block_list *src,int16 x,int16 y); diff --git a/src/map/script.c b/src/map/script.c index 01a7e6410..d3d98ad06 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -112,6 +112,10 @@ const char* script_op2name(int op) { RETURN_OP_NAME(C_SUB_POST); RETURN_OP_NAME(C_ADD_PRE); RETURN_OP_NAME(C_SUB_PRE); +#ifdef PCRE_SUPPORT + RETURN_OP_NAME(C_RE_EQ); + RETURN_OP_NAME(C_RE_NE); +#endif // PCRE_SUPPORT default: ShowDebug("script_op2name: unexpected op=%d\n", op); @@ -1224,6 +1228,10 @@ const char* script_parse_subexpr(const char* p,int limit) { || (op=C_XOR, opl=4, len=1,*p=='^') // ^ || (op=C_EQ, opl=6, len=2,*p=='=' && p[1]=='=') // == || (op=C_NE, opl=6, len=2,*p=='!' && p[1]=='=') // != +#ifdef PCRE_SUPPORT + || (op=C_RE_EQ, opl=6, len=2,*p=='~' && p[1]=='=') // ~= + || (op=C_RE_NE, opl=6, len=2,*p=='~' && p[1]=='!') // ~! +#endif // PCRE_SUPPORT || (op=C_R_SHIFT,opl=8, len=2,*p=='>' && p[1]=='>') // >> || (op=C_GE, opl=7, len=2,*p=='>' && p[1]=='=') // >= || (op=C_GT, opl=7, len=1,*p=='>') // > @@ -3405,6 +3413,8 @@ void op_3(struct script_state* st, int op) /// s1 GE s2 -> i /// s1 LT s2 -> i /// s1 LE s2 -> i +/// s1 RE_EQ s2 -> i +/// s1 RE_NE s2 -> i /// s1 ADD s2 -> s void op_2str(struct script_state* st, int op, const char* s1, const char* s2) { @@ -3417,6 +3427,72 @@ void op_2str(struct script_state* st, int op, const char* s1, const char* s2) case C_GE: a = (strcmp(s1,s2) >= 0); break; case C_LT: a = (strcmp(s1,s2) < 0); break; case C_LE: a = (strcmp(s1,s2) <= 0); break; +#ifdef PCRE_SUPPORT + case C_RE_EQ: + case C_RE_NE: + { + int inputlen = (int)strlen(s1); + pcre *compiled_regex; + pcre_extra *extra_regex; + const char *pcre_error, *pcre_match; + int pcre_erroroffset, offsetcount, i; + int offsets[256*3]; // (max_capturing_groups+1)*3 + + compiled_regex = libpcre->compile(s2, 0, &pcre_error, &pcre_erroroffset, NULL); + + if( compiled_regex == NULL ) { + ShowError("script:op2_str: Invalid regex '%s'.\n", s2); + script->reportsrc(st); + script_pushnil(st); + st->state = END; + return; + } + + extra_regex = libpcre->study(compiled_regex, 0, &pcre_error); + + if( pcre_error != NULL ) { + libpcre->free(compiled_regex); + ShowError("script:op2_str: Unable to optimize the regex '%s': %s\n", s2, pcre_error); + script->reportsrc(st); + script_pushnil(st); + st->state = END; + return; + } + + offsetcount = libpcre->exec(compiled_regex, extra_regex, s1, inputlen, 0, 0, offsets, 256*3); + + if( offsetcount == 0 ) { + offsetcount = 256; + } else if( offsetcount == PCRE_ERROR_NOMATCH ) { + offsetcount = 0; + } else if( offsetcount < 0 ) { + libpcre->free(compiled_regex); + if( extra_regex != NULL ) + libpcre->free(extra_regex); + ShowWarning("script:op2_str: Unable to process the regex '%s'.\n", s2); + script->reportsrc(st); + script_pushnil(st); + st->state = END; + return; + } + + if( op == C_RE_EQ ) { + for( i = 0; i < offsetcount; i++ ) { + libpcre->get_substring(s1, offsets, offsetcount, i, &pcre_match); + mapreg->setregstr(reference_uid(script->add_str("$@regexmatch$"), i), pcre_match); + libpcre->free_substring(pcre_match); + } + mapreg->setreg(script->add_str("$@regexmatchcount"), i); + a = offsetcount; + } else { // C_RE_NE + a = (offsetcount == 0); + } + libpcre->free(compiled_regex); + if( extra_regex != NULL ) + libpcre->free(extra_regex); + } + break; +#endif // PCRE_SUPPORT case C_ADD: { char* buf = (char *)aMalloc((strlen(s1)+strlen(s2)+1)*sizeof(char)); @@ -3988,6 +4064,10 @@ void run_script_main(struct script_state *st) { case C_LOR: case C_R_SHIFT: case C_L_SHIFT: +#ifdef PCRE_SUPPORT + case C_RE_EQ: + case C_RE_NE: +#endif // PCRE_SUPPORT script->op_2(st, c); break; @@ -18500,10 +18580,18 @@ BUILDIN(shopcount) { // declarations that were supposed to be exported from npc_chat.c #ifdef PCRE_SUPPORT - BUILDIN(defpattern); - BUILDIN(activatepset); - BUILDIN(deactivatepset); - BUILDIN(deletepset); +BUILDIN(defpattern); +BUILDIN(activatepset); +BUILDIN(deactivatepset); +BUILDIN(deletepset); + +BUILDIN(pcre_match) { + const char *input = script_getstr(st, 2); + const char *regex = script_getstr(st, 3); + + script->op_2str(st, C_RE_EQ, input, regex); + return true; +} #endif /** @@ -18867,6 +18955,7 @@ void script_parse_builtin(void) { BUILDIN_DEF(activatepset,"i"), // Activate a pattern set [MouseJstr] BUILDIN_DEF(deactivatepset,"i"), // Deactive a pattern set [MouseJstr] BUILDIN_DEF(deletepset,"i"), // Delete a pattern set [MouseJstr] + BUILDIN_DEF(pcre_match,"ss"), #endif BUILDIN_DEF(dispbottom,"s"), //added from jA [Lupus] BUILDIN_DEF(getusersname,""), diff --git a/src/map/script.h b/src/map/script.h index cf7f22aa9..eed0dbf1d 100644 --- a/src/map/script.h +++ b/src/map/script.h @@ -213,6 +213,10 @@ typedef enum c_op { C_SUB_POST, // a-- C_ADD_PRE, // ++a C_SUB_PRE, // --a +#ifdef PCRE_SUPPORT + C_RE_EQ, // ~= + C_RE_NE, // ~! +#endif // PCRE_SUPPORT } c_op; enum hQueueOpt { |