mirror of
https://github.com/Shu-Ying/noname-shuying.git
synced 2026-10-21 14:49:59 +08:00
新增更新通道选择
This commit is contained in:
+8
-5
@@ -49,12 +49,10 @@ shuYing.initFunction = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
shuYing.getOnlineVersionText = () => `最新版本:${lib.config.shuYing_online_version || "检测中..."}`;
|
shuYing.getOnlineVersionText = () => `最新版本:${lib.config.shuYing_online_version || "检测中..."}`;
|
||||||
shuYing.updateOnlineVersionMenu = (version) => {
|
shuYing.updateOnlineVersionMenu = (version, status = "检测中...") => {
|
||||||
if (!version) return;
|
if (version) game.saveConfig("shuYing_online_version", version);
|
||||||
|
|
||||||
game.saveConfig("shuYing_online_version", version);
|
const text = `最新版本:${version || status}`;
|
||||||
|
|
||||||
const text = `最新版本:${version}`;
|
|
||||||
if (lib.extensionMenu.extension_术樱包?.online_version) {
|
if (lib.extensionMenu.extension_术樱包?.online_version) {
|
||||||
lib.extensionMenu.extension_术樱包.online_version.name = text;
|
lib.extensionMenu.extension_术樱包.online_version.name = text;
|
||||||
}
|
}
|
||||||
@@ -113,8 +111,11 @@ shuYing.mergeCharacterPack = function (target, source, sourceName = "附加模
|
|||||||
};
|
};
|
||||||
|
|
||||||
shuYing.getVersion = (callback) => {
|
shuYing.getVersion = (callback) => {
|
||||||
|
const requestId = (shuYing.versionRequestId || 0) + 1;
|
||||||
|
shuYing.versionRequestId = requestId;
|
||||||
return updater.getOnlineVersion()
|
return updater.getOnlineVersion()
|
||||||
.then(version => {
|
.then(version => {
|
||||||
|
if (requestId != shuYing.versionRequestId) return null;
|
||||||
shuYing.updateOnlineVersionMenu(version?.online_version);
|
shuYing.updateOnlineVersionMenu(version?.online_version);
|
||||||
if (typeof callback == "function") {
|
if (typeof callback == "function") {
|
||||||
callback(version);
|
callback(version);
|
||||||
@@ -122,7 +123,9 @@ shuYing.getVersion = (callback) => {
|
|||||||
return version;
|
return version;
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
|
if (requestId != shuYing.versionRequestId) return null;
|
||||||
console.error("术樱包获取在线版本失败:", error);
|
console.error("术樱包获取在线版本失败:", error);
|
||||||
|
shuYing.updateOnlineVersionMenu(null, "获取失败");
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -210,7 +210,7 @@ export default function initShuYingMenu({ lib, game, ui, shuYing, updater }) {
|
|||||||
menu.update_channel = {
|
menu.update_channel = {
|
||||||
name: channelText(updater.getUpdateChannel()),
|
name: channelText(updater.getUpdateChannel()),
|
||||||
clear: true,
|
clear: true,
|
||||||
intro: "切换后立即从 Gitea 对应标签下载并校验文件,完成后需重启游戏。测试版可能回退到较早的内容。",
|
intro: "切换后立即从当前下载源的对应标签下载并校验文件,完成后需重启游戏。测试版可能回退到较早的内容。",
|
||||||
async onclick() {
|
async onclick() {
|
||||||
if (!shuYing.m_bIsDownload) {
|
if (!shuYing.m_bIsDownload) {
|
||||||
alert("有其他文件正在下载,请稍后再试吧。");
|
alert("有其他文件正在下载,请稍后再试吧。");
|
||||||
@@ -239,6 +239,28 @@ export default function initShuYingMenu({ lib, game, ui, shuYing, updater }) {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const sourceText = source => `下载源:${source == "github" ? "GitHub" : "Gitea"}(点击切换)`;
|
||||||
|
menu.update_source = {
|
||||||
|
name: sourceText(updater.getUpdateSource()),
|
||||||
|
clear: true,
|
||||||
|
intro: "选择从 GitHub 或 Gitea 获取标签与文件;切换后刷新在线版本,实际下载由版本检测触发。",
|
||||||
|
onclick() {
|
||||||
|
if (!shuYing.m_bIsDownload) {
|
||||||
|
alert("有其他文件正在下载,请稍后再试吧。");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const next = updater.getUpdateSource() == "github" ? "gitea" : "github";
|
||||||
|
game.saveConfig("shuYing_update_source", next);
|
||||||
|
const text = sourceText(next);
|
||||||
|
menu.update_source.name = text;
|
||||||
|
this.innerHTML = text;
|
||||||
|
game.saveConfig("shuYing_online_version", null);
|
||||||
|
shuYing.updateOnlineVersionMenu(null, "检测中...");
|
||||||
|
shuYing.getVersion();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
menu.updateLog = {
|
menu.updateLog = {
|
||||||
name: '<div class="hth_menu">▶更新日志</div>',
|
name: '<div class="hth_menu">▶更新日志</div>',
|
||||||
clear: true,
|
clear: true,
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import { lib, game } from "../../noname.js";
|
import { lib, game } from "../../noname.js";
|
||||||
|
|
||||||
const repositoryApi = "https://gitea.diuse.work/api/v1/repos/Diuse/noname-shuying";
|
const giteaRepositoryApi = "https://gitea.diuse.work/api/v1/repos/Diuse/noname-shuying";
|
||||||
|
const githubRepositoryApi = "https://api.github.com/repos/Shu-Ying/noname-shuying";
|
||||||
|
const githubRawBase = "https://raw.githubusercontent.com/Shu-Ying/noname-shuying";
|
||||||
const coreTempDir = "extension/术樱包/.update_tmp";
|
const coreTempDir = "extension/术樱包/.update_tmp";
|
||||||
|
|
||||||
function parseVersion(version) {
|
function parseVersion(version) {
|
||||||
@@ -30,15 +32,25 @@ function getUpdateChannel() {
|
|||||||
? "preview" : "stable");
|
? "preview" : "stable");
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRemoteUrl(tag, path) {
|
function getUpdateSource() {
|
||||||
const filePath = path.split("/").map(encodeURIComponent).join("/");
|
return lib.config.shuYing_update_source == "github" ? "github" : "gitea";
|
||||||
return `${repositoryApi}/raw/${filePath}?ref=${encodeURIComponent(tag)}`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getLatestTag(channel = getUpdateChannel()) {
|
function getRemoteUrl(tag, path, source = getUpdateSource()) {
|
||||||
|
const filePath = path.split("/").map(encodeURIComponent).join("/");
|
||||||
|
if (source == "github") {
|
||||||
|
return `${githubRawBase}/${encodeURIComponent(tag)}/${filePath}`;
|
||||||
|
}
|
||||||
|
return `${giteaRepositoryApi}/raw/${filePath}?ref=${encodeURIComponent(tag)}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getLatestTag(channel = getUpdateChannel(), source = getUpdateSource()) {
|
||||||
let latest = null;
|
let latest = null;
|
||||||
for (let page = 1; ; page++) {
|
for (let page = 1; ; page++) {
|
||||||
const response = await fetch(`${repositoryApi}/tags?page=${page}&limit=50`);
|
const tagsUrl = source == "github"
|
||||||
|
? `${githubRepositoryApi}/tags?page=${page}&per_page=50`
|
||||||
|
: `${giteaRepositoryApi}/tags?page=${page}&limit=50`;
|
||||||
|
const response = await fetch(tagsUrl);
|
||||||
if (!response.ok) throw new Error(`标签请求失败:${response.status}`);
|
if (!response.ok) throw new Error(`标签请求失败:${response.status}`);
|
||||||
const tags = await response.json();
|
const tags = await response.json();
|
||||||
if (!Array.isArray(tags)) throw new Error("标签列表格式错误");
|
if (!Array.isArray(tags)) throw new Error("标签列表格式错误");
|
||||||
@@ -55,7 +67,7 @@ async function getLatestTag(channel = getUpdateChannel()) {
|
|||||||
}
|
}
|
||||||
if (tags.length < 50) break;
|
if (tags.length < 50) break;
|
||||||
}
|
}
|
||||||
if (!latest) throw new Error(`Gitea 镜像尚无${channel == "preview" ? "测试版" : "正式版"}标签`);
|
if (!latest) throw new Error(`更新源尚无${channel == "preview" ? "测试版" : "正式版"}标签`);
|
||||||
return latest;
|
return latest;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,8 +204,8 @@ function splitPath(path) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fetchFile(path, tag) {
|
async function fetchFile(path, tag, source) {
|
||||||
const response = await fetch(getRemoteUrl(tag, path));
|
const response = await fetch(getRemoteUrl(tag, path, source));
|
||||||
if (!response.ok) throw new Error(`${path} 下载失败:${response.status}`);
|
if (!response.ok) throw new Error(`${path} 下载失败:${response.status}`);
|
||||||
|
|
||||||
return await response.arrayBuffer();
|
return await response.arrayBuffer();
|
||||||
@@ -209,7 +221,7 @@ async function writeTargetFile(data, target) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function downloadFile(path, target, manifest) {
|
async function downloadFile(path, target, manifest) {
|
||||||
const data = await fetchFile(path, manifest.tag_name);
|
const data = await fetchFile(path, manifest.tag_name, manifest.source);
|
||||||
if (manifest?.files?.[path]) {
|
if (manifest?.files?.[path]) {
|
||||||
await verifyFile(path, data, manifest);
|
await verifyFile(path, data, manifest);
|
||||||
}
|
}
|
||||||
@@ -217,8 +229,9 @@ async function downloadFile(path, target, manifest) {
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getManifestFromTag(tag, requireChannels = true) {
|
async function getManifestFromTag(tag, requireChannels = true,
|
||||||
const response = await fetch(getRemoteUrl(tag.name, "dist/manifest.json"));
|
source = getUpdateSource()) {
|
||||||
|
const response = await fetch(getRemoteUrl(tag.name, "dist/manifest.json", source));
|
||||||
if (!response.ok) throw new Error(`校验清单请求失败:${response.status}`);
|
if (!response.ok) throw new Error(`校验清单请求失败:${response.status}`);
|
||||||
const manifest = await response.json();
|
const manifest = await response.json();
|
||||||
|
|
||||||
@@ -246,11 +259,12 @@ async function getManifestFromTag(tag, requireChannels = true) {
|
|||||||
getManifestRemoveDirectories(manifest);
|
getManifestRemoveDirectories(manifest);
|
||||||
|
|
||||||
manifest.tag_name = tag.name;
|
manifest.tag_name = tag.name;
|
||||||
|
manifest.source = source;
|
||||||
return manifest;
|
return manifest;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getManifest(channel = getUpdateChannel()) {
|
async function getManifest(channel = getUpdateChannel(), source = getUpdateSource()) {
|
||||||
return getManifestFromTag(await getLatestTag(channel));
|
return getManifestFromTag(await getLatestTag(channel, source), true, source);
|
||||||
}
|
}
|
||||||
|
|
||||||
function normalizeManifestPath(path) {
|
function normalizeManifestPath(path) {
|
||||||
@@ -727,8 +741,9 @@ async function downloadList(shuYing, files, manifest) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getOnlineVersion(channel = getUpdateChannel()) {
|
async function getOnlineVersion(channel = getUpdateChannel(),
|
||||||
const manifest = await getManifest(channel);
|
source = getUpdateSource()) {
|
||||||
|
const manifest = await getManifest(channel, source);
|
||||||
return { online_version: manifest.version, manifest };
|
return { online_version: manifest.version, manifest };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -736,19 +751,19 @@ async function checkVersion(shuYing, options = {}) {
|
|||||||
try {
|
try {
|
||||||
shuYing._updateLogs = [];
|
shuYing._updateLogs = [];
|
||||||
await addLog(shuYing, "版本检查开始");
|
await addLog(shuYing, "版本检查开始");
|
||||||
const onlineVersion = await getOnlineVersion(options.channel);
|
const onlineVersion = await getOnlineVersion(options.channel, options.source);
|
||||||
const localVersion = lib.config.shuYing_local_version || "0.0.0.0";
|
const localVersion = lib.config.shuYing_local_version || "0.0.0.0";
|
||||||
const manifest = onlineVersion.manifest;
|
const manifest = onlineVersion.manifest;
|
||||||
if (!options.switchChannel && parseVersion(localVersion)
|
if (!options.switchChannel && parseVersion(localVersion)
|
||||||
&& compareVersions(onlineVersion.online_version, localVersion) < 0) {
|
&& compareVersions(onlineVersion.online_version, localVersion) < 0) {
|
||||||
throw new Error("Gitea 镜像尚未同步到本地版本,请稍后重试");
|
throw new Error("目标更新源的版本落后于本地版本,请稍后重试");
|
||||||
}
|
}
|
||||||
if (options.switchChannel && parseVersion(localVersion)
|
if (options.switchChannel && parseVersion(localVersion)
|
||||||
&& localVersion != manifest.version) {
|
&& localVersion != manifest.version) {
|
||||||
const previous = await getManifestFromTag({
|
const previous = await getManifestFromTag({
|
||||||
name: `v${localVersion}`,
|
name: `v${localVersion}`,
|
||||||
version: localVersion,
|
version: localVersion,
|
||||||
}, false);
|
}, false, manifest.source);
|
||||||
const targetFiles = new Set(getManifestFileKeys(manifest));
|
const targetFiles = new Set(getManifestFileKeys(manifest));
|
||||||
const removed = getManifestFileKeys(previous)
|
const removed = getManifestFileKeys(previous)
|
||||||
.filter(file => !targetFiles.has(file));
|
.filter(file => !targetFiles.has(file));
|
||||||
@@ -757,7 +772,7 @@ async function checkVersion(shuYing, options = {}) {
|
|||||||
}
|
}
|
||||||
const changed = await getChangedFiles(manifest);
|
const changed = await getChangedFiles(manifest);
|
||||||
const obsolete = await getObsoleteFiles(manifest);
|
const obsolete = await getObsoleteFiles(manifest);
|
||||||
await addLog(shuYing, `Gitea 标签:${manifest.tag_name};待更新文件:${changed.length};待删除文件:${obsolete.length}`);
|
await addLog(shuYing, `更新源:${manifest.source};标签:${manifest.tag_name};待更新文件:${changed.length};待删除文件:${obsolete.length}`);
|
||||||
|
|
||||||
if (localVersion == onlineVersion.online_version
|
if (localVersion == onlineVersion.online_version
|
||||||
&& !changed.length && !obsolete.length) {
|
&& !changed.length && !obsolete.length) {
|
||||||
@@ -885,6 +900,7 @@ async function repairCoreFiles(shuYing) {
|
|||||||
export default {
|
export default {
|
||||||
getOnlineVersion,
|
getOnlineVersion,
|
||||||
getUpdateChannel,
|
getUpdateChannel,
|
||||||
|
getUpdateSource,
|
||||||
checkVersion,
|
checkVersion,
|
||||||
repairMissingFiles,
|
repairMissingFiles,
|
||||||
repairCoreFiles,
|
repairCoreFiles,
|
||||||
|
|||||||
Reference in New Issue
Block a user