AI
This commit is contained in:
parent
1be9732279
commit
01aa843d0b
18 changed files with 4122 additions and 2393 deletions
|
|
@ -1,147 +1,429 @@
|
|||
# --- Script Setup ---
|
||||
Start-Transcript -Path '/var/log/dtch/get_matches.log' -Append
|
||||
Write-Output "Starting get_matches script at $(Get-Date)"
|
||||
Write-Output "Running from: $(Get-Location)"
|
||||
|
||||
if ($PSScriptRoot.length -eq 0) {
|
||||
$scriptroot = Get-Location
|
||||
}
|
||||
else {
|
||||
$scriptroot = $PSScriptRoot
|
||||
# Determine script root directory reliably
|
||||
if ($PSScriptRoot) {
|
||||
$scriptRoot = $PSScriptRoot
|
||||
} else {
|
||||
$scriptRoot = Split-Path -Parent -Path $MyInvocation.MyCommand.Definition
|
||||
Write-Warning "PSScriptRoot not defined, using calculated path: $scriptRoot"
|
||||
}
|
||||
Write-Output "Script root identified as: $scriptRoot"
|
||||
|
||||
. $scriptroot\..\includes\ps1\lockfile.ps1
|
||||
new-lock -by "get_matches"
|
||||
# Define paths using Join-Path
|
||||
$includesPath = Join-Path -Path $scriptRoot -ChildPath "..\includes\ps1"
|
||||
$configPath = Join-Path -Path $scriptRoot -ChildPath "..\config"
|
||||
$dataPath = Join-Path -Path $scriptRoot -ChildPath "..\data"
|
||||
$matchesPath = Join-Path -Path $dataPath -ChildPath "matches"
|
||||
$matchesArchivePath = Join-Path -Path $matchesPath -ChildPath "archive"
|
||||
$playerDataJsonPath = Join-Path -Path $dataPath -ChildPath "player_data.json"
|
||||
$playerMatchesJsonPath = Join-Path -Path $dataPath -ChildPath "player_matches.json"
|
||||
$cachedMatchesJsonPath = Join-Path -Path $dataPath -ChildPath "cached_matches.json"
|
||||
|
||||
# Read the content of the file as a single string
|
||||
$fileContent = Get-Content -Path "$scriptroot/../config/config.php" -Raw
|
||||
$players = (Get-Content -Path "$scriptroot/../config/clanmembers.json" | ConvertFrom-Json).clanmembers
|
||||
# Use regex to match the apiKey value
|
||||
if ($fileContent -match "\`$apiKey\s*=\s*\'([^\']+)\'") {
|
||||
$apiKey = $matches[1]
|
||||
}
|
||||
else {
|
||||
Write-Output "API Key not found"
|
||||
}
|
||||
|
||||
$headers = @{
|
||||
'accept' = 'application/vnd.api+json'
|
||||
'Authorization' = "$apiKey"
|
||||
}
|
||||
$player_matches = @()
|
||||
try {
|
||||
$player_data = get-content "$scriptroot/../data/player_data.json" | convertfrom-json -Depth 100
|
||||
}
|
||||
catch {
|
||||
Write-Output 'Unable to read file exitin'
|
||||
exit
|
||||
}
|
||||
foreach ($player in $player_data) {
|
||||
$lastMatches = $player.relationships.matches.data.id #| Select-Object -First 10
|
||||
$playermatches = @()
|
||||
foreach ($match in $lastMatches) {
|
||||
Write-Host "Getting match for $($player.attributes.name) match: $match "
|
||||
if (Test-Path "$scriptroot/../data/matches/$match.json") {
|
||||
write-output "Getting $match from cache"
|
||||
$stats = get-content "$scriptroot/../data/matches/$match.json" | convertfrom-json
|
||||
# Ensure required directories exist
|
||||
@( $dataPath, $matchesPath, $matchesArchivePath ) | ForEach-Object {
|
||||
if (-not (Test-Path -Path $_ -PathType Container)) {
|
||||
Write-Warning "Directory not found at '$_'. Attempting to create."
|
||||
try {
|
||||
New-Item -Path $_ -ItemType Directory -Force -ErrorAction Stop | Out-Null
|
||||
Write-Output "Successfully created directory: $_"
|
||||
} catch {
|
||||
Write-Error "Failed to create directory '$_'. Please check permissions. Error: $($_.Exception.Message)"
|
||||
Stop-Transcript
|
||||
exit 1
|
||||
}
|
||||
else {
|
||||
$stats = Invoke-RestMethod -Uri "https://api.pubg.com/shards/steam/matches/$match" -Method GET -Headers $headers
|
||||
$sortedStats = $stats.included | Sort-Object { $_.attributes.stats.winplace }
|
||||
$stats.included = $sortedStats
|
||||
$stats | ConvertTo-Json -Depth 100 | Out-File "$scriptroot/../data/matches/$match.json"
|
||||
}
|
||||
}
|
||||
|
||||
# --- Locking ---
|
||||
$lockFilePath = Join-Path -Path $includesPath -ChildPath "lockfile.ps1"
|
||||
if (-not (Test-Path -Path $lockFilePath -PathType Leaf)) {
|
||||
Write-Error "Lockfile script not found at '$lockFilePath'. Cannot proceed."
|
||||
Stop-Transcript
|
||||
exit 1
|
||||
}
|
||||
. $lockFilePath
|
||||
New-Lock -by "get_matches" -ErrorAction Stop # Stop if locking fails
|
||||
|
||||
# --- Main Logic in Try/Finally for Lock Removal ---
|
||||
try {
|
||||
# --- Configuration Loading ---
|
||||
$apiKey = $null
|
||||
$clanMembers = @() # Renamed from $players for clarity
|
||||
|
||||
# Load API Key from config.php
|
||||
$phpConfigPath = Join-Path -Path $configPath -ChildPath "config.php"
|
||||
if (Test-Path -Path $phpConfigPath -PathType Leaf) {
|
||||
try {
|
||||
$fileContent = Get-Content -Path $phpConfigPath -Raw -ErrorAction Stop
|
||||
# Corrected regex for apiKey
|
||||
if ($fileContent -match '^\s*\$apiKey\s*=\s*''([^'']+)''') {
|
||||
$apiKey = $matches[1]
|
||||
Write-Output "API Key loaded successfully."
|
||||
} else {
|
||||
Write-Warning "API Key pattern not found in '$phpConfigPath'."
|
||||
}
|
||||
} catch {
|
||||
Write-Warning "Failed to read '$phpConfigPath'. Error: $($_.Exception.Message)"
|
||||
}
|
||||
|
||||
$playermatches += [PSCustomObject]@{
|
||||
stats = $stats.included.ATTRIBUTES.stats | where-object { $_.name -eq $player.attributes.name }
|
||||
matchType = $stats.data.attributes.matchtype
|
||||
gameMode = $stats.data.attributes.gameMode
|
||||
createdAt = $stats.data.attributes.createdAt
|
||||
mapName = $stats.data.attributes.mapName
|
||||
telemetry_url = ($stats.included.attributes | Where-Object { $_.name -eq 'telemetry' }).URL
|
||||
id = $stats.data.id
|
||||
} else {
|
||||
Write-Warning "Config file not found at '$phpConfigPath'."
|
||||
}
|
||||
|
||||
if (-not $apiKey) {
|
||||
Write-Error "API Key could not be loaded. Cannot proceed without API Key."
|
||||
throw "Missing API Key" # Throw to trigger finally block
|
||||
}
|
||||
|
||||
# Load Clan Members from clanmembers.json
|
||||
$clanMembersJsonPath = Join-Path -Path $configPath -ChildPath "clanmembers.json"
|
||||
if (Test-Path -Path $clanMembersJsonPath -PathType Leaf) {
|
||||
try {
|
||||
$clanMembersData = Get-Content -Path $clanMembersJsonPath -Raw | ConvertFrom-Json -ErrorAction Stop
|
||||
if ($clanMembersData -is [PSCustomObject] -and $clanMembersData.PSObject.Properties.Name -contains 'clanMembers' -and $clanMembersData.clanMembers -is [array]) {
|
||||
$clanMembers = $clanMembersData.clanMembers
|
||||
Write-Output "Clan members loaded successfully. Count: $($clanMembers.Count)"
|
||||
} else {
|
||||
Write-Warning "Invalid structure in '$clanMembersJsonPath'. Expected an object with a 'clanMembers' array."
|
||||
}
|
||||
} catch {
|
||||
Write-Warning "Failed to read or parse '$clanMembersJsonPath'. Error: $($_.Exception.Message)"
|
||||
}
|
||||
|
||||
} else {
|
||||
Write-Warning "Clan members file not found at '$clanMembersJsonPath'."
|
||||
}
|
||||
|
||||
$obj = [PSCustomObject]@{
|
||||
playername = $player.attributes.name
|
||||
player_matches = $playermatches
|
||||
|
||||
if ($clanMembers.Count -eq 0) {
|
||||
Write-Warning "No clan members loaded. Proceeding, but cached matches might be incomplete."
|
||||
# Decide if this is a fatal error or not
|
||||
}
|
||||
|
||||
$player_matches += $obj
|
||||
|
||||
}
|
||||
|
||||
if (test-path "$scriptroot/../data/player_matches.json") {
|
||||
try {
|
||||
$old_player_data = get-content "$scriptroot/../data/player_matches.json" | convertfrom-json -Depth 100
|
||||
}
|
||||
catch {
|
||||
Write-Output 'Unable to read file exitin'
|
||||
exit
|
||||
}
|
||||
$new_ids = ($player_matches.player_matches | where-object { $_.stats.winplace -eq 1 }).id
|
||||
$old_ids = ($old_player_data.player_matches | where-object { $_.stats.winplace -eq 1 }).id
|
||||
$new_win_matches = ((Compare-Object -ReferenceObject $old_ids -DifferenceObject $new_ids) | Where-Object { $_.SideIndicator -eq '=>' }).InputObject | Select-Object -Unique
|
||||
$new_win_matches = $old_player_data.new_win_matches + $new_win_matches | Select-Object -Unique
|
||||
$player_matches += [PSCustomObject]@{
|
||||
new_win_matches = $new_win_matches
|
||||
}
|
||||
|
||||
# Nieuwe verloren matches bepalen
|
||||
$new_loss_ids = ($player_matches.player_matches | Where-Object { $_.stats.winplace -ne 1 }).id
|
||||
$old_loss_ids = ($old_player_data.player_matches | Where-Object { $_.stats.winplace -ne 1 }).id
|
||||
$new_loss_matches = ((Compare-Object -ReferenceObject $old_loss_ids -DifferenceObject $new_loss_ids) | Where-Object { $_.SideIndicator -eq '=>' }).InputObject | Select-Object -Unique
|
||||
$new_loss_matches = $old_player_data.new_loss_matches + $new_loss_matches | Select-Object -Unique
|
||||
$player_matches += [PSCustomObject]@{
|
||||
new_loss_matches = $new_loss_matches
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$currentDateTime = Get-Date
|
||||
|
||||
# Get current timezone
|
||||
$currentTimezone = (Get-TimeZone).Id
|
||||
|
||||
# Format and parse the information into a string
|
||||
$formattedString = "$currentDateTime - Time Zone: $currentTimezone"
|
||||
# Output the formatted string
|
||||
$playermatches += [PSCustomObject]@{
|
||||
updated = $formattedString
|
||||
}
|
||||
|
||||
$player_matches | convertto-json -Depth 100 | out-file "$scriptroot/../data/player_matches.json"
|
||||
|
||||
write-output 'Cleaning matches'
|
||||
|
||||
$matchfiles = Get-ChildItem "$scriptroot/../data/matches" -Filter *.json
|
||||
$player_matches_object = @()
|
||||
foreach ($file in $matchfiles) {
|
||||
$filecontent = get-content $file | convertfrom-json
|
||||
$matchfiledate = $filecontent.data.attributes.createdAt
|
||||
if ($matchfiledate -lt (get-date).AddMonths(-3)) {
|
||||
write-output "archiving $matchfiledate"
|
||||
Move-Item -Path $file -Destination "$scriptroot/../data/matches/archive"
|
||||
}
|
||||
else {
|
||||
$result = ($filecontent.included | where-object { $_.type -eq 'participant' } | Where-Object { $players -contains $_.attributes.stats.name })
|
||||
$filecontent.data.id
|
||||
$result.count
|
||||
$player_matches_cached = ($filecontent.included | where-object { $_.type -eq 'participant' } | Where-Object { $players -contains $_.attributes.stats.name }).attributes.stats
|
||||
if ($null -ne $player_matches_cached) {
|
||||
$player_matches_object += [PSCustomObject]@{
|
||||
matchType = $filecontent.data.attributes.matchType
|
||||
gameMode = $filecontent.data.attributes.gameMode
|
||||
createdAt = $filecontent.data.attributes.createdAt
|
||||
mapName = $filecontent.data.attributes.mapName
|
||||
id = $filecontent.data.id
|
||||
stats = @($player_matches_cached)
|
||||
# --- Helper Function for API Calls (Copied from update_clan_members.ps1) ---
|
||||
function Invoke-PubgApi {
|
||||
param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$Uri,
|
||||
[Parameter(Mandatory=$true)]
|
||||
[hashtable]$Headers,
|
||||
[int]$RetryCount = 1,
|
||||
[int]$RetryDelaySeconds = 61
|
||||
)
|
||||
for ($attempt = 1; $attempt -le ($RetryCount + 1); $attempt++) {
|
||||
try {
|
||||
Write-Verbose "Attempting API call (Attempt $($attempt)): $Uri"
|
||||
$response = Invoke-RestMethod -Uri $Uri -Method GET -Headers $Headers -ErrorAction Stop
|
||||
if ($null -ne $response) { Write-Verbose "API call successful."; return $response }
|
||||
else { Write-Warning "API call to $Uri returned null or empty response."; return $null }
|
||||
} catch {
|
||||
$statusCode = $_.Exception.Response.StatusCode.value__
|
||||
$errorMessage = $_.Exception.Message
|
||||
Write-Warning "API call failed (Attempt $($attempt)). Status: $statusCode. Error: $errorMessage"
|
||||
if ($attempt -le $RetryCount -and $statusCode -eq 429) {
|
||||
Write-Warning "Rate limit hit. Sleeping for $RetryDelaySeconds seconds before retry..."
|
||||
Start-Sleep -Seconds $RetryDelaySeconds
|
||||
} elseif ($attempt -gt $RetryCount) { Write-Error "API call failed after $($attempt) attempts. URI: $Uri. Last Error: $errorMessage"; return $null }
|
||||
else { Write-Error "Non-retryable API error. URI: $Uri. Error: $errorMessage"; return $null }
|
||||
}
|
||||
}
|
||||
write-output "NEW $matchfiledate"
|
||||
return $null
|
||||
}
|
||||
}
|
||||
$player_matches_object | Sort-Object createdAt -Descending | convertto-json -Depth 100 | out-file "$scriptroot/../data/cached_matches.json"
|
||||
|
||||
remove-lock
|
||||
Stop-Transcript
|
||||
# --- Load Player Data (IDs and Match Lists) ---
|
||||
$playerData = $null
|
||||
if (Test-Path -Path $playerDataJsonPath -PathType Leaf) {
|
||||
try {
|
||||
# Assuming player_data.json contains an object with a 'data' array property
|
||||
$playerDataWrapper = Get-Content -Path $playerDataJsonPath | ConvertFrom-Json -Depth 100 -ErrorAction Stop
|
||||
if ($null -ne $playerDataWrapper -and $playerDataWrapper.PSObject.Properties.Name -contains 'data' -and $playerDataWrapper.data -is [array]) {
|
||||
$playerData = $playerDataWrapper.data
|
||||
Write-Output "Successfully loaded player data. Count: $($playerData.Count)"
|
||||
} else {
|
||||
Write-Error "Invalid structure in '$playerDataJsonPath'. Expected object with 'data' array. Cannot proceed."
|
||||
throw "Invalid player data structure."
|
||||
}
|
||||
} catch {
|
||||
Write-Error "Error reading '$playerDataJsonPath': $($_.Exception.Message). Cannot proceed."
|
||||
throw $_
|
||||
}
|
||||
} else {
|
||||
Write-Error "Player data file not found at '$playerDataJsonPath'. Run update_clan_members.ps1 first. Cannot proceed."
|
||||
throw "Missing player data file."
|
||||
}
|
||||
|
||||
# --- Fetch and Process Matches for Each Player ---
|
||||
Write-Output "Fetching and processing matches for $($playerData.Count) players..."
|
||||
$allPlayerMatchDetails = @() # Store processed match details for all players
|
||||
$apiHeaders = @{
|
||||
'accept' = 'application/vnd.api+json'
|
||||
'Authorization' = "Bearer $apiKey"
|
||||
}
|
||||
$matchesFetched = 0
|
||||
$matchesCached = 0
|
||||
|
||||
foreach ($player in $playerData) {
|
||||
# Validate player structure
|
||||
if ($null -eq $player.attributes -or $null -eq $player.attributes.name -or $null -eq $player.relationships.matches.data) {
|
||||
Write-Warning "Skipping player due to missing attributes, name, or match data: $($player | Out-String)"
|
||||
continue
|
||||
}
|
||||
$playerName = $player.attributes.name
|
||||
$playerMatchIds = $player.relationships.matches.data.id
|
||||
Write-Output "Processing player: $playerName ($($playerMatchIds.Count) recent matches)"
|
||||
|
||||
$currentPlayerMatches = @()
|
||||
foreach ($matchId in $playerMatchIds) {
|
||||
if (-not $matchId) { Write-Warning "Skipping null/empty match ID for player $playerName."; continue }
|
||||
|
||||
Write-Verbose "Getting match details for $playerName, Match ID: $matchId"
|
||||
$matchJsonPath = Join-Path -Path $matchesPath -ChildPath "$matchId.json"
|
||||
$matchStats = $null
|
||||
|
||||
# Check cache first
|
||||
if (Test-Path -Path $matchJsonPath -PathType Leaf) {
|
||||
Write-Verbose "Getting $matchId from cache."
|
||||
try {
|
||||
$matchStats = Get-Content -Path $matchJsonPath | ConvertFrom-Json -Depth 100 -ErrorAction Stop
|
||||
if ($null -eq $matchStats) { Write-Warning "Failed to parse cached match file: $matchJsonPath" }
|
||||
else { $matchesCached++ }
|
||||
} catch {
|
||||
Write-Warning "Error reading cached match file '$matchJsonPath': $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
|
||||
# Fetch from API if not cached or cache failed
|
||||
if ($null -eq $matchStats) {
|
||||
$apiUrl = "https://api.pubg.com/shards/steam/matches/$matchId"
|
||||
Write-Output "Fetching match $matchId from API..."
|
||||
$matchStats = Invoke-PubgApi -Uri $apiUrl -Headers $apiHeaders
|
||||
|
||||
if ($null -ne $matchStats) {
|
||||
$matchesFetched++
|
||||
# Sort included participants by winPlace before saving (optional, but done in original)
|
||||
try {
|
||||
if ($null -ne $matchStats.included -and $matchStats.included -is [array]) {
|
||||
$matchStats.included = $matchStats.included | Sort-Object -Property { $_.attributes.stats.winPlace } -ErrorAction SilentlyContinue
|
||||
}
|
||||
} catch { Write-Warning "Could not sort 'included' array for match $matchId." }
|
||||
|
||||
# Save to cache
|
||||
try {
|
||||
$matchStats | ConvertTo-Json -Depth 100 | Out-File -FilePath $matchJsonPath -Encoding UTF8 -ErrorAction Stop
|
||||
Write-Verbose "Saved match $matchId to cache."
|
||||
} catch {
|
||||
Write-Warning "Failed to save match $matchId to cache '$matchJsonPath'. Error: $($_.Exception.Message)"
|
||||
}
|
||||
} else {
|
||||
Write-Warning "Failed to fetch match $matchId from API for player $playerName."
|
||||
continue # Skip this match if API fetch failed
|
||||
}
|
||||
}
|
||||
|
||||
# Process the retrieved/cached match stats
|
||||
if ($null -ne $matchStats -and $null -ne $matchStats.data -and $null -ne $matchStats.included) {
|
||||
# Find the specific player's stats within the 'included' array
|
||||
$playerSpecificStats = $null
|
||||
if ($matchStats.included -is [array]) {
|
||||
$playerSpecificStats = $matchStats.included |
|
||||
Where-Object { $_.type -eq 'participant' -and ($_.attributes.stats.name -eq $playerName) } |
|
||||
Select-Object -First 1 -ExpandProperty attributes | Select-Object -ExpandProperty stats
|
||||
}
|
||||
|
||||
# Find telemetry URL
|
||||
$telemetryUrl = $null
|
||||
if ($matchStats.included -is [array]) {
|
||||
$telemetryAsset = $matchStats.included | Where-Object { $_.type -eq 'asset' -and $_.attributes.name -eq 'telemetry' } | Select-Object -First 1
|
||||
if ($telemetryAsset) { $telemetryUrl = $telemetryAsset.attributes.URL }
|
||||
}
|
||||
|
||||
if ($null -ne $playerSpecificStats) {
|
||||
$currentPlayerMatches += [PSCustomObject]@{
|
||||
stats = $playerSpecificStats # Just the stats object for this player
|
||||
matchType = $matchStats.data.attributes.matchType
|
||||
gameMode = $matchStats.data.attributes.gameMode
|
||||
createdAt = $matchStats.data.attributes.createdAt
|
||||
mapName = $matchStats.data.attributes.mapName
|
||||
telemetry_url = $telemetryUrl
|
||||
id = $matchStats.data.id
|
||||
}
|
||||
} else {
|
||||
Write-Warning "Could not find stats for player $playerName within match $matchId data."
|
||||
}
|
||||
} else {
|
||||
Write-Warning "Match data structure for $matchId is invalid or incomplete after retrieval/caching."
|
||||
}
|
||||
} # End foreach matchId
|
||||
|
||||
# Add the processed matches for the current player to the main list
|
||||
$allPlayerMatchDetails += [PSCustomObject]@{
|
||||
playername = $playerName
|
||||
player_matches = $currentPlayerMatches # Array of processed match objects for this player
|
||||
}
|
||||
Write-Output "Finished processing matches for $playerName. Found $($currentPlayerMatches.Count) valid entries."
|
||||
} # End foreach player
|
||||
Write-Output "Finished fetching/processing all matches. API Fetches: $matchesFetched, Cache Hits: $matchesCached."
|
||||
|
||||
# --- Compare with Old Data & Identify New Wins/Losses ---
|
||||
Write-Output "Comparing current matches with old data..."
|
||||
$oldPlayerMatchData = $null
|
||||
$newWinMatchesList = @()
|
||||
$newLossMatchesList = @()
|
||||
|
||||
if (Test-Path -Path $playerMatchesJsonPath -PathType Leaf) {
|
||||
try {
|
||||
$oldPlayerMatchData = Get-Content -Path $playerMatchesJsonPath | ConvertFrom-Json -Depth 100 -ErrorAction Stop
|
||||
if ($null -eq $oldPlayerMatchData) {
|
||||
Write-Warning "Failed to parse old player matches file: $playerMatchesJsonPath. Cannot compare for new wins/losses."
|
||||
} else {
|
||||
Write-Output "Successfully loaded old player matches data for comparison."
|
||||
|
||||
# Extract all current match IDs and old match IDs safely
|
||||
$currentMatchIds = ($allPlayerMatchDetails.player_matches.id | Select-Object -Unique)
|
||||
$oldMatchIds = $null
|
||||
if ($oldPlayerMatchData -is [array]) {
|
||||
$oldMatchIds = ($oldPlayerMatchData.player_matches.id | Select-Object -Unique)
|
||||
} else {
|
||||
Write-Warning "Old player matches data is not in the expected array format."
|
||||
}
|
||||
|
||||
if ($null -ne $oldMatchIds) {
|
||||
# Compare IDs to find newly added matches
|
||||
$newMatchIds = (Compare-Object -ReferenceObject $oldMatchIds -DifferenceObject $currentMatchIds | Where-Object { $_.SideIndicator -eq '=>' }).InputObject | Select-Object -Unique
|
||||
Write-Output "Found $($newMatchIds.Count) new match IDs."
|
||||
|
||||
# Identify new wins and losses among the new matches
|
||||
$newMatchesDetails = $allPlayerMatchDetails.player_matches | Where-Object { $newMatchIds -contains $_.id }
|
||||
$newWinMatchesList = ($newMatchesDetails | Where-Object { $_.stats.winPlace -eq 1 }).id | Select-Object -Unique
|
||||
$newLossMatchesList = ($newMatchesDetails | Where-Object { $_.stats.winPlace -ne 1 }).id | Select-Object -Unique
|
||||
|
||||
Write-Output "Identified $($newWinMatchesList.Count) new wins and $($newLossMatchesList.Count) new losses."
|
||||
|
||||
# Combine with potentially existing lists from old data (if format was correct)
|
||||
$oldWinMatches = $oldPlayerMatchData | Where-Object { $_.PSObject.Properties.Name -eq 'new_win_matches' } | Select-Object -ExpandProperty new_win_matches
|
||||
$oldLossMatches = $oldPlayerMatchData | Where-Object { $_.PSObject.Properties.Name -eq 'new_loss_matches' } | Select-Object -ExpandProperty new_loss_matches
|
||||
|
||||
if ($oldWinMatches -is [array]) { $newWinMatchesList = ($oldWinMatches + $newWinMatchesList) | Select-Object -Unique }
|
||||
if ($oldLossMatches -is [array]) { $newLossMatchesList = ($oldLossMatches + $newLossMatchesList) | Select-Object -Unique }
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
Write-Warning "Error reading or processing old player matches file '$playerMatchesJsonPath': $($_.Exception.Message)"
|
||||
}
|
||||
} else {
|
||||
Write-Output "Old player matches file not found. Cannot compare for new wins/losses."
|
||||
# If no old file, all current wins/losses are "new" for the first run
|
||||
$newWinMatchesList = ($allPlayerMatchDetails.player_matches | Where-Object { $_.stats.winPlace -eq 1 }).id | Select-Object -Unique
|
||||
$newLossMatchesList = ($allPlayerMatchDetails.player_matches | Where-Object { $_.stats.winPlace -ne 1 }).id | Select-Object -Unique
|
||||
Write-Output "Treating all current wins ($($newWinMatchesList.Count)) and losses ($($newLossMatchesList.Count)) as new."
|
||||
}
|
||||
|
||||
# Add the lists of new wins/losses to the data structure
|
||||
$allPlayerMatchDetails += [PSCustomObject]@{ new_win_matches = $newWinMatchesList }
|
||||
$allPlayerMatchDetails += [PSCustomObject]@{ new_loss_matches = $newLossMatchesList }
|
||||
|
||||
# Add update timestamp
|
||||
$currentDateTime = Get-Date
|
||||
$currentTimezone = (Get-TimeZone).Id
|
||||
$formattedString = "$currentDateTime - Time Zone: $currentTimezone"
|
||||
$allPlayerMatchDetails += [PSCustomObject]@{ updated = $formattedString }
|
||||
Write-Output "Added update timestamp and new win/loss lists."
|
||||
|
||||
# --- Save Updated Player Matches Data ---
|
||||
try {
|
||||
$allPlayerMatchDetails | ConvertTo-Json -Depth 100 | Out-File -FilePath $playerMatchesJsonPath -Encoding UTF8 -ErrorAction Stop
|
||||
Write-Output "Updated player matches data saved to '$playerMatchesJsonPath'"
|
||||
} catch {
|
||||
Write-Error "Failed to save updated player matches data to '$playerMatchesJsonPath'. Error: $($_.Exception.Message)"
|
||||
}
|
||||
|
||||
# --- Clean Old Match Files & Create Cached Summary ---
|
||||
Write-Output "Cleaning old match files and creating cached summary..."
|
||||
$cachedMatches = @()
|
||||
$archivedMatchFiles = 0
|
||||
$processedMatchFiles = 0
|
||||
$monthsToKeepMatches = -3 # How long to keep individual match files
|
||||
|
||||
try {
|
||||
$matchFiles = Get-ChildItem -Path $matchesPath -Filter *.json -File -ErrorAction SilentlyContinue
|
||||
if ($matchFiles) {
|
||||
$archiveThreshold = (Get-Date).AddMonths($monthsToKeepMatches)
|
||||
Write-Output "Archiving match files older than: $archiveThreshold"
|
||||
|
||||
foreach ($file in $matchFiles) {
|
||||
$processedMatchFiles++
|
||||
try {
|
||||
$fileContent = Get-Content -Path $file.FullName | ConvertFrom-Json -Depth 100 -ErrorAction Stop
|
||||
# Validate essential structure
|
||||
if ($null -eq $fileContent -or $null -eq $fileContent.data.attributes.createdAt -or $null -eq $fileContent.included) {
|
||||
Write-Warning "Skipping invalid match file: $($file.Name)"
|
||||
continue
|
||||
}
|
||||
|
||||
$matchFileDate = $null
|
||||
try { $matchFileDate = [datetime]$fileContent.data.attributes.createdAt } catch { Write-Warning "Could not parse date in match file $($file.Name)" }
|
||||
|
||||
# Archive old files
|
||||
if ($null -ne $matchFileDate -and $matchFileDate -lt $archiveThreshold) {
|
||||
Write-Verbose "Archiving match file: $($file.Name)"
|
||||
Move-Item -Path $file.FullName -Destination $matchesArchivePath -Force -ErrorAction SilentlyContinue
|
||||
if ($?) { $archivedMatchFiles++ }
|
||||
else { Write-Warning "Failed to archive match file: $($file.Name)" }
|
||||
} else {
|
||||
# Process file for cached summary if it's recent enough
|
||||
$matchAttributes = $fileContent.data.attributes
|
||||
$matchId = $fileContent.data.id
|
||||
|
||||
# Find stats for clan members within this match
|
||||
$clanMemberStatsInMatch = @()
|
||||
if ($fileContent.included -is [array]) {
|
||||
$clanMemberStatsInMatch = $fileContent.included |
|
||||
Where-Object { $_.type -eq 'participant' -and $clanMembers -contains $_.attributes.stats.name } |
|
||||
Select-Object -ExpandProperty attributes | Select-Object -ExpandProperty stats
|
||||
}
|
||||
|
||||
if ($clanMemberStatsInMatch.Count -gt 0) {
|
||||
$cachedMatches += [PSCustomObject]@{
|
||||
matchType = $matchAttributes.matchType
|
||||
gameMode = $matchAttributes.gameMode
|
||||
createdAt = $matchAttributes.createdAt
|
||||
mapName = $matchAttributes.mapName
|
||||
id = $matchId
|
||||
stats = @($clanMemberStatsInMatch) # Ensure stats is always an array
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
Write-Warning "Error processing match file '$($file.Name)': $($_.Exception.Message)"
|
||||
}
|
||||
} # End foreach file
|
||||
Write-Output "Processed $processedMatchFiles match files. Archived: $archivedMatchFiles."
|
||||
|
||||
# Save the cached summary object
|
||||
if ($cachedMatches.Count -gt 0) {
|
||||
try {
|
||||
$cachedMatches | Sort-Object createdAt -Descending | ConvertTo-Json -Depth 100 | Out-File -FilePath $cachedMatchesJsonPath -Encoding UTF8 -ErrorAction Stop
|
||||
Write-Output "Cached matches summary saved to '$cachedMatchesJsonPath'. Count: $($cachedMatches.Count)"
|
||||
} catch {
|
||||
Write-Error "Failed to save cached matches summary to '$cachedMatchesJsonPath'. Error: $($_.Exception.Message)"
|
||||
}
|
||||
} else {
|
||||
Write-Output "No recent matches found containing clan members for cached summary."
|
||||
# Optionally clear or save an empty array to the cache file
|
||||
# @() | ConvertTo-Json | Out-File -FilePath $cachedMatchesJsonPath -Encoding UTF8
|
||||
}
|
||||
|
||||
} else {
|
||||
Write-Output "No match files found in '$matchesPath' to process or clean."
|
||||
}
|
||||
} catch {
|
||||
Write-Warning "Error during match file cleaning/caching process: $($_.Exception.Message)"
|
||||
}
|
||||
|
||||
} # End Main Try Block
|
||||
finally {
|
||||
# --- Cleanup ---
|
||||
Write-Output "Script finished at $(Get-Date)."
|
||||
Remove-Lock # Ensure lock is always removed
|
||||
Stop-Transcript
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue