Frd Functions

This commit is contained in:
Pirater12 2018-07-22 14:54:42 +05:30
parent 2c1f84406e
commit c902e4ed48
2 changed files with 290 additions and 38 deletions

View File

@ -2,7 +2,7 @@
* @file frd.h * @file frd.h
* @brief Friend Services * @brief Friend Services
*/ */
#pragma once #pragma once
#include <3ds.h> #include <3ds.h>
#define FRIENDS_SCREEN_NAME_SIZE 0x16 // 11 (0x16 because UTF-16) #define FRIENDS_SCREEN_NAME_SIZE 0x16 // 11 (0x16 because UTF-16)
@ -18,38 +18,75 @@ typedef struct
u64 localFriendCode; u64 localFriendCode;
} FriendKey; } FriendKey;
/// Friend Title data
typedef struct
{
u64 tid;
u32 version;
u32 unk;
} TitleData;
/// Structure containing basic Mii information. /// Structure containing basic Mii information.
typedef struct typedef struct
{ {
u32 mii_id; u32 mii_id;
u64 system_id; u64 system_id;
u32 cdate; u32 cdate;
u8 mac[0x6]; u8 mac[0x6];
u16 padding; u16 padding;
u16 misc1; u16 misc1;
u16 mii_name[0xB]; u16 mii_name[0xB];
u8 width; u8 width;
u8 height; u8 height;
u32 misc2; u32 misc2;
u32 unknown1; u32 unknown1;
u32 misc3; u32 misc3;
u32 unknown2; u32 unknown2;
u8 allow_copy; u8 allow_copy;
u8 unknown3[0x7]; u8 unknown3[0x7];
u16 author[0xB]; u16 author[0xB];
} MiiData; } MiiData;
/// Friend profile data /// Friend profile data
typedef struct typedef struct
{ {
u8 region; // The region code for the hardware. u8 region; // The region code for the hardware.
u8 country; // Country code. u8 country; // Country code.
u8 area; // Area code. u8 area; // Area code.
u8 language; // Language code. u8 language; // Language code.
u8 platform; // Platform code. u8 platform; // Platform code.
u32 padding; u32 padding;
} Profile; } Profile;
/// Game Description structure
typedef struct
{
TitleData data;
u16 desc[128];
} GameDescription;
/// Friend Notification Event structure
typedef struct
{
u8 type;
u8 padding3[3];
u32 padding;
FriendKey key;
}NotificationEvent;
/// Enum to use with FRD_GetNotificationEvent
typedef enum
{
selfOnline = 1, // Self went online
selfOffline, // Self went offline
friendOnline, // Friend Went Online
friendPresence, // Friend Presence changed
friendMii, // Friend Mii changed
friendProfile, // Friend Profile changed
friendOffline, // Friend went offline
friendBecameFriend, // Friend registered self as friend
friendInvitaton // Friend Sent invitation
}NotificationTypes;
/// Initializes FRD service. /// Initializes FRD service.
Result frdInit(void); Result frdInit(void);
@ -71,6 +108,12 @@ Result FRDU_IsOnline(bool *state);
/// Logs out of Nintendo's friend server. /// Logs out of Nintendo's friend server.
Result FRD_Logout(void); Result FRD_Logout(void);
/**
* @brief Log in to Nintendo's friend server.
* @param event Event to signal when Login is done.
*/
Result FRD_Login(Handle event);
/** /**
* @brief Gets the current user's friend key. * @brief Gets the current user's friend key.
* @param key Pointer to write the current user's friend key to. * @param key Pointer to write the current user's friend key to.
@ -132,6 +175,38 @@ Result FRD_GetMyComment(char *comment, size_t max_size);
*/ */
Result FRD_GetFriendKeyList(FriendKey *friendKeyList, size_t *num, size_t offset, size_t size); Result FRD_GetFriendKeyList(FriendKey *friendKeyList, size_t *num, size_t offset, size_t size);
/**
* @brief Gets Friends Mii data.
* @param mii Pointer to write Mii data to.
* @param keys Pointer to FriendKeys.
* @param numberOfKeys Number of Friendkeys.
*/
Result FRD_GetFriendMii(MiiData *mii, const FriendKey *keys, size_t numberOfKeys);
/**
* @brief Get a friend's profile data.
* @param profile Pointer to write profile data to.
* @param keys Pointer to FriendKeys.
* @param numberOfKeys Number of FriendKeys.
*/
Result FRD_GetFriendProfile(Profile *profile, const FriendKey *keys, size_t numberOfKeys);
/**
* @brief Get a friend's playing Game.
* @param desc Pointer to write Game Description data to.
* @param keys Pointer to FriendKeys,
* @param numberOfKeys Number Of FriendKeys.
*/
Result FRD_GetFriendPlayingGame(GameDescription *desc, const FriendKey *keys, size_t numberOfKeys);
/**
* @brief Get a friend's favourite Game.
* @param desc Pointer to write Game Description data to.
* @param keys Pointer to FriendKeys,
* @param numberOfKeys Number Of FriendKeys.
*/
Result FRD_GetFriendFavouriteGame(GameDescription *desc, const FriendKey *keys, size_t numberOfKeys);
/** /**
* @brief Determines if the application was started using the join game option in the friends applet. * @brief Determines if the application was started using the join game option in the friends applet.
* @param friendKeyList Pointer to a list of friend keys. * @param friendKeyList Pointer to a list of friend keys.
@ -145,6 +220,20 @@ Result FRD_IsFromFriendList(FriendKey *friendKeyList, bool *isFromList);
*/ */
Result FRD_UpdateGameModeDescription(const char *desc); Result FRD_UpdateGameModeDescription(const char *desc);
/**
* @brief Event which is signaled when friend login states change.
* @param event event which will be signaled.
*/
Result FRD_AttachToEventNotification(Handle event);
/**
* @brief Get Latest Event Notification
* @param event Pointer to write recieved notification event struct to.
* @param size Number of events
* @param recievedNotifCount Number of notification reccieved.
*/
Result FRD_GetEventNotification(NotificationEvent *event, size_t size, u32 *recievedNotifCount);
/** /**
* @brief Returns the friend code using the given principal ID. * @brief Returns the friend code using the given principal ID.
* @param principalId The principal ID being used. * @param principalId The principal ID being used.
@ -154,7 +243,7 @@ Result FRD_PrincipalIdToFriendCode(u32 principalId, u64 *friendCode);
/** /**
* @brief Returns the principal ID using the given friend code. * @brief Returns the principal ID using the given friend code.
* @param friendCode The friend code being used. * @param friendCode The friend code being used.
* @param principalId Pointer to write the principal ID to. * @param principalId Pointer to write the principal ID to.
*/ */
Result FRD_FriendCodeToPrincipalId(u64 friendCode, u32 *principalId); Result FRD_FriendCodeToPrincipalId(u64 friendCode, u32 *principalId);
@ -171,3 +260,17 @@ Result FRD_IsValidFriendCode(u64 friendCode, bool *isValid);
* @param sdkVer The SDK version needed to be used. * @param sdkVer The SDK version needed to be used.
*/ */
Result FRD_SetClientSdkVersion(u32 sdkVer); Result FRD_SetClientSdkVersion(u32 sdkVer);
/**
* @brief Add a Friend online.
* @param event Event signaled when friend is registered.
* @param principalId PrincipalId of the friend to add.
*/
Result FRD_AddFriendOnline(Handle event, u32 principalId);
/**
* @brief Remove a Friend.
* @param principalId PrinipalId of the friend code to remove.
* @param localFriendCode LocalFriendCode of the friend code to remove.
*/
Result FRD_RemoveFriend(u32 principalId, u64 localFriendCode);

