diff options
| author | TSR Berry <20988865+TSRBerry@users.noreply.github.com> | 2023-04-08 01:22:00 +0200 |
|---|---|---|
| committer | Mary <thog@protonmail.com> | 2023-04-27 23:51:14 +0200 |
| commit | cee712105850ac3385cd0091a923438167433f9f (patch) | |
| tree | 4a5274b21d8b7f938c0d0ce18736d3f2993b11b1 /src/Ryujinx.HLE/HOS/Services/Mii/StaticService | |
| parent | cd124bda587ef09668a971fa1cac1c3f0cfc9f21 (diff) | |
Move solution and projects to src
Diffstat (limited to 'src/Ryujinx.HLE/HOS/Services/Mii/StaticService')
| -rw-r--r-- | src/Ryujinx.HLE/HOS/Services/Mii/StaticService/DatabaseServiceImpl.cs | 266 | ||||
| -rw-r--r-- | src/Ryujinx.HLE/HOS/Services/Mii/StaticService/IDatabaseService.cs | 425 |
2 files changed, 691 insertions, 0 deletions
diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/StaticService/DatabaseServiceImpl.cs b/src/Ryujinx.HLE/HOS/Services/Mii/StaticService/DatabaseServiceImpl.cs new file mode 100644 index 00000000..4b5ed0d0 --- /dev/null +++ b/src/Ryujinx.HLE/HOS/Services/Mii/StaticService/DatabaseServiceImpl.cs @@ -0,0 +1,266 @@ +using Ryujinx.HLE.HOS.Services.Mii.Types; +using Ryujinx.HLE.HOS.Services.Settings; +using System; + +namespace Ryujinx.HLE.HOS.Services.Mii.StaticService +{ + class DatabaseServiceImpl : IDatabaseService + { + private DatabaseImpl _database; + private DatabaseSessionMetadata _metadata; + private bool _isSystem; + + public DatabaseServiceImpl(DatabaseImpl database, bool isSystem, SpecialMiiKeyCode miiKeyCode) + { + _database = database; + _metadata = _database.CreateSessionMetadata(miiKeyCode); + _isSystem = isSystem; + } + + public bool IsDatabaseTestModeEnabled() + { + if (NxSettings.Settings.TryGetValue("mii!is_db_test_mode_enabled", out object isDatabaseTestModeEnabled)) + { + return (bool)isDatabaseTestModeEnabled; + } + + return false; + } + + protected override bool IsUpdated(SourceFlag flag) + { + return _database.IsUpdated(_metadata, flag); + } + + protected override bool IsFullDatabase() + { + return _database.IsFullDatabase(); + } + + protected override uint GetCount(SourceFlag flag) + { + return _database.GetCount(_metadata, flag); + } + + protected override ResultCode Get(SourceFlag flag, out int count, Span<CharInfoElement> elements) + { + return _database.Get(_metadata, flag, out count, elements); + } + + protected override ResultCode Get1(SourceFlag flag, out int count, Span<CharInfo> elements) + { + return _database.Get(_metadata, flag, out count, elements); + } + + protected override ResultCode UpdateLatest(CharInfo oldCharInfo, SourceFlag flag, out CharInfo newCharInfo) + { + newCharInfo = default; + + return _database.UpdateLatest(_metadata, oldCharInfo, flag, newCharInfo); + } + + protected override ResultCode BuildRandom(Age age, Gender gender, Race race, out CharInfo charInfo) + { + if (age > Age.All || gender > Gender.All || race > Race.All) + { + charInfo = default; + + return ResultCode.InvalidArgument; + } + + _database.BuildRandom(age, gender, race, out charInfo); + + return ResultCode.Success; + } + + protected override ResultCode BuildDefault(uint index, out CharInfo charInfo) + { + if (index >= DefaultMii.TableLength) + { + charInfo = default; + + return ResultCode.InvalidArgument; + } + + _database.BuildDefault(index, out charInfo); + + return ResultCode.Success; + } + + protected override ResultCode Get2(SourceFlag flag, out int count, Span<StoreDataElement> elements) + { + if (!_isSystem) + { + count = -1; + + return ResultCode.PermissionDenied; + } + + return _database.Get(_metadata, flag, out count, elements); + } + + protected override ResultCode Get3(SourceFlag flag, out int count, Span<StoreData> elements) + { + if (!_isSystem) + { + count = -1; + + return ResultCode.PermissionDenied; + } + + return _database.Get(_metadata, flag, out count, elements); + } + + protected override ResultCode UpdateLatest1(StoreData oldStoreData, SourceFlag flag, out StoreData newStoreData) + { + newStoreData = default; + + if (!_isSystem) + { + return ResultCode.PermissionDenied; + } + + return _database.UpdateLatest(_metadata, oldStoreData, flag, newStoreData); + } + + protected override ResultCode FindIndex(CreateId createId, bool isSpecial, out int index) + { + if (!_isSystem) + { + index = -1; + + return ResultCode.PermissionDenied; + } + + index = _database.FindIndex(createId, isSpecial); + + return ResultCode.Success; + } + + protected override ResultCode Move(CreateId createId, int newIndex) + { + if (!_isSystem) + { + return ResultCode.PermissionDenied; + } + + if (newIndex > 0 && _database.GetCount(_metadata, SourceFlag.Database) > newIndex) + { + return _database.Move(_metadata, newIndex, createId); + } + + return ResultCode.InvalidArgument; + } + + protected override ResultCode AddOrReplace(StoreData storeData) + { + if (!_isSystem) + { + return ResultCode.PermissionDenied; + } + + return _database.AddOrReplace(_metadata, storeData); + } + + protected override ResultCode Delete(CreateId createId) + { + if (!_isSystem) + { + return ResultCode.PermissionDenied; + } + + return _database.Delete(_metadata, createId); + } + + protected override ResultCode DestroyFile() + { + if (!IsDatabaseTestModeEnabled()) + { + return ResultCode.TestModeNotEnabled; + } + + return _database.DestroyFile(_metadata); + } + + protected override ResultCode DeleteFile() + { + if (!IsDatabaseTestModeEnabled()) + { + return ResultCode.TestModeNotEnabled; + } + + return _database.DeleteFile(); + } + + protected override ResultCode Format() + { + if (!IsDatabaseTestModeEnabled()) + { + return ResultCode.TestModeNotEnabled; + } + + _database.Format(_metadata); + + return ResultCode.Success; + } + + protected override ResultCode Import(ReadOnlySpan<byte> data) + { + if (!IsDatabaseTestModeEnabled()) + { + return ResultCode.TestModeNotEnabled; + } + + throw new NotImplementedException(); + } + + protected override ResultCode Export(Span<byte> data) + { + if (!IsDatabaseTestModeEnabled()) + { + return ResultCode.TestModeNotEnabled; + } + + throw new NotImplementedException(); + } + + protected override ResultCode IsBrokenDatabaseWithClearFlag(out bool isBrokenDatabase) + { + if (!_isSystem) + { + isBrokenDatabase = false; + + return ResultCode.PermissionDenied; + } + + isBrokenDatabase = _database.IsBrokenDatabaseWithClearFlag(); + + return ResultCode.Success; + } + + protected override ResultCode GetIndex(CharInfo charInfo, out int index) + { + return _database.GetIndex(_metadata, charInfo, out index); + } + + protected override void SetInterfaceVersion(uint interfaceVersion) + { + _database.SetInterfaceVersion(_metadata, interfaceVersion); + } + + protected override ResultCode Convert(Ver3StoreData ver3StoreData, out CharInfo charInfo) + { + throw new NotImplementedException(); + } + + protected override ResultCode ConvertCoreDataToCharInfo(CoreData coreData, out CharInfo charInfo) + { + return _database.ConvertCoreDataToCharInfo(coreData, out charInfo); + } + + protected override ResultCode ConvertCharInfoToCoreData(CharInfo charInfo, out CoreData coreData) + { + return _database.ConvertCharInfoToCoreData(charInfo, out coreData); + } + } +} diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/StaticService/IDatabaseService.cs b/src/Ryujinx.HLE/HOS/Services/Mii/StaticService/IDatabaseService.cs new file mode 100644 index 00000000..e95364be --- /dev/null +++ b/src/Ryujinx.HLE/HOS/Services/Mii/StaticService/IDatabaseService.cs @@ -0,0 +1,425 @@ +using Ryujinx.Common; +using Ryujinx.HLE.HOS.Ipc; +using Ryujinx.HLE.HOS.Services.Mii.Types; +using System; +using System.Runtime.InteropServices; + +namespace Ryujinx.HLE.HOS.Services.Mii.StaticService +{ + abstract class IDatabaseService : IpcService + { + [CommandCmif(0)] + // IsUpdated(SourceFlag flag) -> bool + public ResultCode IsUpdated(ServiceCtx context) + { + SourceFlag flag = (SourceFlag)context.RequestData.ReadInt32(); + + context.ResponseData.Write(IsUpdated(flag)); + + return ResultCode.Success; + } + + [CommandCmif(1)] + // IsFullDatabase() -> bool + public ResultCode IsFullDatabase(ServiceCtx context) + { + context.ResponseData.Write(IsFullDatabase()); + + return ResultCode.Success; + } + + [CommandCmif(2)] + // GetCount(SourceFlag flag) -> u32 + public ResultCode GetCount(ServiceCtx context) + { + SourceFlag flag = (SourceFlag)context.RequestData.ReadInt32(); + + context.ResponseData.Write(GetCount(flag)); + + return ResultCode.Success; + } + + [CommandCmif(3)] + // Get(SourceFlag flag) -> (s32 count, buffer<nn::mii::CharInfoRawElement, 6>) + public ResultCode Get(ServiceCtx context) + { + SourceFlag flag = (SourceFlag)context.RequestData.ReadInt32(); + + IpcBuffDesc outputBuffer = context.Request.ReceiveBuff[0]; + + Span<CharInfoElement> elementsSpan = CreateSpanFromBuffer<CharInfoElement>(context, outputBuffer, true); + + ResultCode result = Get(flag, out int count, elementsSpan); + + elementsSpan = elementsSpan.Slice(0, count); + + context.ResponseData.Write(count); + + WriteSpanToBuffer(context, outputBuffer, elementsSpan); + + return result; + } + + [CommandCmif(4)] + // Get1(SourceFlag flag) -> (s32 count, buffer<nn::mii::CharInfo, 6>) + public ResultCode Get1(ServiceCtx context) + { + SourceFlag flag = (SourceFlag)context.RequestData.ReadInt32(); + + IpcBuffDesc outputBuffer = context.Request.ReceiveBuff[0]; + + Span<CharInfo> elementsSpan = CreateSpanFromBuffer<CharInfo>(context, outputBuffer, true); + + ResultCode result = Get1(flag, out int count, elementsSpan); + + elementsSpan = elementsSpan.Slice(0, count); + + context.ResponseData.Write(count); + + WriteSpanToBuffer(context, outputBuffer, elementsSpan); + + return result; + } + + [CommandCmif(5)] + // UpdateLatest(nn::mii::CharInfo old_char_info, SourceFlag flag) -> nn::mii::CharInfo + public ResultCode UpdateLatest(ServiceCtx context) + { + CharInfo oldCharInfo = context.RequestData.ReadStruct<CharInfo>(); + SourceFlag flag = (SourceFlag)context.RequestData.ReadInt32(); + + ResultCode result = UpdateLatest(oldCharInfo, flag, out CharInfo newCharInfo); + + context.ResponseData.WriteStruct(newCharInfo); + + return result; + } + + [CommandCmif(6)] + // BuildRandom(Age age, Gender gender, Race race) -> nn::mii::CharInfo + public ResultCode BuildRandom(ServiceCtx context) + { + Age age = (Age)context.RequestData.ReadInt32(); + Gender gender = (Gender)context.RequestData.ReadInt32(); + Race race = (Race)context.RequestData.ReadInt32(); + + ResultCode result = BuildRandom(age, gender, race, out CharInfo charInfo); + + context.ResponseData.WriteStruct(charInfo); + + return result; + } + + [CommandCmif(7)] + // BuildDefault(u32 index) -> nn::mii::CharInfoRaw + public ResultCode BuildDefault(ServiceCtx context) + { + uint index = context.RequestData.ReadUInt32(); + + ResultCode result = BuildDefault(index, out CharInfo charInfo); + + context.ResponseData.WriteStruct(charInfo); + + return result; + } + + [CommandCmif(8)] + // Get2(SourceFlag flag) -> (u32 count, buffer<nn::mii::StoreDataElement, 6>) + public ResultCode Get2(ServiceCtx context) + { + SourceFlag flag = (SourceFlag)context.RequestData.ReadInt32(); + + IpcBuffDesc outputBuffer = context.Request.ReceiveBuff[0]; + + Span<StoreDataElement> elementsSpan = CreateSpanFromBuffer<StoreDataElement>(context, outputBuffer, true); + + ResultCode result = Get2(flag, out int count, elementsSpan); + + elementsSpan = elementsSpan.Slice(0, count); + + context.ResponseData.Write(count); + + WriteSpanToBuffer(context, outputBuffer, elementsSpan); + + return result; + } + + [CommandCmif(9)] + // Get3(SourceFlag flag) -> (u32 count, buffer<nn::mii::StoreData, 6>) + public ResultCode Get3(ServiceCtx context) + { + SourceFlag flag = (SourceFlag)context.RequestData.ReadInt32(); + + IpcBuffDesc outputBuffer = context.Request.ReceiveBuff[0]; + + Span<StoreData> elementsSpan = CreateSpanFromBuffer<StoreData>(context, outputBuffer, true); + + ResultCode result = Get3(flag, out int count, elementsSpan); + + elementsSpan = elementsSpan.Slice(0, count); + + context.ResponseData.Write(count); + + WriteSpanToBuffer(context, outputBuffer, elementsSpan); + + return result; + } + + [CommandCmif(10)] + // UpdateLatest1(nn::mii::StoreData old_store_data, SourceFlag flag) -> nn::mii::StoreData + public ResultCode UpdateLatest1(ServiceCtx context) + { + StoreData oldStoreData = context.RequestData.ReadStruct<StoreData>(); + SourceFlag flag = (SourceFlag)context.RequestData.ReadInt32(); + + ResultCode result = UpdateLatest1(oldStoreData, flag, out StoreData newStoreData); + + context.ResponseData.WriteStruct(newStoreData); + + return result; + } + + [CommandCmif(11)] + // FindIndex(nn::mii::CreateId create_id, bool is_special) -> s32 + public ResultCode FindIndex(ServiceCtx context) + { + CreateId createId = context.RequestData.ReadStruct<CreateId>(); + bool isSpecial = context.RequestData.ReadBoolean(); + + ResultCode result = FindIndex(createId, isSpecial, out int index); + + context.ResponseData.Write(index); + + return result; + } + + [CommandCmif(12)] + // Move(nn::mii::CreateId create_id, s32 new_index) + public ResultCode Move(ServiceCtx context) + { + CreateId createId = context.RequestData.ReadStruct<CreateId>(); + int newIndex = context.RequestData.ReadInt32(); + + return Move(createId, newIndex); + } + + [CommandCmif(13)] + // AddOrReplace(nn::mii::StoreData store_data) + public ResultCode AddOrReplace(ServiceCtx context) + { + StoreData storeData = context.RequestData.ReadStruct<StoreData>(); + + return AddOrReplace(storeData); + } + + [CommandCmif(14)] + // Delete(nn::mii::CreateId create_id) + public ResultCode Delete(ServiceCtx context) + { + CreateId createId = context.RequestData.ReadStruct<CreateId>(); + + return Delete(createId); + } + + [CommandCmif(15)] + // DestroyFile() + public ResultCode DestroyFile(ServiceCtx context) + { + return DestroyFile(); + } + + [CommandCmif(16)] + // DeleteFile() + public ResultCode DeleteFile(ServiceCtx context) + { + return DeleteFile(); + } + + [CommandCmif(17)] + // Format() + public ResultCode Format(ServiceCtx context) + { + return Format(); + } + + [CommandCmif(18)] + // Import(buffer<bytes, 5>) + public ResultCode Import(ServiceCtx context) + { + ReadOnlySpan<byte> data = CreateByteSpanFromBuffer(context, context.Request.SendBuff[0], false); + + return Import(data); + } + + [CommandCmif(19)] + // Export() -> buffer<bytes, 6> + public ResultCode Export(ServiceCtx context) + { + IpcBuffDesc outputBuffer = context.Request.ReceiveBuff[0]; + + Span<byte> data = CreateByteSpanFromBuffer(context, outputBuffer, true); + + ResultCode result = Export(data); + + context.Memory.Write(outputBuffer.Position, data.ToArray()); + + return result; + } + + [CommandCmif(20)] + // IsBrokenDatabaseWithClearFlag() -> bool + public ResultCode IsBrokenDatabaseWithClearFlag(ServiceCtx context) + { + ResultCode result = IsBrokenDatabaseWithClearFlag(out bool isBrokenDatabase); + + context.ResponseData.Write(isBrokenDatabase); + + return result; + } + + [CommandCmif(21)] + // GetIndex(nn::mii::CharInfo char_info) -> s32 + public ResultCode GetIndex(ServiceCtx context) + { + CharInfo charInfo = context.RequestData.ReadStruct<CharInfo>(); + + ResultCode result = GetIndex(charInfo, out int index); + + context.ResponseData.Write(index); + + return result; + } + + [CommandCmif(22)] // 5.0.0+ + // SetInterfaceVersion(u32 version) + public ResultCode SetInterfaceVersion(ServiceCtx context) + { + uint interfaceVersion = context.RequestData.ReadUInt32(); + + SetInterfaceVersion(interfaceVersion); + + return ResultCode.Success; + } + + [CommandCmif(23)] // 5.0.0+ + // Convert(nn::mii::Ver3StoreData ver3_store_data) -> nn::mii::CharInfo + public ResultCode Convert(ServiceCtx context) + { + Ver3StoreData ver3StoreData = context.RequestData.ReadStruct<Ver3StoreData>(); + + ResultCode result = Convert(ver3StoreData, out CharInfo charInfo); + + context.ResponseData.WriteStruct(charInfo); + + return result; + } + + [CommandCmif(24)] // 7.0.0+ + // ConvertCoreDataToCharInfo(nn::mii::CoreData core_data) -> nn::mii::CharInfo + public ResultCode ConvertCoreDataToCharInfo(ServiceCtx context) + { + CoreData coreData = context.RequestData.ReadStruct<CoreData>(); + + ResultCode result = ConvertCoreDataToCharInfo(coreData, out CharInfo charInfo); + + context.ResponseData.WriteStruct(charInfo); + + return result; + } + + [CommandCmif(25)] // 7.0.0+ + // ConvertCharInfoToCoreData(nn::mii::CharInfo char_info) -> nn::mii::CoreData + public ResultCode ConvertCharInfoToCoreData(ServiceCtx context) + { + CharInfo charInfo = context.RequestData.ReadStruct<CharInfo>(); + + ResultCode result = ConvertCharInfoToCoreData(charInfo, out CoreData coreData); + + context.ResponseData.WriteStruct(coreData); + + return result; + } + + private Span<byte> CreateByteSpanFromBuffer(ServiceCtx context, IpcBuffDesc ipcBuff, bool isOutput) + { + byte[] rawData; + + if (isOutput) + { + rawData = new byte[ipcBuff.Size]; + } + else + { + rawData = new byte[ipcBuff.Size]; + + context.Memory.Read(ipcBuff.Position, rawData); + } + + return new Span<byte>(rawData); + } + + private Span<T> CreateSpanFromBuffer<T>(ServiceCtx context, IpcBuffDesc ipcBuff, bool isOutput) where T: unmanaged + { + return MemoryMarshal.Cast<byte, T>(CreateByteSpanFromBuffer(context, ipcBuff, isOutput)); + } + + private void WriteSpanToBuffer<T>(ServiceCtx context, IpcBuffDesc ipcBuff, Span<T> span) where T: unmanaged + { + Span<byte> rawData = MemoryMarshal.Cast<T, byte>(span); + + context.Memory.Write(ipcBuff.Position, rawData); + } + + protected abstract bool IsUpdated(SourceFlag flag); + + protected abstract bool IsFullDatabase(); + + protected abstract uint GetCount(SourceFlag flag); + + protected abstract ResultCode Get(SourceFlag flag, out int count, Span<CharInfoElement> elements); + + protected abstract ResultCode Get1(SourceFlag flag, out int count, Span<CharInfo> elements); + + protected abstract ResultCode UpdateLatest(CharInfo oldCharInfo, SourceFlag flag, out CharInfo newCharInfo); + + protected abstract ResultCode BuildRandom(Age age, Gender gender, Race race, out CharInfo charInfo); + + protected abstract ResultCode BuildDefault(uint index, out CharInfo charInfo); + + protected abstract ResultCode Get2(SourceFlag flag, out int count, Span<StoreDataElement> elements); + + protected abstract ResultCode Get3(SourceFlag flag, out int count, Span<StoreData> elements); + + protected abstract ResultCode UpdateLatest1(StoreData oldStoreData, SourceFlag flag, out StoreData newStoreData); + + protected abstract ResultCode FindIndex(CreateId createId, bool isSpecial, out int index); + + protected abstract ResultCode Move(CreateId createId, int newIndex); + + protected abstract ResultCode AddOrReplace(StoreData storeData); + + protected abstract ResultCode Delete(CreateId createId); + + protected abstract ResultCode DestroyFile(); + + protected abstract ResultCode DeleteFile(); + + protected abstract ResultCode Format(); + + protected abstract ResultCode Import(ReadOnlySpan<byte> data); + + protected abstract ResultCode Export(Span<byte> data); + + protected abstract ResultCode IsBrokenDatabaseWithClearFlag(out bool isBrokenDatabase); + + protected abstract ResultCode GetIndex(CharInfo charInfo, out int index); + + protected abstract void SetInterfaceVersion(uint interfaceVersion); + + protected abstract ResultCode Convert(Ver3StoreData ver3StoreData, out CharInfo charInfo); + + protected abstract ResultCode ConvertCoreDataToCharInfo(CoreData coreData, out CharInfo charInfo); + + protected abstract ResultCode ConvertCharInfoToCoreData(CharInfo charInfo, out CoreData coreData); + } +} |
