Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions _config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,8 @@ post_process:
- /assets/js/plugins/smooth-scroll.js
- /assets/js/plugins/jquery.auto-redirect.js
- /assets/js/_main.js
/assets/js/hmcl-signature-verify.min.js:
- /assets/js/hmcl-signature-verify.js
remove_dirs:
- /assets/images/
- /assets/js/plugins/
Expand All @@ -350,3 +352,4 @@ post_process:
- /assets/js/theme.js
- /assets/js/settings.js
- /assets/js/main.min.js.map
- /assets/js/hmcl-signature-verify.js
2 changes: 1 addition & 1 deletion _data/navigation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ docs:
url: /changelog/dev.html
- title: 其他
children:
- title: 验证 HMCL
- title: HMCL 校验
url: /verify.html
- title: 用户协议
url: /eula/hmcl.html
Expand Down
100 changes: 21 additions & 79 deletions _pages/verify.md
Original file line number Diff line number Diff line change
@@ -1,98 +1,40 @@
---
title: 验证 HMCL 文件
title: HMCL 校验
permalink: /verify.html
classes: wide
toc: false
---

<div class="hmcl-verify">
<p>检查 HMCL 文件是否是官方构建。</p>
检查 HMCL 文件是否是官方构建。

<div class="hmcl-verify__actions">
<label class="hmcl-verify__button" for="hmcl-verify-file">选择文件</label>
<span id="hmcl-verify-selected-file" class="hmcl-verify__file">未选择文件</span>
<input id="hmcl-verify-file" class="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 id="hmcl-verify" class="notice">
<div id="hmcl-verify-alert">点击并选择文件或将文件拖拽到此处进行校验</div>
<div id="hmcl-verify-file"></div>
<input id="hmcl-verify-input" type="file" accept=".jar,.exe,.sh">
</div>

<style>
.hmcl-verify {
max-width: 42rem;
font-size: 1rem;
line-height: 1.65;
}

.hmcl-verify p {
margin-bottom: 1rem;
}

.hmcl-verify__actions {
#hmcl-verify {
gap: 2em;
display: flex;
cursor: pointer;
user-select: none;
text-align: center;
align-items: center;
gap: .75rem;
flex-wrap: wrap;
margin: 1rem 0;
}

.hmcl-verify__button {
display: inline-flex;
align-items: center;
aspect-ratio: 16 / 9;
flex-direction: column;
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;
transition: background-color .3s ease;
}

.hmcl-verify__button:hover {
filter: brightness(.95);
#hmcl-verify-alert {
font-size: 2em;
}

.hmcl-verify__file {
min-width: 0;
max-width: 100%;
opacity: .72;
font-size: .9rem;
overflow-wrap: anywhere;
}

.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-file {
font-size: 1.5em;
}

.hmcl-verify__result[hidden] {
#hmcl-verify-input {
display: none;
}

.hmcl-verify__result[data-state="ok"] {
border-color: #2e7d32;
}

.hmcl-verify__result[data-state="error"] {
border-color: #c62828;
}
</style>

<script src="{{ '/assets/js/hmcl-signature-verify.js' | relative_url }}"></script>
<script src="/assets/js/hmcl-signature-verify.min.js"></script>
4 changes: 4 additions & 0 deletions _plugins/kramdown_enhancer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ def convert_html_element(el, indent)
if el.value == "a" && el.attr["href"].is_a?(String)
el.attr["href"] = relative_url(el.attr["href"])
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)
src = el.attr["src"]
el.attr["src"] = relative_url(el.attr["src"])
Expand Down
79 changes: 51 additions & 28 deletions assets/js/hmcl-signature-verify.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,43 +27,70 @@
}
}

const fileInput = document.getElementById("hmcl-verify-file");
const resultElement = document.getElementById("hmcl-verify-result");
const selectedFileElement = document.getElementById("hmcl-verify-selected-file");
let verificationRequestId = 0;
const container = document.getElementById("hmcl-verify");
if (!container) return;
["dragenter", "dragover", "dragleave", "drop"].forEach(eventName => {
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) {
return;
}

fileInput.addEventListener("change", async () => {
fileInput.addEventListener("change", async () => handleFiles(fileInput.files));

let verificationRequestId = 0;
async function handleFiles(files) {
const requestId = ++verificationRequestId;
const file = fileInput.files && fileInput.files[0];
const file = files && files[0];
if (!file) {
setSelectedFileName("");
hideResult();
return;
}

setSelectedFileName(file.name);
setResult("正在验证,请稍候...");
setResult("正在校验中");

try {
await verifyHmclFile(file);
if (!isCurrentVerification(requestId)) {
return;
}
setResult(
"验证通过,该文件是 HMCL 的官方构建,可以放心使用",
"校验成功,该文件是 HMCL 的官方构建,可以放心使用",
"ok"
);
} catch (error) {
if (!isCurrentVerification(requestId)) {
return;
}
setResult(`验证失败。\n${formatVerificationError(error)}`, "error");
setResult(`校验失败,${formatVerificationError(error)}`, "error");
}
});
}

function isCurrentVerification(requestId) {
return requestId === verificationRequestId;
Expand Down Expand Up @@ -359,46 +386,42 @@
function formatVerificationError(error) {
switch (error && error.code) {
case VerificationErrorCode.MISSING_PUBLIC_KEY:
return "这不是可验证的 HMCL 文件,或者 HMCL 版本过低,无法验证";
return "这不是可验证的 HMCL 文件,或者 HMCL 版本过低,无法验证";

case VerificationErrorCode.MISSING_SIGNATURE:
return "这是非官方构建,请谨慎甄别其来源";
return "这是非官方构建,请谨慎甄别其来源";

case VerificationErrorCode.INVALID_PUBLIC_KEY:
case VerificationErrorCode.INVALID_SIGNATURE:
case VerificationErrorCode.INVALID_LAUNCHER_HEADER:
return "该 HMCL 文件可能被篡改或已损坏,请不要使用此文件你可以从 HMCL 官方网站重新下载 HMCL";
return "该 HMCL 文件可能被篡改或已损坏,请不要使用此文件你可以从 HMCL 官方网站重新下载 HMCL";

case VerificationErrorCode.INVALID_ZIP:
return "这个文件不是有效的 HMCL 文件,或文件已经损坏";
return "这个文件不是有效的 HMCL 文件,或文件已经损坏";

case VerificationErrorCode.UNSUPPORTED_ZIP:
return "暂不支持验证这种文件格式";
return "暂不支持验证这种文件格式";

case VerificationErrorCode.UNSUPPORTED_BROWSER:
return "当前浏览器不支持读取这个文件,请换用新版 Chrome、Edge 或 Firefox";
return "当前浏览器不支持读取这个文件,请换用新版 Chrome、Edge 或 Firefox";

default:
return "无法完成验证,请确认你选择的是从官方渠道下载的 HMCL 文件";
return "无法完成验证,请确认你选择的是从官方渠道下载的 HMCL 文件";
}
}

function setResult(message, state) {
resultElement.textContent = message;
resultElement.hidden = false;
if (state) {
resultElement.dataset.state = state;
resultElement.style.display = "block";
if (state === "ok") {
container.className = "notice--success";
} else if (state === "error") {
container.className = "notice--danger";
} else {
delete resultElement.dataset.state;
container.className = "notice";
}
}

function hideResult() {
resultElement.textContent = "";
resultElement.hidden = true;
delete resultElement.dataset.state;
}

function setSelectedFileName(fileName) {
if (selectedFileElement) {
selectedFileElement.textContent = fileName || "未选择文件";
Expand Down
Loading