nitai/projects
rblxtool / src / ui / RblxTool / Interop / RblxEngine.cs
154 lines · 5.6 KB Raw
1using System.Runtime.InteropServices;
2using System.Text.Json;
3using RblxTool.Models;
4
5namespace RblxTool.Interop;
6
7public sealed class RblxEngine : IDisposable
8{
9 private ulong _handle;
10 private bool _disposed;
11
12 private RblxEngine(ulong handle) => _handle = handle;
13
14 public static RblxEngine Open(string? vaultPath = null, string? passphrase = null)
15 {
16 var handle = NativeMethods.rblx_engine_open(vaultPath, passphrase);
17 if (handle == 0)
18 {
19 throw new InvalidOperationException("native engine failed to start");
20 }
21 return new RblxEngine(handle);
22 }
23
24 public static string Version() => Take(NativeMethods.rblx_version());
25
26 public IReadOnlyList<AccountSummary> Accounts()
27 {
28 var json = Take(NativeMethods.rblx_accounts_list(_handle));
29 var envelope = JsonSerializer.Deserialize(
30 json,
31 ToolJsonContext.Default.EnvelopeListAccountSummary);
32 return envelope?.Data ?? new List<AccountSummary>();
33 }
34
35 public AccountSummary AddCookie(string cookie, string? label)
36 {
37 var json = Take(NativeMethods.rblx_account_add_cookie(_handle, cookie, label));
38 var envelope = JsonSerializer.Deserialize(json, ToolJsonContext.Default.EnvelopeAccountSummary);
39 if (envelope is null || !envelope.Ok || envelope.Data is null)
40 {
41 throw new InvalidOperationException(envelope?.Error ?? "cookie rejected");
42 }
43 return envelope.Data;
44 }
45
46 public LoginResult Login(string identifier, string password, string? label)
47 {
48 var json = Take(NativeMethods.rblx_account_login(_handle, identifier, password, label));
49 return JsonSerializer.Deserialize(json, ToolJsonContext.Default.LoginResult)
50 ?? new LoginResult { Ok = false, Error = "login failed" };
51 }
52
53 public AccountSummary SubmitTwoStep(string pendingId, string code)
54 {
55 var json = Take(NativeMethods.rblx_account_two_step(_handle, pendingId, code));
56 var envelope = JsonSerializer.Deserialize(json, ToolJsonContext.Default.EnvelopeAccountSummary);
57 if (envelope is null || !envelope.Ok || envelope.Data is null)
58 {
59 throw new InvalidOperationException(envelope?.Error ?? "verification failed");
60 }
61 return envelope.Data;
62 }
63
64 public OauthUrlResult OauthUrl(OauthRequest request)
65 {
66 var config = JsonSerializer.Serialize(request, ToolJsonContext.Default.OauthRequest);
67 var json = Take(NativeMethods.rblx_account_oauth_url(_handle, config));
68 return JsonSerializer.Deserialize(json, ToolJsonContext.Default.OauthUrlResult)
69 ?? new OauthUrlResult { Ok = false, Error = "oauth url failed" };
70 }
71
72 public AccountSummary OauthExchange(OauthRequest request, string code, string verifier)
73 {
74 var config = JsonSerializer.Serialize(request, ToolJsonContext.Default.OauthRequest);
75 var json = Take(NativeMethods.rblx_account_oauth_exchange(_handle, config, code, verifier));
76 var envelope = JsonSerializer.Deserialize(json, ToolJsonContext.Default.EnvelopeAccountSummary);
77 if (envelope is null || !envelope.Ok || envelope.Data is null)
78 {
79 throw new InvalidOperationException(envelope?.Error ?? "oauth exchange failed");
80 }
81 return envelope.Data;
82 }
83
84 public bool Select(string id) => NativeMethods.rblx_account_select(_handle, id) == 1;
85
86 public bool Remove(string id) => NativeMethods.rblx_account_remove(_handle, id) == 1;
87
88 public AccountOverview? Overview()
89 {
90 var json = Take(NativeMethods.rblx_account_overview(_handle));
91 var envelope = JsonSerializer.Deserialize(json, ToolJsonContext.Default.EnvelopeAccountOverview);
92 return envelope?.Data;
93 }
94
95 public EngineMetrics Metrics()
96 {
97 var json = Take(NativeMethods.rblx_metrics(_handle));
98 var envelope = JsonSerializer.Deserialize(json, ToolJsonContext.Default.EnvelopeEngineMetrics);
99 return envelope?.Data ?? new EngineMetrics();
100 }
101
102 public ulong StartSweep(SweepRequest request) =>
103 Start("sweep", JsonSerializer.Serialize(request, ToolJsonContext.Default.SweepRequest));
104
105 public ulong StartSnipe(SnipeRequest request) =>
106 Start("snipe", JsonSerializer.Serialize(request, ToolJsonContext.Default.SnipeRequest));
107
108 public ulong StartHunt(HuntRequest request) =>
109 Start("grouphunt", JsonSerializer.Serialize(request, ToolJsonContext.Default.HuntRequest));
110
111 private ulong Start(string kind, string configJson) =>
112 NativeMethods.rblx_job_start(_handle, kind, configJson);
113
114 public JobPoll Poll(ulong jobId, int maxEvents = 256)
115 {
116 var json = Take(NativeMethods.rblx_job_poll(_handle, jobId, maxEvents));
117 return JsonSerializer.Deserialize(json, ToolJsonContext.Default.JobPoll) ?? new JobPoll();
118 }
119
120 public void Cancel(ulong jobId) => NativeMethods.rblx_job_cancel(_handle, jobId);
121
122 public string Result(ulong jobId) => Take(NativeMethods.rblx_job_result(_handle, jobId));
123
124 private static string Take(nint pointer)
125 {
126 if (pointer == 0)
127 {
128 return "{}";
129 }
130 try
131 {
132 return Marshal.PtrToStringUTF8(pointer) ?? "{}";
133 }
134 finally
135 {
136 NativeMethods.rblx_string_free(pointer);
137 }
138 }
139
140 public void Dispose()
141 {
142 if (_disposed)
143 {
144 return;
145 }
146 _disposed = true;
147 if (_handle != 0)
148 {
149 NativeMethods.rblx_engine_close(_handle);
150 _handle = 0;
151 }
152 GC.SuppressFinalize(this);
153 }
154}