Add more debug, small optimizations
* Replace all time.Sleep() with <-time.NewTimer().C * Add log.debug callback to all incomming network events * Use slices.Contains() instead of iterating slices in for Loop
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
|||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"fmt"
|
"fmt"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -16,7 +17,9 @@ import (
|
|||||||
// ircClientInit горутинка для работы с протоколом irc.
|
// ircClientInit горутинка для работы с протоколом irc.
|
||||||
func ircClientRun() {
|
func ircClientRun() {
|
||||||
for !shutdown {
|
for !shutdown {
|
||||||
// Иницализируем irc-клиента
|
// Иницализируем irc-клиента.
|
||||||
|
// TODO: make use of capabilities: https://defs.ircdocs.horse/defs/clientcaps .
|
||||||
|
// TODO: make use of tags caps https://defs.ircdocs.horse/defs/tags .
|
||||||
serverString := fmt.Sprintf("%s:%d", config.Irc.Server, config.Irc.Port)
|
serverString := fmt.Sprintf("%s:%d", config.Irc.Server, config.Irc.Port)
|
||||||
log.Debugf("Preparing to connect to %s", serverString)
|
log.Debugf("Preparing to connect to %s", serverString)
|
||||||
log.Debugf("Using nick %s and username %s", config.Irc.Nick, config.Irc.User)
|
log.Debugf("Using nick %s and username %s", config.Irc.Nick, config.Irc.User)
|
||||||
@@ -49,12 +52,11 @@ func ircClientRun() {
|
|||||||
// Навесим коллбэков на некоторые ответы сервера на наши запросы.
|
// Навесим коллбэков на некоторые ответы сервера на наши запросы.
|
||||||
|
|
||||||
// 001 RPL_WELCOME уже есть в github.com/thoj/go-ircevent/irc_callback.go.
|
// 001 RPL_WELCOME уже есть в github.com/thoj/go-ircevent/irc_callback.go.
|
||||||
|
|
||||||
// Сделаем уже что-то полезное! Motd нам уже прислали и теперь можно авторизоваться и джойниться
|
// Сделаем уже что-то полезное! Motd нам уже прислали и теперь можно авторизоваться и джойниться
|
||||||
ircClient.AddCallback("004", func(e *irc.Event) {
|
ircClient.AddCallback("004", func(e *irc.Event) {
|
||||||
// Из это строки мы можем узнать, какие флаги для user MODE и channem MODE можно навешивать.
|
// Из это строки мы можем узнать, какие флаги для user MODE и channem MODE можно навешивать.
|
||||||
// Как минимум, эта строка нам нужна, чтобы выяснить, можем ли мы взять себе +B, мы же бот :).
|
// Как минимум, эта строка нам нужна, чтобы выяснить, можем ли мы взять себе +B, мы же бот :).
|
||||||
log.Debugf("004 RPL_MYINFO, %s", e.Raw)
|
|
||||||
|
|
||||||
e.Connection.Lock()
|
e.Connection.Lock()
|
||||||
|
|
||||||
// Формат строки с MODE-ами https://datatracker.ietf.org/doc/html/rfc2812#section-5.1 .
|
// Формат строки с MODE-ами https://datatracker.ietf.org/doc/html/rfc2812#section-5.1 .
|
||||||
@@ -80,12 +82,15 @@ func ircClientRun() {
|
|||||||
e.Connection.Unlock()
|
e.Connection.Unlock()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
ircClient.AddCallback("005", func(e *irc.Event) {
|
||||||
|
// TODO: Make use of it. https://defs.ircdocs.horse/defs/isupport
|
||||||
|
})
|
||||||
|
|
||||||
ircClient.AddCallback("319", func(e *irc.Event) {
|
ircClient.AddCallback("319", func(e *irc.Event) {
|
||||||
/* Это одна из строк с данными, прилетающая в ответ на запрос whois на определённого юзера
|
/* Это одна из строк с данными, прилетающая в ответ на запрос whois на определённого юзера
|
||||||
* Из этой строки нас интересует, на каких каналах пользователь op (то есть с префиксом @) или имеет voice
|
* Из этой строки нас интересует, на каких каналах пользователь op (то есть с префиксом @) или имеет voice
|
||||||
* (то есть с префиксом +) чтобы внести его в свою базу mode-ов.
|
* (то есть с префиксом +) чтобы внести его в свою базу mode-ов.
|
||||||
*/
|
*/
|
||||||
log.Debugf("319 RPL_WHOISCHANNELS, %s", e.Raw)
|
|
||||||
channelsWithModes := strings.Split(e.Arguments[2], " ")
|
channelsWithModes := strings.Split(e.Arguments[2], " ")
|
||||||
dstNick := e.Arguments[1]
|
dstNick := e.Arguments[1]
|
||||||
|
|
||||||
@@ -120,7 +125,6 @@ func ircClientRun() {
|
|||||||
|
|
||||||
ircClient.AddCallback("353", func(e *irc.Event) {
|
ircClient.AddCallback("353", func(e *irc.Event) {
|
||||||
// Это одна из строк данных, прилетающая в ответ на запрос names, на канале
|
// Это одна из строк данных, прилетающая в ответ на запрос names, на канале
|
||||||
log.Debugf("353 RPL_NAMREPLY, %s", e.Raw)
|
|
||||||
e.Connection.Lock()
|
e.Connection.Lock()
|
||||||
namesString := e.Arguments[3]
|
namesString := e.Arguments[3]
|
||||||
channel := e.Arguments[2]
|
channel := e.Arguments[2]
|
||||||
@@ -155,16 +159,9 @@ func ircClientRun() {
|
|||||||
e.Connection.Unlock()
|
e.Connection.Unlock()
|
||||||
})
|
})
|
||||||
|
|
||||||
ircClient.AddCallback("352", func(e *irc.Event) {
|
|
||||||
// Относительно бесполезная для нас команда. Не возвращает канала (в случае с ngircd), так что узнать mode
|
|
||||||
// юзера на конкретном канале из этого невозможно. А остальные данные пока непонятно куда применять.
|
|
||||||
log.Warnf("352 RPL_WHOREPLY, %s", e.Raw)
|
|
||||||
})
|
|
||||||
|
|
||||||
// Если сервер не может прочитать MOTD, то он может вернуть 422 ERR_NOMOTD, тоде самое навесим и туда тоже.
|
// Если сервер не может прочитать MOTD, то он может вернуть 422 ERR_NOMOTD, тоде самое навесим и туда тоже.
|
||||||
ircClient.AddCallback("376", func(e *irc.Event) {
|
ircClient.AddCallback("376", func(e *irc.Event) {
|
||||||
log.Debugf("376 RPL_ENDOFMOTD %s", e.Raw)
|
// TODO: make use of modes https://defs.ircdocs.horse/defs/usermodes
|
||||||
|
|
||||||
// Если у нас есть доступный +B возьмём его себе, мы же бот.
|
// Если у нас есть доступный +B возьмём его себе, мы же бот.
|
||||||
announced, _ := availableUserModes.Get("announced")
|
announced, _ := availableUserModes.Get("announced")
|
||||||
botFlag, _ := availableUserModes.Get("B")
|
botFlag, _ := availableUserModes.Get("B")
|
||||||
@@ -173,6 +170,7 @@ func ircClientRun() {
|
|||||||
if botFlag {
|
if botFlag {
|
||||||
log.Info("Grabbing +B flag to mark me as bot")
|
log.Info("Grabbing +B flag to mark me as bot")
|
||||||
ircClient.Mode(ircClient.GetNick(), "+B")
|
ircClient.Mode(ircClient.GetNick(), "+B")
|
||||||
|
// TODO: Wait for it.
|
||||||
} else {
|
} else {
|
||||||
log.Info("Skip +B flag, server does not support it, noone will know that I am bot")
|
log.Info("Skip +B flag, server does not support it, noone will know that I am bot")
|
||||||
}
|
}
|
||||||
@@ -195,6 +193,7 @@ func ircClientRun() {
|
|||||||
log.Infof("Joining to %s channel", channel)
|
log.Infof("Joining to %s channel", channel)
|
||||||
ircClient.Join(channel)
|
ircClient.Join(channel)
|
||||||
}
|
}
|
||||||
|
// TODO: wait for join or join error.
|
||||||
})
|
})
|
||||||
|
|
||||||
// Навесим коллбэков на все возможные и невозможные error status code, которые мы можем получить и сдампим это
|
// Навесим коллбэков на все возможные и невозможные error status code, которые мы можем получить и сдампим это
|
||||||
@@ -234,8 +233,7 @@ func ircClientRun() {
|
|||||||
|
|
||||||
// Аналогичный коллбэк висит на 376 RPL_ENDOFMOTD.
|
// Аналогичный коллбэк висит на 376 RPL_ENDOFMOTD.
|
||||||
ircClient.AddCallback("422", func(e *irc.Event) {
|
ircClient.AddCallback("422", func(e *irc.Event) {
|
||||||
log.Debugf("422 ERR_NOMOTD %s", e.Raw)
|
// TODO: make use of modes https://defs.ircdocs.horse/defs/usermodes
|
||||||
|
|
||||||
// Если у нас есть доступный +B возьмём его себе, мы же бот.
|
// Если у нас есть доступный +B возьмём его себе, мы же бот.
|
||||||
botFlag, ok := availableUserModes.Get("B")
|
botFlag, ok := availableUserModes.Get("B")
|
||||||
|
|
||||||
@@ -304,6 +302,16 @@ func ircClientRun() {
|
|||||||
log.Warnf("442 ERR_NOTONCHANNEL, %s", e.Raw)
|
log.Warnf("442 ERR_NOTONCHANNEL, %s", e.Raw)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
ircClient.AddCallback("443", func(e *irc.Event) {
|
||||||
|
// Returned when a client tries to invite a user to a channel they're already on.
|
||||||
|
log.Errorf("443 ERR_USERONCHANNEL, %s", e.Raw)
|
||||||
|
})
|
||||||
|
|
||||||
|
ircClient.AddCallback("446", func(e *irc.Event) {
|
||||||
|
// Returned by USERS when it has been disabled or not implemented.
|
||||||
|
log.Errorf("446 ERR_USERSDISABLED, %s", e.Raw)
|
||||||
|
})
|
||||||
|
|
||||||
ircClient.AddCallback("451", func(e *irc.Event) {
|
ircClient.AddCallback("451", func(e *irc.Event) {
|
||||||
// Предполагается, что надо авторизоваться, перед тем как что-то делать на сервере
|
// Предполагается, что надо авторизоваться, перед тем как что-то делать на сервере
|
||||||
log.Errorf("451 ERR_NOTREGISTERED, %s", e.Raw)
|
log.Errorf("451 ERR_NOTREGISTERED, %s", e.Raw)
|
||||||
@@ -326,19 +334,19 @@ func ircClientRun() {
|
|||||||
log.Errorf("465 ERR_YOUREBANNEDCREEP, %s", e.Raw)
|
log.Errorf("465 ERR_YOUREBANNEDCREEP, %s", e.Raw)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
ircClient.AddCallback("467", func(e *irc.Event) {
|
||||||
|
log.Errorf("467 ERR_KEYSET, %s", e.Raw)
|
||||||
|
})
|
||||||
|
|
||||||
ircClient.AddCallback("471", func(e *irc.Event) {
|
ircClient.AddCallback("471", func(e *irc.Event) {
|
||||||
// Это значит, что народу на канале максимальное количество. Будем пробовать присунуться раз в 30 сек.
|
// Это значит, что народу на канале максимальное количество. Будем пробовать присунуться раз в 30 сек.
|
||||||
channel := e.Arguments[1]
|
channel := e.Arguments[1]
|
||||||
log.Warnf("471 ERR_CHANNELISFULL, %s", e.Raw)
|
log.Warnf("471 ERR_CHANNELISFULL, %s", e.Raw)
|
||||||
time.Sleep(30 * time.Second)
|
<-time.NewTimer(30 * time.Second).C
|
||||||
|
|
||||||
// Проверяем, а должны ли мы быть заджоенныеми к указанному, каналу, а то вдруг нет?
|
// Проверяем, а должны ли мы быть заджоенныеми к указанному, каналу, а то вдруг нет?
|
||||||
for _, ircChan := range config.Irc.Channels {
|
if slices.Contains(config.Irc.Channels, channel) {
|
||||||
if ircChan == channel {
|
ircClient.Join(channel)
|
||||||
ircClient.Join(channel)
|
|
||||||
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -351,15 +359,11 @@ func ircClientRun() {
|
|||||||
// По завершении работ +i снимают.
|
// По завершении работ +i снимают.
|
||||||
channel := e.Arguments[1]
|
channel := e.Arguments[1]
|
||||||
log.Errorf("473 ERR_INVITEONLYCHAN, %s", e.Raw)
|
log.Errorf("473 ERR_INVITEONLYCHAN, %s", e.Raw)
|
||||||
time.Sleep(30 * time.Second)
|
<-time.NewTimer(30 * time.Second).C
|
||||||
|
|
||||||
// Проверяем, а должны ли мы быть заджоенныеми к указанному, каналу, а то вдруг нет?
|
// Проверяем, а должны ли мы быть заджоенными к указанному, каналу, а то вдруг нет?
|
||||||
for _, ircChan := range config.Irc.Channels {
|
if slices.Contains(config.Irc.Channels, channel) {
|
||||||
if ircChan == channel {
|
ircClient.Join(channel)
|
||||||
ircClient.Join(channel)
|
|
||||||
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -369,19 +373,21 @@ func ircClientRun() {
|
|||||||
|
|
||||||
log.Errorf("474 ERR_BANNEDFROMCHAN, %s", e.Raw)
|
log.Errorf("474 ERR_BANNEDFROMCHAN, %s", e.Raw)
|
||||||
// Если нас забанили, то информацию о MODE-ах пользователей мы теряем
|
// Если нас забанили, то информацию о MODE-ах пользователей мы теряем
|
||||||
time.Sleep(30 * time.Second)
|
<-time.NewTimer(30 * time.Second).C
|
||||||
|
|
||||||
// Вдруг, нас забанили, но какбэ не навсегда?
|
// Вдруг, нас забанили, но какбэ не навсегда?
|
||||||
|
// TODO: вынести в настройки?
|
||||||
|
|
||||||
// Проверяем, а должны ли мы быть заджоенныеми к указанному, каналу, а то вдруг нет?
|
// Проверяем, а должны ли мы быть заджоенныеми к указанному, каналу, а то вдруг нет?
|
||||||
for _, ircChan := range config.Irc.Channels {
|
if slices.Contains(config.Irc.Channels, channel) {
|
||||||
if ircChan == channel {
|
ircClient.Join(channel)
|
||||||
ircClient.Join(channel)
|
|
||||||
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
ircClient.AddCallback("475", func(e *irc.Event) {
|
||||||
|
log.Errorf("475 ERR_BADCHANNELKEY, %s", e.Raw)
|
||||||
|
})
|
||||||
|
|
||||||
ircClient.AddCallback("477", func(e *irc.Event) {
|
ircClient.AddCallback("477", func(e *irc.Event) {
|
||||||
log.Errorf("477 ERR_NOCHANMODES, %s", e.Raw)
|
log.Errorf("477 ERR_NOCHANMODES, %s", e.Raw)
|
||||||
})
|
})
|
||||||
@@ -390,6 +396,10 @@ func ircClientRun() {
|
|||||||
log.Errorf("478 ERR_BANLISTFULL, %s", e.Raw)
|
log.Errorf("478 ERR_BANLISTFULL, %s", e.Raw)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
ircClient.AddCallback("481", func(e *irc.Event) {
|
||||||
|
log.Errorf("481 ERR_NOPRIVILEGES, %s", e.Raw)
|
||||||
|
})
|
||||||
|
|
||||||
ircClient.AddCallback("482", func(e *irc.Event) {
|
ircClient.AddCallback("482", func(e *irc.Event) {
|
||||||
log.Errorf("482 ERR_CHANOPRIVSNEEDED, %s", e.Raw)
|
log.Errorf("482 ERR_CHANOPRIVSNEEDED, %s", e.Raw)
|
||||||
})
|
})
|
||||||
@@ -402,6 +412,10 @@ func ircClientRun() {
|
|||||||
log.Errorf("485 ERR_UNIQOPPRIVSNEEDED, %s", e.Raw)
|
log.Errorf("485 ERR_UNIQOPPRIVSNEEDED, %s", e.Raw)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
ircClient.AddCallback("491", func(e *irc.Event) {
|
||||||
|
log.Errorf("491 ERR_NOOPERHOST, %s", e.Raw)
|
||||||
|
})
|
||||||
|
|
||||||
ircClient.AddCallback("501", func(e *irc.Event) {
|
ircClient.AddCallback("501", func(e *irc.Event) {
|
||||||
log.Errorf("501 ERR_UMODEUNKNOWNFLAG, %s", e.Raw)
|
log.Errorf("501 ERR_UMODEUNKNOWNFLAG, %s", e.Raw)
|
||||||
})
|
})
|
||||||
@@ -421,7 +435,8 @@ func ircClientRun() {
|
|||||||
userMode.Delete(channel)
|
userMode.Delete(channel)
|
||||||
// TODO: reason?
|
// TODO: reason?
|
||||||
log.Warnf("%s kicks us from %s", srcFullNick, channel)
|
log.Warnf("%s kicks us from %s", srcFullNick, channel)
|
||||||
time.Sleep(10 * time.Second)
|
<-time.NewTimer(10 * time.Second).C
|
||||||
|
|
||||||
ircClient.Join(channel)
|
ircClient.Join(channel)
|
||||||
} else {
|
} else {
|
||||||
// Кого-то другого кикнули с канала
|
// Кого-то другого кикнули с канала
|
||||||
@@ -557,11 +572,9 @@ func ircClientRun() {
|
|||||||
ircMsgParser(e.Arguments[0], e.Nick, e.User, e.Source, e.Arguments[1])
|
ircMsgParser(e.Arguments[0], e.Nick, e.User, e.Source, e.Arguments[1])
|
||||||
})
|
})
|
||||||
|
|
||||||
/*
|
ircClient.AddCallback("*", func(e *irc.Event) {
|
||||||
ircClient.AddCallback("*", func(e *irc.Event) {
|
log.Debugf("Incoming EVENT (Raw): %s", e.Raw)
|
||||||
log.Debugf("Incoming EVENT (Raw): %s", e.Raw)
|
})
|
||||||
})
|
|
||||||
*/
|
|
||||||
|
|
||||||
log.Debugf("Make an actual connection to irc")
|
log.Debugf("Make an actual connection to irc")
|
||||||
|
|
||||||
@@ -594,7 +607,7 @@ func ircSend() {
|
|||||||
|
|
||||||
sleepDelay := time.Duration(config.Irc.RateLimit.SimpleDelay) * time.Millisecond
|
sleepDelay := time.Duration(config.Irc.RateLimit.SimpleDelay) * time.Millisecond
|
||||||
log.Debugf("Due to delay type simple_delay waiting for %d milliseconds", int(sleepDelay))
|
log.Debugf("Due to delay type simple_delay waiting for %d milliseconds", int(sleepDelay))
|
||||||
time.Sleep(sleepDelay)
|
<-time.NewTimer(sleepDelay).C
|
||||||
case "token_bucket":
|
case "token_bucket":
|
||||||
var currentTimeMs = time.Now().UnixMilli()
|
var currentTimeMs = time.Now().UnixMilli()
|
||||||
|
|
||||||
@@ -636,7 +649,8 @@ func ircSend() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("Sleeping for %d milliseconds", sleepPeriod)
|
log.Debugf("Sleeping for %d milliseconds", sleepPeriod)
|
||||||
time.Sleep(time.Duration(sleepPeriod) * time.Millisecond)
|
<-time.NewTimer(time.Duration(sleepPeriod) * time.Millisecond).C
|
||||||
|
|
||||||
currentTimeMs = time.Now().UnixMilli()
|
currentTimeMs = time.Now().UnixMilli()
|
||||||
// Обновим время отправки сообщения
|
// Обновим время отправки сообщения
|
||||||
msgBucket.Timestamps[len(msgBucket.Timestamps)-1] = currentTimeMs
|
msgBucket.Timestamps[len(msgBucket.Timestamps)-1] = currentTimeMs
|
||||||
|
|||||||
Reference in New Issue
Block a user