Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions AssetEditor.sln
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Editors.AnimationMeta", "Ed
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.AnimationMeta", "Editors\AnimationMeta\Test.AnimationMeta\Test.AnimationMeta.csproj", "{E759BE6D-E0A4-46B8-A02A-E8573F579E2F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssetEditorUpdater", "AssetEditorUpdater\AssetEditorUpdater.csproj", "{24483A6F-DBD6-4415-B4D8-1A2FB86A2A12}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -228,6 +230,10 @@ Global
{E759BE6D-E0A4-46B8-A02A-E8573F579E2F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E759BE6D-E0A4-46B8-A02A-E8573F579E2F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E759BE6D-E0A4-46B8-A02A-E8573F579E2F}.Release|Any CPU.Build.0 = Release|Any CPU
{24483A6F-DBD6-4415-B4D8-1A2FB86A2A12}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{24483A6F-DBD6-4415-B4D8-1A2FB86A2A12}.Debug|Any CPU.Build.0 = Debug|Any CPU
{24483A6F-DBD6-4415-B4D8-1A2FB86A2A12}.Release|Any CPU.ActiveCfg = Release|Any CPU
{24483A6F-DBD6-4415-B4D8-1A2FB86A2A12}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
66 changes: 41 additions & 25 deletions AssetEditor/App.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;
using AssetEditor.Services;
using AssetEditor.UiCommands;
using AssetEditor.ViewModels;
using AssetEditor.Views;
using AssetEditor.Views.Settings;
using Microsoft.Extensions.DependencyInjection;
using Shared.Core.DependencyInjection;
using Shared.Core.DevConfig;
using Shared.Core.ErrorHandling;
using Shared.Core.Events;
using Shared.Core.PackFiles;
using Shared.Core.PackFiles.Utility;
using Shared.Core.Services;
Expand All @@ -29,7 +31,6 @@ protected override void OnStartup(StartupEventArgs e)
PackFileLog.IsLoggingEnabled = false;

ShutdownMode = ShutdownMode.OnExplicitShutdown;
VersionChecker.CheckVersion();
Current.DispatcherUnhandledException += new DispatcherUnhandledExceptionEventHandler(DispatcherUnhandledExceptionHandler);

var forceValidateServiceScopes = Debugger.IsAttached;
Expand All @@ -38,6 +39,8 @@ protected override void OnStartup(StartupEventArgs e)
_ = _serviceProvider.GetRequiredService<RecentFilesTracker>(); // Force instance of the RecentFilesTracker
_ = _serviceProvider.GetRequiredService<IScopeRepository>(); // Force instance of the IScopeRepository

var uiCommandFactory = _serviceProvider.GetRequiredService<IUiCommandFactory>();

var settingsService = _serviceProvider.GetRequiredService<ApplicationSettingsService>();
settingsService.AllowSettingsUpdate = true;
settingsService.Load();
Expand All @@ -48,40 +51,46 @@ protected override void OnStartup(StartupEventArgs e)

// Show the settings window if its the first time the tool is ran
if (settingsService.CurrentSettings.IsFirstTimeStartingApplication)
{
var settingsWindow = _serviceProvider.GetRequiredService<SettingsWindow>();
settingsWindow.DataContext = _serviceProvider.GetRequiredService<SettingsViewModel>();
settingsWindow.ShowDialog();

settingsService.CurrentSettings.IsFirstTimeStartingApplication = false;
settingsService.Save();
}
HandleFirstTimeSettings(uiCommandFactory, settingsService);

var devConfigManager = _serviceProvider.GetRequiredService<DevelopmentConfigurationManager>();
devConfigManager.Initialize(e);
devConfigManager.OverrideSettings();

// Load all packfiles
if (settingsService.CurrentSettings.LoadCaPacksByDefault)
{
var gamePath = settingsService.GetGamePathForCurrentGame();
if (gamePath != null)
{
var packfileService = _serviceProvider.GetRequiredService<IPackFileService>();
var containerLoader = _serviceProvider.GetRequiredService<IPackFileContainerLoader>();
var loadRes = containerLoader.LoadAllCaFiles(settingsService.CurrentSettings.CurrentGame);

if (loadRes == null)
MessageBox.Show($"Unable to load all CA packfiles in {gamePath}");
else
packfileService.AddContainer(loadRes);
}
}
LoadCAPackFiles(settingsService);

devConfigManager.CreateTestPackFiles();
devConfigManager.OpenFileOnLoad();

ShowMainWindow();

_ = CheckVersion(uiCommandFactory);
}

private static void HandleFirstTimeSettings(IUiCommandFactory uiCommandFactory, ApplicationSettingsService settingsService)
{
uiCommandFactory.Create<OpenSettingsDialogCommand>().Execute();

settingsService.CurrentSettings.IsFirstTimeStartingApplication = false;
settingsService.Save();
}

