diff options
author | H. Peter Anvin <hpa@zytor.com> | 2012-03-09 18:42:26 -0800 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2012-03-09 18:42:26 -0800 |
commit | 49753cec02949d52e5d3b1a47046ca6dcff07d93 (patch) | |
tree | 22fea9f95fd5cdad4208e3ce20d7ac431581785e | |
parent | 2ff9ba56832017ddc4227cece65fa0f83ccc7064 (diff) | |
download | grv-49753cec02949d52e5d3b1a47046ca6dcff07d93.tar.gz grv-49753cec02949d52e5d3b1a47046ca6dcff07d93.tar.xz grv-49753cec02949d52e5d3b1a47046ca6dcff07d93.zip |
highscore: be smarter about when to upload high scores
Upload high scores whenever we have anything in our local database
which isn't present on the server. This is possible if the network
connection failed to upload last time we connected.
-rw-r--r-- | grv.c | 4 | ||||
-rw-r--r-- | grv.h | 4 | ||||
-rw-r--r-- | grvscored.c | 11 | ||||
-rw-r--r-- | highscore.c | 84 | ||||
-rw-r--r-- | highscore.h | 17 | ||||
-rw-r--r-- | netopen.c | 5 | ||||
-rw-r--r-- | play.c | 5 | ||||
-rw-r--r-- | scoretbl.c | 57 |
8 files changed, 126 insertions, 61 deletions
@@ -139,7 +139,9 @@ int main(int argc, char *argv[]) exit(1); } - highscore_download(); /* Here for testing... */ + highscore_load(); + highscore_download(); + highscore_upload(); /* If we have something the server didn't... */ while ( 1 ) { intro(); @@ -187,9 +187,11 @@ void run_bullets(void); void mystery(void); /* highscore.c */ +void highscore_load(void); void highscore_download(void); +void highscore_save(void); void highscore_upload(void); -void highscore_show(int myrank, int upload); +void highscore_show(int myrank, int save); void highscore_endgame(void); /* intro.c */ diff --git a/grvscored.c b/grvscored.c index 3524001..7e60df4 100644 --- a/grvscored.c +++ b/grvscored.c @@ -27,10 +27,10 @@ int score_send(const char *file) flock(fileno(f), LOCK_SH); alarm(120); /* Make sure we have a sane timeout */ - highscore_parse(f, fgets); + highscore_parse(f, fgets, 0); fclose(f); - return highscore_write(stdout, fputs) ? 1 : 0; + return highscore_write(stdout, fputs, 0) ? 1 : 0; } int score_recv(const char *file) @@ -49,10 +49,9 @@ int score_recv(const char *file) flock(fileno(f), LOCK_EX); alarm(120); /* Make sure we have a sane timeout */ - highscore_parse(f, fgets); - rewind(f); - highscore_parse(stdin, fgets); - if ( highscore_write(t, fputs) ) { + highscore_parse(f, fgets, 0); + highscore_parse(stdin, fgets, 0); + if ( highscore_write(t, fputs, 0) ) { unlink(tp); fclose(f); return 1; diff --git a/highscore.c b/highscore.c index 37bceaf..e7a4073 100644 --- a/highscore.c +++ b/highscore.c @@ -19,44 +19,63 @@ static int score_ul_port = 22393; static const char score_file[] = "grvscore.dat"; +void highscore_load(void) +{ + FILE *f; + + f = fopen(score_file, "r"); + if ( !f ) + return; + + highscore_parse(f, fgets, 1); + fclose(f); +} void highscore_download(void) { - FILE *f; netcon_t n; - f = fopen(score_file, "r"); - if ( f ) { - highscore_parse(f, fgets); - fclose(f); - } + if ( opt.nonet ) + return; - if ( !opt.nonet ) { - if ( (n = fopen_network(score_server, score_dl_port, 0)) ) { - highscore_parse(n, fgets_network); - fclose_network(n); - } - } + n = fopen_network(score_server, score_dl_port, 0); + if ( !n ) + return; + + highscore_parse(n, fgets_network, 0); + fclose_network(n); } +void highscore_save(void) +{ + FILE *f; + + f = fopen(score_file, "w"); + if ( !f ) + return; + + highscore_write(f, fputs, 1); + fclose(f); +} void highscore_upload(void) { - FILE *f; netcon_t n; - f = fopen(score_file, "w"); - if ( f ) { - highscore_write(f, fputs); - fclose(f); - } + if ( opt.nonet ) + return; - if ( !opt.nonet ) { - if ( (n = fopen_network(score_server, score_ul_port, 1)) ) { - highscore_write(n, fputs_network); - fclose_network(n); - } - } + + if ( !have_upload_scores() ) + return; + + + n = fopen_network(score_server, score_ul_port, 1); + if ( !n ) + return; + + highscore_write(n, fputs_network, 0); + fclose_network(n); } /* @@ -163,7 +182,7 @@ static void enter_name(int rank, char *player) * and (if <= 10) let the user enter name */ -void highscore_show(int myrank, int upload) +void highscore_show(int myrank, int save) { int i, x, y; @@ -189,12 +208,13 @@ void highscore_show(int myrank, int upload) if ( myrank > 0 && myrank <= 10 ) enter_name(myrank, bests.total[myrank-1].player); - if ( upload ) { - /* This can't be done until we have let the user enter name, - and this is as good of a place as any, especially since - there is no blink on the screen right now... */ - highscore_upload(); - } + /* This can't be done until we have let the user enter name, + and this is as good of a place as any, especially since + there is no blink on the screen right now... */ + if (save) + highscore_save(); + + highscore_upload(); color(0,gp.c); lprint(21,8,"Please press any key . . ."); @@ -241,7 +261,7 @@ void highscore_endgame(void) if ( gp.Cheat ) myrank = 0; else - myrank = highscore_add_total(gp.gameid, gp.Sc, gp.MLev, NULL); + myrank = highscore_add_total(gp.gameid, gp.Sc, gp.MLev, NULL, 1); highscore_show(myrank, 1); } diff --git a/highscore.h b/highscore.h index 4047862..5976c69 100644 --- a/highscore.h +++ b/highscore.h @@ -17,16 +17,19 @@ struct best_total { int64_t score; /* Final score */ int32_t endlvl; /* Ending level (-1) */ unsigned char player[PLAYER_LEN+1]; /* Player alias */ + uint8_t upload; /* Need upload */ }; struct best_level { struct best_level_score { uint64_t gameid; int64_t score; + uint8_t upload; } score[MAX_PER_LEVEL]; struct best_level_time { uint64_t gameid; int32_t time_ms; + uint8_t upload; } time_ms[MAX_PER_LEVEL]; }; @@ -39,11 +42,15 @@ extern struct bests bests; #define NO_TIME 0x7fffffff /* Max int32_t value */ -int highscore_add_total(uint64_t gameid, int64_t score, int endlvl, unsigned char **pptr); -int highscore_add_level_score(uint64_t gameid, int lvl, int64_t score); -int highscore_add_level_time(uint64_t gameid, int lvl, int32_t time_ms); +int highscore_add_total(uint64_t gameid, int64_t score, int endlvl, + unsigned char **pptr, uint8_t upload); +int highscore_add_level_score(uint64_t gameid, int lvl, int64_t score, + uint8_t upload); +int highscore_add_level_time(uint64_t gameid, int lvl, int32_t time_ms, + uint8_t upload); void highscore_init(void); -void highscore_parse(void *f, char (*mygets)(char *, int, void *)); -int highscore_write(void *f, int (*myputs)(char *, void *)); +void highscore_parse(void *f, char (*mygets)(char *, int, void *), + uint8_t upload); +int highscore_write(void *f, int (*myputs)(char *, void *), uint8_t leave); #endif @@ -8,9 +8,10 @@ #include "network.h" #include <stdio.h> -#ifdef WIN32 +#ifdef __WIN32__ #define _WIN32_WINNT 0x0501 /* Windows XP */ +#include <windows.h> #include <string.h> #include <io.h> #include <fcntl.h> @@ -18,7 +19,7 @@ #include <ws2tcpip.h> /* This is basically a lame subset of stdio functionality */ -#define NETCON_BUF 32768 +#define NETCON_BUF 65536 struct netcon { int is_output; int buffill; @@ -722,7 +722,7 @@ static void end_level(int done) rank = 0; } else { rank = highscore_add_level_time(gp.gameid, gp.Level, - (int32_t)(gp.Tid * 1000.0)); + (int32_t)(gp.Tid * 1000.0), 1); } for ( i = 0 ; i < 3 ; i++ ) { @@ -743,7 +743,8 @@ static void end_level(int done) if ( gp.Cheat ) { rank = 0; } else { - rank = highscore_add_level_score(gp.gameid, gp.Level, gp.Sc-gp.StScore); + rank = highscore_add_level_score(gp.gameid, gp.Level, + gp.Sc-gp.StScore, 1); } for ( i = 0 ; i < 3 ; i++ ) { @@ -22,8 +22,8 @@ struct bests bests; * Insert a total; return a pointer to the player name string * if applicable. Return place [1,MAX_BEST] or 0 if no ranking */ -int highscore_add_total(uint64_t gameid, int64_t score, - int endlvl, unsigned char **pptr) +int highscore_add_total(uint64_t gameid, int64_t score, int endlvl, + unsigned char **pptr, uint8_t upload) { struct best_total *tp = bests.total; int i; @@ -34,23 +34,30 @@ int highscore_add_total(uint64_t gameid, int64_t score, tp->gameid = gameid; tp->score = score; tp->endlvl = endlvl; + tp->upload = upload; memset(tp->player, 0, sizeof tp->player); - if ( pptr ) *pptr = tp->player; + if ( pptr ) + *pptr = tp->player; return i+1; } else if ( gameid == tp->gameid && score == tp->score ) { - if ( pptr ) *pptr = tp->player; + tp->upload &= upload; + if ( pptr ) + *pptr = tp->player; return i+1; } } - if ( pptr ) *pptr = NULL; + if ( pptr ) + *pptr = NULL; + return 0; } /* * Insert a level best score, return rank (or 0 if N/A) */ -int highscore_add_level_score(uint64_t gameid, int lvl, int64_t score) +int highscore_add_level_score(uint64_t gameid, int lvl, + int64_t score, uint8_t upload) { struct best_level_score *tp; int i; @@ -65,8 +72,10 @@ int highscore_add_level_score(uint64_t gameid, int lvl, int64_t score) memmove(tp+1, tp, (MAX_PER_LEVEL-1-i)*sizeof(*tp)); tp->gameid = gameid; tp->score = score; + tp->upload = upload; return i+1; } else if ( gameid == tp->gameid && score == tp->score ) { + tp->upload &= upload; return i+1; } } @@ -77,7 +86,8 @@ int highscore_add_level_score(uint64_t gameid, int lvl, int64_t score) /* * Insert a level best time, return rank (or 0 if N/A) */ -int highscore_add_level_time(uint64_t gameid, int lvl, int32_t time_ms) +int highscore_add_level_time(uint64_t gameid, int lvl, + int32_t time_ms, uint8_t upload) { struct best_level_time *tp; int i; @@ -92,8 +102,10 @@ int highscore_add_level_time(uint64_t gameid, int lvl, int32_t time_ms) memmove(tp+1, tp, (MAX_PER_LEVEL-1-i)*sizeof(*tp)); tp->gameid = gameid; tp->time_ms = time_ms; + tp->upload = upload; return i+1; } else if ( gameid == tp->gameid && time_ms == tp->time_ms ) { + tp->upload &= upload; return i+1; } } @@ -161,7 +173,8 @@ static char *quote(const unsigned char *i) * kind of sane way to use the stdio library with sockets, we have to abstract * out the I/O function that is allowed to access this. Puke. */ -void highscore_parse(void *f, char (*mygets)(char *, int, void *)) +void highscore_parse(void *f, char (*mygets)(char *, int, void *), + uint8_t upload) { char line[MAXLINE], pname[MAXLINE]; uint64_t gameid; @@ -176,17 +189,17 @@ void highscore_parse(void *f, char (*mygets)(char *, int, void *)) if ( sscanf(line, "TS %" SCNx64 " %" SCNd64 " %d %[0-9a-f]", &gameid, &score, &lvl, pname) == 4 ) { - highscore_add_total(gameid, score, lvl-1, &pptr); + highscore_add_total(gameid, score, lvl-1, &pptr, upload); if ( pptr ) { strncpy(pptr, unquote(pname), PLAYER_LEN+1); pptr[PLAYER_LEN] = '\0'; } } else if ( sscanf(line, "LS %" SCNx64 " %d %" SCNd64, &gameid, &lvl, &score) == 3 ) { - highscore_add_level_score(gameid, lvl-1, score); + highscore_add_level_score(gameid, lvl-1, score, upload); } else if ( sscanf(line, "LT %" SCNx64 " %d %" SCNd32, &gameid, &lvl, &time_ms) == 3 ) { - highscore_add_level_time(gameid, lvl-1, time_ms); + highscore_add_level_time(gameid, lvl-1, time_ms, upload); } } } @@ -194,7 +207,7 @@ void highscore_parse(void *f, char (*mygets)(char *, int, void *)) /* * Write out a high score file; return 0 on success, -1 on failure */ -int highscore_write(void *f, int (*myputs)(char *, void *)) +int highscore_write(void *f, int (*myputs)(char *, void *), uint8_t leave) { char buffer[MAXLINE]; int i, j; @@ -208,6 +221,7 @@ int highscore_write(void *f, int (*myputs)(char *, void *)) bests.total[i].endlvl+1, quote(bests.total[i].player)); if ( myputs(buffer, f) == EOF ) return -1; + bests.total[i].upload &= leave; } } @@ -219,6 +233,7 @@ int highscore_write(void *f, int (*myputs)(char *, void *)) i+1, bests.level[i].score[j].score); if ( myputs(buffer, f) == EOF ) return -1; + bests.level[i].score[j].upload &= leave; } for ( j = 0 ; j < MAX_PER_LEVEL ; j++ ) { if ( bests.level[i].time_ms[j].time_ms != NO_TIME ) @@ -227,8 +242,26 @@ int highscore_write(void *f, int (*myputs)(char *, void *)) i+1, bests.level[i].time_ms[j].time_ms); if ( myputs(buffer, f) == EOF ) return -1; + bests.level[i].time_ms[j].upload &= leave; } } return 0; } + +int have_upload_scores(void) +{ + int i, j; + + for ( i = 0 ; i < MAX_BEST ; i++ ) + if ( bests.total[i].upload ) + return 1; + + for ( i = 0 ; i < MAX_LEVEL ; i++ ) + for ( j = 0 ; j < MAX_PER_LEVEL ; j++ ) + if ( bests.level[i].score[j].upload || + bests.level[i].time_ms[j].upload ) + return 1; + + return 0; +} |