Update README.md, Design.txt and some comments here and there
This commit is contained in:
@@ -1,12 +1,5 @@
|
|||||||
Oсобенности реализации клиентской части.
|
Oсобенности реализации клиентской части.
|
||||||
|
|
||||||
Общие положения
|
|
||||||
------------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Nick для room-ов един и не может задаваться на per-conference основе. На этом завязаны отсылка ping-ов и определение
|
|
||||||
pong-ов, как минимум. Хотя формально джойниться можно с любым ником :) но что-то не хочется потом распутывать этот
|
|
||||||
клубок.
|
|
||||||
|
|
||||||
|
|
||||||
XEP-0410 MUC Self-Ping (Schrödinger's Chat)
|
XEP-0410 MUC Self-Ping (Schrödinger's Chat)
|
||||||
------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
24
README.md
24
README.md
@@ -1,9 +1,17 @@
|
|||||||
# Buny Jabber Bot
|
# Buny Jabber Bot
|
||||||
|
|
||||||
Простой бот, работающий по протоколу xmpp. Его задача - банить абьюзеров чата.
|
<table style="border-collapse: collapse; border: none;">
|
||||||
|
<tr style="border: none;">
|
||||||
Этот бот автоматизирует уборку человеческой грязи. Самый важный вопрос, который следует себе задать перед его
|
<td rowspan=2 style="border: none;"><img src="assets/avatar.png" alt="Бани"></td>
|
||||||
использованием - а не забаню ли я кого-то лишнего?
|
<td style="border: none;">Простой бот, работающий по протоколу xmpp. Его задача - банить абьюзеров чата. При его
|
||||||
|
создании не стояло задачи сделать что-то красивое в архитектурном или каком-то другм плане.</td>
|
||||||
|
</tr>
|
||||||
|
<tr style="border: none;">
|
||||||
|
<td style="border: none;">Этот бот автоматизирует уборку человеческой грязи. Самый важный вопрос, который следует себе
|
||||||
|
задать перед его использованием - а не забаню ли я кого-то лишнего?
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
## Что он может?
|
## Что он может?
|
||||||
|
|
||||||
@@ -11,12 +19,12 @@
|
|||||||
работает по классическим механикам (шифрованный канал связи, без возможности коммуникации в незашифрованном виде),
|
работает по классическим механикам (шифрованный канал связи, без возможности коммуникации в незашифрованном виде),
|
||||||
без поддержки механизма start tls. (Что-то в гошке или на стороне сервера при выборе StartTLS не работает.)
|
без поддержки механизма start tls. (Что-то в гошке или на стороне сервера при выборе StartTLS не работает.)
|
||||||
* Имеет возможность заносить пользователей в бан-лист, согласно заданным в чёрном списке правилам:
|
* Имеет возможность заносить пользователей в бан-лист, согласно заданным в чёрном списке правилам:
|
||||||
- по совпадению с регулярными выражениями в nick-е или jid-е злодея
|
- По совпадению с регулярными выражениями в nick-е или jid-е злодея
|
||||||
- по регулярным выражениям характерных фраз.
|
- По регулярным выражениям характерных фраз.
|
||||||
- Правила можно настроить как глобально, для всех комнат, где присутствует бот, так и для каждой комнаты отдельно.
|
- Правила можно настроить как глобально, для всех комнат, где присутствует бот, так и для каждой комнаты отдельно.
|
||||||
- При изменении списка правил бота не надо перезапускать, достаточно отдать ему команду rehash либо в приват, либо
|
- При изменении списка правил бота не надо перезапускать, достаточно отдать ему команду rehash либо в приват, либо
|
||||||
прям в чатике.
|
прям в чатике.
|
||||||
* Есть настройка заходить в разные комнаты под разными никами
|
* Есть настройка заходить в разные комнаты под разными никами.
|
||||||
|
|
||||||
## Что он не может?
|
## Что он не может?
|
||||||
|
|
||||||
@@ -48,7 +56,7 @@ make
|
|||||||
|
|
||||||
Почему нельзя оставить комнату анонимной? А тут всё просто, в банлист заносится реальный jid пользователя, а не его ник.
|
Почему нельзя оставить комнату анонимной? А тут всё просто, в банлист заносится реальный jid пользователя, а не его ник.
|
||||||
Соответственно, бот должен видеть этот самый реальный jid. В анонимной комнате бот не сможет увидеть реальный jid.
|
Соответственно, бот должен видеть этот самый реальный jid. В анонимной комнате бот не сможет увидеть реальный jid.
|
||||||
А автокик - это конечно хорошо, но есть нюанс: можно, например, гадить ником, поэтому бот в автокик не умеет.
|
А автокик - это, конечно, хорошо, но есть нюанс: можно, например, гадить ником, поэтому бот в автокик не умеет.
|
||||||
|
|
||||||
## Как работает бан?
|
## Как работает бан?
|
||||||
|
|
||||||
|
|||||||
BIN
assets/avatar.png
Normal file
BIN
assets/avatar.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 26 KiB |
@@ -190,8 +190,9 @@
|
|||||||
# command sign символ-суффикс команды, например !rehash или !help. По-умолчанию "!".
|
# command sign символ-суффикс команды, например !rehash или !help. По-умолчанию "!".
|
||||||
"csign" : "!",
|
"csign" : "!",
|
||||||
|
|
||||||
# Многословность логов. Если не задано, то info. Debug - ДЕЙСТВИТЕЛЬНО вербозный уровень логгирования.
|
# Многословность логов. Если не задано, то info.
|
||||||
# Есть ещё trace :)
|
# Есть разные уровни trace, debug, debug, info, warn, error, fatal.
|
||||||
|
# Практически задействованы только trace, debug, info.
|
||||||
"loglevel": "debug",
|
"loglevel": "debug",
|
||||||
|
|
||||||
# Если не задан, логи идут в STDOUT
|
# Если не задан, логи идут в STDOUT
|
||||||
|
|||||||
8
lib.go
8
lib.go
@@ -42,8 +42,8 @@ func sigHandler() {
|
|||||||
if isConnected && !shutdown {
|
if isConnected && !shutdown {
|
||||||
log.Debug("Try to set our presence to Unavailable and status to Offline")
|
log.Debug("Try to set our presence to Unavailable and status to Offline")
|
||||||
|
|
||||||
// Вот тут понадобится коллекция известных пользователей, чтобы им разослать presence, что бот свалил в offline
|
// Вот тут понадобится коллекция известных пользователей, чтобы им разослать presence, что бот свалил в
|
||||||
// Пока за неимением лучшего сообщим об этом самим себе.
|
// offline. Пока за неимением лучшего сообщим об этом самим себе.
|
||||||
for _, room := range roomsConnected {
|
for _, room := range roomsConnected {
|
||||||
if _, err := talk.SendPresence(
|
if _, err := talk.SendPresence(
|
||||||
xmpp.Presence{ //nolint:exhaustruct
|
xmpp.Presence{ //nolint:exhaustruct
|
||||||
@@ -317,7 +317,7 @@ func establishConnection() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// joinMu джойнится к конференциям/каналам/комнатам в джаббере.
|
// joinMuс джойнится к конференциям/каналам/комнатам в джаббере.
|
||||||
func joinMuc(room string) {
|
func joinMuc(room string) {
|
||||||
log.Debugf("Sending disco#info from %s to %s", talk.JID(), room)
|
log.Debugf("Sending disco#info from %s to %s", talk.JID(), room)
|
||||||
|
|
||||||
@@ -411,7 +411,7 @@ func joinMuc(room string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// probeServerLiveness проверяет живость соединения с сервером. Для многих серверов обязательная штука, без которой
|
// probeServerLiveness проверяет живость соединения с сервером. Для многих серверов обязательная штука, без которой
|
||||||
// они выкидывают клиента через некоторое время неактивности.
|
// они выкидывают (дисконнектят) клиента через некоторое время неактивности.
|
||||||
func probeServerLiveness() { //nolint:gocognit
|
func probeServerLiveness() { //nolint:gocognit
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
|
|||||||
18
main.go
18
main.go
@@ -50,9 +50,9 @@ func init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// main - фактичеки начало и соновное тело программы.
|
// main - фактичеcки начало и основное тело программы.
|
||||||
func main() {
|
func main() {
|
||||||
// Откроем лог и скормим его логгеру
|
// Откроем лог и скормим его логгеру.
|
||||||
if config.Log != "" {
|
if config.Log != "" {
|
||||||
logfile, err := os.OpenFile(config.Log, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644)
|
logfile, err := os.OpenFile(config.Log, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644)
|
||||||
|
|
||||||
@@ -85,13 +85,16 @@ func main() {
|
|||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// github.com/mattn/go-xmpp пишет в stdio, нам этого не надо, ловим выхлоп его в logrus с уровнем trace
|
// github.com/mattn/go-xmpp пишет в stdio, нам этого не надо, ловим выхлоп его в logrus с уровнем trace.
|
||||||
xmpp.DebugWriter = log.WithFields(log.Fields{"logger": "stdlib"}).WriterLevel(log.TraceLevel)
|
xmpp.DebugWriter = log.WithFields(log.Fields{"logger": "stdlib"}).WriterLevel(log.TraceLevel)
|
||||||
|
|
||||||
// Хэндлер сигналов не надо трогать, он нужен для завершения программы целиком
|
// Хэндлер сигналов не надо трогать, он нужен для завершения программы целиком.
|
||||||
go sigHandler()
|
go sigHandler()
|
||||||
signal.Notify(sigChan, os.Interrupt)
|
signal.Notify(sigChan, os.Interrupt)
|
||||||
|
|
||||||
|
// Враппер основной программы. Фактически на каждой серьёзной ошибке, например, сетевой, mainLoop и некоторые
|
||||||
|
// вспомогательные корутины прекращает свою работу. Здесь мы это ловим и запускаем их снова. Задача в том, чтобы
|
||||||
|
// запустить все асинхронные процессы заново, с чистого листа, но уже с распарсенным конфигом.
|
||||||
for {
|
for {
|
||||||
options = &xmpp.Options{ //nolint:exhaustruct
|
options = &xmpp.Options{ //nolint:exhaustruct
|
||||||
Host: fmt.Sprintf("%s:%d", config.Jabber.Server, config.Jabber.Port),
|
Host: fmt.Sprintf("%s:%d", config.Jabber.Server, config.Jabber.Port),
|
||||||
@@ -112,12 +115,13 @@ func main() {
|
|||||||
DialTimeout: time.Duration(config.Jabber.ConnectionTimeout) * time.Second,
|
DialTimeout: time.Duration(config.Jabber.ConnectionTimeout) * time.Second,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Через tomb попробуем сделать выход горутинок управляемым
|
// Через tomb попробуем сделать завершение горутинок управляемым.
|
||||||
gTomb = tomb.Tomb{}
|
gTomb = tomb.Tomb{}
|
||||||
|
|
||||||
// Устанавливаем соединение и гребём события, посылаемые сервером
|
// Устанавливаем соединение и гребём события, посылаемые сервером - основной и вспомогательные циклы программы.
|
||||||
myLoop()
|
myLoop()
|
||||||
|
|
||||||
|
// Логгируем причину завершения mainLoop и вспомогательных циклов программы.
|
||||||
log.Error(gTomb.Wait())
|
log.Error(gTomb.Wait())
|
||||||
|
|
||||||
// Если у нас wire error, то вызов .Close() повлечёт за собой ошибку, но мы вынуждены звать .Close(), чтоб
|
// Если у нас wire error, то вызов .Close() повлечёт за собой ошибку, но мы вынуждены звать .Close(), чтоб
|
||||||
@@ -129,7 +133,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Основной цикл программы
|
// Основной цикл программы.
|
||||||
func myLoop() {
|
func myLoop() {
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
|
|||||||
Reference in New Issue
Block a user