水晶球解密地图攻略
@@ -7501,7 +7513,7 @@ margin: 0 0 3px;
});
}
// 宝箱检测
- if (getWhSetting().xmasTownNotify) {
+ if (getWhSettingObj().xmasTownNotify) {
const chestTypeDict = {'1': '金', '2': '银', '3': '铜',};
const chestTypeColorDict = {'1': 'gold', '2': 'silver', '3': 'sandybrown',};
const lootTypeDict = {'chests': '钥匙箱', 'gifts': '礼物', 'combinationChest': '密码箱', 'keys': '钥匙',};
@@ -8698,8 +8710,7 @@ margin: 0 0 3px;
/*
ob
*/
- function initOB(dom = document, opt = {}, func = () => {
- }, dev = false, once = false) {
+ function initOB(dom = document, opt = {}, func = doNothing, dev = false, once = false) {
//let count = -1;
if (dev) {
const mo = new MutationObserver((mutation) => {
@@ -8766,7 +8777,7 @@ margin: 0 0 3px;
const newNode = document.createElement('div');
switch (setting.domType) {
case 'checkbox': {
- newNode.innerHTML += ``;
+ newNode.innerHTML += ``;
settingNode.appendChild(newNode);
settingNode.querySelector(`#${setting.domId}`).onchange = (elem) => {
setWhSetting(setting.dictName, elem.target.checked);
@@ -8782,7 +8793,7 @@ margin: 0 0 3px;
case 'select': {
let optHtml = '';
setting.domSelectOpt.forEach((optObj, i) => {
- const selected = i === getWhSetting()[setting.dictName] ? 'selected' : '';
+ const selected = i === getWhSettingObj()[setting.dictName] ? 'selected' : '';
optHtml += ``;
});
newNode.innerHTML += ``;
@@ -8838,7 +8849,7 @@ margin: 0 0 3px;
// bool 返回当前是否dev状态
function isDev() {
try {
- return getWhSetting().isDev || false;
+ return getWhSettingObj().isDev || false;
} catch (e) {
console.error(`[wh] dev状态错误 ${e}`);
return false;
@@ -8855,16 +8866,19 @@ margin: 0 0 3px;
`;
document.body.append(popup);
- const clickFunc = e => {
+ popup.addEventListener('click', e => {
e.stopImmediatePropagation();
if (e.target === popup) {
- popup.removeEventListener('click', clickFunc);
popup.remove();
callback();
}
+ });
+ const rt = popup.querySelector('#wh-popup-cont')
+ rt.close = () => {
+ popup.remove();
+ callback();
};
- popup.addEventListener('click', clickFunc);
- return popup.querySelector('#wh-popup-cont');
+ return rt;
}
// 弹出窗口是否存在
@@ -8975,16 +8989,14 @@ margin: 0 0 3px;
if (isDev()) console.log('[WH]', ...o)
}
- /**
- * 通知
- *
- * @param {String?} msg 通知上显示的内容,默认为空
- * @param {Number?} timeout 停留的时间,默认3秒
- * @param {Function?} callback 通知结束后执行的函数
- * @param {Boolean?} sysNotify 是否显示系统通知
- * @returns {HTMLElement} 通知的node
- */
- function WHNotify(msg = '', timeout = 3, callback = null, sysNotify = false) {
+ function WHNotify(msg = '', {
+ timeout = 3,
+ callback = doNothing,
+ sysNotify = false,
+ sysNotifyTag = '芜湖助手',
+ sysNotifyClick = () => window.focus(),
+ } = {}) {
+ if (!isWindowActive() || isIframe) return null;
const date = new Date();
// 通知的唯一id
const uid = `${date.getHours()}${date.getSeconds()}${date.getMilliseconds()}${getRandomInt(1000, 9999)}`;
@@ -9028,7 +9040,7 @@ margin: 0 0 3px;
const removeNode = () => {
clearInterval(intervalID);
new_node.remove();
- if (callback !== null) callback();
+ callback();
};
new_node.del = removeNode;
new_node.querySelector('.wh-notify-close button').addEventListener('click', removeNode);
@@ -9083,21 +9095,15 @@ text-decoration:none;
}
const notify_obj = add_notify();
// 浏览器通知
- try {
- if (Notification.permission === 'granted' && sysNotify) {
- const last_notify = getWhSetting('lastNotify');
- const last_notify_date = new Date(last_notify);
- const date_local_string = `[${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}]\r`
- if (!!last_notify_date || date - last_notify_date > 3000) {
- new Notification('芜湖助手', {
- body: date_local_string + notify_contain.msgInnerText,
- requireInteraction: false
- });
- setWhSetting('lastNotify', date.getTime(), false)
- }
- }
- } catch (e) {
- log(e)
+ if (window.Notification && Notification.permission === 'granted' && sysNotify) {
+ const date_local_string = `[${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}]\r`;
+ const sys_notify = new Notification('芜湖助手', {
+ body: date_local_string + notify_contain.msgInnerText,
+ requireInteraction: true,
+ renotify: true,
+ tag: sysNotifyTag,
+ });
+ sys_notify.onclick = sysNotifyClick;
}
return notify_obj;
}
@@ -9162,7 +9168,7 @@ z-index:100001;
_window.GM_setValue("gsp_x", 10);
_window.GM_setValue("gsp_y", 10);
notify.del();
- notify = WHNotify('飞贼小助手已加载', 1);
+ notify = WHNotify('飞贼小助手已加载', {timeout: 1});
const gsp = _docu.querySelector('#gsp');
const init = () => {
ifr.style.height = `${gsp.offsetHeight + 10}px`;
@@ -9216,9 +9222,8 @@ z-index:100001;
/**
* 播放音频
- *
- * @param url:String 播放的音频URL
- * @returns void
+ * @param {string} url 播放的音频URL
+ * @returns {undefined}
*/
function audioPlay(url = 'https://www.torn.com/js/chat/sounds/Warble_1.mp3') {
const audio = new Audio(url);
@@ -9252,18 +9257,18 @@ z-index:100001;
}
// 插件的配置 getter
- function getWhSetting() {
+ function getWhSettingObj() {
return JSON.parse(localStorage.getItem('wh_trans_settings')) || {}
}
// 插件的配置 setter
function setWhSetting(key, value, notify = true) {
- const obj = getWhSetting()
+ const obj = getWhSettingObj()
obj[key] = value
localStorage.setItem('wh_trans_settings', JSON.stringify(obj))
// 通知
- if (notify) WHNotify('已保存设置', 3, null, false)
+ if (notify) WHNotify('已保存设置')
}
// 循环获取json对象
@@ -9271,6 +9276,7 @@ z-index:100001;
let obj;
const res = COFetch(dest);
setInterval(async () => {
+ if (!isWindowActive()) return;
const res = await COFetch(dest);
obj = JSON.parse(res);
}, time * 1000);
@@ -9288,10 +9294,14 @@ z-index:100001;
// 价格监视handle
function priceWatcherHandle() {
setInterval(() => {
- const price_conf = getWhSetting()['priceWatcher'];
+ const price_conf = getWhSettingObj()['priceWatcher'];
const apikey = isPDA ? PDA_APIKey : localStorage.getItem('APIKey');
+ if (!apikey) {
+ log('无法获取APIKey')
+ return;
+ }
if (price_conf['pt'] !== -1) priceWatcherPt(apikey, price_conf['pt']).then();
- if (price_conf['xan'] !== -1) priceWatcherXan(apikey).then();
+ if (price_conf['xan'] !== -1) priceWatcherXan(apikey, price_conf['xan']).then();
}, 10000)
return {status: true};
}
@@ -9315,7 +9325,11 @@ z-index:100001;
// 将id与之前存在的比较,不相同时发送通知
if (JSON.stringify(priceWatcher['watch-pt-lower-id']) !== JSON.stringify(lower_arr)) {
priceWatcher['watch-pt-lower-id'] = lower_arr;
- WHNotify(`PT新低价:$${low}(<${lower_price}) -
点击转跳`, 3, null, true);
+ WHNotify(`PT新低价:$${toThousands(low)}( < $${toThousands(lower_price)}) -
点击转跳`, {
+ timeout: 6,
+ sysNotify: true,
+ sysNotifyClick: () => window.open('https://www.torn.com/pmarket.php'),
+ });
}
} else {
// 查询出错了
@@ -9324,10 +9338,59 @@ z-index:100001;
}
// xan价格监视
- async function priceWatcherXan(apikey) {
+ async function priceWatcherXan(apikey, lower_price) {
+ // 初始化记录上一个条目的id,避免重复发送通知
+ if (!priceWatcher['watch-xan-lower-id']) priceWatcher['watch-xan-lower-id'] = '';
+ const res = await fetch('https://api.torn.com/market/206?selections=bazaar&key=' + apikey);
+ const obj = await res.json();
+ if (obj['bazaar']) {
+ const lowest_item = obj['bazaar'][0]
+ if (lowest_item['cost'] <= lower_price) {
+ if (priceWatcher['watch-xan-lower-id'] !== lowest_item['ID']) {
+ priceWatcher['watch-xan-lower-id'] = lowest_item['ID'];
+ WHNotify(`XAN新低价:$${toThousands(lowest_item['cost'])}( < $${toThousands(lower_price)}) -
点击转跳`,{
+ timeout:6,
+ sysNotify:true,
+ sysNotifyClick:()=>window.open('https://www.torn.com/imarket.php#/p=shop&step=shop&type=&searchname=Xanax')
+ });
+ }
+ }
+ } else {
+ // 查询出错了
+ log('xan查询出错了')
+ }
}
// 空函数
function doNothing() {
}
+
+ // 返回UUID
+ function uuidv4() {
+ if (crypto.randomUUID) return crypto.randomUUID();
+ return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c =>
+ (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
+ );
+ }
+
+ // 返回一个可用查询当前窗口是否激活的函数
+ function getWindowActiveState() {
+ if (isIframe) return false;
+ const uuid = uuidv4();
+ let isFocus = false;
+ localStorage.setItem('whuuid', uuid);
+ document.addEventListener('visibilitychange', () =>
+ (document.visibilityState !== 'hidden') && (localStorage.setItem('whuuid', uuid))
+ );
+ addEventListener('focus', () => isFocus = true)
+ addEventListener('blur', () => isFocus = false)
+ return function () {
+ // 当前窗口获得了焦点 优先级最高
+ if (isFocus) return true;
+ // 可视性
+ if (!document.hidden) return true;
+ // 全部在后台,使用唯一id判断
+ return uuid === localStorage.getItem('whuuid')
+ };
+ }
}());