convert to c#
This commit is contained in:
211
ModpackUpdater.Manager/ModpackInstaller.cs
Normal file
211
ModpackUpdater.Manager/ModpackInstaller.cs
Normal file
@@ -0,0 +1,211 @@
|
||||
using ModpackUpdater.Model;
|
||||
using System.IO.Compression;
|
||||
|
||||
namespace ModpackUpdater.Manager;
|
||||
|
||||
public class ModpackInstaller(ModpackConfig updateConfig, string localPath)
|
||||
{
|
||||
private class LocalZipCacheEntry
|
||||
{
|
||||
public string DownloadUrl { get; set; }
|
||||
public string ExtractedZipPath { get; set; }
|
||||
}
|
||||
|
||||
public event InstallProgessUpdatedEventHandler InstallProgessUpdated;
|
||||
|
||||
public delegate void InstallProgessUpdatedEventHandler(UpdateCheckResult result, int processedSyncs);
|
||||
public event CheckingProgressUpdatedEventHandler CheckingProgressUpdated;
|
||||
|
||||
public delegate void CheckingProgressUpdatedEventHandler(int toCheck, int processed);
|
||||
|
||||
private HttpClient httpClient = new();
|
||||
|
||||
~ModpackInstaller()
|
||||
{
|
||||
httpClient.Dispose();
|
||||
}
|
||||
|
||||
private async Task<UpdateInfos> DownloadUpdateInfos()
|
||||
{
|
||||
var content = await httpClient.GetStringAsync(updateConfig.UpdateUrl);
|
||||
return UpdateInfos.Parse(content);
|
||||
}
|
||||
|
||||
private async Task<InstallInfos> DownloadInstallInfos()
|
||||
{
|
||||
var content = await httpClient.GetStringAsync(updateConfig.InstallUrl);
|
||||
return InstallInfos.Parse(content);
|
||||
}
|
||||
|
||||
public async Task<UpdateCheckResult> Check(bool ignoreRevmoedFiles)
|
||||
{
|
||||
var result = new UpdateCheckResult();
|
||||
|
||||
if (ModpackInfo.HasModpackInfo(localPath))
|
||||
{
|
||||
var infos = await DownloadUpdateInfos();
|
||||
var modpackInfo = ModpackInfo.Load(localPath);
|
||||
|
||||
if (infos is not null && infos.Updates.Count != 0)
|
||||
{
|
||||
var updatesOrderes = infos.Updates.OrderByDescending(n => n.Version);
|
||||
result.LatestVersion = updatesOrderes.First().Version;
|
||||
result.CurrentVersion = modpackInfo.Version;
|
||||
result.IsInstalled = true;
|
||||
|
||||
var checkingVersionIndex = 0;
|
||||
var checkingVersion = updatesOrderes.ElementAtOrDefault(checkingVersionIndex);
|
||||
|
||||
while (checkingVersion is not null && checkingVersion.Version > result.CurrentVersion)
|
||||
{
|
||||
var actionsToAdd = new List<UpdateAction>();
|
||||
|
||||
foreach (var action in checkingVersion.Actions)
|
||||
{
|
||||
if (!result.Actions.Any(n => n.DestPath == action.DestPath))
|
||||
actionsToAdd.Add(action);
|
||||
}
|
||||
|
||||
result.Actions.InsertRange(0, actionsToAdd);
|
||||
|
||||
checkingVersionIndex += 1;
|
||||
checkingVersion = updatesOrderes.ElementAtOrDefault(checkingVersionIndex);
|
||||
}
|
||||
}
|
||||
else
|
||||
result.HasError = true;
|
||||
}
|
||||
|
||||
if (!result.IsInstalled)
|
||||
{
|
||||
var infos = await DownloadInstallInfos();
|
||||
|
||||
if (infos is not null && infos.Actions.Count != 0)
|
||||
result.Actions.AddRange(infos.Actions);
|
||||
else
|
||||
result.HasError = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<bool?> Install(UpdateCheckResult checkResult)
|
||||
{
|
||||
ModpackInfo modpackInfo;
|
||||
int processed = 0;
|
||||
var localZipCache = new List<LocalZipCacheEntry>();
|
||||
|
||||
if (ModpackInfo.HasModpackInfo(localPath))
|
||||
modpackInfo = ModpackInfo.Load(localPath);
|
||||
else
|
||||
{
|
||||
modpackInfo = new ModpackInfo();
|
||||
}
|
||||
|
||||
foreach (InstallAction iaction in checkResult.Actions)
|
||||
{
|
||||
string destFilePath = Path.Combine(localPath, iaction.DestPath);
|
||||
|
||||
if (iaction is UpdateAction)
|
||||
{
|
||||
UpdateAction uaction = (UpdateAction)iaction;
|
||||
|
||||
switch (uaction.Type)
|
||||
{
|
||||
case UpdateActionType.Update:
|
||||
await InstallFile(destFilePath, uaction.DownloadUrl, uaction.IsZip, uaction.ZipPath, localZipCache);
|
||||
break;
|
||||
case UpdateActionType.Delete:
|
||||
{
|
||||
if (uaction.IsDirectory)
|
||||
{
|
||||
if (Directory.Exists(destFilePath))
|
||||
Directory.Delete(destFilePath, true);
|
||||
}
|
||||
else if (File.Exists(destFilePath))
|
||||
File.Delete(destFilePath);
|
||||
}
|
||||
break;
|
||||
case UpdateActionType.Copy:
|
||||
{
|
||||
var srcFilePath = Path.Combine(localPath, uaction.SrcPath);
|
||||
if (uaction.IsDirectory)
|
||||
{
|
||||
if (Directory.Exists(srcFilePath))
|
||||
Extensions.CopyDirectory(srcFilePath, destFilePath, true);
|
||||
}
|
||||
else if (File.Exists(srcFilePath))
|
||||
{
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(destFilePath));
|
||||
File.Copy(srcFilePath, destFilePath, true);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case UpdateActionType.Move:
|
||||
{
|
||||
var srcFilePath = Path.Combine(localPath, uaction.SrcPath);
|
||||
if (uaction.IsDirectory)
|
||||
{
|
||||
if (Directory.Exists(srcFilePath))
|
||||
Directory.Move(srcFilePath, destFilePath);
|
||||
}
|
||||
else if (File.Exists(srcFilePath))
|
||||
{
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(destFilePath));
|
||||
File.Move(srcFilePath, destFilePath, true);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
await InstallFile(destFilePath, iaction.DownloadUrl, iaction.IsZip, iaction.ZipPath, localZipCache);
|
||||
|
||||
processed += 1;
|
||||
InstallProgessUpdated?.Invoke(checkResult, processed);
|
||||
}
|
||||
|
||||
// Save new modpack info
|
||||
modpackInfo.Version = checkResult.LatestVersion;
|
||||
modpackInfo.Save(localPath);
|
||||
|
||||
// Delete cached zip files
|
||||
foreach (var task in localZipCache)
|
||||
Directory.Delete(task.ExtractedZipPath, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private async Task InstallFile(string destFilePath, string sourceUrl, bool isZip, string zipPath, List<LocalZipCacheEntry> localZipCache)
|
||||
{
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(destFilePath));
|
||||
|
||||
// Download
|
||||
var fsDestinationPath = isZip ? Path.Combine(Path.GetTempPath(), $"mc_update_file_{DateTime.Now.ToBinary()}.zip") : destFilePath;
|
||||
var sRemote = await httpClient.GetStreamAsync(sourceUrl);
|
||||
var fs = new FileStream(destFilePath, FileMode.Create, FileAccess.ReadWrite);
|
||||
await sRemote.CopyToAsync(fs);
|
||||
sRemote.Close();
|
||||
fs.Close();
|
||||
|
||||
// Handle zip file
|
||||
if (isZip)
|
||||
{
|
||||
// Extract
|
||||
var zipDir = $"{Path.GetFileNameWithoutExtension(fsDestinationPath)}_extracted";
|
||||
ZipFile.ExtractToDirectory(fsDestinationPath, zipDir);
|
||||
|
||||
// Copy content
|
||||
var zipSrc = Path.Combine(zipDir, zipPath);
|
||||
Extensions.CopyDirectory(zipSrc, destFilePath, true);
|
||||
|
||||
// Delete/cache temporary files
|
||||
File.Delete(fsDestinationPath);
|
||||
localZipCache?.Add(new LocalZipCacheEntry
|
||||
{
|
||||
DownloadUrl = sourceUrl,
|
||||
ExtractedZipPath = zipDir
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user