From 005654ce0593f8773a5c02832e6290ae66e1564c Mon Sep 17 00:00:00 2001 From: hgn Date: Wed, 4 Jun 2025 21:54:19 +0100 Subject: [PATCH] yea yea --- src/gameserver.c | 122 +++++++++++++++++++++++++++- src/gameserver_database.c | 165 +++++++++++++++++++++++++++++++------- src/gameserver_database.h | 22 ++++- src/input.h | 8 +- src/network.c | 21 +++-- src/replay2.c | 10 ++- 6 files changed, 296 insertions(+), 52 deletions(-) diff --git a/src/gameserver.c b/src/gameserver.c index 3782d72..bb42a4a 100644 --- a/src/gameserver.c +++ b/src/gameserver.c @@ -568,7 +568,12 @@ static void gameserver_rx_200_300( SteamNetworkingMessage_t *msg ) u32 propsize = sizeof(netmsg_playerusername) + chs + 1; gameserver_send_to_all( client_id, prop, propsize, k_nSteamNetworkingSend_Reliable ); - db_action_set_username( client->steamid, client->username ); + + struct profile_edits edits = {0}; + edits.steamid = client->steamid; + edits.set_name = 1; + vg_strncpy( client->username, edits.name, sizeof(edits.name), k_strncpy_always_add_null ); + db_action_edit_profile( &edits ); } else if( tmp->inetmsg_id == k_inetmsg_playerframe ) { @@ -765,12 +770,127 @@ static int _rcon_spoofid( int argc, const char *argv[] ) return 0; } +static int _rcon_edit_user( int argc, const char *argv[] ) +{ + if( argc >= 1 ) + { + u64 steamid = 0; + bool hex = 0; + + if( argv[0][0] == '0' ) + if( argv[0][1] == 'x' ) + hex = 1; + + if( hex ) steamid = strtoull( argv[0]+2, NULL, 16 ); + else steamid = strtoull( argv[0], NULL, 10 ); + + if( steamid ) + { + if( argc == 1 ) + { + vg_info( "User details for %lx: not-implemented\n", steamid ); + return 1; + } + + struct profile_edits edits = {0}; + edits.steamid = steamid; + + int j = 1; + while( j < argc ) + { + if( !strcmp( argv[j], "name" ) ) + { + j ++; + if( j == argc ) + { + vg_error( "Need string for name \n" ); + return 0; + } + + edits.set_name = 1; + vg_strncpy( argv[j], edits.name, sizeof(edits.name), k_strncpy_always_add_null ); + j ++; + } + else if( !strcmp( argv[j], "cc" ) ) + { + j ++; + if( j == argc ) + { + vg_error( "Need string for cc \n" ); + return 0; + } + + edits.set_cc = 1; + vg_strncpy( argv[j], edits.cc, 4, k_strncpy_always_add_null ); + j ++; + } + else if( argv[j][0] == '+' || argv[j][0] == '-' ) + { + bool set = argv[j][0] == '+'; + u32 flag = 0x00; + if( !strcmp( argv[j]+1, "LEGEND" ) ) flag = 0x2; + else if( !strcmp( argv[j]+1, "EARLY" ) ) flag = 0x1; + else if( !strcmp( argv[j]+1, "ADMIN" ) ) flag = 0x8000; + else + { + vg_error( "Unknown flag '%s'\n", argv[j]+1 ); + return 0; + } + + if( set ) edits.set_flags |= flag; + else edits.clear_flags |= flag; + j ++; + } + else + { + vg_error( "Unknown option '%s'\n", argv[j] ); + return 0; + } + } + + db_action_edit_profile( &edits ); + } + else + { + vg_error( "Invalid steam id format '%s'\n", argv[0] ); + return 0; + } + } + else + { + vg_info( "Usage: edit_profile\n" + " Options:\n" + " +FLAG (LEGEND,EARLY,ADMIN)\n" + " -FLAG\n" + " cc \n", + " name \n" ); + } + + return 0; +} + +static int _rcon_dumpdb( int argc, const char *argv[] ) +{ + if( argc == 1 ) + { + db_action_dump( argv[0] ); + return 1; + } + else + { + vg_error( "Usage: dumpdb \n" ); + return 0; + } +} + int main( int argc, const char *argv[] ) { _gameserver.thread = pthread_self(); vg_log_init(); vg_console_init(); vg_console_reg_cmd( "spoofid", _rcon_spoofid, NULL ); + vg_console_reg_cmd( "dumpdb", _rcon_dumpdb, NULL ); + vg_console_reg_cmd( "edit_user", _rcon_edit_user, NULL ); signal( SIGINT, inthandler ); signal( SIGQUIT, inthandler ); diff --git a/src/gameserver_database.c b/src/gameserver_database.c index f7079f5..d48a476 100644 --- a/src/gameserver_database.c +++ b/src/gameserver_database.c @@ -36,7 +36,7 @@ static void *database_worker_thread(void *_) _gs_db.users_tree = db->userdata_address + offsetof(struct skaterift_database, users_tree); _gs_db.leaderboards_table = db->userdata_address + offsetof(struct skaterift_database, leaderboards_table); vg_db_tree_init( db, _gs_db.users_tree ); - vg_db_dumb_table_init( db, _gs_db.leaderboards_table, sizeof(struct skaterift_leaderboard), 0xffff ); + vg_db_table_init( db, _gs_db.leaderboards_table, sizeof(struct skaterift_leaderboard), 0xffff ); vg_db_skipper_init( db, db->userdata_address + offsetof(struct skaterift_database,leaderboards_skipper), 0xffff ); while( vg_async_process_next_task( &_gs_db.tasks ) ) {} @@ -72,7 +72,7 @@ struct leaderboard_comparand static i32 leaderboard_uid_compare( vg_skipper_context *ctx, void *comparand, u16 item_index ) { - u64 item_addr = vg_db_dumb_table_get( &_gs_db.db, ctx->table_address, item_index ); + u64 item_addr = vg_db_table_get( &_gs_db.db, ctx->table_address, item_index ); struct leaderboard_comparand *lc = comparand; u32 hash; @@ -103,12 +103,12 @@ u64 db_leaderboard_address( const char *uid ) u16 table_id; if( vg_db_skipper_find( &_gs_db.db, &uid_ctx, &table_id, &lc ) ) - return vg_db_dumb_table_get( &_gs_db.db, _gs_db.leaderboards_table, table_id ); + return vg_db_table_get( &_gs_db.db, _gs_db.leaderboards_table, table_id ); struct skaterift_leaderboard leaderboard; /* create */ - u64 new_address = vg_db_dumb_table_append( &_gs_db.db, _gs_db.leaderboards_table ); + u64 new_address = vg_db_table_append( &_gs_db.db, _gs_db.leaderboards_table ); if( new_address ) { vg_info( "Creating new leaderboard for uid: '%s'\n", uid ); @@ -118,12 +118,12 @@ u64 db_leaderboard_address( const char *uid ) vg_db_write( &_gs_db.db, new_address, &leaderboard, sizeof(leaderboard) ); u16 max = 0xffff; - vg_db_dumb_table_init( &_gs_db.db, new_address+offsetof(struct skaterift_leaderboard,entries), + vg_db_table_init( &_gs_db.db, new_address+offsetof(struct skaterift_leaderboard,entries), sizeof(struct skaterift_entry), max ); vg_db_skipper_init( &_gs_db.db, new_address+offsetof(struct skaterift_leaderboard,steamid_skipper), max ); vg_db_skipper_init( &_gs_db.db, new_address+offsetof(struct skaterift_leaderboard,time_skipper), max ); - u16 table_id = vg_db_dumb_table_count( &_gs_db.db, index_table_address ) -1; + u16 table_id = vg_db_table_count( &_gs_db.db, index_table_address ) -1; vg_db_skipper_placement( &_gs_db.db, &uid_ctx, table_id, &lc ); vg_db_checkpoint( &_gs_db.db ); return new_address; @@ -144,7 +144,7 @@ bool db_get_highscore_table_name( const char *mod_uid, const char *run_uid, char static i32 leaderboard_steamid_compare( vg_skipper_context *ctx, void *comparand, u16 item_index ) { - u64 item_addr = vg_db_dumb_table_get( &_gs_db.db, ctx->table_address, item_index ); + u64 item_addr = vg_db_table_get( &_gs_db.db, ctx->table_address, item_index ); u64 steamid; vg_db_read( &_gs_db.db, item_addr + offsetof(struct skaterift_entry,steamid), &steamid, sizeof(steamid) ); u64 compid = *((u64 *)comparand); @@ -153,7 +153,7 @@ static i32 leaderboard_steamid_compare( vg_skipper_context *ctx, void *comparand } static i32 leaderboard_time_compare( vg_skipper_context *ctx, void *comparand, u16 item_index ) { - u64 item_addr = vg_db_dumb_table_get( &_gs_db.db, ctx->table_address, item_index ); + u64 item_addr = vg_db_table_get( &_gs_db.db, ctx->table_address, item_index ); u32 time; vg_db_read( &_gs_db.db, item_addr + offsetof(struct skaterift_entry,centiseconds), &time, sizeof(time) ); u32 comptime = *((u32 *)comparand); @@ -184,7 +184,7 @@ bool db_writeusertime( char uid[DB_TABLE_UID_MAX], u64 steamid, u32 centiseconds u16 entry_id; if( vg_db_skipper_find( &_gs_db.db, &steamid_ctx, &entry_id, &steamid ) ) { - entry_address = vg_db_dumb_table_get( &_gs_db.db, table, entry_id ); + entry_address = vg_db_table_get( &_gs_db.db, table, entry_id ); vg_db_read( &_gs_db.db, entry_address, &entry, sizeof(entry) ); if( (centiseconds > entry.centiseconds) && (entry.centiseconds > 200) && only_if_faster ) @@ -194,8 +194,8 @@ bool db_writeusertime( char uid[DB_TABLE_UID_MAX], u64 steamid, u32 centiseconds } else { - entry_address = vg_db_dumb_table_append( &_gs_db.db, table ); - entry_id = vg_db_dumb_table_count( &_gs_db.db, table ) -1; + entry_address = vg_db_table_append( &_gs_db.db, table ); + entry_id = vg_db_table_count( &_gs_db.db, table ) -1; vg_db_skipper_placement( &_gs_db.db, &steamid_ctx, entry_id, &steamid ); } @@ -228,49 +228,62 @@ bool db_get_username( u64 steamid, char *out_username, u32 username_max ) return 0; } -struct task_set_username -{ - u64 steamid; - char name[NETWORK_USERNAME_MAX]; -}; -static void task_set_username( vg_async_task *task ) +void _db_edit_profile( struct profile_edits *info ) { THREAD_1; - struct task_set_username *info = (void *)task->data; if( info->steamid == k_steamid_max ) return; struct skaterift_profile profile = {0}; u64 user_address = vg_db_translate( &_gs_db.db, _gs_db.users_tree, info->steamid ); if( user_address ) - { vg_db_read( &_gs_db.db, user_address, &profile, sizeof(profile) ); - } else { user_address = vg_db_virtual_allocate( &_gs_db.db, 32*1024 ); vg_db_tree_map( &_gs_db.db, _gs_db.users_tree, info->steamid, user_address ); } - memset( profile.name, 0, sizeof(profile.name) ); - vg_strncpy( info->name, profile.name, sizeof(profile.name), k_strncpy_always_add_null ); + if( info->set_name ) + { + memset( profile.name, 0, sizeof(profile.name) ); + vg_strncpy( info->name, profile.name, sizeof(profile.name), k_strncpy_always_add_null ); + } + + if( info->set_cc ) + { + memset( profile.cc, 0, sizeof(profile.cc) ); + vg_strncpy( info->cc, profile.cc, sizeof(profile.cc), k_strncpy_always_add_null ); + } + + if( info->set_flags ) + profile.flags |= info->set_flags; + + if( info->clear_flags ) + profile.flags &= ~info->clear_flags; + vg_db_write( &_gs_db.db, user_address, &profile, sizeof(profile) ); vg_db_checkpoint( &_gs_db.db ); } -void db_action_set_username( u64 steamid, const char *username ) +static void task_edit_profile( vg_async_task *task ) { - THREAD_0; + THREAD_1; + _db_edit_profile( (void *)task->data ); +} - vg_async_task *task = vg_allocate_async_task( &_gs_db.tasks, sizeof(struct task_set_username), 1 ); - struct task_set_username *info = (void *)task->data; - info->steamid = steamid; - vg_strncpy( username, info->name, sizeof(info->name), k_strncpy_always_add_null ); - vg_async_task_dispatch( task, task_set_username ); +void db_action_edit_profile( struct profile_edits *edits ) +{ + THREAD_0; + vg_async_task *task = vg_allocate_async_task( &_gs_db.tasks, sizeof(struct profile_edits), 1 ); + memcpy( (void *)task->data, edits, sizeof(struct profile_edits) ); + vg_async_task_dispatch( task, task_edit_profile ); } enum request_status gameserver_read_highscore_table( vg_msg *msg, char uid[ DB_TABLE_UID_MAX ] ) { + THREAD_1; + u64 leaderboard_address = db_leaderboard_address( uid ); u64 table_address = leaderboard_address + offsetof(struct skaterift_leaderboard,entries); @@ -288,7 +301,7 @@ enum request_status gameserver_read_highscore_table( vg_msg *msg, char uid[ DB_T u16 item_index; while( vg_db_skipper_iter( &_gs_db.db, &time_ctx, &item_index ) ) { - u64 entry_address = vg_db_dumb_table_get( &_gs_db.db, table_address, item_index ); + u64 entry_address = vg_db_table_get( &_gs_db.db, table_address, item_index ); struct skaterift_entry entry; vg_db_read( &_gs_db.db, entry_address, &entry, sizeof(entry) ); @@ -319,6 +332,8 @@ enum request_status gameserver_read_highscore_table( vg_msg *msg, char uid[ DB_T enum request_status _gs_db_get_profile( vg_msg *msg, u64 steamid ) { + THREAD_1; + u16 top3_count = 0, top10_count = 0; @@ -339,7 +354,7 @@ enum request_status _gs_db_get_profile( vg_msg *msg, u64 steamid ) u16 item_index; while( vg_db_skipper_iter( &_gs_db.db, &time_ctx, &item_index ) ) { - u64 entry_address = vg_db_dumb_table_get( &_gs_db.db, table_address, item_index ); + u64 entry_address = vg_db_table_get( &_gs_db.db, table_address, item_index ); struct skaterift_entry entry; vg_db_read( &_gs_db.db, entry_address, &entry, sizeof(entry) ); @@ -374,3 +389,91 @@ enum request_status _gs_db_get_profile( vg_msg *msg, u64 steamid ) return k_request_status_ok; } + +struct task_db_dump +{ + u32 none; + char output_path[]; +}; + +void _gs_db_dump_task( vg_async_task *task ) +{ + THREAD_1; + struct task_db_dump *info = (void *)task->data; + + FILE *fp = fopen( info->output_path, "w" ); + if( !fp ) + { + vg_error( "Cannot open '%s'\n", fp ); + return; + } + + vg_db *db = &_gs_db.db; + u64 master_table_addr = db->userdata_address + offsetof(struct skaterift_database, leaderboards_table), + user_tree_addr = db->userdata_address + offsetof(struct skaterift_database, users_tree); + + fprintf( fp, "profiles\n" + "{\n" ); + vg_tree_iter iter; + vg_db_tree_iter_init( db, &iter, user_tree_addr ); + + while( vg_db_tree_iter( db, &iter ) ) + { + u64 steamid = iter.key, + profile_addr = iter.value; + + struct skaterift_profile profile; + vg_db_read( db, profile_addr, &profile, sizeof(profile) ); + fprintf( fp, " 0x%lx\n" + " {\n" + " name %s\n" + " cc %s\n" + " flags 0x%x\n" + " }\n", steamid, profile.name, profile.cc, profile.flags ); + } + + fprintf( fp, "}\n" ); + + fprintf( fp, "leaderboards\n" + "{\n" ); + u16 table_count = vg_db_table_count( db, master_table_addr ); + for( u16 i=0; idata; + info->none = 0; + strcpy( info->output_path, path ); + vg_async_task_dispatch( task, _gs_db_dump_task ); +} diff --git a/src/gameserver_database.h b/src/gameserver_database.h index a7a0102..3a76458 100644 --- a/src/gameserver_database.h +++ b/src/gameserver_database.h @@ -32,10 +32,26 @@ struct _gs_db } extern _gs_db; -void db_action_set_username( u64 steamid, const char *username ); +void db_action_dump( const char *path ); bool db_get_highscore_table_name( const char *mod_uid, const char *run_uid, char table_name[DB_TABLE_UID_MAX] ); bool db_writeusertime( char uid[DB_TABLE_UID_MAX], u64 steamid, u32 score, u64 last_second, bool only_if_faster ); +struct profile_edits +{ + u64 steamid; + + bool set_name; + char name[NETWORK_USERNAME_MAX]; + + bool set_cc; + char cc[4]; + + u32 set_flags; + u32 clear_flags; +}; +void _db_edit_profile( struct profile_edits *info ); +void db_action_edit_profile( struct profile_edits *info ); + /* * Create database connection and users table */ @@ -63,13 +79,13 @@ struct skaterift_leaderboard { u32 uid_hash; char uid[ DB_TABLE_UID_MAX ]; - vg_db_dumb_table entries; + vg_db_table entries; vg_db_skipper steamid_skipper, time_skipper; }; struct skaterift_database { vg_db_address_tree users_tree; - vg_db_dumb_table leaderboards_table; + vg_db_table leaderboards_table; vg_db_skipper leaderboards_skipper; }; diff --git a/src/input.h b/src/input.h index 241080e..78ae13c 100644 --- a/src/input.h +++ b/src/input.h @@ -261,8 +261,10 @@ static int button_press( enum sr_bind button ) static void joystick_state( enum sr_joystick joystick, v2f state ) { + /* TODO: This fucking sucks */ if( (skaterift.activity == k_skaterift_menu) && (vg_input.display_input_method != k_input_method_kbm) && - (menu.main_index != k_menu_main_map) ) + (menu.main_index != k_menu_main_map) && + !((menu.main_index == k_menu_main_online) && menu.choosing_country ) ) { v2_zero( state ); return; @@ -276,7 +278,9 @@ static void joystick_state( enum sr_joystick joystick, v2f state ) static float axis_state( enum sr_axis axis ) { - if( (skaterift.activity == k_skaterift_menu) && (axis < k_sraxis_mbrowse_h ) && (vg_input.display_input_method != k_input_method_kbm) ) + if( (skaterift.activity == k_skaterift_menu) && + (axis < k_sraxis_mbrowse_h ) && + (vg_input.display_input_method != k_input_method_kbm) ) return 0; if( input_filter_generic() ) diff --git a/src/network.c b/src/network.c index b9e1d14..6e60ecb 100644 --- a/src/network.c +++ b/src/network.c @@ -336,28 +336,27 @@ static void on_server_connect_status( CallbackMsg_t *msg ) render_server_status_gui(); } -static void on_persona_state_change( CallbackMsg_t *msg ){ +static void on_persona_state_change( CallbackMsg_t *msg ) +{ if( !network_connected() ) return; PersonaStateChange_t *info = (void *)msg->m_pubParam; ISteamUser *hSteamUser = SteamAPI_SteamUser(); - vg_info( "User: %llu, change: %u\n", info->m_ulSteamID, - info->m_nChangeFlags ); + vg_info( "User: " PRINTF_U64 ", change: %u\n", info->m_ulSteamID, info->m_nChangeFlags ); - if( info->m_ulSteamID == SteamAPI_ISteamUser_GetSteamID(hSteamUser) ){ - if( info->m_nChangeFlags & k_EPersonaChangeName ){ + if( info->m_ulSteamID == SteamAPI_ISteamUser_GetSteamID(hSteamUser) ) + if( info->m_nChangeFlags & k_EPersonaChangeName ) network_send_username(); - } - } - if( info->m_nChangeFlags & k_EPersonaChangeRelationshipChanged ){ - for( u32 i=0; im_nChangeFlags & k_EPersonaChangeRelationshipChanged ) + { + for( u32 i=0; isteamid == info->m_ulSteamID ){ + if( rp->steamid == info->m_ulSteamID ) player_remote_update_friendflags( rp ); - } } } } diff --git a/src/replay2.c b/src/replay2.c index 1c677ce..bbd1adf 100644 --- a/src/replay2.c +++ b/src/replay2.c @@ -99,9 +99,10 @@ static void replay_download_callback( void *data, u32 data_size, u64 userdata, e { char path[1024]; if( _remote_replay.state == k_remote_replay_state_getinfo ) - snprintf( path, sizeof(path), "replaydata/%lx@%lx.bkv", _remote_replay.steamid, _remote_replay.last_second ); + snprintf( path, sizeof(path), "replaydata/" PRINTF_X64 "@" PRINTF_X64 ".bkv", + _remote_replay.steamid, _remote_replay.last_second ); else - snprintf( path, sizeof(path), "replaydata/%lx@%x", _remote_replay.steamid, chunk->minute ); + snprintf( path, sizeof(path), "replaydata/" PRINTF_X64 "@%x", _remote_replay.steamid, chunk->minute ); FILE *fp = fopen( path, "wb" ); if( fp ) @@ -316,12 +317,13 @@ static void _remote_replay_cache_check( void *userdata ) char path[1024]; if( _remote_replay.state == k_remote_replay_state_getinfo ) { - snprintf( path, sizeof(path), "replaydata/%lx@%lx.bvk", _remote_replay.steamid, _remote_replay.last_second ); + snprintf( path, sizeof(path), "replaydata/" PRINTF_X64 "@" PRINTF_X64 ".bvk", + _remote_replay.steamid, _remote_replay.last_second ); } else { struct remote_replay_chunk *chunk = &_remote_replay.chunks[ _remote_replay.chunks_downloaded ]; - snprintf( path, sizeof(path), "replaydata/%lx@%x", _remote_replay.steamid, chunk->minute ); + snprintf( path, sizeof(path), "replaydata/" PRINTF_X64 "@%x", _remote_replay.steamid, chunk->minute ); } vg_async_task *result_task = -- 2.25.1