summaryrefslogtreecommitdiff
path: root/src/char/char.c
diff options
context:
space:
mode:
authorultramage <ultramage@54d463be-8e91-2dee-dedb-b68131a5f0ec>2007-11-09 21:44:29 +0000
committerultramage <ultramage@54d463be-8e91-2dee-dedb-b68131a5f0ec>2007-11-09 21:44:29 +0000
commitb397f7c6615f68f044100168eeaf157f6c60227c (patch)
tree5842a6059f35ec329fedc8970e4151ace6f3ec71 /src/char/char.c
parent5b05a6ab3e2831fcf3a4fc68f746dc29edff6339 (diff)
downloadhercules-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/char.c')
-rw-r--r--src/char/char.c127
1 files changed, 82 insertions, 45 deletions
diff --git a/src/char/char.c b/src/char/char.c
index 0e7d5782d..f7881a33b 100644
--- a/src/char/char.c
+++ b/src/char/char.c
@@ -172,8 +172,6 @@ struct online_char_data {
// Holds all online characters.
static DBMap* online_char_db; // int account_id -> struct online_char_data*
-time_t update_online; // to update online files when we receiving information from a server (not less than 8 seconds)
-
int console = 0;
//------------------------------
@@ -344,6 +342,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;
@@ -363,6 +364,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){
@@ -2305,7 +2309,6 @@ int parse_fromlogin(int fd)
}
ShowStatus("From login-server: receiving information of %d GM accounts.\n", GM_num);
char_log("From login-server: receiving information of %d GM accounts.\n", GM_num);
- create_online_files(); // update online players files (perhaps some online players change of GM level)
// send new gm acccounts level to map-servers
memcpy(buf, RFIFOP(fd,0), RFIFOW(fd,2));
WBUFW(buf,0) = 0x2b15;
@@ -2639,10 +2642,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 (login_fd > 0) { // don't send request if no login-server
WFIFOHEAD(login_fd,2);
@@ -2672,10 +2671,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.
@@ -2774,11 +2774,6 @@ int parse_frommap(int fd)
character->char_id = cid;
character->server = id;
}
- if (update_online < time(NULL)) { // Time is done
- update_online = time(NULL) + 8;
- create_online_files(); // only every 8 sec. (normally, 1 server send users every 5 sec.) Don't update every time, because that takes time, but only every 2 connection.
- // it set to 8 sec because is more than 5 (sec) and if we have more than 1 map-server, informations can be received in shifted.
- }
//If any chars remain in -2, they will be cleaned in the cleanup timer.
RFIFOSKIP(fd,6+i*8);
break;
@@ -3033,8 +3028,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;
@@ -3147,6 +3140,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));
@@ -3783,22 +3783,33 @@ 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);
+
+ // refresh online files (txt and html)
+ create_online_files();
return 0;
}
@@ -3868,6 +3879,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]
@@ -3883,6 +3906,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]
@@ -3931,10 +3971,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;
}
@@ -4181,23 +4221,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;
@@ -4258,18 +4281,32 @@ 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, online_data_cleanup, 0, 0, 600 * 1000);
+
+ // periodic flush of all saved data to disk
add_timer_func_list(mmo_char_sync_timer, "mmo_char_sync_timer");
-
- 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_interval(gettick() + autosave_interval, mmo_char_sync_timer, 0, 0, autosave_interval);
+ add_timer_interval(gettick() + 1000, mmo_char_sync_timer, 0, 0, autosave_interval);
if( console )
{