Fix inconsistencies with UserId (#906)
* Fix inconsistencies with UserId The account user id isn't an UUID. This PR adds a new UserId type with the correct value ordering to avoid mismatch with LibHac's Uid. This also fix an hardcoded value of the UserId. As the userid has been invalid for quite some time (and to avoid forcing users to their recreate saves), the userid has been changed to "00000000000000010000000000000000". Also implement a stub for IApplicationFunctions::GetSaveDataSize. (see the sources for the reason) Fix #626 * Address jd's & Ac_k's comments
This commit is contained in:
parent
f373f870f7
commit
ea14a95524
18 changed files with 172 additions and 72 deletions
|
@ -1,5 +1,4 @@
|
|||
using Ryujinx.HLE.Utilities;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
|
@ -16,14 +15,14 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc
|
|||
_profiles = new ConcurrentDictionary<string, UserProfile>();
|
||||
}
|
||||
|
||||
public void AddUser(UInt128 userId, string name)
|
||||
public void AddUser(UserId userId, string name)
|
||||
{
|
||||
UserProfile profile = new UserProfile(userId, name);
|
||||
|
||||
_profiles.AddOrUpdate(userId.ToString(), profile, (key, old) => profile);
|
||||
}
|
||||
|
||||
public void OpenUser(UInt128 userId)
|
||||
public void OpenUser(UserId userId)
|
||||
{
|
||||
if (_profiles.TryGetValue(userId.ToString(), out UserProfile profile))
|
||||
{
|
||||
|
@ -31,7 +30,7 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc
|
|||
}
|
||||
}
|
||||
|
||||
public void CloseUser(UInt128 userId)
|
||||
public void CloseUser(UserId userId)
|
||||
{
|
||||
if (_profiles.TryGetValue(userId.ToString(), out UserProfile profile))
|
||||
{
|
||||
|
@ -44,7 +43,7 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc
|
|||
return _profiles.Count;
|
||||
}
|
||||
|
||||
internal bool TryGetUser(UInt128 userId, out UserProfile profile)
|
||||
internal bool TryGetUser(UserId userId, out UserProfile profile)
|
||||
{
|
||||
return _profiles.TryGetValue(userId.ToString(), out profile);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
using ARMeilleure.Memory;
|
||||
using Ryujinx.Common;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.HLE.HOS.Services.Arp;
|
||||
using Ryujinx.HLE.Utilities;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Ryujinx.HLE.HOS.Services.Account.Acc
|
||||
|
@ -28,7 +28,7 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc
|
|||
// GetUserExistence(nn::account::Uid) -> bool
|
||||
public ResultCode GetUserExistence(ServiceCtx context)
|
||||
{
|
||||
UInt128 userId = new UInt128(context.RequestData.ReadBytes(0x10));
|
||||
UserId userId = context.RequestData.ReadStruct<UserId>();
|
||||
|
||||
if (userId.IsNull)
|
||||
{
|
||||
|
@ -75,8 +75,8 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc
|
|||
break;
|
||||
}
|
||||
|
||||
context.Memory.WriteInt64(outputPosition + (long)offset, userProfile.UserId.Low);
|
||||
context.Memory.WriteInt64(outputPosition + (long)offset + 8, userProfile.UserId.High);
|
||||
context.Memory.WriteInt64(outputPosition + (long)offset, userProfile.UserId.High);
|
||||
context.Memory.WriteInt64(outputPosition + (long)offset + 8, userProfile.UserId.Low);
|
||||
|
||||
offset += 0x10;
|
||||
}
|
||||
|
@ -97,7 +97,7 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc
|
|||
// GetProfile(nn::account::Uid) -> object<nn::account::profile::IProfile>
|
||||
public ResultCode GetProfile(ServiceCtx context)
|
||||
{
|
||||
UInt128 userId = new UInt128(context.RequestData.ReadBytes(0x10));
|
||||
UserId userId = context.RequestData.ReadStruct<UserId>();
|
||||
|
||||
if (!context.Device.System.State.Account.TryGetUser(userId, out UserProfile userProfile))
|
||||
{
|
||||
|
@ -131,7 +131,7 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc
|
|||
if (context.Device.System.State.Account.GetUserCount() != 1)
|
||||
{
|
||||
// Invalid UserId.
|
||||
new UInt128(0, 0).Write(context.ResponseData);
|
||||
new UserId(0, 0).Write(context.ResponseData);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -191,7 +191,7 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc
|
|||
// GetBaasAccountManagerForApplication(nn::account::Uid) -> object<nn::account::baas::IManagerForApplication>
|
||||
public ResultCode GetBaasAccountManagerForApplication(ServiceCtx context)
|
||||
{
|
||||
UInt128 userId = new UInt128(context.RequestData.ReadBytes(0x10));
|
||||
UserId userId = context.RequestData.ReadStruct<UserId>();
|
||||
|
||||
if (userId.IsNull)
|
||||
{
|
||||
|
@ -220,7 +220,7 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc
|
|||
return ResultCode.InvalidArgument;
|
||||
}
|
||||
|
||||
UInt128 userId = new UInt128(context.RequestData.ReadBytes(0x10));
|
||||
UserId userId = context.RequestData.ReadStruct<UserId>();
|
||||
|
||||
if (userId.IsNull)
|
||||
{
|
||||
|
@ -258,7 +258,7 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc
|
|||
return ResultCode.InvalidArgument;
|
||||
}
|
||||
|
||||
UInt128 userId = new UInt128(context.RequestData.ReadBytes(0x10));
|
||||
UserId userId = context.RequestData.ReadStruct<UserId>();
|
||||
|
||||
if (userId.IsNull)
|
||||
{
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.HLE.HOS.Services.Arp;
|
||||
using Ryujinx.HLE.Utilities;
|
||||
|
||||
namespace Ryujinx.HLE.HOS.Services.Account.Acc
|
||||
{
|
||||
class IManagerForApplication : IpcService
|
||||
{
|
||||
private UInt128 _userId;
|
||||
private UserId _userId;
|
||||
private ApplicationLaunchProperty _applicationLaunchProperty;
|
||||
|
||||
public IManagerForApplication(UInt128 userId, ApplicationLaunchProperty applicationLaunchProperty)
|
||||
public IManagerForApplication(UserId userId, ApplicationLaunchProperty applicationLaunchProperty)
|
||||
{
|
||||
_userId = userId;
|
||||
_applicationLaunchProperty = applicationLaunchProperty;
|
||||
|
|
81
Ryujinx.HLE/HOS/Services/Account/Acc/Types/UserId.cs
Normal file
81
Ryujinx.HLE/HOS/Services/Account/Acc/Types/UserId.cs
Normal file
|
@ -0,0 +1,81 @@
|
|||
using LibHac.Account;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.HLE.HOS.Services.Account.Acc
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct UserId : IEquatable<UserId>
|
||||
{
|
||||
public readonly long High;
|
||||
public readonly long Low;
|
||||
|
||||
public bool IsNull => (Low | High) == 0;
|
||||
|
||||
public UserId(long low, long high)
|
||||
{
|
||||
Low = low;
|
||||
High = high;
|
||||
}
|
||||
|
||||
public UserId(byte[] bytes)
|
||||
{
|
||||
High = BitConverter.ToInt64(bytes, 0);
|
||||
Low = BitConverter.ToInt64(bytes, 8);
|
||||
}
|
||||
|
||||
public UserId(string hex)
|
||||
{
|
||||
if (hex == null || hex.Length != 32 || !hex.All("0123456789abcdefABCDEF".Contains))
|
||||
{
|
||||
throw new ArgumentException("Invalid Hex value!", nameof(hex));
|
||||
}
|
||||
|
||||
Low = Convert.ToInt64(hex.Substring(16), 16);
|
||||
High = Convert.ToInt64(hex.Substring(0, 16), 16);
|
||||
}
|
||||
|
||||
public void Write(BinaryWriter binaryWriter)
|
||||
{
|
||||
binaryWriter.Write(High);
|
||||
binaryWriter.Write(Low);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return High.ToString("x16") + Low.ToString("x16");
|
||||
}
|
||||
|
||||
public static bool operator ==(UserId x, UserId y)
|
||||
{
|
||||
return x.Equals(y);
|
||||
}
|
||||
|
||||
public static bool operator !=(UserId x, UserId y)
|
||||
{
|
||||
return !x.Equals(y);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return obj is UserId userId && Equals(userId);
|
||||
}
|
||||
|
||||
public bool Equals(UserId cmpObj)
|
||||
{
|
||||
return Low == cmpObj.Low && High == cmpObj.High;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashCode.Combine(Low, High);
|
||||
}
|
||||
|
||||
public Uid ToLibHacUid()
|
||||
{
|
||||
return new Uid((ulong)High, (ulong)Low);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,7 +7,7 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc
|
|||
{
|
||||
private static readonly DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
||||
|
||||
public UInt128 UserId { get; private set; }
|
||||
public UserId UserId { get; private set; }
|
||||
|
||||
public string Name { get; private set; }
|
||||
|
||||
|
@ -16,7 +16,7 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc
|
|||
public AccountState AccountState { get; set; }
|
||||
public AccountState OnlinePlayState { get; set; }
|
||||
|
||||
public UserProfile(UInt128 userId, string name)
|
||||
public UserProfile(UserId userId, string name)
|
||||
{
|
||||
UserId = userId;
|
||||
Name = name;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue