// ==UserScript== // @name 海角社区 // @namespace http://tampermonkey.net/ // @version 11.1 // @description 目前可以用,可以查看金币钻石视频 // @author xigua0012 // @license MIT // @match https://*/post/details* // @icon https://hjbc30.top/images/common/project/favicon.ico // @run-at document-start // @grant unsafeWindow // @grant GM_download // @grant GM_openInTab // @grant GM_xmlhttpRequest // @grant GM_xmlhttpRequest // @connect * // @require https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js // ==/UserScript== function pwd() { let word = '' let a = '48/46/116/115' let b = a.split('/') for (let c in b) { let d = parseInt(b[c]) let e = String.fromCharCode(d) word = word + e } return word } function clearContainer(container) { if (container.hasChildNodes()) { container.innerHTML = ""; container.style.border = ""; } } function getContainer() { const existContainer = document.querySelector(".big-img-container-c"); if (!existContainer) { const container = document.createElement("div"); container.className = "big-img-container-c"; container.style.position = "fixed"; container.style.top = 0; container.style.left = 0; container.style.zIndex = 999999; container.onclick = function () { clearContainer(container); }; document.querySelector("html").appendChild(container); return container; } return existContainer; } (function () { 'use strict'; /* if (location.host === "tools.thatwind.com" || location.host === "localhost:3000") { alert("sdfdsf") } */ let newurl = "" let downloadurl = "" let fasongtext = "" let pidtext = "" let posttext="" let video_time_length="" let isphone = IsPhone() let isfirst=true let isgettrue = false if (isphone) { $("body").append("
打赏脚本
"); $("body").append("
下载
"); $("body").append("
等待解析
"); $("body").append("
准备中
"); } else { $("body").append("
打赏脚本
"); $("body").append("
下载
"); $("body").append("
等待解析
"); $("body").append("
准备中
"); } var jxspmyDiv = document.getElementById("jxspmyDiv"); // 获取到id为"myDiv"的div元素 jxspmyDiv.addEventListener('click', function (e) { if (jxspmyDiv.innerHTML == "关闭视频" || jxspmyDiv.innerHTML == "播放视频") { console.log("当前=" + jxspmyDiv.innerHTML); showplay() return } if (isgettrue == false) { if (isfirst == false) { alert("请勿重复解析") return } isfirst=false jxspmyDiv.innerHTML = "解析中" fasong(fasongtext+ "----" +posttext+ "----" +video_time_length+ "----" +pidtext) } else { play(urlbf) } /* if (isfirst==false) { alert("请勿重复解析") return } isfirst=false if (fasongtext.indexOf("IV=") === -1) { jxspmyDiv.innerHTML = "解析失败" alert("解析失败,请刷新重试") return } jxspmyDiv.innerHTML = "解析中" fasong(fasongtext+ "----" +posttext+ "----" +video_time_length+ "----" +pidtext) */ }); var jxmyDiv = document.getElementById("jxmyDiv"); // 获取到id为"myDiv"的div元素 jxmyDiv.addEventListener('click', function (e) { const textarea = document.createElement('textarea'); textarea.value = downloadurl; document.body.appendChild(textarea); textarea.select(); document.execCommand('copy'); document.body.removeChild(textarea); console.log("downloadurl=" + downloadurl); alert("复制下载链接成功"); //jxmyDiv.innerHTML = "fff" }); var dmyDiv = document.getElementById("dmyDiv"); // 获取到id为"myDiv"的div元素 dmyDiv.addEventListener('click', function (e) { //alert("你点击了DIV!"); // 当点击该div时会触发此函数并显示提示信息 var currentUrl = window.location.href; // 输出当前网址 let url = "https://tools.thatwind.com/tool/m3u8downloader#m3u8=" let url2 = "&referer=" + currentUrl + "&filename=%E6%B5%B7%E8%A7%92%E7%A4%BE%E5%8C%BA" let url3 = url + newurl + url2 GM_openInTab(url3, { active: true }); console.log(url3); //window.location.href = url; //window.open(url, "_blank"); }); var myDiv = document.getElementById("myDiv"); // 获取到id为"myDiv"的div元素 myDiv.addEventListener('click', function (e) { //alert("你点击了DIV!"); // 当点击该div时会触发此函数并显示提示信息 const container = getContainer(); const halfWidth = window.innerWidth / 2; const halfHeight = window.innerHeight / 2; clearContainer(container); if (isphone) { const containerX = halfWidth - 160; const containerY = halfHeight - 140; container.style.left = `${containerX}px`; container.style.top = `${containerY}px`; container.style.border = "1px solid #000"; const bigImg = e.target.cloneNode(); container.appendChild(bigImg); // 创建img标签并设置src属性为要显示的图片链接 var img = document.createElement('img'); img.setAttribute("src", "https://pic.imgdb.cn/item/661fc80f0ea9cb140391c2cb.png"); } else { const containerX = halfWidth - 200; const containerY = halfHeight - 140; container.style.left = `${containerX}px`; container.style.top = `${containerY}px`; container.style.border = "1px solid #000"; const bigImg = e.target.cloneNode(); container.appendChild(bigImg); // 创建img标签并设置src属性为要显示的图片链接 var img = document.createElement('img'); img.setAttribute("src", "https://pic.imgdb.cn/item/661fc6920ea9cb14038177db.png"); } var bodyElement = document.getElementsByClassName('big-img-container-c')[0]; bodyElement.appendChild(img); }); function decode(s) { return atob(atob(atob(s))); } function encode(s) { return btoa(btoa(btoa(s))); } function jencode(s) { return encode(JSON.stringify(s, `utf-8`)); } function get_real_m3u8_path(url) { var request = new XMLHttpRequest(); request.open('GET', url, false); request.send(null); if (request.status !== 200) { console.log(`解析失败!`); return url; } let ts_path = request.responseText.split('\n')[6]; let id = ts_path.match(/([\w_]+_?)[\d]+.ts/)[1]; let rurl = url.replace(/([\w_]+).m3u8/, `${id}.m3u8`); return rurl; } function runAsync(url, send_type, data_ry) { console.log("请求开始"); var p = new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: send_type, url: url, headers: { "Content-Type": "application/x-www-form-urlencoded;charset=utf-8" }, data: data_ry, onload: function (response) { console.log("请求成功"); //console.log(response.responseText); resolve(response.responseText); }, onerror: function (response) { console.log("请求失败"); jxspmyDiv.innerHTML = "刷新重试" alert("解析失败,检查脚本是否有更新") reject("请求失败"); } }); }) //console.log("p="+p); return p; } function get_user_dict(host, id) { var url = `https://${host}.com/api/topic/node/topics?page=1&userId=${id}&type=0`; var request = new XMLHttpRequest(); request.open('GET', url, false); request.send(null); if (request.status !== 200) { console.log(`用户信息解析失败!`); return {}; } let p = JSON.parse(request.responseText, `utf-8`).data; p = JSON.parse(decode(p), `utf-8`); let total = p.page.total; let uid = `[banned]`; if (`results` in p) { uid = p.results[0].user.nickname + ` ` + uid; } return { 'isFavorite': false, 'likeCount': 12, 'user': { 'id': parseInt(id), 'nickname': uid, 'avatar': '29', 'description': `hj community`, 'topicCount': total, 'videoCount': 0, 'commentCount': 303, 'fansCount': 57, 'favoriteCount': 39, 'status': 0, 'sex': 1, 'vip': 0, 'vipExpiresTime': '0001-01-01 00:00:00', 'certified': false, 'certVideo': false, 'certProfessor': false, 'famous': false, 'forbidden': false, 'tags': null, 'role': 0, 'popularity': 10, 'diamondConsume': 0, 'title': { 'id': 0, 'name': '', 'consume': 0, 'consumeEnd': 0, 'icon': '' }, 'friendStatus': false, 'voiceStatus': false, 'videoStatus': false, 'voiceMoneyType': 0, 'voiceAmount': 0, 'videoMoneyType': 0, 'videoAmount': 0, 'depositMoney': 0 } } } function destory() { document.getElementsByClassName('preview-title')[0].remove() } function remove_vip(body) { body.node.vipLimit = 0; let attachments = body.attachments; let image_urls = []; let video_urls = ``; let has_video = -1; for (var i = 0; i < attachments.length; i++) { var atta = attachments[i]; if (atta.category === 'images') { image_urls.push(``) } if (atta.category === 'video') { has_video = i; } } let images = image_urls.join(); if (has_video >= 0) { let [nbody, v] = replace_m3u8(body, has_video); body = nbody; video_urls = `` } let content = body.content.replace(/\[[图片视频]+\]?/, ``); content = body.content.replace(/此处内容售价.*?您还没有购买,请购买后查看!/, ``); content = '' + content + '
' + images + '
' + video_urls + '
'; body.content = content; return body; } async function play原(url) { console.log("url=" + url) let isphone = IsPhone() let playpos = '' if (isphone) { //document.querySelector('.sell-btn').remove() playpos = '.sell-btn' let videoInfo = document.querySelector(playpos) videoInfo.innerHTML = '' var video = document.getElementById('video'); var hls = new Hls(); // bind them together console.log("11"); hls.attachMedia(video); hls.on(Hls.Events.MEDIA_ATTACHED, function () { console.log("video and hls.js are now bound together !"); hls.loadSource(url); hls.on(Hls.Events.MANIFEST_PARSED, function (event, data) { console.log("manifest loaded, found " + data.levels.length + " quality level"); }); }); } else { playpos = '.sell-btn' window.dp = new DPlayer({ element: document.querySelector(playpos), autoplay: false, theme: '#FADFA3', loop: true, lang: 'zh', screenshot: true, hotkey: true, preload: 'auto', video: { url: url, type: 'hls' } }) } } function hasClass(element, className) { return element.classList.contains(className); } function 文本_取右边(str, char) { const index = str.indexOf(char); if (index != -1) { return str.substring(index + char.length, index + str.length); } return ""; // 如果字符不存在,返回原字符串 } async function replace_m3u8(body, has_video) { jxspmyDiv.innerHTML = "准备中" jxmyDiv.innerHTML = " 等待解析" let attachments = body.attachments; let vidx = has_video; if (vidx < 0) { return [body, undefined]; } if (body.sale === null || body.sale.money_type == 0) { return [body, attachments[vidx]]; } let url = attachments[vidx].remoteUrl; //console.log("url", url) var currentUrl = window.location.href; //console.log("url=", currentUrl) video_time_length = attachments[vidx].video_time_length; let index = currentUrl.indexOf("/post/details"); // 找到逗号的索引 let leftPart = currentUrl.substring(0, index); // 截取左边的字符串 console.log(leftPart); // 输出: Hello var currentUrl = window.location.href; index = currentUrl.indexOf("pid="); // 找到逗号的索引 pidtext = currentUrl.substring(index+4,currentUrl.length); // 截取左边的字符串 //console.log(pidtext); let topicId=body.topicId; //console.log("pidtext=", pidtext) //console.log(topicId,pidtext); if (topicId!=pidtext) { console.log(topicId,pidtext); // 输出: Hello jxspmyDiv.innerHTML = "解析失败" alert("准备失败,请刷新重试") return } //console.log("url", leftPart + url) let res = await fetch(leftPart + url, { method: 'get', }) let m3u8Text = await res.text() //console.log("m3u8Text=", m3u8Text) let muid=attachments[vidx].id; //console.log('muid=', muid); if (m3u8Text.indexOf(muid) === -1) { jxspmyDiv.innerHTML = "解析失败" alert("准备失败,请刷新重试") return } fasongtext = "hhhjjj" + "----" + m3u8Text jxspmyDiv.innerHTML = "点击解析" } function fasong(textsent) { runAsync("http://ip.haijiao007.asia/get863", "POST", textsent).then((result) => { return result; }).then(function (result) { if (result.indexOf("false") > -1 && result.indexOf("****") === -1) { jxspmyDiv.innerHTML = "解析失败" alert("解析失败,请刷新重试") return } else { if (result.indexOf("IV=") === -1) { jxspmyDiv.innerHTML = "解析失败" alert("解析失败,请刷新重试") return } jxspmyDiv.innerHTML = "解析成功" setTimeout(function () { jxmyDiv.innerHTML = " 复制链接" }, 2000); let splittedText = result.split("****"); // 用空格分割文本 downloadurl = splittedText[1] alert(splittedText[0]) //alert("视频解析成功!\n 先感谢各位老板的打赏,用的好的话,希望各位老板多多打赏,使用人数越来越多,希望打赏可以跟上人数增长!!!我每天努力给大家更新,现在脚本已经优化很多,效果已经好多了。最后还是感谢打赏的各位老板!!!\n后续打算开放外链,可以使用idm下载,这个下载视频很快,也很方便!!\n如果脚本无效,请更新脚本!\n本脚本发布在油猴,别的途径均为倒卖!!!\n 支持油猴脚本的浏览器有猴狐浏览器(推荐)、M浏览器、via浏览器、X浏览器、雨见浏览器。不能用的话可以一个个调试过去"); var blob = new Blob([splittedText[2]], { type: 'text/plain' }); newurl = URL.createObjectURL(blob) console.log("newurl", newurl) //play(newurl) isgettrue = true setTimeout(async () => { await play(newurl) }, 1000) } }); } function showplay() { if (isphone) { let video = document.querySelector('video'); if (jxspmyDiv.innerHTML == "关闭视频") { console.log("播放视频"); jxspmyDiv.innerHTML = "播放视频" video.pause(); video.style.display = 'none'; } else { console.log("关闭视频"); //video.remove(); video.style.display = 'block'; jxspmyDiv.innerHTML = "关闭视频" } } } async function play(url) { let isphone = IsPhone() let playpos = '' if (isphone) { let video = document.querySelector('video'); console.log("11",window.innerWidth); if (!video) { console.log("video不存在"); jxspmyDiv.innerHTML = "关闭视频" video = document.createElement('video'); video.style.position = 'fixed'; video.style.top = '10%'; //video.style.height = '75%'; video.style.left = '15%'; video.style.width = '70%'; //video.style.height = '70%'; video.style.zIndex = '9999'; video.controls = true; video.src = url; document.body.appendChild(video); } else { console.log("video存在"); video.pause(); //video.remove(); video.style.display = 'none'; jxspmyDiv.innerHTML = "播放视频" } var hls = new Hls(); // bind them together //console.log("11"); hls.attachMedia(video); hls.on(Hls.Events.MEDIA_ATTACHED, function () { //console.log("video and hls.js are now bound together !"); hls.loadSource(url); hls.on(Hls.Events.MANIFEST_PARSED, function (event, data) { //console.log("manifest loaded, found " + data.levels.length + " quality level"); }); }); } else { playpos = '.sell-btn' window.dp = new DPlayer({ element: document.querySelector(playpos), autoplay: false, theme: '#FADFA3', loop: true, lang: 'zh', screenshot: true, hotkey: true, preload: 'auto', video: { url: url, type: 'hls' } }) } } function replace_exist_img(body) { let content = body.content; let attachments = body.attachments; let all_img = {}; let has_video = -1; for (var i = 0; i < attachments.length; i++) { var atta = attachments[i]; if (atta.category === 'images') { all_img[atta.id] = atta.remoteUrl; } if (atta.category === 'video') { has_video = i; return [body, undefined, has_video]; } } let re_img = //g; for (let e of content.matchAll(re_img)) { let id = parseInt(e[1]); if (id in all_img) { // let nsrc = all_img[id]; // let src = new RegExp(`()`, 'g'); // content = content.replace(src, `$1${nsrc}$2`); delete all_img[id]; } } body.content = content; return [body, all_img, has_video]; } function modify_data(data) { let body = JSON.parse(decode(data)); //console.log(body) if (body.node.vipLimit != 0) { body = remove_vip(body); return jencode(body); } let [nbody, rest_img, has_video] = replace_exist_img(body); body = nbody; // 已购买的帖子 if (body.content.includes(`[/sell]`)) { return jencode(body); } if ('sale' in body && body.sale !== null) { body.sale.is_buy = true; body.sale.buy_index = parseInt(Math.random() * (5000 - 1000 + 1) + 1000, 10); } if (has_video >= 0) { posttext=decode(data) let [nbody, v] = replace_m3u8(body, has_video); return jencode(nbody); } let img_elements = [] for (const [id, src] of Object.entries(rest_img)) { img_elements.push(``); } let selled_img = `[sell]` + img_elements.join() + `[/sell]`; let ncontent = body.content.replace(//, selled_img); body.content = ncontent; return jencode(body); } function modify_user(data, host, id) { if (data.errorCode === 0) { return data; } data.isEncrypted = true; data.errorCode = 0; data.success = true; data.message = ""; let udict = get_user_dict(host, id); data.data = jencode(udict) return data } function IsPhone() { var info = navigator.userAgent; if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) { // 手机端代码 console.log("isPhone=" + true) return true; } else { // 电脑端代码 console.log("isPhone=" + false) return false; } //var isPhone = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/mobile/i.test(info); } const originOpen = XMLHttpRequest.prototype.open; const re_topic = /\/api\/topic\/\d+/; const re_user = /\/api\/user\/info\/\d+/; XMLHttpRequest.prototype.open = function (_, url) { // 拦截topic if (re_topic.test(url)) { const xhr = this; const getter = Object.getOwnPropertyDescriptor( XMLHttpRequest.prototype, "response" ).get; Object.defineProperty(xhr, "responseText", { get: () => { let result = getter.call(xhr); try { let res = JSON.parse(result, `utf-8`); // 这里修改data res.data = modify_data(res.data) return JSON.stringify(res, `utf-8`); } catch (e) { console.log('发生异常! 解析失败!'); console.log(e); return result; } }, }); } else if (re_user.test(url)) { const xhr = this; const getter = Object.getOwnPropertyDescriptor( XMLHttpRequest.prototype, "response" ).get; Object.defineProperty(xhr, "responseText", { get: () => { let result = getter.call(xhr); try { let res = JSON.parse(result, `utf-8`); let furl = xhr.responseURL; let r = furl.match(/\W*(\w+)\.com\/api\/user\/info\/(\d+)/); // 这里修改data let data = modify_user(res, r[1], r[2]); return JSON.stringify(data, `utf-8`); } catch (e) { console.log('发生异常! 解析失败!'); console.log(e); return result; } }, }); } originOpen.apply(this, arguments); }; let clicked_flag = false; document.addEventListener("DOMNodeInserted", function (event) { if (!clicked_flag) { for (const element of document.getElementsByClassName('el-message-box')) { if (element.innerText.indexOf('令牌已过期') > -1) { clicked_flag = true; let e = element.querySelector("div.el-message-box__header > button"); setTimeout((e) => { e.click(); }, 100, e); break; } } } if (event.relatedNode.getAttribute('id') === 'tidio-chat') { var eles = document.getElementsByTagName('*'); for (var i = 0; i < eles.length; i++) { eles[i].style.userSelect = 'text'; } } }, false); })(); (function () { 'use strict'; const mgmapi = { addStyle(s) { let style = document.createElement("style"); style.innerHTML = s; document.documentElement.appendChild(style); }, xmlHttpRequest(details) { return ((typeof GM_xmlhttpRequest === "function") ? GM_xmlhttpRequest : GM.xmlHttpRequest)(details); }, }; if (location.host === "tools.thatwind.com" || location.host === "localhost:3000") { mgmapi.addStyle("#userscript-tip{display:none !important;}"); console.log("host-----------------" + location.host); //alert("sdfsdf") // 对请求做代理 const _fetch = unsafeWindow.fetch; unsafeWindow.fetch = async function (...args) { try { let response = await _fetch(...args); if (response.status !== 200) throw new Error(response.status); return response; } catch (e) { // 失败请求使用代理 if (args.length == 1) { console.log(`请求代理:${args[0]}`); return await new Promise((resolve, reject) => { let referer = new URLSearchParams(location.hash.slice(1)).get("referer"); let headers = {}; if (referer) { referer = new URL(referer); headers = { "origin": referer.origin, "referer": referer.href }; } mgmapi.xmlHttpRequest({ method: "GET", url: args[0], responseType: 'arraybuffer', headers, onload(r) { resolve({ status: r.status, headers: new Headers(r.responseHeaders.split("\n").filter(n => n).map(s => s.split(/:\s*/)).reduce((all, [a, b]) => { all[a] = b; return all; }, {})), async text() { return r.responseText; }, async arrayBuffer() { return r.response; } }); }, onerror() { reject(new Error()); } }); }); } else { throw e; } } } return; } } )();