mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-11 16:51:29 +00:00
[Feature] Add Alternate Bazaar Search Approach (#4600)
* Add Alternate Bazaar Search This adds an alternate bazaar search allowing multinstance bazaar searching and traders above 600. Allows searches based on Bazaar Shard * Update worldserver.cpp --------- Co-authored-by: Mitch Freeman <neckkola@gmail.com> Co-authored-by: Akkadius <akkadius1@gmail.com>
This commit is contained in:
parent
f21cc170df
commit
37a7b7fc41
@ -31,6 +31,7 @@ Bazaar::GetSearchResults(
|
||||
char_zone_instance_id
|
||||
);
|
||||
|
||||
bool convert = false;
|
||||
std::string search_criteria_trader("TRUE ");
|
||||
|
||||
if (search.search_scope == NonRoFBazaarSearchScope) {
|
||||
@ -51,8 +52,24 @@ Bazaar::GetSearchResults(
|
||||
);
|
||||
}
|
||||
else if (search.trader_id > 0) {
|
||||
search_criteria_trader.append(fmt::format(" AND trader.char_id = {}", search.trader_id));
|
||||
if (RuleB(Bazaar, UseAlternateBazaarSearch)) {
|
||||
if (search.trader_id >= TraderRepository::TRADER_CONVERT_ID) {
|
||||
convert = true;
|
||||
search_criteria_trader.append(fmt::format(
|
||||
" AND trader.char_zone_id = {} AND trader.char_zone_instance_id = {}",
|
||||
Zones::BAZAAR,
|
||||
search.trader_id - TraderRepository::TRADER_CONVERT_ID)
|
||||
);
|
||||
}
|
||||
else {
|
||||
search_criteria_trader.append(fmt::format(" AND trader.char_id = {}", search.trader_id));
|
||||
}
|
||||
}
|
||||
else {
|
||||
search_criteria_trader.append(fmt::format(" AND trader.char_id = {}", search.trader_id));
|
||||
}
|
||||
}
|
||||
|
||||
if (search.min_cost != 0) {
|
||||
search_criteria_trader.append(fmt::format(" AND trader.item_cost >= {}", search.min_cost * 1000));
|
||||
}
|
||||
@ -355,6 +372,12 @@ Bazaar::GetSearchResults(
|
||||
}
|
||||
|
||||
LogTradingDetail("Found item [{}] meeting search criteria.", r.item_name);
|
||||
if (RuleB(Bazaar, UseAlternateBazaarSearch)) {
|
||||
if (convert || (r.trader_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);
|
||||
}
|
||||
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
|
||||
class TraderRepository : public BaseTraderRepository {
|
||||
public:
|
||||
static constexpr uint32 TRADER_CONVERT_ID = 4000000000;
|
||||
|
||||
struct DistinctTraders_Struct {
|
||||
uint32 trader_id;
|
||||
@ -40,7 +41,11 @@ public:
|
||||
int32 char_zone_instance_id
|
||||
);
|
||||
|
||||
static BulkTraders_Struct GetDistinctTraders(Database &db, uint32 char_zone_instance_id, uint32 max_results)
|
||||
static BulkTraders_Struct GetDistinctTraders(
|
||||
Database &db,
|
||||
uint32 char_zone_instance_id,
|
||||
uint32 max_results = std::numeric_limits<uint32>::max()
|
||||
)
|
||||
{
|
||||
BulkTraders_Struct all_entries{};
|
||||
std::vector<DistinctTraders_Struct> distinct_traders;
|
||||
@ -49,7 +54,9 @@ public:
|
||||
"SELECT DISTINCT(t.char_id), t.char_zone_id, t.char_zone_instance_id, t.char_entity_id, c.name "
|
||||
"FROM trader AS t "
|
||||
"JOIN character_data AS c ON t.char_id = c.id "
|
||||
"ORDER BY t.char_zone_instance_id = {} DESC LIMIT {};",
|
||||
"WHERE t.char_zone_instance_id = {} "
|
||||
"ORDER BY t.char_zone_instance_id ASC "
|
||||
"LIMIT {}",
|
||||
char_zone_instance_id,
|
||||
max_results)
|
||||
);
|
||||
@ -227,6 +234,37 @@ public:
|
||||
|
||||
return DeleteWhere(db, fmt::format("`id` IN({})", Strings::Implode(",", delete_ids)));
|
||||
}
|
||||
|
||||
static DistinctTraders_Struct GetTraderByInstanceAndSerialnumber(
|
||||
Database &db,
|
||||
uint32 instance_id,
|
||||
const char *serial_number
|
||||
)
|
||||
{
|
||||
DistinctTraders_Struct trader{};
|
||||
|
||||
auto query = fmt::format(
|
||||
"SELECT t.id, t.char_id, c.name "
|
||||
"FROM trader AS t "
|
||||
"JOIN character_data AS c ON c.id = t.char_id "
|
||||
"WHERE t.char_zone_id = 151 AND t.char_zone_instance_id = {} AND t.item_sn = {} LIMIT 1",
|
||||
instance_id,
|
||||
serial_number
|
||||
);
|
||||
|
||||
auto results = db.QueryDatabase(query);
|
||||
|
||||
if (results.RowCount() == 0) {
|
||||
return trader;
|
||||
}
|
||||
|
||||
auto row = results.begin();
|
||||
std::string name = row[2];
|
||||
trader.trader_id = Strings::ToUnsignedInt(row[1]);
|
||||
trader.trader_name = row[2] ? row[2] : "";
|
||||
|
||||
return trader;
|
||||
}
|
||||
};
|
||||
|
||||
#endif //EQEMU_TRADER_REPOSITORY_H
|
||||
|
||||
@ -830,6 +830,7 @@ RULE_REAL(Bazaar, ParcelDeliveryCostMod, 0.20, "Cost of parcel delivery for a ba
|
||||
RULE_INT(Bazaar, VoucherDeliveryCost, 200, "Number of vouchers for direct delivery for a bazaar purchase. Default is 200 vouchers. RoF+ Only.")
|
||||
RULE_BOOL(Bazaar, EnableParcelDelivery, true, "Enable bazaar purchases via parcel delivery. Default is True.")
|
||||
RULE_INT(Bazaar, MaxBuyerInventorySearchResults, 200, "Maximum number of search results when a Buyer searches the global item list. Default is 200. RoF+ Only.")
|
||||
RULE_BOOL(Bazaar, UseAlternateBazaarSearch, false, "Allows the bazaar search window to search across bazaar shards. Default is false.")
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(Mail)
|
||||
|
||||
@ -295,7 +295,7 @@ public:
|
||||
void SendBazaarDone(uint32 trader_id);
|
||||
void SendBulkBazaarTraders();
|
||||
void SendBulkBazaarBuyers();
|
||||
void DoBazaarInspect(const BazaarInspect_Struct &in);
|
||||
void DoBazaarInspect(BazaarInspect_Struct &in);
|
||||
void SendBazaarDeliveryCosts();
|
||||
static std::string DetermineMoneyString(uint64 copper);
|
||||
|
||||
|
||||
@ -15535,6 +15535,26 @@ void Client::Handle_OP_TraderBuy(const EQApplicationPacket *app)
|
||||
// Client has elected to buy an item from a Trader
|
||||
//
|
||||
auto in = (TraderBuy_Struct *) app->pBuffer;
|
||||
|
||||
if (RuleB(Bazaar, UseAlternateBazaarSearch) && in->trader_id >= TraderRepository::TRADER_CONVERT_ID) {
|
||||
auto trader = TraderRepository::GetTraderByInstanceAndSerialnumber(
|
||||
database,
|
||||
in->trader_id - TraderRepository::TRADER_CONVERT_ID,
|
||||
in->serial_number
|
||||
);
|
||||
|
||||
if (!trader.trader_id) {
|
||||
LogTrading("Unable to convert trader id for {} and serial number {}. Trader Buy aborted.",
|
||||
in->trader_id - TraderRepository::TRADER_CONVERT_ID,
|
||||
in->serial_number
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
in->trader_id = trader.trader_id;
|
||||
strn0cpy(in->seller_name, trader.trader_name.c_str(), sizeof(in->seller_name));
|
||||
}
|
||||
|
||||
auto trader = entity_list.GetClientByID(in->trader_id);
|
||||
|
||||
switch (in->method) {
|
||||
|
||||
@ -3222,11 +3222,42 @@ void Client::SendBulkBazaarTraders()
|
||||
return;
|
||||
}
|
||||
|
||||
auto results = TraderRepository::GetDistinctTraders(
|
||||
database,
|
||||
GetInstanceID(),
|
||||
EQ::constants::StaticLookup(ClientVersion())->BazaarTraderLimit
|
||||
);
|
||||
TraderRepository::BulkTraders_Struct results{};
|
||||
|
||||
if (RuleB(Bazaar, UseAlternateBazaarSearch))
|
||||
{
|
||||
if (GetZoneID() == Zones::BAZAAR) {
|
||||
results = TraderRepository::GetDistinctTraders(database, GetInstanceID());
|
||||
}
|
||||
|
||||
uint32 number = 1;
|
||||
auto shards = CharacterDataRepository::GetInstanceZonePlayerCounts(database, Zones::BAZAAR);
|
||||
for (auto const &shard: shards) {
|
||||
if (GetZoneID() != Zones::BAZAAR || (GetZoneID() == Zones::BAZAAR && GetInstanceID() != shard.instance_id)) {
|
||||
|
||||
TraderRepository::DistinctTraders_Struct t{};
|
||||
t.entity_id = 0;
|
||||
t.trader_id = TraderRepository::TRADER_CONVERT_ID + shard.instance_id;
|
||||
t.trader_name = fmt::format("Bazaar Shard {}", number);
|
||||
t.zone_id = Zones::BAZAAR;
|
||||
t.zone_instance_id = shard.instance_id;
|
||||
results.count += 1;
|
||||
results.name_length += t.trader_name.length() + 1;
|
||||
results.traders.push_back(t);
|
||||
}
|
||||
|
||||
number++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
results = TraderRepository::GetDistinctTraders(
|
||||
database,
|
||||
GetInstanceID(),
|
||||
EQ::constants::StaticLookup(ClientVersion())->BazaarTraderLimit
|
||||
);
|
||||
}
|
||||
|
||||
SetTraderCount(results.count);
|
||||
|
||||
SetTraderCount(results.count);
|
||||
|
||||
@ -3251,8 +3282,28 @@ void Client::SendBulkBazaarTraders()
|
||||
QueuePacket(outapp.get());
|
||||
}
|
||||
|
||||
void Client::DoBazaarInspect(const BazaarInspect_Struct &in)
|
||||
void Client::DoBazaarInspect(BazaarInspect_Struct &in)
|
||||
{
|
||||
if (RuleB(Bazaar, UseAlternateBazaarSearch)) {
|
||||
if (in.trader_id >= TraderRepository::TRADER_CONVERT_ID) {
|
||||
auto trader = TraderRepository::GetTraderByInstanceAndSerialnumber(
|
||||
database,
|
||||
in.trader_id - TraderRepository::TRADER_CONVERT_ID,
|
||||
fmt::format("{}", in.serial_number).c_str()
|
||||
);
|
||||
|
||||
if (!trader.trader_id) {
|
||||
LogTrading("Unable to convert trader id for {} and serial number {}. Trader Buy aborted.",
|
||||
in.trader_id - TraderRepository::TRADER_CONVERT_ID,
|
||||
in.serial_number
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
in.trader_id = trader.trader_id;
|
||||
}
|
||||
}
|
||||
|
||||
auto items = TraderRepository::GetWhere(
|
||||
database, fmt::format("`char_id` = '{}' AND `item_sn` = '{}'", in.trader_id, in.serial_number)
|
||||
);
|
||||
|
||||
@ -3926,16 +3926,36 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
|
||||
out->action = AddTraderToBazaarWindow;
|
||||
if (c.second->GetTraderCount() <
|
||||
EQ::constants::StaticLookup(c.second->ClientVersion())->BazaarTraderLimit) {
|
||||
if (RuleB(Bazaar, UseAlternateBazaarSearch)) {
|
||||
if (out->zone_id == Zones::BAZAAR &&
|
||||
out->zone_instance_id == c.second->GetInstanceID()) {
|
||||
c.second->IncrementTraderCount();
|
||||
c.second->QueuePacket(outapp, true, Mob::CLIENT_CONNECTED);
|
||||
}
|
||||
}
|
||||
else {
|
||||
c.second->IncrementTraderCount();
|
||||
c.second->QueuePacket(outapp, true, Mob::CLIENT_CONNECTED);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case TraderOff: {
|
||||
out->action = RemoveTraderFromBazaarWindow;
|
||||
c.second->DecrementTraderCount();
|
||||
c.second->QueuePacket(outapp, true, Mob::CLIENT_CONNECTED);
|
||||
if (c.second->GetTraderCount() <=
|
||||
EQ::constants::StaticLookup(c.second->ClientVersion())->BazaarTraderLimit) {
|
||||
if (RuleB(Bazaar, UseAlternateBazaarSearch)) {
|
||||
if (out->zone_id == Zones::BAZAAR &&
|
||||
out->zone_instance_id == c.second->GetInstanceID()) {
|
||||
c.second->DecrementTraderCount();
|
||||
c.second->QueuePacket(outapp, true, Mob::CLIENT_CONNECTED);
|
||||
}
|
||||
}
|
||||
else {
|
||||
c.second->DecrementTraderCount();
|
||||
c.second->QueuePacket(outapp, true, Mob::CLIENT_CONNECTED);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user