private void LoadCAPackFiles(ApplicationSettingsService settingsService)
{
var gamePath = settingsService.GetGamePathForCurrentGame();
if (gamePath != null)
{
var packfileService = _serviceProvider.GetRequiredService<IPackFileService>();
var containerLoader = _serviceProvider.GetRequiredService<IPackFileContainerLoader>();
var loadRes = containerLoader.LoadAllCaFiles(settingsService.CurrentSettings.CurrentGame);

if (loadRes == null)
MessageBox.Show($"Unable to load all CA packfiles in {gamePath}");
else
packfileService.AddContainer(loadRes);
}
}

void ShowMainWindow()
Expand All @@ -94,7 +103,7 @@ void ShowMainWindow()
mainWindow.Closed += OnMainWindowClosed;
mainWindow.Show();

// Ensure the window doesn't cover up the windows bar.
// Ensure the window doesn't cover up the windows bar
mainWindow.MaxHeight = SystemParameters.MaximizedPrimaryScreenHeight;
mainWindow.MaxWidth = SystemParameters.MaximizedPrimaryScreenWidth;

Expand All @@ -109,6 +118,13 @@ private void OnMainWindowClosed(object sender, EventArgs e)
Shutdown();
}

private static async Task CheckVersion(IUiCommandFactory uiCommandFactory)
{
var newerReleases = await VersionChecker.GetNewerReleases();
if (newerReleases != null)
uiCommandFactory.Create<OpenUpdaterWindowCommand>().Execute(newerReleases);
}

