-
-
Notifications
You must be signed in to change notification settings - Fork 286
/
message_handlers.go
143 lines (120 loc) · 3.95 KB
/
message_handlers.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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package bot
import (
"github.com/automuteus/automuteus/v8/pkg/settings"
"log"
"strconv"
"time"
"github.com/automuteus/automuteus/v8/pkg/premium"
"github.com/automuteus/automuteus/v8/pkg/task"
"github.com/bsm/redislock"
"github.com/bwmarrin/discordgo"
)
// voiceStateChange handles more edge-case behavior for users moving between voice channels, and catches when
// relevant discord api requests are fully applied successfully. Otherwise, we can issue multiple requests for
// the same mute/unmute, erroneously
func (bot *Bot) handleVoiceStateChange(s *discordgo.Session, m *discordgo.VoiceStateUpdate) {
snowFlakeLock := bot.RedisInterface.LockSnowflake(m.ChannelID + m.UserID + m.SessionID)
// couldn't obtain lock; bail bail bail!
if snowFlakeLock == nil {
return
}
defer snowFlakeLock.Release(ctx)
prem, days, _ := bot.PostgresInterface.GetGuildOrUserPremiumStatus(bot.official, nil, m.GuildID, "")
premTier := premium.FreeTier
if !premium.IsExpired(prem, days) {
premTier = prem
}
sett := bot.StorageInterface.GetGuildSettings(m.GuildID)
gsr := GameStateRequest{
GuildID: m.GuildID,
VoiceChannel: m.ChannelID,
}
stateLock, dgs := bot.RedisInterface.GetDiscordGameStateAndLock(gsr)
if stateLock == nil {
return
}
defer stateLock.Release(ctx)
var voiceLock *redislock.Lock
if dgs.ConnectCode != "" {
voiceLock = bot.RedisInterface.LockVoiceChanges(dgs.ConnectCode, time.Second)
if voiceLock == nil {
return
}
}
g, err := s.State.Guild(dgs.GuildID)
if err != nil || g == nil {
return
}
// fetch the userData from our userData data cache
userData, err := dgs.GetUser(m.UserID)
if err != nil {
// the User doesn't exist in our userdata cache; add them
userData, _ = dgs.checkCacheAndAddUser(g, s, m.UserID)
}
tracked := m.ChannelID != "" && dgs.VoiceChannel == m.ChannelID
auData, found := dgs.GameData.GetByName(userData.InGameName)
var isAlive bool
// only actually tracked if we're in a tracked channel AND linked to a player
if !sett.GetMuteSpectator() {
tracked = tracked && found
isAlive = auData.IsAlive
} else {
if !found {
// we just assume the spectator is dead
isAlive = false
} else {
isAlive = auData.IsAlive
}
}
mute, deaf := sett.GetVoiceState(isAlive, tracked, dgs.GameData.GetPhase())
// check the userdata is linked here to not accidentally undeafen music bots, for example
if found && (userData.ShouldBeDeaf != deaf || userData.ShouldBeMute != mute) && (mute != m.Mute || deaf != m.Deaf) {
userData.SetShouldBeMuteDeaf(mute, deaf)
dgs.UpdateUserData(m.UserID, userData)
if dgs.Running {
uid, _ := strconv.ParseUint(m.UserID, 10, 64)
req := task.UserModifyRequest{
Premium: premTier,
Users: []task.UserModify{
{
UserID: uid,
Mute: mute,
Deaf: deaf,
},
},
}
err = bot.TokenProvider.ModifyUsers(m.GuildID, dgs.ConnectCode, req, voiceLock)
if err != nil {
log.Println("error received from galactus for modifyUsers: ", err.Error())
}
}
}
bot.RedisInterface.SetDiscordGameState(dgs, stateLock)
}
func (bot *Bot) handleGameStartMessage(guildID, textChannelID, voiceChannelID, userID string, sett *settings.GuildSettings, g *discordgo.Guild, connCode string) {
lock, dgs := bot.RedisInterface.GetDiscordGameStateAndLock(GameStateRequest{
GuildID: guildID,
TextChannel: textChannelID,
ConnectCode: connCode,
})
if lock == nil {
log.Println("Couldn't obtain lock for DGS on game start...")
return
}
dgs.GameData.Reset()
dgs.UnlinkAllUsers()
dgs.VoiceChannel = ""
dgs.DeleteGameStateMsg(bot.PrimarySession, true)
dgs.Running = true
if voiceChannelID != "" {
dgs.VoiceChannel = voiceChannelID
for _, v := range g.VoiceStates {
if v.ChannelID == voiceChannelID {
dgs.checkCacheAndAddUser(g, bot.PrimarySession, v.UserID)
}
}
}
_ = dgs.CreateMessage(bot.PrimarySession, bot.gameStateResponse(dgs, sett), textChannelID, userID)
// release the lock
bot.RedisInterface.SetDiscordGameState(dgs, lock)
}