* 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://svn.code.sf.net/p/rathena/svn/trunk@10640 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
parent
1aec42d51a
commit
f3bb9a322d
@ -3,6 +3,12 @@ Date Added
|
|||||||
AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO INTO TRUNK.
|
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.
|
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
|
2007/05/26
|
||||||
* Identified several more glitches, too tired to fix these...
|
* Identified several more glitches, too tired to fix these...
|
||||||
* Fixed server not removing member minimap dot when you leave a guild
|
* Fixed server not removing member minimap dot when you leave a guild
|
||||||
|
@ -3104,68 +3104,79 @@ int parse_frommap(int fd)
|
|||||||
// case 0x2b0f: Not used anymore, available for future use
|
// case 0x2b0f: Not used anymore, available for future use
|
||||||
|
|
||||||
case 0x2b10: // Update and send fame ranking list
|
case 0x2b10: // Update and send fame ranking list
|
||||||
if (RFIFOREST(fd) < 12)
|
if (RFIFOREST(fd) < 11)
|
||||||
return 0;
|
return 0;
|
||||||
{
|
{
|
||||||
int cid = RFIFOL(fd, 2);
|
int cid = RFIFOL(fd, 2);
|
||||||
int fame = RFIFOL(fd, 6);
|
int fame = RFIFOL(fd, 6);
|
||||||
char type = RFIFOB(fd, 10);
|
char type = RFIFOB(fd, 10);
|
||||||
char pos = RFIFOB(fd, 11);
|
|
||||||
int size;
|
int size;
|
||||||
struct fame_list *list = NULL;
|
struct fame_list *list = NULL;
|
||||||
|
|
||||||
switch(type) {
|
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)
|
|
||||||
{
|
{
|
||||||
pos--; //Convert from pos to index.
|
case 1 : size = fame_list_size_smith; list = smith_fame_list; break;
|
||||||
if(
|
case 2 : size = fame_list_size_chemist; list = chemist_fame_list; break;
|
||||||
(pos == 0 || fame < list[pos-1].fame) &&
|
case 3 : size = fame_list_size_taekwon; list = taekwon_fame_list; break;
|
||||||
(pos == size-1 || fame > list[pos+1].fame)
|
default: size = 0; break;
|
||||||
) { //No change in order.
|
|
||||||
list[(int)pos].fame = fame;
|
|
||||||
char_update_fame_list(type, pos, fame);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
// If the player's already in the list, remove the entry and shift the following ones 1 step up
|
if( size == 0 )
|
||||||
memmove(list+pos, list+pos+1, (size-pos-1) * sizeof(struct fame_list));
|
break;// No list
|
||||||
//Clear out last entry.
|
for( i = 0; i < size; ++i )
|
||||||
list[size-1].id = 0;
|
{
|
||||||
list[size-1].fame = 0;
|
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);
|
||||||
|
}
|
||||||
|
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
|
if( i == size && fame >= list[size - 1].fame )
|
||||||
for(i = 0; i < size && fame < list[i].fame; i++);
|
{// not on list and has enough fame
|
||||||
if(i >= size) break; //Out of ranking.
|
size_t j;
|
||||||
// When found someone with less or as much fame, insert just above
|
for( i = 0; fame < list[i].fame; ++i )
|
||||||
memmove(list+i+1, list+i, (size-i-1) * sizeof(struct fame_list));
|
;// get target position
|
||||||
list[i].id = cid;
|
list[i].id = cid;
|
||||||
list[i].fame = fame;
|
list[i].fame = fame;
|
||||||
// Look for the player's name
|
for( j = 0; j < char_num && char_dat[j].status.char_id != cid; ++j )
|
||||||
for(j = 0; j < char_num && char_dat[j].status.char_id != id; j++);
|
;// find char
|
||||||
if(j < char_num)
|
if( j < char_num )
|
||||||
strncpy(list[i].name, char_dat[j].status.name, NAME_LENGTH);
|
strncpy(list[i].name, char_dat[j].status.name, NAME_LENGTH);
|
||||||
else //Not found??
|
else
|
||||||
strncpy(list[i].name, "Unknown", NAME_LENGTH);
|
strncpy(list[i].name, "Unknown", NAME_LENGTH);
|
||||||
char_send_fame_list(-1);
|
char_send_fame_list(-1);
|
||||||
|
}
|
||||||
|
|
||||||
RFIFOSKIP(fd,12);
|
RFIFOSKIP(fd,11);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -2816,64 +2816,73 @@ int parse_frommap(int fd)
|
|||||||
// case 0x2b0f: Not used anymore, available for future use
|
// case 0x2b0f: Not used anymore, available for future use
|
||||||
|
|
||||||
case 0x2b10: // Update and send fame ranking list
|
case 0x2b10: // Update and send fame ranking list
|
||||||
if (RFIFOREST(fd) < 12)
|
if (RFIFOREST(fd) < 11)
|
||||||
return 0;
|
return 0;
|
||||||
{
|
{
|
||||||
int cid = RFIFOL(fd, 2);
|
int cid = RFIFOL(fd, 2);
|
||||||
int fame = RFIFOL(fd, 6);
|
int fame = RFIFOL(fd, 6);
|
||||||
char type = RFIFOB(fd, 10);
|
char type = RFIFOB(fd, 10);
|
||||||
char pos = RFIFOB(fd, 11);
|
|
||||||
int size;
|
int size;
|
||||||
struct fame_list *list = NULL;
|
struct fame_list *list = NULL;
|
||||||
|
|
||||||
switch(type) {
|
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)
|
|
||||||
{
|
{
|
||||||
pos--; //Convert from pos to index.
|
case 1 : size = fame_list_size_smith; list = smith_fame_list; break;
|
||||||
if(
|
case 2 : size = fame_list_size_chemist; list = chemist_fame_list; break;
|
||||||
(pos == 0 || fame < list[pos-1].fame) &&
|
case 3 : size = fame_list_size_taekwon; list = taekwon_fame_list; break;
|
||||||
(pos == size-1 || fame > list[pos+1].fame)
|
default: size = 0; break;
|
||||||
) { //No change in order.
|
|
||||||
list[(int)pos].fame = fame;
|
|
||||||
char_update_fame_list(type, pos, fame);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
// If the player's already in the list, remove the entry and shift the following ones 1 step up
|
if( size == 0 )
|
||||||
memmove(list+pos, list+pos+1, (size-pos-1) * sizeof(struct fame_list));
|
break;// No list
|
||||||
//Clear out last entry.
|
for( i = 0; i < size; ++i )
|
||||||
list[size-1].id = 0;
|
{
|
||||||
list[size-1].fame = 0;
|
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);
|
||||||
|
}
|
||||||
|
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
|
if( i == size && fame >= list[size - 1].fame )
|
||||||
for(i = 0; i < size && fame < list[i].fame; i++);
|
{// not on list and has enough fame
|
||||||
if(i >= size) break; //Out of ranking.
|
for( i = 0; fame < list[i].fame; ++i )
|
||||||
// When found someone with less or as much fame, insert just above
|
;// get target position
|
||||||
memmove(list+i+1, list+i, (size-i-1) * sizeof(struct fame_list));
|
|
||||||
list[i].id = cid;
|
list[i].id = cid;
|
||||||
list[i].fame = fame;
|
list[i].fame = fame;
|
||||||
// Look for the player's name
|
|
||||||
char_loadName(list[i].id, list[i].name);
|
char_loadName(list[i].id, list[i].name);
|
||||||
char_send_fame_list(-1);
|
char_send_fame_list(-1);
|
||||||
|
}
|
||||||
|
|
||||||
RFIFOSKIP(fd,12);
|
RFIFOSKIP(fd,11);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
#define RFIFOSPACE(fd) (session[fd]->max_rdata - session[fd]->rdata_size)
|
#define RFIFOSPACE(fd) (session[fd]->max_rdata - session[fd]->rdata_size)
|
||||||
#define WFIFOSPACE(fd) (session[fd]->max_wdata - session[fd]->wdata_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) \
|
#define RFIFOFLUSH(fd) \
|
||||||
do { \
|
do { \
|
||||||
if(session[fd]->rdata_size == session[fd]->rdata_pos){ \
|
if(session[fd]->rdata_size == session[fd]->rdata_pos){ \
|
||||||
|
@ -1071,8 +1071,7 @@ int chrif_updatefamelist(struct map_session_data *sd)
|
|||||||
WFIFOL(char_fd,2) = sd->status.char_id;
|
WFIFOL(char_fd,2) = sd->status.char_id;
|
||||||
WFIFOL(char_fd,6) = sd->status.fame;
|
WFIFOL(char_fd,6) = sd->status.fame;
|
||||||
WFIFOB(char_fd,10) = type;
|
WFIFOB(char_fd,10) = type;
|
||||||
WFIFOB(char_fd,11) = pc_famerank(sd->status.char_id, sd->class_&MAPID_UPPERMASK);
|
WFIFOSET(char_fd,11);
|
||||||
WFIFOSET(char_fd,12);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user