diff --git a/AutoTrackR2/App.xaml b/AutoTrackR2/App.xaml index b2f9f06..0717447 100644 --- a/AutoTrackR2/App.xaml +++ b/AutoTrackR2/App.xaml @@ -571,5 +571,55 @@ </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/ConfigPage.xaml b/AutoTrackR2/ConfigPage.xaml index 70567a9..b164f23 100644 --- a/AutoTrackR2/ConfigPage.xaml +++ b/AutoTrackR2/ConfigPage.xaml @@ -139,11 +139,15 @@ <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <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" + Orientation="Horizontal" Margin="0,0,5,5"> <TextBlock Text="ⓘ" ToolTip="Perform a Visor Wipe animation on player kill. Requires AHKv2." @@ -167,11 +171,11 @@ </StackPanel> <!-- Video Record Toggle --> - <StackPanel Grid.Column="1" Grid.Row="0" + <StackPanel Grid.Column="0" Grid.Row="1" Orientation="Horizontal" - Margin="5,0,0,5"> + Margin="0,0,5,5"> <TextBlock Text="ⓘ" - ToolTip="Automatically clip your last kill. Check the README for more info." + ToolTip="Record video on player kill. Requires AHKv2." Foreground="{DynamicResource TextBrush}" FontSize="20" Margin="0,4,3,0"/> @@ -192,7 +196,7 @@ </StackPanel> <!-- Offline Mode Toggle --> - <StackPanel Grid.Column="0" Grid.Row="1" + <StackPanel Grid.Column="0" Grid.Row="2" Orientation="Horizontal" Margin="0,0,5,5"> <TextBlock Text="ⓘ" @@ -216,11 +220,78 @@ 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="300" + TickFrequency="10" + 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="2" + <StackPanel Grid.Column="0" Grid.Row="4" Grid.ColumnSpan="2" Orientation="Horizontal" - Margin="0,0,0,5"> + Margin="0,10,0,5"> <TextBlock Text="Theme:" Foreground="{DynamicResource TextBrush}" FontSize="16" diff --git a/AutoTrackR2/ConfigPage.xaml.cs b/AutoTrackR2/ConfigPage.xaml.cs index 1136f55..569041d 100644 --- a/AutoTrackR2/ConfigPage.xaml.cs +++ b/AutoTrackR2/ConfigPage.xaml.cs @@ -11,6 +11,7 @@ using System.Windows.Media; using System.Windows.Media.Effects; using System.Windows.Threading; using Microsoft.Win32; +using System.Threading.Tasks; namespace AutoTrackR2; @@ -37,6 +38,9 @@ public partial class ConfigPage : UserControl OfflineModeSlider.Value = ConfigManager.OfflineMode; ThemeSlider.Value = ConfigManager.Theme; + // Initialize Streamlink slider style + StreamlinkSlider.Style = (Style)Application.Current.FindResource("FalseToggleStyle"); + ApplyToggleModeStyle(OfflineModeSlider.Value, VisorWipeSlider.Value, VideoRecordSlider.Value); const string themeJsonPath = "themes.json"; @@ -213,51 +217,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 VideoRecordSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) { Slider slider = (Slider)sender; @@ -315,6 +274,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 SaveButton_Click(object sender, RoutedEventArgs e) { ConfigManager.ApiKey = ApiKey.Password; @@ -422,6 +426,115 @@ 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; + 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) + { + try + { + // Get the duration from the slider + int duration = (int)StreamlinkDurationSlider.Value; + + // Check if streamlink is installed + var versionInfo = new ProcessStartInfo + { + FileName = "streamlink", + Arguments = "--version", + UseShellExecute = false, + RedirectStandardOutput = true, + CreateNoWindow = true + }; + + using (var process = Process.Start(versionInfo)) + { + if (process == null) + { + MessageBox.Show("Streamlink is not installed. Please install Streamlink to use this feature.", + "Error", MessageBoxButton.OK, MessageBoxImage.Error); + return; + } + + string output = process.StandardOutput.ReadToEnd(); + process.WaitForExit(); + + if (process.ExitCode != 0) + { + MessageBox.Show("Streamlink is not installed or not working correctly. Please install Streamlink to use this feature.", + "Error", MessageBoxButton.OK, MessageBoxImage.Error); + return; + } + } + + // Test recording functionality + var testUrl = "https://www.twitch.tv/starcitizen"; // Example URL for testing + var outputPath = Path.Combine( + ConfigManager.VideoPath ?? Environment.GetFolderPath(Environment.SpecialFolder.MyVideos), + "streamlink_test.mp4" + ); + + var recordInfo = new ProcessStartInfo + { + FileName = "streamlink", + Arguments = $"{testUrl} best -o {outputPath}", + UseShellExecute = false, + RedirectStandardOutput = true, + CreateNoWindow = true + }; + + using (var process = Process.Start(recordInfo)) + { + if (process == null) + { + MessageBox.Show("Failed to start test recording.", "Error", MessageBoxButton.OK, MessageBoxImage.Error); + return; + } + + // Wait for a short duration (5 seconds) to test recording + await Task.Delay(5000); + + try + { + if (!process.HasExited) + { + process.Kill(); + } + } + catch { } + } + + MessageBox.Show($"Streamlink test recording completed successfully.\nA 5-second test recording was saved to:\n{outputPath}", + "Success", MessageBoxButton.OK, MessageBoxImage.Information); + } + catch (Exception ex) + { + MessageBox.Show($"Error testing Streamlink: {ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error); + } + } } public class Theme diff --git a/AutoTrackR2/MainWindow.xaml.cs b/AutoTrackR2/MainWindow.xaml.cs index 15f0722..2e95f60 100644 --- a/AutoTrackR2/MainWindow.xaml.cs +++ b/AutoTrackR2/MainWindow.xaml.cs @@ -196,6 +196,8 @@ 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() { @@ -247,6 +249,10 @@ 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()); } } } @@ -278,6 +284,8 @@ 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/WebHandler.cs b/AutoTrackR2/WebHandler.cs index e53e809..fd2b646 100644 --- a/AutoTrackR2/WebHandler.cs +++ b/AutoTrackR2/WebHandler.cs @@ -155,7 +155,12 @@ public static class WebHandler Console.WriteLine($"Time (UTC): {DateTimeOffset.UtcNow}"); Console.WriteLine("=== End Debug Info ===\n"); - var response = await httpClient.PostAsync(ConfigManager.ApiUrl + "register-kill", new StringContent(jsonData, Encoding.UTF8, "application/json")); + // 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")); if (response.StatusCode != HttpStatusCode.OK) { Console.WriteLine("Failed to submit kill data:"); diff --git a/AutoTrackR2/config.ini b/AutoTrackR2/config.ini index 0f01f82..b661bb4 100644 --- a/AutoTrackR2/config.ini +++ b/AutoTrackR2/config.ini @@ -6,3 +6,4 @@ VisorWipe=0 VideoRecord=0 OfflineMode=0 Theme=0 +StreamlinkEnabled=0