@@ -47,7 +47,7 @@ private ASFService()
47
47
{
48
48
SteamBotsSourceList = new SourceCache < BotViewModel , string > ( t => t . Bot . BotName ) ;
49
49
50
- archiSteamFarmService . OnConsoleWirteLine += OnConsoleWirteLine ;
50
+ archiSteamFarmService . OnConsoleWirteLine += OnConsoleWriteLine ;
51
51
52
52
ASFSettings . ConsoleMaxLine . Subscribe ( x =>
53
53
{
@@ -58,9 +58,9 @@ private ASFService()
58
58
} ) ;
59
59
}
60
60
61
- void OnConsoleWirteLine ( string message )
61
+ void OnConsoleWriteLine ( string message )
62
62
{
63
- MainThread2 . InvokeOnMainThreadAsync ( ( ) =>
63
+ MainThread2 . BeginInvokeOnMainThread ( ( ) =>
64
64
{
65
65
//ConsoleLogBuilder.Append(message); // message 包含换行
66
66
//var text = ConsoleLogBuilder.ToString();
@@ -74,7 +74,7 @@ public void ShellMessageInput(string? input)
74
74
{
75
75
return ;
76
76
}
77
- archiSteamFarmService . ShellMessageInput ( input ) ;
77
+ _ = archiSteamFarmService . ShellMessageInput ( input ) ;
78
78
}
79
79
80
80
/// <summary>
@@ -287,7 +287,7 @@ async Task ImportJsonFileAsync(IEnumerable<string?>? files, bool allowBot, bool
287
287
Toast . Show ( ToastIcon . Success , string . Format ( AppResources . LocalAuth_ImportSuccessTip_ , num ) ) ;
288
288
}
289
289
290
- public async Task SelectASFProgramLocation ( )
290
+ public async Task SelectASFProgramLocationAsync ( )
291
291
{
292
292
AvaloniaFilePickerFileTypeFilter fileTypes = new AvaloniaFilePickerFileTypeFilter . Item [ ] {
293
293
new ( "ArchiSteamFarm" ) {
@@ -302,5 +302,77 @@ await FilePicker2.PickAsync((path) =>
302
302
ASFSettings . ArchiSteamFarmExePath . Value = path ;
303
303
} , fileTypes ) ;
304
304
}
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
+ }
305
377
}
306
378
#endif
0 commit comments