15
15
import com .sedmelluq .discord .lavaplayer .track .AudioTrackInfo ;
16
16
import com .sedmelluq .discord .lavaplayer .track .InternalAudioTrack ;
17
17
import com .sedmelluq .discord .lavaplayer .track .playback .LocalAudioTrackExecutor ;
18
+ import kotlinx .serialization .json .JsonObject ;
19
+ import kotlinx .serialization .json .JsonPrimitive ;
18
20
import org .apache .commons .codec .binary .Hex ;
19
21
import org .apache .http .client .CookieStore ;
20
22
import org .apache .http .client .config .RequestConfig ;
@@ -57,13 +59,13 @@ private static String formatFormats(TrackFormat[] formats) {
57
59
return String .join ("," , strFormats );
58
60
}
59
61
60
- private JsonBrowser getJsonResponse (HttpUriRequest request , boolean useArl ) throws IOException {
62
+ private JsonBrowser getJsonResponse (HttpUriRequest request , String arl ) throws IOException {
61
63
try (HttpInterface httpInterface = this .sourceManager .getHttpInterface ()) {
62
64
httpInterface .getContext ().setRequestConfig (RequestConfig .custom ().setCookieSpec ("standard" ).build ());
63
65
httpInterface .getContext ().setCookieStore (cookieStore );
64
66
65
- if (useArl && this . sourceManager . getArl () != null ) {
66
- request .setHeader ("Cookie" , "arl=" + this . sourceManager . getArl () );
67
+ if (arl != null ) {
68
+ request .setHeader ("Cookie" , "arl=" + arl );
67
69
}
68
70
69
71
return LavaSrcTools .fetchResponseAsJson (httpInterface , request );
@@ -72,21 +74,21 @@ private JsonBrowser getJsonResponse(HttpUriRequest request, boolean useArl) thro
72
74
73
75
private String getSessionId () throws IOException {
74
76
var getSessionID = new HttpPost (DeezerAudioSourceManager .PRIVATE_API_BASE + "?method=deezer.ping&input=3&api_version=1.0&api_token=" );
75
- var sessionIdJson = this .getJsonResponse (getSessionID , false );
77
+ var sessionIdJson = this .getJsonResponse (getSessionID , null );
76
78
77
79
DeezerAudioSourceManager .checkResponse (sessionIdJson , "Failed to get session ID: " );
78
80
return sessionIdJson .get ("results" ).get ("SESSION" ).text ();
79
81
}
80
82
81
- private LicenseToken generateLicenceToken (boolean useArl ) throws IOException {
83
+ private LicenseToken generateLicenceToken (String arl ) throws IOException {
82
84
var request = new HttpGet (DeezerAudioSourceManager .PRIVATE_API_BASE + "?method=deezer.getUserData&input=3&api_version=1.0&api_token=" );
83
85
84
86
// session ID is not needed with ARL and vice-versa.
85
- if (! useArl || this . sourceManager . getArl () == null ) {
87
+ if (arl == null ) {
86
88
request .setHeader ("Cookie" , "sid=" + this .getSessionId ());
87
89
}
88
90
89
- var json = this .getJsonResponse (request , useArl );
91
+ var json = this .getJsonResponse (request , arl );
90
92
DeezerAudioSourceManager .checkResponse (json , "Failed to get user token: " );
91
93
92
94
return new LicenseToken (
@@ -95,30 +97,30 @@ private LicenseToken generateLicenceToken(boolean useArl) throws IOException {
95
97
);
96
98
}
97
99
98
- public SourceWithFormat getSource (boolean useArl , boolean isRetry ) throws IOException , URISyntaxException {
99
- var licenseToken = this .generateLicenceToken (useArl );
100
+ public SourceWithFormat getSource (String arl , boolean isRetry ) throws IOException , URISyntaxException {
101
+ var licenseToken = this .generateLicenceToken (arl );
100
102
101
103
var getTrackToken = new HttpPost (DeezerAudioSourceManager .PRIVATE_API_BASE + "?method=song.getData&input=3&api_version=1.0&api_token=" + licenseToken .apiToken );
102
104
getTrackToken .setEntity (new StringEntity ("{\" sng_id\" :\" " + this .trackInfo .identifier + "\" }" , ContentType .APPLICATION_JSON ));
103
- var trackTokenJson = this .getJsonResponse (getTrackToken , useArl );
105
+ var trackTokenJson = this .getJsonResponse (getTrackToken , arl );
104
106
DeezerAudioSourceManager .checkResponse (trackTokenJson , "Failed to get track token: " );
105
107
106
108
if (trackTokenJson .get ("error" ).get ("VALID_TOKEN_REQUIRED" ).text () != null && !isRetry ) {
107
109
// "error":{"VALID_TOKEN_REQUIRED":"Invalid CSRF token"}
108
110
// seems to indicate an invalid API token?
109
- return this .getSource (useArl , true );
111
+ return this .getSource (arl , true );
110
112
}
111
113
112
114
var trackToken = trackTokenJson .get ("results" ).get ("TRACK_TOKEN" ).text ();
113
115
114
116
var getMediaURL = new HttpPost (DeezerAudioSourceManager .MEDIA_BASE + "/get_url" );
115
117
getMediaURL .setEntity (new StringEntity ("{\" license_token\" :\" " + licenseToken .userLicenseToken + "\" ,\" media\" :[{\" type\" :\" FULL\" ,\" formats\" :[" + formatFormats (this .sourceManager .getFormats ()) + "]}],\" track_tokens\" : [\" " + trackToken + "\" ]}" , ContentType .APPLICATION_JSON ));
116
118
117
- var json = this .getJsonResponse (getMediaURL , useArl );
119
+ var json = this .getJsonResponse (getMediaURL , arl );
118
120
for (var error : json .get ("data" ).get ("errors" ).values ()) {
119
121
if (error .get ("code" ).asLong (0 ) == 2000 ) {
120
122
// error code 2000 = failed to decode track token
121
- return this .getSource (useArl , true );
123
+ return this .getSource (arl , true );
122
124
}
123
125
}
124
126
DeezerAudioSourceManager .checkResponse (json , "Failed to get media URL: " );
@@ -151,7 +153,19 @@ public void process(LocalAudioTrackExecutor executor) throws Exception {
151
153
return ;
152
154
}
153
155
154
- var source = this .getSource (this .sourceManager .getArl () != null , false );
156
+ String arl = null ;
157
+ var userData = this .getUserData (JsonObject .class );
158
+ if (userData != null && userData .containsKey ("arl" )) {
159
+ var userDataArl = userData .get ("arl" );
160
+ if (userDataArl instanceof JsonPrimitive && ((JsonPrimitive ) userDataArl ).isString ()) {
161
+ arl = ((JsonPrimitive ) userDataArl ).getContent ();
162
+ }
163
+ }
164
+ if (arl == null ) {
165
+ arl = this .sourceManager .getArl ();
166
+ }
167
+
168
+ var source = this .getSource (arl , false );
155
169
try (var stream = new DeezerPersistentHttpStream (httpInterface , source .url , source .contentLength , this .getTrackDecryptionKey ())) {
156
170
processDelegate (source .format .trackFactory .apply (this .trackInfo , stream ), executor );
157
171
}
0 commit comments