// ==UserScript==
// @name 萌娘百科缓存部分Api请求
// @namespace https://github.com/gui-ying233/mwApiCache
// @version 3.1.0
// @description 缓存部分Api请求结果以提升速度减少WAF几率
// @author 鬼影233
// @license MIT
// @match zh.moegirl.org.cn/*
// @match mzh.moegirl.org.cn/*
// @match commons.moegirl.org.cn/*
// @match library.moegirl.org.cn/*
// @match en.moegirl.org.cn/*
// @match ja.moegirl.org.cn/*
// @icon http://moegirl.org.cn/favicon.ico
// @supportURL https://github.com/gui-ying233/mwApiCache/issues
// @run-at document-start
// @grant none
// ==/UserScript==
(() => {
"use strict";
if (new URLSearchParams(window.location.search).get("safemode")) return;
const ver = 2;
const id = setInterval(async () => {
if (!window.mediaWiki?.Api?.prototype) return;
clearInterval(id);
const originalMediaWikiApiPost = window.mediaWiki.Api.prototype.post;
await window.$.ready;
const cfg = window.mediaWiki.config;
const userName = cfg.get("wgUserName");
const log = (type, ...args) => {
console.debug(
`%cmwApiCache-${type}\n${args.join("\n")}`,
"border-left:1em solid #4E3DA4;background-color:#3C2D73;color:#D9D9D9;padding:1em"
);
};
window.addEventListener(
"storage",
e => {
if (!e.key.startsWith("mwApiCache-")) return;
if (e.newValue) {
e.storageArea.setItem(e.key, e.newValue);
log("Set", e.key, e.newValue);
} else {
e.storageArea.removeItem(e.key);
log("Del", e.key);
}
},
{ passive: true }
);
const timestamp = Date.now();
for (const key in window.localStorage) {
if (!key.startsWith("mwApiCache-")) continue;
const cache = JSON.parse(window.localStorage.getItem(key));
if (cache.timestamp < timestamp || cache.ver !== ver) {
log("Del", key);
window.localStorage.removeItem(key);
}
}
const bc = new BroadcastChannel("mwApiCache");
bc.addEventListener("message", e => {
if (e.data === "init")
Object.keys(sessionStorage).forEach(
key =>
key.startsWith("mwApiCache-") &&
bc.postMessage({
key: key.replace("mwApiCache-", ""),
value: JSON.parse(sessionStorage.getItem(key)),
})
);
else {
const { key, value } = e.data;
window.sessionStorage.setItem(
`mwApiCache-${key}`,
JSON.stringify(value)
);
log("Set", key, JSON.stringify(value));
}
});
bc.postMessage("init");
const getCache = (t, method, arg, day = 7) => {
const _arg = JSON.stringify(arg);
const cache = JSON.parse(
window[day ? "localStorage" : "sessionStorage"].getItem(
`mwApiCache-${_arg}`
)
);
if (!cache) {
const res = method.call(t, arg);
res.then(_res => {
log("Set", _arg, JSON.stringify(_res));
const key = `mwApiCache-${_arg}`;
const value = {
ver,
timestamp: timestamp + 1000 * 60 * 60 * 24 * day,
res: _res,
};
window[day ? "localStorage" : "sessionStorage"].setItem(
key,
JSON.stringify(value)
);
if (!day) bc.postMessage({ key: _arg, value });
return _res;
});
return res;
}
log("Get", _arg);
return $()
.promise()
.then(() => cache.res);
};
const apiFilter = (t, method, args) => {
const arg = JSON.stringify(args[0]);
switch (arg) {
case `{"action":"query","ususers":"${userName}","meta":["userinfo","siteinfo"],"list":["users"],"uiprop":["rights"],"siprop":["specialpagealiases"],"usprop":["blockinfo"]}`:
case '{"action":"query","meta":"siteinfo","siprop":"specialpagealiases","formatversion":2,"uselang":"content","maxage":3600}':
case '{"action":"query","meta":"userinfo","uiprop":["groups","rights"]}':
case `{"action":"query","prop":"revisions","titles":"User:${userName}/codemirror-mediawiki.json","rvprop":"content","rvlimit":1}`:
case '{"action":"paraminfo","modules":"main","helpformat":"html","uselang":"zh"}':
case '{"action":"paraminfo","modules":"json","helpformat":"html","uselang":"zh"}':
return getCache(t, method, args[0]);
case `{"action":"query","meta":"allmessages","ammessages":["Editnotice-${cfg.get(
"wgNamespaceNumber"
)}","Editnotice-${cfg.get("wgNamespaceNumber")}-${cfg
.get("wgPageName")
.replaceAll("_", " ")
.replace(
`${
cfg.get("wgFormattedNamespaces")[
cfg.get("wgNamespaceNumber")
]
}:`,
""
)}"],"amenableparser":1}`:
return getCache(t, method, args[0], 3);
case `{"action":"query","prop":"revisions|info","inprop":"protection|watched","format":"json","pageids":${cfg.get(
"wgArticleId"
)}}`:
return getCache(t, method, args[0], 0);
default:
if (
/^{"action":"query","meta":"allmessages","ammessages":\[".*?"\],"amlang":"zh","formatversion":2}$/.test(
arg
) ||
/^{"action":"parse","text":"<span id=\\"mw_editnotice_test_var\\".+?","preview":true,"disablelimitreport":true,"disableeditsection":true,"disabletoc":true}$/.test(
arg
)
)
return getCache(t, method, args[0]);
if (args[0]?.action === "compare")
return getCache(t, method, args[0], 0);
log("Ign", arg);
return method.apply(t, args);
}
};
window.mediaWiki.Api.prototype.get = function (...args) {
return apiFilter(this, originalMediaWikiApiPost, args);
};
window.mediaWiki.Api.prototype.post = function (...args) {
return apiFilter(this, originalMediaWikiApiPost, args);
};
}, 5);
})();