diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/char/char.c | 2 | ||||
-rw-r--r-- | src/common/HPM.c | 9 | ||||
-rw-r--r-- | src/common/HPM.h | 2 | ||||
-rw-r--r-- | src/login/login.c | 2 | ||||
-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 | ||||
-rw-r--r-- | src/plugins/HPMHooking/HPMHooking.Hooks.inc | 12 |
10 files changed, 166 insertions, 28 deletions
diff --git a/src/char/char.c b/src/char/char.c index a42524444..bf19a0012 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -5393,7 +5393,7 @@ int do_init(int argc, char **argv) { online_char_db = idb_alloc(DB_OPT_RELEASE_DATA); HPM->share(sql_handle,"sql_handle"); - HPM->config_read(); + HPM->config_read(NULL, 0); HPM->event(HPET_INIT); mmo_char_sql_init(); diff --git a/src/common/HPM.c b/src/common/HPM.c index a25a17782..971eb83bd 100644 --- a/src/common/HPM.c +++ b/src/common/HPM.c @@ -269,11 +269,12 @@ void hplugin_unload(struct hplugin* plugin) { } } -void hplugins_config_read(void) { +void hplugins_config_read(const char * const *extra_plugins, int extra_plugins_count) { config_t plugins_conf; config_setting_t *plist = NULL; const char *config_filename = "conf/plugins.conf"; // FIXME hardcoded name FILE *fp; + int i; // uncomment once login/char support is wrapped up // if( !HPM->DataCheck ) { @@ -294,9 +295,13 @@ void hplugins_config_read(void) { HPM->symbol_defaults_sub(); plist = libconfig->lookup(&plugins_conf, "plugins_list"); + for (i = 0; i < extra_plugins_count; i++) { + config_setting_t *entry = libconfig->setting_add(plist, NULL, CONFIG_TYPE_STRING); + config_setting_set_string(entry, extra_plugins[i]); + } if (plist != NULL) { - int length = libconfig->setting_length(plist), i; + int length = libconfig->setting_length(plist); char filename[60]; for(i = 0; i < length; i++) { if( !strcmpi(libconfig->setting_get_string_elem(plist,i),"HPMHooking") ) {//must load it first diff --git a/src/common/HPM.h b/src/common/HPM.h index 52ad24a03..b466cb4f3 100644 --- a/src/common/HPM.h +++ b/src/common/HPM.h @@ -131,7 +131,7 @@ struct HPM_interface { void *(*import_symbol) (char *name, unsigned int pID); void (*share) (void *, char *); void (*symbol_defaults) (void); - void (*config_read) (void); + void (*config_read) (const char * const *extra_plugins, int extra_plugins_count); bool (*populate) (struct hplugin *plugin,const char *filename); void (*symbol_defaults_sub) (void);//TODO drop char *(*pid2name) (unsigned int pid); diff --git a/src/login/login.c b/src/login/login.c index 252031bb8..cb30de2f3 100644 --- a/src/login/login.c +++ b/src/login/login.c @@ -1821,7 +1821,7 @@ int do_init(int argc, char** argv) } HPM->share(account_db_sql_up(accounts),"sql_handle"); - HPM->config_read(); + HPM->config_read(NULL, 0); HPM->event(HPET_INIT); // server port open & binding 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 { diff --git a/src/plugins/HPMHooking/HPMHooking.Hooks.inc b/src/plugins/HPMHooking/HPMHooking.Hooks.inc index 78987f81a..396b241b0 100644 --- a/src/plugins/HPMHooking/HPMHooking.Hooks.inc +++ b/src/plugins/HPMHooking/HPMHooking.Hooks.inc @@ -35401,13 +35401,13 @@ struct mob_data* HP_map_id2boss(int id) { } return retVal___; } -void HP_map_reloadnpc(bool clear) { +void HP_map_reloadnpc(bool clear, const char *const *extra_scripts, int extra_scripts_count) { int hIndex = 0; if( HPMHooks.count.HP_map_reloadnpc_pre ) { - void (*preHookFunc) (bool *clear); + void (*preHookFunc) (bool *clear, const char *const *extra_scripts, int *extra_scripts_count); for(hIndex = 0; hIndex < HPMHooks.count.HP_map_reloadnpc_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_map_reloadnpc_pre[hIndex].func; - preHookFunc(&clear); + preHookFunc(&clear, extra_scripts, &extra_scripts_count); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -35415,13 +35415,13 @@ void HP_map_reloadnpc(bool clear) { } } { - HPMHooks.source.map.reloadnpc(clear); + HPMHooks.source.map.reloadnpc(clear, extra_scripts, extra_scripts_count); } if( HPMHooks.count.HP_map_reloadnpc_post ) { - void (*postHookFunc) (bool *clear); + void (*postHookFunc) (bool *clear, const char *const *extra_scripts, int *extra_scripts_count); for(hIndex = 0; hIndex < HPMHooks.count.HP_map_reloadnpc_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_map_reloadnpc_post[hIndex].func; - postHookFunc(&clear); + postHookFunc(&clear, extra_scripts, &extra_scripts_count); } } return; |