diff options
author | shennetsind <shennetsind@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2012-07-23 19:26:50 +0000 |
---|---|---|
committer | shennetsind <shennetsind@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2012-07-23 19:26:50 +0000 |
commit | 98e833dc83ad9f0642bdbf6b90b239704292f15f (patch) | |
tree | 73194653b1a88d67d8608d9caaac7f5119a56c6d /src/map/script.c | |
parent | 81bfbbfb9c0f5af32e55f66ccea2d444eb76cabc (diff) | |
download | hercules-98e833dc83ad9f0642bdbf6b90b239704292f15f.tar.gz hercules-98e833dc83ad9f0642bdbf6b90b239704292f15f.tar.bz2 hercules-98e833dc83ad9f0642bdbf6b90b239704292f15f.tar.xz hercules-98e833dc83ad9f0642bdbf6b90b239704292f15f.zip |
Follow up r16471 improved overall feature performance by making the bind list a pointer array, this also allows the system to have a unlimited amount of atcommand bind instances. also fixed a memory leak that'd be caused when npc_do_atcmd_event fails (e.g. when target npc is manually reloaded)
git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@16485 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src/map/script.c')
-rw-r--r-- | src/map/script.c | 115 |
1 files changed, 84 insertions, 31 deletions
diff --git a/src/map/script.c b/src/map/script.c index 9521f2d54..6de233732 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -3956,14 +3956,14 @@ void script_setarray_pc(struct map_session_data* sd, const char* varname, uint8 /*========================================== * I—¹ *------------------------------------------*/ -int do_final_script() -{ +int do_final_script() { + int i; #ifdef DEBUG_HASH if (battle_config.etc_log) { FILE *fp = fopen("hash_dump.txt","wt"); if(fp) { - int i,count[SCRIPT_HASH_SIZE]; + int count[SCRIPT_HASH_SIZE]; int count2[SCRIPT_HASH_SIZE]; // number of buckets with a certain number of items int n=0; int min=INT_MAX,max=0,zero=0; @@ -4033,6 +4033,13 @@ int do_final_script() if (str_buf) aFree(str_buf); + for( i = 0; i < atcmd_binding_count; i++ ) { + aFree(atcmd_binding[i]); + } + + if( atcmd_binding_count != 0 ) + aFree(atcmd_binding); + return 0; } /*========================================== @@ -4050,12 +4057,20 @@ int do_init_script() } int script_reload() { + int i; userfunc_db->clear(userfunc_db, db_script_free_code_sub); db_clear(scriptlabel_db); // @commands (script based) // Clear bindings - memset(atcmd_binding,0,sizeof(atcmd_binding)); + for( i = 0; i < atcmd_binding_count; i++ ) { + aFree(atcmd_binding[i]); + } + + if( atcmd_binding_count != 0 ) + aFree(atcmd_binding); + + atcmd_binding_count = 0; if(sleep_db) { struct linkdb_node *n = (struct linkdb_node *)sleep_db; @@ -16355,52 +16370,90 @@ BUILDIN_FUNC(freeloop) { /** * @commands (script based) **/ -BUILDIN_FUNC(bindatcmd) -{ +BUILDIN_FUNC(bindatcmd) { const char* atcmd; const char* eventName; - int i = 0, level = 0, level2 = 0; - + int i, level = 0, level2 = 0; + bool create = false; + atcmd = script_getstr(st,2); eventName = script_getstr(st,3); + if( *atcmd == atcommand_symbol || *atcmd == charcommand_symbol ) + atcmd++; + if( script_hasdata(st,4) ) level = script_getnum(st,4); if( script_hasdata(st,5) ) level2 = script_getnum(st,5); - // check if event is already binded - ARR_FIND(0, MAX_ATCMD_BINDINGS, i, strcmp(atcmd_binding[i].command,atcmd) == 0); - if( i < MAX_ATCMD_BINDINGS ) - { - safestrncpy(atcmd_binding[i].npc_event, eventName, 50); - atcmd_binding[i].level = level; - atcmd_binding[i].level2 = level2; + if( atcmd_binding_count == 0 ) { + CREATE(atcmd_binding,struct atcmd_binding_data*,1); + + create = true; + } else { + ARR_FIND(0, atcmd_binding_count, i, strcmp(atcmd_binding[i]->command,atcmd) == 0); + if( i < atcmd_binding_count ) {/* update existent entry */ + safestrncpy(atcmd_binding[i]->npc_event, eventName, 50); + atcmd_binding[i]->level = level; + atcmd_binding[i]->level2 = level2; + } else + create = true; } - else - { // make new binding - ARR_FIND(0, MAX_ATCMD_BINDINGS, i, atcmd_binding[i].command[0] == '\0'); - if( i < MAX_ATCMD_BINDINGS ) - { - safestrncpy(atcmd_binding[i].command, atcmd, 50); - safestrncpy(atcmd_binding[i].npc_event, eventName, 50); - atcmd_binding[i].level = level; - atcmd_binding[i].level2 = level2; - } + + if( create ) { + i = atcmd_binding_count; + + if( atcmd_binding_count++ != 0 ) + RECREATE(atcmd_binding,struct atcmd_binding_data*,atcmd_binding_count); + + CREATE(atcmd_binding[i],struct atcmd_binding_data,1); + + safestrncpy(atcmd_binding[i]->command, atcmd, 50); + safestrncpy(atcmd_binding[i]->npc_event, eventName, 50); + atcmd_binding[i]->level = level; + atcmd_binding[i]->level2 = level2; } - + return 0; } -BUILDIN_FUNC(unbindatcmd) -{ +BUILDIN_FUNC(unbindatcmd) { const char* atcmd; int i = 0; atcmd = script_getstr(st, 2); - ARR_FIND(0, MAX_ATCMD_BINDINGS, i, strcmp(atcmd_binding[i].command, atcmd) == 0); - if( i < MAX_ATCMD_BINDINGS ) - memset(&atcmd_binding[i],0,sizeof(atcmd_binding[0])); + if( *atcmd == atcommand_symbol || *atcmd == charcommand_symbol ) + atcmd++; + + if( atcmd_binding_count == 0 ) { + script_pushint(st, 0); + return 0; + } + + ARR_FIND(0, atcmd_binding_count, i, strcmp(atcmd_binding[i]->command, atcmd) == 0); + if( i < atcmd_binding_count ) { + int cursor = 0; + aFree(atcmd_binding[i]); + atcmd_binding[i] = NULL; + /* compact the list now that we freed a slot somewhere */ + for( i = 0, cursor = 0; i < atcmd_binding_count; i++ ) { + if( atcmd_binding[i] == NULL ) + continue; + + if( cursor != i ) { + memmove(&atcmd_binding[cursor], &atcmd_binding[i], sizeof(struct atcmd_binding_data*)); + } + + cursor++; + } + if( (atcmd_binding_count = cursor) == 0 ) + aFree(atcmd_binding); + + script_pushint(st, 1); + } else + script_pushint(st, 0);/* not found */ + return 0; } |