diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2023-09-27 14:21:26 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-09-27 19:21:26 +0200 |
| commit | 01c2b8097c2d66839105470d82405a12d57d196f (patch) | |
| tree | 466e1a04138bd14ba31a6a0738a46065b6033129 /src/Ryujinx.Horizon/Ngc | |
| parent | 4bd2ca3f0de37c53b3ecc78789a0a8296668235a (diff) | |
Implement NGC service (#5681)
* Implement NGC service
* Use raw byte arrays instead of string for _wordSeparators
* Silence IDE0230 for _wordSeparators
* Try to silence warning about _rangeValuesCount not being read on SparseSet
* Make AcType enum private
* Add abstract methods and one TODO that I forgot
* PR feedback
* More PR feedback
* More PR feedback
Diffstat (limited to 'src/Ryujinx.Horizon/Ngc')
| -rw-r--r-- | src/Ryujinx.Horizon/Ngc/Ipc/Service.cs | 64 | ||||
| -rw-r--r-- | src/Ryujinx.Horizon/Ngc/NgcIpcServer.cs | 51 | ||||
| -rw-r--r-- | src/Ryujinx.Horizon/Ngc/NgcMain.cs | 21 |
3 files changed, 136 insertions, 0 deletions
diff --git a/src/Ryujinx.Horizon/Ngc/Ipc/Service.cs b/src/Ryujinx.Horizon/Ngc/Ipc/Service.cs new file mode 100644 index 00000000..828c0919 --- /dev/null +++ b/src/Ryujinx.Horizon/Ngc/Ipc/Service.cs @@ -0,0 +1,64 @@ +using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Sdk.Ngc; +using Ryujinx.Horizon.Sdk.Ngc.Detail; +using Ryujinx.Horizon.Sdk.Sf; +using Ryujinx.Horizon.Sdk.Sf.Hipc; +using System; + +namespace Ryujinx.Horizon.Ngc.Ipc +{ + partial class Service : INgcService + { + private readonly ProfanityFilter _profanityFilter; + + public Service(ProfanityFilter profanityFilter) + { + _profanityFilter = profanityFilter; + } + + [CmifCommand(0)] + public Result GetContentVersion(out uint version) + { + lock (_profanityFilter) + { + return _profanityFilter.GetContentVersion(out version); + } + } + + [CmifCommand(1)] + public Result Check(out uint checkMask, ReadOnlySpan<byte> text, uint regionMask, ProfanityFilterOption option) + { + lock (_profanityFilter) + { + return _profanityFilter.CheckProfanityWords(out checkMask, text, regionMask, option); + } + } + + [CmifCommand(2)] + public Result Mask( + out int maskedWordsCount, + [Buffer(HipcBufferFlags.Out | HipcBufferFlags.MapAlias)] Span<byte> filteredText, + [Buffer(HipcBufferFlags.In | HipcBufferFlags.MapAlias)] ReadOnlySpan<byte> text, + uint regionMask, + ProfanityFilterOption option) + { + lock (_profanityFilter) + { + int length = Math.Min(filteredText.Length, text.Length); + + text[..length].CopyTo(filteredText[..length]); + + return _profanityFilter.MaskProfanityWordsInText(out maskedWordsCount, filteredText, regionMask, option); + } + } + + [CmifCommand(3)] + public Result Reload() + { + lock (_profanityFilter) + { + return _profanityFilter.Reload(); + } + } + } +} diff --git a/src/Ryujinx.Horizon/Ngc/NgcIpcServer.cs b/src/Ryujinx.Horizon/Ngc/NgcIpcServer.cs new file mode 100644 index 00000000..b2a74fb2 --- /dev/null +++ b/src/Ryujinx.Horizon/Ngc/NgcIpcServer.cs @@ -0,0 +1,51 @@ +using Ryujinx.Horizon.Ngc.Ipc; +using Ryujinx.Horizon.Sdk.Fs; +using Ryujinx.Horizon.Sdk.Ngc.Detail; +using Ryujinx.Horizon.Sdk.Sf.Hipc; +using Ryujinx.Horizon.Sdk.Sm; +using System; + +namespace Ryujinx.Horizon.Ngc +{ + class NgcIpcServer + { + private const int MaxSessionsCount = 4; + + private const int PointerBufferSize = 0; + private const int MaxDomains = 0; + private const int MaxDomainObjects = 0; + private const int MaxPortsCount = 1; + + private static readonly ManagerOptions _options = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false); + + private SmApi _sm; + private ServerManager _serverManager; + private ProfanityFilter _profanityFilter; + + public void Initialize(IFsClient fsClient) + { + HeapAllocator allocator = new(); + + _sm = new SmApi(); + _sm.Initialize().AbortOnFailure(); + + _profanityFilter = new(fsClient); + _profanityFilter.Initialize().AbortOnFailure(); + + _serverManager = new ServerManager(allocator, _sm, MaxPortsCount, _options, MaxSessionsCount); + + _serverManager.RegisterObjectForServer(new Service(_profanityFilter), ServiceName.Encode("ngc:u"), MaxSessionsCount); + } + + public void ServiceRequests() + { + _serverManager.ServiceRequests(); + } + + public void Shutdown() + { + _serverManager.Dispose(); + _profanityFilter.Dispose(); + } + } +} diff --git a/src/Ryujinx.Horizon/Ngc/NgcMain.cs b/src/Ryujinx.Horizon/Ngc/NgcMain.cs new file mode 100644 index 00000000..1a584d66 --- /dev/null +++ b/src/Ryujinx.Horizon/Ngc/NgcMain.cs @@ -0,0 +1,21 @@ +namespace Ryujinx.Horizon.Ngc +{ + class NgcMain : IService + { + public static void Main(ServiceTable serviceTable) + { + NgcIpcServer ipcServer = new(); + + ipcServer.Initialize(HorizonStatic.Options.FsClient); + + // TODO: Notification thread, requires implementing OpenSystemDataUpdateEventNotifier on FS. + // The notification thread seems to wait until the event returned by OpenSystemDataUpdateEventNotifier is signalled + // in a loop. When it receives the signal, it calls ContentsReader.Reload and then waits for the next signal. + + serviceTable.SignalServiceReady(); + + ipcServer.ServiceRequests(); + ipcServer.Shutdown(); + } + } +} |
