382 lines
23 KiB
HTML
382 lines
23 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<title>咸鱼喵喵全能助手 V1.1</title>
|
||
<link rel="stylesheet" href="style.css">
|
||
</head>
|
||
<body>
|
||
|
||
<div class="topsticky">
|
||
<header class="topbar">
|
||
<div class="brand">
|
||
<span class="brand-name">咸鱼喵喵全能助手 V1.1</span>
|
||
<span class="brand-sub">粉丝向 · 仅供个人截图与内容创作</span>
|
||
</div>
|
||
<div class="status-wrap">
|
||
<span id="connDot" class="dot"></span>
|
||
<span id="connText">正在检测…</span>
|
||
</div>
|
||
</header>
|
||
|
||
<!-- 游戏状态条 -->
|
||
<section class="statusbar">
|
||
<div class="stat"><label>地图</label><b id="st-map">—</b></div>
|
||
<div class="stat"><label>坐标</label><b id="st-pos">—</b></div>
|
||
<div class="stat"><label>血量</label><b id="st-hp">—</b></div>
|
||
<div class="stat"><label>已开开关</label><b id="st-sw">—</b></div>
|
||
<div class="stat"><label>重力</label><b id="st-grav">—</b></div>
|
||
<div class="stat"><label>无敌</label><b id="st-inv">—</b></div>
|
||
<!-- 当前连的是沙盒还是原版。连到原版时会变红 —— 那时任何操作都在动正式存档 -->
|
||
<div class="stat game-src" id="st-src-wrap"><label>当前连接</label><b id="st-src">—</b></div>
|
||
</section>
|
||
|
||
<!-- 常驻快捷开关:不放在二级页面里,任何标签页下都能直接点 -->
|
||
<section class="quickbar">
|
||
<span class="qb-label">状态</span>
|
||
<button class="chip" id="q-gravity" title="高亮 = 悬停;空中可连续点跳、按下下降,保留技能位移;再点安全落地">悬停</button>
|
||
<button class="chip" id="q-invincible" title="高亮 = 无敌中(不会掉血)">无敌</button>
|
||
<button class="chip" id="q-noclip" title="高亮 = 穿墙中(无视碰撞体)">穿墙</button>
|
||
<button class="chip on" id="q-lily" title="高亮 = 莉莉娅在画面里;点一下把她藏起来">莉莉娅</button>
|
||
|
||
<span class="qb-sep"></span>
|
||
<span class="qb-label">拍照</span>
|
||
<button class="chip on" id="q-msg" title="高亮 = 对话框显示中;点一下藏起来拍干净的场景(只是藏,随时能显示回来)">对话框</button>
|
||
<button class="chip on" id="q-art" title="高亮 = 立绘显示中">立绘</button>
|
||
<button class="chip on" id="q-hud" title="高亮 = 游戏界面(血条、小地图等)显示中">游戏界面</button>
|
||
|
||
<span class="qb-sep"></span>
|
||
<button class="chip danger" id="q-restore" title="恢复重力、碰撞、无敌,撤销摆拍并解除数值锁定(已修改的数值和物品不回退)">全部还原</button>
|
||
</section>
|
||
</div>
|
||
|
||
<div class="note" id="photo-state" role="status"></div>
|
||
<nav class="tabs">
|
||
<button class="tab active" data-panel="teleport">传送</button>
|
||
<button class="tab" data-panel="world-map">地图</button>
|
||
<button class="tab" data-panel="story">对话剧情</button>
|
||
<button class="tab" data-panel="trainer">角色与背包</button>
|
||
<button class="tab" data-panel="encyclopedia">收集百科</button>
|
||
<button class="tab" data-panel="switches">开关</button>
|
||
<button class="tab" data-panel="saves">存档与沙盒</button>
|
||
<button class="tab" data-panel="settings">设置</button>
|
||
</nav>
|
||
|
||
<main>
|
||
<section class="panel" id="panel-world-map">
|
||
<div class="card">
|
||
<h2>世界地图 <span class="tag">原版房间布局</span></h2>
|
||
<div class="row world-map-controls">
|
||
<label>大区域 <select id="world-map-region"><option value="">全部区域</option></select></label>
|
||
<label>地图页 <select id="world-map-page" aria-label="地图页"></select></label>
|
||
<label>收集物 <select id="world-map-type"><option value="">全部类型</option></select></label>
|
||
<label><input type="checkbox" id="world-map-missing">只看未收集</label>
|
||
</div>
|
||
<div class="row mt"><button id="world-map-locate">定位当前</button><button id="world-map-fit">适应地图</button><button id="world-map-minus" aria-label="缩小地图">−</button><button id="world-map-plus" aria-label="放大地图">+</button><button id="world-map-refresh">刷新</button><span id="world-map-summary" class="meta" role="status">连接游戏后可查看</span></div>
|
||
<p class="hint">拖动平移,滚轮缩放;点击方格或图标查看详情。彩色:未收集 · 灰色 ✓:已收集 · ?:状态未知 · 虚线:未探索 · 绿色框:当前位置。查看完整布局不会更改探索记录。</p>
|
||
<div class="world-map-layout">
|
||
<div id="world-map-viewport" tabindex="0" aria-label="世界地图:方向键平移,加减键缩放">
|
||
<svg id="world-map-svg" role="img" aria-label="原版房间与收集物地图"><g id="world-map-drawing"></g></svg>
|
||
<div id="world-map-empty" class="empty">连接游戏后打开地图</div>
|
||
</div>
|
||
<aside id="world-map-detail" class="world-map-detail" aria-label="所选分块详情"><p class="hint">点击地图上的方格或收集图标查看详情。</p></aside>
|
||
</div>
|
||
<p class="hint" id="world-map-coverage"></p>
|
||
</div>
|
||
</section>
|
||
<section class="panel" id="panel-trainer">
|
||
<div class="card">
|
||
<h2>伤害与受击倍率</h2>
|
||
<div class="row"><label>伤害倍率 <input id="combat-outgoing" type="number" min="0" max="1000" step="0.1" value="1"></label><label>受击倍率 <input id="combat-incoming" type="number" min="0" max="1000" step="0.1" value="1"></label><button id="combat-apply" class="primary">应用倍率</button><label><input type="checkbox" id="combat-onehit">一击秒杀</label><button id="combat-reset">恢复正常战斗</button></div>
|
||
<p id="combat-status" class="hint">1 倍为正常;0 倍不扣血。秒杀在玩家或莉莉娅的有效攻击命中敌人时生效,不突破剧情无敌。倍率不改变基础攻击力。</p>
|
||
</div>
|
||
<div class="card">
|
||
<h2>金币、生命与能量</h2>
|
||
<div class="row"><span id="trainer-role">请先连接游戏并进入地图</span><button id="trainer-refresh">刷新数值与背包</button></div>
|
||
<p class="hint">作用于当前操作的角色,喵露露/莉莉娅切换形态后仍有效。输入数值后点「设值」或「设值并锁定」;锁定后不随消耗或拾取变化。修改当前值,不改变最大值。</p>
|
||
<div id="trainer-stats" class="trainer-stats"></div>
|
||
<p class="hint">数值锁定只在本次游戏中有效;读档、新游戏或面板失联超过 2 分钟自动解除。「全部还原」也会解除锁定,已修改的数值与物品不回退。</p>
|
||
</div>
|
||
<div class="card">
|
||
<h2>全部背包物品</h2>
|
||
<p id="trainer-capacity" class="note"></p>
|
||
<p class="hint">直接修改当前背包,游戏正常存档时会保存。移除已装备的饰品/宝石会同时卸下;移除当前武器会换到另一件已有武器。新增宝石按游戏规则自动启用。</p>
|
||
<div class="row">
|
||
<input id="trainer-search" type="search" placeholder="搜索物品名称、描述或编号" aria-label="搜索背包物品">
|
||
<select id="trainer-category" aria-label="物品分类"><option value="">全部分类</option><option value="consumables">食物</option><option value="weapons">咸鱼(武器)</option><option value="stones">鱼眼宝石</option><option value="ornaments">配饰</option><option value="special">材料与铃铛</option></select>
|
||
<label><input id="trainer-owned" type="checkbox">只看已拥有</label>
|
||
<label><input id="trainer-overcap" type="checkbox">允许超过消耗品携带上限</label>
|
||
<label><input id="trainer-map-bells" type="checkbox">允许减少地图铃铛(会重置相应收集点)</label>
|
||
</div>
|
||
<div class="row mt"><button id="trainer-give-filtered">获得筛选结果</button><button class="danger" id="trainer-clear-filtered">清除筛选结果</button><span id="trainer-item-summary" class="meta"></span></div>
|
||
<p class="hint">物品逐项添加/移除,配饰与宝石也可装备/卸下。批量获得会补满食物、添加装备及各 1 个材料/铃铛;批量清除保留当前武器。默认保留地图铃铛;勾选允许减少后,按地图编号从后往前重置对应铃铛收集点。其他物品的背包修改不影响地图收集记录。</p>
|
||
<div id="trainer-items" class="list tall"><div class="empty">连接后读取背包</div></div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ========== 传送 ========== -->
|
||
<section class="panel active" id="panel-teleport">
|
||
<div class="card">
|
||
<h2>坐标传送</h2>
|
||
<p class="hint">
|
||
输入目标格子的横纵坐标。<b>坐标超出地图范围会被自动夹到边界。</b>
|
||
</p>
|
||
|
||
<div class="note">
|
||
<b>传送默认进入「悬浮」状态</b>(暂停重力 + 穿墙)。<br>
|
||
这是为了避开游戏的<b>坠落复位</b>机制 —— 直接落到坑洞地形上,游戏会判定你掉下去了,
|
||
播掉落音效并把你弹回"上次站立的位置",如果这个记录还是上一张地图的,人就会直接消失。<br>
|
||
想站到地上走动时,点下面的<b>「落地」</b>(会先探测脚下安不安全)。
|
||
</div>
|
||
<div class="note">悬停时每次点跳都能继续上升;按住游戏「下」键下降,松开停住,遇到实心地面会停下。下冲等技能保留原有位移。开「穿墙」后四向均可穿过障碍;已卡进地里时先开穿墙飞到空处再关闭。支持原版出口换图并保留设置,无出口的边界仍会阻挡。方向微调点按小步移动,按住连续移动。</div>
|
||
|
||
<div class="row mt">
|
||
<label>X <input type="number" id="tp-x" min="0" step="1" value="0"></label>
|
||
<label>Y <input type="number" id="tp-y" min="0" step="1" value="0"></label>
|
||
<button class="primary" id="tp-go">传送(悬浮)</button>
|
||
<button id="tp-here">填入当前坐标</button>
|
||
<button id="tp-land">落地</button>
|
||
</div>
|
||
<div class="row mt">
|
||
<label>微调</label>
|
||
<select id="tp-step" aria-label="微调像素步长"><option value="1">精细 · 1 像素</option><option value="4" selected>普通 · 4 像素</option><option value="16">快速 · 16 像素</option></select>
|
||
<button data-nudge="-1,0">←</button>
|
||
<button data-nudge="1,0">→</button>
|
||
<button data-nudge="0,-1">↑</button>
|
||
<button data-nudge="0,1">↓</button>
|
||
<span class="pill" id="tp-state">—</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<h2>本图事件</h2>
|
||
<p class="hint">
|
||
默认只列出<b>带剧情的事件</b>(显示台词),也就是截图真正要用的那些。
|
||
金币、平台、装饰这类走「显示全部事件」。
|
||
</p>
|
||
<div class="row">
|
||
<button id="ev-load">读取本图事件</button>
|
||
<input type="search" id="ev-filter" placeholder="按台词 / 说话人 / 立绘名筛选…">
|
||
<label class="chk"><input type="checkbox" id="ev-all"> 显示全部事件</label>
|
||
</div>
|
||
<div class="list" id="ev-list"><div class="empty">点「读取本图事件」加载</div></div>
|
||
</div>
|
||
|
||
<div class="card warn-card">
|
||
<h2>场景还原(摆拍)</h2>
|
||
<p class="hint">
|
||
找出本图<b>本该可见却没出现</b>的角色,强行让它们出现。
|
||
用于「对话框在说话、画面里却没人」的情况。
|
||
</p>
|
||
<div class="note">
|
||
<b>⚠️ 这是摆拍,不是把游戏改回当时的样子。</b><br>
|
||
· 被游戏标记为「已抹除」的事件强行拉出来,它<b>不会执行任何指令</b>,
|
||
只是一个站着的立绘;站位也不一定和原作一致。<br>
|
||
· 摆拍会固定角色,自动和手动存档照常。不推荐摆拍时保存:读档后状态可能无法完整恢复。完成后可点<b>「撤销场景还原」</b>恢复原来的事件状态。
|
||
切图、读档或面板失联两分钟也会撤销摆拍。<br>
|
||
· 如果这条对话有「运行过场」可用,<b>优先用那个</b>——那个是真的在重现演出。
|
||
</div>
|
||
<div class="row">
|
||
<button id="lost-scan">扫描本图角色</button>
|
||
<button class="primary" id="lost-restore-all">恢复被抹除的</button>
|
||
<button id="lost-restore-hidden">连同游戏隐藏的一起</button>
|
||
<button id="lost-unpin">撤销场景还原</button>
|
||
</div>
|
||
<div class="row mt">
|
||
<span class="pill" id="lost-hint">还没扫描</span>
|
||
</div>
|
||
<div class="list" id="lost-list"><div class="empty">点「扫描本图角色」看看本图现在有谁、缺谁</div></div>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="panel" id="panel-encyclopedia">
|
||
<div class="card">
|
||
<h2>收集百科</h2>
|
||
<p class="hint">查看物品用途、获取位置和当前存档的收集状态。背包为空不代表没拿过;地图记录与当前持有数量独立显示。打开游戏背包时也能查百科。</p>
|
||
<p class="hint">「前往分块边缘」优先选择物品所属分块边缘附近、不碰墙且脚下无伤害地形的落点;这个分块被堵住时,会改找邻近分块或同图其他空处,继续传送。到达后保持悬停并恢复碰撞,不会自动穿墙。物品位置和获取条件照常,请自行走过去获取。</p>
|
||
<div class="row"><button id="encyclopedia-refresh" class="primary">刷新百科与收集进度</button><span id="encyclopedia-summary" role="status">连接后读取游戏资料</span></div>
|
||
<div id="encyclopedia-regions" class="collection-regions"></div>
|
||
<div class="row mt">
|
||
<input id="encyclopedia-search" type="search" placeholder="搜索物品、用途、区域或地图编号" aria-label="搜索百科">
|
||
<select id="encyclopedia-category" aria-label="百科物品分类"><option value="">全部分类</option><option value="consumables">食物</option><option value="weapons">咸鱼(武器)</option><option value="stones">鱼眼宝石</option><option value="ornaments">配饰</option><option value="special">材料与铃铛</option><option value="coin">金币</option></select>
|
||
<select id="encyclopedia-area" aria-label="百科区域"><option value="">全部区域</option></select>
|
||
<select id="encyclopedia-status" aria-label="百科状态"><option value="all">全部物品与地点</option><option value="uncollected">有明确未收集地点</option><option value="collected">有已收集地点</option><option value="unknown">有状态未知地点</option><option value="missing">背包未拥有</option><option value="owned">背包已拥有</option></select>
|
||
</div>
|
||
<p id="encyclopedia-coverage" class="hint"></p>
|
||
<div id="encyclopedia-items" class="catalog-list"><div class="empty">请先读档,再刷新百科。</div></div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ========== 对话跳转点 ========== -->
|
||
<section class="panel" id="panel-story">
|
||
<div class="card">
|
||
<h2>对话剧情</h2>
|
||
<p class="hint">
|
||
连接后自动读取台词,支持全文搜索。<br>从游戏数据里解析出的 <b id="story-count">—</b> 条剧情触发点。
|
||
</p>
|
||
<div class="note">
|
||
<b>三种复现方式,优先试「运行过场」</b><br>
|
||
· <b>运行过场</b> —— 执行含这段对话的<b>整个事件页</b>。
|
||
NPC 站位、演出、对白全按原样走,<b>画面最接近原作</b>。通关存档也能用。<br>
|
||
注意:一整段过场会从头播,可能包含好几段对话,一路截图即可。<br>
|
||
· <b>只播台词</b> —— 只调那一段对白,跳过节目前的演出。快,但
|
||
<b>场景里的 NPC 可能不在场</b>(那些角色是靠前面的指令摆出来的)。<br>
|
||
· <b>前往</b> —— 打开所需开关 + 传送,你自己走过去。存档没通关时场景最自然。
|
||
</div>
|
||
<p class="hint" id="story-text-hint"></p>
|
||
<div class="row">
|
||
<input type="search" id="story-filter" placeholder="全文搜索:台词 / 说话人 / 地图 / 开关名…">
|
||
<label class="chk"><input type="checkbox" id="story-only-actionable" checked> 只看可跳转的</label>
|
||
<label class="chk"><input type="checkbox" id="story-need-switch"> 只看需要开关的</label>
|
||
</div>
|
||
<div class="row mt">
|
||
<button id="story-load-text">重新读取台词</button>
|
||
<button id="story-close-msg">关闭对话窗口</button>
|
||
<span class="pill">截完图用它收尾</span>
|
||
</div>
|
||
<div class="list tall" id="story-list"><div class="empty">正在载入…</div></div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ========== 开关 ========== -->
|
||
<section class="panel" id="panel-switches">
|
||
<div class="card">
|
||
<h2>开关</h2>
|
||
<p class="hint">
|
||
默认只显示<b>常用开关</b>——即"隐藏对话触发条件里真正会用到的那 114 个",
|
||
比翻全部 360 个高效得多。需要时可以展开全部。
|
||
</p>
|
||
<div class="row">
|
||
<input type="search" id="sw-filter" placeholder="按开关名或编号搜索…">
|
||
<button id="sw-toggle-all">展开全部 360 个</button>
|
||
<button id="sw-reload">刷新状态</button>
|
||
</div>
|
||
<div class="row mt">
|
||
<span class="pill" id="sw-mode">当前:常用开关</span>
|
||
</div>
|
||
<div class="list tall" id="sw-list"><div class="empty">正在载入…</div></div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ========== 存档与沙盒 ========== -->
|
||
<section class="panel" id="panel-saves">
|
||
<div class="card warn-card">
|
||
<h2>⚠️ 用之前先读这段</h2>
|
||
<ul class="warn-list">
|
||
<li>本工具会改游戏<b>运行时状态</b>(坐标、开关、物理),<b>不改游戏程序和素材;保存、还原会写入明确选定的存档目录</b>。</li>
|
||
<li>作弊状态下游戏可能自动存盘,落到 <code>file0</code>(自动存档槽)。</li>
|
||
<li>本游戏启用了 <b>Steam 云存档</b>。直接在原版游戏上折腾,被污染的存档可能被同步上去且追不回来。</li>
|
||
<li><b>所以推荐用沙盒:把游戏整体拷一份,在副本里折腾。</b>副本不在 Steam 库里,云同步够不着。</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<h2>沙盒副本</h2>
|
||
<p class="hint">复制游戏及存档(排除工具和发布版目录),所有操作都在副本里进行。</p>
|
||
<div class="row">
|
||
<button class="primary" id="sb-create">创建沙盒副本</button>
|
||
<button id="sb-status">刷新状态</button>
|
||
</div>
|
||
<div class="note" id="sb-info">—</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<h2>存档备份</h2>
|
||
<p class="hint">把 <code>save/</code> 整个目录复制一份存档。原版和沙盒可以分别备份。</p>
|
||
<div class="row">
|
||
<button id="bk-original">备份原版存档</button>
|
||
<button id="bk-sandbox">备份沙盒存档</button>
|
||
<button id="bk-reload">刷新列表</button>
|
||
</div>
|
||
<div class="row"><label>还原目标 <select id="bk-target"><option value="">请选择目标</option><option value="sandbox">沙盒存档</option><option value="original">原版存档</option></select></label></div>
|
||
<div class="list" id="bk-list"><div class="empty">—</div></div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<h2>存「拍照专用档」</h2>
|
||
<p class="hint">
|
||
把当前游戏状态存进一个存档槽。摆拍时也可保存,但不保证读档后完整恢复角色、UI 或对白。
|
||
工具会先自动备份整个存档目录,再让游戏自己存。
|
||
</p>
|
||
<div class="note">
|
||
<b>⚠️ 会覆盖该槽位原有的进度。</b>
|
||
你的 24 个槽位(0 是自动存档,1~23 是手动)目前<b>全部占用</b>,
|
||
没有空槽可用——所以请自己挑一个不在乎的槽。
|
||
</div>
|
||
<div class="row">
|
||
<label>存到槽位 <input type="number" id="photo-slot" min="1" max="23" step="1" value="23"></label>
|
||
<span>实际保存目录:<code id="photo-target">未连接</code></span>
|
||
<button class="danger" id="photo-save">存为拍照档</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<h2>关于这个工具</h2>
|
||
<p class="hint">
|
||
粉丝向的截图辅助工具,用于个人复现「错过就没了」的剧情并截图。<br>
|
||
不包含、不打包任何游戏素材;不提供成就解锁功能;不修改游戏任何文件。<br>
|
||
按作者 readme 的要求,<b>请勿用本工具提取或传播游戏素材</b>。
|
||
</p>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ========== 设置 ========== -->
|
||
<section class="panel" id="panel-settings">
|
||
<div class="card">
|
||
<h2>端口与路径</h2>
|
||
<p class="hint">
|
||
改完点保存即可生效,配置文件写在 <code id="set-path">tool/config.json</code>。
|
||
</p>
|
||
<div class="form">
|
||
<label class="field">
|
||
<span>游戏调试端口</span>
|
||
<input type="number" id="set-cdpPort" min="1024" max="65535">
|
||
<em>工具靠这个端口连游戏。原版通常 9222,沙盒建议 9223,两个别撞车。</em>
|
||
</label>
|
||
<label class="field">
|
||
<span>控制面板端口</span>
|
||
<input type="number" id="set-webPort" min="1024" max="65535">
|
||
<em>浏览器打开面板用的端口。<b>改这个要重启工具才生效。</b></em>
|
||
</label>
|
||
<label class="field">
|
||
<span>沙盒副本目录</span>
|
||
<input type="text" id="set-sandboxDir">
|
||
<em>把游戏拷一份到这里。建议放在 Steam 库外面,云同步才够不着。</em>
|
||
</label>
|
||
</div>
|
||
<div class="row mt">
|
||
<button class="primary" id="set-save">保存设置</button>
|
||
<button id="set-reset">恢复默认值</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<h2>怎么启动这个工具</h2>
|
||
<ol class="steps">
|
||
<li>双击 <code>tool\启动.bat</code></li>
|
||
<li>它会自动:检查 SDK 版 NW.js → 备份存档 → 启动游戏 → 启动本服务 → 打开浏览器</li>
|
||
<li>在游戏里<b>正常读档</b>进入地图(工具不能替你读档,见开发文档第 6 节)</li>
|
||
</ol>
|
||
<div class="note">
|
||
<b>只想启动某一部分?</b><br>
|
||
· 只起控制面板(游戏已经在跑):在这个目录执行 <code>node server.js</code><br>
|
||
· 只启动游戏:<code>nw.exe "沙盒目录" --remote-debugging-port=9223</code><br>
|
||
· 改了控制面板端口后,要关掉旧的服务窗口再重新 <code>node server.js</code>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<h2>当前状态</h2>
|
||
<div class="list" id="set-info"><div class="empty">—</div></div>
|
||
</div>
|
||
</section>
|
||
|
||
</main>
|
||
|
||
<div id="toast" class="toast"></div>
|
||
|
||
<script src="app.js"></script>
|
||
</body>
|
||
</html>
|