RLG-Web: use the pty module.
Convert the RLG-Web server to use the pty.js module instead of the ptyhelper binary.
This commit is contained in:
parent
b9a6a1e303
commit
9c45f52722
1 changed files with 19 additions and 17 deletions
36
rlgwebd.js
36
rlgwebd.js
|
|
@ -10,6 +10,7 @@ var fs = require('fs');
|
||||||
var events = require('events');
|
var events = require('events');
|
||||||
var child_process = require('child_process');
|
var child_process = require('child_process');
|
||||||
var daemon = require(path.join(localModules, "daemon"));
|
var daemon = require(path.join(localModules, "daemon"));
|
||||||
|
var pty = require(path.join(localModules, "pty.js"));
|
||||||
|
|
||||||
/* Configuration variables */
|
/* Configuration variables */
|
||||||
// These first two files are NOT in the chroot.
|
// These first two files are NOT in the chroot.
|
||||||
|
|
@ -70,7 +71,7 @@ var nextsession = 0;
|
||||||
* Events:
|
* Events:
|
||||||
* "open": Emitted on startup. Parameters: success (Boolean)
|
* "open": Emitted on startup. Parameters: success (Boolean)
|
||||||
* "data": Data generated by child. Parameters: buf (Buffer)
|
* "data": Data generated by child. Parameters: buf (Buffer)
|
||||||
* "exit": Child terminated. Parameters: exitcode, signal
|
* "exit": Child terminated. Parameters: none
|
||||||
*/
|
*/
|
||||||
function TermSession(game, lkey, dims, handlers) {
|
function TermSession(game, lkey, dims, handlers) {
|
||||||
var ss = this;
|
var ss = this;
|
||||||
|
|
@ -109,15 +110,18 @@ function TermSession(game, lkey, dims, handlers) {
|
||||||
for (var key in process.env) {
|
for (var key in process.env) {
|
||||||
childenv[key] = process.env[key];
|
childenv[key] = process.env[key];
|
||||||
}
|
}
|
||||||
childenv["PTYHELPER"] = String(this.h) + "x" + String(this.w);
|
var args = ["-n", this.pname];
|
||||||
args = [this.game.path, "-n", this.pname];
|
var spawnopts = {"env": childenv, "cwd": "/", "rows": this.h, "cols": this.w,
|
||||||
this.child = child_process.spawn("/bin/ptyhelper", args, {"env": childenv});
|
"name": "xterm-256color"};
|
||||||
|
this.term = pty.spawn(this.game.path, args, spawnopts);
|
||||||
|
tslog("%s playing %s (index %d, pid %d)", this.pname, this.game.uname,
|
||||||
|
this.sessid, this.term.pid);
|
||||||
this.emit('open', true, this.sessid);
|
this.emit('open', true, this.sessid);
|
||||||
/* Set up the lockfile and ttyrec */
|
/* Set up the lockfile and ttyrec */
|
||||||
var ts = timestamp();
|
var ts = timestamp();
|
||||||
var progressdir = "/dgldir/inprogress-" + this.game.uname;
|
var progressdir = "/dgldir/inprogress-" + this.game.uname;
|
||||||
this.lock = path.join(progressdir, this.pname + ":node:" + ts + ".ttyrec");
|
this.lock = path.join(progressdir, this.pname + ":node:" + ts + ".ttyrec");
|
||||||
var lmsg = this.child.pid.toString() + '\n' + this.w + '\n' + this.h + '\n';
|
var lmsg = this.term.pid.toString() + '\n' + this.w + '\n' + this.h + '\n';
|
||||||
fs.writeFile(this.lock, lmsg, "utf8");
|
fs.writeFile(this.lock, lmsg, "utf8");
|
||||||
var ttyrec = path.join("/dgldir/ttyrec", this.pname, this.game.uname,
|
var ttyrec = path.join("/dgldir/ttyrec", this.pname, this.game.uname,
|
||||||
ts + ".ttyrec");
|
ts + ".ttyrec");
|
||||||
|
|
@ -127,11 +131,10 @@ function TermSession(game, lkey, dims, handlers) {
|
||||||
this.framebuf = new Buffer(1024);
|
this.framebuf = new Buffer(1024);
|
||||||
this.frameoff = 0;
|
this.frameoff = 0;
|
||||||
logins[lkey].sessions.push(this.sessid);
|
logins[lkey].sessions.push(this.sessid);
|
||||||
tslog("%s playing %s (index %d, pid %d)", this.pname, this.game.uname,
|
|
||||||
this.sessid, this.child.pid);
|
|
||||||
/* END setup */
|
/* END setup */
|
||||||
function ttyrec_chunk(buf) {
|
function ttyrec_chunk(datastr) {
|
||||||
var ts = new Date();
|
var ts = new Date();
|
||||||
|
var buf = new Buffer(datastr);
|
||||||
var chunk = new Buffer(buf.length + 12);
|
var chunk = new Buffer(buf.length + 12);
|
||||||
/* TTYREC headers */
|
/* TTYREC headers */
|
||||||
chunk.writeUInt32LE(Math.floor(ts.getTime() / 1000), 0);
|
chunk.writeUInt32LE(Math.floor(ts.getTime() / 1000), 0);
|
||||||
|
|
@ -142,8 +145,7 @@ function TermSession(game, lkey, dims, handlers) {
|
||||||
ss.framepush(buf);
|
ss.framepush(buf);
|
||||||
ss.emit('data', buf);
|
ss.emit('data', buf);
|
||||||
}
|
}
|
||||||
this.child.stdout.on("data", ttyrec_chunk);
|
this.term.on("data", ttyrec_chunk);
|
||||||
this.child.stderr.on("data", ttyrec_chunk);
|
|
||||||
this.framepush = function(chunk) {
|
this.framepush = function(chunk) {
|
||||||
/* If this chunk resets the screen, discard what preceded it. */
|
/* If this chunk resets the screen, discard what preceded it. */
|
||||||
if (bufncmp(chunk, this.game.clear, this.game.clear.length)) {
|
if (bufncmp(chunk, this.game.clear, this.game.clear.length)) {
|
||||||
|
|
@ -164,18 +166,18 @@ function TermSession(game, lkey, dims, handlers) {
|
||||||
this.frameoff += chunk.length;
|
this.frameoff += chunk.length;
|
||||||
};
|
};
|
||||||
this.write = function(data) {
|
this.write = function(data) {
|
||||||
this.child.stdin.write(data);
|
this.term.write(data);
|
||||||
};
|
};
|
||||||
this.child.on("exit", function (code, signal) {
|
this.term.on("exit", function () {
|
||||||
fs.unlink(ss.lock);
|
fs.unlink(ss.lock);
|
||||||
ss.record.end();
|
ss.record.end();
|
||||||
ss.emit('exit', code, signal);
|
ss.emit('exit');
|
||||||
var id = ss.sessid;
|
var id = ss.sessid;
|
||||||
delete sessions[id];
|
delete sessions[id];
|
||||||
tslog("Game %s ended.", id);
|
tslog("Game %s ended.", id);
|
||||||
});
|
});
|
||||||
this.close = function () {
|
this.close = function () {
|
||||||
this.child.kill('SIGHUP');
|
this.term.kill('SIGHUP');
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
TermSession.prototype = new events.EventEmitter();
|
TermSession.prototype = new events.EventEmitter();
|
||||||
|
|
@ -203,7 +205,7 @@ function Watcher(session) {
|
||||||
reply.d = buf.toString("hex");
|
reply.d = buf.toString("hex");
|
||||||
ss.sendQ.push(reply);
|
ss.sendQ.push(reply);
|
||||||
}
|
}
|
||||||
function exitH(code, signal) {
|
function exitH() {
|
||||||
ss.alive = false;
|
ss.alive = false;
|
||||||
ss.sendQ.push({"t": "q"});
|
ss.sendQ.push({"t": "q"});
|
||||||
}
|
}
|
||||||
|
|
@ -327,7 +329,7 @@ function Player(gamename, lkey, dims, callback) {
|
||||||
reply.d = chunk.toString("hex");
|
reply.d = chunk.toString("hex");
|
||||||
ss.sendQ.push(reply);
|
ss.sendQ.push(reply);
|
||||||
}
|
}
|
||||||
function exitH(code, signal) {
|
function exitH() {
|
||||||
ss.alive = false;
|
ss.alive = false;
|
||||||
ss.sendQ.push({"t": "q"});
|
ss.sendQ.push({"t": "q"});
|
||||||
}
|
}
|
||||||
|
|
@ -1010,7 +1012,7 @@ function conHandler(chunk) {
|
||||||
|
|
||||||
process.on("exit", function () {
|
process.on("exit", function () {
|
||||||
for (var sessid in sessions) {
|
for (var sessid in sessions) {
|
||||||
sessions[sessid].child.kill('SIGHUP');
|
sessions[sessid].term.kill('SIGHUP');
|
||||||
}
|
}
|
||||||
tslog("Quitting...");
|
tslog("Quitting...");
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue