diff options
Diffstat (limited to 'src/char/char.c')
-rw-r--r-- | src/char/char.c | 55 |
1 files changed, 47 insertions, 8 deletions
diff --git a/src/char/char.c b/src/char/char.c index 8d7ff1ab4..9b3f1443d 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -500,7 +500,7 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p) strcat(save_status, " status"); } - if( p->bank_vault != cp->bank_vault || p->mod_exp != cp->mod_exp || p->mod_drop != cp->mod_drop || p->mod_death != p->mod_death ) { + if( p->bank_vault != cp->bank_vault || p->mod_exp != cp->mod_exp || p->mod_drop != cp->mod_drop || p->mod_death != cp->mod_death ) { if( SQL_ERROR == SQL->Query(sql_handle, "REPLACE INTO `%s` (`account_id`,`bank_vault`,`base_exp`,`base_drop`,`base_death`) VALUES ('%d','%d','%d','%d','%d')",account_data_db,p->account_id,p->bank_vault,p->mod_exp,p->mod_drop,p->mod_death) ) { Sql_ShowDebug(sql_handle); errors++; @@ -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); @@ -3493,14 +3503,14 @@ int parse_frommap(int fd) break; case 0x2b26: // auth request from map-server - if (RFIFOREST(fd) < 19) + if (RFIFOREST(fd) < 20) return 0; { int account_id; int char_id; int login_id1; - char sex; + char sex, standalone; uint32 ip; struct auth_node* node; struct mmo_charstatus* cd; @@ -3511,15 +3521,36 @@ int parse_frommap(int fd) login_id1 = RFIFOL(fd,10); sex = RFIFOB(fd,14); ip = ntohl(RFIFOL(fd,15)); - RFIFOSKIP(fd,19); + standalone = RFIFOB(fd, 19); + RFIFOSKIP(fd,20); node = (struct auth_node*)idb_get(auth_db, account_id); cd = (struct mmo_charstatus*)uidb_get(char_db_,char_id); - if( cd == NULL ) - { //Really shouldn't happen. + + if( cd == NULL ) { //Really shouldn't happen. mmo_char_fromsql(char_id, &char_dat, true); cd = (struct mmo_charstatus*)uidb_get(char_db_,char_id); } + + if( runflag == CHARSERVER_ST_RUNNING && cd && standalone ) { + cd->sex = sex; + + WFIFOHEAD(fd,25 + sizeof(struct mmo_charstatus)); + WFIFOW(fd,0) = 0x2afd; + WFIFOW(fd,2) = 25 + sizeof(struct mmo_charstatus); + WFIFOL(fd,4) = account_id; + WFIFOL(fd,8) = 0; + WFIFOL(fd,12) = 0; + WFIFOL(fd,16) = 0; + WFIFOL(fd,20) = 0; + WFIFOB(fd,24) = 0; + memcpy(WFIFOP(fd,25), cd, sizeof(struct mmo_charstatus)); + WFIFOSET(fd, WFIFOW(fd,2)); + + set_char_online(id, char_id, account_id); + break; + } + if( runflag == CHARSERVER_ST_RUNNING && cd != NULL && node != NULL && @@ -4004,6 +4035,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); } |