forked from Mirror/Ryujinx
friend: Implement GetPlayHistoryRegistrationKey (#1424)
* friend: Implement GetPlayHistoryRegistrationKey This implement IServiceCreator::GetPlayHistoryRegistrationKey call accordingly to RE. Close #1110 * Fix comments * Fix guid and comment some codes * Improve guid casting and remove unused vars
This commit is contained in:
parent
3c099454ca
commit
1457ab5456
2 changed files with 82 additions and 0 deletions
|
@ -1,9 +1,14 @@
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
|
using Ryujinx.Common.Memory;
|
||||||
|
using Ryujinx.Common.Utilities;
|
||||||
using Ryujinx.HLE.HOS.Services.Account.Acc;
|
using Ryujinx.HLE.HOS.Services.Account.Acc;
|
||||||
using Ryujinx.HLE.HOS.Services.Friend.ServiceCreator.FriendService;
|
using Ryujinx.HLE.HOS.Services.Friend.ServiceCreator.FriendService;
|
||||||
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
|
||||||
namespace Ryujinx.HLE.HOS.Services.Friend.ServiceCreator
|
namespace Ryujinx.HLE.HOS.Services.Friend.ServiceCreator
|
||||||
{
|
{
|
||||||
|
@ -186,5 +191,66 @@ namespace Ryujinx.HLE.HOS.Services.Friend.ServiceCreator
|
||||||
|
|
||||||
return ResultCode.Success;
|
return ResultCode.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Command(10700)]
|
||||||
|
// nn::friends::GetPlayHistoryRegistrationKey(b8 unknown, nn::account::Uid) -> buffer<nn::friends::PlayHistoryRegistrationKey, 0x1a>
|
||||||
|
public ResultCode GetPlayHistoryRegistrationKey(ServiceCtx context)
|
||||||
|
{
|
||||||
|
bool unknownBool = context.RequestData.ReadBoolean();
|
||||||
|
UserId userId = context.RequestData.ReadStruct<UserId>();
|
||||||
|
|
||||||
|
long bufferPosition = context.Request.RecvListBuff[0].Position;
|
||||||
|
|
||||||
|
if (userId.IsNull)
|
||||||
|
{
|
||||||
|
return ResultCode.InvalidArgument;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: Calls nn::friends::detail::service::core::PlayHistoryManager::GetInstance and stores the instance.
|
||||||
|
|
||||||
|
byte[] randomBytes = new byte[8];
|
||||||
|
Random random = new Random();
|
||||||
|
|
||||||
|
random.NextBytes(randomBytes);
|
||||||
|
|
||||||
|
// NOTE: Calls nn::friends::detail::service::core::UuidManager::GetInstance and stores the instance.
|
||||||
|
// Then call nn::friends::detail::service::core::AccountStorageManager::GetInstance and store the instance.
|
||||||
|
// Then it checks if an Uuid is already stored for the UserId, if not it generates a random Uuid.
|
||||||
|
// And store it in the savedata 8000000000000080 in the friends:/uid.bin file.
|
||||||
|
|
||||||
|
Array16<byte> randomGuid = new Array16<byte>();
|
||||||
|
|
||||||
|
Guid.NewGuid().ToByteArray().AsSpan().CopyTo(randomGuid.ToSpan());
|
||||||
|
|
||||||
|
PlayHistoryRegistrationKey playHistoryRegistrationKey = new PlayHistoryRegistrationKey
|
||||||
|
{
|
||||||
|
Type = 0x101,
|
||||||
|
KeyIndex = (byte)(randomBytes[0] & 7),
|
||||||
|
UserIdBool = 0, // TODO: Find it.
|
||||||
|
UnknownBool = (byte)(unknownBool ? 1 : 0), // TODO: Find it.
|
||||||
|
Reserved = new Array11<byte>(),
|
||||||
|
Uuid = randomGuid
|
||||||
|
};
|
||||||
|
|
||||||
|
ReadOnlySpan<byte> playHistoryRegistrationKeyBuffer = SpanHelpers.AsByteSpan(ref playHistoryRegistrationKey);
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
NOTE: The service uses the KeyIndex to get a random key from a keys buffer (since the key index is stored in the returned buffer).
|
||||||
|
We currently don't support play history and online services so we can use a blank key for now.
|
||||||
|
Code for reference:
|
||||||
|
|
||||||
|
byte[] hmacKey = new byte[0x20];
|
||||||
|
|
||||||
|
HMACSHA256 hmacSha256 = new HMACSHA256(hmacKey);
|
||||||
|
byte[] hmacHash = hmacSha256.ComputeHash(playHistoryRegistrationKeyBuffer);
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
context.Memory.Write((ulong)bufferPosition, playHistoryRegistrationKeyBuffer);
|
||||||
|
context.Memory.Write((ulong)bufferPosition + 0x20, new byte[0x20]); // HmacHash
|
||||||
|
|
||||||
|
return ResultCode.Success;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
using Ryujinx.Common.Memory;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace Ryujinx.HLE.HOS.Services.Friend.ServiceCreator
|
||||||
|
{
|
||||||
|
[StructLayout(LayoutKind.Sequential, Size = 0x20)]
|
||||||
|
struct PlayHistoryRegistrationKey
|
||||||
|
{
|
||||||
|
public ushort Type;
|
||||||
|
public byte KeyIndex;
|
||||||
|
public byte UserIdBool;
|
||||||
|
public byte UnknownBool;
|
||||||
|
public Array11<byte> Reserved;
|
||||||
|
public Array16<byte> Uuid;
|
||||||
|
}
|
||||||
|
}
|
Reference in a new issue