wuhu-torn-helper/src/func/module/travelHelper.ts
2022-11-03 16:34:58 +08:00

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 = [
'✈ ',
'&nbsp;&nbsp;✈ ',
'&nbsp;&nbsp;&nbsp;&nbsp;✈ ',
'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;✈ ',
'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;✈ ',
'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;✈ ',
'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;✈ ',
'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;✈ ',
'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;✈ ',
'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;✈ ',
];
// 飞行的状态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('出错了');
}
}