From 93e8c5359aa690643c9e9a986373e7e916b3ffc1 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Mon, 28 Jan 2019 20:29:30 +1100 Subject: [PATCH 1/5] Increase cell size and spawn distance, fix player despawn issue --- src/common/Util/SpawnIndexAllocator.h | 2 +- src/world/Actor/Player.cpp | 9 ++++++++- src/world/Territory/CellHandler.h | 2 +- src/world/Territory/Zone.cpp | 5 ++--- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/common/Util/SpawnIndexAllocator.h b/src/common/Util/SpawnIndexAllocator.h index 4ddfcc79..500339eb 100644 --- a/src/common/Util/SpawnIndexAllocator.h +++ b/src/common/Util/SpawnIndexAllocator.h @@ -37,7 +37,7 @@ namespace Sapphire::Util { auto it = m_actorIdToAllocatedMap.find( actorId ); if( it == m_actorIdToAllocatedMap.end() ) - return 0; + return getAllocFailId(); auto index = it->second; m_availableIds.push( index ); diff --git a/src/world/Actor/Player.cpp b/src/world/Actor/Player.cpp index f7e2c317..a4cc4d05 100644 --- a/src/world/Actor/Player.cpp +++ b/src/world/Actor/Player.cpp @@ -1127,11 +1127,14 @@ void Sapphire::Entity::Player::freePlayerSpawnId( uint32_t actorId ) { auto spawnId = m_actorSpawnIndexAllocator.freeUsedSpawnIndex( actorId ); + // actor was never spawned for this player + if( spawnId == m_actorSpawnIndexAllocator.getAllocFailId() ) + return; + auto freeActorSpawnPacket = makeZonePacket< FFXIVIpcActorFreeSpawn >( getId() ); freeActorSpawnPacket->data().actorId = actorId; freeActorSpawnPacket->data().spawnId = spawnId; queuePacket( freeActorSpawnPacket ); - } uint8_t* Sapphire::Entity::Player::getAetheryteArray() @@ -1844,6 +1847,10 @@ void Sapphire::Entity::Player::freeObjSpawnIndexForActorId( uint32_t actorId ) { auto spawnId = m_objSpawnIndexAllocator.freeUsedSpawnIndex( actorId ); + // obj was never spawned for this player + if( spawnId == m_objSpawnIndexAllocator.getAllocFailId() ) + return; + auto freeObjectSpawnPacket = makeZonePacket< FFXIVIpcObjectDespawn >( getId() ); freeObjectSpawnPacket->data().spawnIndex = spawnId; queuePacket( freeObjectSpawnPacket ); diff --git a/src/world/Territory/CellHandler.h b/src/world/Territory/CellHandler.h index bfcdac52..3faca439 100644 --- a/src/world/Territory/CellHandler.h +++ b/src/world/Territory/CellHandler.h @@ -3,7 +3,7 @@ #include #define TilesCount 32 -#define TileSize 250.0f +#define TileSize 500.0f #define _minY (-TilesCount*TileSize/2) #define _minX (-TilesCount*TileSize/2) diff --git a/src/world/Territory/Zone.cpp b/src/world/Territory/Zone.cpp index e1bfb528..f7d56d10 100644 --- a/src/world/Territory/Zone.cpp +++ b/src/world/Territory/Zone.cpp @@ -645,7 +645,7 @@ void Sapphire::Zone::updateInRangeSet( Entity::ActorPtr pActor, Cell* pCell ) auto iter = pCell->m_actors.begin(); - float fRange = 70.0f; + float fRange = 150.0f; int32_t count = 0; while( iter != pCell->m_actors.end() ) { @@ -655,8 +655,7 @@ void Sapphire::Zone::updateInRangeSet( Entity::ActorPtr pActor, Cell* pCell ) if( !pCurAct || pCurAct == pActor ) continue; - float distance = Util::distance( pCurAct->getPos().x, pCurAct->getPos().y, pCurAct->getPos().z, - pActor->getPos().x, pActor->getPos().y, pActor->getPos().z ); + float distance = Util::distance( pCurAct->getPos(), pActor->getPos() ); bool isInRange = ( fRange == 0.0f || distance <= fRange ); bool isInRangeSet = pActor->isInRangeSet( pCurAct ); From 2f7a304303fcbd5e9c24ee2f5a0089bc9e22b82d Mon Sep 17 00:00:00 2001 From: NotAdam Date: Mon, 28 Jan 2019 20:37:51 +1100 Subject: [PATCH 2/5] slightly decrease cell size and inrange distance --- src/world/Territory/CellHandler.h | 2 +- src/world/Territory/Zone.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/world/Territory/CellHandler.h b/src/world/Territory/CellHandler.h index 3faca439..7a0f6c86 100644 --- a/src/world/Territory/CellHandler.h +++ b/src/world/Territory/CellHandler.h @@ -3,7 +3,7 @@ #include #define TilesCount 32 -#define TileSize 500.0f +#define TileSize 325.0f #define _minY (-TilesCount*TileSize/2) #define _minX (-TilesCount*TileSize/2) diff --git a/src/world/Territory/Zone.cpp b/src/world/Territory/Zone.cpp index f7d56d10..f691e25a 100644 --- a/src/world/Territory/Zone.cpp +++ b/src/world/Territory/Zone.cpp @@ -645,7 +645,7 @@ void Sapphire::Zone::updateInRangeSet( Entity::ActorPtr pActor, Cell* pCell ) auto iter = pCell->m_actors.begin(); - float fRange = 150.0f; + float fRange = 100.0f; int32_t count = 0; while( iter != pCell->m_actors.end() ) { From ebec29563f93e9a61f73840b3a2c49ae2d617ab9 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Mon, 28 Jan 2019 20:48:33 +1100 Subject: [PATCH 3/5] Make in range distance configurable --- config/world.ini.default | 1 + src/common/Config/ConfigDef.h | 2 ++ src/world/Manager/TerritoryMgr.cpp | 10 ++++++++++ src/world/Manager/TerritoryMgr.h | 5 +++++ src/world/ServerMgr.cpp | 1 + src/world/Territory/Zone.cpp | 2 +- 6 files changed, 20 insertions(+), 1 deletion(-) diff --git a/config/world.ini.default b/config/world.ini.default index ec461c19..4dacbc65 100644 --- a/config/world.ini.default +++ b/config/world.ini.default @@ -10,6 +10,7 @@ HotSwap = true ListenIp = 0.0.0.0 ListenPort = 54992 DisconnectTimeout = 20 +InRangeDistance = 100.0 [General] ; Sent on login - each line must be shorter than 307 characters, split lines with ';' diff --git a/src/common/Config/ConfigDef.h b/src/common/Config/ConfigDef.h index 3aca9cff..4d99591f 100644 --- a/src/common/Config/ConfigDef.h +++ b/src/common/Config/ConfigDef.h @@ -44,6 +44,8 @@ namespace Sapphire::Common::Config uint16_t listenPort; uint16_t disconnectTimeout; + + float inRangeDistance; } network; struct Housing diff --git a/src/world/Manager/TerritoryMgr.cpp b/src/world/Manager/TerritoryMgr.cpp index 2c2edb83..da8ff1ac 100644 --- a/src/world/Manager/TerritoryMgr.cpp +++ b/src/world/Manager/TerritoryMgr.cpp @@ -2,6 +2,8 @@ #include #include +#include "ServerMgr.h" + #include #include "Actor/Player.h" @@ -59,6 +61,10 @@ bool Sapphire::World::Manager::TerritoryMgr::init() return false; } + auto& cfg = framework()->get< World::ServerMgr >()->getConfig(); + + m_inRangeDistance = cfg.network.inRangeDistance; + return true; } @@ -584,5 +590,9 @@ void Sapphire::World::Manager::TerritoryMgr::disableCurrentFestival() setCurrentFestival( 0 ); } +float Sapphire::World::Manager::TerritoryMgr::getInRangeDistance() const +{ + return m_inRangeDistance; +} diff --git a/src/world/Manager/TerritoryMgr.h b/src/world/Manager/TerritoryMgr.h index 1905b7f6..1c8846be 100644 --- a/src/world/Manager/TerritoryMgr.h +++ b/src/world/Manager/TerritoryMgr.h @@ -155,6 +155,8 @@ namespace Sapphire::World::Manager */ const std::pair< uint16_t, uint16_t >& getCurrentFestival() const; + float getInRangeDistance() const; + private: using TerritoryTypeDetailCache = std::unordered_map< uint16_t, Data::TerritoryTypePtr >; using InstanceIdToZonePtrMap = std::unordered_map< uint32_t, ZonePtr >; @@ -202,6 +204,9 @@ namespace Sapphire::World::Manager /*! current festival(s) to set for public zones from festival.exd */ std::pair< uint16_t, uint16_t > m_currentFestival; + /*! Max distance at which actors in range of a player are sent */ + float m_inRangeDistance; + public: /*! returns a list of instanceContent InstanceIds currently active */ InstanceIdList getInstanceContentIdList( uint16_t instanceContentId ) const; diff --git a/src/world/ServerMgr.cpp b/src/world/ServerMgr.cpp index 7149356d..e5b0367f 100644 --- a/src/world/ServerMgr.cpp +++ b/src/world/ServerMgr.cpp @@ -101,6 +101,7 @@ bool Sapphire::World::ServerMgr::loadSettings( int32_t argc, char* argv[] ) m_config.network.disconnectTimeout = pConfig->getValue< uint16_t >( "Network", "DisconnectTimeout", 20 ); m_config.network.listenIp = pConfig->getValue< std::string >( "Network", "ListenIp", "0.0.0.0" ); m_config.network.listenPort = pConfig->getValue< uint16_t >( "Network", "ListenPort", 54992 ); + m_config.network.inRangeDistance = pConfig->getValue< float >( "Network", "InRangeDistance", 100.f ); m_config.motd = pConfig->getValue< std::string >( "General", "MotD", "" ); diff --git a/src/world/Territory/Zone.cpp b/src/world/Territory/Zone.cpp index f691e25a..d0472427 100644 --- a/src/world/Territory/Zone.cpp +++ b/src/world/Territory/Zone.cpp @@ -645,7 +645,7 @@ void Sapphire::Zone::updateInRangeSet( Entity::ActorPtr pActor, Cell* pCell ) auto iter = pCell->m_actors.begin(); - float fRange = 100.0f; + float fRange = pTeriMgr->getInRangeDistance(); int32_t count = 0; while( iter != pCell->m_actors.end() ) { From 2478b0b2642cde963f49fbb87cdb9d4c638f3ff2 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Mon, 28 Jan 2019 21:02:51 +1100 Subject: [PATCH 4/5] log a warning to world log/player in the event an actor wasn't spawned --- src/world/Actor/Player.cpp | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/src/world/Actor/Player.cpp b/src/world/Actor/Player.cpp index a4cc4d05..9ccc85d2 100644 --- a/src/world/Actor/Player.cpp +++ b/src/world/Actor/Player.cpp @@ -534,7 +534,20 @@ void Sapphire::Entity::Player::initSpawnIdQueue() uint8_t Sapphire::Entity::Player::getSpawnIdForActorId( uint32_t actorId ) { - return m_actorSpawnIndexAllocator.getNextFreeSpawnIndex( actorId ); + auto index = m_actorSpawnIndexAllocator.getNextFreeSpawnIndex( actorId ); + + if( index == m_actorSpawnIndexAllocator.getAllocFailId() ) + { + Logger::warn( "Failed to spawn Chara#{0} for Player#{1} - no remaining spawn indexes available. " + "Consider lowering InRangeDistance in world config.", + actorId, getId() ); + + sendUrgent( "Failed to spawn Chara#{0} for you - no remaining spawn slots. See world log.", actorId ); + + return index; + } + + return index; } bool Sapphire::Entity::Player::isActorSpawnIdValid( uint8_t spawnIndex ) @@ -1835,7 +1848,20 @@ void Sapphire::Entity::Player::teleportQuery( uint16_t aetheryteId, FrameworkPtr uint8_t Sapphire::Entity::Player::getNextObjSpawnIndexForActorId( uint32_t actorId ) { - return m_objSpawnIndexAllocator.getNextFreeSpawnIndex( actorId ); + auto index = m_objSpawnIndexAllocator.getNextFreeSpawnIndex( actorId ); + + if( index == m_objSpawnIndexAllocator.getAllocFailId() ) + { + Logger::warn( "Failed to spawn EObj#{0} for Player#{1} - no remaining spawn indexes available. " + "Consider lowering InRangeDistance in world config.", + actorId, getId() ); + + sendUrgent( "Failed to spawn EObj#{0} for you - no remaining spawn slots. See world log.", actorId ); + + return index; + } + + return index; } void Sapphire::Entity::Player::resetObjSpawnIndex() From 76cca8a7a507ef90210ce310a2c7f731b83fa088 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Mon, 28 Jan 2019 21:13:02 +1100 Subject: [PATCH 5/5] remove InRangeDistance config option --- config/world.ini.default | 1 - 1 file changed, 1 deletion(-) diff --git a/config/world.ini.default b/config/world.ini.default index 4dacbc65..ec461c19 100644 --- a/config/world.ini.default +++ b/config/world.ini.default @@ -10,7 +10,6 @@ HotSwap = true ListenIp = 0.0.0.0 ListenPort = 54992 DisconnectTimeout = 20 -InRangeDistance = 100.0 [General] ; Sent on login - each line must be shorter than 307 characters, split lines with ';'