This repository has been archived on 2022-10-02. You can view files and clone it, but cannot push or open issues or pull requests.
dcbot-old/discord/discord.go

149 lines
3.5 KiB
Go

package discord
import (
"context"
"fmt"
"log"
"strconv"
"strings"
"twdcbot/models"
"twdcbot/server"
"twdcbot/tribe"
"github.com/bwmarrin/discordgo"
)
const (
TribesPerServer = 10
)
type SessionConfig struct {
Token string
CommandPrefix string
Status string
ServerRepository server.Repository
TribeRepository tribe.Repository
}
type Session struct {
dg *discordgo.Session
cfg SessionConfig
}
func New(cfg SessionConfig) (*Session, error) {
var err error
s := &Session{
cfg: cfg,
}
s.dg, err = discordgo.New("Bot " + cfg.Token)
if err != nil {
return nil, err
}
if err := s.init(); err != nil {
return nil, err
}
return s, nil
}
func (s *Session) init() error {
s.dg.AddHandler(s.handleNewMessage)
err := s.dg.Open()
if err != nil {
return fmt.Errorf("error opening ws connection: %s", err.Error())
}
if err := s.dg.UpdateStatus(0, s.cfg.Status); err != nil {
return err
}
return nil
}
func (s *Session) handleNewMessage(_ *discordgo.Session, m *discordgo.MessageCreate) {
if m.Author.ID == s.dg.State.User.ID || m.Author.Bot || m.GuildID == "" {
return
}
if has, err := s.MemberHasPermission(m.GuildID, m.Author.ID, discordgo.PermissionAdministrator); err != nil || !has {
return
}
splitted := strings.Split(m.Content, " ")
argsLength := len(splitted) - 1
args := splitted[1 : argsLength+1]
switch splitted[0] {
case HelpCommand.WithPrefix(s.cfg.CommandPrefix):
if argsLength == 0 {
s.sendHelpMessage(m.Author.Mention(), m.ChannelID)
} else {
s.sendUnknownCommandError(m.Author.Mention(), m.ChannelID, args...)
}
break
case AddCommand.WithPrefix(s.cfg.CommandPrefix):
if argsLength > 2 {
s.sendUnknownCommandError(m.Author.Mention(), m.ChannelID, splitted[3:argsLength+1]...)
return
} else if argsLength < 2 {
s.sendMessage(m.ChannelID, m.Author.Mention()+` tw!add [świat] [id_plemienia]`)
return
}
s.handleAddCommand(m, args...)
}
}
func (s *Session) handleAddCommand(m *discordgo.MessageCreate, args ...string) {
world := args[0]
id, err := strconv.Atoi(args[1])
if err != nil {
s.sendMessage(m.ChannelID, m.Author.Mention()+` tw!add [świat] [id_plemienia]`)
return
}
server := &models.Server{
ID: m.GuildID,
}
err = s.cfg.ServerRepository.Store(context.Background(), server)
if err != nil {
s.sendMessage(m.ChannelID, m.Author.Mention()+` Nie udało się dodać plemienia do obserwowanych.`)
return
}
if len(server.Tribes) >= TribesPerServer {
s.sendMessage(m.ChannelID, m.Author.Mention()+fmt.Sprintf(` Osiągnięto limit plemion (%d/%d).`, TribesPerServer, TribesPerServer))
return
}
log.Println(world, id, server.Tribes)
err = s.cfg.TribeRepository.Store(context.Background(), &models.Tribe{
World: world,
TribeID: id,
ServerID: server.ID,
})
if err != nil {
s.sendMessage(m.ChannelID, m.Author.Mention()+` Nie udało się dodać plemienia do obserwowanych.`)
return
}
}
func (s *Session) Close() error {
return s.dg.Close()
}
func (s *Session) MemberHasPermission(guildID string, userID string, permission int) (bool, error) {
member, err := s.dg.State.Member(guildID, userID)
if err != nil {
if member, err = s.dg.GuildMember(guildID, userID); err != nil {
return false, err
}
}
// Iterate through the role IDs stored in member.Roles
// to check permissions
for _, roleID := range member.Roles {
role, err := s.dg.State.Role(guildID, roleID)
if err != nil {
return false, err
}
if role.Permissions&permission != 0 {
return true, nil
}
}
return false, nil
}