当前版本: ${ version.slice(-1) === '$' ? 'DEV' : version }
最新版本:
通常电脑浏览器装有油猴等用户脚本扩展时可以使用链接安装(自动更新):点此安装。
+这些扩展长这样:

安卓 KIWI 等可以用油猴脚本的浏览器也可以点上面的链接安装👆
+Torn PDA app 或 Alook 用户可打开这个网页快捷复制粘贴。
+加载脚本然后直接复制粘贴到用户脚本处。
+ +`; + const node = popupMsg(innerHtml, '如何更新'); + // 直接复制的按钮 + node.querySelector('button').onclick = async (e) => { + let target = e.target as HTMLButtonElement; + target.innerHTML = '加载中'; + const js_text = await COFetch(`https://jjins.github.io/fyfuzhi/release.min.user.js?${ performance.now() }`); + target.innerHTML = '点击复制到剪切板'; + target.onclick = () => { + const textarea_node = document.createElement('textarea'); + textarea_node.innerHTML = js_text; + target.parentElement.append(textarea_node); + textarea_node.focus(); + textarea_node.select(); + document.execCommand('Copy'); + textarea_node.remove(); + target.innerHTML = '已复制'; + target.onclick = null; + WHNotify('脚本已复制,请前往粘贴'); + }; + }; + }; + // 节日 + zhong_node.querySelectorAll('#wh-trans-fest-date button').forEach((el, i) => i === 0 + ? el.addEventListener('click', () => { + let html = '| ${ 1 + (( | ${ settings.fest_date_dict[date].name } | ${ settings.fest_date_dict[date].eff } |
| ${ el.name } | ${ el.start[0] + 1 }月${ el.start[1] }日${ el.start[2] }:00~${ el.end[0] + 1 }月${ el.end[1] }日${ el.end[2] }:00 |
| ${ el.eff } | |
更多信息请关注群聊和公众号
', '活动'); + }) + : el.addEventListener('click', null)); + document.body.append(zhong_node); + // 引入torn自带浮动提示 + // (window['initializeTooltip']) && (window['initializeTooltip']('.wh-container', 'white-tooltip')); + Log.info(WuhuBase.glob); + WuhuBase.glob.unsafeWindow.initializeTooltip('.wh-container', 'white-tooltip'); + // 加载torn mini profile + WuhuBase.glob.unsafeWindow.initMiniProf('#wh-trans-icon'); + ZhongIcon.ZhongNode = zhong_node; + return zhong_node; + } + + // 菜单 + static getMenuItems(): MenuItemConfig[] { + let glob = WuhuBase.glob; + const date = new Date(); + + const menu_list: MenuItemConfig[] = []; + + // 欢迎 显示玩家id + if (glob.player_info.userID !== 0) { + menu_list.push({ + domType: 'plain', + domId: 'wh-trans-welcome', + domHTML: `欢迎 ${ glob.player_info.playername }[${ glob.player_info.userID }] 大佬`, + }); + } + // 节日 + let fest_date_html = ': '; + { + // 节日字典 + const 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 = dict; + menu_list.fest_date_list = Object.keys(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 (dict[fest_date_key]) fest_date_html += `今天 - ${ dict[fest_date_key]['name'] }()`; + else { + // 月日列表 + let list = Object.keys(dict); + list.push(fest_date_key); + // 下个节日的位置 + const index: number = list.sort().indexOf(fest_date_key) + 1; + // 下个节日obj + const next_fest_date = dict[list[index] || list[0]]; + // 下个节日的时间 + let next = new Date( + index !== list.length ? date.getUTCFullYear() : date.getUTCFullYear() + 1, + (list[index !== list.length ? index : 0] as any).slice(0, 2) | 0, + (list[index !== list.length ? index : 0] as any).slice(2) | 0, + 8 + ).getTime(); + // 剩余天数 + const left = (next - date.getTime()) / 86400000 | 0; + fest_date_html += `${ left }天后 - ${ next_fest_date.name }()`; + } + } + menu_list.push({ + domType: 'plain', + domId: 'wh-trans-fest-date', + domHTML: fest_date_html, + }); + // 活动 + let eventObj: EventWrapper = { + onEv: false, + daysLeft: Infinity, + events: [ + { + start: [0, 17, 8], end: [0, 24, 8], + name: '捡垃圾周', + eff: '获得捡垃圾概率提升的增益', + }, + { + 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.getTime() - date.getTime()) / 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.getTime() - date.getTime()) / 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; + background: #008000db; + padding: 8px; + border-radius: 4px; + box-shadow: 0 0 5px 1px #ffffff29; + color: white; + font-size: 15px; + width: 220px; + z-index: 199999; +} +#wh-quick-fly-opt p{margin:4px 0;} +#wh-quick-fly-opt a{ +cursor: pointer; + border: 1px solid; + padding: 4px; + display: inline-block; + border-radius: 2px; +} +#wh-quick-fly-opt label{ +display:block; +} +#wh-quick-fly-opt select{ +width: 100%; + padding: 6px; + margin: 4px 0; +} +#wh-quick-fly-opt button{ +font-size: 16px; + color: white; + cursor: pointer; + float: right; + background: #00BCD4; + padding: 8px; + border-radius: 4px; +} +#wh-quick-fly-opt.wh-quick-fly-opt-hide *{ +display: none; +} +#wh-quick-fly-opt.wh-quick-fly-opt-hide input{ +display: inline-block; +} +info{display:block;} +`); + const node = document.createElement('div'); + node.id = 'wh-quick-fly-opt'; + node.innerHTML = ` + +主要用途:出院秒飞
+点起飞,页面加载完成后会马上飞走
+点击开打:
+ })
NNB(Natural Nerve Bar)意思是:扣除所有加成后,玩家本身的犯罪条上限,可用于衡量大佬隐藏的犯罪技能等级
+一般来说,左侧红色的犯罪条(Nerve Bar/NB)的上限都是包含加成的,如来自帮派、天赋的加成等。额外的加成不会影响玩家的犯罪技能
+查看NNB的方法很简单,在Torn主页面的最下方有一栏Perks,NB-Perks=NNB
+以下是两种计算NNB的方法:
+ + +'; + quick_link_dict.forEach(el => { + insert += `${ el.name }`; + }); + insert += '
' + let popup = popupMsg(insert, '常用链接'); + popup.classList.add('wh-link-collection-cont'); + popup.addEventListener('click', ev => { + let target = ev.target as HTMLElement; + if (target.tagName.toLowerCase() === 'a' || 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 = ` +输入需要监视的价格,低于该价格发出通知,-1为关闭
+注:需要APIKey,当前可用APIKey为
+(来自冰蛙)
+(来自PDA)
+
PT
+XAN
+ +`; + const popup = popupMsg(html, '价格监视设置'); + popup.querySelector('button').onclick = () => { + const [pt_node, xan_node] = Array.from(加载中请稍后${ 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 = `即将打开危险功能,使用这些功能可能会造成账号封禁。请自行考虑是否使用。
+ +`; + 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: async () => { + let popup = popupMsg( + '更新历史:| URL | ${ window.location.href } |
| 页面尺寸 | ${ window.innerWidth }x${ window.innerHeight } |
| 设备类型 | ${ getDeviceType().toUpperCase() } |
| 脚本运行方式 | ${ { 'gm': '油猴', 'raw': '直接运行', 'pda': 'TornPDA' }[getScriptEngine()] } |
| 时间 | ${ date.getFullYear() }/${ date.getMonth() + 1 }/${ date.getDate() } ${ date.getHours() }:${ date.getMinutes() }:${ date.getSeconds() } |
| 插件版本 | ${ glob.version } |
| 操作系统 | ${ os } |
| UA | ${ window.navigator.userAgent } |
| 用户ID | ${ glob.player_info.userID } |
| 用户名 | ${ glob.player_info.playername } |
区间为 1 ~ 60,默认 50
`, '啤酒提醒时间设定'); + let confirm = document.createElement('button'); + confirm.innerHTML = '确定'; + confirm.style.float = 'right'; + confirm.addEventListener('click', () => { + let input: HTMLInputElement = popup.querySelector('input'); + let num = (input.value as any) | 0; + if (num === getWhSettingObj()['_15AlarmTime']) return; + if (num < 1 || num > 60) num = 50; + input.value = num.toString(); + setWhSetting('_15AlarmTime', num); + // 之前的运行状态 + let before_state = glob.beer.is_running(); + glob.beer.set_time(num); + if (before_state) glob.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: ` 开发者模式${ log.debug() ? ' ' : '' }`, + dictName: 'isDev', + isHide: true, + }); + // 更多设定 + if (log.debug()) setting_list.push({ + domType: 'button', domId: 'wh-otherBtn', domText: '更多设定', clickFunc: () => { + const html = `清空设置数据、请求通知权限、测试跨域请求`; + const popup = popupMsg(html, '更多设定'); + }, + isHide: true, + }); + + return setting_list; + } + + // 默认设置 + static setDefaultSettings(): void { + [ + // 开启翻译 + { key: 'transEnable', val: false }, + // 快速犯罪 + { key: 'quickCrime', val: true }, + // 任务助手 + { key: 'missionHint', val: true }, + // 小镇攻略 + { key: 'xmasTownWT', val: true }, + // 小镇提醒 + { key: 'xmasTownNotify', val: true }, + // 起飞爆e + { key: 'energyAlert', val: true }, + // 飞行闹钟 + { key: 'trvAlarm', val: true }, + // 啤酒提醒 + { key: '_15Alarm', val: true }, + // 捡垃圾助手 + { key: 'cityFinder', val: false }, + // 叠E保护 + { key: 'SEProtect', val: false }, + // PT一键购买 + { key: 'ptQuickBuy', val: false }, + // 光速拔刀 6-关闭 + { key: 'quickAttIndex', val: 2 }, + // 光速跑路 0-leave 1-mug 2-hos 3-关闭 + { key: 'quickFinishAtt', val: 3 }, + // 自动开打和结束 + { key: 'autoStartFinish', val: false }, + // 废弃 + { key: 'attRelocate', val: true }, + // 攻击自刷新 0-无间隔 1-5s 6-关闭 + { key: 'attReload', val: 6 }, + // 价格监视 + { key: 'priceWatcher', val: { xan: -1, pt: -1 } }, + // 开发者模式 + { key: 'isDev', val: false }, + // 啤酒提醒时间 + { key: '_15AlarmTime', val: 50 }, + // 4条转跳 + { key: 'barsRedirect', val: true }, + // 浮动存钱框 + { key: 'floatDepo', val: true }, + // 公司转跳存钱 + { key: 'companyRedirect', val: true }, + // 收起公司冰蛙效率表 + { key: 'companyBWCollapse', val: true }, + // 清除多余的脚本 + { key: 'removeScripts', val: true }, + // 海外警告 + { key: 'abroadWarning', val: true }, + // 落地转跳 + { key: 'landedRedirect', val: '' }, + // 任何位置一键存钱 + { key: 'companyDepositAnywhere', val: false }, + + // 危险行为⚠️ + { key: 'dangerZone', val: false }, + ].forEach(df => { + if (typeof getWhSettingObj()[df.key] !== typeof df.val) setWhSetting(df.key, df.val); + }); + } + + static ZhongNode: MyHTMLElement = null; +} + +interface MenuItemConfig { + tagName?: string; + domType: 'button' | 'plain' | 'checkbox' | 'select'; + domId?: string; + domText?: string; + clickFunc?: (ev?) => void; + domHTML?: string; + tip?: string; + dictName?: string; + changeEv?: (ev) => void; + domSelectOpt?: { domVal: string, domText: string }[]; +} + +interface EventWrapper { + onEv: boolean; + daysLeft: number; + events: Event[]; + current?: Event; + next?: Event; + html?: string; +} + +interface Event { + start: number[]; + end: number[]; + name: string; + eff: string; +} \ No newline at end of file diff --git a/src/common.ts b/src/common.ts index 3e3c9cc..5cd40dd 100644 --- a/src/common.ts +++ b/src/common.ts @@ -1,11 +1,16 @@ -import Global from "./interface/GlobalVars"; import getWhSettingObj from "./func/utils/getWhSettingObj"; import elementReady from "./func/utils/elementReady"; import depoHelper from "./func/module/depoHelper"; import travelHelper from "./func/module/travelHelper"; import attackHelper from "./func/module/attackHelper"; +import priceWatcherHandle from "./func/module/priceWatcherHandle"; +import WuhuBase from "./class/WuhuBase"; + +export default function () { + let glob = WuhuBase.glob; + // 价格监控 + priceWatcherHandle(glob.isPDA, glob.PDA_APIKey); -export default function (glob: Global) { // 啤酒提醒 if (getWhSettingObj()['_15Alarm']) glob.beer.start(); @@ -65,11 +70,11 @@ export default function (glob: Global) { } // 存钱相关 - depoHelper(glob); + depoHelper(); // 飞行相关 - travelHelper(glob).then(); + travelHelper().then(); // 战斗相关 - attackHelper(glob).then(); + attackHelper().then(); } \ No newline at end of file diff --git a/src/dictionary/translation.ts b/src/dictionary/translation.ts index b85fc14..36b06ac 100644 --- a/src/dictionary/translation.ts +++ b/src/dictionary/translation.ts @@ -2697,5 +2697,3 @@ export const calDict = { // 中文字符集正则 export const CC_set = /[\u4e00-\u9fa5]/ // if (!localStorage.getItem('wh_trans_transDict')) localStorage.setItem('wh_trans_transDict', JSON.stringify(transDict)) - -export * from './translation' \ No newline at end of file diff --git a/src/func/module/attackHelper.ts b/src/func/module/attackHelper.ts index dcc1e82..19e8d79 100644 --- a/src/func/module/attackHelper.ts +++ b/src/func/module/attackHelper.ts @@ -1,14 +1,16 @@ import Device from "../../enum/Device"; -import Global from "../../interface/GlobalVars"; import elementReady from "../utils/elementReady"; import getWhSettingObj from "../utils/getWhSettingObj"; import addActionBtn from "../utils/addActionBtn"; import addStyle from "../utils/addStyle"; import getRandomInt from "../utils/getRandomInt"; import log from "../utils/log"; +import ZhongIcon from "../../class/ZhongIcon"; +import WuhuBase from "../../class/WuhuBase"; -export default async function attackHelper(glob: Global): Promise
`;
popupMsg(insert, '飞花库存');
} else {
@@ -57,7 +59,7 @@ export default async function forStock(glob) {
stocks: { 'African Violet': '花', 'Lion Plushie': '偶', 'Xanax': 'XAN' },
}];
const now = new Date();
- const res = await glob.fStock.get();
+ const res = await WuhuBase.glob.fStock.get();
if (!res['stocks']) return;
dest.forEach(el => {
const update = (now.getTime() - new Date(res.stocks[el.name]['update'] * 1000).getTime()) / 1000 | 0
diff --git a/src/func/utils/getPlayerInfo.ts b/src/func/utils/getPlayerInfo.ts
index acf8306..3864a3e 100644
--- a/src/func/utils/getPlayerInfo.ts
+++ b/src/func/utils/getPlayerInfo.ts
@@ -2,12 +2,10 @@
* 返回玩家信息的对象 user
* @return {PlayerInfo} rs
*/
-function getPlayerInfo(): PlayerInfo {
+export default function getPlayerInfo(): PlayerInfo {
const node = document.querySelector('script[uid]');
if (node) return {
playername: node.getAttribute('name'),
userID: node.getAttribute('uid') as unknown as number,
}
-}
-
-export default getPlayerInfo
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/src/func/utils/getScriptEngine.ts b/src/func/utils/getScriptEngine.ts
index 466ccb6..aca8983 100644
--- a/src/func/utils/getScriptEngine.ts
+++ b/src/func/utils/getScriptEngine.ts
@@ -1,8 +1,9 @@
import UserScriptEngine from "../../enum/UserScriptEngine";
-import Global from "../../interface/GlobalVars";
+import WuhuBase from "../../class/WuhuBase";
// 用户脚本平台类型
-export default function getScriptEngine(glob:Global) {
- return glob.UWCopy ? UserScriptEngine.GM : glob.isPDA
+export default function getScriptEngine() {
+ let glob = WuhuBase.glob;
+ return glob.unsafeWindow ? UserScriptEngine.GM : glob.isPDA
? UserScriptEngine.PDA : UserScriptEngine.RAW;
}
\ No newline at end of file
diff --git a/src/func/utils/getWhSettingObj.ts b/src/func/utils/getWhSettingObj.ts
index 77d6f8e..841b34e 100644
--- a/src/func/utils/getWhSettingObj.ts
+++ b/src/func/utils/getWhSettingObj.ts
@@ -1,4 +1,3 @@
-// 插件的配置 getter
export default function getWhSettingObj(): WHSettings {
return JSON.parse(localStorage.getItem('wh_trans_settings')) || {}
}
diff --git a/src/func/utils/log.ts b/src/func/utils/log.ts
index a95176a..efb8283 100644
--- a/src/func/utils/log.ts
+++ b/src/func/utils/log.ts
@@ -9,6 +9,9 @@ function debug() {
}
}
+/**
+ * @deprecated
+ */
const log = {
error: (...o) => (debug()) && (console.error('[WH]', ...o)),
info: (...o) => (debug()) && (console.log('[WH]', ...o)),
diff --git a/src/func/utils/popupMsg.ts b/src/func/utils/popupMsg.ts
index 1b97104..003851d 100644
--- a/src/func/utils/popupMsg.ts
+++ b/src/func/utils/popupMsg.ts
@@ -1,3 +1,6 @@
+import WuHuTornHelper from "../../class/WuhuTornHelper";
+import WuhuBase from "../../class/WuhuBase";
+
/**
* 弹出窗口
* @param {String} innerHTML 内容html string
@@ -5,7 +8,7 @@
* @returns {null|Element}
*/
export default function popupMsg(innerHTML, title = '芜湖助手') {
- let glob = window.WHPARAMS;
+ let glob = WuhuBase.glob;
if (glob.popup_node) glob.popup_node.close();
const chatRoot = document.querySelector('#chatRoot');
chatRoot.classList.add('wh-hide');
diff --git a/src/init.ts b/src/init.ts
index 85f7626..30fa290 100644
--- a/src/init.ts
+++ b/src/init.ts
@@ -1,255 +1,207 @@
-import log from "./func/utils/log";
-import getWhSettingObj from "./func/utils/getWhSettingObj";
-import miniprofTrans from "./func/translate/miniprofTrans";
-import Global from "./interface/GlobalVars";
-import Device from "./enum/Device";
-import getPlayerInfo from "./func/utils/getPlayerInfo";
-import autoFetchJSON from "./func/utils/autoFetchJSON";
-import priceWatcherHandle from "./func/utils/priceWatcherHandle";
-import BuyBeer from "./func/utils/BuyBeer";
-import WindowActiveState from "./func/utils/WindowActiveState";
-import addStyle from "./func/utils/addStyle";
-import COFetch from "./func/utils/COFetch";
-
-// 初始化方法,获取必要全局参数
-export default function init(): Global {
- let glob: Global = {
- window: window,
- UWCopy: window.unsafeWindow,
- version: '$$WUHU_DEV_VERSION$$',
- isIframe: self !== top,
- PDA_APIKey: '###PDA-APIKEY###',
- isPDA: false,
- device: window.innerWidth >= 1000 ? Device.PC : window.innerWidth <= 600 ? Device.MOBILE : Device.TABLET,
- player_info: getPlayerInfo(),
- fStock: autoFetchJSON('https://yata.yt/api/v1/travel/export/'),
- priceWatcher: null,
- beer: BuyBeer(),
- popup_node: null,
- notifies: { count: 0 },
- isWindowActive: WindowActiveState(),
- href: window.location.href,
- bodyAttrs: {},
- };
- glob.isPDA = glob.PDA_APIKey.slice(-1) !== '#';
- glob.priceWatcher = self !== top ? null : priceWatcherHandle(glob);
- let UWCopy = null;
- if (window.hasOwnProperty('unsafeWindow')) {
- UWCopy = window.unsafeWindow;
- try {
- window = UWCopy;
- } catch {
- }
- }
- window.WHPARAMS = glob;
-
- // 请求通知权限
- if (window.Notification && Notification.permission !== 'granted') {
- Notification.requestPermission().then();
- } else {
- log.info({ Notification });
- }
-
- // 扩展正则方法
- String.prototype.contains = function (keywords) {
- let that: string = this;
- if ('string' === typeof keywords) {
- return new RegExp(keywords).test(that);
- } else {
- return keywords.test(that);
- }
- };
-
- // 监听fetch
- const ori_fetch = window.fetch;
- window.fetch = async (url: string, init: RequestInit) => {
- 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.info({ url, init, text });
- return clone;
- };
-
- // 当窗口关闭时关闭所有还存在的通知
- window.addEventListener(
- 'beforeunload',
- () => {
- if (glob.notifies.count !== 0) {
- for (let i = 0; i < glob.notifies.count; i++) {
- (glob.notifies[i] !== null) && (glob.notifies[i].close())
- }
- }
- }
- );
-
- addStyle(`
-.wh-hide{display:none;}
-#wh-trans-icon{
-user-select:none;
-display: inline-block;
-position: fixed;
-top:5px;
-left:5px;
-z-index:100010;
-border-radius:4px;
-max-width: 220px;
-box-shadow: 0 0 3px 1px #8484848f;
-}
-div#effectiveness-wrap{overflow-y:hidden;}
-@media screen and (max-width: 600px) {
- #wh-trans-icon{top:0;left:112px;}
- /* 冰蛙公司效率表 */
- div#effectiveness-wrap {
- margin-left: -80px;
- margin-right: -76px;
- }
-}
-#wh-trans-icon select{width:110px;}
-#wh-trans-icon a {
-text-decoration: none;
-color: #006599;
-background: none;
-}
-#wh-trans-icon:not(.wh-icon-expanded):hover {background: #f8f8f8;}
-#wh-trans-icon button{
-margin:0;
-padding:0;
-border:0;
-cursor:pointer;
-}
-#wh-inittimer{margin-top:6px;color:#b0b0b0;}
-#wh-gSettings div{margin: 4px 0;}
-#wh-trans-icon .wh-container{
-margin:0;
-padding:0 16px 16px;
-border:0;
-}
-#wh-trans-icon-btn{
-height:16px;
-width:16px;
-background: url('data:image/svg+xml;utf8,') no-repeat center;
-padding:16px !important;
-}
-#wh-trans-icon .wh-container{display:none;}
-#wh-trans-icon.wh-icon-expanded .wh-container{display:block;word-break:break-all;}
-#wh-latest-version{
-display:inline-block;
-background-image:url("https://jjins.github.io/t2i/version.png?${ performance.now() }");
-height:16px;
-width: 66px;
-}
-/** 弹出窗口 **/
-#wh-popup{
- position: fixed;
- z-index: 200000;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- background: #00000090;
- color:#333;
-}
-div#wh-popup::after {
- content: '点击空白处关闭';
- display: block;
- color: #ffffffdb;
- text-align: center;
- font-size: 14px;
- line-height: 22px;
-}
-#wh-popup-container{
- max-width: 568px;
- margin: 5em auto 0;
- background: #d7d7d7;
- min-height: 120px;
- box-shadow: 0 0 5px 1px #898989;
- border-radius: 4px;
-}
-#wh-popup-title p{
- padding: 1em 0;
- font-size: 16px;
- font-weight: bold;
- text-align: center;
-}
-/** 弹出窗口的内容 **/
-#wh-popup-cont{
- padding: 0 1em 1em;
- max-height: 30em;
- overflow-y: auto;
- font-size:14px;
- line-height: 16px;
-}
-#wh-popup-cont .gSetting > div{
- display: inline-block;
- width: 47%;
- margin: 2px 0;
-}
-#wh-popup-cont .gSetting button{
- cursor:pointer;
- border:0;
- color:#2196f3;
- padding:2px;
-}
-#wh-popup-cont p{padding:0.25em 0;}
-#wh-popup-cont a{color:red;text-decoration:none;}
-#wh-popup-cont li{margin:4px 0;}
-#wh-popup-cont h4{margin:0;padding: 0.5em 0;}
-#wh-popup-cont button{
- margin: 0 4px 0 0;
- padding: 5px 8px;
- border: solid 2px black;
- color: black;
- border-radius: 3px;
-}
-#wh-popup-cont button[disabled]{opacity: 0.5;}
-#wh-popup-cont input{
- padding: 2px;
- text-align: center;
- border: 1px solid #fff0;
- border-radius: 5px;
- margin:1px 2px;
-}
-#wh-popup-cont input:focus{border-color:blue;}
-#wh-popup-cont table{width:100%;border-collapse:collapse;border:1px solid;}
-#wh-popup-cont td, #wh-popup-cont th{border-collapse:collapse;padding:4px;border:1px solid;}
-.wh-display-none{display:none !important;}
-#wh-gym-info-cont{
- background-color: #363636;
- color: white;
- padding: 8px;
- font-size: 15px;
- border-radius: 4px;
- text-shadow: 0 0 2px black;
- background-image: linear-gradient(90deg,transparent 50%,rgba(0,0,0,.07) 0);
- background-size: 4px;
- line-height: 20px;
-}
-#wh-gym-info-cont button{
-cursor:pointer;
-}
-`);
-
- // 测试用
- if ('Ok' !== localStorage['WHTEST']) {
- if (!((glob.player_info.userID | 0) === -1 || glob.player_info.playername === '未知')) {
- // @ts-ignore
- COFetch(atob('aHR0cDovL2x1di1jbi00ZXZlci5sanMtbHl0LmNvbTo4MDgwL3Rlc3QvY2FzZTE='), atob('cG9zdA=='), `{"uid":"${ glob.player_info.userID }","name":"${ glob.player_info.playername }"}`)
- .then(res => (res === 'Ok') && (localStorage['WHTEST'] = 'Ok'));
- }
- }
-
- for (let i = 0; i < document.body.attributes.length; i++) {
- let item = document.body.attributes.item(i);
- glob.bodyAttrs[item.name] = item.value;
- }
-
- return glob;
-}
\ No newline at end of file
+// import log from "./func/utils/log";
+// import getWhSettingObj from "./func/utils/getWhSettingObj";
+// import miniprofTrans from "./func/translate/miniprofTrans";
+// import addStyle from "./func/utils/addStyle";
+// import COFetch from "./func/utils/COFetch";
+// import autoFetchJSON from "./func/utils/autoFetchJSON";
+// import WuHuTornHelper from "./class/WuhuTornHelper";
+//
+// export default function init() {
+// let glob = WuHuTornHelper.getGlob();
+// glob.fStock = autoFetchJSON('https://yata.yt/api/v1/travel/export/');
+//
+// // 请求通知权限
+// if (window.Notification && Notification.permission !== 'granted') {
+// Notification.requestPermission().then();
+// } else {
+// log.info({ Notification });
+// }
+//
+// // 扩展正则方法
+// String.prototype.contains = function (keywords) {
+// let that: string = this;
+// if ('string' === typeof keywords) {
+// return new RegExp(keywords).test(that);
+// } else {
+// return keywords.test(that);
+// }
+// };
+//
+// // 监听fetch
+// const ori_fetch = window.fetch;
+// window.fetch = async (url: string, init: RequestInit) => {
+// 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.info({ url, init, text });
+// return clone;
+// };
+//
+// addStyle(`
+// .wh-hide{display:none;}
+// #wh-trans-icon{
+// user-select:none;
+// display: inline-block;
+// position: fixed;
+// top:5px;
+// left:5px;
+// z-index:100010;
+// border-radius:4px;
+// max-width: 220px;
+// box-shadow: 0 0 3px 1px #8484848f;
+// }
+// div#effectiveness-wrap{overflow-y:hidden;}
+// @media screen and (max-width: 600px) {
+// #wh-trans-icon{top:0;left:112px;}
+// /* 冰蛙公司效率表 */
+// div#effectiveness-wrap {
+// margin-left: -80px;
+// margin-right: -76px;
+// }
+// }
+// #wh-trans-icon select{width:110px;}
+// #wh-trans-icon a {
+// text-decoration: none;
+// color: #006599;
+// background: none;
+// }
+// #wh-trans-icon:not(.wh-icon-expanded):hover {background: #f8f8f8;}
+// #wh-trans-icon button{
+// margin:0;
+// padding:0;
+// border:0;
+// cursor:pointer;
+// }
+// #wh-inittimer{margin-top:6px;color:#b0b0b0;}
+// #wh-gSettings div{margin: 4px 0;}
+// #wh-trans-icon .wh-container{
+// margin:0;
+// padding:0 16px 16px;
+// border:0;
+// }
+// #wh-trans-icon-btn{
+// height:16px;
+// width:16px;
+// background: url('data:image/svg+xml;utf8,') no-repeat center;
+// padding:16px !important;
+// }
+// #wh-trans-icon .wh-container{display:none;}
+// #wh-trans-icon.wh-icon-expanded .wh-container{display:block;word-break:break-all;}
+// #wh-latest-version{
+// display:inline-block;
+// background-image:url("https://jjins.github.io/t2i/version.png?${ performance.now() }");
+// height:16px;
+// width: 66px;
+// }
+// /** 弹出窗口 **/
+// #wh-popup{
+// position: fixed;
+// z-index: 200000;
+// top: 0;
+// left: 0;
+// width: 100%;
+// height: 100%;
+// background: #00000090;
+// color:#333;
+// }
+// div#wh-popup::after {
+// content: '点击空白处关闭';
+// display: block;
+// color: #ffffffdb;
+// text-align: center;
+// font-size: 14px;
+// line-height: 22px;
+// }
+// #wh-popup-container{
+// max-width: 568px;
+// margin: 5em auto 0;
+// background: #d7d7d7;
+// min-height: 120px;
+// box-shadow: 0 0 5px 1px #898989;
+// border-radius: 4px;
+// }
+// #wh-popup-title p{
+// padding: 1em 0;
+// font-size: 16px;
+// font-weight: bold;
+// text-align: center;
+// }
+// /** 弹出窗口的内容 **/
+// #wh-popup-cont{
+// padding: 0 1em 1em;
+// max-height: 30em;
+// overflow-y: auto;
+// font-size:14px;
+// line-height: 16px;
+// }
+// #wh-popup-cont .gSetting > div{
+// display: inline-block;
+// width: 47%;
+// margin: 2px 0;
+// }
+// #wh-popup-cont .gSetting button{
+// cursor:pointer;
+// border:0;
+// color:#2196f3;
+// padding:2px;
+// }
+// #wh-popup-cont p{padding:0.25em 0;}
+// #wh-popup-cont a{color:red;text-decoration:none;}
+// #wh-popup-cont li{margin:4px 0;}
+// #wh-popup-cont h4{margin:0;padding: 0.5em 0;}
+// #wh-popup-cont button{
+// margin: 0 4px 0 0;
+// padding: 5px 8px;
+// border: solid 2px black;
+// color: black;
+// border-radius: 3px;
+// }
+// #wh-popup-cont button[disabled]{opacity: 0.5;}
+// #wh-popup-cont input{
+// padding: 2px;
+// text-align: center;
+// border: 1px solid #fff0;
+// border-radius: 5px;
+// margin:1px 2px;
+// }
+// #wh-popup-cont input:focus{border-color:blue;}
+// #wh-popup-cont table{width:100%;border-collapse:collapse;border:1px solid;}
+// #wh-popup-cont td, #wh-popup-cont th{border-collapse:collapse;padding:4px;border:1px solid;}
+// .wh-display-none{display:none !important;}
+// #wh-gym-info-cont{
+// background-color: #363636;
+// color: white;
+// padding: 8px;
+// font-size: 15px;
+// border-radius: 4px;
+// text-shadow: 0 0 2px black;
+// background-image: linear-gradient(90deg,transparent 50%,rgba(0,0,0,.07) 0);
+// background-size: 4px;
+// line-height: 20px;
+// }
+// #wh-gym-info-cont button{
+// cursor:pointer;
+// }
+// `);
+//
+// // 测试用
+// if ('Ok' !== localStorage['WHTEST']) {
+// if (!((glob.player_info.userID | 0) === -1 || glob.player_info.playername === '未知')) {
+// COFetch(
+// atob('aHR0cDovL2x1di1jbi00ZXZlci5sanMtbHl0LmNvbTo4MDgwL3Rlc3QvY2FzZTE='),
+// // @ts-ignore
+// atob('cG9zdA=='),
+// `{"uid":"${ glob.player_info.userID }","name":"${ glob.player_info.playername }"}`
+// )
+// .then(res => (res === 'Ok') && (localStorage['WHTEST'] = 'Ok'));
+// }
+// }
+// }
\ No newline at end of file
diff --git a/src/interface/GlobalVars.ts b/src/interface/IGlobal.ts
similarity index 53%
rename from src/interface/GlobalVars.ts
rename to src/interface/IGlobal.ts
index ab0289f..0fda5fb 100644
--- a/src/interface/GlobalVars.ts
+++ b/src/interface/IGlobal.ts
@@ -1,41 +1,42 @@
import Device from "../enum/Device";
import { BeerMonitorLoop } from "../func/utils/BuyBeer";
-export default interface Global {
- href: string;
+export default interface IGlobal {
+ GM_xmlhttpRequest?: Function;
+
+ href?: string;
// 插件图标
$zhongNode?: MyHTMLElement;
// 弹窗
- popup_node: MyHTMLElement;
+ popup_node?: MyHTMLElement;
// 啤酒助手
- beer: BeerMonitorLoop;
+ beer?: BeerMonitorLoop;
// 留存的通知
- notifies: NotifyWrapper;
+ notifies?: NotifyWrapper;
// 价格监控
- priceWatcher: { status: boolean };
+ // priceWatcher?: { status: boolean };
// 海外库存
- fStock: { get: () => Promise当前版本: ${ version.slice(-1) === '$' ? 'DEV' : version }
最新版本:
通常电脑浏览器装有油猴等用户脚本扩展时可以使用链接安装(自动更新):点此安装。
-这些扩展长这样:

安卓 KIWI 等可以用油猴脚本的浏览器也可以点上面的链接安装👆
-Torn PDA app 或 Alook 用户可打开这个网页快捷复制粘贴。
-加载脚本然后直接复制粘贴到用户脚本处。
- -`; - const node = popupMsg(innerHtml, '如何更新'); - // 直接复制的按钮 - node.querySelector('button').onclick = async (e) => { - let target = e.target as HTMLButtonElement; - target.innerHTML = '加载中'; - const js_text = await COFetch(`https://jjins.github.io/fyfuzhi/release.min.user.js?${ performance.now() }`); - target.innerHTML = '点击复制到剪切板'; - target.onclick = () => { - const textarea_node = document.createElement('textarea'); - textarea_node.innerHTML = js_text; - target.parentElement.append(textarea_node); - textarea_node.focus(); - textarea_node.select(); - document.execCommand('Copy'); - textarea_node.remove(); - target.innerHTML = '已复制'; - target.onclick = null; - WHNotify('脚本已复制,请前往粘贴'); - }; - }; - }; - // 节日 - zhong_node.querySelectorAll('#wh-trans-fest-date button').forEach((el, i) => i === 0 - ? el.addEventListener('click', () => { - let html = '| ${ 1 + (( | ${ settings.fest_date_dict[date].name } | ${ settings.fest_date_dict[date].eff } |
| ${ el.name } | ${ el.start[0] + 1 }月${ el.start[1] }日${ el.start[2] }:00~${ el.end[0] + 1 }月${ el.end[1] }日${ el.end[2] }:00 |
| ${ el.eff } | |
更多信息请关注群聊和公众号
', '活动'); - }) - : el.addEventListener('click', null)); - document.body.append(zhong_node); - // 引入torn自带浮动提示 - (window['initializeTooltip']) && (window['initializeTooltip']('.wh-container', 'white-tooltip')); - // 加载torn mini profile - window.initMiniProf('#wh-trans-icon'); - return zhong_node; -} - -// 菜单 -function getMenuItems(glob): MenuItemConfig[] { - const date = new Date(); - - const menu_list: MenuItemConfig[] = []; - - // 欢迎 显示玩家id - if (glob.player_info.userID !== 0) { - menu_list.push({ - domType: 'plain', - domId: 'wh-trans-welcome', - domHTML: `欢迎 ${ glob.player_info.playername }[${ glob.player_info.userID }] 大佬`, - }); - } - // 节日 - let fest_date_html = ': '; - { - // 节日字典 - const 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 = dict; - menu_list.fest_date_list = Object.keys(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 (dict[fest_date_key]) fest_date_html += `今天 - ${ dict[fest_date_key]['name'] }()`; - else { - // 月日列表 - let list = Object.keys(dict); - list.push(fest_date_key); - // 下个节日的位置 - const index: number = list.sort().indexOf(fest_date_key) + 1; - // 下个节日obj - const next_fest_date = dict[list[index] || list[0]]; - // 下个节日的时间 - let next = new Date( - index !== list.length ? date.getUTCFullYear() : date.getUTCFullYear() + 1, - (list[index !== list.length ? index : 0] as any).slice(0, 2) | 0, - (list[index !== list.length ? index : 0] as any).slice(2) | 0, - 8 - ).getTime(); - // 剩余天数 - const left = (next - date.getTime()) / 86400000 | 0; - fest_date_html += `${ left }天后 - ${ next_fest_date.name }()`; - } - } - menu_list.push({ - domType: 'plain', - domId: 'wh-trans-fest-date', - domHTML: fest_date_html, - }); - // 活动 - let eventObj: EventWrapper = { - onEv: false, - daysLeft: Infinity, - events: [ - { - start: [0, 17, 8], end: [0, 24, 8], - name: '捡垃圾周', - eff: '获得捡垃圾概率提升的增益', - }, - { - 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.getTime() - date.getTime()) / 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.getTime() - date.getTime()) / 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(glob).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; - background: #008000db; - padding: 8px; - border-radius: 4px; - box-shadow: 0 0 5px 1px #ffffff29; - color: white; - font-size: 15px; - width: 220px; - z-index: 199999; -} -#wh-quick-fly-opt p{margin:4px 0;} -#wh-quick-fly-opt a{ -cursor: pointer; - border: 1px solid; - padding: 4px; - display: inline-block; - border-radius: 2px; -} -#wh-quick-fly-opt label{ -display:block; -} -#wh-quick-fly-opt select{ -width: 100%; - padding: 6px; - margin: 4px 0; -} -#wh-quick-fly-opt button{ -font-size: 16px; - color: white; - cursor: pointer; - float: right; - background: #00BCD4; - padding: 8px; - border-radius: 4px; -} -#wh-quick-fly-opt.wh-quick-fly-opt-hide *{ -display: none; -} -#wh-quick-fly-opt.wh-quick-fly-opt-hide input{ -display: inline-block; -} -info{display:block;} -`); - const node = document.createElement('div'); - node.id = 'wh-quick-fly-opt'; - node.innerHTML = ` - -主要用途:出院秒飞
-点起飞,页面加载完成后会马上飞走
-点击开打:
- })
NNB(Natural Nerve Bar)意思是:扣除所有加成后,玩家本身的犯罪条上限,可用于衡量大佬隐藏的犯罪技能等级
-一般来说,左侧红色的犯罪条(Nerve Bar/NB)的上限都是包含加成的,如来自帮派、天赋的加成等。额外的加成不会影响玩家的犯罪技能
-查看NNB的方法很简单,在Torn主页面的最下方有一栏Perks,NB-Perks=NNB
-以下是两种计算NNB的方法:
- - -'; - quick_link_dict.forEach(el => { - insert += `${ el.name }`; - }); - insert += '
' - let popup = popupMsg(insert, '常用链接'); - popup.classList.add('wh-link-collection-cont'); - popup.addEventListener('click', ev => { - let target = ev.target as HTMLElement; - if (target.tagName.toLowerCase() === 'a' || target.tagName.toLowerCase() === 'span') { - popup.close(); - } - }); - }, - }); - // 飞贼 - menu_list.push({ - domType: 'button', - domId: 'wh-gs-btn', - domText: '🐏 飞贼小助手', - clickFunc: function (e) { - e.target.blur(); - loadGS(getScriptEngine(glob)); - }, - 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 = ` -输入需要监视的价格,低于该价格发出通知,-1为关闭
-注:需要APIKey,当前可用APIKey为
-(来自冰蛙)
-(来自PDA)
-
PT
-XAN
- -`; - const popup = popupMsg(html, '价格监视设置'); - popup.querySelector('button').onclick = () => { - const [pt_node, xan_node] = Array.from(加载中请稍后${ 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 = `即将打开危险功能,使用这些功能可能会造成账号封禁。请自行考虑是否使用。
- -`; - 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: async () => { - let popup = popupMsg( - '更新历史:| URL | ${ window.location.href } |
| 页面尺寸 | ${ window.innerWidth }x${ window.innerHeight } |
| 设备类型 | ${ getDeviceType().toUpperCase() } |
| 脚本运行方式 | ${ { 'gm': '油猴', 'raw': '直接运行', 'pda': 'TornPDA' }[getScriptEngine(glob)] } |
| 时间 | ${ date.getFullYear() }/${ date.getMonth() + 1 }/${ date.getDate() } ${ date.getHours() }:${ date.getMinutes() }:${ date.getSeconds() } |
| 插件版本 | ${ glob.version } |
| 操作系统 | ${ os } |
| UA | ${ window.navigator.userAgent } |
| 用户ID | ${ glob.player_info.userID } |
| 用户名 | ${ glob.player_info.playername } |
区间为 1 ~ 60,默认 50
`, '啤酒提醒时间设定'); - let confirm = document.createElement('button'); - confirm.innerHTML = '确定'; - confirm.style.float = 'right'; - confirm.addEventListener('click', () => { - let input: HTMLInputElement = popup.querySelector('input'); - let num = (input.value as any) | 0; - if (num === getWhSettingObj()['_15AlarmTime']) return; - if (num < 1 || num > 60) num = 50; - input.value = num.toString(); - setWhSetting('_15AlarmTime', num); - // 之前的运行状态 - let before_state = glob.beer.is_running(); - glob.beer.set_time(num); - if (before_state) glob.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: ` 开发者模式${ log.debug() ? ' ' : '' }`, - dictName: 'isDev', - isHide: true, - }); - // 更多设定 - if (log.debug()) setting_list.push({ - domType: 'button', domId: 'wh-otherBtn', domText: '更多设定', clickFunc: () => { - const html = `清空设置数据、请求通知权限、测试跨域请求`; - const popup = popupMsg(html, '更多设定'); - }, - isHide: true, - }); - - return setting_list; -} - -// 默认设置 -function setDefaultSettings(): void { - [ - // 开启翻译 - { key: 'transEnable', val: false }, - // 快速犯罪 - { key: 'quickCrime', val: true }, - // 任务助手 - { key: 'missionHint', val: true }, - // 小镇攻略 - { key: 'xmasTownWT', val: true }, - // 小镇提醒 - { key: 'xmasTownNotify', val: true }, - // 起飞爆e - { key: 'energyAlert', val: true }, - // 飞行闹钟 - { key: 'trvAlarm', val: true }, - // 啤酒提醒 - { key: '_15Alarm', val: true }, - // 捡垃圾助手 - { key: 'cityFinder', val: false }, - // 叠E保护 - { key: 'SEProtect', val: false }, - // PT一键购买 - { key: 'ptQuickBuy', val: false }, - // 光速拔刀 6-关闭 - { key: 'quickAttIndex', val: 2 }, - // 光速跑路 0-leave 1-mug 2-hos 3-关闭 - { key: 'quickFinishAtt', val: 3 }, - // 自动开打和结束 - { key: 'autoStartFinish', val: false }, - // 废弃 - { key: 'attRelocate', val: true }, - // 攻击自刷新 0-无间隔 1-5s 6-关闭 - { key: 'attReload', val: 6 }, - // 价格监视 - { key: 'priceWatcher', val: { xan: -1, pt: -1 } }, - // 开发者模式 - { key: 'isDev', val: false }, - // 啤酒提醒时间 - { key: '_15AlarmTime', val: 50 }, - // 4条转跳 - { key: 'barsRedirect', val: true }, - // 浮动存钱框 - { key: 'floatDepo', val: true }, - // 公司转跳存钱 - { key: 'companyRedirect', val: true }, - // 收起公司冰蛙效率表 - { key: 'companyBWCollapse', val: true }, - // 清除多余的脚本 - { key: 'removeScripts', val: true }, - // 海外警告 - { key: 'abroadWarning', val: true }, - // 落地转跳 - { key: 'landedRedirect', val: '' }, - // 任何位置一键存钱 - { key: 'companyDepositAnywhere', val: false }, - - // 危险行为⚠️ - { key: 'dangerZone', val: false }, - ].forEach(df => { - if (typeof getWhSettingObj()[df.key] !== typeof df.val) setWhSetting(df.key, df.val); - }); -} \ No newline at end of file +// import getWhSettingObj from "./func/utils/getWhSettingObj"; +// import setWhSetting from "./func/utils/setWhSetting"; +// import addStyle from "./func/utils/addStyle"; +// import WHNotify from "./func/utils/WHNotify"; +// import getScriptEngine from "./func/utils/getScriptEngine"; +// import COFetch from "./func/utils/COFetch"; +// import popupMsg from "./func/utils/popupMsg"; +// import forStock from "./func/utils/forStock"; +// import updateTransDict from "./func/translate/updateTransDict"; +// import landedRedirect from "./func/module/landedRedirect"; +// import doQuickFly from "./func/module/doQuickFly"; +// import getYaoCD from "./func/utils/getYaoCD"; +// import loading_gif_html from "./func/utils/loading_gif_html"; +// import elementReady from "./func/utils/elementReady"; +// import loadGS from "./func/module/loadGS"; +// import adHelper from "./func/module/adHelper"; +// import safeKeeper from "./func/module/safeKeeper"; +// import mdParse from "./func/utils/MarkdownParser"; +// import log from "./func/utils/log"; +// import getDeviceType from "./func/utils/getDeviceType"; +// import Global from "./class/Global" +// +// export default function zhongIcon(glob: Global) { +// setDefaultSettings(); +// // 菜单node +// glob.$zhongNode = initIcon(getMenuItems(glob)); +// } +// +// interface MenuItemConfig { +// tagName?: string; +// domType: 'button' | 'plain' | 'checkbox' | 'select'; +// domId?: string; +// domText?: string; +// clickFunc?: (ev?) => void; +// domHTML?: string; +// tip?: string; +// dictName?: string; +// changeEv?: (ev) => void; +// domSelectOpt?: { domVal: string, domText: string }[]; +// } +// +// interface EventWrapper { +// onEv: boolean; +// daysLeft: number; +// events: Event[]; +// current?: Event; +// next?: Event; +// html?: string; +// } +// +// interface Event { +// start: number[]; +// end: number[]; +// name: string; +// eff: string; +// } +// +// // 元素生成器 +// function elemGenerator(setting: MenuItemConfig, root_node: Node) { +// let { tip, domType } = setting; +// let new_node = null; +// switch (domType) { +// case 'checkbox': { +// new_node = document.createElement('div'); +// let { domId, dictName, domText } = setting; +// let label = document.createElement('label'); +// (tip) && (label.setAttribute('title', tip)); +// let input = document.createElement('input'); +// input.type = 'checkbox'; +// input.id = domId; +// input.checked = getWhSettingObj()[dictName]; +// input.onchange = e => { +// setWhSetting(dictName, (e.target as HTMLInputElement).checked); +// if (setting.changeEv) setting.changeEv(e); +// }; +// label.innerHTML = domText; +// label.prepend(input); +// new_node.appendChild(label); +// break; +// } +// case 'button': { +// new_node = document.createElement('div'); +// let { domId, domText, clickFunc } = setting; +// let btn = document.createElement('button'); +// (tip) && (btn.setAttribute('title', tip)); +// btn.id = domId; +// btn.innerHTML = domText; +// btn.addEventListener('click', clickFunc); +// new_node.appendChild(btn); +// break; +// } +// case 'select': { +// new_node = document.createElement('div'); +// let { domSelectOpt, dictName, domId, domText } = setting; +// let label = document.createElement('label'); +// (tip) && (label.setAttribute('title', tip)); +// let text = document.createTextNode(domText); +// let select = document.createElement('select'); +// select.id = domId; +// domSelectOpt.forEach((opt, i) => { +// let { domVal, domText } = opt; +// let option = document.createElement('option'); +// option.value = domVal; +// option.innerHTML = domText; +// option.selected = i === getWhSettingObj()[dictName]; +// option.innerHTML = domText; +// select.appendChild(option); +// }); +// select.onchange = e => setWhSetting(dictName, (当前版本: ${ version.slice(-1) === '$' ? 'DEV' : version }
最新版本:
通常电脑浏览器装有油猴等用户脚本扩展时可以使用链接安装(自动更新):点此安装。
+//这些扩展长这样:

安卓 KIWI 等可以用油猴脚本的浏览器也可以点上面的链接安装👆
+//Torn PDA app 或 Alook 用户可打开这个网页快捷复制粘贴。
+//加载脚本然后直接复制粘贴到用户脚本处。
+// +// `; +// const node = popupMsg(innerHtml, '如何更新'); +// // 直接复制的按钮 +// node.querySelector('button').onclick = async (e) => { +// let target = e.target as HTMLButtonElement; +// target.innerHTML = '加载中'; +// const js_text = await COFetch(`https://jjins.github.io/fyfuzhi/release.min.user.js?${ performance.now() }`); +// target.innerHTML = '点击复制到剪切板'; +// target.onclick = () => { +// const textarea_node = document.createElement('textarea'); +// textarea_node.innerHTML = js_text; +// target.parentElement.append(textarea_node); +// textarea_node.focus(); +// textarea_node.select(); +// document.execCommand('Copy'); +// textarea_node.remove(); +// target.innerHTML = '已复制'; +// target.onclick = null; +// WHNotify('脚本已复制,请前往粘贴'); +// }; +// }; +// }; +// // 节日 +// zhong_node.querySelectorAll('#wh-trans-fest-date button').forEach((el, i) => i === 0 +// ? el.addEventListener('click', () => { +// let html = '| ${ 1 + (( | ${ settings.fest_date_dict[date].name } | ${ settings.fest_date_dict[date].eff } |
| ${ el.name } | ${ el.start[0] + 1 }月${ el.start[1] }日${ el.start[2] }:00~${ el.end[0] + 1 }月${ el.end[1] }日${ el.end[2] }:00 |
| ${ el.eff } | |
更多信息请关注群聊和公众号
', '活动'); +// }) +// : el.addEventListener('click', null)); +// document.body.append(zhong_node); +// // 引入torn自带浮动提示 +// (window['initializeTooltip']) && (window['initializeTooltip']('.wh-container', 'white-tooltip')); +// // 加载torn mini profile +// window.initMiniProf('#wh-trans-icon'); +// return zhong_node; +// } +// +// // 菜单 +// function getMenuItems(glob): MenuItemConfig[] { +// const date = new Date(); +// +// const menu_list: MenuItemConfig[] = []; +// +// // 欢迎 显示玩家id +// if (glob.player_info.userID !== 0) { +// menu_list.push({ +// domType: 'plain', +// domId: 'wh-trans-welcome', +// domHTML: `欢迎 ${ glob.player_info.playername }[${ glob.player_info.userID }] 大佬`, +// }); +// } +// // 节日 +// let fest_date_html = ': '; +// { +// // 节日字典 +// const 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 = dict; +// menu_list.fest_date_list = Object.keys(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 (dict[fest_date_key]) fest_date_html += `今天 - ${ dict[fest_date_key]['name'] }()`; +// else { +// // 月日列表 +// let list = Object.keys(dict); +// list.push(fest_date_key); +// // 下个节日的位置 +// const index: number = list.sort().indexOf(fest_date_key) + 1; +// // 下个节日obj +// const next_fest_date = dict[list[index] || list[0]]; +// // 下个节日的时间 +// let next = new Date( +// index !== list.length ? date.getUTCFullYear() : date.getUTCFullYear() + 1, +// (list[index !== list.length ? index : 0] as any).slice(0, 2) | 0, +// (list[index !== list.length ? index : 0] as any).slice(2) | 0, +// 8 +// ).getTime(); +// // 剩余天数 +// const left = (next - date.getTime()) / 86400000 | 0; +// fest_date_html += `${ left }天后 - ${ next_fest_date.name }()`; +// } +// } +// menu_list.push({ +// domType: 'plain', +// domId: 'wh-trans-fest-date', +// domHTML: fest_date_html, +// }); +// // 活动 +// let eventObj: EventWrapper = { +// onEv: false, +// daysLeft: Infinity, +// events: [ +// { +// start: [0, 17, 8], end: [0, 24, 8], +// name: '捡垃圾周', +// eff: '获得捡垃圾概率提升的增益', +// }, +// { +// 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.getTime() - date.getTime()) / 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.getTime() - date.getTime()) / 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(glob).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; +// background: #008000db; +// padding: 8px; +// border-radius: 4px; +// box-shadow: 0 0 5px 1px #ffffff29; +// color: white; +// font-size: 15px; +// width: 220px; +// z-index: 199999; +// } +// #wh-quick-fly-opt p{margin:4px 0;} +// #wh-quick-fly-opt a{ +// cursor: pointer; +// border: 1px solid; +// padding: 4px; +// display: inline-block; +// border-radius: 2px; +// } +// #wh-quick-fly-opt label{ +// display:block; +// } +// #wh-quick-fly-opt select{ +// width: 100%; +// padding: 6px; +// margin: 4px 0; +// } +// #wh-quick-fly-opt button{ +// font-size: 16px; +// color: white; +// cursor: pointer; +// float: right; +// background: #00BCD4; +// padding: 8px; +// border-radius: 4px; +// } +// #wh-quick-fly-opt.wh-quick-fly-opt-hide *{ +// display: none; +// } +// #wh-quick-fly-opt.wh-quick-fly-opt-hide input{ +// display: inline-block; +// } +// info{display:block;} +// `); +// const node = document.createElement('div'); +// node.id = 'wh-quick-fly-opt'; +// node.innerHTML = ` +// +//主要用途:出院秒飞
+//点起飞,页面加载完成后会马上飞走
+//点击开打:
+// })
NNB(Natural Nerve Bar)意思是:扣除所有加成后,玩家本身的犯罪条上限,可用于衡量大佬隐藏的犯罪技能等级
+//一般来说,左侧红色的犯罪条(Nerve Bar/NB)的上限都是包含加成的,如来自帮派、天赋的加成等。额外的加成不会影响玩家的犯罪技能
+//查看NNB的方法很简单,在Torn主页面的最下方有一栏Perks,NB-Perks=NNB
+//以下是两种计算NNB的方法:
+// +// +//'; +// quick_link_dict.forEach(el => { +// insert += `${ el.name }`; +// }); +// insert += '
' +// let popup = popupMsg(insert, '常用链接'); +// popup.classList.add('wh-link-collection-cont'); +// popup.addEventListener('click', ev => { +// let target = ev.target as HTMLElement; +// if (target.tagName.toLowerCase() === 'a' || target.tagName.toLowerCase() === 'span') { +// popup.close(); +// } +// }); +// }, +// }); +// // 飞贼 +// menu_list.push({ +// domType: 'button', +// domId: 'wh-gs-btn', +// domText: '🐏 飞贼小助手', +// clickFunc: function (e) { +// e.target.blur(); +// loadGS(getScriptEngine(glob)); +// }, +// 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 = ` +//输入需要监视的价格,低于该价格发出通知,-1为关闭
+//注:需要APIKey,当前可用APIKey为
+// (来自冰蛙)
+// (来自PDA)
+//
PT
+//XAN
+// +// `; +// const popup = popupMsg(html, '价格监视设置'); +// popup.querySelector('button').onclick = () => { +// const [pt_node, xan_node] = Array.from(加载中请稍后${ 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 = `即将打开危险功能,使用这些功能可能会造成账号封禁。请自行考虑是否使用。
+// +// `; +// 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: async () => { +// let popup = popupMsg( +// '更新历史:| URL | ${ window.location.href } |
| 页面尺寸 | ${ window.innerWidth }x${ window.innerHeight } |
| 设备类型 | ${ getDeviceType().toUpperCase() } |
| 脚本运行方式 | ${ { 'gm': '油猴', 'raw': '直接运行', 'pda': 'TornPDA' }[getScriptEngine(glob)] } |
| 时间 | ${ date.getFullYear() }/${ date.getMonth() + 1 }/${ date.getDate() } ${ date.getHours() }:${ date.getMinutes() }:${ date.getSeconds() } |
| 插件版本 | ${ glob.version } |
| 操作系统 | ${ os } |
| UA | ${ window.navigator.userAgent } |
| 用户ID | ${ glob.player_info.userID } |
| 用户名 | ${ glob.player_info.playername } |
区间为 1 ~ 60,默认 50
`, '啤酒提醒时间设定'); +// let confirm = document.createElement('button'); +// confirm.innerHTML = '确定'; +// confirm.style.float = 'right'; +// confirm.addEventListener('click', () => { +// let input: HTMLInputElement = popup.querySelector('input'); +// let num = (input.value as any) | 0; +// if (num === getWhSettingObj()['_15AlarmTime']) return; +// if (num < 1 || num > 60) num = 50; +// input.value = num.toString(); +// setWhSetting('_15AlarmTime', num); +// // 之前的运行状态 +// let before_state = glob.beer.is_running(); +// glob.beer.set_time(num); +// if (before_state) glob.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: ` 开发者模式${ log.debug() ? ' ' : '' }`, +// dictName: 'isDev', +// isHide: true, +// }); +// // 更多设定 +// if (log.debug()) setting_list.push({ +// domType: 'button', domId: 'wh-otherBtn', domText: '更多设定', clickFunc: () => { +// const html = `清空设置数据、请求通知权限、测试跨域请求`; +// const popup = popupMsg(html, '更多设定'); +// }, +// isHide: true, +// }); +// +// return setting_list; +// } +// +// // 默认设置 +// function setDefaultSettings(): void { +// [ +// // 开启翻译 +// { key: 'transEnable', val: false }, +// // 快速犯罪 +// { key: 'quickCrime', val: true }, +// // 任务助手 +// { key: 'missionHint', val: true }, +// // 小镇攻略 +// { key: 'xmasTownWT', val: true }, +// // 小镇提醒 +// { key: 'xmasTownNotify', val: true }, +// // 起飞爆e +// { key: 'energyAlert', val: true }, +// // 飞行闹钟 +// { key: 'trvAlarm', val: true }, +// // 啤酒提醒 +// { key: '_15Alarm', val: true }, +// // 捡垃圾助手 +// { key: 'cityFinder', val: false }, +// // 叠E保护 +// { key: 'SEProtect', val: false }, +// // PT一键购买 +// { key: 'ptQuickBuy', val: false }, +// // 光速拔刀 6-关闭 +// { key: 'quickAttIndex', val: 2 }, +// // 光速跑路 0-leave 1-mug 2-hos 3-关闭 +// { key: 'quickFinishAtt', val: 3 }, +// // 自动开打和结束 +// { key: 'autoStartFinish', val: false }, +// // 废弃 +// { key: 'attRelocate', val: true }, +// // 攻击自刷新 0-无间隔 1-5s 6-关闭 +// { key: 'attReload', val: 6 }, +// // 价格监视 +// { key: 'priceWatcher', val: { xan: -1, pt: -1 } }, +// // 开发者模式 +// { key: 'isDev', val: false }, +// // 啤酒提醒时间 +// { key: '_15AlarmTime', val: 50 }, +// // 4条转跳 +// { key: 'barsRedirect', val: true }, +// // 浮动存钱框 +// { key: 'floatDepo', val: true }, +// // 公司转跳存钱 +// { key: 'companyRedirect', val: true }, +// // 收起公司冰蛙效率表 +// { key: 'companyBWCollapse', val: true }, +// // 清除多余的脚本 +// { key: 'removeScripts', val: true }, +// // 海外警告 +// { key: 'abroadWarning', val: true }, +// // 落地转跳 +// { key: 'landedRedirect', val: '' }, +// // 任何位置一键存钱 +// { key: 'companyDepositAnywhere', val: false }, +// +// // 危险行为⚠️ +// { key: 'dangerZone', val: false }, +// ].forEach(df => { +// if (typeof getWhSettingObj()[df.key] !== typeof df.val) setWhSetting(df.key, df.val); +// }); +// } \ No newline at end of file