Add server admin messaging functionality
It's occasionally important for public servers to notify all the players. Sending a mail is not reliable, as not everyone wants to break conduct, or have mail on. This adds a compile-time defined filename, which NetHack will monitor. The contents of the file are in the same format as SIMPLE_MAIL: "sender:message" on one line.
This commit is contained in:
@@ -1062,6 +1062,7 @@ E void FDECL(nocmov, (int x, int y));
|
|||||||
#ifdef UNIX
|
#ifdef UNIX
|
||||||
E void NDECL(getmailstatus);
|
E void NDECL(getmailstatus);
|
||||||
#endif
|
#endif
|
||||||
|
E void NDECL(ck_server_admin_msg);
|
||||||
E void NDECL(ckmailstatus);
|
E void NDECL(ckmailstatus);
|
||||||
E void FDECL(readmail, (struct obj *));
|
E void FDECL(readmail, (struct obj *));
|
||||||
#endif /* MAIL */
|
#endif /* MAIL */
|
||||||
|
|||||||
+13
-1
@@ -193,7 +193,9 @@
|
|||||||
|
|
||||||
/* If SIMPLE_MAIL is defined, the mail spool file format is
|
/* If SIMPLE_MAIL is defined, the mail spool file format is
|
||||||
"sender:message", one mail per line, and mails are
|
"sender:message", one mail per line, and mails are
|
||||||
read within game, from demon-delivered mail scrolls */
|
read within game, from demon-delivered mail scrolls.
|
||||||
|
The mail spool file will be deleted once the player
|
||||||
|
has read the message. */
|
||||||
/* #define SIMPLE_MAIL */
|
/* #define SIMPLE_MAIL */
|
||||||
|
|
||||||
#ifndef MAILCKFREQ
|
#ifndef MAILCKFREQ
|
||||||
@@ -203,6 +205,16 @@
|
|||||||
|
|
||||||
#endif /* MAIL */
|
#endif /* MAIL */
|
||||||
|
|
||||||
|
/* If SERVER_ADMIN_MSG is defined and the file exists, players get
|
||||||
|
a message from the user defined in the file. The file format
|
||||||
|
is "sender:message" all in one line. */
|
||||||
|
/* #define SERVER_ADMIN_MSG "adminmsg" */
|
||||||
|
#ifndef SERVER_ADMIN_MSG_CKFREQ
|
||||||
|
/* How often admin message file is checked for new messages, in turns */
|
||||||
|
#define SERVER_ADMIN_MSG_CKFREQ 25
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Some terminals or terminal emulators send two character sequence "ESC c"
|
* Some terminals or terminal emulators send two character sequence "ESC c"
|
||||||
* when Alt+c is pressed. The altmeta run-time option allows the user to
|
* when Alt+c is pressed. The altmeta run-time option allows the user to
|
||||||
|
|||||||
@@ -455,6 +455,7 @@ boolean resuming;
|
|||||||
rhack(save_cm);
|
rhack(save_cm);
|
||||||
}
|
}
|
||||||
} else if (multi == 0) {
|
} else if (multi == 0) {
|
||||||
|
ck_server_admin_msg();
|
||||||
#ifdef MAIL
|
#ifdef MAIL
|
||||||
ckmailstatus();
|
ckmailstatus();
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+78
-30
@@ -502,35 +502,50 @@ ckmailstatus()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SIMPLE_MAIL
|
#if defined(SIMPLE_MAIL) || defined(SERVER_ADMIN_MSG)
|
||||||
void
|
void
|
||||||
read_simplemail()
|
read_simplemail(mbox, adminmsg)
|
||||||
|
char *mbox;
|
||||||
|
boolean adminmsg;
|
||||||
{
|
{
|
||||||
FILE* mb = fopen(mailbox, "r");
|
FILE* mb = fopen(mbox, "r");
|
||||||
char curline[102], *msg;
|
char curline[128], *msg;
|
||||||
boolean seen_one_already = FALSE;
|
boolean seen_one_already = FALSE;
|
||||||
|
#ifdef SIMPLE_MAIL
|
||||||
struct flock fl = { 0 };
|
struct flock fl = { 0 };
|
||||||
|
#endif
|
||||||
fl.l_type = F_RDLCK;
|
const char *msgfrom = adminmsg
|
||||||
fl.l_whence = SEEK_SET;
|
? "The voice of %s booms through the caverns:"
|
||||||
fl.l_start = 0;
|
: "This message is from '%s'.";
|
||||||
fl.l_len = 0;
|
|
||||||
|
|
||||||
if (!mb)
|
if (!mb)
|
||||||
goto bail;
|
goto bail;
|
||||||
|
|
||||||
|
#ifdef SIMPLE_MAIL
|
||||||
|
fl.l_type = F_RDLCK;
|
||||||
|
fl.l_whence = SEEK_SET;
|
||||||
|
fl.l_start = 0;
|
||||||
|
fl.l_len = 0;
|
||||||
|
errno = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Allow this call to block. */
|
/* Allow this call to block. */
|
||||||
if (fcntl (fileno (mb), F_SETLKW, &fl) == -1)
|
if (!adminmsg
|
||||||
|
#ifdef SIMPLE_MAIL
|
||||||
|
&& fcntl (fileno (mb), F_SETLKW, &fl) == -1
|
||||||
|
#endif
|
||||||
|
)
|
||||||
goto bail;
|
goto bail;
|
||||||
|
|
||||||
errno = 0;
|
while (fgets(curline, 128, mb) != NULL) {
|
||||||
while (fgets(curline, 102, mb) != NULL) {
|
if (!adminmsg) {
|
||||||
fl.l_type = F_UNLCK;
|
#ifdef SIMPLE_MAIL
|
||||||
fcntl (fileno(mb), F_UNLCK, &fl);
|
fl.l_type = F_UNLCK;
|
||||||
|
fcntl (fileno(mb), F_UNLCK, &fl);
|
||||||
pline("There is a%s message on this scroll.",
|
#endif
|
||||||
seen_one_already ? "nother" : "");
|
pline("There is a%s message on this scroll.",
|
||||||
|
seen_one_already ? "nother" : "");
|
||||||
|
}
|
||||||
msg = strchr(curline, ':');
|
msg = strchr(curline, ':');
|
||||||
|
|
||||||
if (!msg)
|
if (!msg)
|
||||||
@@ -538,28 +553,61 @@ read_simplemail()
|
|||||||
|
|
||||||
*msg = '\0';
|
*msg = '\0';
|
||||||
msg++;
|
msg++;
|
||||||
|
|
||||||
pline("This message is from '%s'.", curline);
|
|
||||||
|
|
||||||
msg[strlen(msg) - 1] = '\0'; /* kill newline */
|
msg[strlen(msg) - 1] = '\0'; /* kill newline */
|
||||||
pline ("It reads: \"%s\".", msg);
|
|
||||||
|
pline(msgfrom, curline);
|
||||||
|
if (adminmsg)
|
||||||
|
verbalize(msg);
|
||||||
|
else
|
||||||
|
pline("It reads: \"%s\".", msg);
|
||||||
|
|
||||||
seen_one_already = TRUE;
|
seen_one_already = TRUE;
|
||||||
|
#ifdef SIMPLE_MAIL
|
||||||
errno = 0;
|
errno = 0;
|
||||||
|
if (!adminmsg) {
|
||||||
fl.l_type = F_RDLCK;
|
fl.l_type = F_RDLCK;
|
||||||
fcntl(fileno(mb), F_SETLKW, &fl);
|
fcntl(fileno(mb), F_SETLKW, &fl);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
fl.l_type = F_UNLCK;
|
#ifdef SIMPLE_MAIL
|
||||||
fcntl(fileno(mb), F_UNLCK, &fl);
|
if (!adminmsg) {
|
||||||
|
fl.l_type = F_UNLCK;
|
||||||
|
fcntl(fileno(mb), F_UNLCK, &fl);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
fclose(mb);
|
fclose(mb);
|
||||||
unlink(mailbox);
|
if (adminmsg)
|
||||||
|
display_nhwindow(WIN_MESSAGE, TRUE);
|
||||||
|
else
|
||||||
|
unlink(mailbox);
|
||||||
|
return;
|
||||||
bail:
|
bail:
|
||||||
pline("It appears to be all gibberish."); /* bail out _professionally_ */
|
/* bail out _professionally_ */
|
||||||
|
if (!adminmsg)
|
||||||
|
pline("It appears to be all gibberish.");
|
||||||
}
|
}
|
||||||
#endif /* SIMPLE_MAIL */
|
#endif /* SIMPLE_MAIL */
|
||||||
|
|
||||||
|
void
|
||||||
|
ck_server_admin_msg()
|
||||||
|
{
|
||||||
|
#ifdef SERVER_ADMIN_MSG
|
||||||
|
static struct stat ost,nst;
|
||||||
|
static long lastchk = 0;
|
||||||
|
|
||||||
|
if (moves < lastchk + SERVER_ADMIN_MSG_CKFREQ) return;
|
||||||
|
lastchk = moves;
|
||||||
|
|
||||||
|
if (!stat(SERVER_ADMIN_MSG, &nst)) {
|
||||||
|
if (nst.st_mtime > ost.st_mtime)
|
||||||
|
read_simplemail(SERVER_ADMIN_MSG, TRUE);
|
||||||
|
ost.st_mtime = nst.st_mtime;
|
||||||
|
}
|
||||||
|
#endif /* SERVER_ADMIN_MSG */
|
||||||
|
}
|
||||||
|
|
||||||
/*ARGSUSED*/
|
/*ARGSUSED*/
|
||||||
void
|
void
|
||||||
readmail(otmp)
|
readmail(otmp)
|
||||||
@@ -569,7 +617,7 @@ struct obj *otmp UNUSED;
|
|||||||
register const char *mr = 0;
|
register const char *mr = 0;
|
||||||
#endif /* DEF_MAILREADER */
|
#endif /* DEF_MAILREADER */
|
||||||
#ifdef SIMPLE_MAIL
|
#ifdef SIMPLE_MAIL
|
||||||
read_simplemail();
|
read_simplemail(mailbox, FALSE);
|
||||||
return;
|
return;
|
||||||
#endif /* SIMPLE_MAIL */
|
#endif /* SIMPLE_MAIL */
|
||||||
#ifdef DEF_MAILREADER /* This implies that UNIX is defined */
|
#ifdef DEF_MAILREADER /* This implies that UNIX is defined */
|
||||||
|
|||||||
Reference in New Issue
Block a user