diff --git a/Directory.props b/Directory.props
new file mode 100644
index 0000000..028fe5a
--- /dev/null
+++ b/Directory.props
@@ -0,0 +1,6 @@
+
+
+
+ 2.1.8
+
+
diff --git a/TrackOMatic.Logic.Test/TrackOMatic.Logic.Test.csproj b/TrackOMatic.Logic.Test/TrackOMatic.Logic.Test.csproj
index 7ab6493..f29c7f4 100644
--- a/TrackOMatic.Logic.Test/TrackOMatic.Logic.Test.csproj
+++ b/TrackOMatic.Logic.Test/TrackOMatic.Logic.Test.csproj
@@ -1,4 +1,6 @@
-
+
+
+
net10.0
@@ -22,4 +24,4 @@
-
\ No newline at end of file
+
diff --git a/TrackOMatic.Logic/TrackOMatic.Logic.csproj b/TrackOMatic.Logic/TrackOMatic.Logic.csproj
index b760144..4a41351 100644
--- a/TrackOMatic.Logic/TrackOMatic.Logic.csproj
+++ b/TrackOMatic.Logic/TrackOMatic.Logic.csproj
@@ -1,4 +1,6 @@
-
+
+
+
net10.0
diff --git a/TrackOMatic.Services.Test/TrackOMatic.Services.Test.csproj b/TrackOMatic.Services.Test/TrackOMatic.Services.Test.csproj
index c809ff5..80f6f7a 100644
--- a/TrackOMatic.Services.Test/TrackOMatic.Services.Test.csproj
+++ b/TrackOMatic.Services.Test/TrackOMatic.Services.Test.csproj
@@ -1,4 +1,6 @@
-
+
+
+
net10.0
@@ -22,4 +24,4 @@
-
\ No newline at end of file
+
diff --git a/TrackOMatic.Services.Test/VersionServiceTests.cs b/TrackOMatic.Services.Test/VersionServiceTests.cs
new file mode 100644
index 0000000..d03531b
--- /dev/null
+++ b/TrackOMatic.Services.Test/VersionServiceTests.cs
@@ -0,0 +1,120 @@
+namespace TrackOMatic.Services.Test;
+
+public class VersionServiceTests
+{
+ private readonly VersionService _sut = new();
+
+ [Fact]
+ public void GetApplicationVersion_ReturnsValidVersion()
+ {
+ // Arrange & Act
+ var version = _sut.GetApplicationVersion();
+
+ Assert.Multiple(() =>
+ {
+ // Assert
+ Assert.NotNull(version);
+ Assert.True(version.Major >= 0, "Major version should be non-negative");
+ });
+ }
+
+ [Fact]
+ public void GetApplicationVersion_ComponentsAreNonNegative()
+ {
+ // Arrange & Act
+ var version = _sut.GetApplicationVersion();
+
+ Assert.Multiple(() =>
+ {
+ // Assert
+ Assert.True(version.Major >= 0, "Major version should be non-negative");
+ Assert.True(version.Minor >= 0, "Minor version should be non-negative");
+ Assert.True(version.Build >= 0, "Build version should be non-negative");
+ Assert.True(version.Revision >= 0, "Revision should be non-negative");
+ });
+ }
+
+ [Fact]
+ public void GetVersionString_ReturnsFormattedString()
+ {
+ // Arrange & Act
+ var versionString = _sut.GetVersionString();
+
+ // Assert
+ Assert.Multiple(() =>
+ {
+ Assert.NotNull(versionString);
+ Assert.NotEmpty(versionString);
+ Assert.Matches(@"^\d+\.\d+\.\d+$", versionString); // Matches Major.Minor.Build format
+ });
+ }
+
+ [Fact]
+ public void GetVersionString_FormatsAsExpected()
+ {
+ // Arrange & Act
+ var version = _sut.GetApplicationVersion();
+ var versionString = _sut.GetVersionString();
+ var expectedFormat = $"{version.Major}.{version.Minor}.{version.Build}";
+
+ // Assert
+ Assert.Equal(expectedFormat, versionString);
+ }
+
+ [Fact]
+ public void GetVersionString_DoesNotIncludeRevision()
+ {
+ // Arrange & Act
+ var version = _sut.GetApplicationVersion();
+ var versionString = _sut.GetVersionString();
+
+ // Assert
+ // Should have exactly 2 dots for Major.Minor.Build format
+ var dotCount = versionString.Count(c => c == '.');
+ Assert.Equal(2, dotCount);
+ }
+
+ [Fact]
+ public void GetApplicationVersion_ConsistentBetweenCalls()
+ {
+ // Arrange & Act
+ var version1 = _sut.GetApplicationVersion();
+ var version2 = _sut.GetApplicationVersion();
+
+ // Assert
+ Assert.Equal(version1, version2);
+ }
+
+ [Fact]
+ public void GetVersionString_ConsistentBetweenCalls()
+ {
+ // Arrange & Act
+ var versionString1 = _sut.GetVersionString();
+ var versionString2 = _sut.GetVersionString();
+
+ // Assert
+ Assert.Equal(versionString1, versionString2);
+ }
+
+ [Fact]
+ public void GetVersionString_VersionStringAndApplicationVersionAreConsistent()
+ {
+ // Arrange & Act
+ var appVersion = _sut.GetApplicationVersion();
+ var versionString = _sut.GetVersionString();
+
+ // Parse the version string to verify it matches the application version
+ var parts = versionString.Split('.');
+ var parsedMajor = int.Parse(parts[0]);
+ var parsedMinor = int.Parse(parts[1]);
+ var parsedBuild = int.Parse(parts[2]);
+
+ // Assert
+ Assert.Multiple(() =>
+ {
+ Assert.Equal(appVersion.Major, parsedMajor);
+ Assert.Equal(appVersion.Minor, parsedMinor);
+ Assert.Equal(appVersion.Build, parsedBuild);
+ });
+ }
+}
diff --git a/TrackOMatic.Services/IVersionService.cs b/TrackOMatic.Services/IVersionService.cs
new file mode 100644
index 0000000..9d9f3f5
--- /dev/null
+++ b/TrackOMatic.Services/IVersionService.cs
@@ -0,0 +1,8 @@
+namespace TrackOMatic.Services;
+
+public interface IVersionService
+{
+ public Version GetApplicationVersion();
+
+ public string GetVersionString();
+}
diff --git a/TrackOMatic.Services/ServiceLocator.cs b/TrackOMatic.Services/ServiceLocator.cs
new file mode 100644
index 0000000..67a8111
--- /dev/null
+++ b/TrackOMatic.Services/ServiceLocator.cs
@@ -0,0 +1,20 @@
+using Microsoft.Extensions.DependencyInjection;
+
+namespace TrackOMatic.Services;
+
+public static class ServiceLocator
+{
+ private static IServiceProvider? _provider;
+
+ public static void Initialize(IServiceProvider provider) => _provider = provider;
+
+ public static T GetService() where T : notnull
+ {
+ if (_provider == null)
+ {
+ throw new InvalidOperationException("ServiceLocator not initialized");
+ }
+
+ return _provider.GetRequiredService();
+ }
+}
diff --git a/TrackOMatic.Services/TrackOMatic.Services.csproj b/TrackOMatic.Services/TrackOMatic.Services.csproj
index 26e2721..9f3b625 100644
--- a/TrackOMatic.Services/TrackOMatic.Services.csproj
+++ b/TrackOMatic.Services/TrackOMatic.Services.csproj
@@ -1,4 +1,6 @@
-
+
+
+
net10.0
diff --git a/TrackOMatic.Services/VersionService.cs b/TrackOMatic.Services/VersionService.cs
new file mode 100644
index 0000000..463ad24
--- /dev/null
+++ b/TrackOMatic.Services/VersionService.cs
@@ -0,0 +1,18 @@
+using System.Reflection;
+
+namespace TrackOMatic.Services;
+
+public class VersionService : IVersionService
+{
+ public Version GetApplicationVersion()
+ {
+ var version = Assembly.GetExecutingAssembly().GetName().Version;
+ return version ?? new(0, 0, 0, 0);
+ }
+
+ public string GetVersionString()
+ {
+ var version = GetApplicationVersion();
+ return $"{version.Major}.{version.Minor}.{version.Build}";
+ }
+}
diff --git a/TrackOMatic.ViewModels.Test/TrackOMatic.ViewModels.Test.csproj b/TrackOMatic.ViewModels.Test/TrackOMatic.ViewModels.Test.csproj
index 4809df1..ac1488e 100644
--- a/TrackOMatic.ViewModels.Test/TrackOMatic.ViewModels.Test.csproj
+++ b/TrackOMatic.ViewModels.Test/TrackOMatic.ViewModels.Test.csproj
@@ -1,4 +1,6 @@
-
+
+
+
net10.0
@@ -22,4 +24,4 @@
-
\ No newline at end of file
+
diff --git a/TrackOMatic.ViewModels/TrackOMatic.ViewModels.csproj b/TrackOMatic.ViewModels/TrackOMatic.ViewModels.csproj
index da7efb2..1d92261 100644
--- a/TrackOMatic.ViewModels/TrackOMatic.ViewModels.csproj
+++ b/TrackOMatic.ViewModels/TrackOMatic.ViewModels.csproj
@@ -1,4 +1,6 @@
-
+
+
+
net10.0
diff --git a/TrackOMatic/App.xaml b/TrackOMatic/App.xaml
index b33a544..d87fa3b 100644
--- a/TrackOMatic/App.xaml
+++ b/TrackOMatic/App.xaml
@@ -1,9 +1,8 @@
-
diff --git a/TrackOMatic/App.xaml.cs b/TrackOMatic/App.xaml.cs
index ea2c6a9..3cb15a3 100644
--- a/TrackOMatic/App.xaml.cs
+++ b/TrackOMatic/App.xaml.cs
@@ -1,52 +1,60 @@
-using System;
-using System.Collections.Generic;
-using System.Configuration;
-using System.Data;
-using System.Linq;
-using System.Threading.Tasks;
using System.Windows;
+
+using Microsoft.Extensions.DependencyInjection;
+
using TrackOMatic.Properties;
+using TrackOMatic.Services;
+
+namespace TrackOMatic;
-namespace TrackOMatic
+///
+/// Interaction logic for App.xaml
+///
+public partial class App : Application
{
- ///
- /// Interaction logic for App.xaml
- ///
- public partial class App : Application
+ private readonly IServiceProvider _serviceProvider;
+
+ App()
{
+ var services = new ServiceCollection();
+ services.AddSingleton();
- App()
- {
- Dispatcher.UnhandledException += OnDispatcherUnhandledException;
- }
+ _serviceProvider = services.BuildServiceProvider();
+ ServiceLocator.Initialize(_serviceProvider);
+ Dispatcher.UnhandledException += OnDispatcherUnhandledException;
+ }
- private void App_Exit(object sender, ExitEventArgs e)
- {
- }
+ private void App_Exit(object sender, ExitEventArgs e)
+ {
+ }
- void OnDispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
- {
- }
+ void OnDispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
+ {
+ }
- protected override void OnStartup(StartupEventArgs e)
- {
- base.OnStartup(e);
- UpdatePadBarrelImages();
- }
+ protected override void OnStartup(StartupEventArgs e)
+ {
+ base.OnStartup(e);
+
+ var versionService = _serviceProvider.GetRequiredService();
+ MainWindow mainWindow = new(versionService);
+ mainWindow.Show();
- public void UpdatePadBarrelImages()
+ UpdatePadBarrelImages();
+ }
+
+ public void UpdatePadBarrelImages()
+ {
+ var dicts = Resources.MergedDictionaries;
+ dicts.Clear();
+ dicts.Add(new ResourceDictionary
+ {
+ Source = new Uri("Dictionary1.xaml", UriKind.Relative)
+ });
+ var path = Settings.Default.ColoredBarrelPadMoves ? "ColoredBarrelPadImages.xaml" : "BaseBarrelPadImages.xaml";
+ dicts.Add(new ResourceDictionary
{
- var dicts = Resources.MergedDictionaries;
- dicts.Clear();
- dicts.Add(new ResourceDictionary
- {
- Source = new Uri("Dictionary1.xaml", UriKind.Relative)
- });
- var path = Settings.Default.ColoredBarrelPadMoves ? "ColoredBarrelPadImages.xaml" : "BaseBarrelPadImages.xaml";
- dicts.Add(new ResourceDictionary
- {
- Source = new Uri(path, UriKind.Relative)
- });
- }
+ Source = new Uri(path, UriKind.Relative)
+ });
}
}
diff --git a/TrackOMatic/AutoUpdateInfo.xml b/TrackOMatic/AutoUpdateInfo.xml
index 309db53..714a3dc 100644
--- a/TrackOMatic/AutoUpdateInfo.xml
+++ b/TrackOMatic/AutoUpdateInfo.xml
@@ -5,3 +5,4 @@
https://github.com/Brian0255/Track-O-Matic/releases
false
+
diff --git a/TrackOMatic/MainWindow.xaml b/TrackOMatic/MainWindow.xaml
index de9294d..014a3ed 100644
--- a/TrackOMatic/MainWindow.xaml
+++ b/TrackOMatic/MainWindow.xaml
@@ -76,7 +76,10 @@
-
+
diff --git a/TrackOMatic/MainWindow.xaml.cs b/TrackOMatic/MainWindow.xaml.cs
index 243519d..d987847 100644
--- a/TrackOMatic/MainWindow.xaml.cs
+++ b/TrackOMatic/MainWindow.xaml.cs
@@ -11,6 +11,7 @@
using Microsoft.Win32;
using TrackOMatic.Properties;
+using TrackOMatic.Services;
using Timer = System.Timers.Timer;
@@ -19,7 +20,7 @@ namespace TrackOMatic
///
/// Interaction logic for MainWindow.xaml
///
- public partial class MainWindow : Window
+ public partial class MainWindow : Window, INotifyPropertyChanged
{
public int TotalGBs { get; private set; }
public BroadcastView? BroadcastView { get; private set; }
@@ -48,10 +49,36 @@ public partial class MainWindow : Window
public Dictionary ITEM_TO_DIRECT_HINT { get; } = new();
public Dictionary ITEM_NAME_TO_ITEM { get; } = new();
+ public IVersionService VersionService { get; init; }
+
+ private string _applicationVersion = "";
+ public string ApplicationVersion
+ {
+ get => _applicationVersion;
+ private set
+ {
+ if (_applicationVersion != value)
+ {
+ _applicationVersion = value;
+ OnPropertyChanged(nameof(ApplicationVersion));
+ }
+ }
+ }
+
+ public event PropertyChangedEventHandler? PropertyChanged;
+
+ private void OnPropertyChanged(string propertyName)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+ }
+
// Timer to save the data every minute. This is properly initialized, but the compiler is finicky.
private Timer SaveTimer = null!;
- public MainWindow()
+ public MainWindow(IVersionService versionService)
{
+ VersionService = versionService;
+ ApplicationVersion = VersionService.GetVersionString();
+ DataContext = this;
InitializeComponent();
HintData.Init();
InitOptions();
@@ -699,7 +726,7 @@ private void MainWindow_Loaded(object sender, RoutedEventArgs e)
AutoUpdater.UpdateFormSize = new System.Drawing.Size(1300, 600);
AutoUpdater.Icon = Properties.Resources.app.ToBitmap();
- AutoUpdater.InstalledVersion = new Version("2.1.8");
+ AutoUpdater.InstalledVersion = VersionService.GetApplicationVersion();
AutoUpdater.Start("https://raw.githubusercontent.com/Brian0255/Track-O-Matic/master/TrackOMatic/AutoUpdateInfo.xml");
if (Settings.Default.DesiredHeight == 0 || Settings.Default.DesiredWidth == 0)
diff --git a/TrackOMatic/Scripts/UpdateAutoUpdateInfo.ps1 b/TrackOMatic/Scripts/UpdateAutoUpdateInfo.ps1
new file mode 100644
index 0000000..4d197ee
--- /dev/null
+++ b/TrackOMatic/Scripts/UpdateAutoUpdateInfo.ps1
@@ -0,0 +1,15 @@
+param(
+ [string]$Version = "2.1.8",
+ [string]$OutputPath = "AutoUpdateInfo.xml"
+)
+
+$xml = [xml](Get-Content $OutputPath)
+$xml.item.version = $Version
+$xml.item.url = "https://github.com/Brian0255/Track-O-Matic/releases/download/$Version/TrackOMatic_$Version.zip"
+$xml.Save($OutputPath)
+
+# Ensure file ends with a blank line
+Add-Content -Path $OutputPath -Value "" -NoNewline
+Add-Content -Path $OutputPath -Value ""
+
+Write-Host "Updated AutoUpdateInfo.xml to version $Version"
diff --git a/TrackOMatic/Scripts/UpdateAutoUpdateInfo.sh b/TrackOMatic/Scripts/UpdateAutoUpdateInfo.sh
new file mode 100755
index 0000000..9399572
--- /dev/null
+++ b/TrackOMatic/Scripts/UpdateAutoUpdateInfo.sh
@@ -0,0 +1,33 @@
+#!/bin/bash
+
+# Cross-platform script to update AutoUpdateInfo.xml with version information
+
+VERSION="${1:-2.1.8}"
+OUTPUT_PATH="${2:-AutoUpdateInfo.xml}"
+
+# Check if the output file exists
+if [ ! -f "$OUTPUT_PATH" ]; then
+ echo "Error: $OUTPUT_PATH not found"
+ exit 1
+fi
+
+# Use a temporary file to avoid issues with in-place editing
+TEMP_FILE="${OUTPUT_PATH}.tmp"
+
+# Update the version in the XML file
+# This approach handles the XML parsing in a cross-platform way
+sed "s|.*|$VERSION|g" "$OUTPUT_PATH" > "$TEMP_FILE"
+
+# Update the URL to include the version
+sed -i.bak "s|.*|https://github.com/Brian0255/Track-O-Matic/releases/download/$VERSION/TrackOMatic_$VERSION.zip|g" "$TEMP_FILE"
+
+# Remove the backup file created by sed -i
+rm -f "${TEMP_FILE}.bak"
+
+# Move the temp file to replace the original
+mv "$TEMP_FILE" "$OUTPUT_PATH"
+
+# Ensure file ends with a newline
+echo "" >> "$OUTPUT_PATH"
+
+echo "Updated AutoUpdateInfo.xml to version $VERSION"
diff --git a/TrackOMatic/Track-O-Matic.csproj b/TrackOMatic/Track-O-Matic.csproj
index 5773e86..e158c27 100644
--- a/TrackOMatic/Track-O-Matic.csproj
+++ b/TrackOMatic/Track-O-Matic.csproj
@@ -1,5 +1,7 @@
+
+
net10.0-windows
@@ -87,4 +89,12 @@
+
+
+
+
+
+
+
+