summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcelest <celest@54d463be-8e91-2dee-dedb-b68131a5f0ec>2005-03-23 15:26:52 +0000
committercelest <celest@54d463be-8e91-2dee-dedb-b68131a5f0ec>2005-03-23 15:26:52 +0000
commit33b8fd47955eeab26cede233b14d683b8e0491b8 (patch)
tree041f7df2acc8b46bdb56512f06b0f9706fe6ec29
parent7d3fedfa5c264169c544fe3ec977229c50e4baa2 (diff)
downloadhercules-33b8fd47955eeab26cede233b14d683b8e0491b8.tar.gz
hercules-33b8fd47955eeab26cede233b14d683b8e0491b8.tar.bz2
hercules-33b8fd47955eeab26cede233b14d683b8e0491b8.tar.xz
hercules-33b8fd47955eeab26cede233b14d683b8e0491b8.zip
* Fixed alot of memory leaks
* Added stray memory cleaning routine to db.c git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/branches/stable@1275 54d463be-8e91-2dee-dedb-b68131a5f0ec
-rw-r--r--Changelog-SVN.txt2
-rw-r--r--src/char/char.c12
-rw-r--r--src/char/int_guild.c20
-rw-r--r--src/char/int_guild.h1
-rw-r--r--src/char/int_party.c11
-rw-r--r--src/char/int_party.h1
-rw-r--r--src/char/int_pet.c11
-rw-r--r--src/char/int_pet.h1
-rw-r--r--src/char/int_storage.c16
-rw-r--r--src/char/int_storage.h1
-rw-r--r--src/char/inter.c23
-rw-r--r--src/char/inter.h1
-rw-r--r--src/char_sql/char.c9
-rw-r--r--src/char_sql/int_guild.c29
-rw-r--r--src/char_sql/int_guild.h1
-rw-r--r--src/char_sql/int_party.c4
-rw-r--r--src/char_sql/int_party.h1
-rw-r--r--src/char_sql/int_pet.c4
-rw-r--r--src/char_sql/int_pet.h1
-rw-r--r--src/char_sql/int_storage.c7
-rw-r--r--src/char_sql/int_storage.h1
-rw-r--r--src/char_sql/inter.c20
-rw-r--r--src/char_sql/inter.h2
-rw-r--r--src/common/core.c12
-rw-r--r--src/common/malloc.c4
-rw-r--r--src/common/malloc.h3
-rw-r--r--src/common/socket.c8
-rw-r--r--src/common/timer.h4
-rw-r--r--src/login/login.c3
-rw-r--r--src/login_sql/login.c43
-rw-r--r--src/map/map.c108
-rw-r--r--src/map/npc.c92
-rw-r--r--src/map/pc.c5
-rw-r--r--src/map/pc.h1
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};