回复
1
查看
189
收藏
2

33

赠楼

30%

赠楼率

690

蒸汽

160

主题

2971

帖子

2万

积分
发表于 昨天 21:44 · 中国香港 | 显示全部楼层 |阅读模式
【SteamDB】游戏筛选页面显示卡牌价格信息脚本
https://keylol.com/t692296-1-1

让gpt修了一下,摆烂.jpg
我这边经常提示访问频繁所以加了个随机延迟,太慢可以自己改一下

  1. // ==UserScript==
  2. // [url=home.php?mod=space&uid=32250]@name[/url]         Steam Get Trading Card Info
  3. // [url=home.php?mod=space&uid=336413]@Namespace[/url]    http://tampermonkey.net/
  4. // @version      1.5.1
  5. // @description  在steam商店页面以及steamdb筛选页面获取游戏的卡牌信息
  6. // [url=home.php?mod=space&uid=683303]@author[/url]       lyzlyslyc
  7. // @license      MIT
  8. // @require      http://cdn.bootcss.com/jquery/3.2.1/jquery.min.js
  9. // [url=home.php?mod=space&uid=384136]@match[/url]        http://store.steampowered.com/app/*
  10. // @match        https://store.steampowered.com/app/*
  11. // @match        https://steamdb.info/sales/*
  12. // @match        http://steamdb.info/sales/*
  13. // [url=home.php?mod=space&uid=336755]@Grant[/url]        GM_xmlhttpRequest
  14. // @grant        GM_getResourceText
  15. // @grant        GM_addStyle
  16. // @connect      steamcommunity.com
  17. // @run-at       document-end
  18. // ==/UserScript==

  19. var timeOut = 6000; //请求超时时长(毫秒)
  20. var interval = 3000; //查询间隔 steamdb (毫秒)

  21. var hasAddTableHead=false;               //是否已经添加表头
  22. var hasAddButton=false;                  //是否添加重试按钮
  23. var queryArray = new Array();            //请求线程列表
  24. var lastIndex = 0;                       //上一个请求的位置
  25. var lastErrorIndex = -1;                 //上一个请求出错的位置
  26. var isSameCountry = true;                //steamdb和社区市场货币相同
  27. var isSteamDB = false;                   //当前页面是否为steamdb
  28. var showPureIncome = false;              //是否显示纯收入
  29. var isBlocked = false;                   //悬浮窗已屏蔽
  30. var currentPage = "1";                   //当前显示页面
  31. var hover;                               //悬浮窗
  32. var steamDBCurrency = null;
  33. var steamCountry = null;
  34. var errorNum = 0;
  35. var successNum = 0;
  36. var noInfoNum = 0;
  37. (function()
  38. {
  39.     'use strict';

  40.     //steamdb
  41.     if(location.href.search("steamdb.info/sales/")!=-1)
  42.     {
  43.         if(location.href.search("#setFilter")!=-1)$("#DataTables_Table_0").ready(()=>{$("#DataTables_Table_0 > thead > tr > th:nth-child(5)").click();});
  44.         isSteamDB = true;
  45.         //样式
  46.         document.head.innerHTML+='<style type="text/css">table.table-sales{table-layout: auto ;word-break: keep-all;}#card_filter_chk_div {display: flex;gap: 10px;margin-top: 25px;justify-content: center;flex-wrap: wrap;}#card_filter_container{max-width:480px;margin: 15px 0;}a.card-filter-btn{width: 100%;margin-top: 5px;padding: 8px;line-height: 1;font-size: 14px;border: 0;color: #fff;background: #338037;box-shadow: none;text-align: center;}</style>';
  47.         //卡牌筛选容器
  48.         const cardFilterContainer = $("<div id = 'card_filter_container'></div>");
  49.         cardFilterContainer.prependTo($("div.filters-container"));
  50.         //选项容器
  51.         const chkContainer = $("<div id ='card_filter_chk_div'></div>");
  52.         chkContainer.appendTo(cardFilterContainer);
  53.         //按钮容器
  54.         const btnContainer = $("<div id ='card_filter_btn_div' style='margin-top: 10px;'></div>");
  55.         btnContainer.appendTo(cardFilterContainer);

  56.         //重试按钮
  57.         const btnRetry = $('<a href="#" class="btn card-filter-btn" id="retry_card_query">失败重试</a>');
  58.         btnRetry.on("click",function(){
  59.             for(var i=0;i<queryArray.length;i++)clearTimeout(queryArray[i]);
  60.             queryArray=[];
  61.             startQuery("retryError");
  62.         });
  63.         btnRetry.appendTo(btnContainer);
  64.         btnRetry.hide();

  65.         //停止按钮
  66.         var btnPause = $('<a href="#" class="btn card-filter-btn" id="abort_card_query">停止</a>');
  67.         btnPause.on("click",function(e){
  68.             if(btnPause.text()=="停止"){
  69.                 for(var i=0;i<queryArray.length;i++)clearTimeout(queryArray[i]);
  70.                 queryArray=[];
  71.                 btnPause.text("继续");
  72.             }
  73.             else if(btnPause.text()=="继续"){
  74.                 startQuery("continue");
  75.             }
  76.         });
  77.         btnPause.appendTo(btnContainer);
  78.         btnPause.hide();

  79.         //开始按钮
  80.         const btnStart = $('<a href="#" class="btn card-filter-btn" id="start_card_query">获取卡牌信息</a>');
  81.         btnStart.on("click",function(){
  82.             for(var i=0;i<queryArray.length;i++)clearTimeout(queryArray[i]);
  83.             queryArray=[];
  84.             btnRetry.show();
  85.             btnPause.show();
  86.             startQuery("start");
  87.             btnStart.text("全部重试");
  88.         });
  89.         btnStart.appendTo(btnContainer);

  90.         //一键设置卡牌筛选
  91.         const btnSetFilter = $('<a href="#setFilter" class="btn card-filter-btn" id="start_card_query">一键设置卡牌条件</a>');
  92.         btnSetFilter.on("click",function(){
  93.             setFilter();
  94.         });
  95.         btnSetFilter.appendTo($("#js-filters"));

  96.         //屏蔽悬浮窗
  97.         const chkBlock = $(`<div class='steamy-checkbox-control' id='block_hover'><div class="steamy-checkbox"></div><span class="steamy-checkbox-label">屏蔽悬浮窗</span></div>`);
  98.         chkBlock.on("click",()=>{
  99.             isBlocked=!isBlocked;
  100.             chkBlock.toggleClass("checked",isBlocked);
  101.             blockHover(isBlocked);
  102.         });
  103.         chkBlock.appendTo(chkContainer);

  104.         //显示净收入
  105.         const chkPureIncome = $(`<div class='steamy-checkbox-control' id='show_pure_income'><div class="steamy-checkbox"></div><span class="steamy-checkbox-label">显示净收入</span></div>`);
  106.         chkPureIncome.on("click",(e)=>{
  107.             showPureIncome=!showPureIncome;
  108.             chkPureIncome.toggleClass("checked",showPureIncome);
  109.             showIncome(showPureIncome);
  110.         });
  111.         chkPureIncome.appendTo(chkContainer);

  112.         //忽略最高价
  113.         const chkIgnoreHighest = $(`<div class='steamy-checkbox-control' id='ignore_highest'><div class="steamy-checkbox"></div><span class="steamy-checkbox-label">忽略最高价</span></div>`);
  114.         chkIgnoreHighest[0].checked=false;
  115.         chkIgnoreHighest.on("click",(e)=>{
  116.             chkIgnoreHighest[0].checked=!chkIgnoreHighest[0].checked;
  117.             chkIgnoreHighest.toggleClass("checked",chkIgnoreHighest[0].checked);
  118.         });
  119.         chkIgnoreHighest.appendTo(chkContainer);

  120.         //使用中位数
  121.         const chkUseMedium = $(`<div class='steamy-checkbox-control' id='use_medium'><div class="steamy-checkbox"></div><span class="steamy-checkbox-label">使用中位数</span></div>`);
  122.         chkUseMedium[0].checked=false;
  123.         chkUseMedium.on("click",(e)=>{
  124.             chkUseMedium[0].checked=!chkUseMedium[0].checked;
  125.             chkUseMedium.toggleClass("checked",chkUseMedium[0].checked);
  126.         });
  127.         chkUseMedium.appendTo(chkContainer);

  128.         //社区登录状态
  129.         $("<a id='loginInfo' style='margin-right: 10px;' href='https://steamcommunity.com' target='_blank'></a>").appendTo($(".header-user.hide-small"));

  130.         //更改单页显示数量后
  131.         document.querySelector("#DataTables_Table_0_length > label > select").addEventListener
  132.         (
  133.             "change",
  134.             function(e)
  135.             {
  136.                 blockHover(document.getElementById("block_hover").checked);
  137.                 if(document.getElementById("abort_card_query")!=null)
  138.                     if(document.getElementById("abort_card_query").innerText == "查询完成")
  139.                         if(lastIndex + 1<document.querySelector("#DataTables_Table_0 tbody").childElementCount)
  140.                             document.getElementById("abort_card_query").innerText ="继续";
  141.             }
  142.         )

  143.         //翻页后
  144.         document.querySelector("#DataTables_Table_0_paginate").addEventListener("click",function(e){
  145.             if(document.querySelector(".paginate_button.active").innerHTML != currentPage)
  146.             {
  147.                 currentPage=document.querySelector(".paginate_button.active").innerHTML;
  148.                 blockHover(document.getElementById("block_hover").checked);
  149.                 for(var i=0;i<queryArray.length;i++)clearTimeout(queryArray[i]);
  150.                 queryArray=[];
  151.                 lastIndex = 0;
  152.                 lastErrorIndex = -1;
  153.                 if(document.getElementById("abort_card_query")!=null)
  154.                     document.getElementById("abort_card_query").innerText ="继续";
  155.             }
  156.         })
  157.         checkLoginStatus();
  158.     }
  159.     else
  160.     //steam界面
  161.     {
  162.         var appid = document.location.href.match(/\/app\/+\d*\//)[0].replace(/[^\d]/ig,"");
  163.         var oriNode = document.querySelector(".release_date");
  164.         var cardDiv = oriNode.cloneNode(true);//克隆样式

  165.         cardDiv.setAttribute("class","card_info_row");
  166.         cardDiv.children[0].innerHTML="卡牌信息:";
  167.         cardDiv.children[1].setAttribute("class","summary column");
  168.         cardDiv.children[1].setAttribute("id","card_info_summary");
  169.         cardDiv.children[1].innerHTML="";
  170.         document.head.innerHTML+='<style type="text/css"> .card_info_row .column {overflow: hidden;white-space: nowrap;text-overflow: ellipsis;}  .card_info_row {display: flex;line-height: 16px;padding-top: 9px;padding-bottom: 13px;} </style>';

  171.         var node=document.createElement("A");
  172.         cardDiv.children[1].appendChild(node);
  173.         oriNode.parentNode.appendChild(cardDiv);

  174.         getCardInfo(appid, node);
  175.     }

  176.     //steamdb开始查询
  177.     function startQuery(status)
  178.     {
  179.         //检查登录状态
  180.         checkLoginStatus();
  181.         //获取steamDB货币
  182.         steamDBCurrency = getSteamDBCurrency();
  183.         //开始添加表头
  184.         //表格工具点
  185.         var table = document.querySelector("#DataTables_Table_0");
  186.         if(!hasAddTableHead)
  187.         {
  188.             //卡牌收入表头
  189.             var cardIncomeHead = table.querySelector("thead > tr > th:nth-child(5)").cloneNode(true);
  190.             //卡牌数量表头
  191.             var cardCountHead = table.querySelector("thead > tr > th:nth-child(5)").cloneNode(true);
  192.             //卡牌均价表头
  193.             var AvgPriceHead = table.querySelector("thead > tr > th:nth-child(5)").cloneNode(true);
  194.             cardIncomeHead.textContent = " CardIncome";
  195.             cardIncomeHead.setAttribute("class","sorting");
  196.             cardIncomeHead.setAttribute("style","width:125px");
  197.             cardIncomeHead.setAttribute("aria-label"," CardIncome: activate to sort column ascending");
  198.             cardIncomeHead.addEventListener("click",function(){sort(0);});
  199.             table.querySelector("thead > tr").appendChild(cardIncomeHead);

  200.             AvgPriceHead.textContent = " AvgPrice";
  201.             AvgPriceHead.setAttribute("class","sorting");
  202.             AvgPriceHead.setAttribute("style","width:100px");
  203.             AvgPriceHead.setAttribute("aria-label"," AvgPrice: activate to sort column ascending");
  204.             AvgPriceHead.addEventListener("click",function(){sort(1);});
  205.             table.querySelector("thead > tr").appendChild(AvgPriceHead);

  206.             cardCountHead.textContent = " Count";
  207.             cardCountHead.setAttribute("class","sorting");
  208.             cardCountHead.setAttribute("style","width:75px");
  209.             cardCountHead.setAttribute("aria-label"," Count: activate to sort column ascending");
  210.             cardCountHead.addEventListener("click",function(){sort(2);});
  211.             table.querySelector("thead > tr").appendChild(cardCountHead);

  212.             hasAddTableHead = true;
  213.         }

  214.         var header = document.querySelectorAll("[class=sorting_desc],[class=sorting_asc]");
  215.         for(i = 0;i<header.length;i++)header[i].setAttribute("class","sorting");
  216.         //获取app列表
  217.         var apps=table.querySelector("tbody");

  218.         btnPause.text("停止");
  219.         //开始查询
  220.         if(status=="start")lastIndex=0;
  221.         var queryCount = 0;
  222.         var i = 0
  223.         if(status=="continue"&&lastIndex+1>=apps.childElementCount)btnPause.text("查询完成");
  224.         //遍历app表格
  225.         for(i=0;i<apps.childElementCount;i++)
  226.         {
  227.             //app行
  228.             var parentNode = apps.children[i];
  229.             //app价格项
  230.             var priceNode = apps.children[i].querySelector("td:nth-child(5)");
  231.             //卡牌收入项
  232.             var cardIncomeNode = parentNode.querySelector("td:nth-child(5)").cloneNode(true);
  233.             //卡牌数量项
  234.             var cardCountNode = parentNode.querySelector("td:nth-child(5)").cloneNode(false);
  235.             //卡牌均价项
  236.             var AvgPriceNode = parentNode.querySelector("td:nth-child(5)").cloneNode(false);
  237.             //卡牌收入结果
  238.             var cardLink = document.createElement("A");
  239.             //设置为查询中
  240.             cardLink.setAttribute("hasQueried","false");
  241.             cardIncomeNode.innerHTML="";
  242.             cardIncomeNode.setAttribute("class","card_income");
  243.             cardIncomeNode.dataset.sort = 0;
  244.             cardCountNode.setAttribute("class","card_count");
  245.             cardCountNode.dataset.sort = 0;
  246.             AvgPriceNode.setAttribute("class","card_avgprice");
  247.             AvgPriceNode.dataset.sort = 0;
  248.             cardIncomeNode.appendChild(cardLink);
  249.             //如果还没有查询过
  250.             if(parentNode.lastChild.className != "card_count")
  251.             {
  252.                 parentNode.appendChild(cardIncomeNode);
  253.                 parentNode.appendChild(AvgPriceNode);
  254.                 parentNode.appendChild(cardCountNode);
  255.                 queryArray.push(
  256.                     setTimeout(
  257.                         getCardInfo,
  258.                         (queryCount + 1) * interval + Math.random() * 1000,
  259.                         apps.children[i].dataset.appid,
  260.                         cardLink,
  261.                         status,
  262.                         i,
  263.                         parseInt(priceNode.dataset.sort),
  264.                         i
  265.                     )
  266.                 );
  267.                 queryCount++;
  268.             }
  269.             else
  270.             {
  271.                 switch(status)
  272.                 {
  273.                     //重试,重新请求加载中和错误的部分
  274.                     case "retryError":
  275.                         if(lastErrorIndex == -1)btnPause.text("继续");
  276.                         if(parentNode.querySelector("[hasqueried]").getAttribute("hasqueried")!="error" && parentNode.querySelector("[hasqueried]").getAttribute("hasqueried")!="loading")break;
  277.                         if(i>lastIndex)break;
  278.                     case "continue":
  279.                         if(parentNode.querySelector("[hasqueried]").getAttribute("hasqueried")=="true")break;
  280.                     default:
  281.                         parentNode.lastChild.previousSibling.previousSibling.replaceWith(cardIncomeNode);
  282.                         parentNode.lastChild.previousSibling.replaceWith(AvgPriceNode);
  283.                         parentNode.lastChild.replaceWith(cardCountNode);
  284.                         queryArray.push(
  285.                             setTimeout(
  286.                                 getCardInfo,
  287.                                 (queryCount + 1) * interval + Math.random() * 1000,
  288.                                 apps.children[i].dataset.appid,
  289.                                 cardLink,
  290.                                 status,
  291.                                 i,
  292.                                 parseInt(priceNode.dataset.sort)
  293.                             )
  294.                         );
  295.                         queryCount++;
  296.                         break;
  297.                 }

  298.             }
  299.         }

  300.     }
  301. })();

  302. //查询线程
  303. async function getCardInfo(appid, infoNode, status = "start", index = 0, appPrice = 699)
  304. {
  305.     var retryTime = 1;
  306.     var queryUrl = `https://steamcommunity.com/market/search?category_cardborder=cardborder_0&category_item_class=item_class_2&appid=753&category_Game=app_${appid}`;
  307.     infoNode.setAttribute("href",queryUrl);
  308.     infoNode.setAttribute("target","_blank");
  309.     infoNode.appendChild(document.createTextNode("读取中..."));
  310.     infoNode.setAttribute("hasQueried","loading");
  311.     if(status=="retryError")infoNode.setAttribute("hasQueried","error");
  312.     GM_xmlhttpRequest
  313.     (
  314.         {
  315.             method: "GET",
  316.             url: queryUrl,
  317.             timeout: timeOut,
  318.             onload: getData,
  319.             ontimeout: timeout,
  320.             onerror: error
  321.         }
  322.     );
  323.     //更新上一次查询位置
  324.     if(index>lastIndex)lastIndex=index;
  325.     if(status=="retryError" && lastErrorIndex==index)
  326.     {
  327.         document.getElementById("abort_card_query").innerText="继续";
  328.         lastErrorIndex = -1;
  329.     }
  330.     if(lastIndex==document.querySelector("tbody").childElementCount-1)document.getElementById("abort_card_query").innerText="查询完成";

  331.     //获取结果
  332.     function getData(res)
  333.     {
  334.         try
  335.         {
  336.             //转换为DOM
  337.             let domparser = new DOMParser();
  338.             let doc = domparser.parseFromString(res.responseText, "text/html");

  339.             //市场返回错误页面
  340.             if((doc.title.search("错误") != -1) || (doc.title.toLowerCase().search("error") != -1))
  341.             {
  342.                 infoNode.textContent="";
  343.                 infoNode.style.color="red";
  344.                 infoNode.appendChild(document.createTextNode("请求过于频繁"));
  345.                 infoNode.setAttribute("hasQueried","error");
  346.                 errorNum++;
  347.                 lastErrorIndex=index;
  348.                 setRetry();
  349.                 return;
  350.             }
  351.             // Steam 搜索页已改版,不再从当前页面解析钱包国家
  352.             var steamDBCountry = null;

  353.             if (isSteamDB) {
  354.                 steamDBCountry = document
  355.                     .querySelector("#DataTables_Table_0 > thead img")
  356.                     .src
  357.                     .replace(/.*\//, "")
  358.                     .replace(".svg", "")
  359.                     .toUpperCase();

  360.                 // steamCountry 由 checkLoginStatus() 提前获取
  361.                 if (steamCountry != null) {
  362.                     isSameCountry = (steamDBCountry == steamCountry);
  363.                 }

  364.                 $("#show_pure_income").toggleClass("disabled", !isSameCountry);
  365.             }

  366.             // 获取所有卡牌价格(新版市场)
  367.             var prices = [...doc.querySelectorAll("span")]
  368.             .filter(x => x.textContent.trim().startsWith("起价:"));

  369.             // 卡牌数量直接取价格数量
  370.             var cardCount = prices.length;
  371.             var avgPrice = 0;
  372.             var parentNode = infoNode.parentNode;

  373.             //有卡
  374.             if(cardCount>0)
  375.             {
  376.                 var firstPriceText = prices[0].textContent;

  377.                 // 起价:UAH 6.00 -> UAH
  378.                 var currencyMatch = firstPriceText.match(/起价:\s*([^\d]+)/);

  379.                 var steamCurrency = {
  380.                     currency: currencyMatch ? currencyMatch[1].trim() + " " : "",
  381.                     position: "front"
  382.                 };
  383.                 var sum = 0;
  384.                 var max = 0;
  385.                 var priceArray = new Array();
  386.                 //获取总价
  387.                 for(var i=0;i<prices.length;i++)
  388.                 {
  389.                     function parsePrice(text) {
  390.                         // 起价:UAH 6.00 -> 600
  391.                         const m = text.match(/([\d.,]+)\s*$/);
  392.                         if (!m) return 0;

  393.                         return Math.round(
  394.                             parseFloat(m[1].replace(",", ".")) * 100
  395.                         );
  396.                     }

  397.                     var curPrice = parsePrice(prices[i].textContent);
  398.                     priceArray[i] = curPrice;
  399.                     if(curPrice>max)max = curPrice;
  400.                     sum += curPrice;
  401.                 }
  402.                 //如果取中位数
  403.                 if(isSteamDB && document.getElementById("use_medium").checked)
  404.                 {
  405.                     priceArray.sort(function(a,b){return a-b;});
  406.                     avgPrice = ((priceArray[Math.floor(priceArray.length/2)] + priceArray[Math.floor((priceArray.length-1)/2)])/200).toFixed(2);
  407.                 }
  408.                 //如果忽略最高价
  409.                 else if(isSteamDB && document.getElementById("ignore_highest").checked)avgPrice = ((sum-max)/100.0/(prices.length-1)).toFixed(2);
  410.                 //取平均
  411.                 else avgPrice = (sum/100.0/prices.length).toFixed(2);
  412.                 var income = (calcfee(avgPrice*100)*Math.ceil(cardCount/2)/100).toFixed(2);
  413.                 var pureIncome = (income - appPrice / 100.0).toFixed(2);
  414.                 infoNode.textContent="";
  415.                 if(isSteamDB)
  416.                 {
  417.                     var appNode = parentNode.parentNode;
  418.                     parentNode.dataset.sort = income;
  419.                     parentNode.dataset.sortpure = pureIncome;
  420.                     parentNode.nextSibling.dataset.sort = avgPrice;
  421.                     parentNode.nextSibling.nextSibling.dataset.sort = cardCount;
  422.                     if(isSameCountry)
  423.                     {
  424.                         if(pureIncome > 0)infoNode.style.color="#5bfd00";
  425.                         if(steamDBCurrency.currency!=null)steamCurrency=steamDBCurrency;
  426.                     }
  427.                     if(steamCurrency.position=="back")
  428.                     {
  429.                         infoNode.innerHTML+=`${(isSameCountry&&showPureIncome)?pureIncome:income}${steamCurrency.currency}`;
  430.                         parentNode.nextSibling.innerHTML+=`${avgPrice}${steamCurrency.currency}`;
  431.                     }
  432.                     else
  433.                     {
  434.                         infoNode.innerHTML+=`${steamCurrency.currency}${(isSameCountry&&showPureIncome)?pureIncome:income}`;
  435.                         parentNode.nextSibling.innerHTML+=`${steamCurrency.currency}${avgPrice}`;
  436.                     }
  437.                     parentNode.nextSibling.nextSibling.innerHTML+=`${cardCount}`;
  438.                 }
  439.                 else infoNode.innerHTML+=`${cardCount}张<br>均价${steamCurrency.currency}${avgPrice}<br>预计税后收入${steamCurrency.currency}${income}`;
  440.                 infoNode.setAttribute("hasQueried","true");
  441.                 successNum++;
  442.             }
  443.             else if(doc.querySelector(".market_listing_table_message")!=null&&doc.querySelector(".market_listing_table_message").innerHTML.match(/(出错|Error)/i)!=null)
  444.             {
  445.                 infoNode.textContent="";
  446.                 infoNode.style.color="red";
  447.                 infoNode.appendChild(document.createTextNode("请求过于频繁"));
  448.                 infoNode.setAttribute("hasQueried","error");
  449.                 errorNum++;
  450.                 lastErrorIndex=index;
  451.                 setRetry();
  452.             }
  453.             //卡牌数量为0,同时重试次数也为0
  454.             else if(retryTime==0)
  455.             {
  456.                 infoNode.textContent="";
  457.                 infoNode.style.color="yellow";
  458.                 infoNode.appendChild(document.createTextNode("未查询到卡牌信息"));
  459.                 infoNode.setAttribute("hasQueried","true");
  460.                 noInfoNum++;
  461.                 setRetry();
  462.             }
  463.             //卡牌数量为0,重试
  464.             else
  465.             {
  466.                 setTimeout
  467.                 (
  468.                     GM_xmlhttpRequest,
  469.                     interval,
  470.                     {
  471.                         method: "GET",
  472.                         url: queryUrl,
  473.                         timeout: timeOut,
  474.                         onload: getData,
  475.                         ontimeout: timeout,
  476.                         onerror: error
  477.                     }
  478.                 );
  479.                 retryTime--;
  480.             }

  481.         }catch(e)
  482.         {
  483.             infoNode.textContent="";
  484.             infoNode.style.color="red";
  485.             infoNode.appendChild(document.createTextNode("解析结果出错"));
  486.             infoNode.setAttribute("hasQueried","error");
  487.             errorNum++;
  488.             lastErrorIndex=index;
  489.             console.log(e);
  490.             setRetry();
  491.         }
  492.     }


  493.     function error()
  494.     {
  495.         infoNode.textContent="";
  496.         infoNode.style.color="red";
  497.         infoNode.appendChild(document.createTextNode("查询出错"));
  498.         infoNode.setAttribute("hasQueried","error");
  499.         errorNum++;
  500.         lastErrorIndex=index;
  501.         setRetry();
  502.     }

  503.     function timeout()
  504.     {
  505.         infoNode.textContent="";
  506.         infoNode.style.color="red";
  507.         infoNode.appendChild(document.createTextNode("请求超时"));
  508.         infoNode.setAttribute("hasQueried","error");
  509.         errorNum++;
  510.         lastErrorIndex=index;
  511.         setRetry();
  512.     }

  513.     function setRetry()
  514.     {
  515.         var retryA = document.createElement("a");
  516.         retryA.appendChild(document.createTextNode("点击重试"));
  517.         retryA.setAttribute("href","javascript:void(0);");
  518.         retryA.addEventListener
  519.         (
  520.             "click",
  521.             function()
  522.             {
  523.                 if(infoNode.getAttribute("hasqueried")=="error")errorNum--;
  524.                 else noInfoNum--;
  525.                 infoNode.innerHTML="";
  526.                 infoNode.removeAttribute("style");
  527.                 var parentNode = infoNode.parentNode;
  528.                 parentNode.innerHTML="";
  529.                 parentNode.appendChild(infoNode);
  530.                 getCardInfo(appid, infoNode, "start", index, appPrice);
  531.             }
  532.         );
  533.         if(infoNode.parentNode.dataset.sort!==undefined)infoNode.parentNode.appendChild(document.createElement("br"));
  534.         infoNode.parentNode.appendChild(retryA);
  535.     }
  536. }

  537. //计算手续费
  538. function calcfee(p){
  539.     var pnofee = Math.max(Math.floor(p/1.15),1);
  540.     var vfee = Math.max(Math.floor(pnofee*0.1),1);
  541.     var pfee = Math.max(Math.floor(pnofee*0.05),1);
  542.     var i = 0;
  543.     while((pnofee + vfee + pfee) != p && i < 100) {
  544.         if((pnofee + vfee + pfee) > p) {
  545.             pnofee--;
  546.         }
  547.         if((pnofee + vfee + pfee) < p) {
  548.             pnofee++;
  549.         }
  550.         vfee = Math.max(Math.floor(pnofee*0.1),1);
  551.         pfee = Math.max(Math.floor(pnofee*0.05),1);
  552.         i++;
  553.     }
  554.     return pnofee;
  555. }

  556. //排序
  557. var ascend = false;
  558. var col = 0;
  559. function sort(column)
  560. {
  561.     if(document.querySelector(".card_income")==null)return;
  562.     if(column == col)ascend = !ascend;
  563.     else ascend = false;
  564.     col = column;


  565.     var table = document.querySelector("tbody");
  566.     var appWithCard = new Array();
  567.     var appWithoutCard = new Array();
  568.     var i = 0;
  569.     for(i = 0;i<table.childElementCount;i++)
  570.     {
  571.         if(table.children[i].querySelector(".card_income")==null||table.children[i].querySelector(".card_income").dataset.sort==0)appWithoutCard.push(table.children[i]);
  572.         else appWithCard.push(table.children[i]);
  573.     }

  574.     appWithCard.sort(compare);

  575.     for(i = 0;i<appWithCard.length;i++)table.appendChild(appWithCard[i]);
  576.     for(i = 0;i<appWithoutCard.length;i++)table.appendChild(appWithoutCard[i]);

  577.     var header = document.querySelectorAll("[class=sorting_desc],[class=sorting_asc]");
  578.     for(i = 0;i<header.length;i++)header[i].setAttribute("class","sorting");
  579.     var curHeader;

  580.     switch(column)
  581.     {
  582.         case 0:
  583.             curHeader = document.querySelector("[aria-label^=' CardIncome']");
  584.             curHeader.setAttribute("class","sorting_" + (ascend ? "asc" : "desc"));
  585.             curHeader.setAttribute("aria-label"," CardIncome: activate to sort column " + (ascend ? "ascending" : "descending"));
  586.             break;
  587.         case 1:
  588.             curHeader = document.querySelector("[aria-label^=' AvgPrice']");
  589.             curHeader.setAttribute("class","sorting_" + (ascend ? "asc" : "desc"));
  590.             curHeader.setAttribute("aria-label"," AvgPrice: activate to sort column " + (ascend ? "ascending" : "descending"));
  591.             break;
  592.         case 2:
  593.             curHeader = document.querySelector("[aria-label^=' Count']");
  594.             curHeader.setAttribute("class","sorting_" + (ascend ? "asc" : "desc"));
  595.             curHeader.setAttribute("aria-label"," Count: activate to sort column " + (ascend ? "ascending" : "descending"));
  596.             break;
  597.         default:
  598.             break;
  599.     }

  600.     function compare(a,b)
  601.     {
  602.         var res = 0;
  603.         switch(col)
  604.         {
  605.             case 0:
  606.                 res = (isSameCountry&&showPureIncome)? (a.querySelector(".card_income").dataset.sortpure - b.querySelector(".card_income").dataset.sortpure) : (a.querySelector(".card_income").dataset.sort - b.querySelector(".card_income").dataset.sort);
  607.                 break;
  608.             case 1:
  609.                 res = a.querySelector(".card_avgprice").dataset.sort - b.querySelector(".card_avgprice").dataset.sort;
  610.                 break;
  611.             case 2:
  612.                 res = a.querySelector(".card_count").dataset.sort - b.querySelector(".card_count").dataset.sort;
  613.                 break;
  614.             default:
  615.                 break;
  616.         }
  617.         return res * (ascend ? 1 : -1);
  618.     }
  619. }


  620. //屏蔽悬浮窗
  621. function blockHover(isBlocked)
  622. {
  623.     if(isBlocked)
  624.     {
  625.         hover = document.getElementById("js-hover");
  626.         document.getElementById("js-hover").remove();
  627.     }
  628.     else
  629.     {
  630.         document.body.appendChild(hover);
  631.     }
  632. }

  633. function showIncome(showPureIncome)
  634. {
  635.     if(!isSameCountry)
  636.     {
  637.         alert("steamdb和steam社区货币不同,该功能无法使用!");
  638.         return;
  639.     }
  640.     var incomeArea = document.getElementsByClassName("card_income");
  641.     if(incomeArea.length == 0)return;
  642.     for(var i=0;i<incomeArea.length;i++)if(incomeArea[i].children[0].getAttribute("hasqueried")=="true")incomeArea[i].children[0].innerHTML = incomeArea[i].children[0].innerHTML.replace(/[-]?[0-9]{1,}[.\d]?[0-9]*/,showPureIncome? `${incomeArea[i].dataset.sortpure}`:`${incomeArea[i].dataset.sort}`);
  643. }

  644. function getSteamDBCurrency(){
  645.     let priceList = document.querySelectorAll("#DataTables_Table_0 > tbody td:nth-child(5)");
  646.     let i = -1;
  647.     let currency = {"currency":null,"position":null};
  648.     try{
  649.         do{
  650.             i++;
  651.             if(priceList[i].innerHTML.match(/^[^0-9]+/)!=null){
  652.                 currency.currency = priceList[i].innerHTML.match(/^[^0-9]+/)[0];
  653.                 currency.position = "front";
  654.             }
  655.             else{
  656.                 currency.currency = priceList[i].innerHTML.match(/[^0-9]+$/)[0];
  657.                 currency.position = "back";
  658.             }
  659.         }
  660.         while(i<priceList.length&&priceList[i].dataset.sort==='0')
  661.     }
  662.     catch(e){
  663.         //layer.msg("获取steamDB货币时出现错误");
  664.         console.log(e);
  665.     }
  666.     return currency;
  667. }

  668. function checkLoginStatus(){
  669.     GM_xmlhttpRequest
  670.     (
  671.         {
  672.             method: "GET",
  673.             url: "https://steamcommunity.com/market/",
  674.             timeout: timeOut,
  675.             onload: function(res){
  676.                 //转换为DOM
  677.                 let domparser = new DOMParser();
  678.                 let doc = domparser.parseFromString(res.responseText, "text/html");
  679.                 if(doc.querySelector("#account_pulldown")!=null){
  680.                     document.getElementById("loginInfo").style.color="rgb(91, 253, 0)";
  681.                     document.getElementById("loginInfo").innerText=`社区已登录:${doc.querySelector("#account_pulldown").innerText.replace(/[\n\t]/g,"")}`;
  682.                     document.getElementById("loginInfo").href = doc.querySelector("#global_actions > a").href;
  683.                     steamCountry = res.responseText.match(/"wallet_country":"([A-Za-z]+)"/);
  684.                     if(steamCountry==null)console.log("未找到Steam社区货币");
  685.                     else steamCountry=steamCountry[1];
  686.                 }
  687.                 else{
  688.                     document.getElementById("loginInfo").style.color="red";
  689.                     document.getElementById("loginInfo").innerText="社区未登录×";
  690.                     document.getElementById("loginInfo").href = "https://steamcommunity.com";
  691.                 }
  692.             },
  693.             ontimeout: err,
  694.             onerror: err
  695.         }
  696.     );

  697.     function err(){
  698.         document.getElementById("loginInfo").style.color="red";
  699.         document.getElementById("loginInfo").innerText="社区连接失败×";
  700.         document.getElementById("loginInfo").href = "https://steamcommunity.com";
  701.         //layer.msg("社区连接失败,请检查加速器是否启动");
  702.     }
  703. }

  704. function setFilter(){
  705.     let url = "https://steamdb.info/sales/?displayOnly=Game&min_reviews=0&tagid=-1003823&min_rating=0&min_discount=0&category=29";
  706.     if(steamCountry!=null)url+=`&cc=${steamCountry.toLowerCase()}`;
  707.     url+="#setFilter";
  708.     location.href = url;
  709. }

复制代码

回复

使用道具 举报

浏览本版块需要:
1. 初阶会员或更高等级;
2. (点击此处)绑定Steam账号
您需要登录后才可以回帖 登录 | 注册

本版积分规则

欢迎发帖参与讨论 o(*≧▽≦)ツ,请注意
1. 寻求帮助或答案的帖子请发到问题互助版块,悬赏有助于问题解决的速度。发错可能失去在该板块发布主题的权限(了解更多
2. 表达观点可以,也请务必注意语气和用词,以免影响他人浏览,特别是针对其他会员的内容。如觉得违规可使用举报功能 交由管理人员处理,请勿引用对方的内容。
3. 开箱晒物交易中心游戏互鉴福利放送版块请注意额外的置顶版规。
4. 除了提问帖和交易帖以外,不确认发在哪个版块的帖子可以先发在谈天说地

  作为民间站点,自 2004 年起为广大中文 Steam 用户提供技术支持与讨论空间。历经二十余载风雨,如今已发展为国内最大的正版玩家据点。

列表模式 · · 微博 · Bilibili频道 · Steam 群组 · 贴吧 · QQ群 
Keylol 其乐 ©2004-2026 Chinese Steam User Fan Site.
Designed by Lee in Balestier, Powered by Discuz!
推荐使用 ChromeMicrosoft Edge 来浏览本站
广告投放|手机版|广州数趣信息科技有限公司 版权所有|其乐 Keylol ( 粤ICP备17068105号 )
GMT+8, 2026-7-1 02:20
快速回复 返回顶部 返回列表