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:
aleos89 2015-08-25 13:23:23 -04:00
parent 9738c825cc
commit b8f6e16f9d
3 changed files with 63 additions and 5 deletions

View File

@ -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)
{
struct block_list *target = map_id2bl(id);
nullpo_retr(1, sd);
if( id != 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_sd = (TBL_NPC*)map_id2bl(sd->npc_id);
TBL_NPC* nd = BL_CAST(BL_NPC, target);
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?(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 ((npc_checknear(sd,map_id2bl(id))) == NULL){
if ((npc_checknear(sd, target)) == NULL) {
ShowWarning("npc_scriptcont: failed npc_checknear test.\n");
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 )
return 1;
if (!sd->st)
return 1;
if( closing && sd->st && sd->st->state == CLOSE )
sd->st->state = END;

View File

@ -3391,6 +3391,8 @@ void script_free_code(struct script_code* code)
{
nullpo_retv(code);
if (code->instances)
script_stop_instances(code);
script_free_vars(code->local.vars);
if (code->local.arrays)
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->sleep.timer = INVALID_TIMER;
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)
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)
{
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
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)
delete_timer(st->sleep.timer, run_script_timer);
if (st->stack) {
@ -3456,7 +3477,7 @@ void script_free_state(struct script_state* st)
ers_free(stack_ers, st->stack);
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)) {
script_free_vars(st->script->local.vars);
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);
}
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
*------------------------------------------*/
@ -9054,6 +9092,18 @@ BUILDIN_FUNC(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 )
st->mes_active = 0;

View File

@ -234,6 +234,7 @@ struct script_code {
int script_size;
unsigned char* script_buf;
struct reg_db local;
unsigned short instances;
};
struct script_stack {
@ -256,7 +257,7 @@ struct script_state {
int pos;
enum e_script_state state;
int rid,oid;
struct script_code *script, *scriptroot;
struct script_code *script;
struct sleep_data {
int tick,timer,charid;
} 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);
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);
void script_free_code(struct script_code* code);
void script_free_vars(struct DBMap *storage);