diff --git a/SCTools/SCTool_Redesigned/Pages/updatePatcher.xaml.cs b/SCTools/SCTool_Redesigned/Pages/updatePatcher.xaml.cs
index 70963a2..29edf86 100644
--- a/SCTools/SCTool_Redesigned/Pages/updatePatcher.xaml.cs
+++ b/SCTools/SCTool_Redesigned/Pages/updatePatcher.xaml.cs
@@ -16,8 +16,8 @@ namespace SCTool_Redesigned.Pages
///
public partial class updatePatcher : Page
{
- private static ApplicationUpdater _updater = new ApplicationUpdater(GetUpdateRepository(), App.ExecutableDir, Properties.Resources.UpdateScript, new CustomPackageVerifier());
- private static CancellationTokenSource _cancellationToken = new CancellationTokenSource(); //TODO: Dispose, cancel when exit
+ private static CustomApplicationUpdater _updater = new(GetUpdateRepository(), App.ExecutableDir, Properties.Resources.UpdateScript, new CustomPackageVerifier());
+ private static CancellationTokenSource _cancellationToken = new(); //TODO: Dispose, cancel when exit
public updatePatcher()
{
InitializeComponent();
diff --git a/SCTools/SCTool_Redesigned/Properties/Resources.ko-KR.resx b/SCTools/SCTool_Redesigned/Properties/Resources.ko-KR.resx
index fc9b46f..1e78d7c 100644
--- a/SCTools/SCTool_Redesigned/Properties/Resources.ko-KR.resx
+++ b/SCTools/SCTool_Redesigned/Properties/Resources.ko-KR.resx
@@ -401,7 +401,7 @@
**문서를 불러올 수 없습니다.**
- 런처 업데이트 중
+ 패쳐 업데이트 중
환영합니다
diff --git a/SCTools/SCTool_Redesigned/Resources/update.bat b/SCTools/SCTool_Redesigned/Resources/update.bat
index 526b4fd..877ade0 100644
--- a/SCTools/SCTool_Redesigned/Resources/update.bat
+++ b/SCTools/SCTool_Redesigned/Resources/update.bat
@@ -5,14 +5,14 @@ set updatepath=%workpath%updates\
set latestpath=%updatepath%latest\
timeout 1
-xcopy "%latestpath%*.*" "%workpath%" /s /k /h /y
+::xcopy "%latestpath%*.*" "%workpath%" /s /k /h /y
if not errorlevel 0 goto update_error
del "%updatepath%latest.json"
-del "%updatepath%latest.zip"
-del /q "%latestpath%*"
-for /d %%p in ("%latestpath%*.*") do rmdir /s /q "%%p"
-rmdir /s /q "%latestpath%"
+::del "%updatepath%latest.zip"
+::del /q "%latestpath%*"
+::for /d %%p in ("%latestpath%*.*") do rmdir /s /q "%%p"
+::rmdir /s /q "%latestpath%"
start "" "%workpath%Shatagon.exe" update_status 0
exit
diff --git a/SCTools/SCTool_Redesigned/Update/CustomApplicationUpdater.cs b/SCTools/SCTool_Redesigned/Update/CustomApplicationUpdater.cs
new file mode 100644
index 0000000..5663c35
--- /dev/null
+++ b/SCTools/SCTool_Redesigned/Update/CustomApplicationUpdater.cs
@@ -0,0 +1,232 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO.Compression;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using NLog;
+using NSW.StarCitizen.Tools.Lib.Helpers;
+using NSW.StarCitizen.Tools.Lib.Update;
+
+namespace SCTool_Redesigned.Update
+{
+ public class CustomApplicationUpdater : IDisposable
+ {
+ private static readonly Logger _logger = LogManager.GetCurrentClassLogger();
+ private readonly IUpdateRepository _updateRepository;
+ private readonly IPackageVerifier _packageVerifier;
+ private readonly string _executableDir;
+ private readonly string _updateScriptContent;
+ private readonly string _updateScriptPath;
+ private readonly string _updatesStoragePath;
+ private readonly string _schedInstallArchivePath;
+ private readonly string _schedInstallExecutablePath;
+ private readonly string _schedInstallJsonPath;
+ private readonly string _installUnpackedDir;
+ private readonly string _installUnpackedExecutablePath;
+ private readonly string _currentVersion;
+
+ public interface IPackageVerifier
+ {
+ bool VerifyPackage(string path);
+ }
+
+ public event EventHandler MonitorStarted
+ {
+ add { _updateRepository.MonitorStarted += value; }
+ remove { _updateRepository.MonitorStarted -= value; }
+ }
+
+ public event EventHandler MonitorStopped
+ {
+ add { _updateRepository.MonitorStopped += value; }
+ remove { _updateRepository.MonitorStopped -= value; }
+ }
+
+ public event EventHandler MonitorNewVersion
+ {
+ add { _updateRepository.MonitorNewVersion += value; }
+ remove { _updateRepository.MonitorNewVersion -= value; }
+ }
+
+ public bool AllowPreReleases
+ {
+ get => _updateRepository.AllowPreReleases;
+ set => _updateRepository.AllowPreReleases = value;
+ }
+
+ public CustomApplicationUpdater(IUpdateRepository updateRepository, string executableDir,
+ string updateScriptContent, IPackageVerifier packageVerifier)
+ {
+ if (updateRepository.CurrentVersion == null)
+ throw new InvalidOperationException("update repository current version is not set");
+ _updateRepository = updateRepository;
+ _executableDir = executableDir;
+ _updateScriptContent = updateScriptContent;
+ _packageVerifier = packageVerifier;
+ _updateScriptPath = Path.Combine(_executableDir, "update.bat");
+ _updatesStoragePath = Path.Combine(_executableDir, "updates");
+ _schedInstallArchivePath = Path.Combine(_updatesStoragePath, "latest.zip");
+ _schedInstallExecutablePath = Path.Combine(_updatesStoragePath, "shatagon.exe");
+ _schedInstallJsonPath = Path.Combine(_updatesStoragePath, "latest.json");
+ _installUnpackedDir = Path.Combine(_updatesStoragePath, "latest");
+ _installUnpackedExecutablePath = Path.Combine(_updatesStoragePath, "latest", "shatagon.exe");
+ _currentVersion = _updateRepository.CurrentVersion;
+ }
+
+ public void Dispose() => _updateRepository.Dispose();
+
+ public void MonitorStart(int refreshTime) => _updateRepository.MonitorStart(refreshTime);
+
+ public void MonitorStop() => _updateRepository.MonitorStop();
+
+ public async Task CheckForUpdateVersionAsync(CancellationToken cancellationToken)
+ {
+ var latestUpdateInfo = await _updateRepository.GetLatestAsync(cancellationToken);
+ if (latestUpdateInfo != null && string.Compare(latestUpdateInfo.GetVersion(),
+ _currentVersion, StringComparison.OrdinalIgnoreCase) != 0)
+ {
+ return latestUpdateInfo;
+ }
+ return null;
+ }
+
+ public async Task DownloadVersionAsync(UpdateInfo version, CancellationToken cancellationToken, IDownloadProgress downloadProgress)
+ {
+ if (!Directory.Exists(_updatesStoragePath))
+ {
+ Directory.CreateDirectory(_updatesStoragePath);
+ }
+ return await _updateRepository.DownloadAsync(version, _updatesStoragePath, cancellationToken, downloadProgress);
+ }
+
+ public InstallUpdateStatus InstallScheduledUpdate()
+ {
+ _logger.Info("Install scheduled update");
+ if (ExtractReadyInstallUpdate() && ExtractUpdateScript())
+ {
+ using var updateProcess = new Process();
+ updateProcess.StartInfo.UseShellExecute = false;
+ updateProcess.StartInfo.RedirectStandardInput = false;
+ updateProcess.StartInfo.RedirectStandardOutput = false;
+ updateProcess.StartInfo.RedirectStandardError = false;
+ updateProcess.StartInfo.ErrorDialog = false;
+ updateProcess.StartInfo.CreateNoWindow = true;
+ updateProcess.StartInfo.WorkingDirectory = _executableDir;
+ updateProcess.StartInfo.FileName = _updateScriptPath;
+ if (!updateProcess.Start())
+ {
+ RemoveUpdateScript();
+ _logger.Info($"Failed launch updater script: {_updateScriptPath}");
+ return InstallUpdateStatus.LaunchScriptError;
+ }
+ return InstallUpdateStatus.Success;
+ }
+ CancelScheduleInstallUpdate();
+ return InstallUpdateStatus.ExtractFilesError;
+ }
+
+ public UpdateInfo? GetScheduledUpdateInfo() => File.Exists(_schedInstallArchivePath) ? JsonHelper.ReadFile(_schedInstallJsonPath) : null;
+
+ public bool IsAlreadyInstalledVersion(UpdateInfo updateInfo) =>
+ string.Compare(updateInfo.GetVersion(), _currentVersion, StringComparison.OrdinalIgnoreCase) == 0;
+
+ public void ApplyScheduledUpdateProps(UpdateInfo updateInfo) => _updateRepository.SetCurrentVersion(updateInfo.GetVersion());
+
+ public bool ScheduleInstallUpdate(UpdateInfo updateInfo, string filePath)
+ {
+ _logger.Info($"Shedule install update with version: {updateInfo.GetVersion()}");
+ if (File.Exists(filePath))
+ {
+ _updateRepository.SetCurrentVersion(_currentVersion);
+ try
+ {
+ if (!Directory.Exists(_updatesStoragePath))
+ {
+ Directory.CreateDirectory(_updatesStoragePath);
+ }
+ if (File.Exists(_schedInstallArchivePath))
+ {
+ File.Delete(_schedInstallArchivePath);
+ }
+ File.Move(filePath, _schedInstallArchivePath);
+ if (JsonHelper.WriteFile(_schedInstallJsonPath, updateInfo))
+ {
+ _updateRepository.SetCurrentVersion(updateInfo.GetVersion());
+ return true;
+ }
+ _logger.Error($"Failed write schedule json: {_schedInstallJsonPath}");
+ return false;
+ }
+ catch (Exception e)
+ {
+ _logger.Error(e, $"Exception during schedule install update at: {filePath}");
+ CancelScheduleInstallUpdate();
+ return false;
+ }
+ }
+ _logger.Error($"No schedule update package: {filePath}");
+ return false;
+ }
+
+ public bool CancelScheduleInstallUpdate()
+ {
+ _updateRepository.SetCurrentVersion(_currentVersion);
+ if (File.Exists(_schedInstallJsonPath))
+ FileUtils.DeleteFileNoThrow(_schedInstallJsonPath);
+ return File.Exists(_schedInstallArchivePath) &&
+ FileUtils.DeleteFileNoThrow(_schedInstallArchivePath);
+ }
+
+ public void RemoveUpdateScript()
+ {
+ if (File.Exists(_updateScriptPath))
+ {
+ FileUtils.DeleteFileNoThrow(_updateScriptPath);
+ }
+ }
+
+ private bool ExtractUpdateScript()
+ {
+ try
+ {
+ File.WriteAllText(_updateScriptPath, _updateScriptContent);
+ }
+ catch (Exception e)
+ {
+ _logger.Error(e, $"Failed extract update script to: {_updateScriptPath}");
+ return false;
+ }
+ return true;
+ }
+
+ private bool ExtractReadyInstallUpdate()
+ {
+ var installUnpackedDir = new DirectoryInfo(_installUnpackedDir);
+ var extractTempDir = new DirectoryInfo(Path.Combine(_updatesStoragePath, "temp_" + Path.GetRandomFileName()));
+ try
+ {
+ if (installUnpackedDir.Exists && !FileUtils.DeleteDirectoryNoThrow(installUnpackedDir, true))
+ {
+ _logger.Error($"Already exist extract directory can't be removed: {_installUnpackedDir}");
+ return false;
+ }
+
+ Directory.CreateDirectory(_installUnpackedDir);
+ File.Move(_schedInstallExecutablePath, _installUnpackedExecutablePath);
+ }
+ catch (Exception e)
+ {
+ _logger.Error(e, $"Failed extract update package to: {_installUnpackedDir}");
+ if (extractTempDir.Exists)
+ FileUtils.DeleteDirectoryNoThrow(extractTempDir, true);
+ if (installUnpackedDir.Exists)
+ FileUtils.DeleteDirectoryNoThrow(installUnpackedDir, true);
+ return false;
+ }
+ return true;
+ }
+ }
+}
diff --git a/SCTools/SCTool_Redesigned/Update/CustomPackageVerifier.cs b/SCTools/SCTool_Redesigned/Update/CustomPackageVerifier.cs
index 98898aa..bf12c92 100644
--- a/SCTools/SCTool_Redesigned/Update/CustomPackageVerifier.cs
+++ b/SCTools/SCTool_Redesigned/Update/CustomPackageVerifier.cs
@@ -4,7 +4,7 @@
namespace SCTool_Redesigned.Update
{
- internal class CustomPackageVerifier : ApplicationUpdater.IPackageVerifier
+ internal class CustomPackageVerifier : CustomApplicationUpdater.IPackageVerifier
{
private string ExecutorName = Assembly.GetExecutingAssembly().GetName().Name;