膜法小工具

方便生活,快乐分享

As of 2018-05-04. See the latest version.

// ==UserScript==
// @name         膜法小工具
// @version      0.5.4
// @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
// @require      https://cdn.jsdelivr.net/npm/js-base64@2.4.3/base64.min.js
// @resource     country_code https://gist.githubusercontent.com/dolaCmeo/f1810f8ceddf25880c6ae14e8dbc23d5/raw/cd3ab8280a2e6cb4decf3bab705d759e7c98deab/country_code.json
// @include      http*://free-ss.*
// @grant        GM_log
// @grant        GM_info
// @grant        GM_addStyle
// @grant        GM_setClipboard
// @grant        GM_getResourceText
// @grant        GM_xmlhttpRequest
// @grant        unsafeWindow
// @run-at       document-idle
// ==/UserScript==
// @0.5.4 2018-05-04   优化页面样式,中文化区域选择
// @0.5.3 2018-05-03   跟随主站更新,解决因更新出现的bug
// @0.5.2 2018-05-02   优化页面样式,新增区域快速选择
// @0.5.1 2018-04-27   问题修复
// @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 enb64 = Base64.encodeURI, deb64 = Base64.decode;
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, areas=[], xyz="http://"+deb64("c3NyLjEyMzQ1NjYueHl6");
var country_code = JSON.parse(""+GM_getResourceText('country_code'));
$("table").each(function (){if ($("#"+this.id+"_wrapper").css("height") === undefined) {ss_id = "#"+this.id;}});
$(ss_id).before("<ul id='tools'></ul>");
GM_addStyle("div.container{max-width: 910px;}"+
            "#tools {margin:0;padding-left:10px;} #tools p{margin:0;height:23px;} #tools button{cursor:pointer; margin-left:3px;}"+
            "h2 small{font-weight:bold;color:#f66;font-size:10px;}"+
            "#tools .txt{display:inline-block;float:left;font-weight:bold;color:#f66;}"+
            "#tools .btn{display:inline-block;float:right;}"+
            "#tools .btn small{color:#e91e63;font-weight: bold;}"+
            "#qrcode p a{font-size: 30px;font-weight: bold;}"+
            "#ss_area {margin-left:3px;border-width:2px;padding:1px 6px;float:right;}");

