trading post try fix crash
This commit is contained in:
@@ -19,6 +19,7 @@
|
||||
#include "PerkProgramData.h"
|
||||
#include "PerkProgramMgr.h"
|
||||
#include "PerksProgramPacketsCommon.h"
|
||||
#include "PerksProgramPackets.h"
|
||||
#include "Config.h"
|
||||
#include "DatabaseEnv.h"
|
||||
#include "ObjectMgr.h"
|
||||
@@ -39,17 +40,21 @@ void WorldSession::HandlePerkProgramRequestPurchase(WorldPackets::PerksProgram::
|
||||
if (!_player)
|
||||
return;
|
||||
|
||||
//GetPerkProgramMgr()->BuyItem(packet.PerksVendorItemID, packet.vendorGuid);
|
||||
GetPerkProgramMgr()->BuyItem(packet.VendorItemID, ObjectGuid::Empty);
|
||||
}
|
||||
|
||||
void WorldSession::HandlePerkProgamSetForzenVendorItem(WorldPackets::PerksProgram::PerksProgramSetFrozenVendorItem& packet)
|
||||
void WorldSession::HandlePerkProgramSetFrozenVendorItem(WorldPackets::PerksProgram::PerksProgramSetFrozenVendorItem& packet)
|
||||
{
|
||||
if (!_player)
|
||||
return;
|
||||
|
||||
GetPerkProgramMgr()->SetFrozenItem(packet.VendorItemID, packet.VendorItemID == -1);
|
||||
}
|
||||
|
||||
void WorldSession::HandlePerkProgramPendingReward(WorldPackets::PerksProgram::PerksProgramPendingReward& packet)
|
||||
{
|
||||
if (!_player)
|
||||
return;
|
||||
|
||||
GetPerkProgramMgr()->SendPendingRewards();
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
#include "DB2Stores.h"
|
||||
#include <sstream>
|
||||
#include "GameTime.h"
|
||||
#include <random>
|
||||
#include <chrono>
|
||||
|
||||
PerkProgramDataStoreMgr::PerkProgramDataStoreMgr() {};
|
||||
|
||||
@@ -47,11 +49,19 @@ void PerkProgramDataStoreMgr::LoadPerkVendorItem()
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 validCount = 0;
|
||||
for (PerksVendorItemEntry const* itemVendor : sPerksVendorItemStore)
|
||||
{
|
||||
if (!itemVendor)
|
||||
continue;
|
||||
|
||||
// Validate item data
|
||||
if (itemVendor->Cost > 1000000) // Reasonable maximum cost
|
||||
{
|
||||
TC_LOG_WARN("server.loading", ">> PerksVendorItem {} has excessive cost {}, skipping", itemVendor->ID, itemVendor->Cost);
|
||||
continue;
|
||||
}
|
||||
|
||||
PerkProgramData::PerkVendorItem vendorItem;
|
||||
vendorItem.Id = itemVendor->ID;
|
||||
vendorItem.ItemID = itemVendor->ItemID;
|
||||
@@ -60,13 +70,15 @@ void PerkProgramDataStoreMgr::LoadPerkVendorItem()
|
||||
vendorItem.TransmogSet = 0;
|
||||
vendorItem.ItemModifiedAppearanceID = 0;
|
||||
vendorItem.ToyItem = 0;
|
||||
vendorItem.AvailableUntil = 0; // Initialize to 0 (no expiration)
|
||||
vendorItem.Cost = itemVendor->Cost;
|
||||
vendorItem.CategoryId = itemVendor->PerksVendorCategoryID;
|
||||
|
||||
_vendorTemplates.insert(std::make_pair(itemVendor->ID, vendorItem));
|
||||
validCount++;
|
||||
}
|
||||
|
||||
TC_LOG_INFO("server.loading", ">> Loaded {} PerkPrograms Vendor Items Templates", uint32(_vendorTemplates.size()));
|
||||
TC_LOG_INFO("server.loading", ">> Loaded {} PerkPrograms Vendor Items Templates ({} valid)", uint32(_vendorTemplates.size()), validCount);
|
||||
}
|
||||
|
||||
std::unordered_map<uint32, PerkProgramData::PerkVendorItem> PerkProgramDataStoreMgr::GetVendorItems()
|
||||
@@ -88,8 +100,11 @@ PerkProgramData::PerkVendorItem const* PerkProgramDataStoreMgr::GetRandomVendorI
|
||||
if (_vendorTemplates.empty())
|
||||
return nullptr;
|
||||
|
||||
// Use proper random number generation
|
||||
static thread_local std::mt19937 generator(std::random_device{}());
|
||||
std::uniform_int_distribution<size_t> distribution(0, _vendorTemplates.size() - 1);
|
||||
auto it = _vendorTemplates.begin();
|
||||
std::advance(it, rand() % _vendorTemplates.size());
|
||||
std::advance(it, distribution(generator));
|
||||
return &it->second;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,8 @@ using namespace PerkPrograms;
|
||||
PerkProgramManager::PerkProgramManager(WorldSession* session)
|
||||
{
|
||||
_session = session;
|
||||
if (session->GetPlayer())
|
||||
m_player = nullptr;
|
||||
if (session && session->GetPlayer())
|
||||
m_player = session->GetPlayer();
|
||||
|
||||
m_currencyAmount = 0;
|
||||
@@ -49,6 +50,17 @@ PerkProgramManager::~PerkProgramManager()
|
||||
|
||||
void PerkProgramManager::SendVendorItems(Creature* vendor, std::vector<uint32> purchasedItems)
|
||||
{
|
||||
// Additional safety check - verify this pointer is valid
|
||||
if (this == nullptr)
|
||||
return;
|
||||
|
||||
if (!_session || !vendor)
|
||||
return;
|
||||
|
||||
// Validate session is still valid
|
||||
if (_session->GetPlayer() != m_player)
|
||||
m_player = _session->GetPlayer();
|
||||
|
||||
WorldPackets::PerksProgram::PerksProgramResult perks;
|
||||
perks.Type = PerkPrograms::RESULT_AVAILABLE_ITEMS;
|
||||
|
||||
@@ -71,7 +83,8 @@ void PerkProgramManager::SendVendorItems(Creature* vendor, std::vector<uint32> p
|
||||
if (cameraId != 0)
|
||||
{
|
||||
std::list<Creature*> list;
|
||||
_session->GetPlayer()->GetCreatureListWithEntryInGrid(list, cameraId, 100);
|
||||
if (_session->GetPlayer())
|
||||
_session->GetPlayer()->GetCreatureListWithEntryInGrid(list, cameraId, 100);
|
||||
|
||||
for (auto cr1 : list)
|
||||
{
|
||||
@@ -93,8 +106,12 @@ void PerkProgramManager::SendVendorItems(Creature* vendor, std::vector<uint32> p
|
||||
vendorItem.OriginalPrice = items.second.CategoryId;
|
||||
vendorItem.Disabled = false;
|
||||
vendorItem.AvailableUntil = items.second.AvailableUntil;
|
||||
perks.Params.VendorItem.FrozenPerksVendorItems.emplace_back(vendorItem);
|
||||
|
||||
// Skip items that are no longer available
|
||||
if (items.second.AvailableUntil > 0 && GameTime::GetGameTime() > items.second.AvailableUntil)
|
||||
continue;
|
||||
|
||||
perks.Params.VendorItem.FrozenPerksVendorItems.emplace_back(vendorItem);
|
||||
}
|
||||
|
||||
_session->SendPacket(perks.Write());
|
||||
@@ -121,7 +138,7 @@ bool PerkProgramManager::IsAccountWideItem(uint32 item)
|
||||
|
||||
bool PerkProgramManager::IsItemAlreadyOwned(PerkProgramData::PerkVendorItem const* vendorItem)
|
||||
{
|
||||
if (!vendorItem)
|
||||
if (!vendorItem || !m_player)
|
||||
return true;
|
||||
|
||||
switch (vendorItem->CategoryId)
|
||||
@@ -145,7 +162,7 @@ bool PerkProgramManager::IsItemAlreadyOwned(PerkProgramData::PerkVendorItem cons
|
||||
|
||||
void PerkProgramManager::GrantItem(PerkProgramData::PerkVendorItem const* vendorItem)
|
||||
{
|
||||
if (!vendorItem)
|
||||
if (!vendorItem || !m_player)
|
||||
return;
|
||||
|
||||
switch (vendorItem->CategoryId)
|
||||
@@ -187,7 +204,7 @@ void PerkProgramManager::GrantItem(PerkProgramData::PerkVendorItem const* vendor
|
||||
|
||||
void PerkProgramManager::RemoveGrantedItem(PerkProgramData::PerkVendorItem const* vendorItem)
|
||||
{
|
||||
if (!vendorItem)
|
||||
if (!vendorItem || !m_player)
|
||||
return;
|
||||
|
||||
switch (vendorItem->CategoryId)
|
||||
@@ -213,6 +230,12 @@ void PerkProgramManager::RemoveGrantedItem(PerkProgramData::PerkVendorItem const
|
||||
|
||||
void PerkProgramManager::BuyItem(uint32 itemId, ObjectGuid /*vendor*/)
|
||||
{
|
||||
if (!m_player)
|
||||
{
|
||||
SendPerksProgramError(6);
|
||||
return;
|
||||
}
|
||||
|
||||
auto const* vendorItem = sPerkProgramDataStore->GetVendorItem(itemId);
|
||||
if (!vendorItem)
|
||||
{
|
||||
@@ -245,6 +268,9 @@ void PerkProgramManager::BuyItem(uint32 itemId, ObjectGuid /*vendor*/)
|
||||
|
||||
void PerkProgramManager::SendBuyItemResult(int32 itemId)
|
||||
{
|
||||
if (!_session)
|
||||
return;
|
||||
|
||||
WorldPackets::PerksProgram::PerksProgramResult perks;
|
||||
perks.Type = PerkPrograms::RESULT_BUY_ITEM;
|
||||
perks.Params.BuyItem.VendorItemID = itemId;
|
||||
@@ -259,15 +285,23 @@ void PerkProgramManager::SendBuyItemResult(int32 itemId)
|
||||
|
||||
void PerkProgramManager::SendCurrencyRefresh()
|
||||
{
|
||||
if (!_session)
|
||||
return;
|
||||
|
||||
WorldPackets::PerksProgram::PerksProgramResult perks;
|
||||
perks.Type = PerkPrograms::RESULT_CURRENCY_REFRESH;
|
||||
perks.Params.Currency.CurrencyAmount = m_currencyAmount;
|
||||
_session->SendPacket(perks.Write());
|
||||
}
|
||||
|
||||
void PerkProgramManager::SendPerksProgramError(uint32 errorCode)
|
||||
{
|
||||
if (!_session)
|
||||
return;
|
||||
|
||||
WorldPackets::PerksProgram::PerksProgramResult perks;
|
||||
perks.Type = PerkPrograms::RESULT_ERROR;
|
||||
perks.Params.Error.ErrorCode = errorCode;
|
||||
_session->SendPacket(perks.Write());
|
||||
}
|
||||
|
||||
@@ -278,6 +312,12 @@ void PerkProgramManager::RecordPurchase(uint32 itemId, time_t purchaseTime)
|
||||
|
||||
void PerkProgramManager::RefundItem(int32 itemId)
|
||||
{
|
||||
if (!m_player)
|
||||
{
|
||||
SendPerksProgramError(6);
|
||||
return;
|
||||
}
|
||||
|
||||
auto it = std::find_if(m_recentPurchases.begin(), m_recentPurchases.end(),
|
||||
[itemId](std::pair<uint32, time_t> const& p) { return p.first == static_cast<uint32>(itemId); });
|
||||
|
||||
@@ -293,6 +333,13 @@ void PerkProgramManager::RefundItem(int32 itemId)
|
||||
return;
|
||||
}
|
||||
|
||||
// Additional safety check for very old purchases
|
||||
if (it->second > GameTime::GetGameTime())
|
||||
{
|
||||
SendPerksProgramError(5);
|
||||
return;
|
||||
}
|
||||
|
||||
auto const* vendorItem = sPerkProgramDataStore->GetVendorItem(itemId);
|
||||
if (!vendorItem)
|
||||
return;
|
||||
@@ -310,6 +357,9 @@ void PerkProgramManager::RefundItem(int32 itemId)
|
||||
|
||||
void PerkProgramManager::SendRefundSuccess(int32 itemId)
|
||||
{
|
||||
if (!_session)
|
||||
return;
|
||||
|
||||
WorldPackets::PerksProgram::PerksProgramResult perks;
|
||||
perks.Type = PerkPrograms::RESULT_REFUND_SUCCESS;
|
||||
perks.Params.BuyItem.VendorItemID = itemId;
|
||||
@@ -318,6 +368,12 @@ void PerkProgramManager::SendRefundSuccess(int32 itemId)
|
||||
|
||||
void PerkProgramManager::CartCheckout(std::vector<uint32> const& vendorItemIDs)
|
||||
{
|
||||
if (!m_player)
|
||||
{
|
||||
SendPerksProgramError(6);
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 totalCost = 0;
|
||||
|
||||
for (uint32 itemId : vendorItemIDs)
|
||||
@@ -359,6 +415,9 @@ void PerkProgramManager::CartCheckout(std::vector<uint32> const& vendorItemIDs)
|
||||
|
||||
void PerkProgramManager::SendCartCheckoutSuccess()
|
||||
{
|
||||
if (!_session)
|
||||
return;
|
||||
|
||||
WorldPackets::PerksProgram::PerksProgramResult perks;
|
||||
perks.Type = PerkPrograms::RESULT_PURCHASE_CART;
|
||||
_session->SendPacket(perks.Write());
|
||||
@@ -366,8 +425,12 @@ void PerkProgramManager::SendCartCheckoutSuccess()
|
||||
|
||||
void PerkProgramManager::SendPerksProgramStatus()
|
||||
{
|
||||
if (!_session)
|
||||
return;
|
||||
|
||||
WorldPackets::PerksProgram::PerksProgramResult perks;
|
||||
perks.Type = PerkPrograms::RESULT_CURRENCY_REFRESH;
|
||||
perks.Params.Currency.CurrencyAmount = m_currencyAmount;
|
||||
_session->SendPacket(perks.Write());
|
||||
}
|
||||
|
||||
@@ -377,6 +440,9 @@ void PerkProgramManager::SendPendingRewards()
|
||||
|
||||
void PerkProgramManager::SetFrozenItem(int32 itemId, bool clear)
|
||||
{
|
||||
if (!_session)
|
||||
return;
|
||||
|
||||
if (clear)
|
||||
{
|
||||
m_frozenItems.clear();
|
||||
@@ -408,13 +474,14 @@ void PerkProgramManager::RemoveTrackedActivity(uint32 activityId)
|
||||
{
|
||||
auto it = std::find(m_trackedActivities.begin(), m_trackedActivities.end(), activityId);
|
||||
if (it != m_trackedActivities.end())
|
||||
{
|
||||
m_trackedActivities.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
void PerkProgramManager::SendPerksProgramActivities()
|
||||
{
|
||||
if (!_session)
|
||||
return;
|
||||
|
||||
WorldPackets::PerksProgram::PerksProgramActivityUpdate activity;
|
||||
|
||||
activity.TimeUntilStart = GameTime::GetGameTime();
|
||||
|
||||
@@ -73,6 +73,12 @@ WorldPacket const* PerksProgramResult::Write()
|
||||
for (auto&& frozenPerksVendorItem : Params.VendorItem.FrozenPerksVendorItems)
|
||||
_worldPacket << frozenPerksVendorItem;
|
||||
break;
|
||||
case 11: //ResultTypes::CurrencyRefresh:
|
||||
_worldPacket << Params.Currency.CurrencyAmount;
|
||||
break;
|
||||
case 10: //ResultTypes::Error:
|
||||
_worldPacket << Params.Error.ErrorCode;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -95,6 +95,16 @@ public:
|
||||
ObjectGuid VendorGuid;
|
||||
ObjectGuid ModelSceneCameraGuid;
|
||||
} VendorItem;
|
||||
|
||||
struct
|
||||
{
|
||||
uint32 CurrencyAmount = 0;
|
||||
} Currency;
|
||||
|
||||
struct
|
||||
{
|
||||
uint32 ErrorCode = 0;
|
||||
} Error;
|
||||
} Params = {};
|
||||
};
|
||||
|
||||
|
||||
@@ -882,7 +882,7 @@ void OpcodeTable::InitializeClientOpcodes()
|
||||
DEFINE_HANDLER(CMSG_PERKS_PROGRAM_REQUEST_PENDING_REWARDS, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandlePerkProgramPendingReward);
|
||||
DEFINE_HANDLER(CMSG_PERKS_PROGRAM_REQUEST_PURCHASE, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandlePerkProgramRequestPurchase);
|
||||
DEFINE_HANDLER(CMSG_PERKS_PROGRAM_REQUEST_REFUND, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL);
|
||||
DEFINE_HANDLER(CMSG_PERKS_PROGRAM_SET_FROZEN_VENDOR_ITEM, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandlePerkProgamSetForzenVendorItem);
|
||||
DEFINE_HANDLER(CMSG_PERKS_PROGRAM_SET_FROZEN_VENDOR_ITEM, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandlePerkProgramSetFrozenVendorItem);
|
||||
DEFINE_HANDLER(CMSG_PERKS_PROGRAM_STATUS_REQUEST, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleGetPerkProgramRequest);
|
||||
DEFINE_HANDLER(CMSG_PETITION_BUY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetitionBuy);
|
||||
DEFINE_HANDLER(CMSG_PETITION_RENAME_GUILD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetitionRenameGuild);
|
||||
|
||||
@@ -1553,7 +1553,7 @@ class TC_GAME_API WorldSession
|
||||
//PERKS
|
||||
void HandleGetPerkProgramRequest(WorldPackets::PerksProgram::PerksProgramStatusRequest& packet);
|
||||
void HandlePerkProgramRequestPurchase(WorldPackets::PerksProgram::PerksProgramRequestPurchase& packet);
|
||||
void HandlePerkProgamSetForzenVendorItem(WorldPackets::PerksProgram::PerksProgramSetFrozenVendorItem& packet);
|
||||
void HandlePerkProgramSetFrozenVendorItem(WorldPackets::PerksProgram::PerksProgramSetFrozenVendorItem& packet);
|
||||
void HandlePerkProgramPendingReward(WorldPackets::PerksProgram::PerksProgramPendingReward& packet);
|
||||
|
||||
//wowcommunity
|
||||
|
||||
Reference in New Issue
Block a user