From 108dbfdd521eea54b5aa6d3528cb390df2d9d9a7 Mon Sep 17 00:00:00 2001 From: Denis Zheleztsov Date: Tue, 19 Jan 2021 11:50:20 +0300 Subject: [PATCH] Allow to disable invition requests --- README.md | 9 +++++ main.go | 113 ++++++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 97 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 71b50f6..4326787 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,8 @@ About cats Inspired from https://github.com/go-chat-bot/plugins/blob/master/catfacts/catfacts.go +## Build + ```go go build ``` @@ -15,3 +17,10 @@ export IRC_PASS="passw0rd" export IRC_URL="localhost:6667" ./ctf2021_ircbot | tee bot.log ``` + +## Commands + +``` +cat|meow|etc - show cat fact or gif +nyastat - show #ctf channel stats +``` diff --git a/main.go b/main.go index f0e6c7b..4b2d82a 100644 --- a/main.go +++ b/main.go @@ -8,11 +8,14 @@ import ( "net/http" "os" "regexp" + "strings" "sync" "time" "log" + "strconv" + irc "github.com/thoj/go-ircevent" ) @@ -20,7 +23,7 @@ var channel = "#ctf" var sendHi = "" const ( - pattern = "(?i)\\b(cat|gato|miau|meow|garfield|lolcat|кот|кошк)[s|z]{0,1}\\b" + pattern = "(?i)\\b(cat|gato|miau|meow|garfield|lolcat)[s|z]{0,1}\\b" nyastat = "nyastat" msgPrefix = "I love cats! Here's a fact: %s ^_^" gifPrefix = "Meow! Here's a gif: %s ^_^" @@ -28,12 +31,13 @@ const ( // environment variables const ( - userEnv = "IRC_USER" - nickEnv = "IRC_NICK" - himsgEnv = "IRC_SEY_HI" - passEnv = "IRC_PASS" - chanEnv = "IRC_CHAN" - urlEnv = "IRC_URL" + userEnv = "IRC_USER" + nickEnv = "IRC_NICK" + himsgEnv = "IRC_SAY_HI" + passEnv = "IRC_PASS" + chanEnv = "IRC_CHAN" + urlEnv = "IRC_URL" + invitionsEnv = "IRC_ENABLE_INVITIONS" ) type catFact struct { @@ -48,12 +52,14 @@ var ( type stats struct { userMessages map[string]uint + invites map[string]bool mux *sync.Mutex } func newStats() *stats { return &stats{ userMessages: make(map[string]uint), + invites: make(map[string]bool), mux: &sync.Mutex{}, } } @@ -79,10 +85,10 @@ func (s *stats) online(e *irc.Event) int { } func (s *stats) realStats(e *irc.Event) { - e.Connection.Privmsg(channel, "🙀🙀🙀 WoW 🙀🙀🙀 NYAStat 🙀🙀🙀") + e.Connection.Privmsg(e.Nick, "🙀🙀🙀 WoW 🙀🙀🙀 NYAStat 🙀🙀🙀") t := "User %s sent %d messages" for u, v := range s.userMessages { - e.Connection.Privmsg(channel, fmt.Sprintf(t, u, v)) + e.Connection.Privmsg(e.Nick, fmt.Sprintf(t, u, v)) } } @@ -91,6 +97,22 @@ func (s *stats) printStats(e *irc.Event) { s.realStats(e) } +func (s *stats) invitionRequest(e *irc.Event) { + s.mux.Lock() + defer s.mux.Unlock() + + if !isInvitionsEnabled() { + return + } + + if sended, ok := s.invites[e.Nick]; !ok || !sended { + log.Printf("Sending invite request to %s", e.Nick) + + s.invites[e.Nick] = true + e.Connection.Privmsg(e.Nick, fmt.Sprintf("Привет, %s! В тиму 0х0 нужны два опытных человека. + в приват @difrex", e.Nick)) + } +} + func addCallbacks(irccon *irc.Connection, s *stats) { irccon.AddCallback("001", func(e *irc.Event) { log.Println("Welcome message:", e.Message()) @@ -101,16 +123,19 @@ func addCallbacks(irccon *irc.Connection, s *stats) { // Join to channel e.Connection.Join(channel) + e.Connection.Action(channel, "=^_^= https://gitea.difrex.ru/CTF2021/irc_bot") + // Greetings if sendHi != "" { e.Connection.Privmsg(channel, `Hi!`) e.Connection.Privmsg(channel, `I'm a cat facts bot!`) - e.Connection.Privmsg(channel, `Try cat /etc/passwd :p`) e.Connection.Privmsg(channel, `Source code and issue tracker: https://gitea.difrex.ru/CTF2021/irc_bot`) e.Connection.Privmsg(channel, `Now with gifs! ^_^`) } }) + irccon.AddCallback("JOIN", s.invitionRequest) + irccon.AddCallback("PRIVMSG", func(e *irc.Event) { log.Printf("Message from %s received: %s", e.Nick, e.Message()) s.addUser(e.Nick) @@ -138,11 +163,29 @@ func main() { irccon.Loop() } +func isHelpCommand(command string, e *irc.Event) bool { + if e.Nick != channel && strings.ToLower(command) == "help" { + return true + } + return false +} + +func showHelp(e *irc.Event) { + e.Connection.Privmsg(e.Nick, "HELP -- show this help") + e.Connection.Privmsg(e.Nick, "cat|meow|etc -- show cat fact or gif") + e.Connection.Privmsg(e.Nick, "nyastat -- show #ctf channel stats") +} + func doCommand(command string, e *irc.Event, s *stats) { - // if ok := statCommand(command); ok { - // s.printStats(e) - // return - // } + if ok := statCommand(command); ok { + s.printStats(e) + return + } + + if isHelpCommand(command, e) { + showHelp(e) + return + } if ok := checkCommad(command, e.Connection); !ok { return @@ -152,10 +195,11 @@ func doCommand(command string, e *irc.Event, s *stats) { i := rand.Intn(50) fmt.Println(i) if i > 30 { - catGif(e.Connection) + catGif(e) return } - catFacts(e.Connection) + + catFacts(e) } func statCommand(command string) bool { @@ -166,18 +210,16 @@ func statCommand(command string) bool { } func checkCommad(command string, con *irc.Connection) bool { - if !re.MatchString(command) { - return false - } - return true + return re.MatchString(command) } -func catGif(con *irc.Connection) (string, error) { +func catGif(e *irc.Event) (string, error) { res, err := http.Get("http://thecatapi.com/api/images/get?format=src&type=gif") if err != nil { return "", err } - con.Privmsg(channel, fmt.Sprintf(gifPrefix, res.Request.URL.String())) + log.Println("Send gif") + e.Connection.Privmsg(channel, fmt.Sprintf(gifPrefix, res.Request.URL.String())) return fmt.Sprintf(gifPrefix, res.Request.URL.String()), nil } @@ -196,8 +238,8 @@ func getJson(url string, v interface{}) error { return json.Unmarshal(body, v) } -func catFacts(con *irc.Connection) (string, error) { - +func catFacts(e *irc.Event) (string, error) { + log.Println("Send fact") data := &catFact{} err := getJson(catFactsURL, data) if err != nil { @@ -208,10 +250,31 @@ func catFacts(con *irc.Connection) (string, error) { return "", nil } - con.Privmsg(channel, fmt.Sprintf(msgPrefix, data.Fact)) + e.Connection.Privmsg(channel, fmt.Sprintf(msgPrefix, data.Fact)) return fmt.Sprintf(msgPrefix, data.Fact), nil } +func getChanName(e *irc.Event) string { + c := channel + if _, err := strconv.Atoi(e.Nick); err != nil { + c = e.Nick + } + + return c +} + +func isInvitionsEnabled() bool { + enabled := os.Getenv(invitionsEnv) + if strings.ToLower(enabled) == "yes" { + return true + } + return false +} + +func getNick() string { + return os.Getenv(nickEnv) +} + func init() { ch := os.Getenv(chanEnv) if ch != "" {