summaryrefslogtreecommitdiff
path: root/src/char_sql/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_sql/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_sql/char.c')
-rw-r--r--src/char_sql/char.c112
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 )
{