diff --git a/src/core/hle/service/frd/frd.cpp b/src/core/hle/service/frd/frd.cpp index e3629a996..a8628b315 100644 --- a/src/core/hle/service/frd/frd.cpp +++ b/src/core/hle/service/frd/frd.cpp @@ -10,6 +10,7 @@ #include "common/string_util.h" #include "core/core.h" #include "core/hle/ipc_helpers.h" +#include "core/hle/kernel/event.h" #include "core/hle/result.h" #include "core/hle/service/cfg/cfg.h" #include "core/hle/service/frd/frd.h" @@ -157,6 +158,44 @@ void Module::Interface::SetClientSdkVersion(Kernel::HLERequestContext& ctx) { LOG_WARNING(Service_FRD, "(STUBBED) called, version: 0x{:08X}", version); } +void Module::Interface::HasLoggedIn(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_FRD, "(STUBBED) called"); + + IPC::RequestParser rp(ctx); + IPC::RequestBuilder rb = rp.MakeBuilder(2, 0); + rb.Push(RESULT_SUCCESS); + rb.Push(frd->logged_in); +} + +void Module::Interface::Login(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_FRD, "(STUBBED) called"); + + IPC::RequestParser rp(ctx); + frd->login_event = rp.PopObject(); + + constexpr auto login_delay_ms = 500; + frd->login_delay_event = frd->system.CoreTiming().RegisterEvent( + "frd::login_event", + // Simulate a small login delay + [this](u64 thread_id, s64 cycle_late) { + frd->logged_in = true; + frd->login_event->Signal(); + frd->system.CoreTiming().RemoveEvent(frd->login_delay_event); + }); + frd->system.CoreTiming().ScheduleEvent(msToCycles(login_delay_ms), frd->login_delay_event); + + IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); + rb.Push(RESULT_SUCCESS); +} + +void Module::Interface::GetLastResponseResult(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_FRD, "(STUBBED) called"); + + IPC::RequestParser rp(ctx); + IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); + rb.Push(RESULT_SUCCESS); +} + Module::Module(Core::System& system) : system(system){}; Module::~Module() = default; diff --git a/src/core/hle/service/frd/frd.h b/src/core/hle/service/frd/frd.h index 16902e45d..064e7f7f1 100644 --- a/src/core/hle/service/frd/frd.h +++ b/src/core/hle/service/frd/frd.h @@ -12,6 +12,10 @@ namespace Core { class System; } +namespace Kernel { +class Event; +} + namespace Service::FRD { struct FriendKey { @@ -146,6 +150,34 @@ public: */ void SetClientSdkVersion(Kernel::HLERequestContext& ctx); + /** + * FRD::Login service function + * Inputs: + * 65 : Address of unknown event + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + */ + void Login(Kernel::HLERequestContext& ctx); + + /** + * FRD::HasLoggedIn service function + * Inputs: + * none + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + * 2 : If the user has logged in 1, otherwise 0 + */ + void HasLoggedIn(Kernel::HLERequestContext& ctx); + + /** + * FRD::GetLastResponseResult service function + * Inputs: + * none + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + */ + void GetLastResponseResult(Kernel::HLERequestContext& ctx); + protected: std::shared_ptr frd; }; @@ -153,12 +185,16 @@ public: private: FriendKey my_friend_key = {0, 0, 0ull}; MyPresence my_presence = {}; + bool logged_in = false; + std::shared_ptr login_event; + Core::TimingEventType* login_delay_event; Core::System& system; template void serialize(Archive& ar, const unsigned int) { ar& my_friend_key; ar& my_presence; + ar& logged_in; } friend class boost::serialization::access; }; diff --git a/src/core/hle/service/frd/frd_a.cpp b/src/core/hle/service/frd/frd_a.cpp index 4fcf04b94..f0d95e8da 100644 --- a/src/core/hle/service/frd/frd_a.cpp +++ b/src/core/hle/service/frd/frd_a.cpp @@ -11,9 +11,9 @@ namespace Service::FRD { FRD_A::FRD_A(std::shared_ptr frd) : Module::Interface(std::move(frd), "frd:a", 8) { static const FunctionInfo functions[] = { - {0x0001, nullptr, "HasLoggedIn"}, + {0x0001, &FRD_A::HasLoggedIn, "HasLoggedIn"}, {0x0002, nullptr, "IsOnline"}, - {0x0003, nullptr, "Login"}, + {0x0003, &FRD_A::Login, "Login"}, {0x0004, nullptr, "Logout"}, {0x0005, &FRD_A::GetMyFriendKey, "GetMyFriendKey"}, {0x0006, nullptr, "GetMyPreference"}, @@ -45,7 +45,7 @@ FRD_A::FRD_A(std::shared_ptr frd) : Module::Interface(std::move(frd), "f {0x0020, nullptr, "AttachToEventNotification"}, {0x0021, nullptr, "SetNotificationMask"}, {0x0022, nullptr, "GetEventNotification"}, - {0x0023, nullptr, "GetLastResponseResult"}, + {0x0023, &FRD_A::GetLastResponseResult, "GetLastResponseResult"}, {0x0024, nullptr, "PrincipalIdToFriendCode"}, {0x0025, nullptr, "FriendCodeToPrincipalId"}, {0x0026, nullptr, "IsValidFriendCode"}, @@ -64,6 +64,14 @@ FRD_A::FRD_A(std::shared_ptr frd) : Module::Interface(std::move(frd), "f {0x0033, nullptr, "GetMyApproachContext"}, {0x0034, nullptr, "AddFriendWithApproach"}, {0x0035, nullptr, "DecryptApproachContext"}, + {0x0406, nullptr, "AddFriendOnline"}, + {0x0409, nullptr, "RemoveFriend"}, + {0x040a, nullptr, "UpdatePlayingGame"}, + {0x040b, nullptr, "UpdatePreference"}, + {0x040c, nullptr, "UpdateMii"}, + {0x040d, nullptr, "UpdateFavoriteGame"}, + {0x040e, nullptr, "UpdateNcPrincipalId"}, + {0x040f, nullptr, "UpdateComment"}, }; RegisterHandlers(functions); } diff --git a/src/core/hle/service/frd/frd_u.cpp b/src/core/hle/service/frd/frd_u.cpp index 46e5f23c3..33b6b6f3f 100644 --- a/src/core/hle/service/frd/frd_u.cpp +++ b/src/core/hle/service/frd/frd_u.cpp @@ -11,9 +11,9 @@ namespace Service::FRD { FRD_U::FRD_U(std::shared_ptr frd) : Module::Interface(std::move(frd), "frd:u", 8) { static const FunctionInfo functions[] = { - {0x0001, nullptr, "HasLoggedIn"}, + {0x0001, &FRD_U::HasLoggedIn, "HasLoggedIn"}, {0x0002, nullptr, "IsOnline"}, - {0x0003, nullptr, "Login"}, + {0x0003, &FRD_U::Login, "Login"}, {0x0004, nullptr, "Logout"}, {0x0005, &FRD_U::GetMyFriendKey, "GetMyFriendKey"}, {0x0006, nullptr, "GetMyPreference"}, @@ -45,7 +45,7 @@ FRD_U::FRD_U(std::shared_ptr frd) : Module::Interface(std::move(frd), "f {0x0020, nullptr, "AttachToEventNotification"}, {0x0021, nullptr, "SetNotificationMask"}, {0x0022, nullptr, "GetEventNotification"}, - {0x0023, nullptr, "GetLastResponseResult"}, + {0x0023, &FRD_U::GetLastResponseResult, "GetLastResponseResult"}, {0x0024, nullptr, "PrincipalIdToFriendCode"}, {0x0025, nullptr, "FriendCodeToPrincipalId"}, {0x0026, nullptr, "IsValidFriendCode"},