Merge branch 'libccy:PR-Branch' into PR-Branch
This commit is contained in:
commit
2e7853862a
|
@ -65,6 +65,10 @@ export class GamePromises {
|
||||||
game.download(url, folder, resolve, reject, dev, onprogress);
|
game.download(url, folder, resolve, reject, dev, onprogress);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @param {string} filename
|
||||||
|
* @returns {Promise<Buffer>}
|
||||||
|
*/
|
||||||
readFile(filename) {
|
readFile(filename) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { lib, ui, game } from "../../noname.js";
|
import { ui, game } from "../../noname.js";
|
||||||
|
|
||||||
// https://github.com/libccy/noname/archive/refs/tags/v1.10.10.zip
|
// https://github.com/libccy/noname/archive/refs/tags/v1.10.10.zip
|
||||||
|
|
||||||
|
@ -386,7 +386,9 @@ export async function request(url, onProgress, options = {}) {
|
||||||
try {
|
try {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
filename = response.headers.get("Content-Disposition").split(";")[1].split("=")[1];
|
filename = response.headers.get("Content-Disposition").split(";")[1].split("=")[1];
|
||||||
} catch {}
|
} catch {
|
||||||
|
/* empty */
|
||||||
|
}
|
||||||
let receivedBytes = 0;
|
let receivedBytes = 0;
|
||||||
let chunks = [];
|
let chunks = [];
|
||||||
|
|
||||||
|
@ -516,3 +518,79 @@ export function createProgress(title, max, fileName, value) {
|
||||||
};
|
};
|
||||||
return parent;
|
return parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the latest version tag from a GitHub repository, excluding a specific tag.
|
||||||
|
* This function fetches the list of tags from the GitHub repository specified by
|
||||||
|
* the owner and repository name, then returns the latest tag name that is not “v1998”.
|
||||||
|
* @param {string} owner - The username or organization name on GitHub that owns the repository.
|
||||||
|
* @param {string} repo - The name of the repository from which to fetch tags.
|
||||||
|
* @returns {Promise<string>} A promise that resolves with the name of the latest version tag,
|
||||||
|
* or rejects with an error if the operation fails.
|
||||||
|
* @throws {Error} Will throw an error if the fetch operation fails or if no valid tags are found.
|
||||||
|
*/
|
||||||
|
export async function getLatestVersionFromGitHub(owner = "libccy", repo = "noname") {
|
||||||
|
if (!localStorage.getItem("noname_authorization")) await gainAuthorization();
|
||||||
|
|
||||||
|
const tags = await getRepoTags({
|
||||||
|
username: owner,
|
||||||
|
repository: repo,
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const tag of tags) {
|
||||||
|
const tagName = tag.name;
|
||||||
|
if (tagName !== "v1998") return tagName;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error("No valid tags found in the repository");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches trees from a GitHub repository within specified directories.
|
||||||
|
* @param {string[]} directories - The list of directories to fetch the trees from.
|
||||||
|
* @param {string} version - The version or branch to fetch the trees from.
|
||||||
|
* @param {string} owner - The owner of the GitHub repository.
|
||||||
|
* @param {string} repo - The name of the GitHub repository.
|
||||||
|
* @returns {Promise<{
|
||||||
|
* path: string;
|
||||||
|
* mode: string;
|
||||||
|
* type: "blob" | "tree";
|
||||||
|
* sha: string;
|
||||||
|
* size: number;
|
||||||
|
* url: string;
|
||||||
|
* }[][]>} A promise that resolves with trees from the specified directories.
|
||||||
|
* @throws {Error} Will throw an error if unable to fetch the repository tree from GitHub.
|
||||||
|
*/
|
||||||
|
export async function getTreesFromGithub(directories, version, owner = "libccy", repo = "noname") {
|
||||||
|
if (!localStorage.getItem("noname_authorization")) await gainAuthorization();
|
||||||
|
|
||||||
|
const treesResponse = await fetch(
|
||||||
|
`https://api.github.com/repos/${owner}/${repo}/git/trees/${version}?recursive=1`,
|
||||||
|
{
|
||||||
|
headers: defaultHeaders,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!treesResponse.ok)
|
||||||
|
throw new Error(`Failed to fetch the GitHub repository tree: HTTP status ${treesResponse.status}`);
|
||||||
|
/**
|
||||||
|
* @type {{
|
||||||
|
* sha: string;
|
||||||
|
* url: string;
|
||||||
|
* tree: {
|
||||||
|
* path: string;
|
||||||
|
* mode: string;
|
||||||
|
* type: "blob" | "tree";
|
||||||
|
* sha: string;
|
||||||
|
* size: number;
|
||||||
|
* url: string;
|
||||||
|
* }[];
|
||||||
|
* truncated: boolean;
|
||||||
|
* }}
|
||||||
|
*/
|
||||||
|
const trees = await treesResponse.json();
|
||||||
|
const tree = trees.tree;
|
||||||
|
return directories.map((directory) =>
|
||||||
|
tree.filter(({ type, path }) => type === "blob" && path.startsWith(directory))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
@ -1,11 +1,5 @@
|
||||||
import {
|
import {
|
||||||
menuContainer,
|
menuContainer,
|
||||||
popupContainer,
|
|
||||||
updateActive,
|
|
||||||
setUpdateActive,
|
|
||||||
updateActiveCard,
|
|
||||||
setUpdateActiveCard,
|
|
||||||
menux,
|
|
||||||
menuxpages,
|
menuxpages,
|
||||||
menuUpdates,
|
menuUpdates,
|
||||||
openMenu,
|
openMenu,
|
||||||
|
@ -22,11 +16,12 @@ import {
|
||||||
checkVersion,
|
checkVersion,
|
||||||
getRepoTags,
|
getRepoTags,
|
||||||
getRepoTagDescription,
|
getRepoTagDescription,
|
||||||
getRepoFilesList,
|
|
||||||
flattenRepositoryFiles,
|
flattenRepositoryFiles,
|
||||||
request,
|
request,
|
||||||
createProgress,
|
createProgress,
|
||||||
gainAuthorization,
|
gainAuthorization,
|
||||||
|
getLatestVersionFromGitHub,
|
||||||
|
getTreesFromGithub,
|
||||||
} from "../../../../library/update.js";
|
} from "../../../../library/update.js";
|
||||||
|
|
||||||
export const otherMenu = function (/** @type { boolean | undefined } */ connectMenu) {
|
export const otherMenu = function (/** @type { boolean | undefined } */ connectMenu) {
|
||||||
|
@ -410,42 +405,41 @@ export const otherMenu = function (/** @type { boolean | undefined } */ connectM
|
||||||
}
|
}
|
||||||
checkAssetButton.innerHTML = "正在检查更新";
|
checkAssetButton.innerHTML = "正在检查更新";
|
||||||
checkAssetButton.disabled = true;
|
checkAssetButton.disabled = true;
|
||||||
|
|
||||||
function refresh() {
|
function refresh() {
|
||||||
checkAssetButton.innerHTML = "检查素材更新";
|
checkAssetButton.innerHTML = "检查素材更新";
|
||||||
checkAssetButton.disabled = false;
|
checkAssetButton.disabled = false;
|
||||||
}
|
}
|
||||||
const assetDirs = [];
|
|
||||||
if (lib.config.asset_font) {
|
const assetDirectories = [];
|
||||||
assetDirs.push("font");
|
if (lib.config.asset_font) assetDirectories.push("font");
|
||||||
}
|
if (lib.config.asset_audio) assetDirectories.push("audio");
|
||||||
if (lib.config.asset_audio) {
|
if (lib.config.asset_image) assetDirectories.push("image");
|
||||||
assetDirs.push("audio");
|
const version = await getLatestVersionFromGitHub();
|
||||||
}
|
const files = await getTreesFromGithub(assetDirectories, version);
|
||||||
if (lib.config.asset_image) {
|
|
||||||
assetDirs.push("image");
|
assetDirectories.forEach((assetDirectory, index) => {
|
||||||
}
|
|
||||||
const files = await Promise.all(assetDirs.map((dir) => flattenRepositoryFiles(dir)));
|
|
||||||
assetDirs.forEach((value, index) => {
|
|
||||||
const arr = files[index];
|
const arr = files[index];
|
||||||
const size = arr.reduce((previous, current) => {
|
const size = arr.reduce((previous, current) => {
|
||||||
return previous + current.size;
|
return previous + current.size;
|
||||||
}, 0);
|
}, 0);
|
||||||
game.saveConfig(`asset_${value}_size`, parseSize(size));
|
game.saveConfig(`asset_${assetDirectory}_size`, parseSize(size));
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param { any[] } arr
|
* @template T
|
||||||
* @param { Function } predicate
|
* @param { T[] } arr
|
||||||
|
* @param { (value: T) => Promise<boolean> } predicate
|
||||||
*/
|
*/
|
||||||
const asyncFilter = async (arr, predicate) => {
|
const asyncFilter = async (arr, predicate) => {
|
||||||
// @ts-ignore
|
|
||||||
const results = await Promise.all(arr.map(predicate));
|
const results = await Promise.all(arr.map(predicate));
|
||||||
// @ts-ignore
|
|
||||||
return arr.filter((_v, index) => results[index]);
|
return arr.filter((_v, index) => results[index]);
|
||||||
};
|
};
|
||||||
// @ts-ignore
|
|
||||||
const result = await asyncFilter(files.flat(), async (v) => {
|
const result = await asyncFilter(files.flat(), async (v) => {
|
||||||
return v.size != (await game.promises.readFile(v.path)).length;
|
return v.size != (await game.promises.readFile(v.path)).length;
|
||||||
}).then((arr) => arr.map((v) => v.path));
|
}).then((arr) => arr.map((v) => v.path));
|
||||||
|
|
||||||
console.log("需要更新的文件有:", result);
|
console.log("需要更新的文件有:", result);
|
||||||
game.print("需要更新的文件有:", result);
|
game.print("需要更新的文件有:", result);
|
||||||
const finish = async () => {
|
const finish = async () => {
|
||||||
|
@ -466,7 +460,7 @@ export const otherMenu = function (/** @type { boolean | undefined } */ connectM
|
||||||
*/
|
*/
|
||||||
let unZipProgress;
|
let unZipProgress;
|
||||||
request(
|
request(
|
||||||
"noname.unitedrhythmized.club/api",
|
"api.unitedrhythmized.club/noname",
|
||||||
(receivedBytes, total, filename) => {
|
(receivedBytes, total, filename) => {
|
||||||
if (typeof filename == "string") {
|
if (typeof filename == "string") {
|
||||||
progress.setFileName(filename);
|
progress.setFileName(filename);
|
||||||
|
@ -484,8 +478,10 @@ export const otherMenu = function (/** @type { boolean | undefined } */ connectM
|
||||||
progress.setProgressValue(received);
|
progress.setProgressValue(received);
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
method: "post",
|
method: "POST",
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
|
action: "downloadAssets",
|
||||||
|
version,
|
||||||
fileList: result.concat("game/asset.js"),
|
fileList: result.concat("game/asset.js"),
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue