From e153b614bd6c3cfb85528ce847fdcb353fe31020 Mon Sep 17 00:00:00 2001 From: shennetsind Date: Mon, 30 Dec 2013 13:18:55 -0200 Subject: Fixed account expiration time Login server no longer insta-denies expired accounts, as there may be free to play (or non paying) char server modes in the list, also made sure type 3 is sent as normal mode to non-expired accounts (client has a hardcoded if type == 3 => "claim need to pay & deny message" Special Thanks to Beret. Signed-off-by: shennetsind --- conf/char-server.conf | 2 +- src/char/char.c | 22 ++++++++++++++++++++-- src/common/mmo.h | 2 +- src/login/login.c | 25 +++++++++++++++---------- src/login/login.h | 2 ++ 5 files changed, 39 insertions(+), 14 deletions(-) diff --git a/conf/char-server.conf b/conf/char-server.conf index cbba2fe0b..4ff2a3398 100644 --- a/conf/char-server.conf +++ b/conf/char-server.conf @@ -64,7 +64,7 @@ console_silent: 0 // Type of server. // No functional side effects at the moment. // Displayed next to the server name in the client. -// 0=normal, 1=maintenance, 2=over 18, 3=paying, 4=P2P +// 0=normal, 1=maintenance, 2=over 18, 3=paying, 4=F2P char_server_type: 0 // Minimum Group ID to join char server when it is on char_server_type 1 (maintenance) diff --git a/src/char/char.c b/src/char/char.c index 8d7ff1ab4..82206cbd9 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -2270,7 +2270,7 @@ int parse_fromlogin(int fd) { // acknowledgement of account authentication request case 0x2713: - if (RFIFOREST(fd) < 29) + if (RFIFOREST(fd) < 33) return 0; { int account_id = RFIFOL(fd,2); @@ -2282,7 +2282,8 @@ int parse_fromlogin(int fd) { uint32 version = RFIFOL(fd,20); uint8 clienttype = RFIFOB(fd,24); int group_id = RFIFOL(fd,25); - RFIFOSKIP(fd,29); + unsigned int expiration_time = RFIFOL(fd, 29); + RFIFOSKIP(fd,33); if( session_isActive(request_id) && (sd=(struct char_session_data*)session[request_id]->session_data) && !sd->auth && sd->account_id == account_id && sd->login_id1 == login_id1 && sd->login_id2 == login_id2 && sd->sex == sex ) @@ -2300,6 +2301,14 @@ int parse_fromlogin(int fd) { WFIFOSET(client_fd,3); break; } + /* the client will already deny this request, this check is to avoid someone bypassing. */ + if( char_server_type == CST_PAYING && (time_t)expiration_time < time(NULL) ) { + WFIFOHEAD(client_fd,3); + WFIFOW(client_fd,0) = 0x6c; + WFIFOB(client_fd,2) = 0;// rejected from server + WFIFOSET(client_fd,3); + break; + } char_auth_ok(client_fd, sd); break; case 1:// auth failed @@ -3070,6 +3079,7 @@ int parse_frommap(int fd) node->login_id2 = login_id2; //node->sex = 0; node->ip = ntohl(ip); + /* sounds troublesome. */ //node->expiration_time = 0; // unlimited/unknown time by default (not display in map-server) //node->gmlevel = 0; idb_put(auth_db, account_id, node); @@ -4004,6 +4014,14 @@ int parse_char(int fd) WFIFOSET(fd,3); break; } + /* the client will already deny this request, this check is to avoid someone bypassing. */ + if( char_server_type == CST_PAYING && (time_t)node->expiration_time < time(NULL) ) { + WFIFOHEAD(fd,3); + WFIFOW(fd,0) = 0x6c; + WFIFOB(fd,2) = 0;// rejected from server + WFIFOSET(fd,3); + break; + } idb_remove(auth_db, account_id); char_auth_ok(fd, sd); } diff --git a/src/common/mmo.h b/src/common/mmo.h index bd5da6a9f..273edc42b 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -863,7 +863,7 @@ enum e_char_server_type { CST_MAINTENANCE = 1, CST_OVER18 = 2, CST_PAYING = 3, - CST_P2P = 4, + CST_F2P = 4, }; /* packet size constant for itemlist */ diff --git a/src/login/login.c b/src/login/login.c index feed7239b..57a2d0b74 100644 --- a/src/login/login.c +++ b/src/login/login.c @@ -67,6 +67,7 @@ struct auth_node { uint32 version; uint8 clienttype; int group_id; + time_t expiration_time; }; static DBMap* auth_db; // int account_id -> struct auth_node* @@ -398,7 +399,7 @@ int parse_fromchar(int fd) //ShowStatus("Char-server '%s': authentication of the account %d accepted (ip: %s).\n", server[id].name, account_id, ip); // send ack - WFIFOHEAD(fd,29); + WFIFOHEAD(fd,33); WFIFOW(fd,0) = 0x2713; WFIFOL(fd,2) = account_id; WFIFOL(fd,6) = login_id1; @@ -409,7 +410,8 @@ int parse_fromchar(int fd) WFIFOL(fd,20) = node->version; WFIFOB(fd,24) = node->clienttype; WFIFOL(fd,25) = node->group_id; - WFIFOSET(fd,29); + WFIFOL(fd,29) = (unsigned int)node->expiration_time; + WFIFOSET(fd,33); // each auth entry can only be used once idb_remove(auth_db, account_id); @@ -417,7 +419,7 @@ int parse_fromchar(int fd) else {// authentication not found ShowStatus("Char-server '%s': authentication of the account %d REFUSED (ip: %s).\n", server[id].name, account_id, ip); - WFIFOHEAD(fd,29); + WFIFOHEAD(fd,33); WFIFOW(fd,0) = 0x2713; WFIFOL(fd,2) = account_id; WFIFOL(fd,6) = login_id1; @@ -428,7 +430,8 @@ int parse_fromchar(int fd) WFIFOL(fd,20) = 0; WFIFOB(fd,24) = 0; WFIFOL(fd,25) = 0; - WFIFOSET(fd,29); + WFIFOL(fd,29) = 0; + WFIFOSET(fd,33); } } break; @@ -1006,11 +1009,6 @@ int mmo_auth(struct login_session_data* sd, bool isServer) { return 1; // 1 = Incorrect Password } - if( acc.expiration_time != 0 && acc.expiration_time < time(NULL) ) { - ShowNotice("Connection refused (account: %s, pass: %s, expired ID, ip: %s)\n", sd->userid, sd->passwd, ip); - return 2; // 2 = This ID is expired - } - if( acc.unban_time != 0 && acc.unban_time > time(NULL) ) { char tmpstr[24]; timestamp2string(tmpstr, sizeof(tmpstr), acc.unban_time, login_config.date_format); @@ -1062,6 +1060,7 @@ int mmo_auth(struct login_session_data* sd, bool isServer) { safestrncpy(sd->lastlogin, acc.lastlogin, sizeof(sd->lastlogin)); sd->sex = acc.sex; sd->group_id = (uint8)acc.group_id; + sd->expiration_time = acc.expiration_time; // update account data timestamp2string(acc.lastlogin, sizeof(acc.lastlogin), time(NULL), "%Y-%m-%d %H:%M:%S"); @@ -1183,7 +1182,12 @@ void login_auth_ok(struct login_session_data* sd) WFIFOW(fd,47+n*32+4) = ntows(htons(server[i].port)); // [!] LE byte order here [!] memcpy(WFIFOP(fd,47+n*32+6), server[i].name, 20); WFIFOW(fd,47+n*32+26) = server[i].users; - WFIFOW(fd,47+n*32+28) = server[i].type; + + if( server[i].type == CST_PAYING && sd->expiration_time > time(NULL) ) + WFIFOW(fd,47+n*32+28) = CST_NORMAL; + else + WFIFOW(fd,47+n*32+28) = server[i].type; + WFIFOW(fd,47+n*32+30) = server[i].new_; n++; } @@ -1199,6 +1203,7 @@ void login_auth_ok(struct login_session_data* sd) node->version = sd->version; node->clienttype = sd->clienttype; node->group_id = sd->group_id; + node->expiration_time = sd->expiration_time; idb_put(auth_db, sd->account_id, node); { diff --git a/src/login/login.h b/src/login/login.h index 494912698..80cbee74b 100644 --- a/src/login/login.h +++ b/src/login/login.h @@ -42,6 +42,8 @@ struct login_session_data { int has_client_hash; int fd; + + time_t expiration_time; }; struct mmo_char_server { -- cgit v1.2.3-60-g2f50