wndrks
This commit is contained in:
File diff suppressed because it is too large
Load Diff
1916
tools/KarismaTcpProbe/CutFileAudit.cs
Normal file
1916
tools/KarismaTcpProbe/CutFileAudit.cs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,27 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Tornado3_2026Election.Domain;
|
||||
|
||||
namespace Tornado3_2026Election.Services;
|
||||
|
||||
public sealed class KarismaThumbnailGeneratorService
|
||||
{
|
||||
public KarismaThumbnailGeneratorService(LogService logService)
|
||||
{
|
||||
}
|
||||
|
||||
public Task<ThumbnailGenerationResult> GenerateAsync(
|
||||
TornadoManager manager,
|
||||
IReadOnlyList<FormatTemplateDefinition> templates,
|
||||
string t3CutPath,
|
||||
VideoWallLayoutPreset videoWallLayoutPreset,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.FromResult(new ThumbnailGenerationResult(0, 0));
|
||||
}
|
||||
}
|
||||
|
||||
public readonly record struct ThumbnailGenerationResult(int GeneratedCount, int FailedCount)
|
||||
{
|
||||
public int TotalCount => GeneratedCount + FailedCount;
|
||||
}
|
||||
@@ -337,6 +337,12 @@ if (args.Length > 0 && string.Equals(args[0], "--report-cut-debug-coverage", Str
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.Length > 0 && string.Equals(args[0], "--audit-cut-files", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
Environment.ExitCode = await CutFileAudit.RunAsync(args[1..]).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
var options = ProbeOptions.Parse(args);
|
||||
|
||||
Console.WriteLine($"Karisma TCP probe starting. target={options.Host}:{options.Port} timeout={options.Timeout.TotalSeconds:0}s");
|
||||
@@ -862,6 +868,25 @@ static Task<SaveSceneImageProbeResult> SaveSceneImageAsync(SaveSceneImageOptions
|
||||
}
|
||||
}
|
||||
|
||||
IReadOnlyList<SceneValidationOperation> operations = string.IsNullOrWhiteSpace(options.OperationsPath)
|
||||
? Array.Empty<SceneValidationOperation>()
|
||||
: LoadSceneOperations(options.ScenePath, options.OperationsPath);
|
||||
foreach (var operation in operations)
|
||||
{
|
||||
var operationResult = ApplySceneOperation(handler, scene!, operation, options.Connection.Timeout);
|
||||
if (!string.Equals(operationResult.Result, eKResult.RESULT_SUCCESS.ToString(), StringComparison.Ordinal))
|
||||
{
|
||||
completion.TrySetResult(
|
||||
new SaveSceneImageProbeResult(
|
||||
true,
|
||||
"SUCCESS",
|
||||
operationResult.Result,
|
||||
options.OutputPath,
|
||||
$"Operation {operationResult.Method} failed for '{operationResult.ObjectName}': {operationResult.Detail}"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (options.MaterialOpacity is not null)
|
||||
{
|
||||
Console.WriteLine(
|
||||
@@ -1283,7 +1308,16 @@ static Task<SceneCatalogProbeResult> CatalogScenesAsync(SceneCatalogOptions opti
|
||||
.EnumerateFiles(options.RootPath, "*.tscn", SearchOption.AllDirectories)
|
||||
.Where(path => string.IsNullOrWhiteSpace(options.SceneFilter) ||
|
||||
path.Contains(options.SceneFilter, StringComparison.OrdinalIgnoreCase))
|
||||
.OrderBy(path => path, StringComparer.OrdinalIgnoreCase)
|
||||
.Select(path => new
|
||||
{
|
||||
Path = path,
|
||||
RelativePath = Path.GetRelativePath(options.RootPath, path)
|
||||
})
|
||||
.OrderBy(item => item.RelativePath.Count(character =>
|
||||
character == Path.DirectorySeparatorChar ||
|
||||
character == Path.AltDirectorySeparatorChar))
|
||||
.ThenBy(item => item.RelativePath, StringComparer.OrdinalIgnoreCase)
|
||||
.Select(item => item.Path)
|
||||
.Take(options.MaxScenes ?? int.MaxValue)
|
||||
.ToArray();
|
||||
|
||||
@@ -2309,142 +2343,7 @@ static Task<SceneValidationProbeResult> ValidateSceneOperationsAsync(SceneValida
|
||||
|
||||
foreach (var operation in operations)
|
||||
{
|
||||
Console.WriteLine($"[VALIDATE] {operation.Method} object={operation.ObjectName}");
|
||||
var sceneObject = scene.GetObject(operation.ObjectName);
|
||||
if (sceneObject is null)
|
||||
{
|
||||
results.Add(new SceneOperationValidationResult(
|
||||
operation.ObjectName,
|
||||
operation.Method,
|
||||
DescribeOperationPayload(operation),
|
||||
"OBJECT_NOT_FOUND",
|
||||
"scene.GetObject returned null."));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (string.Equals(operation.Method, "SetCounterNumberKey", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (sceneObject is not IKACounter counter)
|
||||
{
|
||||
results.Add(new SceneOperationValidationResult(
|
||||
operation.ObjectName,
|
||||
operation.Method,
|
||||
DescribeOperationPayload(operation),
|
||||
"NOT_A_COUNTER",
|
||||
"Object does not implement IKACounter."));
|
||||
continue;
|
||||
}
|
||||
|
||||
handler.ResetCounterNumberKeyTask();
|
||||
counter.SetCounterNumberKey(operation.KeyIndex, operation.Number);
|
||||
if (!WaitForTaskWithMessagePump(handler.CounterNumberKeyTask, options.Connection.Timeout))
|
||||
{
|
||||
results.Add(new SceneOperationValidationResult(
|
||||
operation.ObjectName,
|
||||
operation.Method,
|
||||
DescribeOperationPayload(operation),
|
||||
"TIMEOUT",
|
||||
"OnSetCounterNumberKey timed out."));
|
||||
continue;
|
||||
}
|
||||
|
||||
var callbackResult = handler.CounterNumberKeyTask.Result;
|
||||
results.Add(new SceneOperationValidationResult(
|
||||
operation.ObjectName,
|
||||
operation.Method,
|
||||
DescribeOperationPayload(operation),
|
||||
callbackResult.ToString(),
|
||||
string.Empty));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (string.Equals(operation.Method, "SetVisible", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
handler.ResetVisibleTask();
|
||||
sceneObject.SetVisible(operation.Visible ? 1 : 0);
|
||||
if (!WaitForTaskWithMessagePump(handler.VisibleTask, options.Connection.Timeout))
|
||||
{
|
||||
results.Add(new SceneOperationValidationResult(
|
||||
operation.ObjectName,
|
||||
operation.Method,
|
||||
DescribeOperationPayload(operation),
|
||||
"TIMEOUT",
|
||||
"OnSetVisible timed out."));
|
||||
continue;
|
||||
}
|
||||
|
||||
var callbackResult = handler.VisibleTask.Result;
|
||||
results.Add(new SceneOperationValidationResult(
|
||||
operation.ObjectName,
|
||||
operation.Method,
|
||||
DescribeOperationPayload(operation),
|
||||
callbackResult.ToString(),
|
||||
string.Empty));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (string.Equals(operation.Method, "SetStyleColor", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (sceneObject is not IKAStyle style)
|
||||
{
|
||||
results.Add(new SceneOperationValidationResult(
|
||||
operation.ObjectName,
|
||||
operation.Method,
|
||||
DescribeOperationPayload(operation),
|
||||
"NOT_A_STYLE_OBJECT",
|
||||
"Object does not implement IKAStyle."));
|
||||
continue;
|
||||
}
|
||||
|
||||
handler.ResetStyleColorTask();
|
||||
style.SetStyleColor(
|
||||
ParseStyleType(operation.StyleType),
|
||||
operation.Order,
|
||||
operation.R,
|
||||
operation.G,
|
||||
operation.B,
|
||||
operation.A);
|
||||
if (!WaitForTaskWithMessagePump(handler.StyleColorTask, options.Connection.Timeout))
|
||||
{
|
||||
results.Add(new SceneOperationValidationResult(
|
||||
operation.ObjectName,
|
||||
operation.Method,
|
||||
DescribeOperationPayload(operation),
|
||||
"TIMEOUT",
|
||||
"OnSetStyleColor timed out."));
|
||||
continue;
|
||||
}
|
||||
|
||||
var callbackResult = handler.StyleColorTask.Result;
|
||||
results.Add(new SceneOperationValidationResult(
|
||||
operation.ObjectName,
|
||||
operation.Method,
|
||||
DescribeOperationPayload(operation),
|
||||
callbackResult.ToString(),
|
||||
string.Empty));
|
||||
continue;
|
||||
}
|
||||
|
||||
handler.ResetSetValueTask();
|
||||
sceneObject.SetValue(operation.Value ?? string.Empty);
|
||||
if (!WaitForTaskWithMessagePump(handler.SetValueTask, options.Connection.Timeout))
|
||||
{
|
||||
results.Add(new SceneOperationValidationResult(
|
||||
operation.ObjectName,
|
||||
operation.Method,
|
||||
DescribeOperationPayload(operation),
|
||||
"TIMEOUT",
|
||||
"OnSetValue timed out."));
|
||||
continue;
|
||||
}
|
||||
|
||||
var setValueResult = handler.SetValueTask.Result;
|
||||
results.Add(new SceneOperationValidationResult(
|
||||
operation.ObjectName,
|
||||
operation.Method,
|
||||
DescribeOperationPayload(operation),
|
||||
setValueResult.ToString(),
|
||||
string.Empty));
|
||||
results.Add(ApplySceneOperation(handler, scene, operation, options.Connection.Timeout));
|
||||
}
|
||||
|
||||
WriteSceneValidationMarkdown(options, results);
|
||||
@@ -2532,7 +2431,16 @@ static Task<FolderInspectionProbeResult> InspectTscnFolderAsync(FolderInspection
|
||||
.EnumerateFiles(options.RootPath, "*.tscn", SearchOption.AllDirectories)
|
||||
.Where(path => string.IsNullOrWhiteSpace(options.SceneFilter) ||
|
||||
path.Contains(options.SceneFilter, StringComparison.OrdinalIgnoreCase))
|
||||
.OrderBy(path => path, StringComparer.OrdinalIgnoreCase)
|
||||
.Select(path => new
|
||||
{
|
||||
Path = path,
|
||||
RelativePath = Path.GetRelativePath(options.RootPath, path)
|
||||
})
|
||||
.OrderBy(item => item.RelativePath.Count(character =>
|
||||
character == Path.DirectorySeparatorChar ||
|
||||
character == Path.AltDirectorySeparatorChar))
|
||||
.ThenBy(item => item.RelativePath, StringComparer.OrdinalIgnoreCase)
|
||||
.Select(item => item.Path)
|
||||
.Take(options.MaxScenes ?? int.MaxValue)
|
||||
.ToArray();
|
||||
|
||||
@@ -2865,7 +2773,12 @@ static void WriteFolderInspectionMarkdown(
|
||||
|
||||
static List<SceneValidationOperation> LoadValidationOperations(SceneValidationOptions options)
|
||||
{
|
||||
var json = File.ReadAllText(options.OperationsPath);
|
||||
return LoadSceneOperations(options.ScenePath, options.OperationsPath);
|
||||
}
|
||||
|
||||
static List<SceneValidationOperation> LoadSceneOperations(string scenePath, string operationsPath)
|
||||
{
|
||||
var json = File.ReadAllText(operationsPath);
|
||||
var operations = JsonSerializer.Deserialize<List<SceneValidationOperation>>(json, new JsonSerializerOptions
|
||||
{
|
||||
PropertyNameCaseInsensitive = true
|
||||
@@ -2875,13 +2788,143 @@ static List<SceneValidationOperation> LoadValidationOperations(SceneValidationOp
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(operation.Value))
|
||||
{
|
||||
operation.Value = operation.Value.Replace("${SCENE_DIR}", Path.GetDirectoryName(options.ScenePath) ?? string.Empty, StringComparison.Ordinal);
|
||||
operation.Value = operation.Value.Replace("${SCENE_DIR}", Path.GetDirectoryName(scenePath) ?? string.Empty, StringComparison.Ordinal);
|
||||
}
|
||||
}
|
||||
|
||||
return operations;
|
||||
}
|
||||
|
||||
static SceneOperationValidationResult ApplySceneOperation(
|
||||
ProbeEventHandler handler,
|
||||
IKAScene scene,
|
||||
SceneValidationOperation operation,
|
||||
TimeSpan timeout)
|
||||
{
|
||||
Console.WriteLine($"[VALIDATE] {operation.Method} object={operation.ObjectName}");
|
||||
var sceneObject = scene.GetObject(operation.ObjectName);
|
||||
if (sceneObject is null)
|
||||
{
|
||||
return new SceneOperationValidationResult(
|
||||
operation.ObjectName,
|
||||
operation.Method,
|
||||
DescribeOperationPayload(operation),
|
||||
"OBJECT_NOT_FOUND",
|
||||
"scene.GetObject returned null.");
|
||||
}
|
||||
|
||||
if (string.Equals(operation.Method, "SetCounterNumberKey", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (sceneObject is not IKACounter counter)
|
||||
{
|
||||
return new SceneOperationValidationResult(
|
||||
operation.ObjectName,
|
||||
operation.Method,
|
||||
DescribeOperationPayload(operation),
|
||||
"NOT_A_COUNTER",
|
||||
"Object does not implement IKACounter.");
|
||||
}
|
||||
|
||||
handler.ResetCounterNumberKeyTask();
|
||||
counter.SetCounterNumberKey(operation.KeyIndex, operation.Number);
|
||||
if (!WaitForTaskWithMessagePump(handler.CounterNumberKeyTask, timeout))
|
||||
{
|
||||
return new SceneOperationValidationResult(
|
||||
operation.ObjectName,
|
||||
operation.Method,
|
||||
DescribeOperationPayload(operation),
|
||||
"TIMEOUT",
|
||||
"OnSetCounterNumberKey timed out.");
|
||||
}
|
||||
|
||||
return new SceneOperationValidationResult(
|
||||
operation.ObjectName,
|
||||
operation.Method,
|
||||
DescribeOperationPayload(operation),
|
||||
handler.CounterNumberKeyTask.Result.ToString(),
|
||||
string.Empty);
|
||||
}
|
||||
|
||||
if (string.Equals(operation.Method, "SetVisible", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
handler.ResetVisibleTask();
|
||||
sceneObject.SetVisible(operation.Visible ? 1 : 0);
|
||||
if (!WaitForTaskWithMessagePump(handler.VisibleTask, timeout))
|
||||
{
|
||||
return new SceneOperationValidationResult(
|
||||
operation.ObjectName,
|
||||
operation.Method,
|
||||
DescribeOperationPayload(operation),
|
||||
"TIMEOUT",
|
||||
"OnSetVisible timed out.");
|
||||
}
|
||||
|
||||
return new SceneOperationValidationResult(
|
||||
operation.ObjectName,
|
||||
operation.Method,
|
||||
DescribeOperationPayload(operation),
|
||||
handler.VisibleTask.Result.ToString(),
|
||||
string.Empty);
|
||||
}
|
||||
|
||||
if (string.Equals(operation.Method, "SetStyleColor", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (sceneObject is not IKAStyle style)
|
||||
{
|
||||
return new SceneOperationValidationResult(
|
||||
operation.ObjectName,
|
||||
operation.Method,
|
||||
DescribeOperationPayload(operation),
|
||||
"NOT_A_STYLE_OBJECT",
|
||||
"Object does not implement IKAStyle.");
|
||||
}
|
||||
|
||||
handler.ResetStyleColorTask();
|
||||
style.SetStyleColor(
|
||||
ParseStyleType(operation.StyleType),
|
||||
operation.Order,
|
||||
operation.R,
|
||||
operation.G,
|
||||
operation.B,
|
||||
operation.A);
|
||||
if (!WaitForTaskWithMessagePump(handler.StyleColorTask, timeout))
|
||||
{
|
||||
return new SceneOperationValidationResult(
|
||||
operation.ObjectName,
|
||||
operation.Method,
|
||||
DescribeOperationPayload(operation),
|
||||
"TIMEOUT",
|
||||
"OnSetStyleColor timed out.");
|
||||
}
|
||||
|
||||
return new SceneOperationValidationResult(
|
||||
operation.ObjectName,
|
||||
operation.Method,
|
||||
DescribeOperationPayload(operation),
|
||||
handler.StyleColorTask.Result.ToString(),
|
||||
string.Empty);
|
||||
}
|
||||
|
||||
handler.ResetSetValueTask();
|
||||
sceneObject.SetValue(operation.Value ?? string.Empty);
|
||||
if (!WaitForTaskWithMessagePump(handler.SetValueTask, timeout))
|
||||
{
|
||||
return new SceneOperationValidationResult(
|
||||
operation.ObjectName,
|
||||
operation.Method,
|
||||
DescribeOperationPayload(operation),
|
||||
"TIMEOUT",
|
||||
"OnSetValue timed out.");
|
||||
}
|
||||
|
||||
return new SceneOperationValidationResult(
|
||||
operation.ObjectName,
|
||||
operation.Method,
|
||||
DescribeOperationPayload(operation),
|
||||
handler.SetValueTask.Result.ToString(),
|
||||
string.Empty);
|
||||
}
|
||||
|
||||
static string DescribeOperationPayload(SceneValidationOperation operation)
|
||||
{
|
||||
if (string.Equals(operation.Method, "SetVisible", StringComparison.OrdinalIgnoreCase))
|
||||
@@ -3393,6 +3436,7 @@ internal sealed record SaveSceneImageOptions(
|
||||
bool? VisibleObjectValue,
|
||||
VariableNameUpdate? VariableName,
|
||||
CloneObjectUpdate? CloneObject,
|
||||
string? OperationsPath,
|
||||
MaterialOpacityUpdate? MaterialOpacity,
|
||||
SizeUpdate? Size,
|
||||
PositionUpdate? Position,
|
||||
@@ -3419,6 +3463,7 @@ internal sealed record SaveSceneImageOptions(
|
||||
string? variableNameValue = null;
|
||||
string? cloneSourceObjectName = null;
|
||||
string? cloneVariableName = null;
|
||||
string? operationsPath = null;
|
||||
string? materialOpacityObjectName = null;
|
||||
float? materialOpacityValue = null;
|
||||
string? sizeObjectName = null;
|
||||
@@ -3481,6 +3526,9 @@ internal sealed record SaveSceneImageOptions(
|
||||
case "--clone-name" when index + 1 < args.Length:
|
||||
cloneVariableName = args[++index];
|
||||
break;
|
||||
case "--operations" when index + 1 < args.Length:
|
||||
operationsPath = args[++index];
|
||||
break;
|
||||
case "--material-opacity-object" when index + 1 < args.Length:
|
||||
materialOpacityObjectName = args[++index];
|
||||
break;
|
||||
@@ -3558,6 +3606,9 @@ internal sealed record SaveSceneImageOptions(
|
||||
|
||||
scenePath = Path.GetFullPath(scenePath);
|
||||
outputPath = Path.GetFullPath(outputPath);
|
||||
operationsPath = string.IsNullOrWhiteSpace(operationsPath)
|
||||
? null
|
||||
: Path.GetFullPath(operationsPath);
|
||||
sceneAlias ??= Path.GetFileNameWithoutExtension(scenePath);
|
||||
return new SaveSceneImageOptions(
|
||||
connection,
|
||||
@@ -3573,6 +3624,7 @@ internal sealed record SaveSceneImageOptions(
|
||||
visibleObjectValue,
|
||||
ParseVariableName(variableNameObjectName, variableNameValue),
|
||||
ParseCloneObject(cloneSourceObjectName, cloneVariableName),
|
||||
operationsPath,
|
||||
ParseMaterialOpacity(materialOpacityObjectName, materialOpacityValue),
|
||||
ParseSize(sizeObjectName, sizeRaw),
|
||||
ParsePosition(positionObjectName, positionRaw),
|
||||
@@ -3857,7 +3909,7 @@ internal sealed record SceneCatalogOptions(
|
||||
switch (args[index])
|
||||
{
|
||||
case "--root" when index + 1 < args.Length:
|
||||
index++;
|
||||
rootPath = args[++index];
|
||||
break;
|
||||
case "--output" when index + 1 < args.Length:
|
||||
outputPath = args[++index];
|
||||
@@ -4195,7 +4247,7 @@ internal sealed record FolderInspectionOptions(ProbeOptions Connection, string R
|
||||
switch (args[index])
|
||||
{
|
||||
case "--root" when index + 1 < args.Length:
|
||||
index++;
|
||||
rootPath = args[++index];
|
||||
break;
|
||||
case "--output" when index + 1 < args.Length:
|
||||
outputPath = args[++index];
|
||||
|
||||
Reference in New Issue
Block a user