diff --git a/AutoTrackR2/App.xaml b/AutoTrackR2/App.xaml
index 3f3362f..b2f9f06 100644
--- a/AutoTrackR2/App.xaml
+++ b/AutoTrackR2/App.xaml
@@ -15,20 +15,30 @@
         <Color x:Key="TextColor">#FFFFFF</Color>
         <Color x:Key="AltTextColor">#A88F2C</Color>
 
-        <SolidColorBrush x:Key="TextBrush" Color="{DynamicResource TextColor}" />
-        <SolidColorBrush x:Key="AccentBrush" Color="{DynamicResource AccentColor}" />
-        <SolidColorBrush x:Key="BackgroundDarkBrush" Color="{DynamicResource BackgroundDarkColor}" />
-        <SolidColorBrush x:Key="BackgroundLightBrush" Color="{DynamicResource BackgroundLightColor}" />
-        <SolidColorBrush x:Key="AltTextBrush" Color="{DynamicResource AltTextColor}" />
+        <SolidColorBrush x:Key="TextBrush"
+                Color="{DynamicResource TextColor}"/>
+        <SolidColorBrush x:Key="AccentBrush"
+                Color="{DynamicResource AccentColor}"/>
+        <SolidColorBrush x:Key="BackgroundDarkBrush"
+                Color="{DynamicResource BackgroundDarkColor}"/>
+        <SolidColorBrush x:Key="BackgroundLightBrush"
+                Color="{DynamicResource BackgroundLightColor}"/>
+        <SolidColorBrush x:Key="AltTextBrush"
+                Color="{DynamicResource AltTextColor}"/>
 
         <!-- Define the Style for Window -->
-        <Style TargetType="Window" x:Key="CustomWindowStyle">
+        <Style TargetType="Window"
+                x:Key="CustomWindowStyle">
             <Setter Property="Template">
                 <Setter.Value>
                     <ControlTemplate TargetType="Window">
-                        <Border BorderBrush="{DynamicResource AccentBrush}" BorderThickness="2" CornerRadius="10" Background="{DynamicResource BackgroundLightBrush}">
+                        <Border BorderBrush="{DynamicResource AccentBrush}"
+                                BorderThickness="2"
+                                CornerRadius="10"
+                                Background="{DynamicResource BackgroundLightBrush}">
                             <Grid>
-                                <ContentPresenter HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
+                                <ContentPresenter HorizontalAlignment="Stretch"
+                                        VerticalAlignment="Stretch"/>
                             </Grid>
                         </Border>
                     </ControlTemplate>
@@ -37,62 +47,99 @@
         </Style>
 
         <!-- Tab Button Style -->
-        <Style x:Key="TabButtonStyle" TargetType="Button">
-            <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="Cursor" Value="Hand"/>
-            <Setter Property="Padding" Value="10"/>
-            <Setter Property="Margin" Value="5"/>
-            <Setter Property="FontFamily" Value="{StaticResource Orbitron}"/>
+        <Style x:Key="TabButtonStyle"
+                TargetType="Button">
+            <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="Cursor"
+                    Value="Hand"/>
+            <Setter Property="Padding"
+                    Value="10"/>
+            <Setter Property="Margin"
+                    Value="5"/>
+            <Setter Property="FontFamily"
+                    Value="{StaticResource Orbitron}"/>
             <Setter Property="Template">
                 <Setter.Value>
                     <ControlTemplate TargetType="Button">
-                        <Border Background="{DynamicResource BackgroundDarkBrush}" BorderBrush="{DynamicResource AccentBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="5">
+                        <Border Background="{DynamicResource BackgroundDarkBrush}"
+                                BorderBrush="{DynamicResource AccentBrush}"
+                                BorderThickness="{TemplateBinding BorderThickness}"
+                                CornerRadius="5">
                             <!-- ContentPresenter will automatically inherit Foreground from Button -->
-                            <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
+                            <ContentPresenter HorizontalAlignment="Center"
+                                    VerticalAlignment="Center"/>
                         </Border>
                     </ControlTemplate>
                 </Setter.Value>
             </Setter>
-            
+
         </Style>
 
 
         <!-- General Button Style -->
-        <Style x:Key="DisabledButtonStyle" TargetType="Button">
-            <Setter Property="Foreground" Value="Gray"/>
-            <Setter Property="Background" Value="{DynamicResource BackgroundDarkBrush}"/>
-            <Setter Property="BorderBrush" Value="Gray"/>
-            <Setter Property="BorderThickness" Value="2"/>
-            <Setter Property="FontWeight" Value="Bold"/>
-            <Setter Property="Cursor" Value="Hand"/>
-            <Setter Property="Padding" Value="5"/>
+        <Style x:Key="DisabledButtonStyle"
+                TargetType="Button">
+            <Setter Property="Foreground"
+                    Value="Gray"/>
+            <Setter Property="Background"
+                    Value="{DynamicResource BackgroundDarkBrush}"/>
+            <Setter Property="BorderBrush"
+                    Value="Gray"/>
+            <Setter Property="BorderThickness"
+                    Value="2"/>
+            <Setter Property="FontWeight"
+                    Value="Bold"/>
+            <Setter Property="Cursor"
+                    Value="Hand"/>
+            <Setter Property="Padding"
+                    Value="5"/>
             <Setter Property="Template">
                 <Setter.Value>
                     <ControlTemplate TargetType="Button">
-                        <Border Background="{DynamicResource BackgroundDarkBrush}" BorderBrush="{DynamicResource AccentBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="5">
-                            <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
+                        <Border Background="{DynamicResource BackgroundDarkBrush}"
+                                BorderBrush="{DynamicResource AccentBrush}"
+                                BorderThickness="{TemplateBinding BorderThickness}"
+                                CornerRadius="5">
+                            <ContentPresenter HorizontalAlignment="Center"
+                                    VerticalAlignment="Center"/>
                         </Border>
                     </ControlTemplate>
                 </Setter.Value>
             </Setter>
         </Style>
 
-        <Style x:Key="ButtonStyle" TargetType="Button">
-            <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="FontWeight" Value="Bold"/>
-            <Setter Property="Cursor" Value="Hand"/>
-            <Setter Property="Padding" Value="5"/>
+        <Style x:Key="ButtonStyle"
+                TargetType="Button">
+            <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="FontWeight"
+                    Value="Bold"/>
+            <Setter Property="Cursor"
+                    Value="Hand"/>
+            <Setter Property="Padding"
+                    Value="5"/>
             <Setter Property="Template">
                 <Setter.Value>
                     <ControlTemplate TargetType="Button">
-                        <Border Background="{DynamicResource BackgroundDarkBrush}" BorderBrush="{DynamicResource AccentBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="5">
-                            <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
+                        <Border Background="{DynamicResource BackgroundDarkBrush}"
+                                BorderBrush="{DynamicResource AccentBrush}"
+                                BorderThickness="{TemplateBinding BorderThickness}"
+                                CornerRadius="5">
+                            <ContentPresenter HorizontalAlignment="Center"
+                                    VerticalAlignment="Center"/>
                         </Border>
                     </ControlTemplate>
                 </Setter.Value>
@@ -100,69 +147,141 @@
         </Style>
 
         <!-- Title Bar Button Style -->
-        <Style x:Key="TitleButtonStyle" TargetType="Button">
-            <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="FontWeight" Value="Bold"/>
-            <Setter Property="Cursor" Value="Hand"/>
+        <Style x:Key="TitleButtonStyle"
+                TargetType="Button">
+            <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="FontWeight"
+                    Value="Bold"/>
+            <Setter Property="Cursor"
+                    Value="Hand"/>
             <Setter Property="Template">
                 <Setter.Value>
                     <ControlTemplate TargetType="Button">
-                        <Border Background="{DynamicResource BackgroundDarkBrush}" 
-                        BorderBrush="{DynamicResource AccentBrush}" 
-                        BorderThickness="2" 
-                        CornerRadius="5" 
-                        Margin="0,1,4,1">
-                            <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
+                        <Border Background="{DynamicResource BackgroundDarkBrush}"
+                                BorderBrush="{DynamicResource AccentBrush}"
+                                BorderThickness="2"
+                                CornerRadius="5"
+                                Margin="0,1,4,1">
+                            <ContentPresenter HorizontalAlignment="Center"
+                                    VerticalAlignment="Center"/>
                         </Border>
                     </ControlTemplate>
                 </Setter.Value>
             </Setter>
         </Style>
-        
+
         <!-- Custom style for text blocks -->
-        <Style x:Key="RoundedTextBlock" TargetType="TextBlock">
-            <Setter Property="Foreground" Value="{DynamicResource TextBrush}" />
-            <Setter Property="FontFamily" Value="{StaticResource Roboto}" />
-            <Setter Property="Background" Value="Transparent" />
-            <Setter Property="FontSize" Value="14" />
-            <Setter Property="Padding" Value="10,0,10,0" />
-            <Setter Property="VerticalAlignment" Value="Center" />
-            <Setter Property="HorizontalAlignment" Value="Stretch" />
+        <Style x:Key="RoundedTextBlock"
+                TargetType="TextBlock">
+            <Setter Property="Foreground"
+                    Value="{DynamicResource TextBrush}"/>
+            <Setter Property="FontFamily"
+                    Value="{StaticResource Roboto}"/>
+            <Setter Property="Background"
+                    Value="Transparent"/>
+            <Setter Property="FontSize"
+                    Value="14"/>
+            <Setter Property="Padding"
+                    Value="10,0,10,0"/>
+            <Setter Property="VerticalAlignment"
+                    Value="Center"/>
+            <Setter Property="HorizontalAlignment"
+                    Value="Stretch"/>
         </Style>
 
         <!-- Wrap TextBlock in Border to apply rounded corners -->
-        <Style x:Key="RoundedTextBlockWithBorder" TargetType="Border">
-            <Setter Property="Background" Value="{DynamicResource BackgroundLightBrush}"/>
-            <Setter Property="BorderBrush" Value="{DynamicResource AccentBrush}"/>
-            <Setter Property="BorderThickness" Value="2"/>
-            <Setter Property="CornerRadius" Value="5"/>
-            <Setter Property="Padding" Value="0"/>
-            <Setter Property="Margin" Value="0,10,0,0"/>
+        <Style x:Key="RoundedTextBlockWithBorder"
+                TargetType="Border">
+            <Setter Property="Background"
+                    Value="{DynamicResource BackgroundLightBrush}"/>
+            <Setter Property="BorderBrush"
+                    Value="{DynamicResource AccentBrush}"/>
+            <Setter Property="BorderThickness"
+                    Value="2"/>
+            <Setter Property="CornerRadius"
+                    Value="5"/>
+            <Setter Property="Padding"
+                    Value="0"/>
+            <Setter Property="Margin"
+                    Value="0,10,0,0"/>
         </Style>
 
         <!-- Custom Style for Rounded TextBox -->
-        <Style x:Key="RoundedTextBox" TargetType="TextBox">
-            <Setter Property="Foreground" Value="{DynamicResource TextBrush}"/>
-            <Setter Property="Background" Value="{DynamicResource BackgroundDarkBrush}"/>
-            <Setter Property="BorderBrush" Value="{DynamicResource AccentBrush}"/>
-            <Setter Property="FontFamily" Value="{StaticResource Roboto}"/>
-            <Setter Property="Height" Value="30"/>
-            <Setter Property="Padding" Value="5"/>
-            <Setter Property="VerticalContentAlignment" Value="Center"/>
-            <Setter Property="HorizontalAlignment" Value="Stretch"/>
-            <Setter Property="BorderBrush" Value="{DynamicResource AccentBrush}"/>
-            <Setter Property="BorderThickness" Value="2"/>
+        <Style x:Key="RoundedTextBox"
+                TargetType="TextBox">
+            <Setter Property="Foreground"
+                    Value="{DynamicResource TextBrush}"/>
+            <Setter Property="Background"
+                    Value="{DynamicResource BackgroundDarkBrush}"/>
+            <Setter Property="BorderBrush"
+                    Value="{DynamicResource AccentBrush}"/>
+            <Setter Property="FontFamily"
+                    Value="{StaticResource Roboto}"/>
+            <Setter Property="Height"
+                    Value="30"/>
+            <Setter Property="Padding"
+                    Value="5"/>
+            <Setter Property="VerticalContentAlignment"
+                    Value="Center"/>
+            <Setter Property="HorizontalAlignment"
+                    Value="Stretch"/>
+            <Setter Property="BorderBrush"
+                    Value="{DynamicResource AccentBrush}"/>
+            <Setter Property="BorderThickness"
+                    Value="2"/>
             <!-- The actual border with rounded corners -->
             <Setter Property="Template">
                 <Setter.Value>
                     <ControlTemplate TargetType="TextBox">
                         <Border Background="{DynamicResource BackgroundDarkBrush}"
-                        BorderBrush="{DynamicResource AccentBrush}"
-                        BorderThickness="{TemplateBinding BorderThickness}"
-                        CornerRadius="5">
+                                BorderBrush="{DynamicResource AccentBrush}"
+                                BorderThickness="{TemplateBinding BorderThickness}"
+                                CornerRadius="5">
+                            <ScrollViewer x:Name="PART_ContentHost"/>
+                        </Border>
+                    </ControlTemplate>
+                </Setter.Value>
+            </Setter>
+        </Style>
+
+        <!-- Custom Style for Rounded PasswordBox -->
+        <Style x:Key="RoundedPasswordBox"
+                TargetType="PasswordBox">
+            <Setter Property="Foreground"
+                    Value="{DynamicResource TextBrush}"/>
+            <Setter Property="Background"
+                    Value="{DynamicResource BackgroundDarkBrush}"/>
+            <Setter Property="BorderBrush"
+                    Value="{DynamicResource AccentBrush}"/>
+            <Setter Property="FontFamily"
+                    Value="{StaticResource Roboto}"/>
+            <Setter Property="Height"
+                    Value="30"/>
+            <Setter Property="Padding"
+                    Value="5"/>
+            <Setter Property="VerticalContentAlignment"
+                    Value="Center"/>
+            <Setter Property="HorizontalAlignment"
+                    Value="Stretch"/>
+            <Setter Property="BorderBrush"
+                    Value="{DynamicResource AccentBrush}"/>
+            <Setter Property="BorderThickness"
+                    Value="2"/>
+            <!-- The actual border with rounded corners -->
+            <Setter Property="Template">
+                <Setter.Value>
+                    <ControlTemplate TargetType="PasswordBox">
+                        <Border Background="{DynamicResource BackgroundDarkBrush}"
+                                BorderBrush="{DynamicResource AccentBrush}"
+                                BorderThickness="{TemplateBinding BorderThickness}"
+                                CornerRadius="5">
                             <ScrollViewer x:Name="PART_ContentHost"/>
                         </Border>
                     </ControlTemplate>
@@ -171,39 +290,57 @@
         </Style>
 
         <!-- Custom Style for Slider -->
-        <Style x:Key="ThreePositionSlider" 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" />
+        <Style x:Key="ThreePositionSlider"
+                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="200" Height="30" HorizontalAlignment="Left" Margin="58,-6,0,0">
+                        <Grid Width="200"
+                                Height="30"
+                                HorizontalAlignment="Left"
+                                Margin="58,-6,0,0">
                             <!-- Track Background -->
