diff --git a/autoCreate.go b/autoCreate.go index 908c7d1..45d263b 100644 --- a/autoCreate.go +++ b/autoCreate.go @@ -20,27 +20,37 @@ import ( "github.com/bwmarrin/discordgo" ) -var newChannelEndpoint = make(map[string]*discordgo.Channel) -var createdChannels = make(map[string]map[string][]string) +type AutoGuild struct { + id string + newChannelEndpoint *discordgo.Channel + createdChannels map[string][]string +} -var categoryName = "Gaming🎮" +var managedGuilds = make(map[string]*AutoGuild) + +const CATEGORY_NAME = "Gaming🎮" +const DEFAULT_CHANNEL_NAME = "Stanza" func initChannels(s *discordgo.Session, guildID string) { + var guild AutoGuild + guild.id = guildID + guild.createdChannels = make(map[string][]string) + log.Debugf("Preparing guild %s for automatic channel management", guildID) - category := searchChannel(s, guildID, categoryName, "") + category := searchChannel(s, guildID, CATEGORY_NAME, "") if category == nil { - log.Errorf("Cannot find category %s in guild %s", categoryName, guildID) + log.Errorf("Cannot find category %s in guild %s", CATEGORY_NAME, guildID) return } deleteAllChannelsUnderCategory(s, guildID, category.ID) - createNewChannelEndpoint(s, guildID, category.ID) + guild.createNewChannelEndpoint(s, category.ID) - createdChannels[guildID] = make(map[string][]string) + managedGuilds[guildID] = &guild } -func createNewChannelEndpoint(s *discordgo.Session, guildID string, channelParent string) { +func (guild *AutoGuild) createNewChannelEndpoint(s *discordgo.Session, channelParent string) { newChannelData := discordgo.GuildChannelCreateData{ Name: "Crea nuovo canale", @@ -48,73 +58,76 @@ func createNewChannelEndpoint(s *discordgo.Session, guildID string, channelParen ParentID: channelParent} var err error - newChannelEndpoint[guildID], err = s.GuildChannelCreateComplex(guildID, newChannelData) + guild.newChannelEndpoint, err = s.GuildChannelCreateComplex(guild.id, newChannelData) if err != nil { - log.Errorf("Cannot create channel with name %s in guild %s. This guild is in a corrupted state", newChannelData.Name, guildID) + log.Errorf("Cannot create channel with name %s in guild %s. This guild is in a corrupted state", newChannelData.Name, guild.id) return } - log.Debugf("Created channel with name %s in guild %s", newChannelData.Name, guildID) + log.Debugf("Created channel with name %s in guild %s", newChannelData.Name, guild.id) } -func createNewChannel(s *discordgo.Session, vs *discordgo.VoiceStateUpdate) { - category := searchChannel(s, vs.GuildID, categoryName, "") +func (guild *AutoGuild) createNewChannel(s *discordgo.Session, channelID string, userID string) { + category := searchChannel(s, guild.id, CATEGORY_NAME, "") if category == nil { - log.Errorf("Cannot find category %s in guild %s", categoryName, vs.GuildID) + log.Errorf("Cannot find category %s in guild %s", CATEGORY_NAME, guild.id) return } - channelName := getActivity(s.State, vs.GuildID, vs.UserID) + channelName := guild.getActivity(s.State, userID) editChannelData := discordgo.ChannelEdit{Name: channelName} - _, err := s.ChannelEdit(vs.ChannelID, &editChannelData) + _, err := s.ChannelEdit(channelID, &editChannelData) if err != nil { - log.Errorf("Cannot rename channel %s with new name %s in guild %s", vs.ChannelID, channelName, vs.GuildID) + log.Errorf("Cannot rename channel %s with new name %s in guild %s", channelID, channelName, guild.id) return } - createdChannels[vs.GuildID][vs.ChannelID] = []string{vs.UserID} - log.Debugf("Renamed channel %s to %s in guild %s", vs.ChannelID, channelName, vs.GuildID) + guild.createdChannels[channelID] = []string{userID} + log.Debugf("Renamed channel %s to %s in guild %s", channelID, channelName, guild.id) - createNewChannelEndpoint(s, vs.GuildID, category.ID) + guild.createNewChannelEndpoint(s, category.ID) } -func removeUserFromChannels(s *discordgo.Session, vs *discordgo.VoiceStateUpdate) { - for channelID, channel := range createdChannels[vs.GuildID] { - index := contains(channel, vs.UserID) +func (guild *AutoGuild) removeUserFromChannels(s *discordgo.Session, userID string) { + for channelID, channel := range guild.createdChannels { + index := contains(channel, userID) if index != -1 { if len(channel) == 1 { + // If this user was the only one left in the channel, delete the channel _, err := s.ChannelDelete(channelID) if err != nil { - log.Errorf("Cannot delete channel %s in guild %s", channelID, vs.GuildID) + log.Errorf("Cannot delete channel %s in guild %s", channelID, guild.id) } else { - log.Debugf("Channel %s deleted in guild %s", channelID, vs.GuildID) - delete(createdChannels[vs.GuildID], channelID) + log.Debugf("Channel %s deleted in guild %s", channelID, guild.id) + delete(guild.createdChannels, channelID) } } else { - createdChannels[vs.GuildID][channelID] = remove(channel, index) - updateChannelName(s, vs.GuildID, channelID) + // Otherwise update the channel name and remove user from the list + guild.createdChannels[channelID] = remove(channel, index) + guild.updateChannelName(s, channelID) } } } } -func updateNameOnJoin(s *discordgo.Session, vs *discordgo.VoiceStateUpdate) { - updateChannelName(s, vs.GuildID, vs.ChannelID) +func (guild *AutoGuild) trackUserJoinManagedChannel(s *discordgo.Session, channelID string, userID string) { + guild.createdChannels[channelID] = append(guild.createdChannels[channelID], userID) + guild.updateChannelName(s, channelID) } -func updateChannelName(s *discordgo.Session, guildID string, channelID string) { +func (guild *AutoGuild) updateChannelName(s *discordgo.Session, channelID string) { programs := make(map[string]int) - for _, userID := range createdChannels[guildID][channelID] { - programs[getActivity(s.State, guildID, userID)] += 1 + for _, userID := range guild.createdChannels[channelID] { + programs[guild.getActivity(s.State, userID)] += 1 } max := -1 - name := "Stanza" + name := DEFAULT_CHANNEL_NAME for program, count := range programs { - if program != "Stanza" && count > max { + if program != DEFAULT_CHANNEL_NAME && count > max { max = count name = program } @@ -122,7 +135,7 @@ func updateChannelName(s *discordgo.Session, guildID string, channelID string) { channel, err := s.Channel(channelID) if err != nil { - log.Errorf("Channel %s not found in guild %s", channelID, guildID) + log.Errorf("Channel %s not found in guild %s", channelID, guild.id) return } @@ -135,16 +148,16 @@ func updateChannelName(s *discordgo.Session, guildID string, channelID string) { editChannelData := discordgo.ChannelEdit{Name: name} _, err = s.ChannelEdit(channelID, &editChannelData) if err != nil { - log.Errorf("Cannot rename channel %s with new name %s in guild %s", channelID, name, guildID) + log.Errorf("Cannot rename channel %s with new name %s in guild %s", channelID, name, guild.id) } - log.Debugf("Renamed channel %s from %s to %s in guild %s", channelID, oldName, name, guildID) + log.Debugf("Renamed channel %s from %s to %s in guild %s", channelID, oldName, name, guild.id) } -func getActivity(st *discordgo.State, guildID string, userID string) string { - presence, err := st.Presence(guildID, userID) +func (guild *AutoGuild) getActivity(st *discordgo.State, userID string) string { + presence, err := st.Presence(guild.id, userID) if err != nil || len(presence.Activities) == 0 { - return "Stanza" + return DEFAULT_CHANNEL_NAME } for _, activity := range presence.Activities { @@ -153,5 +166,5 @@ func getActivity(st *discordgo.State, guildID string, userID string) string { } } - return "Stanza" + return DEFAULT_CHANNEL_NAME } diff --git a/main.go b/main.go index c63733c..4fe1bd3 100644 --- a/main.go +++ b/main.go @@ -70,20 +70,23 @@ func main() { } func handleVoiceActivity(s *discordgo.Session, vs *discordgo.VoiceStateUpdate) { - if val, ok := newChannelEndpoint[vs.GuildID]; ok { + if autoGuild, ok := managedGuilds[vs.GuildID]; ok { if vs.ChannelID == "" { - removeUserFromChannels(s, vs) + // The user left a channel + autoGuild.removeUserFromChannels(s, vs.UserID) return } - if vs.ChannelID == val.ID { - removeUserFromChannels(s, vs) - createNewChannel(s, vs) - } else if _, ok := createdChannels[vs.GuildID][vs.ChannelID]; ok { - createdChannels[vs.GuildID][vs.ChannelID] = append(createdChannels[vs.GuildID][vs.ChannelID], vs.UserID) - updateNameOnJoin(s, vs) + if vs.ChannelID == autoGuild.newChannelEndpoint.ID { + // User joined the new channel endpoint + autoGuild.removeUserFromChannels(s, vs.UserID) + autoGuild.createNewChannel(s, vs.ChannelID, vs.UserID) + } else if _, ok := autoGuild.createdChannels[vs.ChannelID]; ok { + // User joined a managed channel + autoGuild.trackUserJoinManagedChannel(s, vs.ChannelID, vs.UserID) } else { - removeUserFromChannels(s, vs) + // User joined a non managed channel + autoGuild.removeUserFromChannels(s, vs.UserID) } } else { initChannels(s, vs.GuildID) @@ -91,11 +94,11 @@ func handleVoiceActivity(s *discordgo.Session, vs *discordgo.VoiceStateUpdate) { } func handlePresenceUpdate(s *discordgo.Session, pu *discordgo.PresenceUpdate) { - if _, ok := newChannelEndpoint[pu.GuildID]; ok { - for channelID, channel := range createdChannels[pu.GuildID] { + if autoGuild, ok := managedGuilds[pu.GuildID]; ok { + for channelID, channel := range autoGuild.createdChannels { for _, user := range channel { if user == pu.User.ID { - updateChannelName(s, pu.GuildID, channelID) + autoGuild.updateChannelName(s, channelID) } } }