From d6ce48b47538ff53db79f6ba61426f10fc0bc1c4 Mon Sep 17 00:00:00 2001 From: Dork Normalize <nope> Date: Fri, 28 Mar 2025 17:01:03 -0700 Subject: [PATCH] Implement KillHistory CSV functionality --- AutoTrackR2/HomePage.xaml.cs | 98 ++++++++++++++++++------------- AutoTrackR2/KillHistoryManager.cs | 83 ++++++++++++++++++++++++++ AutoTrackR2/MainWindow.xaml.cs | 12 ++++ AutoTrackR2/Util.cs | 31 ++++++++++ 4 files changed, 182 insertions(+), 42 deletions(-) create mode 100644 AutoTrackR2/KillHistoryManager.cs create mode 100644 AutoTrackR2/Util.cs diff --git a/AutoTrackR2/HomePage.xaml.cs b/AutoTrackR2/HomePage.xaml.cs index ccd42ab..fe47e59 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) { @@ -89,6 +82,15 @@ public partial class HomePage : UserControl _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 +136,31 @@ 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); + }); + + await WebHandler.SubmitKill(actorDeathData, playerData); + _killHistoryManager.AddKill(killData); } } }; @@ -155,7 +173,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 +199,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 +207,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 +229,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 +260,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 +293,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) 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/MainWindow.xaml.cs b/AutoTrackR2/MainWindow.xaml.cs index e432e97..3d143d0 100644 --- a/AutoTrackR2/MainWindow.xaml.cs +++ b/AutoTrackR2/MainWindow.xaml.cs @@ -195,6 +195,7 @@ namespace AutoTrackR2 public static class ConfigManager { public static string LogFile { get; set; } + public static string KillHistoryFile { get; set; } public static string ApiUrl { get; set; } public static string ApiKey { get; set; } public static string VideoPath { get; set; } @@ -202,6 +203,17 @@ namespace AutoTrackR2 public static int VideoRecord { get; set; } public static int OfflineMode { get; set; } public static int Theme { get; set; } + + static ConfigManager() + { + // Set default values + // AppData\Local\AutoTrackR2\Kill-log.csv + KillHistoryFile = Path.Combine( + Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), + "AutoTrackR2", + "Kill-log.csv" + ); + } public static void LoadConfig() { 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