mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2026-05-13 08:45:47 +00:00
- Fixes `StoreData` layout/update handling so `UpdateLatest` returns the stored Mii data correctly. - Implements `IDatabaseService.Append` (https://switchbrew.org/wiki/Shared_Database_services#IDatabaseService) Also adds regression tests for `UpdateLatest` and `Append`. (Might) fix Mario Kart 8 Deluxe crashing on first boot due to failed Mii verification check (due to custom Mii from emulator), and potentially Tomodachi Life: Living the Dream for the "Import Mii from system" option. Co-authored-by: yell0wsuit <5692900+yell0wsuit@users.noreply.github.com> Reviewed-on: https://git.ryujinx.app/projects/Ryubing/pulls/43
270 lines
7.7 KiB
C#
270 lines
7.7 KiB
C#
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 readonly DatabaseImpl _database;
|
|
private readonly DatabaseSessionMetadata _metadata;
|
|
private readonly 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)
|
|
{
|
|
return _database.UpdateLatest(_metadata, oldCharInfo, flag, out 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)
|
|
{
|
|
if (!_isSystem)
|
|
{
|
|
newStoreData = default;
|
|
|
|
return ResultCode.PermissionDenied;
|
|
}
|
|
|
|
return _database.UpdateLatest(_metadata, oldStoreData, flag, out 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);
|
|
}
|
|
|
|
protected override ResultCode Append(CharInfo charInfo)
|
|
{
|
|
return _database.Append(_metadata, charInfo);
|
|
}
|
|
}
|
|
}
|