SteamClientInfoBoxManage

隐藏"Steam个人游戏列表"页的客户端和下载信息,附加游戏列表排序功能

当前为 2021-10-04 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         SteamClientInfoBoxManage
// @namespace    http://tampermonkey.net/
// @version      0.9
// @description  隐藏"Steam个人游戏列表"页的客户端和下载信息,附加游戏列表排序功能
// @author       澪羽
// @match        https://steamcommunity.com/id/*/games/*
// @icon         data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
// @grant        GM_setValue
// @grant        GM_getValue
// ==/UserScript==

const iGameContainer = "games_list_row_container" // all games container div
const iGameList = "games_list_rows" // all games div
const cActiveBackground = "gameListItemActive" // 活动状态背景
const iClientInfo = "clientConnBlock" // 客户端计算机相关信息
const cDiskStatus = "clientConnItemBlock" // 磁盘信息和下载图标
const cAppInstalled = "gameListItemInstalled" // 客户端已安装

var gDefaultSortApps = getApps()
var gSortApps = new Array()
var gDiskStatus = document.querySelectorAll('.' + cDiskStatus)
var gmSettings = { "SortTypeIndex": 1, "DisplayClientInfo": true, "DisplayActiveBackground": true, "DisplayDiskStatus": true, "DisplayDownloadIcon": true }

function getApps() {
    let aNodeList = document.getElementById(iGameList).childNodes
    let ret = Array.prototype.slice.call(aNodeList, 0)
    return ret.slice(1, ret.length)
}

function getAppName(DOM) {
    return DOM.childNodes[2].childNodes[1].childNodes[1].childNodes[1].innerText
}

function getTimeRecord(DOM) {
    return DOM.childNodes[2].childNodes[1].childNodes[1].childNodes[3].innerText
}

function getPlaytime(s) {
    var ret = 0.00
    let aString = s.split(" ")
    if (aString[0].includes(",")) {
        let aLeft = aString[0].split(",")
        let sLeft = aLeft.join('')
        ret = parseFloat(sLeft)
    } else {
        ret = parseFloat(aString[0])
    }
    return ret
}

function rerenderAppList() {
    for (let i = 0; i < gSortApps.length; i++) {
        document.getElementById(iGameList).appendChild(gSortApps[i].DOM)
    }

    return
}

function sortAndRerender(sFieldName, sSortDirection) {
    switch (sSortDirection) {
        case "DESC":
            gSortApps.sort(compareDESC(sFieldName))
            break
        case "ASC":
            gSortApps.sort(compareASC(sFieldName))
            break
    }
    rerenderAppList()

    return
}

function defaultSortAndRerender() {
    for (let i = 0; i < gDefaultSortApps.length; i++) {
        document.getElementById(iGameList).appendChild(gDefaultSortApps[i])
    }

    return
}

function getFieldName(s) {
    return (s.split("_"))[0]
}

function getSortDirection(s) {
    return (s.split("_"))[1]
}

function initSortTypeSelect(dParent) {
    var dSortTypeArea = document.createElement('div')

    let lSortType = document.createElement('label')
    lSortType.innerText = "排序方式 "

    let sSortType = document.createElement('select')
    const sDefaultSort = "Default_Sort"
    const sPlaytimeDESC = "Playtime_DESC"
    const sPlaytimeASC = "Playtime_ASC"
    const sNameDESC = "Name_DESC"
    const sNameASC = "Name_ASC"
    sSortType.options.add(new Option("Default Sort(默认排序)", sDefaultSort))
    sSortType.options.add(new Option("Playtime DESC(时间降序)", sPlaytimeDESC))
    sSortType.options.add(new Option("Playtime ASC(时间升序)", sPlaytimeASC))
    sSortType.options.add(new Option("Name DESC(名称降序)", sNameDESC))
    sSortType.options.add(new Option("Name ASC(名称升序)", sNameASC))
    sSortType.setAttribute('id', "SortType")
    sSortType.onchange = function () {
        let self = document.getElementById("SortType")
        let sFieldName = getFieldName(self.value)
        let sSortDirection = getSortDirection(self.value)
        switch (self.value) {
            case sDefaultSort:
                defaultSortAndRerender()
                break
            case sPlaytimeDESC: case sPlaytimeASC: case sNameDESC: case sNameASC:
                sortAndRerender(sFieldName, sSortDirection)
                break
            default:
                console.log("unknown SortType:" + self.value)
                return
        }
        GM_setValue("SortTypeIndex", self.selectedIndex)
    }
    sSortType.selectedIndex = gmSettings.SortTypeIndex

    dSortTypeArea.appendChild(lSortType)
    dSortTypeArea.appendChild(sSortType)
    dParent.appendChild(dSortTypeArea)

    return
}

