more db stuff
authorhgn <hgodden00@gmail.com>
Mon, 15 Aug 2022 00:42:05 +0000 (01:42 +0100)
committerhgn <hgodden00@gmail.com>
Mon, 15 Aug 2022 00:42:05 +0000 (01:42 +0100)
highscores.h
network_msg.h
server.c
testaa.c

index 2ffaf6acdd19f90bea341182801835b31c181900..84ab9a4164a5c9e0a8ab14e9d61179d4ca60437e 100644 (file)
@@ -14,15 +14,28 @@ typedef struct highscore highscore;
 typedef struct highscore_record highscore_record;
 typedef struct highscore_track_table highscore_track_table;
 typedef struct highscore_database highscore_database;
+typedef struct highscore_playerinfo highscore_playerinfo;
 
 #pragma pack(push,1)
+
+struct highscore_playerinfo
+{
+   char nickname[16];
+   u64 playerid;
+
+   union
+   {
+      aatree_pool_node aapn;
+      aatree_node aa_playerid;
+   };
+};
+
 struct highscore_record
 {
    u16 trackid, points, time, reserved0;
    u64 playerid;
    u32 datetime;
-
-   u32 reserved[7];
+   u32 reserved1;
    
    union
    {
@@ -35,12 +48,7 @@ struct highscore_record
       }
       aa;
 
-      struct
-      {
-         /* TODO pool allocator */
-         u32 next, prev;
-      }
-      pool;
+      aatree_pool_node pool;
    };
 };
 
@@ -58,8 +66,11 @@ struct highscore_database
 {
    highscore_track_table tracks[ 128 ];
 
-   aatree_ptr pool_head;
-   u32 reserved[63];
+   aatree_ptr pool_head, playerinfo_head;
+   u32 entry_capacity, 
+       playerinfo_capacity, playerinfo_root;
+
+   u32 reserved[59];
 };
 
 #pragma pack(pop)
@@ -71,9 +82,11 @@ static struct highscore_system
           aainfo_points,
           aainfo_time,
           aainfo_playerid,
-          aainfo_datetime;
+          aainfo_datetime,
+          aainfo_playerinfo_playerid,
+          aainfo_playerinfo;
 
-   void *data;
+   void *data, *playerinfo_data;
 }
 highscore_system;
 
@@ -104,24 +117,52 @@ static int highscore_cmp_playerid( void *a, void *b )
    return pa->playerid < pb->playerid? -1: 1;
 }
 
-static int highscores_init( u32 pool_size )
+static int highscore_cmp_playerinfo_playerid( void *a, void *b )
 {
-   struct highscore_system *sys = &highscore_system;
+   highscore_playerinfo *pa = a, *pb = b;
+   if( pa->playerid == pb->playerid ) return 0;
+   return pa->playerid < pb->playerid? -1: 1;
+}
 
