Merge branch 'full-trimming' into 'master'

Enable full trimming

See merge request [ryubing/ryujinx!224](https://git.ryujinx.app/ryubing/ryujinx/-/merge_requests/224)
This commit is contained in:
A-A Ron 2026-01-03 12:23:16 -06:00
commit a63e1880d2
179 changed files with 793 additions and 556 deletions

3
.gitignore vendored
View file

@ -185,3 +185,6 @@ PublishProfiles/
# Ignore distribution build files
distribution/macos/temp/
distribution/macos/output/
# MSBuild logs
*.binlog

6
Directory.Build.targets Normal file
View file

@ -0,0 +1,6 @@
<Project>
<PropertyGroup>
<IsTrimmable Condition="'$(IsTrimmable)' == '' AND $([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net8.0'))">true</IsTrimmable>
<EnableTrimAnalyzer Condition="'$(EnableTrimAnalyzer)' == '' AND $([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net8.0'))">true</EnableTrimAnalyzer>
</PropertyGroup>
</Project>

View file

@ -23,7 +23,7 @@
<PackageVersion Include="DiscordRichPresence" Version="1.6.1.70" />
<PackageVersion Include="DynamicData" Version="9.4.1" />
<PackageVersion Include="FluentAvaloniaUI.NoAnim" Version="2.4.0-build3" />
<PackageVersion Include="Humanizer" Version="2.14.1" />
<PackageVersion Include="Humanizer" Version="3.0.1" />
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.9.2" />
<PackageVersion Include="Microsoft.IdentityModel.JsonWebTokens" Version="8.3.0" />
@ -38,6 +38,7 @@
<PackageVersion Include="OpenTK.Audio.OpenAL" Version="4.8.2" />
<PackageVersion Include="OpenTK.Windowing.GraphicsLibraryFramework" Version="4.8.2" />
<PackageVersion Include="Open.NAT.Core" Version="2.1.0.5" />
<PackageVersion Include="PolySharp" Version="1.15.0" />
<PackageVersion Include="Ryujinx.Audio.OpenAL.Dependencies" Version="1.21.0.1" />
<PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies.AllArch" Version="6.1.2-build3" />
<PackageVersion Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Version="1.2.0" />
@ -59,4 +60,4 @@
<PackageVersion Include="System.Management" Version="9.0.2" />
<PackageVersion Include="UnicornEngine.Unicorn" Version="2.0.2-rc1-fb78016" />
</ItemGroup>
</Project>
</Project>

View file

@ -2,12 +2,14 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<IsTrimmable>false</IsTrimmable>
<EnableTrimAnalyzer>false</EnableTrimAnalyzer>
</PropertyGroup>
<Target Name="PostBuildTarget" AfterTargets="AfterBuild">
<Message Text="Running Validation Project" Importance="high" />
<Exec WorkingDirectory="$(ProjectDir)bin\Debug\$(TargetFramework)\"
<Exec WorkingDirectory="$(OutDir)"
Command="dotnet Ryujinx.BuildValidationTasks.dll &quot;$(ProjectDir)..\..\\&quot;"
ConsoleToMsBuild="true"
Condition="'$(RuntimeIdentifier)' == ''"

View file

@ -37,7 +37,9 @@ namespace Ryujinx.Common.Logging.Formatters
return;
}
#pragma warning disable IL2075 // GetProperties is *probably* fine here, it only really matters what exists anyway
PropertyInfo[] props = dynamicObject.GetType().GetProperties();
#pragma warning restore IL2075
sb.Append('{');

View file

