├── config.ini ├── .gitattributes ├── src ├── Modify.h ├── BlockTheSpot.vcxproj.user ├── stdafx.cpp ├── targetver.h ├── stdafx.h ├── BlockTheSpot.vcxproj.filters ├── dllmain.cpp ├── chrome_elf.def ├── Logger.h ├── BlockTheSpot.cpp ├── Modify.cpp └── BlockTheSpot.vcxproj ├── BlockTheSpot.bat ├── .gitignore ├── uninstall.bat ├── LICENSE ├── .github └── ISSUE_TEMPLATE │ └── bug_report.md ├── README.md └── install.ps1 /config.ini: -------------------------------------------------------------------------------- 1 | [Config] 2 | ;Log system 3 | Log = 0 -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | src/disasm-lib/* linguist-vendored 2 | src/mhook-lib/* linguist-vendored 3 | -------------------------------------------------------------------------------- /src/Modify.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "stdafx.h" 3 | 4 | DWORD WINAPI KillBanner (LPVOID); -------------------------------------------------------------------------------- /src/BlockTheSpot.vcxproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /BlockTheSpot.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | powershell -Command "& {Invoke-WebRequest -UseBasicParsing 'https://raw.githubusercontent.com/revinewyd/SpotifyPremium/main/install.ps1' | Invoke-Expression}" 3 | pause 4 | exit 5 | -------------------------------------------------------------------------------- /src/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // SpotifyAdBlock.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /src/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # This .gitignore file was automatically created by Microsoft(R) Visual Studio. 3 | ################################################################################ 4 | 5 | *.ipch 6 | /.vs/VSWorkspaceState.json 7 | /.vs/ProjectSettings.json 8 | /.vs/slnx.sqlite 9 | /.vs/BlockTheSpot 10 | /src/.vs/BlockTheSpot/v16 11 | /src/Release 12 | *.sln 13 | /Debug 14 | /Release 15 | *.exp 16 | *.iobj 17 | *.ipdb 18 | *.lib 19 | *.dll 20 | /src/Debug 21 | *.aps 22 | *.zip 23 | -------------------------------------------------------------------------------- /src/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #include "targetver.h" 9 | #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers 10 | // Windows Header Files: 11 | #include 12 | #include 13 | 14 | 15 | // TODO: reference additional headers your program requires here 16 | #include 17 | #include 18 | #include 19 | #include 20 | -------------------------------------------------------------------------------- /src/BlockTheSpot.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/dllmain.cpp: -------------------------------------------------------------------------------- 1 | // dllmain.cpp : Defines the entry point for the DLL application. 2 | #include "stdafx.h" 3 | #include "Modify.h" 4 | 5 | BOOL APIENTRY DllMain (HMODULE hModule, 6 | DWORD ul_reason_for_call, LPVOID lpReserved) 7 | { 8 | DisableThreadLibraryCalls (hModule); 9 | std::string_view procname = GetCommandLine (); 10 | // only Spotify process - this help avoid false positive 11 | if (std::string_view::npos != procname.find ("Spotify.exe")) { 12 | switch (ul_reason_for_call) 13 | { 14 | case DLL_PROCESS_ATTACH: 15 | if (std::string_view::npos == procname.find ("--type=")) { 16 | // block ads request - main process 17 | CreateThread (NULL, NULL, KillBanner, NULL, 0, NULL); 18 | } 19 | 20 | break; 21 | } 22 | } 23 | return TRUE; 24 | } 25 | 26 | -------------------------------------------------------------------------------- /src/chrome_elf.def: -------------------------------------------------------------------------------- 1 | LIBRARY "chrome_elf" 2 | 3 | EXPORTS 4 | AddDllToBlacklist 5 | ClearReportsBetween_ExportThunk 6 | CrashForException_ExportThunk 7 | DisableHook 8 | DrainLog 9 | DumpHungProcessWithPtype_ExportThunk 10 | DumpProcessWithoutCrash 11 | GetApplyHookResult 12 | GetBlockedModulesCount 13 | GetCrashReports_ExportThunk 14 | GetCrashpadDatabasePath_ExportThunk 15 | GetHandleVerifier 16 | GetInstallDetailsPayload 17 | GetUniqueBlockedModulesCount 18 | GetUserDataDirectoryThunk 19 | InjectDumpForHungInput_ExportThunk 20 | IsBlacklistInitialized 21 | IsCrashReportingEnabledImpl 22 | IsThirdPartyInitialized 23 | RegisterLogNotification 24 | RequestSingleCrashUpload_ExportThunk 25 | SetCrashKeyValueImpl 26 | SetMetricsClientId 27 | SetUploadConsent_ExportThunk 28 | SignalChromeElf 29 | SignalInitializeCrashReporting 30 | SuccessfullyBlocked -------------------------------------------------------------------------------- /uninstall.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | echo ***************** 3 | echo Author: @rednek46 4 | echo ***************** 5 | echo Removing Patch 6 | if exist "%APPDATA%\Spotify\chrome_elf.dll.bak" ( 7 | del /s /q "%APPDATA%\Spotify\chrome_elf.dll" > NUL 2>&1 8 | move "%APPDATA%\Spotify\chrome_elf.dll.bak" "%APPDATA%\Spotify\chrome_elf.dll" > NUL 2>&1 9 | ) else ( 10 | echo done 11 | ) 12 | 13 | if exist "%APPDATA%\Spotify\Apps\zlink.spa.bak" ( 14 | del /s /q "%APPDATA%\Spotify\Apps\zlink.spa" > NUL 2>&1 15 | move "%APPDATA%\Spotify\Apps\zlink.spa.bak" "%APPDATA%\Spotify\Apps\zlink.spa" > NUL 2>&1 16 | ) else ( 17 | echo done 18 | ) 19 | 20 | if exist "%APPDATA%\Spotify\Apps\xpui.spa.bak" ( 21 | del /s /q "%APPDATA%\Spotify\Apps\xpui.spa" > NUL 2>&1 22 | move "%APPDATA%\Spotify\Apps\xpui.spa.bak" "%APPDATA%\Spotify\Apps\xpui.spa" > NUL 2>&1 23 | ) else ( 24 | echo done 25 | ) 26 | pause 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 master131 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/Logger.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "stdafx.h" 3 | 4 | class Logger { 5 | private: 6 | auto current_datetime () 7 | { 8 | static struct tm newtime; 9 | static __time64_t long_time; 10 | _time64 (&long_time); 11 | localtime_s (&newtime, &long_time); 12 | return std::put_time (&newtime, "%d-%b-%Y %H:%M:%S"); 13 | } 14 | 15 | std::ofstream log_stream; 16 | const bool read (std::string_view app, std::string_view key, int def_value = 0) { 17 | if (1 == GetPrivateProfileInt (app.data (), key.data (), def_value, "./config.ini")) { 18 | return true; 19 | } 20 | return false; 21 | } 22 | 23 | 24 | public: 25 | Logger () { 26 | if (read ("Config", "Log")) { 27 | log_stream.open ("blockthespot_log.txt", std::ios::out | std::ios::app); 28 | //m_log << "BlockTheSpot - Build date: " << __TIMESTAMP__ << std::endl; 29 | } 30 | } 31 | 32 | ~Logger () { 33 | if (log_stream.is_open()) { 34 | log_stream.flush (); 35 | log_stream.close (); 36 | } 37 | } 38 | 39 | void Log (std::string_view log) { 40 | if (log_stream.is_open ()) { 41 | std::stringstream message; 42 | message << "LOG | " << current_datetime () << " - " << log; 43 | log_stream << message.str() << std::endl; 44 | } 45 | 46 | } 47 | 48 | 49 | }; 50 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Make sure you have completed everything in the following checklist. 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | Make sure you have completed everything in the following checklist. 11 | 12 | - [ ] You are using the Spotify `last tested version` mentioned in the [README](https://github.com/mrpond/BlockTheSpot/blob/master/README.md). 13 | - [ ] You are using the latest [BlockTheSpot](https://www.github.com/mrpond/BlockTheSpot/releases) from github. 14 | - [ ] You uninstalled Spotify and just ran [BlockTheSpot.bat](https://raw.githack.com/mrpond/BlockTheSpot/master/BlockTheSpot.bat) and is still having issues. 15 | - [ ] You read through the [known issues](https://github.com/mrpond/BlockTheSpot/blob/master/README.md#known-issues) section in the README. 16 | - [ ] You read through the [additional notes](https://github.com/mrpond/BlockTheSpot/blob/master/README.md#additional-notes) section in the README. 17 | - [ ] You enabled logging by editing config.ini `set log = 1`. 18 | 19 | ### Describe the bug 20 | A clear and concise description of what the bug is, along with your OS [eg. Windows 10]: 21 | 22 | Zip and attach the log file. 23 | 24 | 30 | -------------------------------------------------------------------------------- /src/BlockTheSpot.cpp: -------------------------------------------------------------------------------- 1 | // BlockTheSpot.cpp : Defines the exported functions for the DLL application. 2 | // 3 | 4 | #include "stdafx.h" 5 | 6 | bool AddDllToBlacklist (const wchar_t* dll_name) { return true; } 7 | void ClearReportsBetween_ExportThunk (time_t begin, time_t end) {} 8 | 9 | int CrashForException_ExportThunk (EXCEPTION_POINTERS* info) { 10 | return EXCEPTION_CONTINUE_SEARCH; 11 | } 12 | void DisableHook () {} 13 | 14 | UINT32 DrainLog (UINT8* buffer, 15 | UINT32 buffer_size, 16 | UINT32* log_remaining) { 17 | 18 | return 0; 19 | } 20 | 21 | bool DumpHungProcessWithPtype_ExportThunk (HANDLE process_handle, 22 | const char* ptype) { 23 | return false; 24 | } 25 | 26 | void DumpProcessWithoutCrash (void* task_port) {} 27 | 28 | INT32 GetApplyHookResult () { return 0; } 29 | UINT32 GetBlockedModulesCount () { return 0; } 30 | 31 | size_t GetCrashReports_ExportThunk (void* reports, 32 | size_t reports_size) { 33 | return 0; 34 | } 35 | 36 | const wchar_t* GetCrashpadDatabasePath_ExportThunk () { 37 | return nullptr; 38 | } 39 | void* GetHandleVerifier () { 40 | return nullptr; 41 | } 42 | UINT32 GetInstallDetailsPayload () { return 0; } 43 | UINT32 GetUniqueBlockedModulesCount () { return 0; } 44 | bool GetUserDataDirectoryThunk (wchar_t* user_data_dir, 45 | size_t user_data_dir_length, 46 | wchar_t* invalid_user_data_dir, 47 | size_t invalid_user_data_dir_length) { 48 | return true; 49 | } 50 | HANDLE InjectDumpForHungInput_ExportThunk (HANDLE process) { 51 | return nullptr; 52 | } 53 | bool IsBlacklistInitialized () { 54 | return false; 55 | } 56 | bool IsCrashReportingEnabledImpl () { 57 | return false; 58 | } 59 | bool IsThirdPartyInitialized () { 60 | return false; 61 | } 62 | bool RegisterLogNotification (HANDLE event_handle) { 63 | return false; 64 | } 65 | void RequestSingleCrashUpload_ExportThunk (const char* local_id) {} 66 | void SetCrashKeyValueImpl () {} 67 | void SetMetricsClientId (const char* client_id) {} 68 | void SetUploadConsent_ExportThunk (bool consent) {} 69 | void SignalChromeElf () {} 70 | void SignalInitializeCrashReporting () {} 71 | void SuccessfullyBlocked (const wchar_t** blocked_dlls, int* size) {} -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 |

Follow My Socials

3 |

Join My Discord Server

4 |
5 | 6 |
7 |

Lifetime Spotify Premium (PC Only)

8 |

A multi-purpose adblocker and skip-bypass for the Windows Spotify desktop application.

9 |
Please support Spotify by purchasing premium
10 |

11 | Last updated: 17 August 2021
12 | Last tested version: 1.1.66.580.gbd43cbc9-a 13 |

14 |
15 | 16 | #### Important checks before installing: 17 | 0. Update Windows, update Spotify and update BlockTheSpotify 18 | 1. Go to "Windows Security" -> "Virus & Threat Protection" 19 | 2. Click "Allowed threats" -> "Remove all allowed threats" 20 | 21 | ### Features: 22 | * Blocks all banner/video/audio ads within the app 23 | * Retains friend, vertical video and radio functionality 24 | * Unlocks the skip function for any track 25 | * Now supports the new Alpha version (New UI) 26 | 27 | :warning: This mod is for the [**Desktop Application**](https://www.spotify.com/download/windows/) of Spotify on Windows only and **not the Microsoft Store version**. 28 | 29 | ### Installation/Update: 30 | * Just download and run [BlockTheSpot.bat](https://raw.githubusercontent.com/revinewyd/SpotifyPremium/main/BlockTheSpot.bat) 31 | 32 | or 33 | 34 | * Run The following command in PowerShell: 35 | ```ps1 36 | Invoke-WebRequest -UseBasicParsing 'https://raw.githubusercontent.com/revinewyd/SpotifyPremium/main/install.ps1' | Invoke-Expression 37 | ``` 38 | 39 | 40 | ### Uninstall: 41 | * Just run uninstall.bat 42 | or 43 | * Reinstall Spotify 44 | 45 | ### Known Issues: 46 | * You may face issue [#150](https://github.com/mrpond/BlockTheSpot/issues/150). Can be fixed by enabling the experimental feature when using `BlockTheSpot.bat`. 47 | * We support last 2 version of Spotify (latest + previous) only. Please check it before opening an issue. 48 | 49 | ### Additional Notes: 50 | * Remove "Upgrade" Button [#83](https://github.com/mrpond/BlockTheSpot/issues/83) and Remove "Ad Placeholder" [#150](https://github.com/mrpond/BlockTheSpot/issues/150) only works when you use any of the auto installation methods and press `y` when prompted. 51 | * "chrome_elf.dll" gets replaced by the Spotify installer each time it updates, hence why you'll probably need to apply the patch again when it happens 52 | * [Spicetify](https://github.com/khanhas/spicetify-cli) users will need to reapply BlockTheSpot after applying a Spicetify patches. 53 | * If the automatic install/uninstall scripts do not work, please contact [revinewyd](https://github.com/revinewyd) 54 | * For more support and discussions, join our [Discord server](https://discord.gg/U8Kh2czvks) 55 | -------------------------------------------------------------------------------- /src/Modify.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Modify.h" 3 | #include "Logger.h" 4 | 5 | //#include 6 | 7 | 8 | 9 | /* 10 | * 11 | * Black banner still show even libcef hooked. 12 | * 13 | */ 14 | 15 | /* 16 | using _cef_urlrequest_create = cef_urlrequest_t * (*)(struct _cef_request_t* request, 17 | struct _cef_urlrequest_client_t* client, 18 | struct _cef_request_context_t* request_context); 19 | 20 | static _cef_urlrequest_create cef_urlrequest_create_orig; 21 | 22 | static constexpr std::array block_list = { "/ads/", "/ad-logic/", "/gabo-receiver-service/" }; 23 | 24 | cef_urlrequest_t* cef_urlrequest_create_hook (struct _cef_request_t* request, 25 | struct _cef_urlrequest_client_t* client, 26 | struct _cef_request_context_t* request_context) 27 | { 28 | 29 | cef_string_userfree_utf16_t url_utf16 = request->get_url (request); 30 | 31 | char* c_url = new char[url_utf16->length + 1]; 32 | c_url[url_utf16->length] = '\0'; 33 | 34 | for (size_t i = 0; i < url_utf16->length; i++) { 35 | c_url[i] = *reinterpret_cast(url_utf16->str + i); 36 | } 37 | 38 | std::string url (c_url); 39 | 40 | delete[] c_url; 41 | cef_string_userfree_utf16_free (url_utf16); 42 | 43 | for (const auto& blockurl : block_list) { 44 | if (std::string::npos != url.find (blockurl)) { 45 | g_Logger.Log ("blocked - " + url); 46 | return nullptr; 47 | } 48 | } 49 | g_Logger.Log ("allow - " + url); 50 | return cef_urlrequest_create_orig (request, client, request_context); 51 | } 52 | */ 53 | 54 | // https://www.unknowncheats.me/forum/1064672-post23.html 55 | bool DataCompare (BYTE* pData, BYTE* bSig, char* szMask) 56 | { 57 | for (; *szMask; ++szMask, ++pData, ++bSig) 58 | { 59 | if (*szMask == 'x' && *pData != *bSig) 60 | return false; 61 | } 62 | return (*szMask) == NULL; 63 | } 64 | 65 | BYTE* FindPattern (BYTE* dwAddress, const DWORD dwSize, BYTE* pbSig, char* szMask) 66 | { 67 | DWORD length = strlen (szMask); 68 | for (DWORD i = NULL; i < dwSize - length; i++) 69 | { 70 | __try 71 | { 72 | if (DataCompare (dwAddress + i, pbSig, szMask)) 73 | return dwAddress + i; 74 | } 75 | __except (EXCEPTION_EXECUTE_HANDLER) { 76 | return nullptr; 77 | } 78 | } 79 | return 0; 80 | } 81 | 82 | 83 | DWORD WINAPI KillBanner (LPVOID) 84 | { 85 | Logger g_Logger; 86 | HMODULE hModule = GetModuleHandle (NULL); 87 | MODULEINFO mInfo = { 0 }; 88 | if (GetModuleInformation (GetCurrentProcess (), hModule, &mInfo, sizeof (MODULEINFO))) { 89 | g_Logger.Log ("GetModuleInformation OK!"); 90 | auto skipPod = FindPattern ((uint8_t*)hModule, mInfo.SizeOfImage, (BYTE*)"\x83\xC4\x08\x84\xC0\x0F\x84\xE5\x03\x00\x00", "xxxxxxxxxxx"); 91 | 92 | if (skipPod) 93 | { 94 | DWORD oldProtect; 95 | VirtualProtect ((char*)skipPod + 5, 1, PAGE_EXECUTE_READWRITE, &oldProtect); 96 | memset ((char*)skipPod + 5, 0x90, 1); 97 | VirtualProtect ((char*)skipPod + 5, 1, oldProtect, &oldProtect); 98 | 99 | VirtualProtect ((char*)skipPod + 6, 1, PAGE_EXECUTE_READWRITE, &oldProtect); 100 | memset ((char*)skipPod + 6, 0xE9, 1); 101 | VirtualProtect ((char*)skipPod + 6, 1, oldProtect, &oldProtect); 102 | g_Logger.Log ("main process - patch success!"); 103 | } 104 | else { 105 | g_Logger.Log ("main process - patch failed!"); 106 | 107 | skipPod = FindPattern ((uint8_t*)hModule, mInfo.SizeOfImage, (BYTE*)"\x83\xC4\x08\x84\xC0\x0F\x84\xED\x03\x00\x00", "xxxxxxxxxxx"); 108 | if (skipPod) 109 | { 110 | DWORD oldProtect; 111 | VirtualProtect ((char*)skipPod + 5, 1, PAGE_EXECUTE_READWRITE, &oldProtect); 112 | memset ((char*)skipPod + 5, 0x90, 1); 113 | VirtualProtect ((char*)skipPod + 5, 1, oldProtect, &oldProtect); 114 | 115 | VirtualProtect ((char*)skipPod + 6, 1, PAGE_EXECUTE_READWRITE, &oldProtect); 116 | memset ((char*)skipPod + 6, 0xE9, 1); 117 | VirtualProtect ((char*)skipPod + 6, 1, oldProtect, &oldProtect); 118 | g_Logger.Log ("main process 1.1.66.578.gc54d0f69-a - patch success!"); 119 | } 120 | else { 121 | g_Logger.Log ("main process 1.1.66.578.gc54d0f69-a - patch failed!"); 122 | } 123 | } 124 | 125 | } 126 | else { 127 | g_Logger.Log ("GetModuleInformation failed!"); 128 | } 129 | 130 | /* 131 | hModule = GetModuleHandle ("libcef.dll"); 132 | if (!hModule) 133 | hModule = LoadLibrary ("libcef.dll"); 134 | 135 | if (hModule) 136 | { 137 | cef_urlrequest_create_orig = cef_urlrequest_create;//(_cef_urlrequest_create)GetProcAddress (hModule, "cef_urlrequest_create"); 138 | 139 | if (cef_urlrequest_create_orig) { 140 | Mhook_SetHook ((PVOID*)&cef_urlrequest_create_orig, cef_urlrequest_create_hook); 141 | } 142 | } 143 | */ 144 | 145 | 146 | return 0; 147 | } 148 | -------------------------------------------------------------------------------- /src/BlockTheSpot.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {82F7E20E-D166-4474-8EB1-81160355B5B2} 15 | Win32Proj 16 | SpotifyAdBlock 17 | 10.0 18 | BlockTheSpot 19 | 20 | 21 | 22 | DynamicLibrary 23 | true 24 | v142 25 | MultiByte 26 | 27 | 28 | DynamicLibrary 29 | false 30 | v142 31 | true 32 | MultiByte 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | true 47 | chrome_elf 48 | $(ProjectDir)..\ 49 | 50 | 51 | chrome_elf 52 | $(ProjectDir)..\ 53 | $(ACE_ROOT);$(IncludePath) 54 | $(ACE_ROOT)\lib;$(LibraryPath) 55 | 56 | 57 | 58 | 59 | 60 | Level3 61 | Disabled 62 | WIN32;_DEBUG;_WINDOWS;_USRDLL;BLOCKTHESPOT_EXPORTS;%(PreprocessorDefinitions) 63 | true 64 | stdcpp17 65 | 66 | 67 | Windows 68 | true 69 | chrome_elf.def 70 | %(AdditionalDependencies) 71 | 72 | 73 | 74 | 75 | Level3 76 | 77 | 78 | MaxSpeed 79 | true 80 | WIN32;NDEBUG;_WINDOWS;_USRDLL;BLOCKTHESPOT_EXPORTS;%(PreprocessorDefinitions) 81 | MultiThreaded 82 | None 83 | Speed 84 | AnySuitable 85 | Sync 86 | true 87 | stdcpp17 88 | 89 | 90 | Windows 91 | true 92 | true 93 | false 94 | chrome_elf.def 95 | 96 | 97 | UseLinkTimeCodeGeneration 98 | true 99 | false 100 | %(AdditionalDependencies) 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | false 112 | 113 | 114 | false 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | -------------------------------------------------------------------------------- /install.ps1: -------------------------------------------------------------------------------- 1 | # Ignore errors from `Stop-Process` 2 | $PSDefaultParameterValues['Stop-Process:ErrorAction'] = 'SilentlyContinue' 3 | 4 | write-host @' 5 | ***************** 6 | @revinewyd message: 7 | Follow my socials! 8 | https://myurls.co/revinewyd 9 | ***************** 10 | '@ 11 | 12 | write-host @' 13 | ***************** 14 | Author: @revinewyd 15 | ***************** 16 | '@ 17 | 18 | $SpotifyDirectory = "$env:APPDATA\Spotify" 19 | $SpotifyExecutable = "$SpotifyDirectory\Spotify.exe" 20 | $SpotifyApps = "$SpotifyDirectory\Apps" 21 | 22 | Write-Host 'Stopping Spotify...'`n 23 | Stop-Process -Name Spotify 24 | Stop-Process -Name SpotifyWebHelper 25 | 26 | if ($PSVersionTable.PSVersion.Major -ge 7) 27 | { 28 | Import-Module Appx -UseWindowsPowerShell 29 | } 30 | 31 | if (Get-AppxPackage -Name SpotifyAB.SpotifyMusic) { 32 | Write-Host @' 33 | The Microsoft Store version of Spotify has been detected which is not supported. 34 | '@`n 35 | $ch = Read-Host -Prompt "Uninstall Spotify Windows Store edition (Y/N) " 36 | if ($ch -eq 'y'){ 37 | Write-Host @' 38 | Uninstalling Spotify. 39 | '@`n 40 | Get-AppxPackage -Name SpotifyAB.SpotifyMusic | Remove-AppxPackage 41 | } else{ 42 | Write-Host @' 43 | Exiting... 44 | '@`n 45 | Pause 46 | exit 47 | } 48 | } 49 | 50 | Push-Location -LiteralPath $env:TEMP 51 | try { 52 | # Unique directory name based on time 53 | New-Item -Type Directory -Name "BlockTheSpot-$(Get-Date -UFormat '%Y-%m-%d_%H-%M-%S')" ` 54 | | Convert-Path ` 55 | | Set-Location 56 | } catch { 57 | Write-Output $_ 58 | Pause 59 | exit 60 | } 61 | 62 | Write-Host 'Downloading latest patch (chrome_elf.zip)...'`n 63 | $webClient = New-Object -TypeName System.Net.WebClient 64 | try { 65 | $webClient.DownloadFile( 66 | # Remote file URL 67 | 'https://github.com/mrpond/BlockTheSpot/releases/latest/download/chrome_elf.zip', 68 | # Local file path 69 | "$PWD\chrome_elf.zip" 70 | ) 71 | } catch { 72 | Write-Output $_ 73 | Sleep 74 | } 75 | <# 76 | try { 77 | $webClient.DownloadFile( 78 | # Remote file URL 79 | 'https://github.com/mrpond/BlockTheSpot/files/5969916/zlink.zip', 80 | # Local file path 81 | "$PWD\zlink.zip" 82 | ) 83 | } catch { 84 | Write-Output $_ 85 | Sleep 86 | } 87 | try { 88 | $webClient.DownloadFile( 89 | # Remote file URL 90 | 'https://github.com/mrpond/BlockTheSpot/files/6234124/xpui.zip', 91 | # Local file path 92 | "$PWD\xpui.zip" 93 | ) 94 | } catch { 95 | Write-Output $_ 96 | Sleep 97 | } 98 | #> 99 | Expand-Archive -Force -LiteralPath "$PWD\chrome_elf.zip" -DestinationPath $PWD 100 | Remove-Item -LiteralPath "$PWD\chrome_elf.zip" 101 | <# 102 | Expand-Archive -Force -LiteralPath "$PWD\zlink.zip" -DestinationPath $PWD 103 | Remove-Item -LiteralPath "$PWD\zlink.zip" 104 | Expand-Archive -Force -LiteralPath "$PWD\xpui.zip" -DestinationPath $PWD 105 | Remove-Item -LiteralPath "$PWD\xpui.zip" 106 | #> 107 | $spotifyInstalled = (Test-Path -LiteralPath $SpotifyExecutable) 108 | if (-not $spotifyInstalled) { 109 | Write-Host @' 110 | Spotify installation was not detected. 111 | Downloading Latest Spotify full setup, please wait... 112 | '@ 113 | try { 114 | $webClient.DownloadFile( 115 | # Remote file URL 116 | 'https://download.scdn.co/SpotifyFullSetup.exe', 117 | # Local file path 118 | "$PWD\SpotifyFullSetup.exe" 119 | ) 120 | } catch { 121 | Write-Output $_ 122 | Pause 123 | exit 124 | } 125 | mkdir $SpotifyDirectory >$null 2>&1 126 | Write-Host 'Running installation...' 127 | Start-Process -FilePath "$PWD\SpotifyFullSetup.exe" 128 | Write-Host 'Stopping Spotify...Again' 129 | while ((Get-Process -name Spotify -ErrorAction SilentlyContinue) -eq $null){ 130 | #waiting until installation complete 131 | } 132 | Stop-Process -Name Spotify >$null 2>&1 133 | Stop-Process -Name SpotifyWebHelper >$null 2>&1 134 | Stop-Process -Name SpotifyFullSetup >$null 2>&1 135 | } 136 | 137 | if (!(test-path $SpotifyDirectory/chrome_elf.dll.bak)){ 138 | move $SpotifyDirectory\chrome_elf.dll $SpotifyDirectory\chrome_elf.dll.bak >$null 2>&1 139 | } 140 | 141 | Write-Host 'Patching Spotify...' 142 | $patchFiles = "$PWD\chrome_elf.dll", "$PWD\config.ini" 143 | <# 144 | $remup = "$PWD\zlink.spa" 145 | $uipat = "$PWD\xpui.spa" 146 | #> 147 | Copy-Item -LiteralPath $patchFiles -Destination "$SpotifyDirectory" 148 | <# 149 | $ch = Read-Host -Prompt "Optional - Remove Upgrade Button. (Y/N) " 150 | if ($ch -eq 'y'){ 151 | move $SpotifyApps\zlink.spa $SpotifyApps\zlink.spa.bak >$null 2>&1 152 | Copy-Item -LiteralPath $remup -Destination "$SpotifyApps" 153 | } else{ 154 | Write-Host @' 155 | Won't remove Upgrade Button. 156 | '@`n 157 | } 158 | 159 | $ch = Read-Host -Prompt "Change Alpha UI back to Old UI. (BTS only supports Old UI). (Y/N) " 160 | if ($ch -eq 'y'){ 161 | move $SpotifyApps\xpui.spa $SpotifyApps\xpui.spa.bak >$null 2>&1 162 | Copy-Item -LiteralPath $uipat -Destination "$SpotifyApps" 163 | } else{ 164 | Write-Host @' 165 | UI isn't changed. 166 | '@`n 167 | } 168 | #> 169 | 170 | $ch = Read-Host -Prompt "Optional - Remove ad placeholder and upgrade button. (Experimental) (Y/N) " 171 | if ($ch -eq 'y') { 172 | Add-Type -Assembly 'System.IO.Compression.FileSystem' 173 | 174 | Copy-Item -Path "$SpotifyApps\xpui.spa" -Destination "$SpotifyApps\xpui.spa.bak" 175 | 176 | $zip = [System.IO.Compression.ZipFile]::Open("$SpotifyApps\xpui.spa", 'update') 177 | $entry = $zip.GetEntry('xpui.js') 178 | 179 | # Extract xpui.js from zip to memory 180 | $reader = New-Object System.IO.StreamReader($entry.Open()) 181 | $xpuiContents = $reader.ReadToEnd() 182 | $reader.Close() 183 | 184 | # Replace ".ads.leaderboard.isEnabled" + separator - '}' or ')' 185 | # With ".ads.leaderboard.isEnabled&&false" + separator 186 | $xpuiContents = $xpuiContents -replace '(\.ads\.leaderboard\.isEnabled)(}|\))', '$1&&false$2' 187 | 188 | # Delete ".createElement(XX,{onClick:X,className:XX.X.UpgradeButton}),X()" 189 | $xpuiContents = $xpuiContents -replace '\.createElement\([^.,{]+,{onClick:[^.,]+,className:[^.]+\.[^.]+\.UpgradeButton}\),[^.(]+\(\)', '' 190 | 191 | # Rewrite it to the zip 192 | $writer = New-Object System.IO.StreamWriter($entry.Open()) 193 | $writer.BaseStream.SetLength(0) 194 | $writer.Write($xpuiContents) 195 | $writer.Close() 196 | 197 | $zip.Dispose() 198 | } else { 199 | Write-Host @' 200 | Won't remove ad placeholder and upgrade button. 201 | '@`n 202 | } 203 | 204 | $tempDirectory = $PWD 205 | Pop-Location 206 | 207 | Remove-Item -Recurse -LiteralPath $tempDirectory 208 | 209 | Write-Host 'Patching Complete, starting Spotify...' 210 | Start-Process -WorkingDirectory $SpotifyDirectory -FilePath $SpotifyExecutable 211 | Write-Host 'Done.' 212 | 213 | write-host @' 214 | ***************** 215 | @revinewyd message: 216 | Follow my socials! 217 | https://myurls.co/revinewyd 218 | ***************** 219 | '@ 220 | 221 | exit 222 | --------------------------------------------------------------------------------