318 lines
16 KiB
TypeScript
318 lines
16 KiB
TypeScript
import titleTrans from "../translate/titleTrans";
|
|
import contentTitleLinksTrans from "../translate/contentTitleLinksTrans";
|
|
import Device from "../../enum/Device";
|
|
import WuhuBase from "../../class/WuhuBase";
|
|
import Alert from "../../class/utils/Alert";
|
|
import ActionButtonUtils from "../../class/utils/ActionButtonUtils";
|
|
import WuhuConfig from "../../class/WuhuConfig";
|
|
import CommonUtils from "../../class/utils/CommonUtils";
|
|
import TRAVEL_ALARM_CSS from "../../static/css/travel_alarm.css";
|
|
import TRAVEL_ALARM_HTML from "../../static/html/travel_alarm.html";
|
|
import TornStyleBlock from "../../class/utils/TornStyleBlock";
|
|
import QuickFlyBtnHandler from "../../class/handler/QuickFlyBtnHandler";
|
|
import TRAVEL_STATE from "../../enum/TravelState";
|
|
|
|
export default async function travelHelper(): Promise<void> {
|
|
let { href, bodyAttrs, device } = WuhuBase.glob;
|
|
|
|
if (href.includes('index.php')) {
|
|
switch (CommonUtils.getInstance().getTravelStage()) {
|
|
// 飞行中
|
|
case TRAVEL_STATE.FLYING: {
|
|
// 飞行闹钟
|
|
if (device === Device.PC && WuhuConfig.get('trvAlarm')) {
|
|
// 获取目的地
|
|
let dest_cn;
|
|
let country = document.body.getAttribute('data-country');
|
|
if (country === 'torn') {
|
|
dest_cn = '回城';
|
|
} else {
|
|
dest_cn = {
|
|
'uk': "英国",
|
|
'switzerland': "瑞士",
|
|
'mexico': '墨西哥',
|
|
'canada': '加拿大',
|
|
'cayman': '开曼',
|
|
'hawaii': '夏威夷',
|
|
'argentina': '阿根廷',
|
|
'japan': '日本',
|
|
'china': '中国',
|
|
'uae': 'UAE',
|
|
'south-africa': '南非',
|
|
}[country] || country;
|
|
}
|
|
|
|
// 剩余时间
|
|
const remaining_arr = document.querySelector('#countrTravel').getAttribute('data-to');
|
|
|
|
const wh_trv_alarm = localStorage.getItem('wh_trv_alarm')
|
|
? JSON.parse(localStorage.getItem('wh_trv_alarm'))
|
|
: { 'enable': true, 'alert_time': 30, 'node_pos': [240, 240] };
|
|
const save_trv_settings = () => localStorage.setItem('wh_trv_alarm', JSON.stringify(wh_trv_alarm));
|
|
|
|
const wh_trv_alarm_node = document.createElement('div');
|
|
wh_trv_alarm_node.id = 'wh-trv-alarm';
|
|
wh_trv_alarm_node.style.left = `${ wh_trv_alarm.node_pos[0] }px`;
|
|
wh_trv_alarm_node.style.top = `${ wh_trv_alarm.node_pos[1] }px`;
|
|
wh_trv_alarm_node.innerHTML = TRAVEL_ALARM_HTML
|
|
.replace('{{}}', dest_cn === '回城' ? dest_cn : '飞往' + dest_cn)
|
|
.replace('{{}}', wh_trv_alarm.enable ? 'checked ' : '')
|
|
.replace('{{}}', wh_trv_alarm.alert_time || 30);
|
|
CommonUtils.addStyle(TRAVEL_ALARM_CSS);
|
|
document.body.append(wh_trv_alarm_node);
|
|
// 报错dom
|
|
const error_node = wh_trv_alarm_node.querySelector('#wh-trv-error') as HTMLElement;
|
|
// jquery拖动
|
|
// @ts-ignore
|
|
$(wh_trv_alarm_node).draggable({
|
|
containment: "body",
|
|
distance: 5,
|
|
handle: "#wh-trv-alarm-title",
|
|
stop: () => {
|
|
wh_trv_alarm.node_pos = [parseInt(wh_trv_alarm_node.style.left), parseInt(wh_trv_alarm_node.style.top)];
|
|
save_trv_settings();
|
|
},
|
|
scroll: false,
|
|
});
|
|
// 剩余时间dom
|
|
const remaining_node = wh_trv_alarm_node.querySelector('#wh-trv-alarm-remaining');
|
|
// 设定闹钟响的按钮
|
|
const set_node = wh_trv_alarm_node.querySelectorAll('#wh-trv-alarm-cont button')[0] as HTMLButtonElement;
|
|
// 落地前响铃时长
|
|
const cd_time = wh_trv_alarm_node.querySelector('input[type="number"]') as HTMLInputElement;
|
|
let count_down_notify: MyHTMLElement | { close: Function } = {
|
|
close: () => {
|
|
}
|
|
};
|
|
set_node.onclick = () => {
|
|
try {
|
|
wh_trv_alarm.alert_time = parseInt(cd_time.value);
|
|
} catch {
|
|
wh_trv_alarm.alert_time = 30;
|
|
}
|
|
save_trv_settings();
|
|
set_node.value = wh_trv_alarm.alert_time;
|
|
count_down_notify.close();
|
|
count_down_notify = new Alert('设置已更新');
|
|
};
|
|
// 停止响铃按钮
|
|
const stop_node = wh_trv_alarm_node.querySelectorAll('#wh-trv-alarm-cont button')[1] as HTMLButtonElement;
|
|
stop_node.onclick = () => {
|
|
user_stop_alert = true;
|
|
stop_node.innerText = '本次已关闭';
|
|
stop_node.disabled = true;
|
|
}
|
|
// 开启闹钟勾选
|
|
const enable_node = wh_trv_alarm_node.querySelector('#wh-trv-alarm-cont input[type="checkbox"]') as HTMLInputElement;
|
|
let on_off_notify: MyHTMLElement | { close: Function } = {
|
|
close: () => {
|
|
}
|
|
};
|
|
enable_node.onchange = ev => {
|
|
wh_trv_alarm.enable = (<HTMLInputElement>ev.target).checked;
|
|
save_trv_settings();
|
|
on_off_notify.close();
|
|
on_off_notify = new Alert(wh_trv_alarm.enable ? '闹钟已开启' : '闹钟已关闭');
|
|
};
|
|
// 剩余时间 秒
|
|
const remaining_sec = parseInt(remaining_arr);
|
|
// 落地时timestamp
|
|
const land_timestamp = Date.now() + remaining_sec * 1000;
|
|
// 音频dom
|
|
const audio = document.createElement('audio');
|
|
audio.src = 'https://www.torn.com/js/chat/sounds/Warble_1.mp3';
|
|
audio.play()
|
|
.then(() => audio.pause())
|
|
.catch(() => {
|
|
error_node.style.display = 'table';
|
|
const func = () => {
|
|
error_node.remove();
|
|
document.body.removeEventListener('click', func);
|
|
};
|
|
document.body.addEventListener('click', func);
|
|
});
|
|
// 是否正在响铃
|
|
let audio_play_flag = false;
|
|
// 用户是否停止当前响铃
|
|
let user_stop_alert = false;
|
|
// 响铃循环id
|
|
let audio_play_id = null;
|
|
// 响铃的方法
|
|
let audio_play_handle = () => {
|
|
if (user_stop_alert) {
|
|
clearInterval(audio_play_id);
|
|
audio_play_id = null;
|
|
return;
|
|
}
|
|
if (!audio_play_flag || !wh_trv_alarm.enable) return;
|
|
audio.play().then();
|
|
};
|
|
// 飞机小动画字符
|
|
const flying_arr = [
|
|
'✈ ',
|
|
' ✈ ',
|
|
' ✈ ',
|
|
' ✈ ',
|
|
' ✈ ',
|
|
' ✈ ',
|
|
' ✈ ',
|
|
' ✈ ',
|
|
' ✈ ',
|
|
' ✈ ',
|
|
];
|
|
// 飞行的状态dom
|
|
const flying_status = wh_trv_alarm_node.querySelector('#wh-trv-status');
|
|
// 飞机的小动画dom
|
|
const flying_ani = flying_status.nextElementSibling;
|
|
// 飞机的计数
|
|
let flying_index = 0;
|
|
const id = window.setInterval(() => {
|
|
const remaining_time = (land_timestamp - Date.now()) / 1000 | 0;
|
|
remaining_node.innerText = `${ remaining_time / 3600 | 0 }时${ remaining_time % 3600 / 60 | 0 }分${ remaining_time % 60 }秒`;
|
|
|
|
if (remaining_time < wh_trv_alarm.alert_time) {
|
|
// flying_status.innerHTML = `即将落地...`;
|
|
if (wh_trv_alarm.enable) {
|
|
// 播放提示音
|
|
audio_play_flag = true;
|
|
if (audio_play_id === null && !user_stop_alert) audio_play_id = window.setInterval(audio_play_handle, 750);
|
|
stop_node.parentElement.classList.remove('wh-trv-alarm-stop-hide');
|
|
}
|
|
} else {
|
|
// flying_status.innerHTML = `飞行中...`;
|
|
if (wh_trv_alarm.enable) {
|
|
clearInterval(audio_play_id);
|
|
audio_play_id = null;
|
|
stop_node.parentElement.classList.add('wh-trv-alarm-stop-hide');
|
|
}
|
|
}
|
|
flying_ani.innerHTML = `${ flying_arr[flying_index] }`;
|
|
flying_index = (flying_index + 1) % flying_arr.length;
|
|
}, 1000);
|
|
}
|
|
|
|
// 落地转跳 落地前事件
|
|
if (WuhuConfig.get('landedRedirect') && document.querySelector('#tcLogo[title]') === null) {
|
|
window.addEventListener('beforeunload', () => {
|
|
let obj = { url: WuhuConfig.get('landedRedirect'), timestamp: Date.now() };
|
|
sessionStorage['wh-landed-redirect'] = JSON.stringify(obj);
|
|
});
|
|
}
|
|
break;
|
|
}
|
|
// 海外落地
|
|
case TRAVEL_STATE.ABROAD: {
|
|
// 一键回城
|
|
ActionButtonUtils.getInstance().add('直接回城', travelBack);
|
|
// 海外警告
|
|
if (WuhuConfig.get('abroadWarning')) {
|
|
let c = 1;
|
|
setInterval(() => new Alert(`警告:您已海外落地${ c++ * 30 }秒`, {
|
|
timeout: 30,
|
|
sysNotify: true
|
|
}), 30000);
|
|
}
|
|
// 解毒提醒
|
|
if (bodyAttrs['data-country'] === 'switzerland') {
|
|
let block = new TornStyleBlock('解毒提醒');
|
|
block.setContent('<p><a href="/index.php?page=rehab">❤️ 点击前往解毒</a></p>');
|
|
document.querySelector('h4#skip-to-content').before(block.getBase());
|
|
}
|
|
break;
|
|
}
|
|
// 主页界面
|
|
case TRAVEL_STATE.IN_TORN: {
|
|
// 落地转跳
|
|
if (sessionStorage['wh-landed-redirect']) {
|
|
let { url, timestamp } = JSON.parse(sessionStorage['wh-landed-redirect']);
|
|
if (Date.now() - timestamp < 30000) {
|
|
sessionStorage.removeItem('wh-landed-redirect');
|
|
location.href = url;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
// 起飞页面
|
|
else if (href.contains(/travelagency\.php/)) {
|
|
// 起飞提醒 TODO 去除jquery mutation
|
|
if (WuhuConfig.get('energyAlert')) {
|
|
const contentWrapper = document.querySelector('.content-wrapper');
|
|
const OB = new MutationObserver(() => {
|
|
OB.disconnect();
|
|
titleTrans();
|
|
contentTitleLinksTrans();
|
|
trans();
|
|
OB.observe(contentWrapper, {
|
|
characterData: true,
|
|
attributes: true,
|
|
subtree: true,
|
|
childList: true
|
|
});
|
|
});
|
|
const trans = () => {
|
|
// 当前能量e
|
|
const energyBarStr = $('#barEnergy p[class^="bar-value__"]').text().trim();
|
|
const [curE, maxE] = energyBarStr.split('/').length === 2
|
|
? [parseInt(energyBarStr.split('/')[0]), parseInt(energyBarStr.split('/')[1])]
|
|
: [NaN, NaN];
|
|
const incTime = maxE === 150 ? 10 : 15;
|
|
const fullEnergyTime = !(isNaN(curE) || isNaN(maxE)) ? (maxE - 5 - curE) / 5 * incTime
|
|
+ (incTime - new Date().getMinutes() % incTime) : NaN;
|
|
// 起飞前提示
|
|
$('.travel-confirm .travel-question .q-wrap span:nth-of-type(2)').each((i, e) => {
|
|
if (isNaN(fullEnergyTime)) return;
|
|
const spl = e.innerText.trim().split(' ');
|
|
const [hours, minutes] = spl.length === 5
|
|
? [parseInt(spl[0]), parseInt(spl[3])]
|
|
: [0, parseInt(spl[0])];
|
|
if (fullEnergyTime < (hours * 60 + minutes) * 2) {
|
|
if (!$(e).parent().hasClass('wh-translated')) {
|
|
$(e).parent()
|
|
.prepend(`<div style="color: red">警告:该次飞行往返时间大于体力回复时间,将会爆体!</div>`)
|
|
.addClass('wh-translated');
|
|
}
|
|
}
|
|
});
|
|
};
|
|
trans();
|
|
OB.observe(contentWrapper, {
|
|
characterData: true,
|
|
attributes: true,
|
|
subtree: true,
|
|
childList: true
|
|
});
|
|
}
|
|
// 一键起飞
|
|
if (sessionStorage['wh-quick-fly']) {
|
|
QuickFlyBtnHandler.doQuickFly();
|
|
}
|
|
}
|
|
}
|
|
|
|
async function travelBack(): Promise<null> {
|
|
if (typeof window['getAction'] !== 'function') return;
|
|
let backHomeAction = function (): Promise<string> {
|
|
return new Promise(resolve => {
|
|
window.getAction({
|
|
type: "post",
|
|
action: 'travelagency.php',
|
|
data: {
|
|
step: 'backHomeAction'
|
|
},
|
|
success: function (msg) {
|
|
resolve(msg);
|
|
}
|
|
});
|
|
});
|
|
};
|
|
let res = await backHomeAction();
|
|
new Alert(res);
|
|
if (!res.includes('error')) {
|
|
new Alert('成功,即将刷新');
|
|
window.setTimeout(() => location.reload(), 3000);
|
|
} else {
|
|
new Alert('出错了');
|
|
}
|
|
} |