Skip to content

Commit 163c934

Browse files
committed
Merge branch 'protocol-overhaul' into dev
2 parents c84636c + f8a85f3 commit 163c934

24 files changed

+512
-696
lines changed

IMPLEMENTATION.md

Lines changed: 2 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,7 @@ User-Id: The user id of the bot you are playing music with
2121
```
2222

2323
### Outgoing messages
24-
Make the server queue a voice connection
25-
```json
26-
{
27-
"op": "connect",
28-
"guildId": "...",
29-
"channelId": "..."
30-
}
31-
```
32-
33-
Provide an intercepted voice server update
24+
Provide an intercepted voice server update. This causes the server to connect to the voice channel
3425
```json
3526
{
3627
"op": "voiceUpdate",
@@ -40,33 +31,6 @@ Provide an intercepted voice server update
4031
}
4132
```
4233

43-
Close a voice connection
44-
```json
45-
{
46-
"op": "disconnect",
47-
"guildId": "123"
48-
}
49-
```
50-
51-
Response to `validationReq`. `channelId` is omitted if the request does not display the channel id.
52-
```json
53-
{
54-
"op": "validationRes",
55-
"guildId": "...",
56-
"channelId": "...",
57-
"valid": true
58-
}
59-
```
60-
61-
Response to `isConnectedRes`.
62-
```json
63-
{
64-
"op": "isConnectedRes",
65-
"shardId": 1337,
66-
"connected": true
67-
}
68-
```
69-
7034
Cause the player to play a track.
7135
`startTime` is an optional setting that determines the number of milliseconds to offset the track by. Defaults to 0.
7236
`endTime` is an optional setting that determines at the number of milliseconds at which point the track should stop playing. Helpful if you only want to play a snippet of a bigger track. By default the track plays until it's end as per the encoded data.
@@ -117,35 +81,9 @@ Set player volume. Volume may range from 0 to 150. 100 is default.
11781

11882
### Incoming messages
11983
See
120-
[LavalinkSocket.java](https://github.com/Frederikam/Lavalink/blob/91bc0ef4dab6ca5d5efcba12203ee4054bb55ae9/LavalinkClient/src/main/java/lavalink/client/io/LavalinkSocket.java)
84+
[LavalinkSocket.java](https://github.com/Frederikam/Lavalink/blob/dev/LavalinkClient/src/main/java/lavalink/client/io/LavalinkSocket.java)
12185
for client implementation
12286

123-
Incoming message to forward to mainWS
124-
```json
125-
{
126-
"op": "sendWS",
127-
"shardId": 1337,
128-
"message": "..."
129-
}
130-
```
131-
132-
Request to check if the VC or Guild exists, and that we have access to the VC. Note that the channelId may be omitted, in which case you should only check if we are in the guild.
133-
```json
134-
{
135-
"op": "validationReq",
136-
"guildId": "...",
137-
"channelId": "..."
138-
}
139-
```
140-
141-
Request to check if a shard's mainWS is connected
142-
```json
143-
{
144-
"op": "isConnectedReq",
145-
"shardId": 1337
146-
}
147-
```
148-
14987
Position information about a player. Includes unix timestamp.
15088
```json
15189
{

LavalinkClient/.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
/logs/
33
/target/
44
/dependency-reduced-pom.xml
5-
build/*
5+
build/*
6+
/out/

LavalinkClient/build.gradle

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@ ext {
55
}
66
dependencies {
77
compile group: 'com.sedmelluq', name: 'lavaplayer', version: '1.2.45'
8-
compile group: 'org.java-websocket', name: 'Java-WebSocket', version: '1.3.4'
8+
compile group: 'org.java-websocket', name: 'Java-WebSocket', version: '1.3.7'
99
compile group: 'org.slf4j', name: 'slf4j-api', version: '1.7.25'
10-
compile group: 'org.json', name: 'json', version: '20170516'
11-
compile group: 'net.dv8tion', name: 'JDA', version: '3.3.1_307'
10+
compile group: 'org.json', name: 'json', version: '20171018'
11+
compile group: 'net.dv8tion', name: 'JDA', version: '3.5.0_328'
12+
compileOnly group: 'io.prometheus', name: 'simpleclient', version: '0.1.0'
1213
testCompile group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.0.0-M4'
1314
testCompile group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.0.0-M4'
1415
testCompile group: 'org.junit.platform', name: 'junit-platform-launcher', version: '1.0.0-M4'

LavalinkClient/src/main/java/lavalink/client/LavalinkUtil.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ public class LavalinkUtil {
4545

4646
static {
4747
PLAYER_MANAGER = new DefaultAudioPlayerManager();
48-
PLAYER_MANAGER.enableGcMonitoring();
4948

5049
/* These are only to encode/decode messages */
5150
PLAYER_MANAGER.registerSourceManager(new YoutubeAudioSourceManager());
@@ -65,7 +64,7 @@ public static AudioTrack toAudioTrack(String message) throws IOException {
6564
public static String toMessage(AudioTrack track) throws IOException {
6665
ByteArrayOutputStream baos = new ByteArrayOutputStream();
6766
PLAYER_MANAGER.encodeTrack(new MessageOutput(baos), track);
68-
return new String(Base64.encodeBytesToBytes(baos.toByteArray()));
67+
return Base64.encodeBytes(baos.toByteArray());
6968
}
7069

7170
public static int getShardFromSnowflake(String snowflake, int numShards) {

LavalinkClient/src/main/java/lavalink/client/io/Lavalink.java

Lines changed: 50 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -23,33 +23,31 @@
2323
package lavalink.client.io;
2424

2525
import lavalink.client.LavalinkUtil;
26-
import lavalink.client.player.LavalinkPlayer;
2726
import net.dv8tion.jda.core.JDA;
2827
import net.dv8tion.jda.core.entities.Guild;
29-
import net.dv8tion.jda.core.entities.VoiceChannel;
3028
import net.dv8tion.jda.core.entities.impl.JDAImpl;
31-
import net.dv8tion.jda.core.events.DisconnectEvent;
3229
import net.dv8tion.jda.core.events.ReadyEvent;
3330
import net.dv8tion.jda.core.events.ReconnectedEvent;
34-
import net.dv8tion.jda.core.events.ResumedEvent;
35-
import net.dv8tion.jda.core.events.ShutdownEvent;
36-
import net.dv8tion.jda.core.events.guild.voice.GuildVoiceJoinEvent;
37-
import net.dv8tion.jda.core.events.guild.voice.GuildVoiceLeaveEvent;
38-
import net.dv8tion.jda.core.events.guild.voice.GuildVoiceMoveEvent;
31+
import net.dv8tion.jda.core.events.channel.voice.VoiceChannelDeleteEvent;
32+
import net.dv8tion.jda.core.events.guild.GuildLeaveEvent;
33+
import net.dv8tion.jda.core.handle.SocketHandler;
3934
import net.dv8tion.jda.core.hooks.ListenerAdapter;
4035
import org.java_websocket.drafts.Draft_6455;
4136
import org.slf4j.Logger;
4237
import org.slf4j.LoggerFactory;
4338

39+
import javax.annotation.Nonnull;
4440
import java.net.URI;
4541
import java.util.Collection;
4642
import java.util.HashMap;
4743
import java.util.List;
44+
import java.util.Map;
4845
import java.util.concurrent.ConcurrentHashMap;
4946
import java.util.concurrent.CopyOnWriteArrayList;
5047
import java.util.concurrent.Executors;
5148
import java.util.concurrent.ScheduledExecutorService;
5249
import java.util.concurrent.TimeUnit;
50+
import java.util.concurrent.atomic.AtomicInteger;
5351
import java.util.function.Function;
5452

5553
public class Lavalink extends ListenerAdapter {
@@ -79,6 +77,7 @@ public Lavalink(String userId, int numShards, Function<Integer, JDA> jdaProvider
7977
reconnectService.scheduleWithFixedDelay(new ReconnectTask(this), 0, 500, TimeUnit.MILLISECONDS);
8078
}
8179

80+
8281
@SuppressWarnings("unused")
8382
public void setAutoReconnect(boolean autoReconnect) {
8483
this.autoReconnect = autoReconnect;
@@ -89,13 +88,27 @@ public boolean getAutoReconnect() {
8988
return autoReconnect;
9089
}
9190

92-
public void addNode(URI serverUri, String password) {
91+
private static final AtomicInteger nodeCounter = new AtomicInteger(0);
92+
93+
public void addNode(@Nonnull URI serverUri, @Nonnull String password) {
94+
addNode("Lavalink_Node_#" + nodeCounter.getAndIncrement(), serverUri, password);
95+
}
96+
97+
/**
98+
* @param name
99+
* A name to identify this node. May show up in metrics and other places.
100+
* @param serverUri
101+
* uri of the node to be added
102+
* @param password
103+
* password of the node to be added
104+
*/
105+
public void addNode(@Nonnull String name, @Nonnull URI serverUri, @Nonnull String password) {
93106
HashMap<String, String> headers = new HashMap<>();
94107
headers.put("Authorization", password);
95108
headers.put("Num-Shards", Integer.toString(numShards));
96109
headers.put("User-Id", userId);
97110

98-
nodes.add(new LavalinkSocket(this, serverUri, new Draft_6455(), headers));
111+
nodes.add(new LavalinkSocket(name, this, serverUri, new Draft_6455(), headers));
99112
}
100113

101114
@SuppressWarnings("unused")
@@ -104,16 +117,20 @@ public void removeNode(int key) {
104117
node.close();
105118
}
106119

120+
@SuppressWarnings("unused")
121+
@Nonnull
122+
public LavalinkLoadBalancer getLoadBalancer() {
123+
return loadBalancer;
124+
}
125+
107126
@SuppressWarnings("WeakerAccess")
127+
@Nonnull
108128
public Link getLink(String guildId) {
109129
return links.computeIfAbsent(guildId, __ -> new Link(this, guildId));
110130
}
111131

112-
public LavalinkLoadBalancer getLoadBalancer() {
113-
return loadBalancer;
114-
}
115-
116132
@SuppressWarnings("WeakerAccess")
133+
@Nonnull
117134
public Link getLink(Guild guild) {
118135
return getLink(guild.getId());
119136
}
@@ -124,21 +141,25 @@ public int getNumShards() {
124141
}
125142

126143
@SuppressWarnings("WeakerAccess")
144+
@Nonnull
127145
public Collection<Link> getLinks() {
128146
return links.values();
129147
}
130148

131149
@SuppressWarnings("WeakerAccess")
150+
@Nonnull
132151
public List<LavalinkSocket> getNodes() {
133152
return nodes;
134153
}
135154

136155
@SuppressWarnings("WeakerAccess")
156+
@Nonnull
137157
public JDA getJda(int shardId) {
138158
return jdaProvider.apply(shardId);
139159
}
140160

141161
@SuppressWarnings("WeakerAccess")
162+
@Nonnull
142163
public JDA getJdaFromSnowflake(String snowflake) {
143164
return jdaProvider.apply(LavalinkUtil.getShardFromSnowflake(snowflake, numShards));
144165
}
@@ -153,107 +174,47 @@ void removeDestroyedLink(Link link) {
153174
links.remove(link.getGuildId());
154175
}
155176

156-
/*
157-
* Deprecated, will be removed in v2.0
158-
*/
159-
160-
@Deprecated
161-
LavalinkSocket getSocket(String guildId) {
162-
return getLink(guildId).getNode(false);
163-
}
164-
165-
@Deprecated
166-
public VoiceChannel getConnectedChannel(Guild guild) {
167-
return getLink(guild).getCurrentChannel();
168-
}
169-
170-
@Deprecated
171-
public String getConnectedChannel(String guildId) {
172-
return getLink(guildId).getCurrentChannel().getId();
173-
}
174-
175-
@Deprecated
176-
public LavalinkSocket getNodeForGuild(Guild guild) {
177-
return getLink(guild).getNode(false);
178-
}
179-
180-
@Deprecated
181-
public LavalinkPlayer getPlayer(String guildId) {
182-
return getLink(guildId).getPlayer();
183-
}
184-
185-
@Deprecated
186-
public void openVoiceConnection(VoiceChannel channel) {
187-
getLink(channel.getGuild()).connect(channel);
188-
}
189-
190-
@Deprecated
191-
public void closeVoiceConnection(Guild guild) {
192-
getLink(guild).disconnect();
193-
}
194-
195177
/*
196178
* JDA event handling
197179
*/
198180

199181
@Override
200182
public void onReady(ReadyEvent event) {
201-
((JDAImpl) event.getJDA()).getClient().getHandlers()
202-
.put("VOICE_SERVER_UPDATE", new VoiceServerUpdateInterceptor(this, (JDAImpl) event.getJDA()));
183+
Map<String, SocketHandler> handlers = ((JDAImpl) event.getJDA()).getClient().getHandlers();
184+
handlers.put("VOICE_SERVER_UPDATE", new VoiceServerUpdateInterceptor(this, (JDAImpl) event.getJDA()));
185+
handlers.put("VOICE_STATE_UPDATE", new VoiceStateUpdateInterceptor(this, (JDAImpl) event.getJDA()));
203186
}
204187

205188
@Override
206-
public void onDisconnect(DisconnectEvent event) {
207-
disconnectVoiceConnection(event.getJDA());
208-
}
209-
210-
@Override
211-
public void onShutdown(ShutdownEvent event) {
212-
disconnectVoiceConnection(event.getJDA());
213-
}
214-
215-
@Override
216-
public void onReconnect(ReconnectedEvent event) {
217-
reconnectVoiceConnections(event.getJDA());
218-
}
189+
public void onGuildLeave(GuildLeaveEvent event) {
190+
Link link = links.get(event.getGuild().getId());
191+
if (link == null) return;
219192

220-
@Override
221-
public void onResume(ResumedEvent event) {
222-
reconnectVoiceConnections(event.getJDA());
193+
link.removeConnection();
223194
}
224195

225196
@Override
226-
public void onGuildVoiceJoin(GuildVoiceJoinEvent event) {
227-
// Check if not ourselves
228-
if (!event.getMember().getUser().equals(event.getJDA().getSelfUser())) return;
197+
public void onVoiceChannelDelete(VoiceChannelDeleteEvent event) {
198+
Link link = links.get(event.getGuild().getId());
199+
if (link == null || !event.getChannel().equals(link.getLastChannel())) return;
229200

230-
getLink(event.getGuild()).onVoiceJoin();
201+
link.removeConnection();
231202
}
232203

233204
@Override
234-
public void onGuildVoiceLeave(GuildVoiceLeaveEvent event) {
235-
// Check if not ourselves
236-
if (!event.getMember().getUser().equals(event.getJDA().getSelfUser())) return;
237-
238-
getLink(event.getGuild()).onVoiceLeave();
205+
public void onReconnect(ReconnectedEvent event) {
206+
reconnectVoiceConnections(event.getJDA());
239207
}
240208

241-
@Override
242-
public void onGuildVoiceMove(GuildVoiceMoveEvent event) {
243-
// Check if not ourselves
244-
if (!event.getMember().getUser().equals(event.getJDA().getSelfUser())) return;
245-
246-
getLink(event.getGuild()).onGuildVoiceMove(event);
247-
}
248209

249210
private void reconnectVoiceConnections(JDA jda) {
250211
if (autoReconnect) {
251212
links.forEach((guildId, link) -> {
252213
try {
253214
//Note: We also ensure that the link belongs to the JDA object
254-
if (link.getCurrentChannel() != null
215+
if (link.getLastChannel() != null
255216
&& jda.getGuildById(guildId) != null) {
256-
link.connect(link.getCurrentChannel());
217+
link.connect(link.getLastChannel(), false);
257218
}
258219
} catch (Exception e) {
259220
log.error("Caught exception while trying to reconnect link " + link, e);
@@ -262,16 +223,4 @@ private void reconnectVoiceConnections(JDA jda) {
262223
}
263224
}
264225

265-
private void disconnectVoiceConnection(JDA jda) {
266-
links.forEach((guildId, link) -> {
267-
try {
268-
if (jda.getGuildById(guildId) != null) {
269-
link.disconnect();
270-
}
271-
} catch (Exception e) {
272-
log.error("Caught exception while trying to disconnect link " + link, e);
273-
}
274-
});
275-
}
276-
277226
}

0 commit comments

Comments
 (0)