Steam | Display game languages

Display images of selected languages on store search steam page.

当前为 2024-01-01 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Steam | Display game languages
  3. // @name:uk Steam | Відобразити мови гри
  4. // @namespace http://tampermonkey.net/
  5. // @version 2.1.2024
  6. // @description Display images of selected languages on store search steam page.
  7. // @description:uk Виводить обрані мови (svg картинка) на сторінці пошуку ігр в steam.
  8. // @author Black_Yuzia
  9. // @match https://store.steampowered.com/search*
  10. // @icon https://store.steampowered.com/favicon.ico
  11. // @grant GM_addStyle
  12. // @grant GM_xmlhttpRequest
  13. // @grant GM.getValue
  14. // @grant GM.setValue
  15. // @grant GM.registerMenuCommand
  16. // @grant GM.notification
  17. // @run-at document-body
  18. // @license BY-NC-ND 4.0
  19. // @license-url https://creativecommons.org/licenses/by-nc-nd/4.0/
  20. // @compatible firefox
  21. // @compatible chrome
  22. // @compatible opera
  23. // @compatible safari
  24. // @compatible edge
  25. // @require https://code.jquery.com/jquery-3.7.1.slim.min.js
  26. // @connect localhost:1500
  27. // @connect tm.starserv.net
  28. // ==/UserScript==
  29.  
  30. (() => {
  31. // src/inject.ts
  32. var baseURL = "https://tm.starserv.net";
  33.  
  34. // src/index.ts
  35. // @license BY-NC-ND 4.0
  36. // @license-url https://creativecommons.org/licenses/by-nc-nd/4.0/
  37. (async function() {
  38. "use strict";
  39. GM_addStyle(`
  40. .mr-2 {
  41. margin-right: 2px
  42. }
  43. `);
  44. const baseURL2 = baseURL || "http://localhost:1500";
  45. const notification = await GM.getValue("notification", false);
  46. const languages = await GM.getValue("languages", ["ukrainian", "russian"]);
  47. console.log("lang", languages);
  48. if (!notification) {
  49. await GM.notification("Please choose languages in menu! Default lang: 'Ukrainian,\u0279ussian'", "Warning");
  50. }
  51. await GM.registerMenuCommand("Set Languages", async () => {
  52. const languages2 = prompt("Set language(s) [example: Ukrainian,English,\u0279ussian]");
  53. if (languages2) {
  54. await GM.setValue("notification", true);
  55. await GM.setValue("languages", languages2.split(",").map((v) => v.trim().toLowerCase()));
  56. }
  57. });
  58. const container = await waitForElement("#search_result_container");
  59. const observer = new MutationObserver(async (mutations) => {
  60. const elements = [];
  61. for (const mutate of mutations) {
  62. const e = mutate.target;
  63. if (e.className?.includes("search_result_row") && !e.className?.includes("tm_process")) {
  64. e.className += " tm_process";
  65. elements.push(e);
  66. }
  67. }
  68. if (elements.length > 0) {
  69. const ids = elements.map(parseGameID);
  70. GM_xmlhttpRequest({
  71. url: `${baseURL2}/steam/games/lang?id=${ids.join(",")}`,
  72. method: "GET",
  73. fetch: true,
  74. responseType: "json",
  75. onload(res) {
  76. if (res.status === 200) {
  77. const { response } = res;
  78. for (let i = 0; i < response.length; i++) {
  79. const items = response[i];
  80. if (items.length > 0) {
  81. for (const lang of languages) {
  82. if (items.includes(lang)) {
  83. const element = elements[i];
  84. const img = document.createElement("img");
  85. img.height = 20;
  86. img.width = 20;
  87. img.className = "mr-2";
  88. img.src = `https://fastdl.starserv.net/languages/${lang}@2x.svg`;
  89. const platforms = $(element).find(".platform_img").first().parent("div");
  90. platforms.append(img);
  91. }
  92. }
  93. }
  94. }
  95. }
  96. }
  97. });
  98. }
  99. });
  100. observer.observe(container, {
  101. childList: true,
  102. subtree: true
  103. });
  104. })();
  105. function waitForElement(selector) {
  106. let i = 0;
  107. return new Promise((resolve) => {
  108. if (document.querySelector(selector)) {
  109. return resolve(document.querySelector(selector));
  110. }
  111. const observer = new MutationObserver((mutations) => {
  112. if (document.querySelector(selector)) {
  113. observer.disconnect();
  114. resolve(document.querySelector(selector));
  115. }
  116. });
  117. observer.observe(document.body, {
  118. childList: true,
  119. subtree: true
  120. });
  121. });
  122. }
  123. function parseGameID(e) {
  124. const link = e.attributes.getNamedItem("href")?.value;
  125. const [id] = link.match(/\d+/) || [];
  126. return id;
  127. }
  128. })();