<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PaperMC版本选择</title>
<style type="text/css">
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
select {
outline: none;
width: 110px;
}
#app,
#statusText,
#downloadSlot {
margin-top: 20px;
text-align: center;
}
</style>
</head>
<body>
<div id="app">
<div id="version">
<span>选择游戏版本: </span>
<select id="versionsSlot"></select>
</div>
<div id="build">
<span>选择文件版本: </span>
<select id="buildsSlot"></select>
</div>
</div>
<p id="downloadSlot">
<button id="download">下载</button>
</p>
<p id="statusText"></p>
</body>
<script type="text/javascript">
(() => {
/** @type {HTMLSelectElement} */
const versionsSlot = document.querySelector("#versionsSlot");
/** @type {HTMLSelectElement} */
const buildsSlot = document.querySelector("#buildsSlot");
/** @type {HTMLParagraphElement} */
const statusText = document.querySelector("#statusText");
/** @type {HTMLButtonElement} */
const downloadBtn = document.querySelector("#download");
function selectStatusChange(b) {
versionsSlot.disabled = b;
buildsSlot.disabled = b;
downloadBtn.disabled = b;
if (b) {
statusText.innerText = "加载中..."
} else {
statusText.innerText = "";
}
}
async function init() {
selectStatusChange(true);
/** @type {Array<String>} */
const versions = await getAllVersion();
appendVersion(versions);
/** @type {Array<String>} */
const builds = await getBuilds(versions[0]);
appendBuild(builds);
versionsSlot.onchange = async () => {
selectStatusChange(true);
const builds = await getBuilds(versionsSlot.value);
buildsSlot.innerHTML = "";
appendBuild(builds);
selectStatusChange(false);
}
downloadBtn.onclick = async () => {
selectStatusChange(true);
await getJar(versionsSlot.value, buildsSlot.value);
selectStatusChange(false);
}
selectStatusChange(false);
}
function appendVersion(versions) {
const fragment = document.createDocumentFragment();
for (let i in versions) {
const o = document.createElement("option");
o.innerText = versions[i];
o.value = versions[i];
fragment.appendChild(o);
}
versionsSlot.appendChild(fragment);
}
function appendBuild(builds) {
const fragment = document.createDocumentFragment();
for (let i in builds) {
const o = document.createElement("option");
o.innerText = builds[i]['build'];
o.value = builds[i]['build'];
fragment.appendChild(o);
}
buildsSlot.appendChild(fragment);
}
async function getAllVersion() {
const data = await fetch("https://api.papermc.io/v2/projects/paper");
if (data.ok) {
const { versions } = await data.json();
return versions.reverse();
} else {
return null;
}
}
async function getBuilds(version) {
const data = await fetch(`https://api.papermc.io/v2/projects/paper/versions/${version}/builds`);
if (data.ok) {
const { builds } = await data.json();
return builds.reverse();
} else {
return null;
}
}
async function getJar(version, build) {
const fileName = `paper-${version}-${build}.jar`;
try {
const data = await fetch(`https://api.papermc.io/v2/projects/paper/versions/${version}/builds/${build}/downloads/${fileName}`);
if (data.ok) {
statusText.innerText = `正在下载文件 ${data.url}`;
const b = await data.blob();
const jar = new File([b], fileName, {
type: "application/java-archive"
});
const link = URL.createObjectURL(jar);
const a = document.createElement("a");
a.download = fileName;
a.href = link;
a.click();
} else {
console.log(`status: ${data.status}, statusText: ${data.statusText}`);
alert("请求失败");
}
} catch (e) {
console.error(e);
alert("请求失败");
}
}
init();
})();
</script>
</html>
不用忍受paper那时不时卡死的swagger了