Pushing last changes

This commit is contained in:
Heavy Bob 2025-07-07 04:01:49 +10:00
commit 60fbaa99ac
11 changed files with 328 additions and 183 deletions

View file

@ -10,10 +10,14 @@
<Configurations>Debug;Release;Test</Configurations>
<Platforms>AnyCPU;x64</Platforms>
<ApplicationIcon>AutoTrackR2.ico</ApplicationIcon>
<Version>2.12</Version>
<Version>2.13</Version>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
<Deterministic>true</Deterministic>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<SelfContained>false</SelfContained>
<PublishSingleFile>true</PublishSingleFile>
<IncludeNativeLibrariesForSelfExtract>false</IncludeNativeLibrariesForSelfExtract>
</PropertyGroup>
<ItemGroup>
@ -48,4 +52,8 @@
</None>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Data.Sqlite" Version="9.0.6" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,24 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.5.2.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutoTrackR2", "AutoTrackR2.csproj", "{E22C9485-B9D3-1444-D963-459CE2284B32}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{E22C9485-B9D3-1444-D963-459CE2284B32}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E22C9485-B9D3-1444-D963-459CE2284B32}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E22C9485-B9D3-1444-D963-459CE2284B32}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E22C9485-B9D3-1444-D963-459CE2284B32}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BBD4E112-AC22-4175-9EAB-009EB91E395B}
EndGlobalSection
EndGlobal

View file

@ -14,7 +14,15 @@ public static class Weapons
"*repair*",
"*cutter*",
"*tractor*",
"*carryable*"
"*carryable*",
"*shotgun*",
"*sniper*",
"*rifle*",
"*smg*",
"*pistol*",
"*sniper*",
"*lmg*",
"*volt*",
};
public static bool IsKnownWeapon(string weaponName)

View file

@ -34,6 +34,9 @@ public partial class HomePage : UserControl
{
InitializeComponent();
// Initialize default values
LocalPlayerData.PlayerShip = "Player";
if (string.IsNullOrEmpty(ConfigManager.KillHistoryFile))
{
throw new InvalidOperationException("KillHistoryFile path is not configured.");
@ -119,11 +122,11 @@ public partial class HomePage : UserControl
{
// Game is not running, set everything to Unknown
GameModeTextBox.Text = "Unknown";
PlayerShipTextBox.Text = "Unknown";
PlayerShipTextBox.Text = "Player";
PilotNameTextBox.Text = "Unknown";
LocationTextBox.Text = "Unknown";
LocalPlayerData.CurrentGameMode = GameMode.Unknown;
LocalPlayerData.PlayerShip = string.Empty;
LocalPlayerData.PlayerShip = "Player";
LocalPlayerData.Username = string.Empty;
LocalPlayerData.LastSeenVehicleLocation = "Unknown";
@ -197,6 +200,28 @@ public partial class HomePage : UserControl
});
};
// Vehicle Control
TrackREventDispatcher.VehicleControlEvent += (data) =>
{
Dispatcher.Invoke(() =>
{
PlayerShipTextBox.Text = data.Ship ?? "Player";
AdjustFontSize(PlayerShipTextBox);
LocalPlayerData.PlayerShip = data.Ship ?? "Player";
});
};
// Jump Drive State Changed (Location Only)
TrackREventDispatcher.JumpDriveStateChangedEvent += (data) =>
{
Dispatcher.Invoke(() =>
{
LocalPlayerData.LastSeenVehicleLocation = data.Location;
LocationTextBox.Text = data.Location;
AdjustFontSize(LocationTextBox);
});
};
// Game Mode
TrackREventDispatcher.PlayerChangedGameModeEvent += (mode) =>
{

View file

@ -1,4 +1,5 @@
using System.Globalization;
using Microsoft.Data.Sqlite;
using System.Globalization;
using System.IO;
using System.Text;
using System.Linq;
@ -11,8 +12,7 @@ namespace AutoTrackR2;
public class KillHistoryManager
{
private readonly string _killHistoryPath;
private readonly string _headers = "KillTime,EnemyPilot,EnemyShip,Enlisted,RecordNumber,OrgAffiliation,Player,Weapon,Ship,Method,Mode,GameVersion,TrackRver,Logged,PFP,Hash\n";
private readonly string _dbPath;
private readonly KillStreakManager _killStreakManager;
private readonly ConcurrentQueue<KillData> _killQueue;
private readonly CancellationTokenSource _cancellationTokenSource;
@ -23,13 +23,9 @@ public class KillHistoryManager
{
var appDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "AutoTrackR2");
Directory.CreateDirectory(appDataPath); // Ensure the directory exists
_killHistoryPath = Path.Combine(appDataPath, "Kill-log.csv");
_dbPath = Path.Combine(appDataPath, "kills.db");
// Create the CSV file with headers if it doesn't exist
if (!File.Exists(_killHistoryPath))
{
File.WriteAllText(_killHistoryPath, _headers);
}
InitializeDatabase();
_killStreakManager = new KillStreakManager(soundsPath);
_killQueue = new ConcurrentQueue<KillData>();
@ -39,6 +35,34 @@ public class KillHistoryManager
_processingTask = Task.Run(ProcessKillQueue);
}
private void InitializeDatabase()
{
using var connection = new SqliteConnection($"Data Source={_dbPath}");
connection.Open();
var command = connection.CreateCommand();
command.CommandText = @"
CREATE TABLE IF NOT EXISTS kills (
Hash TEXT PRIMARY KEY,
KillTime TEXT,
EnemyPilot TEXT,
EnemyShip TEXT,
Enlisted TEXT,
RecordNumber TEXT,
OrgAffiliation TEXT,
Weapon TEXT,
Ship TEXT,
Method TEXT,
Location TEXT,
Mode TEXT,
GameVersion TEXT,
TrackRver TEXT,
Logged TEXT,
PFP TEXT
);
";
command.ExecuteNonQuery();
}
private async Task ProcessKillQueue()
{
while (!_cancellationTokenSource.Token.IsCancellationRequested)
@ -70,56 +94,41 @@ public class KillHistoryManager
{
try
{
// Ensure all fields are properly escaped for CSV
var fields = new[]
{
kill.KillTime.ToString(),
EscapeCsvField(kill.EnemyPilot),
EscapeCsvField(kill.EnemyShip),
EscapeCsvField(kill.Enlisted),
EscapeCsvField(kill.RecordNumber),
EscapeCsvField(kill.OrgAffiliation),
EscapeCsvField(kill.Player),
EscapeCsvField(kill.Weapon),
EscapeCsvField(kill.Ship),
EscapeCsvField(kill.Method),
EscapeCsvField(kill.Mode),
EscapeCsvField(kill.GameVersion),
EscapeCsvField(kill.TrackRver),
EscapeCsvField(kill.Logged),
EscapeCsvField(kill.PFP),
EscapeCsvField(kill.Hash)
};
var csvLine = string.Join(",", fields);
// Use FileShare.Read to allow other processes to read while we write
using var stream = new FileStream(_killHistoryPath, FileMode.Append, FileAccess.Write, FileShare.Read);
using var writer = new StreamWriter(stream);
await writer.WriteLineAsync(csvLine);
using var connection = new SqliteConnection($"Data Source={_dbPath}");
await connection.OpenAsync();
var command = connection.CreateCommand();
command.CommandText = @"
INSERT OR IGNORE INTO kills (
Hash, KillTime, EnemyPilot, EnemyShip, Enlisted, RecordNumber, OrgAffiliation, Weapon, Ship, Method, Location, Mode, GameVersion, TrackRver, Logged, PFP
) VALUES (
$Hash, $KillTime, $EnemyPilot, $EnemyShip, $Enlisted, $RecordNumber, $OrgAffiliation, $Weapon, $Ship, $Method, $Location, $Mode, $GameVersion, $TrackRver, $Logged, $PFP
);
";
command.Parameters.AddWithValue("$Hash", kill.Hash ?? "");
command.Parameters.AddWithValue("$KillTime", kill.KillTime ?? "");
command.Parameters.AddWithValue("$EnemyPilot", kill.EnemyPilot ?? "");
command.Parameters.AddWithValue("$EnemyShip", kill.EnemyShip ?? "");
command.Parameters.AddWithValue("$Enlisted", kill.Enlisted ?? "");
command.Parameters.AddWithValue("$RecordNumber", kill.RecordNumber ?? "");
command.Parameters.AddWithValue("$OrgAffiliation", kill.OrgAffiliation ?? "");
command.Parameters.AddWithValue("$Weapon", kill.Weapon ?? "");
command.Parameters.AddWithValue("$Ship", kill.Ship ?? "");
command.Parameters.AddWithValue("$Method", kill.Method ?? "");
command.Parameters.AddWithValue("$Location", kill.Location ?? "");
command.Parameters.AddWithValue("$Mode", kill.Mode ?? "");
command.Parameters.AddWithValue("$GameVersion", kill.GameVersion ?? "");
command.Parameters.AddWithValue("$TrackRver", kill.TrackRver ?? "");
command.Parameters.AddWithValue("$Logged", kill.Logged ?? "");
command.Parameters.AddWithValue("$PFP", kill.PFP ?? "");
await command.ExecuteNonQueryAsync();
}
catch (Exception ex)
{
Debug.WriteLine($"Error writing kill to CSV: {ex.Message}");
Debug.WriteLine($"Error writing kill to SQLite: {ex.Message}");
throw;
}
}
private string EscapeCsvField(string field)
{
if (string.IsNullOrEmpty(field)) return "";
// If the field contains any special characters, wrap it in quotes
if (field.Contains(",") || field.Contains("\"") || field.Contains("\n") || field.Contains("\r"))
{
// Double up any quotes
field = field.Replace("\"", "\"\"");
return $"\"{field}\"";
}
return field;
}
public void AddKill(KillData kill)
{
_killQueue.Enqueue(kill);
@ -145,47 +154,38 @@ public class KillHistoryManager
public List<KillData> GetKills()
{
var kills = new List<KillData>();
using var reader = new StreamReader(new FileStream(_killHistoryPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite));
reader.ReadLine(); // Skip headers
while (reader.Peek() >= 0)
using var connection = new SqliteConnection($"Data Source={_dbPath}");
connection.Open();
var command = connection.CreateCommand();
command.CommandText = "SELECT Hash, KillTime, EnemyPilot, EnemyShip, Enlisted, RecordNumber, OrgAffiliation, Weapon, Ship, Method, Location, Mode, GameVersion, TrackRver, Logged, PFP FROM kills";
using var reader = command.ExecuteReader();
while (reader.Read())
{
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],
Hash = data?[15]
Hash = reader.GetString(0),
KillTime = reader.GetString(1),
EnemyPilot = reader.GetString(2),
EnemyShip = reader.GetString(3),
Enlisted = reader.GetString(4),
RecordNumber = reader.GetString(5),
OrgAffiliation = reader.GetString(6),
Weapon = reader.GetString(7),
Ship = reader.GetString(8),
Method = reader.GetString(9),
Location = reader.GetString(10),
Mode = reader.GetString(11),
GameVersion = reader.GetString(12),
TrackRver = reader.GetString(13),
Logged = reader.GetString(14),
PFP = reader.GetString(15)
});
}
// Apply KillFeedLimit if specified
if (ConfigManager.KillFeedLimit.HasValue && ConfigManager.KillFeedLimit.Value > 0)
{
kills = kills.TakeLast(ConfigManager.KillFeedLimit.Value).ToList();
}
return kills;
}
@ -193,57 +193,45 @@ public class KillHistoryManager
{
string currentMonth = DateTime.Now.ToString("MMM", CultureInfo.InvariantCulture);
var kills = new List<KillData>();
// Read all kills directly from file, ignoring KillFeedLimit
using var reader = new StreamReader(new FileStream(_killHistoryPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite));
reader.ReadLine(); // Skip headers
while (reader.Peek() >= 0)
using var connection = new SqliteConnection($"Data Source={_dbPath}");
connection.Open();
var command = connection.CreateCommand();
command.CommandText = "SELECT Hash, KillTime, EnemyPilot, EnemyShip, Enlisted, RecordNumber, OrgAffiliation, Weapon, Ship, Method, Location, Mode, GameVersion, TrackRver, Logged, PFP FROM kills";
using var reader = command.ExecuteReader();
while (reader.Read())
{
var line = reader.ReadLine();
// Remove extra quotes from CSV data
line = line?.Replace("\"", string.Empty);
var data = line?.Split(',');
var kill = new KillData
{
Hash = reader.GetString(0),
KillTime = reader.GetString(1),
EnemyPilot = reader.GetString(2),
EnemyShip = reader.GetString(3),
Enlisted = reader.GetString(4),
RecordNumber = reader.GetString(5),
OrgAffiliation = reader.GetString(6),
Weapon = reader.GetString(7),
Ship = reader.GetString(8),
Method = reader.GetString(9),
Location = reader.GetString(10),
Mode = reader.GetString(11),
GameVersion = reader.GetString(12),
TrackRver = reader.GetString(13),
Logged = reader.GetString(14),
PFP = reader.GetString(15)
};
// Check if the kill is from the current month before adding it
var killTime = data?[0];
if (string.IsNullOrEmpty(killTime)) continue;
// Try to parse as Unix timestamp first
if (long.TryParse(killTime, out long unixTime))
if (!string.IsNullOrEmpty(kill.KillTime))
{
var date = DateTimeOffset.FromUnixTimeSeconds(unixTime);
if (date.ToString("MMM", CultureInfo.InvariantCulture) != currentMonth) continue;
if (long.TryParse(kill.KillTime, out long unixTime))
{
var date = DateTimeOffset.FromUnixTimeSeconds(unixTime).DateTime;
if (date.ToString("MMM", CultureInfo.InvariantCulture) == currentMonth)
{
kills.Add(kill);
}
}
}
else if (!killTime.Contains(currentMonth))
{
// Fall back to checking if it contains the month name (old format)
continue;
}
kills.Add(new KillData
{
KillTime = killTime,
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],
Hash = data?[15]
});
}
return kills;
}
}

View file

@ -12,12 +12,12 @@ 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 zone (?<Location>.*.)\)");
}
public void Handle(LogEntry entry)
{
if (entry.Message is null) return;
@ -34,6 +34,13 @@ public class JumpDriveStateChangedEvent : ILogEventHandler
{
data.ShipName = match.Groups[1].Value;
}
// Skip applying loadout if ship name matches "Default"
if (data.ShipName?.Equals("Default", StringComparison.OrdinalIgnoreCase) == true)
{
return;
}
if (!string.IsNullOrEmpty(data.ShipName) && !string.IsNullOrEmpty(data.Location))
{
TrackREventDispatcher.OnJumpDriveStateChangedEvent(data);

View file

@ -6,29 +6,35 @@ 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 zone (?<Location>.*.)\)");
}
public void Handle(LogEntry entry)
{
if (entry.Message is null) return;
var match = Pattern.Match(entry.Message);
if (!match.Success) return;
var data = new JumpDriveStateChangedData
{
Location = match.Groups["Location"].Value
};
match = _cleanUpPattern.Match(match.Groups["ShipName"].Value);
if (match.Success)
{
data.ShipName = match.Groups[1].Value;
}
// Skip applying loadout if ship name matches "Default"
if (data.ShipName?.Equals("Default", StringComparison.OrdinalIgnoreCase) == true)
{
return;
}
if (!string.IsNullOrEmpty(data.ShipName) && !string.IsNullOrEmpty(data.Location))
{
TrackREventDispatcher.OnJumpDriveStateChangedEvent(data);

View file

@ -0,0 +1,80 @@
using System.Text.RegularExpressions;
using AutoTrackR2.Constants;
namespace AutoTrackR2.LogEventHandlers;
public struct VehicleControlData
{
public string Action { get; set; } // "SetDriver" or "ClearDriver"
public string VehicleName { get; set; }
public string? Ship { get; set; }
}
public class VehicleControlEvent : ILogEventHandler
{
public Regex Pattern { get; }
private Regex _cleanUpPattern = new Regex(@"(.+?)_\d+$");
public VehicleControlEvent()
{
// Pattern for entering vehicle (granted control)
Pattern = new Regex(@"granted control token for '(?<vehicle_name>[^']+)'", RegexOptions.Compiled);
}
public void Handle(LogEntry entry)
{
if (entry.Message is null) return;
// Check for vehicle entry (granted control)
var enterMatch = Pattern.Match(entry.Message);
if (enterMatch.Success)
{
var vehicleName = enterMatch.Groups["vehicle_name"].Value;
var cleanedShipName = CleanShipName(vehicleName);
LocalPlayerData.PlayerShip = cleanedShipName;
var data = new VehicleControlData
{
Action = "SetDriver",
VehicleName = vehicleName,
Ship = cleanedShipName
};
TrackREventDispatcher.OnVehicleControlEvent(data);
return;
}
}
private string CleanShipName(string vehicleName)
{
var cleanMatch = _cleanUpPattern.Match(vehicleName);
return cleanMatch.Success ? cleanMatch.Groups[1].Value : vehicleName;
}
}
public class VehicleControlClearEvent : ILogEventHandler
{
public Regex Pattern { get; }
public VehicleControlClearEvent()
{
// Pattern for exiting vehicle (releasing control)
Pattern = new Regex(@"releasing control token", RegexOptions.Compiled);
}
public void Handle(LogEntry entry)
{
if (entry.Message is null) return;
var match = Pattern.Match(entry.Message);
if (match.Success)
{
LocalPlayerData.PlayerShip = "Player";
var data = new VehicleControlData
{
Action = "ClearDriver",
VehicleName = "Player",
Ship = "Player"
};
TrackREventDispatcher.OnVehicleControlEvent(data);
}
}
}

View file

@ -1,64 +1,55 @@
using System.Text.RegularExpressions;
using AutoTrackR2.Constants;
namespace AutoTrackR2.LogEventHandlers;
public struct VehicleDestructionData
{
public string Vehicle { get; set; }
public string VehicleName { get; set; }
public string VehicleId { get; set; }
public string Team { 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 string? Ship { get; set; }
}
public class VehicleDestructionEvent : ILogEventHandler
{
public Regex Pattern { get; }
private Regex _shipManufacturerPattern;
private Regex _cleanUpPattern = new Regex(@"(.+?)_\d+$");
public VehicleDestructionEvent()
{
const string patternStr = """
<(?<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>[^']+)'
""";
Pattern = new Regex(Regex.Replace(patternStr, @"\t|\n|\r", ""));
Pattern = new Regex(@"<Vehicle Destruction> Vehicle '(?<vehicle_name>[^']+)' \[(?<vehicle_id>\d+)\] \[(?<team>[^\]]+)\] in zone '(?<vehicle_zone>[^']+)' has been destroyed");
_shipManufacturerPattern = new Regex($"^({string.Join("|", ShipManufacturers.List)})");
}
public void Handle(LogEntry entry)
{
if (entry.Message == null)
{
return;
}
if (entry.Message is null) return;
var match = Pattern.Match(entry.Message);
if (!match.Success)
{
return;
}
if (!match.Success) return;
var data = new VehicleDestructionData
{
Vehicle = match.Groups["vehicle"].Value,
VehicleName = match.Groups["vehicle_name"].Value,
VehicleId = match.Groups["vehicle_id"].Value,
Team = match.Groups["team"].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,
};
// Extract ship name from vehicle name if it's a ship
var shipMatch = _shipManufacturerPattern.Match(data.VehicleName);
if (shipMatch.Success)
{
var cleanMatch = _cleanUpPattern.Match(data.VehicleName);
if (cleanMatch.Success)
{
data.Ship = cleanMatch.Groups[1].Value;
}
}
TrackREventDispatcher.OnVehicleDestructionEvent(data);
}
}

View file

@ -47,7 +47,9 @@ public class LogHandler
new JumpDriveStateChangedEvent(),
new RequestJumpFailedEvent(),
new VehicleDestructionEvent(),
new ActorDeathEvent()
new ActorDeathEvent(),
new VehicleControlEvent(),
new VehicleControlClearEvent()
];
public LogHandler(string? logPath)

View file

@ -18,37 +18,36 @@ public static class TrackREventDispatcher
{
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<JumpDriveStateChangedData>? JumpDriveStateChangedEvent;
public static void OnJumpDriveStateChangedEvent(JumpDriveStateChangedData data)
{
@ -61,4 +60,11 @@ public static class TrackREventDispatcher
{
StreamlinkRecordEvent?.Invoke(streamerHandle);
}
// Vehicle control has changed
public static event Action<VehicleControlData>? VehicleControlEvent;
public static void OnVehicleControlEvent(VehicleControlData data)
{
VehicleControlEvent?.Invoke(data);
}
}