【赛博徒步】生死鳌太线-附修改脚本

2026-04-11 15:111阅读0评论SEO资源
  • 内容介绍
  • 文章标签
  • 相关推荐
问题描述:

上一个帖子不能编辑了 特开新帖
游戏地址:赛博徒步:生死鳌太线 | 一场关于意志与生存的终极考验
image1552×852 108 KB
image791×592 41.4 KB
很久之前就有佬友推荐过 作者一直在更新 随着细节丰富 越来越真实了
没有徒步经验的佬友可以体验一下到底有多难

附上我迭代更新了一个月的脚本:不建议用 用了就没意思了
①解锁付费订阅 支持付费下撤路线(你没看错有氪金项目 还有反调试)
②解锁并未开放的卫星电话 可以救驴友远山了
③解锁全成就&称号
④全物品添加&全地点瞬移
⑤修改属性(体温、体力、精神、饱腹、业力、预算、负重、天数、电话电量)
Tips:在死亡界面修改属性可以强行原地复活

// ==UserScript== // @name 赛博徒步:生死鳌太线 理想值修改器 V7 // @namespace http://tampermonkey.net/ // @version 7.0 // @description 数值修改 + `/~ 显示隐藏 + 面板记忆 + 节点瞬移(中文下拉+自动收集新节点+仅保留“保存当前节点”) // @author @Wet_Dream_Boy // @match https://cyberhiking.com/* // @grant none // @run-at document-start // @require https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js // ==/UserScript== (function () { 'use strict'; const STORAGE_KEY = 'aotai-survival-storage'; const CRYPTO_KEY = 'aotai-survival@2024'; const UI_ID = 'cyber-mod-v6-root'; // 面板输入记忆 const UI_PREF_KEY = 'aotai-ideal-panel-values-v6'; // 节点列表记忆(下拉中文/自动新增也会保存) const UI_NODE_LIST_KEY = 'aotai-node-list-v6'; let isVisible = true; // --- 理想默认值配置 --- const IDEAL_VALUES = { temp: 36.5, stamina: 100, sanity: 100, hunger: 100, karma: 1000, budget: 99999, weight: 0.1, day: 1, battery: 100, victoryCount: 9, hasMountainGodPass: false, subscriptions: '', lastItemId: 'backpack_expedition', }; // --- 默认节点(你在脚本里维护;下拉中文显示)--- const DEFAULT_NODES = [ // --- 正常路线 (塘口 -> 南塬) --- { id: 'tangkou', name: '塘口' }, { id: 'longwanghekou', name: '龙王河口' }, { id: 'xihuagou', name: '西桦沟' }, // ✅ 修正 { id: 'huoshaopo', name: '火烧坡' }, { id: 'camp_2900', name: '2900营地' }, { id: 'penjingyuan', name: '盆景园' }, { id: 'baiqimiao', name: '白起庙' }, { id: 'aotou', name: '鳌头' }, { id: 'aoshanding', name: '鳌山顶' }, { id: 'west_paoma', name: '西跑马梁' }, { id: 'yaowangmiao', name: '药王庙' }, { id: 'maijie_ridge', name: '麦秸岭' }, { id: 'wenxiong_stone', name: '文胸石' }, // ✅ 修正 { id: 'shuiwozi', name: '水窝子' }, { id: 'monument', name: '纪念碑' }, // 纪念碑通常在水窝子到飞机梁之间 { id: 'feiji_liang', name: '飞机梁' }, // ✅ 按你要求:不动 { id: 'liang_yi', name: '梁一' }, { id: 'liang_er', name: '梁二' }, { id: 'liang_san', name: '梁三' }, { id: 'camp_2800', name: '2800营地' }, { id: 'nantianmen_pass', name: '南天门垭口' }, // ✅ 保持你的写法 { id: 'nantianmen_forest', name: '南天门林区' }, { id: 'nantianmen_camp', name: '南天门营地' }, { id: 'pyramid', name: '金字塔' }, { id: 'ta_yi', name: '塔一' }, { id: 'ta_er', name: '塔二' }, { id: 'ta_san', name: '塔三' }, { id: 'jiuchongtian', name: '九重天' }, { id: 'xiyuan_camp', name: '西源营地' }, { id: 'dongyuan_camp', name: '东源营地' }, { id: 'wanxian_array', name: '万仙阵' }, { id: 'leigong_temple', name: '雷公庙' }, { id: 'paoma_liang', name: '跑马梁' }, { id: 'dayehai', name: '大爷海' }, { id: 'dawengong_temple', name: '大文公庙' }, { id: 'fangyang_temple', name: '放羊寺' }, { id: 'mingxing_temple', name: '明星寺' }, { id: 'pingan_temple', name: '平安寺' }, { id: 'nanyuan_village', name: '南塬村' }, // --- 下撤/支线/其他 --- { id: 'qiaodiping', name: '桥底坪' }, { id: 'baiyun_bridge', name: '白云桥' }, { id: 'baiyun_gorge_new', name: '白云峡谷(新)' }, { id: 'maershan_village', name: '马耳山村' }, { id: 'yingge_town', name: '鹦哥镇' }, // 你如果要“鹦鸽镇”就改这里 // --- 北坡下撤路线 --- { id: 'northern_slope_bottom', name: '北坡沟底' }, { id: 'northern_slope_channel', name: '北坡沟道' }, { id: 'northern_slope_river', name: '北坡河道' }, { id: 'northern_slope_ridge', name: '北坡山脊' }, { id: 'northern_slope_cliff_1', name: '北坡悬崖段 1' }, { id: 'northern_slope_cliff_2', name: '北坡悬崖段 2' }, { id: 'northern_slope_cliff_3', name: '北坡悬崖段 3' }, { id: 'northern_slope_valley_1', name: '北坡河谷段 1' }, { id: 'northern_slope_valley_2', name: '北坡山谷段 2' }, ]; // --- 物品列表 (ID -> 中文) --- const ITEM_MAP = [ { id: 'backpack_small', name: '45L 轻量背包' }, { id: 'backpack_medium', name: '65L 进阶背包' }, { id: 'backpack_large', name: '85L 重装背包' }, { id: 'backpack_expedition', name: '100L 远征背包' }, { id: 'poles', name: '碳纤维登山杖' }, { id: 'knee_pads', name: '专业护膝' }, { id: 'tent_4season', name: '高山四季帐' }, { id: 'raincoat', name: '轻量化雨衣' }, { id: 'wind_goggles', name: '防风护目镜' }, { id: 'gloves', name: '防风保暖手套' }, { id: 'mountain_windproof_hat', name: '高山防风保暖帽' }, { id: 'balaclava', name: '防风面罩' }, { id: 'sleeping_pad', name: '高R值防潮垫' }, { id: 'sleeping_bag_0', name: '0°C鹅绒睡袋' }, { id: 'sleeping_bag_10', name: '-10°C鹅绒睡袋' }, { id: 'sleeping_bag_20', name: '-20°C鹅绒睡袋' }, { id: 'sleeping_bag_30', name: '-30°C鹅绒睡袋' }, { id: 'headlamp', name: '专业头灯' }, { id: 'snowshoes', name: '简易冰爪' }, { id: 'snow_gaiters', name: '防雪套' }, { id: 'food_ration', name: '压缩饼干' }, { id: 'chocolate', name: '高能黑巧克力' }, { id: 'energy_gel', name: '能量胶' }, { id: 'salt_pill', name: '电解质盐丸' }, { id: 'gas_tank', name: '高山稳压气罐' }, { id: 'stove', name: '高山稳压炉头' }, { id: 'med_kit', name: '野外医疗包' }, { id: 'emergency_blanket', name: '保温毯' }, { id: 'hand_warmer', name: '暖身贴' }, { id: 'water_filter', name: '户外净水器' }, { id: 'rope', name: '登山绳索' }, { id: 'gps_device', name: '手持GPS导航仪' }, { id: 'satellite_phone', name: '卫星电话' } ]; const ALL_TITLES = [ 'aotai_guardian', 'cyber_living_buddha', 'cyber_philanthropist', 'speedrun_master', 'aotai_photographer', 'aotai_savage', 'hercules', 'qinggong_master', 'biscuit_manufacturer', 'biscuit_wholesaler', 'chocolate_factory', 'wealth_scatterer', 'iron_rooster', 'old_acquaintance', 'freezing_victim', 'freezing_survivor', 'indigenous', 'wicked_master', 'unfulfilled_ambition', 'rookie_driver', 'hunger_king_title', 'aotai_powerful_donkey', 'rational_walker', 'lucky_survivor', 'tangkou_villager', 'tangkou_village_chief', 'victim', 'shennong_descendant', 'bear_grylls_disciple', 'gas_master', 'cure_all' ]; const ALL_ACHIEVEMENTS = [ // --- 58 Achievements from Web (v1.0+) --- 'first_step', 'cloud_wall', 'mountain_master', 'survivor_7d', 'survivor_3d', 'high_altitude', 'nature_lover', 'rich_hiker', 'aotai_photographer', 'kind_heart', 'orographic_slayer', 'destined_meeting', 'golden_sunrise', 'thunder_survivor', 'lnt_guardian', 'star_gazer', 'rare_beast', 'fog_walker', 'night_owl', 'bull_tamer', 'cloud_sea', 'rainbow', 'moon_phantom', 'storm_stoic', 'rainrunner', 'sunset_watcher', 'berry_taster', 'quick_meet', 'memorial_respect', 'together', 'frugal_survivor', 'qinggong_master', 'load_shedder', 'diary_keeper', 'water_connoisseur', 'lost_and_found', 'iron_grip', 'noodle_king', 'free_solo', 'ice_glider', 'generous_soul', 'wild_vet', 'iron_will', 'snow_wise', 'solitude_talk', 'rock_dodger', 'detail_oriented', 'heroic_messenger', 'wind_fighter', 'seven_times_hero', 'mountain_pact', 'spirit_guide', 'accident_survivor', 'lucky_survivor', 'hitchhiker', 'worldly_fireworks', 'equipment_guard', 'wind_repair', // --- Potential Legacy/Save-only IDs (Keep safe) --- 'light_packer', 'water_filter_master', 'hiker_friend', 'hardship_comrade', 'lucky_panda', 'conqueror', 'photographer', 'gale_walker', 'god_of_aotai', 'solitude_survivor', 'tent_rigger' ]; // ====== 工具函数 ====== function loadPanelPrefs() { try { const raw = localStorage.getItem(UI_PREF_KEY); if (!raw) return { ...IDEAL_VALUES }; const parsed = JSON.parse(raw); return { ...IDEAL_VALUES, ...parsed }; } catch (e) { return { ...IDEAL_VALUES }; } } function savePanelPrefs(prefs) { try { localStorage.setItem(UI_PREF_KEY, JSON.stringify(prefs)); } catch (e) { } } function normalizeNodeList(list) { const map = new Map(); // 读用户保存的 (Array.isArray(list) ? list : []).forEach(x => { if (!x || typeof x.id !== 'string') return; const id = x.id.trim(); if (!id) return; const name = (x.name || id).toString().trim() || id; map.set(id, { id, name }); }); // 补齐默认节点(不覆盖用户自定义) DEFAULT_NODES.forEach(d => { if (!map.has(d.id)) map.set(d.id, { id: d.id, name: d.name || d.id }); }); return [...map.values()]; } function loadNodeList() { try { const raw = localStorage.getItem(UI_NODE_LIST_KEY); if (!raw) return normalizeNodeList(DEFAULT_NODES); return normalizeNodeList(JSON.parse(raw)); } catch (e) { return normalizeNodeList(DEFAULT_NODES); } } function saveNodeList(list) { try { localStorage.setItem(UI_NODE_LIST_KEY, JSON.stringify(normalizeNodeList(list))); } catch (e) { } } function upsertNode(list, id, name) { id = (id || '').trim(); if (!id) return list; const next = normalizeNodeList(list); const idx = next.findIndex(x => x.id === id); const item = { id, name: (name || id).toString().trim() || id }; if (idx >= 0) next[idx] = item; else next.push(item); return next; } function decryptData(raw) { if (!raw) return null; try { const parsed = JSON.parse(raw); const bytes = CryptoJS.AES.decrypt(parsed.cipher, CRYPTO_KEY); return JSON.parse(bytes.toString(CryptoJS.enc.Utf8)); } catch (e) { return null; } } function encryptData(data) { try { const cipher = CryptoJS.AES.encrypt(JSON.stringify(data), CRYPTO_KEY).toString(); return JSON.stringify({ "__aotai_enc__": true, "v": 1, "cipher": cipher }); } catch (e) { return null; } } function dispatchStorage(key, newValue, oldValue) { try { window.dispatchEvent(new StorageEvent('storage', { key, newValue, oldValue, storageArea: localStorage, url: location.href })); } catch (e) { } } function isTypingTarget(el) { if (!el) return false; const tag = (el.tagName || '').toLowerCase(); return tag === 'input' || tag === 'textarea' || el.isContentEditable; } function safeNumber(v, fallback) { const n = Number(v); return Number.isFinite(n) ? n : fallback; } function zhSort(a, b) { return (a || '').localeCompare((b || ''), 'zh-Hans-CN'); } // ====== UI ====== function createUI() { if (document.getElementById(UI_ID)) return; const prefs = loadPanelPrefs(); let nodeList = loadNodeList(); const host = document.createElement('div'); host.id = UI_ID; host.style.cssText = 'position: fixed; top: 10px; right: 10px; z-index: 2147483647; transition: opacity 0.2s;'; document.documentElement.appendChild(host); const shadow = host.attachShadow({ mode: 'closed' }); const container = document.createElement('div'); container.style.cssText = ` background: rgba(15, 15, 15, 0.98); color: #00ff00; padding: 15px; border: 1px solid #00ff00; border-radius: 4px; font-family: 'Consolas', 'Monaco', monospace; font-size: 12px; width: 300px; box-shadow: 0 0 15px rgba(0, 255, 0, 0.2); max-height: 85vh; overflow-y: auto; `; container.innerHTML = ` <div style="text-align:center;font-weight:bold;margin-bottom:10px;border-bottom:1px solid #00ff00;padding-bottom:6px;"> CYBER-HIKING IDEAL V7 </div> <style> .section-title { color:#888;font-size:10px;margin:10px 0 6px 0;text-transform:uppercase; } .row { margin-bottom:6px; display:flex; justify-content:space-between; align-items:center; gap:8px; } input, select { width: 150px; background:#000; color:#0ff; border:1px solid #333; padding:2px 4px; font-size:11px; box-sizing:border-box; } button { width:100%; padding:4px; margin-top:8px; cursor:pointer; border:1px solid #00ff00; background:transparent; color:#00ff00; font-weight:bold; } button:hover { background:#00ff00; color:#000; } .btn2 { display:flex; gap:8px; margin-top:8px; } .btn2 button { width: 50%; margin-top:0; } #status { font-size:10px; color:#555; margin-top:10px; text-align:center; } .small { font-size:10px; color:#777; } </style> <div class="section-title">基础生存属性</div> <div class="row"><span>体温</span><input type="number" id="in-temp" step="0.1" value="${prefs.temp}"></div> <div class="row"><span>体力</span><input type="number" id="in-stamina" value="${prefs.stamina}"></div> <div class="row"><span>精神</span><input type="number" id="in-sanity" value="${prefs.sanity}"></div> <div class="row"><span>饱腹</span><input type="number" id="in-hunger" value="${prefs.hunger}"></div> <div class="section-title">进阶属性</div> <div class="row"><span>业力</span><input type="number" id="in-karma" value="${prefs.karma}"></div> <div class="row"><span>预算</span><input type="number" id="in-budget" value="${prefs.budget}"></div> <div class="row"><span>负重</span><input type="number" id="in-weight" step="0.1" value="${prefs.weight}"></div> <div class="section-title">环境与设备</div> <div class="row"><span>当前天数</span><input type="number" id="in-day" value="${prefs.day}"></div> <div class="row"><span>卫星电话电量</span><input type="number" id="in-battery" value="${prefs.battery}"></div> <div class="section-title">特殊权限 & 记录</div> <div class="row"><span>通关次数</span><input type="number" id="in-victory" value="${prefs.victoryCount}"></div> <div class="row"> <span>山神通行证</span> <select id="in-pass"> <option value="true" ${prefs.hasMountainGodPass ? 'selected' : ''}>已拥有 (Yes)</option> <option value="false" ${!prefs.hasMountainGodPass ? 'selected' : ''}>未拥有 (No)</option> </select> </div> <div class="row"><span>订阅(逗号隔开)</span><input type="text" id="in-subs" value="${prefs.subscriptions}" placeholder="vip, etc"></div> <button id="apply">应用数值并刷新</button> <div class="row" style="margin-top: 15px;"> <button id="unlock-all">解锁全成就&称号</button> </div> <div class="row" style="margin-top: 15px;"> <span>物品</span> <select id="in-item" style="width: 110px;"></select> <input type="number" id="in-item-count" value="1" style="width: 50px;" title="数量"> </div> <div class="btn2"> <button id="add-item">添加</button> <button id="add-all-items">全都要(+1)</button> </div> <div class="row" style="margin-top: 15px;"> <span>目的地</span> <select id="in-node"></select> </div> <div class="small">当前节点:<span id="cur-node">读取中...</span></div> <div class="btn2"> <button id="teleport">瞬移并刷新</button> <button id="save-node">保存当前节点</button> </div> <div id="status">\` / ~ 切换显示隐藏;Ctrl+Alt+~ 强制显示</div> `; shadow.appendChild(container); const $ = (id) => shadow.getElementById(id); function getDecryptedState() { const raw = localStorage.getItem(STORAGE_KEY); const obj = decryptData(raw); return { raw, obj }; } function writeStateAndReload(newObj, oldRaw) { const newRaw = encryptData(newObj); if (!newRaw) return alert('加密失败,无法写入存档。'); // 1. 写入我们的数据 localStorage.setItem(STORAGE_KEY, newRaw); dispatchStorage(STORAGE_KEY, newRaw, oldRaw); // 2. 关键:劫持 setItem 防止游戏在 reload 前瞬间覆盖回去 (Game Auto-Save / Unload Save) // "Cyber-Block": Block the game from overwriting our perfect save. const originalSetItem = localStorage.setItem; localStorage.setItem = function (key, value) { if (key === STORAGE_KEY) { console.log('[CyberMod] 拦截到游戏尝试覆盖存档 -> 已阻止'); return; } originalSetItem.call(localStorage, key, value); }; // 3. 立即刷新,不再等待 location.reload(); } // ... (existing helper functions) ... $('apply').onclick = () => { // ... (existing apply logic) ... const { raw: oldRaw, obj } = getDecryptedState(); if (!obj?.state) return alert('未找到存档数据,请先开始游戏!'); const p = readPrefsFromInputs(); savePanelPrefs(p); obj.state.stats.temp = p.temp; obj.state.stats.stamina = p.stamina; obj.state.stats.sanity = p.sanity; obj.state.stats.hunger = p.hunger; obj.state.stats.karma = p.karma; obj.state.budget = p.budget; obj.state.weight = p.weight; obj.state.day = p.day; obj.state.satellitePhoneBattery = p.battery; obj.state.victoryCount = p.victoryCount; obj.state.hasMountainGodPass = p.hasMountainGodPass; if (!obj.state.user) obj.state.user = {}; const subList = (p.subscriptions || '').split(/[,,]/).map(s => s.trim()).filter(Boolean); obj.state.user.subscriptions = subList; writeStateAndReload(obj, oldRaw); }; function refreshNodeSelect(selectedId) { const sel = $('in-node'); sel.innerHTML = ''; const sorted = [...nodeList].sort((a, b) => { const idxA = DEFAULT_NODES.findIndex(x => x.id === a.id); const idxB = DEFAULT_NODES.findIndex(x => x.id === b.id); // If both are in default list, sort by index if (idxA >= 0 && idxB >= 0) return idxA - idxB; // If one is in default list, it comes first if (idxA >= 0) return -1; if (idxB >= 0) return 1; // Otherwise sort alphabetically return zhSort(a.name || a.id, b.name || b.id); }); sorted.forEach(n => { const opt = document.createElement('option'); opt.value = n.id; opt.textContent = `${n.name || n.id} (${n.id})`; sel.appendChild(opt); }); if (selectedId) sel.value = selectedId; } function refreshItemSelect(selectedId) { const sel = $('in-item'); sel.innerHTML = ''; ITEM_MAP.forEach(item => { const opt = document.createElement('option'); opt.value = item.id; opt.textContent = `${item.name} (${item.id})`; sel.appendChild(opt); }); if (selectedId) sel.value = selectedId; } function readPrefsFromInputs() { return { temp: safeNumber($('in-temp').value, IDEAL_VALUES.temp), stamina: safeNumber($('in-stamina').value, IDEAL_VALUES.stamina), sanity: safeNumber($('in-sanity').value, IDEAL_VALUES.sanity), hunger: safeNumber($('in-hunger').value, IDEAL_VALUES.hunger), karma: safeNumber($('in-karma').value, IDEAL_VALUES.karma), budget: safeNumber($('in-budget').value, IDEAL_VALUES.budget), weight: safeNumber($('in-weight').value, IDEAL_VALUES.weight), day: parseInt($('in-day').value, 10) || IDEAL_VALUES.day, battery: safeNumber($('in-battery').value, IDEAL_VALUES.battery), victoryCount: safeNumber($('in-victory').value, IDEAL_VALUES.victoryCount), hasMountainGodPass: $('in-pass').value === 'true', subscriptions: $('in-subs').value || '', lastItemId: $('in-item').value, }; } // 数值输入即记忆 ['in-temp', 'in-stamina', 'in-sanity', 'in-hunger', 'in-karma', 'in-budget', 'in-weight', 'in-day', 'in-battery', 'in-victory', 'in-pass', 'in-subs', 'in-item'] .forEach(id => { const el = $(id); el.addEventListener('input', () => savePanelPrefs(readPrefsFromInputs())); el.addEventListener('change', () => savePanelPrefs(readPrefsFromInputs())); }); // init:同步当前节点 + 确保自动收集 (function initNodeUI() { nodeList = loadNodeList(); const { obj } = getDecryptedState(); const cur = obj?.state?.currentNodeId || '(未知)'; $('cur-node').textContent = cur; // 自动把当前节点加入列表(如果不在默认里) if (cur && cur !== '(未知)') { const found = nodeList.find(x => x.id === cur); nodeList = upsertNode(nodeList, cur, found?.name || cur); saveNodeList(nodeList); } refreshNodeSelect(cur); refreshItemSelect(prefs.lastItemId); })(); $('apply').onclick = () => { const { raw: oldRaw, obj } = getDecryptedState(); if (!obj?.state) return alert('未找到存档数据,请先开始游戏!'); const p = readPrefsFromInputs(); savePanelPrefs(p); obj.state.stats.temp = p.temp; obj.state.stats.stamina = p.stamina; obj.state.stats.sanity = p.sanity; obj.state.stats.hunger = p.hunger; obj.state.stats.karma = p.karma; obj.state.budget = p.budget; obj.state.weight = p.weight; obj.state.day = p.day; obj.state.satellitePhoneBattery = p.battery; // New features obj.state.victoryCount = p.victoryCount; obj.state.hasMountainGodPass = p.hasMountainGodPass; // Subscriptions parsing if (!obj.state.user) obj.state.user = {}; const subList = (p.subscriptions || '').split(/[,,]/).map(s => s.trim()).filter(Boolean); obj.state.user.subscriptions = subList; writeStateAndReload(obj, oldRaw); }; $('add-item').onclick = () => { const itemId = $('in-item').value; const countStr = $('in-item-count').value; const count = parseInt(countStr, 10) || 1; if (!itemId) return; const { raw: oldRaw, obj } = getDecryptedState(); if (!obj?.state) return alert('未找到存档数据,请先开始游戏!'); if (!obj.state.inventory) obj.state.inventory = {}; const currentCount = obj.state.inventory[itemId] || 0; obj.state.inventory[itemId] = currentCount + count; writeStateAndReload(obj, oldRaw); }; $('add-all-items').onclick = () => { const { raw: oldRaw, obj } = getDecryptedState(); if (!obj?.state) return alert('未找到存档数据,请先开始游戏!'); if (!obj.state.inventory) obj.state.inventory = {}; ITEM_MAP.forEach(item => { const cid = item.id; const currentCount = obj.state.inventory[cid] || 0; obj.state.inventory[cid] = currentCount + 1; }); writeStateAndReload(obj, oldRaw); }; $('teleport').onclick = () => { const target = $('in-node').value; if (!target) return; const { raw: oldRaw, obj } = getDecryptedState(); if (!obj?.state) return alert('未找到存档数据,请先开始游戏!'); obj.state.currentNodeId = target; obj.state.pendingTransition = null; obj.state.currentEvent = null; obj.state.currentMission = null; writeStateAndReload(obj, oldRaw); }; $('save-node').onclick = () => { const { obj } = getDecryptedState(); const cur = obj?.state?.currentNodeId; if (!cur) return alert('当前节点未知'); // 若默认表里有中文就用中文;否则用 id 占位 const fromDefault = DEFAULT_NODES.find(x => x.id === cur); nodeList = upsertNode(nodeList, cur, fromDefault?.name || cur); saveNodeList(nodeList); // 立刻刷新下拉(你会马上看到新增) refreshNodeSelect(cur); alert(`✅ 已保存当前节点:${fromDefault?.name || cur} (${cur})`); }; $('unlock-all').onclick = () => { if (!confirm('确定要解锁所有 31 个称号和 69 个成就吗?\n这将直接修改存档记录。')) return; const { raw: oldRaw, obj } = getDecryptedState(); if (!obj?.state) return alert('未找到存档数据,请先开始游戏!'); if (!obj.state.user) obj.state.user = {}; // Init arrays if missing obj.state.user.titles = obj.state.user.titles || []; obj.state.unlockedTitles = obj.state.unlockedTitles || []; obj.state.user.achievements = obj.state.user.achievements || []; obj.state.unlockedAchievements = obj.state.unlockedAchievements || []; let addedT = 0; let addedA = 0; // Add Titles const userTitlesSet = new Set(obj.state.user.titles); const unlockedTitlesSet = new Set(obj.state.unlockedTitles); ALL_TITLES.forEach(t => { if (!userTitlesSet.has(t)) { userTitlesSet.add(t); addedT++; } if (!unlockedTitlesSet.has(t)) { unlockedTitlesSet.add(t); } }); obj.state.user.titles = Array.from(userTitlesSet); obj.state.unlockedTitles = Array.from(unlockedTitlesSet); // Add Achievements const userAchSet = new Set(obj.state.user.achievements); const unlockedAchSet = new Set(obj.state.unlockedAchievements); ALL_ACHIEVEMENTS.forEach(a => { if (!userAchSet.has(a)) { userAchSet.add(a); addedA++; } if (!unlockedAchSet.has(a)) { unlockedAchSet.add(a); } }); obj.state.user.achievements = Array.from(userAchSet); obj.state.unlockedAchievements = Array.from(unlockedAchSet); writeStateAndReload(obj, oldRaw); }; } // --- 快捷键 --- function bindHotkey() { document.addEventListener('keydown', (e) => { // 兜底强制显示 if (e.ctrlKey && e.altKey && e.code === 'Backquote') { const host = document.getElementById(UI_ID); if (host) { isVisible = true; host.style.opacity = '1'; host.style.pointerEvents = 'auto'; } else { createUI(); } e.preventDefault(); e.stopPropagation(); return; } if (isTypingTarget(e.target)) return; const isBackquoteKey = (e.code === 'Backquote' && !e.ctrlKey && !e.altKey && !e.metaKey); if (!isBackquoteKey) return; e.preventDefault(); e.stopPropagation(); if (typeof e.stopImmediatePropagation === 'function') e.stopImmediatePropagation(); const host = document.getElementById(UI_ID); if (!host) return; isVisible = !isVisible; host.style.opacity = isVisible ? '1' : '0'; host.style.pointerEvents = isVisible ? 'auto' : 'none'; }, true); } // --- 注入持久化 --- const observer = new MutationObserver(() => { if (!document.getElementById(UI_ID)) createUI(); }); function init() { createUI(); bindHotkey(); observer.observe(document.documentElement, { childList: true, subtree: true }); } if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init); else init(); })();

