mc_man/util/config.go

401 lines
11 KiB
Go

package util
import (
"fmt"
"github.com/antonholmquist/jason"
"io/ioutil"
"strings"
)
type Config struct {
// The JSON object of what was read
LoadedJson jason.Object
Options jason.Object
FeatureTPHome bool
FeatureTPVisit bool
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")
AddListener(func(i *Message) bool {
if i.User.IsOp && i.Text == "!stop\n" {
mm.Output("stop")
StopServer = true
return true
}
return false
})
for _, option := range o {
opt_name, _ := option.GetString("name")
opt_enabled, _ := option.GetBoolean("enabled")
if opt_name == "home" {
c.FeatureTPHome = opt_enabled
if opt_enabled {
fmt.Println("> Activating 'home' listeners")
// Add !set home listener
AddListener(func(i *Message) bool {
if i.User.Name != "" && i.Text == "!set home\n" {
AddTempListener(func(inp *Message) bool {
listen_for := "Teleported " + i.User.Name + " to "
if inp.User.Name == "" && strings.Contains(inp.Text, listen_for) {
// Found the text
r := strings.Split(inp.Text, listen_for)
if len(r) > 0 {
p_str := r[1]
p_str = strings.Replace(p_str, ",", "", -1)
p_str = strings.Replace(p_str, "\n", "", -1)
SetHome(i.User.Name, p_str)
mm.Tell(i.User.Name, "Set your home to "+p_str, "blue")
return true
}
}
return false
})
mm.Output("tp " + i.User.Name + " ~ ~ ~")
return true
}
return false
})
// Add !home listener
AddListener(func(i *Message) bool {
if i.User.Name != "" && i.Text == "!home\n" {
home_str, found := GetHome(i.User.Name)
if found {
mm.Output("tp " + i.User.Name + " " + home_str)
} else {
mm.Tell(i.User.Name, "I don't know where your home is. Set it to your current position by typing '!set home'", "red")
}
}
return false
})
}
} else if opt_name == "visit" {
c.FeatureTPVisit = opt_enabled
if opt_enabled {
fmt.Println("> Activating 'visit' listeners")
// Add !set porch listener
AddListener(func(i *Message) bool {
if i.User.Name != "" && i.Text == "!set porch\n" {
AddTempListener(func(inp *Message) bool {
listen_for := "Teleported " + i.User.Name + " to "
if inp.User.Name == "" && strings.Contains(inp.Text, listen_for) {
// Found the text
r := strings.Split(inp.Text, listen_for)
if len(r) > 0 {
p_str := r[1]
p_str = strings.Replace(p_str, ",", "", -1)
SetPorch(i.User.Name, p_str)
mm.Tell(i.User.Name, "Set your porch to "+p_str, "blue")
return true
}
}
return false
})
mm.Output("tp " + i.User.Name + " ~ ~ ~")
return true
}
return false
})
// Add !visit listener
AddListener(func(i *Message) bool {
if i.User.Name != "" && strings.HasPrefix(i.Text, "!visit ") {
// Find the user we're trying to visit
r := strings.Split(strings.Replace(i.Text, "\n", "", -1), "!visit ")
if len(r) > 0 {
username := r[1]
porch_str, found := GetPorch(username)
if found {
mm.Output("tp " + i.User.Name + " " + porch_str)
} else {
mm.Tell(i.User.Name, "I don't know where "+username+"'s porch is. They can set it to their current position by typing '!set porch'", "red")
}
}
}
return false
})
}
} else if opt_name == "daynight" {
c.FeatureDayNight = opt_enabled
if opt_enabled {
fmt.Println("> Activating 'time' listeners")
// Add !time day listener
AddListener(func(i *Message) bool {
if i.User.Name != "" && i.Text == "!time day\n" {
// TODO: Start vote
mm.Output("time set day")
mm.Tell("@a", "Day Time time initiated by "+i.User.Name, "yellow")
return true
}
return false
})
// Add !time night listener
AddListener(func(i *Message) bool {
if i.User.Name != "" && i.Text == "!time night\n" {
// TODO: Start vote
mm.Output("time set night")
mm.Tell("@a", "Night Time time initiated by "+i.User.Name, "blue")
return true
}
return false
})
}
}
// Add login listener
AddListener(func(i *Message) bool {
if i.User.Name == "" && strings.Contains(i.Text, " logged in with entity id ") {
// TODO: User Logged in Function
// Find the user that just logged in
r := strings.Split(i.Text, "]: ")
find := ""
if len(r) > 0 {
find = r[1]
r := strings.Split(find, "[/")
if len(r) > 0 {
find = r[0]
// find should be the user name now
LoginUser(*FindUser(find, true))
return true
}
}
}
return false
})
// Add logout listener
AddListener(func(i *Message) bool {
if i.User.Name == "" && strings.Contains(i.Text, " lost connection: ") {
// Find the user that just logged out
r := strings.Split(i.Text, "]: ")
find := ""
if len(r) > 0 {
find = r[1]
r := strings.Split(find, " lost connection: ")
if len(r) > 0 {
find = r[0]
// find should be the user name now
LogoutUser(*FindUser(find, false))
return true
}
}
}
return false
})
// Add !help listener
AddListener(func(i *Message) bool {
if i.User.Name != "" && i.Text == "!help\n" {
mm.Tell(i.User.Name, "-=( mc_man Manager Help )=-", "blue")
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 <username> -- Request a teleport to <username>'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
}
return false
})
}
c.Users = make([]*User, 0, 10)
u, _ := j.GetObjectArray("users")
for _, user := range u {
user_name, err := user.GetString("name")
if err == nil && user_name != "" {
user_home, _ := user.GetString("home")
user_porch, _ := user.GetString("porch")
us := NewUser(user_name)
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))
}
}
func LoginUser(u User) {
for _, user := range c.LoggedInUsers {
if user.Name == u.Name {
// User is already logged in
return
}
}
c.LoggedInUsers = append(c.LoggedInUsers, &u)
}
func LogoutUser(u User) {
for idx, user := range c.LoggedInUsers {
if user.Name == u.Name {
t := append(c.LoggedInUsers[:idx], c.LoggedInUsers[idx+1:]...)
c.LoggedInUsers = make([]*User, len(t))
copy(c.LoggedInUsers, t)
return
}
}
}
func AddUser(username string) {
if username != "" {
us := NewUser(username)
fmt.Println("Adding new user: " + username)
c.Users = append(c.Users, us)
WriteConfig()
}
}
func WriteConfig() {
// TODO: Make mc_man aware of the world
// Generate the JSON string for the config file
d := "{\"options\":["
// Output options array
d = d + "{\"name\":\"home\",\"enabled\":"
if c.FeatureTPHome {
d = d + "true"
} else {
d = d + "false"
}
d = d + "},{\"name\":\"visit\",\"enabled\":"
if c.FeatureTPVisit {
d = d + "true"
} else {
d = d + "false"
}
d = d + "},{\"name\":\"daynight\",\"enabled\":"
if c.FeatureDayNight {
d = d + "true"
} else {
d = d + "false"
}
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)
ioutil.WriteFile("mc_man.config", do, 0664)
}
func SetHome(user string, loc string) {
u := FindUser(user, true)
if u.Index != -1 {
u.Home = strings.Replace(loc, "\n", "", -1)
// Replace the user in the Users array
c.Users[u.Index] = u
WriteConfig()
}
}
func GetHome(user string) (string, bool) {
u := FindUser(user, false)
if u.Index == -1 || u.Home == "" {
return "", false
}
return u.Home, true
}
func SetPorch(user string, loc string) {
u := FindUser(user, true)
if u.Index != -1 {
u.Porch = strings.Replace(loc, "\n", "", -1)
c.Users[u.Index] = u
WriteConfig()
}
}
func GetPorch(user string) (string, bool) {
u := FindUser(user, false)
if u.Index == -1 || u.Porch == "" {
return "", false
}
return u.Porch, true
}
func FindUser(name string, create bool) *User {
for _, user := range c.Users {
if user.Name == name {
return user
}
}
if create && name != "" {
AddUser(name)
return FindUser(name, false)
}
return NewUser("")
}
func GetConfig() *Config {
return c
}