This commit is contained in:
Liwanyi 2022-10-09 11:06:35 +08:00
parent 56b02ebf5e
commit dd411a65fc
13 changed files with 157 additions and 59 deletions

View File

@ -1,10 +1,9 @@
import BuyBeer, { BeerMonitorLoop } from "../func/utils/BuyBeer";
import Device from "../enum/Device"; import Device from "../enum/Device";
import WindowActiveState from "./action/WindowActiveState";
import WuhuBase from "./WuhuBase"; import WuhuBase from "./WuhuBase";
import IGlobal from "../interface/IGlobal"; import IGlobal from "../interface/IGlobal";
import Log from "./Log"; import Log from "./Log";
import InfoUtils from "./utils/InfoUtils"; import InfoUtils from "./utils/InfoUtils";
import BuyBeerHelper from "./action/BuyBeerHelper";
export default class Global extends WuhuBase implements IGlobal { export default class Global extends WuhuBase implements IGlobal {
GM_xmlhttpRequest: Function = null; GM_xmlhttpRequest: Function = null;
@ -13,11 +12,9 @@ export default class Global extends WuhuBase implements IGlobal {
// 弹窗 // 弹窗
popup_node: MyHTMLElement = null; popup_node: MyHTMLElement = null;
// 啤酒助手 // 啤酒助手
beer: BeerMonitorLoop = null; beer = null;
// 留存的通知 // 留存的通知
notifies: NotifyWrapper = null; notifies: NotifyWrapper = null;
// 价格监控
// priceWatcher?: { status: boolean };
// 海外库存 // 海外库存
fStock: { get: () => Promise<any> } = null; fStock: { get: () => Promise<any> } = null;
// 玩家名和数字id // 玩家名和数字id
@ -42,10 +39,6 @@ export default class Global extends WuhuBase implements IGlobal {
// [key: string]: string; // [key: string]: string;
} = null; } = null;
// 窗口活动状态
// isWindowActive = null;
isWindowActive = WindowActiveState.getInstance();
constructor() { constructor() {
Log.info('WH脚本参数初始化'); Log.info('WH脚本参数初始化');
super(); super();
@ -57,17 +50,14 @@ export default class Global extends WuhuBase implements IGlobal {
this.isPDA = !this.PDA_APIKey.includes('###'); this.isPDA = !this.PDA_APIKey.includes('###');
this.device = window.innerWidth >= 1000 ? Device.PC : window.innerWidth <= 600 ? Device.MOBILE : Device.TABLET; this.device = window.innerWidth >= 1000 ? Device.PC : window.innerWidth <= 600 ? Device.MOBILE : Device.TABLET;
this.player_info = InfoUtils.getInstance().getPlayerInfo(); this.player_info = InfoUtils.getInstance().getPlayerInfo();
this.beer = BuyBeer(); this.beer = BuyBeerHelper.getInstance();
this.popup_node = null; this.popup_node = null;
this.notifies = { count: 0 }; this.notifies = { count: 0 };
// this.isWindowActive = WindowActiveState.getInstance();
this.href = window.location.href; this.href = window.location.href;
this.bodyAttrs = {}; this.bodyAttrs = {};
if (this.unsafeWindow) { if (this.unsafeWindow) {
try { try {
window.whtest = '原window';
this.unsafeWindow.whtest = 'unsafeWindow';
window = this.unsafeWindow || this.window; window = this.unsafeWindow || this.window;
Log.info('替换window上下文'); Log.info('替换window上下文');
} catch { } catch {
@ -95,11 +85,4 @@ export default class Global extends WuhuBase implements IGlobal {
Log.info('WH脚本参数初始化结束'); Log.info('WH脚本参数初始化结束');
} }
// static getInstance(this): Global {
// if (!this.instance) {
// this.instance = new this();
// }
// return this.instance;
// }
} }

View File

@ -97,7 +97,7 @@ export default class UrlPattern extends WuhuBase {
let { data } = settings, { responseText } = xhr; let { data } = settings, { responseText } = xhr;
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('已检测成功购买啤酒');
beer.skip_today(); beer.skip_today();
} }
}); });

View File

@ -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 NNB_INFO_HTML from "../static/html/nnb_info.html";
import PRICE_WATCHER_HTML from "../static/html/price_watcher.html"; import PRICE_WATCHER_HTML from "../static/html/price_watcher.html";
import DANGER_ZONE_HTML from "../static/html/danger_zone.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_MENU_HTML from "../static/html/zhong/zhong_menu.html";
import ZHONG_UPDATE_HTML from "../static/html/zhong/zhong_update.html"; import ZHONG_UPDATE_HTML from "../static/html/zhong/zhong_update.html";
import ZHONG_LOOT_HTML from "../static/html/zhong/zhong_loot.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 DEV_DETAILS_HTML from "../static/html/zhong/setting/dev_details.html";
import QUICK_FLY_CSS from "../static/css/quick_fly.css"; import QUICK_FLY_CSS from "../static/css/quick_fly.css";
import QUICK_LINK_CSS from "../static/css/quick_link.css"; import QUICK_LINK_CSS from "../static/css/quick_link.css";
import BuyBeerHelper from "./action/BuyBeerHelper";
export default class ZhongIcon extends WuhuBase { export default class ZhongIcon extends WuhuBase {
public static ZhongNode: MyHTMLElement = null; public static ZhongNode: MyHTMLElement = null;
@ -765,9 +765,10 @@ export default class ZhongIcon extends WuhuBase {
clickFunc: async function () { clickFunc: async function () {
Log.info('测试开始'); Log.info('测试开始');
new Popup('<button>123</button>').getElement() let helper = BuyBeerHelper.getInstance();
.querySelector('button').onclick = () => new Alert('123'); helper.start();
ActionButtonUtils.getInstance().add('123'); Log.info('is_running', helper.is_running());
helper.skip_today();
Log.info('测试结束'); Log.info('测试结束');
}, },
@ -1038,10 +1039,9 @@ export default class ZhongIcon extends WuhuBase {
if (num < 1 || num > 60) num = 50; if (num < 1 || num > 60) num = 50;
input.value = num.toString(); input.value = num.toString();
WuhuConfig.set('_15AlarmTime', num); WuhuConfig.set('_15AlarmTime', num);
// 之前的运行状态
let before_state = beer.is_running();
beer.set_time(num); beer.set_time(num);
if (before_state) beer.start(); // 之前的运行状态
if (beer.is_running()) beer.start();
popup.close(); popup.close();
}); });
popup.getElement().appendChild(confirm); popup.getElement().appendChild(confirm);

View File

@ -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点前将不再提醒 <button id="wh-rd-btn-${ MathUtils.getInstance().getRandomInt(0, 100) }">取消</button>`);
// 通知中的取消按钮
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;
}

View File

@ -5,18 +5,16 @@ import UserScriptEngine from "../../enum/UserScriptEngine";
import Popup from "../utils/Popup"; import Popup from "../utils/Popup";
import STOCK_IMG_HTML from "../../static/html/stock_img.html"; import STOCK_IMG_HTML from "../../static/html/stock_img.html";
import * as FILTER from "../../static/json/for_stock_item_filter.json"; import * as FILTER from "../../static/json/for_stock_item_filter.json";
import WindowActiveState from "./WindowActiveState";
export default class TravelItem extends WuhuBase { export default class TravelItem extends WuhuBase {
private obj: any = null; private obj: any = null;
private res: any = null; private res: any = null;
// private infoUtils: InfoUtils = InfoUtils.getInstance();
// private commonUtils: CommonUtils = CommonUtils.getInstance();
// TODO bug修复
public constructor() { public constructor() {
super(); super();
window.setInterval(async () => { window.setInterval(async () => {
if (!TravelItem.glob.isWindowActive.get()) return; if (!WindowActiveState.getInstance().get()) return;
Log.info('fetching https://yata.yt/api/v1/travel/export/'); Log.info('fetching https://yata.yt/api/v1/travel/export/');
const res = await CommonUtils.COFetch('https://yata.yt/api/v1/travel/export/'); const res = await CommonUtils.COFetch('https://yata.yt/api/v1/travel/export/');
Log.info('fetch returned'); Log.info('fetch returned');

View File

@ -3,6 +3,8 @@ import IWHNotify from "../../interface/IWHNotify";
import NotificationUtils from "./NotificationUtils"; import NotificationUtils from "./NotificationUtils";
import WuhuBase from "../WuhuBase"; import WuhuBase from "../WuhuBase";
import MathUtils from "./MathUtils"; import MathUtils from "./MathUtils";
import NOTIFY_HTML from "../../static/html/notify.html";
import WindowActiveState from "../action/WindowActiveState";
export default class Alert extends WuhuBase { export default class Alert extends WuhuBase {
private static container: HTMLElement = null; private static container: HTMLElement = null;
@ -17,7 +19,7 @@ export default class Alert extends WuhuBase {
let { timeout, callback, sysNotify, } = options; let { timeout, callback, sysNotify, } = options;
// 后台窗口、iframe内判断 // 后台窗口、iframe内判断
if (!Alert.glob.isWindowActive.get() || (self !== top)) return null; if (!WindowActiveState.getInstance().get() || (self !== top)) return null;
// 通知的容器 // 通知的容器
if (Alert.container === null) Alert.initContainer(); if (Alert.container === null) Alert.initContainer();
@ -29,19 +31,13 @@ export default class Alert extends WuhuBase {
} }
private static create(that: Alert, msg, timeout): void { private static create(that: Alert, msg, timeout): void {
let mathUtils: MathUtils = MathUtils.getInstance();
// 通知的唯一id // 通知的唯一id
const uid = '' + mathUtils.getRandomInt(1000, 9999); const uid = '' + MathUtils.getInstance().getRandomInt(1000, 9999);
// const uid = '' + performance.now();
// 每条通知 // 每条通知
const element: MyHTMLElement = document.createElement('div'); const element: MyHTMLElement = document.createElement('div');
element.id = `wh-notify-${ uid }`; element.id = `wh-notify-${ uid }`;
element.classList.add('wh-notify-item'); element.classList.add('wh-notify-item');
element.innerHTML = `<div class="wh-notify-bar"></div> element.innerHTML = NOTIFY_HTML.replace('{{}}', msg);
<div class="wh-notify-cont">
<div class="wh-notify-close"></div>
<div class="wh-notify-msg"><p>${ msg }</p></div>
</div>`;
this.container.append(element); this.container.append(element);
// 进度条node // 进度条node
const progressBar: HTMLElement = element.querySelector('.wh-notify-bar'); const progressBar: HTMLElement = element.querySelector('.wh-notify-bar');
@ -64,9 +60,8 @@ export default class Alert extends WuhuBase {
that.close(); that.close();
} }
}, timeout * 1000 / 100) as unknown as number; }, 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; that.notify = element;
Log.info(that.notify)
} }
private static initContainer() { private static initContainer() {
@ -79,8 +74,7 @@ export default class Alert extends WuhuBase {
this.notify.remove(); this.notify.remove();
this.notify = null; this.notify = null;
this.callback(); this.callback();
let id = this.intervalID; window.clearInterval(this.intervalID);
window.clearInterval(id);
} }
public getElement() { public getElement() {

View File

@ -1,11 +1,13 @@
import audioPlay from "./audioPlay"; import audioPlay from "../audioPlay";
import MathUtils from "../../class/utils/MathUtils"; import MathUtils from "../../../class/utils/MathUtils";
import Alert from "../../class/utils/Alert"; import Alert from "../../../class/utils/Alert";
import InfoUtils from "../../class/utils/InfoUtils"; import InfoUtils from "../../../class/utils/InfoUtils";
import WuhuConfig from "../../class/WuhuConfig"; import WuhuConfig from "../../../class/WuhuConfig";
import Log from "../../class/Log"; import Log from "../../../class/Log";
// 啤酒 /**
* @deprecated
*/
export default function BuyBeer() { export default function BuyBeer() {
// 正在通知 // 正在通知
let is_notified = false; let is_notified = false;

View File

@ -1,8 +1,9 @@
import CommonUtils from "../../class/utils/CommonUtils"; import CommonUtils from "../../../class/utils/CommonUtils";
import WuhuBase from "../../class/WuhuBase"; import WindowActiveState from "../../../class/action/WindowActiveState";
/** /**
* json对象 * json对象
* @deprecated
* @param dest * @param dest
* @param time * @param time
*/ */
@ -10,7 +11,7 @@ function autoFetchJSON(dest, time = 30) {
let obj; let obj;
const res = CommonUtils.COFetch(dest); const res = CommonUtils.COFetch(dest);
setInterval(async () => { setInterval(async () => {
if (!WuhuBase.glob.isWindowActive.get()) return; if (!WindowActiveState.getInstance().get()) return;
const res = await CommonUtils.COFetch(dest); const res = await CommonUtils.COFetch(dest);
obj = JSON.parse(res); obj = JSON.parse(res);
}, time * 1000); }, time * 1000);

View File

@ -1,6 +1,7 @@
import addStyle from "./@deprecated/addStyle"; import addStyle from "./@deprecated/addStyle";
import WuhuBase from "../../class/WuhuBase"; import WuhuBase from "../../class/WuhuBase";
import MathUtils from "../../class/utils/MathUtils"; import MathUtils from "../../class/utils/MathUtils";
import WindowActiveState from "../../class/action/WindowActiveState";
/** /**
* *
@ -14,7 +15,7 @@ import MathUtils from "../../class/utils/MathUtils";
* @return {HTMLElement} * @return {HTMLElement}
*/ */
export default function WHNotify(msg: string, options: WHNotifyOpt = {}): MyHTMLElement { export default function WHNotify(msg: string, options: WHNotifyOpt = {}): MyHTMLElement {
let { isWindowActive, notifies } = WuhuBase.glob; let { notifies } = WuhuBase.glob;
let mathUtils: MathUtils = MathUtils.getInstance(); let mathUtils: MathUtils = MathUtils.getInstance();
let { let {
@ -26,7 +27,7 @@ export default function WHNotify(msg: string, options: WHNotifyOpt = {}): MyHTML
sysNotifyClick = () => window.focus() sysNotifyClick = () => window.focus()
} = options; } = options;
if (!isWindowActive.get() || (self !== top)) return null; if (!WindowActiveState.getInstance().get() || (self !== top)) return null;
const date = new Date(); const date = new Date();
// 通知的唯一id // 通知的唯一id
const uid = `${ date.getHours() }${ date.getSeconds() }${ date.getMilliseconds() }${ mathUtils.getRandomInt(1000, 9999) }`; const uid = `${ date.getHours() }${ date.getSeconds() }${ date.getMilliseconds() }${ mathUtils.getRandomInt(1000, 9999) }`;

View File

@ -1,5 +1,5 @@
import Device from "../enum/Device"; import Device from "../enum/Device";
import { BeerMonitorLoop } from "../func/utils/BuyBeer"; import { BeerMonitorLoop } from "../class/action/BuyBeerHelper";
export default interface IGlobal { export default interface IGlobal {
GM_xmlhttpRequest?: Function; GM_xmlhttpRequest?: Function;
@ -45,5 +45,5 @@ export default interface IGlobal {
}; };
// 窗口活动状态 // 窗口活动状态
isWindowActive: { get: () => boolean }; isWindowActive?: { get: () => boolean };
} }

View File

@ -1,4 +1,5 @@
export default interface IWHNotify { export default interface IWHNotify {
// 秒
timeout?: number; timeout?: number;
callback?: Function; callback?: Function;
sysNotify?: boolean; sysNotify?: boolean;

View File

@ -0,0 +1,5 @@
<span style="background-color:green;color:white;border-radius:3px;font-size:14px;line-height:21px;padding:2px 4px;">啤酒小助手</span>
<br/>提醒您:还有不到 50 秒 NPC 的商品就要刷新了,啤酒血包要抢的可以准备咯。
<button id="wh-rd-btn-{{}}">【今日不再提醒】</button><br/>
<a href="/shops.php?step=bitsnbobs#clickfromnotify" target="_blank">【啤酒店】</a>
<a href="/shops.php?step=pharmacy#clickfromnotify" target="_blank">【血包店】</a>

View File

@ -0,0 +1,5 @@
<div class="wh-notify-bar"></div>
<div class="wh-notify-cont">
<div class="wh-notify-close"></div>
<div class="wh-notify-msg"><p>{{}}</p></div>
</div>