summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHaru <haru@dotalux.com>2014-01-20 15:16:51 +0100
committerHaru <haru@dotalux.com>2014-01-22 13:28:20 +0100
commitce15f827e4e3b945e0aae6881b2d02bffe0d6164 (patch)
tree6dfb8d68b29b63e726315446336d527e39a93b87
parent9701fe324412112c6288afbc956b299f2b9cc779 (diff)
downloadhercules-ce15f827e4e3b945e0aae6881b2d02bffe0d6164.tar.gz
hercules-ce15f827e4e3b945e0aae6881b2d02bffe0d6164.tar.bz2
hercules-ce15f827e4e3b945e0aae6881b2d02bffe0d6164.tar.xz
hercules-ce15f827e4e3b945e0aae6881b2d02bffe0d6164.zip
Improvements to exp_guild.txt loading
- Modified exp_guild.txt processing to honor the value of MAX_GUILDLEVEL and correctly handle overflows. Signed-off-by: Haru <haru@dotalux.com>
-rw-r--r--src/char/int_guild.c50
-rw-r--r--src/map/atcommand.c25
2 files changed, 35 insertions, 40 deletions
diff --git a/src/char/int_guild.c b/src/char/int_guild.c
index 427c57531..ec01dab5b 100644
--- a/src/char/int_guild.c
+++ b/src/char/int_guild.c
@@ -35,7 +35,7 @@ static const char dataToHex[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9
static DBMap* guild_db_; // int guild_id -> struct guild*
static DBMap *castle_db;
-static unsigned int guild_exp[100];
+static unsigned int guild_exp[MAX_GUILDLEVEL];
int mapif_parse_GuildLeave(int fd,int guild_id,int account_id,int char_id,int flag,const char *mes);
int mapif_guild_broken(int guild_id,int flag);
@@ -598,16 +598,15 @@ static struct guild_castle* inter_guildcastle_fromsql(int castle_id)
// Read exp_guild.txt
-static bool exp_guild_parse_row(char* split[], int column, int current)
-{
- unsigned int exp = (unsigned int)atol(split[0]);
+static bool exp_guild_parse_row(char* split[], int column, int current) {
+ int64 exp = strtoll(split[0], NULL, 10);
- if (exp >= UINT_MAX) {
- ShowError("exp_guild: Invalid exp %d at line %d\n", exp, current);
+ if (exp < 0 || exp >= UINT_MAX) {
+ ShowError("exp_guild: Invalid exp %"PRId64" (valid range: 0 - %u) at line %d\n", exp, UINT_MAX, current);
return false;
}
- guild_exp[current] = exp;
+ guild_exp[current] = (unsigned int)exp;
return true;
}
@@ -725,7 +724,7 @@ int inter_guild_sql_init(void)
castle_db = idb_alloc(DB_OPT_RELEASE_DATA);
//Read exp file
- sv->readdb("db", DBPATH"exp_guild.txt", ',', 1, 1, 100, exp_guild_parse_row);
+ sv->readdb("db", DBPATH"exp_guild.txt", ',', 1, 1, MAX_GUILDLEVEL, exp_guild_parse_row);
timer->add_func_list(guild_save_timer, "guild_save_timer");
timer->add(timer->gettick() + 10000, guild_save_timer, 0, 0);
@@ -794,14 +793,13 @@ static bool guild_check_empty(struct guild *g)
return true;
}
-unsigned int guild_nextexp(int level)
-{
+unsigned int guild_nextexp(int level) {
if (level == 0)
return 1;
- if (level < 100 && level > 0) // Change by hack
- return guild_exp[level-1];
+ if (level <= 0 || level >= MAX_GUILDLEVEL)
+ return 0;
- return 0;
+ return guild_exp[level-1];
}
int guild_checkskill(struct guild *g,int id)
@@ -825,7 +823,7 @@ int guild_calcinfo(struct guild *g)
nextexp = guild_nextexp(g->guild_lv);
// Consume guild exp and increase guild level
- while(g->exp >= nextexp && nextexp > 0){ //fixed guild exp overflow [Kevin]
+ while(g->exp >= nextexp && nextexp > 0) { // nextexp would be 0 if g->guild_lv was >= MAX_GUILDLEVEL
g->exp-=nextexp;
g->guild_lv++;
g->skill_point++;
@@ -1424,24 +1422,20 @@ int mapif_parse_GuildMessage(int fd,int guild_id,int account_id,char *mes,int le
}
// Modification of the guild
-int mapif_parse_GuildBasicInfoChange(int fd,int guild_id,int type,const char *data,int len)
-{
- struct guild * g;
- short dw=*((short *)data);
+int mapif_parse_GuildBasicInfoChange(int fd, int guild_id, int type, const void *data, int len) {
+ struct guild *g;
+ short value = *((const int16 *)data);
g = inter_guild_fromsql(guild_id);
if(g==NULL)
return 0;
- switch(type)
- {
+ switch(type) {
case GBI_GUILDLV:
- if(dw>0 && g->guild_lv+dw<=50)
- {
- g->guild_lv+=dw;
- g->skill_point+=dw;
- }
- else if(dw<0 && g->guild_lv+dw>=1)
- g->guild_lv+=dw;
+ if (value > 0 && g->guild_lv + value <= MAX_GUILDLEVEL) {
+ g->guild_lv += value;
+ g->skill_point += value;
+ } else if (value < 0 && g->guild_lv + value >= 1)
+ g->guild_lv += value;
mapif_guild_info(-1,g);
g->save_flag |= GS_LEVEL;
return 0;
@@ -1837,7 +1831,7 @@ int inter_guild_parse_frommap(int fd)
case 0x3035: mapif_parse_GuildChangeMemberInfoShort(fd,RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),RFIFOB(fd,14),RFIFOW(fd,15),RFIFOW(fd,17)); break;
case 0x3036: mapif_parse_BreakGuild(fd,RFIFOL(fd,2)); break;
case 0x3037: mapif_parse_GuildMessage(fd,RFIFOL(fd,4),RFIFOL(fd,8),(char*)RFIFOP(fd,12),RFIFOW(fd,2)-12); break;
- case 0x3039: mapif_parse_GuildBasicInfoChange(fd,RFIFOL(fd,4),RFIFOW(fd,8),(const char*)RFIFOP(fd,10),RFIFOW(fd,2)-10); break;
+ case 0x3039: mapif_parse_GuildBasicInfoChange(fd,RFIFOL(fd,4),RFIFOW(fd,8),(const int16 *)RFIFOP(fd,10),RFIFOW(fd,2)-10); break;
case 0x303A: mapif_parse_GuildMemberInfoChange(fd,RFIFOL(fd,4),RFIFOL(fd,8),RFIFOL(fd,12),RFIFOW(fd,16),(const char*)RFIFOP(fd,18),RFIFOW(fd,2)-18); break;
case 0x303B: mapif_parse_GuildPosition(fd,RFIFOL(fd,4),RFIFOL(fd,8),(struct guild_position *)RFIFOP(fd,12)); break;
case 0x303C: mapif_parse_GuildSkillUp(fd,RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),RFIFOL(fd,14)); break;
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index 0cb552bd0..31357c074 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -2472,10 +2472,9 @@ ACMD(stat_all) {
/*==========================================
*
*------------------------------------------*/
-ACMD(guildlevelup)
-{
+ACMD(guildlevelup) {
int level = 0;
- short added_level;
+ int16 added_level;
struct guild *guild_info;
if (!message || !*message || sscanf(message, "%d", &level) < 1 || level == 0) {
@@ -2487,16 +2486,18 @@ ACMD(guildlevelup)
clif->message(fd, msg_txt(43)); // You're not in a guild.
return false;
}
- //if (strcmp(sd->status.name, guild_info->master) != 0) {
- // clif->message(fd, msg_txt(44)); // You're not the master of your guild.
- // return false;
- //}
+#if 0 // By enabling this, only the guild leader can use this command
+ if (strcmp(sd->status.name, guild_info->master) != 0) {
+ clif->message(fd, msg_txt(44)); // You're not the master of your guild.
+ return false;
+ }
+#endif // 0
- added_level = (short)level;
- if (level > 0 && (level > MAX_GUILDLEVEL || added_level > ((short)MAX_GUILDLEVEL - guild_info->guild_lv))) // fix positiv overflow
- added_level = (short)MAX_GUILDLEVEL - guild_info->guild_lv;
- else if (level < 0 && (level < -MAX_GUILDLEVEL || added_level < (1 - guild_info->guild_lv))) // fix negativ overflow
- added_level = 1 - guild_info->guild_lv;
+ if (level > INT16_MAX || (level > 0 && level > MAX_GUILDLEVEL - guild_info->guild_lv)) // fix positive overflow
+ level = MAX_GUILDLEVEL - guild_info->guild_lv;
+ else if (level < INT16_MIN || (level < 0 && level < 1 - guild_info->guild_lv)) // fix negative overflow
+ level = 1 - guild_info->guild_lv;
+ added_level = (int16)level;
if (added_level != 0) {
intif->guild_change_basicinfo(guild_info->guild_id, GBI_GUILDLV, &added_level, sizeof(added_level));