优化 HMCL 文件校验页面 (#488)

This commit is contained in:
neveler
2026-08-15 20:44:58 +08:00
committed by GitHub
parent 8c9f18ba9c
commit 9d0091ad5e
5 changed files with 81 additions and 109 deletions
+3
View File
@@ -340,6 +340,8 @@ post_process:
- /assets/js/plugins/smooth-scroll.js - /assets/js/plugins/smooth-scroll.js
- /assets/js/plugins/jquery.auto-redirect.js - /assets/js/plugins/jquery.auto-redirect.js
- /assets/js/_main.js - /assets/js/_main.js
/assets/js/hmcl-signature-verify.min.js:
- /assets/js/hmcl-signature-verify.js
remove_dirs: remove_dirs:
- /assets/images/ - /assets/images/
- /assets/js/plugins/ - /assets/js/plugins/
@@ -350,3 +352,4 @@ post_process:
- /assets/js/theme.js - /assets/js/theme.js
- /assets/js/settings.js - /assets/js/settings.js
- /assets/js/main.min.js.map - /assets/js/main.min.js.map
- /assets/js/hmcl-signature-verify.js
+1 -1
View File
@@ -49,7 +49,7 @@ docs:
url: /changelog/dev.html url: /changelog/dev.html
- title: 其他 - title: 其他
children: children:
- title: 验证 HMCL - title: HMCL 校验
url: /verify.html url: /verify.html
- title: 用户协议 - title: 用户协议
url: /eula/hmcl.html url: /eula/hmcl.html
+22 -80
View File
@@ -1,98 +1,40 @@
--- ---
title: 验证 HMCL 文件 title: HMCL 校验
permalink: /verify.html permalink: /verify.html
classes: wide
toc: false toc: false
--- ---
<div class="hmcl-verify"> 检查 HMCL 文件是否是官方构建。
<p>检查 HMCL 文件是否是官方构建。</p>
<div class="hmcl-verify__actions"> <div id="hmcl-verify" class="notice">
<label class="hmcl-verify__button" for="hmcl-verify-file">选择文件</label> <div id="hmcl-verify-alert">点击并选择文件或将文件拖拽到此处进行校验</div>
<span id="hmcl-verify-selected-file" class="hmcl-verify__file">未选择文件</span> <div id="hmcl-verify-file"></div>
<input id="hmcl-verify-file" class="hmcl-verify__input" type="file" accept=".jar,.exe,.sh"> <input id="hmcl-verify-input" type="file" accept=".jar,.exe,.sh">
</div>
<div id="hmcl-verify-result" class="hmcl-verify__result" role="status" aria-live="polite" hidden></div>
</div> </div>
<style> <style>
.hmcl-verify { #hmcl-verify {
max-width: 42rem; gap: 2em;
font-size: 1rem;
line-height: 1.65;
}
.hmcl-verify p {
margin-bottom: 1rem;
}
.hmcl-verify__actions {
display: flex; display: flex;
align-items: center;
gap: .75rem;
flex-wrap: wrap;
margin: 1rem 0;
}
.hmcl-verify__button {
display: inline-flex;
align-items: center;
justify-content: center;
min-height: 2.25rem;
padding: .35rem .8rem;
border: 1px solid rgba(127, 127, 127, .45);
border-radius: 4px;
background: rgba(127, 127, 127, .12);
color: inherit;
font-size: .9rem;
line-height: 1.2;
cursor: pointer; cursor: pointer;
user-select: none;
text-align: center;
align-items: center;
aspect-ratio: 16 / 9;
flex-direction: column;
justify-content: center;
transition: background-color .3s ease;
} }
#hmcl-verify-alert {
.hmcl-verify__button:hover { font-size: 2em;
filter: brightness(.95);
} }
#hmcl-verify-file {
.hmcl-verify__file { font-size: 1.5em;
min-width: 0;
max-width: 100%;
opacity: .72;
font-size: .9rem;
overflow-wrap: anywhere;
} }
#hmcl-verify-input {
.hmcl-verify__input {
position: absolute;
width: 1px;
height: 1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
}
.hmcl-verify__result {
margin-top: 1rem;
padding: .75rem .9rem;
border: 1px solid rgba(127, 127, 127, .35);
border-left-width: 4px;
border-radius: 4px;
background: rgba(127, 127, 127, .08);
font-size: .95rem;
line-height: 1.6;
white-space: pre-wrap;
}
.hmcl-verify__result[hidden] {
display: none; display: none;
} }
.hmcl-verify__result[data-state="ok"] {
border-color: #2e7d32;
}
.hmcl-verify__result[data-state="error"] {
border-color: #c62828;
}
</style> </style>
<script src="{{ '/assets/js/hmcl-signature-verify.js' | relative_url }}"></script> <script src="/assets/js/hmcl-signature-verify.min.js"></script>
+4
View File
@@ -105,6 +105,10 @@ module KramdownEnhancer
if el.value == "a" && el.attr["href"].is_a?(String) if el.value == "a" && el.attr["href"].is_a?(String)
el.attr["href"] = relative_url(el.attr["href"]) el.attr["href"] = relative_url(el.attr["href"])
el.options[:relative] = true el.options[:relative] = true
elsif el.value == "script" && el.attr["src"].is_a?(String)
puts el.attr["src"]
el.attr["src"] = relative_url(el.attr["src"])
el.options[:relative] = true
elsif el.value == "img" && el.attr["src"].is_a?(String) elsif el.value == "img" && el.attr["src"].is_a?(String)
src = el.attr["src"] src = el.attr["src"]
el.attr["src"] = relative_url(el.attr["src"]) el.attr["src"] = relative_url(el.attr["src"])
+51 -28
View File
@@ -27,26 +27,53 @@
} }
} }
const fileInput = document.getElementById("hmcl-verify-file"); const container = document.getElementById("hmcl-verify");
const resultElement = document.getElementById("hmcl-verify-result"); if (!container) return;
const selectedFileElement = document.getElementById("hmcl-verify-selected-file"); ["dragenter", "dragover", "dragleave", "drop"].forEach(eventName => {
let verificationRequestId = 0; container.addEventListener(eventName, (e) => {
e.preventDefault();
e.stopPropagation();
}, false);
});
["dragenter", "dragover"].forEach(eventName => {
container.addEventListener(eventName, () => {
container.className = "notice--info";
}, false);
});
["dragleave", "drop"].forEach(eventName => {
container.addEventListener(eventName, () => {
container.className = "notice";
}, false);
});
container.addEventListener("drop", (event) => handleFiles(event.dataTransfer.files), false);
const fileInput = document.getElementById("hmcl-verify-input");
if (!fileInput) return;
container.addEventListener("click", () => fileInput.click());
const resultElement = document.getElementById("hmcl-verify-alert");
const selectedFileElement = document.getElementById("hmcl-verify-file");
if (!fileInput || !resultElement) { if (!fileInput || !resultElement) {
return; return;
} }
fileInput.addEventListener("change", async () => { fileInput.addEventListener("change", async () => handleFiles(fileInput.files));
let verificationRequestId = 0;
async function handleFiles(files) {
const requestId = ++verificationRequestId; const requestId = ++verificationRequestId;
const file = fileInput.files && fileInput.files[0]; const file = files && files[0];
if (!file) { if (!file) {
setSelectedFileName(""); setSelectedFileName("");
hideResult();
return; return;
} }
setSelectedFileName(file.name); setSelectedFileName(file.name);
setResult("正在验证,请稍候..."); setResult("正在校验中");
try { try {
await verifyHmclFile(file); await verifyHmclFile(file);
@@ -54,16 +81,16 @@
return; return;
} }
setResult( setResult(
"验证通过,该文件是 HMCL 的官方构建,可以放心使用", "校验成功,该文件是 HMCL 的官方构建,可以放心使用",
"ok" "ok"
); );
} catch (error) { } catch (error) {
if (!isCurrentVerification(requestId)) { if (!isCurrentVerification(requestId)) {
return; return;
} }
setResult(`验证失败。\n${formatVerificationError(error)}`, "error"); setResult(`校验失败,${formatVerificationError(error)}`, "error");
}
} }
});
function isCurrentVerification(requestId) { function isCurrentVerification(requestId) {
return requestId === verificationRequestId; return requestId === verificationRequestId;
@@ -359,46 +386,42 @@
function formatVerificationError(error) { function formatVerificationError(error) {
switch (error && error.code) { switch (error && error.code) {
case VerificationErrorCode.MISSING_PUBLIC_KEY: case VerificationErrorCode.MISSING_PUBLIC_KEY:
return "这不是可验证的 HMCL 文件,或者 HMCL 版本过低,无法验证"; return "这不是可验证的 HMCL 文件,或者 HMCL 版本过低,无法验证";
case VerificationErrorCode.MISSING_SIGNATURE: case VerificationErrorCode.MISSING_SIGNATURE:
return "这是非官方构建,请谨慎甄别其来源"; return "这是非官方构建,请谨慎甄别其来源";
case VerificationErrorCode.INVALID_PUBLIC_KEY: case VerificationErrorCode.INVALID_PUBLIC_KEY:
case VerificationErrorCode.INVALID_SIGNATURE: case VerificationErrorCode.INVALID_SIGNATURE:
case VerificationErrorCode.INVALID_LAUNCHER_HEADER: case VerificationErrorCode.INVALID_LAUNCHER_HEADER:
return "该 HMCL 文件可能被篡改或已损坏,请不要使用此文件你可以从 HMCL 官方网站重新下载 HMCL"; return "该 HMCL 文件可能被篡改或已损坏,请不要使用此文件你可以从 HMCL 官方网站重新下载 HMCL";
case VerificationErrorCode.INVALID_ZIP: case VerificationErrorCode.INVALID_ZIP:
return "这个文件不是有效的 HMCL 文件,或文件已经损坏"; return "这个文件不是有效的 HMCL 文件,或文件已经损坏";
case VerificationErrorCode.UNSUPPORTED_ZIP: case VerificationErrorCode.UNSUPPORTED_ZIP:
return "暂不支持验证这种文件格式"; return "暂不支持验证这种文件格式";
case VerificationErrorCode.UNSUPPORTED_BROWSER: case VerificationErrorCode.UNSUPPORTED_BROWSER:
return "当前浏览器不支持读取这个文件,请换用新版 Chrome、Edge 或 Firefox"; return "当前浏览器不支持读取这个文件,请换用新版 Chrome、Edge 或 Firefox";
default: default:
return "无法完成验证,请确认你选择的是从官方渠道下载的 HMCL 文件"; return "无法完成验证,请确认你选择的是从官方渠道下载的 HMCL 文件";
} }
} }
function setResult(message, state) { function setResult(message, state) {
resultElement.textContent = message; resultElement.textContent = message;
resultElement.hidden = false; resultElement.style.display = "block";
if (state) { if (state === "ok") {
resultElement.dataset.state = state; container.className = "notice--success";
} else if (state === "error") {
container.className = "notice--danger";
} else { } else {
delete resultElement.dataset.state; container.className = "notice";
} }
} }
function hideResult() {
resultElement.textContent = "";
resultElement.hidden = true;
delete resultElement.dataset.state;
}
function setSelectedFileName(fileName) { function setSelectedFileName(fileName) {
if (selectedFileElement) { if (selectedFileElement) {
selectedFileElement.textContent = fileName || "未选择文件"; selectedFileElement.textContent = fileName || "未选择文件";