-                            <Border Background="{DynamicResource BackgroundDarkBrush}" BorderBrush="{DynamicResource AccentBrush}" BorderThickness="2" CornerRadius="15" Margin="0,0,-5,-4" />
+                            <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">
+                                           Width="22"
+                                           Height="22"
+                                           Margin="6,4,1,0">
                                         <Thumb.Template>
                                             <ControlTemplate TargetType="Thumb">
-                                                <Ellipse Fill="{DynamicResource AccentBrush}" />
+                                                <Ellipse Fill="{DynamicResource AccentBrush}"/>
                                             </ControlTemplate>
                                         </Thumb.Template>
                                     </Thumb>
                                 </Track.Thumb>
                                 <Track.DecreaseRepeatButton>
-                                    <RepeatButton Background="Transparent" BorderBrush="Transparent" IsHitTestVisible="False"/>
+                                    <RepeatButton Background="Transparent"
+                                            BorderBrush="Transparent"
+                                            IsHitTestVisible="False"/>
                                 </Track.DecreaseRepeatButton>
                                 <Track.IncreaseRepeatButton>
-                                    <RepeatButton Background="Transparent" BorderBrush="Transparent" IsHitTestVisible="False"/>
+                                    <RepeatButton Background="Transparent"
+                                            BorderBrush="Transparent"
+                                            IsHitTestVisible="False"/>
                                 </Track.IncreaseRepeatButton>
                             </Track>
                         </Grid>
@@ -213,39 +350,56 @@
         </Style>
 
         <!-- Toggle Slider Style -->
-        <Style x:Key="ToggleSliderStyle" 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" />
+        <Style x:Key="ToggleSliderStyle"
+                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="50" Height="30" HorizontalAlignment="Left" >
+                        <Grid Width="50"
+                                Height="30"
+                                HorizontalAlignment="Left">
                             <!-- Track Background -->
-                            <Border Background="{DynamicResource BackgroundDarkBrush}" BorderBrush="{DynamicResource AccentBrush}" BorderThickness="2" CornerRadius="15" Margin="0,0,-5,-4" />
+                            <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">
+                                           Width="22"
+                                           Height="22"
+                                           Margin="6,4,1,0">
                                         <Thumb.Template>
                                             <ControlTemplate TargetType="Thumb">
-                                                <Ellipse Fill="{DynamicResource AccentBrush}" />
+                                                <Ellipse Fill="{DynamicResource AccentBrush}"/>
                                             </ControlTemplate>
                                         </Thumb.Template>
                                     </Thumb>
                                 </Track.Thumb>
                                 <Track.DecreaseRepeatButton>
-                                    <RepeatButton Background="Transparent" BorderBrush="Transparent" IsHitTestVisible="False"/>
+                                    <RepeatButton Background="Transparent"
+                                            BorderBrush="Transparent"
+                                            IsHitTestVisible="False"/>
                                 </Track.DecreaseRepeatButton>
                                 <Track.IncreaseRepeatButton>
-                                    <RepeatButton Background="Transparent" BorderBrush="Transparent" IsHitTestVisible="False"/>
+                                    <RepeatButton Background="Transparent"
+                                            BorderBrush="Transparent"
+                                            IsHitTestVisible="False"/>
                                 </Track.IncreaseRepeatButton>
                             </Track>
                         </Grid>
@@ -255,39 +409,56 @@
         </Style>
 
         <!-- False toggle theme -->
-        <Style x:Key="FalseToggleStyle" 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="Gray" />
-            <Setter Property="BorderThickness" Value="2" />
+        <Style x:Key="FalseToggleStyle"
+                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="Gray"/>
+            <Setter Property="BorderThickness"
+                    Value="2"/>
             <Setter Property="Template">
                 <Setter.Value>
                     <ControlTemplate TargetType="Slider">
-                        <Grid Width="50" Height="30" HorizontalAlignment="Left" >
+                        <Grid Width="50"
+                                Height="30"
+                                HorizontalAlignment="Left">
                             <!-- Track Background -->
-                            <Border Background="{DynamicResource BackgroundDarkBrush}" BorderBrush="{DynamicResource AccentBrush}" BorderThickness="2" CornerRadius="15" Margin="0,0,-5,-4" />
+                            <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">
+                                           Width="22"
+                                           Height="22"
+                                           Margin="6,4,1,0">
                                         <Thumb.Template>
                                             <ControlTemplate TargetType="Thumb">
-                                                <Ellipse Fill="Gray" />
+                                                <Ellipse Fill="Gray"/>
                                             </ControlTemplate>
                                         </Thumb.Template>
                                     </Thumb>
                                 </Track.Thumb>
                                 <Track.DecreaseRepeatButton>
-                                    <RepeatButton Background="Transparent" BorderBrush="Transparent" IsHitTestVisible="False"/>
+                                    <RepeatButton Background="Transparent"
+                                            BorderBrush="Transparent"
+                                            IsHitTestVisible="False"/>
                                 </Track.DecreaseRepeatButton>
                                 <Track.IncreaseRepeatButton>
-                                    <RepeatButton Background="Transparent" BorderBrush="Transparent" IsHitTestVisible="False"/>
+                                    <RepeatButton Background="Transparent"
+                                            BorderBrush="Transparent"
+                                            IsHitTestVisible="False"/>
                                 </Track.IncreaseRepeatButton>
                             </Track>
                         </Grid>
@@ -298,15 +469,21 @@
 
         <!-- Modern Rounded ScrollBar Style -->
         <Style TargetType="ScrollBar">
-            <Setter Property="Width" Value="6" />
+            <Setter Property="Width"
+                    Value="6"/>
             <Setter Property="Template">
                 <Setter.Value>
                     <ControlTemplate TargetType="ScrollBar">
                         <Grid>
-                            <Track Name="PART_Track" IsDirectionReversed="true" Width="6" Margin="0,0,0,0">
+                            <Track Name="PART_Track"
+                                    IsDirectionReversed="true"
+                                    Width="6"
+                                    Margin="0,0,0,0">
                                 <!-- Decrease Repeat Button -->
                                 <Track.DecreaseRepeatButton>
-                                    <RepeatButton Background="Transparent" BorderBrush="{DynamicResource AccentBrush}" BorderThickness="0">
+                                    <RepeatButton Background="Transparent"
+                                            BorderBrush="{DynamicResource AccentBrush}"
+                                            BorderThickness="0">
                                         <RepeatButton.Template>
                                             <ControlTemplate TargetType="RepeatButton">
                                                 <Grid x:Name="RepeatButtonGrid">
@@ -314,12 +491,18 @@
                                                         <VisualStateGroup Name="CommonStates">
                                                             <VisualState Name="Normal">
                                                                 <Storyboard>
-                                                                    <DoubleAnimation Storyboard.TargetProperty="Opacity" Storyboard.TargetName="RepeatButtonGrid" To="1" Duration="0:0:0"/>
+                                                                    <DoubleAnimation Storyboard.TargetProperty="Opacity"
+                                                                            Storyboard.TargetName="RepeatButtonGrid"
+                                                                            To="1"
+                                                                            Duration="0:0:0"/>
                                                                 </Storyboard>
                                                             </VisualState>
                                                             <VisualState Name="MouseOver">
                                                                 <Storyboard>
-                                                                    <DoubleAnimation Storyboard.TargetProperty="Opacity" Storyboard.TargetName="RepeatButtonGrid" To="0" Duration="0:0:0.1"/>
+                                                                    <DoubleAnimation Storyboard.TargetProperty="Opacity"
+                                                                            Storyboard.TargetName="RepeatButtonGrid"
+                                                                            To="0"
+                                                                            Duration="0:0:0.1"/>
                                                                 </Storyboard>
                                                             </VisualState>
                                                         </VisualStateGroup>
@@ -338,10 +521,10 @@
                                             <ControlTemplate TargetType="Thumb">
                                                 <Grid>
                                                     <Border
-                                                Background="{DynamicResource AccentBrush}"
-                                                BorderBrush="{DynamicResource AccentBrush}"
-                                                BorderThickness="0"
-                                                CornerRadius="3" />
+                                                        Background="{DynamicResource AccentBrush}"
+                                                        BorderBrush="{DynamicResource AccentBrush}"
+                                                        BorderThickness="0"
+                                                        CornerRadius="3"/>
                                                 </Grid>
                                             </ControlTemplate>
                                         </Thumb.Template>
@@ -350,7 +533,9 @@
 
                                 <!-- Increase Repeat Button -->
                                 <Track.IncreaseRepeatButton>
-                                    <RepeatButton Background="Transparent" BorderBrush="{DynamicResource AccentBrush}" BorderThickness="0">
+                                    <RepeatButton Background="Transparent"
+                                            BorderBrush="{DynamicResource AccentBrush}"
+                                            BorderThickness="0">
                                         <RepeatButton.Template>
                                             <ControlTemplate TargetType="RepeatButton">
                                                 <Grid x:Name="RepeatButtonGrid">
@@ -358,12 +543,18 @@
                                                         <VisualStateGroup Name="CommonStates">
                                                             <VisualState Name="Normal">
                                                                 <Storyboard>
-                                                                    <DoubleAnimation Storyboard.TargetProperty="Opacity" Storyboard.TargetName="RepeatButtonGrid" To="1" Duration="0:0:0"/>
+                                                                    <DoubleAnimation Storyboard.TargetProperty="Opacity"
+                                                                            Storyboard.TargetName="RepeatButtonGrid"
+                                                                            To="1"
+                                                                            Duration="0:0:0"/>
                                                                 </Storyboard>
                                                             </VisualState>
                                                             <VisualState Name="MouseOver">
                                                                 <Storyboard>
-                                                                    <DoubleAnimation Storyboard.TargetProperty="Opacity" Storyboard.TargetName="RepeatButtonGrid" To="0" Duration="0:0:0.1"/>
+                                                                    <DoubleAnimation Storyboard.TargetProperty="Opacity"
+                                                                            Storyboard.TargetName="RepeatButtonGrid"
+                                                                            To="0"
+                                                                            Duration="0:0:0.1"/>
                                                                 </Storyboard>
                                                             </VisualState>
                                                         </VisualStateGroup>
diff --git a/AutoTrackR2/AutoTrackR2.csproj b/AutoTrackR2/AutoTrackR2.csproj
index 0ba95b7..875c53d 100644
--- a/AutoTrackR2/AutoTrackR2.csproj
+++ b/AutoTrackR2/AutoTrackR2.csproj
@@ -109,9 +109,6 @@
   </ItemGroup>
 
   <ItemGroup>
-    <None Update="KillTrackR_MainScript.ps1">
-      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
-    </None>
     <None Update="update.ps1">
       <CopyToOutputDirectory>Always</CopyToOutputDirectory>
     </None>
diff --git a/AutoTrackR2/ConfigPage.xaml b/AutoTrackR2/ConfigPage.xaml
index 3b2016f..5e425e9 100644
--- a/AutoTrackR2/ConfigPage.xaml
+++ b/AutoTrackR2/ConfigPage.xaml
@@ -1,96 +1,234 @@
 <UserControl x:Class="AutoTrackR2.ConfigPage"
              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
-             Height="396" Width="626">
+             Height="410"
+        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" />
+                <RowDefinition Height="*"/>
+                <RowDefinition Height="Auto"/>
             </Grid.RowDefinitions>
 
             <Grid.ColumnDefinitions>
                 <!-- Left column for the main content area -->
-                <ColumnDefinition Width="*" />
+                <ColumnDefinition Width="*"/>
                 <!-- Right column for the buttons -->
-                <ColumnDefinition Width="Auto" />
+                <ColumnDefinition Width="Auto"/>
             </Grid.ColumnDefinitions>
 
             <!-- Section for Config Fields -->
-            <StackPanel Grid.Column="0" VerticalAlignment="Center" Height="389">
+            <StackPanel Grid.Column="0"
+                    VerticalAlignment="Center"
+                    Height="389">
                 <!-- Log File -->
-                <StackPanel Margin="0,10,0,15" Orientation="Horizontal">
-                    <TextBlock Text="Log File:" Foreground="{DynamicResource TextBrush}" FontSize="16" Margin="0,5,0,5" FontFamily="{StaticResource Roboto}"/>
-                    <StackPanel Orientation="Horizontal" Margin="30,0,0,0">
-                        <TextBox Name="LogFilePath" Width="340" Height="30" Style="{StaticResource RoundedTextBox}"/>
-                        <Button Content="Browse" Width="75" Height="30" FontFamily="{StaticResource Orbitron}" Margin="5,0" Style="{StaticResource ButtonStyle}" Click="LogFileBrowseButton_Click"/>
+                <StackPanel Margin="0,10,0,15"
+                        Orientation="Horizontal">
+                    <TextBlock Text="ⓘ"
+                            ToolTip="Set this to the Game.log file in your StarCitizen\LIVE directory."
+                            Foreground="{DynamicResource TextBrush}"
+                            FontSize="20"
+                            Margin="0,0,3,5"/>
+                    <TextBlock Text="Log File:"
+                            Foreground="{DynamicResource TextBrush}"
+                            FontSize="16"
+                            Margin="0,5,0,5"
+                            FontFamily="{StaticResource Roboto}"/>
+                    <StackPanel Orientation="Horizontal"
+                            Margin="30,0,0,0">
+                        <TextBox Name="LogFilePath"
+                                Width="330"
+                                Height="30"
+                                Style="{StaticResource RoundedTextBox}"/>
+                        <Button Content="Browse"
+                                Width="75"
+                                Height="30"
+                                FontFamily="{StaticResource Orbitron}"
+                                Margin="5,0"
+                                Style="{StaticResource ButtonStyle}"
+                                Click="LogFileBrowseButton_Click"/>
                     </StackPanel>
                 </StackPanel>
 
                 <!-- API URL -->
-                <StackPanel Margin="0,0,0,15" Orientation="Horizontal">
-                    <TextBlock Text="API URL:" Foreground="{DynamicResource TextBrush}" FontSize="16" Margin="0,5,0,5"/>
-                    <StackPanel Orientation="Horizontal" Margin="30,0,0,0">
-                        <TextBox Name="ApiUrl" Width="340" Height="30" Style="{StaticResource RoundedTextBox}"/>
-                        <Button Content="Test" Width="75" Height="30" FontFamily="{StaticResource Orbitron}" Margin="5,0" Style="{StaticResource ButtonStyle}" Click="TestApiButton_Click"/>
+                <StackPanel Margin="0,0,0,15"
+                        Orientation="Horizontal">
+                    <TextBlock Text="ⓘ"
+                            ToolTip="Need a URL? No idea what to do? Contact heavy_bob on Discord!"
+                            Foreground="{DynamicResource TextBrush}"
+                            FontSize="20"
+                            Margin="0,3,3,5"/>
+                    <TextBlock Text="API URL:"
+                            Foreground="{DynamicResource TextBrush}"
+                            FontSize="16"
+                            Margin="0,5,0,5"/>
+                    <StackPanel Orientation="Horizontal"
+                            Margin="30,0,0,0">
+                        <TextBox Name="ApiUrl"
+                                Width="330"
+                                Height="30"
+                                Style="{StaticResource RoundedTextBox}"/>
+                        <Button Content="Test"
+                                Width="75"
+                                Height="30"
+                                FontFamily="{StaticResource Orbitron}"
+                                Margin="5,0"
+                                Style="{StaticResource ButtonStyle}"
+                                Click="TestApiButton_Click"/>
                     </StackPanel>
                 </StackPanel>
 
                 <!-- API Key -->
