using BetterGenshinImpact.Core.Script.Utils;
using System;
using System.IO;
using System.Threading.Tasks;
using OpenCvSharp;
using System.Linq;
using BetterGenshinImpact.GameTask.Common;
using Microsoft.Extensions.Logging;
namespace BetterGenshinImpact.Core.Script.Dependence;
public class LimitedFile(string rootPath)
{
///
/// 读取指定文件夹内所有文件和文件夹的路径(非递归方式)。
///
/// 文件夹路径(相对于根目录)
/// 文件夹内所有文件和文件夹的路径数组
public string[] ReadPathSync(string folderPath)
{
try
{
// 对传入的文件夹路径进行标准化
string normalizedFolderPath = NormalizePath(folderPath);
// 确保目录存在
if (!Directory.Exists(normalizedFolderPath))
{
Directory.CreateDirectory(normalizedFolderPath);
}
// 获取指定文件夹下的所有文件(非递归)
string[] files = Directory.GetFiles(normalizedFolderPath, "*", SearchOption.TopDirectoryOnly);
// 获取指定文件夹下的所有子文件夹(非递归)
string[] directories = Directory.GetDirectories(normalizedFolderPath, "*", SearchOption.TopDirectoryOnly);
// 合并文件和文件夹路径
string[] combined = files.Concat(directories).ToArray();
// 将绝对路径转换为相对于 rootPath 的相对路径
return combined.Select(path => Path.GetRelativePath(rootPath, path)).ToArray();
}
catch (Exception ex)
{
// 记录异常并返回空数组
TaskControl.Logger.LogError("ReadPathSync 异常: {Message}", ex.Message);
return Array.Empty();
}
}
///
/// 判断指定路径是否为文件夹。
///
/// 文件或文件夹路径(相对于根目录)。
/// 如果该路径是文件夹则返回 true,否则返回 false。
public bool IsFolder(string path)
{
try
{
// 对传入的路径进行标准化处理
string normalizedPath = NormalizePath(path);
// 使用 Directory.Exists 判断标准化路径是否为文件夹
return Directory.Exists(normalizedPath);
}
catch (Exception ex)
{
// 记录异常并返回 false
TaskControl.Logger.LogError("IsFolder 异常: {Message}", ex.Message);
return false;
}
}
///
/// Normalize and validate a path.
///
private string NormalizePath(string path)
{
return ScriptUtils.NormalizePath(rootPath, path);
}
///
/// Read all text from a file.
///
/// File path.
/// Text read from file.
public string ReadTextSync(string path)
{
try
{
path = NormalizePath(path);
return File.ReadAllText(path);
}
catch (Exception ex)
{
// 记录异常并返回空字符串
TaskControl.Logger.LogError("ReadTextSync 异常: {Message}", ex.Message);
return string.Empty;
}
}
///
/// Read all text from a file.
///
/// File path.
/// Text read from file.
public async Task ReadText(string path)
{
try
{
path = NormalizePath(path);
var ret = await File.ReadAllTextAsync(path);
return ret;
}
catch (Exception ex)
{
// 记录异常并返回空字符串
TaskControl.Logger.LogError("ReadText 异常: {Message}", ex.Message);
return string.Empty;
}
}
///
/// Read all text from a file.
///
/// File path.
/// Callback function.
/// Text read from file.
public async Task ReadText(string path, dynamic callbackFunc)
{
try
{
path = NormalizePath(path);
var ret = await File.ReadAllTextAsync(path);
callbackFunc(null, ret);
return ret;
}
catch (Exception ex)
{
callbackFunc(ex.ToString(), null);
return string.Empty;
}
}
///
/// 读取Mat图片
///
///
///
public Mat ReadImageMatSync(string path)
{
try
{
path = NormalizePath(path);
using var stream = File.OpenRead(path);
var mat = Mat.FromStream(stream, ImreadModes.Color);
return mat;
}
catch (Exception ex)
{
// 记录异常并返回空的Mat
TaskControl.Logger.LogError("ReadImageMatSync 异常: {Message}", ex.Message);
return new Mat();
}
}
///
/// 读取图像文件为Mat对象,并调整到指定尺寸
///
/// 图像文件路径
/// 调整后的宽度
/// 调整后的高度
/// 插值算法,默认为双线性插值(1)
/// 调整尺寸后的Mat图像对象
///
/// 支持的插值算法:
///
/// - 最近邻插值 (0)
/// - 双线性插值 (1) - 默认
/// - 双三次插值 (2)
/// - 像素区域关系重采样 (3)
/// - Lanczos插值 (4)
/// - 精确双线性插值 (5)
///
///
public Mat ReadImageMatWithResizeSync(string path, double width, double height, int interpolation = 1)
{
try
{
if (width <= 0 || height <= 0)
{
throw new Exception("ReadImageMatWithResizeSync: 宽度和高度必须为正数");
}
if (interpolation is < 0 or > 5)
{
throw new Exception($"ReadImageMatWithResizeSync: 不支持的插值算法 {interpolation}");
}
path = NormalizePath(path);
using var stream = File.OpenRead(path);
using var mat = Mat.FromStream(stream, ImreadModes.Color);
var rsz = new Mat();
Cv2.Resize(mat, rsz, new Size(width, height), 0, 0, (InterpolationFlags)interpolation);
return rsz;
}
catch (Exception ex)
{
// 记录异常并返回空的Mat
TaskControl.Logger.LogError("ReadImageMatWithResizeSync 异常: {Message}", ex.Message);
return new Mat();
}
}
///
/// 允许的文件扩展名白名单
///
private readonly string[] _allowedExtensions = [".txt", ".json", ".log", ".csv", ".xml", ".html", ".css", ".png", ".jpg", ".jpeg", ".bmp", ".tiff", ".webp"];
///
/// 最大允许的文件大小(字节)
///
private const long MaxFileSize = 999 * 1024 * 1024; // 999 MB
///
/// 验证路径和内容是否合法,并确保目录存在
///
/// 文件路径
/// 要写入的内容,如果为null则只验证路径
/// 是否合法
private bool IsValid(string path, string? content = null)
{
try
{
// 验证文件扩展名
string extension = Path.GetExtension(path).ToLower();
if (!Array.Exists(_allowedExtensions, ext => ext == extension))
{
return false;
}
// 确保目录存在
var normalizedPath = NormalizePath(path);
string? directoryPath = Path.GetDirectoryName(normalizedPath);
if (!string.IsNullOrEmpty(directoryPath) && !Directory.Exists(directoryPath))
{
Directory.CreateDirectory(directoryPath);
}
// 如果提供了内容,验证内容是否合法
if (content != null)
{
// 检查文件大小
if (content.Length > MaxFileSize)
{
return false;
}
}
return true;
}
catch (Exception ex)
{
// 记录异常并返回 false
TaskControl.Logger.LogError("IsValid 异常: {Message}", ex.Message);
return false;
}
}
///
/// 同步写入文本到文件
///
/// 文件路径
/// 要写入的内容
/// 是否追加到文件末尾,默认为false(覆盖)
/// 是否写入成功
public bool WriteTextSync(string path, string content, bool append = false)
{
try
{
path = NormalizePath(path);
if (!IsValid(path, content))
{
return false;
}
if (append && File.Exists(path))
{
File.AppendAllText(path, content);
}
else
{
File.WriteAllText(path, content);
}
return true;
}
catch
{
return false;
}
}
///
/// 异步写入文本到文件
///
/// 文件路径
/// 要写入的内容
/// 是否追加到文件末尾,默认为false(覆盖)
/// 是否写入成功
public async Task WriteText(string path, string content, bool append = false)
{
try
{
path = NormalizePath(path);
if (!IsValid(path, content))
{
return false;
}
if (append && File.Exists(path))
{
await File.AppendAllTextAsync(path, content);
}
else
{
await File.WriteAllTextAsync(path, content);
}
return true;
}
catch
{
return false;
}
}
///
/// 异步写入文本到文件(带回调)
///
/// 文件路径
/// 要写入的内容
/// 回调函数
/// 是否追加到文件末尾,默认为false(覆盖)
/// 是否写入成功
public async Task WriteText(string path, string content, dynamic callbackFunc, bool append = false)
{
try
{
path = NormalizePath(path);
if (!IsValid(path, content))
{
callbackFunc("路径不合法或文件内容不合法", null);
return false;
}
if (append && File.Exists(path))
{
await File.AppendAllTextAsync(path, content);
}
else
{
await File.WriteAllTextAsync(path, content);
}
callbackFunc(null, true);
return true;
}
catch (Exception ex)
{
callbackFunc(ex.ToString(), null);
return false;
}
}
///
/// 同步写入图片到文件(默认PNG格式)
///
/// 文件路径
/// OpenCV Mat对象
/// 是否写入成功
public bool WriteImageSync(string path, Mat mat)
{
try
{
// 自动追加.png后缀
path = EnsureImageExtension(path);
path = NormalizePath(path);
if (!IsValidImagePath(path))
{
return false;
}
// 确保目录存在
string? directoryPath = Path.GetDirectoryName(path);
if (!string.IsNullOrEmpty(directoryPath) && !Directory.Exists(directoryPath))
{
Directory.CreateDirectory(directoryPath);
}
// 使用OpenCV保存图片(默认PNG格式)
Cv2.ImWrite(path, mat);
return true;
}
catch (Exception ex)
{
// 记录异常并返回 false
TaskControl.Logger.LogError("WriteImageSync 异常: {Message}", ex.Message);
return false;
}
}
///
/// 确保图片路径有正确的扩展名,如果没有则自动追加.png
///
/// 文件路径
/// 带有正确扩展名的路径
private string EnsureImageExtension(string path)
{
string extension = Path.GetExtension(path).ToLower();
string[] imageExtensions = [".png", ".jpg", ".jpeg", ".bmp", ".tiff", ".webp"];
// 如果已经有图片扩展名,直接返回
if (Array.Exists(imageExtensions, ext => ext == extension))
{
return path;
}
// 如果没有扩展名,自动追加.png
return path + ".png";
}
///
/// 验证图片路径是否合法
///
/// 文件路径
/// 是否合法
private bool IsValidImagePath(string path)
{
// 验证文件扩展名
string extension = Path.GetExtension(path).ToLower();
string[] imageExtensions = [".png", ".jpg", ".jpeg", ".bmp", ".tiff", ".webp"];
if (!Array.Exists(imageExtensions, ext => ext == extension))
{
return false;
}
return true;
}
}