annotate rlgwebd.js @ 168:0ceaca924b4c

Remove the TermSession 'open' event. Failure is now signaled with a TermSession.failed flag. Playing two games at the same time no longer causes crashes, but it does send the same output to both players.
author John "Elwin" Edwards
date Fri, 09 Jan 2015 08:55:38 -0500
parents fba1b34e7554
children 6f4b7e1b32e8
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
1 #!/usr/bin/env node
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
2
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
3 var http = require('http');
28
2ad2b6491aa9 rlgwebd.js: become a real daemon.
John "Elwin" Edwards <elwin@sdf.org>
parents: 27
diff changeset
4 var net = require('net');
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
5 var url = require('url');
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
6 var path = require('path');
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
7 var fs = require('fs');
55
96815eae4ebe RLG-Web: make multiple watchers possible.
John "Elwin" Edwards <elwin@sdf.org>
parents: 49
diff changeset
8 var events = require('events');
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
9 var child_process = require('child_process');
141
1a156a7746a7 RLGWebD: use NODE_PATH to find modules.
John "Elwin" Edwards
parents: 139
diff changeset
10 // Dependencies
1a156a7746a7 RLGWebD: use NODE_PATH to find modules.
John "Elwin" Edwards
parents: 139
diff changeset
11 var posix = require("posix");
1a156a7746a7 RLGWebD: use NODE_PATH to find modules.
John "Elwin" Edwards
parents: 139
diff changeset
12 var pty = require("pty.js");
1a156a7746a7 RLGWebD: use NODE_PATH to find modules.
John "Elwin" Edwards
parents: 139
diff changeset
13 var WebSocketServer = require("websocket").server;
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
14
30
b5570a594266 rlgwebd.js: listen on any address
John "Elwin" Edwards <elwin@sdf.org>
parents: 29
diff changeset
15 /* Configuration variables */
139
dcd07c1d846a Replace the daemon module with posix.
John "Elwin" Edwards
parents: 132
diff changeset
16 // The first file is NOT in the chroot.
28
2ad2b6491aa9 rlgwebd.js: become a real daemon.
John "Elwin" Edwards <elwin@sdf.org>
parents: 27
diff changeset
17 var ctlsocket = "/var/local/rlgwebd/ctl";
30
b5570a594266 rlgwebd.js: listen on any address
John "Elwin" Edwards <elwin@sdf.org>
parents: 29
diff changeset
18 var httpPort = 8080;
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
19 var chrootDir = "/var/dgl/";
157
e7f809f06c5c Use posix.getpwnam() to look up UID/GID to drop to.
John "Elwin" Edwards
parents: 156
diff changeset
20 var dropToUser = "rodney";
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
21 var serveStaticRoot = "/var/www/"; // inside the chroot
30
b5570a594266 rlgwebd.js: listen on any address
John "Elwin" Edwards <elwin@sdf.org>
parents: 29
diff changeset
22
39
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
23 /* Data on the games available. */
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
24 var games = {
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
25 "rogue3": {
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
26 "name": "Rogue V3",
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
27 "uname": "rogue3",
42
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
28 "suffix": ".r3sav",
144
81a8e7aa4687 RLGWebD: game binaries have moved to /usr/bin.
John "Elwin" Edwards
parents: 142
diff changeset
29 "path": "/usr/bin/rogue3",
60
31bb3cf4f25f Make sure watchers start with completely drawn screens.
John "Elwin" Edwards <elwin@sdf.org>
parents: 55
diff changeset
30 "clear": new Buffer([27, 91, 72, 27, 91, 50, 74]) // CSI H CSI 2J
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
31 },
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
32 "rogue4": {
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
33 "name": "Rogue V4",
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
34 "uname": "rogue4",
42
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
35 "suffix": ".r4sav",
144
81a8e7aa4687 RLGWebD: game binaries have moved to /usr/bin.
John "Elwin" Edwards
parents: 142
diff changeset
36 "path": "/usr/bin/rogue4",
60
31bb3cf4f25f Make sure watchers start with completely drawn screens.
John "Elwin" Edwards <elwin@sdf.org>
parents: 55
diff changeset
37 "clear": new Buffer([27, 91, 72, 27, 91, 50, 74]) // CSI H CSI 2J
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
38 },
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
39 "rogue5": {
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
40 "name": "Rogue V5",
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
41 "uname": "rogue5",
42
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
42 "suffix": ".r5sav",
144
81a8e7aa4687 RLGWebD: game binaries have moved to /usr/bin.
John "Elwin" Edwards
parents: 142
diff changeset
43 "path": "/usr/bin/rogue5",
60
31bb3cf4f25f Make sure watchers start with completely drawn screens.
John "Elwin" Edwards <elwin@sdf.org>
parents: 55
diff changeset
44 "clear": new Buffer([27, 91, 72, 27, 91, 50, 74]) // CSI H CSI 2J
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
45 },
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
46 "srogue": {
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
47 "name": "Super-Rogue",
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
48 "uname": "srogue",
42
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
49 "suffix": ".srsav",
144
81a8e7aa4687 RLGWebD: game binaries have moved to /usr/bin.
John "Elwin" Edwards
parents: 142
diff changeset
50 "path": "/usr/bin/srogue",
121
077adfeea038 Correct the clear sequence for srogue.
John "Elwin" Edwards <elwin@sdf.org>
parents: 120
diff changeset
51 "clear": new Buffer([27, 91, 72, 27, 91, 50, 74]) // CSI H CSI 2J
120
54979d35611a Add support for Advanced Rogue 5.
John "Elwin" Edwards <elwin@sdf.org>
parents: 113
diff changeset
52 },
54979d35611a Add support for Advanced Rogue 5.
John "Elwin" Edwards <elwin@sdf.org>
parents: 113
diff changeset
53 "arogue5": {
54979d35611a Add support for Advanced Rogue 5.
John "Elwin" Edwards <elwin@sdf.org>
parents: 113
diff changeset
54 "name": "Advanced Rogue 5",
54979d35611a Add support for Advanced Rogue 5.
John "Elwin" Edwards <elwin@sdf.org>
parents: 113
diff changeset
55 "uname": "arogue5",
54979d35611a Add support for Advanced Rogue 5.
John "Elwin" Edwards <elwin@sdf.org>
parents: 113
diff changeset
56 "suffix": ".ar5sav",
144
81a8e7aa4687 RLGWebD: game binaries have moved to /usr/bin.
John "Elwin" Edwards
parents: 142
diff changeset
57 "path": "/usr/bin/arogue5",
120
54979d35611a Add support for Advanced Rogue 5.
John "Elwin" Edwards <elwin@sdf.org>
parents: 113
diff changeset
58 "clear": new Buffer([27, 91, 72, 27, 91, 50, 74]) // CSI H CSI 2J
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
59 }
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
60 };
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
61
39
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
62 /* Global state */
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
63 var logins = {};
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
64 var sessions = {};
156
127f9e256d02 Keep a list of dgamelaunch games and put it in the /status message.
John "Elwin" Edwards
parents: 155
diff changeset
65 var dglgames = {};
39
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
66 var allowlogin = true;
104
7d444ba4739e RLG-Web server: send status events over WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 103
diff changeset
67 var gamemux = new events.EventEmitter();
39
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
68
55
96815eae4ebe RLG-Web: make multiple watchers possible.
John "Elwin" Edwards <elwin@sdf.org>
parents: 49
diff changeset
69 /* Constructor. A TermSession handles a pty and the game running on it.
96815eae4ebe RLG-Web: make multiple watchers possible.
John "Elwin" Edwards <elwin@sdf.org>
parents: 49
diff changeset
70 * game: (String) Name of the game to launch.
96815eae4ebe RLG-Web: make multiple watchers possible.
John "Elwin" Edwards <elwin@sdf.org>
parents: 49
diff changeset
71 * lkey: (String, key) The user's id, a key into logins.
96815eae4ebe RLG-Web: make multiple watchers possible.
John "Elwin" Edwards <elwin@sdf.org>
parents: 49
diff changeset
72 * dims: (Array [Number, Number]) Height and width of the pty.
96815eae4ebe RLG-Web: make multiple watchers possible.
John "Elwin" Edwards <elwin@sdf.org>
parents: 49
diff changeset
73 * handlers: (Object) Key-value pairs, event names and functions to
96815eae4ebe RLG-Web: make multiple watchers possible.
John "Elwin" Edwards <elwin@sdf.org>
parents: 49
diff changeset
74 * install to handle them.
96815eae4ebe RLG-Web: make multiple watchers possible.
John "Elwin" Edwards <elwin@sdf.org>
parents: 49
diff changeset
75 * Events:
96815eae4ebe RLG-Web: make multiple watchers possible.
John "Elwin" Edwards <elwin@sdf.org>
parents: 49
diff changeset
76 * "data": Data generated by child. Parameters: buf (Buffer)
87
bd2cf6dda28d RLG-Web: use the pty module.
John "Elwin" Edwards <elwin@sdf.org>
parents: 85
diff changeset
77 * "exit": Child terminated. Parameters: none
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
78 */
55
96815eae4ebe RLG-Web: make multiple watchers possible.
John "Elwin" Edwards <elwin@sdf.org>
parents: 49
diff changeset
79 function TermSession(game, lkey, dims, handlers) {
96815eae4ebe RLG-Web: make multiple watchers possible.
John "Elwin" Edwards <elwin@sdf.org>
parents: 49
diff changeset
80 var ss = this;
96815eae4ebe RLG-Web: make multiple watchers possible.
John "Elwin" Edwards <elwin@sdf.org>
parents: 49
diff changeset
81 /* Subclass EventEmitter to do the hard work. */
96815eae4ebe RLG-Web: make multiple watchers possible.
John "Elwin" Edwards <elwin@sdf.org>
parents: 49
diff changeset
82 events.EventEmitter.call(this);
96815eae4ebe RLG-Web: make multiple watchers possible.
John "Elwin" Edwards <elwin@sdf.org>
parents: 49
diff changeset
83 for (var evname in handlers)
96815eae4ebe RLG-Web: make multiple watchers possible.
John "Elwin" Edwards <elwin@sdf.org>
parents: 49
diff changeset
84 this.on(evname, handlers[evname]);
96815eae4ebe RLG-Web: make multiple watchers possible.
John "Elwin" Edwards <elwin@sdf.org>
parents: 49
diff changeset
85 /* Don't launch anything that's not a real game. */
32
c75fc4b1d13d rlgwebd.js: add a status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 31
diff changeset
86 if (game in games) {
c75fc4b1d13d rlgwebd.js: add a status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 31
diff changeset
87 this.game = games[game];
c75fc4b1d13d rlgwebd.js: add a status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 31
diff changeset
88 }
c75fc4b1d13d rlgwebd.js: add a status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 31
diff changeset
89 else {
168
0ceaca924b4c Remove the TermSession 'open' event.
John "Elwin" Edwards
parents: 167
diff changeset
90 this.failed = true;
55
96815eae4ebe RLG-Web: make multiple watchers possible.
John "Elwin" Edwards <elwin@sdf.org>
parents: 49
diff changeset
91 return;
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
92 }
55
96815eae4ebe RLG-Web: make multiple watchers possible.
John "Elwin" Edwards <elwin@sdf.org>
parents: 49
diff changeset
93 if (lkey in logins) {
96815eae4ebe RLG-Web: make multiple watchers possible.
John "Elwin" Edwards <elwin@sdf.org>
parents: 49
diff changeset
94 this.key = lkey;
96815eae4ebe RLG-Web: make multiple watchers possible.
John "Elwin" Edwards <elwin@sdf.org>
parents: 49
diff changeset
95 this.pname = logins[lkey].name;
96815eae4ebe RLG-Web: make multiple watchers possible.
John "Elwin" Edwards <elwin@sdf.org>
parents: 49
diff changeset
96 }
96815eae4ebe RLG-Web: make multiple watchers possible.
John "Elwin" Edwards <elwin@sdf.org>
parents: 49
diff changeset
97 else {
168
0ceaca924b4c Remove the TermSession 'open' event.
John "Elwin" Edwards
parents: 167
diff changeset
98 this.failed = true;
55
96815eae4ebe RLG-Web: make multiple watchers possible.
John "Elwin" Edwards <elwin@sdf.org>
parents: 49
diff changeset
99 return;
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
100 }
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
101 /* Grab a spot in the sessions table. */
158
9961a538c00e rlgwebd.js: get rid of numerical game identifiers.
John "Elwin" Edwards
parents: 157
diff changeset
102 sessions[this.game.uname + "/" + this.pname] = this;
16
ef6127ed6da3 RLGWeb: switch to JSON protocol.
John "Elwin" Edwards <elwin@sdf.org>
parents: 8
diff changeset
103 /* Set up the sizes. */
ef6127ed6da3 RLGWeb: switch to JSON protocol.
John "Elwin" Edwards <elwin@sdf.org>
parents: 8
diff changeset
104 this.w = Math.floor(Number(dims[1]));
ef6127ed6da3 RLGWeb: switch to JSON protocol.
John "Elwin" Edwards <elwin@sdf.org>
parents: 8
diff changeset
105 if (!(this.w > 0 && this.w < 256))
ef6127ed6da3 RLGWeb: switch to JSON protocol.
John "Elwin" Edwards <elwin@sdf.org>
parents: 8
diff changeset
106 this.w = 80;
ef6127ed6da3 RLGWeb: switch to JSON protocol.
John "Elwin" Edwards <elwin@sdf.org>
parents: 8
diff changeset
107 this.h = Math.floor(Number(dims[0]));
ef6127ed6da3 RLGWeb: switch to JSON protocol.
John "Elwin" Edwards <elwin@sdf.org>
parents: 8
diff changeset
108 if (!(this.h > 0 && this.h < 256))
ef6127ed6da3 RLGWeb: switch to JSON protocol.
John "Elwin" Edwards <elwin@sdf.org>
parents: 8
diff changeset
109 this.h = 24;
ef6127ed6da3 RLGWeb: switch to JSON protocol.
John "Elwin" Edwards <elwin@sdf.org>
parents: 8
diff changeset
110 /* Environment. */
ef6127ed6da3 RLGWeb: switch to JSON protocol.
John "Elwin" Edwards <elwin@sdf.org>
parents: 8
diff changeset
111 var childenv = {};
ef6127ed6da3 RLGWeb: switch to JSON protocol.
John "Elwin" Edwards <elwin@sdf.org>
parents: 8
diff changeset
112 for (var key in process.env) {
ef6127ed6da3 RLGWeb: switch to JSON protocol.
John "Elwin" Edwards <elwin@sdf.org>
parents: 8
diff changeset
113 childenv[key] = process.env[key];
ef6127ed6da3 RLGWeb: switch to JSON protocol.
John "Elwin" Edwards <elwin@sdf.org>
parents: 8
diff changeset
114 }
87
bd2cf6dda28d RLG-Web: use the pty module.
John "Elwin" Edwards <elwin@sdf.org>
parents: 85
diff changeset
115 var args = ["-n", this.pname];
bd2cf6dda28d RLG-Web: use the pty module.
John "Elwin" Edwards <elwin@sdf.org>
parents: 85
diff changeset
116 var spawnopts = {"env": childenv, "cwd": "/", "rows": this.h, "cols": this.w,
bd2cf6dda28d RLG-Web: use the pty module.
John "Elwin" Edwards <elwin@sdf.org>
parents: 85
diff changeset
117 "name": "xterm-256color"};
bd2cf6dda28d RLG-Web: use the pty module.
John "Elwin" Edwards <elwin@sdf.org>
parents: 85
diff changeset
118 this.term = pty.spawn(this.game.path, args, spawnopts);
158
9961a538c00e rlgwebd.js: get rid of numerical game identifiers.
John "Elwin" Edwards
parents: 157
diff changeset
119 tslog("%s playing %s (pid %d)", this.pname, this.game.uname, this.term.pid);
168
0ceaca924b4c Remove the TermSession 'open' event.
John "Elwin" Edwards
parents: 167
diff changeset
120 this.failed = false;
158
9961a538c00e rlgwebd.js: get rid of numerical game identifiers.
John "Elwin" Edwards
parents: 157
diff changeset
121 gamemux.emit('begin', this.game.uname, this.pname);
40
f7116eb3f791 rlgwebd.js: refactor some game-starting code.
John "Elwin" Edwards <elwin@sdf.org>
parents: 39
diff changeset
122 /* Set up the lockfile and ttyrec */
160
ed837da65e5f RLGWebD: Clean up code related to session timestamps.
John "Elwin" Edwards
parents: 159
diff changeset
123 this.lasttime = new Date();
ed837da65e5f RLGWebD: Clean up code related to session timestamps.
John "Elwin" Edwards
parents: 159
diff changeset
124 var ts = timestamp(this.lasttime);
142
c4304f08e35b RLGWebD: inprogress dirs have moved
John "Elwin" Edwards
parents: 141
diff changeset
125 var progressdir = path.join("/dgldir/inprogress", this.game.uname);
55
96815eae4ebe RLG-Web: make multiple watchers possible.
John "Elwin" Edwards <elwin@sdf.org>
parents: 49
diff changeset
126 this.lock = path.join(progressdir, this.pname + ":node:" + ts + ".ttyrec");
110
18a81cc0084b RLG-Web: fix lockfile mixup.
John "Elwin" Edwards <elwin@sdf.org>
parents: 109
diff changeset
127 var lmsg = this.term.pid.toString() + '\n' + this.h + '\n' + this.w + '\n';
40
f7116eb3f791 rlgwebd.js: refactor some game-starting code.
John "Elwin" Edwards <elwin@sdf.org>
parents: 39
diff changeset
128 fs.writeFile(this.lock, lmsg, "utf8");
55
96815eae4ebe RLG-Web: make multiple watchers possible.
John "Elwin" Edwards <elwin@sdf.org>
parents: 49
diff changeset
129 var ttyrec = path.join("/dgldir/ttyrec", this.pname, this.game.uname,
40
f7116eb3f791 rlgwebd.js: refactor some game-starting code.
John "Elwin" Edwards <elwin@sdf.org>
parents: 39
diff changeset
130 ts + ".ttyrec");
f7116eb3f791 rlgwebd.js: refactor some game-starting code.
John "Elwin" Edwards <elwin@sdf.org>
parents: 39
diff changeset
131 this.record = fs.createWriteStream(ttyrec, { mode: 0664 });
60
31bb3cf4f25f Make sure watchers start with completely drawn screens.
John "Elwin" Edwards <elwin@sdf.org>
parents: 55
diff changeset
132 /* Holds the output since the last screen clear, so watchers can begin
31bb3cf4f25f Make sure watchers start with completely drawn screens.
John "Elwin" Edwards <elwin@sdf.org>
parents: 55
diff changeset
133 * with a complete screen. */
31bb3cf4f25f Make sure watchers start with completely drawn screens.
John "Elwin" Edwards <elwin@sdf.org>
parents: 55
diff changeset
134 this.framebuf = new Buffer(1024);
31bb3cf4f25f Make sure watchers start with completely drawn screens.
John "Elwin" Edwards <elwin@sdf.org>
parents: 55
diff changeset
135 this.frameoff = 0;
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
136 /* END setup */
87
bd2cf6dda28d RLG-Web: use the pty module.
John "Elwin" Edwards <elwin@sdf.org>
parents: 85
diff changeset
137 function ttyrec_chunk(datastr) {
160
ed837da65e5f RLGWebD: Clean up code related to session timestamps.
John "Elwin" Edwards
parents: 159
diff changeset
138 ss.lasttime = new Date();
87
bd2cf6dda28d RLG-Web: use the pty module.
John "Elwin" Edwards <elwin@sdf.org>
parents: 85
diff changeset
139 var buf = new Buffer(datastr);
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
140 var chunk = new Buffer(buf.length + 12);
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
141 /* TTYREC headers */
160
ed837da65e5f RLGWebD: Clean up code related to session timestamps.
John "Elwin" Edwards
parents: 159
diff changeset
142 chunk.writeUInt32LE(Math.floor(ss.lasttime.getTime() / 1000), 0);
ed837da65e5f RLGWebD: Clean up code related to session timestamps.
John "Elwin" Edwards
parents: 159
diff changeset
143 chunk.writeUInt32LE(1000 * (ss.lasttime.getTime() % 1000), 4);
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
144 chunk.writeUInt32LE(buf.length, 8);
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
145 buf.copy(chunk, 12);
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
146 ss.record.write(chunk);
60
31bb3cf4f25f Make sure watchers start with completely drawn screens.
John "Elwin" Edwards <elwin@sdf.org>
parents: 55
diff changeset
147 ss.framepush(buf);
55
96815eae4ebe RLG-Web: make multiple watchers possible.
John "Elwin" Edwards <elwin@sdf.org>
parents: 49
diff changeset
148 ss.emit('data', buf);
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
149 }
87
bd2cf6dda28d RLG-Web: use the pty module.
John "Elwin" Edwards <elwin@sdf.org>
parents: 85
diff changeset
150 this.term.on("data", ttyrec_chunk);
60
31bb3cf4f25f Make sure watchers start with completely drawn screens.
John "Elwin" Edwards <elwin@sdf.org>
parents: 55
diff changeset
151 this.framepush = function(chunk) {
31bb3cf4f25f Make sure watchers start with completely drawn screens.
John "Elwin" Edwards <elwin@sdf.org>
parents: 55
diff changeset
152 /* If this chunk resets the screen, discard what preceded it. */
31bb3cf4f25f Make sure watchers start with completely drawn screens.
John "Elwin" Edwards <elwin@sdf.org>
parents: 55
diff changeset
153 if (bufncmp(chunk, this.game.clear, this.game.clear.length)) {
31bb3cf4f25f Make sure watchers start with completely drawn screens.
John "Elwin" Edwards <elwin@sdf.org>
parents: 55
diff changeset
154 this.framebuf = new Buffer(1024);
31bb3cf4f25f Make sure watchers start with completely drawn screens.
John "Elwin" Edwards <elwin@sdf.org>
parents: 55
diff changeset
155 this.frameoff = 0;
31bb3cf4f25f Make sure watchers start with completely drawn screens.
John "Elwin" Edwards <elwin@sdf.org>
parents: 55
diff changeset
156 }
31bb3cf4f25f Make sure watchers start with completely drawn screens.
John "Elwin" Edwards <elwin@sdf.org>
parents: 55
diff changeset
157 /* Make sure there's space. */
31bb3cf4f25f Make sure watchers start with completely drawn screens.
John "Elwin" Edwards <elwin@sdf.org>
parents: 55
diff changeset
158 while (this.framebuf.length < chunk.length + this.frameoff) {
31bb3cf4f25f Make sure watchers start with completely drawn screens.
John "Elwin" Edwards <elwin@sdf.org>
parents: 55
diff changeset
159 var nbuf = new Buffer(this.framebuf.length * 2);
31bb3cf4f25f Make sure watchers start with completely drawn screens.
John "Elwin" Edwards <elwin@sdf.org>
parents: 55
diff changeset
160 this.framebuf.copy(nbuf, 0, 0, this.frameoff);
31bb3cf4f25f Make sure watchers start with completely drawn screens.
John "Elwin" Edwards <elwin@sdf.org>
parents: 55
diff changeset
161 this.framebuf = nbuf;
31bb3cf4f25f Make sure watchers start with completely drawn screens.
John "Elwin" Edwards <elwin@sdf.org>
parents: 55
diff changeset
162 if (this.framebuf.length > 65536) {
162
5a7e7ec136c8 Properly print session tags in the log.
John "Elwin" Edwards
parents: 160
diff changeset
163 tslog("Warning: Game %s frame buffer at %d bytes", this.tag(),
60
31bb3cf4f25f Make sure watchers start with completely drawn screens.
John "Elwin" Edwards <elwin@sdf.org>
parents: 55
diff changeset
164 this.framebuf.length);
31bb3cf4f25f Make sure watchers start with completely drawn screens.
John "Elwin" Edwards <elwin@sdf.org>
parents: 55
diff changeset
165 }
31bb3cf4f25f Make sure watchers start with completely drawn screens.
John "Elwin" Edwards <elwin@sdf.org>
parents: 55
diff changeset
166 }
31bb3cf4f25f Make sure watchers start with completely drawn screens.
John "Elwin" Edwards <elwin@sdf.org>
parents: 55
diff changeset
167 chunk.copy(this.framebuf, this.frameoff);
31bb3cf4f25f Make sure watchers start with completely drawn screens.
John "Elwin" Edwards <elwin@sdf.org>
parents: 55
diff changeset
168 this.frameoff += chunk.length;
31bb3cf4f25f Make sure watchers start with completely drawn screens.
John "Elwin" Edwards <elwin@sdf.org>
parents: 55
diff changeset
169 };
55
96815eae4ebe RLG-Web: make multiple watchers possible.
John "Elwin" Edwards <elwin@sdf.org>
parents: 49
diff changeset
170 this.write = function(data) {
87
bd2cf6dda28d RLG-Web: use the pty module.
John "Elwin" Edwards <elwin@sdf.org>
parents: 85
diff changeset
171 this.term.write(data);
55
96815eae4ebe RLG-Web: make multiple watchers possible.
John "Elwin" Edwards <elwin@sdf.org>
parents: 49
diff changeset
172 };
158
9961a538c00e rlgwebd.js: get rid of numerical game identifiers.
John "Elwin" Edwards
parents: 157
diff changeset
173 this.tag = function() {
9961a538c00e rlgwebd.js: get rid of numerical game identifiers.
John "Elwin" Edwards
parents: 157
diff changeset
174 return this.game.uname + "/" + this.pname;
9961a538c00e rlgwebd.js: get rid of numerical game identifiers.
John "Elwin" Edwards
parents: 157
diff changeset
175 };
100
3dbfdaf62623 RLG-Web: begin converting to WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 94
diff changeset
176 // Teardown.
87
bd2cf6dda28d RLG-Web: use the pty module.
John "Elwin" Edwards <elwin@sdf.org>
parents: 85
diff changeset
177 this.term.on("exit", function () {
158
9961a538c00e rlgwebd.js: get rid of numerical game identifiers.
John "Elwin" Edwards
parents: 157
diff changeset
178 var tag = ss.tag();
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
179 fs.unlink(ss.lock);
55
96815eae4ebe RLG-Web: make multiple watchers possible.
John "Elwin" Edwards <elwin@sdf.org>
parents: 49
diff changeset
180 ss.record.end();
87
bd2cf6dda28d RLG-Web: use the pty module.
John "Elwin" Edwards <elwin@sdf.org>
parents: 85
diff changeset
181 ss.emit('exit');
158
9961a538c00e rlgwebd.js: get rid of numerical game identifiers.
John "Elwin" Edwards
parents: 157
diff changeset
182 gamemux.emit('end', ss.game.uname, ss.pname);
9961a538c00e rlgwebd.js: get rid of numerical game identifiers.
John "Elwin" Edwards
parents: 157
diff changeset
183 delete sessions[tag];
9961a538c00e rlgwebd.js: get rid of numerical game identifiers.
John "Elwin" Edwards
parents: 157
diff changeset
184 tslog("Game %s ended.", tag);
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
185 });
55
96815eae4ebe RLG-Web: make multiple watchers possible.
John "Elwin" Edwards <elwin@sdf.org>
parents: 49
diff changeset
186 this.close = function () {
158
9961a538c00e rlgwebd.js: get rid of numerical game identifiers.
John "Elwin" Edwards
parents: 157
diff changeset
187 if (this.tag() in sessions)
107
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
188 this.term.kill('SIGHUP');
55
96815eae4ebe RLG-Web: make multiple watchers possible.
John "Elwin" Edwards <elwin@sdf.org>
parents: 49
diff changeset
189 };
96815eae4ebe RLG-Web: make multiple watchers possible.
John "Elwin" Edwards <elwin@sdf.org>
parents: 49
diff changeset
190 }
96815eae4ebe RLG-Web: make multiple watchers possible.
John "Elwin" Edwards <elwin@sdf.org>
parents: 49
diff changeset
191 TermSession.prototype = new events.EventEmitter();
96815eae4ebe RLG-Web: make multiple watchers possible.
John "Elwin" Edwards <elwin@sdf.org>
parents: 49
diff changeset
192
164
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
193 function DglSession(filename) {
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
194 var ss = this;
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
195 events.EventEmitter.call(this);
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
196 var pathcoms = filename.split('/');
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
197 this.gname = pathcoms[pathcoms.length - 2];
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
198 if (!(this.gname in games)) {
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
199 ss.emit('open', false);
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
200 return;
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
201 }
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
202 var basename = pathcoms[pathcoms.length - 1];
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
203 var firstsep = basename.indexOf(':');
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
204 this.pname = basename.slice(0, firstsep);
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
205 var fname = basename.slice(firstsep + 1);
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
206 this.ttyrec = path.join("/dgldir/ttyrec", this.pname, this.gname, fname);
165
59e62710cbb5 rlgwebd.js: prevent races when reading ttyrecs.
John "Elwin" Edwards
parents: 164
diff changeset
207 /* Flag to prevent multiple handlers from reading simultaneously and
59e62710cbb5 rlgwebd.js: prevent races when reading ttyrecs.
John "Elwin" Edwards
parents: 164
diff changeset
208 * getting into a race. */
59e62710cbb5 rlgwebd.js: prevent races when reading ttyrecs.
John "Elwin" Edwards
parents: 164
diff changeset
209 this.reading = false;
164
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
210 this.framebuf = new Buffer(1024);
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
211 this.frameoff = 0;
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
212 this.framepush = function(chunk) {
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
213 /* If this chunk resets the screen, discard what preceded it. */
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
214 var cgame = games[this.gname];
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
215 if (bufncmp(chunk, cgame.clear, cgame.clear.length)) {
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
216 tslog("DGL %s: clearing frame", ss.tag());
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
217 this.framebuf = new Buffer(1024);
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
218 this.frameoff = 0;
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
219 }
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
220 /* Make sure there's space. */
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
221 while (this.framebuf.length < chunk.length + this.frameoff) {
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
222 var nbuf = new Buffer(this.framebuf.length * 2);
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
223 this.framebuf.copy(nbuf, 0, 0, this.frameoff);
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
224 this.framebuf = nbuf;
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
225 if (this.framebuf.length > 65536) {
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
226 tslog("Warning: DGL %s frame buffer at %d bytes", this.tag(),
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
227 this.framebuf.length);
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
228 }
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
229 }
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
230 chunk.copy(this.framebuf, this.frameoff);
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
231 this.frameoff += chunk.length;
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
232 };
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
233 this.readchunk = function () {
165
59e62710cbb5 rlgwebd.js: prevent races when reading ttyrecs.
John "Elwin" Edwards
parents: 164
diff changeset
234 if (this.reading)
59e62710cbb5 rlgwebd.js: prevent races when reading ttyrecs.
John "Elwin" Edwards
parents: 164
diff changeset
235 return;
59e62710cbb5 rlgwebd.js: prevent races when reading ttyrecs.
John "Elwin" Edwards
parents: 164
diff changeset
236 this.reading = true;
164
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
237 var header = new Buffer(12);
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
238 fs.read(ss.fd, header, 0, 12, null, function (err, n, buf) {
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
239 /* Stop recursion if end of file has been reached. */
165
59e62710cbb5 rlgwebd.js: prevent races when reading ttyrecs.
John "Elwin" Edwards
parents: 164
diff changeset
240 if (err || n < 12) {
59e62710cbb5 rlgwebd.js: prevent races when reading ttyrecs.
John "Elwin" Edwards
parents: 164
diff changeset
241 ss.reading = false;
164
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
242 return;
165
59e62710cbb5 rlgwebd.js: prevent races when reading ttyrecs.
John "Elwin" Edwards
parents: 164
diff changeset
243 }
164
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
244 var datalen = buf.readUInt32LE(8);
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
245 //tslog("Allocating %d bytes", datalen);
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
246 var databuf = new Buffer(datalen);
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
247 fs.read(ss.fd, databuf, 0, datalen, null, function (err, n, buf) {
165
59e62710cbb5 rlgwebd.js: prevent races when reading ttyrecs.
John "Elwin" Edwards
parents: 164
diff changeset
248 ss.reading = false;
59e62710cbb5 rlgwebd.js: prevent races when reading ttyrecs.
John "Elwin" Edwards
parents: 164
diff changeset
249 if (err || n < datalen) {
164
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
250 return;
165
59e62710cbb5 rlgwebd.js: prevent races when reading ttyrecs.
John "Elwin" Edwards
parents: 164
diff changeset
251 }
164
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
252 /* Process the data */
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
253 ss.framepush(buf);
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
254 ss.emit("data", buf);
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
255 tslog("DGL %s: %d bytes", ss.tag(), buf.length);
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
256 /* Recurse. */
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
257 ss.readchunk();
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
258 });
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
259 });
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
260 };
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
261 fs.readFile(filename, {encoding: "utf8"}, function (err, data) {
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
262 if (err) {
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
263 ss.emit('open', false);
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
264 return;
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
265 }
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
266 var lines = data.split('\n');
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
267 ss.h = Number(lines[1]);
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
268 ss.w = Number(lines[2]);
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
269 fs.open(ss.ttyrec, "r", function(err, fd) {
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
270 if (err) {
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
271 ss.emit('open', false);
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
272 }
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
273 else {
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
274 ss.fd = fd;
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
275 ss.emit('open', true);
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
276 tslog("DGL %s: open", ss.tag());
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
277 ss.readchunk();
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
278 ss.watcher = fs.watch(ss.ttyrec, function (ev, finame) {
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
279 if (ev == "change")
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
280 ss.readchunk();
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
281 });
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
282 }
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
283 });
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
284 });
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
285 this.tag = function () {
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
286 return this.gname + "/" + this.pname;
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
287 };
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
288 this.close = function () {
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
289 this.watcher.close()
165
59e62710cbb5 rlgwebd.js: prevent races when reading ttyrecs.
John "Elwin" Edwards
parents: 164
diff changeset
290 /* Ensure all data is handled before quitting. */
59e62710cbb5 rlgwebd.js: prevent races when reading ttyrecs.
John "Elwin" Edwards
parents: 164
diff changeset
291 this.readchunk();
164
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
292 fs.close(this.fd);
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
293 this.emit("close");
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
294 tslog("DGL %s: closed", ss.tag());
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
295 };
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
296 }
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
297 DglSession.prototype = new events.EventEmitter();
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
298
100
3dbfdaf62623 RLG-Web: begin converting to WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 94
diff changeset
299 // Also known as WebSocketAndTermSessionClosureGlueFactory
3dbfdaf62623 RLG-Web: begin converting to WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 94
diff changeset
300 function wsWatcher(conn, session) {
3dbfdaf62623 RLG-Web: begin converting to WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 94
diff changeset
301 var ss = this; // is this even needed?
3dbfdaf62623 RLG-Web: begin converting to WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 94
diff changeset
302 var dataH = function(buf) {
3dbfdaf62623 RLG-Web: begin converting to WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 94
diff changeset
303 conn.sendUTF(JSON.stringify({"t": "d", "d": buf.toString("hex")}));
3dbfdaf62623 RLG-Web: begin converting to WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 94
diff changeset
304 };
3dbfdaf62623 RLG-Web: begin converting to WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 94
diff changeset
305 var exitH = function() {
3dbfdaf62623 RLG-Web: begin converting to WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 94
diff changeset
306 if (conn.connected)
3dbfdaf62623 RLG-Web: begin converting to WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 94
diff changeset
307 conn.close();
3dbfdaf62623 RLG-Web: begin converting to WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 94
diff changeset
308 }
3dbfdaf62623 RLG-Web: begin converting to WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 94
diff changeset
309 session.on('data', dataH);
3dbfdaf62623 RLG-Web: begin converting to WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 94
diff changeset
310 session.on('exit', exitH);
3dbfdaf62623 RLG-Web: begin converting to WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 94
diff changeset
311 conn.on('close', function(code, desc) {
3dbfdaf62623 RLG-Web: begin converting to WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 94
diff changeset
312 session.removeListener('data', dataH);
3dbfdaf62623 RLG-Web: begin converting to WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 94
diff changeset
313 session.removeListener('exit', exitH);
158
9961a538c00e rlgwebd.js: get rid of numerical game identifiers.
John "Elwin" Edwards
parents: 157
diff changeset
314 if (session.tag() in sessions)
162
5a7e7ec136c8 Properly print session tags in the log.
John "Elwin" Edwards
parents: 160
diff changeset
315 tslog("A WebSocket watcher has left game %s", session.tag());
100
3dbfdaf62623 RLG-Web: begin converting to WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 94
diff changeset
316 });
101
e59d68082664 RLG-Web: Complete the WebSocket watcher.
John "Elwin" Edwards <elwin@sdf.org>
parents: 100
diff changeset
317 conn.sendUTF(JSON.stringify({
e59d68082664 RLG-Web: Complete the WebSocket watcher.
John "Elwin" Edwards <elwin@sdf.org>
parents: 100
diff changeset
318 "t": "w", "w": session.w, "h": session.h,
e59d68082664 RLG-Web: Complete the WebSocket watcher.
John "Elwin" Edwards <elwin@sdf.org>
parents: 100
diff changeset
319 "p": session.pname, "g": session.game.uname
e59d68082664 RLG-Web: Complete the WebSocket watcher.
John "Elwin" Edwards <elwin@sdf.org>
parents: 100
diff changeset
320 }));
100
3dbfdaf62623 RLG-Web: begin converting to WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 94
diff changeset
321 conn.sendUTF(JSON.stringify({"t": "d",
3dbfdaf62623 RLG-Web: begin converting to WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 94
diff changeset
322 "d": session.framebuf.toString("hex", 0, session.frameoff)}));
3dbfdaf62623 RLG-Web: begin converting to WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 94
diff changeset
323 }
3dbfdaf62623 RLG-Web: begin converting to WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 94
diff changeset
324
107
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
325 function wsPlay(wsReq, game, lkey, dims) {
168
0ceaca924b4c Remove the TermSession 'open' event.
John "Elwin" Edwards
parents: 167
diff changeset
326 tslog("wsPlay: running for %s/%s", game, logins[lkey].name);
0ceaca924b4c Remove the TermSession 'open' event.
John "Elwin" Edwards
parents: 167
diff changeset
327 tslog("Request is for %s", logins[wsReq.resourceURL.query["key"]].name);
107
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
328 var conn;
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
329 var session;
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
330 /* Listeners on the WebSocket */
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
331 function messageH(message) {
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
332 var parsedMsg = getMsgWS(message);
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
333 if (parsedMsg.t == 'q') {
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
334 session.close();
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
335 }
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
336 else if (parsedMsg.t == 'd') {
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
337 var hexstr = parsedMsg.d.replace(/[^0-9a-f]/gi, "");
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
338 if (hexstr.length % 2 != 0) {
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
339 hexstr = hexstr.slice(0, -1);
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
340 }
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
341 var keybuf = new Buffer(hexstr, "hex");
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
342 session.write(keybuf);
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
343 }
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
344 }
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
345 function closeH() {
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
346 session.close();
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
347 }
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
348 /* These listen on the TermSession. */
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
349 function dataH(chunk) {
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
350 var msg = {};
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
351 msg.t = "d";
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
352 msg.d = chunk.toString("hex");
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
353 conn.sendUTF(JSON.stringify(msg));
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
354 }
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
355 function exitH() {
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
356 if (conn.connected)
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
357 conn.sendUTF(JSON.stringify({"t": "q"}));
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
358 conn.close();
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
359 session.removeListener('data', dataH);
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
360 session.removeListener('exit', exitH);
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
361 }
168
0ceaca924b4c Remove the TermSession 'open' event.
John "Elwin" Edwards
parents: 167
diff changeset
362 var handlers = {'data': dataH, 'exit': exitH};
107
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
363 session = new TermSession(game, lkey, dims, handlers);
168
0ceaca924b4c Remove the TermSession 'open' event.
John "Elwin" Edwards
parents: 167
diff changeset
364 if (!session.failed) {
0ceaca924b4c Remove the TermSession 'open' event.
John "Elwin" Edwards
parents: 167
diff changeset
365 var tag = session.game.uname + "/" + session.pname;
0ceaca924b4c Remove the TermSession 'open' event.
John "Elwin" Edwards
parents: 167
diff changeset
366 var reply = {"t": "s", "tag": tag, "w": session.w, "h": session.h,
0ceaca924b4c Remove the TermSession 'open' event.
John "Elwin" Edwards
parents: 167
diff changeset
367 "p": session.pname, "g": session.game.uname};
0ceaca924b4c Remove the TermSession 'open' event.
John "Elwin" Edwards
parents: 167
diff changeset
368 tslog("Accepting for %s", tag);
0ceaca924b4c Remove the TermSession 'open' event.
John "Elwin" Edwards
parents: 167
diff changeset
369 tslog("Request is for %s", logins[wsReq.resourceURL.query["key"]].name);
0ceaca924b4c Remove the TermSession 'open' event.
John "Elwin" Edwards
parents: 167
diff changeset
370 tslog("Session is for %s", session.pname);
0ceaca924b4c Remove the TermSession 'open' event.
John "Elwin" Edwards
parents: 167
diff changeset
371 conn = wsReq.accept(null, wsReq.origin);
0ceaca924b4c Remove the TermSession 'open' event.
John "Elwin" Edwards
parents: 167
diff changeset
372 conn.sendUTF(JSON.stringify(reply));
0ceaca924b4c Remove the TermSession 'open' event.
John "Elwin" Edwards
parents: 167
diff changeset
373 conn.on('message', messageH);
0ceaca924b4c Remove the TermSession 'open' event.
John "Elwin" Edwards
parents: 167
diff changeset
374 conn.on('close', closeH);
0ceaca924b4c Remove the TermSession 'open' event.
John "Elwin" Edwards
parents: 167
diff changeset
375 }
0ceaca924b4c Remove the TermSession 'open' event.
John "Elwin" Edwards
parents: 167
diff changeset
376 else {
0ceaca924b4c Remove the TermSession 'open' event.
John "Elwin" Edwards
parents: 167
diff changeset
377 wsReq.reject(500, errorcodes[5]);
0ceaca924b4c Remove the TermSession 'open' event.
John "Elwin" Edwards
parents: 167
diff changeset
378 tslog("Unable to allocate TTY for %s", game);
0ceaca924b4c Remove the TermSession 'open' event.
John "Elwin" Edwards
parents: 167
diff changeset
379 }
107
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
380 }
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
381
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
382 function wsStart(wsReq) {
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
383 var playmatch = wsReq.resourceURL.pathname.match(/^\/play\/([^\/]*)$/);
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
384 if (!playmatch[1] || !(playmatch[1] in games)) {
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
385 wsReq.reject(404, errorcodes[2]);
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
386 return;
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
387 }
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
388 var gname = playmatch[1];
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
389 if (!allowlogin) {
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
390 wsReq.reject(404, errorcodes[6]);
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
391 return;
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
392 }
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
393 if (!("key" in wsReq.resourceURL.query)) {
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
394 wsReq.reject(404, "No key given.");
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
395 return;
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
396 }
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
397 var lkey = wsReq.resourceURL.query["key"];
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
398 if (!(lkey in logins)) {
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
399 wsReq.reject(404, errorcodes[1]);
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
400 return;
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
401 }
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
402 var pname = logins[lkey].name;
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
403 var dims = [wsReq.resourceURL.query.h, wsReq.resourceURL.query.w];
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
404 function progcallback(err, fname) {
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
405 if (fname) {
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
406 wsReq.reject(404, errorcodes[4]);
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
407 tslog("%s is already playing %s", pname, gname);
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
408 }
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
409 else
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
410 wsPlay(wsReq, gname, lkey, dims);
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
411 };
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
412 checkprogress(pname, games[gname], progcallback, []);
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
413 }
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
414
55
96815eae4ebe RLG-Web: make multiple watchers possible.
John "Elwin" Edwards <elwin@sdf.org>
parents: 49
diff changeset
415 /* Some functions which check whether a player is currently playing or
96815eae4ebe RLG-Web: make multiple watchers possible.
John "Elwin" Edwards <elwin@sdf.org>
parents: 49
diff changeset
416 * has a saved game. Maybe someday they will provide information on
96815eae4ebe RLG-Web: make multiple watchers possible.
John "Elwin" Edwards <elwin@sdf.org>
parents: 49
diff changeset
417 * the game. */
40
f7116eb3f791 rlgwebd.js: refactor some game-starting code.
John "Elwin" Edwards <elwin@sdf.org>
parents: 39
diff changeset
418 function checkprogress(user, game, callback, args) {
142
c4304f08e35b RLGWebD: inprogress dirs have moved
John "Elwin" Edwards
parents: 141
diff changeset
419 var progressdir = path.join("/dgldir/inprogress", game.uname);
40
f7116eb3f791 rlgwebd.js: refactor some game-starting code.
John "Elwin" Edwards <elwin@sdf.org>
parents: 39
diff changeset
420 fs.readdir(progressdir, function(err, files) {
f7116eb3f791 rlgwebd.js: refactor some game-starting code.
John "Elwin" Edwards <elwin@sdf.org>
parents: 39
diff changeset
421 if (err) {
f7116eb3f791 rlgwebd.js: refactor some game-starting code.
John "Elwin" Edwards <elwin@sdf.org>
parents: 39
diff changeset
422 args.unshift(err, null);
f7116eb3f791 rlgwebd.js: refactor some game-starting code.
John "Elwin" Edwards <elwin@sdf.org>
parents: 39
diff changeset
423 callback.apply(null, args);
f7116eb3f791 rlgwebd.js: refactor some game-starting code.
John "Elwin" Edwards <elwin@sdf.org>
parents: 39
diff changeset
424 return;
f7116eb3f791 rlgwebd.js: refactor some game-starting code.
John "Elwin" Edwards <elwin@sdf.org>
parents: 39
diff changeset
425 }
f7116eb3f791 rlgwebd.js: refactor some game-starting code.
John "Elwin" Edwards <elwin@sdf.org>
parents: 39
diff changeset
426 var fre = RegExp("^" + user + ":");
f7116eb3f791 rlgwebd.js: refactor some game-starting code.
John "Elwin" Edwards <elwin@sdf.org>
parents: 39
diff changeset
427 for (var i = 0; i < files.length; i++) {
f7116eb3f791 rlgwebd.js: refactor some game-starting code.
John "Elwin" Edwards <elwin@sdf.org>
parents: 39
diff changeset
428 if (files[i].match(fre)) {
42
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
429 args.unshift(null, files[i]);
40
f7116eb3f791 rlgwebd.js: refactor some game-starting code.
John "Elwin" Edwards <elwin@sdf.org>
parents: 39
diff changeset
430 callback.apply(null, args);
f7116eb3f791 rlgwebd.js: refactor some game-starting code.
John "Elwin" Edwards <elwin@sdf.org>
parents: 39
diff changeset
431 return;
f7116eb3f791 rlgwebd.js: refactor some game-starting code.
John "Elwin" Edwards <elwin@sdf.org>
parents: 39
diff changeset
432 }
f7116eb3f791 rlgwebd.js: refactor some game-starting code.
John "Elwin" Edwards <elwin@sdf.org>
parents: 39
diff changeset
433 }
42
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
434 args.unshift(null, false);
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
435 callback.apply(null, args);
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
436 });
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
437 }
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
438
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
439 function checksaved(user, game, callback, args) {
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
440 var savedirc = game.uname + "save";
157
e7f809f06c5c Use posix.getpwnam() to look up UID/GID to drop to.
John "Elwin" Edwards
parents: 156
diff changeset
441 var basename = String(pwent.uid) + "-" + user + game.suffix;
42
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
442 var savefile = path.join("/var/games/roguelike", savedirc, basename);
81
e4773ac5d4d5 Switch to node v0.8.
John "Elwin" Edwards <elwin@sdf.org>
parents: 66
diff changeset
443 fs.exists(savefile, function (exist) {
42
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
444 args.unshift(exist);
40
f7116eb3f791 rlgwebd.js: refactor some game-starting code.
John "Elwin" Edwards <elwin@sdf.org>
parents: 39
diff changeset
445 callback.apply(null, args);
f7116eb3f791 rlgwebd.js: refactor some game-starting code.
John "Elwin" Edwards <elwin@sdf.org>
parents: 39
diff changeset
446 });
f7116eb3f791 rlgwebd.js: refactor some game-starting code.
John "Elwin" Edwards <elwin@sdf.org>
parents: 39
diff changeset
447 }
f7116eb3f791 rlgwebd.js: refactor some game-starting code.
John "Elwin" Edwards <elwin@sdf.org>
parents: 39
diff changeset
448
42
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
449 function playerstatus(user, callback) {
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
450 var sdata = {};
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
451 function finishp() {
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
452 for (var gname in games) {
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
453 if (!(gname in sdata))
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
454 return;
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
455 }
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
456 callback(sdata);
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
457 }
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
458 function regsaved(exists, game) {
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
459 if (exists)
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
460 sdata[game.uname] = "s";
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
461 else
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
462 sdata[game.uname] = "0";
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
463 finishp();
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
464 }
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
465 function regactive(err, filename, game) {
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
466 if (!err && filename) {
88
d644e7d46852 RLG-Web: make /pstatus/* differentiate between dgl and RLG-Web games.
John "Elwin" Edwards <elwin@sdf.org>
parents: 87
diff changeset
467 if (filename.match(/^[^:]*:node:/))
d644e7d46852 RLG-Web: make /pstatus/* differentiate between dgl and RLG-Web games.
John "Elwin" Edwards <elwin@sdf.org>
parents: 87
diff changeset
468 sdata[game.uname] = "p";
d644e7d46852 RLG-Web: make /pstatus/* differentiate between dgl and RLG-Web games.
John "Elwin" Edwards <elwin@sdf.org>
parents: 87
diff changeset
469 else
d644e7d46852 RLG-Web: make /pstatus/* differentiate between dgl and RLG-Web games.
John "Elwin" Edwards <elwin@sdf.org>
parents: 87
diff changeset
470 sdata[game.uname] = "d";
42
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
471 finishp();
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
472 }
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
473 else
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
474 checksaved(user, game, regsaved, [game]);
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
475 }
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
476 for (var gname in games) {
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
477 checkprogress(user, games[gname], regactive, [games[gname]]);
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
478 }
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
479 }
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
480
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
481 /* A few utility functions */
160
ed837da65e5f RLGWebD: Clean up code related to session timestamps.
John "Elwin" Edwards
parents: 159
diff changeset
482 function timestamp(dd) {
ed837da65e5f RLGWebD: Clean up code related to session timestamps.
John "Elwin" Edwards
parents: 159
diff changeset
483 if (!(dd instanceof Date)) {
ed837da65e5f RLGWebD: Clean up code related to session timestamps.
John "Elwin" Edwards
parents: 159
diff changeset
484 dd = new Date();
ed837da65e5f RLGWebD: Clean up code related to session timestamps.
John "Elwin" Edwards
parents: 159
diff changeset
485 }
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
486 sd = dd.toISOString();
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
487 sd = sd.slice(0, sd.indexOf("."));
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
488 return sd.replace("T", ".");
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
489 }
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
490
39
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
491 function randkey(words) {
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
492 if (!words || !(words > 0))
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
493 words = 1;
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
494 function rand32() {
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
495 rnum = Math.floor(Math.random() * 65536 * 65536);
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
496 hexstr = rnum.toString(16);
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
497 while (hexstr.length < 8)
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
498 hexstr = "0" + hexstr;
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
499 return hexstr;
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
500 }
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
501 var key = "";
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
502 for (var i = 0; i < words; i++)
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
503 key += rand32();
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
504 return key;
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
505 }
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
506
60
31bb3cf4f25f Make sure watchers start with completely drawn screens.
John "Elwin" Edwards <elwin@sdf.org>
parents: 55
diff changeset
507 /* Compares two buffers, returns true for equality up to index n */
31bb3cf4f25f Make sure watchers start with completely drawn screens.
John "Elwin" Edwards <elwin@sdf.org>
parents: 55
diff changeset
508 function bufncmp(buf1, buf2, n) {
31bb3cf4f25f Make sure watchers start with completely drawn screens.
John "Elwin" Edwards <elwin@sdf.org>
parents: 55
diff changeset
509 if (!Buffer.isBuffer(buf1) || !Buffer.isBuffer(buf2))
31bb3cf4f25f Make sure watchers start with completely drawn screens.
John "Elwin" Edwards <elwin@sdf.org>
parents: 55
diff changeset
510 return false;
31bb3cf4f25f Make sure watchers start with completely drawn screens.
John "Elwin" Edwards <elwin@sdf.org>
parents: 55
diff changeset
511 for (var i = 0; i < n; i++) {
31bb3cf4f25f Make sure watchers start with completely drawn screens.
John "Elwin" Edwards <elwin@sdf.org>
parents: 55
diff changeset
512 if (i == buf1.length && i == buf2.length)
31bb3cf4f25f Make sure watchers start with completely drawn screens.
John "Elwin" Edwards <elwin@sdf.org>
parents: 55
diff changeset
513 return true;
31bb3cf4f25f Make sure watchers start with completely drawn screens.
John "Elwin" Edwards <elwin@sdf.org>
parents: 55
diff changeset
514 if (i == buf1.length || i == buf2.length)
31bb3cf4f25f Make sure watchers start with completely drawn screens.
John "Elwin" Edwards <elwin@sdf.org>
parents: 55
diff changeset
515 return false;
31bb3cf4f25f Make sure watchers start with completely drawn screens.
John "Elwin" Edwards <elwin@sdf.org>
parents: 55
diff changeset
516 if (buf1[i] != buf2[i])
31bb3cf4f25f Make sure watchers start with completely drawn screens.
John "Elwin" Edwards <elwin@sdf.org>
parents: 55
diff changeset
517 return false;
31bb3cf4f25f Make sure watchers start with completely drawn screens.
John "Elwin" Edwards <elwin@sdf.org>
parents: 55
diff changeset
518 }
31bb3cf4f25f Make sure watchers start with completely drawn screens.
John "Elwin" Edwards <elwin@sdf.org>
parents: 55
diff changeset
519 return true;
31bb3cf4f25f Make sure watchers start with completely drawn screens.
John "Elwin" Edwards <elwin@sdf.org>
parents: 55
diff changeset
520 }
31bb3cf4f25f Make sure watchers start with completely drawn screens.
John "Elwin" Edwards <elwin@sdf.org>
parents: 55
diff changeset
521
26
9b58f8d3ea70 rlgwebd.js: add timestamps to log messages.
John "Elwin" Edwards <elwin@sdf.org>
parents: 23
diff changeset
522 function tslog() {
9b58f8d3ea70 rlgwebd.js: add timestamps to log messages.
John "Elwin" Edwards <elwin@sdf.org>
parents: 23
diff changeset
523 arguments[0] = new Date().toISOString() + ": " + String(arguments[0]);
9b58f8d3ea70 rlgwebd.js: add timestamps to log messages.
John "Elwin" Edwards <elwin@sdf.org>
parents: 23
diff changeset
524 console.log.apply(console, arguments);
9b58f8d3ea70 rlgwebd.js: add timestamps to log messages.
John "Elwin" Edwards <elwin@sdf.org>
parents: 23
diff changeset
525 }
9b58f8d3ea70 rlgwebd.js: add timestamps to log messages.
John "Elwin" Edwards <elwin@sdf.org>
parents: 23
diff changeset
526
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
527 /* Returns a list of the cookies in the request, obviously. */
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
528 function getCookies(req) {
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
529 cookies = [];
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
530 if ("cookie" in req.headers) {
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
531 cookstrs = req.headers["cookie"].split("; ");
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
532 for (var i = 0; i < cookstrs.length; i++) {
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
533 eqsign = cookstrs[i].indexOf("=");
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
534 if (eqsign > 0) {
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
535 name = cookstrs[i].slice(0, eqsign).toLowerCase();
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
536 val = cookstrs[i].slice(eqsign + 1);
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
537 cookies[name] = val;
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
538 }
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
539 else if (eqsign < 0)
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
540 cookies[cookstrs[i]] = null;
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
541 }
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
542 }
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
543 return cookies;
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
544 }
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
545
16
ef6127ed6da3 RLGWeb: switch to JSON protocol.
John "Elwin" Edwards <elwin@sdf.org>
parents: 8
diff changeset
546 function getMsg(posttext) {
ef6127ed6da3 RLGWeb: switch to JSON protocol.
John "Elwin" Edwards <elwin@sdf.org>
parents: 8
diff changeset
547 var jsonobj;
ef6127ed6da3 RLGWeb: switch to JSON protocol.
John "Elwin" Edwards <elwin@sdf.org>
parents: 8
diff changeset
548 if (!posttext)
ef6127ed6da3 RLGWeb: switch to JSON protocol.
John "Elwin" Edwards <elwin@sdf.org>
parents: 8
diff changeset
549 return {};
ef6127ed6da3 RLGWeb: switch to JSON protocol.
John "Elwin" Edwards <elwin@sdf.org>
parents: 8
diff changeset
550 try {
ef6127ed6da3 RLGWeb: switch to JSON protocol.
John "Elwin" Edwards <elwin@sdf.org>
parents: 8
diff changeset
551 jsonobj = JSON.parse(posttext);
ef6127ed6da3 RLGWeb: switch to JSON protocol.
John "Elwin" Edwards <elwin@sdf.org>
parents: 8
diff changeset
552 }
ef6127ed6da3 RLGWeb: switch to JSON protocol.
John "Elwin" Edwards <elwin@sdf.org>
parents: 8
diff changeset
553 catch (e) {
ef6127ed6da3 RLGWeb: switch to JSON protocol.
John "Elwin" Edwards <elwin@sdf.org>
parents: 8
diff changeset
554 if (e instanceof SyntaxError)
ef6127ed6da3 RLGWeb: switch to JSON protocol.
John "Elwin" Edwards <elwin@sdf.org>
parents: 8
diff changeset
555 return {};
ef6127ed6da3 RLGWeb: switch to JSON protocol.
John "Elwin" Edwards <elwin@sdf.org>
parents: 8
diff changeset
556 }
ef6127ed6da3 RLGWeb: switch to JSON protocol.
John "Elwin" Edwards <elwin@sdf.org>
parents: 8
diff changeset
557 if (typeof(jsonobj) != "object")
ef6127ed6da3 RLGWeb: switch to JSON protocol.
John "Elwin" Edwards <elwin@sdf.org>
parents: 8
diff changeset
558 return {};
ef6127ed6da3 RLGWeb: switch to JSON protocol.
John "Elwin" Edwards <elwin@sdf.org>
parents: 8
diff changeset
559 return jsonobj;
ef6127ed6da3 RLGWeb: switch to JSON protocol.
John "Elwin" Edwards <elwin@sdf.org>
parents: 8
diff changeset
560 }
ef6127ed6da3 RLGWeb: switch to JSON protocol.
John "Elwin" Edwards <elwin@sdf.org>
parents: 8
diff changeset
561
107
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
562 function getMsgWS(msgObj) {
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
563 if (msgObj.type != "utf8")
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
564 return {};
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
565 return getMsg(msgObj.utf8Data);
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
566 }
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
567
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
568 function login(req, res, formdata) {
27
83f9a799a374 rlgwebd.js: read commands from the console
John "Elwin" Edwards <elwin@sdf.org>
parents: 26
diff changeset
569 if (!allowlogin) {
55
96815eae4ebe RLG-Web: make multiple watchers possible.
John "Elwin" Edwards <elwin@sdf.org>
parents: 49
diff changeset
570 sendError(res, 6, null, false);
27
83f9a799a374 rlgwebd.js: read commands from the console
John "Elwin" Edwards <elwin@sdf.org>
parents: 26
diff changeset
571 return;
83f9a799a374 rlgwebd.js: read commands from the console
John "Elwin" Edwards <elwin@sdf.org>
parents: 26
diff changeset
572 }
39
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
573 if (!("name" in formdata)) {
55
96815eae4ebe RLG-Web: make multiple watchers possible.
John "Elwin" Edwards <elwin@sdf.org>
parents: 49
diff changeset
574 sendError(res, 2, "Username not given.", false);
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
575 return;
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
576 }
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
577 else if (!("pw" in formdata)) {
55
96815eae4ebe RLG-Web: make multiple watchers possible.
John "Elwin" Edwards <elwin@sdf.org>
parents: 49
diff changeset
578 sendError(res, 2, "Password not given.", false);
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
579 return;
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
580 }
39
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
581 var username = String(formdata["name"]);
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
582 var password = String(formdata["pw"]);
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
583 function checkit(code, signal) {
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
584 /* Checks the exit status, see sqlickrypt.c for details. */
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
585 if (code != 0) {
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
586 sendError(res, 3);
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
587 if (code == 1)
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
588 tslog("Password check failed for user %s", username);
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
589 else if (code == 2)
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
590 tslog("Attempted login by nonexistent user %s", username);
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
591 else
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
592 tslog("Login failed: sqlickrypt error %d", code);
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
593 return;
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
594 }
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
595 var lkey = randkey(2);
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
596 while (lkey in logins)
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
597 lkey = randkey(2);
160
ed837da65e5f RLGWebD: Clean up code related to session timestamps.
John "Elwin" Edwards
parents: 159
diff changeset
598 logins[lkey] = {"name": username, "ts": new Date()};
39
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
599 res.writeHead(200, {'Content-Type': 'application/json'});
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
600 var reply = {"t": "l", "k": lkey, "u": username};
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
601 res.write(JSON.stringify(reply));
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
602 res.end();
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
603 tslog("%s has logged in (key %s)", username, lkey);
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
604 return;
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
605 }
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
606 /* Launch the sqlickrypt utility to check the password. */
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
607 var pwchecker = child_process.spawn("/bin/sqlickrypt", ["check"]);
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
608 pwchecker.on("exit", checkit);
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
609 pwchecker.stdin.end(username + '\n' + password + '\n', "utf8");
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
610 return;
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
611 }
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
612
20
5f785e1d5cca RLG-Web: set up user directories on registration
John "Elwin" Edwards <elwin@sdf.org>
parents: 19
diff changeset
613 /* Sets things up for a new user, like dgamelaunch's commands[register] */
5f785e1d5cca RLG-Web: set up user directories on registration
John "Elwin" Edwards <elwin@sdf.org>
parents: 19
diff changeset
614 function regsetup(username) {
5f785e1d5cca RLG-Web: set up user directories on registration
John "Elwin" Edwards <elwin@sdf.org>
parents: 19
diff changeset
615 function regsetup_l2(err) {
5f785e1d5cca RLG-Web: set up user directories on registration
John "Elwin" Edwards <elwin@sdf.org>
parents: 19
diff changeset
616 for (var g in games) {
5f785e1d5cca RLG-Web: set up user directories on registration
John "Elwin" Edwards <elwin@sdf.org>
parents: 19
diff changeset
617 fs.mkdir(path.join("/dgldir/ttyrec", username, games[g].uname), 0755);
5f785e1d5cca RLG-Web: set up user directories on registration
John "Elwin" Edwards <elwin@sdf.org>
parents: 19
diff changeset
618 }
5f785e1d5cca RLG-Web: set up user directories on registration
John "Elwin" Edwards <elwin@sdf.org>
parents: 19
diff changeset
619 }
5f785e1d5cca RLG-Web: set up user directories on registration
John "Elwin" Edwards <elwin@sdf.org>
parents: 19
diff changeset
620 fs.mkdir(path.join("/dgldir/userdata", username), 0755);
5f785e1d5cca RLG-Web: set up user directories on registration
John "Elwin" Edwards <elwin@sdf.org>
parents: 19
diff changeset
621 fs.mkdir(path.join("/dgldir/ttyrec/", username), 0755, regsetup_l2);
5f785e1d5cca RLG-Web: set up user directories on registration
John "Elwin" Edwards <elwin@sdf.org>
parents: 19
diff changeset
622 }
5f785e1d5cca RLG-Web: set up user directories on registration
John "Elwin" Edwards <elwin@sdf.org>
parents: 19
diff changeset
623
19
188bbd857124 RLG-Web: add user registration
John "Elwin" Edwards <elwin@sdf.org>
parents: 17
diff changeset
624 function register(req, res, formdata) {
188bbd857124 RLG-Web: add user registration
John "Elwin" Edwards <elwin@sdf.org>
parents: 17
diff changeset
625 var uname, passwd, email;
188bbd857124 RLG-Web: add user registration
John "Elwin" Edwards <elwin@sdf.org>
parents: 17
diff changeset
626 if (typeof (formdata.name) != "string" || formdata.name === "") {
188bbd857124 RLG-Web: add user registration
John "Elwin" Edwards <elwin@sdf.org>
parents: 17
diff changeset
627 sendError(res, 2, "No name given.");
188bbd857124 RLG-Web: add user registration
John "Elwin" Edwards <elwin@sdf.org>
parents: 17
diff changeset
628 return;
188bbd857124 RLG-Web: add user registration
John "Elwin" Edwards <elwin@sdf.org>
parents: 17
diff changeset
629 }
188bbd857124 RLG-Web: add user registration
John "Elwin" Edwards <elwin@sdf.org>
parents: 17
diff changeset
630 else
188bbd857124 RLG-Web: add user registration
John "Elwin" Edwards <elwin@sdf.org>
parents: 17
diff changeset
631 uname = formdata["name"];
188bbd857124 RLG-Web: add user registration
John "Elwin" Edwards <elwin@sdf.org>
parents: 17
diff changeset
632 if (typeof (formdata.pw) != "string" || formdata.pw === "") {
188bbd857124 RLG-Web: add user registration
John "Elwin" Edwards <elwin@sdf.org>
parents: 17
diff changeset
633 sendError(res, 2, "No password given.");
188bbd857124 RLG-Web: add user registration
John "Elwin" Edwards <elwin@sdf.org>
parents: 17
diff changeset
634 return;
188bbd857124 RLG-Web: add user registration
John "Elwin" Edwards <elwin@sdf.org>
parents: 17
diff changeset
635 }
188bbd857124 RLG-Web: add user registration
John "Elwin" Edwards <elwin@sdf.org>
parents: 17
diff changeset
636 else
188bbd857124 RLG-Web: add user registration
John "Elwin" Edwards <elwin@sdf.org>
parents: 17
diff changeset
637 passwd = formdata["pw"];
188bbd857124 RLG-Web: add user registration
John "Elwin" Edwards <elwin@sdf.org>
parents: 17
diff changeset
638 if (typeof (formdata.email) != "string" || formdata.email === "") {
188bbd857124 RLG-Web: add user registration
John "Elwin" Edwards <elwin@sdf.org>
parents: 17
diff changeset
639 /* E-mail is optional */
188bbd857124 RLG-Web: add user registration
John "Elwin" Edwards <elwin@sdf.org>
parents: 17
diff changeset
640 email = "nobody@nowhere.not";
188bbd857124 RLG-Web: add user registration
John "Elwin" Edwards <elwin@sdf.org>
parents: 17
diff changeset
641 }
188bbd857124 RLG-Web: add user registration
John "Elwin" Edwards <elwin@sdf.org>
parents: 17
diff changeset
642 else
188bbd857124 RLG-Web: add user registration
John "Elwin" Edwards <elwin@sdf.org>
parents: 17
diff changeset
643 email = formdata["email"];
188bbd857124 RLG-Web: add user registration
John "Elwin" Edwards <elwin@sdf.org>
parents: 17
diff changeset
644 function checkreg(code, signal) {
39
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
645 if (code === 0) {
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
646 var lkey = randkey(2);
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
647 while (lkey in logins)
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
648 lkey = randkey(2);
160
ed837da65e5f RLGWebD: Clean up code related to session timestamps.
John "Elwin" Edwards
parents: 159
diff changeset
649 logins[lkey] = {"name": uname, "ts": new Date()};
39
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
650 var reply = {"t": "r", "k": lkey, "u": uname};
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
651 res.writeHead(200, {'Content-Type': 'application/json'});
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
652 res.write(JSON.stringify(reply));
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
653 res.end();
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
654 tslog("Added new user: %s", uname);
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
655 regsetup(uname);
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
656 }
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
657 else if (code == 4) {
19
188bbd857124 RLG-Web: add user registration
John "Elwin" Edwards <elwin@sdf.org>
parents: 17
diff changeset
658 sendError(res, 2, "Invalid characters in name or email.");
26
9b58f8d3ea70 rlgwebd.js: add timestamps to log messages.
John "Elwin" Edwards <elwin@sdf.org>
parents: 23
diff changeset
659 tslog("Attempted registration: %s %s", uname, email);
20
5f785e1d5cca RLG-Web: set up user directories on registration
John "Elwin" Edwards <elwin@sdf.org>
parents: 19
diff changeset
660 }
5f785e1d5cca RLG-Web: set up user directories on registration
John "Elwin" Edwards <elwin@sdf.org>
parents: 19
diff changeset
661 else if (code == 1) {
19
188bbd857124 RLG-Web: add user registration
John "Elwin" Edwards <elwin@sdf.org>
parents: 17
diff changeset
662 sendError(res, 2, "Username " + uname + " is already being used.");
26
9b58f8d3ea70 rlgwebd.js: add timestamps to log messages.
John "Elwin" Edwards <elwin@sdf.org>
parents: 23
diff changeset
663 tslog("Attempted duplicate registration: %s", uname);
20
5f785e1d5cca RLG-Web: set up user directories on registration
John "Elwin" Edwards <elwin@sdf.org>
parents: 19
diff changeset
664 }
39
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
665 else {
19
188bbd857124 RLG-Web: add user registration
John "Elwin" Edwards <elwin@sdf.org>
parents: 17
diff changeset
666 sendError(res, 0, null);
26
9b58f8d3ea70 rlgwebd.js: add timestamps to log messages.
John "Elwin" Edwards <elwin@sdf.org>
parents: 23
diff changeset
667 tslog("sqlickrypt register failed with code %d", code);
20
5f785e1d5cca RLG-Web: set up user directories on registration
John "Elwin" Edwards <elwin@sdf.org>
parents: 19
diff changeset
668 }
19
188bbd857124 RLG-Web: add user registration
John "Elwin" Edwards <elwin@sdf.org>
parents: 17
diff changeset
669 }
188bbd857124 RLG-Web: add user registration
John "Elwin" Edwards <elwin@sdf.org>
parents: 17
diff changeset
670 var child_adder = child_process.spawn("/bin/sqlickrypt", ["register"]);
188bbd857124 RLG-Web: add user registration
John "Elwin" Edwards <elwin@sdf.org>
parents: 17
diff changeset
671 child_adder.on("exit", checkreg);
188bbd857124 RLG-Web: add user registration
John "Elwin" Edwards <elwin@sdf.org>
parents: 17
diff changeset
672 child_adder.stdin.end(uname + '\n' + passwd + '\n' + email + '\n', "utf8");
188bbd857124 RLG-Web: add user registration
John "Elwin" Edwards <elwin@sdf.org>
parents: 17
diff changeset
673 return;
188bbd857124 RLG-Web: add user registration
John "Elwin" Edwards <elwin@sdf.org>
parents: 17
diff changeset
674 }
188bbd857124 RLG-Web: add user registration
John "Elwin" Edwards <elwin@sdf.org>
parents: 17
diff changeset
675
111
f56fdfeed01a Replace taking over games with forced saves.
John "Elwin" Edwards <elwin@sdf.org>
parents: 110
diff changeset
676 /* Stops a running game if the request has the proper key. */
f56fdfeed01a Replace taking over games with forced saves.
John "Elwin" Edwards <elwin@sdf.org>
parents: 110
diff changeset
677 function stopgame(res, formdata) {
f56fdfeed01a Replace taking over games with forced saves.
John "Elwin" Edwards <elwin@sdf.org>
parents: 110
diff changeset
678 if (!("key" in formdata) || !(formdata["key"] in logins)) {
f56fdfeed01a Replace taking over games with forced saves.
John "Elwin" Edwards <elwin@sdf.org>
parents: 110
diff changeset
679 sendError(res, 1);
f56fdfeed01a Replace taking over games with forced saves.
John "Elwin" Edwards <elwin@sdf.org>
parents: 110
diff changeset
680 return;
f56fdfeed01a Replace taking over games with forced saves.
John "Elwin" Edwards <elwin@sdf.org>
parents: 110
diff changeset
681 }
f56fdfeed01a Replace taking over games with forced saves.
John "Elwin" Edwards <elwin@sdf.org>
parents: 110
diff changeset
682 var pname = logins[formdata["key"]].name;
f56fdfeed01a Replace taking over games with forced saves.
John "Elwin" Edwards <elwin@sdf.org>
parents: 110
diff changeset
683 if (!("g" in formdata) || !(formdata["g"] in games)) {
f56fdfeed01a Replace taking over games with forced saves.
John "Elwin" Edwards <elwin@sdf.org>
parents: 110
diff changeset
684 sendError(res, 2, "No such game.");
f56fdfeed01a Replace taking over games with forced saves.
John "Elwin" Edwards <elwin@sdf.org>
parents: 110
diff changeset
685 return;
f56fdfeed01a Replace taking over games with forced saves.
John "Elwin" Edwards <elwin@sdf.org>
parents: 110
diff changeset
686 }
f56fdfeed01a Replace taking over games with forced saves.
John "Elwin" Edwards <elwin@sdf.org>
parents: 110
diff changeset
687 var gname = formdata["g"];
f56fdfeed01a Replace taking over games with forced saves.
John "Elwin" Edwards <elwin@sdf.org>
parents: 110
diff changeset
688 function checkback(err, fname) {
f56fdfeed01a Replace taking over games with forced saves.
John "Elwin" Edwards <elwin@sdf.org>
parents: 110
diff changeset
689 if (!fname) {
f56fdfeed01a Replace taking over games with forced saves.
John "Elwin" Edwards <elwin@sdf.org>
parents: 110
diff changeset
690 sendError(res, 7);
f56fdfeed01a Replace taking over games with forced saves.
John "Elwin" Edwards <elwin@sdf.org>
parents: 110
diff changeset
691 return;
f56fdfeed01a Replace taking over games with forced saves.
John "Elwin" Edwards <elwin@sdf.org>
parents: 110
diff changeset
692 }
142
c4304f08e35b RLGWebD: inprogress dirs have moved
John "Elwin" Edwards
parents: 141
diff changeset
693 var fullfile = path.join("/dgldir/inprogress", gname, fname);
111
f56fdfeed01a Replace taking over games with forced saves.
John "Elwin" Edwards <elwin@sdf.org>
parents: 110
diff changeset
694 fs.readFile(fullfile, "utf8", function(err, fdata) {
f56fdfeed01a Replace taking over games with forced saves.
John "Elwin" Edwards <elwin@sdf.org>
parents: 110
diff changeset
695 if (err) {
f56fdfeed01a Replace taking over games with forced saves.
John "Elwin" Edwards <elwin@sdf.org>
parents: 110
diff changeset
696 sendError(res, 7);
f56fdfeed01a Replace taking over games with forced saves.
John "Elwin" Edwards <elwin@sdf.org>
parents: 110
diff changeset
697 return;
f56fdfeed01a Replace taking over games with forced saves.
John "Elwin" Edwards <elwin@sdf.org>
parents: 110
diff changeset
698 }
f56fdfeed01a Replace taking over games with forced saves.
John "Elwin" Edwards <elwin@sdf.org>
parents: 110
diff changeset
699 var pid = parseInt(fdata.split('\n')[0], 10);
139
dcd07c1d846a Replace the daemon module with posix.
John "Elwin" Edwards
parents: 132
diff changeset
700 try {
dcd07c1d846a Replace the daemon module with posix.
John "Elwin" Edwards
parents: 132
diff changeset
701 process.kill(pid, 'SIGHUP');
dcd07c1d846a Replace the daemon module with posix.
John "Elwin" Edwards
parents: 132
diff changeset
702 }
dcd07c1d846a Replace the daemon module with posix.
John "Elwin" Edwards
parents: 132
diff changeset
703 catch (err) {
dcd07c1d846a Replace the daemon module with posix.
John "Elwin" Edwards
parents: 132
diff changeset
704 /* If the PID is invalid, the lockfile is stale. */
dcd07c1d846a Replace the daemon module with posix.
John "Elwin" Edwards
parents: 132
diff changeset
705 if (err.code == "ESRCH") {
dcd07c1d846a Replace the daemon module with posix.
John "Elwin" Edwards
parents: 132
diff changeset
706 var nodere = RegExp("^" + pname + ":node:");
dcd07c1d846a Replace the daemon module with posix.
John "Elwin" Edwards
parents: 132
diff changeset
707 if (fname.match(nodere)) {
dcd07c1d846a Replace the daemon module with posix.
John "Elwin" Edwards
parents: 132
diff changeset
708 fs.unlink(fullfile);
dcd07c1d846a Replace the daemon module with posix.
John "Elwin" Edwards
parents: 132
diff changeset
709 }
dcd07c1d846a Replace the daemon module with posix.
John "Elwin" Edwards
parents: 132
diff changeset
710 }
dcd07c1d846a Replace the daemon module with posix.
John "Elwin" Edwards
parents: 132
diff changeset
711 }
111
f56fdfeed01a Replace taking over games with forced saves.
John "Elwin" Edwards <elwin@sdf.org>
parents: 110
diff changeset
712 /* The response doesn't mean that the game is gone. The only way
f56fdfeed01a Replace taking over games with forced saves.
John "Elwin" Edwards <elwin@sdf.org>
parents: 110
diff changeset
713 * to make sure a dgamelaunch-supervised game is over would be to
f56fdfeed01a Replace taking over games with forced saves.
John "Elwin" Edwards <elwin@sdf.org>
parents: 110
diff changeset
714 * poll fname until it disappears. */
f56fdfeed01a Replace taking over games with forced saves.
John "Elwin" Edwards <elwin@sdf.org>
parents: 110
diff changeset
715 res.writeHead(200, {'Content-Type': 'application/json'});
f56fdfeed01a Replace taking over games with forced saves.
John "Elwin" Edwards <elwin@sdf.org>
parents: 110
diff changeset
716 res.write(JSON.stringify({"t": "q"}));
f56fdfeed01a Replace taking over games with forced saves.
John "Elwin" Edwards <elwin@sdf.org>
parents: 110
diff changeset
717 res.end();
f56fdfeed01a Replace taking over games with forced saves.
John "Elwin" Edwards <elwin@sdf.org>
parents: 110
diff changeset
718 });
f56fdfeed01a Replace taking over games with forced saves.
John "Elwin" Edwards <elwin@sdf.org>
parents: 110
diff changeset
719 }
f56fdfeed01a Replace taking over games with forced saves.
John "Elwin" Edwards <elwin@sdf.org>
parents: 110
diff changeset
720 checkprogress(pname, games[gname], checkback, []);
f56fdfeed01a Replace taking over games with forced saves.
John "Elwin" Edwards <elwin@sdf.org>
parents: 110
diff changeset
721 }
f56fdfeed01a Replace taking over games with forced saves.
John "Elwin" Edwards <elwin@sdf.org>
parents: 110
diff changeset
722
155
245a2959f504 Begin support for watching dgamelaunch games.
John "Elwin" Edwards
parents: 148
diff changeset
723 function startProgressWatcher() {
245a2959f504 Begin support for watching dgamelaunch games.
John "Elwin" Edwards
parents: 148
diff changeset
724 var watchdirs = [];
245a2959f504 Begin support for watching dgamelaunch games.
John "Elwin" Edwards
parents: 148
diff changeset
725 for (var gname in games) {
245a2959f504 Begin support for watching dgamelaunch games.
John "Elwin" Edwards
parents: 148
diff changeset
726 watchdirs.push(path.join("/dgldir/inprogress", gname));
245a2959f504 Begin support for watching dgamelaunch games.
John "Elwin" Edwards
parents: 148
diff changeset
727 }
167
fba1b34e7554 Rename watcher to dglwatcher.
John "Elwin" Edwards
parents: 165
diff changeset
728 var subproc = child_process.spawn("/bin/dglwatcher", watchdirs);
155
245a2959f504 Begin support for watching dgamelaunch games.
John "Elwin" Edwards
parents: 148
diff changeset
729 subproc.stdout.setEncoding('utf8');
245a2959f504 Begin support for watching dgamelaunch games.
John "Elwin" Edwards
parents: 148
diff changeset
730 subproc.stdout.on('data', function (chunk) {
245a2959f504 Begin support for watching dgamelaunch games.
John "Elwin" Edwards
parents: 148
diff changeset
731 var fname = chunk.slice(2, -1);
245a2959f504 Begin support for watching dgamelaunch games.
John "Elwin" Edwards
parents: 148
diff changeset
732 var filere = /.*\/([^\/]*)\/([^\/:]*):(node:)?(.*)/;
245a2959f504 Begin support for watching dgamelaunch games.
John "Elwin" Edwards
parents: 148
diff changeset
733 var matchresult = fname.match(filere);
245a2959f504 Begin support for watching dgamelaunch games.
John "Elwin" Edwards
parents: 148
diff changeset
734 if (!matchresult || matchresult[3])
245a2959f504 Begin support for watching dgamelaunch games.
John "Elwin" Edwards
parents: 148
diff changeset
735 return;
156
127f9e256d02 Keep a list of dgamelaunch games and put it in the /status message.
John "Elwin" Edwards
parents: 155
diff changeset
736 var gname = matchresult[1];
127f9e256d02 Keep a list of dgamelaunch games and put it in the /status message.
John "Elwin" Edwards
parents: 155
diff changeset
737 var pname = matchresult[2];
127f9e256d02 Keep a list of dgamelaunch games and put it in the /status message.
John "Elwin" Edwards
parents: 155
diff changeset
738 var tag = gname + "/" + pname;
155
245a2959f504 Begin support for watching dgamelaunch games.
John "Elwin" Edwards
parents: 148
diff changeset
739 if (chunk[0] == "E") {
245a2959f504 Begin support for watching dgamelaunch games.
John "Elwin" Edwards
parents: 148
diff changeset
740 tslog("DGL: %s is playing %s: %s", pname, gname, fname)
164
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
741 dglgames[tag] = new DglSession(fname);
155
245a2959f504 Begin support for watching dgamelaunch games.
John "Elwin" Edwards
parents: 148
diff changeset
742 }
245a2959f504 Begin support for watching dgamelaunch games.
John "Elwin" Edwards
parents: 148
diff changeset
743 else if (chunk[0] == "C") {
245a2959f504 Begin support for watching dgamelaunch games.
John "Elwin" Edwards
parents: 148
diff changeset
744 tslog("DGL: %s started playing %s: %s", pname, gname, fname)
164
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
745 dglgames[tag] = new DglSession(fname);
155
245a2959f504 Begin support for watching dgamelaunch games.
John "Elwin" Edwards
parents: 148
diff changeset
746 }
245a2959f504 Begin support for watching dgamelaunch games.
John "Elwin" Edwards
parents: 148
diff changeset
747 else if (chunk[0] == "D") {
245a2959f504 Begin support for watching dgamelaunch games.
John "Elwin" Edwards
parents: 148
diff changeset
748 tslog("DGL: %s finished playing %s: %s", pname, gname, fname)
164
3a97e4ee50f0 rlgwebd.js: read ttyrecs created by dgamelaunch.
John "Elwin" Edwards
parents: 163
diff changeset
749 dglgames[tag].close();
156
127f9e256d02 Keep a list of dgamelaunch games and put it in the /status message.
John "Elwin" Edwards
parents: 155
diff changeset
750 delete dglgames[tag];
155
245a2959f504 Begin support for watching dgamelaunch games.
John "Elwin" Edwards
parents: 148
diff changeset
751 }
245a2959f504 Begin support for watching dgamelaunch games.
John "Elwin" Edwards
parents: 148
diff changeset
752 else {
245a2959f504 Begin support for watching dgamelaunch games.
John "Elwin" Edwards
parents: 148
diff changeset
753 tslog("Watcher says: %s", chunk)
245a2959f504 Begin support for watching dgamelaunch games.
John "Elwin" Edwards
parents: 148
diff changeset
754 }
245a2959f504 Begin support for watching dgamelaunch games.
John "Elwin" Edwards
parents: 148
diff changeset
755 });
245a2959f504 Begin support for watching dgamelaunch games.
John "Elwin" Edwards
parents: 148
diff changeset
756 subproc.stdout.resume();
245a2959f504 Begin support for watching dgamelaunch games.
John "Elwin" Edwards
parents: 148
diff changeset
757 return subproc;
245a2959f504 Begin support for watching dgamelaunch games.
John "Elwin" Edwards
parents: 148
diff changeset
758 }
245a2959f504 Begin support for watching dgamelaunch games.
John "Elwin" Edwards
parents: 148
diff changeset
759
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
760 function serveStatic(req, res, fname) {
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
761 var nname = path.normalize(fname);
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
762 if (nname == "" || nname == "/")
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
763 nname = "index.html";
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
764 if (nname.match(/\/$/))
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
765 path.join(nname, "index.html"); /* it was a directory */
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
766 var realname = path.join(serveStaticRoot, nname);
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
767 var extension = path.extname(realname);
81
e4773ac5d4d5 Switch to node v0.8.
John "Elwin" Edwards <elwin@sdf.org>
parents: 66
diff changeset
768 fs.exists(realname, function (exists) {
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
769 var resheaders = {};
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
770 if (!exists || !extension || extension == ".html")
31
7dd6becf9ce9 rlgwebd.js: improve MIME types.
John "Elwin" Edwards <elwin@sdf.org>
parents: 30
diff changeset
771 resheaders["Content-Type"] = "text/html; charset=utf-8";
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
772 else if (extension == ".png")
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
773 resheaders["Content-Type"] = "image/png";
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
774 else if (extension == ".css")
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
775 resheaders["Content-Type"] = "text/css";
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
776 else if (extension == ".js")
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
777 resheaders["Content-Type"] = "text/javascript";
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
778 else if (extension == ".svg")
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
779 resheaders["Content-Type"] = "image/svg+xml";
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
780 else
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
781 resheaders["Content-Type"] = "application/octet-stream";
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
782 if (exists) {
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
783 fs.readFile(realname, function (error, data) {
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
784 if (error) {
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
785 res.writeHead(500, {});
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
786 res.end();
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
787 }
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
788 else {
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
789 res.writeHead(200, resheaders);
34
57f4b36ef06b rlgwebd.js: handle HTTP HEAD properly.
John "Elwin" Edwards <elwin@sdf.org>
parents: 32
diff changeset
790 if (req.method != 'HEAD')
57f4b36ef06b rlgwebd.js: handle HTTP HEAD properly.
John "Elwin" Edwards <elwin@sdf.org>
parents: 32
diff changeset
791 res.write(data);
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
792 res.end();
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
793 }
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
794 });
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
795 }
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
796 else {
125
5ad15380f851 Improve the /uinfo interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 124
diff changeset
797 send404(res, nname, req.method == 'HEAD');
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
798 }
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
799 });
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
800 return;
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
801 }
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
802
160
ed837da65e5f RLGWebD: Clean up code related to session timestamps.
John "Elwin" Edwards
parents: 159
diff changeset
803 /* Currently, this doesn't do anything blocking, but keep the callback */
103
f30495f7ede8 RLG-Web server: refactor statusmsg() to work with WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 102
diff changeset
804 function getStatus(callback) {
66
57bf0dcd080e Display idle time of games in progress.
John "Elwin" Edwards <elwin@sdf.org>
parents: 64
diff changeset
805 var now = new Date();
103
f30495f7ede8 RLG-Web server: refactor statusmsg() to work with WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 102
diff changeset
806 var statusinfo = {"s": allowlogin, "g": []};
158
9961a538c00e rlgwebd.js: get rid of numerical game identifiers.
John "Elwin" Edwards
parents: 157
diff changeset
807 for (var tag in sessions) {
55
96815eae4ebe RLG-Web: make multiple watchers possible.
John "Elwin" Edwards <elwin@sdf.org>
parents: 49
diff changeset
808 var gamedesc = {};
158
9961a538c00e rlgwebd.js: get rid of numerical game identifiers.
John "Elwin" Edwards
parents: 157
diff changeset
809 gamedesc["p"] = sessions[tag].pname;
9961a538c00e rlgwebd.js: get rid of numerical game identifiers.
John "Elwin" Edwards
parents: 157
diff changeset
810 gamedesc["g"] = sessions[tag].game.uname;
160
ed837da65e5f RLGWebD: Clean up code related to session timestamps.
John "Elwin" Edwards
parents: 159
diff changeset
811 gamedesc["i"] = now - sessions[tag].lasttime;
103
f30495f7ede8 RLG-Web server: refactor statusmsg() to work with WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 102
diff changeset
812 statusinfo["g"].push(gamedesc);
32
c75fc4b1d13d rlgwebd.js: add a status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 31
diff changeset
813 }
156
127f9e256d02 Keep a list of dgamelaunch games and put it in the /status message.
John "Elwin" Edwards
parents: 155
diff changeset
814 statusinfo["dgl"] = [];
127f9e256d02 Keep a list of dgamelaunch games and put it in the /status message.
John "Elwin" Edwards
parents: 155
diff changeset
815 for (var tag in dglgames) {
163
0f6da35b27a0 RLGWebD: overhaul the list of current games.
John "Elwin" Edwards
parents: 162
diff changeset
816 var dglinfo = {};
0f6da35b27a0 RLGWebD: overhaul the list of current games.
John "Elwin" Edwards
parents: 162
diff changeset
817 var slash = tag.search('/');
0f6da35b27a0 RLGWebD: overhaul the list of current games.
John "Elwin" Edwards
parents: 162
diff changeset
818 dglinfo["g"] = tag.slice(0, slash);
0f6da35b27a0 RLGWebD: overhaul the list of current games.
John "Elwin" Edwards
parents: 162
diff changeset
819 dglinfo["p"] = tag.slice(slash + 1);
0f6da35b27a0 RLGWebD: overhaul the list of current games.
John "Elwin" Edwards
parents: 162
diff changeset
820 dglinfo["i"] = -1;
0f6da35b27a0 RLGWebD: overhaul the list of current games.
John "Elwin" Edwards
parents: 162
diff changeset
821 statusinfo["dgl"].push(dglinfo);
156
127f9e256d02 Keep a list of dgamelaunch games and put it in the /status message.
John "Elwin" Edwards
parents: 155
diff changeset
822 }
160
ed837da65e5f RLGWebD: Clean up code related to session timestamps.
John "Elwin" Edwards
parents: 159
diff changeset
823 callback(statusinfo);
32
c75fc4b1d13d rlgwebd.js: add a status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 31
diff changeset
824 }
c75fc4b1d13d rlgwebd.js: add a status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 31
diff changeset
825
103
f30495f7ede8 RLG-Web server: refactor statusmsg() to work with WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 102
diff changeset
826 function statusmsg(req, res) {
f30495f7ede8 RLG-Web server: refactor statusmsg() to work with WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 102
diff changeset
827 function respond(info) {
f30495f7ede8 RLG-Web server: refactor statusmsg() to work with WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 102
diff changeset
828 res.writeHead(200, { "Content-Type": "application/json" });
f30495f7ede8 RLG-Web server: refactor statusmsg() to work with WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 102
diff changeset
829 if (req.method != 'HEAD')
f30495f7ede8 RLG-Web server: refactor statusmsg() to work with WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 102
diff changeset
830 res.write(JSON.stringify(info));
f30495f7ede8 RLG-Web server: refactor statusmsg() to work with WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 102
diff changeset
831 res.end();
f30495f7ede8 RLG-Web server: refactor statusmsg() to work with WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 102
diff changeset
832 }
f30495f7ede8 RLG-Web server: refactor statusmsg() to work with WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 102
diff changeset
833 getStatus(respond);
f30495f7ede8 RLG-Web server: refactor statusmsg() to work with WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 102
diff changeset
834 }
f30495f7ede8 RLG-Web server: refactor statusmsg() to work with WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 102
diff changeset
835
42
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
836 function pstatusmsg(req, res) {
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
837 if (req.method == 'HEAD') {
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
838 res.writeHead(200, { "Content-Type": "application/json" });
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
839 res.end();
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
840 return;
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
841 }
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
842 var target = url.parse(req.url).pathname;
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
843 var pmatch = target.match(/^\/pstatus\/(.*)/);
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
844 if (pmatch && pmatch[1])
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
845 var pname = pmatch[1];
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
846 else {
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
847 sendError(res, 2, "No name given.");
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
848 return;
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
849 }
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
850 var reply = {"name": pname};
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
851 playerstatus(pname, function (pdata) {
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
852 reply["stat"] = pdata;
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
853 res.writeHead(200, { "Content-Type": "application/json" });
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
854 res.write(JSON.stringify(reply));
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
855 res.end();
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
856 });
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
857 }
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
858
124
fbeb0bf2b51d Add a user information interface at /uinfo.
John "Elwin" Edwards <elwin@sdf.org>
parents: 121
diff changeset
859 function getuinfo(req, res) {
125
5ad15380f851 Improve the /uinfo interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 124
diff changeset
860 var urlobj = url.parse(req.url, true);
5ad15380f851 Improve the /uinfo interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 124
diff changeset
861 var query = urlobj.query;
124
fbeb0bf2b51d Add a user information interface at /uinfo.
John "Elwin" Edwards <elwin@sdf.org>
parents: 121
diff changeset
862 if (!("key" in query) || !(query["key"] in logins)) {
fbeb0bf2b51d Add a user information interface at /uinfo.
John "Elwin" Edwards <elwin@sdf.org>
parents: 121
diff changeset
863 sendError(res, 1);
fbeb0bf2b51d Add a user information interface at /uinfo.
John "Elwin" Edwards <elwin@sdf.org>
parents: 121
diff changeset
864 return;
fbeb0bf2b51d Add a user information interface at /uinfo.
John "Elwin" Edwards <elwin@sdf.org>
parents: 121
diff changeset
865 }
125
5ad15380f851 Improve the /uinfo interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 124
diff changeset
866 var match = urlobj.pathname.match(/^\/[^\/]*\/(.*)/);
5ad15380f851 Improve the /uinfo interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 124
diff changeset
867 if (!match || !match[1]) {
5ad15380f851 Improve the /uinfo interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 124
diff changeset
868 send404(res, urlobj.pathname, req.method == 'HEAD');
5ad15380f851 Improve the /uinfo interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 124
diff changeset
869 return;
5ad15380f851 Improve the /uinfo interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 124
diff changeset
870 }
5ad15380f851 Improve the /uinfo interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 124
diff changeset
871 var which = match[1];
124
fbeb0bf2b51d Add a user information interface at /uinfo.
John "Elwin" Edwards <elwin@sdf.org>
parents: 121
diff changeset
872 var name = logins[query["key"]].name;
fbeb0bf2b51d Add a user information interface at /uinfo.
John "Elwin" Edwards <elwin@sdf.org>
parents: 121
diff changeset
873 var reply = { "u": name };
fbeb0bf2b51d Add a user information interface at /uinfo.
John "Elwin" Edwards <elwin@sdf.org>
parents: 121
diff changeset
874 function send() {
fbeb0bf2b51d Add a user information interface at /uinfo.
John "Elwin" Edwards <elwin@sdf.org>
parents: 121
diff changeset
875 res.writeHead(200, { "Content-Type": "application/json" });
fbeb0bf2b51d Add a user information interface at /uinfo.
John "Elwin" Edwards <elwin@sdf.org>
parents: 121
diff changeset
876 res.write(JSON.stringify(reply));
fbeb0bf2b51d Add a user information interface at /uinfo.
John "Elwin" Edwards <elwin@sdf.org>
parents: 121
diff changeset
877 res.end();
fbeb0bf2b51d Add a user information interface at /uinfo.
John "Elwin" Edwards <elwin@sdf.org>
parents: 121
diff changeset
878 }
125
5ad15380f851 Improve the /uinfo interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 124
diff changeset
879 if (which == "pw") {
124
fbeb0bf2b51d Add a user information interface at /uinfo.
John "Elwin" Edwards <elwin@sdf.org>
parents: 121
diff changeset
880 /* Don't actually divulge passwords. */
fbeb0bf2b51d Add a user information interface at /uinfo.
John "Elwin" Edwards <elwin@sdf.org>
parents: 121
diff changeset
881 reply["pw"] = "";
125
5ad15380f851 Improve the /uinfo interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 124
diff changeset
882 send();
124
fbeb0bf2b51d Add a user information interface at /uinfo.
John "Elwin" Edwards <elwin@sdf.org>
parents: 121
diff changeset
883 }
125
5ad15380f851 Improve the /uinfo interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 124
diff changeset
884 else if (which == "email") {
124
fbeb0bf2b51d Add a user information interface at /uinfo.
John "Elwin" Edwards <elwin@sdf.org>
parents: 121
diff changeset
885 var address;
fbeb0bf2b51d Add a user information interface at /uinfo.
John "Elwin" Edwards <elwin@sdf.org>
parents: 121
diff changeset
886 function finish(code, signal) {
fbeb0bf2b51d Add a user information interface at /uinfo.
John "Elwin" Edwards <elwin@sdf.org>
parents: 121
diff changeset
887 if (code != 0) {
fbeb0bf2b51d Add a user information interface at /uinfo.
John "Elwin" Edwards <elwin@sdf.org>
parents: 121
diff changeset
888 tslog("sqlickrypt: %d with name %s", code, name);
fbeb0bf2b51d Add a user information interface at /uinfo.
John "Elwin" Edwards <elwin@sdf.org>
parents: 121
diff changeset
889 sendError(res, 2);
fbeb0bf2b51d Add a user information interface at /uinfo.
John "Elwin" Edwards <elwin@sdf.org>
parents: 121
diff changeset
890 }
fbeb0bf2b51d Add a user information interface at /uinfo.
John "Elwin" Edwards <elwin@sdf.org>
parents: 121
diff changeset
891 else {
fbeb0bf2b51d Add a user information interface at /uinfo.
John "Elwin" Edwards <elwin@sdf.org>
parents: 121
diff changeset
892 reply["email"] = address;
fbeb0bf2b51d Add a user information interface at /uinfo.
John "Elwin" Edwards <elwin@sdf.org>
parents: 121
diff changeset
893 send();
fbeb0bf2b51d Add a user information interface at /uinfo.
John "Elwin" Edwards <elwin@sdf.org>
parents: 121
diff changeset
894 }
fbeb0bf2b51d Add a user information interface at /uinfo.
John "Elwin" Edwards <elwin@sdf.org>
parents: 121
diff changeset
895 }
fbeb0bf2b51d Add a user information interface at /uinfo.
John "Elwin" Edwards <elwin@sdf.org>
parents: 121
diff changeset
896 var subproc = child_process.spawn("/bin/sqlickrypt", ["getmail"]);
fbeb0bf2b51d Add a user information interface at /uinfo.
John "Elwin" Edwards <elwin@sdf.org>
parents: 121
diff changeset
897 subproc.stdout.on("data", function (data) {
fbeb0bf2b51d Add a user information interface at /uinfo.
John "Elwin" Edwards <elwin@sdf.org>
parents: 121
diff changeset
898 address = data.toString().replace(/\n/g, "");
fbeb0bf2b51d Add a user information interface at /uinfo.
John "Elwin" Edwards <elwin@sdf.org>
parents: 121
diff changeset
899 });
fbeb0bf2b51d Add a user information interface at /uinfo.
John "Elwin" Edwards <elwin@sdf.org>
parents: 121
diff changeset
900 subproc.on("exit", finish);
fbeb0bf2b51d Add a user information interface at /uinfo.
John "Elwin" Edwards <elwin@sdf.org>
parents: 121
diff changeset
901 subproc.stdin.end(name + '\n', "utf8");
fbeb0bf2b51d Add a user information interface at /uinfo.
John "Elwin" Edwards <elwin@sdf.org>
parents: 121
diff changeset
902 }
125
5ad15380f851 Improve the /uinfo interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 124
diff changeset
903 else {
5ad15380f851 Improve the /uinfo interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 124
diff changeset
904 send404(res, urlobj.pathname, req.method == 'HEAD');
5ad15380f851 Improve the /uinfo interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 124
diff changeset
905 return;
5ad15380f851 Improve the /uinfo interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 124
diff changeset
906 }
124
fbeb0bf2b51d Add a user information interface at /uinfo.
John "Elwin" Edwards <elwin@sdf.org>
parents: 121
diff changeset
907 }
fbeb0bf2b51d Add a user information interface at /uinfo.
John "Elwin" Edwards <elwin@sdf.org>
parents: 121
diff changeset
908
126
3e3824711791 RLG-Web server: allow changing e-mail and password.
John "Elwin" Edwards <elwin@sdf.org>
parents: 125
diff changeset
909 function setuinfo(req, res, postdata) {
3e3824711791 RLG-Web server: allow changing e-mail and password.
John "Elwin" Edwards <elwin@sdf.org>
parents: 125
diff changeset
910 var urlobj = url.parse(req.url, true);
3e3824711791 RLG-Web server: allow changing e-mail and password.
John "Elwin" Edwards <elwin@sdf.org>
parents: 125
diff changeset
911 var query = urlobj.query;
3e3824711791 RLG-Web server: allow changing e-mail and password.
John "Elwin" Edwards <elwin@sdf.org>
parents: 125
diff changeset
912 if (!("key" in query) || !(query["key"] in logins)) {
3e3824711791 RLG-Web server: allow changing e-mail and password.
John "Elwin" Edwards <elwin@sdf.org>
parents: 125
diff changeset
913 sendError(res, 1);
3e3824711791 RLG-Web server: allow changing e-mail and password.
John "Elwin" Edwards <elwin@sdf.org>
parents: 125
diff changeset
914 return;
3e3824711791 RLG-Web server: allow changing e-mail and password.
John "Elwin" Edwards <elwin@sdf.org>
parents: 125
diff changeset
915 }
3e3824711791 RLG-Web server: allow changing e-mail and password.
John "Elwin" Edwards <elwin@sdf.org>
parents: 125
diff changeset
916 var name = logins[query["key"]].name;
3e3824711791 RLG-Web server: allow changing e-mail and password.
John "Elwin" Edwards <elwin@sdf.org>
parents: 125
diff changeset
917 var match = urlobj.pathname.match(/^\/[^\/]*\/(.*)/);
3e3824711791 RLG-Web server: allow changing e-mail and password.
John "Elwin" Edwards <elwin@sdf.org>
parents: 125
diff changeset
918 if (!match || !match[1]) {
3e3824711791 RLG-Web server: allow changing e-mail and password.
John "Elwin" Edwards <elwin@sdf.org>
parents: 125
diff changeset
919 send404(res, urlobj.pathname, true);
3e3824711791 RLG-Web server: allow changing e-mail and password.
John "Elwin" Edwards <elwin@sdf.org>
parents: 125
diff changeset
920 return;
3e3824711791 RLG-Web server: allow changing e-mail and password.
John "Elwin" Edwards <elwin@sdf.org>
parents: 125
diff changeset
921 }
3e3824711791 RLG-Web server: allow changing e-mail and password.
John "Elwin" Edwards <elwin@sdf.org>
parents: 125
diff changeset
922 var which = match[1];
3e3824711791 RLG-Web server: allow changing e-mail and password.
John "Elwin" Edwards <elwin@sdf.org>
parents: 125
diff changeset
923 if (!("v" in postdata)) {
3e3824711791 RLG-Web server: allow changing e-mail and password.
John "Elwin" Edwards <elwin@sdf.org>
parents: 125
diff changeset
924 sendError(res, 2, "No value provided");
3e3824711791 RLG-Web server: allow changing e-mail and password.
John "Elwin" Edwards <elwin@sdf.org>
parents: 125
diff changeset
925 return;
3e3824711791 RLG-Web server: allow changing e-mail and password.
John "Elwin" Edwards <elwin@sdf.org>
parents: 125
diff changeset
926 }
3e3824711791 RLG-Web server: allow changing e-mail and password.
John "Elwin" Edwards <elwin@sdf.org>
parents: 125
diff changeset
927 if (which == "email" || which == "pw") {
3e3824711791 RLG-Web server: allow changing e-mail and password.
John "Elwin" Edwards <elwin@sdf.org>
parents: 125
diff changeset
928 var args;
3e3824711791 RLG-Web server: allow changing e-mail and password.
John "Elwin" Edwards <elwin@sdf.org>
parents: 125
diff changeset
929 if (which == "email")
3e3824711791 RLG-Web server: allow changing e-mail and password.
John "Elwin" Edwards <elwin@sdf.org>
parents: 125
diff changeset
930 args = ["setmail"];
3e3824711791 RLG-Web server: allow changing e-mail and password.
John "Elwin" Edwards <elwin@sdf.org>
parents: 125
diff changeset
931 else
3e3824711791 RLG-Web server: allow changing e-mail and password.
John "Elwin" Edwards <elwin@sdf.org>
parents: 125
diff changeset
932 args = ["setpw"];
3e3824711791 RLG-Web server: allow changing e-mail and password.
John "Elwin" Edwards <elwin@sdf.org>
parents: 125
diff changeset
933 var child = child_process.execFile("/bin/sqlickrypt", args,
3e3824711791 RLG-Web server: allow changing e-mail and password.
John "Elwin" Edwards <elwin@sdf.org>
parents: 125
diff changeset
934 function (err, stdout, stderr) {
3e3824711791 RLG-Web server: allow changing e-mail and password.
John "Elwin" Edwards <elwin@sdf.org>
parents: 125
diff changeset
935 if (err) {
3e3824711791 RLG-Web server: allow changing e-mail and password.
John "Elwin" Edwards <elwin@sdf.org>
parents: 125
diff changeset
936 tslog("Could not set %s: sqlickrypt error %d", which, err.code);
3e3824711791 RLG-Web server: allow changing e-mail and password.
John "Elwin" Edwards <elwin@sdf.org>
parents: 125
diff changeset
937 sendError(res, 2);
3e3824711791 RLG-Web server: allow changing e-mail and password.
John "Elwin" Edwards <elwin@sdf.org>
parents: 125
diff changeset
938 }
3e3824711791 RLG-Web server: allow changing e-mail and password.
John "Elwin" Edwards <elwin@sdf.org>
parents: 125
diff changeset
939 else {
3e3824711791 RLG-Web server: allow changing e-mail and password.
John "Elwin" Edwards <elwin@sdf.org>
parents: 125
diff changeset
940 tslog("User %s has changed %s", name, which);
3e3824711791 RLG-Web server: allow changing e-mail and password.
John "Elwin" Edwards <elwin@sdf.org>
parents: 125
diff changeset
941 res.writeHead(200, { "Content-Type": "application/json" });
3e3824711791 RLG-Web server: allow changing e-mail and password.
John "Elwin" Edwards <elwin@sdf.org>
parents: 125
diff changeset
942 res.end(JSON.stringify({"t": "t"}));
3e3824711791 RLG-Web server: allow changing e-mail and password.
John "Elwin" Edwards <elwin@sdf.org>
parents: 125
diff changeset
943 }
3e3824711791 RLG-Web server: allow changing e-mail and password.
John "Elwin" Edwards <elwin@sdf.org>
parents: 125
diff changeset
944 });
3e3824711791 RLG-Web server: allow changing e-mail and password.
John "Elwin" Edwards <elwin@sdf.org>
parents: 125
diff changeset
945 child.stdin.end(name + "\n" + postdata.v + "\n", "utf8");
3e3824711791 RLG-Web server: allow changing e-mail and password.
John "Elwin" Edwards <elwin@sdf.org>
parents: 125
diff changeset
946 }
3e3824711791 RLG-Web server: allow changing e-mail and password.
John "Elwin" Edwards <elwin@sdf.org>
parents: 125
diff changeset
947 else {
3e3824711791 RLG-Web server: allow changing e-mail and password.
John "Elwin" Edwards <elwin@sdf.org>
parents: 125
diff changeset
948 send404(res, urlobj.pathname, true);
3e3824711791 RLG-Web server: allow changing e-mail and password.
John "Elwin" Edwards <elwin@sdf.org>
parents: 125
diff changeset
949 }
3e3824711791 RLG-Web server: allow changing e-mail and password.
John "Elwin" Edwards <elwin@sdf.org>
parents: 125
diff changeset
950 }
3e3824711791 RLG-Web server: allow changing e-mail and password.
John "Elwin" Edwards <elwin@sdf.org>
parents: 125
diff changeset
951
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
952 var errorcodes = [ "Generic Error", "Not logged in", "Invalid data",
27
83f9a799a374 rlgwebd.js: read commands from the console
John "Elwin" Edwards <elwin@sdf.org>
parents: 26
diff changeset
953 "Login failed", "Already playing", "Game launch failed",
39
e8ac0e3d2614 RLG-Web: separate logging in and starting a game.
John "Elwin" Edwards <elwin@sdf.org>
parents: 37
diff changeset
954 "Server shutting down", "Game not in progress" ];
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
955
55
96815eae4ebe RLG-Web: make multiple watchers possible.
John "Elwin" Edwards <elwin@sdf.org>
parents: 49
diff changeset
956 function sendError(res, ecode, msg, box) {
31
7dd6becf9ce9 rlgwebd.js: improve MIME types.
John "Elwin" Edwards <elwin@sdf.org>
parents: 30
diff changeset
957 res.writeHead(200, { "Content-Type": "application/json" });
16
ef6127ed6da3 RLGWeb: switch to JSON protocol.
John "Elwin" Edwards <elwin@sdf.org>
parents: 8
diff changeset
958 var edict = {"t": "E"};
ef6127ed6da3 RLGWeb: switch to JSON protocol.
John "Elwin" Edwards <elwin@sdf.org>
parents: 8
diff changeset
959 if (!(ecode < errorcodes.length && ecode > 0))
ef6127ed6da3 RLGWeb: switch to JSON protocol.
John "Elwin" Edwards <elwin@sdf.org>
parents: 8
diff changeset
960 ecode = 0;
ef6127ed6da3 RLGWeb: switch to JSON protocol.
John "Elwin" Edwards <elwin@sdf.org>
parents: 8
diff changeset
961 edict["c"] = ecode;
ef6127ed6da3 RLGWeb: switch to JSON protocol.
John "Elwin" Edwards <elwin@sdf.org>
parents: 8
diff changeset
962 edict["s"] = errorcodes[ecode];
ef6127ed6da3 RLGWeb: switch to JSON protocol.
John "Elwin" Edwards <elwin@sdf.org>
parents: 8
diff changeset
963 if (msg)
ef6127ed6da3 RLGWeb: switch to JSON protocol.
John "Elwin" Edwards <elwin@sdf.org>
parents: 8
diff changeset
964 edict["s"] += ": " + msg;
55
96815eae4ebe RLG-Web: make multiple watchers possible.
John "Elwin" Edwards <elwin@sdf.org>
parents: 49
diff changeset
965 if (box)
96815eae4ebe RLG-Web: make multiple watchers possible.
John "Elwin" Edwards <elwin@sdf.org>
parents: 49
diff changeset
966 res.write(JSON.stringify([edict]));
96815eae4ebe RLG-Web: make multiple watchers possible.
John "Elwin" Edwards <elwin@sdf.org>
parents: 49
diff changeset
967 else
96815eae4ebe RLG-Web: make multiple watchers possible.
John "Elwin" Edwards <elwin@sdf.org>
parents: 49
diff changeset
968 res.write(JSON.stringify(edict));
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
969 res.end();
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
970 }
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
971
125
5ad15380f851 Improve the /uinfo interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 124
diff changeset
972 function send404(res, path, nopage) {
5ad15380f851 Improve the /uinfo interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 124
diff changeset
973 res.writeHead(404, {"Content-Type": "text/html; charset=utf-8"});
5ad15380f851 Improve the /uinfo interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 124
diff changeset
974 if (!nopage) {
5ad15380f851 Improve the /uinfo interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 124
diff changeset
975 res.write("<html><head><title>" + path + "</title></head>\n<body><h1>"
5ad15380f851 Improve the /uinfo interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 124
diff changeset
976 + path + " Not Found</h1></body></html>\n");
5ad15380f851 Improve the /uinfo interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 124
diff changeset
977 }
5ad15380f851 Improve the /uinfo interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 124
diff changeset
978 res.end();
5ad15380f851 Improve the /uinfo interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 124
diff changeset
979 }
5ad15380f851 Improve the /uinfo interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 124
diff changeset
980
27
83f9a799a374 rlgwebd.js: read commands from the console
John "Elwin" Edwards <elwin@sdf.org>
parents: 26
diff changeset
981 function webHandler(req, res) {
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
982 /* default headers for the response */
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
983 var resheaders = {'Content-Type': 'text/html'};
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
984 /* The request body will be added to this as it arrives. */
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
985 var reqbody = "";
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
986 var formdata;
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
987
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
988 /* Register a listener to get the body. */
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
989 function moredata(chunk) {
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
990 reqbody += chunk;
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
991 }
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
992 req.on('data', moredata);
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
993
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
994 /* This will send the response once the whole request is here. */
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
995 function respond() {
16
ef6127ed6da3 RLGWeb: switch to JSON protocol.
John "Elwin" Edwards <elwin@sdf.org>
parents: 8
diff changeset
996 formdata = getMsg(reqbody);
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
997 var target = url.parse(req.url).pathname;
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
998 /* First figure out if the client is POSTing to a command interface. */
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
999 if (req.method == 'POST') {
159
a613380ffdc2 RLGWebD: excise polling.
John "Elwin" Edwards
parents: 158
diff changeset
1000 if (target == "/login") {
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
1001 login(req, res, formdata);
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
1002 }
19
188bbd857124 RLG-Web: add user registration
John "Elwin" Edwards <elwin@sdf.org>
parents: 17
diff changeset
1003 else if (target == "/addacct") {
188bbd857124 RLG-Web: add user registration
John "Elwin" Edwards <elwin@sdf.org>
parents: 17
diff changeset
1004 register(req, res, formdata);
188bbd857124 RLG-Web: add user registration
John "Elwin" Edwards <elwin@sdf.org>
parents: 17
diff changeset
1005 }
111
f56fdfeed01a Replace taking over games with forced saves.
John "Elwin" Edwards <elwin@sdf.org>
parents: 110
diff changeset
1006 else if (target == "/quit") {
f56fdfeed01a Replace taking over games with forced saves.
John "Elwin" Edwards <elwin@sdf.org>
parents: 110
diff changeset
1007 stopgame(res, formdata);
f56fdfeed01a Replace taking over games with forced saves.
John "Elwin" Edwards <elwin@sdf.org>
parents: 110
diff changeset
1008 }
126
3e3824711791 RLG-Web server: allow changing e-mail and password.
John "Elwin" Edwards <elwin@sdf.org>
parents: 125
diff changeset
1009 else if (target.match(/^\/uinfo\//)) {
3e3824711791 RLG-Web server: allow changing e-mail and password.
John "Elwin" Edwards <elwin@sdf.org>
parents: 125
diff changeset
1010 setuinfo(req, res, formdata);
3e3824711791 RLG-Web server: allow changing e-mail and password.
John "Elwin" Edwards <elwin@sdf.org>
parents: 125
diff changeset
1011 }
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
1012 else {
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
1013 res.writeHead(405, resheaders);
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
1014 res.end();
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
1015 }
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
1016 }
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
1017 else if (req.method == 'GET' || req.method == 'HEAD') {
159
a613380ffdc2 RLGWebD: excise polling.
John "Elwin" Edwards
parents: 158
diff changeset
1018 if (target == '/status') {
32
c75fc4b1d13d rlgwebd.js: add a status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 31
diff changeset
1019 statusmsg(req, res);
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
1020 }
125
5ad15380f851 Improve the /uinfo interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 124
diff changeset
1021 else if (target.match(/^\/uinfo\//)) {
124
fbeb0bf2b51d Add a user information interface at /uinfo.
John "Elwin" Edwards <elwin@sdf.org>
parents: 121
diff changeset
1022 getuinfo(req, res);
fbeb0bf2b51d Add a user information interface at /uinfo.
John "Elwin" Edwards <elwin@sdf.org>
parents: 121
diff changeset
1023 }
42
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
1024 else if (target.match(/^\/pstatus\//)) {
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
1025 pstatusmsg(req, res);
8f6bc0df58fa rlgwebd.js: add a player status interface.
John "Elwin" Edwards <elwin@sdf.org>
parents: 40
diff changeset
1026 }
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
1027 else /* Go look for it in the filesystem */
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
1028 serveStatic(req, res, target);
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
1029 }
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
1030 else { /* Some other method */
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
1031 res.writeHead(501, resheaders);
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
1032 res.write("<html><head><title>501</title></head>\n<body><h1>501 Not Implemented</h1></body></html>\n");
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
1033 res.end();
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
1034 }
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
1035 return;
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
1036 }
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
1037 req.on('end', respond);
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
1038 }
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
1039
100
3dbfdaf62623 RLG-Web: begin converting to WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 94
diff changeset
1040 function wsHandler(wsRequest) {
158
9961a538c00e rlgwebd.js: get rid of numerical game identifiers.
John "Elwin" Edwards
parents: 157
diff changeset
1041 var watchmatch = wsRequest.resource.match(/^\/watch\/(.*)$/);
107
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
1042 var playmatch = wsRequest.resource.match(/^\/play\//);
104
7d444ba4739e RLG-Web server: send status events over WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 103
diff changeset
1043 if (watchmatch !== null) {
158
9961a538c00e rlgwebd.js: get rid of numerical game identifiers.
John "Elwin" Edwards
parents: 157
diff changeset
1044 if (!(watchmatch[1] in sessions)) {
9961a538c00e rlgwebd.js: get rid of numerical game identifiers.
John "Elwin" Edwards
parents: 157
diff changeset
1045 wsRequest.reject(404, errorcodes[7]);
9961a538c00e rlgwebd.js: get rid of numerical game identifiers.
John "Elwin" Edwards
parents: 157
diff changeset
1046 return;
104
7d444ba4739e RLG-Web server: send status events over WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 103
diff changeset
1047 }
158
9961a538c00e rlgwebd.js: get rid of numerical game identifiers.
John "Elwin" Edwards
parents: 157
diff changeset
1048 var tsession = sessions[watchmatch[1]];
9961a538c00e rlgwebd.js: get rid of numerical game identifiers.
John "Elwin" Edwards
parents: 157
diff changeset
1049 var conn = wsRequest.accept(null, wsRequest.origin);
9961a538c00e rlgwebd.js: get rid of numerical game identifiers.
John "Elwin" Edwards
parents: 157
diff changeset
1050 new wsWatcher(conn, tsession);
162
5a7e7ec136c8 Properly print session tags in the log.
John "Elwin" Edwards
parents: 160
diff changeset
1051 tslog("Game %s is being watched via WebSockets", tsession.tag());
104
7d444ba4739e RLG-Web server: send status events over WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 103
diff changeset
1052 }
107
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
1053 else if (playmatch !== null) {
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
1054 wsStart(wsRequest);
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
1055 }
b64e31c5ec31 RLG-Web server: add playing through WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 104
diff changeset
1056 else if (wsRequest.resourceURL.pathname == "/status") {
100
3dbfdaf62623 RLG-Web: begin converting to WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 94
diff changeset
1057 var conn = wsRequest.accept(null, wsRequest.origin);
104
7d444ba4739e RLG-Web server: send status events over WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 103
diff changeset
1058 var tell = function () {
7d444ba4739e RLG-Web server: send status events over WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 103
diff changeset
1059 getStatus(function (info) {
7d444ba4739e RLG-Web server: send status events over WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 103
diff changeset
1060 info["t"] = "t";
7d444ba4739e RLG-Web server: send status events over WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 103
diff changeset
1061 conn.sendUTF(JSON.stringify(info));
7d444ba4739e RLG-Web server: send status events over WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 103
diff changeset
1062 });
7d444ba4739e RLG-Web server: send status events over WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 103
diff changeset
1063 }
158
9961a538c00e rlgwebd.js: get rid of numerical game identifiers.
John "Elwin" Edwards
parents: 157
diff changeset
1064 var beginH = function (gname, pname) {
9961a538c00e rlgwebd.js: get rid of numerical game identifiers.
John "Elwin" Edwards
parents: 157
diff changeset
1065 conn.sendUTF(JSON.stringify({"t": "b", "p": pname, "g": gname}));
104
7d444ba4739e RLG-Web server: send status events over WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 103
diff changeset
1066 };
7d444ba4739e RLG-Web server: send status events over WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 103
diff changeset
1067 var listH = function (list) {
7d444ba4739e RLG-Web server: send status events over WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 103
diff changeset
1068 conn.sendUTF(JSON.stringify(list));
7d444ba4739e RLG-Web server: send status events over WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 103
diff changeset
1069 };
158
9961a538c00e rlgwebd.js: get rid of numerical game identifiers.
John "Elwin" Edwards
parents: 157
diff changeset
1070 var endH = function (gname, pname) {
9961a538c00e rlgwebd.js: get rid of numerical game identifiers.
John "Elwin" Edwards
parents: 157
diff changeset
1071 conn.sendUTF(JSON.stringify({"t": "e", "p": pname, "g": gname}));
104
7d444ba4739e RLG-Web server: send status events over WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 103
diff changeset
1072 };
7d444ba4739e RLG-Web server: send status events over WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 103
diff changeset
1073 gamemux.on('begin', beginH);
7d444ba4739e RLG-Web server: send status events over WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 103
diff changeset
1074 gamemux.on('list', listH);
7d444ba4739e RLG-Web server: send status events over WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 103
diff changeset
1075 gamemux.on('end', endH);
7d444ba4739e RLG-Web server: send status events over WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 103
diff changeset
1076 conn.on('message', tell);
7d444ba4739e RLG-Web server: send status events over WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 103
diff changeset
1077 conn.on('close', function () {
7d444ba4739e RLG-Web server: send status events over WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 103
diff changeset
1078 gamemux.removeListener('begin', beginH);
7d444ba4739e RLG-Web server: send status events over WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 103
diff changeset
1079 gamemux.removeListener('list', listH);
7d444ba4739e RLG-Web server: send status events over WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 103
diff changeset
1080 gamemux.removeListener('end', endH);
7d444ba4739e RLG-Web server: send status events over WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 103
diff changeset
1081 });
7d444ba4739e RLG-Web server: send status events over WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 103
diff changeset
1082 tell();
100
3dbfdaf62623 RLG-Web: begin converting to WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 94
diff changeset
1083 }
3dbfdaf62623 RLG-Web: begin converting to WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 94
diff changeset
1084 else
104
7d444ba4739e RLG-Web server: send status events over WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 103
diff changeset
1085 wsRequest.reject(404, "No such resource.");
7d444ba4739e RLG-Web server: send status events over WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 103
diff changeset
1086 }
7d444ba4739e RLG-Web server: send status events over WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 103
diff changeset
1087
163
0f6da35b27a0 RLGWebD: overhaul the list of current games.
John "Elwin" Edwards
parents: 162
diff changeset
1088 /* Only games with low idle time are included. Use getStatus() for the
0f6da35b27a0 RLGWebD: overhaul the list of current games.
John "Elwin" Edwards
parents: 162
diff changeset
1089 * complete list. */
104
7d444ba4739e RLG-Web server: send status events over WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 103
diff changeset
1090 function pushStatus() {
163
0f6da35b27a0 RLGWebD: overhaul the list of current games.
John "Elwin" Edwards
parents: 162
diff changeset
1091 var now = new Date();
0f6da35b27a0 RLGWebD: overhaul the list of current games.
John "Elwin" Edwards
parents: 162
diff changeset
1092 var statusinfo = {"t": "p", "s": allowlogin, "g": [], "dgl": []};
0f6da35b27a0 RLGWebD: overhaul the list of current games.
John "Elwin" Edwards
parents: 162
diff changeset
1093 for (var tag in sessions) {
0f6da35b27a0 RLGWebD: overhaul the list of current games.
John "Elwin" Edwards
parents: 162
diff changeset
1094 var delta = now - sessions[tag].lasttime;
0f6da35b27a0 RLGWebD: overhaul the list of current games.
John "Elwin" Edwards
parents: 162
diff changeset
1095 if (delta < 60000) {
0f6da35b27a0 RLGWebD: overhaul the list of current games.
John "Elwin" Edwards
parents: 162
diff changeset
1096 var gamedesc = {};
0f6da35b27a0 RLGWebD: overhaul the list of current games.
John "Elwin" Edwards
parents: 162
diff changeset
1097 gamedesc["p"] = sessions[tag].pname;
0f6da35b27a0 RLGWebD: overhaul the list of current games.
John "Elwin" Edwards
parents: 162
diff changeset
1098 gamedesc["g"] = sessions[tag].game.uname;
0f6da35b27a0 RLGWebD: overhaul the list of current games.
John "Elwin" Edwards
parents: 162
diff changeset
1099 gamedesc["i"] = delta;
0f6da35b27a0 RLGWebD: overhaul the list of current games.
John "Elwin" Edwards
parents: 162
diff changeset
1100 statusinfo["g"].push(gamedesc);
0f6da35b27a0 RLGWebD: overhaul the list of current games.
John "Elwin" Edwards
parents: 162
diff changeset
1101 }
0f6da35b27a0 RLGWebD: overhaul the list of current games.
John "Elwin" Edwards
parents: 162
diff changeset
1102 }
0f6da35b27a0 RLGWebD: overhaul the list of current games.
John "Elwin" Edwards
parents: 162
diff changeset
1103 for (var tag in dglgames) {
0f6da35b27a0 RLGWebD: overhaul the list of current games.
John "Elwin" Edwards
parents: 162
diff changeset
1104 var dglinfo = {};
0f6da35b27a0 RLGWebD: overhaul the list of current games.
John "Elwin" Edwards
parents: 162
diff changeset
1105 var slash = tag.search('/');
0f6da35b27a0 RLGWebD: overhaul the list of current games.
John "Elwin" Edwards
parents: 162
diff changeset
1106 dglinfo["g"] = tag.slice(0, slash);
0f6da35b27a0 RLGWebD: overhaul the list of current games.
John "Elwin" Edwards
parents: 162
diff changeset
1107 dglinfo["p"] = tag.slice(slash + 1);
0f6da35b27a0 RLGWebD: overhaul the list of current games.
John "Elwin" Edwards
parents: 162
diff changeset
1108 dglinfo["i"] = -1;
0f6da35b27a0 RLGWebD: overhaul the list of current games.
John "Elwin" Edwards
parents: 162
diff changeset
1109 statusinfo["dgl"].push(dglinfo);
0f6da35b27a0 RLGWebD: overhaul the list of current games.
John "Elwin" Edwards
parents: 162
diff changeset
1110 }
0f6da35b27a0 RLGWebD: overhaul the list of current games.
John "Elwin" Edwards
parents: 162
diff changeset
1111 gamemux.emit('list', statusinfo);
100
3dbfdaf62623 RLG-Web: begin converting to WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 94
diff changeset
1112 }
3dbfdaf62623 RLG-Web: begin converting to WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 94
diff changeset
1113
27
83f9a799a374 rlgwebd.js: read commands from the console
John "Elwin" Edwards <elwin@sdf.org>
parents: 26
diff changeset
1114 function shutdown () {
83f9a799a374 rlgwebd.js: read commands from the console
John "Elwin" Edwards <elwin@sdf.org>
parents: 26
diff changeset
1115 httpServer.close();
83f9a799a374 rlgwebd.js: read commands from the console
John "Elwin" Edwards <elwin@sdf.org>
parents: 26
diff changeset
1116 httpServer.removeAllListeners('request');
28
2ad2b6491aa9 rlgwebd.js: become a real daemon.
John "Elwin" Edwards <elwin@sdf.org>
parents: 27
diff changeset
1117 ctlServer.close();
27
83f9a799a374 rlgwebd.js: read commands from the console
John "Elwin" Edwards <elwin@sdf.org>
parents: 26
diff changeset
1118 tslog("Shutting down...");
83f9a799a374 rlgwebd.js: read commands from the console
John "Elwin" Edwards <elwin@sdf.org>
parents: 26
diff changeset
1119 process.exit();
83f9a799a374 rlgwebd.js: read commands from the console
John "Elwin" Edwards <elwin@sdf.org>
parents: 26
diff changeset
1120 }
83f9a799a374 rlgwebd.js: read commands from the console
John "Elwin" Edwards <elwin@sdf.org>
parents: 26
diff changeset
1121
158
9961a538c00e rlgwebd.js: get rid of numerical game identifiers.
John "Elwin" Edwards
parents: 157
diff changeset
1122 function consoleHandler(chunk) {
27
83f9a799a374 rlgwebd.js: read commands from the console
John "Elwin" Edwards <elwin@sdf.org>
parents: 26
diff changeset
1123 var msg = chunk.toString().split('\n')[0];
83f9a799a374 rlgwebd.js: read commands from the console
John "Elwin" Edwards <elwin@sdf.org>
parents: 26
diff changeset
1124 if (msg == "quit") {
83f9a799a374 rlgwebd.js: read commands from the console
John "Elwin" Edwards <elwin@sdf.org>
parents: 26
diff changeset
1125 allowlogin = false;
83f9a799a374 rlgwebd.js: read commands from the console
John "Elwin" Edwards <elwin@sdf.org>
parents: 26
diff changeset
1126 tslog("Disconnecting...");
158
9961a538c00e rlgwebd.js: get rid of numerical game identifiers.
John "Elwin" Edwards
parents: 157
diff changeset
1127 for (var tag in sessions) {
9961a538c00e rlgwebd.js: get rid of numerical game identifiers.
John "Elwin" Edwards
parents: 157
diff changeset
1128 sessions[tag].close();
27
83f9a799a374 rlgwebd.js: read commands from the console
John "Elwin" Edwards <elwin@sdf.org>
parents: 26
diff changeset
1129 }
155
245a2959f504 Begin support for watching dgamelaunch games.
John "Elwin" Edwards
parents: 148
diff changeset
1130 progressWatcher.stdin.end("\n");
55
96815eae4ebe RLG-Web: make multiple watchers possible.
John "Elwin" Edwards <elwin@sdf.org>
parents: 49
diff changeset
1131 setTimeout(shutdown, 2000);
27
83f9a799a374 rlgwebd.js: read commands from the console
John "Elwin" Edwards <elwin@sdf.org>
parents: 26
diff changeset
1132 }
83f9a799a374 rlgwebd.js: read commands from the console
John "Elwin" Edwards <elwin@sdf.org>
parents: 26
diff changeset
1133 }
83f9a799a374 rlgwebd.js: read commands from the console
John "Elwin" Edwards <elwin@sdf.org>
parents: 26
diff changeset
1134
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
1135 process.on("exit", function () {
158
9961a538c00e rlgwebd.js: get rid of numerical game identifiers.
John "Elwin" Edwards
parents: 157
diff changeset
1136 for (var tag in sessions) {
9961a538c00e rlgwebd.js: get rid of numerical game identifiers.
John "Elwin" Edwards
parents: 157
diff changeset
1137 sessions[tag].term.kill('SIGHUP');
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
1138 }
26
9b58f8d3ea70 rlgwebd.js: add timestamps to log messages.
John "Elwin" Edwards <elwin@sdf.org>
parents: 23
diff changeset
1139 tslog("Quitting...");
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
1140 return;
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
1141 });
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
1142
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
1143 /* Initialization STARTS HERE */
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
1144 process.env["TERM"] = "xterm-256color";
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
1145
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
1146 if (process.getuid() != 0) {
26
9b58f8d3ea70 rlgwebd.js: add timestamps to log messages.
John "Elwin" Edwards <elwin@sdf.org>
parents: 23
diff changeset
1147 tslog("Not running as root, cannot chroot.");
0
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
1148 process.exit(1);
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
1149 }
bd412f63ce0d Put this project under version control, finally.
John "Elwin" Edwards <elwin@sdf.org>
parents:
diff changeset
1150
29
cf9d294bc52f rlgwebd.js: fix reference error
John "Elwin" Edwards <elwin@sdf.org>
parents: 28
diff changeset
1151 var httpServer; // declare here so shutdown() can find it
100
3dbfdaf62623 RLG-Web: begin converting to WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 94
diff changeset
1152 var wsServer;
155
245a2959f504 Begin support for watching dgamelaunch games.
John "Elwin" Edwards
parents: 148
diff changeset
1153 var progressWatcher;
29
cf9d294bc52f rlgwebd.js: fix reference error
John "Elwin" Edwards <elwin@sdf.org>
parents: 28
diff changeset
1154
157
e7f809f06c5c Use posix.getpwnam() to look up UID/GID to drop to.
John "Elwin" Edwards
parents: 156
diff changeset
1155 var pwent;
e7f809f06c5c Use posix.getpwnam() to look up UID/GID to drop to.
John "Elwin" Edwards
parents: 156
diff changeset
1156 try {
e7f809f06c5c Use posix.getpwnam() to look up UID/GID to drop to.
John "Elwin" Edwards
parents: 156
diff changeset
1157 pwent = posix.getpwnam(dropToUser);
e7f809f06c5c Use posix.getpwnam() to look up UID/GID to drop to.
John "Elwin" Edwards
parents: 156
diff changeset
1158 }
e7f809f06c5c Use posix.getpwnam() to look up UID/GID to drop to.
John "Elwin" Edwards
parents: 156
diff changeset
1159 catch (err) {
e7f809f06c5c Use posix.getpwnam() to look up UID/GID to drop to.
John "Elwin" Edwards
parents: 156
diff changeset
1160 tslog("Could not drop to user %s: user does not exist", dropToUser);
e7f809f06c5c Use posix.getpwnam() to look up UID/GID to drop to.
John "Elwin" Edwards
parents: 156
diff changeset
1161 process.exit(1);
e7f809f06c5c Use posix.getpwnam() to look up UID/GID to drop to.
John "Elwin" Edwards
parents: 156
diff changeset
1162 }
e7f809f06c5c Use posix.getpwnam() to look up UID/GID to drop to.
John "Elwin" Edwards
parents: 156
diff changeset
1163
85
4303d94d87a2 rlgwebd.js: Unlink control socket at startup.
John "Elwin" Edwards <elwin@sdf.org>
parents: 84
diff changeset
1164 /* This could be nonblocking, but nothing else can start yet anyway. */
4303d94d87a2 rlgwebd.js: Unlink control socket at startup.
John "Elwin" Edwards <elwin@sdf.org>
parents: 84
diff changeset
1165 if (fs.existsSync(ctlsocket)) {
4303d94d87a2 rlgwebd.js: Unlink control socket at startup.
John "Elwin" Edwards <elwin@sdf.org>
parents: 84
diff changeset
1166 fs.unlinkSync(ctlsocket);
4303d94d87a2 rlgwebd.js: Unlink control socket at startup.
John "Elwin" Edwards <elwin@sdf.org>
parents: 84
diff changeset
1167 }
4303d94d87a2 rlgwebd.js: Unlink control socket at startup.
John "Elwin" Edwards <elwin@sdf.org>
parents: 84
diff changeset
1168
28
2ad2b6491aa9 rlgwebd.js: become a real daemon.
John "Elwin" Edwards <elwin@sdf.org>
parents: 27
diff changeset
1169 /* Open the control socket before chrooting where it can't be found */
2ad2b6491aa9 rlgwebd.js: become a real daemon.
John "Elwin" Edwards <elwin@sdf.org>
parents: 27
diff changeset
1170 var ctlServer = net.createServer(function (sock) {
158
9961a538c00e rlgwebd.js: get rid of numerical game identifiers.
John "Elwin" Edwards
parents: 157
diff changeset
1171 sock.on('data', consoleHandler);
28
2ad2b6491aa9 rlgwebd.js: become a real daemon.
John "Elwin" Edwards <elwin@sdf.org>
parents: 27
diff changeset
1172 });
2ad2b6491aa9 rlgwebd.js: become a real daemon.
John "Elwin" Edwards <elwin@sdf.org>
parents: 27
diff changeset
1173 ctlServer.listen(ctlsocket, function () {
139
dcd07c1d846a Replace the daemon module with posix.
John "Elwin" Edwards
parents: 132
diff changeset
1174 /* rlgwebd.js now assumes that it has been started by the rlgwebd shell
dcd07c1d846a Replace the daemon module with posix.
John "Elwin" Edwards
parents: 132
diff changeset
1175 * script, or some other method that detaches it and sets up stdio. */
dcd07c1d846a Replace the daemon module with posix.
John "Elwin" Edwards
parents: 132
diff changeset
1176 /* chroot and drop permissions. posix.chroot() does chdir() itself. */
28
2ad2b6491aa9 rlgwebd.js: become a real daemon.
John "Elwin" Edwards <elwin@sdf.org>
parents: 27
diff changeset
1177 try {
139
dcd07c1d846a Replace the daemon module with posix.
John "Elwin" Edwards
parents: 132
diff changeset
1178 posix.chroot(chrootDir);
28
2ad2b6491aa9 rlgwebd.js: become a real daemon.
John "Elwin" Edwards <elwin@sdf.org>
parents: 27
diff changeset
1179 }
2ad2b6491aa9 rlgwebd.js: become a real daemon.
John "Elwin" Edwards <elwin@sdf.org>
parents: 27
diff changeset
1180 catch (err) {
2ad2b6491aa9 rlgwebd.js: become a real daemon.
John "Elwin" Edwards <elwin@sdf.org>
parents: 27
diff changeset
1181 tslog("chroot to %s failed: %s", chrootDir, err);
2ad2b6491aa9 rlgwebd.js: become a real daemon.
John "Elwin" Edwards <elwin@sdf.org>
parents: 27
diff changeset
1182 process.exit(1);
2ad2b6491aa9 rlgwebd.js: become a real daemon.
John "Elwin" Edwards <elwin@sdf.org>
parents: 27
diff changeset
1183 }
2ad2b6491aa9 rlgwebd.js: become a real daemon.
John "Elwin" Edwards <elwin@sdf.org>
parents: 27
diff changeset
1184 try {
2ad2b6491aa9 rlgwebd.js: become a real daemon.
John "Elwin" Edwards <elwin@sdf.org>
parents: 27
diff changeset
1185 // drop gid first, that requires UID=0
157
e7f809f06c5c Use posix.getpwnam() to look up UID/GID to drop to.
John "Elwin" Edwards
parents: 156
diff changeset
1186 process.setgid(pwent.gid);
e7f809f06c5c Use posix.getpwnam() to look up UID/GID to drop to.
John "Elwin" Edwards
parents: 156
diff changeset
1187 process.setuid(pwent.uid);
28
2ad2b6491aa9 rlgwebd.js: become a real daemon.
John "Elwin" Edwards <elwin@sdf.org>
parents: 27
diff changeset
1188 }
2ad2b6491aa9 rlgwebd.js: become a real daemon.
John "Elwin" Edwards <elwin@sdf.org>
parents: 27
diff changeset
1189 catch (err) {
2ad2b6491aa9 rlgwebd.js: become a real daemon.
John "Elwin" Edwards <elwin@sdf.org>
parents: 27
diff changeset
1190 tslog("Could not drop permissions: %s", err);
2ad2b6491aa9 rlgwebd.js: become a real daemon.
John "Elwin" Edwards <elwin@sdf.org>
parents: 27
diff changeset
1191 process.exit(1);
2ad2b6491aa9 rlgwebd.js: become a real daemon.
John "Elwin" Edwards <elwin@sdf.org>
parents: 27
diff changeset
1192 }
29
cf9d294bc52f rlgwebd.js: fix reference error
John "Elwin" Edwards <elwin@sdf.org>
parents: 28
diff changeset
1193 httpServer = http.createServer(webHandler);
30
b5570a594266 rlgwebd.js: listen on any address
John "Elwin" Edwards <elwin@sdf.org>
parents: 29
diff changeset
1194 httpServer.listen(httpPort);
b5570a594266 rlgwebd.js: listen on any address
John "Elwin" Edwards <elwin@sdf.org>
parents: 29
diff changeset
1195 tslog('rlgwebd running on port %d', httpPort);
100
3dbfdaf62623 RLG-Web: begin converting to WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 94
diff changeset
1196 wsServer = new WebSocketServer({"httpServer": httpServer});
3dbfdaf62623 RLG-Web: begin converting to WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 94
diff changeset
1197 wsServer.on("request", wsHandler);
3dbfdaf62623 RLG-Web: begin converting to WebSockets.
John "Elwin" Edwards <elwin@sdf.org>
parents: 94
diff changeset
1198 tslog('WebSockets are online');
155
245a2959f504 Begin support for watching dgamelaunch games.
John "Elwin" Edwards
parents: 148
diff changeset
1199 progressWatcher = startProgressWatcher();
163
0f6da35b27a0 RLGWebD: overhaul the list of current games.
John "Elwin" Edwards
parents: 162
diff changeset
1200 setInterval(pushStatus, 40000);
28
2ad2b6491aa9 rlgwebd.js: become a real daemon.
John "Elwin" Edwards <elwin@sdf.org>
parents: 27
diff changeset
1201 });
2ad2b6491aa9 rlgwebd.js: become a real daemon.
John "Elwin" Edwards <elwin@sdf.org>
parents: 27
diff changeset
1202