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.
This commit is contained in:
lighta 2013-12-06 03:36:51 -05:00
parent edaddfd02d
commit 4f2c1d4eb3
2 changed files with 69 additions and 28 deletions

View File

@ -149,6 +149,7 @@ struct char_session_data {
unsigned int char_moves[MAX_CHARS]; // character moves left unsigned int char_moves[MAX_CHARS]; // character moves left
uint8 isvip; uint8 isvip;
time_t unban_time[MAX_CHARS]; time_t unban_time[MAX_CHARS];
int charblock_timer;
}; };
struct startitem { 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); p.last_point.map = mapindex_name2id(last_map);
sd->found_char[p.slot] = p.char_id; sd->found_char[p.slot] = p.char_id;
if(p.unban_time > time(NULL))
sd->unban_time[p.slot] = p.unban_time; 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);
j += mmo_char_tobuf(WBUFP(buf, j), &p); j += mmo_char_tobuf(WBUFP(buf, j), &p);
// Addon System // Addon System
@ -1954,41 +1952,85 @@ int mmo_char_tobuf(uint8* buffer, struct mmo_charstatus* p)
return 106+offset; return 106+offset;
} }
//---------------------------------------- //----------------------------------------
// Tell client how many pages, kRO sends 17 (Yommy) // Tell client how many pages, kRO sends 17 (Yommy)
//---------------------------------------- //----------------------------------------
void char_charlist_notify( int fd, struct char_session_data* sd ){ void char_charlist_notify( int fd, struct char_session_data* sd ){
int found=0, count=0, i=0;
for(i=0; i<MAX_CHARS; i++){
if(sd->found_char[i] != -1){
found=1;
}
if(i%3 && found){ //each page contains 3char max
count++;
found=0;
}
}
WFIFOHEAD(fd, 6); WFIFOHEAD(fd, 6);
WFIFOW(fd, 0) = 0x9a0; WFIFOW(fd, 0) = 0x9a0;
// pages to req / send them all in 1 until mmo_chars_fromsql can split them up // 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); 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 <PacketLength>.W <TAG_CHARACTER_BLOCK_INFO>24B (HC_BLOCK_CHARACTER) * 0x20d <PacketLength>.W <TAG_CHARACTER_BLOCK_INFO>24B (HC_BLOCK_CHARACTER)
* <GID>L <szExpireDate>20B (TAG_CHARACTER_BLOCK_INFO) * <GID>L <szExpireDate>20B (TAG_CHARACTER_BLOCK_INFO)
*/ */
void char_block_character( int fd, struct char_session_data* sd ){ void char_block_character( int fd, struct char_session_data* sd){
int i=0, len=4; int i=0, j=0, len=4;
time_t now = time(NULL); time_t now = time(NULL);
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); WFIFOHEAD(fd, 4+MAX_CHARS*24);
WFIFOW(fd, 0) = 0x20d; WFIFOW(fd, 0) = 0x20d;
for(i=0; i<MAX_CHARS; i++){ for(i=0; i<MAX_CHARS; i++){
if(sd->found_char[i] == -1)
continue;
if(sd->unban_time[i]){
if( sd->unban_time[i] > now ) { if( sd->unban_time[i] > now ) {
char szExpireDate[21]; 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"); timestamp2string(szExpireDate, 20, sd->unban_time[i], "%Y-%m-%d %H:%M:%S");
memcpy(WFIFOP(fd,8+i*24),szExpireDate,20); 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; len+=24;
j++; //pkt list idx
} }
} }
WFIFOW(fd, 2) = len; //packet len WFIFOW(fd, 2) = len; //packet len
WFIFOSET(fd,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) if (RFIFOREST(fd) < 10+NAME_LENGTH)
return 0; return 0;
else { else {
int aid = RFIFOL(fd,2); //int aid = RFIFOL(fd,2); aid of player who as requested the ban
int timediff = RFIFOL(fd,6); int timediff = RFIFOL(fd,6);
const char* name = (char*)RFIFOP(fd,10); // name of the target character const char* name = (char*)RFIFOP(fd,10); // name of the target character
RFIFOSKIP(fd,10+NAME_LENGTH); RFIFOSKIP(fd,10+NAME_LENGTH);
@ -3006,12 +3048,12 @@ int mapif_parse_reqcharban(int fd){
if( unban_time > now ) { if( unban_time > now ) {
unsigned char buf[11]; unsigned char buf[11];
WBUFW(buf,0) = 0x2b14; WBUFW(buf,0) = 0x2b14;
WBUFL(buf,2) = t_aid; WBUFL(buf,2) = t_cid;
WBUFB(buf,6) = 2; WBUFB(buf,6) = 2;
WBUFL(buf,7) = (unsigned int)unban_time; WBUFL(buf,7) = (unsigned int)unban_time;
mapif_sendall(buf, 11); mapif_sendall(buf, 11);
// disconnect player if online on char-server // disconnect player if online on char-server
disconnect_player(aid); disconnect_player(t_aid);
} }
} }
} }

View File

@ -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] * Disconnection of a player (account has been banned of has a status, from login/char-server) by [Yor]
*------------------------------------------*/ *------------------------------------------*/
int chrif_ban(int fd) { int chrif_ban(int fd) {
int acc, res=0; int id, res=0;
struct map_session_data *sd; 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 res = RFIFOB(fd,6); // 0: change of statut, 1: ban, 2 charban
if ( battle_config.etc_log ) 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 //nothing to do on map if player not connected
return 0; 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 " 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); 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 set_eof(sd->fd); // forced to disconnect for the change
map_quit(sd); // Remove leftovers (e.g. autotrading) [Paradox924X] map_quit(sd); // Remove leftovers (e.g. autotrading) [Paradox924X]