// ==UserScript==
// @name Semiauto Steam Discovery Queue
// @description something aid to accelerate steam discovery queue
// @author desc_inno
// @namespace https://github.com/desc70865/Semiauto-Steam-Discovery-Queue
// @supportURL https://github.com/desc70865/Semiauto-Steam-Discovery-Queue/issues
// @version 0.1.6
// @icon https://store.steampowered.com/favicon.ico
// @match https://store.steampowered.com/app/*
// @match https://store.steampowered.com/explore/*
// @match https://store.steampowered.com/agecheck/*
// @require https://cdn.staticfile.org/jquery/1.12.4/jquery.min.js
// ==/UserScript==
// default set https://store.steampowered.com/account/languagepreferences both simplified & traditional chinese before use
(function() {
'use strict';
window.onload = semiauto();
})();
function semiauto() {
var reg_error = /Failed to load queue|502 Bad Gateway/g,
flag_error = (reg_error).test(document.getElementsByTagName('html')[0].outerHTML); // 首先判断是否加载错误,如遇到错误直接刷新,一般两三次即可恢复
if(flag_error){ // may refresh can work better
window.location.reload(); // if error, refresh the page
};
var path = window.location.pathname.split('/'); // 根据路径选择分支
switch(path[1]) { // switch by path name
case 'explore':
var queue_length = $("div#discovery_queue")[0].childNodes.length; // rest items in queue
if(queue_length > 0){ // 检测队列剩余长度,如果仍有内容则添加按钮并等待用户操作
let button = createButton(),
reg_appid = /\d+/g;
document.getElementById('remove_button').addEventListener('click', function() {
let appid = document.getElementById("discovery_queue_start_link").href.match(reg_appid)[0];
clearAppInQueue(appid);
});
}else{ // 否则模拟点击并刷新生成新队列
let click = $("div.discover_queue_empty_refresh_btn")[0].getElementsByTagName("span")[0].click(),
t = setTimeout(window.location.reload(),3000);
};
break;
case 'app':
var flag_inqueue = (typeof($('.next_in_queue_content')[0]) != "undefined"),
flag_filter = titleMark(); // 在商店页首先运行标题修饰,返回过滤规则判断结果; 可单独在商店页运行 titleMark() 作为独立功能
if(flag_inqueue && flag_filter){ // current game in explore queue
try{ // 如果该游戏在队列中且符合过滤规则,开始自动下一个
$("#es_new_queue")[0].click(); // 尝试生成新队列
}catch(e){ // 正常点击下一个
$("div.btn_next_in_queue_trigger")[0].click();
};
};
// let t = setTimeout(backToExplore, 5000); // back to main page in 5 seconds
break;
case 'agecheck': // readability
/*
document.cookie = "wants_mature_content=1";
document.cookie = "birthtime=22503171";
window.open("https://store.steampowered.com/");
let t = setTimeout(window.location.reload(), 1500);
*/
break;
default:{ // 异常页面,返回主页
let t = setTimeout(backToExplore, 1500);
break;
};
};
};
function titleMark() { // add prefix & suffix to title if u need
let trade_card = cardDetect(), // if has trade cards
chinese_support = languageDetect(), // if supports simplified chinese or traditional chinese
tag_filter = tagsfilter(),
reviews_ratio = ratioDetect(),
this_year = new Date().getFullYear(),
release_year = releaseYearDetect();
if(( (trade_card + chinese_support + tag_filter) < 1 || reviews_ratio < 60 || release_year < (this_year - 10) ) && reviews_ratio < 90 && release_year < this_year ){ // some rules by costomize
return true; // 卡牌,语言支持,标签过滤得分至少为1且好评率>60且十年内发售 或 仅为今年的新游戏(也可能是尚未发售)或好评游戏 该规则的目的是探索新游戏并检测一些质量尚可的冷门游戏
};
return false;
};
function cardDetect() {
if((/Steam 集换式卡牌/g).test(document.body.innerText)){
$('.apphub_AppName')[0].innerHTML = "📇 " + $('.apphub_AppName')[0].innerText; // add emoji to prefix for mark
return 1;
};
return 0;
};
function languageDetect() { // 不支持默认语言时匹配"不支持",同时检测其他语言中包含的辅助语言
let flag_schinese = $('.game_language_options')[0].innerText.match(/不支持/g) == null,
flag_tchinese = $('.game_language_options')[0].innerText.match(/繁体中文/g) != null;
if(flag_schinese == true || flag_tchinese == true){
$('.apphub_AppName')[0].innerHTML = "🀄️ " + $('.apphub_AppName')[0].innerText; // add emoji to prefix for mark
return 1;
};
return 0;
};
function tagsfilter() {
let tags = $("div.popular_tags")[0].childNodes, // get tags
reg_include_tags = /免费/g, // tags you are interested in
reg_exclude_tags = /大师级|虚拟现实/g, // tags you dont want
flag_tag_in = tagsReg(tags, reg_include_tags),// if it has sth you need
flag_tag_ex = tagsReg(tags, reg_exclude_tags); // or just the opposite
return (flag_tag_in - flag_tag_ex); // range [-1,1]
};
function tagsReg(tags, reg) { // tag detector
for(let i = 1; i < 6 && i < tags.length; i++){ // search in top 5 tags
if(reg.test(tags[i].innerText)){
return 1;
};
};
return 0;
};
function ratioDetect() {
let rate_panel = $("div.user_reviews_summary_row"), // get reviews panel
last = rate_panel.length - 1; // if there is recent reviews, it should be 1, or just 0
if((/%/g).test(rate_panel[0].dataset.tooltipHtml)){ // sometimes there wont be enough reviews
let reviews_ratio = rate_panel[last].dataset.tooltipHtml.match(/\d+(?=%)/g), // overall percentage
reviews_total = rate_panel[last].dataset.tooltipHtml.replace(',','').match(/\d+(?= 篇)/g), // a space here / sum of reviews
reviews_positive = parseInt(reviews_total * reviews_ratio / 100);
$('.apphub_AppName')[0].innerHTML = $('.apphub_AppName')[0].innerText + " => ("+ reviews_positive + "/" + reviews_total + ") = " + reviews_ratio + "%☆"; // add rate to suffix for mark
return reviews_ratio;
};
return 60; // set the default value by 80 which should below threshold 90
};
function releaseYearDetect() {
try{
return document.getElementsByClassName('date')[0].innerHTML.match(/\d{4}/g).toString();
}catch(e){
return 2077
};
};
function backToExplore() { // return if error
window.location.href = "https://store.steampowered.com/explore/";
};
function clearAppInQueue(appid) { // core
$J.post('/app/'+appid, {sessionid: g_sessionID, appid_to_clear_from_queue: appid}).done(window.location.reload());
};
function createButton() { // create button for nextAppInQueue at "https://store.steampowered.com/explore/"
let buttonContainerDiv = document.createElement('div'),
buttonSpan = document.createElement('span');
// 设置移除按钮
buttonSpan.innerHTML = '移除当前游戏';
buttonSpan.setAttribute('style', 'padding: 0 15% 0 15%; font-size: 15px; line-height: 64px; color: #ffcc6a; font-family: "Motiva Sans", Sans-serif; font-weight: 300;')
buttonContainerDiv.setAttribute('id', 'remove_button');
buttonContainerDiv.setAttribute('class', 'next_in_queue_content');
buttonContainerDiv.setAttribute('style', 'background: url(/public/images/v6/app/queue_next_btn.png) top left no-repeat; width: 144px; height: 64px; cursor: pointer; background-size: 100% 200%; margin-bottom: -26px; margin-right: 0px; margin-top: -9px; float: right;');
// 并添加节点
buttonContainerDiv.appendChild(buttonSpan);
document.getElementsByClassName('discovery_queue_apps')[0].getElementsByClassName('discovery_queue_static')[0].insertAdjacentHTML('afterend', buttonContainerDiv.outerHTML);
return buttonContainerDiv;
};