From d6a6de6f77ac46c15cc99264becfa0ba859738f8 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Thu, 20 Dec 2018 20:41:16 +1100 Subject: [PATCH 01/16] handle inventory packet sequencing properly for items & containers --- bin/sql/schema/schema.sql | 7 ++++--- src/world/Actor/Player.h | 4 ++++ src/world/Actor/PlayerInventory.cpp | 12 +++++++----- src/world/Manager/HousingMgr.cpp | 8 ++++++++ src/world/Manager/InventoryMgr.cpp | 4 ++-- src/world/Manager/InventoryMgr.h | 3 +-- 6 files changed, 26 insertions(+), 12 deletions(-) diff --git a/bin/sql/schema/schema.sql b/bin/sql/schema/schema.sql index b87b2a9b..185d0225 100644 --- a/bin/sql/schema/schema.sql +++ b/bin/sql/schema/schema.sql @@ -530,9 +530,10 @@ CREATE TABLE `landset` ( ) ENGINE=InnoDB DEFAULT CHARSET=latin1; CREATE TABLE `houseiteminventory` ( - `landIdent` BIGINT(20) UNSIGNED NOT NULL, - `containerId` INT(10) UNSIGNED NOT NULL, - `itemId` INT(20) NOT NULL, + `LandIdent` BIGINT(20) UNSIGNED NOT NULL, + `ContainerId` INT(10) UNSIGNED NOT NULL, + `ItemId` INT(20) NOT NULL, + `SlotId` INT(10) UNSIGNED NOT NULL, INDEX `landIdent` (`landIdent`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; diff --git a/src/world/Actor/Player.h b/src/world/Actor/Player.h index 8532e21a..34ea3204 100644 --- a/src/world/Actor/Player.h +++ b/src/world/Actor/Player.h @@ -910,6 +910,8 @@ namespace Sapphire::Entity bool isObtainable( uint32_t catalogId, uint8_t quantity ); + uint32_t getNextInventorySequence(); + void send(); uint8_t getFreeSlotsInBags(); @@ -939,6 +941,8 @@ namespace Sapphire::Entity bool m_onEnterEventDone; + uint32_t m_inventorySequence; + private: using InventoryMap = std::map< uint16_t, Sapphire::ItemContainerPtr >; diff --git a/src/world/Actor/PlayerInventory.cpp b/src/world/Actor/PlayerInventory.cpp index 365bd622..67545381 100644 --- a/src/world/Actor/PlayerInventory.cpp +++ b/src/world/Actor/PlayerInventory.cpp @@ -357,14 +357,11 @@ void Sapphire::Entity::Player::removeCrystal( Common::CrystalType type, uint32_t void Sapphire::Entity::Player::sendInventory() { - InventoryMap::iterator it; - auto pInvMgr = g_fw.get< World::Manager::InventoryMgr >(); - uint32_t count = 0; - for( it = m_storageMap.begin(); it != m_storageMap.end(); ++it, ++count ) + for( auto it = m_storageMap.begin(); it != m_storageMap.end(); ++it ) { - pInvMgr->sendInventoryContainer( *this, it->second, count ); + pInvMgr->sendInventoryContainer( *this, it->second ); } } @@ -867,3 +864,8 @@ bool Sapphire::Entity::Player::collectHandInItems( std::vector< uint32_t > itemI return true; } + +uint32_t Sapphire::Entity::Player::getNextInventorySequence() +{ + return m_inventorySequence++; +} diff --git a/src/world/Manager/HousingMgr.cpp b/src/world/Manager/HousingMgr.cpp index 2a999e95..80fcbf8c 100644 --- a/src/world/Manager/HousingMgr.cpp +++ b/src/world/Manager/HousingMgr.cpp @@ -24,6 +24,7 @@ #include "Framework.h" #include "ServerMgr.h" #include "Territory/House.h" +#include "InventoryMgr.h" using namespace Sapphire::Common; using namespace Sapphire::Network; @@ -508,5 +509,12 @@ void Sapphire::World::Manager::HousingMgr::sendHousingInventory( Entity::Player& if( targetLand->getOwnerId() != player.getId() ) return; + auto container = targetLand->getItemContainer( inventoryType ); + if( !container ) + return; + player.sendDebug( "got inventory for plot: " + targetLand->getHouse()->getHouseName() ); + + auto invMgr = g_fw.get< Manager::InventoryMgr >(); + invMgr->sendInventoryContainer( player, container ); } \ No newline at end of file diff --git a/src/world/Manager/InventoryMgr.cpp b/src/world/Manager/InventoryMgr.cpp index 8ce40ffe..6529d617 100644 --- a/src/world/Manager/InventoryMgr.cpp +++ b/src/world/Manager/InventoryMgr.cpp @@ -10,9 +10,9 @@ using namespace Sapphire::Network::Packets; void Sapphire::World::Manager::InventoryMgr::sendInventoryContainer( Sapphire::Entity::Player& player, - Sapphire::ItemContainerPtr container, - uint32_t sequence ) + Sapphire::ItemContainerPtr container ) { + auto sequence = player.getNextInventorySequence(); auto pMap = container->getItemMap(); for( auto itM = pMap.begin(); itM != pMap.end(); ++itM ) diff --git a/src/world/Manager/InventoryMgr.h b/src/world/Manager/InventoryMgr.h index 55869850..26fae576 100644 --- a/src/world/Manager/InventoryMgr.h +++ b/src/world/Manager/InventoryMgr.h @@ -9,8 +9,7 @@ namespace Sapphire::World::Manager class InventoryMgr { public: - void sendInventoryContainer( Sapphire::Entity::Player& player, Sapphire::ItemContainerPtr container, - uint32_t sequence = 0 ); + void sendInventoryContainer( Sapphire::Entity::Player& player, Sapphire::ItemContainerPtr container ); }; } From 8da5ae47dbf4a84c2f72a19e8d9aeac6cbb72580 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Thu, 20 Dec 2018 21:52:18 +1100 Subject: [PATCH 02/16] correctly send exterior placed items/storeroom inventories --- src/common/Common.h | 32 ++++++++++++++++--- src/common/Network/CommonActorControl.h | 1 + .../Network/Handlers/ClientTriggerHandler.cpp | 12 ++++--- src/world/Territory/Land.cpp | 21 +++++++++--- src/world/Territory/Land.h | 1 + 5 files changed, 54 insertions(+), 13 deletions(-) diff --git a/src/common/Common.h b/src/common/Common.h index 14de2012..796f01eb 100644 --- a/src/common/Common.h +++ b/src/common/Common.h @@ -222,10 +222,34 @@ namespace Sapphire::Common FreeCompanyGil = 22000, FreeCompanyCrystal = 22001, - HousingExternalAppearance = 25000, - HousingOutdoorItemStoreroom = 25001, - HousingInternalAppearance = 25002, - HousingIndoorItemStoreroom = 25003, + // housing interior containers + HousingInteriorAppearance = 25002, + + // 50 in each container max + HousingInteriorPlacedItems1 = 25003, + HousingInteriorPlacedItems2 = 25004, + HousingInteriorPlacedItems3 = 25005, + HousingInteriorPlacedItems4 = 25006, + HousingInteriorPlacedItems5 = 25007, + HousingInteriorPlacedItems6 = 25008, + + // 50 max per container? + HousingInteriorStoreroom1 = 27001, + HousingInteriorStoreroom2 = 27002, + HousingInteriorStoreroom3 = 27003, + HousingInteriorStoreroom4 = 27004, + HousingInteriorStoreroom5 = 27005, + HousingInteriorStoreroom6 = 27006, + HousingInteriorStoreroom7 = 27007, + HousingInteriorStoreroom8 = 27008, + + + // housing exterior containers + HousingOutdoorPlacedItems = 25001, + HousingOutdoorAppearance = 25000, + HousingOutdoorStoreroom = 27000, + + }; enum ContainerType : uint16_t diff --git a/src/common/Network/CommonActorControl.h b/src/common/Network/CommonActorControl.h index 1f55a52b..0f0eda35 100644 --- a/src/common/Network/CommonActorControl.h +++ b/src/common/Network/CommonActorControl.h @@ -304,6 +304,7 @@ enum ActorControlType : uint16_t AchievementCritReq = 0x3E8, AchievementList = 0x3E9, + SetEstateLightingLevel = 0x40B, // param1 = light level 0 - 5 maps to UI val 5-0 RequestHousingBuildPreset = 0x44C, RequestEstateHallRemoval = 0x44F, RequestBuildPreset = 0x450, // no idea what this is, it gets sent with BuildPresetHandler and has the plot id in param1 diff --git a/src/world/Network/Handlers/ClientTriggerHandler.cpp b/src/world/Network/Handlers/ClientTriggerHandler.cpp index 40add015..de7528c2 100644 --- a/src/world/Network/Handlers/ClientTriggerHandler.cpp +++ b/src/world/Network/Handlers/ClientTriggerHandler.cpp @@ -423,16 +423,18 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( const Packets::FFX } case ClientTriggerType::RequestLandInventory: { - if( param2 != 1 ) - return; - uint8_t plot = ( param12 & 0xFF ); + auto housingMgr = g_fw.get< HousingMgr >(); if( !housingMgr ) break; - housingMgr->sendHousingInventory( player, Common::InventoryType::HousingOutdoorItemStoreroom, plot ); + uint16_t inventoryType = Common::InventoryType::HousingOutdoorPlacedItems; + if( param2 == 1 ) + inventoryType = Common::InventoryType::HousingOutdoorStoreroom; + + housingMgr->sendHousingInventory( player, inventoryType, plot ); break; } @@ -446,7 +448,7 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( const Packets::FFX if( !housingMgr ) break; - housingMgr->sendHousingInventory( player, Common::InventoryType::HousingIndoorItemStoreroom, 255 ); + // housingMgr->sendHousingInventory( player, Common::InventoryType::HousingInd, 255 ); break; } diff --git a/src/world/Territory/Land.cpp b/src/world/Territory/Land.cpp index ee815597..5f7abd9d 100644 --- a/src/world/Territory/Land.cpp +++ b/src/world/Territory/Land.cpp @@ -122,10 +122,23 @@ void Sapphire::Land::init() m_landInventoryMap[ type ] = make_ItemContainer( type, maxSize, "houseiteminventory", true, true ); }; - setupContainer( InventoryType::HousingExternalAppearance, 8 ); - setupContainer( InventoryType::HousingInternalAppearance, 8 ); - setupContainer( InventoryType::HousingOutdoorItemStoreroom, m_maxPlacedExternalItems ); - setupContainer( InventoryType::HousingIndoorItemStoreroom, m_maxPlacedInternalItems ); + setupContainer( InventoryType::HousingOutdoorAppearance, 8 ); + setupContainer( InventoryType::HousingOutdoorPlacedItems, m_maxPlacedExternalItems ); + setupContainer( InventoryType::HousingOutdoorStoreroom, m_maxPlacedExternalItems ); + + setupContainer( InventoryType::HousingInteriorAppearance, 9 ); + + //uint64_t uId, uint32_t catalogId, uint64_t model1, uint64_t model2, bool isHq + auto item = make_Item( 0x1000, 6600, 0, 0, false ); + item->setStackSize(1); + + m_landInventoryMap[ InventoryType::HousingOutdoorPlacedItems ]->setItem( 0, item ); + m_landInventoryMap[ InventoryType::HousingOutdoorStoreroom ]->setItem( 0, item ); +} + +void Sapphire::Land::loadItemContainerContents() +{ + } uint32_t Sapphire::Land::convertItemIdToHousingItemId( uint32_t itemId ) diff --git a/src/world/Territory/Land.h b/src/world/Territory/Land.h index 5aadbb94..a7b73192 100644 --- a/src/world/Territory/Land.h +++ b/src/world/Territory/Land.h @@ -62,6 +62,7 @@ namespace Sapphire uint8_t getLandTag( uint8_t slot ); ItemContainerPtr getItemContainer( uint16_t inventoryType ) const; + void loadItemContainerContents(); private: uint32_t convertItemIdToHousingItemId( uint32_t itemId ); From c54ceea6079528f0fffa872cb54e5a09932fdc57 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Thu, 20 Dec 2018 21:54:03 +1100 Subject: [PATCH 03/16] fix lambda type and remove testing code --- src/world/Manager/HousingMgr.cpp | 2 -- src/world/Territory/Land.cpp | 9 +-------- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/src/world/Manager/HousingMgr.cpp b/src/world/Manager/HousingMgr.cpp index 80fcbf8c..539bd634 100644 --- a/src/world/Manager/HousingMgr.cpp +++ b/src/world/Manager/HousingMgr.cpp @@ -513,8 +513,6 @@ void Sapphire::World::Manager::HousingMgr::sendHousingInventory( Entity::Player& if( !container ) return; - player.sendDebug( "got inventory for plot: " + targetLand->getHouse()->getHouseName() ); - auto invMgr = g_fw.get< Manager::InventoryMgr >(); invMgr->sendInventoryContainer( player, container ); } \ No newline at end of file diff --git a/src/world/Territory/Land.cpp b/src/world/Territory/Land.cpp index 5f7abd9d..20035793 100644 --- a/src/world/Territory/Land.cpp +++ b/src/world/Territory/Land.cpp @@ -117,7 +117,7 @@ void Sapphire::Land::init() } // init item containers - auto setupContainer = [ this ]( InventoryType type, uint8_t maxSize ) + auto setupContainer = [ this ]( InventoryType type, uint16_t maxSize ) { m_landInventoryMap[ type ] = make_ItemContainer( type, maxSize, "houseiteminventory", true, true ); }; @@ -127,13 +127,6 @@ void Sapphire::Land::init() setupContainer( InventoryType::HousingOutdoorStoreroom, m_maxPlacedExternalItems ); setupContainer( InventoryType::HousingInteriorAppearance, 9 ); - - //uint64_t uId, uint32_t catalogId, uint64_t model1, uint64_t model2, bool isHq - auto item = make_Item( 0x1000, 6600, 0, 0, false ); - item->setStackSize(1); - - m_landInventoryMap[ InventoryType::HousingOutdoorPlacedItems ]->setItem( 0, item ); - m_landInventoryMap[ InventoryType::HousingOutdoorStoreroom ]->setItem( 0, item ); } void Sapphire::Land::loadItemContainerContents() From 361c4a0b6a6bcbd8f484f63470a4769dad339ea7 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Thu, 20 Dec 2018 23:38:39 +1100 Subject: [PATCH 04/16] container count notes --- src/common/Common.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/common/Common.h b/src/common/Common.h index 796f01eb..96e46fc8 100644 --- a/src/common/Common.h +++ b/src/common/Common.h @@ -225,7 +225,7 @@ namespace Sapphire::Common // housing interior containers HousingInteriorAppearance = 25002, - // 50 in each container max + // 50 in each container max, 300 slots max HousingInteriorPlacedItems1 = 25003, HousingInteriorPlacedItems2 = 25004, HousingInteriorPlacedItems3 = 25005, @@ -233,7 +233,9 @@ namespace Sapphire::Common HousingInteriorPlacedItems5 = 25007, HousingInteriorPlacedItems6 = 25008, - // 50 max per container? + // 50 max per container, 400 slots max + // slot limit increased 'temporarily' for relocation for all estates + // see: https://na.finalfantasyxiv.com/lodestone/topics/detail/d781e0d538428aef93b8bed4b50dd62c3c50fc74 HousingInteriorStoreroom1 = 27001, HousingInteriorStoreroom2 = 27002, HousingInteriorStoreroom3 = 27003, From 7dbbeea94ccadce28a166b4febe21b61e56809c9 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Thu, 20 Dec 2018 23:57:01 +1100 Subject: [PATCH 05/16] maybe fix travis, fix ci link in readme --- .travis.yml | 3 ++- README.md | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3df10328..c468e2ef 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,7 +29,8 @@ cache: # Setup build matrix and dependencies before_install: - eval "${MATRIX_EVAL}" - - gem install --no-ri --no-rdoc mtime_cache + - echo "gem: --no-document" >> ~/.gemrc + - gem install mtime_cache - sudo add-apt-repository -y ppa:rexut/recoil - sudo apt-get update - sudo apt-get install -y libmysqlclient-dev diff --git a/README.md b/README.md index 1d441c47..582f4ebf 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@

[![Discord Server](https://img.shields.io/badge/discord-Sapphire-7289DA.svg)](https://discord.gg/xxcdCER) -[![Linux Build Status](https://api.travis-ci.org/SapphireServer/Sapphire.svg?branch=master)](https://travis-ci.org/SapphireMordred/Sapphire) +[![Linux Build Status](https://api.travis-ci.org/SapphireServer/Sapphire.svg?branch=master)](https://travis-ci.org/SapphireServer/Sapphire) [![Windows Build Status](https://ci.appveyor.com/api/projects/status/lil7lxa3ty165emm?svg=true)](https://ci.appveyor.com/project/SapphireMordred/Sapphire) From 228af2d18561586a35d3a46497627542ae9b6616 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Thu, 20 Dec 2018 23:59:13 +1100 Subject: [PATCH 06/16] remove old boost shit from travis --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index c468e2ef..91c97051 100644 --- a/.travis.yml +++ b/.travis.yml @@ -31,7 +31,6 @@ before_install: - eval "${MATRIX_EVAL}" - echo "gem: --no-document" >> ~/.gemrc - gem install mtime_cache - - sudo add-apt-repository -y ppa:rexut/recoil - sudo apt-get update - sudo apt-get install -y libmysqlclient-dev From dc5a16512a6ae3faa58449e800a9b459fcc79804 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Fri, 21 Dec 2018 00:00:05 +1100 Subject: [PATCH 07/16] maybe this works --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 91c97051..70c3d8dd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,7 +29,7 @@ cache: # Setup build matrix and dependencies before_install: - eval "${MATRIX_EVAL}" - - echo "gem: --no-document" >> ~/.gemrc + - echo 'gem: --no-document' >> ~/.gemrc - gem install mtime_cache - sudo apt-get update - sudo apt-get install -y libmysqlclient-dev From 07fbc3f24519126d33bd79c8c247161d2b38c113 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Fri, 21 Dec 2018 00:04:11 +1100 Subject: [PATCH 08/16] fucking ruby devs --- .travis.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 70c3d8dd..5e0ff6c4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,6 @@ matrix: apt: sources: - ubuntu-toolchain-r-test - - llvm-toolchain-trusty-6.0 packages: - clang-6.0 - g++-7 @@ -29,8 +28,7 @@ cache: # Setup build matrix and dependencies before_install: - eval "${MATRIX_EVAL}" - - echo 'gem: --no-document' >> ~/.gemrc - - gem install mtime_cache + - gem install mtime_cache --no-ri --no-rdoc - sudo apt-get update - sudo apt-get install -y libmysqlclient-dev From a9c0ce08c72d8bc41518803efc5fccf0c53bd21a Mon Sep 17 00:00:00 2001 From: NotAdam Date: Fri, 21 Dec 2018 00:06:36 +1100 Subject: [PATCH 09/16] don't attempt to install clang --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 5e0ff6c4..3783642b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,7 +14,6 @@ matrix: sources: - ubuntu-toolchain-r-test packages: - - clang-6.0 - g++-7 env: - MATRIX_EVAL="CC=gcc-7 && CXX=g++-7" From 5a4e4ee58ddacd61d487aa8ba1b8bdf6f2e1e9cb Mon Sep 17 00:00:00 2001 From: NotAdam Date: Fri, 21 Dec 2018 00:10:13 +1100 Subject: [PATCH 10/16] how about this --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 3783642b..8ca1bc43 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,7 +27,7 @@ cache: # Setup build matrix and dependencies before_install: - eval "${MATRIX_EVAL}" - - gem install mtime_cache --no-ri --no-rdoc + - gem install mtime_cache --no-document - sudo apt-get update - sudo apt-get install -y libmysqlclient-dev From 4e3de5817fd85f7ee385f3f5f107347340c0a4b8 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Fri, 21 Dec 2018 22:08:05 +1100 Subject: [PATCH 11/16] 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 7aba36f9631201fdb2b0516eb19c4979916b38d9 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Fri, 21 Dec 2018 22:23:49 +1100 Subject: [PATCH 12/16] 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 732e36dc0a128abcc667277149d17c77512962df Mon Sep 17 00:00:00 2001 From: NotAdam Date: Fri, 21 Dec 2018 23:49:46 +1100 Subject: [PATCH 13/16] 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 d6b548afe968be50218ce255dc82a674bddce1e5 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sat, 22 Dec 2018 00:48:43 +1100 Subject: [PATCH 14/16] 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 5f6c2d950a1b18ec7ef022591312e55985d9c86d Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sat, 22 Dec 2018 01:00:31 +1100 Subject: [PATCH 15/16] 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 0fd3bf4194e2f58ba29b5972aa95f95969610fe5 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sat, 22 Dec 2018 01:02:42 +1100 Subject: [PATCH 16/16] 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 );