From 419a61f8ff1bbf0df160c23a9ed857188856027a Mon Sep 17 00:00:00 2001 From: NotAdam Date: Fri, 21 Dec 2018 22:08:05 +1100 Subject: [PATCH 1/6] Move land/house to use LandIdent instead of storing terri/plot/ward --- src/common/Database/ZoneDbConnection.cpp | 8 +++ src/common/Database/ZoneDbConnection.h | 5 ++ src/world/Actor/Player.cpp | 3 +- src/world/Manager/HousingMgr.cpp | 6 +- src/world/Territory/House.cpp | 22 ++----- src/world/Territory/House.h | 10 +-- src/world/Territory/Land.cpp | 81 ++++++++++-------------- src/world/Territory/Land.h | 13 ++-- 8 files changed, 64 insertions(+), 84 deletions(-) diff --git a/src/common/Database/ZoneDbConnection.cpp b/src/common/Database/ZoneDbConnection.cpp index 25b8e037..c6902bf4 100644 --- a/src/common/Database/ZoneDbConnection.cpp +++ b/src/common/Database/ZoneDbConnection.cpp @@ -200,6 +200,14 @@ void Sapphire::Db::ZoneDbConnection::doPrepareStatements() "UPDATE house SET BuildTime = ?, Aetheryte = ?, Comment = ?, HouseName = ?, Endorsements = ?, HousePartModels = ?, HousePartColours = ?, HouseInteriorModels = ? WHERE HouseId = ?;", CONNECTION_BOTH ); + prepareStatement( LAND_INV_SEL_ALL, + "SELECT LandIdent, ContainerId, ItemId, SlotId FROM houseiteminventory;", + CONNECTION_BOTH ); + + prepareStatement( LAND_INV_SEL_HOUSE, + "SELECT LandIdent, ContainerId, ItemId, SlotId FROM houseiteminventory WHERE LandIdent = ?", + CONNECTION_BOTH ); + /*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 df8dfdf1..6f404167 100644 --- a/src/common/Database/ZoneDbConnection.h +++ b/src/common/Database/ZoneDbConnection.h @@ -85,6 +85,11 @@ namespace Sapphire::Db HOUSING_HOUSE_UP, HOUSING_HOUSE_DEL, + LAND_INV_SEL_ALL, + LAND_INV_SEL_HOUSE, + LAND_INV_DEL, + LAND_INV_UP, + MAX_STATEMENTS }; diff --git a/src/world/Actor/Player.cpp b/src/world/Actor/Player.cpp index ead5d2d4..8b94b238 100644 --- a/src/world/Actor/Player.cpp +++ b/src/world/Actor/Player.cpp @@ -1618,7 +1618,8 @@ void Sapphire::Entity::Player::sendZonePackets() state |= HasAetheryte; } - setLandFlags( LandFlagsSlot::Private, state, pLand->getLandId(), pLand->getWardNum(), pLand->getTerritoryTypeId() ); + auto ident = pLand->getLandIdent(); + setLandFlags( LandFlagsSlot::Private, state, ident.landId, ident.wardNum, ident.territoryTypeId ); } sendLandFlags(); diff --git a/src/world/Manager/HousingMgr.cpp b/src/world/Manager/HousingMgr.cpp index 539bd634..02efb7de 100644 --- a/src/world/Manager/HousingMgr.cpp +++ b/src/world/Manager/HousingMgr.cpp @@ -222,7 +222,7 @@ bool Sapphire::World::Manager::HousingMgr::relinquishLand( Entity::Player& playe player.sendLandFlagsSlot( LandFlagsSlot::Private ); auto screenMsgPkt2 = makeActorControl143( player.getId(), ActorControl::LogMsg, 3351, 0x1AA, - pLand->getWardNum() + 1, plot + 1 ); + pLand->getLandIdent().wardNum + 1, plot + 1 ); player.queuePacket( screenMsgPkt2 ); pHousing->sendLandUpdate( plot ); @@ -351,7 +351,9 @@ void Sapphire::World::Manager::HousingMgr::buildPresetEstate( Entity::Player& pl player.eventStart( player.getId(), 0x000B0095, Event::EventHandler::EventType::Housing, 1, 1 ); player.playScene( 0x000B0095, 0, SET_BASE | HIDE_HOTBAR , 0, 1, plotNum, nullptr ); - player.setLandFlags( LandFlagsSlot::Private, EstateBuilt, pLand->getLandId(), pLand->getWardNum(), pLand->getTerritoryTypeId() ); + auto ident = pLand->getLandIdent(); + + player.setLandFlags( LandFlagsSlot::Private, EstateBuilt, ident.landId, ident.wardNum, ident.territoryTypeId ); player.sendLandFlagsSlot( LandFlagsSlot::Private ); hZone->registerHouseEntranceEObj( plotNum ); diff --git a/src/world/Territory/House.cpp b/src/world/Territory/House.cpp index d5b20ef2..820a7b1e 100644 --- a/src/world/Territory/House.cpp +++ b/src/world/Territory/House.cpp @@ -13,12 +13,10 @@ extern Sapphire::Framework g_fw; -Sapphire::House::House( uint32_t houseId, uint32_t landSetId, uint8_t landId, uint8_t wardNum, uint16_t territoryTypeId ) : +Sapphire::House::House( uint32_t houseId, uint32_t landSetId, Common::LandIdent ident ) : m_houseId( houseId ), m_landSetId( landSetId ), - m_landId( landId ), - m_wardNum( wardNum ), - m_territoryTypeId( territoryTypeId ) + m_landIdent( ident ) { auto pDB = g_fw.get< Db::DbWorkerPool< Db::ZoneDbConnection > >(); @@ -37,7 +35,7 @@ Sapphire::House::House( uint32_t houseId, uint32_t landSetId, uint8_t landId, ui pDB->execute( stmt ); // todo: make this nicer/configurable? - m_houseName = "Estate #" + std::to_string( landId + 1 ); + m_houseName = "Estate #" + std::to_string( m_landIdent.landId + 1 ); } else { @@ -121,19 +119,9 @@ uint32_t Sapphire::House::getLandSetId() const return m_landSetId; } -uint8_t Sapphire::House::getLandId() const +Sapphire::Common::LandIdent Sapphire::House::getLandIdent() const { - return m_landId; -} - -uint8_t Sapphire::House::getWardNum() const -{ - return m_wardNum; -} - -uint16_t Sapphire::House::getTerritoryTypeId() const -{ - return m_territoryTypeId; + return m_landIdent; } uint32_t Sapphire::House::getHouseId() const diff --git a/src/world/Territory/House.h b/src/world/Territory/House.h index 183afd1f..f228874b 100644 --- a/src/world/Territory/House.h +++ b/src/world/Territory/House.h @@ -12,7 +12,7 @@ namespace Sapphire class House { public: - House( uint32_t houseId, uint32_t landSetId, uint8_t landId, uint8_t wardNum, uint16_t territoryTypeId ); + House( uint32_t houseId, uint32_t landSetId, Common::LandIdent ident ); virtual ~House(); using HousePart = std::pair< uint32_t, uint8_t >; @@ -20,9 +20,7 @@ namespace Sapphire //gerneral uint32_t getLandSetId() const; - uint8_t getLandId() const; - uint8_t getWardNum() const; - uint16_t getTerritoryTypeId() const; + Common::LandIdent getLandIdent() const; uint32_t getHouseId() const; const std::string& getHouseName() const; @@ -45,9 +43,7 @@ namespace Sapphire private: uint32_t m_landSetId; - uint8_t m_landId; - uint8_t m_wardNum; - uint16_t m_territoryTypeId; + Common::LandIdent m_landIdent; uint32_t m_houseId; uint64_t m_buildTime; diff --git a/src/world/Territory/Land.cpp b/src/world/Territory/Land.cpp index 20035793..cb43cad7 100644 --- a/src/world/Territory/Land.cpp +++ b/src/world/Territory/Land.cpp @@ -28,9 +28,6 @@ using namespace Sapphire::Common; Sapphire::Land::Land( uint16_t territoryTypeId, uint8_t wardNum, uint8_t landId, uint32_t landSetId, Sapphire::Data::HousingLandSetPtr info ) : - m_territoryTypeId( territoryTypeId ), - m_wardNum( wardNum ), - m_landId( landId ), m_currentPrice( 0 ), m_minPrice( 0 ), m_nextDrop( static_cast< uint32_t >( Util::getTimeSeconds() ) + 21600 ), @@ -45,52 +42,42 @@ Sapphire::Land::Land( uint16_t territoryTypeId, uint8_t wardNum, uint8_t landId, { memset( &m_tag, 0x00, 3 ); + m_landIdent.landId = landId; + m_landIdent.territoryTypeId = territoryTypeId; + m_landIdent.wardNum = wardNum; + m_landIdent.worldId = 67; // todo: fix this + init(); } -Sapphire::Land::~Land() -{ - -} +Sapphire::Land::~Land() = default; void Sapphire::Land::init() { + // todo: move this loading logic outside of land and fetch all houses in 1 query auto pDb = g_fw.get< Db::DbWorkerPool< Db::ZoneDbConnection > >(); auto res = pDb->query( "SELECT * FROM land WHERE LandSetId = " + std::to_string( m_landSetId ) + " " - "AND LandId = " + std::to_string( m_landId ) ); - if( !res->next() ) - { - pDb->directExecute( "INSERT INTO land ( landsetid, landid, type, size, status, landprice, UpdateTime, OwnerId, HouseId ) " - "VALUES ( " + std::to_string( m_landSetId ) + "," + std::to_string( m_landId ) + "," - + std::to_string( static_cast< uint8_t >( m_type ) ) + "," - + std::to_string( m_landInfo->plotSize[ m_landId ] ) + "," - + " 1, " + std::to_string( m_landInfo->initialPrice[ m_landId ] ) + ", 0, 0, 0 );" ); + "AND LandId = " + std::to_string( m_landIdent.landId ) ); - m_currentPrice = m_landInfo->initialPrice[ m_landId ]; - m_minPrice = m_landInfo->minPrice[ m_landId ]; - m_size = m_landInfo->plotSize[ m_landId ]; - m_state = HouseState::forSale; - } - else - { - m_type = static_cast< Common::LandType >( res->getUInt( "Type" ) ); - m_size = res->getUInt( "Size" ); - m_state = res->getUInt( "Status" ); - m_currentPrice = res->getUInt( "LandPrice" ); - m_ownerId = res->getUInt64( "OwnerId" ); - m_minPrice = m_landInfo->minPrice[ m_landId ]; - m_maxPrice = m_landInfo->initialPrice[ m_landId ]; + // we're not going to be building the land table at runtime + assert( res->next() ); - auto houseId = res->getUInt( "HouseId" ); + m_type = static_cast< Common::LandType >( res->getUInt( "Type" ) ); + m_size = res->getUInt( "Size" ); + m_state = res->getUInt( "Status" ); + m_currentPrice = res->getUInt( "LandPrice" ); + m_ownerId = res->getUInt64( "OwnerId" ); + m_minPrice = m_landInfo->minPrice[ m_landIdent.landId ]; + m_maxPrice = m_landInfo->initialPrice[ m_landIdent.landId ]; - // fetch the house if we have one for this land - if( houseId > 0 ) - m_pHouse = make_House( houseId, m_landSetId, m_landId, m_wardNum, m_territoryTypeId ); + auto houseId = res->getUInt( "HouseId" ); - } + // 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 >( getTerritoryTypeId(), getLandId() ); + auto info = pExdData->get< Sapphire::Data::HousingMapMarkerInfo >( m_landIdent.territoryTypeId, m_landIdent.landId ); if( info ) { m_mapMarkerPosition.x = info->x; @@ -127,11 +114,17 @@ void Sapphire::Land::init() 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 ); } void Sapphire::Land::loadItemContainerContents() { + } uint32_t Sapphire::Land::convertItemIdToHousingItemId( uint32_t itemId ) @@ -192,19 +185,9 @@ uint32_t Sapphire::Land::getLandSetId() const return m_landSetId; } -uint8_t Sapphire::Land::getWardNum() const +Sapphire::Common::LandIdent Sapphire::Land::getLandIdent() const { - return m_wardNum; -} - -uint8_t Sapphire::Land::getLandId() const -{ - return m_landId; -} - -uint16_t Sapphire::Land::getTerritoryTypeId() const -{ - return m_territoryTypeId; + return m_landIdent; } Sapphire::HousePtr Sapphire::Land::getHouse() const @@ -292,7 +275,7 @@ void Sapphire::Land::updateLandDb() + ", HouseId = " + std::to_string( houseId ) + ", Type = " + std::to_string( static_cast< uint32_t >( m_type ) ) //TODO: add house id + " WHERE LandSetId = " + std::to_string( m_landSetId ) - + " AND LandId = " + std::to_string( m_landId ) + ";" ); + + " AND LandId = " + std::to_string( m_landIdent.landId ) + ";" ); if( auto house = getHouse() ) house->updateHouseDb(); @@ -338,7 +321,7 @@ 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(), getLandId(), getWardNum(), getTerritoryTypeId() ); + m_pHouse = make_House( newId, getLandSetId(), getLandIdent() ); } diff --git a/src/world/Territory/Land.h b/src/world/Territory/Land.h index a7b73192..3e5b7ae0 100644 --- a/src/world/Territory/Land.h +++ b/src/world/Territory/Land.h @@ -31,12 +31,10 @@ namespace Sapphire uint8_t getState() const; uint8_t getSharing() const; uint32_t getLandSetId() const; - uint8_t getWardNum() const; - uint8_t getLandId() const; - uint16_t getTerritoryTypeId() const; Common::LandType getLandType() const; Sapphire::HousePtr getHouse() const; Common::FFXIVARR_POSITION3 getMapMarkerPosition(); + Common::LandIdent getLandIdent() const; //Free Comapny void setFreeCompany( uint32_t id, uint32_t icon, uint32_t color ); @@ -69,10 +67,9 @@ namespace Sapphire void init(); uint32_t getNextHouseId(); - uint8_t m_wardNum; - uint8_t m_landId; + Common::LandIdent m_landIdent; + uint32_t m_landSetId; - uint16_t m_territoryTypeId; uint8_t m_size; uint8_t m_state; Common::LandType m_type; @@ -90,8 +87,8 @@ namespace Sapphire //item storage LandInventoryMap m_landInventoryMap; - uint32_t m_maxPlacedExternalItems; - uint32_t m_maxPlacedInternalItems; + uint16_t m_maxPlacedExternalItems; + uint16_t m_maxPlacedInternalItems; //price uint32_t m_initPrice; From 1c59eb8f986c50d6e453152105773d6b5285e350 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Fri, 21 Dec 2018 22:23:49 +1100 Subject: [PATCH 2/6] more ident cleanup --- src/world/Actor/Player.cpp | 11 ++-- src/world/Actor/Player.h | 2 +- .../DebugCommand/DebugCommandHandler.cpp | 51 ++++++++++--------- src/world/Manager/HousingMgr.cpp | 11 ++-- 4 files changed, 38 insertions(+), 37 deletions(-) diff --git a/src/world/Actor/Player.cpp b/src/world/Actor/Player.cpp index 8b94b238..49dfdb49 100644 --- a/src/world/Actor/Player.cpp +++ b/src/world/Actor/Player.cpp @@ -1618,8 +1618,7 @@ void Sapphire::Entity::Player::sendZonePackets() state |= HasAetheryte; } - auto ident = pLand->getLandIdent(); - setLandFlags( LandFlagsSlot::Private, state, ident.landId, ident.wardNum, ident.territoryTypeId ); + setLandFlags( LandFlagsSlot::Private, state, pLand->getLandIdent() ); } sendLandFlags(); @@ -1800,12 +1799,10 @@ bool Sapphire::Entity::Player::isOnEnterEventDone() const return m_onEnterEventDone; } -void Sapphire::Entity::Player::setLandFlags( uint8_t flagSlot, uint32_t landFlags, - int16_t landId, int16_t wardNum, int16_t zoneId ) +void Sapphire::Entity::Player::setLandFlags( uint8_t flagSlot, uint32_t landFlags, Common::LandIdent ident ) { - m_landFlags[ flagSlot ].landIdent.landId = landId; - m_landFlags[ flagSlot ].landIdent.wardNum = wardNum; - m_landFlags[ flagSlot ].landIdent.territoryTypeId = zoneId; + m_landFlags[ flagSlot ].landIdent = ident; + // todo: leave this in for now but we really need to handle this world id shit properly m_landFlags[ flagSlot ].landIdent.worldId = 67; m_landFlags[ flagSlot ].landFlags = landFlags; m_landFlags[ flagSlot ].unkown1 = 0; diff --git a/src/world/Actor/Player.h b/src/world/Actor/Player.h index 34ea3204..b0c8b1cf 100644 --- a/src/world/Actor/Player.h +++ b/src/world/Actor/Player.h @@ -765,7 +765,7 @@ namespace Sapphire::Entity // Housing Handling ////////////////////////////////////////////////////////////////////////////////////////////////////// - void setLandFlags( uint8_t permissionSet, uint32_t landFlags, int16_t landId, int16_t wardNum, int16_t zoneId ); + void setLandFlags( uint8_t permissionSet, uint32_t landFlags, Common::LandIdent ident ); void sendLandFlags(); void sendLandFlagsSlot( Common::LandFlagsSlot slot ); diff --git a/src/world/DebugCommand/DebugCommandHandler.cpp b/src/world/DebugCommand/DebugCommandHandler.cpp index 2eaa57ed..b3898656 100644 --- a/src/world/DebugCommand/DebugCommandHandler.cpp +++ b/src/world/DebugCommand/DebugCommandHandler.cpp @@ -1006,29 +1006,34 @@ void Sapphire::DebugCommandHandler::housing( char* data, Entity::Player& player, subCommand = params; } - if( subCommand == "permission" || subCommand == "perm" ) - { - uint8_t permissionSet; - sscanf( params.c_str(), "%hhu", &permissionSet ); - - if ( permissionSet < 5 ) - { - auto pZone = player.getCurrentZone(); - if( pTeriMgr->isHousingTerritory( pZone->getTerritoryTypeId() ) ) - { - auto pHousing = std::dynamic_pointer_cast< HousingZone >( pZone ); - if( pHousing ) - { - player.setLandFlags( permissionSet, 0, pHousing->getLandSetId(), pHousing->getWardNum(), pHousing->getTerritoryTypeId() ); - player.sendLandFlags(); - } - else - player.sendDebug( "You aren't in a housing Zone." ); - } - } - else - player.sendDebug( "PermissionSet out of range." ); - } +// if( subCommand == "permission" || subCommand == "perm" ) +// { +// uint8_t permissionSet; +// sscanf( params.c_str(), "%hhu", &permissionSet ); +// +// if ( permissionSet < 5 ) +// { +// auto pZone = player.getCurrentZone(); +// if( pTeriMgr->isHousingTerritory( pZone->getTerritoryTypeId() ) ) +// { +// auto pHousing = std::dynamic_pointer_cast< HousingZone >( pZone ); +// if( pHousing ) +// { +// // todo: wat? +// Common::LandIdent ident {}; +// ident.wardNum = pHousing->getWardNum(); +// ident.territoryTypeId = pHousing->getTerritoryTypeId(); +// +// player.setLandFlags( permissionSet, 0, pHousing->getLandSetId(), ident ); +// player.sendLandFlags(); +// } +// else +// player.sendDebug( "You aren't in a housing Zone." ); +// } +// } +// else +// player.sendDebug( "PermissionSet out of range." ); +// } else { player.sendDebug( "Unknown sub command." ); diff --git a/src/world/Manager/HousingMgr.cpp b/src/world/Manager/HousingMgr.cpp index 02efb7de..44846d0e 100644 --- a/src/world/Manager/HousingMgr.cpp +++ b/src/world/Manager/HousingMgr.cpp @@ -165,8 +165,7 @@ Sapphire::LandPurchaseResult Sapphire::World::Manager::HousingMgr::purchaseLand( pLand->setState( HouseState::sold ); pLand->setLandType( Common::LandType::Private ); - player.setLandFlags( LandFlagsSlot::Private, 0x00, plot, - pHousing->getWardNum(), pHousing->getTerritoryTypeId() ); + player.setLandFlags( LandFlagsSlot::Private, 0x00, pLand->getLandIdent() ); player.sendLandFlagsSlot( LandFlagsSlot::Private ); @@ -217,7 +216,9 @@ bool Sapphire::World::Manager::HousingMgr::relinquishLand( Entity::Player& playe pLand->setLandType( Common::LandType::none ); pLand->updateLandDb(); - player.setLandFlags( LandFlagsSlot::Private, 0x00, 0xFF, 0xFF, 0xFF ); + Common::LandIdent ident { 0xFF, 0xFF, 0xFF, 0xFF }; + + player.setLandFlags( LandFlagsSlot::Private, 0x00, ident ); player.sendLandFlagsSlot( LandFlagsSlot::Private ); @@ -351,9 +352,7 @@ void Sapphire::World::Manager::HousingMgr::buildPresetEstate( Entity::Player& pl player.eventStart( player.getId(), 0x000B0095, Event::EventHandler::EventType::Housing, 1, 1 ); player.playScene( 0x000B0095, 0, SET_BASE | HIDE_HOTBAR , 0, 1, plotNum, nullptr ); - auto ident = pLand->getLandIdent(); - - player.setLandFlags( LandFlagsSlot::Private, EstateBuilt, ident.landId, ident.wardNum, ident.territoryTypeId ); + player.setLandFlags( LandFlagsSlot::Private, EstateBuilt, pLand->getLandIdent() ); player.sendLandFlagsSlot( LandFlagsSlot::Private ); hZone->registerHouseEntranceEObj( plotNum ); From 14848ee955b3c7a7a50789eaab895753255cc04f Mon Sep 17 00:00:00 2001 From: NotAdam Date: Fri, 21 Dec 2018 23:49:46 +1100 Subject: [PATCH 3/6] partially working inventory loading --- src/common/Database/ZoneDbConnection.cpp | 2 +- src/world/Territory/Land.cpp | 29 ++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/common/Database/ZoneDbConnection.cpp b/src/common/Database/ZoneDbConnection.cpp index c6902bf4..7e3b4e4f 100644 --- a/src/common/Database/ZoneDbConnection.cpp +++ b/src/common/Database/ZoneDbConnection.cpp @@ -206,7 +206,7 @@ void Sapphire::Db::ZoneDbConnection::doPrepareStatements() prepareStatement( LAND_INV_SEL_HOUSE, "SELECT LandIdent, ContainerId, ItemId, SlotId FROM houseiteminventory WHERE LandIdent = ?", - CONNECTION_BOTH ); + CONNECTION_SYNC ); /*prepareStatement( LAND_INS, "INSERT INTO land ( LandSetId ) VALUES ( ? );", diff --git a/src/world/Territory/Land.cpp b/src/world/Territory/Land.cpp index cb43cad7..ce2eca89 100644 --- a/src/world/Territory/Land.cpp +++ b/src/world/Territory/Land.cpp @@ -16,6 +16,7 @@ #include "Actor/Player.h" #include "Inventory/ItemContainer.h" #include "Inventory/Item.h" +#include "Inventory/ItemUtil.h" #include "Forwards.h" #include "Land.h" @@ -72,6 +73,8 @@ void Sapphire::Land::init() auto houseId = res->getUInt( "HouseId" ); + res.reset(); + // fetch the house if we have one for this land if( houseId > 0 ) m_pHouse = make_House( houseId, m_landSetId, getLandIdent() ); @@ -119,11 +122,37 @@ void Sapphire::Land::init() // 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( "SELECT LandIdent, ContainerId, ItemId, SlotId FROM houseiteminventory WHERE LandIdent = " + std::to_string( ident ) ); + + while( res->next() ) + { + auto containerId = res->getUInt( "ContainerId" ); + auto itemId = res->getUInt64( "ItemId" ); + auto slotId = res->getUInt( "SlotId" ); + + auto container = m_landInventoryMap[ containerId ]; + + auto item = Sapphire::Items::Util::loadItem( itemId ); + if( item ) + container->setItem( slotId, item ); + } } From 0d66bdd27002f85f7ea9b34240b63eae37be1a58 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sat, 22 Dec 2018 00:48:43 +1100 Subject: [PATCH 4/6] batch land sql queries to 1 per ward instead of 60 --- src/common/Database/ZoneDbConnection.cpp | 4 ++ src/common/Database/ZoneDbConnection.h | 1 + src/world/Territory/HousingZone.cpp | 56 +++++++++++++++++------- src/world/Territory/HousingZone.h | 11 +++++ src/world/Territory/Land.cpp | 30 ++++--------- src/world/Territory/Land.h | 2 +- 6 files changed, 66 insertions(+), 38 deletions(-) diff --git a/src/common/Database/ZoneDbConnection.cpp b/src/common/Database/ZoneDbConnection.cpp index 7e3b4e4f..b35ecf79 100644 --- a/src/common/Database/ZoneDbConnection.cpp +++ b/src/common/Database/ZoneDbConnection.cpp @@ -208,6 +208,10 @@ void Sapphire::Db::ZoneDbConnection::doPrepareStatements() "SELECT LandIdent, ContainerId, ItemId, SlotId FROM houseiteminventory WHERE LandIdent = ?", CONNECTION_SYNC ); + prepareStatement( LANDSET_SEL, + "SELECT * FROM land WHERE LandSetId = ?;", + 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 6f404167..2cbfac6e 100644 --- a/src/common/Database/ZoneDbConnection.h +++ b/src/common/Database/ZoneDbConnection.h @@ -81,6 +81,7 @@ namespace Sapphire::Db LAND_INS, LAND_SEL, LAND_UP, + LANDSET_SEL, HOUSING_HOUSE_INS, HOUSING_HOUSE_UP, HOUSING_HOUSE_DEL, diff --git a/src/world/Territory/HousingZone.cpp b/src/world/Territory/HousingZone.cpp index 5f47d22f..17fdfd3b 100644 --- a/src/world/Territory/HousingZone.cpp +++ b/src/world/Territory/HousingZone.cpp @@ -42,12 +42,15 @@ bool Sapphire::HousingZone::init() { auto pDb = g_fw.get< Db::DbWorkerPool< Db::ZoneDbConnection > >(); - auto res = pDb->query( "SELECT * FROM landset WHERE landsetid = " + std::to_string( m_landSetId ) ); - if( !res->next() ) { - pDb->directExecute( "INSERT INTO landset ( landsetid ) VALUES ( " + std::to_string( m_landSetId ) + " );" ); + auto res = pDb->query( "SELECT * FROM landset WHERE landsetid = " + std::to_string( m_landSetId ) ); + if( !res->next() ) + { + pDb->directExecute( "INSERT INTO landset ( landsetid ) VALUES ( " + std::to_string( m_landSetId ) + " );" ); + } } + int housingIndex; if( m_territoryTypeId == 339 ) housingIndex = 0; @@ -61,25 +64,46 @@ bool Sapphire::HousingZone::init() auto pExdData = g_fw.get< Data::ExdDataGenerated >(); auto info = pExdData->get< Sapphire::Data::HousingLandSet >( housingIndex ); - uint32_t landId; - for( landId = 0; landId < 60; landId++ ) - { - auto pLand = make_Land( m_territoryTypeId, getWardNum(), landId, m_landSetId, info ); - m_landPtrMap[ landId ] = pLand; + auto stmt = pDb->getPreparedStatement( Db::LANDSET_SEL ); + stmt->setUInt64( 1, m_landSetId ); + auto res = pDb->query( stmt ); - if( auto house = pLand->getHouse() ) - { - registerHouseEntranceEObj( landId << 8 ); - } + std::vector< QueuedLandInit > landInit; + + while( res->next() ) + { + + 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 ); + } + + // nuke current query connection so the queries still in land don't fail + res.reset(); + + // spawn land + for( auto& init : landInit ) + { + 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 ); + + m_landPtrMap[ init.m_landId ] = land; + + if( init.m_houseId > 0 ) + registerHouseEntranceEObj( init.m_landId ); } return true; } -Sapphire::HousingZone::~HousingZone() -{ - -} +Sapphire::HousingZone::~HousingZone() = default; void Sapphire::HousingZone::onPlayerZoneIn( Entity::Player& player ) { diff --git a/src/world/Territory/HousingZone.h b/src/world/Territory/HousingZone.h index 3868f31a..63fcfb4b 100644 --- a/src/world/Territory/HousingZone.h +++ b/src/world/Territory/HousingZone.h @@ -53,6 +53,17 @@ 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; diff --git a/src/world/Territory/Land.cpp b/src/world/Territory/Land.cpp index ce2eca89..a9e3781c 100644 --- a/src/world/Territory/Land.cpp +++ b/src/world/Territory/Land.cpp @@ -48,32 +48,20 @@ Sapphire::Land::Land( uint16_t territoryTypeId, uint8_t wardNum, uint8_t landId, m_landIdent.wardNum = wardNum; m_landIdent.worldId = 67; // todo: fix this - init(); + m_minPrice = m_landInfo->minPrice[ m_landIdent.landId ]; + m_maxPrice = m_landInfo->initialPrice[ m_landIdent.landId ]; } Sapphire::Land::~Land() = default; -void Sapphire::Land::init() +void Sapphire::Land::init( Common::LandType type, uint8_t size, uint8_t state, uint32_t currentPrice, uint64_t ownerId, uint64_t houseId ) { - // todo: move this loading logic outside of land and fetch all houses in 1 query - auto pDb = g_fw.get< Db::DbWorkerPool< Db::ZoneDbConnection > >(); - auto res = pDb->query( "SELECT * FROM land WHERE LandSetId = " + std::to_string( m_landSetId ) + " " - "AND LandId = " + std::to_string( m_landIdent.landId ) ); - // we're not going to be building the land table at runtime - assert( res->next() ); - - m_type = static_cast< Common::LandType >( res->getUInt( "Type" ) ); - m_size = res->getUInt( "Size" ); - m_state = res->getUInt( "Status" ); - m_currentPrice = res->getUInt( "LandPrice" ); - m_ownerId = res->getUInt64( "OwnerId" ); - m_minPrice = m_landInfo->minPrice[ m_landIdent.landId ]; - m_maxPrice = m_landInfo->initialPrice[ m_landIdent.landId ]; - - auto houseId = res->getUInt( "HouseId" ); - - res.reset(); + m_type = type; + m_size = size; + m_state = state; + m_currentPrice = currentPrice; + m_ownerId = ownerId; // fetch the house if we have one for this land if( houseId > 0 ) @@ -123,7 +111,7 @@ void Sapphire::Land::init() setupContainer( InventoryType::HousingInteriorPlacedItems1, m_maxPlacedInternalItems ); setupContainer( InventoryType::HousingInteriorStoreroom1, m_maxPlacedInternalItems ); - loadItemContainerContents(); +// loadItemContainerContents(); } void Sapphire::Land::loadItemContainerContents() diff --git a/src/world/Territory/Land.h b/src/world/Territory/Land.h index 3e5b7ae0..bf8a834c 100644 --- a/src/world/Territory/Land.h +++ b/src/world/Territory/Land.h @@ -17,6 +17,7 @@ namespace Sapphire Land( uint16_t zoneId, uint8_t wardNum, uint8_t landId, uint32_t landSetId, Sapphire::Data::HousingLandSetPtr info ); virtual ~Land(); + void init( Common::LandType type, uint8_t size, uint8_t state, uint32_t currentPrice, uint64_t ownerId, uint64_t houseId ); using LandInventoryMap = std::unordered_map< uint16_t, ItemContainerPtr >; @@ -64,7 +65,6 @@ namespace Sapphire private: uint32_t convertItemIdToHousingItemId( uint32_t itemId ); - void init(); uint32_t getNextHouseId(); Common::LandIdent m_landIdent; From 6da9ae57d264163e3fc35c13bc8f5242a4d7c2db Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sat, 22 Dec 2018 01:00:31 +1100 Subject: [PATCH 5/6] fix shitty inventory impl so it works a bit more than before --- src/world/Territory/Land.cpp | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/src/world/Territory/Land.cpp b/src/world/Territory/Land.cpp index a9e3781c..149ef724 100644 --- a/src/world/Territory/Land.cpp +++ b/src/world/Territory/Land.cpp @@ -56,7 +56,6 @@ Sapphire::Land::~Land() = default; void Sapphire::Land::init( Common::LandType type, uint8_t size, uint8_t state, uint32_t currentPrice, uint64_t ownerId, uint64_t houseId ) { - m_type = type; m_size = size; m_state = state; @@ -111,7 +110,7 @@ void Sapphire::Land::init( Common::LandType type, uint8_t size, uint8_t state, u setupContainer( InventoryType::HousingInteriorPlacedItems1, m_maxPlacedInternalItems ); setupContainer( InventoryType::HousingInteriorStoreroom1, m_maxPlacedInternalItems ); -// loadItemContainerContents(); + loadItemContainerContents(); } void Sapphire::Land::loadItemContainerContents() @@ -120,14 +119,16 @@ void Sapphire::Land::loadItemContainerContents() return; auto ident = *reinterpret_cast< uint64_t* >( &m_landIdent ); - g_fw.get< Sapphire::Logger >()->debug( "Loading housing inventory for ident:" + std::to_string( ident ) ); + 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 stmt = pDB->getPreparedStatement( Db::LAND_INV_SEL_HOUSE ); + stmt->setUInt64( 1, ident ); - auto res = pDB->query( "SELECT LandIdent, ContainerId, ItemId, SlotId FROM houseiteminventory WHERE LandIdent = " + std::to_string( ident ) ); + auto res = pDB->query( stmt ); + + std::unordered_map< uint16_t, std::vector< std::pair< uint16_t, uint32_t > > > items; while( res->next() ) { @@ -135,13 +136,22 @@ void Sapphire::Land::loadItemContainerContents() auto itemId = res->getUInt64( "ItemId" ); auto slotId = res->getUInt( "SlotId" ); - auto container = m_landInventoryMap[ containerId ]; - - auto item = Sapphire::Items::Util::loadItem( itemId ); - if( item ) - container->setItem( slotId, item ); + items[ containerId ].push_back( std::make_pair( slotId, itemId ) ); } + res.reset(); + + for( auto it = items.begin(); it != items.end(); it++ ) + { + auto container = m_landInventoryMap[ it->first ]; + + 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 ); + } + } } uint32_t Sapphire::Land::convertItemIdToHousingItemId( uint32_t itemId ) From 74f35ea2ea294fc8faff1e3b4ce859eaecbd7c38 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sat, 22 Dec 2018 01:02:42 +1100 Subject: [PATCH 6/6] a little reminder --- src/world/Territory/Land.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/world/Territory/Land.cpp b/src/world/Territory/Land.cpp index 149ef724..d575cfea 100644 --- a/src/world/Territory/Land.cpp +++ b/src/world/Territory/Land.cpp @@ -145,6 +145,7 @@ void Sapphire::Land::loadItemContainerContents() { 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 );