203 lines
8.3 KiB
Go
203 lines
8.3 KiB
Go
package lib
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"regexp"
|
|
"strings"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
)
|
|
|
|
// Горутинка, которая парсит json-чики прилетевшие из REDIS-ки
|
|
func MsgParser(ctx context.Context, msg string) {
|
|
var sendTo string
|
|
var j rMsg
|
|
var message sMsg
|
|
|
|
log.Debugf("Incomming raw json: %s", msg)
|
|
|
|
if err := json.Unmarshal([]byte(msg), &j); err != nil {
|
|
log.Warnf("Unable to to parse message from redis channel: %s", err)
|
|
return
|
|
}
|
|
|
|
// Validate our j
|
|
if exist := j.From; exist == "" {
|
|
log.Warnf("Incorrect msg from redis, no from field: %s", msg)
|
|
return
|
|
}
|
|
|
|
if exist := j.ChatID; exist == "" {
|
|
log.Warnf("Incorrect msg from redis, no chatid field: %s", msg)
|
|
return
|
|
}
|
|
|
|
if exist := j.UserID; exist == "" {
|
|
log.Warnf("Incorrect msg from redis, no userid field: %s", msg)
|
|
return
|
|
}
|
|
|
|
// j.ThreadID может быть пустым, это нормально
|
|
|
|
if exist := j.Message; exist == "" {
|
|
log.Warnf("Incorrect msg from redis, no message field: %s", msg)
|
|
return
|
|
}
|
|
|
|
if exist := j.Plugin; exist == "" {
|
|
log.Warnf("Incorrect msg from redis, no plugin field: %s", msg)
|
|
return
|
|
} else {
|
|
sendTo = j.Plugin
|
|
}
|
|
|
|
if exist := j.Mode; exist == "" {
|
|
log.Warnf("Incorrect msg from redis, no mode field: %s", msg)
|
|
return
|
|
}
|
|
|
|
// j.Misc.Answer может и не быть, тогда ответа на такое сообщение не будет
|
|
if j.Misc.Answer == 0 {
|
|
log.Debug("Field Misc->Answer = 0, skipping message")
|
|
return
|
|
}
|
|
|
|
// j.Misc.BotNick тоже можно не передавать, тогда будет записана пустая строка
|
|
// j.Misc.CSign если нам его не передали, возьмём значение из конфига
|
|
if exist := j.Misc.CSign; exist == "" {
|
|
j.Misc.CSign = Config.CSign
|
|
}
|
|
|
|
// j.Misc.FwdCnt если нам его не передали, то будет 0
|
|
if exist := j.Misc.FwdCnt; exist == 0 {
|
|
j.Misc.FwdCnt = 1
|
|
}
|
|
|
|
// j.Misc.GoodMorning может быть быть 1 или 0, по-умолчанию 0
|
|
// j.Misc.MsgFormat может быть быть 1 или 0, по-умолчанию 0
|
|
// j.Misc.Username можно не передавать, тогда будет пустая строка
|
|
|
|
// Отвалидировались, теперь вернёмся к нашим баранам.
|
|
|
|
// Если у нас циклическая пересылка сообщения, попробуем её тут разорвать, отбросив сообщение
|
|
if j.Misc.FwdCnt > Config.ForwardsMax {
|
|
log.Warnf("Discarding msg with fwd_cnt exceeding max value: %s", msg)
|
|
return
|
|
} else {
|
|
j.Misc.FwdCnt++
|
|
}
|
|
|
|
// Классифицирем входящие сообщения. Первым делом, попробуем определить команды
|
|
msgLen := len(j.Message)
|
|
|
|
if j.Message[0:len(j.Misc.CSign)] == j.Misc.CSign { //nolint:gocritic
|
|
cmd := j.Message[len(j.Misc.CSign):]
|
|
|
|
if cmd == "friday" || cmd == "пятница" {
|
|
j.Message = friday()
|
|
} else if (cmd == "proverb") || (cmd == "пословица") || (cmd == "пословиться") {
|
|
j.Message = proverb()
|
|
} else if (cmd == "f") || (cmd == "ф") {
|
|
j.Message = fortune()
|
|
} else if (cmd == "fortune") || (cmd == "фортунка") {
|
|
j.Message = fortune()
|
|
} else if (cmd == "karma") || (cmd == "карма") {
|
|
j.Message = getKarma(j.ChatID, "")
|
|
} else if match, _ := regexp.MatchString("^(rum|ром)[[:space:]]?([[:space:]].+)*$", cmd); match {
|
|
format := "/me притаскивает на подносе стопку рома для %s, края стопки искрятся кристаллами соли."
|
|
j.Message = fmt.Sprintf(format, j.Misc.Username)
|
|
} else if match, _ := regexp.MatchString("^(vodka|водка)[[:space:]]?([[:space:]].+)*$", cmd); match {
|
|
format := "/me подаёт шот водки с небольшим маринованным огурчиком на блюдце для %s. Из огурчика торчит "
|
|
format += "небольшая вилочка."
|
|
j.Message = fmt.Sprintf(format, j.Misc.Username)
|
|
} else if match, _ := regexp.MatchString("^(beer|пиво)[[:space:]]?([[:space:]].+)*$", cmd); match {
|
|
format := "/me бахает об стол перед %s кружкой холодного пива, часть пенной шапки сползает по запотевшей "
|
|
format += "стенке кружки."
|
|
j.Message = fmt.Sprintf(format, j.Misc.Username)
|
|
} else if match, _ := regexp.MatchString("^(tequila|текила)[[:space:]]?([[:space:]].+)*$", cmd); match {
|
|
format := "/me ставит рядом с %s шот текилы, аккуратно на ребро стопки насаживает дольку лайма и ставит "
|
|
format += "кофейное блюдце с горочкой соли."
|
|
j.Message = fmt.Sprintf(format, j.Misc.Username)
|
|
} else if match, _ := regexp.MatchString("^(whisky|виски)[[:space:]]?([[:space:]].+)*$", cmd); match {
|
|
format := "/me демонстративно достаёт из морозилки пару кубических камушков, бросает их в толстодонный "
|
|
format += "стакан и аккуратно наливает Jack Daniels. Запускает стакан вдоль барной стойки, он "
|
|
format += "останавливается около %s."
|
|
j.Message = fmt.Sprintf(format, j.Misc.Username)
|
|
} else if match, _ := regexp.MatchString("^(absinth|абсент)[[:space:]]?([[:space:]].+)*$", cmd); match {
|
|
format := "/me наливает абсент в стопку. Смочив кубик сахара в абсенте кладёт его на дырявую ложечку и "
|
|
format += "поджигает. Как только пламя потухнет, %s размешивает оплавившийся кубик в абсенте и подносит "
|
|
format += "стопку %s."
|
|
j.Message = fmt.Sprintf(format, j.Misc.BotNick, j.Misc.Username)
|
|
} else if match, _ := regexp.MatchString("^fuck[[:space:]]*$", cmd); match {
|
|
j.Message = "Не ругайся."
|
|
} else {
|
|
cmdLen := len(cmd)
|
|
cmds := []string{"karma ", "карма "}
|
|
|
|
for _, command := range cmds {
|
|
if cmdLen > len(command) && cmd[0:len(command)] == command {
|
|
j.Message = getKarma(j.ChatID, cmd[len(command):])
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
// Это последняя проверка, поэтому во всех else мы исходящее сообщение можем смело ставить в пустую строку
|
|
} else if msgLen > len("++") {
|
|
if j.Message[msgLen-len("--"):msgLen] == "--" || j.Message[msgLen-len("++"):msgLen] == "++" {
|
|
|
|
// Предполагается, что менять карму мы будем для одной фразы, то есть для 1 строки
|
|
if len(strings.Split(j.Message, "\n")) == 1 {
|
|
if j.Message[msgLen-len("--"):msgLen] == "--" {
|
|
j.Message = changeKarma(j.ChatID, j.Message[0:msgLen-len("--")], "--")
|
|
} else if j.Message[msgLen-len("++"):msgLen] == "++" {
|
|
j.Message = changeKarma(j.ChatID, j.Message[0:msgLen-len("++")], "++")
|
|
} else {
|
|
j.Message = ""
|
|
}
|
|
} else {
|
|
j.Message = ""
|
|
}
|
|
} else {
|
|
j.Message = ""
|
|
}
|
|
} else {
|
|
j.Message = ""
|
|
}
|
|
|
|
if j.Message != "" {
|
|
// Настало время формировать json и засылать его в дальше
|
|
message.From = j.From
|
|
message.Userid = j.UserID
|
|
message.ChatID = j.ChatID
|
|
message.ThreadID = j.ThreadID
|
|
message.Message = j.Message
|
|
message.Plugin = j.Plugin
|
|
message.Mode = j.Mode
|
|
message.Misc.FwdCnt = j.Misc.FwdCnt
|
|
message.Misc.CSign = j.Misc.CSign
|
|
message.Misc.Username = j.Misc.Username
|
|
message.Misc.Answer = j.Misc.Answer
|
|
message.Misc.BotNick = j.Misc.BotNick
|
|
message.Misc.MsgFormat = j.Misc.MsgFormat
|
|
|
|
data, err := json.Marshal(message)
|
|
|
|
if err != nil {
|
|
log.Warnf("Unable to to serialize message for redis: %s", err)
|
|
return
|
|
}
|
|
|
|
// Заталкиваем наш json в редиску
|
|
if err := RedisClient.Publish(ctx, sendTo, data).Err(); err != nil {
|
|
log.Warnf("Unable to send data to redis channel %s: %s", sendTo, err)
|
|
} else {
|
|
log.Debugf("Send msg to redis channel %s: %s", sendTo, string(data))
|
|
}
|
|
}
|
|
}
|
|
|
|
/* vim: set ft=go noet ai ts=4 sw=4 sts=4: */
|