Start building the Model

This commit is contained in:
Brian Buller 2015-04-23 11:09:59 -05:00
parent afdf09607e
commit cd1bc16361
6 changed files with 249 additions and 100 deletions

View File

@ -88,9 +88,11 @@ func main() {
}()
// Web Server Routine
go func() {
util.StartServer(ch)
}()
/*
go func() {
util.StartServer(ch)
}()
*/
// The forever loop to monitor everything
for {

View File

@ -14,8 +14,8 @@ type Config struct {
FeatureTPHome bool
FeatureTPVisit bool
FeatureDayNight bool
Users []*User
LoggedInUsers []*User
MCUsers []*MCUser
LoggedInMCUsers []*MCUser
Whitelist []string
Ops []string
}
@ -28,6 +28,8 @@ func LoadConfig(mm *MessageManager) {
message_manager = mm
c = new(Config)
mc_model := InitializeModel()
// Load the whitelist
whitelist_rd, err := ioutil.ReadFile("whitelist.json")
// We have to make it an object to read it...
@ -64,7 +66,7 @@ func LoadConfig(mm *MessageManager) {
// Add the "Stop" listener
fmt.Println("> Activating 'stop' listener")
AddListener(func(i *Message) bool {
if i.User.IsOp && i.Text == "!stop\n" {
if i.MCUser.IsOp && i.Text == "!stop\n" {
mm.Output("stop")
StopServer = true
return true
@ -81,36 +83,36 @@ func LoadConfig(mm *MessageManager) {
fmt.Println("> Activating 'home' listeners")
// Add !set home listener
AddListener(func(i *Message) bool {
if i.User.Name != "" && i.Text == "!set home\n" {
if i.MCUser.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) {
listen_for := "Teleported " + i.MCUser.Name + " to "
if inp.MCUser.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")
SetHome(i.MCUser.Name, p_str)
mm.Tell(i.MCUser.Name, "Set your home to "+p_str, "blue")
return true
}
}
return false
})
mm.Output("tp " + i.User.Name + " ~ ~ ~")
mm.Output("tp " + i.MCUser.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 i.MCUser.Name != "" && i.Text == "!home\n" {
home_str, found := GetHome(i.MCUser.Name)
if found {
mm.Output("tp " + i.User.Name + " " + home_str)
mm.Output("tp " + i.MCUser.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")
mm.Tell(i.MCUser.Name, "I don't know where your home is. Set it to your current position by typing '!set home'", "red")
}
}
return false
@ -122,39 +124,39 @@ func LoadConfig(mm *MessageManager) {
fmt.Println("> Activating 'visit' listeners")
// Add !set porch listener
AddListener(func(i *Message) bool {
if i.User.Name != "" && i.Text == "!set porch\n" {
if i.MCUser.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) {
listen_for := "Teleported " + i.MCUser.Name + " to "
if inp.MCUser.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")
SetPorch(i.MCUser.Name, p_str)
mm.Tell(i.MCUser.Name, "Set your porch to "+p_str, "blue")
return true
}
}
return false
})
mm.Output("tp " + i.User.Name + " ~ ~ ~")
mm.Output("tp " + i.MCUser.Name + " ~ ~ ~")
return true
}
return false
})
// Add !visit listener
AddListener(func(i *Message) bool {
if i.User.Name != "" && strings.HasPrefix(i.Text, "!visit ") {
if i.MCUser.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)
mm.Output("tp " + i.MCUser.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")
mm.Tell(i.MCUser.Name, "I don't know where "+username+"'s porch is. They can set it to their current position by typing '!set porch'", "red")
}
}
}
@ -167,20 +169,20 @@ func LoadConfig(mm *MessageManager) {
fmt.Println("> Activating 'time' listeners")
// Add !time day listener
AddListener(func(i *Message) bool {
if i.User.Name != "" && i.Text == "!time day\n" {
if i.MCUser.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")
mm.Tell("@a", "Day Time time initiated by "+i.MCUser.Name, "yellow")
return true
}
return false
})
// Add !time night listener
AddListener(func(i *Message) bool {
if i.User.Name != "" && i.Text == "!time night\n" {
if i.MCUser.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")
mm.Tell("@a", "Night Time time initiated by "+i.MCUser.Name, "blue")
return true
}
return false
@ -189,7 +191,7 @@ func LoadConfig(mm *MessageManager) {
}
// Add login listener
AddListener(func(i *Message) bool {
if i.User.Name == "" && strings.Contains(i.Text, " logged in with entity id ") {
if i.MCUser.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, "]: ")
@ -200,7 +202,7 @@ func LoadConfig(mm *MessageManager) {
if len(r) > 0 {
find = r[0]
// find should be the user name now
LoginUser(*FindUser(find, true))
LoginMCUser(*FindMCUser(find, true))
return true
}
}
@ -209,7 +211,7 @@ func LoadConfig(mm *MessageManager) {
})
// Add logout listener
AddListener(func(i *Message) bool {
if i.User.Name == "" && strings.Contains(i.Text, " lost connection: ") {
if i.MCUser.Name == "" && strings.Contains(i.Text, " lost connection: ") {
// Find the user that just logged out
r := strings.Split(i.Text, "]: ")
find := ""
@ -219,7 +221,7 @@ func LoadConfig(mm *MessageManager) {
if len(r) > 0 {
find = r[0]
// find should be the user name now
LogoutUser(*FindUser(find, false))
LogoutMCUser(*FindMCUser(find, false))
return true
}
}
@ -229,42 +231,42 @@ func LoadConfig(mm *MessageManager) {
// 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")
if i.MCUser.Name != "" && i.Text == "!help\n" {
mm.Tell(i.MCUser.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")
mm.Tell(i.MCUser.Name, "!set home -- Set your 'home' to your current position.", "white")
mm.Tell(i.MCUser.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")
mm.Tell(i.MCUser.Name, "!set porch -- Set your 'porch' to your current position.", "white")
mm.Tell(i.MCUser.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")
mm.Tell(i.MCUser.Name, "!time day -- Ask the server to time the time to 'day'.", "white")
mm.Tell(i.MCUser.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.MCUser.Name, "mc_man currently has no user features loaded.", "white")
}
mm.Tell(i.User.Name, "-=========================-", "blue")
mm.Tell(i.MCUser.Name, "-=========================-", "blue")
return true
}
return false
})
}
c.Users = make([]*User, 0, 10)
c.MCUsers = make([]*MCUser, 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)
us := NewMCUser(user_name)
for _, un := range c.Ops {
if un == user_name {
us.IsOp = true
@ -272,39 +274,39 @@ func LoadConfig(mm *MessageManager) {
}
us.Home = user_home
us.Porch = user_porch
c.Users = append(c.Users, us)
c.MCUsers = append(c.MCUsers, us)
}
}
fmt.Printf("> Loaded %d Users\n", len(c.Users))
fmt.Printf("> Loaded %d Users\n", len(c.MCUsers))
}
}
func LoginUser(u User) {
for _, user := range c.LoggedInUsers {
func LoginMCUser(u MCUser) {
for _, user := range c.LoggedInMCUsers {
if user.Name == u.Name {
// User is already logged in
return
}
}
c.LoggedInUsers = append(c.LoggedInUsers, &u)
c.LoggedInMCUsers = append(c.LoggedInMCUsers, &u)
}
func LogoutUser(u User) {
for idx, user := range c.LoggedInUsers {
func LogoutMCUser(u MCUser) {
for idx, user := range c.LoggedInMCUsers {
if user.Name == u.Name {
t := append(c.LoggedInUsers[:idx], c.LoggedInUsers[idx+1:]...)
c.LoggedInUsers = make([]*User, len(t))
copy(c.LoggedInUsers, t)
t := append(c.LoggedInMCUsers[:idx], c.LoggedInMCUsers[idx+1:]...)
c.LoggedInMCUsers = make([]*MCUser, len(t))
copy(c.LoggedInMCUsers, t)
return
}
}
}
func AddUser(username string) {
func AddMCUser(username string) {
if username != "" {
us := NewUser(username)
us := NewMCUser(username)
fmt.Println("Adding new user: " + username)
c.Users = append(c.Users, us)
c.MCUsers = append(c.MCUsers, us)
WriteConfig()
}
}
@ -335,7 +337,7 @@ func WriteConfig() {
d = d + "}],\"users\":["
// Output users array
num_users := 0
for _, u := range c.Users {
for _, u := range c.MCUsers {
if num_users > 0 {
d = d + ","
}
@ -348,17 +350,17 @@ func WriteConfig() {
}
func SetHome(user string, loc string) {
u := FindUser(user, true)
u := FindMCUser(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
c.MCUsers[u.Index] = u
WriteConfig()
}
}
func GetHome(user string) (string, bool) {
u := FindUser(user, false)
u := FindMCUser(user, false)
if u.Index == -1 || u.Home == "" {
return "", false
}
@ -366,33 +368,33 @@ func GetHome(user string) (string, bool) {
}
func SetPorch(user string, loc string) {
u := FindUser(user, true)
u := FindMCUser(user, true)
if u.Index != -1 {
u.Porch = strings.Replace(loc, "\n", "", -1)
c.Users[u.Index] = u
c.MCUsers[u.Index] = u
WriteConfig()
}
}
func GetPorch(user string) (string, bool) {
u := FindUser(user, false)
u := FindMCUser(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 {
func FindMCUser(name string, create bool) *MCUser {
for _, user := range c.MCUsers {
if user.Name == name {
return user
}
}
if create && name != "" {
AddUser(name)
return FindUser(name, false)
AddMCUser(name)
return FindMCUser(name, false)
}
return NewUser("")
return NewMCUser("")
}
func GetConfig() *Config {

View File

@ -6,8 +6,8 @@ import (
)
type Message struct {
User *User
Text string
MCUser *MCUser
Text string
Output func() string
}
@ -15,21 +15,21 @@ type Message struct {
func NewMessage(t string) *Message {
m := new(Message)
msg_user := regexp.MustCompile("<[^>]+>")
tmpUser := msg_user.FindString(t)
tmpUser = strings.Replace(tmpUser, "<", "", -1)
tmpUser = strings.Replace(tmpUser, ">", "", -1)
m.User = FindUser(tmpUser, true)
tmpMCUser := msg_user.FindString(t)
tmpMCUser = strings.Replace(tmpMCUser, "<", "", -1)
tmpMCUser = strings.Replace(tmpMCUser, ">", "", -1)
m.MCUser = FindMCUser(tmpMCUser, true)
m.Text = t
if m.User.Index != -1 && m.User.Name != "" {
res := strings.Split(t, "<"+m.User.Name+"> ")
if m.MCUser.Index != -1 && m.MCUser.Name != "" {
res := strings.Split(t, "<"+m.MCUser.Name+"> ")
if len(res) > 0 {
m.Text = res[1]
}
}
m.Output = func() string {
if m.User.Index != -1 && m.User.Name != "" {
return "<" + m.User.Name + "> " + m.Text
if m.MCUser.Index != -1 && m.MCUser.Name != "" {
return "<" + m.MCUser.Name + "> " + m.Text
} else {
return m.Text
}

109
util/model.go Normal file
View File

@ -0,0 +1,109 @@
package util
import (
"bytes"
"github.com/boltdb/bolt"
"log"
"time"
)
var users_bucket string
var user_prefix string
type Model struct {
db *bolt.DB
}
func InitializeModel() *Model {
var err error
var ret *Model
users_bucket = "mc_users"
user_prefix = "mc_user_"
ret.db, err = bolt.Open("mc_man.db", 0600, nil)
if err != nil {
log.Fatal(err)
}
defer ret.db.Close()
return ret
}
func (m *Model) getMcUsers() []MCUser {
var ret []MCUser
m.db.View(func(tx *bolt.Tx) error {
b := tx.Bucket([]byte(users_bucket))
c := b.Cursor()
srch_prefix := []byte(user_prefix)
for k, _ := c.Seek(srch_prefix); bytes.HasPrefix(k, srch_prefix); k, _ = c.Next() {
// v should be a mc_user bucket
if user_bucket := b.Bucket(k); user_bucket != nil {
if us_name := user_bucket.Get([]byte("name")); us_name != nil {
new_user := NewMCUser(string(us_name))
new_user.IsOp = bytes.Equal(user_bucket.Get([]byte("op")), []byte("true"))
new_user.Home = string(user_bucket.Get([]byte("home")))
new_user.Porch = string(user_bucket.Get([]byte("porch")))
new_user.Quota, _ = time.ParseDuration(string(user_bucket.Get([]byte("quota"))))
new_user.quotaUsed, _ = time.ParseDuration(string(user_bucket.Get([]byte("quota_used"))))
ret = append(ret, *new_user)
}
}
}
return nil
})
return ret
}
// updateMcUser adds or updates a user
func (m *Model) updateMcUser(u MCUser) {
m.db.Update(func(tx *bolt.Tx) error {
b, err := tx.CreateBucketIfNotExists([]byte(users_bucket))
if err != nil {
return err
}
user_key := user_prefix + u.Name
ub, uberr := b.CreateBucketIfNotExists([]byte(user_key))
if uberr != nil {
return uberr
}
addStringPairToBucket(ub, "name", u.Name)
addBooleanPairToBucket(ub, "op", u.IsOp)
addStringPairToBucket(ub, "home", u.Home)
addStringPairToBucket(ub, "porch", u.Porch)
addDurationPairToBucket(ub, "quota", u.Quota)
addDurationPairToBucket(ub, "quotaused", u.quotaUsed)
addTimePairToBucket(ub, "logintime", u.loginTime)
return nil
})
}
func addStringPairToBucket(b *bolt.Bucket, k, v string) error {
if err := b.Put([]byte(k), []byte(v)); err != nil {
return err
}
return nil
}
func addBooleanPairToBucket(b *bolt.Bucket, k string, v bool) error {
write_v := "true"
if !v {
write_v = "false"
}
if err := b.Put([]byte(k), []byte(write_v)); err != nil {
return err
}
return nil
}
func addDurationPairToBucket(b *bolt.Bucket, k string, v time.Duration) error {
write_v := v.String()
if err := b.Put([]byte(k), []byte(write_v)); err != nil {
return err
}
return nil
}
func addTimePairToBucket(b *bolt.Bucket, k string, v time.Time) error {
if err := b.Put([]byte(k), []byte(v.String())); err != nil {
return err
}
return nil
}

View File

@ -4,7 +4,7 @@ import (
"time"
)
type User struct {
type MCUser struct {
Name string
Index int
IsOp bool
@ -16,8 +16,8 @@ type User struct {
loginTime time.Time
}
func NewUser(nm string) *User {
m := new(User)
func NewMCUser(nm string) *MCUser {
m := new(MCUser)
m.Name = nm
if nm == "" {
m.Index = -1
@ -33,7 +33,7 @@ func NewUser(nm string) *User {
return m
}
func (u *User) HasQuota() bool {
func (u *MCUser) HasQuota() bool {
if u.Quota > 0 {
return u.quotaUsed < u.Quota
} else {
@ -41,7 +41,7 @@ func (u *User) HasQuota() bool {
}
}
func (u *User) RemainingQuota() time.Duration {
func (u *MCUser) RemainingQuota() time.Duration {
if u.Quota > 0 {
return u.Quota - u.quotaUsed
} else {

View File

@ -4,8 +4,11 @@ import (
//"database/sql"
"fmt"
//_ "github.com/mattn/go-sqlite3"
//"encoding/json"
"github.com/boltdb/bolt"
"io"
"io/ioutil"
//"log"
"net/http"
"os"
"strings"
@ -13,6 +16,11 @@ import (
var output_channel chan string
type WebUser struct {
Username string `json:"username"`
Password string `json:"password"`
}
func StartServer(ch chan string) {
output_channel = ch
_, err := os.Stat("mapcrafter/index.html")
@ -20,10 +28,9 @@ func StartServer(ch chan string) {
// 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.Handle("/", fs)
}
http.HandleFunc("/api/", serveAPI)
http.HandleFunc("/", serveMcMan)
http.HandleFunc("/admin/", serveMcMan)
http.ListenAndServe(":8080", nil)
}
@ -31,12 +38,18 @@ func serveMcMan(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, htmlHeader("mc_man - Minecraft Manager"))
the_path := r.URL.Path
output_channel <- the_path
output_channel <- the_path + "\n"
if strings.HasPrefix(the_path, "/login") || the_path == "/" {
the_path = strings.TrimPrefix(strings.ToLower(the_path), "/admin")
output_channel <- the_path + "\n"
fmt.Fprintf(w, the_path)
if strings.HasPrefix(the_path, "/login") {
fmt.Fprintf(w, loginScreen())
} else if strings.HasPrefix(the_path, "/dologin") {
fmt.Fprintf(w, doLogin(w, r))
} else if strings.HasPrefix(the_path, "/api/") {
fmt.Fprintf(w, serveAPI(w, r))
}
fmt.Fprintf(w, htmlFooter())
@ -56,17 +69,8 @@ func doLogin(w http.ResponseWriter, r *http.Request) string {
ret := "Do Login<br />"
ret = ret + r.FormValue("username")
ret = ret + r.FormValue("password")
return ret
/*
//r.F
db, err := sql.Open("sqlite3", "mc_man.db")
if err == nil {
// Error opening the DB, can't log in
return false
}
// rows, err := db.Query("SELECT * FROM USERS")
*/
return ret
}
func serveAPI(w http.ResponseWriter, r *http.Request) {
@ -143,6 +147,38 @@ func getWhitelist() string {
return ret
}
func setupDatabase() bool {
/*
db, err := bolt.Open("mc_man.db", 0600, nil)
if err != nil {
log.Fatal(err)
}
defer db.Close()
err = db.Update(func(tx *bolt.Tx) error {
return nil
})
*/
/*
var err error
web_database, err = sql.Open("sqlite3", "mc_man.db")
defer web_database.Close()
if err == nil {
// Error opening the DB, can't log in
return false
}
rows, err := db.Query("SELECT name FROM sqlite_master WHERE type='table' AND name='users';")
defer rows.Close()
for rows.Next() {
err := rows.Scan
}
// rows, err := db.Query("SELECT * FROM USERS")
return true
*/
return true
}
/* HTML Functions */
func htmlHeader(title string) string {
head := `