mirror of
https://github.com/BubbaGumpShrump/AutoTrackR2.git
synced 2025-05-06 18:45:29 +00:00
Generate new CSV from DB.
This commit is contained in:
parent
84fea654a5
commit
24bce82407
3 changed files with 265 additions and 1 deletions
AutoTrackR2
|
@ -40,6 +40,13 @@
|
|||
Margin="0,0"
|
||||
Style="{StaticResource ButtonStyle}"
|
||||
Click="LogFileOpenButton_Click"/>
|
||||
<Button Content="Import CSV from API"
|
||||
Width="120"
|
||||
Height="30"
|
||||
FontFamily="{StaticResource Orbitron}"
|
||||
Margin="5,0"
|
||||
Style="{StaticResource ButtonStyle}"
|
||||
Click="ImportCsvFromApiButton_Click"/>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System.Diagnostics;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Net.Http;
|
||||
|
@ -13,6 +14,8 @@ using System.Windows.Threading;
|
|||
using Microsoft.Win32;
|
||||
using System.Threading.Tasks;
|
||||
using AutoTrackR2.Constants;
|
||||
using AutoTrackR2.Services;
|
||||
using System.Linq;
|
||||
|
||||
namespace AutoTrackR2;
|
||||
|
||||
|
@ -364,6 +367,41 @@ public partial class ConfigPage : UserControl
|
|||
FlashSaveButton();
|
||||
}
|
||||
|
||||
private async void ImportCsvFromApiButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (string.IsNullOrEmpty(ConfigManager.ApiUrl) || string.IsNullOrEmpty(ConfigManager.ApiKey))
|
||||
{
|
||||
MessageBox.Show("Please configure API URL and API Key first.", "Configuration Error", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
var importService = new KillImportService();
|
||||
await importService.ImportKillsFromApi(ConfigManager.ApiUrl, ConfigManager.ApiKey);
|
||||
}
|
||||
|
||||
private string GetRsiValue(JsonElement rsiElement)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (rsiElement.ValueKind == JsonValueKind.Number)
|
||||
{
|
||||
return rsiElement.GetInt64().ToString();
|
||||
}
|
||||
else if (rsiElement.ValueKind == JsonValueKind.String)
|
||||
{
|
||||
if (long.TryParse(rsiElement.GetString(), out long result))
|
||||
{
|
||||
return result.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// If any error occurs, return -1
|
||||
}
|
||||
return "-1";
|
||||
}
|
||||
|
||||
private void FlashSaveButton()
|
||||
{
|
||||
string? originalText = SaveButton.Content?.ToString() ?? string.Empty;
|
||||
|
|
219
AutoTrackR2/Services/KillImportService.cs
Normal file
219
AutoTrackR2/Services/KillImportService.cs
Normal file
|
@ -0,0 +1,219 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Security.Authentication;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Windows;
|
||||
using AutoTrackR2.Constants;
|
||||
|
||||
namespace AutoTrackR2.Services;
|
||||
|
||||
public class KillImportService
|
||||
{
|
||||
public class KillData
|
||||
{
|
||||
public int id { get; set; }
|
||||
public string attacker_ship_name { get; set; } = string.Empty;
|
||||
public string victim_ship_name { get; set; } = string.Empty;
|
||||
public string nickname { get; set; } = string.Empty;
|
||||
public string? avatar { get; set; }
|
||||
public JsonElement rsi { get; set; }
|
||||
public string enlisted { get; set; } = string.Empty;
|
||||
public string? org_name { get; set; }
|
||||
public string? slug { get; set; }
|
||||
public string weapon { get; set; } = string.Empty;
|
||||
public string method { get; set; } = string.Empty;
|
||||
public string created_at { get; set; } = string.Empty;
|
||||
public string game_version { get; set; } = string.Empty;
|
||||
public string gamemode { get; set; } = string.Empty;
|
||||
public string trackr_version { get; set; } = string.Empty;
|
||||
public string hash { get; set; } = string.Empty;
|
||||
public string reported_time { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public class KillResponse
|
||||
{
|
||||
public List<KillData> kills { get; set; } = new();
|
||||
public int total { get; set; }
|
||||
public int page { get; set; }
|
||||
public int per_page { get; set; }
|
||||
}
|
||||
|
||||
private static string FormatField(string? value)
|
||||
{
|
||||
if (string.IsNullOrEmpty(value))
|
||||
{
|
||||
return "\"\"";
|
||||
}
|
||||
// Why the hell did we need to use a .csv file? Fisk you owe me.
|
||||
value = value.Replace(",", "");
|
||||
// Escape any existing double quotes by doubling them because Fisk.
|
||||
value = value.Replace("\"", "\"\"");
|
||||
// Always wrap in quotes to handle any special characters because Fisk.
|
||||
return $"\"{value}\"";
|
||||
}
|
||||
|
||||
private static string FormatEnlistedDate(string isoDate)
|
||||
{
|
||||
if (DateTime.TryParse(isoDate, out DateTime date))
|
||||
{
|
||||
return $"\"{date:MMM dd yyyy}\"";
|
||||
}
|
||||
return "\"\"";
|
||||
}
|
||||
|
||||
private static string GetUnixTimestamp(string isoTimestamp)
|
||||
{
|
||||
if (DateTime.TryParse(isoTimestamp, out DateTime dateTime))
|
||||
{
|
||||
return $"\"{((DateTimeOffset)dateTime).ToUnixTimeSeconds()}\"";
|
||||
}
|
||||
return "\"0\"";
|
||||
}
|
||||
|
||||
private static string GetRsiValue(JsonElement rsiElement)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (rsiElement.ValueKind == JsonValueKind.Number)
|
||||
{
|
||||
return rsiElement.GetInt64().ToString();
|
||||
}
|
||||
else if (rsiElement.ValueKind == JsonValueKind.String)
|
||||
{
|
||||
if (long.TryParse(rsiElement.GetString(), out long result))
|
||||
{
|
||||
return result.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// If any error occurs, return -1
|
||||
}
|
||||
return "-1";
|
||||
}
|
||||
|
||||
public async Task ImportKillsFromApi(string apiUrl, string apiKey)
|
||||
{
|
||||
if (string.IsNullOrEmpty(apiUrl) || string.IsNullOrEmpty(apiKey))
|
||||
{
|
||||
MessageBox.Show("Please configure API URL and API Key first.", "Configuration Error", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Configure HttpClient with TLS 1.2
|
||||
var handler = new HttpClientHandler
|
||||
{
|
||||
SslProtocols = SslProtocols.Tls12
|
||||
};
|
||||
|
||||
using (var client = new HttpClient(handler))
|
||||
{
|
||||
// Set headers
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);
|
||||
client.DefaultRequestHeaders.UserAgent.ParseAdd("AutoTrackR2");
|
||||
|
||||
// Get base URL
|
||||
string baseUrl = Regex.Replace(apiUrl, @"(https?://[^/]+)/?.*", "$1");
|
||||
string endpoint = "player/kills";
|
||||
|
||||
// Create CSV content
|
||||
var csvContent = new StringBuilder();
|
||||
// Add header
|
||||
csvContent.AppendLine("KillTime,EnemyPilot,EnemyShip,Enlisted,RecordNumber,OrgAffiliation,Player,Weapon,Ship,Method,Mode,GameVersion,TrackRver,Logged,PFP,Hash");
|
||||
|
||||
int currentPage = 1;
|
||||
int totalKills = 0;
|
||||
bool hasMorePages = true;
|
||||
|
||||
while (hasMorePages)
|
||||
{
|
||||
// Create JSON body with version and page
|
||||
var jsonBody = new { version = AppConstants.Version, page = currentPage };
|
||||
var content = new StringContent(JsonSerializer.Serialize(jsonBody), Encoding.UTF8, "application/json");
|
||||
|
||||
// Send POST request
|
||||
var response = await client.PostAsync($"{baseUrl}/{endpoint}", content);
|
||||
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
var responseContent = await response.Content.ReadAsStringAsync();
|
||||
var killResponse = JsonSerializer.Deserialize<KillResponse>(responseContent);
|
||||
|
||||
if (killResponse?.kills != null && killResponse.kills.Count > 0)
|
||||
{
|
||||
// Sort kills by timestamp in ascending order
|
||||
var sortedKills = killResponse.kills.OrderBy(k => k.created_at).ToList();
|
||||
|
||||
foreach (var kill in sortedKills)
|
||||
{
|
||||
var fields = new[]
|
||||
{
|
||||
GetUnixTimestamp(kill.created_at), // KillTime
|
||||
FormatField(kill.nickname), // EnemyPilot
|
||||
FormatField(kill.victim_ship_name), // EnemyShip
|
||||
FormatEnlistedDate(kill.enlisted), // Enlisted
|
||||
FormatField(GetRsiValue(kill.rsi)), // RecordNumber
|
||||
FormatField(kill.org_name), // OrgAffiliation
|
||||
FormatField(kill.nickname), // Player
|
||||
FormatField(kill.weapon), // Weapon
|
||||
FormatField(kill.attacker_ship_name), // Ship
|
||||
FormatField(kill.method), // Method
|
||||
FormatField(kill.gamemode), // Mode
|
||||
FormatField(kill.game_version), // GameVersion
|
||||
FormatField(kill.trackr_version), // TrackRver
|
||||
FormatField(""), // Logged
|
||||
FormatField(kill.avatar), // PFP
|
||||
FormatField(kill.hash) // Hash
|
||||
};
|
||||
csvContent.AppendLine(string.Join(",", fields));
|
||||
}
|
||||
|
||||
totalKills += killResponse.kills.Count;
|
||||
|
||||
// Check if we have more pages
|
||||
hasMorePages = killResponse.kills.Count == killResponse.per_page;
|
||||
currentPage++;
|
||||
}
|
||||
else
|
||||
{
|
||||
hasMorePages = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show($"Error: {response.StatusCode} - {response.ReasonPhrase}", "API Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Save the CSV to AppData
|
||||
string appDataPath = Path.Combine(
|
||||
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
|
||||
"AutoTrackR2",
|
||||
"kill-log.csv"
|
||||
);
|
||||
|
||||
// Ensure directory exists
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(appDataPath)!);
|
||||
|
||||
// Write the CSV to file with UTF-8 encoding without BOM
|
||||
await File.WriteAllTextAsync(appDataPath, csvContent.ToString(), new UTF8Encoding(false));
|
||||
|
||||
MessageBox.Show($"Successfully imported {totalKills} kills and saved to kill-log.csv\n\nPlease restart TrackR to apply the changes.", "Success", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show($"Failed to import kill data: {ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue