diff --git a/.gitignore b/.gitignore index 9e450c4..ff96c43 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ mcd *.swp +tmp/* diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..7d120ea --- /dev/null +++ b/Makefile @@ -0,0 +1,4 @@ +test: + go build -o tmp/mcd . + cp mcd.toml tmp/mcd.toml + cd tmp && ./mcd diff --git a/cmd/con.go b/cmd/con.go new file mode 100644 index 0000000..44708b5 --- /dev/null +++ b/cmd/con.go @@ -0,0 +1,47 @@ +/* +Copyright © 2025 Johannes Bülow + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +package cmd + +import ( + "fmt" + + "github.com/spf13/cobra" +) + +// conCmd represents the con command +var conCmd = &cobra.Command{ + Use: "con", + Short: "Attach to the server Console", + Long: `Connects to the console of an mcd-ran server.`, + Run: func(cmd *cobra.Command, args []string) { + fmt.Println("con called") + }, +} + +func init() { + rootCmd.AddCommand(conCmd) + + // Here you will define your flags and configuration settings. + + // Cobra supports Persistent Flags which will work for this command + // and all subcommands, e.g.: + // conCmd.PersistentFlags().String("foo", "", "A help for foo") + + // Cobra supports local flags which will only run when this command + // is called directly, e.g.: + // conCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") +} diff --git a/internal/config/config.go b/internal/config/config.go index d4e84e6..900e195 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -13,7 +13,7 @@ func InitConfig(cfgFile string) func() { // Use config file from the flag. viper.SetConfigFile(cfgFile) } else { - // Search config in home directory with name ".mcd" (without extension). + // Search config in home directory with name "mcd.toml" (without extension). viper.AddConfigPath(".") viper.SetConfigType("toml") viper.SetConfigName("mcd") @@ -29,5 +29,14 @@ func InitConfig(cfgFile string) func() { viper.SetDefault("java.path", "/usr/bin/java") viper.SetDefault("java.args", []string{"-Xms2G", "-Xmx3G"}) viper.SetDefault("server.jar", "./server.jar") + viper.SetDefault("gotify.enabled", false) + viper.SetDefault("gotify.url", "https://gotify.example.com/") + viper.SetDefault("gotify.token", "") + viper.SetDefault("gotify.join", true) + viper.SetDefault("gotify.leave", true) + viper.SetDefault("gotify.name", "mcd") + + //Automatically reload config + viper.WatchConfig() } } diff --git a/internal/gotify/gotify.go b/internal/gotify/gotify.go new file mode 100644 index 0000000..cbf4138 --- /dev/null +++ b/internal/gotify/gotify.go @@ -0,0 +1,52 @@ +package gotify + +import ( + "fmt" + "log" + "net/http" + "net/url" + "strings" + + "github.com/spf13/viper" +) + + +func sendNotification(msg string, title string) error { + if viper.GetBool("gotify.enabled") == false { + return nil + } + gUrl, err := url.Parse(viper.GetString("gotify.url")) + if err != nil { + log.Println("error parsing gotify url") + return err + } + gUrl.Path, err = url.JoinPath(gUrl.Path, "message") + if err != nil { + log.Println("error /message to gotify url") + return err + } + gUrl.RawQuery = fmt.Sprintf("token=%s", viper.GetString("gotify.token")) + resp, err := http.PostForm(gUrl.String(), url.Values{ + "message": {msg}, + "title": {title}, + }) + if err != nil { + log.Println("Error sending gotify message: ", err) + return err + } else { + log.Printf("Gotify: %s title: %s msg=%s\n", resp.Status, title, msg) + return nil + } +} + +func PlayerJoin(text string) { + if strings.Contains(text, "joined the game") && viper.GetBool("gotify.join") { + sendNotification(text, fmt.Sprintf("%s: Player joined", viper.GetString("gotify.name"))) + } +} + +func PlayerLeave(text string) { + if strings.Contains(text, "left the game") && viper.GetBool("gotify.leave") { + sendNotification(text, fmt.Sprintf("%s: Player left", viper.GetString("gotify.name"))) + } +} diff --git a/internal/service/service.go b/internal/service/service.go index f101c93..2bdfcdf 100644 --- a/internal/service/service.go +++ b/internal/service/service.go @@ -10,6 +10,7 @@ import ( "os/signal" "syscall" + "git.jmbit.de/jmb/mcd/internal/gotify" "github.com/spf13/viper" ) @@ -20,6 +21,8 @@ func RunService() { args = append(args, viper.GetString("server.jar")) args = append(args, "--nogui") log.Println("Java: ", viper.GetString("java.path"), " Args: ", args) + log.Println("Gotify-Notifications", viper.GetString("gotify.enabled")) + log.Println("Gotify-Host", viper.GetString("gotify.url")) cmd := exec.Command(viper.GetString("java.path"), args...) @@ -46,7 +49,11 @@ func RunService() { go func() { sc := bufio.NewScanner(stdout) for sc.Scan() { - fmt.Fprintln(os.Stdout, sc.Text()) + text := sc.Text() + go gotify.PlayerJoin(text) + go gotify.PlayerLeave(text) + + fmt.Fprintln(os.Stdout, text) } }() diff --git a/mcd.toml b/mcd.toml index b029364..065bdc1 100644 --- a/mcd.toml +++ b/mcd.toml @@ -3,3 +3,7 @@ path = "/usr/bin/java" args = ["-Xms2G", "-Xmx3G"] [server] jar = "./server.jar" +[gotify] +enabled = true +url = "https://gotify.jmbfountain.de/" +token = "A2Bt_.Ii-kh8yEy"