diff --git a/Ryujinx.HLE/OsHle/Profile.cs b/Ryujinx.HLE/OsHle/Profile.cs new file mode 100644 index 000000000..80b4487bf --- /dev/null +++ b/Ryujinx.HLE/OsHle/Profile.cs @@ -0,0 +1,8 @@ +namespace Ryujinx.HLE.OsHle +{ + public struct Profile + { + public string Username; + public string UserId; + } +} diff --git a/Ryujinx.HLE/OsHle/Services/Acc/IProfile.cs b/Ryujinx.HLE/OsHle/Services/Acc/IProfile.cs index 24daa3d57..0639b09c2 100644 --- a/Ryujinx.HLE/OsHle/Services/Acc/IProfile.cs +++ b/Ryujinx.HLE/OsHle/Services/Acc/IProfile.cs @@ -1,6 +1,9 @@ +using ChocolArm64.Memory; using Ryujinx.HLE.Logging; using Ryujinx.HLE.OsHle.Ipc; +using Ryujinx.HLE.OsHle.Utilities; using System.Collections.Generic; +using System.Text; namespace Ryujinx.HLE.OsHle.Services.Acc { @@ -14,21 +17,37 @@ namespace Ryujinx.HLE.OsHle.Services.Acc { m_Commands = new Dictionary() { + { 0, Get }, { 1, GetBase } }; } - public long GetBase(ServiceCtx Context) + public long Get(ServiceCtx Context) { Context.Ns.Log.PrintStub(LogClass.ServiceAcc, "Stubbed."); - Context.ResponseData.Write(0L); - Context.ResponseData.Write(0L); - Context.ResponseData.Write(0L); - Context.ResponseData.Write(0L); - Context.ResponseData.Write(0L); - Context.ResponseData.Write(0L); - Context.ResponseData.Write(0L); + long Position = Context.Request.ReceiveBuff[0].Position; + + AMemoryHelper.FillWithZeros(Context.Memory, Position, 0x80); + + Context.Memory.WriteInt32(Position, 0); + Context.Memory.WriteInt32(Position + 4, 1); + Context.Memory.WriteByte(Position + 8, 1); + + return GetBase(Context); + } + + public long GetBase(ServiceCtx Context) + { + ProfileBase ProfileBase = new ProfileBase(Context.Ns.Settings.User); + + Context.ResponseData.Write(ProfileBase.UserId.ToBytes()); + Context.ResponseData.Write(ProfileBase.Timestamp); + + int ByteCount = Encoding.UTF8.GetByteCount(ProfileBase.Username); + byte[] Username = StringUtils.GetFixedLengthBytes(ProfileBase.Username, 0x20, Encoding.UTF8); + + Context.ResponseData.Write(Username); return 0; } diff --git a/Ryujinx.HLE/OsHle/Services/Acc/ProfileBase.cs b/Ryujinx.HLE/OsHle/Services/Acc/ProfileBase.cs new file mode 100644 index 000000000..69914a86e --- /dev/null +++ b/Ryujinx.HLE/OsHle/Services/Acc/ProfileBase.cs @@ -0,0 +1,52 @@ +using Ryujinx.HLE.OsHle.Utilities; +using System; +using System.Linq; + +namespace Ryujinx.HLE.OsHle.Services.Acc +{ + struct ProfileBase + { + public UserId UserId; + public long Timestamp; + public string Username; + + public ProfileBase(Profile User) + { + UserId = new UserId(User.UserId); + Username = User.Username; + Timestamp = ((DateTimeOffset)DateTime.Today).ToUnixTimeSeconds(); + } + } + + struct UserId + { + private readonly ulong LowBytes; + private readonly ulong HighBytes; + + public UserId(string UserIdHex) + { + if (UserIdHex == null || UserIdHex.Length != 32 || !UserIdHex.All("0123456789abcdefABCDEF".Contains)) + { + throw new ArgumentException("UserId is not a valid Hex string", "UserIdHex"); + } + + byte[] HexBytes = StringUtils.HexToBytes(UserIdHex); + + LowBytes = BitConverter.ToUInt64(HexBytes, 8); + + Array.Resize(ref HexBytes, 8); + + HighBytes = BitConverter.ToUInt64(HexBytes, 0); + } + + public byte[] ToBytes() + { + return BitConverter.GetBytes(HighBytes).Concat(BitConverter.GetBytes(LowBytes)).ToArray(); + } + + public override string ToString() + { + return BitConverter.ToString(ToBytes()).ToLower().Replace("-", string.Empty); + } + } +} diff --git a/Ryujinx.HLE/OsHle/Utilities/StringUtils.cs b/Ryujinx.HLE/OsHle/Utilities/StringUtils.cs new file mode 100644 index 000000000..b0117f836 --- /dev/null +++ b/Ryujinx.HLE/OsHle/Utilities/StringUtils.cs @@ -0,0 +1,52 @@ +using System; +using System.Globalization; +using System.Linq; +using System.Text; + +namespace Ryujinx.HLE.OsHle.Utilities +{ + static class StringUtils + { + public static byte[] GetFixedLengthBytes(string InputString, int Size, Encoding Encoding) + { + InputString = InputString + "\0"; + + int ByteCount = Encoding.GetByteCount(InputString); + + byte[] Output = new byte[Size]; + + if (ByteCount < Size) + { + Encoding.GetBytes(InputString, 0, InputString.Length, Output, Size - ByteCount); + } + else + { + int NullSize = Encoding.GetByteCount("\0"); + + Output = Encoding.GetBytes(InputString); + + Array.Resize(ref Output, Size - NullSize); + + Output = Output.Concat(Encoding.GetBytes("\0")).ToArray(); + } + + return Output; + } + + public static byte[] HexToBytes(string HexString) + { + //Ignore last charactor if HexLength % 2 != 0 + int BytesInHex = HexString.Length / 2; + + byte[] Output = new byte[BytesInHex]; + + for (int Index = 0; Index < BytesInHex; Index++) + { + Output[Index] = byte.Parse(HexString.Substring(Index * 2, 2), + NumberStyles.HexNumber); + } + + return Output; + } + } +} diff --git a/Ryujinx.HLE/Settings/SystemSettings.cs b/Ryujinx.HLE/Settings/SystemSettings.cs index 555e83bba..fb94807e3 100644 --- a/Ryujinx.HLE/Settings/SystemSettings.cs +++ b/Ryujinx.HLE/Settings/SystemSettings.cs @@ -1,7 +1,11 @@ +using System.Collections.Generic; +using Ryujinx.HLE.OsHle; + namespace Ryujinx.HLE.Settings { public class SystemSettings { - public ColorSet ThemeColor; + public Profile User { get; set; } + public ColorSet ThemeColor { get; set; } } } diff --git a/Ryujinx.HLE/Switch.cs b/Ryujinx.HLE/Switch.cs index a80ca86c1..b219d7740 100644 --- a/Ryujinx.HLE/Switch.cs +++ b/Ryujinx.HLE/Switch.cs @@ -67,6 +67,12 @@ namespace Ryujinx.HLE Os.FontSharedMem.MemoryMapped += Font.ShMemMap; Os.FontSharedMem.MemoryUnmapped += Font.ShMemUnmap; + + Settings.User = new Profile() + { + Username = "Ryujinx", + UserId = "000123456789abcdef09876543210000" + }; } public void LoadCart(string ExeFsDir, string RomFsFile = null) @@ -109,4 +115,4 @@ namespace Ryujinx.HLE } } } -} \ No newline at end of file +} diff --git a/Ryujinx/Config.cs b/Ryujinx/Config.cs index b63455ee8..095682172 100644 --- a/Ryujinx/Config.cs +++ b/Ryujinx/Config.cs @@ -1,4 +1,4 @@ -using Ryujinx.UI.Input; +using Ryujinx.UI.Input; using Ryujinx.HLE.Logging; using System; using System.Globalization; @@ -180,4 +180,4 @@ namespace Ryujinx return Values.TryGetValue(Name, out string Value) ? Value : null; } } -} +} \ No newline at end of file diff --git a/Ryujinx/Ryujinx.conf b/Ryujinx/Ryujinx.conf index 3225acc34..6e15a6ac2 100644 --- a/Ryujinx/Ryujinx.conf +++ b/Ryujinx/Ryujinx.conf @@ -85,4 +85,4 @@ Controls_Right_JoyConController_Button_R = RShoulder Controls_Right_JoyConController_Button_ZR = RTrigger Controls_Left_JoyConController_Stick = LJoystick -Controls_Right_JoyConController_Stick = RJoystick +Controls_Right_JoyConController_Stick = RJoystick \ No newline at end of file