tWe now support dates properly. Names.Month and Names.Year no longer exist; the… | |
git clone git://src.adamsgaard.dk/vaccinewars | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit 9a9ff0d914d62a5f3dd56db880f7a1aca7887d20 | |
parent ce396c47d1a0063856c581d2028b88bbd91111a9 | |
Author: Ben Webb <[email protected]> | |
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(-) | |
--- | |
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 | |
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 | |
diff --git a/doc/configfile.html b/doc/configfile.html | |
t@@ -572,14 +572,21 @@ replaced by "candy bar" or something similarly innocuous… | |
<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>, <… | |
<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> | |
diff --git a/src/curses_client/curses_client.c b/src/curses_client/curses_clien… | |
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); | |
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; | |
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); | |
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 *St… | |
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); | |
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->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); | |
} | |
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; |