- Synced the script.c file with as much data as possible from jA's:
- A lot of functions were moved around, a bunch of indentation and space-usage changes were done to make it easier to diff against their files. - Miscellanous addition and corrections were applied. - Largest one is likely a restructuring of run_script_main, which hopes to solve the memory leaks. - script engine now uses the setjmp functions to restore memory state when there's an error parsing scripts, which means that script errors won't cause the map-server to inmediately bail out anymore. git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@7926 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
parent
8da82e0a0a
commit
c9e9b3b75b
@ -4,6 +4,20 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO
|
|||||||
IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
|
IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
|
||||||
|
|
||||||
2006/07/27
|
2006/07/27
|
||||||
|
* Synced the script.c file with as much data as possible from jA's:
|
||||||
|
[Skotlex]
|
||||||
|
- A lot of functions were moved around, a bunch of indentation and
|
||||||
|
space-usage changes were done to make it easier to diff against their
|
||||||
|
files.
|
||||||
|
- Miscellanous addition and corrections were applied.
|
||||||
|
- Largest one is likely a restructuring of run_script_main, which hopes to
|
||||||
|
solve the memory leaks.
|
||||||
|
- script engine now uses the setjmp functions to restore memory state when
|
||||||
|
there's an error parsing scripts, which means that script errors won't
|
||||||
|
cause the map-server to inmediately bail out anymore.
|
||||||
|
- NOTE that the amount of changes is pretty extensive, so DON'T USE THIS on
|
||||||
|
a live server. Update only to help test and debug to see if the script
|
||||||
|
engine memory leaks are gone.
|
||||||
* Added a cleanup routine on shutdown to remove all characters from memory
|
* Added a cleanup routine on shutdown to remove all characters from memory
|
||||||
for whom the save ack has not returned from the char-server yet. [Skotlex]
|
for whom the save ack has not returned from the char-server yet. [Skotlex]
|
||||||
* Now when you set the guardian's HP, if the guardian is spawned, it's HP
|
* Now when you set the guardian's HP, if the guardian is spawned, it's HP
|
||||||
|
@ -956,10 +956,10 @@ static int itemdb_read_sqldb(void)
|
|||||||
script_free_code(id->script);
|
script_free_code(id->script);
|
||||||
if (sql_row[19] != NULL) {
|
if (sql_row[19] != NULL) {
|
||||||
if (sql_row[19][0] == '{')
|
if (sql_row[19][0] == '{')
|
||||||
id->script = parse_script((unsigned char *) sql_row[19], 0);
|
id->script = parse_script((unsigned char *) sql_row[19],item_db_name[i], 0);
|
||||||
else {
|
else {
|
||||||
sprintf(script, "{%s}", sql_row[19]);
|
sprintf(script, "{%s}", sql_row[19]);
|
||||||
id->script = parse_script((unsigned char *) script, 0);
|
id->script = parse_script((unsigned char *) script, item_db_name[i], 0);
|
||||||
}
|
}
|
||||||
} else id->script = NULL;
|
} else id->script = NULL;
|
||||||
|
|
||||||
@ -967,10 +967,10 @@ static int itemdb_read_sqldb(void)
|
|||||||
script_free_code(id->equip_script);
|
script_free_code(id->equip_script);
|
||||||
if (sql_row[20] != NULL) {
|
if (sql_row[20] != NULL) {
|
||||||
if (sql_row[20][0] == '{')
|
if (sql_row[20][0] == '{')
|
||||||
id->equip_script = parse_script((unsigned char *) sql_row[20], 0);
|
id->equip_script = parse_script((unsigned char *) sql_row[20], item_db_name[i], 0);
|
||||||
else {
|
else {
|
||||||
sprintf(script, "{%s}", sql_row[20]);
|
sprintf(script, "{%s}", sql_row[20]);
|
||||||
id->equip_script = parse_script((unsigned char *) script, 0);
|
id->equip_script = parse_script((unsigned char *) script, item_db_name[i], 0);
|
||||||
}
|
}
|
||||||
} else id->equip_script = NULL;
|
} else id->equip_script = NULL;
|
||||||
|
|
||||||
@ -978,10 +978,10 @@ static int itemdb_read_sqldb(void)
|
|||||||
script_free_code(id->unequip_script);
|
script_free_code(id->unequip_script);
|
||||||
if (sql_row[21] != NULL) {
|
if (sql_row[21] != NULL) {
|
||||||
if (sql_row[21][0] == '{')
|
if (sql_row[21][0] == '{')
|
||||||
id->unequip_script = parse_script((unsigned char *) sql_row[21], 0);
|
id->unequip_script = parse_script((unsigned char *) sql_row[21],item_db_name[i], 0);
|
||||||
else {
|
else {
|
||||||
sprintf(script, "{%s}", sql_row[21]);
|
sprintf(script, "{%s}", sql_row[21]);
|
||||||
id->unequip_script = parse_script((unsigned char *) script, 0);
|
id->unequip_script = parse_script((unsigned char *) script, item_db_name[i], 0);
|
||||||
}
|
}
|
||||||
} else id->unequip_script = NULL;
|
} else id->unequip_script = NULL;
|
||||||
|
|
||||||
@ -1148,11 +1148,11 @@ static int itemdb_readdb(void)
|
|||||||
np = strchr(np+1,'}'); //Jump close brackets until the next field is found.
|
np = strchr(np+1,'}'); //Jump close brackets until the next field is found.
|
||||||
if (!np || !np[1]) {
|
if (!np || !np[1]) {
|
||||||
//Couldn't find the end of the script field.
|
//Couldn't find the end of the script field.
|
||||||
id->script = parse_script((unsigned char *) str[19],lines);
|
id->script = parse_script((unsigned char *) str[19],filename[i],lines);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
np[1] = '\0'; //Set end of script
|
np[1] = '\0'; //Set end of script
|
||||||
id->script = parse_script((unsigned char *) str[19],lines);
|
id->script = parse_script((unsigned char *) str[19],filename[i],lines);
|
||||||
np+=2; //Skip to next field
|
np+=2; //Skip to next field
|
||||||
|
|
||||||
if(!np || (p=strchr(np,'{'))==NULL)
|
if(!np || (p=strchr(np,'{'))==NULL)
|
||||||
@ -1165,18 +1165,18 @@ static int itemdb_readdb(void)
|
|||||||
np = strchr(np+1,'}'); //Jump close brackets until the next field is found.
|
np = strchr(np+1,'}'); //Jump close brackets until the next field is found.
|
||||||
if (!np || !np[1]) {
|
if (!np || !np[1]) {
|
||||||
//Couldn't find the end of the script field.
|
//Couldn't find the end of the script field.
|
||||||
id->equip_script = parse_script((unsigned char *) str[20],lines);
|
id->equip_script = parse_script((unsigned char *) str[20],filename[i],lines);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
np[1] = '\0'; //Set end of script
|
np[1] = '\0'; //Set end of script
|
||||||
id->equip_script = parse_script((unsigned char *) str[20],lines);
|
id->equip_script = parse_script((unsigned char *) str[20],filename[i],lines);
|
||||||
np+=2; //Skip comma, to next field
|
np+=2; //Skip comma, to next field
|
||||||
|
|
||||||
if(!np || (p=strchr(np,'{'))==NULL)
|
if(!np || (p=strchr(np,'{'))==NULL)
|
||||||
continue;
|
continue;
|
||||||
//Unequip script, last column.
|
//Unequip script, last column.
|
||||||
id->unequip_script = parse_script((unsigned char *) p,lines);
|
id->unequip_script = parse_script((unsigned char *) p,filename[i],lines);
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
if (ln > 0) {
|
if (ln > 0) {
|
||||||
|
@ -1023,9 +1023,6 @@ int npc_checknear2(struct map_session_data *sd,struct block_list *bl)
|
|||||||
if(sd->state.using_fake_npc && sd->npc_id == bl->id)
|
if(sd->state.using_fake_npc && sd->npc_id == bl->id)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// if (bl->type!=BL_NPC) //Disguised character or something else...
|
|
||||||
// return 1;
|
|
||||||
|
|
||||||
if (status_get_class(bl)<0) //Class-less npc, enable click from anywhere.
|
if (status_get_class(bl)<0) //Class-less npc, enable click from anywhere.
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -1817,7 +1814,7 @@ static int npc_skip_script (char *w1,char *w2,char *w3,char *w4,char *first_line
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int npc_parse_script (char *w1,char *w2,char *w3,char *w4,char *first_line,FILE *fp,int *lines)
|
static int npc_parse_script(char *w1,char *w2,char *w3,char *w4,char *first_line,FILE *fp,int *lines,const char* file)
|
||||||
{
|
{
|
||||||
int x, y, dir = 0, m, xs = 0, ys = 0, class_ = 0; // [Valaris] thanks to fov
|
int x, y, dir = 0, m, xs = 0, ys = 0, class_ = 0; // [Valaris] thanks to fov
|
||||||
char mapname[MAP_NAME_LENGTH];
|
char mapname[MAP_NAME_LENGTH];
|
||||||
@ -1840,7 +1837,7 @@ static int npc_parse_script (char *w1,char *w2,char *w3,char *w4,char *first_lin
|
|||||||
// 引数の個数チェック
|
// 引数の個数チェック
|
||||||
if (sscanf(w1, "%15[^,],%d,%d,%d", mapname, &x, &y, &dir) != 4 ||
|
if (sscanf(w1, "%15[^,],%d,%d,%d", mapname, &x, &y, &dir) != 4 ||
|
||||||
(strcmp(w2, "script") == 0 && strchr(w4,',') == NULL)) {
|
(strcmp(w2, "script") == 0 && strchr(w4,',') == NULL)) {
|
||||||
ShowError("bad script line (in file %s): %s\n", current_file, w3);
|
ShowError("bad script line (in file %s): %s\n", file, w3);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
m = map_mapname2mapid(mapname);
|
m = map_mapname2mapid(mapname);
|
||||||
@ -1876,11 +1873,11 @@ static int npc_parse_script (char *w1,char *w2,char *w3,char *w4,char *first_lin
|
|||||||
strcat((char *) srcbuf, (const char *) line);
|
strcat((char *) srcbuf, (const char *) line);
|
||||||
}
|
}
|
||||||
if(curly_count > 0) {
|
if(curly_count > 0) {
|
||||||
ShowError("Missing right curly at file %s, line %d\n",current_file, *lines);
|
ShowError("Missing right curly at file %s, line %d\n",file, *lines);
|
||||||
script = NULL;
|
script = NULL;
|
||||||
} else {
|
} else {
|
||||||
// printf("Ok line %d\n",*lines);
|
// printf("Ok line %d\n",*lines);
|
||||||
script = parse_script((unsigned char *) srcbuf, startline);
|
script = parse_script((unsigned char *) srcbuf, file, startline);
|
||||||
}
|
}
|
||||||
if (script == NULL) {
|
if (script == NULL) {
|
||||||
// script parse error?
|
// script parse error?
|
||||||
@ -1892,11 +1889,11 @@ static int npc_parse_script (char *w1,char *w2,char *w3,char *w4,char *first_lin
|
|||||||
char srcname[128];
|
char srcname[128];
|
||||||
struct npc_data *dnd;
|
struct npc_data *dnd;
|
||||||
if (sscanf(w2, "duplicate(%[^)])", srcname) != 1) {
|
if (sscanf(w2, "duplicate(%[^)])", srcname) != 1) {
|
||||||
ShowError("bad duplicate name (in %s)! : %s", current_file, w2);
|
ShowError("bad duplicate name (in %s)! : %s", file, w2);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if ((dnd = npc_name2id(srcname)) == NULL) {
|
if ((dnd = npc_name2id(srcname)) == NULL) {
|
||||||
ShowError("bad duplicate name (in %s)! (not exist) : %s\n", current_file, srcname);
|
ShowError("bad duplicate name (in %s)! (not exist) : %s\n", file, srcname);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
script = dnd->u.scr.script;
|
script = dnd->u.scr.script;
|
||||||
@ -2019,7 +2016,7 @@ static int npc_parse_script (char *w1,char *w2,char *w3,char *w4,char *first_lin
|
|||||||
// and already overwritten if this is here is reached
|
// and already overwritten if this is here is reached
|
||||||
// I leave the check anyway but place it correctly to npc_convertlabel_db
|
// I leave the check anyway but place it correctly to npc_convertlabel_db
|
||||||
if (strlen(lname)>NAME_LENGTH-1) {
|
if (strlen(lname)>NAME_LENGTH-1) {
|
||||||
ShowError("npc_parse_script: label name longer than %d chars! '%s' (%s)\n", NAME_LENGTH-1, lname, current_file);
|
ShowError("npc_parse_script: label name longer than %d chars! '%s' (%s)\n", NAME_LENGTH-1, lname, file);
|
||||||
exit(1);
|
exit(1);
|
||||||
} else {
|
} else {
|
||||||
struct event_data *ev;
|
struct event_data *ev;
|
||||||
@ -2033,7 +2030,7 @@ static int npc_parse_script (char *w1,char *w2,char *w3,char *w4,char *first_lin
|
|||||||
ev->nd=nd;
|
ev->nd=nd;
|
||||||
ev->pos=pos;
|
ev->pos=pos;
|
||||||
if (strdb_put(ev_db,buf,ev) != NULL) //There was already another event of the same name?
|
if (strdb_put(ev_db,buf,ev) != NULL) //There was already another event of the same name?
|
||||||
ShowWarning("npc_parse_script : duplicate event %s (%s)\n",buf, current_file);
|
ShowWarning("npc_parse_script : duplicate event %s (%s)\n",buf, file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2073,7 +2070,7 @@ static int npc_parse_script (char *w1,char *w2,char *w3,char *w4,char *first_lin
|
|||||||
* function行解析
|
* function行解析
|
||||||
*------------------------------------------
|
*------------------------------------------
|
||||||
*/
|
*/
|
||||||
static int npc_parse_function (char *w1, char *w2, char *w3, char *w4, char *first_line, FILE *fp, int *lines)
|
static int npc_parse_function (char *w1, char *w2, char *w3, char *w4, char *first_line, FILE *fp, int *lines,const char* file)
|
||||||
{
|
{
|
||||||
unsigned char *srcbuf, *p;
|
unsigned char *srcbuf, *p;
|
||||||
struct script_code *script;
|
struct script_code *script;
|
||||||
@ -2112,10 +2109,10 @@ static int npc_parse_function (char *w1, char *w2, char *w3, char *w4, char *fir
|
|||||||
strcat(srcbuf,line);
|
strcat(srcbuf,line);
|
||||||
}
|
}
|
||||||
if(curly_count > 0) {
|
if(curly_count > 0) {
|
||||||
ShowError("Missing right curly at file %s, line %d\n",current_file, *lines);
|
ShowError("Missing right curly at file %s, line %d\n",file, *lines);
|
||||||
script = NULL;
|
script = NULL;
|
||||||
} else {
|
} else {
|
||||||
script = parse_script(srcbuf, startline);
|
script = parse_script(srcbuf, file, startline);
|
||||||
}
|
}
|
||||||
if (script == NULL) {
|
if (script == NULL) {
|
||||||
// script parse error?
|
// script parse error?
|
||||||
@ -2516,7 +2513,7 @@ static int npc_parse_mapflag (char *w1, char *w2, char *w3, char *w4)
|
|||||||
else if (strcmpi(w3,"nochat")==0) { // Skotlex
|
else if (strcmpi(w3,"nochat")==0) { // Skotlex
|
||||||
map[m].flag.nochat=state;
|
map[m].flag.nochat=state;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2619,12 +2616,12 @@ void npc_parsesrcfile (char *name)
|
|||||||
npc_parse_shop(w1,w2,w3,w4);
|
npc_parse_shop(w1,w2,w3,w4);
|
||||||
} else if (strcmpi(w2,"script") == 0 && count > 3) {
|
} else if (strcmpi(w2,"script") == 0 && count > 3) {
|
||||||
if (strcmpi(w1,"function") == 0) {
|
if (strcmpi(w1,"function") == 0) {
|
||||||
npc_parse_function(w1,w2,w3,w4,line+w4pos,fp,&lines);
|
npc_parse_function(w1,w2,w3,w4,line+w4pos,fp,&lines,name);
|
||||||
} else {
|
} else {
|
||||||
npc_parse_script(w1,w2,w3,w4,line+w4pos,fp,&lines);
|
npc_parse_script(w1,w2,w3,w4,line+w4pos,fp,&lines,name);
|
||||||
}
|
}
|
||||||
} else if ((i = 0, sscanf(w2,"duplicate%n",&i), (i > 0 && w2[i] == '(')) && count > 3) {
|
} else if ((i = 0, sscanf(w2,"duplicate%n",&i), (i > 0 && w2[i] == '(')) && count > 3) {
|
||||||
npc_parse_script(w1,w2,w3,w4,line+w4pos,fp,&lines);
|
npc_parse_script(w1,w2,w3,w4,line+w4pos,fp,&lines,name);
|
||||||
} else if (strcmpi(w2,"monster") == 0 && count > 3) {
|
} else if (strcmpi(w2,"monster") == 0 && count > 3) {
|
||||||
npc_parse_mob(w1,w2,w3,w4);
|
npc_parse_mob(w1,w2,w3,w4);
|
||||||
} else if (strcmpi(w2,"mapflag") == 0 && count >= 3) {
|
} else if (strcmpi(w2,"mapflag") == 0 && count >= 3) {
|
||||||
|
@ -1352,7 +1352,7 @@ int read_petdb()
|
|||||||
pet_db[j].script = NULL;
|
pet_db[j].script = NULL;
|
||||||
if((np=strchr(p,'{'))==NULL)
|
if((np=strchr(p,'{'))==NULL)
|
||||||
continue;
|
continue;
|
||||||
pet_db[j].script = parse_script((unsigned char *) np,lines);
|
pet_db[j].script = parse_script((unsigned char *) np, filename[i], lines);
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
if (j >= MAX_PET_DB)
|
if (j >= MAX_PET_DB)
|
||||||
|
6489
src/map/script.c
6489
src/map/script.c
File diff suppressed because it is too large
Load Diff
@ -45,26 +45,24 @@ struct script_code {
|
|||||||
unsigned char* script_buf;
|
unsigned char* script_buf;
|
||||||
struct linkdb_node* script_vars;
|
struct linkdb_node* script_vars;
|
||||||
};
|
};
|
||||||
struct script_stack {
|
|
||||||
int sp,sp_max,defsp;
|
|
||||||
struct script_data *stack_data;
|
|
||||||
struct linkdb_node **var_function; // ŠÖ<C5A0>”ˆË‘¶•Ï<E280A2>”
|
|
||||||
};
|
|
||||||
struct script_state {
|
struct script_state {
|
||||||
struct script_stack *stack;
|
struct script_stack {
|
||||||
|
int sp,sp_max,defsp;
|
||||||
|
struct script_data *stack_data;
|
||||||
|
struct linkdb_node **var_function; // ŠÖ<C5A0>”ˆË‘¶•Ï<E280A2>”
|
||||||
|
} *stack;
|
||||||
int start,end;
|
int start,end;
|
||||||
int pos,state;
|
int pos,state;
|
||||||
int rid,oid;
|
int rid,oid;
|
||||||
//unsigned char *script,*new_script;
|
|
||||||
int new_pos,new_defsp;
|
|
||||||
struct script_code *script, *scriptroot;
|
struct script_code *script, *scriptroot;
|
||||||
struct sleep_data {
|
struct sleep_data {
|
||||||
int tick,timer,charid;
|
int tick,timer,charid;
|
||||||
} sleep;
|
} sleep;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct script_code *parse_script(unsigned char *,int);
|
struct script_code* parse_script(unsigned char *,const char*,int);
|
||||||
void run_script(struct script_code *rootscript,int pos,int rid,int oid);
|
void run_script(struct script_code*,int,int,int);
|
||||||
|
|
||||||
int set_var(struct map_session_data *sd, char *name, void *val);
|
int set_var(struct map_session_data *sd, char *name, void *val);
|
||||||
int conv_num(struct script_state *st,struct script_data *data);
|
int conv_num(struct script_state *st,struct script_data *data);
|
||||||
@ -74,13 +72,13 @@ int run_script_timer(int tid, unsigned int tick, int id, int data);
|
|||||||
void run_script_main(struct script_state *st);
|
void run_script_main(struct script_state *st);
|
||||||
|
|
||||||
struct linkdb_node* script_erase_sleepdb(struct linkdb_node *n);
|
struct linkdb_node* script_erase_sleepdb(struct linkdb_node *n);
|
||||||
|
void script_free_stack(struct script_stack*);
|
||||||
void script_free_code(struct script_code* code);
|
void script_free_code(struct script_code* code);
|
||||||
|
|
||||||
struct dbt* script_get_label_db(void);
|
struct dbt* script_get_label_db(void);
|
||||||
struct dbt* script_get_userfunc_db(void);
|
struct dbt* script_get_userfunc_db(void);
|
||||||
|
|
||||||
int script_config_read(char *cfgName);
|
int script_config_read(char *cfgName);
|
||||||
void script_free_stack(struct script_stack*);
|
|
||||||
int do_init_script(void);
|
int do_init_script(void);
|
||||||
int do_final_script(void);
|
int do_final_script(void);
|
||||||
int add_str(const unsigned char *p);
|
int add_str(const unsigned char *p);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user