diff --git a/commands/clear.go b/commands/clear.go index 6f5877b..256c2d9 100644 --- a/commands/clear.go +++ b/commands/clear.go @@ -2,10 +2,8 @@ package commands import ( "fmt" - - "github.com/bwmarrin/discordgo" ) -func ClearCommand(session *discordgo.Session) { +func ClearCommand() { fmt.Print("\n\r\033[H\033[2J") } diff --git a/commands/emote.go b/commands/emote.go index 5c151c2..e5c94f8 100644 --- a/commands/emote.go +++ b/commands/emote.go @@ -5,10 +5,10 @@ import ( "github.com/Cynosphere/comcord/lib" "github.com/Cynosphere/comcord/state" - "github.com/bwmarrin/discordgo" + "github.com/diamondburned/arikawa/v3/discord" ) -func EmoteCommand(session *discordgo.Session) { +func EmoteCommand() { channelId := state.GetCurrentChannel() if channelId == "" { fmt.Print("\n\r") @@ -16,7 +16,7 @@ func EmoteCommand(session *discordgo.Session) { } prompt := ":emote> " - lib.MakePrompt(session, prompt, true, func(session *discordgo.Session, input string, interrupt bool) { + lib.MakePrompt(prompt, true, func(input string, interrupt bool) { if input == "" { if interrupt { fmt.Print("^C\n\r") @@ -25,10 +25,18 @@ func EmoteCommand(session *discordgo.Session) { } } else { fmt.Print(prompt, input, "\n\r") - _, err := session.ChannelMessageSend(channelId, "*" + input + "*") + client := state.GetClient() + + snowflake, err := discord.ParseSnowflake(channelId) + if err != nil { + fmt.Print("\n\r") + return + } + + _, err = client.SendMessage(discord.ChannelID(snowflake), "*" + input + "*") if err != nil { - fmt.Print("\n\r") + fmt.Print("\n\r") } // TODO: update afk state diff --git a/commands/guild.go b/commands/guild.go index 549460b..7e492ec 100644 --- a/commands/guild.go +++ b/commands/guild.go @@ -10,9 +10,9 @@ import ( "github.com/Cynosphere/comcord/lib" "github.com/Cynosphere/comcord/state" - "github.com/bwmarrin/discordgo" + "github.com/diamondburned/arikawa/v3/discord" + tsize "github.com/kopoli/go-terminal-size" "github.com/mgutz/ansi" - tsize "github.com/kopoli/go-terminal-size" ) var REGEX_EMOTE = regexp.MustCompile(`<(?:\x{200b}|&)?a?:(\w+):(\d+)>`) @@ -23,35 +23,38 @@ type GuildListing struct { Online int } -func ListGuildsCommand(session *discordgo.Session) { +func ListGuildsCommand() { + client := state.GetClient() + longest := 0 guilds := make([]GuildListing, 0) - for _, guild := range session.State.Guilds { + clientGuilds, err := client.Guilds() + if err != nil { + fmt.Print("\n\r") + return + } + + for _, guild := range clientGuilds { length := utf8.RuneCountInString(guild.Name) if length > longest { longest = length } - guildWithCounts, err := session.GuildWithCounts(guild.ID) - if err != nil { + withCount, err := client.GuildWithCount(guild.ID) + if err == nil { guilds = append(guilds, GuildListing{ Name: guild.Name, - Members: guild.MemberCount, - Online: 0, + Members: int(withCount.ApproximateMembers), + Online: int(withCount.ApproximatePresences), + }) + } else { + guilds = append(guilds, GuildListing{ + Name: guild.Name, + Members: int(guild.ApproximateMembers), + Online: int(guild.ApproximatePresences), }) - return } - - if guild.Name == "" && guildWithCounts.Name != "" { - guild.Name = guildWithCounts.Name - } - - guilds = append(guilds, GuildListing{ - Name: guild.Name, - Members: guildWithCounts.ApproximateMemberCount, - Online: guildWithCounts.ApproximatePresenceCount, - }) } fmt.Print("\n\r") @@ -64,66 +67,89 @@ func ListGuildsCommand(session *discordgo.Session) { fmt.Print("\n\r") } -func GetSortedChannels(session *discordgo.Session, guildId string, withCategories bool, withPrivate bool) []*discordgo.Channel { - channels := make([]*discordgo.Channel, 0) - guild, err := session.State.Guild(guildId) +func GetSortedChannels(guildId string, withCategories bool, withPrivate bool) []discord.Channel { + client := state.GetClient() + channels := make([]discord.Channel, 0) + + guildSnowflake, err := discord.ParseSnowflake(guildId) if err != nil { return channels } - guildChannels := guild.Channels - if len(guildChannels) == 0 { - c, err := session.GuildChannels(guildId) - if err != nil { - return channels - } - guildChannels = c + + parsedGuildId := discord.GuildID(guildSnowflake) + + guild, err := client.GuildStore.Guild(parsedGuildId) + if err != nil { + return channels + } + + guildChannels, err := client.ChannelStore.Channels(guild.ID) + if err != nil { + return channels + } + + self, err := client.MeStore.Me() + if err != nil { + return channels + } + + selfMember, err := client.MemberStore.Member(guild.ID, self.ID) + if err != nil { + return channels } if withCategories { - categories := make(map[string][]*discordgo.Channel) + categories := make(map[string][]discord.Channel) for _, channel := range guildChannels { - if channel.Type != discordgo.ChannelTypeGuildText && channel.Type != discordgo.ChannelTypeGuildNews { + if channel.Type != discord.GuildText && channel.Type != discord.GuildAnnouncement { continue } - perms, err := session.State.UserChannelPermissions(session.State.User.ID, channel.ID) - if err != nil { - continue - } + perms := discord.CalcOverwrites(*guild, channel, *selfMember) - private := perms & discordgo.PermissionViewChannel == 0 + private := !perms.Has(discord.PermissionViewChannel) if private && !withPrivate { continue } categoryID := "0" - if channel.ParentID != "" { - categoryID = channel.ParentID + if channel.ParentID.IsValid() { + categoryID = channel.ParentID.String() } _, has := categories[categoryID] if !has { - categories[categoryID] = make([]*discordgo.Channel, 0) + categories[categoryID] = make([]discord.Channel, 0) } categories[categoryID] = append(categories[categoryID], channel) } - for id, channels := range categories { - sort.Slice(channels, func(i, j int) bool { - return channels[i].Position < channels[j].Position + for id, category := range categories { + // sort channels by position + sort.Slice(category, func(i, j int) bool { + return category[i].Position < category[j].Position }) - categoryChannels := make([]*discordgo.Channel, 0) + categoryChannels := make([]discord.Channel, 0) + + // append category channel to top if id != "0" { - for _, channel := range guild.Channels { - if channel.ID == id { + parsedCategoryId, err := discord.ParseSnowflake(id) + if err != nil { + continue + } + + for _, channel := range guildChannels { + if channel.ID == discord.ChannelID(parsedCategoryId) { categoryChannels = append(categoryChannels, channel) break } } } - for _, channel := range channels { + + // append channels + for _, channel := range category { categoryChannels = append(categoryChannels, channel) } categories[id] = categoryChannels @@ -137,12 +163,15 @@ func GetSortedChannels(session *discordgo.Session, guildId string, withCategorie keys = append(keys, id) } sort.Slice(keys, func(i, j int) bool { - ca, _ := session.State.Channel(keys[i]) - cb, _ := session.State.Channel(keys[j]) + pa, _ := discord.ParseSnowflake(keys[i]) + pb, _ := discord.ParseSnowflake(keys[i]) + + ca, _ := client.ChannelStore.Channel(discord.ChannelID(pa)) + cb, _ := client.ChannelStore.Channel(discord.ChannelID(pb)) return ca.Position < cb.Position }) - sortedCategories := make(map[string][]*discordgo.Channel) + sortedCategories := make(map[string][]discord.Channel) sortedCategories["0"] = categories["0"] for _, id := range keys { @@ -156,16 +185,13 @@ func GetSortedChannels(session *discordgo.Session, guildId string, withCategorie } } else { for _, channel := range guildChannels { - if channel.Type != discordgo.ChannelTypeGuildText && channel.Type != discordgo.ChannelTypeGuildNews { + if channel.Type != discord.GuildText && channel.Type != discord.GuildAnnouncement { continue } - perms, err := session.State.UserChannelPermissions(session.State.User.ID, channel.ID) - if err != nil { - continue - } + perms := discord.CalcOverwrites(*guild, channel, *selfMember) - private := perms & discordgo.PermissionViewChannel == 0 + private := !perms.Has(discord.PermissionViewChannel) if private && !withPrivate { continue } @@ -181,24 +207,47 @@ func GetSortedChannels(session *discordgo.Session, guildId string, withCategorie return channels } -func ListChannelsCommand(session *discordgo.Session) { +func ListChannelsCommand() { + client := state.GetClient() + self, err := client.MeStore.Me() + if err != nil { + fmt.Print("\n\r") + return + } + currentGuild := state.GetCurrentGuild() if currentGuild == "" { fmt.Print("\n\r") return } + guildSnowflake, err := discord.ParseSnowflake(currentGuild) + if err != nil { + fmt.Print("\n\r") + return + } + + parsedGuildId := discord.GuildID(guildSnowflake) + guild, err := client.GuildStore.Guild(parsedGuildId) + if err != nil { + fmt.Print("\n\r") + return + } + + selfMember, err := client.MemberStore.Member(parsedGuildId, self.ID) + if err != nil { + fmt.Print("\n\r") + return + } + longest := 0 - channels := GetSortedChannels(session, currentGuild, true, false) + channels := GetSortedChannels(currentGuild, true, false) for _, channel := range channels { - perms, err := session.State.UserChannelPermissions(session.State.User.ID, channel.ID) - if err != nil { - continue - } + perms := discord.CalcOverwrites(*guild, channel, *selfMember) - private := perms & discordgo.PermissionViewChannel == 0 - category := channel.Type == discordgo.ChannelTypeGuildCategory + private := !perms.Has(discord.PermissionViewChannel) + category := channel.Type == discord.GuildCategory catLen := 0 if category { @@ -220,13 +269,10 @@ func ListChannelsCommand(session *discordgo.Session) { fmt.Printf(" %*s created topic\n\r", longest, "channel-name") fmt.Print(strings.Repeat("-", 80) + "\n\r") for _, channel := range channels { - perms, err := session.State.UserChannelPermissions(session.State.User.ID, channel.ID) - if err != nil { - continue - } + perms := discord.CalcOverwrites(*guild, channel, *selfMember) - private := perms & discordgo.PermissionViewChannel == 0 - category := channel.Type == discordgo.ChannelTypeGuildCategory + private := !perms.Has(discord.PermissionViewChannel) + category := channel.Type == discord.GuildCategory topic := REGEX_EMOTE.ReplaceAllString(channel.Topic, ":$1:") topic = strings.ReplaceAll(topic, "\n", " ") name := channel.Name @@ -249,10 +295,8 @@ func ListChannelsCommand(session *discordgo.Session) { } created := "??-???-??" - timestamp, err := discordgo.SnowflakeTimestamp(channel.ID) - if err == nil { - created = timestamp.UTC().Format("02-Jan-06") - } + timestamp := channel.CreatedAt() + created = timestamp.UTC().Format("02-Jan-06") fmt.Printf(" %*s %s %s\n\r", longest, name, created, topic) } @@ -263,11 +307,13 @@ func ListChannelsCommand(session *discordgo.Session) { type ListedMember struct { Name string Bot bool - Status discordgo.Status + Status discord.Status Position int } -func ListUsersCommand(session *discordgo.Session) { +func ListUsersCommand() { + client := state.GetClient() + currentGuild := state.GetCurrentGuild() currentChannel := state.GetCurrentChannel() @@ -280,37 +326,49 @@ func ListUsersCommand(session *discordgo.Session) { return } - guild, err := session.State.Guild(state.GetCurrentGuild()) + parsedGuildId, err := discord.ParseSnowflake(currentGuild) if err != nil { + fmt.Print("\n\r") return } - channel, err := session.State.Channel(currentChannel) + parsedChannelId, err := discord.ParseSnowflake(currentChannel) if err != nil { + fmt.Print("\n\r") return } - fmt.Print("\n\r") - fmt.Printf("[you are in '%s' in '#%s' among %d]\n\r", guild.Name, channel.Name, guild.MemberCount) - fmt.Print("\n\r") + guild, err := client.GuildStore.Guild(discord.GuildID(parsedGuildId)) + if err != nil { + fmt.Print("\n\r") + return + } + channel, err := client.ChannelStore.Channel(discord.ChannelID(parsedChannelId)) + if err != nil { + fmt.Print("\n\r") + return + } longest := 0 sortedMembers := make([]ListedMember, 0) - for _, presence := range guild.Presences { - if presence.Status == discordgo.StatusOffline { + presences, err := client.Presences(guild.ID) + if err != nil { + fmt.Print("\n\r") + return + } + + for _, presence := range presences { + if presence.Status == discord.OfflineStatus { continue } - perms, err := session.State.UserChannelPermissions(presence.User.ID, currentChannel) + member, err := client.MemberStore.Member(guild.ID, presence.User.ID) if err != nil { continue } - if perms & discordgo.PermissionViewChannel == 0 { - continue - } - member, err := session.State.Member(currentGuild, presence.User.ID) - if err != nil { + perms := discord.CalcOverwrites(*guild, *channel, *member) + if !perms.Has(discord.PermissionViewChannel) { continue } @@ -320,8 +378,8 @@ func ListUsersCommand(session *discordgo.Session) { } position := 0 - for _, id := range member.Roles { - role, err := session.State.Role(currentGuild, id) + for _, id := range member.RoleIDs { + role, err := client.RoleStore.Role(guild.ID, id) if err != nil { continue } @@ -339,6 +397,10 @@ func ListUsersCommand(session *discordgo.Session) { }) } + fmt.Print("\n\r") + fmt.Printf("[you are in '%s' in '#%s' among %d]\n\r", guild.Name, channel.Name, len(sortedMembers)) + fmt.Print("\n\r") + membersByPosition := make(map[int][]ListedMember) for _, member := range sortedMembers { _, has := membersByPosition[member.Position] @@ -377,11 +439,11 @@ func ListUsersCommand(session *discordgo.Session) { for _, member := range members { statusColor := "reset" - if member.Status == discordgo.StatusOnline { + if member.Status == discord.OnlineStatus { statusColor = "green+b" - } else if member.Status == discordgo.StatusIdle { + } else if member.Status == discord.IdleStatus { statusColor = "yellow+b" - } else if member.Status == discordgo.StatusDoNotDisturb { + } else if member.Status == discord.DoNotDisturbStatus { statusColor = "red+b" } @@ -425,16 +487,24 @@ func ListUsersCommand(session *discordgo.Session) { } } -func SwitchGuild(session *discordgo.Session, input string) { +func SwitchGuild(input string) { + client := state.GetClient() + if input == "" { - ListChannelsCommand(session) - ListUsersCommand(session) + ListChannelsCommand() + ListUsersCommand() } else { target := "" - for _, guild := range session.State.Guilds { + guilds, err := client.GuildStore.Guilds() + if err != nil { + fmt.Print("\n\r") + return + } + + for _, guild := range guilds { if strings.Index(strings.ToLower(guild.Name), strings.ToLower(input)) > -1 { - target = guild.ID + target = guild.ID.String() break; } } @@ -445,34 +515,33 @@ func SwitchGuild(session *discordgo.Session, input string) { state.SetCurrentGuild(target) last := state.GetLastChannel(target) if last == "" { - channels := GetSortedChannels(session, target, false, false) - // NB: ???????????????? + channels := GetSortedChannels(target, false, false) if len(channels) > 0 { topChannel := channels[0] - state.SetCurrentChannel(topChannel.ID) - state.SetLastChannel(target, topChannel.ID) + state.SetCurrentChannel(topChannel.ID.String()) + state.SetLastChannel(target, topChannel.ID.String()) } } else { state.SetCurrentChannel(last) } - ListChannelsCommand(session) - ListUsersCommand(session) + ListChannelsCommand() + ListUsersCommand() - lib.UpdatePresence(session) + lib.UpdatePresence() } } } -func SwitchGuildsCommand(session *discordgo.Session) { - lib.MakePrompt(session, ":guild> ", false, func(session *discordgo.Session, input string, interrupt bool) { +func SwitchGuildsCommand() { + lib.MakePrompt(":guild> ", false, func(input string, interrupt bool) { fmt.Print("\r") - SwitchGuild(session, input) + SwitchGuild(input) }) } -func SwitchChannelsCommand(session *discordgo.Session) { +func SwitchChannelsCommand() { currentGuild := state.GetCurrentGuild() if currentGuild == "" { @@ -480,18 +549,18 @@ func SwitchChannelsCommand(session *discordgo.Session) { return } - lib.MakePrompt(session, ":channel> ", false, func(session *discordgo.Session, input string, interrupt bool) { + lib.MakePrompt(":channel> ", false, func(input string, interrupt bool) { fmt.Print("\r") if input == "" { - ListUsersCommand(session) + ListUsersCommand() } else { target := "" - channels := GetSortedChannels(session, currentGuild, false, false) + channels := GetSortedChannels(currentGuild, false, false) for _, channel := range channels { if strings.Index(strings.ToLower(channel.Name), strings.ToLower(input)) > -1 { - target = channel.ID + target = channel.ID.String() break } } @@ -502,9 +571,9 @@ func SwitchChannelsCommand(session *discordgo.Session) { state.SetCurrentChannel(target) state.SetLastChannel(currentGuild, target) - ListUsersCommand(session) + ListUsersCommand() - lib.UpdatePresence(session) + lib.UpdatePresence() } } }) diff --git a/commands/help.go b/commands/help.go index 5207da0..48b47f6 100644 --- a/commands/help.go +++ b/commands/help.go @@ -8,7 +8,6 @@ import ( "unicode/utf8" "github.com/Cynosphere/comcord/state" - "github.com/bwmarrin/discordgo" "github.com/mgutz/ansi" ) @@ -43,7 +42,7 @@ func lessLower(sa, sb string) bool { } } -func HelpCommand(session *discordgo.Session) { +func HelpCommand() { noColor := state.HasNoColor() fmt.Println("\r\nCOMcord (c)left 2023\n\r") diff --git a/commands/history.go b/commands/history.go index 98fa9bf..422f531 100644 --- a/commands/history.go +++ b/commands/history.go @@ -8,11 +8,19 @@ import ( "github.com/Cynosphere/comcord/lib" "github.com/Cynosphere/comcord/state" - "github.com/bwmarrin/discordgo" + "github.com/diamondburned/arikawa/v3/discord" ) -func GetHistory(session *discordgo.Session, limit int, channel string) { - messages, err := session.ChannelMessages(channel, 100, "", "", "") +func GetHistory(limit int, channel string) { + client := state.GetClient() + + parsedChannelId, err := discord.ParseSnowflake(channel) + if err != nil { + fmt.Print("\n\r") + return + } + + messages, err := client.Messages(discord.ChannelID(parsedChannelId), 50) if err != nil { fmt.Print("\n\r") return @@ -26,7 +34,7 @@ func GetHistory(session *discordgo.Session, limit int, channel string) { lines := make([]string, 0) for _, msg := range messages { - msgLines := lib.ProcessMessage(session, msg, lib.MessageOptions{NoColor: true, InHistory: true}) + msgLines := lib.ProcessMessage(msg, lib.MessageOptions{NoColor: true, InHistory: true}) for _, line := range msgLines { lines = append(lines, line) } @@ -41,43 +49,43 @@ func GetHistory(session *discordgo.Session, limit int, channel string) { fmt.Print("--Review-Complete", strings.Repeat("-", 63), "\n\r") } -func HistoryCommand(session *discordgo.Session) { +func HistoryCommand() { currentChannel := state.GetCurrentChannel() if currentChannel == "" { fmt.Print("\n\r") return } - GetHistory(session, 20, currentChannel) + GetHistory(20, currentChannel) } -func ExtendedHistoryCommand(session *discordgo.Session) { +func ExtendedHistoryCommand() { currentChannel := state.GetCurrentChannel() if currentChannel == "" { fmt.Print("\n\r") return } - lib.MakePrompt(session, ":lines> ", false, func(session *discordgo.Session, input string, interrupt bool) { + lib.MakePrompt(":lines> ", false, func(input string, interrupt bool) { fmt.Print("\r") limit, err := strconv.Atoi(input) if err != nil { fmt.Print("\n\r") } else { - GetHistory(session, limit, currentChannel) + GetHistory(limit, currentChannel) } }) } -func PeekHistory(session *discordgo.Session, guild, channel string) { +func PeekHistory(guild, channel string) { target := "" - channels := GetSortedChannels(session, guild, false, false) + channels := GetSortedChannels(guild, false, false) for _, c := range channels { if strings.Index(strings.ToLower(c.Name), strings.ToLower(channel)) > -1 { - target = c.ID + target = c.ID.String() break } } @@ -85,36 +93,44 @@ func PeekHistory(session *discordgo.Session, guild, channel string) { if target == "" { fmt.Print("\n\r") } else { - GetHistory(session, 20, target) + GetHistory(20, target) } } -func PeekCommand(session *discordgo.Session) { +func PeekCommand() { currentGuild := state.GetCurrentGuild() if currentGuild == "" { fmt.Print("\n\r") return } - lib.MakePrompt(session, ":peek> ", false, func(session *discordgo.Session, input string, interrupt bool) { + lib.MakePrompt(":peek> ", false, func(input string, interrupt bool) { fmt.Print("\r") if input != "" { - PeekHistory(session, currentGuild, input) + PeekHistory(currentGuild, input) } }) } -func CrossPeekCommand(session *discordgo.Session) { - lib.MakePrompt(session, ":guild> ", false, func(session *discordgo.Session, input string, interrupt bool) { +func CrossPeekCommand() { + client := state.GetClient() + + lib.MakePrompt(":guild> ", false, func(input string, interrupt bool) { fmt.Print("\r") if input != "" { targetGuild := "" - for _, guild := range session.State.Guilds { + guilds, err := client.GuildStore.Guilds() + if err != nil { + fmt.Print("\n\r") + return + } + + for _, guild := range guilds { if strings.Index(strings.ToLower(guild.Name), strings.ToLower(input)) > -1 { - targetGuild = guild.ID + targetGuild = guild.ID.String() break; } } @@ -122,11 +138,11 @@ func CrossPeekCommand(session *discordgo.Session) { if targetGuild == "" { fmt.Print("\n\r") } else { - lib.MakePrompt(session, ":peek> ", false, func(session *discordgo.Session, input string, interrupt bool) { + lib.MakePrompt(":peek> ", false, func(input string, interrupt bool) { fmt.Print("\r") if input != "" { - PeekHistory(session, targetGuild, input) + PeekHistory(targetGuild, input) } }) } diff --git a/commands/main.go b/commands/main.go index 74d549c..dc870fd 100644 --- a/commands/main.go +++ b/commands/main.go @@ -1,11 +1,9 @@ package commands -import "github.com/bwmarrin/discordgo" - var commandMap map[string]Command type Command struct { - Run func(*discordgo.Session) + Run func() Description string } diff --git a/commands/quit.go b/commands/quit.go index 8c81036..ade4769 100644 --- a/commands/quit.go +++ b/commands/quit.go @@ -4,11 +4,13 @@ import ( "fmt" "os" - "github.com/bwmarrin/discordgo" + "github.com/Cynosphere/comcord/state" ) -func QuitCommand(session *discordgo.Session) { +func QuitCommand() { + client := state.GetClient() + fmt.Print("Unlinking TTY...\n\r") - session.Close() + client.Close() os.Exit(0) } diff --git a/commands/send.go b/commands/send.go index a4c366c..734fda2 100644 --- a/commands/send.go +++ b/commands/send.go @@ -7,43 +7,64 @@ import ( "github.com/Cynosphere/comcord/lib" "github.com/Cynosphere/comcord/state" - "github.com/bwmarrin/discordgo" + "github.com/diamondburned/arikawa/v3/discord" "github.com/mgutz/ansi" ) -func SendMode(session *discordgo.Session) { +func SendMode() { + client := state.GetClient() + channelId := state.GetCurrentChannel() if channelId == "" { fmt.Print("\n\r") return } + parsedChannelId, err := discord.ParseSnowflake(channelId) + if err != nil { + fmt.Print("\n\r") + return + } - channel, err := session.State.Channel(channelId) + channel, err := client.ChannelStore.Channel(discord.ChannelID(parsedChannelId)) if err != nil { fmt.Print("\n\r") return } - perms, err := session.State.UserChannelPermissions(session.State.User.ID, channel.ID) + guild, err := client.GuildStore.Guild(channel.GuildID) if err != nil { - fmt.Print("\n\r") + fmt.Print("\n\r") return } - if perms & discordgo.PermissionSendMessages == 0 { + self, err := client.MeStore.Me() + if err != nil { + fmt.Print("\n\r") + return + } + + selfMember, err := client.MemberStore.Member(guild.ID, self.ID) + if err != nil { + fmt.Print("\n\r") + return + } + + perms := discord.CalcOverwrites(*guild, *channel, *selfMember) + + if !perms.Has(discord.PermissionSendMessages) { fmt.Print("\n\r") return } - length := utf8.RuneCountInString(session.State.User.Username) + 2 + length := utf8.RuneCountInString(self.Username) + 2 curLength := state.GetNameLength() - prompt := fmt.Sprintf("[%s]%s", session.State.User.Username, strings.Repeat(" ", (curLength - length) + 1)) + prompt := fmt.Sprintf("[%s]%s", self.Username, strings.Repeat(" ", (curLength - length) + 1)) if !state.HasNoColor() { prompt = ansi.Color(prompt, "cyan+b") } - lib.MakePrompt(session, prompt, true, func(session *discordgo.Session, input string, interrupt bool) { + lib.MakePrompt(prompt, true, func(input string, interrupt bool) { if input == "" { if interrupt { fmt.Print("^C\n\r") @@ -52,7 +73,7 @@ func SendMode(session *discordgo.Session) { } } else { fmt.Print(prompt, input, "\n\r") - _, err := session.ChannelMessageSend(channelId, input) + _, err := client.SendMessage(channel.ID, input) if err != nil { fmt.Print("\n\r") diff --git a/commands/time.go b/commands/time.go index dc67a8b..c445fb1 100644 --- a/commands/time.go +++ b/commands/time.go @@ -3,11 +3,9 @@ package commands import ( "fmt" "time" - - "github.com/bwmarrin/discordgo" ) -func TimeCommand(session *discordgo.Session) { +func TimeCommand() { now := time.Now().UTC() fmt.Printf("%s\n\r", now.Format("[Mon 02-Jan-06 15:04:05]")) diff --git a/events/main.go b/events/main.go index 9b6c63b..7d2b358 100644 --- a/events/main.go +++ b/events/main.go @@ -1,9 +1,11 @@ package events -import "github.com/bwmarrin/discordgo" +import ( + "github.com/diamondburned/ningen/v3" +) -func Setup(session *discordgo.Session) { - session.AddHandlerOnce(Ready) - session.AddHandler(MessageCreate) - session.AddHandler(MessageUpdate) +func Setup(session *ningen.State) { + session.PreHandler.AddHandler(Ready) + session.PreHandler.AddHandler(MessageCreate) + session.PreHandler.AddHandler(MessageUpdate) } diff --git a/events/messages.go b/events/messages.go index 343d9c6..6ee1165 100644 --- a/events/messages.go +++ b/events/messages.go @@ -5,65 +5,84 @@ import ( "github.com/Cynosphere/comcord/lib" "github.com/Cynosphere/comcord/state" - "github.com/bwmarrin/discordgo" + "github.com/diamondburned/arikawa/v3/gateway" + "github.com/diamondburned/arikawa/v3/discord" ) -func MessageCreate(session *discordgo.Session, msg *discordgo.MessageCreate) { - if msg.Author.ID == session.State.User.ID { - return - } - - channel, err := session.State.Channel(msg.ChannelID) +func MessageCreate(msg *gateway.MessageCreateEvent) { + client := state.GetClient() + self, err := client.MeStore.Me() if err != nil { return } - isDM := channel.Type == discordgo.ChannelTypeDM || channel.Type == discordgo.ChannelTypeGroupDM + if msg.Author.ID == self.ID { + return + } + + channel, err := client.ChannelStore.Channel(msg.ChannelID) + if err != nil { + return + } + + isDM := channel.Type == discord.DirectMessage || channel.Type == discord.GroupDM if state.IsInPrompt() { state.AddMessageToQueue(msg.Message) } else { - lines := lib.ProcessMessage(session, msg.Message, lib.MessageOptions{NoColor: state.HasNoColor()}) + lines := lib.ProcessMessage(msg.Message, lib.MessageOptions{NoColor: state.HasNoColor()}) for _, line := range lines { fmt.Print(line) } } if isDM { - state.SetLastDM(msg.ChannelID) + state.SetLastDM(msg.ChannelID.String()) } } -func MessageUpdate(session *discordgo.Session, msg *discordgo.MessageUpdate) { - if msg.Author == nil { - return - } - - if msg.Author.ID == session.State.User.ID { - return - } - - if msg.BeforeUpdate != nil && msg.Content == msg.BeforeUpdate.Content { - return - } - - channel, err := session.State.Channel(msg.ChannelID) +func MessageUpdate(msg *gateway.MessageUpdateEvent) { + client := state.GetClient() + self, err := client.MeStore.Me() if err != nil { return } - isDM := channel.Type == discordgo.ChannelTypeDM || channel.Type == discordgo.ChannelTypeGroupDM + if msg.Author.ID == self.ID { + return + } + + old, err := client.MessageStore.Message(msg.ChannelID, msg.ID) + if err != nil { + return + } + + if msg.Content == old.Content { + return + } + + // dont process embed updates as messages + if !msg.EditedTimestamp.IsValid() { + return + } + + channel, err := client.ChannelStore.Channel(msg.ChannelID) + if err != nil { + return + } + + isDM := channel.Type == discord.DirectMessage || channel.Type == discord.GroupDM if state.IsInPrompt() { state.AddMessageToQueue(msg.Message) } else { - lines := lib.ProcessMessage(session, msg.Message, lib.MessageOptions{NoColor: state.HasNoColor()}) + lines := lib.ProcessMessage(msg.Message, lib.MessageOptions{NoColor: state.HasNoColor()}) for _, line := range lines { fmt.Print(line) } } if isDM { - state.SetLastDM(msg.ChannelID) + state.SetLastDM(msg.ChannelID.String()) } } diff --git a/events/ready.go b/events/ready.go index e6e981b..a996151 100644 --- a/events/ready.go +++ b/events/ready.go @@ -6,27 +6,41 @@ import ( "github.com/Cynosphere/comcord/commands" "github.com/Cynosphere/comcord/state" - "github.com/bwmarrin/discordgo" + "github.com/diamondburned/arikawa/v3/discord" + "github.com/diamondburned/arikawa/v3/gateway" "github.com/mgutz/ansi" ) -func Ready(session *discordgo.Session, event *discordgo.Ready) { - fmt.Printf("\rLogged in as: %s\n\r", ansi.Color(fmt.Sprintf("%s (%s)", session.State.User.Username, session.State.User.ID), "yellow")) +func Ready(event *gateway.ReadyEvent) { + client := state.GetClient() + self, err := client.Me() + if err != nil { + fmt.Print("\r% Failed to get self: ", err.Error(), "\n\r") + return + } - state.SetNameLength(utf8.RuneCountInString(session.State.User.Username) + 2) + fmt.Printf("\rLogged in as: %s\n\r", ansi.Color(fmt.Sprintf("%s (%s)", self.Username, self.ID), "yellow")) - commands.ListGuildsCommand(session) + state.SetNameLength(utf8.RuneCountInString(self.Username) + 2) + + commands.ListGuildsCommand() defaultGuild := state.GetConfigValue("defaultGuild") defaultChannel := state.GetConfigValue("defaultChannel") if defaultGuild != "" { - guild, err := session.State.Guild(defaultGuild) + parsedGuildId, err := discord.ParseSnowflake(defaultGuild) + if err != nil { + fmt.Print("\r% Failed to parse guild ID: ", err.Error(), "\n\r") + return + } + + guild, err := client.Guild(discord.GuildID(parsedGuildId)) if err == nil { if defaultChannel != "" { state.SetCurrentChannel(defaultChannel) state.SetLastChannel(defaultGuild, defaultChannel) } - commands.SwitchGuild(session, guild.Name) + commands.SwitchGuild(guild.Name) } else { fmt.Println("\r% This account is not in the defined default guild.") } diff --git a/go.mod b/go.mod index d895978..ffdaecd 100644 --- a/go.mod +++ b/go.mod @@ -4,18 +4,24 @@ go 1.20 require ( atomicgo.dev/keyboard v0.2.9 // indirect - github.com/bwmarrin/discordgo v0.27.1 // indirect github.com/containerd/console v1.0.3 // indirect + github.com/diamondburned/arikawa v1.3.2 // indirect + github.com/diamondburned/arikawa/v3 v3.3.1 // indirect + github.com/diamondburned/ningen/v3 v3.0.0 // indirect github.com/ergochat/readline v0.0.5 // indirect + github.com/gorilla/schema v1.2.0 // indirect github.com/gorilla/websocket v1.4.2 // indirect github.com/kopoli/go-terminal-size v0.0.0-20170219200355-5c97524c8b54 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.17 // indirect github.com/mattn/go-runewidth v0.0.13 // indirect github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/rivo/uniseg v0.2.0 // indirect - golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b // indirect + github.com/twmb/murmur3 v1.1.3 // indirect + golang.org/x/crypto v0.1.0 // indirect golang.org/x/sys v0.10.0 // indirect golang.org/x/term v0.10.0 // indirect golang.org/x/text v0.9.0 // indirect + golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect ) diff --git a/go.sum b/go.sum index 439e67e..89c915c 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,24 @@ atomicgo.dev/keyboard v0.2.9 h1:tOsIid3nlPLZ3lwgG8KZMp/SFmr7P0ssEN5JUsm78K8= atomicgo.dev/keyboard v0.2.9/go.mod h1:BC4w9g00XkxH/f1HXhW2sXmJFOCWbKn9xrOunSFtExQ= +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/MarvinJWendt/testza v0.1.0/go.mod h1:7AxNvlfeHP7Z/hDQ5JtE3OKYT3XFUeLCDE2DQninSqs= github.com/MarvinJWendt/testza v0.2.1/go.mod h1:God7bhG8n6uQxwdScay+gjm9/LnO4D3kkcZX4hv9Rp8= github.com/MarvinJWendt/testza v0.2.8/go.mod h1:nwIcjmr0Zz+Rcwfh3/4UhBp7ePKVhuBExvZqnKYWlII= @@ -10,22 +29,74 @@ github.com/MarvinJWendt/testza v0.4.2/go.mod h1:mSdhXiKH8sg/gQehJ63bINcCKp7RtYew github.com/atomicgo/cursor v0.0.1/go.mod h1:cBON2QmmrysudxNBFthvMtN32r3jxVRIvzkUiF/RuIk= github.com/bwmarrin/discordgo v0.27.1 h1:ib9AIc/dom1E/fSIulrBwnez0CToJE113ZGt4HoliGY= github.com/bwmarrin/discordgo v0.27.1/go.mod h1:NJZpH+1AfhIcyQsPeuBKsUtYrRnjkyu0kIVMCHkZtRY= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/readline v1.5.1 h1:upd/6fQk4src78LMRzh5vItIt361/o4uq553V8B5sGI= github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw= github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/diamondburned/arikawa v1.3.2 h1:ftWgP95IJGXNvCvtO5x0QBYsnFSnIBY0SvDdGoC3ILA= +github.com/diamondburned/arikawa v1.3.2/go.mod h1:nIhVIatzTQhPUa7NB8w4koG1RF9gYbpAr8Fj8sKq660= +github.com/diamondburned/arikawa/v3 v3.1.1-0.20221103093025-87c479a2dcd4/go.mod h1:5jBSNnp82Z/EhsKa6Wk9FsOqSxfVkNZDTDBPOj47LpY= +github.com/diamondburned/arikawa/v3 v3.3.1 h1:puqs7mog383RJnUfRSiug5K+z/pC0Cbuq4yGJMQrQWg= +github.com/diamondburned/arikawa/v3 v3.3.1/go.mod h1:+ifmDonP/JdBiUOzZmVReEjPTHDUSkyqqRRmjSf9NE8= +github.com/diamondburned/ningen v1.0.0 h1:fr+7oDWA0Db73CuVeLY8SScWdW6ft/aWwkULXD0flKw= +github.com/diamondburned/ningen v1.0.0/go.mod h1:TcvJV0bK4bp7t+7m29/Tz9dCqgA0sJBKM/Igt0WkvT4= +github.com/diamondburned/ningen/v3 v3.0.0 h1:S7DF+AwOt/zuFsBMAu00mtE8MfuYqaTtDii6iJPX758= +github.com/diamondburned/ningen/v3 v3.0.0/go.mod h1:wMe9WZQiFgkH5Slr5xK8XBBqMJxWTfRDZU82wPney4Y= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/ergochat/readline v0.0.5 h1:PlmCLW9HUTnVfhFburg65pQUDKb0LB43G8hS+ygEkp8= github.com/ergochat/readline v0.0.5/go.mod h1:8RNv74chpO0eTm6rdD1H6WZGihL5rJ+RfSlhv4fIfjg= github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gookit/color v1.4.2/go.mod h1:fqRyamkC1W8uxl+lxCQxOT09l/vYfZ+QeiX3rKQHCoQ= github.com/gookit/color v1.5.0/go.mod h1:43aQb+Zerm/BWh2GnrgOQm7ffz7tvQXEKV6BFMl7wAo= +github.com/gorilla/schema v1.1.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU= +github.com/gorilla/schema v1.2.0 h1:YufUaxZYCKGFuAq3c96BOhjgd5nmXiOY9NGzF247Tsc= +github.com/gorilla/schema v1.2.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.10/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= @@ -46,7 +117,10 @@ github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQ github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/peterh/liner v1.2.2 h1:aJ4AOodmL+JxOZZEL2u9iJf8omNRpqHc/EbrK+3mAXw= github.com/peterh/liner v1.2.2/go.mod h1:xFwJyiKIXJZUKItq5dGHZSTBRAuG/CpeNpWLyiNRNwI= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/pterm/pterm v0.12.27/go.mod h1:PhQ89w4i95rhgE+xedAoqous6K9X+r6aSOI2eFF7DZI= github.com/pterm/pterm v0.12.29/go.mod h1:WI3qxgvoQFFGKGjGnJR849gU0TsEOvKn5Q8LlY1U7lg= github.com/pterm/pterm v0.12.30/go.mod h1:MOqLIyMOgmTDz9yorcYbcw+HsgoZo3BQfg2wtl3HEFE= @@ -56,28 +130,119 @@ github.com/pterm/pterm v0.12.36/go.mod h1:NjiL09hFhT/vWjQHSj1athJpx6H8cjpHXNAK5b github.com/pterm/pterm v0.12.40/go.mod h1:ffwPLwlbXxP+rxT0GsgDTzS3y3rmpAO1NMjUkGTYf8s= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk= github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/twmb/murmur3 v1.1.3 h1:D83U0XYKcHRYwYIpBKf3Pks91Z0Byda/9SJ8B6EMRcA= +github.com/twmb/murmur3 v1.1.3/go.mod h1:Qq/R7NUyOfr65zD+6Q5IHKsJLwP7exErjN6lyyq3OSQ= github.com/wader/readline v0.0.0-20230307172220-bcb7158e7448 h1:AzpBtmgdXa3uznrb3esNeEoaLqtNEwckRmaUH0qWD6w= github.com/wader/readline v0.0.0-20230307172220-bcb7158e7448/go.mod h1:Zgz8IJWvJoe7NK23CCPpC109XMCqJCpUhpHcnnA4XaM= github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs= +github.com/yuin/goldmark v1.1.30/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.2/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go4.org v0.0.0-20200411211856-f5505b9728dd/go.mod h1:CIiUVy99QCPfoE13bO4EZaz5GZMZXMSBGhxRdsvzbkg= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200423211502-4bdfaf469ed5/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b h1:7mWr3k41Qtv8XlltBkDkl8LoP3mpSgBW8BUoxtEdbXg= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= +golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211001092434-39dca1131b70/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211013075003-97ac67df715c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211117180635-dee7805ff2e1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220627191245-f75cf1eec38b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= @@ -86,17 +251,98 @@ golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9sn golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c= golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs= +golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/lib/messages.go b/lib/messages.go index aebe979..ee84121 100644 --- a/lib/messages.go +++ b/lib/messages.go @@ -9,7 +9,7 @@ import ( "unicode/utf8" "github.com/Cynosphere/comcord/state" - "github.com/bwmarrin/discordgo" + "github.com/diamondburned/arikawa/v3/discord" "github.com/mgutz/ansi" ) @@ -19,12 +19,12 @@ var REGEX_EMOTE = regexp.MustCompile(`<(?:\x{200b}|&)?a?:(\w+):(\d+)>`) type MessageOptions struct { Content string Name string - Channel string + Channel discord.ChannelID Bot bool Webhook bool - Attachments []*discordgo.MessageAttachment - Stickers []*discordgo.Sticker - Reply *discordgo.Message + Attachments []discord.Attachment + Stickers []discord.StickerItem + Reply *discord.Message Timestamp time.Time IsMention bool IsDM bool @@ -35,7 +35,9 @@ type MessageOptions struct { InHistory bool } -func FormatMessage(session *discordgo.Session, options MessageOptions) []string { +func FormatMessage(options MessageOptions) []string { + client := state.GetClient() + lines := make([]string, 0) timestamp := options.Timestamp.UTC().Format("[15:04:05]") @@ -55,7 +57,7 @@ func FormatMessage(session *discordgo.Session, options MessageOptions) []string headerLength := 6 + utf8.RuneCountInString(options.Reply.Author.Username) - content, _ := options.Reply.ContentWithMoreMentionsReplaced(session) + content := options.Reply.Content replyContent := strings.ReplaceAll(content, "\n", " ") // TODO: markdown @@ -71,7 +73,7 @@ func FormatMessage(session *discordgo.Session, options MessageOptions) []string replyContent = strings.TrimSpace(replyContent + fmt.Sprintf(" <%d attachment%s>", attachmentCount, attachmentPlural)) } - stickerCount := len(options.Reply.StickerItems) + stickerCount := len(options.Reply.Stickers) if stickerCount > 0 { stickerPlural := "" if stickerCount > 0 { @@ -161,11 +163,11 @@ func FormatMessage(session *discordgo.Session, options MessageOptions) []string lines = append(lines, str + "\n\r") } else if options.IsJoin { - channel, err := session.State.Channel(options.Channel) + channel, err := client.ChannelStore.Channel(options.Channel) if err != nil { return lines } - guild, err := session.State.Guild(channel.GuildID) + guild, err := client.GuildStore.Guild(channel.GuildID) if err != nil { return lines } @@ -237,27 +239,33 @@ func FormatMessage(session *discordgo.Session, options MessageOptions) []string return lines } -func ProcessMessage(session *discordgo.Session, msg *discordgo.Message, options MessageOptions) []string { +func ProcessMessage(msg discord.Message, options MessageOptions) []string { + client := state.GetClient() lines := make([]string, 0) - channel, err := session.State.Channel(msg.ChannelID) + channel, err := client.ChannelStore.Channel(msg.ChannelID) if err != nil { return lines } - guild, err := session.State.Guild(channel.GuildID) + guild, err := client.GuildStore.Guild(channel.GuildID) if err != nil { return lines } - selfMember, err := session.State.Member(guild.ID, session.State.User.ID) + self, err := client.MeStore.Me() + if err != nil { + return lines + } + + selfMember, err := client.MemberStore.Member(guild.ID, self.ID) if err != nil { return lines } hasMentionedRole := false - for _, role := range msg.MentionRoles { - for _, selfRole := range selfMember.Roles { + for _, role := range msg.MentionRoleIDs { + for _, selfRole := range selfMember.RoleIDs { if role == selfRole { hasMentionedRole = true break; @@ -267,18 +275,18 @@ func ProcessMessage(session *discordgo.Session, msg *discordgo.Message, options isDirectlyMentioned := false for _, user := range msg.Mentions { - if user.ID == session.State.User.ID { + if user.ID == self.ID { isDirectlyMentioned = true break; } } isPing := msg.MentionEveryone || hasMentionedRole || isDirectlyMentioned - isDM := channel.Type == discordgo.ChannelTypeDM || channel.Type == discordgo.ChannelTypeGroupDM - isEdit := msg.EditedTimestamp != nil + isDM := channel.Type == discord.DirectMessage || channel.Type == discord.GroupDM + isEdit := msg.EditedTimestamp.IsValid() currentChannel := state.GetCurrentChannel() - isCurrentChannel := currentChannel == msg.ChannelID + isCurrentChannel := currentChannel == msg.ChannelID.String() if !isCurrentChannel && !isDM && !isPing && !options.InHistory { return lines @@ -292,7 +300,7 @@ func ProcessMessage(session *discordgo.Session, msg *discordgo.Message, options str = str + "\x07\n\r" lines = append(lines, str) } else { - content, _ := msg.ContentWithMoreMentionsReplaced(session) + content := msg.Content if isEdit { content = content + " (edited)" } @@ -305,19 +313,19 @@ func ProcessMessage(session *discordgo.Session, msg *discordgo.Message, options options.Name = msg.Author.Username options.Channel = msg.ChannelID options.Bot = msg.Author.Bot - options.Webhook = msg.WebhookID != "" + options.Webhook = msg.WebhookID.IsValid() options.Attachments = msg.Attachments - options.Stickers = msg.StickerItems + options.Stickers = msg.Stickers if i == 0 { options.Reply = msg.ReferencedMessage } options.IsMention = isPing options.IsDM = isDM - options.IsJoin = msg.Type == discordgo.MessageTypeGuildMemberJoin - options.IsPin = msg.Type == discordgo.MessageTypeChannelPinnedMessage + options.IsJoin = msg.Type == discord.GuildMemberJoinMessage + options.IsPin = msg.Type == discord.ChannelPinnedMessage options.IsDump = false - msgLines := FormatMessage(session, options) + msgLines := FormatMessage(options) for _, line := range msgLines { lines = append(lines, line) } @@ -327,28 +335,28 @@ func ProcessMessage(session *discordgo.Session, msg *discordgo.Message, options options.Name = msg.Author.Username options.Channel = msg.ChannelID options.Bot = msg.Author.Bot - options.Webhook = msg.WebhookID != "" + options.Webhook = msg.WebhookID.IsValid() options.Attachments = msg.Attachments - options.Stickers = msg.StickerItems + options.Stickers = msg.Stickers options.Reply = msg.ReferencedMessage options.IsMention = isPing options.IsDM = isDM - options.IsJoin = msg.Type == discordgo.MessageTypeGuildMemberJoin - options.IsPin = msg.Type == discordgo.MessageTypeChannelPinnedMessage + options.IsJoin = msg.Type == discord.GuildMemberJoinMessage + options.IsPin = msg.Type == discord.ChannelPinnedMessage options.IsDump = isDump - lines = FormatMessage(session, options) + lines = FormatMessage(options) } } return lines } -func ProcessQueue(session *discordgo.Session) { +func ProcessQueue() { queue := state.GetMessageQueue() for _, msg := range queue { - lines := ProcessMessage(session, msg, MessageOptions{NoColor: state.HasNoColor()}) + lines := ProcessMessage(msg, MessageOptions{NoColor: state.HasNoColor()}) for _, line := range lines { fmt.Print(line) } diff --git a/lib/presence.go b/lib/presence.go index e057411..fa7fc98 100644 --- a/lib/presence.go +++ b/lib/presence.go @@ -1,98 +1,57 @@ package lib import ( + "context" "fmt" - "reflect" - "sync" - "time" - "unsafe" "github.com/Cynosphere/comcord/state" - "github.com/bwmarrin/discordgo" - "github.com/gorilla/websocket" + "github.com/diamondburned/arikawa/v3/discord" + "github.com/diamondburned/arikawa/v3/gateway" ) -type ActivityMetadata struct { - ButtonURLs []string `json:"button_urls,omitempty"` -} +func UpdatePresence() { + client := state.GetClient() -type Activity struct { - Name string `json:"name"` - Type discordgo.ActivityType `json:"type"` - //URL string `json:"url,omitempty"` - CreatedAt time.Time `json:"created_at"` - ApplicationID string `json:"application_id,omitempty"` - State string `json:"state,omitempty"` - Details string `json:"details,omitempty"` - Timestamps discordgo.TimeStamps `json:"timestamps,omitempty"` - //Emoji discordgo.Emoji `json:"emoji,omitempty"` - //Party discordgo.Party `json:"party,omitempty"` - Assets discordgo.Assets `json:"assets,omitempty"` - //Secrets discordgo.Secrets `json:"secrets,omitempty"` - //Instance bool `json:"instance,omitempty"` - //Flags int `json:"flags,omitempty"` - Buttons []string `json:"buttons,omitempty"` - Metadata ActivityMetadata `json:"metadata,omitempty"` -} - -type GatewayPresenceUpdate struct { - Since int `json:"since"` - Activities []Activity `json:"activities,omitempty"` - Status string `json:"status"` - AFK bool `json:"afk"` - Broadcast string `json:"broadcast,omitempty"` -} - -type presenceOp struct { - Op int `json:"op"` - Data GatewayPresenceUpdate `json:"d"` -} - -func getUnexportedField(field reflect.Value) interface{} { - return reflect.NewAt(field.Type(), unsafe.Pointer(field.UnsafeAddr())).Elem().Interface() -} - -func UpdatePresence(session *discordgo.Session) { - // there is a way to send presence without reflecting to grab the websocket - // connection, but theres an issue with the serialization that because a value - // isn't being considered "null" that its trying to apply and failing because - // the default doesn't make sense in this context, even if omitempty is set - // - // this doesnt happen with bot accounts because they have certain fields - // stripped - values := reflect.ValueOf(session) - fieldWsConn := reflect.Indirect(values).FieldByName("wsConn") - fieldWsMutex := reflect.Indirect(values).FieldByName("wsMutex") - - wsConn := getUnexportedField(fieldWsConn).(*websocket.Conn) - wsMutex := getUnexportedField(fieldWsMutex).(sync.Mutex) + self, err := client.MeStore.Me() + if err != nil { + return + } afk := state.IsAFK() - presence := GatewayPresenceUpdate{ + presence := gateway.UpdatePresenceCommand{ Since: 0, - AFK: afk, - Activities: make([]Activity, 0), + Activities: make([]discord.Activity, 0), + AFK: false, } currentGuild := state.GetCurrentGuild() currentChannel := state.GetCurrentChannel() - var activity Activity + parsedGuildId, err := discord.ParseSnowflake(currentGuild) + if err != nil { + return + } + parsedChannelId, err := discord.ParseSnowflake(currentChannel) + if err != nil { + return + } + + var activity discord.Activity startTime := state.GetStartTime() - if session.State.User.Bot { - activity = Activity{ - Type: 0, + if self.Bot { + activity = discord.Activity{ + Type: discord.GameActivity, Name: "comcord", } if currentGuild != "" && currentChannel != "" { - guild, guildErr := session.State.Guild(currentGuild) - channel, channelErr := session.State.Channel(currentChannel) + guild, guildErr := client.GuildStore.Guild(discord.GuildID(parsedGuildId)) + channel, channelErr := client.ChannelStore.Channel(discord.ChannelID(parsedChannelId)) if guildErr == nil && channelErr == nil { - activity.Type = 3 + activity.Type = discord.WatchingActivity activity.Name = fmt.Sprintf("#%s in %s | comcord", channel.Name, guild.Name) } } @@ -101,33 +60,38 @@ func UpdatePresence(session *discordgo.Session) { activity.Name = activity.Name + " [AFK]" } } else { - activity = Activity{ - Type: 0, - ApplicationID: "1026163285877325874", - Name: "comcord", - Timestamps: discordgo.TimeStamps{ - StartTimestamp: startTime.Unix(), - }, - Buttons: make([]string, 0), - Metadata: ActivityMetadata{ - ButtonURLs: make([]string, 0), - }, + parsedAppId, err := discord.ParseSnowflake("1026163285877325874") + if err != nil { + return } - activity.Buttons = append(activity.Buttons, "comcord Repo") - activity.Metadata.ButtonURLs = append(activity.Metadata.ButtonURLs, "https://gitdab.com/Cynosphere/comcord") + activity = discord.Activity{ + Type: 0, + AppID: discord.AppID(parsedAppId), + Name: "comcord", + Timestamps: &discord.ActivityTimestamps{ + Start: discord.UnixMsTimestamp(startTime.Unix()), + }, + /*Buttons: make([]string, 0), + Metadata: ActivityMetadata{ + ButtonURLs: make([]string, 0), + },*/ + } + + //activity.Buttons = append(activity.Buttons, "comcord Repo") + //activity.Metadata.ButtonURLs = append(activity.Metadata.ButtonURLs, "https://gitdab.com/Cynosphere/comcord") if currentGuild != "" && currentChannel != "" { - guild, guildErr := session.State.Guild(currentGuild) - channel, channelErr := session.State.Channel(currentChannel) + guild, guildErr := client.GuildStore.Guild(discord.GuildID(parsedGuildId)) + channel, channelErr := client.ChannelStore.Channel(discord.ChannelID(parsedChannelId)) if guildErr == nil && channelErr == nil { activity.Details = fmt.Sprintf("#%s - %s", channel.Name, guild.Name) - activity.Assets = discordgo.Assets{} + activity.Assets = &discord.ActivityAssets{} activity.Assets.LargeText = guild.Name if guild.Icon != "" { - activity.Assets.LargeImageID = fmt.Sprintf("mp:icons/%s/%s.png?size=1024", guild.ID, guild.Icon) + activity.Assets.LargeImage = fmt.Sprintf("mp:icons/%s/%s.png?size=1024", guild.ID, guild.Icon) } } } @@ -137,23 +101,20 @@ func UpdatePresence(session *discordgo.Session) { } } - activity.CreatedAt = startTime + activity.CreatedAt = discord.UnixTimestamp(startTime.Unix()) presence.Activities = append(presence.Activities, activity) defaultStatus := state.GetConfigValue("defaultStatus") if defaultStatus != "" { - presence.Status = defaultStatus + presence.Status = discord.Status(defaultStatus) } else { if afk { - presence.Status = "idle" + presence.Status = discord.IdleStatus } else { - presence.Status = "online" + presence.Status = discord.OnlineStatus } } - op := presenceOp{3, presence} - wsMutex.Lock() - wsConn.WriteJSON(op) - wsMutex.Unlock() + client.Gateway().Send(context.Background(), &presence) } diff --git a/lib/prompt.go b/lib/prompt.go index a85709f..f287b8c 100644 --- a/lib/prompt.go +++ b/lib/prompt.go @@ -4,11 +4,10 @@ import ( "strings" "github.com/Cynosphere/comcord/state" - "github.com/bwmarrin/discordgo" "github.com/ergochat/readline" ) -func MakePrompt(session *discordgo.Session, prompt string, uniqueLine bool, callback func(session *discordgo.Session, input string, interrupt bool)) { +func MakePrompt(prompt string, uniqueLine bool, callback func(input string, interrupt bool)) { state.SetInPrompt(true) state.SetPromptText(prompt) @@ -24,10 +23,10 @@ func MakePrompt(session *discordgo.Session, prompt string, uniqueLine bool, call interrupt := err == readline.ErrInterrupt - callback(session, input, interrupt) + callback(input, interrupt) state.SetInPrompt(false) state.SetPromptText("") - ProcessQueue(session) + ProcessQueue() } diff --git a/main.go b/main.go index 3b4e4d3..76ace95 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,7 @@ package main import ( + "context" "fmt" "os" "runtime" @@ -12,7 +13,10 @@ import ( "github.com/Cynosphere/comcord/events" "github.com/Cynosphere/comcord/rcfile" "github.com/Cynosphere/comcord/state" - "github.com/bwmarrin/discordgo" + "github.com/diamondburned/arikawa/v3/discord" + "github.com/diamondburned/arikawa/v3/gateway" + "github.com/diamondburned/arikawa/v3/utils/handler" + "github.com/diamondburned/ningen/v3" "golang.org/x/term" ) @@ -60,7 +64,6 @@ func main() { fmt.Println("\rType 'h' for Commands") fmt.Print("\r") - state.Setup(config) commands.Setup() allowUserAccounts := config["allowUserAccounts"] == "true" @@ -71,31 +74,26 @@ func main() { fullToken := tokenPrefix + token - client, err := discordgo.New(fullToken) - if err != nil { - fmt.Println("% Failed to create client:", err) - fmt.Print("\r") - os.Exit(1) - return - } - - //client.LogLevel = -1 - client.LogLevel = discordgo.LogDebug - - client.Identify.Intents = discordgo.IntentsAll - - client.Identify.Properties = discordgo.IdentifyProperties{ + props := gateway.IdentifyProperties{ OS: runtime.GOOS, } statusType := config["statusType"] if statusType == "mobile" { - client.Identify.Properties.Browser = "Discord Android" + props.Browser = "Discord Android" } else if statusType == "embedded" { - client.Identify.Properties.Browser = "Discord Embedded" + props.Browser = "Discord Embedded" } else if statusType == "desktop" { - client.Identify.Properties.Browser = "Discord Client" + props.Browser = "Discord Client" } else { - client.Identify.Properties.Browser = "comcord" + props.Browser = "comcord" + } + + ident := gateway.IdentifyCommand{ + Token: fullToken, + Properties: props, + + Compress: true, + LargeThreshold: 50, } status := "online" @@ -105,39 +103,57 @@ func main() { } startTime := state.GetStartTime() - client.Identify.Presence = discordgo.GatewayStatusUpdate{ - Since: 0, - Status: status, - AFK: false, - Game: discordgo.Activity{ - Type: 0, - Name: "comcord", - ApplicationID: "1026163285877325874", - CreatedAt: startTime, + activity := discord.Activity{ + Name: "comcord", + Type: discord.GameActivity, + CreatedAt: discord.UnixTimestamp(startTime.Unix()), + Timestamps: &discord.ActivityTimestamps{ + Start: discord.UnixMsTimestamp(startTime.Unix()), }, } + presence := gateway.UpdatePresenceCommand{ + Since: 0, + Activities: make([]discord.Activity, 0), + Status: discord.Status(status), + AFK: false, + } + presence.Activities = append(presence.Activities, activity) + ident.Presence = &presence + + client := ningen.NewWithIdentifier(gateway.NewIdentifier(ident)) + client.PreHandler = handler.New() + + client.AddIntents(gateway.IntentGuilds) + client.AddIntents(gateway.IntentGuildPresences) + client.AddIntents(gateway.IntentGuildMembers) + client.AddIntents(gateway.IntentGuildMessages) + client.AddIntents(gateway.IntentDirectMessages) + client.AddIntents(gateway.IntentMessageContent) + + state.Setup(config, client) events.Setup(client) - err = client.Open() + err = client.Open(context.Background()) if err != nil { fmt.Println("% Failed to connect to Discord:", err) fmt.Print("\r") os.Exit(1) return } + defer client.Close() keyboard.Listen(func(key keys.Key) (stop bool, err error) { if !state.IsInPrompt() { if key.Code == keys.CtrlC { - commands.QuitCommand(client) + commands.QuitCommand() return true, nil } else { command, has := commands.GetCommand(key.String()) if has { - command.Run(client) + command.Run() } else { - commands.SendMode(client) + commands.SendMode() } } } diff --git a/state/main.go b/state/main.go index 2949db8..c83286d 100644 --- a/state/main.go +++ b/state/main.go @@ -3,11 +3,14 @@ package state import ( "time" - "github.com/bwmarrin/discordgo" + "github.com/diamondburned/arikawa/v3/discord" + "github.com/diamondburned/ningen/v3" ) type ComcordState struct { + Client *ningen.State Config map[string]string + Readied bool Connected bool RPCConnected bool StartTime time.Time @@ -17,7 +20,7 @@ type ComcordState struct { InPrompt bool PromptText string AFK bool - MessageQueue []*discordgo.Message + MessageQueue []discord.Message LastChannel map[string]string LastDM string NoColor bool @@ -25,9 +28,11 @@ type ComcordState struct { var state ComcordState -func Setup(config map[string]string) { +func Setup(config map[string]string, client *ningen.State) { state = ComcordState{} + state.Client = client state.Config = config + state.Readied = false state.Connected = true state.RPCConnected = false state.StartTime = time.Now() @@ -37,12 +42,24 @@ func Setup(config map[string]string) { state.InPrompt = false state.PromptText = "" state.AFK = false - state.MessageQueue = make([]*discordgo.Message, 0) + state.MessageQueue = make([]discord.Message, 0) state.LastChannel = make(map[string]string) state.LastDM = "" state.NoColor = false } +func GetClient() *ningen.State { + return state.Client +} + +func HasReadied() bool { + return state.Readied +} + +func SetReadied(value bool) { + state.Readied = value +} + func IsConnected() bool { return state.Connected } @@ -111,16 +128,16 @@ func SetAFK(value bool) { state.AFK = value } -func GetMessageQueue() []*discordgo.Message { +func GetMessageQueue() []discord.Message { return state.MessageQueue } -func AddMessageToQueue(msg *discordgo.Message) { +func AddMessageToQueue(msg discord.Message) { state.MessageQueue = append(state.MessageQueue, msg) } func EmptyMessageQueue() { - state.MessageQueue = make([]*discordgo.Message, 0) + state.MessageQueue = make([]discord.Message, 0) } func SetLastChannel(guild string, channel string) {