changeset 42:8f6bc0df58fa

rlgwebd.js: add a player status interface. Give information on a player's current status at "/pstatus/<name>". Also fix some shift()/unshift() confusion in checkprogress().
author John "Elwin" Edwards <elwin@sdf.org>
date Sat, 09 Jun 2012 11:46:58 -0700
parents ea3b7775009d
children c4efc7522e7b
files rlgwebd.js
diffstat 1 files changed, 73 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/rlgwebd.js	Sat Jun 09 10:44:11 2012 -0700
+++ b/rlgwebd.js	Sat Jun 09 11:46:58 2012 -0700
@@ -26,21 +26,25 @@
   "rogue3": {
     "name": "Rogue V3",
     "uname": "rogue3",
+    "suffix": ".r3sav",
     "path": "/bin/rogue3"
   },
   "rogue4": {
     "name": "Rogue V4",
     "uname": "rogue4",
+    "suffix": ".r4sav",
     "path": "/bin/rogue4"
   },
   "rogue5": {
     "name": "Rogue V5",
     "uname": "rogue5",
+    "suffix": ".r5sav",
     "path": "/bin/rogue5"
   },
   "srogue": {
     "name": "Super-Rogue",
     "uname": "srogue",
+    "suffix": ".srsav",
     "path": "/bin/srogue"
   }
 };
@@ -236,16 +240,57 @@
     var fre = RegExp("^" + user + ":");
     for (var i = 0; i < files.length; i++) {
       if (files[i].match(fre)) {
-        args.shift(null, files[i]);
+        args.unshift(null, files[i]);
         callback.apply(null, args);
         return;
       }
     }
-    args.shift(null, false);
+    args.unshift(null, false);
+    callback.apply(null, args);
+  });
+}
+
+function checksaved(user, game, callback, args) {
+  var savedirc = game.uname + "save";
+  var basename = String(dropToUID) + "-" + user + game.suffix;
+  var savefile = path.join("/var/games/roguelike", savedirc, basename);
+  path.exists(savefile, function (exist) {
+    args.unshift(exist);
     callback.apply(null, args);
   });
 }
 
+function playerstatus(user, callback) {
+  var sdata = {};
+  tslog("Starting (user %s)", user);
+  function finishp() {
+    for (var gname in games) {
+      if (!(gname in sdata))
+        return;
+    }
+    tslog("Finished: %s", JSON.stringify(sdata));
+    callback(sdata);
+  }
+  function regsaved(exists, game) {
+    if (exists)
+      sdata[game.uname] = "s";
+    else
+      sdata[game.uname] = "0";
+    finishp();
+  }
+  function regactive(err, filename, game) {
+    if (!err && filename) {
+      sdata[game.uname] = "p";
+      finishp();
+    }
+    else
+      checksaved(user, game, regsaved, [game]);
+  }
+  for (var gname in games) {
+    checkprogress(user, games[gname], regactive, [games[gname]]);
+  }
+}
+
 /* A few utility functions */
 function timestamp() {
   dd = new Date();
@@ -609,6 +654,29 @@
   res.end();
 }
 
+function pstatusmsg(req, res) {
+  if (req.method == 'HEAD') {
+    res.writeHead(200, { "Content-Type": "application/json" });
+    res.end();
+    return;
+  }
+  var target = url.parse(req.url).pathname;
+  var pmatch = target.match(/^\/pstatus\/(.*)/);
+  if (pmatch && pmatch[1])
+    var pname = pmatch[1];
+  else {
+    sendError(res, 2, "No name given.");
+    return;
+  }
+  var reply = {"name": pname};
+  playerstatus(pname, function (pdata) {
+    reply["stat"] = pdata;
+    res.writeHead(200, { "Content-Type": "application/json" });
+    res.write(JSON.stringify(reply));
+    res.end();
+  });
+}
+
 var errorcodes = [ "Generic Error", "Not logged in", "Invalid data", 
         "Login failed", "Already playing", "Game launch failed",
         "Server shutting down", "Game not in progress" ];
@@ -698,6 +766,9 @@
       else if (target == '/status') {
         statusmsg(req, res);
       }
+      else if (target.match(/^\/pstatus\//)) {
+        pstatusmsg(req, res);
+      }
       else /* Go look for it in the filesystem */
         serveStatic(req, res, target);
     }