mirror of
https://github.com/Lime3DS/Lime3DS.git
synced 2026-04-07 09:01:29 -06:00
Merge 08f0a9953d into 3066887ff4
This commit is contained in:
commit
c6006e174b
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -106,3 +106,6 @@
|
||||
[submodule "externals/libretro-common"]
|
||||
path = externals/libretro-common/libretro-common
|
||||
url = https://github.com/libretro/libretro-common.git
|
||||
[submodule "externals/rcheevos/rcheevos"]
|
||||
path = externals/rcheevos/rcheevos
|
||||
url = https://github.com/RetroAchievements/rcheevos.git
|
||||
|
||||
@ -136,6 +136,8 @@ option(ENABLE_SSE42 "Enable SSE4.2 optimizations on x86_64" ON)
|
||||
|
||||
option(ENABLE_DEVELOPER_OPTIONS "Enable functionality targeted at emulator developers" OFF)
|
||||
|
||||
option(ENABLE_RETROACHIEVEMENTS "Build with RetroAchievements support" OFF)
|
||||
|
||||
# Compile options
|
||||
CMAKE_DEPENDENT_OPTION(COMPILE_WITH_DWARF "Add DWARF debugging information" ${IS_DEBUG_BUILD} "MINGW" OFF)
|
||||
option(ENABLE_LTO "Enable link time optimization" ${DEFAULT_ENABLE_LTO})
|
||||
|
||||
7
externals/CMakeLists.txt
vendored
7
externals/CMakeLists.txt
vendored
@ -519,4 +519,9 @@ elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|ARM64|armv8")
|
||||
else()
|
||||
target_compile_definitions(xxhash PRIVATE XXH_VECTOR=XXH_SCALAR)
|
||||
message(STATUS "Disabling SIMD for xxHash")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# rcheevos
|
||||
if (ENABLE_RETROACHIEVEMENTS)
|
||||
add_subdirectory(rcheevos)
|
||||
endif()
|
||||
|
||||
30
externals/rcheevos/CMakeLists.txt
vendored
Normal file
30
externals/rcheevos/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
add_library(rcheevos STATIC
|
||||
rcheevos/src/rc_compat.c
|
||||
rcheevos/src/rc_client.c
|
||||
rcheevos/src/rc_util.c
|
||||
rcheevos/src/rc_version.c
|
||||
rcheevos/src/rcheevos/alloc.c
|
||||
rcheevos/src/rcheevos/condition.c
|
||||
rcheevos/src/rcheevos/condset.c
|
||||
rcheevos/src/rcheevos/consoleinfo.c
|
||||
rcheevos/src/rcheevos/format.c
|
||||
rcheevos/src/rcheevos/lboard.c
|
||||
rcheevos/src/rcheevos/memref.c
|
||||
rcheevos/src/rcheevos/operand.c
|
||||
rcheevos/src/rcheevos/rc_validate.c
|
||||
rcheevos/src/rcheevos/richpresence.c
|
||||
rcheevos/src/rcheevos/runtime.c
|
||||
rcheevos/src/rcheevos/runtime_progress.c
|
||||
rcheevos/src/rcheevos/trigger.c
|
||||
rcheevos/src/rcheevos/value.c
|
||||
rcheevos/src/rhash/md5.c
|
||||
rcheevos/src/rapi/rc_api_common.c
|
||||
rcheevos/src/rapi/rc_api_editor.c
|
||||
rcheevos/src/rapi/rc_api_info.c
|
||||
rcheevos/src/rapi/rc_api_runtime.c
|
||||
rcheevos/src/rapi/rc_api_user.c
|
||||
)
|
||||
|
||||
target_include_directories(rcheevos PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rcheevos/include
|
||||
)
|
||||
1
externals/rcheevos/rcheevos
vendored
Submodule
1
externals/rcheevos/rcheevos
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit e9ca3694c862b61235595176dac4b22677848c93
|
||||
@ -184,6 +184,11 @@ if(ENABLE_DEVELOPER_OPTIONS)
|
||||
add_compile_definitions(ENABLE_DEVELOPER_OPTIONS)
|
||||
endif()
|
||||
|
||||
if (ENABLE_RETROACHIEVEMENTS)
|
||||
add_compile_definitions(ENABLE_RETROACHIEVEMENTS)
|
||||
add_subdirectory(retroachievements)
|
||||
endif()
|
||||
|
||||
add_subdirectory(common)
|
||||
add_subdirectory(core)
|
||||
add_subdirectory(video_core)
|
||||
|
||||
@ -334,3 +334,7 @@ endif()
|
||||
if (CITRA_USE_PRECOMPILED_HEADERS)
|
||||
target_precompile_headers(citra_qt PRIVATE precompiled_headers.h)
|
||||
endif()
|
||||
|
||||
if (ENABLE_RETROACHIEVEMENTS)
|
||||
target_link_libraries(citra_qt PRIVATE retroachievements)
|
||||
endif()
|
||||
|
||||
@ -11,6 +11,10 @@
|
||||
#include "citra_qt/uisettings.h"
|
||||
#include "common/file_util.h"
|
||||
#include "common/settings.h"
|
||||
#include "core/core.h"
|
||||
#ifdef ENABLE_RETROACHIEVEMENTS
|
||||
#include "retroachievements/client.h"
|
||||
#endif
|
||||
#include "ui_configure_general.h"
|
||||
|
||||
// The QSlider doesn't have an easy way to set a custom step amount,
|
||||
@ -47,6 +51,10 @@ ConfigureGeneral::ConfigureGeneral(QWidget* parent)
|
||||
ui->updates_group->setVisible(false);
|
||||
#endif
|
||||
|
||||
#ifndef ENABLE_RETROACHIEVEMENTS
|
||||
ui->retroachievements_group->setVisible(false);
|
||||
#endif
|
||||
|
||||
SetupPerGameUI();
|
||||
SetConfiguration();
|
||||
|
||||
@ -74,6 +82,9 @@ ConfigureGeneral::ConfigureGeneral(QWidget* parent)
|
||||
}
|
||||
ui->change_screenshot_dir->setEnabled(true);
|
||||
});
|
||||
|
||||
connect(ui->retroachievements_log_in_button, &QPushButton::clicked, this,
|
||||
&ConfigureGeneral::RetroAchievementsLogIn);
|
||||
}
|
||||
|
||||
ConfigureGeneral::~ConfigureGeneral() = default;
|
||||
@ -196,6 +207,16 @@ void ConfigureGeneral::RetranslateUI() {
|
||||
ui->retranslateUi(this);
|
||||
}
|
||||
|
||||
void ConfigureGeneral::RetroAchievementsLogIn() {
|
||||
#ifdef ENABLE_RETROACHIEVEMENTS
|
||||
std::string username = ui->retroachievements_username_input->text().toStdString(),
|
||||
password = ui->retroachievements_password_input->text().toStdString();
|
||||
|
||||
Core::System::GetInstance().RetroAchievementsClient().LogInUser(username.c_str(),
|
||||
password.c_str());
|
||||
#endif
|
||||
}
|
||||
|
||||
void ConfigureGeneral::SetupPerGameUI() {
|
||||
if (Settings::IsConfiguringGlobal()) {
|
||||
ui->frame_limit->setEnabled(Settings::values.frame_limit.UsingGlobal());
|
||||
|
||||
@ -24,6 +24,7 @@ public:
|
||||
void ApplyConfiguration();
|
||||
void RetranslateUI();
|
||||
void SetConfiguration();
|
||||
void RetroAchievementsLogIn();
|
||||
|
||||
void SetupPerGameUI();
|
||||
|
||||
|
||||
@ -295,7 +295,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="screenshot_dir_label">
|
||||
<widget class="QLabel">
|
||||
<property name="text">
|
||||
<string>Save Screenshots To</string>
|
||||
</property>
|
||||
@ -317,6 +317,82 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="retroachievements_group">
|
||||
<property name="title">
|
||||
<string>RetroAchievements</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout">
|
||||
<item>
|
||||
<widget class="QWidget" name="widget_retroachievements_username" native="true">
|
||||
<layout class="QHBoxLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel">
|
||||
<property name="text">
|
||||
<string>Username</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="retroachievements_username_input"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widget_retroachievements_password" native="true">
|
||||
<layout class="QHBoxLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel">
|
||||
<property name="text">
|
||||
<string>Password</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="retroachievements_password_input">
|
||||
<property name="echoMode">
|
||||
<enum>QLineEdit::PasswordEchoOnEdit</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="retroachievements_log_in_button">
|
||||
<property name="text">
|
||||
<string>Log In</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item alignment="Qt::AlignRight">
|
||||
<widget class="QPushButton" name="button_reset_defaults">
|
||||
<property name="text">
|
||||
|
||||
@ -137,7 +137,8 @@ bool ParseFilterRule(Filter& instance, Iterator begin, Iterator end) {
|
||||
CLS(Movie) \
|
||||
CLS(Loader) \
|
||||
CLS(WebService) \
|
||||
CLS(RPC_Server)
|
||||
CLS(RPC_Server) \
|
||||
CLS(RetroAchievements)
|
||||
|
||||
// GetClassName is a macro defined by Windows.h, grrr...
|
||||
const char* GetLogClassName(Class log_class) {
|
||||
|
||||
@ -52,60 +52,61 @@ enum class Class : u8 {
|
||||
Applet_SWKBD, ///< The Software Keyboard applet
|
||||
Service, ///< HLE implementation of system services. Each major service
|
||||
///< should have its own subclass.
|
||||
Service_SRV, ///< The SRV (Service Directory) implementation
|
||||
Service_FRD, ///< The FRD (Friends) service
|
||||
Service_FS, ///< The FS (Filesystem) service implementation
|
||||
Service_ERR, ///< The ERR (Error) port implementation
|
||||
Service_ACT, ///< The ACT (Account) service
|
||||
Service_APT, ///< The APT (Applets) service
|
||||
Service_BOSS, ///< The BOSS (SpotPass) service
|
||||
Service_GSP, ///< The GSP (GPU control) service
|
||||
Service_AC, ///< The AC (WiFi status) service
|
||||
Service_AM, ///< The AM (Application manager) service
|
||||
Service_PTM, ///< The PTM (Power status & misc.) service
|
||||
Service_LDR, ///< The LDR (3ds dll loader) service
|
||||
Service_MIC, ///< The MIC (Microphone) service
|
||||
Service_NDM, ///< The NDM (Network daemon manager) service
|
||||
Service_NFC, ///< The NFC service
|
||||
Service_NIM, ///< The NIM (Network interface manager) service
|
||||
Service_NS, ///< The NS (Nintendo User Interface Shell) service
|
||||
Service_NWM, ///< The NWM (Network wlan manager) service
|
||||
Service_CAM, ///< The CAM (Camera) service
|
||||
Service_CECD, ///< The CECD (StreetPass) service
|
||||
Service_CFG, ///< The CFG (Configuration) service
|
||||
Service_CSND, ///< The CSND (CWAV format process) service
|
||||
Service_DSP, ///< The DSP (DSP control) service
|
||||
Service_DLP, ///< The DLP (Download Play) service
|
||||
Service_HID, ///< The HID (Human interface device) service
|
||||
Service_HTTP, ///< The HTTP service
|
||||
Service_SOC, ///< The SOC (Socket) service
|
||||
Service_IR, ///< The IR service
|
||||
Service_Y2R, ///< The Y2R (YUV to RGB conversion) service
|
||||
Service_PS, ///< The PS (Process) service
|
||||
Service_PLGLDR, ///< The PLGLDR (plugin loader) service
|
||||
Service_NEWS, ///< The NEWS (Notifications) service
|
||||
HW, ///< Low-level hardware emulation
|
||||
HW_Memory, ///< Memory-map and address translation
|
||||
HW_LCD, ///< LCD register emulation
|
||||
HW_GPU, ///< GPU control emulation
|
||||
HW_AES, ///< AES engine emulation
|
||||
HW_RSA, ///< RSA engine emulation
|
||||
HW_ECC, ///< ECC engine emulation
|
||||
Frontend, ///< Emulator UI
|
||||
Render, ///< Emulator video output and hardware acceleration
|
||||
Render_Software, ///< Software renderer backend
|
||||
Render_OpenGL, ///< OpenGL backend
|
||||
Render_Vulkan, ///< Vulkan backend
|
||||
Audio, ///< Audio emulation
|
||||
Audio_DSP, ///< The HLE and LLE implementations of the DSP
|
||||
Audio_Sink, ///< Emulator audio output backend
|
||||
Loader, ///< ROM loader
|
||||
Input, ///< Input emulation
|
||||
Network, ///< Network emulation
|
||||
Movie, ///< Movie (Input Recording) Playback
|
||||
WebService, ///< Interface to Citra Web Services
|
||||
RPC_Server, ///< RPC server
|
||||
Count, ///< Total number of logging classes
|
||||
Service_SRV, ///< The SRV (Service Directory) implementation
|
||||
Service_FRD, ///< The FRD (Friends) service
|
||||
Service_FS, ///< The FS (Filesystem) service implementation
|
||||
Service_ERR, ///< The ERR (Error) port implementation
|
||||
Service_ACT, ///< The ACT (Account) service
|
||||
Service_APT, ///< The APT (Applets) service
|
||||
Service_BOSS, ///< The BOSS (SpotPass) service
|
||||
Service_GSP, ///< The GSP (GPU control) service
|
||||
Service_AC, ///< The AC (WiFi status) service
|
||||
Service_AM, ///< The AM (Application manager) service
|
||||
Service_PTM, ///< The PTM (Power status & misc.) service
|
||||
Service_LDR, ///< The LDR (3ds dll loader) service
|
||||
Service_MIC, ///< The MIC (Microphone) service
|
||||
Service_NDM, ///< The NDM (Network daemon manager) service
|
||||
Service_NFC, ///< The NFC service
|
||||
Service_NIM, ///< The NIM (Network interface manager) service
|
||||
Service_NS, ///< The NS (Nintendo User Interface Shell) service
|
||||
Service_NWM, ///< The NWM (Network wlan manager) service
|
||||
Service_CAM, ///< The CAM (Camera) service
|
||||
Service_CECD, ///< The CECD (StreetPass) service
|
||||
Service_CFG, ///< The CFG (Configuration) service
|
||||
Service_CSND, ///< The CSND (CWAV format process) service
|
||||
Service_DSP, ///< The DSP (DSP control) service
|
||||
Service_DLP, ///< The DLP (Download Play) service
|
||||
Service_HID, ///< The HID (Human interface device) service
|
||||
Service_HTTP, ///< The HTTP service
|
||||
Service_SOC, ///< The SOC (Socket) service
|
||||
Service_IR, ///< The IR service
|
||||
Service_Y2R, ///< The Y2R (YUV to RGB conversion) service
|
||||
Service_PS, ///< The PS (Process) service
|
||||
Service_PLGLDR, ///< The PLGLDR (plugin loader) service
|
||||
Service_NEWS, ///< The NEWS (Notifications) service
|
||||
HW, ///< Low-level hardware emulation
|
||||
HW_Memory, ///< Memory-map and address translation
|
||||
HW_LCD, ///< LCD register emulation
|
||||
HW_GPU, ///< GPU control emulation
|
||||
HW_AES, ///< AES engine emulation
|
||||
HW_RSA, ///< RSA engine emulation
|
||||
HW_ECC, ///< ECC engine emulation
|
||||
Frontend, ///< Emulator UI
|
||||
Render, ///< Emulator video output and hardware acceleration
|
||||
Render_Software, ///< Software renderer backend
|
||||
Render_OpenGL, ///< OpenGL backend
|
||||
Render_Vulkan, ///< Vulkan backend
|
||||
Audio, ///< Audio emulation
|
||||
Audio_DSP, ///< The HLE and LLE implementations of the DSP
|
||||
Audio_Sink, ///< Emulator audio output backend
|
||||
Loader, ///< ROM loader
|
||||
Input, ///< Input emulation
|
||||
Network, ///< Network emulation
|
||||
Movie, ///< Movie (Input Recording) Playback
|
||||
WebService, ///< Interface to Citra Web Services
|
||||
RPC_Server, ///< RPC server
|
||||
RetroAchievements, ///< RetroAchievements
|
||||
Count, ///< Total number of logging classes
|
||||
};
|
||||
|
||||
} // namespace Common::Log
|
||||
|
||||
@ -506,6 +506,11 @@ target_link_libraries(citra_core PUBLIC citra_common PRIVATE audio_core network
|
||||
target_link_libraries(citra_core PRIVATE Boost::boost Boost::serialization Boost::iostreams httplib)
|
||||
target_link_libraries(citra_core PUBLIC dds-ktx PRIVATE cryptopp fmt lodepng open_source_archives)
|
||||
|
||||
if (ENABLE_RETROACHIEVEMENTS)
|
||||
target_link_libraries(citra_core PUBLIC retroachievements)
|
||||
target_compile_definitions(citra_core PUBLIC ENABLE_RETROACHIEVEMENTS)
|
||||
endif()
|
||||
|
||||
if (ENABLE_WEB_SERVICE)
|
||||
target_link_libraries(citra_core PRIVATE web_service)
|
||||
endif()
|
||||
|
||||
@ -50,6 +50,9 @@
|
||||
#include "core/rpc/server.h"
|
||||
#endif
|
||||
#include "network/network.h"
|
||||
#ifdef ENABLE_RETROACHIEVEMENTS
|
||||
#include "retroachievements/client.h"
|
||||
#endif
|
||||
#include "video_core/custom_textures/custom_tex_manager.h"
|
||||
#include "video_core/gpu.h"
|
||||
#include "video_core/renderer_base.h"
|
||||
@ -73,7 +76,12 @@ Core::Timing& Global() {
|
||||
return System::GetInstance().CoreTiming();
|
||||
}
|
||||
|
||||
System::System() : movie{*this}, cheat_engine{*this} {}
|
||||
System::System() : movie{*this}, cheat_engine{*this} {
|
||||
#ifdef ENABLE_RETROACHIEVEMENTS
|
||||
retroachievements_client = std::make_unique<RetroAchievements::Client>(*this);
|
||||
retroachievements_client->Initialize();
|
||||
#endif
|
||||
}
|
||||
|
||||
System::~System() = default;
|
||||
|
||||
@ -653,6 +661,16 @@ const Cheats::CheatEngine& System::CheatEngine() const {
|
||||
return cheat_engine;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_RETROACHIEVEMENTS
|
||||
RetroAchievements::Client& System::RetroAchievementsClient() {
|
||||
return *retroachievements_client;
|
||||
}
|
||||
|
||||
const RetroAchievements::Client& System::RetroAchievementsClient() const {
|
||||
return *retroachievements_client;
|
||||
}
|
||||
#endif
|
||||
|
||||
void System::RegisterVideoDumper(std::shared_ptr<VideoDumper::Backend> dumper) {
|
||||
video_dumper = std::move(dumper);
|
||||
}
|
||||
|
||||
@ -70,6 +70,12 @@ namespace Loader {
|
||||
class AppLoader;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_RETROACHIEVEMENTS
|
||||
namespace RetroAchievements {
|
||||
class Client;
|
||||
} // namespace RetroAchievements
|
||||
#endif
|
||||
|
||||
namespace Core {
|
||||
|
||||
class ARM_Interface;
|
||||
@ -277,6 +283,14 @@ public:
|
||||
/// Gets a const reference to the cheat engine
|
||||
[[nodiscard]] const Cheats::CheatEngine& CheatEngine() const;
|
||||
|
||||
#ifdef ENABLE_RETROACHIEVEMENTS
|
||||
// Gets a reference to the RetroAchievements client
|
||||
[[nodiscard]] RetroAchievements::Client& RetroAchievementsClient();
|
||||
|
||||
// Gets a const reference to the RetroAchievements client
|
||||
[[nodiscard]] const RetroAchievements::Client& RetroAchievementsClient() const;
|
||||
#endif
|
||||
|
||||
/// Gets a reference to the custom texture cache system
|
||||
[[nodiscard]] VideoCore::CustomTexManager& CustomTexManager();
|
||||
|
||||
@ -430,6 +444,11 @@ private:
|
||||
/// Cheats manager
|
||||
Cheats::CheatEngine cheat_engine;
|
||||
|
||||
#ifdef ENABLE_RETROACHIEVEMENTS
|
||||
/// RetroAchievements
|
||||
std::unique_ptr<RetroAchievements::Client> retroachievements_client;
|
||||
#endif
|
||||
|
||||
/// Video dumper backend
|
||||
std::shared_ptr<VideoDumper::Backend> video_dumper;
|
||||
|
||||
|
||||
6
src/retroachievements/CMakeLists.txt
Normal file
6
src/retroachievements/CMakeLists.txt
Normal file
@ -0,0 +1,6 @@
|
||||
add_library(retroachievements STATIC
|
||||
client.cpp
|
||||
client.h
|
||||
)
|
||||
|
||||
target_link_libraries(retroachievements PRIVATE citra_common httplib rcheevos)
|
||||
113
src/retroachievements/client.cpp
Normal file
113
src/retroachievements/client.cpp
Normal file
@ -0,0 +1,113 @@
|
||||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "client.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
#include <httplib.h>
|
||||
#include <rc_client.h>
|
||||
#include <rc_error.h>
|
||||
|
||||
#include "common/logging/log.h"
|
||||
#include "common/scm_rev.h"
|
||||
|
||||
namespace RetroAchievements {
|
||||
static const char base_url[] = "https://retroachievements.org";
|
||||
|
||||
// TODO: Make this use a numeric version as per
|
||||
// https://github.com/RetroAchievements/rcheevos/wiki/rc_client-integration#user-agent-header
|
||||
static const std::string user_agent = std::string("Azahar/") + Common::g_build_fullname;
|
||||
static const httplib::Headers headers = httplib::Headers({{"User-Agent", user_agent}});
|
||||
|
||||
namespace Callbacks {
|
||||
// This is the function the rc_client will use to read memory for the emulator. we don't need it
|
||||
// yet, so just provide a dummy function that returns "no memory read".
|
||||
static uint32_t read_memory(uint32_t address, uint8_t* buffer, uint32_t num_bytes,
|
||||
rc_client_t* client) {
|
||||
// TODO: implement later
|
||||
LOG_DEBUG(RetroAchievements, "Attempting to read memory.");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void server_call(const rc_api_request_t* request, rc_client_server_callback_t callback,
|
||||
void* callback_data, rc_client_t* rc_client) {
|
||||
LOG_DEBUG(RetroAchievements, "Attempting to call server.");
|
||||
|
||||
if (std::strstr(request->url, base_url) == nullptr) {
|
||||
LOG_ERROR(RetroAchievements, "Invalid URL: \"{}\"", request->url);
|
||||
return;
|
||||
}
|
||||
|
||||
httplib::Client client(base_url);
|
||||
const char* path = &request->url[sizeof(base_url) - 1];
|
||||
|
||||
// TODO: Should make this async?
|
||||
httplib::Result result;
|
||||
if (request->post_data) {
|
||||
result = client.Post(path, headers, request->post_data, std::strlen(request->post_data),
|
||||
request->content_type);
|
||||
} else {
|
||||
result = client.Get(path, headers);
|
||||
}
|
||||
|
||||
if (result) {
|
||||
LOG_DEBUG(RetroAchievements, "Status: {}", result->status);
|
||||
LOG_DEBUG(RetroAchievements, "Body: {}", result->body);
|
||||
|
||||
rc_api_server_response_t server_response = {.body = result->body.c_str(),
|
||||
.body_length = result->body.length(),
|
||||
.http_status_code = result->status};
|
||||
callback(&server_response, callback_data);
|
||||
} else {
|
||||
LOG_DEBUG(RetroAchievements, "HTTP error {}", result.error());
|
||||
}
|
||||
}
|
||||
|
||||
// Write log messages to the console
|
||||
static void log_message(const char* message, const rc_client_t* client) {
|
||||
LOG_DEBUG(RetroAchievements, "RetroAchievements internal message: \"{}\"", message);
|
||||
}
|
||||
} // namespace Callbacks
|
||||
|
||||
Client::Client(const Core::System& _system) : system{_system} {}
|
||||
|
||||
Client::~Client() {
|
||||
if (rc_client) {
|
||||
rc_client_destroy(rc_client);
|
||||
rc_client = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void Client::Initialize() {
|
||||
LOG_DEBUG(RetroAchievements, "Initializing RetroAchievements client.");
|
||||
|
||||
rc_client = rc_client_create(Callbacks::read_memory, Callbacks::server_call);
|
||||
rc_client_enable_logging(rc_client, RC_CLIENT_LOG_LEVEL_VERBOSE, Callbacks::log_message);
|
||||
rc_client_set_hardcore_enabled(rc_client, 0);
|
||||
}
|
||||
|
||||
static void login_callback(int result, const char* error_message, rc_client_t* client,
|
||||
void* userdata) {
|
||||
// If not successful, just report the error and bail.
|
||||
if (result != RC_OK) {
|
||||
LOG_ERROR(RetroAchievements, "Login failed.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Login was successful. Capture the token for future logins so we don't have to store the
|
||||
// password anywhere.
|
||||
const rc_client_user_t* user = rc_client_get_user_info(client);
|
||||
// store_retroachievements_credentials(user->username, user->token);
|
||||
|
||||
// Inform user of successful login
|
||||
LOG_INFO(RetroAchievements, "Logged in as {} ({} points)", user->display_name, user->score);
|
||||
}
|
||||
|
||||
void Client::LogInUser(const char* username, const char* password) {
|
||||
rc_client_begin_login_with_password(rc_client, username, password, login_callback, NULL);
|
||||
}
|
||||
} // namespace RetroAchievements
|
||||
27
src/retroachievements/client.h
Normal file
27
src/retroachievements/client.h
Normal file
@ -0,0 +1,27 @@
|
||||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
}
|
||||
|
||||
struct rc_client_t;
|
||||
|
||||
namespace RetroAchievements {
|
||||
class Client {
|
||||
public:
|
||||
explicit Client(const Core::System& system);
|
||||
~Client();
|
||||
|
||||
void Initialize();
|
||||
|
||||
void LogInUser(const char* username, const char* password);
|
||||
|
||||
private:
|
||||
const Core::System& system;
|
||||
rc_client_t* rc_client = nullptr;
|
||||
};
|
||||
} // namespace RetroAchievements
|
||||
Loading…
Reference in New Issue
Block a user