This commit is contained in:
Lanta 2025-04-15 17:12:33 +02:00
parent 1be9732279
commit 01aa843d0b
18 changed files with 4122 additions and 2393 deletions

View file

@ -1,60 +1,139 @@
Start-Transcript -Path '/var/log/report_new_matches.log' -Append
# --- Script Setup ---
# Note: Transcript path seems incorrect, should likely be specific to this script.
# Consider changing to '/var/log/dtch/report_to_discord.log' or similar.
Start-Transcript -Path '/var/log/dtch/report_to_discord.log' -Append
Write-Output "Starting report_to_discord script at $(Get-Date)"
Write-Output "Running from: $(Get-Location)"
if ($PSScriptRoot.length -eq 0) {
$scriptroot = Get-Location
# 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"
}
else {
$scriptroot = $PSScriptRoot
}
. $scriptroot\..\includes\ps1\lockfile.ps1
new-lock -by "report_to_discord"
function IsValidEntry($entry) {
return ($entry.KD_H -ne 'NaN' -and $entry.KD_ALL -ne 'NaN') -and
($entry.KD_H -ne 'Infinity' -and $entry.KD_ALL -ne 'Infinity')
}
$fileContent = Get-Content -Path "$scriptroot/../discord/config.php" -Raw
Write-Output "Script root identified as: $scriptRoot"
# Use regex to match the apiKey value
if ($fileContent -match "\`$webhookurl\s*=\s*\'([^\']+)\'") {
$webhookurl = $matches[1]
}
else {
Write-Output "API Key not found"
}
# Define paths using Join-Path
$includesPath = Join-Path -Path $scriptRoot -ChildPath "..\includes\ps1"
$discordConfigPath = Join-Path -Path $scriptRoot -ChildPath "config.php" # Config is in the same dir
$dataPath = Join-Path -Path $scriptRoot -ChildPath "..\data"
$lastStatsJsonPath = Join-Path -Path $dataPath -ChildPath "player_last_stats.json"
$stats = get-content "$scriptroot/../data/player_last_stats.json" | convertfrom-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 "report_to_discord" -ErrorAction Stop # Stop if locking fails
# --- Main Logic in Try/Finally for Lock Removal ---
try {
# --- Helper Function ---
# Checks if K/D values are valid numbers (not NaN or Infinity)
function Test-IsValidKdEntry {
param($entry)
# Check if properties exist and are numeric before comparison
$kdHValid = $entry.PSObject.Properties.Name -contains 'KD_H' -and $entry.KD_H -is [double] -and -not [double]::IsNaN($entry.KD_H) -and -not [double]::IsInfinity($entry.KD_H)
$kdAllValid = $entry.PSObject.Properties.Name -contains 'KD_ALL' -and $entry.KD_ALL -is [double] -and -not [double]::IsNaN($entry.KD_ALL) -and -not [double]::IsInfinity($entry.KD_ALL)
return $kdHValid -and $kdAllValid
}
$filteredData = @{
all = $stats.all | Where-Object { IsValidEntry $_ }
}
# --- Configuration Loading ---
$webhookUrl = $null
if (Test-Path -Path $discordConfigPath -PathType Leaf) {
try {
$fileContent = Get-Content -Path $discordConfigPath -Raw -ErrorAction Stop
# Corrected regex for webhookurl
if ($fileContent -match '^\s*\$webhookurl\s*=\s*''([^'']+)''') {
$webhookUrl = $matches[1]
Write-Output "Discord webhook URL loaded successfully."
} else {
Write-Warning "Webhook URL pattern not found in '$discordConfigPath'."
}
} catch {
Write-Warning "Failed to read '$discordConfigPath'. Error: $($_.Exception.Message)"
}
} else {
Write-Warning "Discord config file not found at '$discordConfigPath'."
}
$most_kills = @{
'name' = (($filteredData.all | Sort-Object kills -Descending)[0].playername)
'stat' = (($filteredData.all | Sort-Object kills -Descending)[0].kills)
}
$most_deaths = @{
'name' = (($filteredData.all | Sort-Object deaths -Descending)[0].playername)
'stat' = (($filteredData.all | Sort-Object deaths -Descending)[0].deaths)
}
$most_humankills = @{
'name' = (($filteredData.all | Sort-Object humankills -Descending)[0].playername)
'stat' = (($filteredData.all | Sort-Object humankills -Descending)[0].humankills)
}
$most_KD_H = @{
'name' = (($filteredData.all | Sort-Object KD_H -Descending)[0].playername)
'stat' = (($filteredData.all | Sort-Object KD_H -Descending)[0].KD_H)
}
$most_KD_ALL = @{
'name' = (($filteredData.all | Sort-Object KD_ALL -Descending)[0].playername)
'stat' = (($filteredData.all | Sort-Object KD_ALL -Descending)[0].KD_ALL)
}
$most_matches = @{
'name' = (($filteredData.all | Sort-Object matches -Descending)[0].playername)
'stat' = (($filteredData.all | Sort-Object matches -Descending)[0].matches)
}
if (-not $webhookUrl) {
Write-Error "Discord webhook URL could not be loaded. Cannot send report."
throw "Missing Webhook URL" # Throw to trigger finally block
}
$content = "
# --- Load Stats Data ---
$statsData = $null
if (Test-Path -Path $lastStatsJsonPath -PathType Leaf) {
try {
$statsData = Get-Content -Path $lastStatsJsonPath | ConvertFrom-Json -ErrorAction Stop
if ($null -eq $statsData) {
Write-Error "Failed to parse stats data from '$lastStatsJsonPath'. Cannot generate report."
throw "Invalid Stats Data"
}
Write-Output "Successfully loaded player stats data."
} catch {
Write-Error "Error reading '$lastStatsJsonPath': $($_.Exception.Message). Cannot generate report."
throw $_
}
} else {
Write-Error "Player stats file not found at '$lastStatsJsonPath'. Cannot generate report."
throw "Missing Stats File"
}
# --- Process Stats ---
Write-Output "Processing stats..."
# Safely access the 'all' category and filter valid entries
$filteredAllStats = @()
if ($statsData.PSObject.Properties.Name -contains 'all' -and $statsData.all -is [array]) {
$filteredAllStats = $statsData.all | Where-Object { Test-IsValidKdEntry $_ }
Write-Output "Found $($filteredAllStats.Count) valid entries in 'all' category."
} else {
Write-Warning "Stats data does not contain a valid 'all' array. Report might be incomplete."
}
# --- Find Top Players (Handle Empty/Null Cases) ---
# Helper to safely get top player stat
function Get-TopStat {
param(
[array]$Data,
[string]$Property,
[string]$DefaultName = "N/A",
[string]$DefaultStat = "N/A"
)
$sorted = $Data | Sort-Object $Property -Descending -ErrorAction SilentlyContinue
if ($sorted -and $sorted.Count -gt 0) {
# Ensure the property exists on the top object before accessing
$topEntry = $sorted[0]
$playerName = if ($topEntry.PSObject.Properties.Name -contains 'playername') { $topEntry.playername } else { $DefaultName }
$statValue = if ($topEntry.PSObject.Properties.Name -contains $Property) { $topEntry.$Property } else { $DefaultStat }
# Format numeric stats if needed (e.g., K/D)
if ($Property -like "KD*" -and $statValue -is [double]) { $statValue = "{0:N2}" -f $statValue }
return @{ 'name' = $playerName; 'stat' = $statValue }
} else {
return @{ 'name' = $DefaultName; 'stat' = $DefaultStat }
}
}
$mostKills = Get-TopStat -Data $filteredAllStats -Property 'kills'
$mostDeaths = Get-TopStat -Data $filteredAllStats -Property 'deaths'
$mostHumanKills = Get-TopStat -Data $filteredAllStats -Property 'humankills'
$mostKdH = Get-TopStat -Data $filteredAllStats -Property 'KD_H'
$mostKdAll = Get-TopStat -Data $filteredAllStats -Property 'KD_ALL'
$mostMatches = Get-TopStat -Data $filteredAllStats -Property 'matches'
Write-Output "Determined top players for report."
# --- Format Discord Message ---
# Using PowerShell multi-line string with variable substitution
$reportContent = @"
:rocket: Het maandelijks raportje :rocket:
Hey toppers!
@ -62,22 +141,22 @@ Hey toppers!
Laten we eens duiken in de cijfers van onze supergamers van de afgelopen maand:
:dart: Meeste Kills:
Hats off voor **$($most_kills['name'])**! Met **$($most_kills['stat'])** kills is hij/zij onze scherpschutter van de maand!
Hats off voor **$($mostKills.name)**! Met **$($mostKills.stat)** kills is hij/zij onze scherpschutter van de maand!
:skull_crossbones: Meeste Deaths:
Oei, oei, oei... **$($most_deaths['name'])** is helaas het vaakst naar het hiernamaals gestuurd met **$($most_deaths['stat'])** deaths. Kop op, volgende keer beter!
Oei, oei, oei... **$($mostDeaths.name)** is helaas het vaakst naar het hiernamaals gestuurd met **$($mostDeaths.stat)** deaths. Kop op, volgende keer beter!
:robot: Meeste Humankills:
Watch out! We hebben een Terminator onder ons. Hoedje af voor **$($most_humankills['name'])** met **$($most_humankills['stat'])** humankills!
Watch out! We hebben een Terminator onder ons. Hoedje af voor **$($mostHumanKills.name)** met **$($mostHumanKills.stat)** humankills!
:bar_chart: Beste KD Ratio (Alle vijanden):
De onevenaarbare **$($most_KD_ALL['name'])** heeft een KD van **$($most_KD_ALL['stat'])** ! Niet slecht, toch? 😉
De onevenaarbare **$($mostKdAll.name)** heeft een KD van **$($mostKdAll.stat)** ! Niet slecht, toch? 😉
:adult: Beste KD Ratio (Alleen menselijke spelers):
Opgelet, gamers! **$($most_KD_H['name'])** heeft een KD van **$($most_KD_H['stat'])** tegen andere spelers! Wie daagt hem/haar uit?
Opgelet, gamers! **$($mostKdH.name)** heeft een KD van **$($mostKdH.stat)** tegen andere spelers! Wie daagt hem/haar uit?
:video_game: Meeste Matches:
Onze meest toegewijde gamer, **$($most_matches['name'])**, heeft maar liefst **$($most_matches['stat'])** matches gespeeld. Ga zo door!
Onze meest toegewijde gamer, **$($mostMatches.name)**, heeft maar liefst **$($mostMatches.stat)** matches gespeeld. Ga zo door!
Da's het voor nu, gamers! Blijf schieten, blijf lachen en tot het volgende rapportje!
@ -85,18 +164,33 @@ High fives en knuffels (virtueel, natuurlijk),
Het Gaming Team
Meer stats zijn hier te vinden : https://lanta.eu/DTCH
"
"@
$content
Write-Output "Formatted Discord message content."
# Write-Verbose $reportContent # Uncomment to see the full message in verbose logs
# --- Send to Discord ---
$payload = @{
content = $reportContent
# username = "Stats Bot" # Optional: Override bot name
# avatar_url = "" # Optional: Override bot avatar
} | ConvertTo-Json -Depth 3 # Depth 3 should be sufficient
Write-Output "Sending report to Discord webhook..."
try {
Invoke-RestMethod -Uri $webhookUrl -Method Post -Body $payload -ContentType 'application/json' -ErrorAction Stop
Write-Output "Report successfully sent to Discord."
} catch {
$errorMessage = $_.Exception.Message
Write-Error "Failed to send report to Discord. Error: $errorMessage"
# Consider logging the failed payload or response details if available
# Write-Warning "Payload: $payload"
}
$payload = [PSCustomObject]@{
content = $content
}
Invoke-RestMethod -Uri $webhookurl -Method Post -Body ($payload | ConvertTo-Json) -ContentType 'Application/Json'
remove-lock
Stop-Transcript
} # End Main Try Block
finally {
# --- Cleanup ---
Write-Output "Script finished at $(Get-Date)."
Remove-Lock # Ensure lock is always removed
Stop-Transcript
}