From 8b70f791089ad2274d7d2cefdf405a846418e4b4 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sat, 22 Dec 2018 14:35:42 +1100 Subject: [PATCH] fix house init, some refactoring and base inventory impl --- bin/config/config.ini.default | 6 +- src/common/Database/ZoneDbConnection.cpp | 5 +- src/world/Manager/HousingMgr.cpp | 91 ++++++++++++++------ src/world/Manager/HousingMgr.h | 34 +++++++- src/world/Territory/House.cpp | 105 ++++++++++++----------- src/world/Territory/House.h | 7 +- src/world/Territory/HousingZone.cpp | 11 ++- src/world/Territory/Land.cpp | 12 +-- src/world/Territory/Land.h | 1 + 9 files changed, 184 insertions(+), 88 deletions(-) diff --git a/bin/config/config.ini.default b/bin/config/config.ini.default index 4c11b849..cacd9115 100644 --- a/bin/config/config.ini.default +++ b/bin/config/config.ini.default @@ -55,4 +55,8 @@ ListenPort = 54992 [General] ; Sent on login - each line must be shorter than 307 characters, split lines with ';' -MotD = Welcome to Sapphire!;This is a very good server;You can change these messages by editing General.MotD in config/zone.ini \ No newline at end of file +MotD = Welcome to Sapphire!;This is a very good server;You can change these messages by editing General.MotD in config/config.ini + +[Housing] +; Set the default estate name. %i will be replaced with the plot number +DefaultEstateName = Estate #%i \ No newline at end of file diff --git a/src/common/Database/ZoneDbConnection.cpp b/src/common/Database/ZoneDbConnection.cpp index e3beaaa5..a5104467 100644 --- a/src/common/Database/ZoneDbConnection.cpp +++ b/src/common/Database/ZoneDbConnection.cpp @@ -201,7 +201,10 @@ void Sapphire::Db::ZoneDbConnection::doPrepareStatements() CONNECTION_BOTH ); prepareStatement( LAND_INV_SEL_ALL, - "SELECT LandIdent, ContainerId, ItemId, SlotId FROM houseiteminventory;", + "SELECT houseiteminventory.*, charaglobalitem.catalogId, charaglobalitem.stain, charaglobalitem.CharacterId " + "FROM houseiteminventory " + "LEFT JOIN charaglobalitem " + "ON houseiteminventory.ItemId = charaglobalitem.itemId;", CONNECTION_BOTH ); prepareStatement( LAND_INV_SEL_HOUSE, diff --git a/src/world/Manager/HousingMgr.cpp b/src/world/Manager/HousingMgr.cpp index d38bd9e5..8d7c0b92 100644 --- a/src/world/Manager/HousingMgr.cpp +++ b/src/world/Manager/HousingMgr.cpp @@ -40,12 +40,51 @@ bool Sapphire::World::Manager::HousingMgr::init() { auto log = g_fw.get< Sapphire::Logger >(); - log->info( "HousingMgr: Caching housing land data" ); + log->info( "HousingMgr: Caching housing land init data" ); //LAND_SEL_ALL // 18 wards per territory, 4 territories m_landCache.reserve( 18 * 4 ); + loadLandCache(); + + 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 land entries. Only have " + std::to_string( count ) + " land entries." ); + return false; + } + } + + log->info( "HousingMgr: Cached " + std::to_string( houseCount ) + " houses" ); + + ///// + + if( !loadEstateInventories() ) + return false; + + return true; +} + +bool Sapphire::World::Manager::HousingMgr::loadEstateInventories() +{ + auto log = g_fw.get< Sapphire::Logger >(); + + log->info( "HousingMgr: Loading inventories for estates" ); + + return true; +} + +void Sapphire::World::Manager::HousingMgr::loadLandCache() +{ auto pDb = g_fw.get< Db::DbWorkerPool< Db::ZoneDbConnection > >(); auto stmt = pDb->getPreparedStatement( Db::LAND_SEL_ALL ); @@ -71,33 +110,12 @@ bool Sapphire::World::Manager::HousingMgr::init() // house stuff entry.m_estateWelcome = res->getString( "Welcome" ); entry.m_estateComment = res->getString( "Comment" ); - entry.m_houseName = res->getString( "HouseName" ); + entry.m_estateName = 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 land entries. Only have " + std::to_string( count ) + " land entries." ); - return false; - } - } - - log->info( "HousingMgr: Cached " + std::to_string( houseCount ) + " houses" ); - - - return true; } uint32_t Sapphire::World::Manager::HousingMgr::toLandSetId( uint16_t territoryTypeId, uint8_t wardId ) const @@ -570,7 +588,32 @@ void Sapphire::World::Manager::HousingMgr::sendEstateInventory( Entity::Player& invMgr->sendInventoryContainer( player, container ); } -const Sapphire::World::Manager::HousingMgr::LandSetLandCacheMap& Sapphire::World::Manager::HousingMgr::getLandCacheMap() const +const Sapphire::World::Manager::HousingMgr::LandSetLandCacheMap& + Sapphire::World::Manager::HousingMgr::getLandCacheMap() const { return m_landCache; +} + +Sapphire::World::Manager::HousingMgr::LandIdentToInventoryContainerMap + Sapphire::World::Manager::HousingMgr::getEstateInventories() const +{ + return m_estateInventories; +} + +Sapphire::World::Manager::HousingMgr::ContainerIdToContainerMap + Sapphire::World::Manager::HousingMgr::getEstateInventory( uint64_t ident ) const +{ + auto map = m_estateInventories.find( ident ); + + assert( map != m_estateInventories.end() ); + + return map->second; +} + +Sapphire::World::Manager::HousingMgr::ContainerIdToContainerMap + Sapphire::World::Manager::HousingMgr::getEstateInventory( Sapphire::Common::LandIdent ident ) const +{ + auto u64ident = *reinterpret_cast< uint64_t* >( &ident ); + + getEstateInventory( u64ident ); } \ No newline at end of file diff --git a/src/world/Manager/HousingMgr.h b/src/world/Manager/HousingMgr.h index a221db71..2f92d10e 100644 --- a/src/world/Manager/HousingMgr.h +++ b/src/world/Manager/HousingMgr.h @@ -38,7 +38,7 @@ namespace Sapphire::World::Manager std::string m_estateWelcome; std::string m_estateComment; - std::string m_houseName; + std::string m_estateName; uint64_t m_buildTime; uint64_t m_endorsements; @@ -49,6 +49,15 @@ namespace Sapphire::World::Manager */ using LandSetLandCacheMap = std::unordered_map< uint64_t, std::vector< LandCacheEntry > >; + /*! + * @brief Maps container IDs to their relevant ItemContainerPtr + */ + using ContainerIdToContainerMap = std::unordered_map< uint16_t, ItemContainerPtr >; + /*! + * @brief Maps land idents to a container containing ItemContainerPtrs + */ + using LandIdentToInventoryContainerMap = std::unordered_map< uint64_t, ContainerIdToContainerMap >; + HousingMgr(); virtual ~HousingMgr(); @@ -95,8 +104,31 @@ namespace Sapphire::World::Manager */ const LandSetLandCacheMap& getLandCacheMap() const; + /*! + * @brief Get all loaded inventories for housing estates + * @return + */ + LandIdentToInventoryContainerMap getEstateInventories() const; + + /*! + * @brief Get an estate inventory for a specific estate + * @param ident LandIdent for the specified estate + * @return A map containing container ids to ItemContainerPtr + */ + ContainerIdToContainerMap getEstateInventory( uint64_t ident ) const; + + /*! + * @brief Get an estate inventory for a specific estate + * @param ident LandIdent for the specified estate + * @return A map containing container ids to ItemContainerPtr + */ + ContainerIdToContainerMap getEstateInventory( Common::LandIdent ident ) const; private: + void loadLandCache(); + bool loadEstateInventories(); + LandSetLandCacheMap m_landCache; + LandIdentToInventoryContainerMap m_estateInventories; }; diff --git a/src/world/Territory/House.cpp b/src/world/Territory/House.cpp index 820a7b1e..9979e501 100644 --- a/src/world/Territory/House.cpp +++ b/src/world/Territory/House.cpp @@ -13,57 +13,58 @@ extern Sapphire::Framework g_fw; -Sapphire::House::House( uint32_t houseId, uint32_t landSetId, Common::LandIdent ident ) : +Sapphire::House::House( uint32_t houseId, uint32_t landSetId, Common::LandIdent ident, const std::string& estateName, + const std::string& estateComment ) : m_houseId( houseId ), m_landSetId( landSetId ), - m_landIdent( ident ) + m_landIdent( ident ), + m_estateName( estateName ), + m_estateComment( estateComment ) { - auto pDB = g_fw.get< Db::DbWorkerPool< Db::ZoneDbConnection > >(); - - // todo: convert to prepared statement - auto res = pDB->query( "SELECT * FROM house WHERE HouseId = " + std::to_string( houseId ) ); - - if( !res->next() ) - { - g_fw.get< Sapphire::Logger >()->info( "Creating house House#" + std::to_string( houseId ) + " in LandSet#" + std::to_string( landSetId ) ); - - auto stmt = pDB->getPreparedStatement( Db::HOUSING_HOUSE_INS ); - - stmt->setUInt( 1, m_landSetId ); - stmt->setUInt( 2, m_houseId ); - - pDB->execute( stmt ); - - // todo: make this nicer/configurable? - m_houseName = "Estate #" + std::to_string( m_landIdent.landId + 1 ); - } - else - { - m_estateMessage = res->getString( "Comment" ); - m_houseName = res->getString( "HouseName" ); - - auto housePartModels = res->getBlobVector( "HousePartModels" ); - auto housePartColours = res->getBlobVector( "HousePartColours" ); - - auto models = reinterpret_cast< uint32_t* >( &housePartModels[ 0 ] ); - for( auto i = 0; i < 8; i++ ) - { - m_houseParts[ i ] = { models[ i ], housePartColours[ i ] }; - } - - auto houseInteriorModels = res->getBlobVector( "HouseInteriorModels" ); - - auto interiorModels = reinterpret_cast< uint32_t* >( &houseInteriorModels[ 0 ] ); - for( auto i = 0; i < 10; i++ ) - { - m_houseInteriorParts[ i ] = interiorModels[ i ]; - } - } +// auto pDB = g_fw.get< Db::DbWorkerPool< Db::ZoneDbConnection > >(); +// +// // todo: convert to prepared statement +// auto res = pDB->query( "SELECT * FROM house WHERE HouseId = " + std::to_string( houseId ) ); +// +// if( !res->next() ) +// { +// g_fw.get< Sapphire::Logger >()->info( "Creating house House#" + std::to_string( houseId ) + " in LandSet#" + std::to_string( landSetId ) ); +// +// auto stmt = pDB->getPreparedStatement( Db::HOUSING_HOUSE_INS ); +// +// stmt->setUInt( 1, m_landSetId ); +// stmt->setUInt( 2, m_houseId ); +// +// pDB->execute( stmt ); +// +// // todo: make this nicer/configurable? +// m_estateName = "Estate #" + std::to_string( m_landIdent.landId + 1 ); +// } +// else +// { +// m_estateComment = res->getString( "Comment" ); +// m_estateName = res->getString( "HouseName" ); +// +// auto housePartModels = res->getBlobVector( "HousePartModels" ); +// auto housePartColours = res->getBlobVector( "HousePartColours" ); +// +// auto models = reinterpret_cast< uint32_t* >( &housePartModels[ 0 ] ); +// for( auto i = 0; i < 8; i++ ) +// { +// m_houseParts[ i ] = { models[ i ], housePartColours[ i ] }; +// } +// +// auto houseInteriorModels = res->getBlobVector( "HouseInteriorModels" ); +// +// auto interiorModels = reinterpret_cast< uint32_t* >( &houseInteriorModels[ 0 ] ); +// for( auto i = 0; i < 10; i++ ) +// { +// m_houseInteriorParts[ i ] = interiorModels[ i ]; +// } +// } } -Sapphire::House::~House() -{ -} +Sapphire::House::~House() = default; void Sapphire::House::updateHouseDb() { @@ -77,8 +78,8 @@ void Sapphire::House::updateHouseDb() stmt->setInt64( 1, m_buildTime ); stmt->setInt( 2, 0 ); - stmt->setString( 3, m_estateMessage ); - stmt->setString( 4, m_houseName ); + stmt->setString( 3, m_estateComment ); + stmt->setString( 4, m_estateName ); stmt->setUInt64( 5, 0 ); @@ -166,24 +167,24 @@ Sapphire::House::HousePartsArray const& Sapphire::House::getHouseParts() const const std::string& Sapphire::House::getHouseName() const { - return m_houseName; + return m_estateName; } const std::string& Sapphire::House::getHouseGreeting() const { - return m_estateMessage; + return m_estateComment; } void Sapphire::House::setHouseGreeting( const std::string& greeting ) { - m_estateMessage = greeting; + m_estateComment = greeting; updateHouseDb(); } void Sapphire::House::setHouseName( const std::string& name ) { - m_houseName = name; + m_estateName = name; updateHouseDb(); } \ No newline at end of file diff --git a/src/world/Territory/House.h b/src/world/Territory/House.h index f228874b..22726633 100644 --- a/src/world/Territory/House.h +++ b/src/world/Territory/House.h @@ -12,7 +12,8 @@ namespace Sapphire class House { public: - House( uint32_t houseId, uint32_t landSetId, Common::LandIdent ident ); + House( uint32_t houseId, uint32_t landSetId, Common::LandIdent ident, const std::string& estateName, + const std::string& estateComment ); virtual ~House(); using HousePart = std::pair< uint32_t, uint8_t >; @@ -51,8 +52,8 @@ namespace Sapphire HousePartsArray m_houseParts; uint32_t m_houseInteriorParts[10]; - std::string m_estateMessage; - std::string m_houseName; + std::string m_estateComment; + std::string m_estateName; }; } diff --git a/src/world/Territory/HousingZone.cpp b/src/world/Territory/HousingZone.cpp index 761d556f..ec485c72 100644 --- a/src/world/Territory/HousingZone.cpp +++ b/src/world/Territory/HousingZone.cpp @@ -76,9 +76,18 @@ bool Sapphire::HousingZone::init() } // init the lands - for( auto& entry : landSetCache->second ) + for( HousingMgr::LandCacheEntry& entry : landSetCache->second ) { auto land = make_Land( m_territoryTypeId, getWardNum(), entry.m_landId, m_landSetId, info ); + + // setup house + if( entry.m_houseId ) + { + //uint32_t houseId, uint32_t landSetId, Common::LandIdent ident, const std::string& estateName, + // const std::string& estateMessage + auto house = make_House( entry.m_houseId, m_landSetId, land->getLandIdent(), entry.m_estateName, entry.m_estateComment ); + } + land->init( entry.m_type, entry.m_size, entry.m_status, entry.m_currentPrice, entry.m_ownerId, entry.m_houseId ); m_landPtrMap[ entry.m_landId ] = land; diff --git a/src/world/Territory/Land.cpp b/src/world/Territory/Land.cpp index 21ab6a00..019165a2 100644 --- a/src/world/Territory/Land.cpp +++ b/src/world/Territory/Land.cpp @@ -62,10 +62,6 @@ void Sapphire::Land::init( Common::LandType type, uint8_t size, uint8_t state, u m_currentPrice = currentPrice; m_ownerId = ownerId; - // fetch the house if we have one for this land - if( houseId > 0 ) - m_pHouse = make_House( houseId, m_landSetId, getLandIdent() ); - auto pExdData = g_fw.get< Data::ExdDataGenerated >(); auto info = pExdData->get< Sapphire::Data::HousingMapMarkerInfo >( m_landIdent.territoryTypeId, m_landIdent.landId ); if( info ) @@ -224,6 +220,11 @@ Sapphire::HousePtr Sapphire::Land::getHouse() const return m_pHouse; } +void Sapphire::Land::setHouse( Sapphire::HousePtr house ) +{ + m_pHouse = house; +} + FFXIVARR_POSITION3 Sapphire::Land::getMapMarkerPosition() { return m_mapMarkerPosition; @@ -350,7 +351,8 @@ bool Sapphire::Land::setPreset( uint32_t itemId ) { // todo: i guess we'd create a house here? auto newId = getNextHouseId(); - m_pHouse = make_House( newId, getLandSetId(), getLandIdent() ); + + m_pHouse = make_House( newId, getLandSetId(), getLandIdent(), "Estate #" + std::to_string( m_landIdent.landId + 1 ), "" ); } diff --git a/src/world/Territory/Land.h b/src/world/Territory/Land.h index bf8a834c..c47bf3bb 100644 --- a/src/world/Territory/Land.h +++ b/src/world/Territory/Land.h @@ -33,6 +33,7 @@ namespace Sapphire uint8_t getSharing() const; uint32_t getLandSetId() const; Common::LandType getLandType() const; + void setHouse( Sapphire::HousePtr ); Sapphire::HousePtr getHouse() const; Common::FFXIVARR_POSITION3 getMapMarkerPosition(); Common::LandIdent getLandIdent() const;