Merge branch 'feat/rework-install' into 'master'

Feat/rework install

See merge request gaming/minecraft/minecraft-modpack-updater!1
This commit is contained in:
2024-06-22 16:59:07 +00:00
86 changed files with 1956 additions and 6088 deletions

2
.gitignore vendored
View File

@@ -174,7 +174,7 @@ publish/
*.azurePubxml *.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings, # Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted # but database connection strings (with potential passwords) will be unencrypted
*.pubxml # *.pubxml
*.publishproj *.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to # Microsoft Azure Web App publish settings. Comment the next line if you want to

View File

@@ -1,12 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<RootNamespace>ModpackUpdater.GitLab</RootNamespace>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\ModpackUpdater.Model\ModpackUpdater.Model.vbproj" />
</ItemGroup>
</Project>

View File

@@ -1,33 +0,0 @@
Imports System.Net.Http
Imports ModpackUpdater.Model
Imports Newtonsoft.Json
Public Class UpdateConfigExt
'<Extension>
'Public Sub SaveToSnippet(config As UpdateConfig, gitlabUrl As String, gitlabToken As String, projectId As Integer, snippetId As Integer, snippetFilePath As String)
' Dim client As New GitLabClient(gitlabUrl, gitlabToken)
' Dim update As New SnippetProjectUpdate With {
' .Visibility = VisibilityLevel.Public,
' .ProjectId = projectId,
' .SnippetId = snippetId,
' .Files = {
' New SnippetUpdateFile With {
' .Action = SnippetUpdateFileAction.Update.Create,
' .FilePath = snippetFilePath,
' .Content = JsonConvert.SerializeObject(config)
' }
' }
' }
' client.Snippets.Update(update)
'End Sub
Public Shared Function LoadFromSnippet(url As String) As UpdateConfig
Dim client As New HttpClient
Dim result = client.GetStringAsync(url).Result
Return JsonConvert.DeserializeObject(Of UpdateConfig)(result)
End Function
End Class

View File

@@ -0,0 +1,45 @@
using ModpackUpdater.Model;
namespace ModpackUpdater.Manager;
public static class Extensions
{
public static bool IsSide(this Side @this, Side side)
{
return @this.HasFlag(side) || side.HasFlag(@this);
}
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, true);
}
// 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);
}
}
}
}

View File

@@ -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

View File

