mirror of
https://git.eden-emu.dev/archive/citron
synced 2026-03-23 01:56:08 -04:00
fix: Auto Updater
This commit is contained in:
@@ -3,123 +3,93 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include <QObject>
|
||||
#include <string>
|
||||
#include <filesystem>
|
||||
#include <thread>
|
||||
#include <atomic>
|
||||
#include <QObject>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkReply>
|
||||
#include <QNetworkRequest>
|
||||
#include <QProgressDialog>
|
||||
#include <QMessageBox>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
// Forward declare to keep headers clean
|
||||
class QNetworkAccessManager;
|
||||
|
||||
namespace Updater {
|
||||
|
||||
struct UpdateInfo {
|
||||
std::string version;
|
||||
std::string download_url;
|
||||
std::string changelog;
|
||||
std::string release_date;
|
||||
bool is_newer_version = false;
|
||||
};
|
||||
|
||||
class UpdaterService : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum class UpdateResult {
|
||||
Success,
|
||||
Failed,
|
||||
Cancelled,
|
||||
NetworkError,
|
||||
ExtractionError,
|
||||
PermissionError,
|
||||
InvalidArchive,
|
||||
NoUpdateAvailable
|
||||
struct DownloadOption {
|
||||
std::string name;
|
||||
std::string url;
|
||||
};
|
||||
|
||||
explicit UpdaterService(QObject* parent = nullptr);
|
||||
~UpdaterService() override;
|
||||
struct UpdateInfo {
|
||||
std::string version;
|
||||
std::vector<DownloadOption> download_options; // Used for both Windows .zip and Linux .AppImage
|
||||
std::string changelog;
|
||||
std::string release_date;
|
||||
bool is_newer_version = false;
|
||||
};
|
||||
|
||||
// Check for updates from the configured URL
|
||||
void CheckForUpdates(const std::string& update_url);
|
||||
class UpdaterService : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
// Download and install update
|
||||
void DownloadAndInstallUpdate(const UpdateInfo& update_info);
|
||||
public:
|
||||
enum class UpdateResult { Success, Failed, Cancelled, NetworkError, ExtractionError, PermissionError, InvalidArchive, NoUpdateAvailable };
|
||||
|
||||
// Cancel current operation
|
||||
void CancelUpdate();
|
||||
explicit UpdaterService(QObject* parent = nullptr);
|
||||
~UpdaterService() override;
|
||||
|
||||
// Get current application version
|
||||
std::string GetCurrentVersion() const;
|
||||
void CheckForUpdates(const std::string& update_url);
|
||||
void DownloadAndInstallUpdate(const std::string& download_url);
|
||||
void CancelUpdate();
|
||||
std::string GetCurrentVersion() const;
|
||||
bool IsUpdateInProgress() const;
|
||||
|
||||
// Check if update is in progress
|
||||
bool IsUpdateInProgress() const;
|
||||
static bool HasStagedUpdate(const std::filesystem::path& app_directory);
|
||||
static bool ApplyStagedUpdate(const std::filesystem::path& app_directory);
|
||||
|
||||
// Static methods for startup update handling
|
||||
static bool HasStagedUpdate(const std::filesystem::path& app_directory);
|
||||
static bool ApplyStagedUpdate(const std::filesystem::path& app_directory);
|
||||
signals:
|
||||
void UpdateCheckCompleted(bool has_update, const UpdateInfo& update_info);
|
||||
void UpdateDownloadProgress(int percentage, qint64 bytes_received, qint64 bytes_total);
|
||||
void UpdateInstallProgress(int percentage, const QString& current_file);
|
||||
void UpdateCompleted(UpdateResult result, const QString& message);
|
||||
void UpdateError(const QString& error_message);
|
||||
|
||||
signals:
|
||||
void UpdateCheckCompleted(bool has_update, const UpdateInfo& update_info);
|
||||
void UpdateDownloadProgress(int percentage, qint64 bytes_received, qint64 bytes_total);
|
||||
void UpdateInstallProgress(int percentage, const QString& current_file);
|
||||
void UpdateCompleted(UpdateResult result, const QString& message);
|
||||
void UpdateError(const QString& error_message);
|
||||
private slots:
|
||||
void OnDownloadFinished();
|
||||
void OnDownloadProgress(qint64 bytes_received, qint64 bytes_total);
|
||||
void OnDownloadError(QNetworkReply::NetworkError error);
|
||||
|
||||
private slots:
|
||||
void OnDownloadFinished();
|
||||
void OnDownloadProgress(qint64 bytes_received, qint64 bytes_total);
|
||||
void OnDownloadError(QNetworkReply::NetworkError error);
|
||||
private:
|
||||
void InitializeSSL();
|
||||
void ConfigureSSLForRequest(QNetworkRequest& request);
|
||||
void ParseUpdateResponse(const QByteArray& response);
|
||||
bool CompareVersions(const std::string& current, const std::string& latest) const;
|
||||
|
||||
private:
|
||||
// Network operations
|
||||
void ParseUpdateResponse(const QByteArray& response);
|
||||
bool CompareVersions(const std::string& current, const std::string& latest) const;
|
||||
#ifdef _WIN32
|
||||
bool ExtractArchive(const std::filesystem::path& archive_path, const std::filesystem::path& extract_path);
|
||||
#ifndef CITRON_ENABLE_LIBARCHIVE
|
||||
bool ExtractArchiveWindows(const std::filesystem::path& archive_path, const std::filesystem::path& extract_path);
|
||||
#endif
|
||||
bool InstallUpdate(const std::filesystem::path& update_path);
|
||||
bool CreateBackup();
|
||||
bool RestoreBackup();
|
||||
#endif
|
||||
bool CleanupFiles();
|
||||
std::filesystem::path GetTempDirectory() const;
|
||||
std::filesystem::path GetApplicationDirectory() const;
|
||||
std::filesystem::path GetBackupDirectory() const;
|
||||
bool EnsureDirectoryExists(const std::filesystem::path& path) const;
|
||||
|
||||
// SSL configuration
|
||||
void InitializeSSL();
|
||||
void ConfigureSSLForRequest(QNetworkRequest& request);
|
||||
std::unique_ptr<QNetworkAccessManager> network_manager;
|
||||
QNetworkReply* current_reply = nullptr;
|
||||
std::atomic<bool> update_in_progress{false};
|
||||
std::atomic<bool> cancel_requested{false};
|
||||
UpdateInfo current_update_info;
|
||||
std::filesystem::path app_directory;
|
||||
std::filesystem::path temp_download_path;
|
||||
std::filesystem::path backup_path;
|
||||
|
||||
// File operations
|
||||
bool ExtractArchive(const std::filesystem::path& archive_path, const std::filesystem::path& extract_path);
|
||||
#if defined(_WIN32) && !defined(CITRON_ENABLE_LIBARCHIVE)
|
||||
bool ExtractArchiveWindows(const std::filesystem::path& archive_path, const std::filesystem::path& extract_path);
|
||||
#endif
|
||||
bool InstallUpdate(const std::filesystem::path& update_path);
|
||||
bool CreateBackup();
|
||||
bool RestoreBackup();
|
||||
bool CleanupFiles();
|
||||
static constexpr const char* CITRON_VERSION_FILE = "version.txt";
|
||||
static constexpr const char* BACKUP_DIRECTORY = "backup";
|
||||
};
|
||||
|
||||
// Helper functions
|
||||
std::filesystem::path GetTempDirectory() const;
|
||||
std::filesystem::path GetApplicationDirectory() const;
|
||||
std::filesystem::path GetBackupDirectory() const;
|
||||
bool EnsureDirectoryExists(const std::filesystem::path& path) const;
|
||||
|
||||
// Network components
|
||||
std::unique_ptr<QNetworkAccessManager> network_manager;
|
||||
QNetworkReply* current_reply = nullptr;
|
||||
|
||||
// Update state
|
||||
std::atomic<bool> update_in_progress{false};
|
||||
std::atomic<bool> cancel_requested{false};
|
||||
UpdateInfo current_update_info;
|
||||
|
||||
// File paths
|
||||
std::filesystem::path temp_download_path;
|
||||
std::filesystem::path backup_path;
|
||||
std::filesystem::path app_directory;
|
||||
|
||||
// Constants
|
||||
static constexpr const char* CITRON_VERSION_FILE = "version.txt";
|
||||
static constexpr const char* UPDATE_MANIFEST_FILE = "update_manifest.json";
|
||||
static constexpr const char* BACKUP_DIRECTORY = "backup";
|
||||
static constexpr const char* TEMP_DIRECTORY = "temp";
|
||||
static constexpr size_t MAX_DOWNLOAD_SIZE = 500 * 1024 * 1024; // 500MB limit
|
||||
};
|
||||
|
||||
} // namespace Updater
|
||||
} // namespace Updater
|
||||
|
||||
Reference in New Issue
Block a user