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..937fe68 100644
--- a/AutoTrackR2/ConfigPage.xaml
+++ b/AutoTrackR2/ConfigPage.xaml
@@ -1,7 +1,7 @@
 <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 -->
@@ -23,51 +23,58 @@
             <StackPanel Grid.Column="0" VerticalAlignment="Center" Height="389">
                 <!-- Log File -->
                 <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="340" Height="30" Style="{StaticResource RoundedTextBox}"/>
+                        <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="ⓘ" 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="340" Height="30" Style="{StaticResource RoundedTextBox}"/>
+                        <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="ⓘ" 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"/>
-                    <TextBox Name="ApiKey" Width="340" Height="30" Margin="33,0,0,0" Style="{StaticResource RoundedTextBox}"/>
+                    <TextBox Name="ApiKey" Width="330" Height="30" Margin="33,0,0,0" Style="{StaticResource RoundedTextBox}"/>
                 </StackPanel>
 
                 <!-- Video Path -->
                 <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}"/>
+                        <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="ⓘ" 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="ⓘ" 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">
+                <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>
diff --git a/AutoTrackR2/ConfigPage.xaml.cs b/AutoTrackR2/ConfigPage.xaml.cs
index 5e7f366..f718aed 100644
--- a/AutoTrackR2/ConfigPage.xaml.cs
+++ b/AutoTrackR2/ConfigPage.xaml.cs
@@ -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.Text;
+            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()
diff --git a/AutoTrackR2/HomePage.xaml.cs b/AutoTrackR2/HomePage.xaml.cs
index ccd42ab..cd264e6 100644
--- a/AutoTrackR2/HomePage.xaml.cs
+++ b/AutoTrackR2/HomePage.xaml.cs
@@ -5,38 +5,31 @@ using System.Windows.Media;
 using System.Windows.Media.Effects;
 using System.Windows.Documents;
 using System.Globalization;
+using System.IO;
+using System.Text;
 using System.Windows.Media.Imaging;
 using AutoTrackR2.LogEventHandlers;
 
 namespace AutoTrackR2;
 
-public struct PlayerData
-{
-    public string? PFPURL;
-    public string? UEERecord;
-    public string? OrgURL;
-    public string? OrgName;
-    public string? JoinDate;
-}
-
 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()
     {
         InitializeComponent();
-
-        // Get the current month
-        string currentMonth = DateTime.Now.ToString("MMMM", CultureInfo.InvariantCulture);
+        
+        _killHistoryManager = new KillHistoryManager(ConfigManager.KillHistoryFile);
 
         // Set the TextBlock text
-        KillTallyTitle.Text = $"Kill Tally - {currentMonth}";
+        KillTallyTitle.Text = $"Kill Tally - {_killHistoryManager.GetKillsInCurrentMonth().Count}";
+        AddKillHistoryKillsToUI();
     }
-
-    private Process runningProcess; // Field to store the running process
-    private LogHandler _logHandler;
-    private bool _UIEventsRegistered = false;
-
-
+    
     // Update Start/Stop button states based on the isRunning flag
     public void UpdateButtonState(bool isRunning)
     {
@@ -88,6 +81,16 @@ public partial class HomePage : UserControl
         // _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)
+        {
+            Dispatcher.Invoke(() => { AddKillToScreen(kill); });
+        }
     }
 
     private void RegisterUIEventHandlers()
@@ -134,15 +137,38 @@ public partial class HomePage : UserControl
         };
         
         // Actor Death
-        TrackREventDispatcher.ActorDeathEvent += async (data) => {
-            if (data.VictimPilot != LocalPlayerData.Username)
+        TrackREventDispatcher.ActorDeathEvent += async (actorDeathData) => {
+            if (actorDeathData.VictimPilot != LocalPlayerData.Username)
             {
-                var playerData = await WebHandler.GetPlayerData(data.VictimPilot);
+                var playerData = await WebHandler.GetPlayerData(actorDeathData.VictimPilot);
 
                 if (playerData != null)
                 {
-                    Dispatcher.Invoke(() => { AddKillToScreen(data, playerData); });
-                    await WebHandler.SubmitKill(data, playerData);
+                    var killData = new KillData
+                    {
+                        EnemyPilot = actorDeathData.VictimPilot,
+                        EnemyShip = actorDeathData.VictimShip,
+                        OrgAffiliation = playerData?.OrgName,
+                        Enlisted = playerData?.JoinDate,
+                        KillTime = DateTime.UtcNow.ToString("dd MMM yyyy HH:mm"),
+                        PFP = playerData?.PFPURL
+                    };
+                    
+                    // Add kill to UI
+                    Dispatcher.Invoke(() =>
+                    {
+                        AddKillToScreen(killData);
+                    });
+    
+                    // Only submit kill data if not in offline mode
+                    if (ConfigManager.OfflineMode == 0)
+                    {
+                        await WebHandler.SubmitKill(actorDeathData, playerData);
+                    }
+
+                    _killHistoryManager.AddKill(killData);
+                    VisorWipe();
+                    VideoRecord();
                 }
             }
         };
@@ -155,7 +181,7 @@ public partial class HomePage : UserControl
         _UIEventsRegistered = true;
     }
 
