From 5ee174baa9b2c30e01dc0ca0dfa38f916f805636 Mon Sep 17 00:00:00 2001 From: hgn Date: Sat, 13 Aug 2022 22:47:34 +0100 Subject: [PATCH] loadsa work --- build.sh | 20 ++++ highscores.h | 271 ++++++++++++++++++++++++++++++++++++++++++++++++++ main.c | 2 +- network.h | 27 ++++- network_msg.h | 10 ++ testaa.c | 150 ++++++++++++++++++++++++++++ 6 files changed, 477 insertions(+), 3 deletions(-) create mode 100644 highscores.h create mode 100644 testaa.c diff --git a/build.sh b/build.sh index a4683b7..ace67bf 100755 --- a/build.sh +++ b/build.sh @@ -155,6 +155,20 @@ vg_command(){ compile_x ;; + testaa) + titleit "Dev" + mkdir -p bin/aatest/cfg + + _compiler=$_linux_compiler + _options=$_linux_options + _link="-lm" + _src="testaa.c" + _folder=bin/aatest + _dst="testaa" + _ext="" + + compile_x + ;; #TODO: These are not cross platform in the build script, a full build # from source is therefore not possible on windows, only a linux @@ -213,6 +227,12 @@ vg_command(){ run_server wait ;; + aa) + run_command testaa + cd bin/aatest + ./testaa + cd ./../ + ;; *) echo "Unrecognised command $1" esac diff --git a/highscores.h b/highscores.h new file mode 100644 index 0000000..2ffaf6a --- /dev/null +++ b/highscores.h @@ -0,0 +1,271 @@ +#ifndef HIGHSCORES_H +#define HIGHSCORES_H + +#include "vg/vg_store.h" +#include "vg/vg_stdint.h" + +/* + * Designed to be used across client and server, + * for the client its only storing the local users records, for server its + * storing many. + */ + +typedef struct highscore highscore; +typedef struct highscore_record highscore_record; +typedef struct highscore_track_table highscore_track_table; +typedef struct highscore_database highscore_database; + +#pragma pack(push,1) +struct highscore_record +{ + u16 trackid, points, time, reserved0; + u64 playerid; + u32 datetime; + + u32 reserved[7]; + + union + { + struct + { + aatree_node points, + time, + playerid, + datetime; + } + aa; + + struct + { + /* TODO pool allocator */ + u32 next, prev; + } + pool; + }; +}; + +struct highscore_track_table +{ + aatree_ptr root_points, + root_time, + root_playerid, + root_datetime; + + u32 reserved[12]; +}; + +struct highscore_database +{ + highscore_track_table tracks[ 128 ]; + + aatree_ptr pool_head; + u32 reserved[63]; +}; + +#pragma pack(pop) + +static struct highscore_system +{ + highscore_database dbheader; + aatree aainfo, + aainfo_points, + aainfo_time, + aainfo_playerid, + aainfo_datetime; + + void *data; +} +highscore_system; + +static int highscore_cmp_points( void *a, void *b ) +{ + highscore_record *pa = a, *pb = b; + return (int)pa->points - (int)pb->points; +} + +static int highscore_cmp_datetime( void *a, void *b ) +{ + highscore_record *pa = a, *pb = b; + + if( pa->datetime == pb->datetime ) return 0; + return pa->datetime < pb->datetime? 1: -1; +} + +static int highscore_cmp_time( void *a, void *b ) +{ + highscore_record *pa = a, *pb = b; + return (int)pb->time - (int)pa->time; +} + +static int highscore_cmp_playerid( void *a, void *b ) +{ + highscore_record *pa = a, *pb = b; + if( pa->playerid == pb->playerid ) return 0; + return pa->playerid < pb->playerid? -1: 1; +} + +static int highscores_init( u32 pool_size ) +{ + struct highscore_system *sys = &highscore_system; + + size_t requested_mem = pool_size * sizeof(highscore_record); + sys->data = malloc( requested_mem ); + + requested_mem /= 1024; + requested_mem /= 1024; + + if( !highscore_system.data ) + { + vg_error( "Could not allocated %dmb of memory for database\n", + requested_mem ); + return 0; + } + else + vg_success( "Allocated %dmb for database\n", requested_mem ); + + /* This is ugly.. too bad! */ + sys->aainfo.base = highscore_system.data; + sys->aainfo.stride = sizeof(highscore_record); + sys->aainfo.offset = offsetof(highscore_record,pool); + sys->aainfo.p_cmp = NULL; + + sys->aainfo_datetime.base = highscore_system.data; + sys->aainfo_datetime.stride = sizeof(highscore_record); + sys->aainfo_datetime.offset = offsetof(highscore_record,aa.datetime); + sys->aainfo_datetime.p_cmp = highscore_cmp_datetime; + + sys->aainfo_points.base = highscore_system.data; + sys->aainfo_points.stride = sizeof(highscore_record); + sys->aainfo_points.offset = offsetof(highscore_record,aa.points); + sys->aainfo_points.p_cmp = highscore_cmp_points; + + sys->aainfo_time.base = highscore_system.data; + sys->aainfo_time.stride = sizeof(highscore_record); + sys->aainfo_time.offset = offsetof(highscore_record,aa.time); + sys->aainfo_time.p_cmp = highscore_cmp_time; + + sys->aainfo_playerid.base = highscore_system.data; + sys->aainfo_playerid.stride = sizeof(highscore_record); + sys->aainfo_playerid.offset = offsetof(highscore_record,aa.playerid); + sys->aainfo_playerid.p_cmp = highscore_cmp_playerid; + + + /* TODO: Load from disk if avalible */ + if( 0 ) + { + + } + else + { + vg_info( "Initializing database nodes\n" ); + sys->dbheader.pool_head = aatree_init_pool( &sys->aainfo, pool_size ); + + for( int i=0; idbheader.tracks); i++ ) + { + highscore_track_table *table = &sys->dbheader.tracks[i]; + table->root_points = AATREE_PTR_NIL; + table->root_playerid = AATREE_PTR_NIL; + table->root_time = AATREE_PTR_NIL; + table->root_datetime = AATREE_PTR_NIL; + } + } + + return 1; +} + +static void highscores_free(void) +{ + free( highscore_system.data ); +} + +static aatree_ptr highscores_push_record( highscore_record *record ) +{ + struct highscore_system *sys = &highscore_system; + + /* TODO: Verify steam ID */ + vg_log( "Inserting record into database for track %hu\n",record->trackid ); + + if( record->trackid >= vg_list_size(sys->dbheader.tracks) ) + { + vg_error( "TrackID out of range (%hu>=%d)\n", record->trackid, + vg_list_size(sys->dbheader.tracks) ); + + return AATREE_PTR_NIL; + } + + /* Search for existing record on this track */ + highscore_track_table *table = &sys->dbheader.tracks[record->trackid]; + aatree_ptr existing = aatree_find( &sys->aainfo_playerid, + table->root_playerid, + record ); + + if( existing != AATREE_PTR_NIL ) + { + 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 ); + table->root_points = aatree_del( &sys->aainfo_points, existing ); + table->root_time = aatree_del( &sys->aainfo_time, existing ); + + aatree_pool_free( &sys->aainfo, existing, &sys->dbheader.pool_head ); + } + + aatree_ptr index = + aatree_pool_alloc( &sys->aainfo, &sys->dbheader.pool_head ); + + if( index == AATREE_PTR_NIL ) + return index; + + highscore_record *dst = aatree_get_data( &sys->aainfo, index ); + memset( dst, 0, sizeof(highscore_record) ); + + dst->trackid = record->trackid; + dst->datetime = record->datetime; + dst->playerid = record->playerid; + dst->points = record->points; + dst->time = record->time; + + table->root_time = + aatree_insert( &sys->aainfo_time, table->root_time, index ); + table->root_datetime = + aatree_insert( &sys->aainfo_datetime, table->root_datetime, index ); + table->root_playerid = + aatree_insert( &sys->aainfo_playerid, table->root_playerid, index ); + table->root_points = + aatree_insert( &sys->aainfo_points, table->root_points, index ); + + return index; +} + +static void _highscore_showtime( void *data ) +{ + highscore_record *record = data; + printf( "%hu", record->time ); +} + +static void highscores_print_track( u32 trackid, u32 count ) +{ + struct highscore_system *sys = &highscore_system; + + 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" ); + + 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, + record->trackid ); + + i++; + it = aatree_next( &sys->aainfo_time, it ); + } + + vg_info( "==============================================\n" ); +} + +#endif /* HIGHSCORES_H */ diff --git a/main.c b/main.c index bfac7fd..175f12e 100644 --- a/main.c +++ b/main.c @@ -23,7 +23,7 @@ static int sv_scene = 0; #define SR_NETWORKED /* uncomment this to run the game without any graphics being drawn */ -#define SR_NETWORK_TEST +//#define SR_NETWORK_TEST #include "steam.h" #include "network.h" diff --git a/network.h b/network.h index 1644982..ee0f334 100644 --- a/network.h +++ b/network.h @@ -24,7 +24,6 @@ static void network_end(void); */ static void network_submit_highscore( u32 trackid, u16 points, u16 time ); - /* * Game endpoints are provided with the same names to allow running without a * network connection. @@ -112,6 +111,23 @@ static void server_connect(void) hSteamNetworkingSockets, &remoteAddr, 0, NULL ); } +static void send_auth_ticket(void) +{ + u32 size = sizeof(netmsg_auth) + steam_app_ticket_length; + netmsg_auth *auth = malloc(size); + + auth.inetmsg_id = k_inetmsg_auth; + auth.ticket_length = steam_app_ticket_length; + for( int i=0; i +#include +#include +#include +#include +#include + +#include "vg/vg_platform.h" +#include "vg/vg_stdint.h" +#include "vg/vg_store.h" +#include "vg/vg_io.h" +#include "vg/vg_m.h" + +#include "highscores.h" + +int main(int argc, const char *argv[]) +{ + vg_info( "Database test\n" ); + + if( !highscores_init( 200000 ) ) + return 0; + + vg_log( "Inserting test records...\n" ); + for( int i=0; i<200000; i++ ) + { + highscore_record entry; + entry.trackid = vg_randf() * 129.0f; + entry.points = vg_randf() * 10000.0f; + entry.time = vg_randf() * 20000.0f; + entry.playerid = rand() % 800; + entry.datetime = vg_randf() * 100000.0f; + + highscores_push_record( &entry ); + } + vg_log( "Done.\n" ); + + highscores_print_track( 2, 10 ); + highscores_free(); + return 0; +} + +#if 0 +typedef struct yoyo_t yoyo_t; +struct yoyo_t +{ + int my_data; + aatree_node anode; +}; + +static void yoyo_t_show( void *_data ) +{ + yoyo_t *data = _data; + printf( "%d ", data->my_data ); +} + +static int yoyo_t_cmp( void *_a, void *_b ) +{ + yoyo_t *a = _a, *b = _b; + return b->my_data - a->my_data; +} + +int main(int argc, const char *argv[]) +{ + yoyo_t *allsorts = malloc( sizeof(yoyo_t) * 10000 ); + + aatree test; + test.base = allsorts; + test.offset = offsetof( yoyo_t, anode ); + test.stride = sizeof( yoyo_t ); + test.p_cmp = yoyo_t_cmp; + + for( int i=0; i<30; i++ ) vg_randf(); + + for( int j=0; j<1000; j++ ) + { + int spam_amt = 100; + aatree_ptr root = AATREE_PTR_NIL; + for( int i=0; imy_data = vg_randf() * 563.0f; + root = aatree_insert( &test, root, i ); + } + + int ln=0, err=0; + int drawting = 1; + aatree_show_counts( &test, root, 0, &ln, &err, yoyo_t_show, drawting ); + +#if 0 + int value = 3; + vg_info( "Ptr of %d: %u\n", value, aatree_find( &test, root, &value ) ); + + for( int i=0; i<20; i++ ) + { + yoyo_t *v = aatree_get_data(&test,aatree_kth( &test, root, i )); + vg_info( "Value of [%d]: %d\n", i, v->my_data ); + } +#endif + if( ln != spam_amt || err != 0 ) + { + vg_error( "ADJAWIUDWAJD\n" ); + break; + } + + aatree_ptr traverser = aatree_kth( &test, root, 0 ); + + while( traverser != AATREE_PTR_NIL ) + { + yoyo_t *v = aatree_get_data( &test, traverser ); + vg_info( "... %d\n", v->my_data ); + + traverser = aatree_next( &test, traverser ); + } + + int orig = spam_amt; + for( int i=0; i