diff --git a/LANCommander.Launcher/LANCommander.Launcher.csproj b/LANCommander.Launcher/LANCommander.Launcher.csproj
index d40d5bb6..39af3e04 100644
--- a/LANCommander.Launcher/LANCommander.Launcher.csproj
+++ b/LANCommander.Launcher/LANCommander.Launcher.csproj
@@ -72,10 +72,6 @@
-
-
-
-
diff --git a/LANCommander.Launcher/Program.cs b/LANCommander.Launcher/Program.cs
index d2f133af..e54c8d23 100644
--- a/LANCommander.Launcher/Program.cs
+++ b/LANCommander.Launcher/Program.cs
@@ -1,8 +1,6 @@
using LANCommander.Launcher.Services;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
-using Serilog;
-using Serilog.Events;
using System.Runtime.InteropServices;
using LANCommander.Launcher.Data;
using LANCommander.Launcher.Enums;
@@ -17,78 +15,43 @@ class Program
[STAThread]
static void Main(string[] args)
{
- // Map the Microsoft.Extensions.Logging.LogLevel to Serilog.LogEventLevel.
- var serilogLogLevel = MapLogLevel(LogLevel.Debug);
-
- using var Logger = new LoggerConfiguration()
- .MinimumLevel.Is(serilogLogLevel)
- .MinimumLevel.Override("Microsoft.EntityFrameworkCore.Database.Command", LogEventLevel.Warning)
- .MinimumLevel.Override("Microsoft.AspNetCore.Components", LogEventLevel.Warning)
- .MinimumLevel.Override("AntDesign", LogEventLevel.Warning)
- .Enrich.WithProperty("Application", typeof(Program).Assembly.GetName().Name)
- //.WriteTo.File(Path.Combine(settings.Debug.LoggingPath, "log-.txt"), rollingInterval: settings.Debug.LoggingArchivePeriod)
-#if DEBUG
- .WriteTo.Seq("http://localhost:5341")
-#endif
- .CreateLogger();
-
- Logger?.Information("Starting launcher | Version: {Version}", UpdateService.GetCurrentVersion());
-
WindowService.CreateWindow(new WindowOptions
{
Title = "LANCommander",
Type = WindowType.Main
}, null, async (app) =>
{
- using var scope = app.Services.CreateScope();
- var connectionClient = scope.ServiceProvider.GetRequiredService();
- var settingsProvider = scope.ServiceProvider.GetRequiredService>();
- var databaseContext = scope.ServiceProvider.GetRequiredService();
-
- if (!(await connectionClient.PingAsync()))
- await connectionClient.EnableOfflineModeAsync();
-
- if (settingsProvider.CurrentValue.Games.InstallDirectories.Length == 0)
- {
- if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
- settingsProvider.Update(s =>
- {
- s.Games.InstallDirectories = [Path.Combine(Path.GetPathRoot(AppContext.BaseDirectory) ?? "C:", "Games")];
- });
- if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
- settingsProvider.Update(s =>
- {
- s.Games.InstallDirectories = [Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Games")];
- });
- if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
- settingsProvider.Update(s =>
- {
- s.Games.InstallDirectories = [Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Games")];
- });
- }
-
+ var logger = app.Services.GetRequiredService>();
+ logger.LogInformation("Starting launcher | Version: {Version}", UpdateService.GetCurrentVersion());
+
+ using var scope = app.Services.CreateScope();
+ var connectionClient = scope.ServiceProvider.GetRequiredService();
+ var settingsProvider = scope.ServiceProvider.GetRequiredService>();
+ var databaseContext = scope.ServiceProvider.GetRequiredService();
+
+ if (!(await connectionClient.PingAsync()))
+ await connectionClient.EnableOfflineModeAsync();
+
+ if (settingsProvider.CurrentValue.Games.InstallDirectories.Length == 0)
+ {
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ settingsProvider.Update(s =>
+ {
+ s.Games.InstallDirectories = [Path.Combine(Path.GetPathRoot(AppContext.BaseDirectory) ?? "C:", "Games")];
+ });
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
+ settingsProvider.Update(s =>
+ {
+ s.Games.InstallDirectories = [Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Games")];
+ });
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
+ settingsProvider.Update(s =>
+ {
+ s.Games.InstallDirectories = [Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Games")];
+ });
+ }
+
await databaseContext.Database.MigrateAsync();
}, args);
}
-
- ///
- /// Maps Microsoft.Extensions.Logging.LogLevel to Serilog.Events.LogEventLevel.
- ///
- private static LogEventLevel MapLogLevel(LogLevel level)
- {
- return level switch
- {
- LogLevel.Trace => LogEventLevel.Verbose,
- LogLevel.Debug => LogEventLevel.Debug,
- LogLevel.Information => LogEventLevel.Information,
- LogLevel.Warning => LogEventLevel.Warning,
- LogLevel.Error => LogEventLevel.Error,
- LogLevel.Critical => LogEventLevel.Fatal,
- // LogLevel.None indicates logging should be disabled.
- // Serilog does not have a direct "Off" level so you might choose to
- // either bypass logging configuration or set it high enough to ignore messages.
- LogLevel.None => LogEventLevel.Fatal,
- _ => LogEventLevel.Information
- };
- }
}
diff --git a/LANCommander.Launcher/Startup/Logging.cs b/LANCommander.Launcher/Startup/Logging.cs
index ad5fcd61..85fd4c13 100644
--- a/LANCommander.Launcher/Startup/Logging.cs
+++ b/LANCommander.Launcher/Startup/Logging.cs
@@ -1,7 +1,6 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Photino.Blazor;
-using Serilog;
namespace LANCommander.Launcher.Startup;
@@ -9,15 +8,93 @@ public static class Logging
{
public static PhotinoBlazorAppBuilder AddLogging(this PhotinoBlazorAppBuilder builder)
{
- Log.Debug("Configuring logging...");
+ var logsDirectory = Path.Combine(AppContext.BaseDirectory, "Logs");
+ if (!Directory.Exists(logsDirectory))
+ Directory.CreateDirectory(logsDirectory);
- /*builder.Services.AddLogging(loggingBuilder =>
+ builder.Services.AddLogging(loggingBuilder =>
{
loggingBuilder.ClearProviders();
- loggingBuilder.SetMinimumLevel(settings.Debug.LoggingLevel);
- loggingBuilder.AddSerilog(Logger);
- });*/
+ loggingBuilder.AddConsole();
+ loggingBuilder.AddDebug();
+ loggingBuilder.AddFile(logsDirectory);
+ loggingBuilder.SetMinimumLevel(LogLevel.Debug);
+ loggingBuilder.AddFilter("Microsoft.EntityFrameworkCore.Database.Command", LogLevel.Warning);
+ loggingBuilder.AddFilter("Microsoft.AspNetCore.Components", LogLevel.Warning);
+ loggingBuilder.AddFilter("AntDesign", LogLevel.Warning);
+ });
return builder;
}
+
+ private static ILoggingBuilder AddFile(this ILoggingBuilder builder, string logDirectory)
+ {
+ return builder.AddProvider(new FileLoggerProvider(logDirectory));
+ }
+
+ private class FileLogger : ILogger
+ {
+ private readonly string _logDirectory;
+ private readonly string _categoryName;
+
+ public FileLogger(string logDirectory, string categoryName)
+ {
+ _logDirectory = logDirectory;
+ _categoryName = categoryName;
+ }
+
+ public IDisposable? BeginScope(TState state) where TState : notnull => null;
+
+ public bool IsEnabled(LogLevel logLevel) => logLevel != LogLevel.None;
+
+ public void Log(
+ LogLevel logLevel,
+ EventId eventId,
+ TState state,
+ Exception? exception,
+ Func formatter)
+ {
+ if (!IsEnabled(logLevel))
+ return;
+
+ var logFilePath = Path.Combine(
+ _logDirectory,
+ $"log-{DateTime.Now:yyyy-MM-dd}.txt");
+
+ var message = formatter(state, exception);
+ var logMessage = $"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff} [{logLevel}] [{_categoryName}] {message}";
+
+ if (exception != null)
+ logMessage += Environment.NewLine + exception;
+
+ try
+ {
+ lock (_logDirectory)
+ {
+ File.AppendAllText(logFilePath, logMessage + Environment.NewLine);
+ }
+ }
+ catch
+ {
+ // Silently fail if logging to file fails
+ }
+ }
+ }
+
+ private class FileLoggerProvider : ILoggerProvider
+ {
+ private readonly string _logDirectory;
+
+ public FileLoggerProvider(string logDirectory)
+ {
+ _logDirectory = logDirectory;
+ }
+
+ public ILogger CreateLogger(string categoryName)
+ {
+ return new FileLogger(_logDirectory, categoryName);
+ }
+
+ public void Dispose() { }
+ }
}
\ No newline at end of file
diff --git a/LANCommander.Launcher/Startup/Window.cs b/LANCommander.Launcher/Startup/Window.cs
index ee8784a8..fbc7af94 100644
--- a/LANCommander.Launcher/Startup/Window.cs
+++ b/LANCommander.Launcher/Startup/Window.cs
@@ -1,81 +1,82 @@
-using System.Web;
-using LANCommander.Launcher.Services;
-using Microsoft.Extensions.DependencyInjection;
-using Photino.Blazor;
-using Photino.NET;
-using Serilog;
-
-namespace LANCommander.Launcher.Startup;
-
-public static class MainWindow
-{
- public static PhotinoBlazorApp RegisterMainWindow(this PhotinoBlazorApp app)
- {
- app.MainWindow
- .SetTitle("LANCommander Launcher")
- .RegisterWebMessageReceivedHandler(ChatWindowMessageDelegate)
- .SetChromeless(true);
-
- app.MainWindow.WindowClosing += SaveWindowPosition;
-
- return app;
- }
-
- public static PhotinoBlazorApp RegisterMediaHandler(this PhotinoBlazorApp app)
- {
- var settingsProvider = app.Services.GetRequiredService>();
-
- app.MainWindow.RegisterCustomSchemeHandler("media",
- (object sender, string scheme, string url, out string? contentType) =>
- {
- try
- {
- var uri = new Uri(url);
-
- var query = HttpUtility.ParseQueryString(uri.Query);
-
- var id = query["id"];
- var fileId = query["fileId"];
- var crc32 = query["crc32"];
- var mime = query["mime"];
-
- contentType = mime;
-
- var filePath = Path.Combine(settingsProvider.CurrentValue.Media.StoragePath, $"{fileId}-{crc32}");
-
- if (File.Exists(filePath))
- return new FileStream(filePath, FileMode.Open, FileAccess.Read);
- else
- return null;
- }
- catch (Exception ex)
- {
- Log.Warning(ex, "Unable to load media file from local disk {FileUrl}", url);
-
- contentType = "";
- }
-
- return null;
- });
-
- return app;
- }
-
- public static PhotinoBlazorApp RegisterNotificationHandler(this PhotinoBlazorApp app)
- {
- app.MainWindow.RegisterWebMessageReceivedHandler((sender, message) =>
- {
- if (message == "notification")
- app.MainWindow.SendNotification("Test", "test");
- });
-
- return app;
- }
-
- public static PhotinoBlazorApp RegisterImportHandler(this PhotinoBlazorApp app)
- {
- app.MainWindow.RegisterWebMessageReceivedHandler(async (sender, message) =>
- {
+using System.Web;
+using LANCommander.Launcher.Services;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+using Photino.Blazor;
+using Photino.NET;
+
+namespace LANCommander.Launcher.Startup;
+
+public static class MainWindow
+{
+ public static PhotinoBlazorApp RegisterMainWindow(this PhotinoBlazorApp app)
+ {
+ app.MainWindow
+ .SetTitle("LANCommander Launcher")
+ .RegisterWebMessageReceivedHandler(ChatWindowMessageDelegate)
+ .SetChromeless(true);
+
+ app.MainWindow.WindowClosing += SaveWindowPosition;
+
+ return app;
+ }
+
+ public static PhotinoBlazorApp RegisterMediaHandler(this PhotinoBlazorApp app)
+ {
+ var settingsProvider = app.Services.GetRequiredService>();
+ var logger = app.Services.GetRequiredService>();
+
+ app.MainWindow.RegisterCustomSchemeHandler("media",
+ (object sender, string scheme, string url, out string? contentType) =>
+ {
+ try
+ {
+ var uri = new Uri(url);
+
+ var query = HttpUtility.ParseQueryString(uri.Query);
+
+ var id = query["id"];
+ var fileId = query["fileId"];
+ var crc32 = query["crc32"];
+ var mime = query["mime"];
+
+ contentType = mime;
+
+ var filePath = Path.Combine(settingsProvider.CurrentValue.Media.StoragePath, $"{fileId}-{crc32}");
+
+ if (File.Exists(filePath))
+ return new FileStream(filePath, FileMode.Open, FileAccess.Read);
+ else
+ return null;
+ }
+ catch (Exception ex)
+ {
+ logger.LogWarning(ex, "Unable to load media file from local disk {FileUrl}", url);
+
+ contentType = "";
+ }
+
+ return null;
+ });
+
+ return app;
+ }
+
+ public static PhotinoBlazorApp RegisterNotificationHandler(this PhotinoBlazorApp app)
+ {
+ app.MainWindow.RegisterWebMessageReceivedHandler((sender, message) =>
+ {
+ if (message == "notification")
+ app.MainWindow.SendNotification("Test", "test");
+ });
+
+ return app;
+ }
+
+ public static PhotinoBlazorApp RegisterImportHandler(this PhotinoBlazorApp app)
+ {
+ app.MainWindow.RegisterWebMessageReceivedHandler(async (sender, message) =>
+ {
if (message != "import" || sender is null)
return;
@@ -87,64 +88,64 @@ public static class MainWindow
await importService.ImportAsync();
window.SendWebMessage("importComplete");
- });
-
- return app;
- }
-
- static void ChatWindowMessageDelegate(object? sender, string message)
- {
- if (sender == null)
- return;
-
- var parent = (PhotinoWindow)sender;
-
- if (message == "openChat")
- {
- new PhotinoWindow(parent)
- .SetTitle("LANCommander Chat")
- .Load("wwwroot/index.html")
- .WaitForClose();
- }
- }
-
- public static PhotinoBlazorApp RestoreWindowPosition(this PhotinoBlazorApp app)
- {
- var settingsProvider = app.Services.GetRequiredService>();
-
- if (settingsProvider.CurrentValue.Window.Maximized)
- app.MainWindow.SetMaximized(true);
- else
- {
- if (settingsProvider.CurrentValue.Window.Width != 0 && settingsProvider.CurrentValue.Window.Height != 0)
- {
- app.MainWindow.SetSize(settingsProvider.CurrentValue.Window.Width, settingsProvider.CurrentValue.Window.Height);
- app.MainWindow.SetLocation(new System.Drawing.Point(settingsProvider.CurrentValue.Window.X, settingsProvider.CurrentValue.Window.Y));
- }
- else
- {
- app.MainWindow.SetSize(1024, 768);
- app.MainWindow.Center();
- }
- }
-
- return app;
- }
-
- private static bool SaveWindowPosition(object sender, EventArgs e)
- {
- var window = sender as PhotinoWindow;
-
- /*var settings = SettingService.GetSettings();
-
- settings.Window.Maximized = window.Maximized;
- settings.Window.Width = window.Width;
- settings.Window.Height = window.Height;
- settings.Window.X = window.Left;
- settings.Window.Y = window.Top;
-
- SettingService.SaveSettings(settings);*/
-
- return true;
- }
+ });
+
+ return app;
+ }
+
+ static void ChatWindowMessageDelegate(object? sender, string message)
+ {
+ if (sender == null)
+ return;
+
+ var parent = (PhotinoWindow)sender;
+
+ if (message == "openChat")
+ {
+ new PhotinoWindow(parent)
+ .SetTitle("LANCommander Chat")
+ .Load("wwwroot/index.html")
+ .WaitForClose();
+ }
+ }
+
+ public static PhotinoBlazorApp RestoreWindowPosition(this PhotinoBlazorApp app)
+ {
+ var settingsProvider = app.Services.GetRequiredService>();
+
+ if (settingsProvider.CurrentValue.Window.Maximized)
+ app.MainWindow.SetMaximized(true);
+ else
+ {
+ if (settingsProvider.CurrentValue.Window.Width != 0 && settingsProvider.CurrentValue.Window.Height != 0)
+ {
+ app.MainWindow.SetSize(settingsProvider.CurrentValue.Window.Width, settingsProvider.CurrentValue.Window.Height);
+ app.MainWindow.SetLocation(new System.Drawing.Point(settingsProvider.CurrentValue.Window.X, settingsProvider.CurrentValue.Window.Y));
+ }
+ else
+ {
+ app.MainWindow.SetSize(1024, 768);
+ app.MainWindow.Center();
+ }
+ }
+
+ return app;
+ }
+
+ private static bool SaveWindowPosition(object sender, EventArgs e)
+ {
+ var window = sender as PhotinoWindow;
+
+ /*var settings = SettingService.GetSettings();
+
+ settings.Window.Maximized = window.Maximized;
+ settings.Window.Width = window.Width;
+ settings.Window.Height = window.Height;
+ settings.Window.X = window.Left;
+ settings.Window.Y = window.Top;
+
+ SettingService.SaveSettings(settings);*/
+
+ return true;
+ }
}
\ No newline at end of file