image453×879 63.7 KBimage447×875 54.8 KBimage448×879 44.1 KB
image451×878 58.3 KBimage450×879 57.5 KBimage454×882 47.3 KB

网友解答:
--【壹】--:

4块饼干能成功吗 游戏结束可以晒一下称号哈哈


--【贰】--:

有点意思 有空玩玩


--【叁】--:

挺好玩的 建议不用脚本玩一下


--【肆】--:

哈哈哈哈哈哈有意思!


--【伍】--:

游戏做的挺好的 作者一直在更新


--【陆】--:

我真求你了 哈哈哈哈


--【柒】--:

不建议用脚本 原汁原味挺有意思 挺极限


--【捌】--:

hiking变成hacking了


--【玖】--:

好么 紧贴热点


--【拾】--:

牛逼


--【拾壹】--:

哈哈哈 这也能整个脚本


--【拾贰】--:

感谢大佬 。


--【拾叁】--:

你好水王


--【拾肆】--:

好有意思 饿了还会眼花


--【拾伍】--:

哈哈哈 挺好玩的 建议玩一下


--【拾陆】--:

这是一个梗 陈某放


--【拾柒】--:

嗯呐 鳌太线吞噬太多人了


--【拾捌】--:

我就带4块压缩饼干
image2520×252 48.7 KB


