Follow up to 9738c82
* Fixed some more memory leaks. * Added a few checks that were left out/removed by mistake.
This commit is contained in:
parent
9738c825cc
commit
b8f6e16f9d
@ -1278,11 +1278,14 @@ int npc_click(struct map_session_data* sd, struct npc_data* nd)
|
|||||||
*------------------------------------------*/
|
*------------------------------------------*/
|
||||||
int npc_scriptcont(struct map_session_data* sd, int id, bool closing)
|
int npc_scriptcont(struct map_session_data* sd, int id, bool closing)
|
||||||
{
|
{
|
||||||
|
struct block_list *target = map_id2bl(id);
|
||||||
|
|
||||||
nullpo_retr(1, sd);
|
nullpo_retr(1, sd);
|
||||||
|
|
||||||
if( id != sd->npc_id ){
|
if( id != sd->npc_id ){
|
||||||
TBL_NPC* nd_sd=(TBL_NPC*)map_id2bl(sd->npc_id);
|
TBL_NPC* nd_sd = (TBL_NPC*)map_id2bl(sd->npc_id);
|
||||||
TBL_NPC* nd=(TBL_NPC*)map_id2bl(id);
|
TBL_NPC* nd = BL_CAST(BL_NPC, target);
|
||||||
|
|
||||||
ShowDebug("npc_scriptcont: %s (sd->npc_id=%d) is not %s (id=%d).\n",
|
ShowDebug("npc_scriptcont: %s (sd->npc_id=%d) is not %s (id=%d).\n",
|
||||||
nd_sd?(char*)nd_sd->name:"'Unknown NPC'", (int)sd->npc_id,
|
nd_sd?(char*)nd_sd->name:"'Unknown NPC'", (int)sd->npc_id,
|
||||||
nd?(char*)nd->name:"'Unknown NPC'", (int)id);
|
nd?(char*)nd->name:"'Unknown NPC'", (int)id);
|
||||||
@ -1290,7 +1293,7 @@ int npc_scriptcont(struct map_session_data* sd, int id, bool closing)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(id != fake_nd->bl.id) { // Not item script
|
if(id != fake_nd->bl.id) { // Not item script
|
||||||
if ((npc_checknear(sd,map_id2bl(id))) == NULL){
|
if ((npc_checknear(sd, target)) == NULL) {
|
||||||
ShowWarning("npc_scriptcont: failed npc_checknear test.\n");
|
ShowWarning("npc_scriptcont: failed npc_checknear test.\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -1305,6 +1308,9 @@ int npc_scriptcont(struct map_session_data* sd, int id, bool closing)
|
|||||||
if( sd->progressbar.npc_id && DIFF_TICK(sd->progressbar.timeout,gettick()) > 0 )
|
if( sd->progressbar.npc_id && DIFF_TICK(sd->progressbar.timeout,gettick()) > 0 )
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
if (!sd->st)
|
||||||
|
return 1;
|
||||||
|
|
||||||
if( closing && sd->st && sd->st->state == CLOSE )
|
if( closing && sd->st && sd->st->state == CLOSE )
|
||||||
sd->st->state = END;
|
sd->st->state = END;
|
||||||
|
|
||||||
|
@ -3391,6 +3391,8 @@ void script_free_code(struct script_code* code)
|
|||||||
{
|
{
|
||||||
nullpo_retv(code);
|
nullpo_retv(code);
|
||||||
|
|
||||||
|
if (code->instances)
|
||||||
|
script_stop_instances(code);
|
||||||
script_free_vars(code->local.vars);
|
script_free_vars(code->local.vars);
|
||||||
if (code->local.arrays)
|
if (code->local.arrays)
|
||||||
code->local.arrays->destroy(code->local.arrays, script_free_array_db);
|
code->local.arrays->destroy(code->local.arrays, script_free_array_db);
|
||||||
@ -3424,6 +3426,14 @@ struct script_state* script_alloc_state(struct script_code* rootscript, int pos,
|
|||||||
st->oid = oid;
|
st->oid = oid;
|
||||||
st->sleep.timer = INVALID_TIMER;
|
st->sleep.timer = INVALID_TIMER;
|
||||||
st->npc_item_flag = battle_config.item_enabled_npc;
|
st->npc_item_flag = battle_config.item_enabled_npc;
|
||||||
|
|
||||||
|
if( st->script->instances != USHRT_MAX )
|
||||||
|
st->script->instances++;
|
||||||
|
else {
|
||||||
|
struct npc_data *nd = map_id2nd(oid);
|
||||||
|
|
||||||
|
ShowError("Over 65k instances of '%s' script are being run!\n",nd ? nd->name : "unknown");
|
||||||
|
}
|
||||||
|
|
||||||
if (!st->script->local.vars)
|
if (!st->script->local.vars)
|
||||||
st->script->local.vars = i64db_alloc(DB_OPT_RELEASE_DATA);
|
st->script->local.vars = i64db_alloc(DB_OPT_RELEASE_DATA);
|
||||||
@ -3442,9 +3452,20 @@ struct script_state* script_alloc_state(struct script_code* rootscript, int pos,
|
|||||||
void script_free_state(struct script_state* st)
|
void script_free_state(struct script_state* st)
|
||||||
{
|
{
|
||||||
if (idb_exists(st_db, st->id)) {
|
if (idb_exists(st_db, st->id)) {
|
||||||
|
struct map_session_data *sd = st->rid ? map_id2sd(st->rid) : NULL;
|
||||||
|
|
||||||
if (st->bk_st) // backup was not restored
|
if (st->bk_st) // backup was not restored
|
||||||
ShowDebug("script_free_state: Previous script state lost (rid=%d, oid=%d, state=%d, bk_npcid=%d).\n", st->bk_st->rid, st->bk_st->oid, st->bk_st->state, st->bk_npcid);
|
ShowDebug("script_free_state: Previous script state lost (rid=%d, oid=%d, state=%d, bk_npcid=%d).\n", st->bk_st->rid, st->bk_st->oid, st->bk_st->state, st->bk_npcid);
|
||||||
|
|
||||||
|
if (sd && sd->st == st) { // Current script is aborted.
|
||||||
|
if(sd->state.using_fake_npc) {
|
||||||
|
clif_clearunit_single(sd->npc_id, CLR_OUTSIGHT, sd->fd);
|
||||||
|
sd->state.using_fake_npc = 0;
|
||||||
|
}
|
||||||
|
sd->st = NULL;
|
||||||
|
sd->npc_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (st->sleep.timer != INVALID_TIMER)
|
if (st->sleep.timer != INVALID_TIMER)
|
||||||
delete_timer(st->sleep.timer, run_script_timer);
|
delete_timer(st->sleep.timer, run_script_timer);
|
||||||
if (st->stack) {
|
if (st->stack) {
|
||||||
@ -3456,7 +3477,7 @@ void script_free_state(struct script_state* st)
|
|||||||
ers_free(stack_ers, st->stack);
|
ers_free(stack_ers, st->stack);
|
||||||
st->stack = NULL;
|
st->stack = NULL;
|
||||||
}
|
}
|
||||||
if (st->script) {
|
if (st->script && st->script->instances != USHRT_MAX && --st->script->instances == 0) {
|
||||||
if (st->script->local.vars && !db_size(st->script->local.vars)) {
|
if (st->script->local.vars && !db_size(st->script->local.vars)) {
|
||||||
script_free_vars(st->script->local.vars);
|
script_free_vars(st->script->local.vars);
|
||||||
st->script->local.vars = NULL;
|
st->script->local.vars = NULL;
|
||||||
@ -3942,6 +3963,23 @@ void run_script(struct script_code *rootscript, int pos, int rid, int oid)
|
|||||||
run_script_main(st);
|
run_script_main(st);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void script_stop_instances(struct script_code *code) {
|
||||||
|
DBIterator *iter;
|
||||||
|
struct script_state* st;
|
||||||
|
|
||||||
|
if( !active_scripts )
|
||||||
|
return; // Don't even bother.
|
||||||
|
|
||||||
|
iter = db_iterator(st_db);
|
||||||
|
|
||||||
|
for( st = dbi_first(iter); dbi_exists(iter); st = dbi_next(iter) ) {
|
||||||
|
if( st->script == code )
|
||||||
|
script_free_state(st);
|
||||||
|
}
|
||||||
|
|
||||||
|
dbi_destroy(iter);
|
||||||
|
}
|
||||||
|
|
||||||
/*==========================================
|
/*==========================================
|
||||||
* Timer function for sleep
|
* Timer function for sleep
|
||||||
*------------------------------------------*/
|
*------------------------------------------*/
|
||||||
@ -9054,6 +9092,18 @@ BUILDIN_FUNC(end)
|
|||||||
|
|
||||||
st->state = END;
|
st->state = END;
|
||||||
|
|
||||||
|
if (st->stack->defsp >= 1 && st->stack->stack_data[st->stack->defsp-1].type == C_RETINFO) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i = 0; i < st->stack->sp; i++) {
|
||||||
|
if (st->stack->stack_data[i].type == C_RETINFO) { // Grab the first, aka the original
|
||||||
|
struct script_retinfo *ri = st->stack->stack_data[i].u.ri;
|
||||||
|
st->script = ri->script;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if( st->mes_active )
|
if( st->mes_active )
|
||||||
st->mes_active = 0;
|
st->mes_active = 0;
|
||||||
|
|
||||||
|
@ -234,6 +234,7 @@ struct script_code {
|
|||||||
int script_size;
|
int script_size;
|
||||||
unsigned char* script_buf;
|
unsigned char* script_buf;
|
||||||
struct reg_db local;
|
struct reg_db local;
|
||||||
|
unsigned short instances;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct script_stack {
|
struct script_stack {
|
||||||
@ -256,7 +257,7 @@ struct script_state {
|
|||||||
int pos;
|
int pos;
|
||||||
enum e_script_state state;
|
enum e_script_state state;
|
||||||
int rid,oid;
|
int rid,oid;
|
||||||
struct script_code *script, *scriptroot;
|
struct script_code *script;
|
||||||
struct sleep_data {
|
struct sleep_data {
|
||||||
int tick,timer,charid;
|
int tick,timer,charid;
|
||||||
} sleep;
|
} sleep;
|
||||||
@ -319,6 +320,7 @@ void pop_stack(struct script_state* st, int start, int end);
|
|||||||
int run_script_timer(int tid, unsigned int tick, int id, intptr_t data);
|
int run_script_timer(int tid, unsigned int tick, int id, intptr_t data);
|
||||||
void run_script_main(struct script_state *st);
|
void run_script_main(struct script_state *st);
|
||||||
|
|
||||||
|
void script_stop_instances(struct script_code *code);
|
||||||
struct linkdb_node* script_erase_sleepdb(struct linkdb_node *n);
|
struct linkdb_node* script_erase_sleepdb(struct linkdb_node *n);
|
||||||
void script_free_code(struct script_code* code);
|
void script_free_code(struct script_code* code);
|
||||||
void script_free_vars(struct DBMap *storage);
|
void script_free_vars(struct DBMap *storage);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user