Mercurial > hg > rlgwebd
changeset 111:f56fdfeed01a
Replace taking over games with forced saves.
Instead of reusing the id, just SIGHUP the game process. This works
whether it is using polling, WebSockets, or dgamelaunch.
author | John "Elwin" Edwards <elwin@sdf.org> |
---|---|
date | Sun, 15 Jul 2012 22:33:44 -0700 |
parents | 18a81cc0084b |
children | 4f2b89e6fde2 |
files | rlgterm.js rlgwebd.js |
diffstat | 2 files changed, 84 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/rlgterm.js Sun Jul 15 21:03:36 2012 -0700 +++ b/rlgterm.js Sun Jul 15 22:33:44 2012 -0700 @@ -622,18 +622,20 @@ acttext = "Resume your game"; else if (reply.stat[gname] == "0") acttext = "Start a game"; - else if (reply.stat[gname] == "p") - acttext = "Reconnect"; - else if (reply.stat[gname] == "d") - acttext = "Game in progress (dgl)"; + else if (reply.stat[gname] == "p" || reply.stat[gname] == "d") + acttext = "Force save"; else continue; var button = document.createElement("span"); button.appendChild(document.createTextNode(acttext)); - if ("s0p".indexOf(reply.stat[gname]) >= 0) { + if ("s0".indexOf(reply.stat[gname]) >= 0) { button.onclick = makeStarter(gname); button.className = "ibutton"; } + else { + button.onclick = makeStopper(gname); + button.className = "ibutton"; + } var actdiv = document.createElement("div"); actdiv.appendChild(button); var gamediv = document.createElement("div"); @@ -719,6 +721,44 @@ return; } +function makeStopper(gname) { + if (!(gname in games)) + return null; + var game = games[gname]; + function stopper(ev) { + stopgame(game); + } + return stopper; +} + +function stopgame(game) { + if (!session.lcred) + return; + var stopmsg = {"key": session.lcred, "g": game.uname}; + var req = new XMLHttpRequest(); + req.onerror = errHandler; + req.onreadystatechange = function () { + if (req.readyState != 4 || req.status != 200) + return; + var reply = JSON.parse(req.responseText); + if (reply.t == 'E') { + if (reply.c == 7) + message("That game has already stopped."); + else if (reply.c == 1) { + logout(); + message("The server forgot about you, please log in again.", "warn"); + } + else { + message("That game could not be stopped because: " + reply.s + + "This might be a bug.", "warn"); + } + } + } + req.open('POST', '/quit', true); + req.send(JSON.stringify(stopmsg)); + return; +} + function wsStart(game) { var sockurl = "ws://" + window.location.host + "/play/" + game.uname; sockurl += "?key=" + session.lcred + "&w=80&h=24";
--- a/rlgwebd.js Sun Jul 15 21:03:36 2012 -0700 +++ b/rlgwebd.js Sun Jul 15 22:33:44 2012 -0700 @@ -896,6 +896,42 @@ return; } +/* Stops a running game if the request has the proper key. */ +function stopgame(res, formdata) { + if (!("key" in formdata) || !(formdata["key"] in logins)) { + sendError(res, 1); + return; + } + var pname = logins[formdata["key"]].name; + if (!("g" in formdata) || !(formdata["g"] in games)) { + sendError(res, 2, "No such game."); + return; + } + var gname = formdata["g"]; + function checkback(err, fname) { + if (!fname) { + sendError(res, 7); + return; + } + var fullfile = path.join("/dgldir/inprogress-" + gname, fname); + fs.readFile(fullfile, "utf8", function(err, fdata) { + if (err) { + sendError(res, 7); + return; + } + var pid = parseInt(fdata.split('\n')[0], 10); + process.kill(pid, 'SIGHUP'); + /* The response doesn't mean that the game is gone. The only way + * to make sure a dgamelaunch-supervised game is over would be to + * poll fname until it disappears. */ + res.writeHead(200, {'Content-Type': 'application/json'}); + res.write(JSON.stringify({"t": "q"})); + res.end(); + }); + } + checkprogress(pname, games[gname], checkback, []); +} + function findClient(formdata, playersOnly) { if (typeof(formdata) != "object") return null; @@ -1125,6 +1161,9 @@ else if (target == "/watch") { watch(req, res, formdata); } + else if (target == "/quit") { + stopgame(res, formdata); + } else { res.writeHead(405, resheaders); res.end();