Greasy Fork

Greasy Fork is available in English.

SteampPY已拥有游戏标记

能够以不同的颜色在Steampy平台Cdkey市场上添加标记,包括已拥有,家庭库中及愿望单中

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

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         SteampPY已拥有游戏标记
// @namespace    https://space.bilibili.com/93654843
// @version      2024-08-09
// @description  能够以不同的颜色在Steampy平台Cdkey市场上添加标记,包括已拥有,家庭库中及愿望单中
// @author       FiNNiER
// @match        *://steampy.com/*
// @icon         https://steampy.com/img/logo.63413a4f.png
// @grant        GM_xmlhttpRequest
// @grant        GM_setValue
// @grant        GM_getValue
// @connect      api.steampowered.com
// @connect      store.steampowered.com
// @run-at       document-body
// ==/UserScript==

// ==颜色配置==
const ownedColor = '#0c8918'; //           已拥有
const wishlistColor = '#177cb0'; //         愿望单中
const familygameColor = '#ff8936'; //       家庭库中
const unownedColor = '#ff2e63'; //           未拥有
// ==颜色配置==

var Saves = {
  wishlist: [],
  ownedApps: [],
  familygameList: [],
};

(function () {
  'use strict';
  load();
  init();
  Start();
  observePageChanges();
})();

//读取个人库存及愿望单并储存
function getOwnAndWish() {
  return new Promise((resolve, reject) => {
    var wishlist = [];
    var ownedApps = [];
    GM_xmlhttpRequest({
      method: 'GET',
      url:
        'https://store.steampowered.com/dynamicstore/userdata/?t=' +
        Math.trunc(Date.now() / 1000),
      responseType: 'json',
      onload: function (response) {
        try {
          let data = JSON.parse(response.responseText);
          wishlist = data.rgWishlist;
          ownedApps = data.rgOwnedApps;
          let previousSaves = GM_getValue('Saves', {
            wishlist: [],
            ownedApps: [],
            familygameList: [],
          });
          let newSave = {
            wishlist: wishlist,
            ownedApps: ownedApps,
            familygameList: previousSaves.familygameList,
          };
          console.log(data);

          GM_setValue('Saves', newSave);
          resolve(newSave); // 成功时调用 resolve
        } catch (error) {
          reject(error); // 发生错误时调用 reject
        }
      },
      onerror: function (error) {
        reject(error); // 请求失败时调用 reject
      },
    });
  });
}

//读取家庭库并储存
function getFamilyGame() {
  return new Promise((resolve, reject) => {
    var access_token;
    var family_groupid;
    var familygameList = [];
    GM_xmlhttpRequest({
      method: 'GET',
      url: 'https://store.steampowered.com/pointssummary/ajaxgetasyncconfig',
      responseType: 'json',
      onload: function (response) {
        try {
          let data = JSON.parse(response.responseText);
          access_token = data.data.webapi_token; // access_token
          GM_xmlhttpRequest({
            method: 'GET',
            url: `https://api.steampowered.com/IFamilyGroupsService/GetFamilyGroupForUser/v1/?access_token=${access_token}`,
            responseType: 'json',
            onload: function (response) {
              try {
                let data = JSON.parse(response.responseText);
                family_groupid = data.response.family_groupid; // family_groupid
                GM_xmlhttpRequest({
                  method: 'GET',
                  url: `https://api.steampowered.com/IFamilyGroupsService/GetSharedLibraryApps/v1/?access_token=${access_token}&family_groupid=${family_groupid}&include_own=true`,
                  responseType: 'json',
                  onload: function (response) {
                    try {
                      let data = JSON.parse(response.responseText);
                      data.response.apps.forEach((app) => {
                        if (app.exclude_reason == 0) {
                          familygameList.push(app.appid);
                        }
                      });
                      let previousSaves = GM_getValue('Saves', {
                        wishlist: [],
                        ownedApps: [],
                        familygameList: [],
                      });
                      let newSave = {
                        wishlist: previousSaves.wishlist,
                        ownedApps: previousSaves.ownedApps,
                        familygameList: familygameList,
                      };
                      GM_setValue('Saves', newSave);
                      resolve(familygameList);
                    } catch (error) {
                      reject(error);
                    }
                  },
                  onerror: function (error) {
                    reject(error);
                  },
                });
              } catch (error) {
                reject(error);
              }
            },
            onerror: function (error) {
              reject(error);
            },
          });
        } catch (error) {
          reject(error);
        }
      },
      onerror: function (error) {
        reject(error);
      },
    });
  });
}

