claptrap-go/discord/auto_voice.go

143 lines
4.1 KiB
Go
Raw Permalink Normal View History

2024-07-08 18:09:43 +02:00
package discord
import (
"fmt"
"sebclem/claptrapbot-go/utils"
"slices"
"sort"
"strings"
"github.com/bwmarrin/discordgo"
)
func FindNextVoiceIncrement(status *GuildStatus) int {
numbers := []int{}
for _, value := range status.AutoVoiceStatus.CreatedChannel {
numbers = append(numbers, value.Number)
}
sort.Ints(numbers)
next := 1
for _, value := range numbers {
if value == next {
next += 1
} else {
break
}
}
return next
}
func GetConnectedUserCountInVoiceChannel(s *discordgo.Session, guildID string, channelID string) (int, error) {
guildState, err := s.State.Guild(guildID)
if err != nil {
logger.Errorw("Fail retreve guild status", err, "GuildId", guildID)
return -1, err
}
count := 0
for _, vs := range guildState.VoiceStates {
if vs.ChannelID == channelID {
count++
}
}
return count, nil
}
func CreateAutoVoiceChannel(s *discordgo.Session, guildStatus *GuildStatus, sourceChannelID string, channelNameTemplate string) (*discordgo.Channel, error) {
nextNumber := FindNextVoiceIncrement(guildStatus)
channel, err := s.Channel(sourceChannelID)
if err != nil {
logger.Errorw("Fail to retreve channel information", err, "ChannelID", sourceChannelID)
return nil, err
}
newPosition := channel.Position + nextNumber
channels, err := s.GuildChannels(channel.GuildID)
if err != nil {
logger.Errorw("Fail retrevie channel list", err)
return nil, err
}
// TODO Reoder with list index to prevent accumulated error
for _, thisChannel := range channels {
if thisChannel.ParentID == channel.ParentID {
logger.Debug(thisChannel.Position)
}
if thisChannel.ParentID == channel.ParentID && thisChannel.Position >= newPosition {
thisChannel.Position++
}
}
err = s.GuildChannelsReorder(channel.GuildID, channels)
if err != nil {
logger.Errorw("Fail to reorde channels", err)
return nil, err
}
channelName := strings.ReplaceAll(channelNameTemplate, "@count", fmt.Sprint(nextNumber))
created, err := s.GuildChannelCreateComplex(channel.GuildID, discordgo.GuildChannelCreateData{
Bitrate: channel.Bitrate,
Name: channelName,
Position: newPosition,
PermissionOverwrites: channel.PermissionOverwrites,
ParentID: channel.ParentID,
RateLimitPerUser: channel.RateLimitPerUser,
Type: discordgo.ChannelTypeGuildVoice,
UserLimit: channel.UserLimit,
})
if err != nil {
logger.Errorw("Fail to create Auto voice channel", err, "GuildId", channel.GuildID)
return nil, err
}
guildStatus.AutoVoiceStatus.CreatedChannel[created.ID] = &AutoVoiceChannelCreated{ID: created.ID, Number: nextNumber, Position: newPosition}
return created, nil
}
func AutoVoiceChannelDisconect(s *discordgo.Session, guildStatus *GuildStatus, guildID string, channelID string) {
inVC, err := GetConnectedUserCountInVoiceChannel(s, guildID, channelID)
if err != nil {
return
}
if inVC == 0 {
channel, err := s.Channel(channelID)
if err != nil {
logger.Errorw("Fail to retreve channel information", err, "ChannelID", channelID)
return
}
logger.Debug("Channel is empty, deleting it.")
_, err = s.ChannelDelete(channel.ID)
if err != nil {
logger.Errorw("Fail to delete auto voice channel",
err, "GuildId", channel.GuildID,
"ChannelID", channel.ID)
return
}
channels, err := s.GuildChannels(channel.GuildID)
if err != nil {
logger.Errorw("Fail retrevie channel list", err)
return
}
filtered := utils.Filter(channels, func(c *discordgo.Channel) bool { return c.ParentID == channel.ParentID })
ReoderChannels(s, filtered, guildID)
delete(guildStatus.AutoVoiceStatus.CreatedChannel, channelID)
}
}
func ReoderChannels(s *discordgo.Session, channels []*discordgo.Channel, guildID string) error {
slices.SortFunc(channels, func(a *discordgo.Channel, b *discordgo.Channel) int {
if a.Position < b.Position {
return -1
} else if a.Position > b.Position {
return 1
} else {
return 0
}
})
for i, filtered := range channels {
filtered.Position = i
}
err := s.GuildChannelsReorder(guildID, channels)
if err != nil {
logger.Errorw("Fail to reorde channels", err)
return err
}
return nil
}