diff --git a/include/services/frd.hpp b/include/services/frd.hpp index 17e50bc4..7e56b83e 100644 --- a/include/services/frd.hpp +++ b/include/services/frd.hpp @@ -23,7 +23,9 @@ class FRDService { // Service commands void attachToEventNotification(u32 messagePointer); + void getFriendAttributeFlags(u32 messagePointer); void getFriendKeyList(u32 messagePointer); + void getFriendProfile(u32 messagePointer); void getMyFriendKey(u32 messagePointer); void getMyMii(u32 messagePointer); void getMyPresence(u32 messagePointer); @@ -35,6 +37,15 @@ class FRDService { void setNotificationMask(u32 messagePointer); void updateGameModeDescription(u32 messagePointer); + struct Profile { + u8 region; + u8 country; + u8 area; + u8 language; + u32 unknown; + }; + static_assert(sizeof(Profile) == 8); + public: FRDService(Memory& mem) : mem(mem) {} void reset(); diff --git a/src/core/services/frd.cpp b/src/core/services/frd.cpp index 67683dc1..9ac7049b 100644 --- a/src/core/services/frd.cpp +++ b/src/core/services/frd.cpp @@ -18,6 +18,8 @@ namespace FRDCommands { GetMyScreenName = 0x00090000, GetMyMii = 0x000A0000, GetFriendKeyList = 0x00110080, + GetFriendProfile = 0x00150042, + GetFriendAttributeFlags = 0x00170042, UpdateGameModeDescription = 0x001D0002, }; } @@ -28,7 +30,9 @@ void FRDService::handleSyncRequest(u32 messagePointer) { const u32 command = mem.read32(messagePointer); switch (command) { case FRDCommands::AttachToEventNotification: attachToEventNotification(messagePointer); break; + case FRDCommands::GetFriendAttributeFlags: getFriendAttributeFlags(messagePointer); break; case FRDCommands::GetFriendKeyList: getFriendKeyList(messagePointer); break; + case FRDCommands::GetFriendProfile: getFriendProfile(messagePointer); break; case FRDCommands::GetMyFriendKey: getMyFriendKey(messagePointer); break; case FRDCommands::GetMyMii: getMyMii(messagePointer); break; case FRDCommands::GetMyPresence: getMyPresence(messagePointer); break; @@ -83,6 +87,41 @@ void FRDService::getFriendKeyList(u32 messagePointer) { } } +void FRDService::getFriendProfile(u32 messagePointer) { + log("FRD::GetFriendProfile\n"); + + const u32 count = mem.read32(messagePointer + 4); + const u32 friendKeyList = mem.read32(messagePointer + 12); // Pointer to list of friend keys + const u32 profile = mem.read32(messagePointer + 0x104); // Pointer to friend profile where we'll write info to + + mem.write32(messagePointer, IPC::responseHeader(0x15, 1, 2)); + mem.write32(messagePointer + 4, Result::Success); + + // Clear all profiles + for (u32 i = 0; i < count; i++) { + const u32 pointer = profile + (i * sizeof(Profile)); + for (u32 j = 0; j < sizeof(Profile); j++) { + mem.write8(pointer + j, 0); + } + } +} + +void FRDService::getFriendAttributeFlags(u32 messagePointer) { + log("FRD::GetFriendAttributeFlags\n"); + + const u32 count = mem.read32(messagePointer + 4); + const u32 friendKeyList = mem.read32(messagePointer + 12); // Pointer to list of friend keys + const u32 profile = mem.read32(messagePointer + 0x104); // Pointer to friend profile where we'll write info to + + mem.write32(messagePointer, IPC::responseHeader(0x17, 1, 2)); + mem.write32(messagePointer + 4, Result::Success); + + // Clear flags + for (u32 i = 0; i < count; i++) { + mem.write8(profile + i, 0); + } +} + void FRDService::getMyPresence(u32 messagePointer) { static constexpr u32 presenceSize = 0x12C; // A presence seems to be 12C bytes of data, not sure what it contains log("FRD::GetMyPresence\n");