Hidden_DLC_Helper

显示Steam商店中隐藏的DLC(补丁)。

安装此脚本
作者推荐脚本

您可能也喜欢Steam快速添加购物车

安装此脚本
  1. // ==UserScript==
  2. // @name:zh-CN Steam隐藏DLC查询
  3. // @name Hidden_DLC_Helper
  4. // @namespace https://blog.chrxw.com
  5. // @supportURL https://blog.chrxw.com/scripts.html
  6. // @contributionURL https://afdian.net/@chr233
  7. // @version 1.8
  8. // @description 显示Steam商店中隐藏的DLC(补丁)。
  9. // @description:zh-CN 显示Steam商店中隐藏的DLC(补丁)。
  10. // @author Chr_
  11. // @include /https://store\.steampowered\.com\/app\/\d+/
  12. // @license AGPL-3.0
  13. // @icon https://blog.chrxw.com/favicon.ico
  14. // @grant GM_setClipboard
  15. // @grant GM_addStyle
  16. // ==/UserScript==
  17.  
  18.  
  19. (() => {
  20. "use strict";
  21. const appid = (window.location.pathname.match(/\/app\/(\d+)/) ?? [null, null])[1];
  22. if (appid === null) { return; }
  23. main();
  24. async function main() {
  25. let data = await getAppDetail(appid);
  26. let { dlc: dlc_list1 } = data;
  27. let dlc_list2 = getDLCsFromPage();
  28. if (dlc_list1 === null) {
  29. console.log("未找到DLC");
  30. return;
  31. }
  32. let hidden_dlcs = diffList(dlc_list1, dlc_list2);
  33. console.log(hidden_dlcs);
  34.  
  35. if (hidden_dlcs.length > 0) {
  36. showBtns(hidden_dlcs);
  37. }
  38. }
  39. //复制
  40. function setClipboard(data) {
  41. GM_setClipboard(data, "text");
  42. let dialog = ShowAlertDialog("复制成功", `复制内容: ${data}`, "确定");
  43. setTimeout(() => { dialog.Dismiss(); }, 1000);
  44. };
  45. //显示按钮
  46. function showBtns(appList = []) {
  47. function genBtn(name, foo) {
  48. let s = document.createElement("span");
  49. let a = document.createElement("a");
  50. a.innerText = name;
  51. s.className = "note hdh";
  52. s.appendChild(a);
  53. s.addEventListener("click", foo);
  54. return s;
  55. }
  56. const btnArea = document.querySelector("#gameAreaDLCSection>.gradientbg");
  57. btnArea.innerText = "此游戏的内容";
  58.  
  59. let btnCopyCmd = genBtn("复制ASF指令", () => {
  60. let cmd = "!addlicense a/" + appList.join(",a/");
  61. setClipboard(cmd);
  62. });
  63. btnArea.appendChild(btnCopyCmd);
  64. for (let app of appList) {
  65. let btn = genBtn(`${app}`, () => { showGameDetail(app); });
  66. btnArea.appendChild(btn);
  67. }
  68. }
  69. //显示App详情
  70. async function showGameDetail(app) {
  71. let data = await getAppDetail(app);
  72. let { name, is_free } = data;
  73. let href = `https://store.steampowered.com/app/${app}/`;
  74. if (is_free) {
  75. ShowConfirmDialog("", `<p>游戏名:${name} 【<a href=${href} target="_blank">商店链接</a>】</p>`, "启动Steam安装", "复制ASF入库代码")
  76. .then(() => {
  77. window.open(`steam://install/${app}`);
  78. })
  79. .fail((stats) => {
  80. if (stats) {
  81. setClipboard(`!addlicense a/${app}`);
  82. }
  83. });
  84. } else {
  85. let { price_overview: { final_formatted } } = data;
  86. ShowAlertDialog("", `<p>游戏名:${name} 【<a href=${href} target="_blank">商店链接</a>】</p><p>美区价格:${final_formatted}</p><p>非免费DLC无法直接入库</p>`, "确定");
  87. }
  88. }
  89.  
  90. //从API读取游戏信息
  91. function getAppDetail(appid) {
  92. return new Promise((resolve, reject) => {
  93. fetch(`https://store.steampowered.com/api/appdetails?appids=${appid}&l=english&cc=us`, { credentials: "omit" })
  94. .then(async (response) => {
  95. if (response.ok) {
  96. let json = await response.json();
  97. resolve(json[appid].data);
  98. } else {
  99. console.error(response.status);
  100. reject(response.status);
  101. }
  102. })
  103. .catch((err) => {
  104. console.error(err);
  105. reject(err);
  106. });
  107. });
  108. }
  109. //从页面读取所有DLC
  110. function getDLCsFromPage() {
  111. let DLCs = new Set();
  112. let dlc_list = document.querySelectorAll(".tableView>div>a");
  113. const regAppid = new RegExp(/dlc_row_(\d+)/);
  114. for (let dlc of dlc_list) {
  115. let match = dlc.id.match(regAppid);
  116. if (match) {
  117. let appid = parseInt(match[1]);
  118. DLCs.add(appid);
  119. }
  120. }
  121. return Array.from(DLCs);
  122. }
  123. //获取A与B补集的交集
  124. function diffList(listA, listB) {
  125. let listC = [];
  126. if (listA != undefined && listB != undefined) {
  127. for (let item of listA) {
  128. if (listB.indexOf(item) === -1) {
  129. listC.push(item);
  130. }
  131. }
  132. }
  133. return listC;
  134. }
  135. })();
  136. GM_addStyle(`
  137. .hdh:not(:first-child) {
  138. margin-right: 5px;
  139. }
  140. .hdh > a {
  141. cursor: pointer;
  142. }
  143. `);

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址