aboutsummaryrefslogtreecommitdiffstats
path: root/scoretbl.c
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2012-03-09 18:42:26 -0800
committerH. Peter Anvin <hpa@zytor.com>2012-03-09 18:42:26 -0800
commit49753cec02949d52e5d3b1a47046ca6dcff07d93 (patch)
tree22fea9f95fd5cdad4208e3ce20d7ac431581785e /scoretbl.c
parent2ff9ba56832017ddc4227cece65fa0f83ccc7064 (diff)
downloadgrv-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.
Diffstat (limited to 'scoretbl.c')
-rw-r--r--scoretbl.c57
1 files changed, 45 insertions, 12 deletions
diff --git a/scoretbl.c b/scoretbl.c
index 78d9726..0b7e877 100644
--- a/scoretbl.c
+++ b/scoretbl.c
@@ -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;
+}