-   size_t requested_mem = pool_size * sizeof(highscore_record);
-   sys->data = malloc( requested_mem );
+static void *highscore_malloc( u32 count, u32 size )
+{
+   size_t requested_mem = size * count;
+   void *data = malloc( requested_mem );
 
    requested_mem /= 1024;
    requested_mem /= 1024;
 
-   if( !highscore_system.data )
+   if( !data )
    {
-      vg_error( "Could not allocated %dmb of memory for database\n",
-                  requested_mem );
-      return 0;
+      vg_error( "Could not allocated %dmb of memory\n", requested_mem );
+      return NULL;
    }
    else
-      vg_success( "Allocated %dmb for database\n", requested_mem );
+      vg_success( "Allocated %dmb for %u records\n", requested_mem, count );
+
+   return data;
+}
+
+static void highscores_free(void)
+{
+   free( highscore_system.data );
+   free( highscore_system.playerinfo_data );
+}
+
+static int highscores_init( u32 pool_size, u32 playerinfo_pool_size )
+{
+   struct highscore_system *sys = &highscore_system;
+
+   sys->data = highscore_malloc( pool_size, sizeof(highscore_record) );
+   if( !sys->data ) return 0;
+
+   sys->playerinfo_data = 
+      highscore_malloc( playerinfo_pool_size, sizeof(highscore_playerinfo));
+   if( !sys->playerinfo_data ) 
+   {
+      free( sys->data );
+      return 0;
+   }
 
    /* This is ugly.. too bad! */
    sys->aainfo.base = highscore_system.data;
@@ -149,16 +190,64 @@ static int highscores_init( u32 pool_size )
    sys->aainfo_playerid.offset = offsetof(highscore_record,aa.playerid);
    sys->aainfo_playerid.p_cmp = highscore_cmp_playerid;
 
+   sys->aainfo_playerinfo_playerid.base = highscore_system.playerinfo_data;
+   sys->aainfo_playerinfo_playerid.stride = sizeof(highscore_playerinfo);
+   sys->aainfo_playerinfo_playerid.offset = 
+      offsetof(highscore_playerinfo,aa_playerid);
+   sys->aainfo_playerinfo_playerid.p_cmp = highscore_cmp_playerinfo_playerid;
+
+   sys->aainfo_playerinfo.base = highscore_system.playerinfo_data;
+   sys->aainfo_playerinfo.stride = sizeof(highscore_playerinfo);
+   sys->aainfo_playerinfo.offset = offsetof(highscore_playerinfo,aapn);
+   sys->aainfo_playerinfo.p_cmp = NULL;
 
-   /* TODO: Load from disk if avalible */
-   if( 0 )
+   FILE *fp = fopen( ".aadb", "rb" );
+   if( fp )
    {
+      vg_info( "Loading existing database\n" );
+      
+      u64 count = fread( &sys->dbheader, sizeof(highscore_database), 1, fp );
+
+      if( count != 1 )
+      {
+         vg_error( "Unexpected EOF reading database header\n" );
+         
+         highscores_free();
+         return 0;
+      }
+
+      count = fread( sys->data, sizeof(highscore_record), pool_size, fp );
+      if( count != pool_size )
+      {
+         vg_error( "Unexpected EOF reading database contents;"
+                   " %lu records of %u were read\n", count, pool_size );
+
+         highscores_free();
+         return 0;
+      }
 
+      count = fread( sys->playerinfo_data, sizeof(highscore_playerinfo),
+                     playerinfo_pool_size, fp );
+      if( count != playerinfo_pool_size )
+      {
+         vg_error( "Unexpected EOF reading playerinfo contents;"
+                   " %lu records of %u were read\n", count, 
+                   playerinfo_pool_size );
+         
+         highscores_free();
+         return 0;
+      }
+
+      fclose( fp );
    }
    else
    {
+      vg_log( "No existing database found (.aadb)\n" );
       vg_info( "Initializing database nodes\n" );
+      memset( &sys->dbheader, 0, sizeof(highscore_database) );
+
       sys->dbheader.pool_head = aatree_init_pool( &sys->aainfo, pool_size );
+      sys->dbheader.entry_capacity = pool_size;
 
       for( int i=0; i<vg_list_size(sys->dbheader.tracks); i++ )
       {
@@ -168,14 +257,39 @@ static int highscores_init( u32 pool_size )
          table->root_time = AATREE_PTR_NIL;
          table->root_datetime = AATREE_PTR_NIL;
       }
+
+      /* Initialize secondary db */
+      sys->dbheader.playerinfo_head = aatree_init_pool( 
+            &sys->aainfo_playerinfo,
+            playerinfo_pool_size );
+      sys->dbheader.playerinfo_capacity = playerinfo_pool_size;
+      sys->dbheader.playerinfo_root = AATREE_PTR_NIL;
    }
 
    return 1;
 }
 
-static void highscores_free(void)
+static int highscores_serialize_all(void)
 {
-   free( highscore_system.data );
+   struct highscore_system *sys = &highscore_system;
+   vg_info( "Serializing database\n" );
+
+   FILE *fp = fopen( ".aadb", "wb" );
+
+   if( !fp )
+   {
+      vg_error( "Could not open .aadb\n" );
+      return 0;
+   }
+
+   fwrite( &sys->dbheader, sizeof(highscore_database), 1, fp );
+   fwrite( sys->data, sizeof(highscore_record), 
+           sys->dbheader.entry_capacity, fp );
+   fwrite( sys->playerinfo_data, sizeof(highscore_playerinfo),
+            sys->dbheader.playerinfo_capacity, fp );
+
+   fclose( fp );
+   return 1;
 }
 
 static aatree_ptr highscores_push_record( highscore_record *record )
@@ -201,6 +315,16 @@ static aatree_ptr highscores_push_record( highscore_record *record )
 
    if( existing != AATREE_PTR_NIL )
    {
+      highscore_record *crecord = aatree_get_data( &sys->aainfo_playerid, 
+                                                   existing );
+
+      if( crecord->time < record->time || 
+            (crecord->time == record->time && crecord->points > record->points))
+      {
+         vg_log( "Not overwriting better score\n" );
+         return existing;
+      }
+
       vg_log( "Freeing existing record for player %lu\n", record->playerid );
       table->root_playerid = aatree_del( &sys->aainfo_playerid, existing );
       table->root_datetime = aatree_del( &sys->aainfo_datetime, existing );
@@ -214,7 +338,10 @@ static aatree_ptr highscores_push_record( highscore_record *record )
       aatree_pool_alloc( &sys->aainfo, &sys->dbheader.pool_head );
 
    if( index == AATREE_PTR_NIL )
+   {
+      vg_error( "Database records are over capacity!\n" );
       return index;
+   }
 
    highscore_record *dst = aatree_get_data( &sys->aainfo, index );
    memset( dst, 0, sizeof(highscore_record) );
@@ -237,12 +364,69 @@ static aatree_ptr highscores_push_record( highscore_record *record )
    return index;
 }
 
+static aatree_ptr highscore_set_user_nickname( u64 steamid, char nick[16] )
+{
+   vg_log( "Updating %lu's nickname\n", steamid );
+
+   struct highscore_system *sys = &highscore_system;
+   
+   highscore_playerinfo temp;
+   temp.playerid = steamid;
+
+   aatree_ptr record = aatree_find( &sys->aainfo_playerinfo_playerid, 
+                                     sys->dbheader.playerinfo_root,
+                                     &temp );
+   highscore_playerinfo *info;
+
+   if( record != AATREE_PTR_NIL )
+   {
+      info = aatree_get_data( &sys->aainfo_playerinfo, record );
+   }
+   else
+   {
+      record = aatree_pool_alloc( &sys->aainfo_playerinfo, 
+                                  &sys->dbheader.playerinfo_head );
+
+      if( record == AATREE_PTR_NIL )
+      {
+         vg_error( "Player info database is over capacity!\n" );
+         return AATREE_PTR_NIL;
+      }
+
+      info = aatree_get_data( &sys->aainfo_playerinfo, record );
+      memset( info, 0, sizeof(highscore_playerinfo) );
+
+      info->playerid = steamid;
+      sys->dbheader.playerinfo_root = aatree_insert( 
+            &sys->aainfo_playerinfo_playerid,
+            sys->dbheader.playerinfo_root,
+            record );
+   }
+
+   for( int i=0; i<16; i++ )
+      info->nickname[i] = nick[i];
+
+   return AATREE_PTR_NIL;
+}
+
 static void _highscore_showtime( void *data )
 {
    highscore_record *record = data;
    printf( "%hu", record->time );
 }
 