@ -0,0 +1,173 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using System;
using System.Linq;
using System.Collections.Immutable;
using System.Threading;
namespace Ryujinx.HLE.Generators
{
[Generator]
public class IpcCommandGenerator : IIncrementalGenerator
{
private sealed class CommandData : IEquatable<CommandData>
{
public required string Namespace { get; init; }
public required string TypeName { get; init; }
public required string MethodName { get; init; }
public required ImmutableArray<int> CommandIds { get; init; }
public bool Equals(CommandData other)
{
return Namespace == other.Namespace && TypeName == other.TypeName && MethodName == other.MethodName && CommandIds.SequenceEqual(other.CommandIds);
}
public override bool Equals(object obj)
=> obj is CommandData other && Equals(other);
public override int GetHashCode()
{
unchecked
{
var hashCode = (Namespace != null ? Namespace.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ (TypeName != null ? TypeName.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ (MethodName != null ? MethodName.GetHashCode() : 0);
return hashCode;
}
}
}
private sealed class ServiceData : IEquatable<ServiceData>
{
public required string Namespace { get; init; }
public required string TypeName { get; init; }
public required ImmutableArray<CommandData> CmifCommands { get; init; }
public required ImmutableArray<CommandData> TipcCommands { get; init; }
public bool Equals(ServiceData other)
{
return Namespace == other.Namespace && TypeName == other.TypeName && CmifCommands.SequenceEqual(other.CmifCommands) && TipcCommands.SequenceEqual(other.TipcCommands);
}
public override bool Equals(object obj)
{
return obj is ServiceData other && Equals(other);
}
public override int GetHashCode()
{
unchecked
{
var hashCode = (Namespace != null ? Namespace.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ (TypeName != null ? TypeName.GetHashCode() : 0);
return hashCode;
}
}
}
public void Initialize(IncrementalGeneratorInitializationContext context)
{
Func<SyntaxNode, CancellationToken, bool> predicate = (node, _) => node is MethodDeclarationSyntax;
Func<GeneratorAttributeSyntaxContext, CancellationToken, CommandData> transform = (ctx, _) =>
{
var target = (IMethodSymbol)ctx.TargetSymbol;
return new CommandData
{
Namespace = target.ContainingType.ContainingNamespace?.ToDisplayString(),
TypeName = target.ContainingType.Name,
MethodName = target.Name,
CommandIds = ctx.Attributes.Select(attr => (int)attr.ConstructorArguments[0].Value!).ToImmutableArray(),
};
};
IncrementalValuesProvider<CommandData> cmifCommands =
context.SyntaxProvider.ForAttributeWithMetadataName("Ryujinx.HLE.HOS.Services.CommandCmifAttribute",
predicate,
transform
);
IncrementalValuesProvider<CommandData> tipcCommands =
context.SyntaxProvider.ForAttributeWithMetadataName("Ryujinx.HLE.HOS.Services.CommandTipcAttribute",
predicate,
transform
);
IncrementalValueProvider<(ImmutableArray<CommandData> Left, ImmutableArray<CommandData> Right)> allCommands =
cmifCommands.Collect().Combine(tipcCommands.Collect());
IncrementalValuesProvider<ServiceData> types = allCommands.SelectMany((commands, _) =>
{
ILookup<(string Namespace, string TypeName), CommandData> cmif = commands.Left.ToLookup(c => (c.Namespace, c.TypeName));
ILookup<(string Namespace, string TypeName), CommandData> tipc = commands.Right.ToLookup(c => (c.Namespace, c.TypeName));
ImmutableArray<ServiceData>.Builder builder = ImmutableArray.CreateBuilder<ServiceData>();
foreach ((string Namespace, string TypeName) type in cmif.Select(c => c.Key).Union(tipc.Select(t => t.Key)))
{
builder.Add(new ServiceData
{
Namespace = type.Namespace,
TypeName = type.TypeName,
CmifCommands = cmif.Contains(type) ? cmif[type].ToImmutableArray() : [],
TipcCommands = tipc.Contains(type) ? tipc[type].ToImmutableArray() : [],
});
}
return builder.DrainToImmutable();
});
context.RegisterSourceOutput(types, (ctx, data) =>
{
var generator = new CodeGenerator();
generator.AppendLine("using Ryujinx.HLE.HOS;");
generator.AppendLine("using RC = global::Ryujinx.HLE.HOS.ResultCode;");
generator.EnterScope($"namespace {data.Namespace}");
generator.EnterScope($"partial class {data.TypeName}");
if (!data.CmifCommands.IsEmpty)
{
GenerateCommandMethod("Cmif", data.CmifCommands);
}
if (!data.TipcCommands.IsEmpty)
{
GenerateCommandMethod("Tipc", data.TipcCommands);
}
generator.LeaveScope();
generator.LeaveScope();
ctx.AddSource($"{data.Namespace}.{data.TypeName}.g.cs", generator.ToString());
void GenerateCommandMethod(string commandType, ImmutableArray<CommandData> commands)
{
generator.EnterScope($"protected override RC Invoke{commandType}Method(int id, ServiceCtx context)");
generator.EnterScope("switch (id)");
foreach (CommandData command in commands)
{
generator.AppendLine($"case {string.Join(" or ", command.CommandIds)}:");
generator.IncreaseIndentation();
generator.AppendLine($"LogInvoke(\"{command.MethodName}\");");
generator.AppendLine($"return (RC){command.MethodName}(context);");
generator.DecreaseIndentation();
}
generator.AppendLine($"default: return base.Invoke{commandType}Method(id, context);");
generator.LeaveScope();
generator.LeaveScope();
generator.EnterScope($"public override int {commandType}CommandIdByMethodName(string name)");
generator.EnterScope("return name switch");
foreach (CommandData command in commands)
{
// just return the first command with this name
generator.AppendLine($"\"{command.MethodName}\" => {command.CommandIds[0]},");
}
generator.AppendLine($"_ => base.{commandType}CommandIdByMethodName(name),");
generator.LeaveScope(";");
generator.LeaveScope();
}
});
}
}
}

View file

@ -1,78 +0,0 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using System.Linq;
namespace Ryujinx.HLE.Generators
{
[Generator]
public class IpcServiceGenerator : ISourceGenerator
{
public void Execute(GeneratorExecutionContext context)
{
ServiceSyntaxReceiver syntaxReceiver = (ServiceSyntaxReceiver)context.SyntaxReceiver;
CodeGenerator generator = new();
generator.AppendLine("#nullable enable");
generator.AppendLine("using System;");
generator.EnterScope($"namespace Ryujinx.HLE.HOS.Services.Sm");
generator.EnterScope($"partial class IUserInterface");
generator.EnterScope($"public IpcService? GetServiceInstance(Type type, ServiceCtx context, object? parameter = null)");
foreach (ClassDeclarationSyntax className in syntaxReceiver.Types)
{
if (className.Modifiers.Any(SyntaxKind.AbstractKeyword) || className.Modifiers.Any(SyntaxKind.PrivateKeyword) || !className.AttributeLists.Any(x => x.Attributes.Any(y => y.ToString().StartsWith("Service"))))
continue;
string name = GetFullName(className, context).Replace("global::", string.Empty);
if (!name.StartsWith("Ryujinx.HLE.HOS.Services"))
continue;
ConstructorDeclarationSyntax[] constructors = className.ChildNodes().Where(x => x.IsKind(SyntaxKind.ConstructorDeclaration)).Select(y => y as ConstructorDeclarationSyntax).ToArray();
if (!constructors.Any(x => x.ParameterList.Parameters.Count >= 1))
continue;
if (constructors.Where(x => x.ParameterList.Parameters.Count >= 1).FirstOrDefault().ParameterList.Parameters[0].Type.ToString() == "ServiceCtx")
{
generator.EnterScope($"if (type == typeof({GetFullName(className, context)}))");
if (constructors.Any(x => x.ParameterList.Parameters.Count == 2))
{
TypeSyntax type = constructors.Where(x => x.ParameterList.Parameters.Count == 2).FirstOrDefault().ParameterList.Parameters[1].Type;
SemanticModel model = context.Compilation.GetSemanticModel(type.SyntaxTree);
INamedTypeSymbol typeSymbol = model.GetSymbolInfo(type).Symbol as INamedTypeSymbol;
string fullName = typeSymbol.ToString();
generator.EnterScope("if (parameter != null)");
generator.AppendLine($"return new {GetFullName(className, context)}(context, ({fullName})parameter);");
generator.LeaveScope();
}
if (constructors.Any(x => x.ParameterList.Parameters.Count == 1))
{
generator.AppendLine($"return new {GetFullName(className, context)}(context);");
}
generator.LeaveScope();
}
}
generator.AppendLine("return null;");
generator.LeaveScope();
generator.LeaveScope();
generator.LeaveScope();
generator.AppendLine("#nullable disable");
context.AddSource($"IUserInterface.g.cs", generator.ToString());
}
private string GetFullName(ClassDeclarationSyntax syntaxNode, GeneratorExecutionContext context)
{
INamedTypeSymbol typeSymbol = context.Compilation.GetSemanticModel(syntaxNode.SyntaxTree).GetDeclaredSymbol(syntaxNode);
return typeSymbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
}
public void Initialize(GeneratorInitializationContext context)
{
context.RegisterForSyntaxNotifications(() => new ServiceSyntaxReceiver());
}
}
}

View file

@ -3,8 +3,6 @@
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<CompilerGeneratedFilesOutputPath>Generated</CompilerGeneratedFilesOutputPath>
<IsRoslynComponent>true</IsRoslynComponent>
<DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes>
</PropertyGroup>
@ -15,6 +13,10 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" />
<PackageReference Include="PolySharp">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>

View file

@ -1,24 +0,0 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using System.Collections.Generic;
namespace Ryujinx.HLE.Generators
{
internal class ServiceSyntaxReceiver : ISyntaxReceiver
{
public HashSet<ClassDeclarationSyntax> Types = [];
public void OnVisitSyntaxNode(SyntaxNode syntaxNode)
{
if (syntaxNode is ClassDeclarationSyntax classDeclaration)
{
if (classDeclaration.BaseList == null)
{
return;
}
Types.Add(classDeclaration);
}
}
}
}

View file

@ -0,0 +1,93 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Ryujinx.HLE.Generators
{
[Generator]
public sealed class UserServiceGenerator : IIncrementalGenerator
{
private sealed class ServiceData : IEquatable<ServiceData>
{
public required string FullName { get; init; }
public required IReadOnlyList<(string ServiceName, string ParameterValue)> Instances { get; init; }
public override bool Equals(object obj)
=> obj is ServiceData data && Equals(data);
public bool Equals(ServiceData other)
{
return this.FullName == other.FullName && this.Instances.SequenceEqual(other.Instances);
}
public override int GetHashCode() => FullName.GetHashCode();
}
public void Initialize(IncrementalGeneratorInitializationContext context)
{
IncrementalValuesProvider<ServiceData> pipeline = context.SyntaxProvider.ForAttributeWithMetadataName("Ryujinx.HLE.HOS.Services.ServiceAttribute",
predicate: (node, _) => node is ClassDeclarationSyntax decl && !decl.Modifiers.Any(SyntaxKind.AbstractKeyword) && !decl.Modifiers.Any(SyntaxKind.PrivateKeyword),
transform: (ctx, _) =>
{
var target = (INamedTypeSymbol)ctx.TargetSymbol;
IEnumerable<(string, string param)> instances = ctx.Attributes.Select(attr =>
{
string param = attr.ConstructorArguments is [_, { IsNull: false } arg] ? arg.ToCSharpString() : null;
return ((string)attr.ConstructorArguments[0].Value, param);
});
return new ServiceData
{
FullName = target.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat),
Instances = instances.ToList(),
};
}
);
context.RegisterSourceOutput(pipeline.Collect(),
(ctx, data) =>
{
var generator = new CodeGenerator();
generator.AppendLine("#nullable enable");
generator.AppendLine("using System;");
generator.EnterScope("namespace Ryujinx.HLE.HOS.Services.Sm");
generator.EnterScope("partial class IUserInterface");
generator.EnterScope("public IpcService? GetServiceInstance(string name, ServiceCtx context)");
generator.EnterScope("return name switch");
foreach (ServiceData serviceImpl in data)
{
foreach ((string ServiceName, string ParameterValue) instance in serviceImpl.Instances)
{
if (instance.ParameterValue == null)
{
generator.AppendLine($"\"{instance.ServiceName}\" => new {serviceImpl.FullName}(context),");
}
else
{
generator.AppendLine($"\"{instance.ServiceName}\" => new {serviceImpl.FullName}(context, {instance.ParameterValue}),");
}
}
}
generator.AppendLine("_ => null,");
generator.LeaveScope(";");
generator.LeaveScope();
generator.LeaveScope();
generator.LeaveScope();
generator.AppendLine("#nullable disable");
ctx.AddSource("IUserInterface.g.cs", generator.ToString());
});
}
}
}

View file

@ -7,6 +7,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
namespace Ryujinx.HLE.Exceptions
@ -17,22 +18,22 @@ namespace Ryujinx.HLE.Exceptions
public IpcService Service { get; }
public ServiceCtx Context { get; }
public IpcMessage Request { get; }
private string MethodName { get; }
public ServiceNotImplementedException(IpcService service, ServiceCtx context)
: this(service, context, "The service call is not implemented.") { }
public ServiceNotImplementedException(IpcService service, ServiceCtx context, string message) : base(message)
public ServiceNotImplementedException(IpcService service, ServiceCtx context, string message = "The service call is not implemented.", [CallerMemberName] string methodName = null) : base(message)
{
Service = service;
Context = context;
Request = context.Request;
MethodName = methodName;
}
public ServiceNotImplementedException(IpcService service, ServiceCtx context, string message, Exception inner) : base(message, inner)
public ServiceNotImplementedException(IpcService service, ServiceCtx context, string message, Exception inner, [CallerMemberName] string methodName = null) : base(message, inner)
{
Service = service;
Context = context;
Request = context.Request;
MethodName = methodName;
}
public override string Message
@ -47,25 +48,12 @@ namespace Ryujinx.HLE.Exceptions
{
StringBuilder sb = new();
// Print the IPC command details (service name, command ID, and handler)
(Type callingType, MethodBase callingMethod) = WalkStackTrace(new StackTrace(this));
int commandId = Request.Type > IpcMessageType.TipcCloseSession
? Service.TipcCommandIdByMethodName(MethodName)
: Service.CmifCommandIdByMethodName(MethodName);
if (callingType != null && callingMethod != null)
{
// If the type is past 0xF, we are using TIPC
IReadOnlyDictionary<int, MethodInfo> ipcCommands = Request.Type > IpcMessageType.TipcCloseSession ? Service.TipcCommands : Service.CmifCommands;
// Find the handler for the method called
KeyValuePair<int, MethodInfo> ipcHandler = ipcCommands.FirstOrDefault(x => x.Value == callingMethod);
int ipcCommandId = ipcHandler.Key;
MethodInfo ipcMethod = ipcHandler.Value;
if (ipcMethod != null)
{
sb.AppendLine($"Service Command: {Service.GetType().FullName}: {ipcCommandId} ({ipcMethod.Name})");
sb.AppendLine();
}
}
sb.AppendLine($"Service Command: {Service.GetType().FullName}: {commandId} ({MethodName})");
sb.AppendLine();
sb.AppendLine("Guest Stack Trace:");
sb.AppendLine(Context.Thread.GetGuestStackTrace());
@ -137,26 +125,5 @@ namespace Ryujinx.HLE.Exceptions
return sb.ToString();
}
private static (Type, MethodBase) WalkStackTrace(StackTrace trace)
{
int i = 0;
StackFrame frame;
// Find the IIpcService method that threw this exception
while ((frame = trace.GetFrame(i++)) != null)
{
MethodBase method = frame.GetMethod();
Type declType = method.DeclaringType;
if (typeof(IpcService).IsAssignableFrom(declType))
{
return (declType, method);
}
}
return (null, null);
}
}
}

