Merge pull request #1259 from Rintim/Dev-Enhancement-DivideCharacter

一个想不到好标题的PR
This commit is contained in:
Spmario233 2024-04-22 22:33:12 +08:00 committed by GitHub
commit 1a8746c4d5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 135 additions and 89 deletions

View File

@ -23,7 +23,7 @@ window.noname_package = {
old: "怀旧", old: "怀旧",
diy: "DIY", diy: "DIY",
ddd: "3D精选", ddd: "3D精选",
'key/index' : "Key", key: "Key",
yxs: "英雄杀", yxs: "英雄杀",
hearth: "炉石传说", hearth: "炉石传说",
gwent: "昆特牌", gwent: "昆特牌",

View File

@ -1,28 +1,29 @@
<!DOCTYPE HTML> <!DOCTYPE html>
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8" />
<meta name="format-detection" content="telephone=no"> <meta name="format-detection" content="telephone=no" />
<meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="viewport" content="user-scalable=no, viewport-fit=cover"> <meta name="viewport" content="user-scalable=no, viewport-fit=cover" />
<title>无名杀</title> <title>无名杀</title>
<script> <script>
if (typeof window.require == 'function' && if (
typeof window.process == 'object' && typeof window.require == "function" &&
typeof window.__dirname == 'string') { typeof window.process == "object" &&
typeof window.__dirname == "string"
) {
// 使importMap解析node内置模块 // 使importMap解析node内置模块
const builtinModules = require('module').builtinModules; const builtinModules = require("module").builtinModules;
if (Array.isArray(builtinModules)) { if (Array.isArray(builtinModules)) {
const importMap = { const importMap = {
imports: {} imports: {},
}; };
for (const module of builtinModules) { for (const module of builtinModules) {
importMap.imports[module] = importMap.imports[module] = importMap.imports[`node:${module}`] =
importMap.imports[`node:${module}`] = `./noname-builtinModules/${module}`;
`./noname-builtinModules/${module}`
} }
const im = document.createElement('script'); const im = document.createElement("script");
im.type = 'importmap'; im.type = "importmap";
im.textContent = JSON.stringify(importMap); im.textContent = JSON.stringify(importMap);
document.currentScript.after(im); document.currentScript.after(im);
} }
@ -32,11 +33,11 @@
"use strict"; "use strict";
(() => { (() => {
window.onerror = function (msg, src, line, column, err) { window.onerror = function (msg, src, line, column, err) {
let str = `错误文件: ${typeof src == 'string' && src.length > 0 ? decodeURI(src) : '未知文件'}`; let str = `错误文件: ${typeof src == "string" && src.length > 0 ? decodeURI(src) : "未知文件"}`;
str += `\n错误信息: ${msg}`; str += `\n错误信息: ${msg}`;
str += `\n行号: ${line}`; str += `\n行号: ${line}`;
str += `\n列号: ${column}`; str += `\n列号: ${column}`;
if (err && err.stack) str += '\n' + decodeURI(err.stack); if (err && err.stack) str += "\n" + decodeURI(err.stack);
console.error(str); console.error(str);
alert(str); alert(str);
}; };
@ -50,13 +51,13 @@
// 捕获位置用到的正则 // 捕获位置用到的正则
const regExp = /(.+?)(?::(\d+))?(?::(\d+))?$/; const regExp = /(.+?)(?::(\d+))?(?::(\d+))?$/;
const parts = regExp.exec(urlLike.replace(/[()]/g, '')); const parts = regExp.exec(urlLike.replace(/[()]/g, ""));
// @ts-ignore // @ts-ignore
return [parts[1], parts[2] || void 0, parts[3] || void 0]; return [parts[1], parts[2] || void 0, parts[3] || void 0];
} }
window.onunhandledrejection = async event => { window.onunhandledrejection = async (event) => {
event.promise.catch(error => { event.promise.catch((error) => {
console.log(error); console.log(error);
// 如果`error`是个错误,则继续处理 // 如果`error`是个错误,则继续处理
if (error instanceof Error) { if (error instanceof Error) {
@ -64,11 +65,10 @@
if (errorList.includes(error)) return; if (errorList.includes(error)) return;
errorList.push(error); errorList.push(error);
// 如果`error`拥有字符串形式的报错栈堆且报错栈堆确实符合v8的stack // 如果`error`拥有字符串形式的报错栈堆且报错栈堆确实符合v8的stack
if (typeof error.stack === 'string' && STACK_REGEXP.test(error.stack)) { if (typeof error.stack === "string" && STACK_REGEXP.test(error.stack)) {
// 获取符合栈堆信息的字符串,一般来说就是从第二行开始的所有行 // 获取符合栈堆信息的字符串,一般来说就是从第二行开始的所有行
// 为了处理eval的情况故必须获取完行数 // 为了处理eval的情况故必须获取完行数
let lines = error.stack.split('\n').filter((line) => let lines = error.stack.split("\n").filter((line) => STACK_REGEXP.test(line));
STACK_REGEXP.test(line));
// 提供类型信息防止vscode报错 // 提供类型信息防止vscode报错
/** /**
@ -90,14 +90,19 @@
for (let currentLine = 0; currentLine < lines.length; ++currentLine) { for (let currentLine = 0; currentLine < lines.length; ++currentLine) {
if (/\(eval /.test(lines[currentLine])) continue; if (/\(eval /.test(lines[currentLine])) continue;
let formatedLine = lines[currentLine].replace(/^\s+/, '').replace(/\(eval code/g, '(').replace(/^.*?\s+/, ''); let formatedLine = lines[currentLine]
.replace(/^\s+/, "")
.replace(/\(eval code/g, "(")
.replace(/^.*?\s+/, "");
const location = formatedLine.match(/ (\(.+\)$)/); const location = formatedLine.match(/ (\(.+\)$)/);
if (location) formatedLine = formatedLine.replace(location[0], ''); if (location) formatedLine = formatedLine.replace(location[0], "");
const locationParts = extractLocation(location ? location[1] : formatedLine); const locationParts = extractLocation(location ? location[1] : formatedLine);
fileName = ['eval', '<anonymous>'].includes(locationParts[0]) ? void 0 : locationParts[0]; fileName = ["eval", "<anonymous>"].includes(locationParts[0])
? void 0
: locationParts[0];
line = Number(locationParts[1]); line = Number(locationParts[1]);
column = Number(locationParts[2]); column = Number(locationParts[2]);
break; break;
@ -110,13 +115,14 @@
else { else {
try { try {
// @ts-ignore // @ts-ignore
let [_, src = void 0, line = void 0, column = void 0] = /at\s+.*\s+\((.*):(\d*):(\d*)\)/i.exec(error.stack.split('\n')[1]) let [_, src = void 0, line = void 0, column = void 0] =
if (typeof line == 'string') line = Number(line); /at\s+.*\s+\((.*):(\d*):(\d*)\)/i.exec(error.stack.split("\n")[1]);
if (typeof column == 'string') column = Number(column); if (typeof line == "string") line = Number(line);
if (typeof column == "string") column = Number(column);
// @ts-ignore // @ts-ignore
window.onerror(error.message, src, line, column, error); window.onerror(error.message, src, line, column, error);
} catch (e) { } catch (e) {
window.onerror(error.message, '', 0, 0, error); window.onerror(error.message, "", 0, 0, error);
} }
} }
} }
@ -126,76 +132,83 @@
</script> </script>
<script> <script>
"use strict"; "use strict";
if (location.href.startsWith('http') && typeof window.initReadWriteFunction != 'function' && !window.require && !window.__dirname) { 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) => { return new Promise((resolve, reject) => {
fetch(`./readFile?fileName=noname.js`) fetch(`./readFile?fileName=noname.js`)
.then(response => { .then((response) => {
return response.json(); return response.json();
}) })
.then(result => { .then((result) => {
if (result && result.success) callback(); if (result && result.success) callback();
else reject(result.errorMsg) else reject(result.errorMsg);
}) })
.catch(reject); .catch(reject);
function callback() { function callback() {
game.readFile = function (fileName, callback = () => {}, error = () => {}) {
game.readFile = function (fileName, callback = () => { }, error = () => { }) {
fetch(`./readFile?fileName=${fileName}`) fetch(`./readFile?fileName=${fileName}`)
.then(response => { .then((response) => {
return response.json(); return response.json();
}) })
.then(result => { .then((result) => {
if (result && result.success) callback(new Uint8Array(result.data).buffer); if (result && result.success)
callback(new Uint8Array(result.data).buffer);
else error(result && result.errorMsg); else error(result && result.errorMsg);
}) })
.catch(error); .catch(error);
}; };
game.readFileAsText = function (fileName, callback = () => { }, error = () => { }) { game.readFileAsText = function (fileName, callback = () => {}, error = () => {}) {
fetch(`./readFileAsText?fileName=${fileName}`) fetch(`./readFileAsText?fileName=${fileName}`)
.then(response => { .then((response) => {
return response.json(); return response.json();
}) })
.then(result => { .then((result) => {
if (result && result.success) callback(result.data); if (result && result.success) callback(result.data);
else error(result && result.errorMsg); else error(result && result.errorMsg);
}) })
.catch(error); .catch(error);
}; };
game.writeFile = function (data, path, name, callback = () => { }) { game.writeFile = function (data, path, name, callback = () => {}) {
game.ensureDirectory(path, function () { game.ensureDirectory(path, function () {
if (Object.prototype.toString.call(data) == '[object File]') { if (Object.prototype.toString.call(data) == "[object File]") {
const fileReader = new FileReader(); const fileReader = new FileReader();
fileReader.onload = function (e) { fileReader.onload = function (e) {
game.writeFile(e.target.result, path, name, callback); game.writeFile(e.target.result, path, name, callback);
}; };
fileReader.readAsArrayBuffer(data, "UTF-8"); fileReader.readAsArrayBuffer(data, "UTF-8");
} } else {
else {
let filePath = path; let filePath = path;
if (path.endsWith('/')) { if (path.endsWith("/")) {
filePath += name; filePath += name;
} else if (path == "") { } else if (path == "") {
filePath += name; filePath += name;
} else { } else {
filePath += '/' + name; filePath += "/" + name;
} }
fetch(`./writeFile`, { fetch(`./writeFile`, {
method: 'post', method: "post",
headers: { "Content-Type": "application/json" }, headers: { "Content-Type": "application/json" },
body: JSON.stringify({ body: JSON.stringify({
data: typeof data == 'string' ? data : Array.prototype.slice.call(new Uint8Array(data)), data:
path: filePath typeof data == "string"
? data
: Array.prototype.slice.call(new Uint8Array(data)),
path: filePath,
}),
}) })
}) .then((response) => {
.then(response => {
return response.json(); return response.json();
}) })
.then(result => { .then((result) => {
if (result && result.success) { if (result && result.success) {
callback(); callback();
} else { } else {
@ -206,30 +219,36 @@
}); });
}; };
game.removeFile = function (fileName, callback = () => { }) { game.removeFile = function (fileName, callback = () => {}) {
fetch(`./removeFile?fileName=${fileName}`) fetch(`./removeFile?fileName=${fileName}`)
.then(response => { .then((response) => {
return response.json(); return response.json();
}) })
.then(result => { .then((result) => {
callback(result.errorMsg); callback(result.errorMsg);
}) })
.catch(error); .catch(error);
}; };
game.getFileList = function (dir, callback = () => { }) { game.getFileList = function (dir, callback = () => {}, onerror) {
fetch(`./getFileList?dir=${dir}`) fetch(`./getFileList?dir=${dir}`)
.then(response => { .then((response) => {
return response.json(); return response.json();
}) })
.then(result => { .then((result) => {
if (result && result.success) { if (!result) {
callback(result.data.dirs, result.data.files); throw new Error("Cannot get available resource.");
}
if (result.success) {
callback(result.data.folders, result.data.files);
} else if (onerror) {
onerror(new Error(result.errorMsg));
} }
}); });
}; };
game.ensureDirectory = function (list, callback = () => { }, file = false) { game.ensureDirectory = function (list, callback = () => {}, file = false) {
let pathArray = typeof list == "string" ? list.split("/") : list; let pathArray = typeof list == "string" ? list.split("/") : list;
if (file) { if (file) {
pathArray = pathArray.slice(0, -1); pathArray = pathArray.slice(0, -1);
@ -237,31 +256,39 @@
game.createDir(pathArray.join("/"), callback, console.error); game.createDir(pathArray.join("/"), callback, console.error);
}; };
game.createDir = (directory, successCallback = () => { }, errorCallback = () => { }) => { game.createDir = (
directory,
successCallback = () => {},
errorCallback = () => {}
) => {
fetch(`./createDir?dir=${directory}`) fetch(`./createDir?dir=${directory}`)
.then(response => { .then((response) => {
return response.json(); return response.json();
}) })
.then(result => { .then((result) => {
if (result && result.success) { if (result && result.success) {
successCallback(); successCallback();
} else { } else {
errorCallback(new Error('创建文件夹失败')) errorCallback(new Error("创建文件夹失败"));
}; }
}) })
.catch(errorCallback); .catch(errorCallback);
}; };
game.removeDir = (directory, successCallback = () => { }, errorCallback = () => { }) => { game.removeDir = (
directory,
successCallback = () => {},
errorCallback = () => {}
) => {
fetch(`./removeDir?dir=${directory}`) fetch(`./removeDir?dir=${directory}`)
.then(response => { .then((response) => {
return response.json(); return response.json();
}) })
.then(result => { .then((result) => {
if (result && result.success) { if (result && result.success) {
successCallback(); successCallback();
} else { } else {
errorCallback(new Error('创建文件夹失败')) errorCallback(new Error("创建文件夹失败"));
}; }
}) })
.catch(errorCallback); .catch(errorCallback);
}; };

View File

@ -1,8 +1,10 @@
export { GNC, gnc, setGNC } from './noname/gnc/index.js'; export const rootURL = new URL(import.meta.url);
export { AI, ai, setAI } from './noname/ai/index.js';
export { Game, game, setGame } from './noname/game/index.js'; export { GNC, gnc, setGNC } from "./noname/gnc/index.js";
export { Get, get, setGet } from './noname/get/index.js'; export { AI, ai, setAI } from "./noname/ai/index.js";
export { Library, lib, setLibrary } from './noname/library/index.js'; export { Game, game, setGame } from "./noname/game/index.js";
export { status, _status, setStatus } from './noname/status/index.js'; export { Get, get, setGet } from "./noname/get/index.js";
export { UI, ui, setUI } from './noname/ui/index.js'; export { Library, lib, setLibrary } from "./noname/library/index.js";
export { boot } from './noname/init/index.js'; export { status, _status, setStatus } from "./noname/status/index.js";
export { UI, ui, setUI } from "./noname/ui/index.js";
export { boot } from "./noname/init/index.js";

View File

@ -126,4 +126,17 @@ export class GamePromises {
}) })
); );
} }
/**
* 获取文件列表
*
* @param { string } dir 目录
* @returns { Promise<[string[], string[]]> } 返回一个数组第一个元素是文件夹列表第二个元素是文件列表
*/
getFileList(dir) {
return new Promise((resolve, reject) => {
// @ts-ignore
game.getFileList(dir, (folders, files) => resolve([folders, files]), reject);
});
}
} }

View File

@ -11,10 +11,13 @@ export const importCardPack = generateImportFunction("card", (name) => `../../ca
* @param {string} name - 武将包名 * @param {string} name - 武将包名
* @returns {Promise<void>} * @returns {Promise<void>}
*/ */
export const importCharacterPack = generateImportFunction( export const importCharacterPack = generateImportFunction("character", (name) => {
"character", const alreadyModernCharacterPack = ["key"];
(name) => `../../character/${name}.js`
); return alreadyModernCharacterPack.includes(name)
? `../../character/${name}/index.js`
: `../../character/${name}.js`;
});
/** /**
* @param {string} name - 扩展名 * @param {string} name - 扩展名

View File

@ -724,7 +724,7 @@ export class LibInit {
let k = 0; let k = 0;
let result; let result;
//去除99个step的限制 //去除99个step的限制
while ((result = str.slice(skip).match(new RegExp(`['"]step ${k}['"]`))) != null) { while ((result = str.slice(skip).match(new RegExp(`\\(?['"]step ${k}['"]\\)?;?`))) != null) {
let insertStr; let insertStr;
if (k == 0) { if (k == 0) {
insertStr = `switch(step){case 0:`; insertStr = `switch(step){case 0:`;

View File

@ -43,6 +43,7 @@
// "noResolve": true, /* Disallow `import`s, `require`s or `<reference>`s from expanding the number of files TypeScript should add to a project. */ // "noResolve": true, /* Disallow `import`s, `require`s or `<reference>`s from expanding the number of files TypeScript should add to a project. */
/* JavaScript Support */ /* JavaScript Support */
"allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */ "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */
"allowImportingTsExtensions": true,
"checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */ // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */
/* Emit */ /* Emit */