diff options
Diffstat (limited to 'src/char/char.c')
-rw-r--r-- | src/char/char.c | 177 |
1 files changed, 79 insertions, 98 deletions
diff --git a/src/char/char.c b/src/char/char.c index cc6b12d8e..9a251d733 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -157,6 +157,7 @@ static int max_account_id = DEFAULT_MAX_ACCOUNT_ID, max_char_id = DEFAULT_MAX_CH struct online_char_data { int account_id; int char_id; + int fd; short server; unsigned waiting_disconnect :1; }; @@ -289,6 +290,7 @@ static void * create_online_char_data(DBKey key, va_list args) { character->account_id = key.i; character->char_id = -1; character->server = -1; + character->fd = -1; return character; } @@ -1926,6 +1928,52 @@ static int char_delete(struct mmo_charstatus *cs) { return 0; } +static void char_auth_ok(int fd, struct char_session_data *sd) +{ + struct online_char_data* character; + if (max_connect_user && count_users() >= max_connect_user && + isGM(sd->account_id) < gm_allow_level) { + // refuse connection (over populated) + WFIFOW(fd,0) = 0x6c; + WFIFOW(fd,2) = 0; + WFIFOSET(fd,3); + return; + } + + if (online_check && (character = idb_get(online_char_db, sd->account_id))) + { // check if character is not online already. [Skotlex] + if (character->server > -1) + { //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; + WFIFOW(fd,0) = 0x81; + WFIFOB(fd,2) = 8; + WFIFOSET(fd,3); + return; + } + if (character->fd >= 0 && character->fd != fd) + { //There's already a connection from this account that hasn't picked a char yet. + WFIFOW(fd,0) = 0x81; + WFIFOB(fd,2) = 8; + WFIFOSET(fd,3); + return; + } + character->fd = fd; + } + if (login_fd > 0) { + // request to login-server to obtain e-mail/time limit + WFIFOHEAD(login_fd, 6); + WFIFOW(login_fd,0) = 0x2716; + WFIFOL(login_fd,2) = sd->account_id; + WFIFOSET(login_fd,6); + } + // send characters to player + mmo_char_send006b(fd, sd); +} + int send_accounts_tologin(int tid, unsigned int tick, int id, int data); int parse_tologin(int fd) { @@ -1981,38 +2029,23 @@ int parse_tologin(int fd) { case 0x2713: if (RFIFOREST(fd) < 51) return 0; -// printf("parse_tologin 2713 : %d\n", RFIFOB(fd,6)); - for(i = 0; i < fd_max; i++) { - if (session[i] && (sd = (struct char_session_data*)session[i]->session_data) && sd->account_id == RFIFOL(fd,2)) { - if (RFIFOB(fd,6) != 0) { - WFIFOHEAD(i, 3); - WFIFOW(i,0) = 0x6c; - WFIFOB(i,2) = 0x42; - WFIFOSET(i,3); - } else if (max_connect_user == 0 || count_users() < max_connect_user) { -// if (max_connect_user == 0) -// printf("max_connect_user (unlimited) -> accepted.\n"); -// else -// printf("count_users(): %d < max_connect_user (%d) -> accepted.\n", count_users(), max_connect_user); - memcpy(sd->email, RFIFOP(fd, 7), 40); - if (e_mail_check(sd->email) == 0) - strncpy(sd->email, "a@a.com", 40); // default e-mail - sd->connect_until_time = (time_t)RFIFOL(fd,47); - // send characters to player - mmo_char_send006b(i, sd); - } else if(isGM(sd->account_id) >= gm_allow_level) { - sd->connect_until_time = (time_t)RFIFOL(fd,47); - // send characters to player - mmo_char_send006b(i, sd); - } else { - // refuse connection: too much online players -// printf("count_users(): %d < max_connect_use (%d) -> fail...\n", count_users(), max_connect_user); - WFIFOHEAD(i, 3); - WFIFOW(i,0) = 0x6c; - WFIFOW(i,2) = 0; - WFIFOSET(i,3); - } - break; + for(i = 0; i < fd_max && !( + session[i] && + (sd = (struct char_session_data*)session[i]->session_data) && + sd->account_id == RFIFOL(fd,2)) + ; i++); + if (i < fd_max) { + if (RFIFOB(fd,6) != 0) { + WFIFOHEAD(i, 3); + WFIFOW(i,0) = 0x6c; + WFIFOB(i,2) = 0x42; + WFIFOSET(i,3); + } else { + memcpy(sd->email, RFIFOP(fd, 7), 40); + if (e_mail_check(sd->email) == 0) + strncpy(sd->email, "a@a.com", 40); // default e-mail + sd->connect_until_time = (time_t)RFIFOL(fd,47); + char_auth_ok(i, sd); } } RFIFOSKIP(fd,51); @@ -3327,6 +3360,8 @@ int parse_char(int fd) { struct online_char_data* data = idb_get(online_char_db, sd->account_id); if (!data || data->server== -1) //If it is not in any server, send it offline. [Skotlex] set_char_offline(99,sd->account_id); + if (data && data->fd == fd) + data->fd = -1; } do_close(fd); return 0; @@ -3385,74 +3420,20 @@ int parse_char(int fd) { WFIFOL(fd,0) = RFIFOL(fd,2); WFIFOSET(fd,4); // search authentification - for(i = 0; i < AUTH_FIFO_SIZE; i++) { - if (auth_fifo[i].account_id == sd->account_id && - auth_fifo[i].login_id1 == sd->login_id1 && + for(i = 0; i < AUTH_FIFO_SIZE && !( + auth_fifo[i].account_id == sd->account_id && + auth_fifo[i].login_id1 == sd->login_id1 && #if CMP_AUTHFIFO_LOGIN2 != 0 - auth_fifo[i].login_id2 == sd->login_id2 && // relate to the versions higher than 18 + auth_fifo[i].login_id2 == sd->login_id2 && // relate to the versions higher than 18 #endif - (!check_ip_flag || auth_fifo[i].ip == session[fd]->client_addr.sin_addr.s_addr) && - auth_fifo[i].delflag == 2) { - auth_fifo[i].delflag = 1; - - if (online_check) - { // check if character is not online already. [Skotlex] - struct online_char_data* character; - character = idb_get(online_char_db, sd->account_id); - - if (character) - { - 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()+20000, chardb_waiting_disconnect, character->account_id, 0); - character->waiting_disconnect = 1; - /* Not a good idea because this would trigger when you do a char-change from the map server! [Skotlex] - } else { //Manual kick from char server. - struct char_session_data *tsd; - int i; - for(i = 0; i < fd_max; i++) { - if (session[i] && i!=fd && (tsd = (struct char_session_data*)session[i]->session_data) && tsd->account_id == sd->account_id) - { - WFIFOW(i,0) = 0x81; - WFIFOB(i,2) = 2; - WFIFOSET(i,3); - break; - } - } - if (i == fd_max) //Shouldn't happen, but just in case. - set_char_offline(99, sd->account_id); - */ - WFIFOW(fd,0) = 0x81; - WFIFOB(fd,2) = 8; - WFIFOSET(fd,3); - break; - } - } - } - - if (max_connect_user == 0 || count_users() < max_connect_user) { - if (login_fd > 0) { // don't send request if no login-server - // request to login-server to obtain e-mail/time limit - WFIFOHEAD(login_fd, 6); - WFIFOW(login_fd,0) = 0x2716; - WFIFOL(login_fd,2) = sd->account_id; - WFIFOSET(login_fd,6); - } - // send characters to player - mmo_char_send006b(fd, sd); - } else { - // refuse connection (over populated) - WFIFOW(fd,0) = 0x6c; - WFIFOW(fd,2) = 0; - WFIFOSET(fd,3); - } - break; - } - } - // authentification not found - if (i == AUTH_FIFO_SIZE) { + (!check_ip_flag || auth_fifo[i].ip == session[fd]->client_addr.sin_addr.s_addr) && + auth_fifo[i].delflag == 2) + ; i++); + + if (i < AUTH_FIFO_SIZE) { + auth_fifo[i].delflag = 1; + char_auth_ok(fd, sd); + } else { // authentification not found if (login_fd > 0) { // don't send request if no login-server WFIFOHEAD(login_fd,19); WFIFOW(login_fd,0) = 0x2712; // ask login-server to authentify an account |