221 lines
9.1 KiB
TypeScript
221 lines
9.1 KiB
TypeScript
import UserScriptEngine from "../../enum/UserScriptEngine";
|
||
import WuhuBase from "../WuhuBase";
|
||
import Log from "../Log";
|
||
import Device from "../../enum/Device";
|
||
import AjaxFetchOption from "../../interface/AjaxFetchOption";
|
||
import Alert from "./Alert";
|
||
import LOADING_IMG_HTML from "../../static/html/loading_img.html";
|
||
import Timer from "./Timer";
|
||
|
||
export default class CommonUtils extends WuhuBase {
|
||
className = 'CommonUtils';
|
||
|
||
static getScriptEngine() {
|
||
let glob = CommonUtils.glob;
|
||
return glob.GM_xmlhttpRequest ? UserScriptEngine.GM : glob.isPDA
|
||
? UserScriptEngine.PDA : UserScriptEngine.RAW;
|
||
}
|
||
|
||
static COFetch(url: URL | string, method: 'get' | 'post' = 'get', body: any = null): Promise<string> {
|
||
const engine = this.getScriptEngine();
|
||
let start = performance.now();
|
||
Log.info('跨域获取数据开始, 脚本引擎: ' + engine);
|
||
return new Promise<string>((resolve, reject) => {
|
||
switch (engine) {
|
||
case UserScriptEngine.RAW: {
|
||
Log.error(`跨域请求错误:${ UserScriptEngine.RAW }环境下无法进行跨域请求`);
|
||
reject(`错误:${ UserScriptEngine.RAW }环境下无法进行跨域请求`);
|
||
break;
|
||
}
|
||
case UserScriptEngine.PDA: {
|
||
const { PDA_httpGet, PDA_httpPost } = window;
|
||
// get
|
||
if (method === 'get') {
|
||
if (typeof PDA_httpGet !== 'function') {
|
||
Log.error('COFetch网络错误:PDA版本不支持');
|
||
reject('COFetch网络错误:PDA版本不支持');
|
||
}
|
||
PDA_httpGet(url)
|
||
.then(res => {
|
||
Log.info('跨域获取数据成功, 耗时' + (performance.now() - start | 0) + 'ms');
|
||
resolve(res.responseText);
|
||
})
|
||
.catch(e => {
|
||
Log.error('COFetch网络错误', e);
|
||
reject(`COFetch网络错误 ${ e }`);
|
||
})
|
||
}
|
||
// post
|
||
else {
|
||
if (typeof PDA_httpPost !== 'function') {
|
||
Log.error('COFetch网络错误:PDA版本不支持');
|
||
reject('COFetch网络错误:PDA版本不支持');
|
||
}
|
||
PDA_httpPost(url, { 'content-type': 'application/json' }, body)
|
||
.then(res => resolve(res.responseText))
|
||
.catch(e => {
|
||
Log.error('COFetch网络错误', e);
|
||
reject(`COFetch网络错误 ${ e }`);
|
||
});
|
||
}
|
||
break;
|
||
}
|
||
case UserScriptEngine.GM: {
|
||
let { GM_xmlhttpRequest } = CommonUtils.glob;
|
||
if (typeof GM_xmlhttpRequest !== 'function') {
|
||
Log.error('COFetch网络错误:用户脚本扩展API错误');
|
||
reject('错误:用户脚本扩展API错误');
|
||
}
|
||
GM_xmlhttpRequest({
|
||
method: method,
|
||
url: url,
|
||
data: method === 'get' ? null : body,
|
||
headers: method === 'get' ? null : { 'content-type': 'application/json' },
|
||
onload: res => {
|
||
Log.info('跨域获取数据成功,耗时' + (performance.now() - start | 0) + 'ms');
|
||
resolve(res.response);
|
||
},
|
||
onerror: res => reject(`连接错误 ${ JSON.stringify(res) }`),
|
||
ontimeout: res => reject(`连接超时 ${ JSON.stringify(res) }`),
|
||
});
|
||
}
|
||
}
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 返回玩家信息的对象 { playername: string, userID: number }
|
||
* @return {PlayerInfo} rs
|
||
*/
|
||
static getPlayerInfo(): PlayerInfo {
|
||
const node = document.querySelector('script[uid]');
|
||
if (node) {
|
||
return {
|
||
playername: node.getAttribute('name'),
|
||
userID: node.getAttribute('uid') as unknown as number,
|
||
}
|
||
} else {
|
||
new Alert('严重错误:芜湖助手无法获取用户数据,已退出');
|
||
throw '芜湖助手无法获取用户数据';
|
||
}
|
||
}
|
||
|
||
// 用户设备类型 对应PC MOBILE TABLET
|
||
public static getDeviceType(): Device {
|
||
return window.innerWidth >= 1000
|
||
? Device.PC : window.innerWidth <= 600 ? Device.MOBILE : Device.TABLET;
|
||
}
|
||
|
||
public static 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 '无效'
|
||
}
|
||
}
|
||
|
||
public static ajaxFetch(opt: AjaxFetchOption) {
|
||
let { url, referrer = '/', method, body = null } = opt;
|
||
let req_params: RequestInit = {
|
||
headers: { 'X-Requested-With': 'XMLHttpRequest' },
|
||
referrer,
|
||
method,
|
||
};
|
||
if (method === 'POST') {
|
||
req_params.headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
|
||
req_params.body = body;
|
||
}
|
||
return window.fetch(url, req_params);
|
||
}
|
||
|
||
/**
|
||
* 通过 mutation.observe 方法异步返回元素
|
||
* @param {String} selectors - CSS规则的HTML元素选择器
|
||
* @param {Document} content - 上下文
|
||
* @param {number} timeout - 超时毫秒数
|
||
* @returns {Promise<HTMLElement|null>}
|
||
*/
|
||
public static elementReady(selectors: string, content: Document = document, timeout: number = 30000): Promise<HTMLElement> {
|
||
Log.info('等待元素:' + selectors);
|
||
let timer = new Timer();
|
||
return new Promise((resolve, reject) => {
|
||
let el = content.querySelector(selectors) as HTMLElement;
|
||
if (el) {
|
||
Log.info('已获取元素, 耗时' + timer.getTimeMs(), el);
|
||
resolve(el);
|
||
return;
|
||
}
|
||
let observer = new MutationObserver((_, observer) => {
|
||
content.querySelectorAll(selectors).forEach((element) => {
|
||
Log.info({ innerHTML: element.innerHTML, element });
|
||
observer.disconnect();
|
||
Log.info('已获取元素, 耗时' + timer.getTimeMs(), element);
|
||
resolve(element as HTMLElement);
|
||
});
|
||
});
|
||
setTimeout(() => {
|
||
observer.disconnect();
|
||
Log.error(`等待元素超时! [${ selectors }]\n${ content.documentElement.tagName }, 耗时` + timer.getTimeMs());
|
||
reject(`等待元素超时! [${ selectors }]\n${ content.documentElement.tagName }, 耗时` + timer.getTimeMs());
|
||
}, timeout);
|
||
observer.observe(content.documentElement, { childList: true, subtree: true });
|
||
});
|
||
}
|
||
|
||
public static querySelector(selectors: string, content: Document = document, timeout: number = 30000): Promise<HTMLElement> {
|
||
return CommonUtils.elementReady(selectors, content, timeout);
|
||
}
|
||
|
||
public static addStyle(rules: string): void {
|
||
let element = document.querySelector('style#wh-trans-gStyle');
|
||
if (element) {
|
||
element.innerHTML += rules;
|
||
} else {
|
||
element = document.createElement("style");
|
||
element.id = 'wh-trans-gStyle';
|
||
element.innerHTML = rules;
|
||
document.head.appendChild(element);
|
||
}
|
||
Log.info('CSS规则已添加', element);
|
||
}
|
||
|
||
public static loading_gif_html(): string {
|
||
return LOADING_IMG_HTML;
|
||
}
|
||
|
||
/**
|
||
* 播放音频
|
||
* @param {string} url 播放的音频URL
|
||
* @returns {undefined}
|
||
*/
|
||
public audioPlay(url: string = 'https://www.torn.com/js/chat/sounds/Warble_1.mp3') {
|
||
const audio = new Audio(url);
|
||
audio.addEventListener("canplaythrough", () => {
|
||
audio.play()
|
||
.catch(err => Log.error(err))
|
||
.then();
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 与给定日期对比,现在是否是新的一天
|
||
* @param target
|
||
*/
|
||
public isNewDay(target: number | Date): boolean {
|
||
let tar: Date = typeof target === "number" ? new Date(target) : target;
|
||
let nowUtc: Date = new Date();
|
||
nowUtc.setHours(8);
|
||
nowUtc.setMinutes(0);
|
||
nowUtc.setSeconds(0);
|
||
nowUtc.setMilliseconds(0);
|
||
return nowUtc > tar;
|
||
}
|
||
} |