From 4f2c1d4eb3943d544aed1b418131f5bf76b2f77e Mon Sep 17 00:00:00 2001 From: lighta Date: Fri, 6 Dec 2013 03:36:51 -0500 Subject: [PATCH] Fix charban, align to Herc model, Add a timered function to refresh block data if you still on charselection waiting for unban (prevent deco reco for refresh) Fix char_charlist_notify (0x9a0) counting page. The previous was quite an ugly estimate. --- src/char/char.c | 84 ++++++++++++++++++++++++++++++++++++------------- src/map/chrif.c | 13 ++++---- 2 files changed, 69 insertions(+), 28 deletions(-) diff --git a/src/char/char.c b/src/char/char.c index 6a5cbb8613..b2506cf078 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -149,6 +149,7 @@ struct char_session_data { unsigned int char_moves[MAX_CHARS]; // character moves left uint8 isvip; time_t unban_time[MAX_CHARS]; + int charblock_timer; }; struct startitem { @@ -1148,10 +1149,7 @@ int mmo_chars_fromsql(struct char_session_data* sd, uint8* buf) { p.last_point.map = mapindex_name2id(last_map); sd->found_char[p.slot] = p.char_id; - if(p.unban_time > time(NULL)) - sd->unban_time[p.slot] = p.unban_time; - else if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `unban_time`='0' WHERE `char_id`='%d' LIMIT 1", char_db, p.char_id) ) - Sql_ShowDebug(sql_handle); + sd->unban_time[p.slot] = p.unban_time; j += mmo_char_tobuf(WBUFP(buf, j), &p); // Addon System @@ -1954,41 +1952,85 @@ int mmo_char_tobuf(uint8* buffer, struct mmo_charstatus* p) return 106+offset; } + + //---------------------------------------- // Tell client how many pages, kRO sends 17 (Yommy) //---------------------------------------- void char_charlist_notify( int fd, struct char_session_data* sd ){ + int found=0, count=0, i=0; + for(i=0; ifound_char[i] != -1){ + found=1; + } + if(i%3 && found){ //each page contains 3char max + count++; + found=0; + } + } + WFIFOHEAD(fd, 6); WFIFOW(fd, 0) = 0x9a0; // pages to req / send them all in 1 until mmo_chars_fromsql can split them up - WFIFOL(fd, 2) = (sd->char_slots>3)?sd->char_slots/3:1; //int TotalCnt (nb page to load) + WFIFOL(fd, 2) = count?count:1; WFIFOSET(fd,6); } +void char_block_character( int fd, struct char_session_data* sd ); +int charblock_timer(int tid, unsigned int tick, int id, intptr_t data) +{ + struct char_session_data* sd=NULL; + int i=0; + ARR_FIND( 0, fd_max, i, session[i] && (sd = (struct char_session_data*)session[i]->session_data) && sd->account_id == id); + + if(sd == NULL || sd->charblock_timer==INVALID_TIMER) //has disconected or was required to stop + return 0; + if (sd->charblock_timer != tid){ + sd->charblock_timer = INVALID_TIMER; + return 0; + } + char_block_character(i,sd); + return 0; +} /* * 0x20d .W 24B (HC_BLOCK_CHARACTER) * L 20B (TAG_CHARACTER_BLOCK_INFO) */ -void char_block_character( int fd, struct char_session_data* sd ){ - int i=0, len=4; +void char_block_character( int fd, struct char_session_data* sd){ + int i=0, j=0, len=4; time_t now = time(NULL); + + WFIFOHEAD(fd, 4+MAX_CHARS*24); + WFIFOW(fd, 0) = 0x20d; - ARR_FIND(0, MAX_CHARS, i, sd->unban_time[i] > now); //should we use MAX_CHARS or sd->charslot - if(i < MAX_CHARS){ - WFIFOHEAD(fd, 4+MAX_CHARS*24); - WFIFOW(fd, 0) = 0x20d; - - for(i=0; ifound_char[i] == -1) + continue; + if(sd->unban_time[i]){ if( sd->unban_time[i] > now ) { char szExpireDate[21]; - WFIFOL(fd, 4+i*24) = sd->found_char[i]; + WFIFOL(fd, 4+j*24) = sd->found_char[i]; timestamp2string(szExpireDate, 20, sd->unban_time[i], "%Y-%m-%d %H:%M:%S"); - memcpy(WFIFOP(fd,8+i*24),szExpireDate,20); - len+=24; + memcpy(WFIFOP(fd,8+j*24),szExpireDate,20); } + else { + WFIFOL(fd, 4+j*24) = 0; + sd->unban_time[i] = 0; + if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `unban_time`='0' WHERE `char_id`='%d' LIMIT 1", char_db, sd->found_char[i]) ) + Sql_ShowDebug(sql_handle); + } + len+=24; + j++; //pkt list idx } - WFIFOW(fd, 2) = len; //packet len - WFIFOSET(fd,len); + } + WFIFOW(fd, 2) = len; //packet len + WFIFOSET(fd,len); + + ARR_FIND(0, MAX_CHARS, i, sd->unban_time[i] > now); //sd->charslot only have productible char + if(i < MAX_CHARS ){ + sd->charblock_timer = add_timer( + gettick() + 10000, // each 10s resend that list + charblock_timer, sd->account_id, 0); } } @@ -2957,7 +2999,7 @@ int mapif_parse_reqcharban(int fd){ if (RFIFOREST(fd) < 10+NAME_LENGTH) return 0; else { - int aid = RFIFOL(fd,2); + //int aid = RFIFOL(fd,2); aid of player who as requested the ban int timediff = RFIFOL(fd,6); const char* name = (char*)RFIFOP(fd,10); // name of the target character RFIFOSKIP(fd,10+NAME_LENGTH); @@ -3006,12 +3048,12 @@ int mapif_parse_reqcharban(int fd){ if( unban_time > now ) { unsigned char buf[11]; WBUFW(buf,0) = 0x2b14; - WBUFL(buf,2) = t_aid; + WBUFL(buf,2) = t_cid; WBUFB(buf,6) = 2; WBUFL(buf,7) = (unsigned int)unban_time; mapif_sendall(buf, 11); // disconnect player if online on char-server - disconnect_player(aid); + disconnect_player(t_aid); } } } diff --git a/src/map/chrif.c b/src/map/chrif.c index e38e881f6a..c3b4b95a68 100644 --- a/src/map/chrif.c +++ b/src/map/chrif.c @@ -1030,18 +1030,19 @@ int chrif_deadopt(int father_id, int mother_id, int child_id) { * Disconnection of a player (account has been banned of has a status, from login/char-server) by [Yor] *------------------------------------------*/ int chrif_ban(int fd) { - int acc, res=0; + int id, res=0; struct map_session_data *sd; - acc = RFIFOL(fd,2); + id = RFIFOL(fd,2); res = RFIFOB(fd,6); // 0: change of statut, 1: ban, 2 charban if ( battle_config.etc_log ) - ShowNotice("chrif_ban %d.type = %s \n", acc, res==1?"account":"char"); + ShowNotice("chrif_ban %d.type = %s \n", id, res==1?"account":"char"); - sd = map_id2sd(acc); + if(res==2) sd = map_charid2sd(id); + else sd = map_id2sd(id); - if ( acc < 0 || sd == NULL ) { + if ( id < 0 || sd == NULL ) { //nothing to do on map if player not connected return 0; } @@ -1064,8 +1065,6 @@ int chrif_ban(int fd) { safesnprintf(tmpstr,sizeof(tmpstr),msg_txt(sd,423),res==2?"char":"account",strtime); //"Your %s has been banished until %s " clif_displaymessage(sd->fd, tmpstr); } - if(res == 2 && !map_charid2sd(sd->status.char_id)) //only disconect if char is online - return 0; set_eof(sd->fd); // forced to disconnect for the change map_quit(sd); // Remove leftovers (e.g. autotrading) [Paradox924X]