diff --git a/wuhu-torn-helper.js b/wuhu-torn-helper.js index 5c90431..d571b3e 100644 --- a/wuhu-torn-helper.js +++ b/wuhu-torn-helper.js @@ -27,6 +27,7 @@ }) } + // region 翻译字典 const titleDict = { 'Home': '主页', 'Estate Agents': '地产中介', @@ -2725,36 +2726,6 @@ }; // 中文字符集正则 const CC_set = /[\u4e00-\u9fa5]/; - - // regexp test - String.prototype.contains = function contains(keywords) { - if ('string' === typeof keywords) { - return new RegExp(keywords).test(this); - } - if (keywords.test) { - return keywords.test(this); - } - }; - - // 原始fetch - const ori_fetch = window.fetch; - // 监听fetch - window.fetch = async (url, init) => { - if (url.contains('newsTickers')) { - // 阻止获取新闻横幅 - return new Response('{}'); - } - const res = await ori_fetch(url, init); - // mini profile 翻译 - if (url.includes('profiles.php?step=getUserNameContextMenu') && getWhSettingObj()['transEnable']) { - setTimeout(() => miniprofTrans(), 200); - } - let clone = res.clone(); - let text = await res.text(); - log({ url, init, text }); - return clone; - }; - // const transDict = {}; // transDict.titleDict = titleDict; // transDict.titleLinksDict = titleLinksDict; @@ -2794,6 +2765,36 @@ // transDict.npcShopDict = npcShopDict; // transDict.calDict = calDict; // if (!localStorage.getItem('wh_trans_transDict')) localStorage.setItem('wh_trans_transDict', JSON.stringify(transDict)) + // endregion + + // regexp test + String.prototype.contains = function contains(keywords) { + if ('string' === typeof keywords) { + return new RegExp(keywords).test(this); + } + if (keywords.test) { + return keywords.test(this); + } + }; + + // 原始fetch + const ori_fetch = window.fetch; + // 监听fetch + window.fetch = async (url, init) => { + if (url.contains('newsTickers')) { + // 阻止获取新闻横幅 + return new Response('{}'); + } + const res = await ori_fetch(url, init); + // mini profile 翻译 + if (url.includes('profiles.php?step=getUserNameContextMenu') && getWhSettingObj()['transEnable']) { + setTimeout(() => miniprofTrans(), 200); + } + let clone = res.clone(); + let text = await res.text(); + log({ url, init, text }); + return clone; + }; const date = new Date(); // 伪enum 设备类型 PC MOBILE TABLET @@ -2888,567 +2889,564 @@ if (typeof getWhSettingObj()[df.key] !== typeof df.val) setWhSetting(df.key, df.val); }); - // 助手各项「设置」 + // region 助手各项「设置」 let setting_list = []; - { - // 12月时加入圣诞小镇选项 - if (date.getMonth() === 11) { - setting_list.push({ - domType: 'plain', - domId: '', - domHTML: '圣诞小镇', - tagName: 'h4', - }) - setting_list.push({ - domType: 'checkbox', - domId: 'wh-xmastown-wt', - domText: ' 圣诞小镇攻略', - dictName: 'xmasTownWT', - isHide: true, - }); - setting_list.push({ - domType: 'checkbox', - domId: 'wh-xmastown-notify', - domText: ' 圣诞小镇物品提示', - dictName: 'xmasTownNotify', - isHide: true, - }); - } - - // 翻译 + // 12月时加入圣诞小镇选项 + if (date.getMonth() === 11) { setting_list.push({ domType: 'plain', domId: '', - domHTML: '翻译', + domHTML: '圣诞小镇', tagName: 'h4', - }); - // 开启翻译 + }) setting_list.push({ domType: 'checkbox', - domId: 'wh-trans-enable', - domText: ' 开启翻译', - dictName: 'transEnable', + domId: 'wh-xmastown-wt', + domText: ' 圣诞小镇攻略', + dictName: 'xmasTownWT', isHide: true, }); - // 更新翻译词库 - setting_list.push({ - domType: 'button', - domId: '', - domText: '更新翻译词库', - clickFunc: updateTransDict - }); - - // 战斗优化 - setting_list.push({ - domType: 'plain', - domId: '', - domHTML: '战斗优化', - tagName: 'h4', - }); - // 光速拔刀 - setting_list.push({ - domType: 'select', - domId: 'wh-quick-attack-index', - domText: '光速拔刀 ', - domSelectOpt: [ - { - domVal: 'pri', - domText: '主手', - }, - { - domVal: 'sec', - domText: '副手', - }, - { - domVal: 'wea', - domText: '近战', - }, - { - domVal: 'gre', - domText: '手雷', - }, - { - domVal: 'fis', - domText: '拳头', - }, - { - domVal: 'kic', - domText: '脚踢', - }, - { - domVal: 'none', - domText: '关闭', - }, - ], - dictName: 'quickAttIndex', - isHide: true, - tip: '将Start Fight按钮移动到指定格子上', - }); - // 光速跑路 - setting_list.push({ - domType: 'select', - domId: 'wh-quick-mug', - domText: '光速跑路 ', - domSelectOpt: [ - { - domVal: 'leave', - domText: '跑路(LEAVE)', - }, - { - domVal: 'mug', - domText: '打劫(MUG)', - }, - { - domVal: 'hosp', - domText: '住院(HOSP)', - }, - { - domVal: 'none', - domText: '关闭', - }, - ], - dictName: 'quickFinishAtt', - isHide: true, - tip: '将结束后指定按钮移动到上面指定的格子上', - }); - // 攻击链接转跳 setting_list.push({ domType: 'checkbox', - domId: 'wh-attack-relocate', - domText: ' 真·攻击界面转跳', - dictName: 'attRelocate', - tip: '在无法打开攻击界面的情况下依然可以转跳到正确的攻击页面', - isHide: true, - }); - - // 飞行 - setting_list.push({ - domType: 'plain', - domId: '', - domHTML: '飞行', - tagName: 'h4', - }); - // 起飞警告 - setting_list.push({ - domType: 'checkbox', - domId: 'wh-energy-alert', - domText: ' 起飞爆E警告', - dictName: 'energyAlert', - tip: '起飞前计算来回是否会爆体,红字警告', - isHide: true, - }); - // 飞行闹钟 - setting_list.push({ - domType: 'checkbox', - domId: 'wh-trv-alarm-check', - domText: ' 飞行闹钟', - dictName: 'trvAlarm', - tip: '(仅PC) 飞行页面将显示一个内建的闹钟,落地前声音提醒,需要打开浏览器声音权限', - isHide: true, - }); - // 外海警告 - setting_list.push({ - domType: 'checkbox', - domId: '', - domText: ' 外海警告', - dictName: 'abroadWarning', - tip: '海外落地后每30秒通知警告', - }); - - // 公司 - setting_list.push({ - domType: 'plain', - domId: '', - domHTML: '公司', - tagName: 'h4', - }); - // 浮动存钱框 - setting_list.push({ - domType: 'checkbox', - domId: '', - domText: ' 浮动存钱框', - dictName: 'floatDepo', - tip: '打开公司或帮派的存钱页面后存钱框将浮动显示', - }); - // 公司转跳存钱 - setting_list.push({ - domType: 'checkbox', - domId: '', - domText: ' 公司转跳存钱', - dictName: 'companyRedirect', - tip: '打开公司页面时自动打开存钱选项卡', - }); - // 收起公司冰蛙效率表 - setting_list.push({ - domType: 'checkbox', - domId: '', - domText: ' 收起公司冰蛙效率表', - dictName: 'companyBWCollapse', - tip: '开启后可手动显示隐藏冰蛙公司表格', - }); - - // 啤酒 - setting_list.push({ - domType: 'plain', - domId: '', - domHTML: '啤酒', - tagName: 'h4', - }); - // 啤酒提醒 - setting_list.push({ - domType: 'checkbox', - domId: 'wh-qua-alarm-check', - domText: ' 啤酒提醒 ', - dictName: '_15Alarm', - tip: '每小时的整15分钟的倍数时通知提醒抢啤酒或者血包', - isHide: true, - changeEv: function (ev) { - ev.target.checked ? beer.start() : beer.stop(); - }, - }); - // 啤酒提醒状态 - setting_list.push({ - domType: 'button', - domId: '', - domText: '啤酒提醒状态', - clickFunc: function () { - WHNotify(`啤酒提醒${beer.status()}`); - } - }); - // 啤酒提醒时间 - setting_list.push({ - domType: 'button', - domId: '', - domText: '啤酒提醒时间设定', - // tip: '通知提前时间', - clickFunc: function () { - popup_node.close(); - let popup = popupMsg(`
区间为 1 ~ 60,默认 50
`, '啤酒提醒时间设定'); - let confirm = document.createElement('button'); - confirm.innerHTML = '确定'; - confirm.style.float = 'right'; - confirm.addEventListener('click', () => { - let input = popup.querySelector('input'); - let num = input.value | 0; - if (num === getWhSettingObj()['_15AlarmTime']) return; - if (num < 1 || num > 60) num = 50; - input.value = num.toString(); - setWhSetting('_15AlarmTime', num); - // 之前的运行状态 - let before_state = beer.is_running(); - beer.set_time(num); - if (before_state) beer.start(); - popup.close(); - }); - popup.appendChild(confirm); - }, - }); - - // 其他 - setting_list.push({ - domType: 'plain', - domId: '', - domHTML: '其他', - tagName: 'h4', - }); - // 任务助手 - setting_list.push({ - domType: 'checkbox', - domId: 'wh-mission-lint', - domText: ' 任务助手', - dictName: 'missionHint', - tip: 'Duke任务的一些中文小提示', - isHide: true, - }); - // 捡垃圾助手 - setting_list.push({ - domType: 'checkbox', - domId: 'wh-city-finder', - domText: ' 捡垃圾助手', - dictName: 'cityFinder', - tip: '城市地图中放大显示物品并且估计价值', - isHide: true, - }); - // 快速crime - setting_list.push({ - domType: 'checkbox', - domId: 'wh-quick-crime', - domText: ' 快速犯罪', - dictName: 'quickCrime', - tip: '显示快捷操作按钮,目前不支持自定义', - isHide: true, - }); - // 叠E保护 - setting_list.push({ - domType: 'checkbox', - domId: 'wh-SEProtect-check', - domText: ' 叠E保护', - dictName: 'SEProtect', - tip: '隐藏健身房的锻炼按钮,防止误操作', - isHide: true, - }); - // PT一键购买 - setting_list.push({ - domType: 'checkbox', - domId: 'wh-ptQuickBuy-check', - domText: ' PT一键购买', - dictName: 'ptQuickBuy', - tip: 'PT市场页面购买时跳过确认', - isHide: true, - }); - // 4条转跳 - setting_list.push({ - domType: 'checkbox', - domId: '', - domText: ' 4条转跳', - dictName: 'barsRedirect', - tip: '点击4条时转跳对应页面', - }); - // 清除多余的脚本 - setting_list.push({ - domType: 'checkbox', - domId: '', - domText: ' 清除多余的脚本', - dictName: 'removeScripts', - tip: '清除Google相关脚本、顶部横幅等', - }); - // 危险行为⚠️ - if (getWhSettingObj()['dangerZone'] === true) { - // 攻击界面自刷新 - setting_list.push({ - domType: 'select', - domId: 'wh-attack-reload', - domText: '⚠️攻击界面自动刷新 ', - dictName: 'attReload', - domSelectOpt: [ - { - domVal: 'none', - domText: '无间隔', - }, - { - domVal: '1', - domText: '约1s', - }, - { - domVal: '2', - domText: '约2s', - }, - { - domVal: '3', - domText: '约3s', - }, - { - domVal: '4', - domText: '约4s', - }, - { - domVal: '5', - domText: '约5s', - }, - { - domVal: 'disabled', - domText: '关闭', - }, - ], - isHide: true, - tip: '危险功能:接机时常用,将自动刷新页面直到目标落地', - }); - // 自动开打和结束 - setting_list.push({ - domType: 'checkbox', - domId: 'wh-auto-start-finish', - domText: ' ⚠️自动开打和结束', - dictName: 'autoStartFinish', - tip: '脚本将会自动按下战斗和结束按钮', - isHide: true, - }); - } else { - setWhSetting('autoStartFinish', false, false) - setWhSetting('attReload', 6, false) - } - // dev - setting_list.push({ - domType: 'checkbox', - domId: 'wh-dev-mode', - domText: ` 开发者模式${isDev() ? ' ' : ''}`, - dictName: 'isDev', - isHide: true, - }); - // 更多设定 - if (isDev()) setting_list.push({ - domType: 'button', domId: 'wh-otherBtn', domText: '更多设定', clickFunc: () => { - const html = `清空设置数据、请求通知权限、测试跨域请求`; - const popup = popupMsg(html, '更多设定'); - }, + domId: 'wh-xmastown-notify', + domText: ' 圣诞小镇物品提示', + dictName: 'xmasTownNotify', isHide: true, }); } - // 菜单中的「选项」 - const menu_list = []; - { - // 测试日期 - //const date = new Date(2022, 2, 4, 23); - // 欢迎 显示玩家id - if (player_info.userID !== 0) { - menu_list.push({ - domType: 'plain', - domId: 'wh-trans-welcome', - domHTML: `欢迎 ${player_info.playername}[${player_info.userID}] 大佬`, + // 翻译 + setting_list.push({ + domType: 'plain', + domId: '', + domHTML: '翻译', + tagName: 'h4', + }); + // 开启翻译 + setting_list.push({ + domType: 'checkbox', + domId: 'wh-trans-enable', + domText: ' 开启翻译', + dictName: 'transEnable', + isHide: true, + }); + // 更新翻译词库 + setting_list.push({ + domType: 'button', + domId: '', + domText: '更新翻译词库', + clickFunc: updateTransDict + }); + + // 战斗优化 + setting_list.push({ + domType: 'plain', + domId: '', + domHTML: '战斗优化', + tagName: 'h4', + }); + // 光速拔刀 + setting_list.push({ + domType: 'select', + domId: 'wh-quick-attack-index', + domText: '光速拔刀 ', + domSelectOpt: [ + { + domVal: 'pri', + domText: '主手', + }, + { + domVal: 'sec', + domText: '副手', + }, + { + domVal: 'wea', + domText: '近战', + }, + { + domVal: 'gre', + domText: '手雷', + }, + { + domVal: 'fis', + domText: '拳头', + }, + { + domVal: 'kic', + domText: '脚踢', + }, + { + domVal: 'none', + domText: '关闭', + }, + ], + dictName: 'quickAttIndex', + isHide: true, + tip: '将Start Fight按钮移动到指定格子上', + }); + // 光速跑路 + setting_list.push({ + domType: 'select', + domId: 'wh-quick-mug', + domText: '光速跑路 ', + domSelectOpt: [ + { + domVal: 'leave', + domText: '跑路(LEAVE)', + }, + { + domVal: 'mug', + domText: '打劫(MUG)', + }, + { + domVal: 'hosp', + domText: '住院(HOSP)', + }, + { + domVal: 'none', + domText: '关闭', + }, + ], + dictName: 'quickFinishAtt', + isHide: true, + tip: '将结束后指定按钮移动到上面指定的格子上', + }); + // 攻击链接转跳 + setting_list.push({ + domType: 'checkbox', + domId: 'wh-attack-relocate', + domText: ' 真·攻击界面转跳', + dictName: 'attRelocate', + tip: '在无法打开攻击界面的情况下依然可以转跳到正确的攻击页面', + isHide: true, + }); + + // 飞行 + setting_list.push({ + domType: 'plain', + domId: '', + domHTML: '飞行', + tagName: 'h4', + }); + // 起飞警告 + setting_list.push({ + domType: 'checkbox', + domId: 'wh-energy-alert', + domText: ' 起飞爆E警告', + dictName: 'energyAlert', + tip: '起飞前计算来回是否会爆体,红字警告', + isHide: true, + }); + // 飞行闹钟 + setting_list.push({ + domType: 'checkbox', + domId: 'wh-trv-alarm-check', + domText: ' 飞行闹钟', + dictName: 'trvAlarm', + tip: '(仅PC) 飞行页面将显示一个内建的闹钟,落地前声音提醒,需要打开浏览器声音权限', + isHide: true, + }); + // 外海警告 + setting_list.push({ + domType: 'checkbox', + domId: '', + domText: ' 外海警告', + dictName: 'abroadWarning', + tip: '海外落地后每30秒通知警告', + }); + + // 公司 + setting_list.push({ + domType: 'plain', + domId: '', + domHTML: '公司', + tagName: 'h4', + }); + // 浮动存钱框 + setting_list.push({ + domType: 'checkbox', + domId: '', + domText: ' 浮动存钱框', + dictName: 'floatDepo', + tip: '打开公司或帮派的存钱页面后存钱框将浮动显示', + }); + // 公司转跳存钱 + setting_list.push({ + domType: 'checkbox', + domId: '', + domText: ' 公司转跳存钱', + dictName: 'companyRedirect', + tip: '打开公司页面时自动打开存钱选项卡', + }); + // 收起公司冰蛙效率表 + setting_list.push({ + domType: 'checkbox', + domId: '', + domText: ' 收起公司冰蛙效率表', + dictName: 'companyBWCollapse', + tip: '开启后可手动显示隐藏冰蛙公司表格', + }); + + // 啤酒 + setting_list.push({ + domType: 'plain', + domId: '', + domHTML: '啤酒', + tagName: 'h4', + }); + // 啤酒提醒 + setting_list.push({ + domType: 'checkbox', + domId: 'wh-qua-alarm-check', + domText: ' 啤酒提醒 ', + dictName: '_15Alarm', + tip: '每小时的整15分钟的倍数时通知提醒抢啤酒或者血包', + isHide: true, + changeEv: function (ev) { + ev.target.checked ? beer.start() : beer.stop(); + }, + }); + // 啤酒提醒状态 + setting_list.push({ + domType: 'button', + domId: '', + domText: '啤酒提醒状态', + clickFunc: function () { + WHNotify(`啤酒提醒${beer.status()}`); + } + }); + // 啤酒提醒时间 + setting_list.push({ + domType: 'button', + domId: '', + domText: '啤酒提醒时间设定', + // tip: '通知提前时间', + clickFunc: function () { + popup_node.close(); + let popup = popupMsg(`区间为 1 ~ 60,默认 50
`, '啤酒提醒时间设定'); + let confirm = document.createElement('button'); + confirm.innerHTML = '确定'; + confirm.style.float = 'right'; + confirm.addEventListener('click', () => { + let input = popup.querySelector('input'); + let num = input.value | 0; + if (num === getWhSettingObj()['_15AlarmTime']) return; + if (num < 1 || num > 60) num = 50; + input.value = num.toString(); + setWhSetting('_15AlarmTime', num); + // 之前的运行状态 + let before_state = beer.is_running(); + beer.set_time(num); + if (before_state) beer.start(); + popup.close(); }); - } - // 节日 - let fest_date_html = ': '; - { - const fest_date_dict = { - '0105': { name: '周末自驾游', eff: '获得双倍的赛车点数与赛车技能等级增益' }, - '0114': { name: '情人节', eff: '使用爱情果汁(Love Juice)后获得降低攻击与复活的能量消耗的增益' }, - '0204': { name: '员工激励日', eff: '获得三倍的工作点数与火车增益' }, - '0217': { name: '圣帕特里克日', eff: '获得双倍的酒类效果增益,城市中可以捡到绿色世涛(Green Stout)' }, - '0320': { name: '420日', eff: '获得三倍的大麻(Cannabis)效果增益' }, - '0418': { name: '博物馆日', eff: '获得10%提高的博物馆PT兑换增益' }, - '0514': { name: '世界献血日', eff: '获得减半的抽血CD和扣血增益' }, - '0611': { name: '世界人口日', eff: '获得双倍的通过攻击获取的经验的增益' }, - '0629': { name: '世界老虎日', eff: '获得5倍的狩猎技能增益' }, - '0705': { name: '国际啤酒节', eff: '获得5倍的啤酒物品效果增益' }, - '0827': { name: '旅游节', eff: '获得双倍的起飞后物品携带容量增益' }, - '0915': { name: '饮料节', eff: '获得双倍的能量饮料效果增益' }, - '1014': { name: '世界糖尿病日', eff: '获得三倍的糖类效果增益' }, - '1015': { name: '周年庆', eff: '左上角的TORN图标可以食用' }, - '1025': { name: '黑色星期五', eff: '某些商家将提供1元购活动' }, - '1114': { name: '住院日', eff: '获得降低75%的住院时间增益' }, - }; - menu_list.fest_date_dict = fest_date_dict; - menu_list.fest_date_list = Object.keys(fest_date_dict); - const formatMMDD = (m, d) => { - const MM = m < 10 ? `0${m}` : m.toString(); - const DD = d < 10 ? `0${d}` : d.toString(); - return MM + DD; - } - const fest_date_key = formatMMDD(date.getUTCMonth(), date.getUTCDate()); - if (fest_date_dict[fest_date_key]) fest_date_html += `今天 - ${fest_date_dict[fest_date_key]['name']}()`; - else { - // 月日列表 - let fest_date_list = Object.keys(fest_date_dict); - fest_date_list.push(fest_date_key); - // 下个节日的位置 - const next_fest_date_index = fest_date_list.sort().indexOf(fest_date_key) + 1; - // 下个节日obj - const next_fest_date = fest_date_dict[fest_date_list[next_fest_date_index] || fest_date_list[0]]; - // 下个节日的时间 - const days_left = (new Date( - next_fest_date_index !== fest_date_list.length ? date.getUTCFullYear() : date.getUTCFullYear() + 1, - fest_date_list[next_fest_date_index !== fest_date_list.length ? next_fest_date_index : 0].slice(0, 2) / 1, - fest_date_list[next_fest_date_index !== fest_date_list.length ? next_fest_date_index : 0].slice(2) / 1, - 8 - ) - date) / 86400000 | 0; - fest_date_html += `${days_left}天后 - ${next_fest_date.name}()`; - } - } - menu_list.push({ - domType: 'plain', - domId: 'wh-trans-fest-date', - domHTML: fest_date_html, - }); - // 活动 - let eventObj = { - onEv: false, - daysLeft: Infinity, - events: [ + popup.appendChild(confirm); + }, + }); + + // 其他 + setting_list.push({ + domType: 'plain', + domId: '', + domHTML: '其他', + tagName: 'h4', + }); + // 任务助手 + setting_list.push({ + domType: 'checkbox', + domId: 'wh-mission-lint', + domText: ' 任务助手', + dictName: 'missionHint', + tip: 'Duke任务的一些中文小提示', + isHide: true, + }); + // 捡垃圾助手 + setting_list.push({ + domType: 'checkbox', + domId: 'wh-city-finder', + domText: ' 捡垃圾助手', + dictName: 'cityFinder', + tip: '城市地图中放大显示物品并且估计价值', + isHide: true, + }); + // 快速crime + setting_list.push({ + domType: 'checkbox', + domId: 'wh-quick-crime', + domText: ' 快速犯罪', + dictName: 'quickCrime', + tip: '显示快捷操作按钮,目前不支持自定义', + isHide: true, + }); + // 叠E保护 + setting_list.push({ + domType: 'checkbox', + domId: 'wh-SEProtect-check', + domText: ' 叠E保护', + dictName: 'SEProtect', + tip: '隐藏健身房的锻炼按钮,防止误操作', + isHide: true, + }); + // PT一键购买 + setting_list.push({ + domType: 'checkbox', + domId: 'wh-ptQuickBuy-check', + domText: ' PT一键购买', + dictName: 'ptQuickBuy', + tip: 'PT市场页面购买时跳过确认', + isHide: true, + }); + // 4条转跳 + setting_list.push({ + domType: 'checkbox', + domId: '', + domText: ' 4条转跳', + dictName: 'barsRedirect', + tip: '点击4条时转跳对应页面', + }); + // 清除多余的脚本 + setting_list.push({ + domType: 'checkbox', + domId: '', + domText: ' 清除多余的脚本', + dictName: 'removeScripts', + tip: '清除Google相关脚本、顶部横幅等', + }); + // 危险行为⚠️ + if (getWhSettingObj()['dangerZone'] === true) { + // 攻击界面自刷新 + setting_list.push({ + domType: 'select', + domId: 'wh-attack-reload', + domText: '⚠️攻击界面自动刷新 ', + dictName: 'attReload', + domSelectOpt: [ { - start: [0, 17, 8], end: [0, 24, 8], - name: '捡垃圾周', - eff: '获得捡垃圾概率提升的增益', + domVal: 'none', + domText: '无间隔', }, { - start: [3, 5, 20], end: [3, 25, 20], - name: '复活节狩猎', - eff: '复活节彩蛋会随机出现,集齐10个可兑换金蛋和一个独特的头像框(章)。', + domVal: '1', + domText: '约1s', }, { - start: [5, 20, 20], end: [5, 29, 20], - name: '狗牌', - eff: '击败其他玩家以获得狗牌,小心保护你的狗牌。', + domVal: '2', + domText: '约2s', }, { - start: [6, 5, 20], end: [6, 25, 20], - name: '托恩先生和托恩女士', - eff: '上传你的真实图片,然后拿章', + domVal: '3', + domText: '约3s', }, { - start: [8, 5, 20], end: [8, 23, 20], - name: '大逃杀', - eff: '加入特定队伍后,攻击其他队伍玩家,存活下来的3个队伍可以拿章', + domVal: '4', + domText: '约4s', }, { - start: [9, 25, 20], end: [10, 1, 20], - name: '不给糖就捣蛋', - eff: '买篮子之后攻击其他玩家后会随机掉落糖果,可用于兑换许多高价值物品', + domVal: '5', + domText: '约5s', }, { - start: [11, 14, 20], end: [11, 31, 20], - name: '圣诞小镇', - eff: '在小镇中闲逛来获取随机掉落的物品', + domVal: 'disabled', + domText: '关闭', }, ], - }; - menu_list.events = eventObj.events; - eventObj.events.forEach((obj, index) => { - if (eventObj.onEv) return; - // 当前年份 - const nowYear = date.getFullYear(); - // 当前遍历的活动开始时间 - const start = new Date(nowYear, obj.start[0], obj.start[1], obj.start[2]); - // 当前遍历的活动结束时间 - const end = new Date(nowYear, obj.end[0], obj.end[1], obj.end[2]); - // 当前处于活动中 - if (start < date && date < end) { - eventObj.onEv = true; - eventObj.daysLeft = (end - date) / 86400000 | 0; - eventObj.current = obj; - } - // 当前没有活动 - else { - // 当前遍历的活动如果已经经过了,那么下次活动就是遍历的下一个活动对象,否则为当前活动。 - // 如果本年度活动都经过了,那么下次活动是列表的第一个活动对象 - const next = end < date ? eventObj.events[index + 1] || eventObj.events[0] : obj; - // 经过了最后一个活动所以下次活动开始时间是第二年 - const start = new Date(next !== obj && index === eventObj.events.length - 1 ? nowYear + 1 : nowYear, next.start[0], next.start[1], next.start[2]); - const daysLeft = (start - date) / 86400000 | 0; - if (0 <= daysLeft && daysLeft < eventObj.daysLeft) { - eventObj.daysLeft = daysLeft; - eventObj.next = next; - } - } + isHide: true, + tip: '危险功能:接机时常用,将自动刷新页面直到目标落地', }); - eventObj.html = ': '; - eventObj.onEv - ? eventObj.html += `${eventObj.current.name}() - 剩余${eventObj.daysLeft}天` - : eventObj.html += `${eventObj.daysLeft}天后 - ${eventObj.next.name}()`; + // 自动开打和结束 + setting_list.push({ + domType: 'checkbox', + domId: 'wh-auto-start-finish', + domText: ' ⚠️自动开打和结束', + dictName: 'autoStartFinish', + tip: '脚本将会自动按下战斗和结束按钮', + isHide: true, + }); + } else { + setWhSetting('autoStartFinish', false, false) + setWhSetting('attReload', 6, false) + } + // dev + setting_list.push({ + domType: 'checkbox', + domId: 'wh-dev-mode', + domText: ` 开发者模式${isDev() ? ' ' : ''}`, + dictName: 'isDev', + isHide: true, + }); + // 更多设定 + if (isDev()) setting_list.push({ + domType: 'button', domId: 'wh-otherBtn', domText: '更多设定', clickFunc: () => { + const html = `清空设置数据、请求通知权限、测试跨域请求`; + const popup = popupMsg(html, '更多设定'); + }, + isHide: true, + }); + // endregion + // region 菜单中的「选项」 + const menu_list = []; + //const date = new Date(2022, 2, 4, 23); + + // 欢迎 显示玩家id + if (player_info.userID !== 0) { menu_list.push({ domType: 'plain', - domId: 'wh-trans-event-cont', - domHTML: eventObj.html, + domId: 'wh-trans-welcome', + domHTML: `欢迎 ${player_info.playername}[${player_info.userID}] 大佬`, }); - // 飞花库存 - menu_list.push({ - domType: 'button', - domId: 'wh-foreign-stock-btn', - domText: '🌸 飞花库存', - clickFunc: async function (e) { - e.target.blur(); - forStock().then(); + } + // 节日 + let fest_date_html = ': '; + { + const fest_date_dict = { + '0105': { name: '周末自驾游', eff: '获得双倍的赛车点数与赛车技能等级增益' }, + '0114': { name: '情人节', eff: '使用爱情果汁(Love Juice)后获得降低攻击与复活的能量消耗的增益' }, + '0204': { name: '员工激励日', eff: '获得三倍的工作点数与火车增益' }, + '0217': { name: '圣帕特里克日', eff: '获得双倍的酒类效果增益,城市中可以捡到绿色世涛(Green Stout)' }, + '0320': { name: '420日', eff: '获得三倍的大麻(Cannabis)效果增益' }, + '0418': { name: '博物馆日', eff: '获得10%提高的博物馆PT兑换增益' }, + '0514': { name: '世界献血日', eff: '获得减半的抽血CD和扣血增益' }, + '0611': { name: '世界人口日', eff: '获得双倍的通过攻击获取的经验的增益' }, + '0629': { name: '世界老虎日', eff: '获得5倍的狩猎技能增益' }, + '0705': { name: '国际啤酒节', eff: '获得5倍的啤酒物品效果增益' }, + '0827': { name: '旅游节', eff: '获得双倍的起飞后物品携带容量增益' }, + '0915': { name: '饮料节', eff: '获得双倍的能量饮料效果增益' }, + '1014': { name: '世界糖尿病日', eff: '获得三倍的糖类效果增益' }, + '1015': { name: '周年庆', eff: '左上角的TORN图标可以食用' }, + '1025': { name: '黑色星期五', eff: '某些商家将提供1元购活动' }, + '1114': { name: '住院日', eff: '获得降低75%的住院时间增益' }, + }; + menu_list.fest_date_dict = fest_date_dict; + menu_list.fest_date_list = Object.keys(fest_date_dict); + const formatMMDD = (m, d) => { + const MM = m < 10 ? `0${m}` : m.toString(); + const DD = d < 10 ? `0${d}` : d.toString(); + return MM + DD; + } + const fest_date_key = formatMMDD(date.getUTCMonth(), date.getUTCDate()); + if (fest_date_dict[fest_date_key]) fest_date_html += `今天 - ${fest_date_dict[fest_date_key]['name']}()`; + else { + // 月日列表 + let fest_date_list = Object.keys(fest_date_dict); + fest_date_list.push(fest_date_key); + // 下个节日的位置 + const next_fest_date_index = fest_date_list.sort().indexOf(fest_date_key) + 1; + // 下个节日obj + const next_fest_date = fest_date_dict[fest_date_list[next_fest_date_index] || fest_date_list[0]]; + // 下个节日的时间 + const days_left = (new Date( + next_fest_date_index !== fest_date_list.length ? date.getUTCFullYear() : date.getUTCFullYear() + 1, + fest_date_list[next_fest_date_index !== fest_date_list.length ? next_fest_date_index : 0].slice(0, 2) / 1, + fest_date_list[next_fest_date_index !== fest_date_list.length ? next_fest_date_index : 0].slice(2) / 1, + 8 + ) - date) / 86400000 | 0; + fest_date_html += `${days_left}天后 - ${next_fest_date.name}()`; + } + } + menu_list.push({ + domType: 'plain', + domId: 'wh-trans-fest-date', + domHTML: fest_date_html, + }); + // 活动 + let eventObj = { + onEv: false, + daysLeft: Infinity, + events: [ + { + start: [0, 17, 8], end: [0, 24, 8], + name: '捡垃圾周', + eff: '获得捡垃圾概率提升的增益', }, - }); - // 一键起飞 - menu_list.push({ - domType: 'button', - domId: 'wh-quick-fly-btn', - domText: '✈️ 一键起飞', - clickFunc: async function () { - if (window.hasWHQuickFlyOpt) return; - window.hasWHQuickFlyOpt = true; - addStyle(`#wh-quick-fly-opt{ + { + start: [3, 5, 20], end: [3, 25, 20], + name: '复活节狩猎', + eff: '复活节彩蛋会随机出现,集齐10个可兑换金蛋和一个独特的头像框(章)。', + }, + { + start: [5, 20, 20], end: [5, 29, 20], + name: '狗牌', + eff: '击败其他玩家以获得狗牌,小心保护你的狗牌。', + }, + { + start: [6, 5, 20], end: [6, 25, 20], + name: '托恩先生和托恩女士', + eff: '上传你的真实图片,然后拿章', + }, + { + start: [8, 5, 20], end: [8, 23, 20], + name: '大逃杀', + eff: '加入特定队伍后,攻击其他队伍玩家,存活下来的3个队伍可以拿章', + }, + { + start: [9, 25, 20], end: [10, 1, 20], + name: '不给糖就捣蛋', + eff: '买篮子之后攻击其他玩家后会随机掉落糖果,可用于兑换许多高价值物品', + }, + { + start: [11, 14, 20], end: [11, 31, 20], + name: '圣诞小镇', + eff: '在小镇中闲逛来获取随机掉落的物品', + }, + ], + }; + menu_list.events = eventObj.events; + eventObj.events.forEach((obj, index) => { + if (eventObj.onEv) return; + // 当前年份 + const nowYear = date.getFullYear(); + // 当前遍历的活动开始时间 + const start = new Date(nowYear, obj.start[0], obj.start[1], obj.start[2]); + // 当前遍历的活动结束时间 + const end = new Date(nowYear, obj.end[0], obj.end[1], obj.end[2]); + // 当前处于活动中 + if (start < date && date < end) { + eventObj.onEv = true; + eventObj.daysLeft = (end - date) / 86400000 | 0; + eventObj.current = obj; + } + // 当前没有活动 + else { + // 当前遍历的活动如果已经经过了,那么下次活动就是遍历的下一个活动对象,否则为当前活动。 + // 如果本年度活动都经过了,那么下次活动是列表的第一个活动对象 + const next = end < date ? eventObj.events[index + 1] || eventObj.events[0] : obj; + // 经过了最后一个活动所以下次活动开始时间是第二年 + const start = new Date(next !== obj && index === eventObj.events.length - 1 ? nowYear + 1 : nowYear, next.start[0], next.start[1], next.start[2]); + const daysLeft = (start - date) / 86400000 | 0; + if (0 <= daysLeft && daysLeft < eventObj.daysLeft) { + eventObj.daysLeft = daysLeft; + eventObj.next = next; + } + } + }); + eventObj.html = ': '; + eventObj.onEv + ? eventObj.html += `${eventObj.current.name}() - 剩余${eventObj.daysLeft}天` + : eventObj.html += `${eventObj.daysLeft}天后 - ${eventObj.next.name}()`; + menu_list.push({ + domType: 'plain', + domId: 'wh-trans-event-cont', + domHTML: eventObj.html, + }); + // 飞花库存 + menu_list.push({ + domType: 'button', + domId: 'wh-foreign-stock-btn', + domText: '🌸 飞花库存', + clickFunc: async function (e) { + e.target.blur(); + forStock().then(); + }, + }); + // 一键起飞 + menu_list.push({ + domType: 'button', + domId: 'wh-quick-fly-btn', + domText: '✈️ 一键起飞', + clickFunc: async function () { + if (window.hasWHQuickFlyOpt) return; + window.hasWHQuickFlyOpt = true; + addStyle(`#wh-quick-fly-opt{ position:fixed; left:64px; top:64px; @@ -3494,9 +3492,9 @@ display: inline-block; } info{display:block;} `); - const node = document.createElement('div'); - node.id = 'wh-quick-fly-opt'; - node.innerHTML = ` + const node = document.createElement('div'); + node.id = 'wh-quick-fly-opt'; + node.innerHTML = `主要用途:出院秒飞
点起飞,页面加载完成后会马上飞走
@@ -3509,61 +3507,61 @@ info{display:block;}点击开打:
+ }); + node.querySelector('a').addEventListener('click', (e) => { + e.preventDefault(); + forStock(); + }); + node.querySelector('input').addEventListener('click', (e) => { + node.classList.toggle('wh-quick-fly-opt-hide'); + const el = e.target; + el.value = el.value === ' - ' ? ' + ' : ' - '; + }); + const info_node = node.querySelector('info'); + const time_predict = document.createElement('p'); + const yaoCD = document.createElement('p'); + info_node.append(time_predict); + info_node.append(yaoCD); + const predict = [ + ['~54分', '~36分', '~26分', '~16分',], + ['~1时10分', '~50分', '~36分', '~22分',], + ['~1时22分', '~58分', '~40分', '~24分',], + ['~4时28分', '~3时8分', '~2时14分', '~1时20分',], + ['~5时18分', '~3时42分', '~2时40分', '~1时36分',], + ['~5时34分', '~3时54分', '~2时46分', '~1时40分',], + ['~5时50分', '~4时6分', '~2时56分', '~1时46分',], + ['~7时30分', '~5时16分', '~3时46分', '~2时16分',], + ['~8时4分', '~5时38分', '~4时2分', '~2时24分',], + ['~9时2分', '~6时20分', '~4时30分', '~2时42分',], + ['~9时54分', '~6时56分', '~4时58分', '~2时58分',], + ]; + const showTime = function () { + time_predict.innerHTML = `往返时间:${predict[dest_node.selectedIndex][type_node.selectedIndex]}`; + } + dest_node.addEventListener('change', showTime); + type_node.addEventListener('change', showTime); + document.body.append(node); + showTime(); + yaoCD.innerHTML = `药CD剩余:${getYaoCD()}`; + }, + }); + // NPC LOOT + menu_list.push({ + domType: 'button', + domId: 'wh-npc-loot-btn', + domText: '🔫 LOOT', + clickFunc: function (e) { + e.target.blur(); + const insert = `点击开打:
})
'; + quick_link_dict.forEach(el => { + insert += `${el.name}`; + }); + insert += '
' + let popup = popupMsg(insert, '常用链接'); + popup.classList.add('wh-link-collection-cont'); + popup.addEventListener('click', ev => { + if (ev.target.tagName.toLowerCase() === 'a' || ev.target.tagName.toLowerCase() === 'span') { + popup.close(); } - e.target.blur(); - const quick_link_dict = []; - // 生存手册 - quick_link_dict.push({ - name: '生存手册', - url: 'https://docs.qq.com/doc/DTVpmV2ZaRnB0RG56', - new_tab: true, - img: 'https://www.torn.com/images/items/293/medium.png', - }); - // 买啤酒 - quick_link_dict.push({ - name: '抢啤酒', - url: 'https://www.torn.com/shops.php?step=bitsnbobs', - new_tab: true, - img: 'https://www.torn.com/images/items/180/medium.png', - }); - // 买XAN - quick_link_dict.push({ - name: '买XAN', - url: 'https://www.torn.com/imarket.php#/p=shop&step=shop&type=&searchname=Xanax', - new_tab: true, - img: 'https://www.torn.com/images/items/206/medium.png', - }); - // 起飞 - quick_link_dict.push({ - name: '起飞', - url: 'https://www.torn.com/travelagency.php', - new_tab: true, - img: 'https://www.torn.com/images/items/396/medium.png', - }); - // 买PT - quick_link_dict.push({ - name: '买PT', - url: 'https://www.torn.com/pmarket.php', - new_tab: true, - img: 'https://www.torn.com/images/items/722/medium.png', - }); - // 租PI - quick_link_dict.push({ - name: '租PI', - url: 'https://www.torn.com/properties.php?step=rentalmarket#/property=13', - new_tab: false, - img: 'https://www.torn.com/images/v2/properties/350x230/350x230_default_private_island.png', - }); - // 找工作 - quick_link_dict.push({ - name: '找工作', - url: 'https://www.torn.com/joblist.php#!p=main', - new_tab: false, - img: 'https://www.torn.com/images/items/421/medium.png', - }); - // 下悬赏 - quick_link_dict.push({ - name: '下悬赏', - url: 'https://www.torn.com/bounties.php#/p=add', - new_tab: false, - img: 'https://www.torn.com/images/items/431/medium.png', - }); - let insert = ''; - quick_link_dict.forEach(el => { - insert += `${el.name}`; - }); - insert += '
' - let popup = popupMsg(insert, '常用链接'); - popup.classList.add('wh-link-collection-cont'); - popup.addEventListener('click', ev => { - if (ev.target.tagName.toLowerCase() === 'a' || ev.target.tagName.toLowerCase() === 'span') { - popup.close(); - } - }); - }, - }); - // 飞贼 - menu_list.push({ - domType: 'button', - domId: 'wh-gs-btn', - domText: '🐏 飞贼小助手', - clickFunc: function (e) { - e.target.blur(); - loadGS(getScriptEngine()); - }, - tip: '加载从PC端移植的伞佬的油猴版飞贼小助手', - }); - // 物品价格监视 - menu_list.push({ - domType: 'button', - domId: 'wh-price-watcher-btn', - domText: '💊 价格监视', - clickFunc: function () { - const watcher_conf = getWhSettingObj()['priceWatcher']; - const pre_str = JSON.stringify(watcher_conf); - const html = ` @@ -3791,36 +3789,36 @@ background-size: 100% auto !important;XAN
`; - const popup = popupMsg(html, '价格监视设置'); - popup.querySelector('button').onclick = () => { - const [pt_node, xan_node] = popup.querySelectorAll('input[type="number"]'); - watcher_conf.pt = pt_node.value | 0; - watcher_conf.xan = xan_node.value | 0; - if (JSON.stringify(watcher_conf) !== pre_str) setWhSetting('priceWatcher', watcher_conf); - popup.close(); - }; - } - }); - // 小窗犯罪 - menu_list.push({ - domType: 'button', - domId: 'wh-crime-iframe-btn', - domText: '🤑 小窗犯罪', - clickFunc: function () { - // 弹出小窗口 - const ifHTML = ``; - const popup_insert = `加载中请稍后${loading_gif_html()}
`; - const $popup = popupMsg(popup_insert, '小窗快速犯罪'); - // 运行状态node - let loading_node = $popup.querySelector('p:first-of-type'); - // if容器 - const if_cont = $popup.querySelector('#wh-quick-crime-if-container'); - if_cont.innerHTML = ifHTML; + const popup = popupMsg(html, '价格监视设置'); + popup.querySelector('button').onclick = () => { + const [pt_node, xan_node] = popup.querySelectorAll('input[type="number"]'); + watcher_conf.pt = pt_node.value | 0; + watcher_conf.xan = xan_node.value | 0; + if (JSON.stringify(watcher_conf) !== pre_str) setWhSetting('priceWatcher', watcher_conf); + popup.close(); + }; + } + }); + // 小窗犯罪 + menu_list.push({ + domType: 'button', + domId: 'wh-crime-iframe-btn', + domText: '🤑 小窗犯罪', + clickFunc: function () { + // 弹出小窗口 + const ifHTML = ``; + const popup_insert = `加载中请稍后${loading_gif_html()}
`; + const $popup = popupMsg(popup_insert, '小窗快速犯罪'); + // 运行状态node + let loading_node = $popup.querySelector('p:first-of-type'); + // if容器 + const if_cont = $popup.querySelector('#wh-quick-crime-if-container'); + if_cont.innerHTML = ifHTML; - // if内未加载脚本时插入的快捷crime node - const mobile_prepend_node = document.createElement('div'); - mobile_prepend_node.classList.add('wh-translate'); - mobile_prepend_node.innerHTML = `即将打开危险功能,使用这些功能可能会造成账号封禁。请自行考虑是否使用。
+ // 超时判断 + let time_counter = 0; + let time_out_id = window.setInterval(() => { + loading_node = $popup.querySelector('p:first-of-type'); + if (!loading_node) { + clearInterval(time_out_id); + time_out_id = undefined; + return; + } + time_counter++; + if (time_counter > 0 && !loading_node.querySelector('button')) { + const reload_btn = document.createElement('button'); + reload_btn.innerHTML = '重新加载'; + reload_btn.onclick = () => { + reload_btn.remove(); + time_counter = 0; + if_cont.innerHTML = null; + if_cont.innerHTML = ifHTML; + cIframe = $popup.querySelector('iframe'); + cIframe.onload = if_onload_func; + }; + loading_node.append(reload_btn); + } + }, 1000); + } + }); + // 危险行为开关⚠️ + menu_list.push({ + domType: 'button', + domId: 'wh-danger-zone', + domText: '⚠️ 危险功能', + clickFunc: function (e) { + e.target.blur(); + const insert = `即将打开危险功能,使用这些功能可能会造成账号封禁。请自行考虑是否使用。
`; - const popup = popupMsg(insert, '⚠️警告'); - const warning_check = popup.querySelector('input'); - const ok_btn = popup.querySelector('button'); - warning_check.onchange = () => ok_btn.disabled = false; - ok_btn.onclick = () => { - setWhSetting('dangerZone', warning_check.checked); - popup['close'](); - window.location.reload(); - }; - }, - }); - // 传单助手 - menu_list.push({ - domType: 'button', - domId: '', - domText: '📜️ 传单助手', - clickFunc: adHelper - }); - // 守望者 - menu_list.push({ - domType: 'button', - domId: '', - domText: '🛡️ 守望者', - clickFunc: function () { - safeKeeper(); - }, - }); - // 更新历史 - menu_list.push({ - domType: 'button', domId: '', domText: '🐞 更新历史', clickFunc: () => { - popupMsg('更新历史现已迁移:| URL | ${window.location.href} |
| 页面尺寸 | ${window.innerWidth}x${window.innerHeight} |
| 设备类型 | ${getDeviceType().toUpperCase()} |