--【拾玖】--:

好玩,就是第一次玩就被冻死了

问题描述:

上一个帖子不能编辑了 特开新帖
游戏地址:赛博徒步:生死鳌太线 | 一场关于意志与生存的终极考验
image1552×852 108 KB
image791×592 41.4 KB
很久之前就有佬友推荐过 作者一直在更新 随着细节丰富 越来越真实了
没有徒步经验的佬友可以体验一下到底有多难

附上我迭代更新了一个月的脚本:不建议用 用了就没意思了
①解锁付费订阅 支持付费下撤路线(你没看错有氪金项目 还有反调试)
②解锁并未开放的卫星电话 可以救驴友远山了
③解锁全成就&称号
④全物品添加&全地点瞬移
⑤修改属性(体温、体力、精神、饱腹、业力、预算、负重、天数、电话电量)
Tips:在死亡界面修改属性可以强行原地复活

// ==UserScript== // @name 赛博徒步:生死鳌太线 理想值修改器 V7 // @namespace http://tampermonkey.net/ // @version 7.0 // @description 数值修改 + `/~ 显示隐藏 + 面板记忆 + 节点瞬移(中文下拉+自动收集新节点+仅保留“保存当前节点”) // @author @Wet_Dream_Boy // @match https://cyberhiking.com/* // @grant none // @run-at document-start // @require https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js // ==/UserScript== (function () { 'use strict'; const STORAGE_KEY = 'aotai-survival-storage'; const CRYPTO_KEY = 'aotai-survival@2024'; const UI_ID = 'cyber-mod-v6-root'; // 面板输入记忆 const UI_PREF_KEY = 'aotai-ideal-panel-values-v6'; // 节点列表记忆(下拉中文/自动新增也会保存) const UI_NODE_LIST_KEY = 'aotai-node-list-v6'; let isVisible = true; // --- 理想默认值配置 --- const IDEAL_VALUES = { temp: 36.5, stamina: 100, sanity: 100, hunger: 100, karma: 1000, budget: 99999, weight: 0.1, day: 1, battery: 100, victoryCount: 9, hasMountainGodPass: false, subscriptions: '', lastItemId: 'backpack_expedition', }; // --- 默认节点(你在脚本里维护;下拉中文显示)--- const DEFAULT_NODES = [ // --- 正常路线 (塘口 -> 南塬) --- { id: 'tangkou', name: '塘口' }, { id: 'longwanghekou', name: '龙王河口' }, { id: 'xihuagou', name: '西桦沟' }, // ✅ 修正 { id: 'huoshaopo', name: '火烧坡' }, { id: 'camp_2900', name: '2900营地' }, { id: 'penjingyuan', name: '盆景园' }, { id: 'baiqimiao', name: '白起庙' }, { id: 'aotou', name: '鳌头' }, { id: 'aoshanding', name: '鳌山顶' }, { id: 'west_paoma', name: '西跑马梁' }, { id: 'yaowangmiao', name: '药王庙' }, { id: 'maijie_ridge', name: '麦秸岭' }, { id: 'wenxiong_stone', name: '文胸石' }, // ✅ 修正 { id: 'shuiwozi', name: '水窝子' }, { id: 'monument', name: '纪念碑' }, // 纪念碑通常在水窝子到飞机梁之间 { id: 'feiji_liang', name: '飞机梁' }, // ✅ 按你要求:不动 { id: 'liang_yi', name: '梁一' }, { id: 'liang_er', name: '梁二' }, { id: 'liang_san', name: '梁三' }, { id: 'camp_2800', name: '2800营地' }, { id: 'nantianmen_pass', name: '南天门垭口' }, // ✅ 保持你的写法 { id: 'nantianmen_forest', name: '南天门林区' }, { id: 'nantianmen_camp', name: '南天门营地' }, { id: 'pyramid', name: '金字塔' }, { id: 'ta_yi', name: '塔一' }, { id: 'ta_er', name: '塔二' }, { id: 'ta_san', name: '塔三' }, { id: 'jiuchongtian', name: '九重天' }, { id: 'xiyuan_camp', name: '西源营地' }, { id: 'dongyuan_camp', name: '东源营地' }, { id: 'wanxian_array', name: '万仙阵' }, { id: 'leigong_temple', name: '雷公庙' }, { id: 'paoma_liang', name: '跑马梁' }, { id: 'dayehai', name: '大爷海' }, { id: 'dawengong_temple', name: '大文公庙' }, { id: 'fangyang_temple', name: '放羊寺' }, { id: 'mingxing_temple', name: '明星寺' }, { id: 'pingan_temple', name: '平安寺' }, { id: 'nanyuan_village', name: '南塬村' }, // --- 下撤/支线/其他 --- { id: 'qiaodiping', name: '桥底坪' }, { id: 'baiyun_bridge', name: '白云桥' }, { id: 'baiyun_gorge_new', name: '白云峡谷(新)' }, { id: 'maershan_village', name: '马耳山村' }, { id: 'yingge_town', name: '鹦哥镇' }, // 你如果要“鹦鸽镇”就改这里 // --- 北坡下撤路线 --- { id: 'northern_slope_bottom', name: '北坡沟底' }, { id: 'northern_slope_channel', name: '北坡沟道' }, { id: 'northern_slope_river', name: '北坡河道' }, { id: 'northern_slope_ridge', name: '北坡山脊' }, { id: 'northern_slope_cliff_1', name: '北坡悬崖段 1' }, { id: 'northern_slope_cliff_2', name: '北坡悬崖段 2' }, { id: 'northern_slope_cliff_3', name: '北坡悬崖段 3' }, { id: 'northern_slope_valley_1', name: '北坡河谷段 1' }, { id: 'northern_slope_valley_2', name: '北坡山谷段 2' }, ]; // --- 物品列表 (ID -> 中文) --- const ITEM_MAP = [ { id: 'backpack_small', name: '45L 轻量背包' }, { id: 'backpack_medium', name: '65L 进阶背包' }, { id: 'backpack_large', name: '85L 重装背包' }, { id: 'backpack_expedition', name: '100L 远征背包' }, { id: 'poles', name: '碳纤维登山杖' }, { id: 'knee_pads', name: '专业护膝' }, { id: 'tent_4season', name: '高山四季帐' }, { id: 'raincoat', name: '轻量化雨衣' }, { id: 'wind_goggles', name: '防风护目镜' }, { id: 'gloves', name: '防风保暖手套' }, { id: 'mountain_windproof_hat', name: '高山防风保暖帽' }, { id: 'balaclava', name: '防风面罩' }, { id: 'sleeping_pad', name: '高R值防潮垫' }, { id: 'sleeping_bag_0', name: '0°C鹅绒睡袋' }, { id: 'sleeping_bag_10', name: '-10°C鹅绒睡袋' }, { id: 'sleeping_bag_20', name: '-20°C鹅绒睡袋' }, { id: 'sleeping_bag_30', name: '-30°C鹅绒睡袋' }, { id: 'headlamp', name: '专业头灯' }, { id: 'snowshoes', name: '简易冰爪' }, { id: 'snow_gaiters', name: '防雪套' }, { id: 'food_ration', name: '压缩饼干' }, { id: 'chocolate', name: '高能黑巧克力' }, { id: 'energy_gel', name: '能量胶' }, { id: 'salt_pill', name: '电解质盐丸' }, { id: 'gas_tank', name: '高山稳压气罐' }, { id: 'stove', name: '高山稳压炉头' }, { id: 'med_kit', name: '野外医疗包' }, { id: 'emergency_blanket', name: '保温毯' }, { id: 'hand_warmer', name: '暖身贴' }, { id: 'water_filter', name: '户外净水器' }, { id: 'rope', name: '登山绳索' }, { id: 'gps_device', name: '手持GPS导航仪' }, { id: 'satellite_phone', name: '卫星电话' } ]; const ALL_TITLES = [ 'aotai_guardian', 'cyber_living_buddha', 'cyber_philanthropist', 'speedrun_master', 'aotai_photographer', 'aotai_savage', 'hercules', 'qinggong_master', 'biscuit_manufacturer', 'biscuit_wholesaler', 'chocolate_factory', 'wealth_scatterer', 'iron_rooster', 'old_acquaintance', 'freezing_victim', 'freezing_survivor', 'indigenous', 'wicked_master', 'unfulfilled_ambition', 'rookie_driver', 'hunger_king_title', 'aotai_powerful_donkey', 'rational_walker', 'lucky_survivor', 'tangkou_villager', 'tangkou_village_chief', 'victim', 'shennong_descendant', 'bear_grylls_disciple', 'gas_master', 'cure_all' ]; const ALL_ACHIEVEMENTS = [ // --- 58 Achievements from Web (v1.0+) --- 'first_step', 'cloud_wall', 'mountain_master', 'survivor_7d', 'survivor_3d', 'high_altitude', 'nature_lover', 'rich_hiker', 'aotai_photographer', 'kind_heart', 'orographic_slayer', 'destined_meeting', 'golden_sunrise', 'thunder_survivor', 'lnt_guardian', 'star_gazer', 'rare_beast', 'fog_walker', 'night_owl', 'bull_tamer', 'cloud_sea', 'rainbow', 'moon_phantom', 'storm_stoic', 'rainrunner', 'sunset_watcher', 'berry_taster', 'quick_meet', 'memorial_respect', 'together', 'frugal_survivor', 'qinggong_master', 'load_shedder', 'diary_keeper', 'water_connoisseur', 'lost_and_found', 'iron_grip', 'noodle_king', 'free_solo', 'ice_glider', 'generous_soul', 'wild_vet', 'iron_will', 'snow_wise', 'solitude_talk', 'rock_dodger', 'detail_oriented', 'heroic_messenger', 'wind_fighter', 'seven_times_hero', 'mountain_pact', 'spirit_guide', 'accident_survivor', 'lucky_survivor', 'hitchhiker', 'worldly_fireworks', 'equipment_guard', 'wind_repair', // --- Potential Legacy/Save-only IDs (Keep safe) --- 'light_packer', 'water_filter_master', 'hiker_friend', 'hardship_comrade', 'lucky_panda', 'conqueror', 'photographer', 'gale_walker', 'god_of_aotai', 'solitude_survivor', 'tent_rigger' ]; // ====== 工具函数 ====== function loadPanelPrefs() { try { const raw = localStorage.getItem(UI_PREF_KEY); if (!raw) return { ...IDEAL_VALUES }; const parsed = JSON.parse(raw); return { ...IDEAL_VALUES, ...parsed }; } catch (e) { return { ...IDEAL_VALUES }; } } function savePanelPrefs(prefs) { try { localStorage.setItem(UI_PREF_KEY, JSON.stringify(prefs)); } catch (e) { } } function normalizeNodeList(list) { const map = new Map(); // 读用户保存的 (Array.isArray(list) ? list : []).forEach(x => { if (!x || typeof x.id !== 'string') return; const id = x.id.trim(); if (!id) return; const name = (x.name || id).toString().trim() || id; map.set(id, { id, name }); }); // 补齐默认节点(不覆盖用户自定义) DEFAULT_NODES.forEach(d => { if (!map.has(d.id)) map.set(d.id, { id: d.id, name: d.name || d.id }); }); return [...map.values()]; } function loadNodeList() { try { const raw = localStorage.getItem(UI_NODE_LIST_KEY); if (!raw) return normalizeNodeList(DEFAULT_NODES); return normalizeNodeList(JSON.parse(raw)); } catch (e) { return normalizeNodeList(DEFAULT_NODES); } } function saveNodeList(list) { try { localStorage.setItem(UI_NODE_LIST_KEY, JSON.stringify(normalizeNodeList(list))); } catch (e) { } } function upsertNode(list, id, name) { id = (id || '').trim(); if (!id) return list; const next = normalizeNodeList(list); const idx = next.findIndex(x => x.id === id); const item = { id, name: (name || id).toString().trim() || id }; if (idx >= 0) next[idx] = item; else next.push(item); return next; } function decryptData(raw) { if (!raw) return null; try { const parsed = JSON.parse(raw); const bytes = CryptoJS.AES.decrypt(parsed.cipher, CRYPTO_KEY); return JSON.parse(bytes.toString(CryptoJS.enc.Utf8)); } catch (e) { return null; } } function encryptData(data) { try { const cipher = CryptoJS.AES.encrypt(JSON.stringify(data), CRYPTO_KEY).toString(); return JSON.stringify({ "__aotai_enc__": true, "v": 1, "cipher": cipher }); } catch (e) { return null; } } function dispatchStorage(key, newValue, oldValue) { try { window.dispatchEvent(new StorageEvent('storage', { key, newValue, oldValue, storageArea: localStorage, url: location.href })); } catch (e) { } } function isTypingTarget(el) { if (!el) return false; const tag = (el.tagName || '').toLowerCase(); return tag === 'input' || tag === 'textarea' || el.isContentEditable; } function safeNumber(v, fallback) { const n = Number(v); return Number.isFinite(n) ? n : fallback; } function zhSort(a, b) { return (a || '').localeCompare((b || ''), 'zh-Hans-CN'); } // ====== UI ====== function createUI() { if (document.getElementById(UI_ID)) return; const prefs = loadPanelPrefs(); let nodeList = loadNodeList(); const host = document.createElement('div'); host.id = UI_ID; host.style.cssText = 'position: fixed; top: 10px; right: 10px; z-index: 2147483647; transition: opacity 0.2s;'; document.documentElement.appendChild(host); const shadow = host.attachShadow({ mode: 'closed' }); const container = document.createElement('div'); container.style.cssText = ` background: rgba(15, 15, 15, 0.98); color: #00ff00; padding: 15px; border: 1px solid #00ff00; border-radius: 4px; font-family: 'Consolas', 'Monaco', monospace; font-size: 12px; width: 300px; box-shadow: 0 0 15px rgba(0, 255, 0, 0.2); max-height: 85vh; overflow-y: auto; `; container.innerHTML = ` <div style="text-align:center;font-weight:bold;margin-bottom:10px;border-bottom:1px solid #00ff00;padding-bottom:6px;"> CYBER-HIKING IDEAL V7 </div> <style> .section-title { color:#888;font-size:10px;margin:10px 0 6px 0;text-transform:uppercase; } .row { margin-bottom:6px; display:flex; justify-content:space-between; align-items:center; gap:8px; } input, select { width: 150px; background:#000; color:#0ff; border:1px solid #333; padding:2px 4px; font-size:11px; box-sizing:border-box; } button { width:100%; padding:4px; margin-top:8px; cursor:pointer; border:1px solid #00ff00; background:transparent; color:#00ff00; font-weight:bold; } button:hover { background:#00ff00; color:#000; } .btn2 { display:flex; gap:8px; margin-top:8px; } .btn2 button { width: 50%; margin-top:0; } #status { font-size:10px; color:#555; margin-top:10px; text-align:center; } .small { font-size:10px; color:#777; } </style> <div class="section-title">基础生存属性</div> <div class="row"><span>体温</span><input type="number" id="in-temp" step="0.1" value="${prefs.temp}"></div> <div class="row"><span>体力</span><input type="number" id="in-stamina" value="${prefs.stamina}"></div> <div class="row"><span>精神</span><input type="number" id="in-sanity" value="${prefs.sanity}"></div> <div class="row"><span>饱腹</span><input type="number" id="in-hunger" value="${prefs.hunger}"></div> <div class="section-title">进阶属性</div> <div class="row"><span>业力</span><input type="number" id="in-karma" value="${prefs.karma}"></div> <div class="row"><span>预算</span><input type="number" id="in-budget" value="${prefs.budget}"></div> <div class="row"><span>负重</span><input type="number" id="in-weight" step="0.1" value="${prefs.weight}"></div> <div class="section-title">环境与设备</div> <div class="row"><span>当前天数</span><input type="number" id="in-day" value="${prefs.day}"></div> <div class="row"><span>卫星电话电量</span><input type="number" id="in-battery" value="${prefs.battery}"></div> <div class="section-title">特殊权限 & 记录</div> <div class="row"><span>通关次数</span><input type="number" id="in-victory" value="${prefs.victoryCount}"></div> <div class="row"> <span>山神通行证</span> <select id="in-pass"> <option value="true" ${prefs.hasMountainGodPass ? 'selected' : ''}>已拥有 (Yes)</option> <option value="false" ${!prefs.hasMountainGodPass ? 'selected' : ''}>未拥有 (No)</option> </select> </div> <div class="row"><span>订阅(逗号隔开)</span><input type="text" id="in-subs" value="${prefs.subscriptions}" placeholder="vip, etc"></div> <button id="apply">应用数值并刷新</button> <div class="row" style="margin-top: 15px;"> <button id="unlock-all">解锁全成就&称号</button> </div> <div class="row" style="margin-top: 15px;"> <span>物品</span> <select id="in-item" style="width: 110px;"></select> <input type="number" id="in-item-count" value="1" style="width: 50px;" title="数量"> </div> <div class="btn2"> <button id="add-item">添加</button> <button id="add-all-items">全都要(+1)</button> </div> <div class="row" style="margin-top: 15px;"> <span>目的地</span> <select id="in-node"></select> </div> <div class="small">当前节点:<span id="cur-node">读取中...</span></div> <div class="btn2"> <button id="teleport">瞬移并刷新</button> <button id="save-node">保存当前节点</button> </div> <div id="status">\` / ~ 切换显示隐藏;Ctrl+Alt+~ 强制显示</div> `; shadow.appendChild(container); const $ = (id) => shadow.getElementById(id); function getDecryptedState() { const raw = localStorage.getItem(STORAGE_KEY); const obj = decryptData(raw); return { raw, obj }; } function writeStateAndReload(newObj, oldRaw) { const newRaw = encryptData(newObj); if (!newRaw) return alert('加密失败,无法写入存档。'); // 1. 写入我们的数据 localStorage.setItem(STORAGE_KEY, newRaw); dispatchStorage(STORAGE_KEY, newRaw, oldRaw); // 2. 关键:劫持 setItem 防止游戏在 reload 前瞬间覆盖回去 (Game Auto-Save / Unload Save) // "Cyber-Block": Block the game from overwriting our perfect save. const originalSetItem = localStorage.setItem; localStorage.setItem = function (key, value) { if (key === STORAGE_KEY) { console.log('[CyberMod] 拦截到游戏尝试覆盖存档 -> 已阻止'); return; } originalSetItem.call(localStorage, key, value); }; // 3. 立即刷新,不再等待 location.reload(); } // ... (existing helper functions) ... $('apply').onclick = () => { // ... (existing apply logic) ... const { raw: oldRaw, obj } = getDecryptedState(); if (!obj?.state) return alert('未找到存档数据,请先开始游戏!'); const p = readPrefsFromInputs(); savePanelPrefs(p); obj.state.stats.temp = p.temp; obj.state.stats.stamina = p.stamina; obj.state.stats.sanity = p.sanity; obj.state.stats.hunger = p.hunger; obj.state.stats.karma = p.karma; obj.state.budget = p.budget; obj.state.weight = p.weight; obj.state.day = p.day; obj.state.satellitePhoneBattery = p.battery; obj.state.victoryCount = p.victoryCount; obj.state.hasMountainGodPass = p.hasMountainGodPass; if (!obj.state.user) obj.state.user = {}; const subList = (p.subscriptions || '').split(/[,,]/).map(s => s.trim()).filter(Boolean); obj.state.user.subscriptions = subList; writeStateAndReload(obj, oldRaw); }; function refreshNodeSelect(selectedId) { const sel = $('in-node'); sel.innerHTML = ''; const sorted = [...nodeList].sort((a, b) => { const idxA = DEFAULT_NODES.findIndex(x => x.id === a.id); const idxB = DEFAULT_NODES.findIndex(x => x.id === b.id); // If both are in default list, sort by index if (idxA >= 0 && idxB >= 0) return idxA - idxB; // If one is in default list, it comes first if (idxA >= 0) return -1; if (idxB >= 0) return 1; // Otherwise sort alphabetically return zhSort(a.name || a.id, b.name || b.id); }); sorted.forEach(n => { const opt = document.createElement('option'); opt.value = n.id; opt.textContent = `${n.name || n.id} (${n.id})`; sel.appendChild(opt); }); if (selectedId) sel.value = selectedId; } function refreshItemSelect(selectedId) { const sel = $('in-item'); sel.innerHTML = ''; ITEM_MAP.forEach(item => { const opt = document.createElement('option'); opt.value = item.id; opt.textContent = `${item.name} (${item.id})`; sel.appendChild(opt); }); if (selectedId) sel.value = selectedId; } function readPrefsFromInputs() { return { temp: safeNumber($('in-temp').value, IDEAL_VALUES.temp), stamina: safeNumber($('in-stamina').value, IDEAL_VALUES.stamina), sanity: safeNumber($('in-sanity').value, IDEAL_VALUES.sanity), hunger: safeNumber($('in-hunger').value, IDEAL_VALUES.hunger), karma: safeNumber($('in-karma').value, IDEAL_VALUES.karma), budget: safeNumber($('in-budget').value, IDEAL_VALUES.budget), weight: safeNumber($('in-weight').value, IDEAL_VALUES.weight), day: parseInt($('in-day').value, 10) || IDEAL_VALUES.day, battery: safeNumber($('in-battery').value, IDEAL_VALUES.battery), victoryCount: safeNumber($('in-victory').value, IDEAL_VALUES.victoryCount), hasMountainGodPass: $('in-pass').value === 'true', subscriptions: $('in-subs').value || '', lastItemId: $('in-item').value, }; } // 数值输入即记忆 ['in-temp', 'in-stamina', 'in-sanity', 'in-hunger', 'in-karma', 'in-budget', 'in-weight', 'in-day', 'in-battery', 'in-victory', 'in-pass', 'in-subs', 'in-item'] .forEach(id => { const el = $(id); el.addEventListener('input', () => savePanelPrefs(readPrefsFromInputs())); el.addEventListener('change', () => savePanelPrefs(readPrefsFromInputs())); }); // init:同步当前节点 + 确保自动收集 (function initNodeUI() { nodeList = loadNodeList(); const { obj } = getDecryptedState(); const cur = obj?.state?.currentNodeId || '(未知)'; $('cur-node').textContent = cur; // 自动把当前节点加入列表(如果不在默认里) if (cur && cur !== '(未知)') { const found = nodeList.find(x => x.id === cur); nodeList = upsertNode(nodeList, cur, found?.name || cur); saveNodeList(nodeList); } refreshNodeSelect(cur); refreshItemSelect(prefs.lastItemId); })(); $('apply').onclick = () => { const { raw: oldRaw, obj } = getDecryptedState(); if (!obj?.state) return alert('未找到存档数据,请先开始游戏!'); const p = readPrefsFromInputs(); savePanelPrefs(p); obj.state.stats.temp = p.temp; obj.state.stats.stamina = p.stamina; obj.state.stats.sanity = p.sanity; obj.state.stats.hunger = p.hunger; obj.state.stats.karma = p.karma; obj.state.budget = p.budget; obj.state.weight = p.weight; obj.state.day = p.day; obj.state.satellitePhoneBattery = p.battery; // New features obj.state.victoryCount = p.victoryCount; obj.state.hasMountainGodPass = p.hasMountainGodPass; // Subscriptions parsing if (!obj.state.user) obj.state.user = {}; const subList = (p.subscriptions || '').split(/[,,]/).map(s => s.trim()).filter(Boolean); obj.state.user.subscriptions = subList; writeStateAndReload(obj, oldRaw); }; $('add-item').onclick = () => { const itemId = $('in-item').value; const countStr = $('in-item-count').value; const count = parseInt(countStr, 10) || 1; if (!itemId) return; const { raw: oldRaw, obj } = getDecryptedState(); if (!obj?.state) return alert('未找到存档数据,请先开始游戏!'); if (!obj.state.inventory) obj.state.inventory = {}; const currentCount = obj.state.inventory[itemId] || 0; obj.state.inventory[itemId] = currentCount + count; writeStateAndReload(obj, oldRaw); }; $('add-all-items').onclick = () => { const { raw: oldRaw, obj } = getDecryptedState(); if (!obj?.state) return alert('未找到存档数据,请先开始游戏!'); if (!obj.state.inventory) obj.state.inventory = {}; ITEM_MAP.forEach(item => { const cid = item.id; const currentCount = obj.state.inventory[cid] || 0; obj.state.inventory[cid] = currentCount + 1; }); writeStateAndReload(obj, oldRaw); }; $('teleport').onclick = () => { const target = $('in-node').value; if (!target) return; const { raw: oldRaw, obj } = getDecryptedState(); if (!obj?.state) return alert('未找到存档数据,请先开始游戏!'); obj.state.currentNodeId = target; obj.state.pendingTransition = null; obj.state.currentEvent = null; obj.state.currentMission = null; writeStateAndReload(obj, oldRaw); }; $('save-node').onclick = () => { const { obj } = getDecryptedState(); const cur = obj?.state?.currentNodeId; if (!cur) return alert('当前节点未知'); // 若默认表里有中文就用中文;否则用 id 占位 const fromDefault = DEFAULT_NODES.find(x => x.id === cur); nodeList = upsertNode(nodeList, cur, fromDefault?.name || cur); saveNodeList(nodeList); // 立刻刷新下拉(你会马上看到新增) refreshNodeSelect(cur); alert(`✅ 已保存当前节点:${fromDefault?.name || cur} (${cur})`); }; $('unlock-all').onclick = () => { if (!confirm('确定要解锁所有 31 个称号和 69 个成就吗?\n这将直接修改存档记录。')) return; const { raw: oldRaw, obj } = getDecryptedState(); if (!obj?.state) return alert('未找到存档数据,请先开始游戏!'); if (!obj.state.user) obj.state.user = {}; // Init arrays if missing obj.state.user.titles = obj.state.user.titles || []; obj.state.unlockedTitles = obj.state.unlockedTitles || []; obj.state.user.achievements = obj.state.user.achievements || []; obj.state.unlockedAchievements = obj.state.unlockedAchievements || []; let addedT = 0; let addedA = 0; // Add Titles const userTitlesSet = new Set(obj.state.user.titles); const unlockedTitlesSet = new Set(obj.state.unlockedTitles); ALL_TITLES.forEach(t => { if (!userTitlesSet.has(t)) { userTitlesSet.add(t); addedT++; } if (!unlockedTitlesSet.has(t)) { unlockedTitlesSet.add(t); } }); obj.state.user.titles = Array.from(userTitlesSet); obj.state.unlockedTitles = Array.from(unlockedTitlesSet); // Add Achievements const userAchSet = new Set(obj.state.user.achievements); const unlockedAchSet = new Set(obj.state.unlockedAchievements); ALL_ACHIEVEMENTS.forEach(a => { if (!userAchSet.has(a)) { userAchSet.add(a); addedA++; } if (!unlockedAchSet.has(a)) { unlockedAchSet.add(a); } }); obj.state.user.achievements = Array.from(userAchSet); obj.state.unlockedAchievements = Array.from(unlockedAchSet); writeStateAndReload(obj, oldRaw); }; } // --- 快捷键 --- function bindHotkey() { document.addEventListener('keydown', (e) => { // 兜底强制显示 if (e.ctrlKey && e.altKey && e.code === 'Backquote') { const host = document.getElementById(UI_ID); if (host) { isVisible = true; host.style.opacity = '1'; host.style.pointerEvents = 'auto'; } else { createUI(); } e.preventDefault(); e.stopPropagation(); return; } if (isTypingTarget(e.target)) return; const isBackquoteKey = (e.code === 'Backquote' && !e.ctrlKey && !e.altKey && !e.metaKey); if (!isBackquoteKey) return; e.preventDefault(); e.stopPropagation(); if (typeof e.stopImmediatePropagation === 'function') e.stopImmediatePropagation(); const host = document.getElementById(UI_ID); if (!host) return; isVisible = !isVisible; host.style.opacity = isVisible ? '1' : '0'; host.style.pointerEvents = isVisible ? 'auto' : 'none'; }, true); } // --- 注入持久化 --- const observer = new MutationObserver(() => { if (!document.getElementById(UI_ID)) createUI(); }); function init() { createUI(); bindHotkey(); observer.observe(document.documentElement, { childList: true, subtree: true }); } if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init); else init(); })();

