IG-Owned

indiegala 检测游戏是否已拥有

当前为 2021-02-20 提交的版本,查看 最新版本

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

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

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

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

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

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

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

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

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

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

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

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

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

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

"use strict";

function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }

function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }

function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); }

function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }

function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }

function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }

function _iterableToArrayLimit(arr, i) { if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }

function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }

function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }

function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }

function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e2) { throw _e2; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e3) { didErr = true; err = _e3; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }

function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }

function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }

// ==UserScript==
// @name               IG-Owned
// @namespace          IG-Owned
// @version            1.0.0
// @description        indiegala 检测游戏是否已拥有
// @author             HCLonely
// @license            MIT
// @iconURL            https://auto-task-test.hclonely.com/img/favicon.ico
// @homepage           https://github.com/HCLonely/IG-Helper/
// @supportURL         https://github.com/HCLonely/IG-Helper/issues/
// @include            *://keylol.com/*
// @include            *://*.indiegala.com/*
// @grant              GM_setValue
// @grant              GM_getValue
// @grant              GM_addStyle
// @grant              GM_xmlhttpRequest
// @grant              GM_registerMenuCommand
// @grant              unsafeWindow
// @grant              window.open
// @require            https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.slim.min.js
// @require            https://cdn.jsdelivr.net/npm/sweetalert2@9
// @require            https://cdn.jsdelivr.net/npm/[email protected]/dist/polyfill.min.js
// @require            https://greasyfork.org/scripts/418102-tm-request/code/TM_request.js?version=902218
// @connect            indiegala.com
// @run-at             document-end
// ==/UserScript==

