mirror of
https://github.com/EQEmu/Server.git
synced 2026-01-26 08:33:53 +00:00
Added checks for same item with price change. Client treats them all the same so all need to be updated. Also repaired max stacksize of 32767 on RoF2
This commit is contained in:
parent
32daa4834c
commit
5de05763ad
@ -439,7 +439,7 @@ namespace RoF2
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
LogTradingDetail("Unhandled action <red>[{}]", sub_action);
|
//LogTradingDetail("Unhandled action <red>[{}]", sub_action);
|
||||||
dest->FastQueuePacket(&in);
|
dest->FastQueuePacket(&in);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -533,7 +533,7 @@ namespace RoF2
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
LogTrading("(RoF2) Unhandled action <red>[{}]", action);
|
//LogTradingDetail("(RoF2) Unhandled action <red>[{}]", action);
|
||||||
dest->FastQueuePacket(&in, ack_req);
|
dest->FastQueuePacket(&in, ack_req);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -622,10 +622,10 @@ namespace RoF2
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
LogTrading(
|
// LogTradingDetail(
|
||||||
"(RoF2) Unhandled action <red>[{}]",
|
// "(RoF2) Unhandled action <red>[{}]",
|
||||||
in->action
|
// in->action
|
||||||
);
|
// );
|
||||||
dest->QueuePacket(inapp);
|
dest->QueuePacket(inapp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4339,7 +4339,7 @@ namespace RoF2
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
LogTrading("(RoF2) Unhandled action <red>[{}]", action);
|
// LogTradingDetail("(RoF2) Unhandled action <red>[{}]", action);
|
||||||
EQApplicationPacket *in = *p;
|
EQApplicationPacket *in = *p;
|
||||||
*p = nullptr;
|
*p = nullptr;
|
||||||
|
|
||||||
@ -6224,7 +6224,7 @@ namespace RoF2
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
LogTrading("(RoF2) Unhandled action <red>[{}]", action);
|
//LogTradingDetail("(RoF2) Unhandled action <red>[{}]", action);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6357,7 +6357,7 @@ namespace RoF2
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
LogTrading("(RoF2) Unhandled action <red>[{}]", action);
|
//LogTradingDetail("(RoF2) Unhandled action <red>[{}]", action);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -307,6 +307,7 @@ namespace RoF2
|
|||||||
const size_t SAY_LINK_BODY_SIZE = 56;
|
const size_t SAY_LINK_BODY_SIZE = 56;
|
||||||
const uint32 MAX_GUILD_ID = 50000;
|
const uint32 MAX_GUILD_ID = 50000;
|
||||||
const uint32 MAX_BAZAAR_TRADERS = 600;
|
const uint32 MAX_BAZAAR_TRADERS = 600;
|
||||||
|
const uint64 MAX_BAZAAR_TRANSACTION = 3276700000000; //3276700000000
|
||||||
|
|
||||||
} /*constants*/
|
} /*constants*/
|
||||||
|
|
||||||
|
|||||||
@ -198,30 +198,40 @@ public:
|
|||||||
return UpdateOne(db, m);
|
return UpdateOne(db, m);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int UpdatePrice(Database &db, const std::string &item_unique_id, uint32 price)
|
static std::vector<Trader> UpdatePrice(Database &db, const std::string &item_unique_id, uint32 price)
|
||||||
{
|
{
|
||||||
const auto trader_item = GetWhere(
|
std::vector<Trader> all_entries{};
|
||||||
db,
|
|
||||||
fmt::format("`item_unique_id` = '{}' ", item_unique_id)
|
const auto query = fmt::format(
|
||||||
|
"UPDATE trader t1 SET t1.`item_cost` = '{}', t1.`listing_date` = FROM_UNIXTIME({}) WHERE t1.`item_id` = "
|
||||||
|
"(SELECT t2.`item_id` FROM trader t2 WHERE t2.`item_unique_id` = '{}')",
|
||||||
|
price,
|
||||||
|
time(nullptr),
|
||||||
|
item_unique_id
|
||||||
);
|
);
|
||||||
|
|
||||||
if (trader_item.empty() || trader_item.size() > 1) {
|
auto results = db.QueryDatabase(query);
|
||||||
return 0;
|
if (results.RowsAffected() == 0) {
|
||||||
|
return all_entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto m = trader_item[0];
|
all_entries = GetWhere(
|
||||||
m.item_cost = price;
|
db,
|
||||||
m.listing_date = time(nullptr);
|
fmt::format(
|
||||||
|
"`item_id` = (SELECT t1.`item_id` FROM trader t1 WHERE t1.`item_unique_id` = '{}');",
|
||||||
|
item_unique_id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
return ReplaceOne(db, m);
|
return all_entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Trader GetItemBySerialNumber(Database &db, std::string &item_unique_id, uint32 trader_id)
|
static Trader GetItemByItemUniqueNumber(Database &db, std::string &item_unique_id)
|
||||||
{
|
{
|
||||||
Trader e{};
|
Trader e{};
|
||||||
const auto trader_item = GetWhere(
|
const auto trader_item = GetWhere(
|
||||||
db,
|
db,
|
||||||
fmt::format("`character_id` = '{}' AND `item_unique_id` = '{}' LIMIT 1", trader_id, item_unique_id)
|
fmt::format("`item_unique_id` = '{}' LIMIT 1", item_unique_id)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (trader_item.empty()) {
|
if (trader_item.empty()) {
|
||||||
|
|||||||
@ -740,7 +740,7 @@ bool SharedDatabase::GetInventory(Client *c)
|
|||||||
inst->SetColor(color);
|
inst->SetColor(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (charges == std::numeric_limits<int16>::max()) {
|
if (charges > std::numeric_limits<int16>::max()) {
|
||||||
inst->SetCharges(-1);
|
inst->SetCharges(-1);
|
||||||
} else if (charges == 0 && inst->IsStackable()) {
|
} else if (charges == 0 && inst->IsStackable()) {
|
||||||
// Stackable items need a minimum charge of 1 remain moveable.
|
// Stackable items need a minimum charge of 1 remain moveable.
|
||||||
|
|||||||
@ -377,12 +377,13 @@ public:
|
|||||||
EQ::ItemInstance* FindTraderItemBySerialNumber(std::string &serial_number);
|
EQ::ItemInstance* FindTraderItemBySerialNumber(std::string &serial_number);
|
||||||
EQ::ItemInstance* FindTraderItemByUniqueID(std::string &unique_id);
|
EQ::ItemInstance* FindTraderItemByUniqueID(std::string &unique_id);
|
||||||
EQ::ItemInstance* FindTraderItemByUniqueID(const char* unique_id);
|
EQ::ItemInstance* FindTraderItemByUniqueID(const char* unique_id);
|
||||||
|
std::vector<EQ::ItemInstance *> FindTraderItemsByUniqueID(const char* unique_id);
|
||||||
void FindAndNukeTraderItem(std::string &item_unique_id, int16 quantity, Client* customer, uint16 trader_slot);
|
void FindAndNukeTraderItem(std::string &item_unique_id, int16 quantity, Client* customer, uint16 trader_slot);
|
||||||
void NukeTraderItem(uint16 slot, int16 charges, int16 quantity, Client* customer, uint16 trader_slot, const std::string &serial_number, int32 item_id = 0);
|
void NukeTraderItem(uint16 slot, int16 charges, int16 quantity, Client* customer, uint16 trader_slot, const std::string &serial_number, int32 item_id = 0);
|
||||||
void ReturnTraderReq(const EQApplicationPacket* app,int16 traderitemcharges, uint32 itemid = 0);
|
void ReturnTraderReq(const EQApplicationPacket* app,int16 traderitemcharges, uint32 itemid = 0);
|
||||||
void TradeRequestFailed(const EQApplicationPacket* app);
|
void TradeRequestFailed(const EQApplicationPacket* app);
|
||||||
void BuyTraderItem(const EQApplicationPacket* app);
|
void BuyTraderItem(const EQApplicationPacket* app);
|
||||||
void BuyTraderItemOutsideBazaar(TraderBuy_Struct* tbs, const EQApplicationPacket* app);
|
void BuyTraderItemFromBazaarWindow(const EQApplicationPacket* app);
|
||||||
void FinishTrade(
|
void FinishTrade(
|
||||||
Mob *with,
|
Mob *with,
|
||||||
bool finalizer = false,
|
bool finalizer = false,
|
||||||
@ -422,11 +423,12 @@ public:
|
|||||||
uint32 GetCustomerID() { return customer_id; }
|
uint32 GetCustomerID() { return customer_id; }
|
||||||
void SetCustomerID(uint32 id) { customer_id = id; }
|
void SetCustomerID(uint32 id) { customer_id = id; }
|
||||||
void ClearTraderMerchantList() { m_trader_merchant_list.clear(); }
|
void ClearTraderMerchantList() { m_trader_merchant_list.clear(); }
|
||||||
void AddDataToMerchantList(int16 slot_id, int32 quantity, const std::string &item_unique_id);
|
void AddDataToMerchantList(int16 slot_id, uint32 item_id, int32 quantity, const std::string &item_unique_id);
|
||||||
std::tuple<int16, std::string> GetDataFromMerchantListByMerchantSlotId(int16 slot_id);
|
int16 GetNextFreeSlotFromMerchantList();
|
||||||
|
std::tuple<uint32, int32, std::string> GetDataFromMerchantListByMerchantSlotId(int16 slot_id);
|
||||||
int16 GetSlotFromMerchantListByItemUniqueId(const std::string &unique_id);
|
int16 GetSlotFromMerchantListByItemUniqueId(const std::string &unique_id);
|
||||||
std::pair<int16, std::tuple<uint32, std::string>> GetDataFromMerchantListByItemUniqueId(const std::string &unique_id);
|
std::pair<int16, std::tuple<uint32, int32, std::string>> GetDataFromMerchantListByItemUniqueId(const std::string &unique_id);
|
||||||
std::map<int16, std::tuple<uint32, std::string>>* GetTraderMerchantList() { return &m_trader_merchant_list; }
|
std::map<int16, std::tuple<uint32, int32, std::string>>* GetTraderMerchantList() { return &m_trader_merchant_list; }
|
||||||
|
|
||||||
void SetBuyerID(uint32 id) { m_buyer_id = id; }
|
void SetBuyerID(uint32 id) { m_buyer_id = id; }
|
||||||
uint32 GetBuyerID() { return m_buyer_id; }
|
uint32 GetBuyerID() { return m_buyer_id; }
|
||||||
@ -2112,7 +2114,7 @@ private:
|
|||||||
uint8 mercSlot; // selected merc slot
|
uint8 mercSlot; // selected merc slot
|
||||||
time_t m_trader_transaction_date;
|
time_t m_trader_transaction_date;
|
||||||
uint32 m_trader_count{};
|
uint32 m_trader_count{};
|
||||||
std::map<int16, std::tuple<uint32, std::string>> m_trader_merchant_list{};
|
std::map<int16, std::tuple<uint32, int32, std::string>> m_trader_merchant_list{}; // itemid, qty, item_unique_id
|
||||||
uint32 m_buyer_id;
|
uint32 m_buyer_id;
|
||||||
uint32 m_barter_time;
|
uint32 m_barter_time;
|
||||||
int32 m_parcel_platinum;
|
int32 m_parcel_platinum;
|
||||||
|
|||||||
@ -15510,7 +15510,7 @@ void Client::Handle_OP_TraderBuy(const EQApplicationPacket *app)
|
|||||||
in->quantity,
|
in->quantity,
|
||||||
in->item_unique_id
|
in->item_unique_id
|
||||||
);
|
);
|
||||||
BuyTraderItemOutsideBazaar(in, app);
|
BuyTraderItemFromBazaarWindow(app);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BazaarByDirectToInventory: {
|
case BazaarByDirectToInventory: {
|
||||||
|
|||||||
417
zone/trading.cpp
417
zone/trading.cpp
@ -1011,7 +1011,7 @@ void Client::BulkSendTraderInventory(uint32 character_id)
|
|||||||
inst->SetMerchantCount(inst->IsStackable() ? inst->GetCharges() : 1);
|
inst->SetMerchantCount(inst->IsStackable() ? inst->GetCharges() : 1);
|
||||||
inst->SetMerchantSlot(i + 1);
|
inst->SetMerchantSlot(i + 1);
|
||||||
inst->SetPrice(trader_items.at(i).item_cost);
|
inst->SetPrice(trader_items.at(i).item_cost);
|
||||||
AddDataToMerchantList(i + 1, inst->GetMerchantCount(), inst->GetUniqueID());
|
AddDataToMerchantList(i + 1, inst->GetID(), inst->GetMerchantCount(), inst->GetUniqueID());
|
||||||
SendItemPacket(i + 1, inst.get(), ItemPacketMerchant);
|
SendItemPacket(i + 1, inst.get(), ItemPacketMerchant);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1119,6 +1119,32 @@ EQ::ItemInstance *Client::FindTraderItemByUniqueID(const char* unique_id)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<EQ::ItemInstance *> Client::FindTraderItemsByUniqueID(const char* unique_id)
|
||||||
|
{
|
||||||
|
std::vector<EQ::ItemInstance *> items{};
|
||||||
|
EQ::ItemInstance *item = nullptr;
|
||||||
|
int16 slot_id = 0;
|
||||||
|
|
||||||
|
for (int16 i = EQ::invslot::GENERAL_BEGIN; i <= EQ::invslot::GENERAL_END; i++) {
|
||||||
|
item = GetInv().GetItem(i);
|
||||||
|
if (item && item->GetItem()->BagType == EQ::item::BagTypeTradersSatchel) {
|
||||||
|
for (int16 x = EQ::invbag::SLOT_BEGIN; x <= EQ::invbag::SLOT_END; x++) {
|
||||||
|
// we already have the parent bag and a contents iterator..why not just iterate the bag!??
|
||||||
|
slot_id = EQ::InventoryProfile::CalcSlotId(i, x);
|
||||||
|
item = GetInv().GetItem(slot_id);
|
||||||
|
if (item) {
|
||||||
|
if (item->GetUniqueID().compare(unique_id) == 0) {
|
||||||
|
items.push_back(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LogTrading("Couldn't find item! item_unique_id was [{}]", unique_id);
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
GetItems2_Struct *Client::GetTraderItems()
|
GetItems2_Struct *Client::GetTraderItems()
|
||||||
{
|
{
|
||||||
const EQ::ItemInstance *item = nullptr;
|
const EQ::ItemInstance *item = nullptr;
|
||||||
@ -1469,8 +1495,8 @@ void Client::BuyTraderItem(const EQApplicationPacket *app)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto [slot_id, merchant_data] = GetDataFromMerchantListByItemUniqueId(buy_inst->GetUniqueID());
|
auto [slot_id, merchant_data] = GetDataFromMerchantListByItemUniqueId(buy_inst->GetUniqueID());
|
||||||
auto [merchant_quantity, item_unique_id] = merchant_data;
|
auto [item_id, merchant_quantity, item_unique_id] = merchant_data;
|
||||||
|
|
||||||
data->action = BazaarBuyItem;
|
data->action = BazaarBuyItem;
|
||||||
data->price = in->price;
|
data->price = in->price;
|
||||||
@ -1494,7 +1520,7 @@ void Client::BuyTraderItem(const EQApplicationPacket *app)
|
|||||||
vendor_inst->SetPrice(in->price);
|
vendor_inst->SetPrice(in->price);
|
||||||
auto list = GetTraderMerchantList();
|
auto list = GetTraderMerchantList();
|
||||||
TraderRepository::UpdateQuantity(database, item_unique_id, merchant_quantity - quantity);
|
TraderRepository::UpdateQuantity(database, item_unique_id, merchant_quantity - quantity);
|
||||||
std::get<0>(list->at(slot_id)) -= quantity;
|
std::get<1>(list->at(slot_id)) -= quantity;
|
||||||
SendItemPacket(slot_id, vendor_inst.get(), ItemPacketMerchant);
|
SendItemPacket(slot_id, vendor_inst.get(), ItemPacketMerchant);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -2459,8 +2485,8 @@ void Client::TraderUpdateItem(const EQApplicationPacket *app)
|
|||||||
auto in = reinterpret_cast<TraderPriceUpdate_Struct *>(app->pBuffer);
|
auto in = reinterpret_cast<TraderPriceUpdate_Struct *>(app->pBuffer);
|
||||||
uint32 new_price = in->new_price;
|
uint32 new_price = in->new_price;
|
||||||
auto inst = FindTraderItemByUniqueID(in->item_unique_id);
|
auto inst = FindTraderItemByUniqueID(in->item_unique_id);
|
||||||
std::unique_ptr<EQ::ItemInstance> inst_copy(inst ? inst->Clone() : nullptr);
|
|
||||||
|
|
||||||
|
auto customer = entity_list.GetClientByID(GetCustomerID());
|
||||||
if (new_price == 0) {
|
if (new_price == 0) {
|
||||||
auto result = TraderRepository::DeleteWhere(database, fmt::format("`item_unique_id` = '{}'", in->item_unique_id));
|
auto result = TraderRepository::DeleteWhere(database, fmt::format("`item_unique_id` = '{}'", in->item_unique_id));
|
||||||
if (!result) {
|
if (!result) {
|
||||||
@ -2471,30 +2497,31 @@ void Client::TraderUpdateItem(const EQApplicationPacket *app)
|
|||||||
in->sub_action = BazaarPriceChange_RemoveItem;
|
in->sub_action = BazaarPriceChange_RemoveItem;
|
||||||
QueuePacket(app);
|
QueuePacket(app);
|
||||||
|
|
||||||
auto customer = entity_list.GetClientByID(GetCustomerID());
|
if (customer && inst) {
|
||||||
if (customer && inst_copy) {
|
auto list = customer->GetTraderMerchantList();
|
||||||
auto list = customer->GetTraderMerchantList();
|
|
||||||
auto [slot_id, merchant_data] = customer->GetDataFromMerchantListByItemUniqueId(in->item_unique_id);
|
|
||||||
|
|
||||||
auto client_packet =
|
auto client_packet =
|
||||||
new EQApplicationPacket(OP_ShopDelItem, static_cast<uint32>(sizeof(Merchant_DelItem_Struct)));
|
new EQApplicationPacket(OP_ShopDelItem, static_cast<uint32>(sizeof(Merchant_DelItem_Struct)));
|
||||||
auto client_data = reinterpret_cast<struct Merchant_DelItem_Struct *>(client_packet->pBuffer);
|
|
||||||
|
|
||||||
|
auto client_data = reinterpret_cast<struct Merchant_DelItem_Struct *>(client_packet->pBuffer);
|
||||||
client_data->npcid = GetID();
|
client_data->npcid = GetID();
|
||||||
client_data->playerid = customer->GetID();
|
client_data->playerid = customer->GetID();
|
||||||
client_data->itemslot = slot_id;
|
|
||||||
|
|
||||||
customer->QueuePacket(client_packet);
|
for (auto const [slot_id, merchant_data]: *list) {
|
||||||
|
auto const [item_id, merchant_quantity, item_unique_id] = merchant_data;
|
||||||
|
if (item_id == inst->GetID()) {
|
||||||
|
client_data->itemslot = slot_id;
|
||||||
|
customer->QueuePacket(client_packet);
|
||||||
|
AddDataToMerchantList(slot_id, 0, 0, "0000000000000000");
|
||||||
|
}
|
||||||
|
}
|
||||||
safe_delete(client_packet);
|
safe_delete(client_packet);
|
||||||
|
|
||||||
list->erase(slot_id);
|
|
||||||
|
|
||||||
customer->Message(
|
customer->Message(
|
||||||
Chat::Red,
|
Chat::Red,
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"Trader {} removed item {} from the bazaar. Item no longer available.",
|
"Trader {} removed item {} from the bazaar. Item no longer available.",
|
||||||
GetCleanName(),
|
GetCleanName(),
|
||||||
inst_copy->GetItem()->Name
|
inst->GetItem()->Name
|
||||||
).c_str()
|
).c_str()
|
||||||
);
|
);
|
||||||
LogTrading("Trader removed item from trader list with item_unique_id {}", in->item_unique_id);
|
LogTrading("Trader removed item from trader list with item_unique_id {}", in->item_unique_id);
|
||||||
@ -2503,53 +2530,73 @@ void Client::TraderUpdateItem(const EQApplicationPacket *app)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto result = TraderRepository::UpdatePrice(database, in->item_unique_id, new_price);
|
auto result = TraderRepository::UpdatePrice(database, in->item_unique_id, new_price);
|
||||||
if (!result && inst_copy) {
|
if (result.empty()) {
|
||||||
// Item does not exist so it must be re-created,
|
auto trader_items = FindTraderItemsByUniqueID(in->item_unique_id);
|
||||||
TraderRepository::Trader trader_item{};
|
std::vector<TraderRepository::Trader> queue{};
|
||||||
|
for (auto const& i : trader_items) {
|
||||||
|
TraderRepository::Trader e{};
|
||||||
|
|
||||||
trader_item.id = 0;
|
e.id = 0;
|
||||||
trader_item.char_entity_id = GetID();
|
e.char_entity_id = GetID();
|
||||||
trader_item.character_id = CharacterID();
|
e.character_id = CharacterID();
|
||||||
trader_item.char_zone_id = GetZoneID();
|
e.char_zone_id = GetZoneID();
|
||||||
trader_item.char_zone_instance_id = GetInstanceID();
|
e.char_zone_instance_id = GetInstanceID();
|
||||||
trader_item.item_charges = inst_copy->GetCharges();
|
e.item_charges = i->GetCharges();
|
||||||
trader_item.item_cost = new_price;
|
e.item_cost = new_price;
|
||||||
trader_item.item_id = inst_copy->GetID();
|
e.item_id = i->GetID();
|
||||||
trader_item.item_unique_id = in->item_unique_id;
|
e.item_unique_id = i->GetUniqueID();
|
||||||
trader_item.slot_id = 0;
|
e.slot_id = 0;
|
||||||
trader_item.listing_date = time(nullptr);
|
e.listing_date = time(nullptr);
|
||||||
if (inst_copy->IsAugmented()) {
|
if (i->IsAugmented()) {
|
||||||
auto augs = inst_copy->GetAugmentIDs();
|
auto augs = i->GetAugmentIDs();
|
||||||
trader_item.augment_one = augs.at(0);
|
e.augment_one = augs.at(0);
|
||||||
trader_item.augment_two = augs.at(1);
|
e.augment_two = augs.at(1);
|
||||||
trader_item.augment_three = augs.at(2);
|
e.augment_three = augs.at(2);
|
||||||
trader_item.augment_four = augs.at(3);
|
e.augment_four = augs.at(3);
|
||||||
trader_item.augment_five = augs.at(4);
|
e.augment_five = augs.at(4);
|
||||||
trader_item.augment_six = augs.at(5);
|
e.augment_six = augs.at(5);
|
||||||
|
}
|
||||||
|
|
||||||
|
queue.push_back(e);
|
||||||
|
if (customer) {
|
||||||
|
int16 next_slot_id = GetNextFreeSlotFromMerchantList();
|
||||||
|
if (next_slot_id != INVALID_INDEX) {
|
||||||
|
std::unique_ptr<EQ::ItemInstance> vendor_inst_copy(i ? i->Clone() : nullptr);
|
||||||
|
vendor_inst_copy->SetUniqueID(i->GetUniqueID());
|
||||||
|
vendor_inst_copy->SetMerchantCount(i->IsStackable() ? i->GetCharges() : 1);
|
||||||
|
vendor_inst_copy->SetMerchantSlot(next_slot_id );
|
||||||
|
vendor_inst_copy->SetPrice(new_price);
|
||||||
|
AddDataToMerchantList(next_slot_id, i->GetID(), i->GetMerchantCount(), i->GetUniqueID());
|
||||||
|
customer->SendItemPacket(next_slot_id, vendor_inst_copy.get(), ItemPacketMerchant);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TraderRepository::ReplaceOne(database, trader_item);
|
if (!queue.empty()) {
|
||||||
|
TraderRepository::ReplaceMany(database, queue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (auto const i : result) {
|
||||||
|
auto [slot_id, merchant_data] = customer->GetDataFromMerchantListByItemUniqueId(i.item_unique_id);
|
||||||
|
auto [item_id, merchant_quantity, item_unique_id] = merchant_data;
|
||||||
|
std::unique_ptr<EQ::ItemInstance> vendor_inst_copy(inst ? inst->Clone() : nullptr);
|
||||||
|
vendor_inst_copy->SetUniqueID(i.item_unique_id);
|
||||||
|
vendor_inst_copy->SetMerchantCount(i.item_charges);
|
||||||
|
vendor_inst_copy->SetMerchantSlot(slot_id);
|
||||||
|
vendor_inst_copy->SetPrice(new_price);
|
||||||
|
customer->SendItemPacket(slot_id, vendor_inst_copy.get(), ItemPacketMerchant);
|
||||||
|
}
|
||||||
|
|
||||||
|
customer->Message(
|
||||||
|
Chat::Red,
|
||||||
|
fmt::format("Trader {} updated the price of item {}", GetCleanName(), inst->GetItem()->Name).c_str()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
in->sub_action = BazaarPriceChange_UpdatePrice;
|
in->sub_action = BazaarPriceChange_UpdatePrice;
|
||||||
QueuePacket(app);
|
QueuePacket(app);
|
||||||
|
|
||||||
auto customer = entity_list.GetClientByID(GetCustomerID());
|
|
||||||
if (customer && inst_copy) {
|
|
||||||
auto [slot_id, merchant_data] = customer->GetDataFromMerchantListByItemUniqueId(inst_copy->GetUniqueID());
|
|
||||||
auto [merchant_quantity, item_unique_id] = merchant_data;
|
|
||||||
|
|
||||||
inst_copy->SetMerchantCount(merchant_quantity);
|
|
||||||
inst_copy->SetMerchantSlot(slot_id);
|
|
||||||
inst_copy->SetPrice(new_price);
|
|
||||||
customer->SendItemPacket(slot_id, inst_copy.get(), ItemPacketMerchant);
|
|
||||||
|
|
||||||
customer->Message(
|
|
||||||
Chat::Red,
|
|
||||||
fmt::format("Trader {} updated the price of item {}", GetCleanName(), inst_copy->GetItem()->Name).c_str()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::SendBazaarDone(uint32 trader_id)
|
void Client::SendBazaarDone(uint32 trader_id)
|
||||||
@ -2705,16 +2752,53 @@ std::string Client::DetermineMoneyString(uint64 cp)
|
|||||||
return fmt::format("{}", money);
|
return fmt::format("{}", money);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::BuyTraderItemOutsideBazaar(TraderBuy_Struct *tbs, const EQApplicationPacket *app)
|
void Client::BuyTraderItemFromBazaarWindow(const EQApplicationPacket *app)
|
||||||
{
|
{
|
||||||
auto in = (TraderBuy_Struct *) app->pBuffer;
|
auto in = reinterpret_cast<TraderBuy_Struct *>(app->pBuffer);
|
||||||
auto sn = std::string(tbs->item_unique_id);
|
auto item_unique_id = std::string(in->item_unique_id);
|
||||||
auto trader_item = TraderRepository::GetItemBySerialNumber(database, sn, tbs->trader_id);
|
auto trader_item = TraderRepository::GetItemByItemUniqueNumber(database, item_unique_id);
|
||||||
|
|
||||||
|
LogTradingDetail(
|
||||||
|
"Packet details: \n"
|
||||||
|
"Action :{}\n"
|
||||||
|
"Method :{}\n"
|
||||||
|
"SubAction :{}\n"
|
||||||
|
"Unknown_012 :{}\n"
|
||||||
|
"Trader ID :{}\n"
|
||||||
|
"Buyer Name :{}\n"
|
||||||
|
"Seller Name :{}\n"
|
||||||
|
"Unknown_148 :{}\n"
|
||||||
|
"Item Name :{}\n"
|
||||||
|
"Item Unique ID :{}\n"
|
||||||
|
"Unknown_261 :{}\n"
|
||||||
|
"Item ID :{}\n"
|
||||||
|
"Price :{}\n"
|
||||||
|
"Already Sold :{}\n"
|
||||||
|
"Unknown_276 :{}\n"
|
||||||
|
"Quantity :{}\n",
|
||||||
|
in->action,
|
||||||
|
in->method,
|
||||||
|
in->sub_action,
|
||||||
|
in->unknown_012,
|
||||||
|
in->trader_id,
|
||||||
|
in->buyer_name,
|
||||||
|
in->seller_name,
|
||||||
|
in->unknown_148,
|
||||||
|
in->item_name,
|
||||||
|
in->item_unique_id,
|
||||||
|
in->unknown_261,
|
||||||
|
in->item_id,
|
||||||
|
in->price,
|
||||||
|
in->already_sold,
|
||||||
|
in->unknown_276,
|
||||||
|
in->quantity
|
||||||
|
);
|
||||||
|
|
||||||
if (!trader_item.id || GetTraderTransactionDate() < trader_item.listing_date) {
|
if (!trader_item.id || GetTraderTransactionDate() < trader_item.listing_date) {
|
||||||
LogTrading("Attempt to purchase an item outside of the Bazaar trader_id <red>[{}] item serial_number "
|
LogTrading("Attempt to purchase an item outside of the Bazaar trader_id [{}] item unique_id "
|
||||||
"<red>[{}] The Traders data was outdated.",
|
"[{}] The Traders data was outdated.",
|
||||||
tbs->trader_id,
|
in->trader_id,
|
||||||
tbs->item_unique_id
|
in->item_unique_id
|
||||||
);
|
);
|
||||||
in->method = BazaarByParcel;
|
in->method = BazaarByParcel;
|
||||||
in->sub_action = DataOutDated;
|
in->sub_action = DataOutDated;
|
||||||
@ -2723,10 +2807,10 @@ void Client::BuyTraderItemOutsideBazaar(TraderBuy_Struct *tbs, const EQApplicati
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (trader_item.active_transaction) {
|
if (trader_item.active_transaction) {
|
||||||
LogTrading("Attempt to purchase an item outside of the Bazaar trader_id <red>[{}] item serial_number "
|
LogTrading("Attempt to purchase an item outside of the Bazaar trader_id [{}] item serial_number "
|
||||||
"<red>[{}] The item is already within an active transaction.",
|
"[{}] The item is already within an active transaction.",
|
||||||
tbs->trader_id,
|
in->trader_id,
|
||||||
tbs->item_unique_id
|
in->item_unique_id
|
||||||
);
|
);
|
||||||
in->method = BazaarByParcel;
|
in->method = BazaarByParcel;
|
||||||
in->sub_action = DataOutDated;
|
in->sub_action = DataOutDated;
|
||||||
@ -2736,38 +2820,13 @@ void Client::BuyTraderItemOutsideBazaar(TraderBuy_Struct *tbs, const EQApplicati
|
|||||||
|
|
||||||
TraderRepository::UpdateActiveTransaction(database, trader_item.id, true);
|
TraderRepository::UpdateActiveTransaction(database, trader_item.id, true);
|
||||||
|
|
||||||
std::unique_ptr<EQ::ItemInstance> buy_item(
|
|
||||||
database.CreateItem(
|
|
||||||
trader_item.item_id,
|
|
||||||
trader_item.item_charges,
|
|
||||||
trader_item.augment_one,
|
|
||||||
trader_item.augment_two,
|
|
||||||
trader_item.augment_three,
|
|
||||||
trader_item.augment_four,
|
|
||||||
trader_item.augment_five,
|
|
||||||
trader_item.augment_six
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!buy_item) {
|
|
||||||
LogTrading("Unable to find item id <red>[{}] item_sn <red>[{}] on trader",
|
|
||||||
trader_item.item_id,
|
|
||||||
trader_item.item_unique_id
|
|
||||||
);
|
|
||||||
in->method = BazaarByParcel;
|
|
||||||
in->sub_action = Failed;
|
|
||||||
TraderRepository::UpdateActiveTransaction(database, trader_item.id, false);
|
|
||||||
TradeRequestFailed(app);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto next_slot = FindNextFreeParcelSlot(CharacterID());
|
auto next_slot = FindNextFreeParcelSlot(CharacterID());
|
||||||
if (next_slot == INVALID_INDEX) {
|
if (next_slot == INVALID_INDEX) {
|
||||||
LogTrading(
|
LogTrading(
|
||||||
"{} attempted to purchase {} from the bazaar with parcel delivery. Unfortunately their parcel limit was reached. "
|
"{} attempted to purchase {} from the bazaar with parcel delivery. Unfortunately their parcel limit was reached. "
|
||||||
"Purchase unsuccessful.",
|
"Purchase unsuccessful.",
|
||||||
GetCleanName(),
|
GetCleanName(),
|
||||||
buy_item->GetItem()->Name
|
in->item_name
|
||||||
);
|
);
|
||||||
in->method = BazaarByParcel;
|
in->method = BazaarByParcel;
|
||||||
in->sub_action = TooManyParcels;
|
in->sub_action = TooManyParcels;
|
||||||
@ -2777,36 +2836,18 @@ void Client::BuyTraderItemOutsideBazaar(TraderBuy_Struct *tbs, const EQApplicati
|
|||||||
}
|
}
|
||||||
|
|
||||||
LogTrading(
|
LogTrading(
|
||||||
"Name: <green>[{}] IsStackable: <green>[{}] Requested Quantity: <green>[{}] Charges on Item <green>[{}]",
|
"Name: [{}] Requested Quantity: [{}] Charges on Item [{}]",
|
||||||
buy_item->GetItem()->Name,
|
in->item_name,
|
||||||
buy_item->IsStackable(),
|
in->quantity,
|
||||||
tbs->quantity,
|
trader_item.item_charges
|
||||||
buy_item->GetCharges()
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// Determine the actual quantity for the purchase
|
uint64 total_cost = static_cast<uint64>(in->price) * static_cast<uint64>(in->quantity);
|
||||||
int32 charges = static_cast<int32>(tbs->quantity);
|
if (total_cost > RoF2::constants::MAX_BAZAAR_TRANSACTION) {
|
||||||
if (!buy_item->IsStackable()) {
|
|
||||||
if (buy_item->GetCharges() <= 0) {
|
|
||||||
charges = 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
charges = buy_item->GetCharges();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LogTrading(
|
|
||||||
"Actual quantity that will be traded is <green>[{}] {}",
|
|
||||||
tbs->quantity,
|
|
||||||
buy_item->GetCharges() ? fmt::format("with {} charges", buy_item->GetCharges()) : ""
|
|
||||||
);
|
|
||||||
|
|
||||||
uint64 total_cost = static_cast<uint64>(tbs->price) * static_cast<uint64>(tbs->quantity);
|
|
||||||
if (total_cost > MAX_TRANSACTION_VALUE) {
|
|
||||||
Message(
|
Message(
|
||||||
Chat::Red,
|
Chat::Red,
|
||||||
"That would exceed the single transaction limit of %u platinum.",
|
"That would exceed the single transaction limit of %u platinum.",
|
||||||
MAX_TRANSACTION_VALUE / 1000
|
RoF2::constants::MAX_BAZAAR_TRANSACTION / 1000
|
||||||
);
|
);
|
||||||
TraderRepository::UpdateActiveTransaction(database, trader_item.id, false);
|
TraderRepository::UpdateActiveTransaction(database, trader_item.id, false);
|
||||||
TradeRequestFailed(app);
|
TradeRequestFailed(app);
|
||||||
@ -2815,16 +2856,6 @@ void Client::BuyTraderItemOutsideBazaar(TraderBuy_Struct *tbs, const EQApplicati
|
|||||||
|
|
||||||
uint64 fee = std::round(total_cost * RuleR(Bazaar, ParcelDeliveryCostMod));
|
uint64 fee = std::round(total_cost * RuleR(Bazaar, ParcelDeliveryCostMod));
|
||||||
if (!TakeMoneyFromPP(total_cost + fee, false)) {
|
if (!TakeMoneyFromPP(total_cost + fee, false)) {
|
||||||
RecordPlayerEventLog(
|
|
||||||
PlayerEvent::POSSIBLE_HACK,
|
|
||||||
PlayerEvent::PossibleHackEvent{
|
|
||||||
.message = fmt::format(
|
|
||||||
"{} attempted to buy {} in bazaar but did not have enough money.",
|
|
||||||
GetCleanName(),
|
|
||||||
buy_item->GetItem()->Name
|
|
||||||
)
|
|
||||||
}
|
|
||||||
);
|
|
||||||
in->method = BazaarByParcel;
|
in->method = BazaarByParcel;
|
||||||
in->sub_action = InsufficientFunds;
|
in->sub_action = InsufficientFunds;
|
||||||
TraderRepository::UpdateActiveTransaction(database, trader_item.id, false);
|
TraderRepository::UpdateActiveTransaction(database, trader_item.id, false);
|
||||||
@ -2837,19 +2868,19 @@ void Client::BuyTraderItemOutsideBazaar(TraderBuy_Struct *tbs, const EQApplicati
|
|||||||
|
|
||||||
if (buy_item && PlayerEventLogs::Instance()->IsEventEnabled(PlayerEvent::TRADER_PURCHASE)) {
|
if (buy_item && PlayerEventLogs::Instance()->IsEventEnabled(PlayerEvent::TRADER_PURCHASE)) {
|
||||||
auto e = PlayerEvent::TraderPurchaseEvent{
|
auto e = PlayerEvent::TraderPurchaseEvent{
|
||||||
.item_id = buy_item->GetID(),
|
.item_id = trader_item.item_id,
|
||||||
.augment_1_id = buy_item->GetAugmentItemID(0),
|
.augment_1_id = trader_item.augment_one,
|
||||||
.augment_2_id = buy_item->GetAugmentItemID(1),
|
.augment_2_id = trader_item.augment_two,
|
||||||
.augment_3_id = buy_item->GetAugmentItemID(2),
|
.augment_3_id = trader_item.augment_three,
|
||||||
.augment_4_id = buy_item->GetAugmentItemID(3),
|
.augment_4_id = trader_item.augment_four,
|
||||||
.augment_5_id = buy_item->GetAugmentItemID(4),
|
.augment_5_id = trader_item.augment_five,
|
||||||
.augment_6_id = buy_item->GetAugmentItemID(5),
|
.augment_6_id = trader_item.augment_six,
|
||||||
.item_name = buy_item->GetItem()->Name,
|
.item_name = in->item_name,
|
||||||
.trader_id = tbs->trader_id,
|
.trader_id = in->trader_id,
|
||||||
.trader_name = tbs->seller_name,
|
.trader_name = in->seller_name,
|
||||||
.price = tbs->price,
|
.price = in->price,
|
||||||
.quantity = tbs->quantity,
|
.quantity = in->quantity,
|
||||||
.charges = buy_item->IsStackable() ? 1 : charges,
|
.charges = trader_item.item_charges,
|
||||||
.total_cost = total_cost,
|
.total_cost = total_cost,
|
||||||
.player_money_balance = GetCarriedMoney(),
|
.player_money_balance = GetCarriedMoney(),
|
||||||
};
|
};
|
||||||
@ -2858,17 +2889,17 @@ void Client::BuyTraderItemOutsideBazaar(TraderBuy_Struct *tbs, const EQApplicati
|
|||||||
}
|
}
|
||||||
|
|
||||||
CharacterParcelsRepository::CharacterParcels parcel_out{};
|
CharacterParcelsRepository::CharacterParcels parcel_out{};
|
||||||
parcel_out.from_name = tbs->seller_name;
|
parcel_out.from_name = in->seller_name;
|
||||||
parcel_out.note = "Delivered from a Bazaar Purchase";
|
parcel_out.note = "Delivered from a Bazaar Purchase";
|
||||||
parcel_out.sent_date = time(nullptr);
|
parcel_out.sent_date = time(nullptr);
|
||||||
parcel_out.quantity = charges;
|
parcel_out.quantity = in->quantity;
|
||||||
parcel_out.item_id = buy_item->GetItem()->ID;
|
parcel_out.item_id = trader_item.item_id;
|
||||||
parcel_out.aug_slot_1 = buy_item->GetAugmentItemID(0);
|
parcel_out.aug_slot_1 = trader_item.augment_one;
|
||||||
parcel_out.aug_slot_2 = buy_item->GetAugmentItemID(1);
|
parcel_out.aug_slot_2 = trader_item.augment_two;
|
||||||
parcel_out.aug_slot_3 = buy_item->GetAugmentItemID(2);
|
parcel_out.aug_slot_3 = trader_item.augment_three;
|
||||||
parcel_out.aug_slot_4 = buy_item->GetAugmentItemID(3);
|
parcel_out.aug_slot_4 = trader_item.augment_four;
|
||||||
parcel_out.aug_slot_5 = buy_item->GetAugmentItemID(4);
|
parcel_out.aug_slot_5 = trader_item.augment_five;
|
||||||
parcel_out.aug_slot_6 = buy_item->GetAugmentItemID(5);
|
parcel_out.aug_slot_6 = trader_item.augment_six;
|
||||||
parcel_out.char_id = CharacterID();
|
parcel_out.char_id = CharacterID();
|
||||||
parcel_out.slot_id = next_slot;
|
parcel_out.slot_id = next_slot;
|
||||||
parcel_out.id = 0;
|
parcel_out.id = 0;
|
||||||
@ -2889,7 +2920,7 @@ void Client::BuyTraderItemOutsideBazaar(TraderBuy_Struct *tbs, const EQApplicati
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnTraderReq(app, tbs->quantity, buy_item->GetID());
|
ReturnTraderReq(app, in->quantity, trader_item.item_id);
|
||||||
if (PlayerEventLogs::Instance()->IsEventEnabled(PlayerEvent::PARCEL_SEND)) {
|
if (PlayerEventLogs::Instance()->IsEventEnabled(PlayerEvent::PARCEL_SEND)) {
|
||||||
PlayerEvent::ParcelSend e{};
|
PlayerEvent::ParcelSend e{};
|
||||||
e.from_player_name = parcel_out.from_name;
|
e.from_player_name = parcel_out.from_name;
|
||||||
@ -2901,8 +2932,8 @@ void Client::BuyTraderItemOutsideBazaar(TraderBuy_Struct *tbs, const EQApplicati
|
|||||||
e.augment_4_id = parcel_out.aug_slot_4;
|
e.augment_4_id = parcel_out.aug_slot_4;
|
||||||
e.augment_5_id = parcel_out.aug_slot_5;
|
e.augment_5_id = parcel_out.aug_slot_5;
|
||||||
e.augment_6_id = parcel_out.aug_slot_6;
|
e.augment_6_id = parcel_out.aug_slot_6;
|
||||||
e.quantity = tbs->quantity;
|
e.quantity = in->quantity;
|
||||||
e.charges = buy_item->IsStackable() ? 1 : charges;
|
e.charges = trader_item.item_charges;
|
||||||
e.sent_date = parcel_out.sent_date;
|
e.sent_date = parcel_out.sent_date;
|
||||||
|
|
||||||
RecordPlayerEventLog(PlayerEvent::PARCEL_SEND, e);
|
RecordPlayerEventLog(PlayerEvent::PARCEL_SEND, e);
|
||||||
@ -2912,32 +2943,41 @@ void Client::BuyTraderItemOutsideBazaar(TraderBuy_Struct *tbs, const EQApplicati
|
|||||||
ps.item_slot = parcel_out.slot_id;
|
ps.item_slot = parcel_out.slot_id;
|
||||||
strn0cpy(ps.send_to, GetCleanName(), sizeof(ps.send_to));
|
strn0cpy(ps.send_to, GetCleanName(), sizeof(ps.send_to));
|
||||||
|
|
||||||
if (trader_item.item_charges <= static_cast<int32>(tbs->quantity) || !buy_item->IsStackable()) {
|
if (trader_item.item_charges <= static_cast<int32>(in->quantity) || !trader_item.item_charges <= 0) {
|
||||||
TraderRepository::DeleteOne(database, trader_item.id);
|
TraderRepository::DeleteOne(database, trader_item.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
SendParcelDeliveryToWorld(ps);
|
SendParcelDeliveryToWorld(ps);
|
||||||
|
|
||||||
if (RuleB(Bazaar, AuditTrail)) {
|
auto out_server = std::make_unique<ServerPacket>(ServerOP_BazaarPurchase, static_cast<uint32>(sizeof(BazaarPurchaseMessaging_Struct)));
|
||||||
BazaarAuditTrail(tbs->seller_name, GetName(), buy_item->GetItem()->Name, tbs->quantity, tbs->price, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto out_server = std::make_unique<ServerPacket>(
|
|
||||||
ServerOP_BazaarPurchase, static_cast<uint32>(sizeof(BazaarPurchaseMessaging_Struct))
|
|
||||||
);
|
|
||||||
auto out_data = (BazaarPurchaseMessaging_Struct *) out_server->pBuffer;
|
auto out_data = (BazaarPurchaseMessaging_Struct *) out_server->pBuffer;
|
||||||
|
|
||||||
out_data->trader_buy_struct = *tbs;
|
out_data->trader_buy_struct.action = in->action;
|
||||||
out_data->buyer_id = CharacterID();
|
out_data->trader_buy_struct.method = in->method;
|
||||||
out_data->item_aug_1 = buy_item->GetAugmentItemID(0);
|
out_data->trader_buy_struct.already_sold = in->already_sold;
|
||||||
out_data->item_aug_2 = buy_item->GetAugmentItemID(1);
|
out_data->trader_buy_struct.item_id = in->item_id;
|
||||||
out_data->item_aug_3 = buy_item->GetAugmentItemID(2);
|
out_data->trader_buy_struct.price = in->price;
|
||||||
out_data->item_aug_4 = buy_item->GetAugmentItemID(3);
|
out_data->trader_buy_struct.quantity = in->quantity;
|
||||||
out_data->item_aug_5 = buy_item->GetAugmentItemID(4);
|
out_data->trader_buy_struct.sub_action = in->sub_action;
|
||||||
out_data->item_aug_6 = buy_item->GetAugmentItemID(5);
|
out_data->trader_buy_struct.trader_id = in->trader_id;
|
||||||
out_data->item_quantity_available = trader_item.item_charges;
|
out_data->buyer_id = CharacterID();
|
||||||
out_data->id = trader_item.id;
|
out_data->item_aug_1 = trader_item.augment_one;
|
||||||
|
out_data->item_aug_2 = trader_item.augment_two;
|
||||||
|
out_data->item_aug_3 = trader_item.augment_three;
|
||||||
|
out_data->item_aug_4 = trader_item.augment_four;
|
||||||
|
out_data->item_aug_5 = trader_item.augment_five;
|
||||||
|
out_data->item_aug_6 = trader_item.augment_six;
|
||||||
|
out_data->item_quantity_available = trader_item.item_charges;
|
||||||
|
out_data->id = trader_item.id;
|
||||||
strn0cpy(out_data->trader_buy_struct.buyer_name, GetCleanName(), sizeof(out_data->trader_buy_struct.buyer_name));
|
strn0cpy(out_data->trader_buy_struct.buyer_name, GetCleanName(), sizeof(out_data->trader_buy_struct.buyer_name));
|
||||||
|
strn0cpy(out_data->trader_buy_struct.buyer_name, in->buyer_name, sizeof(out_data->trader_buy_struct.buyer_name));
|
||||||
|
strn0cpy(out_data->trader_buy_struct.item_name, in->item_name, sizeof(out_data->trader_buy_struct.item_name));
|
||||||
|
strn0cpy(out_data->trader_buy_struct.seller_name, in->seller_name, sizeof(out_data->trader_buy_struct.seller_name));
|
||||||
|
strn0cpy(
|
||||||
|
out_data->trader_buy_struct.item_unique_id,
|
||||||
|
in->item_unique_id,
|
||||||
|
sizeof(out_data->trader_buy_struct.item_unique_id)
|
||||||
|
);
|
||||||
|
|
||||||
worldserver.SendPacket(out_server.get());
|
worldserver.SendPacket(out_server.get());
|
||||||
|
|
||||||
@ -3699,16 +3739,33 @@ void Client::CancelTraderTradeWindow()
|
|||||||
FastQueuePacket(&end_session);
|
FastQueuePacket(&end_session);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::AddDataToMerchantList(int16 slot_id, int32 quantity, const std::string &item_unique_id)
|
void Client::AddDataToMerchantList(int16 slot_id, uint32 item_id, int32 quantity, const std::string &item_unique_id)
|
||||||
{
|
{
|
||||||
auto list = GetTraderMerchantList();
|
auto list = GetTraderMerchantList();
|
||||||
list->emplace(std::pair(slot_id, std::make_tuple(quantity, item_unique_id)));
|
list->emplace(std::pair(slot_id, std::make_tuple(item_id, quantity, item_unique_id)));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<int16, std::string> Client::GetDataFromMerchantListByMerchantSlotId(int16 slot_id)
|
int16 Client::GetNextFreeSlotFromMerchantList()
|
||||||
{
|
{
|
||||||
auto list = GetTraderMerchantList();
|
auto list = GetTraderMerchantList();
|
||||||
return list->contains(slot_id) ? list->at(slot_id) : std::make_tuple(INVALID_INDEX, "0000000000000000");
|
for (auto const &[slot_id, merchant_data] : *list) {
|
||||||
|
auto [item_id, quantity, item_unique_id] = merchant_data;
|
||||||
|
if (item_id == 0) {
|
||||||
|
return slot_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (list->size() == GetInv().GetLookup()->InventoryTypeSize.Bazaar) {
|
||||||
|
return INVALID_INDEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
return list->size() + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::tuple<uint32, int32, std::string> Client::GetDataFromMerchantListByMerchantSlotId(int16 slot_id)
|
||||||
|
{
|
||||||
|
auto list = GetTraderMerchantList();
|
||||||
|
return list->contains(slot_id) ? list->at(slot_id) : std::make_tuple(0, 0, "0000000000000000");
|
||||||
}
|
}
|
||||||
|
|
||||||
int16 Client::GetSlotFromMerchantListByItemUniqueId(const std::string &unique_id)
|
int16 Client::GetSlotFromMerchantListByItemUniqueId(const std::string &unique_id)
|
||||||
@ -3716,7 +3773,7 @@ int16 Client::GetSlotFromMerchantListByItemUniqueId(const std::string &unique_id
|
|||||||
auto list = GetTraderMerchantList();
|
auto list = GetTraderMerchantList();
|
||||||
|
|
||||||
for (auto [slot_id, merchant_data] : *list) {
|
for (auto [slot_id, merchant_data] : *list) {
|
||||||
auto [quantity, item_unique_id] = merchant_data;
|
auto [item_id, quantity, item_unique_id] = merchant_data;
|
||||||
if (item_unique_id == unique_id) {
|
if (item_unique_id == unique_id) {
|
||||||
return slot_id;
|
return slot_id;
|
||||||
}
|
}
|
||||||
@ -3725,16 +3782,16 @@ int16 Client::GetSlotFromMerchantListByItemUniqueId(const std::string &unique_id
|
|||||||
return INVALID_INDEX;
|
return INVALID_INDEX;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<int16, std::tuple<uint32, std::string>> Client::GetDataFromMerchantListByItemUniqueId(const std::string &unique_id)
|
std::pair<int16, std::tuple<uint32, int32, std::string>> Client::GetDataFromMerchantListByItemUniqueId(const std::string &unique_id)
|
||||||
{
|
{
|
||||||
auto list = GetTraderMerchantList();
|
auto list = GetTraderMerchantList();
|
||||||
|
|
||||||
for (auto [slot_id, merchant_data] : *list) {
|
for (auto [slot_id, merchant_data] : *list) {
|
||||||
auto [quantity, item_unique_id] = merchant_data;
|
auto [item_id, quantity, item_unique_id] = merchant_data;
|
||||||
if (item_unique_id == unique_id) {
|
if (item_unique_id == unique_id) {
|
||||||
return { slot_id, merchant_data };
|
return { slot_id, merchant_data };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::make_pair(INVALID_INDEX, std::make_tuple(0, "0000000000000000"));
|
return std::make_pair(INVALID_INDEX, std::make_tuple(0, 0, "0000000000000000"));
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user