Update for Minecraft
Using template from the PHP version of this site, from 2016/2017! $ ls -Alh -rw-r--r-- 1 chandler chandler 1.5K Jan 4 2017 index.php
This commit is contained in:
parent
8dd1b7b58d
commit
f17074d22d
7 changed files with 93 additions and 110 deletions
165
factorio-site.go
165
factorio-site.go
|
|
@ -1,165 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"github.com/james4k/rcon"
|
||||
"golang.org/x/crypto/acme/autocert"
|
||||
)
|
||||
|
||||
type config struct {
|
||||
Title string `json:"title"`
|
||||
Content string `json:"content"`
|
||||
Servers []server `json:"servers"`
|
||||
UseTLS bool `json:"useTLS"`
|
||||
TLSHostname string `json:"tlshostname"`
|
||||
ServerPort int `json:"serverport"`
|
||||
BackupDir string `json:"backupDir"`
|
||||
}
|
||||
|
||||
type server struct {
|
||||
Host string `json:"host"` // for display only
|
||||
Port int `json:"port"`
|
||||
RCONHost string `json:"rconhost"` // not displayed, but used to connect; leave blank for no RCON connection
|
||||
RCONPort int `json:"rconport"`
|
||||
RCONPassword string `json:"rconpassword"`
|
||||
Title string `json:"title"` // TODO: get this from RCON?
|
||||
Description string `json:"description"` // TODO: get this from RCON?
|
||||
Version string // Populated by RCON
|
||||
Players string // Populated by RCON
|
||||
rconConnection *rcon.RemoteConsole
|
||||
}
|
||||
|
||||
type pageData struct {
|
||||
Title string
|
||||
Content string
|
||||
Servers []server
|
||||
}
|
||||
|
||||
// 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() {
|
||||
|
||||
// Parse config file
|
||||
configData, err := ioutil.ReadFile("./config.json")
|
||||
if err != nil {
|
||||
log.Fatalf("Error reading config file: %v\n", err)
|
||||
}
|
||||
|
||||
var config config
|
||||
|
||||
err = json.Unmarshal(configData, &config)
|
||||
if err != nil {
|
||||
log.Fatalf("Error parsing config file: %v\n", err)
|
||||
}
|
||||
|
||||
serveBackups := true
|
||||
if stat, err := os.Stat(config.BackupDir); os.IsNotExist(err) || !stat.IsDir() {
|
||||
log.Printf("Backup directory %v does not exist; not serving backups.", config.BackupDir)
|
||||
serveBackups = false
|
||||
}
|
||||
|
||||
data := pageData{}
|
||||
data.Title = config.Title
|
||||
data.Content = config.Content
|
||||
data.Servers = config.Servers
|
||||
|
||||
// Set up templates
|
||||
fmt.Print("Parsing templates...\n")
|
||||
t, err := template.ParseFiles("templates/index.html")
|
||||
if err != nil {
|
||||
log.Fatalf("Error parsing HTML template: %v\n", err)
|
||||
}
|
||||
|
||||
// Connect to RCON servers
|
||||
for i := range config.Servers {
|
||||
s := config.Servers[i]
|
||||
if s.RCONHost != "" {
|
||||
config.Servers[i].rconConnection, err = rcon.Dial(fmt.Sprintf("%v:%v", s.RCONHost, s.RCONPort), s.RCONPassword)
|
||||
if err != nil {
|
||||
log.Fatalf("Error making RCON connection to %v: %v", s.Title, err)
|
||||
}
|
||||
defer config.Servers[i].rconConnection.Close()
|
||||
}
|
||||
}
|
||||
|
||||
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// Update servers with current data
|
||||
for i, s := range config.Servers {
|
||||
if s.rconConnection != nil {
|
||||
config.Servers[i].Players, err = s.rconCommand("/players o")
|
||||
if err != nil {
|
||||
log.Printf("Error executing players online command: %v\n", err)
|
||||
}
|
||||
|
||||
config.Servers[i].Version, err = s.rconCommand("/version")
|
||||
if err != nil {
|
||||
log.Printf("Error executing version command: %v\n", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
err = t.Execute(w, data)
|
||||
if err != nil {
|
||||
log.Printf("Error executing template: %v\n", err)
|
||||
}
|
||||
})
|
||||
|
||||
// Serve backup directory
|
||||
if serveBackups { // TODO: also remove HTML if disabled
|
||||
http.Handle("/backups/", http.StripPrefix("/backups/", http.FileServer(http.Dir(config.BackupDir))))
|
||||
}
|
||||
|
||||
if config.UseTLS {
|
||||
|
||||
certManager := autocert.Manager{
|
||||
Prompt: autocert.AcceptTOS,
|
||||
HostPolicy: autocert.HostWhitelist(config.TLSHostname),
|
||||
Cache: autocert.DirCache("certs"),
|
||||
}
|
||||
|
||||
srv := &http.Server{
|
||||
Addr: ":https",
|
||||
TLSConfig: &tls.Config{
|
||||
GetCertificate: certManager.GetCertificate,
|
||||
},
|
||||
}
|
||||
|
||||
go http.ListenAndServe(":http", certManager.HTTPHandler(nil)) // Handler for LetsEncrypt
|
||||
|
||||
if config.ServerPort == 0 { // Value not set in JSON
|
||||
config.ServerPort = 443
|
||||
}
|
||||
fmt.Printf("Serving HTTPS on port %v...\n", config.ServerPort)
|
||||
srv.ListenAndServeTLS("", "") // Key/cert come from srv.TLSConfig
|
||||
|
||||
} else {
|
||||
if config.ServerPort == 0 { // Value not set in JSON
|
||||
config.ServerPort = 80
|
||||
}
|
||||
fmt.Printf("Serving HTTP on port %v...\n", config.ServerPort)
|
||||
http.ListenAndServe(fmt.Sprintf(":%v", config.ServerPort), nil)
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue