From cb96c26c3e1e2725e537a50f8243cbfaf5a5e459 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sat, 22 Dec 2018 02:08:28 +1100 Subject: [PATCH 01/10] add batch land select to get all land + houses in 1 query --- src/common/Database/ZoneDbConnection.cpp | 7 +++++++ src/common/Database/ZoneDbConnection.h | 1 + src/world/Territory/Land.cpp | 1 + 3 files changed, 9 insertions(+) diff --git a/src/common/Database/ZoneDbConnection.cpp b/src/common/Database/ZoneDbConnection.cpp index b35ecf79..2e96cd6a 100644 --- a/src/common/Database/ZoneDbConnection.cpp +++ b/src/common/Database/ZoneDbConnection.cpp @@ -212,6 +212,13 @@ 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" + "ON land.HouseId = house.HouseId;", + CONNECTION_SYNC ); + /*prepareStatement( LAND_INS, "INSERT INTO land ( LandSetId ) VALUES ( ? );", CONNECTION_BOTH ); diff --git a/src/common/Database/ZoneDbConnection.h b/src/common/Database/ZoneDbConnection.h index 2cbfac6e..47bce834 100644 --- a/src/common/Database/ZoneDbConnection.h +++ b/src/common/Database/ZoneDbConnection.h @@ -80,6 +80,7 @@ namespace Sapphire::Db LAND_INS, LAND_SEL, + LAND_SEL_BATCH, LAND_UP, LANDSET_SEL, HOUSING_HOUSE_INS, diff --git a/src/world/Territory/Land.cpp b/src/world/Territory/Land.cpp index d575cfea..21ab6a00 100644 --- a/src/world/Territory/Land.cpp +++ b/src/world/Territory/Land.cpp @@ -139,6 +139,7 @@ void Sapphire::Land::loadItemContainerContents() items[ containerId ].push_back( std::make_pair( slotId, itemId ) ); } + // fuck the query off res.reset(); for( auto it = items.begin(); it != items.end(); it++ ) From 09f01238095b01367479b12948054f4c97c16831 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sat, 22 Dec 2018 11:33:21 +1100 Subject: [PATCH 02/10] cache all houses on startup --- src/common/Database/ZoneDbConnection.cpp | 8 +- src/common/Database/ZoneDbConnection.h | 2 +- src/world/Manager/HousingMgr.cpp | 78 ++++++++++++++++--- src/world/Manager/HousingMgr.h | 45 ++++++++++- .../Network/Handlers/ClientTriggerHandler.cpp | 2 +- src/world/ServerMgr.cpp | 6 ++ 6 files changed, 123 insertions(+), 18 deletions(-) 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() ) { From 74b41683ace75bb116945ef3d41f92499577defe Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sat, 22 Dec 2018 12:00:03 +1100 Subject: [PATCH 03/10] init houses from land cache instead of territory based queries --- src/world/Manager/HousingMgr.cpp | 7 +++-- src/world/Manager/HousingMgr.h | 4 +-- src/world/Territory/HousingZone.cpp | 41 ++++++++++------------------- 3 files changed, 19 insertions(+), 33 deletions(-) diff --git a/src/world/Manager/HousingMgr.cpp b/src/world/Manager/HousingMgr.cpp index f5ef4403..d38bd9e5 100644 --- a/src/world/Manager/HousingMgr.cpp +++ b/src/world/Manager/HousingMgr.cpp @@ -59,17 +59,16 @@ bool Sapphire::World::Manager::HousingMgr::init() entry.m_landSetId = res->getUInt64( "LandSetId" ); entry.m_landId = res->getUInt64( "LandId" ); - entry.m_type = res->getUInt8( "Type" ); + entry.m_type = static_cast< Common::LandType >( res->getUInt( "Type" ) ); entry.m_size = res->getUInt8( "Size" ); entry.m_status = res->getUInt8( "Status" ); - entry.m_landPrice = res->getUInt64( "LandPrice" ); + entry.m_currentPrice = 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" ); @@ -90,7 +89,7 @@ bool Sapphire::World::Manager::HousingMgr::init() if( landSet.second.size() != 60 ) { - log->fatal( "LandSet " + std::to_string( landSet.first ) + " is missing entries. Only have " + std::to_string( count ) + " land entries." ); + log->fatal( "LandSet " + std::to_string( landSet.first ) + " is missing land entries. Only have " + std::to_string( count ) + " land entries." ); return false; } } diff --git a/src/world/Manager/HousingMgr.h b/src/world/Manager/HousingMgr.h index 8716a3ba..a221db71 100644 --- a/src/world/Manager/HousingMgr.h +++ b/src/world/Manager/HousingMgr.h @@ -24,11 +24,11 @@ namespace Sapphire::World::Manager uint64_t m_landSetId; uint64_t m_landId; - uint8_t m_type; + Common::LandType m_type; uint8_t m_size; uint8_t m_status; - uint64_t m_landPrice; + uint64_t m_currentPrice; uint64_t m_updateTime; uint64_t m_ownerId; diff --git a/src/world/Territory/HousingZone.cpp b/src/world/Territory/HousingZone.cpp index 17fdfd3b..761d556f 100644 --- a/src/world/Territory/HousingZone.cpp +++ b/src/world/Territory/HousingZone.cpp @@ -64,40 +64,27 @@ bool Sapphire::HousingZone::init() auto pExdData = g_fw.get< Data::ExdDataGenerated >(); auto info = pExdData->get< Sapphire::Data::HousingLandSet >( housingIndex ); - auto stmt = pDb->getPreparedStatement( Db::LANDSET_SEL ); - stmt->setUInt64( 1, m_landSetId ); - auto res = pDb->query( stmt ); + auto housingMgr = g_fw.get< World::Manager::HousingMgr >(); + auto landCache = housingMgr->getLandCacheMap(); - std::vector< QueuedLandInit > landInit; - - while( res->next() ) + // make sure the landset exists + auto landSetCache = landCache.find( m_landSetId ); + if( landSetCache == landCache.end() ) { - - QueuedLandInit init; - init.m_landId = res->getUInt64( "LandId" ); - init.m_type = static_cast< Common::LandType >( res->getUInt( "Type" ) ); - init.m_size = res->getUInt( "Size" ); - init.m_status = res->getUInt( "Status" ); - init.m_currentPrice = res->getUInt( "LandPrice" ); - init.m_ownerId = res->getUInt64( "OwnerId" ); - init.m_houseId = res->getUInt64( "HouseId" ); - - landInit.push_back( init ); + g_fw.get< Sapphire::Logger >()->fatal( "LandSet " + std::to_string( m_landSetId ) + " is missing from the land cache." ); + return false; } - // nuke current query connection so the queries still in land don't fail - res.reset(); - - // spawn land - for( auto& init : landInit ) + // init the lands + for( auto& entry : landSetCache->second ) { - auto land = make_Land( m_territoryTypeId, getWardNum(), init.m_landId, m_landSetId, info ); - land->init( init.m_type, init.m_size, init.m_status, init.m_currentPrice, init.m_ownerId, init.m_houseId ); + auto land = make_Land( m_territoryTypeId, getWardNum(), entry.m_landId, m_landSetId, info ); + land->init( entry.m_type, entry.m_size, entry.m_status, entry.m_currentPrice, entry.m_ownerId, entry.m_houseId ); - m_landPtrMap[ init.m_landId ] = land; + m_landPtrMap[ entry.m_landId ] = land; - if( init.m_houseId > 0 ) - registerHouseEntranceEObj( init.m_landId ); + if( entry.m_houseId > 0 ) + registerHouseEntranceEObj( entry.m_landId ); } return true; From 05b4045165e1d4fd8d3356a88811e0e7fe3c9fa6 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sat, 22 Dec 2018 14:35:42 +1100 Subject: [PATCH 04/10] 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; From 3346ce6740b842c52808caf110431e000efb949b Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sat, 22 Dec 2018 15:58:54 +1100 Subject: [PATCH 05/10] load housing invs correctly --- src/world/Manager/HousingMgr.cpp | 48 +++++++++++++++- src/world/Territory/House.cpp | 24 ++++---- src/world/Territory/House.h | 8 +-- src/world/Territory/HousingZone.cpp | 28 +++++----- src/world/Territory/Land.cpp | 86 ++++++----------------------- src/world/Territory/Land.h | 4 -- 6 files changed, 93 insertions(+), 105 deletions(-) diff --git a/src/world/Manager/HousingMgr.cpp b/src/world/Manager/HousingMgr.cpp index 8d7c0b92..a4bc4a1b 100644 --- a/src/world/Manager/HousingMgr.cpp +++ b/src/world/Manager/HousingMgr.cpp @@ -25,6 +25,8 @@ #include "ServerMgr.h" #include "Territory/House.h" #include "InventoryMgr.h" +#include "Inventory/Item.h" +#include "Inventory/ItemContainer.h" using namespace Sapphire::Common; using namespace Sapphire::Network; @@ -48,7 +50,7 @@ bool Sapphire::World::Manager::HousingMgr::init() loadLandCache(); - log->info( "HousingMgr: Checking land counts" ); + log->debug( "HousingMgr: Checking land counts" ); uint32_t houseCount = 0; for( auto& landSet : m_landCache ) @@ -80,6 +82,48 @@ bool Sapphire::World::Manager::HousingMgr::loadEstateInventories() log->info( "HousingMgr: Loading inventories for estates" ); + auto pDb = g_fw.get< Db::DbWorkerPool< Db::ZoneDbConnection > >(); + + auto stmt = pDb->getPreparedStatement( Db::LAND_INV_SEL_ALL ); + auto res = pDb->query( stmt ); + + uint32_t itemCount = 0; + while( res->next() ) + { + //uint64_t uId, uint32_t catalogId, uint64_t model1, uint64_t model2, bool isHq + uint64_t ident = res->getUInt64( "LandIdent" ); + uint16_t containerId = res->getUInt16( "ContainerId" ); + uint64_t itemId = res->getUInt64( "ItemId" ); + uint16_t slot = res->getUInt16( "SlotId" ); + uint32_t catalogId = res->getUInt( "catalogId" ); + uint8_t stain = res->getUInt8( "stain" ); + uint64_t characterId = res->getUInt64( "CharacterId" ); + + auto item = make_Item( itemId, catalogId, 0, 0, 0 ); + item->setStain( stain ); + // todo: need to set the owner character id on the item + + ContainerIdToContainerMap estateInv = m_estateInventories[ ident ]; + + // check if containerId exists + auto container = estateInv.find( containerId ); + if( container == estateInv.end() ) + { + // create container + // todo: how to handle this max slot stuff? override it on land init? + auto ic = make_ItemContainer( containerId, 400, "houseiteminventory", true ); + ic->setItem( slot, item ); + + estateInv[ containerId ] = ic; + } + else + container->second->setItem( slot, item ); + + itemCount++; + } + + log->debug( "HousingMgr: Loaded " + std::to_string( itemCount ) + " inventory items" ); + return true; } @@ -580,7 +624,7 @@ void Sapphire::World::Manager::HousingMgr::sendEstateInventory( Entity::Player& if( targetLand->getOwnerId() != player.getId() ) return; - auto container = targetLand->getItemContainer( inventoryType ); + auto container = getEstateInventory( targetLand->getLandIdent() )[ inventoryType ]; if( !container ) return; diff --git a/src/world/Territory/House.cpp b/src/world/Territory/House.cpp index 9979e501..b4be2e63 100644 --- a/src/world/Territory/House.cpp +++ b/src/world/Territory/House.cpp @@ -51,7 +51,7 @@ Sapphire::House::House( uint32_t houseId, uint32_t landSetId, Common::LandIdent // auto models = reinterpret_cast< uint32_t* >( &housePartModels[ 0 ] ); // for( auto i = 0; i < 8; i++ ) // { -// m_houseParts[ i ] = { models[ i ], housePartColours[ i ] }; +// m_houseModelsCache[ i ] = { models[ i ], housePartColours[ i ] }; // } // // auto houseInteriorModels = res->getBlobVector( "HouseInteriorModels" ); @@ -59,7 +59,7 @@ Sapphire::House::House( uint32_t houseId, uint32_t landSetId, Common::LandIdent // auto interiorModels = reinterpret_cast< uint32_t* >( &houseInteriorModels[ 0 ] ); // for( auto i = 0; i < 10; i++ ) // { -// m_houseInteriorParts[ i ] = interiorModels[ i ]; +// m_houseInteriorModels[ i ] = interiorModels[ i ]; // } // } } @@ -88,7 +88,7 @@ void Sapphire::House::updateHouseDb() for( auto i = 0; i < 8; i++ ) { - auto& part = m_houseParts[ i ]; + auto& part = m_houseModelsCache[ i ]; models.push_back( part.first ); colours.push_back( part.second ); } @@ -104,7 +104,7 @@ void Sapphire::House::updateHouseDb() for( auto i = 0; i < 10; i++ ) { - models.push_back( m_houseInteriorParts[ i ] ); + models.push_back( m_houseInteriorModels[ i ] ); } std::vector< uint8_t > tmp2Models( models.size() * 4 ); @@ -132,37 +132,37 @@ uint32_t Sapphire::House::getHouseId() const uint8_t Sapphire::House::getHousePartColor( Common::HousePartSlot slot ) const { - return m_houseParts[ slot ].second; + return m_houseModelsCache[ slot ].second; } uint32_t Sapphire::House::getHouseInteriorPart( Common::HousingInteriorSlot slot ) const { - return m_houseInteriorParts[ slot ]; + return m_houseInteriorModels[ slot ]; } void Sapphire::House::setHousePart( Common::HousePartSlot slot, uint32_t id ) { - m_houseParts[ slot ].first = id; + m_houseModelsCache[ slot ].first = id; } void Sapphire::House::setHousePartColor( Common::HousePartSlot slot, uint32_t id ) { - m_houseParts[ slot ].second = id; + m_houseModelsCache[ slot ].second = id; } void Sapphire::House::setHouseInteriorPart( Common::HousingInteriorSlot slot, uint32_t id ) { - m_houseInteriorParts[ slot ] = id; + m_houseInteriorModels[ slot ] = id; } uint32_t Sapphire::House::getHousePart( Common::HousePartSlot slot ) const { - return m_houseParts[ slot ].first; + return m_houseModelsCache[ slot ].first; } -Sapphire::House::HousePartsArray const& Sapphire::House::getHouseParts() const +Sapphire::House::HouseModelsArray const& Sapphire::House::getHouseModels() const { - return m_houseParts; + return m_houseModelsCache; } const std::string& Sapphire::House::getHouseName() const diff --git a/src/world/Territory/House.h b/src/world/Territory/House.h index 22726633..f4c71817 100644 --- a/src/world/Territory/House.h +++ b/src/world/Territory/House.h @@ -17,7 +17,7 @@ namespace Sapphire virtual ~House(); using HousePart = std::pair< uint32_t, uint8_t >; - using HousePartsArray = std::array< HousePart, 8 >; + using HouseModelsArray = std::array< HousePart, 8 >; //gerneral uint32_t getLandSetId() const; @@ -38,7 +38,7 @@ namespace Sapphire uint8_t getHousePartColor( Common::HousePartSlot slot ) const; uint32_t getHouseInteriorPart( Common::HousingInteriorSlot slot ) const; - HousePartsArray const& getHouseParts() const; + HouseModelsArray const& getHouseModels() const; void updateHouseDb(); @@ -49,8 +49,8 @@ namespace Sapphire uint64_t m_buildTime; - HousePartsArray m_houseParts; - uint32_t m_houseInteriorParts[10]; + HouseModelsArray m_houseModelsCache; + uint32_t m_houseInteriorModels[10]; std::string m_estateComment; std::string m_estateName; diff --git a/src/world/Territory/HousingZone.cpp b/src/world/Territory/HousingZone.cpp index ec485c72..292344b4 100644 --- a/src/world/Territory/HousingZone.cpp +++ b/src/world/Territory/HousingZone.cpp @@ -83,9 +83,9 @@ bool Sapphire::HousingZone::init() // 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->setHouse( house ); } land->init( entry.m_type, entry.m_size, entry.m_status, entry.m_currentPrice, entry.m_ownerId, entry.m_houseId ); @@ -115,20 +115,20 @@ void Sapphire::HousingZone::onPlayerZoneIn( Entity::Player& player ) for( yardPacketNum = 0; yardPacketNum < yardPacketTotal; yardPacketNum++ ) { - auto housingObjectInitializPacket = makeZonePacket< FFXIVIpcHousingObjectInitialize >( player.getId() ); - memset( &housingObjectInitializPacket->data().landIdent, 0xFF, sizeof( Common::LandIdent ) ); - housingObjectInitializPacket->data().u1 = 0xFF; - housingObjectInitializPacket->data().packetNum = yardPacketNum; - housingObjectInitializPacket->data().packetTotal = yardPacketTotal; + auto housingObjectInit = makeZonePacket< FFXIVIpcHousingObjectInitialize >( player.getId() ); + memset( &housingObjectInit->data().landIdent, 0xFF, sizeof( Common::LandIdent ) ); + housingObjectInit->data().u1 = 0xFF; + housingObjectInit->data().packetNum = yardPacketNum; + housingObjectInit->data().packetTotal = yardPacketTotal; //TODO: Add Objects here - player.queuePacket( housingObjectInitializPacket ); + player.queuePacket( housingObjectInit ); } auto landSetMap = makeZonePacket< FFXIVIpcLandSetMap >( player.getId() ); - landSetMap->data().subdivision = isPlayerSubInstance( player ) == false ? 2 : 1; - uint8_t startIndex = isPlayerSubInstance( player ) == false ? 0 : 30; + landSetMap->data().subdivision = !isPlayerSubInstance( player ) ? 2 : 1; + uint8_t startIndex = !isPlayerSubInstance( player ) ? 0 : 30; for( uint8_t i = startIndex, count = 0; i < ( startIndex + 30 ); i++, count++ ) { landSetMap->data().landInfo[ count ].status = 1; @@ -147,9 +147,9 @@ void Sapphire::HousingZone::sendLandSet( Entity::Player& player ) landsetInitializePacket->data().landIdent.territoryTypeId = m_territoryTypeId; //TODO: get current WorldId landsetInitializePacket->data().landIdent.worldId = 67; - landsetInitializePacket->data().subInstance = isPlayerSubInstance( player ) == false ? 1 : 2; + landsetInitializePacket->data().subInstance = !isPlayerSubInstance( player ) ? 1 : 2; - uint8_t startIndex = isPlayerSubInstance( player ) == false ? 0 : 30; + uint8_t startIndex = !isPlayerSubInstance( player ) ? 0 : 30; for( uint8_t i = startIndex, count = 0; i < ( startIndex + 30 ); ++i, ++count ) { @@ -169,7 +169,7 @@ void Sapphire::HousingZone::sendLandSet( Entity::Player& player ) { landData.flags = 1; - auto& parts = house->getHouseParts(); + auto& parts = house->getHouseModels(); for( auto i = 0; i != parts.size(); i++ ) { @@ -206,7 +206,7 @@ void Sapphire::HousingZone::sendLandUpdate( uint8_t landId ) { landData.flags = 1; - auto& parts = house->getHouseParts(); + auto& parts = house->getHouseModels(); for( auto i = 0; i != parts.size(); i++ ) { diff --git a/src/world/Territory/Land.cpp b/src/world/Territory/Land.cpp index 019165a2..4a1d075a 100644 --- a/src/world/Territory/Land.cpp +++ b/src/world/Territory/Land.cpp @@ -90,66 +90,23 @@ void Sapphire::Land::init( Common::LandType type, uint8_t size, uint8_t state, u } // init item containers - auto setupContainer = [ this ]( InventoryType type, uint16_t maxSize ) - { - m_landInventoryMap[ type ] = make_ItemContainer( type, maxSize, "houseiteminventory", true, true ); - }; - - setupContainer( InventoryType::HousingOutdoorAppearance, 8 ); - setupContainer( InventoryType::HousingOutdoorPlacedItems, m_maxPlacedExternalItems ); - setupContainer( InventoryType::HousingOutdoorStoreroom, m_maxPlacedExternalItems ); - - setupContainer( InventoryType::HousingInteriorAppearance, 9 ); - - // nb: so we're going to store these internally in one container because SE is fucked in the head - // but when an inventory is requested, we will split them into groups of 50 - setupContainer( InventoryType::HousingInteriorPlacedItems1, m_maxPlacedInternalItems ); - setupContainer( InventoryType::HousingInteriorStoreroom1, m_maxPlacedInternalItems ); - - loadItemContainerContents(); -} - -void Sapphire::Land::loadItemContainerContents() -{ - if( !m_pHouse ) - return; - - auto ident = *reinterpret_cast< uint64_t* >( &m_landIdent ); - g_fw.get< Sapphire::Logger >()->debug( "Loading housing inventory for ident: " + std::to_string( ident ) ); - - auto pDB = g_fw.get< Db::DbWorkerPool< Db::ZoneDbConnection > >(); - - auto stmt = pDB->getPreparedStatement( Db::LAND_INV_SEL_HOUSE ); - stmt->setUInt64( 1, ident ); - - auto res = pDB->query( stmt ); - - std::unordered_map< uint16_t, std::vector< std::pair< uint16_t, uint32_t > > > items; - - while( res->next() ) - { - auto containerId = res->getUInt( "ContainerId" ); - auto itemId = res->getUInt64( "ItemId" ); - auto slotId = res->getUInt( "SlotId" ); - - items[ containerId ].push_back( std::make_pair( slotId, itemId ) ); - } - - // fuck the query off - res.reset(); - - for( auto it = items.begin(); it != items.end(); it++ ) - { - auto container = m_landInventoryMap[ it->first ]; - - // todo: delet this - for( auto fuck = it->second.begin(); fuck != it->second.end(); fuck++ ) - { - auto item = Sapphire::Items::Util::loadItem( fuck->second ); - if( item ) - container->setItem( fuck->first, item ); - } - } +// auto setupContainer = [ this ]( InventoryType type, uint16_t maxSize ) +// { +// m_landInventoryMap[ type ] = make_ItemContainer( type, maxSize, "houseiteminventory", true, true ); +// }; +// +// setupContainer( InventoryType::HousingOutdoorAppearance, 8 ); +// setupContainer( InventoryType::HousingOutdoorPlacedItems, m_maxPlacedExternalItems ); +// setupContainer( InventoryType::HousingOutdoorStoreroom, m_maxPlacedExternalItems ); +// +// setupContainer( InventoryType::HousingInteriorAppearance, 9 ); +// +// // nb: so we're going to store these internally in one container because SE is fucked in the head +// // but when an inventory is requested, we will split them into groups of 50 +// setupContainer( InventoryType::HousingInteriorPlacedItems1, m_maxPlacedInternalItems ); +// setupContainer( InventoryType::HousingInteriorStoreroom1, m_maxPlacedInternalItems ); +// +// loadItemContainerContents(); } uint32_t Sapphire::Land::convertItemIdToHousingItemId( uint32_t itemId ) @@ -374,13 +331,4 @@ bool Sapphire::Land::setPreset( uint32_t itemId ) return true; -} - -Sapphire::ItemContainerPtr Sapphire::Land::getItemContainer( uint16_t inventoryType ) const -{ - auto container = m_landInventoryMap.find( inventoryType ); - if( container == m_landInventoryMap.end() ) - return nullptr; - - return container->second; } \ No newline at end of file diff --git a/src/world/Territory/Land.h b/src/world/Territory/Land.h index c47bf3bb..19977e77 100644 --- a/src/world/Territory/Land.h +++ b/src/world/Territory/Land.h @@ -61,9 +61,6 @@ namespace Sapphire void setLandTag( uint8_t slot, uint8_t tag ); uint8_t getLandTag( uint8_t slot ); - ItemContainerPtr getItemContainer( uint16_t inventoryType ) const; - void loadItemContainerContents(); - private: uint32_t convertItemIdToHousingItemId( uint32_t itemId ); uint32_t getNextHouseId(); @@ -87,7 +84,6 @@ namespace Sapphire Sapphire::HousePtr m_pHouse; //item storage - LandInventoryMap m_landInventoryMap; uint16_t m_maxPlacedExternalItems; uint16_t m_maxPlacedInternalItems; From 66156a97ca5f8436fe753dccb5872f1d88198fcf Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sat, 22 Dec 2018 16:00:04 +1100 Subject: [PATCH 06/10] remove old land init struct --- src/world/Territory/HousingZone.h | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/world/Territory/HousingZone.h b/src/world/Territory/HousingZone.h index 63fcfb4b..3868f31a 100644 --- a/src/world/Territory/HousingZone.h +++ b/src/world/Territory/HousingZone.h @@ -53,17 +53,6 @@ namespace Sapphire Entity::EventObjectPtr registerHouseEntranceEObj( uint8_t plotId ); private: - struct QueuedLandInit - { - uint64_t m_landId; - Common::LandType m_type; - uint8_t m_size; - uint8_t m_status; - uint32_t m_currentPrice; - uint64_t m_ownerId; - uint64_t m_houseId; - }; - using LandPtrMap = std::unordered_map< uint8_t, Sapphire::LandPtr >; const uint32_t m_landSetMax = 18; LandPtrMap m_landPtrMap; From 1b097e4181ff45fec7e22972f46146867dd49ed2 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sat, 22 Dec 2018 17:22:24 +1100 Subject: [PATCH 07/10] partially fix inventory loading fuckery --- src/world/Manager/HousingMgr.cpp | 34 ++++++++++++++++++++++++++++- src/world/Manager/HousingMgr.h | 8 +++++++ src/world/Territory/HousingZone.cpp | 1 + 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/world/Manager/HousingMgr.cpp b/src/world/Manager/HousingMgr.cpp index a4bc4a1b..becad6ed 100644 --- a/src/world/Manager/HousingMgr.cpp +++ b/src/world/Manager/HousingMgr.cpp @@ -103,7 +103,7 @@ bool Sapphire::World::Manager::HousingMgr::loadEstateInventories() item->setStain( stain ); // todo: need to set the owner character id on the item - ContainerIdToContainerMap estateInv = m_estateInventories[ ident ]; + ContainerIdToContainerMap& estateInv = m_estateInventories[ ident ]; // check if containerId exists auto container = estateInv.find( containerId ); @@ -660,4 +660,36 @@ Sapphire::World::Manager::HousingMgr::ContainerIdToContainerMap auto u64ident = *reinterpret_cast< uint64_t* >( &ident ); getEstateInventory( u64ident ); +} + +void Sapphire::World::Manager::HousingMgr::updateHouseModels( Sapphire::HousePtr house ) +{ + assert( house ); + + auto getItemData = []( uint32_t itemId ) + { + auto pExdData = g_fw.get< Data::ExdDataGenerated >(); + auto info = pExdData->get< Sapphire::Data::Item >( itemId ); + return info->additionalData; + }; + + auto containers = getEstateInventory( house->getLandIdent() ); + + auto extContainer = containers.find( static_cast< uint16_t >( InventoryType::HousingOutdoorAppearance ) ); + if( extContainer != containers.end() ) + { + for( auto& item : extContainer->second->getItemMap() ) + { + house->setHousePart( static_cast< Common::HousePartSlot >( item.first ), getItemData( item.second->getId() ) ); + } + } + + auto intContainer = containers.find( static_cast< uint16_t >( InventoryType::HousingInteriorAppearance ) ); + if( intContainer != containers.end() ) + { + for( auto& item : intContainer->second->getItemMap() ) + { + house->setHouseInteriorPart( static_cast< Common::HousingInteriorSlot >( item.first ), getItemData( item.second->getId() ) ); + } + } } \ No newline at end of file diff --git a/src/world/Manager/HousingMgr.h b/src/world/Manager/HousingMgr.h index 2f92d10e..3609c173 100644 --- a/src/world/Manager/HousingMgr.h +++ b/src/world/Manager/HousingMgr.h @@ -91,6 +91,14 @@ namespace Sapphire::World::Manager void sendEstateGreeting( Entity::Player& player, const Common::LandIdent ident ); + /*! + * @brief Updates the cached models on a house from the relevant apperance inventories. + * Does not send the subsequent update to clients. + * + * @param house The house to update the models for + */ + void updateHouseModels( HousePtr house ); + /*! * @brief Sends the house inventory for the specified type to a player. * diff --git a/src/world/Territory/HousingZone.cpp b/src/world/Territory/HousingZone.cpp index 292344b4..075059e2 100644 --- a/src/world/Territory/HousingZone.cpp +++ b/src/world/Territory/HousingZone.cpp @@ -85,6 +85,7 @@ bool Sapphire::HousingZone::init() { auto house = make_House( entry.m_houseId, m_landSetId, land->getLandIdent(), entry.m_estateName, entry.m_estateComment ); + housingMgr->updateHouseModels( house ); land->setHouse( house ); } From 54f3a8e933d5c5f1f490b27d2825a0cb7c9d00c3 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sat, 22 Dec 2018 17:25:30 +1100 Subject: [PATCH 08/10] correctly load appearance from db --- src/world/Manager/HousingMgr.cpp | 14 +++++++------- src/world/Manager/HousingMgr.h | 8 ++++---- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/world/Manager/HousingMgr.cpp b/src/world/Manager/HousingMgr.cpp index becad6ed..1395ba9a 100644 --- a/src/world/Manager/HousingMgr.cpp +++ b/src/world/Manager/HousingMgr.cpp @@ -633,19 +633,19 @@ void Sapphire::World::Manager::HousingMgr::sendEstateInventory( Entity::Player& } const Sapphire::World::Manager::HousingMgr::LandSetLandCacheMap& - Sapphire::World::Manager::HousingMgr::getLandCacheMap() const + Sapphire::World::Manager::HousingMgr::getLandCacheMap() { return m_landCache; } -Sapphire::World::Manager::HousingMgr::LandIdentToInventoryContainerMap - Sapphire::World::Manager::HousingMgr::getEstateInventories() const +Sapphire::World::Manager::HousingMgr::LandIdentToInventoryContainerMap& + Sapphire::World::Manager::HousingMgr::getEstateInventories() { return m_estateInventories; } -Sapphire::World::Manager::HousingMgr::ContainerIdToContainerMap - Sapphire::World::Manager::HousingMgr::getEstateInventory( uint64_t ident ) const +Sapphire::World::Manager::HousingMgr::ContainerIdToContainerMap& + Sapphire::World::Manager::HousingMgr::getEstateInventory( uint64_t ident ) { auto map = m_estateInventories.find( ident ); @@ -654,8 +654,8 @@ Sapphire::World::Manager::HousingMgr::ContainerIdToContainerMap return map->second; } -Sapphire::World::Manager::HousingMgr::ContainerIdToContainerMap - Sapphire::World::Manager::HousingMgr::getEstateInventory( Sapphire::Common::LandIdent ident ) const +Sapphire::World::Manager::HousingMgr::ContainerIdToContainerMap& + Sapphire::World::Manager::HousingMgr::getEstateInventory( Sapphire::Common::LandIdent ident ) { auto u64ident = *reinterpret_cast< uint64_t* >( &ident ); diff --git a/src/world/Manager/HousingMgr.h b/src/world/Manager/HousingMgr.h index 3609c173..d0c59a6c 100644 --- a/src/world/Manager/HousingMgr.h +++ b/src/world/Manager/HousingMgr.h @@ -110,27 +110,27 @@ namespace Sapphire::World::Manager * @brief Get the land & house data that was cached on world startup. * @return */ - const LandSetLandCacheMap& getLandCacheMap() const; + const LandSetLandCacheMap& getLandCacheMap(); /*! * @brief Get all loaded inventories for housing estates * @return */ - LandIdentToInventoryContainerMap getEstateInventories() const; + LandIdentToInventoryContainerMap& getEstateInventories(); /*! * @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; + ContainerIdToContainerMap& getEstateInventory( uint64_t ident ); /*! * @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; + ContainerIdToContainerMap& getEstateInventory( Common::LandIdent ident ); private: void loadLandCache(); bool loadEstateInventories(); From 3d0780e9fe6caaff77f264d192c203aa6be69d4a Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sat, 22 Dec 2018 17:29:40 +1100 Subject: [PATCH 09/10] cleanup old house apperance crap --- src/common/Database/ZoneDbConnection.cpp | 2 +- src/world/Territory/House.cpp | 76 +----------------------- 2 files changed, 4 insertions(+), 74 deletions(-) diff --git a/src/common/Database/ZoneDbConnection.cpp b/src/common/Database/ZoneDbConnection.cpp index a5104467..a19f32d9 100644 --- a/src/common/Database/ZoneDbConnection.cpp +++ b/src/common/Database/ZoneDbConnection.cpp @@ -197,7 +197,7 @@ void Sapphire::Db::ZoneDbConnection::doPrepareStatements() CONNECTION_BOTH ); prepareStatement( HOUSING_HOUSE_UP, - "UPDATE house SET BuildTime = ?, Aetheryte = ?, Comment = ?, HouseName = ?, Endorsements = ?, HousePartModels = ?, HousePartColours = ?, HouseInteriorModels = ? WHERE HouseId = ?;", + "UPDATE house SET BuildTime = ?, Aetheryte = ?, Comment = ?, HouseName = ?, Endorsements = ? WHERE HouseId = ?;", CONNECTION_BOTH ); prepareStatement( LAND_INV_SEL_ALL, diff --git a/src/world/Territory/House.cpp b/src/world/Territory/House.cpp index b4be2e63..404f9f47 100644 --- a/src/world/Territory/House.cpp +++ b/src/world/Territory/House.cpp @@ -21,47 +21,7 @@ Sapphire::House::House( uint32_t houseId, uint32_t landSetId, Common::LandIdent 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_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_houseModelsCache[ 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_houseInteriorModels[ i ] = interiorModels[ i ]; -// } -// } + } Sapphire::House::~House() = default; @@ -70,10 +30,9 @@ void Sapphire::House::updateHouseDb() { auto pDB = g_fw.get< Db::DbWorkerPool< Db::ZoneDbConnection > >(); - // BuildTime = 1, Aetheryte = 2, Comment = 3, HouseName = 4, Endorsements = 5, - // HousePartModels = 6, HousePartColours = 7, HouseId = 8 + // BuildTime = 1, Aetheryte = 2, Comment = 3, HouseName = 4, Endorsements = 5, HouseId = 6 auto stmt = pDB->getPreparedStatement( Db::HOUSING_HOUSE_UP ); - stmt->setUInt( 9, m_houseId ); + stmt->setUInt( 6, m_houseId ); stmt->setInt64( 1, m_buildTime ); stmt->setInt( 2, 0 ); @@ -83,35 +42,6 @@ void Sapphire::House::updateHouseDb() stmt->setUInt64( 5, 0 ); - std::vector< uint32_t > models; - std::vector< uint8_t > colours; - - for( auto i = 0; i < 8; i++ ) - { - auto& part = m_houseModelsCache[ i ]; - models.push_back( part.first ); - colours.push_back( part.second ); - } - - // todo: this is shit - std::vector< uint8_t > tmpModels( models.size() * 4 ); - memcpy( tmpModels.data(), models.data(), tmpModels.size() ); - - stmt->setBinary( 6, tmpModels ); - stmt->setBinary( 7, colours ); - - models.clear(); - - for( auto i = 0; i < 10; i++ ) - { - models.push_back( m_houseInteriorModels[ i ] ); - } - - std::vector< uint8_t > tmp2Models( models.size() * 4 ); - memcpy( tmp2Models.data(), models.data(), tmp2Models.size() ); - - stmt->setBinary( 8, tmp2Models ); - pDB->execute( stmt ); } From f774e754f2ccd07da3ba0b091ffccddef4d5b494 Mon Sep 17 00:00:00 2001 From: Adam <893184+NotAdam@users.noreply.github.com> Date: Sat, 22 Dec 2018 17:54:56 +1100 Subject: [PATCH 10/10] fix autism --- src/world/Manager/HousingMgr.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/world/Manager/HousingMgr.cpp b/src/world/Manager/HousingMgr.cpp index 1395ba9a..50138589 100644 --- a/src/world/Manager/HousingMgr.cpp +++ b/src/world/Manager/HousingMgr.cpp @@ -659,7 +659,7 @@ Sapphire::World::Manager::HousingMgr::ContainerIdToContainerMap& { auto u64ident = *reinterpret_cast< uint64_t* >( &ident ); - getEstateInventory( u64ident ); + return getEstateInventory( u64ident ); } void Sapphire::World::Manager::HousingMgr::updateHouseModels( Sapphire::HousePtr house ) @@ -692,4 +692,4 @@ void Sapphire::World::Manager::HousingMgr::updateHouseModels( Sapphire::HousePtr house->setHouseInteriorPart( static_cast< Common::HousingInteriorSlot >( item.first ), getItemData( item.second->getId() ) ); } } -} \ No newline at end of file +}