added gotify integration for join&leave

This commit is contained in:
Johannes Bülow 2025-10-08 20:29:42 +02:00
parent 090e35e46c
commit 13c0fee8ba
Signed by: jmb
GPG key ID: B56971CF7B8F83A6
7 changed files with 126 additions and 2 deletions

1
.gitignore vendored
View file

@ -1,2 +1,3 @@
mcd mcd
*.swp *.swp
tmp/*

4
Makefile Normal file
View file

@ -0,0 +1,4 @@
test:
go build -o tmp/mcd .
cp mcd.toml tmp/mcd.toml
cd tmp && ./mcd

47
cmd/con.go Normal file
View file

@ -0,0 +1,47 @@
/*
Copyright © 2025 Johannes Bülow <johannes.buelow@jmbit.de>
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 <http://www.gnu.org/licenses/>.
*/
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")
}

View file

@ -13,7 +13,7 @@ func InitConfig(cfgFile string) func() {
// Use config file from the flag. // Use config file from the flag.
viper.SetConfigFile(cfgFile) viper.SetConfigFile(cfgFile)
} else { } 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.AddConfigPath(".")
viper.SetConfigType("toml") viper.SetConfigType("toml")
viper.SetConfigName("mcd") viper.SetConfigName("mcd")
@ -29,5 +29,14 @@ func InitConfig(cfgFile string) func() {
viper.SetDefault("java.path", "/usr/bin/java") viper.SetDefault("java.path", "/usr/bin/java")
viper.SetDefault("java.args", []string{"-Xms2G", "-Xmx3G"}) viper.SetDefault("java.args", []string{"-Xms2G", "-Xmx3G"})
viper.SetDefault("server.jar", "./server.jar") 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()
} }
} }

52
internal/gotify/gotify.go Normal file
View file

@ -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")))
}
}

View file

@ -10,6 +10,7 @@ import (
"os/signal" "os/signal"
"syscall" "syscall"
"git.jmbit.de/jmb/mcd/internal/gotify"
"github.com/spf13/viper" "github.com/spf13/viper"
) )
@ -20,6 +21,8 @@ func RunService() {
args = append(args, viper.GetString("server.jar")) args = append(args, viper.GetString("server.jar"))
args = append(args, "--nogui") args = append(args, "--nogui")
log.Println("Java: ", viper.GetString("java.path"), " Args: ", args) 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...) cmd := exec.Command(viper.GetString("java.path"), args...)
@ -46,7 +49,11 @@ func RunService() {
go func() { go func() {
sc := bufio.NewScanner(stdout) sc := bufio.NewScanner(stdout)
for sc.Scan() { 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)
} }
}() }()

View file

@ -3,3 +3,7 @@ path = "/usr/bin/java"
args = ["-Xms2G", "-Xmx3G"] args = ["-Xms2G", "-Xmx3G"]
[server] [server]
jar = "./server.jar" jar = "./server.jar"
[gotify]
enabled = true
url = "https://gotify.jmbfountain.de/"
token = "A2Bt_.Ii-kh8yEy"