summaryrefslogtreecommitdiff
path: root/src/map/chrif.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/chrif.c')
-rw-r--r--src/map/chrif.c114
1 files changed, 74 insertions, 40 deletions
diff --git a/src/map/chrif.c b/src/map/chrif.c
index c4eeea3d9..a14200a36 100644
--- a/src/map/chrif.c
+++ b/src/map/chrif.c
@@ -31,6 +31,8 @@
#include <sys/types.h>
#include <time.h>
+static int check_connect_char_server(int tid, unsigned int tick, int id, intptr_t data);
+
static struct eri *auth_db_ers; //For reutilizing player login structures.
static DBMap* auth_db; // int id -> struct auth_node*
@@ -94,7 +96,7 @@ static const int packet_len_table[0x3d] = { // U - used, F - free
//2b27: Incoming, chrif_authfail -> 'client authentication failed'
int chrif_connected = 0;
-int char_fd = 0; //Using 0 instead of -1 is safer against crashes. [Skotlex]
+int char_fd = -1;
int srvinfo;
static char char_ip_str[128];
static uint32 char_ip = 0;
@@ -110,6 +112,28 @@ int other_mapserver_count=0; //Holds count of how many other map servers are onl
//This define should spare writing the check in every function. [Skotlex]
#define chrif_check(a) { if(!chrif_isconnected()) return a; }
+
+/// Resets all the data.
+void chrif_reset(void)
+{
+ // TODO kick everyone out and reset everything [FlavioJS]
+ exit(EXIT_FAILURE);
+}
+
+
+/// Checks the conditions for the server to stop.
+/// Releases the cookie when all characters are saved.
+/// If all the conditions are met, it stops the core loop.
+void chrif_check_shutdown(void)
+{
+ if( runflag != MAPSERVER_ST_SHUTDOWN )
+ return;
+ if( auth_db->size(auth_db) > 0 )
+ return;
+ runflag = CORE_ST_STOP;
+}
+
+
struct auth_node* chrif_search(int account_id)
{
return (struct auth_node*)idb_get(auth_db, account_id);
@@ -244,9 +268,8 @@ int chrif_save(struct map_session_data *sd, int flag)
{
nullpo_retr(-1, sd);
- if (!flag) //The flag check is needed to prevent 'nosave' taking effect when a jailed player logs out.
- pc_makesavestatus(sd);
-
+ pc_makesavestatus(sd);
+
if (flag && sd->state.active) //Store player data which is quitting.
{
//FIXME: SC are lost if there's no connection at save-time because of the way its related data is cleared immediately after this function. [Skotlex]
@@ -363,6 +386,7 @@ int chrif_removemap(int fd)
static void chrif_save_ack(int fd)
{
chrif_auth_delete(RFIFOL(fd,2), RFIFOL(fd,6), ST_LOGOUT);
+ chrif_check_shutdown();
}
// request to move a character between mapservers
@@ -472,19 +496,13 @@ static int chrif_reconnect(DBKey key,void *data,va_list ap)
return 0;
}
-/*==========================================
- *
- *------------------------------------------*/
-int chrif_sendmapack(int fd)
-{
- if (RFIFOB(fd,2)) {
- ShowFatalError("chrif : send map list to char server failed %d\n", RFIFOB(fd,2));
- exit(EXIT_FAILURE);
- }
- memcpy(wisp_server_name, RFIFOP(fd,3), NAME_LENGTH);
- ShowStatus("Map sending complete. Map Server is now online.\n");
+/// Called when all the connection steps are completed.
+void chrif_on_ready(void)
+{
+ ShowStatus("Map Server is now online.\n");
chrif_state = 2;
+ chrif_check_shutdown();
//If there are players online, send them to the char-server. [Skotlex]
send_users_tochar();
@@ -494,7 +512,21 @@ int chrif_sendmapack(int fd)
//Re-save any storages that were modified in the disconnection time. [Skotlex]
do_reconnect_storage();
+}
+
+/*==========================================
+ *
+ *------------------------------------------*/
+int chrif_sendmapack(int fd)
+{
+ if (RFIFOB(fd,2)) {
+ ShowFatalError("chrif : send map list to char server failed %d\n", RFIFOB(fd,2));
+ exit(EXIT_FAILURE);
+ }
+
+ memcpy(wisp_server_name, RFIFOP(fd,3), NAME_LENGTH);
+ chrif_on_ready();
return 0;
}
@@ -592,7 +624,8 @@ void chrif_authok(int fd)
}
sd = node->sd;
- if(node->char_dat == NULL &&
+ if( runflag == MAPSERVER_ST_RUNNING &&
+ node->char_dat == NULL &&
node->account_id == account_id &&
node->char_id == char_id &&
node->login_id1 == login_id1 )
@@ -661,7 +694,7 @@ int auth_db_cleanup_sub(DBKey key,void *data,va_list ap)
return 0;
}
-int auth_db_cleanup(int tid, unsigned int tick, int id, intptr data)
+int auth_db_cleanup(int tid, unsigned int tick, int id, intptr_t data)
{
if(!chrif_isconnected()) return 0;
auth_db->foreach(auth_db, auth_db_cleanup_sub);
@@ -838,7 +871,7 @@ int chrif_changedsex(int fd)
if ((sd->class_&MAPID_UPPERMASK) == MAPID_BARDDANCER) {
// remove specifical skills of Bard classes
for(i = 315; i <= 322; i++) {
- if (sd->status.skill[i].id > 0 && !sd->status.skill[i].flag) {
+ if (sd->status.skill[i].id > 0 && sd->status.skill[i].flag == SKILL_FLAG_PERMANENT) {
sd->status.skill_point += sd->status.skill[i].lv;
sd->status.skill[i].id = 0;
sd->status.skill[i].lv = 0;
@@ -846,7 +879,7 @@ int chrif_changedsex(int fd)
}
// remove specifical skills of Dancer classes
for(i = 323; i <= 330; i++) {
- if (sd->status.skill[i].id > 0 && !sd->status.skill[i].flag) {
+ if (sd->status.skill[i].id > 0 && sd->status.skill[i].flag == SKILL_FLAG_PERMANENT) {
sd->status.skill_point += sd->status.skill[i].lv;
sd->status.skill[i].id = 0;
sd->status.skill[i].lv = 0;
@@ -1292,22 +1325,22 @@ int chrif_char_online(struct map_session_data *sd)
return 0;
}
-int chrif_disconnect(int fd)
+
+/// Called when the connection to Char Server is disconnected.
+void chrif_on_disconnect(void)
{
- if(fd == char_fd) {
- char_fd = 0;
- ShowWarning("Map Server disconnected from Char Server.\n\n");
- chrif_connected = 0;
-
- other_mapserver_count=0; //Reset counter. We receive ALL maps from all map-servers on reconnect.
- map_eraseallipport();
+ if( chrif_connected != 1 )
+ ShowWarning("Connection to Char Server lost.\n\n");
+ chrif_connected = 0;
+
+ other_mapserver_count = 0; //Reset counter. We receive ALL maps from all map-servers on reconnect.
+ map_eraseallipport();
- //Attempt to reconnect in a second. [Skotlex]
- add_timer(gettick() + 1000, check_connect_char_server, 0, 0);
- }
- return 0;
+ //Attempt to reconnect in a second. [Skotlex]
+ add_timer(gettick() + 1000, check_connect_char_server, 0, 0);
}
+
void chrif_update_ip(int fd)
{
uint32 new_ip;
@@ -1352,10 +1385,9 @@ int chrif_parse(int fd)
if (session[fd]->flag.eof)
{
- if (chrif_connected == 1)
- chrif_disconnect(fd);
-
do_close(fd);
+ char_fd = -1;
+ chrif_on_disconnect();
return 0;
}
@@ -1393,7 +1425,7 @@ int chrif_parse(int fd)
case 0x2afb: chrif_sendmapack(fd); break;
case 0x2afd: chrif_authok(fd); break;
case 0x2b00: map_setusers(RFIFOL(fd,2)); chrif_keepalive(fd); break;
- case 0x2b03: clif_charselectok(RFIFOL(fd,2)); break;
+ case 0x2b03: clif_charselectok(RFIFOL(fd,2), RFIFOB(fd,6)); break;
case 0x2b04: chrif_recvmap(fd); break;
case 0x2b06: chrif_changemapserverack(RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10), RFIFOL(fd,14), RFIFOW(fd,18), RFIFOW(fd,20), RFIFOW(fd,22), RFIFOL(fd,24), RFIFOW(fd,28)); break;
case 0x2b09: map_addnickdb(RFIFOL(fd,2), (char*)RFIFOP(fd,6)); break;
@@ -1423,7 +1455,7 @@ int chrif_parse(int fd)
return 0;
}
-int ping_char_server(int tid, unsigned int tick, int id, intptr data)
+int ping_char_server(int tid, unsigned int tick, int id, intptr_t data)
{
chrif_check(-1);
chrif_keepalive(char_fd);
@@ -1431,7 +1463,7 @@ int ping_char_server(int tid, unsigned int tick, int id, intptr data)
}
// unused
-int send_usercount_tochar(int tid, unsigned int tick, int id, intptr data)
+int send_usercount_tochar(int tid, unsigned int tick, int id, intptr_t data)
{
chrif_check(-1);
@@ -1476,7 +1508,7 @@ int send_users_tochar(void)
* timer関数
* char鯖との接続を確認し、もし切れていたら再度接続する
*------------------------------------------*/
-int check_connect_char_server(int tid, unsigned int tick, int id, intptr data)
+static int check_connect_char_server(int tid, unsigned int tick, int id, intptr_t data)
{
static int displayed = 0;
if (char_fd <= 0 || session[char_fd] == NULL)
@@ -1491,7 +1523,6 @@ int check_connect_char_server(int tid, unsigned int tick, int id, intptr data)
char_fd = make_connection(char_ip, char_port);
if (char_fd == -1)
{ //Attempt to connect later. [Skotlex]
- char_fd = 0;
return 0;
}
@@ -1532,8 +1563,11 @@ int auth_db_final(DBKey k,void *d,va_list ap)
*------------------------------------------*/
int do_final_chrif(void)
{
- if (char_fd > 0)
+ if( char_fd != -1 )
+ {
do_close(char_fd);
+ char_fd = -1;
+ }
auth_db->destroy(auth_db, auth_db_final);
ers_destroy(auth_db_ers);