mirror of
https://gitee.com/huanghongxun/HMCL-docs.git
synced 2026-09-15 07:31:11 +08:00
优化 HMCL 文件校验页面 (#488)
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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
@@ -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>
|
||||||
|
|||||||
@@ -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"])
|
||||||
|
|||||||
@@ -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 || "未选择文件";
|
||||||
|
|||||||
Reference in New Issue
Block a user