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)) { |