image453×879 63.7 KBimage447×875 54.8 KBimage448×879 44.1 KB
image451×878 58.3 KBimage450×879 57.5 KBimage454×882 47.3 KB

网友解答:
--【壹】--:

4块饼干能成功吗 游戏结束可以晒一下称号哈哈


--【贰】--:

有点意思 有空玩玩


--【叁】--:

挺好玩的 建议不用脚本玩一下


--【肆】--:

哈哈哈哈哈哈有意思!


--【伍】--:

游戏做的挺好的 作者一直在更新


--【陆】--:

我真求你了 哈哈哈哈


--【柒】--:

不建议用脚本 原汁原味挺有意思 挺极限


--【捌】--:

hiking变成hacking了


--【玖】--:

好么 紧贴热点


--【拾】--:

牛逼


--【拾壹】--:

哈哈哈 这也能整个脚本


--【拾贰】--:

感谢大佬 。


--【拾叁】--:

你好水王


--【拾肆】--:

好有意思 饿了还会眼花


--【拾伍】--:

哈哈哈 挺好玩的 建议玩一下


--【拾陆】--:

这是一个梗 陈某放


--【拾柒】--:

嗯呐 鳌太线吞噬太多人了


--【拾捌】--:

我就带4块压缩饼干
image2520×252 48.7 KB


--【拾玖】--:

好玩,就是第一次玩就被冻死了