Georg Pfuetzenreuter
dfe7deff72
Allow the database file to reside in a user defined location instead of requiring it to be in the working directory. Signed-off-by: Georg Pfuetzenreuter <mail@georg-pfuetzenreuter.net>
182 lines
3.9 KiB
Go
182 lines
3.9 KiB
Go
package wat
|
|
|
|
import (
|
|
"crypto/tls"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/go-irc/irc"
|
|
"github.com/ergochat/irc-go/ircfmt"
|
|
)
|
|
|
|
type WatBot struct {
|
|
client *irc.Client
|
|
conn *tls.Conn
|
|
c *WatConfig
|
|
game *WatGame
|
|
integration *WatIntegration
|
|
Db *WatDb
|
|
Nick string
|
|
}
|
|
|
|
type WatConfig struct {
|
|
DatabasePath string
|
|
BotHosts []string
|
|
BotGames BotGameConfig
|
|
AdminHosts []string
|
|
IgnoredHosts []string
|
|
AutoJoinChannels []string
|
|
PermittedChannels []string
|
|
}
|
|
|
|
func NewWatBot(config *irc.ClientConfig, watConfig *WatConfig, serverConn *tls.Conn) *WatBot {
|
|
wat := WatBot{conn: serverConn, Nick: config.Nick, c: watConfig}
|
|
wat.Db = NewWatDb(watConfig.DatabasePath)
|
|
wat.game = NewWatGame(&wat, wat.Db)
|
|
wat.integration = NewWatIntegration(&wat, wat.Db, &WatIntegrationConfig{BotHosts: watConfig.BotHosts, BotGames: watConfig.BotGames})
|
|
config.Handler = irc.HandlerFunc(wat.HandleIrcMsg)
|
|
wat.client = irc.NewClient(wat.conn, *config)
|
|
return &wat
|
|
}
|
|
|
|
func CleanNick(nick string) string {
|
|
return string(nick[0]) + "\u200c" + nick[1:]
|
|
}
|
|
|
|
func PrefixChannel(channel string) string {
|
|
// there could theoretically be other channel prefixes ..
|
|
if channel[0] != '#' && channel[0] != '!' {
|
|
channel = "#" + channel
|
|
}
|
|
return channel
|
|
}
|
|
|
|
func (w *WatBot) HandleIrcMsg(c *irc.Client, m *irc.Message) {
|
|
switch cmd := m.Command; cmd {
|
|
case "PING":
|
|
w.write("PONG", m.Params[0])
|
|
case "PRIVMSG":
|
|
w.Msg(m)
|
|
case "001":
|
|
for _, channel := range w.c.AutoJoinChannels {
|
|
w.write("JOIN", PrefixChannel(channel))
|
|
}
|
|
}
|
|
}
|
|
|
|
func (w *WatBot) Admin(m *irc.Message) bool {
|
|
return w.Allowed(m.Prefix.Host, w.c.AdminHosts)
|
|
}
|
|
|
|
func (w *WatBot) Allowed(c string, r []string) bool {
|
|
for _, allowed := range r {
|
|
if c == allowed {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func (w *WatBot) CanRespond(m *irc.Message) bool {
|
|
if w.Admin(m) {
|
|
return true
|
|
}
|
|
if w.Allowed(m.Prefix.Host, w.c.IgnoredHosts) {
|
|
return false
|
|
}
|
|
// if !strings.Contains(m.Prefix.Host, "") {
|
|
// return false
|
|
// }
|
|
if !w.Allowed(PrefixChannel(m.Params[0]), w.c.PermittedChannels) {
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
func (w *WatBot) Msg(m *irc.Message) {
|
|
// bail out if you're not yves, if you're not tripsit or if you're not in an allowed channel
|
|
// but if you're an admin you can do whatever
|
|
if !w.CanRespond(m) {
|
|
return
|
|
}
|
|
|
|
// make sure there's actually some text to process
|
|
if len(m.Params[1]) == 0 {
|
|
return
|
|
}
|
|
|
|
// fieldsfunc allows you to obtain rune separated fields/args
|
|
args := strings.FieldsFunc(ircfmt.Strip(m.Params[1]), func(c rune) bool { return c == ' ' })
|
|
|
|
if len(args) == 0 {
|
|
return
|
|
}
|
|
|
|
if w.Admin(m) {
|
|
// allow impersonation of the robot from anywhere
|
|
if (args[0] == "imp" || args[0] == "imps") && len(args) > 2 {
|
|
if args[0] == "imps" {
|
|
w.write(args[1], args[2], strings.Join(args[3:], " "))
|
|
} else {
|
|
w.write(args[1], args[2:]...)
|
|
}
|
|
return
|
|
}
|
|
}
|
|
|
|
// strip offline message prefix from znc for handling offline buffer
|
|
if args[0][0] == '[' && len(args) > 1 {
|
|
args = args[1:]
|
|
}
|
|
|
|
// integration with games in other bots
|
|
if w.integration.HandleIntegration(m, args) {
|
|
return
|
|
}
|
|
|
|
// check if command char (or something weird) is present
|
|
if args[0] != "wat" && args[0][0] != '#' {
|
|
return
|
|
}
|
|
|
|
// clean input
|
|
if args[0][0] == '#' {
|
|
args[0] = args[0][1:]
|
|
}
|
|
|
|
user := strings.ToLower(m.Prefix.Name)
|
|
player := w.Db.User(user, m.Prefix.Host, true)
|
|
w.game.Msg(m, &player, args)
|
|
}
|
|
|
|
func (w *WatBot) Run() {
|
|
defer w.conn.Close()
|
|
err := w.client.Run()
|
|
if err != nil {
|
|
fmt.Println("Error returned while running client: " + err.Error())
|
|
}
|
|
}
|
|
|
|
func (w *WatBot) say(dest, msg string) {
|
|
if len(msg) == 0 {
|
|
return
|
|
}
|
|
//fmt.Printf("MSG %s: %s\n", dest, msg)
|
|
w.write("PRIVMSG", dest, msg)
|
|
}
|
|
|
|
func (w *WatBot) reply(s *irc.Message, r string) {
|
|
sender := s.Params[0]
|
|
if sender == w.Nick {
|
|
sender = s.Prefix.Name
|
|
}
|
|
w.say(sender, r)
|
|
}
|
|
|
|
func (w *WatBot) write(cmd string, params ...string) {
|
|
w.client.WriteMessage(&irc.Message{
|
|
Command: cmd,
|
|
Params: params,
|
|
})
|
|
}
|