Update to allow multiple servers by a config file

This commit is contained in:
Chandler Swift 2020-03-29 22:02:18 -05:00
parent 5621abe5e7
commit 64cd4dab40
2 changed files with 76 additions and 51 deletions

1
.gitignore vendored
View file

@ -1 +1,2 @@
factorio-site factorio-site
config.json

View file

@ -2,9 +2,10 @@ package main
import ( import (
"crypto/tls" "crypto/tls"
"flag" "encoding/json"
"fmt" "fmt"
"html/template" "html/template"
"io/ioutil"
"log" "log"
"net/http" "net/http"
@ -12,28 +13,57 @@ import (
"golang.org/x/crypto/acme/autocert" "golang.org/x/crypto/acme/autocert"
) )
type config struct {
Servers []server `json:"servers"`
}
type server struct {
Host string `json:"host"`
Port int `json:"port"`
RCONPort int `json:"rconport"`
RCONPassword string `json:"rconpassword"`
Title string `json:"title"`
Description string `json:"description"`
rconConnection *rcon.RemoteConsole
}
type serverData struct { type serverData struct {
IPAddr string IPAddr string
Port int Port int
Title string Title string
Players string Players string
Version string Version string
Description string
}
// rconCommand executes a command on the server, and returns the server's
// response as a string.
func (s server) rconCommand(command string) (response string, err error) {
_, err = s.rconConnection.Write(command)
if err != nil {
return "", err
}
response, _, err = s.rconConnection.Read()
if err != nil {
return "", err
}
return
} }
func main() { func main() {
serverAddr := flag.String("serverAddr", "localhost", "Server to check status of (optional; defaults to localhost") // Parse config file
serverPort := flag.Int("serverPort", 34196, "RCON port on the Factorio server (optional; defaults to 34196)") configData, err := ioutil.ReadFile("./config.json")
password := flag.String("password", "", "RCON password of the server (required)") if err != nil {
flag.Parse() log.Fatalf("Error reading config file: %v\n", err)
if *serverPort < 1 || *serverPort > 65535 {
fmt.Printf("Invalid server port %v\n", *serverPort)
return
} }
if *password == "" { var config config
fmt.Printf("Password flag is required")
err = json.Unmarshal(configData, &config)
if err != nil {
log.Fatalf("Error parsing config file: %v\n", err)
} }
fmt.Print("Parsing templates...\n") fmt.Print("Parsing templates...\n")
@ -42,46 +72,40 @@ func main() {
fmt.Printf("Error parsing HTML template: %v\n", err) fmt.Printf("Error parsing HTML template: %v\n", err)
} }
rconConnection, err := rcon.Dial(fmt.Sprintf("%v:%v", *serverAddr, *serverPort), *password) for _, server := range config.Servers {
if err != nil { server.rconConnection, err = rcon.Dial(fmt.Sprintf("%v:%v", server.Host, server.RCONPort), server.RCONPassword)
log.Fatalf("Error making RCON connection: %v", err) if err != nil {
log.Fatalf("Error making RCON connection to %v: %v", server.Title, err)
}
defer server.rconConnection.Close()
} }
defer rconConnection.Close()
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
_, err := rconConnection.Write("/players o")
if err != nil {
fmt.Print(w, "Error connecting to server")
return
}
playersOnline, _, err := rconConnection.Read()
if err != nil {
fmt.Print(w, "Error receiving data from server")
return
}
_, err = rconConnection.Write("/version")
if err != nil {
fmt.Print(w, "Error connecting to server")
return
}
version, _, err := rconConnection.Read()
if err != nil {
fmt.Print(w, "Error receiving data from server")
return
}
data := []serverData{} data := []serverData{}
data = append(data, serverData{
*serverAddr, for _, server := range config.Servers {
34197,
"Server with Bob's Mod, est. Feb 2020", playersOnline, err := server.rconCommand("/players o")
playersOnline, if err != nil {
version, log.Printf("Error executing players online command: %v\n", err)
}) }
version, err := server.rconCommand("/version")
if err != nil {
log.Printf("Error executing version command: %v\n", err)
}
data = append(data, serverData{
server.Host,
server.Port,
server.Title,
playersOnline,
version,
server.Description,
})
}
t.Execute(w, data) t.Execute(w, data)
}) })