This commit is contained in:
Cynthia Foxwell 2023-07-16 18:05:04 -06:00
parent a584139c81
commit e3fc322980
4 changed files with 174 additions and 5 deletions

View File

@ -442,7 +442,7 @@ func SwitchGuild(session *discordgo.Session, input string) {
ListChannelsCommand(session)
ListUsersCommand(session)
// TODO: update presence
lib.UpdatePresence(session)
}
}
}
@ -486,7 +486,7 @@ func SwitchChannelsCommand(session *discordgo.Session) {
ListUsersCommand(session)
// TODO: update presence
lib.UpdatePresence(session)
}
}
})

152
lib/presence.go Normal file
View File

@ -0,0 +1,152 @@
package lib
import (
"fmt"
"reflect"
"sync"
"time"
"unsafe"
"github.com/Cynosphere/comcord/state"
"github.com/bwmarrin/discordgo"
"github.com/gorilla/websocket"
)
type ActivityMetadata struct {
ButtonURLs []string `json:"button_urls,omitempty"`
}
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) {
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)
afk := state.IsAFK()
presence := GatewayPresenceUpdate{
Since: 0,
AFK: afk,
Activities: make([]Activity, 0),
}
currentGuild := state.GetCurrentGuild()
currentChannel := state.GetCurrentChannel()
var activity Activity
startTime := state.GetStartTime()
if session.State.User.Bot {
activity = Activity{
Type: 0,
Name: "comcord",
}
if currentGuild != "" && currentChannel != "" {
guild, guildErr := session.State.Guild(currentGuild)
channel, channelErr := session.State.Channel(currentChannel)
if guildErr == nil && channelErr == nil {
activity.Type = 3
activity.Name = fmt.Sprintf("#%s in %s | comcord", channel.Name, guild.Name)
}
}
if afk {
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),
},
}
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)
if guildErr == nil && channelErr == nil {
activity.Details = fmt.Sprintf("#%s - %s", channel.Name, guild.Name)
activity.Assets = discordgo.Assets{}
activity.Assets.LargeText = guild.Name
if guild.Icon != "" {
activity.Assets.LargeImageID = fmt.Sprintf("mp:icons/%s/%s.png?size=1024", guild.ID, guild.Icon)
}
}
}
if afk {
activity.State = "AFK"
}
}
activity.CreatedAt = startTime
presence.Activities = append(presence.Activities, activity)
defaultStatus := state.GetConfigValue("defaultStatus")
if defaultStatus != "" {
presence.Status = defaultStatus
} else {
if afk {
presence.Status = "idle"
} else {
presence.Status = "online"
}
}
op := presenceOp{3, presence}
wsMutex.Lock()
wsConn.WriteJSON(op)
wsMutex.Unlock()
}

17
main.go
View File

@ -90,6 +90,23 @@ func main() {
}
}
status := "online"
defaultStatus := config["defaultStatus"]
if defaultStatus != "" {
status = defaultStatus
}
startTime := state.GetStartTime()
client.Identify.Presence = discordgo.GatewayStatusUpdate{
Since: 0,
Status: status,
AFK: false,
Game: discordgo.Activity{
Name: "comcord",
ApplicationID: "1026163285877325874",
CreatedAt: startTime,
},
}
events.Setup(client)
err = client.Open()

View File

@ -10,7 +10,7 @@ type ComcordState struct {
Config map[string]string
Connected bool
RPCConnected bool
StartTime int64
StartTime time.Time
CurrentGuild string
CurrentChannel string
NameLength int
@ -30,7 +30,7 @@ func Setup(config map[string]string) {
state.Config = config
state.Connected = true
state.RPCConnected = false
state.StartTime = time.Now().Unix()
state.StartTime = time.Now()
state.CurrentGuild = ""
state.CurrentChannel = ""
state.NameLength = 2
@ -59,7 +59,7 @@ func SetRPCConnected(value bool) {
state.RPCConnected = value
}
func GetStartTime() int64 {
func GetStartTime() time.Time {
return state.StartTime
}