Conway's Life Server
A few years back I was experimenting with Go and SDL2, I wrote a dead-simple Conway's Game of Life program with it, added loading of a couple popular pattern file formats, and was pretty much finished with it. The other day I came across this cool project while preparing for Thanksgiving by browsing infosec.exchange . Brett has an e-ink display running life and is seeding it from tarpit data which struck me as a really neat idea to keep the world from becoming static as most of the more complex ones tend to do.
I dusted off my sdl2-life project
and got
busy adding a server to it as the first step towards feeding it with live data.
I shuffled some code around to make it easier for the patterns to be applied to
a running system, and found a major bug in my loading code. That’s what happens
when you have no tests, and make changes while manually testing one file format
and not the other. I added a simple server listening for POSTs on port 3051 and
faster than you can type “Bob’s yer Uncle” I was able to update the running
sdl2-life
world by using curl to post pattern files. eg.
curl --data-binary @./examples/glider-gun-1.05.life http://127.0.0.1:3051/
After taking a break to stuff myself with Turkey and all the fixings I started
on a new project to feed sdl2-life
with the logs from the webserver. A few
lines of Go later I had log2life working
.
Have I mentioned how much I mostly really like Go? Except for math, getting the
types right when doing division always takes me longer than in python. Anyway,
I quickly had a program to read the logs, convert the IP to an x, y coordinate
(thanks to my friend Rob, I was trying to over-think it), XOR the data together
and POST it to the live server as a pattern file. Standards and text data
formats win again.
Building and Running
As long as you already have Go
setup on your system
it will be easy (guaranteed!) to get this up and running. Grab the code from
sdl2-life
and from
log2life
and build each of them with go build
. Test out sdl2-life
by running it with no parameters. You should see
a randomly generated world start up.
Restart it with the server listening and a blank world by running:
sdl2-life sdl2-life -rows 250 -columns 250 -server -empty
Test out posting a pattern to it by running curl with one of the example files:
curl --data-binary @./examples/glider-gun-1.05.life http://127.0.0.1:3051/
Now grab a logfile from a webserver. I use lighttpd with mod_accesslog's default format which may work with other servers. If not, see the code here and adjust to fit your situation.
Feed the log to sdl2-life
by running this:
log2life -columns 250 -rows 250 /path/to/logfile.log
This will read the log, one line at a time, send the pattern file to the server,
and then delay based on the timestamp, send the next line, etc. You can speed it
up and slow it down with the -speed
option. eg. -speed 10
will speed it up 10x.
Note that the rows and columns should match the ones used for sdl2-life
,
which defaults to 100x100, so that the IPs are mapped to the whole world.
You can also pass logs to log2life
on stdin by passing it -
instead of the
logfile name. When you do that the speed is set to realtime, it will display
the lines as they are received and not delay between them.
ssh foo@server tail -f /var/log/lighttpd/access.log | log2life -rows 250 -columns 250 -
One last thing to note is that I use dwm as my window manager, so the
sdl2-life
window has no decorations on my system, and I’ve never bothered to
add resize support. If you drag the corners you may find bugs :) The size of the window
can be adjusted using -width
and -height
but you need to make sure that it is evenly
divisible by -rows
and -columns
so that the cells remain square. If you do not it will
round down which can result in a bunch of unused space.