View file

@ -1,6 +1,6 @@
namespace Ryujinx.HLE.HOS.Services.Account.Acc.AccountService
{
class IManagerForApplication : IpcService
partial class IManagerForApplication : IpcService
{
private readonly ManagerServer _managerServer;

View file

@ -1,6 +1,6 @@
namespace Ryujinx.HLE.HOS.Services.Account.Acc.AccountService
{
class IManagerForSystemService : IpcService
partial class IManagerForSystemService : IpcService
{
private readonly ManagerServer _managerServer;

View file

@ -1,6 +1,6 @@
namespace Ryujinx.HLE.HOS.Services.Account.Acc.AccountService
{
class IProfile : IpcService
partial class IProfile : IpcService
{
private readonly ProfileServer _profileServer;

View file

@ -1,6 +1,6 @@
namespace Ryujinx.HLE.HOS.Services.Account.Acc.AccountService
{
class IProfileEditor : IpcService
partial class IProfileEditor : IpcService
{
private readonly ProfileServer _profileServer;

View file

@ -5,7 +5,7 @@ using Ryujinx.HLE.HOS.Services.Account.Acc.AccountService;
namespace Ryujinx.HLE.HOS.Services.Account.Acc
{
[Service("acc:su", AccountServiceFlag.Administrator)] // Max Sessions: 8
class IAccountServiceForAdministrator : IpcService
partial class IAccountServiceForAdministrator : IpcService
{
private readonly ApplicationServiceServer _applicationServiceServer;

View file

@ -5,7 +5,7 @@ using Ryujinx.HLE.HOS.Services.Arp;
namespace Ryujinx.HLE.HOS.Services.Account.Acc
{
[Service("acc:u0", AccountServiceFlag.Application)] // Max Sessions: 4
class IAccountServiceForApplication : IpcService
partial class IAccountServiceForApplication : IpcService
{
private readonly ApplicationServiceServer _applicationServiceServer;

View file

@ -4,7 +4,7 @@ using Ryujinx.HLE.HOS.Services.Account.Acc.AccountService;
namespace Ryujinx.HLE.HOS.Services.Account.Acc
{
[Service("acc:u1", AccountServiceFlag.SystemService)] // Max Sessions: 16
class IAccountServiceForSystemService : IpcService
partial class IAccountServiceForSystemService : IpcService
{
private readonly ApplicationServiceServer _applicationServiceServer;

View file

@ -5,7 +5,7 @@ using System;
namespace Ryujinx.HLE.HOS.Services.Account.Acc
{
class IAsyncContext : IpcService
partial class IAsyncContext : IpcService
{
protected AsyncExecution AsyncExecution;

View file

@ -2,7 +2,7 @@ using Ryujinx.HLE.HOS.Services.Account.Acc.AsyncContext;
namespace Ryujinx.HLE.HOS.Services.Account.Acc
{
class IAsyncNetworkServiceLicenseKindContext : IAsyncContext
partial class IAsyncNetworkServiceLicenseKindContext : IAsyncContext
{
private readonly NetworkServiceLicenseKind? _serviceLicenseKind;

View file

@ -3,6 +3,6 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc
[Service("acc:aa", AccountServiceFlag.BaasAccessTokenAccessor)] // Max Sessions: 4
class IBaasAccessTokenAccessor : IpcService
{
public IBaasAccessTokenAccessor(ServiceCtx context) { }
public IBaasAccessTokenAccessor(ServiceCtx context, AccountServiceFlag serviceFlag) { }
}
}

View file

@ -3,7 +3,7 @@ using Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemA
namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService
{
class ILibraryAppletProxy : IpcService
partial class ILibraryAppletProxy : IpcService
{
private readonly ulong _pid;

View file

@ -2,7 +2,7 @@ using Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemA
namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService
{
class ISystemAppletProxy : IpcService
partial class ISystemAppletProxy : IpcService
{
private readonly ulong _pid;

View file

@ -9,7 +9,7 @@ using System;
namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.LibraryAppletCreator
{
class ILibraryAppletAccessor : DisposableIpcService
partial class ILibraryAppletAccessor : DisposableIpcService
{
private readonly KernelContext _kernelContext;

View file

@ -3,7 +3,7 @@ using System;
namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.LibraryAppletProxy
{
class ILibraryAppletSelfAccessor : IpcService
partial class ILibraryAppletSelfAccessor : IpcService
{
private readonly AppletStandalone _appletStandalone = new();

View file

@ -2,7 +2,7 @@ using Ryujinx.Common;
namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.LibraryAppletProxy
{
class IProcessWindingController : IpcService
partial class IProcessWindingController : IpcService
{
public IProcessWindingController() { }

View file

@ -2,7 +2,7 @@ using Ryujinx.Common.Logging;
namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy
{
class IAudioController : IpcService
partial class IAudioController : IpcService
{
public IAudioController() { }

View file

@ -10,7 +10,7 @@ using System;
namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy
{
class ICommonStateGetter : DisposableIpcService
partial class ICommonStateGetter : DisposableIpcService
{
private readonly ServiceCtx _context;

View file

@ -6,7 +6,7 @@ using System;
namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy
{
class IDisplayController : IpcService
partial class IDisplayController : IpcService
{
private readonly KTransferMemory _transferMem;
private bool _lastApplicationCaptureBufferAcquired;

View file

@ -6,7 +6,7 @@ using System;
namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy
{
class IHomeMenuFunctions : IpcService
partial class IHomeMenuFunctions : IpcService
{
private readonly KEvent _channelEvent;
private int _channelEventHandle;

View file

@ -3,7 +3,7 @@ using Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.Library
namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy
{
class ILibraryAppletCreator : IpcService
partial class ILibraryAppletCreator : IpcService
{
public ILibraryAppletCreator() { }

View file

@ -8,7 +8,7 @@ using System.Threading;
namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy
{
class ISelfController : IpcService
partial class ISelfController : IpcService
{
private readonly ulong _pid;

View file

@ -2,7 +2,7 @@ using Ryujinx.Common.Logging;
namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy
{
class IWindowController : IpcService
partial class IWindowController : IpcService
{
private readonly ulong _pid;

View file

@ -4,7 +4,7 @@ using Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService;
namespace Ryujinx.HLE.HOS.Services.Am.AppletAE
{
[Service("appletAE")]
class IAllSystemAppletProxiesService : IpcService
partial class IAllSystemAppletProxiesService : IpcService
{
public IAllSystemAppletProxiesService(ServiceCtx context) { }

View file

@ -1,6 +1,6 @@
namespace Ryujinx.HLE.HOS.Services.Am.AppletAE
{
class IStorage : IpcService
partial class IStorage : IpcService
{
public bool IsReadOnly { get; private set; }
public byte[] Data { get; private set; }

View file

@ -2,7 +2,7 @@ using System;
namespace Ryujinx.HLE.HOS.Services.Am.AppletAE
{
class IStorageAccessor : IpcService
partial class IStorageAccessor : IpcService
{
private readonly IStorage _storage;

View file

@ -22,7 +22,7 @@ using ApplicationId = LibHac.Ncm.ApplicationId;
namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.ApplicationProxy
{
class IApplicationFunctions : IpcService
partial class IApplicationFunctions : IpcService
{
private long _defaultSaveDataSize = 200000000;
private long _defaultJournalSaveDataSize = 200000000;

View file

@ -3,7 +3,7 @@ using Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.ApplicationPr
namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService
{
class IApplicationProxy : IpcService
partial class IApplicationProxy : IpcService
{
private readonly ulong _pid;

View file

@ -3,7 +3,7 @@ using Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService;
namespace Ryujinx.HLE.HOS.Services.Am
{
[Service("appletOE")]
class IApplicationProxyService : IpcService
partial class IApplicationProxyService : IpcService
{
public IApplicationProxyService(ServiceCtx context) { }

View file

@ -1,6 +1,6 @@
namespace Ryujinx.HLE.HOS.Services.Apm
{
abstract class IManager : IpcService
abstract partial class IManager : IpcService
{
public IManager(ServiceCtx context) { }

View file

@ -3,7 +3,7 @@ namespace Ryujinx.HLE.HOS.Services.Apm
// NOTE: This service doesnt exist anymore after firmware 7.0.1. But some outdated homebrew still uses it.
[Service("apm:p")] // 1.0.0-7.0.1
class IManagerPrivileged : IpcService
partial class IManagerPrivileged : IpcService
{
public IManagerPrivileged(ServiceCtx context) { }

View file

@ -1,6 +1,6 @@
namespace Ryujinx.HLE.HOS.Services.Apm
{
abstract class ISession : IpcService
abstract partial class ISession : IpcService
{
public ISession(ServiceCtx context) { }

View file

@ -1,6 +1,6 @@
namespace Ryujinx.HLE.HOS.Services.Apm
{
abstract class ISystemManager : IpcService
abstract partial class ISystemManager : IpcService
{
public ISystemManager(ServiceCtx context) { }

View file

@ -8,7 +8,7 @@ using System;
namespace Ryujinx.HLE.HOS.Services.Bluetooth
{
[Service("btdrv")]
class IBluetoothDriver : IpcService
partial class IBluetoothDriver : IpcService
{
#pragma warning disable CS0414, IDE0052 // Remove unread private member
private string _unknownLowEnergy;

View file

@ -5,7 +5,7 @@ using Ryujinx.HLE.HOS.Services.Settings;
namespace Ryujinx.HLE.HOS.Services.Bluetooth
{
[Service("bt")]
class IBluetoothUser : IpcService
partial class IBluetoothUser : IpcService
{
public IBluetoothUser(ServiceCtx context) { }

View file

@ -5,7 +5,7 @@ using Ryujinx.Horizon.Common;
namespace Ryujinx.HLE.HOS.Services.BluetoothManager.BtmUser
{
class IBtmUserCore : IpcService
partial class IBtmUserCore : IpcService
{
public KEvent _bleScanEvent;
public int _bleScanEventHandle;

View file

@ -3,7 +3,7 @@ using Ryujinx.HLE.HOS.Services.BluetoothManager.BtmUser;
namespace Ryujinx.HLE.HOS.Services.BluetoothManager
{
[Service("btm:u")] // 5.0.0+
class IBtmUser : IpcService
partial class IBtmUser : IpcService
{
public IBtmUser(ServiceCtx context) { }

View file

@ -5,7 +5,7 @@ using Ryujinx.HLE.HOS.Services.Caps.Types;
namespace Ryujinx.HLE.HOS.Services.Caps
{
[Service("caps:u")]
class IAlbumApplicationService : IpcService
partial class IAlbumApplicationService : IpcService
{
public IAlbumApplicationService(ServiceCtx context) { }

View file

@ -1,7 +1,7 @@
namespace Ryujinx.HLE.HOS.Services.Caps
{
[Service("caps:c")]
class IAlbumControlService : IpcService
partial class IAlbumControlService : IpcService
{
public IAlbumControlService(ServiceCtx context) { }

View file

@ -4,7 +4,7 @@ using Ryujinx.HLE.HOS.Services.Caps.Types;
namespace Ryujinx.HLE.HOS.Services.Caps
{
[Service("caps:su")] // 6.0.0+
class IScreenShotApplicationService : IpcService
partial class IScreenShotApplicationService : IpcService
{
public IScreenShotApplicationService(ServiceCtx context) { }

View file

@ -4,7 +4,7 @@ using Ryujinx.Horizon.Common;
namespace Ryujinx.HLE.HOS.Services.Ectx
{
class IContextRegistrar : DisposableIpcService
partial class IContextRegistrar : DisposableIpcService
{
public IContextRegistrar(ServiceCtx context) { }

View file

@ -1,7 +1,7 @@
namespace Ryujinx.HLE.HOS.Services.Ectx
{
[Service("ectx:aw")] // 11.0.0+
class IWriterForApplication : IpcService
partial class IWriterForApplication : IpcService
{
public IWriterForApplication(ServiceCtx context) { }

View file

@ -7,7 +7,7 @@ using System.Text;
namespace Ryujinx.HLE.HOS.Services.Fatal
{
[Service("fatal:u")]
class IService : IpcService
partial class IService : IpcService
{
public IService(ServiceCtx context) { }

View file

@ -5,7 +5,7 @@ using Ryujinx.Memory;
namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
{
class IDirectory : DisposableIpcService
partial class IDirectory : DisposableIpcService
{
private SharedRef<LibHac.FsSrv.Sf.IDirectory> _baseDirectory;

View file

@ -7,7 +7,7 @@ using Ryujinx.Memory;
namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
{
class IFile : DisposableIpcService
partial class IFile : DisposableIpcService
{
private SharedRef<LibHac.FsSrv.Sf.IFile> _baseFile;

View file

@ -7,7 +7,7 @@ using Path = LibHac.FsSrv.Sf.Path;
namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
{
class IFileSystem : DisposableIpcService
partial class IFileSystem : DisposableIpcService
{
private SharedRef<LibHac.FsSrv.Sf.IFileSystem> _fileSystem;

View file

@ -10,7 +10,7 @@ using System.Threading;
namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
{
class IStorage : DisposableIpcService
partial class IStorage : DisposableIpcService
{
private SharedRef<LibHac.FsSrv.Sf.IStorage> _baseStorage;

View file

@ -5,7 +5,7 @@ using GameCardHandle = System.UInt32;
namespace Ryujinx.HLE.HOS.Services.Fs
{
class IDeviceOperator : DisposableIpcService
partial class IDeviceOperator : DisposableIpcService
{
private SharedRef<LibHac.FsSrv.Sf.IDeviceOperator> _baseOperator;

View file

@ -25,7 +25,7 @@ using IStorage = LibHac.FsSrv.Sf.IStorage;
namespace Ryujinx.HLE.HOS.Services.Fs
{
[Service("fsp-srv")]
class IFileSystemProxy : DisposableIpcService
partial class IFileSystemProxy : DisposableIpcService
{
private SharedRef<LibHac.FsSrv.Sf.IFileSystemProxy> _baseFileSystemProxy;
private ulong _pid;

View file

@ -4,7 +4,7 @@ using Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy;
namespace Ryujinx.HLE.HOS.Services.Fs
{
class IMultiCommitManager : DisposableIpcService // 6.0.0+
partial class IMultiCommitManager : DisposableIpcService // 6.0.0+
{
private SharedRef<LibHac.FsSrv.Sf.IMultiCommitManager> _baseCommitManager;

View file

@ -5,7 +5,7 @@ using Ryujinx.Memory;
namespace Ryujinx.HLE.HOS.Services.Fs
{
class ISaveDataInfoReader : DisposableIpcService
partial class ISaveDataInfoReader : DisposableIpcService
{
private SharedRef<LibHac.FsSrv.Sf.ISaveDataInfoReader> _baseReader;

View file

@ -1,6 +1,6 @@
namespace Ryujinx.HLE.HOS.Services.Hid.HidServer
{
class IActiveApplicationDeviceList : IpcService
partial class IActiveApplicationDeviceList : IpcService
{
public IActiveApplicationDeviceList() { }

View file

@ -5,7 +5,7 @@ using System;
namespace Ryujinx.HLE.HOS.Services.Hid.HidServer
{
class IAppletResource : IpcService
partial class IAppletResource : IpcService
{
private readonly KSharedMemory _hidSharedMem;
private int _hidSharedMemHandle;

View file

@ -13,7 +13,7 @@ using System.Runtime.InteropServices;
namespace Ryujinx.HLE.HOS.Services.Hid
{
[Service("hid")]
class IHidServer : IpcService
partial class IHidServer : IpcService
{
private readonly KEvent _xpadIdEvent;
private readonly KEvent _palmaOperationCompleteEvent;

View file

@ -5,7 +5,7 @@ using Ryujinx.HLE.HOS.Services.Hid.Types;
namespace Ryujinx.HLE.HOS.Services.Hid
{
[Service("hid:sys")]
class IHidSystemServer : IpcService
partial class IHidSystemServer : IpcService
{
public IHidSystemServer(ServiceCtx context) { }

View file

@ -4,7 +4,7 @@ using Ryujinx.Common.Logging;
namespace Ryujinx.HLE.HOS.Services.Hid
{
[Service("hidbus")]
class IHidbusServer : IpcService
partial class IHidbusServer : IpcService
{
public IHidbusServer(ServiceCtx context) { }

View file

@ -9,7 +9,7 @@ using System;
namespace Ryujinx.HLE.HOS.Services.Hid.Irs
{
[Service("irs")]
class IIrSensorServer : IpcService
partial class IIrSensorServer : IpcService
{
private int _irsensorSharedMemoryHandle = 0;

View file

@ -13,9 +13,6 @@ namespace Ryujinx.HLE.HOS.Services
{
abstract class IpcService
{
public IReadOnlyDictionary<int, MethodInfo> CmifCommands { get; }
public IReadOnlyDictionary<int, MethodInfo> TipcCommands { get; }
public ServerBase Server { get; private set; }
private IpcService _parent;
@ -23,46 +20,8 @@ namespace Ryujinx.HLE.HOS.Services
private int _selfId;
private bool _isDomain;
// cache array so we don't recreate it all the time
private object[] _parameters = [null];
public IpcService(ServerBase server = null, bool registerTipc = false)
public IpcService(ServerBase server = null)
{
Stopwatch sw = Stopwatch.StartNew();
CmifCommands = GetType()
.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public)
.SelectMany(methodInfo => methodInfo.GetCustomAttributes<CommandCmifAttribute>()
.Select(command => (command.Id, methodInfo)))
.ToDictionary(command => command.Id, command => command.methodInfo);
sw.Stop();
Logger.Debug?.Print(
LogClass.Emulation,
$"{CmifCommands.Count} Cmif commands loaded in {sw.ElapsedTicks} ticks ({Stopwatch.Frequency} tps).",
GetType().AsPrettyString()
);
if (registerTipc)
{
sw.Start();
TipcCommands = GetType()
.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public)
.SelectMany(methodInfo => methodInfo.GetCustomAttributes<CommandTipcAttribute>()
.Select(command => (command.Id, methodInfo)))
.ToDictionary(command => command.Id, command => command.methodInfo);
sw.Stop();
Logger.Debug?.Print(
LogClass.Emulation,
$"{TipcCommands.Count} Tipc commands loaded in {sw.ElapsedTicks} ticks ({Stopwatch.Frequency} tps).",
GetType().AsPrettyString()
);
}
Server = server;
_parent = this;
@ -87,6 +46,49 @@ namespace Ryujinx.HLE.HOS.Services
_isDomain = false;
}
protected virtual ResultCode InvokeCmifMethod(int id, ServiceCtx context)
{
if (!context.Device.Configuration.IgnoreMissingServices)
{
string dbgMessage = $"{this.GetType().FullName}: {id}";
throw new ServiceNotImplementedException(this, context, dbgMessage);
}
string serviceName = (this is not DummyService dummyService)
? this.GetType().FullName
: dummyService.ServiceName;
Logger.Warning?.Print(LogClass.KernelIpc, $"Missing service {serviceName}: {id} ignored");
return ResultCode.Success;
}
public virtual int CmifCommandIdByMethodName(string name) => -1;
protected virtual ResultCode InvokeTipcMethod(int id, ServiceCtx context)
{
if (!context.Device.Configuration.IgnoreMissingServices)
{
string dbgMessage = $"{this.GetType().FullName}: {id}";
throw new ServiceNotImplementedException(this, context, dbgMessage);
}
string serviceName = (this is not DummyService dummyService)
? this.GetType().FullName
: dummyService.ServiceName;
Logger.Warning?.Print(LogClass.KernelIpc, $"Missing service {serviceName}: {id} ignored");
return ResultCode.Success;
}
public virtual int TipcCommandIdByMethodName(string name) => -1;
protected void LogInvoke(string name)
=> Logger.Trace?.Print(LogClass.KernelIpc, $"{this.GetType().Name}: {name}");
public void CallCmifMethod(ServiceCtx context)
{
IpcService service = this;
@ -137,93 +139,39 @@ namespace Ryujinx.HLE.HOS.Services
#pragma warning restore IDE0059
int commandId = (int)context.RequestData.ReadInt64();
bool serviceExists = service.CmifCommands.TryGetValue(commandId, out MethodInfo processRequest);
context.ResponseData.BaseStream.Seek(_isDomain ? 0x20 : 0x10, SeekOrigin.Begin);
if (context.Device.Configuration.IgnoreMissingServices || serviceExists)
ResultCode result = service.InvokeCmifMethod(commandId, context);
if (_isDomain)
{
ResultCode result = ResultCode.Success;
context.ResponseData.BaseStream.Seek(_isDomain ? 0x20 : 0x10, SeekOrigin.Begin);
if (serviceExists)
foreach (int id in context.Response.ObjectIds)
{
Logger.Trace?.Print(LogClass.KernelIpc, $"{service.GetType().Name}: {processRequest.Name}");
_parameters[0] = context;
result = (ResultCode)processRequest.Invoke(service, _parameters);
}
else
{
string serviceName = (service is not DummyService dummyService) ? service.GetType().FullName : dummyService.ServiceName;
Logger.Warning?.Print(LogClass.KernelIpc, $"Missing service {serviceName}: {commandId} ignored");
context.ResponseData.Write(id);
}
if (_isDomain)
{
foreach (int id in context.Response.ObjectIds)
{
context.ResponseData.Write(id);
}
context.ResponseData.BaseStream.Seek(0, SeekOrigin.Begin);
context.ResponseData.BaseStream.Seek(0, SeekOrigin.Begin);
context.ResponseData.Write(context.Response.ObjectIds.Count);
}
context.ResponseData.BaseStream.Seek(_isDomain ? 0x10 : 0, SeekOrigin.Begin);
context.ResponseData.Write(IpcMagic.Sfco);
context.ResponseData.Write((long)result);
context.ResponseData.Write(context.Response.ObjectIds.Count);
}
else
{
string dbgMessage = $"{service.GetType().FullName}: {commandId}";
throw new ServiceNotImplementedException(service, context, dbgMessage);
}
context.ResponseData.BaseStream.Seek(_isDomain ? 0x10 : 0, SeekOrigin.Begin);
context.ResponseData.Write(IpcMagic.Sfco);
context.ResponseData.Write((long)result);
}
public void CallTipcMethod(ServiceCtx context)
{
int commandId = (int)context.Request.Type - 0x10;
bool serviceExists = TipcCommands.TryGetValue(commandId, out MethodInfo processRequest);
context.ResponseData.BaseStream.Seek(0x4, SeekOrigin.Begin);
if (context.Device.Configuration.IgnoreMissingServices || serviceExists)
{
ResultCode result = ResultCode.Success;
ResultCode result = InvokeTipcMethod(commandId, context);
context.ResponseData.BaseStream.Seek(0x4, SeekOrigin.Begin);
context.ResponseData.BaseStream.Seek(0, SeekOrigin.Begin);
if (serviceExists)
{
Logger.Debug?.Print(LogClass.KernelIpc, $"{GetType().Name}: {processRequest.Name}");
_parameters[0] = context;
result = (ResultCode)processRequest.Invoke(this, _parameters);
}
else
{
string serviceName;
serviceName = (this is not DummyService dummyService) ? GetType().FullName : dummyService.ServiceName;
Logger.Warning?.Print(LogClass.KernelIpc, $"Missing service {serviceName}: {commandId} ignored");
}
context.ResponseData.BaseStream.Seek(0, SeekOrigin.Begin);
context.ResponseData.Write((uint)result);
}
else
{
string dbgMessage = $"{GetType().FullName}: {commandId}";
throw new ServiceNotImplementedException(this, context, dbgMessage);
}
context.ResponseData.Write((uint)result);
}
protected void MakeObject(ServiceCtx context, IpcService obj)

View file

@ -3,7 +3,7 @@ using Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator;
namespace Ryujinx.HLE.HOS.Services.Ldn
{
[Service("ldn:u")]
class IUserServiceCreator : IpcService
partial class IUserServiceCreator : IpcService
{
public IUserServiceCreator(ServiceCtx context) : base(context.Device.System.LdnServer) { }

View file

@ -2,7 +2,7 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.Lp2p
{
[Service("lp2p:app")] // 9.0.0+
[Service("lp2p:sys")] // 9.0.0+
class IServiceCreator : IpcService
partial class IServiceCreator : IpcService
{
public IServiceCreator(ServiceCtx context) { }

View file

@ -2,7 +2,7 @@ using Ryujinx.Common.Logging;
namespace Ryujinx.HLE.HOS.Services.Ldn.Lp2p
{
class ISfService : IpcService
partial class ISfService : IpcService
{
public ISfService(ServiceCtx context) { }

View file

@ -6,7 +6,7 @@ using System;
namespace Ryujinx.HLE.HOS.Services.Ldn.Lp2p
{
class ISfServiceMonitor : IpcService
partial class ISfServiceMonitor : IpcService
{
private readonly KEvent _stateChangeEvent;
private readonly KEvent _jointEvent;

View file

@ -2,7 +2,7 @@ using Ryujinx.Common.Logging;
namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator
{
class IClientProcessMonitor : DisposableIpcService
partial class IClientProcessMonitor : DisposableIpcService
{
public IClientProcessMonitor(ServiceCtx context) { }

View file

@ -21,7 +21,7 @@ using System.Runtime.InteropServices;
namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator
{
class IUserLocalCommunicationService : IpcService, IDisposable
partial class IUserLocalCommunicationService : IpcService, IDisposable
{
public INetworkClient NetworkClient { get; private set; }

View file

@ -3,7 +3,7 @@ using Ryujinx.Common.Logging;
namespace Ryujinx.HLE.HOS.Services.Mii
{
[Service("miiimg")] // 5.0.0+
class IImageDatabaseService : IpcService
partial class IImageDatabaseService : IpcService
{
private uint _imageCount;
private bool _isDirty;

View file

@ -6,7 +6,7 @@ namespace Ryujinx.HLE.HOS.Services.Mii
{
[Service("mii:e", true)]
[Service("mii:u", false)]
class IStaticService : IpcService
partial class IStaticService : IpcService
{
private readonly DatabaseImpl _databaseImpl;

View file

@ -6,7 +6,7 @@ using System.Runtime.InteropServices;
namespace Ryujinx.HLE.HOS.Services.Mii.StaticService
{
abstract class IDatabaseService : IpcService
abstract partial class IDatabaseService : IpcService
{
[CommandCmif(0)]
// IsUpdated(SourceFlag flag) -> bool

View file

@ -6,7 +6,7 @@ using Ryujinx.HLE.HOS.Services.Account.Acc;
namespace Ryujinx.HLE.HOS.Services.Mnpp
{
[Service("mnpp:app")] // 13.0.0+
class IServiceForApplication : IpcService
partial class IServiceForApplication : IpcService
{
public IServiceForApplication(ServiceCtx context) { }

View file

@ -4,7 +4,7 @@ using Ryujinx.HLE.HOS.Services.Ncm.Lr.LocationResolverManager;
namespace Ryujinx.HLE.HOS.Services.Ncm.Lr
{
[Service("lr")]
class ILocationResolverManager : IpcService
partial class ILocationResolverManager : IpcService
{
public ILocationResolverManager(ServiceCtx context) { }

View file

@ -6,7 +6,7 @@ using static Ryujinx.HLE.Utilities.StringUtils;
namespace Ryujinx.HLE.HOS.Services.Ncm.Lr.LocationResolverManager
{
class ILocationResolver : IpcService
partial class ILocationResolver : IpcService
{
private readonly StorageId _storageId;

View file

@ -3,7 +3,7 @@ using Ryujinx.HLE.HOS.Services.Nfc.NfcManager;
namespace Ryujinx.HLE.HOS.Services.Nfc
{
[Service("nfc:sys")]
class ISystemManager : IpcService
partial class ISystemManager : IpcService
{
public ISystemManager(ServiceCtx context) { }

View file

@ -3,7 +3,7 @@ using Ryujinx.HLE.HOS.Services.Nfc.NfcManager;
namespace Ryujinx.HLE.HOS.Services.Nfc
{
[Service("nfc:user")]
class IUserManager : IpcService
partial class IUserManager : IpcService
{
public IUserManager(ServiceCtx context) { }

View file

@ -2,7 +2,7 @@ using Ryujinx.Common.Logging;
namespace Ryujinx.HLE.HOS.Services.Nfc.NfcManager
{
class INfc : IpcService
partial class INfc : IpcService
{
private readonly NfcPermissionLevel _permissionLevel;
private State _state;

View file

@ -3,7 +3,7 @@ using Ryujinx.HLE.HOS.Services.Nfc.Nfp.NfpManager;
namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp
{
[Service("nfp:dbg")]
class IAmManager : IpcService
partial class IAmManager : IpcService
{
public IAmManager(ServiceCtx context) { }

View file

@ -3,7 +3,7 @@ using Ryujinx.HLE.HOS.Services.Nfc.Nfp.NfpManager;
namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp
{
[Service("nfp:sys")]
class ISystemManager : IpcService
partial class ISystemManager : IpcService
{
public ISystemManager(ServiceCtx context) { }

View file

@ -3,7 +3,7 @@ using Ryujinx.HLE.HOS.Services.Nfc.Nfp.NfpManager;
namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp
{
[Service("nfp:user")]
class IUserManager : IpcService
partial class IUserManager : IpcService
{
public IUserManager(ServiceCtx context) { }

View file

@ -16,7 +16,7 @@ using System.Threading.Tasks;
namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp
{
class INfp : IpcService
partial class INfp : IpcService
{
#pragma warning disable IDE0052 // Remove unread private member
private ulong _appletResourceUserId;

View file

@ -1,7 +1,7 @@
namespace Ryujinx.HLE.HOS.Services.Ngct
{
[Service("ngct:u")] // 9.0.0+
class IService : IpcService
partial class IService : IpcService
{
public IService(ServiceCtx context) { }

View file

@ -1,7 +1,7 @@
namespace Ryujinx.HLE.HOS.Services.Ngct
{
[Service("ngct:s")] // 9.0.0+
class IServiceWithManagementApi : IpcService
partial class IServiceWithManagementApi : IpcService
{
public IServiceWithManagementApi(ServiceCtx context) { }

View file

@ -5,7 +5,7 @@ namespace Ryujinx.HLE.HOS.Services.Nifm
[Service("nifm:a")] // Max sessions: 2
[Service("nifm:s")] // Max sessions: 16
[Service("nifm:u")] // Max sessions: 5
class IStaticService : IpcService
partial class IStaticService : IpcService
{
public IStaticService(ServiceCtx context) { }

View file

@ -10,7 +10,7 @@ using System.Runtime.CompilerServices;
namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService
{
class IGeneralService : DisposableIpcService
partial class IGeneralService : DisposableIpcService
{
private readonly GeneralServiceDetail _generalServiceDetail;

View file

@ -6,7 +6,7 @@ using System;
namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService
{
class IRequest : IpcService
partial class IRequest : IpcService
{
private enum RequestState
{

View file

@ -3,7 +3,7 @@ using Ryujinx.HLE.HOS.Services.Nim.ShopServiceAccessServerInterface.ShopServiceA
namespace Ryujinx.HLE.HOS.Services.Nim.ShopServiceAccessServerInterface
{
class IShopServiceAccessServer : IpcService
partial class IShopServiceAccessServer : IpcService
{
public IShopServiceAccessServer() { }

View file

@ -6,7 +6,7 @@ using Ryujinx.HLE.HOS.Services.Nim.ShopServiceAccessServerInterface;
namespace Ryujinx.HLE.HOS.Services.Nim
{
[Service("nim:eca")] // 5.0.0+
class IShopServiceAccessServerInterface : IpcService
partial class IShopServiceAccessServerInterface : IpcService
{
public IShopServiceAccessServerInterface(ServiceCtx context) { }

View file

@ -7,7 +7,7 @@ using System;
namespace Ryujinx.HLE.HOS.Services.Nim.ShopServiceAccessServerInterface.ShopServiceAccessServer
{
class IShopServiceAccessor : IpcService
partial class IShopServiceAccessor : IpcService
{
private readonly KEvent _event;

View file

@ -4,7 +4,7 @@ using Ryujinx.HLE.HOS.Services.Nim.Ntc.StaticService;
namespace Ryujinx.HLE.HOS.Services.Nim.Ntc
{
[Service("ntc")]
class IStaticService : IpcService
partial class IStaticService : IpcService
{
public IStaticService(ServiceCtx context) { }

View file

@ -6,7 +6,7 @@ using System;
namespace Ryujinx.HLE.HOS.Services.Nim.Ntc.StaticService
{
class IEnsureNetworkClockAvailabilityService : IpcService
partial class IEnsureNetworkClockAvailabilityService : IpcService
{
private readonly KEvent _finishNotificationEvent;
private ResultCode _taskResultCode;

View file

@ -8,7 +8,7 @@ using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Ns.Aoc
{
[Service("aoc:u")]
class IAddOnContentManager : IpcService
partial class IAddOnContentManager : IpcService
{
private readonly KEvent _addOnContentListChangedEvent;
private int _addOnContentListChangedEventHandle;

View file

@ -6,7 +6,7 @@ using System;
namespace Ryujinx.HLE.HOS.Services.Ns.Aoc
{
class IPurchaseEventManager : IpcService
partial class IPurchaseEventManager : IpcService
{
private readonly KEvent _purchasedEvent;

View file

@ -4,7 +4,7 @@ using Ryujinx.Common.Utilities;
namespace Ryujinx.HLE.HOS.Services.Ns
{
[Service("ns:am")]
class IApplicationManagerInterface : IpcService
partial class IApplicationManagerInterface : IpcService
{
public IApplicationManagerInterface(ServiceCtx context) { }

Some files were not shown because too many files have changed in this diff Show more