Greasy Fork

Greasy Fork is available in English.

饰品比例列表计算

饰品比例列表计算查看

当前为 2020-09-12 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         饰品比例列表计算
// @namespace    sourcewater
// @version      0.1
// @description  饰品比例列表计算查看
// @author       sourcewater
// @match        https://buff.163.com/market/?game=*
// @match        https://www.c5game.com/dota.html*
// @match        https://www.c5game.com/csgo/default/*
// @match        https://www.igxe.cn/dota2/*
// @match        https://www.igxe.cn/csgo/*
// @grant        GM_xmlhttpRequest
// ==/UserScript==

(function() {

    let log={
        DEBUG:1,
        INFO:5,
        level:1,
        setLevel:function(level){
            this.level=level;
        },
        log:function(msg,level,prefix){
            let date=new Date();
            let time=date.getHours()+":"+date.getMinutes()+":"+date.getSeconds();
            if(level>=this.level){
                console.log(prefix+time+" >>>> "+msg);
            }
        },
        info:function (msg){
            this.log(msg,this.INFO,"info: ");
        },
        debug:function(msg){
            this.log(msg,this.DEBUG,"debug: ");
        }
    };
    log.setLevel(log.INFO);
    let priceCSSEle=document.createElement("style");
    priceCSSEle.setAttribute("type","text/css");
    const displaySuccessClass="s_s_s_s_display_success";
    const itemidAttr="s_s_s_s_item_id";
    const successAttr="s_s_s_s_success";
    const linkRegAttr="s_s_s_s_click_register";
    const contentChangeAttr="s_s_s_s_content_change";
    const progressDivId="s_s_s_s_progress_div";
    const progressDivAttr="s_s_s_s_progress_init_success";
    const waitingDivId="s_s_s_s_waiting_div";
    const appidList={"csgo":730,"dota2":570};
    const buffUrlReg=/buff\.163\.com\//;
    const c5UrlReg=/c5game\.com\//;
    const igxeUrlReg=/igxe\.cn/;
    const timeout=6000;
    let index=0;
    let progressDivEle=document.createElement("div");
    progressDivEle.setAttribute("id",progressDivId);
    progressDivEle.setAttribute("style","border-radius:4px; border: 4px solid white; text-align: center;position: absolute;left: 50%;top: 55%;transform: translate(-50%, -50%);background:white;padding:5px;");
    progressDivEle.innerHTML=`
	<p>
	  <strong>正在初始化</strong><br>
	  <progress style="width:200px;height:25px;"></progress>
	</p>
	`;
    document.body.appendChild(progressDivEle);
    let priceCSS=`
        .s_s_s_s_display_success{
            display:block;
        }
        .s_s_s_s_cell_right,
        .s_s_s_s_cell_link,
        .s_s_s_s_cell_after_fee,
        .s_s_s_s_cell_rate,
        .s_s_s_s_cell_rate_high{
            width:50px;
            text-align:right;
        }
        .s_s_s_s_cell_left{
            display:inline-block;
            width:50px;
            text-align:left;
        }
        .s_s_s_s_cell_right{
            color:#eea20e;
        }
        .s_s_s_s_cell_link{
            color:black;
        }
        .s_s_s_s_cell_after_fee{
            color:purple;
        }
        .s_s_s_s_cell_rate{
            color:green;
        }
        .s_s_s_s_cell_rate_high{
            color:red;
        }
    `;
    let customPriceCss;
    if(buffUrlReg.test(window.location.href)){
        customPriceCss=`
        .s_s_s_s_cell_left{
            color:black;
        }
        .s_s_s_s_display_success{
            margin-left:15px;
            height:167px;
        }
        `;
    }else if(c5UrlReg.test(window.location.href)){
        customPriceCss=`
        .s_s_s_s_cell_left{
            color:white;
        }
        .s_s_s_s_display_success{
            margin-left:15px;
            height:205px;
        }
        `;
    }else if(igxeUrlReg.test(window.location.href)){
        ///////
        customPriceCss=`
        .s_s_s_s_cell_left{
            color:white;
        }
        .s_s_s_s_display_success{
            margin-left:15px;
            height:205px;
        }
        `;
    }
    priceCSSEle.innerHTML=priceCSS+customPriceCss;
    document.head.appendChild(priceCSSEle);
    function checkInitCalculate(){
        if(!progressDivEle.getAttribute(progressDivAttr)){
            initCalculate();
            return;
        }
        log.info("init successfully!");
    }
    function initCalculate(){
        setTimeout(function(){checkInitCalculate();},timeout);
        let steamMarketUrl="https://steamcommunity.com/market/";
        let walletVariable="var g_rgWalletInfo = ";
        GM_xmlhttpRequest({
            url: steamMarketUrl,
            method: 'GET',
            //timeout:10000,
            onload: function(res){
                if(res.status === 200){
                    let html=res.responseText;
                    walletVariable+=html.match(/var g_rgWalletInfo(.|\n)*?(\{+?(.|\n)*?\}+?)+/)[2];
                    let varScriptEle=document.createElement("script");
                    varScriptEle.setAttribute("type","text/javascript");
                    varScriptEle.innerHTML=walletVariable;
                    document.body.appendChild(varScriptEle);
                    let calculateJSUrl="https://steamcommunity-a.akamaihd.net/public/javascript/economy_common.js?v=tsXdRVB0yEaR&l=schinese&_cdn=china_pinyuncloud";
                    GM_xmlhttpRequest({
                        url: calculateJSUrl,
                        method: 'GET',
                        //timeout:10000,
                        onload: function(res){
                            if(res.status === 200){
                                let calculateScript=res.responseText;
                                let calScriptEle=document.createElement("script");
                                calScriptEle.setAttribute("type","text/javascript");
                                calScriptEle.innerHTML=calculateScript;
                                document.head.appendChild(calScriptEle);
                                progressDivEle.setAttribute(progressDivAttr,"success");
                                start(window.location.href);
                                document.body.removeChild(progressDivEle);
                            }else{
                                log.info("initCalculate(): 访问Steam市场错误!");
                            }
                        },onerror : function(err){
                            log.info("initCalculate(): 访问Steam市场超时!");
                        },ontimeout : function(err){
                            log.info("initCalculate(): 访问超时");
                        }
                    });
                }else{
                    log.info("initCalculate(): 访问Steam市场错误!");
                }
            },onerror : function(err){
                log.info("initCalculate(): 访问Steam市场超时!");
            },ontimeout : function(err){
                log.info("initCalculate(): 访问超时");
            }
        });

    }
    initCalculate();
    function getPriceValueAsInt(value){
        if(isNaN(value)){
            value=parseFloat(value);
        }
        return (value*100).toString();
    }
    function receivePirce(price){
        if(typeof price != 'undefined'){
            return (getPriceValueAsInt(price)-CalculateFeeAmount(getPriceValueAsInt(price),g_rgWalletInfo["wallet_publisher_fee_percent_default"]).fees)/100;
        }
        return 0;
    }
    function queryPrice(currentIndex,appid,name,updateView,args){
        log.info("new task index: "+currentIndex);
        if(currentIndex<index){
            log.debug("stop previous check update for index: "+currentIndex);
            return;
        }
        function checkUpdate(currentIndex,item_nameid,steamUrl,element){
            if(currentIndex<index){
                log.debug("stop previous check update for index: "+currentIndex);
                return;
            }
            if(!args.element.getAttribute(successAttr)){
                update(item_nameid,steamUrl);
                log.debug("retry get price >>>> "+item_nameid);
            }
            log.debug(item_nameid+" >>>> get price finish!");
        }
        function update(item_nameid,steamUrl){
            if(currentIndex<index){
                log.debug("stop previous check update for index: "+currentIndex);
                return;
            }
            let buyPrice=-1;
            let sellPrice=-1;
            setTimeout(function(){checkUpdate(currentIndex,item_nameid,steamUrl,args.element);},timeout);
            log.debug(`update: "https://steamcommunity.com/market/itemordershistogram?country=CN&language=schinese&currency=23&item_nameid=${item_nameid}&two_factor=0"`);
            GM_xmlhttpRequest({
                url: `https://steamcommunity.com/market/itemordershistogram?country=CN&language=schinese&currency=23&item_nameid=${item_nameid}&two_factor=0`,
                method: 'GET',
                //timeout:10000,
                responseType: 'json',
                onload: function(res){
                    if(res.status === 200){
                        let data=JSON.parse(res.responseText);
                        if(data.success==1){
                            if(data.buy_order_graph.length>0&&data.buy_order_graph[0].length>0){
                                buyPrice=data.buy_order_graph[0][0];
                            }
                            if(data.sell_order_graph.length>0&&data.sell_order_graph[0].length>0){
                                sellPrice=data.sell_order_graph[0][0];
                            }
                            args.sellPrice=sellPrice;
                            args.buyPrice=buyPrice;
                            args.steamUrl=steamUrl;
                            updateView(args);
                        }
                    }else{
                        log.info("update(): "+res.status+" :访问Steam市场错误!");
                    }
                },onerror : function(err){
                    log.info("update(): 访问Steam市场超时!");
                },ontimeout : function(err){
                    log.info("update(): 访问超时");
                }
            });
        }
        function checkFetchInfo(currentIndex,item_nameid){
            if(currentIndex<index){
                log.debug("stop previous check fetch info for index: "+currentIndex);
                return;
            }
            if(!args.element.getAttribute(itemidAttr)){
                fetchInfo();
                log.debug("retry get item name id.");
            }
            log.debug(item_nameid+" >>>> get item name id finish!");
        }
        function fetchInfo(){
            let item_nameid="";
            if(currentIndex<index){
                log.debug("stop previous check update for index: "+currentIndex);
                return;
            }
            let steamUrl=`https://steamcommunity.com/market/listings/${appid}/${name}`;
            setTimeout(function(){checkFetchInfo(currentIndex,item_nameid);},timeout);
            GM_xmlhttpRequest({
                method: "get",
                url: steamUrl,
                //timeout:10000,
                async: false,
                onload: function(res){
                    if(res.status === 200){
                        let response=res.responseText;
                        let nameidMatchs=response.match(/Market_LoadOrderSpread\(.*?([\d]+).*?\);/);
                        log.debug("<nameidMatchs: "+nameidMatchs+">");
                        if(nameidMatchs){
                            item_nameid=nameidMatchs.length == 2 ? nameidMatchs[1] : "";
                            log.debug("<item_nameid: "+item_nameid+">");
                            if(item_nameid!=""){
                                args.element.setAttribute(itemidAttr,"success");
                                update(item_nameid,steamUrl);
                            }
                        }else{
                            args.element.querySelector("#"+waitingDivId).innerHTML=`<span style="color: red;display:block;text-align: center;position: relative;left: 50%;top: 50%;transform: translate(-50%, -50%);">此物品不在货架上。</span>`;
                            args.element.setAttribute(itemidAttr,"success");
                        }
                    }else{
                        log.info("Error Code: "+res.status);
                    }
                },onerror : function(err){
                    log.info("fetchInfo(): 访问Steam市场错误!");
                },ontimeout : function(err){
                    log.info("fetchInfo(): 访问超时");
                }
            });
        }
        fetchInfo();
    }
    function updateView(args){
        let purchasePrice,sellRate,buyRate;
        let priceSpan=document.createElement("span");
        let success=true;
        if(buffUrlReg.test(args.url)&&!args.element.getAttribute(successAttr)){
            purchasePrice=parseFloat(args.element.querySelector("strong.f_Strong").innerHTML.match(/[\d\.]/g).join(""));
        }else if(c5UrlReg.test(args.url)&&!args.element.getAttribute(successAttr)){
            purchasePrice=parseFloat(args.element.querySelector("span.price").innerHTML.match(/[\d\.]/g).join(""));
        }else if(igxeUrlReg.test(args.url)&&!args.element.getAttribute(successAttr)){
            purchasePrice=parseFloat(args.element.querySelector(".price.fl").textContent.match(/[\d\.]+/g).join(""));
        }else{
            success=false;
        }
        if(success){
            sellRate=(purchasePrice/receivePirce(args.sellPrice)).toFixed(2);
            buyRate=(purchasePrice/receivePirce(args.buyPrice)).toFixed(2);
            args.element.removeChild(args.element.querySelector("#"+waitingDivId));
            priceSpan.setAttribute("class",displaySuccessClass);
            let priceContent=`
                <br><span class="s_s_s_s_cell_left">卖出:</span><span class="s_s_s_s_cell_right">${(args.sellPrice == -1 ? "无" : args.sellPrice)}</span>
                <br><span class="s_s_s_s_cell_left">税后:</span><span class="s_s_s_s_cell_after_fee">${args.sellPrice == -1 ? "无" : receivePirce(args.sellPrice)}</span>
                <br><span class="s_s_s_s_cell_left">比例:</span><span class="${ sellRate > 0.7 ? "s_s_s_s_cell_rate_high": "s_s_s_s_cell_rate"}">${args.sellPrice == -1 ? "无" : sellRate}</span>
                <br><br><span class="s_s_s_s_cell_left">买入:</span><span class="s_s_s_s_cell_right">${(args.buyPrice == -1 ? "无" : args.buyPrice)}</span>
                <br><span class="s_s_s_s_cell_left">税后:</span><span class="s_s_s_s_cell_after_fee">${args.buyPrice == -1 ? "无" : receivePirce(args.buyPrice)}</span>
                <br><span class="s_s_s_s_cell_left">比例:</span><span class="${ buyRate > 0.9 ? "s_s_s_s_cell_rate_high": "s_s_s_s_cell_rate"}">${args.buyPrice == -1 ? "无" : buyRate}</span>
                <br><br>
                <span class="s_s_s_s_cell_link"><a href="${args.steamUrl}" target="_blank">Steam链接</a></span>
        `;
            priceSpan.innerHTML=priceContent;
            args.element.setAttribute(successAttr,"true");
            args.element.appendChild(priceSpan);
            log.debug("update view successfully!");
        }
    }
    function waitForElement(selector,task){
        if(document.querySelector(selector)){
            task();
        }else{
            setTimeout(function(){waitForElement(selector,task);},100);
        }
    }
    let missionStart=false;
    function start(url){
        let cards;
        let cardClass;
        let appid;
        if(buffUrlReg.test(url)){
            let buffCSGOReg=/game=csgo/;
            let buffDotaReg=/game=dota2/;
            if(buffCSGOReg.test(url)){
                cardClass=".card_csgo";
                appid=appidList.csgo;
            }else if(buffDotaReg.test(url)){
                cardClass=".card_dota2";
                appid=appidList.dota2;
            }
            waitForElement(cardClass,function(){
                cards=document.querySelector(cardClass).querySelectorAll("li");
                startQuery();
            });

        }else if(c5UrlReg.test(url)){
            let c5CSGOReg=/\/csgo\//;
            let c5DotaReg=/dota\.html/;
            cardClass=".list-item4";
            if(c5DotaReg.test(url)){
                appid=appidList.dota2;
            }else if(c5CSGOReg.test(url)){
                appid=appidList.csgo;
            }
            waitForElement(cardClass,function(){
                cards=document.querySelector(cardClass).querySelectorAll("li");
                startQuery();
            });
        }else if(igxeUrlReg.test(url)){
            let igxeCSGOReg=/\/csgo\//;
            let igxeDotaReg=/\/dota2\//;
            cardClass=".dataList";
            if(igxeDotaReg.test(url)){
                appid=appidList.dota2;
            }else if(igxeCSGOReg.test(url)){
                appid=appidList.csgo;
            }
            waitForElement(cardClass,function(){
                cards=document.querySelector(cardClass).querySelectorAll("a");
                startQuery();
            });
        }
        function startQuery(){
            ++index;
            if(buffUrlReg.test(url)){
                for(let i=0;i<cards.length;++i){
                    let progressEleDiv=document.createElement("div");
                    progressEleDiv.setAttribute("id",waitingDivId);
                    queryPrice(index,appid,cards[i].querySelector("a").title,updateView,{"url":url,"element":cards[i]});
                    cards[i].setAttribute("style","height:399px!important;");
                    progressEleDiv.setAttribute("style","width:208px;height:120px;");
                    progressEleDiv.innerHTML=`<progress style="text-align: center;position: relative;left: 50%;top: 50%;transform: translate(-50%, -50%);"></progress>`;
                    cards[i].appendChild(progressEleDiv);
                }
                let marketCard=document.querySelector("#j_market_card");
                if(!missionStart){
                    let marketCardConfig = { childList: true };
                    let observer = new MutationObserver(function(){
                        if(!document.querySelector(cardClass)){
                            if(!marketCard.getAttribute(contentChangeAttr)){
                                marketCard.setAttribute(contentChangeAttr,"true");
                            }
                        }
                    });
                    observer.observe(marketCard, marketCardConfig);
                    let marketCardConfigAttr={ attributes: true };
                    let observerAttr = new MutationObserver(function(){
                        if(marketCard.getAttribute(contentChangeAttr)){
                            marketCard.removeAttribute(contentChangeAttr);
                            start(window.location.href);
                        }
                    });
                    observerAttr.observe(marketCard, marketCardConfigAttr);
                    missionStart=true;
                }
            }else if(c5UrlReg.test(url)){
                for(let i=0;i<cards.length;++i){
                    let progressEleSpan=document.createElement("span");
                    progressEleSpan.setAttribute("style","height:205px;display:block;");
                    progressEleSpan.setAttribute("id",waitingDivId);
                    queryPrice(index,appid,cards[i].querySelector("img").alt,updateView,{"url":url,"element":cards[i]});
                    progressEleSpan.innerHTML=`<progress style="text-align: center;position: relative;left: 50%;top: 50%;transform: translate(-50%, -50%);"></progress>`;
                    cards[i].appendChild(progressEleSpan);
                }
            }else if(igxeUrlReg.test(url)){
                const itemEnNameAttr="s_s_s_s_item_enName_success";
                function checkGetEnNameAndQuery(appid,cnName,progressEleSpan,card){
                    if(!card.getAttribute(itemEnNameAttr)){
                        getEnNameAndQuery(appid,cnName,progressEleSpan,card);
                        log.debug("retry get en name");
                    }
                    log.debug("get en name for "+cnName+" successfully!");
                }
                function getEnNameAndQuery(appid,cnName,progressEleSpan,card){
                    setTimeout(function(){checkGetEnNameAndQuery(appid,cnName,progressEleSpan,card);},timeout);
                    GM_xmlhttpRequest({
                        url: `https://steamcommunity.com/market/search?appid=${appid}&q=${cnName}`,
                        method: 'GET',
                        onload: function(res){
                            if(res.status === 200){
                                let html=res.responseText;
                                let itemLinkListReg=/<a[\s]+?class="market_listing_row_link"[\s\S]*?<\/a>/g;
                                let itemNameSpanReg=/<span[\s\S]+?class="market_listing_item_name"[\s\S]*?>(.+?)<\/span>/;
                                let enNameReg=/<div[\s\S]+?class="market_listing_row market_recent_listing_row market_listing_searchresult"[\s\S]*?data-hash-name="(.+)"[\s\S]*?>/
                                let enName="";
                                let linkList=html.match(itemLinkListReg);
                                if(linkList){
                                    for(let i=0;i<linkList.length;++i){
                                        let matchCNName=linkList[i].match(itemNameSpanReg)[1];
                                        if(matchCNName==cnName){
                                            enName=linkList[i].match(enNameReg)[1];
                                            break;
                                        }
                                    }
                                    if(enName==""){
                                        progressEleSpan.innerHTML=`<span style="color: red;display:block;text-align: center;position: relative;left: 50%;top: 50%;transform: translate(-50%, -50%);">此物品不在货架上。</span>`;
                                        card.setAttribute(itemidAttr,"success");
                                    }else{
                                        queryPrice(index,appid,enName,updateView,{"url":url,"element":card});
                                    }
                                    card.setAttribute(itemEnNameAttr,"success");
                                }
                            }else{
                                log.info("startQuery(): 访问Steam市场错误!Code: "+res.status);
                            }
                        },onerror : function(err){
                            log.info("startQuery(): 访问Steam市场超时!");
                        },ontimeout : function(err){
                            log.info("startQuery(): 访问超时");
                        }
                    });
                }
                for(let i=0;i<cards.length;++i){
                    let progressEleSpan=document.createElement("span");
                    progressEleSpan.setAttribute("style","height:205px;display:block;");
                    progressEleSpan.setAttribute("id",waitingDivId);
                    let card=cards[i];
                    let cnName=card.querySelector(".name").title;
                    card.setAttribute("style","height: 450px;");
                    progressEleSpan.innerHTML=`<progress style="text-align: center;position: relative;left: 50%;top: 50%;transform: translate(-50%, -50%);"></progress>`;
                    card.appendChild(progressEleSpan);
                    getEnNameAndQuery(appid,cnName,progressEleSpan,card)
                }
            }
        }
    }
})();