From 39576c86badfbf1df893273909230bfa0fd1e737 Mon Sep 17 00:00:00 2001 From: Liwanyi Date: Wed, 19 Oct 2022 18:05:12 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.js | 9 ++- global.d.ts | 19 ++++--- src/class/Common.ts | 4 ++ src/class/Global.ts | 5 +- src/class/WuhuTornHelper.ts | 21 +++---- src/class/ZhongIcon.ts | 24 +++++++- src/class/action/CompanyHelper.ts | 61 +++++++++++++++++++++ src/class/utils/Alert.ts | 10 +++- src/class/utils/CommonUtils.ts | 14 +++++ src/class/utils/FetchUtils.ts | 14 +++++ src/func/utils/@deprecated/autoFetchJSON.ts | 51 ++++++++--------- src/interface/ISidebarData.ts | 33 ++++++++++- src/interface/IWHNotify.ts | 2 + src/test/Test.ts | 14 +++-- 14 files changed, 220 insertions(+), 61 deletions(-) create mode 100644 src/class/action/CompanyHelper.ts diff --git a/build.js b/build.js index b294394..e6a2369 100644 --- a/build.js +++ b/build.js @@ -7,9 +7,9 @@ let fs = require('fs'); let date = new Date(); let version = process.env.npm_package_version; -let formatedDateTime = `${ date.getFullYear() }${ ('0' + (date.getMonth() + 1)).slice(-2) }${ ('0' + date.getDate()).slice(-2) }${ ('0' + date.getHours()).slice(-2) }${ ('0' + date.getMinutes()).slice(-2) }`; +let formattedDateTime = `${ date.getFullYear() }${ ('0' + (date.getMonth() + 1)).slice(-2) }${ ('0' + date.getDate()).slice(-2) }${ ('0' + date.getHours()).slice(-2) }${ ('0' + date.getMinutes()).slice(-2) }`; let metaData = `// ==UserScript== -// @lastmodified ${ formatedDateTime } +// @lastmodified ${ formattedDateTime } // @name 芜湖助手 // @namespace WOOH // @version ${ version } @@ -20,7 +20,10 @@ let metaData = `// ==UserScript== // @grant unsafeWindow // @connect ljs-lyt.com // @connect yata.yt -// @connect * +// @connect github.io +// @connect gitlab.com +// @connect staticfile.org +// @connect gitee.com // ==/UserScript== ` diff --git a/global.d.ts b/global.d.ts index 21c0ba9..f596659 100644 --- a/global.d.ts +++ b/global.d.ts @@ -20,6 +20,15 @@ declare interface Window { Vue?: Function; /* 油猴脚本引擎自带 */ unsafeWindow?: Window & typeof globalThis; + + GM: any; + + GM_xmlhttpRequest(init: GM_RequestParams): void; + + GM_getValue(k: string, def: any): unknown; + + GM_setValue(k: string, v: any): void; + // google不跟踪标识 _gaUserPrefs?: unknown; dataLayer?: unknown; @@ -44,12 +53,6 @@ declare interface Window { PDA_httpPost(url: URL | string, init: any, body: any): Promise; - GM_xmlhttpRequest(init: GM_RequestParams): void; - - GM_getValue(k: string, def: any): unknown; - - GM_setValue(k: string, v: any): void; - // TODO 临时测试用 // [key: string]: unknown; } @@ -109,4 +112,6 @@ declare module "*.html" { declare module "*.css" { const value: string; export default value; -} \ No newline at end of file +} + +declare function GM_xmlhttpRequest(init: any): void; \ No newline at end of file diff --git a/src/class/Common.ts b/src/class/Common.ts index 86d5ccb..dc1e751 100644 --- a/src/class/Common.ts +++ b/src/class/Common.ts @@ -5,6 +5,7 @@ import priceWatcherHandle from "../func/module/priceWatcherHandle"; import WuhuBase from "./WuhuBase"; import WuhuConfig from "./WuhuConfig"; import CommonUtils from "./utils/CommonUtils"; +import CompanyHelper from "./action/CompanyHelper"; export class Common extends WuhuBase { className = 'Common'; @@ -79,5 +80,8 @@ export class Common extends WuhuBase { // 战斗相关 attackHelper().then(); + + // 公司助手 + CompanyHelper.getInstance(); } } \ No newline at end of file diff --git a/src/class/Global.ts b/src/class/Global.ts index e06c5eb..306f23c 100644 --- a/src/class/Global.ts +++ b/src/class/Global.ts @@ -43,11 +43,10 @@ export default class Global extends WuhuBase implements IGlobal { } = null; constructor() { - Log.info('WH脚本参数初始化'); + Log.info('WH脚本参数[Global]初始化'); super(); - // this.window = window; this.unsafeWindow = window.unsafeWindow || null; - this.GM_xmlhttpRequest = window.GM_xmlhttpRequest || null; + this.GM_xmlhttpRequest = window.GM_xmlhttpRequest || GM_xmlhttpRequest || null; this.version = '$$WUHU_DEV_VERSION$$'; this.PDA_APIKey = '###PDA-APIKEY###'; this.isPDA = !this.PDA_APIKey.includes('###'); diff --git a/src/class/WuhuTornHelper.ts b/src/class/WuhuTornHelper.ts index ccb3ccc..759d365 100644 --- a/src/class/WuhuTornHelper.ts +++ b/src/class/WuhuTornHelper.ts @@ -53,15 +53,17 @@ export default class WuHuTornHelper extends WuhuBase { resolve(new Response('{}')); return; } - ori_fetch(url, init).then(res => { - // mini profile 翻译 - if (url.includes('profiles.php?step=getUserNameContextMenu') && WuhuConfig.get('transEnable')) { - window.setTimeout(() => miniprofTrans(), 200); - } - let clone = res.clone(); - res.text().then(text => Log.info('FETCH响应,耗时' + ((performance.now() - startTime) | 0) + 'ms', { response: text })); - resolve(clone); - }); + ori_fetch(url, init) + .then(res => { + // mini profile 翻译 + if (url.includes('profiles.php?step=getUserNameContextMenu') && WuhuConfig.get('transEnable')) { + window.setTimeout(() => miniprofTrans(), 200); + } + let clone = res.clone(); + res.text().then(text => Log.info('FETCH响应,耗时' + ((performance.now() - startTime) | 0) + 'ms', { response: text })); + resolve(clone); + }) + .catch(error => Log.error('监听到fetch获取错误', error)); }) }; @@ -86,7 +88,6 @@ export default class WuHuTornHelper extends WuhuBase { return true; } }; - window.dataLayer = null; Log.info('WuHuTornHelper初始化结束'); diff --git a/src/class/ZhongIcon.ts b/src/class/ZhongIcon.ts index 60a34f6..a517afd 100644 --- a/src/class/ZhongIcon.ts +++ b/src/class/ZhongIcon.ts @@ -29,6 +29,7 @@ import Test from "../test/Test"; import TornStyleSwitch from "./utils/TornStyleSwitch"; import Global from "./Global"; import BuyBeerHelper from "./action/BuyBeerHelper"; +import Timer from "./utils/Timer"; export default class ZhongIcon extends WuhuBase { className = 'ZhongIcon'; @@ -43,7 +44,6 @@ export default class ZhongIcon extends WuhuBase { .constructWuhuSettingList() .constructMenuList() .insert2Dom(); - Log.info('设置图标结束, ZhongIcon初始化结束'); } @@ -130,6 +130,7 @@ export default class ZhongIcon extends WuhuBase { const menu_cont = zhong_node.querySelector('#wh-gSettings'); // 遍历菜单node设置、生成node、插入dom this.menuItemList.forEach(setting => this.elemGenerator(setting, menu_cont)); + Log.info('生成元素插入完成'); // 计时node zhong_node.initTimer = zhong_node.querySelector('#wh-inittimer'); // 芜湖助手图标点击事件 @@ -199,14 +200,29 @@ export default class ZhongIcon extends WuhuBase { : el.addEventListener('click', null)); document.body.append(zhong_node); // 引入torn自带浮动提示 + Log.info('引入torn自带浮动提示'); (window.initializeTooltip) && (window.initializeTooltip('.wh-container', 'white-tooltip')); // 加载torn mini profile - initMiniProf('#wh-trans-icon'); + Log.info('加载torn mini profile'); + let miniProfileInterval = { + id: window.setInterval(() => { + miniProfileInterval.counter++; + if (window.$ || (window.unsafeWindow && window.unsafeWindow.$)) { + initMiniProf('#wh-trans-icon'); + window.clearInterval(miniProfileInterval.id); + } + if (miniProfileInterval.counter > 30) window.clearInterval(miniProfileInterval.id); + }, 1000), + counter: 0 + }; ZhongIcon.ZhongNode = zhong_node; + Log.info('图标加入文档树完成'); } // 菜单 private constructMenuList(): ZhongIcon { + Log.info('构造展开菜单列表开始'); + let timer = new Timer(); let glob = Global.getInstance(); const date = new Date(); @@ -778,11 +794,14 @@ export default class ZhongIcon extends WuhuBase { }); this.menuItemList = list; + Log.info('构造展开菜单列表结束' + timer.getTimeMs()); return this; } // 设置 private constructWuhuSettingList(): ZhongIcon { + Log.info('构造设置列表开始'); + let timer = new Timer(); const date = new Date(); let beer = BuyBeerHelper.getInstance(); @@ -1220,6 +1239,7 @@ export default class ZhongIcon extends WuhuBase { }); this.settingItemList = list; + Log.info('构造设置列表结束' + timer.getTimeMs()); return this; } diff --git a/src/class/action/CompanyHelper.ts b/src/class/action/CompanyHelper.ts new file mode 100644 index 0000000..0e8df6d --- /dev/null +++ b/src/class/action/CompanyHelper.ts @@ -0,0 +1,61 @@ +import WuhuBase from "../WuhuBase"; +import WuhuConfig from "../WuhuConfig"; +import Log from "../Log"; +import CommonUtils from "../utils/CommonUtils"; +import FetchUtils from "../utils/FetchUtils"; +import InfoUtils from "../utils/InfoUtils"; +import Alert from "../utils/Alert"; + +/** + * 公司助手 + */ +export default class CompanyHelper extends WuhuBase { + className = 'CompanyHelper'; + + public constructor() { + super(); + this.trainsDetect().then(); + } + + /** + * 火车检测 + * 每日判断一次,非公司老板跳过检测 + * TODO 优化、URL判断 + * @private + */ + private async trainsDetect(): Promise { + // 通过用户的icon判断公司老板 + if ((await InfoUtils.getInstance().getSessionData()).statusIcons.icons.company.iconID !== 'icon73') { + Log.info('火车检测跳过:非公司老板'); + return; + } + // 上次检测时间戳 + let lastDetect: number = WuhuConfig.get('CHTrainsDetect') || 0; + // 检测是否过了一天 + if (CommonUtils.getInstance().isNewDay(lastDetect)) { + WuhuConfig.set('CHTrainsDetect', Date.now()); + FetchUtils.getInstance().fetchText('/companies.php') + .then(res => { + let tmp: HTMLElement = document.createElement('div'); + // TODO 未去除body标签 + tmp.innerHTML = res.split('')[1].replace('', '').trim(); + let trains: number = parseInt(tmp.querySelector('span.trains').innerText); + let stars: number = tmp.querySelectorAll('.company-rating .active').length / 2 || 1; + Log.info('火车/星级: ' + trains + '/' + stars); + if (trains + stars > 20) { + new Alert(`公司助手

