rlgwebd.js: read ttyrecs created by dgamelaunch.
TTYREC files created by dgamelaunch are tracked by DglSession objects, as a first step toward making them watchable.
This commit is contained in:
parent
2064d2a9e6
commit
547387846f
1 changed files with 97 additions and 2 deletions
99
rlgwebd.js
99
rlgwebd.js
|
|
@ -191,6 +191,100 @@ function TermSession(game, lkey, dims, handlers) {
|
||||||
}
|
}
|
||||||
TermSession.prototype = new events.EventEmitter();
|
TermSession.prototype = new events.EventEmitter();
|
||||||
|
|
||||||
|
function DglSession(filename) {
|
||||||
|
var ss = this;
|
||||||
|
events.EventEmitter.call(this);
|
||||||
|
var pathcoms = filename.split('/');
|
||||||
|
this.gname = pathcoms[pathcoms.length - 2];
|
||||||
|
if (!(this.gname in games)) {
|
||||||
|
ss.emit('open', false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var basename = pathcoms[pathcoms.length - 1];
|
||||||
|
var firstsep = basename.indexOf(':');
|
||||||
|
this.pname = basename.slice(0, firstsep);
|
||||||
|
var fname = basename.slice(firstsep + 1);
|
||||||
|
this.ttyrec = path.join("/dgldir/ttyrec", this.pname, this.gname, fname);
|
||||||
|
this.framebuf = new Buffer(1024);
|
||||||
|
this.frameoff = 0;
|
||||||
|
this.framepush = function(chunk) {
|
||||||
|
/* If this chunk resets the screen, discard what preceded it. */
|
||||||
|
var cgame = games[this.gname];
|
||||||
|
if (bufncmp(chunk, cgame.clear, cgame.clear.length)) {
|
||||||
|
tslog("DGL %s: clearing frame", ss.tag());
|
||||||
|
this.framebuf = new Buffer(1024);
|
||||||
|
this.frameoff = 0;
|
||||||
|
}
|
||||||
|
/* Make sure there's space. */
|
||||||
|
while (this.framebuf.length < chunk.length + this.frameoff) {
|
||||||
|
var nbuf = new Buffer(this.framebuf.length * 2);
|
||||||
|
this.framebuf.copy(nbuf, 0, 0, this.frameoff);
|
||||||
|
this.framebuf = nbuf;
|
||||||
|
if (this.framebuf.length > 65536) {
|
||||||
|
tslog("Warning: DGL %s frame buffer at %d bytes", this.tag(),
|
||||||
|
this.framebuf.length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
chunk.copy(this.framebuf, this.frameoff);
|
||||||
|
this.frameoff += chunk.length;
|
||||||
|
};
|
||||||
|
this.readchunk = function () {
|
||||||
|
var header = new Buffer(12);
|
||||||
|
fs.read(ss.fd, header, 0, 12, null, function (err, n, buf) {
|
||||||
|
/* Stop recursion if end of file has been reached. */
|
||||||
|
if (err || n < 12)
|
||||||
|
return;
|
||||||
|
var datalen = buf.readUInt32LE(8);
|
||||||
|
//tslog("Allocating %d bytes", datalen);
|
||||||
|
var databuf = new Buffer(datalen);
|
||||||
|
fs.read(ss.fd, databuf, 0, datalen, null, function (err, n, buf) {
|
||||||
|
if (err || n < datalen)
|
||||||
|
return;
|
||||||
|
/* Process the data */
|
||||||
|
ss.framepush(buf);
|
||||||
|
ss.emit("data", buf);
|
||||||
|
tslog("DGL %s: %d bytes", ss.tag(), buf.length);
|
||||||
|
/* Recurse. */
|
||||||
|
ss.readchunk();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
fs.readFile(filename, {encoding: "utf8"}, function (err, data) {
|
||||||
|
if (err) {
|
||||||
|
ss.emit('open', false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var lines = data.split('\n');
|
||||||
|
ss.h = Number(lines[1]);
|
||||||
|
ss.w = Number(lines[2]);
|
||||||
|
fs.open(ss.ttyrec, "r", function(err, fd) {
|
||||||
|
if (err) {
|
||||||
|
ss.emit('open', false);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ss.fd = fd;
|
||||||
|
ss.emit('open', true);
|
||||||
|
tslog("DGL %s: open", ss.tag());
|
||||||
|
ss.readchunk();
|
||||||
|
ss.watcher = fs.watch(ss.ttyrec, function (ev, finame) {
|
||||||
|
if (ev == "change")
|
||||||
|
ss.readchunk();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
this.tag = function () {
|
||||||
|
return this.gname + "/" + this.pname;
|
||||||
|
};
|
||||||
|
this.close = function () {
|
||||||
|
this.watcher.close()
|
||||||
|
fs.close(this.fd);
|
||||||
|
this.emit("close");
|
||||||
|
tslog("DGL %s: closed", ss.tag());
|
||||||
|
};
|
||||||
|
}
|
||||||
|
DglSession.prototype = new events.EventEmitter();
|
||||||
|
|
||||||
// Also known as WebSocketAndTermSessionClosureGlueFactory
|
// Also known as WebSocketAndTermSessionClosureGlueFactory
|
||||||
function wsWatcher(conn, session) {
|
function wsWatcher(conn, session) {
|
||||||
var ss = this; // is this even needed?
|
var ss = this; // is this even needed?
|
||||||
|
|
@ -631,14 +725,15 @@ function startProgressWatcher() {
|
||||||
var tag = gname + "/" + pname;
|
var tag = gname + "/" + pname;
|
||||||
if (chunk[0] == "E") {
|
if (chunk[0] == "E") {
|
||||||
tslog("DGL: %s is playing %s: %s", pname, gname, fname)
|
tslog("DGL: %s is playing %s: %s", pname, gname, fname)
|
||||||
dglgames[tag] = fname;
|
dglgames[tag] = new DglSession(fname);
|
||||||
}
|
}
|
||||||
else if (chunk[0] == "C") {
|
else if (chunk[0] == "C") {
|
||||||
tslog("DGL: %s started playing %s: %s", pname, gname, fname)
|
tslog("DGL: %s started playing %s: %s", pname, gname, fname)
|
||||||
dglgames[tag] = fname;
|
dglgames[tag] = new DglSession(fname);
|
||||||
}
|
}
|
||||||
else if (chunk[0] == "D") {
|
else if (chunk[0] == "D") {
|
||||||
tslog("DGL: %s finished playing %s: %s", pname, gname, fname)
|
tslog("DGL: %s finished playing %s: %s", pname, gname, fname)
|
||||||
|
dglgames[tag].close();
|
||||||
delete dglgames[tag];
|
delete dglgames[tag];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue