diff --git a/src/MaaFramework.Binding.Extensions/Notification/NotificationDetail.cs b/src/MaaFramework.Binding.Extensions/Notification/NotificationDetail.cs
index 7ca4c73..b2e3296 100644
--- a/src/MaaFramework.Binding.Extensions/Notification/NotificationDetail.cs
+++ b/src/MaaFramework.Binding.Extensions/Notification/NotificationDetail.cs
@@ -1,51 +1,84 @@
-using System.Text.Json;
-using System.Text.Json.Serialization;
-
-namespace MaaFramework.Binding.Notification;
-
-///
-public record ResourceLoadingDetail(
- [property: JsonPropertyName("res_id")] int ResourceId,
- [property: JsonPropertyName("hash")] string Hash,
- [property: JsonPropertyName("path")] string Path
-);
-
-///
-public record ControllerActionDetail(
- [property: JsonPropertyName("ctrl_id")] int ControllerId,
- [property: JsonPropertyName("uuid")] string Uuid,
- [property: JsonPropertyName("action")] string Action,
- [property: JsonPropertyName("param")] JsonElement Param
-);
-
-///
-public record TaskerTaskDetail(
- [property: JsonPropertyName("task_id")] int TaskId,
- [property: JsonPropertyName("entry")] string Entry,
- [property: JsonPropertyName("uuid")] string Uuid,
- [property: JsonPropertyName("hash")] string Hash
-);
-
-///
-public record NodeNextListDetail(
- [property: JsonPropertyName("task_id")] int TaskId,
- [property: JsonPropertyName("name")] string Name,
- [property: JsonPropertyName("list")] IReadOnlyList NextList,
- [property: JsonPropertyName("focus")] JsonElement? Focus
-);
-
-///
-public record NodeRecognitionDetail(
- [property: JsonPropertyName("task_id")] int TaskId,
- [property: JsonPropertyName("reco_id")] int RecognitionId,
- [property: JsonPropertyName("name")] string Name,
- [property: JsonPropertyName("focus")] JsonElement? Focus
-);
-
-///
-public record NodeActionDetail(
- [property: JsonPropertyName("task_id")] int TaskId,
- [property: JsonPropertyName("action_id")] int ActionId,
- [property: JsonPropertyName("name")] string Name,
- [property: JsonPropertyName("focus")] JsonElement? Focus
-);
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace MaaFramework.Binding.Notification;
+
+///
+public record ResourceLoadingDetail(
+ [property: JsonPropertyName("res_id")] int ResourceId,
+ [property: JsonPropertyName("hash")] string Hash,
+ [property: JsonPropertyName("path")] string Path
+);
+
+///
+public record ControllerActionDetail(
+ [property: JsonPropertyName("ctrl_id")] int ControllerId,
+ [property: JsonPropertyName("uuid")] string Uuid,
+ [property: JsonPropertyName("action")] string Action,
+ [property: JsonPropertyName("param")] JsonElement Param
+);
+
+///
+public record TaskerTaskDetail(
+ [property: JsonPropertyName("task_id")] int TaskId,
+ [property: JsonPropertyName("entry")] string Entry,
+ [property: JsonPropertyName("uuid")] string Uuid,
+ [property: JsonPropertyName("hash")] string Hash
+);
+
+///
+public record NodePipelineNodeDetail(
+ [property: JsonPropertyName("task_id")] int TaskId,
+ [property: JsonPropertyName("node_id")] int NodeId,
+ [property: JsonPropertyName("name")] string Name,
+ [property: JsonPropertyName("focus")] JsonElement? Focus
+);
+
+///
+public record NodeRecognitionNodeDetail(
+ [property: JsonPropertyName("task_id")] int TaskId,
+ [property: JsonPropertyName("node_id")] int NodeId,
+ [property: JsonPropertyName("name")] string Name,
+ [property: JsonPropertyName("focus")] JsonElement? Focus
+);
+
+///
+public record NodeActionNodeDetail(
+ [property: JsonPropertyName("task_id")] int TaskId,
+ [property: JsonPropertyName("node_id")] int NodeId,
+ [property: JsonPropertyName("name")] string Name,
+ [property: JsonPropertyName("focus")] JsonElement? Focus
+);
+
+///
+/// Represents an item in the next list.
+///
+public record NodeAttr(
+ [property: JsonPropertyName("name")] string Name,
+ [property: JsonPropertyName("jump_back")] bool JumpBack,
+ [property: JsonPropertyName("anchor")] bool Anchor
+);
+
+///
+public record NodeNextListDetail(
+ [property: JsonPropertyName("task_id")] int TaskId,
+ [property: JsonPropertyName("name")] string Name,
+ [property: JsonPropertyName("list")] IReadOnlyList NextList,
+ [property: JsonPropertyName("focus")] JsonElement? Focus
+);
+
+///
+public record NodeRecognitionDetail(
+ [property: JsonPropertyName("task_id")] int TaskId,
+ [property: JsonPropertyName("reco_id")] int RecognitionId,
+ [property: JsonPropertyName("name")] string Name,
+ [property: JsonPropertyName("focus")] JsonElement? Focus
+);
+
+///
+public record NodeActionDetail(
+ [property: JsonPropertyName("task_id")] int TaskId,
+ [property: JsonPropertyName("action_id")] int ActionId,
+ [property: JsonPropertyName("name")] string Name,
+ [property: JsonPropertyName("focus")] JsonElement? Focus
+);
diff --git a/src/MaaFramework.Binding.Extensions/Notification/NotificationDetailContext.cs b/src/MaaFramework.Binding.Extensions/Notification/NotificationDetailContext.cs
index 9c480f7..c3b82d6 100644
--- a/src/MaaFramework.Binding.Extensions/Notification/NotificationDetailContext.cs
+++ b/src/MaaFramework.Binding.Extensions/Notification/NotificationDetailContext.cs
@@ -1,12 +1,16 @@
-using System.Text.Json.Serialization;
-
-namespace MaaFramework.Binding.Notification;
-
-///
-[JsonSerializable(typeof(ResourceLoadingDetail))]
-[JsonSerializable(typeof(ControllerActionDetail))]
-[JsonSerializable(typeof(TaskerTaskDetail))]
-[JsonSerializable(typeof(NodeNextListDetail))]
-[JsonSerializable(typeof(NodeRecognitionDetail))]
-[JsonSerializable(typeof(NodeActionDetail))]
-public partial class NotificationDetailContext : JsonSerializerContext;
+using System.Text.Json.Serialization;
+
+namespace MaaFramework.Binding.Notification;
+
+///
+[JsonSerializable(typeof(ResourceLoadingDetail))]
+[JsonSerializable(typeof(ControllerActionDetail))]
+[JsonSerializable(typeof(TaskerTaskDetail))]
+[JsonSerializable(typeof(NodePipelineNodeDetail))]
+[JsonSerializable(typeof(NodeRecognitionNodeDetail))]
+[JsonSerializable(typeof(NodeActionNodeDetail))]
+[JsonSerializable(typeof(NodeAttr))]
+[JsonSerializable(typeof(NodeNextListDetail))]
+[JsonSerializable(typeof(NodeRecognitionDetail))]
+[JsonSerializable(typeof(NodeActionDetail))]
+public partial class NotificationDetailContext : JsonSerializerContext;
diff --git a/src/MaaFramework.Binding.Extensions/Notification/NotificationHandler.cs b/src/MaaFramework.Binding.Extensions/Notification/NotificationHandler.cs
index a37bd5f..8ede430 100644
--- a/src/MaaFramework.Binding.Extensions/Notification/NotificationHandler.cs
+++ b/src/MaaFramework.Binding.Extensions/Notification/NotificationHandler.cs
@@ -21,6 +21,9 @@ public static class NotificationHandlerExtensions
{
MaaMsg.Resource.Loading.Starting
or MaaMsg.Controller.Action.Starting
+ or MaaMsg.Node.PipelineNode.Starting
+ or MaaMsg.Node.RecognitionNode.Starting
+ or MaaMsg.Node.ActionNode.Starting
or MaaMsg.Node.Action.Starting
or MaaMsg.Node.NextList.Starting
or MaaMsg.Node.Recognition.Starting
@@ -29,6 +32,9 @@ or MaaMsg.Tasker.Task.Starting
MaaMsg.Resource.Loading.Succeeded
or MaaMsg.Controller.Action.Succeeded
+ or MaaMsg.Node.PipelineNode.Succeeded
+ or MaaMsg.Node.RecognitionNode.Succeeded
+ or MaaMsg.Node.ActionNode.Succeeded
or MaaMsg.Node.Action.Succeeded
or MaaMsg.Node.NextList.Succeeded
or MaaMsg.Node.Recognition.Succeeded
@@ -37,6 +43,9 @@ or MaaMsg.Tasker.Task.Succeeded
MaaMsg.Resource.Loading.Failed
or MaaMsg.Controller.Action.Failed
+ or MaaMsg.Node.PipelineNode.Failed
+ or MaaMsg.Node.RecognitionNode.Failed
+ or MaaMsg.Node.ActionNode.Failed
or MaaMsg.Node.Action.Failed
or MaaMsg.Node.NextList.Failed
or MaaMsg.Node.Recognition.Failed
@@ -102,5 +111,17 @@ public static EventHandler ToCallback(this NotificationHan
///
public static EventHandler ToCallback(this NotificationHandler notify)
=> notify.ToCallback(MaaMsg.Node.Action.Prefix);
+
+ ///
+ public static EventHandler ToCallback(this NotificationHandler notify)
+ => notify.ToCallback(MaaMsg.Node.PipelineNode.Prefix);
+
+ ///
+ public static EventHandler ToCallback(this NotificationHandler notify)
+ => notify.ToCallback(MaaMsg.Node.RecognitionNode.Prefix);
+
+ ///
+ public static EventHandler ToCallback(this NotificationHandler notify)
+ => notify.ToCallback(MaaMsg.Node.ActionNode.Prefix);
}
diff --git a/src/MaaFramework.Binding.Extensions/Notification/NotificationHandlerRegistry.cs b/src/MaaFramework.Binding.Extensions/Notification/NotificationHandlerRegistry.cs
index 19a0f3d..fe26bb6 100644
--- a/src/MaaFramework.Binding.Extensions/Notification/NotificationHandlerRegistry.cs
+++ b/src/MaaFramework.Binding.Extensions/Notification/NotificationHandlerRegistry.cs
@@ -45,6 +45,24 @@ public void OnCallback(object? sender, MaaCallbackEventArgs e)
Tasker.Task.OnSucceeded(sender, e.Details); return;
case MaaMsg.Tasker.Task.Failed:
Tasker.Task.OnFailed(sender, e.Details); return;
+ case MaaMsg.Node.PipelineNode.Starting:
+ Node.PipelineNode.OnStarting(sender, e.Details); return;
+ case MaaMsg.Node.PipelineNode.Succeeded:
+ Node.PipelineNode.OnSucceeded(sender, e.Details); return;
+ case MaaMsg.Node.PipelineNode.Failed:
+ Node.PipelineNode.OnFailed(sender, e.Details); return;
+ case MaaMsg.Node.RecognitionNode.Starting:
+ Node.RecognitionNode.OnStarting(sender, e.Details); return;
+ case MaaMsg.Node.RecognitionNode.Succeeded:
+ Node.RecognitionNode.OnSucceeded(sender, e.Details); return;
+ case MaaMsg.Node.RecognitionNode.Failed:
+ Node.RecognitionNode.OnFailed(sender, e.Details); return;
+ case MaaMsg.Node.ActionNode.Starting:
+ Node.ActionNode.OnStarting(sender, e.Details); return;
+ case MaaMsg.Node.ActionNode.Succeeded:
+ Node.ActionNode.OnSucceeded(sender, e.Details); return;
+ case MaaMsg.Node.ActionNode.Failed:
+ Node.ActionNode.OnFailed(sender, e.Details); return;
case MaaMsg.Node.NextList.Starting:
Node.NextList.OnStarting(sender, e.Details); return;
case MaaMsg.Node.NextList.Succeeded:
@@ -130,6 +148,48 @@ internal void OnFailed(object? sender, string details) => Failed?.Invoke(sender,
public NodeRegistry Node { get; } = new();
public sealed class NodeRegistry
{
+ public PipelineNodeRegistry PipelineNode { get; } = new();
+ public sealed class PipelineNodeRegistry
+ {
+ public event EventHandler? Starting;
+ internal void OnStarting(object? sender, string details) => Starting?.Invoke(sender, JsonSerializer.Deserialize(details,
+ NotificationDetailContext.Default.NodePipelineNodeDetail) ?? throw new InvalidCastException());
+ public event EventHandler? Succeeded;
+ internal void OnSucceeded(object? sender, string details) => Succeeded?.Invoke(sender, JsonSerializer.Deserialize(details,
+ NotificationDetailContext.Default.NodePipelineNodeDetail) ?? throw new InvalidCastException());
+ public event EventHandler? Failed;
+ internal void OnFailed(object? sender, string details) => Failed?.Invoke(sender, JsonSerializer.Deserialize(details,
+ NotificationDetailContext.Default.NodePipelineNodeDetail) ?? throw new InvalidCastException());
+ }
+
+ public RecognitionNodeRegistry RecognitionNode { get; } = new();
+ public sealed class RecognitionNodeRegistry
+ {
+ public event EventHandler? Starting;
+ internal void OnStarting(object? sender, string details) => Starting?.Invoke(sender, JsonSerializer.Deserialize(details,
+ NotificationDetailContext.Default.NodeRecognitionNodeDetail) ?? throw new InvalidCastException());
+ public event EventHandler? Succeeded;
+ internal void OnSucceeded(object? sender, string details) => Succeeded?.Invoke(sender, JsonSerializer.Deserialize(details,
+ NotificationDetailContext.Default.NodeRecognitionNodeDetail) ?? throw new InvalidCastException());
+ public event EventHandler? Failed;
+ internal void OnFailed(object? sender, string details) => Failed?.Invoke(sender, JsonSerializer.Deserialize(details,
+ NotificationDetailContext.Default.NodeRecognitionNodeDetail) ?? throw new InvalidCastException());
+ }
+
+ public ActionNodeRegistry ActionNode { get; } = new();
+ public sealed class ActionNodeRegistry
+ {
+ public event EventHandler? Starting;
+ internal void OnStarting(object? sender, string details) => Starting?.Invoke(sender, JsonSerializer.Deserialize(details,
+ NotificationDetailContext.Default.NodeActionNodeDetail) ?? throw new InvalidCastException());
+ public event EventHandler? Succeeded;
+ internal void OnSucceeded(object? sender, string details) => Succeeded?.Invoke(sender, JsonSerializer.Deserialize(details,
+ NotificationDetailContext.Default.NodeActionNodeDetail) ?? throw new InvalidCastException());
+ public event EventHandler? Failed;
+ internal void OnFailed(object? sender, string details) => Failed?.Invoke(sender, JsonSerializer.Deserialize(details,
+ NotificationDetailContext.Default.NodeActionNodeDetail) ?? throw new InvalidCastException());
+ }
+
public NextListRegistry NextList { get; } = new();
public sealed class NextListRegistry
{
diff --git a/src/MaaFramework.Binding.Native/Interop/AgentClient/MaaAgentClientAPI.cs b/src/MaaFramework.Binding.Native/Interop/AgentClient/MaaAgentClientAPI.cs
index dfcd9a0..e07de6d 100644
--- a/src/MaaFramework.Binding.Native/Interop/AgentClient/MaaAgentClientAPI.cs
+++ b/src/MaaFramework.Binding.Native/Interop/AgentClient/MaaAgentClientAPI.cs
@@ -63,6 +63,14 @@ public static partial class MaaAgentClient
[return: MarshalAs(UnmanagedType.U1)]
public static partial bool MaaAgentClientSetTimeout(MaaAgentClientHandle client, long milliseconds);
+ [LibraryImport("MaaAgentClient", StringMarshalling = StringMarshalling.Utf8)]
+ [return: MarshalAs(UnmanagedType.U1)]
+ public static partial bool MaaAgentClientGetCustomRecognitionList(MaaAgentClientHandle client, MaaStringListBufferHandle buffer);
+
+ [LibraryImport("MaaAgentClient", StringMarshalling = StringMarshalling.Utf8)]
+ [return: MarshalAs(UnmanagedType.U1)]
+ public static partial bool MaaAgentClientGetCustomActionList(MaaAgentClientHandle client, MaaStringListBufferHandle buffer);
+
[Obsolete]
[LibraryImport("MaaAgentClient", StringMarshalling = StringMarshalling.Utf8)]
public static partial MaaAgentClientHandle MaaAgentClientCreate();
diff --git a/src/MaaFramework.Binding.Native/Interop/Framework/Instance/MaaContext.cs b/src/MaaFramework.Binding.Native/Interop/Framework/Instance/MaaContext.cs
index 15fc011..febb5e3 100644
--- a/src/MaaFramework.Binding.Native/Interop/Framework/Instance/MaaContext.cs
+++ b/src/MaaFramework.Binding.Native/Interop/Framework/Instance/MaaContext.cs
@@ -50,4 +50,20 @@ public static partial class MaaContext
[LibraryImport("MaaFramework", StringMarshalling = StringMarshalling.Utf8)]
public static partial MaaContextHandle MaaContextClone(MaaContextHandle context);
+
+ [LibraryImport("MaaFramework", StringMarshalling = StringMarshalling.Utf8)]
+ [return: MarshalAs(UnmanagedType.U1)]
+ public static partial bool MaaContextSetAnchor(MaaContextHandle context, string anchorName, string nodeName);
+
+ [LibraryImport("MaaFramework", StringMarshalling = StringMarshalling.Utf8)]
+ [return: MarshalAs(UnmanagedType.U1)]
+ public static partial bool MaaContextGetAnchor(MaaContextHandle context, string anchorName, MaaStringBufferHandle buffer);
+
+ [LibraryImport("MaaFramework", StringMarshalling = StringMarshalling.Utf8)]
+ [return: MarshalAs(UnmanagedType.U1)]
+ public static partial bool MaaContextGetHitCount(MaaContextHandle context, string nodeName, out MaaSize count);
+
+ [LibraryImport("MaaFramework", StringMarshalling = StringMarshalling.Utf8)]
+ [return: MarshalAs(UnmanagedType.U1)]
+ public static partial bool MaaContextClearHitCount(MaaContextHandle context, string nodeName);
}
diff --git a/src/MaaFramework.Binding.Native/Interop/Framework/Instance/MaaController.cs b/src/MaaFramework.Binding.Native/Interop/Framework/Instance/MaaController.cs
index fcaf5f6..d0384e2 100644
--- a/src/MaaFramework.Binding.Native/Interop/Framework/Instance/MaaController.cs
+++ b/src/MaaFramework.Binding.Native/Interop/Framework/Instance/MaaController.cs
@@ -86,6 +86,9 @@ public static partial class MaaController
[LibraryImport("MaaFramework", StringMarshalling = StringMarshalling.Utf8)]
public static partial MaaCtrlId MaaControllerPostScreencap(MaaControllerHandle ctrl);
+ [LibraryImport("MaaFramework", StringMarshalling = StringMarshalling.Utf8)]
+ public static partial MaaCtrlId MaaControllerPostScroll(MaaControllerHandle ctrl, int dx, int dy);
+
[LibraryImport("MaaFramework", StringMarshalling = StringMarshalling.Utf8)]
public static partial MaaStatus MaaControllerStatus(MaaControllerHandle ctrl, MaaCtrlId id);
diff --git a/src/MaaFramework.Binding.Native/Interop/Framework/Instance/MaaCustomController.cs b/src/MaaFramework.Binding.Native/Interop/Framework/Instance/MaaCustomController.cs
index 44a6bb4..4845707 100644
--- a/src/MaaFramework.Binding.Native/Interop/Framework/Instance/MaaCustomController.cs
+++ b/src/MaaFramework.Binding.Native/Interop/Framework/Instance/MaaCustomController.cs
@@ -108,6 +108,7 @@ private sealed class Delegates(IMaaCustomController managed)
public InputTextDelegate InputText = (string text, nint transArg) => managed.InputText(text);
public KeyDownDelegate KeyDown = (int keycode, nint transArg) => managed.KeyDown(keycode);
public KeyUpDelegate KeyUp = (int keycode, nint transArg) => managed.KeyUp(keycode);
+ public ScrollDelegate Scroll = (int dx, int dy, nint transArg) => managed.Scroll(dx, dy);
};
///
@@ -135,6 +136,7 @@ private sealed class Unmanaged(Delegates delegates)
public nint InputText = Marshal.GetFunctionPointerForDelegate(delegates.InputText);
public nint KeyDown = Marshal.GetFunctionPointerForDelegate(delegates.KeyDown);
public nint KeyUp = Marshal.GetFunctionPointerForDelegate(delegates.KeyUp);
+ public nint Scroll = Marshal.GetFunctionPointerForDelegate(delegates.Scroll);
}
[return: MarshalAs(UnmanagedType.U1)]
@@ -201,4 +203,8 @@ private sealed class Unmanaged(Delegates delegates)
[return: MarshalAs(UnmanagedType.U1)]
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate bool KeyUpDelegate(int keycode, nint transArg);
+
+ [return: MarshalAs(UnmanagedType.U1)]
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ public delegate bool ScrollDelegate(int dx, int dy, nint transArg);
}
diff --git a/src/MaaFramework.Binding.Native/Interop/Framework/Instance/MaaResource.cs b/src/MaaFramework.Binding.Native/Interop/Framework/Instance/MaaResource.cs
index 05141e5..8810c41 100644
--- a/src/MaaFramework.Binding.Native/Interop/Framework/Instance/MaaResource.cs
+++ b/src/MaaFramework.Binding.Native/Interop/Framework/Instance/MaaResource.cs
@@ -100,4 +100,12 @@ public static partial class MaaResource
[LibraryImport("MaaFramework", StringMarshalling = StringMarshalling.Utf8)]
[return: MarshalAs(UnmanagedType.U1)]
public static partial bool MaaResourceGetNodeList(MaaResourceHandle res, MaaStringListBufferHandle buffer);
+
+ [LibraryImport("MaaFramework", StringMarshalling = StringMarshalling.Utf8)]
+ [return: MarshalAs(UnmanagedType.U1)]
+ public static partial bool MaaResourceGetCustomRecognitionList(MaaResourceHandle res, MaaStringListBufferHandle buffer);
+
+ [LibraryImport("MaaFramework", StringMarshalling = StringMarshalling.Utf8)]
+ [return: MarshalAs(UnmanagedType.U1)]
+ public static partial bool MaaResourceGetCustomActionList(MaaResourceHandle res, MaaStringListBufferHandle buffer);
}
diff --git a/src/MaaFramework.Binding.Native/MaaAgentClient.cs b/src/MaaFramework.Binding.Native/MaaAgentClient.cs
index 9c9f570..1e7e0d5 100644
--- a/src/MaaFramework.Binding.Native/MaaAgentClient.cs
+++ b/src/MaaFramework.Binding.Native/MaaAgentClient.cs
@@ -356,4 +356,30 @@ private void KillAndDisposeAgentServerProcess(bool disposing)
_agentServerProcess = null;
}
}
+
+ ///
+ ///
+ /// Wrapper of .
+ ///
+ public IList CustomRecognitionList
+ {
+ get
+ {
+ _ = MaaStringListBuffer.TryGetList(out var list, h => MaaAgentClientGetCustomRecognitionList(Handle, h)).ThrowIfFalse();
+ return list!;
+ }
+ }
+
+ ///
+ ///
+ /// Wrapper of .
+ ///
+ public IList CustomActionList
+ {
+ get
+ {
+ _ = MaaStringListBuffer.TryGetList(out var list, h => MaaAgentClientGetCustomActionList(Handle, h)).ThrowIfFalse();
+ return list!;
+ }
+ }
}
diff --git a/src/MaaFramework.Binding.Native/MaaContext.cs b/src/MaaFramework.Binding.Native/MaaContext.cs
index 5860f3c..7c91fe8 100644
--- a/src/MaaFramework.Binding.Native/MaaContext.cs
+++ b/src/MaaFramework.Binding.Native/MaaContext.cs
@@ -136,4 +136,33 @@ IMaaContext IMaaContext.Clone()
///
public MaaContext Clone()
=> new(MaaContextClone(Handle));
+
+ ///
+ ///
+ /// Wrapper of .
+ ///
+ public bool SetAnchor(string anchorName, string nodeName)
+ => MaaContextSetAnchor(Handle, anchorName, nodeName);
+
+ ///
+ ///
+ /// Wrapper of .
+ ///
+ public bool GetAnchor(string anchorName, [MaybeNullWhen(false)] out string nodeName)
+ => MaaStringBuffer.TryGetValue(out nodeName, buffer
+ => MaaContextGetAnchor(Handle, anchorName, buffer));
+
+ ///
+ ///
+ /// Wrapper of .
+ ///
+ public bool GetHitCount(string nodeName, out ulong count)
+ => MaaContextGetHitCount(Handle, nodeName, out count);
+
+ ///
+ ///
+ /// Wrapper of .
+ ///
+ public bool ClearHitCount(string nodeName)
+ => MaaContextClearHitCount(Handle, nodeName);
}
diff --git a/src/MaaFramework.Binding.Native/MaaController.cs b/src/MaaFramework.Binding.Native/MaaController.cs
index c5ea197..33dac53 100644
--- a/src/MaaFramework.Binding.Native/MaaController.cs
+++ b/src/MaaFramework.Binding.Native/MaaController.cs
@@ -182,6 +182,13 @@ public MaaJob KeyUp(int keyCode)
public MaaJob Screencap()
=> CreateJob(MaaControllerPostScreencap(Handle));
+ ///
+ ///
+ /// Wrapper of .
+ ///
+ public MaaJob Scroll(int dx, int dy)
+ => CreateJob(MaaControllerPostScroll(Handle, dx, dy));
+
///
///
/// Wrapper of .
diff --git a/src/MaaFramework.Binding.Native/MaaGlobal.cs b/src/MaaFramework.Binding.Native/MaaGlobal.cs
index cfdf1ec..dac5df1 100644
--- a/src/MaaFramework.Binding.Native/MaaGlobal.cs
+++ b/src/MaaFramework.Binding.Native/MaaGlobal.cs
@@ -33,7 +33,8 @@ public bool SetOption(GlobalOption opt, T value)
(int vvvv, GlobalOption.StdoutLevel) => vvvv.ToMaaOptionValue(),
(string v, GlobalOption.LogDir) => v.ToMaaOptionValue(),
(bool vvv, GlobalOption.SaveDraw
- or GlobalOption.DebugMode) => vvv.ToMaaOptionValue(),
+ or GlobalOption.DebugMode
+ or GlobalOption.SaveOnError) => vvv.ToMaaOptionValue(),
(LoggingLevel v, GlobalOption.StdoutLevel) => ((int)v).ToMaaOptionValue(),
diff --git a/src/MaaFramework.Binding.Native/MaaResource.cs b/src/MaaFramework.Binding.Native/MaaResource.cs
index 4c8e5a5..47ebce1 100644
--- a/src/MaaFramework.Binding.Native/MaaResource.cs
+++ b/src/MaaFramework.Binding.Native/MaaResource.cs
@@ -344,4 +344,30 @@ public IList NodeList
return list!;
}
}
+
+ ///
+ ///
+ /// Wrapper of .
+ ///
+ public IList CustomRecognitionList
+ {
+ get
+ {
+ _ = MaaStringListBuffer.TryGetList(out var list, h => MaaResourceGetCustomRecognitionList(Handle, h)).ThrowIfFalse();
+ return list!;
+ }
+ }
+
+ ///
+ ///
+ /// Wrapper of .
+ ///
+ public IList CustomActionList
+ {
+ get
+ {
+ _ = MaaStringListBuffer.TryGetList(out var list, h => MaaResourceGetCustomActionList(Handle, h)).ThrowIfFalse();
+ return list!;
+ }
+ }
}
diff --git a/src/MaaFramework.Binding.UnitTests/Test_Custom.cs b/src/MaaFramework.Binding.UnitTests/Test_Custom.cs
index ffa96ac..abfb6d9 100644
--- a/src/MaaFramework.Binding.UnitTests/Test_Custom.cs
+++ b/src/MaaFramework.Binding.UnitTests/Test_Custom.cs
@@ -247,6 +247,8 @@ public bool KeyDown(int keycode)
=> c.KeyDown(keycode).Wait().IsSucceeded();
public bool KeyUp(int keycode)
=> c.KeyUp(keycode).Wait().IsSucceeded();
+ public bool Scroll(int dx, int dy)
+ => c.Scroll(dx, dy).Wait().IsSucceeded();
}
internal sealed class TestInvalidResource : IMaaCustomResource
diff --git a/src/MaaFramework.Binding/Custom/IMaaCustomController.cs b/src/MaaFramework.Binding/Custom/IMaaCustomController.cs
index 56ea141..c3a0d5a 100644
--- a/src/MaaFramework.Binding/Custom/IMaaCustomController.cs
+++ b/src/MaaFramework.Binding/Custom/IMaaCustomController.cs
@@ -37,4 +37,5 @@ public interface IMaaCustomController : IMaaCustomResource, IDisposable
bool InputText(string text);
bool KeyDown(int keycode);
bool KeyUp(int keycode);
+ bool Scroll(int dx, int dy);
}
diff --git a/src/MaaFramework.Binding/Enums/Options/GlobalOption.cs b/src/MaaFramework.Binding/Enums/Options/GlobalOption.cs
index 0e5b77f..897cfee 100644
--- a/src/MaaFramework.Binding/Enums/Options/GlobalOption.cs
+++ b/src/MaaFramework.Binding/Enums/Options/GlobalOption.cs
@@ -44,5 +44,12 @@ public enum GlobalOption : System.Int32
/// value: bool, eg: true; val_size: sizeof(bool)
///
DebugMode = 6,
+ ///
+ /// Whether to save screenshot on error
+ ///
+ ///
+ /// value: bool, eg: true; val_size: sizeof(bool)
+ ///
+ SaveOnError = 7,
}
diff --git a/src/MaaFramework.Binding/IMaaAgentClient.cs b/src/MaaFramework.Binding/IMaaAgentClient.cs
index f6405d6..1d84ec5 100644
--- a/src/MaaFramework.Binding/IMaaAgentClient.cs
+++ b/src/MaaFramework.Binding/IMaaAgentClient.cs
@@ -141,4 +141,14 @@ public interface IMaaAgentClient : IMaaDisposable
///
/// The process is unavailable or not managed by .
Process AgentServerProcess { get; }
+
+ ///
+ /// Gets the list of custom recognitions registered by the agent server.
+ ///
+ IList CustomRecognitionList { get; }
+
+ ///
+ /// Gets the list of custom actions registered by the agent server.
+ ///
+ IList CustomActionList { get; }
}
diff --git a/src/MaaFramework.Binding/IMaaContext.cs b/src/MaaFramework.Binding/IMaaContext.cs
index a4c41aa..ce7f706 100644
--- a/src/MaaFramework.Binding/IMaaContext.cs
+++ b/src/MaaFramework.Binding/IMaaContext.cs
@@ -97,4 +97,35 @@ public interface IMaaContext : ICloneable
///
/// The
new IMaaContext Clone();
+
+ ///
+ /// Sets an anchor to a node.
+ ///
+ /// The anchor name.
+ /// The node name.
+ /// if the operation was executed successfully; otherwise, .
+ bool SetAnchor(string anchorName, string nodeName);
+
+ ///
+ /// Gets the node name from an anchor.
+ ///
+ /// The anchor name.
+ /// The node name.
+ /// if the operation was executed successfully; otherwise, .
+ bool GetAnchor(string anchorName, [MaybeNullWhen(false)] out string nodeName);
+
+ ///
+ /// Gets the hit count of a node.
+ ///
+ /// The node name.
+ /// The hit count.
+ /// if the operation was executed successfully; otherwise, .
+ bool GetHitCount(string nodeName, out ulong count);
+
+ ///
+ /// Clears the hit count of a node.
+ ///
+ /// The node name.
+ /// if the operation was executed successfully; otherwise, .
+ bool ClearHitCount(string nodeName);
}
diff --git a/src/MaaFramework.Binding/IMaaController.cs b/src/MaaFramework.Binding/IMaaController.cs
index ef27524..834c43a 100644
--- a/src/MaaFramework.Binding/IMaaController.cs
+++ b/src/MaaFramework.Binding/IMaaController.cs
@@ -128,6 +128,15 @@ public interface IMaaController : IMaaCommon, IMaaOption, IMaa
/// A screen capture .
MaaJob Screencap();
+ ///
+ /// Posts a scroll action.
+ ///
+ /// The horizontal scroll delta. Positive values scroll right, negative values scroll left.
+ /// The vertical scroll delta. Positive values scroll down, negative values scroll up.
+ /// A scroll .
+ /// Not all controllers support scroll. If not supported, the action will fail.
+ MaaJob Scroll(int dx, int dy);
+
///
/// Gets whether the is connected to the device specified by the constructor.
///
diff --git a/src/MaaFramework.Binding/IMaaResource.cs b/src/MaaFramework.Binding/IMaaResource.cs
index 0d5436e..cd5efce 100644
--- a/src/MaaFramework.Binding/IMaaResource.cs
+++ b/src/MaaFramework.Binding/IMaaResource.cs
@@ -118,4 +118,14 @@ public interface IMaaResource : IMaaCommon, IMaaOption, IMaaDisp
///
/// A if the node list was got successfully; otherwise, .
IList NodeList { get; }
+
+ ///
+ /// Gets the list of registered custom recognitions.
+ ///
+ IList CustomRecognitionList { get; }
+
+ ///
+ /// Gets the list of registered custom actions.
+ ///
+ IList CustomActionList { get; }
}
diff --git a/src/MaaFramework.Binding/MaaMsg.cs b/src/MaaFramework.Binding/MaaMsg.cs
index 4ed7cc1..94b911a 100644
--- a/src/MaaFramework.Binding/MaaMsg.cs
+++ b/src/MaaFramework.Binding/MaaMsg.cs
@@ -136,13 +136,118 @@ public static class Task
}
public static class Node
{
+ public static class PipelineNode
+ {
+ ///
+ /// Message for the pipeline node.
+ ///
+ ///
+ /// details_json: { task_id: number, node_id: number, name: string, focus: any, }
+ ///
+ public const string Starting = "Node.PipelineNode.Starting";
+
+ ///
+ /// Message for the pipeline node.
+ ///
+ ///
+ /// details_json: { task_id: number, node_id: number, name: string, focus: any, }
+ ///
+ public const string Prefix = "Node.PipelineNode";
+
+ ///
+ /// Message for the pipeline node.
+ ///
+ ///
+ /// details_json: { task_id: number, node_id: number, name: string, focus: any, }
+ ///
+ public const string Succeeded = "Node.PipelineNode.Succeeded";
+
+ ///
+ /// Message for the pipeline node.
+ ///
+ ///
+ /// details_json: { task_id: number, node_id: number, name: string, focus: any, }
+ ///
+ public const string Failed = "Node.PipelineNode.Failed";
+
+ }
+ public static class RecognitionNode
+ {
+ ///
+ /// Message for the recognition node.
+ ///
+ ///
+ /// details_json: { task_id: number, node_id: number, name: string, focus: any, }
+ ///
+ public const string Starting = "Node.RecognitionNode.Starting";
+
+ ///
+ /// Message for the recognition node.
+ ///
+ ///
+ /// details_json: { task_id: number, node_id: number, name: string, focus: any, }
+ ///
+ public const string Prefix = "Node.RecognitionNode";
+
+ ///
+ /// Message for the recognition node.
+ ///
+ ///
+ /// details_json: { task_id: number, node_id: number, name: string, focus: any, }
+ ///
+ public const string Succeeded = "Node.RecognitionNode.Succeeded";
+
+ ///
+ /// Message for the recognition node.
+ ///
+ ///
+ /// details_json: { task_id: number, node_id: number, name: string, focus: any, }
+ ///
+ public const string Failed = "Node.RecognitionNode.Failed";
+
+ }
+ public static class ActionNode
+ {
+ ///
+ /// Message for the action node.
+ ///
+ ///
+ /// details_json: { task_id: number, node_id: number, name: string, focus: any, }
+ ///
+ public const string Starting = "Node.ActionNode.Starting";
+
+ ///
+ /// Message for the action node.
+ ///
+ ///
+ /// details_json: { task_id: number, node_id: number, name: string, focus: any, }
+ ///
+ public const string Prefix = "Node.ActionNode";
+
+ ///
+ /// Message for the action node.
+ ///
+ ///
+ /// details_json: { task_id: number, node_id: number, name: string, focus: any, }
+ ///
+ public const string Succeeded = "Node.ActionNode.Succeeded";
+
+ ///
+ /// Message for the action node.
+ ///
+ ///
+ /// details_json: { task_id: number, node_id: number, name: string, focus: any, }
+ ///
+ public const string Failed = "Node.ActionNode.Failed";
+
+ }
public static class NextList
{
///
/// Message for the next list of node.
///
///
- /// details_json: { task_id: number, name: string, list: string[], focus: any, }
+ /// details_json: { task_id: number, name: string, list: [{ name: string, jump_back: boolean, anchor: boolean }, ...], focus: any, }
///
public const string Starting = "Node.NextList.Starting";
@@ -150,7 +255,7 @@ public static class NextList
/// Message for the next list of node.
///
///
- /// details_json: { task_id: number, name: string, list: string[], focus: any, }
+ /// details_json: { task_id: number, name: string, list: [{ name: string, jump_back: boolean, anchor: boolean }, ...], focus: any, }
///
public const string Prefix = "Node.NextList";
@@ -158,7 +263,7 @@ public static class NextList
/// Message for the next list of node.
///
///
- /// details_json: { task_id: number, name: string, list: string[], focus: any, }
+ /// details_json: { task_id: number, name: string, list: [{ name: string, jump_back: boolean, anchor: boolean }, ...], focus: any, }
///
public const string Succeeded = "Node.NextList.Succeeded";
@@ -166,7 +271,7 @@ public static class NextList
/// Message for the next list of node.
///
///
- /// details_json: { task_id: number, name: string, list: string[], focus: any, }
+ /// details_json: { task_id: number, name: string, list: [{ name: string, jump_back: boolean, anchor: boolean }, ...], focus: any, }
///
public const string Failed = "Node.NextList.Failed";