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-07-14 09:02:47 +00:00
# include "gta/enums.hpp"
2023-07-15 20:37:20 +00:00
# include "hooking.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-07-15 20:37:20 +00:00
bool_command g_player_db_auto_update_online_states ( " player_db_auto_update_states " , " Auto Update Tracked Player States " , " Toggling this feature will automatically update the tracked players' online states every minute. You must enable this for join redirect to work " ,
2023-05-01 23:23:07 +02:00
g . player_db . update_player_online_states ) ;
2023-07-15 20:37:20 +00:00
const char * player_database_service : : get_name_by_content_id ( const std : : string & content_id )
{
if ( NETWORK : : UGC_QUERY_BY_CONTENT_ID ( content_id . c_str ( ) , false , " gta5mission " ) )
{
while ( NETWORK : : UGC_IS_GETTING ( ) )
script : : get_current ( ) - > yield ( ) ;
if ( ! NETWORK : : UGC_DID_GET_SUCCEED ( ) )
return " " ;
return NETWORK : : UGC_GET_CONTENT_NAME ( 0 ) ;
}
return " " ;
}
2023-07-14 09:02:47 +00:00
void player_database_service : : handle_session_type_change ( persistent_player & player , GSType new_session_type )
{
if ( ! player . notify_online )
return ;
if ( g . player_db . notify_when_joinable & & ! is_joinable_session ( player . session_type ) & & is_joinable_session ( new_session_type ) )
{
g_notification_service - > push_success ( " Player DB " , std : : format ( " {} is now in a joinable session " , player . name ) ) ;
}
else if ( g . player_db . notify_when_online & & ( player . session_type = = GSType : : Invalid | | player . session_type = = GSType : : Unknown ) & & new_session_type ! = GSType : : Invalid )
{
g_notification_service - > push_success ( " Player DB " , std : : format ( " {} is now online " , player . name ) ) ;
}
else if ( g . player_db . notify_when_unjoinable & & is_joinable_session ( player . session_type ) & & ! is_joinable_session ( new_session_type ) & & new_session_type ! = GSType : : Invalid )
{
g_notification_service - > push ( " Player DB " , std : : format ( " {} is no longer in a joinable session " , player . name ) ) ;
}
else if ( g . player_db . notify_when_offline & & player . session_type ! = GSType : : Invalid & & player . session_type ! = GSType : : Unknown & & new_session_type = = GSType : : Invalid )
{
g_notification_service - > push ( " Player DB " , std : : format ( " {} is no longer online " , player . name ) ) ;
}
if ( g . player_db . notify_on_session_type_change & & ( int ) new_session_type > = ( int ) GSType : : InviteOnly & & ( int ) new_session_type < ( int ) GSType : : Max )
{
g_notification_service - > push ( " Player DB " , std : : format ( " {} is now in a{} {} session " , player . name , new_session_type = = GSType : : InviteOnly ? " n " : " " , get_session_type_str ( new_session_type ) ) ) ;
}
}
2023-07-20 22:46:32 +02:00
void player_database_service : : handle_game_mode_change ( uint64_t rid , GameMode old_game_mode , GameMode new_game_mode , std : : string mission_id , std : : string mission_name )
2023-07-15 20:37:20 +00:00
{
const char * old_game_mode_str = get_game_mode_str ( old_game_mode ) ;
const char * new_game_mode_str = get_game_mode_str ( new_game_mode ) ;
auto player = g_player_database_service - > get_player_by_rockstar_id ( rid ) ;
if ( new_game_mode = = GameMode : : None & & old_game_mode ! = GameMode : : None & & old_game_mode_str ! = " None " )
{
g_notification_service - > push ( " Player DB " , std : : format ( " {} is no longer in a {} " , player - > name , old_game_mode_str ) ) ;
return ;
}
if ( ! can_fetch_name ( new_game_mode ) )
{
if ( new_game_mode_str ! = " None " )
g_notification_service - > push ( " Player DB " , std : : format ( " {} is now in a {} " , player - > name , new_game_mode_str ) ) ;
return ;
}
if ( mission_name . empty ( ) )
{
mission_name = get_name_by_content_id ( mission_id ) ;
}
if ( mission_name . empty ( ) )
{
g_notification_service - > push ( " Player DB " , std : : format ( " {} is now in a {} " , player - > name , new_game_mode_str ) ) ;
return ;
}
g_notification_service - > push ( " Player DB " , std : : format ( " {} has joined the {} \" {} \" " , player - > name , new_game_mode_str , mission_name ) ) ;
player - > game_mode_name = mission_name ;
}
void player_database_service : : handle_join_redirect ( )
{
if ( ! * g_pointers - > m_gta . m_presence_data )
return ;
int current_preference_level = 0 ;
rage : : rlSessionInfo preferred_session { } ;
for ( auto & player : m_players )
{
if ( player . second - > join_redirect & & is_joinable_session ( player . second - > session_type )
& & current_preference_level < player . second - > join_redirect_preference )
{
current_preference_level = player . second - > join_redirect_preference ;
preferred_session = player . second - > redirect_info ;
}
}
if ( current_preference_level ! = 0 )
{
join_being_redirected = true ;
char buf [ 0x100 ] { } ;
g_pointers - > m_gta . m_encode_session_info ( & preferred_session , buf , 0xA9 , nullptr ) ;
g_hooking - > get_original < hooks : : update_presence_attribute_string > ( ) ( * g_pointers - > m_gta . m_presence_data , 0 , ( char * ) " gsinfo " , buf ) ;
g_hooking - > get_original < hooks : : update_presence_attribute_int > ( ) ( * g_pointers - > m_gta . m_presence_data ,
0 ,
( char * ) " gstok " ,
preferred_session . m_session_token ) ;
g_hooking - > get_original < hooks : : update_presence_attribute_int > ( ) ( * g_pointers - > m_gta . m_presence_data ,
0 ,
( char * ) " gsid " ,
preferred_session . m_unk ) ;
g_hooking - > get_original < hooks : : update_presence_attribute_int > ( ) ( * g_pointers - > m_gta . m_presence_data , 0 , ( char * ) " gstype " , 5 ) ;
g_hooking - > get_original < hooks : : update_presence_attribute_int > ( ) ( * g_pointers - > m_gta . m_presence_data , 0 , ( char * ) " gshost " , 0 ) ;
g_hooking - > get_original < hooks : : update_presence_attribute_int > ( ) ( * g_pointers - > m_gta . m_presence_data , 0 , ( char * ) " gsjoin " , 1 ) ;
}
else
{
join_being_redirected = false ;
}
}
2022-11-19 01:49:36 +00:00
player_database_service : : player_database_service ( ) :
2023-07-08 17:54:59 +02:00
m_file_path ( g_file_manager . get_project_file ( " ./players.json " ) . get_path ( ) )
2022-11-19 01:49:36 +00:00
{
load ( ) ;
2023-09-18 23:13:46 +02:00
start_update_loop ( ) ;
2022-11-19 01:49:36 +00:00
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 ) )
{
2023-07-01 22:25:40 +00:00
try
{
std : : ifstream file_stream ( m_file_path ) ;
2022-11-19 01:49:36 +00:00
2023-07-01 22:25:40 +00:00
nlohmann : : json json ;
file_stream > > json ;
file_stream . close ( ) ;
2022-11-19 01:49:36 +00:00
2023-07-01 22:25:40 +00:00
for ( auto & [ key , value ] : json . items ( ) )
{
auto player = value . get < std : : shared_ptr < persistent_player > > ( ) ;
m_players [ std : : stoll ( key ) ] = player ;
2023-05-01 23:23:07 +02:00
2023-07-01 22:25:40 +00:00
std : : string lower = player - > name ;
std : : transform ( lower . begin ( ) , lower . end ( ) , lower . begin ( ) , : : tolower ) ;
m_sorted_players [ lower ] = player ;
}
}
catch ( std : : exception & e )
{
LOG ( WARNING ) < < " Failed to load player database file. " < < e . what ( ) ;
2022-11-19 01:49:36 +00:00
}
}
}
2023-07-20 22:46:32 +02:00
std : : unordered_map < 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 ;
}
2023-07-20 22:46:32 +02:00
std : : shared_ptr < persistent_player > player_database_service : : get_player_by_rockstar_id ( 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
}
}
2023-07-20 22:46:32 +02:00
void player_database_service : : update_rockstar_id ( uint64_t old , uint64_t _new )
2022-11-19 01:49:36 +00:00
{
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 ) ) ;
}
2023-07-20 22:46:32 +02:00
void player_database_service : : remove_rockstar_id ( uint64_t rockstar_id )
2022-11-19 01:49:36 +00:00
{
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 ( )
{
g_thread_pool - > push ( [ this ] {
2023-09-18 23:13:46 +02:00
while ( ! g_running )
std : : this_thread : : yield ( ) ;
2023-07-14 09:02:47 +00:00
static auto last_update = std : : chrono : : high_resolution_clock : : now ( ) - 45 s ;
2023-09-18 23:13:46 +02:00
while ( g_running )
2023-05-01 23:23:07 +02:00
{
2023-09-18 23:13:46 +02:00
if ( g . player_db . update_player_online_states )
2023-05-01 23:23:07 +02:00
{
2023-09-18 23:13:46 +02:00
const auto cur = std : : chrono : : high_resolution_clock : : now ( ) ;
if ( cur - last_update > 45 s & & ! updating )
{
updating = true ;
g_fiber_pool - > queue_job ( [ this ] {
update_player_states ( true ) ;
updating = false ;
last_update = std : : chrono : : high_resolution_clock : : now ( ) ;
} ) ;
}
2023-05-01 23:23:07 +02:00
}
std : : this_thread : : sleep_for ( 1 s ) ;
}
} ) ;
2023-02-21 11:52:05 +01:00
}
2023-07-14 09:02:47 +00:00
void player_database_service : : update_player_states ( bool tracked_only )
2023-02-21 11:52:05 +01:00
{
2023-07-14 09:02:47 +00:00
constexpr auto bucket_size = 100 ;
2023-02-21 11:52:05 +01:00
2023-07-15 20:37:20 +00:00
std : : vector < std : : vector < rage : : rlScHandle > > gamer_handle_buckets { } ;
2023-05-01 23:23:07 +02:00
2023-07-14 09:02:47 +00:00
size_t i = 0 ;
for ( auto & player : m_players )
2023-05-01 23:23:07 +02:00
{
2023-07-15 20:37:20 +00:00
if ( ! tracked_only | | ( player . second - > notify_online | | player . second - > join_redirect ) )
2023-07-14 09:02:47 +00:00
{
2023-07-15 20:37:20 +00:00
if ( gamer_handle_buckets . size ( ) < = i / bucket_size )
gamer_handle_buckets . push_back ( { } ) ;
if ( player . second - > rockstar_id = = 0 | | ( ( int64_t ) player . second - > rockstar_id ) < 0 )
continue ;
2023-07-14 09:02:47 +00:00
gamer_handle_buckets [ i / bucket_size ] . push_back ( player . second - > rockstar_id ) ;
i + + ;
}
2023-05-01 23:23:07 +02:00
}
2023-07-14 09:02:47 +00:00
if ( i = = 0 )
return ;
2023-05-01 23:23:07 +02:00
for ( auto & bucket : gamer_handle_buckets )
2023-02-21 11:52:05 +01:00
{
2023-09-20 12:48:44 +00:00
rage : : rlScTaskStatus status { } ;
2023-07-15 20:37:20 +00:00
rage : : rlQueryPresenceAttributesContext contexts [ bucket_size ] [ 9 ] { } ;
2023-07-14 09:02:47 +00:00
rage : : rlQueryPresenceAttributesContext * contexts_per_player [ bucket_size ] { } ;
2023-02-21 11:52:05 +01:00
2023-07-15 20:37:20 +00:00
for ( int i = 0 ; i < bucket . size ( ) ; i + + )
2023-07-14 09:02:47 +00:00
{
2023-07-15 20:37:20 +00:00
contexts [ i ] [ 0 ] . m_presence_attibute_type = 1 ;
2023-07-14 09:02:47 +00:00
strcpy ( contexts [ i ] [ 0 ] . m_presence_attribute_key , " gstype " ) ;
2023-07-15 20:37:20 +00:00
contexts [ i ] [ 0 ] . m_presence_attribute_int_value = - 1 ;
contexts [ i ] [ 1 ] . m_presence_attibute_type = 3 ;
2023-07-14 09:02:47 +00:00
strcpy ( contexts [ i ] [ 1 ] . m_presence_attribute_key , " gsinfo " ) ;
2023-07-15 20:37:20 +00:00
contexts [ i ] [ 2 ] . m_presence_attibute_type = 1 ;
strcpy ( contexts [ i ] [ 2 ] . m_presence_attribute_key , " sctv " ) ;
contexts [ i ] [ 3 ] . m_presence_attibute_type = 1 ;
strcpy ( contexts [ i ] [ 3 ] . m_presence_attribute_key , " gshost " ) ;
contexts [ i ] [ 4 ] . m_presence_attibute_type = 3 ;
strcpy ( contexts [ i ] [ 4 ] . m_presence_attribute_key , " trinfo " ) ;
contexts [ i ] [ 5 ] . m_presence_attibute_type = 1 ;
strcpy ( contexts [ i ] [ 5 ] . m_presence_attribute_key , " trhost " ) ;
contexts [ i ] [ 6 ] . m_presence_attibute_type = 3 ;
strcpy ( contexts [ i ] [ 6 ] . m_presence_attribute_key , " mp_mis_str " ) ;
contexts [ i ] [ 7 ] . m_presence_attibute_type = 3 ;
strcpy ( contexts [ i ] [ 7 ] . m_presence_attribute_key , " mp_mis_id " ) ;
contexts [ i ] [ 8 ] . m_presence_attibute_type = 1 ;
strcpy ( contexts [ i ] [ 8 ] . m_presence_attribute_key , " mp_curr_gamemode " ) ;
2023-07-14 09:02:47 +00:00
contexts_per_player [ i ] = contexts [ i ] ;
}
2023-07-15 20:37:20 +00:00
if ( g_pointers - > m_sc . m_start_get_presence_attributes ( 0 , bucket . data ( ) , bucket . size ( ) , contexts_per_player , 9 , & 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-07-14 09:02:47 +00:00
if ( status . status = = 3 )
2023-02-21 11:52:05 +01:00
{
2023-07-14 09:02:47 +00:00
for ( size_t i = 0 ; i < bucket . size ( ) ; + + i )
2023-05-01 23:23:07 +02:00
{
2023-07-14 09:02:47 +00:00
if ( const auto & it = m_players . find ( bucket [ i ] . m_rockstar_id ) ; it ! = m_players . end ( ) )
2023-06-06 13:37:45 +02:00
{
2023-07-14 09:02:47 +00:00
rage : : rlSessionInfo info { } ;
2023-07-15 20:37:20 +00:00
rage : : rlSessionInfo transition_info { } ;
info . m_session_token = - 1 ;
transition_info . m_session_token = - 1 ;
GSType gstype = ( GSType ) ( int ) contexts [ i ] [ 0 ] . m_presence_attribute_int_value ;
bool is_spectating = ( bool ) contexts [ i ] [ 2 ] . m_presence_attribute_int_value ;
bool is_host_of_session = ( bool ) contexts [ i ] [ 3 ] . m_presence_attribute_int_value ;
bool is_host_of_transition_session = ( bool ) contexts [ i ] [ 5 ] . m_presence_attribute_int_value ;
GameMode game_mode = ( GameMode ) contexts [ i ] [ 8 ] . m_presence_attribute_int_value ;
std : : string mission_id = contexts [ i ] [ 7 ] . m_presence_attribute_string_value ;
std : : string mission_name = contexts [ i ] [ 6 ] . m_presence_attribute_string_value ;
if ( contexts [ i ] [ 1 ] . m_presence_attribute_string_value [ 0 ] = = 0
| | ! g_pointers - > m_gta . m_decode_session_info ( & info , contexts [ i ] [ 1 ] . m_presence_attribute_string_value , nullptr ) )
2023-07-14 09:02:47 +00:00
gstype = GSType : : Invalid ;
2023-07-15 20:37:20 +00:00
if ( can_fetch_name ( game_mode ) & & mission_name . empty ( ) & & mission_id . empty ( ) )
game_mode = GameMode : : None ;
if ( contexts [ i ] [ 4 ] . m_presence_attribute_string_value [ 0 ] = = 0
| | ! g_pointers - > m_gta . m_decode_session_info ( & transition_info , contexts [ i ] [ 4 ] . m_presence_attribute_string_value , nullptr ) )
transition_info . m_session_token = - 1 ;
2023-07-14 09:02:47 +00:00
if ( it - > second - > session_type ! = gstype )
{
handle_session_type_change ( * it - > second , gstype ) ;
}
2023-07-15 20:37:20 +00:00
else if ( it - > second - > notify_online & & it - > second - > session_id ! = info . m_session_token
& & g . player_db . notify_on_session_change )
2023-06-06 13:37:45 +02:00
{
2023-07-14 09:02:47 +00:00
g_notification_service - > push ( " Player DB " ,
std : : format ( " {} has joined a new session " , it - > second - > name ) ) ;
2023-06-06 13:37:45 +02:00
}
2023-07-15 20:37:20 +00:00
if ( gstype ! = GSType : : Invalid )
{
if ( it - > second - > notify_online & & is_spectating ! = it - > second - > is_spectating
& & g . player_db . notify_on_spectator_change )
{
if ( is_spectating )
{
g_notification_service - > push ( " Player DB " ,
std : : format ( " {} is now spectating " , it - > second - > name ) ) ;
}
else
{
g_notification_service - > push ( " Player DB " ,
std : : format ( " {} is no longer spectating " , it - > second - > name ) ) ;
}
}
if ( it - > second - > notify_online & & is_host_of_session ! = it - > second - > is_host_of_session
& & g . player_db . notify_on_become_host & & is_host_of_session & & it - > second - > session_id = = info . m_session_token )
{
g_notification_service - > push ( " Player DB " ,
std : : format ( " {} is now the host of their session " , it - > second - > name ) ) ;
}
if ( it - > second - > notify_online & & g . player_db . notify_on_transition_change
& & transition_info . m_session_token ! = - 1 & & it - > second - > transition_session_id = = - 1 )
{
if ( is_host_of_transition_session )
{
g_notification_service - > push ( " Player DB " ,
std : : format ( " {} has hosted a job lobby " , it - > second - > name ) ) ;
}
else
{
g_notification_service - > push ( " Player DB " ,
std : : format ( " {} has joined a job lobby " , it - > second - > name ) ) ;
}
}
else if ( it - > second - > notify_online & & g . player_db . notify_on_transition_change
& & transition_info . m_session_token = = - 1 & & it - > second - > transition_session_id ! = - 1 )
{
g_notification_service - > push ( " Player DB " ,
std : : format ( " {} is no longer in a job lobby " , it - > second - > name ) ) ;
}
if ( it - > second - > notify_online & & g . player_db . notify_on_mission_change
& & game_mode ! = it - > second - > game_mode )
{
auto rid = it - > second - > rockstar_id ;
auto old_game_mode = it - > second - > game_mode ;
g_fiber_pool - > queue_job ( [ rid , old_game_mode , game_mode , mission_id , mission_name ] {
handle_game_mode_change ( rid , old_game_mode , game_mode , mission_id , mission_name ) ;
} ) ;
}
}
if ( it - > second - > join_redirect )
it - > second - > redirect_info = info ;
it - > second - > session_type = gstype ;
it - > second - > session_id = info . m_session_token ;
it - > second - > is_spectating = is_spectating ;
it - > second - > is_host_of_session = is_host_of_session ;
it - > second - > transition_session_id = transition_info . m_session_token ;
it - > second - > is_host_of_transition_session = is_host_of_transition_session ;
it - > second - > game_mode = game_mode ;
it - > second - > game_mode_id = mission_id ;
it - > second - > game_mode_name = mission_name ;
2023-06-06 13:37:45 +02:00
}
2023-05-01 23:23:07 +02:00
}
2023-07-15 20:37:20 +00:00
handle_join_redirect ( ) ;
2023-02-21 11:52:05 +01:00
}
2023-07-14 09:02:47 +00:00
else
{
LOG ( WARNING ) < < " Presence attribute endpoint failed " ;
}
2023-02-21 11:52:05 +01:00
}
}
}
2023-07-14 09:02:47 +00:00
bool player_database_service : : is_joinable_session ( GSType type )
{
return type = = GSType : : Public | | type = = GSType : : OpenCrew ;
}
const char * player_database_service : : get_session_type_str ( GSType type )
{
switch ( type )
{
case GSType : : Invalid : return " Offline " ;
case GSType : : InviteOnly : return " Invite Only " ;
case GSType : : FriendsOnly : return " Friends Only " ;
case GSType : : ClosedCrew : return " Closed Crew " ;
case GSType : : OpenCrew : return " Crew " ;
case GSType : : Job : return " In Mission " ;
case GSType : : Public : return " Public " ;
case GSType : : Modder : return " Unknown (Concealed By Modder) " ;
}
return " Unknown " ;
}
2023-07-15 20:37:20 +00:00
const char * player_database_service : : get_game_mode_str ( GameMode mode )
{
switch ( mode )
{
case GameMode : : None : return " None " ;
case GameMode : : Mission : return " Mission " ;
case GameMode : : Deathmatch : return " Deathmatch " ;
case GameMode : : Race : return " Race " ;
case GameMode : : Survival : return " Survival " ;
case GameMode : : GangAttack : return " Gang Attack " ;
case GameMode : : Golf : return " Golf " ;
case GameMode : : Tennis : return " Tennis " ;
case GameMode : : ShootingRange : return " Shooting Range " ;
}
return " Unknown " ;
}
bool player_database_service : : can_fetch_name ( GameMode mode )
{
switch ( mode )
{
case GameMode : : Mission :
case GameMode : : Deathmatch :
case GameMode : : Race :
case GameMode : : Survival : return true ;
}
return false ;
}
2022-11-19 01:49:36 +00:00
}