diff --git a/AutoTrackR2/App.xaml b/AutoTrackR2/App.xaml index 0717447..b2f9f06 100644 --- a/AutoTrackR2/App.xaml +++ b/AutoTrackR2/App.xaml @@ -571,55 +571,5 @@ </Setter> </Style> - <!-- Standard Slider Style --> - <Style x:Key="SliderStyle" TargetType="Slider"> - <Setter Property="Height" Value="40"/> - <Setter Property="Width" Value="160"/> - <Setter Property="Foreground" Value="{DynamicResource TextBrush}"/> - <Setter Property="Background" Value="{DynamicResource BackgroundDarkBrush}"/> - <Setter Property="BorderBrush" Value="{DynamicResource AccentBrush}"/> - <Setter Property="BorderThickness" Value="2"/> - <Setter Property="Template"> - <Setter.Value> - <ControlTemplate TargetType="Slider"> - <Grid Width="100" Height="30" HorizontalAlignment="Left"> - <!-- Track Background --> - <Border Background="{DynamicResource BackgroundDarkBrush}" - BorderBrush="{DynamicResource AccentBrush}" - BorderThickness="2" - CornerRadius="15" - Margin="0,0,-5,-4"/> - - <!-- Track --> - <Track x:Name="PART_Track"> - <Track.Thumb> - <Thumb x:Name="PART_Thumb" - Width="22" - Height="22" - Margin="6,4,1,0"> - <Thumb.Template> - <ControlTemplate TargetType="Thumb"> - <Ellipse Fill="{DynamicResource AccentBrush}"/> - </ControlTemplate> - </Thumb.Template> - </Thumb> - </Track.Thumb> - <Track.DecreaseRepeatButton> - <RepeatButton Background="Transparent" - BorderBrush="Transparent" - IsHitTestVisible="False"/> - </Track.DecreaseRepeatButton> - <Track.IncreaseRepeatButton> - <RepeatButton Background="Transparent" - BorderBrush="Transparent" - IsHitTestVisible="False"/> - </Track.IncreaseRepeatButton> - </Track> - </Grid> - </ControlTemplate> - </Setter.Value> - </Setter> - </Style> - </Application.Resources> </Application> diff --git a/AutoTrackR2/App.xaml.cs b/AutoTrackR2/App.xaml.cs index e9a45e7..e84d792 100644 --- a/AutoTrackR2/App.xaml.cs +++ b/AutoTrackR2/App.xaml.cs @@ -19,7 +19,6 @@ namespace AutoTrackR2 "AutoTrackR2", "crash.log" ); - private StreamlinkHandler? _streamlinkHandler; protected override void OnStartup(StartupEventArgs e) { @@ -44,7 +43,6 @@ namespace AutoTrackR2 } base.OnStartup(e); - _streamlinkHandler = new StreamlinkHandler(); } private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) diff --git a/AutoTrackR2/ConfigPage.xaml b/AutoTrackR2/ConfigPage.xaml index 2ecc235..70567a9 100644 --- a/AutoTrackR2/ConfigPage.xaml +++ b/AutoTrackR2/ConfigPage.xaml @@ -2,13 +2,14 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Height="410" - Width="700"> + Width="626"> <Grid Background="{DynamicResource BackgroundLightBrush}"> <!-- Main Layout Grid --> - <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> @@ -21,9 +22,9 @@ </Grid.ColumnDefinitions> <!-- Section for Config Fields --> - <StackPanel Grid.Row="0" - VerticalAlignment="Top" - Margin="20,10,20,0"> + <StackPanel Grid.Column="0" + VerticalAlignment="Center" + Height="389"> <!-- Log File --> <StackPanel Margin="0,5,0,10" Orientation="Horizontal"> @@ -37,11 +38,11 @@ FontSize="16" Margin="0,5,0,5" FontFamily="{StaticResource Roboto}"/> - <StackPanel Orientation="Horizontal"> + <StackPanel Orientation="Horizontal" + Margin="30,0,0,0"> <TextBox Name="LogFilePath" - Width="260" + Width="330" Height="30" - Margin="10,0,0,0" Style="{StaticResource RoundedTextBox}"/> <Button Content="Browse" Width="75" @@ -50,13 +51,6 @@ Margin="5,0" Style="{StaticResource ButtonStyle}" Click="LogFileBrowseButton_Click"/> - <Button Content="Open" - Width="75" - Height="30" - FontFamily="{StaticResource Orbitron}" - Margin="5,0" - Style="{StaticResource ButtonStyle}" - Click="LogFileOpenButton_Click"/> </StackPanel> </StackPanel> @@ -72,11 +66,11 @@ Foreground="{DynamicResource TextBrush}" FontSize="16" Margin="0,5,0,5"/> - <StackPanel Orientation="Horizontal"> + <StackPanel Orientation="Horizontal" + Margin="30,0,0,0"> <TextBox Name="ApiUrl" - Width="260" + Width="330" Height="30" - Margin="10,0,0,0" Style="{StaticResource RoundedTextBox}"/> <Button Content="Test" Width="75" @@ -101,9 +95,9 @@ FontSize="16" Margin="0,5,0,5"/> <PasswordBox Name="ApiKey" - Width="260" + Width="330" Height="30" - Margin="10,0,0,0" + Margin="33,0,0,0" Style="{StaticResource RoundedPasswordBox}"/> </StackPanel> @@ -121,7 +115,7 @@ Margin="0,5,0,5"/> <StackPanel Orientation="Horizontal"> <TextBox Name="VideoPath" - Width="260" + Width="330" Height="30" Margin="10,0,0,0" Style="{StaticResource RoundedTextBox}"/> @@ -132,214 +126,130 @@ Margin="5,0" Style="{StaticResource ButtonStyle}" Click="VideoPathBrowseButton_Click"/> - <Button Content="Open" - Width="75" - Height="30" - FontFamily="{StaticResource Orbitron}" - Margin="5,0" - Style="{StaticResource ButtonStyle}" - Click="VideoPathOpenButton_Click"/> </StackPanel> </StackPanel> <!-- Toggle Settings Grid --> <Grid Margin="0,0,0,10"> - <Grid.ColumnDefinitions> - <ColumnDefinition Width="*"/> - <ColumnDefinition Width="*"/> - </Grid.ColumnDefinitions> - <Grid.RowDefinitions> - <RowDefinition Height="Auto"/> - <RowDefinition Height="Auto"/> - <RowDefinition Height="Auto"/> - <RowDefinition Height="Auto"/> - <RowDefinition Height="Auto"/> - </Grid.RowDefinitions> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="*"/> + <ColumnDefinition Width="*"/> + </Grid.ColumnDefinitions> + <Grid.RowDefinitions> + <RowDefinition Height="Auto"/> + <RowDefinition Height="Auto"/> + <RowDefinition Height="Auto"/> + </Grid.RowDefinitions> - <!-- Left Column Controls --> + <!-- Visor Wipe Toggle --> + <StackPanel Grid.Column="0" Grid.Row="0" + Orientation="Horizontal" + Margin="0,0,5,5"> + <TextBlock Text="ⓘ" + ToolTip="Perform a Visor Wipe animation on player kill. Requires AHKv2." + Foreground="{DynamicResource TextBrush}" + FontSize="20" + Margin="0,4,3,0"/> + <TextBlock Text="Visor Wipe:" + Foreground="{DynamicResource TextBrush}" + FontSize="16" + Margin="0,7,0,0"/> + <Slider Name="VisorWipeSlider" + Minimum="0" + Maximum="1" + TickFrequency="1" + IsSnapToTickEnabled="True" + Value="0" + Style="{StaticResource ToggleSliderStyle}" + Margin="10,-4,0,0" + Width="100" + ValueChanged="VisorWipeSlider_ValueChanged"/> + </StackPanel> - <!-- Visor Wipe Toggle --> - <StackPanel Grid.Column="0" - Grid.Row="0" - Orientation="Horizontal" - Margin="0,0,5,5"> - <TextBlock Text="ⓘ" - ToolTip="Perform a Visor Wipe animation on player kill. Requires AHKv2." - Foreground="{DynamicResource TextBrush}" - FontSize="20" - Margin="0,4,3,0"/> - <TextBlock Text="Visor Wipe:" - Foreground="{DynamicResource TextBrush}" - FontSize="16" - Margin="0,7,0,0"/> - <Slider Name="VisorWipeSlider" - Minimum="0" - Maximum="1" - TickFrequency="1" - IsSnapToTickEnabled="True" - Value="0" - Style="{StaticResource ToggleSliderStyle}" - Margin="10,-4,0,0" - Width="100" - ValueChanged="VisorWipeSlider_ValueChanged"/> - </StackPanel> + <!-- Video Record Toggle --> + <StackPanel Grid.Column="1" Grid.Row="0" + Orientation="Horizontal" + Margin="5,0,0,5"> + <TextBlock Text="ⓘ" + ToolTip="Automatically clip your last kill. Check the README for more info." + Foreground="{DynamicResource TextBrush}" + FontSize="20" + Margin="0,4,3,0"/> + <TextBlock Text="Video Record:" + Foreground="{DynamicResource TextBrush}" + FontSize="16" + Margin="0,7,0,0"/> + <Slider Name="VideoRecordSlider" + Minimum="0" + Maximum="1" + TickFrequency="1" + IsSnapToTickEnabled="True" + Value="0" + Style="{StaticResource ToggleSliderStyle}" + Margin="10,-4,0,0" + Width="100" + ValueChanged="VideoRecordSlider_ValueChanged"/> + </StackPanel> - <!-- Video Record Toggle --> - <StackPanel Grid.Column="0" - Grid.Row="1" - Orientation="Horizontal" - Margin="0,0,5,5"> - <TextBlock Text="ⓘ" - ToolTip="Record video on player kill. Requires AHKv2." - Foreground="{DynamicResource TextBrush}" - FontSize="20" - Margin="0,4,3,0"/> - <TextBlock Text="Video Record:" - Foreground="{DynamicResource TextBrush}" - FontSize="16" - Margin="0,7,0,0"/> - <Slider Name="VideoRecordSlider" - Minimum="0" - Maximum="1" - TickFrequency="1" - IsSnapToTickEnabled="True" - Value="0" - Style="{StaticResource ToggleSliderStyle}" - Margin="10,-4,0,0" - Width="100" - ValueChanged="VideoRecordSlider_ValueChanged"/> - </StackPanel> + <!-- Offline Mode Toggle --> + <StackPanel Grid.Column="0" Grid.Row="1" + Orientation="Horizontal" + Margin="0,0,5,5"> + <TextBlock Text="ⓘ" + ToolTip="With Offline Mode enabled, kills will not be submitted to the configured API." + Foreground="{DynamicResource TextBrush}" + FontSize="20" + Margin="0,4,3,0"/> + <TextBlock Text="Offline Mode:" + Foreground="{DynamicResource TextBrush}" + FontSize="16" + Margin="0,7,0,0"/> + <Slider Name="OfflineModeSlider" + Minimum="0" + Maximum="1" + TickFrequency="1" + IsSnapToTickEnabled="True" + Value="0" + Style="{StaticResource ToggleSliderStyle}" + Margin="10,-4,0,0" + Width="100" + ValueChanged="OfflineModeSlider_ValueChanged"/> + </StackPanel> - <!-- Offline Mode Toggle --> - <StackPanel Grid.Column="0" - Grid.Row="2" - Orientation="Horizontal" - Margin="0,0,5,5"> - <TextBlock Text="ⓘ" - ToolTip="With Offline Mode enabled, kills will not be submitted to the configured API." - Foreground="{DynamicResource TextBrush}" - FontSize="20" - Margin="0,4,3,0"/> - <TextBlock Text="Offline Mode:" - Foreground="{DynamicResource TextBrush}" - FontSize="16" - Margin="0,7,0,0"/> - <Slider Name="OfflineModeSlider" - Minimum="0" - Maximum="1" - TickFrequency="1" - IsSnapToTickEnabled="True" - Value="0" - Style="{StaticResource ToggleSliderStyle}" - Margin="10,-4,0,0" - Width="100" - ValueChanged="OfflineModeSlider_ValueChanged"/> - </StackPanel> - - <!-- Right Column Controls --> - - <!-- Streamlink Toggle --> - <StackPanel Grid.Column="1" - Grid.Row="0" - Orientation="Horizontal" - Margin="5,0,0,5"> - <TextBlock Text="ⓘ" - ToolTip="Use Streamlink for video recording." - Foreground="{DynamicResource TextBrush}" - FontSize="20" - Margin="0,4,3,0"/> - <TextBlock Text="Streamlink:" - Foreground="{DynamicResource TextBrush}" - FontSize="16" - Margin="0,7,0,0"/> - <Slider Name="StreamlinkSlider" - Minimum="0" - Maximum="1" - TickFrequency="1" - IsSnapToTickEnabled="True" - Value="0" - Style="{StaticResource ToggleSliderStyle}" - Margin="10,-4,0,0" - Width="100" - ValueChanged="StreamlinkSlider_ValueChanged"/> - </StackPanel> - - <!-- Streamlink Duration --> - <StackPanel Grid.Column="1" - Grid.Row="1" - Orientation="Horizontal" - Margin="5,0,0,5"> - <TextBlock Text="ⓘ" - ToolTip="Duration of Streamlink recordings in seconds." - Foreground="{DynamicResource TextBrush}" - FontSize="20" - Margin="0,4,3,0"/> - <TextBlock Text="Duration:" - Foreground="{DynamicResource TextBrush}" - FontSize="16" - Margin="0,7,0,0"/> - <Slider Name="StreamlinkDurationSlider" - Minimum="10" - Maximum="600" - TickFrequency="30" - IsSnapToTickEnabled="True" - Value="30" - Style="{StaticResource SliderStyle}" - Margin="10,-4,0,0" - Width="100" - ValueChanged="StreamlinkDurationSlider_ValueChanged"/> - <TextBlock Name="StreamlinkDurationText" - Text="30s" - Foreground="{DynamicResource TextBrush}" - FontSize="16" - Margin="5,7,0,0"/> - </StackPanel> - - <!-- Test Streamlink Button --> - <Button Grid.Column="1" - Grid.Row="2" - Content="Test Streamlink" - Width="120" - Height="30" - FontFamily="{StaticResource Orbitron}" - Margin="5,0,0,5" - Style="{StaticResource ButtonStyle}" - Click="TestStreamlinkButton_Click"/> - - <!-- Theme Slider --> - <StackPanel Grid.Column="0" - Grid.Row="3" - Grid.ColumnSpan="2" - Orientation="Horizontal" - Margin="0,0,0,5"> - <TextBlock Text="Theme:" - Foreground="{DynamicResource TextBrush}" - FontSize="16" - Margin="0,7,10,0"/> - <Slider x:Name="ThemeSlider" - Minimum="0" - Value="0" - TickFrequency="1" - IsSnapToTickEnabled="True" - ValueChanged="ThemeSlider_ValueChanged" - Width="350" - Style="{StaticResource ThreePositionSlider}"/> - </StackPanel> + <!-- Theme Slider --> + <StackPanel Grid.Column="0" Grid.Row="2" + Grid.ColumnSpan="2" + Orientation="Horizontal" + Margin="0,0,0,5"> + <TextBlock Text="Theme:" + Foreground="{DynamicResource TextBrush}" + FontSize="16" + Margin="0,7,10,0"/> + <Slider x:Name="ThemeSlider" + Minimum="0" + Value="0" + TickFrequency="1" + IsSnapToTickEnabled="True" + ValueChanged="ThemeSlider_ValueChanged" + Width="447" + Style="{StaticResource ThreePositionSlider}"/> + </StackPanel> </Grid> </StackPanel> <!-- Save Button --> - <Button x:Name="SaveButton" - Grid.Row="1" - Content="Save" - Width="100" - Height="40" - Style="{StaticResource ButtonStyle}" - FontFamily="{StaticResource Orbitron}" - HorizontalAlignment="Right" - VerticalAlignment="Bottom" - Margin="0,0,80,20" - Click="SaveButton_Click"/> + <StackPanel Grid.Column="2" + HorizontalAlignment="Right" + VerticalAlignment="Bottom" + Margin="0,0,0,10"> + <Button x:Name="SaveButton" + Content="Save" + Width="100" + Height="40" + Style="{StaticResource ButtonStyle}" + FontFamily="{StaticResource Orbitron}" + Click="SaveButton_Click"/> + </StackPanel> </Grid> </Grid> </UserControl> diff --git a/AutoTrackR2/ConfigPage.xaml.cs b/AutoTrackR2/ConfigPage.xaml.cs index e4c1772..1136f55 100644 --- a/AutoTrackR2/ConfigPage.xaml.cs +++ b/AutoTrackR2/ConfigPage.xaml.cs @@ -11,7 +11,6 @@ using System.Windows.Media; using System.Windows.Media.Effects; using System.Windows.Threading; using Microsoft.Win32; -using System.Threading.Tasks; namespace AutoTrackR2; @@ -37,18 +36,6 @@ public partial class ConfigPage : UserControl VideoRecordSlider.Value = ConfigManager.VideoRecord; OfflineModeSlider.Value = ConfigManager.OfflineMode; ThemeSlider.Value = ConfigManager.Theme; - StreamlinkSlider.Value = ConfigManager.StreamlinkEnabled; - StreamlinkDurationSlider.Value = ConfigManager.StreamlinkDuration; - - // Initialize Streamlink slider style - if (StreamlinkSlider.Value == 0) - { - StreamlinkSlider.Style = (Style)Application.Current.FindResource("FalseToggleStyle"); - } - else - { - StreamlinkSlider.Style = (Style)Application.Current.FindResource("ToggleSliderStyle"); - } ApplyToggleModeStyle(OfflineModeSlider.Value, VisorWipeSlider.Value, VideoRecordSlider.Value); @@ -226,6 +213,51 @@ public partial class ConfigPage : UserControl } } + private void VisorWipeSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) + { + Slider slider = (Slider)sender; + + // Build the dynamic file path for the current user + if (string.IsNullOrEmpty(ConfigManager.AHKScriptFolder)) + { + MessageBox.Show("AHK script folder path is not configured.", "Configuration Error", MessageBoxButton.OK, MessageBoxImage.Warning); + return; + } + string filePath = Path.Combine( + ConfigManager.AHKScriptFolder, + "visorwipe.ahk" + ); + + // Get the current value of the slider (0 or 1) + ConfigManager.VisorWipe = (int)slider.Value; + + if (ConfigManager.VisorWipe == 1) + { + // Check if the file exists + if (File.Exists(filePath)) + { + // Apply the enabled style if the file exists + slider.Style = (Style)Application.Current.FindResource("ToggleSliderStyle"); + } + else + { + // File does not exist; revert the toggle to 0 + ConfigManager.VisorWipe = 0; + slider.Value = 0; // Revert the slider value + slider.Style = (Style)Application.Current.FindResource("FalseToggleStyle"); + + // Optionally, display a message to the user + MessageBox.Show($"Visor wipe script not found. Please ensure the file exists at:\n{filePath}", + "File Missing", MessageBoxButton.OK, MessageBoxImage.Warning); + } + } + else + { + // Apply the disabled style + slider.Style = (Style)Application.Current.FindResource("FalseToggleStyle"); + } + } + private void VideoRecordSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) { Slider slider = (Slider)sender; @@ -283,51 +315,6 @@ public partial class ConfigPage : UserControl } } - private void VisorWipeSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) - { - Slider slider = (Slider)sender; - - // Build the dynamic file path for the current user - if (string.IsNullOrEmpty(ConfigManager.AHKScriptFolder)) - { - MessageBox.Show("AHK script folder path is not configured.", "Configuration Error", MessageBoxButton.OK, MessageBoxImage.Warning); - return; - } - string filePath = Path.Combine( - ConfigManager.AHKScriptFolder, - "visorwipe.ahk" - ); - - // Get the current value of the slider (0 or 1) - ConfigManager.VisorWipe = (int)slider.Value; - - if (ConfigManager.VisorWipe == 1) - { - // Check if the file exists - if (File.Exists(filePath)) - { - // Apply the enabled style if the file exists - slider.Style = (Style)Application.Current.FindResource("ToggleSliderStyle"); - } - else - { - // File does not exist; revert the toggle to 0 - ConfigManager.VisorWipe = 0; - slider.Value = 0; // Revert the slider value - slider.Style = (Style)Application.Current.FindResource("FalseToggleStyle"); - - // Optionally, display a message to the user - MessageBox.Show($"Visor wipe script not found. Please ensure the file exists at:\n{filePath}", - "File Missing", MessageBoxButton.OK, MessageBoxImage.Warning); - } - } - else - { - // Apply the disabled style - slider.Style = (Style)Application.Current.FindResource("FalseToggleStyle"); - } - } - private void SaveButton_Click(object sender, RoutedEventArgs e) { ConfigManager.ApiKey = ApiKey.Password; @@ -435,133 +422,6 @@ public partial class ConfigPage : UserControl MessageBox.Show($"API Test Failure. {ex.Message}"); } } - - private void StreamlinkSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) - { - Slider slider = (Slider)sender; - - // Only allow enabling if streamlink is installed - if (slider.Value == 1) - { - if (!StreamlinkHandler.IsStreamlinkInstalled()) - { - MessageBox.Show("Streamlink is not installed. Please install Streamlink to use this feature.", - "Error", MessageBoxButton.OK, MessageBoxImage.Error); - slider.Value = 0; - return; - } - } - - ConfigManager.StreamlinkEnabled = (int)slider.Value; - - // Apply the appropriate style based on the value - if (slider.Value == 0) - { - slider.Style = (Style)Application.Current.FindResource("FalseToggleStyle"); - } - else - { - slider.Style = (Style)Application.Current.FindResource("ToggleSliderStyle"); - } - } - - private void StreamlinkDurationSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) - { - if (StreamlinkDurationText != null) - { - int duration = (int)e.NewValue; - StreamlinkDurationText.Text = $"{duration}s"; - ConfigManager.StreamlinkDuration = duration; - } - } - - private async void TestStreamlinkButton_Click(object sender, RoutedEventArgs e) - { - Debug.WriteLine("TestStreamlinkButton_Click: Starting streamlink test"); - - if (ConfigManager.StreamlinkEnabled != 1) - { - Debug.WriteLine("TestStreamlinkButton_Click: Streamlink is not enabled"); - MessageBox.Show("Streamlink is not enabled. Please enable Streamlink to test.", "Error", MessageBoxButton.OK, MessageBoxImage.Warning); - return; - } - - try - { - Debug.WriteLine("TestStreamlinkButton_Click: Configuring HTTP client"); - // Configure HttpClient with TLS 1.2 - var handler = new HttpClientHandler - { - SslProtocols = System.Security.Authentication.SslProtocols.Tls12 - }; - - using (var client = new HttpClient(handler)) - { - // Set headers - client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", ConfigManager.ApiKey); - client.DefaultRequestHeaders.UserAgent.ParseAdd("AutoTrackR2"); - - // Create JSON body with version - var jsonBody = new { version = "2.10" }; - var content = new StringContent(JsonSerializer.Serialize(jsonBody), Encoding.UTF8, "application/json"); - - // Send POST to test endpoint - string baseUrl = Regex.Replace(ConfigManager.ApiUrl ?? "", @"(https?://[^/]+)/?.*", "$1"); - string endpoint = "test"; - string fullUrl = $"{baseUrl}/{endpoint}"; - Debug.WriteLine($"TestStreamlinkButton_Click: Sending request to {fullUrl}"); - - var response = await client.PostAsync(fullUrl, content); - Debug.WriteLine($"TestStreamlinkButton_Click: Response status code: {response.StatusCode}"); - - if (response.IsSuccessStatusCode) - { - var responseContent = await response.Content.ReadAsStringAsync(); - Debug.WriteLine($"TestStreamlinkButton_Click: Response content: {responseContent}"); - WebHandler.ProcessStreamerResponse(responseContent); - MessageBox.Show("Streamlink Test Success."); - } - else - { - Debug.WriteLine($"TestStreamlinkButton_Click: Error response: {response.StatusCode} - {response.ReasonPhrase}"); - MessageBox.Show($"Error: {response.StatusCode} - {response.ReasonPhrase}"); - } - } - } - catch (Exception ex) - { - Debug.WriteLine($"TestStreamlinkButton_Click: Exception: {ex.Message}"); - MessageBox.Show($"Streamlink Test Failure. {ex.Message}"); - } - } - - private void LogFileOpenButton_Click(object sender, RoutedEventArgs e) - { - if (!string.IsNullOrEmpty(LogFilePath.Text)) - { - string directory = Path.GetDirectoryName(LogFilePath.Text) ?? string.Empty; - if (Directory.Exists(directory)) - { - Process.Start("explorer.exe", directory); - } - else - { - MessageBox.Show("Directory does not exist.", "Error", MessageBoxButton.OK, MessageBoxImage.Error); - } - } - } - - private void VideoPathOpenButton_Click(object sender, RoutedEventArgs e) - { - if (!string.IsNullOrEmpty(VideoPath.Text) && Directory.Exists(VideoPath.Text)) - { - Process.Start("explorer.exe", VideoPath.Text); - } - else - { - MessageBox.Show("Directory does not exist.", "Error", MessageBoxButton.OK, MessageBoxImage.Error); - } - } } public class Theme diff --git a/AutoTrackR2/MainWindow.xaml.cs b/AutoTrackR2/MainWindow.xaml.cs index 2e95f60..15f0722 100644 --- a/AutoTrackR2/MainWindow.xaml.cs +++ b/AutoTrackR2/MainWindow.xaml.cs @@ -196,8 +196,6 @@ namespace AutoTrackR2 public static int VideoRecord { get; set; } public static int OfflineMode { get; set; } public static int Theme { get; set; } - public static int StreamlinkEnabled { get; set; } - public static int StreamlinkDuration { get; set; } = 30; static ConfigManager() { @@ -249,10 +247,6 @@ namespace AutoTrackR2 OfflineMode = int.Parse(line.Substring("OfflineMode=".Length).Trim()); else if (line.StartsWith("Theme=")) Theme = int.Parse(line.Substring("Theme=".Length).Trim()); - else if (line.StartsWith("StreamlinkEnabled=")) - StreamlinkEnabled = int.Parse(line.Substring("StreamlinkEnabled=".Length).Trim()); - else if (line.StartsWith("StreamlinkDuration=")) - StreamlinkDuration = int.Parse(line.Substring("StreamlinkDuration=".Length).Trim()); } } } @@ -284,8 +278,6 @@ namespace AutoTrackR2 writer.WriteLine($"VideoRecord={VideoRecord}"); writer.WriteLine($"OfflineMode={OfflineMode}"); writer.WriteLine($"Theme={Theme}"); - writer.WriteLine($"StreamlinkEnabled={StreamlinkEnabled}"); - writer.WriteLine($"StreamlinkDuration={StreamlinkDuration}"); } } } diff --git a/AutoTrackR2/StreamlinkHandler.cs b/AutoTrackR2/StreamlinkHandler.cs deleted file mode 100644 index f384d61..0000000 --- a/AutoTrackR2/StreamlinkHandler.cs +++ /dev/null @@ -1,88 +0,0 @@ -using System.Diagnostics; -using System.IO; - -namespace AutoTrackR2; - -public class StreamlinkHandler -{ - public StreamlinkHandler() - { - TrackREventDispatcher.StreamlinkRecordEvent += HandleStreamlinkRecord; - } - - public static bool IsStreamlinkInstalled() - { - try - { - var checkInfo = new ProcessStartInfo - { - FileName = "where", - Arguments = "streamlink", - UseShellExecute = false, - RedirectStandardOutput = true, - CreateNoWindow = true - }; - - using (var process = Process.Start(checkInfo)) - { - if (process == null) - { - return false; - } - - string output = process.StandardOutput.ReadToEnd(); - process.WaitForExit(); - - return process.ExitCode == 0 && !string.IsNullOrEmpty(output); - } - } - catch - { - return false; - } - } - - private async void HandleStreamlinkRecord(string streamerHandle) - { - if (ConfigManager.StreamlinkEnabled != 1) - { - return; - } - - try - { - var outputPath = Path.Combine( - ConfigManager.VideoPath ?? Environment.GetFolderPath(Environment.SpecialFolder.MyVideos), - $"kill_{DateTime.Now:yyyyMMdd_HHmmss}.mp4" - ); - - // Calculate the duration for recording (30 seconds before + configured duration after) - var totalDuration = 30 + ConfigManager.StreamlinkDuration; - - var recordInfo = new ProcessStartInfo - { - FileName = "streamlink", - Arguments = $"https://www.twitch.tv/{streamerHandle} best --hls-live-edge 30 --hls-duration {totalDuration} -o {outputPath}", - UseShellExecute = false, - RedirectStandardOutput = true, - CreateNoWindow = true - }; - - using (var process = Process.Start(recordInfo)) - { - if (process == null) - { - return; - } - - // Wait for the recording to complete - await process.WaitForExitAsync(); - } - } - catch (Exception ex) - { - // Log the error but don't crash the application - Debug.WriteLine($"Error recording streamlink clip: {ex.Message}"); - } - } -} \ No newline at end of file diff --git a/AutoTrackR2/TrackREventDispatcher.cs b/AutoTrackR2/TrackREventDispatcher.cs index 36823ac..d5dc3ae 100644 --- a/AutoTrackR2/TrackREventDispatcher.cs +++ b/AutoTrackR2/TrackREventDispatcher.cs @@ -54,11 +54,4 @@ public static class TrackREventDispatcher { JumpDriveStateChangedEvent?.Invoke(data); } - - public static event Action<string>? StreamlinkRecordEvent; - - public static void OnStreamlinkRecordEvent(string streamerHandle) - { - StreamlinkRecordEvent?.Invoke(streamerHandle); - } } \ No newline at end of file diff --git a/AutoTrackR2/WebHandler.cs b/AutoTrackR2/WebHandler.cs index 7015282..e53e809 100644 --- a/AutoTrackR2/WebHandler.cs +++ b/AutoTrackR2/WebHandler.cs @@ -155,12 +155,7 @@ public static class WebHandler Console.WriteLine($"Time (UTC): {DateTimeOffset.UtcNow}"); Console.WriteLine("=== End Debug Info ===\n"); - // Ensure proper URL formatting - string baseUrl = Regex.Replace(ConfigManager.ApiUrl ?? "", @"(https?://[^/]+)/?.*", "$1"); - string endpoint = "register-kill"; - string fullUrl = $"{baseUrl}/{endpoint}"; - - var response = await httpClient.PostAsync(fullUrl, new StringContent(jsonData, Encoding.UTF8, "application/json")); + var response = await httpClient.PostAsync(ConfigManager.ApiUrl + "register-kill", new StringContent(jsonData, Encoding.UTF8, "application/json")); if (response.StatusCode != HttpStatusCode.OK) { Console.WriteLine("Failed to submit kill data:"); @@ -172,50 +167,7 @@ public static class WebHandler else if (response.StatusCode == HttpStatusCode.OK) { Console.WriteLine("Successfully submitted kill data"); - var responseContent = await response.Content.ReadAsStringAsync(); - Console.WriteLine($"Response: {responseContent}"); - - // Only process streamer data if streamlink is enabled - if (ConfigManager.StreamlinkEnabled == 1) - { - ProcessStreamerResponse(responseContent); - } + Console.WriteLine($"Response: {await response.Content.ReadAsStringAsync()}"); } } - - public static void ProcessStreamerResponse(string responseContent) - { - try - { - var responseData = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(responseContent); - if (responseData != null && responseData.TryGetValue("streamer", out JsonElement streamerElement)) - { - string streamerHandle = streamerElement.GetString() ?? string.Empty; - if (!string.IsNullOrEmpty(streamerHandle)) - { - // Sanitize the streamer handle before using it, this is to prevent any malicious instructions. - string sanitizedHandle = SanitizeStreamerHandle(streamerHandle); - if (!string.IsNullOrEmpty(sanitizedHandle)) - { - TrackREventDispatcher.OnStreamlinkRecordEvent(sanitizedHandle); - } - } - } - } - catch (Exception ex) - { - Console.WriteLine($"Error parsing streamer from response: {ex.Message}"); - } - } - - private static string SanitizeStreamerHandle(string handle) - { - // Twitch usernames 4-25 characters, letters, numbers and underscores. - if (Regex.IsMatch(handle, @"^[a-zA-Z0-9_]{4,25}$")) - { - return handle.ToLower(); // Api won't return anything other than lowercase but just in case. - } - - return string.Empty; // Reject invalid handles - } } \ No newline at end of file diff --git a/AutoTrackR2/config.ini b/AutoTrackR2/config.ini index b661bb4..0f01f82 100644 --- a/AutoTrackR2/config.ini +++ b/AutoTrackR2/config.ini @@ -6,4 +6,3 @@ VisorWipe=0 VideoRecord=0 OfflineMode=0 Theme=0 -StreamlinkEnabled=0