您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Enhance Steam app pages with data from VNDB.
// ==UserScript== // @name VNDB Steam Enhancer // @namespace https://vndb.org/ // @version 0.1 // @description Enhance Steam app pages with data from VNDB. // @author Midori Kochiya // @match https://store.steampowered.com/app/* // @icon https://www.google.com/s2/favicons?sz=64&domain=steampowered.com // @grant GM_xmlhttpRequest // @connect api.vndb.org // @run-at document-end // @license MIT // ==/UserScript== (function() { 'use strict'; const LENGTH_MAP = { 1: "Very short", 2: "Short", 3: "Medium", 4: "Long", 5: "Very long" }; function formatMinutes(minutes) { if (minutes < 60) { return "" + minutes + "m"; } return "" + Math.floor(minutes / 60) + "h" + (minutes % 60) + "m"; } // From SteamDB var CurrentAppID; function GetAppIDFromUrl( url ) { const appid = url.match( /\/(?:app|sub|bundle|friendsthatplay|gamecards|recommended|widget)\/(?<id>[0-9]+)/ ); return appid ? parseInt( appid.groups.id, 10 ) : -1; } function GetCurrentAppID() { if( !CurrentAppID ) { CurrentAppID = GetAppIDFromUrl( location.pathname ); } return CurrentAppID; } function makeRow(rowClass, subtitle, linkText, linkUrl) { const row = document.createElement("div"); row.className = "dev_row " + rowClass; const subtitleEl = document.createElement("div"); subtitleEl.className = 'subtitle column'; subtitleEl.textContent = subtitle; let linkEl; if (linkUrl) { linkEl = document.createElement("a"); linkEl.className = "date"; linkEl.textContent = linkText; linkEl.href = linkUrl; } else { linkEl = document.createElement("div"); linkEl.className = "date"; linkEl.textContent = linkText; } row.appendChild(subtitleEl); row.appendChild(linkEl); return row; } let appId = GetCurrentAppID(); if (appId == -1) { return; } GM_xmlhttpRequest({ method: "POST", url: "https://api.vndb.org/kana/vn", data: JSON.stringify({ "filters": ["release", "=", ["extlink", "=", ["steam", appId]]], "fields": "length,length_votes,length_minutes,rating,votecount" }), headers: { "Content-Type": "application/json" }, onload: function(response) { let result = JSON.parse(response.responseText); if (!result.results || result.results.length == 0) { return; } let item = result.results[0]; const vndbIdRow = makeRow( "vndb_id", "VNDB", item.id, "https://vndb.org/" + item.id ); const rows = [ vndbIdRow, ]; if (item.rating) { rows.push(makeRow( "vndb_rating", "VNDB Rating", "" + item.rating + " (" + item.votecount + ")" )); } if (item.length) { let lengthText = LENGTH_MAP[item.length]; if (item.length_minutes && item.length_votes) { lengthText += " (" + formatMinutes(item.length_minutes) + " from " + item.length_votes + " votes)"; } rows.push(makeRow( "vndb_length", "VNDB Length", lengthText )); } // Reverse due to how they are inserted rows.reverse(); const releaseDate = document.querySelector('.release_date'); if( releaseDate ){ for (const el of rows) { releaseDate.parentNode.insertBefore(el, releaseDate.nextSibling); } } else { const firstDevRow = document.querySelector( '.glance_ctn_responsive_left .dev_row' ); if(firstDevRow) { for (const el of rows) { firstDevRow.parentNode.insertBefore(el, firstDevRow); } } } } }); })();