@@ -5,13 +5,15 @@ use songbird::SerenityInit;
5
5
6
6
mod lib {
7
7
pub mod player;
8
+ // pub mod forward_mpsc;
8
9
}
9
10
use lib:: player:: { SpotifyPlayer , SpotifyPlayerKey } ;
10
11
use librespot:: core:: mercury:: MercuryError ;
11
12
use librespot:: playback:: config:: Bitrate ;
12
13
use librespot:: playback:: player:: PlayerEvent ;
13
14
use std:: sync:: Arc ;
14
15
use tokio:: sync:: Mutex ;
16
+ use tokio:: time:: { sleep, Duration } ;
15
17
16
18
use serenity:: client:: Context ;
17
19
@@ -37,31 +39,36 @@ impl EventHandler for Handler {
37
39
println ! ( "Ready!" ) ;
38
40
println ! ( "Invite me with https://discord.com/api/oauth2/authorize?client_id={}&permissions=36700160&scope=bot" , ready. user. id) ;
39
41
42
+ ctx. set_presence ( None , user:: OnlineStatus :: Online ) . await ;
43
+ }
44
+
45
+ async fn cache_ready ( & self , ctx : Context , guilds : Vec < id:: GuildId > ) {
46
+ let guild_id = match guilds. first ( ) {
47
+ Some ( guild_id) => * guild_id,
48
+ None => {
49
+ panic ! ( "Not currently in any guilds." ) ;
50
+ }
51
+ } ;
52
+
40
53
let data = ctx. data . read ( ) . await ;
41
54
42
55
let player = data. get :: < SpotifyPlayerKey > ( ) . unwrap ( ) . clone ( ) ;
43
56
let user_id = * data
44
57
. get :: < UserIdKey > ( )
45
58
. expect ( "User ID placed in at initialisation." ) ;
46
59
47
- // Get guild so it's cached
48
- let _guilds = ctx. cache . current_user ( ) . await . guilds ( & ctx. http ) . await ;
49
-
50
- let guild = match ctx. cache . guilds ( ) . await . first ( ) {
51
- Some ( guild_id) => match ctx. cache . guild ( guild_id) . await {
52
- Some ( guild) => guild,
53
- None => panic ! ( "Could not find guild." ) ,
54
- } ,
55
- None => {
56
- panic ! ( "Not currently in any guilds." ) ;
57
- }
58
- } ;
59
-
60
60
// Handle case when user is in VC when bot starts
61
+ let guild = ctx
62
+ . cache
63
+ . guild ( guild_id)
64
+ . await
65
+ . expect ( "Could not find guild in cache." ) ;
66
+
61
67
let channel_id = guild
62
68
. voice_states
63
69
. get ( & user_id)
64
70
. and_then ( |voice_state| voice_state. channel_id ) ;
71
+ drop ( guild) ;
65
72
66
73
if channel_id. is_some ( ) {
67
74
// Enable casting
@@ -70,7 +77,7 @@ impl EventHandler for Handler {
70
77
71
78
let c = ctx. clone ( ) ;
72
79
73
- // Spawn event channel handler for Spotify
80
+ // Handle Spotify events
74
81
tokio:: spawn ( async move {
75
82
loop {
76
83
let channel = player. lock ( ) . await . event_channel . clone ( ) . unwrap ( ) ;
@@ -79,6 +86,8 @@ impl EventHandler for Handler {
79
86
let event = match receiver. recv ( ) . await {
80
87
Some ( e) => e,
81
88
None => {
89
+ // Busy waiting bad but quick and easy
90
+ sleep ( Duration :: from_millis ( 256 ) ) . await ;
82
91
continue ;
83
92
}
84
93
} ;
@@ -92,7 +101,7 @@ impl EventHandler for Handler {
92
101
. expect ( "Songbird Voice client placed in at initialisation." )
93
102
. clone ( ) ;
94
103
95
- let _ = manager. remove ( guild . id ) . await ;
104
+ let _ = manager. remove ( guild_id ) . await ;
96
105
}
97
106
98
107
PlayerEvent :: Started { .. } => {
@@ -101,6 +110,12 @@ impl EventHandler for Handler {
101
110
. expect ( "Songbird Voice client placed in at initialisation." )
102
111
. clone ( ) ;
103
112
113
+ let guild = c
114
+ . cache
115
+ . guild ( guild_id)
116
+ . await
117
+ . expect ( "Could not find guild in cache." ) ;
118
+
104
119
let channel_id = match guild
105
120
. voice_states
106
121
. get ( & user_id)
@@ -113,9 +128,9 @@ impl EventHandler for Handler {
113
128
}
114
129
} ;
115
130
116
- let _handler = manager. join ( guild . id , channel_id) . await ;
131
+ let _handler = manager. join ( guild_id , channel_id) . await ;
117
132
118
- if let Some ( handler_lock) = manager. get ( guild . id ) {
133
+ if let Some ( handler_lock) = manager. get ( guild_id ) {
119
134
let mut handler = handler_lock. lock ( ) . await ;
120
135
121
136
let mut decoder = input:: codec:: OpusDecoderState :: new ( ) . unwrap ( ) ;
@@ -194,6 +209,12 @@ impl EventHandler for Handler {
194
209
195
210
let player = data. get :: < SpotifyPlayerKey > ( ) . unwrap ( ) ;
196
211
212
+ let guild = ctx
213
+ . cache
214
+ . guild ( ctx. cache . guilds ( ) . await . first ( ) . unwrap ( ) )
215
+ . await
216
+ . unwrap ( ) ;
217
+
197
218
// If user just connected
198
219
if old. clone ( ) . is_none ( ) {
199
220
// Enable casting
@@ -204,19 +225,37 @@ impl EventHandler for Handler {
204
225
// If user disconnected
205
226
if old. clone ( ) . unwrap ( ) . channel_id . is_some ( ) && new. channel_id . is_none ( ) {
206
227
// Disable casting
207
- player. lock ( ) . await . disable_connect ( ) ;
208
- return ;
209
- }
228
+ player. lock ( ) . await . disable_connect ( ) . await ;
210
229
211
- // If user moved channels
212
- if old. unwrap ( ) . channel_id . unwrap ( ) != new. channel_id . unwrap ( ) {
230
+ // Disconnect
213
231
let manager = songbird:: get ( & ctx)
214
232
. await
215
233
. expect ( "Songbird Voice client placed in at initialisation." )
216
234
. clone ( ) ;
217
235
218
- if let Some ( guild_id) = ctx. cache . guilds ( ) . await . first ( ) {
219
- let _handler = manager. join ( * guild_id, new. channel_id . unwrap ( ) ) . await ;
236
+ let _handler = manager. remove ( guild. id ) . await ;
237
+
238
+ return ;
239
+ }
240
+
241
+ // If user moved channels
242
+ if old. unwrap ( ) . channel_id . unwrap ( ) != new. channel_id . unwrap ( ) {
243
+ let bot_id = ctx. cache . current_user_id ( ) . await ;
244
+
245
+ let bot_channel = guild
246
+ . voice_states
247
+ . get ( & bot_id)
248
+ . and_then ( |voice_state| voice_state. channel_id ) ;
249
+
250
+ if Option :: is_some ( & bot_channel) {
251
+ let manager = songbird:: get ( & ctx)
252
+ . await
253
+ . expect ( "Songbird Voice client placed in at initialisation." )
254
+ . clone ( ) ;
255
+
256
+ if let Some ( guild_id) = ctx. cache . guilds ( ) . await . first ( ) {
257
+ let _handler = manager. join ( * guild_id, new. channel_id . unwrap ( ) ) . await ;
258
+ }
220
259
}
221
260
222
261
return ;
0 commit comments