packaged up server, added mutex

This commit is contained in:
DutchEllie 2021-06-04 09:54:28 +02:00
parent a8128b120a
commit 062e9276f2
4 changed files with 33 additions and 29 deletions

View File

@ -13,7 +13,7 @@ import (
/* -------- DB Helper functions -------- */ /* -------- DB Helper functions -------- */
func openDB(dsn string) (*sql.DB, error){ func openDB(dsn string) (*sql.DB, error) {
db, err := sql.Open("mysql", dsn) db, err := sql.Open("mysql", dsn)
if err != nil { if err != nil {
return nil, err return nil, err
@ -25,7 +25,7 @@ func openDB(dsn string) (*sql.DB, error){
return db, nil return db, nil
} }
func (app *application) updateAllBadWords() (error) { func (app *application) updateAllBadWords() error {
var err error var err error
app.allBadWords, err = app.badwords.AllWords() app.allBadWords, err = app.badwords.AllWords()
if err != nil { if err != nil {
@ -39,7 +39,7 @@ func (app *application) updateAllBadWords() (error) {
func (app *application) unknownError(err error, s *discordgo.Session, notifyDiscord bool, channelID string) { func (app *application) unknownError(err error, s *discordgo.Session, notifyDiscord bool, channelID string) {
trace := fmt.Sprintf("%s\n%s", err.Error(), debug.Stack()) trace := fmt.Sprintf("%s\n%s", err.Error(), debug.Stack())
app.errorLog.Output(2, trace) app.errorLog.Output(2, trace)
if notifyDiscord { if notifyDiscord {
msg := fmt.Sprintf("An unknown error occured, error message attached below. Stack trace is in the server logs.\n%s", err.Error()) msg := fmt.Sprintf("An unknown error occured, error message attached below. Stack trace is in the server logs.\n%s", err.Error())
@ -61,4 +61,4 @@ func (app *application) readAuthToken() (string, error) {
} }
return string(token), nil return string(token), nil
} }

View File

@ -10,6 +10,7 @@ import (
"time" "time"
"github.com/bwmarrin/discordgo" "github.com/bwmarrin/discordgo"
"quenten.nl/pepebot/discord/mux"
"quenten.nl/pepebot/limiter" "quenten.nl/pepebot/limiter"
"quenten.nl/pepebot/models/mysql" "quenten.nl/pepebot/models/mysql"
) )
@ -25,10 +26,7 @@ type application struct {
trigger string trigger string
allBadWords map[string][]string allBadWords map[string][]string
limiter *limiter.Limiter limiter *limiter.Limiter
commandMux *CommandMux commandMux *mux.CommandMux
active bool
stop bool
} }
func main() { func main() {
@ -62,8 +60,8 @@ func main() {
Logs: make(map[string][]*limiter.Action), Logs: make(map[string][]*limiter.Action),
} }
mux := NewCommandMux() server := mux.NewCommandMux()
mux.prefix = "!pepe" server.Prefix = "!pepe"
app := &application{ app := &application{
infoLog: infoLog, infoLog: infoLog,
@ -72,7 +70,7 @@ func main() {
adminroles: &mysql.AdminRolesModel{DB: db}, adminroles: &mysql.AdminRolesModel{DB: db},
trigger: "!pepe", trigger: "!pepe",
limiter: limiter, limiter: limiter,
commandMux: mux, commandMux: server,
} }
app.allBadWords, err = app.badwords.AllWords() app.allBadWords, err = app.badwords.AllWords()
@ -80,12 +78,12 @@ func main() {
app.errorLog.Fatal(err) app.errorLog.Fatal(err)
} }
mux.HandleFunc("cringe", app.sendCringe) server.HandleFunc("cringe", app.sendCringe)
mux.HandleFunc("gif", app.sendNigelGif) server.HandleFunc("gif", app.sendNigelGif)
mux.HandleFunc("tuesday", app.sendTuesday) server.HandleFunc("tuesday", app.sendTuesday)
mux.HandleFunc("wednesday", app.sendWednesday) server.HandleFunc("wednesday", app.sendWednesday)
mux.HandleFunc("github", app.sendGithub) server.HandleFunc("github", app.sendGithub)
mux.HandleFunc("source", app.sendGithub) server.HandleFunc("source", app.sendGithub)
/* The admin commands are left out for now. /* The admin commands are left out for now.
They have specialised functions and don't work yet. They have specialised functions and don't work yet.
Their code is left unworking and nonfunctional to be fixed Their code is left unworking and nonfunctional to be fixed
@ -95,7 +93,7 @@ func main() {
It goes underused and has had it's joke. It goes underused and has had it's joke.
Oh and no one must be sad to see the death of the spam command...*/ Oh and no one must be sad to see the death of the spam command...*/
mux.HandleFunc(mux.prefix, app.sendPepe) server.HandleFunc(server.Prefix, app.sendPepe)
/* token, err := app.readAuthToken() /* token, err := app.readAuthToken()
if err != nil { if err != nil {

View File

@ -1,11 +1,14 @@
package main package main
import "github.com/bwmarrin/discordgo" import (
"github.com/bwmarrin/discordgo"
"quenten.nl/pepebot/discord/mux"
)
func (app *application) LogToConsole(next Command) Command { func (app *application) LogToConsole(next mux.Command) mux.Command {
fn := func(s *discordgo.Session, m *discordgo.MessageCreate) { fn := func(s *discordgo.Session, m *discordgo.MessageCreate) {
app.infoLog.Printf("%s \tsaid: %s\n", m.Author.Username, m.Content) app.infoLog.Printf("%s \tsaid: %s\n", m.Author.Username, m.Content)
next.Execute(s, m) next.Execute(s, m)
} }
return HandlerFunc(fn) return mux.HandlerFunc(fn)
} }

View File

@ -1,14 +1,12 @@
package main package mux
import ( import (
"strings" "strings"
"sync"
"github.com/bwmarrin/discordgo" "github.com/bwmarrin/discordgo"
) )
/* The Command interface is a template for the implementation of a command of the discord bot.
The actual command will be executed in the Execute function.
All the actual Command objects will be (similarly to Handlers in the net/http package) put into a CommandMux */
type Command interface { type Command interface {
Execute(s *discordgo.Session, m *discordgo.MessageCreate) Execute(s *discordgo.Session, m *discordgo.MessageCreate)
} }
@ -21,8 +19,9 @@ func (f HandlerFunc) Execute(s *discordgo.Session, m *discordgo.MessageCreate) {
/* The CommandMux struct is a type of mux for Discord commands. It's modelled after the net/http ServeMux */ /* The CommandMux struct is a type of mux for Discord commands. It's modelled after the net/http ServeMux */
type CommandMux struct { type CommandMux struct {
mu sync.RWMutex
m map[string]muxEntry m map[string]muxEntry
prefix string Prefix string
} }
func NewCommandMux() *CommandMux { return new(CommandMux) } func NewCommandMux() *CommandMux { return new(CommandMux) }
@ -44,12 +43,14 @@ func (c *CommandMux) firstCommand(command string) string {
} }
func (c *CommandMux) Handler(m *discordgo.MessageCreate) (cmd Command, pattern string) { func (c *CommandMux) Handler(m *discordgo.MessageCreate) (cmd Command, pattern string) {
if strings.HasPrefix(m.Content, c.prefix) { c.mu.RLock()
defer c.mu.RUnlock()
if strings.HasPrefix(m.Content, c.Prefix) {
/* Special case for this bot alone. It has a command that is only it's prefix /* Special case for this bot alone. It has a command that is only it's prefix
So we check if the whole message is only the prefix before proceding. So we check if the whole message is only the prefix before proceding.
So please don't forget to add the command, since it's totally hardcoded here. */ So please don't forget to add the command, since it's totally hardcoded here. */
if strings.TrimSpace(m.Content) == c.prefix { if strings.TrimSpace(m.Content) == c.Prefix {
return c.m[c.prefix].h, c.m[c.prefix].pattern return c.m[c.Prefix].h, c.m[c.Prefix].pattern
} }
m := c.removeFirst(m.Content) /* Here the prefix is removed, so we're left with only the first keyword */ m := c.removeFirst(m.Content) /* Here the prefix is removed, so we're left with only the first keyword */
@ -73,6 +74,8 @@ func (c *CommandMux) Execute(s *discordgo.Session, m *discordgo.MessageCreate) {
} }
func (c *CommandMux) Handle(pattern string, handler Command) { func (c *CommandMux) Handle(pattern string, handler Command) {
c.mu.Lock()
defer c.mu.Unlock()
if pattern == "" { if pattern == "" {
panic("commandmux: invalid pattern") panic("commandmux: invalid pattern")
} }