Skip to content

Commit 178c074

Browse files
committed
🎨 ASF 增加一键下载功能
1 parent c3279e7 commit 178c074

File tree

5 files changed

+113
-13
lines changed

5 files changed

+113
-13
lines changed

src/BD.WTTS.Client.Plugins.ArchiSteamFarmPlus/Services.Implementation/ArchiSteamFarmServiceImpl.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ public async Task ShellMessageInput(string data)
6969
isFirstStart = false;
7070
}
7171

72-
(var isSuccess, var ipcUrl) = await StartProcess();
72+
(var isSuccess, var ipcUrl) = await StartProcessAsync();
7373
if (!isSuccess && !isFirstStart)
7474
throw new ArgumentException();
7575
else
@@ -85,7 +85,7 @@ public async Task ShellMessageInput(string data)
8585

8686
#region StartProcess
8787

88-
private async Task<(bool IsSuccess, string Message)> StartProcess()
88+
private async Task<(bool IsSuccess, string Message)> StartProcessAsync()
8989
{
9090
var isStartSuccess = false;
9191
var ipcUrl = string.Empty;
@@ -306,7 +306,7 @@ public async Task StopAsync()
306306
}
307307
}
308308

309-
public async Task Restart()
309+
public async Task RestartAsync()
310310
{
311311
Toast.Show(ToastIcon.Info, AppResources.ASF_Restarting, ToastLength.Short);
312312

src/BD.WTTS.Client.Plugins.ArchiSteamFarmPlus/Services/Mvvm/ASFService.cs

Lines changed: 77 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ private ASFService()
4747
{
4848
SteamBotsSourceList = new SourceCache<BotViewModel, string>(t => t.Bot.BotName);
4949

50-
archiSteamFarmService.OnConsoleWirteLine += OnConsoleWirteLine;
50+
archiSteamFarmService.OnConsoleWirteLine += OnConsoleWriteLine;
5151

5252
ASFSettings.ConsoleMaxLine.Subscribe(x =>
5353
{
@@ -58,9 +58,9 @@ private ASFService()
5858
});
5959
}
6060

61-
void OnConsoleWirteLine(string message)
61+
void OnConsoleWriteLine(string message)
6262
{
63-
MainThread2.InvokeOnMainThreadAsync(() =>
63+
MainThread2.BeginInvokeOnMainThread(() =>
6464
{
6565
//ConsoleLogBuilder.Append(message); // message 包含换行
6666
//var text = ConsoleLogBuilder.ToString();
@@ -74,7 +74,7 @@ public void ShellMessageInput(string? input)
7474
{
7575
return;
7676
}
77-
archiSteamFarmService.ShellMessageInput(input);
77+
_ = archiSteamFarmService.ShellMessageInput(input);
7878
}
7979

8080
/// <summary>
@@ -287,7 +287,7 @@ async Task ImportJsonFileAsync(IEnumerable<string?>? files, bool allowBot, bool
287287
Toast.Show(ToastIcon.Success, string.Format(AppResources.LocalAuth_ImportSuccessTip_, num));
288288
}
289289

290-
public async Task SelectASFProgramLocation()
290+
public async Task SelectASFProgramLocationAsync()
291291
{
292292
AvaloniaFilePickerFileTypeFilter fileTypes = new AvaloniaFilePickerFileTypeFilter.Item[] {
293293
new("ArchiSteamFarm") {
@@ -302,5 +302,77 @@ await FilePicker2.PickAsync((path) =>
302302
ASFSettings.ArchiSteamFarmExePath.Value = path;
303303
}, fileTypes);
304304
}
305+
306+
public async void DownloadASFAsync(string variant = "win-x64", IProgress<float>? progress = null, CancellationToken cancellationToken = default)
307+
{
308+
try
309+
{
310+
var assetName = $"{nameof(ASF)}-{variant}.zip";
311+
using var httpClient = new HttpClient();
312+
httpClient.DefaultRequestHeaders.TryAddWithoutValidation("User-Agent", IHttpPlatformHelperService.Instance.UserAgent);
313+
using var latestReleaseStream = await httpClient.GetStreamAsync("https://api.github.com/repos/JustArchiNET/ArchiSteamFarm/releases/latest", cancellationToken);
314+
using var element = await JsonDocument.ParseAsync(latestReleaseStream, cancellationToken: cancellationToken);
315+
if (element.RootElement.TryGetProperty("assets", out var assets) &&
316+
assets.EnumerateArray().FirstOrDefault(s => s.GetProperty("name").ValueEquals(assetName))
317+
.TryGetProperty("browser_download_url", out var downloadUrl))
318+
{
319+
var tag_name = element.RootElement.GetProperty("tag_name").GetString();
320+
var downloadSavingPath = Path.Combine(Plugin.Instance.AppDataDirectory, $"ASF-{tag_name}", assetName);
321+
var downloadSavingDir = Path.GetDirectoryName(downloadSavingPath)!;
322+
Directory.CreateDirectory(downloadSavingDir);
323+
324+
var message = new HttpRequestMessage(HttpMethod.Get, downloadUrl.GetString());
325+
var result = await httpClient.SendAsync(message, HttpCompletionOption.ResponseHeadersRead, cancellationToken);
326+
using var contentStream = await result.Content.ReadAsStreamAsync(cancellationToken);
327+
328+
byte batch = 0;
329+
long readThisBatch = 0;
330+
long batchIncreaseSize = result.Content.Headers.ContentLength.GetValueOrDefault() / 100;
331+
await using (FileStream fileStream = new(downloadSavingPath, FileMode.Create, FileAccess.Write, FileShare.None, 4096, true))
332+
{
333+
ArrayPool<byte> bytePool = ArrayPool<byte>.Shared;
334+
byte[] buffer = bytePool.Rent(4096);
335+
336+
try
337+
{
338+
while (contentStream.CanRead)
339+
{
340+
int read = await contentStream.ReadAsync(buffer.AsMemory(0, buffer.Length), cancellationToken);
341+
342+
if (read == 0)
343+
break;
344+
345+
await fileStream.WriteAsync(buffer.AsMemory(0, read), cancellationToken);
346+
if ((progress == null) || (batchIncreaseSize == 0) || (batch >= 99))
347+
{
348+
continue;
349+
}
350+
351+
readThisBatch += read;
352+
353+
while ((readThisBatch >= batchIncreaseSize) && (batch < 99))
354+
{
355+
readThisBatch -= batchIncreaseSize;
356+
progress.Report(++batch);
357+
}
358+
}
359+
}
360+
finally
361+
{
362+
bytePool.Return(buffer);
363+
}
364+
}
365+
366+
ZipFile.ExtractToDirectory(downloadSavingPath, downloadSavingDir);
367+
ASFSettings.ArchiSteamFarmExePath.Value = Path.Combine(downloadSavingDir, "ArchiSteamFarm.exe");
368+
progress?.Report(100);
369+
Toast.Show(ToastIcon.Success, "ASF 下载成功");
370+
}
371+
}
372+
catch (Exception ex)
373+
{
374+
Toast.LogAndShowT(ex, "ASF 文件下载异常");
375+
}
376+
}
305377
}
306378
#endif

src/BD.WTTS.Client.Plugins.ArchiSteamFarmPlus/UI/ViewModels/ArchiSteamFarmExePathSettingsPageViewModel.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,16 @@ public partial class ArchiSteamFarmExePathSettingsPageViewModel : ViewModelBase
44
{
55
public ICommand SelectProgramPath { get; }
66

7+
public ICommand DownloadASF { get; }
8+
79
public ArchiSteamFarmExePathSettingsPageViewModel()
810
{
9-
SelectProgramPath = ReactiveCommand.Create(ASFService.Current.SelectASFProgramLocation);
11+
SelectProgramPath = ReactiveCommand.Create(ASFService.Current.SelectASFProgramLocationAsync);
12+
DownloadASF = ReactiveCommand.Create(() =>
13+
{
14+
var progress = INotificationService.Instance.NotifyDownload(() => "开始下载 ASF ", NotificationType.NewVersion);
15+
ASFService.Current.DownloadASFAsync(progress: progress);
16+
Toast.Show(ToastIcon.Info, "等待后台下载文件", ToastLength.Short);
17+
});
1018
}
1119
}

src/BD.WTTS.Client.Plugins.ArchiSteamFarmPlus/UI/ViewModels/ArchiSteamFarmPlusPageViewModel.cs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ public sealed partial class ArchiSteamFarmPlusPageViewModel : ViewModelBase
99

1010
public ArchiSteamFarmPlusPageViewModel()
1111
{
12-
SelectASFExePath = ReactiveCommand.CreateFromTask(ASFService.Current.SelectASFProgramLocation);
12+
SelectASFExePath = ReactiveCommand.CreateFromTask(ASFService.Current.SelectASFProgramLocationAsync);
1313

1414
OpenWebUIConsole = ReactiveCommand.Create(() => ASFService.Current.OpenBrowser(null));
1515

@@ -18,12 +18,12 @@ public ArchiSteamFarmPlusPageViewModel()
1818
RunOrStop = ReactiveCommand.Create(RunOrStopASF);
1919
}
2020

21-
public override void Activation()
21+
public override async void Activation()
2222
{
2323
base.Activation();
2424
if (string.IsNullOrEmpty(ASFSettings.ArchiSteamFarmExePath.Value))
2525
{
26-
MainThread2.InvokeOnMainThreadAsync(async () =>
26+
await MainThread2.InvokeOnMainThreadAsync(async () =>
2727
{
2828
var model = new ArchiSteamFarmExePathSettingsPageViewModel();
2929
await IWindowManager.Instance.ShowTaskDialogAsync(model,
@@ -44,7 +44,16 @@ await IWindowManager.Instance.ShowTaskDialogAsync(model,
4444
StartOrStopASF_Click();
4545
}
4646

47-
public static void StartOrStopASF_Click(bool? startOrStop = null) => Task.Run(async () =>
47+
protected override void Dispose(bool disposing)
48+
{
49+
if (disposing)
50+
{
51+
ASFService.Current.StopASFAsync().Wait();
52+
}
53+
base.Dispose(disposing);
54+
}
55+
56+
public void StartOrStopASF_Click(bool? startOrStop = null) => _ = Task.Run(async () =>
4857
{
4958
var s = ASFService.Current;
5059
if (!s.IsASFRuning)

src/BD.WTTS.Client.Plugins.ArchiSteamFarmPlus/UI/Views/Controls/ArchiSteamFarmExePathSettingsPage.axaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,16 @@
2626
<Button Command="{Binding SelectProgramPath}" Content="选择路径" />
2727
</ui:SettingsExpander.Footer>
2828
</ui:SettingsExpander>
29+
<ui:SettingsExpander
30+
Description="下载并设置 ASF 路径"
31+
Header="还没有下载过ASF?请点击下载"
32+
IsClickEnabled="True">
33+
<ui:SettingsExpander.IconSource>
34+
<ui:FontIconSource FontFamily="{StaticResource SymbolThemeFontFamily}" Glyph="&#xE896;" />
35+
</ui:SettingsExpander.IconSource>
36+
<ui:SettingsExpander.Footer>
37+
<Button Command="{Binding DownloadASF}" Content="一键下载" />
38+
</ui:SettingsExpander.Footer>
39+
</ui:SettingsExpander>
2940
</StackPanel>
3041
</UserControl>

0 commit comments

Comments
 (0)