This is the local enforcement application that goes with the Timekeeper.

gregory 32f618d6b6 First pass of fixes. 1 周之前
.idea ad8cbc9fb3 Initial 1 周之前
src 32f618d6b6 First pass of fixes. 1 周之前
.gitignore 32f618d6b6 First pass of fixes. 1 周之前
Readme 32f618d6b6 First pass of fixes. 1 周之前
TimekeeperEnforcement.iml ad8cbc9fb3 Initial 1 周之前

Readme

# TimekeeperEnforcement

Local enforcement for the Timekeeper e107 plugin. Once a minute it looks for each
monitored student's games, asks the server how many play minutes are left
(`timer.php`), warns, and closes the game when there are none.

Needs Java 11 or newer. Run it as root (it stops other users' processes and shows
popups as them).

## Build

```bash
javac -d out src/au/pfip/*.java
jar --create --file TimekeeperEnforcement.jar --main-class au.pfip.Main -C out .
```

## Settings

The first of these that exists is used. Use `/etc/timekeeper.inf`, owned by root and
not writable by the students: a settings file they can edit defeats the monitoring.

1. `/etc/timekeeper.inf`
2. `~/timekeeper.inf`
3. `~/.config/timekeeper/timekeeper.inf`
4. `./timekeeper.inf`

If none exists, a new one is written to `~/.config/timekeeper/timekeeper.inf` with the
defaults below. It is Java XML properties format.

| Key | Default | Meaning |
|---|---|---|
| `UsersToMonitor` | *(empty, must be set)* | Comma separated accounts to watch, e.g. `alice,bob` |
| `TimekeeperActive` | `true` | `false` makes the program wait 10 minutes and exit |
| `ExemptNetwork` | *(empty = none)* | Network name where enforcement is off (checked at start-up only; anyone can name a hotspot after a network) |
| `OfflineChecksBeforeKill` | `5` | Failed server checks in a row before a game is closed (`1` = close at once) |
| `GamesRefreshMinutes` | `60` | How often the games list is fetched again |
| `GamesURL`, `PlaytimeURL` | the overlord URLs | Server endpoints |
| `LogFilePath` | home folder | Where `timekeeper.log` is written |

The games list is cached in `games.cache` next to the settings file and used when the
server can't be reached.

## systemd

```ini
[Unit]
Description=Timekeeper enforcement
After=network-online.target
Wants=network-online.target

[Service]
ExecStart=/usr/bin/java -jar /opt/timekeeper/TimekeeperEnforcement.jar
Restart=always
RestartSec=30
User=root

[Install]
WantedBy=multi-user.target
```

## Tests

`test/au/pfip/Harness.java` and `Harness2.java` run against a fake local server and
start and stop throwaway `sleep` processes owned by the current user:

```bash
javac -d out src/au/pfip/*.java test/au/pfip/*.java
java -cp out au.pfip.Harness
java -cp out au.pfip.Harness2
```