DEADSOFTWARE

Master: Fix timeouts
[d2df-sdl.git] / src / mastersrv / master.c
index 7f476c17ce1a2f7c825a21e96eeb62268074bb8b..ca1c129895cb851f83c68d026288706b462bf011 100644 (file)
@@ -3,6 +3,7 @@
 #include <string.h>
 #include <enet/enet.h>
 #include <enet/types.h>
+#include <time.h>
 
 #define MS_VERSION "0.2"
 #define MS_MAXSRVS 128
 #define LC_MS_LIST "\nSent server list to %x:%u (ver. %s).\n"
 #define LC_MS_DIE  "\nD2DF master server shutting down...\n"
 #define LC_MS_CONN "\nIncoming connection from %x:%u...\n"
+#define LC_MS_MOTD "\nMOTD: %s\n"
+#define LC_MS_URGENT "\nURGENT: %s\n"
 
+#define MS_URGENT_FILE "urgent.txt"
+#define MS_MOTD_FILE "motd.txt"
 
 struct ms_server_s {
   enet_uint8 used;
@@ -40,14 +45,17 @@ struct ms_server_s {
   enet_uint8  s_mode;
   enet_uint8  s_protocol;
   enet_uint16 s_port;
-  enet_uint32 ttl;
+  time_t      deathtime;
 };
 
 typedef struct ms_server_s ms_server;
 
 const char ms_game_ver[] = "0.63";
+char ms_motd[255] = "";
+char ms_urgent[255] = "";
+
 int ms_port = 25660;
-int ms_timeout = 100000;
+int ms_timeout = 100;
 
 size_t b_read = 0;
 size_t b_write = 0;
@@ -126,13 +134,34 @@ void d_getargs (int argc, char *argv[]) {
         ms_port = atoi(argv[++i]);
       }
     } else if (!strcmp(argv[i], "-t") & (i + 1 < argc)) {
-        ms_timeout = atoi(argv[++i]) * 1000;
+        ms_timeout = atoi(argv[++i]);
     }
   }
 }
 
 
-enet_uint8  b_read_uint8 (enet_uint8 buf[], size_t *pos) {
+int d_readtextfile (const char *fname, char *buf, size_t max) {
+  FILE *f = fopen(fname, "r");
+  char *const end = buf + max - 1;
+  char *p = buf;
+  if (f) {
+    char ln[max];
+    char *const lend = ln + max - 1;
+    while(p < end && fgets(ln, sizeof(ln), f)) {
+      for (char *n = ln; n < lend && *n && *n != '\r' && *n != '\n'; ++n) {
+        *(p++) = *n;
+        if (p == end) break;
+      }
+    }
+    *p = '\0';
+    fclose(f);
+    return 0;
+  }
+  return 1;
+}
+
+
+enet_uint8 b_read_uint8 (enet_uint8 buf[], size_t *pos) {
   return buf[(*pos)++];
 }
 
@@ -205,6 +234,12 @@ int main (int argc, char *argv[]) {
 
   printf(LC_MS_INIT, ms_port);
 
+  d_readtextfile(MS_MOTD_FILE, ms_motd, sizeof(ms_motd));
+  d_readtextfile(MS_URGENT_FILE, ms_urgent, sizeof(ms_urgent));
+
+  if (ms_motd[0]) printf(LC_MS_MOTD, ms_motd);
+  if (ms_urgent[0]) printf(LC_MS_URGENT, ms_urgent);
+
   for (int i = 0; i < NET_MAXCLIENTS; ++i) ms_peers[i] = NULL;
 
   for (int i = 0; i < MS_MAXSRVS; ++i) {
@@ -212,7 +247,7 @@ int main (int argc, char *argv[]) {
     ms_srv[i].s_ip[0] = '\0';
     ms_srv[i].s_name[0] = '\0';
     ms_srv[i].s_map[0] = '\0';
-    ms_srv[i].ttl = 0;
+    ms_srv[i].deathtime = 0;
   }
 
   ENetAddress addr;
@@ -244,7 +279,7 @@ int main (int argc, char *argv[]) {
   enet_uint8 proto = 0;
   enet_uint8 pw = 0;
   while (!shutdown) {
-    while (enet_host_service(ms_host, &event, 1) > 0) {
+    while (enet_host_service(ms_host, &event, 5000) > 0) {
       switch (event.type) {
         case ENET_EVENT_TYPE_CONNECT:
           printf(LC_MS_CONN, event.peer->address.host, event.peer->address.port);
@@ -281,7 +316,7 @@ int main (int argc, char *argv[]) {
                     ms_srv[i].s_pw = pw;
                     ms_srv[i].s_mode = gm;
 
-                    ms_srv[i].ttl = ms_timeout;
+                    ms_srv[i].deathtime = time(NULL) + ms_timeout;
 
                     printf(LC_MS_UPD, i, ip, port, name, map, gm, pl, mpl, proto, pw);
                     break;
@@ -296,7 +331,7 @@ int main (int argc, char *argv[]) {
                     ms_srv[i].s_pw = pw;
                     ms_srv[i].s_mode = gm;
                     ms_srv[i].s_protocol = proto;
-                    ms_srv[i].ttl = ms_timeout;
+                    ms_srv[i].deathtime = time(NULL) + ms_timeout;
 
                     ms_srv[i].used = 1;
 
@@ -347,6 +382,9 @@ int main (int argc, char *argv[]) {
                 // TODO: check if this client is outdated (?) and send back new verstring
                 // for now just write the same shit back
                 b_write_dstring(b_send, &b_write, clientver);
+                // write the motd and urgent message
+                b_write_dstring(b_send, &b_write, ms_motd);
+                b_write_dstring(b_send, &b_write, ms_urgent);
               }
 
               ENetPacket *p = enet_packet_create(b_send, b_write, ENET_PACKET_FLAG_RELIABLE);
@@ -367,9 +405,10 @@ int main (int argc, char *argv[]) {
       }
     }
 
+    time_t now = time(NULL);
     for (int i = 0; i < MS_MAXSRVS; ++i) {
       if (ms_srv[i].used) {
-        if (--(ms_srv[i].ttl) == 0) {
+        if (ms_srv[i].deathtime <= now) {
           ms_srv[i].used = 0;
           printf(LC_MS_TIME, i, ms_srv[i].s_ip, ms_srv[i].s_port);
           --ms_count;