diff options
author | ai4rei <ai4rei@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2010-11-22 16:52:46 +0000 |
---|---|---|
committer | ai4rei <ai4rei@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2010-11-22 16:52:46 +0000 |
commit | 808b216c7dd6fedf644a0992dbb86255aed1068d (patch) | |
tree | 15405273f97bae2f965bca6bacc04e49b82220b2 | |
parent | b561fcc8037f50a9f562f2bcaa2b6d8e4644bcc4 (diff) | |
download | hercules-808b216c7dd6fedf644a0992dbb86255aed1068d.tar.gz hercules-808b216c7dd6fedf644a0992dbb86255aed1068d.tar.bz2 hercules-808b216c7dd6fedf644a0992dbb86255aed1068d.tar.xz hercules-808b216c7dd6fedf644a0992dbb86255aed1068d.zip |
* Fixed guild and guild member exp truncation issue (bugreport:4130, since r14242).
- Fixed guild member position, hair, hair color, gender, class and level could potentially become corrupted due to shorts being read as ints (partially since r2986).
git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/branches/renewal@14487 54d463be-8e91-2dee-dedb-b68131a5f0ec
-rw-r--r-- | Changelog-Renewal.txt | 2 | ||||
-rw-r--r-- | src/char/int_guild.c | 30 | ||||
-rw-r--r-- | src/char/int_guild.h | 2 | ||||
-rw-r--r-- | src/char_sql/int_guild.c | 28 | ||||
-rw-r--r-- | src/char_sql/int_guild.h | 2 | ||||
-rw-r--r-- | src/common/mmo.h | 3 | ||||
-rw-r--r-- | src/map/atcommand.c | 2 | ||||
-rw-r--r-- | src/map/clif.c | 2 | ||||
-rw-r--r-- | src/map/guild.c | 2 | ||||
-rw-r--r-- | src/map/guild.h | 2 | ||||
-rw-r--r-- | src/map/intif.c | 19 |
11 files changed, 48 insertions, 46 deletions
diff --git a/Changelog-Renewal.txt b/Changelog-Renewal.txt index fdec5fc24..19f2c6dd3 100644 --- a/Changelog-Renewal.txt +++ b/Changelog-Renewal.txt @@ -7,6 +7,8 @@ Date Added * Fixed map server getting notified of hair, hair color, gender, class and level changes from a char server (TXT only) twice (since r2986). [Ai4rei] * Fixed saving/loading errors with compilers (such as VC6, MinGW), which do not recognize %ll format (since r14242). [Ai4rei] - This also fixes guild leader name being displayed and saved as "(null)" in the guild member list. + * Fixed guild and guild member exp truncation issue (bugreport:4130, since r14242). [Ai4rei] + - Fixed guild member position, hair, hair color, gender, class and level could potentially become corrupted due to shorts being read as ints (partially since r2986). 2010/11/21 * Added msinttypes (rev. 26, http://msinttypes.googlecode.com/svn/trunk/) portability framework for Visual C++ compilers (related bugreport:4059). [Ai4rei] * Added 64-bit variants of the socket and buffer I/O macros. [Ai4rei] diff --git a/src/char/int_guild.c b/src/char/int_guild.c index ed9e52d96..9a815200f 100644 --- a/src/char/int_guild.c +++ b/src/char/int_guild.c @@ -42,7 +42,7 @@ int inter_guild_tostr(char* str, struct guild* g) int i, c, len; // save guild base info - len = sprintf(str, "%d\t%s\t%s\t%d,%d,%u,%d,%d\t%s#\t%s#\t", + len = sprintf(str, "%d\t%s\t%s\t%d,%d,%"PRIu64",%d,%d\t%s#\t%s#\t", g->guild_id, g->name, g->master, g->guild_lv, g->max_member, g->exp, g->skill_point, 0, g->mes1, g->mes2); // save guild member info @@ -118,13 +118,13 @@ int inter_guild_fromstr(char* str, struct guild* g) char master[256]; // only 24 used int guildlv; int max_member; - unsigned int exp; + uint64 exp; int skpoint; char mes1[256]; // only 60 used char mes2[256]; // only 120 used int len; - if( sscanf(str, "%d\t%[^\t]\t%[^\t]\t%d,%d,%u,%d,%*d\t%[^\t]\t%[^\t]\t%n", + if( sscanf(str, "%d\t%[^\t]\t%[^\t]\t%d,%d,%"SCNu64",%d,%*d\t%[^\t]\t%[^\t]\t%n", &guildid, name, master, &guildlv, &max_member, &exp, &skpoint, mes1, mes2, &len) < 9 ) return 1; @@ -1236,55 +1236,55 @@ int mapif_parse_GuildMemberInfoChange(int fd, int guild_id, int account_id, int } switch(type) { case GMI_POSITION: // 役職 - g->member[i].position = *((int *)data); + g->member[i].position = *((short *)data); mapif_guild_memberinfochanged(guild_id, account_id, char_id, type, data, len); break; case GMI_EXP: // EXP { - unsigned int exp, old_exp=g->member[i].exp; - g->member[i].exp=*((unsigned int *)data); + uint64 exp, old_exp=g->member[i].exp; + g->member[i].exp=*((uint64 *)data); if (g->member[i].exp > old_exp) { exp = g->member[i].exp - old_exp; if (guild_exp_rate != 100) exp = exp*guild_exp_rate/100; - if (exp > UINT_MAX - g->exp) - g->exp = UINT_MAX; + if (exp > UINT64_MAX - g->exp) + g->exp = UINT64_MAX; else g->exp+=exp; guild_calcinfo(g); - mapif_guild_basicinfochanged(guild_id,GBI_EXP,&g->exp,4); + mapif_guild_basicinfochanged(guild_id,GBI_EXP,&g->exp,sizeof(g->exp)); } mapif_guild_memberinfochanged(guild_id, account_id, char_id, type, data, len); break; } case GMI_HAIR: { - g->member[i].hair=*((int *)data); + g->member[i].hair=*((short *)data); mapif_guild_memberinfochanged(guild_id,account_id,char_id,type,data,len); break; } case GMI_HAIR_COLOR: { - g->member[i].hair_color=*((int *)data); + g->member[i].hair_color=*((short *)data); mapif_guild_memberinfochanged(guild_id,account_id,char_id,type,data,len); break; } case GMI_GENDER: { - g->member[i].gender=*((int *)data); + g->member[i].gender=*((short *)data); mapif_guild_memberinfochanged(guild_id,account_id,char_id,type,data,len); break; } case GMI_CLASS: { - g->member[i].class_=*((int *)data); + g->member[i].class_=*((short *)data); mapif_guild_memberinfochanged(guild_id,account_id,char_id,type,data,len); break; } case GMI_LEVEL: { - g->member[i].lv=*((int *)data); + g->member[i].lv=*((short *)data); mapif_guild_memberinfochanged(guild_id,account_id,char_id,type,data,len); break; } @@ -1297,7 +1297,7 @@ int mapif_parse_GuildMemberInfoChange(int fd, int guild_id, int account_id, int return 0; } -int inter_guild_sex_changed(int guild_id,int account_id,int char_id, int gender) +int inter_guild_sex_changed(int guild_id,int account_id,int char_id, short gender) { return mapif_parse_GuildMemberInfoChange(0, guild_id, account_id, char_id, GMI_GENDER, (const char*)&gender, sizeof(gender)); } diff --git a/src/char/int_guild.h b/src/char/int_guild.h index 06293eb0f..0be6c50d9 100644 --- a/src/char/int_guild.h +++ b/src/char/int_guild.h @@ -14,7 +14,7 @@ int inter_guild_parse_frommap(int fd); struct guild *inter_guild_search(int guild_id); int inter_guild_mapif_init(int fd); int inter_guild_leave(int guild_id,int account_id,int char_id); -int inter_guild_sex_changed(int guild_id,int account_id,int char_id, int gender); +int inter_guild_sex_changed(int guild_id,int account_id,int char_id, short gender); extern char guild_txt[1024]; extern char castle_txt[1024]; diff --git a/src/char_sql/int_guild.c b/src/char_sql/int_guild.c index 3d2df8977..00331e8e6 100644 --- a/src/char_sql/int_guild.c +++ b/src/char_sql/int_guild.c @@ -241,7 +241,7 @@ int inter_guild_tosql(struct guild *g,int flag) StringBuf_AppendStr(&buf, ", "); else add_comma = true; - StringBuf_Printf(&buf, "`guild_lv`=%d, `skill_point`=%d, `exp`=%u, `next_exp`=%u, `max_member`=%d", g->guild_lv, g->skill_point, g->exp, g->next_exp, g->max_member); + StringBuf_Printf(&buf, "`guild_lv`=%d, `skill_point`=%d, `exp`=%"PRIu64", `next_exp`=%u, `max_member`=%d", g->guild_lv, g->skill_point, g->exp, g->next_exp, g->max_member); } StringBuf_Printf(&buf, " WHERE `guild_id`=%d", g->guild_id); if( SQL_ERROR == Sql_Query(sql_handle, "%s", StringBuf_Value(&buf)) ) @@ -406,7 +406,7 @@ struct guild * inter_guild_fromsql(int guild_id) g->max_member = MAX_GUILD; } Sql_GetData(sql_handle, 5, &data, NULL); g->average_lv = atoi(data); - Sql_GetData(sql_handle, 6, &data, NULL); g->exp = (unsigned int)strtoul(data, NULL, 10); + Sql_GetData(sql_handle, 6, &data, NULL); g->exp = strtoull(data, NULL, 10); Sql_GetData(sql_handle, 7, &data, NULL); g->next_exp = (unsigned int)strtoul(data, NULL, 10); Sql_GetData(sql_handle, 8, &data, NULL); g->skill_point = atoi(data); Sql_GetData(sql_handle, 9, &data, &len); memcpy(g->mes1, data, min(len, sizeof(g->mes1))); @@ -1588,7 +1588,7 @@ int mapif_parse_GuildMemberInfoChange(int fd,int guild_id,int account_id,int cha { case GMI_POSITION: { - g->member[i].position=*((int *)data); + g->member[i].position=*((short *)data); g->member[i].modified = GS_MEMBER_MODIFIED; mapif_guild_memberinfochanged(guild_id,account_id,char_id,type,data,len); g->save_flag |= GS_MEMBER; @@ -1596,8 +1596,8 @@ int mapif_parse_GuildMemberInfoChange(int fd,int guild_id,int account_id,int cha } case GMI_EXP: { // EXP - unsigned int exp, old_exp=g->member[i].exp; - g->member[i].exp=*((unsigned int *)data); + uint64 exp, old_exp=g->member[i].exp; + g->member[i].exp=*((uint64 *)data); g->member[i].modified = GS_MEMBER_MODIFIED; if (g->member[i].exp > old_exp) { @@ -1608,13 +1608,13 @@ int mapif_parse_GuildMemberInfoChange(int fd,int guild_id,int account_id,int cha exp = exp*guild_exp_rate/100; // Update guild exp - if (exp > UINT_MAX - g->exp) - g->exp = UINT_MAX; + if (exp > UINT64_MAX - g->exp) + g->exp = UINT64_MAX; else g->exp+=exp; guild_calcinfo(g); - mapif_guild_basicinfochanged(guild_id,GBI_EXP,&g->exp,4); + mapif_guild_basicinfochanged(guild_id,GBI_EXP,&g->exp,sizeof(g->exp)); g->save_flag |= GS_LEVEL; } mapif_guild_memberinfochanged(guild_id,account_id,char_id,type,data,len); @@ -1623,7 +1623,7 @@ int mapif_parse_GuildMemberInfoChange(int fd,int guild_id,int account_id,int cha } case GMI_HAIR: { - g->member[i].hair=*((int *)data); + g->member[i].hair=*((short *)data); g->member[i].modified = GS_MEMBER_MODIFIED; mapif_guild_memberinfochanged(guild_id,account_id,char_id,type,data,len); g->save_flag |= GS_MEMBER; //Save new data. @@ -1631,7 +1631,7 @@ int mapif_parse_GuildMemberInfoChange(int fd,int guild_id,int account_id,int cha } case GMI_HAIR_COLOR: { - g->member[i].hair_color=*((int *)data); + g->member[i].hair_color=*((short *)data); g->member[i].modified = GS_MEMBER_MODIFIED; mapif_guild_memberinfochanged(guild_id,account_id,char_id,type,data,len); g->save_flag |= GS_MEMBER; //Save new data. @@ -1639,7 +1639,7 @@ int mapif_parse_GuildMemberInfoChange(int fd,int guild_id,int account_id,int cha } case GMI_GENDER: { - g->member[i].gender=*((int *)data); + g->member[i].gender=*((short *)data); g->member[i].modified = GS_MEMBER_MODIFIED; mapif_guild_memberinfochanged(guild_id,account_id,char_id,type,data,len); g->save_flag |= GS_MEMBER; //Save new data. @@ -1647,7 +1647,7 @@ int mapif_parse_GuildMemberInfoChange(int fd,int guild_id,int account_id,int cha } case GMI_CLASS: { - g->member[i].class_=*((int *)data); + g->member[i].class_=*((short *)data); g->member[i].modified = GS_MEMBER_MODIFIED; mapif_guild_memberinfochanged(guild_id,account_id,char_id,type,data,len); g->save_flag |= GS_MEMBER; //Save new data. @@ -1655,7 +1655,7 @@ int mapif_parse_GuildMemberInfoChange(int fd,int guild_id,int account_id,int cha } case GMI_LEVEL: { - g->member[i].lv=*((int *)data); + g->member[i].lv=*((short *)data); g->member[i].modified = GS_MEMBER_MODIFIED; mapif_guild_memberinfochanged(guild_id,account_id,char_id,type,data,len); g->save_flag |= GS_MEMBER; //Save new data. @@ -1668,7 +1668,7 @@ int mapif_parse_GuildMemberInfoChange(int fd,int guild_id,int account_id,int cha return 0; } -int inter_guild_sex_changed(int guild_id,int account_id,int char_id, int gender) +int inter_guild_sex_changed(int guild_id,int account_id,int char_id, short gender) { return mapif_parse_GuildMemberInfoChange(0, guild_id, account_id, char_id, GMI_GENDER, (const char*)&gender, sizeof(gender)); } diff --git a/src/char_sql/int_guild.h b/src/char_sql/int_guild.h index a14e09b00..4577357f3 100644 --- a/src/char_sql/int_guild.h +++ b/src/char_sql/int_guild.h @@ -28,7 +28,7 @@ int inter_guild_mapif_init(int fd); int inter_guild_leave(int guild_id,int account_id,int char_id); int mapif_parse_BreakGuild(int fd,int guild_id); int inter_guild_broken(int guild_id); -int inter_guild_sex_changed(int guild_id,int account_id,int char_id, int gender); +int inter_guild_sex_changed(int guild_id,int account_id,int char_id, short gender); int inter_guild_charname_changed(int guild_id,int account_id, int char_id, char *name); int inter_guild_CharOnline(int char_id, int guild_id); int inter_guild_CharOffline(int char_id, int guild_id); diff --git a/src/common/mmo.h b/src/common/mmo.h index b1a257e9c..6a78d840c 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -468,7 +468,8 @@ struct guild_skill { struct guild { int guild_id; short guild_lv, connect_member, max_member, average_lv; - unsigned int exp,next_exp; + uint64 exp; + unsigned int next_exp; int skill_point; char name[NAME_LENGTH],master[NAME_LENGTH]; struct guild_member member[MAX_GUILD]; diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 77aef527f..ead204fb5 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -3084,7 +3084,7 @@ ACMD_FUNC(guildlevelup) added_level = 1 - guild_info->guild_lv; if (added_level != 0) { - intif_guild_change_basicinfo(guild_info->guild_id, GBI_GUILDLV, &added_level, 2); + intif_guild_change_basicinfo(guild_info->guild_id, GBI_GUILDLV, &added_level, sizeof(added_level)); clif_displaymessage(fd, msg_txt(179)); // Guild level changed. } else { clif_displaymessage(fd, msg_txt(45)); // Guild level change failed. diff --git a/src/map/clif.c b/src/map/clif.c index 94c19287a..087a41187 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -6804,7 +6804,7 @@ int clif_guild_basicinfo(struct map_session_data *sd) WFIFOL(fd,10)=g->connect_member; WFIFOL(fd,14)=g->max_member; WFIFOL(fd,18)=g->average_lv; - WFIFOL(fd,22)=g->exp; + WFIFOL(fd,22)=(uint32)cap_value(g->exp,0,INT_MAX); WFIFOL(fd,26)=g->next_exp; WFIFOL(fd,30)=0; // Tax Points WFIFOL(fd,34)=0; // Tendency: (left) Vulgar [-100,100] Famed (right) diff --git a/src/map/guild.c b/src/map/guild.c index 1b91dfc93..cdc978929 100644 --- a/src/map/guild.c +++ b/src/map/guild.c @@ -1003,7 +1003,7 @@ int guild_recv_message(int guild_id,int account_id,const char *mes,int len) return 0; } // ギルドメンバの役職変更 -int guild_change_memberposition(int guild_id,int account_id,int char_id,int idx) +int guild_change_memberposition(int guild_id,int account_id,int char_id,short idx) { return intif_guild_change_memberinfo(guild_id,account_id,char_id,GMI_POSITION,&idx,sizeof(idx)); } diff --git a/src/map/guild.h b/src/map/guild.h index 753de0da1..c6b380647 100644 --- a/src/map/guild.h +++ b/src/map/guild.h @@ -73,7 +73,7 @@ int guild_check_alliance(int guild_id1, int guild_id2, int flag); int guild_send_memberinfoshort(struct map_session_data *sd,int online); int guild_recv_memberinfoshort(int guild_id,int account_id,int char_id,int online,int lv,int class_); -int guild_change_memberposition(int guild_id,int account_id,int char_id,int idx); +int guild_change_memberposition(int guild_id,int account_id,int char_id,short idx); int guild_memberposition_changed(struct guild *g,int idx,int pos); int guild_change_position(int guild_id,int idx,int mode,int exp_mode,const char *name); int guild_position_changed(int guild_id,int idx,struct guild_position *p); diff --git a/src/map/intif.c b/src/map/intif.c index c8aad3807..ba5230bab 100644 --- a/src/map/intif.c +++ b/src/map/intif.c @@ -1124,7 +1124,7 @@ int intif_parse_GuildBasicInfoChanged(int fd) return 0; switch(type) { - case GBI_EXP: g->exp = RFIFOL(fd,10); break; + case GBI_EXP: g->exp = RFIFOQ(fd,10); break; case GBI_GUILDLV: g->guild_lv = RFIFOW(fd,10); break; case GBI_SKILLPOINT: g->skill_point = RFIFOL(fd,10); break; } @@ -1141,8 +1141,7 @@ int intif_parse_GuildMemberInfoChanged(int fd) int account_id = RFIFOL(fd,8); int char_id = RFIFOL(fd,12); int type = RFIFOW(fd,16); - void* data = RFIFOP(fd,18); - int dd = *((int *)data); + //void* data = RFIFOP(fd,18); struct guild* g; int idx; @@ -1156,13 +1155,13 @@ int intif_parse_GuildMemberInfoChanged(int fd) return 0; switch( type ) { - case GMI_POSITION: g->member[idx].position = dd; guild_memberposition_changed(g,idx,dd); break; - case GMI_EXP: g->member[idx].exp = dd; break; - case GMI_HAIR: g->member[idx].hair = dd; break; - case GMI_HAIR_COLOR: g->member[idx].hair_color = dd; break; - case GMI_GENDER: g->member[idx].gender = dd; break; - case GMI_CLASS: g->member[idx].class_ = dd; break; - case GMI_LEVEL: g->member[idx].lv = dd; break; + case GMI_POSITION: g->member[idx].position = RFIFOW(fd,18); guild_memberposition_changed(g,idx,RFIFOW(fd,18)); break; + case GMI_EXP: g->member[idx].exp = RFIFOQ(fd,18); break; + case GMI_HAIR: g->member[idx].hair = RFIFOW(fd,18); break; + case GMI_HAIR_COLOR: g->member[idx].hair_color = RFIFOW(fd,18); break; + case GMI_GENDER: g->member[idx].gender = RFIFOW(fd,18); break; + case GMI_CLASS: g->member[idx].class_ = RFIFOW(fd,18); break; + case GMI_LEVEL: g->member[idx].lv = RFIFOW(fd,18); break; } return 0; } |