@@ -0,0 +1,240 @@
using ModpackUpdater.Model;
using System.IO.Compression;
namespace ModpackUpdater.Manager;
public class ModpackInstaller(ModpackConfig updateConfig, ModpackInfo modpackInfo)
{
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 readonly 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(UpdateCheckOptions options)
{
InstallInfos installInfos = null;
UpdateInfos updateInfos = null;
var result = new UpdateCheckResult();
var exists = modpackInfo.Exists;
if (updateConfig.Maintenance && !options.IgnoreMaintenance)
{
result.IsInMaintenance = true;
return result;
}
if (modpackInfo == null || !Directory.Exists(modpackInfo.LocaLPath))
{
result.HasError = true;
return result;
}
if (!exists)
{
installInfos = await DownloadInstallInfos();
if (installInfos is not null && installInfos.Actions.Count != 0)
{
var actions = installInfos.Actions.Where(n => n.Side.IsSide(options.Side) && (!n.IsExtra || options.IncludeExtras));
if (actions.Any())
{
result.Actions.AddRange(installInfos.Actions);
result.LatestVersion = installInfos.Version;
result.CurrentVersion = installInfos.Version;
}
}
if (result.Actions.Count == 0)
result.HasError = true;
}
if (exists || options.AllowUpdaterAfterInstall)
{
updateInfos = await DownloadUpdateInfos();
if (updateInfos is not null && updateInfos.Updates.Count != 0)
{
var updatesOrderes = updateInfos.Updates.OrderByDescending(n => n.Version);
result.LatestVersion = updatesOrderes.First().Version;
if (exists)
result.CurrentVersion = modpackInfo.Version;
result.IsInstalled = true;
var checkingVersionIndex = 0;
var checkingVersion = updatesOrderes.ElementAtOrDefault(checkingVersionIndex);
var actionsZeroIndex = result.Actions.Count; // Ensure we insert update actions behind install actions
while (checkingVersion is not null && checkingVersion.Version > result.CurrentVersion)
{
var actionsToAdd = new List<UpdateAction>();
foreach (var action in checkingVersion.Actions)
{
if (action.Side.IsSide(options.Side) && (!action.IsExtra || options.IncludeExtras) && !result.Actions.Any(n => n.DestPath == action.DestPath))
actionsToAdd.Add(action);
}
result.Actions.InsertRange(actionsZeroIndex, actionsToAdd);
checkingVersionIndex += 1;
checkingVersion = updatesOrderes.ElementAtOrDefault(checkingVersionIndex);
}
}
else
result.HasError = true;
}
return result;
}
public async Task<bool?> Install(UpdateCheckResult checkResult)
{
int processed = 0;
var localZipCache = new List<LocalZipCacheEntry>();
foreach (InstallAction iaction in checkResult.Actions)
{
string destFilePath = Path.Combine(modpackInfo.LocaLPath, iaction.DestPath);
if (iaction is UpdateAction uaction)
{
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(modpackInfo.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(modpackInfo.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.ConfigUrl = updateConfig.ConfigUrl;
modpackInfo.Save();
// 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));
if (!isZip || localZipCache.FirstOrDefault(n => n.DownloadUrl == sourceUrl) is not LocalZipCacheEntry cachedZipInfo)
{
// 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(fsDestinationPath, FileMode.Create, FileAccess.ReadWrite);
await sRemote.CopyToAsync(fs);
await fs.FlushAsync();
sRemote.Close();
fs.Close();
// Extract
if (isZip)
{
// Extract files
var zipDir = Path.Combine(Path.GetDirectoryName(fsDestinationPath), Path.GetFileNameWithoutExtension(fsDestinationPath));
ZipFile.ExtractToDirectory(fsDestinationPath, zipDir);
// Create cache entry
cachedZipInfo = new()
{
DownloadUrl = sourceUrl,
ExtractedZipPath = zipDir
};
localZipCache.Add(cachedZipInfo);
// Remofe temp zip file
File.Delete(fsDestinationPath);
}
else
cachedZipInfo = null;
}
// Handle zip file content
if (cachedZipInfo != null)
{
// Copy content
var zipSrc = Path.Combine(cachedZipInfo.ExtractedZipPath, zipPath);
Extensions.CopyDirectory(zipSrc, destFilePath, true);
}
}
}

View File

@@ -1,16 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<RootNamespace>ModpackUpdater.Manager</RootNamespace>
<TargetFramework>net8.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>true</ImplicitUsings>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="WebDav.Client" Version="2.8.0" /> <PackageReference Include="System.IO.Compression.ZipFile" Version="4.3.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\ModpackUpdater.Model\ModpackUpdater.Model.vbproj" /> <ProjectReference Include="..\ModpackUpdater.Model\ModpackUpdater.Model.csproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -0,0 +1,11 @@
using ModpackUpdater.Model;
namespace ModpackUpdater.Manager;
public class UpdateCheckOptions
{
public bool IgnoreMaintenance { get; set; }
public bool AllowUpdaterAfterInstall { get; set; } = true;
public Side Side { get; set; } = Side.Client;
public bool IncludeExtras { get; set; }
}

View File

@@ -0,0 +1,14 @@
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 IsInMaintenance { get; set; }
public bool HasUpdates => !IsInstalled || CurrentVersion < LatestVersion;
}

View File

@@ -1,23 +0,0 @@
Imports ModpackUpdater.Model
Public Class UpdateCheckResult
Public Property IsLegacy As Boolean
Public ReadOnly Property SyncFiles As New List(Of UpdateSyncFile)
Public Property CurrentVersion As Version
Public Property LatestVersion As Version
Public ReadOnly Property UpdateActions As New List(Of UpdateAction)
Public Property HasError As Boolean
Public ReadOnly Property HasUpdates As Boolean
Get
If IsLegacy Then
Return SyncFiles.Where(Function(n) n.SyncAction <> UpdateSyncAction.None).Any
Else
Return CurrentVersion < LatestVersion
End If
End Get
End Property
End Class

View File

@@ -1,268 +0,0 @@
Imports System.IO
Imports System.Net
Imports System.Net.Http
Imports ModpackUpdater.Model
Imports WebDav
Public Class UpdateInstaller
Public Event InstallProgessUpdated(result As UpdateCheckResult, processedSyncs As Integer)
Public Event CheckingProgressUpdated(toCheck As Integer, processed As Integer)
Private ReadOnly updateConfig As UpdateConfig
Private ReadOnly localPath As String
Private webdavClient As WebDavClient = Nothing
Private httpClient As New HttpClient
Public Sub New(updateConfig As UpdateConfig, localPath As String)
Me.updateConfig = updateConfig
Me.localPath = localPath
End Sub
Protected Overrides Sub Finalize()
httpClient.Dispose()
MyBase.Finalize()
End Sub
Private Function CreateClient() As WebDavClient
If webdavClient Is Nothing Then
Dim params As New WebDavClientParams With {
.BaseAddress = New Uri(updateConfig.WebdavURL),
.Credentials = New NetworkCredential(updateConfig.WebdavUsername, updateConfig.WebdavPassword)
}
webdavClient = New WebDavClient(params)
End If
Return webdavClient
End Function
Private Async Function DownloadUpdateInfos() As Task(Of UpdateInfos)
Dim content As String = Await httpClient.GetStringAsync(updateConfig.UpdateUrl)
Return UpdateInfos.Parse(content)
End Function
Public Async Function CheckForUpdates(ignoreRevmoedFiles As Boolean) As Task(Of UpdateCheckResult)
Dim infos As UpdateInfos = Await DownloadUpdateInfos()
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 modpackInfo As ModpackInfo = ModpackInfo.Load(localPath)
result.CurrentVersion = modpackInfo.Version
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.UpdateActions.Any(Function(n) n.DestPath = action.DestPath) Then
actionsToAdd.Add(action)
End If
Next
result.UpdateActions.InsertRange(0, actionsToAdd)
checkingVersionIndex += 1
checkingVersion = updatesOrderes.ElementAtOrDefault(checkingVersionIndex)
Loop
Else
Await CheckForUpdatesLegacy(result, ignoreRevmoedFiles)
End If
End If
Return result
End Function
Private Async Function CheckForUpdatesLegacy(result As UpdateCheckResult, ignoreRevmoedFiles As Boolean) As Task
Dim client As WebDavClient = CreateClient()
Dim resTopFolder As WebDavResource = Nothing
Dim checkedFiles = New List(Of String)()
Dim responseSuccessfull As Boolean = False
result.CurrentVersion = New Version("0.0.0.0")
result.IsLegacy = True
'Check for new & updated files
Dim response = Await client.Propfind(String.Empty, New PropfindParameters() With {.ApplyTo = ApplyTo.Propfind.ResourceAndAncestors})
If resTopFolder Is Nothing AndAlso response.IsSuccessful AndAlso response.Resources.Any() Then
resTopFolder = response.Resources.ElementAtOrDefault(0)
responseSuccessfull = True
End If
If responseSuccessfull AndAlso response.Resources.Count > 1 Then
Dim i As Integer = 1
Dim loopTo As Integer = response.Resources.Count - 1
Do While i <= loopTo
Dim res = response.Resources.ElementAtOrDefault(i)
Dim isFolder As Boolean = res.Uri.EndsWith("/")
If Not isFolder Then
Dim syncAction? As UpdateSyncAction = Nothing
Dim localFile As String
Dim remoteFile As String
'Get remote file path
remoteFile = res.Uri
'Get local file path
localFile = Path.Combine(localPath, Uri.UnescapeDataString(res.Uri.Substring(resTopFolder.Uri.Length)).Replace("/", "\"))
'Check action
If File.Exists(localFile) Then
If File.GetLastWriteTime(localFile) < res.LastModifiedDate = True Then
syncAction = UpdateSyncAction.UpdatedFile
End If
Else
syncAction = UpdateSyncAction.NewFile
End If
'Add to list
checkedFiles.Add(localFile)
If syncAction IsNot Nothing Then
result.SyncFiles.Add(New UpdateSyncFile(syncAction, localFile, remoteFile))
End If
End If
i += 1
RaiseEvent CheckingProgressUpdated(loopTo, i)
Loop
End If
'Find all old files to remove
If responseSuccessfull Then
Dim allLocalFiles = Directory.GetFiles(localPath, "*", SearchOption.AllDirectories)
For Each lf As String In allLocalFiles
Dim isKnown As Boolean = False
For Each checkedFile As String In checkedFiles
If Not isKnown AndAlso If(checkedFile, "") = If(lf, "") Then
isKnown = True
End If
Next
If Not isKnown Then
result.SyncFiles.Add(New UpdateSyncFile(If(ignoreRevmoedFiles, UpdateSyncAction.None, UpdateSyncAction.RemovedFile), lf, String.Empty))
End If
Next
End If
End Function
Public Async Function InstallUpdates(checkResult As UpdateCheckResult, Optional ignoreActions As UpdateSyncAction = UpdateSyncAction.None) As Task(Of Boolean?)
Dim isSuccessfully As Boolean
Dim modpackInfo As ModpackInfo
If ModpackInfo.HasModpackInfo(localPath) Then
modpackInfo = ModpackInfo.Load(localPath)
Else
modpackInfo = New ModpackInfo
End If
If checkResult.IsLegacy Then
isSuccessfully = Await InstallUpdatesLegacy(checkResult, ignoreActions)
Else
Dim processed As Integer = 0
For Each action As UpdateAction In checkResult.UpdateActions
Dim destFilePath As String = Path.Combine(localPath, action.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)
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, 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
processed += 1
RaiseEvent InstallProgessUpdated(checkResult, processed)
Next
isSuccessfully = True
End If
If isSuccessfully Then
modpackInfo.Version = checkResult.LatestVersion
modpackInfo.Save(localPath)
End If
Return isSuccessfully
End Function
Private Async Function InstallUpdatesLegacy(checkResult As UpdateCheckResult, Optional ignoreActions As UpdateSyncAction = UpdateSyncAction.None) As Task(Of Boolean?)
Dim client As WebDavClient = CreateClient()
Dim success As Boolean? = False
Dim processed As Integer = 0
'Init process update
RaiseEvent InstallProgessUpdated(checkResult, processed)
For Each syncFile In checkResult.SyncFiles
If syncFile.SyncAction <> (ignoreActions And syncFile.SyncAction) Then
If syncFile.SyncAction = UpdateSyncAction.UpdatedFile OrElse
syncFile.SyncAction = UpdateSyncAction.RemovedFile Then
If File.Exists(syncFile.LocalFile) Then
File.Delete(syncFile.LocalFile)
End If
End If
If syncFile.SyncAction = UpdateSyncAction.UpdatedFile OrElse
syncFile.SyncAction = UpdateSyncAction.NewFile Then
Dim response = Await client.GetProcessedFile(syncFile.RemoveFile)
Dim dirParent As New DirectoryInfo(Path.GetDirectoryName(syncFile.LocalFile))
If response.IsSuccessful Then
If Not dirParent.Exists Then
dirParent.Create()
End If
Dim fs As New FileStream(syncFile.LocalFile, FileMode.Create, FileAccess.Write)
response.Stream.CopyTo(fs)
fs.Close()
success = True
End If
End If
End If
processed += 1
RaiseEvent InstallProgessUpdated(checkResult, processed)
Next
Return success
End Function
End Class

View File

@@ -1,11 +0,0 @@
Imports Newtonsoft.Json
Imports Newtonsoft.Json.Converters
<JsonConverter(GetType(StringEnumConverter))>
<Flags>
Public Enum UpdateSyncAction
None
NewFile
RemovedFile
UpdatedFile = 4
End Enum

View File

@@ -1,13 +0,0 @@
Public Class UpdateSyncFile
Public ReadOnly Property SyncAction As UpdateSyncAction
Public ReadOnly Property LocalFile As string
Public ReadOnly Property RemoveFile As string
Public Sub New(syncAction As UpdateSyncAction, localFile As string, remoteFile As string)
Me.SyncAction = syncAction
Me.LocalFile = localFile
Me.RemoveFile = remoteFile
End Sub
End Class

View File

@@ -0,0 +1,11 @@
namespace ModpackUpdater.Model;
public class InstallAction
{
public bool IsZip { get; set; }
public string ZipPath { get; set; }
public string DestPath { get; set; }
public string DownloadUrl { get; set; }
public Side Side { get; set; } = Side.Both;
public bool IsExtra { get; set; }
}

View File

@@ -0,0 +1,16 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace ModpackUpdater.Model;
public class InstallInfos
{
[JsonConverter(typeof(VersionConverter))]
public Version Version { get; set; }
public List<InstallAction> Actions { get; } = [];
public static InstallInfos Parse(string content)
{
return JsonConvert.DeserializeObject<InstallInfos>(content);
}
}

View File

@@ -0,0 +1,23 @@
using Newtonsoft.Json;
namespace ModpackUpdater.Model;
public class ModpackConfig
{
public bool Maintenance { get; set; }
public string Name { get; set; }
public string Key { get; set; }
public string UpdateUrl { get; set; }
public string InstallUrl { get; set; }
[JsonIgnore]
public string ConfigUrl { get; set; }
public static ModpackConfig LoadFromUrl(string url)
{
string result = new HttpClient().GetStringAsync(url).Result;
var config = JsonConvert.DeserializeObject<ModpackConfig>(result);
config.ConfigUrl = url;
return config;
}
}

View File

@@ -0,0 +1,58 @@
using Microsoft.VisualBasic.CompilerServices;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace ModpackUpdater.Model;
public class ModpackInfo
{
private const string FILENAME_MODPACKINFO = "modpack-info.json";
[JsonConverter(typeof(VersionConverter))]
public Version Version { get; set; }
public string ConfigUrl { get; set; }
public string ExtrasKey { get; set; }
[JsonIgnore]
public string LocaLPath { get; private set; }
[JsonIgnore]
public bool Exists => File.Exists(GetFilePath(LocaLPath));
public void Save()
{
File.WriteAllText(Conversions.ToString(GetFilePath(LocaLPath)), JsonConvert.SerializeObject(this));
}
public void Save(string mcRoot)
{
LocaLPath = mcRoot;
Save();
}
public static ModpackInfo TryLoad(string mcRoot)
{
if (HasModpackInfo(mcRoot))
return Load(mcRoot);
return new()
{
LocaLPath = mcRoot
};
}
public static ModpackInfo Load(string mcRoot)
{
var info = JsonConvert.DeserializeObject<ModpackInfo>(File.ReadAllText(GetFilePath(mcRoot)));
info.LocaLPath = mcRoot;
return info;
}
public static bool HasModpackInfo(string mcRoot)
{
return File.Exists(Conversions.ToString(GetFilePath(mcRoot)));
}
private static string GetFilePath(string mcRoot)
{
return Path.Combine(mcRoot, FILENAME_MODPACKINFO);
}
}

View File

@@ -1,29 +0,0 @@
Imports System.IO
Imports Newtonsoft.Json
Imports Newtonsoft.Json.Converters
Public Class ModpackInfo
Private Const FILENAME_MODPACKINFO = "modpack-info.json"
<JsonConverter(GetType(VersionConverter))>
Public Property Version As Version
Public Sub Save(mcRoot As String)
File.WriteAllText(GetFilePath(mcRoot), JsonConvert.SerializeObject(Me))
End Sub
Public Shared Function Load(mcRoot As String) As ModpackInfo
Return JsonConvert.DeserializeObject(Of ModpackInfo)(File.ReadAllText(GetFilePath(mcRoot)))
End Function
Public Shared Function HasModpackInfo(mcRoot As String) As Boolean
Return File.Exists(GetFilePath(mcRoot))
End Function
Private Shared Function GetFilePath(mcRoot As String)
Return Path.Combine(mcRoot, FILENAME_MODPACKINFO)
End Function
End Class

View File

@@ -1,12 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<RootNamespace>ModpackUpdater.Model</RootNamespace>
<TargetFramework>net8.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>true</ImplicitUsings>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Pilz.Cryptography" Version="2.0.1" /> <PackageReference Include="Pilz.Cryptography" Version="2.0.1" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -0,0 +1,12 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace ModpackUpdater.Model;
[JsonConverter(typeof(StringEnumConverter)), Flags]
public enum Side
{
Client = 1,
Server = 2,
Both = Client | Server,
}

View File

@@ -0,0 +1,12 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace ModpackUpdater.Model;
public class UpdateAction : InstallAction
{
[JsonConverter(typeof(StringEnumConverter))]
public UpdateActionType Type { get; set; }
public string SrcPath { get; set; }
public bool IsDirectory { get; set; }
}

View File

@@ -1,13 +0,0 @@
Imports Newtonsoft.Json
Imports Newtonsoft.Json.Converters
Public Class UpdateAction
<JsonConverter(GetType(StringEnumConverter))>
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

View File

@@ -0,0 +1,10 @@
namespace ModpackUpdater.Model;
public enum UpdateActionType
{
None,
Update,
Delete,
Move,
Copy
}

View File

@@ -1,7 +0,0 @@
Public Enum UpdateActionType
None
Update
Delete
Move
Copy
End Enum

View File

@@ -1,22 +0,0 @@
Imports System.IO
Imports Newtonsoft.Json
Imports Pilz.Cryptography
Public Class UpdateConfig
Public Property UpdateUrl As String
Public Property WebdavURL As SecureString
Public Property WebdavUsername As SecureString
Public Property WebdavPassword As SecureString
Public Sub SaveToFile(filePath As String)
File.WriteAllText(filePath, JsonConvert.SerializeObject(Me))
End Sub
Public Shared Function LoadFromFile(filePath As String) As UpdateConfig
Return JsonConvert.DeserializeObject(Of UpdateConfig)(File.ReadAllText(filePath))
End Function
End Class

View File

@@ -0,0 +1,11 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace ModpackUpdater.Model;
public class UpdateInfo
{
[JsonConverter(typeof(VersionConverter))]
public Version Version { get; set; }
public List<UpdateAction> Actions { get; private set; } = [];
}

View File

@@ -1,10 +0,0 @@
Imports Newtonsoft.Json
Imports Newtonsoft.Json.Converters
Public Class UpdateInfo
<JsonConverter(GetType(VersionConverter))>
Public Property Version As Version
Public ReadOnly Property Actions As New List(Of UpdateAction)
End Class

View File

@@ -0,0 +1,13 @@
using Newtonsoft.Json;
namespace ModpackUpdater.Model;
public class UpdateInfos
{
public List<UpdateInfo> Updates { get; private set; } = [];
public static UpdateInfos Parse(string content)
{
return JsonConvert.DeserializeObject<UpdateInfos>(content);
}
}

View File

@@ -1,11 +0,0 @@
Imports Newtonsoft.Json
Public Class UpdateInfos
Public ReadOnly Property Updates As New List(Of UpdateInfo)
Public Shared Function Parse(content As String) As UpdateInfos
Return JsonConvert.DeserializeObject(Of UpdateInfos)(content)
End Function
End Class

View File

@@ -3,13 +3,11 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17 # Visual Studio Version 17
VisualStudioVersion = 17.2.32526.322 VisualStudioVersion = 17.2.32526.322
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "ModpackUpdater", "ModpackUpdater\ModpackUpdater.vbproj", "{33DD239C-1F33-40F9-908F-54BC02FBA420}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ModpackUpdater", "ModpackUpdater\ModpackUpdater.csproj", "{81F9A2F7-D36B-0F08-12D7-9EC2606C9080}"
EndProject EndProject
Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "ModpackUpdater.Model", "ModpackUpdater.Model\ModpackUpdater.Model.vbproj", "{BC4FE51B-4045-432C-B4D9-8C6CF5372DC0}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ModpackUpdater.Model", "ModpackUpdater.Model\ModpackUpdater.Model.csproj", "{0E6B6470-8C1D-0CDD-3681-461297A01960}"
EndProject EndProject
Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "ModpackUpdater.Manager", "ModpackUpdater.Manager\ModpackUpdater.Manager.vbproj", "{618DAFD6-3336-4621-82F9-EA5C783D2D2E}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ModpackUpdater.Manager", "ModpackUpdater.Manager\ModpackUpdater.Manager.csproj", "{D3A92EBD-FF6E-09D0-00A1-20221AAA198E}"
EndProject
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "ModpackUpdater.GitLab", "ModpackUpdater.GitLab\ModpackUpdater.GitLab.vbproj", "{65D44991-EB3B-4AC4-9166-3E8D0BADD402}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -17,22 +15,18 @@ Global
Release|Any CPU = Release|Any CPU Release|Any CPU = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{33DD239C-1F33-40F9-908F-54BC02FBA420}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {81F9A2F7-D36B-0F08-12D7-9EC2606C9080}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{33DD239C-1F33-40F9-908F-54BC02FBA420}.Debug|Any CPU.Build.0 = Debug|Any CPU {81F9A2F7-D36B-0F08-12D7-9EC2606C9080}.Debug|Any CPU.Build.0 = Debug|Any CPU
{33DD239C-1F33-40F9-908F-54BC02FBA420}.Release|Any CPU.ActiveCfg = Release|Any CPU {81F9A2F7-D36B-0F08-12D7-9EC2606C9080}.Release|Any CPU.ActiveCfg = Release|Any CPU
{33DD239C-1F33-40F9-908F-54BC02FBA420}.Release|Any CPU.Build.0 = Release|Any CPU {81F9A2F7-D36B-0F08-12D7-9EC2606C9080}.Release|Any CPU.Build.0 = Release|Any CPU
{BC4FE51B-4045-432C-B4D9-8C6CF5372DC0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {0E6B6470-8C1D-0CDD-3681-461297A01960}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BC4FE51B-4045-432C-B4D9-8C6CF5372DC0}.Debug|Any CPU.Build.0 = Debug|Any CPU {0E6B6470-8C1D-0CDD-3681-461297A01960}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BC4FE51B-4045-432C-B4D9-8C6CF5372DC0}.Release|Any CPU.ActiveCfg = Release|Any CPU {0E6B6470-8C1D-0CDD-3681-461297A01960}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BC4FE51B-4045-432C-B4D9-8C6CF5372DC0}.Release|Any CPU.Build.0 = Release|Any CPU {0E6B6470-8C1D-0CDD-3681-461297A01960}.Release|Any CPU.Build.0 = Release|Any CPU
{618DAFD6-3336-4621-82F9-EA5C783D2D2E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {D3A92EBD-FF6E-09D0-00A1-20221AAA198E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{618DAFD6-3336-4621-82F9-EA5C783D2D2E}.Debug|Any CPU.Build.0 = Debug|Any CPU {D3A92EBD-FF6E-09D0-00A1-20221AAA198E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{618DAFD6-3336-4621-82F9-EA5C783D2D2E}.Release|Any CPU.ActiveCfg = Release|Any CPU {D3A92EBD-FF6E-09D0-00A1-20221AAA198E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{618DAFD6-3336-4621-82F9-EA5C783D2D2E}.Release|Any CPU.Build.0 = Release|Any CPU {D3A92EBD-FF6E-09D0-00A1-20221AAA198E}.Release|Any CPU.Build.0 = Release|Any CPU
{65D44991-EB3B-4AC4-9166-3E8D0BADD402}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{65D44991-EB3B-4AC4-9166-3E8D0BADD402}.Debug|Any CPU.Build.0 = Debug|Any CPU
{65D44991-EB3B-4AC4-9166-3E8D0BADD402}.Release|Any CPU.ActiveCfg = Release|Any CPU
{65D44991-EB3B-4AC4-9166-3E8D0BADD402}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

37
ModpackUpdater.sln.bak Normal file
View File

@@ -0,0 +1,37 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.2.32526.322
MinimumVisualStudioVersion = 10.0.40219.1
Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "ModpackUpdater", "ModpackUpdater\ModpackUpdater.vbproj", "{33DD239C-1F33-40F9-908F-54BC02FBA420}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ModpackUpdater.Model", "ModpackUpdater.Model\ModpackUpdater.Model.csproj", "{0E6B6470-8C1D-0CDD-3681-461297A01960}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ModpackUpdater.Manager", "ModpackUpdater.Manager\ModpackUpdater.Manager.csproj", "{D3A92EBD-FF6E-09D0-00A1-20221AAA198E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{33DD239C-1F33-40F9-908F-54BC02FBA420}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{33DD239C-1F33-40F9-908F-54BC02FBA420}.Debug|Any CPU.Build.0 = Debug|Any CPU
{33DD239C-1F33-40F9-908F-54BC02FBA420}.Release|Any CPU.ActiveCfg = Release|Any CPU
{33DD239C-1F33-40F9-908F-54BC02FBA420}.Release|Any CPU.Build.0 = Release|Any CPU
{0E6B6470-8C1D-0CDD-3681-461297A01960}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0E6B6470-8C1D-0CDD-3681-461297A01960}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0E6B6470-8C1D-0CDD-3681-461297A01960}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0E6B6470-8C1D-0CDD-3681-461297A01960}.Release|Any CPU.Build.0 = Release|Any CPU
{D3A92EBD-FF6E-09D0-00A1-20221AAA198E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D3A92EBD-FF6E-09D0-00A1-20221AAA198E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D3A92EBD-FF6E-09D0-00A1-20221AAA198E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D3A92EBD-FF6E-09D0-00A1-20221AAA198E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {322E6A6B-9F3E-4E88-8945-C98A9EF613BF}
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,26 @@
using Newtonsoft.Json;
using Pilz.Configuration;
namespace ModpackUpdater;
public class AppConfig : IChildSettings, ISettingsIdentifier
{
public static string Identifier => "pilz.appconfig";
public string LastMinecraftProfilePath { get; set; }
[JsonIgnore, Obsolete]
public string ConfigFilePath { get; private set; }
[JsonProperty("ConfigFilePath"), Obsolete]
private string ConfigFilePathLegacy
{
set => ConfigFilePath = value;
}
public void Reset()
{
LastMinecraftProfilePath = null;
}
public static AppConfig Instance => Program.Settings.Get<AppConfig>();
}

View File

@@ -1,59 +0,0 @@
Imports System.IO
Imports Newtonsoft.Json.Linq
Public Class AppConfig
Public Property LastMinecraftProfilePath As String
Public Property LastConfigFilePath As String
Public Property KeepLocalFiles As New List(Of String)
Public Property AllowRemoveLocalFiles As Boolean
Public Sub Reset()
KeepLocalFiles.Clear()
KeepLocalFiles.Add("OptiFine_1.7.10_HD_U_E7.jar")
AllowRemoveLocalFiles = False
End Sub
Public Shared ReadOnly Property Instance As AppConfig
Get
Static myInstance As AppConfig = Nothing
If myInstance Is Nothing Then
If File.Exists(SettingsPath) Then
myInstance = LoadConfig(SettingsPath)
Else
myInstance = New AppConfig
myInstance.Reset()
End If
End If
Return myInstance
End Get
End Property
Private Shared ReadOnly Property SettingsPath As string
Get
Static myPath As String = String.Empty
Const AppDataDirectoryName As String = "MinecraftModpackUpdater"
Const SettingsFileName As String = "Settings.json"
If String.IsNullOrEmpty(myPath) Then
myPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), AppDataDirectoryName)
Directory.CreateDirectory(myPath)
myPath = Path.Combine(myPath, SettingsFileName)
End If
Return myPath
End Get
End Property
Public Sub SaveConfig()
File.WriteAllText(SettingsPath, JObject.FromObject(Me).ToString)
End Sub
Private Shared Function LoadConfig(filePath As String) As AppConfig
Return JObject.Parse(File.ReadAllText(filePath)).ToObject(Of AppConfig)
End Function
End Class

View File

@@ -0,0 +1,81 @@
using ModpackUpdater.Model;
using Unleash;
namespace ModpackUpdater;
public enum AppFeatures
{
AllowExtras
}
public static class AppFeaturesExtensions
{
private const string apiUrl = "https://git.pilzinsel64.de/api/v4/feature_flags/unleash/2";
private const string instanceId = "glffct-3vCzJXChAnxjsgvoHijR";
private static IUnleash api;
private static UnleashContext context;
private static UnleashSettings settings;
public static bool IsEnabled(this AppFeatures feature, AppFeatureContext context)
{
return feature switch
{
AppFeatures.AllowExtras => CheckFeature("allow-extras", false, context),
_ => throw new NotSupportedException(),
};
}
public static bool IsEnabled(this AppFeatures feature)
{
return feature switch
{
_ => throw new NotSupportedException(),
};
}
private static bool InitializeApi()
{
if (api == null)
{
settings = new UnleashSettings
{
AppName = "Modpack Updater",
UnleashApi = new Uri(apiUrl),
FetchTogglesInterval = TimeSpan.FromSeconds(60 * 5),
InstanceTag = instanceId,
};
api = new DefaultUnleash(settings);
}
return api != null;
}
private static bool CheckFeature(string name, bool defaultValue, AppFeatureContext context)
{
return InitializeApi() && api.IsEnabled(name, GetContext(context), defaultValue);
}
private static UnleashContext GetContext(AppFeatureContext ccontext)
{
context ??= new();
context.CurrentTime = DateTime.Now;
ccontext?.Apply(context);
return context;
}
}
public abstract class AppFeatureContext
{
public abstract void Apply(UnleashContext context);
}
public class AllowExtrasFeatureContext(ModpackInfo info, ModpackConfig config) : AppFeatureContext
{
public override void Apply(UnleashContext context)
{
context.UserId = info.ExtrasKey;
context.Environment = config.Key;
}
}

View File

@@ -0,0 +1,19 @@
using Pilz.UI.Telerik;
using System.Reflection;
namespace ModpackUpdater;
public class AppSymbolFactory : SymbolFactory<AppSymbols>
{
public static AppSymbolFactory Instance { get; } = new();
public override Assembly GetSvgImageResourceAssembly()
{
return Assembly.GetExecutingAssembly();
}
public override string GetSvgImageRessourcePath(AppSymbols svgImage)
{
return $"{GetType().Namespace}.Symbols.{svgImage}.svg";
}
}

View File

@@ -0,0 +1,20 @@
namespace ModpackUpdater;
public enum AppSymbols
{
checkmark,
close,
delete,
done,
download_from_ftp,
general_warning_sign,
opened_folder,
paste,
refresh,
reload,
save,
services,
software_installer,
update_done,
wrench,
}

View File

@@ -0,0 +1,78 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System.Reflection;
namespace ModpackUpdater;
public class AppUpdater
{
private class UpdateInfo
{
[JsonConverter(typeof(VersionConverter))]
public Version Version { get; set; }
public string DownloadUrl { get; set; }
}
private const string UPDATE_URL = "https://git.pilzinsel64.de/gaming/minecraft/minecraft-modpack-updater/-/snippets/3/raw/main/updates.json";
private readonly HttpClient httpClient = new();
private UpdateInfo info;
public async Task<bool> Check()
{
var hasUpdate = false;
try
{
var appVersion = Assembly.GetExecutingAssembly().GetName().Version;
string result = await httpClient.GetStringAsync(UPDATE_URL);
info = JsonConvert.DeserializeObject<UpdateInfo>(result);
if (info is not null && info.Version > appVersion)
hasUpdate = true;
}
catch
{
}
return hasUpdate;
}
public async Task Install()
{
var client = new HttpClient();
var tempFileName = Path.GetTempFileName();
var appFileName = Pilz.IO.Extensions.GetExecutablePath();
var oldFileName = appFileName + ".old";
// Delete old file
try
{
File.Delete(oldFileName);
}
catch
{
}
// Download the new file
using (var tempFileStream = new FileStream(tempFileName, FileMode.Create, FileAccess.ReadWrite))
{
Stream downloadStream = null;
try
{
downloadStream = await client.GetStreamAsync(info.DownloadUrl);
await downloadStream.CopyToAsync(tempFileStream);
}
catch
{
}
finally
{
downloadStream?.Dispose();
}
}
// Replace current application file with new file
File.Move(appFileName, oldFileName, true);
File.Move(tempFileName, appFileName);
}
}

View File

@@ -1,70 +0,0 @@
Imports System.IO
Imports System.Net
Imports System.Net.Http
Imports WebDav
Public Class AppUpdater
Private Const WEBDAV_URL As String = "https://cloud.pilzinsel64.de/public.php/webdav"
Private Const WEBDAV_KEY As String = "z4dGicDYmG2neG9"
Private Const DOWNLOAD_URL As String = "https://cloud.pilzinsel64.de/s/z4dGicDYmG2neG9/download"
Public Shared Async Function Check() As Task(Of Boolean)
Dim appFileName = Pilz.IO.Extensions.GetExecutablePath()
Dim hasUpdate As Boolean = False
Dim params As New WebDavClientParams With {
.BaseAddress = New Uri(WEBDAV_URL),
.Credentials = New NetworkCredential(WEBDAV_KEY, String.Empty)
}
Try
Using client As New WebDavClient(params)
Dim result = Await client.Propfind(String.Empty)
If result.IsSuccessful AndAlso result.Resources.Count <> 0 Then
Dim resource = result.Resources(0)
Dim appModificationDate = File.GetLastWriteTimeUtc(appFileName)
Dim remoteModificationDate = resource.LastModifiedDate?.ToUniversalTime
If remoteModificationDate > appModificationDate Then
hasUpdate = True
End If
End If
End Using
Catch ex As Exception
End Try
Return hasUpdate
End Function
Public Shared Async Function Install() As Task
Dim client As New HttpClient
Dim tempFileName = Path.GetTempFileName
Dim appFileName = Pilz.IO.Extensions.GetExecutablePath()
Dim oldFileName = appFileName & ".old"
'Delete old file
Try
File.Delete(oldFileName)
Catch ex As Exception
End Try
'Download the new file
Using tempFileStream As New FileStream(tempFileName, FileMode.Create, FileAccess.ReadWrite)
Dim downloadStream As Stream = Nothing
Try
downloadStream = Await client.GetStreamAsync(DOWNLOAD_URL)
Await downloadStream.CopyToAsync(tempFileStream)
Catch
Finally
downloadStream?.Dispose()
End Try
End Using
'Replace current application file with new file
File.Move(appFileName, oldFileName, True)
File.Move(tempFileName, appFileName)
End Function
End Class

View File

@@ -1,40 +0,0 @@
Imports Microsoft.VisualBasic.ApplicationServices
Imports Telerik.WinControls
Namespace My
' The following events are available for MyApplication:
' Startup: Raised when the application starts, before the startup form is created.
' Shutdown: Raised after all application forms are closed. This event is not raised if the application terminates abnormally.
' UnhandledException: Raised if the application encounters an unhandled exception.
' StartupNextInstance: Raised when launching a single-instance application and the application is already active.
' NetworkAvailabilityChanged: Raised when the network connection is connected or disconnected.
' **NEW** ApplyApplicationDefaults: Raised when the application queries default values to be set for the application.
' Example:
' Private Sub MyApplication_ApplyApplicationDefaults(sender As Object, e As ApplyApplicationDefaultsEventArgs) Handles Me.ApplyApplicationDefaults
'
' ' Setting the application-wide default Font:
' e.Font = New Font(FontFamily.GenericSansSerif, 12, FontStyle.Regular)
'
' ' Setting the HighDpiMode for the Application:
' e.HighDpiMode = HighDpiMode.PerMonitorV2
'
' ' If a splash dialog is used, this sets the minimum display time:
' e.MinimumSplashScreenDisplayTime = 4000
' End Sub
Partial Friend Class MyApplication
Private Sub MyApplication_ApplyApplicationDefaults(sender As Object, e As ApplyApplicationDefaultsEventArgs) Handles Me.ApplyApplicationDefaults
Dim validTheme As Boolean =
ThemeResolutionService.LoadPackageResource("ModpackUpdater.Office2019DarkBluePurple.tssp")
If validTheme Then
ThemeResolutionService.ApplicationThemeName = "Office2019DarkBluePurple"
End If
End Sub
End Class
End Namespace

View File

@@ -0,0 +1,95 @@
// ------------------------------------------------------------------------------
// <auto-generated>
// Dieser Code wurde von einem Tool generiert.
// Laufzeitversion:4.0.30319.42000
//
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
// der Code erneut generiert wird.
// </auto-generated>
// ------------------------------------------------------------------------------
using System.Diagnostics;
namespace ModpackUpdater.My.Resources
{
// Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert
// -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
// Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
// mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
/// <summary>
/// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
/// </summary>
[System.CodeDom.Compiler.GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[DebuggerNonUserCode()]
[System.Runtime.CompilerServices.CompilerGenerated()]
internal class FiledialogFilters
{
private static System.Resources.ResourceManager resourceMan;
private static System.Globalization.CultureInfo resourceCulture;
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal FiledialogFilters() : base()
{
}
/// <summary>
/// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
/// </summary>
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Advanced)]
internal static System.Resources.ResourceManager ResourceManager
{
get
{
if (ReferenceEquals(resourceMan, null))
{
var temp = new System.Resources.ResourceManager("ModpackUpdater.FiledialogFilters", typeof(FiledialogFilters).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
/// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
/// </summary>
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Advanced)]
internal static System.Globalization.CultureInfo Culture
{
get
{
return resourceCulture;
}
set
{
resourceCulture = value;
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Json files (*.json) ähnelt.
/// </summary>
internal static string JSON_Display
{
get
{
return ResourceManager.GetString("JSON_Display", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die *.json ähnelt.
/// </summary>
internal static string JSON_Filter
{
get
{
return ResourceManager.GetString("JSON_Filter", resourceCulture);
}
}
}
}

View File

@@ -1,85 +0,0 @@
'------------------------------------------------------------------------------
' <auto-generated>
' Dieser Code wurde von einem Tool generiert.
' Laufzeitversion:4.0.30319.42000
'
' Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
' der Code erneut generiert wird.
' </auto-generated>
'------------------------------------------------------------------------------
Option Strict On
Option Explicit On
Imports System
Namespace My.Resources
'Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert
'-Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
'Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
'mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
'''<summary>
''' Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
'''</summary>
<Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0"), _
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute()> _
Friend Class FiledialogFilters
Private Shared resourceMan As Global.System.Resources.ResourceManager
Private Shared resourceCulture As Global.System.Globalization.CultureInfo
<Global.System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")> _
Friend Sub New()
MyBase.New
End Sub
'''<summary>
''' Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
'''</summary>
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Friend Shared ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager
Get
If Object.ReferenceEquals(resourceMan, Nothing) Then
Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("ModpackUpdater.FiledialogFilters", GetType(FiledialogFilters).Assembly)
resourceMan = temp
End If
Return resourceMan
End Get
End Property
'''<summary>
''' Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
''' Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
'''</summary>
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Friend Shared Property Culture() As Global.System.Globalization.CultureInfo
Get
Return resourceCulture
End Get
Set
resourceCulture = value
End Set
End Property
'''<summary>
''' Sucht eine lokalisierte Zeichenfolge, die Json files (*.json) ähnelt.
'''</summary>
Friend Shared ReadOnly Property JSON_Display() As String
Get
Return ResourceManager.GetString("JSON_Display", resourceCulture)
End Get
End Property
'''<summary>
''' Sucht eine lokalisierte Zeichenfolge, die *.json ähnelt.
'''</summary>
Friend Shared ReadOnly Property JSON_Filter() As String
Get
Return ResourceManager.GetString("JSON_Filter", resourceCulture)
End Get
End Property
End Class
End Namespace

327
ModpackUpdater/Form1.Designer.cs generated Normal file
View File

@@ -0,0 +1,327 @@
using System;
using System.Diagnostics;
using System.Drawing;
using System.Windows.Forms;
namespace ModpackUpdater
{
[Microsoft.VisualBasic.CompilerServices.DesignerGenerated()]
public partial class Form1 : Telerik.WinControls.UI.RadForm
{
// Das Formular überschreibt den Löschvorgang, um die Komponentenliste zu bereinigen.
[DebuggerNonUserCode()]
protected override void Dispose(bool disposing)
{
try
{
if (disposing && components is not null)
components.Dispose();
}
finally
{
base.Dispose(disposing);
}
}
// Wird vom Windows Form-Designer benötigt.
private System.ComponentModel.IContainer components = new System.ComponentModel.Container();
// Hinweis: Die folgende Prozedur ist für den Windows Form-Designer erforderlich.
// Das Bearbeiten ist mit dem Windows Form-Designer möglich.
// Das Bearbeiten mit dem Code-Editor ist nicht möglich.
[DebuggerStepThrough()]
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
RadLabel1 = new Telerik.WinControls.UI.RadLabel();
RadLabel2 = new Telerik.WinControls.UI.RadLabel();
RadLabel3 = new Telerik.WinControls.UI.RadLabel();
RadLabel_Status = new Telerik.WinControls.UI.RadLabel();
RadTextBoxControl_MinecraftProfileFolder = new Telerik.WinControls.UI.RadTextBoxControl();
RadTextBoxControl_ModpackConfig = new Telerik.WinControls.UI.RadTextBoxControl();
RadButton_Install = new Telerik.WinControls.UI.RadButton();
RadButton_CheckForUpdates = new Telerik.WinControls.UI.RadButton();
RadButton_PasteModpackConfig = new Telerik.WinControls.UI.RadButton();
RadButton_SearchMinecraftProfileFolder = new Telerik.WinControls.UI.RadButton();
tableLayoutPanel1 = new TableLayoutPanel();
radLabel4 = new Telerik.WinControls.UI.RadLabel();
radTextBoxControl_InstallKey = new Telerik.WinControls.UI.RadTextBoxControl();
radButton_PasteInstallKey = new Telerik.WinControls.UI.RadButton();
radButton_RefreshConfig = new Telerik.WinControls.UI.RadButton();
((System.ComponentModel.ISupportInitialize)RadLabel1).BeginInit();
((System.ComponentModel.ISupportInitialize)RadLabel2).BeginInit();
((System.ComponentModel.ISupportInitialize)RadLabel3).BeginInit();
((System.ComponentModel.ISupportInitialize)RadLabel_Status).BeginInit();
((System.ComponentModel.ISupportInitialize)RadTextBoxControl_MinecraftProfileFolder).BeginInit();
((System.ComponentModel.ISupportInitialize)RadTextBoxControl_ModpackConfig).BeginInit();
((System.ComponentModel.ISupportInitialize)RadButton_Install).BeginInit();
((System.ComponentModel.ISupportInitialize)RadButton_CheckForUpdates).BeginInit();
((System.ComponentModel.ISupportInitialize)RadButton_PasteModpackConfig).BeginInit();
((System.ComponentModel.ISupportInitialize)RadButton_SearchMinecraftProfileFolder).BeginInit();
tableLayoutPanel1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)radLabel4).BeginInit();
((System.ComponentModel.ISupportInitialize)radTextBoxControl_InstallKey).BeginInit();
((System.ComponentModel.ISupportInitialize)radButton_PasteInstallKey).BeginInit();
((System.ComponentModel.ISupportInitialize)radButton_RefreshConfig).BeginInit();
((System.ComponentModel.ISupportInitialize)this).BeginInit();
SuspendLayout();
//
// RadLabel1
//
RadLabel1.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
RadLabel1.AutoSize = false;
RadLabel1.Location = new Point(3, 3);
RadLabel1.Name = "RadLabel1";
RadLabel1.Size = new Size(144, 22);
RadLabel1.TabIndex = 0;
RadLabel1.Text = "Minecraft profile folder:";
//
// RadLabel2
//
RadLabel2.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
RadLabel2.AutoSize = false;
RadLabel2.Location = new Point(3, 61);
RadLabel2.Name = "RadLabel2";
RadLabel2.Size = new Size(144, 22);
RadLabel2.TabIndex = 1;
RadLabel2.Text = "Modpack config:";
//
// RadLabel3
//
RadLabel3.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
RadLabel3.AutoSize = false;
RadLabel3.Location = new Point(3, 177);
RadLabel3.Name = "RadLabel3";
RadLabel3.Size = new Size(144, 22);
RadLabel3.TabIndex = 2;
RadLabel3.Text = "Status:";
//
// RadLabel_Status
//
RadLabel_Status.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
RadLabel_Status.AutoSize = false;
tableLayoutPanel1.SetColumnSpan(RadLabel_Status, 6);
RadLabel_Status.Location = new Point(153, 177);
RadLabel_Status.Name = "RadLabel_Status";
RadLabel_Status.Size = new Size(266, 22);
RadLabel_Status.TabIndex = 3;
RadLabel_Status.Text = "-";
RadLabel_Status.TextImageRelation = TextImageRelation.ImageBeforeText;
//
// RadTextBoxControl_MinecraftProfileFolder
//
RadTextBoxControl_MinecraftProfileFolder.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
tableLayoutPanel1.SetColumnSpan(RadTextBoxControl_MinecraftProfileFolder, 6);
RadTextBoxControl_MinecraftProfileFolder.IsReadOnly = true;
RadTextBoxControl_MinecraftProfileFolder.Location = new Point(153, 3);
RadTextBoxControl_MinecraftProfileFolder.Name = "RadTextBoxControl_MinecraftProfileFolder";
RadTextBoxControl_MinecraftProfileFolder.NullText = "No file loaded!";
RadTextBoxControl_MinecraftProfileFolder.Size = new Size(266, 22);
RadTextBoxControl_MinecraftProfileFolder.TabIndex = 4;
//
// RadTextBoxControl_ModpackConfig
//
RadTextBoxControl_ModpackConfig.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
tableLayoutPanel1.SetColumnSpan(RadTextBoxControl_ModpackConfig, 6);
RadTextBoxControl_ModpackConfig.IsReadOnly = true;
RadTextBoxControl_ModpackConfig.Location = new Point(153, 61);
RadTextBoxControl_ModpackConfig.Name = "RadTextBoxControl_ModpackConfig";
RadTextBoxControl_ModpackConfig.NullText = "No config url provided.";
RadTextBoxControl_ModpackConfig.Size = new Size(266, 22);
RadTextBoxControl_ModpackConfig.TabIndex = 5;
//
// RadButton_Install
//
RadButton_Install.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
tableLayoutPanel1.SetColumnSpan(RadButton_Install, 2);
RadButton_Install.ImageAlignment = ContentAlignment.MiddleRight;
RadButton_Install.Location = new Point(325, 205);
RadButton_Install.Name = "RadButton_Install";
RadButton_Install.Size = new Size(94, 24);
RadButton_Install.TabIndex = 10;
RadButton_Install.Text = "Install";
RadButton_Install.TextAlignment = ContentAlignment.MiddleLeft;
RadButton_Install.TextImageRelation = TextImageRelation.ImageBeforeText;
RadButton_Install.Click += ButtonX_StartUpdate_Click;
//
// RadButton_CheckForUpdates
//
RadButton_CheckForUpdates.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
tableLayoutPanel1.SetColumnSpan(RadButton_CheckForUpdates, 3);
RadButton_CheckForUpdates.ImageAlignment = ContentAlignment.MiddleRight;
RadButton_CheckForUpdates.Location = new Point(175, 205);
RadButton_CheckForUpdates.Name = "RadButton_CheckForUpdates";
RadButton_CheckForUpdates.Size = new Size(144, 24);
RadButton_CheckForUpdates.TabIndex = 0;
RadButton_CheckForUpdates.Text = "Check for Updates";
RadButton_CheckForUpdates.TextAlignment = ContentAlignment.MiddleLeft;
RadButton_CheckForUpdates.TextImageRelation = TextImageRelation.ImageBeforeText;
RadButton_CheckForUpdates.Click += ButtonX_CheckForUpdates_Click;
//
// RadButton_PasteModpackConfig
//
RadButton_PasteModpackConfig.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
tableLayoutPanel1.SetColumnSpan(RadButton_PasteModpackConfig, 2);
RadButton_PasteModpackConfig.ImageAlignment = ContentAlignment.MiddleRight;
RadButton_PasteModpackConfig.Location = new Point(325, 89);
RadButton_PasteModpackConfig.Name = "RadButton_PasteModpackConfig";
RadButton_PasteModpackConfig.Size = new Size(94, 24);
RadButton_PasteModpackConfig.TabIndex = 7;
RadButton_PasteModpackConfig.Text = "Paste";
RadButton_PasteModpackConfig.TextAlignment = ContentAlignment.MiddleLeft;
RadButton_PasteModpackConfig.TextImageRelation = TextImageRelation.ImageBeforeText;
RadButton_PasteModpackConfig.Click += RadButton_PasteModpackConfig_Click;
//
// RadButton_SearchMinecraftProfileFolder
//
RadButton_SearchMinecraftProfileFolder.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
tableLayoutPanel1.SetColumnSpan(RadButton_SearchMinecraftProfileFolder, 2);
RadButton_SearchMinecraftProfileFolder.ImageAlignment = ContentAlignment.MiddleRight;
RadButton_SearchMinecraftProfileFolder.Location = new Point(325, 31);
RadButton_SearchMinecraftProfileFolder.Name = "RadButton_SearchMinecraftProfileFolder";
RadButton_SearchMinecraftProfileFolder.Size = new Size(94, 24);
RadButton_SearchMinecraftProfileFolder.TabIndex = 6;
RadButton_SearchMinecraftProfileFolder.Text = "Search";
RadButton_SearchMinecraftProfileFolder.TextAlignment = ContentAlignment.MiddleLeft;
RadButton_SearchMinecraftProfileFolder.TextImageRelation = TextImageRelation.ImageBeforeText;
RadButton_SearchMinecraftProfileFolder.Click += ButtonX_SearchMinecraftProfile_Click;
//
// tableLayoutPanel1
//
tableLayoutPanel1.ColumnCount = 7;
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 150F));
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 50F));
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 50F));
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 50F));
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 50F));
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 50F));
tableLayoutPanel1.Controls.Add(RadButton_CheckForUpdates, 2, 7);
tableLayoutPanel1.Controls.Add(RadLabel1, 0, 0);
tableLayoutPanel1.Controls.Add(RadLabel2, 0, 2);
tableLayoutPanel1.Controls.Add(RadTextBoxControl_MinecraftProfileFolder, 1, 0);
tableLayoutPanel1.Controls.Add(RadTextBoxControl_ModpackConfig, 1, 2);
tableLayoutPanel1.Controls.Add(RadLabel_Status, 1, 6);
tableLayoutPanel1.Controls.Add(RadLabel3, 0, 6);
tableLayoutPanel1.Controls.Add(RadButton_SearchMinecraftProfileFolder, 5, 1);
tableLayoutPanel1.Controls.Add(RadButton_Install, 5, 7);
tableLayoutPanel1.Controls.Add(radLabel4, 0, 4);
tableLayoutPanel1.Controls.Add(radTextBoxControl_InstallKey, 1, 4);
tableLayoutPanel1.Controls.Add(radButton_PasteInstallKey, 5, 5);
tableLayoutPanel1.Controls.Add(RadButton_PasteModpackConfig, 5, 3);
tableLayoutPanel1.Controls.Add(radButton_RefreshConfig, 4, 3);
tableLayoutPanel1.Dock = DockStyle.Fill;
tableLayoutPanel1.Location = new Point(0, 0);
tableLayoutPanel1.Name = "tableLayoutPanel1";
tableLayoutPanel1.RowCount = 8;
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.Size = new Size(422, 232);
tableLayoutPanel1.TabIndex = 7;
//
// radLabel4
//
radLabel4.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
radLabel4.AutoSize = false;
radLabel4.Location = new Point(3, 119);
radLabel4.Name = "radLabel4";
radLabel4.Size = new Size(144, 22);
radLabel4.TabIndex = 12;
radLabel4.Text = "Installation key:";
//
// radTextBoxControl_InstallKey
//
radTextBoxControl_InstallKey.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
tableLayoutPanel1.SetColumnSpan(radTextBoxControl_InstallKey, 6);
radTextBoxControl_InstallKey.IsReadOnly = true;
radTextBoxControl_InstallKey.Location = new Point(153, 119);
radTextBoxControl_InstallKey.Name = "radTextBoxControl_InstallKey";
radTextBoxControl_InstallKey.NullText = "No key provided. Only for private servers.";
radTextBoxControl_InstallKey.Size = new Size(266, 22);
radTextBoxControl_InstallKey.TabIndex = 13;
//
// radButton_PasteInstallKey
//
radButton_PasteInstallKey.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
tableLayoutPanel1.SetColumnSpan(radButton_PasteInstallKey, 2);
radButton_PasteInstallKey.ImageAlignment = ContentAlignment.MiddleRight;
radButton_PasteInstallKey.Location = new Point(325, 147);
radButton_PasteInstallKey.Name = "radButton_PasteInstallKey";
radButton_PasteInstallKey.Size = new Size(94, 24);
radButton_PasteInstallKey.TabIndex = 14;
radButton_PasteInstallKey.Text = "Paste";
radButton_PasteInstallKey.TextAlignment = ContentAlignment.MiddleLeft;
radButton_PasteInstallKey.TextImageRelation = TextImageRelation.ImageBeforeText;
radButton_PasteInstallKey.Click += RadButton_PasteInstallKey_Click;
//
// radButton_RefreshConfig
//
radButton_RefreshConfig.Anchor = AnchorStyles.Top | AnchorStyles.Right;
radButton_RefreshConfig.DisplayStyle = Telerik.WinControls.DisplayStyle.Image;
radButton_RefreshConfig.ImageAlignment = ContentAlignment.MiddleCenter;
radButton_RefreshConfig.Location = new Point(295, 89);
radButton_RefreshConfig.Name = "radButton_RefreshConfig";
radButton_RefreshConfig.Size = new Size(24, 24);
radButton_RefreshConfig.TabIndex = 11;
radButton_RefreshConfig.Text = "Reload";
radButton_RefreshConfig.Click += RadButton_RefreshConfig_Click;
//
// Form1
//
AutoScaleBaseSize = new Size(7, 15);
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(422, 232);
Controls.Add(tableLayoutPanel1);
Icon = (Icon)resources.GetObject("$this.Icon");
MaximizeBox = false;
Name = "Form1";
StartPosition = FormStartPosition.CenterScreen;
Text = "Minecraft Modpack Updater";
FormClosing += Form1_FormClosing;
Load += Form1_Load;
Shown += Form1_Shown;
((System.ComponentModel.ISupportInitialize)RadLabel1).EndInit();
((System.ComponentModel.ISupportInitialize)RadLabel2).EndInit();
((System.ComponentModel.ISupportInitialize)RadLabel3).EndInit();
((System.ComponentModel.ISupportInitialize)RadLabel_Status).EndInit();
((System.ComponentModel.ISupportInitialize)RadTextBoxControl_MinecraftProfileFolder).EndInit();
((System.ComponentModel.ISupportInitialize)RadTextBoxControl_ModpackConfig).EndInit();
((System.ComponentModel.ISupportInitialize)RadButton_Install).EndInit();
((System.ComponentModel.ISupportInitialize)RadButton_CheckForUpdates).EndInit();
((System.ComponentModel.ISupportInitialize)RadButton_PasteModpackConfig).EndInit();
((System.ComponentModel.ISupportInitialize)RadButton_SearchMinecraftProfileFolder).EndInit();
tableLayoutPanel1.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)radLabel4).EndInit();
((System.ComponentModel.ISupportInitialize)radTextBoxControl_InstallKey).EndInit();
((System.ComponentModel.ISupportInitialize)radButton_PasteInstallKey).EndInit();
((System.ComponentModel.ISupportInitialize)radButton_RefreshConfig).EndInit();
((System.ComponentModel.ISupportInitialize)this).EndInit();
ResumeLayout(false);
}
internal Telerik.WinControls.UI.RadLabel RadLabel1;
internal Telerik.WinControls.UI.RadLabel RadLabel2;
internal Telerik.WinControls.UI.RadLabel RadLabel3;
internal Telerik.WinControls.UI.RadLabel RadLabel_Status;
internal Telerik.WinControls.UI.RadTextBoxControl RadTextBoxControl_MinecraftProfileFolder;
internal Telerik.WinControls.UI.RadTextBoxControl RadTextBoxControl_ModpackConfig;
internal Telerik.WinControls.UI.RadButton RadButton_Install;
internal Telerik.WinControls.UI.RadButton RadButton_CheckForUpdates;
internal Telerik.WinControls.UI.RadButton RadButton_SearchMinecraftProfileFolder;
internal Telerik.WinControls.UI.RadButton RadButton_PasteModpackConfig;
private TableLayoutPanel tableLayoutPanel1;
private Telerik.WinControls.UI.RadButton radButton_RefreshConfig;
internal Telerik.WinControls.UI.RadLabel radLabel4;
internal Telerik.WinControls.UI.RadTextBoxControl radTextBoxControl_InstallKey;
internal Telerik.WinControls.UI.RadButton radButton_PasteInstallKey;
}
}

