// ==UserScript==
// @name:zh-CN 鉴赏家小工具
// @name Curator_Tools
// @namespace https://blog.chrxw.com
// @supportURL https://blog.chrxw.com/scripts.html
// @contributionURL https://afdian.com/@chr233
// @version 1.9
// @description 添加删除按钮
// @description:zh-CN 添加删除按钮
// @author Chr_
// @include https://store.steampowered.com/curator/*
// @license AGPL-3.0
// @icon https://blog.chrxw.com/favicon.ico
// @grant GM_addStyle
// ==/UserScript==
// 初始化
(() => {
"use strict";
let lastPathname = "";
let lastCount = 0;
setInterval(() => {
if (location.pathname !== lastPathname) {
lastPathname = location.pathname;
if (location.pathname.includes("admin/review_create")) {
const [_, curator, appid] = lastPathname.match(
/\/curator\/([^\/]+)\/admin\/review_create\/?(\d+)?/
) ?? [null, null, null];
if (curator) {
const btnArea = document.querySelector("div.titleframe");
if (appid) {
const btn = genBtn(
"删除该评测",
"ct_btn",
async () => await deleteReview(curator, appid)
);
btnArea.appendChild(btn);
const link = genA(`https://store.steampowered.com/app/${appid}`);
const btn2 = genBtn(
"商店页",
"ct_btn"
);
link.appendChild(btn2);
btnArea.appendChild(link);
} else {
const appSuggest = document.querySelector("#app_suggest_id");
const reviewType = document.querySelector('textarea[name="blurb"]');
if (appSuggest && reviewType) {
let suggestAppId = null;
const btn = genBtn("编辑原先的评测", "ct_btn");
const link = genA("#");
link.appendChild(btn);
btnArea.appendChild(link);
const btn2 = genBtn(
"删除原先的评测",
"ct_btn",
async () => await deleteReview(curator, suggestAppId)
);
btnArea.appendChild(btn2);
const link3 = genA("#");
const btn3 = genBtn("商店页", "ct_btn");
link3.appendChild(btn3);
btnArea.appendChild(link3);
const spStatus = genSpan("test");
btnArea.appendChild(spStatus);
setInterval(() => {
if (appSuggest.value !== suggestAppId) {
suggestAppId = appSuggest.value;
btn.disabled = true;
btn2.disabled = true;
link.href = "#";
if (suggestAppId) {
spStatus.textContent = "正在获取评测内容";
getReviewText(curator, suggestAppId)
.then(text => {
if (text) {
spStatus.textContent = "读取完成";
reviewType.value = text;
btn.disabled = false;
btn2.disabled = false;
link.href = `https://store.steampowered.com/curator/${curator}/admin/review_create/${suggestAppId}`;
} else {
spStatus.textContent = "未写过评测";
}
})
.catch(e => {
spStatus.textContent = "读取失败";
console.error(e);
});
link3.href = `https://store.steampowered.com/app/${suggestAppId}`;
btn3.disabled = false;
} else {
spStatus.textContent = "未选择游戏";
link3.href = "#";
btn3.disabled = true;
}
}
}, 500);
}
}
}
} else if (location.pathname.includes("admin/stats")) {
injectBtn();
injectGotoBtn();
lastCount = document.querySelectorAll(
"#RecentReferralsRows td>.ct_div,#TopReferralsRows td>.ct_div"
).length;
const spanList = document.querySelectorAll(
"#RecentReferrals_controls>span,#RecentReferrals_controls>span>span,#TopReferrals_controls>span,#TopReferrals_controls>span>span"
);
for (let span of spanList) {
span.addEventListener("click", updateInjectBtn);
}
}
}
}, 500);
function genBtn(text, cls, foo) {
const btn = document.createElement("button");
btn.textContent = text;
btn.className = cls;
btn.addEventListener("click", foo);
return btn;
}
function genA(url) {
const a = document.createElement("a");
a.href = url;
a.target = "_blank";
return a;
}
function genDiv(cls) {
const div = document.createElement("div");
div.className = cls;
return div;
}
function genSpan(name) {
const span = document.createElement("span");
span.textContent = name;
return span;
}
// 删除评测
async function deleteReview(curator, appid, ele = null) {
ShowConfirmDialog("", "真的要删除这篇评测吗", "给我删", "手滑了").done(
() => {
fetch(
`https://store.steampowered.com/curator/${curator}/admin/ajaxdeletereview/`,
{
method: "POST",
credentials: "include",
body: `appid=${appid}&sessionid=${g_sessionID}`,
headers: {
"content-type":
"application/x-www-form-urlencoded; charset=UTF-8",
},
}
)
.then(async (response) => {
if (response.ok) {
showAlert("删除成功", true);
setTimeout(() => {
if (location.pathname.includes("review_create")) {
if (location.pathname.includes(appid)) {
location.pathname = `/curator/${curator}/admin/reviews_manage`;
}
} else {
if (ele) {
ele.style.opacity = "0.5";
}
}
}, 500);
} else {
showAlert("删除失败", false);
}
})
.catch((err) => {
console.error(err);
showAlert(`删除出错 ${err}`, false);
});
}
);
}
function updateInjectBtn() {
const t = setInterval(() => {
const count = document.querySelectorAll(
"#RecentReferralsRows td>.ct_div,#TopReferralsRows td>.ct_div"
).length;
if (count != lastCount) {
clearInterval(t);
injectBtn();
lastCount = document.querySelectorAll(
"#RecentReferralsRows td>.ct_div,#TopReferralsRows td>.ct_div"
).length;
}
}, 500);
}
function injectBtn() {
const tdList = document.querySelectorAll(
"#RecentReferralsRows>table>tbody>tr>td:last-child,#TopReferralsRows>table>tbody>tr>td:last-child"
);
for (let td of tdList) {
const a = td.childNodes[0];
if (a.nodeName !== "A") {
continue;
}
const div = genDiv("ct_div");
div.appendChild(a);
td.appendChild(div);
const [_, curator, appid] = a.href.match(
/\/curator\/([^\/]+)\/admin\/review_create\/(\d+)/
) ?? [null, null, null];
if (curator !== null && appid !== null) {
const btn = genBtn("删", "ct_btn", async () =>
deleteReview(curator, appid, td.parentNode)
);
div.appendChild(btn);
getReviewType(curator, appid).then(type => {
let text = "";
let color = "#fff";
switch (type) {
case 0:
text = "推荐";
color = "#a9be7b"
break;
case 1:
text = "不推荐";
color = "#9e2a22"
break;
case 2:
text = "情报";
color = "#ecd452"
break;
default:
text = "错误";
color = "#d3ccd6"
break;
}
const span = genSpan(text);
span.style.color = color;
td.insertBefore(span, td.childNodes[0]);
})
}
}
}
function injectGotoBtn() {
const recentController = new CAjaxPagingControls(g_RecentReferralsPagingData, g_RecentReferralsPagingData['url']);
const recentCtn = document.querySelector("#RecentReferrals_ctn > div:nth-child(2)");
recentCtn.appendChild(genBtn("跳转到...", "ct_btn2", () => {
gotoPage(recentController);
}));
const topController = new CAjaxPagingControls(g_TopReferralsPagingData, g_TopReferralsPagingData['url']);
const topCtn = document.querySelector("#TopReferrals_ctn > div:nth-child(2)");
topCtn.appendChild(genBtn("跳转到...", "ct_btn2", () => {
gotoPage(topController);
}));
}
function gotoPage(controller) {
const dialog = ShowPromptDialog("请输入页码", "", "跳转", "取消");
dialog.done((txt) => {
const page = parseInt(txt);
if (page !== page || page < 1) {
showAlert("请输入有效数字", false);
return;
}
controller.GoToPage(page - 1, true);
updateInjectBtn();
});
dialog.fail(() => {
dialog.Dismiss();
});
}
function showAlert(text, succ = true) {
return ShowAlertDialog(`${succ ? "✅" : "❌"}`, text);
}
//获取评测类型
function getReviewType(curatorId, appId) {
return new Promise((resolve, reject) => {
fetch(`https://store.steampowered.com/curator/${curatorId}/admin/review_create/${appId}`, {
method: "GET",
credentials: "include",
})
.then((response) => {
if (response.ok) {
return response.text();
} else {
resolve(-2);
}
})
.then((data) => {
const match = data.match(/"recommendation_state" value="(\d)" checked/);
if (match) {
resolve(parseInt(match[1]));
} else {
resolve(-1);
}
})
.catch((err) => {
console.error(err);
resolve(-3);
});
});
}
//获取写过的评测
function getReviewText(curatorId, appId) {
return new Promise((resolve, reject) => {
fetch(`https://store.steampowered.com/curator/${curatorId}/admin/review_create/${appId}`, {
method: "GET",
credentials: "include",
})
.then((response) => {
if (response.ok) {
return response.text();
} else {
resolve(-2);
}
})
.then((data) => {
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(data, "text/html");
const match = xmlDoc.querySelector('textarea[name="blurb"]');
if (match) {
resolve(match.value);
} else {
resolve(-1);
}
})
.catch((err) => {
console.error(err);
resolve(-3);
});
});
}
})();
GM_addStyle(`
.ct_btn {
padding: 3px;
margin-right: 10px;
}
.ct_btn2 {
padding: 0 3px;
margin-right: 10px;
}
td {
height: 100%;
}
.ct_div {
display: flex;
align-content: center;
align-items: center;
height: 25px;
width: 40px;
}
tr > td > .ct_div > .ct_btn {
display: none;
}
tr:hover > td > .ct_div > .ct_btn {
display: block;
}
`);