convert to c#
This commit is contained in:
40
ModpackUpdater.Manager/Extensions.cs
Normal file
40
ModpackUpdater.Manager/Extensions.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
namespace ModpackUpdater.Manager;
|
||||
|
||||
|
||||
public static class Extensions
|
||||
{
|
||||
|
||||
public static void CopyDirectory(string sourceDir, string destinationDir, bool recursive)
|
||||
{
|
||||
// Get information about the source directory
|
||||
var dir = new DirectoryInfo(sourceDir);
|
||||
|
||||
// Check if the source directory exists
|
||||
if (!dir.Exists)
|
||||
throw new DirectoryNotFoundException($"Source directory not found: {dir.FullName}");
|
||||
|
||||
// Cache directories before we start copying
|
||||
DirectoryInfo[] dirs = dir.GetDirectories();
|
||||
|
||||
// Create the destination directory
|
||||
Directory.CreateDirectory(destinationDir);
|
||||
|
||||
// Get the files in the source directory and copy to the destination directory
|
||||
foreach (FileInfo @file in dir.GetFiles())
|
||||
{
|
||||
string targetFilePath = Path.Combine(destinationDir, @file.Name);
|
||||
@file.CopyTo(targetFilePath);
|
||||
}
|
||||
|
||||
// If recursive and copying subdirectories, recursively call this method
|
||||
if (recursive)
|
||||
{
|
||||
foreach (DirectoryInfo subDir in dirs)
|
||||
{
|
||||
string newDestinationDir = Path.Combine(destinationDir, subDir.Name);
|
||||
CopyDirectory(subDir.FullName, newDestinationDir, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
Imports System.IO
|
||||
|
||||
Public Module Extensions
|
||||
|
||||
Public Sub CopyDirectory(sourceDir As String, destinationDir As String, recursive As Boolean)
|
||||
' Get information about the source directory
|
||||
Dim dir As New DirectoryInfo(sourceDir)
|
||||
|
||||
' Check if the source directory exists
|
||||
If Not dir.Exists Then
|
||||
Throw New DirectoryNotFoundException($"Source directory not found: {dir.FullName}")
|
||||
End If
|
||||
|
||||
' Cache directories before we start copying
|
||||
Dim dirs As DirectoryInfo() = dir.GetDirectories()
|
||||
|
||||
' Create the destination directory
|
||||
Directory.CreateDirectory(destinationDir)
|
||||
|
||||
' Get the files in the source directory and copy to the destination directory
|
||||
For Each file As FileInfo In dir.GetFiles()
|
||||
Dim targetFilePath As String = Path.Combine(destinationDir, file.Name)
|
||||
file.CopyTo(targetFilePath)
|
||||
Next
|
||||
|
||||
' If recursive and copying subdirectories, recursively call this method
|
||||
If recursive Then
|
||||
For Each subDir As DirectoryInfo In dirs
|
||||
Dim newDestinationDir As String = Path.Combine(destinationDir, subDir.Name)
|
||||
CopyDirectory(subDir.FullName, newDestinationDir, True)
|
||||
Next
|
||||
End If
|
||||
End Sub
|
||||
|
||||
End Module
|
||||
11
ModpackUpdater.Manager/MinecraftProfileChecker.cs
Normal file
11
ModpackUpdater.Manager/MinecraftProfileChecker.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
|
||||
namespace ModpackUpdater.Manager;
|
||||
|
||||
public class MinecraftProfileChecker
|
||||
{
|
||||
public static bool CheckProfile(string folderPath)
|
||||
{
|
||||
// Todo: Adds some checks to verify, if the current folder is a minecraft folder.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
Public Class MinecraftProfileChecker
|
||||
|
||||
Public Shared Function CheckProfile(folderPath As string) As Boolean
|
||||
'Todo: Adds some checks to verify, if the current folder is a minecraft folder.
|
||||
Return True
|
||||
End Function
|
||||
|
||||
End Class
|
||||
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
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,194 +0,0 @@
|
||||
Imports System.IO
|
||||
Imports System.IO.Compression
|
||||
Imports System.Net.Http
|
||||
|
||||
Imports ModpackUpdater.Model
|
||||
|
||||
Public Class ModpackInstaller
|
||||
|
||||
Private Class LocalZipCacheEntry
|
||||
Public Property DownloadUrl As String
|
||||
Public Property ExtractedZipPath As String
|
||||
End Class
|
||||
|
||||
Public Event InstallProgessUpdated(result As UpdateCheckResult, processedSyncs As Integer)
|
||||
Public Event CheckingProgressUpdated(toCheck As Integer, processed As Integer)
|
||||
|
||||
Private ReadOnly updateConfig As ModpackConfig
|
||||
Private ReadOnly localPath As String
|
||||
Private httpClient As New HttpClient
|
||||
|
||||
Public Sub New(updateConfig As ModpackConfig, localPath As String)
|
||||
Me.updateConfig = updateConfig
|
||||
Me.localPath = localPath
|
||||
End Sub
|
||||
|
||||
Protected Overrides Sub Finalize()
|
||||
httpClient.Dispose()
|
||||
MyBase.Finalize()
|
||||
End Sub
|
||||
|
||||
Private Async Function DownloadUpdateInfos() As Task(Of UpdateInfos)
|
||||
Dim content As String = Await httpClient.GetStringAsync(updateConfig.UpdateUrl)
|
||||
Return UpdateInfos.Parse(content)
|
||||
End Function
|
||||
|
||||
Private Async Function DownloadInstallInfos() As Task(Of InstallInfos)
|
||||
Dim content As String = Await httpClient.GetStringAsync(updateConfig.InstallUrl)
|
||||
Return InstallInfos.Parse(content)
|
||||
End Function
|
||||
|
||||
Public Async Function Check(ignoreRevmoedFiles As Boolean) As Task(Of UpdateCheckResult)
|
||||
Dim result As New UpdateCheckResult
|
||||
|
||||
If ModpackInfo.HasModpackInfo(localPath) Then
|
||||
Dim infos As UpdateInfos = Await DownloadUpdateInfos()
|
||||
Dim modpackInfo As ModpackInfo = ModpackInfo.Load(localPath)
|
||||
|
||||
If infos IsNot Nothing AndAlso infos.Updates.Count <> 0 Then
|
||||
Dim updatesOrderes = infos.Updates.OrderByDescending(Function(n) n.Version)
|
||||
result.LatestVersion = updatesOrderes.First.Version
|
||||
result.CurrentVersion = modpackInfo.Version
|
||||
result.IsInstalled = True
|
||||
|
||||
Dim checkingVersionIndex As Integer = 0
|
||||
Dim checkingVersion As UpdateInfo = updatesOrderes(checkingVersionIndex)
|
||||
|
||||
Do While checkingVersion IsNot Nothing AndAlso checkingVersion.Version > result.CurrentVersion
|
||||
Dim actionsToAdd As New List(Of UpdateAction)
|
||||
|
||||
For Each action In checkingVersion.Actions
|
||||
If Not result.Actions.Any(Function(n) n.DestPath = action.DestPath) Then
|
||||
actionsToAdd.Add(action)
|
||||
End If
|
||||
Next
|
||||
|
||||
result.Actions.InsertRange(0, actionsToAdd)
|
||||
|
||||
checkingVersionIndex += 1
|
||||
checkingVersion = updatesOrderes.ElementAtOrDefault(checkingVersionIndex)
|
||||
Loop
|
||||
Else
|
||||
result.HasError = True
|
||||
End If
|
||||
End If
|
||||
|
||||
If Not result.IsInstalled Then
|
||||
Dim infos As InstallInfos = Await DownloadInstallInfos()
|
||||
|
||||
If infos IsNot Nothing AndAlso infos.Actions.Count <> 0 Then
|
||||
result.Actions.AddRange(infos.Actions)
|
||||
Else
|
||||
result.HasError = True
|
||||
End If
|
||||
End If
|
||||
|
||||
Return result
|
||||
End Function
|
||||
|
||||
Public Async Function Install(checkResult As UpdateCheckResult) As Task(Of Boolean?)
|
||||
Dim modpackInfo As ModpackInfo
|
||||
Dim processed As Integer = 0
|
||||
Dim localZipCache As New List(Of LocalZipCacheEntry)
|
||||
|
||||
If ModpackInfo.HasModpackInfo(localPath) Then
|
||||
modpackInfo = ModpackInfo.Load(localPath)
|
||||
Else
|
||||
modpackInfo = New ModpackInfo
|
||||
End If
|
||||
|
||||
For Each iaction As InstallAction In checkResult.Actions
|
||||
Dim destFilePath As String = Path.Combine(localPath, iaction.DestPath)
|
||||
|
||||
If TypeOf iaction Is UpdateAction Then
|
||||
Dim uaction As UpdateAction = iaction
|
||||
|
||||
Select Case uaction.Type
|
||||
Case UpdateActionType.Update
|
||||
Await InstallFile(destFilePath, uaction.DownloadUrl, uaction.IsZip, uaction.ZipPath, localZipCache)
|
||||
Case UpdateActionType.Delete
|
||||
If uaction.IsDirectory Then
|
||||
If Directory.Exists(destFilePath) Then
|
||||
Directory.Delete(destFilePath, True)
|
||||
End If
|
||||
Else
|
||||
If File.Exists(destFilePath) Then
|
||||
File.Delete(destFilePath)
|
||||
End If
|
||||
End If
|
||||
Case UpdateActionType.Copy
|
||||
Dim srcFilePath As String = Path.Combine(localPath, uaction.SrcPath)
|
||||
If uaction.IsDirectory Then
|
||||
If Directory.Exists(srcFilePath) Then
|
||||
CopyDirectory(srcFilePath, destFilePath, True)
|
||||
End If
|
||||
Else
|
||||
If File.Exists(srcFilePath) Then
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(destFilePath))
|
||||
File.Copy(srcFilePath, destFilePath, True)
|
||||
End If
|
||||
End If
|
||||
Case UpdateActionType.Move
|
||||
Dim srcFilePath As String = Path.Combine(localPath, uaction.SrcPath)
|
||||
If uaction.IsDirectory Then
|
||||
If Directory.Exists(srcFilePath) Then
|
||||
Directory.Move(srcFilePath, destFilePath)
|
||||
End If
|
||||
Else
|
||||
If File.Exists(srcFilePath) Then
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(destFilePath))
|
||||
File.Move(srcFilePath, destFilePath, True)
|
||||
End If
|
||||
End If
|
||||
End Select
|
||||
Else
|
||||
Await InstallFile(destFilePath, iaction.DownloadUrl, iaction.IsZip, iaction.ZipPath, localZipCache)
|
||||
End If
|
||||
|
||||
processed += 1
|
||||
RaiseEvent InstallProgessUpdated(checkResult, processed)
|
||||
Next
|
||||
|
||||
'Save new modpack info
|
||||
modpackInfo.Version = checkResult.LatestVersion
|
||||
modpackInfo.Save(localPath)
|
||||
|
||||
'Delete cached zip files
|
||||
For Each task In localZipCache
|
||||
Directory.Delete(task.ExtractedZipPath, True)
|
||||
Next
|
||||
|
||||
Return True
|
||||
End Function
|
||||
|
||||
Private Async Function InstallFile(destFilePath As String, sourceUrl As String, isZip As Boolean, zipPath As String, localZipCache As List(Of LocalZipCacheEntry)) As Task
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(destFilePath))
|
||||
|
||||
'Download
|
||||
Dim fsDestinationPath As String = If(isZip, Path.Combine(Path.GetTempPath(), $"mc_update_file_{Date.Now.ToBinary}.zip"), destFilePath)
|
||||
Dim sRemote As Stream = Await httpClient.GetStreamAsync(sourceUrl)
|
||||
Dim fs As New FileStream(destFilePath, FileMode.Create, FileAccess.ReadWrite)
|
||||
Await sRemote.CopyToAsync(fs)
|
||||
sRemote.Close()
|
||||
fs.Close()
|
||||
|
||||
'Handle zip file
|
||||
If isZip Then
|
||||
'Extract
|
||||
Dim zipDir As String = $"{Path.GetFileNameWithoutExtension(fsDestinationPath)}_extracted"
|
||||
ZipFile.ExtractToDirectory(fsDestinationPath, zipDir)
|
||||
|
||||
'Copy content
|
||||
Dim zipSrc As String = Path.Combine(zipDir, zipPath)
|
||||
CopyDirectory(zipSrc, destFilePath, True)
|
||||
|
||||
'Delete/cache temporary files
|
||||
File.Delete(fsDestinationPath)
|
||||
localZipCache?.Add(New LocalZipCacheEntry With {
|
||||
.DownloadUrl = sourceUrl,
|
||||
.ExtractedZipPath = zipDir
|
||||
})
|
||||
End If
|
||||
End Function
|
||||
|
||||
End Class
|
||||
@@ -1,16 +1,16 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
|
||||
<PropertyGroup>
|
||||
<RootNamespace>ModpackUpdater.Manager</RootNamespace>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>true</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.IO.Compression.ZipFile" Version="4.3.0" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ModpackUpdater.Model\ModpackUpdater.Model.vbproj" />
|
||||
<ProjectReference Include="..\ModpackUpdater.Model\ModpackUpdater.Model.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
</Project>
|
||||
13
ModpackUpdater.Manager/UpdateCheckResult.cs
Normal file
13
ModpackUpdater.Manager/UpdateCheckResult.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using ModpackUpdater.Model;
|
||||
|
||||
namespace ModpackUpdater.Manager;
|
||||
|
||||
public class UpdateCheckResult
|
||||
{
|
||||
public Version CurrentVersion { get; set; }
|
||||
public Version LatestVersion { get; set; }
|
||||
public List<InstallAction> Actions { get; private set; } = [];
|
||||
public bool IsInstalled { get; set; }
|
||||
public bool HasError { get; set; }
|
||||
public bool HasUpdates => !IsInstalled || CurrentVersion < LatestVersion;
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
Imports ModpackUpdater.Model
|
||||
|
||||
Public Class UpdateCheckResult
|
||||
|
||||
Public Property CurrentVersion As Version
|
||||
Public Property LatestVersion As Version
|
||||
Public ReadOnly Property Actions As New List(Of InstallAction)
|
||||
Public Property IsInstalled As Boolean
|
||||
Public Property HasError As Boolean
|
||||
|
||||
Public ReadOnly Property HasUpdates As Boolean
|
||||
Get
|
||||
Return Not IsInstalled OrElse CurrentVersion < LatestVersion
|
||||
End Get
|
||||
End Property
|
||||
|
||||
End Class
|
||||
Reference in New Issue
Block a user