优化自动每日指令与扫码退出秘境

This commit is contained in:
2026-08-30 00:40:18 +08:00
parent da8a82bfd5
commit 2d81615f78
10 changed files with 447 additions and 38 deletions
+124 -11
View File
@@ -47,9 +47,10 @@
width: 100vw;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
align-items: flex-start;
justify-content: flex-start;
background: transparent;
overflow: hidden;
}
body.preview #viewport {
@@ -1315,6 +1316,34 @@
border: 1px solid rgba(255, 242, 201, 0.13);
}
.command-quick-reference {
position: relative;
z-index: 1;
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 2px 12px;
margin: 0 12px 2px;
padding: 3px 8px;
border-top: 1px solid rgba(255, 242, 201, 0.15);
border-bottom: 1px solid rgba(255, 242, 201, 0.15);
color: rgba(244, 255, 247, 0.86);
font-size: 12px;
font-weight: 720;
line-height: 1.25;
}
.command-quick-reference span {
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.command-quick-reference strong {
color: #fff0b5;
font-weight: 900;
}
.tutorial-stage {
position: relative;
z-index: 1;
@@ -1322,19 +1351,20 @@
display: flex;
align-items: center;
justify-content: center;
padding: 0 14px 3px;
min-height: 32px;
padding: 0 10px 1px;
overflow: hidden;
}
.tutorial-text {
width: 100%;
color: var(--text);
font-size: 26px;
font-size: 20px;
font-weight: 900;
line-height: 1.35;
line-height: 1.25;
text-align: center;
white-space: nowrap;
letter-spacing: 0.7px;
letter-spacing: 0;
text-shadow: 0 2px 5px rgba(0, 0, 0, 0.48), 0 0 14px rgba(255, 240, 181, 0.18);
opacity: 1;
transform: translateY(0);
@@ -1342,12 +1372,12 @@
}
.tutorial-text.long {
font-size: 23px;
letter-spacing: 0.35px;
font-size: 18px;
letter-spacing: 0;
}
.tutorial-text.extra-long {
font-size: 21px;
font-size: 16px;
letter-spacing: 0;
}
@@ -1852,6 +1882,7 @@
<!-- 右侧中部:教学轮播 -->
<section class="panel tutorial-panel">
<div class="panel-title tutorial-title">直播间使用说明</div>
<div id="command-quick-reference" class="command-quick-reference"></div>
<div class="tutorial-stage">
<div id="tutorial-text" class="tutorial-text">发送“签到”领取积分,发送“排队”加入队伍</div>
</div>
@@ -1898,7 +1929,7 @@
return m + ":" + String(sec % 60).padStart(2, "0");
}
const tutorialSlides = [
const baseTutorialSlides = [
"发送“签到”领取积分,发送“排队”加入队伍",
"成为队首后,请在90秒内发送“上号”",
"发送“上号”后,请在4分钟内完成扫码登录",
@@ -1907,8 +1938,85 @@
"发送“积分”查询积分,发送“队列”查看排队情况",
"发送“退出”离开队伍,发送“点歌 歌名”点歌"
];
const fallbackCommandHints = {
daily: { enabled: true, aliases: ["自动每日", "每日", "日常"], preferred_alias: "每日" },
switch_party: { enabled: true, aliases: ["切换队伍", "换队"], preferred_alias: "换队" },
edit_party: { enabled: true, aliases: ["修改队员", "换角色"], preferred_alias: "换角色" }
};
let commandHints = fallbackCommandHints;
let tutorialSlides = baseTutorialSlides.slice();
let tutorialIndex = 0;
function normalizeCommandHint(value, fallback) {
const source = value && typeof value === "object" ? value : fallback;
const aliases = Array.isArray(source.aliases)
? source.aliases.map((item) => String(item || "").trim()).filter(Boolean)
: fallback.aliases.slice();
const preferred = String(source.preferred_alias || "").trim()
|| aliases.reduce((best, item) => !best || item.length < best.length ? item : best, "")
|| fallback.preferred_alias;
return {
enabled: source.enabled !== false,
aliases,
preferred_alias: preferred
};
}
function renderCommandQuickReference() {
const el = document.getElementById("command-quick-reference");
if (!el) return;
const daily = commandHints.daily;
if (!daily || !daily.enabled) {
el.hidden = true;
el.innerHTML = "";
return;
}
const cmd = esc(daily.preferred_alias || "每日");
el.hidden = false;
el.innerHTML = [
`<span><strong>${cmd}</strong>:基础流程</span>`,
`<span><strong>${cmd} 秘境</strong> &lt;名称&gt;</span>`,
`<span><strong>${cmd} 地脉</strong> &lt;类型&gt; &lt;国家&gt;</span>`,
`<span><strong>${cmd} 委托</strong>:每日委托</span>`
].join("");
}
function rebuildTutorialSlides() {
const slides = baseTutorialSlides.slice();
const daily = commandHints.daily;
const switchParty = commandHints.switch_party;
const editParty = commandHints.edit_party;
if (daily && daily.enabled) {
const cmd = daily.preferred_alias || "每日";
slides.push(`发送“${cmd}”完成邮件、树脂、尘歌壶和每日奖励`);
slides.push(`发送“${cmd} 秘境 风本”刷到树脂耗尽`);
slides.push(`发送“${cmd} 地脉 经验 蒙德”刷经验地脉`);
slides.push(`发送“${cmd} 委托”执行每日委托配置`);
}
const partyParts = [];
if (switchParty && switchParty.enabled) {
partyParts.push(`${switchParty.preferred_alias || "换队"} 永冻队”切换队伍`);
}
if (editParty && editParty.enabled) {
partyParts.push(`${editParty.preferred_alias || "换角色"} 四名角色”修改队员`);
}
if (partyParts.length) slides.push(`发送${partyParts.join(",发送")}`);
tutorialSlides = slides;
tutorialIndex %= tutorialSlides.length;
renderCommandQuickReference();
showTutorialSlide(tutorialIndex, false);
}
function applyCommandHints(value) {
const source = value && typeof value === "object" ? value : {};
commandHints = {
daily: normalizeCommandHint(source.daily, fallbackCommandHints.daily),
switch_party: normalizeCommandHint(source.switch_party, fallbackCommandHints.switch_party),
edit_party: normalizeCommandHint(source.edit_party, fallbackCommandHints.edit_party)
};
rebuildTutorialSlides();
}
function renderTutorialDots() {
const dots = document.getElementById("tutorial-dots");
if (!dots) return;
@@ -2344,8 +2452,10 @@
themeClasses.forEach((c) => document.body.classList.remove(c));
const theme = cfg.theme || "classic";
if (theme && theme !== "classic") document.body.classList.add("theme-" + theme);
applyCommandHints(cfg.command_hints);
} catch (e) {
console.error("frontend-config", e);
applyCommandHints(fallbackCommandHints);
}
}
@@ -2647,9 +2757,12 @@
function scaleCanvas() {
const canvas = document.getElementById("canvas");
const scale = Math.min(window.innerWidth / 1920, window.innerHeight / 1080);
canvas.style.transform = "scale(" + scale + ")";
const offsetX = Math.max(0, (window.innerWidth - 1920 * scale) / 2);
const offsetY = Math.max(0, (window.innerHeight - 1080 * scale) / 2);
canvas.style.transform = `translate(${offsetX}px, ${offsetY}px) scale(${scale})`;
}
applyCommandHints(fallbackCommandHints);
startTutorialCarousel();
fetchFrontendConfig();
fetchState();