-                <StackPanel Margin="0,0,0,15" Orientation="Horizontal">
-                    <TextBlock Text="API Key:" Foreground="{DynamicResource TextBrush}" FontSize="16" Margin="0,5,0,5"/>
-                    <TextBox Name="ApiKey" Width="340" Height="30" Margin="33,0,0,0" Style="{StaticResource RoundedTextBox}"/>
+                <StackPanel Margin="0,0,0,15"
+                        Orientation="Horizontal">
+                    <TextBlock Text="ⓘ"
+                            ToolTip="Need a key? No idea what to do? Contact heavy_bob on Discord!"
+                            Foreground="{DynamicResource TextBrush}"
+                            FontSize="20"
+                            Margin="0,3,3,5"/>
+                    <TextBlock Text="API Key:"
+                            Foreground="{DynamicResource TextBrush}"
+                            FontSize="16"
+                            Margin="0,5,0,5"/>
+                    <PasswordBox Name="ApiKey"
+                            Width="330"
+                            Height="30"
+                            Margin="33,0,0,0"
+                            Style="{StaticResource RoundedPasswordBox}"/>
                 </StackPanel>
 
                 <!-- Video Path -->
-                <StackPanel Margin="0,0,0,15" Orientation="Horizontal">
-                    <TextBlock Text="Video Path:" Foreground="{DynamicResource TextBrush}" FontSize="16" Margin="0,5,0,5"/>
+                <StackPanel Margin="0,0,0,15"
+                        Orientation="Horizontal">
+                    <TextBlock Text="ⓘ"
+                            ToolTip="The directory where your clipping software saves kills. Check the README."
+                            Foreground="{DynamicResource TextBrush}"
+                            FontSize="20"
+                            Margin="0,3,3,5"/>
+                    <TextBlock Text="Video Path:"
+                            Foreground="{DynamicResource TextBrush}"
+                            FontSize="16"
+                            Margin="0,5,0,5"/>
                     <StackPanel Orientation="Horizontal">
-                        <TextBox Name="VideoPath" Width="340" Height="30" Margin="10,0,0,0" Style="{StaticResource RoundedTextBox}"/>
-                        <Button Content="Browse" Width="75" Height="30" FontFamily="{StaticResource Orbitron}" Margin="5,0" Style="{StaticResource ButtonStyle}" Click="VideoPathBrowseButton_Click"/>
+                        <TextBox Name="VideoPath"
+                                Width="330"
+                                Height="30"
+                                Margin="10,0,0,0"
+                                Style="{StaticResource RoundedTextBox}"/>
+                        <Button Content="Browse"
+                                Width="75"
+                                Height="30"
+                                FontFamily="{StaticResource Orbitron}"
+                                Margin="5,0"
+                                Style="{StaticResource ButtonStyle}"
+                                Click="VideoPathBrowseButton_Click"/>
                     </StackPanel>
                 </StackPanel>
 
                 <!-- Visor Wipe Toggle Slider -->
-                <StackPanel Margin="0,0,0,15" Orientation="Horizontal">
-                    <TextBlock Text="Visor Wipe:" Foreground="{DynamicResource TextBrush}" FontSize="16" Margin="0,7,0,5"/>
-                    <Slider Name="VisorWipeSlider" Minimum="0" Maximum="1" TickFrequency="1" IsSnapToTickEnabled="True" Value="0" Style="{StaticResource ToggleSliderStyle}" Margin="27,-4,0,0" ValueChanged="VisorWipeSlider_ValueChanged"/>
+                <StackPanel Margin="0,0,0,15"
+                        Orientation="Horizontal">
+                    <TextBlock Text="ⓘ"
+                            ToolTip="Perform a Visor Wipe animation on player kill. Requires AHKv2."
+                            Foreground="{DynamicResource TextBrush}"
+                            FontSize="20"
+                            Margin="0,4,3,5"/>
+                    <TextBlock Text="Visor Wipe:"
+                            Foreground="{DynamicResource TextBrush}"
+                            FontSize="16"
+                            Margin="0,7,0,5"/>
+                    <Slider Name="VisorWipeSlider"
+                            Minimum="0"
+                            Maximum="1"
+                            TickFrequency="1"
+                            IsSnapToTickEnabled="True"
+                            Value="0"
+                            Style="{StaticResource ToggleSliderStyle}"
+                            Margin="27,-4,0,0"
+                            ValueChanged="VisorWipeSlider_ValueChanged"/>
                 </StackPanel>
 
                 <!-- Video Record Toggle Slider -->
-                <StackPanel Margin="0,0,0,15" Orientation="Horizontal">
-                    <TextBlock Text="Video Record:" Foreground="{DynamicResource TextBrush}" FontSize="16" Margin="0,7,0,5"/>
-                    <Slider Name="VideoRecordSlider" Minimum="0" Maximum="1" TickFrequency="1" IsSnapToTickEnabled="True" Value="0" Style="{StaticResource ToggleSliderStyle}" Margin="10,-4,0,0" ValueChanged="VideoRecordSlider_ValueChanged"/>
+                <StackPanel Margin="0,0,0,15"
+                        Orientation="Horizontal">
+                    <TextBlock Text="ⓘ"
+                            ToolTip="Automatically clip your last kill. Check the README for more info."
+                            Foreground="{DynamicResource TextBrush}"
+                            FontSize="20"
+                            Margin="0,4,3,5"/>
+                    <TextBlock Text="Video Record:"
+                            Foreground="{DynamicResource TextBrush}"
+                            FontSize="16"
+                            Margin="0,7,0,5"/>
+                    <Slider Name="VideoRecordSlider"
+                            Minimum="0"
+                            Maximum="1"
+                            TickFrequency="1"
+                            IsSnapToTickEnabled="True"
+                            Value="0"
+                            Style="{StaticResource ToggleSliderStyle}"
+                            Margin="10,-4,0,0"
+                            ValueChanged="VideoRecordSlider_ValueChanged"/>
                 </StackPanel>
 
                 <!-- Offline Mode Toggle Slider -->
-                <StackPanel Margin="0,0,0,15" Orientation="Horizontal">
-                    <TextBlock Text="Offline Mode:" Foreground="{DynamicResource TextBrush}" FontSize="16" Margin="0,7,0,5"/>
-                    <Slider Name="OfflineModeSlider" Minimum="0" Maximum="1" TickFrequency="1" IsSnapToTickEnabled="True" Value="0" Style="{StaticResource ToggleSliderStyle}" Margin="12,-4,0,0" ValueChanged="OfflineModeSlider_ValueChanged"/>
+                <StackPanel Margin="0,0,0,10"
+                        Orientation="Horizontal">
+                    <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,5"/>
+                    <TextBlock Text="Offline Mode:"
+                            Foreground="{DynamicResource TextBrush}"
+                            FontSize="16"
+                            Margin="0,7,0,5"/>
+                    <Slider Name="OfflineModeSlider"
+                            Minimum="0"
+                            Maximum="1"
+                            TickFrequency="1"
+                            IsSnapToTickEnabled="True"
+                            Value="0"
+                            Style="{StaticResource ToggleSliderStyle}"
+                            Margin="12,-4,0,0"
+                            ValueChanged="OfflineModeSlider_ValueChanged"/>
                 </StackPanel>
 
                 <!-- 3-Position Toggle Slider -->
-                <StackPanel Margin="0,0,0,15" Orientation="Horizontal">
-                    <TextBlock Text="Theme:" Foreground="{DynamicResource TextBrush}" FontSize="16" Margin="0,7,0,5"/>
+                <StackPanel Margin="0,0,0,15"
+                        Orientation="Horizontal">
+                    <TextBlock Text="Theme:"
+                            Foreground="{DynamicResource TextBrush}"
+                            FontSize="16"
+                            Margin="0,7,0,5"/>
                     <Slider x:Name="ThemeSlider"
-                            Minimum="0" 
+                            Minimum="0"
                             Maximum="21"
                             Value="0"
                             TickFrequency="1"
                             IsSnapToTickEnabled="True"
-                            ValueChanged="ThemeSlider_ValueChanged" Width="447"
-                            Style="{StaticResource ThreePositionSlider}" 
-                    />
+                            ValueChanged="ThemeSlider_ValueChanged"
+                            Width="447"
+                            Style="{StaticResource ThreePositionSlider}"/>
                 </StackPanel>
 
             </StackPanel>
 
             <!-- Save Button -->
-            <StackPanel Grid.Column="2" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0">
-                <Button x:Name="SaveButton" Content="Save" Width="100" Height="40" Style="{StaticResource ButtonStyle}" FontFamily="{StaticResource Orbitron}" Click="SaveButton_Click"/>
+            <StackPanel Grid.Column="2"
+                    HorizontalAlignment="Right"
+                    VerticalAlignment="Bottom"
+                    Margin="0">
+                <Button x:Name="SaveButton"
+                        Content="Save"
+                        Width="100"
+                        Height="40"
+                        Style="{StaticResource ButtonStyle}"
+                        FontFamily="{StaticResource Orbitron}"
+                        Click="SaveButton_Click"/>
             </StackPanel>
         </Grid>
     </Grid>
diff --git a/AutoTrackR2/ConfigPage.xaml.cs b/AutoTrackR2/ConfigPage.xaml.cs
index 5e7f366..bf83314 100644
--- a/AutoTrackR2/ConfigPage.xaml.cs
+++ b/AutoTrackR2/ConfigPage.xaml.cs
@@ -24,10 +24,10 @@ namespace AutoTrackR2
         {
             InitializeComponent();
             this.mainWindow = mainWindow;
-         
+
             LogFilePath.Text = ConfigManager.LogFile;
             ApiUrl.Text = ConfigManager.ApiUrl;
-            ApiKey.Text = ConfigManager.ApiKey;
+            ApiKey.Password = ConfigManager.ApiKey;
             VideoPath.Text = ConfigManager.VideoPath;
             VisorWipeSlider.Value = ConfigManager.VisorWipe;
             VideoRecordSlider.Value = ConfigManager.VideoRecord;
@@ -70,7 +70,7 @@ namespace AutoTrackR2
             // Set the textboxes with the loaded values
             LogFilePath.Text = logFile;
             ApiUrl.Text = apiUrl;
-            ApiKey.Text = apiKey;
+            ApiKey.Password = apiKey;
             VideoPath.Text = videoPath;
 
             // Set the sliders with the loaded values
@@ -123,7 +123,7 @@ namespace AutoTrackR2
 
             // Apply the selected theme
             ApplyTheme(themeIndex);
-            
+
             mainWindow.UpdateTabVisuals();
         }
 
@@ -413,8 +413,7 @@ namespace AutoTrackR2
 
             // Build the dynamic file path for the current user
             string filePath = Path.Combine(
-                Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
-                "AutoTrackR2",
+                ConfigManager.AHKScriptFolder,
                 "visorwipe.ahk"
             );
 
@@ -508,36 +507,19 @@ namespace AutoTrackR2
 
         private void SaveButton_Click(object sender, RoutedEventArgs e)
         {
-            // Get the directory for the user's local application data
-            string appDataDirectory = Path.Combine(
-                Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
-                "AutoTrackR2"
-            );
-
-            // Ensure the directory exists
-            if (!Directory.Exists(appDataDirectory))
-            {
-                Directory.CreateDirectory(appDataDirectory);
-            }
-
-            // Combine the app data directory with the config file name
-            string configFilePath = Path.Combine(appDataDirectory, "config.ini");
-
-            using (StreamWriter writer = new StreamWriter(configFilePath))
-            {
-                writer.WriteLine($"LogFile={LogFilePath.Text}");
-                writer.WriteLine($"ApiUrl={ApiUrl.Text}");
-                writer.WriteLine($"ApiKey={ApiKey.Text}");
-                writer.WriteLine($"VideoPath={VideoPath.Text}");
-                writer.WriteLine($"VisorWipe={(int)VisorWipeSlider.Value}");
-                writer.WriteLine($"VideoRecord={(int)VideoRecordSlider.Value}");
-                writer.WriteLine($"OfflineMode={(int)OfflineModeSlider.Value}");
-                writer.WriteLine($"Theme={(int)ThemeSlider.Value}"); // Assumes you are saving the theme slider value (0, 1, or 2)
-            }
+            ConfigManager.ApiKey = ApiKey.Password;
+            ConfigManager.ApiUrl = ApiUrl.Text;
+            ConfigManager.LogFile = LogFilePath.Text;
+            ConfigManager.VideoPath = VideoPath.Text;
+            ConfigManager.VisorWipe = (int)VisorWipeSlider.Value;
+            ConfigManager.VideoRecord = (int)VideoRecordSlider.Value;
+            ConfigManager.OfflineMode = (int)OfflineModeSlider.Value;
+            ConfigManager.Theme = (int)ThemeSlider.Value;
 
+            // Save the current config values
+            ConfigManager.SaveConfig();
             // Start the flashing effect
             FlashSaveButton();
-            ConfigManager.LoadConfig();
         }
 
         private void FlashSaveButton()
@@ -591,7 +573,7 @@ namespace AutoTrackR2
         {
             string apiUrl = ApiUrl.Text;
             string modifiedUrl = Regex.Replace(apiUrl, @"(https?://[^/]+)/?.*", "$1/test");
-            string apiKey = ApiKey.Text;
+            string apiKey = ApiKey.Password;
             Debug.WriteLine($"Sending to {modifiedUrl}");
 
             try
diff --git a/AutoTrackR2/HomePage.xaml.cs b/AutoTrackR2/HomePage.xaml.cs
index f65af75..e3eb36a 100644
--- a/AutoTrackR2/HomePage.xaml.cs
+++ b/AutoTrackR2/HomePage.xaml.cs
@@ -3,309 +3,360 @@ using System.Windows;
 using System.Windows.Controls;
 using System.Windows.Media;
 using System.Windows.Media.Effects;
-using System.IO;
 using System.Windows.Documents;
 using System.Globalization;
+using System.IO;
+using System.Text;
 using System.Windows.Media.Imaging;
+using AutoTrackR2.LogEventHandlers;
 
-namespace AutoTrackR2
+namespace AutoTrackR2;
+
+public partial class HomePage : UserControl
 {
-    public partial class HomePage : UserControl
+    private Process runningProcess; // Field to store the running process
+    private LogHandler? _logHandler;
+    private KillHistoryManager _killHistoryManager;
+    private bool _UIEventsRegistered = false;
+    
+    public HomePage()
     {
-        public HomePage()
+        InitializeComponent();
+        
+        _killHistoryManager = new KillHistoryManager(ConfigManager.KillHistoryFile);
+
+        // Set the TextBlock text
+        KillTallyTitle.Text = $"Kill Tally - {_killHistoryManager.GetKillsInCurrentMonth().Count}";
+        AddKillHistoryKillsToUI();
+        
+    }
+    //
+    public void UpdateButtonState(bool isRunning)
+    {
+        var accentColor = (Color)Application.Current.Resources["AccentColor"];
+
+        if (isRunning)
         {
-            InitializeComponent();
+            // Set Start button to "Running..." and apply glow effect
+            StartButton.Content = "Running...";
+            StartButton.IsEnabled = false; // Disable Start button
+            StartButton.Style = (Style)FindResource("DisabledButtonStyle");
 
-            // Get the current month
-            string currentMonth = DateTime.Now.ToString("MMMM", CultureInfo.InvariantCulture);
-
-            // Set the TextBlock text
-            KillTallyTitle.Text = $"Kill Tally - {currentMonth}";
-        }
-
-        private Process runningProcess; // Field to store the running process
-
-        // Update Start/Stop button states based on the isRunning flag
-        public void UpdateButtonState(bool isRunning)
-        {
-            var accentColor = (Color)Application.Current.Resources["AccentColor"];
-
-            if (isRunning)
+            // Add glow effect to the Start button
+            StartButton.Effect = new DropShadowEffect
             {
-                // Set Start button to "Running..." and apply glow effect
-                StartButton.Content = "Running...";
-                StartButton.IsEnabled = false; // Disable Start button
-                StartButton.Style = (Style)FindResource("DisabledButtonStyle");
+                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
+            };
 
-                // 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
-            }
-            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
-            }
+            StopButton.Style = (Style)FindResource("ButtonStyle");
+            StopButton.IsEnabled = true;  // Enable Stop button
         }
-
-        public void StartButton_Click(object sender, RoutedEventArgs e)
+        else
         {
-            UpdateButtonState(true);
-            string scriptPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "KillTrackR_MainScript.ps1");
-            TailFileAsync(scriptPath);
+            // 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
         }
