From 484734ab36b06a9e6d35348e357312d99522302c Mon Sep 17 00:00:00 2001 From: Julien Dessaux Date: Wed, 23 Dec 2020 12:01:05 +0100 Subject: Implemented the configuration file format --- config/app.go | 17 +++++++ config/config.go | 31 ++++++++++++ config/config_test.go | 107 ++++++++++++++++++++++++++++++++++++++++++ config/game.go | 11 +++++ config/menu.go | 23 +++++++++ config/test_data/invalid_yaml | 1 + 6 files changed, 190 insertions(+) create mode 100644 config/app.go create mode 100644 config/config.go create mode 100644 config/config_test.go create mode 100644 config/game.go create mode 100644 config/menu.go create mode 100644 config/test_data/invalid_yaml (limited to 'config') 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) -- cgit v1.2.3