This commit is contained in:
Liwanyi 2022-10-24 17:31:28 +08:00
parent a7bd4bc838
commit acc995c4a2
32 changed files with 1451 additions and 1145 deletions

27
global.d.ts vendored
View File

@ -18,10 +18,14 @@ declare interface Window {
// 插件运行标识 // 插件运行标识
WHTRANS?: number; WHTRANS?: number;
Vue?: Function; Vue?: Function;
/* 油猴脚本引擎自带 */ /**
*
*/
unsafeWindow?: Window & typeof globalThis; unsafeWindow?: Window & typeof globalThis;
/**
GM: any; * google
*/
_gaUserPrefs?: unknown;
GM_xmlhttpRequest(init: GM_RequestParams): void; GM_xmlhttpRequest(init: GM_RequestParams): void;
@ -29,26 +33,25 @@ declare interface Window {
GM_setValue(k: string, v: any): void; GM_setValue(k: string, v: any): void;
// google不跟踪标识 /**
_gaUserPrefs?: unknown; * TORN自带
*/
ReactDOM?: any;
dataLayer?: unknown; dataLayer?: unknown;
eval(exc: string): void; eval(exc: string): void;
/* TORN自带 */
ReactDOM?: any;
addRFC(url: URL | string): string; addRFC(url: URL | string): string;
// initMiniProf(selector: string): void;
getAction(opt: TornGetActionParams): void; getAction(opt: TornGetActionParams): void;
initializeTooltip(selector: string, elemId: string): void; initializeTooltip(selector: string, elemId: string): void;
renderMiniProfile(node: Element, props: any): never; renderMiniProfile(node: Element, props: any): never;
/* PDA自带 */ /**
* 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>;
@ -115,3 +118,5 @@ declare module "*.css" {
} }
declare function GM_xmlhttpRequest(init: any): void; declare function GM_xmlhttpRequest(init: any): void;
declare var unsafeWindow: Window & typeof globalThis;

View File

@ -10,12 +10,14 @@ import BuyBeerHelper from "./action/BuyBeerHelper";
*/ */
export default class Global extends WuhuBase implements IGlobal { export default class Global extends WuhuBase implements IGlobal {
className = 'Global'; className = 'Global';
GM_xmlhttpRequest: Function = null;
GM_xmlhttpRequest: Function = null;
href: string = window.location.href; href: string = window.location.href;
// 弹窗 // 弹窗
popup_node: MyHTMLElement = null; popup_node: MyHTMLElement = null;
// 啤酒助手 /**
* @deprecated 使getInstance替代
*/
beer = null; beer = null;
// 留存的通知 // 留存的通知
notifies: NotifyWrapper = null; notifies: NotifyWrapper = null;
@ -45,11 +47,18 @@ export default class Global extends WuhuBase implements IGlobal {
constructor() { constructor() {
Log.info('WH脚本参数[Global]初始化'); Log.info('WH脚本参数[Global]初始化');
super(); super();
this.unsafeWindow = window.unsafeWindow || null; if (typeof unsafeWindow !== 'undefined') {
try { Log.info('存在unsafeWindow, 引入');
// 上层调用如果使用eval此处GM_xmlhttpRequest可能不存在与window中 this.unsafeWindow = unsafeWindow || null;
window.addRFC = this.unsafeWindow.addRFC;
window.getAction = this.unsafeWindow.getAction;
window.initializeTooltip = this.unsafeWindow.initializeTooltip;
window.renderMiniProfile = this.unsafeWindow.renderMiniProfile;
window.ReactDOM = this.unsafeWindow.ReactDOM;
}
if (typeof GM_xmlhttpRequest === 'function') {
// 上层调用如果使用eval此处GM_xmlhttpRequest可能不存在于window中
this.GM_xmlhttpRequest = window.GM_xmlhttpRequest || GM_xmlhttpRequest || null; this.GM_xmlhttpRequest = window.GM_xmlhttpRequest || GM_xmlhttpRequest || null;
} catch {
} }
this.version = '$$WUHU_DEV_VERSION$$'; this.version = '$$WUHU_DEV_VERSION$$';
this.PDA_APIKey = '###PDA-APIKEY###'; this.PDA_APIKey = '###PDA-APIKEY###';
@ -62,15 +71,6 @@ export default class Global extends WuhuBase implements IGlobal {
this.href = window.location.href; this.href = window.location.href;
this.bodyAttrs = {}; this.bodyAttrs = {};
if (this.unsafeWindow) {
Log.info('存在unsafeWindow, 引入部分torn公共方法');
window.addRFC = this.unsafeWindow.addRFC;
window.getAction = this.unsafeWindow.getAction;
window.initializeTooltip = this.unsafeWindow.initializeTooltip;
window.renderMiniProfile = this.unsafeWindow.renderMiniProfile;
window.ReactDOM = this.unsafeWindow.ReactDOM;
}
for (let i = 0; i < document.body.attributes.length; i++) { for (let i = 0; i < document.body.attributes.length; i++) {
let item = document.body.attributes.item(i); let item = document.body.attributes.item(i);
this.bodyAttrs[item.name] = item.value; this.bodyAttrs[item.name] = item.value;

View File

@ -61,7 +61,7 @@ export default class Log {
if (typeof item === 'string') this.logs += item; if (typeof item === 'string') this.logs += item;
else if (item !== null && item !== undefined) { else if (item !== null && item !== undefined) {
let json = '{}'; let json = '{}';
let name = 'UNKNOWN_OBJECT' let name = item.toString ? item.toString() : 'UNKNOWN_OBJECT';
try { try {
json = JSON.stringify(item); json = JSON.stringify(item);
name = Object.getPrototypeOf(item).constructor.name; name = Object.getPrototypeOf(item).constructor.name;

View File

@ -63,11 +63,9 @@ export default class UrlPattern extends WuhuBase {
beer.innerHTML = SHOP_BEER_STATIC_ITEM_HTML; beer.innerHTML = SHOP_BEER_STATIC_ITEM_HTML;
if (clear_node) clear_node.before(beer); if (clear_node) clear_node.before(beer);
else node.append(beer); else node.append(beer);
// (<MyHTMLElement>e.target).remove();
(<HTMLInputElement>e.target).disabled = true; (<HTMLInputElement>e.target).disabled = true;
msg_node.innerHTML = '添加成功'; msg_node.innerHTML = '添加成功';
}); });
// });
// 监听啤酒购买 // 监听啤酒购买
$(document).ajaxComplete((_, xhr, settings) => { $(document).ajaxComplete((_, xhr, settings) => {
@ -76,7 +74,6 @@ export default class UrlPattern extends WuhuBase {
let response = JSON.parse(responseText); let response = JSON.parse(responseText);
if (data.includes('step=buyShopItem') && data.includes('ID=180') && response['success']) { if (data.includes('step=buyShopItem') && data.includes('ID=180') && response['success']) {
new Alert('已检测成功购买啤酒'); new Alert('已检测成功购买啤酒');
// Global.getInstance().beer.skip_today();
BuyBeerHelper.getInstance().skip_today(); BuyBeerHelper.getInstance().skip_today();
} }
}); });
@ -84,6 +81,7 @@ export default class UrlPattern extends WuhuBase {
// 快速crime TODO 重构、与翻译解藕 // 快速crime TODO 重构、与翻译解藕
if (href.contains(/crimes\.php/) && WuhuConfig.get('quickCrime')) { if (href.contains(/crimes\.php/) && WuhuConfig.get('quickCrime')) {
// iframe
if (self !== top) { if (self !== top) {
const isValidate = document.querySelector('h4#skip-to-content').innerText.toLowerCase().includes('validate'); const isValidate = document.querySelector('h4#skip-to-content').innerText.toLowerCase().includes('validate');
CommonUtils.elementReady('#header-root').then(e => e.style.display = 'none'); CommonUtils.elementReady('#header-root').then(e => e.style.display = 'none');
@ -112,13 +110,14 @@ export default class UrlPattern extends WuhuBase {
}); });
const trans = () => { const trans = () => {
const dom = QUICK_CRIMES_HTML; const dom = QUICK_CRIMES_HTML;
const is_wh_translate = element.querySelector('.wh-translate') !== null; const hasInserted = element.querySelector('.wh-translate') !== null;
const is_captcha = element.querySelector('div#tab-menu.captcha') !== null; // const is_captcha = element.querySelector('div#tab-menu.captcha') !== null;
const $title = $('div.content-title'); const $title = document.querySelector('div.content-title');
const $info = $('.info-msg-cont'); const $info = document.querySelector('.info-msg-cont');
if (!is_wh_translate && !is_captcha) { // if (!hasInserted && !is_captcha) {
if ($title.length > 0) $title.before(dom); if (!hasInserted) {
else if ($info.length > 0) $info.before(dom); if ($title) $title.insertAdjacentHTML('beforebegin', dom);
else if ($info) $info.insertAdjacentHTML('beforebegin', dom);
} }
}; };
trans(); trans();
@ -132,13 +131,13 @@ export default class UrlPattern extends WuhuBase {
// 任务助手 TODO 重构、与翻译解藕 // 任务助手 TODO 重构、与翻译解藕
if (href.contains(/loader\.php\?sid=missions/) && WuhuConfig.get('missionHint')) { if (href.contains(/loader\.php\?sid=missions/) && WuhuConfig.get('missionHint')) {
const $$ = $('.content-wrapper'); const anchor = document.querySelector('.content-wrapper');
const OB = new MutationObserver(() => { const OB = new MutationObserver(() => {
OB.disconnect(); OB.disconnect();
// titleTrans(); // titleTrans();
// contentTitleLinksTrans(); // contentTitleLinksTrans();
trans(); trans();
OB.observe($$.get(0), { OB.observe(anchor, {
characterData: true, characterData: true,
attributes: true, attributes: true,
subtree: true, subtree: true,
@ -148,16 +147,18 @@ export default class UrlPattern extends WuhuBase {
const taskList = {}; const taskList = {};
const trans = () => { const trans = () => {
$('ul#giver-tabs a.ui-tabs-anchor').each((i, e) => { $('ul#giver-tabs a.ui-tabs-anchor').each((i, e) => {
if ($(e).children().hasClass('mission-complete-icon')) { let $e = $(e);
if ($e.children().hasClass('mission-complete-icon')) {
taskList[i] = e.innerText.trim(); taskList[i] = e.innerText.trim();
} else { } else {
taskList[i] = $(e).clone().children().remove().end().text().trim(); taskList[i] = $e.clone().children().remove().end().text().trim();
} }
}); });
// 助手注入 // 助手注入
$('div.max-height-fix.info').each((i, e) => { $('div.max-height-fix.info').each((i, e) => {
if ($(e).find('.wh-translated').length !== 0) return; let $e = $(e);
$(e).append(`<div class="wh-translated"><h6 style="color:green"><b>任务助手</b></h6><p>${ getTaskHint(taskList[i]) }</p></div>`); if ($e.find('.wh-translated').length !== 0) return;
$e.append(`<div class="wh-translated"><h6 style="color:green"><b>任务助手</b></h6><p>${ getTaskHint(taskList[i]) }</p></div>`);
}); });
// 任务目标 // 任务目标
$('ul.tasks-list span.title-wrap').contents().each((i, e) => { $('ul.tasks-list span.title-wrap').contents().each((i, e) => {
@ -169,7 +170,7 @@ export default class UrlPattern extends WuhuBase {
}); });
}; };
trans(); trans();
OB.observe($$.get(0), { OB.observe(anchor, {
characterData: true, characterData: true,
attributes: true, attributes: true,
subtree: true, subtree: true,

View File

@ -38,8 +38,8 @@ export default class WuHuTornHelper extends WuhuBase {
}; };
// 监听fetch // 监听fetch
const ori_fetch = window.fetch; let ori_fetch = window.fetch;
window.fetch = (url: string, init: RequestInit) => { let fetchHandle: (string, RequestInit) => Promise<Response> = (url: string, init: RequestInit) => {
let startTime = performance.now(); let startTime = performance.now();
Log.info('FETCH调用[' + url + '], init:', init); Log.info('FETCH调用[' + url + '], init:', init);
return new Promise(resolve => { return new Promise(resolve => {
@ -66,6 +66,10 @@ export default class WuHuTornHelper extends WuhuBase {
.catch(error => Log.error('监听到fetch获取错误', error)); .catch(error => Log.error('监听到fetch获取错误', error));
}) })
}; };
if (Global.getInstance().unsafeWindow) {
Global.getInstance().unsafeWindow.fetch = fetchHandle;
}
window.fetch = fetchHandle;
CommonUtils.addStyle(COMMON_CSS.replace('{{}}', performance.now().toString())); CommonUtils.addStyle(COMMON_CSS.replace('{{}}', performance.now().toString()));

File diff suppressed because it is too large Load Diff

View File

@ -6,6 +6,7 @@ import Alert from "../utils/Alert";
import MathUtils from "../utils/MathUtils"; import MathUtils from "../utils/MathUtils";
import NOTIFY_HTML from "../../static/html/buyBeer/notify.html"; import NOTIFY_HTML from "../../static/html/buyBeer/notify.html";
import CommonUtils from "../utils/CommonUtils"; import CommonUtils from "../utils/CommonUtils";
import Popup from "../utils/Popup";
export default class BuyBeerHelper extends WuhuBase implements BeerMonitorLoop { export default class BuyBeerHelper extends WuhuBase implements BeerMonitorLoop {
className = 'BuyBeerHelper'; className = 'BuyBeerHelper';
@ -98,6 +99,26 @@ export default class BuyBeerHelper extends WuhuBase implements BeerMonitorLoop {
// 通知中的取消按钮 // 通知中的取消按钮
notify.getElement().querySelector('.wh-notify-msg button').addEventListener('click', () => WuhuConfig.set('_15_alarm_ignore', undefined, true)); notify.getElement().querySelector('.wh-notify-msg button').addEventListener('click', () => WuhuConfig.set('_15_alarm_ignore', undefined, true));
} }
public setTimeHandler(): void {
let popup = new Popup(`<label>提前提醒时间(秒)<input type="number" value="${ WuhuConfig.get('_15AlarmTime') }" /></label><p>区间为 1 ~ 60默认 50</p>`, '啤酒提醒时间设定');
let confirm = document.createElement('button');
confirm.innerHTML = '确定';
confirm.style.float = 'right';
confirm.addEventListener('click', () => {
let input: HTMLInputElement = popup.getElement().querySelector('input');
let num = (input.value as any) | 0;
if (num === WuhuConfig.get('_15AlarmTime')) return;
if (num < 1 || num > 60) num = 50;
input.value = num.toString();
WuhuConfig.set('_15AlarmTime', num);
this.set_time(num);
// 之前的运行状态
if (this.is_running()) this.start();
popup.close();
});
popup.getElement().appendChild(confirm);
}
} }
export interface BeerMonitorLoop { export interface BeerMonitorLoop {

View File

@ -4,6 +4,7 @@ import InfoUtils from "../utils/InfoUtils";
import MathUtils from "../utils/MathUtils"; import MathUtils from "../utils/MathUtils";
import CommonUtils from "../utils/CommonUtils"; import CommonUtils from "../utils/CommonUtils";
import TornStyleBlock from "../utils/TornStyleBlock"; import TornStyleBlock from "../utils/TornStyleBlock";
import Timer from "../utils/Timer";
export default class LotteryHelper extends WuhuBase { export default class LotteryHelper extends WuhuBase {
className = 'LotteryHelper'; className = 'LotteryHelper';
@ -22,7 +23,7 @@ export default class LotteryHelper extends WuhuBase {
private readonly mathUtils = MathUtils.getInstance(); private readonly mathUtils = MathUtils.getInstance();
public init() { public init() {
let startTime = performance.now(); let startTime = new Timer();
Log.info('彩票助手初始化开始'); Log.info('彩票助手初始化开始');
let radioLabelDaily = document.createElement('label'); let radioLabelDaily = document.createElement('label');
@ -99,11 +100,11 @@ export default class LotteryHelper extends WuhuBase {
progressBarBg, progressBar, status, desc).insert2Dom(); progressBarBg, progressBar, status, desc).insert2Dom();
// document.querySelector('#websocketConnectionData').after(container); // document.querySelector('#websocketConnectionData').after(container);
Log.info('彩票助手初始化结束,耗时:' + (performance.now() - startTime) + 'ms'); Log.info('彩票助手初始化结束,耗时:' + startTime.getTimeMs());
} }
private async start() { private async start() {
let startTime = performance.now(); let startTime = new Timer();
this.loopFlag = true; this.loopFlag = true;
this.stopBtn.disabled = false; this.stopBtn.disabled = false;
this.startBtn.disabled = true; this.startBtn.disabled = true;
@ -151,7 +152,7 @@ export default class LotteryHelper extends WuhuBase {
rsMsg = '输入有误'; rsMsg = '输入有误';
} }
this.desc.innerHTML = '结束: ' + (rsMsg ? rsMsg + `<br/>耗时:${ (performance.now() - startTime) | 0 }ms` : '出错了'); this.desc.innerHTML = '结束: ' + (rsMsg ? rsMsg + '<br/>耗时:' + startTime.getTimeMs() : '出错了');
this.stopBtn.disabled = true; this.stopBtn.disabled = true;
this.startBtn.disabled = false; this.startBtn.disabled = false;

View File

@ -0,0 +1,27 @@
import WuhuBase from "../WuhuBase";
import Popup from "../utils/Popup";
import Alert from "../utils/Alert";
export default class AdditionalSettingsHandler extends WuhuBase {
className = 'AdditionalSettingsHandler';
public handle(): void {
let pop = new Popup('', '更多设定');
let insertHtml = '<p><button class="torn-btn">清空设置</button></p><p><button class="torn-btn">通知权限</button></p><p><button class="torn-btn">外部数据权限</button></p>';
pop.getElement().insertAdjacentHTML('beforeend', insertHtml);
let [btn1, btn2, btn3] = Array.from(pop.getElement().querySelectorAll('button'));
btn1.addEventListener('click', () => {
localStorage.removeItem('wh_trv_alarm');
localStorage.removeItem('wh_trans_settings');
localStorage.removeItem('whuuid');
localStorage.removeItem('wh-gs-storage');
localStorage.removeItem('WHTEST');
new Alert('已清空,刷新页面');
window.location.reload();
});
btn2.addEventListener('click', () => {
});
btn3.addEventListener('click', () => {
});
}
}

View File

@ -0,0 +1,49 @@
import WuhuBase from "../WuhuBase";
import Popup from "../utils/Popup";
import CommonUtils from "../utils/CommonUtils";
import MDUtils from "../utils/MDUtils";
import Log from "../Log";
export default class ChangeLogHandler extends WuhuBase {
className = 'ChangeLogHandler';
public handle(): void {
let popup = new Popup(
'更新历史:<br/><a target="_blank" href="https://gitlab.com/JJins/wuhu-torn-helper/-/blob/dev/CHANGELOG.md">https://gitlab.com/JJins/wuhu-torn-helper/-/blob/dev/CHANGELOG.md</a><br/>',
'更新历史'
).getElement();
popup.classList.add('wh-changeLog');
let progressBar = document.createElement('div');
progressBar.style.height = '2px';
progressBar.style.width = '1%';
progressBar.style.backgroundColor = 'red';
let progressText = document.createElement('p');
progressText.innerText = '加载更新文件……';
progressText.style.textAlign = 'center';
let style = document.createElement('style');
style.innerHTML = `.wh-changeLog h2,.wh-changeLog h3,.wh-changeLog h4 {margin:8px 0;}.wh-changeLog li{list-style: inside;}`;
popup.append(progressBar, progressText, style);
CommonUtils
.COFetch('https://gitlab.com/JJins/wuhu-torn-helper/-/raw/dev/CHANGELOG.md?' + performance.now())
.then(update => {
progressBar.style.width = '60%';
progressText.innerText = '解析中……';
let md = MDUtils.getInstance().parse(update);
popup.append(md);
progressBar.style.width = '100%';
progressText.innerText = '加载完成';
window.setTimeout(() => {
progressBar.remove();
progressText.remove()
}, 3000);
})
.catch(e => {
Log.error(e);
progressBar.remove();
progressText.innerText = '无法加载';
});
}
}

View File

@ -0,0 +1,95 @@
import WuhuBase from "../WuhuBase";
import CommonUtils from "../utils/CommonUtils";
import Popup from "../utils/Popup";
import QUICK_CRIMES_HTML from "../../static/html/quick_crimes.html";
export default class IFrameCrimeHandler extends WuhuBase {
className = 'IFrameCrimeHandler';
public handle(): void {
// 弹出小窗口
const ifHTML = `<iframe src="/crimes.php?step=main" style="width:100%;max-width: 450px;margin: 0 auto;display: none;height: 340px;"></iframe>`;
const popup_insert = `<p>加载中请稍后${ CommonUtils.loading_gif_html() }</p><div id="wh-quick-crime-if-container"></div>`;
const $popup = new Popup(popup_insert, '小窗快速犯罪').getElement();
// 运行状态node
let loading_node = $popup.querySelector('p:first-of-type');
// if容器
const if_cont = $popup.querySelector('#wh-quick-crime-if-container');
if_cont.innerHTML = ifHTML;
// if内未加载脚本时插入的快捷crime node
const mobile_prepend_node = document.createElement('div');
mobile_prepend_node.classList.add('wh-translate');
mobile_prepend_node.innerHTML = QUICK_CRIMES_HTML;
// if对象加载后运行
let cIframe = $popup.querySelector('iframe');
// 加载状态
const if_onload_func = () => {
// if内部文档对象
const ifDocu = cIframe.contentWindow.document;
// 内部插件运行flag
const ifWH = cIframe.contentWindow.WHTRANS;
// 文档加载完成后移除
if (!!loading_node) loading_node.remove();
// 文档加载完成后才显示if
cIframe.style.display = 'block';
// 验证码flag
const isValidate = ifDocu.querySelector('h4#skip-to-content').innerText.toLowerCase().includes('validate');
// 如果iframe内部未运行脚本
if (ifWH === undefined) {
// 隐藏顶部
CommonUtils.elementReady('#header-root', ifDocu).then(e => e.style.display = 'none');
// 隐藏4条
CommonUtils.elementReady('#sidebarroot', ifDocu).then(e => e.style.display = 'none');
// 隐藏聊天
CommonUtils.elementReady('#chatRoot', ifDocu).then(e => e.style.display = 'none');
// 非验证码页面隐藏滚动条
if (!isValidate) ifDocu.body.style.overflow = 'hidden';
// 调整容器位置
CommonUtils.elementReady('.content-wrapper', ifDocu).then(elem => {
// 加入
elem.prepend(mobile_prepend_node);
elem.style.margin = '0px';
elem.style.position = 'absolute';
elem.style.top = '-35px';
new MutationObserver((m, o) => {
o.disconnect();
if (!elem.querySelector('.wh-translate')) elem.prepend(mobile_prepend_node);
o.observe(elem, { childList: true, subtree: true });
})
.observe(elem, { childList: true, subtree: true });
});
// 隐藏返回顶部按钮
CommonUtils.elementReady('#go-to-top-btn button', ifDocu).then(e => e.style.display = 'none');
}
};
cIframe.onload = if_onload_func;
// 超时判断
let time_counter = 0;
let time_out_id = window.setInterval(() => {
loading_node = $popup.querySelector('p:first-of-type');
if (!loading_node) {
clearInterval(time_out_id);
time_out_id = undefined;
return;
}
time_counter++;
if (time_counter > 0 && !loading_node.querySelector('button')) {
const reload_btn = document.createElement('button');
reload_btn.innerHTML = '重新加载';
reload_btn.onclick = () => {
reload_btn.remove();
time_counter = 0;
if_cont.innerHTML = null;
if_cont.innerHTML = ifHTML;
cIframe = $popup.querySelector('iframe');
cIframe.onload = if_onload_func;
};
loading_node.append(reload_btn);
}
}, 1000);
}
}

View File

@ -0,0 +1,27 @@
import WuhuBase from "../WuhuBase";
import WuhuConfig from "../WuhuConfig";
import PRICE_WATCHER_HTML from "../../static/html/price_watcher.html";
import Popup from "../utils/Popup";
import Global from "../Global";
export default class ItemPriceWatcherHandler extends WuhuBase {
className = 'ItemPriceWatcherHandler';
public handle(): void {
const watcher_conf = WuhuConfig.get('priceWatcher');
const pre_str = JSON.stringify(watcher_conf);
const html = PRICE_WATCHER_HTML
.replace('{{}}', localStorage.getItem('APIKey') || '不可用')
.replace('{{}}', Global.getInstance().isPDA ? Global.getInstance().PDA_APIKey : '不可用')
.replace('{{}}', watcher_conf['pt'] || -1)
.replace('{{}}', watcher_conf['xan'] || -1);
const popup = new Popup(html, '价格监视设置');
popup.getElement().querySelector('button').onclick = () => {
const [pt_node, xan_node] = Array.from(<NodeListOf<HTMLInputElement>>popup.getElement().querySelectorAll('input[type="number"]'));
watcher_conf.pt = (pt_node.value as any) | 0;
watcher_conf.xan = (xan_node.value as any) | 0;
if (JSON.stringify(watcher_conf) !== pre_str) WuhuConfig.set('priceWatcher', watcher_conf);
popup.close();
};
}
}

62
src/class/handler/NNB.ts Normal file
View File

@ -0,0 +1,62 @@
import WuhuBase from "../WuhuBase";
import NNB_INFO_HTML from "../../static/html/nnb_info.html";
import Popup from "../utils/Popup";
import Global from "../Global";
export default class NNB extends WuhuBase {
className = 'NNB';
public handle(): void {
let { isPDA, PDA_APIKey } = Global.getInstance();
const insert = NNB_INFO_HTML
.replace('{{}}', localStorage.getItem('APIKey') || '不可用')
.replace('{{}}', isPDA ? PDA_APIKey : '不可用');
const popup = new Popup(insert, '查看NNB').getElement();
const select = popup.querySelector('input');
const node = popup.querySelector('p');
popup.querySelector('button').addEventListener('click', ev => {
let target = ev.target as HTMLInputElement;
target.style.display = 'none';
node.innerHTML = '加载中';
// API 计算
if (select.checked) {
const api_key = isPDA ? PDA_APIKey : window.localStorage.getItem('APIKey');
window.fetch(`https://api.torn.com/user/?selections=bars,perks&key=${ api_key }`)
.then(res => res.json())
.then(data => {
if (data['error']) {
node.innerHTML = `出错了 ${ JSON.stringify(data['error']) }`;
target.style.display = null;
return;
}
let nb = data['nerve']['maximum'];
let perks = 0;
Object.values(data).forEach(val => {
(val instanceof Array) && val.forEach(s => {
s = s.toLowerCase();
s.includes('maximum nerve') && (perks += (<any>new RegExp('[0-9].').exec(s))[0] | 0)
})
});
node.innerHTML = `NNB: ${ nb - perks }`;
target.style.display = null;
});
}
// 主页计算
else {
if (window.location.href.includes('index.php') && document.title.includes('Home')) {
let nb = (<any>document.querySelector('#barNerve p[class^="bar-value___"]').innerText.split('/')[1]) | 0;
let perks = 0;
document.querySelectorAll('#personal-perks li').forEach(elem => {
const str = elem.innerText.toLowerCase();
str.includes('maximum nerve') && (perks += (/[0-9]./.exec(str) as any)[0] | 0)
});
node.innerHTML = `NNB: ${ nb - perks }`;
target.style.display = null;
return;
}
node.innerHTML = '不在主页面,<a href="/index.php">点击前往</a>';
target.style.display = null;
}
});
}
}

View File

@ -0,0 +1,107 @@
import WuhuBase from "../WuhuBase";
import CommonUtils from "../utils/CommonUtils";
import QUICK_FLY_CSS from "../../static/css/quick_fly.css";
import QUICK_FLY_HTML from "../../static/html/quick_fly.html";
import Alert from "../utils/Alert";
import TravelItem from "../action/TravelItem";
export default class QuickFlyBtnHandler extends WuhuBase {
className = 'QuickFlyBtnHandler';
public static doQuickFly(): void {
// [id: dest, _type: (1...4), ts: timestamp]
const [_id, _type, ts] = sessionStorage['wh-quick-fly'].trim().split(' ');
if (new Date().getTime() - ts > 20000) {
new Alert('超时,一键起飞计划已取消');
return;
}
const keyNode = document.querySelector('div[data-id][data-key]');
if (!keyNode) {
new Alert('出错了,无法起飞,已取消');
return;
}
const _key = keyNode.getAttribute('data-key');
window.getAction({
type: 'post',
data: {
step: 'travel',
id: QuickFlyBtnHandler.getDestId(_id),
key: _key,
type: ['standard', 'airstrip', 'private', 'business'][_type]
},
success: function (str) {
new Alert(str)
if (str.includes('err')) {
new Alert('起飞出错了');
return;
}
window.location.href = 'https://www.torn.com/index.php'
},
before: function () {
}
});
delete sessionStorage['wh-quick-fly'];
}
// 起飞目的地id
private static getDestId(dest): number {
// 墨、开、加、夏、英、阿、瑞s、立本、祖、迪、南
return [2, 12, 9, 3, 10, 7, 8, 5, 6, 11, 4][dest];
}
public handle(): void {
if (window.hasWHQuickFlyOpt) return;
window.hasWHQuickFlyOpt = true;
// TODO
CommonUtils.addStyle(QUICK_FLY_CSS);
const node = document.createElement('div');
node.id = 'wh-quick-fly-opt';
node.innerHTML = QUICK_FLY_HTML;
const [dest_node, type_node] = node.querySelectorAll('select') as any as HTMLSelectElement[];
node.querySelector('button').addEventListener('click', () => {
sessionStorage['wh-quick-fly'] = `${ dest_node.selectedIndex } ${ type_node.selectedIndex } ${ new Date().getTime() }`;
if (!window.location.href.contains('travelagency.php')) {
new Alert('正在转跳');
location.href = 'https://www.torn.com/travelagency.php';
} else {
QuickFlyBtnHandler.doQuickFly();
}
});
node.querySelector('a').addEventListener('click', (e) => {
e.preventDefault();
// forStock();
TravelItem.getInstance().clickHandler();
});
node.querySelector('input').addEventListener('click', (e) => {
node.classList.toggle('wh-quick-fly-opt-hide');
const el = e.target as HTMLInputElement;
el.value = el.value === ' - ' ? ' + ' : ' - ';
});
const info_node = node.querySelector('info');
const time_predict = document.createElement('p');
const yaoCD = document.createElement('p');
info_node.append(time_predict);
info_node.append(yaoCD);
const predict = [
['~54分', '~36分', '~26分', '~16分',],
['~1时10分', '~50分', '~36分', '~22分',],
['~1时22分', '~58分', '~40分', '~24分',],
['~4时28分', '~3时8分', '~2时14分', '~1时20分',],
['~5时18分', '~3时42分', '~2时40分', '~1时36分',],
['~5时34分', '~3时54分', '~2时46分', '~1时40分',],
['~5时50分', '~4时6分', '~2时56分', '~1时46分',],
['~7时30分', '~5时16分', '~3时46分', '~2时16分',],
['~8时4分', '~5时38分', '~4时2分', '~2时24分',],
['~9时2分', '~6时20分', '~4时30分', '~2时42分',],
['~9时54分', '~6时56分', '~4时58分', '~2时58分',],
];
const showTime = function () {
time_predict.innerHTML = `往返时间:${ predict[dest_node.selectedIndex][type_node.selectedIndex] }`;
}
dest_node.addEventListener('change', showTime);
type_node.addEventListener('change', showTime);
document.body.append(node);
showTime();
yaoCD.innerHTML = `药CD剩余${ CommonUtils.getYaoCD() }`;
}
}

View File

@ -0,0 +1,93 @@
import WuhuBase from "../WuhuBase";
import CommonUtils from "../utils/CommonUtils";
import QUICK_LINK_CSS from "../../static/css/quick_link.css";
import Popup from "../utils/Popup";
export default class QuickLinksHandler extends WuhuBase {
className = 'QuickLinksHandler';
private styleAdded: boolean = false;
private list = [];
constructor() {
super();
let list = this.list;
// 生存手册
list.push({
name: '生存手册',
url: 'https://docs.qq.com/doc/DTVpmV2ZaRnB0RG56',
new_tab: true,
img: 'https://www.torn.com/images/items/293/medium.png',
});
// 买啤酒
list.push({
name: '抢啤酒',
url: 'https://www.torn.com/shops.php?step=bitsnbobs',
new_tab: true,
img: 'https://www.torn.com/images/items/180/medium.png',
});
// 买XAN
list.push({
name: '买XAN',
url: 'https://www.torn.com/imarket.php#/p=shop&step=shop&type=&searchname=Xanax',
new_tab: true,
img: 'https://www.torn.com/images/items/206/medium.png',
});
// 起飞
list.push({
name: '起飞',
url: 'https://www.torn.com/travelagency.php',
new_tab: true,
img: 'https://www.torn.com/images/items/396/medium.png',
});
// 买PT
list.push({
name: '买PT',
url: 'https://www.torn.com/pmarket.php',
new_tab: true,
img: 'https://www.torn.com/images/items/722/medium.png',
});
// 租PI
list.push({
name: '租PI',
url: 'https://www.torn.com/properties.php?step=rentalmarket#/property=13',
new_tab: false,
img: 'https://www.torn.com/images/v2/properties/350x230/350x230_default_private_island.png',
});
// 找工作
list.push({
name: '找工作',
url: 'https://www.torn.com/joblist.php#!p=main',
new_tab: false,
img: 'https://www.torn.com/images/items/421/medium.png',
});
// 下悬赏
list.push({
name: '下悬赏',
url: 'https://www.torn.com/bounties.php#/p=add',
new_tab: false,
img: 'https://www.torn.com/images/items/431/medium.png',
});
}
public handle(): void {
if (!this.styleAdded) {
CommonUtils.addStyle(QUICK_LINK_CSS);
this.styleAdded = true;
}
const list = this.list;
let insert = '<p>';
list.forEach(el => {
insert += `<a href="${ el.url }"${ el.new_tab ? ' target="_blank"' : '' }><span class="wh-link-collection-img" style="background: url(${ el.img })"></span><span>${ el.name }</span></a>`;
});
insert += '</p>'
let popup = new Popup(insert, '常用链接');
popup.getElement().classList.add('wh-link-collection-cont');
popup.getElement().addEventListener('click', ev => {
let target = ev.target as HTMLElement;
if (target.tagName.toLowerCase() === 'a' || target.tagName.toLowerCase() === 'span') {
popup.close();
}
});
}
}

View File

@ -0,0 +1,448 @@
import WuhuBase from "../WuhuBase";
import { MenuItemConfig } from "../ZhongIcon";
import Log from "../Log";
import Timer from "../utils/Timer";
import BuyBeerHelper from "../action/BuyBeerHelper";
import UpdateTranslateDict from "./UpdateTranslateDict";
import landedRedirect from "../../func/module/landedRedirect";
import Alert from "../utils/Alert";
import WuhuConfig from "../WuhuConfig";
import ViewLogsHandler from "./ViewLogsHandler";
import AdditionalSettingsHandler from "./AdditionalSettingsHandler";
import Popup from "../utils/Popup";
import CommonUtils from "../utils/CommonUtils";
export default class SettingsHandler extends WuhuBase {
className = 'SettingsHandler';
private list: MenuItemConfig[] = [];
constructor() {
super();
this.constructWuhuSettingList();
}
public handler(): void {
let startTime = new Timer();
Log.info('构造设置开始');
let pop = new Popup(CommonUtils.loading_gif_html(), '芜湖助手设置');
let tmp = document.createElement('div');
tmp.classList.add('gSetting');
this.list.forEach(set => CommonUtils.getInstance().elemGenerator(set, tmp));
pop.getElement().innerHTML = '';
pop.getElement().appendChild(tmp);
// 本日不提醒
pop.getElement().querySelector('#wh-qua-alarm-check-btn')
.addEventListener('click', () => BuyBeerHelper.getInstance().skip_today());
(window.initializeTooltip) && (window.initializeTooltip('#wh-popup-cont', 'white-tooltip'));
Log.info('构造设置结束 ' + startTime.getTimeMs());
}
// 设置
private constructWuhuSettingList(): SettingsHandler {
let timer = new Timer();
Log.info('构造设置列表开始');
const date = new Date();
let beer = BuyBeerHelper.getInstance();
let list = this.list;
// 12月时加入圣诞小镇选项
if (date.getMonth() === 11) {
list.push({
domType: 'plain',
domId: '',
domHTML: '圣诞小镇',
tagName: 'h4',
})
list.push({
domType: 'checkbox',
domId: 'wh-xmastown-wt',
domText: ' 圣诞小镇攻略',
dictName: 'xmasTownWT',
isHide: true,
});
list.push({
domType: 'checkbox',
domId: 'wh-xmastown-notify',
domText: ' 圣诞小镇物品提示',
dictName: 'xmasTownNotify',
isHide: true,
});
}
// 翻译
list.push({
domType: 'plain',
domId: '',
domHTML: '翻译',
tagName: 'h4',
});
// 开启翻译
list.push({
domType: 'checkbox',
domId: 'wh-trans-enable',
domText: ' 开启翻译',
dictName: 'transEnable',
isHide: true,
});
// 更新翻译词库
list.push({
domType: 'button',
domId: '',
domText: '更新翻译词库',
clickFunc: () => UpdateTranslateDict.getInstance().handle()
});
// 战斗优化
list.push({
domType: 'plain',
domId: '',
domHTML: '战斗优化',
tagName: 'h4',
});
// 光速拔刀
list.push({
domType: 'select',
domId: 'wh-quick-attack-index',
domText: '光速拔刀 ',
domSelectOpt: [
{
domVal: 'pri',
domText: '主手',
},
{
domVal: 'sec',
domText: '副手',
},
{
domVal: 'wea',
domText: '近战',
},
{
domVal: 'gre',
domText: '手雷',
},
{
domVal: 'fis',
domText: '拳头',
},
{
domVal: 'kic',
domText: '脚踢',
},
{
domVal: 'none',
domText: '关闭',
},
],
dictName: 'quickAttIndex',
isHide: true,
tip: '将Start Fight按钮移动到指定格子上',
});
// 光速跑路
list.push({
domType: 'select',
domId: 'wh-quick-mug',
domText: '光速跑路 ',
domSelectOpt: [
{
domVal: 'leave',
domText: '跑路(LEAVE)',
},
{
domVal: 'mug',
domText: '打劫(MUG)',
},
{
domVal: 'hosp',
domText: '住院(HOSP)',
},
{
domVal: 'none',
domText: '关闭',
},
],
dictName: 'quickFinishAtt',
isHide: true,
tip: '<del>将结束后指定按钮移动到上面指定的格子上</del>暂时关闭',
});
// 攻击链接转跳
list.push({
domType: 'checkbox',
domId: 'wh-attack-relocate',
domText: ' 真·攻击界面转跳',
dictName: 'attRelocate',
tip: '在无法打开攻击界面的情况下依然可以转跳到正确的攻击页面',
isHide: true,
});
// 危险行为⚠️
if (WuhuConfig.get('dangerZone') === true) {
// 攻击界面自刷新
list.push({
domType: 'select',
domId: 'wh-attack-reload',
domText: '⚠️攻击界面自动刷新 ',
dictName: 'attReload',
domSelectOpt: [
{
domVal: 'none',
domText: '无间隔',
},
{
domVal: '1',
domText: '约1s',
},
{
domVal: '2',
domText: '约2s',
},
{
domVal: '3',
domText: '约3s',
},
{
domVal: '4',
domText: '约4s',
},
{
domVal: '5',
domText: '约5s',
},
{
domVal: 'disabled',
domText: '关闭',
},
],
isHide: true,
tip: '危险功能:接机时常用,将自动刷新页面直到目标落地',
});
// 自动开打和结束
list.push({
domType: 'checkbox',
domId: 'wh-auto-start-finish',
domText: ' ⚠️自动开打和结束',
dictName: 'autoStartFinish',
tip: '脚本将会自动按下战斗和结束按钮',
isHide: true,
});
} else {
WuhuConfig.set('autoStartFinish', false)
WuhuConfig.set('attReload', 6)
}
// 飞行
list.push({
domType: 'plain',
domId: '',
domHTML: '飞行',
tagName: 'h4',
});
// 起飞警告
list.push({
domType: 'checkbox',
domId: 'wh-energy-alert',
domText: ' 起飞爆E警告',
dictName: 'energyAlert',
tip: '起飞前计算来回是否会爆体,红字警告',
isHide: true,
});
// 飞行闹钟
list.push({
domType: 'checkbox',
domId: 'wh-trv-alarm-check',
domText: ' 飞行闹钟',
dictName: 'trvAlarm',
tip: '(仅PC) 飞行页面将显示一个内建的闹钟,落地前声音提醒,需要打开浏览器声音权限',
isHide: true,
});
// 海外警告
list.push({
domType: 'checkbox',
domId: '',
domText: ' 海外警告',
dictName: 'abroadWarning',
tip: '海外落地后每30秒通知警告',
});
// 落地转跳
list.push({ domType: 'button', domId: '', domText: '落地转跳', clickFunc: landedRedirect });
// 公司
list.push({
domType: 'plain',
domId: '',
domHTML: '公司',
tagName: 'h4',
});
// 浮动存钱框
list.push({
domType: 'checkbox',
domId: '',
domText: ' 浮动存钱框',
dictName: 'floatDepo',
tip: '打开公司或帮派的存钱页面后存钱框将浮动显示',
});
// 公司转跳存钱
list.push({
domType: 'checkbox',
domId: '',
domText: ' 公司转跳存钱',
dictName: 'companyRedirect',
tip: '打开公司页面时自动打开存钱选项卡',
});
// 收起公司冰蛙效率表
list.push({
domType: 'checkbox',
domId: '',
domText: ' 收起公司冰蛙效率表',
dictName: 'companyBWCollapse',
tip: '开启后可手动显示隐藏冰蛙公司表格',
});
// 任何位置一键存钱
list.push({
domType: 'checkbox',
domId: '',
domText: ' 任何位置一键存钱',
dictName: 'companyDepositAnywhere',
tip: '在所有页面显示一键存钱按钮Torn OK状态下可用此功能未完全测试无害使用请慎重',
});
// 火车检测开关
list.push({
domType: 'checkbox',
domId: null,
domText: '火车检测',
dictName: 'CHTrainsDetectSwitch',
tip: '检测明日火车是否会超出上限,需要系统通知权限'
});
// 啤酒
list.push({
domType: 'plain',
domId: '',
domHTML: '啤酒',
tagName: 'h4',
});
// 啤酒提醒
list.push({
domType: 'checkbox',
domId: 'wh-qua-alarm-check',
domText: '<span> 啤酒提醒 </span><button id="wh-qua-alarm-check-btn">今日不提醒</button>',
dictName: '_15Alarm',
tip: '每小时的整15分钟的倍数时通知提醒抢啤酒或者血包',
isHide: true,
changeEv: function (ev) {
ev.target.checked ? beer.start() : beer.stop();
},
});
// 啤酒提醒状态
list.push({
domType: 'button',
domId: '',
domText: '啤酒提醒状态',
clickFunc: function () {
new Alert(`啤酒提醒${ beer.status() }`);
}
});
// 啤酒提醒时间
list.push({
domType: 'button',
domId: '',
domText: '啤酒提醒时间设定',
// tip: '通知提前时间',
clickFunc: () => BuyBeerHelper.getInstance().setTimeHandler()
});
// 其他
list.push({
domType: 'plain',
domId: '',
domHTML: '其他',
tagName: 'h4',
});
// 任务助手
list.push({
domType: 'checkbox',
domId: 'wh-mission-lint',
domText: ' 任务助手',
dictName: 'missionHint',
tip: 'Duke任务的一些中文小提示',
isHide: true,
});
// 捡垃圾助手
list.push({
domType: 'checkbox',
domId: 'wh-city-finder',
domText: ' 捡垃圾助手',
dictName: 'cityFinder',
tip: '城市地图中放大显示物品并且估计价值',
isHide: true,
});
// 快速crime
list.push({
domType: 'checkbox',
domId: 'wh-quick-crime',
domText: ' 快速犯罪',
dictName: 'quickCrime',
tip: '显示快捷操作按钮,目前不支持自定义',
isHide: true,
});
// 叠E保护
list.push({
domType: 'checkbox',
domId: 'wh-SEProtect-check',
domText: ' 叠E保护',
dictName: 'SEProtect',
tip: '隐藏健身房的锻炼按钮,防止误操作',
isHide: true,
});
// PT一键购买
list.push({
domType: 'checkbox',
domId: 'wh-ptQuickBuy-check',
domText: ' PT一键购买',
dictName: 'ptQuickBuy',
tip: 'PT市场页面购买时跳过确认',
isHide: true,
});
// 4条转跳
list.push({
domType: 'checkbox',
domId: '',
domText: ' 4条转跳',
dictName: 'barsRedirect',
tip: '点击4条时转跳对应页面',
});
// 清除多余的脚本
list.push({
domType: 'checkbox',
domId: '',
domText: ' 清除多余的脚本',
dictName: 'removeScripts',
tip: '清除Google相关脚本、顶部横幅等',
});
// dev
list.push({
domType: 'checkbox',
domId: 'wh-dev-mode',
domText: '开发模式',
dictName: 'isDev',
isHide: true,
});
// 查看logs
list.push({
domType: 'button',
domId: null,
domText: '查看日志',
clickFunc: () => ViewLogsHandler.getInstance().handle()
});
// 更多设定
list.push({
domType: 'button', domId: 'wh-otherBtn', domText: '更多设定',
clickFunc: () => AdditionalSettingsHandler.getInstance().handle()
});
Log.info('构造设置列表结束' + timer.getTimeMs());
return this;
}
}

View File

@ -0,0 +1,10 @@
import WuhuBase from "../WuhuBase";
import Alert from "../utils/Alert";
export default class UpdateTranslateDict extends WuhuBase {
className = 'UpdateTranslateDict';
public handle(): void {
new Alert('计划中');
}
}

View File

@ -0,0 +1,19 @@
import WuhuBase from "../WuhuBase";
import Log from "../Log";
import Popup from "../utils/Popup";
export default class ViewLogsHandler extends WuhuBase {
className = 'ViewLogsHandler';
public handle(): void {
let logCounter = Log.getCounter();
let pop = new Popup('<textarea readonly style="width:100%;height:340px;"></textarea>', '查看日志');
let text = pop.getElement().querySelector('textarea');
text.innerHTML = Log.getLogs();
text.onclick = () => text.select();
pop.getElement().insertAdjacentHTML(
'afterbegin',
`<p>${ logCounter.info }信息 ${ logCounter.warning }警告 ${ logCounter.error }错误</p>`
);
}
}

View File

@ -3,10 +3,12 @@ import WuhuBase from "../WuhuBase";
import Log from "../Log"; import Log from "../Log";
import Device from "../../enum/Device"; import Device from "../../enum/Device";
import AjaxFetchOption from "../../interface/AjaxFetchOption"; import AjaxFetchOption from "../../interface/AjaxFetchOption";
import Alert from "./Alert";
import LOADING_IMG_HTML from "../../static/html/loading_img.html"; import LOADING_IMG_HTML from "../../static/html/loading_img.html";
import Timer from "./Timer"; import Timer from "./Timer";
import FetchUtils from "./FetchUtils"; import FetchUtils from "./FetchUtils";
import TornStyleSwitch from "./TornStyleSwitch";
import WuhuConfig from "../WuhuConfig";
import { MenuItemConfig } from "../ZhongIcon";
export default class CommonUtils extends WuhuBase { export default class CommonUtils extends WuhuBase {
className = 'CommonUtils'; className = 'CommonUtils';
@ -84,22 +86,22 @@ export default class CommonUtils extends WuhuBase {
}); });
} }
/** // /**
* { playername: string, userID: number } // * 返回玩家信息的对象 { playername: string, userID: number }
* @return {PlayerInfo} rs // * @return {PlayerInfo} rs
*/ // */
static getPlayerInfo(): PlayerInfo { // static getPlayerInfo(): PlayerInfo {
const node = document.querySelector('script[uid]'); // const node = document.querySelector('script[uid]');
if (node) { // if (node) {
return { // return {
playername: node.getAttribute('name'), // playername: node.getAttribute('name'),
userID: node.getAttribute('uid') as unknown as number, // userID: node.getAttribute('uid') as unknown as number,
} // }
} else { // } else {
new Alert('严重错误:芜湖助手无法获取用户数据,已退出'); // new Alert('严重错误:芜湖助手无法获取用户数据,已退出');
throw '芜湖助手无法获取用户数据'; // throw '芜湖助手无法获取用户数据';
} // }
} // }
// 用户设备类型 对应PC MOBILE TABLET // 用户设备类型 对应PC MOBILE TABLET
public static getDeviceType(): Device { public static getDeviceType(): Device {
@ -171,6 +173,12 @@ export default class CommonUtils extends WuhuBase {
}); });
} }
/**
* mutation.observe
* @param selectors
* @param content
* @param timeout
*/
public static querySelector(selectors: string, content: Document = document, timeout: number = 30000): Promise<HTMLElement> { public static querySelector(selectors: string, content: Document = document, timeout: number = 30000): Promise<HTMLElement> {
return CommonUtils.elementReady(selectors, content, timeout); return CommonUtils.elementReady(selectors, content, timeout);
} }
@ -247,4 +255,70 @@ export default class CommonUtils extends WuhuBase {
let time = Math.max(ms, 10); let time = Math.max(ms, 10);
return new Promise(resolve => setTimeout(() => resolve(null), time)); return new Promise(resolve => setTimeout(() => resolve(null), time));
} }
public elemGenerator(setting: MenuItemConfig, root_node: Element): HTMLElement {
let { tip, domType } = setting;
let new_node = null;
switch (domType) {
case 'checkbox': {
new_node = document.createElement('div');
let { domId, dictName, domText, changeEv } = setting;
let switcher = new TornStyleSwitch(domText);
let _input = switcher.getInput();
switcher.getBase().id = domId;
(tip) && (switcher.getBase().setAttribute('title', tip));
_input.checked = WuhuConfig.get(dictName);
_input.onchange = e => {
WuhuConfig.set(dictName, _input.checked, true);
if (changeEv) changeEv(e);
};
new_node.appendChild(switcher.getBase());
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 === WuhuConfig.get(dictName);
option.innerHTML = domText;
select.appendChild(option);
});
select.onchange = e => WuhuConfig.set(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);
}
} }

View File

@ -0,0 +1,53 @@
import Log from "../Log";
import DIALOG_MSG_BOX_HTML from "../../static/html/dialog_msg_box.html";
export default class DialogMsgBox {
private static existed = false;
private readonly container: HTMLElement;
constructor(msg: string, opt: DialogMsgBoxOptions) {
Log.info('创建DialogMsgBox', { msg, opt });
let { title = '提示', callback } = opt;
if (!callback) {
Log.error('无callback');
throw new Error('无callback');
}
if (DialogMsgBox.existed) {
Log.error('无法创建DialogMsgBox已存在');
throw new Error('无法创建DialogMsgBox已存在');
}
this.container = document.createElement('div');
this.container.id = 'wh-dialog';
this.container.innerHTML = DIALOG_MSG_BOX_HTML.replace('{{}}', title).replace('{{}}', msg);
let [confirm, cancel] = Array.from(this.container.querySelectorAll('button'));
confirm.addEventListener('click', () => {
callback(this.container);
this.destroy();
});
cancel.addEventListener('click', () => {
this.destroy();
});
document.body.append(this.container);
// this.hideChat();
DialogMsgBox.existed = true;
}
// private hideChat() {
// document.querySelector('#chatRoot').classList.add('wh-hide');
// }
//
// private showChat() {
// document.querySelector('#chatRoot').classList.remove('wh-hide');
// }
private destroy() {
this.container.remove();
// this.showChat();
DialogMsgBox.existed = false;
}
}
interface DialogMsgBoxOptions {
title?: string;
callback: Function;
}

View File

@ -1,5 +1,5 @@
export default class Timer { export default class Timer {
private startTime: number; private readonly startTime: number;
constructor() { constructor() {
this.startTime = performance.now(); this.startTime = performance.now();

View File

@ -4,11 +4,11 @@ export default class TornStyleSwitch {
private readonly baseElement; private readonly baseElement;
private readonly randomId; private readonly randomId;
constructor(label: string) { constructor(label: string, checked: boolean = false) {
this.randomId = MathUtils.getInstance().getRandomInt(100, 2000); this.randomId = MathUtils.getInstance().getRandomInt(100, 2000);
this.baseElement = document.createElement('span'); this.baseElement = document.createElement('span');
this.baseElement.id = 'WHSwitch' + this.randomId; this.baseElement.id = 'WHSwitch' + this.randomId;
this.baseElement.innerHTML = `<input class="checkbox-css" type="checkbox" id="WHCheck${ this.randomId }"> this.baseElement.innerHTML = `<input class="checkbox-css" type="checkbox" id="WHCheck${ this.randomId }" ${ checked ? 'checked' : '' }/>
<label for="WHCheck${ this.randomId }" class="non-selection marker-css">${ label }</label>`; <label for="WHCheck${ this.randomId }" class="non-selection marker-css">${ label }</label>`;
} }
@ -19,4 +19,8 @@ export default class TornStyleSwitch {
public getInput(): HTMLInputElement { public getInput(): HTMLInputElement {
return this.baseElement.querySelector('input'); return this.baseElement.querySelector('input');
} }
public getHtml(): string {
return this.baseElement.innerHTML;
}
} }

View File

@ -1,43 +1,43 @@
import Alert from "../../class/utils/Alert"; // import Alert from "../../class/utils/Alert";
//
// 一键起飞 // // 一键起飞
export default function doQuickFly() { // export default function doQuickFly() {
// [id: dest, _type: (1...4), ts: timestamp] // // [id: dest, _type: (1...4), ts: timestamp]
const [_id, _type, ts] = sessionStorage['wh-quick-fly'].trim().split(' '); // const [_id, _type, ts] = sessionStorage['wh-quick-fly'].trim().split(' ');
if (new Date().getTime() - ts > 20000) { // if (new Date().getTime() - ts > 20000) {
new Alert('超时,一键起飞计划已取消'); // new Alert('超时,一键起飞计划已取消');
return; // return;
} // }
const keynode = document.querySelector('div[data-id][data-key]'); // const keynode = document.querySelector('div[data-id][data-key]');
if (!keynode) { // if (!keynode) {
new Alert('出错了,无法起飞,已取消'); // new Alert('出错了,无法起飞,已取消');
return; // return;
} // }
const _key = keynode.getAttribute('data-key'); // const _key = keynode.getAttribute('data-key');
window.getAction({ // window.getAction({
type: 'post', // type: 'post',
data: { // data: {
step: 'travel', // step: 'travel',
id: getDestId(_id), // id: getDestId(_id),
key: _key, // key: _key,
type: ['standard', 'airstrip', 'private', 'business'][_type] // type: ['standard', 'airstrip', 'private', 'business'][_type]
}, // },
success: function (str) { // success: function (str) {
new Alert(str) // new Alert(str)
if (str.includes('err')) { // if (str.includes('err')) {
new Alert('起飞出错了'); // new Alert('起飞出错了');
return; // return;
} // }
window.location.href = 'https://www.torn.com/index.php' // window.location.href = 'https://www.torn.com/index.php'
}, // },
before: function () { // before: function () {
} // }
}); // });
delete sessionStorage['wh-quick-fly']; // delete sessionStorage['wh-quick-fly'];
} // }
//
// 起飞目的地id // // 起飞目的地id
function getDestId(dest) { // function getDestId(dest) {
// 墨、开、加、夏、英、阿、瑞s、立本、祖、迪、南 // // 墨、开、加、夏、英、阿、瑞s、立本、祖、迪、南
return [2, 12, 9, 3, 10, 7, 8, 5, 6, 11, 4][dest]; // return [2, 12, 9, 3, 10, 7, 8, 5, 6, 11, 4][dest];
} // }

View File

@ -1,5 +1,3 @@
import getWhSettingObj from "../utils/@deprecated/getWhSettingObj";
import log from "../utils/@deprecated/log";
import toThousands from "../utils/toThousands"; import toThousands from "../utils/toThousands";
import Log from "../../class/Log"; import Log from "../../class/Log";
import Alert from "../../class/utils/Alert"; import Alert from "../../class/utils/Alert";
@ -12,7 +10,7 @@ export default function priceWatcherHandle(isPDA: boolean, PDA_APIKey: string) {
const price_conf = WuhuConfig.get('priceWatcher'); const price_conf = WuhuConfig.get('priceWatcher');
const apikey = isPDA ? PDA_APIKey : localStorage.getItem('APIKey'); const apikey = isPDA ? PDA_APIKey : localStorage.getItem('APIKey');
if (!apikey || (price_conf['pt'] === -1 && price_conf['xan'] === -1)) { if (!apikey || (price_conf['pt'] === -1 && price_conf['xan'] === -1)) {
Log.error('价格监视失败无apikey'); Log.warn('价格监视关闭无apikey或设置未打开');
window.clearInterval(intervalId); window.clearInterval(intervalId);
return; return;
} }

View File

@ -1,7 +1,6 @@
import titleTrans from "../translate/titleTrans"; import titleTrans from "../translate/titleTrans";
import contentTitleLinksTrans from "../translate/contentTitleLinksTrans"; import contentTitleLinksTrans from "../translate/contentTitleLinksTrans";
import Device from "../../enum/Device"; import Device from "../../enum/Device";
import doQuickFly from "./doQuickFly";
import WuhuBase from "../../class/WuhuBase"; import WuhuBase from "../../class/WuhuBase";
import Alert from "../../class/utils/Alert"; import Alert from "../../class/utils/Alert";
import ActionButtonUtils from "../../class/utils/ActionButtonUtils"; import ActionButtonUtils from "../../class/utils/ActionButtonUtils";
@ -10,6 +9,7 @@ import CommonUtils from "../../class/utils/CommonUtils";
import TRAVEL_ALARM_CSS from "../../static/css/travel_alarm.css"; import TRAVEL_ALARM_CSS from "../../static/css/travel_alarm.css";
import TRAVEL_ALARM_HTML from "../../static/html/travel_alarm.html"; import TRAVEL_ALARM_HTML from "../../static/html/travel_alarm.html";
import TornStyleBlock from "../../class/utils/TornStyleBlock"; import TornStyleBlock from "../../class/utils/TornStyleBlock";
import QuickFlyBtnHandler from "../../class/handler/QuickFlyBtnHandler";
export default async function travelHelper(): Promise<null> { export default async function travelHelper(): Promise<null> {
let { href, bodyAttrs, device } = WuhuBase.glob; let { href, bodyAttrs, device } = WuhuBase.glob;
@ -29,7 +29,7 @@ export default async function travelHelper(): Promise<null> {
dest_cn = { dest_cn = {
'uk': "英国", 'switzerland': "瑞士", 'mexico': '墨西哥', 'canada': '加拿大', 'cayman': '开曼', 'uk': "英国", 'switzerland': "瑞士", 'mexico': '墨西哥', 'canada': '加拿大', 'cayman': '开曼',
'hawaii': '夏威夷', 'argentina': '阿根廷', 'hawaii': '夏威夷', 'argentina': '阿根廷',
'japan': '日本', 'china': '中国', 'uae': 'UAE', 'sa': '南非', 'japan': '日本', 'china': '中国', 'uae': 'UAE', 'south-africa': '南非',
}[country] || country; }[country] || country;
} }
@ -286,7 +286,7 @@ export default async function travelHelper(): Promise<null> {
} }
// 一键起飞 // 一键起飞
if (sessionStorage['wh-quick-fly']) { if (sessionStorage['wh-quick-fly']) {
doQuickFly(); QuickFlyBtnHandler.doQuickFly();
} }
} }
} }

View File

@ -37,6 +37,7 @@ import showItemInfoTrans from "./showItemInfoTrans";
import log from "../utils/@deprecated/log"; import log from "../utils/@deprecated/log";
import contentTitleLinksTransReact from "./contentTitleLinksTransReact"; import contentTitleLinksTransReact from "./contentTitleLinksTransReact";
import titleTransReact from "./titleTransReact"; import titleTransReact from "./titleTransReact";
import Log from "../../class/Log";
export default function translateMain(href: string): void { export default function translateMain(href: string): void {
// 时分秒转换 // 时分秒转换
@ -123,12 +124,14 @@ export default function translateMain(href: string): void {
const headerTrans = function headerTrans() { const headerTrans = function headerTrans() {
// 搜索内容下拉框中的文字 已选中 // 搜索内容下拉框中的文字 已选中
if (headerDict[$('div.find button.toggler.down').text()]) let $toggle = $('div.find button.toggler.down');
$('div.find button.toggler.down').text(headerDict[$('div.find button.toggler.down').text()]); if (headerDict[$toggle.text()])
$toggle.text(headerDict[$toggle.text()]);
// pc端 搜索下拉框点击后的搜索类型文字 // pc端 搜索下拉框点击后的搜索类型文字
$('div.find li.item').each((i, e) => { $('div.find li.item').each((i, e) => {
if (headerDict[$(e).text()]) let $e = $(e);
$(e).text(headerDict[$(e).text()]); if (headerDict[$e.text()])
$e.text(headerDict[$e.text()]);
}); });
// 手机端 搜索下拉框点击后的搜索类型文字 // 手机端 搜索下拉框点击后的搜索类型文字
$('li[class^="search-type-"] label').each((i, e) => { $('li[class^="search-type-"] label').each((i, e) => {
@ -136,46 +139,54 @@ export default function translateMain(href: string): void {
$(e).text(headerDict[$(e).text()]); $(e).text(headerDict[$(e).text()]);
}); });
// 搜索框placeholder // 搜索框placeholder
if (headerDict[$('input[class^="searchInput"]').attr('placeholder')]) let $searchInput = $('input[class^="searchInput"]');
$('input[class^="searchInput"]').attr('placeholder', if (headerDict[$searchInput.attr('placeholder')])
headerDict[$('input[class^="searchInput"]').attr('placeholder')]); $searchInput.attr('placeholder',
headerDict[$searchInput.attr('placeholder')]);
// 高级搜索框 search by // 高级搜索框 search by
if (headerDict[document.querySelector('div#header-root legend.title').innerText]) if (headerDict[document.querySelector('div#header-root legend.title').innerText]) {
$('div#header-root legend.title').text(headerDict[$('div#header-root legend.title').text()]); let $title = $('div#header-root legend.title');
$title.text(headerDict[$title.text()]);
}
// 高级搜索框的条件 左 键 // 高级搜索框的条件 左 键
$('ul.advancedSearchFormBody label.label').each((i, e) => { $('ul.advancedSearchFormBody label.label').each((i, e) => {
if (headerDict[$(e).text()]) let $e = $(e);
$(e).text(headerDict[$(e).text()]); if (headerDict[$e.text()])
$e.text(headerDict[$e.text()]);
}); });
// 高级搜索框的已选中 // 高级搜索框的已选中
$('ul.advancedSearchFormBody div.select-wrapper button.toggler.down').each((i, e) => { $('ul.advancedSearchFormBody div.select-wrapper button.toggler.down').each((i, e) => {
// log($(e).text()) let $e = $(e);
if (headerDict[$(e).text().trim()]) if (headerDict[$e.text().trim()])
$(e).text(headerDict[$(e).text().trim()]); $e.text(headerDict[$e.text().trim()]);
else if (propertyDict[$(e).text().trim()]) else if (propertyDict[$e.text().trim()])
$(e).text(propertyDict[$(e).text().trim()]); $e.text(propertyDict[$e.text().trim()]);
}); });
// 高级搜索的下拉选项 // 高级搜索的下拉选项
$('ul.advancedSearchFormBody li.item').each((i, e) => { $('ul.advancedSearchFormBody li.item').each((i, e) => {
if (headerDict[$(e).text()]) let $e = $(e);
$(e).text(headerDict[$(e).text()]); if (headerDict[$e.text()])
else if (propertyDict[$(e).text()]) $e.text(headerDict[$e.text()]);
$(e).text(propertyDict[$(e).text()]); else if (propertyDict[$e.text()])
$e.text(propertyDict[$e.text()]);
}); });
// 高级搜索的"Not" // 高级搜索的"Not"
$('ul.advancedSearchFormBody label.search-condition-not').each((i, e) => { $('ul.advancedSearchFormBody label.search-condition-not').each((i, e) => {
if (headerDict[$(e).text()]) let $e = $(e);
$(e).text(headerDict[$(e).text()]); if (headerDict[$e.text()])
$e.text(headerDict[$e.text()]);
}); });
// 高级搜索的"to" // 高级搜索的"to"
$('ul.advancedSearchFormBody label[for*="To"]').each((i, e) => { $('ul.advancedSearchFormBody label[for*="To"]').each((i, e) => {
if (headerDict[$(e).text()]) let $e = $(e);
$(e).text(headerDict[$(e).text()]); if (headerDict[$e.text()])
$e.text(headerDict[$e.text()]);
}); });
// 高级搜索的reset search按钮 // 高级搜索的reset search按钮
$('form.form-search-extend div.bottom button').each((i, e) => { $('form.form-search-extend div.bottom button').each((i, e) => {
if (headerDict[$(e).text()]) let $e = $(e);
$(e).text(headerDict[$(e).text()]); if (headerDict[$e.text()])
$e.text(headerDict[$e.text()]);
}); });
// log按钮“view log” // log按钮“view log”
const $view_log = $('div.recentHistory a[class^="link"] span[class^="text"]') const $view_log = $('div.recentHistory a[class^="link"] span[class^="text"]')
@ -184,8 +195,9 @@ export default function translateMain(href: string): void {
.text(headerDict[$view_log.text().trim()]); .text(headerDict[$view_log.text().trim()]);
// 点击头像打开的菜单 // 点击头像打开的菜单
$('ul.settings-menu span').each((i, e) => { $('ul.settings-menu span').each((i, e) => {
if (headerDict[$(e).text()] && e.childNodes.length === 1) let $e = $(e);
$(e).text(headerDict[$(e).text()]); if (headerDict[$e.text()] && e.childNodes.length === 1)
$e.text(headerDict[$e.text()]);
else if (e.childNodes.length === 3) else if (e.childNodes.length === 3)
if (headerDict[e.firstChild.nodeValue]) if (headerDict[e.firstChild.nodeValue])
e.firstChild.nodeValue = headerDict[e.firstChild.nodeValue]; e.firstChild.nodeValue = headerDict[e.firstChild.nodeValue];
@ -205,20 +217,22 @@ export default function translateMain(href: string): void {
const chatTrans = function chatTrans() { const chatTrans = function chatTrans() {
// 聊天框的标题 // 聊天框的标题
$('div#chatRoot div[class^="chat-box-title"] span[class^="name"]').each((i, e) => { $('div#chatRoot div[class^="chat-box-title"] span[class^="name"]').each((i, e) => {
if (chatDict[$(e).text().trim()]) let $e = $(e);
$(e).text(chatDict[$(e).text().trim()]); if (chatDict[$e.text().trim()])
$e.text(chatDict[$e.text().trim()]);
}); });
// 聊天设置的左边label // 聊天设置的左边label
$('div[class^="chat-settings-opts"] div[class*="label"]').each((i, e) => { $('div[class^="chat-settings-opts"] div[class*="label"]').each((i, e) => {
if ($(e).next().children('div.rc-slider').length > 0) { let $e = $(e);
if ($e.next().children('div.rc-slider').length > 0) {
// 高度和宽度有响应式的% // 高度和宽度有响应式的%
if (chatDict[$(e).text().split(' ')[0]]) { if (chatDict[$e.text().split(' ')[0]]) {
$(e).text($(e).text().replace($(e).text().split(' ')[0], chatDict[$(e).text().split(' ')[0]])); $e.text($e.text().replace($e.text().split(' ')[0], chatDict[$e.text().split(' ')[0]]));
} }
return; return;
} }
if (chatDict[$(e).text().trim()]) if (chatDict[$e.text().trim()])
$(e).text(chatDict[$(e).text().trim()]); $e.text(chatDict[$e.text().trim()]);
}); });
// 选项下拉栏 // 选项下拉栏
$('div[class^="dropdown-root"]').find('*').contents().each((i, e) => { $('div[class^="dropdown-root"]').find('*').contents().each((i, e) => {
@ -228,29 +242,30 @@ export default function translateMain(href: string): void {
}); });
// 设置的两个选项 // 设置的两个选项
$('label[class^="privacy-label"]').each((i, e) => { $('label[class^="privacy-label"]').each((i, e) => {
if (chatDict[$(e).text().trim()]) let $e = $(e);
$(e).text(chatDict[$(e).text().trim()]); if (chatDict[$e.text().trim()])
$e.text(chatDict[$e.text().trim()]);
}); });
// people中的5个分类 faction friend... // people中的5个分类 faction friend...
$('ul[class^="type-list"] li a').each((i, e) => { $('ul[class^="type-list"] li a').each((i, e) => {
if (chatDict[$(e).text().trim()]) let $e = $(e);
$(e).text(chatDict[$(e).text().trim()]); if (chatDict[$e.text().trim()])
$e.text(chatDict[$e.text().trim()]);
}); });
// people中的列表添加框placeholder // people中的列表添加框placeholder
$('div.ac-wrapper input.ac-search').each((i, e) => { $('div.ac-wrapper input.ac-search').each((i, e) => {
if (chatDict[$(e).attr('placeholder')]) let $e = $(e);
$(e).attr('placeholder', chatDict[$(e).attr('placeholder')]); if (chatDict[$e.attr('placeholder')])
$e.attr('placeholder', chatDict[$e.attr('placeholder')]);
}); });
// //
if (eventsDict[$('div#chatRoot div[class^="overview"] > div > div:nth-child(2)').text().trim()]) { let $chatRootOverview = document.querySelector('div#chatRoot div[class^="overview"] > div > div:nth-child(2)');
$('div#chatRoot div[class^="overview"] > div > div:nth-child(2)') if (eventsDict[$chatRootOverview.innerText.trim()]) {
.text( $chatRootOverview.innerText = eventsDict[$chatRootOverview.innerText.trim()];
eventsDict[document.querySelector('div#chatRoot div[class^="overview"] > div > div:nth-child(2)').innerText.trim()]
);
} }
}; };
chatTrans(); chatTrans();
chatOB.observe($('div#chatRoot').get(0), { childList: true, subtree: true, attributes: true }); chatOB.observe(document.querySelector('div#chatRoot'), { childList: true, subtree: true, attributes: true });
} }
// 搜索玩家的4个分类按钮 // 搜索玩家的4个分类按钮
@ -327,18 +342,18 @@ export default function translateMain(href: string): void {
// 翻译最近5个攻击 // 翻译最近5个攻击
else if (e.firstChild.nodeValue === 'Latest Attacks') { else if (e.firstChild.nodeValue === 'Latest Attacks') {
$(e).parent().next().find('span').each(function () { $(e).parent().next().find('span').each(function () {
let nodes = $(this)[0].childNodes; let $this = $(this);
let nodes = $this[0].childNodes;
nodes.forEach((v, i) => { nodes.forEach((v, i) => {
if (v.nodeValue !== null) { if (v.nodeValue !== null) {
let waitToTsf = v.nodeValue.toString().indexOf(" "); // let waitToTsf = v.nodeValue.toString().indexOf(" ");
let words = v.nodeValue.replace("\n", "").toString().split(" "); let words = v.nodeValue.replace("\n", "").toString().split(" ");
words.forEach((word, j) => { words.forEach((word, j) => {
if (attackDict.hasOwnProperty(word)) { if (attackDict.hasOwnProperty(word)) {
if (word === "Someone") { if (word === "Someone") {
$(this)[0].childNodes[i].nodeValue = $(this)[0].childNodes[i].nodeValue.replace(" ", ""); $this[0].childNodes[i].nodeValue = $(this)[0].childNodes[i].nodeValue.replace(" ", "");
} }
let change = $(this)[0].childNodes[i].nodeValue.replace(word, attackDict[word]); $this[0].childNodes[i].nodeValue = $this[0].childNodes[i].nodeValue.replace(word, attackDict[word]);
$(this)[0].childNodes[i].nodeValue = change;
} }
}) })
@ -373,13 +388,13 @@ export default function translateMain(href: string): void {
}); });
// 标志建筑 标题 // 标志建筑 标题
if (cityDict[$('div.title-black').text()]) let $divTitleBlack = document.querySelector('div.title-black');
$('div.title-black').text(cityDict[$('div.title-black').text()]); if (cityDict[$divTitleBlack.innerText])
$divTitleBlack.innerText = cityDict[$divTitleBlack.innerText];
// 标志建筑 6个分类 // 标志建筑 6个分类
$('ul.map-symbols span').each((i, e) => { $('ul.map-symbols span').each((i, e) => {
if (cityDict[$(e).text()]) if (cityDict[e.innerText]) e.innerText = cityDict[e.innerText];
$(e).text(cityDict[$(e).text()]);
}); });
// 地图显示模式 // 地图显示模式
@ -388,13 +403,13 @@ export default function translateMain(href: string): void {
// 完全显示 文字 // 完全显示 文字
$('span.active-mode').text(cityDict['active-mode']); $('span.active-mode').text(cityDict['active-mode']);
// 开关 // 开关
$('div.on-label').text('已开启'); document.querySelector('div.on-label').innerText = '已开启';
$('div.off-label').text('已关闭'); document.querySelector('div.off-label').innerText = '已关闭';
// 快速链接中的分类标题 // 快速链接中的分类标题
$('li.title').each((i, e) => { $('li.title').each((i, e) => {
if (cityDict[$(e).text()]) if (cityDict[e.innerText])
$(e).text(cityDict[$(e).text()]); e.innerText = cityDict[e.innerText];
}); });
// 快速链接中的区域 // 快速链接中的区域
@ -1235,9 +1250,10 @@ export default function translateMain(href: string): void {
let newspaperTrans = function newspaperTrans() { let newspaperTrans = function newspaperTrans() {
titleTrans(); titleTrans();
contentTitleLinksTrans(); contentTitleLinksTrans();
if ($('a.newspaper-link').length === 0) return; let $newspaperLink = $('a.newspaper-link');
if ($newspaperLink.length === 0) return;
// 导航菜单 // 导航菜单
$('a.newspaper-link').contents().each((i, e) => { $newspaperLink.contents().each((i, e) => {
if (newspaperDict[e.nodeValue]) if (newspaperDict[e.nodeValue])
e.nodeValue = newspaperDict[e.nodeValue]; e.nodeValue = newspaperDict[e.nodeValue];
}); });
@ -1284,8 +1300,9 @@ export default function translateMain(href: string): void {
}); });
// 底部链接 // 底部链接
// Why not visit our sponsor? // Why not visit our sponsor?
if (newspaperDict[$('div.link-left').text().trim()]) let $linkLeft = document.querySelector('div.link-left');
$('div.link-left').text(newspaperDict[$('div.link-left').text().trim()]); if (newspaperDict[$linkLeft.innerText.trim()])
$linkLeft.innerText = newspaperDict[$linkLeft.innerText.trim()];
// View all | Advertise here // View all | Advertise here
$('div.link-right a').contents().each((i, e) => { $('div.link-right a').contents().each((i, e) => {
if (newspaperDict[e.nodeValue.trim()]) if (newspaperDict[e.nodeValue.trim()])
@ -1306,8 +1323,9 @@ export default function translateMain(href: string): void {
} }
// 漫画 // 漫画
if (window.location.href.contains(/freebies/)) { if (window.location.href.contains(/freebies/)) {
if (newspaperDict[$('div.bonus-wrap a').text().trim()]) let $bonusWrapA = document.querySelector('div.bonus-wrap a');
$('div.bonus-wrap a').text(newspaperDict[$('div.bonus-wrap a').text().trim()]); if (newspaperDict[$bonusWrapA.innerText.trim()])
$bonusWrapA.innerText = newspaperDict[$bonusWrapA.innerText.trim()];
} }
// 悬赏 // 悬赏
if (window.location.href.contains(/bounties/)) { if (window.location.href.contains(/bounties/)) {
@ -1960,39 +1978,42 @@ export default function translateMain(href: string): void {
//攻击链盒 //攻击链盒
$('div[class^="chain-box"]').contents().each((i, e) => { $('div[class^="chain-box"]').contents().each((i, e) => {
if (factionDict[$(e).text().trim()]) { let $e = $(e);
$(e).text(factionDict[$(e).text().trim()]); if (factionDict[$e.text().trim()]) {
$e.text(factionDict[$e.text().trim()]);
} }
}) })
//帮派消息类别 //帮派消息类别
$('div[class^="newsHeader"]').contents().each((i, e) => { $('div[class^="newsHeader"]').contents().each((i, e) => {
if (factionDict[$(e).text().trim()]) { let $e = $(e);
$(e).text(factionDict[$(e).text().trim()]); if (factionDict[$e.text().trim()]) {
$e.text(factionDict[$e.text().trim()]);
} }
}) })
//帮派主要消息日志 //帮派主要消息日志
$('button[class^="tab"] ').each((i, e) => { $('button[class^="tab"] ').each((i, e) => {
if ($(e).attr('class').indexOf("active") >= 0) { if (e.classList.contains('active')) {
log.info($(e).text()); Log.info(e.innerText);
switch ($(e).text().trim()) { let $newListInfo = $('ul[class^="news-list"] span[class^="info"]');
switch (e.innerText.trim()) {
case "主要消息": case "主要消息":
$('ul[class^="news-list"] span[class^="info"]').contents().each((i, u) => { $newListInfo.contents().each((i, u) => {
if (factionDict[$(u).text().trim()]) { if (factionDict[$(u).text().trim()]) {
u.nodeValue = u.nodeValue.replace($(u).text().trim(), factionDict[$(u).text().trim()]); u.nodeValue = u.nodeValue.replace($(u).text().trim(), factionDict[$(u).text().trim()]);
} }
}) })
break; break;
case "攻击": case "攻击":
$('ul[class^="news-list"] span[class^="info"]').find('*').contents().each((i, u) => { $newListInfo.find('*').contents().each((i, u) => {
log.info($(u).text().trim()) Log.info($(u).text().trim());
if (factionDict[$(u).text().trim()]) { if (factionDict[$(u).text().trim()]) {
u.nodeValue = factionDict[$(u).text().trim()]; u.nodeValue = factionDict[$(u).text().trim()];
} }
}) })
break; break;
case "资金流动": case "资金流动":
$('ul[class^="news-list"] span[class^="info"]').contents().each((i, u) => { $newListInfo.contents().each((i, u) => {
if (u.nodeValue) { if (u.nodeValue) {
u.nodeValue = u.nodeValue.replace("deposited", "存放了"); u.nodeValue = u.nodeValue.replace("deposited", "存放了");
} }

View File

@ -1,6 +1,6 @@
import Alert from "../../class/utils/Alert"; // import Alert from "../../class/utils/Alert";
//
// 更新词库 // // 更新词库
export default function updateTransDict() { // export default function updateTransDict() {
new Alert('计划中'); // new Alert('计划中');
} // }

View File

@ -1,5 +1,4 @@
export default interface ISidebarData { export default interface ISidebarData {
// TODO 补全
statusIcons?: StatusIcons; statusIcons?: StatusIcons;
user?: { user?: {
userID: number, userID: number,

View File

@ -114,10 +114,7 @@ div#wh-popup::after {
#wh-popup-container { #wh-popup-container {
max-width: 568px; max-width: 568px;
margin: 5em auto 0; margin: 5em auto 0;
/*background: #d7d7d7;*/ /*box-shadow: 0 0 5px 1px #898989;*/
/*min-height: 120px;*/
box-shadow: 0 0 5px 1px #898989;
/*border-radius: 4px;*/
} }
#wh-popup-title p { #wh-popup-title p {

View File

@ -0,0 +1,54 @@
<style>
html {
overflow: hidden !important;
}
#chatRoot {
display: none !important;
}
#wh-dialog {
position: absolute;
/*width: 100%;*/
/*height: 100%;*/
background: #00000066;
flex-direction: column;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 290001;
}
#wh-dialog .top-round {
text-align: center;
}
#wh-dialog div.wh-content {
padding: 1em;
}
#wh-dialog .border-round {
margin: auto;
max-width: 400px;
position: fixed;
top: 100px;
left: 0;
right: 0;
}
#wh-dialog .pin-bottom {
text-align: center;
padding: 8px 0;
}
</style>
<div class="border-round">
<div class="title-black top-round">{{}}</div>
<div class="cont-gray bottom-round">
<div class="wh-content">{{}}</div>
<div class="non-selection pin-bottom">
<button class="torn-btn">确定</button>
<button class="torn-btn">取消</button>
</div>
</div>
</div>

View File

@ -2,7 +2,7 @@
<div id="deadman_header" style="margin:10px 0px; border:1px solid darkgray; text-align:center;"> <div id="deadman_header" style="margin:10px 0px; border:1px solid darkgray; text-align:center;">
<button class="torn-btn" id="deadman-start-btn" style="margin:5px;">开始寻找木桩</button> <button class="torn-btn" id="deadman-start-btn" style="margin:5px;">开始寻找木桩</button>
</div> </div>
<div id="deadman_tips" style="text-align:center; margin-bottom: 3px; font-size: 4px;">未开始</div> <div id="deadman_tips" style="text-align:center; margin-bottom: 3px; font-size: 16px;">未开始</div>
<div id="deadman_wrapper" <div id="deadman_wrapper"
style="min-height:700px;margin:10px 0px; border:1px solid darkgray; text-align:center;overflow:hidden;"> style="min-height:700px;margin:10px 0px; border:1px solid darkgray; text-align:center;overflow:hidden;">
<table cellspacing="0" id="watchlist-table" style="width:100%; background-color: white; font-size:12px;"> <table cellspacing="0" id="watchlist-table" style="width:100%; background-color: white; font-size:12px;">

View File

@ -1,15 +1,13 @@
import WuhuBase from "../class/WuhuBase"; import WuhuBase from "../class/WuhuBase";
import Log from "../class/Log"; import Log from "../class/Log";
import Popup from "../class/utils/Popup"; import DialogMsgBox from "../class/utils/DialogMsgBox";
import WuhuConfig from "../class/WuhuConfig";
import Alert from "../class/utils/Alert";
export default class Test extends WuhuBase { export default class Test extends WuhuBase {
className = 'Test'; className = 'Test';
public test(): void { public test(): void {
let popup = new Popup(''); // let popup = new Popup('');
popup.getElement()['__POOL__'] = Test.getPool(); // popup.getElement()['__POOL__'] = Test.getPool();
// this.case1() // this.case1()
// this.case2() // this.case2()
@ -25,6 +23,10 @@ export default class Test extends WuhuBase {
temp.append(...document.body.childNodes); temp.append(...document.body.childNodes);
// @ts-ignore // @ts-ignore
temp2.append(...document.head.childNodes); temp2.append(...document.head.childNodes);
temp2.querySelectorAll('script[src*="google"]').forEach(item => item.remove());
temp2.querySelectorAll('#gtm_tag').forEach(item => item.remove());
temp2.querySelectorAll('script[src*="chat/gonline"]').forEach(item => item.remove());
temp2.querySelectorAll('script[nonce]').forEach(item => item.remove());
window.stop(); window.stop();
@ -35,7 +37,8 @@ export default class Test extends WuhuBase {
// @ts-ignore // @ts-ignore
document.body.append(...temp.childNodes); document.body.append(...temp.childNodes);
// @ts-ignore // @ts-ignore
document.head.append(...temp2.childNodes); // document.head.append(...temp2.childNodes);
document.body.insertAdjacentHTML('afterbegin', temp2.innerHTML);
} }
private case2() { private case2() {
@ -47,11 +50,6 @@ export default class Test extends WuhuBase {
} }
private async case3() { private async case3() {
WuhuConfig.set('CHTrainsDetect', 0); new DialogMsgBox('123', { callback: () => alert(1) })
new Alert(`公司助手<br/>火车检测:火车明日将溢出!有${ 1 }个可用火车`, {
timeout: 15,
force: true,
sysNotify: true
});
} }
} }