重写更新逻辑(50%,需要另外的服务器支持增量更新)
This commit is contained in:
parent
612d0231b3
commit
bd7cb202b7
|
@ -5572,3 +5572,20 @@ div[data-decoration="bronze"]::after{
|
||||||
* {
|
* {
|
||||||
scrollbar-width: none;
|
scrollbar-width: none;
|
||||||
}
|
}
|
||||||
|
/* 更新进度条 */
|
||||||
|
progress.progress {
|
||||||
|
width: 75%;
|
||||||
|
height: 10px;
|
||||||
|
border: 2px solid;
|
||||||
|
border-radius: 15px;
|
||||||
|
vertical-align: middle;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
}
|
||||||
|
progress.progress::-webkit-progress-bar {
|
||||||
|
background: rgb(239, 239, 239);
|
||||||
|
border-radius: 0.2rem;
|
||||||
|
}
|
||||||
|
progress.progress::-webkit-progress-value {
|
||||||
|
border-radius: 0.2rem;
|
||||||
|
background: rgb(0, 117, 255);
|
||||||
|
}
|
||||||
|
|
|
@ -73,7 +73,6 @@ declare type Dialog = import('../../noname/library/index.js').Dialog;
|
||||||
declare type GameEvent = import('../../noname/library/index.js').GameEvent;
|
declare type GameEvent = import('../../noname/library/index.js').GameEvent;
|
||||||
declare type GameEventPromise = import('../../noname/library/index.js').GameEventPromise;
|
declare type GameEventPromise = import('../../noname/library/index.js').GameEventPromise;
|
||||||
declare type Player = import('../../noname/library/index.js').Player;
|
declare type Player = import('../../noname/library/index.js').Player;
|
||||||
declare type VCard = import('../../noname/library/index.js').VCard;
|
|
||||||
declare type Control = import('../../noname/library/index.js').Control;
|
declare type Control = import('../../noname/library/index.js').Control;
|
||||||
|
|
||||||
declare type Video = import('../../noname/game/index.js').Video;
|
declare type Video = import('../../noname/game/index.js').Video;
|
||||||
|
@ -85,6 +84,27 @@ declare type Sex = 'male' | 'female' | 'dobule' | 'none';
|
||||||
declare type Character = [Sex, string, number | string, string[], string[]] | [Sex, string, number | string, string[]];
|
declare type Character = [Sex, string, number | string, string[], string[]] | [Sex, string, number | string, string[]];
|
||||||
declare type Select = [number, number];
|
declare type Select = [number, number];
|
||||||
|
|
||||||
|
declare interface progress extends HTMLDivElement {
|
||||||
|
/** 获取标题 */
|
||||||
|
getTitle: () => string;
|
||||||
|
/** 更改标题 */
|
||||||
|
setTitle: (title: string) => void;
|
||||||
|
/** 获取显示的文件名 */
|
||||||
|
getFileName: () => string;
|
||||||
|
/** 更改显示的文件名 */
|
||||||
|
setFileName: (title: string) => void;
|
||||||
|
/** 获取进度*/
|
||||||
|
getProgressValue: () => number;
|
||||||
|
/** 更改进度*/
|
||||||
|
setProgressValue: (value: number) => void;
|
||||||
|
/** 获取下载文件总数 */
|
||||||
|
getProgressMax: () => number;
|
||||||
|
/** 修改下载文件总数 */
|
||||||
|
setProgressMax: (max: number) => void;
|
||||||
|
/** 通过数组自动解析文件名 */
|
||||||
|
autoSetFileNameFromArray: (fileNameList: string[]) => void;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 导入武将包的配置
|
* 导入武将包的配置
|
||||||
*/
|
*/
|
||||||
|
@ -269,7 +289,7 @@ declare interface importModeConfig {
|
||||||
*/
|
*/
|
||||||
characterSort?: SMap<SMap<string[]>>;
|
characterSort?: SMap<SMap<string[]>>;
|
||||||
/** 卡牌(主要是放些该模式下特有的卡牌) */
|
/** 卡牌(主要是放些该模式下特有的卡牌) */
|
||||||
card?: SMap<ExCardData>;
|
card?: SMap<Card>;
|
||||||
/**
|
/**
|
||||||
* 卡包
|
* 卡包
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -19,7 +19,7 @@ export function canUseHttpProtocol() {
|
||||||
// 如果是http了就不用
|
// 如果是http了就不用
|
||||||
if (location.protocol.startsWith('http')) return false;
|
if (location.protocol.startsWith('http')) return false;
|
||||||
// 首次启动不更新(即还没进行过新手教程)
|
// 首次启动不更新(即还没进行过新手教程)
|
||||||
if (!lib.config.new_tutorial) return false;
|
if (!config.get('new_tutorial')) return false;
|
||||||
if (typeof nonameInitialized == 'string') {
|
if (typeof nonameInitialized == 'string') {
|
||||||
// 手机端
|
// 手机端
|
||||||
if (window.cordova) {
|
if (window.cordova) {
|
||||||
|
@ -134,18 +134,6 @@ export async function boot() {
|
||||||
setWindowListener();
|
setWindowListener();
|
||||||
const promiseErrorHandler = await setOnError();
|
const promiseErrorHandler = await setOnError();
|
||||||
|
|
||||||
// 无名杀更新日志
|
|
||||||
if (window.noname_update) {
|
|
||||||
Reflect.set(lib, 'version', window.noname_update.version);
|
|
||||||
lib.changeLog = window.noname_update.changeLog;
|
|
||||||
if (window.noname_update.players) {
|
|
||||||
lib.changeLog.push('players://' + JSON.stringify(window.noname_update.players));
|
|
||||||
}
|
|
||||||
if (window.noname_update.cards) {
|
|
||||||
lib.changeLog.push('cards://' + JSON.stringify(window.noname_update.cards));
|
|
||||||
}
|
|
||||||
delete window.noname_update;
|
|
||||||
}
|
|
||||||
// 确认手机端平台
|
// 确认手机端平台
|
||||||
const noname_inited = localStorage.getItem('noname_inited');
|
const noname_inited = localStorage.getItem('noname_inited');
|
||||||
if (noname_inited && noname_inited !== 'nodejs') {
|
if (noname_inited && noname_inited !== 'nodejs') {
|
||||||
|
@ -498,6 +486,39 @@ export async function boot() {
|
||||||
}
|
}
|
||||||
delete _status.htmlbg;
|
delete _status.htmlbg;
|
||||||
|
|
||||||
|
// 无名杀更新日志
|
||||||
|
if (window.noname_update) {
|
||||||
|
Reflect.set(lib, 'version', window.noname_update.version);
|
||||||
|
// 更全面的更新内容
|
||||||
|
if (config.get(`version_description_v${window.noname_update.version}`)) {
|
||||||
|
try {
|
||||||
|
const description = config.get(`version_description_v${window.noname_update.version}`);
|
||||||
|
const html = String.raw;
|
||||||
|
lib.changeLog.push(
|
||||||
|
html`
|
||||||
|
<div style="position: relative;width:50px;height:50px;border-radius:50px;background-image:url('${description.author.avatar_url}');background-size:cover;vertical-align:middle;"></div>
|
||||||
|
${description.author.login}于${description.published_at}发布
|
||||||
|
`.trim(),
|
||||||
|
description.body.replaceAll('\n', '<br/>')
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
lib.changeLog.push(...window.noname_update.changeLog);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 原更新内容
|
||||||
|
else {
|
||||||
|
lib.changeLog.push(...window.noname_update.changeLog);
|
||||||
|
}
|
||||||
|
if (window.noname_update.players) {
|
||||||
|
lib.changeLog.push('players://' + JSON.stringify(window.noname_update.players));
|
||||||
|
}
|
||||||
|
if (window.noname_update.cards) {
|
||||||
|
lib.changeLog.push('cards://' + JSON.stringify(window.noname_update.cards));
|
||||||
|
}
|
||||||
|
delete window.noname_update;
|
||||||
|
}
|
||||||
|
|
||||||
// 虽然但是,我就暴露个import,应该没啥问题
|
// 虽然但是,我就暴露个import,应该没啥问题
|
||||||
Reflect.set(window, 'game', {
|
Reflect.set(window, 'game', {
|
||||||
import: game.import.bind(null)
|
import: game.import.bind(null)
|
||||||
|
@ -715,6 +736,7 @@ async function loadConfig() {
|
||||||
Reflect.set(lib, 'config', Reflect.get(window, 'config'));
|
Reflect.set(lib, 'config', Reflect.get(window, 'config'));
|
||||||
Reflect.set(lib, 'configOL', {});
|
Reflect.set(lib, 'configOL', {});
|
||||||
Reflect.deleteProperty(window, 'config');
|
Reflect.deleteProperty(window, 'config');
|
||||||
|
|
||||||
let result;
|
let result;
|
||||||
if (localStorage.getItem(`${lib.configprefix}nodb`))
|
if (localStorage.getItem(`${lib.configprefix}nodb`))
|
||||||
Reflect.set(window, 'nodb', true);
|
Reflect.set(window, 'nodb', true);
|
||||||
|
|
|
@ -0,0 +1,418 @@
|
||||||
|
import { ui } from '../../noname.js';
|
||||||
|
|
||||||
|
// https://github.com/libccy/noname/archive/refs/tags/v1.10.10.zip
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HTTP响应头中的Rate Limit相关信息:
|
||||||
|
* X-RateLimit-Limit: 请求总量限制
|
||||||
|
* X-RateLimit-Remaining: 剩余请求次数
|
||||||
|
* X-RateLimit-Reset: 限制重置时间(UTC时间戳)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @type { HeadersInit } */
|
||||||
|
const defaultHeaders = {
|
||||||
|
'Accept': 'application/vnd.github.v3+json',
|
||||||
|
// 根据GitHub API的要求添加适当的认证头信息
|
||||||
|
// 如果公共仓库则无需认证,私有仓库需提供token
|
||||||
|
// 'Authorization': `Bearer ${YOUR_GITHUB_PERSONAL_ACCESS_TOKEN}`
|
||||||
|
};
|
||||||
|
|
||||||
|
const defaultResponse = response => {
|
||||||
|
const limit = response.headers.get("X-RateLimit-Limit");
|
||||||
|
const remaining = response.headers.get("X-RateLimit-Remaining");
|
||||||
|
const reset = response.headers.get("X-RateLimit-Reset");
|
||||||
|
console.log(`请求总量限制`, limit);
|
||||||
|
console.log(`剩余请求次数`, remaining);
|
||||||
|
console.log(`限制重置时间`, (new Date(reset * 1000)).toLocaleString());
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 字节转换
|
||||||
|
* @param { number } limit
|
||||||
|
*/
|
||||||
|
export function parseSize(limit) {
|
||||||
|
let size = "";
|
||||||
|
if (limit < 1 * 1024) {
|
||||||
|
// 小于1KB,则转化成B
|
||||||
|
size = limit.toFixed(2) + "B"
|
||||||
|
} else if (limit < 1 * 1024 * 1024) {
|
||||||
|
// 小于1MB,则转化成KB
|
||||||
|
size = (limit / 1024).toFixed(2) + "KB"
|
||||||
|
} else if (limit < 1 * 1024 * 1024 * 1024) {
|
||||||
|
// 小于1GB,则转化成MB
|
||||||
|
size = (limit / (1024 * 1024)).toFixed(2) + "MB"
|
||||||
|
} else {
|
||||||
|
// 其他转化成GB
|
||||||
|
size = (limit / (1024 * 1024 * 1024)).toFixed(2) + "GB"
|
||||||
|
}
|
||||||
|
|
||||||
|
// 转成字符串
|
||||||
|
let sizeStr = size + "";
|
||||||
|
// 获取小数点处的索引
|
||||||
|
let index = sizeStr.indexOf(".");
|
||||||
|
// 获取小数点后两位的值
|
||||||
|
let dou = sizeStr.slice(index + 1, 2);
|
||||||
|
// 判断后两位是否为00,如果是则删除00
|
||||||
|
if (dou == "00") {
|
||||||
|
return sizeStr.slice(0, index) + sizeStr.slice(index + 3, 2);
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对比版本号
|
||||||
|
* @param { string } ver1
|
||||||
|
* @param { string } ver2
|
||||||
|
* @returns { -1 | 0 | 1 }
|
||||||
|
*/
|
||||||
|
export function checkVersion(ver1, ver2) {
|
||||||
|
if (typeof ver1 !== 'string') ver1 = String(ver1);
|
||||||
|
if (typeof ver2 !== 'string') ver2 = String(ver2);
|
||||||
|
|
||||||
|
// 移除 'v' 开头
|
||||||
|
if (ver1.startsWith('v')) ver1 = ver1.slice(1);
|
||||||
|
if (ver2.startsWith('v')) ver2 = ver2.slice(1);
|
||||||
|
|
||||||
|
// 验证版本号格式
|
||||||
|
if (/[^0-9.-]/i.test(ver1) || /[^0-9.-]/i.test(ver2)) {
|
||||||
|
throw new Error('Invalid characters found in the version numbers');
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param { string } str */
|
||||||
|
function* walk(str) {
|
||||||
|
let part = '';
|
||||||
|
for (const char of str) {
|
||||||
|
if (char === '.' || char === '-') {
|
||||||
|
if (part) yield Number(part);
|
||||||
|
part = '';
|
||||||
|
} else {
|
||||||
|
part += char;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (part) yield Number(part);
|
||||||
|
}
|
||||||
|
|
||||||
|
const iterator1 = walk(ver1);
|
||||||
|
const iterator2 = walk(ver2);
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
const iter1 = iterator1.next();
|
||||||
|
const iter2 = iterator2.next();
|
||||||
|
let { value: item1 } = iter1;
|
||||||
|
let { value: item2 } = iter2;
|
||||||
|
|
||||||
|
// 如果任意一个迭代器已经没有剩余值,将该值视为0
|
||||||
|
item1 = item1 === undefined ? 0 : item1;
|
||||||
|
item2 = item2 === undefined ? 0 : item2;
|
||||||
|
|
||||||
|
if (isNaN(item1) || isNaN(item2)) {
|
||||||
|
throw new Error('Non-numeric part found in the version numbers');
|
||||||
|
} else if (item1 > item2) {
|
||||||
|
return 1;
|
||||||
|
} else if (item1 < item2) {
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
if (iter1.done && iter2.done) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 若正常遍历结束,说明版本号相等
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 获取指定仓库的tags
|
||||||
|
* @param { Object } options
|
||||||
|
* @param { string } [options.username = 'libccy'] 仓库拥有者
|
||||||
|
* @param { string } [options.repository = 'noname'] 仓库名称
|
||||||
|
* @param { string } [options.accessToken] 身份令牌
|
||||||
|
* @returns { Promise<{ commit: { sha: string, url: string }, name: string, node_id: string, tarball_url: string, zipball_url: string }[]> }
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```js
|
||||||
|
* getRepoTags().then(tags => {
|
||||||
|
* console.log("All tags:", tags.map(tag => tag.name));
|
||||||
|
* // 获取最新tag(假设按时间顺序排列,最新tag在数组首位)
|
||||||
|
* const latestTag = tags[0].name;
|
||||||
|
* console.log("Latest tag:", latestTag);
|
||||||
|
* });
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
export async function getRepoTags(options = { username: 'libccy', repository: 'noname' }) {
|
||||||
|
const { username = 'libccy', repository = 'noname', accessToken } = options;
|
||||||
|
const headers = Object.assign({}, defaultHeaders);
|
||||||
|
if (accessToken) {
|
||||||
|
headers['Authorization'] = `token ${accessToken}`;
|
||||||
|
}
|
||||||
|
const url = `https://api.github.com/repos/${username}/${repository}/tags`;
|
||||||
|
const response = await fetch(url, { headers });
|
||||||
|
defaultResponse(response);
|
||||||
|
if (response.ok) {
|
||||||
|
const data = await response.json();
|
||||||
|
return data;
|
||||||
|
} else {
|
||||||
|
throw new Error(`Error fetching tags: ${response.statusText}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指定仓库的指定tags的描述
|
||||||
|
* @param { string } tagName tag名称
|
||||||
|
* @param { Object } options
|
||||||
|
* @param { string } [options.username = 'libccy'] 仓库拥有者
|
||||||
|
* @param { string } [options.repository = 'noname'] 仓库名称
|
||||||
|
* @param { string } [options.accessToken] 身份令牌
|
||||||
|
* @example
|
||||||
|
* ```js
|
||||||
|
* getRepoTagDescription('v1.10.10')
|
||||||
|
* .then(description => console.log(description))
|
||||||
|
* .catch(error => console.error('Failed to fetch description:', error));
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
|
||||||
|
export async function getRepoTagDescription(tagName, options = { username: 'libccy', repository: 'noname' }) {
|
||||||
|
const { username = 'libccy', repository = 'noname', accessToken } = options;
|
||||||
|
const headers = Object.assign({}, defaultHeaders);
|
||||||
|
if (accessToken) {
|
||||||
|
headers['Authorization'] = `token ${accessToken}`;
|
||||||
|
}
|
||||||
|
const apiUrl = `https://api.github.com/repos/${username}/${repository}/releases/tags/${tagName}`;
|
||||||
|
const response = await fetch(apiUrl, { headers });
|
||||||
|
defaultResponse(response);
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`Request failed with status ${response.status}`);
|
||||||
|
}
|
||||||
|
const releaseData = await response.json();
|
||||||
|
// console.log(releaseData);
|
||||||
|
// 从json里拿我们需要的
|
||||||
|
return {
|
||||||
|
/** @type { { browser_download_url: string, content_type: string, name: string, size: number }[] } tag额外上传的素材包 */
|
||||||
|
assets: releaseData.assets,
|
||||||
|
author: {
|
||||||
|
/** @type { string } 用户名 */
|
||||||
|
login: releaseData.author.login,
|
||||||
|
/** @type { string } 用户头像地址 */
|
||||||
|
avatar_url: releaseData.author.avatar_url,
|
||||||
|
/** @type { string } 用户仓库地址 */
|
||||||
|
html_url: releaseData.author.html_url,
|
||||||
|
},
|
||||||
|
/** @type { string } tag描述 */
|
||||||
|
body: releaseData.body,
|
||||||
|
// created_at: (new Date(releaseData.created_at)).toLocaleString(),
|
||||||
|
/** @type { string } tag页面 */
|
||||||
|
html_url: releaseData.html_url,
|
||||||
|
/** @type { string } tag名称 */
|
||||||
|
name: releaseData.name,
|
||||||
|
/** 发布日期 */
|
||||||
|
published_at: (new Date(releaseData.published_at)).toLocaleString(),
|
||||||
|
/** @type { string } 下载地址 */
|
||||||
|
zipball_url: releaseData.zipball_url,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 获取仓库指定分支和指定目录内的所有文件和目录
|
||||||
|
* @param { string } [path = ''] 路径名称(可放参数)
|
||||||
|
* @param { string } [branch = ''] 仓库分支名称
|
||||||
|
* @param { Object } options
|
||||||
|
* @param { string } [options.username = 'libccy'] 仓库拥有者
|
||||||
|
* @param { string } [options.repository = 'noname'] 仓库名称
|
||||||
|
* @param { string } [options.accessToken] 身份令牌
|
||||||
|
* @returns { Promise<{ download_url: string, name: string, path: string, sha: string, size: number, type: 'file' } | { download_url: null, name: string, path: string, sha: string, size: 0, type: 'dir' }> }
|
||||||
|
* @example
|
||||||
|
* ```js
|
||||||
|
* getRepoFilesList()
|
||||||
|
* .then(files => console.log(files))
|
||||||
|
* .catch(error => console.error('Failed to fetch files:', error));
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
export async function getRepoFilesList(path = '', branch, options = { username: 'libccy', repository: 'noname' }) {
|
||||||
|
const { username = 'libccy', repository = 'noname', accessToken } = options;
|
||||||
|
const headers = Object.assign({}, defaultHeaders);
|
||||||
|
if (accessToken) {
|
||||||
|
headers['Authorization'] = `token ${accessToken}`;
|
||||||
|
}
|
||||||
|
let url = `https://api.github.com/repos/${username}/${repository}/contents/${path}`;
|
||||||
|
if (typeof branch == 'string' && branch.length > 0) {
|
||||||
|
const searchParams = new URLSearchParams(new URL(url).search.slice(1));
|
||||||
|
if (searchParams.has('ref')) {
|
||||||
|
throw new TypeError(`设置了branch参数后,不应在path参数内拼接ref`);
|
||||||
|
}
|
||||||
|
searchParams.append('ref', branch);
|
||||||
|
url = searchParams.toString();
|
||||||
|
}
|
||||||
|
const response = await fetch(url, { headers });
|
||||||
|
defaultResponse(response);
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`Request failed with status ${response.status}`);
|
||||||
|
}
|
||||||
|
const data = await response.json();
|
||||||
|
console.log(data);
|
||||||
|
// 处理响应数据,返回文件列表
|
||||||
|
return data.map(({ download_url, name, path, sha, size, type }) => ({
|
||||||
|
download_url,
|
||||||
|
name,
|
||||||
|
path,
|
||||||
|
sha,
|
||||||
|
size,
|
||||||
|
type
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求一个文件而不是直接储存为文件
|
||||||
|
* @param { string } url
|
||||||
|
* @param { (receivedBytes: number, total?:number, filename?: string) => void } [onProgress]
|
||||||
|
* @example
|
||||||
|
* ```js
|
||||||
|
* await getRepoTagDescription('v1.10.10').then(({ zipball_url }) => request(zipball_url));
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
export async function request(url, onProgress) {
|
||||||
|
const response = await fetch(url, {
|
||||||
|
// 告诉服务器我们期望得到范围请求的支持
|
||||||
|
headers: { 'Range': 'bytes=0-' },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`HTTP error! status: ${response.status}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
let total = parseInt(response.headers.get('Content-Length'), 10);
|
||||||
|
// 如果服务器未返回Content-Length,则无法准确计算进度
|
||||||
|
// @ts-ignore
|
||||||
|
if (isNaN(total)) total = null;
|
||||||
|
// @ts-ignore
|
||||||
|
const reader = response.body.getReader();
|
||||||
|
let filename;
|
||||||
|
try {
|
||||||
|
// @ts-ignore
|
||||||
|
filename = response.headers.get('Content-Disposition').split(';')[1].split('=')[1];
|
||||||
|
} catch {}
|
||||||
|
let receivedBytes = 0;
|
||||||
|
let chunks = [];
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
// 使用ReadableStream来获取部分数据并计算进度
|
||||||
|
const { done, value } = await reader.read();
|
||||||
|
|
||||||
|
if (done) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
chunks.push(value);
|
||||||
|
receivedBytes += value.length;
|
||||||
|
|
||||||
|
if (typeof onProgress == 'function') {
|
||||||
|
if (total) {
|
||||||
|
const progress = (receivedBytes / total) * 100;
|
||||||
|
onProgress(receivedBytes, progress, filename);
|
||||||
|
} else {
|
||||||
|
onProgress(receivedBytes, void 0, filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 合并chunks并转换为Blob
|
||||||
|
const blob = new Blob(chunks);
|
||||||
|
|
||||||
|
// 仅做演示,打印已合并的Blob大小
|
||||||
|
console.log(`Download completed. Total size: ${ parseSize(blob.size) }.`);
|
||||||
|
|
||||||
|
return blob;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param { string } [title]
|
||||||
|
* @param { string | number } [max]
|
||||||
|
* @param { string } [fileName]
|
||||||
|
* @param { string | number } [value]
|
||||||
|
* @returns { progress }
|
||||||
|
*/
|
||||||
|
export function createProgress(title, max, fileName, value) {
|
||||||
|
/** @type { progress } */
|
||||||
|
// @ts-ignore
|
||||||
|
const parent = ui.create.div(ui.window, {
|
||||||
|
textAlign: 'center',
|
||||||
|
width: '300px',
|
||||||
|
height: '150px',
|
||||||
|
left: 'calc(50% - 150px)',
|
||||||
|
top: 'auto',
|
||||||
|
bottom: 'calc(50% - 75px)',
|
||||||
|
zIndex: '10',
|
||||||
|
boxShadow: 'rgb(0 0 0 / 40 %) 0 0 0 1px, rgb(0 0 0 / 20 %) 0 3px 10px',
|
||||||
|
backgroundImage: 'linear-gradient(rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0.4))',
|
||||||
|
borderRadius: '8px',
|
||||||
|
overflow: 'hidden scroll'
|
||||||
|
});
|
||||||
|
|
||||||
|
// 可拖动
|
||||||
|
parent.className = 'dialog';
|
||||||
|
|
||||||
|
const container = ui.create.div(parent, {
|
||||||
|
position: 'absolute',
|
||||||
|
top: '0',
|
||||||
|
left: '0',
|
||||||
|
width: '100%',
|
||||||
|
height: '100%'
|
||||||
|
});
|
||||||
|
|
||||||
|
container.ontouchstart = ui.click.dialogtouchStart;
|
||||||
|
container.ontouchmove = ui.click.touchScroll;
|
||||||
|
// @ts-ignore
|
||||||
|
container.style.WebkitOverflowScrolling = 'touch';
|
||||||
|
parent.ontouchstart = ui.click.dragtouchdialog;
|
||||||
|
|
||||||
|
const caption = ui.create.div(container, '', title, {
|
||||||
|
position: 'relative',
|
||||||
|
paddingTop: '8px',
|
||||||
|
fontSize: '20px'
|
||||||
|
});
|
||||||
|
|
||||||
|
ui.create.node('br', container);
|
||||||
|
|
||||||
|
const tip = ui.create.div(container, {
|
||||||
|
position: 'relative',
|
||||||
|
paddingTop: '8px',
|
||||||
|
fontSize: '20px',
|
||||||
|
width: '100%'
|
||||||
|
});
|
||||||
|
|
||||||
|
const file = ui.create.node('span', tip, '', fileName);
|
||||||
|
file.style.width = file.style.maxWidth = '100%';
|
||||||
|
ui.create.node('br', tip);
|
||||||
|
const index = ui.create.node('span', tip, '', String(value || '0'));
|
||||||
|
ui.create.node('span', tip, '', '/');
|
||||||
|
const maxSpan = ui.create.node('span', tip, '', String(max || '未知'));
|
||||||
|
|
||||||
|
ui.create.node('br', container);
|
||||||
|
|
||||||
|
const progress = ui.create.node('progress.progress', container);
|
||||||
|
progress.setAttribute('value', value || '0');
|
||||||
|
progress.setAttribute('max', max);
|
||||||
|
|
||||||
|
parent.getTitle = () => caption.innerText;
|
||||||
|
parent.setTitle = title => caption.innerHTML = title;
|
||||||
|
parent.getFileName = () => file.innerText;
|
||||||
|
parent.setFileName = name => file.innerHTML = name;
|
||||||
|
parent.getProgressValue = () => progress.value;
|
||||||
|
parent.setProgressValue = value => progress.value = index.innerHTML = value;
|
||||||
|
parent.getProgressMax = () => progress.max;
|
||||||
|
parent.setProgressMax = max => progress.max = maxSpan.innerHTML = max;
|
||||||
|
parent.autoSetFileNameFromArray = fileNameList => {
|
||||||
|
if (fileNameList.length > 2) {
|
||||||
|
parent.setFileName(fileNameList.slice(0, 2).concat(`......等${fileNameList.length - 2}个文件`).join('<br/>'));
|
||||||
|
} else if (fileNameList.length == 2) {
|
||||||
|
parent.setFileName(fileNameList.join('<br/>'));
|
||||||
|
} else if (fileNameList.length == 1) {
|
||||||
|
parent.setFileName(fileNameList[0]);
|
||||||
|
} else {
|
||||||
|
parent.setFileName('当前没有正在下载的文件');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return parent;
|
||||||
|
};
|
|
@ -15,8 +15,17 @@ import {
|
||||||
clickMenuItem,
|
clickMenuItem,
|
||||||
createMenu,
|
createMenu,
|
||||||
createConfig
|
createConfig
|
||||||
} from "../index.js";
|
} from '../index.js';
|
||||||
import { ui, game, get, ai, lib, _status } from "../../../../../noname.js";
|
import { ui, game, get, ai, lib, _status } from "../../../../../noname.js";
|
||||||
|
import {
|
||||||
|
parseSize,
|
||||||
|
checkVersion,
|
||||||
|
getRepoTags,
|
||||||
|
getRepoTagDescription,
|
||||||
|
getRepoFilesList,
|
||||||
|
request,
|
||||||
|
createProgress
|
||||||
|
} from "../../../../library/update.js"
|
||||||
|
|
||||||
export const otherMenu = function (connectMenu) {
|
export const otherMenu = function (connectMenu) {
|
||||||
if (connectMenu) return;
|
if (connectMenu) return;
|
||||||
|
@ -108,263 +117,229 @@ export const otherMenu = function (connectMenu) {
|
||||||
var li1 = document.createElement('li');
|
var li1 = document.createElement('li');
|
||||||
var li2 = document.createElement('li');
|
var li2 = document.createElement('li');
|
||||||
var li3 = document.createElement('li');
|
var li3 = document.createElement('li');
|
||||||
const trimURL = url => {
|
// const trimURL = url => {
|
||||||
const updateURLS = lib.updateURLS;
|
// const updateURLS = lib.updateURLS;
|
||||||
for (const key in updateURLS) {
|
// for (const key in updateURLS) {
|
||||||
const updateURL = updateURLS[key];
|
// const updateURL = updateURLS[key];
|
||||||
if (url == updateURL) return lib.configMenu.general.config.update_link.item[key];
|
// if (url == updateURL) return lib.configMenu.general.config.update_link.item[key];
|
||||||
}
|
// }
|
||||||
let index = url.indexOf('://');
|
// let index = url.indexOf('://');
|
||||||
if (index != -1) url = url.slice(index + 3);
|
// if (index != -1) url = url.slice(index + 3);
|
||||||
index = url.indexOf('/');
|
// index = url.indexOf('/');
|
||||||
if (index != -1) url = url.slice(0, index);
|
// if (index != -1) url = url.slice(0, index);
|
||||||
if (url.length > 15) {
|
// if (url.length > 15) {
|
||||||
const list = url.split('.');
|
// const list = url.split('.');
|
||||||
if (list.length > 1) list.shift();
|
// if (list.length > 1) list.shift();
|
||||||
url = list.join('.');
|
// url = list.join('.');
|
||||||
}
|
// }
|
||||||
if (url.length > 15) {
|
// if (url.length > 15) {
|
||||||
const list = url.split('.');
|
// const list = url.split('.');
|
||||||
if (list.length > 1) list.pop();
|
// if (list.length > 1) list.pop();
|
||||||
url = list.join('.');
|
// url = list.join('.');
|
||||||
}
|
// }
|
||||||
return url;
|
// return url;
|
||||||
};
|
// };
|
||||||
li1.innerHTML = '游戏版本:' + lib.version + '<p style="margin-top:8px;white-space:nowrap"></p>';
|
li1.innerHTML = '游戏版本:' + lib.version + '<p style="margin-top:8px;white-space:nowrap"></p>';
|
||||||
li2.innerHTML = '素材版本:' + (lib.config.asset_version || '无') + '<p style="margin-top:8px"></p>';
|
li2.innerHTML = '素材版本:' + (lib.config.asset_version || '无') + '<p style="margin-top:8px"></p>';
|
||||||
li3.innerHTML = '更新地址:<span>' + trimURL(lib.config.updateURL || lib.updateURL) + '</span><p style="margin-top:8px"></p>';
|
// li3.innerHTML = '更新地址:<span>' + trimURL(lib.config.updateURL || lib.updateURL) + '</span><p style="margin-top:8px"></p>';
|
||||||
li3.style.whiteSpace = 'nowrap';
|
li3.style.whiteSpace = 'nowrap';
|
||||||
li3.style.display = 'none';// coding
|
li3.style.display = 'none';// coding
|
||||||
|
|
||||||
var button1, button2, button3, button4, button5;
|
var checkVersionButton, checkAssetButton, checkDevVersionButton/*, button4, button5*/;
|
||||||
|
|
||||||
game.checkForUpdate = function (forcecheck, dev) {
|
game.checkForUpdate = async function (forcecheck, dev) {
|
||||||
if (!dev && button1.disabled) {
|
if (!dev && checkVersionButton.disabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (dev && button3.disabled) {
|
else if (dev && checkDevVersionButton.disabled) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (!game.download) {
|
|
||||||
alert('此版本不支持游戏内更新,请手动更新');
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (dev) {
|
if (dev) {
|
||||||
button3.innerHTML = '正在检查更新';
|
checkDevVersionButton.innerHTML = '正在检查更新';
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
button1.innerHTML = '正在检查更新';
|
checkVersionButton.innerHTML = '正在检查更新';
|
||||||
}
|
|
||||||
button3.disabled = true;
|
|
||||||
button1.disabled = true;
|
|
||||||
|
|
||||||
var goupdate = function (files, update) {
|
|
||||||
lib.version = update.version;
|
|
||||||
if (update.dev && !lib.config.debug) {
|
|
||||||
dev = 'nodev';
|
|
||||||
}
|
|
||||||
lib.init.req('game/source.js', function () {
|
|
||||||
try {
|
|
||||||
eval(this.responseText);
|
|
||||||
if (!window.noname_source_list) {
|
|
||||||
throw ('err');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
alert('更新地址有误');
|
|
||||||
console.log(e);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var updates = window.noname_source_list;
|
checkDevVersionButton.disabled = true;
|
||||||
delete window.noname_source_list;
|
checkVersionButton.disabled = true;
|
||||||
if (Array.isArray(files)) {
|
|
||||||
files.add('game/update.js');
|
function refresh() {
|
||||||
var files2 = [];
|
checkVersionButton.disabled = false;
|
||||||
for (var i = 0; i < files.length; i++) {
|
checkVersionButton.innerHTML = '检查游戏更新';
|
||||||
var str = files[i].indexOf('*');
|
checkDevVersionButton.disabled = false;
|
||||||
if (str != -1) {
|
checkDevVersionButton.innerHTML = '更新到开发版';
|
||||||
str = files[i].slice(0, str);
|
|
||||||
files.splice(i--, 1);
|
|
||||||
for (var j = 0; j < updates.length; j++) {
|
|
||||||
if (updates[j].startsWith(str)) {
|
|
||||||
files2.push(updates[j]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
updates = files.concat(files2);
|
|
||||||
}
|
|
||||||
for (var i = 0; i < updates.length; i++) {
|
|
||||||
if (updates[i].startsWith('theme/') && !updates[i].includes('.css')) {
|
|
||||||
updates.splice(i--, 1);
|
|
||||||
}
|
|
||||||
else if (updates[i].startsWith('node_modules/') && !update.node) {
|
|
||||||
updates.splice(i--, 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ui.arena.classList.contains('menupaused')) {
|
|
||||||
ui.click.configMenu();
|
|
||||||
ui.click.menuTab('其它');
|
|
||||||
}
|
|
||||||
var p = button1.parentNode;
|
|
||||||
button1.remove();
|
|
||||||
button3.remove();
|
|
||||||
var span = document.createElement('span');
|
|
||||||
var n1 = 0;
|
|
||||||
var n2 = updates.length;
|
|
||||||
span.innerHTML = '正在下载文件(' + n1 + '/' + n2 + ')';
|
|
||||||
p.appendChild(span);
|
|
||||||
var finish = function () {
|
|
||||||
span.innerHTML = '游戏更新完毕(' + n1 + '/' + n2 + ')';
|
|
||||||
p.appendChild(document.createElement('br'));
|
|
||||||
var button = document.createElement('button');
|
|
||||||
button.innerHTML = '重新启动';
|
|
||||||
button.onclick = game.reload;
|
|
||||||
button.style.marginTop = '8px';
|
|
||||||
p.appendChild(button);
|
|
||||||
};
|
|
||||||
game.multiDownload(updates, function () {
|
|
||||||
n1++;
|
|
||||||
span.innerHTML = '正在下载文件(' + n1 + '/' + n2 + ')';
|
|
||||||
}, function (e) {
|
|
||||||
game.print('下载失败:' + e.source);
|
|
||||||
}, function () {
|
|
||||||
setTimeout(finish, 500);
|
|
||||||
}, null, dev);
|
|
||||||
}, function () {
|
|
||||||
alert('更新地址有误');
|
|
||||||
}, true);
|
|
||||||
};
|
|
||||||
|
|
||||||
lib.init.req('game/update.js', function () {
|
|
||||||
try {
|
|
||||||
eval(this.responseText);
|
|
||||||
if (!window.noname_update) {
|
|
||||||
throw ('err');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
alert('更新地址有误');
|
|
||||||
console.log(e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var update = window.noname_update;
|
|
||||||
delete window.noname_update;
|
|
||||||
if (forcecheck === false) {
|
|
||||||
if (update.version == lib.config.check_version) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
game.saveConfig('check_version', update.version);
|
|
||||||
var goon = true;
|
|
||||||
if (!dev) {
|
if (!dev) {
|
||||||
if (update.version.includes('beta') || update.version == lib.version) {
|
getRepoTags()
|
||||||
goon = false;
|
.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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (goon) {
|
const str = versionResult > 0 ? (`有新版本${description.name}可用,是否下载?`) : (`本地版本${ lib.version }高于或等于github版本${description.name},是否强制下载?`);
|
||||||
var files = null;
|
const str2 = description.body;
|
||||||
var version = lib.version;
|
|
||||||
if (Array.isArray(update.dev) && dev) {
|
|
||||||
files = update.dev;
|
|
||||||
}
|
|
||||||
else if (Array.isArray(update.files) && update.update && !dev) {
|
|
||||||
var version1 = version.split('.');
|
|
||||||
var version2 = update.update.split('.');
|
|
||||||
for (var i = 0; i < version1.length && i < version2.length; i++) {
|
|
||||||
if (version2[i] > version1[i]) {
|
|
||||||
files = false; break;
|
|
||||||
}
|
|
||||||
else if (version1[i] > version2[i]) {
|
|
||||||
files = update.files.slice(0); break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (files === null) {
|
|
||||||
if (version1.length >= version2.length) {
|
|
||||||
files = update.files.slice(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var str;
|
|
||||||
if (dev) {
|
|
||||||
str = '开发版仅供测试使用,可能存在风险,是否确定更新?';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
str = '有新版本' + update.version + '可用,是否下载?';
|
|
||||||
}
|
|
||||||
if (navigator.notification && navigator.notification.confirm) {
|
if (navigator.notification && navigator.notification.confirm) {
|
||||||
var str2;
|
|
||||||
if (dev) {
|
|
||||||
str2 = str;
|
|
||||||
str = '更新到开发版';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
str2 = update.changeLog[0];
|
|
||||||
for (var i = 1; i < update.changeLog.length; i++) {
|
|
||||||
if (update.changeLog[i].indexOf('://') == -1) {
|
|
||||||
str2 += ';' + update.changeLog[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
navigator.notification.confirm(
|
navigator.notification.confirm(
|
||||||
str2,
|
str2,
|
||||||
function (index) {
|
function (index) {
|
||||||
if (index == 1) {
|
if (index == 1) {
|
||||||
goupdate(files, update);
|
download(description);
|
||||||
}
|
|
||||||
else {
|
|
||||||
button1.disabled = false;
|
|
||||||
button1.innerHTML = '检查游戏更新';
|
|
||||||
button3.disabled = false;
|
|
||||||
button3.innerHTML = '更新到开发版';
|
|
||||||
}
|
}
|
||||||
|
else refresh();
|
||||||
},
|
},
|
||||||
str,
|
str,
|
||||||
['确定', '取消']
|
['确定', '取消']
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (confirm(str)) {
|
if (confirm(str + '\n' + str2)) {
|
||||||
goupdate(files, update);
|
download(description);
|
||||||
}
|
}
|
||||||
else {
|
else refresh();
|
||||||
button1.disabled = false;
|
}
|
||||||
button1.innerHTML = '检查游戏更新';
|
})
|
||||||
button3.disabled = false;
|
.catch(e => {
|
||||||
button3.innerHTML = '更新到开发版';
|
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'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
function download(description) {
|
||||||
|
const progress = createProgress('正在更新' + description.name, 1, description.name + '.zip');
|
||||||
|
let unZipProgress;
|
||||||
|
let url = description.zipball_url;
|
||||||
|
if (Array.isArray(description.assets) && description.assets.length > 0) {
|
||||||
|
const coreZipData = description.assets.find(v => v.name == 'noname.core.zip');
|
||||||
|
if (coreZipData && confirm(`检测到该版本(${description.name})有离线包资源,是否改为下载离线包资源?否则将下载完整包资源`)) {
|
||||||
|
url = 'https://ghproxy.cc/' + coreZipData.browser_download_url;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
alert('当前版本已是最新');
|
|
||||||
button1.disabled = false;
|
|
||||||
button1.innerHTML = '检查游戏更新';
|
|
||||||
button3.disabled = false;
|
|
||||||
button3.innerHTML = '更新到开发版';
|
|
||||||
}
|
}
|
||||||
}, function () {
|
request(url, (receivedBytes, total, filename) => {
|
||||||
if (forcecheck === false) {
|
if (typeof filename == 'string') {
|
||||||
return;
|
progress.setFileName(filename);
|
||||||
|
}
|
||||||
|
let received = 0, max = 0;
|
||||||
|
if (total) {
|
||||||
|
max = +(total / (1024 * 1024)).toFixed(1)
|
||||||
|
} else {
|
||||||
|
max = 1000;
|
||||||
|
}
|
||||||
|
received = +(receivedBytes / (1024 * 1024)).toFixed(1);
|
||||||
|
if (received > max) max = received;
|
||||||
|
progress.setProgressMax(max);
|
||||||
|
progress.setProgressValue(received);
|
||||||
|
}).then(async blob => {
|
||||||
|
progress.remove();
|
||||||
|
await import('../../../../../game/jszip.js');
|
||||||
|
const zip = new window.JSZip().load(await blob.arrayBuffer());
|
||||||
|
const entries = Object.entries(zip.files);
|
||||||
|
let root;
|
||||||
|
const hiddenFileFlags = ['.', '_'];
|
||||||
|
unZipProgress = createProgress('正在解压' + progress.getFileName(), entries.length);
|
||||||
|
let i = 0;
|
||||||
|
for (const [key, value] of entries) {
|
||||||
|
// 第一个是文件夹的话,就是根文件夹
|
||||||
|
if (i == 0 && value.dir && !description.name.includes('noname.core.zip')) {
|
||||||
|
root = key;
|
||||||
|
}
|
||||||
|
unZipProgress.setProgressValue(i++);
|
||||||
|
const fileName = typeof root == 'string' && key.startsWith(root) ? key.replace(root, '') : key;
|
||||||
|
if (hiddenFileFlags.includes(fileName[0])) continue;
|
||||||
|
if (value.dir) {
|
||||||
|
await game.promises.createDir(fileName);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
unZipProgress.setFileName(fileName);
|
||||||
|
const [path, name] = [fileName.split('/').slice(0, -1).join('/'), fileName.split('/').slice(-1).join('/')];
|
||||||
|
game.print(`${fileName}(${i}/${entries.length})`);
|
||||||
|
await game.promises.writeFile(value.asArrayBuffer(), path, name)
|
||||||
|
.catch(async e => {
|
||||||
|
// 特殊处理
|
||||||
|
if (name == 'noname-server.exe' && e.message.includes('resource busy or locked') && location.protocol.startsWith('http')) {
|
||||||
|
if (typeof window.require == 'function' &&
|
||||||
|
typeof window.process == 'object' &&
|
||||||
|
typeof window.__dirname == 'string') {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const cp = require('child_process');
|
||||||
|
cp.exec(`taskkill /IM noname-server.exe /F`, e => {
|
||||||
|
if (e) reject(e);
|
||||||
|
else game.promises.writeFile(value.asArrayBuffer(), path, name).then(() => {
|
||||||
|
cp.exec(`start /b ${__dirname}\\noname-server.exe -platform=electron`, () => { });
|
||||||
|
function loadURL() {
|
||||||
|
let myAbortController = new AbortController();;
|
||||||
|
let signal = myAbortController.signal;
|
||||||
|
setTimeout(() => myAbortController.abort(), 2000);
|
||||||
|
fetch(`http://localhost:8089/app.html`, { signal })
|
||||||
|
.then(({ ok }) => {
|
||||||
|
if (ok) resolve(null);
|
||||||
|
else throw new Error('fetch加载失败');
|
||||||
|
})
|
||||||
|
.catch(() => loadURL());
|
||||||
|
}
|
||||||
|
loadURL();
|
||||||
|
}).catch(reject);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else throw e;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
unZipProgress.remove();
|
||||||
|
// await import('../../../../../game/update.js');
|
||||||
|
// if (Array.isArray(window.noname_asset_list)) {
|
||||||
|
// game.saveConfig('asset_version', window.noname_asset_list[0]);
|
||||||
|
// delete window.noname_asset_list;
|
||||||
|
// }
|
||||||
|
if (confirm('更新完成,是否重启?')) {
|
||||||
|
game.reload();
|
||||||
|
}
|
||||||
|
refresh();
|
||||||
|
}).catch(e => {
|
||||||
|
if (progress.parentNode) progress.remove();
|
||||||
|
if (unZipProgress && unZipProgress.parentNode) unZipProgress.remove();
|
||||||
|
refresh();
|
||||||
|
throw e;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
alert('连接失败');
|
|
||||||
button1.disabled = false;
|
|
||||||
button1.innerHTML = '检查游戏更新';
|
|
||||||
button3.disabled = false;
|
|
||||||
button3.innerHTML = '更新到开发版';
|
|
||||||
}, true);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
game.checkForAssetUpdate = function (type) {
|
game.checkForAssetUpdate = function (type) {
|
||||||
if (button2.disabled) {
|
return alert('暂不支持更新素材,请点击检查游戏更新按钮下载完整包');
|
||||||
|
if (checkAssetButton.disabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (game.download) {
|
else if (game.download) {
|
||||||
button2.innerHTML = '正在检查更新';
|
checkAssetButton.innerHTML = '正在检查更新';
|
||||||
button2.disabled = true;
|
checkAssetButton.disabled = true;
|
||||||
lib.init.req('game/asset.js', function () {
|
lib.init.req('game/asset.js', function () {
|
||||||
try {
|
try {
|
||||||
eval(this.responseText);
|
eval(this.responseText);
|
||||||
|
@ -455,12 +430,12 @@ export const otherMenu = function (connectMenu) {
|
||||||
game.print(updates);
|
game.print(updates);
|
||||||
game.saveConfig('asset_version', asset_version);
|
game.saveConfig('asset_version', asset_version);
|
||||||
alert('素材已是最新');
|
alert('素材已是最新');
|
||||||
button2.disabled = false;
|
checkAssetButton.disabled = false;
|
||||||
button2.innerHTML = '检查素材更新';
|
checkAssetButton.innerHTML = '检查素材更新';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var p = button2.parentNode;
|
var p = checkAssetButton.parentNode;
|
||||||
button2.remove();
|
checkAssetButton.remove();
|
||||||
var span = document.createElement('span');
|
var span = document.createElement('span');
|
||||||
span.style.whiteSpace = 'nowrap';
|
span.style.whiteSpace = 'nowrap';
|
||||||
var n1 = 0;
|
var n1 = 0;
|
||||||
|
@ -515,8 +490,8 @@ export const otherMenu = function (connectMenu) {
|
||||||
game.checkFileList(updates, proceed);
|
game.checkFileList(updates, proceed);
|
||||||
}, function () {
|
}, function () {
|
||||||
alert('连接失败');
|
alert('连接失败');
|
||||||
button2.disabled = false;
|
checkAssetButton.disabled = false;
|
||||||
button2.innerHTML = '检查素材更新';
|
checkAssetButton.innerHTML = '检查素材更新';
|
||||||
}, true);
|
}, true);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -524,19 +499,19 @@ export const otherMenu = function (connectMenu) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
button1 = document.createElement('button');
|
checkVersionButton = document.createElement('button');
|
||||||
button1.innerHTML = '检查游戏更新';
|
checkVersionButton.innerHTML = '检查游戏更新';
|
||||||
button1.onclick = game.checkForUpdate;
|
checkVersionButton.onclick = game.checkForUpdate;
|
||||||
li1.lastChild.appendChild(button1);
|
li1.lastChild.appendChild(checkVersionButton);
|
||||||
|
|
||||||
button3 = document.createElement('button');
|
checkDevVersionButton = document.createElement('button');
|
||||||
button3.innerHTML = '更新到开发版';
|
checkDevVersionButton.innerHTML = '更新到开发版';
|
||||||
button3.style.marginLeft = '5px';
|
checkDevVersionButton.style.marginLeft = '5px';
|
||||||
button3.onclick = function () {
|
checkDevVersionButton.onclick = function () {
|
||||||
game.checkForUpdate(null, true);
|
game.checkForUpdate(null, true);
|
||||||
};
|
};
|
||||||
// if(lib.config.dev){
|
// if(lib.config.dev){
|
||||||
// li1.lastChild.appendChild(button3);
|
// li1.lastChild.appendChild(checkDevVersionButton);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
(function () {
|
(function () {
|
||||||
|
@ -572,53 +547,53 @@ export const otherMenu = function (connectMenu) {
|
||||||
ui.updateUpdate();
|
ui.updateUpdate();
|
||||||
}());
|
}());
|
||||||
|
|
||||||
button4 = document.createElement('button');
|
// button4 = document.createElement('button');
|
||||||
button4.innerHTML = '设置更新地址';
|
// button4.innerHTML = '设置更新地址';
|
||||||
button4.onclick = function () {
|
// button4.onclick = function () {
|
||||||
game.prompt('设置更新地址', function (str) {
|
// game.prompt('设置更新地址', function (str) {
|
||||||
if (str) {
|
// if (str) {
|
||||||
game.saveConfig('updateURL', str);
|
// game.saveConfig('updateURL', str);
|
||||||
li3.querySelector('span').innerHTML = trimURL(str);
|
// li3.querySelector('span').innerHTML = trimURL(str);
|
||||||
button5.style.display = '';
|
// button5.style.display = '';
|
||||||
button6.style.display = 'none';
|
// button6.style.display = 'none';
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
};
|
// };
|
||||||
// li3.lastChild.appendChild(button4);
|
// li3.lastChild.appendChild(button4);
|
||||||
|
|
||||||
var button6 = document.createElement('button');
|
// var button6 = document.createElement('button');
|
||||||
button6.innerHTML = '设为备用镜像';
|
// button6.innerHTML = '设为备用镜像';
|
||||||
button6.style.display = 'none';// coding
|
// button6.style.display = 'none';// coding
|
||||||
// button6.style.marginLeft='5px';
|
// button6.style.marginLeft='5px';
|
||||||
button6.onclick = function () {
|
// button6.onclick = function () {
|
||||||
game.saveConfig('updateURL', lib.mirrorURL);
|
// game.saveConfig('updateURL', lib.mirrorURL);
|
||||||
button5.style.display = '';
|
// // button5.style.display = '';
|
||||||
button6.style.display = 'none';
|
// button6.style.display = 'none';
|
||||||
li3.querySelector('span').innerHTML = trimURL(lib.mirrorURL);
|
// li3.querySelector('span').innerHTML = trimURL(lib.mirrorURL);
|
||||||
};
|
// };
|
||||||
li3.lastChild.appendChild(button6);
|
// li3.lastChild.appendChild(button6);
|
||||||
|
|
||||||
button5 = document.createElement('button');
|
// button5 = document.createElement('button');
|
||||||
button5.innerHTML = '设为默认镜像';
|
// button5.innerHTML = '设为默认镜像';
|
||||||
// button5.style.marginLeft='5px';
|
// button5.style.marginLeft='5px';
|
||||||
button5.onclick = function () {
|
// button5.onclick = function () {
|
||||||
game.saveConfig('updateURL');
|
// game.saveConfig('updateURL');
|
||||||
button5.style.display = 'none';
|
// button5.style.display = 'none';
|
||||||
button6.style.display = '';
|
// button6.style.display = '';
|
||||||
li3.querySelector('span').innerHTML = trimURL(lib.updateURL);
|
// li3.querySelector('span').innerHTML = trimURL(lib.updateURL);
|
||||||
};
|
// };
|
||||||
li3.lastChild.appendChild(button5);
|
// li3.lastChild.appendChild(button5);
|
||||||
if (!lib.config.updateURL) {
|
// if (!lib.config.updateURL) {
|
||||||
button5.style.display = 'none';
|
// button5.style.display = 'none';
|
||||||
}
|
// }
|
||||||
else {
|
// else {
|
||||||
button6.style.display = 'none';
|
// button6.style.display = 'none';
|
||||||
}
|
// }
|
||||||
|
|
||||||
button2 = document.createElement('button');
|
checkAssetButton = document.createElement('button');
|
||||||
button2.innerHTML = '检查素材更新';
|
checkAssetButton.innerHTML = '检查素材更新';
|
||||||
button2.onclick = game.checkForAssetUpdate;
|
checkAssetButton.onclick = game.checkForAssetUpdate;
|
||||||
li2.lastChild.appendChild(button2);
|
li2.lastChild.appendChild(checkAssetButton);
|
||||||
|
|
||||||
var span1 = ui.create.div('.config.more', '选项 <div>></div>');
|
var span1 = ui.create.div('.config.more', '选项 <div>></div>');
|
||||||
span1.style.fontSize = 'small';
|
span1.style.fontSize = 'small';
|
||||||
|
@ -626,39 +601,27 @@ export const otherMenu = function (connectMenu) {
|
||||||
span1.toggle = function () {
|
span1.toggle = function () {
|
||||||
if (!this.classList.toggle('on')) {
|
if (!this.classList.toggle('on')) {
|
||||||
game.saveConfig('asset_toggle_off', true);
|
game.saveConfig('asset_toggle_off', true);
|
||||||
span2.style.display = 'none';
|
[
|
||||||
span2_br.style.display = 'none';
|
span2, span2_br, span2_check,
|
||||||
span2_check.style.display = 'none';
|
span3, span3_br, span3_check,
|
||||||
span3.style.display = 'none';
|
span4, span4_br, span4_check,
|
||||||
span3_br.style.display = 'none';
|
span5, span5_br, span5_check,
|
||||||
span3_check.style.display = 'none';
|
span6, span6_br, span6_check,
|
||||||
span4.style.display = 'none';
|
].forEach(item => HTMLDivElement.prototype.css.call(item, {
|
||||||
span4_br.style.display = 'none';
|
display: 'none'
|
||||||
span4_check.style.display = 'none';
|
}));
|
||||||
span5.style.display = 'none';
|
|
||||||
span5_br.style.display = 'none';
|
|
||||||
span5_check.style.display = 'none';
|
|
||||||
span6.style.display = 'none';
|
|
||||||
span6_br.style.display = 'none';
|
|
||||||
span6_check.style.display = 'none';
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
game.saveConfig('asset_toggle_off');
|
game.saveConfig('asset_toggle_off');
|
||||||
span2.style.display = '';
|
[
|
||||||
span2_br.style.display = '';
|
span2, span2_br, span2_check,
|
||||||
span2_check.style.display = '';
|
span3, span3_br, span3_check,
|
||||||
span3.style.display = '';
|
span4, span4_br, span4_check,
|
||||||
span3_br.style.display = '';
|
span5, span5_br, span5_check,
|
||||||
span3_check.style.display = '';
|
span6, span6_br, span6_check,
|
||||||
span4.style.display = '';
|
].forEach(item => HTMLDivElement.prototype.css.call(item, {
|
||||||
span4_br.style.display = '';
|
display: ''
|
||||||
span4_check.style.display = '';
|
}));
|
||||||
span5.style.display = '';
|
|
||||||
span5_br.style.display = '';
|
|
||||||
span5_check.style.display = '';
|
|
||||||
span6.style.display = '';
|
|
||||||
span6_br.style.display = '';
|
|
||||||
span6_check.style.display = '';
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
span1.listen(span1.toggle);
|
span1.listen(span1.toggle);
|
||||||
|
@ -752,21 +715,15 @@ export const otherMenu = function (connectMenu) {
|
||||||
};
|
};
|
||||||
li2.lastChild.appendChild(span6_check);
|
li2.lastChild.appendChild(span6_check);
|
||||||
|
|
||||||
span2.style.display = 'none';
|
[
|
||||||
span2_br.style.display = 'none';
|
span2, span2_br, span2_check,
|
||||||
span2_check.style.display = 'none';
|
span3, span3_br, span3_check,
|
||||||
span3.style.display = 'none';
|
span4, span4_br, span4_check,
|
||||||
span3_br.style.display = 'none';
|
span5, span5_br, span5_check,
|
||||||
span3_check.style.display = 'none';
|
span6, span6_br, span6_check,
|
||||||
span4.style.display = 'none';
|
].forEach(item => HTMLDivElement.prototype.css.call(item, {
|
||||||
span4_br.style.display = 'none';
|
display: 'none'
|
||||||
span4_check.style.display = 'none';
|
}));
|
||||||
span5.style.display = 'none';
|
|
||||||
span5_br.style.display = 'none';
|
|
||||||
span5_check.style.display = 'none';
|
|
||||||
span6.style.display = 'none';
|
|
||||||
span6_br.style.display = 'none';
|
|
||||||
span6_check.style.display = 'none';
|
|
||||||
|
|
||||||
ul.appendChild(li1);
|
ul.appendChild(li1);
|
||||||
ul.appendChild(li2);
|
ul.appendChild(li2);
|
||||||
|
|
Loading…
Reference in New Issue