Rewrite accounting of play time
Replace daychange() and gettimeleft() by update_timeused_login(), update_timeused() and enforce_minimum_session_time(). The new code doesn't assume the day is always 24 hours long which can occur when transitioning into or out of DST and such. Logging in after more a multiple of 128 days now resets nat_timeused properly. Fix nat_timeused calculation on midnight rollover to include the time since midnight. struct natstr member nat_dayno and struct player member timeleft are now unused, remove them.
This commit is contained in:
parent
f46dc55254
commit
875a80d14f
8 changed files with 69 additions and 74 deletions
|
@ -95,7 +95,6 @@ struct natstr {
|
||||||
char nat_userid[32]; /* userid of last user, may be empty */
|
char nat_userid[32]; /* userid of last user, may be empty */
|
||||||
coord nat_xcap, nat_ycap; /* cap location in abs coords */
|
coord nat_xcap, nat_ycap; /* cap location in abs coords */
|
||||||
coord nat_xorg, nat_yorg; /* origin location in abs coords */
|
coord nat_xorg, nat_yorg; /* origin location in abs coords */
|
||||||
signed char nat_dayno; /* day of the year mod 128 */
|
|
||||||
signed char nat_update; /* Want an update or not. */
|
signed char nat_update; /* Want an update or not. */
|
||||||
unsigned short nat_tgms; /* # of telegrams to be announced */
|
unsigned short nat_tgms; /* # of telegrams to be announced */
|
||||||
unsigned short nat_ann; /* # of annos pending */
|
unsigned short nat_ann; /* # of annos pending */
|
||||||
|
|
|
@ -67,8 +67,7 @@ struct player {
|
||||||
char *argp[128]; /* arguments, ASCII, valid if command */
|
char *argp[128]; /* arguments, ASCII, valid if command */
|
||||||
char *condarg; /* conditional, ASCII, valid if command */
|
char *condarg; /* conditional, ASCII, valid if command */
|
||||||
char *comtail[128]; /* start of args in combuf[] */
|
char *comtail[128]; /* start of args in combuf[] */
|
||||||
time_t lasttime; /* when timeleft was last debited */
|
time_t lasttime; /* when nat_timeused was last updated */
|
||||||
int timeleft;
|
|
||||||
int btused;
|
int btused;
|
||||||
int god;
|
int god;
|
||||||
int owner;
|
int owner;
|
||||||
|
|
|
@ -367,8 +367,9 @@ extern int getcommand(char *);
|
||||||
extern void init_player_commands(void);
|
extern void init_player_commands(void);
|
||||||
extern void log_last_commands(void);
|
extern void log_last_commands(void);
|
||||||
extern int gamedown(void);
|
extern int gamedown(void);
|
||||||
extern void daychange(time_t);
|
extern void update_timeused_login(time_t now);
|
||||||
extern int gettimeleft(time_t, int);
|
extern void update_timeused(time_t now);
|
||||||
|
extern void enforce_minimum_session_time(void);
|
||||||
/* more under Commands */
|
/* more under Commands */
|
||||||
/* empmod.c */
|
/* empmod.c */
|
||||||
/* init_nats.c */
|
/* init_nats.c */
|
||||||
|
|
|
@ -563,7 +563,6 @@ struct castr cou_ca[] = {
|
||||||
EF_BAD, NSC_DEITY | NSC_EXTRA},
|
EF_BAD, NSC_DEITY | NSC_EXTRA},
|
||||||
{"yorg", fldoff(nat_yorg), NSC_YCOORD, 0, NULL,
|
{"yorg", fldoff(nat_yorg), NSC_YCOORD, 0, NULL,
|
||||||
EF_BAD, NSC_DEITY | NSC_EXTRA},
|
EF_BAD, NSC_DEITY | NSC_EXTRA},
|
||||||
{"dayno", fldoff(nat_dayno), NSC_CHAR, 0, NULL, EF_BAD, 0},
|
|
||||||
{"update", fldoff(nat_update), NSC_CHAR, 0, NULL, EF_BAD, 0},
|
{"update", fldoff(nat_update), NSC_CHAR, 0, NULL, EF_BAD, 0},
|
||||||
{"tgms", fldoff(nat_tgms), NSC_USHORT, 0, NULL, EF_BAD, 0},
|
{"tgms", fldoff(nat_tgms), NSC_USHORT, 0, NULL, EF_BAD, 0},
|
||||||
{"ann", fldoff(nat_ann), NSC_USHORT, 0, NULL, EF_BAD, 0},
|
{"ann", fldoff(nat_ann), NSC_USHORT, 0, NULL, EF_BAD, 0},
|
||||||
|
|
|
@ -213,33 +213,58 @@ gamedown(void)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
seconds_since_midnight(time_t time)
|
||||||
|
{
|
||||||
|
struct tm *tm = localtime(&time);
|
||||||
|
time_t midnight;
|
||||||
|
|
||||||
|
tm->tm_hour = 0;
|
||||||
|
tm->tm_min = 0;
|
||||||
|
tm->tm_sec = 0;
|
||||||
|
tm->tm_isdst = -1;
|
||||||
|
midnight = mktime(tm);
|
||||||
|
|
||||||
|
return(time - midnight);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
daychange(time_t now)
|
update_timeused_login(time_t now)
|
||||||
{
|
{
|
||||||
struct natstr *natp;
|
struct natstr *natp = getnatp(player->cnum);
|
||||||
struct tm *tm;
|
time_t midnight_secs = seconds_since_midnight(player->lasttime);
|
||||||
|
|
||||||
natp = getnatp(player->cnum);
|
if (now - natp->nat_last_logout > midnight_secs) {
|
||||||
tm = localtime(&now);
|
|
||||||
if ((tm->tm_yday % 128) != natp->nat_dayno) {
|
|
||||||
natp->nat_dayno = tm->tm_yday % 128;
|
|
||||||
natp->nat_timeused = 0;
|
natp->nat_timeused = 0;
|
||||||
|
putnat(natp);
|
||||||
}
|
}
|
||||||
|
player->lasttime = now;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
void
|
||||||
gettimeleft(time_t now, int mpd)
|
update_timeused(time_t now)
|
||||||
{
|
{
|
||||||
struct tm *tm;
|
struct natstr *natp = getnatp(player->cnum);
|
||||||
int nsecleft;
|
time_t midnight_secs = seconds_since_midnight(now);
|
||||||
struct natstr *natp;
|
time_t dt = now - player->lasttime;
|
||||||
int n;
|
|
||||||
|
|
||||||
tm = localtime(&now);
|
if (dt > midnight_secs)
|
||||||
natp = getnatp(player->cnum);
|
natp->nat_timeused = midnight_secs;
|
||||||
nsecleft = mpd * 60 - natp->nat_timeused;
|
else
|
||||||
n = 60 * 60 * 24 - (tm->tm_sec + tm->tm_min * 60 + tm->tm_hour * 3600);
|
natp->nat_timeused += dt;
|
||||||
if (n < nsecleft)
|
player->lasttime = now;
|
||||||
nsecleft = n;
|
putnat(natp);
|
||||||
return nsecleft;
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
enforce_minimum_session_time(void)
|
||||||
|
{
|
||||||
|
struct natstr *natp = getnatp(player->cnum);
|
||||||
|
|
||||||
|
time_t dt = natp->nat_last_logout - natp->nat_last_login;
|
||||||
|
if (dt > seconds_since_midnight(natp->nat_last_logout))
|
||||||
|
dt = seconds_since_midnight(natp->nat_last_logout);
|
||||||
|
if (dt < 15)
|
||||||
|
natp->nat_timeused += 15 - dt;
|
||||||
|
putnat(natp);
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,13 +60,12 @@ void
|
||||||
player_main(struct player *p)
|
player_main(struct player *p)
|
||||||
{
|
{
|
||||||
struct natstr *natp;
|
struct natstr *natp;
|
||||||
int secs;
|
|
||||||
char buf[128];
|
char buf[128];
|
||||||
|
|
||||||
p->state = PS_PLAYING;
|
p->state = PS_PLAYING;
|
||||||
player = p;
|
player = p;
|
||||||
time(&player->lasttime);
|
|
||||||
time(&player->curup);
|
time(&player->curup);
|
||||||
|
update_timeused_login(player->curup);
|
||||||
show_motd();
|
show_motd();
|
||||||
if (init_nats() < 0) {
|
if (init_nats() < 0) {
|
||||||
pr("Server confused, try again later\n");
|
pr("Server confused, try again later\n");
|
||||||
|
@ -78,8 +77,8 @@ player_main(struct player *p)
|
||||||
if (natp->nat_stat != STAT_GOD)
|
if (natp->nat_stat != STAT_GOD)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
daychange(player->curup);
|
if (natp->nat_stat == STAT_ACTIVE &&
|
||||||
if ((player->timeleft = gettimeleft(player->curup, m_m_p_d)) <= 0) {
|
natp->nat_timeused > m_m_p_d * 60) {
|
||||||
pr("Time exceeded today\n");
|
pr("Time exceeded today\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -118,14 +117,10 @@ player_main(struct player *p)
|
||||||
}
|
}
|
||||||
/* #*# I put the following line in to prevent server crash -KHS */
|
/* #*# I put the following line in to prevent server crash -KHS */
|
||||||
natp = getnatp(player->cnum);
|
natp = getnatp(player->cnum);
|
||||||
/*
|
|
||||||
* randomly round up to the nearest minute,
|
|
||||||
* charging at least 15 seconds.
|
|
||||||
*/
|
|
||||||
time(&natp->nat_last_logout);
|
time(&natp->nat_last_logout);
|
||||||
secs = MAX(natp->nat_last_logout - player->lasttime, 15);
|
|
||||||
natp->nat_timeused += secs;
|
|
||||||
putnat(natp);
|
putnat(natp);
|
||||||
|
update_timeused(natp->nat_last_logout);
|
||||||
|
enforce_minimum_session_time();
|
||||||
pr("Bye-bye\n");
|
pr("Bye-bye\n");
|
||||||
journal_logout();
|
journal_logout();
|
||||||
}
|
}
|
||||||
|
@ -182,27 +177,7 @@ status(void)
|
||||||
pr("You are no longer broke!\n");
|
pr("You are no longer broke!\n");
|
||||||
|
|
||||||
time(&player->curup);
|
time(&player->curup);
|
||||||
second = player->curup - player->lasttime;
|
update_timeused(player->curup);
|
||||||
if (second > 0) {
|
|
||||||
player->timeleft -= second;
|
|
||||||
if (player->timeleft <= 0) {
|
|
||||||
/*
|
|
||||||
* countdown timer "player->timeleft" has expired.
|
|
||||||
* either day change, or hours restriction
|
|
||||||
*/
|
|
||||||
daychange(player->curup);
|
|
||||||
if (!gamehours(player->curup)) {
|
|
||||||
pr("Empire hours restriction in force\n");
|
|
||||||
if (natp->nat_stat != STAT_GOD) {
|
|
||||||
putnat(natp);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
player->timeleft = gettimeleft(player->curup, m_m_p_d);
|
|
||||||
}
|
|
||||||
player->lasttime += second;
|
|
||||||
natp->nat_timeused += second;
|
|
||||||
}
|
|
||||||
if (natp->nat_stat == STAT_ACTIVE &&
|
if (natp->nat_stat == STAT_ACTIVE &&
|
||||||
natp->nat_timeused > m_m_p_d * 60) {
|
natp->nat_timeused > m_m_p_d * 60) {
|
||||||
pr("Max minutes per day limit exceeded.\n");
|
pr("Max minutes per day limit exceeded.\n");
|
||||||
|
|
|
@ -84,7 +84,6 @@ nat_reset(struct natstr *natp, enum nat_status stat, coord x, coord y)
|
||||||
natp->nat_yorg = 0;
|
natp->nat_yorg = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
natp->nat_dayno = 0;
|
|
||||||
natp->nat_timeused = 0;
|
natp->nat_timeused = 0;
|
||||||
natp->nat_update = 0;
|
natp->nat_update = 0;
|
||||||
|
|
||||||
|
|
|
@ -780,7 +780,7 @@ index 3106849..726b5fc 100644
|
||||||
return lp;
|
return lp;
|
||||||
}
|
}
|
||||||
diff --git a/src/lib/player/player.c b/src/lib/player/player.c
|
diff --git a/src/lib/player/player.c b/src/lib/player/player.c
|
||||||
index 513382b..4b97be7 100644
|
index f81e2f0..a9a1f74 100644
|
||||||
--- a/src/lib/player/player.c
|
--- a/src/lib/player/player.c
|
||||||
+++ b/src/lib/player/player.c
|
+++ b/src/lib/player/player.c
|
||||||
@@ -40,6 +40,7 @@
|
@@ -40,6 +40,7 @@
|
||||||
|
@ -791,18 +791,16 @@ index 513382b..4b97be7 100644
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
#include "journal.h"
|
#include "journal.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
@@ -65,8 +66,8 @@ player_main(struct player *p)
|
@@ -64,7 +65,7 @@ player_main(struct player *p)
|
||||||
|
|
||||||
p->state = PS_PLAYING;
|
p->state = PS_PLAYING;
|
||||||
player = p;
|
player = p;
|
||||||
- time(&player->lasttime);
|
|
||||||
- time(&player->curup);
|
- time(&player->curup);
|
||||||
+ empire_time(&player->lasttime);
|
|
||||||
+ empire_time(&player->curup);
|
+ empire_time(&player->curup);
|
||||||
|
update_timeused_login(player->curup);
|
||||||
show_motd();
|
show_motd();
|
||||||
if (init_nats() < 0) {
|
if (init_nats() < 0) {
|
||||||
pr("Server confused, try again later\n");
|
@@ -98,7 +99,7 @@ player_main(struct player *p)
|
||||||
@@ -100,7 +101,7 @@ player_main(struct player *p)
|
|
||||||
strcpy(natp->nat_hostname, player->hostname);
|
strcpy(natp->nat_hostname, player->hostname);
|
||||||
strcpy(natp->nat_hostaddr, player->hostaddr);
|
strcpy(natp->nat_hostaddr, player->hostaddr);
|
||||||
|
|
||||||
|
@ -811,24 +809,24 @@ index 513382b..4b97be7 100644
|
||||||
putnat(natp);
|
putnat(natp);
|
||||||
journal_login();
|
journal_login();
|
||||||
if (natp->nat_flags & NF_INFORM && natp->nat_tgms > 0) {
|
if (natp->nat_flags & NF_INFORM && natp->nat_tgms > 0) {
|
||||||
@@ -123,7 +124,7 @@ player_main(struct player *p)
|
@@ -117,7 +118,7 @@ player_main(struct player *p)
|
||||||
* randomly round up to the nearest minute,
|
}
|
||||||
* charging at least 15 seconds.
|
/* #*# I put the following line in to prevent server crash -KHS */
|
||||||
*/
|
natp = getnatp(player->cnum);
|
||||||
- time(&natp->nat_last_logout);
|
- time(&natp->nat_last_logout);
|
||||||
+ empire_time(&natp->nat_last_logout);
|
+ empire_time(&natp->nat_last_logout);
|
||||||
secs = MAX(natp->nat_last_logout - player->lasttime, 15);
|
|
||||||
natp->nat_timeused += secs;
|
|
||||||
putnat(natp);
|
putnat(natp);
|
||||||
@@ -182,7 +183,7 @@ status(void)
|
update_timeused(natp->nat_last_logout);
|
||||||
|
enforce_minimum_session_time();
|
||||||
|
@@ -176,7 +177,7 @@ status(void)
|
||||||
if (!(old_nstat & MONEY) && (player->nstat & MONEY))
|
if (!(old_nstat & MONEY) && (player->nstat & MONEY))
|
||||||
pr("You are no longer broke!\n");
|
pr("You are no longer broke!\n");
|
||||||
|
|
||||||
- time(&player->curup);
|
- time(&player->curup);
|
||||||
+ empire_time(&player->curup);
|
+ empire_time(&player->curup);
|
||||||
second = player->curup - player->lasttime;
|
update_timeused(player->curup);
|
||||||
if (second > 0) {
|
if (natp->nat_stat == STAT_ACTIVE &&
|
||||||
player->timeleft -= second;
|
natp->nat_timeused > m_m_p_d * 60) {
|
||||||
diff --git a/src/lib/player/recvclient.c b/src/lib/player/recvclient.c
|
diff --git a/src/lib/player/recvclient.c b/src/lib/player/recvclient.c
|
||||||
index ab4ef69..8934189 100644
|
index ab4ef69..8934189 100644
|
||||||
--- a/src/lib/player/recvclient.c
|
--- a/src/lib/player/recvclient.c
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue