tWe now support dates properly. Names.Month and Names.Year no longer exist; they are replaced by StartDate and Names.Date. This changes the protocol; old clients without the A_DATE ability will be fed suitable defaults for Names.Month and Names.Year so as not to upset them. - vaccinewars - be a doctor and try to vaccinate the world
(HTM) git clone git://src.adamsgaard.dk/vaccinewars
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
(DIR) commit 9a9ff0d914d62a5f3dd56db880f7a1aca7887d20
(DIR) parent ce396c47d1a0063856c581d2028b88bbd91111a9
(HTM) Author: Ben Webb <ben@salilab.org>
Date: Mon, 12 Aug 2002 11:33:56 +0000
We now support dates properly. Names.Month and Names.Year no longer exist;
tthey are replaced by StartDate and Names.Date. This changes the protocol;
old clients without the A_DATE ability will be fed suitable defaults for
Names.Month and Names.Year so as not to upset them.
Diffstat:
M ChangeLog | 3 +++
M TODO | 1 -
M doc/configfile.html | 23 +++++++++++++++--------
M src/curses_client/curses_client.c | 2 +-
M src/dopewars.c | 57 +++++++++++++++++++++++--------
M src/dopewars.h | 11 ++++++++++-
M src/gui_client/gtk_client.c | 2 +-
M src/message.c | 41 +++++++++++++++++++++++++------
M src/serverside.c | 1 +
9 files changed, 107 insertions(+), 34 deletions(-)
---
(DIR) diff --git a/ChangeLog b/ChangeLog
t@@ -8,6 +8,9 @@ cvs
all network messages will be sent in UTF-8 (Unicode) encoding (without
the ability, all messages are assumed to be in your locale's default
codeset, which may cause problems on non-US ASCII systems)
+ - Names.Month and Names.Year have been replaced with StartDate.Day,
+ StartDate.Month, StartDate.Year and Names.Date; these can be used to
+ handle the date display properly after the turn number exceeds 31
- Encoding config variable added, to allow the config file's encoding
(usually taken from the locale) to be overridden
- Spanish translation added by Quique
(DIR) diff --git a/TODO b/TODO
t@@ -1,7 +1,6 @@
- Fix the Encoding variable so that a) it works only on the current file
(not on _all_ config files) and b) it only translates config file variables,
not the defaults (which could be in a different codeset)
-- Support for "proper" game dates, e.g. mm-dd-yy or dd-mm-yy
- Limit rate of server connections to combat DOS attacks / players trying
to get a good starting day?
- Add support for reading/writing multiple configuration files to GUI client's
(DIR) diff --git a/doc/configfile.html b/doc/configfile.html
t@@ -572,14 +572,21 @@ replaced by "candy bar" or something similarly innocuous).</dd>
<dt><b>Names.Drugs=<i>"drugs"</i></b></dt>
<dd>Sets the word used to describe two or more "drugs".</dd>
-<dt><b>Names.Month=<i>"12-"</i></b></dt>
-<dd>Sets the text which is displayed on the client's screen to the immediate
-left of the current turn (by default, a "turn" is a day, and so this part
-is the month, in displaying the date in MM-DD-YYYY format)</dd>
+<dt><b>Names.Date=<i>"%m-%d-%Y"</i></b></dt>
+<dd>Sets the format string (which is passed to the strftime() function) for
+displaying the current game date. This example (the default) displays the
+date in MM-DD-YYYY format, as is commonplace in the US. Only date (not time)
+formats can be used, and the special format %T is used to display the
+current game turn.</dd>
-<dt><b>Names.Year=<i>"-1984"</i></b></dt>
-<dd>Sets the text displayed to the immediate right of the current turn (by
-default, the year).</dd>
+<dt><b>StartDate.Day=<i>"1"</i></b></dt>
+<dd>Sets the day of the month on which the game starts to <i>1</i>.</dd>
+
+<dt><b>StartDate.Month=<i>"12"</i></b></dt>
+<dd>Sets the month in which the game starts to <i>12</i> (i.e. December).</dd>
+
+<dt><b>StartDate.Year=<i>"1984"</i></b></dt>
+<dd>Sets the year in which the game starts to <i>1984</i>.</dd>
<dt><b>Prices.Spy=<i>20000</i></b></dt>
<dd>Sets the price to pay a bitch to spy on another player to be
t@@ -662,7 +669,7 @@ can be configured in the same way are: <b>FightMiss</b>, <b>FightReload</b>,
<li><a href="index.html">Main index</a></li>
</ul>
<p>
- Last update: <b>04-08-2002</b><br />
+ Last update: <b>11-08-2002</b><br />
Valid <a href="http://validator.w3.org/check/referer">XHTML 1.1</a>
</p>
</body>
(DIR) diff --git a/src/curses_client/curses_client.c b/src/curses_client/curses_client.c
t@@ -1703,7 +1703,7 @@ void print_status(Player *Play, gboolean DispDrug)
text = g_string_new(NULL);
attrset(TitleAttr);
clear_line(0);
- g_string_sprintf(text, "%s%02d%s", Names.Month, Play->Turn, Names.Year);
+ GetDateString(text, Play);
mvaddstr(0, 3, text->str);
attrset(StatsAttr);
(DIR) diff --git a/src/dopewars.c b/src/dopewars.c
t@@ -84,6 +84,10 @@ gchar *Encoding = NULL;
gboolean WantHelp, WantVersion, WantAntique, WantColour, WantNetwork;
gboolean WantConvert, WantAdmin;
+struct DATE StartDate = {
+ 1, 12, 1984
+};
+
#ifdef CYGWIN
gboolean MinToSysTray = TRUE;
#else
t@@ -154,7 +158,7 @@ struct DRUG StaticDrug, *Drug = NULL;
struct GUN StaticGun, *Gun = NULL;
struct COP StaticCop, *Cop = NULL;
struct NAMES Names = {
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
struct SOUNDS Sounds = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
t@@ -179,13 +183,10 @@ struct NAMES DefaultNames = {
N_("drug"),
/* Word used for two or more drugs */
N_("drugs"),
- /* Text that is printed before the turn number. In US mm-dd-yyyy date
- * notation, with MaxTurns at 31 or less, this works out as the month -
- * i.e. December in this case */
- N_("12-"),
- /* Text that is printed _after_ the turn number (the year, in US
- * notation) */
- N_("-1984"),
+ /* String for displaying the game date or turn number. This is passed
+ * to the strftime() function, with the exception that %T is used to
+ * mean the turn number rather than the calendar date. */
+ N_("%m-%d-%Y"),
/* Names of the loan shark, the bank, the gun shop, and the pub,
* respectively */
N_("the Loan Shark"), N_("the Bank"),
t@@ -332,6 +333,15 @@ struct GLOBALS Globals[] = {
{&NumTurns, NULL, NULL, NULL, NULL, "NumTurns",
N_("No. of game turns (if 0, game never ends)"),
NULL, NULL, 0, "", NULL, NULL, FALSE, 0},
+ {&StartDate.day, NULL, NULL, NULL, NULL, "StartDate.Day",
+ N_("Day of the month on which the game starts"),
+ NULL, NULL, 0, "", NULL, NULL, FALSE, 0},
+ {&StartDate.month, NULL, NULL, NULL, NULL, "StartDate.Month",
+ N_("Month in which the game starts"),
+ NULL, NULL, 0, "", NULL, NULL, FALSE, 0},
+ {&StartDate.year, NULL, NULL, NULL, NULL, "StartDate.Year",
+ N_("Year in which the game starts"),
+ NULL, NULL, 0, "", NULL, NULL, FALSE, 0},
{NULL, NULL, NULL, &Currency.Symbol, NULL, "Currency.Symbol",
N_("The currency symbol (e.g. $)"),
NULL, NULL, 0, "", NULL, NULL, FALSE, 0},
t@@ -582,11 +592,8 @@ struct GLOBALS Globals[] = {
{NULL, NULL, NULL, &Names.Drugs, NULL, "Names.Drugs",
N_("Word used to denote two or more drugs"), NULL, NULL, 0, "", NULL,
NULL, FALSE, 0},
- {NULL, NULL, NULL, &Names.Month, NULL, "Names.Month",
- N_("Text prefixed to the turn number (i.e. the month)"),
- NULL, NULL, 0, "", NULL, NULL, FALSE, 0},
- {NULL, NULL, NULL, &Names.Year, NULL, "Names.Year",
- N_("Text appended to the turn number (i.e. the year)"),
+ {NULL, NULL, NULL, &Names.Date, NULL, "Names.Date",
+ N_("strftime() format string for displaying the game turn"),
NULL, NULL, 0, "", NULL, NULL, FALSE, 0},
{NULL, NULL, &Prices.Spy, NULL, NULL, "Prices.Spy",
N_("Cost for a bitch to spy on the enemy"),
t@@ -836,6 +843,8 @@ GSList *AddPlayer(int fd, Player *NewPlayer, GSList *First)
InitList(&(NewPlayer->SpyList));
InitList(&(NewPlayer->TipList));
NewPlayer->Turn = 1;
+ NewPlayer->date = g_date_new_dmy(StartDate.day, StartDate.month,
+ StartDate.year);
NewPlayer->Cash = StartCash;
NewPlayer->Debt = StartDebt;
NewPlayer->Bank = 0;
t@@ -893,6 +902,7 @@ GSList *RemovePlayer(Player *Play, GSList *First)
#endif
ClearList(&(Play->SpyList));
ClearList(&(Play->TipList));
+ g_date_free(Play->date);
g_free(Play->Name);
g_free(Play->Guns);
g_free(Play->Drugs);
t@@ -1619,8 +1629,7 @@ void CopyNames(struct NAMES *dest, struct NAMES *src)
AssignName(&dest->Guns, _(src->Guns));
AssignName(&dest->Drug, _(src->Drug));
AssignName(&dest->Drugs, _(src->Drugs));
- AssignName(&dest->Month, _(src->Month));
- AssignName(&dest->Year, _(src->Year));
+ AssignName(&dest->Date, _(src->Date));
AssignName(&dest->LoanSharkName, _(src->LoanSharkName));
AssignName(&dest->BankName, _(src->BankName));
AssignName(&dest->GunShopName, _(src->GunShopName));
t@@ -2439,6 +2448,24 @@ void SetupParameters(void)
}
}
+void GetDateString(GString *str, Player *Play)
+{
+ gchar buf[200], *turn, *pt;
+
+ turn = g_strdup_printf("%d", Play->Turn);
+ g_string_assign(str, Names.Date);
+ while ((pt = strstr(str->str, "%T")) != NULL) {
+ int ind = pt - str->str;
+
+ g_string_erase(str, ind, 2);
+ g_string_insert(str, ind, turn);
+ }
+
+ g_date_strftime(buf, sizeof(buf), str->str, Play->date);
+ g_string_assign(str, buf);
+ g_free(turn);
+}
+
static void PluginHelp(void)
{
gchar *plugins;
(DIR) diff --git a/src/dopewars.h b/src/dopewars.h
t@@ -68,6 +68,8 @@ typedef enum {
* client sends the server a C_DONE message */
A_UTF8, /* All strings are sent over the network using
* UTF-8 (Unicode) encoding */
+ A_DATE, /* We can understand "proper" dd-mm-yy dates
+ * rather than just turn numbers */
A_NUM /* N.B. Must be last */
} AbilType;
t@@ -82,7 +84,7 @@ typedef struct ABILITIES {
struct NAMES {
gchar *Bitch, *Bitches, *Gun, *Guns, *Drug, *Drugs;
- gchar *Month, *Year, *LoanSharkName, *BankName;
+ gchar *Date, *LoanSharkName, *BankName;
gchar *GunShopName, *RoughPubName;
};
t@@ -163,6 +165,11 @@ struct LOG {
FILE *fp;
};
+struct DATE {
+ int day, month, year;
+};
+
+extern struct DATE StartDate;
extern int ClientSock, ListenSock;
extern gboolean Network, Client, Server, NotifyMetaServer, AIPlayer;
extern unsigned Port;
t@@ -287,6 +294,7 @@ typedef struct TDopeList DopeList;
struct PLAYER_T {
guint ID;
int Turn;
+ GDate *date;
price_t Cash, Debt, Bank;
int Health;
int CoatSize;
t@@ -427,6 +435,7 @@ gboolean SetConfigValue(int GlobalIndex, int StructIndex,
gboolean IndexGiven, GScanner *scanner);
gboolean IsCop(Player *Play);
void RestoreConfig(void);
+void GetDateString(GString *str, Player *Play);
void ScannerErrorHandler(GScanner *scanner, gchar *msg, gint error);
gboolean IsConnectedPlayer(Player *play);
void BackupConfig(void);
(DIR) diff --git a/src/gui_client/gtk_client.c b/src/gui_client/gtk_client.c
t@@ -1190,7 +1190,7 @@ void DisplayStats(Player *Play, struct StatusWidgets *Status)
Location[Play->IsAt].Name);
gtk_label_set_text(GTK_LABEL(Status->Location), text->str);
- g_string_sprintf(text, "%s%02d%s", Names.Month, Play->Turn, Names.Year);
+ GetDateString(text, Play);
gtk_label_set_text(GTK_LABEL(Status->Date), text->str);
g_string_sprintf(text, "%d", Play->CoatSize);
(DIR) diff --git a/src/message.c b/src/message.c
t@@ -256,6 +256,7 @@ void InitAbilities(Player *Play)
#else
Play->Abil.Local[A_UTF8] = FALSE;
#endif
+ Play->Abil.Local[A_DATE] = TRUE;
if (!Network) {
for (i = 0; i < A_NUM; i++) {
t@@ -653,6 +654,10 @@ void SendSpyReport(Player *To, Player *SpiedOn)
g_free(cashstr);
g_free(debtstr);
g_free(bankstr);
+ if (HaveAbility(SpiedOn, A_DATE)) {
+ g_string_sprintfa(text, "%d^%d^%d^", g_date_day(SpiedOn->date),
+ g_date_month(SpiedOn->date), g_date_year(SpiedOn->date));
+ }
for (i = 0; i < NumGun; i++) {
g_string_sprintfa(text, "%d^", SpiedOn->Guns[i].Carried);
}
t@@ -674,13 +679,13 @@ void SendSpyReport(Player *To, Player *SpiedOn)
g_string_free(text, TRUE);
}
-#define NUMNAMES 12
+#define NUMNAMES 11
void SendInitialData(Player *To)
{
gchar *LocalNames[NUMNAMES] = { Names.Bitch, Names.Bitches, Names.Gun,
Names.Guns, Names.Drug, Names.Drugs,
- Names.Month, Names.Year, Names.LoanSharkName,
+ Names.Date, Names.LoanSharkName,
Names.BankName, Names.GunShopName,
Names.RoughPubName
};
t@@ -696,15 +701,23 @@ void SendInitialData(Player *To)
text = g_string_new("");
g_string_sprintf(text, "%s^%d^%d^%d^", VERSION, NumLocation, NumGun,
NumDrug);
- for (i = 0; i < 8; i++) {
+ for (i = 0; i < 6; i++) {
g_string_append(text, LocalNames[i]);
g_string_append_c(text, '^');
}
+
+ if (HaveAbility(To, A_DATE)) {
+ g_string_append(text, LocalNames[6]);
+ g_string_append_c(text, '^');
+ } else {
+ g_string_sprintfa(text, "%d-^-%d^", StartDate.month, StartDate.year);
+ }
+
if (HaveAbility(To, A_PLAYERID))
g_string_sprintfa(text, "%d^", To->ID);
- /* Player ID is expected after the first 8 names, so send the rest now */
- for (i = 8; i < NUMNAMES; i++) {
+ /* Player ID is expected after the first 7 names, so send the rest now */
+ for (i = 7; i < NUMNAMES; i++) {
g_string_append(text, LocalNames[i]);
g_string_append_c(text, '^');
}
t@@ -739,8 +752,17 @@ void ReceiveInitialData(Player *Play, char *Data)
AssignName(&Names.Guns, GetNextWord(&pt, ""));
AssignName(&Names.Drug, GetNextWord(&pt, ""));
AssignName(&Names.Drugs, GetNextWord(&pt, ""));
- AssignName(&Names.Month, GetNextWord(&pt, ""));
- AssignName(&Names.Year, GetNextWord(&pt, ""));
+ if (HaveAbility(Play, A_DATE)) {
+ AssignName(&Names.Date, GetNextWord(&pt, ""));
+ } else {
+ gchar *month, *year, *date;
+ month = GetNextWord(&pt, "");
+ year = GetNextWord(&pt, "");
+
+ date = g_strdup_printf("%s%%T%s", month, year);
+ AssignName(&Names.Date, date);
+ g_free(date);
+ }
if (HaveAbility(Play, A_PLAYERID))
Play->ID = GetNextInt(&pt, 0);
t@@ -880,6 +902,11 @@ void ReceivePlayerData(Player *Play, char *text, Player *From)
From->IsAt = GetNextInt(&cp, 0);
From->Turn = GetNextInt(&cp, 0);
From->Flags = GetNextInt(&cp, 0);
+ if (HaveAbility(Play, A_DATE)) {
+ g_date_set_day(From->date, GetNextInt(&cp, 1));
+ g_date_set_month(From->date, GetNextInt(&cp, 1));
+ g_date_set_year(From->date, GetNextInt(&cp, 1980));
+ }
for (i = 0; i < NumGun; i++) {
From->Guns[i].Carried = GetNextInt(&cp, 0);
}
(DIR) diff --git a/src/serverside.c b/src/serverside.c
t@@ -525,6 +525,7 @@ void HandleServerMessage(gchar *buf, Player *Play)
GetPlayerName(Play), Location[i].Name);
Play->IsAt = i;
Play->Turn++;
+ g_date_add_days(Play->date, 1);
Play->Debt = Play->Debt * (DebtInterest + 100) / 100;
Play->Debt = MAX(Play->Debt, 0);
Play->Bank = Play->Bank * (BankInterest + 100) / 100;