Skip to content

Commit

Permalink
add autoremoval of deleted autovcs [#324, #357]
Browse files Browse the repository at this point in the history
When an auto voice channel is deleted, also remove the entry from the database.
  • Loading branch information
zekroTJA committed Mar 3, 2022
1 parent d5c814d commit 2e2a9c0
Show file tree
Hide file tree
Showing 2 changed files with 146 additions and 125 deletions.
5 changes: 4 additions & 1 deletion internal/inits/botsession.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,14 +86,14 @@ func InitDiscordBotSession(container di.Container) (release func()) {

listenerStarboard := listeners.NewListenerStarboard(container)
listenerVerification := listeners.NewListenerVerifications(container)
listenerAutoVoice := listeners.NewListenerAutoVoice(container)

session.AddHandler(listeners.NewListenerReady(container).Handler)
session.AddHandler(listeners.NewListenerMemberAdd(container).Handler)
session.AddHandler(listeners.NewListenerMemberRemove(container).Handler)
session.AddHandler(listeners.NewListenerVote(container).Handler)
session.AddHandler(listeners.NewListenerChannelCreate(container).Handler)
session.AddHandler(listeners.NewListenerVoiceUpdate(container).Handler)
session.AddHandler(listeners.NewListenerAutoVoice(container).Handler)
session.AddHandler(listeners.NewListenerKarma(container).Handler)
session.AddHandler(listeners.NewListenerAntiraid(container).HandlerMemberAdd)
session.AddHandler(listeners.NewListenerBotMention(container).Listener)
Expand All @@ -118,6 +118,9 @@ func InitDiscordBotSession(container di.Container) (release func()) {
session.AddHandler(listenerVerification.HandlerMemberAdd)
session.AddHandler(listenerVerification.HandlerMemberRemove)

session.AddHandler(listenerAutoVoice.HandlerVoiceUpdate)
session.AddHandler(listenerAutoVoice.HandlerChannelDelete)

session.AddHandler(func(s *discordgo.Session, e *discordgo.MessageCreate) {
atomic.AddUint64(&util.StatsMessagesAnalysed, 1)
})
Expand Down
266 changes: 142 additions & 124 deletions internal/listeners/autovc.go
Original file line number Diff line number Diff line change
@@ -1,124 +1,142 @@
package listeners

import (
"github.com/bwmarrin/discordgo"
"github.com/sarulabs/di/v2"
"github.com/zekroTJA/shinpuru/internal/services/database"
"github.com/zekroTJA/shinpuru/internal/services/permissions"
"github.com/zekroTJA/shinpuru/internal/util/static"
"github.com/zekrotja/dgrs"
"strings"
)

type ListenerAutoVoice struct {
db database.Database
st *dgrs.State
pmw *permissions.Permissions
autovcCache map[string]string
voiceStateCache map[string]*discordgo.VoiceState
}

func NewListenerAutoVoice(container di.Container) *ListenerAutoVoice {
return &ListenerAutoVoice{
db: container.Get(static.DiDatabase).(database.Database),
st: container.Get(static.DiState).(*dgrs.State),
pmw: container.Get(static.DiPermissions).(*permissions.Permissions),
autovcCache: map[string]string{},
voiceStateCache: map[string]*discordgo.VoiceState{},
}
}

func (l *ListenerAutoVoice) Handler(s *discordgo.Session, e *discordgo.VoiceStateUpdate) {

allowed, _, err := l.pmw.CheckPermissions(s, e.GuildID, e.UserID, "sp.chat.autochannel")
if err != nil || !allowed {
return
}
vsOld, _ := l.voiceStateCache[e.UserID]
vsNew := e.VoiceState

l.voiceStateCache[e.UserID] = vsNew

ids, err := l.db.GetGuildAutoVC(e.GuildID)
if err != nil {
return
}
idString := strings.Join(ids, ";")

if vsOld == nil || (vsOld != nil && vsOld.ChannelID == "") {

if !strings.Contains(idString, vsNew.ChannelID) {
return
}

if err := l.createAutoVC(s, e.UserID, e.GuildID, vsNew.ChannelID); err != nil {
return
}

} else if vsOld != nil && vsNew.ChannelID != "" && vsOld.ChannelID != vsNew.ChannelID {

// we don't want to delete the channel, if the user get's moved to their auto voicechannel
if vsNew.ChannelID == l.autovcCache[e.UserID] {

} else if strings.Contains(idString, vsNew.ChannelID) && l.autovcCache[e.UserID] == "" {
if l.autovcCache[e.UserID] == "" {
if err := l.createAutoVC(s, e.UserID, e.GuildID, vsNew.ChannelID); err != nil {
return
}
} else {
if err := l.deleteAutoVC(s, e.UserID); err != nil {
return
}
}
} else if l.autovcCache[e.UserID] != "" {
if err := l.deleteAutoVC(s, e.UserID); err != nil {
return
}
}

} else if vsOld != nil && vsNew.ChannelID == "" {
if l.autovcCache[e.UserID] != "" {
if err := l.deleteAutoVC(s, e.UserID); err != nil {
return
}
}

}
}

func (l *ListenerAutoVoice) createAutoVC(s *discordgo.Session, userID, guildID, parentChannelId string) error {
parentCh, err := l.st.Channel(parentChannelId)
if err != nil {
return err
}
user, err := l.st.User(userID)
if err != nil {
return err
}
ch, err := s.GuildChannelCreate(guildID, user.Username, discordgo.ChannelTypeGuildVoice)
if err != nil {
return err
}
ch, err = s.ChannelEditComplex(ch.ID, &discordgo.ChannelEdit{
ParentID: parentCh.ParentID,
Position: parentCh.Position,
})
if err != nil {
return err
}
l.autovcCache[userID] = ch.ID
if err := s.GuildMemberMove(guildID, userID, &ch.ID); err != nil {
return err
}
return nil
}

func (l *ListenerAutoVoice) deleteAutoVC(s *discordgo.Session, userID string) error {
vcID := l.autovcCache[userID]
_, err := s.ChannelDelete(vcID)
if err != nil {
return err
}
delete(l.autovcCache, userID)
return nil
}
package listeners

import (
"strings"

"github.com/bwmarrin/discordgo"
"github.com/sarulabs/di/v2"
"github.com/zekroTJA/shinpuru/internal/services/database"
"github.com/zekroTJA/shinpuru/internal/services/permissions"
"github.com/zekroTJA/shinpuru/internal/util/static"
"github.com/zekroTJA/shinpuru/pkg/slices"
"github.com/zekrotja/dgrs"
)

type ListenerAutoVoice struct {
db database.Database
st *dgrs.State
pmw *permissions.Permissions
autovcCache map[string]string
voiceStateCache map[string]*discordgo.VoiceState
}

func NewListenerAutoVoice(container di.Container) *ListenerAutoVoice {
return &ListenerAutoVoice{
db: container.Get(static.DiDatabase).(database.Database),
st: container.Get(static.DiState).(*dgrs.State),
pmw: container.Get(static.DiPermissions).(*permissions.Permissions),
autovcCache: map[string]string{},
voiceStateCache: map[string]*discordgo.VoiceState{},
}
}

func (l *ListenerAutoVoice) HandlerVoiceUpdate(s *discordgo.Session, e *discordgo.VoiceStateUpdate) {

allowed, _, err := l.pmw.CheckPermissions(s, e.GuildID, e.UserID, "sp.chat.autochannel")
if err != nil || !allowed {
return
}
vsOld, _ := l.voiceStateCache[e.UserID]
vsNew := e.VoiceState

l.voiceStateCache[e.UserID] = vsNew

ids, err := l.db.GetGuildAutoVC(e.GuildID)
if err != nil {
return
}
idString := strings.Join(ids, ";")

if vsOld == nil || (vsOld != nil && vsOld.ChannelID == "") {

if !strings.Contains(idString, vsNew.ChannelID) {
return
}

if err := l.createAutoVC(s, e.UserID, e.GuildID, vsNew.ChannelID); err != nil {
return
}

} else if vsOld != nil && vsNew.ChannelID != "" && vsOld.ChannelID != vsNew.ChannelID {

// we don't want to delete the channel, if the user get's moved to their auto voicechannel
if vsNew.ChannelID == l.autovcCache[e.UserID] {

} else if strings.Contains(idString, vsNew.ChannelID) && l.autovcCache[e.UserID] == "" {
if l.autovcCache[e.UserID] == "" {
if err := l.createAutoVC(s, e.UserID, e.GuildID, vsNew.ChannelID); err != nil {
return
}
} else {
if err := l.deleteAutoVC(s, e.UserID); err != nil {
return
}
}
} else if l.autovcCache[e.UserID] != "" {
if err := l.deleteAutoVC(s, e.UserID); err != nil {
return
}
}

} else if vsOld != nil && vsNew.ChannelID == "" {
if l.autovcCache[e.UserID] != "" {
if err := l.deleteAutoVC(s, e.UserID); err != nil {
return
}
}

}
}

func (l *ListenerAutoVoice) HandlerChannelDelete(s *discordgo.Session, e *discordgo.ChannelDelete) {
autoVCs, err := l.db.GetGuildAutoVC(e.GuildID)
if err != nil || len(autoVCs) == 0 {
return
}

i := slices.IndexOf(autoVCs, e.Channel.ID)
if i == -1 {
return
}

autoVCs, _ = slices.Splice(autoVCs, i, 1)

l.db.SetGuildAutoVC(e.GuildID, autoVCs)
}

func (l *ListenerAutoVoice) createAutoVC(s *discordgo.Session, userID, guildID, parentChannelId string) error {
parentCh, err := l.st.Channel(parentChannelId)
if err != nil {
return err
}
user, err := l.st.User(userID)
if err != nil {
return err
}
ch, err := s.GuildChannelCreate(guildID, user.Username, discordgo.ChannelTypeGuildVoice)
if err != nil {
return err
}
ch, err = s.ChannelEditComplex(ch.ID, &discordgo.ChannelEdit{
ParentID: parentCh.ParentID,
Position: parentCh.Position,
})
if err != nil {
return err
}
l.autovcCache[userID] = ch.ID
if err := s.GuildMemberMove(guildID, userID, &ch.ID); err != nil {
return err
}
return nil
}

func (l *ListenerAutoVoice) deleteAutoVC(s *discordgo.Session, userID string) error {
vcID := l.autovcCache[userID]
_, err := s.ChannelDelete(vcID)
if err != nil {
return err
}
delete(l.autovcCache, userID)
return nil
}

0 comments on commit 2e2a9c0

Please sign in to comment.