summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2012-03-10 02:42:26 (GMT)
committerH. Peter Anvin <hpa@zytor.com>2012-03-10 02:42:26 (GMT)
commit49753cec02949d52e5d3b1a47046ca6dcff07d93 (patch)
tree22fea9f95fd5cdad4208e3ce20d7ac431581785e
parent2ff9ba56832017ddc4227cece65fa0f83ccc7064 (diff)
downloadgrv-49753cec02949d52e5d3b1a47046ca6dcff07d93.zip
grv-49753cec02949d52e5d3b1a47046ca6dcff07d93.tar.gz
grv-49753cec02949d52e5d3b1a47046ca6dcff07d93.tar.bz2
grv-49753cec02949d52e5d3b1a47046ca6dcff07d93.tar.xz
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.c4
-rw-r--r--grv.h4
-rw-r--r--grvscored.c11
-rw-r--r--highscore.c84
-rw-r--r--highscore.h17
-rw-r--r--netopen.c5
-rw-r--r--play.c5
-rw-r--r--scoretbl.c57
8 files changed, 126 insertions, 61 deletions
diff --git a/grv.c b/grv.c
index 65c8b2c..1a1476e 100644
--- a/grv.c
+++ b/grv.c
@@ -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();
diff --git a/grv.h b/grv.h
index 3bd28bc..5c81879 100644
--- a/grv.h
+++ b/grv.h
@@ -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
diff --git a/netopen.c b/netopen.c
index 6dabec9..cf17cda 100644
--- a/netopen.c
+++ b/netopen.c
@@ -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;
diff --git a/play.c b/play.c
index 59091b6..612e150 100644
--- a/play.c
+++ b/play.c
@@ -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++ ) {
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;
+}