做了个啥?
用GPT生成了一个tampermonkey的脚本在鸡腿页面可以实现统计数据
效果

tampermonkey代码
// ==UserScript==
// @name NS Yearly Summary
// @namespace http://tampermonkey.net/
// @version 2.1
// @description 生成年度总结并展示类似年终报告的页面,包含加入时间等详细信息,以及完整统计数据展示
// @author KefIe with GPT 4o
// @match https://www.nodeseek.com/credit
// @grant GM_xmlhttpRequest
// @grant GM_addStyle
// @run-at document-end
// ==/UserScript==
(async function () {
'use strict';
// 格式化数据,将原始数组转换为 JSON 对象
function formatData(rawData) {
if (!rawData || !rawData.success || !Array.isArray(rawData.data)) {
throw new Error('数据格式无效');
}
// 将数据转换为所需格式
return rawData.data.map(item => ({
change: item[0], // 加/扣分值
balance: item[1], // 当前余额
reason: item[2], // 操作原因
timestamp: new Date(item[3]), // 时间戳
}));
}
// 筛选出从 2024-01-01 开始的数据
function filterData(data) {
const startDate = new Date('2024-01-01T00:00:00Z');
return data.filter(item => item.timestamp >= startDate);
}
// 生成年度总结
function generateSummary(allData, filteredData) {
const summary = {
joinDate: allData[allData.length - 1]?.timestamp, // 加入时间为最早的记录时间
totalDays: 0,
totalGains: 0,
totalLosses: 0,
totalEntries: filteredData.length,
details: {
"签到收益": { total: 0, count: 0, earliest: null, latest: null },
"回帖奖励": { total: 0, count: 0 },
"发帖奖励": { total: 0, count: 0 },
"被投喂鸡腿": { total: 0, count: 0 },
"投喂鸡腿": { total: 0, count: 0 },
"认定为轻度灌水": { total: 0, count: 0 },
"公开帖子私有化": { total: 0, count: 0 },
"内板代价": { total: 0, count: 0 },
"代理相关须发内板": { total: 0, count: 0 },
"其他": { total: 0, count: 0 }
},
maxDeduction: { reason: '', amount: 0 }, // 最大扣分项
totalDeductions: { total: 0, count: 0 } // 扣分总计
};
filteredData.forEach(item => {
const { change, reason, timestamp } = item;
if (change > 0) {
summary.totalGains += change;
if (reason.includes("签到收益")) {
summary.details["签到收益"].total += change;
summary.details["签到收益"].count++;
if (!summary.details["签到收益"].earliest || timestamp < summary.details["签到收益"].earliest) {
summary.details["签到收益"].earliest = timestamp;
}
if (!summary.details["签到收益"].latest || timestamp > summary.details["签到收益"].latest) {
summary.details["签到收益"].latest = timestamp;
}
} else if (reason.includes("回帖奖励")) {
summary.details["回帖奖励"].total += change;
summary.details["回帖奖励"].count++;
} else if (reason.includes("发帖奖励")) {
summary.details["发帖奖励"].total += change;
summary.details["发帖奖励"].count++;
} else if (reason.includes("被") && reason.includes("投喂鸡腿")) {
summary.details["被投喂鸡腿"].total += change;
summary.details["被投喂鸡腿"].count++;
} else {
summary.details["其他"].total += change;
summary.details["其他"].count++;
}
} else {
const absChange = Math.abs(change);
summary.totalLosses += absChange;
summary.totalDeductions.total += absChange;
summary.totalDeductions.count++;
if (absChange > summary.maxDeduction.amount) {
summary.maxDeduction = { reason, amount: absChange };
}
if (reason.includes("轻度灌水")) {
summary.details["认定为轻度灌水"].total += absChange;
summary.details["认定为轻度灌水"].count++;
} else if (reason.includes("公开帖子私有化")) {
summary.details["公开帖子私有化"].total += absChange;
summary.details["公开帖子私有化"].count++;
} else if (reason.includes("内板代价")) {
summary.details["内板代价"].total += absChange;
summary.details["内板代价"].count++;
} else if (reason.includes("代理相关须发内板")) {
summary.details["代理相关须发内板"].total += absChange;
summary.details["代理相关须发内板"].count++;
} else if (reason.includes("投喂鸡腿")) {
summary.details["投喂鸡腿"].total += absChange;
summary.details["投喂鸡腿"].count++;
} else {
summary.details["其他"].total += absChange;
summary.details["其他"].count++;
}
}
});
summary.totalDays = Math.floor((new Date() - summary.joinDate) / (1000 * 60 * 60 * 24));
return summary;
}
// 显示年度总结页面
function displaySummary(summary) {
// 清空页面内容
document.body.innerHTML = '';
const container = document.createElement('div');
container.style.fontFamily = 'Arial, sans-serif';
container.style.margin = '20px';
container.style.opacity = '0';
container.style.transition = 'opacity 1s';
document.body.appendChild(container);
const sections = [];
// 第一版:年度总结标题
sections.push(`<h1 style="text-align: center;">2024 年度总结</h1>`);
// 第二版:加入时间
sections.push(
`<p>您是在 <strong>${summary.joinDate.toLocaleDateString()}</strong> 加入的NS,距离现在已经有 <strong>${summary.totalDays}</strong> 天。</p>`
);
// 第三版:总加分、总扣分
sections.push(
`<p>今年共计加了 <strong>${summary.totalGains}</strong> 分,扣了 <strong>${summary.totalLosses}</strong> 分,总计 <strong>${summary.totalGains - summary.totalLosses}</strong> 分。</p>`
);
// 第四版:签到统计
const signIn = summary.details["签到收益"];
if (signIn.count > 0) {
const avgGain = (signIn.total / signIn.count).toFixed(2);
const comment = avgGain < 5 ? "明年可能还是拿低保的好" : "你真是个幸运的人";
sections.push(
`<p>今年共计签到 <strong>${signIn.count}</strong> 次,
最早一次签到是在 <strong>${signIn.earliest.toLocaleTimeString()}</strong>,
最晚一次签到是在 <strong>${signIn.latest.toLocaleTimeString()}</strong>,
平均每次获得鸡腿 <strong>${avgGain}</strong> 个。${comment}</p>`
);
}
// 第五版:扣分统计
// 添加扣分统计显示逻辑
if (summary.totalDeductions.total === 0) {
// 如果没有扣分记录,显示“你真是个乖宝宝”
sections.push('<h1 style="text-align: center; color: green;">你真是个乖宝宝</h1>');
} else {
// 显示扣分统计
sections.push('<h2>扣分统计</h2>');
sections.push(
`<p>总计扣分 <strong>${summary.totalDeductions.total}</strong> 分,次数 <strong>${summary.totalDeductions.count}</strong>。</p>`
);
// 添加每种扣分项的详细统计
Object.keys(summary.details).forEach(key => {
if (key.includes("轻度灌水") || key.includes("公开帖子私有化") || key.includes("内板代价") || key.includes("代理相关须发内板")) {
const detail = summary.details[key];
sections.push(
`<p><strong>${key}:</strong> 总计扣分 <strong>${detail.total}</strong> 分,次数 <strong>${detail.count}</strong></p>`
);
}
});
}
// 第六版:投喂统计
const feeding = summary.details["被投喂鸡腿"];
if (feeding.count > 0) {
sections.push(
`<p>今年你被投喂了 <strong>${feeding.count}</strong> 次,希望明年还能看到你更好的作品。</p>`
);
}
// 第七版:完整统计数据
sections.push('<h2>完整统计数据</h2>');
Object.keys(summary.details).forEach(key => {
const detail = summary.details[key];
sections.push(
`<p><strong>${key}:</strong> 总计 <strong>${detail.total}</strong> 分,次数 <strong>${detail.count}</strong></p>`
);
});
// 插入内容
sections.forEach((section, index) => {
const sectionElement = document.createElement('div');
sectionElement.innerHTML = section;
sectionElement.style.opacity = '0';
sectionElement.style.transition = 'opacity 1s';
sectionElement.style.marginBottom = '20px';
container.appendChild(sectionElement);
setTimeout(() => {
sectionElement.style.opacity = '1';
}, index * 1000); // 每段内容依次淡入
});
// 动态淡入效果
setTimeout(() => {
container.style.opacity = '1';
}, 100);
}
// 获取 Cookie
function getCookie() {
return document.cookie;
}
// 封装 GM_xmlhttpRequest 为 Promise
function gmRequest(options) {
return new Promise((resolve, reject) => {
GM_xmlhttpRequest({
...options,
onload: (response) => {
if (response.status >= 200 && response.status < 300) {
resolve(response);
} else {
reject(new Error(`HTTP Error: ${response.status}`));
}
},
onerror: (error) => {
reject(error);
}
});
});
}
// 动态创建一个按钮并固定在页面中间
const button = document.createElement('button');
button.innerText = '开始获取你的ns年终报告';
button.id = 'centered-button';
document.body.appendChild(button);
// 添加样式,让按钮固定在页面中间
GM_addStyle(`
#centered-button {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 10000;
padding: 15px 30px;
font-size: 16px;
cursor: pointer;
background-color: #007BFF;
color: white;
border: none;
border-radius: 5px;
box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.1);
}
#centered-button:hover {
background-color: #0056b3;
}
`);
let flag = false; // 防止重复点击
// 给按钮添加点击事件
button.addEventListener('click', async () => {
if (flag) return; // 防止重复执行
flag = true;
let allData = []; // 存储所有页面的数据
const lastPageElement = document.querySelectorAll('.pager-pos');
let lastPageNum = 1;
// 获取最后一页页码
if (lastPageElement.length > 2) {
lastPageNum = parseInt(
lastPageElement[lastPageElement.length - 2].href.replace('https://www.nodeseek.com/credit#/p-', '')
);
}
const cookies = getCookie(); // 获取本地 Cookie
for (let i = 1; i <= lastPageNum; i++) {
console.log(`正在获取第 ${i}/${lastPageNum} 页的数据`);
button.innerText = `正在获取第 ${i}/${lastPageNum} 页的数据...`;
try {
const response = await gmRequest({
method: 'GET',
url: `https://www.nodeseek.com/api/account/credit/page-${i}`, // 替换为实际的 API URL
headers: {
'Content-Type': 'application/json',
cookie: cookies,
},
});
const rawData = JSON.parse(response.responseText);
const formattedData = formatData(rawData);
// 合并数据
allData = [...allData, ...formattedData];
} catch (error) {
console.error(`第 ${i} 页请求失败:`, error);
alert(`第 ${i} 页请求失败,请检查控制台日志!`);
button.innerText = '点击重新获取'; // 恢复按钮文字
flag = false;
return;
}
}
// 筛选出从 2024-01-01 开始的数据
const filteredData = filterData(allData);
console.log('筛选后的数据:', filteredData);
// 生成总结
const summary = generateSummary(allData, filteredData);
console.log('年度总结:', summary);
// 动态展示总结
displaySummary(summary);
flag = false; // 重置状态
});
})();
计划更新1.增加更多属性修复bug1.投喂鸡腿被计入扣分2.页面超过100页,无法获取真实加入时间NS论坛官方版本已经发布,效果和数据也更加真实,后续不再更新,感谢论坛支持
@3az7qmfd #3 不到一年干到6级,大佬啊
牛逼了
666
您是在 2024/5/17 加入的NS,距离现在已经有 220 天。
今年共计加了 3289 分,扣了 30 分,总计 3259 分。
今年共计签到 179 次, 最早一次签到是在 00:16:58, 最晚一次签到是在 12:26:18, 平均每次获得鸡腿 5.08 个。你真是个幸运的人
扣分统计
总计扣分 30 分,次数 16。
认定为轻度灌水: 总计扣分 0 分,次数 0
公开帖子私有化: 总计扣分 10 分,次数 1
内板代价: 总计扣分 5 分,次数 1
代理相关须发内板: 总计扣分 0 分,次数 0
今年你被投喂了 248 次,希望明年还能看到你更好的作品。
完整统计数据
签到收益: 总计 910 分,次数 179
回帖奖励: 总计 1431 分,次数 1431
发帖奖励: 总计 620 分,次数 124
被投喂鸡腿: 总计 248 分,次数 248
投喂鸡腿: 总计 0 分,次数 0
认定为轻度灌水: 总计 0 分,次数 0
公开帖子私有化: 总计 10 分,次数 1
内板代价: 总计 5 分,次数 1
代理相关须发内板: 总计 0 分,次数 0
其他: 总计 95 分,次数 16
今年共计签到 289 次, 最早一次签到是在 10:35:10, 最晚一次签到是在 22:10:36, 平均每次获得鸡腿 4.89 个。明年可能还是拿低保的好
今年大部分都是随机签到,看来随机签到确实不如固定签到拿的多
这个怎么用呀,需要改自己名字吧
牛逼,挺好的,送你个免费鸡腿
@Adger #5 不用,你要在鸡腿页面才会显示
@Adm1n #4 哈哈 我用随机 就超出了5
这个好玩,可以有