diff options
34 files changed, 327 insertions, 135 deletions
diff --git a/Changelog-SVN.txt b/Changelog-SVN.txt index 7d4f3d92a..047c96b99 100644 --- a/Changelog-SVN.txt +++ b/Changelog-SVN.txt @@ -1,6 +1,8 @@ Date Added 03/23 + * Fixed alot of memory leaks [celest] + * Added stray memory cleaning routine to db.c [celest] * Fixed some compile errors, sorry xP [celest] * Corrected potion creation success chances, thanks to Avaj and DracoRPG * Removed some unused potion creation code, thanks to DracoRPG diff --git a/src/char/char.c b/src/char/char.c index 1a2b61389..78f4bd3ae 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -22,6 +22,7 @@ #include "socket.h" #include "timer.h" #include "mmo.h" +#include "db.h" #include "version.h" #include "lock.h" #include "char.h" @@ -630,11 +631,6 @@ int mmo_char_init(void) { printf("out of memory: mmo_char_init (calloc of char_dat).\n"); exit(1); } - online_chars = (struct online_chars*)aCalloc(sizeof(struct online_chars) * 256, 1); - if (!online_chars) { - printf("out of memory: mmo_char_init (calloc of online_chars).\n"); - exit(1); - } for(i = 0; i < char_max; i++) { online_chars[i].char_id = -1; @@ -3456,8 +3452,9 @@ void do_final(void) { delete_session(login_fd); delete_session(char_fd); - for(i = 0; i < fd_max; i++) - if(session[i] != NULL) aFree(session[i]); + inter_final(); + exit_dbn(); + timer_final(); char_log("----End of char-server (normal end with closing of all files)." RETCODE); } @@ -3512,7 +3509,6 @@ int do_init(int argc, char **argv) { online_chars[i].server = -1; } - mmo_char_init(); update_online = time(NULL); diff --git a/src/char/int_guild.c b/src/char/int_guild.c index 267b66f0f..78e6b476f 100644 --- a/src/char/int_guild.c +++ b/src/char/int_guild.c @@ -488,10 +488,28 @@ int inter_guild_init() { return 0; } +int castle_db_final (void *k, void *data, va_list ap) +{ + struct guild_castle *gc = data; + if (gc) aFree(gc); + return 0; +} +int guild_db_final (void *k, void *data, va_list ap) +{ + struct guild *g = data; + if (g) aFree(g); + return 0; +} +void inter_guild_final() { + numdb_final(castle_db, castle_db_final); + numdb_final(guild_db, guild_db_final); + return; +} + struct guild *inter_guild_search(int guild_id) { struct guild *g; - g= (struct guild *) numdb_search(guild_db, guild_id); + g = (struct guild *) numdb_search(guild_db, guild_id); return g; } diff --git a/src/char/int_guild.h b/src/char/int_guild.h index 555f5e123..3eeb1b3db 100644 --- a/src/char/int_guild.h +++ b/src/char/int_guild.h @@ -3,6 +3,7 @@ #define _INT_GUILD_H_ int inter_guild_init(); +void inter_guild_final(); int inter_guild_save(); int inter_guild_parse_frommap(int fd); struct guild *inter_guild_search(int guild_id); diff --git a/src/char/int_party.c b/src/char/int_party.c index 3298587f1..5ee48fc70 100644 --- a/src/char/int_party.c +++ b/src/char/int_party.c @@ -117,6 +117,17 @@ int inter_party_init() { return 0; } +int party_db_final (void *k, void *data, va_list ap) { + struct party *p = data; + if (p) aFree(p); + return 0; +} +void inter_party_final() +{ + numdb_final(party_db, party_db_final); + return; +} + // パ?ティ?デ?タのセ?ブ用 int inter_party_save_sub(void *key, void *data, va_list ap) { char line[8192]; diff --git a/src/char/int_party.h b/src/char/int_party.h index b265b4c2e..e3180f3b7 100644 --- a/src/char/int_party.h +++ b/src/char/int_party.h @@ -3,6 +3,7 @@ #define _INT_PARTY_H_ int inter_party_init(); +void inter_party_final(); int inter_party_save(); int inter_party_parse_frommap(int fd); diff --git a/src/char/int_pet.c b/src/char/int_pet.c index 8682860c0..342854f8b 100644 --- a/src/char/int_pet.c +++ b/src/char/int_pet.c @@ -109,6 +109,17 @@ int inter_pet_init() return 0; } +int pet_db_final (void *k, void *data, va_list ap) { + struct s_pet *p = data; + if (p) aFree(p); + return 0; +} +void inter_pet_final() +{ + numdb_final(pet_db, pet_db_final); + return; +} + int inter_pet_save_sub(void *key,void *data,va_list ap) { char line[8192]; diff --git a/src/char/int_pet.h b/src/char/int_pet.h index 993f913ab..3a48ada3b 100644 --- a/src/char/int_pet.h +++ b/src/char/int_pet.h @@ -3,6 +3,7 @@ #define _INT_PET_H_ int inter_pet_init(); +void inter_pet_final(); int inter_pet_save(); int inter_pet_delete(int pet_id); diff --git a/src/char/int_storage.c b/src/char/int_storage.c index 3c5695c90..67b25909b 100644 --- a/src/char/int_storage.c +++ b/src/char/int_storage.c @@ -291,6 +291,22 @@ int inter_storage_init() return 0; } +int storage_db_final (void *k, void *data, va_list ap) { + struct storage *p = data; + if (p) aFree(p); + return 0; +} +int guild_storage_db_final (void *k, void *data, va_list ap) { + struct guild_storage *p = data; + if (p) aFree(p); + return 0; +} +void inter_storage_final() { + numdb_final(storage_db, storage_db_final); + numdb_final(guild_storage_db, guild_storage_db_final); + return; +} + int inter_storage_save_sub(void *key,void *data,va_list ap) { char line[65536]; diff --git a/src/char/int_storage.h b/src/char/int_storage.h index d918f5fe3..f228be53d 100644 --- a/src/char/int_storage.h +++ b/src/char/int_storage.h @@ -3,6 +3,7 @@ #define _INT_STORAGE_H_ int inter_storage_init(); +void inter_storage_final(); int inter_storage_save(); int inter_guild_storage_save(); int inter_storage_delete(int account_id); diff --git a/src/char/inter.c b/src/char/inter.c index f368a48b6..3a388ea82 100644 --- a/src/char/inter.c +++ b/src/char/inter.c @@ -261,6 +261,29 @@ int inter_init(const char *file) { return 0; } +// finalize +int accreg_db_final (void *k, void *data, va_list ap) { + struct accreg *p = data; + if (p) aFree(p); + return 0; +} +int wis_db_final (void *k, void *data, va_list ap) { + struct WisData *p = data; + if (p) aFree(p); + return 0; +} +void inter_final() { + numdb_final(accreg_db, accreg_db_final); + numdb_final(wis_db, wis_db_final); + + inter_party_final(); + inter_guild_final(); + inter_storage_final(); + inter_pet_final(); + + return; +} + // マップサーバー接続 int inter_mapif_init(int fd) { inter_guild_mapif_init(fd); diff --git a/src/char/inter.h b/src/char/inter.h index 0b6f809d7..636ce31d8 100644 --- a/src/char/inter.h +++ b/src/char/inter.h @@ -3,6 +3,7 @@ #define _INTER_H_ int inter_init(const char *file); +void inter_final(); int inter_save(); int inter_parse_frommap(int fd); int inter_mapif_init(int fd); diff --git a/src/char_sql/char.c b/src/char_sql/char.c index 78467b579..6b122974f 100644 --- a/src/char_sql/char.c +++ b/src/char_sql/char.c @@ -3134,6 +3134,12 @@ int char_lan_config_read(const char *lancfgName){ return 0; } +static int char_db_final(void *key,void *data,va_list ap) +{ + struct mmo_charstatus *p = data; + if (p) aFree(p); + return 0; +} void do_final(void) { printf("Doing final stage...\n"); //mmo_char_sync(); @@ -3162,9 +3168,12 @@ void do_final(void) { delete_session(login_fd); delete_session(char_fd); + numdb_final(char_db_, char_db_final); + exit_dbn(); mysql_close(&mysql_handle); mysql_close(&lmysql_handle); + timer_final(); printf("ok! all done...\n"); } diff --git a/src/char_sql/int_guild.c b/src/char_sql/int_guild.c index 2f294bade..4961fd933 100644 --- a/src/char_sql/int_guild.c +++ b/src/char_sql/int_guild.c @@ -709,6 +709,35 @@ int inter_guild_sql_init() return 0; } +int guild_expcache_db_final (void *k, void *data, va_list ap) { return 0; } +int guild_infoevent_db_final (void *k, void *data, va_list ap) { return 0; } +int guild_castleinfoevent_db_final (void *k, void *data, va_list ap) { return 0; } +int guild_db_final (void *k, void *data, va_list ap) +{ + struct guild *g = data; + if (g) aFree(g); + return 0; +} +int castle_db_final (void *k, void *data, va_list ap) +{ + struct guild_castle *gc = data; + if (gc) aFree(gc); + return 0; +} +void inter_guild_sql_final() +{ + if (guild_pt) aFree(guild_pt); + if (guild_pt2) aFree(guild_pt2); + if (guildcastle_pt) aFree(guildcastle_pt); + + numdb_final(guild_db_, guild_db_); + numdb_final(castle_db_, castle_db_final); + numdb_final(guild_expcache_db_, guild_expcache_db_final); + numdb_final(guild_infoevent_db_, guild_infoevent_db_final); + numdb_final(guild_castleinfoevent_db_, guild_castleinfoevent_db_final); + + return; +} // Get guild by its name struct guild* search_guildname(char *str) diff --git a/src/char_sql/int_guild.h b/src/char_sql/int_guild.h index 8f4203d7c..8257cf8f6 100644 --- a/src/char_sql/int_guild.h +++ b/src/char_sql/int_guild.h @@ -3,6 +3,7 @@ int inter_guild_parse_frommap(int fd); int inter_guild_sql_init(); +void inter_guild_sql_final(); int inter_guild_mapif_init(int fd); int inter_guild_leave(int guild_id,int account_id,int char_id); diff --git a/src/char_sql/int_party.c b/src/char_sql/int_party.c index 4cafa9f4d..03392feb6 100644 --- a/src/char_sql/int_party.c +++ b/src/char_sql/int_party.c @@ -237,6 +237,10 @@ int inter_party_sql_init(){ return 0; } +void inter_party_sql_final(){ + if (party_pt) aFree(party_pt); + return; +} // Search for the party according to its name diff --git a/src/char_sql/int_party.h b/src/char_sql/int_party.h index 04f71c881..686d70b04 100644 --- a/src/char_sql/int_party.h +++ b/src/char_sql/int_party.h @@ -3,6 +3,7 @@ int inter_party_parse_frommap(int fd); int inter_party_sql_init(); +void inter_party_sql_final(); int inter_party_leave(int party_id,int account_id); #endif diff --git a/src/char_sql/int_pet.c b/src/char_sql/int_pet.c index 35a7710a7..ea1fed67d 100644 --- a/src/char_sql/int_pet.c +++ b/src/char_sql/int_pet.c @@ -136,6 +136,10 @@ int inter_pet_sql_init(){ return 0; } +void inter_pet_sql_final(){ + if (pet_pt) aFree(pet_pt); + return; +} //---------------------------------- int inter_pet_delete(int pet_id){ printf("request delete pet: %d.......\n",pet_id); diff --git a/src/char_sql/int_pet.h b/src/char_sql/int_pet.h index b6e3f1bbf..39f127262 100644 --- a/src/char_sql/int_pet.h +++ b/src/char_sql/int_pet.h @@ -2,6 +2,7 @@ #define _INT_PET_H_ int inter_pet_init(); +void inter_pet_sql_final(); int inter_pet_save(); int inter_pet_delete(int pet_id); diff --git a/src/char_sql/int_storage.c b/src/char_sql/int_storage.c index 48f5e04a1..9bb5318c6 100644 --- a/src/char_sql/int_storage.c +++ b/src/char_sql/int_storage.c @@ -166,6 +166,13 @@ int inter_storage_sql_init(){ return 1; } +// storage data finalize +void inter_storage_sql_final() +{ + if (storage_pt) aFree(storage_pt); + if (guild_storage_pt) aFree(guild_storage_pt); + return; +} // q?f[^? int inter_storage_delete(int account_id) { diff --git a/src/char_sql/int_storage.h b/src/char_sql/int_storage.h index f9f37db3e..5541d1ed7 100644 --- a/src/char_sql/int_storage.h +++ b/src/char_sql/int_storage.h @@ -2,6 +2,7 @@ #define _INT_STORAGE_H_ int inter_storage_sql_init(); +void inter_storage_sql_final(); int inter_storage_delete(int account_id); int inter_guild_storage_delete(int guild_id); diff --git a/src/char_sql/inter.c b/src/char_sql/inter.c index a8e0d4f44..13ce0acbe 100644 --- a/src/char_sql/inter.c +++ b/src/char_sql/inter.c @@ -290,12 +290,32 @@ int inter_init(const char *file) inter_pet_sql_init(); inter_accreg_sql_init(); + atexit(inter_final); + //printf ("interserver timer initializing : %d sec...\n",autosave_interval); //i=add_timer_interval(gettick()+autosave_interval,inter_save_timer,0,0,autosave_interval); return 0; } +// finalize +int wis_db_final (void *k, void *data, va_list ap) { + struct WisData *p = data; + if (p) aFree(p); + return 0; +} +void inter_final() { + numdb_final(wis_db, wis_db_final); + + inter_guild_sql_final(); + inter_storage_sql_final(); + inter_party_sql_final(); + inter_pet_sql_final(); + + if (accreg_pt) aFree(accreg_pt); + return; +} + int inter_mapif_init(int fd) { inter_guild_mapif_init(fd); diff --git a/src/char_sql/inter.h b/src/char_sql/inter.h index 4b61b69c5..1e6a26dce 100644 --- a/src/char_sql/inter.h +++ b/src/char_sql/inter.h @@ -2,10 +2,10 @@ #define _INTER_H_ int inter_init(const char *file); +void inter_final(); int inter_parse_frommap(int fd); int inter_mapif_init(int fd); - int inter_check_length(int fd,int length); int inter_log(char *fmt,...); diff --git a/src/common/core.c b/src/common/core.c index 96d2c872b..03945040a 100644 --- a/src/common/core.c +++ b/src/common/core.c @@ -285,6 +285,12 @@ int main(int argc,char **argv) { int next; + display_title(); +#ifdef USE_MEMMGR + // call this first so it'll be finalised last + do_init_memmgr(argv[0]); // 一番最初に実行する必要がある +#endif + sscanf(argv[0], "./%24[^\n]", server_type); // map/char/login? atexit(log_uptime); pid_create(argv[0]); @@ -305,12 +311,6 @@ int main(int argc,char **argv) compat_signal(SIGTRAP, SIG_DFL); #endif - display_title(); - -#ifdef USE_MEMMGR - do_init_memmgr(argv[0]); // 一番最初に実行する必要がある -#endif - tick_ = time(0); ticks = gettick(); diff --git a/src/common/malloc.c b/src/common/malloc.c index 40c9f34bf..703933d01 100644 --- a/src/common/malloc.c +++ b/src/common/malloc.c @@ -7,9 +7,6 @@ #include "memwatch.h" #endif -// 独自メモリマネージャを使用する場合、次のコメントを外してください。 -// #define USE_MEMMGR - #if !defined(DMALLOC) && !defined(GCOLLECT) && !defined(BCHECK) && !defined(USE_MEMMGR) void* aMalloc_( size_t size, const char *file, int line, const char *func ) @@ -537,6 +534,7 @@ static void memmer_exit(void) { printf("memmgr: no memory leaks found.\n"); } else { printf("memmgr: memory leaks found.\n"); + fclose(fp); } } diff --git a/src/common/malloc.h b/src/common/malloc.h index 45451c9e0..eec138cdd 100644 --- a/src/common/malloc.h +++ b/src/common/malloc.h @@ -3,6 +3,9 @@ #include <stdlib.h> +// 独自メモリマネージャを使用する場合、次のコメントを外してください。 +// #define USE_MEMMGR + #if defined(DMALLOC) # include "dmalloc.h" diff --git a/src/common/socket.c b/src/common/socket.c index f49d4c0ca..1c4d5931a 100644 --- a/src/common/socket.c +++ b/src/common/socket.c @@ -943,11 +943,9 @@ void do_final_socket(void) aFree(access_deny); // session[0] のダミーデータを削除 - if (session[0]) { - aFree(session[0]->rdata); - aFree(session[0]->wdata); - aFree(session[0]); - } + aFree(session[0]->rdata); + aFree(session[0]->wdata); + aFree(session[0]); } void do_socket(void) diff --git a/src/common/timer.h b/src/common/timer.h index c43c0e6b0..57036ae01 100644 --- a/src/common/timer.h +++ b/src/common/timer.h @@ -36,11 +36,9 @@ int addtick_timer(int tid,unsigned int tick); struct TimerData *get_timer(int tid); int do_timer(unsigned int tick); +void timer_final(); int add_timer_func_list(int (*)(int,unsigned int,int,int),char*); -void do_final_timer(void); char* search_timer_func_list(int (*)(int,unsigned int,int,int)); -extern void timer_final(); - #endif // _TIMER_H_ diff --git a/src/login/login.c b/src/login/login.c index a54aca410..27f7c12ce 100644 --- a/src/login/login.c +++ b/src/login/login.c @@ -3923,11 +3923,12 @@ void do_final(void) { memset(&server[i], 0, sizeof(struct mmo_char_server)); close(fd); delete_session(fd); - if(session[fd]) aFree(session[fd]); } } close(login_fd); delete_session(login_fd); + exit_dbn(); + timer_final(); login_log("----End of login-server (normal end with closing of all files)." RETCODE); diff --git a/src/login_sql/login.c b/src/login_sql/login.c index 91fc9ccb8..071b6d32c 100644 --- a/src/login_sql/login.c +++ b/src/login_sql/login.c @@ -41,30 +41,19 @@ void Gettimeofday(struct timeval *timenow) #include <signal.h> #include <fcntl.h> #include <string.h> -#include "malloc.h" //add include for DBMS(mysql) #include <mysql.h> -#include "../common/strlib.h" -#include "timer.h" -/* -#include "timer.h" -#include "core.h" -#include "socket.h" -#include "login.h" -#include "mmo.h" -#include "version.h" -#include "db.h" -*/ - #include "../common/core.h" #include "../common/socket.h" -#include "login.h" -#include "../common/mmo.h" -#include "../common/version.h" +#include "../common/malloc.h" #include "../common/db.h" #include "../common/timer.h" +#include "../common/strlib.h" +#include "../common/mmo.h" +#include "../common/version.h" +#include "login.h" #ifdef PASSWORDENC #include "md5calc.h" @@ -1835,6 +1824,24 @@ int flush_timer(int tid, unsigned int tick, int id, int data){ return 0; } +//-------------------------------------- +// Function called at exit of the server +//-------------------------------------- +static int online_db_final(void *key,void *data,va_list ap) +{ + int *p = data; + if (p) aFree(p); + return 0; +} +void do_final(void) { + //sync account when terminating. + //but no need when you using DBMS (mysql) + mmo_db_close(); + numdb_final(online_db, online_db_final); + exit_dbn(); + timer_final(); +} + int do_init(int argc,char **argv){ //initialize login server int i; @@ -1876,9 +1883,7 @@ int do_init(int argc,char **argv){ printf ("Running mmo_auth_sqldb_init()\n"); mmo_auth_sqldb_init(); printf ("finished mmo_auth_sqldb_init()\n"); - //sync account when terminating. - //but no need when you using DBMS (mysql) - set_termfunc(mmo_db_close); + set_termfunc(do_final); //set default parser as parse_login function set_defaultparse(parse_login); diff --git a/src/map/map.c b/src/map/map.c index 60d41b84e..9dcf541c1 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -1697,24 +1697,24 @@ int map_addnpc(int m,struct npc_data *nd) { } void map_removenpc(void) { - int i,m,n=0; - - for(m=0;m<map_num;m++) { - for(i=0;i<map[m].npc_num && i<MAX_NPC_PER_MAP;i++) { - if(map[m].npc[i]!=NULL) { - clif_clearchar_area(&map[m].npc[i]->bl,2); - map_delblock(&map[m].npc[i]->bl); - numdb_erase(id_db,map[m].npc[i]->bl.id); - if(map[m].npc[i]->bl.subtype==SCRIPT) { -// aFree(map[m].npc[i]->u.scr.script); -// aFree(map[m].npc[i]->u.scr.label_list); - } - aFree(map[m].npc[i]); - map[m].npc[i] = NULL; - n++; - } - } - } + int i,m,n=0; + + for(m=0;m<map_num;m++) { + for(i=0;i<map[m].npc_num && i<MAX_NPC_PER_MAP;i++) { + if(map[m].npc[i]!=NULL) { + clif_clearchar_area(&map[m].npc[i]->bl,2); + map_delblock(&map[m].npc[i]->bl); + numdb_erase(id_db,map[m].npc[i]->bl.id); + if(map[m].npc[i]->bl.subtype==SCRIPT) { + aFree(map[m].npc[i]->u.scr.script); + aFree(map[m].npc[i]->u.scr.label_list); + } + aFree(map[m].npc[i]); + map[m].npc[i] = NULL; + n++; + } + } + } sprintf(tmp_output,"Successfully removed and freed from memory '"CL_WHITE"%d"CL_RESET"' NPCs.\n",n); ShowStatus(tmp_output); @@ -3097,29 +3097,20 @@ int flush_timer(int tid, unsigned int tick, int id, int data){ return 0; } -int id_db_final(void *k,void *d,va_list ap) +int id_db_final(void *k,void *d,va_list ap) { return 0; } +int map_db_final(void *k,void *d,va_list ap) { return 0; } +int nick_db_final(void *k,void *d,va_list ap) { - struct mob_data *id; - nullpo_retr(0, id = (struct mob_data*)d); - if(id->lootitem) - aFree(id->lootitem); - if(id) - aFree(id); + char *p = d; + if (p) aFree(p); return 0; } - -int map_db_final(void *k,void *d,va_list ap) +int charid_db_final(void *k,void *d,va_list ap) { - struct map_data *id; - nullpo_retr(0, id = (struct map_data*)d); - if(id->gat) - aFree(id->gat); - if(id) - aFree(id); + struct charid2nick *p = d; + if (p) aFree(p); return 0; } -int nick_db_final(void *k,void *d,va_list ap){ return 0; } -int charid_db_final(void *k,void *d,va_list ap){ return 0; } int cleanup_sub(struct block_list *bl, va_list ap) { nullpo_retr(0, bl); @@ -3152,12 +3143,12 @@ int cleanup_sub(struct block_list *bl, va_list ap) { *------------------------------------------ */ void do_final(void) { - int map_id, i; + int i; ShowStatus("Terminating...\n"); - for (map_id = 0; map_id < map_num;map_id++) - if(map[map_id].m) - map_foreachinarea(cleanup_sub, map_id, 0, 0, map[map_id].xs, map[map_id].ys, 0, 0); + for (i = 0; i < map_num; i++) + if(map[i].m) + map_foreachinarea(cleanup_sub, i, 0, 0, map[i].xs, map[i].ys, 0, 0); #ifndef TXT_ONLY chrif_char_reset_offline(); @@ -3165,38 +3156,35 @@ void do_final(void) { chrif_flush_fifo(); - for (i = 0; i < fd_max; i++) - delete_session(i); - -#if 0 - map_removenpc(); - -// do_final_timer(); (we used timer_final() instead) - timer_final(); -// numdb_final(id_db, id_db_final); - strdb_final(map_db, map_db_final); - strdb_final(nick_db, nick_db_final); - numdb_final(charid_db, charid_db_final); - +//#if 0 // why is this here? >_> do_final_chrif(); // この内部でキャラを全て切断する + do_final_npc(); +// map_removenpc(); do_final_script(); do_final_itemdb(); do_final_storage(); do_final_guild(); + do_final_party(); + do_final_pc(); do_final_pet(); -/* - for(i=0;i<map_num;i++){ - if(map[i].gat) { - aFree(map[i].gat); - map[i].gat=NULL; //isn't it NULL already o_O? - } + + for (i=0; i<map_num; i++) { + if(map[i].gat) aFree(map[i].gat); if(map[i].block) aFree(map[i].block); if(map[i].block_mob) aFree(map[i].block_mob); if(map[i].block_count) aFree(map[i].block_count); if(map[i].block_mob_count) aFree(map[i].block_mob_count); } -*/ -#endif + +// do_final_timer(); (we used timer_final() instead) + timer_final(); + numdb_final(id_db, id_db_final); + strdb_final(map_db, map_db_final); + strdb_final(nick_db, nick_db_final); + numdb_final(charid_db, charid_db_final); + exit_dbn(); + +//#endif #ifndef TXT_ONLY map_sql_close(); diff --git a/src/map/npc.c b/src/map/npc.c index eb3f33ac5..0e158bc77 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -2315,7 +2315,37 @@ static int npc_read_indoors(void) return 0; } +static int npc_unload(struct npc_data *nd) +{ + struct chat_data *cd; + + nullpo_retr (0, nd); + if (nd->chat_id && (cd=(struct chat_data*)map_id2bl(nd->chat_id))){ + aFree (cd); + cd = NULL; + } + if (nd->bl.subtype == SCRIPT) { + if (nd->u.scr.timer_event) + aFree(nd->u.scr.timer_event); + if (nd->u.scr.src_id==0) { + if(nd->u.scr.script) { + aFree(nd->u.scr.script); + nd->u.scr.script=NULL; + } + if (nd->u.scr.label_list) { + aFree(nd->u.scr.label_list); + nd->u.scr.label_list = NULL; + } + } + } + clif_clearchar_area(&nd->bl, 2); + map_delblock(&nd->bl); + map_deliddb(&nd->bl); + aFree(nd); + nd = NULL; + return 0; +} static int ev_db_final(void *key,void *data,va_list ap) { aFree(data); @@ -2328,6 +2358,30 @@ static int npcname_db_final(void *key,void *data,va_list ap) return 0; } /*========================================== + * + *------------------------------------------ + */ +int npc_reload(void) +{ + struct npc_data *nd; + struct block_list *bl; + int i; + + if(ev_db) + strdb_final(ev_db,ev_db_final); + if(npcname_db) + strdb_final(npcname_db,npcname_db_final); + + for (i = START_NPC_NUM; i < npc_id; i++) { + if((bl = map_id2bl(i)) && bl->type == BL_NPC && (nd = (struct npc_data *)bl)) + npc_unload(nd); + } + + return 0; + + +} +/*========================================== * 終了 *------------------------------------------ */ @@ -2337,7 +2391,6 @@ int do_final_npc(void) struct block_list *bl; struct npc_data *nd; struct mob_data *md; - struct chat_data *cd; struct pet_data *pd; if(ev_db) @@ -2345,31 +2398,14 @@ int do_final_npc(void) if(npcname_db) strdb_final(npcname_db,npcname_db_final); - for(i=START_NPC_NUM;i<npc_id;i++){ - if((bl=map_id2bl(i))){ + npc_clearsrcfile(); + + for (i = START_NPC_NUM; i < npc_id; i++){ + if((bl = map_id2bl(i))){ if(bl->type == BL_NPC && (nd = (struct npc_data *)bl)){ - if(nd->chat_id && (cd=(struct chat_data*)map_id2bl(nd->chat_id))){ - aFree(cd); - cd = NULL; - } - if(nd->bl.subtype == SCRIPT){ - if(nd->u.scr.timer_event) - aFree(nd->u.scr.timer_event); - if(nd->u.scr.src_id==0){ - if(nd->u.scr.script){ - aFree(nd->u.scr.script); - nd->u.scr.script=NULL; - } - if(nd->u.scr.label_list){ - aFree(nd->u.scr.label_list); - nd->u.scr.label_list = NULL; - } - } - } - aFree(nd); - nd = NULL; - }else if(bl->type == BL_MOB && (md = (struct mob_data *)bl)){ - if(md->lootitem){ + npc_unload(nd); + }else if (bl->type == BL_MOB && (md = (struct mob_data *)bl)){ + if (md->lootitem){ aFree(md->lootitem); md->lootitem = NULL; } @@ -2415,10 +2451,10 @@ int do_init_npc(void) // comparing only the first 24 chars of labels that are 50 chars long isn't that nice // will cause "duplicated" labels where actually no dup is... //ev_db=strdb_init(24); - ev_db=strdb_init(51); - npcname_db=strdb_init(24); + ev_db = strdb_init(51); + npcname_db = strdb_init(24); - ev_db->release = ev_release; + ev_db->release = ev_release; memset(&ev_tm_b,-1,sizeof(ev_tm_b)); diff --git a/src/map/pc.c b/src/map/pc.c index 07e712dbe..8c0857d4b 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -7234,6 +7234,11 @@ int pc_readdb(void) * pc? 係初期化 *------------------------------------------ */ +void do_final_pc(void) { + if (gm_account) + aFree(gm_account); + return; +} int do_init_pc(void) { pc_readdb(); diff --git a/src/map/pc.h b/src/map/pc.h index 242ae3147..8c4f96529 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -202,6 +202,7 @@ int pc_delspiritball(struct map_session_data *sd,int,int); int pc_eventtimer(int tid,unsigned int tick,int id,int data); // for npc_dequeue int do_init_pc(void); +void do_final_pc(void); enum {ADDITEM_EXIST,ADDITEM_NEW,ADDITEM_OVERAMOUNT}; |