2019-10-14 18:41:16 +11:00
|
|
|
#include <filesystem>
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2018-03-06 22:22:19 +01:00
|
|
|
#include <Util/Util.h>
|
|
|
|
#include <Network/PacketContainer.h>
|
|
|
|
#include <Logging/Logger.h>
|
2021-11-27 00:53:57 +01:00
|
|
|
#include <Service.h>
|
2018-03-02 07:22:25 -03:00
|
|
|
|
2017-12-08 15:38:25 +01:00
|
|
|
#include "Network/GameConnection.h"
|
2018-03-02 07:22:25 -03:00
|
|
|
#include "Actor/Player.h"
|
2021-11-27 00:53:57 +01:00
|
|
|
#include "WorldServer.h"
|
|
|
|
#include "Manager/PlayerMgr.h"
|
2018-03-02 07:22:25 -03:00
|
|
|
|
2017-08-08 13:53:47 +02:00
|
|
|
#include "Session.h"
|
|
|
|
|
2021-11-27 00:53:57 +01:00
|
|
|
using namespace Sapphire::World::Manager;
|
2019-10-14 18:41:16 +11:00
|
|
|
namespace fs = std::filesystem;
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2021-11-27 00:53:57 +01:00
|
|
|
Sapphire::World::Session::Session( uint32_t entityId ) :
|
|
|
|
m_entityId( entityId ),
|
2019-06-02 00:34:22 +10:00
|
|
|
m_lastDataTime( Common::Util::getTimeSeconds() ),
|
|
|
|
m_lastSqlTime( Common::Util::getTimeSeconds() ),
|
2018-12-25 01:57:50 +01:00
|
|
|
m_isValid( false ),
|
2021-11-27 00:53:57 +01:00
|
|
|
m_isReplaying( false ),
|
|
|
|
m_lastPing( 0 )
|
2017-08-08 13:53:47 +02:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2018-12-22 22:25:03 +01:00
|
|
|
void Sapphire::World::Session::setZoneConnection( Network::GameConnectionPtr pZoneCon )
|
2017-08-08 13:53:47 +02:00
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
pZoneCon->m_conType = Network::ConnectionType::Zone;
|
|
|
|
m_pZoneConnection = pZoneCon;
|
2017-08-08 13:53:47 +02:00
|
|
|
}
|
|
|
|
|
2018-12-22 22:25:03 +01:00
|
|
|
void Sapphire::World::Session::setChatConnection( Network::GameConnectionPtr pChatCon )
|
2017-08-20 20:48:55 +02:00
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
pChatCon->m_conType = Network::ConnectionType::Chat;
|
|
|
|
m_pChatConnection = pChatCon;
|
2017-08-20 20:48:55 +02:00
|
|
|
}
|
|
|
|
|
2018-12-22 22:25:03 +01:00
|
|
|
Sapphire::Network::GameConnectionPtr Sapphire::World::Session::getZoneConnection() const
|
2017-08-08 13:53:47 +02:00
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
return m_pZoneConnection;
|
2017-08-08 13:53:47 +02:00
|
|
|
}
|
|
|
|
|
2018-12-22 22:25:03 +01:00
|
|
|
Sapphire::Network::GameConnectionPtr Sapphire::World::Session::getChatConnection() const
|
2017-08-20 20:48:55 +02:00
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
return m_pChatConnection;
|
2017-08-20 20:48:55 +02:00
|
|
|
}
|
|
|
|
|
2018-12-22 22:25:03 +01:00
|
|
|
bool Sapphire::World::Session::loadPlayer()
|
2017-08-08 13:53:47 +02:00
|
|
|
{
|
2021-11-27 00:53:57 +01:00
|
|
|
auto& server = Common::Service< World::WorldServer >::ref();
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2021-11-27 00:53:57 +01:00
|
|
|
m_isValid = false;
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2021-11-27 00:53:57 +01:00
|
|
|
m_pPlayer = server.getPlayer( m_entityId );
|
|
|
|
|
|
|
|
if( !m_pPlayer )
|
2018-08-29 21:40:59 +02:00
|
|
|
return false;
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2021-11-27 00:53:57 +01:00
|
|
|
// check and sync player data on login
|
|
|
|
if( !server.syncPlayer( m_pPlayer->getCharacterId() ) )
|
|
|
|
return false;
|
2018-08-29 21:40:59 +02:00
|
|
|
|
2021-11-27 00:53:57 +01:00
|
|
|
m_isValid = true;
|
2018-08-29 21:40:59 +02:00
|
|
|
return true;
|
2017-08-08 13:53:47 +02:00
|
|
|
}
|
|
|
|
|
2018-12-22 22:25:03 +01:00
|
|
|
void Sapphire::World::Session::close()
|
2017-08-08 13:53:47 +02:00
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
if( m_pZoneConnection )
|
2019-03-08 09:43:56 +01:00
|
|
|
m_pZoneConnection->disconnect();
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
if( m_pChatConnection )
|
2019-03-08 09:43:56 +01:00
|
|
|
m_pChatConnection->disconnect();
|
2017-10-06 00:13:29 +02:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
// remove the session from the player
|
|
|
|
if( m_pPlayer )
|
2018-11-01 13:05:10 +01:00
|
|
|
{
|
2023-02-10 21:22:54 +01:00
|
|
|
auto& playerMgr = Common::Service< World::Manager::PlayerMgr >::ref();
|
|
|
|
playerMgr.onLogout( *m_pPlayer );
|
|
|
|
|
2021-11-27 00:53:57 +01:00
|
|
|
m_pPlayer->unload();
|
2018-11-01 13:05:10 +01:00
|
|
|
}
|
2017-08-08 13:53:47 +02:00
|
|
|
}
|
|
|
|
|
2018-12-22 22:25:03 +01:00
|
|
|
uint32_t Sapphire::World::Session::getId() const
|
2017-08-08 13:53:47 +02:00
|
|
|
{
|
2021-11-27 00:53:57 +01:00
|
|
|
return m_entityId;
|
2017-08-08 13:53:47 +02:00
|
|
|
}
|
|
|
|
|
2018-12-22 22:25:03 +01:00
|
|
|
int64_t Sapphire::World::Session::getLastDataTime() const
|
2017-08-08 13:53:47 +02:00
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
return m_lastDataTime;
|
2017-08-08 13:53:47 +02:00
|
|
|
}
|
|
|
|
|
2018-12-22 22:25:03 +01:00
|
|
|
int64_t Sapphire::World::Session::getLastSqlTime() const
|
2017-10-04 00:02:16 +02:00
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
return m_lastSqlTime;
|
2017-10-04 00:02:16 +02:00
|
|
|
}
|
|
|
|
|
2018-12-22 22:25:03 +01:00
|
|
|
bool Sapphire::World::Session::isValid() const
|
2017-10-06 12:54:03 +02:00
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
return m_isValid;
|
2017-10-06 12:54:03 +02:00
|
|
|
}
|
|
|
|
|
2018-12-22 22:25:03 +01:00
|
|
|
void Sapphire::World::Session::updateLastDataTime()
|
2017-08-08 13:53:47 +02:00
|
|
|
{
|
2019-06-02 00:34:22 +10:00
|
|
|
m_lastDataTime = Common::Util::getTimeSeconds();
|
2017-10-04 00:02:16 +02:00
|
|
|
}
|
|
|
|
|
2018-12-22 22:25:03 +01:00
|
|
|
void Sapphire::World::Session::updateLastSqlTime()
|
2017-10-04 00:02:16 +02:00
|
|
|
{
|
2019-06-02 00:34:22 +10:00
|
|
|
m_lastSqlTime = Common::Util::getTimeSeconds();
|
2017-08-08 13:53:47 +02:00
|
|
|
}
|
|
|
|
|
2018-12-22 22:25:03 +01:00
|
|
|
void Sapphire::World::Session::startReplay( const std::string& path )
|
2018-01-08 21:42:44 +01:00
|
|
|
{
|
2018-10-25 13:38:06 +11:00
|
|
|
if( !fs::exists( path ) )
|
2018-08-29 21:40:59 +02:00
|
|
|
{
|
2023-02-10 21:22:54 +01:00
|
|
|
PlayerMgr::sendDebug( *getPlayer(), "Couldn't find folder {}.", path );
|
2018-08-29 21:40:59 +02:00
|
|
|
return;
|
|
|
|
}
|
2018-01-08 21:42:44 +01:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
m_replayCache.clear();
|
2018-01-08 21:42:44 +01:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
std::vector< std::tuple< uint64_t, std::string > > loadedSets;
|
2018-01-08 21:42:44 +01:00
|
|
|
|
2018-10-25 13:38:06 +11:00
|
|
|
for( auto it = fs::directory_iterator( fs::path( path ) );
|
|
|
|
it != fs::directory_iterator(); ++it )
|
2018-08-29 21:40:59 +02:00
|
|
|
{
|
|
|
|
// Get the filename of the current element
|
|
|
|
auto fileName = it->path().filename().string();
|
2023-02-10 21:22:54 +01:00
|
|
|
auto unixTime = std::stoull( fileName.substr( 0, 14 ) );
|
2018-01-08 21:42:44 +01:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
if( unixTime > 1000000000 )
|
|
|
|
{
|
2023-02-10 21:22:54 +01:00
|
|
|
loadedSets.emplace_back( unixTime, it->path().string() );
|
2018-08-29 21:40:59 +02:00
|
|
|
}
|
|
|
|
}
|
2018-01-08 21:42:44 +01:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
sort( loadedSets.begin(), loadedSets.end(),
|
|
|
|
[]( const std::tuple< uint64_t, std::string >& left, const std::tuple< uint64_t, std::string >& right )
|
|
|
|
{
|
|
|
|
return std::get< 0 >( left ) < std::get< 0 >( right );
|
|
|
|
} );
|
2018-01-08 21:42:44 +01:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
uint64_t startTime = std::get< 0 >( loadedSets.at( 0 ) );
|
2018-01-08 21:42:44 +01:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
for( auto set : loadedSets )
|
|
|
|
{
|
2023-02-10 21:22:54 +01:00
|
|
|
m_replayCache.emplace_back( Common::Util::getTimeMs() + ( std::get< 0 >( set ) - startTime ), std::get< 1 >( set ) );
|
2018-01-08 23:38:27 +01:00
|
|
|
|
2019-01-04 12:34:19 +01:00
|
|
|
Logger::info( "Registering {0} for {1}", std::get< 1 >( set ), std::get< 0 >( set ) - startTime );
|
2018-08-29 21:40:59 +02:00
|
|
|
}
|
2018-01-08 21:42:44 +01:00
|
|
|
|
2021-11-27 00:53:57 +01:00
|
|
|
PlayerMgr::sendDebug( *getPlayer(), "Registered {0} sets for replay" ), m_replayCache.size();
|
2018-08-29 21:40:59 +02:00
|
|
|
m_isReplaying = true;
|
2018-01-08 21:42:44 +01:00
|
|
|
}
|
|
|
|
|
2018-12-22 22:25:03 +01:00
|
|
|
void Sapphire::World::Session::stopReplay()
|
2018-01-08 21:42:44 +01:00
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
m_isReplaying = false;
|
|
|
|
m_replayCache.clear();
|
2018-01-08 21:42:44 +01:00
|
|
|
}
|
|
|
|
|
2018-12-22 22:25:03 +01:00
|
|
|
void Sapphire::World::Session::processReplay()
|
2017-08-08 13:53:47 +02:00
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
int at = 0;
|
|
|
|
for( const auto& set : m_replayCache )
|
|
|
|
{
|
2019-06-02 00:34:22 +10:00
|
|
|
if( std::get< 0 >( set ) <= Common::Util::getTimeMs() )
|
2018-08-29 21:40:59 +02:00
|
|
|
{
|
|
|
|
m_pZoneConnection->injectPacket( std::get< 1 >( set ), *getPlayer().get() );
|
|
|
|
m_replayCache.erase( m_replayCache.begin() + at );
|
|
|
|
//g_framework.getLogger().info( "Sent for " + std::to_string( std::get< 0 >( set ) ) + ", left: " + std::to_string( m_replayCache.size() ) );
|
|
|
|
}
|
|
|
|
at++;
|
|
|
|
}
|
2018-01-09 18:54:09 +01:00
|
|
|
|
2023-02-10 21:22:54 +01:00
|
|
|
if( m_replayCache.empty() )
|
2018-08-29 21:40:59 +02:00
|
|
|
m_isReplaying = false;
|
2018-01-09 18:54:09 +01:00
|
|
|
}
|
|
|
|
|
2018-12-22 22:25:03 +01:00
|
|
|
void Sapphire::World::Session::sendReplayInfo()
|
2018-01-09 18:54:09 +01:00
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
std::string message = std::to_string( m_replayCache.size() ) + " Sets left in cache, ";
|
2018-01-09 18:54:09 +01:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
if( m_isReplaying )
|
|
|
|
message += " is active";
|
|
|
|
else
|
|
|
|
message += " is idle";
|
2018-01-09 18:54:09 +01:00
|
|
|
|
2021-11-27 00:53:57 +01:00
|
|
|
PlayerMgr::sendDebug( *getPlayer(), message );
|
2018-01-08 23:38:27 +01:00
|
|
|
}
|
|
|
|
|
2018-12-22 22:25:03 +01:00
|
|
|
void Sapphire::World::Session::update()
|
2018-01-08 23:38:27 +01:00
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
if( m_isReplaying )
|
|
|
|
processReplay();
|
|
|
|
|
|
|
|
if( m_pZoneConnection )
|
|
|
|
{
|
|
|
|
m_pZoneConnection->processInQueue();
|
2018-01-08 21:42:44 +01:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
// SESSION LOGIC
|
2019-06-02 00:34:22 +10:00
|
|
|
m_pPlayer->update( Common::Util::getTimeMs() );
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2019-06-02 00:34:22 +10:00
|
|
|
if( Common::Util::getTimeSeconds() - static_cast< uint32_t >( getLastSqlTime() ) > 10 )
|
2018-08-29 21:40:59 +02:00
|
|
|
{
|
|
|
|
updateLastSqlTime();
|
|
|
|
m_pPlayer->updateSql();
|
|
|
|
}
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
m_pZoneConnection->processOutQueue();
|
|
|
|
}
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
if( m_pChatConnection )
|
|
|
|
{
|
|
|
|
m_pChatConnection->processInQueue();
|
|
|
|
m_pChatConnection->processOutQueue();
|
|
|
|
}
|
2017-08-20 20:48:55 +02:00
|
|
|
|
2017-08-08 13:53:47 +02:00
|
|
|
}
|
|
|
|
|
2018-12-22 22:25:03 +01:00
|
|
|
Sapphire::Entity::PlayerPtr Sapphire::World::Session::getPlayer() const
|
2017-08-08 13:53:47 +02:00
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
return m_pPlayer;
|
2017-08-08 13:53:47 +02:00
|
|
|
}
|
|
|
|
|
2021-11-27 00:53:57 +01:00
|
|
|
void Sapphire::World::Session::setLastPing( uint32_t ping )
|
|
|
|
{
|
|
|
|
m_lastPing = ping;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t Sapphire::World::Session::getLastPing() const
|
|
|
|
{
|
|
|
|
return m_lastPing;
|
|
|
|
}
|