mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-04-21 20:14:45 +00:00
Updater
This commit is contained in:
parent
b911c70d35
commit
875363a8da
9 changed files with 428 additions and 15 deletions
80
.github/workflows/windows-qt.yml
vendored
80
.github/workflows/windows-qt.yml
vendored
|
@ -11,15 +11,18 @@ on:
|
|||
|
||||
env:
|
||||
BUILD_TYPE: Release
|
||||
TARGET_REPO: "DanielSvoboda/teste"
|
||||
SHADPS4_TOKEN: ${{ secrets.SHADPS4_TOKEN }}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: windows-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
submodules: recursive
|
||||
|
||||
- name: Setup Qt
|
||||
uses: jurplel/install-qt-action@v4
|
||||
|
@ -33,35 +36,86 @@ jobs:
|
|||
- name: Cache CMake dependency source code
|
||||
uses: actions/cache@v4
|
||||
env:
|
||||
cache-name: ${{ runner.os }}-qt-cache-cmake-dependency-sources
|
||||
cache-name: ${{ runner.os }}-qt-cache-cmake-dependency-sources
|
||||
with:
|
||||
path: |
|
||||
${{github.workspace}}/build
|
||||
key: ${{ env.cache-name }}-${{ hashFiles('**/CMakeLists.txt', 'cmake/**') }}
|
||||
restore-keys: |
|
||||
${{ env.cache-name }}-
|
||||
path: |
|
||||
${{ github.workspace }}/build
|
||||
key: ${{ env.cache-name }}-${{ hashFiles('**/CMakeLists.txt', 'cmake/**') }}
|
||||
restore-keys: |
|
||||
${{ env.cache-name }}-
|
||||
|
||||
- name: Configure CMake
|
||||
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -T ClangCL -DENABLE_QT_GUI=ON
|
||||
run: cmake -B ${{ github.workspace }}/build -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} -T ClangCL -DENABLE_QT_GUI=ON
|
||||
|
||||
- name: Build
|
||||
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel
|
||||
run: cmake --build ${{ github.workspace }}/build --config ${{ env.BUILD_TYPE }} --parallel
|
||||
|
||||
- name: Deploy
|
||||
run: |
|
||||
mkdir upload
|
||||
move build/Release/shadPS4.exe upload
|
||||
windeployqt --dir upload upload/shadPS4.exe
|
||||
|
||||
|
||||
- name: Get date and git hash
|
||||
id: vars
|
||||
shell: pwsh
|
||||
run: |
|
||||
echo "date=$(Get-Date -Format 'yyyy-MM-dd')" >> $env:GITHUB_OUTPUT
|
||||
echo "shorthash=$(git rev-parse --short HEAD)" >> $env:GITHUB_OUTPUT
|
||||
$date = Get-Date -Format 'yyyy-MM-dd'
|
||||
$shorthash = git rev-parse --short HEAD
|
||||
echo "date=$date" >> $env:GITHUB_ENV
|
||||
echo "shorthash=$shorthash" >> $env:GITHUB_ENV
|
||||
|
||||
- name: Create Zip Archive
|
||||
if: github.event_name == 'push'
|
||||
run: |
|
||||
$zipName = "shadPS4-win64-qt-$($env:date)-$($env:shorthash).zip"
|
||||
Compress-Archive -Path upload/* -DestinationPath $zipName
|
||||
echo "zipName=$zipName" >> $env:GITHUB_ENV
|
||||
|
||||
- name: Upload executable
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: shadps4-win64-qt-${{ steps.vars.outputs.date }}-${{ steps.vars.outputs.shorthash }}
|
||||
path: upload
|
||||
|
||||
- name: Upload Zip Archive
|
||||
if: github.event_name == 'push'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ env.zipName }}
|
||||
path: ${{ env.zipName }}
|
||||
|
||||
- name: Create GitHub Release
|
||||
if: github.event_name == 'push'
|
||||
id: create_release
|
||||
shell: pwsh
|
||||
run: |
|
||||
$date = $env:date
|
||||
$shorthash = $env:shorthash
|
||||
$uri = "https://api.github.com/repos/${{ env.TARGET_REPO }}/releases"
|
||||
$headers = @{
|
||||
"Authorization" = "token $($env:SHADPS4_TOKEN)"
|
||||
"Accept" = "application/vnd.github.v3+json"
|
||||
}
|
||||
$body = @{
|
||||
"tag_name" = "build-$date-$shorthash"
|
||||
"name" = "shadPS4-win64-qt-$($env:date)-$($env:shorthash)"
|
||||
"draft" = $false
|
||||
"prerelease" = $false
|
||||
} | ConvertTo-Json
|
||||
|
||||
$response = Invoke-RestMethod -Uri $uri -Method Post -Headers $headers -Body $body -ContentType "application/json"
|
||||
$response.id | Out-File -FilePath release_id.txt
|
||||
|
||||
- name: Upload to GitHub Release
|
||||
if: github.event_name == 'push'
|
||||
shell: pwsh
|
||||
run: |
|
||||
$release_id = Get-Content release_id.txt
|
||||
$filePath = $env:zipName
|
||||
$url = "https://uploads.github.com/repos/${{ env.TARGET_REPO }}/releases/$release_id/assets?name=$filePath"
|
||||
Write-Output "Uploading $filePath to $url"
|
||||
Invoke-RestMethod -Uri $url -Method Post -Headers @{
|
||||
"Authorization" = "token $($env:SHADPS4_TOKEN)"
|
||||
"Content-Type" = "application/octet-stream"
|
||||
} -InFile $filePath
|
|
@ -628,6 +628,8 @@ set(QT_GUI src/qt_gui/about_dialog.cpp
|
|||
src/qt_gui/about_dialog.ui
|
||||
src/qt_gui/cheats_patches.cpp
|
||||
src/qt_gui/cheats_patches.h
|
||||
src/qt_gui/checkUpdate.cpp
|
||||
src/qt_gui/checkUpdate.h
|
||||
src/qt_gui/memory_patcher.cpp
|
||||
src/qt_gui/memory_patcher.h
|
||||
src/qt_gui/main_window_ui.h
|
||||
|
|
|
@ -21,6 +21,7 @@ static bool useSpecialPad = false;
|
|||
static int specialPadClass = 1;
|
||||
static bool isDebugDump = false;
|
||||
static bool isShowSplash = false;
|
||||
static bool isAutoUpdate = true;
|
||||
static bool isNullGpu = false;
|
||||
static bool shouldCopyGPUBuffers = false;
|
||||
static bool shouldDumpShaders = false;
|
||||
|
@ -102,6 +103,10 @@ bool showSplash() {
|
|||
return isShowSplash;
|
||||
}
|
||||
|
||||
bool autoUpdate() {
|
||||
return isAutoUpdate;
|
||||
}
|
||||
|
||||
bool nullGpu() {
|
||||
return isNullGpu;
|
||||
}
|
||||
|
@ -170,6 +175,10 @@ void setShowSplash(bool enable) {
|
|||
isShowSplash = enable;
|
||||
}
|
||||
|
||||
void setAutoUpdate(bool enable) {
|
||||
isAutoUpdate = enable;
|
||||
}
|
||||
|
||||
void setNullGpu(bool enable) {
|
||||
isNullGpu = enable;
|
||||
}
|
||||
|
@ -365,6 +374,7 @@ void load(const std::filesystem::path& path) {
|
|||
logType = toml::find_or<std::string>(general, "logType", "sync");
|
||||
userName = toml::find_or<std::string>(general, "userName", "shadPS4");
|
||||
isShowSplash = toml::find_or<bool>(general, "showSplash", true);
|
||||
isAutoUpdate = toml::find_or<bool>(general, "autoUpdate", true);
|
||||
}
|
||||
|
||||
if (data.contains("Input")) {
|
||||
|
@ -457,6 +467,7 @@ void save(const std::filesystem::path& path) {
|
|||
data["General"]["logType"] = logType;
|
||||
data["General"]["userName"] = userName;
|
||||
data["General"]["showSplash"] = isShowSplash;
|
||||
data["General"]["autoUpdate"] = isAutoUpdate;
|
||||
data["Input"]["useSpecialPad"] = useSpecialPad;
|
||||
data["Input"]["specialPadClass"] = specialPadClass;
|
||||
data["GPU"]["screenWidth"] = screenWidth;
|
||||
|
@ -511,6 +522,7 @@ void setDefaultValues() {
|
|||
specialPadClass = 1;
|
||||
isDebugDump = false;
|
||||
isShowSplash = false;
|
||||
isAutoUpdate = true;
|
||||
isNullGpu = false;
|
||||
shouldDumpShaders = false;
|
||||
shouldDumpPM4 = false;
|
||||
|
@ -526,4 +538,4 @@ void setDefaultValues() {
|
|||
gpuId = -1;
|
||||
}
|
||||
|
||||
} // namespace Config
|
||||
} // namespace Config
|
|
@ -26,6 +26,7 @@ s32 getGpuId();
|
|||
|
||||
bool debugDump();
|
||||
bool showSplash();
|
||||
bool autoUpdate();
|
||||
bool nullGpu();
|
||||
bool copyGPUCmdBuffers();
|
||||
bool dumpShaders();
|
||||
|
@ -35,6 +36,7 @@ u32 vblankDiv();
|
|||
|
||||
void setDebugDump(bool enable);
|
||||
void setShowSplash(bool enable);
|
||||
void setAutoUpdate(bool enable);
|
||||
void setNullGpu(bool enable);
|
||||
void setCopyGPUCmdBuffers(bool enable);
|
||||
void setDumpShaders(bool enable);
|
||||
|
|
289
src/qt_gui/checkUpdate.cpp
Normal file
289
src/qt_gui/checkUpdate.cpp
Normal file
|
@ -0,0 +1,289 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QLabel>
|
||||
#include <QMessageBox>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkReply>
|
||||
#include <QPushButton>
|
||||
#include <QString>
|
||||
#include <QVBoxLayout>
|
||||
#include <common/config.h>
|
||||
#include <common/path_util.h>
|
||||
#include <common/scm_rev.h>
|
||||
#include "checkUpdate.h"
|
||||
//#include "externals/minizip-ng/mz.h"
|
||||
//#include "externals/minizip-ng/mz_strm.h"
|
||||
//#include "externals/minizip-ng/mz_strm_buf.h"
|
||||
//#include "externals/minizip-ng/mz_strm_mem.h"
|
||||
//#include "externals/minizip-ng/mz_strm_os.h"
|
||||
//#include "externals/minizip-ng/mz_zip.h"
|
||||
|
||||
using namespace Common::FS;
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
CheckUpdate::CheckUpdate(QWidget* parent) : QDialog(parent) {
|
||||
setWindowTitle("Update Check");
|
||||
CheckForUpdates();
|
||||
}
|
||||
|
||||
void CheckUpdate::CheckForUpdates() {
|
||||
QNetworkAccessManager* manager = new QNetworkAccessManager(this);
|
||||
QNetworkRequest request(
|
||||
QUrl("https://api.github.com/repos/DanielSvoboda/teste/releases/latest"));
|
||||
QNetworkReply* reply = manager->get(request);
|
||||
|
||||
connect(reply, &QNetworkReply::finished, this, [this, reply]() {
|
||||
if (reply->error() != QNetworkReply::NoError) {
|
||||
QMessageBox::warning(this, tr("Error"),
|
||||
QString(tr("Network error: ") + "\n%1").arg(reply->errorString()));
|
||||
reply->deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
QByteArray response = reply->readAll();
|
||||
QJsonDocument jsonDoc(QJsonDocument::fromJson(response));
|
||||
QJsonObject jsonObj = jsonDoc.object();
|
||||
|
||||
QString downloadUrl =
|
||||
jsonObj["assets"].toArray().first().toObject()["browser_download_url"].toString();
|
||||
QString latestVersion = QFileInfo(downloadUrl).baseName();
|
||||
QString latestRev = latestVersion.right(7);
|
||||
|
||||
QString currentRev = QString::fromStdString(Common::g_scm_rev).left(7);
|
||||
|
||||
if (latestRev == currentRev) {
|
||||
setupUI_NoUpdate();
|
||||
} else {
|
||||
updateDownloadUrl = downloadUrl;
|
||||
setupUI_UpdateAvailable(downloadUrl);
|
||||
}
|
||||
|
||||
reply->deleteLater();
|
||||
});
|
||||
}
|
||||
|
||||
void CheckUpdate::setupUI_NoUpdate() {
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
|
||||
QLabel* noUpdateLabel = new QLabel("Your version is already up to date!.", this);
|
||||
layout->addWidget(noUpdateLabel);
|
||||
|
||||
autoUpdateCheckBox = new QCheckBox("Auto Update", this);
|
||||
layout->addWidget(autoUpdateCheckBox);
|
||||
|
||||
autoUpdateCheckBox->setChecked(Config::autoUpdate());
|
||||
|
||||
connect(autoUpdateCheckBox, &QCheckBox::stateChanged, this, [](int state) {
|
||||
const auto user_dir = Common::FS::GetUserPath(Common::FS::PathType::UserDir);
|
||||
Config::setAutoUpdate(state == Qt::Checked);
|
||||
Config::save(user_dir / "config.toml");
|
||||
});
|
||||
|
||||
setLayout(layout);
|
||||
}
|
||||
|
||||
void CheckUpdate::setupUI_UpdateAvailable(const QString& downloadUrl) {
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
|
||||
QLabel* updateLabel =
|
||||
new QLabel("An update is available!\nDo you want to download and install it?", this);
|
||||
updateLabel->setAlignment(Qt::AlignCenter);
|
||||
layout->addWidget(updateLabel);
|
||||
|
||||
// Criar um layout horizontal para os botões
|
||||
QHBoxLayout* buttonLayout = new QHBoxLayout();
|
||||
|
||||
yesButton = new QPushButton("Yes", this);
|
||||
noButton = new QPushButton("No", this);
|
||||
|
||||
// Adicionar os botões ao layout horizontal
|
||||
buttonLayout->addWidget(yesButton);
|
||||
buttonLayout->addWidget(noButton);
|
||||
|
||||
// Adicionar o layout horizontal ao layout principal
|
||||
layout->addLayout(buttonLayout);
|
||||
|
||||
connect(yesButton, &QPushButton::clicked, this,
|
||||
[this]() { DownloadAndInstallUpdate(updateDownloadUrl); });
|
||||
|
||||
connect(noButton, &QPushButton::clicked, this, [this]() { close(); });
|
||||
|
||||
autoUpdateCheckBox = new QCheckBox("Auto Update (Check at Startup)", this);
|
||||
layout->addWidget(autoUpdateCheckBox);
|
||||
|
||||
autoUpdateCheckBox->setChecked(Config::autoUpdate());
|
||||
|
||||
connect(autoUpdateCheckBox, &QCheckBox::stateChanged, this, [](int state) {
|
||||
const auto user_dir = Common::FS::GetUserPath(Common::FS::PathType::UserDir);
|
||||
Config::setAutoUpdate(state == Qt::Checked);
|
||||
Config::save(user_dir / "config.toml");
|
||||
});
|
||||
|
||||
setLayout(layout);
|
||||
}
|
||||
|
||||
void CheckUpdate::DownloadAndInstallUpdate(const QString& url) {
|
||||
QNetworkAccessManager* manager = new QNetworkAccessManager(this);
|
||||
QNetworkRequest request(url);
|
||||
QNetworkReply* reply = manager->get(request);
|
||||
|
||||
connect(reply, &QNetworkReply::finished, this, [this, reply]() {
|
||||
if (reply->error() != QNetworkReply::NoError) {
|
||||
QMessageBox::warning(this, tr("Error"),
|
||||
QString(tr("Network error: ") + "\n%1").arg(reply->errorString()));
|
||||
reply->deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
QString userPath =
|
||||
QString::fromStdString(Common::FS::GetUserPath(Common::FS::PathType::UserDir).string());
|
||||
QString tempDownloadPath = userPath + "/temp_download_update";
|
||||
QDir dir(tempDownloadPath);
|
||||
if (!dir.exists()) {
|
||||
dir.mkpath(".");
|
||||
}
|
||||
|
||||
QString downloadPath = tempDownloadPath + "/temp_download_update.zip";
|
||||
QFile file(downloadPath);
|
||||
if (file.open(QIODevice::WriteOnly)) {
|
||||
file.write(reply->readAll());
|
||||
file.close();
|
||||
QMessageBox::information(this, tr("Download Complete"),
|
||||
tr("The update has been downloaded. Starting installation."));
|
||||
Unzip();
|
||||
} else {
|
||||
QMessageBox::warning(
|
||||
this, tr("Error"),
|
||||
QString(tr("Failed to save the update file at") + "\n%1").arg(downloadPath));
|
||||
}
|
||||
|
||||
reply->deleteLater();
|
||||
});
|
||||
}
|
||||
|
||||
void CheckUpdate::Unzip() {
|
||||
//QString userPath =
|
||||
// QString::fromStdString(Common::FS::GetUserPath(Common::FS::PathType::UserDir).string());
|
||||
//QString tempDirPath = userPath + "/temp_download_update";
|
||||
//QString zipFilePath = tempDirPath + "/temp_download_update.zip";
|
||||
|
||||
//if (!fs::exists(zipFilePath.toStdString())) {
|
||||
// QMessageBox::warning(this, tr("Error"),
|
||||
// QString(tr("Arquivo zip não encontrado:") + "\n%1").arg(zipFilePath));
|
||||
// return;
|
||||
//}
|
||||
|
||||
//void* zip_reader = NULL;
|
||||
//void* stream = NULL;
|
||||
|
||||
//mz_stream_os_create();
|
||||
//if (mz_stream_os_open(stream, zipFilePath.toStdString().c_str(), MZ_OPEN_MODE_READ) != MZ_OK) {
|
||||
|
||||
// QMessageBox::warning(this, tr("Error"),
|
||||
// QString(tr("Erro ao abrir o arquivo zip") + "\n%1").arg(zipFilePath));
|
||||
// mz_stream_os_delete(&stream);
|
||||
// return;
|
||||
//}
|
||||
|
||||
//// Criar o leitor do ZIP
|
||||
//mz_zip_create();
|
||||
//if (mz_zip_open(zip_reader, stream, MZ_OPEN_MODE_READ) != MZ_OK) {
|
||||
|
||||
// QMessageBox::warning(
|
||||
// this, tr("Error"),
|
||||
// QString(tr("Erro ao abrir o arquivo zip com mz_zip_open") + "\n%1").arg(zipFilePath));
|
||||
|
||||
// mz_zip_delete(&zip_reader);
|
||||
// mz_stream_os_delete(&stream);
|
||||
// return;
|
||||
//}
|
||||
|
||||
//// Passa por (arquivo ou diretório) no arquivo zip
|
||||
//while (mz_zip_goto_next_entry(zip_reader) == MZ_OK) {
|
||||
// mz_zip_file* file_info = nullptr;
|
||||
// if (mz_zip_entry_get_info(zip_reader, &file_info) != MZ_OK) {
|
||||
// QMessageBox::warning(
|
||||
// this, tr("Error"),
|
||||
// QString(tr("Erro ao obter informações da entrada no zip.") + "\n%1")
|
||||
// .arg(zipFilePath));
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// QString caminho_arquivo = tempDirPath + "/" + file_info->filename;
|
||||
|
||||
// // Verifique se a entrada do zip é um diretório
|
||||
// if (mz_zip_entry_is_dir(zip_reader) == MZ_OK) {
|
||||
// fs::create_directories(caminho_arquivo.toStdString());
|
||||
// QMessageBox::warning(this, tr("Error"),
|
||||
// QString(tr("Diretório criado:") + "\n%1").arg(caminho_arquivo));
|
||||
// } else {
|
||||
// // Certifique-se de que o diretório pai do arquivo exista
|
||||
// fs::create_directories(fs::path(caminho_arquivo.toStdString()).parent_path());
|
||||
|
||||
// // Abra o arquivo de saída para gravação
|
||||
// std::ofstream arquivo_saida(caminho_arquivo.toStdString(), std::ios::binary);
|
||||
// if (!arquivo_saida) {
|
||||
|
||||
// QMessageBox::warning(
|
||||
// this, tr("Error"),
|
||||
// QString(tr("Erro ao abrir o arquivo de saída:") + "\n%1").arg(caminho_arquivo));
|
||||
|
||||
// mz_zip_entry_close(zip_reader);
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// // Buffer temporário para leitura dos dados
|
||||
// char buffer[4096];
|
||||
// int32_t bytes_lidos;
|
||||
|
||||
// // Leia os dados do arquivo zip e escreva no arquivo de saída
|
||||
// while ((bytes_lidos = mz_zip_entry_read(zip_reader, buffer, sizeof(buffer))) > 0) {
|
||||
// arquivo_saida.write(buffer, bytes_lidos);
|
||||
// }
|
||||
// arquivo_saida.close();
|
||||
// QMessageBox::warning(this, tr("Error"),
|
||||
// QString(tr("Arquivo extraído:") + "\n%1").arg(caminho_arquivo));
|
||||
// }
|
||||
// mz_zip_entry_close(zip_reader);
|
||||
//}
|
||||
|
||||
//// Fechar o arquivo zip
|
||||
//mz_zip_close(zip_reader);
|
||||
//mz_zip_delete(&zip_reader);
|
||||
//mz_stream_os_close(stream);
|
||||
//mz_stream_os_delete(&stream);
|
||||
|
||||
//QMessageBox::warning(this, tr("Error"),
|
||||
// QString(tr("Descompactação concluída em:") + "\n%1").arg(tempDirPath));
|
||||
}
|
||||
|
||||
//// Criar e executar o arquivo batch para atualizar
|
||||
// QFile batFile(tempDirPath + "/update.bat");
|
||||
// if (batFile.open(QIODevice::WriteOnly)) {
|
||||
// QTextStream out(&batFile);
|
||||
// out << "@echo off\n";
|
||||
// out << "taskkill /IM shadps4.exe /F\n";
|
||||
// out << "move /Y \"" << tempDirPath << "\\*\" \"" << userPath << "\"\n";
|
||||
// out << "start \"\" \"" << userPath << "\\shadps4.exe\"\n";
|
||||
// batFile.close();
|
||||
|
||||
// if (!QProcess::startDetached(batFile.fileName())) {
|
||||
// QMessageBox::warning(
|
||||
// this, tr("Error"),
|
||||
// tr("Failed to start the update batch file:\n%1").arg(batFile.fileName()));
|
||||
// }
|
||||
//} else {
|
||||
// QMessageBox::warning(
|
||||
// this, tr("Error"),
|
||||
// tr("Failed to create the update batch file:\n%1").arg(batFile.fileName()));
|
||||
//}
|
31
src/qt_gui/checkUpdate.h
Normal file
31
src/qt_gui/checkUpdate.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#ifndef CHECKUPDATE_H
|
||||
#define CHECKUPDATE_H
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QDialog>
|
||||
|
||||
class CheckUpdate : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit CheckUpdate(QWidget* parent = nullptr);
|
||||
|
||||
private slots:
|
||||
void CheckForUpdates();
|
||||
void DownloadAndInstallUpdate(const QString& url);
|
||||
void Unzip();
|
||||
|
||||
private:
|
||||
void setupUI_NoUpdate();
|
||||
void setupUI_UpdateAvailable(const QString& downloadUrl);
|
||||
|
||||
QCheckBox* autoUpdateCheckBox;
|
||||
QPushButton* yesButton;
|
||||
QPushButton* noButton;
|
||||
QString updateDownloadUrl;
|
||||
};
|
||||
|
||||
#endif // CHECKUPDATE_H
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include "about_dialog.h"
|
||||
#include "cheats_patches.h"
|
||||
#include "checkUpdate.h"
|
||||
#include "common/io_file.h"
|
||||
#include "common/string_util.h"
|
||||
#include "common/version.h"
|
||||
|
@ -46,6 +47,7 @@ bool MainWindow::Init() {
|
|||
this->show();
|
||||
// load game list
|
||||
LoadGameLists();
|
||||
CheckUpdateMain(true);
|
||||
|
||||
auto end = std::chrono::steady_clock::now();
|
||||
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
|
||||
|
@ -160,6 +162,18 @@ void MainWindow::LoadGameLists() {
|
|||
}
|
||||
}
|
||||
|
||||
void MainWindow::CheckUpdateMain(bool check) {
|
||||
#ifdef _WIN64
|
||||
if (check) {
|
||||
if (!Config::autoUpdate()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
auto checkUpdate = new CheckUpdate(this);
|
||||
checkUpdate->show();
|
||||
#endif
|
||||
}
|
||||
|
||||
void MainWindow::GetPhysicalDevices() {
|
||||
Vulkan::Instance instance(false, false);
|
||||
auto physical_devices = instance.GetPhysicalDevices();
|
||||
|
@ -221,6 +235,8 @@ void MainWindow::CreateConnects() {
|
|||
settingsDialog->exec();
|
||||
});
|
||||
|
||||
connect(ui->updaterAct, &QAction::triggered, this, [this]() { CheckUpdateMain(false); });
|
||||
|
||||
connect(ui->aboutAct, &QAction::triggered, this, [this]() {
|
||||
auto aboutDialog = new AboutDialog(this);
|
||||
aboutDialog->exec();
|
||||
|
@ -845,6 +861,7 @@ void MainWindow::SetUiIcons(bool isWhite) {
|
|||
ui->bootInstallPkgAct->setIcon(RecolorIcon(ui->bootInstallPkgAct->icon(), isWhite));
|
||||
ui->bootGameAct->setIcon(RecolorIcon(ui->bootGameAct->icon(), isWhite));
|
||||
ui->exitAct->setIcon(RecolorIcon(ui->exitAct->icon(), isWhite));
|
||||
ui->updaterAct->setIcon(RecolorIcon(ui->updaterAct->icon(), isWhite));
|
||||
ui->aboutAct->setIcon(RecolorIcon(ui->aboutAct->icon(), isWhite));
|
||||
ui->setlistModeListAct->setIcon(RecolorIcon(ui->setlistModeListAct->icon(), isWhite));
|
||||
ui->setlistModeGridAct->setIcon(RecolorIcon(ui->setlistModeGridAct->icon(), isWhite));
|
||||
|
@ -949,4 +966,4 @@ void MainWindow::OnLanguageChanged(const std::string& locale) {
|
|||
Config::setEmulatorLanguage(locale);
|
||||
|
||||
LoadTranslation();
|
||||
}
|
||||
}
|
|
@ -54,6 +54,7 @@ private:
|
|||
void CreateDockWindows();
|
||||
void GetPhysicalDevices();
|
||||
void LoadGameLists();
|
||||
void CheckUpdateMain(bool check);
|
||||
void CreateConnects();
|
||||
void SetLastUsedTheme();
|
||||
void SetLastIconSizeBullet();
|
||||
|
|
|
@ -26,6 +26,7 @@ public:
|
|||
QAction* downloadCheatsPatchesAct;
|
||||
QAction* dumpGameListAct;
|
||||
QAction* pkgViewerAct;
|
||||
QAction* updaterAct;
|
||||
QAction* aboutAct;
|
||||
QAction* configureAct;
|
||||
QAction* setThemeDark;
|
||||
|
@ -127,6 +128,8 @@ public:
|
|||
pkgViewerAct = new QAction(MainWindow);
|
||||
pkgViewerAct->setObjectName("pkgViewer");
|
||||
pkgViewerAct->setIcon(QIcon(":images/file_icon.png"));
|
||||
updaterAct = new QAction(MainWindow);
|
||||
updaterAct->setObjectName("updaterAct");
|
||||
aboutAct = new QAction(MainWindow);
|
||||
aboutAct->setObjectName("aboutAct");
|
||||
aboutAct->setIcon(QIcon(":images/about_icon.png"));
|
||||
|
@ -285,6 +288,7 @@ public:
|
|||
menuUtils->addAction(downloadCheatsPatchesAct);
|
||||
menuUtils->addAction(dumpGameListAct);
|
||||
menuUtils->addAction(pkgViewerAct);
|
||||
menuAbout->addAction(updaterAct);
|
||||
menuAbout->addAction(aboutAct);
|
||||
|
||||
retranslateUi(MainWindow);
|
||||
|
@ -299,6 +303,7 @@ public:
|
|||
bootInstallPkgAct->setText(
|
||||
QCoreApplication::translate("MainWindow", "Install Packages (PKG)", nullptr));
|
||||
bootGameAct->setText(QCoreApplication::translate("MainWindow", "Boot Game", nullptr));
|
||||
updaterAct->setText(QCoreApplication::translate("MainWindow", "Check Update", nullptr));
|
||||
aboutAct->setText(QCoreApplication::translate("MainWindow", "About shadPS4", nullptr));
|
||||
configureAct->setText(QCoreApplication::translate("MainWindow", "Configure...", nullptr));
|
||||
#if QT_CONFIG(tooltip)
|
||||
|
|
Loading…
Add table
Reference in a new issue