|
@@ -176,7 +176,7 @@ struct online_char_data {
|
|
|
};
|
|
|
|
|
|
static DBMap* online_char_db; // int account_id -> struct online_char_data*
|
|
|
-static int chardb_waiting_disconnect(int tid, unsigned int tick, int id, intptr data);
|
|
|
+static int chardb_waiting_disconnect(int tid, unsigned int tick, int id, intptr_t data);
|
|
|
|
|
|
static void* create_online_char_data(DBKey key, va_list args)
|
|
|
{
|
|
@@ -571,8 +571,8 @@ int mmo_char_tostr(char *str, struct mmo_charstatus *p, struct global_reg *reg,
|
|
|
*(str_p++) = '\t';
|
|
|
|
|
|
for(i = 0; i < MAX_SKILL; i++)
|
|
|
- if (p->skill[i].id && p->skill[i].flag != 1) {
|
|
|
- str_p += sprintf(str_p, "%d,%d ", p->skill[i].id, (p->skill[i].flag == 0) ? p->skill[i].lv : p->skill[i].flag-2);
|
|
|
+ if (p->skill[i].id != 0 && p->skill[i].flag != SKILL_FLAG_TEMPORARY) {
|
|
|
+ str_p += sprintf(str_p, "%d,%d ", p->skill[i].id, (p->skill[i].flag == SKILL_FLAG_PERMANENT) ? p->skill[i].lv : p->skill[i].flag - SKILL_FLAG_REPLACED_LV_0);
|
|
|
}
|
|
|
*(str_p++) = '\t';
|
|
|
|
|
@@ -1229,7 +1229,7 @@ void mmo_char_sync(void)
|
|
|
//----------------------------------------------------
|
|
|
// Function to save (in a periodic way) datas in files
|
|
|
//----------------------------------------------------
|
|
|
-int mmo_char_sync_timer(int tid, unsigned int tick, int id, intptr data)
|
|
|
+int mmo_char_sync_timer(int tid, unsigned int tick, int id, intptr_t data)
|
|
|
{
|
|
|
if (save_log)
|
|
|
ShowInfo("Saving all files...\n");
|
|
@@ -1782,7 +1782,7 @@ int count_users(void)
|
|
|
int i, users;
|
|
|
|
|
|
users = 0;
|
|
|
- for(i = 0; i < MAX_MAP_SERVERS; i++) {
|
|
|
+ for(i = 0; i < ARRAYLENGTH(server); i++) {
|
|
|
if (server[i].fd > 0) {
|
|
|
users += server[i].users;
|
|
|
}
|
|
@@ -2060,24 +2060,74 @@ static void char_auth_ok(int fd, struct char_session_data *sd)
|
|
|
// continues when account data is received...
|
|
|
}
|
|
|
|
|
|
-int send_accounts_tologin(int tid, unsigned int tick, int id, intptr data);
|
|
|
+int send_accounts_tologin(int tid, unsigned int tick, int id, intptr_t data);
|
|
|
+void mapif_server_reset(int id);
|
|
|
+
|
|
|
+
|
|
|
+/// Resets all the data.
|
|
|
+void loginif_reset(void)
|
|
|
+{
|
|
|
+ int id;
|
|
|
+ // TODO kick everyone out and reset everything or wait for connect and try to reaquire locks [FlavioJS]
|
|
|
+ for( id = 0; id < ARRAYLENGTH(server); ++id )
|
|
|
+ mapif_server_reset(id);
|
|
|
+ flush_fifos();
|
|
|
+ exit(EXIT_FAILURE);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/// Checks the conditions for the server to stop.
|
|
|
+/// If all the conditions are met, it stops the core loop.
|
|
|
+void loginif_check_shutdown(void)
|
|
|
+{
|
|
|
+ if( runflag != CHARSERVER_ST_SHUTDOWN )
|
|
|
+ return;
|
|
|
+ runflag = CORE_ST_STOP;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/// Called when the connection to Login Server is disconnected.
|
|
|
+void loginif_on_disconnect(void)
|
|
|
+{
|
|
|
+ ShowWarning("Connection to Login Server lost.\n\n");
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/// Called when all the connection steps are completed.
|
|
|
+void loginif_on_ready(void)
|
|
|
+{
|
|
|
+ int i;
|
|
|
+
|
|
|
+ loginif_check_shutdown();
|
|
|
+
|
|
|
+ //Send online accounts to login server.
|
|
|
+ send_accounts_tologin(INVALID_TIMER, gettick(), 0, 0);
|
|
|
+
|
|
|
+ // if no map-server already connected, display a message...
|
|
|
+ ARR_FIND( 0, ARRAYLENGTH(server), i, server[i].fd > 0 && server[i].map[0] );
|
|
|
+ if( i == ARRAYLENGTH(server) )
|
|
|
+ ShowStatus("Awaiting maps from map-server.\n");
|
|
|
+}
|
|
|
+
|
|
|
|
|
|
int parse_fromlogin(int fd)
|
|
|
{
|
|
|
+ struct char_session_data* sd = NULL;
|
|
|
int i;
|
|
|
- struct char_session_data *sd;
|
|
|
|
|
|
- // only login-server can have an access to here.
|
|
|
- // so, if it isn't the login-server, we disconnect the session.
|
|
|
+ // only process data from the login-server
|
|
|
if( fd != login_fd )
|
|
|
- set_eof(fd);
|
|
|
+ {
|
|
|
+ ShowDebug("parse_fromlogin: Disconnecting invalid session #%d (is not the login-server)\n", fd);
|
|
|
+ do_close(fd);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
|
|
|
- if(session[fd]->flag.eof) {
|
|
|
- if (fd == login_fd) {
|
|
|
- ShowWarning("Connection to login-server lost (connection #%d).\n", fd);
|
|
|
- login_fd = -1;
|
|
|
- }
|
|
|
+ if( session[fd]->flag.eof )
|
|
|
+ {
|
|
|
do_close(fd);
|
|
|
+ login_fd = -1;
|
|
|
+ loginif_on_disconnect();
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -2101,16 +2151,11 @@ int parse_fromlogin(int fd)
|
|
|
ShowError("The server communication passwords (default s1/p1) are probably invalid.\n");
|
|
|
ShowError("Also, please make sure your accounts file (default: accounts.txt) has the correct communication username/passwords and the gender of the account is S.\n");
|
|
|
ShowError("The communication passwords are set in map_athena.conf and char_athena.conf\n");
|
|
|
+ set_eof(fd);
|
|
|
+ return 0;
|
|
|
} else {
|
|
|
ShowStatus("Connected to login-server (connection #%d).\n", fd);
|
|
|
-
|
|
|
- //Send online accounts to login server.
|
|
|
- send_accounts_tologin(INVALID_TIMER, gettick(), 0, 0);
|
|
|
-
|
|
|
- // if no map-server already connected, display a message...
|
|
|
- ARR_FIND( 0, MAX_MAP_SERVERS, i, server[i].fd > 0 && server[i].map[0] );
|
|
|
- if( i == MAX_MAP_SERVERS )
|
|
|
- ShowStatus("Awaiting maps from map-server.\n");
|
|
|
+ loginif_on_ready();
|
|
|
}
|
|
|
RFIFOSKIP(fd,3);
|
|
|
break;
|
|
@@ -2226,7 +2271,7 @@ int parse_fromlogin(int fd)
|
|
|
}
|
|
|
// remove specifical skills of classes 19, 4020 and 4042
|
|
|
for(j = 315; j <= 322; j++) {
|
|
|
- if (char_dat[i].status.skill[j].id > 0 && !char_dat[i].status.skill[j].flag) {
|
|
|
+ if (char_dat[i].status.skill[j].id > 0 && char_dat[i].status.skill[j].flag == SKILL_FLAG_PERMANENT) {
|
|
|
char_dat[i].status.skill_point += char_dat[i].status.skill[j].lv;
|
|
|
char_dat[i].status.skill[j].id = 0;
|
|
|
char_dat[i].status.skill[j].lv = 0;
|
|
@@ -2234,7 +2279,7 @@ int parse_fromlogin(int fd)
|
|
|
}
|
|
|
// remove specifical skills of classes 20, 4021 and 4043
|
|
|
for(j = 323; j <= 330; j++) {
|
|
|
- if (char_dat[i].status.skill[j].id > 0 && !char_dat[i].status.skill[j].flag) {
|
|
|
+ if (char_dat[i].status.skill[j].id > 0 && char_dat[i].status.skill[j].flag == SKILL_FLAG_PERMANENT) {
|
|
|
char_dat[i].status.skill_point += char_dat[i].status.skill[j].lv;
|
|
|
char_dat[i].status.skill[j].id = 0;
|
|
|
char_dat[i].status.skill[j].lv = 0;
|
|
@@ -2377,6 +2422,34 @@ int parse_fromlogin(int fd)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+int check_connect_login_server(int tid, unsigned int tick, int id, intptr_t data);
|
|
|
+int ping_login_server(int tid, unsigned int tick, int id, intptr_t data);
|
|
|
+int send_accounts_tologin(int tid, unsigned int tick, int id, intptr_t data);
|
|
|
+
|
|
|
+void do_init_loginif(void)
|
|
|
+{
|
|
|
+ // establish char-login connection if not present
|
|
|
+ add_timer_func_list(check_connect_login_server, "check_connect_login_server");
|
|
|
+ add_timer_interval(gettick() + 1000, check_connect_login_server, 0, 0, 10 * 1000);
|
|
|
+
|
|
|
+ // keep the char-login connection alive
|
|
|
+ add_timer_func_list(ping_login_server, "ping_login_server");
|
|
|
+ add_timer_interval(gettick() + 1000, ping_login_server, 0, 0, ((int)stall_time-2) * 1000);
|
|
|
+
|
|
|
+ // send a list of all online account IDs to login server
|
|
|
+ add_timer_func_list(send_accounts_tologin, "send_accounts_tologin");
|
|
|
+ add_timer_interval(gettick() + 1000, send_accounts_tologin, 0, 0, 3600 * 1000); //Sync online accounts every hour
|
|
|
+}
|
|
|
+
|
|
|
+void do_final_loginif(void)
|
|
|
+{
|
|
|
+ if( login_fd != -1 )
|
|
|
+ {
|
|
|
+ do_close(login_fd);
|
|
|
+ login_fd = -1;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
int request_accreg2(int account_id, int char_id)
|
|
|
{
|
|
|
if (login_fd > 0) {
|
|
@@ -2592,36 +2665,76 @@ int char_loadName(int char_id, char* name)
|
|
|
|
|
|
int search_mapserver(unsigned short map, uint32 ip, uint16 port);
|
|
|
|
|
|
+
|
|
|
+/// Initializes a server structure.
|
|
|
+void mapif_server_init(int id)
|
|
|
+{
|
|
|
+ memset(&server[id], 0, sizeof(server[id]));
|
|
|
+ server[id].fd = -1;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/// Destroys a server structure.
|
|
|
+void mapif_server_destroy(int id)
|
|
|
+{
|
|
|
+ if( server[id].fd == -1 )
|
|
|
+ {
|
|
|
+ do_close(server[id].fd);
|
|
|
+ server[id].fd = -1;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/// Resets all the data related to a server.
|
|
|
+void mapif_server_reset(int id)
|
|
|
+{
|
|
|
+ int i,j;
|
|
|
+ unsigned char buf[16384];
|
|
|
+ int fd = server[id].fd;
|
|
|
+ //Notify other map servers that this one is gone. [Skotlex]
|
|
|
+ WBUFW(buf,0) = 0x2b20;
|
|
|
+ WBUFL(buf,4) = htonl(server[id].ip);
|
|
|
+ WBUFW(buf,8) = htons(server[id].port);
|
|
|
+ j = 0;
|
|
|
+ for(i = 0; i < MAX_MAP_PER_SERVER; i++)
|
|
|
+ if (server[id].map[i])
|
|
|
+ WBUFW(buf,10+(j++)*4) = server[id].map[i];
|
|
|
+ if (j > 0) {
|
|
|
+ WBUFW(buf,2) = j * 4 + 10;
|
|
|
+ mapif_sendallwos(fd, buf, WBUFW(buf,2));
|
|
|
+ }
|
|
|
+ online_char_db->foreach(online_char_db,char_db_setoffline,id); //Tag relevant chars as 'in disconnected' server.
|
|
|
+ create_online_files();
|
|
|
+ mapif_server_destroy(id);
|
|
|
+ mapif_server_init(id);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/// Called when the connection to a Map Server is disconnected.
|
|
|
+void mapif_on_disconnect(int id)
|
|
|
+{
|
|
|
+ ShowStatus("Map-server #%d has disconnected.\n", id);
|
|
|
+ mapif_server_reset(id);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
int parse_frommap(int fd)
|
|
|
{
|
|
|
int i, j;
|
|
|
int id;
|
|
|
|
|
|
- ARR_FIND( 0, MAX_MAP_SERVERS, id, server[id].fd == fd );
|
|
|
- if(id == MAX_MAP_SERVERS)
|
|
|
- set_eof(fd);
|
|
|
- if(session[fd]->flag.eof) {
|
|
|
- if (id < MAX_MAP_SERVERS) {
|
|
|
- unsigned char buf[16384];
|
|
|
- ShowStatus("Map-server %d (session #%d) has disconnected.\n", id, fd);
|
|
|
- //Notify other map servers that this one is gone. [Skotlex]
|
|
|
- WBUFW(buf,0) = 0x2b20;
|
|
|
- WBUFL(buf,4) = htonl(server[id].ip);
|
|
|
- WBUFW(buf,8) = htons(server[id].port);
|
|
|
- j = 0;
|
|
|
- for(i = 0; i < MAX_MAP_PER_SERVER; i++)
|
|
|
- if (server[id].map[i])
|
|
|
- WBUFW(buf,10+(j++)*4) = server[id].map[i];
|
|
|
- if (j > 0) {
|
|
|
- WBUFW(buf,2) = j * 4 + 10;
|
|
|
- mapif_sendallwos(fd, buf, WBUFW(buf,2));
|
|
|
- }
|
|
|
- memset(&server[id], 0, sizeof(struct mmo_map_server));
|
|
|
- server[id].fd = -1;
|
|
|
- online_char_db->foreach(online_char_db,char_db_setoffline,id); //Tag relevant chars as 'in disconnected' server.
|
|
|
- }
|
|
|
+ ARR_FIND( 0, ARRAYLENGTH(server), id, server[id].fd == fd );
|
|
|
+ if( id == ARRAYLENGTH(server) )
|
|
|
+ {// not a map server
|
|
|
+ ShowDebug("parse_frommap: Disconnecting invalid session #%d (is not a map-server)\n", fd);
|
|
|
do_close(fd);
|
|
|
- create_online_files();
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ if( session[fd]->flag.eof )
|
|
|
+ {
|
|
|
+ do_close(fd);
|
|
|
+ server[id].fd = -1;
|
|
|
+ mapif_on_disconnect(id);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -2672,14 +2785,14 @@ int parse_frommap(int fd)
|
|
|
mapif_sendallwos(fd, buf, WBUFW(buf,2));
|
|
|
}
|
|
|
// Transmitting the maps of the other map-servers to the new map-server
|
|
|
- for(x = 0; x < MAX_MAP_SERVERS; x++) {
|
|
|
+ for(x = 0; x < ARRAYLENGTH(server); x++) {
|
|
|
if (server[x].fd > 0 && x != id) {
|
|
|
- WFIFOHEAD(fd,10 +4*MAX_MAP_PER_SERVER);
|
|
|
+ WFIFOHEAD(fd,10 +4*ARRAYLENGTH(server));
|
|
|
WFIFOW(fd,0) = 0x2b04;
|
|
|
WFIFOL(fd,4) = htonl(server[x].ip);
|
|
|
WFIFOW(fd,8) = htons(server[x].port);
|
|
|
j = 0;
|
|
|
- for(i = 0; i < MAX_MAP_PER_SERVER; i++)
|
|
|
+ for(i = 0; i < ARRAYLENGTH(server); i++)
|
|
|
if (server[x].map[i])
|
|
|
WFIFOW(fd,10+(j++)*4) = server[x].map[i];
|
|
|
if (j > 0) {
|
|
@@ -2802,26 +2915,37 @@ int parse_frommap(int fd)
|
|
|
uint32 ip = RFIFOL(fd,14);
|
|
|
RFIFOSKIP(fd,18);
|
|
|
|
|
|
- // create temporary auth entry
|
|
|
- CREATE(node, struct auth_node, 1);
|
|
|
- node->account_id = account_id;
|
|
|
- node->char_id = 0;
|
|
|
- node->login_id1 = login_id1;
|
|
|
- node->login_id2 = login_id2;
|
|
|
- //node->sex = 0;
|
|
|
- node->ip = ntohl(ip);
|
|
|
- //node->expiration_time = 0; // unlimited/unknown time by default (not display in map-server)
|
|
|
- //node->gmlevel = 0;
|
|
|
- idb_put(auth_db, account_id, node);
|
|
|
-
|
|
|
- //Set char to "@ char select" in online db [Kevin]
|
|
|
- set_char_charselect(account_id);
|
|
|
-
|
|
|
- WFIFOHEAD(fd,7);
|
|
|
- WFIFOW(fd,0) = 0x2b03;
|
|
|
- WFIFOL(fd,2) = account_id;
|
|
|
- WFIFOB(fd,6) = 0;
|
|
|
- WFIFOSET(fd,7);
|
|
|
+ if( runflag != CHARSERVER_ST_RUNNING )
|
|
|
+ {
|
|
|
+ WFIFOHEAD(fd,7);
|
|
|
+ WFIFOW(fd,0) = 0x2b03;
|
|
|
+ WFIFOL(fd,2) = account_id;
|
|
|
+ WFIFOB(fd,6) = 0;// not ok
|
|
|
+ WFIFOSET(fd,7);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // create temporary auth entry
|
|
|
+ CREATE(node, struct auth_node, 1);
|
|
|
+ node->account_id = account_id;
|
|
|
+ node->char_id = 0;
|
|
|
+ node->login_id1 = login_id1;
|
|
|
+ node->login_id2 = login_id2;
|
|
|
+ //node->sex = 0;
|
|
|
+ node->ip = ntohl(ip);
|
|
|
+ //node->expiration_time = 0; // unlimited/unknown time by default (not display in map-server)
|
|
|
+ //node->gmlevel = 0;
|
|
|
+ idb_put(auth_db, account_id, node);
|
|
|
+
|
|
|
+ //Set char to "@ char select" in online db [Kevin]
|
|
|
+ set_char_charselect(account_id);
|
|
|
+
|
|
|
+ WFIFOHEAD(fd,7);
|
|
|
+ WFIFOW(fd,0) = 0x2b03;
|
|
|
+ WFIFOL(fd,2) = account_id;
|
|
|
+ WFIFOB(fd,6) = 1;// ok
|
|
|
+ WFIFOSET(fd,7);
|
|
|
+ }
|
|
|
}
|
|
|
break;
|
|
|
|
|
@@ -2839,7 +2963,9 @@ int parse_frommap(int fd)
|
|
|
|
|
|
char_data = search_character(RFIFOL(fd,2), RFIFOL(fd,14));
|
|
|
|
|
|
- if (map_fd >= 0 && session[map_fd] && char_data)
|
|
|
+ if( runflag == CHARSERVER_ST_RUNNING &&
|
|
|
+ session_isActive(map_fd) &&
|
|
|
+ char_data )
|
|
|
{ //Send the map server the auth of this player.
|
|
|
struct auth_node* node;
|
|
|
|
|
@@ -3140,7 +3266,9 @@ int parse_frommap(int fd)
|
|
|
|
|
|
node = (struct auth_node*)idb_get(auth_db, account_id);
|
|
|
cd = search_character(account_id, char_id);
|
|
|
- if( node != NULL && cd != NULL &&
|
|
|
+ if( runflag == CHARSERVER_ST_RUNNING &&
|
|
|
+ cd != NULL &&
|
|
|
+ node != NULL &&
|
|
|
node->account_id == account_id &&
|
|
|
node->char_id == char_id &&
|
|
|
node->login_id1 == login_id1 &&
|
|
@@ -3204,13 +3332,27 @@ int parse_frommap(int fd)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+void do_init_mapif(void)
|
|
|
+{
|
|
|
+ int i;
|
|
|
+ for( i = 0; i < ARRAYLENGTH(server); ++i )
|
|
|
+ mapif_server_init(i);
|
|
|
+}
|
|
|
+
|
|
|
+void do_final_mapif(void)
|
|
|
+{
|
|
|
+ int i;
|
|
|
+ for( i = 0; i < ARRAYLENGTH(server); ++i )
|
|
|
+ mapif_server_destroy(i);
|
|
|
+}
|
|
|
+
|
|
|
// Searches for the mapserver that has a given map (and optionally ip/port, if not -1).
|
|
|
// If found, returns the server's index in the 'server' array (otherwise returns -1).
|
|
|
int search_mapserver(unsigned short map, uint32 ip, uint16 port)
|
|
|
{
|
|
|
int i, j;
|
|
|
|
|
|
- for(i = 0; i < MAX_MAP_SERVERS; i++)
|
|
|
+ for(i = 0; i < ARRAYLENGTH(server); i++)
|
|
|
{
|
|
|
if (server[i].fd > 0
|
|
|
&& (ip == (uint32)-1 || server[i].ip == ip)
|
|
@@ -3526,6 +3668,15 @@ int parse_char(int fd)
|
|
|
WFIFOL(fd,0) = account_id;
|
|
|
WFIFOSET(fd,4);
|
|
|
|
|
|
+ if( runflag != CHARSERVER_ST_RUNNING )
|
|
|
+ {
|
|
|
+ WFIFOHEAD(fd,3);
|
|
|
+ WFIFOW(fd,0) = 0x6c;
|
|
|
+ WFIFOB(fd,2) = 0;// rejected from server
|
|
|
+ WFIFOSET(fd,3);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
// search authentification
|
|
|
node = (struct auth_node*)idb_get(auth_db, account_id);
|
|
|
if( node != NULL &&
|
|
@@ -3602,8 +3753,8 @@ int parse_char(int fd)
|
|
|
if (i < 0) {
|
|
|
unsigned short j;
|
|
|
//First check that there's actually a map server online.
|
|
|
- ARR_FIND( 0, MAX_MAP_SERVERS, j, server[j].fd >= 0 && server[j].map[0] );
|
|
|
- if (j == MAX_MAP_SERVERS) {
|
|
|
+ ARR_FIND( 0, ARRAYLENGTH(server), j, server[j].fd >= 0 && server[j].map[0] );
|
|
|
+ if (j == ARRAYLENGTH(server)) {
|
|
|
ShowInfo("Connection Closed. No map servers available.\n");
|
|
|
WFIFOHEAD(fd,3);
|
|
|
WFIFOW(fd,0) = 0x81;
|
|
@@ -3927,8 +4078,12 @@ int parse_char(int fd)
|
|
|
char* l_pass = (char*)RFIFOP(fd,26);
|
|
|
l_user[23] = '\0';
|
|
|
l_pass[23] = '\0';
|
|
|
- ARR_FIND( 0, MAX_MAP_SERVERS, i, server[i].fd <= 0 );
|
|
|
- if (i == MAX_MAP_SERVERS || strcmp(l_user, userid) || strcmp(l_pass, passwd)) {
|
|
|
+ ARR_FIND( 0, ARRAYLENGTH(server), i, server[i].fd <= 0 );
|
|
|
+ if( runflag != CHARSERVER_ST_RUNNING ||
|
|
|
+ i == ARRAYLENGTH(server) ||
|
|
|
+ strcmp(l_user, userid) != 0 ||
|
|
|
+ strcmp(l_pass, passwd) != 0 )
|
|
|
+ {
|
|
|
WFIFOHEAD(fd,3);
|
|
|
WFIFOW(fd,0) = 0x2af9;
|
|
|
WFIFOB(fd,2) = 3;
|
|
@@ -3991,7 +4146,7 @@ int mapif_sendall(unsigned char *buf, unsigned int len)
|
|
|
int i, c;
|
|
|
|
|
|
c = 0;
|
|
|
- for(i = 0; i < MAX_MAP_SERVERS; i++) {
|
|
|
+ for(i = 0; i < ARRAYLENGTH(server); i++) {
|
|
|
int fd;
|
|
|
if ((fd = server[i].fd) > 0) {
|
|
|
WFIFOHEAD(fd,len);
|
|
@@ -4009,7 +4164,7 @@ int mapif_sendallwos(int sfd, unsigned char *buf, unsigned int len)
|
|
|
int i, c;
|
|
|
|
|
|
c = 0;
|
|
|
- for(i = 0; i < MAX_MAP_SERVERS; i++) {
|
|
|
+ for(i = 0; i < ARRAYLENGTH(server); i++) {
|
|
|
int fd;
|
|
|
if ((fd = server[i].fd) > 0 && fd != sfd) {
|
|
|
WFIFOHEAD(fd,len);
|
|
@@ -4027,8 +4182,8 @@ int mapif_send(int fd, unsigned char *buf, unsigned int len)
|
|
|
int i;
|
|
|
|
|
|
if (fd >= 0) {
|
|
|
- ARR_FIND( 0, MAX_MAP_SERVERS, i, fd == server[i].fd );
|
|
|
- if( i < MAX_MAP_SERVERS )
|
|
|
+ ARR_FIND( 0, ARRAYLENGTH(server), i, fd == server[i].fd );
|
|
|
+ if( i < ARRAYLENGTH(server) )
|
|
|
{
|
|
|
WFIFOHEAD(fd,len);
|
|
|
memcpy(WFIFOP(fd,0), buf, len);
|
|
@@ -4039,7 +4194,7 @@ int mapif_send(int fd, unsigned char *buf, unsigned int len)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-int broadcast_user_count(int tid, unsigned int tick, int id, intptr data)
|
|
|
+int broadcast_user_count(int tid, unsigned int tick, int id, intptr_t data)
|
|
|
{
|
|
|
uint8 buf[6];
|
|
|
int users = count_users();
|
|
@@ -4085,7 +4240,7 @@ static int send_accounts_tologin_sub(DBKey key, void* data, va_list ap)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-int send_accounts_tologin(int tid, unsigned int tick, int id, intptr data)
|
|
|
+int send_accounts_tologin(int tid, unsigned int tick, int id, intptr_t data)
|
|
|
{
|
|
|
if (login_fd > 0 && session[login_fd])
|
|
|
{
|
|
@@ -4103,7 +4258,7 @@ int send_accounts_tologin(int tid, unsigned int tick, int id, intptr data)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-int check_connect_login_server(int tid, unsigned int tick, int id, intptr data)
|
|
|
+int check_connect_login_server(int tid, unsigned int tick, int id, intptr_t data)
|
|
|
{
|
|
|
if (login_fd > 0 && session[login_fd] != NULL)
|
|
|
return 0;
|
|
@@ -4136,7 +4291,7 @@ int check_connect_login_server(int tid, unsigned int tick, int id, intptr data)
|
|
|
}
|
|
|
|
|
|
// sends a ping packet to login server (will receive pong 0x2718)
|
|
|
-int ping_login_server(int tid, unsigned int tick, int id, intptr data)
|
|
|
+int ping_login_server(int tid, unsigned int tick, int id, intptr_t data)
|
|
|
{
|
|
|
if (login_fd > 0 && session[login_fd] != NULL)
|
|
|
{
|
|
@@ -4151,7 +4306,7 @@ int ping_login_server(int tid, unsigned int tick, int id, intptr data)
|
|
|
//Invoked 15 seconds after mapif_disconnectplayer in case the map server doesn't
|
|
|
//replies/disconnect the player we tried to kick. [Skotlex]
|
|
|
//------------------------------------------------
|
|
|
-static int chardb_waiting_disconnect(int tid, unsigned int tick, int id, intptr data)
|
|
|
+static int chardb_waiting_disconnect(int tid, unsigned int tick, int id, intptr_t data)
|
|
|
{
|
|
|
struct online_char_data* character;
|
|
|
if ((character = (struct online_char_data*)idb_get(online_char_db, id)) != NULL && character->waiting_disconnect == tid)
|
|
@@ -4175,7 +4330,7 @@ static int online_data_cleanup_sub(DBKey key, void *data, va_list ap)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static int online_data_cleanup(int tid, unsigned int tick, int id, intptr data)
|
|
|
+static int online_data_cleanup(int tid, unsigned int tick, int id, intptr_t data)
|
|
|
{
|
|
|
online_char_db->foreach(online_char_db, online_data_cleanup_sub);
|
|
|
return 0;
|
|
@@ -4431,12 +4586,16 @@ int char_config_read(const char *cfgName)
|
|
|
#ifndef TXT_SQL_CONVERT
|
|
|
void do_final(void)
|
|
|
{
|
|
|
- ShowStatus("Terminating server.\n");
|
|
|
+ ShowStatus("Terminating...\n");
|
|
|
|
|
|
mmo_char_sync();
|
|
|
inter_save();
|
|
|
set_all_offline(-1);
|
|
|
flush_fifos();
|
|
|
+
|
|
|
+ do_final_mapif();
|
|
|
+ do_final_loginif();
|
|
|
+
|
|
|
// write online players files with no player
|
|
|
online_char_db->clear(online_char_db, NULL);
|
|
|
create_online_files();
|
|
@@ -4445,11 +4604,12 @@ void do_final(void)
|
|
|
auth_db->destroy(auth_db, NULL);
|
|
|
|
|
|
if(char_dat) aFree(char_dat);
|
|
|
-
|
|
|
- if (login_fd > 0)
|
|
|
- do_close(login_fd);
|
|
|
- if (char_fd > 0)
|
|
|
+
|
|
|
+ if( char_fd != -1 )
|
|
|
+ {
|
|
|
do_close(char_fd);
|
|
|
+ char_fd = -1;
|
|
|
+ }
|
|
|
|
|
|
#ifdef ENABLE_SC_SAVING
|
|
|
status_final();
|
|
@@ -4458,6 +4618,7 @@ void do_final(void)
|
|
|
mapindex_final();
|
|
|
|
|
|
char_log("----End of char-server (normal end with closing of all files).\n");
|
|
|
+ ShowStatus("Finished.\n");
|
|
|
}
|
|
|
|
|
|
//------------------------------
|
|
@@ -4473,15 +4634,27 @@ void set_server_type(void)
|
|
|
SERVER_TYPE = ATHENA_SERVER_CHAR;
|
|
|
}
|
|
|
|
|
|
-int do_init(int argc, char **argv)
|
|
|
-{
|
|
|
- int i;
|
|
|
|
|
|
- for(i = 0; i < MAX_MAP_SERVERS; i++) {
|
|
|
- memset(&server[i], 0, sizeof(struct mmo_map_server));
|
|
|
- server[i].fd = -1;
|
|
|
+/// Called when a terminate signal is received.
|
|
|
+void do_shutdown(void)
|
|
|
+{
|
|
|
+ if( runflag != CHARSERVER_ST_SHUTDOWN )
|
|
|
+ {
|
|
|
+ int id;
|
|
|
+ runflag = CHARSERVER_ST_SHUTDOWN;
|
|
|
+ ShowStatus("Shutting down...\n");
|
|
|
+ // TODO proper shutdown procedure; wait for acks?, kick all characters, ... [FlavoJS]
|
|
|
+ for( id = 0; id < ARRAYLENGTH(server); ++id )
|
|
|
+ mapif_server_reset(id);
|
|
|
+ loginif_check_shutdown();
|
|
|
+ flush_fifos();
|
|
|
+ runflag = CORE_ST_STOP;
|
|
|
}
|
|
|
+}
|
|
|
|
|
|
+
|
|
|
+int do_init(int argc, char **argv)
|
|
|
+{
|
|
|
//Read map indexes
|
|
|
mapindex_init();
|
|
|
start_point.map = mapindex_name2id("new_zone01");
|
|
@@ -4512,8 +4685,6 @@ int do_init(int argc, char **argv)
|
|
|
inter_init_txt((argc > 2) ? argv[2] : inter_cfgName); // inter server �‰Šú‰»
|
|
|
ShowInfo("char server initialized.\n");
|
|
|
|
|
|
- set_defaultparse(parse_char);
|
|
|
-
|
|
|
if ((naddr_ != 0) && (!login_ip || !char_ip))
|
|
|
{
|
|
|
char ip_str[16];
|
|
@@ -4533,22 +4704,13 @@ int do_init(int argc, char **argv)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // establish char-login connection if not present
|
|
|
- add_timer_func_list(check_connect_login_server, "check_connect_login_server");
|
|
|
- add_timer_interval(gettick() + 1000, check_connect_login_server, 0, 0, 10 * 1000);
|
|
|
-
|
|
|
- // keep the char-login connection alive
|
|
|
- add_timer_func_list(ping_login_server, "ping_login_server");
|
|
|
- add_timer_interval(gettick() + 1000, ping_login_server, 0, 0, ((int)stall_time-2) * 1000);
|
|
|
+ do_init_loginif();
|
|
|
+ do_init_mapif();
|
|
|
|
|
|
// periodically update the overall user count on all mapservers + login server
|
|
|
add_timer_func_list(broadcast_user_count, "broadcast_user_count");
|
|
|
add_timer_interval(gettick() + 1000, broadcast_user_count, 0, 0, 5 * 1000);
|
|
|
|
|
|
- // send a list of all online account IDs to login server
|
|
|
- add_timer_func_list(send_accounts_tologin, "send_accounts_tologin");
|
|
|
- add_timer_interval(gettick() + 1000, send_accounts_tologin, 0, 0, 3600 * 1000); //Sync online accounts every hour
|
|
|
-
|
|
|
// ???
|
|
|
add_timer_func_list(chardb_waiting_disconnect, "chardb_waiting_disconnect");
|
|
|
|
|
@@ -4564,10 +4726,17 @@ int do_init(int argc, char **argv)
|
|
|
{
|
|
|
//##TODO invoke a CONSOLE_START plugin event
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
+ set_defaultparse(parse_char);
|
|
|
char_fd = make_listen_bind(bind_ip, char_port);
|
|
|
char_log("The char-server is ready (Server is listening on the port %d).\n", char_port);
|
|
|
ShowStatus("The char-server is "CL_GREEN"ready"CL_RESET" (Server is listening on the port %d).\n\n", char_port);
|
|
|
+
|
|
|
+ if( runflag != CORE_ST_STOP )
|
|
|
+ {
|
|
|
+ shutdown_callback = do_shutdown;
|
|
|
+ runflag = CHARSERVER_ST_RUNNING;
|
|
|
+ }
|
|
|
|
|
|
return 0;
|
|
|
}
|