2022-11-19 01:49:36 +00:00
# include "player_database_service.hpp"
2023-03-01 21:27:15 +00:00
2023-05-01 23:23:07 +02:00
# include "backend/bool_command.hpp"
2022-11-19 01:49:36 +00:00
# include "file_manager.hpp"
2023-02-21 11:52:05 +01:00
# include "pointers.hpp"
2023-03-01 21:27:15 +00:00
# include "util/session.hpp"
2022-11-19 01:49:36 +00:00
namespace big
{
2023-05-01 23:23:07 +02:00
bool_command g_player_db_auto_update_online_states ( " player_db_auto_update_states " , " Auto Update Player Online States " , " Toggling this feature will automatically update the player online states every 5minutes. " ,
g . player_db . update_player_online_states ) ;
2022-11-19 01:49:36 +00:00
player_database_service : : player_database_service ( ) :
2023-03-01 21:27:15 +00:00
m_file_path ( g_file_manager - > get_project_file ( " ./players.json " ) . get_path ( ) )
2022-11-19 01:49:36 +00:00
{
load ( ) ;
g_player_database_service = this ;
}
player_database_service : : ~ player_database_service ( )
{
g_player_database_service = nullptr ;
}
void player_database_service : : save ( )
{
nlohmann : : json json ;
2023-03-01 21:27:15 +00:00
2022-11-19 01:49:36 +00:00
for ( auto & [ rid , player ] : m_players )
{
json [ std : : to_string ( rid ) ] = player ;
}
std : : ofstream file_stream ( m_file_path ) ;
file_stream < < json ;
}
void player_database_service : : load ( )
{
m_selected = nullptr ;
if ( std : : filesystem : : exists ( m_file_path ) )
{
std : : ifstream file_stream ( m_file_path ) ;
nlohmann : : json json ;
file_stream > > json ;
file_stream . close ( ) ;
2023-05-01 23:23:07 +02:00
for ( auto & [ key , value ] : json . items ( ) )
2022-11-19 01:49:36 +00:00
{
2023-05-01 23:23:07 +02:00
auto player = value . get < std : : shared_ptr < persistent_player > > ( ) ;
m_players [ std : : stoll ( key ) ] = player ;
std : : string lower = player - > name ;
std : : transform ( lower . begin ( ) , lower . end ( ) , lower . begin ( ) , : : tolower ) ;
m_sorted_players [ lower ] = player ;
2022-11-19 01:49:36 +00:00
}
}
}
2023-05-01 23:23:07 +02:00
std : : unordered_map < std : : uint64_t , std : : shared_ptr < persistent_player > > & player_database_service : : get_players ( )
2022-11-19 01:49:36 +00:00
{
return m_players ;
}
2023-05-01 23:23:07 +02:00
std : : map < std : : string , std : : shared_ptr < persistent_player > > & player_database_service : : get_sorted_players ( )
{
return m_sorted_players ;
}
std : : shared_ptr < persistent_player > player_database_service : : add_player ( std : : int64_t rid , const std : : string_view name )
{
std : : string lower = name . data ( ) ;
std : : transform ( lower . begin ( ) , lower . end ( ) , lower . begin ( ) , : : tolower ) ;
if ( m_players . contains ( rid ) )
{
m_sorted_players . erase ( lower ) ;
}
auto player = std : : make_shared < persistent_player > ( name . data ( ) , rid ) ;
m_players [ rid ] = player ;
m_sorted_players [ lower ] = player ;
return player ;
}
std : : shared_ptr < persistent_player > player_database_service : : get_player_by_rockstar_id ( std : : uint64_t rockstar_id )
2022-11-19 01:49:36 +00:00
{
if ( m_players . contains ( rockstar_id ) )
2023-05-01 23:23:07 +02:00
return m_players [ rockstar_id ] ;
2022-11-19 01:49:36 +00:00
return nullptr ;
}
2023-05-01 23:23:07 +02:00
std : : shared_ptr < persistent_player > player_database_service : : get_or_create_player ( player_ptr player )
2022-11-19 01:49:36 +00:00
{
2023-02-04 16:35:18 +00:00
if ( m_players . contains ( player - > get_net_data ( ) - > m_gamer_handle . m_rockstar_id ) )
2023-05-01 23:23:07 +02:00
return m_players [ player - > get_net_data ( ) - > m_gamer_handle . m_rockstar_id ] ;
2022-11-19 01:49:36 +00:00
else
{
2023-05-01 23:23:07 +02:00
auto player_ptr = add_player ( player - > get_net_data ( ) - > m_gamer_handle . m_rockstar_id , player - > get_name ( ) ) ;
2022-11-19 01:49:36 +00:00
save ( ) ;
2023-05-01 23:23:07 +02:00
return player_ptr ;
2022-11-19 01:49:36 +00:00
}
}
void player_database_service : : update_rockstar_id ( std : : uint64_t old , std : : uint64_t _new )
{
2023-03-01 21:27:15 +00:00
auto player = m_players . extract ( old ) ;
2022-11-19 01:49:36 +00:00
player . key ( ) = _new ;
m_players . insert ( std : : move ( player ) ) ;
}
void player_database_service : : remove_rockstar_id ( std : : uint64_t rockstar_id )
{
if ( m_selected & & m_selected - > rockstar_id = = rockstar_id )
m_selected = nullptr ;
2023-05-01 23:23:07 +02:00
if ( auto it = m_players . find ( rockstar_id ) ; it ! = m_players . end ( ) )
{
std : : string lower = it - > second - > name ;
std : : transform ( lower . begin ( ) , lower . end ( ) , lower . begin ( ) , : : tolower ) ;
m_sorted_players . erase ( lower ) ;
m_players . erase ( it ) ;
}
2022-11-19 01:49:36 +00:00
}
2023-05-01 23:23:07 +02:00
void player_database_service : : set_selected ( std : : shared_ptr < persistent_player > selected )
2022-11-19 01:49:36 +00:00
{
m_selected = selected ;
}
2023-05-01 23:23:07 +02:00
std : : shared_ptr < persistent_player > player_database_service : : get_selected ( )
2022-11-19 01:49:36 +00:00
{
return m_selected ;
}
2023-02-21 11:52:05 +01:00
2023-05-01 23:23:07 +02:00
void player_database_service : : start_update_loop ( )
{
if ( ! g . player_db . update_player_online_states )
return ;
g_thread_pool - > push ( [ this ] {
static auto last_update = std : : chrono : : high_resolution_clock : : now ( ) - 5 min ;
while ( g_running & & g . player_db . update_player_online_states )
{
const auto cur = std : : chrono : : high_resolution_clock : : now ( ) ;
if ( cur - last_update > 5 min )
{
g_fiber_pool - > queue_job ( [ this ] {
update_player_states ( ) ;
} ) ;
last_update = cur ;
}
std : : this_thread : : sleep_for ( 1 s ) ;
}
} ) ;
2023-02-21 11:52:05 +01:00
}
void player_database_service : : update_player_states ( )
{
2023-05-01 23:23:07 +02:00
const auto player_count = m_players . size ( ) ;
2023-02-21 11:52:05 +01:00
2023-05-01 23:23:07 +02:00
std : : vector < std : : vector < rage : : rlGamerHandle > > gamer_handle_buckets ;
gamer_handle_buckets . resize ( std : : ceil ( player_count / 32.f ) ) ;
auto it = m_players . begin ( ) ;
for ( size_t i = 0 ; i < player_count ; + + i )
{
gamer_handle_buckets [ i / 32 ] . push_back ( it - > second - > rockstar_id ) ;
it + + ;
}
for ( auto & bucket : gamer_handle_buckets )
2023-02-21 11:52:05 +01:00
{
2023-05-01 23:23:07 +02:00
rage : : rlTaskStatus status ;
std : : array < int , 32 > online ;
2023-02-21 11:52:05 +01:00
2023-05-01 23:23:07 +02:00
if ( g_pointers - > m_gta . m_get_gamer_online_state ( 0 , bucket . data ( ) , bucket . size ( ) , online . data ( ) , & status ) )
2023-02-21 11:52:05 +01:00
{
2023-05-01 23:23:07 +02:00
while ( status . status = = 1 )
{
2023-02-21 11:52:05 +01:00
script : : get_current ( ) - > yield ( ) ;
2023-05-01 23:23:07 +02:00
}
2023-02-21 11:52:05 +01:00
2023-05-01 23:23:07 +02:00
for ( size_t i = 0 ; i < bucket . size ( ) ; + + i )
2023-02-21 11:52:05 +01:00
{
2023-05-01 23:23:07 +02:00
if ( const auto & it = m_players . find ( bucket [ i ] . m_rockstar_id ) ; it ! = m_players . end ( ) )
{
if ( online [ i ] = = 1 )
2023-06-06 13:37:45 +02:00
{
if ( it - > second - > online_state = = PlayerOnlineStatus : : OFFLINE & & it - > second - > notify_online )
{
g_notification_service - > push_success ( " Player DB " , std : : format ( " {} is now online! " , it - > second - > name ) ) ;
}
2023-05-01 23:23:07 +02:00
it - > second - > online_state = PlayerOnlineStatus : : ONLINE ;
2023-06-06 13:37:45 +02:00
continue ;
}
it - > second - > online_state = PlayerOnlineStatus : : OFFLINE ;
2023-05-01 23:23:07 +02:00
}
2023-02-21 11:52:05 +01:00
}
}
}
}
2022-11-19 01:49:36 +00:00
}