-
Notifications
You must be signed in to change notification settings - Fork 35
/
discord.go
114 lines (99 loc) · 3.39 KB
/
discord.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
// discord.go
// Copyright(c) 2022-2024 vice contributors, licensed under the GNU Public License, Version 3.
// SPDX: GPL-3.0-only
package main
import (
"log/slog"
"strconv"
"sync"
"time"
"github.com/mmp/vice/pkg/log"
discord_client "github.com/hugolgst/rich-go/client"
)
// DiscordStatus encapsulates the user's current vice activity; if the user is not
// currently controlling, Callsign should be an empty string.
type DiscordStatus struct {
TotalDepartures, TotalArrivals int
Callsign string
Start time.Time
}
// discord collects various variables related to the state of the discord
// connection / activity updates.
var discord struct {
// mu should be held when reading from or writing to any of the other
// fields in the structure.
mu sync.Mutex
// last reported status from the user
status DiscordStatus
// has the status changed since the last activity update sent to
// discord?
statusChanged bool
updaterLaunched bool
}
func SetDiscordStatus(s DiscordStatus, config *Config, lg *log.Logger) {
discord.mu.Lock()
defer discord.mu.Unlock()
if s.TotalDepartures != discord.status.TotalDepartures ||
s.TotalArrivals != discord.status.TotalArrivals ||
s.Callsign != discord.status.Callsign ||
s.Start != discord.status.Start {
discord.statusChanged = true
}
// Record the current status even if we're not sending discord updates;
// they may be enabled later.
discord.status = s
// Don't even launch the update goroutine if the user has asked to not
// update their discord status.
if !discord.updaterLaunched && !config.InhibitDiscordActivity.Load() {
discord.updaterLaunched = true
go updateDiscordStatus(config, lg)
}
}
func updateDiscordStatus(config *Config, lg *log.Logger) {
// Sign in to the Vice app on Discord
discord_err := discord_client.Login("1158289394717970473")
if discord_err != nil {
lg.Warn("Discord RPC Error", slog.String("error", discord_err.Error()))
return
}
lg.Info("Successfully logged into Discord")
for {
// Immediately make a copy of all of the values we need and release
// the mutex quickly.
discord.mu.Lock()
status := discord.status
changed := discord.statusChanged
discord.statusChanged = false
discord.mu.Unlock()
// Skip updates if the user has disabled discord updates.
if changed && !config.InhibitDiscordActivity.Load() {
// Common discord_client.Activity initialization regardless of
// whether we're connected or not.
activity := discord_client.Activity{
LargeImage: "towerlarge",
LargeText: "Vice ATC",
Timestamps: &discord_client.Timestamps{
Start: &status.Start,
},
}
if status.Callsign == "" {
// Disconnected
activity.State = "In the main menu"
activity.Details = "On Break"
} else {
activity.State = strconv.Itoa(status.TotalDepartures) + " departures" + " | " +
strconv.Itoa(status.TotalArrivals) + " arrivals"
activity.Details = "Controlling " + status.Callsign
}
if err := discord_client.SetActivity(activity); err != nil {
lg.Error("Discord RPC Error: ", slog.String("error", err.Error()))
} else {
lg.Info("Updated Discord activity", slog.Any("activity", activity))
}
}
// Rate limit updates; note that this may introduce a small lag
// from receiving an update (if we haven't sent an update for a
// while), but it's just a few seconds so no big deal..
time.Sleep(5 * time.Second)
}
}