Skip to content

Commit a775c01

Browse files
committed
Merge remote-tracking branch 'origin/dev'
2 parents 8d9e1bd + 21f135d commit a775c01

File tree

12 files changed

+464
-389
lines changed

12 files changed

+464
-389
lines changed

CHANGELOG.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,23 @@
33
Each release usually includes various fixes and improvements.
44
The most noteworthy of these, as well as any features and breaking changes, are listed here.
55

6+
## v3.1.1
7+
* Add equalizer support
8+
* Update lavaplayer to 1.3.10
9+
* Fixed automatic versioning
10+
* Added build config to upload binaries to GitHub releases from CI
11+
12+
Contributors:
13+
[@Devoxin](https://github.com/Devoxin),
14+
[@Frederikam](https://github.com/Frederikam/),
15+
[@calebj](https://github.com/calebj)
16+
17+
## v3.1
18+
* Replaced JDAA with Magma
19+
* Added an event for when the Discord voice WebSocket is closed
20+
* Replaced Tomcat and Java_Websocket with Undertow. WS and REST is now handled by the same
21+
server and port. Port is specified by `server.port`.
22+
623
## v3.0
724
* **Breaking:** The minimum required Java version to run the server is now Java 10.
825
**Please note**: Java 10 will be obsolete

IMPLEMENTATION.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,24 @@ Set player volume. Volume may range from 0 to 1000. 100 is default.
110110
}
111111
```
112112

113+
Using the player equalizer
114+
```json
115+
{
116+
"op": "equalizer",
117+
"guildId": "...",
118+
"bands": [
119+
{
120+
"band": 0,
121+
"gain": 0.2
122+
}
123+
]
124+
}
125+
```
126+
There are 16 bands (0-15) that can be changed.
127+
`gain` is the multiplier for the given band. The default value is 0. Valid values range from -0.25 to 1.0,
128+
where -0.25 means the given band is completely muted, and 0.25 means it is doubled. Modifying the gain could
129+
also change the volume of the output.
130+
113131
Tell the server to potentially disconnect from the voice server and potentially remove the player with all its data.
114132
This is useful if you want to move to a new node for a voice connection. Calling this op does not affect voice state,
115133
and you can send the same VOICE_SERVER_UPDATE to a new node.

LavalinkServer/build.gradle

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ apply plugin: 'application'
44
apply plugin: 'org.springframework.boot'
55
apply plugin: 'com.gorylenko.gradle-git-properties'
66
apply plugin: 'org.ajoberstar.grgit'
7+
apply plugin: 'kotlin'
8+
apply plugin: 'kotlin-spring'
79

810
description = 'Play audio to discord voice channels'
911
mainClassName = "lavalink.server.Launcher"
@@ -39,6 +41,7 @@ dependencies {
3941
compile group: 'space.npstr', name: 'Magma', version: magmaVersion
4042
compile group: 'com.sedmelluq', name: 'lavaplayer', version: lavaplayerVersion
4143
compile group: 'com.sedmelluq', name: 'jda-nas', version: jdaNasVersion
44+
compile group: 'org.jetbrains.kotlin', name: 'kotlin-reflect', version: kotlinVersion
4245

4346
compile group: 'com.github.shredder121', name: 'jda-async-packetprovider', version: jappVersion
4447
//required by japp
@@ -79,6 +82,17 @@ build {
7982
}
8083
}
8184

85+
compileKotlin {
86+
kotlinOptions {
87+
jvmTarget = "1.8"
88+
}
89+
}
90+
compileTestKotlin {
91+
kotlinOptions {
92+
jvmTarget = "1.8"
93+
}
94+
}
95+
8296
@SuppressWarnings("GrMethodMayBeStatic")
8397
String versionFromTag() {
8498

LavalinkServer/src/main/java/lavalink/server/io/SocketContext.java

Lines changed: 0 additions & 145 deletions
This file was deleted.
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
/*
2+
* Copyright (c) 2017 Frederik Ar. Mikkelsen & NoobLance
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy
5+
* of this software and associated documentation files (the "Software"), to deal
6+
* in the Software without restriction, including without limitation the rights
7+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
* copies of the Software, and to permit persons to whom the Software is
9+
* furnished to do so, subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in all
12+
* copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20+
* SOFTWARE.
21+
*/
22+
23+
package lavalink.server.io
24+
25+
import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager
26+
import lavalink.server.player.Player
27+
import lavalink.server.util.Ws
28+
import org.json.JSONObject
29+
import org.slf4j.LoggerFactory
30+
import org.springframework.web.socket.WebSocketSession
31+
import space.npstr.magma.MagmaApi
32+
import space.npstr.magma.MagmaMember
33+
import space.npstr.magma.events.api.MagmaEvent
34+
import space.npstr.magma.events.api.WebSocketClosed
35+
import java.util.*
36+
import java.util.concurrent.ConcurrentHashMap
37+
import java.util.concurrent.Executors
38+
import java.util.concurrent.ScheduledExecutorService
39+
import java.util.concurrent.TimeUnit
40+
import java.util.function.Consumer
41+
import java.util.function.Supplier
42+
43+
class SocketContext internal constructor(audioPlayerManagerSupplier: Supplier<AudioPlayerManager>, val session: WebSocketSession,
44+
socketServer: SocketServer, val userId: String) {
45+
46+
val audioPlayerManager: AudioPlayerManager = audioPlayerManagerSupplier.get()
47+
internal val magma: MagmaApi = MagmaApi.of { socketServer.getAudioSendFactory(it) }
48+
//guildId <-> Player
49+
val players = ConcurrentHashMap<String, Player>()
50+
private val statsExecutor: ScheduledExecutorService
51+
val playerUpdateService: ScheduledExecutorService
52+
53+
val playingPlayers: List<Player>
54+
get() {
55+
val newList = LinkedList<Player>()
56+
players.values.forEach { player -> if (player.isPlaying) newList.add(player) }
57+
return newList
58+
}
59+
60+
61+
init {
62+
magma.eventStream.subscribe { this.handleMagmaEvent(it) }
63+
64+
statsExecutor = Executors.newSingleThreadScheduledExecutor()
65+
statsExecutor.scheduleAtFixedRate(StatsTask(this, socketServer), 0, 1, TimeUnit.MINUTES)
66+
67+
playerUpdateService = Executors.newScheduledThreadPool(2) { r ->
68+
val thread = Thread(r)
69+
thread.name = "player-update"
70+
thread.isDaemon = true
71+
thread
72+
}
73+
}
74+
75+
internal fun getPlayer(guildId: String): Player {
76+
return players.computeIfAbsent(guildId
77+
) { _ -> Player(this, guildId, audioPlayerManager) }
78+
}
79+
80+
internal fun getPlayers(): Map<String, Player> {
81+
return players
82+
}
83+
84+
private fun handleMagmaEvent(magmaEvent: MagmaEvent) {
85+
if (magmaEvent is WebSocketClosed) {
86+
val out = JSONObject()
87+
out.put("op", "event")
88+
out.put("type", "WebSocketClosedEvent")
89+
out.put("guildId", magmaEvent.member.guildId)
90+
out.put("reason", magmaEvent.reason)
91+
out.put("code", magmaEvent.closeCode)
92+
out.put("byRemote", magmaEvent.isByRemote)
93+
94+
Ws.send(session, out)
95+
}
96+
}
97+
98+
internal fun shutdown() {
99+
log.info("Shutting down " + playingPlayers.size + " playing players.")
100+
statsExecutor.shutdown()
101+
audioPlayerManager.shutdown()
102+
playerUpdateService.shutdown()
103+
players.keys.forEach { guildId ->
104+
val member = MagmaMember.builder()
105+
.userId(userId)
106+
.guildId(guildId)
107+
.build()
108+
magma.removeSendHandler(member)
109+
magma.closeConnection(member)
110+
}
111+
112+
players.values.forEach(Consumer<Player> { it.stop() })
113+
magma.shutdown()
114+
}
115+
116+
companion object {
117+
118+
private val log = LoggerFactory.getLogger(SocketContext::class.java)
119+
}
120+
}

0 commit comments

Comments
 (0)