summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changelog-Trunk.txt6
-rw-r--r--src/char/char.c107
-rw-r--r--src/char_sql/char.c97
-rw-r--r--src/common/socket.h2
-rw-r--r--src/map/chrif.c3
5 files changed, 120 insertions, 95 deletions
diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt
index 4c9a041cd..9e68687bc 100644
--- a/Changelog-Trunk.txt
+++ b/Changelog-Trunk.txt
@@ -3,6 +3,12 @@ Date Added
AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO INTO TRUNK.
IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
+2007/05/28
+ * RFIFOREST returns 0 when the session is eof (input data is implicitly
+ discarted).
+ * Reworked the player fame update: [FlavioJS]
+ - would crash if an invalid pos was received
+ - the wrong player could be updated on certain conditions
2007/05/26
* Identified several more glitches, too tired to fix these...
* Fixed server not removing member minimap dot when you leave a guild
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;
}