using AdonisUI.Controls;
using Microsoft.Win32;
using Serilog;
using System;
using System.Globalization;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Threading;
using FModel.Framework;
using FModel.Services;
using FModel.Settings;
using Newtonsoft.Json;
using Serilog.Sinks.SystemConsole.Themes;
using MessageBox = AdonisUI.Controls.MessageBox;
using MessageBoxImage = AdonisUI.Controls.MessageBoxImage;
using MessageBoxResult = AdonisUI.Controls.MessageBoxResult;
namespace FModel;
///
/// Interaction logic for App.xaml
///
public partial class App
{
[DllImport("kernel32.dll")]
private static extern bool AttachConsole(int dwProcessId);
[DllImport("winbrand.dll", CharSet = CharSet.Unicode)]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
static extern string BrandingFormatString(string format);
protected override void OnStartup(StartupEventArgs e)
{
#if DEBUG
AttachConsole(-1);
#endif
base.OnStartup(e);
try
{
UserSettings.Default = JsonConvert.DeserializeObject(
File.ReadAllText(UserSettings.FilePath), JsonNetSerializer.SerializerSettings);
/*if (UserSettings.Default.ShowChangelog) */MigrateV1Games();
}
catch
{
UserSettings.Default = new UserSettings();
}
var createMe = false;
if (!Directory.Exists(UserSettings.Default.OutputDirectory))
{
UserSettings.Default.OutputDirectory = Path.Combine(Directory.GetCurrentDirectory(), "Output");
}
if (!Directory.Exists(UserSettings.Default.RawDataDirectory))
{
createMe = true;
UserSettings.Default.RawDataDirectory = Path.Combine(UserSettings.Default.OutputDirectory, "Exports");
}
if (!Directory.Exists(UserSettings.Default.PropertiesDirectory))
{
createMe = true;
UserSettings.Default.PropertiesDirectory = Path.Combine(UserSettings.Default.OutputDirectory, "Exports");
}
if (!Directory.Exists(UserSettings.Default.TextureDirectory))
{
createMe = true;
UserSettings.Default.TextureDirectory = Path.Combine(UserSettings.Default.OutputDirectory, "Exports");
}
if (!Directory.Exists(UserSettings.Default.AudioDirectory))
{
createMe = true;
UserSettings.Default.AudioDirectory = Path.Combine(UserSettings.Default.OutputDirectory, "Exports");
}
if (!Directory.Exists(UserSettings.Default.ModelDirectory))
{
createMe = true;
UserSettings.Default.ModelDirectory = Path.Combine(UserSettings.Default.OutputDirectory, "Exports");
}
Directory.CreateDirectory(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "FModel"));
Directory.CreateDirectory(Path.Combine(UserSettings.Default.OutputDirectory, "Backups"));
if (createMe) Directory.CreateDirectory(Path.Combine(UserSettings.Default.OutputDirectory, "Exports"));
Directory.CreateDirectory(Path.Combine(UserSettings.Default.OutputDirectory, "Logs"));
Directory.CreateDirectory(Path.Combine(UserSettings.Default.OutputDirectory, ".data"));
#if DEBUG
Log.Logger = new LoggerConfiguration().WriteTo.Console(theme: AnsiConsoleTheme.Literate).CreateLogger();
#else
Log.Logger = new LoggerConfiguration().WriteTo.Console(theme: AnsiConsoleTheme.Literate).WriteTo.File(
Path.Combine(UserSettings.Default.OutputDirectory, "Logs", $"FModel-Log-{DateTime.Now:yyyy-MM-dd}.txt"),
outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss} [FModel] [{Level:u3}] {Message:lj}{NewLine}{Exception}").CreateLogger();
#endif
Log.Information("Version {Version}", Constants.APP_VERSION);
Log.Information("{OS}", GetOperatingSystemProductName());
Log.Information("{RuntimeVer}", RuntimeInformation.FrameworkDescription);
Log.Information("Culture {SysLang}", CultureInfo.CurrentCulture);
}
private void AppExit(object sender, ExitEventArgs e)
{
Log.Information("––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––");
Log.CloseAndFlush();
UserSettings.Save();
Environment.Exit(0);
}
private void OnUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
Log.Error("{Exception}", e.Exception);
var messageBox = new MessageBoxModel
{
Text = $"An unhandled exception occurred: {e.Exception.Message}",
Caption = "Fatal Error",
Icon = MessageBoxImage.Error,
Buttons = new[]
{
MessageBoxButtons.Custom("Reset Settings", EErrorKind.ResetSettings),
MessageBoxButtons.Custom("Restart", EErrorKind.Restart),
MessageBoxButtons.Custom("OK", EErrorKind.Ignore)
},
IsSoundEnabled = false
};
MessageBox.Show(messageBox);
if (messageBox.Result == MessageBoxResult.Custom && (EErrorKind) messageBox.ButtonPressed.Id != EErrorKind.Ignore)
{
if ((EErrorKind) messageBox.ButtonPressed.Id == EErrorKind.ResetSettings)
UserSettings.Default = new UserSettings();
ApplicationService.ApplicationView.Restart();
}
e.Handled = true;
}
private void MigrateV1Games()
{
foreach ((var gameDir, var setting) in UserSettings.Default.ManualGames)
{
if (!Directory.Exists(gameDir)) continue;
UserSettings.Default.PerDirectory[gameDir] =
DirectorySettings.Default(setting.GameName, setting.GameDirectory, true, setting.OverridedGame, setting.AesKeys?.MainKey);
}
UserSettings.Default.ManualGames.Clear();
}
private string GetOperatingSystemProductName()
{
var productName = string.Empty;
try
{
productName = BrandingFormatString("%WINDOWS_LONG%");
}
catch
{
// ignored
}
if (string.IsNullOrEmpty(productName))
productName = Environment.OSVersion.VersionString;
return $"{productName} ({(Environment.Is64BitOperatingSystem ? "64" : "32")}-bit)";
}
public static string GetRegistryValue(string path, string name = null, RegistryHive root = RegistryHive.CurrentUser)
{
using var rk = RegistryKey.OpenBaseKey(root, RegistryView.Default).OpenSubKey(path);
if (rk != null)
return rk.GetValue(name, null) as string;
return string.Empty;
}
}