auto run trough steam next fest discovery queue
// ==UserScript== // @name Steam New Queue AutoDiscover // @version 0.2 // @description auto run trough steam next fest discovery queue // @author gortik // @license MIT // @match https://store.steampowered.com/explore/ // @icon https://store.steampowered.com/favicon.ico // @grant none // @require https://cdn.jsdelivr.net/npm/[email protected]/dist/light/protobuf.min.js // @namespace https://greasyfork.org/users/968091 // ==/UserScript== var access_token, skipDelay = 300, //in ms newDiscoveryQueueModal; var jsonGetQueue = {"nested":{"getQueue":{"fields":{"appids":{"rule":"repeated","type":"int32","id":1,"options":{"packed":false}},"b":{"rule":"required","type":"string","id":2},"c":{"rule":"required","type":"string","id":3},"d":{"rule":"required","type":"int32","id":4},"e":{"rule":"required","type":"int32","id":5},"f":{"rule":"required","type":"int32","id":6}}}}}, jsonSkip = {"nested":{"skipAppid":{"fields":{"a":{"rule":"required","type":"int32","id":1},"appid":{"rule":"required","type":"int32","id":2},"in1":{"rule":"required","type":"In1","id":3}}},"In1":{"fields":{"in2":{"rule":"required","type":"In2","id":1}}},"In2":{"fields":{"a":{"rule":"required","type":"int32","id":1}}}}} function sleep(ms) { return new Promise(resolve => { console.log('Sleep: ' + ms/1000 + 's.'); setTimeout(resolve, ms) }); } function buffer2hex(buffer) { function i2hex(i) { return ('0' + i.toString(16)).slice(-2); } return Array.from(buffer).map(i2hex).join(' '); } function buffer2base64(buffer) { let str = buffer.reduce((acc, char) => acc + String.fromCharCode(char) , ''); return btoa(str); } async function getAccessToken() { //document.querySelector('#application_config').dataset.loyalty_webapi_token /*if (window.location.href.indexOf('steampowered') > -1) { } else if(window.location.href.indexOf('steamcommunity') > -1) { }*/ let response = await fetch('https://store.steampowered.com/points/shop'); let text = await response.text(); let match = text.match(/webapi_token":"([\d\w]+)"/); console.log('access_token: ' + match[1]); return match[1]; } //arrGet = [8, 168, 219, 83, 8, 170, 243, 117, 8, 204, 243, 66, 8, 150, 176, 126, 8, 172, 169, 127, 8, 186, 169, 111, 8, 196, 129, 126, 8, 170, 242, 104, 8, 250, 195, 118, 8, 160, 232, 119, 8, 178, 170, 71, 8, 150, 196, 116, 18, 2, 83, 75, 26, 0, 32, 68, 40, 0, 48, 0] //arrGet = [8, 242, 255, 90, 8, 178, 162, 107, 8, 232, 155, 100, 8, 244, 198, 81, 8, 158, 208, 105, 8, 178, 238, 115, 8, 212, 205, 105, 8, 138, 202, 57, 8, 238, 162, 77, 8, 130, 194, 70, 8, 208, 134, 123, 8, 174, 231, 125, 18, 2, 83, 75, 26, 0, 32, 12, 40, 0, 48, 0] //accepts base64 or Array or Uint8Array function decode(json, messageName, msg) { let root = protobuf.Root.fromJSON(json); let message = root.lookupType(messageName); let arr = []; //if msg is array or Uint8Array if (Array.isArray(msg) || ArrayBuffer.isView(msg)) arr = msg; else protobuf.util.base64.decode(protobufMsg, arr, 0) //let arr = new Uint8Array(X) //X = bytes needed return message.decode(arr); } //j = decode(jsonGetQueue, 'getQueue', arrGet) function createPayload(appid) { return { a: 1, appid: appid, in1: { in2: { a: 1235711 } } } } function encode(json, messageName, payload) { let root = protobuf.Root.fromJSON(json), message = root.lookupType(messageName); //var payload = { a: 1, appid: 987654, in1: { in2: { a: 1235711 } } }; let msg_to_send = message.create(payload); let buffer = message.encode(msg_to_send).finish(); return buffer2base64(buffer); } async function getQueue() { let body = { access_token: access_token, input_protobuf_encoded: 'CAESAlNLGAEwAWIGCgQI/7VL' }, url = 'https://api.steampowered.com/IStoreService/GetDiscoveryQueue/v1?' + new URLSearchParams(body).toString(), options = { "credentials":"omit", "headers":{ "accept":"application/json, text/plain, */*", "accept-language":"en-US,en;q=0.9", "sec-fetch-mode":"cors", "sec-fetch-site":"same-site" }, "referrer":"https://store.steampowered.com/sale/nextfest", "referrerPolicy":"no-referrer-when-downgrade", "body": null, "method": "GET", "mode":"cors" } let response = await fetch(url, options); let arrBuff = await response.arrayBuffer(); let uint8 = new Uint8Array(arrBuff); //let uint8 = Array.from(arrBuff); console.log(buffer2base64(uint8)); let json = decode(jsonGetQueue, 'getQueue', uint8) return json; } async function postSkip(protobufBase64) { let query = { access_token: access_token }, body = { input_protobuf_encoded: protobufBase64 }, url = 'https://api.steampowered.com/IStoreService/SkipDiscoveryQueueItem/v1?' + new URLSearchParams(query).toString(); let res = await fetch(url, { "headers": { "accept": "application/json, text/plain, */*", "accept-language": "en-US,en;q=0.9,sk;q=0.8,cs;q=0.7", // "content-type": "multipart/form-data; boundary=----WebKitFormBoundary5BetF1tNQduIif48", "content-type": "application/x-www-form-urlencoded", //"sec-ch-ua": "\";Not A Brand\";v=\"99\", \"Chromium\";v=\"88\"", //"sec-ch-ua-mobile": "?0", //"sec-fetch-dest": "empty", "sec-fetch-mode": "cors", "sec-fetch-site": "same-site" }, //"referrer": "https://store.steampowered.com/", //"referrerPolicy": "strict-origin-when-cross-origin", //"body": "------WebKitFormBoundary5BetF1tNQduIif48\r\nContent-Disposition: form-data; name=\"input_protobuf_encoded\"\r\n\r\nCAEQsqpHGgYKBAj/tUs=\r\n------WebKitFormBoundary5BetF1tNQduIif48--\r\n", "body": new URLSearchParams(body).toString(), "method": "POST", "mode": "cors", "credentials": "omit" }); let text = await res.text(); if (text == '') console.log('OK'); else console.log('') } async function skipAppids(appids) { let i = 0; for (let appid of appids) { console.log(appid); let payload = createPayload(appid); let payload_base64 = encode(jsonSkip, 'skipAppid', payload); await postSkip(payload_base64); newDiscoveryQueueModal.Dismiss(); newDiscoveryQueueModal = ShowBlockingWaitDialog('Exploring the queue...', 'Request ' + ++i + ' of ' + appids.length); await sleep(skipDelay); } console.log('Done'); } function showDoneDialog(queueTotal) { if (newDiscoveryQueueModal) newDiscoveryQueueModal.Dismiss(); newDiscoveryQueueModal = ShowConfirmDialog('Done', 'Queue has been explored ' + queueTotal + ' times', 'Open badge page') .done(function() { window.open('https://steamcommunity.com/my/badges/62', '_blank'); }); } function showGeneratingDialog(queueCount, queueTotal) { if (newDiscoveryQueueModal) newDiscoveryQueueModal.Dismiss(); newDiscoveryQueueModal = ShowBlockingWaitDialog('Generating the new queue...', 'Generating new discovery queue ' + queueCount + ' of ' + queueTotal); } async function skipQueues(queueTotal) { let queueCount = 0; access_token = access_token || await getAccessToken(); for (let i = 0; i < queueTotal; i++) { queueCount++; console.log('Queue #' + queueCount); showGeneratingDialog(queueCount, queueTotal); let json = await getQueue(); await sleep(1e3); await skipAppids(json.appids); } showDoneDialog(queueTotal); } function addHTML() { let parentElem = document.querySelector('.discovery_queue_customize_ctn'); parentElem.insertAdjacentHTML('afterend', '<div class="discovery_queue_customize_ctn"><div class="btnv6_blue_hoverfade btn_medium" id="js-new-queue-auto"><span>Auto discover new queue</span></div><span>Discover the queue 6 times to get the badge</span></div>') let button = document.getElementById('js-new-queue-auto'); button.addEventListener('click', function() { skipQueues(6); }, false ); } (function() { 'use strict'; addHTML(); })();