View File

@@ -1,253 +0,0 @@
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class Form1
Inherits Telerik.WinControls.UI.RadForm
'Das Formular überschreibt den Löschvorgang, um die Komponentenliste zu bereinigen.
<System.Diagnostics.DebuggerNonUserCode()> _
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub
'Wird vom Windows Form-Designer benötigt.
Private components As System.ComponentModel.IContainer
'Hinweis: Die folgende Prozedur ist für den Windows Form-Designer erforderlich.
'Das Bearbeiten ist mit dem Windows Form-Designer möglich.
'Das Bearbeiten mit dem Code-Editor ist nicht möglich.
<System.Diagnostics.DebuggerStepThrough()> _
Private Sub InitializeComponent()
Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(Form1))
RadLabel1 = New Telerik.WinControls.UI.RadLabel()
RadLabel2 = New Telerik.WinControls.UI.RadLabel()
RadLabel3 = New Telerik.WinControls.UI.RadLabel()
RadLabel_Status = New Telerik.WinControls.UI.RadLabel()
RadTextBoxControl_MinecraftProfileFolder = New Telerik.WinControls.UI.RadTextBoxControl()
RadTextBoxControl_ModpackConfig = New Telerik.WinControls.UI.RadTextBoxControl()
Panel1 = New Panel()
RadButton_Install = New Telerik.WinControls.UI.RadButton()
RadButton_CheckForUpdates = New Telerik.WinControls.UI.RadButton()
RadButton_EditModpackConfig = New Telerik.WinControls.UI.RadButton()
RadButton_SearchModpackConfig = New Telerik.WinControls.UI.RadButton()
RadButton_SearchMinecraftProfileFolder = New Telerik.WinControls.UI.RadButton()
RadButton_PasteModpackConfig = New Telerik.WinControls.UI.RadButton()
CType(RadLabel1, ComponentModel.ISupportInitialize).BeginInit()
CType(RadLabel2, ComponentModel.ISupportInitialize).BeginInit()
CType(RadLabel3, ComponentModel.ISupportInitialize).BeginInit()
CType(RadLabel_Status, ComponentModel.ISupportInitialize).BeginInit()
CType(RadTextBoxControl_MinecraftProfileFolder, ComponentModel.ISupportInitialize).BeginInit()
CType(RadTextBoxControl_ModpackConfig, ComponentModel.ISupportInitialize).BeginInit()
Panel1.SuspendLayout()
CType(RadButton_Install, ComponentModel.ISupportInitialize).BeginInit()
CType(RadButton_CheckForUpdates, ComponentModel.ISupportInitialize).BeginInit()
CType(RadButton_EditModpackConfig, ComponentModel.ISupportInitialize).BeginInit()
CType(RadButton_SearchModpackConfig, ComponentModel.ISupportInitialize).BeginInit()
CType(RadButton_SearchMinecraftProfileFolder, ComponentModel.ISupportInitialize).BeginInit()
CType(RadButton_PasteModpackConfig, ComponentModel.ISupportInitialize).BeginInit()
CType(Me, ComponentModel.ISupportInitialize).BeginInit()
SuspendLayout()
'
' RadLabel1
'
RadLabel1.Location = New Point(3, 5)
RadLabel1.Name = "RadLabel1"
RadLabel1.Size = New Size(124, 18)
RadLabel1.TabIndex = 0
RadLabel1.Text = "Minecraft profile folder:"
'
' RadLabel2
'
RadLabel2.Location = New Point(3, 63)
RadLabel2.Name = "RadLabel2"
RadLabel2.Size = New Size(90, 18)
RadLabel2.TabIndex = 1
RadLabel2.Text = "Modpack config:"
'
' RadLabel3
'
RadLabel3.Location = New Point(3, 121)
RadLabel3.Name = "RadLabel3"
RadLabel3.Size = New Size(39, 18)
RadLabel3.TabIndex = 2
RadLabel3.Text = "Status:"
'
' RadLabel_Status
'
RadLabel_Status.Anchor = AnchorStyles.Top Or AnchorStyles.Left Or AnchorStyles.Right
RadLabel_Status.AutoSize = False
RadLabel_Status.Location = New Point(144, 119)
RadLabel_Status.Name = "RadLabel_Status"
RadLabel_Status.Size = New Size(273, 22)
RadLabel_Status.TabIndex = 3
RadLabel_Status.Text = "-"
RadLabel_Status.TextImageRelation = TextImageRelation.ImageBeforeText
'
' RadTextBoxControl_MinecraftProfileFolder
'
RadTextBoxControl_MinecraftProfileFolder.Anchor = AnchorStyles.Top Or AnchorStyles.Left Or AnchorStyles.Right
RadTextBoxControl_MinecraftProfileFolder.IsReadOnly = True
RadTextBoxControl_MinecraftProfileFolder.Location = New Point(144, 3)
RadTextBoxControl_MinecraftProfileFolder.Name = "RadTextBoxControl_MinecraftProfileFolder"
RadTextBoxControl_MinecraftProfileFolder.NullText = "No file loaded!"
RadTextBoxControl_MinecraftProfileFolder.Size = New Size(273, 22)
RadTextBoxControl_MinecraftProfileFolder.TabIndex = 4
'
' RadTextBoxControl_ModpackConfig
'
RadTextBoxControl_ModpackConfig.Anchor = AnchorStyles.Top Or AnchorStyles.Left Or AnchorStyles.Right
RadTextBoxControl_ModpackConfig.IsReadOnly = True
RadTextBoxControl_ModpackConfig.Location = New Point(144, 61)
RadTextBoxControl_ModpackConfig.Name = "RadTextBoxControl_ModpackConfig"
RadTextBoxControl_ModpackConfig.NullText = "No file loaded!"
RadTextBoxControl_ModpackConfig.Size = New Size(273, 22)
RadTextBoxControl_ModpackConfig.TabIndex = 5
'
' Panel1
'
Panel1.BackColor = Color.Transparent
Panel1.Controls.Add(RadButton_Install)
Panel1.Controls.Add(RadButton_CheckForUpdates)
Panel1.Controls.Add(RadButton_EditModpackConfig)
Panel1.Controls.Add(RadButton_PasteModpackConfig)
Panel1.Controls.Add(RadButton_SearchModpackConfig)
Panel1.Controls.Add(RadButton_SearchMinecraftProfileFolder)
Panel1.Controls.Add(RadLabel1)
Panel1.Controls.Add(RadTextBoxControl_ModpackConfig)
Panel1.Controls.Add(RadLabel2)
Panel1.Controls.Add(RadTextBoxControl_MinecraftProfileFolder)
Panel1.Controls.Add(RadLabel3)
Panel1.Controls.Add(RadLabel_Status)
Panel1.Dock = DockStyle.Fill
Panel1.Location = New Point(0, 0)
Panel1.Name = "Panel1"
Panel1.Size = New Size(420, 176)
Panel1.TabIndex = 6
'
' RadButton_Install
'
RadButton_Install.Anchor = AnchorStyles.Bottom Or AnchorStyles.Right
RadButton_Install.Image = My.Resources.MySymbols.icons8_software_installer_16px
RadButton_Install.ImageAlignment = ContentAlignment.MiddleRight
RadButton_Install.Location = New Point(337, 149)
RadButton_Install.Name = "RadButton_Install"
RadButton_Install.Size = New Size(80, 24)
RadButton_Install.TabIndex = 10
RadButton_Install.Text = "Install"
RadButton_Install.TextAlignment = ContentAlignment.MiddleLeft
RadButton_Install.TextImageRelation = TextImageRelation.ImageBeforeText
'
' RadButton_CheckForUpdates
'
RadButton_CheckForUpdates.Anchor = AnchorStyles.Bottom Or AnchorStyles.Right
RadButton_CheckForUpdates.Image = My.Resources.MySymbols.icons8_update_16px
RadButton_CheckForUpdates.ImageAlignment = ContentAlignment.MiddleRight
RadButton_CheckForUpdates.Location = New Point(191, 149)
RadButton_CheckForUpdates.Name = "RadButton_CheckForUpdates"
RadButton_CheckForUpdates.Size = New Size(140, 24)
RadButton_CheckForUpdates.TabIndex = 0
RadButton_CheckForUpdates.Text = "Check for Updates"
RadButton_CheckForUpdates.TextAlignment = ContentAlignment.MiddleLeft
RadButton_CheckForUpdates.TextImageRelation = TextImageRelation.ImageBeforeText
'
' RadButton_EditModpackConfig
'
RadButton_EditModpackConfig.Anchor = AnchorStyles.Bottom Or AnchorStyles.Left
RadButton_EditModpackConfig.Image = My.Resources.MySymbols.icons8_wrench_16px
RadButton_EditModpackConfig.ImageAlignment = ContentAlignment.MiddleRight
RadButton_EditModpackConfig.Location = New Point(3, 149)
RadButton_EditModpackConfig.Name = "RadButton_EditModpackConfig"
RadButton_EditModpackConfig.Size = New Size(150, 24)
RadButton_EditModpackConfig.TabIndex = 8
RadButton_EditModpackConfig.Text = "Edit modpack config"
RadButton_EditModpackConfig.TextAlignment = ContentAlignment.MiddleLeft
RadButton_EditModpackConfig.TextImageRelation = TextImageRelation.ImageBeforeText
'
' RadButton_SearchModpackConfig
'
RadButton_SearchModpackConfig.Anchor = AnchorStyles.Top Or AnchorStyles.Right
RadButton_SearchModpackConfig.Image = CType(resources.GetObject("RadButton_SearchModpackConfig.Image"), Image)
RadButton_SearchModpackConfig.ImageAlignment = ContentAlignment.MiddleRight
RadButton_SearchModpackConfig.Location = New Point(327, 89)
RadButton_SearchModpackConfig.Name = "RadButton_SearchModpackConfig"
RadButton_SearchModpackConfig.Size = New Size(90, 24)
RadButton_SearchModpackConfig.TabIndex = 7
RadButton_SearchModpackConfig.Text = "Search"
RadButton_SearchModpackConfig.TextAlignment = ContentAlignment.MiddleLeft
RadButton_SearchModpackConfig.TextImageRelation = TextImageRelation.ImageBeforeText
'
' RadButton_SearchMinecraftProfileFolder
'
RadButton_SearchMinecraftProfileFolder.Anchor = AnchorStyles.Top Or AnchorStyles.Right
RadButton_SearchMinecraftProfileFolder.Image = CType(resources.GetObject("RadButton_SearchMinecraftProfileFolder.Image"), Image)
RadButton_SearchMinecraftProfileFolder.ImageAlignment = ContentAlignment.MiddleRight
RadButton_SearchMinecraftProfileFolder.Location = New Point(327, 31)
RadButton_SearchMinecraftProfileFolder.Name = "RadButton_SearchMinecraftProfileFolder"
RadButton_SearchMinecraftProfileFolder.Size = New Size(90, 24)
RadButton_SearchMinecraftProfileFolder.TabIndex = 6
RadButton_SearchMinecraftProfileFolder.Text = "Search"
RadButton_SearchMinecraftProfileFolder.TextAlignment = ContentAlignment.MiddleLeft
RadButton_SearchMinecraftProfileFolder.TextImageRelation = TextImageRelation.ImageBeforeText
'
' RadButton_PasteModpackConfig
'
RadButton_PasteModpackConfig.Anchor = AnchorStyles.Top Or AnchorStyles.Right
RadButton_PasteModpackConfig.Image = CType(resources.GetObject("RadButton_PasteModpackConfig.Image"), Image)
RadButton_PasteModpackConfig.ImageAlignment = ContentAlignment.MiddleRight
RadButton_PasteModpackConfig.Location = New Point(231, 89)
RadButton_PasteModpackConfig.Name = "RadButton_PasteModpackConfig"
RadButton_PasteModpackConfig.Size = New Size(90, 24)
RadButton_PasteModpackConfig.TabIndex = 7
RadButton_PasteModpackConfig.Text = "Paste"
RadButton_PasteModpackConfig.TextAlignment = ContentAlignment.MiddleLeft
RadButton_PasteModpackConfig.TextImageRelation = TextImageRelation.ImageBeforeText
'
' Form1
'
AutoScaleBaseSize = New Size(7, 15)
AutoScaleDimensions = New SizeF(7F, 15F)
AutoScaleMode = AutoScaleMode.Font
ClientSize = New Size(420, 176)
Controls.Add(Panel1)
Icon = CType(resources.GetObject("$this.Icon"), Icon)
MaximizeBox = False
Name = "Form1"
StartPosition = FormStartPosition.CenterScreen
Text = "Minecraft Modpack Updater"
CType(RadLabel1, ComponentModel.ISupportInitialize).EndInit()
CType(RadLabel2, ComponentModel.ISupportInitialize).EndInit()
CType(RadLabel3, ComponentModel.ISupportInitialize).EndInit()
CType(RadLabel_Status, ComponentModel.ISupportInitialize).EndInit()
CType(RadTextBoxControl_MinecraftProfileFolder, ComponentModel.ISupportInitialize).EndInit()
CType(RadTextBoxControl_ModpackConfig, ComponentModel.ISupportInitialize).EndInit()
Panel1.ResumeLayout(False)
Panel1.PerformLayout()
CType(RadButton_Install, ComponentModel.ISupportInitialize).EndInit()
CType(RadButton_CheckForUpdates, ComponentModel.ISupportInitialize).EndInit()
CType(RadButton_EditModpackConfig, ComponentModel.ISupportInitialize).EndInit()
CType(RadButton_SearchModpackConfig, ComponentModel.ISupportInitialize).EndInit()
CType(RadButton_SearchMinecraftProfileFolder, ComponentModel.ISupportInitialize).EndInit()
CType(RadButton_PasteModpackConfig, ComponentModel.ISupportInitialize).EndInit()
CType(Me, ComponentModel.ISupportInitialize).EndInit()
ResumeLayout(False)
End Sub
Friend WithEvents RadLabel1 As Telerik.WinControls.UI.RadLabel
Friend WithEvents RadLabel2 As Telerik.WinControls.UI.RadLabel
Friend WithEvents RadLabel3 As Telerik.WinControls.UI.RadLabel
Friend WithEvents RadLabel_Status As Telerik.WinControls.UI.RadLabel
Friend WithEvents RadTextBoxControl_MinecraftProfileFolder As Telerik.WinControls.UI.RadTextBoxControl
Friend WithEvents RadTextBoxControl_ModpackConfig As Telerik.WinControls.UI.RadTextBoxControl
Friend WithEvents Panel1 As System.Windows.Forms.Panel
Friend WithEvents RadButton_Install As Telerik.WinControls.UI.RadButton
Friend WithEvents RadButton_CheckForUpdates As Telerik.WinControls.UI.RadButton
Friend WithEvents RadButton_EditModpackConfig As Telerik.WinControls.UI.RadButton
Friend WithEvents RadButton_SearchModpackConfig As Telerik.WinControls.UI.RadButton
Friend WithEvents RadButton_SearchMinecraftProfileFolder As Telerik.WinControls.UI.RadButton
Friend WithEvents RadButton_PasteModpackConfig As Telerik.WinControls.UI.RadButton
End Class

