TruyenFull downloader

Tải truyện từ TruyenFull định dạng EPUB.

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name            TruyenFull downloader
// @name:vi         TruyenFull downloader
// @namespace       https://baivong.github.io/
// @description     Tải truyện từ TruyenFull định dạng EPUB.
// @description:vi  Tải truyện từ TruyenFull định dạng EPUB.
// @version         4.7.1
// @icon            https://i.imgur.com/FQY8btq.png
// @author          Maivl
// @oujs:author     Maivl
// @license         MIT; https://baivong.mit-license.org/license.txt
// @match           https://sstruyen.vn/*
// @require         https://code.jquery.com/jquery-3.6.3.min.js
// @require         https://unpkg.com/[email protected]/dist/jszip.min.js
// @require         https://unpkg.com/[email protected]/dist/FileSaver.min.js
// @require         https://unpkg.com/[email protected]/ejs.min.js
// @require         https://unpkg.com/[email protected]/dist/jepub.min.js
// @require         https://greasemonkey.github.io/gm4-polyfill/gm4-polyfill.js?v=a834d46
// @noframes
// @connect         self
// @connect         8cache.com
// @supportURL      https://github.com/lelinhtinh/Userscript/issues
// @run-at          document-idle
// @grant           GM_xmlhttpRequest
// @grant           GM.xmlHttpRequest
// ==/UserScript==

(function() {
    'use strict';

    async function fetchText(url) {
        return new Promise((resolve, reject) => {
            GM_xmlhttpRequest({
                method: "GET",
                url: url,
                onload: response => resolve(response.responseText),
                onerror: () => reject(`Lỗi tải: ${url}`)
            });
        });
    }

    async function getChapterList() {
        const doc = new DOMParser().parseFromString(await fetchText(location.href), "text/html");
        return [...doc.querySelectorAll(".list-chapter li a")].map(a => ({
            title: a.textContent.trim(),
            url: a.href
        }));
    }

    async function fetchChapterContent(chapter) {
        const doc = new DOMParser().parseFromString(await fetchText(chapter.url), "text/html");
        const content = doc.querySelector(".chapter-c")?.innerHTML.replace(/<[^>]*>/g, '') || "[Lỗi tải nội dung]";
        return `\n\n${chapter.title}\n${"=".repeat(50)}\n${content}`;
    }

    async function downloadNovel() {
        alert("Bắt đầu tải truyện, vui lòng chờ...");
        const chapters = await getChapterList();
        const contents = await Promise.all(chapters.map(fetchChapterContent));
        
        const blob = new Blob([contents.join("\n")], { type: "text/plain" });
        const link = document.createElement("a");
        link.href = URL.createObjectURL(blob);
        link.download = document.title.replace(/\s+/g, "_") + ".txt";
        link.click();
    }

    const btn = document.createElement("button");
    btn.textContent = "📥 Tải Truyện";
    btn.style.cssText = "position:fixed;top:10px;right:10px;padding:10px;background:#ff5722;color:white;border:none;cursor:pointer;z-index:1000;";
    btn.onclick = downloadNovel;
    document.body.appendChild(btn);
})();