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)
|
||||
{
|
||||
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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user