Skip to content

Commit

Permalink
Improvements to exp_guild.txt loading
Browse files Browse the repository at this point in the history
- Modified exp_guild.txt processing to honor the value of MAX_GUILDLEVEL
  and correctly handle overflows.

Signed-off-by: Haru <haru@dotalux.com>
  • Loading branch information
MishimaHaruna committed Jan 22, 2014
1 parent 9701fe3 commit ce15f82
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 40 deletions.
50 changes: 22 additions & 28 deletions src/char/int_guild.c
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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)
Expand All @@ -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++;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
25 changes: 13 additions & 12 deletions src/map/atcommand.c
Expand Up @@ -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) {
Expand All @@ -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));
Expand Down

0 comments on commit ce15f82

Please sign in to comment.