+static void _highscore_showname( void *data )
+{
+   char namebuf[17];
+   namebuf[16] = '\0';
+
+   highscore_playerinfo *info = data;
+   for( int i=0; i<16; i++ )
+      namebuf[i] = info->nickname[i];
+
+   printf( " %lu %s", info->playerid, namebuf );
+}
+
 static void highscores_print_track( u32 trackid, u32 count )
 {
    struct highscore_system *sys = &highscore_system;
@@ -250,22 +434,45 @@ static void highscores_print_track( u32 trackid, u32 count )
    highscore_track_table *table = &sys->dbheader.tracks[ trackid ];
    aatree_ptr it = aatree_kth( &sys->aainfo_time, table->root_time, 0 );
 
-   vg_info( "Highscores, top %u records for track %u\n", count, trackid );
-   vg_info( "==============================================\n" );
-
+   vg_info( "Highscores: top %u fastest records for track %u\n", count, trackid );
+   vg_info( "================================================\n" );
+   vg_info( "%3s| %16s | %5s | %5s | %s\n", "#", "Player", "Time", "Score", 
+                                                                   "TrackID" );
+   vg_info( "================================================\n" );
    int i=0;
    while( it != AATREE_PTR_NIL && i < 10 )
    {
       highscore_record *record = aatree_get_data( &sys->aainfo_time, it );
-      vg_info( "  [%d]: player(%lu), time: %hu, score: %hu, track:%hu\n",
-                  i+1, record->playerid, record->time, record->points,
+
+      highscore_playerinfo temp;
+      temp.playerid = record->playerid;
+
+      aatree_ptr info_ptr = aatree_find( &sys->aainfo_playerinfo_playerid,
+                                          sys->dbheader.playerinfo_root,
+                                          &temp );
+
+      char namebuf[17];
+      if( info_ptr == AATREE_PTR_NIL )
+         snprintf( namebuf, 16, "[%lu]", record->playerid );
+      else
+      {
+         highscore_playerinfo *inf = aatree_get_data( 
+               &sys->aainfo_playerinfo_playerid, info_ptr );
+
+         for( int i=0; i<16; i++ )
+            namebuf[i] = inf->nickname[i];
+         namebuf[16] = '\0';
+      }
+
+      vg_info( "%3d| %16s   %5hu   %5hu   %3hu\n",
+                  i+1, namebuf, record->time, record->points,
                   record->trackid );
 
       i++;
       it = aatree_next( &sys->aainfo_time, it );
    }
 
-   vg_info( "==============================================\n" );
+   vg_info( "================================================\n" );
 }
 
 #endif /* HIGHSCORES_H */
index 6c072f14fc44196f9ce7f6af2912a0a2431cd908..4ab094227cc014935397656e3082507695aedf87 100644 (file)
@@ -12,43 +12,46 @@ struct netmsg_blank
 };
 enum{ k_inetmsg_blank = 0 };
 
+typedef struct netmsg_auth netmsg_auth;
+struct netmsg_auth
+{
+   u32 inetmsg_id;
+
+   u32 ticket_length;
+   u8 ticket[];
+};
+enum{ k_inetmsg_auth = 1 };
+
 typedef struct netmsg_scores_request netmsg_scores_request;
 struct netmsg_scores_request
 {
    u32 inetmsg_id;
 };
-enum{ k_inetmsg_scores_request = 1 };
+enum{ k_inetmsg_scores_request = 2 };
 
-typedef struct netmsg_scores_info netmsg_scores_info;
-struct netmsg_scores_info
+typedef struct netmsg_set_score netmsg_set_score;
+struct netmsg_set_score
 {
    u32 inetmsg_id;
-   
+
    u32 record_count;
    struct netmsg_score_record
    {
       u32 trackid;
-
-      struct netmsg_score_entry
-      {
-         u64 steamid64;
-         u16 points, time;
-      }
-      top10[10];
+      u64 playerid;
+      u16 points, time;
    }
-   scores[];
+   records[];
 };
-enum{ k_inetmsg_scores_info = 2 };
+enum{ k_inetmsg_set_score = 3 };
 
-typedef struct netmsg_auth netmsg_auth;
-struct netmsg_auth
+typedef struct netmsg_set_nickname netmsg_set_nickname;
+struct netmsg_set_nickname
 {
    u32 inetmsg_id;
-
-   u32 ticket_length;
-   u8 ticket[];
+   char nickname[16];
 };
-enum{ k_inetmsg_auth = 3 };
+enum{ k_inetmsg_set_nickname = 4 };
 
 #pragma pack(pop)
 #endif /* NETWORK_MSG_H */
index 7d8e0e36a28d554bc2add7e18bb4b77ea7a65681..578c3f5b5723d407cdc94e09c7772082498fae9f 100644 (file)
--- a/server.c
+++ b/server.c
@@ -24,6 +24,7 @@ void inthandler( int signum )
 #include "vg/vg_steam_http.h"
 #include "vg/vg_steam_auth.h"
 #include "network_msg.h"
