2020-03-19 23:20:59 -05:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2020-03-29 21:05:34 -05:00
|
|
|
"crypto/tls"
|
2020-03-19 23:20:59 -05:00
|
|
|
"flag"
|
|
|
|
"fmt"
|
|
|
|
"html/template"
|
2020-03-19 23:40:23 -05:00
|
|
|
"log"
|
2020-03-19 23:20:59 -05:00
|
|
|
"net/http"
|
2020-03-19 23:40:23 -05:00
|
|
|
|
|
|
|
"github.com/james4k/rcon"
|
2020-03-29 21:05:34 -05:00
|
|
|
"golang.org/x/crypto/acme/autocert"
|
2020-03-19 23:20:59 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
type serverData struct {
|
|
|
|
IPAddr string
|
2020-03-20 11:37:17 -05:00
|
|
|
Port int
|
2020-03-19 23:20:59 -05:00
|
|
|
Title string
|
|
|
|
Players string
|
|
|
|
}
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
|
2020-03-29 21:02:32 -05:00
|
|
|
serverAddr := flag.String("serverAddr", "localhost", "Server to check status of (optional; defaults to localhost")
|
|
|
|
serverPort := flag.Int("serverPort", 34196, "RCON port on the Factorio server (optional; defaults to 34196)")
|
2020-03-19 23:40:23 -05:00
|
|
|
password := flag.String("password", "", "RCON password of the server (required)")
|
2020-03-19 23:20:59 -05:00
|
|
|
flag.Parse()
|
|
|
|
|
2020-03-29 21:02:32 -05:00
|
|
|
if *serverPort < 1 || *serverPort > 65535 {
|
|
|
|
fmt.Printf("Invalid server port %v\n", *serverPort)
|
2020-03-19 23:20:59 -05:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2020-03-19 23:40:23 -05:00
|
|
|
if *password == "" {
|
|
|
|
fmt.Printf("Password flag is required")
|
|
|
|
}
|
|
|
|
|
2020-03-19 23:20:59 -05:00
|
|
|
fmt.Print("Parsing templates...\n")
|
|
|
|
t, err := template.ParseFiles("templates/index.html")
|
|
|
|
if err != nil {
|
|
|
|
fmt.Printf("Error parsing HTML template: %v\n", err)
|
|
|
|
}
|
|
|
|
|
2020-03-19 23:40:23 -05:00
|
|
|
rconConnection, err := rcon.Dial(fmt.Sprintf("%v:%v", *serverAddr, *serverPort), *password)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalf("Error making RCON connection: %v", err)
|
2020-03-19 23:20:59 -05:00
|
|
|
}
|
2020-03-19 23:40:23 -05:00
|
|
|
defer rconConnection.Close()
|
2020-03-19 23:20:59 -05:00
|
|
|
|
|
|
|
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
2020-03-19 23:40:23 -05:00
|
|
|
|
|
|
|
_, 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
|
|
|
|
}
|
|
|
|
|
|
|
|
data := serverData{
|
|
|
|
*serverAddr,
|
2020-03-20 11:37:17 -05:00
|
|
|
34197,
|
2020-03-19 23:40:23 -05:00
|
|
|
"Server with Bob's Mod, est. Feb 2020",
|
|
|
|
playersOnline,
|
|
|
|
}
|
|
|
|
|
2020-03-19 23:20:59 -05:00
|
|
|
t.Execute(w, data)
|
|
|
|
})
|
|
|
|
|
2020-03-29 21:05:34 -05:00
|
|
|
certManager := autocert.Manager{
|
|
|
|
Prompt: autocert.AcceptTOS,
|
|
|
|
HostPolicy: autocert.HostWhitelist("factorio.blackolivepineapple.pizza"), // TODO: add config
|
|
|
|
Cache: autocert.DirCache("certs"),
|
|
|
|
}
|
|
|
|
|
|
|
|
server := &http.Server{
|
|
|
|
Addr: ":https",
|
|
|
|
TLSConfig: &tls.Config{
|
|
|
|
GetCertificate: certManager.GetCertificate,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
go http.ListenAndServe(":http", certManager.HTTPHandler(nil)) // Handler for LetsEncrypt
|
|
|
|
|
2020-03-29 21:02:32 -05:00
|
|
|
fmt.Println("Serving...")
|
2020-03-29 21:05:34 -05:00
|
|
|
server.ListenAndServeTLS("", "") // Key/cert come from server.TLSConfig
|
2020-03-19 23:20:59 -05:00
|
|
|
|
|
|
|
}
|