fix: guard the group-loot division by zero

OnLootMoney counts group members within loot reward distance, then divides
gold by that count with no guard. If no member passes the distance check the
count stays 0 and the division raises SIGFPE, taking worldserver down. The
looter normally counts themselves so this is a latent rather than live bug,
but the guard is free.

Also hoists the LootMultiplier check above the member loop, which skips the
whole walk when the module is configured off, and drops the now-redundant
second test in the solo branch.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019vTNrJGsprcjdjjjDJD5ZM
This commit is contained in:
Claude 2026-09-03 17:21:13 +00:00
parent f69bff1cfa
commit d114e665be
No known key found for this signature in database

View file

@ -5,6 +5,9 @@
void GuildFunds::OnLootMoney(Player* player, uint32 gold) void GuildFunds::OnLootMoney(Player* player, uint32 gold)
{ {
if (LootMultiplier < 1)
return;
if (Group* group = player->GetGroup()) if (Group* group = player->GetGroup())
{ {
uint32 membersInRange = 0; uint32 membersInRange = 0;
@ -17,7 +20,10 @@ void GuildFunds::OnLootMoney(Player* player, uint32 gold)
} }
} }
if (LootMultiplier < 1) // Guard the division. In practice the looter counts themselves, but a group whose
// members all fail the distance check would divide by zero and take worldserver
// down with SIGFPE.
if (!membersInRange)
return; return;
uint32 money = (gold / membersInRange) * LootMultiplier / 100; uint32 money = (gold / membersInRange) * LootMultiplier / 100;
@ -49,7 +55,7 @@ void GuildFunds::OnLootMoney(Player* player, uint32 gold)
{ {
uint32 money = gold * LootMultiplier / 100; uint32 money = gold * LootMultiplier / 100;
if (money < 1 || LootMultiplier < 1) if (money < 1)
return; return;
guild->HandleMemberDepositMoney(player->GetSession(), money); guild->HandleMemberDepositMoney(player->GetSession(), money);