NetworkTransferTask

This commit is contained in:
Timerix 2024-09-20 03:25:21 +05:00
parent 9560acad07
commit 581c4b5498
5 changed files with 109 additions and 21 deletions

View File

@ -1,13 +1,72 @@
namespace Млаумчерб.Клиент; using System.Net.Http;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
public record struct NetworkTransferResult namespace Млаумчерб.Клиент;
public record struct NetworkTransferResult(long BytesTotal, long BytesTransferred, long BytesPerSecond)
{ {
public long BytesTotal; public override string ToString()
public long BytesTransferred; {
public long BytesPerSecond; return $"transferred {BytesTransferred}/{BytesTotal} bytes ({BytesPerSecond}) bps";
}
} }
public class NetworkHelper public class NetworkTransferTask
{ {
public Task Task { get; private set; }
public Progress<NetworkTransferResult> Progress { get; private set; }
private Stream _src;
private Stream _dst;
private CancellationTokenSource _cts;
private DTLib.Timer _timer;
public NetworkTransferTask(Stream src, Stream dst)
{
_src = src;
_dst = dst;
_cts = new CancellationTokenSource();
Progress = new Progress<NetworkTransferResult>();
_timer = new(true, 1000, ReportProgress);
Task = Task.CompletedTask;
}
public void Start()
{
_timer.Start();
Task = _src.CopyToAsync(_dst);
_timer.Stop();
}
public void Stop()
{
_cts.Cancel();
_timer.Stop();
}
private long previousBytesTransferred;
private void ReportProgress()
{
long bytesTotal = _src.Length, bytesTransferred = _src.Position;
long bytesPerSecond = bytesTransferred - previousBytesTransferred;
previousBytesTransferred = bytesTransferred;
((IProgress<NetworkTransferResult>)Progress).Report(new NetworkTransferResult(bytesTotal, bytesTransferred, bytesPerSecond));
}
public TaskAwaiter GetAwaiter() => Task.GetAwaiter();
}
public static class NetworkHelper
{
private static HttpClient http = new();
public static NetworkTransferTask DownloadHTTPFileAsync(string url, Stream destinationStream)
{
var sourceStream = http.GetStreamAsync(url).GetAwaiter().GetResult();
NetworkTransferTask task = new(sourceStream, destinationStream);
task.Start();
return task;
}
} }

View File

@ -2,6 +2,7 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using CliWrap; using CliWrap;
using DTLib.Extensions; using DTLib.Extensions;
using Newtonsoft.Json;
using Млаумчерб.Клиент.классы; using Млаумчерб.Клиент.классы;
namespace Млаумчерб.Клиент; namespace Млаумчерб.Клиент;
@ -11,7 +12,7 @@ public interface IGame
string Name { get; } string Name { get; }
IOPath InstallationDirectory { get; } IOPath InstallationDirectory { get; }
Progress<NetworkTransferResult> BeginUpdate(); Progress<NetworkTransferResult> BeginUpdate();
void EndUpdate(); void CancelUpdate();
Task Launch(); Task Launch();
void Close(); void Close();
} }
@ -21,17 +22,25 @@ public class MinecraftVersion : IGame
public string Name { get; } public string Name { get; }
public IOPath InstallationDirectory { get; } public IOPath InstallationDirectory { get; }
private IOPath JavawFilePath; private IOPath JavaExecutableFilePath;
private MinecraftVersionDescriptor descriptor;
private JavaArguments javaArgs; private JavaArguments javaArgs;
private GameArguments gameArgs; private GameArguments gameArgs;
private CancellationTokenSource? cts; private CancellationTokenSource? cts;
private CommandTask<CommandResult> commandTask; private CommandTask<CommandResult>? commandTask;
public MinecraftVersion(string name) public MinecraftVersion(IOPath descriptorFilePath)
{ {
Name = name; Name = descriptorFilePath.LastName().ToString().Replace(".json", "");
InstallationDirectory = Path.Concat("minecraft", Path.ReplaceRestrictedChars(name)); InstallationDirectory = Path.Concat(Приложение.Настройки.путь_к_кубачу, Name);
string descriptorText = File.ReadAllText(descriptorFilePath);
descriptor = JsonConvert.DeserializeObject<MinecraftVersionDescriptor>(descriptorText)
?? throw new Exception($"can't parse descriptor file '{descriptorFilePath}'");
javaArgs = new JavaArguments(descriptor);
gameArgs = new GameArguments(descriptor);
JavaExecutableFilePath = Path.Concat(Приложение.Настройки.путь_к_жабе, "bin",
OperatingSystem.IsWindows() ? "javaw.exe" : "javaw");
} }
public Progress<NetworkTransferResult> BeginUpdate() public Progress<NetworkTransferResult> BeginUpdate()
@ -39,7 +48,7 @@ public class MinecraftVersion : IGame
throw new NotImplementedException(); throw new NotImplementedException();
} }
public void EndUpdate() public void CancelUpdate()
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
@ -48,7 +57,7 @@ public class MinecraftVersion : IGame
{ {
var javaArgsList = javaArgs.FillPlaceholders([]); var javaArgsList = javaArgs.FillPlaceholders([]);
var gameArgsList = gameArgs.FillPlaceholders([]); var gameArgsList = gameArgs.FillPlaceholders([]);
var command = Cli.Wrap(JavawFilePath.ToString()) var command = Cli.Wrap(JavaExecutableFilePath.ToString())
.WithWorkingDirectory(InstallationDirectory.ToString()) .WithWorkingDirectory(InstallationDirectory.ToString())
.WithArguments(javaArgsList) .WithArguments(javaArgsList)
.WithArguments(gameArgsList); .WithArguments(gameArgsList);
@ -68,4 +77,6 @@ public class MinecraftVersion : IGame
{ {
cts?.Cancel(); cts?.Cancel();
} }
public override string ToString() => Name;
} }