void DispatcherUnhandledExceptionHandler(object sender, DispatcherUnhandledExceptionEventArgs args)
{
Logging.Create<App>().Here().Fatal(args.Exception.ToString());
Expand Down
14 changes: 14 additions & 0 deletions AssetEditor/AssetEditor.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,18 @@
<PackageProjectUrl>https://github.com/donkeyProgramming/TheAssetEditor</PackageProjectUrl>
<RepositoryUrl>https://github.com/donkeyProgramming/TheAssetEditor</RepositoryUrl>
<PackageId>AssetEditor</PackageId>
<Version>0.68.0</Version>
<AnalysisLevel>6.0</AnalysisLevel>
</PropertyGroup>

<ItemGroup>
<None Include="..\.editorconfig" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="MdXaml" Version="1.27.0" />
</ItemGroup>

<ItemGroup>
<Resource Include="AssetEditorIcon.png" />
</ItemGroup>
Expand All @@ -77,4 +82,13 @@
<GenerateDocumentationFile>False</GenerateDocumentationFile>
<NoWarn>$(NoWarn),1573,1591,1712</NoWarn>
</PropertyGroup>

<Target Name="PublishUpdater" AfterTargets="ComputeFilesToPublish">
<PropertyGroup>
<UpdaterProject>$(MSBuildProjectDirectory)\..\AssetEditorUpdater\AssetEditorUpdater.csproj</UpdaterProject>
<AbsolutePublishDir>$([System.IO.Path]::GetFullPath('$(PublishDir)'))</AbsolutePublishDir>
</PropertyGroup>

<MSBuild Projects="$(UpdaterProject)" Targets="Restore;Publish" Properties="PublishDir=$(AbsolutePublishDir);Configuration=$(Configuration);RuntimeIdentifier=$(RuntimeIdentifier);SelfContained=$(SelfContained);PublishSingleFile=$(PublishSingleFile);PublishReadyToRun=$(PublishReadyToRun)" />
</Target>
</Project>
4 changes: 4 additions & 0 deletions AssetEditor/DependencyInjectionContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using AssetEditor.ViewModels;
using AssetEditor.Views;
using AssetEditor.Views.Settings;
using AssetEditor.Views.Updater;
using Microsoft.Extensions.DependencyInjection;
using Shared.Core.DependencyInjection;
using Shared.Core.DevConfig;
Expand All @@ -24,13 +25,16 @@ public override void Register(IServiceCollection serviceCollection)
serviceCollection.AddTransient<OpenGamePackCommand>();
serviceCollection.AddTransient<OpenPackFileCommand>();
serviceCollection.AddTransient<OpenSettingsDialogCommand>();
serviceCollection.AddTransient<OpenUpdaterWindowCommand>();
serviceCollection.AddTransient<OpenWebpageCommand>();
serviceCollection.AddTransient<PrintScopesCommand>();
serviceCollection.AddTransient<OpenEditorCommand>();
serviceCollection.AddTransient<TogglePackFileExplorerCommand>();

serviceCollection.AddTransient<SettingsWindow>();
serviceCollection.AddTransient<SettingsViewModel>();
serviceCollection.AddTransient<UpdaterWindow>();
serviceCollection.AddTransient<UpdaterViewModel>();
serviceCollection.AddScoped<MenuBarViewModel>();

serviceCollection.AddScoped<MainWindow>();
Expand Down
26 changes: 26 additions & 0 deletions AssetEditor/UiCommands/OpenUpdaterWindowCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using AssetEditor.ViewModels;
using AssetEditor.Views.Updater;
using Microsoft.Extensions.DependencyInjection;
using Octokit;
using Shared.Core.Events;

namespace AssetEditor.UiCommands
{
public class OpenUpdaterWindowCommand(IServiceProvider serviceProvider) : IUiCommand
{
private readonly IServiceProvider _serviceProvider = serviceProvider;

public void Execute(List<Release> newerReleases)
{
var window = _serviceProvider.GetRequiredService<UpdaterWindow>();
var viewModel = _serviceProvider.GetRequiredService<UpdaterViewModel>();
viewModel.SetReleaseInfo(newerReleases);
viewModel.SetCloseAction(window.Close);
window.DataContext = viewModel;
window.ShowDialog();
}
}
}

2 changes: 1 addition & 1 deletion AssetEditor/ViewModels/MainViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public MainViewModel(

ToolsFactory = toolFactory;

ApplicationTitle = $"AssetEditor v{VersionChecker.CurrentVersion}";
ApplicationTitle = $"AssetEditor v{VersionChecker.GetCurrentVersion()}";
CurrentGame = $"Current Game: {GameInformationDatabase.GetGameById(applicationSettingsService.CurrentSettings.CurrentGame).DisplayName}";
}

Expand Down
125 changes: 125 additions & 0 deletions AssetEditor/ViewModels/UpdaterViewModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Text;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Octokit;
using Serilog;
using Shared.Core.ErrorHandling;
using Shared.Core.Misc;
using Shared.Core.Services;
using Application = System.Windows.Application;

namespace AssetEditor.ViewModels
{
public class ReleaseNoteItem(Release release)
{
public string ReleaseName { get; } = release.Name;
public string PublishedAt { get; } = $"Published {release.PublishedAt.Value:dd MMM yyyy}";
public string ReleaseNotes { get; } = release.Body;
}

partial class UpdaterViewModel : ObservableObject
{
private readonly ILogger _logger = Logging.Create<UpdaterViewModel>();
private Action _closeAction;

private const string AssetEditorUpdaterExe = "AssetEditorUpdater.exe";

private List<Release> _newerReleases = [];

[ObservableProperty] private ObservableCollection<ReleaseNoteItem> _releaseNotesItems = [];

[ObservableProperty] private string _latestVersionInfo;

public void SetReleaseInfo(List<Release> newerReleases)
{
_newerReleases = newerReleases;

var currentVersion = VersionChecker.GetCurrentVersion();
var latestRelease = _newerReleases[0];
var latestVersion = VersionChecker.ParseReleaseVersion(latestRelease.TagName);

var stringBuilder = new StringBuilder();
stringBuilder.AppendLine($"A new version of AssetEditor is available! The AssetEditor donkeys have been busy...");
stringBuilder.AppendLine();
stringBuilder.AppendLine($"Your current version is {currentVersion}. The latest verison is {latestVersion}.");
stringBuilder.AppendLine();
stringBuilder.AppendLine("Update to get the changes detailed in the release notes below.");
LatestVersionInfo = stringBuilder.ToString();

ReleaseNotesItems.Clear();
foreach (var release in _newerReleases)
ReleaseNotesItems.Add(new ReleaseNoteItem(release));
}

[RelayCommand] public void Update()
{
if (Debugger.IsAttached)
return;

var currentVersion = VersionChecker.GetCurrentVersion();
var latestRelease = _newerReleases[0];
var latestVersion = VersionChecker.ParseReleaseVersion(latestRelease.TagName);
_logger.Information($"Updating AssetEditor from version {currentVersion} to version {latestVersion}");

DeleteUpdateDirectory();

LaunchUpdater();

Application.Current.Shutdown();
}

public static void DeleteUpdateDirectory()
{
var updateDirectory = DirectoryHelper.UpdateDirectory;
if (Directory.Exists(updateDirectory))
Directory.Delete(updateDirectory, true);
}

public static void LaunchUpdater()
{
var currentDirectory = AppContext.BaseDirectory;
var updaterPath = Path.Combine(currentDirectory, AssetEditorUpdaterExe);

var processStartInfo = new ProcessStartInfo
{
FileName = updaterPath,
WorkingDirectory = currentDirectory,
UseShellExecute = true,
};

if (UpdaterRequiresAdministratorPrivileges())
processStartInfo.Verb = "runas";

Process.Start(processStartInfo);
}

public static bool UpdaterRequiresAdministratorPrivileges()
{
try
{
var currentDirectory = AppContext.BaseDirectory;
var testFilePath = Path.Combine(currentDirectory, $"updater_admin_privileges_test{Guid.NewGuid():N}.tmp");

using (File.Create(testFilePath, 1, FileOptions.DeleteOnClose))
{
}

return false;
}
catch (UnauthorizedAccessException)
{
return true;
}
}

[RelayCommand] public void CloseWindowAction() => _closeAction?.Invoke();


public void SetCloseAction(Action closeAction) => _closeAction = closeAction;
}
}
Loading
Loading