function displayClientInfo(bHide) {
    GM_setValue("DisplayClientInfo", bHide)
    if (bHide) {
        document.getElementById(iClientInfo).style.display = 'none'
    } else {
        document.getElementById(iClientInfo).style.display = 'block'
    }

    return
}

function displayActiveBackground(bHide) {
    GM_setValue("DisplayActiveBackground", bHide)
    if (bHide) {
        for (let i = 0; i < gSortApps.length; i++) {
            if (gSortApps[i].ActiveBackgroundFlag) {
                let sAppClass = gSortApps[i].DOM.getAttribute('class')
                sAppClass = sAppClass.replace(cActiveBackground, "")
                gSortApps[i].DOM.setAttribute('class', sAppClass)
            }
        }
    } else {
        for (let i = 0; i < gSortApps.length; i++) {
            if (gSortApps[i].ActiveBackgroundFlag) {
                let sAppClass = gSortApps[i].DOM.getAttribute('class')
                sAppClass = sAppClass.concat(" " + cActiveBackground)
                gSortApps[i].DOM.setAttribute('class', sAppClass)
            }
        }
    }

    return
}

function displayDiskStatus(bHide) {
    GM_setValue("DisplayDiskStatus", bHide)
    if (bHide) {
        for (let i = 0; i < gDiskStatus.length; i++) {
            gDiskStatus[i].childNodes[1].style.display = 'none'
        }
    } else {
        for (let i = 0; i < gDiskStatus.length; i++) {
            gDiskStatus[i].childNodes[1].style.display = 'block'
        }
    }

    return
}

function displayDownloadIcon(bHide) {
    GM_setValue("DisplayDownloadIcon", bHide)
    if (bHide) {
        for (let i = 0; i < gDiskStatus.length; i++) {
            let aDownloadInfo = gDiskStatus[i].childNodes
            if ((aDownloadInfo.length) >= 5) {
                aDownloadInfo[3].style.display = 'none'
            }
        }
    } else {
        for (let i = 0; i < gDiskStatus.length; i++) {
            let aDownloadInfo = gDiskStatus[i].childNodes
            if ((aDownloadInfo.length) >= 5) {
                aDownloadInfo[3].style.display = 'block'
            }
        }
    }

    return
}

function initSettingCheckbox(dParent) {
    var dCheckboxArea = document.createElement('div')

    let dClientInfo = document.createElement('div')
    let cClientInfo = document.createElement('input')
    cClientInfo.setAttribute('type', 'checkbox')
    cClientInfo.setAttribute('id', "ClientInfo")
    cClientInfo.onclick = function () {
        let self = document.getElementById("ClientInfo")
        displayClientInfo(self.checked)
    }
    cClientInfo.checked = gmSettings.DisplayClientInfo
    dClientInfo.appendChild(cClientInfo)
    let tClientInfo = document.createTextNode("Hide Client Info(隐藏客户端信息框)")
    dClientInfo.appendChild(tClientInfo)

    let dActiveBackground = document.createElement('div')
    let cActiveBackground = document.createElement('input')
    cActiveBackground.setAttribute('type', 'checkbox')
    cActiveBackground.setAttribute('id', "ActiveBackground")
    cActiveBackground.onclick = function () {
        let self = document.getElementById("ActiveBackground")
        displayActiveBackground(self.checked)
    }
    cActiveBackground.checked = gmSettings.DisplayActiveBackground
    dActiveBackground.appendChild(cActiveBackground)
    let tActiveBackground = document.createTextNode("Hide Active Background(隐藏活动中游戏的背景颜色条)")
    dActiveBackground.appendChild(tActiveBackground)

    let dDiskStatus = document.createElement('div')
    let cDiskStatus = document.createElement('input')
    cDiskStatus.setAttribute('type', 'checkbox')
    cDiskStatus.setAttribute('id', "DiskStatus")
    cDiskStatus.onclick = function () {
        let self = document.getElementById("DiskStatus")
        displayDiskStatus(self.checked)
    }
    cDiskStatus.checked = gmSettings.DisplayDiskStatus
    dDiskStatus.appendChild(cDiskStatus)
    let tDiskStatus = document.createTextNode("Hide Disk Status(隐藏磁盘占用信息)")
    dDiskStatus.appendChild(tDiskStatus)

    let dDownloadIcon = document.createElement('div')
    let cDownloadIcon = document.createElement('input')
    cDownloadIcon.setAttribute('type', 'checkbox')
    cDownloadIcon.setAttribute('id', "DownloadIcon")
    cDownloadIcon.onclick = function () {
        let self = document.getElementById("DownloadIcon")
        displayDownloadIcon(self.checked)
    }
    cDownloadIcon.checked = gmSettings.DisplayDownloadIcon
    dDownloadIcon.appendChild(cDownloadIcon)
    let tDownloadIcon = document.createTextNode("Hide Download Icon(隐藏下载图标)")
    dDownloadIcon.appendChild(tDownloadIcon)

    dCheckboxArea.appendChild(dClientInfo)
    dCheckboxArea.appendChild(dActiveBackground)
    dCheckboxArea.appendChild(dDiskStatus)
    dCheckboxArea.appendChild(dDownloadIcon)
    dParent.appendChild(dCheckboxArea)

    return
}

function initSettingArea() {
    // root dom
    var dRootDiv = document.createElement('div')

    // todo:展开/收起功能设置区域+(文字描述or分隔线)
    var dHeader = document.createElement('div')
    initSortTypeSelect(dHeader)

    // 选项
    var dSettingArea = document.createElement('div')
    initSettingCheckbox(dSettingArea)

    dRootDiv.appendChild(dHeader)
    dRootDiv.appendChild(dSettingArea)
    let dGameContainer = document.getElementById(iGameContainer)
    let dParent = dGameContainer.parentNode
    dParent.insertBefore(dRootDiv, dGameContainer)

    return
}

function loadStorageConfig() {
    if (!(typeof (GM_getValue("SortTypeIndex")) == 'undefined')) {
        gmSettings.SortTypeIndex = GM_getValue("SortTypeIndex")
    }

    if (!(typeof (GM_getValue("DisplayClientInfo")) == 'undefined')) {
        gmSettings.DisplayClientInfo = GM_getValue("DisplayClientInfo")
    }
    displayClientInfo(gmSettings.DisplayClientInfo)

    if (!(typeof (GM_getValue("DisplayActiveBackground")) == 'undefined')) {
        gmSettings.DisplayActiveBackground = GM_getValue("DisplayActiveBackground")
    }

    if (!(typeof (GM_getValue("DisplayDiskStatus")) == 'undefined')) {
        gmSettings.DisplayDiskStatus = GM_getValue("DisplayDiskStatus")
    }
    displayDiskStatus(gmSettings.DisplayDiskStatus)

    if (!(typeof (GM_getValue("DisplayDownloadIcon")) == 'undefined')) {
        gmSettings.DisplayDownloadIcon = GM_getValue("DisplayDownloadIcon")
    }
    displayDownloadIcon(gmSettings.DisplayDownloadIcon)

    return
}

(function () {
    'use strict';

    // Your code here...
    loadStorageConfig()
    initSettingArea()

    for (let i = 0; i < gDefaultSortApps.length; i++) {
        let dNode = { "ActiveBackgroundFlag": false, "Playtime": 0.00 }

        // ActiveBackground初始化
        let sAppClass = gDefaultSortApps[i].getAttribute('class')
        if (sAppClass.indexOf(cActiveBackground) != -1) {
            dNode.ActiveBackgroundFlag = true
            if (gmSettings.DisplayActiveBackground) {
                sAppClass = sAppClass.replace(cActiveBackground, "")
                gDefaultSortApps[i].setAttribute('class', sAppClass)
            }
        }

        dNode.DOM = gDefaultSortApps[i]
        dNode.Name = getAppName(gDefaultSortApps[i])
        let sTimeRecord = getTimeRecord(gDefaultSortApps[i])
        if (!(sTimeRecord == "")) {
            dNode.Playtime = getPlaytime(sTimeRecord)
        }

        gSortApps.push(dNode)
    }

    if (gmSettings.SortTypeIndex > 0) {
        let sSortType = document.getElementById("SortType")
        let sFieldName = getFieldName(sSortType.options[gmSettings.SortTypeIndex].value)
        let sSortDirection = getSortDirection(sSortType.options[gmSettings.SortTypeIndex].value)
        sortAndRerender(sFieldName, sSortDirection)
    }

    return
})();

function compareDESC(sFieldName) {
    return function (a, b) {
        let v1 = (a[sFieldName])
        let v2 = (b[sFieldName])
        if (v1 < v2) {
            return 1
        }
        if (v1 > v2) {
            return -1
        }
        return 0
    }
}

function compareASC(sFieldName) {
    return function (a, b) {
        let v1 = a[sFieldName]
        let v2 = b[sFieldName]
        if (v1 < v2) {
            return -1
        }
        if (v1 > v2) {
            return 1
        }
        return 0
    }
}