history repeats itself
discordgo -> arikawa
This commit is contained in:
parent
7af5462d54
commit
0d6a1398f0
19 changed files with 775 additions and 378 deletions
|
@ -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)
|
||||
}
|
||||
|
|
149
lib/presence.go
149
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)
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue