mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-16 18:52:22 +00:00
[Feature] Add RoF2 Bazaar Support (#4315)
* Add RoF2 Bazaar Support Enable RoF2 bazaar features * Add augments to Trader Items * Cleanup Cleanup of formatting and unused functions * Update PlayerProfile for correct char_id in trader transactions. Further cleanup. * Add parcel delivery price functionality Add parcel delivery price functionality via rules and new delivery cost struct. * Add RoF support for bazaar window outside of bazaar with parcel delivery * Further Testing and ActiveTransaction added Further testing and a few fixes and messages added. Add active transaction check to ensure two clients cannot purchase from the bazaar window at the same time * Cleanup and Formatting updates Cleanup and Formatting updates * Update database manifest for the trader table against default peq trader table * Logs and formatting * Update bazaarsearch to be content_db aware * Fix crash * Simplify search * Search fixes * Push up more search logging * More search fixes * Formatting * Update trader_repository.h * Add Rule for Bazaar Parcel Delivery Add a rule Bazaar:EnableParcelDelivery to enable/disable bazaar parcel delivery. Default is True. * Fix crash * Update Bazaar Search Adds/Tested bazaar search with move to content_db - race, class, money, number of returned items, stats, name, slot, level, traders, local traders, specific trader. Outstanding - type, more stats to add (heroic, etc) * Formatting * Push * Update bazaarsearch to include all stats that are available in RoF2 * Update BazaarSearch Updates the bazaar search for item types. They should be working as per RoF2+ types. * Formatting * Final updates to BazaarSearch Add search by augmentation slots available on the item. This enables all but Prestige, which I believe are not implemented yet. * Add Titanium functionality correct ItemType Search Add Titanium /trader /bazaar functionality. Added itemtype=armor bazaar search. It was missed in the search work * Close off for loops --------- Co-authored-by: Akkadius <akkadius1@gmail.com>
This commit is contained in:
+108
-165
@@ -51,6 +51,9 @@
|
||||
#include "../common/repositories/character_corpse_items_repository.h"
|
||||
#include "../common/repositories/zone_repository.h"
|
||||
|
||||
#include "../common/repositories/trader_repository.h"
|
||||
|
||||
|
||||
#include <ctime>
|
||||
#include <iostream>
|
||||
#include <fmt/format.h>
|
||||
@@ -302,187 +305,114 @@ void ZoneDatabase::DeleteWorldContainer(uint32 parent_id, uint32 zone_id)
|
||||
);
|
||||
}
|
||||
|
||||
Trader_Struct* ZoneDatabase::LoadTraderItem(uint32 char_id)
|
||||
std::unique_ptr<EQ::ItemInstance> ZoneDatabase::LoadSingleTraderItem(uint32 char_id, int serial_number)
|
||||
{
|
||||
auto loadti = new Trader_Struct;
|
||||
memset(loadti,0,sizeof(Trader_Struct));
|
||||
auto results = TraderRepository::GetWhere(
|
||||
database,
|
||||
fmt::format(
|
||||
"`char_id` = '{}' AND `item_sn` = '{}' ORDER BY slot_id",
|
||||
char_id,
|
||||
serial_number
|
||||
)
|
||||
);
|
||||
|
||||
std::string query = StringFormat("SELECT * FROM trader WHERE char_id = %i ORDER BY slot_id LIMIT 80", char_id);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogTrading("Failed to load trader information!\n");
|
||||
return loadti;
|
||||
if (results.empty()) {
|
||||
LogTrading("Could not find item serial number {} for character id {}", serial_number, char_id);
|
||||
}
|
||||
|
||||
loadti->Code = BazaarTrader_ShowItems;
|
||||
for (auto& row = results.begin(); row != results.end(); ++row) {
|
||||
if (Strings::ToInt(row[5]) >= 80 || Strings::ToInt(row[4]) < 0) {
|
||||
LogTrading("Bad Slot number when trying to load trader information!\n");
|
||||
continue;
|
||||
}
|
||||
int item_id = results.at(0).item_id;
|
||||
int charges = results.at(0).item_charges;
|
||||
int cost = results.at(0).item_cost;
|
||||
|
||||
loadti->Items[Strings::ToInt(row[5])] = Strings::ToInt(row[1]);
|
||||
loadti->ItemCost[Strings::ToInt(row[5])] = Strings::ToInt(row[4]);
|
||||
const EQ::ItemData *item = database.GetItem(item_id);
|
||||
if (!item) {
|
||||
LogTrading("Unable to create item.");
|
||||
return nullptr;
|
||||
}
|
||||
return loadti;
|
||||
|
||||
if (item->NoDrop == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<EQ::ItemInstance> inst(
|
||||
database.CreateItem(
|
||||
item_id,
|
||||
charges,
|
||||
results.at(0).aug_slot_1,
|
||||
results.at(0).aug_slot_2,
|
||||
results.at(0).aug_slot_3,
|
||||
results.at(0).aug_slot_4,
|
||||
results.at(0).aug_slot_5,
|
||||
results.at(0).aug_slot_6
|
||||
)
|
||||
);
|
||||
if (!inst) {
|
||||
LogTrading("Unable to create item instance.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
inst->SetCharges(charges);
|
||||
inst->SetSerialNumber(serial_number);
|
||||
inst->SetMerchantSlot(serial_number);
|
||||
inst->SetPrice(cost);
|
||||
|
||||
if (inst->IsStackable()) {
|
||||
inst->SetMerchantCount(charges);
|
||||
}
|
||||
|
||||
return std::move(inst);
|
||||
}
|
||||
|
||||
TraderCharges_Struct* ZoneDatabase::LoadTraderItemWithCharges(uint32 char_id)
|
||||
{
|
||||
auto loadti = new TraderCharges_Struct;
|
||||
memset(loadti,0,sizeof(TraderCharges_Struct));
|
||||
void ZoneDatabase::UpdateTraderItemPrice(int char_id, uint32 item_id, uint32 charges, uint32 new_price) {
|
||||
|
||||
std::string query = StringFormat("SELECT * FROM trader WHERE char_id=%i ORDER BY slot_id LIMIT 80", char_id);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogTrading("Failed to load trader information!\n");
|
||||
return loadti;
|
||||
}
|
||||
|
||||
for (auto& row = results.begin(); row != results.end(); ++row) {
|
||||
if (Strings::ToInt(row[5]) >= 80 || Strings::ToInt(row[5]) < 0) {
|
||||
LogTrading("Bad Slot number when trying to load trader information!\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
loadti->ItemID[Strings::ToInt(row[5])] = Strings::ToInt(row[1]);
|
||||
loadti->SerialNumber[Strings::ToInt(row[5])] = Strings::ToInt(row[2]);
|
||||
loadti->Charges[Strings::ToInt(row[5])] = Strings::ToInt(row[3]);
|
||||
loadti->ItemCost[Strings::ToInt(row[5])] = Strings::ToInt(row[4]);
|
||||
}
|
||||
return loadti;
|
||||
}
|
||||
|
||||
EQ::ItemInstance* ZoneDatabase::LoadSingleTraderItem(uint32 CharID, int SerialNumber) {
|
||||
std::string query = StringFormat("SELECT * FROM trader WHERE char_id = %i AND serialnumber = %i "
|
||||
"ORDER BY slot_id LIMIT 80", CharID, SerialNumber);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return nullptr;
|
||||
|
||||
if (results.RowCount() == 0) {
|
||||
LogTrading("Bad result from query\n"); fflush(stdout);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto& row = results.begin();
|
||||
|
||||
int ItemID = Strings::ToInt(row[1]);
|
||||
int Charges = Strings::ToInt(row[3]);
|
||||
int Cost = Strings::ToInt(row[4]);
|
||||
|
||||
const EQ::ItemData *item = database.GetItem(ItemID);
|
||||
LogTrading("ZoneDatabase::UpdateTraderPrice([{}], [{}], [{}], [{}])", char_id, item_id, charges, new_price);
|
||||
const EQ::ItemData *item = database.GetItem(item_id);
|
||||
|
||||
if(!item) {
|
||||
LogTrading("Unable to create item\n");
|
||||
fflush(stdout);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (item->NoDrop == 0)
|
||||
return nullptr;
|
||||
|
||||
EQ::ItemInstance* inst = database.CreateItem(item);
|
||||
if(!inst) {
|
||||
LogTrading("Unable to create item instance\n");
|
||||
fflush(stdout);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
inst->SetCharges(Charges);
|
||||
inst->SetSerialNumber(SerialNumber);
|
||||
inst->SetMerchantSlot(SerialNumber);
|
||||
inst->SetPrice(Cost);
|
||||
|
||||
if(inst->IsStackable())
|
||||
inst->SetMerchantCount(Charges);
|
||||
|
||||
return inst;
|
||||
}
|
||||
|
||||
void ZoneDatabase::SaveTraderItem(uint32 CharID, uint32 ItemID, uint32 SerialNumber, int32 Charges, uint32 ItemCost, uint8 Slot){
|
||||
|
||||
std::string query = StringFormat("REPLACE INTO trader VALUES(%i, %i, %i, %i, %i, %i)",
|
||||
CharID, ItemID, SerialNumber, Charges, ItemCost, Slot);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogDebug("[CLIENT] Failed to save trader item: [{}] for char_id: [{}], the error was: [{}]\n", ItemID, CharID, results.ErrorMessage().c_str());
|
||||
|
||||
}
|
||||
|
||||
void ZoneDatabase::UpdateTraderItemCharges(int CharID, uint32 SerialNumber, int32 Charges) {
|
||||
LogTrading("ZoneDatabase::UpdateTraderItemCharges([{}], [{}], [{}])", CharID, SerialNumber, Charges);
|
||||
|
||||
std::string query = StringFormat("UPDATE trader SET charges = %i WHERE char_id = %i AND serialnumber = %i",
|
||||
Charges, CharID, SerialNumber);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogDebug("[CLIENT] Failed to update charges for trader item: [{}] for char_id: [{}], the error was: [{}]\n", SerialNumber, CharID, results.ErrorMessage().c_str());
|
||||
|
||||
}
|
||||
|
||||
void ZoneDatabase::UpdateTraderItemPrice(int CharID, uint32 ItemID, uint32 Charges, uint32 NewPrice) {
|
||||
|
||||
LogTrading("ZoneDatabase::UpdateTraderPrice([{}], [{}], [{}], [{}])", CharID, ItemID, Charges, NewPrice);
|
||||
|
||||
const EQ::ItemData *item = database.GetItem(ItemID);
|
||||
|
||||
if(!item)
|
||||
return;
|
||||
}
|
||||
|
||||
if(NewPrice == 0) {
|
||||
LogTrading("Removing Trader items from the DB for CharID [{}], ItemID [{}]", CharID, ItemID);
|
||||
if (new_price == 0) {
|
||||
LogTrading("Removing Trader items from the DB for char_id [{}], item_id [{}]", char_id, item_id);
|
||||
|
||||
std::string query = StringFormat("DELETE FROM trader WHERE char_id = %i AND item_id = %i",CharID, ItemID);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogDebug("[CLIENT] Failed to remove trader item(s): [{}] for char_id: [{}], the error was: [{}]\n", ItemID, CharID, results.ErrorMessage().c_str());
|
||||
auto results = TraderRepository::DeleteWhere(
|
||||
database,
|
||||
fmt::format(
|
||||
"`char_id` = '{}' AND `item_id` = {}",
|
||||
char_id,
|
||||
item_id
|
||||
)
|
||||
);
|
||||
if (!results) {
|
||||
LogDebug("[CLIENT] Failed to remove trader item(s): [{}] for char_id: [{}]",
|
||||
item_id,
|
||||
char_id
|
||||
);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(!item->Stackable) {
|
||||
std::string query = StringFormat("UPDATE trader SET item_cost = %i "
|
||||
"WHERE char_id = %i AND item_id = %i AND charges=%i",
|
||||
NewPrice, CharID, ItemID, Charges);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogDebug("[CLIENT] Failed to update price for trader item: [{}] for char_id: [{}], the error was: [{}]\n", ItemID, CharID, results.ErrorMessage().c_str());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
std::string query = StringFormat("UPDATE trader SET item_cost = %i "
|
||||
"WHERE char_id = %i AND item_id = %i",
|
||||
NewPrice, CharID, ItemID);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogDebug("[CLIENT] Failed to update price for trader item: [{}] for char_id: [{}], the error was: [{}]\n", ItemID, CharID, results.ErrorMessage().c_str());
|
||||
}
|
||||
|
||||
void ZoneDatabase::DeleteTraderItem(uint32 char_id){
|
||||
|
||||
if(char_id==0) {
|
||||
const std::string query = "DELETE FROM trader";
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogDebug("[CLIENT] Failed to delete all trader items data, the error was: [{}]\n", results.ErrorMessage().c_str());
|
||||
|
||||
return;
|
||||
if (!item->Stackable) {
|
||||
auto results = TraderRepository::UpdateItem(database, char_id, new_price, item_id, charges);
|
||||
if (!results) {
|
||||
LogTrading(
|
||||
"Failed to update price for trader item [{}] for char_id: [{}]",
|
||||
item_id,
|
||||
char_id
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
std::string query = StringFormat("DELETE FROM trader WHERE char_id = %i", char_id);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogDebug("[CLIENT] Failed to delete trader item data for char_id: [{}], the error was: [{}]\n", char_id, results.ErrorMessage().c_str());
|
||||
|
||||
}
|
||||
void ZoneDatabase::DeleteTraderItem(uint32 CharID,uint16 SlotID) {
|
||||
|
||||
std::string query = StringFormat("DELETE FROM trader WHERE char_id = %i And slot_id = %i", CharID, SlotID);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogDebug("[CLIENT] Failed to delete trader item data for char_id: [{}], the error was: [{}]\n",CharID, results.ErrorMessage().c_str());
|
||||
auto results = TraderRepository::UpdateItem(database, char_id, new_price, item_id, 0);
|
||||
if (!results) {
|
||||
LogTrading(
|
||||
"Failed to update price for trader item [{}] for char_id: [{}]",
|
||||
item_id,
|
||||
char_id
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void ZoneDatabase::DeleteBuyLines(uint32 CharID) {
|
||||
@@ -526,10 +456,22 @@ void ZoneDatabase::UpdateBuyLine(uint32 CharID, uint32 BuySlot, uint32 Quantity)
|
||||
return;
|
||||
}
|
||||
|
||||
std::string query = StringFormat("UPDATE buyer SET quantity = %i WHERE charid = %i AND buyslot = %i", Quantity, CharID, BuySlot);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogDebug("[CLIENT] Failed to update quantity in buyslot [{}] for charid: [{}], the error was: [{}]\n", BuySlot, CharID, results.ErrorMessage().c_str());
|
||||
std::string query = StringFormat(
|
||||
"UPDATE buyer SET quantity = %i WHERE charid = %i AND buyslot = %i",
|
||||
Quantity,
|
||||
CharID,
|
||||
BuySlot
|
||||
);
|
||||
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogTrading(
|
||||
"Failed to update quantity in buyslot [{}] for charid [{}], the error was [{}]\n",
|
||||
BuySlot,
|
||||
CharID,
|
||||
results.ErrorMessage().c_str()
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -630,6 +572,7 @@ bool ZoneDatabase::LoadCharacterData(uint32 character_id, PlayerProfile_Struct*
|
||||
pp->raidAutoconsent = e.raid_auto_consent;
|
||||
pp->guildAutoconsent = e.guild_auto_consent;
|
||||
pp->RestTimer = e.RestTimer;
|
||||
pp->char_id = e.id;
|
||||
m_epp->aa_effects = e.e_aa_effects;
|
||||
m_epp->perAA = e.e_percent_to_aa;
|
||||
m_epp->expended_aa = e.e_expended_aa_spent;
|
||||
|
||||
Reference in New Issue
Block a user