+#include "highscores.h"
 
 void  *hSteamHTTP,
       *hSteamNetworkingSockets;
@@ -51,6 +52,22 @@ static void recieve_http( void *callresult, void *context )
    SteamAPI_ISteamHTTP_ReleaseHTTPRequest( hSteamHTTP, result->m_hRequest );
 }
 
+static u64_steamid get_connection_authsteamid( SteamNetworkingMessage_t *msg )
+{
+   i64 userdata = SteamAPI_ISteamNetworkingSockets_GetConnectionUserData(
+            hSteamNetworkingSockets, msg->m_conn );
+
+   return *((u64_steamid *)&userdata);
+}
+
+static void set_connection_authsteamid(HSteamNetConnection con, u64_steamid id)
+{
+   i64 userdata = *((i64 *)&id);
+   
+   SteamAPI_ISteamNetworkingSockets_SetConnectionUserData(
+         hSteamNetworkingSockets, con, userdata );
+}
+
 static void new_client_connecting( HSteamNetConnection client )
 {
    EResult accept_status = SteamAPI_ISteamNetworkingSockets_AcceptConnection(
@@ -62,6 +79,8 @@ static void new_client_connecting( HSteamNetConnection client )
       SteamAPI_ISteamNetworkingSockets_SetConnectionPollGroup(
             hSteamNetworkingSockets,
             client, client_pollgroup );
+
+      set_connection_authsteamid( client, 0 );
    }
    else
    {
@@ -92,6 +111,179 @@ static void on_connect_status( CallbackMsg_t *msg )
    }
 }
 
