您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
ASF bot list trade matcher
当前为
// ==UserScript== // @name ASF STM // @language English // @namespace https://gf.qytechs.cn/users/2205 // @description ASF bot list trade matcher // @include http*://steamcommunity.com/id/*/badges // @include http*://steamcommunity.com/id/*/badges/ // @include http*://steamcommunity.com/profiles/*/badges // @include http*://steamcommunity.com/profiles/*/badges/ // @version 1.0 // @connect asf.justarchi.net // @grant GM.xmlhttpRequest // @grant GM_xmlhttpRequest // ==/UserScript== /* global g_steamID */ (function() { const limiter = 0; const debug = false; const maxErrors = 5; let errors=0; let bots; let assets=[]; let descriptions=[]; let mybadges=[]; let userbadges=[]; let maxpages; function debugProfile(name){ if (debug) { console.time(name); } } function debugProfileEnd(name){ if (debug) { console.timeEnd(name); } } function debugPrint(msg){ if (debug) { console.log(msg); } } function getPartner(str) { return (BigInt(str)%BigInt(4294967296)).toString(); // eslint-disable-line } function EnableButton(){ let buttondiv=document.getElementById("asf_stm_button_div"); buttondiv.setAttribute("class","profile_small_header_additional"); let button=document.getElementById("asf_stm_button"); button.addEventListener("click",ButtonPressed, false); } function DisableButton(){ let buttondiv=document.getElementById("asf_stm_button_div"); buttondiv.setAttribute("class","profile_small_header_additional btn_disabled"); let button=document.getElementById("asf_stm_button"); button.removeEventListener("click",ButtonPressed, false); } function UpdateMessage(text){ let message=document.getElementById("asf_stm_message"); message.textContent=text; } function HideMessage(){ let messagebox=document.getElementById("asf_stm_messagebox"); messagebox.setAttribute("style","display: none;"); } function HideThrobber(){ let throbber=document.getElementById("throbber"); throbber.setAttribute("style","display: none;"); } function UpdateProgress(index){ let bar=document.getElementById("asf_stm_progress"); let progress = 100*((index+1)/bots.length); bar.setAttribute("style","width: "+progress+"%;"); } function populateCards(item) { let classlist = ""; let htmlCards = ""; for (let j=0;j<item.cards.length; j++) { let item_icon = item.cards[j].icon_url; let item_name = item.cards[j].item.substring(item.cards[j].item.indexOf("-")+1); for (let k=0; k<item.cards[j].count; k++) { if (classlist!=""){ classlist+=";"; } classlist+=item.cards[j].class; let cardTemplate =` <div class="showcase_slot"> <img class="image-container" src="https://steamcommunity-a.akamaihd.net/economy/image/${item_icon}/98x115"> <div class="commentthread_subscribe_hint" style="width: 98px;">${item_name}</div> </div> `; htmlCards+=cardTemplate; } } return {"htmlCards":htmlCards,"classlist": classlist}; } function getClasses(item){ let classes=""; for (let j=0;j<item.cards.length; j++) { for (let k=0; k<item.cards[j].count; k++) { if (classes!=""){ classes+=";"; } classes+=item.cards[j].class; } } return classes; } function UpdateTrade(row) { let index=row.id.split("_")[1]; let tradelink = row.getElementsByClassName("full_trade_url")[0]; let spliturl=tradelink.href.split("&"); let them = ""; let you = ""; let filterWidget = document.getElementById("asf_stm_filters"); for (let i = 0; i < bots[index].itemsToSend.length; i++){ let appid=bots[index].itemsToSend[i].appid; let checkbox=filterWidget.getElementsBySelector("#astm_"+appid)[0]; if (checkbox.checked) { if (you!=""){ you+=";"; } you=you+getClasses(bots[index].itemsToSend[i]); if (them!=""){ them+=";"; } them=them+getClasses(bots[index].itemsToReceive[i]); } } spliturl[3]="them="+them; spliturl[4]="you="+you; tradelink.href=spliturl.join("&"); } function CheckRow(row){ debugPrint("CheckRow"); let matches = row.getElementsByClassName("badge_row"); let visible = false; for (let i=0; i<matches.length;i++) { if (matches[i].parentElement.visible()){ visible = true; break; } } if (visible) { row.show(); UpdateTrade(row); } else { row.hide(); } } function AddMatchRow(index,botname){ debugPrint("AddMatchRow "+index); let itemsToSend=bots[index].itemsToSend; let itemsToReceive=bots[index].itemsToReceive; let tradeurl="https://steamcommunity.com/tradeoffer/new/?partner="+getPartner(bots[index].steam_id)+"&token="+bots[index].trade_token+"&source=stm"; let globalyou=""; let globalthem=""; let matches = ""; let any = ""; if (bots[index].match_everything==1) { any=` <sup><span class="avatar_block_status_in-game" style="font-size: 8px; cursor:help" title="This bots trades for any cards within same set"> ANY </span></sup>`; } for (let i=0;i<itemsToSend.length;i++) { let appid = itemsToSend[i].appid; let itemToReceive = itemsToReceive.find(a => a.appid == appid); let gameName = itemsToSend[i].title; let display = "inline-block"; //remove placeholder let filterWidget = document.getElementById("asf_stm_filters"); let placeholder = filterWidget.getElementsBySelector("#asf_stm_placeholder"); if (placeholder.length!=0) { placeholder[0].remove(); } //add filter let checkboxes=filterWidget.getElementsBySelector("#astm_"+appid); if (checkboxes.length==0) { let newFilter=`<span style="margin-right: 15px; white-space: nowrap; display: inline-block;"><input type="checkbox" id="astm_${appid}" checked="">${gameName}</span>` let spanTemplate = document.createElement('template'); spanTemplate.innerHTML = newFilter.trim(); filterWidget.appendChild(spanTemplate.content.firstChild); } else { if (checkboxes[0].checked == false){ display = "none" } } let sendResult = populateCards(itemsToSend[i]); let receiveResult = populateCards(itemToReceive); let tradeurlappid=tradeurl+"&them="+receiveResult.classlist+"&you="+sendResult.classlist; let matchTemplate = ` <div class="asf_stm_appid_${appid}" style="display:${display}"> <div class="badge_row is_link goo_untradable_note showcase_slot"> <div class="notLoggedInText"> <img alt="${gameName}" src="https://steamcdn-a.akamaihd.net/steam/apps/${appid}/capsule_184x69.jpg"> <div> <div title="View badge progress for this game"> <a target="_blank" href="https://steamcommunity.com/my/gamecards/${appid}/">${gameName}</a> </div> </div> <div class="btn_darkblue_white_innerfade btn_medium"> <span> <a href="${tradeurlappid}" target="_blank" rel="noopener">Offer a trade</a> </span> </div> </div> <div class="showcase_slot"> <div class="showcase_slot profile_header"> <div class="badge_info_unlocked profile_xp_block_mid avatar_block_status_in-game badge_info_title badge_row_overlay" style="height: 15px;">You</div> ${sendResult.htmlCards} </div> <span class="showcase_slot badge_info_title booster_creator_actions"> <h1>➡</h1> </span> </div> <div class="showcase_slot profile_header"> <div class="badge_info_unlocked profile_xp_block_mid avatar_block_status_online badge_info_title badge_row_overlay ellipsis" style="height: 15px;"> ${botname} </div> ${receiveResult.htmlCards} </div> </div> </div> `; if (checkboxes.length==0 || checkboxes[0].checked) { matches+=matchTemplate; if (globalyou!=""){ globalyou+=";"; }; globalyou+=sendResult.classlist; if (globalthem!=""){ globalthem+=";"; }; globalthem+=receiveResult.classlist } } let tradeurlfull = tradeurl+"&them="+globalthem+"&you="+globalyou; let rowTemplate = ` <div id="asfstmbot_${index}" class="badge_row"> <div class="badge_row_inner"> <div class="badge_title_row guide_showcase_contributors"> <div class="badge_title_stats"> <div class="btn_darkblue_white_innerfade btn_medium"> <span> <a class="full_trade_url" href="${tradeurlfull}" target="_blank" rel="noopener" >Offer a trade for all</a> </span> </div> </div> <div class="badge_title"> ${botname}${any} </div> </div> <div class="badge_title_rule"></div> ${matches} </div> </div> `; let template = document.createElement('template'); template.innerHTML = rowTemplate.trim(); let maincontent = document.getElementsByClassName("maincontent")[0]; let newchild = template.content.firstChild; maincontent.appendChild(newchild); CheckRow(newchild); } function DeepClone(object) { return JSON.parse(JSON.stringify(object)); } function fetchinventory(steamid,startasset,callback) { let url="https://steamcommunity.com/inventory/"+steamid+"/753/6?l=english&count=5000&l=english"; if (startasset>0) { url=url+"&start_assetid="+startasset.toString(); } else { assets.clear(); descriptions.clear(); } debugPrint(url); let xhr = new XMLHttpRequest(); xhr.open('GET', url, true); xhr.responseType = 'json'; xhr.onload = function() { debugPrint("..."); let status = xhr.status; let lastasset=startasset; if (status === 200) { errors = 0; if (typeof(xhr.response) !== 'undefined') { if (typeof(xhr.response.descriptions) !== 'undefined') { assets=assets.concat(xhr.response.assets); descriptions=descriptions.concat(xhr.response.descriptions); if (typeof(xhr.response.last_assetid) == 'undefined') { //end of inventory debugPrint("total_inventory_count = "+xhr.response.total_inventory_count); callback(); return; } else { lastasset=xhr.response.last_assetid; } } } } else { errors++; debugPrint("HTTP Error="+status); } if (status==403) { assets.clear(); //switch to next bot callback(); } else if ((status<400 || status>=500 || status==408)&&(errors <= maxErrors)) { setTimeout((function(steamid,startasset,callback) { return function(){ fetchinventory(steamid,startasset,callback); };})(steamid,lastasset,callback), limiter); } else { UpdateMessage("Error getting inventory, ERROR "+status); HideThrobber(); EnableButton(); } } xhr.onerror = function() { errors++; if (errors <= maxErrors) { setTimeout((function(steamid,startasset,callback) { return function(){ fetchinventory(steamid,startasset,callback); };})(steamid,startasset,callback), limiter); } else { debugPrint("error getting inventory"); UpdateMessage("Error getting inventory"); HideThrobber(); EnableButton(); } } xhr.send(); } function CalcState(badge) { //state 0 - less than max sets; state 1 - we have max sets, even out the rest, state 2 - all even let state = 0; if (badge.cards[0].count == badge.lastset) { return 2; //nothing to do } else if (badge.cards[badge.maxcards-1].count == badge.maxsets) { return 1; //max sets are here, but we can distribute cards further } return 0; //less than max sets } function CompareCards(index,callback) { let itemsToSend=[]; let itemsToReceive=[]; userbadges.clear(); userbadges = DeepClone(mybadges); for (let i = 0; i < userbadges.length; i++) { userbadges[i].cards.clear(); } PopulateExistingCards(userbadges,false); debugPrint("bot's cards"); debugPrint(DeepClone(userbadges)); debugPrint("our cards"); debugPrint(DeepClone(mybadges)); for(let i = 0; i < userbadges.length; i++) { let mybadge = DeepClone(mybadges[i]); let theirbadge = DeepClone(userbadges[i]); let mystate=CalcState(mybadge); while (mystate<2) { let foundmatch=false; for (let j = 0; j<theirbadge.maxcards; j++) { //index of card they give if (theirbadge.cards[j].count > 0) { //try to match //if (bots[index].match_everything) {} let myInd = mybadge.cards.findIndex(a => a.item == theirbadge.cards[j].item); //index of slot where we receive card if (myInd==-1) { debugPrint("we don't have it"); let empty = mybadge.cards.find(card => card.item==null); if (empty != undefined) { debugPrint("found a place!"); empty.item=theirbadge.cards[j].item; empty.icon_url=theirbadge.cards[j].icon_url; myInd=mybadge.cards.indexOf(empty); } else { debugPrint("Error! We found more cards than expected"); debugPrint(DeepClone(mybadge.cards)); debugPrint(DeepClone(theirbadge.cards)); } } if ((mystate==0 && mybadge.cards[myInd].count < mybadge.maxsets) || (mystate==1 && mybadge.cards[myInd].count < mybadge.lastset)) { //we need this ^Kfor the Emperor debugPrint("we need this: "+theirbadge.cards[j].item+" ("+theirbadge.cards[j].count+")"); //find a card to match. for (let k = 0; k < myInd; k++) { //index of card we give debugPrint("i="+i+" j="+j+" k="+k+" mystate="+mystate); debugPrint("we have this: "+mybadge.cards[k].item+" ("+mybadge.cards[k].count+")"); if ((mystate==0 && mybadge.cards[k].count>mybadge.maxsets) || (mystate==1 && mybadge.cards[k].count>mybadge.lastset)) { //that's fine for us debugPrint("it's a good trade for us"); let theirInd = theirbadge.cards.findIndex(a => a.item == mybadge.cards[k].item); //index of slot where they will receive card if (theirInd == -1) { //they don't even know this card theirInd = theirbadge.cards.findIndex(a => a.item == null); //index of empty space //it's safe to assign item name to this card, they don't have it theirbadge.cards[theirInd].item = mybadge.cards[k].item; } if (bots[index].match_everything==0) { //make sure it's neutral+ for them if (theirbadge.cards[theirInd].count >= theirbadge.cards[j].count) { debugPrint("Not fair for them") debugPrint("they have this: "+theirbadge.cards[theirInd].item+" ("+theirbadge.cards[theirInd].count+")"); continue; //it's not neutral+, check other options } } debugPrint("it's a match!"); let itemToSend = {"item":mybadge.cards[k].item,"count":1, "class":mybadge.cards[k].class, "icon_url":mybadge.cards[k].icon_url}; let itemToReceive = {"item":theirbadge.cards[j].item,"count":1, "class":theirbadge.cards[j].class, "icon_url":theirbadge.cards[j].icon_url}; //fill items to send let sendmatch = itemsToSend.find(item => item.appid == mybadges[i].appid); if (sendmatch == undefined) { let newmatch = {"appid":mybadges[i].appid, "title":mybadge.title ,"cards":[ itemToSend ]}; itemsToSend.push(newmatch); } else { let existingCard = sendmatch.cards.find(a => a.item == itemToSend.item); if (existingCard == undefined) { sendmatch.cards.push(itemToSend); } else { existingCard.count += 1; } } //add this item to their inventory theirbadge.cards[theirInd].count +=1; //remove this item from our inventory mybadge.cards[k].count -= 1; //fill items to receive let receivematch = itemsToReceive.find(item => item.appid == mybadges[i].appid); if (receivematch == undefined) { let newmatch = {"appid":mybadges[i].appid,"title":mybadge.title,"cards":[ itemToReceive ]}; itemsToReceive.push(newmatch); } else { let existingCard = sendmatch.cards.find(a => a.item == itemToReceive.item); if (existingCard == undefined) { receivematch.cards.push(itemToReceive); } else { existingCard.count += 1; } } //add this item to our inventory mybadge.cards[myInd].count +=1; //remove this item from their inventory theirbadge.cards[j].count -= 1; foundmatch=true; break; //found a match! } } } } } if (!foundmatch) { break; //found no matches - move to next badge } mybadge.cards.sort((a,b)=>b.count-a.count); theirbadge.cards.sort((a,b)=>b.count-a.count); mystate=CalcState(mybadge); } } debugPrint("items to send"); debugPrint(DeepClone(itemsToSend)); debugPrint("items to receive"); debugPrint(DeepClone(itemsToReceive)); bots[index].itemsToSend = itemsToSend; bots[index].itemsToReceive = itemsToReceive; if (itemsToSend.length>0){ getUsername(index,callback); } else { debugPrint("no matches"); callback(); } } function getUsername(index,callback){ let url="https://steamcommunity.com/profiles/"+bots[index].steam_id+"?xml=1"; let xhr = new XMLHttpRequest(); xhr.open('GET', url, true); xhr.responseType = 'text'; //xhr.setRequestHeader("Range","bytes=0-200"); //fuck it, get the whole page xhr.onload = function() { let status = xhr.status; let username=bots[index].steam_id; debugPrint("getting username"); if (status === 200) { errors = 0; let re = /<steamID><!\[CDATA\[(.+)]]><\/steamID>/g; username = re.exec(xhr.response)[1]; debugPrint(username); AddMatchRow(index,username); callback(); } else { errors++; if (errors <= maxErrors) { setTimeout((function(index,callback) {return function(){ getUsername(index,callback); } })(index,callback), limiter); } else { debugPrint("error HTTP Status="+status); UpdateMessage("Error getting username data, ERROR="+status); HideThrobber(); EnableButton(); } } }; xhr.onerror = function() { errors++; if (errors <= maxErrors) { setTimeout((function(index,callback) {return function(){ getUsername(index,callback); } })(index,callback), limiter); } else { debugPrint("error"); UpdateMessage("Error getting username data"); HideThrobber(); EnableButton(); } }; xhr.send(); } function checkuser(index){ debugPrint(index); UpdateMessage("Fetching bot "+(index+1).toString()+" of "+bots.length.toString()); UpdateProgress(index); fetchinventory(bots[index].steam_id,0,function() { debugPrint(bots[index].steam_id); debugPrint(assets.length); CompareCards(index, function() { if (index<bots.length-1) { setTimeout((function(index) { return function(){ checkuser(index); };})(index+1), limiter); } else { debugPrint("finished"); debugPrint(new Date(Date.now())); console.log(new Date(Date.now())); HideThrobber(); HideMessage(); UpdateProgress(bots.length-1); EnableButton(); } }); }); } function PopulateExistingCards(badges, filter){ debugProfile("PopulateExistingCards1"); debugPrint(DeepClone(assets)); debugPrint(DeepClone(descriptions)); descriptions=descriptions.filter(desc=>badges.find(item=>item.appid==desc.market_hash_name.split("-")[0])!=undefined); assets=assets.filter(asset=>descriptions.find(item=>item.classid==asset.classid)!=undefined); for (let i = 0; i < assets.length; i++){ debugPrint("."); let descr = descriptions.find(desc=>desc.classid==assets[i].classid); // eslint-disable-line if (descr != undefined) { let appid=descr.market_hash_name.split("-")[0]; let title=appid; let game_tag=descr.tags.find(tag=>tag.category=="Game"); if (game_tag != undefined) { title=game_tag.localized_tag_name; } let item_class_tag=descr.tags.find(tag=>tag.category=="item_class"); if (item_class_tag != undefined) { if (item_class_tag.internal_name == "item_class_2") { let cardborder_tag=descr.tags.find(tag=>tag.category=="cardborder"); if (cardborder_tag != undefined) { if (cardborder_tag.internal_name == "cardborder_0") { let badge = badges.find(badge=>badge.appid==appid); if (badge != undefined) { let card=badge.cards.find(card=>card.item==descr.market_hash_name); if (card == undefined) { let newcard = {"item":descr.market_hash_name, "count":1,"class": assets[i].classid ,"icon_url":descr.icon_url}; badge.cards.push(newcard); badge.title = title; } else { card.count+=1; } } } } } } } } debugProfileEnd("PopulateExistingCards1"); debugProfile("PopulateExistingCards2"); for (let i = badges.length-1; i >=0; i--) { for (let j = badges[i].cards.length; j < badges[i].maxcards; j++){ badges[i].cards.push({"item":null, "count":0,"class":0, "icon_url":null}); //fill missing cards with dummy element } badges[i].cards.sort((a,b)=>b.count-a.count); if (filter) { if (badges[i].cards[0].count-badges[i].cards[badges[i].cards.length-1].count<2) { //nothing to match, remove from list. badges.splice(i,1); continue; } } let totalcards = 0; for (let j = 0; j<badges[i].maxcards; j++) { totalcards+=badges[i].cards[j].count; } badges[i].maxsets = Math.floor(totalcards/badges[i].maxcards); badges[i].lastset = Math.ceil(totalcards/badges[i].maxcards); } debugProfileEnd("PopulateExistingCards2"); } function PopulateMaxcards(index){ while (index < mybadges.length) { if (mybadges[index].maxcards === 0) { let url="https://steamcommunity.com/my/gamecards/"+mybadges[index].appid+"?l=english"; let xhr = new XMLHttpRequest(); xhr.open('GET', url, true); xhr.responseType = 'document'; xhr.onload = function() { // eslint-disable-line let status = xhr.status; let lastasset=0; if (status === 200) { errors = 0; debugPrint("processing badge "+mybadges[index].appid); UpdateMessage("Getting badge data for "+mybadges[index].appid); let maxcards = xhr.response.documentElement.getElementsByClassName("gamecard").length; mybadges[index].maxcards=maxcards; index++; } else { errors++; } if ((status<400 || status>=500)&&(errors <= maxErrors)) { setTimeout((function(index) { return function(){ PopulateMaxcards(index); };})(index), limiter); } else { UpdateMessage("Error getting badge data, ERROR "+status); HideThrobber(); EnableButton(); } }; xhr.onerror = function() { // eslint-disable-line errors++; if (errors <= maxErrors) { setTimeout((function(index) { return function(){ PopulateMaxcards(index); };})(index), limiter); return; } else { debugPrint("error"); UpdateMessage("Error getting badge data"); HideThrobber(); EnableButton(); } }; xhr.send(); return; //do this synchronously to avoid rate limit } else { index++; } } debugPrint("populated"); UpdateMessage("Fetching own inventory"); //g_steamID is a global steam variable fetchinventory(g_steamID,0,function(){ debugPrint("fetched"); debugPrint(DeepClone(assets)); debugPrint(DeepClone(descriptions)); debugPrint("our cards"); debugPrint(DeepClone(mybadges)); PopulateExistingCards(mybadges,true); checkuser(0); }); } function getbadges(page){ let url="https://steamcommunity.com/my/badges?p="+page+"&l=english"; let xhr = new XMLHttpRequest(); xhr.open('GET', url, true); xhr.responseType = 'document'; xhr.onload = function() { let status = xhr.status; if (status === 200) { errors = 0; debugPrint("processing page "+page); UpdateMessage("Processing badges page "+page); if (page===1) { let pagelinks=xhr.response.documentElement.getElementsByClassName("pagelink"); if (pagelinks.length>0) { maxpages=Number(pagelinks[pagelinks.length-1].textContent.trim()); } } let badges=xhr.response.documentElement.getElementsByClassName("badge_row_inner"); for (let i=0;i<badges.length;i++){ if (badges[i].getElementsByClassName("owned").length>0){ //we only need badges where we have at least one card, and no special badges let appidNodes = badges[i].getElementsByClassName("card_drop_info_dialog"); if (appidNodes.length>0) { let appidText=appidNodes[0].getAttribute("id"); let appidSplitted = appidText.split("_"); if (appidSplitted.length >= 5) { let appid = Number(appidSplitted[4]); let maxcards=0; if (badges[i].getElementsByClassName("badge_craft_button").length === 0 ){ let maxcardsText=badges[i].getElementsByClassName("badge_progress_info")[0].innerText.trim() let maxcardsSplitted=maxcardsText.split(" "); maxcards = Number(maxcardsSplitted[2]); } let badge_stub = {"appid":appid,"title":null, "maxcards":maxcards, "maxsets":0, "lastset":0, "cards":[]}; mybadges.push(badge_stub); } } } } page++; } else { errors++; } if ((status<400 || status>=500)&&(errors <= maxErrors)) { if (page<=maxpages) { setTimeout((function(page) { return function(){ getbadges(page); };})(page), limiter); } else { debugPrint("all badge pages processed"); if (mybadges.length===0){ HideThrobber(); UpdateMessage("No cards to match"); return; } else { PopulateMaxcards(0); } } } else { UpdateMessage("Error getting badge data, ERROR "+status); HideThrobber(); EnableButton(); } }; xhr.onerror = function() { errors++; if (errors <= maxErrors) { setTimeout((function(page) { return function(){ getbadges(page); };})(page), limiter); } else { debugPrint("error getting badge page"); UpdateMessage("Error getting badge page"); HideThrobber(); EnableButton(); } }; xhr.send(); } function FilterEventHandler(event){ let appid = event.target.id.split("_")[1]; let matches = document.getElementsByClassName("asf_stm_appid_"+appid); for (let i = 0; i<matches.length; i++) { matches[i].style.display = event.target.checked ? "inline-block" : "none"; CheckRow(matches[i].parentElement.parentElement); } } function FiltersButton(){ let filterWidget = document.getElementById("asf_stm_filters"); if (filterWidget.style.marginRight == "-50%") { filterWidget.style.marginRight ="unset"; } else { filterWidget.style.marginRight ="-50%"; } } function ButtonPressed(){ DisableButton(); debugPrint(new Date(Date.now())); console.log(new Date(Date.now())); let maincontent = document.getElementsByClassName("maincontent")[0]; maincontent.textContent=""; maincontent.style.width="90%"; maincontent.innerHTML=` <div class="profile_badges_header"> <div id="throbber"> <div class="LoadingWrapper"> <div class="LoadingThrobber"> <div class="Bar Bar1"></div> <div class="Bar Bar2"></div> <div class="Bar Bar3"></div> </div> </div> </div> <div> <div id="asf_stm_messagebox" class="profile_badges_header"> <div id="asf_stm_message" class="profile_badges_header_title" style="text-align: center;">Initialization</div> </div> </div> <div class="profile_xp_block_remaining_bar"> <div id="asf_stm_progress" class="profile_xp_block_remaining_bar_progress" style="width: 0%"></div> </div> </div> <div id="asf_stm_filters" style="position: fixed; z-index: 1000; right: 5px; bottom: 45px; transition-duration: 500ms; transition-timing-function: ease; margin-right: -50%;padding: 5px;max-width: 40%;display: inline-block;border-radius: 2px;background: rgba( 103, 193, 245, 0.2 );color: #67c1f5;"> <span id="asf_stm_placeholder" style="margin-right: 15px;">No matches to filter</span> </div> <div style="position: fixed;z-index: 1000;right: 5px;bottom: 5px;" id="asf_stm_filters_button_div"> <a id="asf_stm_filters_button" class="btnv6_blue_hoverfade btn_medium"> <span>Filters</span> </a> </div> `; document.getElementById("asf_stm_filters").addEventListener("input",FilterEventHandler); document.getElementById("asf_stm_filters_button").addEventListener("click", FiltersButton, false); maxpages=1; getbadges(1); } if (document.getElementsByClassName("badge_details_set_favorite").length != 0) { let requestURL = 'https://asf.justarchi.net/Api/Bots'; GM_xmlhttpRequest({ method: "GET", url: requestURL, onload: function(response) { let re = /("steam_id":)(\d+)/g; let fixedjson = response.response.replace(re, '$1\"$2\"'); //because fuck js bots = JSON.parse(fixedjson); //bots.filter(bot=>bot.matchable_cards===1||bot.matchable_foil_cards===1); //I don't think this is really needed bots.sort(function(a,b) { //sort received array as I like it. let result = b.match_everything - a.match_everything; //bots with match_everything go first if (result===0) { result = b.items_count - a.items_count; //then by items_counts descending } if (result===0) { result = b.games_count - a.games_count; //then by games_count descending } return result; }); debugPrint ("found total "+bots.length+" bots"); let buttondiv =document.createElement("div"); buttondiv.setAttribute("class","profile_small_header_additional"); buttondiv.setAttribute("style","margin-top: 40px;"); buttondiv.setAttribute("id","asf_stm_button_div"); let button = document.createElement("a"); button.setAttribute("class","btnv6_blue_hoverfade btn_medium"); button.setAttribute("id","asf_stm_button"); button.appendChild(document.createElement("span")); button.firstChild.appendChild(document.createTextNode("Scan ASF STM")) buttondiv.appendChild(button); let anchor = document.getElementsByClassName("profile_small_header_texture")[0]; anchor.appendChild(buttondiv); EnableButton(); } }); } })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址