Greasy Fork

Greasy Fork is available in English.

下载L4D2创意工坊文件

Download L4D2 workshop file.

当前为 2023-12-15 提交的版本,查看 最新版本

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         下载L4D2创意工坊文件
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  Download L4D2 workshop file.
// @author       TEAEGGY
// @match        https://steamcommunity.com/sharedfiles/filedetails/*
// @connect      steamworkshop.download
// @icon         https://media.st.dl.eccdnx.com/steamcommunity/public/images/apps/550/7d5a243f9500d2f8467312822f8af2a2928777ed.jpg
// @grant        GM_xmlhttpRequest
// @grant        GM_download
// @grant        GM_addStyle
// ==/UserScript==

(function() {
    'use strict';
    const is550 = document.querySelector("div.apphub_HomeHeaderContent > div.apphub_HeaderTop.workshop > div.apphub_OtherSiteInfo.responsive_hidden > a").href.substring(35, 39);
    if (is550 != "550?") {
        return;
    }

    let css = `
        .topbox {
            display: flex;
            flex-direction: row;
            justify-content: space-between;
            align-items: center;
            position: fixed;
            z-index: 9999;
            top: 30px;
            right: 10px;
        }

        .itembox {
            display: flex;
            flex-direction: row;
            justify-content: center;
            align-items: center;
            margin: 10px;
            writing-mode: horizontal-tb;
        }

        .button {
            padding: 10px 20px;
            border: none;
            text-align: center;
            text-decoration: none;
            color: white;
            font-size: 16px;
            cursor: pointer;
        }

        .button:hover {
            transform: scale(1.05);
        }

        .button:active {
            transform: scale(0.95);
        }

        .download_on {
            background: #718e05;
            pointer-events: auto;
        }

        .download_off {
            background: #1f3043;
            pointer-events: none;
        }

        .cancel_on {
            background: #c73809;
            pointer-events: auto;
        }

        .cancel_off {
            background: #16212e;
            pointer-events: none;
        }
    `
    GM_addStyle(css);
    //获取URL请求参数
    function getQueryString(url_string, name) {
        const url = new URL(url_string);
        return url.searchParams.get(name);
    }
    //获取下载信息
    function waitForLink(url_string) {
        return new Promise((resolve, reject) => {
            GM_xmlhttpRequest({
                method:"GET",
                url:"http://steamworkshop.download/download/view/" + getQueryString(url_string, 'id'),
                onload:(e) => {
                    const parser = new DOMParser();
                    const doc = parser.parseFromString(e.response, 'text/html');
                    const download_name = doc.querySelector('#wrapper > div.width2 > div > table > tbody > tr > td > b > a').innerHTML.substring(10);
                    const download_link = doc.querySelector('#wrapper > div.width2 > div > table > tbody > tr > td > b > a').href;
                    resolve({
                        name:download_name,
                        link:download_link
                    });
                }
            })
        });
    }
    //创建按钮
    function createTopBtn() {
        const container = document.createElement('div');
        const download = document.createElement('button');
        const cancel = document.createElement('button');
        container.className = "topbox";

        download.className = "button download_off";
        download.innerHTML = "wait...";

        cancel.className = "button";
        cancel.className = "button cancel_off";
        cancel.innerHTML = "X";
        document.body.append(container);
        container.appendChild(download);
        container.appendChild(cancel);
        return {
            download:download,
            cancel:cancel
        }
    }

    function createItemBtn(dom) {
        const container = document.createElement('div');
        const download = document.createElement('button');
        const cancel = document.createElement('button');
        container.className = "itembox";

        download.className = "button download_off";
        download.innerHTML = "wait...";

        cancel.className = "button";
        cancel.className = "button cancel_off";
        cancel.innerHTML = "X";
        dom.append(container);
        container.appendChild(download);
        container.appendChild(cancel);
        return {
            download:download,
            cancel:cancel
        }
    }

    async function main() {
        const btn = createTopBtn();
        const download = await waitForLink(window.location.href);
        btn.download.className = "button download_on";
        btn.download.innerHTML = "download";

        btn.download.addEventListener('click', () => {
            btn.download.innerHTML = "downloading...";
            btn.download.className = "button download_off";
            var dw = GM_download({
                url: download.link,
                name: download.name + ".vpk", //Format: ItemTitle.vpk
                saveAs: false,
                onerror: (info) => {
                    if (info.error === "not_whitelisted") {
                        alert("请在Tampermonkey®设置页面添加'.vpk'的白名单!(可以前往脚本发布页面查看教程)");
                        btn.cancel.className = "button cancel_off";
                    }
                    else if (info.error === "aborted") {
                        alert("下载已取消");
                        btn.cancel.className = "button cancel_off";
                    }
                    else {
                        alert(info.error);
                        btn.cancel.className = "button cancel_off";
                    }
                    btn.download.innerHTML = "reload";
                    btn.download.className = "button download_on";
                },
                onprogress: (details) => {
                    btn.download.innerHTML = (details.loaded / details.total * 100).toFixed(2) + "%";
                },
                ontimeout: () => {
                    alert("下载超时,请重新尝试!");
                },
                onload: () => {
                    btn.download.innerHTML = "reload";
                    btn.download.className = "button download_on";
                    btn.cancel.className = "button cancel_off";
                }
            });
            btn.cancel.className = "button cancel_on";
            btn.cancel.addEventListener('click', () => {
                dw.abort();
            });
        })
    }

    async function collection_main() {
        const items = document.querySelectorAll('.collectionItem');
        items.forEach(async (e) => {
            console.log(e.querySelector('.collectionItemDetails > a'));
            const btn = createItemBtn(e);
            const download = await waitForLink(e.querySelector('.collectionItemDetails > a').href);
            btn.download.className = "button download_on";
            btn.download.innerHTML = "download";
            btn.download.addEventListener('click', () => {
                btn.download.innerHTML = "downloading...";
                btn.download.className = "button download_off";
                var dw = GM_download({
                    url: download.link,
                    name: download.name + ".vpk", //Format: ItemTitle.vpk
                    saveAs: false,
                    onerror: (info) => {
                        if (info.error === "not_whitelisted") {
                            alert("请在Tampermonkey®设置页面添加'.vpk'的白名单!");
                            btn.cancel.className = "button cancel_off";
                        }
                        else if (info.error === "aborted") {
                            alert("下载已取消");
                            btn.cancel.className = "button cancel_off";
                        }
                        else {
                            alert(info.error);
                            btn.cancel.className = "button cancel_off";
                        }
                        btn.download.innerHTML = "reload";
                        btn.download.className = "button download_on";
                    },
                    onprogress: (details) => {
                        btn.download.innerHTML = (details.loaded / details.total * 100).toFixed(2) + "%";
                    },
                    ontimeout: () => {
                        alert("下载超时,请重新尝试!");
                    },
                    onload: () => {
                        btn.download.innerHTML = "reload";
                        btn.download.className = "button download_on";
                        btn.cancel.className = "button cancel_off";
                    }
                });
                btn.cancel.className = "button cancel_on";
                btn.cancel.addEventListener('click', () => {
                    dw.abort();
                });
            })

            //const download_link = await waitForLink();
            //btn.download.className = "button download_on";
            //btn.download.innerHTML = "download";
        })
    }

    let isCollection = document.querySelector('.collectionChildren');
    if (isCollection) {
        collection_main();
    }
    else {
        main();
    }

})();