// ==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;">←</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;">→</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);
});
})