Multiple games can now run at the same time, and data will be sent to
the proper place. The interaction of multiple players with watchers
has not yet been tested.
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.
DglSession objects read a 12-byte TTYREC header, extract therefrom the
length of the data chunk, and then read the data. In between these two
reads, the file watcher could trigger another readchunk() invocation,
which might attempt to read a header from the beginning of the data
chunk. This usually results in expecting a data chunk of several GB
and failing to create a Buffer for it.
The race is remedied by setting a flag on the DglSession object
whenever readchunk() is called, clearing it when both reads complete,
and refusing to read if it is already set.
The /status WebSocket now only sends a complete list when opened. At
40-second intervals, it sends a list of games that have been updated in
the last minute. The client now uses this to keep its own list.
TermSessions now store the timestamp of the latest data. This removes
the need to use fstat() to calculate idle times.
The reaper() function is removed. It may be useful to find another way
to remove old login keys.
Games will be indentified by gamename/username pairs. This will allow
better interoperability with dgamelaunch.
Polling clients are no longer supported; the code remnants need to be
removed. The reaper() function will likely crash. Unexpectedly, the
WebSocket client still works well enough to play. Watching and listing
current games are probably broken.
watcher.c is a subprocess which uses inotify to watch the inprogress
directories. A C program is used because node's fs.watch() can't tell
the difference between creation and deletion.
The daemon module doesn't include chroot() anymore, so a replacement
is needed. Detaching a daemon keeps getting harder to do in Node, so
some setup has been moved into a shell script.
User information can be retrieved at /uinfo?key=<login key>&<prop>.
The only property currently retrievable is email; eventually these will
also be settable via POST.
rlgwebd sets TERM to xterm-256color, which uses CSI H CSI 2J to clear
the screen. The description of srogue had been CSI H CSI J, which is
the sequence for screen.
Server-side, have gamemux 'end' events include the name and game, so
they can be sent to WebSockets connected to /status. This means a
WebSocket client only needs to update its choice list when it gets a
begin or end message with its own username. So it only needs to check
/pstatus/<name> at those times and can stop polling.
WebSocket sessions should not be taken over, and polling sessions are
not yet convertible to WebSockets. Eventually the current method of
taking over via Player#reset() should be replaced with autosaving the
game, which will always work.
Delete some TermSession code left over from the first attempt at
Websockets. Also don't bother logging the disconnection of watchers
after the game has ended.
Split the TermSession class into the new TermSession, which handles the
PTY, and client classes, which handle HTTP sessions. These are Player
and Watcher. This allows multiple watchers per game, and other
improvements.
Add a TermSession.sendq flag that indicates whether a type q message
has been sent to the client. Don't immediately destroy the TermSession
on child exit if the message hasn't been sent.
This is an ugly hack until the TermSession class is separated into an
EventEmitter to handle the PTY and a listening object that handles
communication with the client. That will also allow other clients to
watch the game.