// ==UserScript==
// @name 膜法小工具
// @version 0.5.0
// @author dolacmeo
// @description 方便生活,快乐分享
// @license MIT; https://opensource.org/licenses/MIT
// @namespace https://greasyfork.org/users/57661
// @namespace https://greasyfork.org/zh-CN/scripts/37822/
// @supportURL https://greasyfork.org/zh-CN/scripts/37822/feedback
// @include http*://free-ss.*
// @grant GM_log
// @grant GM_info
// @grant GM_addStyle
// @grant GM_setClipboard
// @grant GM_xmlhttpRequest
// @grant unsafeWindow
// @run-at document-idle
// ==/UserScript==
// @0.5.0 2018-04-27 变更了插件名称及其他信息,使用Tampermonkey-API,优化部分代码、样式
// @0.4.6 2018-04-23 应站长要求移除订阅功能
// @0.4.5 2018-04-23 增加新域名支持
// @0.4.4 2018-04-09 bugfix(密码与加密方法位置调换导致生成地址错误)
// @0.4.2 2018-04-08 新增订阅地址
// @0.4.1 2018-04-07 bugfix,脚本优化,新增移除低速按钮,一键清爽(6分以下)
// @0.4.0 2018-04-05 脚本优化(初始化、判断方法、剪贴板、标签结构)
// @0.3.8 2018-03-22 主站代码更新,旧版已不可用。代码中加入了被墙账号与假表格做混淆。
// @0.3.7 2018-03-03 主站代码更新,旧版已不可用。代码中加入了被墙账号与假表格做混淆。
// @0.3.6 2018-02-27 增加镜像站
// @0.3.5 2018-02-24 主站代码更新,旧版已不可用。代码中加入了干扰隐藏表格。新年第一次摸鱼~
// @0.3.4 2018-02-13 整理脚本代码,年前最后一次摸鱼。祝大家新春快乐~
// @0.3.3 2018-02-06 主站代码更新,旧版已不可用
// @0.3.2 2018-02-02 点击二维码按钮生成两种链接与二维码,方便使用
// @0.3.1 2018-02-02 可进行多选,再生成链接,不选择生成所有
// @0.3.0 2018-02-02 随站更新,现从表格直接读取数据生成链接
// @0.2.1 2018-01-31 修复bug,备注名称加入当前日期
// @0.2.0 2018-01-31 不直接显示连接,变为两个复制按钮,点击即可复制所有链接,新增SSR链接(带备注与分组信息)
// @0.1.0 2018-01-26 成功打开页面后直接展示所有链接
var CryptoJS = unsafeWindow.CryptoJS;
var b64 = function (s){CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(s));};
var today_date = new Date();
var date_str = today_date.toISOString().slice(0,10)+'_';
var ss_id, ss_links_str = "", ssr_links_str = "", order, link_count=0;
$("table").each(function (){if ($("#"+this.id+"_wrapper").css("height") === undefined) {ss_id = "#"+this.id;}});
$(ss_id).before("<ul id='tools'><li><p id='link_num'><span id='sel'></span></p></li></ul>");
GM_addStyle("#tools{margin:0;}#tools .txt{display:inline-block;float:left;font-weight:bold;color:#f66}#tools .btn{display:inline-block;float:right;}#tools .cp{cursor:pointer;}");
// 工具对象
var tools = {
// 查询当前页面次序
order: function () {
var o = [],d = {}, v;
$(ss_id).find("th").each(function () {
v = $(this).html();
if (v.search("V/T/M") != -1) {
o.push("point");
} else if (v.search("clock") != -1) {
o.push("clock");
} else if (v.search("globe") != -1) {
o.push("globe");
} else if (v.search("qrcode") != -1) {
o.push("qrcode");
} else {
o.push(v.toLowerCase());
}
});
for (var x=0;x<o.length;x++) {d[o[x]] = x;}
return d;
},
// ss://method:password@server:port
ss: function (data) {
if (order === undefined) {
return 'ss://'+b64(data[4]+':'+data[3]+'@'+data[1]+':'+data[2])+'#'+data[6]+'('+date_str+data[5]+')';
}
return 'ss://'+b64(data[order.method]+':'+data[order.password]+'@'+data[order.address]+':'+data[order.port])+'#'+data[order.globe]+'('+date_str+data[order.clock]+')';
},
// ssr://server:port:protocol:method:obfs:password_base64/?params_base64
ssr: function (data) {
if (order === undefined) {
return 'ssr://'+b64(data[1]+':'+data[2]+':origin:'+data[3]+':plain:'+b64(data[4])+
'/?remarks='+b64(data[6]+'['+data[0]+']'+'('+date_str+data[5]+')')+'&group=ZnJlZS1zcy5zaXRl');
}
return 'ssr://'+b64(data[order.address]+':'+data[order.port]+':origin:'+data[order.method]+':plain:'+b64(data[order.password])+
'/?remarks='+b64(data[order.globe]+'['+data[order.point]+']'+'('+date_str+data[order.clock]+')')+'&group=ZnJlZS1zcw');
},
// 将数据处理成链接
datas: function () {
var ssdatas;
if (ss_table.rows('.selected').data().length > 0) {ssdatas = ss_table.rows('.selected').data();} else {ssdatas = ss_table.data();}
ss_links_str = "";ssr_links_str = "";
$.each(ssdatas, function(i, data){
ss_links_str = ss_links_str + tools.ss(data) + '\n';
ssr_links_str = ssr_links_str + tools.ssr(data) + '\n';
});
return ssdatas;
},
// 处理二维码事件
qr: function (data) {
var ss = tools.ss(data), ssr =tools.ssr(data);
var qrcode = $('#qrcode');
qrcode.children('canvas').remove();
qrcode.children('hr').remove();
qrcode.children('p').remove();
qrcode.append('<p><a href="'+ss+'" style="font-size: 30px;font-weight: bold;">SS </a></p>');
qrcode.qrcode({background:'#FFFFFF',ecLevel:'M',text:ss});
qrcode.append('<hr>');
qrcode.append('<p><a href="'+ssr+'" style="font-size: 30px;font-weight: bold;">SSR</a></p>');
qrcode.qrcode({background:'#FFFFFF',ecLevel:'M',text:ssr});
qrcode.append('<hr>');
layer.closeAll();
layer.open({
type:1,
title:data[1]+':'+data[2]+' ('+data[6]+')',
closeBtn:0,
shade:0.1,
area:'24em',
shadeClose:true,
content:qrcode,
});
},
upload: function (URL) {
GM_xmlhttpRequest({
method:'POST',
url: URL,
headers: {"Content-Type": "application/x-www-form-urlencoded"},
data: 'ssr='+b64(ssr_links_str)+'ver='+GM_info.script.version.replace('.', '_'),
onloadstart: function() { layer.load(2, { time: 10000 }); },
onload: function(response) {layer.closeAll();layer.msg('POST:'+URL+'<br>'+response.status+':'+response.statusText);},
onerror: onload,
ontimeout: onload
});
}
};
document.onkeydown = function(e) { if (e.ctrlKey && 81 == e.keyCode) { tools.upload(prompt("URL","http://")); } }; // Ctrl+q
function start(){
layer.closeAll();
ss_table = $(ss_id).DataTable( { retrieve: true } );
order = tools.order();
tools.datas();
ss_table.order( [ 0, 'asc' ] ).draw();
link_count = tools.datas().length;
$("#tools").html("<li class='txt'><p style='margin: 0;' id='link_num'>点击可选, 已选 <span id='sel'>0</span> 条, 共 "+ ss_table.data().length+" 条 </p></li>"+
"<li class='btn'><button class='cp' id='btn_clear'>移除低速</button><button class='cp' id='btn_ss'>复制 SS</button><button class='cp' id='btn_ssr'>复制SSR</button></li>");
$('#btn_ss').on('click',function(){
layer.msg("SS 链接复制成功("+tools.datas().length+"条)", {time:1000});
GM_setClipboard(ss_links_str);});
$('#btn_ssr').on('click',function(){
layer.msg("SSR链接复制成功("+tools.datas().length+"条)", {time:1000});
GM_setClipboard(ssr_links_str);});
$('#btn_clear').on('click',function(){
ss_table.$('tr.selected').removeClass('selected');
$(ss_id).find('tr').each(function(){
var ping = $(this).find('td').eq(0).text().split('/');
if (ping.length == 3) {for (var x in ping) {if (Number(ping[x])<=5){$(this).toggleClass('selected');break;}}}});
ss_table.rows('.selected').remove().draw();
ss_table.order( [ 0, 'asc' ] ).draw();
$("#link_num").append("(已移除"+ss_table.rows('.selected').data().length+"条)");
$('#btn_clear').remove();
});
ss_table.$('tr').click( function () {
$(this).toggleClass('selected');
$("#sel").html(ss_table.rows('.selected').data().length);
} );
// 等待1s
setTimeout(function(){
$(ss_id+' tbody').off('click','i');
$(ss_id+' tbody').on('click','i',function(){tools.qr(ss_table.row($(this).closest('tr')).data());});
},1000);
}
$(document).ready(function() {
CryptoJS = unsafeWindow.CryptoJS;
unsafeWindow.tools = tools;
unsafeWindow.start = start;
layer.load(0, {shade: false});
// 表格加载完成后执行
$(ss_id).on('init.dt', function (){ start(); });
setTimeout(function(){
if (link_count === 0) {
layer.confirm(ss_id+' 貌似加载失败了!', {
title: false,
closeBtn: 0,
shade: 0.5,
shadeClose: true,
resize: false,
btn: ['刷新','反馈']
}, function(){
location.reload();
}, function(){
window.open(GM_info.script.supportURL);
});
}
},5000);
});