diff --git a/internal/irc/irc.go b/internal/irc/irc.go
index 310916c..8a5965c 100644
--- a/internal/irc/irc.go
+++ b/internal/irc/irc.go
@@ -55,13 +55,13 @@ type KardBot struct {
startTime time.Time
Prompts []string
Database scribble.Driver
- channelData map[string]ChannelData
+ ChannelData map[string]ChannelData
}
type ChannelData struct {
Name string `json:"name"`
AdminKey string `json:"value,omitempty"`
- CustomCommand string `json:"customcommand,omitempty"`
+ Command string `json:"customcommand,omitempty"`
ExtraStrings string `json:"extrastrings,omitempty"`
JoinTime time.Time `json:"jointime"`
}
@@ -136,8 +136,9 @@ func (bb *KardBot) HandleChat() error {
if nil != cmdMatches {
cmd := cmdMatches[1]
+ rgb.YPrintf("[%s] Checking cmd %s against %s\n", TimeStamp(), cmd, bb.ChannelData[channel].Command)
switch cmd {
- case "card":
+ case bb.ChannelData[channel].Command:
rgb.CPrintf("[%s] Card asked for by %s on %s' channel!\n", TimeStamp(), userName, channel)
bb.Say("Your prompt is : "+bb.Prompts[rand.Intn(len(bb.Prompts))], channel)
@@ -184,6 +185,15 @@ func (bb *KardBot) Login() {
bb.conn.Write([]byte("NICK " + bb.Name + "\r\n"))
}
+
+func (bb *KardBot) LeaveChannel(channels ...string) {
+ for _, channel := range channels {
+ rgb.YPrintf("[%s] Leaving #%s...\n", TimeStamp(), channel)
+ bb.conn.Write([]byte("PART #" + channel + "\r\n"))
+ rgb.YPrintf("[%s] Left #%s as @%s!\n", TimeStamp(), channel, bb.Name)
+ }
+}
+
// Makes the bot join its pre-specified channel.
func (bb *KardBot) JoinChannel(channels ...string) {
if len(channels) == 0 {
@@ -264,8 +274,8 @@ func (bb *KardBot) Start() {
for {
bb.Connect()
bb.Login()
- if len(bb.channelData) > 0 {
- for channelName := range(bb.channelData) {
+ if len(bb.ChannelData) > 0 {
+ for channelName := range(bb.ChannelData) {
bb.JoinChannel(channelName)
}
} else {
@@ -288,15 +298,15 @@ func (bb *KardBot) readChannelData() error {
records, err := bb.Database.ReadAll("channelData")
if err != nil {
// no db? initialise one?
- record := ChannelData{Name: bb.Channel, JoinTime: time.Now()}
- rgb.YPrintf("[%s] No channel data for #%s exists, creating...\n", TimeStamp(), bb.Channel)
+ record := ChannelData{Name: bb.Channel, JoinTime: time.Now(), Command: "card"}
+ rgb.YPrintf("[%s] No channel table for #%s exists, creating...\n", TimeStamp(), bb.Channel)
if err := bb.Database.Write("channelData", bb.Channel, record); err != nil {
return err
}
- bb.channelData = make(map[string]ChannelData)
- bb.channelData[bb.Channel] = record;
+ bb.ChannelData = make(map[string]ChannelData)
+ bb.ChannelData[bb.Channel] = record;
} else {
- bb.channelData = make(map[string]ChannelData)
+ bb.ChannelData = make(map[string]ChannelData)
}
for _, data := range records {
record := ChannelData{}
@@ -304,8 +314,29 @@ func (bb *KardBot) readChannelData() error {
if err != nil {
return err
}
- bb.channelData[record.Name] = record
+ if record.Name != "" {
+ if record.Command == "" {
+ record.Command = "card"
+
+ rgb.YPrintf("[%s] Rewriting data for #%s...\n", TimeStamp(), bb.Channel)
+ if err := bb.Database.Write("channelData", record.Name, record); err != nil {
+ return err
+ }
+ }
+ bb.ChannelData[record.Name] = record
+ }
}
+ // Managed to leave the main channel!?
+ if bb.ChannelData[bb.Channel].Name == "" {
+ rgb.YPrintf("[%s] No channel data for #%s exists, creating...\n", TimeStamp(), bb.Channel)
+ record := ChannelData{Name: bb.Channel, JoinTime: time.Now(), Command: "card"}
+ bb.ChannelData[bb.Channel] = record
+ if err := bb.Database.Write("channelData", bb.Channel, record); err != nil {
+ return err
+ }
+ records, err = bb.Database.ReadAll("channelData")
+ }
+ rgb.YPrintf("[%s] Read channel data for %d channels\n", TimeStamp(), len(bb.ChannelData))
return nil
}
@@ -313,14 +344,14 @@ func (bb *KardBot) readOrCreateChannelKey(channel string) string {
magicCode := ""
var err error
var record ChannelData
- if record, ok := bb.channelData[channel]; !ok {
+ if record, ok := bb.ChannelData[channel]; !ok {
rgb.YPrintf("[%s] No channel data for #%s exists, creating\n", TimeStamp(), channel)
err = bb.Database.Read("channelData", channel, &record);
if err == nil {
- bb.channelData[channel] = record
+ bb.ChannelData[channel] = record
}
}
- record = bb.channelData[channel]
+ record = bb.ChannelData[channel]
if err != nil || record.AdminKey == "" {
rgb.YPrintf("[%s] No channel key for #%s exists, creating one\n", TimeStamp(), channel)
newuu, _ := uuid.NewRandom()
@@ -332,7 +363,7 @@ func (bb *KardBot) readOrCreateChannelKey(channel string) string {
if err := bb.Database.Write("channelData", channel, record); err != nil {
rgb.RPrintf("[%s] Error writing channel data for #%s\n", TimeStamp(), channel)
}
- bb.channelData[record.Name] = record
+ bb.ChannelData[record.Name] = record
rgb.YPrintf("[%s] Cached channel key for #%s\n", TimeStamp(), record.Name)
} else {
magicCode = record.AdminKey
diff --git a/internal/webserver/webserver.go b/internal/webserver/webserver.go
index 89ea4e1..afa09d5 100755
--- a/internal/webserver/webserver.go
+++ b/internal/webserver/webserver.go
@@ -17,7 +17,7 @@ import (
//var store = sessions.NewCookieStore(os.Getenv("SESSION_KEY"))
-var ircBot irc.KardBot
+var ircBot *irc.KardBot
func HealthHandler(response http.ResponseWriter, request *http.Request) {
response.Header().Add("Content-type", "text/plain")
@@ -73,7 +73,7 @@ func TemplateHandler(response http.ResponseWriter, request *http.Request) {
// NotFoundHandler(response, request)
// return
}
- var td = TemplateData{ircBot.Prompts[rand.Intn(len(ircBot.Prompts))], len(ircBot.Prompts), 0, 0}
+ var td = TemplateData{ircBot.Prompts[rand.Intn(len(ircBot.Prompts))], len(ircBot.Prompts), len(ircBot.ChannelData), 0}
err = tmpl.Execute(response, td)
if err != nil {
http.Error(response, err.Error(), http.StatusInternalServerError)
@@ -81,19 +81,71 @@ func TemplateHandler(response http.ResponseWriter, request *http.Request) {
}
}
-func AdminHandler(response http.ResponseWriter, request *http.Request) {
- request.URL.Path = "/index.html"
+func LeaveHandler(response http.ResponseWriter, request *http.Request) {
+ request.URL.Path = "/bye.html"
TemplateHandler(response, request)
}
-func HandleHTTP(passedIrcBot irc.KardBot) {
+func AdminHandler(response http.ResponseWriter, request *http.Request) {
+ vars := mux.Vars(request)
+ if vars["key"] != ircBot.ChannelData[vars["channel"]].AdminKey {
+ UnauthorizedHandler(response, request)
+ return
+ }
+ type TemplateData struct {
+ Channel string
+ Command string
+ ExtraStrings string
+ SinceTime time.Time
+ Leaving bool
+ }
+ channelData := ircBot.ChannelData[vars["channel"]]
+ var td = TemplateData{channelData.Name, channelData.Command, channelData.ExtraStrings, channelData.JoinTime, false}
+
+ if request.Method == "POST" {
+ request.ParseForm()
+ if strings.Join(request.PostForm["leave"],",") == "Leave twitch channel" {
+ td.Leaving = true
+ } else if strings.Join(request.PostForm["reallyleave"],",") == "Really leave twitch channel" {
+ delete(ircBot.ChannelData,vars["channel"])
+ ircBot.Database.Delete("channelData", vars["channel"])
+ ircBot.LeaveChannel(vars["channel"])
+ LeaveHandler(response, request)
+ return
+ }
+ sourceData := ircBot.ChannelData[vars["channel"]]
+ if strings.Join(request.PostForm["Command"],",") != "" {
+ sourceData.Command = strings.Join(request.PostForm["Command"],",")
+ td.Command = sourceData.Command
+ ircBot.ChannelData[vars["channel"]] = sourceData
+ }
+ if strings.Join(request.PostForm["ExtraStrings"],",") != sourceData.ExtraStrings {
+ sourceData.ExtraStrings = strings.Join(request.PostForm["ExtraStrings"],",")
+ td.ExtraStrings = sourceData.ExtraStrings
+ ircBot.ChannelData[vars["channel"]] = sourceData
+ }
+ ircBot.Database.Write("channelData", vars["channel"], sourceData);
+ }
+ tmpl := template.Must(template.ParseFiles("web/admin.html"))
+ tmpl.Execute(response, td)
+}
+
+func UnauthorizedHandler(response http.ResponseWriter, request *http.Request) {
+ response.Header().Add("X-Template-File", "html"+request.URL.Path)
+ response.WriteHeader(401)
+ tmpl := template.Must(template.ParseFiles("web/401.html"))
+ tmpl.Execute(response, nil)
+}
+
+func HandleHTTP(passedIrcBot *irc.KardBot) {
ircBot = passedIrcBot
r := mux.NewRouter()
loggedRouter := handlers.LoggingHandler(os.Stdout, r)
r.NotFoundHandler = http.HandlerFunc(NotFoundHandler)
r.HandleFunc("/", RootHandler)
r.HandleFunc("/healthz", HealthHandler)
- r.HandleFunc("/example/{.*}", TemplateHandler)
+ r.HandleFunc("/web/{.*}", TemplateHandler)
+ r.PathPrefix("/static/").Handler(http.FileServer(http.Dir("./web/")))
r.HandleFunc("/cover.css", CSSHandler)
r.HandleFunc("/admin/{channel}/{key}", AdminHandler)
http.Handle("/", r)
diff --git a/main.go b/main.go
index 89c4225..1996938 100755
--- a/main.go
+++ b/main.go
@@ -208,7 +208,7 @@ func main() {
}
go func() {
rgb.YPrintf("[%s] Starting webserver on port %s\n", irc.TimeStamp(), "5353")
- webserver.HandleHTTP(myBot)
+ webserver.HandleHTTP(&myBot)
}()
myBot.Start()
}
diff --git a/web/401.html b/web/401.html
new file mode 100755
index 0000000..80bc8a8
--- /dev/null
+++ b/web/401.html
@@ -0,0 +1,107 @@
+
+
+
+
+
+
+
+
+ The great unknown!
+
+
+
+
+
+
+
+
+
+
+
+
+
k8s-zoo
+
+
+
+
+
Scary user alert!
+
+
It seems you've gone somewhere you shouldn't! 401 NOT AUTHORIZED!
+
+
I'm not quite sure how you got here to be honest, if it was via a link on the site, let me know via twitch DM, if it was from someone else, let them know.
+
Shameless self-promotion : Follow me on twitch - iMartynOnTwitch, oddly enough, I do a lot of twitchsings!