From cb1131db4cde40c0352e6c75069defab06128c93 Mon Sep 17 00:00:00 2001 From: FlavioJS Date: Mon, 28 May 2007 18:25:32 +0000 Subject: * RFIFOREST returns 0 when the session is eof (input data is implicitly discarted). * Reworked the player fame update: - would crash if an invalid pos was received - the wrong player could be updated on certain conditions git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@10640 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/char/char.c | 107 +++++++++++++++++++++++++++++----------------------- src/char_sql/char.c | 97 ++++++++++++++++++++++++++--------------------- src/common/socket.h | 2 +- src/map/chrif.c | 3 +- 4 files changed, 114 insertions(+), 95 deletions(-) (limited to 'src') diff --git a/src/char/char.c b/src/char/char.c index a6db79ebb..9d02641da 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -3104,68 +3104,79 @@ int parse_frommap(int fd) // case 0x2b0f: Not used anymore, available for future use case 0x2b10: // Update and send fame ranking list - if (RFIFOREST(fd) < 12) + if (RFIFOREST(fd) < 11) return 0; { int cid = RFIFOL(fd, 2); int fame = RFIFOL(fd, 6); char type = RFIFOB(fd, 10); - char pos = RFIFOB(fd, 11); int size; struct fame_list *list = NULL; - switch(type) { - case 1: - size = fame_list_size_smith; - list = smith_fame_list; - break; - case 2: - size = fame_list_size_chemist; - list = chemist_fame_list; - break; - case 3: - size = fame_list_size_taekwon; - list = taekwon_fame_list; - break; - default: - size = 0; - break; + switch(type) + { + case 1 : size = fame_list_size_smith; list = smith_fame_list; break; + case 2 : size = fame_list_size_chemist; list = chemist_fame_list; break; + case 3 : size = fame_list_size_taekwon; list = taekwon_fame_list; break; + default: size = 0; break; } - if(!size) break; //No list. - if(pos) + if( size == 0 ) + break;// No list + for( i = 0; i < size; ++i ) { - pos--; //Convert from pos to index. - if( - (pos == 0 || fame < list[pos-1].fame) && - (pos == size-1 || fame > list[pos+1].fame) - ) { //No change in order. - list[(int)pos].fame = fame; - char_update_fame_list(type, pos, fame); - break; + if( list[i].id != cid ) + continue; + // player found, update position + if( i > 0 && fame >= list[i - 1].fame ) + {// moved up + struct fame_list entry; + int t; + for( t = 0; fame < list[t].fame ; ++t ) + ;// get target position (always < i) + memcpy(&entry, &list[i], sizeof(struct fame_list)); + entry.fame = fame; + memmove(&list[t + 1], &list[t], (t - i)*sizeof(struct fame_list)); + memcpy(&list[t], &entry, sizeof(struct fame_list)); + char_send_fame_list(-1); } - // If the player's already in the list, remove the entry and shift the following ones 1 step up - memmove(list+pos, list+pos+1, (size-pos-1) * sizeof(struct fame_list)); - //Clear out last entry. - list[size-1].id = 0; - list[size-1].fame = 0; + else if( i < size - 1 && fame < list[i + 1].fame ) + {// moved down - always stays in the list + struct fame_list entry; + int t; + for( t = i + 2; t < size && fame < list[t].fame ; ++t ) + ;// get target position + --t; + memcpy(&entry, &list[i], sizeof(struct fame_list)); + entry.fame = fame; + memmove(&list[i], &list[i + 1], (t - i)*sizeof(struct fame_list)); + memcpy(&list[t], &entry, sizeof(struct fame_list)); + char_send_fame_list(-1); + } + else + {// same position + list[i].fame = fame; + char_update_fame_list(type, i, fame); + } + break; } - // Find the position where the player has to be inserted - for(i = 0; i < size && fame < list[i].fame; i++); - if(i >= size) break; //Out of ranking. - // When found someone with less or as much fame, insert just above - memmove(list+i+1, list+i, (size-i-1) * sizeof(struct fame_list)); - list[i].id = cid; - list[i].fame = fame; - // Look for the player's name - for(j = 0; j < char_num && char_dat[j].status.char_id != id; j++); - if(j < char_num) - strncpy(list[i].name, char_dat[j].status.name, NAME_LENGTH); - else //Not found?? - strncpy(list[i].name, "Unknown", NAME_LENGTH); - char_send_fame_list(-1); + if( i == size && fame >= list[size - 1].fame ) + {// not on list and has enough fame + size_t j; + for( i = 0; fame < list[i].fame; ++i ) + ;// get target position + list[i].id = cid; + list[i].fame = fame; + for( j = 0; j < char_num && char_dat[j].status.char_id != cid; ++j ) + ;// find char + if( j < char_num ) + strncpy(list[i].name, char_dat[j].status.name, NAME_LENGTH); + else + strncpy(list[i].name, "Unknown", NAME_LENGTH); + char_send_fame_list(-1); + } - RFIFOSKIP(fd,12); + RFIFOSKIP(fd,11); } break; diff --git a/src/char_sql/char.c b/src/char_sql/char.c index ce09c43dd..6dba28992 100644 --- a/src/char_sql/char.c +++ b/src/char_sql/char.c @@ -2816,64 +2816,73 @@ int parse_frommap(int fd) // case 0x2b0f: Not used anymore, available for future use case 0x2b10: // Update and send fame ranking list - if (RFIFOREST(fd) < 12) + if (RFIFOREST(fd) < 11) return 0; { int cid = RFIFOL(fd, 2); int fame = RFIFOL(fd, 6); char type = RFIFOB(fd, 10); - char pos = RFIFOB(fd, 11); int size; struct fame_list *list = NULL; - switch(type) { - case 1: - size = fame_list_size_smith; - list = smith_fame_list; - break; - case 2: - size = fame_list_size_chemist; - list = chemist_fame_list; - break; - case 3: - size = fame_list_size_taekwon; - list = taekwon_fame_list; - break; - default: - size = 0; - break; + switch(type) + { + case 1 : size = fame_list_size_smith; list = smith_fame_list; break; + case 2 : size = fame_list_size_chemist; list = chemist_fame_list; break; + case 3 : size = fame_list_size_taekwon; list = taekwon_fame_list; break; + default: size = 0; break; } - if(!size) break; //No list. - if(pos) + if( size == 0 ) + break;// No list + for( i = 0; i < size; ++i ) { - pos--; //Convert from pos to index. - if( - (pos == 0 || fame < list[pos-1].fame) && - (pos == size-1 || fame > list[pos+1].fame) - ) { //No change in order. - list[(int)pos].fame = fame; - char_update_fame_list(type, pos, fame); - break; + if( list[i].id != cid ) + continue; + // player found, update position + if( i > 0 && fame >= list[i - 1].fame ) + {// moved up + struct fame_list entry; + int t; + for( t = 0; fame < list[t].fame ; ++t ) + ;// get target position (always < i) + memcpy(&entry, &list[i], sizeof(struct fame_list)); + entry.fame = fame; + memmove(&list[t + 1], &list[t], (t - i)*sizeof(struct fame_list)); + memcpy(&list[t], &entry, sizeof(struct fame_list)); + char_send_fame_list(-1); + } + else if( i < size - 1 && fame < list[i + 1].fame ) + {// moved down - always stays in the list + struct fame_list entry; + int t; + for( t = i + 2; t < size && fame < list[t].fame ; ++t ) + ;// get target position + --t; + memcpy(&entry, &list[i], sizeof(struct fame_list)); + entry.fame = fame; + memmove(&list[i], &list[i + 1], (t - i)*sizeof(struct fame_list)); + memcpy(&list[t], &entry, sizeof(struct fame_list)); + char_send_fame_list(-1); } - // If the player's already in the list, remove the entry and shift the following ones 1 step up - memmove(list+pos, list+pos+1, (size-pos-1) * sizeof(struct fame_list)); - //Clear out last entry. - list[size-1].id = 0; - list[size-1].fame = 0; + else + {// same position + list[i].fame = fame; + char_update_fame_list(type, i, fame); + } + break; } - // Find the position where the player has to be inserted - for(i = 0; i < size && fame < list[i].fame; i++); - if(i >= size) break; //Out of ranking. - // When found someone with less or as much fame, insert just above - memmove(list+i+1, list+i, (size-i-1) * sizeof(struct fame_list)); - list[i].id = cid; - list[i].fame = fame; - // Look for the player's name - char_loadName(list[i].id, list[i].name); - char_send_fame_list(-1); + if( i == size && fame >= list[size - 1].fame ) + {// not on list and has enough fame + for( i = 0; fame < list[i].fame; ++i ) + ;// get target position + list[i].id = cid; + list[i].fame = fame; + char_loadName(list[i].id, list[i].name); + char_send_fame_list(-1); + } - RFIFOSKIP(fd,12); + RFIFOSKIP(fd,11); } break; diff --git a/src/common/socket.h b/src/common/socket.h index f1997defe..469ff678d 100644 --- a/src/common/socket.h +++ b/src/common/socket.h @@ -35,7 +35,7 @@ #define RFIFOSPACE(fd) (session[fd]->max_rdata - session[fd]->rdata_size) #define WFIFOSPACE(fd) (session[fd]->max_wdata - session[fd]->wdata_size) -#define RFIFOREST(fd) (session[fd]->rdata_size - session[fd]->rdata_pos) +#define RFIFOREST(fd) (session[fd]->eof ? 0 : session[fd]->rdata_size - session[fd]->rdata_pos) #define RFIFOFLUSH(fd) \ do { \ if(session[fd]->rdata_size == session[fd]->rdata_pos){ \ diff --git a/src/map/chrif.c b/src/map/chrif.c index 4b5dde218..770e232b5 100644 --- a/src/map/chrif.c +++ b/src/map/chrif.c @@ -1071,8 +1071,7 @@ int chrif_updatefamelist(struct map_session_data *sd) WFIFOL(char_fd,2) = sd->status.char_id; WFIFOL(char_fd,6) = sd->status.fame; WFIFOB(char_fd,10) = type; - WFIFOB(char_fd,11) = pc_famerank(sd->status.char_id, sd->class_&MAPID_UPPERMASK); - WFIFOSET(char_fd,12); + WFIFOSET(char_fd,11); return 0; } -- cgit v1.2.3-70-g09d2