Overview

Combination lock

Have you ever seen a show where the spy infiltrates an office to steal sensitive documents?

They get to the computer, only to find the files locked behind a four-digit password. Frantically, they search for clues and just barely manage to crack the code in time to get away.

This project involved making a "fake OS" for an escape room. You're a player locked in a deadly game! You have one hour before the murderer returns. To escape, you must unlock files on the computer and save them to a USB drive so you can take them to the police.

My first instinct was to make a fullscreen game that emulates a desktop, but I quickly realized that wouldn't be flexible enough to suit the client's needs and would end up re-inventing a lot of existing technology. The final product is a fully customized desktop environment for the raspberry pi, complete with a suite of custom software written in python and C++.

Skills used in this project:

  • Python
  • Linux/Raspberry Pi
  • C++
  • Udev, Dbus
  • Modifying open source projects

Themes

Here you can see the final product. One of the benefits of using existing technology is customizability. I used Openbox as a window manager, which means the window titles can be easily themed. The desktop background can be changed just as easily, and even the icons are customizable.

File Manager

Original

My modified file view

During the escape, players interact with files on the desktop and eventually open a folder containing a document. The piece of software that handles those things is called a file manager.

I decided to use PCManFM as the file manager, because I knew it would work well with Openbox, as they're used together in the popular desktop environment LXDE.

The file view of PCManFM has a lot of features that needed to be cut. I removed as much as I could by editing configs, and then I had to get my hands dirty modifying the source code. PCManFM is a monolithic project written in C++ without great documentation, so it was a little bit of reverse engineering and trial and error.

Eventually, I got it to the state you see here.

Original

The original file view, giving access to the underlying file system

Screensaver

Screensaver Timer

This is what confronts you when you first look at the computer. Fullscreen, red text that counts down to your doom. As soon as you move the mouse or press a key, it minimizes to a corner, but is always visible.

My initial design featured a shrinking circle to visualize the time, but the client wanted a red seven-segment display, so I scrapped it.

Like most of the GUI software in this project, this was written with python and tkinter.

Audio player

Audio player

Audio files on the desktop serve as clues to solve the escape room.

There wasn't an audio player barebones enough, so I wrote a custom one using tkSnack. It features a waveform view that doubles as a scrub control.

Alice's Messages

Alice's hint

You aren't alone. Alice helps you out when you reach certain points in the puzzle, giving you clues and keeping you focused.

I made a daemon to display messages with python and tkinter. It uses files as IPC. Knowing what I know now, I would use dbus instead, due to some unnecessary complexity that introduced.

Combination Lock

Combination lock

This lock shows up twice. Once in the beginning, when you try to open a folder, and once at the end when you try to save to your USB drive.

Thus, it has to be flexible. The PIN can be changed via an ini file, and the lock can be used to activate any arbitrary command. It even saves its state, so you don't have to unlock the same thing twice.

USB Monitor

USB Save Dialogue

Near the end of the puzzle, you need to find a USB drive and plug it in to save the incriminating evidence you've uncovered.

I used pyudev to monitor for usb devices. I had to do a bit of reverse engineering to determine what counts as a usb drive.

Document Puzzle

USB Save Dialogue

After unlocking a folder on the desktop, you're confronted with this document. You need to fill in the right information so you can save it and take it to the police.

This is the only GUI software I wrote that doesn't use tkinter. Instead, it's an html document, displayed using pywebview. I made it that way so that the client could customize it more easily.

It's still written mostly in python, but I also used some Javascript, as well as HTML and CSS, of course!

Video Player

Video player

Initially I thought I could get away with using a pre-existing video player. Unfortunately, it didn't work with the client's pi.

The video player I made is a wrapper around omxplayer. I made the gui with tkinter and used python-dbus to control the video.

Additional Software

A few non-gui applications were needed. One was a daemon to perform GPIO operations like resetting the puzzle, a debug button for exiting the desktop environment, and shutting down the pi.

Closing Thoughts

I made nearly all of the GUI with tkinter, but if I could do it again I would probably use a more modern solution like qt.

A note on security: I had to strip out all the context menus and remove any special key combinations to keep the player from leaving the desktop or gaining access to a terminal, but it's possible that I missed something. For an added layer of security, I put the entire application in a chroot environment. That took a lot of fiddling, but it ultimately made delivering the project much easier.

Given another chance, I would probably try to use Docker for the same task, since it's such a relevant technology right now.