yea yea master
authorhgn <hgodden00@gmail.com>
Wed, 4 Jun 2025 20:54:19 +0000 (21:54 +0100)
committerhgn <hgodden00@gmail.com>
Wed, 4 Jun 2025 20:54:19 +0000 (21:54 +0100)
src/gameserver.c
src/gameserver_database.c
src/gameserver_database.h
src/input.h
src/network.c
src/replay2.c

index 3782d7223f0a6233f341865349b8c66e2253509a..bb42a4aad01984bec27ab65db94ff331cf426f02 100644 (file)
@@ -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 <x>\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 <x>\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    <cc>\n",
+               "  name  <username>\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 <output_filepath>\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 );
index f7079f5147398810f3d31e99af69212516a8d5a1..d48a4766ab62f10455a57b3bf0b41f4643036e74 100644 (file)
@@ -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; i<table_count; i ++ )
+   {
+      u64 leaderboard_addr = vg_db_table_get( db, master_table_addr, i );
+
+      char uid[ DB_TABLE_UID_MAX ];
+      vg_db_read( db, leaderboard_addr + offsetof(struct skaterift_leaderboard,uid), uid, sizeof(uid) );
+      fprintf( fp, "   %s\n"
+                   "   {\n", uid );
+
+      u64 entries_addr = leaderboard_addr + offsetof(struct skaterift_leaderboard, entries);
+      u16 entries_count = vg_db_table_count( db, entries_addr );
+
+      for( u16 j=0; j<entries_count; j ++ )
+      {
+         struct skaterift_entry entry;
+         u64 entry_addr = vg_db_table_get( db, entries_addr, j );
+         vg_db_read( db, entry_addr, &entry, sizeof(entry) );
+         fprintf( fp, "      0x%lx\n"
+                      "      {\n"
+                      "         last_second %lu\n"
+                      "         centiseconds %u\n"
+                      "      }\n", entry.steamid, entry.last_second, entry.centiseconds );
+      }
+
+      fprintf( fp, "   }\n" );
+   }
+   fprintf( fp, "}\n" );
+
+   fclose( fp );
+}
+
+void db_action_dump( const char *path )
+{
+   THREAD_0;
+   vg_async_task *task = vg_allocate_async_task( &_gs_db.tasks, sizeof(struct task_db_dump) + strlen(path)+1, 1 );
+   struct task_db_dump *info = (void *)task->data;
+   info->none = 0;
+   strcpy( info->output_path, path );
+   vg_async_task_dispatch( task, _gs_db_dump_task );
+}
index a7a01024add4e698bb0eb278838b25e850400a55..3a76458788de3808c23d7f4652667e88532ca21a 100644 (file)
@@ -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;
 };
index 241080eba213aec7a4acb719e302dda63fb6edb1..78ae13c2977d7681eba124f4f7e9e99179f767f9 100644 (file)
@@ -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() )
index b9e1d14ce8d9cdafb9210f84fe20b6c0ecd40d17..6e60ecb32bcdf3ed3800c2513ab2330ca70f1a13 100644 (file)
@@ -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; i<NETWORK_MAX_PLAYERS; i ++ ){
+   if( info->m_nChangeFlags & k_EPersonaChangeRelationshipChanged )
+   {
+      for( u32 i=0; i<NETWORK_MAX_PLAYERS; i ++ )
+      {
          struct network_player *rp = &netplayers.list[i];
-         if( rp->steamid == info->m_ulSteamID ){
+         if( rp->steamid == info->m_ulSteamID )
             player_remote_update_friendflags( rp );
-         }
       }
    }
 }
index 1c677cecc0eec85d78988b9c81d029f829f30431..bbd1adfe4ffe8319873572a118c12316c51719d3 100644 (file)
@@ -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 =