diff --git a/.gitignore b/.gitignore index 3b64f16..c9e5f78 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ # Custom Ignores /mc_man -/mc_man_test +/live_test # Vim swap files *.swp diff --git a/mc_man.go b/mc_man.go index 5eb890f..a94f6fc 100644 --- a/mc_man.go +++ b/mc_man.go @@ -2,7 +2,7 @@ package main import ( "fmt" - "github.com/br0xen/mc_man/util" + "gogs.bullercodeworks.com/brian/mc_man/util" "log" "os" "os/exec" @@ -61,11 +61,13 @@ func main() { ch <- string(buf[:n]) } if err != nil { + fmt.Print("Caught: ", err, "\n") // Error, break out of loop break } } fmt.Println("mc_man stopped") + util.StopServer = true close(ch) }() @@ -85,6 +87,11 @@ func main() { } }() + // Web Server Routine + go func() { + util.StartServer(ch) + }() + // The forever loop to monitor everything for { time.Sleep(time.Second) diff --git a/util/config.go b/util/config.go index bddc7e2..a7aba39 100644 --- a/util/config.go +++ b/util/config.go @@ -16,20 +16,53 @@ type Config struct { FeatureDayNight bool Users []*User LoggedInUsers []*User + Whitelist []string + Ops []string } var c *Config var StopServer = false +var message_manager *MessageManager func LoadConfig(mm *MessageManager) { + message_manager = mm c = new(Config) + + // Load the whitelist + whitelist_rd, err := ioutil.ReadFile("whitelist.json") + // We have to make it an object to read it... + whitelist_rd = append(append([]byte("{\"whitelist\":"), whitelist_rd...), '}') + if err == nil { + j, _ := jason.NewObjectFromBytes(whitelist_rd) + jo, _ := j.GetObjectArray("whitelist") + for _, wl_u := range jo { + n, _ := wl_u.GetString("name") + fmt.Print("> Whitelisted User ", n, "\n") + c.Whitelist = append(c.Whitelist, n) + } + } + + // Load the Op list + oplist_rd, err := ioutil.ReadFile("ops.json") + // We have to make it an object to read it... + oplist_rd = append(append([]byte("{\"ops\":"), oplist_rd...), '}') + if err == nil { + j, _ := jason.NewObjectFromBytes(oplist_rd) + jo, _ := j.GetObjectArray("ops") + for _, ol_u := range jo { + n, _ := ol_u.GetString("name") + fmt.Print("> Opped User ", n, "\n") + c.Ops = append(c.Ops, n) + } + } + config_str, err := ioutil.ReadFile("mc_man.config") if err == nil { j, _ := jason.NewObjectFromBytes(config_str) o, _ := j.GetObjectArray("options") // Add the "Stop" listener - fmt.Println("Activating 'stop' listener") + fmt.Println("> Activating 'stop' listener") AddListener(func(i *Message) bool { if i.User.IsOp && i.Text == "!stop\n" { mm.Output("stop") @@ -45,7 +78,7 @@ func LoadConfig(mm *MessageManager) { if opt_name == "home" { c.FeatureTPHome = opt_enabled if opt_enabled { - fmt.Println("Activating 'home' listeners") + fmt.Println("> Activating 'home' listeners") // Add !set home listener AddListener(func(i *Message) bool { if i.User.Name != "" && i.Text == "!set home\n" { @@ -86,7 +119,7 @@ func LoadConfig(mm *MessageManager) { } else if opt_name == "visit" { c.FeatureTPVisit = opt_enabled if opt_enabled { - fmt.Println("Activating 'visit' listeners") + fmt.Println("> Activating 'visit' listeners") // Add !set porch listener AddListener(func(i *Message) bool { if i.User.Name != "" && i.Text == "!set porch\n" { @@ -131,23 +164,23 @@ func LoadConfig(mm *MessageManager) { } else if opt_name == "daynight" { c.FeatureDayNight = opt_enabled if opt_enabled { - fmt.Println("Activating 'daynight' listeners") - // Add !switch day listener + fmt.Println("> Activating 'time' listeners") + // Add !time day listener AddListener(func(i *Message) bool { - if i.User.Name != "" && i.Text == "!switch day\n" { + if i.User.Name != "" && i.Text == "!time day\n" { // TODO: Start vote mm.Output("time set day") - mm.Tell("@a", "Day Time switch initiated by "+i.User.Name, "yellow") + mm.Tell("@a", "Day Time time initiated by "+i.User.Name, "yellow") return true } return false }) - // Add !switch night listener + // Add !time night listener AddListener(func(i *Message) bool { - if i.User.Name != "" && i.Text == "!switch night\n" { + if i.User.Name != "" && i.Text == "!time night\n" { // TODO: Start vote mm.Output("time set night") - mm.Tell("@a", "Night Time switch initiated by "+i.User.Name, "blue") + mm.Tell("@a", "Night Time time initiated by "+i.User.Name, "blue") return true } return false @@ -198,12 +231,25 @@ func LoadConfig(mm *MessageManager) { AddListener(func(i *Message) bool { if i.User.Name != "" && i.Text == "!help\n" { mm.Tell(i.User.Name, "-=( mc_man Manager Help )=-", "blue") - mm.Tell(i.User.Name, "!set home -- Set your 'home' to your current position.", "white") - mm.Tell(i.User.Name, "!home -- Request a teleport to your 'home' position.", "white") - mm.Tell(i.User.Name, "!set porch -- Set your 'porch' to your current position.", "white") - mm.Tell(i.User.Name, "!visit -- Request a teleport to 's 'porch' position.", "white") - mm.Tell(i.User.Name, "!switch day -- Ask the server to switch the time to 'day'.", "white") - mm.Tell(i.User.Name, "!switch night -- Ask the server to switch the time to 'night'.", "white") + numFeatures := 0 + if c.FeatureTPHome == true { + numFeatures++ + mm.Tell(i.User.Name, "!set home -- Set your 'home' to your current position.", "white") + mm.Tell(i.User.Name, "!home -- Request a teleport to your 'home' position.", "white") + } + if c.FeatureTPVisit == true { + numFeatures++ + mm.Tell(i.User.Name, "!set porch -- Set your 'porch' to your current position.", "white") + mm.Tell(i.User.Name, "!visit -- Request a teleport to 's 'porch' position.", "white") + } + if c.FeatureDayNight == true { + numFeatures++ + mm.Tell(i.User.Name, "!time day -- Ask the server to time the time to 'day'.", "white") + mm.Tell(i.User.Name, "!time night -- Ask the server to time the time to 'night'.", "white") + } + if numFeatures == 0 { + mm.Tell(i.User.Name, "mc_man currently has no user features loaded.", "white") + } mm.Tell(i.User.Name, "-=========================-", "blue") return true } @@ -219,16 +265,17 @@ func LoadConfig(mm *MessageManager) { user_home, _ := user.GetString("home") user_porch, _ := user.GetString("porch") us := NewUser(user_name) - // TODO: Check if this user is an op on the server - if user_name == "br0xen" { - us.IsOp = true + for _, un := range c.Ops { + if un == user_name { + us.IsOp = true + } } us.Home = user_home us.Porch = user_porch c.Users = append(c.Users, us) } } - fmt.Printf("Loaded %d Users\n", len(c.Users)) + fmt.Printf("> Loaded %d Users\n", len(c.Users)) } } @@ -287,8 +334,13 @@ func WriteConfig() { } d = d + "}],\"users\":[" // Output users array + num_users := 0 for _, u := range c.Users { + if num_users > 0 { + d = d + "," + } d = d + u.ToJSONString() + num_users++ } d = d + "]}" do := []byte(d) diff --git a/util/user.go b/util/user.go index 5544587..dcc6e58 100644 --- a/util/user.go +++ b/util/user.go @@ -25,8 +25,10 @@ func NewUser(nm string) *User { m.IsOp = false m.Home = "" m.Porch = "" + m.Quota = 0 + m.quotaUsed = 0 m.ToJSONString = func() string { - return "{\"name\":\"" + m.Name + "\",\"home\":\"" + m.Home + "\",\"porch\":\"" + m.Porch + "\",\"quota\":\"" + string(m.Quota) + "\",\"quota_used\":\"" + string(m.quotaUsed) + "\"}" + return "{\"name\":\"" + m.Name + "\",\"home\":\"" + m.Home + "\",\"porch\":\"" + m.Porch + "\",\"quota\":\"" + m.Quota.String() + "\",\"quota_used\":\"" + m.quotaUsed.String() + "\"}" } return m } diff --git a/util/webserver.go b/util/webserver.go new file mode 100644 index 0000000..01260a4 --- /dev/null +++ b/util/webserver.go @@ -0,0 +1,126 @@ +package util + +import ( + "fmt" + "io" + "io/ioutil" + "net/http" + "os" +) + +var output_channel chan string + +func StartServer(ch chan string) { + output_channel = ch + _, err := os.Stat("mapcrafter/index.html") + if err == nil { + // Looks like mapcrafter is present + output_channel <- "* Mapcrafter Directory is Present, routing to /map\n" + fs := http.FileServer(http.Dir("mapcrafter")) + http.Handle("/map/", http.StripPrefix("/map/", fs)) + } + http.HandleFunc("/api/", serveAPI) + http.HandleFunc("/", serveMcMan) + http.ListenAndServe(":8080", nil) +} + +func serveMcMan(w http.ResponseWriter, r *http.Request) { + fmt.Fprintf(w, htmlHeader("mc_man - Minecraft Manager")) + fmt.Fprintf(w, "Hey-o! It's the manager!") + fmt.Fprintf(w, htmlFooter()) +} + +func serveAPI(w http.ResponseWriter, r *http.Request) { + body, err := ioutil.ReadAll(io.LimitReader(r.Body, 1048576)) + if err != nil { + panic(err) + } + if err := r.Body.Close(); err != nil { + panic(err) + } + w.Header().Set("Content-Type", "application/json; charset=UTF-8") + // What are we doing with this request? + output_channel <- fmt.Sprint("HTTP Request: (", r.Method, ") ", r.URL, "\n") + the_path = r.URL.Path + output_string = "" + if strings.HasPrefix(the_path, "/api") { + the_path = strings.TrimPrefix(the_path, "/api") + if strings.HasPrefix(the_path, "/v1") { + the_path = strings.TrimPrefix(the_path, "/v1") + if strings.HasPrefix(the_path, "/whitelist") { + output_string = handleWhitelist(r) + } else if strings.HasPrefix(the_path, "/ops") { + output_string = handleOps(r) + } + } + } +} + +/* JSON Functions */ +func handleOps(r *http.Request) string { + if r.Method == "GET" { + return getOps() + } else if r.Method == "POST" { + // Add posted user to Ops + } + return "" +} + +func handleWhitelist(r *http.Request) string { + if r.Method == "GET" { + return getWhitelist() + } else if r.Method == "POST" { + // Add posted user to whitelist + } + return "" +} + +func getOps() string { + ret := "[" + num_users := 0 + for _, op_user := range GetConfig().Ops { + if num_users > 0 { + ret += "," + } + ret += fmt.Sprint("\"", op_user, "\"") + } + ret += "]" + return ret + +} + +func getWhitelist() string { + ret := "[" + num_users := 0 + for _, wl_user := range GetConfig().Whitelist { + if num_users > 0 { + ret += "," + } + ret += fmt.Sprint("\"", wl_user, "\"") + } + ret += "]" + return ret +} + +/* HTML Functions */ +func htmlHeader(title string) string { + head := ` + + + + ` + head += title + head += ` + + + +` + return head +} + +func htmlFooter() string { + return ` + + +` +}