-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathMaaCoreBridgeStub.cs
More file actions
182 lines (152 loc) · 6.47 KB
/
Copy pathMaaCoreBridgeStub.cs
File metadata and controls
182 lines (152 loc) · 6.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
using System.Runtime.CompilerServices;
using System.Threading.Channels;
namespace MAAUnified.CoreBridge;
public sealed class MaaCoreBridgeStub : IMaaCoreBridge
{
private readonly Channel<CoreCallbackEvent> _callbackChannel = Channel.CreateUnbounded<CoreCallbackEvent>();
private bool _initialized;
private bool _connected;
private bool _running;
private bool _disposed;
private int _taskId;
public bool SupportsBackToHome => true;
public bool SupportsStartCloseDown => true;
public Task<CoreResult<CoreInitializeInfo>> InitializeAsync(
CoreInitializeRequest request,
CancellationToken cancellationToken = default)
{
if (_disposed)
{
return Task.FromResult(CoreResult<CoreInitializeInfo>.Fail(new CoreError(CoreErrorCode.Disposed, "Bridge is disposed.")));
}
_initialized = true;
return Task.FromResult(
CoreResult<CoreInitializeInfo>.Ok(
new CoreInitializeInfo(
request.BaseDirectory,
Path.Combine(request.BaseDirectory, "stub-core"),
"stub",
request.ClientType)));
}
public Task<CoreResult<bool>> ConnectAsync(CoreConnectionInfo connectionInfo, CancellationToken cancellationToken = default)
{
if (!_initialized)
{
return Task.FromResult(CoreResult<bool>.Fail(new CoreError(CoreErrorCode.NotInitialized, "Bridge not initialized.")));
}
_connected = !string.IsNullOrWhiteSpace(connectionInfo.Address);
return Task.FromResult(
_connected
? CoreResult<bool>.Ok(true)
: CoreResult<bool>.Fail(new CoreError(CoreErrorCode.ConnectFailed, "Stub connect failed.")));
}
public Task<CoreResult<bool>> ApplyInstanceOptionsAsync(CoreInstanceOptions options, CancellationToken cancellationToken = default)
{
if (_disposed)
{
return Task.FromResult(CoreResult<bool>.Fail(new CoreError(CoreErrorCode.Disposed, "Bridge is disposed.")));
}
if (!_initialized)
{
return Task.FromResult(CoreResult<bool>.Fail(new CoreError(CoreErrorCode.NotInitialized, "Bridge not initialized.")));
}
return Task.FromResult(CoreResult<bool>.Ok(true));
}
public Task<CoreResult<bool>> SetConnectionExtrasAsync(
string name,
string extrasJson,
CancellationToken cancellationToken = default)
{
if (_disposed)
{
return Task.FromResult(CoreResult<bool>.Fail(new CoreError(CoreErrorCode.Disposed, "Bridge is disposed.")));
}
if (!_initialized)
{
return Task.FromResult(CoreResult<bool>.Fail(new CoreError(CoreErrorCode.NotInitialized, "Bridge not initialized.")));
}
return Task.FromResult(CoreResult<bool>.Ok(true));
}
public Task<CoreResult<int>> AppendTaskAsync(CoreTaskRequest task, CancellationToken cancellationToken = default)
{
if (!_connected)
{
return Task.FromResult(CoreResult<int>.Fail(new CoreError(CoreErrorCode.AppendTaskFailed, "Stub is not connected.")));
}
_taskId += 1;
return Task.FromResult(CoreResult<int>.Ok(_taskId));
}
public Task<CoreResult<bool>> StartAsync(CancellationToken cancellationToken = default)
{
_running = _connected;
return Task.FromResult(
_running
? CoreResult<bool>.Ok(true)
: CoreResult<bool>.Fail(new CoreError(CoreErrorCode.StartFailed, "Stub start failed.")));
}
public Task<CoreResult<bool>> StopAsync(CancellationToken cancellationToken = default)
{
var wasRunning = _running;
_running = false;
return Task.FromResult(
wasRunning
? CoreResult<bool>.Ok(true)
: CoreResult<bool>.Fail(new CoreError(CoreErrorCode.StopFailed, "Stub was not running.")));
}
public Task<CoreResult<bool>> BackToHomeAsync(CancellationToken cancellationToken = default)
{
if (!_connected)
{
return Task.FromResult(CoreResult<bool>.Fail(new CoreError(CoreErrorCode.NotInitialized, "Stub is not connected.")));
}
return Task.FromResult(CoreResult<bool>.Ok(true));
}
public async Task<CoreResult<bool>> StartCloseDownAsync(string clientType, CancellationToken cancellationToken = default)
{
if (!_connected)
{
return CoreResult<bool>.Fail(new CoreError(CoreErrorCode.NotInitialized, "Stub is not connected."));
}
var append = await AppendTaskAsync(
new CoreTaskRequest(
"CloseDown",
"CloseDown",
true,
$"{{\"client_type\":\"{clientType?.Trim() ?? string.Empty}\"}}"),
cancellationToken);
if (!append.Success)
{
return CoreResult<bool>.Fail(append.Error!);
}
return await StartAsync(cancellationToken);
}
public Task<CoreResult<CoreRuntimeStatus>> GetRuntimeStatusAsync(CancellationToken cancellationToken = default)
{
return Task.FromResult(CoreResult<CoreRuntimeStatus>.Ok(new CoreRuntimeStatus(_initialized, _connected, _running)));
}
public Task<CoreResult<bool>> AttachWindowAsync(CoreAttachWindowRequest request, CancellationToken cancellationToken = default)
{
return Task.FromResult(CoreResult<bool>.Fail(new CoreError(CoreErrorCode.NotSupported, "Stub does not support AttachWindow.")));
}
public Task<CoreResult<byte[]>> GetImageAsync(CancellationToken cancellationToken = default)
{
return Task.FromResult(CoreResult<byte[]>.Fail(new CoreError(CoreErrorCode.GetImageFailed, "Stub has no image source.")));
}
public Task<CoreResult<byte[]>> GetImageBgrAsync(bool forceScreencap = false, CancellationToken cancellationToken = default)
{
return Task.FromResult(CoreResult<byte[]>.Fail(new CoreError(CoreErrorCode.NotSupported, "Stub has no raw image source.")));
}
public async IAsyncEnumerable<CoreCallbackEvent> CallbackStreamAsync([EnumeratorCancellation] CancellationToken cancellationToken = default)
{
await foreach (var callback in _callbackChannel.Reader.ReadAllAsync(cancellationToken))
{
yield return callback;
}
}
public ValueTask DisposeAsync()
{
_disposed = true;
_callbackChannel.Writer.TryComplete();
return ValueTask.CompletedTask;
}
}