minecraft-site/minecraft-site.go

150 lines
3.6 KiB
Go
Raw Permalink Normal View History

2020-03-19 23:20:59 -05:00
package main
import (
2020-03-29 21:05:34 -05:00
"crypto/tls"
_ "embed"
"encoding/json"
2020-03-19 23:20:59 -05:00
"fmt"
"html/template"
2020-03-19 23:40:23 -05:00
"log"
2020-03-19 23:20:59 -05:00
"net/http"
2020-04-17 19:53:02 -05:00
"os"
2020-03-19 23:40:23 -05:00
"github.com/dreamscached/minequery/v2"
2020-03-29 21:05:34 -05:00
"golang.org/x/crypto/acme/autocert"
2020-03-19 23:20:59 -05:00
)
type config struct {
Title string `json:"title"`
Content template.HTML `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"`
Port int `json:"port"`
Status *minequery.Status17
}
2021-02-13 21:18:51 -06:00
type pageData struct {
Title string
Content template.HTML
2021-02-13 21:18:51 -06:00
Servers []server
2020-03-19 23:20:59 -05:00
}
//go:embed index.html
var indexhtml string
func main() {
2020-03-19 23:20:59 -05:00
// Parse config file
configData, err := os.ReadFile("./config.json")
if err != nil {
log.Fatalf("Error reading config file: %v\n", err)
2020-03-19 23:20:59 -05:00
}
var config config
err = json.Unmarshal(configData, &config)
if err != nil {
log.Fatalf("Error parsing config file: %v\n", err)
2020-03-19 23:40:23 -05:00
}
2020-04-17 19:53:02 -05:00
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
}
2021-02-13 21:18:51 -06:00
data := pageData{}
data.Title = config.Title
data.Content = config.Content
data.Servers = config.Servers
2020-04-17 19:53:02 -05:00
// Set up templates
2020-03-19 23:20:59 -05:00
fmt.Print("Parsing templates...\n")
t, err := template.New("").Parse(indexhtml)
2020-03-19 23:20:59 -05:00
if err != nil {
2021-02-13 21:18:51 -06:00
log.Fatalf("Error parsing HTML template: %v\n", err)
2020-03-19 23:20:59 -05:00
}
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
2023-10-12 22:02:59 -05:00
if r.URL.Path != "/" {
http.NotFound(w, r)
2023-10-12 22:04:18 -05:00
return
2023-10-12 22:02:59 -05:00
}
2020-03-19 23:40:23 -05:00
2021-02-13 21:18:51 -06:00
// Update servers with current data
for i, s := range config.Servers {
// TODO: Query instead (opportunistically?) to get mod lists, etc
config.Servers[i].Status, err = minequery.Ping17(s.Host, s.Port)
if err != nil {
log.Printf("Error querying server: %v", err)
}
}
2020-03-19 23:40:23 -05:00
2021-02-13 21:18:51 -06:00
err = t.Execute(w, data)
if err != nil {
log.Printf("Error executing template: %v\n", err)
}
2020-03-19 23:20:59 -05:00
})
2023-10-12 22:04:26 -05:00
http.HandleFunc("/data.json", func(w http.ResponseWriter, r *http.Request) {
// Update servers with current data
for i, s := range config.Servers {
// TODO: Query instead (opportunistically?) to get mod lists, etc
config.Servers[i].Status, err = minequery.Ping17(s.Host, s.Port)
if err != nil {
log.Printf("Error querying server: %v", err)
}
}
msg, err := json.Marshal(config.Servers)
if err != nil {
http.Error(w, err.Error(), 500)
}
w.Header().Set("Content-Type", "application/json")
w.Write(msg)
})
2020-04-17 19:53:02 -05:00
// Serve backup directory
if serveBackups { // TODO: add HTML
2020-04-17 19:53:02 -05:00
http.Handle("/backups/", http.StripPrefix("/backups/", http.FileServer(http.Dir(config.BackupDir))))
}
if config.UseTLS {
2020-03-29 21:05:34 -05:00
certManager := autocert.Manager{
Prompt: autocert.AcceptTOS,
HostPolicy: autocert.HostWhitelist(config.TLSHostname),
Cache: autocert.DirCache("certs"),
}
2020-03-29 21:05:34 -05:00
srv := &http.Server{
Addr: ":https",
TLSConfig: &tls.Config{
GetCertificate: certManager.GetCertificate,
},
}
2020-03-29 21:05:34 -05:00
go http.ListenAndServe(":http", certManager.HTTPHandler(nil)) // Handler for LetsEncrypt
2021-02-13 21:18:51 -06:00
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
2021-02-13 21:18:51 -06:00
} else {
if config.ServerPort == 0 { // Value not set in JSON
config.ServerPort = 80
}
2021-02-13 21:18:51 -06:00
fmt.Printf("Serving HTTP on port %v...\n", config.ServerPort)
http.ListenAndServe(fmt.Sprintf(":%v", config.ServerPort), nil)
}
2020-03-19 23:20:59 -05:00
}