Implement KillHistory CSV functionality

This commit is contained in:
Dork Normalize 2025-03-28 17:01:03 -07:00
parent c6e6a7e6bd
commit d6ce48b475
4 changed files with 182 additions and 42 deletions

View file

@ -5,38 +5,31 @@ using System.Windows.Media;
using System.Windows.Media.Effects; using System.Windows.Media.Effects;
using System.Windows.Documents; using System.Windows.Documents;
using System.Globalization; using System.Globalization;
using System.IO;
using System.Text;
using System.Windows.Media.Imaging; using System.Windows.Media.Imaging;
using AutoTrackR2.LogEventHandlers; using AutoTrackR2.LogEventHandlers;
namespace AutoTrackR2; 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 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(); InitializeComponent();
// Get the current month _killHistoryManager = new KillHistoryManager(ConfigManager.KillHistoryFile);
string currentMonth = DateTime.Now.ToString("MMMM", CultureInfo.InvariantCulture);
// Set the TextBlock text // 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 // Update Start/Stop button states based on the isRunning flag
public void UpdateButtonState(bool isRunning) public void UpdateButtonState(bool isRunning)
{ {
@ -89,6 +82,15 @@ public partial class HomePage : UserControl
_logHandler = new LogHandler(ConfigManager.LogFile); _logHandler = new LogHandler(ConfigManager.LogFile);
_logHandler.Initialize(); _logHandler.Initialize();
} }
private void AddKillHistoryKillsToUI()
{
var kills = _killHistoryManager.GetKills();
foreach (var kill in kills)
{
Dispatcher.Invoke(() => { AddKillToScreen(kill); });
}
}
private void RegisterUIEventHandlers() private void RegisterUIEventHandlers()
{ {
@ -134,15 +136,31 @@ public partial class HomePage : UserControl
}; };
// Actor Death // Actor Death
TrackREventDispatcher.ActorDeathEvent += async (data) => { TrackREventDispatcher.ActorDeathEvent += async (actorDeathData) => {
if (data.VictimPilot != LocalPlayerData.Username) if (actorDeathData.VictimPilot != LocalPlayerData.Username)
{ {
var playerData = await WebHandler.GetPlayerData(data.VictimPilot); var playerData = await WebHandler.GetPlayerData(actorDeathData.VictimPilot);
if (playerData != null) if (playerData != null)
{ {
Dispatcher.Invoke(() => { AddKillToScreen(data, playerData); }); var killData = new KillData
await WebHandler.SubmitKill(data, playerData); {
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; _UIEventsRegistered = true;
} }
private void AddKillToScreen(ActorDeathData deathData, PlayerData? playerData) private void AddKillToScreen(KillData killData)
{ {
// Fetch the dynamic resource for AltTextColor // Fetch the dynamic resource for AltTextColor
var altTextColorBrush = new SolidColorBrush((Color)Application.Current.Resources["AltTextColor"]); var altTextColorBrush = new SolidColorBrush((Color)Application.Current.Resources["AltTextColor"]);
@ -181,7 +199,7 @@ public partial class HomePage : UserControl
Foreground = altTextColorBrush, Foreground = altTextColorBrush,
FontFamily = orbitronFontFamily, FontFamily = orbitronFontFamily,
}); });
killTextBlock.Inlines.Add(new Run($"{deathData.VictimPilot}\n")); killTextBlock.Inlines.Add(new Run($"{killData.EnemyPilot}\n"));
// Repeat for other lines // Repeat for other lines
killTextBlock.Inlines.Add(new Run("Victim Ship: ") killTextBlock.Inlines.Add(new Run("Victim Ship: ")
@ -189,21 +207,21 @@ public partial class HomePage : UserControl
Foreground = altTextColorBrush, Foreground = altTextColorBrush,
FontFamily = orbitronFontFamily, 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: ") killTextBlock.Inlines.Add(new Run("Victim Org: ")
{ {
Foreground = altTextColorBrush, Foreground = altTextColorBrush,
FontFamily = orbitronFontFamily, 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: ") killTextBlock.Inlines.Add(new Run("Join Date: ")
{ {
Foreground = altTextColorBrush, Foreground = altTextColorBrush,
FontFamily = orbitronFontFamily, 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: ") killTextBlock.Inlines.Add(new Run("UEE Record: ")
{ {
@ -211,16 +229,12 @@ public partial class HomePage : UserControl
FontFamily = orbitronFontFamily, FontFamily = orbitronFontFamily,
}); });
const string dateFormatString = "dd MMM yyyy HH:mm";
var currentTime = DateTime.UtcNow.ToString(dateFormatString);
killTextBlock.Inlines.Add(new Run("Kill Time: ") killTextBlock.Inlines.Add(new Run("Kill Time: ")
{ {
Foreground = altTextColorBrush, Foreground = altTextColorBrush,
FontFamily = orbitronFontFamily, FontFamily = orbitronFontFamily,
}); });
killTextBlock.Inlines.Add(new Run($"{currentTime}")); killTextBlock.Inlines.Add(new Run($"{killData.KillTime}"));
// Create a Border and apply the RoundedTextBlockWithBorder style // Create a Border and apply the RoundedTextBlockWithBorder style
var killBorder = new Border var killBorder = new Border
@ -246,7 +260,7 @@ public partial class HomePage : UserControl
// Create the Image for the profile // Create the Image for the profile
var profileImage = new Image 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, Width = 90,
Height = 90, Height = 90,
Stretch = Stretch.Fill, // Adjust how the image fits 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) public void StopButton_Click(object sender, RoutedEventArgs e)
{ {
_logHandler.Stop(); _logHandler?.Stop();
// Clear the text boxes // Clear the text boxes
System.Threading.Thread.Sleep(200); // System.Threading.Thread.Sleep(200);
PilotNameTextBox.Text = string.Empty; // PilotNameTextBox.Text = string.Empty;
PlayerShipTextBox.Text = string.Empty; // PlayerShipTextBox.Text = string.Empty;
GameModeTextBox.Text = string.Empty; // GameModeTextBox.Text = string.Empty;
KillTallyTextBox.Text = string.Empty; // KillTallyTextBox.Text = string.Empty;
KillFeedStackPanel.Children.Clear(); // KillFeedStackPanel.Children.Clear();
} }
private void AdjustFontSize(TextBlock textBlock) private void AdjustFontSize(TextBlock textBlock)

View file

@ -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();
}
}

View file

@ -195,6 +195,7 @@ namespace AutoTrackR2
public static class ConfigManager public static class ConfigManager
{ {
public static string LogFile { get; set; } public static string LogFile { get; set; }
public static string KillHistoryFile { get; set; }
public static string ApiUrl { get; set; } public static string ApiUrl { get; set; }
public static string ApiKey { get; set; } public static string ApiKey { get; set; }
public static string VideoPath { get; set; } public static string VideoPath { get; set; }
@ -202,6 +203,17 @@ namespace AutoTrackR2
public static int VideoRecord { get; set; } public static int VideoRecord { get; set; }
public static int OfflineMode { get; set; } public static int OfflineMode { get; set; }
public static int Theme { 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() public static void LoadConfig()
{ {

31
AutoTrackR2/Util.cs Normal file
View file

@ -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;
}