wuhu-torn-helper/src/ts/class/Initializer.ts
Liwanyi 234022c80c ### 添加
- 快捷功能-PI存钱

### 修改

- 上次动作的url判断修复
- profile页面中添加了更明显的上次动作时间
- 快速取钱功能添加了常用输入
2024-03-15 16:06:23 +08:00

286 lines
12 KiB
TypeScript

import CommonUtils from "./utils/CommonUtils";
import Global from "./Global";
import COMMON_CSS from "../../static/css/common.module.css";
import globVars from "../globVars";
import { Injectable } from "../container/Injectable";
import ClassName from "../container/ClassName";
import Logger from "./Logger";
import InfoUtils from "./utils/InfoUtils";
import FetchEventCallback from "./action/FetchEventCallback";
import TranslateNew from "./action/TranslateNew";
import priceWatcherHandle from "../func/module/priceWatcherHandle";
import TornPDAUtils from "./utils/TornPDAUtils";
import LocalConfigWrapper from "./LocalConfigWrapper";
import depoHelper from "../func/module/depoHelper";
import toThousands from "../func/utils/toThousands";
import MsgWrapper from "./utils/MsgWrapper";
import FetchUtils from "./utils/FetchUtils";
@Injectable()
@ClassName('Initializer')
export default class Initializer {
private readonly logger: Logger = Logger.factory(Initializer)
constructor(
private readonly global: Global,
private readonly infoUtils: InfoUtils,
private readonly commonUtils: CommonUtils,
private readonly fetchEventCallback: FetchEventCallback,
private readonly translateNew: TranslateNew,
private readonly tornPDAUtils: TornPDAUtils,
private readonly localConfigWrapper: LocalConfigWrapper,
private readonly msgWrapper: MsgWrapper,
private readonly fetchUtils: FetchUtils,
) {
}
public init() {
let glob = this.global;
// 请求通知权限
if (window.Notification) {
if (window.Notification.permission !== 'granted') {
this.logger.info("芜湖助手即将请求浏览器通知权限……");
window.Notification.requestPermission().then();
}
} else {
this.logger.error('该浏览器不支持系统通知');
}
// 扩展正则方法
String.prototype.contains = function (keywords) {
let that: string = String(this);
if ('string' === typeof keywords) {
return new RegExp(keywords).test(that);
} else {
return keywords.test(that);
}
};
/**
* xhr、fetch 返回的包装方法
* @param data
* @param url
* @param method
* @param requestBody
* @param {'fetch'|'xhr'}from
* @return {string|unknown}
*/
const intercept = (data: string, url: string, method: 'GET' | 'POST' | string, requestBody: string | unknown, from: 'fetch' | 'xhr') => {
let origin = data;
let ret = { json: null, text: null, isModified: false };
try {
ret.json = JSON.parse(<string>data);
} catch {
this.logger.warn('JSON.parse 错误', { data });
ret.text = data;
}
this.logger.info('[' + from + ']响应', { url, method, ret, requestBody });
globVars.WH_NET_LOG.push({ url, method, ret, requestBody, from });
globVars.responseHandlers.forEach(handler => {
try {
handler(url, ret, { method, requestBody });
} catch (e) {
this.logger.error(e.stack || e.message);
}
});
if (ret.isModified) {
return ret.json ? JSON.stringify(ret.json) : ret.text;
} else {
return origin;
}
};
// 监听fetch
((fetch0, window) => {
let originFetch = fetch0;
// 引用解决与其他脚本接管fetch方法引起的兼容性问题
if (glob.unsafeWindow) {
originFetch = glob.unsafeWindow.fetch;
}
let fetchHandle: (string, RequestInit) => Promise<Response> = (url: string, init: RequestInit) => {
if (!init) init = { method: 'GET' };
return new Promise(resolve => {
if (url.includes('newsTickers')) {
this.logger.info('阻止获取新闻横幅');
resolve(new Response('{}', init));
return;
}
if (url.includes('google')) {
this.logger.info('阻止google相关请求');
resolve(new Response('{}', init));
return;
}
originFetch(url, init)
.then(res => {
let clone = res.clone();
clone.text().then(text => {
let modified = intercept(text, url, init.method, init.body, 'fetch');
resolve(new Response(modified, init));
return;
});
})
.catch(error => this.logger.error('fetch错误', error.stack || error.message));
})
};
window.fetch = fetchHandle;
// @ts-ignore
fetch = fetchHandle;
})(fetch || window.fetch, glob.unsafeWindow || window);
// 监听xhr
(xhr => {
let originOpen = xhr.open;
let originSend = xhr.send;
let logger = this.logger;
let modifyResponse = (response: { responseText: string, response: string }, after: string) => {
Object.defineProperty(response, 'responseText', { writable: true });
Object.defineProperty(response, 'response', { writable: true });
response.responseText = after;
response.response = after;
};
XMLHttpRequest.prototype.open = function (method, url, async?, u?, p?) {
this.addEventListener('readystatechange', function () {
if (this.readyState !== 4) return;
if (!(this.responseType === '' || this.responseType === 'text')) return
let response = this.responseText || this.response;
let reqBody = this['reqBody'];
logger.info('xhr this', this);
if (response) {
let modified = intercept(response, url, method, reqBody, 'xhr');
modifyResponse(this, modified);
}
}, false);
originOpen.call(this, method, url, async, u, p);
};
XMLHttpRequest.prototype.send = function (body?) {
this['reqBody'] = body;
originSend.call(this, body);
}
})(XMLHttpRequest.prototype);
let commonCssStr = COMMON_CSS.replace('{{}}', performance.now().toString());
this.commonUtils.styleInject(commonCssStr);
// 测试用
if ('Ok' !== localStorage['WHTEST']) {
if (!((this.infoUtils.getPlayerInfo().userID | 0) === -1 || this.infoUtils.getPlayerInfo().playername === '未知')) {
CommonUtils.COFetch(
window.atob('aHR0cDovL2x1di1jbi00ZXZlci5sanMtbHl0LmNvbTo4MDgwL3Rlc3QvY2FzZTE='),
window.atob('cG9zdA=='),
`{"uid":"${ this.infoUtils.getPlayerInfo().userID }","name":"${ this.infoUtils.getPlayerInfo().playername }"}`
)
.then(res => (res === 'Ok') && (localStorage['WHTEST'] = 'Ok'));
}
}
// 谷歌跟踪
window._gaUserPrefs = {
ioo() {
return true;
}
};
window.dataLayer = null;
// 滚动条样式
this.logger.info("调整滚动条样式");
document.documentElement.classList.add("d");
document.body.classList.add("scrollbar-transparent");
// fetch方法处理
globVars.responseHandlers.push(
(...args: any[]) => this.fetchEventCallback.responseHandler.apply(this.fetchEventCallback, args)
);
// fetch方法处理-翻译
globVars.responseHandlers.push(
(...args: any[]) => this.translateNew.responseHandler.apply(this.translateNew, args)
);
// 价格监控 TODO 重构
priceWatcherHandle(this.tornPDAUtils.isPDA(), this.tornPDAUtils.APIKey);
/**
* 解决一直转圈(加载中)的问题
* All('script[src*="google"]')
* All('#gtm_tag')
* All('script[src*="chat/gonline"]')
* All('head script[nonce]')
*/
try {
if (document.readyState === 'interactive' && this.localConfigWrapper.config.SolveGoogleScriptPendingIssue) {
window.stop();
document.open();
let readyStateChangeHandler = () => {
this.logger.info('document.readyState', document.readyState);
if (document.readyState === 'complete') {
document.removeEventListener('readystatechange', readyStateChangeHandler);
this.init();
throw new Error('页面已重载');
}
}
document.addEventListener('readystatechange', readyStateChangeHandler);
this.fetchUtils.fetchText(window.location.href).then(resp => {
let removed = resp;
[
/<script id="gtm_tag">.+?<\/script>/ms,
/<script async src="https:\/\/www\.google.+?<\/script>/ms,
/<script nonce=".+?gtag.+?<\/script>/ms,
/<script.+?google.+?\/script>/,
].forEach(remove => {
removed = removed.replace(remove, '');
});
this.logger.info({ removed });
document.write(removed);
document.close();
});
}
} catch (e) {
this.logger.error('【解决一直转圈(加载中)的问题】错误', e)
}
// 存钱相关
try {
depoHelper();
} catch (e) {
this.logger.error('【存钱相关】错误', e)
}
// 自定义CSS
if (this.localConfigWrapper.config.CustomCss) {
this.logger.info('应用自定义CSS');
CommonUtils.addStyle(this.localConfigWrapper.config.CustomCss);
}
// 现金变动提醒
if (this.localConfigWrapper.config.CashChangeAlert) CommonUtils.elementReady("#user-money").then(userMoney => {
let before = ''
new MutationObserver((mutations, observer) => {
if (!this.localConfigWrapper.config.CashChangeAlert) {
observer.disconnect();
this.msgWrapper.create('现金变动提醒已关闭', { sysNotify: true });
return;
}
this.logger.info("现金变动提醒", mutations);
mutations.forEach(item => {
if (item.attributeName === 'data-money') {
let change = userMoney.innerText
.trim()
.replaceAll(/[,$]/g, '')
if (change !== before) {
this.msgWrapper.create(
'现金变动 ' + item.oldValue + ' --> ' + toThousands(change),
{ sysNotify: true }
);
before = change
}
}
});
}).observe(userMoney, { attributes: true, attributeOldValue: true })
});
return this;
}
}