171 lines
5.2 KiB
Go
171 lines
5.2 KiB
Go
// InnkeeperBot, a bot to create and manage custom channels
|
|
// Copyright (C) 2020-2021 Matteo Schiff
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU Affero General Public License as published
|
|
// by the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU Affero General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Affero General Public License
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
package main
|
|
|
|
import (
|
|
"github.com/bwmarrin/discordgo"
|
|
)
|
|
|
|
type AutoGuild struct {
|
|
id string
|
|
newChannelEndpoint *discordgo.Channel
|
|
createdChannels map[string][]string
|
|
}
|
|
|
|
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, CATEGORY_NAME, "")
|
|
if category == nil {
|
|
log.Errorf("Cannot find category %s in guild %s", CATEGORY_NAME, guildID)
|
|
return
|
|
}
|
|
|
|
deleteAllChannelsUnderCategory(s, guildID, category.ID)
|
|
guild.createNewChannelEndpoint(s, category.ID)
|
|
|
|
managedGuilds[guildID] = &guild
|
|
}
|
|
|
|
func (guild *AutoGuild) createNewChannelEndpoint(s *discordgo.Session, channelParent string) {
|
|
|
|
newChannelData := discordgo.GuildChannelCreateData{
|
|
Name: "Crea nuovo canale",
|
|
Type: discordgo.ChannelTypeGuildVoice,
|
|
ParentID: channelParent}
|
|
|
|
var err error
|
|
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, guild.id)
|
|
return
|
|
}
|
|
|
|
log.Debugf("Created channel with name %s in guild %s", newChannelData.Name, guild.id)
|
|
}
|
|
|
|
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", CATEGORY_NAME, guild.id)
|
|
return
|
|
}
|
|
|
|
channelName := guild.getActivity(s.State, userID)
|
|
editChannelData := discordgo.ChannelEdit{Name: channelName}
|
|
_, err := s.ChannelEdit(channelID, &editChannelData)
|
|
if err != nil {
|
|
log.Errorf("Cannot rename channel %s with new name %s in guild %s", channelID, channelName, guild.id)
|
|
return
|
|
}
|
|
guild.createdChannels[channelID] = []string{userID}
|
|
log.Debugf("Renamed channel %s to %s in guild %s", channelID, channelName, guild.id)
|
|
|
|
guild.createNewChannelEndpoint(s, category.ID)
|
|
}
|
|
|
|
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, guild.id)
|
|
} else {
|
|
log.Debugf("Channel %s deleted in guild %s", channelID, guild.id)
|
|
delete(guild.createdChannels, channelID)
|
|
}
|
|
} else {
|
|
// Otherwise update the channel name and remove user from the list
|
|
guild.createdChannels[channelID] = remove(channel, index)
|
|
guild.updateChannelName(s, 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 (guild *AutoGuild) updateChannelName(s *discordgo.Session, channelID string) {
|
|
programs := make(map[string]int)
|
|
|
|
for _, userID := range guild.createdChannels[channelID] {
|
|
programs[guild.getActivity(s.State, userID)] += 1
|
|
}
|
|
|
|
max := -1
|
|
name := DEFAULT_CHANNEL_NAME
|
|
|
|
for program, count := range programs {
|
|
if program != DEFAULT_CHANNEL_NAME && count > max {
|
|
max = count
|
|
name = program
|
|
}
|
|
}
|
|
|
|
channel, err := s.Channel(channelID)
|
|
if err != nil {
|
|
log.Errorf("Channel %s not found in guild %s", channelID, guild.id)
|
|
return
|
|
}
|
|
|
|
oldName := channel.Name
|
|
|
|
if oldName == name {
|
|
return
|
|
}
|
|
|
|
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, guild.id)
|
|
}
|
|
log.Debugf("Renamed channel %s from %s to %s in guild %s", channelID, oldName, name, guild.id)
|
|
}
|
|
|
|
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 DEFAULT_CHANNEL_NAME
|
|
}
|
|
|
|
for _, activity := range presence.Activities {
|
|
if activity.Name != "Hang Status" {
|
|
return activity.Name
|
|
}
|
|
}
|
|
|
|
return DEFAULT_CHANNEL_NAME
|
|
}
|