+        
+        RegisterUIEventHandlers();
+    }
 
-        private async void TailFileAsync(string scriptPath)
+    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()
+    {
+        var kills = _killHistoryManager.GetKills();
+        foreach (var kill in kills)
         {
-            await Task.Run(() =>
+            Dispatcher.Invoke(() => { AddKillToScreen(kill); });
+        }
+    }
+
+    private void RegisterUIEventHandlers()
+    {
+        if (_UIEventsRegistered)
+            return;
+        
+        // Username
+        TrackREventDispatcher.PlayerLoginEvent += (username) => {
+            Dispatcher.Invoke(() =>
             {
-                try
+                PilotNameTextBox.Text = username;
+                AdjustFontSize(PilotNameTextBox);
+                LocalPlayerData.Username = username;
+            });
+        };
+        
+        // Ship
+        TrackREventDispatcher.JumpDriveStateChangedEvent += (shipName) => {
+                Dispatcher.Invoke(() =>
                 {
-                    ProcessStartInfo psi = new ProcessStartInfo
-                    {
-                        FileName = "powershell.exe",
-                        Arguments = $"-NoProfile -ExecutionPolicy Bypass -File \"{scriptPath}\"",
-                        WorkingDirectory = AppDomain.CurrentDomain.BaseDirectory,
-                        RedirectStandardOutput = true,
-                        RedirectStandardError = true,
-                        UseShellExecute = false,
-                        CreateNoWindow = true
-                    };
+                    PlayerShipTextBox.Text = shipName;
+                    AdjustFontSize(PlayerShipTextBox);
+                    LocalPlayerData.PlayerShip = shipName;
+                });
+        };
+        
+        // Game Mode
+        TrackREventDispatcher.PlayerChangedGameModeEvent += (mode) => {
+            Dispatcher.Invoke(() =>
+            {
+                GameModeTextBox.Text = mode.ToString();
+                AdjustFontSize(GameModeTextBox);
+                LocalPlayerData.CurrentGameMode = mode;
+            });
+        };
+        
+        // Game Version
+        TrackREventDispatcher.GameVersionEvent += (version) => {
+                LocalPlayerData.GameVersion = version;
+        };
+        
+        // Actor Death
+        TrackREventDispatcher.ActorDeathEvent += async (actorDeathData) => {
+            if (actorDeathData.VictimPilot != LocalPlayerData.Username)
+            {
+                var playerData = await WebHandler.GetPlayerData(actorDeathData.VictimPilot);
 
-                    runningProcess = new Process { StartInfo = psi }; // Store the process in the field
-
-                    runningProcess.OutputDataReceived += (s, e) =>
-                    {
-                        if (!string.IsNullOrEmpty(e.Data))
-                        {
-                            Dispatcher.Invoke(() =>
-                            {
-                                // Parse and display key-value pairs in the OutputTextBox
-                                if (e.Data.Contains("PlayerName="))
-                                {
-                                    string pilotName = e.Data.Split('=')[1].Trim();
-                                    PilotNameTextBox.Text = pilotName; // Update the Button's Content
-                                    AdjustFontSize(PilotNameTextBox);
-                                }
-                                else if (e.Data.Contains("PlayerShip="))
-                                {
-                                    string playerShip = e.Data.Split('=')[1].Trim();
-                                    PlayerShipTextBox.Text = playerShip;
-                                    AdjustFontSize(PlayerShipTextBox);
-                                }
-                                else if (e.Data.Contains("GameMode="))
-                                {
-                                    string gameMode = e.Data.Split('=')[1].Trim();
-                                    GameModeTextBox.Text = gameMode;
-                                    AdjustFontSize(GameModeTextBox);
-                                }
-                                else if (e.Data.Contains("KillTally="))
-                                {
-                                    string killTally = e.Data.Split('=')[1].Trim();
-                                    KillTallyTextBox.Text = killTally;
-                                    AdjustFontSize(KillTallyTextBox);
-                                }
-                                else if (e.Data.Contains("NewKill="))
-                                {
-                                    // Parse the kill data
-                                    var killData = e.Data.Split('=')[1].Trim(); // Assume the kill data follows after "NewKill="
-                                    var killParts = killData.Split(',');
-
-                                    // Fetch the dynamic resource for AltTextColor
-                                    var altTextColorBrush = new SolidColorBrush((Color)Application.Current.Resources["AltTextColor"]);
-                                    var accentColorBrush = new SolidColorBrush((Color)Application.Current.Resources["AccentColor"]);
-
-                                    // Fetch the Orbitron FontFamily from resources
-                                    var orbitronFontFamily = (FontFamily)Application.Current.Resources["Orbitron"];
-                                    var gemunuFontFamily = (FontFamily)Application.Current.Resources["Gemunu"];
-
-                                    // Create a new TextBlock for each kill
-                                    var killTextBlock = new TextBlock
-                                    {
-                                        Margin = new Thickness(0, 10, 0, 10),
-                                        Style = (Style)Application.Current.Resources["RoundedTextBlock"], // Apply style for text
-                                        FontSize = 14,
-                                        FontWeight = FontWeights.Bold,
-                                        FontFamily = gemunuFontFamily,
-                                    };
-
-                                    // Add styled content using Run elements
-                                    killTextBlock.Inlines.Add(new Run("Victim Name: ")
-                                    {
-                                        Foreground = altTextColorBrush,
-                                        FontFamily = orbitronFontFamily,
-                                    });
-                                    killTextBlock.Inlines.Add(new Run($"{killParts[1]}\n"));
-
-                                    // Repeat for other lines
-                                    killTextBlock.Inlines.Add(new Run("Victim Ship: ")
-                                    {
-                                        Foreground = altTextColorBrush,
-                                        FontFamily = orbitronFontFamily,
-                                    });
-                                    killTextBlock.Inlines.Add(new Run($"{killParts[2]}\n"));
-
-                                    killTextBlock.Inlines.Add(new Run("Victim Org: ")
-                                    {
-                                        Foreground = altTextColorBrush,
-                                        FontFamily = orbitronFontFamily,
-                                    });
-                                    killTextBlock.Inlines.Add(new Run($"{killParts[3]}\n"));
-
-                                    killTextBlock.Inlines.Add(new Run("Join Date: ")
-                                    {
-                                        Foreground = altTextColorBrush,
-                                        FontFamily = orbitronFontFamily,
-                                    });
-                                    killTextBlock.Inlines.Add(new Run($"{killParts[4]}\n"));
-
-                                    killTextBlock.Inlines.Add(new Run("UEE Record: ")
-                                    {
-                                        Foreground = altTextColorBrush,
-                                        FontFamily = orbitronFontFamily,
-                                    });
-                                    killTextBlock.Inlines.Add(new Run($"{killParts[5]}\n"));
-
-                                    killTextBlock.Inlines.Add(new Run("Kill Time: ")
-                                    {
-                                        Foreground = altTextColorBrush,
-                                        FontFamily = orbitronFontFamily,
-                                    });
-                                    killTextBlock.Inlines.Add(new Run($"{killParts[6]}"));
-
-                                    // Create a Border and apply the RoundedTextBlockWithBorder style
-                                    var killBorder = new Border
-                                    {
-                                        Style = (Style)Application.Current.Resources["RoundedTextBlockWithBorder"], // Apply border style
-                                    };
-
-                                    // Create a Grid to hold the TextBlock and the Image
-                                    var killGrid = new Grid
-                                    {
-                                        Width = 400, // Adjust the width of the Grid
-                                        Height = 130, // Adjust the height as needed
-                                    };
-
-                                    // Define two columns in the Grid: one for the text and one for the image
-                                    killGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(3, GridUnitType.Star) }); // Text column
-                                    killGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Auto) }); // Image column
-
-                                    // Add the TextBlock to the first column of the Grid
-                                    Grid.SetColumn(killTextBlock, 0);
-                                    killGrid.Children.Add(killTextBlock);
-
-                                    // Create the Image for the profile
-                                    var profileImage = new Image
-                                    {
-                                        Source = new BitmapImage(new Uri(killParts[7])), // Assuming the 8th part contains the profile image URL
-                                        Width = 90,
-                                        Height = 90,
-                                        Stretch = Stretch.Fill, // Adjust how the image fits
-                                    };
-
-                                    // Create a Border around the Image
-                                    var imageBorder = new Border
-                                    {
-                                        BorderBrush = accentColorBrush, // Set the border color
-                                        BorderThickness = new Thickness(2), // Set the border thickness
-                                        Padding = new Thickness(0), // Optional padding inside the border
-                                        CornerRadius = new CornerRadius(5),
-                                        Margin = new Thickness(10,18,15,18),
-                                        Child = profileImage // Set the Image as the content of the Border
-                                    };
-
-                                    // Add the Border (with the image inside) to the Grid
-                                    Grid.SetColumn(imageBorder, 1);
-                                    killGrid.Children.Add(imageBorder);
-
-                                    // Set the Grid as the child of the Border
-                                    killBorder.Child = killGrid;
-
-                                    // Add the new Border to the StackPanel inside the Border
-                                    KillFeedStackPanel.Children.Insert(0, killBorder);
-                                }
-
-                                else
-                                {
-                                    DebugPanel.AppendText(e.Data + Environment.NewLine);
-                                }
-                            });
-                        }
-                    };
-
-                    runningProcess.ErrorDataReceived += (s, e) =>
-                    {
-                        if (!string.IsNullOrEmpty(e.Data))
-                        {
-                            Dispatcher.Invoke(() =>
-                            {
-                                DebugPanel.AppendText(e.Data + Environment.NewLine);
-                            });
-                        }
-                    };
-
-                    runningProcess.Start();
-                    runningProcess.BeginOutputReadLine();
-                    runningProcess.BeginErrorReadLine();
-
-                    runningProcess.WaitForExit();
-                }
-                catch (Exception ex)
+                if (playerData != null)
                 {
+                    var killData = new KillData
+                    {
+                        EnemyPilot = actorDeathData.VictimPilot,
+                        EnemyShip = actorDeathData.VictimShip,
+                        OrgAffiliation = playerData?.OrgName,
+                        Weapon = actorDeathData.Weapon,
+                        Ship = LocalPlayerData.PlayerShip ?? "Unknown",
+                        Method = actorDeathData.DamageType,
+                        RecordNumber = playerData?.UEERecord,
+                        GameVersion = LocalPlayerData.GameVersion ?? "Unknown",
+                        TrackRver = UpdatePage.currentVersion.Replace("v", "") ?? "Unknown",
+                        Enlisted = playerData?.JoinDate,
+                        KillTime = DateTime.UtcNow.ToString("dd MMM yyyy HH:mm"),
+                        PFP = playerData?.PFPURL ?? "https://cdn.robertsspaceindustries.com/static/images/account/avatar_default_big.jpg"
+                    };
+                    
+                    switch (LocalPlayerData.CurrentGameMode)
+                    {
+                        case GameMode.PersistentUniverse:
+                            killData.Mode = "pu";
+                            break;
+                        case GameMode.ArenaCommander:
+                            killData.Mode = "ac";
+                            break;
+                    }
+                    
+                    // Add kill to UI
                     Dispatcher.Invoke(() =>
                     {
-                        MessageBox.Show($"Error running script: {ex.Message}");
+                        AddKillToScreen(killData);
                     });
+    
+                    // Only submit kill data if not in offline mode
+                    if (ConfigManager.OfflineMode == 0)
+                    {
+                        await WebHandler.SubmitKill(killData);
+                    }
+
+                    _killHistoryManager.AddKill(killData);
+                    VisorWipe();
+                    VideoRecord();
                 }
-            });
-        }
-
-        public void StopButton_Click(object sender, RoutedEventArgs e)
-        {
-            if (runningProcess != null && !runningProcess.HasExited)
-            {
-                // Kill the running process
-                runningProcess.Kill();
-                runningProcess = null; // Clear the reference to the process
             }
+        };
+        
+        // Vehicle Destruction
+        TrackREventDispatcher.VehicleDestructionEvent += (data) => {
+            LocalPlayerData.LastSeenVehicleLocation = data.VehicleZone;
+        };
+        
+        _UIEventsRegistered = true;
+    }
 
