summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changelog-Trunk.txt6
-rw-r--r--db/skill_db.txt2
-rw-r--r--src/char/char.c7
-rw-r--r--src/char_sql/char.c8
-rw-r--r--src/common/core.c11
-rw-r--r--src/common/core.h1
-rw-r--r--src/ladmin/ladmin.c6
-rw-r--r--src/login/login.c7
-rw-r--r--src/login_sql/login.c7
-rw-r--r--src/map/map.c28
-rw-r--r--src/map/skill.c2
-rw-r--r--src/map/status.c18
-rw-r--r--src/txt-converter/char-converter.c4
-rw-r--r--src/txt-converter/login-converter.c3
14 files changed, 97 insertions, 13 deletions
diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt
index 6ad6c835c..273315354 100644
--- a/Changelog-Trunk.txt
+++ b/Changelog-Trunk.txt
@@ -4,6 +4,12 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO
IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
2007/03/30
+ * Added "do_abort" function to the core. It is invoked when the server has
+ received a Segmentation Fault or Floating Point Exception signal. Currently
+ the only one that uses it is the map-server, which then attempts to save
+ all online characters before aborting. Note that due to the current
+ coding of the sig plugin, do_abort will not be invoked if you use it!
+ This plugin needs to be updated... [Skotlex]
* Continued script.c cleanup [Toms]
2007/03/29
* Corrected OPTION_XMAS since 2007 clients have split it up from
diff --git a/db/skill_db.txt b/db/skill_db.txt
index 3aee7235d..4eddf7404 100644
--- a/db/skill_db.txt
+++ b/db/skill_db.txt
@@ -386,7 +386,7 @@
345,9,6,1,-1,0,0,10,1,no,0,0x2,0,weapon,0 //NPC_BREAKHELM#Break helm#
346,9,6,1,-1,0,0,10,1,no,0,0x2,0,weapon,0 //NPC_BREAKSHIELD#Break shield#
347,-1,6,1,9,0,0,10,1,no,0,0x2,0,weapon,0 //NPC_UNDEADATTACK
-348,9,0,1,9,0x1,0,10,1,no,0,0x2,0,magic,0 //NPC_CHANGEUNDEAD
+348,9,0,1,9,0x1,0,5,1,no,0,0x2,0,magic,0 //NPC_CHANGEUNDEAD
349,0,6,4,0,0x1,0,10,0,no,0,0x2,0,weapon,0 //NPC_POWERUP
350,0,6,4,0,0x1,0,10,0,no,0,0x2,0,none,0 //NPC_AGIUP
351,0,0,0,0,0x1,0,0,0,no,0,0x2,0,none,0 //NPC_SIEGEMODE
diff --git a/src/char/char.c b/src/char/char.c
index be691808a..68d67f56c 100644
--- a/src/char/char.c
+++ b/src/char/char.c
@@ -4297,6 +4297,13 @@ void do_final(void) {
char_log("----End of char-server (normal end with closing of all files)." RETCODE);
}
+//------------------------------
+// Function called when the server
+// has received a crash signal.
+//------------------------------
+void do_abort(void) {
+}
+
void set_server_type(void)
{
SERVER_TYPE = ATHENA_SERVER_CHAR;
diff --git a/src/char_sql/char.c b/src/char_sql/char.c
index 693ddee12..4e325700e 100644
--- a/src/char_sql/char.c
+++ b/src/char_sql/char.c
@@ -3909,6 +3909,14 @@ void do_final(void) {
ShowInfo("ok! all done...\n");
}
+
+//------------------------------
+// Function called when the server
+// has received a crash signal.
+//------------------------------
+void do_abort(void) {
+}
+
#endif //TXT_SQL_CONVERT
void sql_config_read(const char *cfgName){ /* Kalaspuff, to get login_db */
char line[1024], w1[1024], w2[1024];
diff --git a/src/common/core.c b/src/common/core.c
index 5924a0aa6..60d25546a 100644
--- a/src/common/core.c
+++ b/src/common/core.c
@@ -92,6 +92,13 @@ static void sig_proc(int sn)
exit(0);
runflag = 0;
break;
+ case SIGSEGV:
+ case SIGFPE:
+ do_abort();
+ // Pass the signal to the system's default handler
+ compat_signal(sn, SIG_DFL);
+ raise(sn);
+ break;
#ifndef _WIN32
case SIGXFSZ:
// ignore and allow it to set errno to EFBIG
@@ -109,10 +116,10 @@ void signals_init (void)
{
compat_signal(SIGTERM, sig_proc);
compat_signal(SIGINT, sig_proc);
+ compat_signal(SIGSEGV, sig_proc);
+ compat_signal(SIGFPE, sig_proc);
// Signal to create coredumps by system when necessary (crash)
- compat_signal(SIGSEGV, SIG_DFL);
- compat_signal(SIGFPE, SIG_DFL);
compat_signal(SIGILL, SIG_DFL);
#ifndef _WIN32
compat_signal(SIGXFSZ, sig_proc);
diff --git a/src/common/core.h b/src/common/core.h
index 5e396cc7a..f59a87e3e 100644
--- a/src/common/core.h
+++ b/src/common/core.h
@@ -18,6 +18,7 @@ extern const char *get_svn_revision(void);
extern int do_init(int,char**);
extern void set_server_type(void);
extern void set_termfunc(void (*termfunc)(void));
+extern void do_abort(void);
extern void do_final(void);
#endif /* _CORE_H_ */
diff --git a/src/ladmin/ladmin.c b/src/ladmin/ladmin.c
index 947af1900..4f4099493 100644
--- a/src/ladmin/ladmin.c
+++ b/src/ladmin/ladmin.c
@@ -4361,6 +4361,12 @@ int ladmin_config_read(const char *cfgName) {
return 0;
}
+//------------------------------
+// Function called when the server
+// has received a crash signal.
+//------------------------------
+void do_abort(void) {}
+
//--------------------------------------
// Function called at exit of the server
//--------------------------------------
diff --git a/src/login/login.c b/src/login/login.c
index 25f91c3d6..1b5e96596 100644
--- a/src/login/login.c
+++ b/src/login/login.c
@@ -4035,6 +4035,13 @@ void do_final(void) {
}
//------------------------------
+// Function called when the server
+// has received a crash signal.
+//------------------------------
+void do_abort(void) {
+}
+
+//------------------------------
// Main function of login-server
//------------------------------
void set_server_type(void)
diff --git a/src/login_sql/login.c b/src/login_sql/login.c
index 6173d0fe1..2d2e7af9f 100644
--- a/src/login_sql/login.c
+++ b/src/login_sql/login.c
@@ -2038,6 +2038,13 @@ void do_final(void)
aFree(gm_account_db);
}
+//------------------------------
+// Function called when the server
+// has received a crash signal.
+//------------------------------
+void do_abort(void) {
+}
+
void set_server_type(void)
{
SERVER_TYPE = ATHENA_SERVER_LOGIN;
diff --git a/src/map/map.c b/src/map/map.c
index fba8faa88..9cf047d56 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -3156,6 +3156,34 @@ void do_final(void) {
ShowStatus("Successfully terminated.\n");
}
+static int map_abort_sub(DBKey key,void * data,va_list ap)
+{
+ struct map_session_data *sd = (TBL_PC*)data;
+
+ if (!sd->state.auth || sd->state.waitingdisconnect || sd->state.finalsave)
+ return 0;
+
+ chrif_save(sd,1);
+ return 1;
+}
+
+
+//------------------------------
+// Function called when the server
+// has received a crash signal.
+//------------------------------
+void do_abort(void) {
+ //Save all characters and then flush the inter-connection.
+ if (!chrif_isconnect())
+ {
+ ShowFatalError("Server has crashed without a connection to the char-server, character data can't be saved!\n");
+ return;
+ }
+ ShowError("Server received crash signal! Attempting to save all online characters!\n");
+ map_foreachpc(map_abort_sub);
+ chrif_flush_fifo();
+}
+
/*======================================================
* Map-Server Version Screen [MC Cameri]
*------------------------------------------------------
diff --git a/src/map/skill.c b/src/map/skill.c
index 5c77f186a..65cc19bcf 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -4831,7 +4831,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
case NPC_CHANGETELEKINESIS:
case NPC_CHANGEUNDEAD:
clif_skill_nodamage(src,bl,skillid,skilllv,
- sc_start4(bl, type, 100, skilllv, skillid, skill_get_pl(skillid,skilllv), 0,
+ sc_start2(bl, type, 100, skilllv, skill_get_pl(skillid,skilllv),
skill_get_time(skillid, skilllv)));
break;
diff --git a/src/map/status.c b/src/map/status.c
index b7c595d51..993be24ea 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -3874,9 +3874,9 @@ static unsigned char status_calc_element(struct block_list *bl, struct status_ch
if( sc->data[SC_BENEDICTIO].timer!=-1 )
return ELE_HOLY;
if( sc->data[SC_CHANGEUNDEAD].timer!=-1)
- return sc->data[SC_CHANGEUNDEAD].val3;
+ return ELE_UNDEAD;
if( sc->data[SC_ELEMENTALCHANGE].timer!=-1)
- return sc->data[SC_ELEMENTALCHANGE].val3;
+ return sc->data[SC_ELEMENTALCHANGE].val2;
return cap_value(element,0,UCHAR_MAX);
}
@@ -3893,7 +3893,7 @@ static unsigned char status_calc_element_lv(struct block_list *bl, struct status
if( sc->data[SC_CHANGEUNDEAD].timer!=-1)
return 1;
if(sc->data[SC_ELEMENTALCHANGE].timer!=-1)
- return sc->data[SC_ELEMENTALCHANGE].val4;
+ return sc->data[SC_ELEMENTALCHANGE].val1;
return cap_value(lv,1,4);
}
@@ -5007,10 +5007,14 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val
skill_enchant_elemental_end(bl,type);
break;
case SC_ELEMENTALCHANGE:
- //Val1 is skill level, val2 is skill that invoked this.
- if (!val3) //Val 3 holds the element, when not given, a random one is picked.
- val3 = rand()%ELE_MAX;
- val4 =1+rand()%4; //Elemental Lv is always a random value between 1 and 4.
+ //Val1 is elemental change level, val2 is eleemnt to use.
+ if (!val2) //Val 3 holds the element, when not given, a random one is picked.
+ val2 = rand()%ELE_MAX;
+ //Elemental Lv is always a random value between 1 and 4.
+ if (val1 == 1)
+ val1 =1+rand()%4;
+ else if (val1 > 4)
+ val1 = 4;
break;
case SC_PROVIDENCE:
val2=val1*5; //Race/Ele resist
diff --git a/src/txt-converter/char-converter.c b/src/txt-converter/char-converter.c
index b5f604bf8..3d1f59391 100644
--- a/src/txt-converter/char-converter.c
+++ b/src/txt-converter/char-converter.c
@@ -278,4 +278,6 @@ int do_init(int argc, char **argv){
exit (0);
}
-void do_final () {}
+void do_abort(void) {}
+
+void do_final (void) {}
diff --git a/src/txt-converter/login-converter.c b/src/txt-converter/login-converter.c
index 840d61e1c..1f5b4141c 100644
--- a/src/txt-converter/login-converter.c
+++ b/src/txt-converter/login-converter.c
@@ -228,5 +228,6 @@ int do_init(int argc,char **argv)
exit (0);
}
+void do_abort(void) {}
-void do_final() {}
+void do_final(void) {}