From 382bc6b7ce97f1e46a3c86c49414548055dcd4be Mon Sep 17 00:00:00 2001 From: Martin Michelsen Date: Wed, 4 Mar 2026 21:18:45 -0800 Subject: [PATCH] don't allow error cases for bb_exchange_pd_percent to destroy items --- src/QuestScript.cc | 2 +- src/ReceiveSubcommands.cc | 14 ++++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/QuestScript.cc b/src/QuestScript.cc index 1de207b6..bdb6d9cc 100644 --- a/src/QuestScript.cc +++ b/src/QuestScript.cc @@ -2004,7 +2004,7 @@ static const QuestScriptOpcodeDefinition opcode_defs[] = { {0xF8CB, "clear_slot_invincible", "set_slot_targetable?", {R_REG}, F_V3_V4}, // These opcodes inflict various status conditions on a player. In the case of Shifta/Deband/Jellen/Zalure, the - // effective technicuqe level is 21. + // effective technique level is 21. // regA = client ID {0xF8CC, "set_slot_poison", nullptr, {R_REG}, F_V3_V4}, {0xF8CD, "set_slot_paralyze", nullptr, {R_REG}, F_V3_V4}, diff --git a/src/ReceiveSubcommands.cc b/src/ReceiveSubcommands.cc index fa52d48a..a857c11c 100644 --- a/src/ReceiveSubcommands.cc +++ b/src/ReceiveSubcommands.cc @@ -5377,10 +5377,8 @@ static asio::awaitable on_upgrade_weapon_attribute_bb(shared_ptr c if (payment_item.stack_size(*s->item_stack_limits(c->version())) < cmd.payment_count) { throw runtime_error("not enough payment items present"); } - p->remove_item(payment_item.id, cmd.payment_count, *s->item_stack_limits(c->version())); - send_destroy_item_to_lobby(c, payment_item.id, cmd.payment_count); - uint8_t attribute_amount = 0; + int8_t attribute_amount = 0; if (cmd.payment_type == 1 && cmd.payment_count == 1) { attribute_amount = 30; } else if (cmd.payment_type == 0 && cmd.payment_count == 4) { @@ -5401,8 +5399,16 @@ static asio::awaitable on_upgrade_weapon_attribute_bb(shared_ptr c if (attribute_index == 0) { throw runtime_error("no available attribute slots"); } + int8_t new_attr_value = static_cast(item.data1[attribute_index + 1]) + attribute_amount; + if (new_attr_value > 100) { + throw runtime_error("bonus value exceeds 100"); + } + + p->remove_item(payment_item.id, cmd.payment_count, *s->item_stack_limits(c->version())); + send_destroy_item_to_lobby(c, payment_item.id, cmd.payment_count); + item.data1[attribute_index] = cmd.attribute; - item.data1[attribute_index + 1] += attribute_amount; + item.data1[attribute_index + 1] += new_attr_value; send_destroy_item_to_lobby(c, item.id, 1); send_create_inventory_item_to_lobby(c, c->lobby_client_id, item);