mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-04-27 14:57:44 +00:00
Merge pull request #512 from NotAdam/develop
Fix player despawning in the event an actor isn't found in the spawned list
This commit is contained in:
commit
b3dc663b5c
8 changed files with 58 additions and 8 deletions
|
@ -44,6 +44,8 @@ namespace Sapphire::Common::Config
|
||||||
uint16_t listenPort;
|
uint16_t listenPort;
|
||||||
|
|
||||||
uint16_t disconnectTimeout;
|
uint16_t disconnectTimeout;
|
||||||
|
|
||||||
|
float inRangeDistance;
|
||||||
} network;
|
} network;
|
||||||
|
|
||||||
struct Housing
|
struct Housing
|
||||||
|
|
|
@ -37,7 +37,7 @@ namespace Sapphire::Util
|
||||||
{
|
{
|
||||||
auto it = m_actorIdToAllocatedMap.find( actorId );
|
auto it = m_actorIdToAllocatedMap.find( actorId );
|
||||||
if( it == m_actorIdToAllocatedMap.end() )
|
if( it == m_actorIdToAllocatedMap.end() )
|
||||||
return 0;
|
return getAllocFailId();
|
||||||
|
|
||||||
auto index = it->second;
|
auto index = it->second;
|
||||||
m_availableIds.push( index );
|
m_availableIds.push( index );
|
||||||
|
|
|
@ -534,7 +534,20 @@ void Sapphire::Entity::Player::initSpawnIdQueue()
|
||||||
|
|
||||||
uint8_t Sapphire::Entity::Player::getSpawnIdForActorId( uint32_t actorId )
|
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 )
|
bool Sapphire::Entity::Player::isActorSpawnIdValid( uint8_t spawnIndex )
|
||||||
|
@ -1127,11 +1140,14 @@ void Sapphire::Entity::Player::freePlayerSpawnId( uint32_t actorId )
|
||||||
{
|
{
|
||||||
auto spawnId = m_actorSpawnIndexAllocator.freeUsedSpawnIndex( 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() );
|
auto freeActorSpawnPacket = makeZonePacket< FFXIVIpcActorFreeSpawn >( getId() );
|
||||||
freeActorSpawnPacket->data().actorId = actorId;
|
freeActorSpawnPacket->data().actorId = actorId;
|
||||||
freeActorSpawnPacket->data().spawnId = spawnId;
|
freeActorSpawnPacket->data().spawnId = spawnId;
|
||||||
queuePacket( freeActorSpawnPacket );
|
queuePacket( freeActorSpawnPacket );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t* Sapphire::Entity::Player::getAetheryteArray()
|
uint8_t* Sapphire::Entity::Player::getAetheryteArray()
|
||||||
|
@ -1832,7 +1848,20 @@ void Sapphire::Entity::Player::teleportQuery( uint16_t aetheryteId, FrameworkPtr
|
||||||
|
|
||||||
uint8_t Sapphire::Entity::Player::getNextObjSpawnIndexForActorId( uint32_t actorId )
|
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()
|
void Sapphire::Entity::Player::resetObjSpawnIndex()
|
||||||
|
@ -1844,6 +1873,10 @@ void Sapphire::Entity::Player::freeObjSpawnIndexForActorId( uint32_t actorId )
|
||||||
{
|
{
|
||||||
auto spawnId = m_objSpawnIndexAllocator.freeUsedSpawnIndex( 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() );
|
auto freeObjectSpawnPacket = makeZonePacket< FFXIVIpcObjectDespawn >( getId() );
|
||||||
freeObjectSpawnPacket->data().spawnIndex = spawnId;
|
freeObjectSpawnPacket->data().spawnIndex = spawnId;
|
||||||
queuePacket( freeObjectSpawnPacket );
|
queuePacket( freeObjectSpawnPacket );
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
#include <Database/DatabaseDef.h>
|
#include <Database/DatabaseDef.h>
|
||||||
#include <Exd/ExdDataGenerated.h>
|
#include <Exd/ExdDataGenerated.h>
|
||||||
|
|
||||||
|
#include "ServerMgr.h"
|
||||||
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
#include "Actor/Player.h"
|
#include "Actor/Player.h"
|
||||||
|
@ -59,6 +61,10 @@ bool Sapphire::World::Manager::TerritoryMgr::init()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto& cfg = framework()->get< World::ServerMgr >()->getConfig();
|
||||||
|
|
||||||
|
m_inRangeDistance = cfg.network.inRangeDistance;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -584,5 +590,9 @@ void Sapphire::World::Manager::TerritoryMgr::disableCurrentFestival()
|
||||||
setCurrentFestival( 0 );
|
setCurrentFestival( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float Sapphire::World::Manager::TerritoryMgr::getInRangeDistance() const
|
||||||
|
{
|
||||||
|
return m_inRangeDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -155,6 +155,8 @@ namespace Sapphire::World::Manager
|
||||||
*/
|
*/
|
||||||
const std::pair< uint16_t, uint16_t >& getCurrentFestival() const;
|
const std::pair< uint16_t, uint16_t >& getCurrentFestival() const;
|
||||||
|
|
||||||
|
float getInRangeDistance() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using TerritoryTypeDetailCache = std::unordered_map< uint16_t, Data::TerritoryTypePtr >;
|
using TerritoryTypeDetailCache = std::unordered_map< uint16_t, Data::TerritoryTypePtr >;
|
||||||
using InstanceIdToZonePtrMap = std::unordered_map< uint32_t, ZonePtr >;
|
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 */
|
/*! current festival(s) to set for public zones from festival.exd */
|
||||||
std::pair< uint16_t, uint16_t > m_currentFestival;
|
std::pair< uint16_t, uint16_t > m_currentFestival;
|
||||||
|
|
||||||
|
/*! Max distance at which actors in range of a player are sent */
|
||||||
|
float m_inRangeDistance;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*! returns a list of instanceContent InstanceIds currently active */
|
/*! returns a list of instanceContent InstanceIds currently active */
|
||||||
InstanceIdList getInstanceContentIdList( uint16_t instanceContentId ) const;
|
InstanceIdList getInstanceContentIdList( uint16_t instanceContentId ) const;
|
||||||
|
|
|
@ -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.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.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.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", "" );
|
m_config.motd = pConfig->getValue< std::string >( "General", "MotD", "" );
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
#define TilesCount 32
|
#define TilesCount 32
|
||||||
#define TileSize 250.0f
|
#define TileSize 325.0f
|
||||||
#define _minY (-TilesCount*TileSize/2)
|
#define _minY (-TilesCount*TileSize/2)
|
||||||
#define _minX (-TilesCount*TileSize/2)
|
#define _minX (-TilesCount*TileSize/2)
|
||||||
|
|
||||||
|
|
|
@ -645,7 +645,7 @@ void Sapphire::Zone::updateInRangeSet( Entity::ActorPtr pActor, Cell* pCell )
|
||||||
|
|
||||||
auto iter = pCell->m_actors.begin();
|
auto iter = pCell->m_actors.begin();
|
||||||
|
|
||||||
float fRange = 70.0f;
|
float fRange = pTeriMgr->getInRangeDistance();
|
||||||
int32_t count = 0;
|
int32_t count = 0;
|
||||||
while( iter != pCell->m_actors.end() )
|
while( iter != pCell->m_actors.end() )
|
||||||
{
|
{
|
||||||
|
@ -655,8 +655,7 @@ void Sapphire::Zone::updateInRangeSet( Entity::ActorPtr pActor, Cell* pCell )
|
||||||
if( !pCurAct || pCurAct == pActor )
|
if( !pCurAct || pCurAct == pActor )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
float distance = Util::distance( pCurAct->getPos().x, pCurAct->getPos().y, pCurAct->getPos().z,
|
float distance = Util::distance( pCurAct->getPos(), pActor->getPos() );
|
||||||
pActor->getPos().x, pActor->getPos().y, pActor->getPos().z );
|
|
||||||
|
|
||||||
bool isInRange = ( fRange == 0.0f || distance <= fRange );
|
bool isInRange = ( fRange == 0.0f || distance <= fRange );
|
||||||
bool isInRangeSet = pActor->isInRangeSet( pCurAct );
|
bool isInRangeSet = pActor->isInRangeSet( pCurAct );
|
||||||
|
|
Loading…
Add table
Reference in a new issue