aboutsummaryrefslogtreecommitdiff
path: root/config
diff options
context:
space:
mode:
Diffstat (limited to 'config')
-rw-r--r--config/app.go17
-rw-r--r--config/config.go31
-rw-r--r--config/config_test.go107
-rw-r--r--config/game.go11
-rw-r--r--config/menu.go23
-rw-r--r--config/test_data/invalid_yaml1
6 files changed, 190 insertions, 0 deletions
diff --git a/config/app.go b/config/app.go
new file mode 100644
index 0000000..541699c
--- /dev/null
+++ b/config/app.go
@@ -0,0 +1,17 @@
+package config
+
+// App struct contains the configuration for this application
+type App struct {
+ // WorkingDirectory is the program working directory where the user data, save files and scores are stored
+ WorkingDirectory string `yaml:"WorkingDirectory"`
+ // MaxUsers is the maximum amount of registered users to allow
+ MaxUsers int `yaml:"MaxUsers"`
+ // AllowRegistration allows registration of new users
+ AllowRegistration bool `yaml:"AllowRegistration"`
+ // MaxNickLen Maximum length for a nickname
+ MaxNickLen int `yaml:"MaxNickLen"`
+ // MenuMaxIdleTime is the maximum number of seconds a user can be idle on the menu before the program exits
+ MenuMaxIdleTime int `yaml:"MenuMaxIdleTime"`
+ // PostLoginCommands is the list of commands to execute upon login, like creating save directories for games
+ PostLoginCommands []string `yaml:"PostLoginCommands"`
+}
diff --git a/config/config.go b/config/config.go
new file mode 100644
index 0000000..2c94dbe
--- /dev/null
+++ b/config/config.go
@@ -0,0 +1,31 @@
+package config
+
+import (
+ "os"
+
+ "gopkg.in/yaml.v2"
+)
+
+type Config struct {
+ // AppConfig is the application level configuration entries
+ App App `yaml:"App"`
+ // Menus is the list of menus. The first one is the default menu for an anonymous user, the second one is the default menu for an authenticated user
+ Menus []Menu `yaml:"Menus"`
+ // Games is the list of games.
+ Games map[string]Game `yaml:"Games"`
+}
+
+// LoadFile loads the config from a given file
+func LoadFile(path string) (config Config, err error) {
+ var f *os.File
+ f, err = os.Open(path)
+ if err != nil {
+ return
+ }
+ defer f.Close()
+ decoder := yaml.NewDecoder(f)
+ if err = decoder.Decode(&config); err != nil {
+ return
+ }
+ return
+}
diff --git a/config/config_test.go b/config/config_test.go
new file mode 100644
index 0000000..adbfc7e
--- /dev/null
+++ b/config/config_test.go
@@ -0,0 +1,107 @@
+package config
+
+import (
+ "reflect"
+ "testing"
+)
+
+func TestLoadFile(t *testing.T) {
+ _, err := LoadFile("test_data/non-existant")
+ if err == nil {
+ t.Fatal("non-existant config file failed without error")
+ }
+ _, err = LoadFile("test_data/invalid_yaml")
+ if err == nil {
+ t.Fatal("invalid_yaml config file failed without error")
+ }
+ config, err := LoadFile("../example/complete.yaml")
+ want := Config{
+ App: App{
+ WorkingDirectory: "var/",
+ MaxUsers: 512,
+ AllowRegistration: true,
+ MaxNickLen: 15,
+ MenuMaxIdleTime: 600,
+ PostLoginCommands: []string{
+ "mkdir %w/userdata/%u",
+ "mkdir %w/userdata/%u/dumplog",
+ "mkdir %w/userdata/%u/ttyrec",
+ },
+ },
+ Menus: []Menu{
+ Menu{
+ Banner: "Shell Game Launcher - Anonymous access%n======================================",
+ XOffset: 5,
+ YOffset: 2,
+ MenuEntries: []MenuEntry{
+ MenuEntry{
+ Key: "l",
+ Label: "login",
+ Action: "login",
+ },
+ MenuEntry{
+ Key: "r",
+ Label: "register",
+ Action: "register",
+ },
+ MenuEntry{
+ Key: "w",
+ Label: "watch",
+ Action: "watch_menu",
+ },
+ MenuEntry{
+ Key: "s",
+ Label: "scores",
+ Action: "scores",
+ },
+ MenuEntry{
+ Key: "q",
+ Label: "quit",
+ Action: "quit",
+ },
+ },
+ },
+ Menu{
+ Banner: "Shell Game Launcher%n===================",
+ XOffset: 5,
+ YOffset: 2,
+ MenuEntries: []MenuEntry{
+ MenuEntry{
+ Key: "p",
+ Label: "play Nethack 3.7",
+ Action: "play nethack3.7",
+ },
+ MenuEntry{
+ Key: "o",
+ Label: "edit game options",
+ Action: "options",
+ },
+ MenuEntry{
+ Key: "w",
+ Label: "watch",
+ Action: "watch_menu",
+ },
+ MenuEntry{
+ Key: "s",
+ Label: "scores",
+ Action: "scores",
+ },
+ MenuEntry{
+ Key: "q",
+ Label: "quit",
+ Action: "quit",
+ },
+ },
+ },
+ },
+ Games: map[string]Game{
+ "nethack3.7": Game{
+ ChrootPath: "/opt/nethack",
+ FileMode: "0666",
+ },
+ },
+ }
+ if err != nil || !reflect.DeepEqual(want, config) {
+ t.Fatalf("complete example failed:\nerror %v\nwant:%+v\ngot: %+v", err, want, config)
+ }
+}
diff --git a/config/game.go b/config/game.go
new file mode 100644
index 0000000..0eea917
--- /dev/null
+++ b/config/game.go
@@ -0,0 +1,11 @@
+package config
+
+// Game struct containers the configuration for a game
+type Game struct {
+ // ChrootPath is the chroot path for the game
+ ChrootPath string `yaml:"ChrootPath"`
+ // FileMode is the file mode to use when copying files
+ FileMode string `yaml:"FileMode"`
+ // Commands is the command list
+ Commands []string `yaml:"Commands"`
+}
diff --git a/config/menu.go b/config/menu.go
new file mode 100644
index 0000000..2913be2
--- /dev/null
+++ b/config/menu.go
@@ -0,0 +1,23 @@
+package config
+
+// Menu struct describes a screen menu
+type Menu struct {
+ // Banner is the banner to display before the menu
+ Banner string `yaml:"Banner"`
+ // XOffset is the X offset between the banner and the menu
+ XOffset int `yaml:"XOffset"`
+ // YOffset is the Y offset between the banner and the menu
+ YOffset int `yaml:"YOffset"`
+ // Commands is the list of commands in the menu
+ MenuEntries []MenuEntry `yaml:"MenuEntries"`
+}
+
+// MenuEntry struct describes a menu entry
+type MenuEntry struct {
+ // Key is the key associated with the action. We need to store it as a string because of how yaml unmarshal works
+ Key string `yaml:"Key"`
+ // Label is the text displayed on the menu
+ Label string `yaml:"Label"`
+ // Action is the action executed when the menu entry is selected
+ Action string `yaml:"Action"`
+}
diff --git a/config/test_data/invalid_yaml b/config/test_data/invalid_yaml
new file mode 100644
index 0000000..db1ddad
--- /dev/null
+++ b/config/test_data/invalid_yaml
@@ -0,0 +1 @@
+blargh(ads)