Fixes a potential map-server crash by skill units (#6226)
Fixes #6224. Restart the iterator if a skill unit is deleted when trying to clear previous grouped unit skills. Thanks to @technoken! Co-authored-by: Lemongrass3110 <lemongrass@kstp.at>
This commit is contained in:
parent
fe7cb5a33f
commit
bccbf8b166
@ -17862,10 +17862,10 @@ int skill_attack_area(struct block_list *bl, va_list ap)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear skill unit group
|
* Clear skill unit group
|
||||||
* @param bl
|
* @param bl: Unit to check
|
||||||
* @param flag &1
|
* @param flag: Skill group to clear
|
||||||
*/
|
*/
|
||||||
int skill_clear_group(struct block_list *bl, int flag)
|
int skill_clear_group(block_list *bl, uint8 flag)
|
||||||
{
|
{
|
||||||
nullpo_ret(bl);
|
nullpo_ret(bl);
|
||||||
|
|
||||||
@ -17875,8 +17875,10 @@ int skill_clear_group(struct block_list *bl, int flag)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
|
bool deleted;
|
||||||
|
|
||||||
for (auto it = ud->skillunits.begin(); it != ud->skillunits.end(); it++) {
|
// The after loop statement might look stupid, but this prevents iteration problems, if an entry was deleted
|
||||||
|
for (auto it = ud->skillunits.begin(); it != ud->skillunits.end(); (deleted ? it = ud->skillunits.begin() : it++), deleted = false) {
|
||||||
switch ((*it)->skill_id) {
|
switch ((*it)->skill_id) {
|
||||||
case SA_DELUGE:
|
case SA_DELUGE:
|
||||||
case SA_VOLCANO:
|
case SA_VOLCANO:
|
||||||
@ -17890,6 +17892,7 @@ int skill_clear_group(struct block_list *bl, int flag)
|
|||||||
if (flag & 1) {
|
if (flag & 1) {
|
||||||
skill_delunitgroup(*it);
|
skill_delunitgroup(*it);
|
||||||
count++;
|
count++;
|
||||||
|
deleted = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SO_CLOUD_KILL:
|
case SO_CLOUD_KILL:
|
||||||
@ -17897,18 +17900,21 @@ int skill_clear_group(struct block_list *bl, int flag)
|
|||||||
if (flag & 4) {
|
if (flag & 4) {
|
||||||
skill_delunitgroup(*it);
|
skill_delunitgroup(*it);
|
||||||
count++;
|
count++;
|
||||||
|
deleted = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SO_WARMER:
|
case SO_WARMER:
|
||||||
if (flag & 8) {
|
if (flag & 8) {
|
||||||
skill_delunitgroup(*it);
|
skill_delunitgroup(*it);
|
||||||
count++;
|
count++;
|
||||||
|
deleted = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (flag & 2 && skill_get_inf2((*it)->skill_id, INF2_ISTRAP)) {
|
if (flag & 2 && skill_get_inf2((*it)->skill_id, INF2_ISTRAP)) {
|
||||||
skill_delunitgroup(*it);
|
skill_delunitgroup(*it);
|
||||||
count++;
|
count++;
|
||||||
|
deleted = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -568,7 +568,7 @@ std::shared_ptr<s_skill_unit_group> skill_initunitgroup(struct block_list* src,
|
|||||||
int skill_delunitgroup_(std::shared_ptr<s_skill_unit_group> group, const char* file, int line, const char* func);
|
int skill_delunitgroup_(std::shared_ptr<s_skill_unit_group> group, const char* file, int line, const char* func);
|
||||||
#define skill_delunitgroup(group) skill_delunitgroup_(group,__FILE__,__LINE__,__func__)
|
#define skill_delunitgroup(group) skill_delunitgroup_(group,__FILE__,__LINE__,__func__)
|
||||||
void skill_clear_unitgroup(struct block_list *src);
|
void skill_clear_unitgroup(struct block_list *src);
|
||||||
int skill_clear_group(struct block_list *bl, int flag);
|
int skill_clear_group(block_list *bl, uint8 flag);
|
||||||
void ext_skill_unit_onplace(struct skill_unit *unit, struct block_list *bl, t_tick tick);
|
void ext_skill_unit_onplace(struct skill_unit *unit, struct block_list *bl, t_tick tick);
|
||||||
int64 skill_unit_ondamaged(struct skill_unit *unit,int64 damage);
|
int64 skill_unit_ondamaged(struct skill_unit *unit,int64 damage);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user