-            // Clear the text boxes
-            System.Threading.Thread.Sleep(200);
-            PilotNameTextBox.Text = string.Empty;
-            PlayerShipTextBox.Text = string.Empty;
-            GameModeTextBox.Text = string.Empty;
-            KillTallyTextBox.Text = string.Empty;
-            KillFeedStackPanel.Children.Clear();
-        }
+    private void AddKillToScreen(KillData killData)
+    { 
+        // Fetch the dynamic resource for AltTextColor
+        var altTextColorBrush = new SolidColorBrush((Color)Application.Current.Resources["AltTextColor"]);
+        var accentColorBrush = new SolidColorBrush((Color)Application.Current.Resources["AccentColor"]);
 
-        private void AdjustFontSize(TextBlock textBlock)
+        // Fetch the Orbitron FontFamily from resources
+        var orbitronFontFamily = (FontFamily)Application.Current.Resources["Orbitron"];
+        var gemunuFontFamily = (FontFamily)Application.Current.Resources["Gemunu"];
+
+        // Create a new TextBlock for each kill
+        var killTextBlock = new TextBlock
         {
-            // Set a starting font size
-            double fontSize = 14;
-            double maxWidth = textBlock.Width;
+            Margin = new Thickness(0, 10, 0, 10),
+            Style = (Style)Application.Current.Resources["RoundedTextBlock"], // Apply style for text
+            FontSize = 14,
+            FontWeight = FontWeights.Bold,
+            FontFamily = gemunuFontFamily,
+        };
 
-            if (string.IsNullOrEmpty(textBlock.Text) || double.IsNaN(maxWidth))
-                return;
+        // Add styled content using Run elements
+        killTextBlock.Inlines.Add(new Run("Victim Name: ")
+        {
+            Foreground = altTextColorBrush,
+            FontFamily = orbitronFontFamily,
+        });
+        killTextBlock.Inlines.Add(new Run($"{killData.EnemyPilot}\n"));
 
-            // Measure the rendered width of the text
-            FormattedText formattedText = new FormattedText(
+        // Repeat for other lines
+        killTextBlock.Inlines.Add(new Run("Victim Ship: ")
+        {
+            Foreground = altTextColorBrush,
+            FontFamily = orbitronFontFamily,
+        });
+        killTextBlock.Inlines.Add(new Run($"{killData.EnemyShip}\n"));
+
+        killTextBlock.Inlines.Add(new Run("Victim Org: ")
+        {
+            Foreground = altTextColorBrush,
+            FontFamily = orbitronFontFamily,
+        });
+        killTextBlock.Inlines.Add(new Run($"{killData.OrgAffiliation}\n"));
+        
+        killTextBlock.Inlines.Add(new Run("Join Date: ")
+        {
+            Foreground = altTextColorBrush,
+            FontFamily = orbitronFontFamily,
+        });
+        killTextBlock.Inlines.Add(new Run($"{killData.Enlisted}\n"));
+        
+        killTextBlock.Inlines.Add(new Run("UEE Record: ")
+        {
+            Foreground = altTextColorBrush,
+            FontFamily = orbitronFontFamily,
+        });
+        
+        killTextBlock.Inlines.Add(new Run($"{killData.RecordNumber}\n"));
+        
+        killTextBlock.Inlines.Add(new Run("Kill Time: ")
+        {
+            Foreground = altTextColorBrush,
+            FontFamily = orbitronFontFamily,
+        });
+        killTextBlock.Inlines.Add(new Run($"{killData.KillTime}"));
+
+        // Create a Border and apply the RoundedTextBlockWithBorder style
+        var killBorder = new Border
+        {
+            Style = (Style)Application.Current.Resources["RoundedTextBlockWithBorder"], // Apply border style
+        };
+
+        // Create a Grid to hold the TextBlock and the Image
+        var killGrid = new Grid
+        {
+            Width = 400, // Adjust the width of the Grid
+            Height = 130, // Adjust the height as needed
+        };
+
+        // Define two columns in the Grid: one for the text and one for the image
+        killGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(3, GridUnitType.Star) }); // Text column
+        killGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Auto) }); // Image column
+
+        // Add the TextBlock to the first column of the Grid
+        Grid.SetColumn(killTextBlock, 0);
+        killGrid.Children.Add(killTextBlock);
+
+        if (killData.PFP == "")
+        {
+            killData.PFP = "https://cdn.robertsspaceindustries.com/static/images/account/avatar_default_big.jpg";
+        }
+        
+        // Create the Image for the profile
+        var profileImage = new Image
+        {
+            Source = new BitmapImage(new Uri(killData.PFP)), // Assuming the 8th part contains the profile image URL
+            Width = 90,
+            Height = 90,
+            Stretch = Stretch.Fill, // Adjust how the image fits
+        };
+
+        // Create a Border around the Image
+        var imageBorder = new Border
+        {
+            BorderBrush = accentColorBrush, // Set the border color
+            BorderThickness = new Thickness(2), // Set the border thickness
+            Padding = new Thickness(0), // Optional padding inside the border
+            CornerRadius = new CornerRadius(5),
+            Margin = new Thickness(10,18,15,18),
+            Child = profileImage // Set the Image as the content of the Border
+        };
+
+        // Add the Border (with the image inside) to the Grid
+        Grid.SetColumn(imageBorder, 1);
+        killGrid.Children.Add(imageBorder);
+
+        // Set the Grid as the child of the Border
+        killBorder.Child = killGrid;
+
+        // Add the new Border to the StackPanel inside the Border
+        Dispatcher.Invoke(() =>
+        {
+            KillFeedStackPanel.Children.Insert(0, killBorder);
+        });
+    }
+
+    public void StopButton_Click(object sender, RoutedEventArgs e)
+    {
+        _logHandler?.Stop();
+
+        // Clear the text boxes
+        // System.Threading.Thread.Sleep(200);
+        // PilotNameTextBox.Text = string.Empty;
+        // PlayerShipTextBox.Text = string.Empty;
+        // GameModeTextBox.Text = string.Empty;
+        // KillTallyTextBox.Text = string.Empty;
+        // KillFeedStackPanel.Children.Clear();
+    }
+
+    private void AdjustFontSize(TextBlock textBlock)
+    {
+        // Set a starting font size
+        double fontSize = 14;
+        double maxWidth = textBlock.Width;
+
+        if (string.IsNullOrEmpty(textBlock.Text) || double.IsNaN(maxWidth))
+            return;
+
+        // Measure the rendered width of the text
+        FormattedText formattedText = new FormattedText(
+            textBlock.Text,
+            CultureInfo.CurrentCulture,
+            FlowDirection.LeftToRight,
+            new Typeface(textBlock.FontFamily, textBlock.FontStyle, textBlock.FontWeight, textBlock.FontStretch),
+            fontSize,
+            textBlock.Foreground,
+            VisualTreeHelper.GetDpi(this).PixelsPerDip
+        );
+
+        // Reduce font size until text fits within the width
+        while (formattedText.Width > maxWidth && fontSize > 6)
+        {
+            fontSize -= 0.5;
+            formattedText = new FormattedText(
                 textBlock.Text,
                 CultureInfo.CurrentCulture,
                 FlowDirection.LeftToRight,
@@ -314,24 +365,44 @@ namespace AutoTrackR2
                 textBlock.Foreground,
                 VisualTreeHelper.GetDpi(this).PixelsPerDip
             );
+        }
 
-            // Reduce font size until text fits within the width
-            while (formattedText.Width > maxWidth && fontSize > 6)
-            {
-                fontSize -= 0.5;
-                formattedText = new FormattedText(
-                    textBlock.Text,
-                    CultureInfo.CurrentCulture,
-                    FlowDirection.LeftToRight,
-                    new Typeface(textBlock.FontFamily, textBlock.FontStyle, textBlock.FontWeight, textBlock.FontStretch),
-                    fontSize,
-                    textBlock.Foreground,
-                    VisualTreeHelper.GetDpi(this).PixelsPerDip
-                );
-            }
+        // Apply the adjusted font size
+        textBlock.FontSize = fontSize;
+    }
+    
+    public static void RunAHKScript(string path)
+    {
+        string scriptPath = Path.Combine(ConfigManager.AHKScriptFolder, path);
+            
+        if (!File.Exists(scriptPath))
+        {
+            return;
+        }
+            
+        // Run the script using powershell
+        using var ahkProcess = new Process();
+            
+        // Runs the script via Explorer, ensuring it uses whatever the
+        // default binary for AHK is. Skips having to find a specific path to AHK
+        ahkProcess.StartInfo.FileName = "explorer";
+        ahkProcess.StartInfo.Arguments = "\"" + scriptPath + "\"";
+        ahkProcess.Start();
+    }
 
-            // Apply the adjusted font size
-            textBlock.FontSize = fontSize;
+    private void VisorWipe()
+    {
+        if (ConfigManager.VisorWipe == 1)
+        {
+            RunAHKScript(ConfigManager.VisorWipeScript);
+        }
+    }
+    
+    private void VideoRecord()
+    {
+        if (ConfigManager.VideoRecord == 1)
+        {
+            RunAHKScript(ConfigManager.VideoRecordScript);
         }
     }
 }
