mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-04-17 01:23:51 +00:00
Fix online selling: CMSG_SELL_ITEM count as uint32, read coinage from field 1219, handle sell/inventory errors
This commit is contained in:
parent
4c530e9cee
commit
8b141658b7
5 changed files with 60 additions and 9 deletions
|
|
@ -364,7 +364,7 @@ public:
|
|||
void openVendor(uint64_t npcGuid);
|
||||
void closeVendor();
|
||||
void buyItem(uint64_t vendorGuid, uint32_t itemId, uint32_t slot, uint8_t count);
|
||||
void sellItem(uint64_t vendorGuid, uint64_t itemGuid, uint8_t count);
|
||||
void sellItem(uint64_t vendorGuid, uint64_t itemGuid, uint32_t count);
|
||||
void sellItemBySlot(int backpackIndex);
|
||||
void autoEquipItemBySlot(int backpackIndex);
|
||||
void useItemBySlot(int backpackIndex);
|
||||
|
|
|
|||
|
|
@ -1277,7 +1277,7 @@ public:
|
|||
/** CMSG_SELL_ITEM packet builder */
|
||||
class SellItemPacket {
|
||||
public:
|
||||
static network::Packet build(uint64_t vendorGuid, uint64_t itemGuid, uint8_t count);
|
||||
static network::Packet build(uint64_t vendorGuid, uint64_t itemGuid, uint32_t count);
|
||||
};
|
||||
|
||||
/** SMSG_LIST_INVENTORY parser */
|
||||
|
|
|
|||
|
|
@ -1183,9 +1183,49 @@ void GameHandler::handlePacket(network::Packet& packet) {
|
|||
}
|
||||
case Opcode::SMSG_LOOT_CLEAR_MONEY:
|
||||
case Opcode::SMSG_NPC_TEXT_UPDATE:
|
||||
case Opcode::SMSG_SELL_ITEM:
|
||||
break;
|
||||
case Opcode::SMSG_SELL_ITEM: {
|
||||
// uint64 vendorGuid, uint64 itemGuid, uint8 result
|
||||
if ((packet.getSize() - packet.getReadPos()) >= 17) {
|
||||
packet.readUInt64(); // vendorGuid
|
||||
packet.readUInt64(); // itemGuid
|
||||
uint8_t result = packet.readUInt8();
|
||||
if (result != 0) {
|
||||
static const char* sellErrors[] = {
|
||||
"OK", "Can't find item", "Can't sell item",
|
||||
"Can't find vendor", "You don't own that item",
|
||||
"Unknown error", "Only empty bag"
|
||||
};
|
||||
const char* msg = (result < 7) ? sellErrors[result] : "Unknown sell error";
|
||||
addSystemChatMessage(std::string("Sell failed: ") + msg);
|
||||
LOG_WARNING("SMSG_SELL_ITEM error: ", (int)result, " (", msg, ")");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Opcode::SMSG_INVENTORY_CHANGE_FAILURE: {
|
||||
if ((packet.getSize() - packet.getReadPos()) >= 1) {
|
||||
uint8_t error = packet.readUInt8();
|
||||
if (error != 0) {
|
||||
LOG_WARNING("SMSG_INVENTORY_CHANGE_FAILURE: error=", (int)error);
|
||||
// Common error codes
|
||||
std::string msg;
|
||||
switch (error) {
|
||||
case 1: msg = "Item slots occupied."; break;
|
||||
case 4: msg = "Item doesn't go there."; break;
|
||||
case 5: msg = "Bag is full."; break;
|
||||
case 14: msg = "Can't equip that."; break;
|
||||
case 23: msg = "Can't equip with two-handed weapon."; break;
|
||||
case 26: msg = "Inventory full."; break;
|
||||
case 29: msg = "Item is locked."; break;
|
||||
default: msg = "Inventory error (" + std::to_string(error) + ")."; break;
|
||||
}
|
||||
addSystemChatMessage(msg);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Opcode::SMSG_BUY_FAILED:
|
||||
case Opcode::SMSG_INVENTORY_CHANGE_FAILURE:
|
||||
case Opcode::SMSG_GAMEOBJECT_QUERY_RESPONSE:
|
||||
case Opcode::MSG_RAID_TARGET_UPDATE:
|
||||
case Opcode::SMSG_QUESTGIVER_STATUS:
|
||||
|
|
@ -2635,7 +2675,7 @@ void GameHandler::handleUpdateObject(network::Packet& packet) {
|
|||
if (ch.guid == playerGuid) { ch.level = val; break; }
|
||||
}
|
||||
}
|
||||
else if (key == 632) { playerMoneyCopper_ = val; } // PLAYER_FIELD_COINAGE
|
||||
else if (key == 1219) { playerMoneyCopper_ = val; } // PLAYER_FIELD_COINAGE
|
||||
}
|
||||
if (applyInventoryFields(block.fields)) slotsChanged = true;
|
||||
if (slotsChanged) rebuildOnlineInventory();
|
||||
|
|
@ -2728,7 +2768,7 @@ void GameHandler::handleUpdateObject(network::Packet& packet) {
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (key == 632) {
|
||||
else if (key == 1219) {
|
||||
playerMoneyCopper_ = val;
|
||||
LOG_INFO("Money updated via VALUES: ", val, " copper");
|
||||
}
|
||||
|
|
@ -4072,7 +4112,7 @@ void GameHandler::buyItem(uint64_t vendorGuid, uint32_t itemId, uint32_t slot, u
|
|||
socket->send(packet);
|
||||
}
|
||||
|
||||
void GameHandler::sellItem(uint64_t vendorGuid, uint64_t itemGuid, uint8_t count) {
|
||||
void GameHandler::sellItem(uint64_t vendorGuid, uint64_t itemGuid, uint32_t count) {
|
||||
if (state != WorldState::IN_WORLD || !socket) return;
|
||||
auto packet = SellItemPacket::build(vendorGuid, itemGuid, count);
|
||||
socket->send(packet);
|
||||
|
|
@ -4099,10 +4139,17 @@ void GameHandler::sellItemBySlot(int backpackIndex) {
|
|||
if (itemGuid == 0) {
|
||||
itemGuid = resolveOnlineItemGuid(slot.item.itemId);
|
||||
}
|
||||
LOG_DEBUG("sellItemBySlot: slot=", backpackIndex,
|
||||
" item=", slot.item.name,
|
||||
" itemGuid=0x", std::hex, itemGuid, std::dec,
|
||||
" vendorGuid=0x", std::hex, currentVendorItems.vendorGuid, std::dec);
|
||||
if (itemGuid != 0 && currentVendorItems.vendorGuid != 0) {
|
||||
sellItem(currentVendorItems.vendorGuid, itemGuid, 1);
|
||||
} else if (itemGuid == 0) {
|
||||
addSystemChatMessage("Cannot sell: item not found in inventory.");
|
||||
LOG_WARNING("Sell failed: missing item GUID for slot ", backpackIndex);
|
||||
} else {
|
||||
addSystemChatMessage("Cannot sell: no vendor.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2104,11 +2104,11 @@ network::Packet BuyItemPacket::build(uint64_t vendorGuid, uint32_t itemId, uint3
|
|||
return packet;
|
||||
}
|
||||
|
||||
network::Packet SellItemPacket::build(uint64_t vendorGuid, uint64_t itemGuid, uint8_t count) {
|
||||
network::Packet SellItemPacket::build(uint64_t vendorGuid, uint64_t itemGuid, uint32_t count) {
|
||||
network::Packet packet(static_cast<uint16_t>(Opcode::CMSG_SELL_ITEM));
|
||||
packet.writeUInt64(vendorGuid);
|
||||
packet.writeUInt64(itemGuid);
|
||||
packet.writeUInt8(count);
|
||||
packet.writeUInt32(count);
|
||||
return packet;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1084,6 +1084,10 @@ void InventoryScreen::renderItemSlot(game::Inventory& inventory, const game::Ite
|
|||
|
||||
// Right-click: vendor sell (if vendor mode) or auto-equip/unequip
|
||||
if (ImGui::IsItemClicked(ImGuiMouseButton_Right) && !holdingItem) {
|
||||
LOG_DEBUG("Right-click slot: kind=", (int)kind,
|
||||
" backpackIndex=", backpackIndex,
|
||||
" vendorMode=", vendorMode_,
|
||||
" hasHandler=", (gameHandler_ != nullptr));
|
||||
if (vendorMode_ && gameHandler_ && kind == SlotKind::BACKPACK && backpackIndex >= 0) {
|
||||
// Sell to vendor
|
||||
gameHandler_->sellItemBySlot(backpackIndex);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue