2015-04-29 03:25:17 +00:00
|
|
|
|
<!DOCTYPE HTML>
|
2024-02-16 09:33:42 +00:00
|
|
|
|
|
2023-09-24 04:22:57 +00:00
|
|
|
|
<head>
|
2023-12-27 15:07:16 +00:00
|
|
|
|
<meta charset="UTF-8">
|
|
|
|
|
<meta name="format-detection" content="telephone=no">
|
|
|
|
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
|
|
|
|
<meta name="viewport" content="user-scalable=no, viewport-fit=cover">
|
|
|
|
|
<title>无名杀</title>
|
|
|
|
|
<script>
|
2024-02-16 09:33:42 +00:00
|
|
|
|
(() => {
|
|
|
|
|
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 = [];
|
2024-03-08 16:38:21 +00:00
|
|
|
|
function extractLocation(urlLike) {
|
|
|
|
|
// 不存在地址信息的字符串
|
|
|
|
|
if (!/:/.test(urlLike)) {
|
|
|
|
|
return [urlLike];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 捕获位置用到的正则
|
|
|
|
|
const regExp = /(.+?)(?::(\d+))?(?::(\d+))?$/;
|
|
|
|
|
const parts = regExp.exec(urlLike.replace(/[()]/g, ''));
|
|
|
|
|
|
|
|
|
|
// @ts-ignore
|
|
|
|
|
return [parts[1], parts[2] || void 0, parts[3] || void 0];
|
|
|
|
|
}
|
2024-02-16 09:33:42 +00:00
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
})();
|
2023-12-27 15:07:16 +00:00
|
|
|
|
</script>
|
2024-01-15 13:08:05 +00:00
|
|
|
|
<script>
|
|
|
|
|
if (location.href.startsWith('http') && typeof window.initReadWriteFunction != 'function' && !window.require && !window.__dirname) {
|
2024-02-16 09:33:42 +00:00
|
|
|
|
window.initReadWriteFunction = async function (game) {
|
2024-01-19 15:57:05 +00:00
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
|
fetch(`./readFile?fileName=noname.js`)
|
2024-01-15 13:08:05 +00:00
|
|
|
|
.then(response => {
|
|
|
|
|
return response.json();
|
|
|
|
|
})
|
|
|
|
|
.then(result => {
|
2024-01-19 15:57:05 +00:00
|
|
|
|
if (result && result.success) callback();
|
|
|
|
|
else reject(result.errorMsg)
|
2024-01-15 13:08:05 +00:00
|
|
|
|
})
|
2024-01-19 15:57:05 +00:00
|
|
|
|
.catch(reject);
|
2024-01-15 13:08:05 +00:00
|
|
|
|
|
2024-01-19 15:57:05 +00:00
|
|
|
|
function callback() {
|
|
|
|
|
game.createDir = function (dir, success = () => { }, error = () => { }) {
|
|
|
|
|
fetch(`./createDir?dir=${dir}`)
|
|
|
|
|
.then(response => {
|
|
|
|
|
return response.json();
|
|
|
|
|
})
|
|
|
|
|
.then(result => {
|
|
|
|
|
if (result && result.success) success();
|
|
|
|
|
else error();
|
|
|
|
|
})
|
|
|
|
|
.catch(error);
|
|
|
|
|
};
|
2024-01-15 13:08:05 +00:00
|
|
|
|
|
2024-01-19 15:57:05 +00:00
|
|
|
|
game.readFile = function (fileName, callback = () => { }, error = () => { }) {
|
|
|
|
|
fetch(`./readFile?fileName=${fileName}`)
|
|
|
|
|
.then(response => {
|
|
|
|
|
return response.json();
|
|
|
|
|
})
|
|
|
|
|
.then(result => {
|
|
|
|
|
if (result && result.success) callback(new Uint8Array(result.data).buffer);
|
|
|
|
|
else error(result && result.errorMsg);
|
|
|
|
|
})
|
|
|
|
|
.catch(error);
|
|
|
|
|
};
|
2024-01-15 13:08:05 +00:00
|
|
|
|
|
2024-01-19 15:57:05 +00:00
|
|
|
|
game.readFileAsText = function (fileName, callback = () => { }, error = () => { }) {
|
|
|
|
|
fetch(`./readFileAsText?fileName=${fileName}`)
|
|
|
|
|
.then(response => {
|
|
|
|
|
return response.json();
|
2024-01-15 13:08:05 +00:00
|
|
|
|
})
|
2024-01-19 15:57:05 +00:00
|
|
|
|
.then(result => {
|
|
|
|
|
if (result && result.success) callback(result.data);
|
|
|
|
|
else error(result && result.errorMsg);
|
|
|
|
|
})
|
|
|
|
|
.catch(error);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
game.writeFile = function (data, path, name, callback = () => { }) {
|
|
|
|
|
game.ensureDirectory(path, function () {
|
|
|
|
|
if (Object.prototype.toString.call(data) == '[object File]') {
|
|
|
|
|
const fileReader = new FileReader();
|
|
|
|
|
fileReader.onload = function (e) {
|
|
|
|
|
game.writeFile(e.target.result, path, name, callback);
|
|
|
|
|
};
|
|
|
|
|
fileReader.readAsArrayBuffer(data, "UTF-8");
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
let filePath = path;
|
|
|
|
|
if (path.endsWith('/')) {
|
|
|
|
|
filePath += name;
|
|
|
|
|
} else if (path == "") {
|
|
|
|
|
filePath += name;
|
|
|
|
|
} else {
|
|
|
|
|
filePath += '/' + name;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fetch(`./writeFile`, {
|
|
|
|
|
method: 'post',
|
|
|
|
|
headers: { "Content-Type": "application/json" },
|
|
|
|
|
body: JSON.stringify({
|
|
|
|
|
data: typeof data == 'string' ? data : Array.prototype.slice.call(new Uint8Array(data)),
|
|
|
|
|
path: filePath
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
.then(response => {
|
|
|
|
|
return response.json();
|
|
|
|
|
})
|
|
|
|
|
.then(result => {
|
|
|
|
|
if (result && result.success) {
|
|
|
|
|
callback();
|
|
|
|
|
} else {
|
|
|
|
|
callback(result.errorMsg);
|
|
|
|
|
}
|
|
|
|
|
});
|
2024-01-15 13:08:05 +00:00
|
|
|
|
}
|
|
|
|
|
});
|
2024-01-19 15:57:05 +00:00
|
|
|
|
};
|
2024-01-15 13:08:05 +00:00
|
|
|
|
|
2024-01-19 15:57:05 +00:00
|
|
|
|
game.removeFile = function (fileName, callback = () => { }) {
|
|
|
|
|
fetch(`./removeFile?fileName=${fileName}`)
|
|
|
|
|
.then(response => {
|
|
|
|
|
return response.json();
|
|
|
|
|
})
|
|
|
|
|
.then(result => {
|
|
|
|
|
callback(result.errorMsg);
|
|
|
|
|
})
|
|
|
|
|
.catch(error);
|
|
|
|
|
};
|
2024-01-15 13:08:05 +00:00
|
|
|
|
|
2024-01-19 15:57:05 +00:00
|
|
|
|
game.getFileList = function (dir, callback = () => { }) {
|
|
|
|
|
fetch(`./getFileList?dir=${dir}`)
|
|
|
|
|
.then(response => {
|
|
|
|
|
return response.json();
|
|
|
|
|
})
|
|
|
|
|
.then(result => {
|
|
|
|
|
if (result && result.success) {
|
|
|
|
|
callback(result.data.dirs, result.data.files);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
game.ensureDirectory = function (list, callback = () => { }, file = false) {
|
|
|
|
|
let pathArray = typeof list == "string" ? list.split("/") : list;
|
|
|
|
|
if (file) {
|
|
|
|
|
pathArray = pathArray.slice(0, -1);
|
2024-01-15 13:08:05 +00:00
|
|
|
|
}
|
2024-01-19 15:57:05 +00:00
|
|
|
|
game.createDir(pathArray.join("/"), callback, console.error);
|
|
|
|
|
};
|
2024-01-15 13:08:05 +00:00
|
|
|
|
|
2024-01-19 15:57:05 +00:00
|
|
|
|
resolve();
|
2024-01-15 13:08:05 +00:00
|
|
|
|
}
|
2024-01-19 15:57:05 +00:00
|
|
|
|
});
|
2024-01-15 13:08:05 +00:00
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
</script>
|
2023-12-27 15:07:16 +00:00
|
|
|
|
<script src="game/update.js"></script>
|
|
|
|
|
<script src="game/config.js"></script>
|
|
|
|
|
<script src="game/package.js"></script>
|
|
|
|
|
<script src="game/game.js"></script>
|
2023-09-24 04:22:57 +00:00
|
|
|
|
</head>
|