Mercurial > hg > rlgwebd
comparison 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 |
comparison
equal
deleted
inserted
replaced
167:fba1b34e7554 | 168:0ceaca924b4c |
---|---|
71 * lkey: (String, key) The user's id, a key into logins. | 71 * lkey: (String, key) The user's id, a key into logins. |
72 * dims: (Array [Number, Number]) Height and width of the pty. | 72 * dims: (Array [Number, Number]) Height and width of the pty. |
73 * handlers: (Object) Key-value pairs, event names and functions to | 73 * handlers: (Object) Key-value pairs, event names and functions to |
74 * install to handle them. | 74 * install to handle them. |
75 * Events: | 75 * Events: |
76 * "open": Emitted on startup. Parameters: success (Boolean) | |
77 * "data": Data generated by child. Parameters: buf (Buffer) | 76 * "data": Data generated by child. Parameters: buf (Buffer) |
78 * "exit": Child terminated. Parameters: none | 77 * "exit": Child terminated. Parameters: none |
79 */ | 78 */ |
80 function TermSession(game, lkey, dims, handlers) { | 79 function TermSession(game, lkey, dims, handlers) { |
81 var ss = this; | 80 var ss = this; |
86 /* Don't launch anything that's not a real game. */ | 85 /* Don't launch anything that's not a real game. */ |
87 if (game in games) { | 86 if (game in games) { |
88 this.game = games[game]; | 87 this.game = games[game]; |
89 } | 88 } |
90 else { | 89 else { |
91 this.emit('open', false); | 90 this.failed = true; |
92 return; | 91 return; |
93 } | 92 } |
94 if (lkey in logins) { | 93 if (lkey in logins) { |
95 this.key = lkey; | 94 this.key = lkey; |
96 this.pname = logins[lkey].name; | 95 this.pname = logins[lkey].name; |
97 } | 96 } |
98 else { | 97 else { |
99 this.emit('open', false); | 98 this.failed = true; |
100 return; | 99 return; |
101 } | 100 } |
102 /* Grab a spot in the sessions table. */ | 101 /* Grab a spot in the sessions table. */ |
103 sessions[this.game.uname + "/" + this.pname] = this; | 102 sessions[this.game.uname + "/" + this.pname] = this; |
104 /* Set up the sizes. */ | 103 /* Set up the sizes. */ |
116 var args = ["-n", this.pname]; | 115 var args = ["-n", this.pname]; |
117 var spawnopts = {"env": childenv, "cwd": "/", "rows": this.h, "cols": this.w, | 116 var spawnopts = {"env": childenv, "cwd": "/", "rows": this.h, "cols": this.w, |
118 "name": "xterm-256color"}; | 117 "name": "xterm-256color"}; |
119 this.term = pty.spawn(this.game.path, args, spawnopts); | 118 this.term = pty.spawn(this.game.path, args, spawnopts); |
120 tslog("%s playing %s (pid %d)", this.pname, this.game.uname, this.term.pid); | 119 tslog("%s playing %s (pid %d)", this.pname, this.game.uname, this.term.pid); |
121 this.emit('open', true, this.game.uname, this.pname); | 120 this.failed = false; |
122 gamemux.emit('begin', this.game.uname, this.pname); | 121 gamemux.emit('begin', this.game.uname, this.pname); |
123 /* Set up the lockfile and ttyrec */ | 122 /* Set up the lockfile and ttyrec */ |
124 this.lasttime = new Date(); | 123 this.lasttime = new Date(); |
125 var ts = timestamp(this.lasttime); | 124 var ts = timestamp(this.lasttime); |
126 var progressdir = path.join("/dgldir/inprogress", this.game.uname); | 125 var progressdir = path.join("/dgldir/inprogress", this.game.uname); |
322 conn.sendUTF(JSON.stringify({"t": "d", | 321 conn.sendUTF(JSON.stringify({"t": "d", |
323 "d": session.framebuf.toString("hex", 0, session.frameoff)})); | 322 "d": session.framebuf.toString("hex", 0, session.frameoff)})); |
324 } | 323 } |
325 | 324 |
326 function wsPlay(wsReq, game, lkey, dims) { | 325 function wsPlay(wsReq, game, lkey, dims) { |
326 tslog("wsPlay: running for %s/%s", game, logins[lkey].name); | |
327 tslog("Request is for %s", logins[wsReq.resourceURL.query["key"]].name); | |
327 var conn; | 328 var conn; |
328 var session; | 329 var session; |
329 /* Listeners on the WebSocket */ | 330 /* Listeners on the WebSocket */ |
330 function messageH(message) { | 331 function messageH(message) { |
331 var parsedMsg = getMsgWS(message); | 332 var parsedMsg = getMsgWS(message); |
343 } | 344 } |
344 function closeH() { | 345 function closeH() { |
345 session.close(); | 346 session.close(); |
346 } | 347 } |
347 /* These listen on the TermSession. */ | 348 /* These listen on the TermSession. */ |
348 function openH(success, gname, pname) { | |
349 if (success) { | |
350 var tag = gname + "/" + pname; | |
351 var reply = {"t": "s", "tag": tag, "w": sessions[tag].w, "h": | |
352 sessions[tag].h, "p": pname, "g": gname}; | |
353 conn = wsReq.accept(null, wsReq.origin); | |
354 conn.sendUTF(JSON.stringify(reply)); | |
355 conn.on('message', messageH); | |
356 conn.on('close', closeH); | |
357 } | |
358 else { | |
359 wsReq.reject(500, errorcodes[5]); | |
360 tslog("Unable to allocate TTY for %s", game); | |
361 } | |
362 } | |
363 function dataH(chunk) { | 349 function dataH(chunk) { |
364 var msg = {}; | 350 var msg = {}; |
365 msg.t = "d"; | 351 msg.t = "d"; |
366 msg.d = chunk.toString("hex"); | 352 msg.d = chunk.toString("hex"); |
367 conn.sendUTF(JSON.stringify(msg)); | 353 conn.sendUTF(JSON.stringify(msg)); |
368 } | 354 } |
369 function exitH() { | 355 function exitH() { |
370 if (conn.connected) | 356 if (conn.connected) |
371 conn.sendUTF(JSON.stringify({"t": "q"})); | 357 conn.sendUTF(JSON.stringify({"t": "q"})); |
372 conn.close(); | 358 conn.close(); |
373 session.removeListener('open', openH); | |
374 session.removeListener('data', dataH); | 359 session.removeListener('data', dataH); |
375 session.removeListener('exit', exitH); | 360 session.removeListener('exit', exitH); |
376 } | 361 } |
377 var handlers = {'open': openH, 'data': dataH, 'exit': exitH}; | 362 var handlers = {'data': dataH, 'exit': exitH}; |
378 session = new TermSession(game, lkey, dims, handlers); | 363 session = new TermSession(game, lkey, dims, handlers); |
364 if (!session.failed) { | |
365 var tag = session.game.uname + "/" + session.pname; | |
366 var reply = {"t": "s", "tag": tag, "w": session.w, "h": session.h, | |
367 "p": session.pname, "g": session.game.uname}; | |
368 tslog("Accepting for %s", tag); | |
369 tslog("Request is for %s", logins[wsReq.resourceURL.query["key"]].name); | |
370 tslog("Session is for %s", session.pname); | |
371 conn = wsReq.accept(null, wsReq.origin); | |
372 conn.sendUTF(JSON.stringify(reply)); | |
373 conn.on('message', messageH); | |
374 conn.on('close', closeH); | |
375 } | |
376 else { | |
377 wsReq.reject(500, errorcodes[5]); | |
378 tslog("Unable to allocate TTY for %s", game); | |
379 } | |
379 } | 380 } |
380 | 381 |
381 function wsStart(wsReq) { | 382 function wsStart(wsReq) { |
382 var playmatch = wsReq.resourceURL.pathname.match(/^\/play\/([^\/]*)$/); | 383 var playmatch = wsReq.resourceURL.pathname.match(/^\/play\/([^\/]*)$/); |
383 if (!playmatch[1] || !(playmatch[1] in games)) { | 384 if (!playmatch[1] || !(playmatch[1] in games)) { |