//脚本配置菜单
function init() {
  const settings = document.createElement('div');
  settings.innerHTML = `
    <div class="ml-20-rem">
      <div class="withdraw" id="settings">脚本设定</div>
    </div>
    <div id="popup-window" class="popup-window">
      <div class="popup-content">
        <span class="close-btn" id="close-popup">&times;</span>
        <h1>脚本设定</h1>
        <div id="loading" style="display: none;">加载中...</div>
        <p id="ownedAppsCount">已加载${
          GM_getValue('Saves').ownedApps.length
        } 个库存游戏及DLC</p>
        <p id="wishListCount">已加载${
          GM_getValue('Saves').wishlist.length
        } 个愿望单游戏</p>
        <p id="familyGameCount">已加载${
          GM_getValue('Saves').familygameList.length
        } 个家庭库游戏</p>
        <label for="family-library">是否加入了家庭库:</label>
        <input type="checkbox" id="family-library" name="family-library">
        <div class="button-container">
        <button id="refresh-saves">刷新存档</button>
        <button id="clear-saves">清除存档</button>
      </div>
      </div>
    </div>
  `;
  const targetElementSelector = '.balanceTitle > div';
  function tryAppend() {
    const targetElement = document.querySelector(targetElementSelector);
    if (targetElement) {
      targetElement.appendChild(settings);
      document
        .getElementById('settings')
        .addEventListener('click', function () {
          document.getElementById('popup-window').style.display = 'block';
        });
      document
        .getElementById('close-popup')
        .addEventListener('click', function () {
          document.getElementById('popup-window').style.display = 'none';
        });
      document
        .getElementById('refresh-saves')
        .addEventListener('click', async function () {
          document.getElementById('loading').style.display = 'block';
          await getOwnAndWish();
          if (document.getElementById('family-library').checked) {
            await getFamilyGame();
          }
          //
          document.getElementById('loading').style.display = 'none';
          updateCounts();
        });
      document
        .getElementById('clear-saves')
        .addEventListener('click', function () {
          let nullSaves = {
            wishlist: [],
            ownedApps: [],
            familygameList: [],
          };
          GM_setValue('Saves', nullSaves);
          updateCounts();
        });
      dragElement(document.getElementById('popup-window'));
    } else {
      setTimeout(tryAppend, 100);
    }
  }
  function updateCounts() {
    const saves = GM_getValue('Saves');
    document.getElementById(
      'ownedAppsCount'
    ).innerHTML = `已加载${saves.ownedApps.length} 个库存游戏及DLC`;
    document.getElementById(
      'wishListCount'
    ).innerHTML = `已加载${saves.wishlist.length} 个愿望单游戏`;
    document.getElementById(
      'familyGameCount'
    ).innerHTML = `已加载${saves.familygameList.length} 个家庭库游戏`;
  }
  tryAppend();
}

//CSS样式
const style = document.createElement('style');
style.innerHTML = `
  .popup-window {
    display: none;
    position: fixed;
    z-index: 1000;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    width: 400px;
    background-color: white;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
    border-radius: 10px;
    cursor: default	; /* 设置鼠标指针样式 */
  }
  .popup-content {
    padding: 20px;
    font-size: 18px; /* 设置字体大小 */
    cursor: default	; /* 设置鼠标指针样式 */
  }
  .close-btn {
    float: right;
    font-size: 20px;
    cursor: default	;
  }
`;
document.head.appendChild(style);

//拖拽功能
function dragElement(element) {
  let pos1 = 0,
    pos2 = 0,
    pos3 = 0,
    pos4 = 0;
  element.onmousedown = dragMouseDown;

  function dragMouseDown(e) {
    e = e || window.event;
    e.preventDefault();
    pos3 = e.clientX;
    pos4 = e.clientY;
    document.onmouseup = closeDragElement;
    document.onmousemove = elementDrag;
  }

  function elementDrag(e) {
    e = e || window.event;
    e.preventDefault();
    pos1 = pos3 - e.clientX;
    pos2 = pos4 - e.clientY;
    pos3 = e.clientX;
    pos4 = e.clientY;
    element.style.top = element.offsetTop - pos2 + 'px';
    element.style.left = element.offsetLeft - pos1 + 'px';
  }

  function closeDragElement() {
    document.onmouseup = null;
    document.onmousemove = null;
  }
}

//等待页面加载
function Start() {
  const getterTimer = setInterval(() => {
    const dom = document.querySelector('.cdkGameIcon');
    if (dom) {
      clearInterval(getterTimer);
      gameChecker();
    }
  }, 200);
}

//游戏状态标记
function gameChecker() {
  const isAppOwned = (appId) => Saves.ownedApps.includes(appId);
  const isAppinwishlist = (appId) => Saves.wishlist.includes(appId);
  const isAppShared = (appId) => Saves.familygameList.includes(appId);
  const getAppId = (url) => (url.match(/\/apps\/(\d+)\//) || [])[1] || null;
  const game_layout = document.querySelector(
    '.flex-row.jc-space-flex-start.flex-wrap.w-auto'
  );
  if (game_layout) {
    const gameIcons = game_layout.querySelectorAll('.cdkGameIcon');
    gameIcons.forEach((icon) => {
      const appId = Number(getAppId(icon.getAttribute('data-src')));
      if (isAppOwned(appId)) {
        const gameNameElement = icon
          .closest('.gameblock')
          .querySelector('.gameName');
        if (gameNameElement) {
          gameNameElement.style.color = ownedColor;
        }
      } else if (isAppShared(appId)) {
        const gameNameElement = icon
          .closest('.gameblock')
          .querySelector('.gameName');
        if (gameNameElement) {
          gameNameElement.style.color = familygameColor;
        }
      } else if (isAppinwishlist(appId)) {
        const gameNameElement = icon
          .closest('.gameblock')
          .querySelector('.gameName');
        if (gameNameElement) {
          gameNameElement.style.color = wishlistColor;
        }
      } else {
        const gameNameElement = icon
          .closest('.gameblock')
          .querySelector('.gameName');
        if (gameNameElement) {
          gameNameElement.style.color = unownedColor;
        }
      }
    });
  }
}

//加载存档
function load() {
  var previousSave = GM_getValue('Saves');
  if (previousSave !== undefined) {
    Saves = GM_getValue('Saves', {
      wishlist: [],
      ownedApps: [],
      familygameList: [],
    });
  } else {
    GM_setValue('Saves', Saves);
  }
}
// 监听页面变化
function observePageChanges() {
  const targetNode = document.body;
  const config = { childList: true, subtree: true };

  const callback = function (mutationsList, observer) {
    for (let mutation of mutationsList) {
      if (mutation.type === 'childList') {
        gameChecker();
        break;
      }
    }
  };

  const observer = new MutationObserver(callback);
  observer.observe(targetNode, config);
}