// 工具对象
var tools = {
    // 查询当前页面次序
    order: function () {
        var o = [],d = {}, v;
        $(ss_id).find("th").each(function () {
            v = $(this).html();
            if (v.search("V/T/U/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;
    },
    area: function() {
        var ssdatas = ss_table.data(), column = 6, l=[];
        if (order != undefined) {
            column = order.globe;
        }
        $.each(ssdatas, function(i, data){
            if ($.inArray(data[column], l) == -1) {
                if (data[column][0] != '*'){
                    l.push(data[column]);
                }
            }
        });
        areas = l;
        return l;
    },
    // ss://method:password@server:port
    ss: function (data) {
        if (order === undefined) {
            return 'ss://'+enb64(data[4]+':'+data[3]+'@'+data[1]+':'+data[2])+'#'+data[6]+'('+date_str+data[5]+')';
        }
        return 'ss://'+enb64(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://'+enb64(data[1]+':'+data[2]+':origin:'+data[3]+':plain:'+enb64(data[4])+
                                  '/?remarks='+enb64(data[6]+'['+data[0]+']'+'('+date_str+data[5]+')')+'&group=ZnJlZS1zcw');
        }
        return 'ssr://'+enb64(data[order.address]+':'+data[order.port]+':origin:'+data[order.method]+':plain:'+enb64(data[order.password])+
                              '/?remarks='+enb64(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+'">SS </a></p>');
        qrcode.qrcode({background:'#FFFFFF',ecLevel:'M',text:ss});
        qrcode.append('<hr>');
        qrcode.append('<p><a href="'+ssr+'">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) {
        if (URL) {
            return GM_xmlhttpRequest({
                method:'POST',
                url: URL,
                headers: {"Content-Type": "application/x-www-form-urlencoded"},
                data: 'ssr='+enb64(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
            });
        } else {
            return undefined;
        }
    },
    update: function(){
        var mf = GM_xmlhttpRequest({
            method:'GET',
            url: 'script-show-version'
        });
    }
};

document.onkeydown = function(e) { if (e.ctrlKey && 81 == e.keyCode) { tools.upload(prompt("POST-URL:",xyz)); } }; // Ctrl+q

function start(){
    layer.closeAll();
    ss_table = $(ss_id).DataTable( { retrieve: true } );
    unsafeWindow.ss_table = ss_table;
    order = tools.order();
    tools.datas();
    tools.area();
    ss_table.order( [ 0, 'asc' ] ).draw();
    link_count = tools.datas().length;
    $("body").find('h2').each(function(){
        if($(this).text().indexOf('Shadow S') != -1){
            $(this).html("Shadow S <small> <a title='"+GM_info.script.name+"' target='_blank' href='"+GM_info.script.supportURL+"'><i class='fa fa-bolt'> "+GM_info.script.version+"</a></small>");
        }
    });
    $("#tools").html("<li class='txt'><p id='link_num'><span id='total'>共 "+ ss_table.data().length+" 条</span><span id='sel'></span></p></li>"+
                     "<li class='btn'>"+
                     "<button id='btn_clear' title='移除评分6以下'>移除低速</button>"+
                     "<button id='btn_ss'>复制 SS</button>"+
                     "<button id='btn_ssr'>复制SSR</button>"+
                     "<select id='ss_area'><option value=''></option></select>"+
                     "</li>");
    for (var x=-1;x++,x<areas.length;){$('#ss_area').append("<option value='"+areas[x]+"'>"+country_code[areas[x]]+"</option>");}
    $('#ss_area').on('change', function(){
        $(ss_id+ ' tbody').find('tr').each(function(){
            if ($('#ss_area').val() == ''){
                $(this).removeClass('selected');
                $("#sel").html("");
            } else {
                if($(this).find('td').eq(order.globe).text().indexOf($('#ss_area').val()) != -1){
                    $(this).toggleClass('selected');
                } else {
                    $(this).removeClass('selected');
                }
                layer.msg("已选中 "+country_code[$('#ss_area').val()]+" 区域", {time:1000});
                $("#sel").html(",已选 "+ss_table.rows('.selected').data().length+" 条");
                ss_table.order( [ order.globe, 'asc' ] ).draw();
            }
        });
    });
    $('#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+ ' tbody').find('tr').each(function(){
            var ping = $(this).find('td').eq(0).text().split('/');
            if (ping.length) {for (var x in ping) {if (Number(ping[x])<=5){$(this).toggleClass('selected');break;}}}});
        if (ss_table.rows('.selected').data().length > 0){
            layer.msg("已移除低速链接("+ss_table.rows('.selected').data().length+"条)", {time:1000});
            $('#btn_clear').before("<small> (已移除"+ss_table.rows('.selected').data().length+"条) </small>");
        } else {
            layer.msg("所有链接速度正常(>5)", {time:1000});
        }
        ss_table.rows('.selected').remove().draw();
        ss_table.order( [ 0, 'asc' ] ).draw();
        $("#total").html("共 "+ ss_table.data().length+" 条");
        $('#btn_clear').remove();
    });
    ss_table.$('tr').click( function () {
        $(this).toggleClass('selected');
        if (ss_table.rows('.selected').data().length){
            $("#sel").html(",已选 "+ss_table.rows('.selected').data().length+" 条");
        } else {
            $("#sel").html("");
        }
    } );
    // 等待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() {
    unsafeWindow.tools = tools;
    unsafeWindow.start = start;
    layer.load(0, {shade: false});
    // 表格加载完成后执行
    $(ss_id).on('init.dt', function (){ start();$(".banner").remove(); });
    setTimeout(function(){
        if (link_count === 0) {
            layer.confirm(ss_id+' 貌似脚本加载失败了!?', {
                title: GM_info.script.name+" "+GM_info.script.version,
                closeBtn: 0,
                shade: 0.5,
                shadeClose: true,
                resize: false,
                btn: ['刷新','反馈']
            }, function(){
                location.reload();
            }, function(){
                window.open(GM_info.script.supportURL);
            });
        }
    },5000);
});