diff --git a/noname/game/promises.js b/noname/game/promises.js index 6659b8187..a79a407d3 100644 --- a/noname/game/promises.js +++ b/noname/game/promises.js @@ -67,7 +67,7 @@ export class GamePromises { } /** * @param {string} filename - * @returns {Promise} + * @returns {Promise} */ readFile(filename) { return new Promise((resolve, reject) => { diff --git a/noname/library/update.js b/noname/library/update.js index ebc22697f..b8497c199 100644 --- a/noname/library/update.js +++ b/noname/library/update.js @@ -1,4 +1,4 @@ -import { ui, game } from "../../noname.js"; +import { ui, game, lib } from "../../noname.js"; // https://github.com/libccy/noname/archive/refs/tags/v1.10.10.zip @@ -21,6 +21,9 @@ if (localStorage.getItem("noname_authorization")) { defaultHeaders["Authorization"] = `token ${localStorage.getItem("noname_authorization")}`; } +/** + * 获取github授权的token + */ export async function gainAuthorization() { if (!localStorage.getItem("noname_authorization") && !sessionStorage.getItem("noname_authorization")) { const result = await game.promises.prompt("请输入您github的token以解除访问每小时60次的限制"); @@ -85,9 +88,10 @@ export function parseSize(limit) { /** * 对比版本号 - * @param { string } ver1 - * @param { string } ver2 - * @returns { -1 | 0 | 1 } + * @param { string } ver1 版本号1 + * @param { string } ver2 版本号2 + * @returns { -1 | 0 | 1 } -1为ver1 < ver2, 0为ver1 == ver2, 1为ver1 > ver2 + * @throws {Error} */ export function checkVersion(ver1, ver2) { if (typeof ver1 !== "string") ver1 = String(ver1); @@ -243,7 +247,7 @@ export async function getRepoTagDescription(tagName, options = { username: "libc /** * - * 获取仓库指定分支和指定目录内的所有文件和目录 + * 获取仓库指定分支和指定(单个)目录内的所有文件和目录 * @param { string } [path = ''] 路径名称(可放参数) * @param { string } [branch = ''] 仓库分支名称 * @param { Object } options @@ -301,6 +305,9 @@ export async function getRepoFilesList( /** * * 获取仓库指定分支和指定目录内的所有文件(包含子目录的文件) + * + * **注意: 此api可能会大幅度消耗请求次数,请谨慎使用** + * * @param { string } [path = ''] 路径名称(可放参数) * @param { string } [branch = ''] 仓库分支名称 * @param { Object } options @@ -350,7 +357,7 @@ export async function flattenRepositoryFiles( } /** - * 请求一个文件而不是直接储存为文件 + * 请求一个文件而不是直接储存为文件,这样可以省内存空间 * @param { string } url * @param { (receivedBytes: number, total?:number, filename?: string) => void } [onProgress] * @param { RequestInit } [options={}] @@ -520,14 +527,13 @@ export function createProgress(title, max, fileName, value) { } /** - * 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} 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. + * 从GitHub存储库检索最新版本(tag),不包括特定tag。 + * + * 此函数从GitHub存储库中获取由所有者和存储库名称指定的tags列表,然后返回不是“v1998”的最新tag名称。 + * @param {string} owner GitHub上拥有存储库的用户名或组织名称。 + * @param {string} repo 要从中提取tag的存储库的名称。 + * @returns {Promise} 以最新版本tag的名称解析的promise,或者如果操作失败则以错误拒绝。 + * @throws {Error} 如果获取操作失败或找不到有效tag,将抛出错误。 */ export async function getLatestVersionFromGitHub(owner = "libccy", repo = "noname") { if (!localStorage.getItem("noname_authorization")) await gainAuthorization(); @@ -539,18 +545,24 @@ export async function getLatestVersionFromGitHub(owner = "libccy", repo = "nonam for (const tag of tags) { const tagName = tag.name; - if (tagName !== "v1998") return tagName; + if (tagName === "v1998") continue; + try { + checkVersion(tagName, lib.version); + return tagName; + } catch { + // 非标准版本号 + } } 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. + * 从指定目录中的GitHub存储库中获取树 + * @param {string[]} directories 要从中获取树的目录列表 + * @param {string} version 从中获取树的版本或分支。 + * @param {string} [owner = 'libccy'] GitHub上拥有存储库的用户名或组织名称。 + * @param {string} [repo = 'noname'] GitHub存储库的名称 * @returns {Promise<{ * path: string; * mode: string; diff --git a/noname/ui/create/menu/pages/otherMenu.js b/noname/ui/create/menu/pages/otherMenu.js index 1dd130c4f..7452f198b 100644 --- a/noname/ui/create/menu/pages/otherMenu.js +++ b/noname/ui/create/menu/pages/otherMenu.js @@ -328,17 +328,17 @@ export const otherMenu = function (/** @type { boolean | undefined } */ connectM } if (!dev) { - getRepoTags() - .then((tags) => tags.filter((tag) => tag.name != "v1998")[0]) - .then((tag) => { - game.saveConfig("check_version", tag.name.slice(1)); - if (typeof lib.config["version_description_" + tag.name] == "object") { + getLatestVersionFromGitHub() + .then(tagName => { + game.saveConfig("check_version", tagName.slice(1)); + if (typeof lib.config[`version_description_${tagName}`] == "object") { /** @type { ReturnType } */ - const description = lib.config["version_description_" + tag.name]; + const description = lib.config[`version_description_${tagName}`]; return description; - } else return getRepoTagDescription(tag.name); + } + else return getRepoTagDescription(tagName); }) - .then((description) => { + .then(description => { // 保存版本信息 if (typeof lib.config["version_description_" + description.name] != "object") { game.saveConfig("version_description_" + description.name, description); @@ -436,18 +436,28 @@ export const otherMenu = function (/** @type { boolean | undefined } */ connectM * @param { (value: T) => Promise } predicate */ const asyncFilter = async (arr, predicate) => { - const results = await Promise.all(arr.map(predicate)); + //将arr每10个分为一个数组,分别使用Promise.all + /** @type { boolean[] } */ + const results = []; + for (let i = 0; i < arr.length; i += 10) { + const pushArr = arr.slice(i, i + 10); + results.push( + ...await Promise.all(pushArr.map(predicate)) + ); + } return arr.filter((_v, index) => results[index]); }; - const result = await asyncFilter(files.flat(), async (v) => { - return v.size != (await game.promises.readFile(v.path)).length; - }).then((arr) => arr.map((v) => v.path)); + const result = await asyncFilter(files.flat(), async v => { + return game.promises.readFile(v.path).then(data => { + return v.size != data.byteLength; + }) + }).then(arr => arr.map((v) => v.path)); console.log("需要更新的文件有:", result); game.print("需要更新的文件有:", result); const finish = async () => { - await lib.init.promises.js("game", "asset.js"); + await lib.init.promises.js("game", "asset"); if (Array.isArray(window.noname_asset_list)) { game.saveConfig("asset_version", window.noname_asset_list[0]); delete window.noname_asset_list;