Merge pull request #1218 from nonameShijian/PR-Branch
限制自动检测更新,支持导入esm扩展,修复其他bug
This commit is contained in:
commit
e87ce7a597
|
@ -2229,18 +2229,72 @@ export class Game {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
alert(`导入失败:\n${JSON.stringify(error, null, "\t")}`);
|
alert(`导入失败:\n${JSON.stringify(error, null, "\t")}`);
|
||||||
|
console.error(error);
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
zip.load(data);
|
zip.load(data);
|
||||||
// alert(zip.file('文件夹/加扩展.js').asText())
|
let extensionFile = zip.file("extension.js");
|
||||||
const str = zip.file("extension.js").asText();
|
let isTsFile = false;
|
||||||
if (str === "" || undefined) throw "你导入的不是扩展!请选择正确的文件";
|
// 未找到extension.js
|
||||||
|
if (!extensionFile) {
|
||||||
|
extensionFile = zip.file("extension.ts");
|
||||||
|
if (!extensionFile) throw new Error("未找到extension.js");
|
||||||
|
isTsFile = true;
|
||||||
|
}
|
||||||
|
/** @type { string } */
|
||||||
|
// @ts-ignore
|
||||||
|
let str = extensionFile.asText();
|
||||||
|
if (str === "" || str === undefined) throw "你导入的不是扩展!请选择正确的文件";
|
||||||
|
// 编译ts扩展
|
||||||
|
if (isTsFile) {
|
||||||
|
if (typeof globalThis.ts === 'undefined') {
|
||||||
|
await lib.init.promises.js('game', 'typescript');
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @type {typeof import('typescript')}
|
||||||
|
*/
|
||||||
|
const ts = globalThis.ts;
|
||||||
|
str = ts.transpile(str, {
|
||||||
|
module: ts.ModuleKind.ES2015,
|
||||||
|
//@todo: ES2019 -> ES2020
|
||||||
|
target: ts.ScriptTarget.ES2019,
|
||||||
|
inlineSourceMap: true,
|
||||||
|
resolveJsonModule: true,
|
||||||
|
esModuleInterop: true,
|
||||||
|
}, 'extension.ts');
|
||||||
|
}
|
||||||
_status.importingExtension = true;
|
_status.importingExtension = true;
|
||||||
|
try {
|
||||||
|
// 导入普通扩展
|
||||||
eval(str);
|
eval(str);
|
||||||
|
// esm扩展可以不写game.impoprt或许会导致_status.extensionLoading不存在
|
||||||
|
if (Array.isArray(_status.extensionLoading)) {
|
||||||
await Promise.allSettled(_status.extensionLoading);
|
await Promise.allSettled(_status.extensionLoading);
|
||||||
delete _status.extensionLoading;
|
delete _status.extensionLoading;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
// 是模块扩展
|
||||||
|
if (
|
||||||
|
// @ts-ignore
|
||||||
|
error.message === 'Cannot use import statement outside a module' ||
|
||||||
|
// @ts-ignore
|
||||||
|
error.message === 'await is only valid in async functions and the top level bodies of modules'
|
||||||
|
) {
|
||||||
|
// 改为用info.json判断扩展名
|
||||||
|
const infoFile = zip.file("info.json");
|
||||||
|
if (!infoFile) throw new Error("未找到info.json,导入模块化扩展必须加入info.json!");
|
||||||
|
const info = JSON.parse(infoFile.asText());
|
||||||
|
if (typeof info.name == 'string') {
|
||||||
|
await game.import('extension', () => {
|
||||||
|
return Object.assign(info, {
|
||||||
|
config: {},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
_status.importingExtension = false;
|
_status.importingExtension = false;
|
||||||
if (!game.importedPack) throw "err";
|
if (!game.importedPack) throw "此压缩包不是一个扩展";
|
||||||
const extensionName = game.importedPack.name;
|
const extensionName = game.importedPack.name;
|
||||||
if (lib.config.all.plays.includes(extensionName)) throw "禁止安装游戏原生扩展";
|
if (lib.config.all.plays.includes(extensionName)) throw "禁止安装游戏原生扩展";
|
||||||
const extensions = lib.config.extensions;
|
const extensions = lib.config.extensions;
|
||||||
|
@ -2260,7 +2314,6 @@ export class Game {
|
||||||
fileList = Object.keys(files)
|
fileList = Object.keys(files)
|
||||||
.filter((key) => !files[key].dir && !hiddenFileFlags.includes(key[0]))
|
.filter((key) => !files[key].dir && !hiddenFileFlags.includes(key[0]))
|
||||||
.reverse();
|
.reverse();
|
||||||
//alert(filelist)
|
|
||||||
//电脑端
|
//电脑端
|
||||||
//具备nodeJS环境
|
//具备nodeJS环境
|
||||||
if (lib.node && lib.node.fs) {
|
if (lib.node && lib.node.fs) {
|
||||||
|
@ -2286,14 +2339,14 @@ export class Game {
|
||||||
)
|
)
|
||||||
).then(writeFile);
|
).then(writeFile);
|
||||||
return fileName.length
|
return fileName.length
|
||||||
? game
|
? game.promises
|
||||||
.createDir(`extension/${extensionName}/${fileName.join("/")}`)
|
.createDir(`extension/${extensionName}/${fileName.join("/")}`)
|
||||||
.then(() => letGo(`${fileName.join("/")}/${name}`))
|
.then(() => letGo(`${fileName.join("/")}/${name}`))
|
||||||
: letGo(name);
|
: letGo(name);
|
||||||
}
|
}
|
||||||
finishLoad();
|
finishLoad();
|
||||||
};
|
};
|
||||||
game.ensureDirectory(`extension/${extensionName}`).then(writeFile).catch(UHP);
|
game.promises.ensureDirectory(`extension/${extensionName}`).then(writeFile).catch(UHP);
|
||||||
} else
|
} else
|
||||||
new Promise((resolve, reject) =>
|
new Promise((resolve, reject) =>
|
||||||
window.resolveLocalFileSystemURL(nonameInitialized, resolve, reject)
|
window.resolveLocalFileSystemURL(nonameInitialized, resolve, reject)
|
||||||
|
@ -2351,7 +2404,7 @@ export class Game {
|
||||||
)
|
)
|
||||||
.then(writeFile);
|
.then(writeFile);
|
||||||
return fileName.length
|
return fileName.length
|
||||||
? game
|
? game.promises
|
||||||
.createDir(`extension/${extensionName}/${fileName.join("/")}`)
|
.createDir(`extension/${extensionName}/${fileName.join("/")}`)
|
||||||
.then(() => letGo(`${fileName.join("/")}/${name}`))
|
.then(() => letGo(`${fileName.join("/")}/${name}`))
|
||||||
: letGo(name);
|
: letGo(name);
|
||||||
|
@ -4960,10 +5013,13 @@ export class Game {
|
||||||
* @param { string } extensionName
|
* @param { string } extensionName
|
||||||
*/
|
*/
|
||||||
hasExtension(extensionName) {
|
hasExtension(extensionName) {
|
||||||
|
if (this.hasExtensionInstalled(extensionName)) {
|
||||||
if (typeof lib.config[`extension_${extensionName}_enable`] != "boolean") {
|
if (typeof lib.config[`extension_${extensionName}_enable`] != "boolean") {
|
||||||
game.saveExtensionConfig(extensionName, "enable", true);
|
game.saveExtensionConfig(extensionName, "enable", true);
|
||||||
}
|
}
|
||||||
return this.hasExtensionInstalled(extensionName) && lib.config[`extension_${extensionName}_enable`];
|
return lib.config[`extension_${extensionName}_enable`] === true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @param { string } extensionName
|
* @param { string } extensionName
|
||||||
|
|
|
@ -67,7 +67,7 @@ export class GamePromises {
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @param {string} filename
|
* @param {string} filename
|
||||||
* @returns {Promise<Buffer>}
|
* @returns {Promise<ArrayBuffer | Buffer>}
|
||||||
*/
|
*/
|
||||||
readFile(filename) {
|
readFile(filename) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
|
|
@ -184,9 +184,12 @@ export function nodeReady() {
|
||||||
game.createDir = (directory, successCallback, errorCallback) => {
|
game.createDir = (directory, successCallback, errorCallback) => {
|
||||||
const target = lib.node.path.join(__dirname, directory);
|
const target = lib.node.path.join(__dirname, directory);
|
||||||
if (lib.node.fs.existsSync(target)) {
|
if (lib.node.fs.existsSync(target)) {
|
||||||
if (typeof errorCallback == "function") {
|
// 修改逻辑,路径存在且是文件才会报错
|
||||||
errorCallback(new Error(`${target}已存在`));
|
if (!lib.node.fs.lstatSync(target).isDirectory()){
|
||||||
|
if (typeof errorCallback == "function") errorCallback(new Error(`${target}文件已存在`));
|
||||||
|
else if (typeof successCallback == "function") successCallback();
|
||||||
}
|
}
|
||||||
|
else if (typeof successCallback == "function") successCallback();
|
||||||
} else if (checkVersion(process.versions.node, "10.12.0") > -1) {
|
} else if (checkVersion(process.versions.node, "10.12.0") > -1) {
|
||||||
lib.node.fs.mkdir(target, { recursive: true }, (e) => {
|
lib.node.fs.mkdir(target, { recursive: true }, (e) => {
|
||||||
if (e) {
|
if (e) {
|
||||||
|
|
|
@ -124,6 +124,9 @@ export class Library {
|
||||||
onload = [];
|
onload = [];
|
||||||
onload2 = [];
|
onload2 = [];
|
||||||
onprepare = [];
|
onprepare = [];
|
||||||
|
/**
|
||||||
|
* @type { Function[] | undefined }
|
||||||
|
*/
|
||||||
arenaReady = [];
|
arenaReady = [];
|
||||||
onfree = [];
|
onfree = [];
|
||||||
inpile = [];
|
inpile = [];
|
||||||
|
|
|
@ -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
|
// https://github.com/libccy/noname/archive/refs/tags/v1.10.10.zip
|
||||||
|
|
||||||
|
@ -21,9 +21,12 @@ if (localStorage.getItem("noname_authorization")) {
|
||||||
defaultHeaders["Authorization"] = `token ${localStorage.getItem("noname_authorization")}`;
|
defaultHeaders["Authorization"] = `token ${localStorage.getItem("noname_authorization")}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取github授权的token
|
||||||
|
*/
|
||||||
export async function gainAuthorization() {
|
export async function gainAuthorization() {
|
||||||
if (!localStorage.getItem("noname_authorization") && !sessionStorage.getItem("noname_authorization")) {
|
if (!localStorage.getItem("noname_authorization") && !sessionStorage.getItem("noname_authorization")) {
|
||||||
const result = await game.promises.prompt("请输入您github的token以解除访问每小时60次的限制");
|
const result = await game.promises.prompt("请输入您github的token以解除访问每小时60次的限制(可不输入)");
|
||||||
if (typeof result == "string") {
|
if (typeof result == "string") {
|
||||||
localStorage.setItem("noname_authorization", result);
|
localStorage.setItem("noname_authorization", result);
|
||||||
defaultHeaders["Authorization"] = `token ${localStorage.getItem("noname_authorization")}`;
|
defaultHeaders["Authorization"] = `token ${localStorage.getItem("noname_authorization")}`;
|
||||||
|
@ -42,11 +45,17 @@ const defaultResponse = async (/** @type {Response} */ response) => {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
console.log(`限制重置时间`, new Date(reset * 1000).toLocaleString());
|
console.log(`限制重置时间`, new Date(reset * 1000).toLocaleString());
|
||||||
if (
|
if (
|
||||||
|
(
|
||||||
Number(remaining) === 0 &&
|
Number(remaining) === 0 &&
|
||||||
!sessionStorage.getItem("noname_authorization") &&
|
!sessionStorage.getItem("noname_authorization") &&
|
||||||
confirm(`您达到了每小时${limit}次的访问限制,是否输入您github的token以获取更高的请求总量限制`)
|
confirm(`您达到了每小时${limit}次的访问限制,是否输入您github账号的token以获取更高的请求总量限制`)
|
||||||
|
) || (
|
||||||
|
response.status === 401 &&
|
||||||
|
(localStorage.removeItem("noname_authorization"), true) &&
|
||||||
|
(alert(`身份验证凭证错误,是否重新输入您github账号的token以获取更高的请求总量限制`), true)
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
await gainAuthorization();
|
return gainAuthorization();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -85,9 +94,10 @@ export function parseSize(limit) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 对比版本号
|
* 对比版本号
|
||||||
* @param { string } ver1
|
* @param { string } ver1 版本号1
|
||||||
* @param { string } ver2
|
* @param { string } ver2 版本号2
|
||||||
* @returns { -1 | 0 | 1 }
|
* @returns { -1 | 0 | 1 } -1为ver1 < ver2, 0为ver1 == ver2, 1为ver1 > ver2
|
||||||
|
* @throws {Error}
|
||||||
*/
|
*/
|
||||||
export function checkVersion(ver1, ver2) {
|
export function checkVersion(ver1, ver2) {
|
||||||
if (typeof ver1 !== "string") ver1 = String(ver1);
|
if (typeof ver1 !== "string") ver1 = String(ver1);
|
||||||
|
@ -164,9 +174,9 @@ export function checkVersion(ver1, ver2) {
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
export async function getRepoTags(options = { username: "libccy", repository: "noname" }) {
|
export async function getRepoTags(options = { username: "libccy", repository: "noname" }) {
|
||||||
if (!localStorage.getItem("noname_authorization")) {
|
// if (!localStorage.getItem("noname_authorization")) {
|
||||||
await gainAuthorization();
|
// await gainAuthorization();
|
||||||
}
|
// }
|
||||||
const { username = "libccy", repository = "noname", accessToken } = options;
|
const { username = "libccy", repository = "noname", accessToken } = options;
|
||||||
const headers = Object.assign({}, defaultHeaders);
|
const headers = Object.assign({}, defaultHeaders);
|
||||||
if (accessToken) {
|
if (accessToken) {
|
||||||
|
@ -199,9 +209,9 @@ export async function getRepoTags(options = { username: "libccy", repository: "n
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export async function getRepoTagDescription(tagName, options = { username: "libccy", repository: "noname" }) {
|
export async function getRepoTagDescription(tagName, options = { username: "libccy", repository: "noname" }) {
|
||||||
if (!localStorage.getItem("noname_authorization")) {
|
// if (!localStorage.getItem("noname_authorization")) {
|
||||||
await gainAuthorization();
|
// await gainAuthorization();
|
||||||
}
|
// }
|
||||||
const { username = "libccy", repository = "noname", accessToken } = options;
|
const { username = "libccy", repository = "noname", accessToken } = options;
|
||||||
const headers = Object.assign({}, defaultHeaders);
|
const headers = Object.assign({}, defaultHeaders);
|
||||||
if (accessToken) {
|
if (accessToken) {
|
||||||
|
@ -243,7 +253,7 @@ export async function getRepoTagDescription(tagName, options = { username: "libc
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* 获取仓库指定分支和指定目录内的所有文件和目录
|
* 获取仓库指定分支和指定(单个)目录内的所有文件和目录
|
||||||
* @param { string } [path = ''] 路径名称(可放参数)
|
* @param { string } [path = ''] 路径名称(可放参数)
|
||||||
* @param { string } [branch = ''] 仓库分支名称
|
* @param { string } [branch = ''] 仓库分支名称
|
||||||
* @param { Object } options
|
* @param { Object } options
|
||||||
|
@ -263,9 +273,9 @@ export async function getRepoFilesList(
|
||||||
branch,
|
branch,
|
||||||
options = { username: "libccy", repository: "noname" }
|
options = { username: "libccy", repository: "noname" }
|
||||||
) {
|
) {
|
||||||
if (!localStorage.getItem("noname_authorization")) {
|
// if (!localStorage.getItem("noname_authorization")) {
|
||||||
await gainAuthorization();
|
// await gainAuthorization();
|
||||||
}
|
// }
|
||||||
const { username = "libccy", repository = "noname", accessToken } = options;
|
const { username = "libccy", repository = "noname", accessToken } = options;
|
||||||
const headers = Object.assign({}, defaultHeaders);
|
const headers = Object.assign({}, defaultHeaders);
|
||||||
if (accessToken) {
|
if (accessToken) {
|
||||||
|
@ -301,6 +311,9 @@ export async function getRepoFilesList(
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* 获取仓库指定分支和指定目录内的所有文件(包含子目录的文件)
|
* 获取仓库指定分支和指定目录内的所有文件(包含子目录的文件)
|
||||||
|
*
|
||||||
|
* **注意: 此api可能会大幅度消耗请求次数,请谨慎使用**
|
||||||
|
*
|
||||||
* @param { string } [path = ''] 路径名称(可放参数)
|
* @param { string } [path = ''] 路径名称(可放参数)
|
||||||
* @param { string } [branch = ''] 仓库分支名称
|
* @param { string } [branch = ''] 仓库分支名称
|
||||||
* @param { Object } options
|
* @param { Object } options
|
||||||
|
@ -320,6 +333,9 @@ export async function flattenRepositoryFiles(
|
||||||
branch,
|
branch,
|
||||||
options = { username: "libccy", repository: "noname" }
|
options = { username: "libccy", repository: "noname" }
|
||||||
) {
|
) {
|
||||||
|
if (!localStorage.getItem("noname_authorization")) {
|
||||||
|
await gainAuthorization();
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* @type { { download_url: string, name: string, path: string, sha: string, size: number, type: 'file' }[] }
|
* @type { { download_url: string, name: string, path: string, sha: string, size: number, type: 'file' }[] }
|
||||||
*/
|
*/
|
||||||
|
@ -350,7 +366,7 @@ export async function flattenRepositoryFiles(
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 请求一个文件而不是直接储存为文件
|
* 请求一个文件而不是直接储存为文件,这样可以省内存空间
|
||||||
* @param { string } url
|
* @param { string } url
|
||||||
* @param { (receivedBytes: number, total?:number, filename?: string) => void } [onProgress]
|
* @param { (receivedBytes: number, total?:number, filename?: string) => void } [onProgress]
|
||||||
* @param { RequestInit } [options={}]
|
* @param { RequestInit } [options={}]
|
||||||
|
@ -520,18 +536,15 @@ export function createProgress(title, max, fileName, value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the latest version tag from a GitHub repository, excluding a specific tag.
|
* 从GitHub存储库检索最新版本(tag),不包括特定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”.
|
* 此函数从GitHub存储库中获取由所有者和存储库名称指定的tags列表,然后返回不是“v1998”的最新tag名称。
|
||||||
* @param {string} owner - The username or organization name on GitHub that owns the repository.
|
* @param {string} owner GitHub上拥有存储库的用户名或组织名称。
|
||||||
* @param {string} repo - The name of the repository from which to fetch tags.
|
* @param {string} repo 要从中提取tag的存储库的名称。
|
||||||
* @returns {Promise<string>} A promise that resolves with the name of the latest version tag,
|
* @returns {Promise<string>} 以最新版本tag的名称解析的promise,或者如果操作失败则以错误拒绝。
|
||||||
* or rejects with an error if the operation fails.
|
* @throws {Error} 如果获取操作失败或找不到有效tag,将抛出错误。
|
||||||
* @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") {
|
export async function getLatestVersionFromGitHub(owner = "libccy", repo = "noname") {
|
||||||
if (!localStorage.getItem("noname_authorization")) await gainAuthorization();
|
|
||||||
|
|
||||||
const tags = await getRepoTags({
|
const tags = await getRepoTags({
|
||||||
username: owner,
|
username: owner,
|
||||||
repository: repo,
|
repository: repo,
|
||||||
|
@ -539,18 +552,24 @@ export async function getLatestVersionFromGitHub(owner = "libccy", repo = "nonam
|
||||||
|
|
||||||
for (const tag of tags) {
|
for (const tag of tags) {
|
||||||
const tagName = tag.name;
|
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");
|
throw new Error("No valid tags found in the repository");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetches trees from a GitHub repository within specified directories.
|
* 从指定目录中的GitHub存储库中获取树
|
||||||
* @param {string[]} directories - The list of directories to fetch the trees from.
|
* @param {string[]} directories 要从中获取树的目录列表
|
||||||
* @param {string} version - The version or branch to fetch the trees from.
|
* @param {string} version 从中获取树的版本或分支。
|
||||||
* @param {string} owner - The owner of the GitHub repository.
|
* @param {string} [owner = 'libccy'] GitHub上拥有存储库的用户名或组织名称。
|
||||||
* @param {string} repo - The name of the GitHub repository.
|
* @param {string} [repo = 'noname'] GitHub存储库的名称
|
||||||
* @returns {Promise<{
|
* @returns {Promise<{
|
||||||
* path: string;
|
* path: string;
|
||||||
* mode: string;
|
* mode: string;
|
||||||
|
@ -562,7 +581,7 @@ export async function getLatestVersionFromGitHub(owner = "libccy", repo = "nonam
|
||||||
* @throws {Error} Will throw an error if unable to fetch the repository tree from GitHub.
|
* @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") {
|
export async function getTreesFromGithub(directories, version, owner = "libccy", repo = "noname") {
|
||||||
if (!localStorage.getItem("noname_authorization")) await gainAuthorization();
|
// if (!localStorage.getItem("noname_authorization")) await gainAuthorization();
|
||||||
|
|
||||||
const treesResponse = await fetch(
|
const treesResponse = await fetch(
|
||||||
`https://api.github.com/repos/${owner}/${repo}/git/trees/${version}?recursive=1`,
|
`https://api.github.com/repos/${owner}/${repo}/git/trees/${version}?recursive=1`,
|
||||||
|
@ -570,7 +589,7 @@ export async function getTreesFromGithub(directories, version, owner = "libccy",
|
||||||
headers: defaultHeaders,
|
headers: defaultHeaders,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
await defaultResponse(treesResponse);
|
||||||
if (!treesResponse.ok)
|
if (!treesResponse.ok)
|
||||||
throw new Error(`Failed to fetch the GitHub repository tree: HTTP status ${treesResponse.status}`);
|
throw new Error(`Failed to fetch the GitHub repository tree: HTTP status ${treesResponse.status}`);
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -41,37 +41,41 @@ export class status {
|
||||||
prehidden_skills = [];
|
prehidden_skills = [];
|
||||||
postReconnect = {};
|
postReconnect = {};
|
||||||
/**
|
/**
|
||||||
* @type { string | void }
|
* @type { string | undefined }
|
||||||
*/
|
*/
|
||||||
extension = undefined;
|
extension = undefined;
|
||||||
/**
|
/**
|
||||||
* @type { boolean | void }
|
* @type { boolean | undefined }
|
||||||
*/
|
*/
|
||||||
dragged = undefined;
|
dragged = undefined;
|
||||||
/**
|
/**
|
||||||
* @type { boolean | void }
|
* @type { boolean | undefined }
|
||||||
*/
|
*/
|
||||||
touchconfirmed = undefined;
|
touchconfirmed = undefined;
|
||||||
/**
|
/**
|
||||||
* @type { boolean | void }
|
* @type { boolean | undefined }
|
||||||
*/
|
*/
|
||||||
connectMode = undefined;
|
connectMode = undefined;
|
||||||
/**
|
/**
|
||||||
* @type { boolean | void }
|
* @type { boolean | undefined }
|
||||||
*/
|
*/
|
||||||
importingExtension = undefined;
|
importingExtension = undefined;
|
||||||
/**
|
/**
|
||||||
* @type { Promise<any>[] | void }
|
* @type { Promise<any>[] | undefined }
|
||||||
*/
|
*/
|
||||||
extensionLoaded = undefined;
|
extensionLoaded = undefined;
|
||||||
/**
|
/**
|
||||||
* @type { Promise<any>[] | void }
|
* @type { Promise<any>[] | undefined }
|
||||||
*/
|
*/
|
||||||
extensionLoading = undefined;
|
extensionLoading = undefined;
|
||||||
/**
|
/**
|
||||||
* @type { { [key: string]: Promise<any>[] } | void }
|
* @type { { [key: string]: Promise<any>[] } | undefined }
|
||||||
*/
|
*/
|
||||||
importing = undefined;
|
importing = undefined;
|
||||||
|
/**
|
||||||
|
* @type { Function | boolean | undefined }
|
||||||
|
*/
|
||||||
|
new_tutorial = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export let _status = new status();
|
export let _status = new status();
|
||||||
|
|
|
@ -13,6 +13,10 @@ export class Click {
|
||||||
* @type {(arg0: string) => void}
|
* @type {(arg0: string) => void}
|
||||||
*/
|
*/
|
||||||
menuTab;
|
menuTab;
|
||||||
|
/**
|
||||||
|
* @type {() => void}
|
||||||
|
*/
|
||||||
|
configMenu;
|
||||||
identitycircle() {
|
identitycircle() {
|
||||||
var list = [];
|
var list = [];
|
||||||
this.classList.toggle("transparent");
|
this.classList.toggle("transparent");
|
||||||
|
|
|
@ -2558,12 +2558,12 @@ export class Create {
|
||||||
lib.status.date = new Date();
|
lib.status.date = new Date();
|
||||||
lib.status.dateDelayed = 0;
|
lib.status.dateDelayed = 0;
|
||||||
|
|
||||||
while (lib.arenaReady.length) {
|
// @ts-ignore
|
||||||
lib.arenaReady.shift()();
|
while (lib.arenaReady.length) lib.arenaReady.shift()();
|
||||||
}
|
|
||||||
delete lib.arenaReady;
|
delete lib.arenaReady;
|
||||||
if (lib.config.auto_check_update) {
|
if (lib.config.auto_check_update && !sessionStorage.getItem("auto_check_update")) {
|
||||||
setTimeout(function () {
|
setTimeout(() => {
|
||||||
|
sessionStorage.setItem("auto_check_update", '1');
|
||||||
game.checkForUpdate(false);
|
game.checkForUpdate(false);
|
||||||
}, 3000);
|
}, 3000);
|
||||||
}
|
}
|
||||||
|
@ -2574,7 +2574,7 @@ export class Create {
|
||||||
game.saveConfig("asset_version", "无");
|
game.saveConfig("asset_version", "无");
|
||||||
} else {
|
} else {
|
||||||
var func = function () {
|
var func = function () {
|
||||||
if (confirm("是否下载图片和字体素材?(约175MB)")) {
|
if (confirm("是否下载图片和字体素材?(约386.6MB)")) {
|
||||||
if (!ui.arena.classList.contains("menupaused")) {
|
if (!ui.arena.classList.contains("menupaused")) {
|
||||||
ui.click.configMenu();
|
ui.click.configMenu();
|
||||||
ui.click.menuTab("其它");
|
ui.click.menuTab("其它");
|
||||||
|
|
|
@ -2632,9 +2632,9 @@ export const extensionMenu = function (connectMenu) {
|
||||||
fileReader.onerror = reject;
|
fileReader.onerror = reject;
|
||||||
fileReader.onload = resolve;
|
fileReader.onload = resolve;
|
||||||
fileReader.readAsArrayBuffer(fileToLoad, "UTF-8");
|
fileReader.readAsArrayBuffer(fileToLoad, "UTF-8");
|
||||||
}).then((progressEvent) => {
|
}).then(async (progressEvent) => {
|
||||||
if (
|
if (
|
||||||
game.importExtension(progressEvent.target.result, () => {
|
await game.importExtension(progressEvent.target.result, () => {
|
||||||
extensionNode.innerHTML = "导入成功,3秒后将重启";
|
extensionNode.innerHTML = "导入成功,3秒后将重启";
|
||||||
new Promise((resolve) => setTimeout(resolve, 1000))
|
new Promise((resolve) => setTimeout(resolve, 1000))
|
||||||
.then(() => {
|
.then(() => {
|
||||||
|
|
|
@ -14,12 +14,9 @@ import { ui, game, get, ai, lib, _status } from "../../../../../noname.js";
|
||||||
import {
|
import {
|
||||||
parseSize,
|
parseSize,
|
||||||
checkVersion,
|
checkVersion,
|
||||||
getRepoTags,
|
|
||||||
getRepoTagDescription,
|
getRepoTagDescription,
|
||||||
flattenRepositoryFiles,
|
|
||||||
request,
|
request,
|
||||||
createProgress,
|
createProgress,
|
||||||
gainAuthorization,
|
|
||||||
getLatestVersionFromGitHub,
|
getLatestVersionFromGitHub,
|
||||||
getTreesFromGithub,
|
getTreesFromGithub,
|
||||||
} from "../../../../library/update.js";
|
} from "../../../../library/update.js";
|
||||||
|
@ -56,6 +53,9 @@ export const otherMenu = function (/** @type { boolean | undefined } */ connectM
|
||||||
saveButton.style.display = "none";
|
saveButton.style.display = "none";
|
||||||
saveButton.style.transition = "opacity 0.3s";
|
saveButton.style.transition = "opacity 0.3s";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @this { HTMLDivElement }
|
||||||
|
*/
|
||||||
var clickMode = function () {
|
var clickMode = function () {
|
||||||
if (this.classList.contains("off")) return;
|
if (this.classList.contains("off")) return;
|
||||||
var active = this.parentNode.querySelector(".active");
|
var active = this.parentNode.querySelector(".active");
|
||||||
|
@ -166,79 +166,17 @@ export const otherMenu = function (/** @type { boolean | undefined } */ connectM
|
||||||
checkDevVersionButton.disabled = true;
|
checkDevVersionButton.disabled = true;
|
||||||
checkVersionButton.disabled = true;
|
checkVersionButton.disabled = true;
|
||||||
|
|
||||||
function refresh() {
|
const refresh = () => {
|
||||||
checkVersionButton.disabled = false;
|
checkVersionButton.disabled = false;
|
||||||
checkVersionButton.innerHTML = "检查游戏更新";
|
checkVersionButton.innerHTML = "检查游戏更新";
|
||||||
checkDevVersionButton.disabled = false;
|
checkDevVersionButton.disabled = false;
|
||||||
checkDevVersionButton.innerHTML = "更新到开发版";
|
checkDevVersionButton.innerHTML = "更新到开发版";
|
||||||
}
|
}
|
||||||
|
|
||||||
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") {
|
|
||||||
/** @type { ReturnType<import('../../../../library/update.js').getRepoTagDescription> } */
|
|
||||||
const description = lib.config["version_description_" + tag.name];
|
|
||||||
return description;
|
|
||||||
} else return getRepoTagDescription(tag.name);
|
|
||||||
})
|
|
||||||
.then((description) => {
|
|
||||||
// 保存版本信息
|
|
||||||
if (typeof lib.config["version_description_" + description.name] != "object") {
|
|
||||||
game.saveConfig("version_description_" + description.name, description);
|
|
||||||
}
|
|
||||||
const versionResult = checkVersion(lib.version, description.name);
|
|
||||||
if (versionResult === 0) {
|
|
||||||
// forcecheck: 为false的时候是自动检测更新的调用
|
|
||||||
if (forcecheck === false || !confirm("版本已是最新,是否强制更新?")) {
|
|
||||||
refresh();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const str =
|
|
||||||
versionResult > 0
|
|
||||||
? `有新版本${description.name}可用,是否下载?`
|
|
||||||
: `本地版本${lib.version}高于或等于github版本${description.name},是否强制下载?`;
|
|
||||||
const str2 = description.body;
|
|
||||||
if (navigator.notification && navigator.notification.confirm) {
|
|
||||||
navigator.notification.confirm(
|
|
||||||
str2,
|
|
||||||
function (index) {
|
|
||||||
if (index == 1) {
|
|
||||||
download(description);
|
|
||||||
} else refresh();
|
|
||||||
},
|
|
||||||
str,
|
|
||||||
["确定", "取消"]
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
if (confirm(str + "\n" + str2)) {
|
|
||||||
download(description);
|
|
||||||
} else refresh();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((e) => {
|
|
||||||
alert("获取更新失败: " + e);
|
|
||||||
refresh();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
if (confirm("将要直接下载dev版本的完整包,是否继续?")) {
|
|
||||||
download({
|
|
||||||
name: "noname-PR-Branch",
|
|
||||||
assets: [],
|
|
||||||
zipball_url:
|
|
||||||
"https://ghproxy.cc/https://github.com/libccy/noname/archive/PR-Branch.zip",
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
refresh();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* @param {{ assets: any; author?: { login: string; avatar_url: string; html_url: string; }; body?: string; html_url?: string; name: any; published_at?: string; zipball_url: any; }} description
|
* @param {{ assets: any; author?: { login: string; avatar_url: string; html_url: string; }; body?: string; html_url?: string; name: any; published_at?: string; zipball_url: any; }} description
|
||||||
*/
|
*/
|
||||||
function download(description) {
|
const download = description => {
|
||||||
const progress = createProgress(
|
const progress = createProgress(
|
||||||
"正在更新" + description.name,
|
"正在更新" + description.name,
|
||||||
1,
|
1,
|
||||||
|
@ -385,6 +323,69 @@ export const otherMenu = function (/** @type { boolean | undefined } */ connectM
|
||||||
throw e;
|
throw e;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!dev) {
|
||||||
|
getLatestVersionFromGitHub()
|
||||||
|
.then(tagName => {
|
||||||
|
game.saveConfig("check_version", tagName.slice(1));
|
||||||
|
if (typeof lib.config[`version_description_${tagName}`] == "object") {
|
||||||
|
/** @type { ReturnType<import('../../../../library/update.js').getRepoTagDescription> } */
|
||||||
|
const description = lib.config[`version_description_${tagName}`];
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
else return getRepoTagDescription(tagName);
|
||||||
|
})
|
||||||
|
.then(description => {
|
||||||
|
// 保存版本信息
|
||||||
|
if (typeof lib.config["version_description_" + description.name] != "object") {
|
||||||
|
game.saveConfig("version_description_" + description.name, description);
|
||||||
|
}
|
||||||
|
const versionResult = checkVersion(lib.version, description.name);
|
||||||
|
if (versionResult === 0) {
|
||||||
|
// forcecheck: 为false的时候是自动检测更新的调用
|
||||||
|
if (forcecheck === false || !confirm("版本已是最新,是否强制更新?")) {
|
||||||
|
refresh();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const str =
|
||||||
|
versionResult > 0
|
||||||
|
? `有新版本${description.name}可用,是否下载?`
|
||||||
|
: `本地版本${lib.version}高于或等于github版本${description.name},是否强制下载?`;
|
||||||
|
const str2 = description.body;
|
||||||
|
if (navigator.notification && navigator.notification.confirm) {
|
||||||
|
navigator.notification.confirm(
|
||||||
|
str2,
|
||||||
|
function (index) {
|
||||||
|
if (index == 1) {
|
||||||
|
download(description);
|
||||||
|
} else refresh();
|
||||||
|
},
|
||||||
|
str,
|
||||||
|
["确定", "取消"]
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
if (confirm(str + "\n" + str2)) {
|
||||||
|
download(description);
|
||||||
|
} else refresh();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
alert("获取更新失败: " + e);
|
||||||
|
refresh();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
if (confirm("将要直接下载dev版本的完整包,是否继续?")) {
|
||||||
|
download({
|
||||||
|
name: "noname-PR-Branch",
|
||||||
|
assets: [],
|
||||||
|
zipball_url:
|
||||||
|
"https://ghproxy.cc/https://github.com/libccy/noname/archive/PR-Branch.zip",
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -392,21 +393,21 @@ export const otherMenu = function (/** @type { boolean | undefined } */ connectM
|
||||||
if (checkAssetButton.disabled) {
|
if (checkAssetButton.disabled) {
|
||||||
return;
|
return;
|
||||||
} else if (game.download) {
|
} else if (game.download) {
|
||||||
if (
|
// if (
|
||||||
!localStorage.getItem("noname_authorization") &&
|
// !localStorage.getItem("noname_authorization") &&
|
||||||
!sessionStorage.getItem("noname_authorization")
|
// !sessionStorage.getItem("noname_authorization")
|
||||||
) {
|
// ) {
|
||||||
if (
|
// if (
|
||||||
confirm(
|
// confirm(
|
||||||
"素材更新或许会直接超过每小时的访问限制,是否输入您github的token以解除访问每小时60次的限制?"
|
// "素材更新或许会直接超过每小时的访问限制,是否输入您github的token以解除访问每小时60次的限制?"
|
||||||
)
|
// )
|
||||||
)
|
// )
|
||||||
await gainAuthorization();
|
// await gainAuthorization();
|
||||||
}
|
// }
|
||||||
checkAssetButton.innerHTML = "正在检查更新";
|
checkAssetButton.innerHTML = "正在检查更新";
|
||||||
checkAssetButton.disabled = true;
|
checkAssetButton.disabled = true;
|
||||||
|
|
||||||
function refresh() {
|
const refresh = () => {
|
||||||
checkAssetButton.innerHTML = "检查素材更新";
|
checkAssetButton.innerHTML = "检查素材更新";
|
||||||
checkAssetButton.disabled = false;
|
checkAssetButton.disabled = false;
|
||||||
}
|
}
|
||||||
|
@ -415,8 +416,14 @@ export const otherMenu = function (/** @type { boolean | undefined } */ connectM
|
||||||
if (lib.config.asset_font) assetDirectories.push("font");
|
if (lib.config.asset_font) assetDirectories.push("font");
|
||||||
if (lib.config.asset_audio) assetDirectories.push("audio");
|
if (lib.config.asset_audio) assetDirectories.push("audio");
|
||||||
if (lib.config.asset_image) assetDirectories.push("image");
|
if (lib.config.asset_image) assetDirectories.push("image");
|
||||||
const version = await getLatestVersionFromGitHub();
|
const version = await getLatestVersionFromGitHub().catch(e => {
|
||||||
const files = await getTreesFromGithub(assetDirectories, version);
|
refresh();
|
||||||
|
throw e;
|
||||||
|
});
|
||||||
|
const files = await getTreesFromGithub(assetDirectories, version).catch(e => {
|
||||||
|
refresh();
|
||||||
|
throw e;
|
||||||
|
});
|
||||||
|
|
||||||
assetDirectories.forEach((assetDirectory, index) => {
|
assetDirectories.forEach((assetDirectory, index) => {
|
||||||
const arr = files[index];
|
const arr = files[index];
|
||||||
|
@ -432,18 +439,28 @@ export const otherMenu = function (/** @type { boolean | undefined } */ connectM
|
||||||
* @param { (value: T) => Promise<boolean> } predicate
|
* @param { (value: T) => Promise<boolean> } predicate
|
||||||
*/
|
*/
|
||||||
const asyncFilter = async (arr, 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]);
|
return arr.filter((_v, index) => results[index]);
|
||||||
};
|
};
|
||||||
|
|
||||||
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 game.promises.readFile(v.path).then(data => {
|
||||||
}).then((arr) => arr.map((v) => v.path));
|
return v.size != data.byteLength;
|
||||||
|
})
|
||||||
|
}).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 () => {
|
||||||
await lib.init.promises.js("game", "asset.js");
|
await lib.init.promises.js("game", "asset");
|
||||||
if (Array.isArray(window.noname_asset_list)) {
|
if (Array.isArray(window.noname_asset_list)) {
|
||||||
game.saveConfig("asset_version", window.noname_asset_list[0]);
|
game.saveConfig("asset_version", window.noname_asset_list[0]);
|
||||||
delete window.noname_asset_list;
|
delete window.noname_asset_list;
|
||||||
|
@ -460,7 +477,7 @@ export const otherMenu = function (/** @type { boolean | undefined } */ connectM
|
||||||
*/
|
*/
|
||||||
let unZipProgress;
|
let unZipProgress;
|
||||||
request(
|
request(
|
||||||
"api.unitedrhythmized.club/noname",
|
"https://api.unitedrhythmized.club/noname",
|
||||||
(receivedBytes, total, filename) => {
|
(receivedBytes, total, filename) => {
|
||||||
if (typeof filename == "string") {
|
if (typeof filename == "string") {
|
||||||
progress.setFileName(filename);
|
progress.setFileName(filename);
|
||||||
|
|
Loading…
Reference in New Issue