Signal 数据中心改为运行时加载 schema,解除 StandardScene 工程编译耦合。
加固 Config/Signal 路径解析,前端 DataCenter 表单类型与 API 对齐。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -15,8 +15,8 @@ public sealed record SignalTableDef(
|
||||
IReadOnlyList<SignalColumn> Columns);
|
||||
|
||||
/// <summary>
|
||||
/// 读写 SimpleLite 工作目录 <c>Config/Signal/*.json</c>,供迷毂「数据中心」表格编辑。
|
||||
/// 表结构优先从 StandardScene.Signal.dll 反射;无插件时才读 signal-tables.json。
|
||||
/// 读写 Simple3 工作目录 <c>Config/Signal/*.json</c>,供迷毂「数据中心」表格编辑。
|
||||
/// 表结构只从 Simple3 <c>plugins/StandardScene.Signal.dll</c> 反射;无插件时才读 signal-tables.json。
|
||||
/// </summary>
|
||||
public sealed class SignalDataStore
|
||||
{
|
||||
@@ -28,11 +28,11 @@ public sealed class SignalDataStore
|
||||
|
||||
private static readonly object FileLock = new();
|
||||
|
||||
private readonly SimpleLiteLauncher _launcher;
|
||||
private readonly Simple3Launcher _launcher;
|
||||
private IReadOnlyList<SignalTableDef>? _cachedTables;
|
||||
private long _cachedSignature;
|
||||
|
||||
public SignalDataStore(SimpleLiteLauncher launcher) => _launcher = launcher;
|
||||
public SignalDataStore(Simple3Launcher launcher) => _launcher = launcher;
|
||||
|
||||
public IReadOnlyList<SignalTableDef> GetTables()
|
||||
{
|
||||
@@ -55,9 +55,11 @@ public sealed class SignalDataStore
|
||||
{
|
||||
var wd = _launcher.ResolveWorkingDirectory();
|
||||
if (string.IsNullOrWhiteSpace(wd))
|
||||
return (null, "未找到 SimpleLite 工作目录,无法定位 Config/Signal");
|
||||
return (null, "未找到 Simple3 工作目录,无法定位 Config/Signal");
|
||||
|
||||
if (!TryResolveUnderSignalDir(wd, table.FileName, out var dest, out var pathError))
|
||||
return (null, pathError);
|
||||
|
||||
var dest = Path.GetFullPath(Path.Combine(wd, "Config", "Signal", table.FileName));
|
||||
if (File.Exists(dest))
|
||||
return (dest, null);
|
||||
|
||||
@@ -109,4 +111,29 @@ public sealed class SignalDataStore
|
||||
lock (FileLock)
|
||||
File.WriteAllText(path, rows.ToJsonString(FileJson));
|
||||
}
|
||||
|
||||
private static bool TryResolveUnderSignalDir(string workingDirectory, string fileName, out string dest, out string error)
|
||||
{
|
||||
dest = "";
|
||||
error = "";
|
||||
if (string.IsNullOrWhiteSpace(fileName) ||
|
||||
Path.IsPathRooted(fileName) ||
|
||||
fileName.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0)
|
||||
{
|
||||
error = "信号表文件名非法";
|
||||
return false;
|
||||
}
|
||||
|
||||
var root = Path.GetFullPath(Path.Combine(workingDirectory, "Config", "Signal"));
|
||||
dest = Path.GetFullPath(Path.Combine(root, fileName));
|
||||
var prefix = root.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar) + Path.DirectorySeparatorChar;
|
||||
if (!dest.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
error = "信号表路径超出 Config/Signal";
|
||||
dest = "";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user