Issue information

Issue ID
#5012
Status
Fixed
Severity
Low
Started
Hercules Elf Bot
Jul 29, 2011 20:18
Last Post
Hercules Elf Bot
Apr 5, 2012 8:06
Confirmation
N/A

Hercules Elf Bot - Jul 29, 2011 20:18

Originally posted by [b]NoH[/b]
http://www.eathena.ws/board/index.php?autocom=bugtracker&showbug=5012

And yes, I do mean critical, check how it can be exploited in the RE branch to have unlimited XP: http://www.eathena.ws/board/index.php?auto...g=5011&st=0

So, here is the thing: checkquest(x,HUNTING) returns 2 even if the quest is completed, not just when it's active (aka: checkquest(x) == 0 or checkquest(x) == 1). Poorly scripted scripts such as the Aegis eden scripts converted to use the eA syntax may therefore ignore the fact you don't have the quest and give you the reward over and over if you have completed the HUNTING part.

Here is the fix. In quest.c:

CODE
int quest_check(TBL_PC * sd, int quest_id, quest_check_type type)
{
    int i;

    ARR_FIND(0, sd->num_quests, i, sd->quest_log[i].quest_id == quest_id);
    if(i == sd->num_quests)
        return -1;

    switch( type )
    {
    case HAVEQUEST:        
        return sd->quest_log[i].state;
    case PLAYTIME:
        return (sd->quest_log[i].time < (unsigned int)time(NULL) ? 2 : sd->quest_log[i].state == Q_COMPLETE ? 1 : 0);
    case HUNTING:
        {
            int j;
            ARR_FIND(0, MAX_QUEST_OBJECTIVES, j, sd->quest_log[i].count[j] < quest_db[sd->quest_index[i]].count[j]);
            if( j == MAX_QUEST_OBJECTIVES )
                return 2;
            if( sd->quest_log[i].time < (unsigned int)time(NULL) )
                return 1;
            return 0;
        }


->

CODE
int quest_check(TBL_PC * sd, int quest_id, quest_check_type type)
{
    int i;

    ARR_FIND(0, sd->num_quests, i, sd->quest_log[i].quest_id == quest_id);
    if(i == sd->num_quests)
        return -1;

    switch( type )
    {
    case HAVEQUEST:        
        return sd->quest_log[i].state;
    case PLAYTIME:
        return (sd->quest_log[i].time < (unsigned int)time(NULL) ? 2 : sd->quest_log[i].state == Q_COMPLETE ? 1 : 0);
    case HUNTING:
        {
            if (sd->quest_log[i].state == 0 || sd->quest_log[i].state == 1) {
                int j;
                ARR_FIND(0, MAX_QUEST_OBJECTIVES, j, sd->quest_log[i].count[j] < quest_db[sd->quest_index[i]].count[j]);
                if( j == MAX_QUEST_OBJECTIVES )
                    return 2;
                if( sd->quest_log[i].time < (unsigned int)time(NULL) )
                    return 1;
                return 0;
            }
            else
                return 0;
        }

Hercules Elf Bot - Dec 17, 2011 4:48

Originally posted by [b]Ind[/b]
Fixed in [rev=15147]