package jabber import ( "buny-jabber-bot/internal/log" "fmt" "slices" "strings" "github.com/davecgh/go-spew/spew" "github.com/xmppo/go-xmpp" ) // Cmd парсит команды из чятика. func (j *Jabber) Cmd(v xmpp.Chat) error { var err error switch v.Text { case j.C.CSign + "help", j.C.CSign + "помощь": var ( answer string chosenOneTalks = false ) realJID := j.GetRealJIDfromNick(v.Remote) for _, master := range j.C.Jabber.BotMasters { if (strings.SplitN(realJID, "/", 2))[0] == master { chosenOneTalks = true } } if chosenOneTalks { answer = j.C.CSign + "помощь - этот список команд\n" answer += j.C.CSign + "help - this commands list\n" answer += j.C.CSign + "rehash - reload white and black lists (available to bot admins only)\n" answer += j.C.CSign + "ver | " + j.C.CSign + "version - prints version of software" } else { answer = "Ничем помочь не могу. Луна не светит на тебя." } dest := v.Remote if v.Type == "groupchat" { dest = (strings.SplitN(v.Remote, "/", 2))[0] } if _, err := j.Talk.Send( xmpp.Chat{ //nolint:exhaustruct Remote: dest, Text: strings.TrimSpace(answer), Type: v.Type, }, ); err != nil { err = fmt.Errorf("unable to send message to %s: %w", v.Remote, err) return err } case j.C.CSign + "rehash": /* Эта команда может прилетать из приватной беседы с realjid-ом, из приватной беседы с chat-nick-ом, а также из * чятика. * Groupchat мы можем определить по v.Type (groupchat) и тогда понятно что делать. * А вот, например, приватные притязания определить несколько сложно-вато. Но можно попробовать, например, * пытаться по списку presence-ов находить персонажа и его real jid и уже из этого определять master он или нет. */ // Попробуем определить каков алгоритм наших действий, в зависимости от типа сообщения. switch v.Type { case "groupchat": // Проверим, является ли "командир" избранным или это самозванец? var ( chosenOneTalks = false listsLoaded = true ) realJID := j.GetRealJIDfromNick(v.Remote) for _, master := range j.C.Jabber.BotMasters { if (strings.SplitN(realJID, "/", 2))[0] == master { chosenOneTalks = true } } if !chosenOneTalks { log.Infof( "Command %srehash given by non-bot_master user %s(%s), ignoring", j.C.CSign, realJID, v.Remote, ) var msg xmpp.Chat msg.Remote = v.Remote msg.Type = v.Type msg.Text = "Ничем помочь не могу. Луна не светит на тебя." _, err := j.Talk.Send(msg) return err } if err := j.ReadWhitelist(); err != nil { listsLoaded = false var msg xmpp.Chat msg.Remote = v.Remote msg.Type = "chat" // private message. msg.Text = fmt.Sprint(err) if _, err := j.Talk.Send(msg); err != nil { return err } } if err := j.ReadBlacklist(); err != nil { listsLoaded = false var msg xmpp.Chat msg.Remote = v.Remote msg.Type = "chat" // private message. msg.Text = fmt.Sprint(err) if _, err := j.Talk.Send(msg); err != nil { return err } } if listsLoaded { room := (strings.SplitN(v.Remote, "/", 2))[0] var msg xmpp.Chat msg.Remote = room msg.Type = v.Type msg.Text = "Сделано" if _, err := j.Talk.Send(msg); err != nil { return err } } case "chat": room := (strings.SplitN(v.Remote, "/", 2))[0] // Реагировать на приватную команду "из комнаты", только если бот в комнате. if slices.Contains(j.RoomsConnected, room) { var ( chosenOneTalks = false listsLoaded = true ) // Реагировать на rehash только если собеседник является bot master-ом. realJID := j.GetRealJIDfromNick(v.Remote) for _, master := range j.C.Jabber.BotMasters { if (strings.SplitN(realJID, "/", 2))[0] == master { chosenOneTalks = true } } if !chosenOneTalks { log.Infof( "Command %srehash given by non-bot_master user %s(%s), ignoring", j.C.CSign, realJID, v.Remote, ) var msg xmpp.Chat msg.Remote = v.Remote msg.Type = v.Type msg.Text = "Ничем помочь не могу. Луна не светит на тебя." _, err := j.Talk.Send(msg) return err } if err := j.ReadWhitelist(); err != nil { listsLoaded = false var msg xmpp.Chat msg.Remote = v.Remote msg.Type = v.Type msg.Text = fmt.Sprint(err) if _, err := j.Talk.Send(msg); err != nil { return err } } if err := j.ReadBlacklist(); err != nil { listsLoaded = false var msg xmpp.Chat msg.Remote = v.Remote msg.Type = v.Type msg.Text = fmt.Sprint(err) if _, err := j.Talk.Send(msg); err != nil { return err } } if listsLoaded { var msg xmpp.Chat msg.Remote = v.Remote msg.Type = v.Type msg.Text = "Сделано" if _, err := j.Talk.Send(msg); err != nil { return err } } } default: msg := "Rehash command from outer space: " + spew.Sdump(v) for str := range strings.SplitSeq(msg, "\n") { log.Info(str) } } return err case j.C.CSign + "ver", j.C.CSign + "version": var ( answer = "Version " + j.C.Version ) dest := v.Remote if v.Type == "groupchat" { dest = (strings.SplitN(v.Remote, "/", 2))[0] } if _, err := j.Talk.Send( xmpp.Chat{ //nolint:exhaustruct Remote: dest, Text: strings.TrimSpace(answer), Type: v.Type, }, ); err != nil { err = fmt.Errorf("unable to send message to %s: %w", v.Remote, err) return err } default: return err } return err } /* vim: set ft=go noet ai ts=4 sw=4 sts=4: */