143 lines
4.1 KiB
Go
143 lines
4.1 KiB
Go
|
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
|
||
|
}
|