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";