火车检测:火车明日将溢出!${ trains }/20火车`, { + timeout: 15, + force: true, + sysNotify: true + }); + } + }) + .catch(error => { + Log.error('火车检测出错', error); + WuhuConfig.set('CHTrainsDetect', 0); + }); + } else { + Log.info('火车检测:今日已提醒,跳过'); + } + } +} \ No newline at end of file diff --git a/src/class/utils/Alert.ts b/src/class/utils/Alert.ts index 1c95600..eeda10f 100644 --- a/src/class/utils/Alert.ts +++ b/src/class/utils/Alert.ts @@ -17,12 +17,16 @@ export default class Alert extends WuhuBase { public constructor(msg: string, options: IWHNotify = {}) { super(); - let { timeout, callback, sysNotify, } = options; + let { timeout, callback, sysNotify, force } = options; // 后台窗口、iframe内判断 if (!WindowActiveState.getInstance().get() || (self !== top)) { - Log.warn('后台通知已被屏蔽'); - return null; + if (!force) { + Log.warn('后台通知已被屏蔽'); + return null; + } else { + Log.info('强制后台通知'); + } } // 通知的容器 diff --git a/src/class/utils/CommonUtils.ts b/src/class/utils/CommonUtils.ts index f97a731..88c610c 100644 --- a/src/class/utils/CommonUtils.ts +++ b/src/class/utils/CommonUtils.ts @@ -204,4 +204,18 @@ export default class CommonUtils extends WuhuBase { .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; + } } \ No newline at end of file diff --git a/src/class/utils/FetchUtils.ts b/src/class/utils/FetchUtils.ts index aa2e8a9..a290a57 100644 --- a/src/class/utils/FetchUtils.ts +++ b/src/class/utils/FetchUtils.ts @@ -1,7 +1,9 @@ import WuhuBase from "../WuhuBase"; +import Log from "../Log"; export default class FetchUtils extends WuhuBase { className = 'FetchUtils'; + /** * 包装jquery ajax 异步返回string * @param url @@ -21,4 +23,16 @@ export default class FetchUtils extends WuhuBase { }); }); } + + public fetchText(url: string, init: RequestInit = null): Promise { + return new Promise((resolve, reject) => + window.fetch(url, init) + .then(res => res.text()) + .then(t => resolve(t)) + .catch(err => { + Log.error('fetchText出错了', err); + reject(err); + }) + ); + } } \ No newline at end of file diff --git a/src/func/utils/@deprecated/autoFetchJSON.ts b/src/func/utils/@deprecated/autoFetchJSON.ts index c76268f..1cf8917 100644 --- a/src/func/utils/@deprecated/autoFetchJSON.ts +++ b/src/func/utils/@deprecated/autoFetchJSON.ts @@ -1,27 +1,24 @@ -import CommonUtils from "../../../class/utils/CommonUtils"; -import WindowActiveState from "../../../class/action/WindowActiveState"; - -/** - * 循环获取json对象 - * @deprecated - * @param dest - * @param time - */ -function autoFetchJSON(dest, time = 30) { - let obj; - const res = CommonUtils.COFetch(dest); - setInterval(async () => { - if (!WindowActiveState.getInstance().get()) return; - const res = await CommonUtils.COFetch(dest); - obj = JSON.parse(res); - }, time * 1000); - return { - get: async function () { - if (!obj) { - const str = await res - return obj = JSON.parse(str); - } - return obj; - } - }; -} \ No newline at end of file +// import CommonUtils from "../../../class/utils/CommonUtils"; +// import WindowActiveState from "../../../class/action/WindowActiveState"; +// +// /** +// * @deprecated +// */ +// function autoFetchJSON(dest, time = 30) { +// let obj; +// const res = CommonUtils.COFetch(dest); +// setInterval(async () => { +// if (!WindowActiveState.getInstance().get()) return; +// const res = await CommonUtils.COFetch(dest); +// obj = JSON.parse(res); +// }, time * 1000); +// return { +// get: async function () { +// if (!obj) { +// const str = await res +// return obj = JSON.parse(str); +// } +// return obj; +// } +// }; +// } \ No newline at end of file diff --git a/src/interface/ISidebarData.ts b/src/interface/ISidebarData.ts index ac2b546..5089b8c 100644 --- a/src/interface/ISidebarData.ts +++ b/src/interface/ISidebarData.ts @@ -1,6 +1,6 @@ export default interface ISidebarData { // TODO 补全 - statusIcons?: unknown; + statusIcons?: StatusIcons; user?: { userID: number, name: string, @@ -105,4 +105,35 @@ interface Link { "link": string, "icon": string, "inNewTab": boolean +} + +interface StatusIcons { + "visible": boolean, + "icons": { + "enbyGender": Icon, + "donator": Icon, + "married": Icon, + "company": Icon, + "faction": Icon, + "education": Icon, + "bazaar": Icon, + "stock_market": Icon, + "drug_cooldown": Icon, + "drug_addiction": Icon, + "travelling": Icon, + // 未收录图标 + [key: string]: Icon, + }, + "size": "big svg" | string, + "onTop": boolean +} + +interface Icon { + "iconID": string, + "title": string, + "subtitle"?: string, + "link"?: string, + "serverTimestamp"?: number, + "timerExpiresAt"?: number, + "isShortFormatTimer"?: boolean } \ No newline at end of file diff --git a/src/interface/IWHNotify.ts b/src/interface/IWHNotify.ts index ac1a03a..2bf6e24 100644 --- a/src/interface/IWHNotify.ts +++ b/src/interface/IWHNotify.ts @@ -5,4 +5,6 @@ export default interface IWHNotify { sysNotify?: boolean; sysNotifyTag?: string; sysNotifyClick?: Function; + // 强制后台也通知 + force?: boolean; } \ No newline at end of file diff --git a/src/test/Test.ts b/src/test/Test.ts index 8251178..e2e4ff9 100644 --- a/src/test/Test.ts +++ b/src/test/Test.ts @@ -1,9 +1,12 @@ import WuhuBase from "../class/WuhuBase"; import Log from "../class/Log"; import Popup from "../class/utils/Popup"; +import WuhuConfig from "../class/WuhuConfig"; +import Alert from "../class/utils/Alert"; export default class Test extends WuhuBase { className = 'Test'; + public test(): void { let popup = new Popup(''); popup.getElement()['__POOL__'] = Test.getPool(); @@ -44,10 +47,11 @@ export default class Test extends WuhuBase { } private async case3() { - Log.info('window.addRFC', typeof window.addRFC); - Log.info('window.getAction', typeof window.getAction); - Log.info('window.initializeTooltip', typeof window.initializeTooltip); - Log.info('window.renderMiniProfile', typeof window.renderMiniProfile); - // 12 + WuhuConfig.set('CHTrainsDetect', 0); + new Alert(`公司助手
火车检测:火车明日将溢出!有${ 1 }个可用火车`, { + timeout: 15, + force: true, + sysNotify: true + }); } } \ No newline at end of file