2019-12-13 07:13:25 +00:00
package config
import (
2022-01-09 00:27:19 +00:00
"bytes"
"fmt"
"io"
2021-09-06 01:07:49 +00:00
"os"
2022-01-09 00:27:19 +00:00
"runtime"
2022-01-08 22:29:51 +00:00
2022-01-09 00:27:19 +00:00
"github.com/rs/zerolog"
"github.com/spf13/viper"
2019-12-13 07:13:25 +00:00
)
2022-01-09 00:27:19 +00:00
// generic vars
var (
f * os . File
err error
noColorForce = false
customconfig = false
home string
prefConfigLocation string
snek * viper . Viper
)
// exported generic vars
var (
// Debug is the value of our debug on/off toggle as per the current configuration.
Debug bool
// Filename returns the current location of our toml config file.
Filename string
)
func init ( ) {
if home , err = os . UserHomeDir ( ) ; err != nil {
panic ( err )
}
prefConfigLocation = home + "/.config/" + Title
snek = viper . New ( )
2021-09-06 01:07:49 +00:00
}
2022-01-09 00:27:19 +00:00
func writeConfig ( ) {
if runtime . GOOS == "windows" {
newconfig := Title + "-config"
snek . SetConfigName ( newconfig )
if err = snek . MergeInConfig ( ) ; err != nil {
if err = snek . SafeWriteConfigAs ( newconfig + ".toml" ) ; err != nil {
fmt . Println ( err . Error ( ) )
os . Exit ( 1 )
}
}
return
}
if _ , err := os . Stat ( prefConfigLocation ) ; os . IsNotExist ( err ) {
if err = os . MkdirAll ( prefConfigLocation , 0 o755 ) ; err != nil {
println ( "error writing new config: " + err . Error ( ) )
os . Exit ( 1 )
}
}
newconfig := prefConfigLocation + "/" + "config.toml"
if err = snek . SafeWriteConfigAs ( newconfig ) ; err != nil {
fmt . Println ( err . Error ( ) )
os . Exit ( 1 )
}
Filename = newconfig
2019-12-13 07:13:25 +00:00
}
2022-01-09 00:27:19 +00:00
// LoadConfig will initialize our toml configuration engine and define our default configuration values which can be written to a new configuration file if desired
func LoadConfig ( ) {
snek . SetConfigType ( "toml" )
snek . SetConfigName ( "config" )
argParse ( )
if customconfig {
associateExportedVariables ( )
return
}
setDefaults ( )
for _ , loc := range getConfigPaths ( ) {
snek . AddConfigPath ( loc )
}
if err = snek . MergeInConfig ( ) ; err != nil {
writeConfig ( )
}
if len ( Filename ) < 1 {
Filename = snek . ConfigFileUsed ( )
}
associateExportedVariables ( )
2021-09-06 01:07:49 +00:00
}
2022-01-09 00:27:19 +00:00
func getConfigPaths ( ) ( paths [ ] string ) {
paths = append ( paths , "./" )
2021-09-06 01:07:49 +00:00
2022-01-09 00:27:19 +00:00
if runtime . GOOS != "windows" {
paths = append ( paths ,
prefConfigLocation , "/etc/" + Title + "/" , "../" , "../../" )
}
2019-12-13 07:13:25 +00:00
2022-01-09 00:27:19 +00:00
return
}
2019-12-13 07:13:25 +00:00
2022-01-09 00:27:19 +00:00
func loadCustomConfig ( path string ) {
if f , err = os . Open ( path ) ; err != nil {
println ( "Error opening specified config file: " + path )
panic ( "config file open fatal error: " + err . Error ( ) )
}
buf , err := io . ReadAll ( f )
err2 := snek . ReadConfig ( bytes . NewBuffer ( buf ) )
switch {
case err != nil :
fmt . Println ( "config file read fatal error: " , err . Error ( ) )
case err2 != nil :
fmt . Println ( "config file read fatal error: " , err2 . Error ( ) )
default :
break
}
customconfig = true
}
2021-09-06 01:07:49 +00:00
2022-01-09 00:27:19 +00:00
func processOpts ( ) {
// string options and their exported variables
stringOpt := map [ string ] * string {
"http.bind_addr" : & HTTPBind ,
"http.bind_port" : & HTTPPort ,
"logger.directory" : & logDir ,
"data.directory" : & DataDirectory ,
"habbo.bind" : & HabboBind ,
}
// string slice options and their exported variables
strSliceOpt := map [ string ] * [ ] string { }
2021-09-06 01:07:49 +00:00
2022-01-09 00:27:19 +00:00
// bool options and their exported variables
boolOpt := map [ string ] * bool {
"logger.debug" : & Debug ,
"logger.nocolor" : & NoColor ,
}
// integer options and their exported variables
intOpt := map [ string ] * int {
"habbo.port" : & HabboPort ,
"habbo.maxconns" : & MaxConns ,
2019-12-13 07:13:25 +00:00
}
2022-01-09 00:27:19 +00:00
for key , opt := range stringOpt {
* opt = snek . GetString ( key )
}
for key , opt := range strSliceOpt {
* opt = snek . GetStringSlice ( key )
}
for key , opt := range boolOpt {
* opt = snek . GetBool ( key )
}
for key , opt := range intOpt {
* opt = snek . GetInt ( key )
}
2019-12-13 07:13:25 +00:00
}
2021-09-06 01:07:49 +00:00
2022-01-09 00:27:19 +00:00
func associateExportedVariables ( ) {
processOpts ( )
if noColorForce {
NoColor = true
}
if Debug {
zerolog . SetGlobalLevel ( zerolog . DebugLevel )
2021-09-06 01:07:49 +00:00
}
}