+static void on_inet_auth( SteamNetworkingMessage_t *msg )
+{
+   if( get_connection_authsteamid( msg ) )
+   {
+      vg_warn( "Already authorized this user but app ticket was sent"
+               " again (%u)\n", msg->m_conn );
+      return;
+   }
+
+   vg_log( "Attempting to verify user\n" );
+
+   if( msg->m_cbSize < sizeof(netmsg_auth) )
+   {
+      vg_error( "Malformed auth ticket, too small (%u)\n", msg->m_conn );
+      return;
+   }
+
+   netmsg_auth *auth = msg->m_pData;
+
+   if( msg->m_cbSize < sizeof(netmsg_auth)+auth->ticket_length ||
+       auth->ticket_length > 1024 )
+   {
+      vg_error( "Malformed auth ticket, ticket_length incorrect (%u)\n",
+            auth->ticket_length );
+      return;
+   }
+
+   u8 decrypted[1024];
+   u32 ticket_len;
+
+   int success = SteamEncryptedAppTicket_BDecryptTicket(
+         auth->ticket, auth->ticket_length, decrypted,
+         &ticket_len, steam_symetric_key,
+         k_nSteamEncryptedAppTicketSymmetricKeyLen );
+
+   if( !success )
+   {
+      vg_error( "Failed to decrypt users ticket (client %u)\n", msg->m_conn );
+
+      SteamAPI_ISteamNetworkingSockets_CloseConnection(
+            hSteamNetworkingSockets,
+            msg->m_conn, 0, NULL, 0 );
+      return;
+   }
+
+   if( SteamEncryptedAppTicket_GetTicketIssueTime( decrypted, ticket_len ))
+   {
+      RTime32 ctime = time(NULL),
+              tickettime = SteamEncryptedAppTicket_GetTicketIssueTime(
+                    decrypted, ticket_len ),
+              expiretime = tickettime + 24*3*60*60;
+      
+      if( ctime > expiretime )
+      {
+         vg_error( "Ticket expired (client %u)\n", msg->m_conn );
+
+         /* TODO: Send expired information */
+         SteamAPI_ISteamNetworkingSockets_CloseConnection(
+               hSteamNetworkingSockets,
+               msg->m_conn, 0, NULL, 0 );
+         return;
+      }
+   }
+
+   CSteamID steamid;
+   SteamEncryptedAppTicket_GetTicketSteamID( decrypted, ticket_len, &steamid );
+   vg_success( "User is authenticated! steamid %lu (%u)\n", 
+         steamid.m_unAll64Bits, msg->m_conn );
+
+   set_connection_authsteamid( msg->m_conn, steamid.m_unAll64Bits );
+}
+
+static int inet_require_auth( SteamNetworkingMessage_t *msg )
+{
+   if( !get_connection_authsteamid( msg ) )
+   {
+      vg_warn( "Unauthorized request! Disconnecting client: %u\n", 
+            msg->m_conn );
+
+      SteamAPI_ISteamNetworkingSockets_CloseConnection(
+            hSteamNetworkingSockets,
+            msg->m_conn, 0, NULL, 0 );
+
+      return 0;
+   }
+   else return 1;
+}
+
+static void on_inet_score_request( SteamNetworkingMessage_t *msg )
+{
+#if 0
+   if( get_connection_authsteamid( msg ) )
+   {
+      vg_log( "Recieved score request, sending records. (id: %u)\n", 
+               msg->m_conn );
+
+      /* Send back current scores */
+      u32 data_size = sizeof(netmsg_scores_info) + 
+                        0*sizeof(struct netmsg_score_record);
+      netmsg_scores_info *return_info = malloc( data_size );
+
+      return_info->inetmsg_id = k_inetmsg_scores_info;
+      return_info->record_count = 0;
+
+      SteamAPI_ISteamNetworkingSockets_SendMessageToConnection(
+            hSteamNetworkingSockets, msg->m_conn, 
+            return_info, data_size,
+            k_nSteamNetworkingSend_Reliable, NULL );
+   }
+   else
+   {
+      vg_warn( "Unauthorized request! Disconnecting client: %u\n", 
+            msg->m_conn );
+
+      SteamAPI_ISteamNetworkingSockets_CloseConnection(
+            hSteamNetworkingSockets,
+            msg->m_conn, 0, NULL, 0 );
+   }
+#endif
+}
+
+static void on_inet_set_nickname( SteamNetworkingMessage_t *msg )
+{
+   if(!inet_require_auth(msg)) return;
+
+   u64_steamid steamid = get_connection_authsteamid(msg);
+   netmsg_set_nickname *setnick = msg->m_pData;
+   if( msg->m_cbSize < sizeof(netmsg_set_nickname) )
+   {
+      vg_warn( "Invalid nickname request from client: %u, steamid: %lu\n", 
+            msg->m_conn, steamid );
+      return;
+   }
+   
+   highscore_set_user_nickname( steamid, setnick->nickname );
+}
+
+static void on_inet_set_score( SteamNetworkingMessage_t *msg )
+{
+   if(!inet_require_auth(msg)) return;
+
+   u64_steamid steamid = get_connection_authsteamid(msg);
+   
+   if( msg->m_cbSize < sizeof(netmsg_set_score) )
+   {
+      vg_warn( "Invalid set score post from client: %u, steamid: %lu\n",
+            msg->m_conn, steamid );
+      return;
+   }
+
+   netmsg_set_score *info = msg->m_pData;
+
+   if( msg->m_cbSize < sizeof(netmsg_set_score) +
+                       sizeof(struct netmsg_score_record)*info->record_count )
+   {
+      vg_warn( "Malformed set score post from client: %u, steamid: %lu\n",
+            msg->m_conn, steamid );
+      return;
+   }
+
+   for( int i=0; i<info->record_count; i++ )
+   {
+      highscore_record temp;
+      temp.trackid  = info->records[i].trackid;
+      temp.datetime = time(NULL);
+      temp.playerid = steamid;
+      temp.points   = info->records[i].points;
+      temp.time     = info->records[i].time;
+
+      highscores_push_record( &temp );
+   }
+}
+
 static void poll_connections(void)
 {
    SteamNetworkingMessage_t *messages[32];
@@ -118,35 +310,32 @@ static void poll_connections(void)
          }
 
          netmsg_blank *tmp = msg->m_pData;
