Greasy Fork is available in English.

Прави учебниците безплатни

Сменя от демо сървъра, към пълната тетрадка. Видеята не работят, липсва функцията и трябва да разгадая дали може да се хакнат

// ==UserScript==
// @name        Прави учебниците безплатни
// @namespace   https://greasyfork.org
// @match       https://ebook.domino.bg/books/*
// @grant       GM_addStyle
// @version     1.5
// @author      RedTTG
// @description Сменя от демо сървъра, към пълната тетрадка. Видеята не работят, липсва функцията и трябва да разгадая дали може да се хакнат
// @run-at      document-start
// @grant       GM.xmlHttpRequest
// @connect     *
// ==/UserScript==

const STYLE = `.tophead._demo {
  background-color: rgba(0, 66, 99, 0.5);
}
.tophead._demo div.txt {
  background-color: rgba(11, 222, 162, 0.4);
}`

const initialText = "(v1.5) Хакнато от RedTTG";

const regexIdentifier = /\/books\/([^\/]+\/[^\/]+)\//;

let hacked = false;
let added_styles = false;

function replaceDemo(script) {
    //return script.replaceAll("docs_demo", "docs");
    return script.replaceAll("docs_demo", `https://ugiu8fgifh2wduy1dhsuidhisudahgs8i.free.bg${window.location.pathname}`)

}

window.addEventListener('beforescriptexecute', function(e) {  // FIREFOX ONLY
    if (e.target.innerHTML.search("FlowPaperViewer") != -1) {
        e.target.innerHTML = replaceDemo(e.target.innerHTML);
        console.log("Switched from demo server to complete book! Enjoy ;)")
        hacked = true;
    } else if (e.target.innerHTML.search("ebookLoginPrompt") != -1) {
        e.target.innerHTML = e.target.innerHTML.replace("ebookLoginPrompt()", `console.log("Removed prompt to buy book!")`)
    }
})

function extractConfig(scriptText) {
    const match = scriptText.match(/FlowPaperViewer\(([\s\S]*?)\)/);

    if (match) {
        const configString = match[1];
        try {
            const configObject = eval('(' + replaceDemo(configString) + ')');
            return configObject;
        } catch (error) {
            console.error('Error parsing config config:', error);
            return null;
        }
    }

    return null;
}

function try_hack_1_2(demo_text) {  // CHROME // NON FIREFOX
    let buyOverlay = document.getElementById("simplemodal-overlay");
    let buyContainer = document.getElementById("simplemodal-container");

    demo_text.innerHTML = "Oпит за non Firefox..."

    buyOverlay.remove();
    buyContainer.remove();

    let flowpaper = FlowPaperViewer_InstancedocumentViewer;
    console.log(flowpaper);
    if (flowpaper.initialized){
      flowpaper.dispose();
    } else {
      let flowpaperLoader = document.querySelectorAll(".flowpaper_loader")[0];
      flowpaperLoader.remove();
    }

    const scripts = document.querySelectorAll('script');

    scripts.forEach((script) => {
        const scriptText = script.textContent || script.innerText;

        const config = extractConfig(scriptText);

        if (config) {
            $('#documentViewer').FlowPaperViewer(config);
            hacked = true;
            demo_text.innerHTML = initialText + " - non Firefox";
            finalize_hack();
            return;
        }
    });


    if (!hacked) {
        demo_text.innerHTML = initialText + " - грешка";
        finalize_hack();
    }
}

window.addEventListener("load", () => {
    let demo_text = document.getElementsByClassName("demo")[0];
    if (demo_text) {
        if (hacked) {
            demo_text.innerHTML = initialText + " - Firefox"
        } else {
            demo_text.innerHTML = "Грешка, опит за non Firefox след 2 секунди..."
            setTimeout(() => {
                try_hack_1_2(demo_text)
            }, 2000)
        }
        console.log("Leaving a positive text")
    } else {
        console.error("Couldn't find the negative demo text :(")
    }
    finalize_hack();
})

function finalize_hack() {
    var tocButtons = document.getElementsByClassName("flowpaper_toc_close");
    if (tocButtons.length > 0) {
        tocButtons[0].dispatchEvent(new Event('mousedown'));
        setTimeout(load_pages, 100);
    } else {
        setTimeout(finalize_hack, 100);
    }
    if (hacked && !added_styles) {
        GM_addStyle(STYLE);
        added_styles = true;
    }
  if (hacked) {
    let i = 2 / 0;
  }
}

function get_local_storage() {
  var url = window.location.href;
  var match = url.match(regexIdentifier);
  return `page-+-${match ? match[1] : "BLANK"}`;
}

function load_pages() {
  const pageN = localStorage.getItem(get_local_storage(), 1);
  let flowpaper = FlowPaperViewer_InstancedocumentViewer;

  $('body').click(function (event) {
    setTimeout(function () {
      localStorage.setItem(get_local_storage(), flowpaper.getCurrPage());
    }, 100);
  })

  if (pageN === null) {
    return null;
  }


  flowpaper.gotoPage(pageN);
}

(function() {
    // Store the original XMLHttpRequest open method
    const originalOpen = XMLHttpRequest.prototype.open;

    // Override XMLHttpRequest.open
    XMLHttpRequest.prototype.open = function(method, url) {
        console.log("Intercepting XHR:", method, url);

        // Store the request method and URL
        this._url = replaceDemo(url);
        this._method = method;

        // Prevent further execution of original XHR open
        return originalOpen.apply(this, arguments);
    };

    // Override send to use GM.xmlHttpRequest
    const originalSend = XMLHttpRequest.prototype.send;
    XMLHttpRequest.prototype.send = function(body) {
        const xhr = this;

        // Use GM.xmlHttpRequest to bypass CORS restrictions
        GM.xmlHttpRequest({
            method: xhr._method,
            url: xhr._url,
            data: body,
            headers: {
                'Content-Type': 'application/json',
                // Add other headers if needed
            },
            onload: function(response) {
                // Simulate successful response to the original XHR request
                Object.defineProperty(xhr, 'responseText', { value: response.responseText });
                Object.defineProperty(xhr, 'status', { value: response.status });
                Object.defineProperty(xhr, 'readyState', { value: 4 });

                // Trigger the original event listeners, pretending the XHR finished
                if (typeof xhr.onreadystatechange === 'function') {
                    xhr.onreadystatechange();
                }
            },
            onerror: function(error) {
                console.error("Request failed:", error);
            }
        });
    };
})();