wytk-tieba

无影坦克

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         wytk-tieba
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  无影坦克
// @author       cjq
// @match        https://tieba.baidu.com/p/*
// @match        http://tieba.baidu.com/photo/p*
// @match        http://tiebapic.baidu.com/forum/pic/item/*
// @grant        GM_setValue
// @grant        GM_getValue
// @require      http://cdn.bootcss.com/jquery/1.8.3/jquery.min.js
// @run-at       document-end
// ==/UserScript==

(function () {
    jQuery.noConflict();
    //引入原脚本
    function utf8Encode(string) {
        var utftext = "";
        for (var n = 0; n<string.length; n++) {
            var c = string.charCodeAt(n);
            if (c<128) {
                utftext += String.fromCharCode(c);
            } else if ((c>127) && (c<2048)) {
                utftext += String.fromCharCode((c >> 6) | 192);
                utftext += String.fromCharCode((c & 63) | 128);
            } else {
                utftext += String.fromCharCode((c >> 12) | 224);
                utftext += String.fromCharCode(((c >> 6) & 63) | 128);
                utftext += String.fromCharCode((c & 63) | 128);
            }
        }
        return utftext;
    }

    function utf8Decode(inputStr) {
        var outputStr = "";
        var code1, code2, code3, code4;
        for(var i = 0; i < inputStr.length; i++) {
            code1 = inputStr.charCodeAt(i);
            if(code1 < 128) {
                outputStr += String.fromCharCode(code1);
            }else if(code1 < 224) {
                code2 = inputStr.charCodeAt(++i);
                outputStr += String.fromCharCode(((code1 & 31) << 6) | (code2 & 63));
            }else if(code1 < 240) {
                code2 = inputStr.charCodeAt(++i);
                code3 = inputStr.charCodeAt(++i);
                outputStr += String.fromCharCode(((code1 & 15) << 12) | ((code2 & 63) << 6) | (code3 & 63));
            }else {
                code2 = inputStr.charCodeAt(++i);
                code3 = inputStr.charCodeAt(++i);
                code4 = inputStr.charCodeAt(++i);
                outputStr += String.fromCharCode(((code1 & 7) << 18) | ((code2 & 63) << 12) |((code3 & 63) << 6) | (code2 & 63));
            }
        }
        return outputStr;
    }

    let IMG1=new Image();
    let IMGINFO=[];
    let IMG2=new Image();
    let MODE=4;
    let SRC1="";
    let SRC2="";
    let CURR_URL="";
    var DOMAIN=document.URL;

    function a1(){
        requestAnimationFrame(function(){
            requestAnimationFrame(function(){
                try{
                    let f=gen(MODE);
                    if(SRC1){URL.revokeObjectURL(SRC1)}
                    SRC1=URL.createObjectURL(f);
                    jQuery("#a1").attr("href",SRC1);
                    jQuery("#img1").attr("src",SRC1);
                    jQuery("#a1").css("display","inline");
                    jQuery("#a1").attr("download","download.png");
                }catch(e){alert("图片生成失败")}
            })
        })
    }

    function a2(){
        try{
            let f=sol();
            if(SRC2){URL.revokeObjectURL(SRC2)}
            SRC2=URL.createObjectURL(f[0]);
            jQuery("#" + String(id - 1)).attr("src",SRC2)
            jQuery("#" + String(id - 1)).before(createTip("图片读取成功!"))
        }catch(e){
            tryOpenOriginPicWhenDecodeError();
            jQuery("#" + String(id - 1)).before(createTip("解析读取失败,试试放大。如果已经放大,那就是无法解析。"))
        }
    }

    function select(){
        let l=[0,"500K","1M","1.5M","2M"]
        MODE=parseInt(jQuery("#compress_level_select")[0].value);
        document.getElementById("info1").innerHTML="建议里图大小:小于"+l[MODE]
    }

    function ipt1(){
        var oFReader = new FileReader();
        var ofile = jQuery("#ipt1")[0].files[0];
        oFReader.readAsDataURL(ofile);
        oFReader.onloadend = function(oFRevent){
            var osrc = oFRevent.target.result;
            IMG1.src=osrc;
        }
    }

    function ipt(){
        var oFReader = new FileReader();
        var ofile = jQuery("#ipt")[0].files[0];
        oFReader.readAsArrayBuffer(ofile);
        oFReader.onloadend = function(oFRevent){
            try{
                let l=new Uint8Array(oFRevent.target.result);
                IMGINFO=[ [l.length,utf8Encode(ofile.name),ofile.type],l];
            }catch(e){}
        }
    }

    //解密
    function ipt2(){
        var oFReader = new FileReader();
        //得到文件
        var ofile = document.getElementById("ipt2").files[0];
        console.log(ofile);
        oFReader.readAsDataURL(ofile);

        oFReader.onloadend = function(oFRevent){
            var osrc = oFRevent.target.result;
            IMG2.src=osrc;
            console.log(IMG2.src);

            IMG2.onload=function(){
                console.log('img2.onload')
                a2()
            }
        }
    }

    function dataURLtoBlob(dataurl) {
        var arr = dataurl.split(',');
        var _arr = arr[1];
        var mime = arr[0].match(/:(.*?);/)[1],
            bstr =atob(_arr),
            n = bstr.length,
            u8arr = new Uint8Array(n);
        while (n--) {
            u8arr[n] = bstr.charCodeAt(n);
        }
        return new Blob([u8arr.buffer], {type: mime});
    }

    function gen(mode){
        let modelist=[0,3,mode];
        let word=IMGINFO[0].join(String.fromCharCode(1))+String.fromCharCode(0);
        let length=2+parseInt((word.length+IMGINFO[1].length)*8/(mode*3))
        let ax=Math.sqrt(length/(IMG1.width*IMG1.height));
        let wid=Math.ceil(IMG1.width*ax);
        let hit=Math.ceil(IMG1.height*ax);
        let cv=document.createElement("canvas");
        let cvd=cv.getContext("2d");
        cv.width=wid;
        cv.height=hit;
        cvd.fillStyle="#ffffff";
        cvd.fillRect(0,0,wid,hit);
        cvd.drawImage(IMG1,0,0,wid,hit);

        if(jQuery('#beizhucheckbox').is(':checked')){
            let w=jQuery('#beizhu')[0].value;
            cvd.font="16px Arial";
            cvd.textBaseline="middle";
            cvd.fillStyle="rgba(255,255,255,0.75)";
            cvd.fillRect(0,0,cvd.measureText(w).width+8,28);
            cvd.fillStyle="#000000";
            cvd.fillText(w,4,14,wid-8);
        }

        return new File([dataURLtoBlob(en(mode,modelist,cvd.getImageData(0,0,wid,hit),word,IMGINFO[1]," wytk.github.io"))],"download.png",{type:"image/png"})
    }

    function sol(){
        let cv=document.createElement("canvas");
        let cvd=cv.getContext("2d");
        cv.width=IMG2.width;
        cv.height=IMG2.height;
        cvd.drawImage(IMG2,0,0);
        let imgdata=cvd.getImageData(0,0,IMG2.width,IMG2.height);
        let klist=de(imgdata.data[2]%8,imgdata);
        let file=new File([klist[1].buffer],utf8Decode(klist[0][1]),{type:klist[0][2]})
        return [file,utf8Decode(klist[0][1])]
    }

    function closer(mode,m,n){
        let a=m % mode
        if(255-m<=mode/2 || m<mode/2){
            return parseInt(m/mode)*mode+n
        }else if(n-a>mode/2){
            return parseInt(m/mode)*mode+n-mode
        }else if(a-n>=mode/2){
            return parseInt(m/mode)*mode+n+mode
        }else{
            return parseInt(m/mode)*mode+n
        }
    }

    function en(mode,fplist,imgdata,aword,blist,cword){
        let aa=Math.ceil(8/3/mode);
        let n=imgdata.width*imgdata.height;
        let j=0;
        let k="";
        let i=1;
        let mlist=[1,2,4,8,16,32,64,128];
        let cv=document.createElement("canvas");
        let cvd=cv.getContext("2d");
        cv.width=imgdata.width;
        cv.height=imgdata.height;
        imgdata.data[0]=closer(8,imgdata.data[0],fplist[0]);
        imgdata.data[1]=closer(8,imgdata.data[1],fplist[1]);
        imgdata.data[2]=closer(8,imgdata.data[2],fplist[2]);
        while(i<n && j<aword.length){
            k=k+(aword.charCodeAt(j)+256).toString(2).slice(1);
            for(let ii=0;ii<aa;ii++){
                if(k.length>=mode*3){
                    imgdata.data[4*i  ]=closer(mlist[mode],imgdata.data[4*i  ],parseInt(k.slice(0     ,mode  ),2));
                    imgdata.data[4*i+1]=closer(mlist[mode],imgdata.data[4*i+1],parseInt(k.slice(mode  ,mode*2),2));
                    imgdata.data[4*i+2]=closer(mlist[mode],imgdata.data[4*i+2],parseInt(k.slice(mode*2,mode*3),2));
                    k=k.slice(mode*3);
                    i++
                }
            }
            j++
        }
        j=0;
        while(i<n && j<blist.length){
            k=k+(blist[j]+256).toString(2).slice(1);
            for(let ii=0;ii<aa;ii++){
                if(k.length>=mode*3){
                    imgdata.data[4*i  ]=closer(mlist[mode],imgdata.data[4*i  ],parseInt(k.slice(0     ,mode  ),2));
                    imgdata.data[4*i+1]=closer(mlist[mode],imgdata.data[4*i+1],parseInt(k.slice(mode  ,mode*2),2));
                    imgdata.data[4*i+2]=closer(mlist[mode],imgdata.data[4*i+2],parseInt(k.slice(mode*2,mode*3),2));
                    k=k.slice(mode*3);
                    i++
                }
            }
            j++
        }
        j=0;
        while(i<n){
            k=k+(cword.charCodeAt(j%cword.length)+256).toString(2).slice(1);
            for(let ii=0;ii<aa;ii++){
                if(k.length>=mode*3){
                    imgdata.data[4*i  ]=closer(mlist[mode],imgdata.data[4*i  ],parseInt(k.slice(0     ,mode  ),2));
                    imgdata.data[4*i+1]=closer(mlist[mode],imgdata.data[4*i+1],parseInt(k.slice(mode  ,mode*2),2));
                    imgdata.data[4*i+2]=closer(mlist[mode],imgdata.data[4*i+2],parseInt(k.slice(mode*2,mode*3),2));
                    k=k.slice(mode*3);
                    i++
                }
            }
            j++
        }
        cvd.putImageData(imgdata,0,0);
        return cv.toDataURL();
    }

    function de(mode,imgdata){
        let aa=Math.ceil(3*mode/8);
        let n=imgdata.width*imgdata.height;
        let j=0;
        let k="";
        let i=1;
        let mlist=[1,2,4,8,16,32,64,128];
        let word="";
        let blist//=new Uint8Array();
        let blength=0;
        while(i<n && (word.length==0 || word.slice(-1).charCodeAt(0)>0)){
            k=k+(imgdata.data[4*i  ]+256).toString(2).slice(-mode);
            k=k+(imgdata.data[4*i+1]+256).toString(2).slice(-mode);
            k=k+(imgdata.data[4*i+2]+256).toString(2).slice(-mode);
            i++
            for(let ii=0;ii<aa;ii++){
                if(k.length>=8 && (word.length==0 || word.slice(-1).charCodeAt(0)>0)){
                    word=word+String.fromCharCode(parseInt(k.slice(0,8),2));
                    k=k.slice(8);
                }
            }
        }
        //word分隔符:","
        blength=parseInt(word.split(String.fromCharCode(1))[0]);
        if(!(blength>-1)){
            throw "error"
        }
        if(!(word.split(String.fromCharCode(1)).length>2)){
            throw "error"
        }
        blist=new Uint8Array(blength);
        if(k.length>=8 && j<blength){
            blist[j]=parseInt(k.slice(0,8),2);
            k=k.slice(8);
            j++
        }
        while(i<n && j<blength){
            k=k+(imgdata.data[4*i  ]+256).toString(2).slice(-mode);
            k=k+(imgdata.data[4*i+1]+256).toString(2).slice(-mode);
            k=k+(imgdata.data[4*i+2]+256).toString(2).slice(-mode);
            i++
            for(let ii=0;ii<aa;ii++){
                if(k.length>=8 && j<blength){
                    blist[j]=parseInt(k.slice(0,8),2);
                    k=k.slice(8);
                    j++
                }
            }
        }
        return [word.split(String.fromCharCode(0))[0].split(String.fromCharCode(1)),blist]
    }

    //url转data
    function getImageFileFromUrl(url, imageName,callback) {

        // imageName一定要带上后缀
        var blob = null;
        var xhr = new XMLHttpRequest();
        xhr.open("GET", url);
        xhr.setRequestHeader('Accept', 'image/jpeg');
        xhr.responseType = "blob";
        xhr.onload = () => {
            if (xhr.status == 200) {
                blob = xhr.response;
                let imgFile = new File([blob], imageName, {type: 'image/jpeg'});
                console.log(imgFile)
                callback.call(this,imgFile);
            }else{jQuery("#" + String(id)).before(createTip("网络出错,无法读取。"))}};
        xhr.send();

    }

    //获取协议类型
    function getProtocolStr(url){
        var reg=/http:/;
        if(reg.test(url)){
            return "http";
        }else{
            return "https"
        }
    }

    //得到链接中图片的名称
    function getUrlLastPathNameStr(url){
        var index = url.lastIndexOf("\/");
        var last= url.substring(index + 1, url.length);
        return last;
    }

    //如果解析失败可能是因为图片需要放大解析,但是由于跨域问题,所以要在新页面中解析,此时hover事件再次绑定成功,即可解析
    function tryOpenOriginPicWhenDecodeError(){
        if(DOMAIN.startsWith("https://tieba.baidu.com")){
            window.open('http://tiebapic.baidu.com/forum/pic/item/'+getUrlLastPathNameStr(CURR_URL));
        }
    }

    //创建提示标签
    function createTip(str){
        return "<p style=\"font-size:15px;color:orange\">"+str+"</p><br/>";
    }

    var id = 0;

    if(!GM_getValue('firstTime')){
        GM_setValue('firstTime',true);
        GM_setValue('pluginOnOffFlag',true);
        GM_setValue('autoJumpOriginFlag',true);
    }
    console.log(GM_getValue('pluginOnOffFlag'));
    var userConfig={
        pluginOnOffFlag:GM_getValue('pluginOnOffFlag'),
        pluginAutoJumpOriginFlag:GM_getValue('autoJumpOriginFlag')
    }

    //在firefox下并不总是有效果,所以我把加载内容都给移出了,并且使用了 document-end 注解
    window.onload=function(){

        console.log("onloading~");

        //下面这两行不知道是干什么的,屏蔽掉了
        //let w="<!DOCTYPE "+"html>"+document.documentElement.outerHTML;
        //document.getElementById("bc").href=URL.createObjectURL(new Blob([w],{type:"text/html"}))

        var timerId=setInterval(function(){

            //考虑到有些用户会不自觉放大页面
            //检查是不是有原图,有则跳转到新标签页显示,因为在原图网页我绑定不了hover事件
            var picURL=jQuery('.image_original_original').attr('src');
            if(picURL!=undefined && picURL!='' && userConfig.pluginAutoJumpOriginFlag){
                window.open(picURL);
                clearInterval(timerId);
            }
        },1000);

        console.log("onload end~");
    }

    //左浮窗功能
    jQuery("body").append("\
<div id='plugin_float' \
style='left: 20px;\
bottom: 20px;\
background: #9beee2;\
color:#3e32d2;\
overflow: hidden;\
z-index: 9999;\
position: fixed;\
padding:5px;\
text-align:left;\
font-size:20px;\
'></div>");

    jQuery("#plugin_float").append('<p>无影坦克𝐈𝐈:</p>')
        .append('<input type="checkbox" id="plugin_enable_state"> 鼠标悬浮解析 <br>')
        .append('<input type="checkbox" id="plugin_autojump_state"> 自动跳大图 <br>')
        .append('<p>找不到心爱的小锤锤?给你🔨</p>');

    if(userConfig.pluginOnOffFlag){
        jQuery('#plugin_enable_state').attr('checked','checked');
    }

    if(userConfig.pluginAutoJumpOriginFlag){
        jQuery('#plugin_autojump_state').attr('checked','checked');
    }

    jQuery("#plugin_float").append("🖼️<a href = \"javascript:void(0)\"onclick = \"document.getElementById('light').style.display='block';document.getElementById('fade').style.display='block'\"> 快速制图 </a>");

    //中间浮窗,用来制图
    jQuery("body").append("\
<style>\
.black_overlay{\
display: none;\
position: fixed;\
top: 0%;\
left: 0%;\
width: 100%;\
height: 100%;\
background-color: black;\
z-index:1040;\
-moz-opacity: 0.8;\
opacity:.80;\
filter: alpha(opacity=88);\
}\
.white_content {\
display: none;\
position: fixed;\
top: 25%;\
left: 25%;\
width: 55%;\
height: 55%;\
padding: 20px;\
border: 10px solid orange;\
background-color: white;\
z-index:1050;\
overflow: auto;\
}\
</style>");

    jQuery("body").append("<div id=\"light\" class=\"white_content\"> \
<br>\
<a href=\"https://wytk.github.io/\">GITHUB官方制图工具链接 https://wytk.github.io/</a> <br>\
\
<summary>制作坦克</summary> \
<span>选择表图</span><br><input type=\"file\" id=\"ipt1\" accept=\"image/*\"> \
<br> \
<span>选择里图</span><br><input type=\"file\" id=\"ipt\" accept=\"image/*\"> \
<br> \
<span>添加备注</span><input id=\"beizhucheckbox\" type=\"checkbox\" checked=\"true\"> \
<br><input type=\"text\" id=\"beizhu\" style=\"width:150px\" value=\"TK\"> \
<br> \
<span>表图压缩度 </span><select id=\"compress_level_select\" \
<option value=\"1\">1</option> \
<option value=\"2\">2</option> \
<option value=\"3\">3</option> \
<option value=\"4\" selected=\"true\">4</option> \
</select>\
<br>\
<span id=\"info1\">建议里图大小:小于2M</span>\
<br>\
<button id=\"a1_button\">合成图片</button> \
<br> \
<img id=\"img1\"> \
<br> \
<a href=\"\" id=\"a1\" style=\"display:none\">保存图片</a> \
\
<a href = \"javascript:void(0)\" onclick = \"document.getElementById('light').style.display='none';document.getElementById('fade').style.display='none'\">关闭窗口<br></a>\
<br> \
</div> \
<div id=\"fade\" class=\"black_overlay\"></div>");

    //冒泡事件,防止动态加载
    jQuery("body").on("hover","img",function(event){

        //只响应鼠标移动到图片上,忽略移开
        if(event.type=="mouseenter"){

            if(!userConfig.pluginOnOffFlag)
                return;

            //忽略上次处理过的图片
            if(jQuery(this).attr("id")==(id-1))
                return;

            //忽略制图中的图片,否则会导致无法继续制图
            if(jQuery(this).attr("id")=="img1")
                return;

            jQuery(this).attr("id",String(id));
            jQuery("#" + String(id)).before(createTip("正在加载。。。若长时间无反应请手动点击图片!"));
            id = id + 1;

            var url=jQuery(this).attr("src");
            CURR_URL=url;

            //请求资源的协议看domain不看资源的src,否则会产生mixed错误
            getImageFileFromUrl(getProtocolStr(DOMAIN) + url.substring(4,url.length),'testFile.jpg',function(file){
                console.log(file)
                var r = new FileReader()
                r.readAsDataURL(file)
                r.onloadend = function(oFRevent){
                    var osrc = oFRevent.target.result;
                    IMG2.src=osrc;
                    IMG2.onload=function(){
                        a2()
                    }
                }
            });
        }
    });

    jQuery("body").on("click",function(event){
        //console.log(event.target);

        if(event.target.id=="plugin_enable_state"){
            userConfig.pluginOnOffFlag=jQuery('#plugin_enable_state').is(':checked');
            GM_setValue('pluginOnOffFlag',userConfig.pluginOnOffFlag);
            console.log("插件使能状态改变:"+userConfig.pluginOnOffFlag);
        }

        if(event.target.id=="plugin_autojump_state"){
            userConfig.pluginAutoJumpOriginFlag=jQuery('#plugin_autojump_state').is(':checked');
            GM_setValue('autoJumpOriginFlag',userConfig.pluginAutoJumpOriginFlag);
            console.log("自动跳大图状态改变:"+userConfig.pluginAutoJumpOriginFlag);
        }

        if(event.target.id=="a1_button"){
            a1();
        }

    });

    jQuery("body").on("change",function(event){
        //console.log(event.target);
        if(event.target.id=="ipt1"){
            ipt1();
        }

        if(event.target.id=="ipt"){
            ipt();
        }

        if(event.target.id=="compress_level_select"){
            select();
        }

    });

})();