mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-03 21:41:26 +12:00
update_manager: use v3 api for all OS
This commit is contained in:
parent
6123838a48
commit
50387cc516
5 changed files with 169 additions and 109 deletions
|
@ -61,15 +61,6 @@ DYNAMIC_IMPORT("ntdll.dll", NtSetTimerResolution, NTSTATUS(ULONG DesiredResoluti
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
#include <dispatch/dispatch.h>
|
#include <dispatch/dispatch.h>
|
||||||
#if defined (__x86_64__)
|
|
||||||
// sysinfo_darwin.mm
|
|
||||||
namespace Darwin_Version
|
|
||||||
{
|
|
||||||
extern int getNSmajorVersion();
|
|
||||||
extern int getNSminorVersion();
|
|
||||||
extern int getNSpatchVersion();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "Utilities/Config.h"
|
#include "Utilities/Config.h"
|
||||||
|
@ -618,12 +609,10 @@ int main(int argc, char** argv)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__APPLE__) && defined(__x86_64__)
|
#if defined(__APPLE__) && defined(__x86_64__)
|
||||||
const int osx_ver_major = Darwin_Version::getNSmajorVersion();
|
if (const utils::OS_version os = utils::get_OS_version();
|
||||||
const int osx_ver_minor = Darwin_Version::getNSminorVersion();
|
os.version_major == 14 && os.version_minor < 3 && (utils::get_cpu_brand().rfind("VirtualApple", 0) == 0))
|
||||||
if ((osx_ver_major == 14 && osx_ver_minor < 3) && (utils::get_cpu_brand().rfind("VirtualApple", 0) == 0))
|
|
||||||
{
|
{
|
||||||
const int osx_ver_patch = Darwin_Version::getNSpatchVersion();
|
report_fatal_error(fmt::format("RPCS3 requires macOS 14.3.0 or later.\nYou're currently using macOS %i.%i.%i.\nPlease update macOS from System Settings.\n\n", os.version_major, os.version_minor, os.version_patch));
|
||||||
report_fatal_error(fmt::format("RPCS3 requires macOS 14.3.0 or later.\nYou're currently using macOS %i.%i.%i.\nPlease update macOS from System Settings.\n\n", osx_ver_major, osx_ver_minor, osx_ver_patch));
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -659,7 +648,7 @@ int main(int argc, char** argv)
|
||||||
|
|
||||||
// Write OS version
|
// Write OS version
|
||||||
logs::stored_message os{sys_log.always()};
|
logs::stored_message os{sys_log.always()};
|
||||||
os.text = utils::get_OS_version();
|
os.text = utils::get_OS_version_string();
|
||||||
|
|
||||||
// Write Qt version
|
// Write Qt version
|
||||||
logs::stored_message qt{(strcmp(QT_VERSION_STR, qVersion()) != 0) ? sys_log.error : sys_log.notice};
|
logs::stored_message qt{(strcmp(QT_VERSION_STR, qVersion()) != 0) ? sys_log.error : sys_log.notice};
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "Crypto/utils.h"
|
#include "Crypto/utils.h"
|
||||||
#include "util/logs.hpp"
|
#include "util/logs.hpp"
|
||||||
#include "util/types.hpp"
|
#include "util/types.hpp"
|
||||||
|
#include "util/sysinfo.hpp"
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QCheckBox>
|
#include <QCheckBox>
|
||||||
|
@ -45,16 +46,6 @@
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
|
||||||
// sysinfo_darwin.mm
|
|
||||||
namespace Darwin_Version
|
|
||||||
{
|
|
||||||
extern int getNSmajorVersion();
|
|
||||||
extern int getNSminorVersion();
|
|
||||||
extern int getNSpatchVersion();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
LOG_CHANNEL(update_log, "UPDATER");
|
LOG_CHANNEL(update_log, "UPDATER");
|
||||||
|
|
||||||
update_manager::update_manager(QObject* parent, std::shared_ptr<gui_settings> gui_settings)
|
update_manager::update_manager(QObject* parent, std::shared_ptr<gui_settings> gui_settings)
|
||||||
|
@ -116,25 +107,10 @@ void update_manager::check_for_updates(bool automatic, bool check_only, bool aut
|
||||||
Q_EMIT signal_update_available(result_json && !m_update_message.isEmpty());
|
Q_EMIT signal_update_available(result_json && !m_update_message.isEmpty());
|
||||||
});
|
});
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
const utils::OS_version os = utils::get_OS_version();
|
||||||
const std::string url = fmt::format("https://update.rpcs3.net/"
|
|
||||||
"?api=v3"
|
const std::string url = fmt::format("https://update.rpcs3.net/?api=v3&c=%s&os_type=%s&os_arch=%s&os_version=%i.%i.%i",
|
||||||
"&c=%s"
|
rpcs3::get_commit_and_hash().second, os.type, os.arch, os.version_major, os.version_minor, os.version_patch);
|
||||||
"&os_type=macos"
|
|
||||||
"&os_arch="
|
|
||||||
#if defined(ARCH_X64)
|
|
||||||
"x64"
|
|
||||||
#elif defined(ARCH_ARM64)
|
|
||||||
"arm64"
|
|
||||||
#endif
|
|
||||||
"&os_version=%i.%i.%i",
|
|
||||||
rpcs3::get_commit_and_hash().second,
|
|
||||||
Darwin_Version::getNSmajorVersion(),
|
|
||||||
Darwin_Version::getNSminorVersion(),
|
|
||||||
Darwin_Version::getNSpatchVersion());
|
|
||||||
#else
|
|
||||||
const std::string url = "https://update.rpcs3.net/?api=v2&c=" + rpcs3::get_commit_and_hash().second;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
m_downloader->start(url, true, !automatic, tr("Checking For Updates"), true);
|
m_downloader->start(url, true, !automatic, tr("Checking For Updates"), true);
|
||||||
}
|
}
|
||||||
|
@ -199,11 +175,25 @@ bool update_manager::handle_json(bool automatic, bool check_only, bool auto_acce
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Check that every bit of info we need is there
|
// Check that every bit of info we need is there
|
||||||
if (!latest[os].isObject() || !latest[os]["download"].isString() || !latest[os]["size"].isDouble() || !latest[os]["checksum"].isString() || !latest["version"].isString() ||
|
const auto check_json = [](bool cond, std::string_view msg) -> bool
|
||||||
!latest["datetime"].isString() ||
|
{
|
||||||
(hash_found && (!current.isObject() || !current["version"].isString() || !current["datetime"].isString())))
|
if (cond) return true;
|
||||||
|
update_log.error("%s", msg);
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
if (!(check_json(latest[os].isObject(), fmt::format("Node 'latest_build: %s' not found", os)) &&
|
||||||
|
check_json(latest[os]["download"].isString(), fmt::format("Node 'latest_build: %s: download' not found or not a string", os)) &&
|
||||||
|
check_json(latest[os]["size"].isDouble(), fmt::format("Node 'latest_build: %s: size' not found or not a double", os)) &&
|
||||||
|
check_json(latest[os]["checksum"].isString(), fmt::format("Node 'latest_build: %s: checksum' not found or not a string", os)) &&
|
||||||
|
check_json(latest["version"].isString(), "Node 'latest_build: version' not found or not a string") &&
|
||||||
|
check_json(latest["datetime"].isString(), "Node 'latest_build: datetime' not found or not a string")
|
||||||
|
) ||
|
||||||
|
(hash_found && !(
|
||||||
|
check_json(current.isObject(), "JSON doesn't contain current_build section") &&
|
||||||
|
check_json(current["version"].isString(), "Node 'current_build: datetime' not found or not a string") &&
|
||||||
|
check_json(current["datetime"].isString(), "Node 'current_build: version' not found or not a string")
|
||||||
|
)))
|
||||||
{
|
{
|
||||||
update_log.error("Some information seems unavailable");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -129,20 +129,6 @@ namespace utils
|
||||||
per_core_usage.resize(utils::get_thread_count());
|
per_core_usage.resize(utils::get_thread_count());
|
||||||
std::fill(per_core_usage.begin(), per_core_usage.end(), 0.0);
|
std::fill(per_core_usage.begin(), per_core_usage.end(), 0.0);
|
||||||
|
|
||||||
#if defined(_WIN32) || defined(__linux__)
|
|
||||||
const auto string_to_number = [](const std::string& str) -> std::pair<bool, size_t>
|
|
||||||
{
|
|
||||||
std::add_pointer_t<char> eval;
|
|
||||||
const size_t number = std::strtol(str.c_str(), &eval, 10);
|
|
||||||
|
|
||||||
if (str.c_str() + str.size() == eval)
|
|
||||||
{
|
|
||||||
return { true, number };
|
|
||||||
}
|
|
||||||
|
|
||||||
return { false, 0 };
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if (!m_cpu_cores || !m_cpu_query)
|
if (!m_cpu_cores || !m_cpu_query)
|
||||||
{
|
{
|
||||||
|
@ -304,7 +290,6 @@ namespace utils
|
||||||
{
|
{
|
||||||
perf_log.error("Failed to open /proc/stat (%s)", strerror(errno));
|
perf_log.error("Failed to open /proc/stat (%s)", strerror(errno));
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#else
|
#else
|
||||||
total_usage = get_usage();
|
total_usage = get_usage();
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -74,45 +74,45 @@ namespace Darwin_ProcessInfo
|
||||||
namespace utils
|
namespace utils
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
// Some helpers for sanity
|
||||||
|
const auto read_reg_dword = [](HKEY hKey, std::string_view value_name) -> std::pair<bool, DWORD>
|
||||||
|
{
|
||||||
|
DWORD val = 0;
|
||||||
|
DWORD len = sizeof(val);
|
||||||
|
if (ERROR_SUCCESS != RegQueryValueExA(hKey, value_name.data(), nullptr, nullptr, reinterpret_cast<LPBYTE>(&val), &len))
|
||||||
|
{
|
||||||
|
return { false, 0 };
|
||||||
|
}
|
||||||
|
return { true, val };
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto read_reg_sz = [](HKEY hKey, std::string_view value_name) -> std::pair<bool, std::string>
|
||||||
|
{
|
||||||
|
constexpr usz MAX_SZ_LEN = 255;
|
||||||
|
char sz[MAX_SZ_LEN + 1] {};
|
||||||
|
DWORD sz_len = MAX_SZ_LEN;
|
||||||
|
|
||||||
|
// Safety; null terminate
|
||||||
|
sz[0] = 0;
|
||||||
|
sz[MAX_SZ_LEN] = 0;
|
||||||
|
|
||||||
|
// Read string
|
||||||
|
if (ERROR_SUCCESS != RegQueryValueExA(hKey, value_name.data(), nullptr, nullptr, reinterpret_cast<LPBYTE>(sz), &sz_len))
|
||||||
|
{
|
||||||
|
return { false, "" };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Safety, force null terminator
|
||||||
|
if (sz_len < MAX_SZ_LEN)
|
||||||
|
{
|
||||||
|
sz[sz_len] = 0;
|
||||||
|
}
|
||||||
|
return { true, sz };
|
||||||
|
};
|
||||||
|
|
||||||
// Alternative way to read OS version using the registry.
|
// Alternative way to read OS version using the registry.
|
||||||
static std::string get_fallback_windows_version()
|
static std::string get_fallback_windows_version()
|
||||||
{
|
{
|
||||||
// Some helpers for sanity
|
|
||||||
const auto read_reg_dword = [](HKEY hKey, std::string_view value_name) -> std::pair<bool, DWORD>
|
|
||||||
{
|
|
||||||
DWORD val;
|
|
||||||
DWORD len = sizeof(val);
|
|
||||||
if (ERROR_SUCCESS != RegQueryValueExA(hKey, value_name.data(), nullptr, nullptr, reinterpret_cast<LPBYTE>(&val), &len))
|
|
||||||
{
|
|
||||||
return { false, 0 };
|
|
||||||
}
|
|
||||||
return { true, val };
|
|
||||||
};
|
|
||||||
|
|
||||||
const auto read_reg_sz = [](HKEY hKey, std::string_view value_name) -> std::pair<bool, std::string>
|
|
||||||
{
|
|
||||||
constexpr usz MAX_SZ_LEN = 255;
|
|
||||||
char sz[MAX_SZ_LEN + 1];
|
|
||||||
DWORD sz_len = MAX_SZ_LEN;
|
|
||||||
|
|
||||||
// Safety; null terminate
|
|
||||||
sz[0] = 0;
|
|
||||||
sz[MAX_SZ_LEN] = 0;
|
|
||||||
|
|
||||||
// Read string
|
|
||||||
if (ERROR_SUCCESS != RegQueryValueExA(hKey, value_name.data(), nullptr, nullptr, reinterpret_cast<LPBYTE>(sz), &sz_len))
|
|
||||||
{
|
|
||||||
return { false, "" };
|
|
||||||
}
|
|
||||||
|
|
||||||
// Safety, force null terminator
|
|
||||||
if (sz_len < MAX_SZ_LEN)
|
|
||||||
{
|
|
||||||
sz[sz_len] = 0;
|
|
||||||
}
|
|
||||||
return { true, sz };
|
|
||||||
};
|
|
||||||
|
|
||||||
HKEY hKey;
|
HKEY hKey;
|
||||||
if (ERROR_SUCCESS != RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, KEY_READ, &hKey))
|
if (ERROR_SUCCESS != RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, KEY_READ, &hKey))
|
||||||
{
|
{
|
||||||
|
@ -661,14 +661,88 @@ std::string utils::get_firmware_version()
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string utils::get_OS_version()
|
utils::OS_version utils::get_OS_version()
|
||||||
|
{
|
||||||
|
OS_version res {};
|
||||||
|
|
||||||
|
#if _WIN32
|
||||||
|
res.type = "windows";
|
||||||
|
#elif __linux__
|
||||||
|
res.type = "linux";
|
||||||
|
#elif __APPLE__
|
||||||
|
res.type = "macos";
|
||||||
|
#elif __FreeBSD__
|
||||||
|
res.type = "freebsd";
|
||||||
|
#else
|
||||||
|
res.type = "unknown";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(ARCH_X64)
|
||||||
|
res.arch = "x64";
|
||||||
|
#elif defined(ARCH_ARM64)
|
||||||
|
res.arch = "arm64";
|
||||||
|
#else
|
||||||
|
res.arch = "unknown";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
// GetVersionEx is deprecated, RtlGetVersion is kernel-mode only and AnalyticsInfo is UWP only.
|
||||||
|
// So we're forced to read PEB instead to get Windows version info. It's ugly but works.
|
||||||
|
#if defined(ARCH_X64)
|
||||||
|
constexpr DWORD peb_offset = 0x60;
|
||||||
|
const INT_PTR peb = __readgsqword(peb_offset);
|
||||||
|
res.version_major = *reinterpret_cast<const DWORD*>(peb + 0x118);
|
||||||
|
res.version_minor = *reinterpret_cast<const DWORD*>(peb + 0x11c);
|
||||||
|
res.version_patch = *reinterpret_cast<const WORD*>(peb + 0x120);
|
||||||
|
#else
|
||||||
|
HKEY hKey;
|
||||||
|
if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, KEY_READ, &hKey) == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
const auto [check_major, version_major] = read_reg_dword(hKey, "CurrentMajorVersionNumber");
|
||||||
|
const auto [check_minor, version_minor] = read_reg_dword(hKey, "CurrentMinorVersionNumber");
|
||||||
|
const auto [check_build, version_patch] = read_reg_sz(hKey, "CurrentBuildNumber");
|
||||||
|
|
||||||
|
if (check_major) res.version_major = version_major;
|
||||||
|
if (check_minor) res.version_minor = version_minor;
|
||||||
|
if (check_build) res.version_patch = stoi(version_patch);
|
||||||
|
|
||||||
|
RegCloseKey(hKey);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#elif defined (__APPLE__)
|
||||||
|
res.version_major = Darwin_Version::getNSmajorVersion();
|
||||||
|
res.version_minor = Darwin_Version::getNSminorVersion();
|
||||||
|
res.version_patch = Darwin_Version::getNSpatchVersion();
|
||||||
|
#else
|
||||||
|
if (struct utsname details = {}; !uname(&details))
|
||||||
|
{
|
||||||
|
const std::vector<std::string> version_list = fmt::split(details.release, { "." });
|
||||||
|
const auto get_version_part = [&version_list](usz i) -> usz
|
||||||
|
{
|
||||||
|
if (version_list.size() <= i) return 0;
|
||||||
|
if (const auto [success, version_part] = string_to_number(version_list[i]); success)
|
||||||
|
{
|
||||||
|
return version_part;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
res.version_major = get_version_part(0);
|
||||||
|
res.version_minor = get_version_part(1);
|
||||||
|
res.version_patch = get_version_part(2);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string utils::get_OS_version_string()
|
||||||
{
|
{
|
||||||
std::string output;
|
std::string output;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
// GetVersionEx is deprecated, RtlGetVersion is kernel-mode only and AnalyticsInfo is UWP only.
|
// GetVersionEx is deprecated, RtlGetVersion is kernel-mode only and AnalyticsInfo is UWP only.
|
||||||
// So we're forced to read PEB instead to get Windows version info. It's ugly but works.
|
// So we're forced to read PEB instead to get Windows version info. It's ugly but works.
|
||||||
#if defined(ARCH_X64)
|
#if defined(ARCH_X64)
|
||||||
const DWORD peb_offset = 0x60;
|
constexpr DWORD peb_offset = 0x60;
|
||||||
const INT_PTR peb = __readgsqword(peb_offset);
|
const INT_PTR peb = __readgsqword(peb_offset);
|
||||||
const DWORD version_major = *reinterpret_cast<const DWORD*>(peb + 0x118);
|
const DWORD version_major = *reinterpret_cast<const DWORD*>(peb + 0x118);
|
||||||
const DWORD version_minor = *reinterpret_cast<const DWORD*>(peb + 0x11c);
|
const DWORD version_minor = *reinterpret_cast<const DWORD*>(peb + 0x11c);
|
||||||
|
@ -1014,10 +1088,20 @@ u32 utils::get_cpu_model()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace utils
|
u64 utils::_get_main_tid()
|
||||||
{
|
{
|
||||||
u64 _get_main_tid()
|
return thread_ctrl::get_tid();
|
||||||
{
|
}
|
||||||
return thread_ctrl::get_tid();
|
|
||||||
}
|
std::pair<bool, usz> utils::string_to_number(std::string_view str)
|
||||||
|
{
|
||||||
|
std::add_pointer_t<char> eval;
|
||||||
|
const usz number = std::strtol(str.data(), &eval, 10);
|
||||||
|
|
||||||
|
if (str.data() + str.size() == eval)
|
||||||
|
{
|
||||||
|
return { true, number };
|
||||||
|
}
|
||||||
|
|
||||||
|
return { false, 0 };
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "util/types.hpp"
|
#include "util/types.hpp"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -67,7 +67,17 @@ namespace utils
|
||||||
|
|
||||||
std::string get_firmware_version();
|
std::string get_firmware_version();
|
||||||
|
|
||||||
std::string get_OS_version();
|
struct OS_version
|
||||||
|
{
|
||||||
|
std::string type;
|
||||||
|
std::string arch;
|
||||||
|
int version_major = 0;
|
||||||
|
int version_minor = 0;
|
||||||
|
int version_patch = 0;
|
||||||
|
};
|
||||||
|
OS_version get_OS_version();
|
||||||
|
|
||||||
|
std::string get_OS_version_string();
|
||||||
|
|
||||||
int get_maxfiles();
|
int get_maxfiles();
|
||||||
|
|
||||||
|
@ -94,4 +104,6 @@ namespace utils
|
||||||
{
|
{
|
||||||
return s_tsc_freq;
|
return s_tsc_freq;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::pair<bool, usz> string_to_number(std::string_view str);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue