diff --git a/DIU.meta.js b/DIU.meta.js index 141613a..36b1dd7 100644 --- a/DIU.meta.js +++ b/DIU.meta.js @@ -1,7 +1,7 @@ // ==UserScript== // @name Digitally Imported Userscript // @namespace LTKDIFMU -// @version 2017.10.0 +// @version 2018.1.0 // @author LethaK Maas // @description Removes afk popup and minimize ads if possible // @include https://*.di.fm* diff --git a/DIU.user.js b/DIU.user.js index fd359a0..cb1635c 100644 --- a/DIU.user.js +++ b/DIU.user.js @@ -1,7 +1,7 @@ // ==UserScript== // @name Digitally Imported Userscript // @namespace LTKDIFMU -// @version 2017.10.0 +// @version 2018.1.0 // @author LethaK Maas // @description Removes afk popup and minimize ads if possible // @include https://*.di.fm* @@ -16,8 +16,34 @@ // @run-at document-start // ==/UserScript== (function(){ - console.warn('[DIUserscript] Initializing'); + console.log('[DIUserscript] Initializing...'); + document.addEventListener("DOMContentLoaded", function(event) { + console.log('[DIUserscript] window.document ready'); + + redefineCommands(); + redefineReqres(); + redefineBlockAdBlock(); + redefineOptions(); + adSilencer(); + initTimeout(); + initInterval(); + + addVolumeNumericInput(); // comment this line if you don't want this feature + + + + console.log('[DIUserscript] Initialized'); + }); + + /** + * Utility function + * + * @param obj + * @param propName + * @param propValue + * @returns {*} + */ var defineProp = function(obj, propName, propValue){ delete obj[propName]; Object.defineProperty(obj, propName, { @@ -29,8 +55,83 @@ return obj; }; + /** + * Seems useful to identify if we are on DI or the other sites. + * Not required at the moment + * + * @returns string di|jazzradio|radiotunes|classicalradio|rockradio + */ + var getCurrentSiteKey = function() { + return di.app.options.network_key; + }; + + /** + * WebPlayer Utilities + * + * @type {{getCurentVolume: getCurentVolume, setVolume: setVolume}} + */ + var WebPlayer = { + event: { + onVolumeChange: function(func) { + console.log('[DIUserscript] WebPlayer.event.onVolumeChange (new handler)'); + if (typeof func !== 'function') { + var func = function(e,value){}; + } + di.app.WebplayerApp.model.on('change:volume', func); + } + }, + getVolume: function() { + return di.app.reqres.request('webplayer:volume'); + }, + setVolume: function(volume) { + console.log('[DIUserscript] WebPlayer.setVolume ', volume); + if (typeof volume === 'undefined') { + var volume = 10; + } + if (volume < 0) { + volume = 0; + } + if (volume > 100) { + volume = 100; + } + + di.app.commands.execute('webplayer:volume', volume); + // di.app.WebplayerApp.model.setVolume(value); + } + }; + + var removeHomeHeroPremiumVisualAds = function() { + var $bannersAnchors = jQuery('.banner a[href^="/premium?"]', '#hero.home'); + var iToRemove = 0 + $bannersAnchors.length; + var iRemoved = 0; + $bannersAnchors.each(function(i,v) { + jQuery(v).parents('.banner').remove(); + iRemoved = iRemoved + 1; + }); + + if (iRemoved > 0) { + console.warn('[DIUserscript] removeHomeHeroPremiumVisualAds (remove count): ', iRemoved); + } + }; + + /** + * This seems like a good idea to help keeping ads away + */ + var redefineOptions = function() { + console.log('[DIUserscript] redefineOptions'); + + defineProp(di.app.options.advertising, 'ad_repeat_cap', 0); + defineProp(di.app.options.advertising, 'interruptible_track_length', 13371337); + defineProp(di.app.options.advertising, 'interruptible_track_grace_period', 13371337); + defineProp(di.app.options.advertising, 'midroll_banner_continue_delay', 0); + defineProp(di.app.options, 'registration_wall', null); + }; + + /** + * Silencing audio ads whenever they get played. + */ var adSilencer = function(){ - console.warn('[DIUserscript] adSilencer'); + console.log('[DIUserscript] adSilencer'); // Silence ads whenever they get played ... (should not be happening, but we never know, the rascals ;) di.app.vent.on('webplayer:ad:begin', function(t) { @@ -44,30 +145,84 @@ }); }; + /** + * Adding a new volume control as a numerical input form + */ + var addVolumeNumericInput = function(){ + console.log('[DIUserscript] addVolumeNumericInput'); + + try{ + var $inputVolume = jQuery(''); + $inputVolume + .val(WebPlayer.getVolume()) // Initializing the input value with the current app volume + .on('change', function(e){ + e.stopPropagation(); + // When the user is using the input, we set the app volume corresponding to the value displayed. + WebPlayer.setVolume(jQuery(this).val()); + }) + .on('click', function(e){ + // Prevents the volume to reach 100 each time we change the volume using the input's native arrows, due to where the input is injected into the DOM for convenience. + e.stopPropagation(); + }) + ; + + var $containerCandidates = jQuery('#popup-volume'); // multisite supported: di and the others + if ($containerCandidates <= 0) { + throw {message: 'Cannot find a proper container in the DOM'}; + } + $inputVolume.appendTo($containerCandidates.first().find('.icon-sound')); // This is kind of hacky, but quick and working. + $containerCandidates.first() + .css('width', '210px') + .css('left', '-186px') + ; + + // When the user is changing the volume using the default slider, we adjust the input value with the new volume value. + WebPlayer.event.onVolumeChange(function(e, volume) { + this.val(volume); + }.bind($inputVolume)); + + } catch(err) { + console.error('[DIUserscript] addVolumeNumericInput error: ', err.message); + } + }; + + /** + * Confusing the client internal timers + * No certain this is still useful + */ var redefineTimers = function(){ - console.warn('[DIUserscript] redefineTimers'); + console.log('[DIUserscript] redefineTimers'); + var getTimeRemaining = function() { + console.warn('[DIUserscript] timers getTimeRemaining', 1337); + return 1337; + }; + try{ - di.app.WebplayerApp.Ads.Supervisor.timers.gracePeriod.getTimeRemaining = function() { return 1337; }; - di.app.WebplayerApp.Ads.Supervisor.timers.midroll.getTimeRemaining = function() { return 1337; }; - di.app.WebplayerApp.Ads.Supervisor.timers.session.getTimeRemaining = function() { return 1337; }; + di.app.WebplayerApp.Ads.Supervisor.timers.gracePeriod.getTimeRemaining = getTimeRemaining; + di.app.WebplayerApp.Ads.Supervisor.timers.session.getTimeRemaining = getTimeRemaining; } catch(err) { - console.error('[DIUserscript] redefineTimers error', err.message); + console.error('[DIUserscript] redefineTimers error: ', err.message); } }; + /** + * Overriding parts of the Command bus + */ var redefineCommands = function(){ - console.warn('[DIUserscript] redefineCommands'); + console.log('[DIUserscript] redefineCommands'); - // Go away + // Go away: Confusing the anti-adblock system into thinking we will not enforce its rules defineProp(di.app.commands._wreqrHandlers['adblocker:enforceWall'], 'callback', function () { console.warn('[DIUserscript] adblocker:enforceWall', 'rejected'); return jQuery.Deferred().reject().promise(); }); - }; + /** + * Overriding parts of the Request bus + */ var redefineReqres = function(){ - console.warn('[DIUserscript] redefineReqres'); + console.log('[DIUserscript] redefineReqres'); try { @@ -119,12 +274,13 @@ // Always judging people ... defineProp(di.app.reqres._wreqrHandlers['current_user:isPremium'], 'callback', function () { console.warn('[DIUserscript] current_user:isPremium', true); + // This is only to confuse the DI client, this will not give access to higher audio qualitiy or premium perks, unless if logged in with a real paid premium account from DI. return true; }); // Lets pretend var userType = di.app.reqres.request('current_user:type'); // guest|public|premium - console.warn('[DIUserscript] current_user:type ORIGINAL ', userType); + console.log('[DIUserscript] current_user:type ORIGINAL ', userType); if (userType === 'guest') { defineProp(di.app.reqres._wreqrHandlers['current_user:type'], 'callback', function () { console.warn('[DIUserscript] current_user:type', 'premium'); @@ -133,47 +289,15 @@ } } catch(err) { - console.error('[DIUserscript] redefineReqres error', err.message); + console.error('[DIUserscript] redefineReqres error: ', err.message); } - }; - // jQuery(window.document).ready(function() { - document.addEventListener("DOMContentLoaded", function(event) { - console.warn('[DIUserscript] window.document ready'); - - redefineCommands(); - redefineReqres(); - adSilencer(); - - setTimeout(function(){ - // // Improved webplayer quality (3 = High) (disabled, Free Listeners can change it via their account settings) - // console.warn('[DIUserscript] preferredQuality:set', 3); - // di.app.commands.execute('preferredQuality:set', 3); - // setTimeout(function(){ - // var audioQuality = di.app.reqres.request('audioQualities:selected').attributes; - // di.app.commands.execute('message:success', 'Webplayer audio quality is now: '+audioQuality.name+' '+audioQuality.content_quality.name+' '+audioQuality.content_format.name); - // }, 2000); - - redefineTimers(); - di.app.commands.execute('message:notice', 'DIUserscript is enabled ! enjoy free uninterrupted music'); - }, 2000); - - setInterval(function(){ - // Removing Premium ad display - jQuery('.premium-upsell').remove(); - jQuery('.menu-item.go-premium').remove(); - jQuery('.sidebar-ad-component').remove(); - jQuery('#panel-ad').remove(); - jQuery('.go-premium-cta').remove(); - - // Breaking anti AFK system - try { di.eventbus.trigger('user:active'); } catch(err) { console.error('(DIUserscript) : '+err.message); } - try { di.app.vent.trigger('user:active'); } catch(err) { console.error('(DIUserscript) : '+err.message); } - try { di.app.timedAlerts.stop(); } catch(err) { console.error('(DIUserscript) : '+err.message); } - }, 1000); - - + /** + * Overriding BlockAdBlock to prevent the anti-adblock system from messing with us. Who wants to be forced to eat shit ? + */ + var redefineBlockAdBlock = function(){ + console.log('[DIUserscript] redefineBlockAdBlock'); // Fuck BlockAdBlock var BlockAdBlock = function(options) { @@ -206,6 +330,52 @@ }; }; defineProp(window, 'BlockAdBlock', BlockAdBlock); - }); + }; + + /** + * Executed once, 2s after DOM document is ready + */ + var initTimeout = function(){ + console.log('[DIUserscript] initTimeout'); + + setTimeout(function(){ + // // Improved webplayer quality (3 = High) (disabled, Free Listeners can change it via their account settings) + // console.warn('[DIUserscript] preferredQuality:set', 3); + // di.app.commands.execute('preferredQuality:set', 3); + // setTimeout(function(){ + // var audioQuality = di.app.reqres.request('audioQualities:selected').attributes; + // di.app.commands.execute('message:success', 'Webplayer audio quality is now: '+audioQuality.name+' '+audioQuality.content_quality.name+' '+audioQuality.content_format.name); + // }, 2000); + + redefineTimers(); + + // Self promoting this script in case you want to quickly find the link to send to a friend ;) just comment this next line if you don't want it. + jQuery('