Compare commits
	
		
			1 Commits
		
	
	
		
			cheat_mana
			...
			be_my_frie
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					43a7bd18b2 | 
@@ -459,8 +459,12 @@ add_library(core STATIC
 | 
			
		||||
    hle/service/fgm/fgm.h
 | 
			
		||||
    hle/service/friend/friend.cpp
 | 
			
		||||
    hle/service/friend/friend.h
 | 
			
		||||
    hle/service/friend/friend_interface.cpp
 | 
			
		||||
    hle/service/friend/friend_interface.h
 | 
			
		||||
    hle/service/friend/friend_results.h
 | 
			
		||||
    hle/service/friend/friend_service.cpp
 | 
			
		||||
    hle/service/friend/friend_service.h
 | 
			
		||||
    hle/service/friend/friend_types.h
 | 
			
		||||
    hle/service/friend/notification_service.cpp
 | 
			
		||||
    hle/service/friend/notification_service.h
 | 
			
		||||
    hle/service/glue/arp.cpp
 | 
			
		||||
    hle/service/glue/arp.h
 | 
			
		||||
    hle/service/glue/bgtc.cpp
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,6 @@
 | 
			
		||||
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
 | 
			
		||||
// SPDX-License-Identifier: GPL-2.0-or-later
 | 
			
		||||
 | 
			
		||||
#include <queue>
 | 
			
		||||
#include "common/logging/log.h"
 | 
			
		||||
#include "common/uuid.h"
 | 
			
		||||
#include "core/core.h"
 | 
			
		||||
@@ -14,6 +13,9 @@
 | 
			
		||||
#include "core/hle/service/server_manager.h"
 | 
			
		||||
 | 
			
		||||
namespace Service::Friend {
 | 
			
		||||
Module::Interface::Interface(std::shared_ptr<Module> module_, Core::System& system_,
 | 
			
		||||
                             const char* name)
 | 
			
		||||
    : ServiceFramework{system_, name}, module{std::move(module_)} {}
 | 
			
		||||
 | 
			
		||||
class IFriendService final : public ServiceFramework<IFriendService> {
 | 
			
		||||
public:
 | 
			
		||||
@@ -330,11 +332,17 @@ void Module::Interface::CreateNotificationService(HLERequestContext& ctx) {
 | 
			
		||||
    rb.PushIpcInterface<INotificationService>(system, uuid);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Module::Interface::Interface(std::shared_ptr<Module> module_, Core::System& system_,
 | 
			
		||||
                             const char* name)
 | 
			
		||||
    : ServiceFramework{system_, name}, module{std::move(module_)} {}
 | 
			
		||||
Friend::Friend(std::shared_ptr<Module> module_, Core::System& system_, const char* name)
 | 
			
		||||
    : Interface(std::move(module_), system_, name) {
 | 
			
		||||
    static const FunctionInfo functions[] = {
 | 
			
		||||
        {0, &Friend::CreateFriendService, "CreateFriendService"},
 | 
			
		||||
        {1, &Friend::CreateNotificationService, "CreateNotificationService"},
 | 
			
		||||
        {2, nullptr, "CreateDaemonSuspendSessionService"},
 | 
			
		||||
    };
 | 
			
		||||
    RegisterHandlers(functions);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Module::Interface::~Interface() = default;
 | 
			
		||||
Friend::~Friend() = default;
 | 
			
		||||
 | 
			
		||||
void LoopProcess(Core::System& system) {
 | 
			
		||||
    auto server_manager = std::make_unique<ServerManager>(system);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,20 +0,0 @@
 | 
			
		||||
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
 | 
			
		||||
// SPDX-License-Identifier: GPL-2.0-or-later
 | 
			
		||||
 | 
			
		||||
#include "core/hle/service/friend/friend_interface.h"
 | 
			
		||||
 | 
			
		||||
namespace Service::Friend {
 | 
			
		||||
 | 
			
		||||
Friend::Friend(std::shared_ptr<Module> module_, Core::System& system_, const char* name)
 | 
			
		||||
    : Interface(std::move(module_), system_, name) {
 | 
			
		||||
    static const FunctionInfo functions[] = {
 | 
			
		||||
        {0, &Friend::CreateFriendService, "CreateFriendService"},
 | 
			
		||||
        {1, &Friend::CreateNotificationService, "CreateNotificationService"},
 | 
			
		||||
        {2, nullptr, "CreateDaemonSuspendSessionService"},
 | 
			
		||||
    };
 | 
			
		||||
    RegisterHandlers(functions);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Friend::~Friend() = default;
 | 
			
		||||
 | 
			
		||||
} // namespace Service::Friend
 | 
			
		||||
@@ -1,16 +0,0 @@
 | 
			
		||||
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
 | 
			
		||||
// SPDX-License-Identifier: GPL-2.0-or-later
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "core/hle/service/friend/friend.h"
 | 
			
		||||
 | 
			
		||||
namespace Service::Friend {
 | 
			
		||||
 | 
			
		||||
class Friend final : public Module::Interface {
 | 
			
		||||
public:
 | 
			
		||||
    explicit Friend(std::shared_ptr<Module> module_, Core::System& system_, const char* name);
 | 
			
		||||
    ~Friend() override;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace Service::Friend
 | 
			
		||||
							
								
								
									
										14
									
								
								src/core/hle/service/friend/friend_results.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/core/hle/service/friend/friend_results.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
			
		||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
 | 
			
		||||
// SPDX-License-Identifier: GPL-2.0-or-later
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "core/hle/result.h"
 | 
			
		||||
 | 
			
		||||
namespace Service::Friend {
 | 
			
		||||
 | 
			
		||||
constexpr Result NotInitialized{ErrorModule::Account, 1};
 | 
			
		||||
constexpr Result InvalidArgument{ErrorModule::Account, 2};
 | 
			
		||||
constexpr Result NoNotifications{ErrorModule::Account, 15};
 | 
			
		||||
 | 
			
		||||
} // namespace Service::Friend
 | 
			
		||||
							
								
								
									
										184
									
								
								src/core/hle/service/friend/friend_service.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										184
									
								
								src/core/hle/service/friend/friend_service.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,184 @@
 | 
			
		||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
 | 
			
		||||
// SPDX-License-Identifier: GPL-2.0-or-later
 | 
			
		||||
 | 
			
		||||
#include "common/logging/log.h"
 | 
			
		||||
#include "common/uuid.h"
 | 
			
		||||
#include "core/hle/ipc_helpers.h"
 | 
			
		||||
#include "core/hle/service/friend/friend_results.h"
 | 
			
		||||
#include "core/hle/service/friend/friend_service.h"
 | 
			
		||||
#include "core/hle/service/friend/friend_types.h"
 | 
			
		||||
 | 
			
		||||
namespace Service::Friend {
 | 
			
		||||
 | 
			
		||||
IFriendService::IFriendService(Core::System& system_)
 | 
			
		||||
    : ServiceFramework{system_, "IFriendService"}, service_context{system, "IFriendService"} {
 | 
			
		||||
    // clang-format off
 | 
			
		||||
        static const FunctionInfo functions[] = {
 | 
			
		||||
            {0, &IFriendService::GetCompletionEvent, "GetCompletionEvent"},
 | 
			
		||||
            {1, nullptr, "Cancel"},
 | 
			
		||||
            {10100, nullptr, "GetFriendListIds"},
 | 
			
		||||
            {10101, &IFriendService::GetFriendList, "GetFriendList"},
 | 
			
		||||
            {10102, nullptr, "UpdateFriendInfo"},
 | 
			
		||||
            {10110, nullptr, "GetFriendProfileImage"},
 | 
			
		||||
            {10120, &IFriendService::CheckFriendListAvailability, "CheckFriendListAvailability"},
 | 
			
		||||
            {10121, nullptr, "EnsureFriendListAvailable"},
 | 
			
		||||
            {10200, nullptr, "SendFriendRequestForApplication"},
 | 
			
		||||
            {10211, nullptr, "AddFacedFriendRequestForApplication"},
 | 
			
		||||
            {10400, &IFriendService::GetBlockedUserListIds, "GetBlockedUserListIds"},
 | 
			
		||||
            {10420, nullptr, "IsBlockedUserListCacheAvailable"},
 | 
			
		||||
            {10421, nullptr, "EnsureBlockedUserListAvailable"},
 | 
			
		||||
            {10500, nullptr, "GetProfileList"},
 | 
			
		||||
            {10600, nullptr, "DeclareOpenOnlinePlaySession"},
 | 
			
		||||
            {10601, &IFriendService::DeclareCloseOnlinePlaySession, "DeclareCloseOnlinePlaySession"},
 | 
			
		||||
            {10610, &IFriendService::UpdateUserPresence, "UpdateUserPresence"},
 | 
			
		||||
            {10700, &IFriendService::GetPlayHistoryRegistrationKey, "GetPlayHistoryRegistrationKey"},
 | 
			
		||||
            {10701, nullptr, "GetPlayHistoryRegistrationKeyWithNetworkServiceAccountId"},
 | 
			
		||||
            {10702, nullptr, "AddPlayHistory"},
 | 
			
		||||
            {11000, nullptr, "GetProfileImageUrl"},
 | 
			
		||||
            {20100, nullptr, "GetFriendCount"},
 | 
			
		||||
            {20101, nullptr, "GetNewlyFriendCount"},
 | 
			
		||||
            {20102, nullptr, "GetFriendDetailedInfo"},
 | 
			
		||||
            {20103, nullptr, "SyncFriendList"},
 | 
			
		||||
            {20104, nullptr, "RequestSyncFriendList"},
 | 
			
		||||
            {20110, nullptr, "LoadFriendSetting"},
 | 
			
		||||
            {20200, nullptr, "GetReceivedFriendRequestCount"},
 | 
			
		||||
            {20201, nullptr, "GetFriendRequestList"},
 | 
			
		||||
            {20300, nullptr, "GetFriendCandidateList"},
 | 
			
		||||
            {20301, nullptr, "GetNintendoNetworkIdInfo"},
 | 
			
		||||
            {20302, nullptr, "GetSnsAccountLinkage"},
 | 
			
		||||
            {20303, nullptr, "GetSnsAccountProfile"},
 | 
			
		||||
            {20304, nullptr, "GetSnsAccountFriendList"},
 | 
			
		||||
            {20400, nullptr, "GetBlockedUserList"},
 | 
			
		||||
            {20401, nullptr, "SyncBlockedUserList"},
 | 
			
		||||
            {20500, nullptr, "GetProfileExtraList"},
 | 
			
		||||
            {20501, nullptr, "GetRelationship"},
 | 
			
		||||
            {20600, nullptr, "GetUserPresenceView"},
 | 
			
		||||
            {20700, nullptr, "GetPlayHistoryList"},
 | 
			
		||||
            {20701, nullptr, "GetPlayHistoryStatistics"},
 | 
			
		||||
            {20800, nullptr, "LoadUserSetting"},
 | 
			
		||||
            {20801, nullptr, "SyncUserSetting"},
 | 
			
		||||
            {20900, nullptr, "RequestListSummaryOverlayNotification"},
 | 
			
		||||
            {21000, nullptr, "GetExternalApplicationCatalog"},
 | 
			
		||||
            {22000, nullptr, "GetReceivedFriendInvitationList"},
 | 
			
		||||
            {22001, nullptr, "GetReceivedFriendInvitationDetailedInfo"},
 | 
			
		||||
            {22010, nullptr, "GetReceivedFriendInvitationCountCache"},
 | 
			
		||||
            {30100, nullptr, "DropFriendNewlyFlags"},
 | 
			
		||||
            {30101, nullptr, "DeleteFriend"},
 | 
			
		||||
            {30110, nullptr, "DropFriendNewlyFlag"},
 | 
			
		||||
            {30120, nullptr, "ChangeFriendFavoriteFlag"},
 | 
			
		||||
            {30121, nullptr, "ChangeFriendOnlineNotificationFlag"},
 | 
			
		||||
            {30200, nullptr, "SendFriendRequest"},
 | 
			
		||||
            {30201, nullptr, "SendFriendRequestWithApplicationInfo"},
 | 
			
		||||
            {30202, nullptr, "CancelFriendRequest"},
 | 
			
		||||
            {30203, nullptr, "AcceptFriendRequest"},
 | 
			
		||||
            {30204, nullptr, "RejectFriendRequest"},
 | 
			
		||||
            {30205, nullptr, "ReadFriendRequest"},
 | 
			
		||||
            {30210, nullptr, "GetFacedFriendRequestRegistrationKey"},
 | 
			
		||||
            {30211, nullptr, "AddFacedFriendRequest"},
 | 
			
		||||
            {30212, nullptr, "CancelFacedFriendRequest"},
 | 
			
		||||
            {30213, nullptr, "GetFacedFriendRequestProfileImage"},
 | 
			
		||||
            {30214, nullptr, "GetFacedFriendRequestProfileImageFromPath"},
 | 
			
		||||
            {30215, nullptr, "SendFriendRequestWithExternalApplicationCatalogId"},
 | 
			
		||||
            {30216, nullptr, "ResendFacedFriendRequest"},
 | 
			
		||||
            {30217, nullptr, "SendFriendRequestWithNintendoNetworkIdInfo"},
 | 
			
		||||
            {30300, nullptr, "GetSnsAccountLinkPageUrl"},
 | 
			
		||||
            {30301, nullptr, "UnlinkSnsAccount"},
 | 
			
		||||
            {30400, nullptr, "BlockUser"},
 | 
			
		||||
            {30401, nullptr, "BlockUserWithApplicationInfo"},
 | 
			
		||||
            {30402, nullptr, "UnblockUser"},
 | 
			
		||||
            {30500, nullptr, "GetProfileExtraFromFriendCode"},
 | 
			
		||||
            {30700, nullptr, "DeletePlayHistory"},
 | 
			
		||||
            {30810, nullptr, "ChangePresencePermission"},
 | 
			
		||||
            {30811, nullptr, "ChangeFriendRequestReception"},
 | 
			
		||||
            {30812, nullptr, "ChangePlayLogPermission"},
 | 
			
		||||
            {30820, nullptr, "IssueFriendCode"},
 | 
			
		||||
            {30830, nullptr, "ClearPlayLog"},
 | 
			
		||||
            {30900, nullptr, "SendFriendInvitation"},
 | 
			
		||||
            {30910, nullptr, "ReadFriendInvitation"},
 | 
			
		||||
            {30911, nullptr, "ReadAllFriendInvitations"},
 | 
			
		||||
            {40100, nullptr, "DeleteFriendListCache"},
 | 
			
		||||
            {40400, nullptr, "DeleteBlockedUserListCache"},
 | 
			
		||||
            {49900, nullptr, "DeleteNetworkServiceAccountCache"},
 | 
			
		||||
        };
 | 
			
		||||
    // clang-format on
 | 
			
		||||
 | 
			
		||||
    RegisterHandlers(functions);
 | 
			
		||||
 | 
			
		||||
    completion_event = service_context.CreateEvent("IFriendService:CompletionEvent");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
IFriendService::~IFriendService() {
 | 
			
		||||
    service_context.CloseEvent(completion_event);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void IFriendService::GetCompletionEvent(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
    LOG_DEBUG(Service_Friend, "called");
 | 
			
		||||
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 2, 1};
 | 
			
		||||
    rb.Push(ResultSuccess);
 | 
			
		||||
    rb.PushCopyObjects(completion_event->GetReadableEvent());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void IFriendService::GetBlockedUserListIds(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
    // This is safe to stub, as there should be no adverse consequences from reporting no
 | 
			
		||||
    // blocked users.
 | 
			
		||||
    LOG_WARNING(Service_Friend, "(STUBBED) called");
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 3};
 | 
			
		||||
    rb.Push(ResultSuccess);
 | 
			
		||||
    rb.Push<u32>(0); // Indicates there are no blocked users
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void IFriendService::DeclareCloseOnlinePlaySession(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
    // Stub used by Splatoon 2
 | 
			
		||||
    LOG_WARNING(Service_Friend, "(STUBBED) called");
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 2};
 | 
			
		||||
    rb.Push(ResultSuccess);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void IFriendService::UpdateUserPresence(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
    // Stub used by Retro City Rampage
 | 
			
		||||
    LOG_WARNING(Service_Friend, "(STUBBED) called");
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 2};
 | 
			
		||||
    rb.Push(ResultSuccess);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void IFriendService::GetPlayHistoryRegistrationKey(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
    IPC::RequestParser rp{ctx};
 | 
			
		||||
    const auto local_play = rp.Pop<bool>();
 | 
			
		||||
    const auto uuid = rp.PopRaw<Common::UUID>();
 | 
			
		||||
 | 
			
		||||
    LOG_WARNING(Service_Friend, "(STUBBED) called, local_play={}, uuid=0x{}", local_play,
 | 
			
		||||
                uuid.RawString());
 | 
			
		||||
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 2};
 | 
			
		||||
    rb.Push(ResultSuccess);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void IFriendService::GetFriendList(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
    IPC::RequestParser rp{ctx};
 | 
			
		||||
    const auto friend_offset = rp.Pop<u32>();
 | 
			
		||||
    const auto uuid = rp.PopRaw<Common::UUID>();
 | 
			
		||||
    [[maybe_unused]] const auto filter = rp.PopRaw<SizedFriendFilter>();
 | 
			
		||||
    const auto pid = rp.Pop<u64>();
 | 
			
		||||
    LOG_WARNING(Service_Friend, "(STUBBED) called, offset={}, uuid=0x{}, pid={}", friend_offset,
 | 
			
		||||
                uuid.RawString(), pid);
 | 
			
		||||
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 3};
 | 
			
		||||
    rb.Push(ResultSuccess);
 | 
			
		||||
 | 
			
		||||
    rb.Push<u32>(0); // Friend count
 | 
			
		||||
    // TODO(ogniK): Return a buffer of u64s which are the "NetworkServiceAccountId"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void IFriendService::CheckFriendListAvailability(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
    IPC::RequestParser rp{ctx};
 | 
			
		||||
    const auto uuid{rp.PopRaw<Common::UUID>()};
 | 
			
		||||
 | 
			
		||||
    LOG_WARNING(Service_Friend, "(STUBBED) called, uuid=0x{}", uuid.RawString());
 | 
			
		||||
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 3};
 | 
			
		||||
    rb.Push(ResultSuccess);
 | 
			
		||||
    rb.Push(true);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace Service::Friend
 | 
			
		||||
							
								
								
									
										31
									
								
								src/core/hle/service/friend/friend_service.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								src/core/hle/service/friend/friend_service.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
			
		||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
 | 
			
		||||
// SPDX-License-Identifier: GPL-2.0-or-later
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "core/hle/service/friend/friend.h"
 | 
			
		||||
#include "core/hle/service/kernel_helpers.h"
 | 
			
		||||
#include "core/hle/service/service.h"
 | 
			
		||||
 | 
			
		||||
namespace Service::Friend {
 | 
			
		||||
 | 
			
		||||
class IFriendService final : public ServiceFramework<IFriendService> {
 | 
			
		||||
public:
 | 
			
		||||
    explicit IFriendService(Core::System& system_);
 | 
			
		||||
    ~IFriendService() override;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    void GetCompletionEvent(Kernel::HLERequestContext& ctx);
 | 
			
		||||
    void GetFriendList(Kernel::HLERequestContext& ctx);
 | 
			
		||||
    void CheckFriendListAvailability(Kernel::HLERequestContext& ctx);
 | 
			
		||||
    void GetBlockedUserListIds(Kernel::HLERequestContext& ctx);
 | 
			
		||||
    void DeclareCloseOnlinePlaySession(Kernel::HLERequestContext& ctx);
 | 
			
		||||
    void UpdateUserPresence(Kernel::HLERequestContext& ctx);
 | 
			
		||||
    void GetPlayHistoryRegistrationKey(Kernel::HLERequestContext& ctx);
 | 
			
		||||
 | 
			
		||||
    KernelHelpers::ServiceContext service_context;
 | 
			
		||||
 | 
			
		||||
    Kernel::KEvent* completion_event;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace Service::Friend
 | 
			
		||||
							
								
								
									
										46
									
								
								src/core/hle/service/friend/friend_types.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								src/core/hle/service/friend/friend_types.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
			
		||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
 | 
			
		||||
// SPDX-License-Identifier: GPL-2.0-or-later
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <array>
 | 
			
		||||
#include "common/common_types.h"
 | 
			
		||||
 | 
			
		||||
namespace Service::Friend {
 | 
			
		||||
 | 
			
		||||
enum class PresenceFilter : u32 {
 | 
			
		||||
    None = 0,
 | 
			
		||||
    Online = 1,
 | 
			
		||||
    OnlinePlay = 2,
 | 
			
		||||
    OnlineOrOnlinePlay = 3,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct SizedFriendFilter {
 | 
			
		||||
    PresenceFilter presence;
 | 
			
		||||
    u8 is_favorite;
 | 
			
		||||
    u8 same_app;
 | 
			
		||||
    u8 same_app_played;
 | 
			
		||||
    u8 arbitary_app_played;
 | 
			
		||||
    u64 group_id;
 | 
			
		||||
};
 | 
			
		||||
static_assert(sizeof(SizedFriendFilter) == 0x10, "SizedFriendFilter is an invalid size");
 | 
			
		||||
 | 
			
		||||
enum class NotificationTypes : u32 {
 | 
			
		||||
    HasUpdatedFriendsList = 0x65,
 | 
			
		||||
    HasReceivedFriendRequest = 0x1,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct SizedNotificationInfo {
 | 
			
		||||
    NotificationTypes notification_type;
 | 
			
		||||
    INSERT_PADDING_WORDS(
 | 
			
		||||
        1); // TODO(ogniK): This doesn't seem to be used within any IPC returns as of now
 | 
			
		||||
    u64_le account_id;
 | 
			
		||||
};
 | 
			
		||||
static_assert(sizeof(SizedNotificationInfo) == 0x10, "SizedNotificationInfo is an incorrect size");
 | 
			
		||||
 | 
			
		||||
struct States {
 | 
			
		||||
    bool has_updated_friends;
 | 
			
		||||
    bool has_received_friend_request;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace Service::Friend
 | 
			
		||||
							
								
								
									
										83
									
								
								src/core/hle/service/friend/notification_service.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								src/core/hle/service/friend/notification_service.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,83 @@
 | 
			
		||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
 | 
			
		||||
// SPDX-License-Identifier: GPL-2.0-or-later
 | 
			
		||||
 | 
			
		||||
#include "common/logging/log.h"
 | 
			
		||||
#include "core/hle/ipc_helpers.h"
 | 
			
		||||
#include "core/hle/service/friend/friend_results.h"
 | 
			
		||||
#include "core/hle/service/friend/friend_types.h"
 | 
			
		||||
#include "core/hle/service/friend/notification_service.h"
 | 
			
		||||
 | 
			
		||||
namespace Service::Friend {
 | 
			
		||||
 | 
			
		||||
INotificationService::INotificationService(Core::System& system_, Common::UUID uuid_)
 | 
			
		||||
    : ServiceFramework{system_, "INotificationService"}, uuid{uuid_}, service_context{
 | 
			
		||||
                                                                          system_,
 | 
			
		||||
                                                                          "INotificationService"} {
 | 
			
		||||
    // clang-format off
 | 
			
		||||
        static const FunctionInfo functions[] = {
 | 
			
		||||
            {0, &INotificationService::GetEvent, "GetEvent"},
 | 
			
		||||
            {1, &INotificationService::Clear, "Clear"},
 | 
			
		||||
            {2, &INotificationService::Pop, "Pop"}
 | 
			
		||||
        };
 | 
			
		||||
    // clang-format on
 | 
			
		||||
 | 
			
		||||
    RegisterHandlers(functions);
 | 
			
		||||
 | 
			
		||||
    notification_event = service_context.CreateEvent("INotificationService:NotifyEvent");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
INotificationService::~INotificationService() {
 | 
			
		||||
    service_context.CloseEvent(notification_event);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void INotificationService::GetEvent(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
    LOG_DEBUG(Service_Friend, "called");
 | 
			
		||||
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 2, 1};
 | 
			
		||||
    rb.Push(ResultSuccess);
 | 
			
		||||
    rb.PushCopyObjects(notification_event->GetReadableEvent());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void INotificationService::Clear(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
    LOG_DEBUG(Service_Friend, "called");
 | 
			
		||||
    while (!notifications.empty()) {
 | 
			
		||||
        notifications.pop();
 | 
			
		||||
    }
 | 
			
		||||
    std::memset(&states, 0, sizeof(States));
 | 
			
		||||
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 2};
 | 
			
		||||
    rb.Push(ResultSuccess);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void INotificationService::Pop(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
    LOG_DEBUG(Service_Friend, "called");
 | 
			
		||||
 | 
			
		||||
    if (notifications.empty()) {
 | 
			
		||||
        LOG_ERROR(Service_Friend, "No notifications in queue!");
 | 
			
		||||
        IPC::ResponseBuilder rb{ctx, 2};
 | 
			
		||||
        rb.Push(NoNotifications);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const auto notification = notifications.front();
 | 
			
		||||
    notifications.pop();
 | 
			
		||||
 | 
			
		||||
    switch (notification.notification_type) {
 | 
			
		||||
    case NotificationTypes::HasUpdatedFriendsList:
 | 
			
		||||
        states.has_updated_friends = false;
 | 
			
		||||
        break;
 | 
			
		||||
    case NotificationTypes::HasReceivedFriendRequest:
 | 
			
		||||
        states.has_received_friend_request = false;
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        // HOS seems not have an error case for an unknown notification
 | 
			
		||||
        LOG_WARNING(Service_Friend, "Unknown notification {:08X}", notification.notification_type);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 6};
 | 
			
		||||
    rb.Push(ResultSuccess);
 | 
			
		||||
    rb.PushRaw<SizedNotificationInfo>(notification);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace Service::Friend
 | 
			
		||||
							
								
								
									
										32
									
								
								src/core/hle/service/friend/notification_service.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								src/core/hle/service/friend/notification_service.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,32 @@
 | 
			
		||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
 | 
			
		||||
// SPDX-License-Identifier: GPL-2.0-or-later
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
#include <queue>
 | 
			
		||||
 | 
			
		||||
#include "common/uuid.h"
 | 
			
		||||
#include "core/hle/service/friend/friend_types.h"
 | 
			
		||||
#include "core/hle/service/kernel_helpers.h"
 | 
			
		||||
#include "core/hle/service/service.h"
 | 
			
		||||
 | 
			
		||||
namespace Service::Friend {
 | 
			
		||||
 | 
			
		||||
class INotificationService final : public ServiceFramework<INotificationService> {
 | 
			
		||||
public:
 | 
			
		||||
    explicit INotificationService(Core::System& system_, Common::UUID uuid_);
 | 
			
		||||
    ~INotificationService() override;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    void GetEvent(Kernel::HLERequestContext& ctx);
 | 
			
		||||
    void Clear(Kernel::HLERequestContext& ctx);
 | 
			
		||||
    void Pop(Kernel::HLERequestContext& ctx);
 | 
			
		||||
 | 
			
		||||
    Common::UUID uuid;
 | 
			
		||||
    KernelHelpers::ServiceContext service_context;
 | 
			
		||||
 | 
			
		||||
    Kernel::KEvent* notification_event;
 | 
			
		||||
    std::queue<SizedNotificationInfo> notifications;
 | 
			
		||||
    States states{};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace Service::Friend
 | 
			
		||||
		Reference in New Issue
	
	Block a user