View File

@ -18,11 +18,8 @@
<PackageReference Include="Avalonia.Themes.Simple" Version="11.*" /> <PackageReference Include="Avalonia.Themes.Simple" Version="11.*" />
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.*" /> <PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.*" />
<PackageReference Include="Avalonia.Labs.Gif" Version="11.2.999-cibuild-00051673"/> <PackageReference Include="Avalonia.Labs.Gif" Version="11.2.999-cibuild-00051673"/>
<PackageReference Include="CliWrap" Version="3.6.6" /> <PackageReference Include="CliWrap" Version="3.6.*" />
<PackageReference Include="DTLib" Version="1.3.*" /> <PackageReference Include="DTLib" Version="1.4.0" />
<PackageReference Include="DTLib.Ben.Demystifier" Version="1.0.*" />
<PackageReference Include="DTLib.Logging" Version="1.3.*" />
<PackageReference Include="DTLib.Network" Version="1.4.*" />
<PackageReference Include="MessageBox.Avalonia" Version="3.1.*" /> <PackageReference Include="MessageBox.Avalonia" Version="3.1.*" />
<PackageReference Include="Newtonsoft.Json" Version="13.*" /> <PackageReference Include="Newtonsoft.Json" Version="13.*" />
</ItemGroup> </ItemGroup>

View File

@ -7,7 +7,10 @@ public record Настройки
public string имя_пользователя { get; set; } = ""; public string имя_пользователя { get; set; } = "";
public int выделенная_память_мб { get; set; } = 4096; public int выделенная_память_мб { get; set; } = 4096;
public bool открыватьаесь_экран { get; set; } public bool открыватьаесь_экран { get; set; }
public string путь_к_кубачу { get; set; } = ".";
public string путь_к_жабе { get; set; } = "java";
public bool скачатьабу { get; set; } = true;
public static Настройки ЗагрузитьИзФайла(string имяайла = "млаумчерб.настройки") public static Настройки ЗагрузитьИзФайла(string имяайла = "млаумчерб.настройки")
{ {
Приложение.Логгер.LogInfo(nameof(Настройки), $"попытка загрузить настройки из файла '{имя_файла}'"); Приложение.Логгер.LogInfo(nameof(Настройки), $"попытка загрузить настройки из файла '{имя_файла}'");

View File

@ -57,6 +57,15 @@ public partial class Окне : Window
Username = Приложение.Настройки.имя_пользователя; Username = Приложение.Настройки.имя_пользователя;
MemoryLimit = Приложение.Настройки.выделенная_память_мб; MemoryLimit = Приложение.Настройки.выделенная_память_мб;
Fullscreen = Приложение.Настройки.открыватьаесь_экран; Fullscreen = Приложение.Настройки.открыватьаесь_экран;
IOPath localDescriptorsDir = Path.Concat(Приложение.Настройки.путь_к_кубачу, "version_descriptors");
Directory.Create(localDescriptorsDir);
var descriptorFiles = Directory.GetFiles(localDescriptorsDir);
foreach(var descriptorFile in descriptorFiles)
{
MinecraftVersion mc = new(descriptorFile);
VersionComboBox.Items.Add(mc);
}
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -72,7 +81,16 @@ public partial class Окне : Window
Приложение.Настройки.выделенная_память_мб = MemoryLimit; Приложение.Настройки.выделенная_память_мб = MemoryLimit;
Приложение.Настройки.открыватьаесь_экран = Fullscreen; Приложение.Настройки.открыватьаесь_экран = Fullscreen;
Приложение.Настройки.СохранитьВФайл(); Приложение.Настройки.СохранитьВФайл();
IGame? game = (IGame?)VersionComboBox.SelectionBoxItem;
if (game != null)
{
if (UpdateGameFiles)
{
var progress = game.BeginUpdate();
progress.ProgressChanged += (o, result) => Приложение.Логгер.LogDebug("Downloads", result);
}
}
} }
catch (Exception ex) catch (Exception ex)
{ {