Adds steam info to games in the topics list
// ==UserScript==
// @name cs.rin Steam Info in Topics List
// @namespace none
// @version 1
// @description Adds steam info to games in the topics list
// @author odusi
// @match https://cs.rin.ru/forum/viewforum.php?f=10
// @match https://cs.rin.ru/forum/viewforum.php?f=10&start=*
// @match https://cs.rin.ru/forum/viewforum.php?f=22
// @match https://cs.rin.ru/forum/viewforum.php?f=22&start=*
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_addStyle
// @grant GM_xmlhttpRequest
// ==/UserScript==
const max_tags = 6
function promiseXHR(url, options) {
return new Promise((resolve, reject) => {
GM_xmlhttpRequest({
url,
...options,
onabort: (response) => {
reject(response);
},
onerror: (response) => {
reject(response);
},
ontimeout: (response) => {
reject(response);
},
onload: (response) => {
resolve(response.responseText);
},
})
})
}
GM_addStyle( //language=css
` .steaminfo-description {
font-size: 0.6rem;
color: #8dc1c1;
width: max-content
}
.steaminfo-tags {
font-size: 0.65rem;
color: #efb970;
}
`)
let errorTitles = GM_getValue('errorTitles', [])
const topicHeader = document.querySelectorAll("b.genmed")[location.href.includes('start=') && !location.href.endsWith('start=0') ? 2 : 3].closest('tr')
let curRow = topicHeader.nextElementSibling
const parser = new DOMParser()
const inMainForum = location.href.includes('f=10')
function errTitle(descElement, title) {
descElement.textContent = 'Failed to get steam info'
descElement.style.color = 'red'
errorTitles.push(title)
GM_setValue('errorTitles', errorTitles)
}
function setElementsProperties(id, description, tags, descElement, tagsElement) {
descElement.classList.add('steaminfo-description')
descElement.style.cursor = 'pointer'
descElement.textContent = 'Show Description'
descElement.addEventListener("click", () => {
descElement.style.width = '60%'
descElement.textContent = description + ' '
descElement.style.cursor = 'initial'
descElement.insertAdjacentHTML('beforeend', `<a href=https://store.steampowered.com/app/${id} style="color:#5093cf;">Steam</a>`)
})
tagsElement.classList.add('steaminfo-tags')
tagsElement.textContent = tags
}
while (curRow && !curRow.align) {
const topicRow = curRow.querySelector(':nth-child(2)')
let title
if (inMainForum) {
const titleQ = topicRow.querySelector('.topictitle :nth-child(3)') ?? topicRow.querySelector('.topictitle') // 2nd is for untagged topics
title = titleQ.tagName === 'SPAN' ? titleQ.nextSibling.nodeValue.replace(/[\[(].*?[\])]/g, '') /* remove brackets and their text */ .trim() : titleQ.innerText.trim()
} else {
title = topicRow.querySelector('.topictitle :nth-child(2)').nextSibling.nodeValue.replace(/[\[(].*?[\])]/g, '').replace('Series', '').trim()
}
curRow = curRow.nextElementSibling
if (errorTitles.includes(title)) continue
let {id, description, tags} = GM_getValue(title, {})
const descElement = document.createElement('p')
const tagsElement = document.createElement('p')
if (id) {
setElementsProperties(id, description, tags, descElement, tagsElement)
topicRow.append(descElement)
topicRow.append(tagsElement)
} else {
descElement.textContent = 'Getting steam info'
descElement.style.color = '#d6fd0f'
topicRow.append(descElement)
promiseXHR(`https://store.steampowered.com/search/?sort_by=_ASC&term=${title}`, {})
.then(text => {
const searchPage = parser.parseFromString(text, "text/html")
const firstResultLink = searchPage.querySelector("#search_resultsRows > a:nth-child(1)").href
promiseXHR(firstResultLink, {})
.then(text => {
const appPage = parser.parseFromString(text, "text/html")
try {
description = appPage.querySelector(".game_description_snippet").innerText.trim()
} catch (e) {
errTitle(descElement, title)
}
let tagList = []
appPage.querySelectorAll('.glance_tags a').forEach(tag => {
if (!tag.innerText.includes('Indie') && tagList.length < max_tags) tagList.push(tag.innerText.toLowerCase().trim())
})
tags = tagList.join(', ')
const id = /\d+/.exec(firstResultLink)[0]
GM_setValue(title, {id, description, tags})
setElementsProperties(id, description, tags, descElement, tagsElement)
descElement.style.removeProperty('color')
topicRow.append(tagsElement)
})
})
.catch(() => {
errTitle(descElement, title)
})
}
}