Script for blocking ads in VK (VKontakte), bypassing blocking detection, etc.
// ==UserScript== // @name VK Ads Fixes // @name:ru Правки рекламы ВКонтакте // @name:uk Правки реклами ВКонтакте // @namespace https://vtosters.app/ // @version 2.2 // @description Script for blocking ads in VK (VKontakte), bypassing blocking detection, etc. // @description:ru Скрипт для блокировки рекламы в VK (ВКонтакте), обхода обнаружения блокировки и т.д. // @description:uk Скрипт для блокування реклами у VK (ВКонтакті), обходу виявлення блокування тощо. // @author gdlbo, Vologhat // @match https://vk.com/* // @match https://vk.ru/* // @grant none // ==/UserScript== (() => { "use strict" class VkPeProperties { static #KEYS=[ "send_user_info_stats", "force_send_user_info", "send_user_info_on_localhost", "send_navigation_stats_in_spa", "log_send_user_info_errors", "web_mytracker_collect_post_stats", "web_stats_device_id", "web_stats_reduce_debounce", "web_stats_send_beacon", "web_stats_send_on_events_limit", "web_stats_transport_story_view", "sentry_js_web_request_timeouts_feature", "sentry_js_web_request_timeouts_forwarding", "sentry_js_web_timeouts_forwarding", "sentry_js_web_verbose", "sentry_log_network_errors", "ads_app_form_link_redirect", "ads_autopromotion_web_geo", "ads_easy_promote_goods_new_create_api", "ads_light_methods_protection", "ads_market_autopromotion_bookmarks_stats", "ads_use_vk_community_video_portrait_4_5", "clips_web_my_tracker", "feed_post_track_code_client_web", "games_send_track_visitor_activity", "js_errors_no_write_uncaught_errors", "tgb_adblock_protection", "post_adblock_protection_promo", "eager_error_monitoring", "mini_apps_performance_close_app_empty_event", "mini_apps_performance_iframe_errors", "mini_apps_performance_web", "mini_apps_send_my_tracker_activity", "post_click_analytics_int_ext_link_click_web", "posting_track_event_count", "unique_adblock_users", "audio_my_tracker_web", "mini_apps_send_stat_arguments_bridge_events_sdk", "ajax_request_parse_html_error", "js_errors_no_write_uncaught_errors", "tns_track_sections", "tns_track_hosts", "geminus_counter", "ads_pixels_track_new_events_web_mvk", "web_navigation_handlers", "measure_module_navigation_stats", "group_join_track_event_count", "feed_content_events_open_post_event_web", "feed_posts_duration_stats_fix", "collect_unsupported_user_info_stats", "log_fetch_requests", "log_fetch_requests_get", "post_adguard_protection_promo", "extended_ajax_logging", "messenger_mediascope_stats_collect", "audio_player_stats_web" ]; static isValidProperty(key) { return key in this.#KEYS } } //hook vk let actualVk=window.vk const vkHooks=new Set(); Object.defineProperty(window,"vk", { get:() => actualVk, set:(value) => { actualVk=value if(actualVk)vkHooks.forEach( hook => hook(actualVk)) return true }, configurable:true }) //hook vk properties const createAndPerformVkPropHook=(key,hookfn) => { //hook when vk redefines vkHooks.add(vk => { if(vk&&vk[key])hookfn(vk[key]) //hook when property redefines let actualProp=vk[key] Object.defineProperty(vk,key, { get:() => actualProp, set:(value) => { actualProp=value hookfn(actualProp) return true }, configurable:true, enumerable:true }) }) } //remove properties from vk.pe hook createAndPerformVkPropHook("pe",pe => { console.log("patch pe") Object.keys(pe) .filter(key => VkPeProperties.isValidProperty(key)) .forEach(key => delete window.vk.pe[key]) }) //patch vk.AudioAdsConfig hook createAndPerformVkPropHook("audioAdsConfig",audioAdsConfig => { console.log("patch audioAdsConfig") Object.defineProperties(audioAdsConfig, { enabled: { value:false }, day_limit_reached: { value:false }, sections: { value:[] } }) }) //disable error monitor DSN hook createAndPerformVkPropHook("cfg",cfg => { console.log("disable error monitoring DSN") Object.defineProperty(cfg.error_monitoring_config,"dsn", { value:"http://127.0.0.1" }) }) //patch vk.adParams hook createAndPerformVkPropHook("adParams",adParams => { console.log("patch adParams") Object.defineProperties(adParams, { ads_can_show: { value:0 }, leftads: { value:"" }, wsTransport: { value:"http://127.0.0.1" }, ads_rotate_interval: { vallue:Number.MAX_SAFE_INTEGER } }) }) //trigger vk and properties hooks window.vk=window.vk setInterval(() => { //replace "away.php" url to the redirect url document.querySelectorAll("a[href*='away.php']") .forEach(a => { const url=URL.parse(a.href) if(!url.pathname.endsWith("away.php"))return //find a search parameter with valid redirect url url.searchParams.forEach((value) => { if(URL.canParse(value)) { a.href=value return } }) }) //remove _ads_block_data_w blocks document.querySelectorAll("div._ads_block_data_w") .forEach(div => { console.log(`Remove block with id ${div.id}]`) div.remove() }) //remove ads_left block const adsLeft=document.getElementById("ads_left") if(adsLeft) { console.log("Remove block with id: ads_left") adsLeft.remove() } //clear all AdsLight functions if(window.AdsLight) Object.keys(window.AdsLight) .filter(key => typeof window.AdsLight[key]==="function") .forEach(key => Object.defineProperty(window.AdsLight,key, { value:() => {} })) //patch window ads properties Object.defineProperties(window, { noAds: { value:true, configurable:true }, noAdsAtAll: { value:true, configurable:true }, no_left_ads: { value:true, configurable:true }, no_ads: { value:true, configurable:true }, isNoAdsForce: { value:true, configurable:true }, hide_ad: { value:true, configurable:true }, ya_direct: { value:false, configurable:true }, yaDIrectAdActive: { value:false, configurable:true }, __adsSet: { value:() => {}, configurable:true }, __adsUpdate: { value:() => {}, configurable:true }, AdmanHTML: { value:false, configurable:true }, audioAdsConfig: { value:false, configurable:true }, __adsGetAjaxParams: { value:() => {}, configurable:true }, __adsLoader: { value:() => {}, configurable:true }, }) },30000/navigator.hardwareConcurrency) })();