diff --git a/common/bazaar.cpp b/common/bazaar.cpp index a9c2fad21..d670b0880 100644 --- a/common/bazaar.cpp +++ b/common/bazaar.cpp @@ -265,7 +265,7 @@ Bazaar::GetSearchResults( std::unordered_set trader_items_ids{}; // auto const trader_results = TraderRepository::GetBazaarTraderDetails(db, search_criteria_trader, search.max_results); - auto const item_results = TraderRepository::GetBazaarTraderDetails( + auto const trader_results = TraderRepository::GetBazaarTraderDetails( db, search_criteria_trader, search.item_name, @@ -274,37 +274,66 @@ Bazaar::GetSearchResults( search.max_results ); - // if (trader_results.empty()) { - // LogTradingDetail("Bazaar - No traders found in bazaar search."); - // return all_entries; - // } + if (trader_results.empty()) { + LogTradingDetail("Bazaar - No traders found in bazaar search."); + return all_entries; + } - // for (auto const &i: trader_results) { - // trader_items_ids.emplace(std::to_string(i.trader.item_id)); - // //trader_items_ids.push_back(std::to_string(i.trader.item_id)); - // } + for (auto const &i: trader_results) { + trader_items_ids.emplace(std::to_string(i.trader.item_id)); + //trader_items_ids.push_back(std::to_string(i.trader.item_id)); + } - // auto const item_results = ItemsRepository::GetItemsForBazaarSearch( - // content_db, - // trader_items_ids, - // std::string(search.item_name), - // field_criteria_items, - // where_criteria_items, - // search.max_results - // ); + auto const item_results = ItemsRepository::GetItemsForBazaarSearch( + content_db, + trader_items_ids, + std::string(search.item_name), + field_criteria_items, + where_criteria_items, + search.max_results + ); if (item_results.empty()) { LogTradingDetail("Bazaar - No items found in bazaar search."); return all_entries; } - //all_entries.reserve(trader_results.size()); + all_entries.reserve(trader_results.size()); - // for (auto const& t:trader_results) { - // if (!item_results.contains(t.trader.item_id)) { - // continue; - // } - // + for (auto const& t:trader_results) { + if (!item_results.contains(t.trader.item_id)) { + continue; + } + + BazaarSearchResultsFromDB_Struct r{}; + r.count = 1; + r.trader_id = t.trader.character_id; + r.item_unique_id = t.trader.item_unique_id; + r.cost = t.trader.item_cost; + r.slot_id = t.trader.slot_id; + r.charges = t.trader.item_charges; + r.stackable = item_results.at(t.trader.item_id).stackable; + r.icon_id = item_results.at(t.trader.item_id).icon; + r.trader_zone_id = t.trader.char_zone_id; + r.trader_zone_instance_id = t.trader.char_zone_instance_id; + r.trader_entity_id = t.trader.char_entity_id; + r.item_name = fmt::format("{:.63}\0", item_results.at(t.trader.item_id).name); + r.trader_name = fmt::format("{:.63}\0", t.trader_name); + r.item_stat = item_results.at(t.trader.item_id).stats; + + if (RuleB(Bazaar, UseAlternateBazaarSearch)) { + if (convert || + char_zone_id != Zones::BAZAAR || + (char_zone_id == Zones::BAZAAR && r.trader_zone_instance_id != char_zone_instance_id) + ) { + r.trader_id = TraderRepository::TRADER_CONVERT_ID + r.trader_zone_instance_id; + } + } + + all_entries.push_back(r); + } + + // for (auto const& t:item_results) { // BazaarSearchResultsFromDB_Struct r{}; // r.count = 1; // r.trader_id = t.trader.character_id; @@ -312,14 +341,14 @@ Bazaar::GetSearchResults( // r.cost = t.trader.item_cost; // r.slot_id = t.trader.slot_id; // r.charges = t.trader.item_charges; - // r.stackable = item_results.at(t.trader.item_id).stackable; - // r.icon_id = item_results.at(t.trader.item_id).icon; + // r.stackable = t.stackable; + // r.icon_id = t.icon; // r.trader_zone_id = t.trader.char_zone_id; // r.trader_zone_instance_id = t.trader.char_zone_instance_id; // r.trader_entity_id = t.trader.char_entity_id; - // r.item_name = fmt::format("{:.63}\0", item_results.at(t.trader.item_id).name); + // r.item_name = fmt::format("{:.63}\0", t.name); // r.trader_name = fmt::format("{:.63}\0", t.trader_name); - // r.item_stat = item_results.at(t.trader.item_id).stats; + // r.item_stat = t.stats; // // if (RuleB(Bazaar, UseAlternateBazaarSearch)) { // if (convert || @@ -333,35 +362,6 @@ Bazaar::GetSearchResults( // all_entries.push_back(r); // } - for (auto const& t:item_results) { - BazaarSearchResultsFromDB_Struct r{}; - r.count = 1; - r.trader_id = t.trader.character_id; - r.item_unique_id = t.trader.item_unique_id; - r.cost = t.trader.item_cost; - r.slot_id = t.trader.slot_id; - r.charges = t.trader.item_charges; - r.stackable = t.stackable; - r.icon_id = t.icon; - r.trader_zone_id = t.trader.char_zone_id; - r.trader_zone_instance_id = t.trader.char_zone_instance_id; - r.trader_entity_id = t.trader.char_entity_id; - r.item_name = fmt::format("{:.63}\0", t.name); - r.trader_name = fmt::format("{:.63}\0", t.trader_name); - r.item_stat = t.stats; - - if (RuleB(Bazaar, UseAlternateBazaarSearch)) { - if (convert || - char_zone_id != Zones::BAZAAR || - (char_zone_id == Zones::BAZAAR && r.trader_zone_instance_id != char_zone_instance_id) - ) { - r.trader_id = TraderRepository::TRADER_CONVERT_ID + r.trader_zone_instance_id; - } - } - - all_entries.push_back(r); - } - // if (all_entries.size() > search.max_results) { // all_entries.resize(search.max_results); // } diff --git a/common/patches/rof2_structs.h b/common/patches/rof2_structs.h index d544dc1d3..745ecc470 100644 --- a/common/patches/rof2_structs.h +++ b/common/patches/rof2_structs.h @@ -3616,22 +3616,22 @@ struct TraderStatus_Struct { }; struct TraderBuy_Struct { -/*000*/ uint32 action; -/*004*/ uint32 method; -/*008*/ uint32 sub_action; -/*012*/ uint32 unknown_012; -/*016*/ uint32 trader_id; -/*020*/ char buyer_name[64]; -/*084*/ char seller_name[64]; -/*148*/ char unknown_148[32]; -/*180*/ char item_name[64]; -/*244*/ char item_unique_id[17]; -/*261*/ char unknown_261[3]; -/*264*/ uint32 item_id; -/*268*/ uint32 price; -/*272*/ uint32 already_sold; -/*276*/ uint32 unknown_276; -/*280*/ uint32 quantity; +/*000*/ uint32 action; +/*004*/ uint32 method; +/*008*/ uint32 sub_action; +/*012*/ uint32 unknown_012; +/*016*/ uint32 trader_id; +/*020*/ char buyer_name[64]; +/*084*/ char seller_name[64]; +/*148*/ char unknown_148[32]; +/*180*/ char item_name[64]; +/*244*/ char item_unique_id[17]; +/*261*/ char unknown_261[3]; +/*264*/ uint32 item_id; +/*268*/ uint32 price; +/*272*/ uint32 already_sold; +/*276*/ uint32 unknown_276; +/*280*/ uint32 quantity; /*284*/ }; diff --git a/common/repositories/trader_repository.h b/common/repositories/trader_repository.h index 32381da55..edbe0069b 100644 --- a/common/repositories/trader_repository.h +++ b/common/repositories/trader_repository.h @@ -309,41 +309,41 @@ public: { std::vector all_entries{}; - auto query_2 = fmt::format( - "WITH ranked_trader_items AS (" - "SELECT trader.id, trader.character_id, trader.item_id, trader.item_unique_id, trader.augment_one, " - "trader.augment_two, trader.augment_three, trader.augment_four, trader.augment_five, trader.augment_six, " - "trader.item_charges, trader.item_cost, trader.slot_id, trader.char_entity_id, trader.char_zone_id, " - "trader.char_zone_instance_id, trader.active_transaction, c.`name`, " - "items.name AS n1, items.stackable, items.icon, {}, " - "ROW_NUMBER() OVER (PARTITION BY trader.character_id) AS row_num " - "FROM trader " - "INNER JOIN character_data AS c ON trader.character_id = c.id " - "JOIN peq642024_content.items AS items ON trader.item_id = items.id " - "WHERE items.`name` LIKE '%{}%' AND {} AND {}" - ") " - "SELECT * FROM ranked_trader_items " - "WHERE row_num <= '{}';", - field_criteria_items, - Strings::Escape(name), - where_criteria_items, - search_criteria_trader, - max_results - ); - - // auto query = fmt::format( + // auto query_2 = fmt::format( + // "WITH ranked_trader_items AS (" // "SELECT trader.id, trader.character_id, trader.item_id, trader.item_unique_id, trader.augment_one, " // "trader.augment_two, trader.augment_three, trader.augment_four, trader.augment_five, trader.augment_six, " // "trader.item_charges, trader.item_cost, trader.slot_id, trader.char_entity_id, trader.char_zone_id, " - // "trader.char_zone_instance_id, trader.active_transaction, c.`name` FROM `trader` " + // "trader.char_zone_instance_id, trader.active_transaction, c.`name`, " + // "items.name AS n1, items.stackable, items.icon, {}, " + // "ROW_NUMBER() OVER (PARTITION BY trader.character_id) AS row_num " + // "FROM trader " // "INNER JOIN character_data AS c ON trader.character_id = c.id " - // "WHERE {} " - // "GROUP BY trader.item_id " - // "ORDER BY trader.character_id ASC", - // search_criteria_trader + // "JOIN peq642024_content.items AS items ON trader.item_id = items.id " + // "WHERE items.`name` LIKE '%{}%' AND {} AND {}" + // ") " + // "SELECT * FROM ranked_trader_items " + // "WHERE row_num <= '{}';", + // field_criteria_items, + // Strings::Escape(name), + // where_criteria_items, + // search_criteria_trader, + // max_results // ); - auto results = db.QueryDatabase(query_2); + auto query = fmt::format( + "SELECT trader.id, trader.character_id, trader.item_id, trader.item_unique_id, trader.augment_one, " + "trader.augment_two, trader.augment_three, trader.augment_four, trader.augment_five, trader.augment_six, " + "trader.item_charges, trader.item_cost, trader.slot_id, trader.char_entity_id, trader.char_zone_id, " + "trader.char_zone_instance_id, trader.active_transaction, c.`name` FROM `trader` " + "INNER JOIN character_data AS c ON trader.character_id = c.id " + "WHERE {} " + "GROUP BY trader.item_id " + "ORDER BY trader.character_id ASC", + search_criteria_trader + ); + + auto results = db.QueryDatabase(query); if (results.RowCount() == 0) { return all_entries; @@ -371,10 +371,10 @@ public: e.trader.char_zone_instance_id = row[15] ? static_cast(atoi(row[15])) : 0; e.trader.active_transaction = row[16] ? static_cast(strtoul(row[16], nullptr, 10)) : 0; e.trader_name = row[17] ? row[17] : std::string(""); - e.name = row[18] ? row[18] : ""; - e.stackable = atoi(row[19]) ? true : false; - e.icon = row[20] ? static_cast(atoi(row[20])) : 0; - e.stats = row[21] ? static_cast(atoi(row[21])) : 0; + // e.name = row[18] ? row[18] : ""; + // e.stackable = atoi(row[19]) ? true : false; + // e.icon = row[20] ? static_cast(atoi(row[20])) : 0; + // e.stats = row[21] ? static_cast(atoi(row[21])) : 0; all_entries.push_back(e); } diff --git a/zone/client.cpp b/zone/client.cpp index a27801e2b..5b990635a 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -21,8 +21,6 @@ #include #include "../common/global_define.h" -#include "../common/repositories/inventory_snapshots_repository.h" - // for windows compile #ifndef _WINDOWS #include diff --git a/zone/inventory.cpp b/zone/inventory.cpp index 30d19b6f0..3a8eb0260 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -4693,6 +4693,10 @@ bool Client::PutItemInInventoryWithStacking(EQ::ItemInstance *inst) uint8 bag_size = inv_inst->GetItem()->BagSlots; for (uint8 bag_slot = EQ::invbag::SLOT_BEGIN; bag_slot < bag_size; bag_slot++) { + if (quantity == 0) { + break; + } + auto bag_inst = GetInv().GetItem(base_slot_id + bag_slot); if (!bag_inst && inv_inst->GetItem()->BagSize >= inst->GetItem()->Size) { LogError("Found a parent {} base_slot_id {} bag_slot {} in bag", i, base_slot_id, bag_slot); diff --git a/zone/trading.cpp b/zone/trading.cpp index 0b00dcc56..c78cca0fb 100644 --- a/zone/trading.cpp +++ b/zone/trading.cpp @@ -1399,18 +1399,6 @@ static void BazaarAuditTrail(const char *seller, const char *buyer, const char * void Client::BuyTraderItem(const EQApplicationPacket *app) { - struct Checks { - bool take_customer_money {false}; - bool give_trader_money {false}; - bool give_customer_item {false}; - bool take_trader_item {false}; - uint64 customer_money {false}; - uint64 trader_money {false}; - EQ::ItemInstance *trader_item {nullptr}; - EQ::ItemInstance *customer_item {nullptr}; - }; - - Checks checks{}; auto in = reinterpret_cast(app->pBuffer); auto trader = entity_list.GetClientByID(in->trader_id); @@ -1433,7 +1421,7 @@ void Client::BuyTraderItem(const EQApplicationPacket *app) return; } - int16 quantity = static_cast(in->quantity); + auto quantity = in->quantity; inst_copy->SetCharges(quantity); if (inst_copy->IsStackable() && quantity != buy_inst->GetCharges()) { inst_copy->CreateUniqueID(); @@ -1448,8 +1436,6 @@ void Client::BuyTraderItem(const EQApplicationPacket *app) if (CheckLoreConflict(inst_copy->GetItem())) { MessageString(Chat::Red, DUPLICATE_LORE); - in->method = BazaarByParcel; - in->sub_action = DataOutDated; TradeRequestFailed(app); return; } @@ -1488,7 +1474,6 @@ void Client::BuyTraderItem(const EQApplicationPacket *app) TradeRequestFailed(app); return; } - checks.take_customer_money = true; if (!trader->RemoveItemByItemUniqueId(buy_inst->GetUniqueID(), quantity)) { AddMoneyToPP(total_cost, true); @@ -1496,10 +1481,8 @@ void Client::BuyTraderItem(const EQApplicationPacket *app) TradeRequestFailed(app); return; } - checks.take_trader_item = true; trader->AddMoneyToPP(total_cost, true); - checks.give_trader_money = true; if (!PutItemInInventoryWithStacking(inst_copy.get())) { AddMoneyToPP(total_cost, true); @@ -1509,7 +1492,6 @@ void Client::BuyTraderItem(const EQApplicationPacket *app) TradeRequestFailed(app); return; } - checks.give_customer_item = true; auto [slot_id, merchant_data] = GetDataFromMerchantListByItemUniqueId(buy_inst->GetUniqueID()); auto [item_id, merchant_quantity, item_unique_id] = merchant_data; @@ -1526,17 +1508,21 @@ void Client::BuyTraderItem(const EQApplicationPacket *app) QueuePacket(app); - LogTrading("Customer Paid: [{}] in Copper", total_cost); - LogTrading("Trader Received: [{}] in Copper", total_cost); + LogTrading("Customer Paid: [{}] to {}", DetermineMoneyString(total_cost), trader->GetCleanName()); + LogTrading("Customer Received: [{}] {} with unique_id of {}", quantity, in->item_name, inst_copy->GetUniqueID()); + LogTrading("Trader Received: [{}] from {}", DetermineMoneyString(total_cost), GetCleanName()); + LogTrading("Trader Sent: [{}] {} with unique_id of {}", quantity, in->item_name, buy_inst->GetUniqueID()); if (merchant_quantity > quantity) { std::unique_ptr vendor_inst(buy_inst ? buy_inst->Clone() : nullptr); vendor_inst->SetMerchantCount(merchant_quantity - quantity); vendor_inst->SetMerchantSlot(slot_id); vendor_inst->SetPrice(in->price); + auto list = GetTraderMerchantList(); - TraderRepository::UpdateQuantity(database, item_unique_id, merchant_quantity - quantity); std::get<1>(list->at(slot_id)) -= quantity; + + TraderRepository::UpdateQuantity(database, item_unique_id, merchant_quantity - quantity); SendItemPacket(slot_id, vendor_inst.get(), ItemPacketMerchant); } else { @@ -1552,6 +1538,7 @@ void Client::BuyTraderItem(const EQApplicationPacket *app) auto list = GetTraderMerchantList(); list->erase(slot_id); + TraderRepository::DeleteWhere(database, fmt::format("`item_unique_id` = '{}'", item_unique_id)); }