Compare commits

...

4 Commits

Author SHA1 Message Date
jcm
84d6e8d121 Standardize logging locations across desktop platforms (#6238)
* Standardize logging locations across desktop platforms

* Return null instead of empty literal on exceptions

* Remove LogDirectoryPath from LoggerModule

* Catch exception when creating DirectoryInfo in FileLogTarget

* Remove redundant log path vars, handle exception better, add null check

* Address styling issues

* Remove extra newline, quote file path in log, move directory check to OpenHelper

* Add GetOrCreateLogsDir to get/create log directory during runtime

* misc format changes

* Update src/Ryujinx.Common/Configuration/AppDataManager.cs

---------

Co-authored-by: jcm <butt@butts.com>
Co-authored-by: TSR Berry <20988865+TSRBerry@users.noreply.github.com>
Co-authored-by: Ac_K <Acoustik666@gmail.com>
2024-02-11 02:17:19 +01:00
lasers
95c4912d58 Linux: Reorder available executables in Ryujinx.sh (#6171)
* Avoid Ryujinx.Headless.SDL2 as a last resort in Ryujinx.desktop when you
  have more than one executable installed.
2024-02-11 00:57:23 +01:00
Isaac Marovitz
356a75af0b Remove ReflectionBinding in Mod Manager (#6280) 2024-02-11 00:52:11 +01:00
sunshineinabox
4ae9921063 Update Avalonia About Window like requested in PR #6267 (#6278)
* Update About Window like requested in PR #6267

* Feedback

* Apply suggestions from code review

Co-authored-by: Isaac Marovitz <42140194+IsaacMarovitz@users.noreply.github.com>

* Fix indents

---------

Co-authored-by: Isaac Marovitz <42140194+IsaacMarovitz@users.noreply.github.com>
2024-02-11 00:45:14 +01:00
9 changed files with 198 additions and 79 deletions

View File

@@ -1,14 +1,21 @@
#!/bin/sh #!/bin/sh
SCRIPT_DIR=$(dirname "$(realpath "$0")") SCRIPT_DIR=$(dirname "$(realpath "$0")")
RYUJINX_BIN="Ryujinx"
if [ -f "$SCRIPT_DIR/Ryujinx.Headless.SDL2" ]; then
RYUJINX_BIN="Ryujinx.Headless.SDL2"
fi
if [ -f "$SCRIPT_DIR/Ryujinx.Ava" ]; then if [ -f "$SCRIPT_DIR/Ryujinx.Ava" ]; then
RYUJINX_BIN="Ryujinx.Ava" RYUJINX_BIN="Ryujinx.Ava"
fi fi
if [ -f "$SCRIPT_DIR/Ryujinx.Headless.SDL2" ]; then if [ -f "$SCRIPT_DIR/Ryujinx" ]; then
RYUJINX_BIN="Ryujinx.Headless.SDL2" RYUJINX_BIN="Ryujinx"
fi
if [ -z "$RYUJINX_BIN" ]; then
exit 1
fi fi
COMMAND="env DOTNET_EnableAlternateStackCheck=1" COMMAND="env DOTNET_EnableAlternateStackCheck=1"
@@ -17,4 +24,4 @@ if command -v gamemoderun > /dev/null 2>&1; then
COMMAND="$COMMAND gamemoderun" COMMAND="$COMMAND gamemoderun"
fi fi
$COMMAND "$SCRIPT_DIR/$RYUJINX_BIN" "$@" exec $COMMAND "$SCRIPT_DIR/$RYUJINX_BIN" "$@"

View File

@@ -1350,16 +1350,11 @@ namespace Ryujinx.Ava.UI.ViewModels
public void OpenLogsFolder() public void OpenLogsFolder()
{ {
string logPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs"); string logPath = AppDataManager.GetOrCreateLogsDir();
if (!string.IsNullOrEmpty(logPath))
if (LoggerModule.LogDirectoryPath != null)
{ {
logPath = LoggerModule.LogDirectoryPath; OpenHelper.OpenFolder(logPath);
} }
new DirectoryInfo(logPath).Create();
OpenHelper.OpenFolder(logPath);
} }
public void ToggleDockMode() public void ToggleDockMode()

View File

@@ -44,31 +44,37 @@
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<Image <StackPanel
Grid.Column="0" Grid.Column="1"
Height="80" Orientation="Horizontal"
Source="resm:Ryujinx.Ui.Common.Resources.Logo_Ryujinx.png?assembly=Ryujinx.Ui.Common" /> HorizontalAlignment="Center"
<WrapPanel Spacing="10">
Grid.Column="2" <Image
HorizontalAlignment="Right" Height="80"
VerticalAlignment="Center" Source="resm:Ryujinx.Ui.Common.Resources.Logo_Ryujinx.png?assembly=Ryujinx.Ui.Common"
Orientation="Vertical">
<TextBlock
HorizontalAlignment="Center" HorizontalAlignment="Center"
IsHitTestVisible="True" />
<WrapPanel
HorizontalAlignment="Right"
VerticalAlignment="Center" VerticalAlignment="Center"
FontSize="28" Orientation="Vertical">
FontWeight="Bold" <TextBlock
Text="Ryujinx" FontSize="28"
TextAlignment="Center" FontWeight="Bold"
Width="110" /> Text="Ryujinx"
<TextBlock TextAlignment="Start"
HorizontalAlignment="Center" Width="110"
VerticalAlignment="Center" HorizontalAlignment="Center"
FontSize="11" VerticalAlignment="Center" />
Text="(REE-YOU-JINX)" <TextBlock
TextAlignment="Center" FontSize="11"
Width="110" /> Text="(REE-YOU-JINX)"
</WrapPanel> TextAlignment="Start"
Width="110"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</WrapPanel>
</StackPanel>
</Grid> </Grid>
<TextBlock <TextBlock
HorizontalAlignment="Center" HorizontalAlignment="Center"

View File

@@ -40,14 +40,14 @@
Name="EnableAllButton" Name="EnableAllButton"
MinWidth="90" MinWidth="90"
Margin="5" Margin="5"
Command="{ReflectionBinding EnableAll}"> Command="{Binding EnableAll}">
<TextBlock Text="{locale:Locale DlcManagerEnableAllButton}" /> <TextBlock Text="{locale:Locale DlcManagerEnableAllButton}" />
</Button> </Button>
<Button <Button
Name="DisableAllButton" Name="DisableAllButton"
MinWidth="90" MinWidth="90"
Margin="5" Margin="5"
Command="{ReflectionBinding DisableAll}"> Command="{Binding DisableAll}">
<TextBlock Text="{locale:Locale DlcManagerDisableAllButton}" /> <TextBlock Text="{locale:Locale DlcManagerDisableAllButton}" />
</Button> </Button>
</StackPanel> </StackPanel>

View File

@@ -30,6 +30,8 @@ namespace Ryujinx.Common.Configuration
public static string KeysDirPath { get; private set; } public static string KeysDirPath { get; private set; }
public static string KeysDirPathUser { get; } public static string KeysDirPathUser { get; }
public static string LogsDirPath { get; private set; }
public const string DefaultNandDir = "bis"; public const string DefaultNandDir = "bis";
public const string DefaultSdcardDir = "sdcard"; public const string DefaultSdcardDir = "sdcard";
private const string DefaultModsDir = "mods"; private const string DefaultModsDir = "mods";
@@ -46,15 +48,7 @@ namespace Ryujinx.Common.Configuration
public static void Initialize(string baseDirPath) public static void Initialize(string baseDirPath)
{ {
string appDataPath; string appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
if (OperatingSystem.IsMacOS())
{
appDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Library", "Application Support");
}
else
{
appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
}
if (appDataPath.Length == 0) if (appDataPath.Length == 0)
{ {
@@ -118,9 +112,126 @@ namespace Ryujinx.Common.Configuration
SetupBasePaths(); SetupBasePaths();
} }
public static string GetOrCreateLogsDir()
{
if (Directory.Exists(LogsDirPath))
{
return LogsDirPath;
}
Logger.Notice.Print(LogClass.Application, "Logging directory not found; attempting to create new logging directory.");
LogsDirPath = SetUpLogsDir();
return LogsDirPath;
}
private static string SetUpLogsDir()
{
string logDir = "";
if (Mode == LaunchMode.Portable)
{
logDir = Path.Combine(BaseDirPath, "Logs");
try
{
Directory.CreateDirectory(logDir);
}
catch
{
Logger.Warning?.Print(LogClass.Application, $"Logging directory could not be created '{logDir}'");
return null;
}
}
else
{
if (OperatingSystem.IsMacOS())
{
// NOTE: Should evaluate to "~/Library/Logs/Ryujinx/".
logDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Library", "Logs", DefaultBaseDir);
try
{
Directory.CreateDirectory(logDir);
}
catch
{
Logger.Warning?.Print(LogClass.Application, $"Logging directory could not be created '{logDir}'");
logDir = "";
}
if (string.IsNullOrEmpty(logDir))
{
// NOTE: Should evaluate to "~/Library/Application Support/Ryujinx/Logs".
logDir = Path.Combine(BaseDirPath, "Logs");
try
{
Directory.CreateDirectory(logDir);
}
catch
{
Logger.Warning?.Print(LogClass.Application, $"Logging directory could not be created '{logDir}'");
return null;
}
}
}
else if (OperatingSystem.IsWindows())
{
// NOTE: Should evaluate to a "Logs" directory in whatever directory Ryujinx was launched from.
logDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs");
try
{
Directory.CreateDirectory(logDir);
}
catch
{
Logger.Warning?.Print(LogClass.Application, $"Logging directory could not be created '{logDir}'");
logDir = "";
}
if (string.IsNullOrEmpty(logDir))
{
// NOTE: Should evaluate to "C:\Users\user\AppData\Roaming\Ryujinx\Logs".
logDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), DefaultBaseDir, "Logs");
try
{
Directory.CreateDirectory(logDir);
}
catch
{
Logger.Warning?.Print(LogClass.Application, $"Logging directory could not be created '{logDir}'");
return null;
}
}
}
else if (OperatingSystem.IsLinux())
{
// NOTE: Should evaluate to "~/.config/Ryujinx/Logs".
logDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), DefaultBaseDir, "Logs");
try
{
Directory.CreateDirectory(logDir);
}
catch
{
Logger.Warning?.Print(LogClass.Application, $"Logging directory could not be created '{logDir}'");
return null;
}
}
}
return logDir;
}
private static void SetupBasePaths() private static void SetupBasePaths()
{ {
Directory.CreateDirectory(BaseDirPath); Directory.CreateDirectory(BaseDirPath);
LogsDirPath = SetUpLogsDir();
Directory.CreateDirectory(GamesDirPath = Path.Combine(BaseDirPath, GamesDir)); Directory.CreateDirectory(GamesDirPath = Path.Combine(BaseDirPath, GamesDir));
Directory.CreateDirectory(ProfilesDirPath = Path.Combine(BaseDirPath, ProfilesDir)); Directory.CreateDirectory(ProfilesDirPath = Path.Combine(BaseDirPath, ProfilesDir));
Directory.CreateDirectory(KeysDirPath = Path.Combine(BaseDirPath, KeysDir)); Directory.CreateDirectory(KeysDirPath = Path.Combine(BaseDirPath, KeysDir));

View File

@@ -23,7 +23,18 @@ namespace Ryujinx.Common.Logging.Targets
public static FileStream PrepareLogFile(string path) public static FileStream PrepareLogFile(string path)
{ {
// Ensure directory is present // Ensure directory is present
DirectoryInfo logDir = new(path); DirectoryInfo logDir;
try
{
logDir = new DirectoryInfo(path);
}
catch (ArgumentException exception)
{
Logger.Warning?.Print(LogClass.Application, $"Logging directory path ('{path}') was invalid: {exception}");
return null;
}
try try
{ {
logDir.Create(); logDir.Create();

View File

@@ -427,16 +427,12 @@ namespace Ryujinx.Headless.SDL2
if (!option.DisableFileLog) if (!option.DisableFileLog)
{ {
FileStream logFile = FileLogTarget.PrepareLogFile(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs")); string logDir = AppDataManager.LogsDirPath;
FileStream logFile = null;
if (logFile == null) if (!string.IsNullOrEmpty(logDir))
{ {
logFile = FileLogTarget.PrepareLogFile(Path.Combine(AppDataManager.BaseDirPath, "Logs")); logFile = FileLogTarget.PrepareLogFile(logDir);
if (logFile == null)
{
Logger.Error?.Print(LogClass.Application, "No writable log directory available. Make sure either the application directory or the Ryujinx directory is writable.");
}
} }
if (logFile != null) if (logFile != null)
@@ -447,6 +443,10 @@ namespace Ryujinx.Headless.SDL2
AsyncLogTargetOverflowAction.Block AsyncLogTargetOverflowAction.Block
)); ));
} }
else
{
Logger.Error?.Print(LogClass.Application, "No writable log directory available. Make sure either the Logs directory, Application Data, or the Ryujinx directory is writable.");
}
} }
// Setup graphics configuration // Setup graphics configuration

View File

@@ -9,8 +9,6 @@ namespace Ryujinx.Ui.Common.Configuration
{ {
public static class LoggerModule public static class LoggerModule
{ {
public static string LogDirectoryPath { get; private set; }
public static void Initialize() public static void Initialize()
{ {
ConfigurationState.Instance.Logger.EnableDebug.Event += ReloadEnableDebug; ConfigurationState.Instance.Logger.EnableDebug.Event += ReloadEnableDebug;
@@ -84,26 +82,22 @@ namespace Ryujinx.Ui.Common.Configuration
{ {
if (e.NewValue) if (e.NewValue)
{ {
string logDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs"); string logDir = AppDataManager.LogsDirPath;
FileStream logFile = FileLogTarget.PrepareLogFile(logDir); FileStream logFile = null;
if (!string.IsNullOrEmpty(logDir))
{
logFile = FileLogTarget.PrepareLogFile(logDir);
}
if (logFile == null) if (logFile == null)
{ {
logDir = Path.Combine(AppDataManager.BaseDirPath, "Logs"); Logger.Error?.Print(LogClass.Application, "No writable log directory available. Make sure either the Logs directory, Application Data, or the Ryujinx directory is writable.");
logFile = FileLogTarget.PrepareLogFile(logDir); Logger.RemoveTarget("file");
if (logFile == null) return;
{
Logger.Error?.Print(LogClass.Application, "No writable log directory available. Make sure either the application directory or the Ryujinx directory is writable.");
LogDirectoryPath = null;
Logger.RemoveTarget("file");
return;
}
} }
LogDirectoryPath = logDir;
Logger.AddTarget(new AsyncLogTargetWrapper( Logger.AddTarget(new AsyncLogTargetWrapper(
new FileLogTarget("file", logFile), new FileLogTarget("file", logFile),
1000, 1000,

View File

@@ -1376,16 +1376,11 @@ namespace Ryujinx.Ui
private void OpenLogsFolder_Pressed(object sender, EventArgs args) private void OpenLogsFolder_Pressed(object sender, EventArgs args)
{ {
string logPath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs"); string logPath = AppDataManager.GetOrCreateLogsDir();
if (!string.IsNullOrEmpty(logPath))
if (LoggerModule.LogDirectoryPath != null)
{ {
logPath = LoggerModule.LogDirectoryPath; OpenHelper.OpenFolder(logPath);
} }
new DirectoryInfo(logPath).Create();
OpenHelper.OpenFolder(logPath);
} }
private void Exit_Pressed(object sender, EventArgs args) private void Exit_Pressed(object sender, EventArgs args)