From dd411a65fcd5cdfa90d14701f26dca08ba46f844 Mon Sep 17 00:00:00 2001 From: Liwanyi Date: Sun, 9 Oct 2022 11:06:35 +0800 Subject: [PATCH] =?UTF-8?q?TS=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/class/Global.ts | 23 +--- src/class/UrlMatch.ts | 2 +- src/class/ZhongIcon.ts | 14 +-- src/class/action/BuyBeerHelper.ts | 108 ++++++++++++++++++ src/class/action/TravelItem.ts | 6 +- src/class/utils/Alert.ts | 20 ++-- src/func/utils/{ => @deprecated}/BuyBeer.ts | 16 +-- .../utils/{ => @deprecated}/autoFetchJSON.ts | 7 +- src/func/utils/WHNotify.ts | 5 +- src/interface/IGlobal.ts | 4 +- src/interface/IWHNotify.ts | 1 + src/static/html/buyBeer/notify.html | 5 + src/static/html/notify.html | 5 + 13 files changed, 157 insertions(+), 59 deletions(-) create mode 100644 src/class/action/BuyBeerHelper.ts rename src/func/utils/{ => @deprecated}/BuyBeer.ts (92%) rename src/func/utils/{ => @deprecated}/autoFetchJSON.ts (70%) create mode 100644 src/static/html/buyBeer/notify.html create mode 100644 src/static/html/notify.html diff --git a/src/class/Global.ts b/src/class/Global.ts index 7e68f5b..2c4abcf 100644 --- a/src/class/Global.ts +++ b/src/class/Global.ts @@ -1,10 +1,9 @@ -import BuyBeer, { BeerMonitorLoop } from "../func/utils/BuyBeer"; import Device from "../enum/Device"; -import WindowActiveState from "./action/WindowActiveState"; import WuhuBase from "./WuhuBase"; import IGlobal from "../interface/IGlobal"; import Log from "./Log"; import InfoUtils from "./utils/InfoUtils"; +import BuyBeerHelper from "./action/BuyBeerHelper"; export default class Global extends WuhuBase implements IGlobal { GM_xmlhttpRequest: Function = null; @@ -13,11 +12,9 @@ export default class Global extends WuhuBase implements IGlobal { // 弹窗 popup_node: MyHTMLElement = null; // 啤酒助手 - beer: BeerMonitorLoop = null; + beer = null; // 留存的通知 notifies: NotifyWrapper = null; - // 价格监控 - // priceWatcher?: { status: boolean }; // 海外库存 fStock: { get: () => Promise } = null; // 玩家名和数字id @@ -42,10 +39,6 @@ export default class Global extends WuhuBase implements IGlobal { // [key: string]: string; } = null; - // 窗口活动状态 - // isWindowActive = null; - isWindowActive = WindowActiveState.getInstance(); - constructor() { Log.info('WH脚本参数初始化'); super(); @@ -57,17 +50,14 @@ export default class Global extends WuhuBase implements IGlobal { this.isPDA = !this.PDA_APIKey.includes('###'); this.device = window.innerWidth >= 1000 ? Device.PC : window.innerWidth <= 600 ? Device.MOBILE : Device.TABLET; this.player_info = InfoUtils.getInstance().getPlayerInfo(); - this.beer = BuyBeer(); + this.beer = BuyBeerHelper.getInstance(); this.popup_node = null; this.notifies = { count: 0 }; - // this.isWindowActive = WindowActiveState.getInstance(); this.href = window.location.href; this.bodyAttrs = {}; if (this.unsafeWindow) { try { - window.whtest = '原window'; - this.unsafeWindow.whtest = 'unsafeWindow'; window = this.unsafeWindow || this.window; Log.info('替换window上下文'); } catch { @@ -95,11 +85,4 @@ export default class Global extends WuhuBase implements IGlobal { Log.info('WH脚本参数初始化结束'); } - - // static getInstance(this): Global { - // if (!this.instance) { - // this.instance = new this(); - // } - // return this.instance; - // } } \ No newline at end of file diff --git a/src/class/UrlMatch.ts b/src/class/UrlMatch.ts index a228d50..f54f06d 100644 --- a/src/class/UrlMatch.ts +++ b/src/class/UrlMatch.ts @@ -97,7 +97,7 @@ export default class UrlPattern extends WuhuBase { let { data } = settings, { responseText } = xhr; let response = JSON.parse(responseText); if (data.includes('step=buyShopItem') && data.includes('ID=180') && response['success']) { - new Alert('已检测成功购买啤酒') + new Alert('已检测成功购买啤酒'); beer.skip_today(); } }); diff --git a/src/class/ZhongIcon.ts b/src/class/ZhongIcon.ts index b5499bf..d3e1cd8 100644 --- a/src/class/ZhongIcon.ts +++ b/src/class/ZhongIcon.ts @@ -19,7 +19,6 @@ import QUICK_FLY_HTML from "../static/html/quick_fly.html"; import NNB_INFO_HTML from "../static/html/nnb_info.html"; import PRICE_WATCHER_HTML from "../static/html/price_watcher.html"; import DANGER_ZONE_HTML from "../static/html/danger_zone.html"; -import ActionButtonUtils from "./utils/ActionButtonUtils"; import ZHONG_MENU_HTML from "../static/html/zhong/zhong_menu.html"; import ZHONG_UPDATE_HTML from "../static/html/zhong/zhong_update.html"; import ZHONG_LOOT_HTML from "../static/html/zhong/zhong_loot.html"; @@ -27,6 +26,7 @@ import QUICK_CRIMES_HTML from "../static/html/quick_crimes.html"; import DEV_DETAILS_HTML from "../static/html/zhong/setting/dev_details.html"; import QUICK_FLY_CSS from "../static/css/quick_fly.css"; import QUICK_LINK_CSS from "../static/css/quick_link.css"; +import BuyBeerHelper from "./action/BuyBeerHelper"; export default class ZhongIcon extends WuhuBase { public static ZhongNode: MyHTMLElement = null; @@ -765,9 +765,10 @@ export default class ZhongIcon extends WuhuBase { clickFunc: async function () { Log.info('测试开始'); - new Popup('').getElement() - .querySelector('button').onclick = () => new Alert('123'); - ActionButtonUtils.getInstance().add('123'); + let helper = BuyBeerHelper.getInstance(); + helper.start(); + Log.info('is_running', helper.is_running()); + helper.skip_today(); Log.info('测试结束'); }, @@ -1038,10 +1039,9 @@ export default class ZhongIcon extends WuhuBase { if (num < 1 || num > 60) num = 50; input.value = num.toString(); WuhuConfig.set('_15AlarmTime', num); - // 之前的运行状态 - let before_state = beer.is_running(); beer.set_time(num); - if (before_state) beer.start(); + // 之前的运行状态 + if (beer.is_running()) beer.start(); popup.close(); }); popup.getElement().appendChild(confirm); diff --git a/src/class/action/BuyBeerHelper.ts b/src/class/action/BuyBeerHelper.ts new file mode 100644 index 0000000..8958220 --- /dev/null +++ b/src/class/action/BuyBeerHelper.ts @@ -0,0 +1,108 @@ +import WuhuBase from "../WuhuBase"; +import WuhuConfig from "../WuhuConfig"; +import Log from "../Log"; +import InfoUtils from "../utils/InfoUtils"; +import Alert from "../utils/Alert"; +import audioPlay from "../../func/utils/audioPlay"; +import MathUtils from "../utils/MathUtils"; +import NOTIFY_HTML from "../../static/html/buyBeer/notify.html"; + +export default class BuyBeerHelper extends WuhuBase implements BeerMonitorLoop { + + private isNotifying = false; + private loopId: number = null; + private time: number; + private readonly notifyHtml: string = NOTIFY_HTML.replace('{{}}', MathUtils.getInstance().getRandomInt(0, 99).toString()); + + public constructor() { + super(); + this.time = WuhuConfig.get('_15AlarmTime') || 30; + } + + public start(): void { + if (this.loopId) { + Log.info('啤酒助手已在运行'); + } else { + this.loopId = window.setInterval(async () => { + // 海外取消提醒 + let { isTravelling, isAbroad } = await InfoUtils.getInstance().getUserState(); + if (isTravelling || isAbroad) { + this.stop(); + return; + } + let dt = new Date(); + // 已选当天不提醒 + const now = [dt.getUTCFullYear(), dt.getUTCMonth(), dt.getUTCDate()]; + const ignore_date = WuhuConfig.get('_15_alarm_ignore') || '{}'; + if (JSON.stringify(now) === JSON.stringify(ignore_date)) return; + // 正常提醒 + let m = 14 - (dt.getMinutes() % 15); + let s = 60 - dt.getSeconds(); + if (m === 0 && s < this.time) { + // 如从通知点开,则本次通知跳过 + if (location.href.includes('clickfromnotify')) { + this.isNotifying = true; + location.hash = ''; + return; + } + // 本次已通知 + if (this.isNotifying) return; + this.isNotifying = true; + // 发送通知 + const notify = new Alert(this.notifyHtml, { + timeout: 30, + sysNotify: true, + }); + notify.getElement().querySelector('.wh-notify-msg button').addEventListener('click', () => this.skip_today()); + notify.getElement().addEventListener('click', ev => { + if ((ev.target as HTMLElement).tagName.toLowerCase() === 'a') { + notify.close(); + } + }); + window.setTimeout(audioPlay, 800); + window.setTimeout(audioPlay, 800 * 2); + window.setTimeout(audioPlay, 800 * 3); + } else { + this.isNotifying = false; + } + }, 1000); + } + } + + public stop(): void { + if (this.loopId) { + window.clearInterval(this.loopId); + this.loopId = null; + } + } + + public set_time(t: number): void { + this.time = t; + } + + public status(): '已启动' | '未启动' { + return this.loopId ? '已启动' : '未启动'; + } + + public is_running(): boolean { + return this.loopId !== null; + } + + public skip_today(): void { + const date = new Date(); + WuhuConfig.set('_15_alarm_ignore', [date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()], false); + // 通知 + const notify = new Alert(`明早8点前将不再提醒 `); + // 通知中的取消按钮 + notify.getElement().querySelector('.wh-notify-msg button').addEventListener('click', () => WuhuConfig.set('_15_alarm_ignore', undefined)); + } +} + +export interface BeerMonitorLoop { + start?: Function; + stop?: Function; + set_time?: Function; + status?: Function; + is_running?: Function; + skip_today?: Function; +} diff --git a/src/class/action/TravelItem.ts b/src/class/action/TravelItem.ts index c250835..5294248 100644 --- a/src/class/action/TravelItem.ts +++ b/src/class/action/TravelItem.ts @@ -5,18 +5,16 @@ import UserScriptEngine from "../../enum/UserScriptEngine"; import Popup from "../utils/Popup"; import STOCK_IMG_HTML from "../../static/html/stock_img.html"; import * as FILTER from "../../static/json/for_stock_item_filter.json"; +import WindowActiveState from "./WindowActiveState"; export default class TravelItem extends WuhuBase { private obj: any = null; private res: any = null; - // private infoUtils: InfoUtils = InfoUtils.getInstance(); - // private commonUtils: CommonUtils = CommonUtils.getInstance(); - // TODO bug修复 public constructor() { super(); window.setInterval(async () => { - if (!TravelItem.glob.isWindowActive.get()) return; + if (!WindowActiveState.getInstance().get()) return; Log.info('fetching https://yata.yt/api/v1/travel/export/'); const res = await CommonUtils.COFetch('https://yata.yt/api/v1/travel/export/'); Log.info('fetch returned'); diff --git a/src/class/utils/Alert.ts b/src/class/utils/Alert.ts index dee1384..8532f81 100644 --- a/src/class/utils/Alert.ts +++ b/src/class/utils/Alert.ts @@ -3,6 +3,8 @@ import IWHNotify from "../../interface/IWHNotify"; import NotificationUtils from "./NotificationUtils"; import WuhuBase from "../WuhuBase"; import MathUtils from "./MathUtils"; +import NOTIFY_HTML from "../../static/html/notify.html"; +import WindowActiveState from "../action/WindowActiveState"; export default class Alert extends WuhuBase { private static container: HTMLElement = null; @@ -17,7 +19,7 @@ export default class Alert extends WuhuBase { let { timeout, callback, sysNotify, } = options; // 后台窗口、iframe内判断 - if (!Alert.glob.isWindowActive.get() || (self !== top)) return null; + if (!WindowActiveState.getInstance().get() || (self !== top)) return null; // 通知的容器 if (Alert.container === null) Alert.initContainer(); @@ -29,19 +31,13 @@ export default class Alert extends WuhuBase { } private static create(that: Alert, msg, timeout): void { - let mathUtils: MathUtils = MathUtils.getInstance(); // 通知的唯一id - const uid = '' + mathUtils.getRandomInt(1000, 9999); - // const uid = '' + performance.now(); + const uid = '' + MathUtils.getInstance().getRandomInt(1000, 9999); // 每条通知 const element: MyHTMLElement = document.createElement('div'); element.id = `wh-notify-${ uid }`; element.classList.add('wh-notify-item'); - element.innerHTML = `
-
-
-

${ msg }

-
`; + element.innerHTML = NOTIFY_HTML.replace('{{}}', msg); this.container.append(element); // 进度条node const progressBar: HTMLElement = element.querySelector('.wh-notify-bar'); @@ -64,9 +60,8 @@ export default class Alert extends WuhuBase { that.close(); } }, timeout * 1000 / 100) as unknown as number; - element.querySelector('.wh-notify-close').addEventListener('click', that.close); + element.querySelector('.wh-notify-close').addEventListener('click', () => that.close()); that.notify = element; - Log.info(that.notify) } private static initContainer() { @@ -79,8 +74,7 @@ export default class Alert extends WuhuBase { this.notify.remove(); this.notify = null; this.callback(); - let id = this.intervalID; - window.clearInterval(id); + window.clearInterval(this.intervalID); } public getElement() { diff --git a/src/func/utils/BuyBeer.ts b/src/func/utils/@deprecated/BuyBeer.ts similarity index 92% rename from src/func/utils/BuyBeer.ts rename to src/func/utils/@deprecated/BuyBeer.ts index 3cf015e..1b44262 100644 --- a/src/func/utils/BuyBeer.ts +++ b/src/func/utils/@deprecated/BuyBeer.ts @@ -1,11 +1,13 @@ -import audioPlay from "./audioPlay"; -import MathUtils from "../../class/utils/MathUtils"; -import Alert from "../../class/utils/Alert"; -import InfoUtils from "../../class/utils/InfoUtils"; -import WuhuConfig from "../../class/WuhuConfig"; -import Log from "../../class/Log"; +import audioPlay from "../audioPlay"; +import MathUtils from "../../../class/utils/MathUtils"; +import Alert from "../../../class/utils/Alert"; +import InfoUtils from "../../../class/utils/InfoUtils"; +import WuhuConfig from "../../../class/WuhuConfig"; +import Log from "../../../class/Log"; -// 啤酒 +/** + * @deprecated + */ export default function BuyBeer() { // 正在通知 let is_notified = false; diff --git a/src/func/utils/autoFetchJSON.ts b/src/func/utils/@deprecated/autoFetchJSON.ts similarity index 70% rename from src/func/utils/autoFetchJSON.ts rename to src/func/utils/@deprecated/autoFetchJSON.ts index e5537a3..c76268f 100644 --- a/src/func/utils/autoFetchJSON.ts +++ b/src/func/utils/@deprecated/autoFetchJSON.ts @@ -1,8 +1,9 @@ -import CommonUtils from "../../class/utils/CommonUtils"; -import WuhuBase from "../../class/WuhuBase"; +import CommonUtils from "../../../class/utils/CommonUtils"; +import WindowActiveState from "../../../class/action/WindowActiveState"; /** * 循环获取json对象 + * @deprecated * @param dest * @param time */ @@ -10,7 +11,7 @@ function autoFetchJSON(dest, time = 30) { let obj; const res = CommonUtils.COFetch(dest); setInterval(async () => { - if (!WuhuBase.glob.isWindowActive.get()) return; + if (!WindowActiveState.getInstance().get()) return; const res = await CommonUtils.COFetch(dest); obj = JSON.parse(res); }, time * 1000); diff --git a/src/func/utils/WHNotify.ts b/src/func/utils/WHNotify.ts index e74f4a4..2730392 100644 --- a/src/func/utils/WHNotify.ts +++ b/src/func/utils/WHNotify.ts @@ -1,6 +1,7 @@ import addStyle from "./@deprecated/addStyle"; import WuhuBase from "../../class/WuhuBase"; import MathUtils from "../../class/utils/MathUtils"; +import WindowActiveState from "../../class/action/WindowActiveState"; /** * 通知方法 @@ -14,7 +15,7 @@ import MathUtils from "../../class/utils/MathUtils"; * @return {HTMLElement} */ export default function WHNotify(msg: string, options: WHNotifyOpt = {}): MyHTMLElement { - let { isWindowActive, notifies } = WuhuBase.glob; + let { notifies } = WuhuBase.glob; let mathUtils: MathUtils = MathUtils.getInstance(); let { @@ -26,7 +27,7 @@ export default function WHNotify(msg: string, options: WHNotifyOpt = {}): MyHTML sysNotifyClick = () => window.focus() } = options; - if (!isWindowActive.get() || (self !== top)) return null; + if (!WindowActiveState.getInstance().get() || (self !== top)) return null; const date = new Date(); // 通知的唯一id const uid = `${ date.getHours() }${ date.getSeconds() }${ date.getMilliseconds() }${ mathUtils.getRandomInt(1000, 9999) }`; diff --git a/src/interface/IGlobal.ts b/src/interface/IGlobal.ts index 8bfad61..8e3d524 100644 --- a/src/interface/IGlobal.ts +++ b/src/interface/IGlobal.ts @@ -1,5 +1,5 @@ import Device from "../enum/Device"; -import { BeerMonitorLoop } from "../func/utils/BuyBeer"; +import { BeerMonitorLoop } from "../class/action/BuyBeerHelper"; export default interface IGlobal { GM_xmlhttpRequest?: Function; @@ -45,5 +45,5 @@ export default interface IGlobal { }; // 窗口活动状态 - isWindowActive: { get: () => boolean }; + isWindowActive?: { get: () => boolean }; } \ No newline at end of file diff --git a/src/interface/IWHNotify.ts b/src/interface/IWHNotify.ts index b76ad69..ac1a03a 100644 --- a/src/interface/IWHNotify.ts +++ b/src/interface/IWHNotify.ts @@ -1,4 +1,5 @@ export default interface IWHNotify { + // 秒 timeout?: number; callback?: Function; sysNotify?: boolean; diff --git a/src/static/html/buyBeer/notify.html b/src/static/html/buyBeer/notify.html new file mode 100644 index 0000000..b54e8df --- /dev/null +++ b/src/static/html/buyBeer/notify.html @@ -0,0 +1,5 @@ +啤酒小助手 +
提醒您:还有不到 50 秒 NPC 的商品就要刷新了,啤酒血包要抢的可以准备咯。 +
+【啤酒店】 +【血包店】 \ No newline at end of file diff --git a/src/static/html/notify.html b/src/static/html/notify.html new file mode 100644 index 0000000..c1b6cbb --- /dev/null +++ b/src/static/html/notify.html @@ -0,0 +1,5 @@ +
+
+
+

{{}}

+
\ No newline at end of file