LSP+1

LSP+1自动领取

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name        LSP+1
// @namespace    https://github.com/inory121/tamperscript
// @version      1.0
// @match        https://www.lspsp.me/bonus*
// @require      https://code.jquery.com/jquery-3.6.0.min.js
// @grant        GM_registerMenuCommand
// @grant        GM_notification
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        unsafeWindow
// @description  LSP+1自动领取
// @author       hiiro
// @match        https://www.lspsp.me/bonus
// @icon         https://static.lspsp.cn/global/other/v3.png
// @run-at       document-start
// @license      MIT
// ==/UserScript==

unsafeWindow.alert = function (msg) {
  console.log('自动确认alert:', msg);
  GM_notification({
    title: 'LSP有信息!!',
    text: msg,
    image: 'https://static.lspsp.cn/global/other/v3.png',
    timeout: 6000,
  })
  closeBtn();
};

window.confirm = function (msg) {
  console.log('自动确认confirm:', msg);
  return true;
};
function closeBtn() {
  const closeBtn = $('.close-btn');
  if (closeBtn.length) {
    closeBtn.click();
  }
}
$(function () {
  "use strict"
  GM_registerMenuCommand("重新运行脚本", getGame);
  function getGame() {
    var activeBtns = document.querySelectorAll('.links>button:not([disabled]):not(.owned)')
    if (activeBtns.length != 0) {
      console.log(`【LSP+1】可领取游戏数量:${activeBtns.length}`)
      GM_notification({
        title: 'LSP有信息!!',
        text: '游戏可以领取啦!!!!',
        image: 'https://static.lspsp.cn/global/other/v3.png',
        timeout: 4000,
      })
      // 顺序处理领取按钮,避免多个弹窗同时出现
      function processBtns(btns, idx = 0) {
        if (idx >= btns.length) return;
        btns[idx].click();
        let tried = 0;
        const maxTries = 4; // 最多等待1秒
        const interval = setInterval(() => {
          const confirmBtn = $('.actions>button[name=confirm]:not([disabled])');
          if (confirmBtn.length) {
            confirmBtn.click();
            clearInterval(interval);
            setTimeout(() => processBtns(btns, idx + 1), 500); // 递归处理下一个
          } else {
            tried++;
            if (tried >= maxTries) {
              console.log('【LSP+1】没有领取次数!!!');
              clearInterval(interval);
              closeBtn()
              setTimeout(() => processBtns(btns, idx + 1), 500); // 超时也递归下一个
            }
          }
        }, 250);
      }
      processBtns(Array.from(activeBtns));
    } else {
      console.log("【LSP+1】没有游戏可以领取");
    }
  }
  // 自动刷新前清除定时器,防止多次叠加
  let autoRefreshTimer = null;
  function resetAutoRefreshTimer() {
    if (autoRefreshTimer) clearInterval(autoRefreshTimer);
    autoRefreshTimer = setInterval(function () {
      updatePanelCount();
      if (autoRefresh) {
        clearInterval(autoRefreshTimer); // 防止多次叠加
        document.location.reload();
      }
    }, refreshInterval);
  }
  setInterval(() => {
    document.location.reload();
  }, 5 * 60 * 1000);

  // 1. 插入样式
  const panelStyle = `
  #lsp-panel {
    position: fixed;
    right: 30px;
    bottom: 30px;
    width: 270px;
    background: #fff;
    border-radius: 10px;
    box-shadow: 0 4px 16px rgba(0,0,0,0.15);
    z-index: 99999;
    font-family: '微软雅黑', Arial, sans-serif;
    border: 1px solid #e0e0e0;
    overflow: hidden;
  }
  #lsp-panel-header {
    background: #4f8cff;
    color: #fff;
    padding: 10px 16px;
    font-size: 16px;
    font-weight: bold;
    display: flex;
    justify-content: space-between;
    align-items: center;
  }
  #lsp-panel-close {
    cursor: pointer;
    font-size: 18px;
    font-weight: bold;
  }
  #lsp-panel-body {
    padding: 16px;
    color: #333;
  }
  #lsp-panel-btn, #lsp-panel-refresh, #lsp-panel-logout {
    background: #4f8cff;
    color: #fff;
    border: none;
    border-radius: 5px;
    padding: 8px 16px;
    margin-top: 10px;
    margin-right: 8px;
    cursor: pointer;
    font-size: 15px;
    transition: background 0.2s;
    display: inline-block;
  }
  #lsp-panel-btn:hover, #lsp-panel-refresh:hover, #lsp-panel-logout:hover {
    background: #2563c9;
  }
  #lsp-panel-buttons {
    text-align: center;
    margin-top: 10px;
  }
  #lsp-panel-switch {
    vertical-align: middle;
  }
  #lsp-panel-refresh-row {
    display: flex;
    align-items: center;
    margin-top: 12px;
    gap: 6px;
    flex-wrap: nowrap;
    overflow: hidden;
  }
  #lsp-panel-refresh-row label {
    margin: 0;
    font-size: 15px;
    white-space: nowrap;
  }
  #lsp-panel-interval {
    margin-left: 6px;
    padding: 2px 4px;
    border-radius: 4px;
    border: 1px solid #ccc;
    font-size: 14px;
    vertical-align: middle;
    width: 48px;
    box-sizing: border-box;
  }
  #lsp-panel-interval-unit {
    margin-left: 4px;
    padding: 2px 4px;
    border-radius: 4px;
    border: 1px solid #ccc;
    font-size: 14px;
    vertical-align: middle;
    max-width: 60px;
    box-sizing: border-box;
  }
  `;

  $('head').append(`<style>${panelStyle}</style>`);

  // 2. 插入面板HTML
  const panelHtml = `
  <div id="lsp-panel">
    <div id="lsp-panel-header">
      LSP+1助手
      <span id="lsp-panel-close" title="关闭">×</span>
    </div>
    <div id="lsp-panel-body">
      <div id="lsp-panel-locate-row" style="display:flex;align-items:center;justify-content:space-between;margin-bottom:2px;gap:8px;">
        <div style="display:flex;flex-direction:column;align-items:center;min-width:70px;">
          <span>可领取游戏数:</span>
          <span id="lsp-panel-count" style="font-size:18px;font-weight:bold;">0</span>
        </div>
        <div style="display:flex;flex-direction:column;align-items:center;flex:1;">
          <span style="font-weight:bold;margin-bottom:2px;">定位到游戏</span>
          <div style="display:flex;align-items:center;gap:6px;">
            <button id="lsp-panel-locate-prev" title="上一个可领取游戏" style="padding:2px 8px;font-size:15px;">&#8592;</button>
            <span id="lsp-panel-locate-index" style="min-width:48px;text-align:center;font-size:14px;">0/0</span>
            <button id="lsp-panel-locate-next" title="下一个可领取游戏" style="padding:2px 8px;font-size:15px;">&#8594;</button>
          </div>
        </div>
      </div>
      <div id="lsp-panel-buttons">
        <button id="lsp-panel-btn" title="立即自动领取所有可领取游戏">自动领取</button>
        <button id="lsp-panel-logout" title="退出账号">退出账号</button>
      </div>
      <div id="lsp-panel-refresh-row">
        <label for="lsp-panel-switch">
          <input type="checkbox" id="lsp-panel-switch" checked>
          自动刷新页面
        </label>
        <input type="number" id="lsp-panel-interval" min="1"  step="1" value="1">
        <select id="lsp-panel-interval-unit">
          <option value="minute" selected>分钟</option>
          <option value="second">秒</option>
        </select>
      </div>
    </div>
  </div>
  `;
  $('body').append(panelHtml);

  // 3. 关闭按钮
  $('#lsp-panel-close').on('click', function () {
    $('#lsp-panel').hide();
  });

  // 5. 绑定按钮和刷新逻辑
  function updatePanelCount() {
    const count = document.querySelectorAll('.links>button:not([disabled]):not(.owned)').length;
    $('#lsp-panel-count').text(count);
  }
  updatePanelCount();

  $('#lsp-panel-btn').on('click', function () {
    getGame();
    setTimeout(updatePanelCount, 500);
  });

  // 读取油猴存储
  let autoRefresh = typeof GM_getValue === 'function' ? GM_getValue('lsp_auto_refresh', true) : true;
  let intervalValue = typeof GM_getValue === 'function' ? parseFloat(GM_getValue('lsp_refresh_interval', 1)) : 1;
  if (isNaN(intervalValue)) intervalValue = 1;
  let refreshInterval = 60000;
  let intervalUnit = typeof GM_getValue === 'function' ? GM_getValue('lsp_refresh_unit', 'minute') : 'minute';
  // 初始化界面
  $('#lsp-panel-switch').prop('checked', autoRefresh);
  $('#lsp-panel-interval').val(intervalValue);
  $('#lsp-panel-interval-unit').val(intervalUnit);
  // 计算初始刷新间隔
  if (intervalUnit === 'minute') {
    refreshInterval = intervalValue * 60 * 1000;
  } else {
    refreshInterval = intervalValue * 1000;
  }

  $('#lsp-panel-switch').on('change', function () {
    autoRefresh = this.checked;
    if (typeof GM_setValue === 'function') GM_setValue('lsp_auto_refresh', autoRefresh);
  });

  $('#lsp-panel-interval').on('change', function () {
    let min = 0.1, max = 60;
    let val = parseFloat(this.value);
    if (isNaN(val) || val < min) val = min;
    if (val > max) val = max;
    this.value = val;
    if (typeof GM_setValue === 'function') GM_setValue('lsp_refresh_interval', val);
    if (intervalUnit === 'minute') {
      refreshInterval = val * 60 * 1000;
    } else {
      refreshInterval = val * 1000;
    }
    resetAutoRefreshTimer();
  });

  $('#lsp-panel-interval-unit').on('change', function () {
    intervalUnit = this.value;
    if (typeof GM_setValue === 'function') GM_setValue('lsp_refresh_unit', intervalUnit);
    // 重新计算刷新间隔
    let val = parseFloat($('#lsp-panel-interval').val());
    if (isNaN(val) || val < 0.1) val = 0.1;
    if (val > 60) val = 60;
    if (intervalUnit === 'minute') {
      refreshInterval = val * 60 * 1000;
    } else {
      refreshInterval = val * 1000;
    }
    resetAutoRefreshTimer();
  });

  // 定时刷新(可变间隔)
  resetAutoRefreshTimer();

  // 页面变化时自动更新数量
  setInterval(updatePanelCount, 2000);

  // 退出账号功能:删除loginUser cookie并刷新页面
  $('#lsp-panel-logout').on('click', function () {
    document.cookie = 'loginUser=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/;';
    GM_notification({
      title: 'LSP+1',
      text: '已尝试删除loginUser,页面即将刷新',
      image: 'https://static.lspsp.cn/global/other/v3.png',
      timeout: 2000,
    });
    setTimeout(() => location.reload(), 1200);
  });

  // 上下箭头定位功能
  let locateIdx = 0;
  function updateLocateIndex() {
    const btns = document.querySelectorAll('.links>button:not([disabled]):not(.owned)');
    const total = btns.length;
    if (total === 0) {
      $('#lsp-panel-locate-index').text('0/0');
      locateIdx = 0;
    } else {
      if (locateIdx >= total) locateIdx = 0;
      if (locateIdx < 0) locateIdx = total - 1;
      $('#lsp-panel-locate-index').text(`${locateIdx + 1}/${total}`);
    }
  }
  // 初始和每次数量更新时都刷新索引
  const oldUpdatePanelCount = updatePanelCount;
  updatePanelCount = function () {
    oldUpdatePanelCount();
    updateLocateIndex();
  }
  updateLocateIndex();
  function locateToCurrent() {
    const btns = document.querySelectorAll('.links>button:not([disabled]):not(.owned)');
    if (btns.length === 0) {
      GM_notification({
        title: 'LSP+1',
        text: '没有可领取的游戏',
        image: 'https://static.lspsp.cn/global/other/v3.png',
        timeout: 2000,
      });
      return;
    }
    const btn = btns[locateIdx];
    if (btn) {
      btn.scrollIntoView({ behavior: 'smooth', block: 'center' });
      const $btn = $(btn);
      $btn.css({ 'box-shadow': '0 0 0 3px #ff9800', 'transition': 'box-shadow 0.3s' });
      setTimeout(() => $btn.css('box-shadow', ''), 1500);
    }
  }
  $('#lsp-panel-locate-prev').on('click', function () {
    const btns = document.querySelectorAll('.links>button:not([disabled]):not(.owned)');
    if (btns.length === 0) return;
    locateIdx = (locateIdx - 1 + btns.length) % btns.length;
    updateLocateIndex();
    locateToCurrent();
  });
  $('#lsp-panel-locate-next').on('click', function () {
    const btns = document.querySelectorAll('.links>button:not([disabled]):not(.owned)');
    if (btns.length === 0) return;
    locateIdx = (locateIdx + 1) % btns.length;
    updateLocateIndex();
    locateToCurrent();
  });

  // 页面加载后默认定位到第一个可领取游戏
  $(function () {
    setTimeout(() => {
      locateIdx = 0;
      updateLocateIndex();
      locateToCurrent();
    }, 300);
  });
})