Merge pull request #957 from nonameShijian/PR-Branch

在index.html添加promise错误的捕获, 优化file协议升级到http后弹窗的显示,第一次启动不升级协议
This commit is contained in:
Spmario233 2024-02-16 18:07:45 +08:00 committed by GitHub
commit c531642469
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 119 additions and 33 deletions

View File

@ -62,9 +62,7 @@ boot().then(() => {
const thisWindow = remote.getCurrentWindow();
thisWindow.loadURL(url);
} else {
setTimeout(() => {
location.href = url;
}, 1000);
location.href = url;
}
}
}

View File

@ -43,14 +43,27 @@ new Promise(resolve => {
}
};
// 这个弹窗在升级到http协议下的客户端不应该进行提示。
if (!localStorage.getItem('gplv3_noname_alerted')) {
if (confirm('①无名杀是一款基于GPLv3协议的开源软件\n你可以在遵守GPLv3协议的基础上任意使用修改并转发《无名杀》以及所有基于《无名杀》开发的拓展。\n点击“确定”即代表您认可并接受GPLv3协议↓\nhttps://www.gnu.org/licenses/gpl-3.0.html\n②无名杀官方发布地址仅有GitHub仓库\n其他所有的所谓“无名杀”社群包括但不限于绝大多数“官方”QQ群、QQ频道等均为玩家自发组织与无名杀官方无关')) {
// @ts-ignore
localStorage.setItem('gplv3_noname_alerted', true);
}
else {
exit();
}
const nonameInitialized = localStorage.getItem('noname_inited');
const callback = () => {
if (confirm('①无名杀是一款基于GPLv3协议的开源软件\n你可以在遵守GPLv3协议的基础上任意使用修改并转发《无名杀》以及所有基于《无名杀》开发的拓展。\n点击“确定”即代表您认可并接受GPLv3协议↓\nhttps://www.gnu.org/licenses/gpl-3.0.html\n②无名杀官方发布地址仅有GitHub仓库\n其他所有的所谓“无名杀”社群包括但不限于绝大多数“官方”QQ群、QQ频道等均为玩家自发组织与无名杀官方无关')) {
// @ts-ignore
localStorage.setItem('gplv3_noname_alerted', true);
}
else {
exit();
}
};
if (location.protocol.startsWith('http')) {
if (!nonameInitialized || nonameInitialized.length == 0) {
callback();
} else {
// @ts-ignore
localStorage.setItem('gplv3_noname_alerted', true);
}
} else callback();
}
window['b' + 'ann' + 'e' + 'dE' + 'x' + 'ten' + 's' + 'i' + 'o' + 'ns'] = ['\u4fa0\u4e49', '\u5168\u6559\u7a0b'];
@ -86,11 +99,15 @@ new Promise(resolve => {
if (core in supportMap && supportMap[core].some((current, index) => current > versions[index])) {
const tip = '检测到您的浏览器内核版本无法支持当前无名杀所需的功能请立即升级浏览器或手机webview内核';
console.error(tip);
const redirect_tip = `您使用的浏览器或无名杀客户端内核版本过低,已经无法正常运行无名杀!\n目前使用的浏览器UA信息为\n${userAgent}\n点击“确认”以前往GitHub下载最新版无名杀客户端可能需要科学上网\n稍后您的无名杀将自动退出(可能的话)`;
if (confirm(redirect_tip)) {
window.open('https://github.com/libccy/noname/releases/tag/chromium77-client');
let redirect_tip = `您使用的浏览器或无名杀客户端内核版本过低,已经无法正常运行无名杀!\n目前使用的浏览器UA信息为\n${userAgent}\n点击“确认”以前往GitHub下载最新版无名杀客户端可能需要科学上网\n稍后您的无名杀将自动退出(可能的话)`;
if (core === 'safari') {
alert(`您使用的safari浏览器无法支持当前无名杀所需的功能请至少升级至14.5.0\n稍后您的无名杀将自动退出(可能的话)`);
} else {
if (confirm(redirect_tip)) {
window.open('https://github.com/libccy/noname/releases/tag/chromium77-client');
}
}
exit()
exit();
}
else {
// node环境下
@ -144,12 +161,9 @@ new Promise(resolve => {
if (location.protocol.startsWith('http') && 'serviceWorker' in navigator) {
let scope = window.location.protocol + '//' + window.location.host + '/';
navigator.serviceWorker.getRegistrations().then(registrations => {
let findServiceWorker = false;
for (let registration of registrations) {
if (registration && registration.active && registration.active.scriptURL == `${scope}service-worker.js`) {
findServiceWorker = true;
}
}
let findServiceWorker = registrations.find(registration => {
return registration && registration.active && registration.active.scriptURL == `${scope}service-worker.js`;
})
navigator.serviceWorker.register(`${scope}service-worker.js`, {
updateViaCache: "all",
scope,
@ -172,7 +186,7 @@ new Promise(resolve => {
script.async = true;
script.onerror = event => {
console.error(event);
const message = `您使用的浏览器或《无名杀》客户端加载内容失败!\n目前使用的浏览器UA信息为\n${userAgent}\n若您使用的客户端为自带内核的旧版“兼容版”,请及时更新客户端版本!\n若您使用的客户端为手机端的非兼容版《无名杀》请尝试更新手机的WebView内核或者更换为1.8.2版本及以上的兼容版!\n若您是直接使用浏览器加载index.html进行游戏请改为运行文件夹内的“noname-server.exe”或使用VSCode等工具启动Live Server以动态服务器的方式启动《无名杀》`;
const message = `您使用的浏览器或《无名杀》客户端加载内容失败!\n请检查是否缺少游戏文件!隔版本更新请下载完整包而不是离线包!\n目前使用的浏览器UA信息为\n${userAgent}\n若您使用的客户端为自带内核的旧版“兼容版”,请及时更新客户端版本!\n若您使用的客户端为手机端的非兼容版《无名杀》请尝试更新手机的WebView内核或者更换为1.8.2版本及以上的兼容版!\n若您是直接使用浏览器加载index.html进行游戏请改为运行文件夹内的“noname-server.exe”或使用VSCode等工具启动Live Server以动态服务器的方式启动《无名杀》\n若您使用的是苹果端请至少将Safari升级至14.5.0`;
console.error(message);
alert(message);
exit();

View File

@ -1,4 +1,5 @@
<!DOCTYPE HTML>
<head>
<meta charset="UTF-8">
<meta name="format-detection" content="telephone=no">
@ -6,19 +7,90 @@
<meta name="viewport" content="user-scalable=no, viewport-fit=cover">
<title>无名杀</title>
<script>
window.onerror = function (msg, src, line, column, err) {
let str = `错误文件: ${typeof src == 'string' && src.length > 0 ? decodeURI(src) : '未知文件'}`;
str += `\n错误信息: ${msg}`;
str += `\n行号: ${line}`;
str += `\n列号: ${column}`;
if (err && err.stack) str += '\n' + decodeURI(err.stack);
console.error(str);
alert(str);
};
(() => {
window.onerror = function (msg, src, line, column, err) {
let str = `错误文件: ${typeof src == 'string' && src.length > 0 ? decodeURI(src) : '未知文件'}`;
str += `\n错误信息: ${msg}`;
str += `\n行号: ${line}`;
str += `\n列号: ${column}`;
if (err && err.stack) str += '\n' + decodeURI(err.stack);
console.error(str);
alert(str);
};
const STACK_REGEXP = /^\s*at .*(\S+:\d+|\(native\))/m;
const errorList = [];
window.onunhandledrejection = async event => {
event.promise.catch(error => {
console.log(error);
// 如果`error`是个错误,则继续处理
if (error instanceof Error) {
// 如果已经处理过该错误,则不再处理
if (errorList.includes(error)) return;
errorList.push(error);
// 如果`error`拥有字符串形式的报错栈堆且报错栈堆确实符合v8的stack
if (typeof error.stack === 'string' && STACK_REGEXP.test(error.stack)) {
// 获取符合栈堆信息的字符串,一般来说就是从第二行开始的所有行
// 为了处理eval的情况故必须获取完行数
let lines = error.stack.split('\n').filter((line) =>
STACK_REGEXP.test(line));
// 提供类型信息防止vscode报错
/**
* @type {string | undefined}
*/
let fileName = void 0;
/**
* @type {number | undefined}
*/
let line = void 0;
/**
* @type {number | undefined}
*/
let column = void 0;
// 从第一条开始遍历一直遍历到不存在eval的位置
for (let currentLine = 0; currentLine < lines.length; ++currentLine) {
if (/\(eval /.test(lines[currentLine])) continue;
let formatedLine = lines[currentLine].replace(/^\s+/, '').replace(/\(eval code/g, '(').replace(/^.*?\s+/, '');
const location = formatedLine.match(/ (\(.+\)$)/);
if (location) formatedLine = formatedLine.replace(location[0], '');
const locationParts = extractLocation(location ? location[1] : formatedLine);
fileName = ['eval', '<anonymous>'].includes(locationParts[0]) ? void 0 : locationParts[0];
line = Number(locationParts[1]);
column = Number(locationParts[2]);
break;
}
// @ts-ignore
window.onerror(error.message, fileName, line, column, error);
}
// 反之我们只能不考虑报错文件信息直接调用onerror
else {
try {
// @ts-ignore
let [_, src = void 0, line = void 0, column = void 0] = /at\s+.*\s+\((.*):(\d*):(\d*)\)/i.exec(error.stack.split('\n')[1])
if (typeof line == 'string') line = Number(line);
if (typeof column == 'string') column = Number(column);
// @ts-ignore
window.onerror(error.message, src, line, column, error);
} catch (e) {
window.onerror(error.message, '', 0, 0, error);
}
}
}
});
};
})();
</script>
<script>
if (location.href.startsWith('http') && typeof window.initReadWriteFunction != 'function' && !window.require && !window.__dirname) {
window.initReadWriteFunction = async function(game) {
window.initReadWriteFunction = async function (game) {
return new Promise((resolve, reject) => {
fetch(`./readFile?fileName=noname.js`)
.then(response => {

View File

@ -18,6 +18,8 @@ import { onload } from './onload.js';
export function canUseHttpProtocol() {
// 如果是http了就不用
if (location.protocol.startsWith('http')) return false;
// 首次启动不更新(即还没进行过新手教程)
if (!lib.config.new_tutorial) return false;
if (typeof nonameInitialized == 'string') {
// 手机端
if (window.cordova) {
@ -846,9 +848,9 @@ async function setOnError() {
if (promiseErrorHandler.onLoad) await promiseErrorHandler.onLoad();
window.addEventListener("unhandledrejection", async (event) => {
window.onunhandledrejection = async (event) => {
if (promiseErrorHandler.onHandle) await promiseErrorHandler.onHandle(event);
});
};
window.onerror = function (msg, src, line, column, err) {
if (promiseErrorHandler.onErrorPrepare) promiseErrorHandler.onErrorPrepare();