Compare commits

..

10 Commits

Author SHA1 Message Date
uh wot e7c610f089
changed homepage url 2022-08-23 14:55:07 +02:00
uh wot 86a2b45689
changed default media server 2022-08-17 15:06:44 +02:00
uh wot 725f846b77
changed homepage / download urls 2022-08-17 14:31:20 +02:00
uh wot a94074382c
added device limit bypass 2022-07-24 21:09:05 +02:00
uh wot a21c19228b
fixed gapless playback 2022-06-21 02:36:45 +02:00
uh wot 0ac770d844
removed more popup crap 2022-06-17 01:56:23 +02:00
uh wot 7891c8a093
replaced fetch library crap 2022-03-18 20:40:02 +01:00
uh wot 795b7fd1bb
disabled skip limit on mixes 2022-02-10 00:42:01 +01:00
uh wot ff1d8d2351
updated url in README 2021-11-22 00:11:11 +01:00
uh wot 3298f125c7
updated urls 2021-11-22 00:09:57 +01:00
2 changed files with 75 additions and 96 deletions

View File

@ -6,4 +6,4 @@ enables deezer hifi features lol
- install [violentmonke](https://violentmonkey.github.io/) (other userscript extensions may work, but are not supported) - install [violentmonke](https://violentmonkey.github.io/) (other userscript extensions may work, but are not supported)
- click [this link](https://git.freezer.life/uhwot/dzunlock/raw/branch/master/dzunlock.user.js) - click [this link](https://uhwotgit.fly.dev/uhwot/dzunlock/raw/branch/master/dzunlock.user.js)

View File

@ -3,10 +3,10 @@
// @namespace io.github.uhwot.dzunlock // @namespace io.github.uhwot.dzunlock
// @description enables deezer hifi features lol // @description enables deezer hifi features lol
// @author uh wot // @author uh wot
// @version 1.3.3 // @version 1.4.3
// @license GPL-3.0-only // @license GPL-3.0-only
// @homepageURL https://git.freezer.life/uhwot/dzunlock // @homepageURL https://git.uhwot.cf/uhwot/dzunlock
// @downloadURL https://git.freezer.life/uhwot/dzunlock/raw/branch/master/dzunlock.user.js // @downloadURL https://uhwotgit.fly.dev/uhwot/dzunlock/raw/branch/master/dzunlock.user.js
// @icon https://cdns-files.dzcdn.net/cache/images/common/favicon/favicon-96x96.852baf648e79894b668670e115e4a375.png // @icon https://cdns-files.dzcdn.net/cache/images/common/favicon/favicon-96x96.852baf648e79894b668670e115e4a375.png
// @include /^https:\/\/www\.deezer\.com\/[a-z]{2}\/($|track|album|artist|playlist|episode|show|profile|channels|podcasts|radio|\?|#)/ // @include /^https:\/\/www\.deezer\.com\/[a-z]{2}\/($|track|album|artist|playlist|episode|show|profile|channels|podcasts|radio|\?|#)/
// @match https://www.deezer.com/search/* // @match https://www.deezer.com/search/*
@ -26,65 +26,6 @@ function log(...args) {
} }
} }
// https://github.com/werk85/fetch-intercept/blob/develop/src/attach.js modified for browser support
let interceptors = [];
function interceptor(fetch, ...args) {
const reversedInterceptors = interceptors.reduce((array, interceptor) => [interceptor].concat(array), []);
let promise = Promise.resolve(args);
// Register request interceptors
reversedInterceptors.forEach(({ request, requestError }) => {
if (request || requestError) {
promise = promise.then(args => request(...args), requestError);
}
});
// Register fetch call
promise = promise.then(args => {
const request = new Request(...args);
return fetch(request).then(response => {
response.request = request;
return response;
}).catch(error => {
error.request = request;
return Promise.reject(error);
});
});
// Register response interceptors
reversedInterceptors.forEach(({ response, responseError }) => {
if (response || responseError) {
promise = promise.then(response, responseError);
}
});
return promise;
}
unsafeWindow.fetch = (function (fetch) {
return function (...args) {
return interceptor(fetch, ...args);
};
})(unsafeWindow.fetch);
fetchIntercept = {
register: function (interceptor) {
interceptors.push(interceptor);
return () => {
const index = interceptors.indexOf(interceptor);
if (index >= 0) {
interceptors.splice(index, 1);
}
};
},
clear: function () {
interceptors = [];
}
};
// main code starts here
const playerTokenKey = [102, 228, 95, 242, 215, 50, 122, 26, 57, 216, 206, 38, 164, 237, 200, 85] const playerTokenKey = [102, 228, 95, 242, 215, 50, 122, 26, 57, 216, 206, 38, 164, 237, 200, 85]
const cipher = new aesjs.ModeOfOperation.ecb(playerTokenKey) const cipher = new aesjs.ModeOfOperation.ecb(playerTokenKey)
@ -126,6 +67,8 @@ function playerTokenPatch(playerToken) {
// disables previews // disables previews
playerToken.streaming = true playerToken.streaming = true
playerToken.limited = false playerToken.limited = false
// disables skip limit on mixes
playerToken.radio_skips = 0
log(playerToken) log(playerToken)
@ -152,12 +95,59 @@ window.addEventListener('DOMContentLoaded', (_) => {
})(unsafeWindow.dzPlayer.setTrackList); })(unsafeWindow.dzPlayer.setTrackList);
}); });
fetchIntercept.register({ // https://greasyfork.org/en/scripts/38248-websocket-logger/code
request: function (url, config) { unsafeWindow.WebSocket = new Proxy(unsafeWindow.WebSocket, {
// Modify the url or config here construct: function (target, args, _) {
const url = args[0]
const ws = new target(url)
if (url !== 'wss://messaging.deezer.com/websocket') {
return ws
} else {
log('hooking websocket')
return new Proxy(ws, {
set: function (target, prop, val) {
if (prop == 'onmessage') {
var onmsg = val;
val = function (e) {
if (e.data.includes('SingleInstancePlayback')) {
log('preventing SingleInstancePlayback pubsub receive')
return
}
onmsg(e)
};
}
return target[prop] = val
},
get: function (target, prop) {
var val = target[prop];
if (prop == 'send') val = function (data) {
if (data.includes('SingleInstancePlayback')) {
log('preventing SingleInstancePlayback pubsub send')
return
}
target.send(data)
};
else if (typeof val == 'function') val = val.bind(target)
return val
}
})
}
}
})
unsafeWindow.fetch = (function (fetch) {
return async function (url, init) {
if (url === 'https://media.deezer.com/v1/get_url') { if (url === 'https://media.deezer.com/v1/get_url') {
let track
if (unsafeWindow.dzPlayer.getPosition() === 0) {
track = unsafeWindow.dzPlayer.getCurrentSong()
} else {
track = unsafeWindow.dzPlayer.getNextSong() // gapless playback
}
const quality = unsafeWindow.dzPlayer.control.getAudioQuality() const quality = unsafeWindow.dzPlayer.control.getAudioQuality()
const track = unsafeWindow.dzPlayer.getCurrentSong()
const id = parseInt(track.SNG_ID) const id = parseInt(track.SNG_ID)
let is_subbed = !unsafeWindow.dzPlayer.user_status.can_subscribe let is_subbed = !unsafeWindow.dzPlayer.user_status.can_subscribe
@ -168,7 +158,7 @@ fetchIntercept.register({
} }
if (id >= 0 && !is_quality_available) { if (id >= 0 && !is_quality_available) {
const media_server = GM_getValue('media_server', 'https://dzmedia.herokuapp.com') const media_server = GM_getValue('media_server', 'https://dzmedia.fly.dev')
url = `${media_server}/get_url` url = `${media_server}/get_url`
const body = { const body = {
@ -184,24 +174,14 @@ fetchIntercept.register({
} }
} }
config.body = JSON.stringify(body) init.body = JSON.stringify(body)
} }
} }
return [url, config]; let resp = await fetch(url, init)
},
requestError: function (error) { if (url.startsWith('https://www.deezer.com/ajax/gw-light.php?method=deezer.getUserData')) {
// Called when an error occured during another 'request' interceptor call let json = await resp.json()
return Promise.reject(error);
},
response: async function (response) {
// Modify the response object
if (response.url.startsWith('https://www.deezer.com/ajax/gw-light.php?method=deezer.getUserData')) {
let json = await response.json()
// removes upgrade popup stuff // removes upgrade popup stuff
json.results.USER.ENTRYPOINTS = {} json.results.USER.ENTRYPOINTS = {}
@ -215,25 +195,24 @@ fetchIntercept.register({
log(json) log(json)
return new Response(JSON.stringify(json)) resp = new Response(JSON.stringify(json), resp)
} } else if (url.startsWith('https://www.deezer.com/ajax/gw-light.php?method=deezer.userMenu')) {
let json = await resp.json()
if (response.url.startsWith('https://www.deezer.com/ajax/gw-light.php?method=log.listen')) { delete json.results.MARKETING_PUSH
const json = await response.json() delete json.results.MARKETING_PUSH_DATA
resp = new Response(JSON.stringify(json), resp)
} else if (url.startsWith('https://www.deezer.com/ajax/gw-light.php?method=log.listen')) {
const json = await resp.json()
if (typeof json.results === 'string') { if (typeof json.results === 'string') {
json.results = playerTokenPatch(json.results) json.results = playerTokenPatch(json.results)
} }
return new Response(JSON.stringify(json)) resp = new Response(JSON.stringify(json), resp)
} }
return response; return resp
}, };
})(unsafeWindow.fetch);
responseError: function (error) {
// Handle an fetch error
return Promise.reject(error);
}
});