diff options
author | Happy <markaizer@gmail.com> | 2014-08-21 04:50:46 +0800 |
---|---|---|
committer | Happy <markaizer@gmail.com> | 2014-08-21 04:50:46 +0800 |
commit | f52e1007fe08c67003c0bc4c78231904dd3fd5cc (patch) | |
tree | 99907d827264e501774e58ab4630e41fa7103c02 /src/map/npc_chat.c | |
parent | 2410110dece79b4598c12f1c953219f1d0d1904a (diff) | |
parent | 769b1d05aa5cfa8cddfe7d21b35d5c5e4da3bbd6 (diff) | |
download | hercules-f52e1007fe08c67003c0bc4c78231904dd3fd5cc.tar.gz hercules-f52e1007fe08c67003c0bc4c78231904dd3fd5cc.tar.bz2 hercules-f52e1007fe08c67003c0bc4c78231904dd3fd5cc.tar.xz hercules-f52e1007fe08c67003c0bc4c78231904dd3fd5cc.zip |
Merge pull request #1 from HerculesWS/master
Update from original
Diffstat (limited to 'src/map/npc_chat.c')
-rw-r--r-- | src/map/npc_chat.c | 238 |
1 files changed, 117 insertions, 121 deletions
diff --git a/src/map/npc_chat.c b/src/map/npc_chat.c index c7faa2df6..8bc246819 100644 --- a/src/map/npc_chat.c +++ b/src/map/npc_chat.c @@ -2,25 +2,33 @@ // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#ifdef PCRE_SUPPORT +#define HERCULES_CORE -#include "../common/timer.h" -#include "../common/malloc.h" -#include "../common/nullpo.h" -#include "../common/showmsg.h" -#include "../common/strlib.h" +#ifdef PCRE_SUPPORT -#include "mob.h" // struct mob_data #include "npc.h" // struct npc_data -#include "pc.h" // struct map_session_data -#include "script.h" // set_var() - -#include "../../3rdparty/pcre/include/pcre.h" +#include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <stdarg.h> + +#include "../../3rdparty/pcre/include/pcre.h" + +#include "mob.h" // struct mob_data +#include "pc.h" // struct map_session_data +#include "script.h" // set_var() +#include "../common/malloc.h" +#include "../common/nullpo.h" +#include "../common/showmsg.h" +#include "../common/strlib.h" +#include "../common/timer.h" + +/** + * interface sources + **/ +struct npc_chat_interface npc_chat_s; +struct pcre_interface libpcre_s; /** @@ -41,7 +49,7 @@ * * defpattern 1, "[^:]+: (.*) loves (.*)", "label"; * - * this defines a new pattern in set 1 using perl syntax + * this defines a new pattern in set 1 using perl syntax * (http://www.troubleshooters.com/codecorn/littperl/perlreg.htm) * and tells it to jump to the supplied label when the pattern * is matched. @@ -51,7 +59,7 @@ * before the script gets executed. * * activatepset 1; - * + * * This activates a set of patterns.. You can have many pattern * sets defined and many active all at once. This feature allows * you to set up "conversations" and ever changing expectations of @@ -70,47 +78,16 @@ * deletes a pset */ -/* Structure containing all info associated with a single pattern block */ -struct pcrematch_entry { - struct pcrematch_entry* next; - char* pattern; - pcre* pcre_; - pcre_extra* pcre_extra_; - char* label; -}; - -/* A set of patterns that can be activated and deactived with a single command */ -struct pcrematch_set { - struct pcrematch_set* prev; - struct pcrematch_set* next; - struct pcrematch_entry* head; - int setid; -}; - -/* - * Entire data structure hung off a NPC - * - * The reason I have done it this way (a void * in npc_data and then - * this) was to reduce the number of patches that needed to be applied - * to a ragnarok distribution to bring this code online. I - * also wanted people to be able to grab this one file to get updates - * without having to do a large number of changes. - */ -struct npc_parse { - struct pcrematch_set* active; - struct pcrematch_set* inactive; -}; - /** - * delete everythign associated with a entry + * delete everything associated with a entry * * This does NOT do the list management */ void finalize_pcrematch_entry(struct pcrematch_entry* e) { - pcre_free(e->pcre_); - pcre_free(e->pcre_extra_); + libpcre->free(e->pcre_); + libpcre->free(e->pcre_extra_); aFree(e->pattern); aFree(e->label); } @@ -118,12 +95,11 @@ void finalize_pcrematch_entry(struct pcrematch_entry* e) /** * Lookup (and possibly create) a new set of patterns by the set id */ -static struct pcrematch_set* lookup_pcreset(struct npc_data* nd, int setid) -{ +struct pcrematch_set* lookup_pcreset(struct npc_data* nd, int setid) { struct pcrematch_set *pcreset; - struct npc_parse *npcParse = (struct npc_parse *) nd->chatdb; - if (npcParse == NULL) - nd->chatdb = npcParse = (struct npc_parse *) aCalloc(sizeof(struct npc_parse), 1); + struct npc_parse *npcParse = nd->chatdb; + if (npcParse == NULL) + nd->chatdb = npcParse = (struct npc_parse *)aCalloc(sizeof(struct npc_parse), 1); pcreset = npcParse->active; @@ -132,7 +108,7 @@ static struct pcrematch_set* lookup_pcreset(struct npc_data* nd, int setid) break; pcreset = pcreset->next; } - if (pcreset == NULL) + if (pcreset == NULL) pcreset = npcParse->inactive; while (pcreset != NULL) { @@ -142,7 +118,7 @@ static struct pcrematch_set* lookup_pcreset(struct npc_data* nd, int setid) } if (pcreset == NULL) { - pcreset = (struct pcrematch_set *) aCalloc(sizeof(struct pcrematch_set), 1); + pcreset = (struct pcrematch_set *)aCalloc(sizeof(struct pcrematch_set), 1); pcreset->next = npcParse->inactive; if (pcreset->next != NULL) pcreset->next->prev = pcreset; @@ -159,11 +135,11 @@ static struct pcrematch_set* lookup_pcreset(struct npc_data* nd, int setid) * * if the setid does not exist, this will silently return */ -static void activate_pcreset(struct npc_data* nd, int setid) +void activate_pcreset(struct npc_data* nd, int setid) { struct pcrematch_set *pcreset; - struct npc_parse *npcParse = (struct npc_parse *) nd->chatdb; - if (npcParse == NULL) + struct npc_parse *npcParse = nd->chatdb; + if (npcParse == NULL) return; // Nothing to activate... pcreset = npcParse->inactive; while (pcreset != NULL) { @@ -177,7 +153,7 @@ static void activate_pcreset(struct npc_data* nd, int setid) pcreset->next->prev = pcreset->prev; if (pcreset->prev != NULL) pcreset->prev->next = pcreset->next; - else + else npcParse->inactive = pcreset->next; pcreset->prev = NULL; @@ -192,15 +168,15 @@ static void activate_pcreset(struct npc_data* nd, int setid) * * if the setid does not exist, this will silently return */ -static void deactivate_pcreset(struct npc_data* nd, int setid) +void deactivate_pcreset(struct npc_data* nd, int setid) { struct pcrematch_set *pcreset; - struct npc_parse *npcParse = (struct npc_parse *) nd->chatdb; - if (npcParse == NULL) + struct npc_parse *npcParse = nd->chatdb; + if (npcParse == NULL) return; // Nothing to deactivate... if (setid == -1) { while(npcParse->active != NULL) - deactivate_pcreset(nd, npcParse->active->setid); + npc_chat->deactivate_pcreset(nd, npcParse->active->setid); return; } pcreset = npcParse->active; @@ -215,7 +191,7 @@ static void deactivate_pcreset(struct npc_data* nd, int setid) pcreset->next->prev = pcreset->prev; if (pcreset->prev != NULL) pcreset->prev->next = pcreset->next; - else + else npcParse->active = pcreset->next; pcreset->prev = NULL; @@ -228,12 +204,12 @@ static void deactivate_pcreset(struct npc_data* nd, int setid) /** * delete a set of patterns. */ -static void delete_pcreset(struct npc_data* nd, int setid) +void delete_pcreset(struct npc_data* nd, int setid) { int active = 1; struct pcrematch_set *pcreset; - struct npc_parse *npcParse = (struct npc_parse *) nd->chatdb; - if (npcParse == NULL) + struct npc_parse *npcParse = nd->chatdb; + if (npcParse == NULL) return; // Nothing to deactivate... pcreset = npcParse->active; while (pcreset != NULL) { @@ -250,7 +226,7 @@ static void delete_pcreset(struct npc_data* nd, int setid) pcreset = pcreset->next; } } - if (pcreset == NULL) + if (pcreset == NULL) return; if (pcreset->next != NULL) @@ -268,8 +244,8 @@ static void delete_pcreset(struct npc_data* nd, int setid) while (pcreset->head) { struct pcrematch_entry* n = pcreset->head->next; - finalize_pcrematch_entry(pcreset->head); - aFree(pcreset->head); // Cleanin' the last ones.. [Lance] + npc_chat->finalize_pcrematch_entry(pcreset->head); + aFree(pcreset->head); // Cleaning the last ones.. [Lance] pcreset->head = n; } @@ -277,9 +253,9 @@ static void delete_pcreset(struct npc_data* nd, int setid) } /** - * create a new pattern entry + * create a new pattern entry */ -static struct pcrematch_entry* create_pcrematch_entry(struct pcrematch_set* set) +struct pcrematch_entry* create_pcrematch_entry(struct pcrematch_set* set) { struct pcrematch_entry * e = (struct pcrematch_entry *) aCalloc(sizeof(struct pcrematch_entry), 1); struct pcrematch_entry * last = set->head; @@ -313,31 +289,31 @@ void npc_chat_def_pattern(struct npc_data* nd, int setid, const char* pattern, c const char *err; int erroff; - struct pcrematch_set * s = lookup_pcreset(nd, setid); - struct pcrematch_entry *e = create_pcrematch_entry(s); + struct pcrematch_set * s = npc_chat->lookup_pcreset(nd, setid); + struct pcrematch_entry *e = npc_chat->create_pcrematch_entry(s); e->pattern = aStrdup(pattern); e->label = aStrdup(label); - e->pcre_ = pcre_compile(pattern, PCRE_CASELESS, &err, &erroff, NULL); - e->pcre_extra_ = pcre_study(e->pcre_, 0, &err); + e->pcre_ = libpcre->compile(pattern, PCRE_CASELESS, &err, &erroff, NULL); + e->pcre_extra_ = libpcre->study(e->pcre_, 0, &err); } /** * Delete everything associated with a NPC concerning the pattern - * matching code + * matching code * - * this could be more efficent but.. how often do you do this? + * this could be more efficient but.. how often do you do this? */ void npc_chat_finalize(struct npc_data* nd) { - struct npc_parse *npcParse = (struct npc_parse *) nd->chatdb; + struct npc_parse *npcParse = nd->chatdb; if (npcParse == NULL) return; while(npcParse->active) - delete_pcreset(nd, npcParse->active->setid); + npc_chat->delete_pcreset(nd, npcParse->active->setid); while(npcParse->inactive) - delete_pcreset(nd, npcParse->inactive->setid); + npc_chat->delete_pcreset(nd, npcParse->inactive->setid); // Additional cleaning up [Lance] aFree(npcParse); @@ -348,8 +324,8 @@ void npc_chat_finalize(struct npc_data* nd) */ int npc_chat_sub(struct block_list* bl, va_list ap) { - struct npc_data* nd = (struct npc_data *) bl; - struct npc_parse* npcParse = (struct npc_parse *) nd->chatdb; + struct npc_data *nd = (struct npc_data *) bl; + struct npc_parse *npcParse = nd->chatdb; char* msg; int len, i; struct map_session_data* sd; @@ -368,13 +344,13 @@ int npc_chat_sub(struct block_list* bl, va_list ap) // iterate across all active sets for (pcreset = npcParse->active; pcreset != NULL; pcreset = pcreset->next) { - // interate across all patterns in that set + // n across all patterns in that set for (e = pcreset->head; e != NULL; e = e->next) { - int offsets[2*10 + 10]; // 1/3 reserved for temp space requred by pcre_exec + int offsets[2*10 + 10]; // 1/3 reserved for temp space required by pcre_exec // perform pattern match - int r = pcre_exec(e->pcre_, e->pcre_extra_, msg, len, 0, 0, offsets, ARRAYLENGTH(offsets)); + int r = libpcre->exec(e->pcre_, e->pcre_extra_, msg, len, 0, 0, offsets, ARRAYLENGTH(offsets)); if (r > 0) { // save out the matched strings @@ -382,20 +358,20 @@ int npc_chat_sub(struct block_list* bl, va_list ap) { char var[6], val[255]; snprintf(var, sizeof(var), "$@p%i$", i); - pcre_copy_substring(msg, offsets, r, i, val, sizeof(val)); - set_var(sd, var, val); + libpcre->copy_substring(msg, offsets, r, i, val, sizeof(val)); + script->set_var(sd, var, val); } // find the target label.. this sucks.. lst = nd->u.scr.label_list; ARR_FIND(0, nd->u.scr.label_list_num, i, strncmp(lst[i].name, e->label, sizeof(lst[i].name)) == 0); if (i == nd->u.scr.label_list_num) { - ShowWarning("Unable to find label: %s\n", e->label); + ShowWarning("npc_chat_sub: Unable to find label: %s\n", e->label); return 0; } // run the npc script - run_script(nd->u.scr.script,lst[i].pos,sd->bl.id,nd->bl.id); + script->run(nd->u.scr.script,lst[i].pos,sd->bl.id,nd->bl.id); return 0; } } @@ -404,48 +380,68 @@ int npc_chat_sub(struct block_list* bl, va_list ap) return 0; } -// Various script builtins used to support these functions +// Various script built-ins used to support these functions +BUILDIN(defpattern) { + int setid = script_getnum(st,2); + const char* pattern = script_getstr(st,3); + const char* label = script_getstr(st,4); + struct npc_data* nd = (struct npc_data *)map->id2bl(st->oid); + + npc_chat->def_pattern(nd, setid, pattern, label); -int buildin_defpattern(struct script_state* st) -{ - int setid = script->conv_num(st,& (st->stack->stack_data[st->start+2])); - const char* pattern = script->conv_str(st,& (st->stack->stack_data[st->start+3])); - const char* label = script->conv_str(st,& (st->stack->stack_data[st->start+4])); - struct npc_data* nd = (struct npc_data *)iMap->id2bl(st->oid); - - npc_chat_def_pattern(nd, setid, pattern, label); - - return 1; + return true; } -int buildin_activatepset(struct script_state* st) -{ - int setid = script->conv_num(st,& (st->stack->stack_data[st->start+2])); - struct npc_data* nd = (struct npc_data *)iMap->id2bl(st->oid); - - activate_pcreset(nd, setid); +BUILDIN(activatepset) { + int setid = script_getnum(st,2); + struct npc_data* nd = (struct npc_data *)map->id2bl(st->oid); - return 1; + npc_chat->activate_pcreset(nd, setid); + + return true; } -int buildin_deactivatepset(struct script_state* st) -{ - int setid = script->conv_num(st,& (st->stack->stack_data[st->start+2])); - struct npc_data* nd = (struct npc_data *)iMap->id2bl(st->oid); +BUILDIN(deactivatepset) { + int setid = script_getnum(st,2); + struct npc_data* nd = (struct npc_data *)map->id2bl(st->oid); - deactivate_pcreset(nd, setid); + npc_chat->deactivate_pcreset(nd, setid); - return 1; + return true; } -int buildin_deletepset(struct script_state* st) -{ - int setid = script->conv_num(st,& (st->stack->stack_data[st->start+2])); - struct npc_data* nd = (struct npc_data *)iMap->id2bl(st->oid); - - delete_pcreset(nd, setid); +BUILDIN(deletepset) { + int setid = script_getnum(st,2); + struct npc_data* nd = (struct npc_data *)map->id2bl(st->oid); - return 1; + npc_chat->delete_pcreset(nd, setid); + + return true; +} + +void npc_chat_defaults(void) { + npc_chat = &npc_chat_s; + + npc_chat->sub = npc_chat_sub; + npc_chat->finalize = npc_chat_finalize; + npc_chat->def_pattern = npc_chat_def_pattern; + npc_chat->create_pcrematch_entry = create_pcrematch_entry; + npc_chat->delete_pcreset = delete_pcreset; + npc_chat->deactivate_pcreset = deactivate_pcreset; + npc_chat->activate_pcreset = activate_pcreset; + npc_chat->lookup_pcreset = lookup_pcreset; + npc_chat->finalize_pcrematch_entry = finalize_pcrematch_entry; + + libpcre = &libpcre_s; + + libpcre->compile = pcre_compile; + libpcre->study = pcre_study; + libpcre->exec = pcre_exec; + libpcre->free = pcre_free; + libpcre->copy_substring = pcre_copy_substring; + libpcre->free_substring = pcre_free_substring; + libpcre->copy_named_substring = pcre_copy_named_substring; + libpcre->get_substring = pcre_get_substring; } #endif //PCRE_SUPPORT |