diff --git a/cmd/bot/config/config.go b/cmd/bot/config/config.go index 77285ec..c15a740 100644 --- a/cmd/bot/config/config.go +++ b/cmd/bot/config/config.go @@ -13,9 +13,11 @@ import ( type Configuration struct { GuildID string `json:"guild-id"` BotToken string `json:"bot-token"` - RealWeatherPath string `json:"real-weather-path"` - RealWeatherLog string `json:"real-weather-log-path"` Log string `json:"log"` + Instances []struct { + RealWeatherPath string `json:"real-weather-path"` + RealWeatherLog string `json:"real-weather-log-path"` + } `json:"instances"` } //go:embed config.json @@ -50,8 +52,43 @@ func init() { log.Fatalf("Error decoding config: %v", err) } - // remove exe from path - config.RealWeatherPath = filepath.Dir(config.RealWeatherPath) + // verify config values + var fatalBotConfig bool + + if config.GuildID == "" { + log.Println("Guild ID is required to be configured.") + fatalBotConfig = true + } + + if config.BotToken == "" { + log.Println("Bot token is required to be configured.") + fatalBotConfig = true + } + + if len(config.Instances) < 1 { + log.Println("At least one instance must be configured.") + fatalBotConfig = true + } + + // validate each instance + for i := range config.Instances { + config.Instances[i].RealWeatherPath = filepath.Dir(config.Instances[i].RealWeatherPath) + + if config.Instances[i].RealWeatherPath == "" { + log.Printf("Real Weather path is required to be configured for each instance (check #%d).", i+1) + fatalBotConfig = true + } + + if config.Instances[i].RealWeatherLog == "" { + log.Printf("Real Weather log path is required to be configured for each instance (check #%d).", i+1) + fatalBotConfig = true + } + } + + if fatalBotConfig { + log.Fatalf("One or more errors exist in your config. Please correct them then restart the bot!") + } + } func Get() Configuration { diff --git a/cmd/bot/config/config.json b/cmd/bot/config/config.json index b37228c..d7c3d4a 100644 --- a/cmd/bot/config/config.json +++ b/cmd/bot/config/config.json @@ -1,7 +1,11 @@ { "guild-id": "", "bot-token": "", - "real-weather-path": "", - "real-weather-log-path": "", - "log": "rwbot.log" + "log": "rwbot.log", + "instances": [ + { + "real-weather-path": "", + "real-weather-log-path": "" + } + ] } diff --git a/cmd/bot/handlers/lastmetar.go b/cmd/bot/handlers/lastmetar.go index 4416212..c8359bc 100644 --- a/cmd/bot/handlers/lastmetar.go +++ b/cmd/bot/handlers/lastmetar.go @@ -10,6 +10,8 @@ import ( "strings" dg "github.com/bwmarrin/discordgo" + + "github.com/evogelsa/DCS-real-weather/cmd/bot/config" ) type scanner struct { @@ -69,7 +71,7 @@ func (s *scanner) Line() (string, error) { var reMETAR = regexp.MustCompile(`^\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} METAR: (?P.*)`) -func LastMETAR(s *dg.Session, i *dg.InteractionCreate, rwLogPath string) { +func LastMETAR(s *dg.Session, i *dg.InteractionCreate) { const command = `/last-metar` log.Println(command, "called") defer timeCommand(command)() @@ -78,6 +80,15 @@ func LastMETAR(s *dg.Session, i *dg.InteractionCreate, rwLogPath string) { return } + cfg := config.Get() + + var server int64 + if len(cfg.Instances) > 1 { + server = getServer(i) + } + + rwLogPath := cfg.Instances[server].RealWeatherLog + f, err := os.Open(rwLogPath) if err != nil { log.Printf("Unable to open Real Weather log file: %v", err) diff --git a/cmd/bot/handlers/setweather.go b/cmd/bot/handlers/setweather.go index d8ca519..1fb0917 100644 --- a/cmd/bot/handlers/setweather.go +++ b/cmd/bot/handlers/setweather.go @@ -11,12 +11,13 @@ import ( dg "github.com/bwmarrin/discordgo" + "github.com/evogelsa/DCS-real-weather/cmd/bot/config" "github.com/evogelsa/DCS-real-weather/weather" ) var isICAO = regexp.MustCompile(`^[A-Z]{4}$`).MatchString -func SetWeather(s *dg.Session, i *dg.InteractionCreate, rwPath string) { +func SetWeather(s *dg.Session, i *dg.InteractionCreate) { const command = `/set-weather` log.Println(command, "called") defer timeCommand(command)() @@ -25,6 +26,15 @@ func SetWeather(s *dg.Session, i *dg.InteractionCreate, rwPath string) { return } + cfg := config.Get() + + var server int64 + if len(cfg.Instances) > 1 { + server = getServer(i) + } + + rwPath := cfg.Instances[server].RealWeatherPath + var data weather.WeatherData data.Data = make([]weather.Data, 1) diff --git a/cmd/bot/handlers/util.go b/cmd/bot/handlers/util.go index 6b53723..a12080d 100644 --- a/cmd/bot/handlers/util.go +++ b/cmd/bot/handlers/util.go @@ -92,3 +92,13 @@ func timeCommand(command string) func() { log.Printf("%s completed in %v", command, time.Since(start)) } } + +func getServer(i *dg.InteractionCreate) int64 { + for _, option := range i.ApplicationCommandData().Options { + if option.Name == "server" { + return option.IntValue() - 1 + } + } + log.Fatalf("Something went terribly wrong, report this as a bug :)") + return -1 +} diff --git a/cmd/bot/main.go b/cmd/bot/main.go index b25fc96..d9d990c 100644 --- a/cmd/bot/main.go +++ b/cmd/bot/main.go @@ -38,28 +38,6 @@ func init() { log.SetOutput(mw) } - - // verify bot config - var fatalBotConfig bool - - if cfg.GuildID == "" { - log.Println("Guild ID is required to be configured.") - fatalBotConfig = true - } - - if cfg.BotToken == "" { - log.Println("Bot token is required to be configured.") - fatalBotConfig = true - } - - if cfg.RealWeatherPath == "" { - log.Println("Real Weather path is required to be configured.") - fatalBotConfig = true - } - - if fatalBotConfig { - log.Fatalf("One or more errors exist in your config. Please correct them then rerun.") - } } var s *dg.Session @@ -236,15 +214,31 @@ var ( } commandHandlers = map[string]func(s *dg.Session, i *dg.InteractionCreate){ - "set-weather": func(s *dg.Session, i *dg.InteractionCreate) { - handlers.SetWeather(s, i, cfg.RealWeatherPath) - }, - "last-metar": func(s *dg.Session, i *dg.InteractionCreate) { - handlers.LastMETAR(s, i, cfg.RealWeatherLog) - }, + "set-weather": handlers.SetWeather, + "last-metar": handlers.LastMETAR, } ) +// adjust command signatures if using multi instances +func init() { + if len(cfg.Instances) > 1 { + for i := range commands { + commands[i].Options = append( + []*dg.ApplicationCommandOption{ + { + Type: dg.ApplicationCommandOptionInteger, + Name: "server", + Description: "which server instance to use (first instance is 1)", + Required: true, + }, + }, + commands[i].Options..., + ) + } + } +} + +// add command handlers func init() { s.AddHandler(func(s *dg.Session, i *dg.InteractionCreate) { if h, ok := commandHandlers[i.ApplicationCommandData().Name]; ok { @@ -286,7 +280,7 @@ func main() { for _, v := range commands { _, err := s.ApplicationCommandCreate(s.State.User.ID, guildID, v) if err != nil { - log.Printf("Failed to register command: %s", v.Name) + log.Printf("Failed to register command %s: %v", v.Name, err) } else { log.Printf("Registered command: %s", v.Name) }