diff --git a/AutoTrackR2/App.xaml b/AutoTrackR2/App.xaml index 455b71a..a94f622 100644 --- a/AutoTrackR2/App.xaml +++ b/AutoTrackR2/App.xaml @@ -20,7 +20,7 @@ <SolidColorBrush x:Key="BackgroundDarkBrush" Color="{DynamicResource BackgroundDarkColor}" /> <SolidColorBrush x:Key="BackgroundLightBrush" Color="{DynamicResource BackgroundLightColor}" /> - <!-- Define the Style for Window --> + <!-- Define the Style for Window --> <Style TargetType="Window" x:Key="CustomWindowStyle"> <Setter Property="Template"> <Setter.Value> @@ -159,7 +159,7 @@ <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Slider"> - <Grid Width="90" Height="30" HorizontalAlignment="Left" Margin="58,-6,0,0"> + <Grid Width="120" Height="30" HorizontalAlignment="Left" Margin="58,-6,0,0"> <!-- Track Background --> <Border Background="{DynamicResource BackgroundDarkBrush}" BorderBrush="{DynamicResource AccentBrush}" BorderThickness="2" CornerRadius="15" Margin="0,0,-5,-4" /> @@ -273,5 +273,90 @@ </Setter.Value> </Setter> </Style> + + <!-- Modern Rounded ScrollBar Style --> + <Style TargetType="ScrollBar"> + <Setter Property="Width" Value="5" /> + <Setter Property="Template"> + <Setter.Value> + <ControlTemplate TargetType="ScrollBar"> + <Grid> + <Track Name="PART_Track" IsDirectionReversed="true" Width="12" Margin="5,0,0,0"> + <!-- Decrease Repeat Button --> + <Track.DecreaseRepeatButton> + <RepeatButton Background="Transparent" BorderBrush="Transparent" BorderThickness="0"> + <RepeatButton.Template> + <ControlTemplate TargetType="RepeatButton"> + <Grid x:Name="RepeatButtonGrid"> + <VisualStateManager.VisualStateGroups> + <VisualStateGroup Name="CommonStates"> + <VisualState Name="Normal"> + <Storyboard> + <DoubleAnimation Storyboard.TargetProperty="Opacity" Storyboard.TargetName="RepeatButtonGrid" To="1" Duration="0:0:0"/> + </Storyboard> + </VisualState> + <VisualState Name="MouseOver"> + <Storyboard> + <DoubleAnimation Storyboard.TargetProperty="Opacity" Storyboard.TargetName="RepeatButtonGrid" To="0" Duration="0:0:0.1"/> + </Storyboard> + </VisualState> + </VisualStateGroup> + </VisualStateManager.VisualStateGroups> + </Grid> + </ControlTemplate> + </RepeatButton.Template> + </RepeatButton> + </Track.DecreaseRepeatButton> + + + <!-- Thumb (Handle) --> + <Track.Thumb> + <Thumb> + <Thumb.Template> + <ControlTemplate TargetType="Thumb"> + <Grid> + <Border + Background="{DynamicResource BackgroundBrush}" + BorderBrush="{DynamicResource AccentBrush}" + BorderThickness="2" + CornerRadius="3" /> + </Grid> + </ControlTemplate> + </Thumb.Template> + </Thumb> + </Track.Thumb> + + <!-- Increase Repeat Button --> + <Track.IncreaseRepeatButton> + <RepeatButton Background="Transparent" BorderBrush="Transparent" BorderThickness="0"> + <RepeatButton.Template> + <ControlTemplate TargetType="RepeatButton"> + <Grid x:Name="RepeatButtonGrid"> + <VisualStateManager.VisualStateGroups> + <VisualStateGroup Name="CommonStates"> + <VisualState Name="Normal"> + <Storyboard> + <DoubleAnimation Storyboard.TargetProperty="Opacity" Storyboard.TargetName="RepeatButtonGrid" To="1" Duration="0:0:0"/> + </Storyboard> + </VisualState> + <VisualState Name="MouseOver"> + <Storyboard> + <DoubleAnimation Storyboard.TargetProperty="Opacity" Storyboard.TargetName="RepeatButtonGrid" To="0" Duration="0:0:0.1"/> + </Storyboard> + </VisualState> + </VisualStateGroup> + </VisualStateManager.VisualStateGroups> + </Grid> + </ControlTemplate> + </RepeatButton.Template> + </RepeatButton> + </Track.IncreaseRepeatButton> + </Track> + </Grid> + </ControlTemplate> + </Setter.Value> + </Setter> + </Style> + </Application.Resources> </Application> diff --git a/AutoTrackR2/Assets/HIT.png b/AutoTrackR2/Assets/HIT.png new file mode 100644 index 0000000..cdc8a4a Binary files /dev/null and b/AutoTrackR2/Assets/HIT.png differ diff --git a/AutoTrackR2/AutoTrackR2.csproj b/AutoTrackR2/AutoTrackR2.csproj index 5a92e6e..07f33db 100644 --- a/AutoTrackR2/AutoTrackR2.csproj +++ b/AutoTrackR2/AutoTrackR2.csproj @@ -11,23 +11,28 @@ <ItemGroup> <None Remove="Assets\D3VL.png" /> <None Remove="Assets\EMP.png" /> + <None Remove="Assets\HIT.png" /> <None Remove="Assets\NW.png" /> <None Remove="Assets\VOX.png" /> <None Remove="Fonts\Orbitron-Bold.ttf" /> <None Remove="Fonts\Roboto-Regular.ttf" /> + <None Remove="KillTrackR_MainScript.ps1" /> </ItemGroup> <ItemGroup> <Resource Include="Assets\D3VL.png"> <CopyToOutputDirectory>Always</CopyToOutputDirectory> </Resource> - <Resource Include="Assets\EMP.png" /> + <Resource Include="Assets\EMP.png"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Resource> <Resource Include="Assets\GN.png"> <CopyToOutputDirectory>Always</CopyToOutputDirectory> </Resource> <Resource Include="Assets\AutoTrackR.png"> <CopyToOutputDirectory>Always</CopyToOutputDirectory> </Resource> + <Resource Include="Assets\HIT.png" /> <Resource Include="Assets\NW.png"> <CopyToOutputDirectory>Always</CopyToOutputDirectory> </Resource> @@ -40,6 +45,9 @@ <Resource Include="Fonts\Roboto-Regular.ttf"> <CopyToOutputDirectory>Always</CopyToOutputDirectory> </Resource> + <EmbeddedResource Include="KillTrackR_MainScript.ps1"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </EmbeddedResource> </ItemGroup> </Project> diff --git a/AutoTrackR2/ConfigPage.xaml b/AutoTrackR2/ConfigPage.xaml index 25adc33..7a74a86 100644 --- a/AutoTrackR2/ConfigPage.xaml +++ b/AutoTrackR2/ConfigPage.xaml @@ -77,11 +77,11 @@ <TextBlock Text="Theme:" Foreground="{DynamicResource TextBrush}" FontSize="16" Margin="0,7,0,5"/> <Slider x:Name="ThemeSlider" Minimum="0" - Maximum="8" + Maximum="9" Value="0" TickFrequency="1" IsSnapToTickEnabled="True" - ValueChanged="ThemeSlider_ValueChanged" Width="180" + ValueChanged="ThemeSlider_ValueChanged" Width="200" Style="{StaticResource ThreePositionSlider}" /> </StackPanel> diff --git a/AutoTrackR2/ConfigPage.xaml.cs b/AutoTrackR2/ConfigPage.xaml.cs index bf2a1e0..7f42d76 100644 --- a/AutoTrackR2/ConfigPage.xaml.cs +++ b/AutoTrackR2/ConfigPage.xaml.cs @@ -184,14 +184,23 @@ namespace AutoTrackR2 break; case 6: // D3VL Theme UpdateThemeColors( - (Color)ColorConverter.ConvertFromString("#000000"), // Accent/Border (Bright Red) + (Color)ColorConverter.ConvertFromString("#000000"), // Accent/Border (Color)ColorConverter.ConvertFromString("#3E3E3E"), // Button (Color)ColorConverter.ConvertFromString("#4C1C1C"), // Background (Color)ColorConverter.ConvertFromString("#FF0000") // Text ); ChangeLogo("/Assets/D3VL.png", (Color)ColorConverter.ConvertFromString("#000000")); break; - case 7: // VOX Theme + case 7: // HIT Theme + UpdateThemeColors( + (Color)ColorConverter.ConvertFromString("#000000"), // Accent/Border + (Color)ColorConverter.ConvertFromString("#3E3E3E"), // Button + (Color)ColorConverter.ConvertFromString("#4C1C1C"), // Background + (Color)ColorConverter.ConvertFromString("#FF0000") // Text + ); + ChangeLogo("/Assets/HIT.png", (Color)ColorConverter.ConvertFromString("#fd2929")); + break; + case 8: // VOX Theme UpdateThemeColors( (Color)ColorConverter.ConvertFromString("#C0C0C0"), // Accent/Border (Color)ColorConverter.ConvertFromString("#1C1C1C"), // Button @@ -200,7 +209,7 @@ namespace AutoTrackR2 ); ChangeLogo("/Assets/VOX.png", (Color)ColorConverter.ConvertFromString("#FFD700")); break; - case 8: // EMP Theme + case 9: // EMP Theme UpdateThemeColors( (Color)ColorConverter.ConvertFromString("#F5721C"), // Accent/Border (Color)ColorConverter.ConvertFromString("#535353"), // Button @@ -322,14 +331,14 @@ namespace AutoTrackR2 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) + 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) } // Start the flashing effect diff --git a/AutoTrackR2/HomePage.xaml b/AutoTrackR2/HomePage.xaml index b501825..b1c9baf 100644 --- a/AutoTrackR2/HomePage.xaml +++ b/AutoTrackR2/HomePage.xaml @@ -13,20 +13,30 @@ <Grid.ColumnDefinitions> <!-- Left column for the main content area --> - <ColumnDefinition Width="*" /> + <ColumnDefinition /> <!-- Right column for the buttons --> - <ColumnDefinition Width="Auto" /> + <ColumnDefinition Width="Auto" MinWidth="173" /> </Grid.ColumnDefinitions> <!-- Border for the kill feed section --> - <Border Grid.Row="0" Grid.Column="0" BorderBrush="{DynamicResource AccentBrush}" BorderThickness="2" CornerRadius="10" Padding="10" Background="{DynamicResource BackgroundDarkBrush}" Margin="0,0,20,0"> + <TextBox Name="OutputTextBox" Grid.Row="0" Grid.Column="0" Grid.RowSpan="2" Height="NaN" Margin="0,0,20,0" TextWrapping="Wrap" VerticalScrollBarVisibility="Auto" IsReadOnly="True" Style="{StaticResource RoundedTextBox}"/> + <!-- Border Grid.Row="0" Grid.Column="0" BorderBrush="{DynamicResource AccentBrush}" BorderThickness="2" CornerRadius="10" Padding="10" Background="{DynamicResource BackgroundDarkBrush}" Margin="0,0,20,0"> <TextBlock Text="Kill Feed Goes Here..." FontSize="18" Foreground="{DynamicResource TextBrush}" HorizontalAlignment="Center" VerticalAlignment="Center" /> - </Border> + </Border --> <!-- StackPanel for Start and Stop buttons --> - <StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Bottom" HorizontalAlignment="Center" Margin="0,0,0,0"> - <Button Name="StartButton" Content="Start" Width="100" Height="40" Style="{StaticResource ButtonStyle}" FontFamily="{StaticResource Orbitron}" Margin="0,20"/> - <Button Name="StopButton" Content="Stop" Width="100" Height="40" Style="{StaticResource DisabledButtonStyle}" FontFamily="{StaticResource Orbitron}" IsEnabled="False"/> + <Border Background="{DynamicResource BackgroundDarkBrush}" BorderBrush="{DynamicResource AccentBrush}" Grid.Row="0" Grid.Column="1" BorderThickness="2" CornerRadius="5" Margin="0,0,0,134"/> + <StackPanel Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Center" Height="269" Width="152"> + <TextBlock Name="PilotNameTitle" Text="Pilot" Width="152" Height="20" Background="Transparent" FontFamily="{StaticResource Orbitron}" Margin="0,5,0,0" Foreground="{DynamicResource AccentBrush}" FontSize="14"/> + <TextBlock Name="PilotNameTextBox" Text="X" Width="152" Height="20" Background="Transparent" FontFamily="{StaticResource Orbitron}" Margin="0,0,0,0" Foreground="{DynamicResource TextBrush}" FontSize="11" TextAlignment="Center"/> + <TextBlock Name="PlayerShipTitle" Text="Ship" Width="152" Height="20" Background="Transparent" FontFamily="{StaticResource Orbitron}" Margin="0,5,0,0" Foreground="{DynamicResource AccentBrush}" FontSize="14" /> + <TextBlock Name="PlayerShipTextBox" Text="X" Width="152" Height="20" Background="Transparent" FontFamily="{StaticResource Orbitron}" Margin="0,0,0,0" Foreground="{DynamicResource TextBrush}" FontSize="11" TextAlignment="Center"/> + <TextBlock Name="GameModeTitle" Text="Game Mode" Width="152" Height="20" Background="Transparent" FontFamily="{StaticResource Orbitron}" Margin="0,5,0,0" Foreground="{DynamicResource AccentBrush}" FontSize="14"/> + <TextBlock Name="GameModeTextBox" Text="X" Width="152" Height="20" Background="Transparent" FontFamily="{StaticResource Orbitron}" Margin="0,0,0,0" Foreground="{DynamicResource TextBrush}" FontSize="11" TextAlignment="Center"/> + </StackPanel> + <StackPanel Grid.Row="1" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Center" Height="120" Width="172" > + <Button Name="StartButton" Content="Start" Width="100" Height="40" Style="{StaticResource ButtonStyle}" FontFamily="{StaticResource Orbitron}" Margin="0,20" Click="StartButton_Click"/> + <Button Name="StopButton" Content="Stop" Width="100" Height="40" Style="{StaticResource DisabledButtonStyle}" FontFamily="{StaticResource Orbitron}" IsEnabled="False"/> </StackPanel> </Grid> </Grid> diff --git a/AutoTrackR2/HomePage.xaml.cs b/AutoTrackR2/HomePage.xaml.cs index 723ea91..99dcdf0 100644 --- a/AutoTrackR2/HomePage.xaml.cs +++ b/AutoTrackR2/HomePage.xaml.cs @@ -1,7 +1,9 @@ -using System.Windows; +using System.Diagnostics; +using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Media.Effects; +using System.IO; namespace AutoTrackR2 { @@ -53,5 +55,88 @@ namespace AutoTrackR2 StopButton.IsEnabled = false; // Disable Stop button } } + + private void StartButton_Click(object sender, RoutedEventArgs e) + { + string scriptPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "KillTrackR_MainScript.ps1"); + TailFileAsync(scriptPath); + } + + private async void TailFileAsync(string scriptPath) + { + await Task.Run(() => + { + try + { + ProcessStartInfo psi = new ProcessStartInfo + { + FileName = "powershell.exe", + Arguments = $"-NoProfile -ExecutionPolicy Bypass -File \"{scriptPath}\"", + RedirectStandardOutput = true, + RedirectStandardError = true, + UseShellExecute = false, + CreateNoWindow = true + }; + + using (Process process = new Process { StartInfo = psi }) + { + process.OutputDataReceived += (s, e) => + { + if (!string.IsNullOrEmpty(e.Data)) + { + Dispatcher.Invoke(() => + { + // Parse and display key-value pairs in the OutputTextBox + if (e.Data.Contains("PlayerName=")) + { + string pilotName = e.Data.Split('=')[1].Trim(); + PilotNameTextBox.Text = pilotName; // Update the Button's Content + } + else if (e.Data.Contains("PlayerShip=")) + { + string playerShip = e.Data.Split('=')[1].Trim(); + PlayerShipTextBox.Text = playerShip; + } + else if (e.Data.Contains("GameMode=")) + { + string gameMode = e.Data.Split('=')[1].Trim(); + GameModeTextBox.Text = gameMode; + } + else + { + OutputTextBox.AppendText(e.Data + Environment.NewLine); + } + }); + } + }; + + process.ErrorDataReceived += (s, e) => + { + if (!string.IsNullOrEmpty(e.Data)) + { + Dispatcher.Invoke(() => + { + OutputTextBox.AppendText("Error: " + e.Data + Environment.NewLine); + }); + } + }; + + process.Start(); + process.BeginOutputReadLine(); + process.BeginErrorReadLine(); + + process.WaitForExit(); + } + } + catch (Exception ex) + { + Dispatcher.Invoke(() => + { + MessageBox.Show($"Error running script: {ex.Message}"); + }); + } + }); + } + } } diff --git a/AutoTrackR2/KillTrackR_MainScript.ps1 b/AutoTrackR2/KillTrackR_MainScript.ps1 new file mode 100644 index 0000000..2633574 --- /dev/null +++ b/AutoTrackR2/KillTrackR_MainScript.ps1 @@ -0,0 +1,333 @@ +# Path to the config file +$scriptFolder = Split-Path -Parent $MyInvocation.MyCommand.Path +$configFile = Join-Path -Path $scriptFolder -ChildPath "config.ini" + +# Read the config file into a hashtable +if (Test-Path $configFile) { + Write-Output "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 +} + +$PlayerName = "Immersion_Breaker" +$PlayerShip = "ANVL_F7A_Mk2" +$GameMode = "PU" + +Write-Output "PlayerName=$PlayerName" +Write-Output "PlayerShip=$PlayerShip" +Write-Output "GameMode=$GameMode" + +# Access config values +$logFile = $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 +} + +if ($videoRecord -eq 1){ + $videoRecord = $true +} else { + $videoRecord = $false +} + +$logfileContent = Get-Content $logFile + +If (Test-Path $logFile) { + Write-Output "Logfile found." +} else { + Write-Output "Logfile not found." +} + +Write-Output $logfileContent +<# 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=[^ ]+ status="Finished" runningTime=\d+\.\d+ numRuns=\d+ map="megamap" gamerules="SC_Default" sessionId="[a-f0-9\-]+" \[Team_Network\]\[Network\]\[Replication\]\[Loading\]\[Persistence\]' +$acPattern = "ArenaCommanderFeature" +$loadoutPattern = '\[InstancedInterior\] OnEntityLeaveZone - InstancedInterior \[(?<InstancedInterior>[^\]]+)\] \[\d+\] -> Entity \[(?<Entity>[^\]]+)\] \[\d+\] -- m_openDoors\[\d+\], m_managerGEID\[(?<ManagerGEID>\d+)\], m_ownerGEID\[(?<OwnerGEID>[^\[]+)\]' +# $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+$' + +# Lookup Patterns +$joinDatePattern = '<span class="label">Enlisted</span>\s*<strong class="value">([^<]+)</strong>' +$orgPattern = '<IMG[^>]*>\s*([^<]+)' +$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 + +# Function to process new log entries and write to the host +function Read-LogEntry { + param ( + [string]$line + ) + + # Apply the regex pattern to the line + if ($line -match $killPattern -and $global:logStart -eq $TRUE) { + # 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 -eq $global:lastKill){ + $enemyShip = "Passenger" + } Else { + $global:lastKill = $enemyShip + } + + If (($player -eq $global:userName -and $enemyPilot -ne $global:userName) -and ($enemyPilot -notlike "PU_*" -and $enemyPilot -notlike "NPC_*")){ + 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 -like "*bullet*") { + $ship = "Player" + } + If ($ship -match $cleanupPattern){ + $ship = $matches[1] + } + if ($ship -like "OOC_*"){ + $ship = "Player" + } + If ($enemyShip -like "OOC_*" -or $enemyShip -like "hangar*") { + $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)$', '' + } + + $KillTime = Get-Date([DateTime]::UtcNow) -UFormat "%d%b%Y %r" + $page1 = Invoke-WebRequest -uri "https://robertsspaceindustries.com/citizens/$enemyPilot" + $page2 = Invoke-WebRequest -uri "https://robertsspaceindustries.com/citizens/$enemyPilot/organizations" + + # Get Enlisted Date + if ($($page1.content) -match $joinDatePattern) { + $joinDate = $matches[1] + } else { + $joinDate = "UNKNOWN" + } + + # Find Org matches using the regex pattern + $orgMatches = [regex]::matches($($page2.links.innerhtml), $orgPattern) + # Check if there are any matches + $enemyOrgs = @() + if ($orgMatches.Count -eq 0) { + $enemyOrgs = "N/A" + } else { + # Loop through each match and display the organization name + foreach ($match in $orgMatches) { + $organizationName = $match.Groups[1].Value.Trim() + $enemyOrgs = $enemyOrgs + $organizationName + } + } + + # Get UEE Number + if ($($page1.content) -match $ueePattern) { + # The matched UEE Citizen Record number is in $matches[1] + $citizenRecord = $matches[1] + } else { + $citizenRecord = "-1" + } + If ($citizenRecord -eq "N/A") { + $citizenRecordAPI = "-1" + } Else { + $citizenRecordAPI = $citizenRecord + } + + # Cleanup Output + $textColor = "Green" + $killText = "Congratulations!" + + # Send to API + # Define the data to send + If ($apiDetected -eq $true -and $urlDetected -eq $true){ + $data = @{ + victim_ship = $enemyShip + victim = $enemyPilot + enlisted = $joinDate + rsi = $citizenRecordAPI + weapon = $weapon + method = $damageType + loadout_ship = $ship + #version = $version + } + + # Headers which may or may not be necessary + $headers = @{ + "Authorization" = "Bearer $apiToken" + "Content-Type" = "application/json" + "User-Agent" = "TEST-PS" + } + + try { + # Send the POST request with JSON data + Invoke-RestMethod -Uri $apiURL -Method Post -Body ($data | ConvertTo-Json -Depth 5) -Headers $headers + } catch { + # Catch and display errors + Write-Output "Error: $($_)" -ForegroundColor red + Write-output "Send error to devs" + Write-Output "Kill saved in $outputPath" + $apiError = $_ + # Add to output file + Add-Content -Path $outputPath -value $($_) + } + } + + # Write-Output to console + write-host "=== $killText" -ForegroundColor $textColor + Write-Host "$killTime" + Write-Host "Enemy Pilot: " -NoNewLine -ForegroundColor $textColor + Write-Host "$enemyPilot" + Write-Host "Enemy Ship: " -NoNewLine -ForegroundColor $textColor + Write-Host "$enemyShip" + Write-Host "Enlisted: " -NoNewLine -ForegroundColor $textColor + Write-Host "$joinDate" + Write-Host "Record #: " -NoNewLine -ForegroundColor $textColor + Write-Host "$citizenRecord" + Write-Host "Org Affiliation: " -NoNewLine -ForegroundColor $textColor + ForEach ($org in $enemyOrgs){ + Write-Host $org + } + Write-Host "Player: " -NoNewLine -ForegroundColor $textColor + Write-Host "$player" + Write-Host "Weapon: " -NoNewLine -ForegroundColor $textColor + Write-Host "$weapon" + Write-Host "Ship: " -NoNewLine -ForegroundColor $textColor + Write-Host "$ship"s + Write-Host "Method: " -NoNewLine -ForegroundColor $textColor + Write-Host "$damageType" + Write-Host "-------------------------" + + # Write output to local log + If ($apiDetected -eq $false -or $urlDetected -eq $false -or $null -ne $apiError){ + Add-Content -Path $outputPath -Value "=== $killText" + Add-Content -Path $outputPath -Value "$killTime" + Add-Content -Path $outputPath -Value "Enemy Pilot: $enemyPilot" + Add-Content -Path $outputPath -Value "Enemy Ship: $enemyShip" + Add-Content -Path $outputPath -Value "Enlisted: $joinDate" + Add-Content -Path $outputPath -Value "Record #: $citizenRecord" + Add-Content -Path $outputPath -Value "Org Affiliation: " -NoNewLine + ForEach ($org in $enemyOrgs){ + Add-Content -Path $outputPath -Value $org + } + Add-Content -Path $outputPath -Value "Player: $player" + Add-Content -Path $outputPath -Value "Weapon: $weapon" + Add-Content -Path $outputPath -Value "Ship: $ship" + Add-Content -Path $outputPath -Value "Method: $damageType" + Add-Content -Path $outputPath -Value "-------------------------" + } + + $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 + &$visorPath + } + + # Record video + if ($recording -eq $true -and $enemyShip -ne "Passenger"){ + # send keybind for windows game bar recording + Start-Sleep 2 + $sleeptimer = $sleeptimer -9 + &$recordPath + Write-Host "=== Kill Clipped!" -ForegroundColor Green + Write-Host "-------------------------" + Start-Sleep 7 + + # + $latestFile = Get-ChildItem -Path $videoPath | Where-Object { -not $_.PSIsContainer } | Sort-Object CreationTime -Descending | Select-Object -First 1 + # Generate a timestamp in ddMMMyyyy-HH:mm format + $timestamp = (Get-Date).ToString("ddMMMyyyy-HHmm") + # Rename the file if it exists + if ($latestFile) { + Rename-Item -Path $latestFile.FullName -NewName "$enemyPilot.$enemyShip.$timestamp.mp4" + } + } + 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-Host "Logged in as $global:userName" -ForegroundColor Green + Write-Host "-------------------------" + } + } + + # Detect PU or AC + if ($line -match $puPattern -and $global:logStart -eq $FALSE) { + $global:logStart = $TRUE + Write-Host "=== Logging: $global:logStart" -ForegroundColor Green + Write-Host "-------------------------" + } + if ($line -match $acPattern -and $global:logStart -eq $TRUE) { + $global:logStart = $FALSE + Write-Host "=== Logging: $global:logStart" -ForegroundColor Red + Write-Host "-------------------------" + } + + #Set loadout + if ($line -match $loadoutPattern) { + $entity = $matches['Entity'] + $ownerGEID = $matches['OwnerGEID'] + + If ($ownerGEID -eq $global:userName -and $entity -notlike "*SoundListener*" -and $entity -notlike "*StreamingSOC*" -and $entity -ne $global:userName) { + $global:loadOut = $entity + If ($global:loadOut -match $cleanupPattern){ + $global:loadOut = $matches[1] + } + Write-Host "=== Loadout: $global:loadOut" -ForegroundColor Yellow + Write-Host "-------------------------" + + } + } +} + +# Monitor the log file and process new lines as they are added +Get-Content -Path $logFile -Wait -Tail 0 | ForEach-Object { + Read-LogEntry $_ +} +#> \ No newline at end of file diff --git a/AutoTrackR2/MainWindow.xaml.cs b/AutoTrackR2/MainWindow.xaml.cs index dfe6832..8c9da87 100644 --- a/AutoTrackR2/MainWindow.xaml.cs +++ b/AutoTrackR2/MainWindow.xaml.cs @@ -196,21 +196,21 @@ namespace AutoTrackR2 foreach (var line in File.ReadLines(configFilePath)) { if (line.StartsWith("LogFile=")) - LogFile = line.Substring("LogFile=\"".Length).Trim('\"'); + LogFile = line.Substring("LogFile=".Length).Trim(); else if (line.StartsWith("ApiUrl=")) - ApiUrl = line.Substring("ApiUrl=\"".Length).Trim('\"'); + ApiUrl = line.Substring("ApiUrl=".Length).Trim(); else if (line.StartsWith("ApiKey=")) - ApiKey = line.Substring("ApiKey=\"".Length).Trim('\"'); + ApiKey = line.Substring("ApiKey=".Length).Trim(); else if (line.StartsWith("VideoPath=")) - VideoPath = line.Substring("VideoPath=\"".Length).Trim('\"'); + VideoPath = line.Substring("VideoPath=".Length).Trim(); else if (line.StartsWith("VisorWipe=")) - VisorWipe = int.Parse(line.Substring("VisorWipe=\"".Length).Trim('\"')); + VisorWipe = int.Parse(line.Substring("VisorWipe=".Length).Trim()); else if (line.StartsWith("VideoRecord=")) - VideoRecord = int.Parse(line.Substring("VideoRecord=\"".Length).Trim('\"')); + VideoRecord = int.Parse(line.Substring("VideoRecord=".Length).Trim()); else if (line.StartsWith("OfflineMode=")) - OfflineMode = int.Parse(line.Substring("OfflineMode=\"".Length).Trim('\"')); + OfflineMode = int.Parse(line.Substring("OfflineMode=".Length).Trim()); else if (line.StartsWith("Theme=")) - Theme = int.Parse(line.Substring("Theme=\"".Length).Trim('\"')); + Theme = int.Parse(line.Substring("Theme=".Length).Trim()); } } }