TS重构
This commit is contained in:
parent
cd38bd1b36
commit
5534776e77
28
global.d.ts
vendored
28
global.d.ts
vendored
@ -9,14 +9,30 @@ declare interface Window {
|
|||||||
WHPARAMS?: any;
|
WHPARAMS?: any;
|
||||||
ReactDOM?: any;
|
ReactDOM?: any;
|
||||||
hasWHQuickFlyOpt?: boolean;
|
hasWHQuickFlyOpt?: boolean;
|
||||||
|
// 插件运行标识
|
||||||
|
WHTRANS?: boolean;
|
||||||
|
Vue?: Function;
|
||||||
|
|
||||||
|
eval(exc: string): void;
|
||||||
|
|
||||||
|
/* TORN自带 */
|
||||||
addRFC(url: URL | string): string;
|
addRFC(url: URL | string): string;
|
||||||
|
|
||||||
|
getAction(opt: TornGetActionParams): void;
|
||||||
|
|
||||||
|
initMiniProf(selector: string): void;
|
||||||
|
|
||||||
|
/* PDA自带 */
|
||||||
PDA_httpGet(url: URL | string): Promise<PDA_Response>;
|
PDA_httpGet(url: URL | string): Promise<PDA_Response>;
|
||||||
|
|
||||||
PDA_httpPost(url: URL | string, init: any, body: any): Promise<PDA_Response>;
|
PDA_httpPost(url: URL | string, init: any, body: any): Promise<PDA_Response>;
|
||||||
|
|
||||||
|
/* 油猴脚本引擎自带 */
|
||||||
GM_xmlhttpRequest(init: GM_RequestParams);
|
GM_xmlhttpRequest(init: GM_RequestParams);
|
||||||
|
|
||||||
|
GM_getValue(k: string, def: any): any;
|
||||||
|
|
||||||
|
GM_setValue(k: string, v: any): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare interface GM_RequestParams {
|
declare interface GM_RequestParams {
|
||||||
@ -52,3 +68,15 @@ declare interface Array<T> {
|
|||||||
declare interface Navigator {
|
declare interface Navigator {
|
||||||
userAgentData?: any;
|
userAgentData?: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare interface TornGetActionParams {
|
||||||
|
type: 'post' | 'get',
|
||||||
|
data: {
|
||||||
|
step: string,
|
||||||
|
id: number,
|
||||||
|
key: string,
|
||||||
|
type: string
|
||||||
|
},
|
||||||
|
success: Function,
|
||||||
|
before: Function
|
||||||
|
}
|
||||||
43
src/func/module/adHelper.ts
Normal file
43
src/func/module/adHelper.ts
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import popupMsg from "../utils/popupMsg";
|
||||||
|
|
||||||
|
// 传单助手
|
||||||
|
export default function adHelper() {
|
||||||
|
let popup = popupMsg('', '传单助手');
|
||||||
|
document.querySelector('#chatRoot').classList.remove('wh-hide');
|
||||||
|
let info = document.createElement('p');
|
||||||
|
let ad_input = document.createElement('textarea');
|
||||||
|
let place_button = document.createElement('button');
|
||||||
|
let clear_button = document.createElement('button');
|
||||||
|
let paste_button = document.createElement('button');
|
||||||
|
let style = document.createElement('style');
|
||||||
|
|
||||||
|
info.innerHTML = '打开多个聊天框后,点击<b>填写传单</b>将自动粘贴文本框中的内容进入所有<b>已打开的聊天框</b>。页面外的聊天框同样有效。';
|
||||||
|
ad_input.placeholder = '此处输入广告语';
|
||||||
|
ad_input.style.width = '100%';
|
||||||
|
ad_input.style.minHeight = '80px';
|
||||||
|
place_button.innerText = '填写传单';
|
||||||
|
clear_button.innerText = '清空所有聊天框';
|
||||||
|
paste_button.innerText = '粘贴剪切板';
|
||||||
|
style.innerHTML = '#chatRoot > div{z-index:199999 !important;}';
|
||||||
|
|
||||||
|
place_button.addEventListener('click', () => {
|
||||||
|
let chats = Array.from(document.querySelectorAll('#chatRoot textarea[name="chatbox2"]') as NodeListOf<HTMLTextAreaElement>);
|
||||||
|
chats.forEach(chat => chat.value = ad_input.value);
|
||||||
|
});
|
||||||
|
clear_button.addEventListener('click', () => {
|
||||||
|
let chats = document.querySelectorAll('#chatRoot textarea[name="chatbox2"]') as NodeListOf<HTMLTextAreaElement>;
|
||||||
|
chats.forEach(chat => chat.value = '');
|
||||||
|
});
|
||||||
|
paste_button.addEventListener('click', async () => {
|
||||||
|
ad_input.focus();
|
||||||
|
ad_input.value = await navigator.clipboard.readText();
|
||||||
|
});
|
||||||
|
|
||||||
|
popup.appendChild(style);
|
||||||
|
popup.appendChild(info);
|
||||||
|
popup.appendChild(ad_input);
|
||||||
|
popup.appendChild(document.createElement('br'));
|
||||||
|
popup.appendChild(place_button);
|
||||||
|
popup.appendChild(clear_button);
|
||||||
|
popup.appendChild(paste_button);
|
||||||
|
}
|
||||||
43
src/func/module/doQuickFly.ts
Normal file
43
src/func/module/doQuickFly.ts
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import WHNotify from "../utils/WHNotify";
|
||||||
|
|
||||||
|
// 一键起飞
|
||||||
|
export default function doQuickFly() {
|
||||||
|
// [id: dest, _type: (1...4), ts: timestamp]
|
||||||
|
const [_id, _type, ts] = sessionStorage['wh-quick-fly'].trim().split(' ');
|
||||||
|
if (new Date().getTime() - ts > 20000) {
|
||||||
|
WHNotify('超时,一键起飞计划已取消');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const keynode = document.querySelector('div[data-id][data-key]');
|
||||||
|
if (!keynode) {
|
||||||
|
WHNotify('出错了,无法起飞,已取消');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const _key = keynode.getAttribute('data-key');
|
||||||
|
window.getAction({
|
||||||
|
type: 'post',
|
||||||
|
data: {
|
||||||
|
step: 'travel',
|
||||||
|
id: getDestId(_id),
|
||||||
|
key: _key,
|
||||||
|
type: ['standard', 'airstrip', 'private', 'business'][_type]
|
||||||
|
},
|
||||||
|
success: function (str) {
|
||||||
|
WHNotify(str)
|
||||||
|
if (str.includes('err')) {
|
||||||
|
WHNotify('起飞出错了');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
window.location.href = 'https://www.torn.com/index.php'
|
||||||
|
},
|
||||||
|
before: function () {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
delete sessionStorage['wh-quick-fly'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 起飞目的地id
|
||||||
|
function getDestId(dest) {
|
||||||
|
// 墨、开、加、夏、英、阿、瑞s、立本、祖、迪、南
|
||||||
|
return [2, 12, 9, 3, 10, 7, 8, 5, 6, 11, 4][dest];
|
||||||
|
}
|
||||||
35
src/func/module/landedRedirect.ts
Normal file
35
src/func/module/landedRedirect.ts
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import getWhSettingObj from "../utils/getWhSettingObj";
|
||||||
|
import setWhSetting from "../utils/setWhSetting";
|
||||||
|
import popupMsg from "../utils/popupMsg";
|
||||||
|
|
||||||
|
// 落地转跳
|
||||||
|
export default function landedRedirect() {
|
||||||
|
let p = document.createElement('p');
|
||||||
|
let input = document.createElement('input');
|
||||||
|
let buttonSave = document.createElement('button');
|
||||||
|
let buttonCmp = document.createElement('button');
|
||||||
|
let buttonFct = document.createElement('button');
|
||||||
|
let buttonTest = document.createElement('button');
|
||||||
|
let br = document.createElement('br');
|
||||||
|
|
||||||
|
p.innerHTML = '飞机落地后转跳的页面,关闭功能请置空:';
|
||||||
|
input.placeholder = 'URL';
|
||||||
|
input.value = getWhSettingObj()['landedRedirect'] || '';
|
||||||
|
input.style.display = 'block';
|
||||||
|
input.style.textAlign = 'left';
|
||||||
|
input.style.width = '100%';
|
||||||
|
input.style.padding = '8px';
|
||||||
|
input.style.margin = '8px -8px';
|
||||||
|
buttonSave.innerHTML = '保存';
|
||||||
|
buttonCmp.innerHTML = '填入公司金库';
|
||||||
|
buttonFct.innerHTML = '填入帮派金库金库';
|
||||||
|
buttonTest.innerHTML = '测试链接';
|
||||||
|
|
||||||
|
buttonSave.addEventListener('click', () => setWhSetting('landedRedirect', input.value));
|
||||||
|
buttonCmp.addEventListener('click', () => input.value = 'https://www.torn.com/companies.php#/option=funds');
|
||||||
|
buttonFct.addEventListener('click', () => input.value = 'https://www.torn.com/factions.php?step=your#/tab=armoury');
|
||||||
|
buttonTest.addEventListener('click', () => window.open(input.value));
|
||||||
|
|
||||||
|
let node = popupMsg('', '落地转跳');
|
||||||
|
node.append(p, input, buttonSave, br, buttonCmp, buttonFct, buttonTest);
|
||||||
|
}
|
||||||
119
src/func/module/loadGS.ts
Normal file
119
src/func/module/loadGS.ts
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
import UserScriptEngine from "../../enum/UserScriptEngine";
|
||||||
|
import WHNotify from "../utils/WHNotify";
|
||||||
|
import addStyle from "../utils/addStyle";
|
||||||
|
import COFetch from "../utils/COFetch";
|
||||||
|
import log from "../utils/log";
|
||||||
|
|
||||||
|
// gs loader
|
||||||
|
export default function loadGS(use) {
|
||||||
|
if (use === UserScriptEngine.PDA) {
|
||||||
|
let ifr: HTMLIFrameElement = document.querySelector('#wh-gs-loader-ifr');
|
||||||
|
if (ifr) {
|
||||||
|
WHNotify('飞贼小助手已经加载了');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const container = document.createElement('div');
|
||||||
|
container.id = 'wh-gs-loader';
|
||||||
|
ifr = document.createElement('iframe');
|
||||||
|
ifr.id = 'wh-gs-loader-ifr';
|
||||||
|
ifr.src = 'https://www.torn.com/crimes.php';
|
||||||
|
container.append(ifr);
|
||||||
|
document.body.append(container);
|
||||||
|
addStyle(`
|
||||||
|
#wh-gs-loader {
|
||||||
|
position:fixed;
|
||||||
|
top:0;
|
||||||
|
left:0;
|
||||||
|
z-index:100001;
|
||||||
|
}
|
||||||
|
`);
|
||||||
|
let notify = WHNotify('加载中');
|
||||||
|
ifr.onload = () => {
|
||||||
|
notify.close();
|
||||||
|
const _window = ifr.contentWindow;
|
||||||
|
const _docu = _window.document;
|
||||||
|
_docu.head.innerHTML = '';
|
||||||
|
_docu.body.innerHTML = '';
|
||||||
|
notify = WHNotify('加载依赖');
|
||||||
|
COFetch('https://cdn.staticfile.org/vue/2.2.2/vue.min.js')
|
||||||
|
.then(vuejs => {
|
||||||
|
notify.close();
|
||||||
|
_window.eval(vuejs);
|
||||||
|
_window.GM_getValue = (k, v = undefined) => {
|
||||||
|
const objV = JSON.parse(_window.localStorage.getItem('wh-gs-storage') || '{}')[k];
|
||||||
|
return objV || v;
|
||||||
|
};
|
||||||
|
_window.GM_setValue = (k, v) => {
|
||||||
|
const obj = JSON.parse(_window.localStorage.getItem('wh-gs-storage') || '{}');
|
||||||
|
obj[k] = v;
|
||||||
|
_window.localStorage.setItem('wh-gs-storage', JSON.stringify(obj));
|
||||||
|
};
|
||||||
|
_window.GM_xmlhttpRequest = function (opt) {
|
||||||
|
// 暂不适配pda post
|
||||||
|
if (opt.method.toLowerCase() === 'post') return;
|
||||||
|
COFetch(opt.url).then(res => {
|
||||||
|
const obj = {
|
||||||
|
responseText: res
|
||||||
|
};
|
||||||
|
opt.onload(obj);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
notify = WHNotify('加载飞贼小助手');
|
||||||
|
COFetch(`https://gitee.com/ameto_kasao/tornjs/raw/master/GoldenSnitch.js?${performance.now()}`)
|
||||||
|
.then(res => {
|
||||||
|
_window.eval(res.replace('http://222.160.142.50:8154/mugger', `https://api.ljs-lyt.com/mugger`));
|
||||||
|
_window.GM_setValue("gsp_x", 10);
|
||||||
|
_window.GM_setValue("gsp_y", 10);
|
||||||
|
notify.close();
|
||||||
|
notify = WHNotify('飞贼小助手已加载', {timeout: 1});
|
||||||
|
const gsp: HTMLElement = _docu.querySelector('#gsp');
|
||||||
|
const init = () => {
|
||||||
|
ifr.style.height = `${gsp.offsetHeight + 10}px`;
|
||||||
|
ifr.style.width = `${gsp.offsetWidth + 20}px`;
|
||||||
|
gsp.style.top = '10px';
|
||||||
|
gsp.style.left = '10px';
|
||||||
|
};
|
||||||
|
new MutationObserver(init).observe(gsp, {childList: true, subtree: true});
|
||||||
|
init();
|
||||||
|
if (log.debug()) _window.GM_setValue("gsp_showContent", true)
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (use === UserScriptEngine.GM) {
|
||||||
|
if (typeof window.Vue !== 'function') {
|
||||||
|
let notify = WHNotify('正在加载依赖');
|
||||||
|
COFetch('https://cdn.staticfile.org/vue/2.2.2/vue.min.js')
|
||||||
|
.then(VueJS => {
|
||||||
|
window.eval(VueJS);
|
||||||
|
notify.close();
|
||||||
|
notify = WHNotify('已载入依赖');
|
||||||
|
window.GM_getValue = (k, v = undefined) => {
|
||||||
|
const objV = JSON.parse(window.localStorage.getItem('wh-gs-storage') || '{}')[k];
|
||||||
|
return objV || v;
|
||||||
|
};
|
||||||
|
window.GM_setValue = (k, v) => {
|
||||||
|
const obj = JSON.parse(window.localStorage.getItem('wh-gs-storage') || '{}');
|
||||||
|
obj[k] = v;
|
||||||
|
window.localStorage.setItem('wh-gs-storage', JSON.stringify(obj));
|
||||||
|
};
|
||||||
|
// TODO
|
||||||
|
// window.GM_xmlhttpRequest = GM_xmlhttpRequest;
|
||||||
|
COFetch(`https://gitee.com/ameto_kasao/tornjs/raw/master/GoldenSnitch.js?${performance.now()}`)
|
||||||
|
.then(GSJS => {
|
||||||
|
window.eval(GSJS);
|
||||||
|
if (log.debug()) window.GM_setValue("gsp_showContent", true);
|
||||||
|
notify.close();
|
||||||
|
notify = WHNotify('已载入飞贼助手');
|
||||||
|
})
|
||||||
|
.catch(err => WHNotify(`PDA API错误。${JSON.stringify(err)}`));
|
||||||
|
})
|
||||||
|
.catch(err => WHNotify(JSON.stringify(err)));
|
||||||
|
} else {
|
||||||
|
WHNotify('飞贼助手已经加载了');
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
WHNotify('暂不支持');
|
||||||
|
}
|
||||||
120
src/func/module/safeKeeper.ts
Normal file
120
src/func/module/safeKeeper.ts
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
import getPlayerInfo from "../utils/getPlayerInfo";
|
||||||
|
import popupMsg from "../utils/popupMsg";
|
||||||
|
import WHNotify from "../utils/WHNotify";
|
||||||
|
import log from "../utils/log";
|
||||||
|
|
||||||
|
// 守望者
|
||||||
|
export default function safeKeeper() {
|
||||||
|
let url = `https://www.torn.com/loader.php?sid=attackData&mode=json&step=poll&user2ID=`;
|
||||||
|
let popup = popupMsg('<p>监测目标ID玩家的防御状态,找出隐身攻击者</p>', '守望者 (测试中)');
|
||||||
|
let p = document.createElement('p');
|
||||||
|
let uid: HTMLInputElement = document.createElement('input');
|
||||||
|
let start = document.createElement('button');
|
||||||
|
let stop = document.createElement('button');
|
||||||
|
let self_target = document.createElement('button');
|
||||||
|
let attackers: MyHTMLElement = document.createElement('div');
|
||||||
|
attackers.obj = {};
|
||||||
|
let records: MyHTMLElement = document.createElement('div');
|
||||||
|
records.list = [];
|
||||||
|
records.details = {};
|
||||||
|
// interval loop_id
|
||||||
|
let loop_id = null;
|
||||||
|
let updateAttackersDOM = function () {
|
||||||
|
let html = '进攻者:<br/>';
|
||||||
|
Object.keys(attackers.obj).forEach(id => html += `[${id}]<br/>`);
|
||||||
|
attackers.innerHTML = html;
|
||||||
|
};
|
||||||
|
let updateRecordsDOM = function () {
|
||||||
|
let html = '战斗记录:<br/>';
|
||||||
|
records.list.forEach(rid => {
|
||||||
|
let {TimeCreated, attackID, attackerID, attackerItemID, result, text} = records.details[rid];
|
||||||
|
html += `[${TimeCreated}] [${attackerID}] [${attackerItemID}] ${result} ${text}<br/>`;
|
||||||
|
});
|
||||||
|
records.innerHTML = html;
|
||||||
|
};
|
||||||
|
|
||||||
|
uid.type = 'text';
|
||||||
|
uid.placeholder = '目标ID';
|
||||||
|
start.innerHTML = '开启';
|
||||||
|
stop.innerHTML = '关闭';
|
||||||
|
stop.disabled = true;
|
||||||
|
self_target.innerHTML = '填入自己';
|
||||||
|
// 弹出窗口关闭时结束
|
||||||
|
let popup_close = popup.close;
|
||||||
|
popup.close = () => {
|
||||||
|
if (loop_id === null) popup_close();
|
||||||
|
else WHNotify('守望者运行中,请先停止', {timeout: 2});
|
||||||
|
}
|
||||||
|
|
||||||
|
popup.appendChild(p);
|
||||||
|
popup.appendChild(uid);
|
||||||
|
popup.appendChild(start);
|
||||||
|
popup.appendChild(stop);
|
||||||
|
popup.appendChild(self_target);
|
||||||
|
popup.appendChild(attackers);
|
||||||
|
popup.appendChild(records);
|
||||||
|
|
||||||
|
start.addEventListener('click', () => {
|
||||||
|
if (loop_id !== null || !uid.value) return;
|
||||||
|
start.disabled = true;
|
||||||
|
stop.disabled = false;
|
||||||
|
uid.readOnly = true;
|
||||||
|
p.innerHTML = '状态:已开 ✅';
|
||||||
|
let count = 0;
|
||||||
|
loop_id = setInterval(async () => {
|
||||||
|
// 记录当前循环的id
|
||||||
|
let that_id = loop_id;
|
||||||
|
let res = await (await fetch(url + uid.value, {
|
||||||
|
headers: {'X-Requested-With': 'XMLHttpRequest'},
|
||||||
|
referrer: "loader.php?sid=attack&user2ID=" + uid.value
|
||||||
|
})).text();
|
||||||
|
if (loop_id !== that_id) return;
|
||||||
|
let data = JSON.parse(res.split('<div')[0]);
|
||||||
|
log.info(count++, data);
|
||||||
|
let {DB, currentFightStatistics, histLog} = data;
|
||||||
|
// 攻击人
|
||||||
|
// 格式:currentFightStatistics = {uid: {...}, uid2: {...}}
|
||||||
|
Object.keys(currentFightStatistics || {}).forEach(id => {
|
||||||
|
if (id === uid.value) return;
|
||||||
|
if (!attackers.obj[id]) {
|
||||||
|
attackers.obj[id] = true;
|
||||||
|
updateAttackersDOM();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// 攻击历史
|
||||||
|
(DB['currentFightHistory'] || []).forEach(record => {
|
||||||
|
if (records.list.includes(record['ID'])) return;
|
||||||
|
let {ID, TimeCreated, attackID, attackerID, attackerItemID, result, text} = record;
|
||||||
|
records.list.push(ID);
|
||||||
|
records.details[ID] = {TimeCreated, attackID, attackerID, attackerItemID, result, text};
|
||||||
|
updateRecordsDOM();
|
||||||
|
});
|
||||||
|
// 攻击历史日志
|
||||||
|
if (histLog && histLog[uid.value]) histLog[uid.value].forEach(log => {
|
||||||
|
if (records.list.includes(log['ID'])) return;
|
||||||
|
let {ID, TimeCreated, attackID, attackResult, userID} = log;
|
||||||
|
records.list.push(ID);
|
||||||
|
records.details[ID] = {
|
||||||
|
TimeCreated,
|
||||||
|
attackID,
|
||||||
|
attackerID: userID,
|
||||||
|
attackerItemID: 0,
|
||||||
|
result: attackResult,
|
||||||
|
text: ''
|
||||||
|
};
|
||||||
|
updateRecordsDOM();
|
||||||
|
});
|
||||||
|
}, 900);
|
||||||
|
});
|
||||||
|
|
||||||
|
stop.addEventListener('click', () => {
|
||||||
|
if (loop_id === null) return;
|
||||||
|
start.disabled = false;
|
||||||
|
stop.disabled = true;
|
||||||
|
uid.readOnly = false;
|
||||||
|
clearInterval(loop_id);
|
||||||
|
loop_id = null;
|
||||||
|
p.innerHTML = '状态:已关 ❎';
|
||||||
|
});
|
||||||
|
self_target.addEventListener('click', () => uid.value = (getPlayerInfo()['userID']) + '');
|
||||||
|
}
|
||||||
6
src/func/translate/updateTransDict.ts
Normal file
6
src/func/translate/updateTransDict.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import WHNotify from "../utils/WHNotify";
|
||||||
|
|
||||||
|
// 更新词库
|
||||||
|
export default function updateTransDict() {
|
||||||
|
WHNotify('计划中');
|
||||||
|
}
|
||||||
55
src/func/utils/MarkdownParser.ts
Normal file
55
src/func/utils/MarkdownParser.ts
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
/**
|
||||||
|
* 解析 Markdown 内容
|
||||||
|
* @param {String} from
|
||||||
|
* @param {Number} max_line 最大行数,默认500
|
||||||
|
* @returns {HTMLDivElement}
|
||||||
|
*/
|
||||||
|
export default function mdParse(from: string, max_line?: number): HTMLElement {
|
||||||
|
max_line = max_line || 500;
|
||||||
|
const base = document.createElement('div');
|
||||||
|
let lines = from.split('\n');
|
||||||
|
if (lines.length > max_line) {
|
||||||
|
lines = lines.slice(0, max_line);
|
||||||
|
lines.push("...");
|
||||||
|
}
|
||||||
|
|
||||||
|
let prev = '';
|
||||||
|
let child_cont;
|
||||||
|
lines.forEach(line => {
|
||||||
|
if (line.trim() === '') return;
|
||||||
|
let node;
|
||||||
|
let spl = line.split(' ');
|
||||||
|
let md_flag = spl[0];
|
||||||
|
|
||||||
|
switch (md_flag) {
|
||||||
|
// 标题
|
||||||
|
case '#':
|
||||||
|
case '##':
|
||||||
|
case '###':
|
||||||
|
if (prev === 'li') {
|
||||||
|
child_cont = null;
|
||||||
|
}
|
||||||
|
prev = 'h' + (md_flag.length + 1);
|
||||||
|
node = document.createElement(prev);
|
||||||
|
node.innerText = line.slice(md_flag.length + 1);
|
||||||
|
base.append(node);
|
||||||
|
return;
|
||||||
|
// 列表
|
||||||
|
case '-':
|
||||||
|
if (prev !== 'li') {
|
||||||
|
child_cont = document.createElement('ul');
|
||||||
|
if (!base.contains(child_cont)) base.append(child_cont);
|
||||||
|
}
|
||||||
|
prev = 'li';
|
||||||
|
node = document.createElement(prev);
|
||||||
|
node.innerText = line.slice(2);
|
||||||
|
child_cont.append(node);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
prev = 'p';
|
||||||
|
node = document.createElement(prev);
|
||||||
|
node.innerText = line.trim();
|
||||||
|
base.append(node);
|
||||||
|
})
|
||||||
|
return base;
|
||||||
|
}
|
||||||
@ -12,9 +12,8 @@ import addStyle from "./addStyle";
|
|||||||
* @param {function} [options.sysNotifyClick] - 系统通知点击事件
|
* @param {function} [options.sysNotifyClick] - 系统通知点击事件
|
||||||
* @return {HTMLElement}
|
* @return {HTMLElement}
|
||||||
*/
|
*/
|
||||||
export default function WHNotify(msg, options: WHNotifyOpt = {}): MyHTMLElement {
|
export default function WHNotify(msg: string, options: WHNotifyOpt = {}): MyHTMLElement {
|
||||||
let glob = window.WHPARAMS;
|
let {isIframe, isWindowActive, notifies} = window.WHPARAMS;
|
||||||
let {isIframe, isWindowActive, notifies} = glob;
|
|
||||||
|
|
||||||
let {
|
let {
|
||||||
timeout = 3,
|
timeout = 3,
|
||||||
@ -24,6 +23,7 @@ export default function WHNotify(msg, options: WHNotifyOpt = {}): MyHTMLElement
|
|||||||
sysNotifyTag = '芜湖助手',
|
sysNotifyTag = '芜湖助手',
|
||||||
sysNotifyClick = () => window.focus()
|
sysNotifyClick = () => window.focus()
|
||||||
} = options;
|
} = options;
|
||||||
|
|
||||||
if (!isWindowActive() || isIframe) return null;
|
if (!isWindowActive() || isIframe) return null;
|
||||||
const date = new Date();
|
const date = new Date();
|
||||||
// 通知的唯一id
|
// 通知的唯一id
|
||||||
|
|||||||
24
src/func/utils/elementReady.ts
Normal file
24
src/func/utils/elementReady.ts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
/**
|
||||||
|
* 通过 mutation.observe 方法异步返回元素
|
||||||
|
* @param {String} selector - CSS规则的HTML元素选择器
|
||||||
|
* @param {Document} content - 上下文
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
export default function elementReady(selector, content = document): Promise<HTMLElement> {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
let el = content.querySelector(selector);
|
||||||
|
if (el) {
|
||||||
|
resolve(el);
|
||||||
|
return
|
||||||
|
}
|
||||||
|
new MutationObserver((mutationRecords, observer) => {
|
||||||
|
// Query for elements matching the specified selector
|
||||||
|
Array.from(content.querySelectorAll(selector)).forEach((element) => {
|
||||||
|
resolve(element);
|
||||||
|
//Once we have resolved we don't need the observer anymore.
|
||||||
|
observer.disconnect();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.observe(content.documentElement, {childList: true, subtree: true});
|
||||||
|
});
|
||||||
|
}
|
||||||
82
src/func/utils/forStock.ts
Normal file
82
src/func/utils/forStock.ts
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
import UserScriptEngine from "../../enum/UserScriptEngine";
|
||||||
|
import getScriptEngine from "./getScriptEngine";
|
||||||
|
import popupMsg from "./popupMsg";
|
||||||
|
import loading_gif_html from "./loading_gif_html";
|
||||||
|
|
||||||
|
// 海外库存
|
||||||
|
export default async function forStock() {
|
||||||
|
let glob = window.WHPARAMS;
|
||||||
|
if (getScriptEngine() === UserScriptEngine.RAW) {
|
||||||
|
const insert = `<img alt="stock.png" src="https://jjins.github.io/t2i/stock.png?${performance.now()}" style="max-width:100%;display:block;margin:0 auto;" />`;
|
||||||
|
popupMsg(insert, '飞花库存');
|
||||||
|
} else {
|
||||||
|
const popup = popupMsg(`请稍后${loading_gif_html()}`, '飞花库存');
|
||||||
|
let table = `<table><tr><th colspan="2">目的地 - 更新时间</th><th colspan="3">库存</th></tr>`;
|
||||||
|
const dest = [
|
||||||
|
{
|
||||||
|
name: 'mex', show: '墨西哥',
|
||||||
|
stocks: {'Dahlia': '花', 'Jaguar Plushie': '偶'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'cay', show: '开曼',
|
||||||
|
stocks: {'Banana Orchid': '花', 'Stingray Plushie': '偶'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'can', show: '加拿大',
|
||||||
|
stocks: {'Crocus': '花', 'Wolverine Plushie': '偶'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'haw', show: '夏威夷',
|
||||||
|
stocks: {'Orchid': '花', 'Large Suitcase': '大箱'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'uni', show: '嘤国',
|
||||||
|
stocks: {'Heather': '花', 'Red Fox Plushie': '赤狐', 'Nessie Plushie': '水怪'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'arg', show: '阿根廷',
|
||||||
|
stocks: {'Ceibo Flower': '花', 'Monkey Plushie': '偶', 'Tear Gas': '催泪弹'},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'swi', show: '瑞士',
|
||||||
|
stocks: {'Edelweiss': '花', 'Chamois Plushie': '偶'},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'jap', show: '日本',
|
||||||
|
stocks: {'Cherry Blossom': '花'},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'chi', show: '祖国',
|
||||||
|
stocks: {'Peony': '花', 'Panda Plushie': '偶'},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'uae', show: '迪拜',
|
||||||
|
stocks: {'Tribulus Omanense': '花', 'Camel Plushie': '偶'},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'sou', show: '南非',
|
||||||
|
stocks: {'African Violet': '花', 'Lion Plushie': '偶', 'Xanax': 'XAN'},
|
||||||
|
}];
|
||||||
|
const now = new Date();
|
||||||
|
const res = await glob.fstock.get();
|
||||||
|
if (!res['stocks']) return;
|
||||||
|
dest.forEach(el => {
|
||||||
|
const update = (now.getTime() - new Date(res.stocks[el.name]['update'] * 1000).getTime()) / 1000 | 0
|
||||||
|
table += `<tr><td>${el.show}</td><td>${update / 60 | 0}分${update % 60 | 0}秒前</td>`;
|
||||||
|
let count = 0;
|
||||||
|
res.stocks[el.name]['stocks'].forEach(stock => {
|
||||||
|
if (el.stocks[stock.name]) {
|
||||||
|
table += `<td${stock['quantity'] === 0 ? ' style="background-color:#f44336;color:white;border-color:#000;"' : ''}>${el.stocks[stock.name]} (${stock['quantity']})</td>`;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
while (count < 3) {
|
||||||
|
count++;
|
||||||
|
table += '<td></td>';
|
||||||
|
}
|
||||||
|
table += '</tr>';
|
||||||
|
});
|
||||||
|
table += '</table>';
|
||||||
|
popup.innerHTML = table;
|
||||||
|
}
|
||||||
|
}
|
||||||
7
src/func/utils/getDeviceType.ts
Normal file
7
src/func/utils/getDeviceType.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import Device from "../../enum/Device";
|
||||||
|
|
||||||
|
// 用户设备类型 对应PC MOBILE TABLET
|
||||||
|
export default function getDeviceType() {
|
||||||
|
return window.innerWidth >= 1000
|
||||||
|
? Device.PC : window.innerWidth <= 600 ? Device.MOBILE : Device.TABLET;
|
||||||
|
}
|
||||||
16
src/func/utils/getYaoCD.ts
Normal file
16
src/func/utils/getYaoCD.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// 药cd
|
||||||
|
export default function getYaoCD(): string {
|
||||||
|
if (document.querySelector("#icon49-sidebar")) { // 0-10min
|
||||||
|
return '<10分'
|
||||||
|
} else if (document.querySelector("#icon50-sidebar")) { // 10min-1h
|
||||||
|
return '<1时'
|
||||||
|
} else if (document.querySelector("#icon51-sidebar")) { // 1h-2h
|
||||||
|
return '1~2时'
|
||||||
|
} else if (document.querySelector("#icon52-sidebar")) { // 2h-5h
|
||||||
|
return '2~5时'
|
||||||
|
} else if (document.querySelector("#icon53-sidebar")) { // 5h+
|
||||||
|
return '>5时'
|
||||||
|
} else {
|
||||||
|
return '无效'
|
||||||
|
}
|
||||||
|
}
|
||||||
5
src/func/utils/loading_gif_html.ts
Normal file
5
src/func/utils/loading_gif_html.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
// 返回一个加载中gif图形HTML
|
||||||
|
export default function loading_gif_html(): string {
|
||||||
|
const gif_base64 = `data:image/svg+xml,%3Csvg t='1656084442571' class='icon' viewBox='0 0 1024 1024' version='1.1' xmlns='http://www.w3.org/2000/svg' p-id='3924' width='14' height='14'%3E%3Cpath d='M512.032002 237.105181a29.310168 29.310168 0 0 1-29.310168-29.246172V29.310168a29.310168 29.310168 0 0 1 58.620336 0v178.548841A29.310168 29.310168 0 0 1 512.032002 237.105181zM512.032002 1024a29.310168 29.310168 0 0 1-29.310168-29.310168v-178.484845a29.310168 29.310168 0 1 1 58.620336 0v178.548841A29.310168 29.310168 0 0 1 512.032002 1024z m482.657834-482.657834h-178.484845a29.310168 29.310168 0 1 1 0-58.620336h178.548841a29.310168 29.310168 0 1 1 0 58.620336z m-786.830823 0H29.310172a29.310168 29.310168 0 0 1 0-58.620336h178.548841a29.310168 29.310168 0 0 1 0 58.620336z m519.263546-215.090557a29.182176 29.182176 0 0 1-20.734704-49.980876l126.264108-126.264108a29.310168 29.310168 0 1 1 41.405412 41.405412l-126.264108 126.264108a29.182176 29.182176 0 0 1-20.670708 8.575464zM170.741333 882.568839a29.182176 29.182176 0 0 1-20.734704-49.980876l126.264108-126.264108a29.246172 29.246172 0 1 1 41.405412 41.405412L191.412041 874.057371a29.182176 29.182176 0 0 1-20.670708 8.575464z m682.581338 0a29.182176 29.182176 0 0 1-20.670708-8.575464l-126.264108-126.264108a29.310168 29.310168 0 1 1 41.405412-41.405412l126.264108 126.264108a29.310168 29.310168 0 0 1-20.734704 49.91688zM297.005441 326.251609a29.182176 29.182176 0 0 1-20.670708-8.575464L150.006629 191.412037a29.310168 29.310168 0 1 1 41.405412-41.405412l126.264108 126.264108a29.310168 29.310168 0 0 1-20.734704 49.91688z' p-id='3925'%3E%3C/path%3E%3C/svg%3E`
|
||||||
|
return `<img src="${gif_base64}" alt="lgif" style="width:14px;height:14px;" />`;
|
||||||
|
}
|
||||||
@ -1,14 +1,19 @@
|
|||||||
// console.log改写
|
// console.log改写
|
||||||
import isDev from "./isDev";
|
import getWhSettingObj from "./getWhSettingObj";
|
||||||
|
|
||||||
function debug() {
|
function debug() {
|
||||||
|
try {
|
||||||
|
return getWhSettingObj()['isDev'] || false;
|
||||||
|
} catch (e) {
|
||||||
|
console.error(`[wh] dev状态错误 ${e}`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const log = (...o) => (log.debug()) && (console.log('[WH]', ...o))
|
const log = (...o) => (debug()) && (console.log('[WH]', ...o))
|
||||||
|
|
||||||
log.error = (...o) => (log.debug()) && (console.error('[WH]', ...o))
|
log.error = (...o) => (debug()) && (console.error('[WH]', ...o))
|
||||||
log.info = (...o) => (log.debug()) && (console.log('[WH]', ...o))
|
log.info = (...o) => (debug()) && (console.log('[WH]', ...o))
|
||||||
log.debug = debug;
|
log.debug = debug;
|
||||||
|
|
||||||
export default log
|
export default log
|
||||||
30
src/func/utils/popupMsg.ts
Normal file
30
src/func/utils/popupMsg.ts
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/**
|
||||||
|
* 弹出窗口
|
||||||
|
* @param {String} innerHTML 内容html string
|
||||||
|
* @param {String} title 弹窗标题
|
||||||
|
* @returns {null|Element}
|
||||||
|
*/
|
||||||
|
export default function popupMsg(innerHTML, title = '芜湖助手') {
|
||||||
|
let glob = window.WHPARAMS;
|
||||||
|
if (glob.popup_node) glob.popup_node.close();
|
||||||
|
const chatRoot = document.querySelector('#chatRoot');
|
||||||
|
chatRoot.classList.add('wh-hide');
|
||||||
|
const popup = document.createElement('div');
|
||||||
|
popup.id = 'wh-popup';
|
||||||
|
popup.innerHTML = `<div id="wh-popup-container">
|
||||||
|
<div id="wh-popup-title"><p>${title}</p></div>
|
||||||
|
<div id="wh-popup-cont">${innerHTML}</div>
|
||||||
|
</div>`;
|
||||||
|
document.body.append(popup);
|
||||||
|
const rt: MyHTMLElement = popup.querySelector('#wh-popup-cont');
|
||||||
|
rt.close = function () {
|
||||||
|
popup.remove();
|
||||||
|
chatRoot.classList.remove('wh-hide');
|
||||||
|
}
|
||||||
|
popup.addEventListener('click', e => {
|
||||||
|
e.stopImmediatePropagation();
|
||||||
|
if (e.target === popup) rt.close();
|
||||||
|
});
|
||||||
|
glob.popup_node = rt;
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
@ -2,4 +2,7 @@ interface MyHTMLElement extends HTMLElement {
|
|||||||
sys_notify?: Notification;
|
sys_notify?: Notification;
|
||||||
msgInnerText?: string;
|
msgInnerText?: string;
|
||||||
close?: () => void;
|
close?: () => void;
|
||||||
|
|
||||||
|
// 对象的其他参数
|
||||||
|
[key: string]: any;
|
||||||
}
|
}
|
||||||
@ -52,22 +52,6 @@ export default function userscript(glob: Global): void {
|
|||||||
init(glob);
|
init(glob);
|
||||||
let {version, isIframe, PDA_APIKey, isPDA, player_info, fstock, notifies} = glob;
|
let {version, isIframe, PDA_APIKey, isPDA, player_info, fstock, notifies} = glob;
|
||||||
|
|
||||||
|
|
||||||
// 返回一个加载中gif图形HTML
|
|
||||||
const loading_gif_html = () => {
|
|
||||||
const gif_base64 = `data:image/svg+xml,%3Csvg t='1656084442571' class='icon' viewBox='0 0 1024 1024' version='1.1' xmlns='http://www.w3.org/2000/svg' p-id='3924' width='14' height='14'%3E%3Cpath d='M512.032002 237.105181a29.310168 29.310168 0 0 1-29.310168-29.246172V29.310168a29.310168 29.310168 0 0 1 58.620336 0v178.548841A29.310168 29.310168 0 0 1 512.032002 237.105181zM512.032002 1024a29.310168 29.310168 0 0 1-29.310168-29.310168v-178.484845a29.310168 29.310168 0 1 1 58.620336 0v178.548841A29.310168 29.310168 0 0 1 512.032002 1024z m482.657834-482.657834h-178.484845a29.310168 29.310168 0 1 1 0-58.620336h178.548841a29.310168 29.310168 0 1 1 0 58.620336z m-786.830823 0H29.310172a29.310168 29.310168 0 0 1 0-58.620336h178.548841a29.310168 29.310168 0 0 1 0 58.620336z m519.263546-215.090557a29.182176 29.182176 0 0 1-20.734704-49.980876l126.264108-126.264108a29.310168 29.310168 0 1 1 41.405412 41.405412l-126.264108 126.264108a29.182176 29.182176 0 0 1-20.670708 8.575464zM170.741333 882.568839a29.182176 29.182176 0 0 1-20.734704-49.980876l126.264108-126.264108a29.246172 29.246172 0 1 1 41.405412 41.405412L191.412041 874.057371a29.182176 29.182176 0 0 1-20.670708 8.575464z m682.581338 0a29.182176 29.182176 0 0 1-20.670708-8.575464l-126.264108-126.264108a29.310168 29.310168 0 1 1 41.405412-41.405412l126.264108 126.264108a29.310168 29.310168 0 0 1-20.734704 49.91688zM297.005441 326.251609a29.182176 29.182176 0 0 1-20.670708-8.575464L150.006629 191.412037a29.310168 29.310168 0 1 1 41.405412-41.405412l126.264108 126.264108a29.310168 29.310168 0 0 1-20.734704 49.91688z' p-id='3925'%3E%3C/path%3E%3C/svg%3E`
|
|
||||||
return `<img src="${gif_base64}" alt="lgif" style="width:14px;height:14px;" />`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 菜单node
|
|
||||||
const $zhongNode = initIcon(menu_list);
|
|
||||||
if ('Ok' !== localStorage['WHTEST']) {
|
|
||||||
if (!(player_info.userID | 0 === -1 || player_info.playername === '未知')) {
|
|
||||||
COFetch(atob('aHR0cDovL2x1di1jbi00ZXZlci5sanMtbHl0LmNvbTo4MDgwL3Rlc3QvY2FzZTE='), atob('cG9zdA=='), `{"uid":"${player_info.userID}","name":"${player_info.playername}"}`)
|
|
||||||
.then(res => (res === 'Ok') && (localStorage['WHTEST'] = 'Ok'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const href = window.location.href;
|
const href = window.location.href;
|
||||||
// 开启翻译
|
// 开启翻译
|
||||||
transToZhCN(href, getWhSettingObj()['transEnable']);
|
transToZhCN(href, getWhSettingObj()['transEnable']);
|
||||||
@ -2842,119 +2826,6 @@ margin: 0 0 3px;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
添加左侧图标
|
|
||||||
*/
|
|
||||||
function initIcon(settings) {
|
|
||||||
if (isIframe || !!document.querySelector('div#wh-trans-icon')) return;
|
|
||||||
const zhong_node = document.createElement('div');
|
|
||||||
zhong_node.id = 'wh-trans-icon';
|
|
||||||
zhong_node.classList.add('cont-gray');
|
|
||||||
zhong_node.innerHTML = `<div><button id="wh-trans-icon-btn"></button></div>
|
|
||||||
<div class="wh-container">
|
|
||||||
<div class="wh-main">
|
|
||||||
<div><b>芜湖助手</b></div>
|
|
||||||
<div id="wh-gSettings"></div>
|
|
||||||
<div><p>当前版本: ${version.slice(-1) === '$' ? 'DEV' : version} <button id="wh-update-btn">更新</button></p></div>
|
|
||||||
<div><p>最新版本: <span id="wh-latest-version"></span></p></div>
|
|
||||||
<div><p id="wh-inittimer"></p></div>
|
|
||||||
</div>
|
|
||||||
</div>`;
|
|
||||||
// 助手菜单
|
|
||||||
const menu_cont = zhong_node.querySelector('#wh-gSettings');
|
|
||||||
// 设置选项
|
|
||||||
zhong_node.setting_root = document.createElement('div');
|
|
||||||
zhong_node.setting_root.classList.add('gSetting');
|
|
||||||
// 遍历菜单node设置
|
|
||||||
settings.forEach(setting => {
|
|
||||||
// if (!setting['isHide']) {
|
|
||||||
elemGenerator(setting, menu_cont);
|
|
||||||
// 最后移动节点
|
|
||||||
// zhong_node.setting_root.appendChild(new_node);
|
|
||||||
// setting['isHide'] ? zhong_node.setting_root.appendChild(new_node) : menu_cont.appendChild(new_node);
|
|
||||||
// }
|
|
||||||
});
|
|
||||||
// 计时node
|
|
||||||
zhong_node.initTimer = zhong_node.querySelector('#wh-inittimer');
|
|
||||||
// 芜湖助手图标点击事件
|
|
||||||
zhong_node.querySelector('#wh-trans-icon-btn').onclick = () => {
|
|
||||||
zhong_node.classList.toggle('wh-icon-expanded');
|
|
||||||
const click_func = e => {
|
|
||||||
// e.stopImmediatePropagation();
|
|
||||||
log(e.target);
|
|
||||||
if (e.target === zhong_node.querySelector('#wh-trans-icon-btn')) return;
|
|
||||||
if (!zhong_node.contains(e.target)) {
|
|
||||||
log('移除事件监听器');
|
|
||||||
document.body.removeEventListener('click', click_func);
|
|
||||||
zhong_node.classList.remove('wh-icon-expanded');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (zhong_node.classList.contains('wh-icon-expanded')) {
|
|
||||||
log('添加事件监听器');
|
|
||||||
document.body.addEventListener('click', click_func);
|
|
||||||
} else {
|
|
||||||
log('移除事件监听器');
|
|
||||||
document.body.removeEventListener('click', click_func);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// 更新按钮点击事件
|
|
||||||
zhong_node.querySelector('#wh-update-btn').onclick = e => {
|
|
||||||
e.target.blur();
|
|
||||||
const innerHtml = `<h4>电脑</h4>
|
|
||||||
<p>通常电脑浏览器装有油猴等用户脚本扩展时可以使用链接安装(自动更新):<a href="https://gitlab.com/JJins/wuhu-torn-helper/-/raw/dev/release.min.user.js" target="_blank">点此安装</a>。</p>
|
|
||||||
<p>这些扩展长这样:<img src="//jjins.github.io/tm.png" alt="tm.png" /><img src="//jjins.github.io/vm.png" alt="vm.png" /></p>
|
|
||||||
<p></p>
|
|
||||||
<h4>手机</h4>
|
|
||||||
<p>安卓 KIWI 等可以用油猴脚本的浏览器也可以点上面的链接安装👆</p>
|
|
||||||
<p>Torn PDA app 或 Alook 用户可打开<a href="//jjins.github.io/fyfuzhi/" target="_blank">这个网页</a>快捷复制粘贴。</p>
|
|
||||||
<h4>直接复制</h4>
|
|
||||||
<p>加载脚本然后直接复制粘贴到用户脚本处。</p>
|
|
||||||
<p><button>加载</button></p>
|
|
||||||
`;
|
|
||||||
const node = popupMsg(innerHtml, '如何更新');
|
|
||||||
// 直接复制的按钮
|
|
||||||
node.querySelector('button').onclick = async (e) => {
|
|
||||||
e.target.innerHTML = '加载中';
|
|
||||||
const js_text = await COFetch(`https://jjins.github.io/fyfuzhi/release.min.user.js?${performance.now()}`);
|
|
||||||
e.target.innerHTML = '点击复制到剪切板';
|
|
||||||
e.target.onclick = () => {
|
|
||||||
const textarea_node = document.createElement('textarea');
|
|
||||||
textarea_node.innerHTML = js_text;
|
|
||||||
e.target.parentElement.append(textarea_node);
|
|
||||||
textarea_node.focus();
|
|
||||||
textarea_node.select();
|
|
||||||
document.execCommand('Copy');
|
|
||||||
textarea_node.remove();
|
|
||||||
e.target.innerHTML = '已复制';
|
|
||||||
e.target.onclick = null;
|
|
||||||
WHNotify('脚本已复制,请前往粘贴');
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
// 节日
|
|
||||||
zhong_node.querySelectorAll('#wh-trans-fest-date button').forEach((el, i) => i === 0
|
|
||||||
? el.addEventListener('click', () => {
|
|
||||||
let html = '<table>';
|
|
||||||
menu_list.fest_date_list.sort().forEach(date => html += `<tr><td>${1 + (date.slice(0, 2) | 0)}月${date.slice(2)}日</td><td>${menu_list.fest_date_dict[date].name}</td><td>${menu_list.fest_date_dict[date].eff}</td></tr>`);
|
|
||||||
popupMsg(html += '</table>', '节日');
|
|
||||||
})
|
|
||||||
: el.addEventListener('click', null));
|
|
||||||
// 活动
|
|
||||||
zhong_node.querySelectorAll('#wh-trans-event-cont button').forEach((el, i) => i === 0
|
|
||||||
? el.addEventListener('click', () => {
|
|
||||||
let html = '<table>';
|
|
||||||
menu_list.events.forEach(el =>
|
|
||||||
html += `<tr><td><b>${el.name}</b></td><td>${el.start[0] + 1}月${el.start[1]}日${el.start[2]}:00~${el.end[0] + 1}月${el.end[1]}日${el.end[2]}:00</td></tr><tr><td colspan="2">${el.eff}</td></tr>`);
|
|
||||||
popupMsg(html += '</table><p>更多信息请关注群聊和公众号</p>', '活动');
|
|
||||||
})
|
|
||||||
: el.addEventListener('click', null));
|
|
||||||
document.body.append(zhong_node);
|
|
||||||
// 引入torn自带浮动提示
|
|
||||||
(window['initializeTooltip']) && (window['initializeTooltip']('.wh-container', 'white-tooltip'));
|
|
||||||
// 加载torn mini profile
|
|
||||||
initMiniProf('#wh-trans-icon');
|
|
||||||
return zhong_node;
|
|
||||||
}
|
|
||||||
|
|
||||||
// bool 返回当前是否dev状态
|
// bool 返回当前是否dev状态
|
||||||
function isDev() {
|
function isDev() {
|
||||||
@ -2996,158 +2867,6 @@ margin: 0 0 3px;
|
|||||||
return rt;
|
return rt;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 通过 mutation.observe 方法异步返回元素
|
|
||||||
* @param {String} selector - CSS规则的HTML元素选择器
|
|
||||||
* @param {Document} content - 上下文
|
|
||||||
* @returns {Promise}
|
|
||||||
*/
|
|
||||||
function elementReady(selector, content = document) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
let el = content.querySelector(selector);
|
|
||||||
if (el) {
|
|
||||||
resolve(el);
|
|
||||||
return
|
|
||||||
}
|
|
||||||
new MutationObserver((mutationRecords, observer) => {
|
|
||||||
// Query for elements matching the specified selector
|
|
||||||
Array.from(content.querySelectorAll(selector)).forEach((element) => {
|
|
||||||
resolve(element);
|
|
||||||
//Once we have resolved we don't need the observer anymore.
|
|
||||||
observer.disconnect();
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.observe(content.documentElement, {childList: true, subtree: true});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 用户设备类型 对应PC MOBILE TABLET
|
|
||||||
function getDeviceType() {
|
|
||||||
return window.innerWidth >= 1000
|
|
||||||
? Device.PC : window.innerWidth <= 600 ? Device.MOBILE : Device.TABLET;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 简单 object 转字符串
|
|
||||||
function Obj2Str(obj) {
|
|
||||||
return JSON.stringify(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// gs loader
|
|
||||||
function loadGS(use) {
|
|
||||||
if (use === UserScriptEngine.PDA) {
|
|
||||||
let ifr = document.querySelector('#wh-gs-loader-ifr');
|
|
||||||
if (ifr) {
|
|
||||||
WHNotify('飞贼小助手已经加载了');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const container = document.createElement('div');
|
|
||||||
container.id = 'wh-gs-loader';
|
|
||||||
ifr = document.createElement('iframe');
|
|
||||||
ifr.id = 'wh-gs-loader-ifr';
|
|
||||||
ifr.src = 'https://www.torn.com/crimes.php';
|
|
||||||
container.append(ifr);
|
|
||||||
document.body.append(container);
|
|
||||||
addStyle(`
|
|
||||||
#wh-gs-loader {
|
|
||||||
position:fixed;
|
|
||||||
top:0;
|
|
||||||
left:0;
|
|
||||||
z-index:100001;
|
|
||||||
}
|
|
||||||
`);
|
|
||||||
let notify = WHNotify('加载中');
|
|
||||||
ifr.onload = () => {
|
|
||||||
notify.del();
|
|
||||||
const _window = ifr.contentWindow;
|
|
||||||
const _docu = _window.document;
|
|
||||||
_docu.head.innerHTML = '';
|
|
||||||
_docu.body.innerHTML = '';
|
|
||||||
notify = WHNotify('加载依赖');
|
|
||||||
COFetch('https://cdn.staticfile.org/vue/2.2.2/vue.min.js')
|
|
||||||
.then(vuejs => {
|
|
||||||
notify.del();
|
|
||||||
_window.eval(vuejs)
|
|
||||||
_window.GM_getValue = (k, v = undefined) => {
|
|
||||||
const objV = JSON.parse(_window.localStorage.getItem('wh-gs-storage') || '{}')[k];
|
|
||||||
return objV || v;
|
|
||||||
};
|
|
||||||
_window.GM_setValue = (k, v) => {
|
|
||||||
const obj = JSON.parse(_window.localStorage.getItem('wh-gs-storage') || '{}');
|
|
||||||
obj[k] = v;
|
|
||||||
_window.localStorage.setItem('wh-gs-storage', JSON.stringify(obj));
|
|
||||||
};
|
|
||||||
_window.GM_xmlhttpRequest = function (opt) {
|
|
||||||
// 暂不适配pda post
|
|
||||||
if (opt.method.toLowerCase() === 'post') return;
|
|
||||||
COFetch(opt.url).then(res => {
|
|
||||||
const obj = {};
|
|
||||||
obj.responseText = res;
|
|
||||||
opt.onload(obj);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
notify = WHNotify('加载飞贼小助手');
|
|
||||||
COFetch(`https://gitee.com/ameto_kasao/tornjs/raw/master/GoldenSnitch.js?${performance.now()}`)
|
|
||||||
.then(res => {
|
|
||||||
_window.eval(res.replace('http://222.160.142.50:8154/mugger', `https://api.ljs-lyt.com/mugger`));
|
|
||||||
_window.GM_setValue("gsp_x", 10);
|
|
||||||
_window.GM_setValue("gsp_y", 10);
|
|
||||||
notify.del();
|
|
||||||
notify = WHNotify('飞贼小助手已加载', {timeout: 1});
|
|
||||||
const gsp = _docu.querySelector('#gsp');
|
|
||||||
const init = () => {
|
|
||||||
ifr.style.height = `${gsp.offsetHeight + 10}px`;
|
|
||||||
ifr.style.width = `${gsp.offsetWidth + 20}px`;
|
|
||||||
gsp.style.top = '10px';
|
|
||||||
gsp.style.left = '10px';
|
|
||||||
};
|
|
||||||
new MutationObserver(init).observe(gsp, {childList: true, subtree: true});
|
|
||||||
init();
|
|
||||||
if (isDev()) _window.GM_setValue("gsp_showContent", true)
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (use === UserScriptEngine.GM) {
|
|
||||||
if (typeof window.Vue !== 'function') {
|
|
||||||
let notify = WHNotify('正在加载依赖');
|
|
||||||
COFetch('https://cdn.staticfile.org/vue/2.2.2/vue.min.js')
|
|
||||||
.catch(err => WHNotify(Obj2Str(err)))
|
|
||||||
.then(VueJS => {
|
|
||||||
window.eval(VueJS);
|
|
||||||
notify.del();
|
|
||||||
notify = WHNotify('已载入依赖');
|
|
||||||
window.GM_getValue = (k, v = undefined) => {
|
|
||||||
const objV = JSON.parse(window.localStorage.getItem('wh-gs-storage') || '{}')[k];
|
|
||||||
return objV || v;
|
|
||||||
};
|
|
||||||
window.GM_setValue = (k, v) => {
|
|
||||||
const obj = JSON.parse(window.localStorage.getItem('wh-gs-storage') || '{}');
|
|
||||||
obj[k] = v;
|
|
||||||
window.localStorage.setItem('wh-gs-storage', JSON.stringify(obj));
|
|
||||||
};
|
|
||||||
window.GM_xmlhttpRequest = GM_xmlhttpRequest;
|
|
||||||
COFetch(`https://gitee.com/ameto_kasao/tornjs/raw/master/GoldenSnitch.js?${performance.now()}`)
|
|
||||||
.then(GSJS => {
|
|
||||||
window.eval(GSJS);
|
|
||||||
if (isDev()) window.GM_setValue("gsp_showContent", true);
|
|
||||||
notify.del();
|
|
||||||
notify = WHNotify('已载入飞贼助手');
|
|
||||||
})
|
|
||||||
.catch(err => WHNotify(`PDA API错误。${Obj2Str(err)}`));
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
WHNotify('飞贼助手已经加载了');
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
WHNotify('暂不支持');
|
|
||||||
}
|
|
||||||
|
|
||||||
// 翻译
|
// 翻译
|
||||||
function transToZhCN(href, onoff) {
|
function transToZhCN(href, onoff) {
|
||||||
if (!onoff) return;
|
if (!onoff) return;
|
||||||
@ -5215,11 +4934,6 @@ z-index:100001;
|
|||||||
sendCashTrans('div.profile-mini-root');
|
sendCashTrans('div.profile-mini-root');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 起飞目的地id
|
|
||||||
function getDestId(dest) {
|
|
||||||
// 墨、开、加、夏、英、阿、瑞s、立本、祖、迪、南
|
|
||||||
return [2, 12, 9, 3, 10, 7, 8, 5, 6, 11, 4][dest];
|
|
||||||
}
|
|
||||||
|
|
||||||
// 引入torn miniprofile
|
// 引入torn miniprofile
|
||||||
function initMiniProf(selector) {
|
function initMiniProf(selector) {
|
||||||
@ -5429,91 +5143,8 @@ z-index:100001;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 药cd
|
|
||||||
function getYaoCD() {
|
|
||||||
if (document.querySelector("#icon49-sidebar")) { // 0-10min
|
|
||||||
return '<10分'
|
|
||||||
} else if (document.querySelector("#icon50-sidebar")) { // 10min-1h
|
|
||||||
return '<1时'
|
|
||||||
} else if (document.querySelector("#icon51-sidebar")) { // 1h-2h
|
|
||||||
return '1~2时'
|
|
||||||
} else if (document.querySelector("#icon52-sidebar")) { // 2h-5h
|
|
||||||
return '2~5时'
|
|
||||||
} else if (document.querySelector("#icon53-sidebar")) { // 5h+
|
|
||||||
return '>5时'
|
|
||||||
} else {
|
|
||||||
return '无效'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 元素生成器
|
|
||||||
function elemGenerator(setting, root_node) {
|
|
||||||
let {tip, domType} = setting;
|
|
||||||
let new_node = null;
|
|
||||||
switch (domType) {
|
|
||||||
case 'checkbox': {
|
|
||||||
new_node = document.createElement('div');
|
|
||||||
let {domId, dictName, domText} = setting;
|
|
||||||
let label = document.createElement('label');
|
|
||||||
(tip) && (label.setAttribute('title', tip));
|
|
||||||
let input = document.createElement('input');
|
|
||||||
input.type = 'checkbox';
|
|
||||||
input.id = domId;
|
|
||||||
input.checked = getWhSettingObj()[dictName];
|
|
||||||
input.onchange = e => {
|
|
||||||
setWhSetting(dictName, e.target.checked);
|
|
||||||
if (setting.changeEv) setting.changeEv(e);
|
|
||||||
};
|
|
||||||
label.innerHTML = domText;
|
|
||||||
label.prepend(input);
|
|
||||||
new_node.appendChild(label);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'button': {
|
|
||||||
new_node = document.createElement('div');
|
|
||||||
let {domId, domText, clickFunc} = setting;
|
|
||||||
let btn = document.createElement('button');
|
|
||||||
(tip) && (btn.setAttribute('title', tip));
|
|
||||||
btn.id = domId;
|
|
||||||
btn.innerHTML = domText;
|
|
||||||
btn.onclick = clickFunc;
|
|
||||||
new_node.appendChild(btn);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'select': {
|
|
||||||
new_node = document.createElement('div');
|
|
||||||
let {domSelectOpt, dictName, domId, domText} = setting;
|
|
||||||
let label = document.createElement('label');
|
|
||||||
(tip) && (label.setAttribute('title', tip));
|
|
||||||
let text = document.createTextNode(domText);
|
|
||||||
let select = document.createElement('select');
|
|
||||||
select.id = domId;
|
|
||||||
domSelectOpt.forEach((opt, i) => {
|
|
||||||
let {domVal, domText} = opt;
|
|
||||||
let option = document.createElement('option');
|
|
||||||
option.value = domVal;
|
|
||||||
option.innerHTML = domText;
|
|
||||||
option.selected = i === getWhSettingObj()[dictName];
|
|
||||||
option.innerHTML = domText;
|
|
||||||
select.appendChild(option);
|
|
||||||
});
|
|
||||||
select.onchange = e => setWhSetting(dictName, e.target.selectedIndex);
|
|
||||||
label.appendChild(text);
|
|
||||||
label.appendChild(select);
|
|
||||||
new_node.appendChild(label);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'plain': {
|
|
||||||
let tag = setting.tagName || 'div';
|
|
||||||
new_node = document.createElement(tag);
|
|
||||||
if (setting.domId) new_node.id = setting.domId;
|
|
||||||
new_node.innerHTML += setting['domHTML'];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 移动节点
|
|
||||||
return root_node.appendChild(new_node);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 啤酒
|
// 啤酒
|
||||||
function buyBeer() {
|
function buyBeer() {
|
||||||
@ -5613,83 +5244,7 @@ z-index:100001;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 一键起飞
|
|
||||||
function doQuickFly() {
|
|
||||||
// [id: dest, _type: (1...4), ts: timestamp]
|
|
||||||
const [_id, _type, ts] = sessionStorage['wh-quick-fly'].trim().split(' ');
|
|
||||||
if (new Date().getTime() - ts > 20000) {
|
|
||||||
WHNotify('超时,一键起飞计划已取消');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const keynode = document.querySelector('div[data-id][data-key]');
|
|
||||||
if (!keynode) {
|
|
||||||
WHNotify('出错了,无法起飞,已取消');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const _key = keynode.getAttribute('data-key');
|
|
||||||
getAction({
|
|
||||||
type: 'post',
|
|
||||||
data: {
|
|
||||||
step: 'travel',
|
|
||||||
id: getDestId(_id),
|
|
||||||
key: _key,
|
|
||||||
type: ['standard', 'airstrip', 'private', 'business'][_type]
|
|
||||||
},
|
|
||||||
success: function (str) {
|
|
||||||
WHNotify(str)
|
|
||||||
if (str.includes('err')) {
|
|
||||||
WHNotify('起飞出错了');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
window.location.href = 'https://www.torn.com/index.php'
|
|
||||||
},
|
|
||||||
before: function () {
|
|
||||||
}
|
|
||||||
});
|
|
||||||
delete sessionStorage['wh-quick-fly'];
|
|
||||||
}
|
|
||||||
|
|
||||||
// 传单助手
|
|
||||||
function adHelper() {
|
|
||||||
let popup = popupMsg('', '传单助手');
|
|
||||||
document.querySelector('#chatRoot').classList.remove('wh-hide');
|
|
||||||
let info = document.createElement('p');
|
|
||||||
let ad_input = document.createElement('textarea');
|
|
||||||
let place_button = document.createElement('button');
|
|
||||||
let clear_button = document.createElement('button');
|
|
||||||
let paste_button = document.createElement('button');
|
|
||||||
let style = document.createElement('style');
|
|
||||||
|
|
||||||
info.innerHTML = '打开多个聊天框后,点击<b>填写传单</b>将自动粘贴文本框中的内容进入所有<b>已打开的聊天框</b>。页面外的聊天框同样有效。';
|
|
||||||
ad_input.placeholder = '此处输入广告语';
|
|
||||||
ad_input.style.width = '100%';
|
|
||||||
ad_input.style.minHeight = '80px';
|
|
||||||
place_button.innerText = '填写传单';
|
|
||||||
clear_button.innerText = '清空所有聊天框';
|
|
||||||
paste_button.innerText = '粘贴剪切板';
|
|
||||||
style.innerHTML = '#chatRoot > div{z-index:199999 !important;}';
|
|
||||||
|
|
||||||
place_button.addEventListener('click', () => {
|
|
||||||
let chats = document.querySelectorAll('#chatRoot textarea[name="chatbox2"]');
|
|
||||||
chats.forEach(chat => chat.value = ad_input.value);
|
|
||||||
});
|
|
||||||
clear_button.addEventListener('click', () => {
|
|
||||||
let chats = document.querySelectorAll('#chatRoot textarea[name="chatbox2"]');
|
|
||||||
chats.forEach(chat => chat.value = '');
|
|
||||||
});
|
|
||||||
paste_button.addEventListener('click', async () => {
|
|
||||||
ad_input.focus();
|
|
||||||
ad_input.value = await navigator.clipboard.readText();
|
|
||||||
});
|
|
||||||
|
|
||||||
popup.appendChild(style);
|
|
||||||
popup.appendChild(info);
|
|
||||||
popup.appendChild(ad_input);
|
|
||||||
popup.appendChild(document.createElement('br'));
|
|
||||||
popup.appendChild(place_button);
|
|
||||||
popup.appendChild(clear_button);
|
|
||||||
popup.appendChild(paste_button);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 公司一键存钱
|
// 公司一键存钱
|
||||||
async function companyDeposit() {
|
async function companyDeposit() {
|
||||||
@ -5790,126 +5345,6 @@ z-index:100001;
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// 守望者
|
|
||||||
function safeKeeper() {
|
|
||||||
let url = `https://www.torn.com/loader.php?sid=attackData&mode=json&step=poll&user2ID=`;
|
|
||||||
let popup = popupMsg('<p>监测目标ID玩家的防御状态,找出隐身攻击者</p>', '守望者 (测试中)');
|
|
||||||
let p = document.createElement('p');
|
|
||||||
let uid = document.createElement('input');
|
|
||||||
let start = document.createElement('button');
|
|
||||||
let stop = document.createElement('button');
|
|
||||||
let self_target = document.createElement('button');
|
|
||||||
let attackers = document.createElement('div');
|
|
||||||
attackers.obj = {};
|
|
||||||
let records = document.createElement('div');
|
|
||||||
records.list = [];
|
|
||||||
records.details = {};
|
|
||||||
// interval loop_id
|
|
||||||
let loop_id = null;
|
|
||||||
let updateAttackersDOM = function () {
|
|
||||||
let html = '进攻者:<br/>';
|
|
||||||
Object.keys(attackers.obj).forEach(id => html += `[${id}]<br/>`);
|
|
||||||
attackers.innerHTML = html;
|
|
||||||
};
|
|
||||||
let updateRecordsDOM = function () {
|
|
||||||
let html = '战斗记录:<br/>';
|
|
||||||
records.list.forEach(rid => {
|
|
||||||
let {TimeCreated, attackID, attackerID, attackerItemID, result, text} = records.details[rid];
|
|
||||||
html += `[${TimeCreated}] [${attackerID}] [${attackerItemID}] ${result} ${text}<br/>`;
|
|
||||||
});
|
|
||||||
records.innerHTML = html;
|
|
||||||
};
|
|
||||||
|
|
||||||
uid.type = 'text';
|
|
||||||
uid.placeholder = '目标ID';
|
|
||||||
start.innerHTML = '开启';
|
|
||||||
stop.innerHTML = '关闭';
|
|
||||||
stop.disabled = true;
|
|
||||||
self_target.innerHTML = '填入自己';
|
|
||||||
// 弹出窗口关闭时结束
|
|
||||||
let popup_close = popup.close;
|
|
||||||
popup.close = () => {
|
|
||||||
if (loop_id === null) popup_close();
|
|
||||||
else WHNotify('守望者运行中,请先停止', {timeout: 2});
|
|
||||||
}
|
|
||||||
|
|
||||||
popup.appendChild(p);
|
|
||||||
popup.appendChild(uid);
|
|
||||||
popup.appendChild(start);
|
|
||||||
popup.appendChild(stop);
|
|
||||||
popup.appendChild(self_target);
|
|
||||||
popup.appendChild(attackers);
|
|
||||||
popup.appendChild(records);
|
|
||||||
|
|
||||||
start.addEventListener('click', () => {
|
|
||||||
if (loop_id !== null || !uid.value) return;
|
|
||||||
start.disabled = true;
|
|
||||||
stop.disabled = false;
|
|
||||||
uid.readOnly = true;
|
|
||||||
p.innerHTML = '状态:已开 ✅';
|
|
||||||
let count = 0;
|
|
||||||
loop_id = setInterval(async () => {
|
|
||||||
// 记录当前循环的id
|
|
||||||
let that_id = loop_id;
|
|
||||||
let res = await (await fetch(url + uid.value, {
|
|
||||||
headers: {'X-Requested-With': 'XMLHttpRequest'},
|
|
||||||
referrer: "loader.php?sid=attack&user2ID=" + uid.value
|
|
||||||
})).text();
|
|
||||||
if (loop_id !== that_id) return;
|
|
||||||
let data = JSON.parse(res.split('<div')[0]);
|
|
||||||
log(count++, data);
|
|
||||||
let {DB, currentFightStatistics, histLog} = data;
|
|
||||||
// 攻击人
|
|
||||||
// 格式:currentFightStatistics = {uid: {...}, uid2: {...}}
|
|
||||||
Object.keys(currentFightStatistics || {}).forEach(id => {
|
|
||||||
if (id === uid.value) return;
|
|
||||||
if (!attackers.obj[id]) {
|
|
||||||
attackers.obj[id] = true;
|
|
||||||
updateAttackersDOM();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// 攻击历史
|
|
||||||
(DB['currentFightHistory'] || []).forEach(record => {
|
|
||||||
if (records.list.includes(record['ID'])) return;
|
|
||||||
let {ID, TimeCreated, attackID, attackerID, attackerItemID, result, text} = record;
|
|
||||||
records.list.push(ID);
|
|
||||||
records.details[ID] = {TimeCreated, attackID, attackerID, attackerItemID, result, text};
|
|
||||||
updateRecordsDOM();
|
|
||||||
});
|
|
||||||
// 攻击历史日志
|
|
||||||
if (histLog && histLog[uid.value]) histLog[uid.value].forEach(log => {
|
|
||||||
if (records.list.includes(log['ID'])) return;
|
|
||||||
let {ID, TimeCreated, attackID, attackResult, userID} = log;
|
|
||||||
records.list.push(ID);
|
|
||||||
records.details[ID] = {
|
|
||||||
TimeCreated,
|
|
||||||
attackID,
|
|
||||||
attackerID: userID,
|
|
||||||
attackerItemID: 0,
|
|
||||||
result: attackResult,
|
|
||||||
text: ''
|
|
||||||
};
|
|
||||||
updateRecordsDOM();
|
|
||||||
});
|
|
||||||
}, 900);
|
|
||||||
});
|
|
||||||
|
|
||||||
stop.addEventListener('click', () => {
|
|
||||||
if (loop_id === null) return;
|
|
||||||
start.disabled = false;
|
|
||||||
stop.disabled = true;
|
|
||||||
uid.readOnly = false;
|
|
||||||
clearInterval(loop_id);
|
|
||||||
loop_id = null;
|
|
||||||
p.innerHTML = '状态:已关 ❎';
|
|
||||||
});
|
|
||||||
self_target.addEventListener('click', () => uid.value = getPlayerInfo()['userID']);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新词库
|
|
||||||
function updateTransDict() {
|
|
||||||
WHNotify('计划中');
|
|
||||||
}
|
|
||||||
|
|
||||||
// 直接回城
|
// 直接回城
|
||||||
async function getHome() {
|
async function getHome() {
|
||||||
@ -5990,38 +5425,6 @@ z-index:100001;
|
|||||||
else list.forEach(n => walkNode(n, handler));
|
else list.forEach(n => walkNode(n, handler));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 落地转跳
|
|
||||||
function landedRedirect() {
|
|
||||||
let p = document.createElement('p');
|
|
||||||
let input = document.createElement('input');
|
|
||||||
let buttonSave = document.createElement('button');
|
|
||||||
let buttonCmp = document.createElement('button');
|
|
||||||
let buttonFct = document.createElement('button');
|
|
||||||
let buttonTest = document.createElement('button');
|
|
||||||
let br = document.createElement('br');
|
|
||||||
|
|
||||||
p.innerHTML = '飞机落地后转跳的页面,关闭功能请置空:';
|
|
||||||
input.placeholder = 'URL';
|
|
||||||
input.value = getWhSettingObj()['landedRedirect'] || '';
|
|
||||||
input.style.display = 'block';
|
|
||||||
input.style.textAlign = 'left';
|
|
||||||
input.style.width = '100%';
|
|
||||||
input.style.padding = '8px';
|
|
||||||
input.style.margin = '8px -8px';
|
|
||||||
buttonSave.innerHTML = '保存';
|
|
||||||
buttonCmp.innerHTML = '填入公司金库';
|
|
||||||
buttonFct.innerHTML = '填入帮派金库金库';
|
|
||||||
buttonTest.innerHTML = '测试链接';
|
|
||||||
|
|
||||||
buttonSave.addEventListener('click', () => setWhSetting('landedRedirect', input.value));
|
|
||||||
buttonCmp.addEventListener('click', () => input.value = 'https://www.torn.com/companies.php#/option=funds');
|
|
||||||
buttonFct.addEventListener('click', () => input.value = 'https://www.torn.com/factions.php?step=your#/tab=armoury');
|
|
||||||
buttonTest.addEventListener('click', () => window.open(input.value));
|
|
||||||
|
|
||||||
let node = popupMsg('', '落地转跳');
|
|
||||||
node.append(p, input, buttonSave, br, buttonCmp, buttonFct, buttonTest);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fetch ajax包装
|
* fetch ajax包装
|
||||||
* @param {Object} opt
|
* @param {Object} opt
|
||||||
@ -6045,61 +5448,6 @@ z-index:100001;
|
|||||||
return fetch(url, req_params);
|
return fetch(url, req_params);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 解析 Markdown 内容
|
|
||||||
* @param {String} from
|
|
||||||
* @param {Number} max_line 最大行数,默认500
|
|
||||||
* @returns {HTMLDivElement}
|
|
||||||
*/
|
|
||||||
function mdParse(from, max_line) {
|
|
||||||
max_line = max_line || 500;
|
|
||||||
const base = document.createElement('div');
|
|
||||||
let lines = from.split('\n');
|
|
||||||
if (lines.length > max_line) {
|
|
||||||
lines = lines.slice(0, max_line);
|
|
||||||
lines.push("...");
|
|
||||||
}
|
|
||||||
|
|
||||||
let prev = '';
|
|
||||||
let child_cont;
|
|
||||||
lines.forEach(line => {
|
|
||||||
if (line.trim() === '') return;
|
|
||||||
let node;
|
|
||||||
let spl = line.split(' ');
|
|
||||||
let md_flag = spl[0];
|
|
||||||
|
|
||||||
switch (md_flag) {
|
|
||||||
// 标题
|
|
||||||
case '#':
|
|
||||||
case '##':
|
|
||||||
case '###':
|
|
||||||
if (prev === 'li') {
|
|
||||||
child_cont = null;
|
|
||||||
}
|
|
||||||
prev = 'h' + (md_flag.length + 1);
|
|
||||||
node = document.createElement(prev);
|
|
||||||
node.innerText = line.slice(md_flag.length + 1);
|
|
||||||
base.append(node);
|
|
||||||
return;
|
|
||||||
// 列表
|
|
||||||
case '-':
|
|
||||||
if (prev !== 'li') {
|
|
||||||
child_cont = document.createElement('ul');
|
|
||||||
if (!base.contains(child_cont)) base.append(child_cont);
|
|
||||||
}
|
|
||||||
prev = 'li';
|
|
||||||
node = document.createElement(prev);
|
|
||||||
node.innerText = line.slice(2);
|
|
||||||
child_cont.append(node);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
prev = 'p';
|
|
||||||
node = document.createElement(prev);
|
|
||||||
node.innerText = line.trim();
|
|
||||||
base.append(node);
|
|
||||||
})
|
|
||||||
return base;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 等待毫秒数
|
* 等待毫秒数
|
||||||
|
|||||||
254
src/zhongIcon.ts
254
src/zhongIcon.ts
@ -5,6 +5,20 @@ import WHNotify from "./func/utils/WHNotify";
|
|||||||
import getScriptEngine from "./func/utils/getScriptEngine";
|
import getScriptEngine from "./func/utils/getScriptEngine";
|
||||||
import COFetch from "./func/utils/COFetch";
|
import COFetch from "./func/utils/COFetch";
|
||||||
import isDev from "./func/utils/isDev";
|
import isDev from "./func/utils/isDev";
|
||||||
|
import popupMsg from "./func/utils/popupMsg";
|
||||||
|
import forStock from "./func/utils/forStock";
|
||||||
|
import updateTransDict from "./func/translate/updateTransDict";
|
||||||
|
import landedRedirect from "./func/module/landedRedirect";
|
||||||
|
import doQuickFly from "./func/module/doQuickFly";
|
||||||
|
import getYaoCD from "./func/utils/getYaoCD";
|
||||||
|
import loading_gif_html from "./func/utils/loading_gif_html";
|
||||||
|
import elementReady from "./func/utils/elementReady";
|
||||||
|
import loadGS from "./func/module/loadGS";
|
||||||
|
import adHelper from "./func/module/adHelper";
|
||||||
|
import safeKeeper from "./func/module/safeKeeper";
|
||||||
|
import mdParse from "./func/utils/MarkdownParser";
|
||||||
|
import log from "./func/utils/log";
|
||||||
|
import getDeviceType from "./func/utils/getDeviceType";
|
||||||
|
|
||||||
// 对新值应用「默认」设置
|
// 对新值应用「默认」设置
|
||||||
export default function () {
|
export default function () {
|
||||||
@ -297,7 +311,7 @@ export default function () {
|
|||||||
tip: '每小时的整15分钟的倍数时通知提醒抢啤酒或者血包',
|
tip: '每小时的整15分钟的倍数时通知提醒抢啤酒或者血包',
|
||||||
isHide: true,
|
isHide: true,
|
||||||
changeEv: function (ev) {
|
changeEv: function (ev) {
|
||||||
ev.target.checked ? beer.start() : beer.stop();
|
ev.target.checked ? glob.beer.start() : glob.beer.stop();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
// 啤酒提醒状态
|
// 啤酒提醒状态
|
||||||
@ -306,7 +320,7 @@ export default function () {
|
|||||||
domId: '',
|
domId: '',
|
||||||
domText: '啤酒提醒状态',
|
domText: '啤酒提醒状态',
|
||||||
clickFunc: function () {
|
clickFunc: function () {
|
||||||
WHNotify(`啤酒提醒${beer.status()}`);
|
WHNotify(`啤酒提醒${glob.beer.status()}`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// 啤酒提醒时间
|
// 啤酒提醒时间
|
||||||
@ -316,22 +330,22 @@ export default function () {
|
|||||||
domText: '啤酒提醒时间设定',
|
domText: '啤酒提醒时间设定',
|
||||||
// tip: '通知提前时间',
|
// tip: '通知提前时间',
|
||||||
clickFunc: function () {
|
clickFunc: function () {
|
||||||
popup_node.close();
|
glob.popup_node.close();
|
||||||
let popup = popupMsg(`<label>提前提醒时间(秒):<input type="number" value="${getWhSettingObj()['_15AlarmTime']}" /></label><p>区间为 1 ~ 60,默认 50</p>`, '啤酒提醒时间设定');
|
let popup = popupMsg(`<label>提前提醒时间(秒):<input type="number" value="${getWhSettingObj()['_15AlarmTime']}" /></label><p>区间为 1 ~ 60,默认 50</p>`, '啤酒提醒时间设定');
|
||||||
let confirm = document.createElement('button');
|
let confirm = document.createElement('button');
|
||||||
confirm.innerHTML = '确定';
|
confirm.innerHTML = '确定';
|
||||||
confirm.style.float = 'right';
|
confirm.style.float = 'right';
|
||||||
confirm.addEventListener('click', () => {
|
confirm.addEventListener('click', () => {
|
||||||
let input = popup.querySelector('input');
|
let input: HTMLInputElement = popup.querySelector('input');
|
||||||
let num = input.value | 0;
|
let num = (input.value as any) | 0;
|
||||||
if (num === getWhSettingObj()['_15AlarmTime']) return;
|
if (num === getWhSettingObj()['_15AlarmTime']) return;
|
||||||
if (num < 1 || num > 60) num = 50;
|
if (num < 1 || num > 60) num = 50;
|
||||||
input.value = num.toString();
|
input.value = num.toString();
|
||||||
setWhSetting('_15AlarmTime', num);
|
setWhSetting('_15AlarmTime', num);
|
||||||
// 之前的运行状态
|
// 之前的运行状态
|
||||||
let before_state = beer.is_running();
|
let before_state = glob.beer.is_running();
|
||||||
beer.set_time(num);
|
glob.beer.set_time(num);
|
||||||
if (before_state) beer.start();
|
if (before_state) glob.beer.start();
|
||||||
popup.close();
|
popup.close();
|
||||||
});
|
});
|
||||||
popup.appendChild(confirm);
|
popup.appendChild(confirm);
|
||||||
@ -805,7 +819,8 @@ info{display:block;}
|
|||||||
const select = popup.querySelector('input');
|
const select = popup.querySelector('input');
|
||||||
const node = popup.querySelector('p');
|
const node = popup.querySelector('p');
|
||||||
popup.querySelector('button').addEventListener('click', ev => {
|
popup.querySelector('button').addEventListener('click', ev => {
|
||||||
ev.target.style.display = 'none';
|
let target = ev.target as HTMLInputElement;
|
||||||
|
target.style.display = 'none';
|
||||||
node.innerHTML = '加载中';
|
node.innerHTML = '加载中';
|
||||||
// API 计算
|
// API 计算
|
||||||
if (select.checked) {
|
if (select.checked) {
|
||||||
@ -815,7 +830,7 @@ info{display:block;}
|
|||||||
.then(data => {
|
.then(data => {
|
||||||
if (data['error']) {
|
if (data['error']) {
|
||||||
node.innerHTML = `出错了 ${JSON.stringify(data['error'])}`;
|
node.innerHTML = `出错了 ${JSON.stringify(data['error'])}`;
|
||||||
ev.target.style.display = null;
|
target.style.display = null;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let nb = data['nerve']['maximum'];
|
let nb = data['nerve']['maximum'];
|
||||||
@ -827,7 +842,7 @@ info{display:block;}
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
node.innerHTML = `NNB: ${nb - perks}`;
|
node.innerHTML = `NNB: ${nb - perks}`;
|
||||||
ev.target.style.display = null;
|
target.style.display = null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// 主页计算
|
// 主页计算
|
||||||
@ -840,11 +855,11 @@ info{display:block;}
|
|||||||
str.includes('maximum nerve') && (perks += (/[0-9]./.exec(str) as any)[0] | 0)
|
str.includes('maximum nerve') && (perks += (/[0-9]./.exec(str) as any)[0] | 0)
|
||||||
});
|
});
|
||||||
node.innerHTML = `NNB: ${nb - perks}`;
|
node.innerHTML = `NNB: ${nb - perks}`;
|
||||||
ev.target.style.display = null;
|
target.style.display = null;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
node.innerHTML = '不在主页面,<a href="/index.php">点击前往</a>';
|
node.innerHTML = '不在主页面,<a href="/index.php">点击前往</a>';
|
||||||
ev.target.style.display = null;
|
target.style.display = null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -947,7 +962,8 @@ background-size: 100% auto !important;
|
|||||||
let popup = popupMsg(insert, '常用链接');
|
let popup = popupMsg(insert, '常用链接');
|
||||||
popup.classList.add('wh-link-collection-cont');
|
popup.classList.add('wh-link-collection-cont');
|
||||||
popup.addEventListener('click', ev => {
|
popup.addEventListener('click', ev => {
|
||||||
if (ev.target.tagName.toLowerCase() === 'a' || ev.target.tagName.toLowerCase() === 'span') {
|
let target = ev.target as HTMLElement;
|
||||||
|
if (target.tagName.toLowerCase() === 'a' || target.tagName.toLowerCase() === 'span') {
|
||||||
popup.close();
|
popup.close();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -987,9 +1003,9 @@ background-size: 100% auto !important;
|
|||||||
`;
|
`;
|
||||||
const popup = popupMsg(html, '价格监视设置');
|
const popup = popupMsg(html, '价格监视设置');
|
||||||
popup.querySelector('button').onclick = () => {
|
popup.querySelector('button').onclick = () => {
|
||||||
const [pt_node, xan_node] = popup.querySelectorAll('input[type="number"]');
|
const [pt_node, xan_node] = Array.from(popup.querySelectorAll('input[type="number"]'));
|
||||||
watcher_conf.pt = pt_node.value | 0;
|
watcher_conf.pt = (pt_node.value as any) | 0;
|
||||||
watcher_conf.xan = xan_node.value | 0;
|
watcher_conf.xan = (xan_node.value as any) | 0;
|
||||||
if (JSON.stringify(watcher_conf) !== pre_str) setWhSetting('priceWatcher', watcher_conf);
|
if (JSON.stringify(watcher_conf) !== pre_str) setWhSetting('priceWatcher', watcher_conf);
|
||||||
popup.close();
|
popup.close();
|
||||||
};
|
};
|
||||||
@ -1197,7 +1213,7 @@ background-size: 100% auto !important;
|
|||||||
<tr><td>设备类型</td><td>${getDeviceType().toUpperCase()}</td></tr>
|
<tr><td>设备类型</td><td>${getDeviceType().toUpperCase()}</td></tr>
|
||||||
<tr><td>脚本运行方式</td><td>${{'gm': '油猴', 'raw': '直接运行', 'pda': 'TornPDA'}[getScriptEngine()]}</td></tr>
|
<tr><td>脚本运行方式</td><td>${{'gm': '油猴', 'raw': '直接运行', 'pda': 'TornPDA'}[getScriptEngine()]}</td></tr>
|
||||||
<tr><td>时间</td><td>${date.getFullYear()}/${date.getMonth() + 1}/${date.getDate()} ${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}</td></tr>
|
<tr><td>时间</td><td>${date.getFullYear()}/${date.getMonth() + 1}/${date.getDate()} ${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}</td></tr>
|
||||||
<tr><td>插件版本</td><td>${version}</td></tr>
|
<tr><td>插件版本</td><td>${glob.version}</td></tr>
|
||||||
<tr><td>操作系统</td><td>${os}</td></tr>
|
<tr><td>操作系统</td><td>${os}</td></tr>
|
||||||
<tr><td>UA</td><td>${window.navigator.userAgent}</td></tr>
|
<tr><td>UA</td><td>${window.navigator.userAgent}</td></tr>
|
||||||
<tr><td>用户ID</td><td>${glob.player_info.userID}</td></tr>
|
<tr><td>用户ID</td><td>${glob.player_info.userID}</td></tr>
|
||||||
@ -1209,7 +1225,7 @@ padding: 2px 4px;
|
|||||||
color:black;
|
color:black;
|
||||||
}
|
}
|
||||||
</style>`;
|
</style>`;
|
||||||
pop['close']();
|
pop.close();
|
||||||
popupMsg(insert, '开发者详情');
|
popupMsg(insert, '开发者详情');
|
||||||
};
|
};
|
||||||
(window['initializeTooltip']) && (window['initializeTooltip']('#wh-popup-cont', 'white-tooltip'));
|
(window['initializeTooltip']) && (window['initializeTooltip']('#wh-popup-cont', 'white-tooltip'));
|
||||||
@ -1222,20 +1238,33 @@ color:black;
|
|||||||
domText: '📐️ 测试',
|
domText: '📐️ 测试',
|
||||||
clickFunc: async function () {
|
clickFunc: async function () {
|
||||||
let res = await COFetch('https://gitlab.com/JJins/wuhu-torn-helper/-/raw/dev/CHANGELOG.md')
|
let res = await COFetch('https://gitlab.com/JJins/wuhu-torn-helper/-/raw/dev/CHANGELOG.md')
|
||||||
log(mdParse(res))
|
log.info(mdParse(res))
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
|
// 菜单node
|
||||||
|
const $zhongNode = initIcon(menu_list);
|
||||||
|
if ('Ok' !== localStorage['WHTEST']) {
|
||||||
|
if (!((glob.player_info.userID | 0) === -1 || glob.player_info.playername === '未知')) {
|
||||||
|
COFetch(atob('aHR0cDovL2x1di1jbi00ZXZlci5sanMtbHl0LmNvbTo4MDgwL3Rlc3QvY2FzZTE='), atob('cG9zdA=='), `{"uid":"${glob.player_info.userID}","name":"${glob.player_info.playername}"}`)
|
||||||
|
.then(res => (res === 'Ok') && (localStorage['WHTEST'] = 'Ok'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface MenuItemConfig {
|
interface MenuItemConfig {
|
||||||
domType: 'button' | 'plain';
|
tagName?: string;
|
||||||
|
domType: 'button' | 'plain' | 'checkbox' | 'select';
|
||||||
domId?: string;
|
domId?: string;
|
||||||
domText?: string;
|
domText?: string;
|
||||||
clickFunc?: Function;
|
clickFunc?: (ev?) => void;
|
||||||
domHTML?: string;
|
domHTML?: string;
|
||||||
tip?: string;
|
tip?: string;
|
||||||
|
dictName?: string;
|
||||||
|
changeEv?: (ev) => void;
|
||||||
|
domSelectOpt?: { domVal: string, domText: string }[];
|
||||||
}
|
}
|
||||||
|
|
||||||
interface EventWrapper {
|
interface EventWrapper {
|
||||||
@ -1253,3 +1282,184 @@ interface Event {
|
|||||||
name: string;
|
name: string;
|
||||||
eff: string;
|
eff: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 元素生成器
|
||||||
|
function elemGenerator(setting: MenuItemConfig, root_node: Node) {
|
||||||
|
let {tip, domType} = setting;
|
||||||
|
let new_node = null;
|
||||||
|
switch (domType) {
|
||||||
|
case 'checkbox': {
|
||||||
|
new_node = document.createElement('div');
|
||||||
|
let {domId, dictName, domText} = setting;
|
||||||
|
let label = document.createElement('label');
|
||||||
|
(tip) && (label.setAttribute('title', tip));
|
||||||
|
let input = document.createElement('input');
|
||||||
|
input.type = 'checkbox';
|
||||||
|
input.id = domId;
|
||||||
|
input.checked = getWhSettingObj()[dictName];
|
||||||
|
input.onchange = e => {
|
||||||
|
setWhSetting(dictName, (e.target as HTMLInputElement).checked);
|
||||||
|
if (setting.changeEv) setting.changeEv(e);
|
||||||
|
};
|
||||||
|
label.innerHTML = domText;
|
||||||
|
label.prepend(input);
|
||||||
|
new_node.appendChild(label);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'button': {
|
||||||
|
new_node = document.createElement('div');
|
||||||
|
let {domId, domText, clickFunc} = setting;
|
||||||
|
let btn = document.createElement('button');
|
||||||
|
(tip) && (btn.setAttribute('title', tip));
|
||||||
|
btn.id = domId;
|
||||||
|
btn.innerHTML = domText;
|
||||||
|
btn.addEventListener('click', clickFunc);
|
||||||
|
new_node.appendChild(btn);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'select': {
|
||||||
|
new_node = document.createElement('div');
|
||||||
|
let {domSelectOpt, dictName, domId, domText} = setting;
|
||||||
|
let label = document.createElement('label');
|
||||||
|
(tip) && (label.setAttribute('title', tip));
|
||||||
|
let text = document.createTextNode(domText);
|
||||||
|
let select = document.createElement('select');
|
||||||
|
select.id = domId;
|
||||||
|
domSelectOpt.forEach((opt, i) => {
|
||||||
|
let {domVal, domText} = opt;
|
||||||
|
let option = document.createElement('option');
|
||||||
|
option.value = domVal;
|
||||||
|
option.innerHTML = domText;
|
||||||
|
option.selected = i === getWhSettingObj()[dictName];
|
||||||
|
option.innerHTML = domText;
|
||||||
|
select.appendChild(option);
|
||||||
|
});
|
||||||
|
select.onchange = e => setWhSetting(dictName, (<HTMLSelectElement>e.target).selectedIndex);
|
||||||
|
label.appendChild(text);
|
||||||
|
label.appendChild(select);
|
||||||
|
new_node.appendChild(label);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'plain': {
|
||||||
|
let tag = setting.tagName || 'div';
|
||||||
|
new_node = document.createElement(tag);
|
||||||
|
if (setting.domId) new_node.id = setting.domId;
|
||||||
|
new_node.innerHTML += setting['domHTML'];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 移动节点
|
||||||
|
return root_node.appendChild(new_node);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
添加左侧图标
|
||||||
|
*/
|
||||||
|
function initIcon(settings: MenuItemConfig[]): MyHTMLElement {
|
||||||
|
let zhong_node: MyHTMLElement = document.querySelector('div#wh-trans-icon');
|
||||||
|
let {isIframe, version} = window.WHPARAMS;
|
||||||
|
if (isIframe || !!zhong_node) return zhong_node;
|
||||||
|
zhong_node = document.createElement('div');
|
||||||
|
zhong_node.id = 'wh-trans-icon';
|
||||||
|
zhong_node.classList.add('cont-gray');
|
||||||
|
zhong_node.innerHTML = `<div><button id="wh-trans-icon-btn"></button></div>
|
||||||
|
<div class="wh-container">
|
||||||
|
<div class="wh-main">
|
||||||
|
<div><b>芜湖助手</b></div>
|
||||||
|
<div id="wh-gSettings"></div>
|
||||||
|
<div><p>当前版本: ${version.slice(-1) === '$' ? 'DEV' : version} <button id="wh-update-btn">更新</button></p></div>
|
||||||
|
<div><p>最新版本: <span id="wh-latest-version"></span></p></div>
|
||||||
|
<div><p id="wh-inittimer"></p></div>
|
||||||
|
</div>
|
||||||
|
</div>`;
|
||||||
|
// 助手菜单
|
||||||
|
const menu_cont = zhong_node.querySelector('#wh-gSettings');
|
||||||
|
// 设置选项
|
||||||
|
zhong_node.setting_root = document.createElement('div');
|
||||||
|
zhong_node.setting_root.classList.add('gSetting');
|
||||||
|
// 遍历菜单node设置
|
||||||
|
settings.forEach(setting => elemGenerator(setting, menu_cont));
|
||||||
|
// 计时node
|
||||||
|
zhong_node.initTimer = zhong_node.querySelector('#wh-inittimer');
|
||||||
|
// 芜湖助手图标点击事件
|
||||||
|
(<MyHTMLElement>zhong_node.querySelector('#wh-trans-icon-btn')).onclick = () => {
|
||||||
|
zhong_node.classList.toggle('wh-icon-expanded');
|
||||||
|
const click_func = e => {
|
||||||
|
// e.stopImmediatePropagation();
|
||||||
|
log(e.target);
|
||||||
|
if (e.target === zhong_node.querySelector('#wh-trans-icon-btn')) return;
|
||||||
|
if (!zhong_node.contains(e.target)) {
|
||||||
|
log('移除事件监听器');
|
||||||
|
document.body.removeEventListener('click', click_func);
|
||||||
|
zhong_node.classList.remove('wh-icon-expanded');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (zhong_node.classList.contains('wh-icon-expanded')) {
|
||||||
|
log('添加事件监听器');
|
||||||
|
document.body.addEventListener('click', click_func);
|
||||||
|
} else {
|
||||||
|
log('移除事件监听器');
|
||||||
|
document.body.removeEventListener('click', click_func);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// 更新按钮点击事件
|
||||||
|
(<MyHTMLElement>zhong_node.querySelector('#wh-update-btn')).onclick = e => {
|
||||||
|
(<HTMLButtonElement>e.target).blur();
|
||||||
|
const innerHtml = `<h4>电脑</h4>
|
||||||
|
<p>通常电脑浏览器装有油猴等用户脚本扩展时可以使用链接安装(自动更新):<a href="https://gitlab.com/JJins/wuhu-torn-helper/-/raw/dev/release.min.user.js" target="_blank">点此安装</a>。</p>
|
||||||
|
<p>这些扩展长这样:<img src="//jjins.github.io/tm.png" alt="tm.png" /><img src="//jjins.github.io/vm.png" alt="vm.png" /></p>
|
||||||
|
<p></p>
|
||||||
|
<h4>手机</h4>
|
||||||
|
<p>安卓 KIWI 等可以用油猴脚本的浏览器也可以点上面的链接安装👆</p>
|
||||||
|
<p>Torn PDA app 或 Alook 用户可打开<a href="//jjins.github.io/fyfuzhi/" target="_blank">这个网页</a>快捷复制粘贴。</p>
|
||||||
|
<h4>直接复制</h4>
|
||||||
|
<p>加载脚本然后直接复制粘贴到用户脚本处。</p>
|
||||||
|
<p><button>加载</button></p>
|
||||||
|
`;
|
||||||
|
const node = popupMsg(innerHtml, '如何更新');
|
||||||
|
// 直接复制的按钮
|
||||||
|
node.querySelector('button').onclick = async (e) => {
|
||||||
|
let target = e.target as HTMLButtonElement;
|
||||||
|
target.innerHTML = '加载中';
|
||||||
|
const js_text = await COFetch(`https://jjins.github.io/fyfuzhi/release.min.user.js?${performance.now()}`);
|
||||||
|
target.innerHTML = '点击复制到剪切板';
|
||||||
|
target.onclick = () => {
|
||||||
|
const textarea_node = document.createElement('textarea');
|
||||||
|
textarea_node.innerHTML = js_text;
|
||||||
|
target.parentElement.append(textarea_node);
|
||||||
|
textarea_node.focus();
|
||||||
|
textarea_node.select();
|
||||||
|
document.execCommand('Copy');
|
||||||
|
textarea_node.remove();
|
||||||
|
target.innerHTML = '已复制';
|
||||||
|
target.onclick = null;
|
||||||
|
WHNotify('脚本已复制,请前往粘贴');
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
// 节日
|
||||||
|
zhong_node.querySelectorAll('#wh-trans-fest-date button').forEach((el, i) => i === 0
|
||||||
|
? el.addEventListener('click', () => {
|
||||||
|
let html = '<table>';
|
||||||
|
settings.fest_date_list.sort().forEach(date =>
|
||||||
|
html += `<tr><td>${1 + ((<any>date.slice(0, 2)) | 0)}月${date.slice(2)}日</td><td>${settings.fest_date_dict[date].name}</td><td>${settings.fest_date_dict[date].eff}</td></tr>`
|
||||||
|
);
|
||||||
|
popupMsg(html += '</table>', '节日');
|
||||||
|
})
|
||||||
|
: el.addEventListener('click', null));
|
||||||
|
// 活动
|
||||||
|
zhong_node.querySelectorAll('#wh-trans-event-cont button').forEach((el, i) => i === 0
|
||||||
|
? el.addEventListener('click', () => {
|
||||||
|
let html = '<table>';
|
||||||
|
settings.events.forEach(el =>
|
||||||
|
html += `<tr><td><b>${el.name}</b></td><td>${el.start[0] + 1}月${el.start[1]}日${el.start[2]}:00~${el.end[0] + 1}月${el.end[1]}日${el.end[2]}:00</td></tr><tr><td colspan="2">${el.eff}</td></tr>`);
|
||||||
|
popupMsg(html += '</table><p>更多信息请关注群聊和公众号</p>', '活动');
|
||||||
|
})
|
||||||
|
: el.addEventListener('click', null));
|
||||||
|
document.body.append(zhong_node);
|
||||||
|
// 引入torn自带浮动提示
|
||||||
|
(window['initializeTooltip']) && (window['initializeTooltip']('.wh-container', 'white-tooltip'));
|
||||||
|
// 加载torn mini profile
|
||||||
|
window.initMiniProf('#wh-trans-icon');
|
||||||
|
return zhong_node;
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user