海角社区
// ==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(" <div id='myDiv'; style='right: 3px;width: 40px;height: 40px;font-size: 12px;border-radius:50%; bottom: 120px;background: #FF6666;color:#ffffff;overflow: hidden;z-index: 9999;position: fixed;padding:5px;text-align:center;'>打赏脚本</div>");
$("body").append(" <div id='dmyDiv'; style='right: 3px;width: 40px;height: 40px;font-size: 12px;border-radius:50%; bottom: 160px;background: #FF6666;color:#ffffff;overflow: hidden;z-index: 9999;position: fixed;padding:5px;text-align:center;'>下载</div>");
$("body").append(" <div id='jxmyDiv'; style='right: 3px;width: 40px;height: 40px;font-size: 12px;border-radius:50%; bottom: 200px;background: #FF6666;color:#ffffff;overflow: hidden;z-index: 9999;position: fixed;padding:5px;text-align:center;'>等待解析</div>");
$("body").append(" <div id='jxspmyDiv'; style='right: 3px;width: 40px;height: 40px;font-size: 12px;border-radius:50%; bottom: 240px;background: #FF6666;color:#ffffff;overflow: hidden;z-index: 9999;position: fixed;padding:5px;text-align:center;'>准备中</div>");
}
else {
$("body").append(" <div id='myDiv'; style='right: 3px;width: 50px;height: 50px;font-size: 16px;border-radius:50%; bottom: 120px;background: #FF6666;color:#ffffff;overflow: hidden;z-index: 9999;position: fixed;padding:5px;text-align:center;'>打赏脚本</div>");
$("body").append(" <div id='dmyDiv'; style='right: 3px;width: 50px;height: 50px;font-size: 16px;border-radius:50%; bottom: 170px;background: #FF6666;color:#ffffff;overflow: hidden;z-index: 9999;position: fixed;padding:5px;text-align:center;'>下载</div>");
$("body").append(" <div id='jxmyDiv'; style='right: 3px;width: 50px;height: 50px;font-size: 16px;border-radius:50%; bottom: 220px;background: #FF6666;color:#ffffff;overflow: hidden;z-index: 9999;position: fixed;padding:5px;text-align:center;'>等待解析</div>");
$("body").append(" <div id='jxspmyDiv'; style='right: 3px;width: 50px;height: 50px;font-size: 16px;border-radius:50%; bottom: 270px;background: #FF6666;color:#ffffff;overflow: hidden;z-index: 9999;position: fixed;padding:5px;text-align:center;'>准备中</div>");
}
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(`<img src="${atta.remoteUrl}" data-id="${atta.id}"/>`)
}
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 = `<video src="${v.remoteUrl}" data-id="${v.id}"/></video>`
}
let content = body.content.replace(/\[[图片视频]+\]?/, ``);
content = body.content.replace(/此处内容售价.*?您还没有购买,请购买后查看!/, ``);
content = '<html><head></head><body>' + content + '<br/>' + images + '<br/>' + video_urls + '<br/></body></html>';
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 = '<video id="video" controls autoplay width="100%"></video>'
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 = /<img src=\"https:\/\/[\w\.\/]+?\/images\/.*?\" data-id=\"(\d+)\".*?\/>/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(`(<img src=\")https:\/\/[\\w\.\/]+?\/images\/.*?\(" data-id=\"${id}\".*?\/>)`, '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(`<img src="${src}" data-id="${id}"/>`);
}
let selled_img = `[sell]` + img_elements.join() + `[/sell]`;
let ncontent = body.content.replace(/<span class=\"sell-btn\".*<\/span>/, 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;
}
}
)();