diff options
author | ultramage <ultramage@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2007-11-09 21:44:29 +0000 |
---|---|---|
committer | ultramage <ultramage@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2007-11-09 21:44:29 +0000 |
commit | b397f7c6615f68f044100168eeaf157f6c60227c (patch) | |
tree | 5842a6059f35ec329fedc8970e4151ace6f3ec71 /src/char_sql/char.c | |
parent | 5b05a6ab3e2831fcf3a4fc68f746dc29edff6339 (diff) | |
download | hercules-b397f7c6615f68f044100168eeaf157f6c60227c.tar.gz hercules-b397f7c6615f68f044100168eeaf157f6c60227c.tar.bz2 hercules-b397f7c6615f68f044100168eeaf157f6c60227c.tar.xz hercules-b397f7c6615f68f044100168eeaf157f6c60227c.zip |
* Re-worked the login-char-map packet spam mechanism
- mapserver no longer sends entire user list to charserver every 10 seconds; similar change done to the char-login connection
- user count updates are only sent when the value actually changes instead of servers polling each other every few seconds
- the servers now prevent interserver connection timeout explicitly by sending ping/ack packet pairs instead of relying on the usercount polling to do so; keepalive is sent every 'stall_time'-2 seconds
- removed the @refreshonline command as refresh happens automatically every 5 seconds
git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@11703 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src/char_sql/char.c')
-rw-r--r-- | src/char_sql/char.c | 112 |
1 files changed, 76 insertions, 36 deletions
diff --git a/src/char_sql/char.c b/src/char_sql/char.c index 89f31e2c1..e48ecc9e4 100644 --- a/src/char_sql/char.c +++ b/src/char_sql/char.c @@ -246,6 +246,9 @@ void set_char_online(int map_id, int char_id, int account_id) character->char_id = (char_id==99)?-1:char_id; character->server = (char_id==99)?-1:map_id; + if( character->server > -1 ) + server[character->server].users++; + if(character->waiting_disconnect != -1) { delete_timer(character->waiting_disconnect, chardb_waiting_disconnect); character->waiting_disconnect = -1; @@ -289,6 +292,9 @@ void set_char_offline(int char_id, int account_id) if ((character = idb_get(online_char_db, account_id)) != NULL) { //We don't free yet to avoid aCalloc/aFree spamming during char change. [Skotlex] + if( character->server > -1 ) + server[character->server].users--; + character->char_id = -1; character->server = -1; if(character->waiting_disconnect != -1){ @@ -2098,10 +2104,6 @@ int parse_frommap(int fd) switch(RFIFOW(fd, 0)) { - case 0x2718: // map-server alive packet - RFIFOSKIP(fd,2); - break; - case 0x2af7: // request from map-server to reload GM accounts. Transmission to login-server if(char_gm_read) //Re-read gm accounts. read_gm_account(); @@ -2132,10 +2134,11 @@ int parse_frommap(int fd) if (max_account_id != DEFAULT_MAX_ACCOUNT_ID || max_char_id != DEFAULT_MAX_CHAR_ID) mapif_send_maxid(max_account_id, max_char_id); //Send the current max ids to the server to keep in sync [Skotlex] + // send name for wisp to player WFIFOHEAD(fd, 3 + NAME_LENGTH); WFIFOW(fd,0) = 0x2afb; WFIFOB(fd,2) = 0; - memcpy(WFIFOP(fd,3), wisp_server_name, NAME_LENGTH); // name for wisp to player + memcpy(WFIFOP(fd,3), wisp_server_name, NAME_LENGTH); WFIFOSET(fd,3+NAME_LENGTH); char_send_fame_list(fd); //Send fame list. @@ -2519,8 +2522,6 @@ int parse_frommap(int fd) } break; -// case 0x2b0f: Not used anymore, available for future use - case 0x2b10: // Update and send fame ranking list if (RFIFOREST(fd) < 11) return 0; @@ -2657,6 +2658,13 @@ int parse_frommap(int fd) } break; + case 0x2b23: // map-server alive packet + WFIFOHEAD(fd,2); + WFIFOW(fd,0) = 0x2b24; + WFIFOSET(fd,2); + RFIFOSKIP(fd,2); + break; + case 0x2736: // ip address update if (RFIFOREST(fd) < 6) return 0; server[id].ip = ntohl(RFIFOL(fd, 2)); @@ -3266,22 +3274,30 @@ int mapif_send(int fd, unsigned char *buf, unsigned int len) return 0; } -int send_users_tologin(int tid, unsigned int tick, int id, int data) +int broadcast_user_count(int tid, unsigned int tick, int id, int data) { + uint8 buf[6]; int users = count_users(); - unsigned char buf[16]; - if (login_fd > 0 && session[login_fd]) { + // only send an update when needed + static prev_users = 0; + if( prev_users == users ) + return 0; + prev_users = users; + + if( login_fd > 0 && session[login_fd] ) + { // send number of user to login server WFIFOHEAD(login_fd,6); WFIFOW(login_fd,0) = 0x2714; WFIFOL(login_fd,2) = users; WFIFOSET(login_fd,6); } + // send number of players to all map-servers WBUFW(buf,0) = 0x2b00; WBUFL(buf,2) = users; - mapif_sendall(buf, 6); + mapif_sendall(buf,6); return 0; } @@ -3351,6 +3367,18 @@ int check_connect_login_server(int tid, unsigned int tick, int id, int data) return 1; } +// sends a ping packet to login server (will receive pong 0x2718) +int ping_login_server(int tid, unsigned int tick, int id, int data) +{ + if (login_fd > 0 && session[login_fd] != NULL) + { + WFIFOHEAD(login_fd,2); + WFIFOW(login_fd,0) = 0x2719; + WFIFOSET(login_fd,2); + } + return 0; +} + //------------------------------------------------ //Invoked 15 seconds after mapif_disconnectplayer in case the map server doesn't //replies/disconnect the player we tried to kick. [Skotlex] @@ -3366,6 +3394,23 @@ static int chardb_waiting_disconnect(int tid, unsigned int tick, int id, int dat return 0; } +static int online_data_cleanup_sub(DBKey key, void *data, va_list ap) +{ + struct online_char_data *character= (struct online_char_data*)data; + if (character->server == -2) //Unknown server.. set them offline + set_char_offline(character->char_id, character->account_id); + if (character->server < 0) + //Free data from players that have not been online for a while. + db_remove(online_char_db, key); + return 0; +} + +static int online_data_cleanup(int tid, unsigned int tick, int id, int data) +{ + online_char_db->foreach(online_char_db, online_data_cleanup_sub); + return 0; +} + //---------------------------------- // Reading Lan Support configuration // Rewrote: Anvanced subnet check [LuzZza] @@ -3414,10 +3459,10 @@ int char_lan_config_read(const char *lancfgName) subnet_count++; } - - ShowStatus("Read information about %d subnetworks.\n", subnet_count); } + ShowStatus("Read information about %d subnetworks.\n", subnet_count); + fclose(fp); return 0; } @@ -3726,23 +3771,6 @@ void set_server_type(void) SERVER_TYPE = ATHENA_SERVER_CHAR; } -static int online_data_cleanup_sub(DBKey key, void *data, va_list ap) -{ - struct online_char_data *character= (struct online_char_data*)data; - if (character->server == -2) //Unknown server.. set them offline - set_char_offline(character->char_id, character->account_id); - if (character->server < 0) - //Free data from players that have not been online for a while. - db_remove(online_char_db, key); - return 0; -} - -static int online_data_cleanup(int tid, unsigned int tick, int id, int data) -{ - online_char_db->foreach(online_char_db, online_data_cleanup_sub); - return 0; -} - int do_init(int argc, char **argv) { int i; @@ -3800,16 +3828,28 @@ 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_func_list(send_users_tologin, "send_users_tologin"); + 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); + + // 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"); - add_timer_func_list(online_data_cleanup, "online_data_cleanup"); - add_timer_interval(gettick() + 1000, check_connect_login_server, 0, 0, 10*1000); - add_timer_interval(gettick() + 1000, send_users_tologin, 0, 0, 5*1000); - add_timer_interval(gettick() + 3600*1000, send_accounts_tologin, 0, 0, 3600*1000); //Sync online accounts every hour. - add_timer_interval(gettick() + 600*1000, online_data_cleanup, 0, 0, 600*1000); + // ??? + add_timer_func_list(online_data_cleanup, "online_data_cleanup"); + add_timer_interval(gettick() + 1000, online_data_cleanup, 0, 0, 600 * 1000); if( console ) { |