Index: progressionmanager.cpp =================================================================== --- progressionmanager.cpp (revision 1484) +++ progressionmanager.cpp (working copy) @@ -5018,7 +5018,7 @@ bool training= false; if (isTraining) training= true; - + psGUISkillMessage newmsg(client->GetClientNum(), psGUISkillMessage::SKILL_LIST, "", Index: adminmanager.cpp =================================================================== --- adminmanager.cpp (revision 1484) +++ adminmanager.cpp (working copy) @@ -5939,14 +5939,24 @@ return; } + // use unsigned int since skills are never negative (this also takes care of overflows) + unsigned int value = data.value; + unsigned int max = MAX(MAX_SKILL, MAX_STAT); if (data.skill == "all") { + // if the value is out of range, send an error + if (value < 0 || value > max) + { + psserver->SendSystemError(me->clientnum, "Valid values are between 0 and %u", max); + return; + } + for (int i=0; iSetSkillRank(skill->id, data.value); + pchar->SetSkillRank(skill->id, value); } psserver->SendSystemInfo(me->clientnum, "Fine"); @@ -5963,14 +5973,25 @@ unsigned int old_value = pchar->GetSkills()->GetSkillRank(skill->id); if (data.value == -1) { - psserver->SendSystemInfo(me->clientnum, "Current '%s' is %d",skill->name.GetDataSafe(),old_value); + psserver->SendSystemInfo(me->clientnum, "Current '%s' is %u",skill->name.GetDataSafe(),old_value); return; - } else + } + else if (skill->category == PSSKILLS_CATEGORY_STATS && (value < 0 || value > MAX_STAT)) + { + psserver->SendSystemError(me->clientnum, "Stat values are between 0 and %u", MAX_STAT); + return; + } + else if (skill->category != PSSKILLS_CATEGORY_STATS && (value < 0 || value > MAX_SKILL)) + { + psserver->SendSystemError(me->clientnum, "Skill values are between 0 and %u", MAX_SKILL); + return; + } - pchar->SetSkillRank(skill->id, data.value); - psserver->SendSystemInfo(me->clientnum, "Changed '%s' from %d to %d",skill->name.GetDataSafe(),old_value,data.value); + pchar->SetSkillRank(skill->id, value); + psserver->SendSystemInfo(me->clientnum, "Changed '%s' from %u to %u",skill->name.GetDataSafe(),old_value,data.value); } + // Send updated skill list to client psserver->GetProgressionManager()->SendSkillList(target, false); if (target != client) Index: bulkobjects/pscharacter.h =================================================================== --- bulkobjects/pscharacter.h (revision 1484) +++ bulkobjects/pscharacter.h (working copy) @@ -418,7 +418,7 @@ * @param rank The value to set this skill rank at. * @param recalculatestats if true, stats of player will be recalculated taking into account the new skill rank */ - void SetSkillRank( PSSKILL which, int rank, bool recalculatestats = true); + void SetSkillRank( PSSKILL which, unsigned int rank, bool recalculatestats = true); /** Update the costs for all the skills. */ Index: bulkobjects/psskills.h =================================================================== --- bulkobjects/psskills.h (revision 1484) +++ bulkobjects/psskills.h (working copy) @@ -36,6 +36,8 @@ // Local Includes //============================================================================= +#define MAX_SKILL 10000 +#define MAX_STAT 10000 enum PSSKILL { PSSKILL_NONE = -1, Index: bulkobjects/pscharacter.cpp =================================================================== --- bulkobjects/pscharacter.cpp (revision 1484) +++ bulkobjects/pscharacter.cpp (working copy) @@ -3785,11 +3785,15 @@ void StatSet::SetStat(PSITEMSTATS_STAT attrib, unsigned int val, bool recalculatestats) { - if (attrib<0 || attrib>=PSITEMSTATS_STAT_COUNT) + if (attrib < 0 || attrib >= PSITEMSTATS_STAT_COUNT) return; - stats[attrib].rank=val; - if (recalculatestats) + // Clamp values to prevent huge numbers + if (val > MAX_STAT) + val = MAX_STAT; + + stats[attrib].rank = val; + if (recalculatestats) self->RecalculateStats(); } @@ -3798,7 +3802,7 @@ if (attrib<0 || attrib>=PSITEMSTATS_STAT_COUNT) return; - stats[attrib].rank += delta; + stats[attrib].rank += delta; self->RecalculateStats(); } @@ -3946,14 +3950,20 @@ self->RecalculateStats(); } -void SkillSet::SetSkillRank( PSSKILL which, int rank, bool recalculatestats ) +void SkillSet::SetSkillRank( PSSKILL which, unsigned int rank, bool recalculatestats ) { - if (which<0 || which>=PSSKILL_COUNT) + if (which < 0 || which >= PSSKILL_COUNT) return; + bool isStat = (which >= PSSKILL_AGI && which <= PSSKILL_WILL); + // Clamp rank to stay within sane values, even if given something totally outrageous. if (rank < 0) rank = 0; + else if (!isStat && rank > MAX_SKILL) + rank = MAX_SKILL; + else if (isStat && rank > MAX_STAT) + rank = MAX_STAT; skills[which].rank = rank; skills[which].CalculateCosts(self);