import WT_HTML from "../../../static/html/xmasTown/wt.html"; import WT_XMAS_TOWN_HTML from "../../../static/html/xmasTown/wt_xmas_town.html"; import WT_MALTESE_SNOW_GLOBE_HTML from "../../../static/html/xmasTown/wt_maltese_snow_globe.html"; import WT_LONG_WAY_FROM_HOME_HTML from "../../../static/html/xmasTown/wt_long_way_from_home.html"; import WT_CHEDBURN_TOWERS_HTML from "../../../static/html/xmasTown/wt_chedburn_towers.html"; import WT_KIDNAPPED_SANTA_HTML from "../../../static/html/xmasTown/wt_kidnapped_santa.html"; import WT_HOLIDAY_TERROR_HTML from "../../../static/html/xmasTown/wt_holiday_terror.html"; import WT_AMONG_US_HTML from "../../../static/html/xmasTown/wt_among_us.html"; import WT_KISS_MY_FESTIVUS_HTML from "../../../static/html/xmasTown/wt_kiss_my_festivus.html"; import WT_STANLEY_HOTEL_HTML from "../../../static/html/xmasTown/wt_stanley_hotel.html"; import WT_DOGGOQUEST_HTML from "../../../static/html/xmasTown/wt_doggoQuest.html"; import WT_POKEMON_CT_HTML from "../../../static/html/xmasTown/wt_pokemon_ct.html"; import WT_WINTER_IN_GATLIN_HTML from "../../../static/html/xmasTown/wt_winter_in_gatlin.html"; import XMAS_TOWN_NOTIFY_HTML from "../../../static/html/xmasTown/xmas_town_notify.html"; import { Container } from "../../container/Container"; import LocalConfigWrapper from "../../class/LocalConfigWrapper"; export default function christmasTownHelper() { const localConfigWrapper = Container.factory(LocalConfigWrapper); let $root = document.querySelector('#christmastownroot'); const xmasTownWT = localConfigWrapper.config.xmasTownWT; const xmasTownNotify = localConfigWrapper.config.xmasTownNotify; // 解密攻略 if (xmasTownWT) { const insert_html = WT_HTML; const wt_dict = { "None": { title: '', wt: ``, }, "Christmas Town": { title: '圣诞小镇', wt: WT_XMAS_TOWN_HTML, }, "Maltese Snow Globe": { title: 'Maltese Snow Globe', wt: WT_MALTESE_SNOW_GLOBE_HTML, }, "Long way from home": { title: 'Long way from home', wt: WT_LONG_WAY_FROM_HOME_HTML, }, "Chedburn Towers": { title: 'Chedburn Towers', wt: WT_CHEDBURN_TOWERS_HTML, }, "Kidnapped Santa": { title: 'Kidnapped Santa', wt: WT_KIDNAPPED_SANTA_HTML, }, "Holiday terror": { title: 'Holiday terror', wt: WT_HOLIDAY_TERROR_HTML, }, "Among Us": { title: 'Among Us', wt: WT_AMONG_US_HTML, }, "Kiss My Festivus": { title: 'Kiss My Festivus', wt: WT_KISS_MY_FESTIVUS_HTML, }, "Stanley Hotel": { title: 'Stanley Hotel', wt: WT_STANLEY_HOTEL_HTML, }, "DoggoQuest": { title: 'DoggoQuest', wt: WT_DOGGOQUEST_HTML, }, "Pokemon CT": { title: 'Pokemon CT', wt: WT_POKEMON_CT_HTML, }, "Winter in Gatlin": { title: 'Winter in Gatlin', wt: WT_WINTER_IN_GATLIN_HTML, }, }; const $city_wrapper = $root.querySelectorAll('div[class^="core-layout__"]'); $city_wrapper.forEach(el => { let $wh_container = $root.querySelector('#wh-xmas-cont'); if (!$wh_container) { $(el).prepend(insert_html); $wh_container = $root.querySelector('#wh-xmas-cont'); // 显示 隐藏 const jquery$wh_container = $($wh_container); const $cont_gray = jquery$wh_container.find('.cont-gray'); jquery$wh_container.find('button').click(e => { if (e.target.innerText === '[隐藏]') { $cont_gray.hide(); e.target.innerText = '[显示]'; } else { $cont_gray.show(); e.target.innerText = '[隐藏]'; } }); // 内容 const $wt_content = jquery$wh_container.find('#wt-content'); jquery$wh_container.find('select').change(e => { const selected = e.target.value; $wt_content.html(`

${ wt_dict[selected].title }

${ wt_dict[selected].wt }

`) }); } }); } // 宝箱检测 if (xmasTownNotify) { const chestTypeDict = { '1': '金', '2': '银', '3': '铜', }; const chestTypeColorDict = { '1': 'gold', '2': 'silver', '3': 'sandybrown', }; const lootTypeDict = { 'chests': '钥匙箱', 'gifts': '礼物', 'combinationChest': '密码箱', 'keys': '钥匙', }; const keyTypeDict = { 'b': '铜', 's': '银', 'g': '金', }; let dropHist = localStorage.getItem('wh-loot-store') ? JSON.parse(localStorage.getItem('wh-loot-store')) : {}; const alertSettings = localStorage.getItem('wh-loot-setting') ? JSON.parse(localStorage.getItem('wh-loot-setting')) : { blink: 'y', sound: 'y', chest: 'y' }; let $ct_wrap; let soundLoopFlag = false; const getDOMOb = new MutationObserver(() => { $ct_wrap = $root.querySelector('#ct-wrap'); if ($ct_wrap) { getDOMOb.disconnect(); const insert_html = XMAS_TOWN_NOTIFY_HTML .replace('{{}}', alertSettings.blink === 'y' ? 'checked' : '') .replace('{{}}', alertSettings.sound === 'y' ? 'checked' : '') .replace('{{}}', alertSettings.chest === 'y' ? 'checked' : ''); $($ct_wrap).before(insert_html); 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') 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 => { let target = e.target as HTMLButtonElement; target.innerText = target.innerText === '设置' ? '收起' : '设置'; $($ex).toggleClass('wh-hide'); target.blur(); }; $clear_btn.onclick = e => { 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) { 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'; } } else { alertSettings.blink = 'n'; ($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) { alertSettings.sound = 'y'; if ($wh_loot_container.querySelector('#wh-loot-item-count').innerText !== '(0)') { soundLoopFlag = true; } } else { alertSettings.sound = 'n'; soundLoopFlag = false; } localStorage.setItem('wh-loot-setting', JSON.stringify(alertSettings)); }; $chest.onchange = e => { alertSettings.chest = (e.target).checked ? 'y' : 'n'; localStorage.setItem('wh-loot-setting', JSON.stringify(alertSettings)); }; const soundIntervalID = window.setInterval(() => { if (soundLoopFlag) $audio.play().then(); }, 1200); ob.observe($root, { childList: true, subtree: true }); } }); const ob = new MutationObserver(() => { ob.disconnect(); // 页面刷新重新获取dom $root = document.querySelector('#christmastownroot'); $ct_wrap = $root.querySelector('#ct-wrap'); if (!$ct_wrap) { ob.observe($root, { childList: true, subtree: true }); return; } const $ct_title = $ct_wrap.querySelector('.status-title'); const $pos = $ct_wrap.querySelector('.map-title span[class^="position___"]') || $ct_wrap.querySelector('.status-title span[class^="position___"]'); if (!$pos) { ob.observe($root, { childList: true, subtree: true }); return; } const $pos_spl = $pos.innerText.trim().split(','); 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') 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.url = el.firstElementChild.src; const srcSpl = item_props.url.trim().split('/'); item_props.name = srcSpl[6]; item_props.type = srcSpl[8].slice(0, 1); nearby_arr.push(item_props); }); const $wh_loot_container_items = $wh_loot_container.querySelector('#wh-loot-container-items'); const $wh_loot_container_chests = $wh_loot_container.querySelector('#wh-loot-container-chests'); let item_count = 0, chest_count = 0; $wh_loot_container_items.innerHTML = ''; $wh_loot_container_chests.innerHTML = ''; nearby_arr.forEach(nearby_item => { let path = '='; if (nearby_item.x < player_position.x && nearby_item.y < player_position.y) path = '↙'; else if (nearby_item.x < player_position.x && nearby_item.y === player_position.y) path = '←'; else if (nearby_item.x < player_position.x && nearby_item.y > player_position.y) path = '↖'; else if (nearby_item.x === player_position.x && nearby_item.y > player_position.y) path = '↑'; else if (nearby_item.x > player_position.x && nearby_item.y > player_position.y) path = '↗'; else if (nearby_item.x > player_position.x && nearby_item.y === player_position.y) path = '→'; else if (nearby_item.x > player_position.x && nearby_item.y < player_position.y) path = '↘'; else if (nearby_item.x === player_position.x && nearby_item.y < player_position.y) path = '↓'; let item_name; if (nearby_item.name === 'chests') { chest_count++; item_name = chestTypeDict[nearby_item.type] + lootTypeDict[nearby_item.name]; $wh_loot_container_chests.innerHTML += `${ path }[${ nearby_item.x },${ nearby_item.y }] ${ item_name }` } else { item_count++; item_name = (nearby_item.name === 'keys' ? keyTypeDict[nearby_item.type] || '' : '') + lootTypeDict[nearby_item.name] || nearby_item.name; $wh_loot_container_items.innerHTML += `${ path }[${ nearby_item.x },${ nearby_item.y }] ${ item_name }` } // 确认地图坐标存在 if ($ct_title) { const hist_key = `[${ nearby_item.x },${ nearby_item.y }]"${ $ct_title.firstChild.nodeValue.trim() }"${ item_name }`; const el = dropHist[hist_key]; if (el) { if (path === '=' && (nearby_item.name === 'keys' || nearby_item.name === 'gifts')) { el.isPassed = true; } } else { if (!(nearby_item.name === 'chests' && $chest.checked)) { const now = new Date(); dropHist[hist_key] = { pos: `[${ nearby_item.x },${ nearby_item.y }]`, data: $ct_title.firstChild.nodeValue.trim(), last: `${ now.getFullYear() }-${ now.getMonth() + 1 }-${ now.getDate() } ${ now.getHours() }:${ now.getMinutes() }:${ now.getSeconds() }`, name: item_name, id: Object.keys(dropHist).length, }; } } } }); $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 = ''; soundLoopFlag = false; } else { 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 })`; if (chest_count === 0) $wh_loot_container_chests.innerText = '暂无'; const history = Object.keys(dropHist).map(key => dropHist[key]).sort((a, b) => a.id - b.id); let table_html = ''; history.forEach(e => { table_html += `${ e.pos }${ e.map }${ e.name }${ e.last }${ e.isPassed ? '已取得' : '不确定' }`; }); $tbody.innerHTML = table_html; localStorage.setItem('wh-loot-store', JSON.stringify(dropHist)); ob.observe($root, { childList: true, subtree: true }); }); getDOMOb.observe($root, { childList: true, subtree: true }); } }