diff --git a/AutoTrackR2/HomePage.xaml b/AutoTrackR2/HomePage.xaml index d1e2557..9c08122 100644 --- a/AutoTrackR2/HomePage.xaml +++ b/AutoTrackR2/HomePage.xaml @@ -1,48 +1,176 @@ <UserControl x:Class="AutoTrackR2.HomePage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" - Height="396" Width="626"> - <Grid Background="{DynamicResource BackgroundLightBrush}"> - <!-- Main Layout Grid --> - <Grid Margin="0,0,5,7"> - <Grid.RowDefinitions> - <!-- One row for the content, the other for buttons --> - <RowDefinition Height="*" /> - <RowDefinition Height="Auto" /> - </Grid.RowDefinitions> + Height="396" + Width="626"> + <Grid Background="{DynamicResource BackgroundLightBrush}"> + <!-- Main Layout Grid --> + <Grid Margin="0,0,5,7"> + <Grid.RowDefinitions> + <!-- One row for the content, the other for buttons --> + <RowDefinition Height="*"/> + <RowDefinition Height="Auto"/> + </Grid.RowDefinitions> - <Grid.ColumnDefinitions> - <!-- Left column for the main content area --> - <ColumnDefinition /> - <!-- Right column for the buttons --> - <ColumnDefinition Width="Auto" MinWidth="173" /> - </Grid.ColumnDefinitions> + <Grid.ColumnDefinitions> + <!-- Left column for the main content area --> + <ColumnDefinition/> + <!-- Right column for the buttons --> + <ColumnDefinition Width="Auto" + MinWidth="173"/> + </Grid.ColumnDefinitions> - <!-- Border for the kill feed section --> - <!--TextBox Name="OutputTextBox" Grid.Row="0" Grid.Column="0" Grid.RowSpan="2" Height="NaN" Margin="0,0,20,0" TextWrapping="Wrap" VerticalScrollBarVisibility="Auto" IsReadOnly="True" Style="{StaticResource RoundedTextBox}"/--> - <Border Grid.Row="0" Grid.Column="0" Grid.RowSpan="2" BorderBrush="{DynamicResource AccentBrush}" BorderThickness="2" CornerRadius="5" Padding="10,0,0,0" Background="{DynamicResource BackgroundDarkBrush}" Margin="0,0,20,0"> - <ScrollViewer VerticalScrollBarVisibility="Auto" Width="419" Margin="0,0,-5,0"> - <StackPanel Name="KillFeedStackPanel" Orientation="Vertical" Margin="0,0,0,0" Width="402" HorizontalAlignment="Left"/> - </ScrollViewer> - </Border> + <!-- Border for the kill feed section --> + <!--TextBox Name="OutputTextBox" Grid.Row="0" Grid.Column="0" Grid.RowSpan="2" Height="NaN" Margin="0,0,20,0" TextWrapping="Wrap" VerticalScrollBarVisibility="Auto" IsReadOnly="True" Style="{StaticResource RoundedTextBox}"/--> + <Border Grid.Row="0" + Grid.Column="0" + Grid.RowSpan="2" + BorderBrush="{DynamicResource AccentBrush}" + BorderThickness="2" + CornerRadius="5" + Padding="10,0,0,0" + Background="{DynamicResource BackgroundDarkBrush}" + Margin="0,0,20,0"> + <ScrollViewer VerticalScrollBarVisibility="Auto" + Width="419" + Margin="0,0,-5,0"> + <StackPanel Name="KillFeedStackPanel" + Orientation="Vertical" + Margin="0,0,0,0" + Width="402" + HorizontalAlignment="Left"/> + </ScrollViewer> + </Border> - <!-- StackPanel for Start and Stop buttons --> - <Border Background="{DynamicResource BackgroundDarkBrush}" BorderBrush="{DynamicResource AccentBrush}" Grid.Row="0" Grid.Column="1" BorderThickness="2" CornerRadius="5" Margin="0,0,0,82"/> - <StackPanel Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Center" Height="269" Width="152"> - <TextBlock Name="PilotNameTitle" Text="Pilot" Width="152" Height="20" Background="Transparent" FontFamily="{StaticResource Orbitron}" Margin="0,5,0,0" Foreground="{DynamicResource AltTextBrush}" FontSize="14"/> - <TextBlock Name="PilotNameTextBox" Text="" Width="152" Height="20" Background="Transparent" FontFamily="{StaticResource Orbitron}" Margin="0,0,0,0" Foreground="{DynamicResource TextBrush}" FontSize="10" TextAlignment="Center"/> - <TextBlock Name="PlayerShipTitle" Text="Ship" Width="152" Height="20" Background="Transparent" FontFamily="{StaticResource Orbitron}" Margin="0,5,0,0" Foreground="{DynamicResource AltTextBrush}" FontSize="14" /> - <TextBlock Name="PlayerShipTextBox" Text="" Width="152" Height="20" Background="Transparent" FontFamily="{StaticResource Orbitron}" Margin="0,0,0,0" Foreground="{DynamicResource TextBrush}" FontSize="10" TextAlignment="Center"/> - <TextBlock Name="GameModeTitle" Text="Game Mode" Width="152" Height="20" Background="Transparent" FontFamily="{StaticResource Orbitron}" Margin="0,5,0,0" Foreground="{DynamicResource AltTextBrush}" FontSize="14"/> - <TextBlock Name="GameModeTextBox" Text="" Width="152" Height="20" Background="Transparent" FontFamily="{StaticResource Orbitron}" Margin="0,0,0,0" Foreground="{DynamicResource TextBrush}" FontSize="10" TextAlignment="Center"/> - <TextBlock Name="KillTallyTitle" Text="Kill Tally" Width="152" Height="20" Background="Transparent" FontFamily="{StaticResource Orbitron}" Margin="0,5,0,0" Foreground="{DynamicResource AltTextBrush}" FontSize="14"/> - <TextBlock Name="KillTallyTextBox" Text="" Width="152" Height="20" Background="Transparent" FontFamily="{StaticResource Orbitron}" Margin="0,0,0,0" Foreground="{DynamicResource TextBrush}" FontSize="10" TextAlignment="Center"/> - <TextBox x:Name="DebugPanel" Text="" Width="152" Height="98" Background="Transparent" FontFamily="{StaticResource Orbitron}" Foreground="{DynamicResource TextBrush}" FontSize="8" BorderThickness="0" Margin="0,9,0,0"/> - </StackPanel> - <StackPanel Grid.Row="1" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Center" Height="120" Width="172" > - <Button Name="StartButton" Content="Start" Width="100" Height="40" Style="{StaticResource ButtonStyle}" FontFamily="{StaticResource Orbitron}" Margin="0,20" Click="StartButton_Click"/> - <Button Name="StopButton" Content="Stop" Width="100" Height="40" Style="{StaticResource DisabledButtonStyle}" FontFamily="{StaticResource Orbitron}" IsEnabled="False" Click="StopButton_Click"/> - </StackPanel> + <!-- StackPanel for Start and Stop buttons --> + <Border Background="{DynamicResource BackgroundDarkBrush}" + BorderBrush="{DynamicResource AccentBrush}" + Grid.Row="0" + Grid.Column="1" + BorderThickness="2" + CornerRadius="5" + Margin="0,0,0,82"/> + <StackPanel Grid.Column="1" + VerticalAlignment="Center" + HorizontalAlignment="Center" + Height="269" + Width="152"> + <TextBlock Name="PilotNameTitle" + Text="Pilot" + Width="152" + Height="20" + Background="Transparent" + FontFamily="{StaticResource Orbitron}" + Margin="0,5,0,0" + Foreground="{DynamicResource AltTextBrush}" + FontSize="14"/> + <TextBlock Name="PilotNameTextBox" + Text="" + Width="152" + Height="20" + Background="Transparent" + FontFamily="{StaticResource Orbitron}" + Margin="0,0,0,0" + Foreground="{DynamicResource TextBrush}" + FontSize="10" + TextAlignment="Center"/> + <TextBlock Name="PlayerShipTitle" + Text="Ship" + Width="152" + Height="20" + Background="Transparent" + FontFamily="{StaticResource Orbitron}" + Margin="0,5,0,0" + Foreground="{DynamicResource AltTextBrush}" + FontSize="14"/> + <TextBlock Name="PlayerShipTextBox" + Text="" + Width="152" + Height="20" + Background="Transparent" + FontFamily="{StaticResource Orbitron}" + Margin="0,0,0,0" + Foreground="{DynamicResource TextBrush}" + FontSize="10" + TextAlignment="Center"/> + <TextBlock Name="GameModeTitle" + Text="Game Mode" + Width="152" + Height="20" + Background="Transparent" + FontFamily="{StaticResource Orbitron}" + Margin="0,5,0,0" + Foreground="{DynamicResource AltTextBrush}" + FontSize="14"/> + <TextBlock Name="GameModeTextBox" + Text="" + Width="152" + Height="20" + Background="Transparent" + FontFamily="{StaticResource Orbitron}" + Margin="0,0,0,0" + Foreground="{DynamicResource TextBrush}" + FontSize="10" + TextAlignment="Center"/> + <TextBlock Name="KillTallyTitle" + Text="Kill Tally" + Width="152" + Height="20" + Background="Transparent" + FontFamily="{StaticResource Orbitron}" + Margin="0,5,0,0" + Foreground="{DynamicResource AltTextBrush}" + FontSize="14"/> + <TextBlock Name="KillTallyTextBox" + Text="" + Width="152" + Height="20" + Background="Transparent" + FontFamily="{StaticResource Orbitron}" + Margin="0,0,0,0" + Foreground="{DynamicResource TextBrush}" + FontSize="10" + TextAlignment="Center"/> + <TextBox x:Name="DebugPanel" + Text="" + Width="152" + Height="98" + Background="Transparent" + FontFamily="{StaticResource Orbitron}" + Foreground="{DynamicResource TextBrush}" + FontSize="8" + BorderThickness="0" + Margin="0,9,0,0"/> + </StackPanel> + <StackPanel Grid.Row="1" + Grid.Column="1" + VerticalAlignment="Center" + HorizontalAlignment="Center" + Height="120" + Width="172"> + <Border Background="{DynamicResource BackgroundDarkBrush}" + BorderBrush="{DynamicResource AccentBrush}" + BorderThickness="2" + CornerRadius="5" + Height="80" + Margin="0,10,0,0"> + <StackPanel Orientation="Horizontal" + HorizontalAlignment="Center" + VerticalAlignment="Center"> + <Ellipse x:Name="StatusLight" + Width="15" + Height="15" + Margin="0,0,10,0" + Fill="Red"/> + <TextBlock x:Name="StatusText" + Text="TrackR
Standby" + Foreground="{DynamicResource TextBrush}" + FontFamily="{StaticResource Orbitron}" + FontSize="14" + VerticalAlignment="Center"/> + </StackPanel> + </Border> + </StackPanel> + </Grid> </Grid> - </Grid> </UserControl> diff --git a/AutoTrackR2/HomePage.xaml.cs b/AutoTrackR2/HomePage.xaml.cs index 1baf48b..f8755df 100644 --- a/AutoTrackR2/HomePage.xaml.cs +++ b/AutoTrackR2/HomePage.xaml.cs @@ -9,15 +9,18 @@ using System.IO; using System.Text; using System.Windows.Media.Imaging; using AutoTrackR2.LogEventHandlers; +using System.Timers; +using System.Linq; namespace AutoTrackR2; public partial class HomePage : UserControl { - private Process runningProcess; // Field to store the running process private LogHandler? _logHandler; private KillHistoryManager _killHistoryManager; private bool _UIEventsRegistered = false; + private System.Timers.Timer _statusCheckTimer; + private bool _isLogHandlerRunning = false; public HomePage() { @@ -31,59 +34,71 @@ public partial class HomePage : UserControl AdjustFontSize(KillTallyTextBox); AddKillHistoryKillsToUI(); - } - // - public void UpdateButtonState(bool isRunning) - { - var accentColor = (Color)Application.Current.Resources["AccentColor"]; + // Initialize and start the status check timer + _statusCheckTimer = new System.Timers.Timer(1000); // Check every second + _statusCheckTimer.Elapsed += CheckStarCitizenStatus; + _statusCheckTimer.Start(); + // Check if Star Citizen is already running and initialize accordingly + if (IsStarCitizenRunning()) + { + Dispatcher.Invoke(() => + { + UpdateStatusIndicator(true); + ReadInitialStates(); // Read states first + InitializeLogHandler(); // Then initialize the log handler + }); + } + } + + private void CheckStarCitizenStatus(object sender, ElapsedEventArgs e) + { + bool isRunning = IsStarCitizenRunning(); + Dispatcher.Invoke(() => + { + UpdateStatusIndicator(isRunning); + + if (isRunning) + { + if (!_isLogHandlerRunning) + { + // Game is running, start log monitoring and read initial states + InitializeLogHandler(); + ReadInitialStates(); + } + } + else + { + // Game is not running, set everything to Unknown + GameModeTextBox.Text = "Unknown"; + PlayerShipTextBox.Text = "Unknown"; + PilotNameTextBox.Text = "Unknown"; + LocalPlayerData.CurrentGameMode = GameMode.Unknown; + LocalPlayerData.PlayerShip = string.Empty; + LocalPlayerData.Username = string.Empty; + + // Stop log monitoring if it's running + if (_isLogHandlerRunning) + { + _logHandler?.StopMonitoring(); + _isLogHandlerRunning = false; + } + } + }); + } + + private void UpdateStatusIndicator(bool isRunning) + { if (isRunning) { - // Set Start button to "Running..." and apply glow effect - StartButton.Content = "Running..."; - StartButton.IsEnabled = false; // Disable Start button - StartButton.Style = (Style)FindResource("DisabledButtonStyle"); - - // Add glow effect to the Start button - StartButton.Effect = new DropShadowEffect - { - Color = accentColor, - BlurRadius = 30, // Adjust blur radius for desired glow intensity - ShadowDepth = 0, // Set shadow depth to 0 for a pure glow effect - Opacity = 1, // Set opacity for glow visibility - Direction = 0 // Direction doesn't matter for glow - }; - - StopButton.Style = (Style)FindResource("ButtonStyle"); - StopButton.IsEnabled = true; // Enable Stop button + StatusLight.Fill = new SolidColorBrush(Colors.Green); + StatusText.Text = "TrackR\nActive"; } else { - // Reset Start button back to its original state - StartButton.Content = "Start"; - StartButton.IsEnabled = true; // Enable Start button - - // Remove the glow effect from Start button - StartButton.Effect = null; - - StopButton.Style = (Style)FindResource("DisabledButtonStyle"); - StartButton.Style = (Style)FindResource("ButtonStyle"); - StopButton.IsEnabled = false; // Disable Stop button + StatusLight.Fill = new SolidColorBrush(Colors.Red); + StatusText.Text = "TrackR\nStandby"; } - - RegisterUIEventHandlers(); - } - - public void StartButton_Click(object sender, RoutedEventArgs e) - { - UpdateButtonState(true); - //string scriptPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "KillTrackR_MainScript.ps1"); - // TailFileAsync(scriptPath); - - // _logHandler = new LogHandler(@"U:\\StarCitizen\\StarCitizen\\LIVE\\Game.log"); - _logHandler = new LogHandler(ConfigManager.LogFile); - _logHandler.Initialize(); - } private void AddKillHistoryKillsToUI() @@ -116,7 +131,7 @@ public partial class HomePage : UserControl { Dispatcher.Invoke(() => { - PlayerShipTextBox.Text = shipName; + PlayerShipTextBox.Text = LocalPlayerData.CurrentGameMode == GameMode.PersistentUniverse ? "Player" : shipName; AdjustFontSize(PlayerShipTextBox); LocalPlayerData.PlayerShip = shipName; }); @@ -127,7 +142,7 @@ public partial class HomePage : UserControl { Dispatcher.Invoke(() => { - GameModeTextBox.Text = mode == GameMode.PersistentUniverse ? "PU" : mode.ToString(); + GameModeTextBox.Text = mode == GameMode.PersistentUniverse ? "Player" : mode.ToString(); AdjustFontSize(GameModeTextBox); LocalPlayerData.CurrentGameMode = mode; }); @@ -327,7 +342,7 @@ public partial class HomePage : UserControl public void StopButton_Click(object sender, RoutedEventArgs e) { - _logHandler?.Stop(); + _logHandler?.StopMonitoring(); // Clear the text boxes // System.Threading.Thread.Sleep(200); @@ -411,4 +426,159 @@ public partial class HomePage : UserControl RunAHKScript(ConfigManager.VideoRecordScript); } } + + public void InitializeLogHandler() + { + if (_logHandler == null) + { + _logHandler = new LogHandler(ConfigManager.LogFile); + _logHandler.Initialize(); + RegisterUIEventHandlers(); + _isLogHandlerRunning = true; + + // Read initial states after initializing log handler + ReadInitialStates(); + } + else if (!_isLogHandlerRunning) + { + _logHandler.Initialize(); + _isLogHandlerRunning = true; + ReadInitialStates(); + } + } + + private void ReadInitialStates() + { + if (string.IsNullOrEmpty(ConfigManager.LogFile) || !File.Exists(ConfigManager.LogFile)) + { + Debug.WriteLine("Log file not found or path is empty"); + return; + } + + try + { + Debug.WriteLine("Reading initial states from log file..."); + // Read the entire log file + var lines = File.ReadAllLines(ConfigManager.LogFile); + string username = ""; + string shipName = ""; + GameMode gameMode = GameMode.Unknown; + + // Read from the end of the file to get the most recent states + for (int i = lines.Length - 1; i >= 0; i--) + { + var line = lines[i]; + + // Check for username (login) + if (line.Contains("'s Character")) + { + int startIndex = line.IndexOf("'s Character"); + if (startIndex > 0) + { + username = line.Substring(0, startIndex).Trim(); + Debug.WriteLine($"Found username: {username}"); + } + } + // Check for ship name + else if (line.Contains("Entering quantum travel from")) + { + int startIndex = line.IndexOf("in ship") + 8; + int endIndex = line.IndexOf(" to ", startIndex); + if (startIndex > 8 && endIndex > startIndex) + { + shipName = line.Substring(startIndex, endIndex - startIndex).Trim(); + Debug.WriteLine($"Found ship: {shipName}"); + } + } + // Check for game mode + else if (line.Contains("Loading level")) + { + if (line.Contains("Persistent_Universe")) + { + gameMode = GameMode.PersistentUniverse; + Debug.WriteLine("Found game mode: PU"); + } + else if (line.Contains("Arena_Commander")) + { + gameMode = GameMode.ArenaCommander; + Debug.WriteLine("Found game mode: AC"); + } + } + + // If we've found all the information we need, we can stop reading + if (!string.IsNullOrEmpty(username) && !string.IsNullOrEmpty(shipName) && gameMode != GameMode.Unknown) + { + break; + } + } + + // Update UI with found states + Dispatcher.Invoke(() => + { + if (!string.IsNullOrEmpty(username)) + { + PilotNameTextBox.Text = username; + LocalPlayerData.Username = username; + AdjustFontSize(PilotNameTextBox); + Debug.WriteLine($"Set username in UI: {username}"); + } + else + { + PilotNameTextBox.Text = "Unknown"; + LocalPlayerData.Username = string.Empty; + AdjustFontSize(PilotNameTextBox); + Debug.WriteLine("Username not found, set to Unknown"); + } + + if (!string.IsNullOrEmpty(shipName)) + { + PlayerShipTextBox.Text = gameMode == GameMode.PersistentUniverse ? "Player" : shipName; + LocalPlayerData.PlayerShip = shipName; + AdjustFontSize(PlayerShipTextBox); + Debug.WriteLine($"Set ship in UI: {PlayerShipTextBox.Text}"); + } + else + { + PlayerShipTextBox.Text = "Unknown"; + LocalPlayerData.PlayerShip = string.Empty; + AdjustFontSize(PlayerShipTextBox); + Debug.WriteLine("Ship not found, set to Unknown"); + } + + if (gameMode != GameMode.Unknown) + { + GameModeTextBox.Text = gameMode == GameMode.PersistentUniverse ? "Player" : gameMode.ToString(); + LocalPlayerData.CurrentGameMode = gameMode; + AdjustFontSize(GameModeTextBox); + Debug.WriteLine($"Set game mode in UI: {GameModeTextBox.Text}"); + } + else + { + GameModeTextBox.Text = "Unknown"; + LocalPlayerData.CurrentGameMode = GameMode.Unknown; + AdjustFontSize(GameModeTextBox); + Debug.WriteLine("Game mode not found, set to Unknown"); + } + }); + } + catch (Exception ex) + { + Debug.WriteLine($"Error reading initial states: {ex.Message}"); + } + } + + public void Cleanup() + { + // Stop and dispose the status check timer + _statusCheckTimer?.Stop(); + _statusCheckTimer?.Dispose(); + + // Stop the log handler if it's running + _logHandler?.StopMonitoring(); + } + + private bool IsStarCitizenRunning() + { + return Process.GetProcessesByName("StarCitizen").Length > 0; + } } diff --git a/AutoTrackR2/LocalPlayerData.cs b/AutoTrackR2/LocalPlayerData.cs index 668ebcd..87d8911 100644 --- a/AutoTrackR2/LocalPlayerData.cs +++ b/AutoTrackR2/LocalPlayerData.cs @@ -3,8 +3,9 @@ public enum GameMode { - ArenaCommander, - PersistentUniverse + Unknown, + PersistentUniverse, + ArenaCommander } public static class LocalPlayerData diff --git a/AutoTrackR2/LogHandler.cs b/AutoTrackR2/LogHandler.cs index 38ddd6e..fed7b33 100644 --- a/AutoTrackR2/LogHandler.cs +++ b/AutoTrackR2/LogHandler.cs @@ -12,7 +12,7 @@ public class LogEntry { public DateTime Timestamp { get; set; } public required string? Message { get; set; } - + } enum GameProcessState @@ -22,16 +22,18 @@ enum GameProcessState Unknown } -public class LogHandler(string logPath) +public class LogHandler { - private readonly string? _logPath = logPath; + private string _logPath; private FileStream? _fileStream; private StreamReader? _reader; - private GameProcessState _gameProcessState = GameProcessState.Unknown; + private Thread? _monitorThread; + private CancellationTokenSource? _cancellationTokenSource; + private GameProcessState _gameProcessState = GameProcessState.NotRunning; + private bool _isMonitoring = false; + + public bool IsMonitoring => _isMonitoring; - private CancellationTokenSource cancellationToken = new CancellationTokenSource(); - Thread? monitorThread; - // Handlers that should be run on every log entry // Overlap with _startupEventHandlers is fine private readonly List<ILogEventHandler> _eventHandlers = [ @@ -44,17 +46,21 @@ public class LogHandler(string logPath) new RequestJumpFailedEvent() ]; - // Initialize the LogHandler and run all startup handlers + public LogHandler(string logPath) + { + _logPath = logPath; + } + public void Initialize() { if (!File.Exists(_logPath)) { throw new FileNotFoundException("Log file not found", _logPath); } - + _fileStream = new FileStream(_logPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); _reader = new StreamReader(_fileStream); - + while (_reader.ReadLine() is { } line) { HandleLogEntry(line); @@ -62,19 +68,31 @@ public class LogHandler(string logPath) // Ensures that any deaths already in log aren't sent to the APIs until the monitor thread is running _eventHandlers.Add(new ActorDeathEvent()); - - monitorThread = new Thread(() => MonitorLog(cancellationToken.Token)); - monitorThread.Start(); + + StartMonitoring(); } - public void Stop() + public void StartMonitoring() { - // Stop the monitor thread - cancellationToken?.Cancel(); + if (_isMonitoring) return; + + _cancellationTokenSource = new CancellationTokenSource(); + _monitorThread = new Thread(() => MonitorLog(_cancellationTokenSource.Token)); + _monitorThread.Start(); + _isMonitoring = true; + } + + public void StopMonitoring() + { + if (!_isMonitoring) return; + + _cancellationTokenSource?.Cancel(); + _monitorThread?.Join(); _reader?.Close(); _fileStream?.Close(); + _isMonitoring = false; } - + // Parse a single line of the log file and run matching handlers private void HandleLogEntry(string line) { @@ -83,7 +101,7 @@ public class LogHandler(string logPath) { var match = handler.Pattern.Match(line); if (!match.Success) continue; - + var entry = new LogEntry { Timestamp = DateTime.Now, @@ -93,7 +111,7 @@ public class LogHandler(string logPath) break; } } - + private void MonitorLog(CancellationToken token) { while (!token.IsCancellationRequested) @@ -102,9 +120,9 @@ public class LogHandler(string logPath) { break; } - + CheckGameProcessState(); - + List<string> lines = new List<string>(); while (_reader.ReadLine() is { } line) { @@ -131,21 +149,21 @@ public class LogHandler(string logPath) { // Check if the game process is running by window name var process = Process.GetProcesses().FirstOrDefault(p => p.MainWindowTitle == "Star Citizen"); - + GameProcessState newGameProcessState = process != null ? GameProcessState.Running : GameProcessState.NotRunning; - + if (newGameProcessState == GameProcessState.Running && _gameProcessState == GameProcessState.NotRunning) { // Game process went from NotRunning to Running, so reload the Game.log file Console.WriteLine("Game process started, reloading log file"); - + _reader?.Close(); _fileStream?.Close(); - + _fileStream = new FileStream(_logPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); _reader = new StreamReader(_fileStream); } - + _gameProcessState = newGameProcessState; } } \ No newline at end of file diff --git a/AutoTrackR2/MainWindow.xaml.cs b/AutoTrackR2/MainWindow.xaml.cs index 637e90f..4efcee9 100644 --- a/AutoTrackR2/MainWindow.xaml.cs +++ b/AutoTrackR2/MainWindow.xaml.cs @@ -13,7 +13,6 @@ namespace AutoTrackR2 { public partial class MainWindow : Window { - private Dictionary<string, bool> tabStates = new Dictionary<string, bool> { { "HomeTab", true }, // HomeTab is selected by default @@ -23,9 +22,7 @@ namespace AutoTrackR2 }; private HomePage homePage; // Persistent HomePage instance - private bool isRunning = false; // Single source of truth for the running state - // Ensure this method is not static public void ChangeLogoImage(string imagePath) { Logo.Source = new BitmapImage(new Uri(imagePath, UriKind.RelativeOrAbsolute)); @@ -38,10 +35,6 @@ namespace AutoTrackR2 homePage = new HomePage(); // Create a single instance of HomePage ContentControl.Content = homePage; // Default to HomePage - // Attach event handlers for the HomePage buttons - homePage.StartButton.Click += StartButton_Click; - homePage.StopButton.Click += StopButton_Click; - // Create ConfigPage and pass the MainWindow reference to it var configPage = new ConfigPage(this); @@ -51,6 +44,7 @@ namespace AutoTrackR2 UpdateTabVisuals(); Loaded += MainWindow_Loaded; // Handle Loaded event + Closing += MainWindow_Closing; // Handle Closing event } private void MainWindow_Loaded(object sender, RoutedEventArgs e) @@ -59,16 +53,23 @@ namespace AutoTrackR2 var args = Environment.GetCommandLineArgs(); if (args.Contains("-start", StringComparer.OrdinalIgnoreCase)) { - homePage.StartButton_Click(null, null); + // Initialize log handler if needed + homePage.InitializeLogHandler(); } } + private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e) + { + // Clean up resources + homePage?.Cleanup(); + + // Make sure the application exits completely + Application.Current.Shutdown(); + } + private void CloseWindow(object sender, RoutedEventArgs e) { - // If runningProcess is not null and still active, terminate it - homePage.StopButton_Click(sender, e); - - // Close the main window + // This will trigger the Closing event this.Close(); } @@ -91,9 +92,6 @@ namespace AutoTrackR2 { // Reuse the existing HomePage instance ContentControl.Content = homePage; - - // Update the button state on the HomePage - homePage.UpdateButtonState(isRunning); } else if (clickedTabName == "StatsTab") { @@ -158,20 +156,6 @@ namespace AutoTrackR2 } } - private void StartButton_Click(object sender, RoutedEventArgs e) - { - isRunning = true; // Update the running state - homePage.UpdateButtonState(isRunning); // Update HomePage button visuals - // Start your logic here - } - - private void StopButton_Click(object sender, RoutedEventArgs e) - { - isRunning = false; // Update the running state - homePage.UpdateButtonState(isRunning); // Update HomePage button visuals - // Stop your logic here - } - private void InitializeConfigPage() { // Set the values from the loaded config @@ -195,12 +179,12 @@ namespace AutoTrackR2 { public static string LogFile { get; set; } public static string KillHistoryFile { get; set; } - + public static string AHKScriptFolder { get; set; } - + public static string VisorWipeScript { get; set; } public static string VideoRecordScript { get; set; } - + public static string ApiUrl { get; set; } public static string ApiKey { get; set; } public static string VideoPath { get; set; } @@ -208,11 +192,11 @@ namespace AutoTrackR2 public static int VideoRecord { get; set; } public static int OfflineMode { get; set; } public static int Theme { get; set; } - + static ConfigManager() - { + { LoadConfig(); - + // Set default values // AppData\Local\AutoTrackR2\Kill-log.csv KillHistoryFile = Path.Combine( @@ -220,12 +204,12 @@ namespace AutoTrackR2 "AutoTrackR2", "Kill-log.csv" ); - + AHKScriptFolder = Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "AutoTrackR2" ); - + VisorWipeScript = "visorwipe.ahk"; VideoRecordScript = "videorecord.ahk"; }