From 994c3f6cf2e8a1a5b531340df3ab713cf176b854 Mon Sep 17 00:00:00 2001 From: skotlex Date: Fri, 23 Mar 2007 15:58:36 +0000 Subject: - Made waiting_disconnect on the char server be an int to hold the timer ID of the timeout timer. It is now deleted when a player is successfully set offline/online. - Corrected @unjail having the GM level check backwards. - chrif_authok will now reject to store the newly received status data when the player it was received from is still online, should prevent losing data in certain situations. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@10060 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/char/char.c | 33 +++++++++++++++++++++------------ src/char_sql/char.c | 35 ++++++++++++++++++++++------------- src/map/atcommand.c | 2 +- src/map/chrif.c | 11 +++++++++++ 4 files changed, 55 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/char/char.c b/src/char/char.c index 92286bea8..2c4fa32f5 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -157,8 +157,8 @@ struct online_char_data { int account_id; int char_id; int fd; + int waiting_disconnect; short server; - unsigned waiting_disconnect :1; }; struct dbt *online_char_db; //Holds all online characters. @@ -290,6 +290,7 @@ static void * create_online_char_data(DBKey key, va_list args) { character->char_id = -1; character->server = -1; character->fd = -1; + character->waiting_disconnect = -1; return character; } @@ -321,7 +322,10 @@ void set_char_online(int map_id, int char_id, int account_id) { character->account_id, character->char_id, character->server, map_id, account_id, char_id); mapif_disconnectplayer(server_fd[character->server], character->account_id, character->char_id, 2); } - character->waiting_disconnect = 0; + if(character->waiting_disconnect != -1){ + delete_timer(character->waiting_disconnect, chardb_waiting_disconnect); + character->waiting_disconnect = -1; + } character->char_id = (char_id==99)?-1:char_id; character->server = (char_id==99)?-1:map_id; @@ -341,7 +345,10 @@ void set_char_offline(int char_id, int account_id) { { //We don't free yet to avoid aCalloc/aFree spamming during char change. [Skotlex] character->char_id = -1; character->server = -1; - character->waiting_disconnect = 0; + if(character->waiting_disconnect != -1){ + delete_timer(character->waiting_disconnect, chardb_waiting_disconnect); + character->waiting_disconnect = -1; + } } if (login_fd <= 0 || session[login_fd]->eof) return; @@ -358,7 +365,10 @@ static int char_db_setoffline(DBKey key, void* data, va_list ap) { if (server == -1) { character->char_id = -1; character->server = -1; - character->waiting_disconnect = 0; + if(character->waiting_disconnect != -1){ + delete_timer(character->waiting_disconnect, chardb_waiting_disconnect); + character->waiting_disconnect = -1; + } } else if (character->server == server) character->server = -2; //In some map server that we aren't connected to. return 0; @@ -375,7 +385,7 @@ static int char_db_kickoffline(DBKey key, void* data, va_list ap) { if (character->server > -1) mapif_disconnectplayer(server_fd[character->server], character->account_id, character->char_id, 1); - else if (!character->waiting_disconnect) + else if (character->waiting_disconnect == -1) set_char_offline(character->char_id, character->account_id); else return 0; return 1; @@ -1945,9 +1955,8 @@ static void char_auth_ok(int fd, struct char_session_data *sd) { //Character already online. KICK KICK KICK mapif_disconnectplayer(server_fd[character->server], character->account_id, character->char_id, 2); - if (!character->waiting_disconnect) - add_timer(gettick()+20000, chardb_waiting_disconnect, character->account_id, 0); - character->waiting_disconnect = 1; + if (character->waiting_disconnect == -1) + character->waiting_disconnect = add_timer(gettick()+20000, chardb_waiting_disconnect, character->account_id, 0); WFIFOW(fd,0) = 0x81; WFIFOB(fd,2) = 8; WFIFOSET(fd,3); @@ -2438,9 +2447,8 @@ int parse_tologin(int fd) { if (character->server > -1) { //Kick it from the map server it is on. mapif_disconnectplayer(server_fd[character->server], character->account_id, character->char_id, 2); - if (!character->waiting_disconnect) - add_timer(gettick()+15000, chardb_waiting_disconnect, character->account_id, 0); - character->waiting_disconnect = 1; + if (character->waiting_disconnect == -1) + character->waiting_disconnect = add_timer(gettick()+15000, chardb_waiting_disconnect, character->account_id, 0); } else { //Manual kick from char server. struct char_session_data *tsd; int i; @@ -3984,8 +3992,9 @@ int check_connect_login_server(int tid, unsigned int tick, int id, int data) { static int chardb_waiting_disconnect(int tid, unsigned int tick, int id, int data) { struct online_char_data* character; - if ((character = idb_get(online_char_db, id)) != NULL && character->waiting_disconnect) + if ((character = idb_get(online_char_db, id)) != NULL && character->waiting_disconnect == tid) { //Mark it offline due to timeout. + character->waiting_disconnect = -1; set_char_offline(character->char_id, character->account_id); } return 0; diff --git a/src/char_sql/char.c b/src/char_sql/char.c index 4f9ef962f..b9fa206df 100644 --- a/src/char_sql/char.c +++ b/src/char_sql/char.c @@ -179,8 +179,8 @@ struct online_char_data { int account_id; int char_id; int fd; + int waiting_disconnect; short server; - unsigned waiting_disconnect :1; }; struct dbt *online_char_db; //Holds all online characters. @@ -204,6 +204,7 @@ static void * create_online_char_data(DBKey key, va_list args) { character->char_id = -1; character->server = -1; character->fd = -1; + character->waiting_disconnect = -1; return character; } @@ -223,7 +224,7 @@ void set_char_online(int map_id, int char_id, int account_id) { if (max_account_id < account_id || max_char_id < char_id) { //Notify map-server of the new max IDs [Skotlex] if (account_id > max_account_id) - max_account_id = account_id; + max_account_id = account_id; if (char_id > max_char_id) max_char_id = char_id; mapif_send_maxid(max_account_id, max_char_id); @@ -243,7 +244,10 @@ 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; - character->waiting_disconnect = 0; + if(character->waiting_disconnect != -1){ + delete_timer(character->waiting_disconnect, chardb_waiting_disconnect); + character->waiting_disconnect = -1; + } if (char_id != 99) { //Set char online in guild cache. If char is in memory, use the guild id on it, otherwise seek it. struct mmo_charstatus *cp; @@ -284,7 +288,10 @@ void set_char_offline(int char_id, int account_id) { { //We don't free yet to avoid aCalloc/aFree spamming during char change. [Skotlex] character->char_id = -1; character->server = -1; - character->waiting_disconnect = 0; + if(character->waiting_disconnect != -1){ + delete_timer(character->waiting_disconnect, chardb_waiting_disconnect); + character->waiting_disconnect = -1; + } } if (login_fd > 0 && !session[login_fd]->eof) @@ -302,7 +309,10 @@ static int char_db_setoffline(DBKey key, void* data, va_list ap) { if (server == -1) { character->char_id = -1; character->server = -1; - character->waiting_disconnect = 0; + if(character->waiting_disconnect != -1){ + delete_timer(character->waiting_disconnect, chardb_waiting_disconnect); + character->waiting_disconnect = -1; + } } else if (character->server == server) character->server = -2; //In some map server that we aren't connected to. return 0; @@ -318,7 +328,7 @@ static int char_db_kickoffline(DBKey key, void* data, va_list ap) { if (character->server > -1) mapif_disconnectplayer(server_fd[character->server], character->account_id, character->char_id, 1); - else if (!character->waiting_disconnect) + else if (character->waiting_disconnect == -1) set_char_offline(character->char_id, character->account_id); else return 0; return 1; @@ -1805,9 +1815,8 @@ static void char_auth_ok(int fd, struct char_session_data *sd) { //Character already online. KICK KICK KICK mapif_disconnectplayer(server_fd[character->server], character->account_id, character->char_id, 2); - if (!character->waiting_disconnect) - add_timer(gettick()+20000, chardb_waiting_disconnect, character->account_id, 0); - character->waiting_disconnect = 1; + if (character->waiting_disconnect == -1) + character->waiting_disconnect = add_timer(gettick()+20000, chardb_waiting_disconnect, character->account_id, 0); WFIFOW(fd,0) = 0x81; WFIFOB(fd,2) = 8; WFIFOSET(fd,3); @@ -2204,9 +2213,8 @@ int parse_tologin(int fd) { if (character->server > -1) { //Kick it from the map server it is on. mapif_disconnectplayer(server_fd[character->server], character->account_id, character->char_id, 2); - if (!character->waiting_disconnect) - add_timer(gettick()+15000, chardb_waiting_disconnect, character->account_id, 0); - character->waiting_disconnect = 1; + if (character->waiting_disconnect == -1) + character->waiting_disconnect = add_timer(gettick()+15000, chardb_waiting_disconnect, character->account_id, 0); } else { //Manual kick from char server. struct char_session_data *tsd; int i; @@ -3783,8 +3791,9 @@ int check_connect_login_server(int tid, unsigned int tick, int id, int data) { static int chardb_waiting_disconnect(int tid, unsigned int tick, int id, int data) { struct online_char_data* character; - if ((character = idb_get(online_char_db, id)) != NULL && character->waiting_disconnect) + if ((character = idb_get(online_char_db, id)) != NULL && character->waiting_disconnect == tid) { //Mark it offline due to timeout. + character->waiting_disconnect = -1; set_char_offline(character->char_id, character->account_id); } return 0; diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 232b53569..e47deeb25 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -6440,7 +6440,7 @@ int atcommand_charjailtime(const int fd, struct map_session_data* sd, const char clif_displaymessage(fd, msg_txt(3)); // Character not found. return -1; } - if (pc_isGM(pl_sd) < pc_isGM(sd)) { + if (pc_isGM(pl_sd) >= pc_isGM(sd)) { clif_displaymessage(fd, msg_txt(81)); // Your GM level don't authorize you to do this action on this player. return -1; } diff --git a/src/map/chrif.c b/src/map/chrif.c index e19f66126..403cfdcb1 100644 --- a/src/map/chrif.c +++ b/src/map/chrif.c @@ -496,7 +496,18 @@ void chrif_authreq(struct map_session_data *sd) //character selected, insert into auth db void chrif_authok(int fd) { struct auth_node *auth_data; + TBL_PC* sd; RFIFOHEAD(fd); + //Check if we don't already have player data in our server + //(prevents data that is to be saved from being overwritten by + //this received status data if this auth is later successful) [Skotlex] + if ((sd = map_id2sd(RFIFOL(fd, 4))) != NULL) + { + struct mmo_charstatus *status = (struct mmo_charstatus *)RFIFOP(fd, 20); + //Auth check is because this could be the very same sd that is waiting char-server authorization. + if (sd->state.auth && sd->status.char_id == status->char_id) + return; + } if ((auth_data =uidb_get(auth_db, RFIFOL(fd, 4))) != NULL) { //Is the character already awaiting authorization? -- cgit v1.2.3-60-g2f50