winmr-api/Services/IPCClientService.cs
2026-01-08 21:35:06 +03:00

232 lines
8.7 KiB
C#

using Google.Protobuf;
using Microsoft.Extensions.Options;
using WebmrAPI.Configuration;
using WebmrAPI.Utils;
using WebmrAPI.Utils.Sequences;
using WinIPC.Models;
using WinIPC.Services;
using WinIPC.Utils;
namespace WebmrAPI.Services
{
public sealed class IPCClientService : IPCBaseClientService
{
public IPCClientService(ILogger<IPCClientService> logger, IOptions<AppSettings> appConfigOptions)
: base(logger, appConfigOptions?.Value?.IPCServiceOptions.BasePipeName ?? throw new ArgumentNullException(nameof(appConfigOptions)))
{ }
public async Task<IEnumerable<WindowInfo>> GetWindowInfos(int sessionId, IEnumerable<IntPtr>? hwnds = null)
{
var req = new WindowsRequest();
if (hwnds != null)
{
foreach (var hwnd in hwnds)
{
req.Hwnds.Add((int)hwnd);
}
}
var resp = await SendRequest(sessionId, CommandType.GetWindowsInfo, req).GetResponseAsync();
if (resp != null && resp.Success)
{
return PayloadHandler.ExtractPayload<WindowsResponse>(resp).Data;
}
// TODO log Error
return new List<WindowInfo>();
}
public async Task<byte[]> GetScreenshot(int sessionId, IntPtr hwnd = 0, int x = 0, int y = 0, int width = 0, int height = 0)
{
var req = new ScreenshotRequest()
{
Hwnd = (int)hwnd,
CropPosition = new() { X = x, Y = y },
CropSize = new() { Width = width, Height = height }
};
var resp = await SendRequest(sessionId, CommandType.GetScreenshot, req).GetResponseAsync();
if (resp != null && resp.Success)
{
return PayloadHandler.ExtractPayload<ScreenshotResponse>(resp).Data.ToByteArray();
}
// TODO log Error
return Array.Empty<byte>();
}
public async Task<int> GetPixelColor(int sessionId, IntPtr hwnd = 0, int x = 0, int y = 0)
{
var req = new PixelRequest()
{
Hwnd = (int)hwnd,
PixelPosition = new() { X = x, Y = y }
};
var resp = await SendRequest(sessionId, CommandType.GetPixelColor, req).GetResponseAsync();
if (resp != null && resp.Success)
{
return (int)PayloadHandler.ExtractPayload<PixelResponse>(resp).RgbColor;
}
// TODO log Error
return -1;
}
private IEnumerable<InputAction> GetMouseMovingPath(ISequenceGenerator<Point> pGen, DelayGenerator dGen, ref int nActions)
{
List<InputAction> actions = new();
foreach (var p in pGen)
{
var input = new MouseMoveInput() { Position = new() { X = p.X, Y = p.Y } };
actions.Add(new InputAction()
{
Type = InputType.MouseMoveTo,
DelayMs = (uint)dGen.Next().Value,
Payload = ByteString.CopyFrom(PayloadHandler.Serialize(input))
});
++nActions;
}
return actions;
}
private IEnumerable<InputAction> GetMouseScrollSequence(ScrollAmountGenerator sGen, DelayGenerator dGen, ref int nActions)
{
List<InputAction> actions = new();
foreach (var s in sGen)
{
var input = new ScrollInput() { Offset = s };
actions.Add(new InputAction()
{
Type = InputType.MouseScroll,
DelayMs = (uint)dGen.Next().Value,
Payload = ByteString.CopyFrom(PayloadHandler.Serialize(input))
});
++nActions;
}
return actions;
}
private async Task<int> SendInputActions(int sessionId, IntPtr hwnd, IEnumerable<InputAction> actions, int nActions)
{
var resp = await SendRequest(sessionId, CommandType.InputAction, new InputRequest() { Hwnd = (int)hwnd, Actions = { actions } }).GetResponseAsync();
if (resp != null && resp.Success)
{
return nActions - PayloadHandler.ExtractPayload<InputResponse>(resp).Count;
}
// TODO log Error
return -nActions;
}
public Task<int> MouseMove(int sessionId, ISequenceGenerator<Point> pGen, DelayGenerator dGen, IntPtr hwnd = 0)
{
int nActions = 0;
return SendInputActions(sessionId, hwnd, GetMouseMovingPath(pGen, dGen, ref nActions), nActions);
}
public Task<int> HoldDownAndMouseMove(int sessionId, ISequenceGenerator<Point> pGen, DelayGenerator dGen, Key key, IntPtr hwnd = 0)
{
return HoldDownAndMouseMove(sessionId, pGen, dGen, new KeyShortcut(key), hwnd);
}
public Task<int> HoldDownAndMouseMove(int sessionId, ISequenceGenerator<Point> pGen, DelayGenerator dGen, KeyShortcut sc, IntPtr hwnd = 0)
{
IEnumerable<InputAction> holdDown = sc.GetHoldDownActions(), holdUp = sc.GetHoldUpActions();
int nActions = holdDown.Count() + holdUp.Count();
return SendInputActions(sessionId, hwnd, holdDown.Concat(GetMouseMovingPath(pGen, dGen, ref nActions)).Concat(holdUp), nActions);
}
public Task<int> MouseMoveAndPress(int sessionId, ISequenceGenerator<Point> pGen, DelayGenerator dGen, Key key, IntPtr hwnd = 0)
{
return MouseMoveAndPress(sessionId, pGen, dGen, new KeyShortcut(key), hwnd);
}
public Task<int> MouseMoveAndPress(int sessionId, ISequenceGenerator<Point> pGen, DelayGenerator dGen, KeyShortcut sc, IntPtr hwnd = 0)
{
return MouseMoveAndPress(sessionId, pGen, dGen, new KeyShortcutSequence(sc), hwnd);
}
public Task<int> MouseMoveAndPress(int sessionId, ISequenceGenerator<Point> pGen, DelayGenerator dGen, KeyShortcutSequence seq, IntPtr hwnd = 0)
{
IEnumerable<InputAction> press = seq.GetInputActions();
int nActions = press.Count();
return SendInputActions(sessionId, hwnd, GetMouseMovingPath(pGen, dGen, ref nActions).Concat(press), nActions);
}
public Task<int> MouseScroll(int sessionId, ScrollAmountGenerator sGen, DelayGenerator dGen, IntPtr hwnd = 0)
{
int nActions = 0;
return SendInputActions(sessionId, hwnd, GetMouseScrollSequence(sGen, dGen, ref nActions), nActions);
}
public Task<int> HoldDownAndMouseScroll(int sessionId, ScrollAmountGenerator sGen, DelayGenerator dGen, Key key, IntPtr hwnd = 0)
{
return HoldDownAndMouseScroll(sessionId, sGen, dGen, new KeyShortcut(key), hwnd);
}
public Task<int> HoldDownAndMouseScroll(int sessionId, ScrollAmountGenerator sGen, DelayGenerator dGen, KeyShortcut sc, IntPtr hwnd = 0)
{
IEnumerable<InputAction> holdDown = sc.GetHoldDownActions(), holdUp = sc.GetHoldUpActions();
int nActions = holdDown.Count() + holdUp.Count();
return SendInputActions(sessionId, hwnd, holdDown.Concat(GetMouseScrollSequence(sGen, dGen, ref nActions)).Concat(holdUp), nActions);
}
public Task<int> HoldDown(int sessionId, Key key, IntPtr hwnd = 0)
{
return HoldDown(sessionId, new KeyShortcut(key), hwnd);
}
public Task<int> HoldUp(int sessionId, Key key, IntPtr hwnd = 0)
{
return HoldUp(sessionId, new KeyShortcut(key), hwnd);
}
public Task<int> HoldDown(int sessionId, KeyShortcut sc, IntPtr hwnd = 0)
{
IEnumerable<InputAction> holdDown = sc.GetHoldDownActions();
return SendInputActions(sessionId, hwnd, holdDown, holdDown.Count());
}
public Task<int> HoldUp(int sessionId, KeyShortcut sc, IntPtr hwnd = 0)
{
IEnumerable<InputAction> holdUp = sc.GetHoldUpActions();
return SendInputActions(sessionId, hwnd, holdUp, holdUp.Count());
}
public Task<int> Press(int sessionId, Key key, IntPtr hwnd = 0)
{
return Press(sessionId, new KeyShortcut(key), hwnd);
}
public Task<int> Press(int sessionId, KeyShortcut sc, IntPtr hwnd = 0)
{
return Press(sessionId, new KeyShortcutSequence(sc), hwnd);
}
public Task<int> Press(int sessionId, KeyShortcutSequence seq, IntPtr hwnd = 0)
{
IEnumerable<InputAction> press = seq.GetInputActions();
return SendInputActions(sessionId, hwnd, press, press.Count());
}
}
}