304
ModpackUpdater/Form1.cs Normal file
View File

@@ -0,0 +1,304 @@
using ModpackUpdater.Manager;
using ModpackUpdater.Model;
using ModpackUpdater.My.Resources;
using Pilz.UI.Telerik;
using System.Diagnostics;
using System.Reflection;
using Telerik.WinControls;
using Telerik.WinControls.UI;
namespace ModpackUpdater;
public partial class Form1
{
private ModpackInfo modpackInfo = new();
private ModpackConfig updateConfig = new();
private bool currentUpdating = false;
private UpdateCheckResult lastUpdateCheckResult = null;
private readonly UpdateCheckOptionsAdv updateOptions;
public Form1(UpdateCheckOptionsAdv updateOptions) : this()
{
this.updateOptions = updateOptions;
if (!string.IsNullOrWhiteSpace(updateOptions.ProfileFolder))
LoadMinecraftProfile(updateOptions.ProfileFolder);
else if (!string.IsNullOrWhiteSpace(AppConfig.Instance.LastMinecraftProfilePath))
LoadMinecraftProfile(AppConfig.Instance.LastMinecraftProfilePath);
}
public Form1()
{
InitializeComponent();
Text = $"{Text} (v{Assembly.GetExecutingAssembly().GetName().Version})";
RadButton_Install.SvgImage = AppSymbolFactory.Instance.GetSvgImage(AppSymbols.software_installer, SvgImageSize.Small);
RadButton_CheckForUpdates.SvgImage = AppSymbolFactory.Instance.GetSvgImage(AppSymbols.update_done, SvgImageSize.Small);
radButton_RefreshConfig.SvgImage = AppSymbolFactory.Instance.GetSvgImage(AppSymbols.refresh, SvgImageSize.Small);
RadButton_SearchMinecraftProfileFolder.SvgImage = AppSymbolFactory.Instance.GetSvgImage(AppSymbols.opened_folder, SvgImageSize.Small);
radButton_PasteInstallKey.SvgImage = AppSymbolFactory.Instance.GetSvgImage(AppSymbols.paste, SvgImageSize.Small);
RadButton_PasteModpackConfig.SvgImage = AppSymbolFactory.Instance.GetSvgImage(AppSymbols.paste, SvgImageSize.Small);
}
private void LoadMinecraftProfile(string folderPath)
{
RadTextBoxControl_MinecraftProfileFolder.Text = folderPath;
AppConfig.Instance.LastMinecraftProfilePath = folderPath;
CheckStatusAndUpdate(loadedProfile: true);
}
private void LoadUpdateConfigFile(string filePath)
{
RadTextBoxControl_ModpackConfig.Text = filePath;
CheckStatusAndUpdate();
}
private void LoadInstallKey(string installKey)
{
radTextBoxControl_InstallKey.Text = modpackInfo.ExtrasKey = installKey;
CheckStatusAndUpdate();
}
private void SetStatus(string statusText, RadSvgImage image)
{
RadLabel_Status.Text = statusText;
RadLabel_Status.SvgImage = image;
}
private void ClearStatus()
{
RadLabel_Status.Text = "-";
RadLabel_Status.SvgImage = null;
}
private void CheckStatusAndUpdate(bool loadedProfile = false)
{
if (CheckStatus(loadedProfile))
RadButton_CheckForUpdates.PerformClick();
}
private bool CheckStatus(bool loadedProfile)
{
try
{
modpackInfo = ModpackInfo.TryLoad(RadTextBoxControl_MinecraftProfileFolder.Text.Trim());
if (loadedProfile)
{
RadTextBoxControl_ModpackConfig.Text = modpackInfo.ConfigUrl;
radTextBoxControl_InstallKey.Text = modpackInfo.ExtrasKey;
}
}
catch
{
}
try
{
updateConfig = ModpackConfig.LoadFromUrl(RadTextBoxControl_ModpackConfig.Text);
}
catch (Exception)
{
}
if (modpackInfo == null || string.IsNullOrWhiteSpace(RadTextBoxControl_MinecraftProfileFolder.Text) /*|| modpackInfo.Valid*/)
{
SetStatus(LangRes.StatusText_MinecraftProfileWarning, AppSymbolFactory.Instance.GetSvgImage(AppSymbols.general_warning_sign, SvgImageSize.Small));
RadButton_PasteModpackConfig.Enabled = false;
radButton_PasteInstallKey.Enabled = false;
RadButton_CheckForUpdates.Enabled = false;
RadButton_Install.Enabled = false;
return false;
}
else if (updateConfig == null || string.IsNullOrWhiteSpace(RadTextBoxControl_ModpackConfig.Text))
{
SetStatus(LangRes.StatusText_ConfigIncompleteOrNotLoaded, AppSymbolFactory.Instance.GetSvgImage(AppSymbols.general_warning_sign, SvgImageSize.Small));
RadButton_PasteModpackConfig.Enabled = true;
radButton_PasteInstallKey.Enabled = false;
RadButton_CheckForUpdates.Enabled = false;
RadButton_Install.Enabled = false;
return false;
}
else if (updateConfig.Maintenance && !updateOptions.IgnoreMaintenance)
{
SetStatus(LangRes.StatusText_Maintenance, AppSymbolFactory.Instance.GetSvgImage(AppSymbols.services, SvgImageSize.Small));
RadButton_PasteModpackConfig.Enabled = true;
radButton_PasteInstallKey.Enabled = true;
RadButton_CheckForUpdates.Enabled = false;
RadButton_Install.Enabled = false;
return false;
}
RadButton_PasteModpackConfig.Enabled = true;
radButton_PasteInstallKey.Enabled = true;
RadButton_CheckForUpdates.Enabled = true;
RadButton_Install.Enabled = true;
return true;
}
private async Task ExecuteUpdate(bool doInstall)
{
var updater = new ModpackInstaller(updateConfig, modpackInfo);
updater.InstallProgessUpdated += Update_InstallProgessUpdated;
updater.CheckingProgressUpdated += Updated_CheckingProgresssUpdated;
void error()
{
SetStatus(LangRes.StatusText_ErrorWhileUpdateCheckOrUpdate, AppSymbolFactory.Instance.GetSvgImage(AppSymbols.close, SvgImageSize.Small));
currentUpdating = false;
}
void installing()
{
SetStatus(LangRes.StatusText_Installing, AppSymbolFactory.Instance.GetSvgImage(AppSymbols.software_installer, SvgImageSize.Small));
currentUpdating = true;
}
void updatesAvailable()
{
SetStatus(LangRes.StatusText_UpdateAvailable, AppSymbolFactory.Instance.GetSvgImage(AppSymbols.software_installer, SvgImageSize.Small));
}
void everythingOk()
{
SetStatus(LangRes.StatusTest_EverythingOk, AppSymbolFactory.Instance.GetSvgImage(AppSymbols.done, SvgImageSize.Small));
currentUpdating = false;
}
// Check only if not pressed "install", not really needed otherwise.
if (lastUpdateCheckResult is null || !doInstall)
{
SetStatus(LangRes.StatusText_CheckingForUpdates, AppSymbolFactory.Instance.GetSvgImage(AppSymbols.update_done, SvgImageSize.Small));
// Check for extras once again
updateOptions.IncludeExtras = AppFeatures.AllowExtras.IsEnabled(new AllowExtrasFeatureContext(modpackInfo, updateConfig));
try
{
lastUpdateCheckResult = await updater.Check(updateOptions);
}
catch(Exception)
{
error();
if (Debugger.IsAttached)
throw;
}
finally
{
}
}
// Error while update check
if (lastUpdateCheckResult is null || lastUpdateCheckResult.HasError)
{
error();
return;
}
// No updates available
if (!lastUpdateCheckResult.HasUpdates)
{
everythingOk();
return;
}
// Updates available (but don't install)
if (!doInstall)
{
updatesAvailable();
return;
}
// Install updates
installing();
currentUpdating = true;
try
{
// Install
if (await updater.Install(lastUpdateCheckResult) == false)
{
error();
return;
}
// Success
lastUpdateCheckResult = null; // Reset last update check, a new one would be needed now.
everythingOk();
}
catch (Exception)
{
// Error
error();
if (Debugger.IsAttached)
throw;
}
}
private void Update_InstallProgessUpdated(UpdateCheckResult result, int processedSyncs)
{
int actionCount = result.Actions.Count;
SetStatus(Math.Round(processedSyncs / (double)actionCount * 100d, 1) + "%", AppSymbolFactory.Instance.GetSvgImage(AppSymbols.software_installer, SvgImageSize.Small));
}
private void Updated_CheckingProgresssUpdated(int toCheck, int processed)
{
SetStatus(Math.Round(processed / (double)toCheck * 100d, 1) + "%", AppSymbolFactory.Instance.GetSvgImage(AppSymbols.update_done, SvgImageSize.Small));
}
private void ButtonX_SearchMinecraftProfile_Click(object sender, EventArgs e)
{
var ofd = new RadOpenFolderDialog();
if (ofd.ShowDialog(this) == DialogResult.OK)
LoadMinecraftProfile(ofd.FileName);
}
private void RadButton_PasteModpackConfig_Click(object sender, EventArgs e)
{
LoadUpdateConfigFile(Clipboard.GetText());
}
private void RadButton_PasteInstallKey_Click(object sender, EventArgs e)
{
LoadInstallKey(Clipboard.GetText());
}
private void RadButton_RefreshConfig_Click(object sender, EventArgs e)
{
LoadUpdateConfigFile(RadTextBoxControl_ModpackConfig.Text);
}
private async void ButtonX_CheckForUpdates_Click(object sender, EventArgs e)
{
ClearStatus();
await ExecuteUpdate(false);
}
private async void ButtonX_StartUpdate_Click(object sender, EventArgs e)
{
if (!currentUpdating)
{
ClearStatus();
await ExecuteUpdate(true);
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
AppConfig.Instance.LastMinecraftProfilePath = RadTextBoxControl_MinecraftProfileFolder.Text;
}
private void Form1_Load(object sender, EventArgs e)
{
if (Directory.Exists(AppConfig.Instance.LastMinecraftProfilePath))
LoadMinecraftProfile(AppConfig.Instance.LastMinecraftProfilePath);
}
private async void Form1_Shown(object sender, EventArgs e)
{
var updater = new AppUpdater();
if (!updateOptions.NoUpdate && await updater.Check() && RadMessageBox.Show(LangRes.MsgBox_UpdateAvailable, LangRes.MsgBox_UpdateAvailable_Title, MessageBoxButtons.YesNo, RadMessageIcon.Info) == DialogResult.Yes)
{
SetStatus(LangRes.StatusText_InstallingAppUpdate, AppSymbolFactory.Instance.GetSvgImage(AppSymbols.software_installer, SvgImageSize.Small));
Enabled = false;
await updater.Install();
Application.Restart();
}
}
}

View File

@@ -118,34 +118,6 @@
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> <assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="RadButton_PasteModpackConfig.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAADvSURBVDhPY8AFJixbowfCUC5pYNLidfoTlqxbBcJ9SzboQoXxA9eolHlA/BOo6T8I9y5a87Jv
4ZpXMD5IDojnQJVjAqDk3x8/f/2fu247WAMynrt+x3+QHFDNH6hyTACU/E8IgNRAlWMCZAM+//z3/9bb
vxg4rn7a/wknf4aCMFQbAiAbAFI84dRPvBiqDQFoYoDDpPsYOHrpC+INyFj3BgXDbKefARR7AV0zzHas
BrhEpXzaffjY/4MnTv/feOIWimJsGKoNAVwiU4Ndo1NWukalrkrrWnoMmyZkDNWGHUw68cti4smfq/Fh
iEoGBgDk9v/D66ccygAAAABJRU5ErkJggg==
</value>
</data>
<data name="RadButton_SearchModpackConfig.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAMhJREFUOE9j
GBzg/34Glv8LGNz+z2cIheNFDNxQacIAqLkZiP+j4PkMB4g25P9ChlUYBuDGP4F4DlQrBJBoAAj/gWqF
ALgBi5j+/z+o8P//SY3//08RxHf/n9GWQzVgNTc2hXiwZjiqAZuFsSjCg09rGaIasFsKu0Ls+Pf/2yrs
qAYcVsSmEBe+CtYMAmADFjICBdXRFeHB6iug2oEGLGBo+b+CA4sifFgzC6odaAAoKa/lDPy/S6KMKLxf
Kvz/fwZGqPYBBQwMAFjinO6ZYVu0AAAAAElFTkSuQmCC
</value>
</data>
<data name="RadButton_SearchMinecraftProfileFolder.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAMhJREFUOE9j
GBzg/34Glv8LGNz+z2cIheNFDNxQacIAqLkZiP+j4PkMB4g25P9ChlUYBuDGP4F4DlQrBJBoAAj/gWqF
ALgBi5j+/z+o8P//SY3//08RxHf/n9GWQzVgNTc2hXiwZjiqAZuFsSjCg09rGaIasFsKu0Ls+Pf/2yrs
qAYcVsSmEBe+CtYMAmADFjICBdXRFeHB6iug2oEGLGBo+b+CA4sifFgzC6odaAAoKa/lDPy/S6KMKLxf
Kvz/fwZGqPYBBQwMAFjinO6ZYVu0AAAAAElFTkSuQmCC
</value>
</data>
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> <data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value> <value>
AAABAAYAEBAAAAEAIABoBAAAZgAAACAgAAABACAAqBAAAM4EAAAwMAAAAQAgAKglAAB2FQAAQEAAAAEA AAABAAYAEBAAAAEAIABoBAAAZgAAACAgAAABACAAqBAAAM4EAAAwMAAAAQAgAKglAAB2FQAAQEAAAAEA

View File

@@ -1,215 +0,0 @@
Imports System.IO
Imports ModpackUpdater.GitLab
Imports ModpackUpdater.Manager
Imports ModpackUpdater.Model
Imports ModpackUpdater.My.Resources
Imports Telerik.WinControls
Imports Telerik.WinControls.UI
Public Class Form1
Private updateConfig As New UpdateConfig
Private currentUpdating As Boolean = False
Private lastUpdateCheckResult As UpdateCheckResult = Nothing
Public Sub New()
InitializeComponent()
Text = $"{Text} (v{Application.ProductVersion})"
End Sub
Private Function IsMinecaftProfileLoaded() As Boolean
Return Not String.IsNullOrEmpty(GetMinecraftProfilePath)
End Function
Private Function GetMinecraftProfilePath() As String
Return RadTextBoxControl_MinecraftProfileFolder.Text.Trim
End Function
Private Function IsUpdateConfigLoaded() As Boolean
Return Not String.IsNullOrEmpty(GetUpdateconfigPath)
End Function
Private Function GetUpdateconfigPath() As String
Return RadTextBoxControl_ModpackConfig.Text.Trim
End Function
Private Function CheckStatus() As Boolean
If Not IsMinecaftProfileLoaded() OrElse Not MinecraftProfileChecker.CheckProfile(GetMinecraftProfilePath) Then
SetStatus(LangRes.StatusText_MinecraftProfileWarning, MySymbols.icons8_general_warning_sign_16px)
CheckStatus = False
ElseIf Not IsUpdateConfigLoaded() Then
SetStatus(LangRes.StatusText_MinecraftProfileWarning, MySymbols.icons8_general_warning_sign_16px)
CheckStatus = False
Else
CheckStatus = True
End If
End Function
Private Sub SetStatus(statusText As String, image As Image)
RadLabel_Status.Text = statusText
RadLabel_Status.Image = image
End Sub
Private Sub ClearStatus()
RadLabel_Status.Text = "-"
RadLabel_Status.Image = Nothing
End Sub
Private Sub LoadMinecraftProfile(folderPath As String)
RadTextBoxControl_MinecraftProfileFolder.Text = folderPath
If IsUpdateConfigLoaded() Then
RadButton_CheckForUpdates.PerformClick()
Else
ClearStatus()
End If
End Sub
Private Sub LoadUpdateConfigFile(filePath As String)
RadTextBoxControl_ModpackConfig.Text = filePath
Try
If IsUpdateConfigLoaded() Then
If filePath.StartsWith("http") Then
updateConfig = UpdateConfigExt.LoadFromSnippet(filePath)
Else
updateConfig = UpdateConfig.LoadFromFile(filePath)
End If
End If
Catch ex As Exception
RadTextBoxControl_ModpackConfig.Text = String.Empty
End Try
If IsMinecaftProfileLoaded() Then
RadButton_CheckForUpdates.PerformClick()
Else
ClearStatus()
End If
End Sub
Private Async Function ExecuteUpdate(doInstall As Boolean) As Task
Dim updater As New UpdateInstaller(updateConfig, GetMinecraftProfilePath)
AddHandler updater.InstallProgessUpdated, AddressOf Update_InstallProgessUpdated
AddHandler updater.CheckingProgressUpdated, AddressOf Updated_CheckingProgresssUpdated
'Check only if not pressed "install", not really needed otherwise.
If lastUpdateCheckResult Is Nothing OrElse Not doInstall Then
SetStatus(LangRes.StatusText_CheckingForUpdates, MySymbols.icons8_update_16px)
Try
lastUpdateCheckResult = Await updater.CheckForUpdates(Not AppConfig.Instance.AllowRemoveLocalFiles)
Catch ex As Exception
SetStatus(LangRes.StatusText_ErrorWhileUpdateCheckOrUpdate, MySymbols.icons8_delete_16px)
Finally
End Try
End If
If lastUpdateCheckResult Is Nothing OrElse lastUpdateCheckResult.HasError Then
SetStatus(LangRes.StatusText_ErrorWhileUpdateCheckOrUpdate, MySymbols.icons8_delete_16px)
ElseIf lastUpdateCheckResult.HasUpdates Then
If doInstall Then
SetStatus(LangRes.StatusText_Installing, MySymbols.icons8_software_installer_16px)
currentUpdating = True
Try
If Await updater.InstallUpdates(lastUpdateCheckResult) Then
lastUpdateCheckResult = Nothing 'Reset last update check, a new one would be needed now.
SetStatus(LangRes.StatusTest_EverythingOk, MySymbols.icons8_checkmark_16px)
Else
SetStatus(LangRes.StatusText_ErrorWhileUpdateCheckOrUpdate, MySymbols.icons8_delete_16px)
End If
Catch
SetStatus(LangRes.StatusText_ErrorWhileUpdateCheckOrUpdate, MySymbols.icons8_delete_16px)
Finally
currentUpdating = False
End Try
Else
SetStatus(LangRes.StatusText_UpdateAvailable, MySymbols.icons8_software_installer_16px)
End If
Else
SetStatus(LangRes.StatusTest_EverythingOk, MySymbols.icons8_checkmark_16px)
End If
End Function
Private Sub Update_InstallProgessUpdated(result As UpdateCheckResult, processedSyncs As Integer)
Dim actionCount = If(result.IsLegacy, result.SyncFiles.Count, result.UpdateActions.Count)
SetStatus(Math.Round(processedSyncs / actionCount * 100, 1) & "%", MySymbols.icons8_software_installer_16px)
End Sub
Private Sub Updated_CheckingProgresssUpdated(toCheck As Integer, processed As Integer)
SetStatus(Math.Round(processed / toCheck * 100, 1) & "%", MySymbols.icons8_update_16px)
End Sub
Private Sub ButtonX_SearchMinecraftProfile_Click(sender As Object, e As EventArgs) Handles RadButton_SearchMinecraftProfileFolder.Click
Dim ofd As New RadOpenFolderDialog
If ofd.ShowDialog(Me) = DialogResult.OK Then
LoadMinecraftProfile(ofd.FileName)
End If
End Sub
Private Sub ButtonX_SearchUpdateConfig_Click(sender As Object, e As EventArgs) Handles RadButton_SearchModpackConfig.Click
Dim ofd As New RadOpenFileDialog With {
.Filter = FiledialogFilters.JSON_Display & "|" & FiledialogFilters.JSON_Filter
}
If ofd.ShowDialog(Me) = DialogResult.OK Then
LoadUpdateConfigFile(ofd.FileName)
End If
End Sub
Private Sub RadButton_PasteModpackConfig_Click(sender As Object, e As EventArgs) Handles RadButton_PasteModpackConfig.Click
Dim text = Clipboard.GetText
If text.StartsWith("http") Then
LoadUpdateConfigFile(text)
End If
End Sub
Private Sub ButtonX_EditUpdateConfig_Click(sender As Object, e As EventArgs) Handles RadButton_EditModpackConfig.Click
Dim frm As New FormSettings(updateConfig)
frm.ShowDialog(Me)
End Sub
Private Async Sub ButtonX_CheckForUpdates_Click(sender As Object, e As EventArgs) Handles RadButton_CheckForUpdates.Click
ClearStatus()
If CheckStatus() Then
Await ExecuteUpdate(False)
End If
End Sub
Private Async Sub ButtonX_StartUpdate_Click(sender As Object, e As EventArgs) Handles RadButton_Install.Click
If Not currentUpdating Then
ClearStatus()
If CheckStatus() Then
Await ExecuteUpdate(True)
End If
End If
End Sub
Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
AppConfig.Instance.LastMinecraftProfilePath = RadTextBoxControl_MinecraftProfileFolder.Text
AppConfig.Instance.LastConfigFilePath = RadTextBoxControl_ModpackConfig.Text
AppConfig.Instance.SaveConfig()
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
If Directory.Exists(AppConfig.Instance.LastMinecraftProfilePath) Then
LoadMinecraftProfile(AppConfig.Instance.LastMinecraftProfilePath)
End If
LoadUpdateConfigFile(AppConfig.Instance.LastConfigFilePath)
End Sub
Private Async Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown
If Await AppUpdater.Check AndAlso RadMessageBox.Show(LangRes.MsgBox_UpdateAvailable, LangRes.MsgBox_UpdateAvailable_Title, MessageBoxButtons.YesNo, RadMessageIcon.Info) = DialogResult.Yes Then
SetStatus(LangRes.StatusText_InstallingAppUpdate, MySymbols.icons8_software_installer_16px)
Enabled = False
Await AppUpdater.Install()
Application.Restart()
End If
End Sub
End Class

View File

@@ -1,154 +0,0 @@
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class FormSettings
Inherits Telerik.WinControls.UI.RadForm
'Das Formular überschreibt den Löschvorgang, um die Komponentenliste zu bereinigen.
<System.Diagnostics.DebuggerNonUserCode()> _
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub
'Wird vom Windows Form-Designer benötigt.
Private components As System.ComponentModel.IContainer
'Hinweis: Die folgende Prozedur ist für den Windows Form-Designer erforderlich.
'Das Bearbeiten ist mit dem Windows Form-Designer möglich.
'Das Bearbeiten mit dem Code-Editor ist nicht möglich.
<System.Diagnostics.DebuggerStepThrough()> _
Private Sub InitializeComponent()
Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(FormSettings))
Me.Panel1 = New System.Windows.Forms.Panel()
Me.RadTextBoxControl_WebdavPassword = New Telerik.WinControls.UI.RadTextBoxControl()
Me.RadTextBoxControl_WebdavUsername = New Telerik.WinControls.UI.RadTextBoxControl()
Me.RadTextBoxControl_WebdavURL = New Telerik.WinControls.UI.RadTextBoxControl()
Me.RadButton_SaveAndClose = New Telerik.WinControls.UI.RadButton()
Me.RadButton_SaveAs = New Telerik.WinControls.UI.RadButton()
Me.RadLabel3 = New Telerik.WinControls.UI.RadLabel()
Me.RadLabel2 = New Telerik.WinControls.UI.RadLabel()
Me.RadLabel1 = New Telerik.WinControls.UI.RadLabel()
Me.RadTextBoxControl_UpdateUrl = New Telerik.WinControls.UI.RadTextBoxControl()
Me.RadLabel4 = New Telerik.WinControls.UI.RadLabel()
Me.Panel1.SuspendLayout()
CType(Me.RadTextBoxControl_WebdavPassword, System.ComponentModel.ISupportInitialize).BeginInit()
CType(Me.RadTextBoxControl_WebdavUsername, System.ComponentModel.ISupportInitialize).BeginInit()
CType(Me.RadTextBoxControl_WebdavURL, System.ComponentModel.ISupportInitialize).BeginInit()
CType(Me.RadButton_SaveAndClose, System.ComponentModel.ISupportInitialize).BeginInit()
CType(Me.RadButton_SaveAs, System.ComponentModel.ISupportInitialize).BeginInit()
CType(Me.RadLabel3, System.ComponentModel.ISupportInitialize).BeginInit()
CType(Me.RadLabel2, System.ComponentModel.ISupportInitialize).BeginInit()
CType(Me.RadLabel1, System.ComponentModel.ISupportInitialize).BeginInit()
CType(Me.RadTextBoxControl_UpdateUrl, System.ComponentModel.ISupportInitialize).BeginInit()
CType(Me.RadLabel4, System.ComponentModel.ISupportInitialize).BeginInit()
CType(Me, System.ComponentModel.ISupportInitialize).BeginInit()
Me.SuspendLayout()
'
'Panel1
'
Me.Panel1.BackColor = System.Drawing.Color.Transparent
Me.Panel1.Controls.Add(Me.RadTextBoxControl_UpdateUrl)
Me.Panel1.Controls.Add(Me.RadLabel4)
Me.Panel1.Controls.Add(Me.RadTextBoxControl_WebdavPassword)
Me.Panel1.Controls.Add(Me.RadTextBoxControl_WebdavUsername)
Me.Panel1.Controls.Add(Me.RadTextBoxControl_WebdavURL)
Me.Panel1.Controls.Add(Me.RadButton_SaveAndClose)
Me.Panel1.Controls.Add(Me.RadButton_SaveAs)
Me.Panel1.Controls.Add(Me.RadLabel3)
Me.Panel1.Controls.Add(Me.RadLabel2)
Me.Panel1.Controls.Add(Me.RadLabel1)
resources.ApplyResources(Me.Panel1, "Panel1")
Me.Panel1.Name = "Panel1"
'
'RadTextBoxControl_WebdavPassword
'
resources.ApplyResources(Me.RadTextBoxControl_WebdavPassword, "RadTextBoxControl_WebdavPassword")
Me.RadTextBoxControl_WebdavPassword.Name = "RadTextBoxControl_WebdavPassword"
'
'RadTextBoxControl_WebdavUsername
'
resources.ApplyResources(Me.RadTextBoxControl_WebdavUsername, "RadTextBoxControl_WebdavUsername")
Me.RadTextBoxControl_WebdavUsername.Name = "RadTextBoxControl_WebdavUsername"
'
'RadTextBoxControl_WebdavURL
'
resources.ApplyResources(Me.RadTextBoxControl_WebdavURL, "RadTextBoxControl_WebdavURL")
Me.RadTextBoxControl_WebdavURL.Name = "RadTextBoxControl_WebdavURL"
'
'RadButton_SaveAndClose
'
resources.ApplyResources(Me.RadButton_SaveAndClose, "RadButton_SaveAndClose")
Me.RadButton_SaveAndClose.Image = Global.ModpackUpdater.My.Resources.MySymbols.icons8_save_16px
Me.RadButton_SaveAndClose.Name = "RadButton_SaveAndClose"
'
'RadButton_SaveAs
'
resources.ApplyResources(Me.RadButton_SaveAs, "RadButton_SaveAs")
Me.RadButton_SaveAs.Image = Global.ModpackUpdater.My.Resources.MySymbols.icons8_opened_folder_16px
Me.RadButton_SaveAs.Name = "RadButton_SaveAs"
'
'RadLabel3
'
resources.ApplyResources(Me.RadLabel3, "RadLabel3")
Me.RadLabel3.Name = "RadLabel3"
'
'RadLabel2
'
resources.ApplyResources(Me.RadLabel2, "RadLabel2")
Me.RadLabel2.Name = "RadLabel2"
'
'RadLabel1
'
resources.ApplyResources(Me.RadLabel1, "RadLabel1")
Me.RadLabel1.Name = "RadLabel1"
'
'RadTextBoxControl_UpdateUrl
'
resources.ApplyResources(Me.RadTextBoxControl_UpdateUrl, "RadTextBoxControl_UpdateUrl")
Me.RadTextBoxControl_UpdateUrl.Name = "RadTextBoxControl_UpdateUrl"
'
'RadLabel4
'
resources.ApplyResources(Me.RadLabel4, "RadLabel4")
Me.RadLabel4.Name = "RadLabel4"
'
'FormSettings
'
resources.ApplyResources(Me, "$this")
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.Controls.Add(Me.Panel1)
Me.MaximizeBox = False
Me.Name = "FormSettings"
Me.Panel1.ResumeLayout(False)
Me.Panel1.PerformLayout()
CType(Me.RadTextBoxControl_WebdavPassword, System.ComponentModel.ISupportInitialize).EndInit()
CType(Me.RadTextBoxControl_WebdavUsername, System.ComponentModel.ISupportInitialize).EndInit()
CType(Me.RadTextBoxControl_WebdavURL, System.ComponentModel.ISupportInitialize).EndInit()
CType(Me.RadButton_SaveAndClose, System.ComponentModel.ISupportInitialize).EndInit()
CType(Me.RadButton_SaveAs, System.ComponentModel.ISupportInitialize).EndInit()
CType(Me.RadLabel3, System.ComponentModel.ISupportInitialize).EndInit()
CType(Me.RadLabel2, System.ComponentModel.ISupportInitialize).EndInit()
CType(Me.RadLabel1, System.ComponentModel.ISupportInitialize).EndInit()
CType(Me.RadTextBoxControl_UpdateUrl, System.ComponentModel.ISupportInitialize).EndInit()
CType(Me.RadLabel4, System.ComponentModel.ISupportInitialize).EndInit()
CType(Me, System.ComponentModel.ISupportInitialize).EndInit()
Me.ResumeLayout(False)
End Sub
Friend WithEvents Panel1 As Panel
Friend WithEvents RadLabel1 As Telerik.WinControls.UI.RadLabel
Friend WithEvents RadTextBoxControl_WebdavPassword As Telerik.WinControls.UI.RadTextBoxControl
Friend WithEvents RadTextBoxControl_WebdavUsername As Telerik.WinControls.UI.RadTextBoxControl
Friend WithEvents RadTextBoxControl_WebdavURL As Telerik.WinControls.UI.RadTextBoxControl
Friend WithEvents RadButton_SaveAndClose As Telerik.WinControls.UI.RadButton
Friend WithEvents RadButton_SaveAs As Telerik.WinControls.UI.RadButton
Friend WithEvents RadLabel3 As Telerik.WinControls.UI.RadLabel
Friend WithEvents RadLabel2 As Telerik.WinControls.UI.RadLabel
Friend WithEvents RadTextBoxControl_UpdateUrl As Telerik.WinControls.UI.RadTextBoxControl
Friend WithEvents RadLabel4 As Telerik.WinControls.UI.RadLabel
End Class

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,47 +0,0 @@
Imports ModpackUpdater.Model
Imports ModpackUpdater.My.Resources
Imports Telerik.WinControls.UI
Public Class FormSettings
Private ReadOnly updateConfig As UpdateConfig
Public Sub New(updateConfig As UpdateConfig)
InitializeComponent()
Me.updateConfig = updateConfig
End Sub
Private Sub LoadConfig()
RadTextBoxControl_WebdavURL.Text = updateConfig.WebdavURL
RadTextBoxControl_WebdavUsername.Text = updateConfig.WebdavUsername
RadTextBoxControl_WebdavPassword.Text = updateConfig.WebdavPassword
RadTextBoxControl_UpdateUrl.Text = updateConfig.UpdateUrl
End Sub
Private Sub SaveConfig()
updateConfig.WebdavURL = RadTextBoxControl_WebdavURL.Text.Trim
updateConfig.WebdavUsername = RadTextBoxControl_WebdavUsername.Text.Trim
updateConfig.WebdavPassword = RadTextBoxControl_WebdavPassword.Text
updateConfig.UpdateUrl = RadTextBoxControl_UpdateUrl.Text
End Sub
Private Sub ButtonX_SaveAs_Click(sender As Object, e As EventArgs) Handles RadButton_SaveAs.Click
Dim ofd As New RadSaveFileDialog
ofd.Filter = FiledialogFilters.JSON_Display & "|" & FiledialogFilters.JSON_Filter
If ofd.ShowDialog(Me) = DialogResult.OK Then
updateConfig.SaveToFile(ofd.FileName)
End If
End Sub
Private Sub ButtonX_SaveAndClose_Click(sender As Object, e As EventArgs) Handles RadButton_SaveAndClose.Click
SaveConfig()
Close()
End Sub
Private Sub FormSettings_Load(sender As Object, e As EventArgs) Handles Me.Load
LoadConfig()
End Sub
End Class

