[Bug Fix] Fix trader mode (#4397)

* Fix bazaar trading

* Update `constexpr`

* Added world trader table truncate on boot to ensure that the trader table is always empty when world starts.

---------

Co-authored-by: Mitch Freeman <65987027+neckkola@users.noreply.github.com>
This commit is contained in:
JJ 2024-06-16 20:55:14 -04:00 committed by GitHub
parent 7b914c731b
commit ac24c9bf5a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 19 additions and 10 deletions

View File

@ -77,6 +77,7 @@
#include "zone_store.h" #include "zone_store.h"
#include "repositories/merchantlist_temp_repository.h" #include "repositories/merchantlist_temp_repository.h"
#include "repositories/bot_data_repository.h" #include "repositories/bot_data_repository.h"
#include "repositories/trader_repository.h"
extern Client client; extern Client client;
@ -2104,3 +2105,8 @@ void Database::ClearGuildOnlineStatus()
{ {
GuildMembersRepository::ClearOnlineStatus(*this); GuildMembersRepository::ClearOnlineStatus(*this);
} }
void Database::ClearTraderDetails()
{
TraderRepository::Truncate(*this);
}

View File

@ -244,6 +244,7 @@ public:
void PurgeAllDeletedDataBuckets(); void PurgeAllDeletedDataBuckets();
void ClearGuildOnlineStatus(); void ClearGuildOnlineStatus();
void ClearTraderDetails();
/* Database Variables */ /* Database Variables */

View File

@ -289,6 +289,8 @@ bool WorldBoot::DatabaseLoadRoutines(int argc, char **argv)
LogInfo("Clearing inventory snapshots"); LogInfo("Clearing inventory snapshots");
database.ClearInvSnapshots(); database.ClearInvSnapshots();
LogInfo("Loading items"); LogInfo("Loading items");
LogInfo("Clearing trader table details");
database.ClearTraderDetails();
if (!content_db.LoadItems(hotfix_name)) { if (!content_db.LoadItems(hotfix_name)) {
LogError("Error: Could not load item data. But ignoring"); LogError("Error: Could not load item data. But ignoring");

View File

@ -41,7 +41,7 @@ extern QueryServ* QServ;
// The maximum amount of a single bazaar/barter transaction expressed in copper. // The maximum amount of a single bazaar/barter transaction expressed in copper.
// Equivalent to 2 Million plat // Equivalent to 2 Million plat
#define MAX_TRANSACTION_VALUE 2000000000 constexpr auto MAX_TRANSACTION_VALUE = 2000000000;
// ########################################## // ##########################################
// Trade implementation // Trade implementation
// ########################################## // ##########################################
@ -1048,12 +1048,12 @@ void Client::TraderStartTrader(const EQApplicationPacket *app)
std::vector<TraderRepository::Trader> trader_items{}; std::vector<TraderRepository::Trader> trader_items{};
//Check inventory for no-trade items //Check inventory for no-trade items
for (auto const &i: inv->serial_number) { for (auto i = 0; i < max_items; i++) {
if (i <= 0) { if (inv->items[i] == 0 || inv->serial_number[i] == 0) {
continue; continue;
} }
auto inst = FindTraderItemBySerialNumber(i); auto inst = FindTraderItemBySerialNumber(inv->serial_number[i]);
if (inst) { if (inst) {
if (inst->GetItem() && inst->GetItem()->NoDrop == 0) { if (inst->GetItem() && inst->GetItem()->NoDrop == 0) {
Message( Message(
@ -1320,7 +1320,7 @@ GetItems_Struct *Client::GetTraderItems()
{ {
const EQ::ItemInstance *item = nullptr; const EQ::ItemInstance *item = nullptr;
int16 slot_id = INVALID_INDEX; int16 slot_id = INVALID_INDEX;
auto gis = new GetItems_Struct; auto gis = new GetItems_Struct{0};
uint8 ndx = 0; uint8 ndx = 0;
for (int16 i = EQ::invslot::GENERAL_BEGIN; i <= EQ::invslot::GENERAL_END; i++) { for (int16 i = EQ::invslot::GENERAL_BEGIN; i <= EQ::invslot::GENERAL_END; i++) {
@ -1338,7 +1338,7 @@ GetItems_Struct *Client::GetTraderItems()
item = GetInv().GetItem(slot_id); item = GetInv().GetItem(slot_id);
if (item) { if (item) {
gis->items[ndx] = item->GetItem()->ID; gis->items[ndx] = item->GetID();
gis->serial_number[ndx] = item->GetSerialNumber(); gis->serial_number[ndx] = item->GetSerialNumber();
gis->charges[ndx] = item->GetCharges() == 0 ? 1 : item->GetCharges(); gis->charges[ndx] = item->GetCharges() == 0 ? 1 : item->GetCharges();
ndx++; ndx++;
@ -2044,7 +2044,7 @@ void Client::SendBazaarResults(
int Count = 0; int Count = 0;
uint32 StatValue = 0; uint32 StatValue = 0;
for (auto row = results.begin(); row != results.end(); ++row) { for (auto &row = results.begin(); row != results.end(); ++row) {
VARSTRUCT_ENCODE_TYPE(uint32, bufptr, Action); VARSTRUCT_ENCODE_TYPE(uint32, bufptr, Action);
Count = Strings::ToInt(row[0]); Count = Strings::ToInt(row[0]);
VARSTRUCT_ENCODE_TYPE(uint32, bufptr, Count); VARSTRUCT_ENCODE_TYPE(uint32, bufptr, Count);
@ -2304,7 +2304,7 @@ void Client::SendBuyerResults(char* searchString, uint32 searchID) {
uint32 lastCharID = 0; uint32 lastCharID = 0;
Client *buyer = nullptr; Client *buyer = nullptr;
for (auto row = results.begin(); row != results.end(); ++row) { for (auto &row = results.begin(); row != results.end(); ++row) {
char itemName[64]; char itemName[64];
uint32 charID = Strings::ToInt(row[0]); uint32 charID = Strings::ToInt(row[0]);
@ -2407,7 +2407,7 @@ void Client::ShowBuyLines(const EQApplicationPacket *app) {
if (!results.Success() || results.RowCount() == 0) if (!results.Success() || results.RowCount() == 0)
return; return;
for (auto row = results.begin(); row != results.end(); ++row) { for (auto &row = results.begin(); row != results.end(); ++row) {
char ItemName[64]; char ItemName[64];
uint32 BuySlot = Strings::ToInt(row[1]); uint32 BuySlot = Strings::ToInt(row[1]);
uint32 ItemID = Strings::ToInt(row[2]); uint32 ItemID = Strings::ToInt(row[2]);
@ -3309,7 +3309,7 @@ void Client::DoBazaarInspect(const BazaarInspect_Struct &in)
return; return;
} }
auto item = items.front(); auto &item = items.front();
std::unique_ptr<EQ::ItemInstance> inst( std::unique_ptr<EQ::ItemInstance> inst(
database.CreateItem( database.CreateItem(