From f48d546d85eb6deb6ca4a36511da7eda969ba9e5 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Tue, 18 Dec 2018 21:40:44 +1100 Subject: [PATCH 1/6] show better errors for exd/config related issues --- src/api/main.cpp | 7 +++++-- src/common/Config/ConfigMgr.cpp | 4 ++-- src/lobby/ServerLobby.cpp | 1 + src/world/ServerMgr.cpp | 7 +++++-- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/api/main.cpp b/src/api/main.cpp index e8641c50..7b2dff21 100644 --- a/src/api/main.cpp +++ b/src/api/main.cpp @@ -74,6 +74,7 @@ bool loadSettings( int32_t argc, char* argv[] ) if( !m_pConfig->loadConfig( configPath ) ) { g_log.fatal( "Error loading config " + configPath ); + g_log.fatal( "If this is the first time starting the server, we've copied the default one for your editing pleasure." ); return false; } @@ -140,9 +141,11 @@ bool loadSettings( int32_t argc, char* argv[] ) } g_log.info( "Setting up generated EXD data" ); - if( !g_exdDataGen.init( m_pConfig->getValue< std::string >( "GlobalParameters", "DataPath", "" ) ) ) + auto dataPath = m_pConfig->getValue< std::string >( "GlobalParameters", "DataPath", "" ); + if( !g_exdDataGen.init( dataPath ) ) { - g_log.fatal( "Error setting up generated EXD data " ); + g_log.fatal( "Error setting up generated EXD data. Make sure that DataPath is set correctly in config.ini" ); + g_log.fatal( "DataPath: " + dataPath ); return false; } diff --git a/src/common/Config/ConfigMgr.cpp b/src/common/Config/ConfigMgr.cpp index d4c9cddc..b1e975f2 100644 --- a/src/common/Config/ConfigMgr.cpp +++ b/src/common/Config/ConfigMgr.cpp @@ -17,8 +17,8 @@ bool Sapphire::ConfigMgr::loadConfig( const std::string& configName ) if( !fs::exists( configFile ) ) { - if( !copyDefaultConfig( configName ) ) - return false; + copyDefaultConfig( configName ); + return false; } m_pInih = std::unique_ptr< INIReader >( new INIReader( configFile.string() ) ); diff --git a/src/lobby/ServerLobby.cpp b/src/lobby/ServerLobby.cpp index bfaaeb53..e084889a 100644 --- a/src/lobby/ServerLobby.cpp +++ b/src/lobby/ServerLobby.cpp @@ -90,6 +90,7 @@ bool ServerLobby::loadSettings( int32_t argc, char* argv[] ) if( !m_pConfig->loadConfig( m_configPath ) ) { g_log.fatal( "Error loading config " + m_configPath ); + g_log.fatal( "If this is the first time starting the server, we've copied the default one for your editing pleasure." ); return false; } std::vector< std::string > args( argv + 1, argv + argc ); diff --git a/src/world/ServerMgr.cpp b/src/world/ServerMgr.cpp index b1b92588..270e0423 100644 --- a/src/world/ServerMgr.cpp +++ b/src/world/ServerMgr.cpp @@ -69,6 +69,7 @@ bool Sapphire::ServerMgr::loadSettings( int32_t argc, char* argv[] ) if( !pConfig->loadConfig( m_configName ) ) { pLog->fatal( "Error loading config " + m_configName ); + pLog->fatal( "If this is the first time starting the server, we've copied the default one for your editing pleasure." ); return false; } @@ -100,9 +101,11 @@ void Sapphire::ServerMgr::run( int32_t argc, char* argv[] ) pLog->info( "Setting up generated EXD data" ); auto pExdData = std::make_shared< Data::ExdDataGenerated >(); - if( !pExdData->init( pConfig->getValue< std::string >( "GlobalParameters", "DataPath", "" ) ) ) + auto dataPath = pConfig->getValue< std::string >( "GlobalParameters", "DataPath", "" ); + if( !pExdData->init( dataPath ) ) { - pLog->fatal( "Error setting up generated EXD data " ); + pLog->fatal( "Error setting up generated EXD data. Make sure that DataPath is set correctly in config.ini" ); + pLog->fatal( "DataPath: " + dataPath ); return; } g_fw.set< Data::ExdDataGenerated >( pExdData ); From 5010de4aab9002f4dac0804eb1af2f33f6329fc9 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Tue, 18 Dec 2018 21:49:42 +1100 Subject: [PATCH 2/6] Ignore config folder contents except the default file --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index 29e00e8f..cd13283c 100644 --- a/.gitignore +++ b/.gitignore @@ -129,3 +129,7 @@ cotire/ # doxygen output folder doxygen/generated/ doxygen/*.tmp + +# ignore config directory contents except the default file +bin/config/*.ini +!bin/config/config.ini.default \ No newline at end of file From 3f6f0d5a5fa5dec30916d598808ce31cb38caf8e Mon Sep 17 00:00:00 2001 From: NotAdam Date: Tue, 18 Dec 2018 22:06:34 +1100 Subject: [PATCH 3/6] Ignore built tools --- .gitignore | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.gitignore b/.gitignore index cd13283c..cf25145f 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,16 @@ [Bb]in/world [Bb]in/lobby [Bb]in/dbm +src/tools/[Bb]in/*.exe +src/tools/[Bb]in/*.pdb +src/tools/[Bb]in/discovery_parser +src/tools/[Bb]in/event_object_parser +src/tools/[Bb]in/exd_common_gen +src/tools/[Bb]in/exd_struct_test +src/tools/[Bb]in/mob_parse +src/tools/[Bb]in/pcb_reader2 +src/tools/[Bb]in/quest_parse +src/tools/[Bb]in/exd_struct_gen # Script Directory # TODO: Sperate script directory from bin From f44c6b5efe6dd733a29ac6b2aba7931c2d3a2bf6 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Tue, 18 Dec 2018 22:59:01 +1100 Subject: [PATCH 4/6] Move inventory container sending to its own function --- .../Network/PacketDef/Zone/ServerZoneDef.h | 6 +- src/world/Actor/PlayerInventory.cpp | 52 ++--------------- src/world/Manager/InventoryMgr.cpp | 58 +++++++++++++++++++ src/world/Manager/InventoryMgr.h | 18 ++++++ src/world/ServerMgr.cpp | 3 + 5 files changed, 88 insertions(+), 49 deletions(-) create mode 100644 src/world/Manager/InventoryMgr.cpp create mode 100644 src/world/Manager/InventoryMgr.h diff --git a/src/common/Network/PacketDef/Zone/ServerZoneDef.h b/src/common/Network/PacketDef/Zone/ServerZoneDef.h index 2db26254..8c7768a9 100644 --- a/src/common/Network/PacketDef/Zone/ServerZoneDef.h +++ b/src/common/Network/PacketDef/Zone/ServerZoneDef.h @@ -1078,7 +1078,7 @@ struct FFXIVIpcCharaNameReq : struct FFXIVIpcItemInfo : FFXIVIpcBasePacket< ItemInfo > { - uint32_t sequence; + uint32_t containerSequence; uint32_t unknown; uint16_t containerId; uint16_t slot; @@ -1113,7 +1113,7 @@ struct FFXIVIpcItemInfo : struct FFXIVIpcContainerInfo : FFXIVIpcBasePacket< ContainerInfo > { - uint32_t sequence; + uint32_t containerSequence; uint32_t numItems; uint32_t containerId; uint32_t unknown; @@ -1126,7 +1126,7 @@ struct FFXIVIpcContainerInfo : struct FFXIVIpcCurrencyCrystalInfo : FFXIVIpcBasePacket< CurrencyCrystalInfo > { - uint32_t sequence; + uint32_t containerSequence; uint16_t containerId; uint16_t slot; uint32_t quantity; diff --git a/src/world/Actor/PlayerInventory.cpp b/src/world/Actor/PlayerInventory.cpp index d7c78044..365bd622 100644 --- a/src/world/Actor/PlayerInventory.cpp +++ b/src/world/Actor/PlayerInventory.cpp @@ -27,6 +27,7 @@ #include "Network/PacketWrappers/ServerNoticePacket.h" #include "Network/PacketWrappers/ActorControlPacket143.h" +#include "Manager/InventoryMgr.h" #include "Framework.h" #include @@ -358,54 +359,13 @@ void Sapphire::Entity::Player::sendInventory() { InventoryMap::iterator it; - int32_t count = 0; - for( it = m_storageMap.begin(); it != m_storageMap.end(); ++it, count++ ) + auto pInvMgr = g_fw.get< World::Manager::InventoryMgr >(); + + uint32_t count = 0; + for( it = m_storageMap.begin(); it != m_storageMap.end(); ++it, ++count ) { - - auto pMap = it->second->getItemMap(); - auto itM = pMap.begin(); - - for( ; itM != pMap.end(); ++itM ) - { - if( !itM->second ) - return; - - if( it->second->getId() == InventoryType::Currency || it->second->getId() == InventoryType::Crystal ) - { - auto currencyInfoPacket = makeZonePacket< FFXIVIpcCurrencyCrystalInfo >( getId() ); - currencyInfoPacket->data().sequence = count; - currencyInfoPacket->data().catalogId = itM->second->getId(); - currencyInfoPacket->data().unknown = 1; - currencyInfoPacket->data().quantity = itM->second->getStackSize(); - currencyInfoPacket->data().containerId = it->second->getId(); - currencyInfoPacket->data().slot = 0; - queuePacket( currencyInfoPacket ); - } - else - { - auto itemInfoPacket = makeZonePacket< FFXIVIpcItemInfo >( getId() ); - itemInfoPacket->data().sequence = count; - itemInfoPacket->data().containerId = it->second->getId(); - itemInfoPacket->data().slot = itM->first; - itemInfoPacket->data().quantity = itM->second->getStackSize(); - itemInfoPacket->data().catalogId = itM->second->getId(); - itemInfoPacket->data().condition = itM->second->getDurability(); - itemInfoPacket->data().spiritBond = 0; - itemInfoPacket->data().hqFlag = itM->second->isHq() ? 1 : 0; - itemInfoPacket->data().stain = itM->second->getStain(); - queuePacket( itemInfoPacket ); - } - } - - auto containerInfoPacket = makeZonePacket< FFXIVIpcContainerInfo >( getId() ); - containerInfoPacket->data().sequence = count; - containerInfoPacket->data().numItems = it->second->getEntryCount(); - containerInfoPacket->data().containerId = it->second->getId(); - queuePacket( containerInfoPacket ); - - + pInvMgr->sendInventoryContainer( *this, it->second, count ); } - } Sapphire::Entity::Player::InvSlotPairVec Sapphire::Entity::Player::getSlotsOfItemsInInventory( uint32_t catalogId ) diff --git a/src/world/Manager/InventoryMgr.cpp b/src/world/Manager/InventoryMgr.cpp new file mode 100644 index 00000000..8ce40ffe --- /dev/null +++ b/src/world/Manager/InventoryMgr.cpp @@ -0,0 +1,58 @@ +#include "InventoryMgr.h" + +#include +#include "Actor/Player.h" +#include "Inventory/ItemContainer.h" +#include "Inventory/Item.h" +#include +#include + +using namespace Sapphire::Network::Packets; + +void Sapphire::World::Manager::InventoryMgr::sendInventoryContainer( Sapphire::Entity::Player& player, + Sapphire::ItemContainerPtr container, + uint32_t sequence ) +{ + auto pMap = container->getItemMap(); + + for( auto itM = pMap.begin(); itM != pMap.end(); ++itM ) + { + if( !itM->second ) + return; + + if( container->getId() == Common::InventoryType::Currency || container->getId() == Common::InventoryType::Crystal ) + { + auto currencyInfoPacket = makeZonePacket< Server::FFXIVIpcCurrencyCrystalInfo >( player.getId() ); + currencyInfoPacket->data().containerSequence = sequence; + currencyInfoPacket->data().catalogId = itM->second->getId(); + currencyInfoPacket->data().unknown = 1; + currencyInfoPacket->data().quantity = itM->second->getStackSize(); + currencyInfoPacket->data().containerId = container->getId(); + currencyInfoPacket->data().slot = 0; + + player.queuePacket( currencyInfoPacket ); + } + else + { + auto itemInfoPacket = makeZonePacket< Server::FFXIVIpcItemInfo >( player.getId() ); + itemInfoPacket->data().containerSequence = sequence; + itemInfoPacket->data().containerId = container->getId(); + itemInfoPacket->data().slot = itM->first; + itemInfoPacket->data().quantity = itM->second->getStackSize(); + itemInfoPacket->data().catalogId = itM->second->getId(); + itemInfoPacket->data().condition = itM->second->getDurability(); + itemInfoPacket->data().spiritBond = 0; + itemInfoPacket->data().hqFlag = itM->second->isHq() ? 1 : 0; + itemInfoPacket->data().stain = itM->second->getStain(); + + player.queuePacket( itemInfoPacket ); + } + } + + auto containerInfoPacket = makeZonePacket< Server::FFXIVIpcContainerInfo >( player.getId() ); + containerInfoPacket->data().containerSequence = sequence; + containerInfoPacket->data().numItems = container->getEntryCount(); + containerInfoPacket->data().containerId = container->getId(); + + player.queuePacket( containerInfoPacket ); +} \ No newline at end of file diff --git a/src/world/Manager/InventoryMgr.h b/src/world/Manager/InventoryMgr.h new file mode 100644 index 00000000..55869850 --- /dev/null +++ b/src/world/Manager/InventoryMgr.h @@ -0,0 +1,18 @@ +#ifndef SAPPHIRE_INVENTORYMGR_H +#define SAPPHIRE_INVENTORYMGR_H + +#include "ForwardsZone.h" + +namespace Sapphire::World::Manager +{ + + class InventoryMgr + { + public: + void sendInventoryContainer( Sapphire::Entity::Player& player, Sapphire::ItemContainerPtr container, + uint32_t sequence = 0 ); + }; + +} + +#endif //SAPPHIRE_INVENTORYMGR_H diff --git a/src/world/ServerMgr.cpp b/src/world/ServerMgr.cpp index 270e0423..ec597356 100644 --- a/src/world/ServerMgr.cpp +++ b/src/world/ServerMgr.cpp @@ -36,6 +36,7 @@ #include "DebugCommand/DebugCommandHandler.h" #include "Manager/PlayerMgr.h" #include "Manager/ShopMgr.h" +#include "Manager/InventoryMgr.h" extern Sapphire::Framework g_fw; @@ -168,10 +169,12 @@ void Sapphire::ServerMgr::run( int32_t argc, char* argv[] ) auto pDebugCom = std::make_shared< DebugCommandHandler >(); auto pPlayerMgr = std::make_shared< Manager::PlayerMgr >(); auto pShopMgr = std::make_shared< Manager::ShopMgr >(); + auto pInventoryMgr = std::make_shared< Manager::InventoryMgr >(); g_fw.set< DebugCommandHandler >( pDebugCom ); g_fw.set< Manager::PlayerMgr >( pPlayerMgr ); g_fw.set< Manager::ShopMgr >( pShopMgr ); + g_fw.set< Manager::InventoryMgr >( pInventoryMgr ); pLog->info( "World server running on " + m_ip + ":" + std::to_string( m_port ) ); From 107c94f33c2854a75f586be06fb2c6a7ee72b689 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Wed, 19 Dec 2018 00:54:25 +1100 Subject: [PATCH 5/6] minor cleanup and fix ward/landid being read incorrectly --- src/world/Manager/HousingMgr.cpp | 17 +++++++---------- src/world/Territory/Land.cpp | 6 +++--- src/world/Territory/Land.h | 6 +++--- 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/world/Manager/HousingMgr.cpp b/src/world/Manager/HousingMgr.cpp index 0079f319..e4444723 100644 --- a/src/world/Manager/HousingMgr.cpp +++ b/src/world/Manager/HousingMgr.cpp @@ -87,20 +87,14 @@ void Sapphire::World::Manager::HousingMgr::sendLandSignOwned( Entity::Player& pl auto land = hZone->getLand( ident.landId ); if( !land ) - { - land = getLandByOwnerId( player.getId() ); - } + return; auto landInfoSignPacket = makeZonePacket< Server::FFXIVIpcLandInfoSign >( player.getId() ); - uint32_t playerId = land->getPlayerOwner(); - std::string playerName = g_fw.get< Sapphire::ServerMgr >()->getPlayerNameFromDb( playerId ); - //memcpy( &landInfoSignPacket->data().estateGreeting, "Hello World", 11 ); - //memcpy( &landInfoSignPacket->data().estateName, land->getLandName().c_str(), land->getLandName().size() ); landInfoSignPacket->data().houseSize = land->getSize(); landInfoSignPacket->data().houseType = static_cast< uint8_t >( land->getLandType() ); landInfoSignPacket->data().landIdent = ident; landInfoSignPacket->data().houseIconAdd = land->getSharing(); - landInfoSignPacket->data().ownerId = player.getContentId(); // should be real owner contentId, not player.contentId() + landInfoSignPacket->data().ownerId = player.getContentId(); // todo: should be real owner contentId, not player.contentId() if( auto house = land->getHouse() ) { @@ -108,6 +102,9 @@ void Sapphire::World::Manager::HousingMgr::sendLandSignOwned( Entity::Player& pl std::strcpy( landInfoSignPacket->data().estateGreeting, house->getHouseGreeting().c_str() ); } + uint32_t playerId = land->getPlayerOwner(); + std::string playerName = g_fw.get< Sapphire::ServerMgr >()->getPlayerNameFromDb( playerId ); + memcpy( &landInfoSignPacket->data().ownerName, playerName.c_str(), playerName.size() ); player.queuePacket( landInfoSignPacket ); @@ -458,8 +455,8 @@ Sapphire::Common::LandIdent Sapphire::World::Manager::HousingMgr::clientTriggerP Common::LandIdent ident; ident.worldId = param11 >> 16; ident.territoryTypeId = param11 & 0xFFFF; - ident.wardNum = param12 >> 16; - ident.landId = param12 & 0xFFFF; + ident.wardNum = (param12 >> 8) & 0xFF; + ident.landId = param12 & 0xFF; return ident; } diff --git a/src/world/Territory/Land.cpp b/src/world/Territory/Land.cpp index 84bd215f..afe1bb8b 100644 --- a/src/world/Territory/Land.cpp +++ b/src/world/Territory/Land.cpp @@ -77,7 +77,7 @@ void Sapphire::Land::init() m_size = res->getUInt( "Size" ); m_state = res->getUInt( "Status" ); m_currentPrice = res->getUInt( "LandPrice" ); - m_ownerPlayerId = res->getUInt( "OwnerId" ); + m_ownerPlayerId = res->getUInt64( "OwnerId" ); m_minPrice = m_landInfo->minPrice[ m_landId ]; m_maxPrice = m_landInfo->initialPrice[ m_landId ]; @@ -240,12 +240,12 @@ uint32_t Sapphire::Land::getFcColor() } //Player -void Sapphire::Land::setPlayerOwner( uint32_t id ) +void Sapphire::Land::setPlayerOwner( uint64_t id ) { m_ownerPlayerId = id; } -uint32_t Sapphire::Land::getPlayerOwner() +uint64_t Sapphire::Land::getPlayerOwner() { return m_ownerPlayerId; } diff --git a/src/world/Territory/Land.h b/src/world/Territory/Land.h index 7d3ee6a1..35f29457 100644 --- a/src/world/Territory/Land.h +++ b/src/world/Territory/Land.h @@ -45,8 +45,8 @@ namespace Sapphire uint32_t getFcColor(); //Player - void setPlayerOwner( uint32_t id ); - uint32_t getPlayerOwner(); + void setPlayerOwner( uint64_t id ); + uint64_t getPlayerOwner(); //Housing Functions void setCurrentPrice( uint32_t currentPrice ); bool setPreset( uint32_t itemId ); @@ -82,7 +82,7 @@ namespace Sapphire Common::FFXIVARR_POSITION3 m_mapMarkerPosition; - uint32_t m_ownerPlayerId; + uint64_t m_ownerPlayerId; Sapphire::Data::HousingLandSetPtr m_landInfo; Sapphire::HousePtr m_pHouse; From 55e2290565060965131cede6244a6e4ef854d255 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Wed, 19 Dec 2018 01:03:41 +1100 Subject: [PATCH 6/6] fix this stupid inconsistency where its sometimes 2 u8s, sometimes u16s --- src/world/Manager/HousingMgr.cpp | 15 ++++++++++++--- src/world/Manager/HousingMgr.h | 2 +- .../Network/Handlers/ClientTriggerHandler.cpp | 2 +- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/world/Manager/HousingMgr.cpp b/src/world/Manager/HousingMgr.cpp index e4444723..011f4d82 100644 --- a/src/world/Manager/HousingMgr.cpp +++ b/src/world/Manager/HousingMgr.cpp @@ -450,13 +450,22 @@ void Sapphire::World::Manager::HousingMgr::requestEstateEditGuestAccess( Entity: player.queuePacket( packet ); } -Sapphire::Common::LandIdent Sapphire::World::Manager::HousingMgr::clientTriggerParamsToLandIdent( uint32_t param11, uint32_t param12 ) const +Sapphire::Common::LandIdent Sapphire::World::Manager::HousingMgr::clientTriggerParamsToLandIdent( uint32_t param11, uint32_t param12, bool use16bits ) const { Common::LandIdent ident; ident.worldId = param11 >> 16; ident.territoryTypeId = param11 & 0xFFFF; - ident.wardNum = (param12 >> 8) & 0xFF; - ident.landId = param12 & 0xFF; + + if( use16bits ) + { + ident.wardNum = param12 >> 16; + ident.landId = param12 & 0xFFFF; + } + else + { + ident.wardNum = (param12 >> 8) & 0xFF; + ident.landId = param12 & 0xFF; + } return ident; } diff --git a/src/world/Manager/HousingMgr.h b/src/world/Manager/HousingMgr.h index e0f5c232..b4334714 100644 --- a/src/world/Manager/HousingMgr.h +++ b/src/world/Manager/HousingMgr.h @@ -33,7 +33,7 @@ namespace Sapphire::World::Manager /*! * @brief Converts param1 of a client trigger into a Common::LandIndent */ - Common::LandIdent clientTriggerParamsToLandIdent( uint32_t param11, uint32_t param12 ) const; + Common::LandIdent clientTriggerParamsToLandIdent( uint32_t param11, uint32_t param12, bool use16bits = true ) const; void sendWardLandInfo( Entity::Player& player, uint8_t wardId, uint16_t territoryTypeId ); diff --git a/src/world/Network/Handlers/ClientTriggerHandler.cpp b/src/world/Network/Handlers/ClientTriggerHandler.cpp index b2236677..40add015 100644 --- a/src/world/Network/Handlers/ClientTriggerHandler.cpp +++ b/src/world/Network/Handlers/ClientTriggerHandler.cpp @@ -336,7 +336,7 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( const Packets::FFX { auto pHousingMgr = g_fw.get< HousingMgr >(); - auto ident = pHousingMgr->clientTriggerParamsToLandIdent( param11, param12 ); + auto ident = pHousingMgr->clientTriggerParamsToLandIdent( param11, param12, false ); pHousingMgr->sendLandSignOwned( player, ident ); break;