Add basic PowerShell module for SteamCMD
This commit is contained in:
parent
fec743a630
commit
676898608b
2 changed files with 214 additions and 0 deletions
14
LANCommander.Server/Modules/SteamCMD/SteamCMD.psd1
Normal file
14
LANCommander.Server/Modules/SteamCMD/SteamCMD.psd1
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
@{
|
||||
RootModule = 'SteamCMD.psm1'
|
||||
ModuleVersion = '1.0.0'
|
||||
GUID = 'd9e2b2b7-7c4a-4c1c-9c33-93d5f65a4a21'
|
||||
Author = 'Pat Hartl'
|
||||
CompanyName = 'LANCommander'
|
||||
Description = 'Install and update Steam games using SteamCMD'
|
||||
PowerShellVersion = '7.0'
|
||||
|
||||
FunctionsToExport = @('Install-SteamGame')
|
||||
CmdletsToExport = @()
|
||||
VariablesToExport = @()
|
||||
AliasesToExport = @()
|
||||
}
|
||||
200
LANCommander.Server/Modules/SteamCMD/SteamCMD.psm1
Normal file
200
LANCommander.Server/Modules/SteamCMD/SteamCMD.psm1
Normal file
|
|
@ -0,0 +1,200 @@
|
|||
Set-StrictMode -Version Latest
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
function Invoke-SteamCmd {
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory)] [string] $SteamCmdPath,
|
||||
[Parameter(Mandatory)] [string[]] $Arguments,
|
||||
[Parameter()] [string] $LogPath = ""
|
||||
)
|
||||
|
||||
$psi = [System.Diagnostics.ProcessStartInfo]::new()
|
||||
$psi.FileName = $SteamCmdPath
|
||||
$psi.UseShellExecute = $false
|
||||
$psi.RedirectStandardOutput = $true
|
||||
$psi.RedirectStandardError = $true
|
||||
|
||||
foreach ($a in $Arguments) { [void]$psi.ArgumentList.Add($a) }
|
||||
|
||||
$proc = [System.Diagnostics.Process]::new()
|
||||
$proc.StartInfo = $psi
|
||||
|
||||
[void]$proc.Start()
|
||||
|
||||
$stdout = $proc.StandardOutput.ReadToEnd()
|
||||
$stderr = $proc.StandardError.ReadToEnd()
|
||||
|
||||
$proc.WaitForExit()
|
||||
|
||||
$combined = @(
|
||||
"===== SteamCMD STDOUT ====="
|
||||
$stdout
|
||||
"===== SteamCMD STDERR ====="
|
||||
$stderr
|
||||
) -join "`n"
|
||||
|
||||
if ($LogPath) {
|
||||
$dir = Split-Path -Parent $LogPath
|
||||
if ($dir) { New-Item -ItemType Directory -Path $dir -Force | Out-Null }
|
||||
Set-Content -LiteralPath $LogPath -Value $combined -Encoding UTF8
|
||||
}
|
||||
|
||||
[PSCustomObject]@{
|
||||
ExitCode = $proc.ExitCode
|
||||
StdOut = $stdout
|
||||
StdErr = $stderr
|
||||
Combined = $combined
|
||||
}
|
||||
}
|
||||
|
||||
function Install-SteamGame {
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
[int] $AppId,
|
||||
|
||||
[Parameter(Mandatory)]
|
||||
[string] $GameName,
|
||||
|
||||
[Parameter(Mandatory)]
|
||||
[string] $InstallRoot,
|
||||
|
||||
[Parameter()]
|
||||
[string] $SteamCmdPath = "steamcmd",
|
||||
|
||||
[Parameter()]
|
||||
[string] $Username = "anonymous",
|
||||
|
||||
[Parameter()]
|
||||
[string] $Password = "",
|
||||
|
||||
[Parameter()]
|
||||
[string] $Branch = "",
|
||||
|
||||
[Parameter()]
|
||||
[string] $BranchPassword = "",
|
||||
|
||||
[Parameter()]
|
||||
[switch] $Validate,
|
||||
|
||||
[Parameter()]
|
||||
[switch] $IncludeSteamNews = $true
|
||||
)
|
||||
|
||||
function Join-PathPortable([string] $A, [string] $B) {
|
||||
if ($A.EndsWith("/") -or $A.EndsWith("\")) { return "$A$B" }
|
||||
if ($A -match "^[a-zA-Z]:\\") { return "$A\$B" }
|
||||
return "$A/$B"
|
||||
}
|
||||
|
||||
function Find-AppManifest([string] $InstallDir, [int] $AppIdValue) {
|
||||
$expected = Join-PathPortable $InstallDir ("steamapps/appmanifest_{0}.acf" -f $AppIdValue)
|
||||
if (Test-Path -LiteralPath $expected) { return $expected }
|
||||
|
||||
Get-ChildItem -LiteralPath $InstallDir -Recurse -File `
|
||||
-Filter ("appmanifest_{0}.acf" -f $AppIdValue) `
|
||||
-ErrorAction SilentlyContinue |
|
||||
Select-Object -First 1 |
|
||||
ForEach-Object FullName
|
||||
}
|
||||
|
||||
function Parse-AppManifestBuildInfo([string] $ManifestPath) {
|
||||
$content = Get-Content -LiteralPath $ManifestPath -Raw
|
||||
|
||||
$buildId = [regex]::Match($content, '"buildid"\s+"(\d+)"').Groups[1].Value
|
||||
$lastUpdated = [regex]::Match($content, '"LastUpdated"\s+"(\d+)"').Groups[1].Value
|
||||
|
||||
[PSCustomObject]@{
|
||||
BuildId = $buildId
|
||||
LastUpdatedUtc = if ($lastUpdated) {
|
||||
[DateTimeOffset]::FromUnixTimeSeconds([int64]$lastUpdated).UtcDateTime
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Get-SteamNewsChangelog([int] $AppIdValue) {
|
||||
try {
|
||||
$uri = "https://api.steampowered.com/ISteamNews/GetNewsForApp/v2/?appid=$AppIdValue&count=3&maxlength=800&format=json"
|
||||
$resp = Invoke-RestMethod -Uri $uri -TimeoutSec 15
|
||||
$resp.appnews.newsitems |
|
||||
ForEach-Object {
|
||||
"[{0}] {1}`n{2}" -f `
|
||||
([DateTimeOffset]::FromUnixTimeSeconds($_.date).ToString("u")),
|
||||
$_.title,
|
||||
$_.contents
|
||||
} -join "`n`n"
|
||||
}
|
||||
catch {
|
||||
""
|
||||
}
|
||||
}
|
||||
|
||||
# ---- Install ----
|
||||
|
||||
$installDir = Join-PathPortable $InstallRoot $GameName
|
||||
New-Item -ItemType Directory -Path $installDir -Force | Out-Null
|
||||
|
||||
$args = @(
|
||||
"+force_install_dir", $installDir,
|
||||
"+login", $Username
|
||||
)
|
||||
|
||||
if ($Username -ne "anonymous" -and $Password) {
|
||||
$args += $Password
|
||||
}
|
||||
|
||||
$args += "+app_update", $AppId
|
||||
|
||||
if ($Branch) {
|
||||
$args += "-beta", $Branch
|
||||
if ($BranchPassword) {
|
||||
$args += "-betapassword", $BranchPassword
|
||||
}
|
||||
}
|
||||
|
||||
if ($Validate) {
|
||||
$args += "validate"
|
||||
}
|
||||
|
||||
$args += "+quit"
|
||||
|
||||
$logPath = Join-Path -Path $installDir -ChildPath "steamcmd.log"
|
||||
|
||||
$result = Invoke-SteamCmd -SteamCmdPath $SteamCmdPath -Arguments $args -LogPath $logPath
|
||||
|
||||
if ($result.ExitCode -ne 0) {
|
||||
$tail = ($result.Combined -split "`r?`n" | Select-Object -Last 80) -join "`n"
|
||||
throw @(
|
||||
"SteamCMD failed with exit code $($result.ExitCode)."
|
||||
"Log: $logPath"
|
||||
""
|
||||
"Last 80 lines:"
|
||||
$tail
|
||||
) -join "`n"
|
||||
}
|
||||
|
||||
|
||||
# ---- Version / Changelog ----
|
||||
|
||||
$manifest = Find-AppManifest -InstallDir $installDir -AppIdValue $AppId
|
||||
$build = if ($manifest) { Parse-AppManifestBuildInfo $manifest }
|
||||
|
||||
$version = $build?.BuildId ?? "unknown"
|
||||
|
||||
$changelog = if ($IncludeSteamNews) {
|
||||
Get-SteamNewsChangelog $AppId
|
||||
}
|
||||
|
||||
if (-not $changelog) {
|
||||
$changelog = "BuildID: $version"
|
||||
}
|
||||
|
||||
return [PSCustomObject]@{
|
||||
Path = $installDir
|
||||
Version = $version
|
||||
Changelog = $changelog
|
||||
}
|
||||
}
|
||||
|
||||
Export-ModuleMember -Function Install-SteamGame
|
||||
Loading…
Add table
Add a link
Reference in a new issue