162
ModpackUpdater/LangRes.Designer.cs generated Normal file
View File

@@ -0,0 +1,162 @@
//------------------------------------------------------------------------------
// <auto-generated>
// Dieser Code wurde von einem Tool generiert.
// Laufzeitversion:4.0.30319.42000
//
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
// der Code erneut generiert wird.
// </auto-generated>
//------------------------------------------------------------------------------
namespace ModpackUpdater.My.Resources {
using System;
/// <summary>
/// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
/// </summary>
// Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert
// -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
// Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
// mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class LangRes {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal LangRes() {
}
/// <summary>
/// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ModpackUpdater.LangRes", typeof(LangRes).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
/// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die A new version of this program is available. If you confirm, the update will be installed automatically. It takes just a few seconds. Continue? ähnelt.
/// </summary>
internal static string MsgBox_UpdateAvailable {
get {
return ResourceManager.GetString("MsgBox_UpdateAvailable", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die New program version available ähnelt.
/// </summary>
internal static string MsgBox_UpdateAvailable_Title {
get {
return ResourceManager.GetString("MsgBox_UpdateAvailable_Title", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Everything is right and up-to-date. ähnelt.
/// </summary>
internal static string StatusTest_EverythingOk {
get {
return ResourceManager.GetString("StatusTest_EverythingOk", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Checking for Updates... ähnelt.
/// </summary>
internal static string StatusText_CheckingForUpdates {
get {
return ResourceManager.GetString("StatusText_CheckingForUpdates", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Config incomplete or not loaded! ähnelt.
/// </summary>
internal static string StatusText_ConfigIncompleteOrNotLoaded {
get {
return ResourceManager.GetString("StatusText_ConfigIncompleteOrNotLoaded", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Error on update check or while updating! ähnelt.
/// </summary>
internal static string StatusText_ErrorWhileUpdateCheckOrUpdate {
get {
return ResourceManager.GetString("StatusText_ErrorWhileUpdateCheckOrUpdate", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Installing... ähnelt.
/// </summary>
internal static string StatusText_Installing {
get {
return ResourceManager.GetString("StatusText_Installing", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Downloading program update... ähnelt.
/// </summary>
internal static string StatusText_InstallingAppUpdate {
get {
return ResourceManager.GetString("StatusText_InstallingAppUpdate", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die The update servers are in maintenance. ähnelt.
/// </summary>
internal static string StatusText_Maintenance {
get {
return ResourceManager.GetString("StatusText_Maintenance", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Minecraft profile folder seems to be not valid. ähnelt.
/// </summary>
internal static string StatusText_MinecraftProfileWarning {
get {
return ResourceManager.GetString("StatusText_MinecraftProfileWarning", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die An update is available! ähnelt.
/// </summary>
internal static string StatusText_UpdateAvailable {
get {
return ResourceManager.GetString("StatusText_UpdateAvailable", resourceCulture);
}
}
}
}

View File

@@ -1,157 +0,0 @@
'------------------------------------------------------------------------------
' <auto-generated>
' Dieser Code wurde von einem Tool generiert.
' Laufzeitversion:4.0.30319.42000
'
' Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
' der Code erneut generiert wird.
' </auto-generated>
'------------------------------------------------------------------------------
Option Strict On
Option Explicit On
Imports System
Namespace My.Resources
'Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert
'-Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
'Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
'mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
'''<summary>
''' Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
'''</summary>
<Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0"), _
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute()> _
Friend Class LangRes
Private Shared resourceMan As Global.System.Resources.ResourceManager
Private Shared resourceCulture As Global.System.Globalization.CultureInfo
<Global.System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")> _
Friend Sub New()
MyBase.New
End Sub
'''<summary>
''' Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
'''</summary>
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Friend Shared ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager
Get
If Object.ReferenceEquals(resourceMan, Nothing) Then
Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("ModpackUpdater.LangRes", GetType(LangRes).Assembly)
resourceMan = temp
End If
Return resourceMan
End Get
End Property
'''<summary>
''' Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
''' Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
'''</summary>
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Friend Shared Property Culture() As Global.System.Globalization.CultureInfo
Get
Return resourceCulture
End Get
Set
resourceCulture = value
End Set
End Property
'''<summary>
''' Sucht eine lokalisierte Zeichenfolge, die A new version of this program is available. If you confirm, the update will be installed automatically. It takes just a few seconds. Continue? ähnelt.
'''</summary>
Friend Shared ReadOnly Property MsgBox_UpdateAvailable() As String
Get
Return ResourceManager.GetString("MsgBox_UpdateAvailable", resourceCulture)
End Get
End Property
'''<summary>
''' Sucht eine lokalisierte Zeichenfolge, die New program version available ähnelt.
'''</summary>
Friend Shared ReadOnly Property MsgBox_UpdateAvailable_Title() As String
Get
Return ResourceManager.GetString("MsgBox_UpdateAvailable_Title", resourceCulture)
End Get
End Property
'''<summary>
''' Sucht eine lokalisierte Zeichenfolge, die Everything is right and up-to-date. ähnelt.
'''</summary>
Friend Shared ReadOnly Property StatusTest_EverythingOk() As String
Get
Return ResourceManager.GetString("StatusTest_EverythingOk", resourceCulture)
End Get
End Property
'''<summary>
''' Sucht eine lokalisierte Zeichenfolge, die Checking for Updates... ähnelt.
'''</summary>
Friend Shared ReadOnly Property StatusText_CheckingForUpdates() As String
Get
Return ResourceManager.GetString("StatusText_CheckingForUpdates", resourceCulture)
End Get
End Property
'''<summary>
''' Sucht eine lokalisierte Zeichenfolge, die Config incomplete or not loaded! ähnelt.
'''</summary>
Friend Shared ReadOnly Property StatusText_ConfigIncompleteOrNotLoaded() As String
Get
Return ResourceManager.GetString("StatusText_ConfigIncompleteOrNotLoaded", resourceCulture)
End Get
End Property
'''<summary>
''' Sucht eine lokalisierte Zeichenfolge, die Error on update check or while updating! ähnelt.
'''</summary>
Friend Shared ReadOnly Property StatusText_ErrorWhileUpdateCheckOrUpdate() As String
Get
Return ResourceManager.GetString("StatusText_ErrorWhileUpdateCheckOrUpdate", resourceCulture)
End Get
End Property
'''<summary>
''' Sucht eine lokalisierte Zeichenfolge, die Installing... ähnelt.
'''</summary>
Friend Shared ReadOnly Property StatusText_Installing() As String
Get
Return ResourceManager.GetString("StatusText_Installing", resourceCulture)
End Get
End Property
'''<summary>
''' Sucht eine lokalisierte Zeichenfolge, die Downloading program update... ähnelt.
'''</summary>
Friend Shared ReadOnly Property StatusText_InstallingAppUpdate() As String
Get
Return ResourceManager.GetString("StatusText_InstallingAppUpdate", resourceCulture)
End Get
End Property
'''<summary>
''' Sucht eine lokalisierte Zeichenfolge, die Minecraft profile folder seems to be not valid. ähnelt.
'''</summary>
Friend Shared ReadOnly Property StatusText_MinecraftProfileWarning() As String
Get
Return ResourceManager.GetString("StatusText_MinecraftProfileWarning", resourceCulture)
End Get
End Property
'''<summary>
''' Sucht eine lokalisierte Zeichenfolge, die An update is available! ähnelt.
'''</summary>
Friend Shared ReadOnly Property StatusText_UpdateAvailable() As String
Get
Return ResourceManager.GetString("StatusText_UpdateAvailable", resourceCulture)
End Get
End Property
End Class
End Namespace

View File

@@ -141,6 +141,9 @@
<data name="StatusText_InstallingAppUpdate" xml:space="preserve"> <data name="StatusText_InstallingAppUpdate" xml:space="preserve">
<value>Downloading program update...</value> <value>Downloading program update...</value>
</data> </data>
<data name="StatusText_Maintenance" xml:space="preserve">
<value>The update servers are in maintenance.</value>
</data>
<data name="StatusText_MinecraftProfileWarning" xml:space="preserve"> <data name="StatusText_MinecraftProfileWarning" xml:space="preserve">
<value>Minecraft profile folder seems to be not valid.</value> <value>Minecraft profile folder seems to be not valid.</value>
</data> </data>

View File

@@ -1,85 +1,69 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<OutputType>WinExe</OutputType> <OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows</TargetFramework> <TargetFramework>net8.0-windows</TargetFramework>
<StartupObject>Sub Main</StartupObject>
<UseWindowsForms>true</UseWindowsForms> <UseWindowsForms>true</UseWindowsForms>
<MyType>WindowsForms</MyType>
<ApplicationIcon>icons8_download_from_ftp.ico</ApplicationIcon> <ApplicationIcon>icons8_download_from_ftp.ico</ApplicationIcon>
<AssemblyName>Minecraft Modpack Updater</AssemblyName> <AssemblyName>Minecraft Modpack Updater</AssemblyName>
<ImplicitUsings>true</ImplicitUsings>
<IncludeAllContentForSelfExtract>true</IncludeAllContentForSelfExtract> <IncludeAllContentForSelfExtract>true</IncludeAllContentForSelfExtract>
<Version>1.4.1.0</Version> <Version>1.5.0.6</Version>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<DebugSymbols>true</DebugSymbols>
<DebugType>embedded</DebugType>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<None Remove="CustomThemes\Office2019DarkBluePurple.tssp" /> <None Remove="CustomThemes\Office2019DarkBluePurple.tssp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<EmbeddedResource Include="CustomThemes\Office2019DarkBluePurple.tssp" /> <EmbeddedResource Include="CustomThemes\Office2019DarkBluePurple.tssp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Import Include="System.Data" /> <Compile Update="FiledialogFilters.Designer.cs">
<Import Include="System.Drawing" />
<Import Include="System.Windows.Forms" />
</ItemGroup>
<ItemGroup>
<Compile Update="FiledialogFilters.Designer.vb">
<DesignTime>True</DesignTime> <DesignTime>True</DesignTime>
<AutoGen>True</AutoGen> <AutoGen>True</AutoGen>
<DependentUpon>FiledialogFilters.resx</DependentUpon> <DependentUpon>FiledialogFilters.resx</DependentUpon>
</Compile> </Compile>
<Compile Update="LangRes.Designer.vb"> <Compile Update="LangRes.Designer.cs">
<DesignTime>True</DesignTime> <DesignTime>True</DesignTime>
<AutoGen>True</AutoGen> <AutoGen>True</AutoGen>
<DependentUpon>LangRes.resx</DependentUpon> <DependentUpon>LangRes.resx</DependentUpon>
</Compile> </Compile>
<Compile Update="My Project\Application.Designer.vb">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Application.myapp</DependentUpon>
</Compile>
<Compile Update="MySymbols.Designer.vb">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>MySymbols.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<None Update="My Project\Application.myapp">
<Generator>MyApplicationCodeGenerator</Generator>
<LastGenOutput>Application.Designer.vb</LastGenOutput>
</None>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<EmbeddedResource Update="FiledialogFilters.resx"> <EmbeddedResource Update="FiledialogFilters.resx">
<Generator>ResXFileCodeGenerator</Generator> <Generator>ResXFileCodeGenerator</Generator>
<CustomToolNamespace>My.Resources</CustomToolNamespace> <CustomToolNamespace>ModpackUpdater.My.Resources</CustomToolNamespace>
<LastGenOutput>FiledialogFilters.Designer.vb</LastGenOutput> <LastGenOutput>FiledialogFilters.Designer.cs</LastGenOutput>
</EmbeddedResource> </EmbeddedResource>
<EmbeddedResource Update="LangRes.resx"> <EmbeddedResource Update="LangRes.resx">
<Generator>ResXFileCodeGenerator</Generator> <Generator>ResXFileCodeGenerator</Generator>
<CustomToolNamespace>My.Resources</CustomToolNamespace> <CustomToolNamespace>ModpackUpdater.My.Resources</CustomToolNamespace>
<LastGenOutput>LangRes.Designer.vb</LastGenOutput> <LastGenOutput>LangRes.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Update="MySymbols.resx">
<Generator>ResXFileCodeGenerator</Generator>
<CustomToolNamespace>My.Resources</CustomToolNamespace>
<LastGenOutput>MySymbols.Designer.vb</LastGenOutput>
</EmbeddedResource> </EmbeddedResource>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Mono.Options" Version="6.12.0.148" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Pilz.Configuration" Version="3.1.2" />
<PackageReference Include="Pilz.Cryptography" Version="2.0.1" /> <PackageReference Include="Pilz.Cryptography" Version="2.0.1" />
<PackageReference Include="Pilz.IO" Version="2.0.0" /> <PackageReference Include="Pilz.IO" Version="2.0.0" />
<PackageReference Include="Pilz.UI.Telerik.SymbolFactory" Version="2.0.3" />
<PackageReference Include="Pilz.Win32" Version="2.0.0" /> <PackageReference Include="Pilz.Win32" Version="2.0.0" />
<PackageReference Include="UI.for.WinForms.Common" Version="2024.2.514" /> <PackageReference Include="UI.for.WinForms.Common" Version="2024.2.514" />
<PackageReference Include="Unleash.Client" Version="4.1.9" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\ModpackUpdater.GitLab\ModpackUpdater.GitLab.vbproj" /> <ProjectReference Include="..\ModpackUpdater.Manager\ModpackUpdater.Manager.csproj" />
<ProjectReference Include="..\ModpackUpdater.Manager\ModpackUpdater.Manager.vbproj" /> <ProjectReference Include="..\ModpackUpdater.Model\ModpackUpdater.Model.csproj" />
<ProjectReference Include="..\ModpackUpdater.Model\ModpackUpdater.Model.vbproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Symbols\*.svg" />
</ItemGroup>
</Project> </Project>

View File

@@ -1,38 +0,0 @@
'------------------------------------------------------------------------------
' <auto-generated>
' Dieser Code wurde von einem Tool generiert.
' Laufzeitversion:4.0.30319.42000
'
' Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
' der Code erneut generiert wird.
' </auto-generated>
'------------------------------------------------------------------------------
Option Strict On
Option Explicit On
Namespace My
'HINWEIS: Diese Datei wird automatisch generiert und darf nicht direkt bearbeitet werden. Wenn Sie Änderungen vornehmen möchten
' oder in dieser Datei Buildfehler auftreten, wechseln Sie zum Projekt-Designer.
' (Wechseln Sie dazu zu den Projekteigenschaften, oder doppelklicken Sie auf den Knoten "Mein Projekt" im
' Projektmappen-Explorer). Nehmen Sie auf der Registerkarte "Anwendung" entsprechende Änderungen vor.
'
Partial Friend Class MyApplication
<Global.System.Diagnostics.DebuggerStepThroughAttribute()> _
Public Sub New()
MyBase.New(Global.Microsoft.VisualBasic.ApplicationServices.AuthenticationMode.Windows)
Me.IsSingleInstance = false
Me.EnableVisualStyles = true
Me.SaveMySettingsOnExit = true
Me.ShutDownStyle = Global.Microsoft.VisualBasic.ApplicationServices.ShutdownMode.AfterMainFormCloses
End Sub
<Global.System.Diagnostics.DebuggerStepThroughAttribute()> _
Protected Overrides Sub OnCreateMainForm()
Me.MainForm = Global.ModpackUpdater.Form1
End Sub
End Class
End Namespace

View File

@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<MyApplicationData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<MySubMain>true</MySubMain>
<MainForm>Form1</MainForm>
<SingleInstance>false</SingleInstance>
<ShutdownMode>0</ShutdownMode>
<EnableVisualStyles>true</EnableVisualStyles>
<AuthenticationMode>0</AuthenticationMode>
<SaveMySettingsOnExit>true</SaveMySettingsOnExit>
</MyApplicationData>

View File

@@ -1,157 +0,0 @@
'------------------------------------------------------------------------------
' <auto-generated>
' Dieser Code wurde von einem Tool generiert.
' Laufzeitversion:4.0.30319.42000
'
' Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
' der Code erneut generiert wird.
' </auto-generated>
'------------------------------------------------------------------------------
Option Strict On
Option Explicit On
Imports System
Namespace My.Resources
'Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert
'-Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
'Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
'mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
'''<summary>
''' Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
'''</summary>
<Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0"), _
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute()> _
Friend Class MySymbols
Private Shared resourceMan As Global.System.Resources.ResourceManager
Private Shared resourceCulture As Global.System.Globalization.CultureInfo
<Global.System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")> _
Friend Sub New()
MyBase.New
End Sub
'''<summary>
''' Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
'''</summary>
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Friend Shared ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager
Get
If Object.ReferenceEquals(resourceMan, Nothing) Then
Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("ModpackUpdater.MySymbols", GetType(MySymbols).Assembly)
resourceMan = temp
End If
Return resourceMan
End Get
End Property
'''<summary>
''' Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
''' Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
'''</summary>
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Friend Shared Property Culture() As Global.System.Globalization.CultureInfo
Get
Return resourceCulture
End Get
Set
resourceCulture = value
End Set
End Property
'''<summary>
''' Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
'''</summary>
Friend Shared ReadOnly Property icons8_checkmark_16px() As System.Drawing.Bitmap
Get
Dim obj As Object = ResourceManager.GetObject("icons8_checkmark_16px", resourceCulture)
Return CType(obj,System.Drawing.Bitmap)
End Get
End Property
'''<summary>
''' Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
'''</summary>
Friend Shared ReadOnly Property icons8_delete_16px() As System.Drawing.Bitmap
Get
Dim obj As Object = ResourceManager.GetObject("icons8_delete_16px", resourceCulture)
Return CType(obj,System.Drawing.Bitmap)
End Get
End Property
'''<summary>
''' Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
'''</summary>
Friend Shared ReadOnly Property icons8_download_from_ftp_16px() As System.Drawing.Bitmap
Get
Dim obj As Object = ResourceManager.GetObject("icons8_download_from_ftp_16px", resourceCulture)
Return CType(obj,System.Drawing.Bitmap)
End Get
End Property
'''<summary>
''' Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
'''</summary>
Friend Shared ReadOnly Property icons8_general_warning_sign_16px() As System.Drawing.Bitmap
Get
Dim obj As Object = ResourceManager.GetObject("icons8_general_warning_sign_16px", resourceCulture)
Return CType(obj,System.Drawing.Bitmap)
End Get
End Property
'''<summary>
''' Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
'''</summary>
Friend Shared ReadOnly Property icons8_opened_folder_16px() As System.Drawing.Bitmap
Get
Dim obj As Object = ResourceManager.GetObject("icons8_opened_folder_16px", resourceCulture)
Return CType(obj,System.Drawing.Bitmap)
End Get
End Property
'''<summary>
''' Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
'''</summary>
Friend Shared ReadOnly Property icons8_save_16px() As System.Drawing.Bitmap
Get
Dim obj As Object = ResourceManager.GetObject("icons8_save_16px", resourceCulture)
Return CType(obj,System.Drawing.Bitmap)
End Get
End Property
'''<summary>
''' Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
'''</summary>
Friend Shared ReadOnly Property icons8_software_installer_16px() As System.Drawing.Bitmap
Get
Dim obj As Object = ResourceManager.GetObject("icons8_software_installer_16px", resourceCulture)
Return CType(obj,System.Drawing.Bitmap)
End Get
End Property
'''<summary>
''' Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
'''</summary>
Friend Shared ReadOnly Property icons8_update_16px() As System.Drawing.Bitmap
Get
Dim obj As Object = ResourceManager.GetObject("icons8_update_16px", resourceCulture)
Return CType(obj,System.Drawing.Bitmap)
End Get
End Property
'''<summary>
''' Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
'''</summary>
Friend Shared ReadOnly Property icons8_wrench_16px() As System.Drawing.Bitmap
Get
Dim obj As Object = ResourceManager.GetObject("icons8_wrench_16px", resourceCulture)
Return CType(obj,System.Drawing.Bitmap)
End Get
End Property
End Class
End Namespace

View File

@@ -1,148 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="icons8_checkmark_16px" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>Resources\icons8_checkmark_16px.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icons8_delete_16px" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>Resources\icons8_delete_16px.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icons8_download_from_ftp_16px" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>Resources\icons8_download_from_ftp_16px.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icons8_general_warning_sign_16px" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>Resources\icons8_general_warning_sign_16px.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icons8_opened_folder_16px" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>Resources\icons8_opened_folder_16px.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icons8_save_16px" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>Resources\icons8_save_16px.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icons8_software_installer_16px" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>Resources\icons8_software_installer_16px.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icons8_update_16px" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>Resources\icons8_update_16px.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icons8_wrench_16px" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>Resources\icons8_wrench_16px.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>

32
ModpackUpdater/Options.cs Normal file
View File

@@ -0,0 +1,32 @@
using ModpackUpdater.Model;
using Mono.Options;
namespace ModpackUpdater;
internal class Options
{
private readonly List<string> additionals = [];
public IReadOnlyList<string> Additionals => additionals;
public bool Silent { get; private set; }
public bool NoUi { get; private set; }
public UpdateCheckOptionsAdv UpdateOptions { get; } = new();
public Options(string[] args)
{
var options = new OptionSet
{
{ "silent", "Do not output anything.", s => Silent = s != null },
{ "n|noui", "Install without user interface.", n => NoUi = n != null },
{ "p|profile=", "Sets the minecraft profile folder.", p => UpdateOptions.ProfileFolder = p },
{ "c|config=", "Sets the minecraft profile folder.", c => UpdateOptions.ModpackConfig = c },
{ "s|side=", "Sets the minecraft profile folder.\nDefault side is Client.\nAvailable: Client, Server", s => UpdateOptions.Side = Enum.Parse<Side>(s)},
{ "u|uai", "Allow an update directly after install. This only has affect if there is no existing installation.", uai => UpdateOptions.AllowUpdaterAfterInstall = uai != null},
{ "noupdate", "Skip the update check.", noupdate => UpdateOptions.NoUpdate = noupdate != null},
{ "m|maintenance", "Ignores the maintenance mode.", m => UpdateOptions.IgnoreMaintenance = m != null},
{ "k|key=", "An key for retriving extra files on updates.", k => UpdateOptions.ExtrasKey = k},
};
additionals.AddRange(options.Parse(args));
}
}

114
ModpackUpdater/Program.cs Normal file
View File

@@ -0,0 +1,114 @@
using ModpackUpdater.Manager;
using ModpackUpdater.Model;
using Newtonsoft.Json;
using Pilz.Configuration;
using Telerik.WinControls;
namespace ModpackUpdater;
public static class Program
{
private static readonly SettingsManager settingsManager;
public static ISettings Settings => settingsManager.Instance;
static Program()
{
settingsManager = new(GetSettingsPath(2), true);
MigrateLegacySettings(GetSettingsPath(null));
}
[STAThread]
internal static void Main(string[] args)
{
var options = new Options(args);
if (options.NoUi)
InstallWithoutGui(options.UpdateOptions, options.Silent);
else
RunApp(options.UpdateOptions);
}
private static void RunApp(UpdateCheckOptionsAdv updateOptions)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.SetHighDpiMode(HighDpiMode.PerMonitorV2);
if (ThemeResolutionService.LoadPackageResource("ModpackUpdater.CustomThemes.Office2019DarkBluePurple.tssp"))
ThemeResolutionService.ApplicationThemeName = "Office2019DarkBluePurple";
Application.Run(new Form1(updateOptions));
}
private static string GetSettingsPath(int? settingsVersion = 2)
{
const string AppDataDirectoryName = "MinecraftModpackUpdater";
var fileNamePostfix = settingsVersion == null ? string.Empty : $"V{settingsVersion}";
var SettingsFileName = $"Settings{fileNamePostfix}.json";
var settingsPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), AppDataDirectoryName);
Directory.CreateDirectory(settingsPath);
settingsPath = Path.Combine(settingsPath, SettingsFileName);
return settingsPath;
}
private static void MigrateLegacySettings(string settingsPath)
{
// Try load legacy config file
if (!File.Exists(settingsPath) || JsonConvert.DeserializeObject<AppConfig>(File.ReadAllText(settingsPath)) is not AppConfig legacyConfig)
return;
// Migrate
var newConfig = Settings.Get<AppConfig>();
newConfig.LastMinecraftProfilePath = legacyConfig.LastMinecraftProfilePath;
if (ModpackInfo.TryLoad(legacyConfig.LastMinecraftProfilePath) is ModpackInfo info)
{
#pragma warning disable CS0612 // Typ oder Element ist veraltet
info.ConfigUrl = legacyConfig.ConfigFilePath;
#pragma warning restore CS0612 // Typ oder Element ist veraltet
}
// Ensure save settings
settingsManager.Save();
// Delete legacy config file
File.Delete(settingsPath);
}
private static void InstallWithoutGui(UpdateCheckOptionsAdv updateOptions, bool silent)
{
var info = ModpackInfo.TryLoad(updateOptions.ProfileFolder);
var config = ModpackConfig.LoadFromUrl(CheckModpackConfigUrl(updateOptions.ModpackConfig, info));
// Check features
if (!string.IsNullOrWhiteSpace(updateOptions.ExtrasKey))
info.ExtrasKey = updateOptions.ExtrasKey;
if (!string.IsNullOrWhiteSpace(info.ExtrasKey))
updateOptions.IncludeExtras = AppFeatures.AllowExtras.IsEnabled(new AllowExtrasFeatureContext(info, config));
// Check for update
var installer = new ModpackInstaller(config, info);
var result = installer.Check(updateOptions).Result;
if (!silent && !updateOptions.NoUpdate && new AppUpdater().Check().Result)
Console.WriteLine("A new version is available!");
if (result.HasUpdates)
{
var success = installer.Install(result).Result;
if (!silent)
Console.WriteLine($"Installation {(success ?? false ? "completed successfully" : "failed")}!");
}
else if (!silent)
Console.WriteLine("No updates available");
}
private static string CheckModpackConfigUrl(string configUrl, ModpackInfo info)
{
if (string.IsNullOrWhiteSpace(configUrl) && !string.IsNullOrWhiteSpace(info.ConfigUrl))
return info.ConfigUrl;
return configUrl;
}
}

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project>
<PropertyGroup>
<Configuration>Release</Configuration>
<Platform>Any CPU</Platform>
<PublishDir>bin\publish\general\</PublishDir>
<PublishProtocol>FileSystem</PublishProtocol>
<_TargetId>Folder</_TargetId>
<TargetFramework>net8.0-windows</TargetFramework>
<RuntimeIdentifier>win-x86</RuntimeIdentifier>
<SelfContained>true</SelfContained>
<PublishSingleFile>true</PublishSingleFile>
<PublishReadyToRun>false</PublishReadyToRun>
</PropertyGroup>
</Project>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 337 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 417 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 494 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 588 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 334 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 321 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 430 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 631 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 490 B

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="32" height="32">
<path fill="#c8e6c9" d="M44,24c0,11.045-8.955,20-20,20S4,35.045,4,24S12.955,4,24,4S44,12.955,44,24z" />
<path fill="#4caf50" d="M34.586,14.586l-13.57,13.586l-5.602-5.586l-2.828,2.828l8.434,8.414l16.395-16.414L34.586,14.586z" />
</svg>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 48 48">
<path fill="#F44336" d="M21.5 4.5H26.501V43.5H21.5z" transform="rotate(45.001 24 24)" />
<path fill="#F44336" d="M21.5 4.5H26.5V43.501H21.5z" transform="rotate(135.008 24 24)" />
</svg>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="32" height="32">
<path fill="#b39ddb" d="M30.6,44H17.4c-2,0-3.7-1.4-4-3.4L9,11h30l-4.5,29.6C34.2,42.6,32.5,44,30.6,44z" />
<path fill="#9575cd" d="M28 6L20 6 14 12 34 12z" />
<path fill="#7e57c2" d="M10,8h28c1.1,0,2,0.9,2,2v2H8v-2C8,8.9,8.9,8,10,8z" />
</svg>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="32" height="32">
<path fill="#43A047" d="M40.6 12.1L17 35.7 7.4 26.1 4.6 29 17 41.3 43.4 14.9z" />
</svg>

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 48 48">
<path fill="#FFA000" d="M38,14H20l-4-4H6c-2.209,0-4,1.791-4,4v8h40v-4C42,15.791,40.209,14,38,14" />
<path fill="#FFCA28" d="M38,14H6c-2.209,0-4,1.791-4,4v20c0,2.209,1.791,4,4,4h32c2.209,0,4-1.791,4-4V18C42,15.791,40.209,14,38,14" />
<path fill="#1565C0" d="M22 46L15 38 29 38z" />
<path fill="#1565C0" d="M19 28H25V39.125H19z" />
<path fill="#4A148C" d="M46,7.5C46,8.328,45.329,9,44.5,9S43,8.328,43,7.5S43.671,6,44.5,6S46,6.672,46,7.5" />
<path fill="#9C27B0" d="M45.5,16c-5.238,0-9.5-4.262-9.5-9.5V6h-3v1h0.025C33.284,13.493,38.508,18.716,45,18.975V19h1v-3H45.5z" />
<path fill="#7B1FA2" d="M45.5,11C43.019,11,41,8.981,41,6.5V6h-3v1h0.025c0.248,3.736,3.238,6.727,6.975,6.975V14h1v-3H45.5z" />
<path fill="#BA68C8" d="M45.5,21C37.505,21,31,14.495,31,6.5V6h-3v1h0.025C28.289,16.25,35.751,23.711,45,23.975V24h1v-3H45.5z" />
</svg>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="32" height="32">
<path fill="#ffeb3b" d="M24,6c0.18,0,0.626,0.049,0.893,0.504l19.968,34.005c0.249,0.424,0.111,0.795,0.006,0.978C44.778,41.641,44.513,42,43.968,42H4.032c-0.546,0-0.81-0.359-0.898-0.514c-0.105-0.183-0.244-0.554,0.006-0.978L23.107,6.504C23.374,6.049,23.82,6,24,6" />
<circle cx="24" cy="37" r="2" fill="#455a64" />
<polygon fill="#455a64" points="25,32 23,32 22,17 22,16 26,16 26,17" />
<path fill="#607d8b" d="M24,7l0.03,0.01L43.968,41L4.002,41.015l19.966-34.01C23.971,7.004,23.983,7,24,7 M24,4c-1.017,0-2.034,0.497-2.617,1.491L1.415,39.496C0.241,41.494,1.697,44,4.032,44h39.936c2.335,0,3.791-2.506,2.617-4.504L26.617,5.491C26.034,4.497,25.017,4,24,4L24,4z" />
</svg>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="32" height="32">
<path fill="#FFA000" d="M38,12H22l-4-4H8c-2.2,0-4,1.8-4,4v24c0,2.2,1.8,4,4,4h31c1.7,0,3-1.3,3-3V16C42,13.8,40.2,12,38,12z" />
<path fill="#FFCA28" d="M42.2,18H15.3c-1.9,0-3.6,1.4-3.9,3.3L8,40h31.7c1.9,0,3.6-1.4,3.9-3.3l2.5-14C46.6,20.3,44.7,18,42.2,18z" />
</svg>

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 48 48">
<path fill="#455A64" d="M32,6h-8c0,1.104-1,3-3,3s-3-1.896-3-3h-8c-2.209,0-4,1.791-4,4v30c0,2.209,1.791,4,4,4h22c2.209,0,4-1.791,4-4V10C36,7.791,34.209,6,32,6" />
<path fill="#FFF" d="M32,41H10c-0.552,0-1-0.448-1-1V10c0-0.552,0.448-1,1-1h22c0.552,0,1,0.448,1,1v30C33,40.552,32.552,41,32,41z" />
<path fill="#90A4AE" d="M23,6c0,1.105-0.895,2-2,2s-2-0.895-2-2h-7v4c0,1.105,0.895,2,2,2h14c1.105,0,2-0.895,2-2V6H23z" />
<path fill="#90A4AE" d="M21,2c-2.206,0-4,1.794-4,4s1.794,4,4,4s4-1.794,4-4S23.206,2,21,2 M21,8c-1.103,0-2-0.896-2-2s0.897-2,2-2s2,0.896,2,2S22.103,8,21,8" />
<path fill="#90CAF9" d="M17 17H42V47H17z" />
<g>
<path fill="#1976D2" d="M21 37H33V39H21zM21 33H38V35H21zM21 29H33V31H21zM21 25H38V27H21z" />
</g>
</svg>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="32" height="32">
<path fill="#1565c0" d="M13,13c0-3.3,2.7-6,6-6h10c3.3,0,6,2.7,6,6h4c0-5.5-4.5-10-10-10H19C13.5,3,9,7.5,9,13v11.2h4V13z" />
<path fill="#1565c0" d="M4.6,22l6.4,8.4l6.4-8.4H4.6z" />
<path fill="#1565c0" d="M35,35c0,3.3-2.7,6-6,6H19c-3.3,0-6-2.7-6-6H9c0,5.5,4.5,10,10,10h10c5.5,0,10-4.5,10-10V23h-4V35z" />
<path fill="#1565c0" d="M30.6,26l6.4-8.4l6.4,8.4H30.6z" />
</svg>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="32" height="32">
<path fill="#2196f3" d="M24 12L16 6 24 0z" />
<path fill="#2196f3" d="M24,44C13,44,4,35,4,24c0-4.7,1.7-9.3,4.8-12.9l3,2.6C9.3,16.5,8,20.2,8,24c0,8.8,7.2,16,16,16 s16-7.2,16-16S32.8,8,24,8h-3.2V4H24c11,0,20,9,20,20C44,35,35,44,24,44z" />
</svg>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="32" height="32">
<path fill="#3498db" d="M42 42L6 42 6 6 37 6 42 11z" />
<path fill="#fff" d="M39,39c0,0.553-0.447,1-1,1H10c-0.553,0-1-0.447-1-1V25c0-0.553,0.447-1,1-1h28c0.553,0,1,0.447,1,1 V39z" />
<path fill="#cfd8dc" d="M13 31H35V33H13zM13 27H35V29H13zM13 35H35V37H13z" />
<path fill="#2980b9" d="M9,6v10c0,1.104,0.896,2,2,2h15c1.104,0,2-0.896,2-2V6H9z" />
<path fill="#b0bec5" d="M15,6v10c0,1.104,0.896,2,2,2h15c1.104,0,2-0.896,2-2V6H15z" />
<path fill="#263238" d="M26 8H30V16H26z" />
</svg>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="32" height="32">
<path fill="#E65100" d="M25.6,34.4c0.1-0.4,0.1-0.9,0.1-1.4s0-0.9-0.1-1.4l2.8-2c0.3-0.2,0.4-0.6,0.2-0.9l-2.7-4.6c-0.2-0.3-0.5-0.4-0.8-0.3L22,25.3c-0.7-0.6-1.5-1-2.4-1.4l-0.3-3.4c0-0.3-0.3-0.6-0.6-0.6h-5.3c-0.3,0-0.6,0.3-0.6,0.6L12.4,24c-0.9,0.3-1.6,0.8-2.4,1.4l-3.1-1.4c-0.3-0.1-0.7,0-0.8,0.3l-2.7,4.6c-0.2,0.3-0.1,0.7,0.2,0.9l2.8,2c-0.1,0.4-0.1,0.9-0.1,1.4s0,0.9,0.1,1.4l-2.8,2c-0.3,0.2-0.4,0.6-0.2,0.9l2.7,4.6c0.2,0.3,0.5,0.4,0.8,0.3l3.1-1.4c0.7,0.6,1.5,1,2.4,1.4l0.3,3.4c0,0.3,0.3,0.6,0.6,0.6h5.3c0.3,0,0.6-0.3,0.6-0.6l0.3-3.4c0.9-0.3,1.6-0.8,2.4-1.4l3.1,1.4c0.3,0.1,0.7,0,0.8-0.3l2.7-4.6c0.2-0.3,0.1-0.7-0.2-0.9L25.6,34.4z M16,38c-2.8,0-5-2.2-5-5c0-2.8,2.2-5,5-5c2.8,0,5,2.2,5,5C21,35.8,18.8,38,16,38z" />
<path fill="#FFA000" d="M41.9,15.3C42,14.8,42,14.4,42,14s0-0.8-0.1-1.3l2.5-1.8c0.3-0.2,0.3-0.5,0.2-0.8l-2.5-4.3c-0.2-0.3-0.5-0.4-0.8-0.2l-2.9,1.3c-0.7-0.5-1.4-0.9-2.2-1.3l-0.3-3.1C36,2.2,35.8,2,35.5,2h-4.9c-0.3,0-0.6,0.2-0.6,0.5l-0.3,3.1c-0.8,0.3-1.5,0.7-2.2,1.3l-2.9-1.3c-0.3-0.1-0.6,0-0.8,0.2l-2.5,4.3c-0.2,0.3-0.1,0.6,0.2,0.8l2.5,1.8C24,13.2,24,13.6,24,14s0,0.8,0.1,1.3l-2.5,1.8c-0.3,0.2-0.3,0.5-0.2,0.8l2.5,4.3c0.2,0.3,0.5,0.4,0.8,0.2l2.9-1.3c0.7,0.5,1.4,0.9,2.2,1.3l0.3,3.1c0,0.3,0.3,0.5,0.6,0.5h4.9c0.3,0,0.6-0.2,0.6-0.5l0.3-3.1c0.8-0.3,1.5-0.7,2.2-1.3l2.9,1.3c0.3,0.1,0.6,0,0.8-0.2l2.5-4.3c0.2-0.3,0.1-0.6-0.2-0.8L41.9,15.3z M33,19c-2.8,0-5-2.2-5-5c0-2.8,2.2-5,5-5c2.8,0,5,2.2,5,5C38,16.8,35.8,19,33,19z" />
</svg>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 48 48">
<path fill="#78909C" d="M6,29v10c0,2.209,1.791,4,4,4h28c2.209,0,4-1.791,4-4V29H6z" />
<path fill="#455A64" d="M42,29c0,2.209-1.791,4-4,4H10c-2.209,0-4-1.791-4-4l3-18c0.219-2.094,1.791-4,4-4h22c2.209,0,3.688,1.75,4,4L42,29z" />
<path fill="#64DD17" d="M35 36A2 2 0 1 0 35 40A2 2 0 1 0 35 36Z" />
<path fill="#00E5FF" d="M24.001 27.242L32 19.242 16 19.242z" />
<path fill="#00E5FF" d="M21 4H26.998V19.999000000000002H21z" />
</svg>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="32" height="32">
<path fill="#fbc02d" d="M23.9,44C12.9,44,4,35,4,24S12.9,4,23.9,4c8.2,0,15.7,5.2,18.6,12.9l-3.7,1.4 C36.5,12.2,30.5,8,23.9,8C15.1,8,8,15.2,8,24s7.1,16,15.9,16c6.5,0,12.3-3.9,14.8-10l3.7,1.5C39.3,39.1,32.1,44,23.9,44z" />
<path fill="#fbc02d" d="M45,11l-3,10l-9-3.7L45,11z" />
<path fill="#43a047" d="M48,38c0,5.523-4.478,10-10,10c-5.523,0-10-4.477-10-10s4.477-10,10-10C43.522,28,48,32.477,48,38" />
<path fill="#dcedc8" d="M42.492 33.35L36.802 39.051 34.074 36.33 31.951 38.457 36.806 43.301 44.619 35.473z" />
</svg>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="32" height="32">
<path fill="#607d8b" d="M42.625,11l-7.016,7.016c0,0-2.172,0.172-3.984-1.641s-1.641-3.984-1.641-3.984L37,5.375 C37,5.375,35.75,5,33.952,5c-3.182,0-6.464,1.322-8.69,3.486C23.629,10.149,23,11.871,23,13.5c0,2.5,1.011,4.091,1,5.125 c-0.003,0.25-0.189,0.493-0.388,0.692l-9.056,9.056c-0.654-0.185-1.342-0.291-2.056-0.291c-4.142,0-7.5,3.339-7.5,7.459 S8.358,43,12.5,43s7.5-3.339,7.5-7.459c0-0.748-0.114-1.47-0.32-2.151l9.003-9.003c0.199-0.199,0.443-0.385,0.692-0.388 c1.034-0.011,2.625,1,5.125,1c1.628,0,3.351-0.629,5.014-2.263C41.678,20.512,43,17.23,43,14.048C43,12.25,42.625,11,42.625,11z M13.438,39l-3.5-0.938L9,34.562L11.562,32l3.5,0.938l0.938,3.5L13.438,39z" />
</svg>

View File

@@ -0,0 +1,11 @@
using ModpackUpdater.Manager;
namespace ModpackUpdater;
public class UpdateCheckOptionsAdv : UpdateCheckOptions
{
public string ProfileFolder { get; set; }
public string ModpackConfig { get; set; }
public bool NoUpdate { get; set; }
public string ExtrasKey { get; set; }
}