diff --git a/global.d.ts b/global.d.ts index a286737..b172f73 100644 --- a/global.d.ts +++ b/global.d.ts @@ -28,6 +28,8 @@ declare interface Window { initMiniProf(selector: string): void; + renderMiniProfile(node: Element, props: any); + /* PDA自带 */ PDA_httpGet(url: URL | string): Promise; diff --git a/src/WHNext.ts b/src/common.ts similarity index 100% rename from src/WHNext.ts rename to src/common.ts diff --git a/src/func/module/cityFinder.ts b/src/func/module/cityFinder.ts new file mode 100644 index 0000000..9d34a03 --- /dev/null +++ b/src/func/module/cityFinder.ts @@ -0,0 +1,139 @@ +import elementReady from "../utils/elementReady"; +import COFetch from "../utils/COFetch"; +import addStyle from "../utils/addStyle"; +import toThousands from "../utils/toThousands"; +import log from "../utils/log"; + +export default function cityFinder(): void { + addStyle(` +.wh-city-finds .leaflet-marker-pane img[src*="torn.com/images/items/"]{ +display: block !important; +box-sizing: border-box; +width: 40px !important; +height: 40px !important; +left: -20px !important; +top: -20px !important; +padding: 10px 0; +border: none; +border-radius: 100%; +background-color:#d2d2d28c; +box-shadow:0 0 10px 5px #000; +z-index: 999 !important; +} +.wh-city-finds .leaflet-marker-pane.leaflet-marker-icon.user-item-pinpoint.leaflet-clickable{display: none !important;} +#wh-city-finder{ +box-shadow: 0 0 3px 0px #696969; +border-radius: 4px; +} +#wh-city-finder-header{ +background-color: #3f51b5; +color: white; +padding: 8px; +font-size: 15px; +border-radius: 4px 4px 0 0; +text-shadow: 0 0 2px black; +background-image: linear-gradient(90deg,transparent 50%,rgba(0,0,0,.07) 0); +background-size: 4px; +} +#wh-city-finder-cont{ +background: #616161; +padding: 8px; +color: #c7c7c7; +border-radius: 0 0 4px 4px; +font-size: 13px; +} +#wh-city-finder-cont span{ +margin:2px 4px 2px 0; +padding:2px; +border-radius:2px; +background:green; +color:white; +display:inline-block; +} +`); + // 物品名与价格 + let items = null; + const base = document.createElement('div'); + base.id = 'wh-city-finder'; + const container = document.createElement('div'); + container.id = 'wh-city-finder-cont'; + const header = document.createElement('div'); + header.id = 'wh-city-finder-header'; + header.innerHTML = '捡垃圾助手'; + const info = document.createElement('div'); + info.innerHTML = '已找到物品:'; + container.append(info); + base.append(header); + base.append(container); + COFetch('https://jjins.github.io/item_price_raw.json') + .then(r => items = JSON.parse(r)) + .catch(err => { + log.info(err) + items = undefined + }); + elementReady('div.leaflet-marker-pane').then(elem => { + document.querySelector('#map').classList.add('wh-city-finds'); + document.querySelector('.content-wrapper').prepend(base); + // 发现的物品id与map img node + const founds = []; + elem.querySelectorAll('img.map-user-item-icon').forEach(node => { + const item_id = node.src.split('/')[5]; + const finder_item = document.createElement('span'); + finder_item.id = 'wh-city-finder-item' + item_id; + finder_item.innerHTML = item_id; + founds.push({ 'id': item_id, 'node': finder_item, 'map_item': node }); + container.append(finder_item); + }); + // 未发现物品 返回 + if (founds.length === 0) { + // header.innerHTML = '捡垃圾助手'; + info.innerHTML = '空空如也,请大佬明天再来'; + return; + } + // 将id显示为物品名与价格的函数 + const displayNamePrice = () => { + // 总价 + let total = 0; + founds.forEach(el => { + const value = items[el.id]['price']; + el.node.innerHTML = `${ items[el.id]['name'] } ($${ toThousands(value) })`; + // 灰色 100k以下 + if (value < 100000) el.node.style.backgroundColor = '#9e9e9e'; + // 绿色 1m以下 + else if (value < 1000000) el.node.style.backgroundColor = '#4caf50'; + // 蓝色 25m以下 + else if (value < 25000000) el.node.style.backgroundColor = '#03a9f4'; + // 橙色 500m以下 + else if (value < 500000000) el.node.style.backgroundColor = '#ffc107'; + // 红色 >500m + else if (value >= 500000000) el.node.style.backgroundColor = '#f44336'; + total += items[el.id]['price']; + }); + header.innerHTML = `捡垃圾助手 - ${ founds.length } 个物品,总价值 $${ toThousands(total) }`; + }; + // 未取到数据时添加循环来调用函数 + if (items === null) { + // 15s超时 + let timeout = 30; + const interval = window.setInterval(() => { + timeout--; + if (items !== null) { + displayNamePrice(); + clearInterval(interval); + } + if (0 === timeout) { + log.info('获取物品名称与价格信息超时') + clearInterval(interval) + } + }, 500); + } + // 无法跨域获取数据时 + else if (items === undefined) { + info.innerHTML += '(当前平台暂不支持查询价格)'; + } + // 调用函数 + else { + displayNamePrice(); + } + }) +} \ No newline at end of file diff --git a/src/func/translate/getTaskHint.ts b/src/func/translate/getTaskHint.ts index bbf1fba..5f19445 100644 --- a/src/func/translate/getTaskHint.ts +++ b/src/func/translate/getTaskHint.ts @@ -3,10 +3,11 @@ import { missionDict } from "../../dictionary/translation"; /** * 任务助手 */ -function getTaskHint(task_name): string { +export default function getTaskHint(task_name): string { task_name = task_name .toLowerCase() .replaceAll(' ', '_') + .replaceAll('!', '') .replaceAll('-', '_') .replaceAll(',', ''); if (!missionDict._taskHint[task_name]) return '暂无,请联系开发者'; diff --git a/src/func/translate/miniprofTrans.ts b/src/func/translate/miniprofTrans.ts index 09e7df9..938e84f 100644 --- a/src/func/translate/miniprofTrans.ts +++ b/src/func/translate/miniprofTrans.ts @@ -1,6 +1,7 @@ -// mini profile 翻译 import playerStatusTrans from "./playerStatusTrans"; +import sendCashTrans from "./sendCashTrans"; +// mini profile 翻译 function miniprofTrans() { // 迷你资料卡状态 playerStatusTrans($('div.profile-mini-root div.description span')); diff --git a/src/func/translate/sendCashTrans.ts b/src/func/translate/sendCashTrans.ts index 93c35ac..881d218 100644 --- a/src/func/translate/sendCashTrans.ts +++ b/src/func/translate/sendCashTrans.ts @@ -3,7 +3,7 @@ import { sendCashDict } from "../../dictionary/translation"; /** * 发钱翻译 */ -function sendCashTrans(domPath = '', buttonClass = '.send-cash') { +export default function sendCashTrans(domPath = '', buttonClass = '.send-cash') { const sc = $(`${ domPath } ${ buttonClass } *`); if (sc.length === 0) return; sc.contents().each((i, e) => { @@ -21,6 +21,4 @@ function sendCashTrans(domPath = '', buttonClass = '.send-cash') { } } }); -} - -export default sendCashDict \ No newline at end of file +} \ No newline at end of file diff --git a/src/func/utils/getWhSettingObj.ts b/src/func/utils/getWhSettingObj.ts index 0643fae..77d6f8e 100644 --- a/src/func/utils/getWhSettingObj.ts +++ b/src/func/utils/getWhSettingObj.ts @@ -1,5 +1,5 @@ // 插件的配置 getter -export default function getWhSettingObj (): WHSettings { +export default function getWhSettingObj(): WHSettings { return JSON.parse(localStorage.getItem('wh_trans_settings')) || {} } diff --git a/src/func/utils/initMiniProf.ts b/src/func/utils/initMiniProf.ts new file mode 100644 index 0000000..de841ed --- /dev/null +++ b/src/func/utils/initMiniProf.ts @@ -0,0 +1,130 @@ +// 引入torn miniprofile +function initMiniProf(selector) { + let profileMini = { + timeout: 0, + clickable: false, + rootElement: null, + targetElement: null, + rootId: 'profile-mini-root', + rootSelector: '#profile-mini-root', + userNameSelector: "a[href*='profiles.php?XID=']", + // contentWrapper: '#wh-trans-icon', + contentWrapper: selector, + setClickable: function (value) { + this.clickable = value + }, + setRootElement: function () { + if (!document.getElementById(this.rootId)) { + this.rootElement = document.createElement('div'); + this.rootElement.classList.add(this.rootId); + this.rootElement.id = this.rootId; + $('body').append(this.rootElement); + } else { + window.ReactDOM.unmountComponentAtNode($(this.rootSelector).get(0)); + this.rootElement = document.getElementById(this.rootId); + } + }, + subscribeForHideListeners: function () { + const that = this; + let width = $(window).width(); + + function handleResize(e) { + if ($(this).width() !== width) { + width = $(this).width(); + hideMiniProfile.call(that, e); + } + } + + function handleScroll(e) { + if (!document.activeElement.classList.contains('send-cash-input')) { + hideMiniProfile.call(that, e); + } + } + + function hideMiniProfile(e) { + if ($(e.target).closest(this.rootSelector).length === 0 || ['resize', 'scroll'].includes(e.type)) { + that.targetElement = null + window.ReactDOM.unmountComponentAtNode($(this.rootSelector).get(0)); + $(this.userNameSelector).off('click', this.handleUserNameClick); + $(this.userNameSelector).unbind('contextmenu'); + $(document).off('click', hideMiniProfile); + $(window).off('hashchange', hideMiniProfile); + $(window).off('resize', handleResize); + $(window).off('scroll', handleScroll); + } + } + + $(document).on('click', hideMiniProfile.bind(this)); + $(window).on('hashchange', hideMiniProfile.bind(this)); + $(window).on('resize', handleResize); + if (that.targetElement.closest('#chatRoot')) { + $(window).on('scroll', handleScroll); + } + }, + subscribeForUserNameClick: function () { + $(this.userNameSelector).click(this.handleUserNameClick.bind(this)) + }, + handleUserNameClick: function () { + if (!this.clickable) { + this.setClickable(true); + return false; + } + }, + subscribeForContextMenu: function (element) { + $(element).on('contextmenu', function (e) { + e.preventDefault(); + e.stopPropagation(); + e.stopImmediatePropagation(); + return false; + }) + }, + handleMouseDown: function () { + const that = this; + $(this.contentWrapper).on('mousedown touchstart', this.userNameSelector, function (e) { + if (e.which !== 1 && e.type !== 'touchstart') { + return false; + } + that.targetElement = e.currentTarget; + that.subscribeForContextMenu(that.targetElement); + that.handleFocusLost(e.currentTarget); + that.timeout = setTimeout(function () { + if (e.type !== 'touchstart') { + that.setClickable(false); + that.subscribeForUserNameClick(); + } else { + $(e.currentTarget).off('touchmove mouseleave'); + } + that.subscribeForHideListeners(); + that.setRootElement(); + const userID = e.currentTarget.search.slice('?XID='.length); + const props = { + userID: userID, + event: e.originalEvent + }; + window.renderMiniProfile(that.rootElement, props); + }, 500); + if (e.type !== 'touchstart') { + return false; + } + }) + }, + handleMouseUp: function () { + const that = this; + $(this.contentWrapper).on('mouseup touchend', this.userNameSelector, function () { + that.timeout && clearTimeout(that.timeout); + }) + }, + handleFocusLost: function (element) { + const that = this; + $(element).on('touchmove mouseleave', function unsubscribe() { + that.timeout && clearTimeout(that.timeout); + $(this).off('touchmove mouseleave', unsubscribe) + }) + }, + init: function () { + this.handleMouseDown(); + this.handleMouseUp(); + } + }; + profileMini.init(); +} \ No newline at end of file diff --git a/src/func/utils/log.ts b/src/func/utils/log.ts index e436ee0..a95176a 100644 --- a/src/func/utils/log.ts +++ b/src/func/utils/log.ts @@ -1,4 +1,3 @@ -// console.log改写 import getWhSettingObj from "./getWhSettingObj"; function debug() { @@ -10,10 +9,10 @@ function debug() { } } -const log = (...o) => (debug()) && (console.log('[WH]', ...o)) - -log.error = (...o) => (debug()) && (console.error('[WH]', ...o)) -log.info = (...o) => (debug()) && (console.log('[WH]', ...o)) -log.debug = debug; +const log = { + error: (...o) => (debug()) && (console.error('[WH]', ...o)), + info: (...o) => (debug()) && (console.log('[WH]', ...o)), + debug, +} export default log \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index 6136281..3c2b076 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,9 +1,9 @@ -import userscript from "./userscript"; import zhongIcon from "./zhongIcon"; import init from "./init"; import getWhSettingObj from "./func/utils/getWhSettingObj"; import translateMain from "./func/translate/translateMain"; -import WHNext from "./WHNext"; +import common from "./common"; +import urlMatch from "./urlMatch"; (function main() { let started = new Date().getTime(); @@ -16,11 +16,11 @@ import WHNext from "./WHNext"; if (getWhSettingObj()['transEnable']) translateMain(glob.href); - WHNext(glob); + common(glob); - userscript(); + urlMatch(glob).then(); let runTime = new Date().getTime() - started; glob.$zhongNode.initTimer.innerHTML = `助手加载时间 ${ runTime }ms`; }) -(); \ No newline at end of file +(); diff --git a/src/userscript.ts b/src/urlMatch.ts similarity index 77% rename from src/userscript.ts rename to src/urlMatch.ts index bdff608..1a121a5 100644 --- a/src/userscript.ts +++ b/src/urlMatch.ts @@ -1,152 +1,23 @@ -import { - cityDict, - eventsDict, - gymList, - missionDict, - ocList, - titleDict, - titleLinksDict, -} from './dictionary/translation'; -import Device from "./enum/Device"; +import Global from "./interface/GlobalVars"; +import getWhSettingObj from "./func/utils/getWhSettingObj"; +import cityFinder from "./func/module/cityFinder"; +import WHNotify from "./func/utils/WHNotify"; +import elementReady from "./func/utils/elementReady"; +import setWhSetting from "./func/utils/setWhSetting"; +import log from "./func/utils/log"; +import { missionDict } from "./dictionary/translation"; +import getTaskHint from "./func/translate/getTaskHint"; import getPlayerInfo from "./func/utils/getPlayerInfo"; +import Device from "./enum/Device"; +import getSidebarData from "./func/utils/getSidebarData"; +import getDeviceType from "./func/utils/getDeviceType"; +import addStyle from "./func/utils/addStyle"; -export default function userscript(): void { - let { version, isIframe, PDA_APIKey, isPDA, player_info, fstock, notifies } = window.WHPARAMS; - - +export default async function urlMatch(glob: Global) { + let { href, beer, isIframe } = glob; // 捡垃圾助手 - if (getWhSettingObj()['cityFinder'] && href.includes('city.php')) { - addStyle(` -.wh-city-finds .leaflet-marker-pane img[src*="torn.com/images/items/"]{ -display: block !important; -box-sizing: border-box; -width: 40px !important; -height: 40px !important; -left: -20px !important; -top: -20px !important; -padding: 10px 0; -border: none; -border-radius: 100%; -background-color:#d2d2d28c; -box-shadow:0 0 10px 5px #000; -z-index: 999 !important; -} -.wh-city-finds .leaflet-marker-pane.leaflet-marker-icon.user-item-pinpoint.leaflet-clickable{display: none !important;} -#wh-city-finder{ -box-shadow: 0 0 3px 0px #696969; -border-radius: 4px; -} -#wh-city-finder-header{ -background-color: #3f51b5; -color: white; -padding: 8px; -font-size: 15px; -border-radius: 4px 4px 0 0; -text-shadow: 0 0 2px black; -background-image: linear-gradient(90deg,transparent 50%,rgba(0,0,0,.07) 0); -background-size: 4px; -} -#wh-city-finder-cont{ -background: #616161; -padding: 8px; -color: #c7c7c7; -border-radius: 0 0 4px 4px; -font-size: 13px; -} -#wh-city-finder-cont span{ -margin:2px 4px 2px 0; -padding:2px; -border-radius:2px; -background:green; -color:white; -display:inline-block; -} -`); - // 物品名与价格 - let items = null; - const base = document.createElement('div'); - base.id = 'wh-city-finder'; - const container = document.createElement('div'); - container.id = 'wh-city-finder-cont'; - const header = document.createElement('div'); - header.id = 'wh-city-finder-header'; - header.innerHTML = '捡垃圾助手'; - const info = document.createElement('div'); - info.innerHTML = '已找到物品:'; - container.append(info); - base.append(header); - base.append(container); - COFetch('https://jjins.github.io/item_price_raw.json') - .catch(err => { - log(err) - items = undefined - }) - .then(r => items = JSON.parse(r)); - elementReady('div.leaflet-marker-pane').then(elem => { - document.querySelector('#map').classList.add('wh-city-finds'); - document.querySelector('.content-wrapper').prepend(base); - // 发现的物品id与map img node - const founds = []; - elem.querySelectorAll('img.map-user-item-icon').forEach(node => { - const item_id = node.src.split('/')[5]; - const finder_item = document.createElement('span'); - finder_item.id = 'wh-city-finder-item' + item_id; - finder_item.innerHTML = item_id; - founds.push({ 'id': item_id, 'node': finder_item, 'map_item': node }); - container.append(finder_item); - }); - // 未发现物品 返回 - if (founds.length === 0) { - // header.innerHTML = '捡垃圾助手'; - info.innerHTML = '空空如也,请大佬明天再来'; - return; - } - // 将id显示为物品名与价格的函数 - const displayNamePrice = () => { - // 总价 - let total = 0; - founds.forEach(el => { - const value = items[el.id]['price']; - el.node.innerHTML = `${ items[el.id]['name'] } ($${ toThousands(value) })`; - // 灰色 100k以下 - if (value < 100000) el.node.style.backgroundColor = '#9e9e9e'; - // 绿色 1m以下 - else if (value < 1000000) el.node.style.backgroundColor = '#4caf50'; - // 蓝色 25m以下 - else if (value < 25000000) el.node.style.backgroundColor = '#03a9f4'; - // 橙色 500m以下 - else if (value < 500000000) el.node.style.backgroundColor = '#ffc107'; - // 红色 >500m - else if (value >= 500000000) el.node.style.backgroundColor = '#f44336'; - total += items[el.id]['price']; - }); - header.innerHTML = `捡垃圾助手 - ${ founds.length } 个物品,总价值 $${ toThousands(total) }`; - }; - // 未取到数据时添加循环来调用函数 - if (items === null) { - // 15s超时 - let timeout = 30; - const interval = window.setInterval(() => { - timeout--; - if (items !== null) { - displayNamePrice(); - clearInterval(interval); - } - if (0 === timeout) { - log('获取物品名称与价格信息超时') - clearInterval(interval) - } - }, 500); - } - // 无法跨域获取数据时 - else if (items === undefined) { - info.innerHTML += '(当前平台暂不支持查询价格)'; - } - // 调用函数 - else { - displayNamePrice(); - } - }) + if (href.includes('city.php') && getWhSettingObj()['cityFinder']) { + cityFinder(); } // pt一键购买 @@ -167,9 +38,10 @@ display:inline-block; } new MutationObserver(e => { for (const t of e) { - for (const e of t.addedNodes) { - 'LI' === e.tagName && rmv_cfm(e) - } + // for (const e of t.addedNodes) { + // 'LI' === e.tagName && rmv_cfm(e) + // } + t.addedNodes.forEach(e => 'LI' === (e as HTMLElement).tagName && rmv_cfm(e)) } }).observe(points_sales, { childList: true }); } @@ -181,8 +53,9 @@ display:inline-block; switch_node.innerHTML = ``; switch_node.id = 'wh-gym-info-cont'; switch_node.querySelector('input').onchange = e => { + let target = e.target as HTMLInputElement; cont.classList.toggle('wh-display-none'); - setWhSetting('SEProtect', e.target.checked); + setWhSetting('SEProtect', target.checked); }; elementReady('#gymroot').then(node => { cont = node; @@ -277,14 +150,14 @@ $1,000 `; if (clear_node) clear_node.before(beer); else node.append(beer); - e.target.remove(); + (e.target).remove(); msg_node.innerHTML = '添加成功'; }); document.querySelector('.content-wrapper').prepend(add_btn_node); }); // 监听啤酒购买 $(document).ajaxComplete((_, xhr, settings) => { - log({ xhr, settings }); + log.info({ xhr, settings }); let { data } = settings, { responseText } = xhr; let response = JSON.parse(responseText); if (data.includes('step=buyShopItem') && data.includes('ID=180') && response['success']) { @@ -294,7 +167,7 @@ $1,000 }); } - // 快速crime + // 快速crime TODO 重构、与翻译解藕 if (href.contains(/crimes\.php/) && getWhSettingObj()['quickCrime']) { if (isIframe) { const isValidate = document.querySelector('h4#skip-to-content').innerText.toLowerCase().includes('validate'); @@ -312,8 +185,8 @@ $1,000 const $$ = document.querySelector('.content-wrapper'); const OB = new MutationObserver(() => { OB.disconnect(); - titleTrans(); - contentTitleLinksTrans(); + // titleTrans(); + // contentTitleLinksTrans(); trans(); OB.observe($$, { characterData: true, @@ -385,13 +258,13 @@ $1,000 }); } - // 任务助手 + // 任务助手 TODO 重构、与翻译解藕 if (href.contains(/loader\.php\?sid=missions/) && getWhSettingObj()['missionHint']) { const $$ = $('.content-wrapper'); const OB = new MutationObserver(() => { OB.disconnect(); - titleTrans(); - contentTitleLinksTrans(); + // titleTrans(); + // contentTitleLinksTrans(); trans(); OB.observe($$.get(0), { characterData: true, @@ -431,7 +304,6 @@ $1,000 childList: true }); } - // 圣诞小镇 if (href.contains(/christmas_town\.php/)) { let $root = document.querySelector('#christmastownroot'); @@ -810,40 +682,42 @@ margin: 0 0 3px; } `; $($ct_wrap).before(insert_html); - const $wh_loot_container = $root.querySelector('#wh-loot-container'); - const $btn = $wh_loot_container.querySelector('#wh-loot-btn button'); - const $clear_btn = $wh_loot_container.querySelector('#wh-hist-clear button'); + const $wh_loot_container = $root.querySelector('#wh-loot-container') as HTMLElement; + const $btn = $wh_loot_container.querySelector('#wh-loot-btn button') as HTMLButtonElement; + const $clear_btn = $wh_loot_container.querySelector('#wh-hist-clear button') as HTMLButtonElement; const $ex = $wh_loot_container.querySelector('#wh-loot-container-ex'); const $tbody = $wh_loot_container.querySelector('tbody'); - const $blink = $wh_loot_container.querySelector('#wh-loot-setting-blink'); - const $sound = $wh_loot_container.querySelector('#wh-loot-setting-sound'); - const $chest = $wh_loot_container.querySelector('#wh-loot-setting-chest'); + const $blink = $wh_loot_container.querySelector('#wh-loot-setting-blink') as HTMLInputElement; + const $sound = $wh_loot_container.querySelector('#wh-loot-setting-sound') as HTMLInputElement; + const $chest = $wh_loot_container.querySelector('#wh-loot-setting-chest') as HTMLInputElement; const $audio = $wh_loot_container.querySelector('audio'); $btn.onclick = e => { - e.target.innerText = e.target.innerText === '设置' ? '收起' : '设置'; + let target = e.target as HTMLButtonElement; + target.innerText = target.innerText === '设置' ? '收起' : '设置'; $($ex).toggleClass('wh-hide'); - e.target.blur(); + target.blur(); }; $clear_btn.onclick = e => { - e.target.blur(); + let target = e.target as HTMLButtonElement; + target.blur(); dropHist = {}; $tbody.innerHTML = ''; localStorage.setItem('wh-loot-store', JSON.stringify(dropHist)); }; $blink.onchange = e => { - if (e.target.checked) { + if ((e.target).checked) { alertSettings.blink = 'y'; if ($wh_loot_container.querySelector('#wh-loot-item-count').innerText !== '(0)') { - $wh_loot_container.querySelector('#wh-loot-container-main').style.animation = 'lootFoundAlert 2s infinite'; + ($wh_loot_container.querySelector('#wh-loot-container-main')).style.animation = 'lootFoundAlert 2s infinite'; } } else { alertSettings.blink = 'n'; - $wh_loot_container.querySelector('#wh-loot-container-main').style.animation = ''; + ($wh_loot_container.querySelector('#wh-loot-container-main')).style.animation = ''; } localStorage.setItem('wh-loot-setting', JSON.stringify(alertSettings)); }; $sound.onchange = e => { - if (e.target.checked) { + if ((e.target).checked) { alertSettings.sound = 'y'; if ($wh_loot_container.querySelector('#wh-loot-item-count').innerText !== '(0)') { soundLoopFlag = true; @@ -855,7 +729,7 @@ margin: 0 0 3px; localStorage.setItem('wh-loot-setting', JSON.stringify(alertSettings)); }; $chest.onchange = e => { - alertSettings.chest = e.target.checked ? 'y' : 'n'; + alertSettings.chest = (e.target).checked ? 'y' : 'n'; localStorage.setItem('wh-loot-setting', JSON.stringify(alertSettings)); }; const soundIntervalID = window.setInterval(() => { @@ -880,26 +754,29 @@ margin: 0 0 3px; return; } const $pos_spl = $pos.innerText.trim().split(','); - const player_position = {}; - player_position.x = parseInt($pos_spl[0]); - player_position.y = parseInt($pos_spl[1]); + const player_position = { + x: parseInt($pos_spl[0]), + y: parseInt($pos_spl[1]), + }; + // player_position.x = parseInt($pos_spl[0]); + // player_position.y = parseInt($pos_spl[1]); const $wh_loot_container = $root.querySelector('#wh-loot-container'); if (!$wh_loot_container) { console.error('掉落助手未找到DOM容器'); ob.observe($root, { childList: true, subtree: true }); return; } - const $blink = $wh_loot_container.querySelector('#wh-loot-setting-blink'); - const $sound = $wh_loot_container.querySelector('#wh-loot-setting-sound'); - const $chest = $wh_loot_container.querySelector('#wh-loot-setting-chest'); + const $blink = $wh_loot_container.querySelector('#wh-loot-setting-blink') as HTMLInputElement; + const $sound = $wh_loot_container.querySelector('#wh-loot-setting-sound') as HTMLInputElement; + const $chest = $wh_loot_container.querySelector('#wh-loot-setting-chest') as HTMLInputElement; const $tbody = $wh_loot_container.querySelector('tbody'); const nearby_arr = []; const items = $root.querySelectorAll('div.grid-layer div.items-layer div.ct-item'); // 附近的所有物品 items.forEach(el => { const item_props = { x: 0, y: 0, name: '', type: '', url: '', }; - item_props.x = parseInt(el.style.left.replaceAll('px', '')) / 30; - item_props.y = -parseInt(el.style.top.replaceAll('px', '')) / 30; + item_props.x = parseInt((el).style.left.replaceAll('px', '')) / 30; + item_props.y = -parseInt((el).style.top.replaceAll('px', '')) / 30; item_props.url = el.firstElementChild.src; const srcSpl = item_props.url.trim().split('/'); item_props.name = srcSpl[6]; @@ -956,10 +833,10 @@ margin: 0 0 3px; $wh_loot_container.querySelector('#wh-loot-item-count').innerText = `(${ item_count })`; if (item_count === 0) { $wh_loot_container_items.innerText = '暂无'; - $wh_loot_container.querySelector('#wh-loot-container-main').style.animation = ''; + ($wh_loot_container.querySelector('#wh-loot-container-main')).style.animation = ''; soundLoopFlag = false; } else { - if ($blink.checked) $wh_loot_container.querySelector('#wh-loot-container-main').style.animation = 'lootFoundAlert 2s infinite'; + if ($blink.checked) ($wh_loot_container.querySelector('#wh-loot-container-main')).style.animation = 'lootFoundAlert 2s infinite'; if ($sound.checked) soundLoopFlag = true; } $wh_loot_container.querySelector('#wh-loot-chest-count').innerText = `(${ chest_count })`; @@ -1040,158 +917,21 @@ margin: 0 0 3px; await rw_raider(); } + // 特定代码块 if (getPlayerInfo()['userID'] === 2687093 && getDeviceType() === Device.PC) { await getSidebarData(); let item = document.getElementById('nav-items'); if (item) { let copy = item.cloneNode(true); - copy.firstChild.style.backgroundColor = '#ff5722'; - let a = copy.firstChild.firstChild; + // TODO 待验证 + (copy.firstChild).style.backgroundColor = '#ff5722'; + // copy.firstChild.style.backgroundColor = '#ff5722'; + let a = copy.firstChild.firstChild as HTMLAnchorElement; a.href = '/item.php?temp=1'; - let span = a.lastChild; + let span = a.lastChild as HTMLElement; span.innerHTML = '物品'; span.style.color = 'white'; item.after(copy); } } - - // mini profile 翻译 - function miniprofTrans() { - // 迷你资料卡状态 - playerStatusTrans($('div.profile-mini-root div.description span')); - // 转钱 - sendCashTrans('div.profile-mini-root'); - } - - // 引入torn miniprofile - function initMiniProf(selector) { - let profileMini = { - timeout: 0, - clickable: false, - rootElement: null, - targetElement: null, - rootId: 'profile-mini-root', - rootSelector: '#profile-mini-root', - userNameSelector: "a[href*='profiles.php?XID=']", - // contentWrapper: '#wh-trans-icon', - contentWrapper: selector, - setClickable: function (value) { - this.clickable = value - }, - setRootElement: function () { - if (!document.getElementById(this.rootId)) { - this.rootElement = document.createElement('div'); - this.rootElement.classList.add(this.rootId); - this.rootElement.id = this.rootId; - $('body').append(this.rootElement); - } else { - ReactDOM.unmountComponentAtNode($(this.rootSelector).get(0)); - this.rootElement = document.getElementById(this.rootId); - } - }, - subscribeForHideListeners: function () { - const that = this; - let width = $(window).width(); - - function handleResize(e) { - if ($(this).width() !== width) { - width = $(this).width(); - hideMiniProfile.call(that, e); - } - } - - function handleScroll(e) { - if (!document.activeElement.classList.contains('send-cash-input')) { - hideMiniProfile.call(that, e); - } - } - - function hideMiniProfile(e) { - if ($(e.target).closest(this.rootSelector).length === 0 || ['resize', 'scroll'].includes(e.type)) { - that.targetElement = null - ReactDOM.unmountComponentAtNode($(this.rootSelector).get(0)); - $(this.userNameSelector).off('click', this.handleUserNameClick); - $(this.userNameSelector).unbind('contextmenu'); - $(document).off('click', hideMiniProfile); - $(window).off('hashchange', hideMiniProfile); - $(window).off('resize', handleResize); - $(window).off('scroll', handleScroll); - } - } - - $(document).on('click', hideMiniProfile.bind(this)); - $(window).on('hashchange', hideMiniProfile.bind(this)); - $(window).on('resize', handleResize); - if (that.targetElement.closest('#chatRoot')) { - $(window).on('scroll', handleScroll); - } - }, - subscribeForUserNameClick: function () { - $(this.userNameSelector).click(this.handleUserNameClick.bind(this)) - }, - handleUserNameClick: function () { - if (!this.clickable) { - this.setClickable(true); - return false; - } - }, - subscribeForContextMenu: function (element) { - $(element).on('contextmenu', function (e) { - e.preventDefault(); - e.stopPropagation(); - e.stopImmediatePropagation(); - return false; - }) - }, - handleMouseDown: function () { - const that = this; - $(this.contentWrapper).on('mousedown touchstart', this.userNameSelector, function (e) { - if (e.which !== 1 && e.type !== 'touchstart') { - return false; - } - that.targetElement = e.currentTarget; - that.subscribeForContextMenu(that.targetElement); - that.handleFocusLost(e.currentTarget); - that.timeout = setTimeout(function () { - if (e.type !== 'touchstart') { - that.setClickable(false); - that.subscribeForUserNameClick(); - } else { - $(e.currentTarget).off('touchmove mouseleave'); - } - that.subscribeForHideListeners(); - that.setRootElement(); - const userID = e.currentTarget.search.slice('?XID='.length); - const props = { - userID: userID, - event: e.originalEvent - }; - window.renderMiniProfile(that.rootElement, props); - }, 500); - if (e.type !== 'touchstart') { - return false; - } - }) - }, - handleMouseUp: function () { - const that = this; - $(this.contentWrapper).on('mouseup touchend', this.userNameSelector, function () { - that.timeout && clearTimeout(that.timeout); - }) - }, - handleFocusLost: function (element) { - const that = this; - $(element).on('touchmove mouseleave', function unsubscribe() { - that.timeout && clearTimeout(that.timeout); - $(this).off('touchmove mouseleave', unsubscribe) - }) - }, - init: function () { - this.handleMouseDown(); - this.handleMouseUp(); - } - }; - profileMini.init(); - } - } \ No newline at end of file