diff --git a/ModpackUpdater.Manager/ModpackInstaller.vb b/ModpackUpdater.Manager/ModpackInstaller.vb index 1c3728c..0d0950f 100644 --- a/ModpackUpdater.Manager/ModpackInstaller.vb +++ b/ModpackUpdater.Manager/ModpackInstaller.vb @@ -1,4 +1,5 @@ Imports System.IO +Imports System.IO.Compression Imports System.Net Imports System.Net.Http @@ -28,17 +29,23 @@ Public Class ModpackInstaller Return UpdateInfos.Parse(content) End Function - Public Async Function CheckForUpdates(ignoreRevmoedFiles As Boolean) As Task(Of UpdateCheckResult) - Dim infos As UpdateInfos = Await DownloadUpdateInfos() + 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 infos IsNot Nothing AndAlso infos.Updates.Any Then - Dim updatesOrderes = infos.Updates.OrderByDescending(Function(n) n.Version) - result.LatestVersion = updatesOrderes.First.Version + If ModpackInfo.HasModpackInfo(localPath) Then + Dim infos As UpdateInfos = Await DownloadUpdateInfos() + Dim modpackInfo As ModpackInfo = ModpackInfo.Load(localPath) - If ModpackInfo.HasModpackInfo(localPath) Then - 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) @@ -47,24 +54,37 @@ Public Class ModpackInstaller Dim actionsToAdd As New List(Of UpdateAction) For Each action In checkingVersion.Actions - If Not result.UpdateActions.Any(Function(n) n.DestPath = action.DestPath) Then + If Not result.Actions.Any(Function(n) n.DestPath = action.DestPath) Then actionsToAdd.Add(action) End If Next - result.UpdateActions.InsertRange(0, actionsToAdd) + 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 InstallUpdates(checkResult As UpdateCheckResult) As Task(Of Boolean?) + Public Async Function Install(checkResult As UpdateCheckResult) As Task(Of Boolean?) Dim modpackInfo As ModpackInfo + Dim processed As Integer = 0 If ModpackInfo.HasModpackInfo(localPath) Then modpackInfo = ModpackInfo.Load(localPath) @@ -72,41 +92,41 @@ Public Class ModpackInstaller modpackInfo = New ModpackInfo End If - Dim processed As Integer = 0 - For Each action As UpdateAction In checkResult.UpdateActions - Dim destFilePath As String = Path.Combine(localPath, action.DestPath) + For Each iaction As InstallAction In checkResult.Actions + Dim destFilePath As String = Path.Combine(localPath, iaction.DestPath) - Select Case action.Type - Case UpdateActionType.Update - Directory.CreateDirectory(Path.GetDirectoryName(destFilePath)) - Dim sRemote As Stream = Await httpClient.GetStreamAsync(action.DownloadUrl) - Dim fs As New FileStream(destFilePath, FileMode.Create, FileAccess.ReadWrite) - Await sRemote.CopyToAsync(fs) - sRemote.Close() - fs.Close() - Case UpdateActionType.Delete - If action.IsDirectory Then - If Directory.Exists(destFilePath) Then - Directory.Delete(destFilePath, True) + 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) + 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 - Else - If File.Exists(destFilePath) Then - File.Delete(destFilePath) + Case UpdateActionType.Copy + Dim srcFilePath As String = Path.Combine(localPath, uaction.SrcPath) + If File.Exists(srcFilePath) Then + Directory.CreateDirectory(Path.GetDirectoryName(destFilePath)) + File.Copy(srcFilePath, destFilePath, True) End If - End If - Case UpdateActionType.Copy - Dim srcFilePath As String = Path.Combine(localPath, action.SrcPath) - If File.Exists(srcFilePath) Then - Directory.CreateDirectory(Path.GetDirectoryName(destFilePath)) - File.Copy(srcFilePath, destFilePath, True) - End If - Case UpdateActionType.Move - Dim srcFilePath As String = Path.Combine(localPath, action.SrcPath) - If File.Exists(srcFilePath) Then - Directory.CreateDirectory(Path.GetDirectoryName(destFilePath)) - File.Move(srcFilePath, destFilePath, True) - End If - End Select + Case UpdateActionType.Move + Dim srcFilePath As String = Path.Combine(localPath, uaction.SrcPath) + If File.Exists(srcFilePath) Then + Directory.CreateDirectory(Path.GetDirectoryName(destFilePath)) + File.Move(srcFilePath, destFilePath, True) + End If + End Select + Else + Await InstallFile(destFilePath, iaction.DownloadUrl, iaction.IsZip, iaction.ZipPath) + End If processed += 1 RaiseEvent InstallProgessUpdated(checkResult, processed) @@ -118,4 +138,23 @@ Public Class ModpackInstaller Return True End Function + Private Async Function InstallFile(destFilePath As String, sourceUrl As String, isZip As Boolean, zipPath As String) As Task + Directory.CreateDirectory(Path.GetDirectoryName(destFilePath)) + + 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() + + If isZip Then + Dim zipDir As String = $"{Path.GetFileNameWithoutExtension(fsDestinationPath)}_extracted" + ZipFile.ExtractToDirectory(fsDestinationPath, zipDir) + '... + File.Delete(fsDestinationPath) + Directory.Delete(zipDir, True) + End If + End Function + End Class diff --git a/ModpackUpdater.Manager/ModpackUpdater.Manager.vbproj b/ModpackUpdater.Manager/ModpackUpdater.Manager.vbproj index a69543d..c976e8f 100644 --- a/ModpackUpdater.Manager/ModpackUpdater.Manager.vbproj +++ b/ModpackUpdater.Manager/ModpackUpdater.Manager.vbproj @@ -5,6 +5,10 @@ net8.0 + + + + diff --git a/ModpackUpdater.Manager/UpdateCheckResult.vb b/ModpackUpdater.Manager/UpdateCheckResult.vb index ae15c4d..09b33fd 100644 --- a/ModpackUpdater.Manager/UpdateCheckResult.vb +++ b/ModpackUpdater.Manager/UpdateCheckResult.vb @@ -4,12 +4,13 @@ Public Class UpdateCheckResult Public Property CurrentVersion As Version Public Property LatestVersion As Version - Public ReadOnly Property UpdateActions As New List(Of UpdateAction) + 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 CurrentVersion < LatestVersion + Return Not IsInstalled OrElse CurrentVersion < LatestVersion End Get End Property diff --git a/ModpackUpdater.Model/InstallAction.vb b/ModpackUpdater.Model/InstallAction.vb index 908f32e..16aecd9 100644 --- a/ModpackUpdater.Model/InstallAction.vb +++ b/ModpackUpdater.Model/InstallAction.vb @@ -1,9 +1,8 @@ -Imports Newtonsoft.Json.Converters - -Public Class InstallAction +Public Class InstallAction + Public Property IsZip As Boolean + Public Property ZipPath As String Public Property DestPath As String Public Property DownloadUrl As String - Public Property IsZip As Boolean End Class diff --git a/ModpackUpdater.Model/UpdateAction.vb b/ModpackUpdater.Model/UpdateAction.vb index a5cb520..0de1622 100644 --- a/ModpackUpdater.Model/UpdateAction.vb +++ b/ModpackUpdater.Model/UpdateAction.vb @@ -2,12 +2,11 @@ Imports Newtonsoft.Json.Converters Public Class UpdateAction + Inherits InstallAction Public Property Type As UpdateActionType - Public Property DestPath As String Public Property SrcPath As String - Public Property DownloadUrl As String Public Property IsDirectory As Boolean End Class diff --git a/ModpackUpdater/Form1.vb b/ModpackUpdater/Form1.vb index 97eb809..4cd3638 100644 --- a/ModpackUpdater/Form1.vb +++ b/ModpackUpdater/Form1.vb @@ -97,7 +97,7 @@ Public Class Form1 SetStatus(LangRes.StatusText_CheckingForUpdates, MySymbols.icons8_update_16px) Try - lastUpdateCheckResult = Await updater.CheckForUpdates(Not AppConfig.Instance.AllowRemoveLocalFiles) + lastUpdateCheckResult = Await updater.Check(Not AppConfig.Instance.AllowRemoveLocalFiles) Catch ex As Exception SetStatus(LangRes.StatusText_ErrorWhileUpdateCheckOrUpdate, MySymbols.icons8_delete_16px) Finally @@ -112,7 +112,7 @@ Public Class Form1 currentUpdating = True Try - If Await updater.InstallUpdates(lastUpdateCheckResult) Then + If Await updater.Install(lastUpdateCheckResult) Then lastUpdateCheckResult = Nothing 'Reset last update check, a new one would be needed now. SetStatus(LangRes.StatusTest_EverythingOk, MySymbols.icons8_checkmark_16px) Else @@ -132,7 +132,7 @@ Public Class Form1 End Function Private Sub Update_InstallProgessUpdated(result As UpdateCheckResult, processedSyncs As Integer) - Dim actionCount = result.UpdateActions.Count + Dim actionCount = result.Actions.Count SetStatus(Math.Round(processedSyncs / actionCount * 100, 1) & "%", MySymbols.icons8_software_installer_16px) End Sub