CTF2021/irc_bot
Archived
4
0
This repository has been archived on 2021-02-12. You can view files and clone it, but cannot push or open issues or pull requests.
irc_bot/main.go

205 lines
4.1 KiB
Go
Raw Normal View History

2021-01-16 00:20:50 +03:00
package main
import (
2021-01-16 17:55:13 +03:00
"encoding/json"
2021-01-16 00:20:50 +03:00
"fmt"
2021-01-16 17:55:13 +03:00
"io/ioutil"
2021-01-16 13:33:30 +03:00
"math/rand"
"net/http"
2021-01-16 00:20:50 +03:00
"os"
"regexp"
2021-01-16 17:55:13 +03:00
"sync"
2021-01-16 13:33:30 +03:00
"time"
2021-01-16 00:20:50 +03:00
2021-01-16 17:55:13 +03:00
"log"
2021-01-16 00:20:50 +03:00
irc "github.com/thoj/go-ircevent"
)
2021-01-16 18:23:56 +03:00
var channel = "#ctf"
var sendWelcome = ""
2021-01-16 00:20:50 +03:00
const (
2021-01-16 18:23:56 +03:00
pattern = "(?i)\\b(cat|gato|miau|meow|garfield|lolcat|кот|кошк)[s|z]{0,1}\\b"
2021-01-16 17:55:13 +03:00
nyastat = "nyastat"
2021-01-16 13:33:30 +03:00
msgPrefix = "I love cats! Here's a fact: %s ^_^"
gifPrefix = "Meow! Here's a gif: %s ^_^"
2021-01-16 00:20:50 +03:00
)
type catFact struct {
Fact string `json:"fact"`
Length int `json:"length"`
}
var (
re = regexp.MustCompile(pattern)
catFactsURL = "http://catfact.ninja/fact"
)
2021-01-16 17:55:13 +03:00
type stats struct {
userMessages map[string]uint
mux *sync.Mutex
}
func newStats() *stats {
return &stats{
userMessages: make(map[string]uint),
mux: &sync.Mutex{},
}
}
func (s *stats) addUser(user string) {
s.mux.Lock()
defer s.mux.Unlock()
if v, ok := s.userMessages[user]; ok {
log.Printf("User %s writes %d message", user, v+1)
s.userMessages[user]++
return
}
log.Printf("First message from user %s", user)
s.userMessages[user] = 1
}
func (s *stats) online(e *irc.Event) int {
e.Connection.Mutex.Lock()
defer e.Connection.Mutex.Unlock()
return -1
}
func (s *stats) realStats(e *irc.Event) {
e.Connection.Privmsg(channel, "🙀🙀🙀 WoW 🙀🙀🙀 NYAStat 🙀🙀🙀")
t := "User %s sent %d messages"
for u, v := range s.userMessages {
e.Connection.Privmsg(channel, fmt.Sprintf(t, u, v))
}
}
func (s *stats) printStats(e *irc.Event) {
s.online(e)
s.realStats(e)
}
2021-01-16 00:20:50 +03:00
func main() {
nick := os.Getenv("CTF2021NICK")
2021-01-16 10:49:40 +03:00
irccon := irc.IRC(nick, os.Getenv("CTF2021USER"))
2021-01-16 00:20:50 +03:00
2021-01-16 17:55:13 +03:00
s := newStats()
2021-01-16 00:20:50 +03:00
irccon.VerboseCallbackHandler = false
irccon.Debug = false
irccon.UseTLS = false
irccon.AddCallback("001", func(e *irc.Event) {
log.Println("Welcome message:", e.Message())
e.Connection.Privmsg("nickserv", "identify "+os.Getenv("CTF2021PASS"))
if sendWelcome != "" {
e.Connection.Join(channel)
e.Connection.Privmsg(channel, `I'm a cat bot!`)
e.Connection.Privmsg(channel, `Inspired from https://github.com/go-chat-bot/plugins/blob/master/catfacts/catfacts.go`)
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! ^_^`)
}
2021-01-16 00:20:50 +03:00
})
irccon.AddCallback("PRIVMSG", func(e *irc.Event) {
log.Printf("Message from %s received: %s", e.Nick, e.Message())
2021-01-16 17:55:13 +03:00
s.addUser(e.Nick)
doCommand(e.Message(), e, s)
2021-01-16 00:20:50 +03:00
})
err := irccon.Connect(os.Getenv("CTF2021URL"))
if err != nil {
fmt.Printf("Err %s", err)
return
}
irccon.Loop()
}
2021-01-16 17:55:13 +03:00
func doCommand(command string, e *irc.Event, s *stats) {
// if ok := statCommand(command); ok {
// s.printStats(e)
// return
// }
2021-01-16 17:55:13 +03:00
if ok := checkCommad(command, e.Connection); !ok {
2021-01-16 13:33:30 +03:00
return
}
rand.Seed(time.Now().UnixNano())
i := rand.Intn(50)
fmt.Println(i)
if i > 30 {
2021-01-16 17:55:13 +03:00
catGif(e.Connection)
2021-01-16 13:33:30 +03:00
return
}
2021-01-16 17:55:13 +03:00
catFacts(e.Connection)
}
func statCommand(command string) bool {
if command == nyastat {
return true
}
return false
2021-01-16 13:33:30 +03:00
}
func checkCommad(command string, con *irc.Connection) bool {
2021-01-16 00:20:50 +03:00
if !re.MatchString(command) {
2021-01-16 13:33:30 +03:00
return false
2021-01-16 00:20:50 +03:00
}
2021-01-16 13:33:30 +03:00
return true
}
func catGif(con *irc.Connection) (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()))
return fmt.Sprintf(gifPrefix, res.Request.URL.String()), nil
}
2021-01-16 17:55:13 +03:00
func getJson(url string, v interface{}) error {
res, err := http.Get(url)
if err != nil {
return err
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
return err
}
return json.Unmarshal(body, v)
}
2021-01-16 13:33:30 +03:00
func catFacts(con *irc.Connection) (string, error) {
2021-01-16 00:20:50 +03:00
data := &catFact{}
2021-01-16 17:55:13 +03:00
err := getJson(catFactsURL, data)
2021-01-16 00:20:50 +03:00
if err != nil {
return "", err
}
if len(data.Fact) == 0 {
return "", nil
}
con.Privmsg(channel, fmt.Sprintf(msgPrefix, data.Fact))
return fmt.Sprintf(msgPrefix, data.Fact), nil
}
2021-01-16 18:23:56 +03:00
func init() {
ch := os.Getenv("CTF2021CHANNEL")
if ch != "" {
channel = ch
}
sendWelcome = os.Getenv("CTF2021WC")
2021-01-16 18:23:56 +03:00
}