summaryrefslogtreecommitdiff
path: root/src/map/script.c
diff options
context:
space:
mode:
authorshennetsind <shennetsind@54d463be-8e91-2dee-dedb-b68131a5f0ec>2012-07-23 19:26:50 +0000
committershennetsind <shennetsind@54d463be-8e91-2dee-dedb-b68131a5f0ec>2012-07-23 19:26:50 +0000
commit98e833dc83ad9f0642bdbf6b90b239704292f15f (patch)
tree73194653b1a88d67d8608d9caaac7f5119a56c6d /src/map/script.c
parent81bfbbfb9c0f5af32e55f66ccea2d444eb76cabc (diff)
downloadhercules-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.c115
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;
}