您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Download folders from Minehut's file manager without having to pay
当前为
// ==UserScript== // @name Minehut folder download // @namespace Violentmonkey Scripts // @match *://app.minehut.com/* // @grant none // @version 1.0.2 // @author - // @require https://greasyfork.org/scripts/441873-zip-js/code/zipjs.js?version=1030820 // @description Download folders from Minehut's file manager without having to pay // @license MIT // ==/UserScript== (() => { let downloadFolder = (async (progressFn) => { function getCookieValue(cookieName) { let name = cookieName + "="; let decodedCookie = decodeURIComponent(document.cookie); let cookieArray = decodedCookie.split(';'); for (let i = 0; i < cookieArray.length; i++) { let cookie = cookieArray[i]; while (cookie.charAt(0) === ' ') { cookie = cookie.substring(1); } if (cookie.indexOf(name) === 0) { return cookie.substring(name.length, cookie.length); } } return ""; } let accessToken = getCookieValue('access_token_prd'); let slgToken = localStorage.getItem('slg_user_token'); let minehutSession = localStorage.getItem('minehut_session_id'); let activeServerData = localStorage.getItem('activeServer'); if (!accessToken || !slgToken || !minehutSession || !activeServerData) { alert('You must select a server to use this script°'); return; } let activeServer = JSON.parse(activeServerData); let sideCarBase = `https://${activeServer._id}.manager.minehut.com`; let headers = { 'Content-Type': 'application/json', Authorization: `Bearer ${accessToken}`, 'x-profile-id': slgToken, 'x-session-id': minehutSession }; async function apiRequest(url, method = 'GET', body = undefined) { return await fetch('https://api.minehut.com' + url, { method: method, headers: headers, body: body }); } async function sideCarRequest(url, method = 'GET', body = undefined) { return await fetch(sideCarBase + url, { method: method, headers: headers, body: body }); } async function list(path) { let response = await apiRequest(`/file/${activeServer._id}/list/${path}`); return await response.json(); } async function download(path) { let response = await sideCarRequest(`/file/download?files=${JSON.stringify([path])}`); return await response.blob(); } async function listRecursive(path) { let files = await list(path); let fileList = []; for (let file of files.files) { if (file.directory) { fileList = fileList.concat(await listRecursive(`${path}/${file.name}`)); } else if (!file.blocked) { fileList.push(`${path}/${file.name}`); } } return fileList; } function downloadBlob(blob, fileName) { let a = document.createElement('a'); a.href = URL.createObjectURL(blob); a.download = fileName; a.click(); URL.revokeObjectURL(a.href); } async function createZip(files, progressFn) { const zipFileWriter = new zip.BlobWriter(); const zipWriter = new zip.ZipWriter(zipFileWriter); let i = 1; for (let path of files) { progressFn(`Downloading (${i}/${files.length}) ...`); let data = await download(path); await zipWriter.add(path.replace(/^\/+/, ''), new zip.BlobReader(data)); i++; } await zipWriter.close(); return await zipFileWriter.getData(); } let folderName = prompt('Enter the full path of the folder to download (e.g. world or plugins/WorldEdit)'); if (!folderName) { alert('You must enter a folder name'); return; } if (!folderName.startsWith('/')) { folderName = '/' + folderName; } if (folderName.endsWith('/')) { folderName = folderName.slice(0, -1); } progressFn('Scanning folder...'); let contents = await listRecursive(folderName); let result = await createZip(contents, progressFn); let name = folderName.split('/').pop(); if (name === '') { name = 'root'; } downloadBlob(result, name + '.zip'); }); let activeDownload = false; let button = document.createElement('button'); button.className = 'themed___PBHap primary-theme___q1d2u no-border___6w-uL themed-control___KmjCR no-underline___h2l-L page-control___rxMPx'; button.textContent = 'Download Folder'; button.style.position = 'fixed'; button.style.zIndex = '10000'; button.style.top = '5px'; button.style.right = '5px'; button.style.display = 'none'; button.onclick = async () => { if (activeDownload) { return; } activeDownload = true; button.textContent = 'Starting...'; try { await downloadFolder(progress => { button.textContent = progress; }); } catch (e) { alert('An error occurred while downloading the folder: ' + e.message); } activeDownload = false; button.textContent = 'Download Folder'; }; document.body.appendChild(button); setInterval(() => { if (window.location.pathname.startsWith('/dashboard/files')) { button.style.display = 'block'; } else { button.style.display = 'none'; } }, 250); })();