From d7057efe1561dd016c5ddb0c9db7557a17200f2c Mon Sep 17 00:00:00 2001
From: Heavy Bob <ferrettclay@gmail.com>
Date: Thu, 10 Apr 2025 01:55:35 +1000
Subject: [PATCH] Streamlink - Almost done.

---
 AutoTrackR2/App.xaml.cs              |   2 +
 AutoTrackR2/ConfigPage.xaml          | 407 ++++++++++++++-------------
 AutoTrackR2/ConfigPage.xaml.cs       | 124 ++++----
 AutoTrackR2/StreamlinkHandler.cs     |  88 ++++++
 AutoTrackR2/TrackREventDispatcher.cs |   7 +
 AutoTrackR2/WebHandler.cs            |  21 +-
 6 files changed, 385 insertions(+), 264 deletions(-)
 create mode 100644 AutoTrackR2/StreamlinkHandler.cs

diff --git a/AutoTrackR2/App.xaml.cs b/AutoTrackR2/App.xaml.cs
index e84d792..e9a45e7 100644
--- a/AutoTrackR2/App.xaml.cs
+++ b/AutoTrackR2/App.xaml.cs
@@ -19,6 +19,7 @@ namespace AutoTrackR2
             "AutoTrackR2",
             "crash.log"
         );
+        private StreamlinkHandler? _streamlinkHandler;
 
         protected override void OnStartup(StartupEventArgs e)
         {
@@ -43,6 +44,7 @@ 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 b164f23..2ecc235 100644
--- a/AutoTrackR2/ConfigPage.xaml
+++ b/AutoTrackR2/ConfigPage.xaml
@@ -2,14 +2,13 @@
              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
              Height="410"
-             Width="626">
+             Width="700">
 
 
         <Grid Background="{DynamicResource BackgroundLightBrush}">
                 <!-- Main Layout Grid -->
-                <Grid Margin="0,0,5,7">
+                <Grid>
                         <Grid.RowDefinitions>
-                                <!-- One row for the content, the other for buttons -->
                                 <RowDefinition Height="*"/>
                                 <RowDefinition Height="Auto"/>
                         </Grid.RowDefinitions>
@@ -22,9 +21,9 @@
                         </Grid.ColumnDefinitions>
 
                         <!-- Section for Config Fields -->
-                        <StackPanel Grid.Column="0"
-                                    VerticalAlignment="Center"
-                                    Height="389">
+                        <StackPanel Grid.Row="0"
+                                    VerticalAlignment="Top"
+                                    Margin="20,10,20,0">
                                 <!-- Log File -->
                                 <StackPanel Margin="0,5,0,10"
                                             Orientation="Horizontal">
@@ -38,11 +37,11 @@
                                                    FontSize="16"
                                                    Margin="0,5,0,5"
                                                    FontFamily="{StaticResource Roboto}"/>
-                                        <StackPanel Orientation="Horizontal"
-                                                    Margin="30,0,0,0">
+                                        <StackPanel Orientation="Horizontal">
                                                 <TextBox Name="LogFilePath"
-                                                         Width="330"
+                                                         Width="260"
                                                          Height="30"
+                                                         Margin="10,0,0,0"
                                                          Style="{StaticResource RoundedTextBox}"/>
                                                 <Button Content="Browse"
                                                         Width="75"
@@ -51,6 +50,13 @@
                                                         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>
 
@@ -66,11 +72,11 @@
                                                    Foreground="{DynamicResource TextBrush}"
                                                    FontSize="16"
                                                    Margin="0,5,0,5"/>
-                                        <StackPanel Orientation="Horizontal"
-                                                    Margin="30,0,0,0">
+                                        <StackPanel Orientation="Horizontal">
                                                 <TextBox Name="ApiUrl"
-                                                         Width="330"
+                                                         Width="260"
                                                          Height="30"
+                                                         Margin="10,0,0,0"
                                                          Style="{StaticResource RoundedTextBox}"/>
                                                 <Button Content="Test"
                                                         Width="75"
@@ -95,9 +101,9 @@
                                                    FontSize="16"
                                                    Margin="0,5,0,5"/>
                                         <PasswordBox Name="ApiKey"
-                                                     Width="330"
+                                                     Width="260"
                                                      Height="30"
-                                                     Margin="33,0,0,0"
+                                                     Margin="10,0,0,0"
                                                      Style="{StaticResource RoundedPasswordBox}"/>
                                 </StackPanel>
 
@@ -115,7 +121,7 @@
                                                    Margin="0,5,0,5"/>
                                         <StackPanel Orientation="Horizontal">
                                                 <TextBox Name="VideoPath"
-                                                         Width="330"
+                                                         Width="260"
                                                          Height="30"
                                                          Margin="10,0,0,0"
                                                          Style="{StaticResource RoundedTextBox}"/>
@@ -126,201 +132,214 @@
                                                         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"/>
+                                                <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>
+                                        <!-- Left Column Controls -->
 
-                                    <!-- 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>
+                                        <!-- 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>
 
-                                    <!-- 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>
+                                        <!-- 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>
 
-                                    <!-- 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>
+                                        <!-- 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>
 
-                                    <!-- 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>
+                                        <!-- Right Column Controls -->
 
-                                    <!-- 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"/>
+                                        <!-- 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>
 
-                                    <!-- Theme Slider -->
-                                    <StackPanel Grid.Column="0" Grid.Row="4"
-                                              Grid.ColumnSpan="2"
-                                              Orientation="Horizontal"
-                                              Margin="0,10,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>
+                                        <!-- 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>
                                 </Grid>
                         </StackPanel>
 
                         <!-- Save Button -->
-                        <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>
+                        <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"/>
                 </Grid>
         </Grid>
 </UserControl>
diff --git a/AutoTrackR2/ConfigPage.xaml.cs b/AutoTrackR2/ConfigPage.xaml.cs
index 569041d..284f835 100644
--- a/AutoTrackR2/ConfigPage.xaml.cs
+++ b/AutoTrackR2/ConfigPage.xaml.cs
@@ -37,9 +37,18 @@ 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
-        StreamlinkSlider.Style = (Style)Application.Current.FindResource("FalseToggleStyle");
+        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);
 
@@ -430,6 +439,19 @@ public partial class ConfigPage : UserControl
     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
@@ -459,82 +481,46 @@ public partial class ConfigPage : UserControl
         {
             // 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;
-                }
+            // Calculate the total duration (30 seconds before + configured duration)
+            int totalDuration = 30 + duration;
 
-                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);
+            // Test recording functionality, we're using spacecutlet cause need a good tester.
+            TrackREventDispatcher.OnStreamlinkRecordEvent("spacecutlet");
         }
         catch (Exception ex)
         {
             MessageBox.Show($"Error testing Streamlink: {ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
         }
     }
+
+    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/StreamlinkHandler.cs b/AutoTrackR2/StreamlinkHandler.cs
new file mode 100644
index 0000000..f384d61
--- /dev/null
+++ b/AutoTrackR2/StreamlinkHandler.cs
@@ -0,0 +1,88 @@
+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 d5dc3ae..36823ac 100644
--- a/AutoTrackR2/TrackREventDispatcher.cs
+++ b/AutoTrackR2/TrackREventDispatcher.cs
@@ -54,4 +54,11 @@ 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 fd2b646..c18d440 100644
--- a/AutoTrackR2/WebHandler.cs
+++ b/AutoTrackR2/WebHandler.cs
@@ -172,7 +172,26 @@ public static class WebHandler
         else if (response.StatusCode == HttpStatusCode.OK)
         {
             Console.WriteLine("Successfully submitted kill data");
-            Console.WriteLine($"Response: {await response.Content.ReadAsStringAsync()}");
+            var responseContent = await response.Content.ReadAsStringAsync();
+            Console.WriteLine($"Response: {responseContent}");
+
+            // Check if the response contains a streamer field
+            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))
+                    {
+                        TrackREventDispatcher.OnStreamlinkRecordEvent(streamerHandle);
+                    }
+                }
+            }
+            catch (Exception ex)
+            {
+                Console.WriteLine($"Error parsing streamer from response: {ex.Message}");
+            }
         }
     }
 }
\ No newline at end of file