]> granicus.if.org Git - nethack/commitdiff
Add server admin messaging functionality
authorPasi Kallinen <paxed@alt.org>
Mon, 4 Jan 2016 21:04:56 +0000 (23:04 +0200)
committerPasi Kallinen <paxed@alt.org>
Mon, 4 Jan 2016 21:04:59 +0000 (23:04 +0200)
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.

include/extern.h
include/unixconf.h
src/allmain.c
src/mail.c

index 3bba9fe1dff53a2fbccb970cc9ba7a36b58c4fe2..537c58a06db4f06370992bf62b6fcb3cd1daa1d0 100644 (file)
@@ -1062,6 +1062,7 @@ E void FDECL(nocmov, (int x, int y));
 #ifdef UNIX
 E void NDECL(getmailstatus);
 #endif
+E void NDECL(ck_server_admin_msg);
 E void NDECL(ckmailstatus);
 E void FDECL(readmail, (struct obj *));
 #endif /* MAIL */
index 751895ba97416fdacf8ebab44ec1c1f6a8c122af..236994bce124347972b9e18b8773809bd64898f2 100644 (file)
 
 /* If SIMPLE_MAIL is defined, the mail spool file format is
    "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 */
 
 #ifndef MAILCKFREQ
 
 #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"
  * when Alt+c is pressed.  The altmeta run-time option allows the user to
index 9f4329143a3f9afa14feafdf4d209d6cc3db629d..9bc6bdcab832dfab688f5e738b48d23699077bd3 100644 (file)
@@ -455,6 +455,7 @@ boolean resuming;
                 rhack(save_cm);
             }
         } else if (multi == 0) {
+            ck_server_admin_msg();
 #ifdef MAIL
             ckmailstatus();
 #endif
index ec31393a42d6d445ceff7e4428569336f29879d2..552f263d458f1e74a2e8cbbce621fbd5c07e6801 100644 (file)
@@ -502,35 +502,50 @@ ckmailstatus()
     }
 }
 
-#ifdef SIMPLE_MAIL
+#if defined(SIMPLE_MAIL) || defined(SERVER_ADMIN_MSG)
 void
-read_simplemail()
+read_simplemail(mbox, adminmsg)
+char *mbox;
+boolean adminmsg;
 {
-    FILE* mb = fopen(mailbox, "r");
-    char curline[102], *msg;
+    FILE* mb = fopen(mbox, "r");
+    char curline[128], *msg;
     boolean seen_one_already = FALSE;
+#ifdef SIMPLE_MAIL
     struct flock fl = { 0 };
+#endif
+    const char *msgfrom = adminmsg
+        ? "The voice of %s booms through the caverns:"
+        : "This message is from '%s'.";
+
+    if (!mb)
+        goto bail;
 
+#ifdef SIMPLE_MAIL
     fl.l_type = F_RDLCK;
     fl.l_whence = SEEK_SET;
     fl.l_start = 0;
     fl.l_len = 0;
-
-    if (!mb)
-        goto bail;
+    errno = 0;
+#endif
 
     /* 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;
 
-    errno = 0;
-    while (fgets(curline, 102, mb) != NULL) {
-        fl.l_type = F_UNLCK;
-        fcntl (fileno(mb), F_UNLCK, &fl);
-
-        pline("There is a%s message on this scroll.",
-              seen_one_already ? "nother" : "");
-
+    while (fgets(curline, 128, mb) != NULL) {
+        if (!adminmsg) {
+#ifdef SIMPLE_MAIL
+            fl.l_type = F_UNLCK;
+            fcntl (fileno(mb), F_UNLCK, &fl);
+#endif
+            pline("There is a%s message on this scroll.",
+                  seen_one_already ? "nother" : "");
+        }
         msg = strchr(curline, ':');
 
         if (!msg)
@@ -538,28 +553,61 @@ read_simplemail()
 
         *msg = '\0';
         msg++;
-
-        pline("This message is from '%s'.", curline);
-
         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;
+#ifdef SIMPLE_MAIL
         errno = 0;
-
-        fl.l_type = F_RDLCK;
-        fcntl(fileno(mb), F_SETLKW, &fl);
+        if (!adminmsg) {
+            fl.l_type = F_RDLCK;
+            fcntl(fileno(mb), F_SETLKW, &fl);
+        }
+#endif
     }
 
-    fl.l_type = F_UNLCK;
-    fcntl(fileno(mb), F_UNLCK, &fl);
+#ifdef SIMPLE_MAIL
+    if (!adminmsg) {
+        fl.l_type = F_UNLCK;
+        fcntl(fileno(mb), F_UNLCK, &fl);
+    }
+#endif
     fclose(mb);
-    unlink(mailbox);
+    if (adminmsg)
+        display_nhwindow(WIN_MESSAGE, TRUE);
+    else
+        unlink(mailbox);
+    return;
 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 */
 
+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*/
 void
 readmail(otmp)
@@ -569,7 +617,7 @@ struct obj *otmp UNUSED;
     register const char *mr = 0;
 #endif /* DEF_MAILREADER */
 #ifdef SIMPLE_MAIL
-    read_simplemail();
+    read_simplemail(mailbox, FALSE);
     return;
 #endif /* SIMPLE_MAIL */
 #ifdef DEF_MAILREADER /* This implies that UNIX is defined */