-         if( tmp->inetmsg_id == k_inetmsg_scores_request )
-         {
-            vg_log( "Recieved score request, sending records. (id: %u)\n", 
-                     msg->m_conn );
-
-            /* Send back current scores */
-            u32 data_size = sizeof(netmsg_scores_info) + 
-                              0*sizeof(struct netmsg_score_record);
-            netmsg_scores_info *return_info = malloc( data_size );
 
-            return_info->inetmsg_id = k_inetmsg_scores_info;
-            return_info->record_count = 0;
-
-            SteamAPI_ISteamNetworkingSockets_SendMessageToConnection(
-                  hSteamNetworkingSockets, msg->m_conn, 
-                  return_info, data_size,
-                  k_nSteamNetworkingSend_Reliable, NULL );
-         }
+         if( tmp->inetmsg_id == k_inetmsg_auth )
+            on_inet_auth( msg );
+         else if( tmp->inetmsg_id == k_inetmsg_scores_request )
+            on_inet_score_request( msg );
+         else if( tmp->inetmsg_id == k_inetmsg_set_nickname )
+            on_inet_set_nickname( msg );
 
          SteamAPI_SteamNetworkingMessage_t_Release( msg );
       }
    }
 }
 
+u64 seconds_to_server_ticks( double s )
+{
+   return s / 0.1;
+}
+
 int main( int argc, char *argv[] )
 {
-   steamworks_ensure_txt( "2103940" );
    signal( SIGINT, inthandler );
+   signal( SIGQUIT, inthandler );
 
+   highscores_init( 250000, 10000 );
+
+   steamworks_ensure_txt( "2103940" );
    if( !vg_load_steam_symetric_key( "application_key", steam_symetric_key ) )
       return 0;
 
@@ -203,7 +392,8 @@ int main( int argc, char *argv[] )
    SteamAPI_ISteamHTTP_SendHTTPRequest( hSteamHTTP, test_req, &call1->id );
 #endif
 
-   u64 server_ticks = 8000;
+   u64 server_ticks = 8000,
+       last_record_save = 8000;
 
    while( !sig_stop )
    {
@@ -212,7 +402,16 @@ int main( int argc, char *argv[] )
 
       usleep(100000);
       server_ticks ++;
+
+      if(last_record_save+server_ticks > seconds_to_server_ticks( 10.0*60.0 ))
+      {
+         last_record_save = server_ticks;
+         highscores_serialize_all();
+      }
    }
+
+   highscores_serialize_all();
+   highscores_free();
    
    SteamAPI_ISteamNetworkingSockets_DestroyPollGroup( hSteamNetworkingSockets,
          client_pollgroup );
index aa1bf13b86f7cf6312c312aa618f8b295f2c0837..5e2cd93c8ed863676e8d5690c2d54f682c92049d 100644 (file)
--- a/testaa.c
+++ b/testaa.c
@@ -17,14 +17,15 @@ int main(int argc, const char *argv[])
 {
    vg_info( "Database test\n" );
 
-   if( !highscores_init( 200000 ) )
+   if( !highscores_init( 200000, 100000 ) )
       return 0;
-
+   
+   srand(time(0));
    vg_log( "Inserting test records...\n" );
-   for( int i=0; i<200000; i++ )
+   for( int i=0; i<5000; i++ )
    {
       highscore_record entry;
-      entry.trackid = vg_randf() * 129.0f;
+      entry.trackid = vg_randf() * 138.0f;
       entry.points = vg_randf() * 10000.0f;
       entry.time = vg_randf() * 20000.0f;
       entry.playerid = rand() % 800;
@@ -32,9 +33,30 @@ int main(int argc, const char *argv[])
       
       highscores_push_record( &entry );
    }
+
+   for( int i=0; i<80; i++ )
+   {
+      char rando[16];
+
+      int l=2+rand()%8;
+      for( int i=0; i<l; i++ )
+         rando[i] = 'a' + rand() % 10;
+      rando[l] = '\0';
+
+      highscore_set_user_nickname( rand() % 800, rando );
+   }
+
    vg_log( "Done.\n" );
 
-   highscores_print_track( 2, 10 );
+#if 0
+   int ln =0, err=0;
+   aatree_show_counts( &highscore_system.aainfo_playerinfo_playerid,
+                        highscore_system.dbheader.playerinfo_root, 0,
+                        &ln, &err, _highscore_showname, 1 );
+#endif
+
+   highscores_print_track( 12, 10 );
+   highscores_serialize_all();
    highscores_free();
    return 0;
 }