CTF2021/irc_bot
Archived
4
0

Allow to disable invition requests

This commit is contained in:
Denis Zheleztsov 2021-01-19 11:50:20 +03:00
parent 0d6e2457b5
commit 108dbfdd52
Signed by: Difrex
GPG Key ID: D423378A747E202E
2 changed files with 97 additions and 25 deletions

View File

@ -4,6 +4,8 @@ About cats
Inspired from https://github.com/go-chat-bot/plugins/blob/master/catfacts/catfacts.go Inspired from https://github.com/go-chat-bot/plugins/blob/master/catfacts/catfacts.go
## Build
```go ```go
go build go build
``` ```
@ -15,3 +17,10 @@ export IRC_PASS="passw0rd"
export IRC_URL="localhost:6667" export IRC_URL="localhost:6667"
./ctf2021_ircbot | tee bot.log ./ctf2021_ircbot | tee bot.log
``` ```
## Commands
```
cat|meow|etc - show cat fact or gif
nyastat - show #ctf channel stats
```

113
main.go
View File

@ -8,11 +8,14 @@ import (
"net/http" "net/http"
"os" "os"
"regexp" "regexp"
"strings"
"sync" "sync"
"time" "time"
"log" "log"
"strconv"
irc "github.com/thoj/go-ircevent" irc "github.com/thoj/go-ircevent"
) )
@ -20,7 +23,7 @@ var channel = "#ctf"
var sendHi = "" var sendHi = ""
const ( 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" nyastat = "nyastat"
msgPrefix = "I love cats! Here's a fact: %s ^_^" msgPrefix = "I love cats! Here's a fact: %s ^_^"
gifPrefix = "Meow! Here's a gif: %s ^_^" gifPrefix = "Meow! Here's a gif: %s ^_^"
@ -28,12 +31,13 @@ const (
// environment variables // environment variables
const ( const (
userEnv = "IRC_USER" userEnv = "IRC_USER"
nickEnv = "IRC_NICK" nickEnv = "IRC_NICK"
himsgEnv = "IRC_SEY_HI" himsgEnv = "IRC_SAY_HI"
passEnv = "IRC_PASS" passEnv = "IRC_PASS"
chanEnv = "IRC_CHAN" chanEnv = "IRC_CHAN"
urlEnv = "IRC_URL" urlEnv = "IRC_URL"
invitionsEnv = "IRC_ENABLE_INVITIONS"
) )
type catFact struct { type catFact struct {
@ -48,12 +52,14 @@ var (
type stats struct { type stats struct {
userMessages map[string]uint userMessages map[string]uint
invites map[string]bool
mux *sync.Mutex mux *sync.Mutex
} }
func newStats() *stats { func newStats() *stats {
return &stats{ return &stats{
userMessages: make(map[string]uint), userMessages: make(map[string]uint),
invites: make(map[string]bool),
mux: &sync.Mutex{}, mux: &sync.Mutex{},
} }
} }
@ -79,10 +85,10 @@ func (s *stats) online(e *irc.Event) int {
} }
func (s *stats) realStats(e *irc.Event) { 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" t := "User %s sent %d messages"
for u, v := range s.userMessages { 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) 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) { func addCallbacks(irccon *irc.Connection, s *stats) {
irccon.AddCallback("001", func(e *irc.Event) { irccon.AddCallback("001", func(e *irc.Event) {
log.Println("Welcome message:", e.Message()) log.Println("Welcome message:", e.Message())
@ -101,16 +123,19 @@ func addCallbacks(irccon *irc.Connection, s *stats) {
// Join to channel // Join to channel
e.Connection.Join(channel) e.Connection.Join(channel)
e.Connection.Action(channel, "=^_^= https://gitea.difrex.ru/CTF2021/irc_bot")
// Greetings // Greetings
if sendHi != "" { if sendHi != "" {
e.Connection.Privmsg(channel, `Hi!`) e.Connection.Privmsg(channel, `Hi!`)
e.Connection.Privmsg(channel, `I'm a cat facts bot!`) 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, `Source code and issue tracker: https://gitea.difrex.ru/CTF2021/irc_bot`)
e.Connection.Privmsg(channel, `Now with gifs! ^_^`) e.Connection.Privmsg(channel, `Now with gifs! ^_^`)
} }
}) })
irccon.AddCallback("JOIN", s.invitionRequest)
irccon.AddCallback("PRIVMSG", func(e *irc.Event) { irccon.AddCallback("PRIVMSG", func(e *irc.Event) {
log.Printf("Message from %s received: %s", e.Nick, e.Message()) log.Printf("Message from %s received: %s", e.Nick, e.Message())
s.addUser(e.Nick) s.addUser(e.Nick)
@ -138,11 +163,29 @@ func main() {
irccon.Loop() 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) { func doCommand(command string, e *irc.Event, s *stats) {
// if ok := statCommand(command); ok { if ok := statCommand(command); ok {
// s.printStats(e) s.printStats(e)
// return return
// } }
if isHelpCommand(command, e) {
showHelp(e)
return
}
if ok := checkCommad(command, e.Connection); !ok { if ok := checkCommad(command, e.Connection); !ok {
return return
@ -152,10 +195,11 @@ func doCommand(command string, e *irc.Event, s *stats) {
i := rand.Intn(50) i := rand.Intn(50)
fmt.Println(i) fmt.Println(i)
if i > 30 { if i > 30 {
catGif(e.Connection) catGif(e)
return return
} }
catFacts(e.Connection)
catFacts(e)
} }
func statCommand(command string) bool { func statCommand(command string) bool {
@ -166,18 +210,16 @@ func statCommand(command string) bool {
} }
func checkCommad(command string, con *irc.Connection) bool { func checkCommad(command string, con *irc.Connection) bool {
if !re.MatchString(command) { return re.MatchString(command)
return false
}
return true
} }
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") res, err := http.Get("http://thecatapi.com/api/images/get?format=src&type=gif")
if err != nil { if err != nil {
return "", err 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 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) 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{} data := &catFact{}
err := getJson(catFactsURL, data) err := getJson(catFactsURL, data)
if err != nil { if err != nil {
@ -208,10 +250,31 @@ func catFacts(con *irc.Connection) (string, error) {
return "", nil 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 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() { func init() {
ch := os.Getenv(chanEnv) ch := os.Getenv(chanEnv)
if ch != "" { if ch != "" {