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 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<any> } = 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;
// }
}

View File

@ -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();
}
});

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 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('<button>123</button>').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);

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 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');

View File

@ -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 = `<div class="wh-notify-bar"></div>
<div class="wh-notify-cont">
<div class="wh-notify-close"></div>
<div class="wh-notify-msg"><p>${ msg }</p></div>
</div>`;
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() {

View File

@ -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;

View File

@ -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);

View File

@ -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) }`;

View File

@ -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 };
}

View File

@ -1,4 +1,5 @@
export default interface IWHNotify {
// 秒
timeout?: number;
callback?: Function;
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>