View File

@ -6,20 +6,20 @@ static int frdRefCount;
static void frdConvertToUTF8(char* out, const u16* in, size_t max) static void frdConvertToUTF8(char* out, const u16* in, size_t max)
{ {
if (!in || !*in) if (!in || !*in)
{ {
out[0] = 0; out[0] = 0;
return; return;
} }
ssize_t units = utf16_to_utf8((uint8_t*)out, in, max); ssize_t units = utf16_to_utf8((uint8_t*)out, in, max);
if (units < 0) if (units < 0)
{ {
out[0] = 0; out[0] = 0;
return; return;
} }
out[units] = 0; out[units] = 0;
} }
static void frdConvertToUTF16(u16* out, const char* in, size_t max) static void frdConvertToUTF16(u16* out, const char* in, size_t max)
@ -88,13 +88,27 @@ Result FRDU_IsOnline(bool *state)
return (Result)cmdbuf[1]; return (Result)cmdbuf[1];
} }
Result FRD_Login(Handle event)
{
Result ret = 0;
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x03,0,2); // 0x30002
cmdbuf[1] = 0;
cmdbuf[2] = (u32)event;
if (R_FAILED(ret = svcSendSyncRequest(frdHandle))) return ret;
return (Result)cmdbuf[1];
}
Result FRD_Logout(void) Result FRD_Logout(void)
{ {
Result ret = 0; Result ret = 0;
u32 *cmdbuf = getThreadCommandBuffer(); u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x04,0,0); // 0x40000 cmdbuf[0] = IPC_MakeHeader(0x04,0,0); // 0x40000
if (R_FAILED(ret = svcSendSyncRequest(frdHandle))) return ret; if (R_FAILED(ret = svcSendSyncRequest(frdHandle))) return ret;
return (Result)cmdbuf[1]; return (Result)cmdbuf[1];
@ -232,6 +246,79 @@ Result FRD_GetFriendKeyList(FriendKey *friendKeyList, size_t *num, size_t offset
return (Result)cmdbuf[1]; return (Result)cmdbuf[1];
} }
Result FRD_GetFriendMii(MiiData *mii, const FriendKey *keys, size_t numberOfKeys)
{
Result ret = 0;
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x14,1,4); //0x140044
cmdbuf[1] = numberOfKeys;
cmdbuf[2] = (numberOfKeys << 18)|2;
cmdbuf[3] = (u32)keys;
cmdbuf[4] = 0x600 * numberOfKeys | 0xC;
cmdbuf[5] = (u32)mii;
if(R_FAILED(ret = svcSendSyncRequest(frdHandle))) return ret;
return (Result)cmdbuf[1];
}
Result FRD_GetFriendProfile(Profile *profile, const FriendKey *keys, size_t numberOfKeys)
{
Result ret = 0;
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x15,1,2); // 0x150042
cmdbuf[1] = numberOfKeys;
cmdbuf[2] = (numberOfKeys << 18)|2;
cmdbuf[3] = (u32)keys;
u32 *staticbuf = getThreadStaticBuffers();
staticbuf[0] = (numberOfKeys << 17)|2;
staticbuf[1] = (u32)profile;
if(R_FAILED(ret = svcSendSyncRequest(frdHandle))) return ret;
return (Result)cmdbuf[1];
}
Result FRD_GetFriendPlayingGame(GameDescription *desc, const FriendKey *keys, size_t numberOfKeys)
{
Result ret = 0;
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x18,1,4); // 0x180044
cmdbuf[1] = numberOfKeys;
cmdbuf[2] = (numberOfKeys << 18) | 2;
cmdbuf[3] = (u32)keys;
cmdbuf[4] = 0x1100 * numberOfKeys | 0xC;
cmdbuf[5] = (u32)desc;
if (R_FAILED(ret = svcSendSyncRequest(frdHandle))) return ret;
return (Result)cmdbuf[1];
}
Result FRD_GetFriendFavouriteGame(GameDescription *desc, const FriendKey *keys, size_t numberOfKeys)
{
Result ret = 0;
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x19,1,2); // 0x190042
cmdbuf[1] = numberOfKeys;
cmdbuf[2] = (numberOfKeys << 18) | 2;
cmdbuf[3] = (u32)keys;
u32 *staticbuf = getThreadStaticBuffers();
staticbuf[0] = (numberOfKeys << 18) | 2;
staticbuf[1] = (u32)desc;
if(R_FAILED(svcSendSyncRequest(frdHandle))) return ret;
return (Result)cmdbuf[1];
}
Result FRD_IsFromFriendList(FriendKey *friendKeyList, bool *isFromList) Result FRD_IsFromFriendList(FriendKey *friendKeyList, bool *isFromList)
{ {
Result ret = 0; Result ret = 0;
@ -260,12 +347,46 @@ Result FRD_UpdateGameModeDescription(const char *desc)
cmdbuf[0] = IPC_MakeHeader(0x1D,0,2); // 0x1D0002 cmdbuf[0] = IPC_MakeHeader(0x1D,0,2); // 0x1D0002
cmdbuf[1] = 0x400802; cmdbuf[1] = 0x400802;
cmdbuf[2] = (uintptr_t)u16_desc; cmdbuf[2] = (uintptr_t)u16_desc;
if (R_FAILED(ret = svcSendSyncRequest(frdHandle))) return ret; if (R_FAILED(ret = svcSendSyncRequest(frdHandle))) return ret;
return (Result)cmdbuf[1]; return (Result)cmdbuf[1];
} }
Result FRD_AttachToEventNotification(Handle event)
{
Result ret = 0;
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] =IPC_MakeHeader(0x20,0,2); //0x200002;
cmdbuf[1] = 0;
cmdbuf[2] = (u32)event;
if(R_FAILED(ret = svcSendSyncRequest(frdHandle))) return ret;
return (Result)cmdbuf[1];
}
Result FRD_GetEventNotification(NotificationEvent *event, size_t size, u32 *recievedNotifCount)
{
Result ret = 0;
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x22,1,0); //0x220040
cmdbuf[1] = (u32)size;
u32 *staticbuf = getThreadStaticBuffers();
staticbuf[0] = 0x60000 * size | 2;
staticbuf[1] = (u32)event;
if(R_FAILED(ret = svcSendSyncRequest(frdHandle)))
return ret;
*recievedNotifCount = cmdbuf[3];
return (Result)cmdbuf[1];
}
Result FRD_PrincipalIdToFriendCode(u32 principalId, u64 *friendCode) Result FRD_PrincipalIdToFriendCode(u32 principalId, u64 *friendCode)
{ {
Result ret = 0; Result ret = 0;
@ -325,4 +446,32 @@ Result FRD_SetClientSdkVersion(u32 sdkVer)
if (R_FAILED(ret = svcSendSyncRequest(frdHandle))) return ret; if (R_FAILED(ret = svcSendSyncRequest(frdHandle))) return ret;
return (Result)cmdbuf[1]; return (Result)cmdbuf[1];
}
Result FRD_AddFriendOnline(Handle event, u32 principalId)
{
Result ret = 0;
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x406,1,2); //0x4060042;
cmdbuf[1] = principalId;
cmdbuf[2] = 0;
cmdbuf[3] = (u32)event;
if(R_FAILED(ret = svcSendSyncRequest(frdHandle))) return ret;
return (Result)cmdbuf[1];
}
Result FRD_RemoveFriend(u32 principalId, u64 localFriendCode)
{
Result ret = 0;
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x409,4,0); //0x4090100;
cmdbuf[1] = principalId;
cmdbuf[2] = localFriendCode & 0xffffffff;
cmdbuf[3] = (localFriendCode >> 32) & 0xffffffff;
if(R_FAILED(ret = svcSendSyncRequest(frdHandle))) return ret;
return cmdbuf[1];
} }