From 4ff67a9c9977e216c5b63bf5c80480dba1e2fcab Mon Sep 17 00:00:00 2001 From: shennetsind Date: Mon, 24 Jun 2013 13:13:27 -0300 Subject: Fixed Bug #7412 Special Thanks to shenhuyong http://hercules.ws/board/tracker/issue-7412-create-instancereloadscript-causes-map-server-crash/ Signed-off-by: shennetsind --- src/map/instance.c | 45 ++++++++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 19 deletions(-) (limited to 'src/map/instance.c') diff --git a/src/map/instance.c b/src/map/instance.c index 690f14cfe..6b80f5d75 100644 --- a/src/map/instance.c +++ b/src/map/instance.c @@ -46,10 +46,11 @@ bool instance_is_valid(int instance_id) { * On success return instance_id *--------------------------------------*/ int instance_create(int owner_id, const char *name, enum instance_owner_type type) { - unsigned short *iptr = NULL, *icptr = NULL; struct map_session_data *sd = NULL; + unsigned short *icptr = NULL; struct party_data *p = NULL; struct guild *g = NULL; + short *iptr = NULL; int i, j; switch ( type ) { @@ -91,7 +92,7 @@ int instance_create(int owner_id, const char *name, enum instance_owner_type typ } ARR_FIND(0, instance->instances, i, instances[i].state == INSTANCE_FREE); - + if( i == instance->instances ) RECREATE(instances, struct instance_data, ++instance->instances); @@ -109,10 +110,9 @@ int instance_create(int owner_id, const char *name, enum instance_owner_type typ instances[i].vars = idb_alloc(DB_OPT_RELEASE_DATA); safestrncpy( instances[i].name, name, sizeof(instances[i].name) ); - instances[i].map = NULL; if( type != IOT_NONE ) { - ARR_FIND(0, *icptr, j, iptr[j] == 0); + ARR_FIND(0, *icptr, j, iptr[j] == -1); if( j == *icptr ) { switch( type ) { case IOT_CHAR: @@ -162,8 +162,8 @@ int instance_add_map(const char *name, int instance_id, bool usebasename, const return -4; } - ARR_FIND( instance->start_id, iMap->map_num, i, !map[i].name[0] ); // Searching for a Free Map - + ARR_FIND( instance->start_id, iMap->map_num, i, map[i].name[0] == 0 ); // Searching for a Free Map + if( i < iMap->map_num ) im = i; // Unused map found (old instance) else { @@ -370,6 +370,7 @@ void instance_del_map(int16 m) { iMap->removemapdb(&map[m]); memset(&map[m], 0x00, sizeof(map[0])); + map[m].name[0] = 0; map[m].instance_id = -1; map[m].mob_delete_timer = INVALID_TIMER; } @@ -386,13 +387,14 @@ int instance_destroy_timer(int tid, unsigned int tick, int id, intptr_t data) { * Removes a instance, all its maps and npcs. *--------------------------------------*/ void instance_destroy(int instance_id) { - unsigned short *iptr = NULL, *icptr = NULL; struct map_session_data *sd = NULL; + unsigned short *icptr = NULL; struct party_data *p = NULL; struct guild *g = NULL; - int last = 0, type, j; + short *iptr = NULL; + int type, j, last = 0; unsigned int now = (unsigned int)time(NULL); - + if( !instance->valid(instance_id) ) return; // nothing to do @@ -402,7 +404,7 @@ void instance_destroy(int instance_id) { type = 2; else type = 3; - + clif->instance(instance_id, 5, type); // Report users this instance has been destroyed switch ( instances[instance_id].owner_type ) { @@ -430,21 +432,21 @@ void instance_destroy(int instance_id) { icptr = &g->instances; break; default: - ShowError("instance_destroy: unknown type %d for owner_id %d and name %s.\n", instances[instance_id].owner_type,instances[instance_id].owner_id,instances[instance_id].name); + ShowError("instance_destroy: unknown type %d for owner_id %d and name '%s'.\n", instances[instance_id].owner_type,instances[instance_id].owner_id,instances[instance_id].name); break; } if( iptr != NULL ) { ARR_FIND(0, *icptr, j, iptr[j] == instance_id); if( j != *icptr ) - iptr[j] = 0; + iptr[j] = -1; } while( instances[instance_id].num_map && last != instances[instance_id].map[0] ) { // Remove all maps from instance last = instances[instance_id].map[0]; instance->del_map( instances[instance_id].map[0] ); } - + if( instances[instance_id].vars ) db_destroy(instances[instance_id].vars); @@ -455,10 +457,12 @@ void instance_destroy(int instance_id) { instances[instance_id].vars = NULL; - aFree(instances[instance_id].map); + if( instances[instance_id].map ) + aFree(instances[instance_id].map); - memset( &instances[instance_id], 0x00, sizeof(struct instance_data) ); - + instances[instance_id].map = NULL; + instances[instance_id].state = INSTANCE_FREE; + instances[instance_id].num_map = 0; } /*-------------------------------------- @@ -540,12 +544,15 @@ void instance_check_kick(struct map_session_data *sd) { void do_final_instance(void) { int i; - + for(i = 0; i < instance->instances; i++) { - instance_destroy(i); + instance->destroy(i); } - aFree(instances); + if( instances ) + aFree(instances); + + instance->instances = 0; } void do_init_instance(void) { -- cgit v1.2.3-60-g2f50