added OverrideMods argument for headless ryujinx

This commit is contained in:
simon 2025-01-06 23:19:43 +01:00
parent 8827bce223
commit dcd19facff
2 changed files with 57 additions and 50 deletions

View file

@ -1,6 +1,7 @@
using CommandLine; using CommandLine;
using Gommon; using Gommon;
using Ryujinx.Ava; using Ryujinx.Ava;
using Ryujinx.Ava.Utilities;
using Ryujinx.Ava.Utilities.Configuration; using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Common; using Ryujinx.Common;
using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration;
@ -84,23 +85,23 @@ namespace Ryujinx.Headless
.WithNotParsed(errors => .WithNotParsed(errors =>
{ {
Logger.Error?.PrintMsg(LogClass.Application, "Error parsing command-line arguments:"); Logger.Error?.PrintMsg(LogClass.Application, "Error parsing command-line arguments:");
errors.ForEach(err => Logger.Error?.PrintMsg(LogClass.Application, $" - {err.Tag}")); errors.ForEach(err => Logger.Error?.PrintMsg(LogClass.Application, $" - {err.Tag}"));
}); });
} }
public static void ReloadConfig(string customConfigPath = null) public static void ReloadConfig(string customConfigPath = null)
{ {
string localConfigurationPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ReleaseInformation.ConfigName); string localConfigurationPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ReleaseInformation.ConfigName);
string appDataConfigurationPath = Path.Combine(AppDataManager.BaseDirPath, ReleaseInformation.ConfigName); string appDataConfigurationPath = Path.Combine(AppDataManager.BaseDirPath, ReleaseInformation.ConfigName);
string configurationPath = null; string configurationPath = null;
// Now load the configuration as the other subsystems are now registered // Now load the configuration as the other subsystems are now registered
if (customConfigPath != null && File.Exists(customConfigPath)) if (customConfigPath != null && File.Exists(customConfigPath))
{ {
configurationPath = customConfigPath; configurationPath = customConfigPath;
} }
else if (File.Exists(localConfigurationPath)) else if (File.Exists(localConfigurationPath))
{ {
configurationPath = localConfigurationPath; configurationPath = localConfigurationPath;
@ -147,11 +148,11 @@ namespace Ryujinx.Headless
option.InheritMainConfig(originalArgs, ConfigurationState.Instance, out useLastUsedProfile); option.InheritMainConfig(originalArgs, ConfigurationState.Instance, out useLastUsedProfile);
} }
AppDataManager.Initialize(option.BaseDataDir, []); AppDataManager.Initialize(option.BaseDataDir, option.OverrideMods.Split(","));
if (useLastUsedProfile && AccountSaveDataManager.GetLastUsedUser().TryGet(out var profile)) if (useLastUsedProfile && AccountSaveDataManager.GetLastUsedUser().TryGet(out var profile))
option.UserProfile = profile.Name; option.UserProfile = profile.Name;
// Check if keys exists. // Check if keys exists.
if (!File.Exists(Path.Combine(AppDataManager.KeysDirPath, "prod.keys"))) if (!File.Exists(Path.Combine(AppDataManager.KeysDirPath, "prod.keys")))
{ {
@ -160,14 +161,14 @@ namespace Ryujinx.Headless
Logger.Error?.Print(LogClass.Application, "Keys not found"); Logger.Error?.Print(LogClass.Application, "Keys not found");
} }
} }
ReloadConfig(); ReloadConfig();
if (option.InheritConfig) if (option.InheritConfig)
{ {
option.InheritMainConfigInput(originalArgs, ConfigurationState.Instance); option.InheritMainConfigInput(originalArgs, ConfigurationState.Instance);
} }
_virtualFileSystem = VirtualFileSystem.CreateInstance(); _virtualFileSystem = VirtualFileSystem.CreateInstance();
_libHacHorizonManager = new LibHacHorizonManager(); _libHacHorizonManager = new LibHacHorizonManager();
@ -230,9 +231,9 @@ namespace Ryujinx.Headless
_enableMouse = option.EnableMouse; _enableMouse = option.EnableMouse;
LoadPlayerConfiguration(option.InputProfile1Name, option.InputId1, PlayerIndex.Player1); LoadPlayerConfiguration(option.InputProfile1Name, option.InputId1, PlayerIndex.Player1);
LoadPlayerConfiguration(option.InputProfile2Name, option.InputId2, PlayerIndex.Player2); LoadPlayerConfiguration(option.InputProfile2Name, option.InputId2, PlayerIndex.Player2);
LoadPlayerConfiguration(option.InputProfile3Name, option.InputId3, PlayerIndex.Player3); LoadPlayerConfiguration(option.InputProfile3Name, option.InputId3, PlayerIndex.Player3);
LoadPlayerConfiguration(option.InputProfile4Name, option.InputId4, PlayerIndex.Player4); LoadPlayerConfiguration(option.InputProfile4Name, option.InputId4, PlayerIndex.Player4);
LoadPlayerConfiguration(option.InputProfile5Name, option.InputId5, PlayerIndex.Player5); LoadPlayerConfiguration(option.InputProfile5Name, option.InputId5, PlayerIndex.Player5);
@ -240,7 +241,7 @@ namespace Ryujinx.Headless
LoadPlayerConfiguration(option.InputProfile7Name, option.InputId7, PlayerIndex.Player7); LoadPlayerConfiguration(option.InputProfile7Name, option.InputId7, PlayerIndex.Player7);
LoadPlayerConfiguration(option.InputProfile8Name, option.InputId8, PlayerIndex.Player8); LoadPlayerConfiguration(option.InputProfile8Name, option.InputId8, PlayerIndex.Player8);
LoadPlayerConfiguration(option.InputProfileHandheldName, option.InputIdHandheld, PlayerIndex.Handheld); LoadPlayerConfiguration(option.InputProfileHandheldName, option.InputIdHandheld, PlayerIndex.Handheld);
if (_inputConfiguration.Count == 0) if (_inputConfiguration.Count == 0)
{ {
return; return;
@ -304,7 +305,7 @@ namespace Ryujinx.Headless
_inputManager.Dispose(); _inputManager.Dispose();
return; return;
void LoadPlayerConfiguration(string inputProfileName, string inputId, PlayerIndex index) void LoadPlayerConfiguration(string inputProfileName, string inputId, PlayerIndex index)
{ {
if (index == PlayerIndex.Handheld && _inputConfiguration.Count > 0) if (index == PlayerIndex.Handheld && _inputConfiguration.Count > 0)
@ -312,7 +313,7 @@ namespace Ryujinx.Headless
Logger.Info?.Print(LogClass.Configuration, "Skipping handheld configuration as there are already other players configured."); Logger.Info?.Print(LogClass.Configuration, "Skipping handheld configuration as there are already other players configured.");
return; return;
} }
InputConfig inputConfig = option.InheritedInputConfigs[index] ?? HandlePlayerConfiguration(inputProfileName, inputId, index); InputConfig inputConfig = option.InheritedInputConfigs[index] ?? HandlePlayerConfiguration(inputProfileName, inputId, index);
if (inputConfig != null) if (inputConfig != null)

View file

@ -24,7 +24,7 @@ namespace Ryujinx.Headless
if (NeedsOverride(nameof(EnableKeyboard))) if (NeedsOverride(nameof(EnableKeyboard)))
EnableKeyboard = configurationState.Hid.EnableKeyboard; EnableKeyboard = configurationState.Hid.EnableKeyboard;
if (NeedsOverride(nameof(EnableMouse))) if (NeedsOverride(nameof(EnableMouse)))
EnableMouse = configurationState.Hid.EnableMouse; EnableMouse = configurationState.Hid.EnableMouse;
@ -39,40 +39,40 @@ namespace Ryujinx.Headless
if (NeedsOverride(nameof(DisableFsIntegrityChecks))) if (NeedsOverride(nameof(DisableFsIntegrityChecks)))
DisableFsIntegrityChecks = configurationState.System.EnableFsIntegrityChecks; DisableFsIntegrityChecks = configurationState.System.EnableFsIntegrityChecks;
if (NeedsOverride(nameof(FsGlobalAccessLogMode))) if (NeedsOverride(nameof(FsGlobalAccessLogMode)))
FsGlobalAccessLogMode = configurationState.System.FsGlobalAccessLogMode; FsGlobalAccessLogMode = configurationState.System.FsGlobalAccessLogMode;
if (NeedsOverride(nameof(VSyncMode))) if (NeedsOverride(nameof(VSyncMode)))
VSyncMode = configurationState.Graphics.VSyncMode; VSyncMode = configurationState.Graphics.VSyncMode;
if (NeedsOverride(nameof(CustomVSyncInterval))) if (NeedsOverride(nameof(CustomVSyncInterval)))
CustomVSyncInterval = configurationState.Graphics.CustomVSyncInterval; CustomVSyncInterval = configurationState.Graphics.CustomVSyncInterval;
if (NeedsOverride(nameof(DisableShaderCache))) if (NeedsOverride(nameof(DisableShaderCache)))
DisableShaderCache = !configurationState.Graphics.EnableShaderCache; DisableShaderCache = !configurationState.Graphics.EnableShaderCache;
if (NeedsOverride(nameof(EnableTextureRecompression))) if (NeedsOverride(nameof(EnableTextureRecompression)))
EnableTextureRecompression = configurationState.Graphics.EnableTextureRecompression; EnableTextureRecompression = configurationState.Graphics.EnableTextureRecompression;
if (NeedsOverride(nameof(DisableDockedMode))) if (NeedsOverride(nameof(DisableDockedMode)))
DisableDockedMode = !configurationState.System.EnableDockedMode; DisableDockedMode = !configurationState.System.EnableDockedMode;
if (NeedsOverride(nameof(SystemLanguage))) if (NeedsOverride(nameof(SystemLanguage)))
SystemLanguage = (SystemLanguage)(int)configurationState.System.Language.Value; SystemLanguage = (SystemLanguage)(int)configurationState.System.Language.Value;
if (NeedsOverride(nameof(SystemRegion))) if (NeedsOverride(nameof(SystemRegion)))
SystemRegion = (RegionCode)(int)configurationState.System.Region.Value; SystemRegion = (RegionCode)(int)configurationState.System.Region.Value;
if (NeedsOverride(nameof(SystemTimeZone))) if (NeedsOverride(nameof(SystemTimeZone)))
SystemTimeZone = configurationState.System.TimeZone; SystemTimeZone = configurationState.System.TimeZone;
if (NeedsOverride(nameof(SystemTimeOffset))) if (NeedsOverride(nameof(SystemTimeOffset)))
SystemTimeOffset = configurationState.System.SystemTimeOffset; SystemTimeOffset = configurationState.System.SystemTimeOffset;
if (NeedsOverride(nameof(MemoryManagerMode))) if (NeedsOverride(nameof(MemoryManagerMode)))
MemoryManagerMode = configurationState.System.MemoryManagerMode; MemoryManagerMode = configurationState.System.MemoryManagerMode;
if (NeedsOverride(nameof(AudioVolume))) if (NeedsOverride(nameof(AudioVolume)))
AudioVolume = configurationState.System.AudioVolume; AudioVolume = configurationState.System.AudioVolume;
@ -81,28 +81,28 @@ namespace Ryujinx.Headless
if (NeedsOverride(nameof(MultiplayerLanInterfaceId))) if (NeedsOverride(nameof(MultiplayerLanInterfaceId)))
MultiplayerLanInterfaceId = configurationState.Multiplayer.LanInterfaceId; MultiplayerLanInterfaceId = configurationState.Multiplayer.LanInterfaceId;
if (NeedsOverride(nameof(DisableFileLog))) if (NeedsOverride(nameof(DisableFileLog)))
DisableFileLog = !configurationState.Logger.EnableFileLog; DisableFileLog = !configurationState.Logger.EnableFileLog;
if (NeedsOverride(nameof(LoggingEnableDebug))) if (NeedsOverride(nameof(LoggingEnableDebug)))
LoggingEnableDebug = configurationState.Logger.EnableDebug; LoggingEnableDebug = configurationState.Logger.EnableDebug;
if (NeedsOverride(nameof(LoggingDisableStub))) if (NeedsOverride(nameof(LoggingDisableStub)))
LoggingDisableStub = !configurationState.Logger.EnableStub; LoggingDisableStub = !configurationState.Logger.EnableStub;
if (NeedsOverride(nameof(LoggingDisableInfo))) if (NeedsOverride(nameof(LoggingDisableInfo)))
LoggingDisableInfo = !configurationState.Logger.EnableInfo; LoggingDisableInfo = !configurationState.Logger.EnableInfo;
if (NeedsOverride(nameof(LoggingDisableWarning))) if (NeedsOverride(nameof(LoggingDisableWarning)))
LoggingDisableWarning = !configurationState.Logger.EnableWarn; LoggingDisableWarning = !configurationState.Logger.EnableWarn;
if (NeedsOverride(nameof(LoggingDisableError))) if (NeedsOverride(nameof(LoggingDisableError)))
LoggingDisableError = !configurationState.Logger.EnableError; LoggingDisableError = !configurationState.Logger.EnableError;
if (NeedsOverride(nameof(LoggingEnableTrace))) if (NeedsOverride(nameof(LoggingEnableTrace)))
LoggingEnableTrace = configurationState.Logger.EnableTrace; LoggingEnableTrace = configurationState.Logger.EnableTrace;
if (NeedsOverride(nameof(LoggingDisableGuest))) if (NeedsOverride(nameof(LoggingDisableGuest)))
LoggingDisableGuest = !configurationState.Logger.EnableGuest; LoggingDisableGuest = !configurationState.Logger.EnableGuest;
@ -114,45 +114,45 @@ namespace Ryujinx.Headless
if (NeedsOverride(nameof(ResScale))) if (NeedsOverride(nameof(ResScale)))
ResScale = configurationState.Graphics.ResScale; ResScale = configurationState.Graphics.ResScale;
if (NeedsOverride(nameof(MaxAnisotropy))) if (NeedsOverride(nameof(MaxAnisotropy)))
MaxAnisotropy = configurationState.Graphics.MaxAnisotropy; MaxAnisotropy = configurationState.Graphics.MaxAnisotropy;
if (NeedsOverride(nameof(AspectRatio))) if (NeedsOverride(nameof(AspectRatio)))
AspectRatio = configurationState.Graphics.AspectRatio; AspectRatio = configurationState.Graphics.AspectRatio;
if (NeedsOverride(nameof(BackendThreading))) if (NeedsOverride(nameof(BackendThreading)))
BackendThreading = configurationState.Graphics.BackendThreading; BackendThreading = configurationState.Graphics.BackendThreading;
if (NeedsOverride(nameof(DisableMacroHLE))) if (NeedsOverride(nameof(DisableMacroHLE)))
DisableMacroHLE = !configurationState.Graphics.EnableMacroHLE; DisableMacroHLE = !configurationState.Graphics.EnableMacroHLE;
if (NeedsOverride(nameof(GraphicsShadersDumpPath))) if (NeedsOverride(nameof(GraphicsShadersDumpPath)))
GraphicsShadersDumpPath = configurationState.Graphics.ShadersDumpPath; GraphicsShadersDumpPath = configurationState.Graphics.ShadersDumpPath;
if (NeedsOverride(nameof(GraphicsBackend))) if (NeedsOverride(nameof(GraphicsBackend)))
GraphicsBackend = configurationState.Graphics.GraphicsBackend; GraphicsBackend = configurationState.Graphics.GraphicsBackend;
if (NeedsOverride(nameof(AntiAliasing))) if (NeedsOverride(nameof(AntiAliasing)))
AntiAliasing = configurationState.Graphics.AntiAliasing; AntiAliasing = configurationState.Graphics.AntiAliasing;
if (NeedsOverride(nameof(ScalingFilter))) if (NeedsOverride(nameof(ScalingFilter)))
ScalingFilter = configurationState.Graphics.ScalingFilter; ScalingFilter = configurationState.Graphics.ScalingFilter;
if (NeedsOverride(nameof(ScalingFilterLevel))) if (NeedsOverride(nameof(ScalingFilterLevel)))
ScalingFilterLevel = configurationState.Graphics.ScalingFilterLevel; ScalingFilterLevel = configurationState.Graphics.ScalingFilterLevel;
if (NeedsOverride(nameof(DramSize))) if (NeedsOverride(nameof(DramSize)))
DramSize = configurationState.System.DramSize; DramSize = configurationState.System.DramSize;
if (NeedsOverride(nameof(IgnoreMissingServices))) if (NeedsOverride(nameof(IgnoreMissingServices)))
IgnoreMissingServices = configurationState.System.IgnoreMissingServices; IgnoreMissingServices = configurationState.System.IgnoreMissingServices;
if (NeedsOverride(nameof(IgnoreControllerApplet))) if (NeedsOverride(nameof(IgnoreControllerApplet)))
IgnoreControllerApplet = configurationState.IgnoreApplet; IgnoreControllerApplet = configurationState.IgnoreApplet;
return; return;
bool NeedsOverride(string argKey) => originalArgs.None(arg => arg.TrimStart('-').EqualsIgnoreCase(OptionName(argKey))); bool NeedsOverride(string argKey) => originalArgs.None(arg => arg.TrimStart('-').EqualsIgnoreCase(OptionName(argKey)));
} }
@ -179,15 +179,15 @@ namespace Ryujinx.Headless
} }
return; return;
bool NeedsOverride(string argKey) => originalArgs.None(arg => arg.TrimStart('-').EqualsIgnoreCase(OptionName(argKey))); bool NeedsOverride(string argKey) => originalArgs.None(arg => arg.TrimStart('-').EqualsIgnoreCase(OptionName(argKey)));
} }
private static string OptionName(string propertyName) => private static string OptionName(string propertyName) =>
typeof(Options)!.GetProperty(propertyName)!.GetCustomAttribute<OptionAttribute>()!.LongName; typeof(Options)!.GetProperty(propertyName)!.GetCustomAttribute<OptionAttribute>()!.LongName;
// General // General
[Option("use-main-config", Required = false, Default = false, HelpText = "Use the settings from what was configured via the UI.")] [Option("use-main-config", Required = false, Default = false, HelpText = "Use the settings from what was configured via the UI.")]
public bool InheritConfig { get; set; } public bool InheritConfig { get; set; }
@ -410,7 +410,7 @@ namespace Ryujinx.Headless
[Option("ignore-missing-services", Required = false, Default = false, HelpText = "Enable ignoring missing services.")] [Option("ignore-missing-services", Required = false, Default = false, HelpText = "Enable ignoring missing services.")]
public bool IgnoreMissingServices { get; set; } public bool IgnoreMissingServices { get; set; }
[Option("ignore-controller-applet", Required = false, Default = false, HelpText = "Enable ignoring the controller applet when your game loses connection to your controller.")] [Option("ignore-controller-applet", Required = false, Default = false, HelpText = "Enable ignoring the controller applet when your game loses connection to your controller.")]
public bool IgnoreControllerApplet { get; set; } public bool IgnoreControllerApplet { get; set; }
@ -420,5 +420,11 @@ namespace Ryujinx.Headless
public string InputPath { get; set; } public string InputPath { get; set; }
public SafeDictionary<PlayerIndex, InputConfig> InheritedInputConfigs = new(); public SafeDictionary<PlayerIndex, InputConfig> InheritedInputConfigs = new();
// Mod
[Option('m', "mod", Required = false, Default = "", HelpText = "Overrides enabled mods with user input (Format: \"mod1\",\"mod2\").")]
public string OverrideMods { get; set; }
} }
} }