mirror of
https://github.com/EQEmu/Server.git
synced 2026-01-06 01:03:52 +00:00
wip
This commit is contained in:
parent
125457afe6
commit
93c38f5e24
@ -48,6 +48,7 @@ static const EQ::constants::LookupEntry constants_static_lookup_entries[EQ::vers
|
||||
ClientUnknown::constants::EXPANSIONS_MASK,
|
||||
ClientUnknown::INULL,
|
||||
ClientUnknown::INULL,
|
||||
ClientUnknown::INULL,
|
||||
ClientUnknown::INULL
|
||||
),
|
||||
/*[ClientVersion::Client62] =*/
|
||||
@ -57,6 +58,7 @@ static const EQ::constants::LookupEntry constants_static_lookup_entries[EQ::vers
|
||||
Client62::constants::EXPANSIONS_MASK,
|
||||
Client62::INULL,
|
||||
Client62::INULL,
|
||||
Client62::INULL,
|
||||
Client62::INULL
|
||||
),
|
||||
/*[ClientVersion::Titanium] =*/
|
||||
@ -66,6 +68,7 @@ static const EQ::constants::LookupEntry constants_static_lookup_entries[EQ::vers
|
||||
Titanium::constants::EXPANSIONS_MASK,
|
||||
Titanium::constants::CHARACTER_CREATION_LIMIT,
|
||||
Titanium::constants::SAY_LINK_BODY_SIZE,
|
||||
Titanium::INULL,
|
||||
Titanium::INULL
|
||||
),
|
||||
/*[ClientVersion::SoF] =*/
|
||||
@ -75,6 +78,7 @@ static const EQ::constants::LookupEntry constants_static_lookup_entries[EQ::vers
|
||||
SoF::constants::EXPANSIONS_MASK,
|
||||
SoF::constants::CHARACTER_CREATION_LIMIT,
|
||||
SoF::constants::SAY_LINK_BODY_SIZE,
|
||||
SoF::INULL,
|
||||
SoF::INULL
|
||||
),
|
||||
/*[ClientVersion::SoD] =*/
|
||||
@ -84,6 +88,7 @@ static const EQ::constants::LookupEntry constants_static_lookup_entries[EQ::vers
|
||||
SoD::constants::EXPANSIONS_MASK,
|
||||
SoD::constants::CHARACTER_CREATION_LIMIT,
|
||||
SoD::constants::SAY_LINK_BODY_SIZE,
|
||||
SoD::INULL,
|
||||
SoD::INULL
|
||||
),
|
||||
/*[ClientVersion::UF] =*/
|
||||
@ -93,6 +98,7 @@ static const EQ::constants::LookupEntry constants_static_lookup_entries[EQ::vers
|
||||
UF::constants::EXPANSIONS_MASK,
|
||||
UF::constants::CHARACTER_CREATION_LIMIT,
|
||||
UF::constants::SAY_LINK_BODY_SIZE,
|
||||
UF::INULL,
|
||||
UF::INULL
|
||||
),
|
||||
/*[ClientVersion::RoF] =*/
|
||||
@ -102,6 +108,7 @@ static const EQ::constants::LookupEntry constants_static_lookup_entries[EQ::vers
|
||||
RoF::constants::EXPANSIONS_MASK,
|
||||
RoF::constants::CHARACTER_CREATION_LIMIT,
|
||||
RoF::constants::SAY_LINK_BODY_SIZE,
|
||||
RoF::INULL,
|
||||
RoF::INULL
|
||||
),
|
||||
/*[ClientVersion::RoF2] =*/
|
||||
@ -111,7 +118,8 @@ static const EQ::constants::LookupEntry constants_static_lookup_entries[EQ::vers
|
||||
RoF2::constants::EXPANSIONS_MASK,
|
||||
RoF2::constants::CHARACTER_CREATION_LIMIT,
|
||||
RoF2::constants::SAY_LINK_BODY_SIZE,
|
||||
RoF2::constants::MAX_BAZAAR_TRADERS
|
||||
RoF2::constants::MAX_BAZAAR_TRADERS,
|
||||
RoF2::constants::MAX_BAZAAR_TRANSACTION
|
||||
)
|
||||
};
|
||||
|
||||
|
||||
@ -43,6 +43,7 @@ namespace EQ
|
||||
int16 CharacterCreationLimit;
|
||||
size_t SayLinkBodySize;
|
||||
uint32 BazaarTraderLimit;
|
||||
uint32 BazaarMaxTransaction;
|
||||
|
||||
LookupEntry(const LookupEntry *lookup_entry) { }
|
||||
LookupEntry(
|
||||
@ -51,14 +52,16 @@ namespace EQ
|
||||
uint32 ExpansionsMask,
|
||||
int16 CharacterCreationLimit,
|
||||
size_t SayLinkBodySize,
|
||||
uint32 BazaarTraderLimit
|
||||
uint32 BazaarTraderLimit,
|
||||
uint32 BazaarMaxTransaction
|
||||
) :
|
||||
Expansion(Expansion),
|
||||
ExpansionBit(ExpansionBit),
|
||||
ExpansionsMask(ExpansionsMask),
|
||||
CharacterCreationLimit(CharacterCreationLimit),
|
||||
SayLinkBodySize(SayLinkBodySize),
|
||||
BazaarTraderLimit(BazaarTraderLimit)
|
||||
BazaarTraderLimit(BazaarTraderLimit),
|
||||
BazaarMaxTransaction(BazaarMaxTransaction)
|
||||
{ }
|
||||
};
|
||||
|
||||
|
||||
@ -369,12 +369,13 @@ enum {
|
||||
};
|
||||
|
||||
enum {
|
||||
BazaarPurchaseFailed = 0,
|
||||
BazaarPurchaseSuccess = 1,
|
||||
BazaarPurchaseSellerFailed = 2,
|
||||
BazaarPurchaseSellerSuccess = 3,
|
||||
BazaarPurchaseBuyerFailed = 4,
|
||||
BazaarPurchaseBuyerSuccess = 5
|
||||
BazaarPurchaseFailed = 0,
|
||||
BazaarPurchaseSuccess = 1,
|
||||
BazaarPurchaseBuyerCompleteSendToSeller = 2,
|
||||
BazaarPurchaseSellerCompleteSendToBuyer = 3,
|
||||
BazaarPurchaseBuyerFailed = 4,
|
||||
BazaarPurchaseBuyerSuccess = 5,
|
||||
BazaarPurchaseTraderFailed = 6
|
||||
};
|
||||
/************ PACKET RELATED STRUCT ************/
|
||||
class ServerPacket
|
||||
@ -1783,10 +1784,13 @@ struct BazaarPurchaseMessaging_Struct {
|
||||
uint32 item_aug_5;
|
||||
uint32 item_aug_6;
|
||||
uint32 buyer_id;
|
||||
uint32 item_charges;
|
||||
uint32 item_quantity;
|
||||
int16 item_charges;
|
||||
uint32 id;
|
||||
uint32 trader_zone_id;
|
||||
uint32 trader_zone_instance_id;
|
||||
uint32 buyer_zone_id;
|
||||
uint32 buyer_zone_instance_id;
|
||||
uint32 transaction_status;
|
||||
};
|
||||
|
||||
|
||||
@ -1674,21 +1674,23 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) {
|
||||
break;
|
||||
}
|
||||
case ServerOP_BazaarPurchase: {
|
||||
auto in = (BazaarPurchaseMessaging_Struct *)pack->pBuffer;
|
||||
if (in->trader_buy_struct.trader_id <= 0) {
|
||||
LogTrading(
|
||||
"World Message [{}] received with invalid trader_id [{}]",
|
||||
"ServerOP_BazaarPurchase",
|
||||
in->trader_buy_struct.trader_id
|
||||
);
|
||||
return;
|
||||
auto in = reinterpret_cast<BazaarPurchaseMessaging_Struct *>(pack->pBuffer);
|
||||
switch (in->transaction_status) {
|
||||
case BazaarPurchaseBuyerCompleteSendToSeller: {
|
||||
zoneserver_list.SendPacket(in->trader_zone_id, in->trader_zone_instance_id, pack);
|
||||
break;
|
||||
}
|
||||
case BazaarPurchaseTraderFailed:
|
||||
case BazaarPurchaseSuccess: {
|
||||
zoneserver_list.SendPacket(in->buyer_zone_id, in->buyer_zone_instance_id, pack);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
LogError(
|
||||
"ServerOP_BazaarPurchase received with no corresponding action for [{}]",
|
||||
in->transaction_status);
|
||||
}
|
||||
}
|
||||
|
||||
auto trader = ClientList::Instance()->FindCLEByCharacterID(in->trader_buy_struct.trader_id);
|
||||
if (trader) {
|
||||
ZSList::Instance()->SendPacket(in->trader_zone_id, in->trader_zone_instance_id, pack);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case ServerOP_BuyerMessaging: {
|
||||
|
||||
129
zone/trading.cpp
129
zone/trading.cpp
@ -1462,11 +1462,11 @@ void Client::BuyTraderItem(const EQApplicationPacket *app)
|
||||
}
|
||||
|
||||
uint64 total_transaction_value = static_cast<uint64>(in->price) * static_cast<uint64>(quantity);
|
||||
if (total_transaction_value > RoF2::constants::MAX_BAZAAR_TRANSACTION) {
|
||||
if (total_transaction_value > EQ::constants::StaticLookup(ClientVersion())->BazaarMaxTransaction) {
|
||||
Message(
|
||||
Chat::Red,
|
||||
"That would exceed the single transaction limit of %u platinum.",
|
||||
RoF2::constants::MAX_BAZAAR_TRANSACTION / 1000
|
||||
EQ::constants::StaticLookup(ClientVersion())->BazaarMaxTransaction / 1000
|
||||
);
|
||||
TradeRequestFailed(app);
|
||||
return;
|
||||
@ -2853,9 +2853,9 @@ void Client::BuyTraderItemFromBazaarWindow(const EQApplicationPacket *app)
|
||||
TraderRepository::UpdateActiveTransaction(database, trader_item.id, true);
|
||||
|
||||
uint32 quantity = in->quantity;
|
||||
int16 charges = 1;
|
||||
auto item = database.GetItem(trader_item.item_id);
|
||||
auto item = database.GetItem(trader_item.item_id);
|
||||
|
||||
int16 charges = 1;
|
||||
if (trader_item.item_charges > 0 || item->Stackable || item->MaxCharges > 0) {
|
||||
charges = trader_item.item_charges;
|
||||
}
|
||||
@ -2870,12 +2870,12 @@ void Client::BuyTraderItemFromBazaarWindow(const EQApplicationPacket *app)
|
||||
in->item_unique_id
|
||||
);
|
||||
|
||||
uint64 total_cost = static_cast<uint64>(in->price) * static_cast<uint64>(in->quantity);
|
||||
if (total_cost > RoF2::constants::MAX_BAZAAR_TRANSACTION) {
|
||||
uint64 total_cost = static_cast<uint64>(in->price) * static_cast<uint64>(quantity);
|
||||
if (total_cost > EQ::constants::StaticLookup(ClientVersion())->BazaarMaxTransaction) {
|
||||
Message(
|
||||
Chat::Red,
|
||||
"That would exceed the single transaction limit of %u platinum.",
|
||||
RoF2::constants::MAX_BAZAAR_TRANSACTION / 1000
|
||||
EQ::constants::StaticLookup(ClientVersion())->BazaarMaxTransaction / 1000
|
||||
);
|
||||
TraderRepository::UpdateActiveTransaction(database, trader_item.id, false);
|
||||
TradeRequestFailed(app);
|
||||
@ -2895,114 +2895,10 @@ void Client::BuyTraderItemFromBazaarWindow(const EQApplicationPacket *app)
|
||||
LogTrading("Customer [{}] Paid: [{}] to trader [{}]", CharacterID(), DetermineMoneyString(total_cost), trader_item.character_id);
|
||||
LogTradingDetail("Step 2:Bazaar Purchase. Took [{}] from Buyer [{}] ", DetermineMoneyString(total_cost), CharacterID());
|
||||
|
||||
if (buy_item && PlayerEventLogs::Instance()->IsEventEnabled(PlayerEvent::TRADER_PURCHASE)) {
|
||||
auto e = PlayerEvent::TraderPurchaseEvent{
|
||||
.item_id = trader_item.item_id,
|
||||
.augment_1_id = trader_item.augment_one,
|
||||
.augment_2_id = trader_item.augment_two,
|
||||
.augment_3_id = trader_item.augment_three,
|
||||
.augment_4_id = trader_item.augment_four,
|
||||
.augment_5_id = trader_item.augment_five,
|
||||
.augment_6_id = trader_item.augment_six,
|
||||
.item_name = in->item_name,
|
||||
.trader_id = in->trader_id,
|
||||
.trader_name = in->seller_name,
|
||||
.price = in->price,
|
||||
.quantity = in->quantity,
|
||||
.charges = trader_item.item_charges,
|
||||
.total_cost = total_cost,
|
||||
.player_money_balance = GetCarriedMoney(),
|
||||
};
|
||||
|
||||
RecordPlayerEventLog(PlayerEvent::TRADER_PURCHASE, e);
|
||||
}
|
||||
|
||||
CharacterParcelsRepository::CharacterParcels parcel_out{};
|
||||
parcel_out.from_name = in->seller_name;
|
||||
parcel_out.note = "Delivered from a Bazaar Purchase";
|
||||
parcel_out.sent_date = time(nullptr);
|
||||
parcel_out.quantity = charges;
|
||||
parcel_out.item_id = trader_item.item_id;
|
||||
parcel_out.aug_slot_1 = trader_item.augment_one;
|
||||
parcel_out.aug_slot_2 = trader_item.augment_two;
|
||||
parcel_out.aug_slot_3 = trader_item.augment_three;
|
||||
parcel_out.aug_slot_4 = trader_item.augment_four;
|
||||
parcel_out.aug_slot_5 = trader_item.augment_five;
|
||||
parcel_out.aug_slot_6 = trader_item.augment_six;
|
||||
parcel_out.char_id = CharacterID();
|
||||
parcel_out.slot_id = next_slot;
|
||||
parcel_out.id = 0;
|
||||
|
||||
auto result = CharacterParcelsRepository::InsertOne(database, parcel_out);
|
||||
if (!result.id) {
|
||||
LogError("Failed to add parcel to database. From {} to {} item {} quantity {}",
|
||||
parcel_out.from_name,
|
||||
GetCleanName(),
|
||||
parcel_out.item_id,
|
||||
parcel_out.quantity
|
||||
);
|
||||
Message(Chat::Yellow, "Unable to save parcel to the database. Please contact an administrator.");
|
||||
in->method = BazaarByParcel;
|
||||
in->sub_action = Failed;
|
||||
TraderRepository::UpdateActiveTransaction(database, trader_item.id, false);
|
||||
AddMoneyToPP(total_cost + fee);
|
||||
TradeRequestFailed(app);
|
||||
return;
|
||||
}
|
||||
|
||||
ReturnTraderReq(app, in->quantity, trader_item.item_id);
|
||||
if (PlayerEventLogs::Instance()->IsEventEnabled(PlayerEvent::PARCEL_SEND)) {
|
||||
PlayerEvent::ParcelSend e{};
|
||||
e.from_player_name = parcel_out.from_name;
|
||||
e.to_player_name = GetCleanName();
|
||||
e.item_id = parcel_out.item_id;
|
||||
e.augment_1_id = parcel_out.aug_slot_1;
|
||||
e.augment_2_id = parcel_out.aug_slot_2;
|
||||
e.augment_3_id = parcel_out.aug_slot_3;
|
||||
e.augment_4_id = parcel_out.aug_slot_4;
|
||||
e.augment_5_id = parcel_out.aug_slot_5;
|
||||
e.augment_6_id = parcel_out.aug_slot_6;
|
||||
e.quantity = in->quantity;
|
||||
e.charges = trader_item.item_charges;
|
||||
e.sent_date = parcel_out.sent_date;
|
||||
|
||||
RecordPlayerEventLog(PlayerEvent::PARCEL_SEND, e);
|
||||
}
|
||||
|
||||
Parcel_Struct ps{};
|
||||
ps.item_slot = parcel_out.slot_id;
|
||||
strn0cpy(ps.send_to, GetCleanName(), sizeof(ps.send_to));
|
||||
SendParcelDeliveryToWorld(ps);
|
||||
|
||||
LogTradingDetail("Step 3:Bazaar Purchase. Sent parcel to Buyer [{}] Item ID [{}] Quantity [{}] Charges [{}]",
|
||||
CharacterID(),
|
||||
trader_item.item_id,
|
||||
quantity,
|
||||
charges
|
||||
);
|
||||
|
||||
if (item->Stackable && quantity != charges) {
|
||||
TraderRepository::UpdateQuantity(database, in->item_unique_id, trader_item.item_charges - quantity);
|
||||
LogTradingDetail(
|
||||
"Step 4a:Bazaar Purchase. Decreased database id {} from [{}] to [{}] charges",
|
||||
trader_item.item_id,
|
||||
trader_item.item_charges,
|
||||
charges
|
||||
);
|
||||
}
|
||||
else {
|
||||
TraderRepository::DeleteOne(database, trader_item.id);
|
||||
LogTradingDetail(
|
||||
"Step 4b:Bazaar Purchase. Deleted database id [{}] because database quantity [{}] equals [{}] purchased quantity",
|
||||
trader_item.id,
|
||||
trader_item.item_charges,
|
||||
charges
|
||||
);
|
||||
}
|
||||
|
||||
auto out_server = std::make_unique<ServerPacket>(ServerOP_BazaarPurchase, sizeof(BazaarPurchaseMessaging_Struct));
|
||||
auto out_data = (BazaarPurchaseMessaging_Struct *) out_server->pBuffer;
|
||||
auto out_data = reinterpret_cast<BazaarPurchaseMessaging_Struct *>(out_server->pBuffer);
|
||||
|
||||
out_data->transaction_status = BazaarPurchaseBuyerCompleteSendToSeller;
|
||||
out_data->trader_buy_struct.action = in->action;
|
||||
out_data->trader_buy_struct.method = in->method;
|
||||
out_data->trader_buy_struct.already_sold = in->already_sold;
|
||||
@ -3010,7 +2906,7 @@ void Client::BuyTraderItemFromBazaarWindow(const EQApplicationPacket *app)
|
||||
out_data->trader_buy_struct.price = in->price;
|
||||
out_data->trader_buy_struct.quantity = in->quantity;
|
||||
out_data->trader_buy_struct.sub_action = in->sub_action;
|
||||
out_data->trader_buy_struct.trader_id = in->trader_id;
|
||||
out_data->trader_buy_struct.trader_id = trader_item.character_id;
|
||||
out_data->buyer_id = CharacterID();
|
||||
out_data->item_aug_1 = trader_item.augment_one;
|
||||
out_data->item_aug_2 = trader_item.augment_two;
|
||||
@ -3018,10 +2914,13 @@ void Client::BuyTraderItemFromBazaarWindow(const EQApplicationPacket *app)
|
||||
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_charges = trader_item.item_charges;
|
||||
out_data->item_quantity = quantity;
|
||||
out_data->item_charges = charges;
|
||||
out_data->id = trader_item.id;
|
||||
out_data->trader_zone_id = trader_item.char_zone_id;
|
||||
out_data->trader_zone_instance_id = trader_item.char_zone_instance_id;
|
||||
out_data->buyer_zone_id = GetZoneID();
|
||||
out_data->buyer_zone_instance_id = GetInstanceID();
|
||||
strn0cpy(out_data->trader_buy_struct.buyer_name, GetCleanName(), sizeof(out_data->trader_buy_struct.buyer_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_name, in->item_name, sizeof(out_data->trader_buy_struct.item_name));
|
||||
|
||||
@ -3774,62 +3774,226 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
|
||||
break;
|
||||
}
|
||||
case ServerOP_BazaarPurchase: {
|
||||
auto in = (BazaarPurchaseMessaging_Struct *) pack->pBuffer;
|
||||
auto trader_pc = entity_list.GetClientByCharID(in->trader_buy_struct.trader_id);
|
||||
if (!trader_pc) {
|
||||
LogTrading("Request trader_id <red>[{}] could not be found in zone_id <red>[{}]",
|
||||
in->trader_buy_struct.trader_id,
|
||||
zone->GetZoneID()
|
||||
);
|
||||
return;
|
||||
}
|
||||
auto in = reinterpret_cast<BazaarPurchaseMessaging_Struct *>(pack->pBuffer);
|
||||
switch (in->transaction_status) {
|
||||
case BazaarPurchaseBuyerCompleteSendToSeller: {
|
||||
auto trader_pc = entity_list.GetClientByCharID(in->trader_buy_struct.trader_id);
|
||||
if (!trader_pc) {
|
||||
LogTrading(
|
||||
"Request trader_id <red>[{}] could not be found in zone_id <red>[{}]",
|
||||
in->trader_buy_struct.trader_id,
|
||||
zone->GetZoneID());
|
||||
return;
|
||||
}
|
||||
|
||||
if (trader_pc->IsThereACustomer()) {
|
||||
auto customer = entity_list.GetClientByID(trader_pc->GetCustomerID());
|
||||
if (customer) {
|
||||
customer->CancelTraderTradeWindow();
|
||||
auto item = trader_pc->FindTraderItemByUniqueID(in->trader_buy_struct.item_unique_id);
|
||||
if (!item) {
|
||||
in->transaction_status = BazaarPurchaseTraderFailed;
|
||||
TraderRepository::UpdateActiveTransaction(database, in->id, false);
|
||||
worldserver.SendPacket(pack);
|
||||
break;
|
||||
}
|
||||
|
||||
//if there is a customer currently browsing, close to ensure no conflict of purchase
|
||||
if (trader_pc->IsThereACustomer()) {
|
||||
auto customer = entity_list.GetClientByID(trader_pc->GetCustomerID());
|
||||
if (customer) {
|
||||
customer->CancelTraderTradeWindow();
|
||||
}
|
||||
}
|
||||
|
||||
//Update the trader's db entries
|
||||
if (item->IsStackable() && in->item_quantity != in->item_charges) {
|
||||
TraderRepository::UpdateQuantity(database, in->trader_buy_struct.item_unique_id, item->GetCharges() - in->item_quantity);
|
||||
LogTradingDetail(
|
||||
"Step 4a:Bazaar Purchase. Decreased database id {} from [{}] to [{}] charges",
|
||||
in->trader_buy_struct.item_id,
|
||||
in->item_charges,
|
||||
in->item_charges
|
||||
);
|
||||
}
|
||||
else {
|
||||
TraderRepository::DeleteOne(database, in->trader_buy_struct.item_id);
|
||||
LogTradingDetail(
|
||||
"Step 4b:Bazaar Purchase. Deleted database id [{}] because database quantity [{}] equals [{}] purchased quantity",
|
||||
in->trader_buy_struct.item_id,
|
||||
in->item_charges,
|
||||
in->item_charges
|
||||
);
|
||||
}
|
||||
|
||||
//at this time, buyer checks ok, seller checks ok.
|
||||
//perform actions to trader
|
||||
uint64 total_cost = static_cast<uint64>(in->trader_buy_struct.price) * static_cast<uint64>(in->item_quantity);
|
||||
if (!trader_pc->RemoveItemByItemUniqueId(in->trader_buy_struct.item_unique_id, in->item_quantity)) {
|
||||
in->transaction_status = BazaarPurchaseTraderFailed;
|
||||
TraderRepository::UpdateActiveTransaction(database, in->id, false);
|
||||
worldserver.SendPacket(pack);
|
||||
break;
|
||||
}
|
||||
|
||||
trader_pc->AddMoneyToPP(total_cost, true);
|
||||
|
||||
//Update the trader to indicate the sale has completed
|
||||
EQApplicationPacket outapp(OP_Trader, sizeof(TraderBuy_Struct));
|
||||
auto data = reinterpret_cast<TraderBuy_Struct *>(outapp.pBuffer);
|
||||
|
||||
memcpy(data, &in->trader_buy_struct, sizeof(TraderBuy_Struct));
|
||||
trader_pc->QueuePacket(&outapp);
|
||||
|
||||
if (item && PlayerEventLogs::Instance()->IsEventEnabled(PlayerEvent::TRADER_SELL)) {
|
||||
auto e = PlayerEvent::TraderSellEvent{
|
||||
.item_id = item->GetID(),
|
||||
.augment_1_id = item->GetAugmentItemID(0),
|
||||
.augment_2_id = item->GetAugmentItemID(1),
|
||||
.augment_3_id = item->GetAugmentItemID(2),
|
||||
.augment_4_id = item->GetAugmentItemID(3),
|
||||
.augment_5_id = item->GetAugmentItemID(4),
|
||||
.augment_6_id = item->GetAugmentItemID(5),
|
||||
.item_name = in->trader_buy_struct.item_name,
|
||||
.buyer_id = in->buyer_id,
|
||||
.buyer_name = in->trader_buy_struct.buyer_name,
|
||||
.price = in->trader_buy_struct.price,
|
||||
.quantity = in->item_quantity,
|
||||
.charges = in->item_charges,
|
||||
.total_cost = total_cost,
|
||||
.player_money_balance = trader_pc->GetCarriedMoney(),
|
||||
};
|
||||
RecordPlayerEventLogWithClient(trader_pc, PlayerEvent::TRADER_SELL, e);
|
||||
}
|
||||
|
||||
in->transaction_status = BazaarPurchaseSuccess;
|
||||
TraderRepository::UpdateActiveTransaction(database, in->id, false);
|
||||
worldserver.SendPacket(pack);
|
||||
|
||||
break;
|
||||
}
|
||||
case BazaarPurchaseTraderFailed: {
|
||||
auto buyer = entity_list.GetClientByCharID(in->buyer_id);
|
||||
if (!buyer) {
|
||||
LogTrading(
|
||||
"Requested buyer_id [{}] could not be found in zone_id [{}] instance_id [{}]",
|
||||
in->trader_buy_struct.trader_id,
|
||||
zone->GetZoneID(),
|
||||
zone->GetInstanceID()
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// return buyer's money including the fee
|
||||
uint64 total_cost =
|
||||
static_cast<uint64>(in->trader_buy_struct.price) * static_cast<uint64>(in->item_quantity);
|
||||
uint64 fee = std::round(total_cost * RuleR(Bazaar, ParcelDeliveryCostMod));
|
||||
buyer->AddMoneyToPP(total_cost + fee, false);
|
||||
buyer->SendMoneyUpdate();
|
||||
|
||||
break;
|
||||
}
|
||||
case BazaarPurchaseSuccess: {
|
||||
auto buyer = entity_list.GetClientByCharID(in->buyer_id);
|
||||
if (!buyer) {
|
||||
LogTrading(
|
||||
"Requested buyer_id [{}] could not be found in zone_id [{}] instance_id [{}]",
|
||||
in->trader_buy_struct.trader_id,
|
||||
zone->GetZoneID(),
|
||||
zone->GetInstanceID()
|
||||
);
|
||||
return;
|
||||
}
|
||||
uint64 total_cost =
|
||||
static_cast<uint64>(in->trader_buy_struct.price) * static_cast<uint64>(in->item_quantity);
|
||||
|
||||
if (player_event_logs.IsEventEnabled(PlayerEvent::TRADER_PURCHASE)) {
|
||||
auto e = PlayerEvent::TraderPurchaseEvent{
|
||||
.item_id = in->trader_buy_struct.item_id,
|
||||
.augment_1_id = in->item_aug_1,
|
||||
.augment_2_id = in->item_aug_2,
|
||||
.augment_3_id = in->item_aug_3,
|
||||
.augment_4_id = in->item_aug_4,
|
||||
.augment_5_id = in->item_aug_5,
|
||||
.augment_6_id = in->item_aug_6,
|
||||
.item_name = in->trader_buy_struct.item_name,
|
||||
.trader_id = in->trader_buy_struct.trader_id,
|
||||
.trader_name = in->trader_buy_struct.seller_name,
|
||||
.price = in->trader_buy_struct.price,
|
||||
.quantity = in->item_quantity,
|
||||
.charges = in->item_charges,
|
||||
.total_cost = total_cost,
|
||||
.player_money_balance = buyer->GetCarriedMoney(),
|
||||
};
|
||||
|
||||
RecordPlayerEventLogWithClient(buyer, PlayerEvent::TRADER_PURCHASE, e);
|
||||
}
|
||||
|
||||
auto item = database.GetItem(in->trader_buy_struct.item_id);
|
||||
auto quantity = in->item_quantity;
|
||||
if (item->MaxCharges > 0) {
|
||||
quantity = in->item_charges;
|
||||
}
|
||||
|
||||
//Send the item via parcel
|
||||
CharacterParcelsRepository::CharacterParcels parcel_out{};
|
||||
parcel_out.from_name = in->trader_buy_struct.seller_name;
|
||||
parcel_out.note = "Delivered from a Bazaar Purchase";
|
||||
parcel_out.sent_date = time(nullptr);
|
||||
parcel_out.quantity = quantity;
|
||||
parcel_out.item_id = in->trader_buy_struct.item_id;
|
||||
parcel_out.aug_slot_1 = in->item_aug_1;
|
||||
parcel_out.aug_slot_2 = in->item_aug_2;
|
||||
parcel_out.aug_slot_3 = in->item_aug_3;
|
||||
parcel_out.aug_slot_4 = in->item_aug_4;
|
||||
parcel_out.aug_slot_5 = in->item_aug_5;
|
||||
parcel_out.aug_slot_6 = in->item_aug_6;
|
||||
parcel_out.char_id = buyer->CharacterID();
|
||||
parcel_out.slot_id = buyer->FindNextFreeParcelSlot(buyer->CharacterID());
|
||||
parcel_out.id = 0;
|
||||
|
||||
CharacterParcelsRepository::InsertOne(database, parcel_out);
|
||||
|
||||
if (player_event_logs.IsEventEnabled(PlayerEvent::PARCEL_SEND)) {
|
||||
PlayerEvent::ParcelSend e{};
|
||||
e.from_player_name = parcel_out.from_name;
|
||||
e.to_player_name = buyer->GetCleanName();
|
||||
e.item_id = parcel_out.item_id;
|
||||
e.augment_1_id = parcel_out.aug_slot_1;
|
||||
e.augment_2_id = parcel_out.aug_slot_2;
|
||||
e.augment_3_id = parcel_out.aug_slot_3;
|
||||
e.augment_4_id = parcel_out.aug_slot_4;
|
||||
e.augment_5_id = parcel_out.aug_slot_5;
|
||||
e.augment_6_id = parcel_out.aug_slot_6;
|
||||
e.quantity = in->item_quantity;
|
||||
e.charges = in->item_charges;
|
||||
e.sent_date = parcel_out.sent_date;
|
||||
|
||||
RecordPlayerEventLogWithClient(buyer, PlayerEvent::PARCEL_SEND, e);
|
||||
}
|
||||
|
||||
Parcel_Struct ps{};
|
||||
ps.item_slot = parcel_out.slot_id;
|
||||
strn0cpy(ps.send_to, buyer->GetCleanName(), sizeof(ps.send_to));
|
||||
buyer->SendParcelDeliveryToWorld(ps);
|
||||
|
||||
LogTradingDetail(
|
||||
"Step 3:Bazaar Purchase. Sent parcel to Buyer [{}] Item ID [{}] Quantity [{}] Charges [{}]",
|
||||
buyer->CharacterID(),
|
||||
in->trader_buy_struct.item_id,
|
||||
in->item_quantity,
|
||||
in->item_charges
|
||||
);
|
||||
|
||||
//Update the buyer to indicate the sale has completed
|
||||
EQApplicationPacket outapp(OP_Trader, sizeof(TraderBuy_Struct));
|
||||
auto data = reinterpret_cast<TraderBuy_Struct *>(outapp.pBuffer);
|
||||
|
||||
memcpy(data, &in->trader_buy_struct, sizeof(TraderBuy_Struct));
|
||||
buyer->ReturnTraderReq(&outapp, in->item_quantity, in->trader_buy_struct.item_id);
|
||||
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
}
|
||||
}
|
||||
|
||||
auto sn = std::string(in->trader_buy_struct.item_unique_id);
|
||||
auto outapp = std::make_unique<EQApplicationPacket>(OP_Trader, static_cast<uint32>(sizeof(TraderBuy_Struct)));
|
||||
auto data = (TraderBuy_Struct *) outapp->pBuffer;
|
||||
|
||||
memcpy(data, &in->trader_buy_struct, sizeof(TraderBuy_Struct));
|
||||
|
||||
if (trader_pc->ClientVersion() < EQ::versions::ClientVersion::RoF) {
|
||||
data->price = in->trader_buy_struct.price * in->trader_buy_struct.quantity;
|
||||
}
|
||||
|
||||
TraderRepository::UpdateActiveTransaction(database, in->id, false);
|
||||
|
||||
auto item = trader_pc->FindTraderItemBySerialNumber(sn);
|
||||
|
||||
if (item && PlayerEventLogs::Instance()->IsEventEnabled(PlayerEvent::TRADER_SELL)) {
|
||||
auto e = PlayerEvent::TraderSellEvent{
|
||||
.item_id = item ? item->GetID() : 0,
|
||||
.augment_1_id = item->GetAugmentItemID(0),
|
||||
.augment_2_id = item->GetAugmentItemID(1),
|
||||
.augment_3_id = item->GetAugmentItemID(2),
|
||||
.augment_4_id = item->GetAugmentItemID(3),
|
||||
.augment_5_id = item->GetAugmentItemID(4),
|
||||
.augment_6_id = item->GetAugmentItemID(5),
|
||||
.item_name = in->trader_buy_struct.item_name,
|
||||
.buyer_id = in->buyer_id,
|
||||
.buyer_name = in->trader_buy_struct.buyer_name,
|
||||
.price = in->trader_buy_struct.price,
|
||||
.quantity = in->trader_buy_struct.quantity,
|
||||
.charges = item ? item->IsStackable() ? 1 : item->GetCharges() : 0,
|
||||
.total_cost = (in->trader_buy_struct.price * in->trader_buy_struct.quantity),
|
||||
.player_money_balance = trader_pc->GetCarriedMoney(),
|
||||
};
|
||||
RecordPlayerEventLogWithClient(trader_pc, PlayerEvent::TRADER_SELL, e);
|
||||
}
|
||||
|
||||
trader_pc->RemoveItemByItemUniqueId(sn, in->trader_buy_struct.quantity);
|
||||
trader_pc->AddMoneyToPP(in->trader_buy_struct.price * in->trader_buy_struct.quantity, true);
|
||||
trader_pc->QueuePacket(outapp.get());
|
||||
|
||||
break;
|
||||
}
|
||||
case ServerOP_BuyerMessaging: {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user