-    private void AddKillToScreen(ActorDeathData deathData, PlayerData? playerData)
+    private void AddKillToScreen(KillData killData)
     { 
         // Fetch the dynamic resource for AltTextColor
         var altTextColorBrush = new SolidColorBrush((Color)Application.Current.Resources["AltTextColor"]);
@@ -181,7 +207,7 @@ public partial class HomePage : UserControl
             Foreground = altTextColorBrush,
             FontFamily = orbitronFontFamily,
         });
-        killTextBlock.Inlines.Add(new Run($"{deathData.VictimPilot}\n"));
+        killTextBlock.Inlines.Add(new Run($"{killData.EnemyPilot}\n"));
 
         // Repeat for other lines
         killTextBlock.Inlines.Add(new Run("Victim Ship: ")
@@ -189,21 +215,21 @@ public partial class HomePage : UserControl
             Foreground = altTextColorBrush,
             FontFamily = orbitronFontFamily,
         });
-        killTextBlock.Inlines.Add(new Run($"{deathData.VictimShip}\n"));
+        killTextBlock.Inlines.Add(new Run($"{killData.EnemyShip}\n"));
 
         killTextBlock.Inlines.Add(new Run("Victim Org: ")
         {
             Foreground = altTextColorBrush,
             FontFamily = orbitronFontFamily,
         });
-        killTextBlock.Inlines.Add(new Run($"{playerData?.OrgName}\n"));
+        killTextBlock.Inlines.Add(new Run($"{killData.OrgAffiliation}\n"));
         
         killTextBlock.Inlines.Add(new Run("Join Date: ")
         {
             Foreground = altTextColorBrush,
             FontFamily = orbitronFontFamily,
         });
-        killTextBlock.Inlines.Add(new Run($"{playerData?.JoinDate}\n"));
+        killTextBlock.Inlines.Add(new Run($"{killData.Enlisted}\n"));
         
         killTextBlock.Inlines.Add(new Run("UEE Record: ")
         {
@@ -211,16 +237,12 @@ public partial class HomePage : UserControl
             FontFamily = orbitronFontFamily,
         });
         
-        
-        const string dateFormatString = "dd MMM yyyy HH:mm";
-        var currentTime = DateTime.UtcNow.ToString(dateFormatString);
-        
         killTextBlock.Inlines.Add(new Run("Kill Time: ")
         {
             Foreground = altTextColorBrush,
             FontFamily = orbitronFontFamily,
         });
-        killTextBlock.Inlines.Add(new Run($"{currentTime}"));
+        killTextBlock.Inlines.Add(new Run($"{killData.KillTime}"));
 
         // Create a Border and apply the RoundedTextBlockWithBorder style
         var killBorder = new Border
@@ -246,7 +268,7 @@ public partial class HomePage : UserControl
         // Create the Image for the profile
         var profileImage = new Image
         {
-            Source = new BitmapImage(new Uri(playerData?.PFPURL)), // Assuming the 8th part contains the profile image URL
+            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
@@ -279,15 +301,15 @@ public partial class HomePage : UserControl
 
     public void StopButton_Click(object sender, RoutedEventArgs e)
     {
-        _logHandler.Stop();
+        _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();
+        // 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)
@@ -328,4 +350,39 @@ public partial class HomePage : UserControl
         // 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();
+    }
+
+    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..fd07f2e
--- /dev/null
+++ b/AutoTrackR2/KillHistoryManager.cs
@@ -0,0 +1,83 @@
+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);
+        }
+        
+        // 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}\"");
+        File.AppendAllText(_killHistoryPath, csv.ToString());
+    }
+    
+    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 26f0ed2..0000000
--- a/AutoTrackR2/KillTrackR_MainScript.ps1
+++ /dev/null
@@ -1,516 +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\]'
-$acPattern =  "Requesting Mode Change"  # "ArenaCommanderFeature"
-$loadoutPattern = '\[InstancedInterior\] OnEntityLeaveZone - InstancedInterior \[(?<InstancedInterior>[^\]]+)\] \[\d+\] -> Entity \[(?<Entity>[^\]]+)\] \[\d+\] -- m_openDoors\[\d+\], m_managerGEID\[(?<ManagerGEID>\d+)\], m_ownerGEID\[(?<OwnerGEID>[^\[]+)\]'
-$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) {
-			$entity = $matches['Entity']
-			$ownerGEID = $matches['OwnerGEID']
-
-			If ($ownerGEID -eq $global:userName -and $entity -match $shipManPattern) {
-				$tryloadOut = $entity
-				If ($tryloadOut -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"
-				}
-				If ($ship -match $cleanupPattern){
-					$ship = $matches[1]
-				}
-				if ($ship -notmatch $shipManPattern){
-					$ship = "Player"
-				}
-				If ($enemyShip -notmatch $shipManPattern -and $enemyShip -notlike "Passenger" ) {
-					$enemyShip = "Player"
-				}
-			
-				# 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) {
-		$entity = $matches['Entity']
-		$ownerGEID = $matches['OwnerGEID']
-
-        If ($ownerGEID -eq $global:userName -and $entity -match $shipManPattern) {
-			$tryloadOut = $entity
-			If ($tryloadOut -match $cleanupPattern){
-				$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/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/UpdatePage.xaml.cs b/AutoTrackR2/UpdatePage.xaml.cs
index 75d9e70..87b260e 100644
--- a/AutoTrackR2/UpdatePage.xaml.cs
+++ b/AutoTrackR2/UpdatePage.xaml.cs
@@ -9,7 +9,7 @@ namespace AutoTrackR2
 {
     public partial class UpdatePage : UserControl
     {
-        public static 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