diff --git a/AutoTrackR2/KillHistoryManager.cs b/AutoTrackR2/KillHistoryManager.cs
new file mode 100644
index 0000000..5c87a17
--- /dev/null
+++ b/AutoTrackR2/KillHistoryManager.cs
@@ -0,0 +1,98 @@
+using System.Globalization;
+using System.IO;
+using System.Text;
+
+namespace AutoTrackR2;
+
+public class KillHistoryManager
+{
+    private string _killHistoryPath;
+    private readonly string _headers = "KillTime,EnemyPilot,EnemyShip,Enlisted,RecordNumber,OrgAffiliation,Player,Weapon,Ship,Method,Mode,GameVersion,TrackRver,Logged,PFP\n";
+    
+    public KillHistoryManager(string logPath)
+    {
+        _killHistoryPath = logPath;
+        
+        if (!File.Exists(_killHistoryPath))
+        {
+            File.WriteAllText(_killHistoryPath, _headers);
+        }
+    }
+    
+    public void AddKill(KillData killData)
+    {
+        // Ensure the CSV file exists
+        // This should only happen if the file was deleted or corrupted
+        if (!File.Exists(_killHistoryPath))
+        {
+            File.WriteAllText(_killHistoryPath, _headers);
+        }
+        
+        // Remove comma from Enlisted
+        killData.Enlisted = killData.Enlisted?.Replace(",", string.Empty);
+        
+        // Append the new kill data to the CSV file
+        var csv = new StringBuilder();
+        csv.AppendLine($"\"{killData.KillTime}\",\"{killData.EnemyPilot}\",\"{killData.EnemyShip}\",\"{killData.Enlisted}\",\"{killData.RecordNumber}\",\"{killData.OrgAffiliation}\",\"{killData.Player}\",\"{killData.Weapon}\",\"{killData.Ship}\",\"{killData.Method}\",\"{killData.Mode}\",\"{killData.GameVersion}\",\"{killData.TrackRver}\",\"{killData.Logged}\",\"{killData.PFP}\"");
+        
+        // Check file can be written to
+        try
+        {
+            using var fileStream = new FileStream(_killHistoryPath, FileMode.Append, FileAccess.Write, FileShare.None);
+            using var writer = new StreamWriter(fileStream);
+            writer.Write(csv.ToString());
+        }
+        catch (IOException ex)
+        {
+            // Handle the exception (e.g., log it)
+            Console.WriteLine($"Error writing to file: {ex.Message}");
+        }
+    }
+    
+    public List<KillData> GetKills()
+    {
+        var kills = new List<KillData>();
+
+        using var reader = new StreamReader(_killHistoryPath);
+        reader.ReadLine(); // Skip headers
+            
+        while (reader.Peek() >= 0)
+        {
+            var line = reader.ReadLine();
+            
+            // Remove extra quotes from CSV data
+            // Todo: These quotes are for handling commas in the data, but not sure if they're necessary
+            line = line?.Replace("\"", string.Empty);
+            
+            var data = line?.Split(',');
+                
+            kills.Add(new KillData
+            {
+                KillTime = data?[0],
+                EnemyPilot = data?[1],
+                EnemyShip = data?[2],
+                Enlisted = data?[3],
+                RecordNumber = data?[4],
+                OrgAffiliation = data?[5],
+                Player = data?[6],
+                Weapon = data?[7],
+                Ship = data?[8],
+                Method = data?[9],
+                Mode = data?[10],
+                GameVersion = data?[11],
+                TrackRver = data?[12],
+                Logged = data?[13],
+                PFP = data?[14]
+            });
+        }
+
+        return kills;
+    }
+
+    public List<KillData> GetKillsInCurrentMonth()
+    {
+        string currentMonth = DateTime.Now.ToString("MMM", CultureInfo.InvariantCulture);
+        var kills = GetKills();
+        return kills.Where(kill => kill.KillTime?.Contains(currentMonth) == true).ToList();
+    }
+}
\ No newline at end of file
diff --git a/AutoTrackR2/KillTrackR_MainScript.ps1 b/AutoTrackR2/KillTrackR_MainScript.ps1
deleted file mode 100644
index 2fb1d52..0000000
--- a/AutoTrackR2/KillTrackR_MainScript.ps1
+++ /dev/null
@@ -1,510 +0,0 @@
-$TrackRver = "2.07"
-
-# Path to the config file
-$appName = "AutoTrackR2"
-$scriptFolder = Join-Path -Path $env:LOCALAPPDATA -ChildPath $appName
-$configFile = Join-Path -Path $scriptFolder -ChildPath "config.ini"
-
-# Read the config file into a hashtable
-if (Test-Path $configFile) {
-    Write-Output "PlayerName=Config.ini found."
-    $configContent = Get-Content $configFile | Where-Object { $_ -notmatch '^#|^\s*$' }
-
-    # Escape backslashes by doubling them
-    $configContent = $configContent -replace '\\', '\\\\'
-
-    # Convert to key-value pairs
-    $config = $configContent -replace '^([^=]+)=(.+)$', '$1=$2' | ConvertFrom-StringData
-} else {
-    Write-Output "Config.ini not found."
-    exit
-}
-
-$parentApp = (Get-Process -Name AutoTrackR2).ID
-
-# Access config values
-$logFilePath = $config.Logfile
-$apiUrl = $config.ApiUrl
-$apiKey = $config.ApiKey
-$videoPath = $config.VideoPath
-$visorWipe = $config.VisorWipe
-$videoRecord = $config.VideoRecord
-$offlineMode = $config.OfflineMode
-
-if ($offlineMode -eq 1){
-    $offlineMode = $true
-} else {
-    $offlineMode = $false
-}
-Write-Output "PlayerName=OfflineMode: $offlineMode"
-
-if ($videoRecord -eq 1){
-    $videoRecord = $true
-} else {
-    $videoRecord = $false
-}
-Write-Output "PlayerName=VideoRecord: $videoRecord"
-
-if ($visorWipe -eq 1){
-    $visorWipe = $true
-} else {
-    $visorWipe = $false
-}
-Write-Output "PlayerName=VisorWipe: $visorWipe"
-
-If (Test-Path $logFilePath) {
-    Write-Output "PlayerName=Logfile found"
-} else {
-    Write-Output "Logfile not found."
-}
-
-If ($null -ne $apiUrl){
-    if ($apiUrl -notlike "*/register-kill") {
-        $apiUrl = $apiUrl.TrimEnd("/") + "/register-kill"
-    }
-    Write-output "PlayerName=$apiURL"
-}
-
-# Ship Manufacturers
-$prefixes = @(
-    "ORIG",
-    "CRUS",
-    "RSI",
-    "AEGS",
-    "VNCL",
-    "DRAK",
-    "ANVL",
-    "BANU",
-    "MISC",
-    "CNOU",
-    "XIAN",
-    "GAMA",
-    "TMBL",
-    "ESPR",
-    "KRIG",
-    "GRIN",
-    "XNAA",
-	"MRAI"
-)
-
-# Define the regex pattern to extract information
-$killPattern = "<Actor Death> CActor::Kill: '(?<EnemyPilot>[^']+)' \[\d+\] in zone '(?<EnemyShip>[^']+)' killed by '(?<Player>[^']+)' \[[^']+\] using '(?<Weapon>[^']+)' \[Class (?<Class>[^\]]+)\] with damage type '(?<DamageType>[^']+)'"
-$puPattern = '<\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z> \[Notice\] <ContextEstablisherTaskFinished> establisher="CReplicationModel" message="CET completed" taskname="StopLoadingScreen" state=[^\s()]+\(\d+\) status="Finished" runningTime=\d+\.\d+ numRuns=\d+ map="megamap" gamerules="SC_Default" sessionId="[a-f0-9\-]+" \[Team_Network\]\[Network\]\[Replication\]\[Loading\]\[Persistence\]'
-$loadoutPattern = '<Jump Drive State Changed>.*.adam: (?<ShipName>.*.) in'
-$acPattern =  "Requesting Mode Change"  # "ArenaCommanderFeature"
-$shipManPattern = "^(" + ($prefixes -join "|") + ")"
-# $loginPattern = "\[Notice\] <AccountLoginCharacterStatus_Character> Character: createdAt [A-Za-z0-9]+ - updatedAt [A-Za-z0-9]+ - geid [A-Za-z0-9]+ - accountId [A-Za-z0-9]+ - name (?<Player>[A-Za-z0-9_-]+) - state STATE_CURRENT" # KEEP THIS INCASE LEGACY LOGIN IS REMOVED 
-$loginPattern = "\[Notice\] <Legacy login response> \[CIG-net\] User Login Success - Handle\[(?<Player>[A-Za-z0-9_-]+)\]"
-$cleanupPattern = '^(.+?)_\d+$'
-$versionPattern = "--system-trace-env-id='pub-sc-alpha-(?<gameversion>\d{3,4}-\d{7})'"
-$vehiclePattern = "<(?<timestamp>[^>]+)> \[Notice\] <Vehicle Destruction> CVehicle::OnAdvanceDestroyLevel: " +
-    "Vehicle '(?<vehicle>[^']+)' \[\d+\] in zone '(?<vehicle_zone>[^']+)' " +
-    "\[pos x: (?<pos_x>[-\d\.]+), y: (?<pos_y>[-\d\.]+), z: (?<pos_z>[-\d\.]+) " +
-    "vel x: [^,]+, y: [^,]+, z: [^\]]+\] driven by '(?<driver>[^']+)' \[\d+\] " +
-    "advanced from destroy level (?<destroy_level_from>\d+) to (?<destroy_level_to>\d+) " +
-    "caused by '(?<caused_by>[^']+)' \[\d+\] with '(?<damage_type>[^']+)'"
-
-# Lookup Patterns
-$joinDatePattern = '<span class="label">Enlisted</span>\s*<strong class="value">([^<]+)</strong>'
-$ueePattern = '<p class="entry citizen-record">\s*<span class="label">UEE Citizen Record<\/span>\s*<strong class="value">#?(n\/a|\d+)<\/strong>\s*<\/p>'
-
-[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
-$process = Get-Process | Where-Object {$_.Name -like "AutoTrackR2"}
-$global:killTally = 0
-
-# Load historic kills from csv
-if (Test-Path "$scriptFolder\Kill-Log.csv") {
-	$historicKills = Import-CSV "$scriptFolder\Kill-log.csv"
-	$currentDate = Get-Date
-	$dateFormat = "dd MMM yyyy HH:mm UTC"
-	foreach ($kill in $historicKills) {
-		$killDate = [datetime]::ParseExact($kill.KillTime.Trim(), $dateFormat, [System.Globalization.CultureInfo]::InvariantCulture)
-		If ($killdate.year -eq $currentDate.Year -and $killdate.month -eq $currentDate.Month) {
-			$global:killTally++
-		}
-		Try {
-			Write-Output "NewKill=throwaway,$($kill.EnemyPilot),$($kill.EnemyShip),$($kill.OrgAffiliation),$($kill.Enlisted),$($kill.RecordNumber),$($kill.KillTime), $($kill.PFP)"
-		} Catch {
-			Write-Output "Error Loading Kill: $($kill.EnemyPilot)"
-		}
-	}
-}
-Write-Output "KillTally=$global:killTally"
-
-# Match and extract username from gamelog
-Do {
-    # Load gamelog into memory
-    $authLog = Get-Content -Path $logFilePath
-
-    # Initialize variable to store username
-    $global:userName = $null
-	$global:loadout = "Player"
-
-    # Loop through each line in the log to find the matching line
-    foreach ($line in $authLog) {
-        if ($line -match $loginPattern) {
-            $global:userName = $matches['Player']
-            Write-Output "PlayerName=$global:userName"
-        }
-		# Get Loadout
-		if ($line -match $loadoutPattern) {
-				If ($matches['ShipName'] -match $cleanupPattern){
-					if ($null -ne $matches[1]){
-						$global:loadOut = $matches[1]
-					}
-		        }
-		    Write-Output "PlayerShip=$global:loadOut"
-		}
-
-		If ($line -match $versionPattern){
-			$global:GameVersion = $matches['gameversion']
-		}
-		if ($line -match $acPattern){
-			$global:GameMode = "AC"
-		}
-		if ($line -match $puPattern){
-			$global:GameMode = "PU"
-		}
-		Write-Output "GameMode=$global:GameMode"
-
-	}
-    # If no match found, print "Logged In: False"
-    if (-not $global:userName) {
-		Write-Output "PlayerName=No Player Found..."
-        Start-Sleep -Seconds 30
-    }
-
-    # Clear the log from memory
-    $authLog = $null
-} until ($null -ne $global:userName)
-
-# Function to process new log entries and write to the host
-function Read-LogEntry {
-    param (
-        [string]$line
-    )
-
-    # Look for vehicle events
-    if ($line -match $vehiclePattern) {
-        # Access the named capture groups from the regex match
-        $global:vehicle_id = $matches['vehicle']
-        $global:location = $matches['vehicle_zone']
-
-    }
-    
-    # Apply the regex pattern to the line
-    if ($line -match $killPattern) {
-        # Access the named capture groups from the regex match
-        $enemyPilot = $matches['EnemyPilot']
-        $enemyShip = $matches['EnemyShip']
-        $player = $matches['Player']
-		$weapon = $matches['Weapon']
-		$damageType = $matches['DamageType']
-		$ship = $global:loadOut
-
-        If ($enemyShip -ne "vehicle_id"){
-            
-            $global:got_location = $location
-        }
-        else
-        {
-            $global:got_location = "NONE"
-        }
-
-		Try {
-			$page1 = Invoke-WebRequest -uri "https://robertsspaceindustries.com/citizens/$enemyPilot"
-		} Catch {
-			$page1 = $null
-		}
-
-		If ($null -ne $page1){
-			# Check if the Autotrackr2 process is running
-			if ($null -eq (Get-Process -ID $parentApp -ErrorAction SilentlyContinue)) {
-				Stop-Process -Id $PID -Force
-			}
-			If ($enemyShip -ne "Player"){
-				If ($enemyShip -eq $global:lastKill){
-					$enemyShip = "Passenger"
-				} Else {
-					$global:lastKill = $enemyShip
-				}
-			}
-
-			If ($player -eq $global:userName -and $enemyPilot -ne $global:userName){
-				If ($enemyShip -match $cleanupPattern){
-					$enemyShip = $matches[1]
-				}
-				If ($weapon -match $cleanupPattern){
-					$weapon = $matches[1]
-				}
-				If ($weapon -eq "KLWE_MassDriver_S10"){
-					$global:loadOut = "AEGS_Idris"
-					$ship = "AEGS_Idris"
-				}
-				if ($damageType -eq "Bullet" -or $weapon -like "apar_special_ballistic*") {
-					$ship = "Player"
-					$enemyShip = "Player"
-					$global:got_location = "NONE"
-				}
-				If ($ship -match $cleanupPattern){
-					$ship = $matches[1]
-				}
-				if ($ship -notmatch $shipManPattern){
-					$ship = "Player"
-					$global:got_location = "NONE"
-				}
-				If ($enemyShip -notmatch $shipManPattern -and $enemyShip -notlike "Passenger" ) {
-					$enemyShip = "Player"
-					$global:got_location = "NONE"
-				}
-			
-				# Repeatedly remove all suffixes
-				while ($enemyShip -match '_(PU|AI|CIV|MIL|PIR)$') {
-					$enemyShip = $enemyShip -replace '_(PU|AI|CIV|MIL|PIR)$', ''
-				}
-				# Repeatedly remove all suffixes
-				while ($ship -match '_(PU|AI|CIV|MIL|PIR)$') {
-					$ship = $ship -replace '_(PU|AI|CIV|MIL|PIR)$', ''
-				}
-				while ($enemyShip -match '-00(1|2|3|4|5|6|7|8|9|0)$') {
-					$enemyShip = $enemyShip -replace '-00(1|2|3|4|5|6|7|8|9|0)$', ''
-				}while ($ship -match '-00(1|2|3|4|5|6|7|8|9|0)$') {
-					$ship = $ship -replace '-00(1|2|3|4|5|6|7|8|9|0)$', ''
-				}
-
-				$KillTime = (Get-Date).ToUniversalTime().ToString("dd MMM yyyy HH:mm 'UTC'", [System.Globalization.CultureInfo]::InvariantCulture)
-			
-				# Get Enlisted Date
-				if ($($page1.content) -match $joinDatePattern) {
-					$joinDate = $matches[1]
-					$joinDate2 = $joinDate -replace ',', ''
-				} else {
-					$joinDate2 = "-"
-				}
-
-				# Check if there are any matches
-				If ($null -eq $page1.links[0].innerHTML) {
-					$enemyOrgs = $page1.links[4].innerHTML
-				} Else {
-					$enemyOrgs = $page1.links[3].innerHTML
-				}
-
-				if ($null -eq $enemyOrgs) {
-					$enemyOrgs = "-"
-				}
-
-				# Get UEE Number
-				if ($($page1.content) -match $ueePattern) {
-					# The matched UEE Citizen Record number is in $matches[1]
-					$citizenRecord = $matches[1]
-				} else {
-					$citizenRecord = "n/a"
-				}
-				If ($citizenRecord -eq "n/a") {
-					$citizenRecordAPI = "-1"
-					$citizenRecord = "-"
-				} Else {
-					$citizenRecordAPI = $citizenRecord
-				}
-
-				# Get PFP
-				if ($page1.images[0].src -like "/media/*") {
-					$victimPFP = "https://robertsspaceindustries.com$($page1.images[0].src)"
-				} Else {
-					$victimPFP = "https://cdn.robertsspaceindustries.com/static/images/account/avatar_default_big.jpg"
-				}
-
-				$global:killTally++
-				Write-Output "KillTally=$global:killTally"
-				Write-Output "NewKill=throwaway,$enemyPilot,$enemyShip,$enemyOrgs,$joinDate2,$citizenRecord,$killTime,$victimPFP"
-
-				$global:GameMode = $global:GameMode.ToLower()
-				# Send to API
-				# Define the data to send
-				If ($null -ne $apiUrl -and $offlineMode -eq $false){
-					$data = @{
-						victim_ship		= $enemyShip
-						victim			= $enemyPilot
-						enlisted		= $joinDate
-						rsi				= $citizenRecordAPI
-						weapon			= $weapon
-						method			= $damageType
-						loadout_ship	= $ship
-						game_version	= $global:GameVersion
-						gamemode		= $global:GameMode
-						trackr_version	= $TrackRver
-                        location        = $got_location
-					}
-
-					# Headers which may or may not be necessary
-					$headers = @{
-						"Authorization" = "Bearer $apiKey"
-						"Content-Type" = "application/json"
-						"User-Agent" = "AutoTrackR2"
-					}
-
-					try {
-						# Send the POST request with JSON data
-						$null = Invoke-RestMethod -Uri $apiURL -Method Post -Body ($data | ConvertTo-Json -Depth 5) -Headers $headers
-						$logMode = "API"
-                        $global:got_location = "NONE"
-					} catch {
-						# Catch and display errors
-						$apiError = $_
-						# Add to output file
-						$logMode = "Err-Local"
-					}
-				} Else {
-					$logMode = "Local"
-				}
-			
-				# Define the output CSV path
-				$csvPath = "$scriptFolder\Kill-log.csv"
-
-				# Create an object to hold the data
-				$killData = [PSCustomObject]@{
-					KillTime         = $killTime
-					EnemyPilot       = $enemyPilot
-					EnemyShip        = $enemyShip
-					Enlisted         = $joinDate2
-					RecordNumber     = $citizenRecord
-					OrgAffiliation   = $enemyOrgs
-					Player           = $player
-					Weapon           = $weapon
-					Ship             = $ship
-					Method           = $damageType
-					Mode             = $global:GameMode
-					GameVersion      = $global:GameVersion
-					TrackRver		 = $TrackRver
-					Logged			 = $logMode
-					PFP				 = $victimPFP
-				}
-
-				# Remove commas from all properties
-				foreach ($property in $killData.PSObject.Properties) {
-					if ($property.Value -is [string]) {
-						$property.Value = $property.Value -replace ',', ''
-					}
-				}
-
-				# Export to CSV
-				if (-Not (Test-Path $csvPath)) {
-					# If file doesn't exist, create it with headers
-					$killData | Export-Csv -Path $csvPath -NoTypeInformation
-				} else {
-					# Append data to the existing file without adding headers
-					$killData | ConvertTo-Csv -NoTypeInformation | Select-Object -Skip 1 | Out-File -Append -Encoding utf8 -FilePath $csvPath
-				}
-
-				$sleeptimer = 10
-
-				# VisorWipe
-				If ($visorwipe -eq $true -and $enemyShip -ne "Passenger" -and $damageType -notlike "*Bullet*"){
-					# send keybind for visorwipe
-					start-sleep 1
-					$sleeptimer = $sleeptimer -1
-					&"$scriptFolder\visorwipe.ahk"
-				}
-			
-				# Record video
-				if ($videoRecord -eq $true -and $enemyShip -ne "Passenger"){
-					# send keybind for windows game bar recording
-					Start-Sleep 2
-					$sleeptimer = $sleeptimer -9
-					&"$scriptFolder\videorecord.ahk"
-					Start-Sleep 7
-
-					$latestFile = Get-ChildItem -Path $videoPath | Where-Object { -not $_.PSIsContainer } | Sort-Object CreationTime -Descending | Select-Object -First 1
-					# Check if the latest file is no more than 30 seconds old
-					if ($latestFile) {
-						$fileAgeInSeconds = (New-TimeSpan -Start $latestFile.CreationTime -End (Get-Date)).TotalSeconds
-						if ($fileAgeInSeconds -le 30) {
-							# Generate a timestamp in ddMMMyyyy-HH:mm format
-							$timestamp = (Get-Date).ToString("ddMMMyyyy-HHmm")
-        
-							# Extract the file extension to preserve it
-							$fileExtension = $latestFile.Extension
-
-							# Rename the file, preserving the original file extension
-							Rename-Item -Path $latestFile.FullName -NewName "$enemyPilot.$enemyShip.$timestamp$fileExtension"
-						} else {}
-					} else {}
-				}
-				Start-Sleep $sleeptimer
-			}
-		}
-	}
-
-	# Get Logged-in User
-	If ($line -match $loginPattern) {
-		# Load gamelog into memory
-		$authLog = Get-Content -Path $logFilePath
-		$authLog = $authlog -match $loginPattern
-		$authLog = $authLog | Out-String
-
-		# Extract User Name
-		$nameExtract = "name\s+(?<PlayerName>[^\s-]+)"
-
-		If ($authLog -match $nameExtract -and $global:userName -ne $nameExtract){
-			$global:userName = $matches['PlayerName']
-			Write-Output "PlayerName=$global:userName"
-		}
-	}
-
-	# Detect PU or AC
-	if ($line -match $puPattern) {
-		$global:GameMode = "PU"
-		Write-Output "GameMode=$global:GameMode"
-	}
-	if ($line -match $acPattern) {
-		$global:GameMode = "AC"
-		Write-Output "GameMode=$global:GameMode"
-	}
-
-	#Set loadout 
-    if ($line -match $loadoutPattern) {
-            If ($matches['ShipName'] -match $cleanupPattern){
-                if ($null -ne $matches[1]){
-                    $global:loadOut = $matches[1]
-                }
-            }
-        Write-Output "PlayerShip=$global:loadOut"
-    }
-
-}
-
-
-# Monitor the log file and process new lines as they are added
-Get-Content -Path $logFilePath -Wait -Tail 0 | ForEach-Object {
-    Read-LogEntry $_
-}
-
-<#
-# Open the log file with shared access for reading and writing
-$fileStream = [System.IO.FileStream]::new($logFilePath, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read, [System.IO.FileShare]::ReadWrite)
-$reader = [System.IO.StreamReader]::new($fileStream, [System.Text.Encoding]::UTF8)  # Ensure we're reading as UTF-8
-
-try {
-    # Move to the end of the file to start monitoring new entries
-    $reader.BaseStream.Seek(0, [System.IO.SeekOrigin]::End)
-
-    while ($true) {
-        # Read the next line from the file
-        $line = $reader.ReadLine()
-
-        # Ensure we have new content to process
-        if ($line) {
-            # Process the line (this is where your log entry handler would go)
-            Read-LogEntry $line
-        }
-
-        # Sleep for a brief moment to avoid high CPU usage
-        Start-Sleep -Milliseconds 100
-    }
-}
-finally {
-    # Ensure we close the reader and file stream properly when done
-    $reader.Close()
-    $fileStream.Close()
-}
-#>
diff --git a/AutoTrackR2/LocalPlayerData.cs b/AutoTrackR2/LocalPlayerData.cs
new file mode 100644
index 0000000..668ebcd
--- /dev/null
+++ b/AutoTrackR2/LocalPlayerData.cs
@@ -0,0 +1,17 @@
+namespace AutoTrackR2;
+
+
+public enum GameMode
+{
+    ArenaCommander,
+    PersistentUniverse
+}
+
+public static class LocalPlayerData
+{
+    public static string? Username;
+    public static string? PlayerShip;
+    public static string? GameVersion;
+    public static GameMode CurrentGameMode;
+    public static string? LastSeenVehicleLocation;
+}
\ No newline at end of file
diff --git a/AutoTrackR2/LogEventHandlers/ActorDeathEvent.cs b/AutoTrackR2/LogEventHandlers/ActorDeathEvent.cs
new file mode 100644
index 0000000..5dee7f3
--- /dev/null
+++ b/AutoTrackR2/LogEventHandlers/ActorDeathEvent.cs
@@ -0,0 +1,59 @@
+using System.Text.RegularExpressions;
+
+namespace AutoTrackR2.LogEventHandlers;
+
+public struct ActorDeathData
+{
+    public string VictimPilot;
+    public string VictimShip;
+    public string Player;
+    public string Weapon;
+    public string Class;
+    public string DamageType;
+    public string Timestamp;
+}
+
+public class ActorDeathEvent : ILogEventHandler
+{
+    public Regex Pattern { get; }
+    public ActorDeathEvent()
+    {
+        Pattern = new Regex(@"<Actor Death> CActor::Kill: '(?<EnemyPilot>[^']+)' \[\d+\] in zone '(?<EnemyShip>[^']+)' killed by '(?<Player>[^']+)' \[[^']+\] using '(?<Weapon>[^']+)' \[Class (?<Class>[^\]]+)\] with damage type '(?<DamageType>[^']+)");
+    }
+    
+    Regex cleanUpPattern = new Regex(@"^(.+?)_\d+$");
+
+    public void Handle(LogEntry entry)
+    {
+        if (entry.Message is null) return;
+        
+        var match = Pattern.Match(entry.Message);
+        if (!match.Success) return;
+        
+        var data = new ActorDeathData {
+            VictimPilot = match.Groups["EnemyPilot"].Value,
+            VictimShip = match.Groups["EnemyShip"].Value,
+            Player = match.Groups["Player"].Value,
+            Weapon = match.Groups["Weapon"].Value,
+            Class = match.Groups["Class"].Value,
+            DamageType = match.Groups["DamageType"].Value,
+            Timestamp = entry.Timestamp.ToString("yyyy-MM-dd HH:mm:ss")
+        };
+        
+        if (cleanUpPattern.IsMatch(data.VictimShip))
+        {
+            data.VictimShip = cleanUpPattern.Match(data.VictimShip).Groups[1].Value;
+        }
+        
+        if (cleanUpPattern.IsMatch(data.Weapon))
+        {
+            data.Weapon = cleanUpPattern.Match(data.Weapon).Groups[1].Value;
+        }
+        
+        
+        TrackREventDispatcher.OnActorDeathEvent(data);
+        
+    }
+
+
+}
\ No newline at end of file
diff --git a/AutoTrackR2/LogEventHandlers/GameVersionEvent.cs b/AutoTrackR2/LogEventHandlers/GameVersionEvent.cs
new file mode 100644
index 0000000..abeca73
--- /dev/null
+++ b/AutoTrackR2/LogEventHandlers/GameVersionEvent.cs
@@ -0,0 +1,21 @@
+using System.Text.RegularExpressions;
+
+namespace AutoTrackR2.LogEventHandlers;
+
+public class GameVersionEvent : ILogEventHandler
+{
+    public Regex Pattern { get; }
+    
+    public GameVersionEvent()
+    {
+        Pattern = new Regex(@"--system-trace-env-id='pub-sc-alpha-(?<GameVersion>\d{3,4}-\d{7})'");
+    }
+    public void Handle(LogEntry entry)
+    {
+        if (entry.Message is null) return;
+        var match = Pattern.Match(entry.Message);
+        if (!match.Success) return;
+        
+        TrackREventDispatcher.OnGameVersionEvent(match.Groups["GameVersion"].Value);
+    }
+}
\ No newline at end of file
diff --git a/AutoTrackR2/LogEventHandlers/ILogEventHandler.cs b/AutoTrackR2/LogEventHandlers/ILogEventHandler.cs
new file mode 100644
index 0000000..adaf1ba
--- /dev/null
+++ b/AutoTrackR2/LogEventHandlers/ILogEventHandler.cs
@@ -0,0 +1,10 @@
+using System.Text.RegularExpressions;
+
+namespace AutoTrackR2.LogEventHandlers;
+
+public interface ILogEventHandler
+{ 
+    Regex Pattern { get; }
+    void Handle(LogEntry entry);
+
+}
\ No newline at end of file
diff --git a/AutoTrackR2/LogEventHandlers/InArenaCommanderEvent.cs b/AutoTrackR2/LogEventHandlers/InArenaCommanderEvent.cs
new file mode 100644
index 0000000..defdd4c
--- /dev/null
+++ b/AutoTrackR2/LogEventHandlers/InArenaCommanderEvent.cs
@@ -0,0 +1,22 @@
+using System.Text.RegularExpressions;
+
+namespace AutoTrackR2.LogEventHandlers;
+
+public class InArenaCommanderEvent : ILogEventHandler
+{
+    public Regex Pattern { get; }
+    
+    public InArenaCommanderEvent()
+    {
+        Pattern = new Regex("Requesting Mode Change");
+    }
+    
+    public void Handle(LogEntry entry)
+    {
+        if (entry.Message is null) return;
+        var match = Pattern.Match(entry.Message);
+        if (!match.Success) return;
+        
+        TrackREventDispatcher.OnPlayerChangedGameModeEvent(GameMode.ArenaCommander);
+    }
+}
\ No newline at end of file
diff --git a/AutoTrackR2/LogEventHandlers/InPersistentUniverseEvent.cs b/AutoTrackR2/LogEventHandlers/InPersistentUniverseEvent.cs
new file mode 100644
index 0000000..2f7c53e
--- /dev/null
+++ b/AutoTrackR2/LogEventHandlers/InPersistentUniverseEvent.cs
@@ -0,0 +1,22 @@
+using System.Text.RegularExpressions;
+
+namespace AutoTrackR2.LogEventHandlers;
+
+public class InPersistentUniverseEvent : ILogEventHandler
+{
+    public Regex Pattern { get; }
+    
+    public InPersistentUniverseEvent()
+    {
+        Pattern = new Regex(@"<\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z> \[Notice\] <ContextEstablisherTaskFinished> establisher=""CReplicationModel"" message=""CET completed"" taskname=""StopLoadingScreen"" state=[^\s()]+\(\d+\) status=""Finished"" runningTime=\d+\.\d+ numRuns=\d+ map=""megamap"" gamerules=""SC_Default"" sessionId=""[a-f0-9\-]+"" \[Team_Network\]\[Network\]\[Replication\]\[Loading\]\[Persistence\]");
+    }
+    
+    public void Handle(LogEntry entry)
+    {
+        if (entry.Message is null) return;
+        var match = Pattern.Match(entry.Message);
+        if (!match.Success) return;
+        
+        TrackREventDispatcher.OnPlayerChangedGameModeEvent(GameMode.PersistentUniverse);
+    }
+}
\ No newline at end of file
diff --git a/AutoTrackR2/LogEventHandlers/InstancedInteriorEvent.cs b/AutoTrackR2/LogEventHandlers/InstancedInteriorEvent.cs
new file mode 100644
index 0000000..62ab732
--- /dev/null
+++ b/AutoTrackR2/LogEventHandlers/InstancedInteriorEvent.cs
@@ -0,0 +1,77 @@
+using System.Text.RegularExpressions;
+
+namespace AutoTrackR2.LogEventHandlers;
+
+public struct InstancedInteriorData
+{
+    public string Entity;
+    public string OwnerGEID;
+    public string ManagerGEID;
+    public string InstancedInterior;
+    public string? Ship;
+}
+
+// A ship loadout has been changed
+public class InstancedInteriorEvent : ILogEventHandler
+{
+    public Regex Pattern { get; }
+
+    private Regex _shipManufacturerPattern;
+    private Regex _cleanUpPattern = new Regex(@"(.+?)_\d+$");
+    
+    private List<string> _shipManufacturers = new List<string>
+    {
+        "ORIG",
+        "CRUS",
+        "RSI",
+        "AEGS",
+        "VNCL",
+        "DRAK",
+        "ANVL",
+        "BANU",
+        "MISC",
+        "CNOU",
+        "XIAN",
+        "GAMA",
+        "TMBL",
+        "ESPR",
+        "KRIG",
+        "GRIN",
+        "XNAA",
+        "MRAI"
+    };
+    
+    public InstancedInteriorEvent()
+    {
+        Pattern = new Regex(@"\[InstancedInterior\] OnEntityLeaveZone - InstancedInterior \[(?<InstancedInterior>[^\]]+)\] \[\d+\] -> Entity \[(?<Entity>[^\]]+)\] \[\d+\] -- m_openDoors\[\d+\], m_managerGEID\[(?<ManagerGEID>\d+)\], m_ownerGEID\[(?<OwnerGEID>[^\[]+)\]");
+        _shipManufacturerPattern = new Regex($"^({string.Join("|", _shipManufacturers)})");
+    }
+
+    public void Handle(LogEntry entry)
+    {
+        if (entry.Message is null) return;
+        var match = Pattern.Match(entry.Message);
+        if (!match.Success) return;
+        
+        var data = new InstancedInteriorData {
+            Entity = match.Groups["Entity"].Value,
+            OwnerGEID = match.Groups["OwnerGEID"].Value,
+            ManagerGEID = match.Groups["ManagerGEID"].Value,
+            InstancedInterior = match.Groups["InstancedInterior"].Value,
+        };
+        
+        match = _shipManufacturerPattern.Match(data.Entity);
+        if (match.Success)
+        {
+            match = _cleanUpPattern.Match(data.Entity);
+            if (match.Success)
+            {
+                data.Ship = match.Groups[1].Value;
+            }
+        }
+        
+        TrackREventDispatcher.OnInstancedInteriorEvent(data);
+        
+    }
+
+}
\ No newline at end of file
diff --git a/AutoTrackR2/LogEventHandlers/JumpDriveStateChangedEvent.cs b/AutoTrackR2/LogEventHandlers/JumpDriveStateChangedEvent.cs
new file mode 100644
index 0000000..9955f7f
--- /dev/null
+++ b/AutoTrackR2/LogEventHandlers/JumpDriveStateChangedEvent.cs
@@ -0,0 +1,27 @@
+using System.Text.RegularExpressions;
+
+namespace AutoTrackR2.LogEventHandlers;
+
+public class JumpDriveStateChangedEvent : ILogEventHandler
+{
+    public Regex Pattern { get; }
+    private Regex _cleanUpPattern = new Regex(@"(.+?)_\d+$");
+    
+    public JumpDriveStateChangedEvent()
+    {
+        Pattern = new Regex(@"<Jump Drive State Changed>.*.adam: (?<ShipName>.*.) in");
+    }
+    
+    public void Handle(LogEntry entry)
+    {
+        if (entry.Message is null) return;
+        var match = Pattern.Match(entry.Message);
+        if (!match.Success) return;
+        
+        match = _cleanUpPattern.Match(match.Groups["ShipName"].Value);
+        if (match.Success)
+        {
+            TrackREventDispatcher.OnJumpDriveStateChangedEvent(match.Groups[1].Value);;
+        }
+    }
+}
\ No newline at end of file
diff --git a/AutoTrackR2/LogEventHandlers/LoginEvent.cs b/AutoTrackR2/LogEventHandlers/LoginEvent.cs
new file mode 100644
index 0000000..e6f9cc4
--- /dev/null
+++ b/AutoTrackR2/LogEventHandlers/LoginEvent.cs
@@ -0,0 +1,24 @@
+using System.Text.RegularExpressions;
+
+namespace AutoTrackR2.LogEventHandlers;
+
+// Local player has logged in
+public class LoginEvent : ILogEventHandler
+{
+    public Regex Pattern { get; }
+    
+    public LoginEvent()
+    {
+        Pattern = new Regex(@"\[Notice\] <Legacy login response> \[CIG-net\] User Login Success - Handle\[(?<Player>[A-Za-z0-9_-]+)\]");
+    }
+    
+    public void Handle(LogEntry entry)
+    {
+        if (entry.Message is null) return;
+        
+        var match = Pattern.Match(entry.Message);
+        if (!match.Success) return;
+
+        TrackREventDispatcher.OnPlayerLoginEvent(match.Groups["Player"].Value);
+    }
+}
\ No newline at end of file
diff --git a/AutoTrackR2/LogEventHandlers/RequestJumpFailedEvent.cs b/AutoTrackR2/LogEventHandlers/RequestJumpFailedEvent.cs
new file mode 100644
index 0000000..c998685
--- /dev/null
+++ b/AutoTrackR2/LogEventHandlers/RequestJumpFailedEvent.cs
@@ -0,0 +1,27 @@
+using System.Text.RegularExpressions;
+
+namespace AutoTrackR2.LogEventHandlers;
+
+public class RequestJumpFailedEvent : ILogEventHandler
+{
+    public Regex Pattern { get; }
+    private Regex _cleanUpPattern = new Regex(@"(.+?)_\d+$");
+    
+    public RequestJumpFailedEvent()
+    {
+        Pattern = new Regex(@"<Request Jump Failed>.*.adam: (?<ShipName>.*.) in");
+    }
+    
+    public void Handle(LogEntry entry)
+    {
+        if (entry.Message is null) return;
+        var match = Pattern.Match(entry.Message);
+        if (!match.Success) return;
+        
+        match = _cleanUpPattern.Match(match.Groups["ShipName"].Value);
+        if (match.Success)
+        {
+            TrackREventDispatcher.OnJumpDriveStateChangedEvent(match.Groups[1].Value);;
+        }
+    }
+}
\ No newline at end of file
diff --git a/AutoTrackR2/LogEventHandlers/VehicleDestructionEvent.cs b/AutoTrackR2/LogEventHandlers/VehicleDestructionEvent.cs
new file mode 100644
index 0000000..041859a
--- /dev/null
+++ b/AutoTrackR2/LogEventHandlers/VehicleDestructionEvent.cs
@@ -0,0 +1,59 @@
+using System.Text.RegularExpressions;
+
+namespace AutoTrackR2.LogEventHandlers;
+
+public struct VehicleDestructionData
+{
+    public string Vehicle { get; set; }
+    public string VehicleZone { get; set; }
+    public float PosX { get; set; }
+    public float PosY { get; set; }
+    public float PosZ { get; set; }
+    public string Driver { get; set; }
+    public int DestroyLevelFrom { get; set; }
+    public int DestroyLevelTo { get; set; }
+    public string CausedBy { get; set; }
+    public string DamageType { get; set; }
+}
+
+public class VehicleDestructionEvent : ILogEventHandler
+{
+    public Regex Pattern { get; }
+    
+    public VehicleDestructionEvent()
+    {
+        Pattern = new Regex("""
+                            "<(?<timestamp>[^>]+)> \[Notice\] <Vehicle Destruction> CVehicle::OnAdvanceDestroyLevel: " +
+                            "Vehicle '(?<vehicle>[^']+)' \[\d+\] in zone '(?<vehicle_zone>[^']+)' " +
+                            "\[pos x: (?<pos_x>[-\d\.]+), y: (?<pos_y>[-\d\.]+), z: (?<pos_z>[-\d\.]+) " +
+                            "vel x: [^,]+, y: [^,]+, z: [^\]]+\] driven by '(?<driver>[^']+)' \[\d+\] " +
+                            "advanced from destroy level (?<destroy_level_from>\d+) to (?<destroy_level_to>\d+) " +
+                            "caused by '(?<caused_by>[^']+)' \[\d+\] with '(?<damage_type>[^']+)'"
+                            """);
+    }
+
+    public void Handle(LogEntry entry)
+    {
+        var match = Pattern.Match(entry.Message);
+        if (!match.Success)
+        {
+            return;
+        }
+
+        var data = new VehicleDestructionData
+        {
+            Vehicle = match.Groups["vehicle"].Value,
+            VehicleZone = match.Groups["vehicle_zone"].Value,
+            PosX = float.Parse(match.Groups["pos_x"].Value),
+            PosY = float.Parse(match.Groups["pos_y"].Value),
+            PosZ = float.Parse(match.Groups["pos_z"].Value),
+            Driver = match.Groups["driver"].Value,
+            DestroyLevelFrom = int.Parse(match.Groups["destroy_level_from"].Value),
+            DestroyLevelTo = int.Parse(match.Groups["destroy_level_to"].Value),
+            CausedBy = match.Groups["caused_by"].Value,
+            DamageType = match.Groups["damage_type"].Value,
+        };
+
+        TrackREventDispatcher.OnVehicleDestructionEvent(data);
+    }
+}
\ No newline at end of file
diff --git a/AutoTrackR2/LogHandler.cs b/AutoTrackR2/LogHandler.cs
new file mode 100644
index 0000000..38ddd6e
--- /dev/null
+++ b/AutoTrackR2/LogHandler.cs
@@ -0,0 +1,151 @@
+using System.Diagnostics;
+using System.IO;
+using System.Text.RegularExpressions;
+using AutoTrackR2.LogEventHandlers;
+
+namespace AutoTrackR2;
+
+
+// Represents a single log entry
+// This is the object that will be passed to each handler, mostly for convenience
+public class LogEntry
+{
+    public DateTime Timestamp { get; set; }
+    public required string? Message { get; set; }
+    
+}
+
+enum GameProcessState
+{
+    NotRunning,
+    Running,
+    Unknown
+}
+
+public class LogHandler(string logPath)
+{
+    private readonly string? _logPath = logPath;
+    private FileStream? _fileStream;
+    private StreamReader? _reader;
+    private GameProcessState _gameProcessState = GameProcessState.Unknown;
+
+    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 = [
+        new LoginEvent(),
+        new InstancedInteriorEvent(),
+        new InArenaCommanderEvent(),
+        new InPersistentUniverseEvent(),
+        new GameVersionEvent(),
+        new JumpDriveStateChangedEvent(),
+        new RequestJumpFailedEvent()
+    ];
+
+    // Initialize the LogHandler and run all startup handlers
+    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);
+        }
+
+        // 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();
+    }
+
+    public void Stop()
+    {
+        // Stop the monitor thread
+        cancellationToken?.Cancel();
+        _reader?.Close();
+        _fileStream?.Close();
+    }
+    
+    // Parse a single line of the log file and run matching handlers
+    private void HandleLogEntry(string line)
+    {
+        // Console.WriteLine(line);
+        foreach (var handler in _eventHandlers)
+        {
+            var match = handler.Pattern.Match(line);
+            if (!match.Success) continue;
+            
+            var entry = new LogEntry
+            {
+                Timestamp = DateTime.Now,
+                Message = line
+            };
+            handler.Handle(entry);
+            break;
+        }
+    }
+    
+    private void MonitorLog(CancellationToken token)
+    {
+        while (!token.IsCancellationRequested)
+        {
+            if (_reader == null || _fileStream == null)
+            {
+                break;
+            }
+            
+            CheckGameProcessState();
+            
+            List<string> lines = new List<string>();
+            while (_reader.ReadLine() is { } line)
+            {
+                lines.Add(line);
+            }
+
+            foreach (var line in lines)
+            {
+                // start new thread to handle log entry
+                var thread = new Thread(() => HandleLogEntry(line));
+                thread.Start();
+                // Console.WriteLine(line);
+            }
+
+            {
+                // Wait for new lines to be written to the log file
+                Thread.Sleep(1000);
+            }
+        }
+        Console.WriteLine("Monitor thread stopped");
+    }
+
+    private void CheckGameProcessState()
+    {
+        // 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 e432e97..637e90f 100644
--- a/AutoTrackR2/MainWindow.xaml.cs
+++ b/AutoTrackR2/MainWindow.xaml.cs
@@ -1,4 +1,6 @@
 //using System.Collections.Generic;
+
+using System.Diagnostics;
 using System.Windows;
 using System.Windows.Controls;
 using System.Windows.Input;
@@ -33,9 +35,6 @@ namespace AutoTrackR2
         {
             InitializeComponent();
 
-            // Load configuration settings before setting them in any page
-            ConfigManager.LoadConfig();
-
             homePage = new HomePage(); // Create a single instance of HomePage
             ContentControl.Content = homePage; // Default to HomePage
 
@@ -195,6 +194,13 @@ namespace AutoTrackR2
     public static class ConfigManager
     {
         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; }
@@ -202,6 +208,27 @@ 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(
+                Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
+                "AutoTrackR2",
+                "Kill-log.csv"
+            );
+            
+            AHKScriptFolder = Path.Combine(
+                Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
+                "AutoTrackR2"
+            );
+            
+            VisorWipeScript = "visorwipe.ahk";
+            VideoRecordScript = "videorecord.ahk";
+        }
 
         public static void LoadConfig()
         {
@@ -241,7 +268,7 @@ namespace AutoTrackR2
             // Define the config file path in a writable location
             string configDirectory = Path.Combine(
                 Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
-                "YourAppName"
+                "AutoTrackR2"
             );
 
             // Ensure the directory exists
diff --git a/AutoTrackR2/TrackREventDispatcher.cs b/AutoTrackR2/TrackREventDispatcher.cs
new file mode 100644
index 0000000..9aaab03
--- /dev/null
+++ b/AutoTrackR2/TrackREventDispatcher.cs
@@ -0,0 +1,57 @@
+using AutoTrackR2.LogEventHandlers;
+
+namespace AutoTrackR2;
+
+public static class TrackREventDispatcher
+{
+    // Local Player Login
+    public static event Action<string>? PlayerLoginEvent;
+    public static void OnPlayerLoginEvent(string playerName)
+    {
+        PlayerLoginEvent?.Invoke(playerName);
+    }
+
+    // An instanced interior has changed
+    // Example: Player enters/leaves a ship
+    public static event Action<InstancedInteriorData>? InstancedInteriorEvent;
+    public static void OnInstancedInteriorEvent(InstancedInteriorData data)
+    {
+        InstancedInteriorEvent?.Invoke(data);
+    }
+    
+    // Player changed GameMode (AC or PU)
+    public static event Action<GameMode>? PlayerChangedGameModeEvent;
+    public static void OnPlayerChangedGameModeEvent(GameMode mode)
+    {
+        PlayerChangedGameModeEvent?.Invoke(mode);
+    }
+    
+    // Game version has been detected
+    public static event Action<string>? GameVersionEvent;
+    public static void OnGameVersionEvent(string value)
+    {
+        GameVersionEvent?.Invoke(value);
+    }
+    
+    // Actor has died
+    public static event Action<ActorDeathData>? ActorDeathEvent;
+    public static void OnActorDeathEvent(ActorDeathData data)
+    {
+        ActorDeathEvent?.Invoke(data);
+    }
+    
+    // Vehicle has been destroyed
+    public static event Action<VehicleDestructionData>? VehicleDestructionEvent;
+    public static void OnVehicleDestructionEvent(VehicleDestructionData data)
+    {
+        VehicleDestructionEvent?.Invoke(data);
+    }
+    
+    // Jump Drive state has changed
+    // Todo: Add proper data for this event. Right now only ship name is used.
+    public static event Action<string>? JumpDriveStateChangedEvent;
+    public static void OnJumpDriveStateChangedEvent(string shipName)
+    {
+        JumpDriveStateChangedEvent?.Invoke(shipName);
+    }
+}
\ No newline at end of file
diff --git a/AutoTrackR2/UpdatePage.xaml.cs b/AutoTrackR2/UpdatePage.xaml.cs
index 0d834fd..87b260e 100644
--- a/AutoTrackR2/UpdatePage.xaml.cs
+++ b/AutoTrackR2/UpdatePage.xaml.cs
@@ -9,7 +9,7 @@ namespace AutoTrackR2
 {
     public partial class UpdatePage : UserControl
     {
-        private string currentVersion = "v2.08";
+        public static string currentVersion = "v2.09";
         private string latestVersion;
 
         public UpdatePage()
diff --git a/AutoTrackR2/Util.cs b/AutoTrackR2/Util.cs
new file mode 100644
index 0000000..b5931de
--- /dev/null
+++ b/AutoTrackR2/Util.cs
@@ -0,0 +1,31 @@
+namespace AutoTrackR2;
+
+// Data returned from the CIG API
+public struct PlayerData
+{
+    public string? PFPURL;
+    public string? UEERecord;
+    public string? OrgURL;
+    public string? OrgName;
+    public string? JoinDate;
+}
+
+// Amalgamation of all data from a single kill
+public struct KillData
+{
+    public string? KillTime;
+    public string? EnemyPilot;
+    public string? EnemyShip;
+    public string? Enlisted;
+    public string? RecordNumber;
+    public string? OrgAffiliation;
+    public string? Player;
+    public string? Weapon;
+    public string? Ship;
+    public string? Method;
+    public string? Mode;
+    public string? GameVersion;
+    public string? TrackRver;
+    public string? Logged;
+    public string? PFP;
+}
\ No newline at end of file
diff --git a/AutoTrackR2/WebHandler.cs b/AutoTrackR2/WebHandler.cs
new file mode 100644
index 0000000..2d8ad59
--- /dev/null
+++ b/AutoTrackR2/WebHandler.cs
@@ -0,0 +1,122 @@
+using System.Net;
+using System.Net.Http;
+using System.Text;
+using System.Text.Json;
+using System.Text.RegularExpressions;
+using AutoTrackR2.LogEventHandlers;
+
+namespace AutoTrackR2;
+
+public static class WebHandler
+{
+    class APIKillData
+    {
+            public string? victim_ship { get; set; }
+            public string? victim{ get; set; }
+            public string? enlisted{ get; set; }
+            public string? rsi{ get; set; }
+            public string? weapon{ get; set; }
+            public string? method{ get; set; }
+            public string? loadout_ship{ get; set; }
+            public string? game_version{ get; set; }
+            public string? gamemode{ get; set; }
+            public string? trackr_version{ get; set; }
+            public string? location{ get; set; }
+    }
+
+    public static async Task<PlayerData?> GetPlayerData(string enemyPilot)
+    {
+        var joinDataPattern = new Regex("<span class=\"label\">Enlisted</span>\\s*<strong class=\"value\">([^<]+)</strong>");
+        var ueePattern = new Regex("<p class=\"entry citizen-record\">\\n.*.<span class=\"label\">UEE Citizen Record<\\/span>\\n.*.<strong class=\"value\">#(?<UEERecord>\\d+)<\\/strong>");
+        var orgPattern = new Regex("\\/orgs\\/(?<OrgURL>[A-z0-9]+)\" .*\\>(?<OrgName>.*)<");
+        var pfpPattern = new Regex("/media/(.*)\"");
+       
+        // Make web request to check player data
+        var playerData = new PlayerData();
+        var httpClient = new HttpClient();
+        var response = await httpClient.GetAsync($"https://robertsspaceindustries.com/en/citizens/{enemyPilot}");
+        
+        if (response.StatusCode != HttpStatusCode.OK)
+        {
+            return null;
+        }
+
+        var content = await response.Content.ReadAsStringAsync();
+        var joinDataMatch = joinDataPattern.Match(content);
+        if (joinDataMatch.Success)
+        {
+            playerData.JoinDate = joinDataMatch.Groups[1].Value;
+        }
+        
+        var ueeMatch = ueePattern.Match(content);
+        if (ueeMatch.Success)
+        {
+            playerData.UEERecord = ueeMatch.Groups["UEERecord"].Value == "n/a" ? "-1" : ueeMatch.Groups[1].Value;
+        }
+        
+        var orgMatch = orgPattern.Match(content);
+        if (orgMatch.Success)
+        {
+            playerData.OrgName = orgMatch.Groups["OrgName"].Value;
+            playerData.OrgURL = "https://robertsspaceindustries.com/en/orgs/" + orgMatch.Groups["OrgURL"].Value;
+        }
+        
+        var pfpMatch = pfpPattern.Match(content);
+        if (pfpMatch.Success)
+        {
+            var match = pfpMatch.Groups[1].Value;
+            if (match.Contains("heap_thumb"))
+            {
+                playerData.PFPURL = "https://cdn.robertsspaceindustries.com/static/images/account/avatar_default_big.jpg";
+            }
+            else
+            {
+                playerData.PFPURL = "https://robertsspaceindustries.com/media/" + pfpMatch.Groups[1].Value;
+            }
+        }
+
+        return playerData;
+    }
+    
+    public static async Task SubmitKill(KillData killData)
+    {
+        // int secondSpaceIndex = killData.Enlisted.IndexOf(" ", killData.Enlisted.IndexOf(" ") + 1);
+        // killData.Enlisted = killData.Enlisted.Insert(secondSpaceIndex, ",");
+        var apiKillData = new APIKillData
+        {
+            victim_ship = killData.EnemyShip,
+            victim = killData.EnemyPilot,
+            enlisted = killData.Enlisted,
+            rsi = killData.RecordNumber,
+            weapon = killData.Weapon,
+            method = killData.Method,
+            gamemode = killData.Mode,
+            // loadout_ship = LocalPlayerData.PlayerShip ?? "Unknown",
+            loadout_ship = killData.Ship,
+            game_version = killData.GameVersion,
+            trackr_version = killData.TrackRver,
+            location = "Unknown"
+        };
+        
+        if (string.IsNullOrEmpty(apiKillData.rsi))
+        {
+            apiKillData.rsi = "-1";
+        }
+        
+        var httpClient = new HttpClient();
+        string jsonData = JsonSerializer.Serialize(apiKillData);
+        httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + ConfigManager.ApiKey);
+        httpClient.DefaultRequestHeaders.Add("User-Agent", "AutoTrackR2");
+        httpClient.DefaultRequestHeaders.Add("Accept", "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: ");
+            Console.WriteLine(jsonData);
+        }
+        else if (response.StatusCode == HttpStatusCode.OK)
+        {
+            Console.WriteLine("Successfully submitted kill data");
+        }
+    }
+}
\ No newline at end of file