diff --git a/d2core/d2asset/archive_manager.go b/d2core/d2asset/archive_manager.go index c358806ec..ef4a9a5af 100644 --- a/d2core/d2asset/archive_manager.go +++ b/d2core/d2asset/archive_manager.go @@ -17,7 +17,7 @@ type archiveEntry struct { type archiveManager struct { cache *d2common.Cache - config *d2config.Configuration + config d2config.Configuration entries []archiveEntry mutex sync.Mutex } @@ -26,7 +26,7 @@ const ( archiveBudget = 1024 * 1024 * 512 ) -func createArchiveManager(config *d2config.Configuration) *archiveManager { +func createArchiveManager(config d2config.Configuration) *archiveManager { return &archiveManager{cache: d2common.CreateCache(archiveBudget), config: config} } diff --git a/d2core/d2asset/file_manager.go b/d2core/d2asset/file_manager.go index 850ea24df..c8b50b9bb 100644 --- a/d2core/d2asset/file_manager.go +++ b/d2core/d2asset/file_manager.go @@ -16,10 +16,10 @@ const ( type fileManager struct { cache *d2common.Cache archiveManager *archiveManager - config *d2config.Configuration + config d2config.Configuration } -func createFileManager(config *d2config.Configuration, archiveManager *archiveManager) *fileManager { +func createFileManager(config d2config.Configuration, archiveManager *archiveManager) *fileManager { return &fileManager{d2common.CreateCache(fileBudget), archiveManager, config} } diff --git a/d2core/d2config/config.go b/d2core/d2config/config.go index fa4e8e210..1510e2fc9 100644 --- a/d2core/d2config/config.go +++ b/d2core/d2config/config.go @@ -1,12 +1,15 @@ package d2config import ( + "encoding/json" + "io/ioutil" + "os" "os/user" "path" "runtime" ) -func getDefaultConfiguration() *Configuration { +func getDefaultConfig() *Configuration { config := &Configuration{ Language: "ENG", FullScreen: false, @@ -61,3 +64,59 @@ func getDefaultConfiguration() *Configuration { return config } + +func getDefaultConfigPath() string { + if configDir, err := os.UserConfigDir(); err == nil { + return path.Join(configDir, "OpenDiablo2", "config.json") + } + + return getLocalConfigPath() +} + +func getLocalConfigPath() string { + return path.Join(path.Dir(os.Args[0]), "config.json") +} + +func load(configPath string) error { + configFile, err := os.Open(configPath) + defer configFile.Close() + + if err != nil { + return err + } + + data, err := ioutil.ReadAll(configFile) + if err != nil { + return err + } + + if err := json.Unmarshal(data, &singleton); err != nil { + return err + } + + return nil +} + +func save(configPath string) error { + configDir := path.Dir(configPath) + if err := os.MkdirAll(configDir, 0755); err != nil { + return err + } + + configFile, err := os.Create(configPath) + defer configFile.Close() + if err != nil { + return err + } + + data, err := json.MarshalIndent(singleton, "", " ") + if err != nil { + return err + } + + if _, err := configFile.Write(data); err != nil { + return err + } + + return nil +} diff --git a/d2core/d2config/d2config.go b/d2core/d2config/d2config.go index a4e16068b..56531dfdf 100644 --- a/d2core/d2config/d2config.go +++ b/d2core/d2config/d2config.go @@ -1,17 +1,7 @@ package d2config import ( - "encoding/json" - "errors" "log" - "os" - "path" - "path/filepath" -) - -var ( - ErrNotInit = errors.New("configuration is not initialized") - ErrWasInit = errors.New("configuration has already been initialized") ) // Configuration defines the configuration for the engine, loaded from config.json @@ -29,89 +19,54 @@ type Configuration struct { BgmVolume float64 } -var singleton *Configuration +var singleton *Configuration = getDefaultConfig() -func Initialize() error { - verifyNotInit() - - configDir, err := os.UserConfigDir() - if err != nil { - singleton = getDefaultConfiguration() - return nil +func Load() error { + configPaths := []string{ + getLocalConfigPath(), + getDefaultConfigPath(), } - configDir = path.Join(configDir, "OpenDiablo2") - configPath := path.Join(configDir, "config.json") - log.Printf("loading configuration file from %s...", configPath) - configFile, err := os.Open(configPath) - - if err == nil { - var config Configuration - decoder := json.NewDecoder(configFile) - defer configFile.Close() - if err := decoder.Decode(&config); err == nil { - singleton = &config - return nil + var loaded bool + for _, configPath := range configPaths { + log.Printf("loading configuration file from %s...", configPath) + if err := load(configPath); err == nil { + loaded = true + break } - } else { - log.Printf("configuration file not found, writing default") - os.MkdirAll(filepath.Dir(configPath), os.ModePerm) - configFile, err := os.Create(configPath) - if err == nil { - encoder := json.NewEncoder(configFile) - defer configFile.Close() - encoder.Encode(getDefaultConfiguration()) - } else { - log.Printf("failed to write default configuration (%s)", err) + } + + if !loaded { + log.Println("failed to load configuration file, saving default configuration...") + if err := Save(); err != nil { + return err } } - singleton = getDefaultConfiguration() return nil } func Save() error { - verifyWasInit() - - configDir, err := os.UserConfigDir() - if err != nil { - return err - } - - configDir = path.Join(configDir, "OpenDiablo2") - if err := os.MkdirAll(configDir, 0755); err != nil { - return err - } - - configPath := path.Join(configDir, "config.json") + configPath := getDefaultConfigPath() log.Printf("saving configuration file to %s...", configPath) - configFile, err := os.Create(configPath) - if err != nil { - return err - } - encoder := json.NewEncoder(configFile) - encoder.SetIndent("", " ") - if err := encoder.Encode(singleton); err != nil { - return err + var err error + if err = save(configPath); err != nil { + log.Printf("failed to write configuration file (%s)", err) } - return nil + return err } -func Get() *Configuration { - verifyWasInit() - return singleton +func Set(config Configuration) { + temp := config + singleton = &temp } -func verifyWasInit() { +func Get() Configuration { if singleton == nil { - panic(ErrNotInit) + panic("configuration is not initialized") } -} -func verifyNotInit() { - if singleton != nil { - panic(ErrWasInit) - } + return *singleton } diff --git a/main.go b/main.go index f57fa607d..45963ca08 100644 --- a/main.go +++ b/main.go @@ -76,7 +76,7 @@ func initialize() error { singleton.timeScale = 1.0 singleton.lastTime = d2common.Now() - if err := d2config.Initialize(); err != nil { + if err := d2config.Load(); err != nil { return err }