2018-12-31 23:20:36 +11:00
|
|
|
#include "MarketMgr.h"
|
|
|
|
|
2021-11-27 00:53:57 +01:00
|
|
|
#include <Exd/ExdData.h>
|
2019-01-01 11:51:48 +11:00
|
|
|
#include <Logging/Logger.h>
|
|
|
|
|
|
|
|
#include <Network/CommonNetwork.h>
|
2019-03-08 15:34:38 +01:00
|
|
|
#include <Network/GamePacket.h>
|
2019-01-01 11:51:48 +11:00
|
|
|
#include <Network/PacketDef/Zone/ServerZoneDef.h>
|
|
|
|
|
|
|
|
#include "Actor/Player.h"
|
|
|
|
|
2019-01-01 14:19:44 +11:00
|
|
|
#include <algorithm>
|
|
|
|
|
2021-11-27 00:53:57 +01:00
|
|
|
#include <Service.h>
|
|
|
|
#include "WorldServer.h"
|
|
|
|
#include "Session.h"
|
|
|
|
#include "Network/GameConnection.h"
|
|
|
|
|
2022-01-27 21:08:43 +01:00
|
|
|
using namespace Sapphire;
|
|
|
|
using namespace Sapphire::World::Manager;
|
2021-11-27 00:53:57 +01:00
|
|
|
using namespace Sapphire::Network;
|
2019-01-01 11:51:48 +11:00
|
|
|
using namespace Sapphire::Network::Packets;
|
2021-11-27 00:53:57 +01:00
|
|
|
using namespace Sapphire::Network::Packets::WorldPackets::Server;
|
2019-01-01 11:51:48 +11:00
|
|
|
|
2022-01-27 21:08:43 +01:00
|
|
|
bool MarketMgr::init()
|
2018-12-31 23:20:36 +11:00
|
|
|
{
|
2019-01-01 23:37:32 +11:00
|
|
|
// Logger::info( "MarketMgr: warming up marketable item cache..." );
|
|
|
|
//
|
|
|
|
// // build item cache
|
2020-03-01 01:00:57 +11:00
|
|
|
// auto& exdData = Common::Service< Sapphire::Data::ExdDataGenerated >::ref();
|
|
|
|
// auto idList = exdData.getItemIdList();
|
2019-01-01 23:37:32 +11:00
|
|
|
//
|
|
|
|
// for( auto id : idList )
|
|
|
|
// {
|
|
|
|
// if( id > 10000 )
|
|
|
|
// break;
|
|
|
|
//
|
2020-03-01 01:00:57 +11:00
|
|
|
// auto item = exdData.get< Sapphire::Data::Item >( id );
|
2019-01-01 23:37:32 +11:00
|
|
|
// if( !item )
|
|
|
|
// continue;
|
|
|
|
//
|
|
|
|
// if( item->isUntradable )
|
|
|
|
// continue;
|
|
|
|
//
|
|
|
|
// MarketableItem cacheEntry {};
|
|
|
|
// cacheEntry.catalogId = id;
|
|
|
|
// cacheEntry.itemSearchCategory = item->itemSearchCategory;
|
|
|
|
// cacheEntry.maxEquipLevel = item->levelEquip;
|
|
|
|
// cacheEntry.name = item->name;
|
|
|
|
// cacheEntry.classJob = item->classJobUse;
|
|
|
|
// cacheEntry.itemLevel = item->levelItem;
|
|
|
|
//
|
|
|
|
// m_marketItemCache.push_back( std::move( cacheEntry ) );
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// std::sort( m_marketItemCache.begin(), m_marketItemCache.end(), []( const MarketableItem& a, const MarketableItem& b )
|
|
|
|
// {
|
|
|
|
// return a.itemLevel > b.itemLevel;
|
|
|
|
// } );
|
|
|
|
//
|
|
|
|
// Logger::info( "MarketMgr: Cached " + std::to_string( m_marketItemCache.size() ) + " marketable items" );
|
2019-01-01 11:51:48 +11:00
|
|
|
|
2018-12-31 23:20:36 +11:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2022-01-27 21:08:43 +01:00
|
|
|
void MarketMgr::requestItemListingInfo( Entity::Player& player, uint32_t catalogId, uint32_t requestId )
|
2019-01-01 11:51:48 +11:00
|
|
|
{
|
2021-11-27 00:53:57 +01:00
|
|
|
|
|
|
|
auto& server = Common::Service< World::WorldServer >::ref();
|
|
|
|
auto pSession = server.getSession( player.getCharacterId() );
|
|
|
|
|
|
|
|
auto countPkt = makeZonePacket< FFFXIVIpcMarketBoardItemListingCount >( player.getId() );
|
2019-01-01 17:29:06 +11:00
|
|
|
countPkt->data().quantity = 1 << 8;
|
2019-01-01 11:51:48 +11:00
|
|
|
countPkt->data().itemCatalogId = catalogId;
|
2019-01-01 17:29:06 +11:00
|
|
|
countPkt->data().requestId = requestId;
|
|
|
|
|
2021-11-27 00:53:57 +01:00
|
|
|
pSession->getZoneConnection()->queueOutPacket( countPkt );
|
2019-01-01 17:29:06 +11:00
|
|
|
|
2021-11-27 00:53:57 +01:00
|
|
|
auto historyPkt = makeZonePacket< FFXIVIpcGetItemHistoryResult >( player.getId() );
|
|
|
|
historyPkt->data().CatalogID = catalogId;
|
2019-01-01 17:29:06 +11:00
|
|
|
|
2019-01-01 23:37:32 +11:00
|
|
|
std::string name = "fix game pls se :(((";
|
2019-01-01 17:29:06 +11:00
|
|
|
|
2019-01-01 23:37:32 +11:00
|
|
|
for( int i = 0; i < 10; i++ )
|
2019-01-01 17:29:06 +11:00
|
|
|
{
|
2021-11-27 00:53:57 +01:00
|
|
|
auto& listing = historyPkt->data().ItemHistoryList[ i ];
|
2019-01-01 17:29:06 +11:00
|
|
|
|
2021-11-27 00:53:57 +01:00
|
|
|
listing.CatalogID = catalogId;
|
|
|
|
listing.Stack = i + 1;
|
|
|
|
listing.BuyRealDate = Common::Util::getTimeSeconds();
|
|
|
|
listing.SellPrice = 69420420;
|
|
|
|
listing.SubQuality = 1;
|
2019-01-01 23:37:32 +11:00
|
|
|
|
2021-11-27 00:53:57 +01:00
|
|
|
strcpy( listing.BuyCharacterName, name.c_str() );
|
2019-01-01 17:29:06 +11:00
|
|
|
}
|
|
|
|
|
2021-11-27 00:53:57 +01:00
|
|
|
pSession->getZoneConnection()->queueOutPacket( historyPkt );
|
2019-01-01 11:51:48 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-01-27 21:08:43 +01:00
|
|
|
void MarketMgr::searchMarketboard( Entity::Player& player, uint8_t itemSearchCategory, uint8_t maxEquipLevel, uint8_t classJob,
|
|
|
|
const std::string_view& searchStr, uint32_t requestId, uint32_t startIdx )
|
2018-12-31 23:20:36 +11:00
|
|
|
{
|
2021-11-27 00:53:57 +01:00
|
|
|
auto& server = Common::Service< World::WorldServer >::ref();
|
|
|
|
auto pSession = server.getSession( player.getCharacterId() );
|
|
|
|
|
2019-01-01 11:51:48 +11:00
|
|
|
ItemSearchResultList resultList;
|
|
|
|
findItems( searchStr, itemSearchCategory, maxEquipLevel, classJob, resultList );
|
|
|
|
|
|
|
|
auto numResults = resultList.size();
|
|
|
|
|
|
|
|
if( startIdx > numResults )
|
|
|
|
return;
|
|
|
|
|
|
|
|
auto endIdx = std::min< size_t >( startIdx + 20, numResults );
|
|
|
|
auto size = endIdx - startIdx;
|
|
|
|
|
2021-11-27 00:53:57 +01:00
|
|
|
auto resultPkt = makeZonePacket< FFXIVIpcCatalogSearchResult >( player.getId() );
|
|
|
|
resultPkt->data().Index = startIdx;
|
|
|
|
resultPkt->data().RequestKey = requestId;
|
2019-01-01 11:51:48 +11:00
|
|
|
|
2019-01-01 14:19:44 +11:00
|
|
|
for( auto i = 0; i < size; i++ )
|
2019-01-01 11:51:48 +11:00
|
|
|
{
|
|
|
|
auto& item = resultList.at( startIdx + i );
|
2021-11-27 00:53:57 +01:00
|
|
|
auto& data = resultPkt->data().CatalogList[ i ];
|
2019-01-01 11:51:48 +11:00
|
|
|
|
2021-11-27 00:53:57 +01:00
|
|
|
data.CatalogID = item.catalogId;
|
|
|
|
data.StockCount = item.quantity;
|
|
|
|
data.RequestItemCount = 420;
|
2019-01-01 11:51:48 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
if( size < 20 )
|
2021-11-27 00:53:57 +01:00
|
|
|
resultPkt->data().NextIndex = 0;
|
2019-01-01 11:51:48 +11:00
|
|
|
else
|
2021-11-27 00:53:57 +01:00
|
|
|
resultPkt->data().NextIndex = startIdx + 20;
|
2019-01-01 11:51:48 +11:00
|
|
|
|
2021-11-27 00:53:57 +01:00
|
|
|
pSession->getZoneConnection()->queueOutPacket( resultPkt );
|
2019-01-01 11:51:48 +11:00
|
|
|
}
|
|
|
|
|
2022-01-27 21:08:43 +01:00
|
|
|
void MarketMgr::requestItemListings( Sapphire::Entity::Player& player, uint16_t catalogId )
|
2019-01-01 17:29:06 +11:00
|
|
|
{
|
2019-01-01 23:37:32 +11:00
|
|
|
|
2019-01-01 17:29:06 +11:00
|
|
|
}
|
|
|
|
|
2022-01-27 21:08:43 +01:00
|
|
|
void MarketMgr::findItems( const std::string_view& searchStr, uint8_t itemSearchCat, uint8_t maxEquipLevel, uint8_t classJob,
|
|
|
|
MarketMgr::ItemSearchResultList& resultList )
|
2019-01-01 11:51:48 +11:00
|
|
|
{
|
|
|
|
for( const auto& item : m_marketItemCache )
|
|
|
|
{
|
|
|
|
if( item.itemSearchCategory != itemSearchCat )
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if( maxEquipLevel > 0 && item.maxEquipLevel > maxEquipLevel )
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if( classJob > 0 && item.classJob != classJob )
|
|
|
|
continue;
|
|
|
|
|
|
|
|
resultList.push_back( { item.catalogId, 1 } );
|
|
|
|
}
|
2019-03-08 15:34:38 +01:00
|
|
|
}
|