Files
Shigure/Runtime/StateBuilder.cs
waynebian01 5a00da85d5 Refactor and implement runtime session management
- Removed the UnitSelector class from UI and added a new UnitSelector class in Modules.
- Introduced RuntimeSessionCoordinator to manage runtime sessions, ensuring safe concurrent operations.
- Created ShigureRuntimeFactory to handle the creation of ShigureRuntime instances.
- Added WindowsTriggerKeyState and WindowsVirtualKeyMap for handling key states and virtual key mappings.
- Implemented IKeymapResolver interface for key mapping resolution.
- Established runtime dependencies with interfaces for screen scanning, state building, logic evaluation, and key output.
2026-08-06 01:17:28 +08:00

149 lines
5.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Text.Json.Nodes;
namespace Shigure;
public sealed class StateBuilder : IRuntimeStateBuilder
{
private readonly ConfigService _config;
public StateBuilder(ConfigService config)
{
_config = config;
}
public GameState Build(
IReadOnlyDictionary<int, int> rowData,
IReadOnlyDictionary<int, int> barData,
IReadOnlyDictionary<int, int>? healAbsorbData = null)
{
var classId = rowData.TryGetValue(2, out var cid) ? cid : 0;
var specId = rowData.TryGetValue(3, out var sid) ? sid : 0;
var stateConfig = _config.BuildStateConfig(classId, specId);
var result = new Dictionary<string, object?>();
healAbsorbData ??= new Dictionary<int, int>();
foreach (var (key, node) in stateConfig)
{
if (key is "group" or "spells" or "auras" || node is not JsonObject field || !field.ContainsKey("step"))
{
continue;
}
result[key] = ConvertRawValue(ResolveRaw(field, rowData, barData), JsonHelpers.GetString(JsonHelpers.Get(field, "type")));
}
if (JsonHelpers.Get(stateConfig, "spells") is JsonObject spellsConfig)
{
result["spells"] = BuildFieldMap(spellsConfig, rowData, barData);
}
if (JsonHelpers.Get(stateConfig, "auras") is JsonObject aurasConfig)
{
result["auras"] = BuildFieldMap(aurasConfig, rowData, barData);
}
if (JsonHelpers.Get(stateConfig, "group") is JsonObject groupConfig)
{
var group = BuildGroup(groupConfig, rowData, barData, healAbsorbData);
result["group"] = group;
}
return new GameState(result);
}
private static Dictionary<string, object?> BuildFieldMap(
JsonObject fieldsConfig,
IReadOnlyDictionary<int, int> rowData,
IReadOnlyDictionary<int, int> barData)
{
var values = new Dictionary<string, object?>();
foreach (var (fieldName, node) in fieldsConfig)
{
if (node is not JsonObject field || !field.ContainsKey("step"))
{
continue;
}
values[fieldName] = ConvertRawValue(ResolveRaw(field, rowData, barData), JsonHelpers.GetString(JsonHelpers.Get(field, "type")));
}
return values;
}
private static Dictionary<string, IReadOnlyDictionary<string, object?>> BuildGroup(
JsonObject groupConfig,
IReadOnlyDictionary<int, int> rowData,
IReadOnlyDictionary<int, int> barData,
IReadOnlyDictionary<int, int> healAbsorbData)
{
var start = JsonHelpers.GetInt(JsonHelpers.Get(groupConfig, "start")) ?? 26;
var numParams = JsonHelpers.GetInt(JsonHelpers.Get(groupConfig, "num")) ?? 5;
var group = new Dictionary<string, IReadOnlyDictionary<string, object?>>();
for (var i = 1; i <= 30; i++)
{
var baseStep = start + (i - 1) * numParams;
var sub = new Dictionary<string, object?>();
foreach (var (fieldName, node) in groupConfig)
{
if (fieldName is "start" or "num" || node is not JsonObject field || !field.ContainsKey("step"))
{
continue;
}
int? raw;
var stepNode = JsonHelpers.Get(field, "step");
if (JsonHelpers.GetString(stepNode) == "bar")
{
raw = ResolveRaw(field, rowData, barData);
}
else
{
var relStep = JsonHelpers.GetInt(stepNode);
raw = relStep is null
? null
: rowData.TryGetValue(baseStep + relStep.Value, out var rawValue) ? rawValue : null;
}
sub[fieldName] = ConvertRawValue(raw, JsonHelpers.GetString(JsonHelpers.Get(field, "type")));
}
// 治疗吸收来自网格扫描:白块右侧像素的 B=单位编号G-1=吸收值。
// 插件像素里的生命值含吸收盾,这里折算为真实生命:生命值 -= 治疗吸收。
var absorb = healAbsorbData.TryGetValue(i, out var absorbValue) ? absorbValue : 0;
sub["治疗吸收"] = absorb;
if (absorb != 0 && sub.TryGetValue("生命值", out var healthObj) && healthObj is int health)
{
sub["生命值"] = Math.Max(0, health - absorb);
}
group[i.ToString()] = sub;
}
return group;
}
private static int? ResolveRaw(JsonObject field, IReadOnlyDictionary<int, int> rowData, IReadOnlyDictionary<int, int> barData)
{
var stepNode = JsonHelpers.Get(field, "step");
if (JsonHelpers.GetString(stepNode) == "bar")
{
var barIndex = JsonHelpers.GetInt(JsonHelpers.Get(field, "bar"));
return barIndex is not null && barData.TryGetValue(barIndex.Value, out var barValue) ? barValue : null;
}
var step = JsonHelpers.GetInt(stepNode);
return step is not null && rowData.TryGetValue(step.Value, out var value) ? value : null;
}
private static object ConvertRawValue(int? raw, string? type)
{
return type switch
{
"bool" => raw.GetValueOrDefault() != 0,
"string" => raw?.ToString() ?? string.Empty,
_ => raw.GetValueOrDefault()
};
}
}