/* global syncIgLib */
(function () {
  function checkIgOwned() {
    var _GM_getValue;

    var allGames = ((_GM_getValue = GM_getValue('IG-Owned')) === null || _GM_getValue === void 0 ? void 0 : _GM_getValue.games) || [];

    var _iterator = _createForOfIteratorHelper($('a[href*=".indiegala.com/"]:not(".ig-checked")')),
        _step;

    try {
      for (_iterator.s(); !(_step = _iterator.n()).done;) {
        var el = _step.value;
        var $this = $(el).addClass('ig-checked');
        var href = $this.attr('href');

        if (/^https?:\/\/.+?\.indiegala\.com\/.+$/.test(href) && allGames.includes(new URL(href).pathname.replace(/\//g, '').toLowerCase())) {
          $this.addClass('ig-owned');
        }
      }
    } catch (err) {
      _iterator.e(err);
    } finally {
      _iterator.f();
    }
  }

  unsafeWindow.syncIgLib = /*#__PURE__*/function () {
    var _syncIgLib = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
      var _GM_getValue2;

      var notice,
          update,
          allGames,
          _yield$getGames,
          _yield$getGames2,
          pages,
          games,
          i,
          _yield$getGames3,
          _yield$getGames4,
          _games,
          _args = arguments;

      return regeneratorRuntime.wrap(function _callee$(_context) {
        while (1) {
          switch (_context.prev = _context.next) {
            case 0:
              notice = _args.length > 0 && _args[0] !== undefined ? _args[0] : false;
              update = _args.length > 1 && _args[1] !== undefined ? _args[1] : false;
              allGames = ((_GM_getValue2 = GM_getValue('IG-Owned')) === null || _GM_getValue2 === void 0 ? void 0 : _GM_getValue2.games) || [];
              _context.next = 5;
              return getGames(1, notice);

            case 5:
              _yield$getGames = _context.sent;
              _yield$getGames2 = _slicedToArray(_yield$getGames, 2);
              pages = _yield$getGames2[0];
              games = _yield$getGames2[1];

              if (!(pages === 0)) {
                _context.next = 11;
                break;
              }

              return _context.abrupt("return");

            case 11:
              allGames = [].concat(_toConsumableArray(allGames), _toConsumableArray(games));

              if (!(pages > 1 && update)) {
                _context.next = 24;
                break;
              }

              i = 2;

            case 14:
              if (!(i <= pages)) {
                _context.next = 24;
                break;
              }

              _context.next = 17;
              return getGames(i, notice);

            case 17:
              _yield$getGames3 = _context.sent;
              _yield$getGames4 = _slicedToArray(_yield$getGames3, 2);
              _games = _yield$getGames4[1];
              allGames = [].concat(_toConsumableArray(allGames), _toConsumableArray(_games));

            case 21:
              i++;
              _context.next = 14;
              break;

            case 24:
              allGames = _toConsumableArray(new Set(allGames));
              GM_setValue('IG-Owned', {
                time: new Date().getTime(),
                games: allGames
              });

              if (notice) {
                Swal.fire({
                  title: '同步完成!',
                  icon: 'success'
                });
              }

              return _context.abrupt("return", allGames);

            case 28:
            case "end":
              return _context.stop();
          }
        }
      }, _callee);
    }));

    function syncIgLib() {
      return _syncIgLib.apply(this, arguments);
    }

    return syncIgLib;
  }();

  function getGames(page, notice) {
    if (notice) {
      Swal.fire({
        title: '正在同步第' + page + '页...',
        icon: 'info'
      });
    }

    return TM_request({
      url: 'https://www.indiegala.com/library/showcase/' + page,
      method: 'GET',
      timeout: 30000,
      retry: 3
    }).then(function (response) {
      if (notice && new URL(response.finalUrl).pathname === '/login') {
        Swal.fire({
          title: '请先登录!',
          icon: 'error',
          showCancelButton: true,
          confirmButtonText: '登录',
          cancelButtonText: '关闭'
        }).then(function (_ref) {
          var value = _ref.value;

          if (value) {
            window.open('https://www.indiegala.com/login', '_blank');
          }
        });
        return [0, []];
      }

      if (response.status === 200) {
        var pages = 1;

        if (page === 1) {
          var _$$find$attr$match;

          var lastPageNum = parseInt((_$$find$attr$match = $(response.responseText).find('a.profile-private-page-library-pagination-item[href*="library/showcase"]:has(.fa-angle-double-right)').attr('href').match(/[\d]+/)) === null || _$$find$attr$match === void 0 ? void 0 : _$$find$attr$match[0]);

          if (!isNaN(lastPageNum)) {
            pages = lastPageNum;
          }
        }

        var games = _toConsumableArray(response.responseText.matchAll(/<a class="library-showcase-title" href="https:\/\/.*?\.indiegala\.com\/(.*?)" target="_blank">/g)).map(function (e) {
          return e[1].toLowerCase();
        }).filter(function (e) {
          return e;
        });

        return [pages, games];
      } else {
        console.error(response);

        if (notice) {
          Swal.fire({
            title: '获取游戏库数据失败!',
            text: response.status,
            icon: 'error'
          });
        }
      }
    })["catch"](function (error) {
      console.error(error);

      if (notice) {
        Swal.fire({
          title: '获取游戏库数据失败!',
          icon: 'error'
        });
      }

      return [0, []];
    });
  }

  GM_registerMenuCommand('同步游戏库', function () {
    syncIgLib(true, true);
  });
  GM_addStyle('.ig-owned{color:#ffffff !important;background:#5c8a00 !important;}');

  if (!GM_getValue('IG-Owned')) {
    Swal.fire({
      title: '首次使用IG游戏库检测请先同步!',
      icon: 'warning',
      showCancelButton: true,
      confirmButtonText: '同步',
      cancelButtonText: '关闭'
    }).then(function (_ref2) {
      var value = _ref2.value;

      if (value) {
        syncIgLib(true, true);
      }
    });
    return;
  }

  checkIgOwned();
  var observer = new MutationObserver(checkIgOwned);
  observer.observe(document.documentElement, {
    attributes: true,
    characterData: true,
    childList: true,
    subtree: true
  });
  syncIgLib(false, false);
})();