diff --git a/src/common/Database/ZoneDbConnection.cpp b/src/common/Database/ZoneDbConnection.cpp index 2e96cd6a..e3beaaa5 100644 --- a/src/common/Database/ZoneDbConnection.cpp +++ b/src/common/Database/ZoneDbConnection.cpp @@ -212,10 +212,10 @@ void Sapphire::Db::ZoneDbConnection::doPrepareStatements() "SELECT * FROM land WHERE LandSetId = ?;", CONNECTION_SYNC ); - prepareStatement( LAND_SEL_BATCH, - "SELECT land.*, house.Welcome, house.Aetheryte, house.Comment, house.HouseName, house.BuildTime, house.Endorsements" - "FROM land" - "LEFT JOIN house" + prepareStatement( LAND_SEL_ALL, + "SELECT land.*, house.Welcome, house.Aetheryte, house.Comment, house.HouseName, house.BuildTime, house.Endorsements " + "FROM land " + "LEFT JOIN house " "ON land.HouseId = house.HouseId;", CONNECTION_SYNC ); diff --git a/src/common/Database/ZoneDbConnection.h b/src/common/Database/ZoneDbConnection.h index 47bce834..179993d9 100644 --- a/src/common/Database/ZoneDbConnection.h +++ b/src/common/Database/ZoneDbConnection.h @@ -80,7 +80,7 @@ namespace Sapphire::Db LAND_INS, LAND_SEL, - LAND_SEL_BATCH, + LAND_SEL_ALL, LAND_UP, LANDSET_SEL, HOUSING_HOUSE_INS, diff --git a/src/world/Manager/HousingMgr.cpp b/src/world/Manager/HousingMgr.cpp index 44846d0e..f5ef4403 100644 --- a/src/world/Manager/HousingMgr.cpp +++ b/src/world/Manager/HousingMgr.cpp @@ -33,18 +33,70 @@ using namespace Sapphire::Network::Packets::Server; extern Sapphire::Framework g_fw; -Sapphire::World::Manager::HousingMgr::HousingMgr() -{ - -} - -Sapphire::World::Manager::HousingMgr::~HousingMgr() -{ - -} +Sapphire::World::Manager::HousingMgr::HousingMgr() = default; +Sapphire::World::Manager::HousingMgr::~HousingMgr() = default; bool Sapphire::World::Manager::HousingMgr::init() { + auto log = g_fw.get< Sapphire::Logger >(); + + log->info( "HousingMgr: Caching housing land data" ); + //LAND_SEL_ALL + + // 18 wards per territory, 4 territories + m_landCache.reserve( 18 * 4 ); + + auto pDb = g_fw.get< Db::DbWorkerPool< Db::ZoneDbConnection > >(); + + auto stmt = pDb->getPreparedStatement( Db::LAND_SEL_ALL ); + auto res = pDb->query( stmt ); + + while( res->next() ) + { + LandCacheEntry entry; + + // land stuff + entry.m_landSetId = res->getUInt64( "LandSetId" ); + entry.m_landId = res->getUInt64( "LandId" ); + + entry.m_type = res->getUInt8( "Type" ); + entry.m_size = res->getUInt8( "Size" ); + entry.m_status = res->getUInt8( "Status" ); + entry.m_landPrice = res->getUInt64( "LandPrice" ); + entry.m_updateTime = res->getUInt64( "UpdateTime" ); + entry.m_ownerId = res->getUInt64( "OwnerId" ); + + entry.m_houseId = res->getUInt64( "HouseId" ); + + // house stuff + + entry.m_estateWelcome = res->getString( "Welcome" ); + entry.m_estateComment = res->getString( "Comment" ); + entry.m_houseName = res->getString( "HouseName" ); + entry.m_buildTime = res->getUInt64( "BuildTime" ); + entry.m_endorsements = res->getUInt64( "Endorsements" ); + + m_landCache[ entry.m_landSetId ].push_back( entry ); + } + + log->info( "HousingMgr: Checking land counts" ); + + uint32_t houseCount = 0; + for( auto& landSet : m_landCache ) + { + auto count = landSet.second.size(); + + houseCount += count; + + if( landSet.second.size() != 60 ) + { + log->fatal( "LandSet " + std::to_string( landSet.first ) + " is missing entries. Only have " + std::to_string( count ) + " land entries." ); + return false; + } + } + + log->info( "HousingMgr: Cached " + std::to_string( houseCount ) + " houses" ); + return true; } @@ -472,7 +524,8 @@ Sapphire::Common::LandIdent Sapphire::World::Manager::HousingMgr::clientTriggerP return ident; } -void Sapphire::World::Manager::HousingMgr::sendHousingInventory( Entity::Player& player, uint16_t inventoryType, uint8_t plotNum ) +void Sapphire::World::Manager::HousingMgr::sendEstateInventory( Entity::Player& player, uint16_t inventoryType, + uint8_t plotNum ) { Sapphire::LandPtr targetLand; @@ -516,4 +569,9 @@ void Sapphire::World::Manager::HousingMgr::sendHousingInventory( Entity::Player& auto invMgr = g_fw.get< Manager::InventoryMgr >(); invMgr->sendInventoryContainer( player, container ); +} + +const Sapphire::World::Manager::HousingMgr::LandSetLandCacheMap& Sapphire::World::Manager::HousingMgr::getLandCacheMap() const +{ + return m_landCache; } \ No newline at end of file diff --git a/src/world/Manager/HousingMgr.h b/src/world/Manager/HousingMgr.h index b4334714..8716a3ba 100644 --- a/src/world/Manager/HousingMgr.h +++ b/src/world/Manager/HousingMgr.h @@ -17,6 +17,38 @@ namespace Sapphire::World::Manager { public: + + struct LandCacheEntry + { + // land table + uint64_t m_landSetId; + uint64_t m_landId; + + uint8_t m_type; + uint8_t m_size; + uint8_t m_status; + + uint64_t m_landPrice; + + uint64_t m_updateTime; + uint64_t m_ownerId; + uint64_t m_houseId; + + // house table + + std::string m_estateWelcome; + std::string m_estateComment; + std::string m_houseName; + + uint64_t m_buildTime; + uint64_t m_endorsements; + }; + + /*! + * @brief Maps land id to a list of cached entries + */ + using LandSetLandCacheMap = std::unordered_map< uint64_t, std::vector< LandCacheEntry > >; + HousingMgr(); virtual ~HousingMgr(); @@ -53,9 +85,18 @@ namespace Sapphire::World::Manager /*! * @brief Sends the house inventory for the specified type to a player. * - * This enforces permissions on the inventory too so random players can't request a houses items + * This enforces permissions on the inventory too so random players can't request an estates items */ - void sendHousingInventory( Entity::Player& player, uint16_t inventoryType, uint8_t plotNum ); + void sendEstateInventory( Entity::Player& player, uint16_t inventoryType, uint8_t plotNum ); + + /*! + * @brief Get the land & house data that was cached on world startup. + * @return + */ + const LandSetLandCacheMap& getLandCacheMap() const; + + private: + LandSetLandCacheMap m_landCache; }; diff --git a/src/world/Network/Handlers/ClientTriggerHandler.cpp b/src/world/Network/Handlers/ClientTriggerHandler.cpp index de7528c2..e61e168d 100644 --- a/src/world/Network/Handlers/ClientTriggerHandler.cpp +++ b/src/world/Network/Handlers/ClientTriggerHandler.cpp @@ -434,7 +434,7 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( const Packets::FFX if( param2 == 1 ) inventoryType = Common::InventoryType::HousingOutdoorStoreroom; - housingMgr->sendHousingInventory( player, inventoryType, plot ); + housingMgr->sendEstateInventory( player, inventoryType, plot ); break; } diff --git a/src/world/ServerMgr.cpp b/src/world/ServerMgr.cpp index ec597356..842151d3 100644 --- a/src/world/ServerMgr.cpp +++ b/src/world/ServerMgr.cpp @@ -151,6 +151,12 @@ void Sapphire::ServerMgr::run( int32_t argc, char* argv[] ) auto pTeriMgr = std::make_shared< Manager::TerritoryMgr >(); auto pHousingMgr = std::make_shared< Manager::HousingMgr >(); g_fw.set< Manager::HousingMgr >( pHousingMgr ); + if( !pHousingMgr->init() ) + { + pLog->fatal( "Failed to setup housing!" ); + return; + } + g_fw.set< Manager::TerritoryMgr >( pTeriMgr ); if( !pTeriMgr->init() ) {