XNSim/XNSimHtml/utils/file-utils.js

175 lines
4.3 KiB
JavaScript
Raw Permalink Normal View History

2025-04-28 12:25:20 +08:00
const path = require('path');
2025-05-28 16:20:01 +08:00
const fs = require('fs'); // 添加同步方法支持
const fsPromises = require('fs').promises; // 重命名为fsPromises以区分
const Database = require('better-sqlite3');
// 数据库连接管理
let dbConnection = null;
// 获取数据库连接
function getDBConnection(readonly = false) {
try {
if (dbConnection) {
return dbConnection;
}
const xnCorePath = getXNCorePath();
if (!xnCorePath) {
throw new Error('XNCore环境变量未设置无法获取数据库路径');
}
const dbPath = path.join(xnCorePath, 'database', 'XNSim.db');
if (!dbPath) {
throw new Error('无法找到数据库文件');
}
// 打开数据库连接,始终以可读可写模式打开
dbConnection = new Database(dbPath);
return dbConnection;
} catch (error) {
console.error('数据库连接失败:', error);
throw error;
}
}
// 关闭数据库连接
function closeDBConnection() {
if (dbConnection) {
dbConnection.close();
dbConnection = null;
}
}
2025-04-28 12:25:20 +08:00
// 获取XNCore路径
function getXNCorePath() {
const xnCorePath = process.env.XNCore || '';
if (!xnCorePath) {
console.error('XNCore环境变量未设置');
}
return xnCorePath;
}
// 场景文件目录路径
function getScenarioPath() {
const xnCorePath = getXNCorePath();
if (!xnCorePath) return '';
return path.join(xnCorePath, 'Scenario');
}
// 项目模型文件目录路径
function getProjectModelPath() {
const xnCorePath = getXNCorePath();
if (!xnCorePath) return '';
return path.join(xnCorePath, 'Project', 'Model');
}
// 模型文件目录路径
function getModelPath() {
const xnCorePath = getXNCorePath();
if (!xnCorePath) return '';
return path.join(xnCorePath, 'Models');
}
// 服务文件目录路径
function getServicePath() {
const xnCorePath = getXNCorePath();
if (!xnCorePath) return '';
return path.join(xnCorePath, 'Services');
}
// 日志目录路径处理
2025-05-28 16:20:01 +08:00
async function getActualLogPath(requestedPath) {
2025-04-28 12:25:20 +08:00
const xnCorePath = getXNCorePath();
2025-05-28 16:20:01 +08:00
const currentDir = process.cwd();
2025-04-28 12:25:20 +08:00
2025-05-28 16:20:01 +08:00
// 如果请求的路径是/log开头
2025-04-28 12:25:20 +08:00
if (requestedPath.startsWith('/log')) {
2025-05-28 16:20:01 +08:00
// 首先尝试在XNCore下查找
const xnCoreLogPath = path.join(xnCorePath, requestedPath);
if (fs.existsSync(xnCoreLogPath)) {
return xnCoreLogPath;
}
// 如果XNCore下不存在则尝试在当前目录下查找
const currentLogPath = path.join(currentDir, requestedPath);
if (fs.existsSync(currentLogPath)) {
return currentLogPath;
}
// 如果都不存在默认使用XNCore下的路径
return xnCoreLogPath;
2025-04-28 12:25:20 +08:00
}
// 如果已经是绝对路径并且在XNCore下
else if (requestedPath.startsWith(xnCorePath)) {
return requestedPath;
}
2025-05-28 16:20:01 +08:00
// 如果已经是绝对路径并且在当前目录下
else if (requestedPath.startsWith(currentDir)) {
return requestedPath;
}
2025-04-28 12:25:20 +08:00
// 默认不允许访问其他路径
else {
return null;
}
}
// 检查文件路径安全性
function isPathSafe(filePath, allowedDir) {
// 安全检查确保allowedDir不为空
if (!allowedDir) {
return false;
}
// 确保路径是绝对路径
const absolutePath = path.resolve(filePath);
// 检查路径是否在允许的目录内
return absolutePath.startsWith(allowedDir);
}
// 确保目录存在,如不存在则创建
async function ensureDirectoryExists(dirPath) {
try {
2025-05-28 16:20:01 +08:00
await fsPromises.access(dirPath);
2025-04-28 12:25:20 +08:00
} catch (error) {
if (error.code === 'ENOENT') {
try {
2025-05-28 16:20:01 +08:00
await fsPromises.mkdir(dirPath, { recursive: true });
2025-04-28 12:25:20 +08:00
return true;
} catch (mkdirError) {
console.error('创建目录失败:', mkdirError);
throw mkdirError;
}
} else {
throw error;
}
}
return false;
}
// XML 验证
async function validateXml(content) {
if (!content || !content.trim()) return true;
try {
const parser = new (require('xml2js')).Parser();
await parser.parseStringPromise(content);
return true;
} catch (xmlError) {
return { error: 'XML格式无效', details: xmlError.message };
}
}
module.exports = {
getXNCorePath,
getScenarioPath,
getModelPath,
getProjectModelPath,
getServicePath,
getActualLogPath,
isPathSafe,
ensureDirectoryExists,
validateXml,
getDBConnection,
closeDBConnection
2025-04-28 12:25:20 +08:00
};