From def9450e64bf13878a4ecb1650278e48e15ded20 Mon Sep 17 00:00:00 2001 From: Dastgir Date: Tue, 29 Mar 2016 19:08:01 +0530 Subject: Fixed defense overflow exploit * The defense penalty for being attacked by many enemies at the same time can no longer make DEF go negative * Fixed two potential overflow exploits When being hit by a lot of monsters, your DEF will become negative and then eventually overflow, making you almost invincible. On official servers the simultaneous attacker count is limited to 22. So at max, your def is reduced by ((22-2)*5%) = 100%. So it should neither be able to make your DEF negative nor cause an overflow. Merge from https://github.com/rathena/rathena/commit/590f42cd15c58de78cff8be6053109852375bce1#diff-d96b6365b4bdad78139e676d6e7e3295R4589 --- src/map/battle.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/map/battle.c') diff --git a/src/map/battle.c b/src/map/battle.c index fceb30be1..16b503e9d 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -1382,6 +1382,7 @@ static int64 battle_calc_defense(int attack_type, struct block_list *src, struct #ifndef RENEWAL if(skill_id == AM_ACIDTERROR) def1 = 0; //Acid Terror ignores only armor defense. [Skotlex] #endif + def1 = max(def1, 0); if(def2 < 1) def2 = 1; } //Vitality reduction from rodatazone: http://rodatazone.simgaming.net/mechanics/substats.php#def -- cgit v1.2.3-70-g09d2 From fb33bf84fde847d8329ec241e83ea3a05595caa5 Mon Sep 17 00:00:00 2001 From: Haru Date: Wed, 14 Nov 2018 19:43:28 +0100 Subject: Clarify the code around the def/flee reduction for multiple attackers This is just a clarification/sanitization, no functional changes intended. Signed-off-by: Haru --- src/map/battle.c | 66 ++++++++++++++++++++++++++++++-------------------------- 1 file changed, 35 insertions(+), 31 deletions(-) (limited to 'src/map/battle.c') diff --git a/src/map/battle.c b/src/map/battle.c index 16b503e9d..8f5200e72 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -1365,25 +1365,28 @@ static int64 battle_calc_defense(int attack_type, struct block_list *src, struct #endif } - if( battle_config.vit_penalty_type && battle_config.vit_penalty_target&target->type ) { - unsigned char target_count; //256 max targets should be a sane max - target_count = unit->counttargeted(target); - if(target_count >= battle_config.vit_penalty_count) { - if(battle_config.vit_penalty_type == 1) { - if( !tsc || !tsc->data[SC_STEELBODY] ) - def1 = (def1 * (100 - (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num))/100; - def2 = (def2 * (100 - (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num))/100; - } else { //Assume type 2 - if( !tsc || !tsc->data[SC_STEELBODY] ) - def1 -= (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num; - def2 -= (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num; + if (battle_config.vit_penalty_type != 0 && (battle_config.vit_penalty_target & target->type) != 0) { + int target_count = unit->counttargeted(target); + if (target_count >= battle_config.vit_penalty_count) { + int penalty = (target_count - (battle_config.vit_penalty_count - 1)) * battle_config.vit_penalty_num; + if (battle_config.vit_penalty_type == 1) { + if (tsc == NULL || tsc->data[SC_STEELBODY] == NULL) + def1 = def1 * (100 - penalty) / 100; + def2 = def2 * (100 - penalty) / 100; + } else { // Assume type 2 + if (tsc == NULL || tsc->data[SC_STEELBODY] == NULL) + def1 -= penalty; + def2 -= penalty; } } #ifndef RENEWAL - if(skill_id == AM_ACIDTERROR) def1 = 0; //Acid Terror ignores only armor defense. [Skotlex] + if (skill_id == AM_ACIDTERROR) + def1 = 0; // Acid Terror ignores only armor defense. [Skotlex] #endif - def1 = max(def1, 0); - if(def2 < 1) def2 = 1; + if (def1 < 0) + def1 = 0; + if (def2 < 1) + def2 = 1; } //Vitality reduction from rodatazone: http://rodatazone.simgaming.net/mechanics/substats.php#def if (tsd) { @@ -4225,16 +4228,16 @@ static struct Damage battle_calc_misc_attack(struct block_list *src, struct bloc hitrate = 80; //Default hitrate #endif - if(battle_config.agi_penalty_type && battle_config.agi_penalty_target&target->type) { - unsigned char attacker_count; //256 max targets should be a sane max - attacker_count = unit->counttargeted(target); - if(attacker_count >= battle_config.agi_penalty_count) - { + if (battle_config.agi_penalty_type != 0 && (battle_config.agi_penalty_target & target->type) != 0) { + int attacker_count = unit->counttargeted(target); + if (attacker_count >= battle_config.agi_penalty_count) { + int penalty = (attacker_count - (battle_config.agi_penalty_count - 1)) * battle_config.agi_penalty_num; if (battle_config.agi_penalty_type == 1) - flee = (flee * (100 - (attacker_count - (battle_config.agi_penalty_count - 1))*battle_config.agi_penalty_num))/100; + flee = flee * (100 - penalty) / 100; else // assume type 2: absolute reduction - flee -= (attacker_count - (battle_config.agi_penalty_count - 1))*battle_config.agi_penalty_num; - if(flee < 1) flee = 1; + flee -= penalty; + if (flee < 1) + flee = 1; } } @@ -4750,15 +4753,16 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src, struct bl short hitrate = 80; //Default hitrate #endif - if(battle_config.agi_penalty_type && battle_config.agi_penalty_target&target->type) { - unsigned char attacker_count; //256 max targets should be a sane max - attacker_count = unit->counttargeted(target); - if(attacker_count >= battle_config.agi_penalty_count) { + if (battle_config.agi_penalty_type != 0 && (battle_config.agi_penalty_target & target->type) != 0) { + int attacker_count = unit->counttargeted(target); + if (attacker_count >= battle_config.agi_penalty_count) { + int penalty = (attacker_count - (battle_config.agi_penalty_count - 1)) * battle_config.agi_penalty_num; if (battle_config.agi_penalty_type == 1) - flee = (flee * (100 - (attacker_count - (battle_config.agi_penalty_count - 1))*battle_config.agi_penalty_num))/100; - else //asume type 2: absolute reduction - flee -= (attacker_count - (battle_config.agi_penalty_count - 1))*battle_config.agi_penalty_num; - if(flee < 1) flee = 1; + flee = flee * (100 - penalty) / 100; + else // asume type 2: absolute reduction + flee -= penalty; + if (flee < 1) + flee = 1; } } -- cgit v1.2.3-70-g09d2